#22245: [PATCH 891] [generic] Pull-up delay for DS2482 1-wire master driver
-------------------------------------+-------------------------------------
Reporter: Eugene Yarshevich | Owner: developers
<yarshevich@…> | Status: new
Type: defect | Milestone: Designated Driver
Priority: normal | (Trunk)
Component: kernel | Version: Chaos Calmer 15.05
Keywords: ds2482 |
-------------------------------------+-------------------------------------
'''DS2482''' 1-wire bus master driver implemented in
'''./drivers/w1/masters/ds2482.c''' has incomplete support for strong
pull-up feature.
Driver sets chip registers properly, however it completely ignores
requested delay value (in milliseconds). As a result, write-read operation
happens too fast, and parasitically-powered 1-wire slave devices have not
enough time to charge and perform requested operation.
{{{
static u8 ds2482_w1_set_pullup(void *data, int delay)
{
struct ds2482_w1_chan *pchan = data;
struct ds2482_data *pdev = pchan->pdev;
u8 retval = 1;
/* if delay is non-zero activate the pullup,
* the strong pullup will be automatically deactivated
* by the master, so do not explicitly deactive it
*/
if (delay) {
/* both waits are crucial, otherwise devices might not be
* powered long enough, causing e.g. a w1_therm sensor to
* provide wrong conversion results
*/
ds2482_wait_1wire_idle(pdev);
/* note: it seems like both SPU and APU have to be set! */
retval = ds2482_send_cmd_data(pdev,
DS2482_CMD_WRITE_CONFIG,
ds2482_calculate_config(DS2482_REG_CFG_SPU |
DS2482_REG_CFG_APU));
ds2482_wait_1wire_idle(pdev);
}
return retval;
}
}}}
In comparison, GPIO-based w1 master driver adds such delay via
'''msleep(..)''' method call.
{{{
static u8 w1_gpio_set_pullup(void *data, int delay)
{
struct w1_gpio_platform_data *pdata = data;
if (delay) {
pdata->pullup_duration = delay;
} else {
if (pdata->pullup_duration) {
gpio_direction_output(pdata->pin, 1);
msleep(pdata->pullup_duration);
gpio_direction_input(pdata->pin);
}
pdata->pullup_duration = 0;
}
return 0;
}
}}}
Proposed patch fixes the issue by introducing delay between write and read
operations. Implementation is similar to GPIO-based w1 master driver.
Exact delay duration in milliseconds is received from w1-slave driver.
{{{
static u8 ds2482_w1_set_pullup(void *data, int delay)
{
struct ds2482_w1_chan *pchan = data;
struct ds2482_data *pdev = pchan->pdev;
u8 retval = 1;
if (delay) {
/*
* Activate pullup request received prior to the write
request,
* the strong pullup will be automatically deactivated
* by the master, so do not explicitly deactivate it
*/
ds2482_wait_1wire_idle(pdev);
/* note: it seems like both SPU and APU have to be set! */
retval = ds2482_send_cmd_data(pdev,
DS2482_CMD_WRITE_CONFIG,
ds2482_calculate_config(DS2482_REG_CFG_SPU |
DS2482_REG_CFG_APU));
ds2482_wait_1wire_idle(pdev);
} else {
/*
* When pullup has been activated, another request with
delay == 0
* would be issued right before the subsequent read
request.
* We should guarantee, however, that long enough delay
has been
* injected prior to read command, so parasitic-powered
devices
* would charge and do the conversion properly.
*/
if (pdev->pullup_delay > 0)
msleep(pdev->pullup_delay);
}
pdev->pullup_delay = delay;
return retval;
}
}}}
Changes are made in accordance with '''DS2482''' chip specification.
Tested with '''DS18B20''' temperature sensor ('''w1_therm''' driver) and
latest truck version. Tested using externally powered and parasitically-
powered sensor configuration.
Signed-off-by: Eugene Yarshevich <[email protected]>
--
Ticket URL: <https://dev.openwrt.org/ticket/22245>
OpenWrt <http://openwrt.org>
Opensource Wireless Router Technology
_______________________________________________
openwrt-tickets mailing list
[email protected]
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-tickets