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. WinPcap4.13无法安装解决方法

    360软件管家提示把WinPcap更新至版本:4.1.0.2980,于是把旧版下载后,可新版本怎么也无法顺利安装,出现以下信息,旧版本已安装,关闭所有winpcap-based应用程序和再次运行安装程 ...

  2. ExtJs 实现表单联动

    最近做的项目使用Extjs.遇到表单联动的业务.下面来说说主要实现思想: 说明:表单联动一般存在从属关系,有大范围的对象和大范围中的小对象.比如地理位置的选定(例:浙江省-杭州市-某某县).在这里,我 ...

  3. Linux 命令收集

    http://www.cnblogs.com/tzhangofseu/archive/2011/12/17/2290955.html vim :r filename :sh  enter shell ...

  4. Android ListView 的基本应用,包括缓存

    class MyAdapter extends BaseAdapter {         //返回要显示的条目的数量         @Override         public int get ...

  5. App提交iTunes Connect,"二进制无效"问题解决方案。

    昨天提交打包提交App,将包上传到iTunes Connect之后,以为就能发布了,便点击构建版本,发现没有刚刚上传的包,于是就点击"预发行"看一下,会看到"已上传&qu ...

  6. 微信 5.3 for iPhone已放出 微信iphone版更新下载

    就在几个小时前,微信发布了更新,本次只放出微信 5.3 for iPhone,距离发布微信5.3内测版也就几天时间.和往常一样微信iphone版先发布,微信android版延后发布,微信看重的是ios ...

  7. 第3月第13天 cpp模版 Iterator模式 proactor

    1.模版除了传参,还可以自动创建.而传指针只是传参而已. template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_P ...

  8. c#微信开发 转

    using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System. ...

  9. 最大堆 最小堆 解决TOPK问题

    堆:实质是一颗完全二叉树,最大堆的特点:父节点值均大于子节点:最小堆的父节点值均小于子节点: 一般使用连续内存存储堆内的值,因而可以根据当前节点的索引值推断子节点的索引值: 节点i的父节点为(i-1) ...

  10. MVC项目使用easyui的filebox控件上传文件

    开发环境:WIN10+IE11,浏览器请使用IE10或以上版本 开发技术框架MVC4+JQuery Easyui+knockoutjs 效果为弹出小窗体,如下图 1.前端cshtml文件代码(只包含文 ...