Linux 设备驱动篇之-------I2c设备驱动(待续)

Linux 设备驱动篇之-------I2c设备驱动

 

虽然I2C硬件体系结构和协议都很容易理解,但是Linux I2C驱动体系结构却有相当的复杂度,它主要由3部分组成,即I2C设备驱动、I2C总线驱动和I2C核心。I2C核心是I2c总线和I2c设备驱动的中间枢纽,它以通用的、与平台无关的接口实现了I2C中设备与适配器的沟通。I2c总线驱动填充I2c_adapter和I2c_algorithm结构体,I2c设备驱动填充I2c_driver结构体并实现其本身所对应设备类型的驱动。

另外,系统中i2c-dev.c文件定义的主设备号为89的设备可以方便地给应用程序提供读写I2c设备寄存器的能力,使得工程师大多数时候并不需要为具体的I2c设备驱动定义文件操作接口。

如何理解adapter、I2c适配器和client呢?他在s3c2440中对应的是什么?Adapter、I2c适配器和client都是linux驱动软件抽象出来的东西,Linux I2C框架搞那么复杂是为了通用性及为了符合Linux内核驱动模式而制定的。简单的说,你的开发板上有几个I2C接口,就有几个adapter , 也就是有几条I2C bus , I2C client对应的就是你的外围I2C 设备,有几个就有几个client , 把这些设备插入开发板, 对应其中的一条bus, 那么相应的就对应了其中的一个adapter , 接下来的就是I2c核心部分使client与 adapter匹配成对。

在linux内核中,所有的I2C设备都在sysfs文件系统中显示,存在于/sys/bus/i2c/目录下,适配器地址和芯片地址的形式列出,例如:

[fulinux@ubuntu linux-3.0]$ tree /sys/bus/i2c/       

/sys/bus/i2c/

|-- devices

|   |-- i2c-0 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-0

|   |-- i2c-1 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-1

|   |-- i2c-2 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-2

|   |-- i2c-3 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-3

|   |-- i2c-4 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-4

|   |-- i2c-5 -> ../../../devices/pci0000:00/0000:00:02.0/i2c-5

|   |-- i2c-6 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-1/i2c-6

|   `-- i2c-7 -> ../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-DP-2/i2c-7

|-- drivers

|   |-- 88PM860x

|   |   |-- bind

|   |   |-- uevent

|   |   `-- unbind

|   |-- aat2870

|   |   |-- bind

|   |   |-- uevent

|   |   `-- unbind

|   |-- ab3100

|   |   |-- bind

|   |   |-- uevent

|   |   `-- unbind

|   |-- adp5520

下面我以s3c2440开发板及其之上的EEPROM芯片AT24C02和linux-3.0内核平台讲解I2c的三个部分。

S3c2440芯片上的I2c模块特性

请看s3c2440.pdf

芯片AT24C02的电气特性:

• Low-voltage and Standard-voltage Operation

– 2.7 (VCC= 2.7V to 5.5V)

– 1.8 (VCC= 1.8V to 5.5V)

• Internally Organized 128 x 8 (1K), 256 x 8 (2K), 512 x 8 (4K),

1024 x 8 (8K) or 2048 x 8 (16K)

• Two-wire Serial Interface

• Schmitt Trigger, Filtered Inputs for Noise Suppression

• Bidirectional Data Transfer Protocol

• 100 kHz (1.8V) and 400 kHz (2.7V, 5V) Compatibility

• Write Protect Pin for Hardware Data Protection

• 8-byte Page (1K, 2K), 16-byte Page (4K, 8K, 16K) Write Modes

• Partial Page Writes Allowed

• Self-timed Write Cycle (5 ms max)

• High-reliability

– Endurance: 1 Million Write Cycles

– Data Retention: 100 Years

• Automotive Grade and Lead-free/Halogen-free Devices Available

• 8-lead PDIP, 8-lead JEDEC SOIC, 8-lead MAP, 5-lead SOT23,

8-lead TSSOP and 8-ball dBGA2 Packages

• Die Sales: Wafer Form, Waffle Pack and Bumped Wafers

主要是看AT24C02.pdf

S3c244开发板核心板电路图:

AT24C02电路图:

i2c.h头文件

内核中i2c.h这个头文件对i2c_driver、i2c_client、i2c_adapter和i2c_algorithm着4个数据结构进行了定义。理解这4个结构的作用十分关键,代码清单1、2、3、4分别给出了它们的定义。

代码清单1 i2c_adapter结构体

1. /*

2.  * i2c_adapter is the structure used to identify a physical i2c bus along

3.  * with the access algorithms necessary to access it.

4.  */

5. struct i2c_adapter {

6.     struct module *owner;

7.     unsigned int class;       /* classes to allow probing for */

8.     const struct i2c_algorithm *algo; /* the algorithm to access the bus */

9.     void *algo_data;

10.     /* data fields that are valid for all devices   */

11.     struct rt_mutex bus_lock;

12.     int timeout;            /* in jiffies */

13.     int retries;

14.     struct device dev;      /* the adapter device */

15.     int nr;

16.     char name[48];

17.     struct completion dev_released;

18.     struct mutex userspace_clients_lock;

19.     struct list_head userspace_clients;

20. };

代码清单2 i2c_algorithm结构体

1. /*

2.  * The following structs are for those who like to implement new bus drivers:

3.  * i2c_algorithm is the interface to a class of hardware solutions which can

4.  * be addressed using the same bus algorithms - i.e. bit-banging or the PCF8584

5.  * to name two of the most common.

6.  */

7. struct i2c_algorithm {

8.     /* If an adapter algorithm can't do I2C-level access, set master_xfer

9.        to NULL. If an adapter algorithm can do SMBus access, set

10.        smbus_xfer. If set to NULL, the SMBus protocol is simulated

11.        using common I2C messages */

12.     /* master_xfer should return the number of messages successfully

13.        processed, or a negative value on error */

14.     int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs,

15.                int num);

16.     int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr,

17.                unsigned short flags, char read_write,

18.                u8 command, int size, union i2c_smbus_data *data);

19.     /* To determine what the adapter supports */

20.     u32 (*functionality) (struct i2c_adapter *);

21. };

上述代码第4行对应为SMBus传输函数指针,SMBus大部分基于I2C总线规范,SMBus不需要增加额外引脚。与I2C总线相比,SMBus增加了一些新的功能特性,在访问时序也有一定的差异。

代码清单3 i2c_driver结构体

1. /*

2.  * struct i2c_driver - represent an I2C device driver

3.  * @class: What kind of i2c device we instantiate (for detect)

4.  * @attach_adapter: Callback for bus addition (deprecated)

5.  * @detach_adapter: Callback for bus removal (deprecated)

6.  * @probe: Callback for device binding

7.  * @remove: Callback for device unbinding

8.  * @shutdown: Callback for device shutdown

9.  * @suspend: Callback for device suspend

10.  * @resume: Callback for device resume

11.  * @alert: Alert callback, for example for the SMBus alert protocol

12.  * @command: Callback for bus-wide signaling (optional)

13.  * @driver: Device driver model driver

14.  * @id_table: List of I2C devices supported by this driver

15.  * @detect: Callback for device detection

16.  * @address_list: The I2C addresses to probe (for detect)

17.  * @clients: List of detected clients we created (for i2c-core use only)

18.  *

19.  * The driver.owner field should be set to the module owner of this driver.

20.  * The driver.name field should be set to the name of this driver.

21.  *

22.  * For automatic device detection, both @detect and @address_data must

23.  * be defined. @class should also be set, otherwise only devices forced

24.  * with module parameters will be created. The detect function must

25.  * fill at least the name field of the i2c_board_info structure it is

26.  * handed upon successful detection, and possibly also the flags field.

27.  *

28.  * If @detect is missing, the driver will still work fine for enumerated

29.  * devices. Detected devices simply won't be supported. This is expected

30.  * for the many I2C/SMBus devices which can't be detected reliably, and

31.  * the ones which can always be enumerated in practice.

32.  *

33.  * The i2c_client structure which is handed to the @detect callback is

34.  * not a real i2c_client. It is initialized just enough so that you can

35.  * call i2c_smbus_read_byte_data and friends on it. Don't do anything

36.  * else with it. In particular, calling dev_dbg and friends on it is

37.  * not allowed.

38.  */

39. struct i2c_driver {

40.     unsigned int class;

41.     /* Notifies the driver that a new bus has appeared or is about to be

42.      * removed. You should avoid using this, it will be removed in a

43.      * near future.

44.      */

45.     int (*attach_adapter)(struct i2c_adapter *) __deprecated;

46.     int (*detach_adapter)(struct i2c_adapter *) __deprecated;

47.     /* Standard driver model interfaces */

48.     int (*probe)(struct i2c_client *, const struct i2c_device_id *);

49.     int (*remove)(struct i2c_client *);

50.     /* driver model interfaces that don't relate to enumeration  */

51.     void (*shutdown)(struct i2c_client *);

52.     int (*suspend)(struct i2c_client *, pm_message_t mesg);

53.     int (*resume)(struct i2c_client *);

54.     /* Alert callback, for example for the SMBus alert protocol.

55.      * The format and meaning of the data value depends on the protocol.

56.      * For the SMBus alert protocol, there is a single bit of data passed

57.      * as the alert response's low bit ("event flag").

58.      */

59.     void (*alert)(struct i2c_client *, unsigned int data);

60.     /* a ioctl like command that can be used to perform specific functions

61.      * with the device.

62.      */

63.     int (*command)(struct i2c_client *client, unsigned int cmd, void *arg);

64.     struct device_driver driver;

65.     const struct i2c_device_id *id_table;

66.     /* Device detection callback for automatic device creation */

67.     int (*detect)(struct i2c_client *, struct i2c_board_info *);

68.     const unsigned short *address_list;

69.     struct list_head clients;

70. };

代码清单4 i2c_client结构体

1. /**

2.  * struct i2c_client - represent an I2C slave device

3.  * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;

4.  *  I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking

5.  * @addr: Address used on the I2C bus connected to the parent adapter.

6.  * @name: Indicates the type of the device, usually a chip name that's

7.  *  generic enough to hide second-sourcing and compatible revisions.

8.  * @adapter: manages the bus segment hosting this I2C device

9.  * @driver: device's driver, hence pointer to access routines

10.  * @dev: Driver model device node for the slave.

11.  * @irq: indicates the IRQ generated by this device (if any)

12.  * @detected: member of an i2c_driver.clients list or i2c-core's

13.  *  userspace_devices list

14.  *

15.  * An i2c_client identifies a single device (i.e. chip) connected to an

16.  * i2c bus. The behaviour exposed to Linux is defined by the driver

17.  * managing the device.

18.  */

19. struct i2c_client {

20.     unsigned short flags;       /* div., see below      */

21.     unsigned short addr;        /* chip address - NOTE: 7bit    */

22.                     /* addresses are stored in the  */

23.                     /* _LOWER_ 7 bits       */

24.     char name[I2C_NAME_SIZE];

25.     struct i2c_adapter *adapter;    /* the adapter we sit on    */

26.     struct i2c_driver *driver;  /* and our access routines  */

27.     struct device dev;      /* the device structure     */

28.     int irq;            /* irq issued by device     */

29.     struct list_head detected;

30. };

下面分析i2c_driver、i2c_client、i2c_adapter和i2c_algorithm这4个数据结构的作用及盘根错节的关系。

(1)i2c_adapter与i2c_algorithm.

i2c_adapter对应于物理上的一个适配器,而i2c_algorithm对应一套通信方法。一个I2C适配器需要i2c_algorithm中提供的通信函数来控制适配器上产生特定的访问周期。缺少i2c_algorithm的i2c_adapter什么也做不了,因此i2c_adapter中包含其使用的i2c_algorithm的指针。

I2c_algorithm中关键函数master_xfer用于产生I2C访问周期需要的信号,以i2c_msg(即I2C消息)为单位。I2c_msg结构体非常关键,代码清单5给出了它的定义。

代码清单5 i2c_msg结构体

1. /**

2.  * struct i2c_msg - an I2C transaction segment beginning with START

3.  * @addr: Slave address, either seven or ten bits.  When this is a ten

4.  *  bit address, I2C_M_TEN must be set in @flags and the adapter

5.  *  must support I2C_FUNC_10BIT_ADDR.

6.  * @flags: I2C_M_RD is handled by all adapters.  No other flags may be

7.  *  provided unless the adapter exported the relevant I2C_FUNC_*

8.  *  flags through i2c_check_functionality().

9.  * @len: Number of data bytes in @buf being read from or written to the

10.  *  I2C slave address.  For read transactions where I2C_M_RECV_LEN

11.  *  is set, the caller guarantees that this buffer can hold up to

12.  *  32 bytes in addition to the initial length byte sent by the

13.  *  slave (plus, if used, the SMBus PEC); and this value will be

14.  *  incremented by the number of block data bytes received.

15.  * @buf: The buffer into which data is read, or from which it's written.

16.  *

17.  * An i2c_msg is the low level representation of one segment of an I2C

18.  * transaction.  It is visible to drivers in the @i2c_transfer() procedure,

19.  * to userspace from i2c-dev, and to I2C adapter drivers through the

20.  * @i2c_adapter.@master_xfer() method.

21.  *

22.  * Except when I2C "protocol mangling" is used, all I2C adapters implement

23.  * the standard rules for I2C transactions.  Each transaction begins with a

24.  * START.  That is followed by the slave address, and a bit encoding read

25.  * versus write.  Then follow all the data bytes, possibly including a byte

26.  * with SMBus PEC.  The transfer terminates with a NAK, or when all those

27.  * bytes have been transferred and ACKed.  If this is the last message in a

28.  * group, it is followed by a STOP.  Otherwise it is followed by the next

29.  * @i2c_msg transaction segment, beginning with a (repeated) START.

30.  *

31.  * Alternatively, when the adapter supports I2C_FUNC_PROTOCOL_MANGLING then

32.  * passing certain @flags may have changed those standard protocol behaviors.

33.  * Those flags are only for use with broken/nonconforming slaves, and with

34.  * adapters which are known to support the specific mangling options they

35.  * need (one or more of IGNORE_NAK, NO_RD_ACK, NOSTART, and REV_DIR_ADDR).

36.  */

37. struct i2c_msg {

38.     __u16 addr; /* slave address            */

39.     __u16 flags;

40. #define I2C_M_TEN       0x0010  /* this is a ten bit chip address */

41. #define I2C_M_RD        0x0001  /* read data, from slave to master */

42. #define I2C_M_NOSTART       0x4000  /* if I2C_FUNC_PROTOCOL_MANGLING */

43. #define I2C_M_REV_DIR_ADDR  0x2000  /* if I2C_FUNC_PROTOCOL_MANGLING */

44. #define I2C_M_IGNORE_NAK    0x1000  /* if I2C_FUNC_PROTOCOL_MANGLING */

45. #define I2C_M_NO_RD_ACK     0x0800  /* if I2C_FUNC_PROTOCOL_MANGLING */

46. #define I2C_M_RECV_LEN      0x0400  /* length will be first received byte */

47.     __u16 len;      /* msg length               */

48.     __u8 *buf;      /* pointer to msg data          */

49. };

(2)i2c_driver与i2c_client。

i2c_driver对应一套驱动方法,其主要成员函数是probe()、remove()、suspend()、resume()等,另外id_table是该驱动所支持的I2C设备的ID表。i2c_client对应于真实的物理设备,每个I2C设备都需要一个i2c_client来描述。I2c_driver和i2c_client的关系是一对多,一个i2c_driver上可以支持多个同类型的i2c_client。

I2c_client信息通常在BSP的板文件中通过i2c_board_info填充,如下面代码就定义了一个I2C设备ID为“24c02”、地址为0x50的i2c_client:

代码清单6 i2c_board_info结构体定义

1. static struct i2c_board_info __initdata smdk2440_i2c_devs[] = {

2.     {

3.         I2C_BOARD_INFO("24c02", 0x50),

4.         .platform_data = &at24c02,

5.     },

6.     /*  more devices can be added using expansion connectors */

7. };

在I2C总线驱动i2c_bus_type的match()函数i2c_device_match()中,会调用i2c_match_id()函数匹配板文件中定义的ID和i2c_driver所支持的ID表。

代码清单7 i2c_device_match函数在linux-3.0/drivers/i2c/i2c-core.c

1. static int i2c_device_match(struct device *dev, struct device_driver *drv)

2. {

3.     struct i2c_client   *client = i2c_verify_client(dev);

4.     struct i2c_driver   *driver;

5.     if (!client)

6.         return 0;

7.     /* Attempt an OF style match */

8.     if (of_driver_match_device(dev, drv))

9.         return 1;

10.     driver = to_i2c_driver(drv);

11.     /* match on an id table if there is one */

12.     if (driver->id_table)

13.         return i2c_match_id(driver->id_table, client) != NULL;

14.     return 0;

15. }

(3)i2c_adpater与i2c_client。

i2c_adapter与i2c_client的关系与I2C硬件体系中适配器和设备的关系一致,即i2c_client依附于i2c_adapter。由于一个适配器上可以连接多个I2C设备,所以一个i2c_adapter也可以被多个i2c_client依附,i2c_adapter中包含依附于它的i2c_client的链表。

代码清单8 i2c_client的链表

1. struct list_head userspace_clients;

假设I2C总线适配器xxx上有两个使用相同驱动程序的yyyI2C设备,在打开盖I2C总线的设备节点后相关数据结构之间的逻辑组织关系将如下图所示:

从上面的分析可知,虽然I2C硬件体系结构简单,但是I2C体系结构在linux中的实现却相当复杂。当工程师拿到实际的电路板,面对复杂的linux I2C子系统,应该如何下手写驱动呢?究竟要哪些是需要亲自做的,哪些是内核已经提供的呢?理清这个问题非常有意义,可以使我们面对具体问题时迅速地抓住重点。

一方面,适配器驱动可能是linux内核本身还不包含的;另一方面,挂接在适配器上的就提设备可能也是linux内核还不包含的。因此,工程师要实现的主要工作如下。

l 提供I2C适配器的硬件驱动,探测、初始化I2C适配器(如申请I2C的I/O地址和中断号)、驱动CPU控制的I2C适配器从硬件上产生各种信号以及处理I2C中断等。

l 提供I2C适配器的algorithm,具体适配器的xxx_xfer()函数填充i2c_algorithm的master_xfer指针,并把i2c_algorithm指针赋值给i2c_adapter的algo指针。

l 实现I2C设备驱动中的i2c_driver接口,具体设备yyy_probe()、yyy_remove()、yyy_suspend()、yyy_resume()函数指针和i2c_device_id设备ID表赋值给i2c_driver的probe、remove、suspend、resume和id_table指针。

l 实现I2C设备所对应类型的具体驱动,i2c_driver只是实现设备与总线的挂接,而挂接在总线上的设备则是千差万别的。例如,如果字符设备,就实现文件操作接口,即实现具体yyy的yyy_read()、yyy_write()和yyy_ioctl()函数等;如果是声卡,就实现ALSA驱动。

I2c的第一部分----I2C设备驱动

上述工作中前两个属于I2C总线驱动,后两个属于I2C设备驱动,做完这些工作,系统会增加两个内核模块。在详细分析这些工作的实施方法给出设计模板之前,先看下linux I2C核心部分。

Linux I2C核心

I2C核心(driver/i2c/i2c-core.c)文件中提供了一组不依赖与硬件平台的接口函数,这个文件一般不需要被工程师修改,但是理解其中的主要函数非常关键,因为I2C总线驱动和设备驱动之间依赖于I2C核心作为纽带I2C核心中的主要函数如下。

(1)增加/删除i2c_adapter。

代码清单9 i2c_add_adapter函数:

1. /**

2.  * i2c_add_adapter - declare i2c adapter, use dynamic bus number

3.  * @adapter: the adapter to add

4.  * Context: can sleep

5.  *

6.  * This routine is used to declare an I2C adapter when its bus number

7.  * doesn't matter.  Examples: for I2C adapters dynamically added by

8.  * USB links or PCI plugin cards.

9.  *

10.  * When this returns zero, a new bus number was allocated and stored

11.  * in adap->nr, and the specified adapter became available for clients.

12.  * Otherwise, a negative errno value is returned.

13.  */

14. int i2c_add_adapter(struct i2c_adapter *adapter)

15. {

16.     int id, res = 0;

17. retry:

18.     if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0)

19.         return -ENOMEM;

20.     mutex_lock(&core_lock);

21.     /* "above" here means "above or equal to", sigh */

22.     res = idr_get_new_above(&i2c_adapter_idr, adapter,

23.                 __i2c_first_dynamic_bus_num, &id);

24.     mutex_unlock(&core_lock);

25.     if (res < 0) {

26.         if (res == -EAGAIN)

27.             goto retry;

28.         return res;

29.     }

30.     adapter->nr = id;

31.     return i2c_register_adapter(adapter);

32. }

33. EXPORT_SYMBOL(i2c_add_adapter);

代码清单10 I2c_del_adapter函数:

1. /**

2.  * i2c_del_adapter - unregister I2C adapter

3.  * @adap: the adapter being unregistered

4.  * Context: can sleep

5.  *

6.  * This unregisters an I2C adapter which was previously registered

7.  * by @i2c_add_adapter or @i2c_add_numbered_adapter.

8.  */

9. int i2c_del_adapter(struct i2c_adapter *adap)

10. {

11.     int res = 0;

12.     struct i2c_adapter *found;

13.     struct i2c_client *client, *next;

14.     /* First make sure that this adapter was ever added */

15.     mutex_lock(&core_lock);

16.     found = idr_find(&i2c_adapter_idr, adap->nr);

17.     mutex_unlock(&core_lock);

18.     if (found != adap) {

19.         pr_debug("i2c-core: attempting to delete unregistered "

20.              "adapter [%s]\n", adap->name);

21.         return -EINVAL;

22.     }

23.     /* Tell drivers about this removal */

24.     mutex_lock(&core_lock);

25.     res = bus_for_each_drv(&i2c_bus_type, NULL, adap,

26.                    __process_removed_adapter);

27.     mutex_unlock(&core_lock);

28.     if (res)

29.         return res;

30.     /* Remove devices instantiated from sysfs */

31.     mutex_lock(&adap->userspace_clients_lock);

32.     list_for_each_entry_safe(client, next, &adap->userspace_clients,

33.                  detected) {

34.         dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,

35.             client->addr);

36.         list_del(&client->detected);

37.         i2c_unregister_device(client);

38.     }

39.     mutex_unlock(&adap->userspace_clients_lock);

40.     /* Detach any active clients. This can't fail, thus we do not

41.      * check the returned value. This is a two-pass process, because

42.      * we can't remove the dummy devices during the first pass: they

43.      * could have been instantiated by real devices wishing to clean

44.      * them up properly, so we give them a chance to do that first. */

45.     res = device_for_each_child(&adap->dev, NULL, __unregister_client);

46.     res = device_for_each_child(&adap->dev, NULL, __unregister_dummy);

47. #ifdef CONFIG_I2C_COMPAT

48.     class_compat_remove_link(i2c_adapter_compat_class, &adap->dev,

49.                  adap->dev.parent);

50. #endif

51.     /* device name is gone after device_unregister */

52.     dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);

53.     /* clean up the sysfs representation */

54.     init_completion(&adap->dev_released);

55.     device_unregister(&adap->dev);

56.     /* wait for sysfs to drop all references */

57.     wait_for_completion(&adap->dev_released);

58.     /* free bus id */

59.     mutex_lock(&core_lock);

60.     idr_remove(&i2c_adapter_idr, adap->nr);

61.     mutex_unlock(&core_lock);

62.     /* Clear the device structure in case this adapter is ever going to be

63.        added again */

64.     memset(&adap->dev, 0, sizeof(adap->dev));

65.     return 0;

66. }

67. EXPORT_SYMBOL(i2c_del_adapter);

(2)增加/删除i2c_driver。

代码清单11 I2c_register_driver函数:

1. static int i2c_register_adapter(struct i2c_adapter *adap)

2. {

3.     int res = 0;

4.     /* Can't register until after driver model init */

5.     if (unlikely(WARN_ON(!i2c_bus_type.p))) {

6.         res = -EAGAIN;

7.         goto out_list;

8.     }  

9.     /* Sanity checks */

10.     if (unlikely(adap->name[0] == '\0')) {   

11.         pr_err("i2c-core: Attempt to register an adapter with "

12.                "no name!\n");

13.         return -EINVAL;

14.     }  

15.     if (unlikely(!adap->algo)) {        

16.         pr_err("i2c-core: Attempt to register adapter '%s' with "

17.                "no algo!\n", adap->name);        

18.         return -EINVAL;

19.     }  

20.     rt_mutex_init(&adap->bus_lock);     

21.     mutex_init(&adap->userspace_clients_lock);

22.     INIT_LIST_HEAD(&adap->userspace_clients);

23.     /* Set default timeout to 1 second if not already set */

24.     if (adap->timeout == 0)

25.         adap->timeout = HZ;             

26.     dev_set_name(&adap->dev, "i2c-%d", adap->nr);

27.     adap->dev.bus = &i2c_bus_type;

28.     adap->dev.type = &i2c_adapter_type;

29.     res = device_register(&adap->dev);

30.     if (res)

31.         goto out_list;

32.     dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);

33. #ifdef CONFIG_I2C_COMPAT

34.     res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev,

35.                        adap->dev.parent);

36.     if (res)

37.         dev_warn(&adap->dev,

38.              "Failed to create compatibility class link\n");

39. #endif

40.     /* create pre-declared device nodes */

41.     if (adap->nr < __i2c_first_dynamic_bus_num)

42.         i2c_scan_static_board_info(adap);

43.     /* Notify drivers */

44.     mutex_lock(&core_lock);

45.     bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);

46.     mutex_unlock(&core_lock);

47.     return 0;

48. out_list:

49.     mutex_lock(&core_lock);

50.     idr_remove(&i2c_adapter_idr, adap->nr);

51.     mutex_unlock(&core_lock);

52.     return res;

53. }

代码清单12 i2c_del_driver函数:

1. /**

2.  * i2c_del_driver - unregister I2C driver

3.  * @driver: the driver being unregistered

4.  * Context: can sleep

5.  */

6. void i2c_del_driver(struct i2c_driver *driver)

7. {

8.     i2c_for_each_dev(driver, __process_removed_driver);

9.     driver_unregister(&driver->driver);

10.     pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);

11. }

12. EXPORT_SYMBOL(i2c_del_driver);

(3)i2c_client依附/脱离。

当一个具体的client被侦测到并被关联的时候,设备和使用爽肤水文件件被注册。相反地,在client杯取消关联的时候,sysfs文件和设备也被注销。如下代码清单。

代码清单13 i2c_new_device函数:

1. /**

2.  * i2c_new_device - instantiate an i2c device

3.  * @adap: the adapter managing the device

4.  * @info: describes one I2C device; bus_num is ignored

5.  * Context: can sleep

6.  *

7.  * Create an i2c device. Binding is handled through driver model

8.  * probe()/remove() methods.  A driver may be bound to this device when we

9.  * return from this function, or any later moment (e.g. maybe hotplugging will

10.  * load the driver module).  This call is not appropriate for use by mainboard

11.  * initialization logic, which usually runs during an arch_initcall() long

12.  * before any i2c_adapter could exist.

13.  *

14.  * This returns the new i2c client, which may be saved for later use with

15.  * i2c_unregister_device(); or NULL to indicate an error.

16.  */

17. struct i2c_client *

18. i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info)

19. {

20.     struct i2c_client   *client;

21.     int         status;

22.     client = kzalloc(sizeof *client, GFP_KERNEL);

23.     if (!client)

24.         return NULL;

25.     client->adapter = adap;

26.     client->dev.platform_data = info->platform_data;

27.     if (info->archdata)

28.         client->dev.archdata = *info->archdata;

29.     client->flags = info->flags;

30.     client->addr = info->addr;

31.     client->irq = info->irq;

32.     strlcpy(client->name, info->type, sizeof(client->name));

33.     /* Check for address validity */

34.     status = i2c_check_client_addr_validity(client);

35.     if (status) {

36.         dev_err(&adap->dev, "Invalid %d-bit I2C address 0x%02hx\n",

37.             client->flags & I2C_CLIENT_TEN ? 10 : 7, client->addr);

38.         goto out_err_silent;

39.     }

40.     /* Check for address business */

41.     status = i2c_check_addr_busy(adap, client->addr);

42.     if (status)

43.         goto out_err;

44.     client->dev.parent = &client->adapter->dev;

45.     client->dev.bus = &i2c_bus_type;

46.     client->dev.type = &i2c_client_type;

47.     client->dev.of_node = info->of_node;

48.     dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),

49.              client->addr);

50.     status = device_register(&client->dev);

51.     if (status)

52.         goto out_err;

53.     dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n",

54.         client->name, dev_name(&client->dev));

55.     return client;

56. out_err:

57.     dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x "

58.         "(%d)\n", client->name, client->addr, status);

59. out_err_silent:

60.     kfree(client);

61.     return NULL;

62. }

63. EXPORT_SYMBOL_GPL(i2c_new_device);

代码清单14 i2c_unregister_device函数

1. /**

2.  * i2c_unregister_device - reverse effect of i2c_new_device()

3.  * @client: value returned from i2c_new_device()

4.  * Context: can sleep

5.  */

6. void i2c_unregister_device(struct i2c_client *client)

7. {

8.     device_unregister(&client->dev);

9. }

10. EXPORT_SYMBOL_GPL(i2c_unregister_device);

(4)I2C传输、发送和接收。

I2c_transfer()函数本身不具备驱动适配器物理硬件完成消息交互的能力,它只是寻找到i2c_adapter对应的i2c_algorithm,并使用i2c_algorithm的master_xfer()函数真正驱动硬件流程。

代码清单15 i2c_transfer函数

1. /* ----------------------------------------------------

2.  * the functional interface to the i2c busses.

3.  * ----------------------------------------------------

4.  */

5. /**

6.  * i2c_transfer - execute a single or combined I2C message

7.  * @adap: Handle to I2C bus

8.  * @msgs: One or more messages to execute before STOP is issued to

9.  *  terminate the operation; each message begins with a START.

10.  * @num: Number of messages to be executed.

11.  *

12.  * Returns negative errno, else the number of messages executed.

13.  *

14.  * Note that there is no requirement that each message be sent to

15.  * the same slave address, although that is the most common model.

16.  */

17. int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)

18. {

19.     unsigned long orig_jiffies;

20.     int ret, try;

21.     /* REVISIT the fault reporting model here is weak:

22.      *

23.      *  - When we get an error after receiving N bytes from a slave,

24.      *    there is no way to report "N".

25.      *

26.      *  - When we get a NAK after transmitting N bytes to a slave,

27.      *    there is no way to report "N" ... or to let the master

28.      *    continue executing the rest of this combined message, if

29.      *    that's the appropriate response.

30.      *

31.      *  - When for example "num" is two and we successfully complete

32.      *    the first message but get an error part way through the

33.      *    second, it's unclear whether that should be reported as

34.      *    one (discarding status on the second message) or errno

35.      *    (discarding status on the first one).

36.      */

37.     if (adap->algo->master_xfer) {

38. #ifdef DEBUG

39.         for (ret = 0; ret < num; ret++) {

40.             dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "

41.                 "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)

42.                 ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,

43.                 (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");

44.         }

45. #endif

46.         if (in_atomic() || irqs_disabled()) {

47.             ret = i2c_trylock_adapter(adap);

48.             if (!ret)

49.                 /* I2C activity is ongoing. */

50.                 return -EAGAIN;

51.         } else {

52.             i2c_lock_adapter(adap);

53.         }

54.         /* Retry automatically on arbitration loss */

55.         orig_jiffies = jiffies;

56.         for (ret = 0, try = 0; try <= adap->retries; try++) {

57.             ret = adap->algo->master_xfer(adap, msgs, num);

58.             if (ret != -EAGAIN)

59.                 break;

60.             if (time_after(jiffies, orig_jiffies + adap->timeout))

61.                 break;

62.         }

63.         i2c_unlock_adapter(adap);

64.         return ret;

65.     } else {

66.         dev_dbg(&adap->dev, "I2C level transfers not supported\n");

67.         return -EOPNOTSUPP;

68.     }

69. }

70. EXPORT_SYMBOL(i2c_transfer);

代码清单16 i2c_master_send函数

1. /**

2.  * i2c_master_send - issue a single I2C message in master transmit mode

3.  * @client: Handle to slave device

4.  * @buf: Data that will be written to the slave

5.  * @count: How many bytes to write, must be less than 64k since msg.len is u16

6.  *

7.  * Returns negative errno, or else the number of bytes written.

8.  */

9. int i2c_master_send(const struct i2c_client *client, const char *buf, int count)

10. {

11.     int ret;

12.     struct i2c_adapter *adap = client->adapter;

13.     struct i2c_msg msg;

14.     msg.addr = client->addr;

15.     msg.flags = client->flags & I2C_M_TEN;

16.     msg.len = count;

17.     msg.buf = (char *)buf;

18.     ret = i2c_transfer(adap, &msg, 1);

19.     /* If everything went ok (i.e. 1 msg transmitted), return #bytes

20.        transmitted, else error code. */

21.     return (ret == 1) ? count : ret;

22. }

23. EXPORT_SYMBOL(i2c_master_send);

代码清单17 i2c_master_recv函数

1. /**

2.  * i2c_master_recv - issue a single I2C message in master receive mode

3.  * @client: Handle to slave device

4.  * @buf: Where to store data read from slave

5.  * @count: How many bytes to read, must be less than 64k since msg.len is u16

6.  *

7.  * Returns negative errno, or else the number of bytes read.

8.  */

9. int i2c_master_recv(const struct i2c_client *client, char *buf, int count)

10. {

11.     struct i2c_adapter *adap = client->adapter;

12.     struct i2c_msg msg;

13.     int ret;

14.     msg.addr = client->addr;

15.     msg.flags = client->flags & I2C_M_TEN;

16.     msg.flags |= I2C_M_RD;

17.     msg.len = count;

18.     msg.buf = buf;

19.     ret = i2c_transfer(adap, &msg, 1);

20.     /* If everything went ok (i.e. 1 msg transmitted), return #bytes

21.        transmitted, else error code. */

22.     return (ret == 1) ? count : ret;

23. }

24. EXPORT_SYMBOL(i2c_master_recv);

i2c_transfer()函数用于进行I2C适配器和I2C设备之间的一组消息交互,i2c_master_send()函数和i2c_master_recv()函数内部会调用i2c_transfer函数分别完成一条写消息和一条读消息。

I2c的第二部分----I2C总线驱动

I2c总线驱动模块的加载函数要完成两个工作。

l 第一个是初始化i2c适配器所使用的硬件资源,如申请I/O地址、中断号等。

l 第二个是通过i2c_add_adapter()添加i2c_adapter的数据结构,当然这个i2c_adapter数据结构的成员已经被适配器的相应的函数指针所初始化。

第一个工作对于s3c2440的i2c模块而言内核中做了这个工作,如下:

S3c2440处理器内部集成了一个I2C控制器,通过4个寄存器就可以方便地对其进行控制,这4个寄存器如下:

l IICCON:I2C控制寄存器。

l IICSTAT:I2C状态寄存器。

l IICDS:I2C收发数据移位寄存器。

l IICADD:I2C地址寄存器。

S3c2440处理器内部集成的I2C控制器可支持主、从两种模式,我们主要使用其主模式。通过对IICCON、IICDS和IICADD寄存器的操作,可

在I2C总线上产生开始位、停止位、数据和地址,而传输的状态则通过IICSTAT寄存器获取。

s3c2440 I2C 总线驱动总体分析

s3c_2440的I2C总线驱动driver/i2c/busses/i2c-s3c2410.c支持s3c24xx、s3c64xx、s5pc1xx和s5p64xx处理器,在我们使用的3.0内核版本中,其名称任然叫2410,显然是历史原因引起的。它主要完成以下工作。

(1)

代码清单18 module_init

1. module_init(i2c_dev_init);

i2c_dev_init函数

代码清单19 i2c_dev_init函数                                                                                                  

1. /* ------------------------------------------------------------------------- */

2. /*

3.  * module load/unload record keeping

4.  */

5. static int __init i2c_dev_init(void)

6. {

7.     int res;

8.     printk(KERN_INFO "i2c /dev entries driver\n");

9.     res = register_chrdev(I2C_MAJOR, "i2c", &i2cdev_fops);

10.     if (res)

11.         goto out;

12.     i2c_dev_class = class_create(THIS_MODULE, "i2c-dev");

13.     if (IS_ERR(i2c_dev_class)) {

14.         res = PTR_ERR(i2c_dev_class);

15.         goto out_unreg_chrdev;

16.     }

17.     /* Keep track of adapters which will be added or removed later */

18.     res = bus_register_notifier(&i2c_bus_type, &i2cdev_notifier);

19.     if (res)

20.         goto out_unreg_class;

21.     /* Bind to already existing adapters right away */

22.     i2c_for_each_dev(NULL, i2cdev_attach_adapter);

23.     return 0;

24. out_unreg_class:

25.     class_destroy(i2c_dev_class);

26. out_unreg_chrdev:

27.     unregister_chrdev(I2C_MAJOR, "i2c");

28. out:

29.     printk(KERN_ERR "%s: Driver Initialisation failed\n", __FILE__);

30.     return res;

31. }

函数首先调用register_chardev函数向内核注册主设备号为I2C_MAJOR、操作集为i2cdev_fops的字符设备。然后调用一次调用-->i2c_for_each_dev-->bus_for_each_dev-->fn函数来立即绑定已经存在的适配器adapters

代码清单20 file_opertions结构体初始化

1. static const struct file_operations i2cdev_fops = {

2.     .owner      = THIS_MODULE,

3.     .llseek     = no_llseek,

4.     .read       = i2cdev_read,

5.     .write      = i2cdev_write,

6.     .unlocked_ioctl = i2cdev_ioctl,

7.     .open       = i2cdev_open,

8.     .release    = i2cdev_release,

9. };

I2c设备驱动(也称为客户驱动)是对I2c硬件体系结构中设备端的实现,我们这里是AT24C02的I2c设备驱动,设备一般挂接在受CPU控制的I2c适配器上,通过I2c适配器与CPU交换数据。

首先是要在内核中注册板级信息,因为设备和驱动需要匹配,他们是通过设备名和驱动名进行匹配的。因为AT24C02芯片是由2048bits构成,所以有2048 / 8 = 256byte,并将其分成32页每页有8byte大小,是8bits寻址,如果AT24C02芯片的A0A1,A2,这三个引脚接地,着AT24C02芯片从地址是01010000b(0x50),如果AT24C02芯片的A0结高电平,A1A2两个引脚接地,着AT24C02芯片从地址是01010001b(0x51),这些都是AT24C02datasheet上有的,不同芯片不同情况。下面在linux-3.0/arch/arm/mach-s3c2440/mach-smdk2440.c添加AT24C02设备的板级信息如下(其中行首的行号是文件中大致的位置):

[fulinux@ubuntu linux-3.0]$ vim arch/arm/mach-s3c2440/mach-smdk2440.c 

54 #include <linux/i2c.h>     

55 #include <linux/i2c/at24.h> 

190 static struct at24_platform_data at24c02= {

191     .byte_len   = SZ_2K / 8,

192     .page_size  = 8,

193     .flags      = AT24_FLAG_ADDR8,

194 };

195 

196 static struct i2c_board_info __initdata smdk2440_i2c_devs[] = {

197     {

198         I2C_BOARD_INFO("24c02", 0x50),

199         .platform_data = &at24c02,

200     },

201     /*  more devices can be added using expansion connectors */

202 };

I2c设备驱动主要包含了数据结构i2c_driver和i2c_clien,我们需要根据具体的设备实现其中的成员函数。下面我们紧紧围绕这两个数据结构展开。

i2c_driver

在linux-3.0/include/linux/i2c.h文件中有定义其i2c_driver数据结构,如下:

/*

 * struct i2c_driver - represent an I2C device driver

 * @class: What kind of i2c device we instantiate (for detect)

 * @attach_adapter: Callback for bus addition (deprecated)

 * @detach_adapter: Callback for bus removal (deprecated)

 * @probe: Callback for device binding

 * @remove: Callback for device unbinding

 * @shutdown: Callback for device shutdown

 * @suspend: Callback for device suspend

 * @resume: Callback for device resume

 * @alert: Alert callback, for example for the SMBus alert protocol

 * @command: Callback for bus-wide signaling (optional)

 * @driver: Device driver model driver

 * @id_table: List of I2C devices supported by this driver

 * @detect: Callback for device detection

 * @address_list: The I2C addresses to probe (for detect)

 * @clients: List of detected clients we created (for i2c-core use only)

 *

 * The driver.owner field should be set to the module owner of this driver.

 * The driver.name field should be set to the name of this driver.

 *

 * For automatic device detection, both @detect and @address_data must

 * be defined. @class should also be set, otherwise only devices forced

 * with module parameters will be created. The detect function must

 * fill at least the name field of the i2c_board_info structure it is

 * handed upon successful detection, and possibly also the flags field.

 *

 * If @detect is missing, the driver will still work fine for enumerated

 * devices. Detected devices simply won't be supported. This is expected

 * for the many I2C/SMBus devices which can't be detected reliably, and

 * the ones which can always be enumerated in practice.

 *

 * The i2c_client structure which is handed to the @detect callback is

 * not a real i2c_client. It is initialized just enough so that you can

 * call i2c_smbus_read_byte_data and friends on it. Don't do anything

 * else with it. In particular, calling dev_dbg and friends on it is

 * not allowed.

 */

struct i2c_driver {

    unsigned int class;

    /* Notifies the driver that a new bus has appeared or is about to be

     * removed. You should avoid using this, it will be removed in a

     * near future.

     */

    int (*attach_adapter)(struct i2c_adapter *) __deprecated;

    int (*detach_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;

};

675/*--------------------------------------------------------------------*/

676 

677 static struct i2c_driver at24_driver = {

678     .driver = {

679         .name = "at24",

680         .owner = THIS_MODULE,

681     },

682     .probe = at24_probe,

683     .remove = __devexit_p(at24_remove),

684     .id_table = at24_ids,

685 };

686 

/**

 * struct i2c_client - represent an I2C slave device

 * @flags: I2C_CLIENT_TEN indicates the device uses a ten bit chip address;

 *  I2C_CLIENT_PEC indicates it uses SMBus Packet Error Checking

 * @addr: Address used on the I2C bus connected to the parent adapter.

 * @name: Indicates the type of the device, usually a chip name that's

 *  generic enough to hide second-sourcing and compatible revisions.

 * @adapter: manages the bus segment hosting this I2C device

 * @driver: device's driver, hence pointer to access routines

 * @dev: Driver model device node for the slave.

 * @irq: indicates the IRQ generated by this device (if any)

 * @detected: member of an i2c_driver.clients list or i2c-core's

 *  userspace_devices list

 *

 * An i2c_client identifies a single device (i.e. chip) connected to an

 * i2c bus. The behaviour exposed to Linux is defined by the driver

 * managing the device.

 */

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 i2c_driver *driver;  /* and our access routines  */

    struct device dev;      /* the device structure     */

    int irq;            /* irq issued by device     */

    struct list_head detected;

};

I2c的第三部分----linux I2c核心:

由于I2c核心(drivers/i2c/i2c-core.c)中提供了一组不依赖与硬件平台的接口函数,这个文件一般不需要修改。I2c核心中的主要函数如下:

你可能感兴趣的:(i2c,i2c设备驱动)