regmap-w1.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. * Register map access API - W1 (1-Wire) support
  3. *
  4. * Copyright (c) 2017 Radioavionica Corporation
  5. * Author: Alex A. Mihaylov <minimumlaw@rambler.ru>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License version 2 as
  9. * published by the Free Software Foundation
  10. */
  11. #include <linux/regmap.h>
  12. #include <linux/module.h>
  13. #include <linux/w1.h>
  14. #include "internal.h"
  15. #define W1_CMD_READ_DATA 0x69
  16. #define W1_CMD_WRITE_DATA 0x6C
  17. /*
  18. * 1-Wire slaves registers with addess 8 bit and data 8 bit
  19. */
  20. static int w1_reg_a8_v8_read(void *context, unsigned int reg, unsigned int *val)
  21. {
  22. struct device *dev = context;
  23. struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  24. int ret = 0;
  25. if (reg > 255)
  26. return -EINVAL;
  27. mutex_lock(&sl->master->bus_mutex);
  28. if (!w1_reset_select_slave(sl)) {
  29. w1_write_8(sl->master, W1_CMD_READ_DATA);
  30. w1_write_8(sl->master, reg);
  31. *val = w1_read_8(sl->master);
  32. } else {
  33. ret = -ENODEV;
  34. }
  35. mutex_unlock(&sl->master->bus_mutex);
  36. return ret;
  37. }
  38. static int w1_reg_a8_v8_write(void *context, unsigned int reg, unsigned int val)
  39. {
  40. struct device *dev = context;
  41. struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  42. int ret = 0;
  43. if (reg > 255)
  44. return -EINVAL;
  45. mutex_lock(&sl->master->bus_mutex);
  46. if (!w1_reset_select_slave(sl)) {
  47. w1_write_8(sl->master, W1_CMD_WRITE_DATA);
  48. w1_write_8(sl->master, reg);
  49. w1_write_8(sl->master, val);
  50. } else {
  51. ret = -ENODEV;
  52. }
  53. mutex_unlock(&sl->master->bus_mutex);
  54. return ret;
  55. }
  56. /*
  57. * 1-Wire slaves registers with addess 8 bit and data 16 bit
  58. */
  59. static int w1_reg_a8_v16_read(void *context, unsigned int reg,
  60. unsigned int *val)
  61. {
  62. struct device *dev = context;
  63. struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  64. int ret = 0;
  65. if (reg > 255)
  66. return -EINVAL;
  67. mutex_lock(&sl->master->bus_mutex);
  68. if (!w1_reset_select_slave(sl)) {
  69. w1_write_8(sl->master, W1_CMD_READ_DATA);
  70. w1_write_8(sl->master, reg);
  71. *val = w1_read_8(sl->master);
  72. *val |= w1_read_8(sl->master)<<8;
  73. } else {
  74. ret = -ENODEV;
  75. }
  76. mutex_unlock(&sl->master->bus_mutex);
  77. return ret;
  78. }
  79. static int w1_reg_a8_v16_write(void *context, unsigned int reg,
  80. unsigned int val)
  81. {
  82. struct device *dev = context;
  83. struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  84. int ret = 0;
  85. if (reg > 255)
  86. return -EINVAL;
  87. mutex_lock(&sl->master->bus_mutex);
  88. if (!w1_reset_select_slave(sl)) {
  89. w1_write_8(sl->master, W1_CMD_WRITE_DATA);
  90. w1_write_8(sl->master, reg);
  91. w1_write_8(sl->master, val & 0x00FF);
  92. w1_write_8(sl->master, val>>8 & 0x00FF);
  93. } else {
  94. ret = -ENODEV;
  95. }
  96. mutex_unlock(&sl->master->bus_mutex);
  97. return ret;
  98. }
  99. /*
  100. * 1-Wire slaves registers with addess 16 bit and data 16 bit
  101. */
  102. static int w1_reg_a16_v16_read(void *context, unsigned int reg,
  103. unsigned int *val)
  104. {
  105. struct device *dev = context;
  106. struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  107. int ret = 0;
  108. if (reg > 65535)
  109. return -EINVAL;
  110. mutex_lock(&sl->master->bus_mutex);
  111. if (!w1_reset_select_slave(sl)) {
  112. w1_write_8(sl->master, W1_CMD_READ_DATA);
  113. w1_write_8(sl->master, reg & 0x00FF);
  114. w1_write_8(sl->master, reg>>8 & 0x00FF);
  115. *val = w1_read_8(sl->master);
  116. *val |= w1_read_8(sl->master)<<8;
  117. } else {
  118. ret = -ENODEV;
  119. }
  120. mutex_unlock(&sl->master->bus_mutex);
  121. return ret;
  122. }
  123. static int w1_reg_a16_v16_write(void *context, unsigned int reg,
  124. unsigned int val)
  125. {
  126. struct device *dev = context;
  127. struct w1_slave *sl = container_of(dev, struct w1_slave, dev);
  128. int ret = 0;
  129. if (reg > 65535)
  130. return -EINVAL;
  131. mutex_lock(&sl->master->bus_mutex);
  132. if (!w1_reset_select_slave(sl)) {
  133. w1_write_8(sl->master, W1_CMD_WRITE_DATA);
  134. w1_write_8(sl->master, reg & 0x00FF);
  135. w1_write_8(sl->master, reg>>8 & 0x00FF);
  136. w1_write_8(sl->master, val & 0x00FF);
  137. w1_write_8(sl->master, val>>8 & 0x00FF);
  138. } else {
  139. ret = -ENODEV;
  140. }
  141. mutex_unlock(&sl->master->bus_mutex);
  142. return ret;
  143. }
  144. /*
  145. * Various types of supported bus addressing
  146. */
  147. static struct regmap_bus regmap_w1_bus_a8_v8 = {
  148. .reg_read = w1_reg_a8_v8_read,
  149. .reg_write = w1_reg_a8_v8_write,
  150. };
  151. static struct regmap_bus regmap_w1_bus_a8_v16 = {
  152. .reg_read = w1_reg_a8_v16_read,
  153. .reg_write = w1_reg_a8_v16_write,
  154. };
  155. static struct regmap_bus regmap_w1_bus_a16_v16 = {
  156. .reg_read = w1_reg_a16_v16_read,
  157. .reg_write = w1_reg_a16_v16_write,
  158. };
  159. static const struct regmap_bus *regmap_get_w1_bus(struct device *w1_dev,
  160. const struct regmap_config *config)
  161. {
  162. if (config->reg_bits == 8 && config->val_bits == 8)
  163. return &regmap_w1_bus_a8_v8;
  164. if (config->reg_bits == 8 && config->val_bits == 16)
  165. return &regmap_w1_bus_a8_v16;
  166. if (config->reg_bits == 16 && config->val_bits == 16)
  167. return &regmap_w1_bus_a16_v16;
  168. return ERR_PTR(-ENOTSUPP);
  169. }
  170. struct regmap *__regmap_init_w1(struct device *w1_dev,
  171. const struct regmap_config *config,
  172. struct lock_class_key *lock_key,
  173. const char *lock_name)
  174. {
  175. const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config);
  176. if (IS_ERR(bus))
  177. return ERR_CAST(bus);
  178. return __regmap_init(w1_dev, bus, w1_dev, config,
  179. lock_key, lock_name);
  180. return NULL;
  181. }
  182. EXPORT_SYMBOL_GPL(__regmap_init_w1);
  183. struct regmap *__devm_regmap_init_w1(struct device *w1_dev,
  184. const struct regmap_config *config,
  185. struct lock_class_key *lock_key,
  186. const char *lock_name)
  187. {
  188. const struct regmap_bus *bus = regmap_get_w1_bus(w1_dev, config);
  189. if (IS_ERR(bus))
  190. return ERR_CAST(bus);
  191. return __devm_regmap_init(w1_dev, bus, w1_dev, config,
  192. lock_key, lock_name);
  193. return NULL;
  194. }
  195. EXPORT_SYMBOL_GPL(__devm_regmap_init_w1);
  196. MODULE_LICENSE("GPL");