1回答

0收藏

创龙TL570x-EVM评估板--调试rx8025驱动

创龙科技 创龙科技 1432 人阅读 | 1 人回复 | 2022-04-08

本帖最后由 eefocus_3828686 于 2022-4-9 00:30 编辑

最近做项目剩余几颗rtc芯片rx8025,这款时钟芯片不用外接晶振,i2c接口,连接即用,于是焊接了一个简易的板子,连接在创龙TL570x-EVM评估板子上调试体验一下,实物图如下:

在此也附上rx8025数据手册:
RX-8025SA_en.pdf (747.02 KB, 下载次数: 3)

打开内核源码,版本为linux-4.9.65,发现内核驱动代码中已经自带了rx8025的驱动源码了:
  1. pix@ubuntu:~/tronlong/AM57x/kernel$ ls drivers/rtc/rtc-rx8025.c
  2. drivers/rtc/rtc-rx8025.c
  3. pix@ubuntu:~/tronlong/AM57x/kernel$
复制代码
  1. rtc-rx8025.c文件中的信息如下:
复制代码

那ok,先编译出来试试看能不能用再说,设备树修改如下:
  1. /* rtc0 = &ds1340; */
  2. rtc0 = &rx8025;
复制代码
  1. /*
  2.         ds1340: rtc@68 {
  3.                 compatible = "dallas,ds1340";
  4.                 reg = <0x68>;
  5.                 trickle-resistor-ohms = <250>;
  6.         };
  7.         */
  8.         rx8025: rtc@32{
  9.                 compatible = "rx8025";
  10.                 reg = <0x32>;
  11.         };
复制代码

编译选项配置,添加对rx8025支持:


编译、下载、启动,发现有打印信息如下:
  1. [    4.968663] rtc-ds1307 3-0032: power-on detected
  2. [    4.974045] rtc-ds1307 3-0032: voltage drop detected
  3. [    4.980406] rtc-ds1307 3-0032: rtc core: registered rx8025 as rtc0
  4. [    4.986712] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
复制代码
好像不太对,设备树里明明已经注释掉了ds1307这个节点了,怎么打印信息了还会出现rtc-ds1307这个设备驱动呢?看一眼rx8025的i2c子节点信息,在/sys/bus/i2c/devices/3-0032里
  1. root@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032# ls -al
  2. drwxr-xr-x    4 root     root             0 Aug  5 13:54 .
  3. drwxr-xr-x   10 root     root             0 Aug  5 13:54 ..
  4. lrwxrwxrwx    1 root     root             0 Aug  5 14:01 driver -> ../../../../../../bus/i2c/drivers/rtc-ds1307
  5. -r--r--r--    1 root     root          4096 Aug  5 14:01 modalias
  6. -r--r--r--    1 root     root          4096 Aug  5 14:01 name
  7. lrwxrwxrwx    1 root     root             0 Aug  5 14:01 of_node -> ../../../../../../firmware/devicetree/base/ocp/i2c@4807a000/rtc@32
  8. drwxr-xr-x    2 root     root             0 Aug  5 14:01 power
  9. drwxr-xr-x    3 root     root             0 Aug  5 13:54 rtc
  10. lrwxrwxrwx    1 root     root             0 Aug  5 13:54 subsystem -> ../../../../../../bus/i2c
  11. -rw-r--r--    1 root     root          4096 Aug  5 13:54 uevent
  12. root@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032#
复制代码
发现“rx8025: rtc@32”这个设备节点的驱动匹配到“drivers/rtc-ds1307”去了,在rtc-ds1037.c里有如下信息:
  1. static struct i2c_driver ds1307_driver = {
  2.         .driver = {
  3.                 .name        = "rtc-ds1307",
  4.         },
  5.         .probe                = ds1307_probe,
  6.         .remove                = ds1307_remove,
  7.         .id_table        = ds1307_id,
  8. };
复制代码
由以上可知,rx8025确实匹配到rtc-ds1037.c这个驱动文件了,再细看rtc-ds1037.c里有如下信息:
  1. static const struct i2c_device_id ds1307_id[] = {
  2.         { "ds1307", ds_1307 },
  3.         { "ds1337", ds_1337 },
  4.         { "ds1338", ds_1338 },
  5.         { "ds1339", ds_1339 },
  6.         { "ds1388", ds_1388 },
  7.         { "ds1340", ds_1340 },
  8.         { "ds3231", ds_3231 },
  9.         { "m41t00", m41t00 },
  10.         { "mcp7940x", mcp794xx },
  11.         { "mcp7941x", mcp794xx },
  12.         { "pt7c4338", ds_1307 },
  13.          { "rx8025", rx_8025 },
  14.         { "isl12057", ds_1337 },
  15.         { }
  16. };
  17. MODULE_DEVICE_TABLE(i2c, ds1307_id);
复制代码
原来如此,rtc-ds1037.c里有rx8025的支持,那好,我们姑且把它注释掉:
  1. /* { "rx8025", rx_8025 }, */
复制代码
编译、下载、启动,发现有打印信息如下:
  1. [    4.973593] <font color="#ff0000">rtc-rx8025</font> 3-0032: power voltage drop detected
  2. [    4.979111] <font color="#ff0000">rtc-rx8025</font> 3-0032: power-on reset detected, date is <font color="#ff0000">invalid</font>
  3. [    4.986577] <font color="#ff0000">rtc-rx8025</font> 3-0032: rtc core: registered rx8025 as rtc0
  4. [    4.992886] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
  5. [    5.000227] input: gpio_keys as /devices/platform/gpio_keys/input/input0
  6. [    5.008081] <font color="#ff0000">rtc-rx8025</font> 3-0032: power voltage drop detected
  7. [    5.013683] <font color="#ff0000">rtc-rx8025</font> 3-0032: power-on reset detected, date is <font color="#ff0000">invalid</font>
  8. [    5.020350] <font color="#ff0000">rtc-rx8025</font> 3-0032: hctosys: unable to read the hardware clock
复制代码
  1. root@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032# ls -al
  2. drwxr-xr-x    4 root     root             0 Aug  5 13:54 .
  3. drwxr-xr-x   10 root     root             0 Aug  5 13:54 ..
  4. -rw-r--r--    1 root     root          4096 Aug  5 14:10 clock_adjust_ppb
  5. lrwxrwxrwx    1 root     root             0 Aug  5 14:10 driver -> ../../../../../../bus/i2c/drivers/rtc-rx8025
  6. -r--r--r--    1 root     root          4096 Aug  5 14:10 modalias
  7. -r--r--r--    1 root     root          4096 Aug  5 14:10 name
  8. lrwxrwxrwx    1 root     root             0 Aug  5 14:10 of_node -> ../../../../../../firmware/devicetree/base/ocp/i2c@4807a000/rtc@32
  9. drwxr-xr-x    2 root     root             0 Aug  5 14:10 power
  10. drwxr-xr-x    3 root     root             0 Aug  5 13:54 rtc
  11. lrwxrwxrwx    1 root     root             0 Aug  5 13:54 subsystem -> ../../../../../../bus/i2c
  12. -rw-r--r--    1 root     root          4096 Aug  5 13:54 uevent
复制代码

好了,看来已经匹配上rx8025已经和rtc-rx8025.c匹配上了,但是提示一堆invalid,源码里:
  1. static int rx8025_check_validity(struct device *dev)
  2. {
  3.         struct rx8025_data *rx8025 = dev_get_drvdata(dev);
  4.         int ctrl2;

  5.         ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
  6.         if (ctrl2 < 0)
  7.                 return ctrl2;

  8.         if (ctrl2 & RX8025_BIT_CTRL2_VDET)
  9.             dev_warn(dev, "power voltage drop detected\n");

  10.         if (ctrl2 & RX8025_BIT_CTRL2_PON) {
复制代码
添加打印,看看RX8025_REG_CTRL2寄存器的值是什么:
  1. printk("<<-DBG-INFO->> File:%s@Func:%s@Line:%d RX8025_REG_CTRL2:0x%02x\r\n",__FILE__,__func__,__LINE__, ctrl2);
复制代码
编译、下载、启动,发现有打印信息如下:
  1. [    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总线有问题?好了,自己组包来读寄存器试试看,如下:
  1. s32 rx8025_i2c_read(struct i2c_client *client, u8 *buf, s32 len)
  2. {
  3.     struct i2c_msg msgs[2];
  4.     s32 ret = -1;
  5.     s32 retries = 0;

  6.     msgs[0].flags = !I2C_M_RD;
  7.     msgs[0].addr  = client->addr;
  8.     msgs[0].len   = 1;
  9.     msgs[0].buf   = &buf[0];
  10.    
  11.     msgs[1].flags = I2C_M_RD;
  12.     msgs[1].addr  = client->addr;
  13.     msgs[1].len   = len - 1;
  14.     msgs[1].buf   = &buf[1];

  15.     while(retries < 5){
  16.         ret = i2c_transfer(client->adapter, msgs, 2);
  17.         if(ret == 2)break;
  18.         retries++;
  19.     }

  20.         if((retries >= 5)){
  21.                 ret = -1;
  22.         }
  23.    
  24.     return ret;
  25. }
复制代码
  1. static int rx8025_check_validity(struct device *dev)
  2. {
  3.         struct rx8025_data *rx8025 = dev_get_drvdata(dev);
  4.         int ctrl2;
  5.         u8 buf[2] = { 0 };

  6.         buf[0] = RX8025_REG_CTRL2;
  7.         buf[1] = 0;
  8.         rx8025_i2c_read(rx8025->client, buf, 2);
  9.         ctrl2 = buf[1];
  10.         if (ctrl2 < 0)
  11.                 return ctrl2;
  12.         printk("<<-DBG-INFO->> File:%s@Func:%s@Line:%d RX8025_REG_CTRL2:0x%02x\r\n",__FILE__,__func__,__LINE__, ctrl2);
  13.         if (ctrl2 & RX8025_BIT_CTRL2_VDET)
  14.                 dev_warn(dev, "power voltage drop detected\n");

  15.         if (ctrl2 & RX8025_BIT_CTRL2_PON) {
  16.                 dev_warn(dev, "power-on reset detected, date is invalid\n");
  17.                 return -EINVAL;
  18.         }

  19.         if (!(ctrl2 & RX8025_BIT_CTRL2_XST)) {
  20.                 dev_warn(dev, "crystal stopped, date is invalid\n");
  21.                 return -EINVAL;
  22.         }

  23.         return 0;
  24. }
复制代码


编译、下载、启动,打印信息如下:
  1. [    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原有的读写接口确实有问题,看一眼:
  1. static s32 rx8025_read_reg(const struct i2c_client *client, u8 number)
  2. {
  3.         return i2c_smbus_read_byte_data(client, number << 4);
  4. }

  5. static int rx8025_read_regs(const struct i2c_client *client,
  6.                             u8 number, u8 length, u8 *values)
  7. {
  8.         int ret = i2c_smbus_read_i2c_block_data(client, number << 4, length, values);
  9.         if (ret != length)
  10.                 return ret < 0 ? ret : -EIO;

  11.         return 0;
  12. }

  13. static s32 rx8025_write_reg(const struct i2c_client *client, u8 number,
  14.                             u8 value)
  15. {
  16.         return i2c_smbus_write_byte_data(client, number << 4, value);
  17. }

  18. static s32 rx8025_write_regs(const struct i2c_client *client,
  19.                              u8 number, u8 length, const u8 *values)
  20. {
  21.         return i2c_smbus_write_i2c_block_data(client, number << 4, length, values);
  22. }
复制代码
果然,读写时寄存器地址全部都给左移了4位,把以上四处“<< 4”删除掉,rx8025_check_validity函数恢复原样:
  1. static int rx8025_check_validity(struct device *dev)
  2. {
  3.         struct rx8025_data *rx8025 = dev_get_drvdata(dev);
  4.         int ctrl2;
  5.         u8 buf[2] = { 0 };

  6.         ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
  7.         if (ctrl2 < 0)
  8.                 return ctrl2;
  9.         printk("<<-DBG-INFO->> File:%s@Func:%s@Line:%d RX8025_REG_CTRL2:0x%02x\r\n",__FILE__,__func__,__LINE__, ctrl2);
  10.         if (ctrl2 & RX8025_BIT_CTRL2_VDET)
  11.                 dev_warn(dev, "power voltage drop detected\n");

  12.         if (ctrl2 & RX8025_BIT_CTRL2_PON) {
  13.                 dev_warn(dev, "power-on reset detected, date is invalid\n");
  14.                 return -EINVAL;
  15.         }

  16.         if (!(ctrl2 & RX8025_BIT_CTRL2_XST)) {
  17.                 dev_warn(dev, "crystal stopped, date is invalid\n");
  18.                 return -EINVAL;
  19.         }

  20.         return 0;
  21. }
复制代码

编译、下载、启动,打印信息如下:
  1. [    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试试看,初始化函数后面添加以下代码:
  1. static int rx8025_init_client(struct i2c_client *client)
  2. {
  3.         struct rx8025_data *rx8025 = i2c_get_clientdata(client);
  4.         u8 ctrl[2], ctrl2;
  5.         int need_clear = 0;
  6.         int err;

  7.         err = rx8025_read_regs(rx8025->client, RX8025_REG_CTRL1, 2, ctrl);
  8.         if (err)
  9.                 goto out;

  10.         /* Keep test bit zero ! */
  11.         rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST;

  12.         if (ctrl[1] & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) {
  13.                 dev_warn(&client->dev, "Alarm was detected\n");
  14.                 need_clear = 1;
  15.         }

  16.         if (ctrl[1] & RX8025_BIT_CTRL2_CTFG)
  17.                 need_clear = 1;

  18.         if (need_clear) {
  19.                 ctrl2 = ctrl[1];
  20.                 ctrl2 &= ~(RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG |
  21.                            RX8025_BIT_CTRL2_DAFG);

  22.                 err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);
  23.         }

  24. #define RX8025_BIT_CTRL2_VDSL BIT(7)
  25.         ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
  26.         ctrl2 |= RX8025_BIT_CTRL2_VDSL;
  27.         err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);
  28. out:
  29.         return err;
  30. }
复制代码
编译、下载、启动,打印信息如下:
  1. [    4.779513] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
  2. [    4.790526] rtc-rx8025 3-0032: rtc core: registered rx8025 as rtc0
  3. [    4.796837] omap_i2c 4807a000.i2c: bus 3 rev0.12 at 400 kHz
  4. [    4.804221] input: gpio_keys as /devices/platform/gpio_keys/input/input0
  5. [    4.812087] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
  6. [    4.823032] rtc-rx8025 3-0032: setting system clock to 2021-08-05 06:09:50 UTC (1628143790)
复制代码
OK,rx8025已成功作为系统启动时钟rtc0,终端下读取RTC时钟,正常输出:
  1. root@AM57xx-Tronlong:~# hwclock -u
  2. [  363.207246] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
  3. Thu Aug  5 14:15:49 2021  0.000000 seconds
  4. root@AM57xx-Tronlong:~# hwclock -u
  5. [  365.624086] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
  6. Thu Aug  5 14:15:51 2021  0.000000 seconds
  7. root@AM57xx-Tronlong:~# hwclock -u
  8. [  367.402024] <<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
  9. Thu Aug  5 14:15:53 2021  0.000000 seconds
  10. 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的掉电电压阈值




分享到:
回复

使用道具 举报

回答|共 1 个

倒序浏览

沙发

jhcj2014

发表于 2022-4-14 10:53:47 | 只看该作者

最近刚入手了同款,学习一下
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条