w1_therm.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. /*
  2. * w1_therm.c
  3. *
  4. * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
  5. *
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the therms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include <asm/types.h>
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/moduleparam.h>
  25. #include <linux/sched.h>
  26. #include <linux/device.h>
  27. #include <linux/types.h>
  28. #include <linux/slab.h>
  29. #include <linux/delay.h>
  30. #include <linux/hwmon.h>
  31. #include <linux/w1.h>
  32. #define W1_THERM_DS18S20 0x10
  33. #define W1_THERM_DS1822 0x22
  34. #define W1_THERM_DS18B20 0x28
  35. #define W1_THERM_DS1825 0x3B
  36. #define W1_THERM_DS28EA00 0x42
  37. /* Allow the strong pullup to be disabled, but default to enabled.
  38. * If it was disabled a parasite powered device might not get the require
  39. * current to do a temperature conversion. If it is enabled parasite powered
  40. * devices have a better chance of getting the current required.
  41. * In case the parasite power-detection is not working (seems to be the case
  42. * for some DS18S20) the strong pullup can also be forced, regardless of the
  43. * power state of the devices.
  44. *
  45. * Summary of options:
  46. * - strong_pullup = 0 Disable strong pullup completely
  47. * - strong_pullup = 1 Enable automatic strong pullup detection
  48. * - strong_pullup = 2 Force strong pullup
  49. */
  50. static int w1_strong_pullup = 1;
  51. module_param_named(strong_pullup, w1_strong_pullup, int, 0);
  52. struct w1_therm_family_data {
  53. uint8_t rom[9];
  54. atomic_t refcnt;
  55. };
  56. struct therm_info {
  57. u8 rom[9];
  58. u8 crc;
  59. u8 verdict;
  60. };
  61. /* return the address of the refcnt in the family data */
  62. #define THERM_REFCNT(family_data) \
  63. (&((struct w1_therm_family_data *)family_data)->refcnt)
  64. static int w1_therm_add_slave(struct w1_slave *sl)
  65. {
  66. sl->family_data = kzalloc(sizeof(struct w1_therm_family_data),
  67. GFP_KERNEL);
  68. if (!sl->family_data)
  69. return -ENOMEM;
  70. atomic_set(THERM_REFCNT(sl->family_data), 1);
  71. return 0;
  72. }
  73. static void w1_therm_remove_slave(struct w1_slave *sl)
  74. {
  75. int refcnt = atomic_sub_return(1, THERM_REFCNT(sl->family_data));
  76. while (refcnt) {
  77. msleep(1000);
  78. refcnt = atomic_read(THERM_REFCNT(sl->family_data));
  79. }
  80. kfree(sl->family_data);
  81. sl->family_data = NULL;
  82. }
  83. static ssize_t w1_slave_show(struct device *device,
  84. struct device_attribute *attr, char *buf);
  85. static ssize_t w1_slave_store(struct device *device,
  86. struct device_attribute *attr, const char *buf, size_t size);
  87. static ssize_t w1_seq_show(struct device *device,
  88. struct device_attribute *attr, char *buf);
  89. static DEVICE_ATTR_RW(w1_slave);
  90. static DEVICE_ATTR_RO(w1_seq);
  91. static struct attribute *w1_therm_attrs[] = {
  92. &dev_attr_w1_slave.attr,
  93. NULL,
  94. };
  95. static struct attribute *w1_ds28ea00_attrs[] = {
  96. &dev_attr_w1_slave.attr,
  97. &dev_attr_w1_seq.attr,
  98. NULL,
  99. };
  100. ATTRIBUTE_GROUPS(w1_therm);
  101. ATTRIBUTE_GROUPS(w1_ds28ea00);
  102. #if IS_REACHABLE(CONFIG_HWMON)
  103. static int w1_read_temp(struct device *dev, u32 attr, int channel,
  104. long *val);
  105. static umode_t w1_is_visible(const void *_data, enum hwmon_sensor_types type,
  106. u32 attr, int channel)
  107. {
  108. return attr == hwmon_temp_input ? 0444 : 0;
  109. }
  110. static int w1_read(struct device *dev, enum hwmon_sensor_types type,
  111. u32 attr, int channel, long *val)
  112. {
  113. switch (type) {
  114. case hwmon_temp:
  115. return w1_read_temp(dev, attr, channel, val);
  116. default:
  117. return -EOPNOTSUPP;
  118. }
  119. }
  120. static const u32 w1_temp_config[] = {
  121. HWMON_T_INPUT,
  122. 0
  123. };
  124. static const struct hwmon_channel_info w1_temp = {
  125. .type = hwmon_temp,
  126. .config = w1_temp_config,
  127. };
  128. static const struct hwmon_channel_info *w1_info[] = {
  129. &w1_temp,
  130. NULL
  131. };
  132. static const struct hwmon_ops w1_hwmon_ops = {
  133. .is_visible = w1_is_visible,
  134. .read = w1_read,
  135. };
  136. static const struct hwmon_chip_info w1_chip_info = {
  137. .ops = &w1_hwmon_ops,
  138. .info = w1_info,
  139. };
  140. #define W1_CHIPINFO (&w1_chip_info)
  141. #else
  142. #define W1_CHIPINFO NULL
  143. #endif
  144. static struct w1_family_ops w1_therm_fops = {
  145. .add_slave = w1_therm_add_slave,
  146. .remove_slave = w1_therm_remove_slave,
  147. .groups = w1_therm_groups,
  148. .chip_info = W1_CHIPINFO,
  149. };
  150. static struct w1_family_ops w1_ds28ea00_fops = {
  151. .add_slave = w1_therm_add_slave,
  152. .remove_slave = w1_therm_remove_slave,
  153. .groups = w1_ds28ea00_groups,
  154. .chip_info = W1_CHIPINFO,
  155. };
  156. static struct w1_family w1_therm_family_DS18S20 = {
  157. .fid = W1_THERM_DS18S20,
  158. .fops = &w1_therm_fops,
  159. };
  160. static struct w1_family w1_therm_family_DS18B20 = {
  161. .fid = W1_THERM_DS18B20,
  162. .fops = &w1_therm_fops,
  163. };
  164. static struct w1_family w1_therm_family_DS1822 = {
  165. .fid = W1_THERM_DS1822,
  166. .fops = &w1_therm_fops,
  167. };
  168. static struct w1_family w1_therm_family_DS28EA00 = {
  169. .fid = W1_THERM_DS28EA00,
  170. .fops = &w1_ds28ea00_fops,
  171. };
  172. static struct w1_family w1_therm_family_DS1825 = {
  173. .fid = W1_THERM_DS1825,
  174. .fops = &w1_therm_fops,
  175. };
  176. struct w1_therm_family_converter {
  177. u8 broken;
  178. u16 reserved;
  179. struct w1_family *f;
  180. int (*convert)(u8 rom[9]);
  181. int (*precision)(struct device *device, int val);
  182. int (*eeprom)(struct device *device);
  183. };
  184. /* write configuration to eeprom */
  185. static inline int w1_therm_eeprom(struct device *device);
  186. /* Set precision for conversion */
  187. static inline int w1_DS18B20_precision(struct device *device, int val);
  188. static inline int w1_DS18S20_precision(struct device *device, int val);
  189. /* The return value is millidegrees Centigrade. */
  190. static inline int w1_DS18B20_convert_temp(u8 rom[9]);
  191. static inline int w1_DS18S20_convert_temp(u8 rom[9]);
  192. static struct w1_therm_family_converter w1_therm_families[] = {
  193. {
  194. .f = &w1_therm_family_DS18S20,
  195. .convert = w1_DS18S20_convert_temp,
  196. .precision = w1_DS18S20_precision,
  197. .eeprom = w1_therm_eeprom
  198. },
  199. {
  200. .f = &w1_therm_family_DS1822,
  201. .convert = w1_DS18B20_convert_temp,
  202. .precision = w1_DS18S20_precision,
  203. .eeprom = w1_therm_eeprom
  204. },
  205. {
  206. .f = &w1_therm_family_DS18B20,
  207. .convert = w1_DS18B20_convert_temp,
  208. .precision = w1_DS18B20_precision,
  209. .eeprom = w1_therm_eeprom
  210. },
  211. {
  212. .f = &w1_therm_family_DS28EA00,
  213. .convert = w1_DS18B20_convert_temp,
  214. .precision = w1_DS18S20_precision,
  215. .eeprom = w1_therm_eeprom
  216. },
  217. {
  218. .f = &w1_therm_family_DS1825,
  219. .convert = w1_DS18B20_convert_temp,
  220. .precision = w1_DS18S20_precision,
  221. .eeprom = w1_therm_eeprom
  222. }
  223. };
  224. static inline int w1_therm_eeprom(struct device *device)
  225. {
  226. struct w1_slave *sl = dev_to_w1_slave(device);
  227. struct w1_master *dev = sl->master;
  228. u8 rom[9], external_power;
  229. int ret, max_trying = 10;
  230. u8 *family_data = sl->family_data;
  231. if (!sl->family_data) {
  232. ret = -ENODEV;
  233. goto error;
  234. }
  235. /* prevent the slave from going away in sleep */
  236. atomic_inc(THERM_REFCNT(family_data));
  237. ret = mutex_lock_interruptible(&dev->bus_mutex);
  238. if (ret != 0)
  239. goto dec_refcnt;
  240. memset(rom, 0, sizeof(rom));
  241. while (max_trying--) {
  242. if (!w1_reset_select_slave(sl)) {
  243. unsigned int tm = 10;
  244. unsigned long sleep_rem;
  245. /* check if in parasite mode */
  246. w1_write_8(dev, W1_READ_PSUPPLY);
  247. external_power = w1_read_8(dev);
  248. if (w1_reset_select_slave(sl))
  249. continue;
  250. /* 10ms strong pullup/delay after the copy command */
  251. if (w1_strong_pullup == 2 ||
  252. (!external_power && w1_strong_pullup))
  253. w1_next_pullup(dev, tm);
  254. w1_write_8(dev, W1_COPY_SCRATCHPAD);
  255. if (external_power) {
  256. mutex_unlock(&dev->bus_mutex);
  257. sleep_rem = msleep_interruptible(tm);
  258. if (sleep_rem != 0) {
  259. ret = -EINTR;
  260. goto dec_refcnt;
  261. }
  262. ret = mutex_lock_interruptible(&dev->bus_mutex);
  263. if (ret != 0)
  264. goto dec_refcnt;
  265. } else if (!w1_strong_pullup) {
  266. sleep_rem = msleep_interruptible(tm);
  267. if (sleep_rem != 0) {
  268. ret = -EINTR;
  269. goto mt_unlock;
  270. }
  271. }
  272. break;
  273. }
  274. }
  275. mt_unlock:
  276. mutex_unlock(&dev->bus_mutex);
  277. dec_refcnt:
  278. atomic_dec(THERM_REFCNT(family_data));
  279. error:
  280. return ret;
  281. }
  282. /* DS18S20 does not feature configuration register */
  283. static inline int w1_DS18S20_precision(struct device *device, int val)
  284. {
  285. return 0;
  286. }
  287. static inline int w1_DS18B20_precision(struct device *device, int val)
  288. {
  289. struct w1_slave *sl = dev_to_w1_slave(device);
  290. struct w1_master *dev = sl->master;
  291. u8 rom[9], crc;
  292. int ret, max_trying = 10;
  293. u8 *family_data = sl->family_data;
  294. uint8_t precision_bits;
  295. uint8_t mask = 0x60;
  296. if (val > 12 || val < 9) {
  297. pr_warn("Unsupported precision\n");
  298. ret = -EINVAL;
  299. goto error;
  300. }
  301. if (!sl->family_data) {
  302. ret = -ENODEV;
  303. goto error;
  304. }
  305. /* prevent the slave from going away in sleep */
  306. atomic_inc(THERM_REFCNT(family_data));
  307. ret = mutex_lock_interruptible(&dev->bus_mutex);
  308. if (ret != 0)
  309. goto dec_refcnt;
  310. memset(rom, 0, sizeof(rom));
  311. /* translate precision to bitmask (see datasheet page 9) */
  312. switch (val) {
  313. case 9:
  314. precision_bits = 0x00;
  315. break;
  316. case 10:
  317. precision_bits = 0x20;
  318. break;
  319. case 11:
  320. precision_bits = 0x40;
  321. break;
  322. case 12:
  323. default:
  324. precision_bits = 0x60;
  325. break;
  326. }
  327. while (max_trying--) {
  328. crc = 0;
  329. if (!w1_reset_select_slave(sl)) {
  330. int count = 0;
  331. /* read values to only alter precision bits */
  332. w1_write_8(dev, W1_READ_SCRATCHPAD);
  333. count = w1_read_block(dev, rom, 9);
  334. if (count != 9)
  335. dev_warn(device, "w1_read_block() returned %u instead of 9.\n", count);
  336. crc = w1_calc_crc8(rom, 8);
  337. if (rom[8] == crc) {
  338. rom[4] = (rom[4] & ~mask) | (precision_bits & mask);
  339. if (!w1_reset_select_slave(sl)) {
  340. w1_write_8(dev, W1_WRITE_SCRATCHPAD);
  341. w1_write_8(dev, rom[2]);
  342. w1_write_8(dev, rom[3]);
  343. w1_write_8(dev, rom[4]);
  344. break;
  345. }
  346. }
  347. }
  348. }
  349. mutex_unlock(&dev->bus_mutex);
  350. dec_refcnt:
  351. atomic_dec(THERM_REFCNT(family_data));
  352. error:
  353. return ret;
  354. }
  355. static inline int w1_DS18B20_convert_temp(u8 rom[9])
  356. {
  357. s16 t = le16_to_cpup((__le16 *)rom);
  358. return t*1000/16;
  359. }
  360. static inline int w1_DS18S20_convert_temp(u8 rom[9])
  361. {
  362. int t, h;
  363. if (!rom[7])
  364. return 0;
  365. if (rom[1] == 0)
  366. t = ((s32)rom[0] >> 1)*1000;
  367. else
  368. t = 1000*(-1*(s32)(0x100-rom[0]) >> 1);
  369. t -= 250;
  370. h = 1000*((s32)rom[7] - (s32)rom[6]);
  371. h /= (s32)rom[7];
  372. t += h;
  373. return t;
  374. }
  375. static inline int w1_convert_temp(u8 rom[9], u8 fid)
  376. {
  377. int i;
  378. for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i)
  379. if (w1_therm_families[i].f->fid == fid)
  380. return w1_therm_families[i].convert(rom);
  381. return 0;
  382. }
  383. static ssize_t w1_slave_store(struct device *device,
  384. struct device_attribute *attr, const char *buf,
  385. size_t size)
  386. {
  387. int val, ret;
  388. struct w1_slave *sl = dev_to_w1_slave(device);
  389. int i;
  390. ret = kstrtoint(buf, 0, &val);
  391. if (ret)
  392. return ret;
  393. for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
  394. if (w1_therm_families[i].f->fid == sl->family->fid) {
  395. /* zero value indicates to write current configuration to eeprom */
  396. if (val == 0)
  397. ret = w1_therm_families[i].eeprom(device);
  398. else
  399. ret = w1_therm_families[i].precision(device, val);
  400. break;
  401. }
  402. }
  403. return ret ? : size;
  404. }
  405. static ssize_t read_therm(struct device *device,
  406. struct w1_slave *sl, struct therm_info *info)
  407. {
  408. struct w1_master *dev = sl->master;
  409. u8 external_power;
  410. int ret, max_trying = 10;
  411. u8 *family_data = sl->family_data;
  412. if (!family_data) {
  413. ret = -ENODEV;
  414. goto error;
  415. }
  416. /* prevent the slave from going away in sleep */
  417. atomic_inc(THERM_REFCNT(family_data));
  418. ret = mutex_lock_interruptible(&dev->bus_mutex);
  419. if (ret != 0)
  420. goto dec_refcnt;
  421. memset(info->rom, 0, sizeof(info->rom));
  422. while (max_trying--) {
  423. info->verdict = 0;
  424. info->crc = 0;
  425. if (!w1_reset_select_slave(sl)) {
  426. int count = 0;
  427. unsigned int tm = 750;
  428. unsigned long sleep_rem;
  429. w1_write_8(dev, W1_READ_PSUPPLY);
  430. external_power = w1_read_8(dev);
  431. if (w1_reset_select_slave(sl))
  432. continue;
  433. /* 750ms strong pullup (or delay) after the convert */
  434. if (w1_strong_pullup == 2 ||
  435. (!external_power && w1_strong_pullup))
  436. w1_next_pullup(dev, tm);
  437. w1_write_8(dev, W1_CONVERT_TEMP);
  438. if (external_power) {
  439. mutex_unlock(&dev->bus_mutex);
  440. sleep_rem = msleep_interruptible(tm);
  441. if (sleep_rem != 0) {
  442. ret = -EINTR;
  443. goto dec_refcnt;
  444. }
  445. ret = mutex_lock_interruptible(&dev->bus_mutex);
  446. if (ret != 0)
  447. goto dec_refcnt;
  448. } else if (!w1_strong_pullup) {
  449. sleep_rem = msleep_interruptible(tm);
  450. if (sleep_rem != 0) {
  451. ret = -EINTR;
  452. goto mt_unlock;
  453. }
  454. }
  455. if (!w1_reset_select_slave(sl)) {
  456. w1_write_8(dev, W1_READ_SCRATCHPAD);
  457. count = w1_read_block(dev, info->rom, 9);
  458. if (count != 9) {
  459. dev_warn(device, "w1_read_block() "
  460. "returned %u instead of 9.\n",
  461. count);
  462. }
  463. info->crc = w1_calc_crc8(info->rom, 8);
  464. if (info->rom[8] == info->crc)
  465. info->verdict = 1;
  466. }
  467. }
  468. if (info->verdict)
  469. break;
  470. }
  471. mt_unlock:
  472. mutex_unlock(&dev->bus_mutex);
  473. dec_refcnt:
  474. atomic_dec(THERM_REFCNT(family_data));
  475. error:
  476. return ret;
  477. }
  478. static ssize_t w1_slave_show(struct device *device,
  479. struct device_attribute *attr, char *buf)
  480. {
  481. struct w1_slave *sl = dev_to_w1_slave(device);
  482. struct therm_info info;
  483. u8 *family_data = sl->family_data;
  484. int ret, i;
  485. ssize_t c = PAGE_SIZE;
  486. u8 fid = sl->family->fid;
  487. ret = read_therm(device, sl, &info);
  488. if (ret)
  489. return ret;
  490. for (i = 0; i < 9; ++i)
  491. c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ", info.rom[i]);
  492. c -= snprintf(buf + PAGE_SIZE - c, c, ": crc=%02x %s\n",
  493. info.crc, (info.verdict) ? "YES" : "NO");
  494. if (info.verdict)
  495. memcpy(family_data, info.rom, sizeof(info.rom));
  496. else
  497. dev_warn(device, "Read failed CRC check\n");
  498. for (i = 0; i < 9; ++i)
  499. c -= snprintf(buf + PAGE_SIZE - c, c, "%02x ",
  500. ((u8 *)family_data)[i]);
  501. c -= snprintf(buf + PAGE_SIZE - c, c, "t=%d\n",
  502. w1_convert_temp(info.rom, fid));
  503. ret = PAGE_SIZE - c;
  504. return ret;
  505. }
  506. #if IS_REACHABLE(CONFIG_HWMON)
  507. static int w1_read_temp(struct device *device, u32 attr, int channel,
  508. long *val)
  509. {
  510. struct w1_slave *sl = dev_get_drvdata(device);
  511. struct therm_info info;
  512. u8 fid = sl->family->fid;
  513. int ret;
  514. switch (attr) {
  515. case hwmon_temp_input:
  516. ret = read_therm(device, sl, &info);
  517. if (ret)
  518. return ret;
  519. if (!info.verdict) {
  520. ret = -EIO;
  521. return ret;
  522. }
  523. *val = w1_convert_temp(info.rom, fid);
  524. ret = 0;
  525. break;
  526. default:
  527. ret = -EOPNOTSUPP;
  528. break;
  529. }
  530. return ret;
  531. }
  532. #endif
  533. #define W1_42_CHAIN 0x99
  534. #define W1_42_CHAIN_OFF 0x3C
  535. #define W1_42_CHAIN_OFF_INV 0xC3
  536. #define W1_42_CHAIN_ON 0x5A
  537. #define W1_42_CHAIN_ON_INV 0xA5
  538. #define W1_42_CHAIN_DONE 0x96
  539. #define W1_42_CHAIN_DONE_INV 0x69
  540. #define W1_42_COND_READ 0x0F
  541. #define W1_42_SUCCESS_CONFIRM_BYTE 0xAA
  542. #define W1_42_FINISHED_BYTE 0xFF
  543. static ssize_t w1_seq_show(struct device *device,
  544. struct device_attribute *attr, char *buf)
  545. {
  546. struct w1_slave *sl = dev_to_w1_slave(device);
  547. ssize_t c = PAGE_SIZE;
  548. int rv;
  549. int i;
  550. u8 ack;
  551. u64 rn;
  552. struct w1_reg_num *reg_num;
  553. int seq = 0;
  554. mutex_lock(&sl->master->bus_mutex);
  555. /* Place all devices in CHAIN state */
  556. if (w1_reset_bus(sl->master))
  557. goto error;
  558. w1_write_8(sl->master, W1_SKIP_ROM);
  559. w1_write_8(sl->master, W1_42_CHAIN);
  560. w1_write_8(sl->master, W1_42_CHAIN_ON);
  561. w1_write_8(sl->master, W1_42_CHAIN_ON_INV);
  562. msleep(sl->master->pullup_duration);
  563. /* check for acknowledgment */
  564. ack = w1_read_8(sl->master);
  565. if (ack != W1_42_SUCCESS_CONFIRM_BYTE)
  566. goto error;
  567. /* In case the bus fails to send 0xFF, limit*/
  568. for (i = 0; i <= 64; i++) {
  569. if (w1_reset_bus(sl->master))
  570. goto error;
  571. w1_write_8(sl->master, W1_42_COND_READ);
  572. rv = w1_read_block(sl->master, (u8 *)&rn, 8);
  573. reg_num = (struct w1_reg_num *) &rn;
  574. if (reg_num->family == W1_42_FINISHED_BYTE)
  575. break;
  576. if (sl->reg_num.id == reg_num->id)
  577. seq = i;
  578. w1_write_8(sl->master, W1_42_CHAIN);
  579. w1_write_8(sl->master, W1_42_CHAIN_DONE);
  580. w1_write_8(sl->master, W1_42_CHAIN_DONE_INV);
  581. w1_read_block(sl->master, &ack, sizeof(ack));
  582. /* check for acknowledgment */
  583. ack = w1_read_8(sl->master);
  584. if (ack != W1_42_SUCCESS_CONFIRM_BYTE)
  585. goto error;
  586. }
  587. /* Exit from CHAIN state */
  588. if (w1_reset_bus(sl->master))
  589. goto error;
  590. w1_write_8(sl->master, W1_SKIP_ROM);
  591. w1_write_8(sl->master, W1_42_CHAIN);
  592. w1_write_8(sl->master, W1_42_CHAIN_OFF);
  593. w1_write_8(sl->master, W1_42_CHAIN_OFF_INV);
  594. /* check for acknowledgment */
  595. ack = w1_read_8(sl->master);
  596. if (ack != W1_42_SUCCESS_CONFIRM_BYTE)
  597. goto error;
  598. mutex_unlock(&sl->master->bus_mutex);
  599. c -= snprintf(buf + PAGE_SIZE - c, c, "%d\n", seq);
  600. return PAGE_SIZE - c;
  601. error:
  602. mutex_unlock(&sl->master->bus_mutex);
  603. return -EIO;
  604. }
  605. static int __init w1_therm_init(void)
  606. {
  607. int err, i;
  608. for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i) {
  609. err = w1_register_family(w1_therm_families[i].f);
  610. if (err)
  611. w1_therm_families[i].broken = 1;
  612. }
  613. return 0;
  614. }
  615. static void __exit w1_therm_fini(void)
  616. {
  617. int i;
  618. for (i = 0; i < ARRAY_SIZE(w1_therm_families); ++i)
  619. if (!w1_therm_families[i].broken)
  620. w1_unregister_family(w1_therm_families[i].f);
  621. }
  622. module_init(w1_therm_init);
  623. module_exit(w1_therm_fini);
  624. MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
  625. MODULE_DESCRIPTION("Driver for 1-wire Dallas network protocol, temperature family.");
  626. MODULE_LICENSE("GPL");
  627. MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS18S20));
  628. MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS1822));
  629. MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS18B20));
  630. MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS1825));
  631. MODULE_ALIAS("w1-family-" __stringify(W1_THERM_DS28EA00));