#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

Reply via email to