summaryrefslogtreecommitdiffstats
path: root/drivers/rtc
diff options
context:
space:
mode:
authorTrent Piepho <tpiepho@kymetacorp.com>2016-05-19 23:39:32 +0000
committerSascha Hauer <s.hauer@pengutronix.de>2016-05-30 07:12:19 +0200
commit24fcf5fceec8a3af9fab21f2ba702da08ba7c430 (patch)
treeb83db8ef00cb564dc26e720fd11ae725212c9de5 /drivers/rtc
parent61ddbd35207af8dbd9b1a0c17619148179235203 (diff)
downloadbarebox-24fcf5fceec8a3af9fab21f2ba702da08ba7c430.tar.gz
barebox-24fcf5fceec8a3af9fab21f2ba702da08ba7c430.tar.xz
rtc: ds1307: Add support for configuring external clock pin
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@kymetacorp.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/rtc')
-rw-r--r--drivers/rtc/rtc-ds1307.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index ca630ea971..73d88ba6f2 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