configure ds1307 driver for m41t00 rtc using device tree overlays

I’m trying to get a M41T00 RTC up on a custom cape using Angstrom and kernel 3.8.13. The DS1307 is well supported and the adafruit rtc cape dts file has an example device tree overlay fragment which looks like this:

fragment@0 {
target = <&i2c2>;

overlay {
/* shut up DTC warnings */
#address-cells = <1>;
#size-cells = <0>;

/* DS1307 RTC module */
rtc@68 {
compatible = “dallas,ds1307”;
reg = <0x68>;
};
};
};

After looking at the rtc-ds1307.c module source, I see that there is a type enumeration with a m41t00 entry which tweaks certain operations in the module. My question is how do I communicate this option using device tree overlays?

Will something like this work?

fragment@0 {
target = <&i2c2>;

overlay {
/* shut up DTC warnings */
#address-cells = <1>;
#size-cells = <0>;

/* M41T00 RTC module */
rtc@68 {
compatible = “dallas,ds1307”;
reg = <0x68>;
ds_type = “m41t00”;
};
};
};

Thanks!

–David

Ok, I figured it out. The rtc-1307 kernel driver takes care of a list of devices, all specified in the i2c_device_id struct:

`


static const struct i2c_device_id ds1307_id[] = {
       { "ds1307", ds_1307 },
  { "ds1337", ds_1337 },
  { "ds1338", ds_1338 },
  { "ds1339", ds_1339 },
  { "ds1388", ds_1388 },
  { "ds1340", ds_1340 },
  { "ds3231", ds_3231 },
  { "m41t00", m41t00 },
   { "mcp7941x", mcp7941x },
       { "pt7c4338", ds_1307 },
        { "rx8025", rx_8025 },
  { }
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);

`

So, using Device Trees, you can specify any one of those literal strings using the compatible property, and the kernel will know that the rtc-ds1307 driver handles it. Here is the fragment that I used to get a ST M41T00S working on I2C2:

`
fragment@5 {
target = <&i2c2>;
overlay {
/* Properties taken from am33xx.dtsi */
#address-cells = <1>;
#size-cells = <0>;

/* M41T00 RTC module */
gptu_rtc_m41t00: rtc@68 {
compatible = “st,m41t00”;
reg = <0x68>;
};
};
};

`

Note that the compatible property has the general syntax of “manufacturer,device”, and as far as I could tell, the manufacturer field is ignored. I used “dallas,m41t00” and “st,m41t00” and both worked without any noticeable differences.

You can verify that things are working correctly by observing dmesg output. The device rtc1 should be mentioned if the driver found the device on the bus correctly.

Once this was all working, I was still getting an error while trying to read the RTC:

`
hwclock -r -f /dev/rtc1
hwclock: RTC_RD_TIME: Invalid argument

`

This was due to the fact that the RTC had not been initialized with correct values, so the date/time bytes being read were invalid. I fixed it by setting the system time to a correct value and then pushing that to the RTC.

`
date -s 2013.07.25-23:39:30
hwclock -w -f /dev/rtc1

`

I hope someone else finds this helpful!

–David