regmap-i2c.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  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. static int regmap_smbus_byte_reg_read(void *context, unsigned int reg,
  16. unsigned int *val)
  17. {
  18. struct device *dev = context;
  19. struct i2c_client *i2c = to_i2c_client(dev);
  20. int ret;
  21. if (reg > 0xff)
  22. return -EINVAL;
  23. ret = i2c_smbus_read_byte_data(i2c, reg);
  24. if (ret < 0)
  25. return ret;
  26. *val = ret;
  27. return 0;
  28. }
  29. static int regmap_smbus_byte_reg_write(void *context, unsigned int reg,
  30. unsigned int val)
  31. {
  32. struct device *dev = context;
  33. struct i2c_client *i2c = to_i2c_client(dev);
  34. if (val > 0xff || reg > 0xff)
  35. return -EINVAL;
  36. return i2c_smbus_write_byte_data(i2c, reg, val);
  37. }
  38. static struct regmap_bus regmap_smbus_byte = {
  39. .reg_write = regmap_smbus_byte_reg_write,
  40. .reg_read = regmap_smbus_byte_reg_read,
  41. };
  42. static int regmap_smbus_word_reg_read(void *context, unsigned int reg,
  43. unsigned int *val)
  44. {
  45. struct device *dev = context;
  46. struct i2c_client *i2c = to_i2c_client(dev);
  47. int ret;
  48. if (reg > 0xff)
  49. return -EINVAL;
  50. ret = i2c_smbus_read_word_data(i2c, reg);
  51. if (ret < 0)
  52. return ret;
  53. *val = ret;
  54. return 0;
  55. }
  56. static int regmap_smbus_word_reg_write(void *context, unsigned int reg,
  57. unsigned int val)
  58. {
  59. struct device *dev = context;
  60. struct i2c_client *i2c = to_i2c_client(dev);
  61. if (val > 0xffff || reg > 0xff)
  62. return -EINVAL;
  63. return i2c_smbus_write_word_data(i2c, reg, val);
  64. }
  65. static struct regmap_bus regmap_smbus_word = {
  66. .reg_write = regmap_smbus_word_reg_write,
  67. .reg_read = regmap_smbus_word_reg_read,
  68. };
  69. static int regmap_i2c_write(void *context, const void *data, size_t count)
  70. {
  71. struct device *dev = context;
  72. struct i2c_client *i2c = to_i2c_client(dev);
  73. int ret;
  74. ret = i2c_master_send(i2c, data, count);
  75. if (ret == count)
  76. return 0;
  77. else if (ret < 0)
  78. return ret;
  79. else
  80. return -EIO;
  81. }
  82. static int regmap_i2c_gather_write(void *context,
  83. const void *reg, size_t reg_size,
  84. const void *val, size_t val_size)
  85. {
  86. struct device *dev = context;
  87. struct i2c_client *i2c = to_i2c_client(dev);
  88. struct i2c_msg xfer[2];
  89. int ret;
  90. /* If the I2C controller can't do a gather tell the core, it
  91. * will substitute in a linear write for us.
  92. */
  93. if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_NOSTART))
  94. return -ENOTSUPP;
  95. xfer[0].addr = i2c->addr;
  96. xfer[0].flags = 0;
  97. xfer[0].len = reg_size;
  98. xfer[0].buf = (void *)reg;
  99. xfer[1].addr = i2c->addr;
  100. xfer[1].flags = I2C_M_NOSTART;
  101. xfer[1].len = val_size;
  102. xfer[1].buf = (void *)val;
  103. ret = i2c_transfer(i2c->adapter, xfer, 2);
  104. if (ret == 2)
  105. return 0;
  106. if (ret < 0)
  107. return ret;
  108. else
  109. return -EIO;
  110. }
  111. static int regmap_i2c_read(void *context,
  112. const void *reg, size_t reg_size,
  113. void *val, size_t val_size)
  114. {
  115. struct device *dev = context;
  116. struct i2c_client *i2c = to_i2c_client(dev);
  117. struct i2c_msg xfer[2];
  118. int ret;
  119. xfer[0].addr = i2c->addr;
  120. xfer[0].flags = 0;
  121. xfer[0].len = reg_size;
  122. xfer[0].buf = (void *)reg;
  123. xfer[1].addr = i2c->addr;
  124. xfer[1].flags = I2C_M_RD;
  125. xfer[1].len = val_size;
  126. xfer[1].buf = val;
  127. ret = i2c_transfer(i2c->adapter, xfer, 2);
  128. if (ret == 2)
  129. return 0;
  130. else if (ret < 0)
  131. return ret;
  132. else
  133. return -EIO;
  134. }
  135. static struct regmap_bus regmap_i2c = {
  136. .write = regmap_i2c_write,
  137. .gather_write = regmap_i2c_gather_write,
  138. .read = regmap_i2c_read,
  139. };
  140. static const struct regmap_bus *regmap_get_i2c_bus(struct i2c_client *i2c,
  141. const struct regmap_config *config)
  142. {
  143. if (i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C))
  144. return &regmap_i2c;
  145. else if (config->val_bits == 16 && config->reg_bits == 8 &&
  146. i2c_check_functionality(i2c->adapter,
  147. I2C_FUNC_SMBUS_WORD_DATA))
  148. return &regmap_smbus_word;
  149. else if (config->val_bits == 8 && config->reg_bits == 8 &&
  150. i2c_check_functionality(i2c->adapter,
  151. I2C_FUNC_SMBUS_BYTE_DATA))
  152. return &regmap_smbus_byte;
  153. return ERR_PTR(-ENOTSUPP);
  154. }
  155. /**
  156. * regmap_init_i2c(): Initialise register map
  157. *
  158. * @i2c: Device that will be interacted with
  159. * @config: Configuration for register map
  160. *
  161. * The return value will be an ERR_PTR() on error or a valid pointer to
  162. * a struct regmap.
  163. */
  164. struct regmap *regmap_init_i2c(struct i2c_client *i2c,
  165. const struct regmap_config *config)
  166. {
  167. const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
  168. if (IS_ERR(bus))
  169. return ERR_CAST(bus);
  170. return regmap_init(&i2c->dev, bus, &i2c->dev, config);
  171. }
  172. EXPORT_SYMBOL_GPL(regmap_init_i2c);
  173. /**
  174. * devm_regmap_init_i2c(): Initialise managed register map
  175. *
  176. * @i2c: Device that will be interacted with
  177. * @config: Configuration for register map
  178. *
  179. * The return value will be an ERR_PTR() on error or a valid pointer
  180. * to a struct regmap. The regmap will be automatically freed by the
  181. * device management code.
  182. */
  183. struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c,
  184. const struct regmap_config *config)
  185. {
  186. const struct regmap_bus *bus = regmap_get_i2c_bus(i2c, config);
  187. if (IS_ERR(bus))
  188. return ERR_CAST(bus);
  189. return devm_regmap_init(&i2c->dev, bus, &i2c->dev, config);
  190. }
  191. EXPORT_SYMBOL_GPL(devm_regmap_init_i2c);
  192. MODULE_LICENSE("GPL");