Skip to content

Instantly share code, notes, and snippets.

@tomaskrcka
Created July 10, 2015 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tomaskrcka/a6279f8cd9ba6acc758c to your computer and use it in GitHub Desktop.
Save tomaskrcka/a6279f8cd9ba6acc758c to your computer and use it in GitHub Desktop.
Kernel 3.2 rtc patch for rv4162c7 to check battery status
diff -rupN linux-3.2.orig//drivers/rtc/rtc-m41t80.c linux-3.2.new//drivers/rtc/rtc-m41t80.c
--- linux-3.2.orig//drivers/rtc/rtc-m41t80.c 2014-03-06 09:23:32.842957166 +0100
+++ linux-3.2.new//drivers/rtc/rtc-m41t80.c 2014-03-06 14:40:31.250580900 +0100
@@ -59,15 +59,17 @@
#define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */
#define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */
#define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */
+#define M41T80_FLAG_OSCI_FAIL (1 << 2) /* Osci fail bit */
#define M41T80_FEATURE_HT (1 << 0) /* Halt feature */
#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
+#define M41T80_FEATURE_OSCI (1 << 5) /* Osci fail flag */
#define DRV_NAME "rtc-m41t80"
-#define DRV_VERSION "0.05"
+#define DRV_VERSION "0.06"
static DEFINE_MUTEX(m41t80_rtc_mutex);
static const struct i2c_device_id m41t80_id[] = {
@@ -81,11 +83,19 @@ static const struct i2c_device_id m41t80
{ "m41st84", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
{ "m41st85", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
{ "m41st87", M41T80_FEATURE_HT | M41T80_FEATURE_BL | M41T80_FEATURE_SQ },
- { "rv4162c7", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
+ { "rv4162c7", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT | M41T80_FEATURE_OSCI },
{ }
};
MODULE_DEVICE_TABLE(i2c, m41t80_id);
+static struct rtc_time default_time = {
+ .tm_year = 70,
+ .tm_mon = 0,
+ .tm_mday = 1,
+ .tm_hour = 1,
+ .tm_min = 0,
+};
+
struct m41t80_data {
u8 features;
struct rtc_device *rtc;
@@ -865,6 +875,35 @@ static int m41t80_probe(struct i2c_clien
rc & ~M41T80_ALHOUR_HT) < 0)
goto ht_err;
}
+
+ if (clientdata->features & M41T80_FEATURE_OSCI) {
+ rc = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
+ if (rc < 0)
+ goto st_err;
+
+ if (rc & M41T80_FLAG_OSCI_FAIL) {
+ dev_warn(&client->dev,
+ "Oscillator Failure. Check RTC battery. " \
+ "Time has been set to default\n");
+ m41t80_set_datetime(client, &default_time);
+ if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
+ rc & ~M41T80_FLAG_OSCI_FAIL) < 0)
+ goto st_err;
+
+ rc = i2c_smbus_read_byte_data(client,
+ M41T80_REG_FLAGS);
+ if (rc < 0)
+ goto st_err;
+ if (rc & M41T80_FLAG_OSCI_FAIL) {
+ dev_warn(&client->dev,
+ "OF bit is still set, kickstarting clock.\n");
+ rc = i2c_smbus_read_byte_data(client,
+ M41T80_REG_SEC);
+ i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
+ rc | M41T80_SEC_ST);
+ }
+ }
+ }
/* Make sure ST (stop) bit is cleared */
rc = i2c_smbus_read_byte_data(client, M41T80_REG_SEC);
@@ -872,10 +911,12 @@ static int m41t80_probe(struct i2c_clien
goto st_err;
if (rc & M41T80_SEC_ST) {
+ dev_info(&client->dev, "Stop bit was set!\n");
if (i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
rc & ~M41T80_SEC_ST) < 0)
goto st_err;
}
+
rc = m41t80_sysfs_register(&client->dev);
if (rc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment