Author: avg
Date: Wed Oct 30 15:26:41 2019
New Revision: 354181
URL: https://svnweb.freebsd.org/changeset/base/354181

Log:
  ow(4): protocol timings can now be changed as sysctl-s / tunables
  
  I limited potentially infinite timings by 960 us based on a footnote on
  page 38 of Maxim Integrated Application Note 937, Book of iButton
  Standards: "In order not to mask interrupt signalling by other devices
  on the 1–Wire bus, tRSTL + tR should always be less than 960 us."
  
  MFC after:    3 weeks

Modified:
  head/sys/dev/ow/ow.c

Modified: head/sys/dev/ow/ow.c
==============================================================================
--- head/sys/dev/ow/ow.c        Wed Oct 30 15:15:53 2019        (r354180)
+++ head/sys/dev/ow/ow.c        Wed Oct 30 15:26:41 2019        (r354181)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/malloc.h>
 #include <sys/module.h>
 #include <sys/mutex.h>
+#include <sys/sysctl.h>
 
 #include <dev/ow/ow.h>
 #include <dev/ow/owll.h>
@@ -75,34 +76,137 @@ static void ow_release_bus(device_t ndev, device_t pde
 
 static MALLOC_DEFINE(M_OW, "ow", "House keeping data for 1wire bus");
 
+static const struct ow_timing timing_regular_min = {
+       .t_slot = 60,
+       .t_low0 = 60,
+       .t_low1 = 1,
+       .t_release = 0,
+       .t_rec = 1,
+       .t_rdv = 15,            /* fixed */
+       .t_rstl = 480,
+       .t_rsth = 480,
+       .t_pdl = 60,
+       .t_pdh = 15,
+       .t_lowr = 1,
+};
+
+static const struct ow_timing timing_regular_max = {
+       .t_slot = 120,
+       .t_low0 = 120,
+       .t_low1 = 15,
+       .t_release = 45,
+       .t_rec = 960,           /* infinity */
+       .t_rdv = 15,            /* fixed */
+       .t_rstl = 960,          /* infinity */
+       .t_rsth = 960,          /* infinity */
+       .t_pdl = 240,           /* 60us to 240us */
+       .t_pdh = 60,            /* 15us to 60us */
+       .t_lowr = 15,           /* 1us */
+};
+
 static struct ow_timing timing_regular = {
-       .t_slot = 60,           /* 60 to 120 */
-       .t_low0 = 60,           /* really 60 to 120 */
-       .t_low1 = 1,            /* really 1 to 15 */
-       .t_release = 45,        /* <= 45us */
-       .t_rec = 15,            /* at least 1us */
-       .t_rdv = 15,            /* 15us */
-       .t_rstl = 480,          /* 480us or more */
-       .t_rsth = 480,          /* 480us or more */
-       .t_pdl = 60,            /* 60us to 240us */
-       .t_pdh = 60,            /* 15us to 60us */
-       .t_lowr = 1,            /* 1us */
+       .t_slot = 60,           /*  60 <= t < 120 */
+       .t_low0 = 60,           /*  60 <= t < t_slot < 120 */
+       .t_low1 = 1,            /*   1 <= t < 15 */
+       .t_release = 45,        /*   0 <= t < 45 */
+       .t_rec = 15,            /*   1 <= t < inf */
+       .t_rdv = 15,            /* t == 15 */
+       .t_rstl = 480,          /* 480 <= t < inf */
+       .t_rsth = 480,          /* 480 <= t < inf */
+       .t_pdl = 60,            /*  60 <= t < 240 */
+       .t_pdh = 60,            /*  15 <= t < 60 */
+       .t_lowr = 1,            /*   1 <= t < 15 */
 };
 
 /* NB: Untested */
+static const struct ow_timing timing_overdrive_min = {
+       .t_slot = 6,
+       .t_low0 = 6,
+       .t_low1 = 1,
+       .t_release = 0,
+       .t_rec = 1,
+       .t_rdv = 2,             /* fixed */
+       .t_rstl = 48,
+       .t_rsth = 48,
+       .t_pdl = 8,
+       .t_pdh = 2,
+       .t_lowr = 1,
+};
+
+static const struct ow_timing timing_overdrive_max = {
+       .t_slot = 16,
+       .t_low0 = 16,
+       .t_low1 = 2,
+       .t_release = 4,
+       .t_rec = 960,           /* infinity */
+       .t_rdv = 2,             /* fixed */
+       .t_rstl = 80,
+       .t_rsth = 960,          /* infinity */
+       .t_pdl = 24,
+       .t_pdh = 6,
+       .t_lowr = 2,
+};
+
 static struct ow_timing timing_overdrive = {
-       .t_slot = 11,           /* 6us to 16us */
-       .t_low0 = 6,            /* really 6 to 16 */
-       .t_low1 = 1,            /* really 1 to 2 */
-       .t_release = 4,         /* <= 4us */
-       .t_rec = 1,             /* at least 1us */
-       .t_rdv = 2,             /* 2us */
-       .t_rstl = 48,           /* 48us to 80us */
-       .t_rsth = 48,           /* 48us or more  */
-       .t_pdl = 8,             /* 8us to 24us */
-       .t_pdh = 2,             /* 2us to 6us */
-       .t_lowr = 1,            /* 1us */
+       .t_slot = 11,           /* 6 <= t < 16 */
+       .t_low0 = 6,            /* 6 <= t < t_slot < 16 */
+       .t_low1 = 1,            /* 1 <= t < 2 */
+       .t_release = 4,         /* 0 <= t < 4 */
+       .t_rec = 1,             /* 1 <= t < inf */
+       .t_rdv = 2,             /* t == 2 */
+       .t_rstl = 48,           /* 48 <= t < 80 */
+       .t_rsth = 48,           /* 48 <= t < inf */
+       .t_pdl = 8,             /* 8 <= t < 24 */
+       .t_pdh = 2,             /* 2 <= t < 6 */
+       .t_lowr = 1,            /* 1 <= t < 2 */
 };
+
+SYSCTL_DECL(_hw);
+SYSCTL_NODE(_hw, OID_AUTO, ow, CTLFLAG_RD, 0, "1-Wire protocol");
+SYSCTL_NODE(_hw_ow, OID_AUTO, regular, CTLFLAG_RD, 0,
+    "Regular mode timings");
+SYSCTL_NODE(_hw_ow, OID_AUTO, overdrive, CTLFLAG_RD, 0,
+    "Overdrive mode timings");
+
+#define        _OW_TIMING_SYSCTL(mode, param)          \
+    static int \
+    sysctl_ow_timing_ ## mode ## _ ## param(SYSCTL_HANDLER_ARGS) \
+    { \
+           int val = timing_ ## mode.param; \
+           int err; \
+           err = sysctl_handle_int(oidp, &val, 0, req); \
+           if (err != 0 || req->newptr == NULL) \
+               return (err); \
+           if (val < timing_ ## mode ## _min.param) \
+               return (EINVAL); \
+           else if (val >= timing_ ## mode ## _max.param) \
+               return (EINVAL); \
+           timing_ ## mode.param = val; \
+           return (0); \
+    } \
+SYSCTL_PROC(_hw_ow_ ## mode, OID_AUTO, param, \
+    CTLTYPE_INT | CTLFLAG_RWTUN, 0, sizeof(int), \
+    sysctl_ow_timing_ ## mode ## _ ## param, "I", \
+    "1-Wire timing parameter in microseconds (-1 resets to default)")
+
+#define        OW_TIMING_SYSCTL(param) \
+    _OW_TIMING_SYSCTL(regular, param); \
+    _OW_TIMING_SYSCTL(overdrive, param)
+
+OW_TIMING_SYSCTL(t_slot);
+OW_TIMING_SYSCTL(t_low0);
+OW_TIMING_SYSCTL(t_low1);
+OW_TIMING_SYSCTL(t_release);
+OW_TIMING_SYSCTL(t_rec);
+OW_TIMING_SYSCTL(t_rdv);
+OW_TIMING_SYSCTL(t_rstl);
+OW_TIMING_SYSCTL(t_rsth);
+OW_TIMING_SYSCTL(t_pdl);
+OW_TIMING_SYSCTL(t_pdh);
+OW_TIMING_SYSCTL(t_lowr);
+
+#undef _OW_TIMING_SYSCTL
+#undef OW_TIMING_SYSCTL
 
 static void
 ow_send_byte(device_t lldev, struct ow_timing *t, uint8_t byte)
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to