Author: stas
Date: Mon Apr 20 15:47:06 2009
New Revision: 191322
URL: http://svn.freebsd.org/changeset/base/191322

Log:
  - Give a warning and start the oscillator if it was not previously
    runned.
  - Rename ds1672 -> rtc to follow the other drivers.
  - Refactor/simplify the code a bit.
  
  MFC after:    2 weeks

Modified:
  head/sys/arm/conf/AVILA.hints
  head/sys/arm/conf/BWCT.hints
  head/sys/arm/conf/CAMBRIA.hints
  head/sys/dev/iicbus/ds1672.c

Modified: head/sys/arm/conf/AVILA.hints
==============================================================================
--- head/sys/arm/conf/AVILA.hints       Mon Apr 20 15:19:54 2009        
(r191321)
+++ head/sys/arm/conf/AVILA.hints       Mon Apr 20 15:47:06 2009        
(r191322)
@@ -44,5 +44,5 @@ hint.ad7418.0.at="iicbus0"
 hint.ad7418.0.addr=0x50
 
 # Dallas Semiconductor DS1672 RTC
-hint.ds1672.0.at="iicbus0"
-hint.ds1672.0.addr=0xd0
+hint.rtc.0.at="iicbus0"
+hint.rtc.0.addr=0xd0

Modified: head/sys/arm/conf/BWCT.hints
==============================================================================
--- head/sys/arm/conf/BWCT.hints        Mon Apr 20 15:19:54 2009        
(r191321)
+++ head/sys/arm/conf/BWCT.hints        Mon Apr 20 15:47:06 2009        
(r191322)
@@ -1,8 +1,8 @@
 # $FreeBSD$
 
 # Dallas Semiconductor DS1672 RTC sitting on the I2C bus
-hint.ds1672.0.at="iicbus0"
-hint.ds1672.0.addr=0xd0
+hint.rtc.0.at="iicbus0"
+hint.rtc.0.addr=0xd0
 
 # NAtional Semiconductor LM75 temperature sensor sitting on the I2C bus
 hint.lm75.0.at="iicbus0"

Modified: head/sys/arm/conf/CAMBRIA.hints
==============================================================================
--- head/sys/arm/conf/CAMBRIA.hints     Mon Apr 20 15:19:54 2009        
(r191321)
+++ head/sys/arm/conf/CAMBRIA.hints     Mon Apr 20 15:47:06 2009        
(r191322)
@@ -46,8 +46,8 @@ hint.ad7418.0.at="iicbus0"
 hint.ad7418.0.addr=0x50
 
 # Dallas Semiconductor DS1672 RTC
-hint.ds1672.0.at="iicbus0"
-hint.ds1672.0.addr=0xd0
+hint.rtc.0.at="iicbus0"
+hint.rtc.0.addr=0xd0
 
 # USB is part of the chip
 hint.ehci.0.at="ixp0"

Modified: head/sys/dev/iicbus/ds1672.c
==============================================================================
--- head/sys/dev/iicbus/ds1672.c        Mon Apr 20 15:19:54 2009        
(r191321)
+++ head/sys/dev/iicbus/ds1672.c        Mon Apr 20 15:47:06 2009        
(r191322)
@@ -50,8 +50,12 @@ __FBSDID("$FreeBSD$");
 #define        DS1672_CTRL     4       /* control (1 byte) */
 #define        DS1672_TRICKLE  5       /* trickle charger (1 byte) */
 
+#define        DS1672_CTRL_EOSC        (1 << 7)        /* Stop/start flag. */
+
 #define NANOSEC                1000000000
 
+#define        MAX_IIC_DATA_SIZE       4
+
 struct ds1672_softc {
        device_t                sc_dev;
 };
@@ -65,12 +69,64 @@ ds1672_probe(device_t dev)
 }
 
 static int
+ds1672_read(device_t dev, uint8_t addr, uint8_t *data, uint8_t size)
+{
+       struct iic_msg msgs[2] = {
+            { DS1672_ADDR, IIC_M_WR, 1, &addr },
+            { DS1672_ADDR, IIC_M_RD, size, data }
+       };
+
+       return (iicbus_transfer(dev, msgs, 2));
+}
+
+static int
+ds1672_write(device_t dev, uint8_t addr, uint8_t *data, uint8_t size)
+{
+       uint8_t buffer[MAX_IIC_DATA_SIZE + 1];
+       struct iic_msg msgs[1] = {
+            { DS1672_ADDR, IIC_M_WR, size + 1, buffer },
+       };
+       
+       if (size > MAX_IIC_DATA_SIZE)
+               return (ENOMEM);
+       /* NB: register pointer precedes actual data */
+       buffer[0] = addr;
+       memcpy(buffer + 1, data, size);
+       return (iicbus_transfer(dev, msgs, 1));
+}
+
+static int
+ds1672_init(device_t dev)
+{
+       uint8_t ctrl;
+       int error;
+
+       error = ds1672_read(dev, DS1672_CTRL, &ctrl, 1);
+       if (error)
+               return (error);
+
+       /*
+        * Check if oscialltor is not runned.
+        */
+       if (ctrl & DS1672_CTRL_EOSC) {
+               device_printf(dev, "RTC oscillator was stopped. Check system"
+                   " time and RTC battery.\n");
+               ctrl &= ~DS1672_CTRL_EOSC;      /* Start oscillator. */
+               error = ds1672_write(dev, DS1672_CTRL, &ctrl, 1);
+       }
+       return (error);
+}
+
+static int
 ds1672_attach(device_t dev)
 {
        struct ds1672_softc *sc = device_get_softc(dev);
+       int error;
 
        sc->sc_dev = dev;
-
+       error = ds1672_init(dev);
+       if (error)
+               return (error);
        clock_register(dev, 1000);
        return (0);
 }
@@ -78,39 +134,30 @@ ds1672_attach(device_t dev)
 static int
 ds1672_gettime(device_t dev, struct timespec *ts)
 {
-       uint8_t addr[1] = { DS1672_COUNTER };
        uint8_t secs[4];
-       struct iic_msg msgs[2] = {
-            { DS1672_ADDR, IIC_M_WR, 1, addr },
-            { DS1672_ADDR, IIC_M_RD, 4, secs },
-       };
        int error;
 
-       error = iicbus_transfer(dev, msgs, 2);
+       error = ds1672_read(dev, DS1672_COUNTER, secs, 4);
        if (error == 0) {
                /* counter has seconds since epoch */
                ts->tv_sec = (secs[3] << 24) | (secs[2] << 16)
                           | (secs[1] <<  8) | (secs[0] <<  0);
                ts->tv_nsec = NANOSEC / 2;
        }
-       return error;
+       return (error);
 }
 
 static int
 ds1672_settime(device_t dev, struct timespec *ts)
 {
-       /* NB: register pointer precedes actual data */
-       uint8_t data[5] = { DS1672_COUNTER };
-       struct iic_msg msgs[1] = {
-            { DS1672_ADDR, IIC_M_WR, 5, data },
-       };
+       uint8_t data[4];
 
-       data[1] = (ts->tv_sec >> 0) & 0xff;
-       data[2] = (ts->tv_sec >> 8) & 0xff;
-       data[3] = (ts->tv_sec >> 16) & 0xff;
-       data[4] = (ts->tv_sec >> 24) & 0xff;
+       data[0] = (ts->tv_sec >> 0) & 0xff;
+       data[1] = (ts->tv_sec >> 8) & 0xff;
+       data[2] = (ts->tv_sec >> 16) & 0xff;
+       data[3] = (ts->tv_sec >> 24) & 0xff;
 
-       return iicbus_transfer(dev, msgs, 1);
+       return (ds1672_write(dev, DS1672_COUNTER, data, 4));
 }
 
 static device_method_t ds1672_methods[] = {
@@ -124,7 +171,7 @@ static device_method_t ds1672_methods[] 
 };
 
 static driver_t ds1672_driver = {
-       "ds1672",
+       "rtc",
        ds1672_methods,
        sizeof(struct ds1672_softc),
 };
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to