diff --git a/Documentation/devicetree/bindings/rtc/dallas,ds1307.rst b/Documentation/devicetree/bindings/rtc/dallas,ds1307.rst new file mode 100644 index 0000000..602f74b --- /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 @@ * 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 @@ 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 @@ 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