#include <linux/bcd.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/rtc.h>
#define ISL1208_REG_SC …
#define ISL1208_REG_MN …
#define ISL1208_REG_HR …
#define ISL1208_REG_HR_MIL …
#define ISL1208_REG_HR_PM …
#define ISL1208_REG_DT …
#define ISL1208_REG_MO …
#define ISL1208_REG_YR …
#define ISL1208_REG_DW …
#define ISL1208_RTC_SECTION_LEN …
#define ISL1208_REG_SR …
#define ISL1208_REG_SR_ARST …
#define ISL1208_REG_SR_XTOSCB …
#define ISL1208_REG_SR_WRTC …
#define ISL1208_REG_SR_EVT …
#define ISL1208_REG_SR_ALM …
#define ISL1208_REG_SR_BAT …
#define ISL1208_REG_SR_RTCF …
#define ISL1208_REG_INT …
#define ISL1208_REG_INT_ALME …
#define ISL1208_REG_INT_IM …
#define ISL1219_REG_EV …
#define ISL1219_REG_EV_EVEN …
#define ISL1219_REG_EV_EVIENB …
#define ISL1208_REG_ATR …
#define ISL1208_REG_DTR …
#define ISL1208_REG_SCA …
#define ISL1208_REG_MNA …
#define ISL1208_REG_HRA …
#define ISL1208_REG_DTA …
#define ISL1208_REG_MOA …
#define ISL1208_REG_DWA …
#define ISL1208_ALARM_SECTION_LEN …
#define ISL1208_REG_USR1 …
#define ISL1208_REG_USR2 …
#define ISL1208_USR_SECTION_LEN …
#define ISL1219_REG_SCT …
#define ISL1219_REG_MNT …
#define ISL1219_REG_HRT …
#define ISL1219_REG_DTT …
#define ISL1219_REG_MOT …
#define ISL1219_REG_YRT …
#define ISL1219_EVT_SECTION_LEN …
static struct i2c_driver isl1208_driver;
struct isl1208_config { … };
static const struct isl1208_config config_isl1208 = …;
static const struct isl1208_config config_isl1209 = …;
static const struct isl1208_config config_isl1218 = …;
static const struct isl1208_config config_isl1219 = …;
static const struct isl1208_config config_raa215300_a0 = …;
static const struct i2c_device_id isl1208_id[] = …;
MODULE_DEVICE_TABLE(i2c, isl1208_id);
static const __maybe_unused struct of_device_id isl1208_of_match[] = …;
MODULE_DEVICE_TABLE(of, isl1208_of_match);
struct isl1208_state { … };
static int
isl1208_i2c_read_regs(struct i2c_client *client, u8 reg, u8 buf[],
unsigned len)
{ … }
static int
isl1208_i2c_set_regs(struct i2c_client *client, u8 reg, u8 const buf[],
unsigned len)
{ … }
static int
isl1208_i2c_validate_client(struct i2c_client *client)
{ … }
static int isl1208_set_xtoscb(struct i2c_client *client, int sr, int xtosb_val)
{ … }
static int
isl1208_i2c_get_sr(struct i2c_client *client)
{ … }
static int
isl1208_i2c_get_atr(struct i2c_client *client)
{ … }
static int
isl1208_i2c_get_dtr(struct i2c_client *client)
{ … }
static int
isl1208_i2c_get_usr(struct i2c_client *client)
{ … }
static int
isl1208_i2c_set_usr(struct i2c_client *client, u16 usr)
{ … }
static int
isl1208_rtc_toggle_alarm(struct i2c_client *client, int enable)
{ … }
static int
isl1208_rtc_proc(struct device *dev, struct seq_file *seq)
{ … }
static int
isl1208_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
{ … }
static int
isl1208_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
{ … }
static int
isl1208_i2c_set_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
{ … }
static int
isl1208_rtc_read_time(struct device *dev, struct rtc_time *tm)
{ … }
static int
isl1208_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
{ … }
static int
isl1208_rtc_set_time(struct device *dev, struct rtc_time *tm)
{ … }
static int
isl1208_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ … }
static int
isl1208_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{ … }
static ssize_t timestamp0_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev->parent);
int sr;
sr = isl1208_i2c_get_sr(client);
if (sr < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
return sr;
}
sr &= ~ISL1208_REG_SR_EVT;
sr = i2c_smbus_write_byte_data(client, ISL1208_REG_SR, sr);
if (sr < 0)
dev_err(dev, "%s: writing SR failed\n",
__func__);
return count;
};
static ssize_t timestamp0_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev->parent);
u8 regs[ISL1219_EVT_SECTION_LEN] = { 0, };
struct rtc_time tm;
int sr;
sr = isl1208_i2c_get_sr(client);
if (sr < 0) {
dev_err(dev, "%s: reading SR failed\n", __func__);
return sr;
}
if (!(sr & ISL1208_REG_SR_EVT))
return 0;
sr = isl1208_i2c_read_regs(client, ISL1219_REG_SCT, regs,
ISL1219_EVT_SECTION_LEN);
if (sr < 0) {
dev_err(dev, "%s: reading event section failed\n",
__func__);
return 0;
}
tm.tm_sec = bcd2bin(regs[ISL1219_REG_SCT - ISL1219_REG_SCT] & 0x7f);
tm.tm_min = bcd2bin(regs[ISL1219_REG_MNT - ISL1219_REG_SCT] & 0x7f);
tm.tm_hour = bcd2bin(regs[ISL1219_REG_HRT - ISL1219_REG_SCT] & 0x3f);
tm.tm_mday = bcd2bin(regs[ISL1219_REG_DTT - ISL1219_REG_SCT] & 0x3f);
tm.tm_mon =
bcd2bin(regs[ISL1219_REG_MOT - ISL1219_REG_SCT] & 0x1f) - 1;
tm.tm_year = bcd2bin(regs[ISL1219_REG_YRT - ISL1219_REG_SCT]) + 100;
sr = rtc_valid_tm(&tm);
if (sr)
return sr;
return sprintf(buf, "%llu\n",
(unsigned long long)rtc_tm_to_time64(&tm));
};
static DEVICE_ATTR_RW(timestamp0);
static irqreturn_t
isl1208_rtc_interrupt(int irq, void *data)
{ … }
static const struct rtc_class_ops isl1208_rtc_ops = …;
static ssize_t
isl1208_sysfs_show_atrim(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR(atrim, S_IRUGO, isl1208_sysfs_show_atrim, NULL);
static ssize_t
isl1208_sysfs_show_dtrim(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static DEVICE_ATTR(dtrim, S_IRUGO, isl1208_sysfs_show_dtrim, NULL);
static ssize_t
isl1208_sysfs_show_usr(struct device *dev,
struct device_attribute *attr, char *buf)
{ … }
static ssize_t
isl1208_sysfs_store_usr(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{ … }
static DEVICE_ATTR(usr, S_IRUGO | S_IWUSR, isl1208_sysfs_show_usr,
isl1208_sysfs_store_usr);
static struct attribute *isl1208_rtc_attrs[] = …;
static const struct attribute_group isl1208_rtc_sysfs_files = …;
static struct attribute *isl1219_rtc_attrs[] = …;
static const struct attribute_group isl1219_rtc_sysfs_files = …;
static int isl1208_nvmem_read(void *priv, unsigned int off, void *buf,
size_t count)
{ … }
static int isl1208_nvmem_write(void *priv, unsigned int off, void *buf,
size_t count)
{ … }
static const struct nvmem_config isl1208_nvmem_config = …;
static int isl1208_setup_irq(struct i2c_client *client, int irq)
{ … }
static int
isl1208_clk_present(struct i2c_client *client, const char *name)
{ … }
static int
isl1208_probe(struct i2c_client *client)
{ … }
static struct i2c_driver isl1208_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;