文章目录[隐藏]
- RV1126(更新完导出pdf保存)
- i2c-tools工具安装
- TP
- 配置编译工具
- 编译应用程序
- alsa
- alsa-lib,alsa-utils移植
- shell脚本框架
- 【ALSA】 asound.conf 插件讲解
- 查询log关键字
- 修改kernel 的编译的config文件
- 添加开机启动脚本
- 登录evb板的调试方式
- 调试PHY网口
- 虚拟机系统链接网络设置
- 关于CONFIG_OF
- 安检门DTSI
- zk_ajm_rv1126_v1.dtsi(闸机板子)
RV1126(更新完导出pdf保存)
大佬实战教程:
https://gitee.com/owlvisiontech/owlvtech-patch-rv1126/wikis/OWL%E5%BC%80%E5%8F%91%E6%9D%BF%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B?sort_id=2876107
固件烧录
1.找到sdk的烧录工具位置
rv1126_rv1109_linux_210301/tools/linux/Linux_Upgrade_Tool
2.安装工具
unzip Linux_Upgrade_Tool_xxxx.zip
cd Linux_UpgradeTool_xxxx
sudo mv upgrade_tool /usr/local/bin
sudo chown root:root /usr/local/bin/upgrade_tool
sudo chmod a+x /usr/local/bin/upgrade_tool
3.升级
- 按住设备
recovery
按键后使用Typec
线连接设备和电脑上电, 等待3
秒松开recovery
按键。或按住recovery 3s 然后按一下reset - 进入下载固件的路径下依次运行以下命令完成升级。
sudo upgrade_tool ul MiniLoaderAll.bin
sudo upgrade_tool di -p parameter.txt
sudo upgrade_tool di -uboot uboot.img
sudo upgrade_tool di -b boot.img
sudo upgrade_tool di -r recovery.img
sudo upgrade_tool di -m misc.img
sudo upgrade_tool di -oem oem.img
sudo upgrade_tool di -userdata userdata.img
sudo upgrade_tool di -rootfs rootfs.img
sudo upgrade_tool rd
# 如果升级的固件不在当前目录,请输入完整路径。
4.注意事项
4.1关闭回读校验
通过设置 config.ini 文件中 rb_check_off=true 来关闭回读校验,默认是进行回读校验
4.2Config.ini配置生效
将 config.ini 文件放在$HOME/.config/upgrade_tool/位置下,运行工具即可生效.
修改调试串口波特率
1.修改uboot配置
1.1进入u-boot/路径 make menuconfig
修改位置
│ Symbol: BAUDRATE [=1500000] │
│ Type : integer │
│ Prompt: Default baudrate │
│ Location: │
│ -> Device Drivers │
│ -> Serial drivers
保存配置
现在还保存不了,每次编译会被重新加载
1.2直接修改config文件
u-boot/configs/rv1126_defconfig
CONFIG_BAUDRATE=115200
2.修改kernel
修改调试串口的dts配置
//debug uart
&fiq_debugger {
compatible = "rockchip,fiq-debugger";
status = "okay";
rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */
};
DTS
dts的使用以及格式
参考链接:http://www.voidcn.com/article/p-mvvttwny-bms.html
参考文档:Device Tree Usage
快速定位板子编译的dts
打开/home/jelly/rv1126_rv1109_linux_210301/device/rockchip/rv1126_rv1109/BoardConfig.mk
里面会有
#Kernel dts
export RK_KERNEL_DTS=rv1126-evb-ddr3-v13
rv1126-evb-ddr3-v13 就是要编译的dts文件
当然你也可以用rk给的方法./build.sh lunch 去选择要编译的板子类型的mk 文件,然后去查看这个mk文件里面的dts是编译的哪一个
解析dts文件
打开/home/jelly/rv1126_rv1109_linux_210301/kernel/arch/arm/boot/dts/rv1126-evb-ddr3-v13.dts
里面包含
#include "rv1126.dtsi"
#include "rv1126-evb-v13.dtsi"
/ {
model = "Rockchip RV1126 EVB DDR3 V13 Board";
compatible = "rockchip,rv1126-evb-ddr3-v13", "rockchip,rv1126";
chosen {
bootargs = "earlycon=uart8250,mmio32,0xff570000 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait snd_aloop.index=7";
};
};
打开include “rv1126.dtsi”
这里面是rv1126芯片的各各外设模块寄存器地址,还有外设定义
打开 rv1126-evb-v13.dtsi
#include "rv1126-evb-v12.dtsi"
&backlight {
pwms = <&pwm0 0 25000 0>;
};
&pwm0 {
status = "okay";
};
&pwm3 {
status = "disabled";
};
&u2phy0 {
vup-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>;
};
打开 include “rv1126-evb-v12.dtsi”
* >```
>#include "rv1126-evb-v10.dtsi"
>/ {
> /delete-node/ vdd-npu;
> /delete-node/ vdd-vepu;
> vdd_logic: vdd-logic {
compatible = "regulator-fixed"; regulator-name = "vdd_logic"; regulator-always-on; regulator-boot-on; regulator-min-microvolt = <810000>; regulator-max-microvolt = <810000>; }; }; &rk809 { regulators { /delete-node/ DCDC_REG1; vdd_npu_vepu: DCDC_REG1 { regulator-always-on; regulator-boot-on; regulator-min-microvolt = <650000>; regulator-max-microvolt = <950000>; regulator-ramp-delay = <6001>; regulator-initial-mode = <0x2>; regulator-name = "vdd_npu_vepu"; regulator-state-mem { regulator-off-in-suspend; }; }; }; }; &ov4689 { reset-gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; }; &os04a10 { reset-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; }; &npu { npu-supply = <&vdd_npu_vepu>; }; &pwm0 { status = "disabled"; }; &pwm1 { status = "disabled"; }; &rkvenc { venc-supply = <&vdd_npu_vepu>; }; &rkvenc_opp_table { /* * max IR-drop values on different freq condition for this board! */ rockchip,board-irdrop = < /* MHz MHz uV */ 500 594 50000 >; >}; ``` ```
打开 include “rv1126-evb-v10.dtsi”
#include <dt-bindings/display/drm_mipi_dsi.h>
#include <dt-bindings/input/input.h>
/ {
.
.
.
.......
代码太多这里就不复制了
这里主要是rv1126开发板的外设初始化dts配置,继承这里就可以做自己的开发板dts啦
驱动和设备树交互过程
在设备树中定义的信息。
flash_SY7803:flashlight {
compatible = "qcom,leds-gpio-flash"; //匹配参数
status = "okay";
pinctrl-names = "flash_default";
pinctrl-0 = <&SY7803_default>;
qcom,flash-en = <&msm_gpio 31 0>;
qcom,flash-now = <&msm_gpio 32 0>;
qcom,op-seq = "flash_en", "flash_now";
qcom,torch-seq-val = <0 1>;
qcom,flash-seq-val = <1 0>;
linux,name = "flashlight"; //属性 linux,name
linux,default-trigger = "flashlight-trigger";
};
在驱动中如何能获得设备树的信息呢? 是通过node 节点
struct device_node *node = pdev->dev.of_node; //取得node
涉及到下边的一些用法,都是用来取得设备树中的信息的
1. int of_property_read_string(struct device_node *np, const char *propname,const char **out_string)
Find and read a string from a property
rc = of_property_read_string(node, "linux,default-trigger", &temp_str);
of_get_named_gpio
of_get_named_gpio(struct device_node *np,const char *propname, int index)
of_get_named_gpio(node, "qcom,flash-en", 0);
// 取得的值应当是31
of_property_read_string
int of_property_read_string(struct device_node *np, const char *propname,const char **out_string)
rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
//flash_led->cdev.name = flashlight
of_property_read_u32_array
int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values,size_t sz)
uint32_t array_flash_seq[2];
rc = of_property_read_u32_array(node, "qcom,flash-seq-val",array_flash_seq, 2);
array_flash_seq <1 0>
5
.of_property_read_string_index
int of_property_read_string_index(struct device_node *np, const char *propname,int index, const char **output)
rc = of_property_read_string_index(node, "qcom,op-seq", i, &seq_name);
//"flash_en", "flash_now";
-------------------
compatible 使用来匹配驱动的
.of_match_table = led_gpio_flash_of_match,
\1. 设备树中 compatible
键值对
2.driver中
platform_driver 结构体
probe
remove
of_match_table
probe 中
1.通过of函数获得相关的资源信息,
\2. 申请引脚信息 pinctrl
3.注册设备 classdev
led_classdev_register
明确驱动如何找到设备树,然后再驱动中找到相应的代码分析就可以了。
想了解更多请参考韦东山的驱动篇教程有专门讲dts部分,很详细
Pinctrl
这会涉及 2 个对象: pin controller、 client device。
前者提供服务:可以用它来复用引脚、配置引脚。
后者使用服务:声明自己要使用哪些引脚的哪些功能,怎么配置它们。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8q4ijj8-1628238375526)(RV1126.assets/image-20210409173807653.png)]
芯片的默认pinctrl DTS文件路径:
/home/jelly/rv1126_rv1109_linux_210301/kernel/arch/arm/boot/dts/rv1126-pinctrl.dtsi
of_device_id 和 xxx_device_id
设备号
of_device_id:用于设备树device信息匹配 driver
xxx_device_id:用于device匹配 driver
系统会优先使用of_device_id数据,在没有匹配上of_device_id 时系统才会用 xxx_device_id去匹配driver
例子:
static const struct i2c_device_id es7243_i2c_id[] = {
#if ES7243_CHANNELS_MAX > 0
{ "MicArray_0", 0 },//es7243_0
#endif
#if ES7243_CHANNELS_MAX > 2
{ "MicArray_1", 1 },//es7243_1
#endif
#if ES7243_CHANNELS_MAX > 4
{ "MicArray_2", 2 },//es7243_2
#endif
#if ES7243_CHANNELS_MAX > 6
{ "MicArray_3", 3 },//es7243_3
#endif
{ }
};
MODULE_DEVICE_TABLE(i2c, es7243_i2c_id);
static const struct of_device_id es7243_dt_ids[] = {
#if ES7243_CHANNELS_MAX > 0
{ .compatible = "MicArray_0", },//es7243_0
#endif
#if ES7243_CHANNELS_MAX > 2
{ .compatible = "MicArray_1", },//es7243_1
#endif
#if ES7243_CHANNELS_MAX > 4
{ .compatible = "MicArray_2", },//es7243_2
#endif
#if ES7243_CHANNELS_MAX > 6
{ .compatible = "MicArray_3", },//es7243_3
#endif
{},
};
MODULE_DEVICE_TABLE(of, es7243_dt_ids);
static struct i2c_driver es7243_i2c_driver = {
.driver = {
.name = "es7243",
.owner = THIS_MODULE,
#if ES7243_MATCH_DTS_EN
.of_match_table = es7243_dt_ids,
#endif
},
.probe = es7243_i2c_probe,
.remove = __exit_p(es7243_i2c_remove),
.class = I2C_CLASS_HWMON,
.id_table = es7243_i2c_id,
#if !ES7243_MATCH_DTS_EN
.address_list = es7243_i2c_addr,
.detect = es7243_i2c_detect,
#endif
};
建立自己的开发板dts
1.将开发板的dts文件夹拷贝出来,并将芯片相关的dts文件提取出来
2.用vscod 编辑自己的dts文件
(这么做是为了方便查找dts相关的变量)
3.根据自己的原理图修改或添加自己的dts配置,没有改动的就不需要修改,沿用官方的dts配置
查找soc自带的dts外设驱动配置
在下面这个路径下又各种外设的dts配置说明文档,查找与自己相关的dts文档参考即可
kernel/Documentation/devicetree/bindings/clock/clock-bindings.txt
DTS的方式时钟配置
dts的方式
时钟默认配置
cru: clock-controller@ff760000 {
compatible = "rockchip,rk3399-cru";
reg = <0x0 0xff760000 0x0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
assigned-clocks =
<&cru ACLK_VOP0>, <&cru HCLK_VOP0>,
<&cru ACLK_VOP1>, <&cru HCLK_VOP1>,
<&cru ARMCLKL>, <&cru ARMCLKB>,
<&cru PLL_GPLL>, <&cru PLL_CPLL>,
<&cru ACLK_GPU>, <&cru PLL_NPLL>,
<&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>,
<&cru PCLK_PERIHP>,
<&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
<&cru PCLK_PERILP0>,
<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
assigned-clock-rates =
<400000000>, <200000000>,
<400000000>, <200000000>,
<816000000>, <816000000>,
<594000000>, <800000000>,
<200000000>, <1000000000>,
<150000000>, <75000000>,
<37500000>,
<100000000>, <100000000>,
<50000000>,
<100000000>, <50000000>;
};
== 分配的父时钟和速率 ==
某些平台可能需要初始配置默认的父时钟和时钟频率。 可以在设备树节点中通过已分配的时钟,已分配的时钟父对象和已分配的时钟速率属性指定这种配置
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
}
参考soc厂商的dts配置的快捷方式
将soc厂商的dts文件拷贝出来然后用vsconde查找编辑
驱动实现步骤
1.用设备树写好设备信息
2.定义of_device_id 和 xxx_device_id
3.定义driver
4.实现deiver具体功能以及相关函数
5.注册driver
exmple:
1.用设备树写好设备信息
在注册 I2C 设备时,需要结构体 i2c_client
来描述 I2C 设备。然而在标准 Linux 中,用户只需要提供相应的 I2C 设备信息,Linux 就会根据所提供的信息构造 i2c_client
结构体。
用户所提供的 I2C 设备信息以节点的形式写到 DTS 文件中,如下所示:
kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-edp.dts
&i2c4 {
status = "okay";
gsl3680: gsl3680@41 {
compatible = "gslX680";
reg = <0x41>;
screen_max_x = <1536>;
screen_max_y = <2048>;
touch-gpio = <&gpio1 20 IRQ_TYPE_LEVEL_LOW>;
reset-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
};
2.定义of_device_id 和 xxx_device_id
在定义 I2C 驱动之前,用户首先要定义变量 of_device_id
和 i2c_device_id
。
of_device_id
用于在驱动中调用 DTS 文件中定义的设备信息,其定义如下所示:
static struct of_device_id gsl_ts_ids[] = {
{.compatible = "gslX680"},
{}
};
定义变量 i2c_device_id
:
static const struct i2c_device_id gsl_ts_id[] = {
{GSLX680_I2C_NAME, 0},
{}
};
MODULE_DEVICE_TABLE(i2c, gsl_ts_id);
3.定义driver
static struct i2c_driver gsl_ts_driver = {
.driver = { .name = GSLX680_I2C_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(gsl_ts_ids),
},
#ifndef CONFIG_HAS_EARLYSUSPEND
//.suspend = gsl_ts_suspend,
//.resume = gsl_ts_resume,
#endif
.probe = gsl_ts_probe,
.remove = gsl_ts_remove,
.id_table = gsl_ts_id,
};
注:变量 id_table
指示该驱动所支持的设备。
4.实现deiver具体功能以及相关函数
5.注册driver
使用 i2c_add_driver
函数注册 I2C 驱动。
i2c_add_driver(&gsl_ts_driver);
在调用 i2c_add_driver
注册 I2C 驱动时,会遍历 I2C 设备,如果该驱动支持所遍历到的设备,则会调用该驱动的 probe
函数。
通过 I2C 收发数据
以太网(RMII)
1.因为rmii是标准接口,所以只需要配置dts就可以了
SOC输出时钟模式(现在还没调通,估计是时钟问题)
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
PHY输出时钟模式
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
}
设置时钟频率
设置成soc输出时钟的画要设置成50M时钟输出
设置成pyh输出时钟的画也是设置成50m但十物理时钟用25m就设置成25m
一般rimm百兆接口设置成soc输出时钟,除非soc没有50m时钟
常见问题
无法做到ping通
1.将虚拟机改为桥接模式
2.检查网段是不是存在ip冲突
3.电脑,虚拟机,板子,是不是在同一个网段
参考资料:
《Rockchip 以太网 开发指南 V2.3.1-20160708》
kernel/Documentation/devicetree/bindings/clock/clock-bindings.txt
WIFI/BLE
WIFI
参考资料 doc/Linux/Wfifbt
编译wifi code
│ CONFIG_RTL8723DS: │
│ │
│ Help message of RTL8723DS │
│ │
│ Symbol: RTL8723DS [=y] │
│ Type : tristate │
│ Prompt: Realtek 8723D SDIO or SPI WiFi │
│ Location: │
│ -> Device Drivers │
│ -> Network device support (NETDEVICES [=y]) │
│ -> Wireless LAN (WLAN [=y]) │
│ -> Rockchip Wireless LAN support (WL_ROCKCHIP [=y]) │
│ -> Realtek Wireless Device Driver Support (RTL_WIRELESS_SOL
查看所有网卡信息
ifconfig -a
使能失能网卡
ifconfig wlan0 up/down
wifi配置
- 首先确保Wi-Fi的服务进程启动,串口输入:
ps | grep wpa_supplicant
- 如果没启动,请手动启动:
wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf &
- 修改 /data/cfg/wpa_supplicant.conf 文件,添加配置项
vi /data/cfg/wpa_supplicant.conf
network={
ssid="WiFi-AP" // Wi-Fi名字
psk="12345678" // Wi-Fi密码
key_mgmt=WPA-PSK // 选填加密方式,不填的话可以自动识别
#key_mgmt=NONE // 不加密
}
- 重新读取上述配置: wpa_cli reconfigure
wpa_cli reconfigure
- 重新连接: wpa_cli reconnect
wpa_cli reconnect
I2C
I2C子系统驱动架构 - 驱动框架:
https://blog.csdn.net/cc289123557/article/details/51814778?spm=1001.2014.3001.5501
https://blog.csdn.net/weixin_34032792/article/details/85582751?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
需要注意的是,现阶段只要注册了 i2c_add_drive , adapter 不需要关心,i2c_add_drive 里面会注册adapter
i2c的实现方式参考 “驱动实现步骤” 章节。
es7243调试
查看设备
cat /proc/asound/pcm
寄存器调试:
路径 /sys/bus/i2c/devices/1-0011/driver
驱动提供了寄存器的读写调试,路径 /sys/devices/platform/ff110000.i2c/i2c-1/1-0013/es7243_debug
读例子:
//读取0x00开始的16个寄存器
#echo 0010 > es7243
查看时钟开启情况
cat /sys/kernel/debug/clk/clk_summary | grep i2s
cat /sys/kernel/debug/clk/clk_summary
PWM
dts配置:
内核 3.10 版本和 4.4 版本的 DTS 节点,略有不同的地方在配置的参数个数上,内核 3.10 版本配置的参
数数目为 2,内核 4.4 版本配置的参数数目为 2 或者 3;参数数目与 PWM 节点中的 “pwm-cells” 对
应,如果 “pwm-cells” 配置是 3,则需要配置可选的极性;如果是 2,就不需要配置极性。
DTS 配置参考文档 Documentation/devicetree/bindings/pwm/pwm.txt,主要几个参数说明下:
参数 1,表示 index (per-chip index of the PWM to request),一般是 0,因为我们 Rockchip
PWM 每个 chip 只有一个。
参数 2,表示 PWM 输出波形的时间周期,单位是 ns;例如下面配置的 25000 就是表示想要得到
的 PWM 输出周期是 40K 赫兹。
参数 3,表示极性,为可选参数;下面例子中的配置为负极性。
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&pwm10m1_pins_pull_down>;
};
PWM 使用:
对于 PWM 的 kernel 和 user space 使用说明在 Documentation/pwm.txt 有说明,下面重点提下 user
space 部分。就像 pwm.txt 文档里面说的,PWM 提供了用户层的接口,在 /sys/class/pwm/ 节点下
面,PWM 驱动加载成功后,会在 /sys/class/pwm/ 目录下产生 pwmchip0 目录;向 export 文件写入
0,就是打开 pwm 定时器 0,会产生一个 pwm0 目录,相反的往 unexport 写入 0 就会关闭 pwm 定
时器了,同时 pwm0 目录会被删除,该目录下有以下几个文件:
enable:写入 1 使能 pwm,写入 0 关闭 pwm;
polarity:有 normal 或 inversed 两个参数选择,表示输出引脚电平翻转;
duty_cycle:在 normal 模式下,表示一个周期内高电平持续的时间(单位:纳秒),在 reversed
模式下,表示一个周期中低电平持续的时间(单位:纳秒);
period:表示 pwm 波的周期(单位:纳秒);
以下是 pwmchip0 的例子,设置 pwm0 输出频率 100K,占空比 50%, 极性为正极性:
PWM Backlight
PWM 的连续模式使用最多,且背光使用较为频繁。
\1. Backlight DTS
以下是 DTS 文件中背光很常见的背光配置节点:
cd /sys/class/pwm/pwmchip0/
echo 0 > export
cd pwm0
echo 10000 > period
echo 5000 > duty_cycle
echo normal > polarity
echo 1 > enable
调试方式:
查看注册是否成功,成功则返回接口名和寄存器地址
cat /sys/kernel/debug/pwm
注意事项:
dts修改pwm外设后要关注在dts的其他头文件dtsi中有没有调用或修改相关外设,不然会导致外设配置失败的问题
参考文档:
Rockchip_Developer_Guide_Linux_PWM_CN
MIPI DSI
屏配置方式一**😗* 使用短字符串匹配写死的timing
屏配置方式二**😗* 直接将timing写在dts文件中
需要一份屏幕规格书
1.提取屏幕硬件信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTYKvGhZ-1628238375536)(RV1126.assets/image-20210508143954525.png)]
提取信息:
Display resolution:720*1280
Lcd active aera:62.10*110.4
Screen size:5.0
2.提取时序信息
display-timings
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y5MdW4Ks-1628238375540)(RV1126.assets/image-20210508164703206.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IxFpGwW2-1628238375542)(RV1126.assets/image-20210508164829835.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwcXHeu0-1628238375545)(RV1126.assets/image-20210508172033689.png)]
/home/jelly/rv1126_rv1109_linux_210301/kernel/Documentation/devicetree/bindings/display/panel/cat display-timing.txt
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xCbVt9he-1628238375546)(RV1126.assets/image-20210508170012273.png)]
注意:这里没有找到1126的soc的显示时序图,先在用的soc的图是三星的soc的图
soc lcd屏 驱动 DTS
垂直方向
VSPW VSA/tvpw 1<y<20 y=10 vsync_len vsync-len
VBPD VBP/tvb-tvpw 23-tvpw 13 upper_margin vback-porch
LINVAL VACT/tvd 1280 yres vactive
VFPD VFP/tvfp 22 lower_margin vfront-porch
水平方向
HSPW HSA/thpw 1<x<40 x=20 hsync_len hsync-len
HBPD HBP/thb-thpw 46-thpw 26 left_margin hback-porch
HOZVAL HACT/thd 720 xres hactive
HFPD HFP/thfp 210 right_margin hfront-porch
关键信息提炼出来:
4 data lines(厂家推荐值):
Hactive = 800
HFP = 40
HBP = 20
Hsync = 20
Vactive = 1280
VFP = 20
VBP = 20
VSync = 10
clock-frequency = (h_active + hfp + hbp + h_sync) * (v_active + vfp + vbp + v_sync) * fps
厂商给参考值60Hz,
fps= clk/ (800 + 40 + 20 +20) * (1280 + 20 + 20 + 10) = 60Hz
Pixel Clock Frequency(Pclk)= 70.22MHZ
这里我们详细说一下各个参数的含义,这个对我们后续调屏会非常有帮助。
另外根据以上的信息,我们还能计算出 Mipi Dsi Clock 。
DCLK = 100 + H_total×V_total × fps × 3 × 8 / lanes_nums
total 这里指的是 sync + front + back + active
比如 H_total = Hsync + HFP(hfront-proch) + HBP(hback-porch) + Hactive
fps 指的是帧率,一般我们按照 60 帧来计算
3 × 8 代表一个 RGB 为 3 个字节,每个字节 8 bit
lanes 代表 mipi data 通道数
所以对于我这个屏
DCLK
= 100Mbps + H_Total × V_Total x fps x 3 x 8 / lanes_nums
= 100 + ( 800 + 40 + 20 + 20 ) x ( 1280 + 20 + 20+ 10 ) x 60 帧 x 3 字节 x 8 bit / 4 lanes
= 100Mbps + 421Mbps = 521 Mbps
MIPI CLK Lane * 2 = MIPI DATA Lane
3.提取gpio配置信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-syisI3HP-1628238375548)(RV1126.assets/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16204613948073.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FnbkKPbE-1628238375550)(RV1126.assets/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16204614954716.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UkhxmDJ9-1628238375551)(RV1126.assets/image-20210512152619719.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSjg8rO5-1628238375553)(RV1126.assets/image-20210517163545204.png)]
4.DTS配置
参考文档
panel node
----------
Required properties:
- compatible: Should contain one of the following:
- "simple-panel": for common simple panel
- "simple-panel-dsi": for common simple dsi panel
- "vendor,panel": for vendor specific panel
- power-supply: See panel-common.txt
Optional properties:
- vsp-supply: positive voltage supply
- vsn-supply: negative voltage supply
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- enable-gpios: GPIO pin to enable or disable the panel
- reset-gpios: GPIO pin to reset the panel
- backlight: phandle of the backlight device attached to the panel
- prepare-delay-ms: the time (in milliseconds) that it takes for the panel to
become ready and start receiving video data
- enable-delay-ms: the time (in milliseconds) that it takes for the panel to
display the first valid frame after starting to receive
video data
- disable-delay-ms: the time (in milliseconds) that it takes for the panel to
turn the display off (no content is visible)
- unprepare-delay-ms: the time (in milliseconds) that it takes for the panel
to power itself down completely
- reset-delay-ms: the time (in milliseconds) that it takes for the panel to
reset itself completely
- init-delay-ms: the time (in milliseconds) that it takes for the panel to
send init command sequence after reset deassert
- width-mm: width (in millimeters) of the panel's active display area
- height-mm: height (in millimeters) of the panel's active display area
- bpc: bits per color/component
- bus-format: Pixel data format on the wire
- dsi,lanes: number of active data lanes
- dsi,format: pixel format for video mode
- dsi,flags: DSI operation mode related flags
- panel-init-sequence:
- panel-exit-sequence:
A byte stream formed by simple multiple dcs packets.
byte 0: dcs data type
byte 1: wait number of specified ms after dcs command transmitted
byte 2: packet payload length
byte 3 and beyond: number byte of payload
- power-invert: power invert control
- rockchip,cmd-type: default is DSI cmd, or "spi", "mcu" cmd type
- spi-sdi: spi init panel for spi-sdi io
- spi-scl: spi init panel for spi-scl io
- spi-cs: spi init pael for spi-cs io
Example:
panel: panel {
compatible = "cptt,claa101wb01";
ddc-i2c-bus = <&panelddc>;
power-supply = <&vdd_pnl_reg>;
enable-gpios = <&gpio 90 0>;
backlight = <&backlight>;
};
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "ilitek,ili9881d", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <62>;
height-mm = <110>;
panel-init-sequence = [
39 00 04 ff 98 81 03
15 00 02 01 00
15 00 02 02 00
15 00 02 03 73
15 00 02 04 00
15 00 02 05 00
15 00 02 06 0a
.
.
.
.
这个配置要严格按照屏幕厂商提供的配置参数配置,不然显示会不正常
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <75000000>;
hactive = <720>;
vactive = <1280>;
hfront-porch = <100>;
hsync-len = <33>;
hback-porch = <100>;
vfront-porch = <14>;
vsync-len = <4>;
vback-porch = <14>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
屏配置方式三**😗* 使用edid
MIPI DSI协议介绍
https://blog.csdn.net/longxiaowu/article/details/24410021
调试
显示信息
//由于rockchip driver的一些配置未upstream到libdrm上, 所以从libdrm upstream
//下载编译的modetest默认不带rockchip支持, 需要在使用的时候加个-M rockchip.
(shell)# modetest -M rockchip
显示输出命令
modetest -M rockchip -s 56@53:720x1280 -v
屏幕上即可看到闪烁的彩条显示,
如需使用dp输出,将命令中的connector的id换成dp的即可.
如需使用另一个crtc输出, 将命令中的crtc的id换成另一个crtc的id即可
如需使用别的分辨率输出, 将命令中1440x900换成connectors modes里面别的分辨率即可
参考资料:
ILI9881D_DTS_V102_20170306_Normal
Rockchip_DRM_Panel_Porting_Guide_V1.6_20190228
Rockchip DRM Display Driver Development Guide V1.0
rockchip_drm_integration_helper-zh
3399 lcd配置:https://blog.csdn.net/kentyu001/article/details/78266280
https://blog.csdn.net/qq_41533289/article/details/88872660?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
https://blog.csdn.net/wenjin359/article/details/82693980?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-16.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-16.control
应用层:https://blog.csdn.net/wuu19/article/details/111078502
i2c-tools工具安装
安装以及使用教程:
https://blog.csdn.net/anyuliuxing/article/details/106382827?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-7.control
1.下载
直接下载 https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/
或克隆下了
git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git
2.编译
将i2c工具解压到/home/jelly/rv1126_rv1109_linux_210301/external/路径
修改makefile
CC ?= arm-linux-gnueabihf-gcc
AR ?= arm-linux-gnueabihf-ar
STRIP ?= arm-linux-gnueabihf-strip
编译
make USE_STATIC_LIB=1 && make install
3.编译sdk并烧录到板子即可
使用
1.查地址
i2cdetect -a 3
2.查寄存器的值
i2cdump -f -y 3 0x10
i2cset和i2cget使用方法:
i2cset -f -y 1 0x20 0x77 0x3f (设置i2c-1上0x20器件的0x77寄存器值为0x3f)
i2cget -f -y 1 0x20 0x77 (读取i2c-1上0x20器件的0x77寄存器值)
TP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3VGPjvf-1628238375555)(RV1126.assets/image-20210518140837081.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FacHIInf-1628238375557)(RV1126.assets/image-20210518141936054.png)]
1.在kernel 中找到gt911的驱动源码路径
/home/jelly/rv1126_rv1109_linux_210301/kernel/drivers/input/touchscreen/gt9xx
(如果没有驱动程序的话需要原厂提供,最好连dts,makefile,kconfig一起提供)
makefile 添加
obj-$(CONFIG_TOUCHSCREEN_GT9XX_V2_8) += gt9xx_v2.8.0.2/
Kconfig
#
# Goodix GT9xx Touchscreen driver
#
config TOUCHSCREEN_GT9XX_2_8
tristate "Goodix touchpanel GT9xx series"
depends on I2C
help
Say Y here if you have a Goodix GT9xx touchscreen
controller.
If unsure, say N.
config TOUCHSCREEN_GT9XX_2_8_UPDATE
tristate "Goodix GT9xx touch controller auto update support"
depends on TOUCHSCREEN_GT9XX_2_8
default y
help
Enable this for support firmware update.
Say Y here if you want update touch controller firmware.
If unsure, say N.
config TOUCHSCREEN_GT9XX_2_8_TOOL
tristate "Goodix GT9xx Tools for debuging"
depends on TOUCHSCREEN_GT9XX_2_8
default y
help
This implement interface support for Goodix GT9xx
touchscreen debug.
Say Y here if you want to have a Android app debug interface
to your system.
If unsure, say N.
上层kconfig
bool "TOUCHSCREEN_GT9XX_V2_8"
help
Say Y here, and a list of supported touchscreens will be displayed.
This option doesn't affect the kernel.
If unsure, say Y.
if TOUCHSCREEN_GT9XX_V2_8
source "drivers/input/touchscreen/gt9xx_v2.8.0.2/Kconfig"
endif
2.配置内核编译选项,编译gt9xx
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbjzukbM-1628238375559)(RV1126.assets/image-20210519155906377.png)]
3.添加dts配置
驱动官方dts说明文档
Goodix GT9xx series touch controller
Required properties:
- compatible : Should be "goodix,gt9xx", compatible with the
of_match_table defined in driver.
- reg : I2C slave address of the device.
- interrupt-parent : Parent of interrupt.
- interrupts : Configuration of touch panel interrupt controller.
- irq-gpio : Interrupt gpio which is to provide interrupts to
host, same as "interrupts" node.
- rst-gpio : Reset gpio to control the reset of chip.
- irq-flags = <2>; : 1 for rising edge trigger, 2 for failing edge trigger
Optional properties:
- vdd_ana-supply : Power supply needed to power up the device, when use
external regulator, do not add this property.
- vcc_i2c-supply : Power source required to power up i2c bus.
GT9xx series can provide 1.8V from internal
LDO, add this properties base on hardware design.
- pinctrl-names : Pinctrl related properties, generally this is used
for enable irq-gpio output function.
- touchscreen-max-id : generally no need to change this value keep the default
is OK, if you want support active pen this value must
no less then 11.
- touchscreen-key-map : Specify the touch panel key code if you want support
touch buttons on the device surface.
- goodix,int-sync : Set this with 1 if you use non-fixed I2C address.
- goodix,esd-protect : Start ESD check function when driver installed.
- goodix,auto-update-cfg : Update config before firmware update.
- goodix,power-off-sleep : Power off when enter sleep mode.
- goodix,pen-suppress-finger : Set to 1 if you want suppress finger touch point
when there have a pen detected.
- goodix,cfg-groupX : Touch screen controller config data group X, where X
represent sensor ID.
Driver supports maximum six config groups. driver
will select config group depending on sensor id.
Example:
gt9xx@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
status = "okay";
interrupt-parent = <&msm_gpio>;
interrupts = <13 0x2800>;
pinctrl-names = "default", "int-output-low","int-output-high", "int-input";
pinctrl-0 = <&ts_int_default>;
pinctrl-1 = <&ts_int_output_low>;
pinctrl-2 = <&ts_int_output_high>;
pinctrl-3 = <&ts_int_input>;
reset-gpios = <&msm_gpio 12 0x0>;
irq-gpios = <&msm_gpio 13 0x2800>;
irq-flags = <2>;
touchscreen-max-id = <11>;
touchscreen-size-x = <1080>;
touchscreen-size-y = <1920>;
touchscreen-max-w = <512>;
touchscreen-max-p = <512>;
touchscreen-key-map = <172>, <158>; /*KEY_HOMEPAGE=172, KEY_BACK=158,KEY_MENU=139*/
goodix,slide-wakeup = <0>;
goodix,type-a-report = <0>;
goodix,driver-send-cfg = <0>;
goodix,resume-in-workqueue = <0>;
goodix,int-sync = <1>;
goodix,swap-x2y = <0>;
goodix,esd-protect = <1>;
goodix,auto-update-cfg = <0>;
goodix,power-off-sleep = <0>;
goodix,pen-suppress-finger = <0>;
goodix,cfg-group0 = [
53 D0 02 00 05 05 F5 D5 21 48 2D 0F 5A 41 0E 05 00 00 32 32 20 00 05 14 14 1A 14 8B 2B 00
];
};
根据原理图配置dts
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@28 {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
};
4.调试
https://blog.csdn.net/qwe15954250805/article/details/80642446?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-10.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-10.control
查看中断
cat /proc/interrupts
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iqqvvnkW-1628238375560)(RV1126.assets/image-20210519115049866.png)]
怎么理解代码
关键结构体解析:
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
type: 上报事件的类型
EV_SYN: 同步事件
EV_KEY:键盘事件
EV_REL: 相对坐标事件-鼠标
EV_ABS: 绝对坐标事件-触摸屏
我们解析一个input event 时,首先要确定type属性,code和value属性都是根据不同的type有不同的含义(在不同的前缀下,找对应的含义)
code: 不同的type,code有不同的含义
type = EV_KEY时,code代表键盘以及鼠标上不同的按键,如code = 9,表示此时event上报的是键盘上数字“9”对应的事件;code = 46,表示此时event上报的是键盘上字母"C“对应的事件
type = EV_REL时,code代表轨迹的类型,指示鼠标移动的方向,如code = 3,表示此时event上报的是鼠标向X轴移动的数据;当code = 4时,表示此时event上报的时鼠标向Y轴移动的数据。
type = EV_ABS时,code代表触摸坐标轴,如code = 0x35 ,表示此时的event上报的就是当前触摸点X轴的坐标;code = 0x36,表示此时的event 上报的就是当前触摸点Y轴的坐标。
value: 不同的code,value有不同的含义(tpye是根),举几个列子:
type = EV_KEY,code = 9, value = 0:表示键盘上数字”9“被放开
type = EV_KEY,code = 9, value = 1:表示键盘上数字”9“被按下
type = EV_ABS,code = 0x35, value = 128:表示触摸点的X轴坐标为128
type = EV_ABS,code = 0x36,value = 560;表示触摸点的Y轴坐标为560
type = EV_ABS, code = 0x3a, value = 50: 表示触摸点的压力值为50
type = EV_ABS, code = 0x39,value = 0: 表示该触摸点的ID = 0,在多点触控式与其他触摸点区分。
每次事件的上报之后还需要完成一次同步上报,通常情况下,同步有固定的格式:
type = 0,code = 0, value = 0:表示同步
type = 0,code = 2, value = 0;表示MT同步
对于触摸屏来说,上面的分析已经涵盖了同步、坐标、压力、多点触控区分等信息了,但是还缺少接触触摸屏和离开触摸屏两个信息。其实,这两个信息是必不可少的信息,对于不同的触控IC有不用的实现(tpye、code、value)。我使用的触控IC是汇顶科技的gt1x系列,在驱动中通过如下事件区分接触和离开触摸屏事件:
type = 1,code = 330 , value = 1 :表示接触触摸屏
type = 1,code = 330 , value = 0 :表示离开触摸屏
gt9xx代码中,事件类型的定义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7mXUoiTI-1628238375562)(RV1126.assets/image-20210519155123354.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwCdiC8m-1628238375564)(RV1126.assets/image-20210519155143827.png)]
可以看出0x35代表x坐标,0x36代表y坐标
调试代码
#include <stdio.h>
#include <linux/input.h>
static int event1_fd = -1;
struct input_event ev0[64];
static int handle_event1()
{
int button = 0, realx=0, realy=0, i, rd;
rd = read(event1_fd, ev0, sizeof(struct input_event)* 64);
if(rd < sizeof(struct input_event)) return 0;
for(i=0;i<rd/sizeof(struct input_event); i++)
{
if(EV_ABS == ev0[i].type)
{
if(ev0[i].code == 53) {
realx = ev0[i].value;
} else if(ev0[i].code == 54) {
realy = ev0[i].value;
}
}
printf("event(%d):type:%d; code:%3d; value:%3d; realx:%3d; realy:%3d\n",i,ev0[i].type,ev0[i].code,ev0[i].value,realx,realy);
}
return 1;
}
int main(void)
{
int done = 1;
event1_fd = open("/dev/input/event1",02);
if(event1_fd <0) {
printf("open input device error\n");
return -1;
}
while (done)
{
printf("begin handle_event1...\n");
done = handle_event1();
printf("end handle_event1...\n");
}
if(event1_fd > 0)
{
close(event1_fd);
event1_fd = -1;
}
return 0;
}
留下的疑问:
为什么地址0x28不行,反而用地址用0x5d可以,官方例程用的是5d?
lunch rk3568_r-userdebug
make ARCH=arm64 rockchip_defconfig rk356x_evb.config android-11.config;
make ARCH=arm64 rk3568-evb1-ddr4-v10.img -j24;
配置编译工具
1.su root
2.gedit ~/.bashrc
3.添加交叉编译链工具路径:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf- PATH=$PATH:/home/jelly/rv1126_rv1109_linux_210301/prebuilts/gcc/linux-x86/arm/gcc- arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
4.source ~/.bashrc
编译应用程序
1.配置编译工具环境变量
2.包含头文件的方式
https://blog.csdn.net/liuxiangxxl/article/details/89212291
-l参数指定程序要链接的库,如库名字为libtest.so,则编译时加-ltest参数。放在/lib与/usr/lib与/usr/local/lib中的库可直接链接之,若不在这三个目录,用-L参数指定之如:-L /home/zzhiyuan/demo -ltest。
若程序用头文件未在/usr/include则用-I参数指定之。如:-I /home/zzhiyuan/myinclude。
arm-linux-gnueabihf-gcc linux_pcm_save.c -o 123 -I /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include -L /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/lib/ -lasound
2.编译
arm-linux-gnueabihf-gcc -o hello.exe hello.c
alsa
https://blog.csdn.net/xiaolong1126626497/article/details/108739508?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
调试
查看音频驱动注册情况
cat /proc/asound/pcm
alsa-lib,alsa-utils移植
下载alsa-lib库
https://www.alsa-project.org/wiki/Download
编译alsa-lib库
1.配置
CC=arm-linux-gnueabihf-gcc ./configure --host=arm-linux-gnueabihf --prefix=/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build --enable-static --enable-shared --disable-python --with-configdir=/usr/local/share/alsa --with-plugindir=/usr/local/lib/alsa_lib
注意:要动态编译,不然可能会失败
2.编译
make
3.安装
make install
编译alsa-utils
1.配置
CC=arm-linux-gnueabihf-gcc ./configure --host=arm-linux-gnueabihf-gcc --prefix=/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build --enable-shared CFLAGS="-I/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include" LDFLAGS="-L/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/lib -lasound" --disable-alsamixer --disable-xmlto --with-alsa-inc-prefix=/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include
2.编译
make
3.安装
make install
安装到嵌入式平台
alsa 配置文件asound.conf
https://blog.csdn.net/weixin_41965270/article/details/81272710?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
运行测试程序
编写应用程序
参考:https://blog.csdn.net/xiaolong1126626497/article/details/105368195?utm_medium=distribute.pc_relevant_download.none-task-blog-baidujs-4.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-baidujs-4.nonecase
编译应用程序
-l参数指定程序要链接的库,如库名字为libtest.so,则编译时加-ltest参数。放在/lib与/usr/lib与/usr/local/lib中的库可直接链接之,若不在这三个目录,用-L参数指定之如:-L /home/zzhiyuan/demo -ltest。
若程序用头文件未在/usr/include则用-I参数指定之。如:-I /home/zzhiyuan/myinclude。
arm-linux-gnueabihf-gcc linux_pcm_save.c -o 123 -I /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include -L /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/lib/ -lasound
应用程序解析
配置解析:
https://www.alsa-project.org/wiki/Asoundrc
本文就以树的结构来分析一下pcm流建立的过程。
default树
为了简便起见,下面就称第一颗树为capture树,第二颗为default树。
int snd_pcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)
{
int err;
assert(pcmp && name);
//刷新/system/usr/share/alsa/alsa.conf文件内容到snd_config_t结构中,构建配置树
err = snd_config_update();
if (err < 0)
return err;
//真正执行树创建的例程
return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);
}
该函数主要完成如下两步:
第一步:构建配置树
第二步:创建PCM流
点击录音时传入的name为AndroidCapture(其它模式类似),在第二步中根据传入的name参数在配置树中查找对应的snd_config_t结点。根据我们的配置asla-lib.conf,查找到capture树。
下面看一下这个函数,
snd_pcm_open_noupdate
会调用到这里
static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
snd_config_t *pcm_root, snd_config_t *pcm_conf,
snd_pcm_stream_t stream, int mode);
这个函数的功能是取下pcm_conf配置树中type孩子结点对应的字符串值,并利用该字符串构造一新的函数并调用。在我们的系统中可以简单地这样理解。下面以capture树为例说明一下。
snd_pcm_open-->snd_pcm_open_noupdate-->snd_pcm_open_conf
此时传入的 pcm_conf配置树为capture树,它会取下type孩子结点的字符串str(hooks),构建函数名sprintf(open_name, “snd_pcm%s_open”, str);之后调用函数snd_pcm_hooks_open.下snd_pcm_open的主要流程:
_snd_pcm_hooks_open-->_snd_pcm_empty_open--->_snd_pcm_plug_open--->_snd_pcm_hw_open
结合capture树和default树,不难看出,后三个函数名也是用类似构造snd_pcm_hook_open的方法生成的,之后调用。事实确 实是这样的,在snd_pcm_open过程中多次调用snd_pcm_open_conf只是每次传入的pcm_conf配置树不一样而已。那么我们的 default树是如何获取的呢?
在snd_pcm_hook_open中会查找capture树的slave孩子结点,并将slave的pcm子结点的str(default)作为 新的name重新调用snd_pcm_open_noupdate.然后根据name参数在配置树中查找到default对应的结点,即default 树。
前面说过snd_pcm_open_noupdate会调用到snd_pcm_open_conf,由此不难想象到它会构造 snd_pcm_empty_open,并调用它。之后snd_pcm_plug_open–>snd_pcm_hw_open函数的构造 也是类似的这里都不多介绍了。读者可认真看一下snd_pcm_xxx_open,会发现它都会调用到snd_pcm_open_conf函数来加载下 一层的type xxxx.就这样对default树进行逐层分析.
_snd_pcm_hooks_open-->_snd_pcm_empty_open->_snd_pcm_plug_open->_snd_pcm_hw_open
上面是我给大家介绍的重点之一。
此流程执行完,也要逐层返回,在snd_pcm_hooks_open/snd_pcm_plug_open/snd_pcm_hw_open三层分别还会创建三种类型的pcm流对象和它的私有数据成员及和它对应的函数集。
下面就从里到外顺序介绍一下相关代码,先看一下hw层
…
//pcm_hw.c 创建类型为SND_PCM_TYPE_HW的pcm流
ret = snd_pcm_new(&pcm, SND_PCM_TYPE_HW, name, info.stream, mode);
if (ret < 0) {
free(hw);
close(fd);
return ret;
}
//HW层的函数集
pcm->ops = &snd_pcm_hw_ops;
pcm->fast_ops = &snd_pcm_hw_fast_ops;
//snd_pcm_hw_t结构hw作为私有数据成员,存储一些信息。
pcm->private_data = hw;
//打开/dev/snd/pcmC0D0c
pcm->poll_fd = fd;
....
返回plug层
//pcm_plug.c
int snd_pcm_plug_open(snd_pcm_t **pcmp,
const char *name,
snd_pcm_format_t sformat, int schannels, int srate,
const snd_config_t *rate_converter,
enum snd_pcm_plug_route_policy route_policy,
snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_ssize,
unsigned int tt_cused, unsigned int tt_sused,
snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
snd_pcm_plug_t *plug;
int err;
assert(pcmp && slave);
//分配私有数据成员
plug = calloc(1, sizeof(snd_pcm_plug_t));
if (!plug)
return -ENOMEM;
plug->sformat = sformat;
plug->schannels = schannels;
plug->srate = srate;
plug->rate_converter = rate_converter;
//将HW层的pcm流对象存放在PLUG层pcm流的私有数据成员中
plug->gen.slave = plug->req_slave = slave;
plug->gen.close_slave = close_slave;
plug->route_policy = route_policy;
plug->ttable = ttable;
plug->tt_ssize = tt_ssize;
plug->tt_cused = tt_cused;
plug->tt_sused = tt_sused;
//创建SND_PCM_TYPE_PLUG类型的pcm流对象
err = snd_pcm_new(&pcm, SND_PCM_TYPE_PLUG, name, slave->stream, slave->mode);
if (err < 0) {
free(plug);
return err;
}
//PLUG层函数集
pcm->ops = &snd_pcm_plug_ops;
pcm->fast_ops = slave->fast_ops;
pcm->fast_op_arg = slave->fast_op_arg;
//plug关联到私有成员中
pcm->private_data = plug;
pcm->poll_fd = slave->poll_fd;
pcm->poll_events = slave->poll_events;
pcm->mmap_shadow = 1;
pcm->monotonic = slave->monotonic;
snd_pcm_link_hw_ptr(pcm, slave);
snd_pcm_link_appl_ptr(pcm, slave);
*pcmp = pcm;
return 0;
}
最后再来看一下HOOKS层
//pcm_hooks.c
int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
snd_pcm_hooks_t *h;
unsigned int k;
int err;
assert(pcmp && slave);
//分配私有成员空间
h = calloc(1, sizeof(snd_pcm_hooks_t));
if (!h)
return -ENOMEM;
//寄存PLUG层的pcm流对象
h->gen.slave = slave;
h->gen.close_slave = close_slave;
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
INIT_LIST_HEAD(&h->hooks[k]);
}
//SND_PCM_TYPE_HOOKS类型的pcm流对象创建
err = snd_pcm_new(&pcm, SND_PCM_TYPE_HOOKS, name, slave->stream, slave->mode);
if (err < 0) {
free(h);
return err;
}
//HOOKS层函数集
pcm->ops = &snd_pcm_hooks_ops;
pcm->fast_ops = &snd_pcm_hooks_fast_ops;
//关联私有数据
pcm->private_data = h;
pcm->poll_fd = slave->poll_fd;
pcm->poll_events = slave->poll_events;
pcm->mmap_shadow = 1;
pcm->monotonic = slave->monotonic;
snd_pcm_link_hw_ptr(pcm, slave);
snd_pcm_link_appl_ptr(pcm, slave);
*pcmp = pcm;
return 0;
}
由此可见,在整个过程中创建了三种类型的pcm流对象,HOOKS,PLUG,HW
_snd_pcm_hooks_open-->_snd_pcm_empty_open--->_snd_pcm_plug_open--->_snd_pcm_hw_open
层层递进分析配置树
_snd_pcm_hooks_open<--....................................<---_snd_pcm_plug_open<--_snd_pcm_hw_open
层层回溯。
回溯过程依次创建了HW pcm–>PLUG pcm–>HOOKS pcm及和它们区配的私有数据及相关操作函数集,而且可以通过HOOKS层的pcm流,查找到plug,hw的pcm.它们都被寄存在上层的private_data成员中。如下图
时知道调用的是
至此返回_snd_pcm_hooks_open,下面这个函数还会对capture树的hooks孩子结点分析。
static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_t *conf)
它类似snd_pcm_open_conf,它会调用 _snd_pcm_hook_ctl_elems_install–>snd_ctl_open打开对应的
/dev/snd /ControlC0(snd_ctl_open和snd_pcm_open类似都是通过传入字符串查找配置树,然后分析找开设备之类操作),执行成功能 会带回一个snd_sctl_t结构类型对象。
由此可以PCM流打开需要两步:snd_pcm_open /dev/snd/pcmC0D0c 的打开和snd_ctl_open /dev/snd/ControlC0的打开,两个设备文件。
之后_snd_pcm_hook_ctl_elems_install->snd_sctl_build,但是根据我们的配置在这里会返回错误信 息(snd_sctl_build会添加hook_args下面所有的参数信息并生成一个新的snd_sctl_t对象(add_elem),就是在添加 参数信息时我们的配置有问题,所以出错返回)。错误发生,会释放HOOKS层的pcm流对象,级联PLUG和HW层。最终snd_pcm_open会返回 错误信息。pcm流创建失败。
这是我们系统中snd_pcm_open的整个流程,虽然这里创建失败但是可以让我们清晰地认识流创建过程:它是一个分层的流建立过程。 hooks->plug->hw(pcm) 及hooks->empty->plug->hw函数层次调用过程。
这个层次结构就是我给大家介绍的第二个要点,特别是多种pcm流类型,及它们相互引用和各自的私有数据成员及对应的函数操作集。有了这个认识,我们才能在pcm->fast_ops->read(…)时知道调用的是哪一层的函数集。
虽然这里创建PCM流失败,但是我们的系统会有另一种方案重新创建default pcm流。可以参考我们系统中流的创建过程。
移植参考链接:
https://blog.csdn.net/RopenYuan/article/details/8078100
shell脚本框架
#!/bin/bash
export LC_ALL=C
unset RK_CFG_TOOLCHAIN
#进入要操作的路径
TOP_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
IMAGE_PATH=$TOP_DIR/rockdev
echo "$IMAGE_PATH"
cd $IMAGE_PATH
#指令帮助信息
function usage()
{
echo "Usage: dowload.sh [OPTIONS]"
echo "Available options:"
echo "loader -upgrade MiniLoaderAll.bin"
echo "parameter -upgrade parameter.txt"
echo "uboot -upgrade uboot.img"
echo "boot -upgrade boot.img"
echo "recovery -upgrade recovery.img"
echo "misc -upgrade misc.img"
echo "oem -upgrade oem.img"
echo "userdata -upgrade userdata.img"
echo "rootfs -upgrade rootfs.img"
echo "rd -restart sys"
echo "all -upgrade all img"
echo ""
}
#各个函数实现
function upgrade_loader()
{
sudo upgrade_tool ul MiniLoaderAll.bin
echo "sudo upgrade_tool ul MiniLoaderAll.bin"
}
function upgrade_parameter()
{
sudo upgrade_tool di -p parameter.txt
echo "sudo upgrade_tool di -p parameter.txt"
}
function upgrade_uboot()
{
sudo upgrade_tool di -uboot uboot.img
echo "sudo upgrade_tool di -uboot uboot.img"
}
function upgrade_boot()
{
sudo upgrade_tool di -b boot.img
echo "sudo upgrade_tool di -b boot.img"
}
function upgrade_recovery()
{
sudo upgrade_tool di -r recovery.img
echo "sudo upgrade_tool di -r recovery.img"
}
function upgrade_misc()
{
sudo upgrade_tool di -m misc.img
echo "sudo upgrade_tool di -m misc.img"
}
function upgrade_oem()
{
sudo upgrade_tool di -oem oem.img
echo "sudo upgrade_tool di -oem oem.img"
}
function upgrade_userdata()
{
sudo upgrade_tool di -userdata userdata.img
echo "sudo upgrade_tool di -userdata userdata.img"
}
function upgrade_rootfs()
{
sudo upgrade_tool di -rootfs rootfs.img
echo "sudo upgrade_tool di -rootfs rootfs.img"
}
function upgrade_rd()
{
sudo upgrade_tool rd
echo "sudo upgrade_tool rd"
}
function upgrade_all()
{
upgrade_loader
upgrade_parameter
upgrade_uboot
upgrade_boot
upgrade_recovery
upgrade_misc
upgrade_oem
upgrade_userdata
upgrade_rootfs
upgrade_rd
}
#=========================
# build targets
#=========================
if echo $@|grep -wqE "help|-h"; then
if [ -n "$2" -a "$(type -t usage$2)" == function ]; then
echo "###Current SDK Default [ $2 ] Build Command###"
eval usage$2
else
usage
fi
exit 0
fi
#执行相关指令调用相关函数
OPTIONS="$@"
for option in ${OPTIONS}; do
echo "processing option: $option"
case $option in
loader) upgrade_loader ;;
parameter) upgrade_parameter ;;
uboot) upgrade_uboot ;;
boot) upgrade_boot ;;
recovery) upgrade_recovery ;;
misc) upgrade_misc ;;
oem) upgrade_oem ;;
userdata) upgrade_userdata ;;
rootfs) upgrade_rootfs ;;
rd) upgrade_rd ;;
all) upgrade_all ;;
*) usage ;;
esac
done
【ALSA】 asound.conf 插件讲解
https://blog.csdn.net/qq_31811537/article/details/103800745?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-2.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-2.nonecase
查询log关键字
dmesg命令用于打印Linux系统开机启动信息,kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看(print or control the kernel ring buffer)。开机信息亦保存在/var/log/dmesg的文件里
格式:dmesg
查看开机信息。
搜索开机信息:dmesg | grep xxx(需要查找的字符)
格式:dmesg -c
清除开机信息,但/var/log/dmesg文件中仍然有这些信息。
1、使用grep命令进行筛选:
如:grep -i “http” /var/log/messages,可以查询出现“http”的所有行。
2、使用cat加grep查询
如: cat /var/log/messages | grep “http”,和上面一样的功能。
修改kernel 的编译的config文件
1.修改BoardConfig.mk
路径:device/rockchip/rv1126_rv1109/BoardConfig.mk
修改 TARGET_KERNEL_CONFIG
TARGET_KERNEL_CONFIG =zk_rv1126_config
2.将配置好的config文件考到 arch/arm/configs/zk_rv1126_config 路径
我这里写一个脚本做这个事
#!/bin/bash
export LC_ALL=C
unset RK_CFG_TOOLCHAIN
TOP_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
echo "$IMAGE_PATH"
make ARCH=arm zk_rv1126_config
make ARCH=arm menuconfig
make ARCH=arm savedefconfig
cp zk_rv1126_config arch/arm/configs/zk_rv1126_config
make
cd ../
./mkfirmware.sh
#./dowload.sh
以后编译kernel的时候就会配置zk_rv1126_config 文件为编译的文件啦
需要注意,每次修改config后要保存成zk_rv1126_config 的名字
或者更改配置后直接保存
make menuconfig
make savedefconfig
就可以编译最新的配置
添加开机启动脚本
我们都了解**/etc/init.d/**目录下的所有文件都是脚本文件,这个目录下的脚本文件,在设置好开机自启动项后,在开机时会自动执行。
1.在根目录下创建beyond.sh文件
vi beyond.sh
2.保存完脚本后,使用chmod设置可执行权限:
chmod +x beyond.sh
3.然后将其拷贝到/etc/init.d/目录下,否则添加服务不成功:
cp beyond.sh /etc/init.d/
4.进入/etc/init.d/目录下:
cd /etc/init.d/
5.将beyond.sh添加到系统服务:
chkconfig --add beyond.sh
6.设置开机启动:
chkconfig beyond.sh on
8.然后重启linux:
reboot
8.重启之后连接查看效果:rds换成自己的服务
ps -ef | grep rds
登录evb板的调试方式
网络
注意:
1.通过SSH登陆EVB板调试
### 清除上次登陆信息(EVB板的IP地址192.168.163.222)
ssh-keygen -f "$HOME/.ssh/known_hosts" -R 192.168.163.222
### 使用SSH命令登陆
ssh root@192.168.163.222
### 输入默认密码:rockchip
2.通过SCP调试
### 从PC端上传文件test-file到EVB板的目录/userdata
scp test-file root@192.168.163.222:/userdata/
root@192.168.163.222's password:
### 输入默认密码:rockchip
### 下载EVB板上的文件/userdata/test-file下载到PC端
scp root@192.168.163.222:/userdata/test-file test-file
root@192.168.163.222's password:
### 输入默认密码:rockchip
3.通过网络ADB调试
### 获取EVB板的IP地址192.168.163.222
adb connect 192.168.163.222
adb devices
List of devices attached
192.168.163.222:5555 device
### adb登陆EVB板子调试
adb -s 192.168.163.222:5555 shell
### 从PC端上传文件test-file到EVB板的目录/userdata
adb -s 192.168.163.222:5555 push test-file /userdata/
### 下载EVB板上的文件/userdata/test-file下载到PC端
adb -s 192.168.163.222:5555 pull /userdata/test-file test-file
usb
1.adb shell
2.串口
拷贝应用程序到板子
(dowload.sh 脚本的一段程序)
function adb_push()
{
adb connect 192.168.163.222
adb devices
adb -s 192.168.163.222:5555 push adb-file /userdata/
finish_build
}
调试PHY网口
设置板子IP
静态
切换到/etc/network文件夹,找到interfaces文件
vi /etc/network/interfaces
#添加:
auto eth0
iface eth0 inet static
address 192.168.163.222
netmask 255.255.255.0
gateway 192.168.163.1
动态
使用ifconfig命令配置
ifconfig eth0 192.168.163.222 netmask 255.255.255.0
使用route命令配置网关
route add default gw 192.168.163.1
配置完成后使用以下命令进行重启即可
/etc/init.d/S40network restart
补充:若网卡eth0 未开启,可使用以下命令开启
ifconfig eth0 up//开启eth0网卡
ifconfig eth0 down//关闭eth0网卡
查找电脑链接的ip
arp -a
虚拟机系统链接网络设置
1.设置成链接到主机模式
2.将/etc/network/interfaces,里面的静态ip设置注释掉
关于CONFIG_OF
最近在调i2c驱动,看到了很多 #ifdef CONFIG_OF 的宏条件,但在各个头文件中都没有找到CONFIG_OF,后来发现这和内核设备树有关;
在内核的 arch/arm/Kconfig中有 select OF 这一项:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBbe4ida-1628238375569)(RV1126.assets/image-20210519140528250.png)]
上面显示它在菜单 Boot options 里,于是我在内核目录下make menuconfig ,再选择Boot options,将Flattened Device Tree sopport 选中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJa9zpPk-1628238375572)(RV1126.assets/image-20210519140548821.png)]
也不知道到底是不是这样,(#.#),错了的话,还望有大佬能指正。
————————————————
版权声明:本文为CSDN博主「小辉。?」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43772810/article/details/109554607
安检门DTSI
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*/
#include "rv1126-evb-v13.dtsi"
/ {
es7243e_sound_1: es7243e-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243e";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243e_0
//&es7243e_1
//&es7243e_2
//&es7243e_3
>;
};
};
/*es7243e_sound: es7243e-sound {
status = "okay";
compatible = "rockchip,multicodecs-card";
rockchip,card-name = "rockchip,es7243e";
rockchip,mclk-fs = <768>;
rockchip,cpu = <&i2s0_8ch>;
rockchip,codec = <&es7243e_0>;
};*/
es7243e_sound_2: es7243e-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243e";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s2_2ch>;
};
simple-audio-card,codec {
sound-dai = <&es7243e_5>;
};
};
es7243e_sound_3: es7243e-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243e";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = < &i2s1_2ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243e_4>;
};
};
};
/*&wireless-bluetooth {
status = "okay";
};*/
&wireless_wlan {
clocks = <&rk809 1>;
//WIFI,poweren_gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
//WIFI,host_wake_irq = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
wifi_chip_type = "rtl8723ds";
status = "okay";
};
&sdio {
//max-frequency = <50000000>;
status = "okay";
};
//debug uart
&fiq_debugger {
status = "okay";
compatible = "rockchip,fiq-debugger";
rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */
};
&ar0230 {
status = "disabled";
};
&ov4689 {
status = "disabled";
};
&os04a10 {
status = "disabled";
};
&rk809_sound {
status = "disabled";
};
/********************************************************************************************/
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
//if use zhaji board open this
//pinctrl-0 = <&pwm10m1_pins_pull_down>;
pinctrl-0 = <&pwm10m0_pins_pull_down>;
//pinctrl-0 = <&pwm9m1_pins_pull_down>;
};
&pwm3 {
status = "disabled";
};
//SHENZHEN FRIDA LCD CO.,LTD Model No:FRD700B30012-B
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "frida,ek79007ad", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <154>;
height-mm = <86>;
panel-init-sequence = [
15 00 02 80 8b
15 00 02 81 78
15 00 02 82 84
15 00 02 83 88
15 00 02 84 a8
15 00 02 85 ae
15 00 02 86 88
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <51000000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hsync-len = <70>;
hback-porch = <90>;
vfront-porch = <12>;
vsync-len = <10>;
vback-porch = <13>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&uart0 {
status = "okay";
};
/*********************************************************************************/
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@5d {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
//rtc zt0701
sd3078@32 {
status = "okay";
compatible = "rockchip,sd3078";
reg = <0x32>;
};
};
/************************************************************************************/
//Dts 的 codec 的i2c部分:
//Dts 的 platform 的 i2s 部分:
//i2c adapter3 信息
&i2c3{
clock-frequency = <400000>;//设置传输速率 400k
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_xfer>;
status = "okay";
es7243e_0: es7243e_0@10{
status = "okay";
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
pinctrl-0 = <&i2s0m1_mclk>;
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
};
es7243e_1: es7243e_1@11{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x11>;
};
es7243e_2: es7243e_2@13{
#sound-dai-cells = <0>;
compatible = "MicArray_2";
reg = <0x13>;
};
es7243e_3: es7243e_3@12{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x12>;
};
};
&i2c1{
clock-frequency = <400000>;//设置传输速率 400k
//i2c-scl-rising-time-ns = <280>;
//i2c-scl-falling-time-ns = <16>;
status = "okay";
es7243e_4: es7243e_4@11{
#sound-dai-cells = <0>;
compatible = "MicArray_4";
reg = <0x10>;
clocks = <&cru MCLK_I2S1_OUT2IO>;
clock-names = "mclk";
//pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S1_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S1>;
//pinctrl-0 = <&i2s1m1_mclk>;
};
es7243e_5: es7243e_5@13{
#sound-dai-cells = <0>;
compatible = "MicArray_5";
reg = <0x12>;
clocks = <&cru MCLK_I2S2_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S2_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S2>;
pinctrl-0 = <&i2s2m1_mclk>;
};
};
&i2s0_8ch {
status = "okay";
#sound-dai-cells = <0>;
rockchip,clk-trcm = <2>;
rockchip,mclk-calibrate;
rockchip,i2s-rx-route = <0 1 2 3>;
pinctrl-names = "default";
pinctrl-0 = <
//&i2s0m1_mclk
//&i2s0m1_sclk_tx
&i2s0m1_sclk_rx
//&i2s0m1_lrck_tx
&i2s0m1_lrck_rx
&i2s0m1_sdi0
//&i2s0m1_sdo0
&i2s0m1_sdo1_sdi3
&i2s0m1_sdo2_sdi2
&i2s0m1_sdo3_sdi1>;
};
&i2s1_2ch {
status = "okay";
#sound-dai-cells = <0>;
//rockchip,bclk-fs: configure the i2s bclk fs.
rockchip,clk-trcm = <0>; //tx and rx lrck/bclk common use.
pinctrl-names = "default";
pinctrl-0 = <&i2s1m1_sclk
&i2s1m1_lrck
//&i2s1m1_sdo
&i2s1m1_sdi
&i2s1m1_mclk //zhe li bu zhushi yinping shebei chubulai ,haibu zhidao weishenme?
>;
};
&i2s2_2ch {
status = "okay";
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s2m1_sclk
&i2s2m1_lrck
//&i2s2m1_sdo
&i2s2m1_sdi
//&i2s2m1_mclk
>;
};
/*********************************************************************************************/
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = "okay";
phy: phy@0 {
status = "okay";
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
zk_ajm_rv1126_v1.dtsi(闸机板子)
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*/
#include "rv1126-evb-v13.dtsi"
/ {
es7243_sound: es7243-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&es7243_0
&es7243_1
&es7243_2
&es7243_3>;
};
};
wireless-bluetooth {
status = "okay";
};
wireless_wlan: wireless-wlan {
wifi_chip_type = "rtl8723ds";
status = "okay";
};
};
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&pwm10m1_pins_pull_down>;
};
&pwm3 {
status = "disabled";
};
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "ilitek,ili9881d", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <62>;
height-mm = <110>;
panel-init-sequence = [
39 00 04 ff 98 81 03
15 00 02 01 00
15 00 02 02 00
15 00 02 03 73
15 00 02 04 00
15 00 02 05 00
15 00 02 06 0a
15 00 02 07 00
15 00 02 08 00
15 00 02 09 01
15 00 02 0a 00
15 00 02 0b 00
15 00 02 0c 01
15 00 02 0d 00
15 00 02 0e 00
15 00 02 0f 1d
15 00 02 10 1d
15 00 02 11 00
15 00 02 12 00
15 00 02 13 00
15 00 02 14 00
15 00 02 15 00
15 00 02 16 00
15 00 02 17 00
15 00 02 18 00
15 00 02 19 00
15 00 02 1a 00
15 00 02 1b 00
15 00 02 1c 00
15 00 02 1d 00
15 00 02 1e 40
15 00 02 1f 80
15 00 02 20 06
15 00 02 21 02
15 00 02 22 00
15 00 02 23 00
15 00 02 24 00
15 00 02 25 00
15 00 02 26 00
15 00 02 27 00
15 00 02 28 33
15 00 02 29 03
15 00 02 2a 00
15 00 02 2b 00
15 00 02 2c 00
15 00 02 2d 00
15 00 02 2e 00
15 00 02 2f 00
15 00 02 30 00
15 00 02 31 00
15 00 02 32 00
15 00 02 33 00
15 00 02 34 04
15 00 02 35 00
15 00 02 36 00
15 00 02 37 00
15 00 02 38 3c
15 00 02 39 35
15 00 02 3a 01
15 00 02 3b 40
15 00 02 3c 00
15 00 02 3d 01
15 00 02 3e 00
15 00 02 3f 00
15 00 02 40 00
15 00 02 41 88
15 00 02 42 00
15 00 02 43 00
15 00 02 44 1f
15 00 02 50 01
15 00 02 51 23
15 00 02 52 45
15 00 02 53 67
15 00 02 54 89
15 00 02 55 ab
15 00 02 56 01
15 00 02 57 23
15 00 02 58 45
15 00 02 59 67
15 00 02 5a 89
15 00 02 5b ab
15 00 02 5c cd
15 00 02 5d ef
15 00 02 5e 11
15 00 02 5f 01
15 00 02 60 00
15 00 02 61 15
15 00 02 62 14
15 00 02 63 0e
15 00 02 64 0f
15 00 02 65 0c
15 00 02 66 0d
15 00 02 67 06
15 00 02 68 02
15 00 02 69 07
15 00 02 6a 02
15 00 02 6b 02
15 00 02 6c 02
15 00 02 6d 02
15 00 02 6e 02
15 00 02 6f 02
15 00 02 70 02
15 00 02 71 02
15 00 02 72 02
15 00 02 73 02
15 00 02 74 02
15 00 02 75 01
15 00 02 76 00
15 00 02 77 14
15 00 02 78 15
15 00 02 79 0e
15 00 02 7a 0f
15 00 02 7b 0c
15 00 02 7c 0d
15 00 02 7d 06
15 00 02 7e 02
15 00 02 7f 07
15 00 02 80 02
15 00 02 81 02
15 00 02 82 02
15 00 02 83 02
15 00 02 84 02
15 00 02 85 02
15 00 02 86 02
15 00 02 87 02
15 00 02 88 02
15 00 02 89 02
15 00 02 8a 02
39 00 04 ff 98 81 04
//15 00 02 00 80
15 00 02 70 00
15 00 02 71 00
//15 00 02 66 fe
15 00 02 82 0f
15 00 02 84 0f
15 00 02 85 0d
//15 00 02 3a 24
15 00 02 32 ac
15 00 02 8c 80
15 00 02 3c f5
15 00 02 b5 07
15 00 02 31 45
15 00 02 3a 24
15 00 02 88 33
39 00 04 ff 98 81 01
15 00 02 22 09
15 00 02 31 00
15 00 02 53 8a
15 00 02 55 a2
15 00 02 50 81
15 00 02 51 85
//15 00 02 60 20
//15 00 02 61 00
15 00 02 62 0d
//15 00 02 63 00
15 00 02 a0 00
15 00 02 a1 1a
15 00 02 a2 28
15 00 02 a3 13
15 00 02 a4 16
15 00 02 a5 29
15 00 02 a6 1d
15 00 02 a7 1e
15 00 02 a8 84
15 00 02 a9 1c
15 00 02 aa 28
15 00 02 ab 75
15 00 02 ac 1a
15 00 02 ad 19
15 00 02 ae 4d
15 00 02 af 22
15 00 02 b0 28
15 00 02 b1 54
15 00 02 b2 66
//15 00 02 b1 2e
//15 00 02 b2 32
15 00 02 b3 39
15 00 02 c0 00
15 00 02 c1 1a
15 00 02 c2 28
15 00 02 c3 13
15 00 02 c4 16
15 00 02 c5 29
15 00 02 c6 1d
15 00 02 c7 1e
15 00 02 c8 84
15 00 02 c9 1c
15 00 02 ca 28
15 00 02 cb 75
15 00 02 cc 1a
15 00 02 cd 19
15 00 02 ce 4d
15 00 02 cf 22
15 00 02 d0 28
15 00 02 d1 54
15 00 02 d2 66
15 00 02 d3 39
39 00 04 ff 98 81 00
15 00 02 36 03
05 00 01 35
05 00 01 11
05 01 01 29
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <75000000>;
hactive = <720>;
vactive = <1280>;
hfront-porch = <100>;
hsync-len = <33>;
hback-porch = <100>;
vfront-porch = <14>;
vsync-len = <4>;
vback-porch = <14>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&uart0 {
status = "okay";
};
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@5d {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
};
&rk809_sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "rockchip,rk809-codec";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Mic Jack", "MICBIAS1",
"IN1P", "Mic Jack",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&rk809_codec_i2c4>;
};
};
&i2c4 {
status = "okay";
clock-frequency = <400000>;
rk809_codec_i2c4: codec {
#sound-dai-cells = <0>;
compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
pinctrl-0 = <&i2s0m0_mclk>;
hp-volume = <20>;
spk-volume = <3>;
};
};
//Dts 的 codec 的i2c部分:
//Dts 的 platform 的 i2s 部分:
//i2c adapter3 信息
&i2c3{
clock-frequency = <400000>;//设置传输速率 400k
status = "okay";
es7243_0: es7243_0@10{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
clocks = <&cru MCLK_I2S0_RX>;//?还不知道这个时钟要怎么选,明天看看sdk关于i2c的文档怎么搞
clock-names = "mclk";
realtek,in1-differential; //?这是什么意思,没有搞懂啊
};
es7243_1: es7243_1@11{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_RX>;
clock-names = "mclk";
realtek,in1-differential;
};
es7243_2: es7243_2@13{
#sound-dai-cells = <0>;
compatible = "MicArray_2";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_RX>;
clock-names = "mclk";
realtek,in1-differential;
};
es7243_3: es7243_3@12{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x12>;
clocks = <&cru MCLK_I2S0_RX>;
clock-names = "mclk";
realtek,in1-differential;
};
};
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = "okay";
phy: phy@0 {
status = "okay";
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
/*以下部分是rv1126 官方外设DTS部分,用于提供参考*/
/*
i2c0: i2c@ff3f0000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff3f0000 0x1000>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&pmucru CLK_I2C0>, <&pmucru PCLK_I2C0>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c0_xfer>;
status = "disabled";
};
i2c2: i2c@ff400000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff400000 0x1000>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&pmugrf>;
clocks = <&pmucru CLK_I2C2>, <&pmucru PCLK_I2C2>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c2_xfer>;
status = "disabled";
};
i2c1: i2c@ff510000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff510000 0x1000>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_xfer>;
status = "disabled";
};
i2c3: i2c@ff520000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff520000 0x1000>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c3m0_xfer>;
status = "disabled";
};
i2c4: i2c@ff530000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff530000 0x1000>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c4m0_xfer>;
status = "disabled";
};
i2c5: i2c@ff540000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff540000 0x1000>;
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c5m0_xfer>;
status = "disabled";
};
i2s0_8ch: i2s@ff800000 {
compatible = "rockchip,rv1126-i2s-tdm";
reg = <0xff800000 0x1000>;
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru MCLK_I2S0_TX>, <&cru MCLK_I2S0_RX>, <&cru HCLK_I2S0>;
clock-names = "mclk_tx", "mclk_rx", "hclk";
dmas = <&dmac 20>, <&dmac 19>;
dma-names = "tx", "rx";
resets = <&cru SRST_I2S0_TX_M>, <&cru SRST_I2S0_RX_M>;
reset-names = "tx-m", "rx-m";
rockchip,cru = <&cru>;
rockchip,grf = <&grf>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0m0_sclk_tx
&i2s0m0_sclk_rx
&i2s0m0_lrck_tx
&i2s0m0_lrck_rx
&i2s0m0_sdi0
&i2s0m0_sdo0
&i2s0m0_sdo1_sdi3
&i2s0m0_sdo2_sdi2
&i2s0m0_sdo3_sdi1>;
status = "disabled";
}
i2s1_2ch: i2s@ff810000 {
compatible = "rockchip,rv1126-i2s", "rockchip,rk3066-i2s";
reg = <0xff810000 0x1000>;
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru MCLK_I2S1>, <&cru HCLK_I2S1>;
clock-names = "i2s_clk", "i2s_hclk";
dmas = <&dmac 22>, <&dmac 21>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_sclk
&i2s1m0_lrck
&i2s1m0_sdi
&i2s1m0_sdo>;
status = "disabled";
};
i2s2_2ch: i2s@ff820000 {
compatible = "rockchip,rv1126-i2s", "rockchip,rk3066-i2s";
reg = <0xff820000 0x1000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru MCLK_I2S2>, <&cru HCLK_I2S2>;
clock-names = "i2s_clk", "i2s_hclk";
dmas = <&dmac 24>, <&dmac 23>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&i2s2m0_sclk
&i2s2m0_lrck
&i2s2m0_sdi
&i2s2m0_sdo>;
status = "disabled";
};
*/
/*rt5640-sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "rockchip,rt5640-codec";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Mic Jack", "MICBIAS1",
"IN1P", "Mic Jack",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,cpu {
sound-dai = <&i2s_8ch>;//cup dai device
};
simple-audio-card,codec {
sound-dai = <&rt5640>;//codec dai device
};
};
//codec dai device
&i2c1 {
status = "okay";
rt5640: rt5640@1c {
#sound-dai-cells = <0>;
compatible = "realtek,rt5640";
reg = <0x1c>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk";
realtek,in1-differential;
};
};*/
安检门板子DTSI
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*/
#include "rv1126-evb-v13.dtsi"
/ {
es7243_sound_1: es7243-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243_0
&es7243_1
&es7243_2
&es7243_3
>;
};
};
es7243_sound_2: es7243-sound {
status = "disabled";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s2_2ch>;
};
simple-audio-card,codec {
sound-dai = <&es7243_5>;
};
};
es7243_sound_3: es7243-sound {
status = "disabled";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = < &i2s1_2ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243_4>;
};
};
};
/*&wireless-bluetooth {
status = "okay";
};*/
&wireless_wlan {
clocks = <&rk809 0>;
//WIFI,poweren_gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
//WIFI,host_wake_irq = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
wifi_chip_type = "rtl8723ds";
status = "okay";
};
&sdio {
max-frequency = <150000000>;
status = "okay";
};
//debug uart
&fiq_debugger {
//status = "okay";
compatible = "rockchip,fiq-debugger";
rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */
};
&ov4689 {
status = "disabled";
};
&os04a10 {
status = "disabled";
};
&rk809_sound {
status = "disabled";
};
/********************************************************************************************/
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
//if use zhaji board open this
//pinctrl-0 = <&pwm10m1_pins_pull_down>;
pinctrl-0 = <&pwm10m0_pins_pull_down>;
};
&pwm3 {
status = "disabled";
};
//SHENZHEN FRIDA LCD CO.,LTD Model No:FRD700B30012-B
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "frida,ek79007ad", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <154>;
height-mm = <86>;
panel-init-sequence = [
15 00 02 80 8b
15 00 02 81 78
15 00 02 82 84
15 00 02 83 88
15 00 02 84 a8
15 00 02 85 ae
15 00 02 86 88
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <51000000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hsync-len = <70>;
hback-porch = <90>;
vfront-porch = <12>;
vsync-len = <10>;
vback-porch = <13>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&uart0 {
status = "okay";
};
/*********************************************************************************/
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@5d {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
//rtc zt0701
sd3078@32 {
status = "okay";
compatible = "rockchip,sd3078";
reg = <0x32>;
};
};
/************************************************************************************/
//Dts 的 codec 的i2c部分:
//Dts 的 platform 的 i2s 部分:
//i2c adapter3 信息
/* rk809_codec: codec {
#sound-dai-cells = <0>;
compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
pinctrl-0 = <&i2s0m0_mclk>;
hp-volume = <20>;
spk-volume = <3>;
};*/
&i2c3{
clock-frequency = <400000>;//设置传输速率 400k
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_xfer>;
status = "okay";
es7243_0: es7243_0@11{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;//?还不知道这个时钟要怎么选,明天看看sdk关于i2c的文档怎搞
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_1: es7243_1@12{
#sound-dai-cells = <0>;
compatible = "MicArray_2";
reg = <0x12>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_2: es7243_2@10{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_3: es7243_3@13{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
};
&i2c1{
clock-frequency = <400000>;//设置传输速率 400k
//pinctrl-names = "default";
//pinctrl-0 = <&i2c3m1_xfer>;
status = "okay";
es7243_4: es7243_4@11{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
es7243_5: es7243_5@13{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
};
&i2s0_8ch {
status = "okay";
/*#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
rockchip,i2s-rx-route = <3 1 2 0>;*/
pinctrl-names = "default";
pinctrl-0 = <
&i2s0m1_mclk
//&i2s0m1_sclk_tx
&i2s0m1_sclk_rx
//&i2s0m1_lrck_tx
&i2s0m1_lrck_rx
&i2s0m1_sdi0
//&i2s0m1_sdo0
&i2s0m1_sdo1_sdi3
&i2s0m1_sdo2_sdi2
&i2s0m1_sdo3_sdi1>;
};
&i2s1_2ch {
status = "okay";
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = <3 1 2 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s1m1_sclk
&i2s1m1_lrck
&i2s1m1_sdo
&i2s1m1_sdi
&i2s1m1_mclk>;
};
&i2s2_2ch {
status = "okay";
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = <3 1 2 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s2m1_sclk
&i2s2m1_lrck
&i2s2m1_sdo
&i2s2m1_sdi
&i2s2m1_mclk>;
};
/*********************************************************************************************/
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = "okay";
phy: phy@0 {
status = "okay";
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
es7243_2: es7243_2@10{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_3: es7243_3@13{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
};
&i2c1{
clock-frequency = <400000>;//设置传输速率 400k
//pinctrl-names = “default”;
//pinctrl-0 = <&i2c3m1_xfer>;
status = “okay”;
es7243_4: es7243_4@11{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
es7243_5: es7243_5@13{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
};
&i2s0_8ch {
status = “okay”;
/#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
rockchip,i2s-rx-route = ❤️ 1 2 0>;/
pinctrl-names = “default”;
pinctrl-0 = <
&i2s0m1_mclk
//&i2s0m1_sclk_tx
&i2s0m1_sclk_rx
//&i2s0m1_lrck_tx
&i2s0m1_lrck_rx
&i2s0m1_sdi0
//&i2s0m1_sdo0
&i2s0m1_sdo1_sdi3
&i2s0m1_sdo2_sdi2
&i2s0m1_sdo3_sdi1>;
};
&i2s1_2ch {
status = “okay”;
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = ❤️ 1 2 0>;
pinctrl-names = “default”;
pinctrl-0 = <&i2s1m1_sclk
&i2s1m1_lrck
&i2s1m1_sdo
&i2s1m1_sdi
&i2s1m1_mclk>;
};
&i2s2_2ch {
status = “okay”;
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = ❤️ 1 2 0>;
pinctrl-names = “default”;
pinctrl-0 = <&i2s2m1_sclk
&i2s2m1_lrck
&i2s2m1_sdo
&i2s2m1_sdi
&i2s2m1_mclk>;
};
/*********************************************************************************************/
&gmac {
phy-mode = “rmii”;
clock_in_out = “input”;
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = “okay”;
phy: phy@0 {
status = “okay”;
compatible = “ethernet-phy-ieee802.3-c22”;
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
版权声明:本文为CSDN博主「自学Linux记录」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43209963/article/details/119458150
RV1126(更新完导出pdf保存)
大佬实战教程:
https://gitee.com/owlvisiontech/owlvtech-patch-rv1126/wikis/OWL%E5%BC%80%E5%8F%91%E6%9D%BF%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B?sort_id=2876107
固件烧录
1.找到sdk的烧录工具位置
rv1126_rv1109_linux_210301/tools/linux/Linux_Upgrade_Tool
2.安装工具
unzip Linux_Upgrade_Tool_xxxx.zip
cd Linux_UpgradeTool_xxxx
sudo mv upgrade_tool /usr/local/bin
sudo chown root:root /usr/local/bin/upgrade_tool
sudo chmod a+x /usr/local/bin/upgrade_tool
3.升级
- 按住设备
recovery
按键后使用Typec
线连接设备和电脑上电, 等待3
秒松开recovery
按键。或按住recovery 3s 然后按一下reset - 进入下载固件的路径下依次运行以下命令完成升级。
sudo upgrade_tool ul MiniLoaderAll.bin
sudo upgrade_tool di -p parameter.txt
sudo upgrade_tool di -uboot uboot.img
sudo upgrade_tool di -b boot.img
sudo upgrade_tool di -r recovery.img
sudo upgrade_tool di -m misc.img
sudo upgrade_tool di -oem oem.img
sudo upgrade_tool di -userdata userdata.img
sudo upgrade_tool di -rootfs rootfs.img
sudo upgrade_tool rd
# 如果升级的固件不在当前目录,请输入完整路径。
4.注意事项
4.1关闭回读校验
通过设置 config.ini 文件中 rb_check_off=true 来关闭回读校验,默认是进行回读校验
4.2Config.ini配置生效
将 config.ini 文件放在$HOME/.config/upgrade_tool/位置下,运行工具即可生效.
修改调试串口波特率
1.修改uboot配置
1.1进入u-boot/路径 make menuconfig
修改位置
│ Symbol: BAUDRATE [=1500000] │
│ Type : integer │
│ Prompt: Default baudrate │
│ Location: │
│ -> Device Drivers │
│ -> Serial drivers
保存配置
现在还保存不了,每次编译会被重新加载
1.2直接修改config文件
u-boot/configs/rv1126_defconfig
CONFIG_BAUDRATE=115200
2.修改kernel
修改调试串口的dts配置
//debug uart
&fiq_debugger {
compatible = "rockchip,fiq-debugger";
status = "okay";
rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */
};
DTS
dts的使用以及格式
参考链接:http://www.voidcn.com/article/p-mvvttwny-bms.html
参考文档:Device Tree Usage
快速定位板子编译的dts
打开/home/jelly/rv1126_rv1109_linux_210301/device/rockchip/rv1126_rv1109/BoardConfig.mk
里面会有
#Kernel dts
export RK_KERNEL_DTS=rv1126-evb-ddr3-v13
rv1126-evb-ddr3-v13 就是要编译的dts文件
当然你也可以用rk给的方法./build.sh lunch 去选择要编译的板子类型的mk 文件,然后去查看这个mk文件里面的dts是编译的哪一个
解析dts文件
打开/home/jelly/rv1126_rv1109_linux_210301/kernel/arch/arm/boot/dts/rv1126-evb-ddr3-v13.dts
里面包含
#include "rv1126.dtsi"
#include "rv1126-evb-v13.dtsi"
/ {
model = "Rockchip RV1126 EVB DDR3 V13 Board";
compatible = "rockchip,rv1126-evb-ddr3-v13", "rockchip,rv1126";
chosen {
bootargs = "earlycon=uart8250,mmio32,0xff570000 console=ttyFIQ0 root=PARTUUID=614e0000-0000 rootfstype=ext4 rootwait snd_aloop.index=7";
};
};
打开include “rv1126.dtsi”
这里面是rv1126芯片的各各外设模块寄存器地址,还有外设定义
打开 rv1126-evb-v13.dtsi
#include "rv1126-evb-v12.dtsi"
&backlight {
pwms = <&pwm0 0 25000 0>;
};
&pwm0 {
status = "okay";
};
&pwm3 {
status = "disabled";
};
&u2phy0 {
vup-gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>;
};
打开 include “rv1126-evb-v12.dtsi”
* >```
>#include "rv1126-evb-v10.dtsi"
>/ {
> /delete-node/ vdd-npu;
> /delete-node/ vdd-vepu;
> vdd_logic: vdd-logic {
compatible = "regulator-fixed"; regulator-name = "vdd_logic"; regulator-always-on; regulator-boot-on; regulator-min-microvolt = <810000>; regulator-max-microvolt = <810000>; }; }; &rk809 { regulators { /delete-node/ DCDC_REG1; vdd_npu_vepu: DCDC_REG1 { regulator-always-on; regulator-boot-on; regulator-min-microvolt = <650000>; regulator-max-microvolt = <950000>; regulator-ramp-delay = <6001>; regulator-initial-mode = <0x2>; regulator-name = "vdd_npu_vepu"; regulator-state-mem { regulator-off-in-suspend; }; }; }; }; &ov4689 { reset-gpios = <&gpio2 RK_PA0 GPIO_ACTIVE_LOW>; }; &os04a10 { reset-gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>; }; &npu { npu-supply = <&vdd_npu_vepu>; }; &pwm0 { status = "disabled"; }; &pwm1 { status = "disabled"; }; &rkvenc { venc-supply = <&vdd_npu_vepu>; }; &rkvenc_opp_table { /* * max IR-drop values on different freq condition for this board! */ rockchip,board-irdrop = < /* MHz MHz uV */ 500 594 50000 >; >}; ``` ```
打开 include “rv1126-evb-v10.dtsi”
#include <dt-bindings/display/drm_mipi_dsi.h>
#include <dt-bindings/input/input.h>
/ {
.
.
.
.......
代码太多这里就不复制了
这里主要是rv1126开发板的外设初始化dts配置,继承这里就可以做自己的开发板dts啦
驱动和设备树交互过程
在设备树中定义的信息。
flash_SY7803:flashlight {
compatible = "qcom,leds-gpio-flash"; //匹配参数
status = "okay";
pinctrl-names = "flash_default";
pinctrl-0 = <&SY7803_default>;
qcom,flash-en = <&msm_gpio 31 0>;
qcom,flash-now = <&msm_gpio 32 0>;
qcom,op-seq = "flash_en", "flash_now";
qcom,torch-seq-val = <0 1>;
qcom,flash-seq-val = <1 0>;
linux,name = "flashlight"; //属性 linux,name
linux,default-trigger = "flashlight-trigger";
};
在驱动中如何能获得设备树的信息呢? 是通过node 节点
struct device_node *node = pdev->dev.of_node; //取得node
涉及到下边的一些用法,都是用来取得设备树中的信息的
1. int of_property_read_string(struct device_node *np, const char *propname,const char **out_string)
Find and read a string from a property
rc = of_property_read_string(node, "linux,default-trigger", &temp_str);
of_get_named_gpio
of_get_named_gpio(struct device_node *np,const char *propname, int index)
of_get_named_gpio(node, "qcom,flash-en", 0);
// 取得的值应当是31
of_property_read_string
int of_property_read_string(struct device_node *np, const char *propname,const char **out_string)
rc = of_property_read_string(node, "linux,name", &flash_led->cdev.name);
//flash_led->cdev.name = flashlight
of_property_read_u32_array
int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values,size_t sz)
uint32_t array_flash_seq[2];
rc = of_property_read_u32_array(node, "qcom,flash-seq-val",array_flash_seq, 2);
array_flash_seq <1 0>
5
.of_property_read_string_index
int of_property_read_string_index(struct device_node *np, const char *propname,int index, const char **output)
rc = of_property_read_string_index(node, "qcom,op-seq", i, &seq_name);
//"flash_en", "flash_now";
-------------------
compatible 使用来匹配驱动的
.of_match_table = led_gpio_flash_of_match,
\1. 设备树中 compatible
键值对
2.driver中
platform_driver 结构体
probe
remove
of_match_table
probe 中
1.通过of函数获得相关的资源信息,
\2. 申请引脚信息 pinctrl
3.注册设备 classdev
led_classdev_register
明确驱动如何找到设备树,然后再驱动中找到相应的代码分析就可以了。
想了解更多请参考韦东山的驱动篇教程有专门讲dts部分,很详细
Pinctrl
这会涉及 2 个对象: pin controller、 client device。
前者提供服务:可以用它来复用引脚、配置引脚。
后者使用服务:声明自己要使用哪些引脚的哪些功能,怎么配置它们。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8q4ijj8-1628238375526)(RV1126.assets/image-20210409173807653.png)]
芯片的默认pinctrl DTS文件路径:
/home/jelly/rv1126_rv1109_linux_210301/kernel/arch/arm/boot/dts/rv1126-pinctrl.dtsi
of_device_id 和 xxx_device_id
设备号
of_device_id:用于设备树device信息匹配 driver
xxx_device_id:用于device匹配 driver
系统会优先使用of_device_id数据,在没有匹配上of_device_id 时系统才会用 xxx_device_id去匹配driver
例子:
static const struct i2c_device_id es7243_i2c_id[] = {
#if ES7243_CHANNELS_MAX > 0
{ "MicArray_0", 0 },//es7243_0
#endif
#if ES7243_CHANNELS_MAX > 2
{ "MicArray_1", 1 },//es7243_1
#endif
#if ES7243_CHANNELS_MAX > 4
{ "MicArray_2", 2 },//es7243_2
#endif
#if ES7243_CHANNELS_MAX > 6
{ "MicArray_3", 3 },//es7243_3
#endif
{ }
};
MODULE_DEVICE_TABLE(i2c, es7243_i2c_id);
static const struct of_device_id es7243_dt_ids[] = {
#if ES7243_CHANNELS_MAX > 0
{ .compatible = "MicArray_0", },//es7243_0
#endif
#if ES7243_CHANNELS_MAX > 2
{ .compatible = "MicArray_1", },//es7243_1
#endif
#if ES7243_CHANNELS_MAX > 4
{ .compatible = "MicArray_2", },//es7243_2
#endif
#if ES7243_CHANNELS_MAX > 6
{ .compatible = "MicArray_3", },//es7243_3
#endif
{},
};
MODULE_DEVICE_TABLE(of, es7243_dt_ids);
static struct i2c_driver es7243_i2c_driver = {
.driver = {
.name = "es7243",
.owner = THIS_MODULE,
#if ES7243_MATCH_DTS_EN
.of_match_table = es7243_dt_ids,
#endif
},
.probe = es7243_i2c_probe,
.remove = __exit_p(es7243_i2c_remove),
.class = I2C_CLASS_HWMON,
.id_table = es7243_i2c_id,
#if !ES7243_MATCH_DTS_EN
.address_list = es7243_i2c_addr,
.detect = es7243_i2c_detect,
#endif
};
建立自己的开发板dts
1.将开发板的dts文件夹拷贝出来,并将芯片相关的dts文件提取出来
2.用vscod 编辑自己的dts文件
(这么做是为了方便查找dts相关的变量)
3.根据自己的原理图修改或添加自己的dts配置,没有改动的就不需要修改,沿用官方的dts配置
查找soc自带的dts外设驱动配置
在下面这个路径下又各种外设的dts配置说明文档,查找与自己相关的dts文档参考即可
kernel/Documentation/devicetree/bindings/clock/clock-bindings.txt
DTS的方式时钟配置
dts的方式
时钟默认配置
cru: clock-controller@ff760000 {
compatible = "rockchip,rk3399-cru";
reg = <0x0 0xff760000 0x0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
assigned-clocks =
<&cru ACLK_VOP0>, <&cru HCLK_VOP0>,
<&cru ACLK_VOP1>, <&cru HCLK_VOP1>,
<&cru ARMCLKL>, <&cru ARMCLKB>,
<&cru PLL_GPLL>, <&cru PLL_CPLL>,
<&cru ACLK_GPU>, <&cru PLL_NPLL>,
<&cru ACLK_PERIHP>, <&cru HCLK_PERIHP>,
<&cru PCLK_PERIHP>,
<&cru ACLK_PERILP0>, <&cru HCLK_PERILP0>,
<&cru PCLK_PERILP0>,
<&cru HCLK_PERILP1>, <&cru PCLK_PERILP1>;
assigned-clock-rates =
<400000000>, <200000000>,
<400000000>, <200000000>,
<816000000>, <816000000>,
<594000000>, <800000000>,
<200000000>, <1000000000>,
<150000000>, <75000000>,
<37500000>,
<100000000>, <100000000>,
<50000000>,
<100000000>, <50000000>;
};
== 分配的父时钟和速率 ==
某些平台可能需要初始配置默认的父时钟和时钟频率。 可以在设备树节点中通过已分配的时钟,已分配的时钟父对象和已分配的时钟速率属性指定这种配置
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
}
参考soc厂商的dts配置的快捷方式
将soc厂商的dts文件拷贝出来然后用vsconde查找编辑
驱动实现步骤
1.用设备树写好设备信息
2.定义of_device_id 和 xxx_device_id
3.定义driver
4.实现deiver具体功能以及相关函数
5.注册driver
exmple:
1.用设备树写好设备信息
在注册 I2C 设备时,需要结构体 i2c_client
来描述 I2C 设备。然而在标准 Linux 中,用户只需要提供相应的 I2C 设备信息,Linux 就会根据所提供的信息构造 i2c_client
结构体。
用户所提供的 I2C 设备信息以节点的形式写到 DTS 文件中,如下所示:
kernel/arch/arm64/boot/dts/rockchip/rk3399-firefly-edp.dts
&i2c4 {
status = "okay";
gsl3680: gsl3680@41 {
compatible = "gslX680";
reg = <0x41>;
screen_max_x = <1536>;
screen_max_y = <2048>;
touch-gpio = <&gpio1 20 IRQ_TYPE_LEVEL_LOW>;
reset-gpio = <&gpio0 12 GPIO_ACTIVE_HIGH>;
};
};
2.定义of_device_id 和 xxx_device_id
在定义 I2C 驱动之前,用户首先要定义变量 of_device_id
和 i2c_device_id
。
of_device_id
用于在驱动中调用 DTS 文件中定义的设备信息,其定义如下所示:
static struct of_device_id gsl_ts_ids[] = {
{.compatible = "gslX680"},
{}
};
定义变量 i2c_device_id
:
static const struct i2c_device_id gsl_ts_id[] = {
{GSLX680_I2C_NAME, 0},
{}
};
MODULE_DEVICE_TABLE(i2c, gsl_ts_id);
3.定义driver
static struct i2c_driver gsl_ts_driver = {
.driver = { .name = GSLX680_I2C_NAME,
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(gsl_ts_ids),
},
#ifndef CONFIG_HAS_EARLYSUSPEND
//.suspend = gsl_ts_suspend,
//.resume = gsl_ts_resume,
#endif
.probe = gsl_ts_probe,
.remove = gsl_ts_remove,
.id_table = gsl_ts_id,
};
注:变量 id_table
指示该驱动所支持的设备。
4.实现deiver具体功能以及相关函数
5.注册driver
使用 i2c_add_driver
函数注册 I2C 驱动。
i2c_add_driver(&gsl_ts_driver);
在调用 i2c_add_driver
注册 I2C 驱动时,会遍历 I2C 设备,如果该驱动支持所遍历到的设备,则会调用该驱动的 probe
函数。
通过 I2C 收发数据
以太网(RMII)
1.因为rmii是标准接口,所以只需要配置dts就可以了
SOC输出时钟模式(现在还没调通,估计是时钟问题)
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
PHY输出时钟模式
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
}
设置时钟频率
设置成soc输出时钟的画要设置成50M时钟输出
设置成pyh输出时钟的画也是设置成50m但十物理时钟用25m就设置成25m
一般rimm百兆接口设置成soc输出时钟,除非soc没有50m时钟
常见问题
无法做到ping通
1.将虚拟机改为桥接模式
2.检查网段是不是存在ip冲突
3.电脑,虚拟机,板子,是不是在同一个网段
参考资料:
《Rockchip 以太网 开发指南 V2.3.1-20160708》
kernel/Documentation/devicetree/bindings/clock/clock-bindings.txt
WIFI/BLE
WIFI
参考资料 doc/Linux/Wfifbt
编译wifi code
│ CONFIG_RTL8723DS: │
│ │
│ Help message of RTL8723DS │
│ │
│ Symbol: RTL8723DS [=y] │
│ Type : tristate │
│ Prompt: Realtek 8723D SDIO or SPI WiFi │
│ Location: │
│ -> Device Drivers │
│ -> Network device support (NETDEVICES [=y]) │
│ -> Wireless LAN (WLAN [=y]) │
│ -> Rockchip Wireless LAN support (WL_ROCKCHIP [=y]) │
│ -> Realtek Wireless Device Driver Support (RTL_WIRELESS_SOL
查看所有网卡信息
ifconfig -a
使能失能网卡
ifconfig wlan0 up/down
wifi配置
- 首先确保Wi-Fi的服务进程启动,串口输入:
ps | grep wpa_supplicant
- 如果没启动,请手动启动:
wpa_supplicant -B -i wlan0 -c /data/cfg/wpa_supplicant.conf &
- 修改 /data/cfg/wpa_supplicant.conf 文件,添加配置项
vi /data/cfg/wpa_supplicant.conf
network={
ssid="WiFi-AP" // Wi-Fi名字
psk="12345678" // Wi-Fi密码
key_mgmt=WPA-PSK // 选填加密方式,不填的话可以自动识别
#key_mgmt=NONE // 不加密
}
- 重新读取上述配置: wpa_cli reconfigure
wpa_cli reconfigure
- 重新连接: wpa_cli reconnect
wpa_cli reconnect
I2C
I2C子系统驱动架构 - 驱动框架:
https://blog.csdn.net/cc289123557/article/details/51814778?spm=1001.2014.3001.5501
https://blog.csdn.net/weixin_34032792/article/details/85582751?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
需要注意的是,现阶段只要注册了 i2c_add_drive , adapter 不需要关心,i2c_add_drive 里面会注册adapter
i2c的实现方式参考 “驱动实现步骤” 章节。
es7243调试
查看设备
cat /proc/asound/pcm
寄存器调试:
路径 /sys/bus/i2c/devices/1-0011/driver
驱动提供了寄存器的读写调试,路径 /sys/devices/platform/ff110000.i2c/i2c-1/1-0013/es7243_debug
读例子:
//读取0x00开始的16个寄存器
#echo 0010 > es7243
查看时钟开启情况
cat /sys/kernel/debug/clk/clk_summary | grep i2s
cat /sys/kernel/debug/clk/clk_summary
PWM
dts配置:
内核 3.10 版本和 4.4 版本的 DTS 节点,略有不同的地方在配置的参数个数上,内核 3.10 版本配置的参
数数目为 2,内核 4.4 版本配置的参数数目为 2 或者 3;参数数目与 PWM 节点中的 “pwm-cells” 对
应,如果 “pwm-cells” 配置是 3,则需要配置可选的极性;如果是 2,就不需要配置极性。
DTS 配置参考文档 Documentation/devicetree/bindings/pwm/pwm.txt,主要几个参数说明下:
参数 1,表示 index (per-chip index of the PWM to request),一般是 0,因为我们 Rockchip
PWM 每个 chip 只有一个。
参数 2,表示 PWM 输出波形的时间周期,单位是 ns;例如下面配置的 25000 就是表示想要得到
的 PWM 输出周期是 40K 赫兹。
参数 3,表示极性,为可选参数;下面例子中的配置为负极性。
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&pwm10m1_pins_pull_down>;
};
PWM 使用:
对于 PWM 的 kernel 和 user space 使用说明在 Documentation/pwm.txt 有说明,下面重点提下 user
space 部分。就像 pwm.txt 文档里面说的,PWM 提供了用户层的接口,在 /sys/class/pwm/ 节点下
面,PWM 驱动加载成功后,会在 /sys/class/pwm/ 目录下产生 pwmchip0 目录;向 export 文件写入
0,就是打开 pwm 定时器 0,会产生一个 pwm0 目录,相反的往 unexport 写入 0 就会关闭 pwm 定
时器了,同时 pwm0 目录会被删除,该目录下有以下几个文件:
enable:写入 1 使能 pwm,写入 0 关闭 pwm;
polarity:有 normal 或 inversed 两个参数选择,表示输出引脚电平翻转;
duty_cycle:在 normal 模式下,表示一个周期内高电平持续的时间(单位:纳秒),在 reversed
模式下,表示一个周期中低电平持续的时间(单位:纳秒);
period:表示 pwm 波的周期(单位:纳秒);
以下是 pwmchip0 的例子,设置 pwm0 输出频率 100K,占空比 50%, 极性为正极性:
PWM Backlight
PWM 的连续模式使用最多,且背光使用较为频繁。
\1. Backlight DTS
以下是 DTS 文件中背光很常见的背光配置节点:
cd /sys/class/pwm/pwmchip0/
echo 0 > export
cd pwm0
echo 10000 > period
echo 5000 > duty_cycle
echo normal > polarity
echo 1 > enable
调试方式:
查看注册是否成功,成功则返回接口名和寄存器地址
cat /sys/kernel/debug/pwm
注意事项:
dts修改pwm外设后要关注在dts的其他头文件dtsi中有没有调用或修改相关外设,不然会导致外设配置失败的问题
参考文档:
Rockchip_Developer_Guide_Linux_PWM_CN
MIPI DSI
屏配置方式一**😗* 使用短字符串匹配写死的timing
屏配置方式二**😗* 直接将timing写在dts文件中
需要一份屏幕规格书
1.提取屏幕硬件信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTYKvGhZ-1628238375536)(RV1126.assets/image-20210508143954525.png)]
提取信息:
Display resolution:720*1280
Lcd active aera:62.10*110.4
Screen size:5.0
2.提取时序信息
display-timings
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-y5MdW4Ks-1628238375540)(RV1126.assets/image-20210508164703206.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IxFpGwW2-1628238375542)(RV1126.assets/image-20210508164829835.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MwcXHeu0-1628238375545)(RV1126.assets/image-20210508172033689.png)]
/home/jelly/rv1126_rv1109_linux_210301/kernel/Documentation/devicetree/bindings/display/panel/cat display-timing.txt
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xCbVt9he-1628238375546)(RV1126.assets/image-20210508170012273.png)]
注意:这里没有找到1126的soc的显示时序图,先在用的soc的图是三星的soc的图
soc lcd屏 驱动 DTS
垂直方向
VSPW VSA/tvpw 1<y<20 y=10 vsync_len vsync-len
VBPD VBP/tvb-tvpw 23-tvpw 13 upper_margin vback-porch
LINVAL VACT/tvd 1280 yres vactive
VFPD VFP/tvfp 22 lower_margin vfront-porch
水平方向
HSPW HSA/thpw 1<x<40 x=20 hsync_len hsync-len
HBPD HBP/thb-thpw 46-thpw 26 left_margin hback-porch
HOZVAL HACT/thd 720 xres hactive
HFPD HFP/thfp 210 right_margin hfront-porch
关键信息提炼出来:
4 data lines(厂家推荐值):
Hactive = 800
HFP = 40
HBP = 20
Hsync = 20
Vactive = 1280
VFP = 20
VBP = 20
VSync = 10
clock-frequency = (h_active + hfp + hbp + h_sync) * (v_active + vfp + vbp + v_sync) * fps
厂商给参考值60Hz,
fps= clk/ (800 + 40 + 20 +20) * (1280 + 20 + 20 + 10) = 60Hz
Pixel Clock Frequency(Pclk)= 70.22MHZ
这里我们详细说一下各个参数的含义,这个对我们后续调屏会非常有帮助。
另外根据以上的信息,我们还能计算出 Mipi Dsi Clock 。
DCLK = 100 + H_total×V_total × fps × 3 × 8 / lanes_nums
total 这里指的是 sync + front + back + active
比如 H_total = Hsync + HFP(hfront-proch) + HBP(hback-porch) + Hactive
fps 指的是帧率,一般我们按照 60 帧来计算
3 × 8 代表一个 RGB 为 3 个字节,每个字节 8 bit
lanes 代表 mipi data 通道数
所以对于我这个屏
DCLK
= 100Mbps + H_Total × V_Total x fps x 3 x 8 / lanes_nums
= 100 + ( 800 + 40 + 20 + 20 ) x ( 1280 + 20 + 20+ 10 ) x 60 帧 x 3 字节 x 8 bit / 4 lanes
= 100Mbps + 421Mbps = 521 Mbps
MIPI CLK Lane * 2 = MIPI DATA Lane
3.提取gpio配置信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-syisI3HP-1628238375548)(RV1126.assets/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16204613948073.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FnbkKPbE-1628238375550)(RV1126.assets/%E4%BC%81%E4%B8%9A%E5%BE%AE%E4%BF%A1%E6%88%AA%E5%9B%BE_16204614954716.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UkhxmDJ9-1628238375551)(RV1126.assets/image-20210512152619719.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vSjg8rO5-1628238375553)(RV1126.assets/image-20210517163545204.png)]
4.DTS配置
参考文档
panel node
----------
Required properties:
- compatible: Should contain one of the following:
- "simple-panel": for common simple panel
- "simple-panel-dsi": for common simple dsi panel
- "vendor,panel": for vendor specific panel
- power-supply: See panel-common.txt
Optional properties:
- vsp-supply: positive voltage supply
- vsn-supply: negative voltage supply
- ddc-i2c-bus: phandle of an I2C controller used for DDC EDID probing
- enable-gpios: GPIO pin to enable or disable the panel
- reset-gpios: GPIO pin to reset the panel
- backlight: phandle of the backlight device attached to the panel
- prepare-delay-ms: the time (in milliseconds) that it takes for the panel to
become ready and start receiving video data
- enable-delay-ms: the time (in milliseconds) that it takes for the panel to
display the first valid frame after starting to receive
video data
- disable-delay-ms: the time (in milliseconds) that it takes for the panel to
turn the display off (no content is visible)
- unprepare-delay-ms: the time (in milliseconds) that it takes for the panel
to power itself down completely
- reset-delay-ms: the time (in milliseconds) that it takes for the panel to
reset itself completely
- init-delay-ms: the time (in milliseconds) that it takes for the panel to
send init command sequence after reset deassert
- width-mm: width (in millimeters) of the panel's active display area
- height-mm: height (in millimeters) of the panel's active display area
- bpc: bits per color/component
- bus-format: Pixel data format on the wire
- dsi,lanes: number of active data lanes
- dsi,format: pixel format for video mode
- dsi,flags: DSI operation mode related flags
- panel-init-sequence:
- panel-exit-sequence:
A byte stream formed by simple multiple dcs packets.
byte 0: dcs data type
byte 1: wait number of specified ms after dcs command transmitted
byte 2: packet payload length
byte 3 and beyond: number byte of payload
- power-invert: power invert control
- rockchip,cmd-type: default is DSI cmd, or "spi", "mcu" cmd type
- spi-sdi: spi init panel for spi-sdi io
- spi-scl: spi init panel for spi-scl io
- spi-cs: spi init pael for spi-cs io
Example:
panel: panel {
compatible = "cptt,claa101wb01";
ddc-i2c-bus = <&panelddc>;
power-supply = <&vdd_pnl_reg>;
enable-gpios = <&gpio 90 0>;
backlight = <&backlight>;
};
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "ilitek,ili9881d", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <62>;
height-mm = <110>;
panel-init-sequence = [
39 00 04 ff 98 81 03
15 00 02 01 00
15 00 02 02 00
15 00 02 03 73
15 00 02 04 00
15 00 02 05 00
15 00 02 06 0a
.
.
.
.
这个配置要严格按照屏幕厂商提供的配置参数配置,不然显示会不正常
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <75000000>;
hactive = <720>;
vactive = <1280>;
hfront-porch = <100>;
hsync-len = <33>;
hback-porch = <100>;
vfront-porch = <14>;
vsync-len = <4>;
vback-porch = <14>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
屏配置方式三**😗* 使用edid
MIPI DSI协议介绍
https://blog.csdn.net/longxiaowu/article/details/24410021
调试
显示信息
//由于rockchip driver的一些配置未upstream到libdrm上, 所以从libdrm upstream
//下载编译的modetest默认不带rockchip支持, 需要在使用的时候加个-M rockchip.
(shell)# modetest -M rockchip
显示输出命令
modetest -M rockchip -s 56@53:720x1280 -v
屏幕上即可看到闪烁的彩条显示,
如需使用dp输出,将命令中的connector的id换成dp的即可.
如需使用另一个crtc输出, 将命令中的crtc的id换成另一个crtc的id即可
如需使用别的分辨率输出, 将命令中1440x900换成connectors modes里面别的分辨率即可
参考资料:
ILI9881D_DTS_V102_20170306_Normal
Rockchip_DRM_Panel_Porting_Guide_V1.6_20190228
Rockchip DRM Display Driver Development Guide V1.0
rockchip_drm_integration_helper-zh
3399 lcd配置:https://blog.csdn.net/kentyu001/article/details/78266280
https://blog.csdn.net/qq_41533289/article/details/88872660?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-2.control
https://blog.csdn.net/wenjin359/article/details/82693980?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-16.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-16.control
应用层:https://blog.csdn.net/wuu19/article/details/111078502
i2c-tools工具安装
安装以及使用教程:
https://blog.csdn.net/anyuliuxing/article/details/106382827?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EOPENSEARCH%7Edefault-7.control
1.下载
直接下载 https://mirrors.edge.kernel.org/pub/software/utils/i2c-tools/
或克隆下了
git clone git://git.kernel.org/pub/scm/utils/i2c-tools/i2c-tools.git
2.编译
将i2c工具解压到/home/jelly/rv1126_rv1109_linux_210301/external/路径
修改makefile
CC ?= arm-linux-gnueabihf-gcc
AR ?= arm-linux-gnueabihf-ar
STRIP ?= arm-linux-gnueabihf-strip
编译
make USE_STATIC_LIB=1 && make install
3.编译sdk并烧录到板子即可
使用
1.查地址
i2cdetect -a 3
2.查寄存器的值
i2cdump -f -y 3 0x10
i2cset和i2cget使用方法:
i2cset -f -y 1 0x20 0x77 0x3f (设置i2c-1上0x20器件的0x77寄存器值为0x3f)
i2cget -f -y 1 0x20 0x77 (读取i2c-1上0x20器件的0x77寄存器值)
TP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-V3VGPjvf-1628238375555)(RV1126.assets/image-20210518140837081.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FacHIInf-1628238375557)(RV1126.assets/image-20210518141936054.png)]
1.在kernel 中找到gt911的驱动源码路径
/home/jelly/rv1126_rv1109_linux_210301/kernel/drivers/input/touchscreen/gt9xx
(如果没有驱动程序的话需要原厂提供,最好连dts,makefile,kconfig一起提供)
makefile 添加
obj-$(CONFIG_TOUCHSCREEN_GT9XX_V2_8) += gt9xx_v2.8.0.2/
Kconfig
#
# Goodix GT9xx Touchscreen driver
#
config TOUCHSCREEN_GT9XX_2_8
tristate "Goodix touchpanel GT9xx series"
depends on I2C
help
Say Y here if you have a Goodix GT9xx touchscreen
controller.
If unsure, say N.
config TOUCHSCREEN_GT9XX_2_8_UPDATE
tristate "Goodix GT9xx touch controller auto update support"
depends on TOUCHSCREEN_GT9XX_2_8
default y
help
Enable this for support firmware update.
Say Y here if you want update touch controller firmware.
If unsure, say N.
config TOUCHSCREEN_GT9XX_2_8_TOOL
tristate "Goodix GT9xx Tools for debuging"
depends on TOUCHSCREEN_GT9XX_2_8
default y
help
This implement interface support for Goodix GT9xx
touchscreen debug.
Say Y here if you want to have a Android app debug interface
to your system.
If unsure, say N.
上层kconfig
bool "TOUCHSCREEN_GT9XX_V2_8"
help
Say Y here, and a list of supported touchscreens will be displayed.
This option doesn't affect the kernel.
If unsure, say Y.
if TOUCHSCREEN_GT9XX_V2_8
source "drivers/input/touchscreen/gt9xx_v2.8.0.2/Kconfig"
endif
2.配置内核编译选项,编译gt9xx
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gbjzukbM-1628238375559)(RV1126.assets/image-20210519155906377.png)]
3.添加dts配置
驱动官方dts说明文档
Goodix GT9xx series touch controller
Required properties:
- compatible : Should be "goodix,gt9xx", compatible with the
of_match_table defined in driver.
- reg : I2C slave address of the device.
- interrupt-parent : Parent of interrupt.
- interrupts : Configuration of touch panel interrupt controller.
- irq-gpio : Interrupt gpio which is to provide interrupts to
host, same as "interrupts" node.
- rst-gpio : Reset gpio to control the reset of chip.
- irq-flags = <2>; : 1 for rising edge trigger, 2 for failing edge trigger
Optional properties:
- vdd_ana-supply : Power supply needed to power up the device, when use
external regulator, do not add this property.
- vcc_i2c-supply : Power source required to power up i2c bus.
GT9xx series can provide 1.8V from internal
LDO, add this properties base on hardware design.
- pinctrl-names : Pinctrl related properties, generally this is used
for enable irq-gpio output function.
- touchscreen-max-id : generally no need to change this value keep the default
is OK, if you want support active pen this value must
no less then 11.
- touchscreen-key-map : Specify the touch panel key code if you want support
touch buttons on the device surface.
- goodix,int-sync : Set this with 1 if you use non-fixed I2C address.
- goodix,esd-protect : Start ESD check function when driver installed.
- goodix,auto-update-cfg : Update config before firmware update.
- goodix,power-off-sleep : Power off when enter sleep mode.
- goodix,pen-suppress-finger : Set to 1 if you want suppress finger touch point
when there have a pen detected.
- goodix,cfg-groupX : Touch screen controller config data group X, where X
represent sensor ID.
Driver supports maximum six config groups. driver
will select config group depending on sensor id.
Example:
gt9xx@5d {
compatible = "goodix,gt9xx";
reg = <0x5d>;
status = "okay";
interrupt-parent = <&msm_gpio>;
interrupts = <13 0x2800>;
pinctrl-names = "default", "int-output-low","int-output-high", "int-input";
pinctrl-0 = <&ts_int_default>;
pinctrl-1 = <&ts_int_output_low>;
pinctrl-2 = <&ts_int_output_high>;
pinctrl-3 = <&ts_int_input>;
reset-gpios = <&msm_gpio 12 0x0>;
irq-gpios = <&msm_gpio 13 0x2800>;
irq-flags = <2>;
touchscreen-max-id = <11>;
touchscreen-size-x = <1080>;
touchscreen-size-y = <1920>;
touchscreen-max-w = <512>;
touchscreen-max-p = <512>;
touchscreen-key-map = <172>, <158>; /*KEY_HOMEPAGE=172, KEY_BACK=158,KEY_MENU=139*/
goodix,slide-wakeup = <0>;
goodix,type-a-report = <0>;
goodix,driver-send-cfg = <0>;
goodix,resume-in-workqueue = <0>;
goodix,int-sync = <1>;
goodix,swap-x2y = <0>;
goodix,esd-protect = <1>;
goodix,auto-update-cfg = <0>;
goodix,power-off-sleep = <0>;
goodix,pen-suppress-finger = <0>;
goodix,cfg-group0 = [
53 D0 02 00 05 05 F5 D5 21 48 2D 0F 5A 41 0E 05 00 00 32 32 20 00 05 14 14 1A 14 8B 2B 00
];
};
根据原理图配置dts
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@28 {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
};
4.调试
https://blog.csdn.net/qwe15954250805/article/details/80642446?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-10.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-10.control
查看中断
cat /proc/interrupts
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iqqvvnkW-1628238375560)(RV1126.assets/image-20210519115049866.png)]
怎么理解代码
关键结构体解析:
struct input_event {
struct timeval time;
__u16 type;
__u16 code;
__s32 value;
};
type: 上报事件的类型
EV_SYN: 同步事件
EV_KEY:键盘事件
EV_REL: 相对坐标事件-鼠标
EV_ABS: 绝对坐标事件-触摸屏
我们解析一个input event 时,首先要确定type属性,code和value属性都是根据不同的type有不同的含义(在不同的前缀下,找对应的含义)
code: 不同的type,code有不同的含义
type = EV_KEY时,code代表键盘以及鼠标上不同的按键,如code = 9,表示此时event上报的是键盘上数字“9”对应的事件;code = 46,表示此时event上报的是键盘上字母"C“对应的事件
type = EV_REL时,code代表轨迹的类型,指示鼠标移动的方向,如code = 3,表示此时event上报的是鼠标向X轴移动的数据;当code = 4时,表示此时event上报的时鼠标向Y轴移动的数据。
type = EV_ABS时,code代表触摸坐标轴,如code = 0x35 ,表示此时的event上报的就是当前触摸点X轴的坐标;code = 0x36,表示此时的event 上报的就是当前触摸点Y轴的坐标。
value: 不同的code,value有不同的含义(tpye是根),举几个列子:
type = EV_KEY,code = 9, value = 0:表示键盘上数字”9“被放开
type = EV_KEY,code = 9, value = 1:表示键盘上数字”9“被按下
type = EV_ABS,code = 0x35, value = 128:表示触摸点的X轴坐标为128
type = EV_ABS,code = 0x36,value = 560;表示触摸点的Y轴坐标为560
type = EV_ABS, code = 0x3a, value = 50: 表示触摸点的压力值为50
type = EV_ABS, code = 0x39,value = 0: 表示该触摸点的ID = 0,在多点触控式与其他触摸点区分。
每次事件的上报之后还需要完成一次同步上报,通常情况下,同步有固定的格式:
type = 0,code = 0, value = 0:表示同步
type = 0,code = 2, value = 0;表示MT同步
对于触摸屏来说,上面的分析已经涵盖了同步、坐标、压力、多点触控区分等信息了,但是还缺少接触触摸屏和离开触摸屏两个信息。其实,这两个信息是必不可少的信息,对于不同的触控IC有不用的实现(tpye、code、value)。我使用的触控IC是汇顶科技的gt1x系列,在驱动中通过如下事件区分接触和离开触摸屏事件:
type = 1,code = 330 , value = 1 :表示接触触摸屏
type = 1,code = 330 , value = 0 :表示离开触摸屏
gt9xx代码中,事件类型的定义
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7mXUoiTI-1628238375562)(RV1126.assets/image-20210519155123354.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kwCdiC8m-1628238375564)(RV1126.assets/image-20210519155143827.png)]
可以看出0x35代表x坐标,0x36代表y坐标
调试代码
#include <stdio.h>
#include <linux/input.h>
static int event1_fd = -1;
struct input_event ev0[64];
static int handle_event1()
{
int button = 0, realx=0, realy=0, i, rd;
rd = read(event1_fd, ev0, sizeof(struct input_event)* 64);
if(rd < sizeof(struct input_event)) return 0;
for(i=0;i<rd/sizeof(struct input_event); i++)
{
if(EV_ABS == ev0[i].type)
{
if(ev0[i].code == 53) {
realx = ev0[i].value;
} else if(ev0[i].code == 54) {
realy = ev0[i].value;
}
}
printf("event(%d):type:%d; code:%3d; value:%3d; realx:%3d; realy:%3d\n",i,ev0[i].type,ev0[i].code,ev0[i].value,realx,realy);
}
return 1;
}
int main(void)
{
int done = 1;
event1_fd = open("/dev/input/event1",02);
if(event1_fd <0) {
printf("open input device error\n");
return -1;
}
while (done)
{
printf("begin handle_event1...\n");
done = handle_event1();
printf("end handle_event1...\n");
}
if(event1_fd > 0)
{
close(event1_fd);
event1_fd = -1;
}
return 0;
}
留下的疑问:
为什么地址0x28不行,反而用地址用0x5d可以,官方例程用的是5d?
lunch rk3568_r-userdebug
make ARCH=arm64 rockchip_defconfig rk356x_evb.config android-11.config;
make ARCH=arm64 rk3568-evb1-ddr4-v10.img -j24;
配置编译工具
1.su root
2.gedit ~/.bashrc
3.添加交叉编译链工具路径:
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf- PATH=$PATH:/home/jelly/rv1126_rv1109_linux_210301/prebuilts/gcc/linux-x86/arm/gcc- arm-8.3-2019.03-x86_64-arm-linux-gnueabihf/bin
4.source ~/.bashrc
编译应用程序
1.配置编译工具环境变量
2.包含头文件的方式
https://blog.csdn.net/liuxiangxxl/article/details/89212291
-l参数指定程序要链接的库,如库名字为libtest.so,则编译时加-ltest参数。放在/lib与/usr/lib与/usr/local/lib中的库可直接链接之,若不在这三个目录,用-L参数指定之如:-L /home/zzhiyuan/demo -ltest。
若程序用头文件未在/usr/include则用-I参数指定之。如:-I /home/zzhiyuan/myinclude。
arm-linux-gnueabihf-gcc linux_pcm_save.c -o 123 -I /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include -L /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/lib/ -lasound
2.编译
arm-linux-gnueabihf-gcc -o hello.exe hello.c
alsa
https://blog.csdn.net/xiaolong1126626497/article/details/108739508?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242
调试
查看音频驱动注册情况
cat /proc/asound/pcm
alsa-lib,alsa-utils移植
下载alsa-lib库
https://www.alsa-project.org/wiki/Download
编译alsa-lib库
1.配置
CC=arm-linux-gnueabihf-gcc ./configure --host=arm-linux-gnueabihf --prefix=/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build --enable-static --enable-shared --disable-python --with-configdir=/usr/local/share/alsa --with-plugindir=/usr/local/lib/alsa_lib
注意:要动态编译,不然可能会失败
2.编译
make
3.安装
make install
编译alsa-utils
1.配置
CC=arm-linux-gnueabihf-gcc ./configure --host=arm-linux-gnueabihf-gcc --prefix=/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build --enable-shared CFLAGS="-I/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include" LDFLAGS="-L/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/lib -lasound" --disable-alsamixer --disable-xmlto --with-alsa-inc-prefix=/home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include
2.编译
make
3.安装
make install
安装到嵌入式平台
alsa 配置文件asound.conf
https://blog.csdn.net/weixin_41965270/article/details/81272710?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
运行测试程序
编写应用程序
参考:https://blog.csdn.net/xiaolong1126626497/article/details/105368195?utm_medium=distribute.pc_relevant_download.none-task-blog-baidujs-4.nonecase&depth_1-utm_source=distribute.pc_relevant_download.none-task-blog-baidujs-4.nonecase
编译应用程序
-l参数指定程序要链接的库,如库名字为libtest.so,则编译时加-ltest参数。放在/lib与/usr/lib与/usr/local/lib中的库可直接链接之,若不在这三个目录,用-L参数指定之如:-L /home/zzhiyuan/demo -ltest。
若程序用头文件未在/usr/include则用-I参数指定之。如:-I /home/zzhiyuan/myinclude。
arm-linux-gnueabihf-gcc linux_pcm_save.c -o 123 -I /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/include -L /home/jelly/rv1126_rv1109_linux_210301/external/alsa-lib-1.2.4/build/lib/ -lasound
应用程序解析
配置解析:
https://www.alsa-project.org/wiki/Asoundrc
本文就以树的结构来分析一下pcm流建立的过程。
default树
为了简便起见,下面就称第一颗树为capture树,第二颗为default树。
int snd_pcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_stream_t stream, int mode)
{
int err;
assert(pcmp && name);
//刷新/system/usr/share/alsa/alsa.conf文件内容到snd_config_t结构中,构建配置树
err = snd_config_update();
if (err < 0)
return err;
//真正执行树创建的例程
return snd_pcm_open_noupdate(pcmp, snd_config, name, stream, mode, 0);
}
该函数主要完成如下两步:
第一步:构建配置树
第二步:创建PCM流
点击录音时传入的name为AndroidCapture(其它模式类似),在第二步中根据传入的name参数在配置树中查找对应的snd_config_t结点。根据我们的配置asla-lib.conf,查找到capture树。
下面看一下这个函数,
snd_pcm_open_noupdate
会调用到这里
static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
snd_config_t *pcm_root, snd_config_t *pcm_conf,
snd_pcm_stream_t stream, int mode);
这个函数的功能是取下pcm_conf配置树中type孩子结点对应的字符串值,并利用该字符串构造一新的函数并调用。在我们的系统中可以简单地这样理解。下面以capture树为例说明一下。
snd_pcm_open-->snd_pcm_open_noupdate-->snd_pcm_open_conf
此时传入的 pcm_conf配置树为capture树,它会取下type孩子结点的字符串str(hooks),构建函数名sprintf(open_name, “snd_pcm%s_open”, str);之后调用函数snd_pcm_hooks_open.下snd_pcm_open的主要流程:
_snd_pcm_hooks_open-->_snd_pcm_empty_open--->_snd_pcm_plug_open--->_snd_pcm_hw_open
结合capture树和default树,不难看出,后三个函数名也是用类似构造snd_pcm_hook_open的方法生成的,之后调用。事实确 实是这样的,在snd_pcm_open过程中多次调用snd_pcm_open_conf只是每次传入的pcm_conf配置树不一样而已。那么我们的 default树是如何获取的呢?
在snd_pcm_hook_open中会查找capture树的slave孩子结点,并将slave的pcm子结点的str(default)作为 新的name重新调用snd_pcm_open_noupdate.然后根据name参数在配置树中查找到default对应的结点,即default 树。
前面说过snd_pcm_open_noupdate会调用到snd_pcm_open_conf,由此不难想象到它会构造 snd_pcm_empty_open,并调用它。之后snd_pcm_plug_open–>snd_pcm_hw_open函数的构造 也是类似的这里都不多介绍了。读者可认真看一下snd_pcm_xxx_open,会发现它都会调用到snd_pcm_open_conf函数来加载下 一层的type xxxx.就这样对default树进行逐层分析.
_snd_pcm_hooks_open-->_snd_pcm_empty_open->_snd_pcm_plug_open->_snd_pcm_hw_open
上面是我给大家介绍的重点之一。
此流程执行完,也要逐层返回,在snd_pcm_hooks_open/snd_pcm_plug_open/snd_pcm_hw_open三层分别还会创建三种类型的pcm流对象和它的私有数据成员及和它对应的函数集。
下面就从里到外顺序介绍一下相关代码,先看一下hw层
…
//pcm_hw.c 创建类型为SND_PCM_TYPE_HW的pcm流
ret = snd_pcm_new(&pcm, SND_PCM_TYPE_HW, name, info.stream, mode);
if (ret < 0) {
free(hw);
close(fd);
return ret;
}
//HW层的函数集
pcm->ops = &snd_pcm_hw_ops;
pcm->fast_ops = &snd_pcm_hw_fast_ops;
//snd_pcm_hw_t结构hw作为私有数据成员,存储一些信息。
pcm->private_data = hw;
//打开/dev/snd/pcmC0D0c
pcm->poll_fd = fd;
....
返回plug层
//pcm_plug.c
int snd_pcm_plug_open(snd_pcm_t **pcmp,
const char *name,
snd_pcm_format_t sformat, int schannels, int srate,
const snd_config_t *rate_converter,
enum snd_pcm_plug_route_policy route_policy,
snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_ssize,
unsigned int tt_cused, unsigned int tt_sused,
snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
snd_pcm_plug_t *plug;
int err;
assert(pcmp && slave);
//分配私有数据成员
plug = calloc(1, sizeof(snd_pcm_plug_t));
if (!plug)
return -ENOMEM;
plug->sformat = sformat;
plug->schannels = schannels;
plug->srate = srate;
plug->rate_converter = rate_converter;
//将HW层的pcm流对象存放在PLUG层pcm流的私有数据成员中
plug->gen.slave = plug->req_slave = slave;
plug->gen.close_slave = close_slave;
plug->route_policy = route_policy;
plug->ttable = ttable;
plug->tt_ssize = tt_ssize;
plug->tt_cused = tt_cused;
plug->tt_sused = tt_sused;
//创建SND_PCM_TYPE_PLUG类型的pcm流对象
err = snd_pcm_new(&pcm, SND_PCM_TYPE_PLUG, name, slave->stream, slave->mode);
if (err < 0) {
free(plug);
return err;
}
//PLUG层函数集
pcm->ops = &snd_pcm_plug_ops;
pcm->fast_ops = slave->fast_ops;
pcm->fast_op_arg = slave->fast_op_arg;
//plug关联到私有成员中
pcm->private_data = plug;
pcm->poll_fd = slave->poll_fd;
pcm->poll_events = slave->poll_events;
pcm->mmap_shadow = 1;
pcm->monotonic = slave->monotonic;
snd_pcm_link_hw_ptr(pcm, slave);
snd_pcm_link_appl_ptr(pcm, slave);
*pcmp = pcm;
return 0;
}
最后再来看一下HOOKS层
//pcm_hooks.c
int snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name, snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
snd_pcm_hooks_t *h;
unsigned int k;
int err;
assert(pcmp && slave);
//分配私有成员空间
h = calloc(1, sizeof(snd_pcm_hooks_t));
if (!h)
return -ENOMEM;
//寄存PLUG层的pcm流对象
h->gen.slave = slave;
h->gen.close_slave = close_slave;
for (k = 0; k <= SND_PCM_HOOK_TYPE_LAST; ++k) {
INIT_LIST_HEAD(&h->hooks[k]);
}
//SND_PCM_TYPE_HOOKS类型的pcm流对象创建
err = snd_pcm_new(&pcm, SND_PCM_TYPE_HOOKS, name, slave->stream, slave->mode);
if (err < 0) {
free(h);
return err;
}
//HOOKS层函数集
pcm->ops = &snd_pcm_hooks_ops;
pcm->fast_ops = &snd_pcm_hooks_fast_ops;
//关联私有数据
pcm->private_data = h;
pcm->poll_fd = slave->poll_fd;
pcm->poll_events = slave->poll_events;
pcm->mmap_shadow = 1;
pcm->monotonic = slave->monotonic;
snd_pcm_link_hw_ptr(pcm, slave);
snd_pcm_link_appl_ptr(pcm, slave);
*pcmp = pcm;
return 0;
}
由此可见,在整个过程中创建了三种类型的pcm流对象,HOOKS,PLUG,HW
_snd_pcm_hooks_open-->_snd_pcm_empty_open--->_snd_pcm_plug_open--->_snd_pcm_hw_open
层层递进分析配置树
_snd_pcm_hooks_open<--....................................<---_snd_pcm_plug_open<--_snd_pcm_hw_open
层层回溯。
回溯过程依次创建了HW pcm–>PLUG pcm–>HOOKS pcm及和它们区配的私有数据及相关操作函数集,而且可以通过HOOKS层的pcm流,查找到plug,hw的pcm.它们都被寄存在上层的private_data成员中。如下图
时知道调用的是
至此返回_snd_pcm_hooks_open,下面这个函数还会对capture树的hooks孩子结点分析。
static int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *root, snd_config_t *conf)
它类似snd_pcm_open_conf,它会调用 _snd_pcm_hook_ctl_elems_install–>snd_ctl_open打开对应的
/dev/snd /ControlC0(snd_ctl_open和snd_pcm_open类似都是通过传入字符串查找配置树,然后分析找开设备之类操作),执行成功能 会带回一个snd_sctl_t结构类型对象。
由此可以PCM流打开需要两步:snd_pcm_open /dev/snd/pcmC0D0c 的打开和snd_ctl_open /dev/snd/ControlC0的打开,两个设备文件。
之后_snd_pcm_hook_ctl_elems_install->snd_sctl_build,但是根据我们的配置在这里会返回错误信 息(snd_sctl_build会添加hook_args下面所有的参数信息并生成一个新的snd_sctl_t对象(add_elem),就是在添加 参数信息时我们的配置有问题,所以出错返回)。错误发生,会释放HOOKS层的pcm流对象,级联PLUG和HW层。最终snd_pcm_open会返回 错误信息。pcm流创建失败。
这是我们系统中snd_pcm_open的整个流程,虽然这里创建失败但是可以让我们清晰地认识流创建过程:它是一个分层的流建立过程。 hooks->plug->hw(pcm) 及hooks->empty->plug->hw函数层次调用过程。
这个层次结构就是我给大家介绍的第二个要点,特别是多种pcm流类型,及它们相互引用和各自的私有数据成员及对应的函数操作集。有了这个认识,我们才能在pcm->fast_ops->read(…)时知道调用的是哪一层的函数集。
虽然这里创建PCM流失败,但是我们的系统会有另一种方案重新创建default pcm流。可以参考我们系统中流的创建过程。
移植参考链接:
https://blog.csdn.net/RopenYuan/article/details/8078100
shell脚本框架
#!/bin/bash
export LC_ALL=C
unset RK_CFG_TOOLCHAIN
#进入要操作的路径
TOP_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
IMAGE_PATH=$TOP_DIR/rockdev
echo "$IMAGE_PATH"
cd $IMAGE_PATH
#指令帮助信息
function usage()
{
echo "Usage: dowload.sh [OPTIONS]"
echo "Available options:"
echo "loader -upgrade MiniLoaderAll.bin"
echo "parameter -upgrade parameter.txt"
echo "uboot -upgrade uboot.img"
echo "boot -upgrade boot.img"
echo "recovery -upgrade recovery.img"
echo "misc -upgrade misc.img"
echo "oem -upgrade oem.img"
echo "userdata -upgrade userdata.img"
echo "rootfs -upgrade rootfs.img"
echo "rd -restart sys"
echo "all -upgrade all img"
echo ""
}
#各个函数实现
function upgrade_loader()
{
sudo upgrade_tool ul MiniLoaderAll.bin
echo "sudo upgrade_tool ul MiniLoaderAll.bin"
}
function upgrade_parameter()
{
sudo upgrade_tool di -p parameter.txt
echo "sudo upgrade_tool di -p parameter.txt"
}
function upgrade_uboot()
{
sudo upgrade_tool di -uboot uboot.img
echo "sudo upgrade_tool di -uboot uboot.img"
}
function upgrade_boot()
{
sudo upgrade_tool di -b boot.img
echo "sudo upgrade_tool di -b boot.img"
}
function upgrade_recovery()
{
sudo upgrade_tool di -r recovery.img
echo "sudo upgrade_tool di -r recovery.img"
}
function upgrade_misc()
{
sudo upgrade_tool di -m misc.img
echo "sudo upgrade_tool di -m misc.img"
}
function upgrade_oem()
{
sudo upgrade_tool di -oem oem.img
echo "sudo upgrade_tool di -oem oem.img"
}
function upgrade_userdata()
{
sudo upgrade_tool di -userdata userdata.img
echo "sudo upgrade_tool di -userdata userdata.img"
}
function upgrade_rootfs()
{
sudo upgrade_tool di -rootfs rootfs.img
echo "sudo upgrade_tool di -rootfs rootfs.img"
}
function upgrade_rd()
{
sudo upgrade_tool rd
echo "sudo upgrade_tool rd"
}
function upgrade_all()
{
upgrade_loader
upgrade_parameter
upgrade_uboot
upgrade_boot
upgrade_recovery
upgrade_misc
upgrade_oem
upgrade_userdata
upgrade_rootfs
upgrade_rd
}
#=========================
# build targets
#=========================
if echo $@|grep -wqE "help|-h"; then
if [ -n "$2" -a "$(type -t usage$2)" == function ]; then
echo "###Current SDK Default [ $2 ] Build Command###"
eval usage$2
else
usage
fi
exit 0
fi
#执行相关指令调用相关函数
OPTIONS="$@"
for option in ${OPTIONS}; do
echo "processing option: $option"
case $option in
loader) upgrade_loader ;;
parameter) upgrade_parameter ;;
uboot) upgrade_uboot ;;
boot) upgrade_boot ;;
recovery) upgrade_recovery ;;
misc) upgrade_misc ;;
oem) upgrade_oem ;;
userdata) upgrade_userdata ;;
rootfs) upgrade_rootfs ;;
rd) upgrade_rd ;;
all) upgrade_all ;;
*) usage ;;
esac
done
【ALSA】 asound.conf 插件讲解
https://blog.csdn.net/qq_31811537/article/details/103800745?utm_medium=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-2.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task-blog-baidujs-2.nonecase
查询log关键字
dmesg命令用于打印Linux系统开机启动信息,kernel会将开机信息存储在ring buffer中。您若是开机时来不及查看信息,可利用dmesg来查看(print or control the kernel ring buffer)。开机信息亦保存在/var/log/dmesg的文件里
格式:dmesg
查看开机信息。
搜索开机信息:dmesg | grep xxx(需要查找的字符)
格式:dmesg -c
清除开机信息,但/var/log/dmesg文件中仍然有这些信息。
1、使用grep命令进行筛选:
如:grep -i “http” /var/log/messages,可以查询出现“http”的所有行。
2、使用cat加grep查询
如: cat /var/log/messages | grep “http”,和上面一样的功能。
修改kernel 的编译的config文件
1.修改BoardConfig.mk
路径:device/rockchip/rv1126_rv1109/BoardConfig.mk
修改 TARGET_KERNEL_CONFIG
TARGET_KERNEL_CONFIG =zk_rv1126_config
2.将配置好的config文件考到 arch/arm/configs/zk_rv1126_config 路径
我这里写一个脚本做这个事
#!/bin/bash
export LC_ALL=C
unset RK_CFG_TOOLCHAIN
TOP_DIR=$(cd $(dirname "${BASH_SOURCE[0]}") && pwd)
echo "$IMAGE_PATH"
make ARCH=arm zk_rv1126_config
make ARCH=arm menuconfig
make ARCH=arm savedefconfig
cp zk_rv1126_config arch/arm/configs/zk_rv1126_config
make
cd ../
./mkfirmware.sh
#./dowload.sh
以后编译kernel的时候就会配置zk_rv1126_config 文件为编译的文件啦
需要注意,每次修改config后要保存成zk_rv1126_config 的名字
或者更改配置后直接保存
make menuconfig
make savedefconfig
就可以编译最新的配置
添加开机启动脚本
我们都了解**/etc/init.d/**目录下的所有文件都是脚本文件,这个目录下的脚本文件,在设置好开机自启动项后,在开机时会自动执行。
1.在根目录下创建beyond.sh文件
vi beyond.sh
2.保存完脚本后,使用chmod设置可执行权限:
chmod +x beyond.sh
3.然后将其拷贝到/etc/init.d/目录下,否则添加服务不成功:
cp beyond.sh /etc/init.d/
4.进入/etc/init.d/目录下:
cd /etc/init.d/
5.将beyond.sh添加到系统服务:
chkconfig --add beyond.sh
6.设置开机启动:
chkconfig beyond.sh on
8.然后重启linux:
reboot
8.重启之后连接查看效果:rds换成自己的服务
ps -ef | grep rds
登录evb板的调试方式
网络
注意:
1.通过SSH登陆EVB板调试
### 清除上次登陆信息(EVB板的IP地址192.168.163.222)
ssh-keygen -f "$HOME/.ssh/known_hosts" -R 192.168.163.222
### 使用SSH命令登陆
ssh root@192.168.163.222
### 输入默认密码:rockchip
2.通过SCP调试
### 从PC端上传文件test-file到EVB板的目录/userdata
scp test-file root@192.168.163.222:/userdata/
root@192.168.163.222's password:
### 输入默认密码:rockchip
### 下载EVB板上的文件/userdata/test-file下载到PC端
scp root@192.168.163.222:/userdata/test-file test-file
root@192.168.163.222's password:
### 输入默认密码:rockchip
3.通过网络ADB调试
### 获取EVB板的IP地址192.168.163.222
adb connect 192.168.163.222
adb devices
List of devices attached
192.168.163.222:5555 device
### adb登陆EVB板子调试
adb -s 192.168.163.222:5555 shell
### 从PC端上传文件test-file到EVB板的目录/userdata
adb -s 192.168.163.222:5555 push test-file /userdata/
### 下载EVB板上的文件/userdata/test-file下载到PC端
adb -s 192.168.163.222:5555 pull /userdata/test-file test-file
usb
1.adb shell
2.串口
拷贝应用程序到板子
(dowload.sh 脚本的一段程序)
function adb_push()
{
adb connect 192.168.163.222
adb devices
adb -s 192.168.163.222:5555 push adb-file /userdata/
finish_build
}
调试PHY网口
设置板子IP
静态
切换到/etc/network文件夹,找到interfaces文件
vi /etc/network/interfaces
#添加:
auto eth0
iface eth0 inet static
address 192.168.163.222
netmask 255.255.255.0
gateway 192.168.163.1
动态
使用ifconfig命令配置
ifconfig eth0 192.168.163.222 netmask 255.255.255.0
使用route命令配置网关
route add default gw 192.168.163.1
配置完成后使用以下命令进行重启即可
/etc/init.d/S40network restart
补充:若网卡eth0 未开启,可使用以下命令开启
ifconfig eth0 up//开启eth0网卡
ifconfig eth0 down//关闭eth0网卡
查找电脑链接的ip
arp -a
虚拟机系统链接网络设置
1.设置成链接到主机模式
2.将/etc/network/interfaces,里面的静态ip设置注释掉
关于CONFIG_OF
最近在调i2c驱动,看到了很多 #ifdef CONFIG_OF 的宏条件,但在各个头文件中都没有找到CONFIG_OF,后来发现这和内核设备树有关;
在内核的 arch/arm/Kconfig中有 select OF 这一项:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iBbe4ida-1628238375569)(RV1126.assets/image-20210519140528250.png)]
上面显示它在菜单 Boot options 里,于是我在内核目录下make menuconfig ,再选择Boot options,将Flattened Device Tree sopport 选中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IJa9zpPk-1628238375572)(RV1126.assets/image-20210519140548821.png)]
也不知道到底是不是这样,(#.#),错了的话,还望有大佬能指正。
————————————————
版权声明:本文为CSDN博主「小辉。?」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43772810/article/details/109554607
安检门DTSI
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*/
#include "rv1126-evb-v13.dtsi"
/ {
es7243e_sound_1: es7243e-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243e";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243e_0
//&es7243e_1
//&es7243e_2
//&es7243e_3
>;
};
};
/*es7243e_sound: es7243e-sound {
status = "okay";
compatible = "rockchip,multicodecs-card";
rockchip,card-name = "rockchip,es7243e";
rockchip,mclk-fs = <768>;
rockchip,cpu = <&i2s0_8ch>;
rockchip,codec = <&es7243e_0>;
};*/
es7243e_sound_2: es7243e-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243e";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s2_2ch>;
};
simple-audio-card,codec {
sound-dai = <&es7243e_5>;
};
};
es7243e_sound_3: es7243e-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243e";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = < &i2s1_2ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243e_4>;
};
};
};
/*&wireless-bluetooth {
status = "okay";
};*/
&wireless_wlan {
clocks = <&rk809 1>;
//WIFI,poweren_gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
//WIFI,host_wake_irq = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
wifi_chip_type = "rtl8723ds";
status = "okay";
};
&sdio {
//max-frequency = <50000000>;
status = "okay";
};
//debug uart
&fiq_debugger {
status = "okay";
compatible = "rockchip,fiq-debugger";
rockchip,baudrate = <1500000>; /* Only 115200 and 1500000 */
};
&ar0230 {
status = "disabled";
};
&ov4689 {
status = "disabled";
};
&os04a10 {
status = "disabled";
};
&rk809_sound {
status = "disabled";
};
/********************************************************************************************/
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
//if use zhaji board open this
//pinctrl-0 = <&pwm10m1_pins_pull_down>;
pinctrl-0 = <&pwm10m0_pins_pull_down>;
//pinctrl-0 = <&pwm9m1_pins_pull_down>;
};
&pwm3 {
status = "disabled";
};
//SHENZHEN FRIDA LCD CO.,LTD Model No:FRD700B30012-B
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "frida,ek79007ad", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <154>;
height-mm = <86>;
panel-init-sequence = [
15 00 02 80 8b
15 00 02 81 78
15 00 02 82 84
15 00 02 83 88
15 00 02 84 a8
15 00 02 85 ae
15 00 02 86 88
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <51000000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hsync-len = <70>;
hback-porch = <90>;
vfront-porch = <12>;
vsync-len = <10>;
vback-porch = <13>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&uart0 {
status = "okay";
};
/*********************************************************************************/
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@5d {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
//rtc zt0701
sd3078@32 {
status = "okay";
compatible = "rockchip,sd3078";
reg = <0x32>;
};
};
/************************************************************************************/
//Dts 的 codec 的i2c部分:
//Dts 的 platform 的 i2s 部分:
//i2c adapter3 信息
&i2c3{
clock-frequency = <400000>;//设置传输速率 400k
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_xfer>;
status = "okay";
es7243e_0: es7243e_0@10{
status = "okay";
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
pinctrl-0 = <&i2s0m1_mclk>;
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
};
es7243e_1: es7243e_1@11{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x11>;
};
es7243e_2: es7243e_2@13{
#sound-dai-cells = <0>;
compatible = "MicArray_2";
reg = <0x13>;
};
es7243e_3: es7243e_3@12{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x12>;
};
};
&i2c1{
clock-frequency = <400000>;//设置传输速率 400k
//i2c-scl-rising-time-ns = <280>;
//i2c-scl-falling-time-ns = <16>;
status = "okay";
es7243e_4: es7243e_4@11{
#sound-dai-cells = <0>;
compatible = "MicArray_4";
reg = <0x10>;
clocks = <&cru MCLK_I2S1_OUT2IO>;
clock-names = "mclk";
//pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S1_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S1>;
//pinctrl-0 = <&i2s1m1_mclk>;
};
es7243e_5: es7243e_5@13{
#sound-dai-cells = <0>;
compatible = "MicArray_5";
reg = <0x12>;
clocks = <&cru MCLK_I2S2_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S2_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S2>;
pinctrl-0 = <&i2s2m1_mclk>;
};
};
&i2s0_8ch {
status = "okay";
#sound-dai-cells = <0>;
rockchip,clk-trcm = <2>;
rockchip,mclk-calibrate;
rockchip,i2s-rx-route = <0 1 2 3>;
pinctrl-names = "default";
pinctrl-0 = <
//&i2s0m1_mclk
//&i2s0m1_sclk_tx
&i2s0m1_sclk_rx
//&i2s0m1_lrck_tx
&i2s0m1_lrck_rx
&i2s0m1_sdi0
//&i2s0m1_sdo0
&i2s0m1_sdo1_sdi3
&i2s0m1_sdo2_sdi2
&i2s0m1_sdo3_sdi1>;
};
&i2s1_2ch {
status = "okay";
#sound-dai-cells = <0>;
//rockchip,bclk-fs: configure the i2s bclk fs.
rockchip,clk-trcm = <0>; //tx and rx lrck/bclk common use.
pinctrl-names = "default";
pinctrl-0 = <&i2s1m1_sclk
&i2s1m1_lrck
//&i2s1m1_sdo
&i2s1m1_sdi
&i2s1m1_mclk //zhe li bu zhushi yinping shebei chubulai ,haibu zhidao weishenme?
>;
};
&i2s2_2ch {
status = "okay";
#sound-dai-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s2m1_sclk
&i2s2m1_lrck
//&i2s2m1_sdo
&i2s2m1_sdi
//&i2s2m1_mclk
>;
};
/*********************************************************************************************/
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = "okay";
phy: phy@0 {
status = "okay";
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
zk_ajm_rv1126_v1.dtsi(闸机板子)
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*/
#include "rv1126-evb-v13.dtsi"
/ {
es7243_sound: es7243-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&es7243_0
&es7243_1
&es7243_2
&es7243_3>;
};
};
wireless-bluetooth {
status = "okay";
};
wireless_wlan: wireless-wlan {
wifi_chip_type = "rtl8723ds";
status = "okay";
};
};
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
pinctrl-0 = <&pwm10m1_pins_pull_down>;
};
&pwm3 {
status = "disabled";
};
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "ilitek,ili9881d", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <62>;
height-mm = <110>;
panel-init-sequence = [
39 00 04 ff 98 81 03
15 00 02 01 00
15 00 02 02 00
15 00 02 03 73
15 00 02 04 00
15 00 02 05 00
15 00 02 06 0a
15 00 02 07 00
15 00 02 08 00
15 00 02 09 01
15 00 02 0a 00
15 00 02 0b 00
15 00 02 0c 01
15 00 02 0d 00
15 00 02 0e 00
15 00 02 0f 1d
15 00 02 10 1d
15 00 02 11 00
15 00 02 12 00
15 00 02 13 00
15 00 02 14 00
15 00 02 15 00
15 00 02 16 00
15 00 02 17 00
15 00 02 18 00
15 00 02 19 00
15 00 02 1a 00
15 00 02 1b 00
15 00 02 1c 00
15 00 02 1d 00
15 00 02 1e 40
15 00 02 1f 80
15 00 02 20 06
15 00 02 21 02
15 00 02 22 00
15 00 02 23 00
15 00 02 24 00
15 00 02 25 00
15 00 02 26 00
15 00 02 27 00
15 00 02 28 33
15 00 02 29 03
15 00 02 2a 00
15 00 02 2b 00
15 00 02 2c 00
15 00 02 2d 00
15 00 02 2e 00
15 00 02 2f 00
15 00 02 30 00
15 00 02 31 00
15 00 02 32 00
15 00 02 33 00
15 00 02 34 04
15 00 02 35 00
15 00 02 36 00
15 00 02 37 00
15 00 02 38 3c
15 00 02 39 35
15 00 02 3a 01
15 00 02 3b 40
15 00 02 3c 00
15 00 02 3d 01
15 00 02 3e 00
15 00 02 3f 00
15 00 02 40 00
15 00 02 41 88
15 00 02 42 00
15 00 02 43 00
15 00 02 44 1f
15 00 02 50 01
15 00 02 51 23
15 00 02 52 45
15 00 02 53 67
15 00 02 54 89
15 00 02 55 ab
15 00 02 56 01
15 00 02 57 23
15 00 02 58 45
15 00 02 59 67
15 00 02 5a 89
15 00 02 5b ab
15 00 02 5c cd
15 00 02 5d ef
15 00 02 5e 11
15 00 02 5f 01
15 00 02 60 00
15 00 02 61 15
15 00 02 62 14
15 00 02 63 0e
15 00 02 64 0f
15 00 02 65 0c
15 00 02 66 0d
15 00 02 67 06
15 00 02 68 02
15 00 02 69 07
15 00 02 6a 02
15 00 02 6b 02
15 00 02 6c 02
15 00 02 6d 02
15 00 02 6e 02
15 00 02 6f 02
15 00 02 70 02
15 00 02 71 02
15 00 02 72 02
15 00 02 73 02
15 00 02 74 02
15 00 02 75 01
15 00 02 76 00
15 00 02 77 14
15 00 02 78 15
15 00 02 79 0e
15 00 02 7a 0f
15 00 02 7b 0c
15 00 02 7c 0d
15 00 02 7d 06
15 00 02 7e 02
15 00 02 7f 07
15 00 02 80 02
15 00 02 81 02
15 00 02 82 02
15 00 02 83 02
15 00 02 84 02
15 00 02 85 02
15 00 02 86 02
15 00 02 87 02
15 00 02 88 02
15 00 02 89 02
15 00 02 8a 02
39 00 04 ff 98 81 04
//15 00 02 00 80
15 00 02 70 00
15 00 02 71 00
//15 00 02 66 fe
15 00 02 82 0f
15 00 02 84 0f
15 00 02 85 0d
//15 00 02 3a 24
15 00 02 32 ac
15 00 02 8c 80
15 00 02 3c f5
15 00 02 b5 07
15 00 02 31 45
15 00 02 3a 24
15 00 02 88 33
39 00 04 ff 98 81 01
15 00 02 22 09
15 00 02 31 00
15 00 02 53 8a
15 00 02 55 a2
15 00 02 50 81
15 00 02 51 85
//15 00 02 60 20
//15 00 02 61 00
15 00 02 62 0d
//15 00 02 63 00
15 00 02 a0 00
15 00 02 a1 1a
15 00 02 a2 28
15 00 02 a3 13
15 00 02 a4 16
15 00 02 a5 29
15 00 02 a6 1d
15 00 02 a7 1e
15 00 02 a8 84
15 00 02 a9 1c
15 00 02 aa 28
15 00 02 ab 75
15 00 02 ac 1a
15 00 02 ad 19
15 00 02 ae 4d
15 00 02 af 22
15 00 02 b0 28
15 00 02 b1 54
15 00 02 b2 66
//15 00 02 b1 2e
//15 00 02 b2 32
15 00 02 b3 39
15 00 02 c0 00
15 00 02 c1 1a
15 00 02 c2 28
15 00 02 c3 13
15 00 02 c4 16
15 00 02 c5 29
15 00 02 c6 1d
15 00 02 c7 1e
15 00 02 c8 84
15 00 02 c9 1c
15 00 02 ca 28
15 00 02 cb 75
15 00 02 cc 1a
15 00 02 cd 19
15 00 02 ce 4d
15 00 02 cf 22
15 00 02 d0 28
15 00 02 d1 54
15 00 02 d2 66
15 00 02 d3 39
39 00 04 ff 98 81 00
15 00 02 36 03
05 00 01 35
05 00 01 11
05 01 01 29
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <75000000>;
hactive = <720>;
vactive = <1280>;
hfront-porch = <100>;
hsync-len = <33>;
hback-porch = <100>;
vfront-porch = <14>;
vsync-len = <4>;
vback-porch = <14>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&uart0 {
status = "okay";
};
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@5d {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
};
&rk809_sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "rockchip,rk809-codec";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Mic Jack", "MICBIAS1",
"IN1P", "Mic Jack",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = <&rk809_codec_i2c4>;
};
};
&i2c4 {
status = "okay";
clock-frequency = <400000>;
rk809_codec_i2c4: codec {
#sound-dai-cells = <0>;
compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
pinctrl-0 = <&i2s0m0_mclk>;
hp-volume = <20>;
spk-volume = <3>;
};
};
//Dts 的 codec 的i2c部分:
//Dts 的 platform 的 i2s 部分:
//i2c adapter3 信息
&i2c3{
clock-frequency = <400000>;//设置传输速率 400k
status = "okay";
es7243_0: es7243_0@10{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
clocks = <&cru MCLK_I2S0_RX>;//?还不知道这个时钟要怎么选,明天看看sdk关于i2c的文档怎么搞
clock-names = "mclk";
realtek,in1-differential; //?这是什么意思,没有搞懂啊
};
es7243_1: es7243_1@11{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_RX>;
clock-names = "mclk";
realtek,in1-differential;
};
es7243_2: es7243_2@13{
#sound-dai-cells = <0>;
compatible = "MicArray_2";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_RX>;
clock-names = "mclk";
realtek,in1-differential;
};
es7243_3: es7243_3@12{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x12>;
clocks = <&cru MCLK_I2S0_RX>;
clock-names = "mclk";
realtek,in1-differential;
};
};
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = "okay";
phy: phy@0 {
status = "okay";
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
/*以下部分是rv1126 官方外设DTS部分,用于提供参考*/
/*
i2c0: i2c@ff3f0000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff3f0000 0x1000>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&pmucru CLK_I2C0>, <&pmucru PCLK_I2C0>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c0_xfer>;
status = "disabled";
};
i2c2: i2c@ff400000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff400000 0x1000>;
interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
rockchip,grf = <&pmugrf>;
clocks = <&pmucru CLK_I2C2>, <&pmucru PCLK_I2C2>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c2_xfer>;
status = "disabled";
};
i2c1: i2c@ff510000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff510000 0x1000>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c1_xfer>;
status = "disabled";
};
i2c3: i2c@ff520000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff520000 0x1000>;
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c3m0_xfer>;
status = "disabled";
};
i2c4: i2c@ff530000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff530000 0x1000>;
interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c4m0_xfer>;
status = "disabled";
};
i2c5: i2c@ff540000 {
compatible = "rockchip,rv1126-i2c", "rockchip,rk3399-i2c";
reg = <0xff540000 0x1000>;
interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>;
clock-names = "i2c", "pclk";
pinctrl-names = "default";
pinctrl-0 = <&i2c5m0_xfer>;
status = "disabled";
};
i2s0_8ch: i2s@ff800000 {
compatible = "rockchip,rv1126-i2s-tdm";
reg = <0xff800000 0x1000>;
interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru MCLK_I2S0_TX>, <&cru MCLK_I2S0_RX>, <&cru HCLK_I2S0>;
clock-names = "mclk_tx", "mclk_rx", "hclk";
dmas = <&dmac 20>, <&dmac 19>;
dma-names = "tx", "rx";
resets = <&cru SRST_I2S0_TX_M>, <&cru SRST_I2S0_RX_M>;
reset-names = "tx-m", "rx-m";
rockchip,cru = <&cru>;
rockchip,grf = <&grf>;
pinctrl-names = "default";
pinctrl-0 = <&i2s0m0_sclk_tx
&i2s0m0_sclk_rx
&i2s0m0_lrck_tx
&i2s0m0_lrck_rx
&i2s0m0_sdi0
&i2s0m0_sdo0
&i2s0m0_sdo1_sdi3
&i2s0m0_sdo2_sdi2
&i2s0m0_sdo3_sdi1>;
status = "disabled";
}
i2s1_2ch: i2s@ff810000 {
compatible = "rockchip,rv1126-i2s", "rockchip,rk3066-i2s";
reg = <0xff810000 0x1000>;
interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru MCLK_I2S1>, <&cru HCLK_I2S1>;
clock-names = "i2s_clk", "i2s_hclk";
dmas = <&dmac 22>, <&dmac 21>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&i2s1m0_sclk
&i2s1m0_lrck
&i2s1m0_sdi
&i2s1m0_sdo>;
status = "disabled";
};
i2s2_2ch: i2s@ff820000 {
compatible = "rockchip,rv1126-i2s", "rockchip,rk3066-i2s";
reg = <0xff820000 0x1000>;
interrupts = <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru MCLK_I2S2>, <&cru HCLK_I2S2>;
clock-names = "i2s_clk", "i2s_hclk";
dmas = <&dmac 24>, <&dmac 23>;
dma-names = "tx", "rx";
pinctrl-names = "default";
pinctrl-0 = <&i2s2m0_sclk
&i2s2m0_lrck
&i2s2m0_sdi
&i2s2m0_sdo>;
status = "disabled";
};
*/
/*rt5640-sound {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "rockchip,rt5640-codec";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Mic Jack", "MICBIAS1",
"IN1P", "Mic Jack",
"Headphone Jack", "HPOL",
"Headphone Jack", "HPOR";
simple-audio-card,cpu {
sound-dai = <&i2s_8ch>;//cup dai device
};
simple-audio-card,codec {
sound-dai = <&rt5640>;//codec dai device
};
};
//codec dai device
&i2c1 {
status = "okay";
rt5640: rt5640@1c {
#sound-dai-cells = <0>;
compatible = "realtek,rt5640";
reg = <0x1c>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk";
realtek,in1-differential;
};
};*/
安检门板子DTSI
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
* Copyright (c) 2020 Rockchip Electronics Co., Ltd.
*/
#include "rv1126-evb-v13.dtsi"
/ {
es7243_sound_1: es7243-sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s0_8ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243_0
&es7243_1
&es7243_2
&es7243_3
>;
};
};
es7243_sound_2: es7243-sound {
status = "disabled";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = <&i2s2_2ch>;
};
simple-audio-card,codec {
sound-dai = <&es7243_5>;
};
};
es7243_sound_3: es7243-sound {
status = "disabled";
compatible = "simple-audio-card";
simple-audio-card,name = "rockchip,es7243";
simple-audio-card,format = "i2s";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,cpu {
sound-dai = < &i2s1_2ch>;
};
simple-audio-card,codec {
sound-dai = < &es7243_4>;
};
};
};
/*&wireless-bluetooth {
status = "okay";
};*/
&wireless_wlan {
clocks = <&rk809 0>;
//WIFI,poweren_gpio = <&gpio0 RK_PA6 GPIO_ACTIVE_HIGH>;
//WIFI,host_wake_irq = <&gpio0 RK_PB0 GPIO_ACTIVE_HIGH>;
wifi_chip_type = "rtl8723ds";
status = "okay";
};
&sdio {
max-frequency = <150000000>;
status = "okay";
};
//debug uart
&fiq_debugger {
//status = "okay";
compatible = "rockchip,fiq-debugger";
rockchip,baudrate = <115200>; /* Only 115200 and 1500000 */
};
&ov4689 {
status = "disabled";
};
&os04a10 {
status = "disabled";
};
&rk809_sound {
status = "disabled";
};
/********************************************************************************************/
&backlight {
pwms = <&pwm10 0 25000 0>;
};
&pwm10 {
status = "okay";
pinctrl-names = "active";
//if use zhaji board open this
//pinctrl-0 = <&pwm10m1_pins_pull_down>;
pinctrl-0 = <&pwm10m0_pins_pull_down>;
};
&pwm3 {
status = "disabled";
};
//SHENZHEN FRIDA LCD CO.,LTD Model No:FRD700B30012-B
&dsi {
status = "okay";
rockchip,lane-rate = <480>;
panel@0 {
compatible = "frida,ek79007ad", "simple-panel-dsi";
reg = <0>;
backlight = <&backlight>;
prepare-delay-ms = <10>;
reset-delay-ms = <10>;
init-delay-ms = <120>;
disable-delay-ms = <20>;
unprepare-delay-ms = <10>;
reset-gpios = <&gpio2 RK_PC7 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>;
width-mm = <154>;
height-mm = <86>;
panel-init-sequence = [
15 00 02 80 8b
15 00 02 81 78
15 00 02 82 84
15 00 02 83 88
15 00 02 84 a8
15 00 02 85 ae
15 00 02 86 88
];
display-timings {
native-mode = <&timing0>;
timing0: timing0 {
clock-frequency = <51000000>;
hactive = <1024>;
vactive = <600>;
hfront-porch = <160>;
hsync-len = <70>;
hback-porch = <90>;
vfront-porch = <12>;
vsync-len = <10>;
vback-porch = <13>;
hsync-active = <1>;
vsync-active = <0>;
de-active = <0>;
pixelclk-active = <0>;
};
};
};
};
&uart0 {
status = "okay";
};
/*********************************************************************************/
&i2c5 {
status = "disabled";
clock-frequency = <400000>;
gt1x: gt1x@14 {
compatible = "goodix,gt1x";
reg = <0x14>;
gtp_ics_slot_report;
power-supply = <&vcc18_lcd_n>;
goodix,rst-gpio = <&gpio2 RK_PB0 GPIO_ACTIVE_HIGH>;
goodix,irq-gpio = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
};
};
&i2c2 {
status = "okay";
clock-frequency = <400000>;
gt9xx: gt9xx@5d {
compatible = "goodix,gt9xx";
status = "okay";
reg = <0x5d>;
irq-gpios = <&gpio2 RK_PB2 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>;
irq-flags = <2>;
touchscreen-size-x = <720>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
touchscreen-size-y = <1280>; // 设置为触摸屏的最大分辨率,而不是屏幕的分辨率
goodix,pen-suppress-finger = <1>;
goodix,swap-x2y = <1>;
goodix,int-sync = <1>; // 注意这个必须要
};
//rtc zt0701
sd3078@32 {
status = "okay";
compatible = "rockchip,sd3078";
reg = <0x32>;
};
};
/************************************************************************************/
//Dts 的 codec 的i2c部分:
//Dts 的 platform 的 i2s 部分:
//i2c adapter3 信息
/* rk809_codec: codec {
#sound-dai-cells = <0>;
compatible = "rockchip,rk809-codec", "rockchip,rk817-codec";
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
pinctrl-names = "default";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
pinctrl-0 = <&i2s0m0_mclk>;
hp-volume = <20>;
spk-volume = <3>;
};*/
&i2c3{
clock-frequency = <400000>;//设置传输速率 400k
pinctrl-names = "default";
pinctrl-0 = <&i2c3m1_xfer>;
status = "okay";
es7243_0: es7243_0@11{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;//?还不知道这个时钟要怎么选,明天看看sdk关于i2c的文档怎搞
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_1: es7243_1@12{
#sound-dai-cells = <0>;
compatible = "MicArray_2";
reg = <0x12>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_2: es7243_2@10{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_3: es7243_3@13{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
};
&i2c1{
clock-frequency = <400000>;//设置传输速率 400k
//pinctrl-names = "default";
//pinctrl-0 = <&i2c3m1_xfer>;
status = "okay";
es7243_4: es7243_4@11{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
es7243_5: es7243_5@13{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
};
&i2s0_8ch {
status = "okay";
/*#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
rockchip,i2s-rx-route = <3 1 2 0>;*/
pinctrl-names = "default";
pinctrl-0 = <
&i2s0m1_mclk
//&i2s0m1_sclk_tx
&i2s0m1_sclk_rx
//&i2s0m1_lrck_tx
&i2s0m1_lrck_rx
&i2s0m1_sdi0
//&i2s0m1_sdo0
&i2s0m1_sdo1_sdi3
&i2s0m1_sdo2_sdi2
&i2s0m1_sdo3_sdi1>;
};
&i2s1_2ch {
status = "okay";
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = <3 1 2 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s1m1_sclk
&i2s1m1_lrck
&i2s1m1_sdo
&i2s1m1_sdi
&i2s1m1_mclk>;
};
&i2s2_2ch {
status = "okay";
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = <3 1 2 0>;
pinctrl-names = "default";
pinctrl-0 = <&i2s2m1_sclk
&i2s2m1_lrck
&i2s2m1_sdo
&i2s2m1_sdi
&i2s2m1_mclk>;
};
/*********************************************************************************************/
&gmac {
phy-mode = "rmii";
clock_in_out = "input";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = "okay";
phy: phy@0 {
status = "okay";
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
es7243_2: es7243_2@10{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x10>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
es7243_3: es7243_3@13{
#sound-dai-cells = <0>;
compatible = "MicArray_3";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_RX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_RX>;
};
};
&i2c1{
clock-frequency = <400000>;//设置传输速率 400k
//pinctrl-names = “default”;
//pinctrl-0 = <&i2c3m1_xfer>;
status = “okay”;
es7243_4: es7243_4@11{
#sound-dai-cells = <0>;
compatible = "MicArray_0";
reg = <0x11>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
es7243_5: es7243_5@13{
#sound-dai-cells = <0>;
compatible = "MicArray_1";
reg = <0x13>;
clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
clock-names = "mclk";
assigned-clocks = <&cru MCLK_I2S0_TX_OUT2IO>;
assigned-clock-parents = <&cru MCLK_I2S0_TX>;
};
};
&i2s0_8ch {
status = “okay”;
/#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
rockchip,i2s-rx-route = ❤️ 1 2 0>;/
pinctrl-names = “default”;
pinctrl-0 = <
&i2s0m1_mclk
//&i2s0m1_sclk_tx
&i2s0m1_sclk_rx
//&i2s0m1_lrck_tx
&i2s0m1_lrck_rx
&i2s0m1_sdi0
//&i2s0m1_sdo0
&i2s0m1_sdo1_sdi3
&i2s0m1_sdo2_sdi2
&i2s0m1_sdo3_sdi1>;
};
&i2s1_2ch {
status = “okay”;
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = ❤️ 1 2 0>;
pinctrl-names = “default”;
pinctrl-0 = <&i2s1m1_sclk
&i2s1m1_lrck
&i2s1m1_sdo
&i2s1m1_sdi
&i2s1m1_mclk>;
};
&i2s2_2ch {
status = “okay”;
#sound-dai-cells = <0>;
rockchip,clk-trcm = <1>;
//rockchip,i2s-rx-route = ❤️ 1 2 0>;
pinctrl-names = “default”;
pinctrl-0 = <&i2s2m1_sclk
&i2s2m1_lrck
&i2s2m1_sdo
&i2s2m1_sdi
&i2s2m1_mclk>;
};
/*********************************************************************************************/
&gmac {
phy-mode = “rmii”;
clock_in_out = “input”;
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;//根据原理图设置复位gpio
snps,reset-active-low;
snps,reset-delays-us = <0 20000 100000>;
assigned-clocks = <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>, <&cru CLK_GMAC_ETHERNET_OUT>;
assigned-clock-rates = <50000000>, <0>, <25000000>;//设置上面3个时钟频率
assigned-clock-parents = <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;// <&ext_gmac>;
//这里的意思是设置CLK_GMAC_SRC_M1为CLK_GMAC_SRC的父时钟,RMII_MODE_CLK设置为CLK_GMAC_ETHERNET_OUT的父时钟
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level3_pins>;//设置用到的数据gpio
//pinctrl-0 = <&rmiim1_pins>;
//tx_delay = <0x30>;
//rx_delay = <0x10>;
phy-handle = <&phy>;
status = "okay";
/*phy-mode = "rmii";
clock_in_out = "output";
snps,reset-gpio = <&gpio2 RK_PA5 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
snps,reset-delays-us = <0 20000 10000>;
assigned-clocks = <&cru CLK_GMAC_SRC_M1>, <&cru CLK_GMAC_SRC>, <&cru CLK_GMAC_TX_RX>;
assigned-clock-rates = <0>, <50000000>;
assigned-clock-parents = <&cru CLK_GMAC_RGMII_M1>, <&cru CLK_GMAC_SRC_M1>, <&cru RMII_MODE_CLK>;
pinctrl-names = "default";
pinctrl-0 = <&rmiim1_pins &gmac_clk_m1_pins &gmac_clk_m1_drv_level0_pins>;
phy-handle = <&phy>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};*/
};
&mdio {
status = “okay”;
phy: phy@0 {
status = “okay”;
compatible = “ethernet-phy-ieee802.3-c22”;
reg = <0x0>;
clocks = <&cru CLK_GMAC_ETHERNET_OUT>;
};
};
/*
疑问:
1.怎么分配数据管脚?
2.clock 怎么选择?
*/
版权声明:本文为CSDN博主「自学Linux记录」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43209963/article/details/119458150
暂无评论