http://blog.csdn.net/bob_fly1984/article/details/8820670

struct ov5640_data {
    struct ov5640_platform_data chip;
    bool use_smbus;

    /*  
     * Lock protects against activities from other Linux tasks,
     * but not from changes by other I2C masters.
     */
    struct mutex lock;
    struct bin_attribute bin;

    u8 *writebuf;
    unsigned write_max;
    unsigned num_addresses;

    /*  
     * Some chips tie up multiple I2C addresses; dummy devices reserve
     * them for us, and we'll use them with SMBus calls.
     */
    struct i2c_client *client[];
};

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

static struct ov5640_platform_data ov5640_chip_info;

static struct i2c_board_info ov5640_i2c_board_info  __initdata ={
    .type = CONFIG_OV5640_TYPE,
    .addr = CONFIG_OV5640_DEVICE_ADDR,
};

static void __init i2c_board_init(void)
{
    int i;
    for (i = 0; i < sizeof(ov5640_list) / sizeof(struct ov5640_info); i++) {
        if (strcmp(ov5640_i2c_board_info.type, ov5640_list[i].name) == 0) {
            ov5640_chip_info.byte_len = ov5640_list[i].byte_len;
            ov5640_chip_info.page_size = ov5640_list[i].page_size;
            ov5640_chip_info.flags = ov5640_list[i].flags;
            ov5640_i2c_board_info.platform_data = &ov5640_chip_info;
            break;
        }
    }
    i2c_register_board_info(CONFIG_OV5640_I2C_BUS_NUM, &ov5640_i2c_board_info, 1);
}
这一堆是一个从设备client dev的注册

一个从设备的属性,注册通过

i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned n);

struct i2c_board_info {
    char        type[I2C_NAME_SIZE];/×相当于设备名用于区分×/
    unsigned short  flags;
    unsigned short  addr;
    void        *platform_data;    
    struct dev_archdata *archdata;
    struct device_node *of_node;   
    struct acpi_dev_node acpi_node;
    int     irq;
};

自定义一个结构体

struct ov5640_info {
    char *name;
    unsigned int byte_len;   /* size (sum of all addr) */
    unsigned short page_size;  /* for writes */
    unsigned char flags;
};

定义一个结构体数组

static const struct ov5640_info ov5640_list[] = {
    { "OV5640",   128 / 8,     1,   ov5640_FLAG_TAKE8ADDR },
    { NULL,      0,           0,   0 }  /* END OF LIST */
};

相当于busnum,几路i2c

定义一个结构体存储用户数据

struct at24_platform_data {
    u32     byte_len;       /* size (sum of all addr) */
    u16     page_size;      /* for writes */
    u8      flags;
#define AT24_FLAG_ADDR16    0x80    /* address pointer is 16 bit */
#define AT24_FLAG_READONLY  0x40    /* sysfs-entry will be read-only */
#define AT24_FLAG_IRUGO     0x20    /* sysfs-entry will be world-readable */
#define AT24_FLAG_TAKE8ADDR 0x10    /* take always 8 addresses (24c00) */

    void        (*setup)(struct memory_accessor *, void *context);
    void        *context;
};

static struct ov5640_platform_data ov5640_chip_info;

static struct i2c_board_info ov5640_i2c_board_info  __initdata ={
    .type = CONFIG_OV5640_TYPE,
    .addr = CONFIG_OV5640_DEVICE_ADDR,
};

static void __init i2c_board_init(void)
{
    int i;
    for (i = 0; i < sizeof(ov5640_list) / sizeof(struct ov5640_info); i++) {
        if (strcmp(ov5640_i2c_board_info.type, ov5640_list[i].name) == 0) {
            ov5640_chip_info.byte_len = ov5640_list[i].byte_len;
            ov5640_chip_info.page_size = ov5640_list[i].page_size;
            ov5640_chip_info.flags = ov5640_list[i].flags;
            ov5640_i2c_board_info.platform_data = &ov5640_chip_info;
            break;
        }
    }
    i2c_register_board_info(CONFIG_OV5640_I2C_BUS_NUM, &ov5640_i2c_board_info, 1);
}

将定义的platform_data注册进去

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

static const struct i2c_device_id ov5640_ids[] = {
    { "OV5640", 0 },
};
MODULE_DEVICE_TABLE(i2c, ov5640_ids);

static struct i2c_driver ov5640_driver = {
    .driver = {
        .name = "OV5640",
        .owner = THIS_MODULE,
    },
    .probe = ov5640_probe,
    .remove = __devexit_p(ov5640_remove),
    .id_table = ov5640_ids,
};

i2c_driver模型

struct i2c_driver {
    unsigned int class;       

    /* Notifies the driver that a new bus has appeared. You should avoid
     * using this, it will be removed in a near future.
     */
    int (*attach_adapter)(struct i2c_adapter *) __deprecated;

    /* Standard driver model interfaces */
    int (*probe)(struct i2c_client *, const struct i2c_device_id *);
    int (*remove)(struct i2c_client *);

    /* driver model interfaces that don't relate to enumeration  */
    void (*shutdown)(struct i2c_client *);
    int (*suspend)(struct i2c_client *, pm_message_t mesg);
    int (*resume)(struct i2c_client *);

    /* Alert callback, for example for the SMBus alert protocol.
     * The format and meaning of the data value depends on the protocol.
     * For the SMBus alert protocol, there is a single bit of data passed
     * as the alert response's low bit ("event flag").
     */
    void (*alert)(struct i2c_client *, unsigned int data);

    /* a ioctl like command that can be used to perform specific functions
     * with the device.
     */
    int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

    struct device_driver driver;
    const struct i2c_device_id *id_table;

    /* Device detection callback for automatic device creation */
    int (*detect)(struct i2c_client *, struct i2c_board_info *);
    const unsigned short *address_list;
    struct list_head clients;
};

struct i2c_client {
    unsigned short flags;       /* div., see below      */
    unsigned short addr;        /* chip address - NOTE: 7bit    */
                    /* addresses are stored in the  */
                    /* _LOWER_ 7 bits       */
    char name[I2C_NAME_SIZE];
    struct i2c_adapter *adapter;    /* the adapter we sit on    */
    struct device dev;      /* the device structure     */
    int irq;            /* irq issued by device     */
    struct list_head detected;
};

static int __init ov5640_init(void)
{
    io_limit = rounddown_pow_of_two(io_limit);
    return i2c_add_driver(&ov5640_driver);
}
module_init(ov5640_init);

static void __exit ov5640_exit(void)
{
    i2c_del_driver(&ov5640_driver);
}
module_exit(ov5640_exit);

/* eeprom device private list */

linux设备驱动的更多相关文章

  1. 浅谈Android系统移植、Linux设备驱动

    一.Android系统架构 第一层:Linux内核 包括驱动程序,管理内存.进程.电源等资源的程序 第二层:C/C++代码库 包括Linux的.so文件以及嵌入到APK程序中的NDK代码 第三层:An ...

  2. linux设备驱动概述,王明学learn

    linux设备驱动学习-1 本章节主要学习有操作系统的设备驱动和无操作系统设备驱动的区别,以及对操作系统和设备驱动关系的认识. 一.设备驱动的作用 对设备驱动最通俗的解释就是“驱使硬件设备行动” .设 ...

  3. Linux设备驱动工程师之路——内核链表的使用【转】

    本文转载自:http://blog.csdn.net/forever_key/article/details/6798685 Linux设备驱动工程师之路——内核链表的使用 K-Style 转载请注明 ...

  4. linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-119723.html linux设备驱动归纳总结(十三):1.触摸屏与ADC时钟 xxxxxxxxxx ...

  5. linux设备驱动归纳总结(十二):简单的数码相框【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-116926.html linux设备驱动归纳总结(十二):简单的数码相框 xxxxxxxxxxxxxx ...

  6. linux设备驱动归纳总结(十一):写个简单的看门狗驱动【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-112879.html linux设备驱动归纳总结(十一):写个简单的看门狗驱动 xxxxxxxxxxx ...

  7. linux设备驱动归纳总结(十):1.udev&misc【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-111839.html linux设备驱动归纳总结(十):1.udev&misc xxxxxxx ...

  8. linux设备驱动归纳总结(九):1.platform总线的设备和驱动【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-111745.html linux设备驱动归纳总结(九):1.platform总线的设备和驱动 xxxx ...

  9. linux设备驱动归纳总结(八):4.总线热插拔【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-110774.html linux设备驱动归纳总结(八):4.总线热插拔 xxxxxxxxxxxxxxx ...

  10. linux设备驱动归纳总结(八):3.设备管理的分层与面向对象思想【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-110738.html linux设备驱动归纳总结(八):3.设备管理的分层与面向对象思想 xxxxxx ...

随机推荐

  1. JVM Management API

    JVM本身提供了一组管理的API,通过该API,我们可以获取得到JVM内部主要运行信息,包括内存各代的数据.JVM当前所有线程及其栈相关信 息等等.各种JDK自带的剖析工具,包括jps.jstack. ...

  2. mac系统小记

    1.设置 ls  命令结果的颜色 默认的 ls 是没有颜色的,可以通过设置 CLICOLOR 和 LSCOLORS 两个环境变量来实现.其中,CLICOLOR 是用来设置是否进行颜色的显示(CLI: ...

  3. util类中非静态方法中注入serivce,在controller层是使用util。

    今天碰到如题的问题,刚一开始在util中注入service总是注入失败,起初我以为是util中没有注入成功,debug看了一下果然注入不进来. 然后各种纠结,最终坑爹的问题是在controller直接 ...

  4. jq的$()里面 一定要是字符串类型!!!!!!!!!!!!!!!!!!!!!!!!

    var s = "[value="+uid+"]"; $(s).attr("checked",'true');

  5. 微信"附近的人"新增商家公众号入驻功能

    微信近日升级了“附近的人”,新增商家公众号(认证的服务号和有卡券功能的公众号)可自入驻,这是微信在推出卡券和微信wifi功能后,又一加强连接线下商户能力的功能. 微信在“附近的人”中 增加搜索商户功能 ...

  6. Go - 项目收藏

    谷歌官方维护了一个基于go语言的开源项目列表: https://github.com/golang/go/wiki/Projects Web框架 web.go.beego Go项目 httpmq:A ...

  7. 二叉树建立,遍历和二叉排序树的判断【c++】

    // test.cpp : Defines the entry point for the console application. // #include "stdafx.h" ...

  8. ACM-ICPC如何起步

    刚刚绝定投身ACM-ICPC的同学先要过两关. 第一关:程序设计语言 如果学校有开设相关课程,则省去了很多麻烦.如果没有则可以选择<程序设计导引及在线实践>作为教材.现在的比赛中允许使用的 ...

  9. 配置SVN、GIT总结

    SVN使用说明 svn地址(可以是内网,也可以是外网的):svn://192.168.3.1/xxxhttp://192.168.3.1/xxxhttps://192.168.3.1/xxx 一个sv ...

  10. hive创建索引

    索引是hive0.7之后才有的功能,创建索引需要评估其合理性,因为创建索引也是要磁盘空间,维护起来也是需要代价的 创建索引 hive> create index [index_studentid ...