创龙TL570x-EVM评估板--调试rx8025驱动
本帖最后由 eefocus_3828686 于 2022-4-9 00:30 编辑最近做项目剩余几颗rtc点点taptap安卓rx8025,这款时钟点点taptap安卓不用外接晶振,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$rtc-rx8025.c文件中的信息如下:
那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 Aug5 13:54 .
drwxr-xr-x 10 root root 0 Aug5 13:54 ..
lrwxrwxrwx 1 root root 0 Aug5 14:01 driver -> ../../../../../../bus/i2c/drivers/rtc-ds1307
-r--r--r-- 1 root root 4096 Aug5 14:01 modalias
-r--r--r-- 1 root root 4096 Aug5 14:01 name
lrwxrwxrwx 1 root root 0 Aug5 14:01 of_node -> ../../../../../../firmware/devicetree/base/ocp/i2c@4807a000/rtc@32
drwxr-xr-x 2 root root 0 Aug5 14:01 power
drwxr-xr-x 3 root root 0 Aug5 13:54 rtc
lrwxrwxrwx 1 root root 0 Aug5 13:54 subsystem -> ../../../../../../bus/i2c
-rw-r--r-- 1 root root 4096 Aug5 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 clockroot@AM57xx-Tronlong:/sys/bus/i2c/devices/3-0032# ls -al
drwxr-xr-x 4 root root 0 Aug5 13:54 .
drwxr-xr-x 10 root root 0 Aug5 13:54 ..
-rw-r--r-- 1 root root 4096 Aug5 14:10 clock_adjust_ppb
lrwxrwxrwx 1 root root 0 Aug5 14:10 driver -> ../../../../../../bus/i2c/drivers/rtc-rx8025
-r--r--r-- 1 root root 4096 Aug5 14:10 modalias
-r--r--r-- 1 root root 4096 Aug5 14:10 name
lrwxrwxrwx 1 root root 0 Aug5 14:10 of_node -> ../../../../../../firmware/devicetree/base/ocp/i2c@4807a000/rtc@32
drwxr-xr-x 2 root root 0 Aug5 14:10 power
drwxr-xr-x 3 root root 0 Aug5 13:54 rtc
lrwxrwxrwx 1 root root 0 Aug5 13:54 subsystem -> ../../../../../../bus/i2c
-rw-r--r-- 1 root root 4096 Aug5 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;
s32 ret = -1;
s32 retries = 0;
msgs.flags = !I2C_M_RD;
msgs.addr= client->addr;
msgs.len = 1;
msgs.buf = &buf;
msgs.flags = I2C_M_RD;
msgs.addr= client->addr;
msgs.len = len - 1;
msgs.buf = &buf;
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 = { 0 };
buf = RX8025_REG_CTRL2;
buf = 0;
rx8025_i2c_read(rx8025->client, buf, 2);
ctrl2 = buf;
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 = { 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说明点点taptap安卓检测到掉电了,但是点点taptap安卓正常上着点呢,再细看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, 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 & ~RX8025_BIT_CTRL1_TEST;
if (ctrl & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) {
dev_warn(&client->dev, "Alarm was detected\n");
need_clear = 1;
}
if (ctrl & RX8025_BIT_CTRL2_CTFG)
need_clear = 1;
if (need_clear) {
ctrl2 = ctrl;
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
<<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
Thu Aug5 14:15:49 20210.000000 seconds
root@AM57xx-Tronlong:~# hwclock -u
<<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
Thu Aug5 14:15:51 20210.000000 seconds
root@AM57xx-Tronlong:~# hwclock -u
<<-DBG-INFO->> File:drivers/rtc/rtc-rx8025.c@Func:rx8025_check_validity@Line:151 RX8025_REG_CTRL2:0xa0
Thu Aug5 14:15:53 20210.000000 seconds
root@AM57xx-Tronlong:~#
linux-4.9.65使用rtc-rx8025.c作为rx8025驱动总结:
1、设备树添加对rx8025的支持,把其他rtc点点taptap安卓的节点注释掉
2、注释掉rtc-ds1037.c里对rx8025的支持
3、rtc-rx8025.c里去掉所有“<< 4”字样;根据实际板子供电情况,设置rx8025的掉电电压阈值
最近刚入手了同款,学习一下
页:
[1]