root/drivers/w1/slaves/w1_therm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. w1_therm_add_slave
  2. w1_therm_remove_slave
  3. w1_is_visible
  4. w1_read
  5. w1_therm_eeprom
  6. w1_DS18S20_precision
  7. w1_DS18B20_precision
  8. w1_DS18B20_convert_temp
  9. w1_DS18S20_convert_temp
  10. w1_convert_temp
  11. w1_slave_store
  12. read_therm
  13. w1_slave_show
  14. w1_read_temp
  15. w1_seq_show
  16. w1_therm_init
  17. w1_therm_fini

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

/* [<][>][^][v][top][bottom][index][help] */