Linux I2C子系统分析-I2C总线驱动

drivers/i2c/busses下包含各种I2C总线驱动,如S3C2440I2C总线驱动i2c-s3c2410.c,使用GPIO模拟I2C总线的驱动i2c-gpio.c,这里只分析i2c-gpio.c

i2c-gpio.c它是gpio模拟I2C总线的驱动,总线也是个设备,在这里将总线当作平台设备处理,那驱动当然是平台设备驱动,看它的驱动注册和注销函数。

static int __init i2c_gpio_init(void) { int ret; ret = platform_driver_register(&i2c_gpio_driver); if (ret) printk(KERN_ERR "i2c-gpio: probe failed: %d\n", ret); return ret; } module_init(i2c_gpio_init); static void __exit i2c_gpio_exit(void) { platform_driver_unregister(&i2c_gpio_driver); } module_exit(i2c_gpio_exit);

没有什么好说的,它的初始化和注销函数就是注册和注销一个平台设备驱动,直接看它的platform_driver结构i2c_gpio_driver

static struct platform_driver i2c_gpio_driver = { .driver = { .name = "i2c-gpio", .owner = THIS_MODULE, }, .probe = i2c_gpio_probe, .remove = __devexit_p(i2c_gpio_remove), };

小提示:是不是我们应该注册一个平台设备,以和这个驱动匹配,那先来注册这个平台设备。

先定义这个平台设备结构,至于怎么注册平台设备我想大家都应该知道吧。

#if defined(CONFIG_I2C_GPIO) | \ defined(CONFIG_I2C_GPIO_MODULE) static struct i2c_gpio_platform_data i2c_gpio_adapter_data = { .sda_pin = PINID_GPMI_D05, .scl_pin = PINID_GPMI_D04, .udelay = 5, //100KHz .timeout = 100, .sda_is_open_drain = 1, .scl_is_open_drain = 1, }; static struct platform_device i2c_gpio = { .name = "i2c-gpio", .id = 0, .dev = { .platform_data = &i2c_gpio_adapter_data, .release = mxs_nop_release, }, }; #endif

在这里struct platform_device结构中的name字段要和struct platform_driverdriver字段中name字段要相同,因为平台总线就是通过这个来判断设备和驱动是否匹配的。注意这里的id将它赋值了0,至于到底有什么用,后面再来细看。这个结构里面还包含一个最重要的数据i2c_gpio_adapter_data,它struct i2c_gpio_platform_data结构类型变量,这个结构体类型定义在include/linux/i2c-gpio.h中。

struct i2c_gpio_platform_data { unsigned int sda_pin; unsigned int scl_pin; int udelay; int timeout; unsigned int sda_is_open_drain:1; unsigned int scl_is_open_drain:1; unsigned int scl_is_output_only:1; };

这个结构体主要描述gpio模拟i2c总线,sda_pinscl_pin表示使用哪两个IO管脚来模拟I2C总线,udelaytimeout分别为它的时钟频率和超时时间,sda_is_open_drainscl_is_open_drain表示sdascl这两个管脚是否是开漏(opendrain)电路,如果是设置为1scl_is_output_only表示scl这个管脚是否只是作为输出,如果是设置为1

回到驱动中,看其中最重要的i2c_gpio_probe

static int __devinit i2c_gpio_probe(struct platform_device *pdev) { struct i2c_gpio_platform_data *pdata; struct i2c_algo_bit_data *bit_data; struct i2c_adapter *adap; int ret; pdata = pdev->dev.platform_data; if (!pdata) return -ENXIO; ret = -ENOMEM; adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); if (!adap) goto err_alloc_adap; bit_data = kzalloc(sizeof(struct i2c_algo_bit_data), GFP_KERNEL); if (!bit_data) goto err_alloc_bit_data; ret = gpio_request(pdata->sda_pin, "sda"); if (ret) goto err_request_sda; ret = gpio_request(pdata->scl_pin, "scl"); if (ret) goto err_request_scl; if (pdata->sda_is_open_drain) { gpio_direction_output(pdata->sda_pin, 1); bit_data->setsda = i2c_gpio_setsda_val; } else { gpio_direction_input(pdata->sda_pin); bit_data->setsda = i2c_gpio_setsda_dir; } if (pdata->scl_is_open_drain || pdata->scl_is_output_only) { gpio_direction_output(pdata->scl_pin, 1); bit_data->setscl = i2c_gpio_setscl_val; } else { gpio_direction_input(pdata->scl_pin); bit_data->setscl = i2c_gpio_setscl_dir; } if (!pdata->scl_is_output_only) bit_data->getscl = i2c_gpio_getscl; bit_data->getsda = i2c_gpio_getsda; if (pdata->udelay) bit_data->udelay = pdata->udelay; else if (pdata->scl_is_output_only) bit_data->udelay = 50; /* 10 kHz */ else bit_data->udelay = 5; /* 100 kHz */ if (pdata->timeout) bit_data->timeout = pdata->timeout; else bit_data->timeout = HZ / 10; /* 100 ms */ bit_data->data = pdata; adap->owner = THIS_MODULE; snprintf(adap->name, sizeof(adap->name), "i2c-gpio%d", pdev->id); adap->algo_data = bit_data; adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; adap->dev.parent = &pdev->dev; /* * If "dev->id" is negative we consider it as zero. * The reason to do so is to avoid sysfs names that only make * sense when there are multiple adapters. */ adap->nr = (pdev->id != -1) ? pdev->id : 0; ret = i2c_bit_add_numbered_bus(adap); if (ret) goto err_add_bus; platform_set_drvdata(pdev, adap); dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n", pdata->sda_pin, pdata->scl_pin, pdata->scl_is_output_only ? ", no clock stretching" : ""); return 0; err_add_bus: gpio_free(pdata->scl_pin); err_request_scl: gpio_free(pdata->sda_pin); err_request_sda: kfree(bit_data); err_alloc_bit_data: kfree(adap); err_alloc_adap: return ret; }

从这句开始pdata= pdev->dev.platform_data;这不正是我们在平台设备结构中定义的数据吗。然后是使用kzalloc申请两段内存空间,一个是为结构struct i2c_adapter申请的,另一个是为结构structi2c_algo_bit_data申请的。

struct i2c_adapter结构定义在include/linux/i2c.h

struct i2c_adapter { struct module *owner; unsigned int id; unsigned int class; /* classes to allow probing for */ const struct i2c_algorithm *algo; /* the algorithm to access the bus */ void *algo_data; /* data fields that are valid for all devices */ u8 level; /* nesting level for lockdep */ struct mutex bus_lock; int timeout; /* in jiffies */ int retries; struct device dev; /* the adapter device */ int nr; char name[48]; struct completion dev_released; };

I2C子系统中,I2C适配器使用结构struct i2c_adapter描述,代表一条实际的I2C总线。

struct i2c_algo_bit_data结构定义在include/linux/i2c-algo-bit.h

struct i2c_algo_bit_data { void *data; /* private data for lowlevel routines */ void (*setsda) (void *data, int state); void (*setscl) (void *data, int state); int (*getsda) (void *data); int (*getscl) (void *data); /* local settings */ int udelay; /* half clock cycle time in us, minimum 2 us for fast-mode I2C, minimum 5 us for standard-mode I2C and SMBus, maximum 50 us for SMBus */ int timeout; /* in jiffies */ };

这个结构主要用来定义对GPIO管脚的一些操作,还是回到probe

接下来使用gpio_request去申请这个两个GPIO管脚,申请的目的是为了防止重复使用管脚。然后是根据struct i2c_gpio_platform_data结构中定义的后面三个数据对struct i2c_algo_bit_data结构中的函数指针做一些赋值操作。接下来是I2C时钟频率和超时设置,如果在struct i2c_gpio_platform_data结构中定义了值,那么就采用定义的值,否则就采用默认的值。然后是对struct i2c_adapter结构的一些赋值操作,比如指定它的父设备为这里的平台设备,前面在平台设备中定义了一个id,这里用到了,赋给了struct i2c_adapter中的nr成员,这个值表示总线号,这里的总线号和硬件无关,只是在软件上的区分。然后到了最后的主角i2c_bit_add_numbered_bus,这个函数定义在drivers/i2c/algos/i2c-algo-bit.c

int i2c_bit_add_numbered_bus(struct i2c_adapter *adap) { int err; err = i2c_bit_prepare_bus(adap); if (err) return err; return i2c_add_numbered_adapter(adap); }

先看i2c_bit_prepare_bus函数

static int i2c_bit_prepare_bus(struct i2c_adapter *adap) { struct i2c_algo_bit_data *bit_adap = adap->algo_data; if (bit_test) { int ret = test_bus(bit_adap, adap->name); if (ret < 0) return -ENODEV; } /* register new adapter to i2c module... */ adap->algo = &i2c_bit_algo; adap->retries = 3; return 0; }

bit_test为模块参数,这里不管它,看这样一句adap->algo= &i2c_bit_algo;

来看这个结构定义

static const struct i2c_algorithm i2c_bit_algo = { .master_xfer = bit_xfer, .functionality = bit_func, };

先看这个结构类型在哪里定义的include/linux/i2c.h

struct i2c_algorithm { /* If an adapter algorithm can't do I2C-level access, set master_xfer to NULL. If an adapter algorithm can do SMBus access, set smbus_xfer. If set to NULL, the SMBus protocol is simulated using common I2C messages */ /* master_xfer should return the number of messages successfully processed, or a negative value on error */ int (*master_xfer)(struct i2c_adapter *adap, struct i2c_msg *msgs, int num); int (*smbus_xfer) (struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write, u8 command, int size, union i2c_smbus_data *data); /* To determine what the adapter supports */ u32 (*functionality) (struct i2c_adapter *); };

其实也没什么,就三个函数指针外加一长串注释

这个结构的master_xfer指针为主机的数据传输,具体来看bit_xfer这个函数,这个函数和I2C协议相关,I2C协议规定要先发送起始信号,才能开始进行数据的传输,最后数据传输完成后发送停止信号,看接下来代码对I2C协议要熟悉,所以这里的关键点是I2C协议。

static int bit_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) { struct i2c_msg *pmsg; struct i2c_algo_bit_data *adap = i2c_adap->algo_data; int i, ret; unsigned short nak_ok; bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); /*发送起始信号*/ i2c_start(adap); for (i = 0; i < num; i++) { pmsg = &msgs[i]; nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; if (!(pmsg->flags & I2C_M_NOSTART)) { if (i) { bit_dbg(3, &i2c_adap->dev, "emitting " "repeated start condition\n"); i2c_repstart(adap); } ret = bit_doAddress(i2c_adap, pmsg); if ((ret != 0) && !nak_ok) { bit_dbg(1, &i2c_adap->dev, "NAK from " "device addr 0x%02x msg #%d\n", msgs[i].addr, i); goto bailout; } } if (pmsg->flags & I2C_M_RD) { /* read bytes into buffer*/ ret = readbytes(i2c_adap, pmsg); if (ret >= 1) bit_dbg(2, &i2c_adap->dev, "read %d byte%s\n", ret, ret == 1 ? "" : "s"); if (ret < pmsg->len) { if (ret >= 0) ret = -EREMOTEIO; goto bailout; } } else { /* write bytes from buffer */ ret = sendbytes(i2c_adap, pmsg); if (ret >= 1) bit_dbg(2, &i2c_adap->dev, "wrote %d byte%s\n", ret, ret == 1 ? "" : "s"); if (ret < pmsg->len) { if (ret >= 0) ret = -EREMOTEIO; goto bailout; } } } ret = i; bailout: bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); i2c_stop(adap); return ret; }

1.发送起始信号

i2c_start(adap);

看这个函数前,先看I2C协议怎么定义起始信号的


起始信号就是在SCL为高电平期间,SDA从高到低的跳变,再来看代码是怎么实现的

static void i2c_start(struct i2c_algo_bit_data *adap) { /* assert: scl, sda are high */ setsda(adap, 0); udelay(adap->udelay); scllo(adap); }

这些setsdasetscl这些都是使用的总线的函数,在这里是使用的i2c-gpio.c中定义的函数,还记得那一系列判断赋值吗。

#define setsda(adap, val) adap->setsda(adap->data, val) #define setscl(adap, val) adap->setscl(adap->data, val) #define getsda(adap) adap->getsda(adap->data) #define getscl(adap) adap->getscl(adap->data)

2.往下是个大的for循环

到了这里又不得不说这个struct i2c_msg结构,这个结构定义在include/linux/i2c.h

struct i2c_msg { __u16 addr; /* slave address */ __u16 flags; #define I2C_M_TEN 0x0010 /* this is a ten bit chip address */ #define I2C_M_RD 0x0001 /* read data, from slave to master */ #define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */ #define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */ __u16 len; /* msg length */ __u8 *buf; /* pointer to msg data */ };

这个结构专门用于数据传输相关的addrI2C设备地址,flags为一些标志位,len为数据的长度,buf为数据。这里宏定义的一些标志还是需要了解一下。

I2C_M_TEN表示10位设备地址

I2C_M_RD读标志

I2C_M_NOSTART无起始信号标志

I2C_M_IGNORE_NAK忽略应答信号标志

回到for,这里的num代表有几个struct i2c_msg,进入for语句,接下来是个if语句,判断这个设备是否定义了I2C_M_NOSTART标志,这个标志主要用于写操作时,不必重新发送起始信号和设备地址,但是对于读操作就不同了,要调用i2c_repstart这个函数去重新发送起始信号,调用bit_doAddress函数去重新构造设备地址字节,来看这个函数。

static int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { unsigned short flags = msg->flags; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; struct i2c_algo_bit_data *adap = i2c_adap->algo_data; unsigned char addr; int ret, retries; retries = nak_ok ? 0 : i2c_adap->retries; if (flags & I2C_M_TEN) { /* a ten bit address */ addr = 0xf0 | ((msg->addr >> 7) & 0x03); bit_dbg(2, &i2c_adap->dev, "addr0: %d\n", addr); /* try extended address code...*/ ret = try_address(i2c_adap, addr, retries); if ((ret != 1) && !nak_ok) { dev_err(&i2c_adap->dev, "died at extended address code\n"); return -EREMOTEIO; } /* the remaining 8 bit address */ ret = i2c_outb(i2c_adap, msg->addr & 0x7f); if ((ret != 1) && !nak_ok) { /* the chip did not ack / xmission error occurred */ dev_err(&i2c_adap->dev, "died at 2nd address code\n"); return -EREMOTEIO; } if (flags & I2C_M_RD) { bit_dbg(3, &i2c_adap->dev, "emitting repeated " "start condition\n"); i2c_repstart(adap); /* okay, now switch into reading mode */ addr |= 0x01; ret = try_address(i2c_adap, addr, retries); if ((ret != 1) && !nak_ok) { dev_err(&i2c_adap->dev, "died at repeated address code\n"); return -EREMOTEIO; } } } else { /* normal 7bit address */ addr = msg->addr << 1; if (flags & I2C_M_RD) addr |= 1; if (flags & I2C_M_REV_DIR_ADDR) addr ^= 1; ret = try_address(i2c_adap, addr, retries); if ((ret != 1) && !nak_ok) return -ENXIO; } return 0; }

这里先做了一个判断,10位设备地址和7位设备地址分别做不同的处理,通常一条I2C总线上不会挂那么多I2C设备,所以10位地址不常用,直接看对7位地址的处理。struct i2c_msgaddr中是真正的设备地址,而这里发送的addr7位才是设备地址,最低位为读写位,如果为读,最低位为1,如果为写,最低位为0。所以要将struct i2c_msgaddr向左移1位,如果定义了I2C_M_RD标志,就将addr或上1,前面就说过,这个标志就代表读,如果是写,这里就不用处理,因为最低位本身就是0。最后调用try_address函数将这个地址字节发送出去。

static int try_address(struct i2c_adapter *i2c_adap, unsigned char addr, int retries) { struct i2c_algo_bit_data *adap = i2c_adap->algo_data; int i, ret = 0; for (i = 0; i <= retries; i++) { ret = i2c_outb(i2c_adap, addr); if (ret == 1 || i == retries) break; bit_dbg(3, &i2c_adap->dev, "emitting stop condition\n"); i2c_stop(adap); udelay(adap->udelay); yield(); bit_dbg(3, &i2c_adap->dev, "emitting start condition\n"); i2c_start(adap); } if (i && ret) bit_dbg(1, &i2c_adap->dev, "Used %d tries to %s client at " "0x%02x: %s\n", i + 1, addr & 1 ? "read from" : "write to", addr >> 1, ret == 1 ? "success" : "failed, timeout?"); return ret; }

最主要的就是调用i2c_outb发送一个字节,retries为重复次数,看前面adap->retries= 3;

如果发送失败,也就是设备没有给出应答信号,那就发送停止信号,发送起始信号,再发送这个地址字节,这就叫retries。来看这个具体的i2c_outb函数

static int i2c_outb(struct i2c_adapter *i2c_adap, unsigned char c) { int i; int sb; int ack; struct i2c_algo_bit_data *adap = i2c_adap->algo_data; /* assert: scl is low */ for (i = 7; i >= 0; i--) { sb = (c >> i) & 1; setsda(adap, sb); udelay((adap->udelay + 1) / 2); if (sclhi(adap) < 0) { /* timed out */ bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " "timeout at bit #%d\n", (int)c, i); return -ETIMEDOUT; } /* FIXME do arbitration here: * if (sb && !getsda(adap)) -> ouch! Get out of here. * * Report a unique code, so higher level code can retry * the whole (combined) message and *NOT* issue STOP. */ scllo(adap); } sdahi(adap); if (sclhi(adap) < 0) { /* timeout */ bit_dbg(1, &i2c_adap->dev, "i2c_outb: 0x%02x, " "timeout at ack\n", (int)c); return -ETIMEDOUT; } /* read ack: SDA should be pulled down by slave, or it may * NAK (usually to report problems with the data we wrote). */ ack = !getsda(adap); /* ack: sda is pulled low -> success */ bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, ack ? "A" : "NA"); scllo(adap); return ack; /* assert: scl is low (sda undef) */ }

这个函数有两个参数,一个是structi2c_adapter代表I2C主机,一个是发送的字节数据。那么I2C是怎样将一个字节数据发送出去的呢,那再来看看协议。



首先是发送字节数据的最高位,在时钟为高电平期间将一位数据发送出去,最后是发送字节数据的最低位。发送完成之后,我们需要一个ACK信号,要不然我怎么知道发送成功没有,ACK信号就是在第九个时钟周期时数据线为低,所以在一个字节数据传送完成后,还要将数据线拉高,我们看程序中就是这一句sdahi(adap);等待这个ACK信号的到来,这样一个字节数据就发送完成。

回到bit_xfer函数中,前面只是将设备地址字节发送出去了,那么接下来就是该发送数据了。

注意:这里的数据包括操作设备的基地址

如果是读则调用readbytes函数去读,如果是写则调用sendbytes去写,先看readbytes函数

static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { int inval; int rdcount = 0; /* counts bytes read */ unsigned char *temp = msg->buf; int count = msg->len; const unsigned flags = msg->flags; while (count > 0) { inval = i2c_inb(i2c_adap); if (inval >= 0) { *temp = inval; rdcount++; } else { /* read timed out */ break; } temp++; count--; /* Some SMBus transactions require that we receive the transaction length as the first read byte. */ if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) { if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) { if (!(flags & I2C_M_NO_RD_ACK)) acknak(i2c_adap, 0); dev_err(&i2c_adap->dev, "readbytes: invalid " "block length (%d)\n", inval); return -EREMOTEIO; } /* The original count value accounts for the extra bytes, that is, either 1 for a regular transaction, or 2 for a PEC transaction. */ count += inval; msg->len += inval; } bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n", inval, (flags & I2C_M_NO_RD_ACK) ? "(no ack/nak)" : (count ? "A" : "NA")); if (!(flags & I2C_M_NO_RD_ACK)) { inval = acknak(i2c_adap, count); if (inval < 0) return inval; } } return rdcount; }

其中一个大的while循环,调用i2c_inb去读一个字节,count为数据的长度,单位为多少个字节,

那就来看i2c_inb函数。

static int i2c_inb(struct i2c_adapter *i2c_adap) { /* read byte via i2c port, without start/stop sequence */ /* acknowledge is sent in i2c_read. */ int i; unsigned char indata = 0; struct i2c_algo_bit_data *adap = i2c_adap->algo_data; /* assert: scl is low */ sdahi(adap); for (i = 0; i < 8; i++) { if (sclhi(adap) < 0) { /* timeout */ bit_dbg(1, &i2c_adap->dev, "i2c_inb: timeout at bit " "#%d\n", 7 - i); return -ETIMEDOUT; } indata *= 2; if (getsda(adap)) indata |= 0x01; setscl(adap, 0); udelay(i == 7 ? adap->udelay / 2 : adap->udelay); } /* assert: scl is low */ return indata; }

再来看sendbytes函数

static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) { const unsigned char *temp = msg->buf; int count = msg->len; unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; int retval; int wrcount = 0; while (count > 0) { retval = i2c_outb(i2c_adap, *temp); /* OK/ACK; or ignored NAK */ if ((retval > 0) || (nak_ok && (retval == 0))) { count--; temp++; wrcount++; /* A slave NAKing the master means the slave didn't like * something about the data it saw. For example, maybe * the SMBus PEC was wrong. */ } else if (retval == 0) { dev_err(&i2c_adap->dev, "sendbytes: NAK bailout.\n"); return -EIO; /* Timeout; or (someday) lost arbitration * * FIXME Lost ARB implies retrying the transaction from * the first message, after the "winning" master issues * its STOP. As a rule, upper layer code has no reason * to know or care about this ... it is *NOT* an error. */ } else { dev_err(&i2c_adap->dev, "sendbytes: error %d\n", retval); return retval; } } return wrcount; }

也是一个大的while循环,同发送地址字节一样,也是调用i2c_outb去发送一个字节,count也是数据长度,由于i2c_outb函数在前面发送设备地址那里已经介绍了,这里也就不贴出来了。

还是回到bit_xfer函数,数据传输完成后,调用i2c_stop函数发送停止信号。我们看停止信号函数怎么去实现的。

static void i2c_stop(struct i2c_algo_bit_data *adap) { /* assert: scl is low */ sdalo(adap); sclhi(adap); setsda(adap, 1); udelay(adap->udelay); }

看前面发送起始信号的那张图,停止信号就是在时钟为高电平期间,数据线从低到高的跳变。我们看程序是先将数据线拉低,将时钟线拉高,最后将数据拉高,这样就够成了一个停止信号。

还是回到i2c_bit_add_numbered_bus这个函数中来,看另外一个函数调用i2c_add_numbered_adapter

int i2c_add_numbered_adapter(struct i2c_adapter *adap) { int id; int status; if (adap->nr & ~MAX_ID_MASK) return -EINVAL; retry: if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) return -ENOMEM; mutex_lock(&core_lock); /* "above" here means "above or equal to", sigh; * we need the "equal to" result to force the result */ status = idr_get_new_above(&i2c_adapter_idr, adap, adap->nr, &id); if (status == 0 && id != adap->nr) { status = -EBUSY; idr_remove(&i2c_adapter_idr, id); } mutex_unlock(&core_lock); if (status == -EAGAIN) goto retry; if (status == 0) status = i2c_register_adapter(adap); return status; }

最重要的是这句i2c_register_adapter,注册这条I2C总线,进去看看

static int i2c_register_adapter(struct i2c_adapter *adap) { int res = 0, dummy; /* Can't register until after driver model init */ if (unlikely(WARN_ON(!i2c_bus_type.p))) { res = -EAGAIN; goto out_list; } mutex_init(&adap->bus_lock); /* Set default timeout to 1 second if not already set */ if (adap->timeout == 0) adap->timeout = HZ; dev_set_name(&adap->dev, "i2c-%d", adap->nr); adap->dev.bus = &i2c_bus_type; adap->dev.type = &i2c_adapter_type; res = device_register(&adap->dev); if (res) goto out_list; dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name); #ifdef CONFIG_I2C_COMPAT res = class_compat_create_link(i2c_adapter_compat_class, &adap->dev, adap->dev.parent); if (res) dev_warn(&adap->dev, "Failed to create compatibility class link\n"); #endif /* create pre-declared device nodes */ if (adap->nr < __i2c_first_dynamic_bus_num) i2c_scan_static_board_info(adap); /* Notify drivers */ mutex_lock(&core_lock); dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap, i2c_do_add_adapter); mutex_unlock(&core_lock); return 0; out_list: mutex_lock(&core_lock); idr_remove(&i2c_adapter_idr, adap->nr); mutex_unlock(&core_lock); return res; }

看内核代码有时就会这样,会陷入内核代码的汪洋大海中,而拔不出来,直接后果是最后都忘记看这段代码的目的,丧失继续看下去的信心。所以为了避免这样情况出现,所以最好在开始看代码的时候要明确目标,我通过这段代码到底要了解什么东西,主干要抓住,其它枝叶就不要看了。

在这里我认为主要的有

1.注册这个I2C总线设备

adap->dev.bus = &i2c_bus_type; adap->dev.type = &i2c_adapter_type; res = device_register(&adap->dev);

这个设备的总线类型为i2c_bus_type

struct bus_type i2c_bus_type = { .name = "i2c", .match = i2c_device_match, .probe = i2c_device_probe, .remove = i2c_device_remove, .shutdown = i2c_device_shutdown, .suspend = i2c_device_suspend, .resume = i2c_device_resume, };

看一下它的match函数

static int i2c_device_match(struct device *dev, struct device_driver *drv) { struct i2c_client *client = i2c_verify_client(dev); struct i2c_driver *driver; if (!client) return 0; driver = to_i2c_driver(drv); /* match on an id table if there is one */ if (driver->id_table) return i2c_match_id(driver->id_table, client) != NULL; return 0; }

这个match函数主要用来匹配我们的I2C设备和I2C驱动的,如果匹配成功,最后会调用驱动的probe函数,来看它如何匹配的。

static const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id, const struct i2c_client *client) { while (id->name[0]) { if (strcmp(client->name, id->name) == 0) return id; id++; } return NULL; }

就是判断I2C设备的name字段和驱动中id_table中定义的name字段是否相等。

2.往这条总线上添加设备

static void i2c_scan_static_board_info(struct i2c_adapter *adapter) { struct i2c_devinfo *devinfo; down_read(&__i2c_board_lock); list_for_each_entry(devinfo, &__i2c_board_list, list) { if (devinfo->busnum == adapter->nr && !i2c_new_device(adapter, &devinfo->board_info)) dev_err(&adapter->dev, "Can't create device at 0x%02x\n", devinfo->board_info.addr); } up_read(&__i2c_board_lock); }

遍历__i2c_board_list这条链表,看下面的if语句,首先要让struct i2c_devinfo结构中的busnum等于struct i2c_adapter中的nr,我们前面也说了,这个nr就是i2c总线的总线号,这里可以理解为是在往这条总线上添加设备。所以,如果我们要向I2C注册一个I2C设备的话,直接向__i2c_board_list添加一个设备信息就可以了,先来看这个设备信息结构是怎么定义的。

struct i2c_board_info { char type[I2C_NAME_SIZE]; unsigned short flags; unsigned short addr; void *platform_data; struct dev_archdata *archdata; int irq; };

定义这样一个信息呢一般使用一个宏I2C_BOARD_INFO

#define I2C_BOARD_INFO(dev_type, dev_addr) \ .type = dev_type, .addr = (dev_addr)

dev_type为设备的名字,前面也说了,这个name一定要和I2C驱动相同。addr为设备的地址。

定义了这样一组信息之后呢,接下来当然是往链表添加这些信息了。

int __init i2c_register_board_info(int busnum, struct i2c_board_info const *info, unsigned len) { int status; down_write(&__i2c_board_lock); /* dynamic bus numbers will be assigned after the last static one */ if (busnum >= __i2c_first_dynamic_bus_num) __i2c_first_dynamic_bus_num = busnum + 1; for (status = 0; len; len--, info++) { struct i2c_devinfo *devinfo; devinfo = kzalloc(sizeof(*devinfo), GFP_KERNEL); if (!devinfo) { pr_debug("i2c-core: can't register boardinfo!\n"); status = -ENOMEM; break; } devinfo->busnum = busnum; devinfo->board_info = *info; list_add_tail(&devinfo->list, &__i2c_board_list); } up_write(&__i2c_board_lock); return status; }

第一个参数呢需要注意,它是I2C总线号,一定要和具体的I2C总线对应。我们看又定义了这样一个结构struct i2c_devinfo

struct i2c_devinfo { struct list_head list; int busnum; struct i2c_board_info board_info; };

最后是调用list_add_tail__i2c_board_list这条链表添加设备信息。

然后是i2c_new_device

struct i2c_client * i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info) { struct i2c_client *client; int status; /*为I2C设备申请内存*/ client = kzalloc(sizeof *client, GFP_KERNEL); if (!client) return NULL; /*指定I2C设备的总线*/ client->adapter = adap; client->dev.platform_data = info->platform_data; if (info->archdata) client->dev.archdata = *info->archdata; client->flags = info->flags; client->addr = info->addr; /*I2C设备地址*/ client->irq = info->irq; strlcpy(client->name, info->type, sizeof(client->name)); /*检查这个地址有没有被设备占用*/ /* Check for address business */ status = i2c_check_addr(adap, client->addr); if (status) goto out_err; client->dev.parent = &client->adapter->dev; /*指定设备的父设备*/ client->dev.bus = &i2c_bus_type; /*指定设备的总线类型*/ client->dev.type = &i2c_client_type; dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap), client->addr); status = device_register(&client->dev); /*注册设备*/ if (status) goto out_err; dev_dbg(&adap->dev, "client [%s] registered with bus id %s\n", client->name, dev_name(&client->dev)); return client; out_err: dev_err(&adap->dev, "Failed to register i2c client %s at 0x%02x " "(%d)\n", client->name, client->addr, status); kfree(client); return NULL; }

这个函数的功能是新建一个I2C设备并注册它,在I2C子系统中,I2C设备使用结构structi2c_client描述,那么首先要申请内存空间,I2C设备的主机是谁,必须知道挂载到哪条总线上的,然后就是一些赋值操作,最后就是注册设备,那么这个设备就实实在在的挂在到这条总线上了,这也是新的I2C设备注册方式。

3.i2c_do_add_adapter

你看说着说着就跑远了

static int i2c_do_add_adapter(struct device_driver *d, void *data) { struct i2c_driver *driver = to_i2c_driver(d); struct i2c_adapter *adap = data; /* Detect supported devices on that bus, and instantiate them */ i2c_detect(adap, driver); /* Let legacy drivers scan this bus for matching devices */ if (driver->attach_adapter) { /* We ignore the return code; if it fails, too bad */ driver->attach_adapter(adap); } return 0; }

前面通过i2c_scan_static_board_infoI2C总线上添加设备是新的方式,而这里调用每个I2C设备驱动的attach_adapter函数,然后在attach_adapter函数中去实现设备的注册,这是老的方式,i2c-dev.c中就是采用的这种方式。至此,总线这块就看完了。

转载于:https://www.cnblogs.com/phonegap/archive/2012/01/19/2536122.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值