w1_ds2408.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * w1_ds2408.c - w1 family 29 (DS2408) driver
  4. *
  5. * Copyright (c) 2010 Jean-Francois Dagenais <[email protected]>
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/moduleparam.h>
  10. #include <linux/device.h>
  11. #include <linux/types.h>
  12. #include <linux/delay.h>
  13. #include <linux/slab.h>
  14. #include <linux/w1.h>
  15. #define W1_FAMILY_DS2408 0x29
  16. #define W1_F29_RETRIES 3
  17. #define W1_F29_REG_LOGIG_STATE 0x88 /* R */
  18. #define W1_F29_REG_OUTPUT_LATCH_STATE 0x89 /* R */
  19. #define W1_F29_REG_ACTIVITY_LATCH_STATE 0x8A /* R */
  20. #define W1_F29_REG_COND_SEARCH_SELECT_MASK 0x8B /* RW */
  21. #define W1_F29_REG_COND_SEARCH_POL_SELECT 0x8C /* RW */
  22. #define W1_F29_REG_CONTROL_AND_STATUS 0x8D /* RW */
  23. #define W1_F29_FUNC_READ_PIO_REGS 0xF0
  24. #define W1_F29_FUNC_CHANN_ACCESS_READ 0xF5
  25. #define W1_F29_FUNC_CHANN_ACCESS_WRITE 0x5A
  26. /* also used to write the control/status reg (0x8D): */
  27. #define W1_F29_FUNC_WRITE_COND_SEARCH_REG 0xCC
  28. #define W1_F29_FUNC_RESET_ACTIVITY_LATCHES 0xC3
  29. #define W1_F29_SUCCESS_CONFIRM_BYTE 0xAA
  30. static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf)
  31. {
  32. u8 wrbuf[3];
  33. dev_dbg(&sl->dev,
  34. "Reading with slave: %p, reg addr: %0#4x, buff addr: %p",
  35. sl, (unsigned int)address, buf);
  36. if (!buf)
  37. return -EINVAL;
  38. mutex_lock(&sl->master->bus_mutex);
  39. dev_dbg(&sl->dev, "mutex locked");
  40. if (w1_reset_select_slave(sl)) {
  41. mutex_unlock(&sl->master->bus_mutex);
  42. return -EIO;
  43. }
  44. wrbuf[0] = W1_F29_FUNC_READ_PIO_REGS;
  45. wrbuf[1] = address;
  46. wrbuf[2] = 0;
  47. w1_write_block(sl->master, wrbuf, 3);
  48. *buf = w1_read_8(sl->master);
  49. mutex_unlock(&sl->master->bus_mutex);
  50. dev_dbg(&sl->dev, "mutex unlocked");
  51. return 1;
  52. }
  53. static ssize_t state_read(struct file *filp, struct kobject *kobj,
  54. struct bin_attribute *bin_attr, char *buf, loff_t off,
  55. size_t count)
  56. {
  57. dev_dbg(&kobj_to_w1_slave(kobj)->dev,
  58. "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
  59. bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
  60. if (count != 1 || off != 0)
  61. return -EFAULT;
  62. return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf);
  63. }
  64. static ssize_t output_read(struct file *filp, struct kobject *kobj,
  65. struct bin_attribute *bin_attr, char *buf,
  66. loff_t off, size_t count)
  67. {
  68. dev_dbg(&kobj_to_w1_slave(kobj)->dev,
  69. "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
  70. bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
  71. if (count != 1 || off != 0)
  72. return -EFAULT;
  73. return _read_reg(kobj_to_w1_slave(kobj),
  74. W1_F29_REG_OUTPUT_LATCH_STATE, buf);
  75. }
  76. static ssize_t activity_read(struct file *filp, struct kobject *kobj,
  77. struct bin_attribute *bin_attr, char *buf,
  78. loff_t off, size_t count)
  79. {
  80. dev_dbg(&kobj_to_w1_slave(kobj)->dev,
  81. "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
  82. bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
  83. if (count != 1 || off != 0)
  84. return -EFAULT;
  85. return _read_reg(kobj_to_w1_slave(kobj),
  86. W1_F29_REG_ACTIVITY_LATCH_STATE, buf);
  87. }
  88. static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj,
  89. struct bin_attribute *bin_attr, char *buf,
  90. loff_t off, size_t count)
  91. {
  92. dev_dbg(&kobj_to_w1_slave(kobj)->dev,
  93. "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p",
  94. bin_attr->attr.name, kobj, (unsigned int)off, count, buf);
  95. if (count != 1 || off != 0)
  96. return -EFAULT;
  97. return _read_reg(kobj_to_w1_slave(kobj),
  98. W1_F29_REG_COND_SEARCH_SELECT_MASK, buf);
  99. }
  100. static ssize_t cond_search_polarity_read(struct file *filp,
  101. struct kobject *kobj,
  102. struct bin_attribute *bin_attr,
  103. char *buf, loff_t off, size_t count)
  104. {
  105. if (count != 1 || off != 0)
  106. return -EFAULT;
  107. return _read_reg(kobj_to_w1_slave(kobj),
  108. W1_F29_REG_COND_SEARCH_POL_SELECT, buf);
  109. }
  110. static ssize_t status_control_read(struct file *filp, struct kobject *kobj,
  111. struct bin_attribute *bin_attr, char *buf,
  112. loff_t off, size_t count)
  113. {
  114. if (count != 1 || off != 0)
  115. return -EFAULT;
  116. return _read_reg(kobj_to_w1_slave(kobj),
  117. W1_F29_REG_CONTROL_AND_STATUS, buf);
  118. }
  119. #ifdef CONFIG_W1_SLAVE_DS2408_READBACK
  120. static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
  121. {
  122. u8 w1_buf[3];
  123. if (w1_reset_resume_command(sl->master))
  124. return false;
  125. w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
  126. w1_buf[1] = W1_F29_REG_OUTPUT_LATCH_STATE;
  127. w1_buf[2] = 0;
  128. w1_write_block(sl->master, w1_buf, 3);
  129. return (w1_read_8(sl->master) == expected);
  130. }
  131. #else
  132. static bool optional_read_back_valid(struct w1_slave *sl, u8 expected)
  133. {
  134. return true;
  135. }
  136. #endif
  137. static ssize_t output_write(struct file *filp, struct kobject *kobj,
  138. struct bin_attribute *bin_attr, char *buf,
  139. loff_t off, size_t count)
  140. {
  141. struct w1_slave *sl = kobj_to_w1_slave(kobj);
  142. u8 w1_buf[3];
  143. unsigned int retries = W1_F29_RETRIES;
  144. ssize_t bytes_written = -EIO;
  145. if (count != 1 || off != 0)
  146. return -EFAULT;
  147. dev_dbg(&sl->dev, "locking mutex for write_output");
  148. mutex_lock(&sl->master->bus_mutex);
  149. dev_dbg(&sl->dev, "mutex locked");
  150. if (w1_reset_select_slave(sl))
  151. goto out;
  152. do {
  153. w1_buf[0] = W1_F29_FUNC_CHANN_ACCESS_WRITE;
  154. w1_buf[1] = *buf;
  155. w1_buf[2] = ~(*buf);
  156. w1_write_block(sl->master, w1_buf, 3);
  157. if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE &&
  158. optional_read_back_valid(sl, *buf)) {
  159. bytes_written = 1;
  160. goto out;
  161. }
  162. if (w1_reset_resume_command(sl->master))
  163. goto out; /* unrecoverable error */
  164. /* try again, the slave is ready for a command */
  165. } while (--retries);
  166. out:
  167. mutex_unlock(&sl->master->bus_mutex);
  168. dev_dbg(&sl->dev, "%s, mutex unlocked retries:%d\n",
  169. (bytes_written > 0) ? "succeeded" : "error", retries);
  170. return bytes_written;
  171. }
  172. /**
  173. * Writing to the activity file resets the activity latches.
  174. */
  175. static ssize_t activity_write(struct file *filp, struct kobject *kobj,
  176. struct bin_attribute *bin_attr, char *buf,
  177. loff_t off, size_t count)
  178. {
  179. struct w1_slave *sl = kobj_to_w1_slave(kobj);
  180. unsigned int retries = W1_F29_RETRIES;
  181. if (count != 1 || off != 0)
  182. return -EFAULT;
  183. mutex_lock(&sl->master->bus_mutex);
  184. if (w1_reset_select_slave(sl))
  185. goto error;
  186. while (retries--) {
  187. w1_write_8(sl->master, W1_F29_FUNC_RESET_ACTIVITY_LATCHES);
  188. if (w1_read_8(sl->master) == W1_F29_SUCCESS_CONFIRM_BYTE) {
  189. mutex_unlock(&sl->master->bus_mutex);
  190. return 1;
  191. }
  192. if (w1_reset_resume_command(sl->master))
  193. goto error;
  194. }
  195. error:
  196. mutex_unlock(&sl->master->bus_mutex);
  197. return -EIO;
  198. }
  199. static ssize_t status_control_write(struct file *filp, struct kobject *kobj,
  200. struct bin_attribute *bin_attr, char *buf,
  201. loff_t off, size_t count)
  202. {
  203. struct w1_slave *sl = kobj_to_w1_slave(kobj);
  204. u8 w1_buf[4];
  205. unsigned int retries = W1_F29_RETRIES;
  206. if (count != 1 || off != 0)
  207. return -EFAULT;
  208. mutex_lock(&sl->master->bus_mutex);
  209. if (w1_reset_select_slave(sl))
  210. goto error;
  211. while (retries--) {
  212. w1_buf[0] = W1_F29_FUNC_WRITE_COND_SEARCH_REG;
  213. w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
  214. w1_buf[2] = 0;
  215. w1_buf[3] = *buf;
  216. w1_write_block(sl->master, w1_buf, 4);
  217. if (w1_reset_resume_command(sl->master))
  218. goto error;
  219. w1_buf[0] = W1_F29_FUNC_READ_PIO_REGS;
  220. w1_buf[1] = W1_F29_REG_CONTROL_AND_STATUS;
  221. w1_buf[2] = 0;
  222. w1_write_block(sl->master, w1_buf, 3);
  223. if (w1_read_8(sl->master) == *buf) {
  224. /* success! */
  225. mutex_unlock(&sl->master->bus_mutex);
  226. return 1;
  227. }
  228. }
  229. error:
  230. mutex_unlock(&sl->master->bus_mutex);
  231. return -EIO;
  232. }
  233. /*
  234. * This is a special sequence we must do to ensure the P0 output is not stuck
  235. * in test mode. This is described in rev 2 of the ds2408's datasheet
  236. * (http://datasheets.maximintegrated.com/en/ds/DS2408.pdf) under
  237. * "APPLICATION INFORMATION/Power-up timing".
  238. */
  239. static int w1_f29_disable_test_mode(struct w1_slave *sl)
  240. {
  241. int res;
  242. u8 magic[10] = {0x96, };
  243. u64 rn = le64_to_cpu(*((u64*)&sl->reg_num));
  244. memcpy(&magic[1], &rn, 8);
  245. magic[9] = 0x3C;
  246. mutex_lock(&sl->master->bus_mutex);
  247. res = w1_reset_bus(sl->master);
  248. if (res)
  249. goto out;
  250. w1_write_block(sl->master, magic, ARRAY_SIZE(magic));
  251. res = w1_reset_bus(sl->master);
  252. out:
  253. mutex_unlock(&sl->master->bus_mutex);
  254. return res;
  255. }
  256. static BIN_ATTR_RO(state, 1);
  257. static BIN_ATTR_RW(output, 1);
  258. static BIN_ATTR_RW(activity, 1);
  259. static BIN_ATTR_RO(cond_search_mask, 1);
  260. static BIN_ATTR_RO(cond_search_polarity, 1);
  261. static BIN_ATTR_RW(status_control, 1);
  262. static struct bin_attribute *w1_f29_bin_attrs[] = {
  263. &bin_attr_state,
  264. &bin_attr_output,
  265. &bin_attr_activity,
  266. &bin_attr_cond_search_mask,
  267. &bin_attr_cond_search_polarity,
  268. &bin_attr_status_control,
  269. NULL,
  270. };
  271. static const struct attribute_group w1_f29_group = {
  272. .bin_attrs = w1_f29_bin_attrs,
  273. };
  274. static const struct attribute_group *w1_f29_groups[] = {
  275. &w1_f29_group,
  276. NULL,
  277. };
  278. static const struct w1_family_ops w1_f29_fops = {
  279. .add_slave = w1_f29_disable_test_mode,
  280. .groups = w1_f29_groups,
  281. };
  282. static struct w1_family w1_family_29 = {
  283. .fid = W1_FAMILY_DS2408,
  284. .fops = &w1_f29_fops,
  285. };
  286. module_w1_family(w1_family_29);
  287. MODULE_AUTHOR("Jean-Francois Dagenais <[email protected]>");
  288. MODULE_DESCRIPTION("w1 family 29 driver for DS2408 8 Pin IO");
  289. MODULE_LICENSE("GPL");
  290. MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2408));