ZYNQ:Linux添加I2C-RTC驱动
硬件情况
使用的是DS1338
这款RTC时钟芯片,I2C总线对应到PS端的I2C1。
配置
内核
添加有关的驱动:
因为DS1338用的驱动与DS13307相似,一找发现是同一个配置。
CONFIG_RTC_DRV_DS1307
Device Drivers --->
[*] Real Time Clock --->
<*> Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057
[ ] HWMON support for rtc-ds130
[ ] Century bit support for rtc-ds1307
设备树
修改system-user.dtsi
,添加有关的设备树:
编译内核以后发现rtc时钟还是不能用。
查阅文档时,根据其他人的问题描述,才想起来发现需要使用设备树。
&i2c1 { // 根据 zynq-7000.dtsi,选择了i2c1
status = "okay"; // 开启
#address-cells = <1>;
#size-cells = <0>;
// 添加 RTC 设备节点, @68 代表设备地址
rtc0:rtc-ds1338@68 {
// 根据 drivers/rtc/rtc-ds1307.c 中的 compatible 表 找到的。
compatible = "dallas,ds1338";
// 设备地址
reg = <0x68>; // PDF P13 : 1101 000 R/nW , 0x68+ R/nW
};
};
附录:RTC配置调试记录
寻找ds1338驱动
$ cd drivers/rtc
$ alias ft="grep -nR 2>/dev/null"
$ ft 1338
Kconfig:234: should handle DS1307, DS1337, DS1338, DS1339, DS1340, DS1341,
Binary file rtc-ds1307.o matches
rtc-ds1307.c:39: ds_1338,
rtc-ds1307.c:78:#define DS1307_REG_CONTROL 0x07 /* or ds1338 */
rtc-ds1307.c:80:# define DS1338_BIT_OSF 0x20
rtc-ds1307.c:189: [ds_1338] = {
rtc-ds1307.c:244: { "ds1338", ds_1338 },
rtc-ds1307.c:277: .compatible = "dallas,ds1338",
rtc-ds1307.c:278: .data = (void *)ds_1338
rtc-ds1307.c:338: { .id = "DS1338", .driver_data = ds_1338 },
rtc-ds1307.c:1563: case ds_1338:
rtc-ds1307.c:1569: if (regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
rtc-ds1307.c:1572: ~DS1338_BIT_OSF);
在drivers/rtc/rtc-ds1307.c
发现了对应的设备树适配接口:
static const struct of_device_id ds1307_of_match[] = {
{
.compatible = "dallas,ds1307",
.data = (void *)ds_1307
},
{
.compatible = "dallas,ds1308",
.data = (void *)ds_1308
},
{
.compatible = "dallas,ds1337",
.data = (void *)ds_1337
},
{
.compatible = "dallas,ds1338", // 我所需要的设备树节点属性
.data = (void *)ds_1338
},
{
.compatible = "dallas,ds1339",
.data = (void *)ds_1339
},
{
.compatible = "dallas,ds1388",
.data = (void *)ds_1388
},
知道后面应该会使用到compatible = "dallas,ds1338"
,复制了下来。
配置i2c总线
本文地址:https://www.cnblogs.com/schips/p/xilinx_zynq_linux_config_rtc_with_dts.html
之前配置好了I2C总线以后,能够找到2个i2c总线驱动:
# ls /dev/i2c-*
/dev/i2c-0 /dev/i2c-1
但是发现一直不行。
# dmsg
...
hwclock: can't open '/dev/misc/rtc': No such file or directory
...
一度怀疑过是不是要手动创建设备节点(例如alsa),试过几次以后放弃了这个方向。
rtc从设备地址的确定
下载并翻阅了DS1338Z的手册,找到了读写地址有关描述:
设备地址(7位):1101000
= 0x68
设备读地址(BIT[0] = 1, R):11010001
= 0xD1
设备读地址(BIT[0] = 0, W):11010000
= 0xD0
移植使用i2c-tools
根据文档采用了i2c-tools
这个工具。
因为整个系统的源码是通过PetaLinux构建以后提取出来的,因此使用i2c-tools
也是需要事先移植。
移植很简单,见《arm linux 移植 i2c-tools 与 简单使用》
通过这个工具快速确定了总线、以及设备地址:
/mnt/i2c_tools/sbin# ./i2cdetect -l
i2c-1 i2c Cadence I2C at e0005000 I2C adapter
i2c-0 i2c Cadence I2C at e0004000 I2C adapter
/mnt/i2c_tools/sbin# ./i2cdump -f -y 1 0x68
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 28 52 23 02 02 01 00 b3 40 20 71 04 96 28 48 03 (R#???.?@ q??(H?
10: 80 00 42 c8 05 02 40 30 20 00 20 08 00 55 44 22 ?.B???@0 . ?.UD"
20: 49 a9 24 28 48 10 44 20 21 f1 2d a2 04 00 43 8c I?$(H?D !?-??.C?
30: 50 24 00 24 20 2c 14 20 01 a0 01 89 02 00 21 88 P$.$ ,? ?????.!?
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
80: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
更正设备树
根据这个情况,对设备树进行了改正。
其实是因为自己记错了总线,总以为是i2c-0
此后,rtc功能正常:
# dmsg
...
i2c /dev entries driver
cdns-i2c e0004000.i2c: 400 kHz mmio e0004000 irq 23
rtc-ds1307 1-0068: SET TIME!
rtc-ds1307 1-0068: registered as rtc0
cdns-i2c e0005000.i2c: 400 kHz mmio e0005000 irq 24
...
也能够通过hwclock
进行读写。
如果说我的文章对你有用,只不过是我站在巨人的肩膀上再继续努力罢了。
若在页首无特别声明,本篇文章由 Schips 经过整理后发布。
博客地址:https://www.cnblogs.com/schips/
若在页首无特别声明,本篇文章由 Schips 经过整理后发布。
博客地址:https://www.cnblogs.com/schips/