regmap-i2c.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Register map access API - I2C support
  3. *
  4. * Copyright 2011 Wolfson Microelectronics plc
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License version 2 as
  10. * published by the Free Software Foundation.
  11. */
  12. #include <linux/regmap.h>
  13. #include <linux/i2c.h>
  14. #include <linux/module.h>
  15. #include <linux/init.h>
  16. static int regmap_i2c_write(struct device *dev, const void *data, size_t count)
  17. {
  18. struct i2c_client *i2c = to_i2c_client(dev);
  19. int ret;
  20. ret = i2c_master_send(i2c, data, count);
  21. if (ret == count)
  22. return 0;
  23. else if (ret < 0)
  24. return ret;
  25. else
  26. return -EIO;
  27. }
  28. static int regmap_i2c_gather_write(struct device *dev,
  29. const void *reg, size_t reg_size,
  30. const void *val, size_t val_size)
  31. {
  32. struct i2c_client *i2c = to_i2c_client(dev);
  33. struct i2c_msg xfer[2];
  34. int ret;
  35. /* If the I2C controller can't do a gather tell the core, it
  36. * will substitute in a linear write for us.
  37. */
  38. if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_PROTOCOL_MANGLING))
  39. return -ENOTSUPP;
  40. xfer[0].addr = i2c->addr;
  41. xfer[0].flags = 0;
  42. xfer[0].len = reg_size;
  43. xfer[0].buf = (void *)reg;
  44. xfer[1].addr = i2c->addr;
  45. xfer[1].flags = I2C_M_NOSTART;
  46. xfer[1].len = val_size;
  47. xfer[1].buf = (void *)val;
  48. ret = i2c_transfer(i2c->adapter, xfer, 2);
  49. if (ret == 2)
  50. return 0;
  51. if (ret < 0)
  52. return ret;
  53. else
  54. return -EIO;
  55. }
  56. static int regmap_i2c_read(struct device *dev,
  57. const void *reg, size_t reg_size,
  58. void *val, size_t val_size)
  59. {
  60. struct i2c_client *i2c = to_i2c_client(dev);
  61. struct i2c_msg xfer[2];
  62. int ret;
  63. xfer[0].addr = i2c->addr;
  64. xfer[0].flags = 0;
  65. xfer[0].len = reg_size;
  66. xfer[0].buf = (void *)reg;
  67. xfer[1].addr = i2c->addr;
  68. xfer[1].flags = I2C_M_RD;
  69. xfer[1].len = val_size;
  70. xfer[1].buf = val;
  71. ret = i2c_transfer(i2c->adapter, xfer, 2);
  72. if (ret == 2)
  73. return 0;
  74. else if (ret < 0)
  75. return ret;
  76. else
  77. return -EIO;
  78. }
  79. static struct regmap_bus regmap_i2c = {
  80. .write = regmap_i2c_write,
  81. .gather_write = regmap_i2c_gather_write,
  82. .read = regmap_i2c_read,
  83. };
  84. /**
  85. * regmap_init_i2c(): Initialise register map
  86. *
  87. * @i2c: Device that will be interacted with
  88. * @config: Configuration for register map
  89. *
  90. * The return value will be an ERR_PTR() on error or a valid pointer to
  91. * a struct regmap.
  92. */
  93. struct regmap *regmap_init_i2c(struct i2c_client *i2c,
  94. const struct regmap_config *config)
  95. {
  96. return regmap_init(&i2c->dev, &regmap_i2c, config);
  97. }
  98. EXPORT_SYMBOL_GPL(regmap_init_i2c);
  99. /**
  100. * devm_regmap_init_i2c(): Initialise managed register map
  101. *
  102. * @i2c: Device that will be interacted with
  103. * @config: Configuration for register map
  104. *
  105. * The return value will be an ERR_PTR() on error or a valid pointer
  106. * to a struct regmap. The regmap will be automatically freed by the
  107. * device management code.
  108. */
  109. struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
  110. const struct regmap_config *config)
  111. {
  112. return devm_regmap_init(&i2c->dev, &regmap_i2c, config);
  113. }
  114. EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
  115. MODULE_LICENSE("GPL");