|
@@ -17,9 +17,11 @@
|
|
|
#define DEVICE_DS1307 1
|
|
|
#define DEVICE_DS1337 2
|
|
|
|
|
|
+#define DS1307_SEC 0x00
|
|
|
#define DS1307_MAX_ADDR 0x3F
|
|
|
|
|
|
#define DS1337_CTL 0x0E
|
|
|
+#define DS1337_STAT 0x0F
|
|
|
|
|
|
static int model_detected;
|
|
|
|
|
@@ -75,12 +77,45 @@ static int ds13307_detect_device(struct i2c_client *client) {
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+/* The oscillator is stopped for both chips when power is first applied,
|
|
|
+ * therefore this function checks its status and clears the stop bit.
|
|
|
+ */
|
|
|
+static int ds13307_start_oscillator(struct i2c_client *client) {
|
|
|
+ u8 data;
|
|
|
+ int r, v;
|
|
|
+ unsigned char addr;
|
|
|
+ char buf[2];
|
|
|
+ if (model_detected == DEVICE_DS1307) {
|
|
|
+ addr = DS1307_SEC;
|
|
|
+ } else {
|
|
|
+ addr = DS1337_STAT;
|
|
|
+ }
|
|
|
+ r = ds13307_read_single_byte(client, &addr, &data);
|
|
|
+ if (data & 0x80) {
|
|
|
+ buf[0] = addr;
|
|
|
+ buf[1] = data ^ 0x80;
|
|
|
+ v = i2c_master_send(client, buf, 2);
|
|
|
+ } else {
|
|
|
+ v = 2;
|
|
|
+ }
|
|
|
+ if ((r<0) || (v!=2)) {
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int ds13307_probe(struct i2c_client *client,
|
|
|
const struct i2c_device_id *id) {
|
|
|
model_detected = ds13307_detect_device(client);
|
|
|
if ((model_detected != DEVICE_DS1307) && (model_detected != DEVICE_DS1337)) {
|
|
|
return -EIO;
|
|
|
}
|
|
|
+ if (ds13307_start_oscillator(client)) {
|
|
|
+ printk(KERN_ERR "%s: failed to initialize the oscillator\n", M_NAME);
|
|
|
+ return -EIO;
|
|
|
+ } else {
|
|
|
+ printk(KERN_DEBUG "%s: oscillator stop bit successfully cleared\n", M_NAME);
|
|
|
+ }
|
|
|
return 0;
|
|
|
}
|
|
|
|