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. SQLPROMPT5.3对各种加密对象的解密测试

    SQLPROMPT5.3对各种加密对象的解密测试 测试环境: SQL2005个人开发者版 SP4 SQLPROMPT版本:5.3.8.2 视图 CREATE VIEW aa WITH ENCRYPTI ...

  2. 浅谈Android中Activity的生命周期

    引言 我想对于Android开发人员来说,Activity是再熟悉不过了,今天我们就来探讨下Activity的生命周期.熟悉的掌握Activity对于开发健壮的Android应用程序来说至关重要.下面 ...

  3. centos7 没有iptables服务 file or directory? 用secureCRT登录centos?

    cenetos7 采用systemd来管理服务 centos7 没有采用传统的iptables服务, 而是采用的firewalld 服务, 以及firewall-cmd 命令; 也可以采用传统的 ip ...

  4. win7挂载VHD文件,模拟多系统并存

    挂载vhd是win7 一个很特殊的功能,xp不能支持,一些服务器版的系统 像2008.2008R2这些可能也是支持的,只是没有测试过. 提前的准备: Win7  wim 镜像文件 Imagex.exe ...

  5. WindowsPhone8.1RT建立空白应用挂起没反应的解决方案

    wp8.1下, 建立空白应用后遇到的问题:想要实现保存.提取数据都无法成功 在退出程序后无法进入到OnNavigatedFrom()中去. 网上说要手动的Invoke OnSuspending事件. ...

  6. java表格的使用 单元格绘制二

    JTable单元格是由单元格绘制器绘制出来的,这是一些执行TableCellRenderer接口的类.TableCellRenderer接口定义了唯一的getTableCellRendererComp ...

  7. Shell入门教程:Shell变量

    变量 是一种很“弱”的变量,默认情况下,一个变量保存一个串,Shell不关心这个串是什么含义.所以若要进行数学运算,必须使用一些命令例如 let.declare.expr.双括号等. Shell变量可 ...

  8. Unity3D代码旋转

    subGameObject.transform.Rotate (,,,Space.Self); 一行代码

  9. PHP中计划任务

    PHP不支持多线程,有时候处理问题不是那么爽,今天谈论一下PHP定时执行的方法 PHP定时执行的三种方式实现 .windows 的计划任务 .linux的脚本程序 .让web浏览器定时刷新 windo ...

  10. window跳转页面

    1.直接的事件跳转 window.location.href="你所要跳转的页面"; 2.新窗口跳转 window.open('你所要跳转的页面'); 3.返回上一页 window ...