TA的每日心情 | 奋斗 2025-6-6 13:54 |
|---|
签到天数: 49 天 连续签到: 1 天 [LV.5]常住居民I
进士
- 积分
- 1093
|
本帖最后由 eefocus_3828686 于 2022-4-9 00:30 编辑
最近做项目剩余几颗rtc芯片rx8025,这款时钟芯片不用外接晶振,i2c接口,连接即用,于是焊接了一个简易的板子,连接在创龙TL570x-EVM评估板子上调试体验一下,实物图如下:
在此也附上rx8025数据手册:
打开内核源码,版本为linux-4.9.65,发现内核驱动代码中已经自带了rx8025的驱动源码了:
- pix@ubuntu:~/tronlong/AM57x/kernel$ ls drivers/rtc/rtc-rx8025.c
- drivers/rtc/rtc-rx8025.c
- pix@ubuntu:~/tronlong/AM57x/kernel$
复制代码
那ok,先编译出来试试看能不能用再说,设备树修改如下:
- /* rtc0 = &ds1340; */
- rtc0 = &rx8025;
复制代码- /*
- ds1340: rtc@68 {
- compatible = "dallas,ds1340";
- reg = <0x68>;
- trickle-resistor-ohms = <250>;
- };
- */
- rx8025: rtc@32{
- compatible = "rx8025";
- reg = <0x32>;
- };
复制代码
编译选项配置,添加对rx8025支持:
编译、下载、启动,发现有打印信息如下:
- [ 4.968663] rtc-ds1307 3-0032: power-on detected
- [ 4.974045] rtc-ds1307 3-0032: voltage drop detected
- [ 4.980406] rtc-ds1307 3-0032: rtc core: registered rx8025 as rtc0
- [ 4.986712] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
复制代码 好像不太对,设备树里明明已经注释掉了ds1307这个节点了,怎么打印信息了还会出现rtc-ds1307这个设备驱动呢?看一眼rx8025的i2c子节点信息,在/sys/bus/i2c/devices/3-0032里:
- root@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032# ls -al
- drwxr-xr-x 4 root root 0 Aug 5 13:54 .
- drwxr-xr-x 10 root root 0 Aug 5 13:54 ..
- lrwxrwxrwx 1 root root 0 Aug 5 14:01 driver -> ../../../../../../bus/i2c/drivers/rtc-ds1307
- -r--r--r-- 1 root root 4096 Aug 5 14:01 modalias
- -r--r--r-- 1 root root 4096 Aug 5 14:01 name
- lrwxrwxrwx 1 root root 0 Aug 5 14:01 of_node -> ../../../../../../firmware/devicetree/base/ocp/i2c@4807a000/rtc@32
- drwxr-xr-x 2 root root 0 Aug 5 14:01 power
- drwxr-xr-x 3 root root 0 Aug 5 13:54 rtc
- lrwxrwxrwx 1 root root 0 Aug 5 13:54 subsystem -> ../../../../../../bus/i2c
- -rw-r--r-- 1 root root 4096 Aug 5 13:54 uevent
- root@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032#
复制代码 发现“rx8025: rtc@32”这个设备节点的驱动匹配到“drivers/rtc-ds1307”去了,在rtc-ds1037.c里有如下信息:
- static struct i2c_driver ds1307_driver = {
- .driver = {
- .name = "rtc-ds1307",
- },
- .probe = ds1307_probe,
- .remove = ds1307_remove,
- .id_table = ds1307_id,
- };
复制代码 由以上可知,rx8025确实匹配到rtc-ds1037.c这个驱动文件了,再细看rtc-ds1037.c里有如下信息:
- static const struct i2c_device_id ds1307_id[] = {
- { "ds1307", ds_1307 },
- { "ds1337", ds_1337 },
- { "ds1338", ds_1338 },
- { "ds1339", ds_1339 },
- { "ds1388", ds_1388 },
- { "ds1340", ds_1340 },
- { "ds3231", ds_3231 },
- { "m41t00", m41t00 },
- { "mcp7940x", mcp794xx },
- { "mcp7941x", mcp794xx },
- { "pt7c4338", ds_1307 },
- { "rx8025", rx_8025 },
- { "isl12057", ds_1337 },
- { }
- };
- MODULE_DEVICE_TABLE(i2c, ds1307_id);
复制代码 原来如此,rtc-ds1037.c里有rx8025的支持,那好,我们姑且把它注释掉:
- /* { "rx8025", rx_8025 }, */
复制代码 编译、下载、启动,发现有打印信息如下:
- [ 4.973593] <font color="#ff0000">rtc-rx8025</font> 3-0032: power voltage drop detected
- [ 4.979111] <font color="#ff0000">rtc-rx8025</font> 3-0032: power-on reset detected, date is <font color="#ff0000">invalid</font>
- [ 4.986577] <font color="#ff0000">rtc-rx8025</font> 3-0032: rtc core: registered rx8025 as rtc0
- [ 4.992886] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
- [ 5.000227] input: gpio_keys as /devices/platform/gpio_keys/input/input0
- [ 5.008081] <font color="#ff0000">rtc-rx8025</font> 3-0032: power voltage drop detected
- [ 5.013683] <font color="#ff0000">rtc-rx8025</font> 3-0032: power-on reset detected, date is <font color="#ff0000">invalid</font>
- [ 5.020350] <font color="#ff0000">rtc-rx8025</font> 3-0032: hctosys: unable to read the hardware clock
复制代码- root@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032# ls -al
- drwxr-xr-x 4 root root 0 Aug 5 13:54 .
- drwxr-xr-x 10 root root 0 Aug 5 13:54 ..
- -rw-r--r-- 1 root root 4096 Aug 5 14:10 clock_adjust_ppb
- lrwxrwxrwx 1 root root 0 Aug 5 14:10 driver -> ../../../../../../bus/i2c/drivers/rtc-rx8025
- -r--r--r-- 1 root root 4096 Aug 5 14:10 modalias
- -r--r--r-- 1 root root 4096 Aug 5 14:10 name
- lrwxrwxrwx 1 root root 0 Aug 5 14:10 of_node -> ../../../../../../firmware/devicetree/base/ocp/i2c@4807a000/rtc@32
- drwxr-xr-x 2 root root 0 Aug 5 14:10 power
- drwxr-xr-x 3 root root 0 Aug 5 13:54 rtc
- lrwxrwxrwx 1 root root 0 Aug 5 13:54 subsystem -> ../../../../../../bus/i2c
- -rw-r--r-- 1 root root 4096 Aug 5 13:54 uevent
复制代码
好了,看来已经匹配上rx8025已经和rtc-rx8025.c匹配上了,但是提示一堆invalid,源码里:
- static int rx8025_check_validity(struct device *dev)
- {
- struct rx8025_data *rx8025 = dev_get_drvdata(dev);
- int ctrl2;
- ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
- if (ctrl2 < 0)
- return ctrl2;
- if (ctrl2 & RX8025_BIT_CTRL2_VDET)
- dev_warn(dev, "power voltage drop detected\n");
- if (ctrl2 & RX8025_BIT_CTRL2_PON) {
复制代码 添加打印,看看RX8025_REG_CTRL2寄存器的值是什么:
- printk("<<-DBG-INFO->> File:%s@Func:%s@Line:%d RX8025_REG_CTRL2:0x%02x\r\n",__FILE__,__func__,__LINE__, ctrl2);
复制代码 编译、下载、启动,发现有打印信息如下:
- [ 4.973445] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:115 RX8025_REG_CTRL2:0xff
复制代码 可见i2c读出RX8025_REG_CTRL2寄存器的值为0xff,感觉不太对,难道是rtc-rx8025.c的i2c总线有问题?好了,自己组包来读寄存器试试看,如下:- s32 rx8025_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
- {
- struct i2c_msg msgs[2];
- s32 ret = -1;
- s32 retries = 0;
- msgs[0].flags = !I2C_M_RD;
- msgs[0].addr = client->addr;
- msgs[0].len = 1;
- msgs[0].buf = &buf[0];
-
- msgs[1].flags = I2C_M_RD;
- msgs[1].addr = client->addr;
- msgs[1].len = len - 1;
- msgs[1].buf = &buf[1];
- while(retries < 5){
- ret = i2c_transfer(client->adapter, msgs, 2);
- if(ret == 2)break;
- retries++;
- }
- if((retries >= 5)){
- ret = -1;
- }
-
- return ret;
- }
复制代码- static int rx8025_check_validity(struct device *dev)
- {
- struct rx8025_data *rx8025 = dev_get_drvdata(dev);
- int ctrl2;
- u8 buf[2] = { 0 };
- buf[0] = RX8025_REG_CTRL2;
- buf[1] = 0;
- rx8025_i2c_read(rx8025->client, buf, 2);
- ctrl2 = buf[1];
- if (ctrl2 < 0)
- return ctrl2;
- printk("<<-DBG-INFO->> File:%s@Func:%s@Line:%d RX8025_REG_CTRL2:0x%02x\r\n",__FILE__,__func__,__LINE__, ctrl2);
- if (ctrl2 & RX8025_BIT_CTRL2_VDET)
- dev_warn(dev, "power voltage drop detected\n");
- if (ctrl2 & RX8025_BIT_CTRL2_PON) {
- dev_warn(dev, "power-on reset detected, date is invalid\n");
- return -EINVAL;
- }
- if (!(ctrl2 & RX8025_BIT_CTRL2_XST)) {
- dev_warn(dev, "crystal stopped, date is invalid\n");
- return -EINVAL;
- }
- return 0;
- }
复制代码
编译、下载、启动,打印信息如下:
- [ 4.973531] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:150 RX8025_REG_CTRL2:0x40
复制代码 可见i2c读出RX8025_REG_CTRL2寄存器的值为0x40,看来rtc-rx8025.c原有的读写接口确实有问题,看一眼:
- static s32 rx8025_read_reg(const struct i2c_client *client, u8 number)
- {
- return i2c_smbus_read_byte_data(client, number << 4);
- }
- static int rx8025_read_regs(const struct i2c_client *client,
- u8 number, u8 length, u8 *values)
- {
- int ret = i2c_smbus_read_i2c_block_data(client, number << 4, length, values);
- if (ret != length)
- return ret < 0 ? ret : -EIO;
- return 0;
- }
- static s32 rx8025_write_reg(const struct i2c_client *client, u8 number,
- u8 value)
- {
- return i2c_smbus_write_byte_data(client, number << 4, value);
- }
- static s32 rx8025_write_regs(const struct i2c_client *client,
- u8 number, u8 length, const u8 *values)
- {
- return i2c_smbus_write_i2c_block_data(client, number << 4, length, values);
- }
复制代码 果然,读写时寄存器地址全部都给左移了4位,把以上四处“<< 4”删除掉,rx8025_check_validity函数恢复原样:
- static int rx8025_check_validity(struct device *dev)
- {
- struct rx8025_data *rx8025 = dev_get_drvdata(dev);
- int ctrl2;
- u8 buf[2] = { 0 };
- ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
- if (ctrl2 < 0)
- return ctrl2;
- printk("<<-DBG-INFO->> File:%s@Func:%s@Line:%d RX8025_REG_CTRL2:0x%02x\r\n",__FILE__,__func__,__LINE__, ctrl2);
- if (ctrl2 & RX8025_BIT_CTRL2_VDET)
- dev_warn(dev, "power voltage drop detected\n");
- if (ctrl2 & RX8025_BIT_CTRL2_PON) {
- dev_warn(dev, "power-on reset detected, date is invalid\n");
- return -EINVAL;
- }
- if (!(ctrl2 & RX8025_BIT_CTRL2_XST)) {
- dev_warn(dev, "crystal stopped, date is invalid\n");
- return -EINVAL;
- }
- return 0;
- }
复制代码
编译、下载、启动,打印信息如下:
- [ 5.012655] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0x40
复制代码 好了,读出来也是0x40,说明i2c读写是正常了,但是rx8025并没有正常工作。查询rx8025手册可知RX8025_REG_CTRL2寄存器0x40说明芯片检测到掉电了,但是芯片正常上着点呢,再细看RX8025_REG_CTRL2寄存器第7位为0,即2.1V为掉电阈值,我们把RX8025_REG_CTRL2寄存器第7位置1,即把掉电阈值设置为1.3V试试看,初始化函数后面添加以下代码:
- static int rx8025_init_client(struct i2c_client *client)
- {
- struct rx8025_data *rx8025 = i2c_get_clientdata(client);
- u8 ctrl[2], ctrl2;
- int need_clear = 0;
- int err;
- err = rx8025_read_regs(rx8025->client, RX8025_REG_CTRL1, 2, ctrl);
- if (err)
- goto out;
- /* Keep test bit zero ! */
- rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST;
- if (ctrl[1] & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) {
- dev_warn(&client->dev, "Alarm was detected\n");
- need_clear = 1;
- }
- if (ctrl[1] & RX8025_BIT_CTRL2_CTFG)
- need_clear = 1;
- if (need_clear) {
- ctrl2 = ctrl[1];
- ctrl2 &= ~(RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG |
- RX8025_BIT_CTRL2_DAFG);
- err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);
- }
- #define RX8025_BIT_CTRL2_VDSL BIT(7)
- ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
- ctrl2 |= RX8025_BIT_CTRL2_VDSL;
- err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);
- out:
- return err;
- }
复制代码 编译、下载、启动,打印信息如下:
- [ 4.779513] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
- [ 4.790526] rtc-rx8025 3-0032: rtc core: registered rx8025 as rtc0
- [ 4.796837] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
- [ 4.804221] input: gpio_keys as /devices/platform/gpio_keys/input/input0
- [ 4.812087] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
- [ 4.823032] rtc-rx8025 3-0032: setting system clock to 2021-08-05 06:09:50 UTC (1628143790)
复制代码 OK,rx8025已成功作为系统启动时钟rtc0,终端下读取RTC时钟,正常输出:
- root@AM57xx-Tronlong:~# hwclock -u
- [ 363.207246] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
- Thu Aug 5 14:15:49 2021 0.000000 seconds
- root@AM57xx-Tronlong:~# hwclock -u
- [ 365.624086] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
- Thu Aug 5 14:15:51 2021 0.000000 seconds
- root@AM57xx-Tronlong:~# hwclock -u
- [ 367.402024] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
- Thu Aug 5 14:15:53 2021 0.000000 seconds
- root@AM57xx-Tronlong:~#
复制代码
linux-4.9.65使用rtc-rx8025.c作为rx8025驱动总结:
1、设备树添加对rx8025的支持,把其他rtc芯片的节点注释掉
2、注释掉rtc-ds1037.c里对rx8025的支持
3、rtc-rx8025.c里去掉所有“<< 4”字样;根据实际板子供电情况,设置rx8025的掉电电压阈值
|
|