(单总线的部分归单总线,RTC的部分归RTC,不可混淆)
DS2417是一个时间管理芯片,通过单总线和CPU相连。
linux内核版本使用的是2.6.35,CPU使用飞思卡尔imx53。
首先单总线驱动程序位于/kernel/drivers/w1,这个目录下有两个文件夹,分别是masters和slaves。imx53CPU单总线控制器部分代码在masters下,从主从关系出发,masters是单总线的主部分,slaves是单总线的从部分。所以slaves下包含的是单总线支持的各种芯片。但是我们的内核里并没有对ds2417的芯片进行支持,相关代码需要我们自行添加。masters中的代码我们不需要改变,在w1驱动中我们仅仅需要在slaves下添加w1_ds2417.c和w1_ds2417.h两个文件。
w1_ds2417.c源码:
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/idr.h>
#include "../w1.h"
#include "../w1_int.h"
#include "../w1_family.h"
#include "w1_ds2417.h"
static int w1_ds2417_io(struct device *dev, char *buf, size_t count,int io)
{
struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
if (!dev)
return 0;
mutex_lock(&sl->master->mutex);
w1_reset_bus(sl->master);
if (!w1_reset_select_slave(sl)) {
if (!io) {
w1_write_8(sl->master, W1_DS2417_READ_CLOCK);
count = w1_read_block(sl->master, buf, count);
} else {
w1_write_8(sl->master, W1_DS2417_WRITE_CLOCK);
w1_write_block(sl->master, buf, count);
/* XXX w1_write_block returns void, not n_written */
}
}
mutex_unlock(&sl->master->mutex);
return count;
}
int w1_ds2417_read(struct device *dev, char *buf, size_t count)
{
return w1_ds2417_io(dev, buf, count, 0);
}
int w1_ds2417_write(struct device *dev, char *buf, size_t count)
{
return w1_ds2417_io(dev, buf, count, 1);
}
static DEFINE_IDR(rtc_idr);
static DEFINE_MUTEX(rtc_idr_lock);
static int new_rtc_id(void)
{
int ret;
while (1) {
int id;
ret = idr_pre_get(&rtc_idr, GFP_KERNEL);
if (ret == 0)
return -ENOMEM;
mutex_lock(&rtc_idr_lock);
ret = idr_get_new(&rtc_idr, NULL, &id);
mutex_unlock(&rtc_idr_lock);
if (ret == 0) {
ret = id & MAX_ID_MASK;
break;
} else if (ret == -EAGAIN) {
continue;
} else {
break;
}
}
return ret;
}
static void release_rtc_id(int id)
{
mutex_lock(&