aboutsummaryrefslogtreecommitdiff
path: root/drivers/w1
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/w1')
-rw-r--r--drivers/w1/masters/ds2490.c128
-rw-r--r--drivers/w1/slaves/w1_therm.c78
2 files changed, 139 insertions, 67 deletions
diff --git a/drivers/w1/masters/ds2490.c b/drivers/w1/masters/ds2490.c
index cd8821580f71..0eb560fc0153 100644
--- a/drivers/w1/masters/ds2490.c
+++ b/drivers/w1/masters/ds2490.c
@@ -172,8 +172,9 @@ static int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
CONTROL_CMD, VENDOR, value, index, NULL, 0, 1000);
if (err < 0) {
- pr_err("Failed to send command control message %x.%x: err=%d.\n",
- value, index, err);
+ dev_err(&dev->udev->dev,
+ "Failed to send command control message %x.%x: err=%d.\n",
+ value, index, err);
return err;
}
@@ -187,8 +188,9 @@ static int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
MODE_CMD, VENDOR, value, index, NULL, 0, 1000);
if (err < 0) {
- pr_err("Failed to send mode control message %x.%x: err=%d.\n",
- value, index, err);
+ dev_err(&dev->udev->dev,
+ "Failed to send mode control message %x.%x: err=%d.\n",
+ value, index, err);
return err;
}
@@ -202,74 +204,68 @@ static int ds_send_control(struct ds_device *dev, u16 value, u16 index)
err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
COMM_CMD, VENDOR, value, index, NULL, 0, 1000);
if (err < 0) {
- pr_err("Failed to send control message %x.%x: err=%d.\n",
- value, index, err);
+ dev_err(&dev->udev->dev,
+ "Failed to send control message %x.%x: err=%d.\n",
+ value, index, err);
return err;
}
return err;
}
-static inline void ds_print_msg(unsigned char *buf, unsigned char *str, int off)
-{
- pr_info("%45s: %8x\n", str, buf[off]);
-}
-
-static void ds_dump_status(struct ds_device *dev, unsigned char *buf, int count)
+static void ds_dump_status(struct ds_device *ds_dev, unsigned char *buf, int count)
{
+ struct device *dev = &ds_dev->udev->dev;
int i;
- pr_info("0x%x: count=%d, status: ", dev->ep[EP_STATUS], count);
- for (i = 0; i < count; ++i)
- pr_info("%02x ", buf[i]);
- pr_info("\n");
+ dev_info(dev, "ep_status=0x%x, count=%d, status=%*phC",
+ ds_dev->ep[EP_STATUS], count, count, buf);
if (count >= 16) {
- ds_print_msg(buf, "enable flag", 0);
- ds_print_msg(buf, "1-wire speed", 1);
- ds_print_msg(buf, "strong pullup duration", 2);
- ds_print_msg(buf, "programming pulse duration", 3);
- ds_print_msg(buf, "pulldown slew rate control", 4);
- ds_print_msg(buf, "write-1 low time", 5);
- ds_print_msg(buf, "data sample offset/write-0 recovery time",
- 6);
- ds_print_msg(buf, "reserved (test register)", 7);
- ds_print_msg(buf, "device status flags", 8);
- ds_print_msg(buf, "communication command byte 1", 9);
- ds_print_msg(buf, "communication command byte 2", 10);
- ds_print_msg(buf, "communication command buffer status", 11);
- ds_print_msg(buf, "1-wire data output buffer status", 12);
- ds_print_msg(buf, "1-wire data input buffer status", 13);
- ds_print_msg(buf, "reserved", 14);
- ds_print_msg(buf, "reserved", 15);
+ dev_dbg(dev, "enable flag: 0x%02x", buf[0]);
+ dev_dbg(dev, "1-wire speed: 0x%02x", buf[1]);
+ dev_dbg(dev, "strong pullup duration: 0x%02x", buf[2]);
+ dev_dbg(dev, "programming pulse duration: 0x%02x", buf[3]);
+ dev_dbg(dev, "pulldown slew rate control: 0x%02x", buf[4]);
+ dev_dbg(dev, "write-1 low time: 0x%02x", buf[5]);
+ dev_dbg(dev, "data sample offset/write-0 recovery time: 0x%02x", buf[6]);
+ dev_dbg(dev, "reserved (test register): 0x%02x", buf[7]);
+ dev_dbg(dev, "device status flags: 0x%02x", buf[8]);
+ dev_dbg(dev, "communication command byte 1: 0x%02x", buf[9]);
+ dev_dbg(dev, "communication command byte 2: 0x%02x", buf[10]);
+ dev_dbg(dev, "communication command buffer status: 0x%02x", buf[11]);
+ dev_dbg(dev, "1-wire data output buffer status: 0x%02x", buf[12]);
+ dev_dbg(dev, "1-wire data input buffer status: 0x%02x", buf[13]);
+ dev_dbg(dev, "reserved: 0x%02x", buf[14]);
+ dev_dbg(dev, "reserved: 0x%02x", buf[15]);
}
+
for (i = 16; i < count; ++i) {
if (buf[i] == RR_DETECT) {
- ds_print_msg(buf, "new device detect", i);
+ dev_dbg(dev, "New device detect.\n");
continue;
}
- ds_print_msg(buf, "Result Register Value: ", i);
+ dev_dbg(dev, "Result Register Value: 0x%02x", buf[i]);
if (buf[i] & RR_NRS)
- pr_info("NRS: Reset no presence or ...\n");
+ dev_dbg(dev, "NRS: Reset no presence or ...\n");
if (buf[i] & RR_SH)
- pr_info("SH: short on reset or set path\n");
+ dev_dbg(dev, "SH: short on reset or set path\n");
if (buf[i] & RR_APP)
- pr_info("APP: alarming presence on reset\n");
+ dev_dbg(dev, "APP: alarming presence on reset\n");
if (buf[i] & RR_VPP)
- pr_info("VPP: 12V expected not seen\n");
+ dev_dbg(dev, "VPP: 12V expected not seen\n");
if (buf[i] & RR_CMP)
- pr_info("CMP: compare error\n");
+ dev_dbg(dev, "CMP: compare error\n");
if (buf[i] & RR_CRC)
- pr_info("CRC: CRC error detected\n");
+ dev_dbg(dev, "CRC: CRC error detected\n");
if (buf[i] & RR_RDP)
- pr_info("RDP: redirected page\n");
+ dev_dbg(dev, "RDP: redirected page\n");
if (buf[i] & RR_EOS)
- pr_info("EOS: end of search error\n");
+ dev_dbg(dev, "EOS: end of search error\n");
}
}
-static int ds_recv_status(struct ds_device *dev, struct ds_status *st,
- bool dump)
+static int ds_recv_status(struct ds_device *dev, struct ds_status *st)
{
int count, err;
@@ -283,14 +279,12 @@ static int ds_recv_status(struct ds_device *dev, struct ds_status *st,
dev->st_buf, sizeof(dev->st_buf),
&count, 1000);
if (err < 0) {
- pr_err("Failed to read 1-wire data from 0x%x: err=%d.\n",
- dev->ep[EP_STATUS], err);
+ dev_err(&dev->udev->dev,
+ "Failed to read 1-wire data from 0x%x: err=%d.\n",
+ dev->ep[EP_STATUS], err);
return err;
}
- if (dump)
- ds_dump_status(dev, dev->st_buf, count);
-
if (st && count >= sizeof(*st))
memcpy(st, dev->st_buf, sizeof(*st));
@@ -304,13 +298,15 @@ static void ds_reset_device(struct ds_device *dev)
* the strong pullup.
*/
if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE))
- pr_err("ds_reset_device: Error allowing strong pullup\n");
+ dev_err(&dev->udev->dev,
+ "%s: Error allowing strong pullup\n", __func__);
/* Chip strong pullup time was cleared. */
if (dev->spu_sleep) {
/* lower 4 bits are 0, see ds_set_pullup */
u8 del = dev->spu_sleep>>4;
if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del))
- pr_err("ds_reset_device: Error setting duration\n");
+ dev_err(&dev->udev->dev,
+ "%s: Error setting duration\n", __func__);
}
}
@@ -331,9 +327,16 @@ static int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
buf, size, &count, 1000);
if (err < 0) {
- pr_info("Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
+ int recv_len;
+
+ dev_info(&dev->udev->dev, "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
- ds_recv_status(dev, NULL, true);
+
+ /* status might tell us why endpoint is stuck? */
+ recv_len = ds_recv_status(dev, NULL);
+ if (recv_len >= 0)
+ ds_dump_status(dev, dev->st_buf, recv_len);
+
return err;
}
@@ -357,7 +360,7 @@ static int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
count = 0;
err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
if (err < 0) {
- pr_err("Failed to write 1-wire data to ep0x%x: "
+ dev_err(&dev->udev->dev, "Failed to write 1-wire data to ep0x%x: "
"err=%d.\n", dev->ep[EP_DATA_OUT], err);
return err;
}
@@ -379,7 +382,7 @@ int ds_stop_pulse(struct ds_device *dev, int limit)
err = ds_send_control(dev, CTL_RESUME_EXE, 0);
if (err)
break;
- err = ds_recv_status(dev, &st, false);
+ err = ds_recv_status(dev, &st);
if (err)
break;
@@ -426,7 +429,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
do {
st->status = 0;
- err = ds_recv_status(dev, st, false);
+ err = ds_recv_status(dev, st);
#if 0
if (err >= 0) {
int i;
@@ -439,7 +442,7 @@ static int ds_wait_status(struct ds_device *dev, struct ds_status *st)
} while (!(st->status & ST_IDLE) && !(err < 0) && ++count < 100);
if (err >= 16 && st->status & ST_EPOF) {
- pr_info("Resetting device after ST_EPOF.\n");
+ dev_info(&dev->udev->dev, "Resetting device after ST_EPOF.\n");
ds_reset_device(dev);
/* Always dump the device status. */
count = 101;
@@ -723,7 +726,7 @@ static void ds9490r_search(void *data, struct w1_master *master,
do {
schedule_timeout(jtime);
- err = ds_recv_status(dev, &st, false);
+ err = ds_recv_status(dev, &st);
if (err < 0 || err < sizeof(st))
break;
@@ -994,10 +997,9 @@ static int ds_probe(struct usb_interface *intf,
int i, err, alt;
dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL);
- if (!dev) {
- pr_info("Failed to allocate new DS9490R structure.\n");
+ if (!dev)
return -ENOMEM;
- }
+
dev->udev = usb_get_dev(udev);
if (!dev->udev) {
err = -ENOMEM;
@@ -1027,7 +1029,7 @@ static int ds_probe(struct usb_interface *intf,
iface_desc = intf->cur_altsetting;
if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
- pr_info("Num endpoints=%d. It is not DS9490R.\n",
+ dev_err(&dev->udev->dev, "Num endpoints=%d. It is not DS9490R.\n",
iface_desc->desc.bNumEndpoints);
err = -EINVAL;
goto err_out_clear;
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 565578002d79..067692626cf0 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -574,6 +574,41 @@ static inline int w1_DS18S20_convert_time(struct w1_slave *sl)
return SLAVE_CONV_TIME_OVERRIDE(sl);
}
+static inline int w1_DS1825_convert_time(struct w1_slave *sl)
+{
+ int ret;
+
+ if (!sl->family_data)
+ return -ENODEV; /* device unknown */
+
+ if (SLAVE_CONV_TIME_OVERRIDE(sl) != CONV_TIME_DEFAULT)
+ return SLAVE_CONV_TIME_OVERRIDE(sl);
+
+ /* Return the conversion time, depending on resolution,
+ * select maximum conversion time among all compatible devices
+ */
+ switch (SLAVE_RESOLUTION(sl)) {
+ case 9:
+ ret = 95;
+ break;
+ case 10:
+ ret = 190;
+ break;
+ case 11:
+ ret = 375;
+ break;
+ case 12:
+ ret = 750;
+ break;
+ case 14:
+ ret = 100; /* MAX31850 only. Datasheet says 100ms */
+ break;
+ default:
+ ret = 750;
+ }
+ return ret;
+}
+
static inline int w1_DS18B20_write_data(struct w1_slave *sl,
const u8 *data)
{
@@ -594,6 +629,7 @@ static inline int w1_DS18B20_set_resolution(struct w1_slave *sl, int val)
/* DS18B20 resolution is 9 to 12 bits */
/* GX20MH01 resolution is 9 to 14 bits */
+ /* MAX31850 resolution is fixed 14 bits */
if (val < W1_THERM_RESOLUTION_MIN || val > W1_THERM_RESOLUTION_MAX)
return -EINVAL;
@@ -649,6 +685,7 @@ static inline int w1_DS18B20_get_resolution(struct w1_slave *sl)
+ W1_THERM_RESOLUTION_MIN;
/* GX20MH01 has one special case:
* >=14 means 14 bits when getting resolution from bit value.
+ * MAX31850 delivers fixed 15 and has 14 bits.
* Other devices have no more then 12 bits.
*/
if (resolution > W1_THERM_RESOLUTION_MAX)
@@ -715,6 +752,34 @@ static inline int w1_DS18S20_convert_temp(u8 rom[9])
return t;
}
+/**
+ * w1_DS1825_convert_temp() - temperature computation for DS1825
+ * @rom: data read from device RAM (8 data bytes + 1 CRC byte)
+ *
+ * Can be called for any DS1825 compliant device.
+ * Is used by MAX31850, too
+ *
+ * Return: value in millidegrees Celsius.
+ */
+
+static inline int w1_DS1825_convert_temp(u8 rom[9])
+{
+ u16 bv;
+ s16 t;
+
+ /* Signed 16-bit value to unsigned, cpu order */
+ bv = le16_to_cpup((__le16 *)rom);
+
+ /* Config register bit 7 = 1 - MA31850 found, 14 bit resolution */
+ if (rom[4] & 0x80) {
+ /* Mask out bits 0 (Fault) and 1 (Reserved) */
+ /* Avoid arithmetic shift of signed value */
+ bv = (bv & 0xFFFC); /* Degrees, lowest 4 bits are 2^-1, 2^-2 and 2 zero bits */
+ }
+ t = (s16)bv; /* Degrees, lowest bit is 2^-4 */
+ return (int)t * 1000 / 16; /* Sign-extend to int; millidegrees */
+}
+
/* Device capability description */
/* GX20MH01 device shares family number and structure with DS18B20 */
@@ -757,9 +822,10 @@ static struct w1_therm_family_converter w1_therm_families[] = {
.bulk_read = false
},
{
+ /* Also used for MAX31850 */
.f = &w1_therm_family_DS1825,
- .convert = w1_DS18B20_convert_temp,
- .get_conversion_time = w1_DS18B20_convert_time,
+ .convert = w1_DS1825_convert_temp,
+ .get_conversion_time = w1_DS1825_convert_time,
.set_resolution = w1_DS18B20_set_resolution,
.get_resolution = w1_DS18B20_get_resolution,
.write_data = w1_DS18B20_write_data,
@@ -2089,16 +2155,20 @@ static ssize_t w1_seq_show(struct device *device,
if (sl->reg_num.id == reg_num->id)
seq = i;
+ if (w1_reset_bus(sl->master))
+ goto error;
+
+ /* Put the device into chain DONE state */
+ w1_write_8(sl->master, W1_MATCH_ROM);
+ w1_write_block(sl->master, (u8 *)&rn, 8);
w1_write_8(sl->master, W1_42_CHAIN);
w1_write_8(sl->master, W1_42_CHAIN_DONE);
w1_write_8(sl->master, W1_42_CHAIN_DONE_INV);
- w1_read_block(sl->master, &ack, sizeof(ack));
/* check for acknowledgment */
ack = w1_read_8(sl->master);
if (ack != W1_42_SUCCESS_CONFIRM_BYTE)
goto error;
-
}
/* Exit from CHAIN state */