Linux SPI、I2C驱动
1 SPI
1.1 结构体介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| struct xxx_dev{ struct spi_device *spi;
};
struct of_device_id xxx_table[] = { {.compatible = "forlinx,xxx"}, {}, };
struct spi_driver xxx_driver = { .driver = { .name = "xxx", .of_match_table = xxx_table, }, .probe = xxx_probe, .remove = xxx_remove, };
module_spi_driver(xxx_driver); MODULE_LICENSE("GPL");
|
1.2 probe函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| static int xxx_probe(struct spi_device *spi){ struct xxx_dev *dev; dev = devm_kzalloc(&spi->dev, sizeof(*dev), GFP_KERNEL); dev->client = spi; i2c_set_clientdata(spi, dev);
return 0; }
|
1.3 remove函数
1 2 3 4 5 6 7 8
| static int xxx_remove(struct spi_device *spi){ struct xxx_dev *dev = spi_get_drvdata(spi);
return 0; }
|
1.4 SPI读写函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| static int spi_read_reg(struct spi_device *spi, u8 reg, u8 *val) { int ret; u8 tx_buf = reg | 0x80; u8 rx_buf = 0;
ret = spi_write_then_read(spi, &tx_buf, 1, &rx_buf, 1); if (ret < 0) { return ret; } *val = rx_buf; return 0; }
static int spi_write_reg(struct spi_device *spi, u8 reg, u8 val) { u8 tx_buf[2]; tx_buf[0] = reg & 0x7F; tx_buf[1] = val;
return spi_write(spi, tx_buf, 2); }
|
I2C驱动
2.1 结构体介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| struct xxx_dev{ struct i2c_client *i2c;
};
static struct of_device_id xxx_table[] = { {.compatible = "forlinx,xxx"}, {}, };
static struct i2c_driver xxx_driver = { .driver = { .name = "xxx", .of_match_table = xxx_table, }, .probe = xxx_probe, .remove = xxx_remove, };
module_i2c_driver(xxx_driver); MODULE_LICENSE("GPL");
|
2.2 probe函数
1 2 3 4 5 6 7 8 9 10 11 12 13
| static int xxx_probe(struct i2c_client *i2c){ struct xxx_dev *dev; dev = devm_kzalloc(&i2c->dev, sizeof(*dev), GFP_KERNEL); dev->i2c = i2c; i2c_set_clientdata(i2c, dev);
return 0; }
|
2.3 remove函数
1 2 3 4 5 6 7 8
| static int xxx_remove(struct i2c_client *i2c){ struct xxx_dev *dev = i2c_get_clientdata(i2c);
return 0; }
|
2.4 I2C读写函数
1 2
| i2c_smbus_read_byte_data(dev->i2c, REG) i2c_smbus_write_byte_data(dev->i2c, GEG, 0x00);
|
总结
其实从代码结构来看SPI 和 I2C驱动的主体结构体是相互对应,主要是它们所操作的对应的硬件的不同(子系统不同),需要构建相应的硬件操作对象(为了解耦)。这里是一个复杂点,关于操作的硬件对象我们在下一章节介绍