2. I2C 簡介
24LC02 EEPROM 簡介
Linux I2C Driver Framework
I2C Client Driver FOR 24LC02
I2c Host Controller (Master Driver)
User Space Driver
Low-Level Sysfs Operations
Outline
3. 它是一種半雙工的串列式 bus
它是一種廣播式的 bus
三種通訊速度
1. Standard is 100 Kbps
2. Fast-mode is 400 Kbps
3. high-speed mode supports speeds up to 3.4
Mbps
supports 7-bit and 10-bit address
Master-slave communication
3
What is I2C (Inter-IC) ?
11. 24C02 Write OPERATION
Page write operations are limited to writing bytes within a single physical page
Physical page boundaries start at addresses that are integer multiples of the page buffer size
(or ‘page size’) and end at addresses that are integer multiples of [page size – 1].
24. i2c_transfer()
int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
{
if (adap->algo->master_xfer) {
……..
ret = __i2c_transfer(adap, msgs, num);
….
} else {
dev_dbg(&adap->dev, "I2C level transfers not supportedn");
return -EOPNOTSUPP;
}
}
It depends on the implementation of
bus driver …….
(we will discuss later)
46. static u32 bcm2708_i2c_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static struct i2c_algorithm bcm2708_i2c_algorithm = {
.master_xfer = bcm2708_i2c_master_xfer, // implement bus transfer function
.functionality = bcm2708_i2c_functionality,
};
47. Bus transfer function (i2c-bcm2708.c)
static int bcm2708_i2c_master_xfer( struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
struct bcm2708_i2c *bi = adap->algo_data; // chip register control
spin_lock_irqsave(&bi->lock, flags);
INIT_COMPLETION(bi->done);
bi->msg = msgs;
bi->pos = 0;
bi->nmsgs = num;
bi->error = false;
bcm2708_bsc_setup(bi); // active chip to do i2c transfer and then wait for its completion
/* unlockig _after_ the setup to avoid races with the interrupt routine */
spin_unlock_irqrestore(&bi->lock, flags);
ret = wait_for_completion_timeout(&bi->done,
msecs_to_jiffies(I2C_TIMEOUT_MS));
if (ret == 0) {
dev_err(&adap->dev, "transfer timed outn");
spin_lock_irqsave(&bi->lock, flags);
bcm2708_bsc_reset(bi);
spin_unlock_irqrestore(&bi->lock, flags);
return -ETIMEDOUT;
}
return bi->error ? -EIO : num;
}