summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/stable/sysfs-driver-w1_ds24387
-rw-r--r--Documentation/w1/slaves/w1_ds2438.rst11
-rw-r--r--drivers/w1/slaves/w1_ds2438.c49
3 files changed, 66 insertions, 1 deletions
diff --git a/Documentation/ABI/stable/sysfs-driver-w1_ds2438 b/Documentation/ABI/stable/sysfs-driver-w1_ds2438
index fa47437c11d9..d2e7681cc287 100644
--- a/Documentation/ABI/stable/sysfs-driver-w1_ds2438
+++ b/Documentation/ABI/stable/sysfs-driver-w1_ds2438
@@ -4,3 +4,10 @@ Contact: Luiz Sampaio <sampaio.ime@gmail.com>
Description: read the contents of the page1 of the DS2438
see Documentation/w1/slaves/w1_ds2438.rst for detailed information
Users: any user space application which wants to communicate with DS2438
+
+What: /sys/bus/w1/devices/.../offset
+Date: April 2021
+Contact: Luiz Sampaio <sampaio.ime@gmail.com>
+Description: write the contents to the offset register of the DS2438
+ see Documentation/w1/slaves/w1_ds2438.rst for detailed information
+Users: any user space application which wants to communicate with DS2438
diff --git a/Documentation/w1/slaves/w1_ds2438.rst b/Documentation/w1/slaves/w1_ds2438.rst
index ac8d0d4b0d0e..5c5573991351 100644
--- a/Documentation/w1/slaves/w1_ds2438.rst
+++ b/Documentation/w1/slaves/w1_ds2438.rst
@@ -22,7 +22,7 @@ is also often used in weather stations and applications such as: rain gauge,
wind speed/direction measuring, humidity sensing, etc.
Current support is provided through the following sysfs files (all files
-except "iad" are readonly):
+except "iad" and "offset" are readonly):
"iad"
-----
@@ -52,6 +52,15 @@ Internally when this file is read, the additional CRC byte is also obtained
from the slave device. If it is correct, the 8 bytes page data are passed
to userspace, otherwise an I/O error is returned.
+"offset"
+-------
+This file controls the 2-byte Offset Register of the chip.
+Writing a 2-byte value will change the Offset Register, which changes the
+current measurement done by the chip. Changing this register to the two's complement
+of the current register while forcing zero current through the load will calibrate
+the chip, canceling offset errors in the current ADC.
+
+
"temperature"
-------------
Opening and reading this file initiates the CONVERT_T (temperature conversion)
diff --git a/drivers/w1/slaves/w1_ds2438.c b/drivers/w1/slaves/w1_ds2438.c
index 42080ae779f0..ca64f99c8f3d 100644
--- a/drivers/w1/slaves/w1_ds2438.c
+++ b/drivers/w1/slaves/w1_ds2438.c
@@ -193,6 +193,34 @@ static int w1_ds2438_change_config_bit(struct w1_slave *sl, u8 mask, u8 value)
return -1;
}
+static int w1_ds2438_change_offset_register(struct w1_slave *sl, u8 *value)
+{
+ unsigned int retries = W1_DS2438_RETRIES;
+ u8 w1_buf[9];
+ u8 w1_page1_buf[DS2438_PAGE_SIZE + 1 /*for CRC*/];
+
+ if (w1_ds2438_get_page(sl, 1, w1_page1_buf) == 0) {
+ memcpy(&w1_buf[2], w1_page1_buf, DS2438_PAGE_SIZE - 1); /* last register reserved */
+ w1_buf[7] = value[0]; /* change only offset register */
+ w1_buf[8] = value[1];
+ while (retries--) {
+ if (w1_reset_select_slave(sl))
+ continue;
+ w1_buf[0] = W1_DS2438_WRITE_SCRATCH;
+ w1_buf[1] = 0x01; /* write to page 1 */
+ w1_write_block(sl->master, w1_buf, 9);
+
+ if (w1_reset_select_slave(sl))
+ continue;
+ w1_buf[0] = W1_DS2438_COPY_SCRATCH;
+ w1_buf[1] = 0x01;
+ w1_write_block(sl->master, w1_buf, 2);
+ return 0;
+ }
+ }
+ return -1;
+}
+
static int w1_ds2438_get_voltage(struct w1_slave *sl,
int adc_input, uint16_t *voltage)
{
@@ -364,6 +392,25 @@ static ssize_t page1_read(struct file *filp, struct kobject *kobj,
return ret;
}
+static ssize_t offset_write(struct file *filp, struct kobject *kobj,
+ struct bin_attribute *bin_attr, char *buf,
+ loff_t off, size_t count)
+{
+ struct w1_slave *sl = kobj_to_w1_slave(kobj);
+ int ret;
+
+ mutex_lock(&sl->master->bus_mutex);
+
+ if (w1_ds2438_change_offset_register(sl, buf) == 0)
+ ret = count;
+ else
+ ret = -EIO;
+
+ mutex_unlock(&sl->master->bus_mutex);
+
+ return ret;
+}
+
static ssize_t temperature_read(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr, char *buf,
loff_t off, size_t count)
@@ -430,6 +477,7 @@ static ssize_t vdd_read(struct file *filp, struct kobject *kobj,
static BIN_ATTR_RW(iad, 0);
static BIN_ATTR_RO(page0, DS2438_PAGE_SIZE);
static BIN_ATTR_RO(page1, DS2438_PAGE_SIZE);
+static BIN_ATTR_WO(offset, 2);
static BIN_ATTR_RO(temperature, 0/* real length varies */);
static BIN_ATTR_RO(vad, 0/* real length varies */);
static BIN_ATTR_RO(vdd, 0/* real length varies */);
@@ -438,6 +486,7 @@ static struct bin_attribute *w1_ds2438_bin_attrs[] = {
&bin_attr_iad,
&bin_attr_page0,
&bin_attr_page1,
+ &bin_attr_offset,
&bin_attr_temperature,
&bin_attr_vad,
&bin_attr_vdd,