Monday, August 17, 2015

I2C application Driver



For understanding I2C application driver(Slave only), lets discuss with sample open source driver. The post explains only about I2C Interface related information and how it is implemented on MAX8952 driver.
Consider Maxim 8952 Step-down Regulator module needs to be connected to our embedded system. Assume this driver is not available in Linux kernel.
As per the Datasheet, I2C Interface can be used to communicate with the device. Refer the block diagram of MAX8952 device.
  • An I2C-compatible, 2 wire serial interface controls the step down converter output voltage, ramp rate, operating mode and synchronization.
  • A Bus master initiates communication with slave device(Here MAX8952) by issuing a START condition followed by slave address.
  • Only I2C byte read/write operations done on device.
The application driver basic structure is follows
  1. Fill the i2c_driver
322 static struct i2c_driver max8952_pmic_driver = {
323         .probe          = max8952_pmic_probe,
324         .driver         = {
325                 .name   = "max8952",
326                 .of_match_table = of_match_ptr(max8952_dt_match),
327         },
328         .id_table       = max8952_ids,
329 };
2. Check whether the adapter supports the required functionality
192 static int max8952_pmic_probe(struct i2c_client *client,
193                 const struct i2c_device_id *i2c_id)
194 {
195         struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
...
211         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
212                 return -EIO;
3. Implement Read/Write functions.
 57 static int max8952_read_reg(struct max8952_data *max8952, u8 reg)
 58 {
 59         int ret = i2c_smbus_read_byte_data(max8952->client, reg);
 60 
 61         if (ret > 0)
 62                 ret &= 0xff;
 63 
 64         return ret;
 65 }
 66 
 67 static int max8952_write_reg(struct max8952_data *max8952,
 68                 u8 reg, u8 value)
 69 {
 70         return i2c_smbus_write_byte_data(max8952->client, reg, value);
 71 }
 72 
4. Register/Remove I2C driver
331 static int __init max8952_pmic_init(void)
332 {
333         return i2c_add_driver(&max8952_pmic_driver); <-- Driver Register at Init
334 }
335 subsys_initcall(max8952_pmic_init); <==== Init call mechanism which ensures early call of this driver 
336 
337 static void __exit max8952_pmic_exit(void)
338 {
339         i2c_del_driver(&max8952_pmic_driver); <-- Driver Removal at Cleanup 
340 }
341 module_exit(max8952_pmic_exit); <=== cleanup module macro

Note :: Some drivers uses  module_i2c_driver() macro instead of subsys_initcall(). If the driver is loadable then there is no need of init call mechanism. module_i2c_driver() will expands to init module and cleanup module for i2c driver. Refer the following link for sample driver.

http://lxr.free-electrons.com/source/drivers/input/keyboard/qt1070.c#L277

References

http://lxr.free-electrons.com/source/drivers/regulator/max8952.c


http://www.maximintegrated.com/en/products/power/switching-regulators/MAX8952.html/tb_tab0






1 comment: