S3C6410使用 25 I2C裝置驅動分析

2021-07-16 20:37:48 字數 4421 閱讀 1596

**:1 .1 資料結構

include/linux/i2c.h:

struct i2c_board_info

;drivers/i2c/i2c-core.h:

struct i2c_devinfo

;

1.2 全域性變數
drivers/i2c/i2c-core.h:

extern

struct rw_semaphore __i2c_board_lock;

//

extern

struct list_head __i2c_board_list;

// extern

int __i2c_first_dynamic_bus_num;

//全域性變數的初始化,在driver/i2c/i2c-boardinfo.c中

declare_rwsem

(__i2c_board_lock)

;//讀寫鎖

export_symbol_gpl

(__i2c_board_lock)

;list_head

(__i2c_board_list)

;//雙向鍊錶

export_symbol_gpl

(__i2c_board_list)

;int __i2c_first_dynamic_bus_num;

export_symbol_gpl

(__i2c_first_dynamic_bus_num)

;

1.3 i2c裝置的定義
在arch/arm/mach-s3c64xx/mach-smdk6410.c中,定義了i2c的裝置 

static

struct i2c_board_info i2c_devs0[

] __initdata =

,// gjl};

static

struct i2c_board_info i2c_devs1[

] __initdata =

,/* samsung s524ad0xd1 */};

其中 #define i2c_board_info

(dev_type, dev_addr) \

.type = dev_type,

.addr =

(dev_addr)

.type 是name

.addr 是裝置在i2c上的位址

在arch/arm/mach-s3c64xx/mach-smdk6410.c中

static

void __init smdk6410_machine_init

(void

)在driver/i2c/i2c-boardinfo.c中:

int __init i2c_register_board_info

(int busnum,

struct i2c_board_info const

*info,

unsigned len)

up_write

(&__i2c_board_lock)

;return status;

}

1.4 i2c裝置的新增過程
s3c24xx_i2c_probe 

--> i2c_add_numbered_adapter

--> i2c_register_adapter

--> i2c_scan_static_board_info

--> i2c_new_device

i2c裝置的新增過程是隨著i2c控制器的新增而新增的!

二. i2c裝置驅動的註冊過程

這兒以ov9650為例說明一下,(為什麼呢? 因為ok6410上面沒有其它的i2c裝置了!)

drivers/media/video/samsung/fimc/ov965x.c 

static __init int

ov965x_init

(void

)module_init

(ov965x_init)

ov965x_init

--> i2c_add_driver

static

inline

inti2c_add_driver

(struct i2c_driver *driver)

在driver/i2c/i2c-core.c中

inti2c_register_driver

(struct module *owner,

struct i2c_driver *driver)

export_symbol

(i2c_register_driver)

;ov965x_init

--> i2c_add_driver

--> i2c_device_probe

driver/i2c/i2c-core.c

static

inti2c_device_probe

(struct device *dev)

下面接著分析

三. i2c裝置驅動的寫過程

i2c_device_probe 

--> ov965x_probe

static

intov965x_probe

(struct i2c_client *c,

const

struct i2c_device_id *id)

return0;

}i2c_device_probe

--> ov965x_probe

--> i2c_smbus_write_byte_data

driver/i2c/i2c-core.c

s32 i2c_smbus_write_byte_data

(const

struct i2c_client *client, u8 command, u8 value)

s32 i2c_smbus_xfer

(struct i2c_adapter *adapter, u16 addr,

unsigned

short flags,

char read_write, u8 command,

int protocol,

union i2c_smbus_data *data)

i2c_device_probe

--> ov965x_probe

--> i2c_smbus_write_byte_data

--> i2c_smbus_xfer_emulated

driver/i2c/i2c-core.c

static s32 i2c_smbus_xfer_emulated

(struct i2c_adapter *adapter, u16 addr,

unsigned

short flags,

char read_write, u8 command,

int size,

union i2c_smbus_data *data),}

; msgbuf0[0]

= command;

switch

(size)

status =

i2c_transfer

(adapter, msg, num)

;//把要傳輸的資訊組裝成msg,進行傳輸

//i==0 && i2c_smbus_read

}i2c_device_probe

--> ov965x_probe

--> i2c_smbus_write_byte_data

--> i2c_smbus_xfer_emulated

--> i2c_transfer

driver/i2c/i2c-core.c

inti2c_transfer

(struct i2c_adapter *adap,

struct i2c_msg *msgs,

int num)

else

i2c_lock_adapter

(adap)

;//加把鎖

orig_jiffies = jiffies;

for(ret =

0, try =

0; try <= adap->retries; try++

)i2c_unlock_adapter

(adap)

;//unlock

return ret;

}

s3c6410儲存器對映

1.引導映象區 0x0000 0000 0x07ff ffff 2.內部儲存區 1 內部rom 0x0800 0000 0x0bff ffff 2 內部sram 0x0c00 0000 0x0fff ffff 3.靜態儲存區 0x1000 0000 0x3fff ffff 4.動態儲存區 0x400...

S3C6410啟動模式介紹

目前的arm處理器都支援多種啟動模式,s3c6410和以前的samsung的arm處理器一樣,通過外部管腳om 4 0 的拉高拉低來決定是從哪個儲存裝置上啟動。我認為s3c6410的user manual並沒有說的很清楚,所以我在最開始使用的時候,也對其啟動模式有一些誤解,下面就我個人的理解,介紹一...

S3C6410啟動模式介紹

from 目前的arm處理器都支援多種啟動模式,s3c6410和以前的samsung的arm處理器一樣,通過外部管腳om 4 0 的拉高拉低來決定是從哪個儲存裝置上啟動。我認為s3c6410的user manual並沒有說的很清楚,所以我在最開始使用的時候,也對其啟動模式有一些誤解,下面就我個人的理...