Commit 5909b87d authored by Trent Piepho's avatar Trent Piepho Committed by Alexandre Belloni

rtc: isl1208: Support more chip variations

Add more support in the driver for dealing with differences in is1208
compatible chips.  Put the 1208, 1209, 1218, and 1219 in the list and
encode information about nvram size, tamper, and timestamp features.

This adds support for the isl1209, which has a tamper detect but no
timestamp feature.

Cc: Alessandro Zummo <a.zummo@towertech.it>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: default avatarTrent Piepho <tpiepho@impinj.com>
Signed-off-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
parent ed3c52a0
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/bcd.h> #include <linux/bcd.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/rtc.h> #include <linux/rtc.h>
...@@ -73,15 +74,49 @@ ...@@ -73,15 +74,49 @@
static struct i2c_driver isl1208_driver; static struct i2c_driver isl1208_driver;
/* ISL1208 various variants */ /* ISL1208 various variants */
enum { enum isl1208_id {
TYPE_ISL1208 = 0, TYPE_ISL1208 = 0,
TYPE_ISL1209,
TYPE_ISL1218, TYPE_ISL1218,
TYPE_ISL1219, TYPE_ISL1219,
ISL_LAST_ID
}; };
/* Chip capabilities table */
static const struct isl1208_config {
const char name[8];
unsigned int nvmem_length;
unsigned has_tamper:1;
unsigned has_timestamp:1;
} isl1208_configs[] = {
[TYPE_ISL1208] = { "isl1208", 2, false, false },
[TYPE_ISL1209] = { "isl1209", 2, true, false },
[TYPE_ISL1218] = { "isl1218", 8, false, false },
[TYPE_ISL1219] = { "isl1219", 2, true, true },
};
static const struct i2c_device_id isl1208_id[] = {
{ "isl1208", TYPE_ISL1208 },
{ "isl1209", TYPE_ISL1209 },
{ "isl1218", TYPE_ISL1218 },
{ "isl1219", TYPE_ISL1219 },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl1208_id);
static const struct of_device_id isl1208_of_match[] = {
{ .compatible = "isil,isl1208", .data = &isl1208_configs[TYPE_ISL1208] },
{ .compatible = "isil,isl1209", .data = &isl1208_configs[TYPE_ISL1209] },
{ .compatible = "isil,isl1218", .data = &isl1208_configs[TYPE_ISL1218] },
{ .compatible = "isil,isl1219", .data = &isl1208_configs[TYPE_ISL1219] },
{ }
};
MODULE_DEVICE_TABLE(of, isl1208_of_match);
/* Device state */ /* Device state */
struct isl1208_state { struct isl1208_state {
struct rtc_device *rtc; struct rtc_device *rtc;
const struct isl1208_config *config;
}; };
/* block read */ /* block read */
...@@ -602,11 +637,12 @@ isl1208_rtc_interrupt(int irq, void *data) ...@@ -602,11 +637,12 @@ isl1208_rtc_interrupt(int irq, void *data)
return err; return err;
} }
if (sr & ISL1208_REG_SR_EVT) { if (isl1208->config->has_tamper && (sr & ISL1208_REG_SR_EVT)) {
sysfs_notify(&isl1208->rtc->dev.kobj, NULL,
dev_attr_timestamp0.attr.name);
dev_warn(&client->dev, "event detected"); dev_warn(&client->dev, "event detected");
handled = 1; handled = 1;
if (isl1208->config->has_timestamp)
sysfs_notify(&isl1208->rtc->dev.kobj, NULL,
dev_attr_timestamp0.attr.name);
} }
return handled ? IRQ_HANDLED : IRQ_NONE; return handled ? IRQ_HANDLED : IRQ_NONE;
...@@ -743,6 +779,17 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -743,6 +779,17 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
return -ENOMEM; return -ENOMEM;
i2c_set_clientdata(client, isl1208); i2c_set_clientdata(client, isl1208);
/* Determine which chip we have */
if (client->dev.of_node) {
isl1208->config = of_device_get_match_data(&client->dev);
if (!isl1208->config)
return -ENODEV;
} else {
if (id->driver_data >= ISL_LAST_ID)
return -ENODEV;
isl1208->config = &isl1208_configs[id->driver_data];
}
isl1208->rtc = devm_rtc_allocate_device(&client->dev); isl1208->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(isl1208->rtc)) if (IS_ERR(isl1208->rtc))
return PTR_ERR(isl1208->rtc); return PTR_ERR(isl1208->rtc);
...@@ -759,7 +806,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -759,7 +806,7 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_warn(&client->dev, "rtc power failure detected, " dev_warn(&client->dev, "rtc power failure detected, "
"please set clock.\n"); "please set clock.\n");
if (id->driver_data == TYPE_ISL1219) { if (isl1208->config->has_tamper) {
struct device_node *np = client->dev.of_node; struct device_node *np = client->dev.of_node;
u32 evienb; u32 evienb;
...@@ -780,10 +827,12 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -780,10 +827,12 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
dev_err(&client->dev, "could not enable tamper detection\n"); dev_err(&client->dev, "could not enable tamper detection\n");
return rc; return rc;
} }
evdet_irq = of_irq_get_byname(np, "evdet");
}
if (isl1208->config->has_timestamp) {
rc = rtc_add_group(isl1208->rtc, &isl1219_rtc_sysfs_files); rc = rtc_add_group(isl1208->rtc, &isl1219_rtc_sysfs_files);
if (rc) if (rc)
return rc; return rc;
evdet_irq = of_irq_get_byname(np, "evdet");
} }
rc = rtc_add_group(isl1208->rtc, &isl1208_rtc_sysfs_files); rc = rtc_add_group(isl1208->rtc, &isl1208_rtc_sysfs_files);
...@@ -803,22 +852,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id) ...@@ -803,22 +852,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
return rtc_register_device(isl1208->rtc); return rtc_register_device(isl1208->rtc);
} }
static const struct i2c_device_id isl1208_id[] = {
{ "isl1208", TYPE_ISL1208 },
{ "isl1218", TYPE_ISL1218 },
{ "isl1219", TYPE_ISL1219 },
{ }
};
MODULE_DEVICE_TABLE(i2c, isl1208_id);
static const struct of_device_id isl1208_of_match[] = {
{ .compatible = "isil,isl1208" },
{ .compatible = "isil,isl1218" },
{ .compatible = "isil,isl1219" },
{ }
};
MODULE_DEVICE_TABLE(of, isl1208_of_match);
static struct i2c_driver isl1208_driver = { static struct i2c_driver isl1208_driver = {
.driver = { .driver = {
.name = "rtc-isl1208", .name = "rtc-isl1208",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment