免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5201 | 回复: 6

关于i2c的一些疑问 [复制链接]

论坛徽章:
0
发表于 2010-01-18 15:21 |显示全部楼层
6可用积分
1)i2c-core 、i2c-dev、i2c-s3c2410三个文件是否就可以完成对24C02的操作,我查了一些资料里面有个i2c-algo-s3c2410.c这个文件,可我在2.6.18和2.6.24内核中没有发现这个文件,是否还需要?
我如果加载了i2c-dev,  24c02应该通过应用程序直接就可以打开了,可我查了下sys/bues/i2c/device的i2c-0设备是i2c-adapter,我看刘洪涛的一篇文章(见附件)里直接用open打开了i2c-0设备。我还有点不太明白。

2)我用了一块2440带24c02的板子运行了一下刘洪涛关于i2c的第一篇文章里的test.c程序,输出“buff=0”可按理说应该是0x58,我的/sys/bus/devices/下有两个设备,都是以i2c-0开始的,分别是.../0005c和.../0005d,可24c02设备节点在什么地方呢?

   3)我用cat /proc/devices 查看只显示了89 i2c设备,可我的i2c总线上挂在了24C02和zlg7290,我加载了i2c-dev,是不是他们应该会有个类似节点的东西,他们都是用i2c-dev可以访问的,可我没有找到这些节点,因为cat /proc/devices里面只有i2c-0,而且是apapter。不知道怎么办了,恳请各位高人给指导一下。




新手没多少分,不过了,全部奉送~

liuhongtao.rar

61.22 KB, 下载次数: 166

最佳答案

查看完整内容

记忆中i2c-dev只是一个通常的字符设备驱动,就是i2c模块当普通字符设备用,然后字符设备号是89,i2c-s3c2410,i2c-algo-s3c2410.c一看就是bus的驱动,看文件名,i2c-s3c2410肯定调用了i2c-algo-s3c2410.c的接收发送函数了,没有i2c-algo-s3c2410.c文件,就是发送接受的算法直接写在adapter的驱动i2c-s3c2410里或者从别的algo里刨出来的函数。i2c设备能用,得有具体的设备驱动,比如时钟什么的,你直接通过应用程序打开的就是adapte ...

论坛徽章:
0
发表于 2010-01-18 15:21 |显示全部楼层

不用分的,哈哈

记忆中i2c-dev只是一个通常的字符设备驱动,就是i2c模块当普通字符设备用,然后字符设备号是89,i2c-s3c2410,i2c-algo-s3c2410.c一看就是bus的驱动,看文件名,i2c-s3c2410肯定调用了i2c-algo-s3c2410.c的接收发送函数了,没有i2c-algo-s3c2410.c文件,就是发送接受的算法直接写在adapter的驱动i2c-s3c2410里或者从别的algo里刨出来的函数。
i2c设备能用,得有具体的设备驱动,比如时钟什么的,你直接通过应用程序打开的就是adapter而不是i2c device,把adapter当一个普通的char device ,跟i2c device没关系的,
外面挂什么i2c device ,得有相关驱动的,现在你只是有了adapter driver , i2c-dev文件只是个抽象的普遍的char device ,不要和i2c device 搞混,这个东东要不要没关系,要了方便应用程序打开文件调下adapter参数什么的,不要也不会影响的,关键的是i2c device的driver.

我只是看到了,就瞎说了下,附件没看,分不分的倒无所谓

论坛徽章:
0
发表于 2010-01-20 21:48 |显示全部楼层
I2C只是一种总线,由I2C总线控制器控制,I2C总线控制器是CPU可以直接访问的(直接指令访问总线控制器寄存器组的映射地址)。

I2C总线上挂的设备是I2C设备,一条I2C总线最多可以挂40个设备,每个设备的访问必须通过I2C总线控制器的寄存器组。

所以根据I2C总线协议自己写驱动吧

论坛徽章:
0
发表于 2010-01-21 15:42 |显示全部楼层

回复 #2 star_ice 的帖子

非常感谢star_ice,看了好多书,都没有个明确的答案~~多谢~~

论坛徽章:
0
发表于 2010-01-21 15:44 |显示全部楼层
谢谢readkernel的参与

论坛徽章:
0
发表于 2010-02-04 11:11 |显示全部楼层
回复 1# jary06

关于i2c驱动的问题:
  在drive/i2c/i2c-dev.c和driver/i2c/i2c-core.c的两个函数不要去改它,我们可以去调用。
要添加设备的话,例如CODEC,EEPROM,FM等I2C接口的设备时,就在chips文件夹写一个驱动就可以了,
例如PCF8574的驱动:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>

/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
                                        0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
                                        I2C_CLIENT_END };

/* Insmod parameters */
I2C_CLIENT_INSMOD_2(pcf8574, pcf8574a);

/* Each client has this additional data */
struct pcf8574_data {
        struct i2c_client client;

        int write;                        /* Remember last written value */
};

static int pcf8574_attach_adapter(struct i2c_adapter *adapter);
static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind);
static int pcf8574_detach_client(struct i2c_client *client);
static void pcf8574_init_client(struct i2c_client *client);

/* This is the driver that will be inserted */
static struct i2c_driver pcf8574_driver = {
        .driver = {
                .name        = "pcf8574",
        },
        .id                = I2C_DRIVERID_PCF8574,
        .attach_adapter        = pcf8574_attach_adapter,
        .detach_client        = pcf8574_detach_client,
};

/* following are the sysfs callback functions */
static ssize_t show_read(struct device *dev, struct device_attribute *attr, char *buf)
{
        struct i2c_client *client = to_i2c_client(dev);
        return sprintf(buf, "%u\n", i2c_smbus_read_byte(client));
}

static DEVICE_ATTR(read, S_IRUGO, show_read, NULL);

static ssize_t show_write(struct device *dev, struct device_attribute *attr, char *buf)
{
        struct pcf8574_data *data = i2c_get_clientdata(to_i2c_client(dev));

        if (data->write < 0)
                return data->write;

        return sprintf(buf, "%d\n", data->write);
}

static ssize_t set_write(struct device *dev, struct device_attribute *attr, const char *buf,
                         size_t count)
{
        struct i2c_client *client = to_i2c_client(dev);
        struct pcf8574_data *data = i2c_get_clientdata(client);
        unsigned long val = simple_strtoul(buf, NULL, 10);

        if (val > 0xff)
                return -EINVAL;

        data->write = val;
        i2c_smbus_write_byte(client, data->write);
        return count;
}

static DEVICE_ATTR(write, S_IWUSR | S_IRUGO, show_write, set_write);

static struct attribute *pcf8574_attributes[] = {
        &dev_attr_read.attr,
        &dev_attr_write.attr,
        NULL
};

static const struct attribute_group pcf8574_attr_group = {
        .attrs = pcf8574_attributes,
};

/*
* Real code
*/

static int pcf8574_attach_adapter(struct i2c_adapter *adapter)
{
        return i2c_probe(adapter, &addr_data, pcf8574_detect);
}

/* This function is called by i2c_probe */
static int pcf8574_detect(struct i2c_adapter *adapter, int address, int kind)
{
        struct i2c_client *new_client;
        struct pcf8574_data *data;
        int err = 0;
        const char *client_name = "";

        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
                goto exit;

        /* OK. For now, we presume we have a valid client. We now create the
           client structure, even though we cannot fill it completely yet. */
        if (!(data = kzalloc(sizeof(struct pcf8574_data), GFP_KERNEL))) {
                err = -ENOMEM;
                goto exit;
        }

        new_client = &data->client;
        i2c_set_clientdata(new_client, data);
        new_client->addr = address;
        new_client->adapter = adapter;
        new_client->driver = &pcf8574_driver;
        new_client->flags = 0;

        /* Now, we would do the remaining detection. But the PCF8574 is plainly
           impossible to detect! Stupid chip. */

        /* Determine the chip type */
        if (kind <= 0) {
                if (address >= 0x38 && address <= 0x3f)
                        kind = pcf8574a;
                else
                        kind = pcf8574;
        }

        if (kind == pcf8574a)
                client_name = "pcf8574a";
        else
                client_name = "pcf8574";

        /* Fill in the remaining client fields and put it into the global list */
        strlcpy(new_client->name, client_name, I2C_NAME_SIZE);

        /* Tell the I2C layer a new client has arrived */
        if ((err = i2c_attach_client(new_client)))
                goto exit_free;
       
        /* Initialize the PCF8574 chip */
        pcf8574_init_client(new_client);

        /* Register sysfs hooks */
        err = sysfs_create_group(&new_client->dev.kobj, &pcf8574_attr_group);
        if (err)
                goto exit_detach;
        return 0;

      exit_detach:
        i2c_detach_client(new_client);
      exit_free:
        kfree(data);
      exit:
        return err;
}

static int pcf8574_detach_client(struct i2c_client *client)
{
        int err;

        sysfs_remove_group(&client->dev.kobj, &pcf8574_attr_group);

        if ((err = i2c_detach_client(client)))
                return err;

        kfree(i2c_get_clientdata(client));
        return 0;
}

/* Called when we have found a new PCF8574. */
static void pcf8574_init_client(struct i2c_client *client)
{
        struct pcf8574_data *data = i2c_get_clientdata(client);
        data->write = -EAGAIN;
}

static int __init pcf8574_init(void)
{
        return i2c_add_driver(&pcf8574_driver);
}

static void __exit pcf8574_exit(void)
{
        i2c_del_driver(&pcf8574_driver);
}


MODULE_AUTHOR
    ("Frodo Looijaard <frodol@dds.nl>, "
     "Philip Edelbrock <phil@netroedge.com>, "
     "Dan Eaton <dan.eaton@rocketlogix.com> "
     "and Aurelien Jarno <aurelien@aurel32.net>");
MODULE_DESCRIPTION("PCF8574 driver");
MODULE_LICENSE("GPL");

module_init(pcf8574_init);
module_exit(pcf8574_exit);

论坛徽章:
0
发表于 2010-02-05 10:18 |显示全部楼层
回复 6# anderson5198


对,说的很对,我试试看~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP