[PATCH 2/2] rtc: ds1307: Add support for configuring external clock pin

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The DS1307 has a square wave output pin, which can be used to output a
clock signal from the DS1307.  Additionally, the DS1308 supports
configuring this pin as an input from an external clock source to
which it should sync itself.

Add support with OF device tree properties to configure these
settings.  Supported features are using the clock pin as an output, an
input, the rate of the pin, and if it should be enabled on battery
backup power.

The driver does not check that the selected features are supported by
the clock chip being used.  It is the designer's responsibility to
create a valid device tree node; the bootloader does not attempt to be
a device tree validator.

Signed-off-by: Trent Piepho <tpiepho@xxxxxxxxxxxxxx>
---
 .../devicetree/bindings/rtc/dallas,ds1307.rst      | 33 ++++++++++++++++
 drivers/rtc/rtc-ds1307.c                           | 45 +++++++++++++++++++++-
 2 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/rtc/dallas,ds1307.rst

diff --git a/Documentation/devicetree/bindings/rtc/dallas,ds1307.rst b/Documentation/devicetree/bindings/rtc/dallas,ds1307.rst
new file mode 100644
index 0000000..52787a8
--- /dev/null
+++ b/Documentation/devicetree/bindings/rtc/dallas,ds1307.rst
@@ -0,0 +1,33 @@
+Dallas DS1307 I2C Serial Real-Time Clock
+========================================
+
+Required properties:
+* ``compatible``: ``dallas,ds1307``, ``dallas,ds1308``, ``dallas,ds1338``
+	"maxim" can be used in place of "dallas"
+
+* ``reg``: I2C address for chip
+
+Optional properties:
+* ``ext-clock-input``: Enable external clock input pin
+* ``ext-clock-output``:  Enable square wave output.  The above two
+  properties are mutually exclusive
+* ``ext-clock-bb``: Enable external clock on battery power
+* ``ext-clock-rate``:  Expected/Generated rate on external clock pin
+  in Hz.  Allowable values are 1, 50, 60, 4096, 8192, and 32768 Hz. 
+  Not all values are valid for all configurations.
+
+The default is ext-clock-input, ext-clock-output, and ext-clock-bb
+disabled and ext-clock-rate of 1 Hz.
+
+Example::
+	ds1307: rtc@68 {
+		compatible = "dallas,ds1307";
+		reg = <0x68>;
+	};
+
+	ds1308: rtc@68 {
+		compatible = "maxim,ds1308";
+		reg = <0x68>;
+		ext-clock-output;
+		ext-clock-rate = <32768>;
+	};
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index ca630ea..73d88ba 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -59,10 +59,13 @@ enum ds_type {
  * start at 7, and they differ a LOT. Only control and status matter for
  * basic RTC date and time functionality; be careful using them.
  */
-#define DS1307_REG_CONTROL	0x07		/* or ds1338 */
+#define DS1307_REG_CONTROL	0x07		/* or ds1338, 1308 */
 #	define DS1307_BIT_OUT		0x80
+#	define DS1308_BIT_ECLK		0x40
 #	define DS1338_BIT_OSF		0x20
 #	define DS1307_BIT_SQWE		0x10
+#	define DS1308_BIT_LOS		0x08
+#	define DS1308_BIT_BBCLK		0x04
 #	define DS1307_BIT_RS1		0x02
 #	define DS1307_BIT_RS0		0x01
 #define DS1337_REG_CONTROL	0x0e
@@ -288,6 +291,7 @@ static int ds1307_probe(struct device_d *dev)
 	int			tmp;
 	unsigned char		*buf;
 	unsigned long driver_data;
+	const struct device_node *np = dev->device_node;
 
 	ds1307 = xzalloc(sizeof(struct ds1307));
 
@@ -377,6 +381,45 @@ read_rtc:
 		goto exit;
 	}
 
+	/* Configure clock using OF data if available */
+	if (IS_ENABLED(CONFIG_OFDEVICE) && np) {
+		u8 control = ds1307->regs[DS1307_REG_CONTROL];
+		u32 rate = 0;
+
+		if (of_property_read_bool(np, "ext-clock-input"))
+			control |= DS1308_BIT_ECLK;
+		else
+			control &= ~DS1308_BIT_ECLK;
+
+		if (of_property_read_bool(np, "ext-clock-output"))
+			control |= DS1307_BIT_SQWE;
+		else
+			control &= ~DS1307_BIT_SQWE;
+
+		if (of_property_read_bool(np, "ext-clock-bb"))
+			control |= DS1308_BIT_BBCLK;
+		else
+			control &= ~DS1308_BIT_BBCLK;
+
+		control &= ~(DS1307_BIT_RS1 | DS1307_BIT_RS0);
+		of_property_read_u32(np, "ext-clock-rate", &rate);
+		switch (rate) {
+			default:
+			case 1:     control |= 0; break;
+			case 50:    control |= 1; break;
+			case 60:    control |= 2; break;
+			case 4096:  control |= 1; break;
+			case 8192:  control |= 2; break;
+			case 32768: control |= 3; break;
+		}
+		dev_dbg(&client->dev, "control reg: 0x%02x\n", control);
+
+		if (ds1307->regs[DS1307_REG_CONTROL] != control) {
+			i2c_smbus_write_byte_data(client, DS1307_REG_CONTROL, control);
+			ds1307->regs[DS1307_REG_CONTROL]  = control;
+		}
+	}
+
 	/*
 	 * minimal sanity checking; some chips (like DS1340) don't
 	 * specify the extra bits as must-be-zero, but there are
-- 
2.7.0.25.gfc10eb5.dirty


_______________________________________________
barebox mailing list
barebox@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/barebox



[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux