• linux设备驱动


    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 */

  • 相关阅读:
    汇编语言实验4
    汇编语言实验3
    汇编语言实验2
    汇编语言实验1
    汇编语言学习心得
    Java 之不小心修改对象值
    实验九 根据材料编程
    实验5 编写、调试具有多个段的程序
    实验四 [bx]和loop的使用
    ASCII(侵权删)
  • 原文地址:https://www.cnblogs.com/chencesc/p/6022924.html
Copyright © 2020-2023  润新知