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. HTML5学习笔记(持续更新中....)

    平时的工作中,不知不觉我们应用了很多HTML5,但当正儿八经问起来你对HTML5了解多少,很多时候都有点懵. 做个简单的HTML5总结.包括简介.要学的知识点.凌乱的知识点 HMTL5简介 定义:ht ...

  2. [NHibernate]HQL查询

    目录 写在前面 文档与系列文章 查询的几种方式 HQL查询 一个例子 总结 写在前面 上篇文章介绍了nhibernate在项目中的基本配置,包括数据库连接字符串的设置,映射文件的配置及需注意的地方,这 ...

  3. ThinkPHP3.2.3整合smarty模板(二)

    前言:继ThinkPHP3.2.3整合smarty模板(一)之后,继续来探讨一下tp框架整合smarty模板,看到有人在群上问到怎么使用自定义的常量,今天就具体来谈谈: 一.开发一个项目,必不可少会用 ...

  4. tyvj1192 迎春舞会之集体舞

    背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 描述 表演者排成n排,构成一个向前的正三角形(在屏幕上,即向下).而就每个人,他有可能正面朝前(小的向前正三角形).或向后三角形(小的向后正 ...

  5. CentOS6.3 编译安装LAMP(2):编译安装 Apache2.2.25

    所需源码包: /usr/local/src/Apache-2.2.25/httpd-2.2.25.tar.gz 编译安装 Apache2.2.25 #切换到源码目录 cd /usr/local/src ...

  6. 【Android学习】《Android开发视频教程》第一季笔记

    视频地址: http://study.163.com/course/courseMain.htm?courseId=207001 课时5    Activity基础概念 1.Android开发技术结构 ...

  7. C和指针 第七章 可变参数

    可变参数列表是通过stdarg.h内的宏来实现的: 类型 va_list 三个宏: va_start va_arg va_end 我们可以声明一个va_list变量,与这三个宏配合使用. 可变参数必须 ...

  8. Apache curator-client详解

    Apache curator框架中curator-client组件可以作为zookeeper client来使用,它提供了zk实例创建/重连机制等,简单便捷.不过直接使用curator-client并 ...

  9. 【转】Intellij IDEA 14中使用MyBatis-generator 自动生成MyBatis代码

    Intellij IDEA 14 作为Java IDE 神器,接触后发现,非常好用,对它爱不释手,打算离开eclipse和myeclipse,投入Intellij IDEA的怀抱. 然而在使用的过程中 ...

  10. 在VFP6中模拟CursorAdapter的功能

    这个是我在2002年做的一个VFP程序中实现的方法, 现在看来功能和VFP8,9中的CursorAdapter非常相似, 因为属性设置有许多相同的地方,我甚至怀疑CA就是就是在这样的基础上再包装出来的 ...