I2C adapter驱动框架
struct xxx_i2c {
void __iomem *base;
struct device *dev;
struct i2c_adapter adap;
struct clk *clk;
u32 quick;
};
static u32 xxx_i2c_functionality(struct i2c_adapter *adap)
{
struct s5pv210_i2c *i2c = container_of(adap, struct s5pv210_i2c, adap);
return i2c->quick;
}
static int xxx_smbus_xfer(struct i2c_adapter *adap, u16 addr, unsigned short flags, char read_write,
u8 cmd, int size, union i2c_smbus_data *data)
{
return 0;
}
static const struct i2c_algorithm xxx_i2c_algo = {
.smbus_xfer = xxx_smbus_xfer,
.functionality = xxx_i2c_functionality,
};
static int xxx_i2c_register(struct xxx_i2c *i2c)
{
struct i2c_adapter *adap = &i2c->adap;
adap->algo = &xxx_i2c_algo;
adap->algo.dev.of_node = i2c->dev->of_node;
adap->alog.dev.parent = i2c->dev;
adap->owner = THIS_MODULE;
adap->quick = I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C;
return i2c_add_adapter(adap);
}
static int xxx_i2c_probe(struct platform_device *pdev)
{
struct xxx_i2c *i2c;
int ret;
i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
if (!i2c)
return -ENOMEM;
i2c->dev = &pdev->dev;
i2c->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(i2c->base)) {
return PTR_ERR(i2c->base);
}
ret = xxx_i2c_register(i2c);
if (ret)
return ret;
platform_set_drvdata(pdev, i2c);
return 0;
}
static int xxx_i2c_remove(struct platform_device *pdev)
{
struct xxx_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adap);
return 0;
}
const struct of_device_id xxx_ids[] = {
{.compatible = "xxx,i2c-adapter"},
};
struct platform_driver xxx_i2c_adap_drv = {
.probe = xxx_i2c_probe,
.remove = xxx_i2c_remove,
.driver = {
.name = "xxx-i2c-adaper",
.of_match_table = xxx_ids,
},
};
module_platform_driver(xxx_i2c_adap_drv);
在I2C adapter驱动中algo中的functionality回调函数返回设备支持的功能,这些功能的定义在uapi/linux/i2c.h中。
smbus_xfer这个函数用于向I2C设备发送数据。