Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

w1: w1_therm: Add support for Maxim MAX31850 thermoelement IF.

MAX31850 shares family number 0x3B with DS1825. The device is generally
compatible with DS1825 but needs a different temperature readout.
It operates always in 14 bit mode and has all 4 higher bits of the
Config register set to 1. Conversion time is 100ms.

Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
Link: https://lore.kernel.org/r/20220306145817.8753-1-m.reichl@fivetechno.de
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Markus Reichl and committed by
Greg Kroah-Hartman
6e07a33f 6caf745d

+68 -2
+68 -2
drivers/w1/slaves/w1_therm.c
··· 574 574 return SLAVE_CONV_TIME_OVERRIDE(sl); 575 575 } 576 576 577 + static inline int w1_DS1825_convert_time(struct w1_slave *sl) 578 + { 579 + int ret; 580 + 581 + if (!sl->family_data) 582 + return -ENODEV; /* device unknown */ 583 + 584 + if (SLAVE_CONV_TIME_OVERRIDE(sl) != CONV_TIME_DEFAULT) 585 + return SLAVE_CONV_TIME_OVERRIDE(sl); 586 + 587 + /* Return the conversion time, depending on resolution, 588 + * select maximum conversion time among all compatible devices 589 + */ 590 + switch (SLAVE_RESOLUTION(sl)) { 591 + case 9: 592 + ret = 95; 593 + break; 594 + case 10: 595 + ret = 190; 596 + break; 597 + case 11: 598 + ret = 375; 599 + break; 600 + case 12: 601 + ret = 750; 602 + break; 603 + case 14: 604 + ret = 100; /* MAX31850 only. Datasheet says 100ms */ 605 + break; 606 + default: 607 + ret = 750; 608 + } 609 + return ret; 610 + } 611 + 577 612 static inline int w1_DS18B20_write_data(struct w1_slave *sl, 578 613 const u8 *data) 579 614 { ··· 629 594 630 595 /* DS18B20 resolution is 9 to 12 bits */ 631 596 /* GX20MH01 resolution is 9 to 14 bits */ 597 + /* MAX31850 resolution is fixed 14 bits */ 632 598 if (val < W1_THERM_RESOLUTION_MIN || val > W1_THERM_RESOLUTION_MAX) 633 599 return -EINVAL; 634 600 ··· 685 649 + W1_THERM_RESOLUTION_MIN; 686 650 /* GX20MH01 has one special case: 687 651 * >=14 means 14 bits when getting resolution from bit value. 652 + * MAX31850 delivers fixed 15 and has 14 bits. 688 653 * Other devices have no more then 12 bits. 689 654 */ 690 655 if (resolution > W1_THERM_RESOLUTION_MAX) ··· 752 715 return t; 753 716 } 754 717 718 + /** 719 + * w1_DS1825_convert_temp() - temperature computation for DS1825 720 + * @rom: data read from device RAM (8 data bytes + 1 CRC byte) 721 + * 722 + * Can be called for any DS1825 compliant device. 723 + * Is used by MAX31850, too 724 + * 725 + * Return: value in millidegrees Celsius. 726 + */ 727 + 728 + static inline int w1_DS1825_convert_temp(u8 rom[9]) 729 + { 730 + u16 bv; 731 + s16 t; 732 + 733 + /* Signed 16-bit value to unsigned, cpu order */ 734 + bv = le16_to_cpup((__le16 *)rom); 735 + 736 + /* Config register bit 7 = 1 - MA31850 found, 14 bit resolution */ 737 + if (rom[4] & 0x80) { 738 + /* Mask out bits 0 (Fault) and 1 (Reserved) */ 739 + /* Avoid arithmetic shift of signed value */ 740 + bv = (bv & 0xFFFC); /* Degrees, lowest 4 bits are 2^-1, 2^-2 and 2 zero bits */ 741 + } 742 + t = (s16)bv; /* Degrees, lowest bit is 2^-4 */ 743 + return (int)t * 1000 / 16; /* Sign-extend to int; millidegrees */ 744 + } 745 + 755 746 /* Device capability description */ 756 747 /* GX20MH01 device shares family number and structure with DS18B20 */ 757 748 ··· 822 757 .bulk_read = false 823 758 }, 824 759 { 760 + /* Also used for MAX31850 */ 825 761 .f = &w1_therm_family_DS1825, 826 - .convert = w1_DS18B20_convert_temp, 827 - .get_conversion_time = w1_DS18B20_convert_time, 762 + .convert = w1_DS1825_convert_temp, 763 + .get_conversion_time = w1_DS1825_convert_time, 828 764 .set_resolution = w1_DS18B20_set_resolution, 829 765 .get_resolution = w1_DS18B20_get_resolution, 830 766 .write_data = w1_DS18B20_write_data,