|
@@ -49,24 +49,11 @@ static struct regmap_config regmap_config = {
|
|
|
};
|
|
|
|
|
|
/* Reads a specified number of bytes via i2c, returns 0 on success */
|
|
|
-static int ds13307_read_bytes(struct i2c_client *client,
|
|
|
+static int ds13307_read_bytes(struct regmap *regmap,
|
|
|
u8 *addr, u8 *bytes, int length) {
|
|
|
int r;
|
|
|
- struct i2c_msg msgs[] = {
|
|
|
- {
|
|
|
- .addr = client->addr,
|
|
|
- .len = 1,
|
|
|
- .buf = addr
|
|
|
- },
|
|
|
- {
|
|
|
- .addr = client->addr,
|
|
|
- .flags = I2C_M_RD,
|
|
|
- .len = length,
|
|
|
- .buf = bytes
|
|
|
- }
|
|
|
- };
|
|
|
- r = i2c_transfer(client->adapter, msgs, 2);
|
|
|
- if (r == 2) {
|
|
|
+ r = regmap_bulk_read(regmap, (*addr), bytes, length);
|
|
|
+ if (r == length) {
|
|
|
return 0;
|
|
|
} else {
|
|
|
return r;
|
|
@@ -74,24 +61,11 @@ static int ds13307_read_bytes(struct i2c_client *client,
|
|
|
}
|
|
|
|
|
|
/* Writes a specified number of bytes via 2ic, returns 0 on success */
|
|
|
-static int ds13307_write_bytes(struct i2c_client *client,
|
|
|
+static int ds13307_write_bytes(struct regmap *regmap,
|
|
|
u8 *addr, u8 *bytes, int length) {
|
|
|
int r;
|
|
|
- u8 *buf;
|
|
|
- struct i2c_msg msg;
|
|
|
- buf = (u8*) kmalloc(length +1, GFP_KERNEL);
|
|
|
- if (buf == NULL) {
|
|
|
- printk(KERN_ERR "%s: Could not allocate memory for buffer\n", M_NAME);
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
- buf[0] = (*addr);
|
|
|
- memmove(buf + 1, bytes, length);
|
|
|
- msg.addr = client->addr;
|
|
|
- msg.len = length + 1;
|
|
|
- msg.buf = buf;
|
|
|
- r = i2c_transfer(client->adapter, &msg, 1);
|
|
|
- kfree(buf);
|
|
|
- if (r == 1) {
|
|
|
+ r = regmap_bulk_write(regmap, (*addr), bytes, length);
|
|
|
+ if (r == length) {
|
|
|
return 0;
|
|
|
} else {
|
|
|
return r;
|
|
@@ -101,7 +75,7 @@ static int ds13307_write_bytes(struct i2c_client *client,
|
|
|
/* 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) {
|
|
|
+static int ds13307_start_oscillator(struct regmap *regmap) {
|
|
|
u8 data, addr, buf;
|
|
|
int r, v = 0;
|
|
|
if (model_detected == DEVICE_DS1307) {
|
|
@@ -109,10 +83,10 @@ static int ds13307_start_oscillator(struct i2c_client *client) {
|
|
|
} else {
|
|
|
addr = DS1337_STAT;
|
|
|
}
|
|
|
- r = ds13307_read_bytes(client, &addr, &data, 1);
|
|
|
+ r = ds13307_read_bytes(regmap, &addr, &data, 1);
|
|
|
if (data & COMMON_HIGH_BIT) {
|
|
|
buf = data ^ COMMON_HIGH_BIT;
|
|
|
- v = ds13307_write_bytes(client, &addr, &buf, 1);
|
|
|
+ v = ds13307_write_bytes(regmap, &addr, &buf, 1);
|
|
|
if (!v) {
|
|
|
printk(KERN_DEBUG "%s: oscillator stop bit successfully cleared\n", M_NAME);
|
|
|
}
|
|
@@ -138,15 +112,15 @@ static int ds13307_check_12h_am_pm(u8 *byte) {
|
|
|
}
|
|
|
|
|
|
static int ds13307_read_time(struct device *dev, struct rtc_time *time) {
|
|
|
- struct i2c_client *client;
|
|
|
+ struct regmap *regmap;
|
|
|
int r, century = 1, h12 = 0;
|
|
|
u8 buf[7], stopbit;
|
|
|
u8 addr = COMMON_SEC;
|
|
|
- client = to_i2c_client(dev);
|
|
|
- r = ds13307_read_bytes(client, &addr, buf, 7);
|
|
|
+ regmap = dev_get_drvdata(dev);
|
|
|
+ r = ds13307_read_bytes(regmap, &addr, buf, 7);
|
|
|
if (model_detected == DEVICE_DS1337) {
|
|
|
addr = DS1337_STAT;
|
|
|
- r = ds13307_read_bytes(client, &addr, &stopbit, 1);
|
|
|
+ r = ds13307_read_bytes(regmap, &addr, &stopbit, 1);
|
|
|
stopbit = stopbit & COMMON_HIGH_BIT;
|
|
|
} else {
|
|
|
stopbit = buf[COMMON_SEC] & COMMON_HIGH_BIT;
|
|
@@ -182,10 +156,10 @@ static int ds13307_read_time(struct device *dev, struct rtc_time *time) {
|
|
|
}
|
|
|
|
|
|
static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
|
|
|
- struct i2c_client *client;
|
|
|
+ struct regmap *regmap;
|
|
|
u8 buf[7], addr;
|
|
|
- client = to_i2c_client(dev);
|
|
|
- if (ds13307_start_oscillator(client)) {
|
|
|
+ regmap = dev_get_drvdata(dev);
|
|
|
+ if (ds13307_start_oscillator(regmap)) {
|
|
|
printk(KERN_ERR "%s: failed to initialize the oscillator\n", M_NAME);
|
|
|
return -EIO;
|
|
|
}
|
|
@@ -204,7 +178,7 @@ static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
|
|
|
buf[5] = bin2bcd(time->tm_mon + 1);
|
|
|
}
|
|
|
buf[6] = bin2bcd(time->tm_year % 100);
|
|
|
- if(ds13307_write_bytes(client, &addr, buf, 7)) {
|
|
|
+ if(ds13307_write_bytes(regmap, &addr, buf, 7)) {
|
|
|
return -EIO;
|
|
|
}
|
|
|
return 0;
|
|
@@ -212,11 +186,11 @@ static int ds13307_set_time(struct device *dev, struct rtc_time *time) {
|
|
|
}
|
|
|
|
|
|
static int ds13307_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
- struct i2c_client *client;
|
|
|
+ struct regmap *regmap;
|
|
|
u8 buf[9], addr = DS1337_ALRM1;
|
|
|
int h12;
|
|
|
- client = to_i2c_client(dev);
|
|
|
- if (!ds13307_read_bytes(client, &addr, buf, 9)) {
|
|
|
+ regmap = dev_get_drvdata(dev);
|
|
|
+ if (!ds13307_read_bytes(regmap, &addr, buf, 9)) {
|
|
|
// select for A1IE bit
|
|
|
alarm->enabled = buf[7] & 0x01;
|
|
|
// select for A1F bit
|
|
@@ -243,10 +217,10 @@ static int ds13307_read_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
|
|
|
/* Sets the alarm to the values passed to the function */
|
|
|
static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
- struct i2c_client *client;
|
|
|
+ struct regmap *regmap;
|
|
|
u8 buf[9], addr = DS1337_ALRM1;
|
|
|
- client = to_i2c_client(dev);
|
|
|
- if(!ds13307_read_bytes(client, &addr, buf, 9)) {
|
|
|
+ regmap = dev_get_drvdata(dev);
|
|
|
+ if(!ds13307_read_bytes(regmap, &addr, buf, 9)) {
|
|
|
// enable or disable the alarm as requested
|
|
|
if ((alarm->enabled && (!(buf[7] & 0x01))) || ((!alarm->enabled && (buf[7] & 0x01)))) {
|
|
|
buf[7] ^= 0x01;
|
|
@@ -263,7 +237,7 @@ static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
buf[1] = bin2bcd(alarm->time.tm_min);
|
|
|
buf[2] = bin2bcd(alarm->time.tm_hour);
|
|
|
buf[3] = bin2bcd(alarm->time.tm_mday);
|
|
|
- if(!ds13307_write_bytes(client, &addr, buf, 9)) {
|
|
|
+ if(!ds13307_write_bytes(regmap, &addr, buf, 9)) {
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
@@ -271,16 +245,16 @@ static int ds13307_write_alarm(struct device *dev, struct rtc_wkalrm *alarm) {
|
|
|
}
|
|
|
|
|
|
static int ds13307_alarm_irq_enable(struct device *dev, unsigned int enabled) {
|
|
|
- struct i2c_client *client;
|
|
|
+ struct regmap *regmap;
|
|
|
u8 buf, addr = DS1337_CTL;
|
|
|
- client = to_i2c_client(dev);
|
|
|
- if (ds13307_read_bytes(client, &addr, &buf, 1)) {
|
|
|
+ regmap = dev_get_drvdata(dev);
|
|
|
+ if (ds13307_read_bytes(regmap, &addr, &buf, 1)) {
|
|
|
return -EIO;
|
|
|
}
|
|
|
if ((!enabled && (buf & 0x01)) || (enabled & (!(buf & 0x01)))) {
|
|
|
buf ^= 0x01;
|
|
|
}
|
|
|
- if(!ds13307_write_bytes(client, &addr, &buf, 1)) {
|
|
|
+ if(!ds13307_write_bytes(regmap, &addr, &buf, 1)) {
|
|
|
return 0;
|
|
|
}
|
|
|
return -EIO;
|
|
@@ -288,13 +262,13 @@ static int ds13307_alarm_irq_enable(struct device *dev, unsigned int enabled) {
|
|
|
|
|
|
/* Reads the alarm bit and copies it to userspace */
|
|
|
static int ds13307_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) {
|
|
|
- struct i2c_client *client;
|
|
|
+ struct regmap *regmap;
|
|
|
u8 addr, buf;
|
|
|
switch(cmd) {
|
|
|
case IOCTL_DS13307_ALRM:
|
|
|
addr = DS1337_STAT;
|
|
|
- client = to_i2c_client(dev);
|
|
|
- if (ds13307_read_bytes(client, &addr, &buf, 1)) {
|
|
|
+ regmap = dev_get_drvdata(dev);
|
|
|
+ if (ds13307_read_bytes(regmap, &addr, &buf, 1)) {
|
|
|
return -EIO;
|
|
|
}
|
|
|
buf &= 0x01;
|
|
@@ -316,22 +290,22 @@ static struct rtc_class_ops ds13307_rtc_ops = {
|
|
|
* DS1307 and DS1337 chips. Returns the defined device ID or
|
|
|
* -1 on failure
|
|
|
*/
|
|
|
-static int ds13307_detect_device(struct i2c_client *client) {
|
|
|
+static int ds13307_detect_device(struct regmap *regmap) {
|
|
|
u8 data, addr = DS1307_MAX_ADDR;
|
|
|
int result;
|
|
|
- result = ds13307_read_bytes(client, &addr, &data, 1);
|
|
|
+ result = ds13307_read_bytes(regmap, &addr, &data, 1);
|
|
|
if (!result) {
|
|
|
printk(KERN_INFO "%s: Detected device DS1307\n", M_NAME);
|
|
|
return DEVICE_DS1307;
|
|
|
}
|
|
|
addr = DS1337_CTL;
|
|
|
- result = ds13307_read_bytes(client, &addr, &data, 1);
|
|
|
+ result = ds13307_read_bytes(regmap, &addr, &data, 1);
|
|
|
if (!result) {
|
|
|
printk(KERN_INFO "%s: Detected device DS1337\n", M_NAME);
|
|
|
return DEVICE_DS1337;
|
|
|
}
|
|
|
printk(KERN_ERR "%s: Could not talk to I2C device at addr %x, is it connected?\n",
|
|
|
- M_NAME, client->addr);
|
|
|
+ M_NAME, 0x68);
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
@@ -350,7 +324,11 @@ static int ds13307_probe(struct i2c_client *client,
|
|
|
struct rtc_device *rtc;
|
|
|
int error;
|
|
|
struct regmap * regmap;
|
|
|
- model_detected = ds13307_detect_device(client);
|
|
|
+ regmap = devm_regmap_init_i2c(client, ®map_config);
|
|
|
+ if (IS_ERR(regmap)) {
|
|
|
+ return PTR_ERR(regmap);
|
|
|
+ }
|
|
|
+ model_detected = ds13307_detect_device(regmap);
|
|
|
if ((model_detected != DEVICE_DS1307) && (model_detected != DEVICE_DS1337)) {
|
|
|
return -EIO;
|
|
|
}
|
|
@@ -358,10 +336,6 @@ static int ds13307_probe(struct i2c_client *client,
|
|
|
if (IS_ERR(rtc)) {
|
|
|
return PTR_ERR(rtc);
|
|
|
}
|
|
|
- regmap = devm_regmap_init_i2c(client, ®map_config);
|
|
|
- if (IS_ERR(regmap)) {
|
|
|
- return PTR_ERR(regmap);
|
|
|
- }
|
|
|
rtc->uie_unsupported = 1;
|
|
|
device_set_wakeup_capable(&client->dev, 0);
|
|
|
client->irq = 0;
|
|
@@ -381,6 +355,7 @@ static int ds13307_probe(struct i2c_client *client,
|
|
|
}
|
|
|
rtc->ops = &ds13307_rtc_ops;
|
|
|
i2c_set_clientdata(client,rtc);
|
|
|
+ dev_set_drvdata(&client->dev, regmap);
|
|
|
error = rtc_register_device(rtc);
|
|
|
return error ? error: 0;
|
|
|
}
|