#include <linux/clk-provider.h>
#include <linux/bcd.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#define RV3028_SEC …
#define RV3028_MIN …
#define RV3028_HOUR …
#define RV3028_WDAY …
#define RV3028_DAY …
#define RV3028_MONTH …
#define RV3028_YEAR …
#define RV3028_ALARM_MIN …
#define RV3028_ALARM_HOUR …
#define RV3028_ALARM_DAY …
#define RV3028_STATUS …
#define RV3028_CTRL1 …
#define RV3028_CTRL2 …
#define RV3028_EVT_CTRL …
#define RV3028_TS_COUNT …
#define RV3028_TS_SEC …
#define RV3028_RAM1 …
#define RV3028_EEPROM_ADDR …
#define RV3028_EEPROM_DATA …
#define RV3028_EEPROM_CMD …
#define RV3028_CLKOUT …
#define RV3028_OFFSET …
#define RV3028_BACKUP …
#define RV3028_STATUS_PORF …
#define RV3028_STATUS_EVF …
#define RV3028_STATUS_AF …
#define RV3028_STATUS_TF …
#define RV3028_STATUS_UF …
#define RV3028_STATUS_BSF …
#define RV3028_STATUS_CLKF …
#define RV3028_STATUS_EEBUSY …
#define RV3028_CLKOUT_FD_MASK …
#define RV3028_CLKOUT_PORIE …
#define RV3028_CLKOUT_CLKSY …
#define RV3028_CLKOUT_CLKOE …
#define RV3028_CTRL1_EERD …
#define RV3028_CTRL1_WADA …
#define RV3028_CTRL2_RESET …
#define RV3028_CTRL2_12_24 …
#define RV3028_CTRL2_EIE …
#define RV3028_CTRL2_AIE …
#define RV3028_CTRL2_TIE …
#define RV3028_CTRL2_UIE …
#define RV3028_CTRL2_TSE …
#define RV3028_EVT_CTRL_TSR …
#define RV3028_EEPROM_CMD_UPDATE …
#define RV3028_EEPROM_CMD_WRITE …
#define RV3028_EEPROM_CMD_READ …
#define RV3028_EEBUSY_POLL …
#define RV3028_EEBUSY_TIMEOUT …
#define RV3028_BACKUP_TCE …
#define RV3028_BACKUP_TCR_MASK …
#define RV3028_BACKUP_BSM …
#define RV3028_BACKUP_BSM_DSM …
#define RV3028_BACKUP_BSM_LSM …
#define OFFSET_STEP_PPT …
enum rv3028_type { … };
struct rv3028_data { … };
static u16 rv3028_trickle_resistors[] = …;
static ssize_t timestamp0_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR,
RV3028_EVT_CTRL_TSR);
return count;
};
static ssize_t timestamp0_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
struct rtc_time tm;
int ret, count;
u8 date[6];
ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count);
if (ret)
return ret;
if (!count)
return 0;
ret = regmap_bulk_read(rv3028->regmap, RV3028_TS_SEC, date,
sizeof(date));
if (ret)
return ret;
tm.tm_sec = bcd2bin(date[0]);
tm.tm_min = bcd2bin(date[1]);
tm.tm_hour = bcd2bin(date[2]);
tm.tm_mday = bcd2bin(date[3]);
tm.tm_mon = bcd2bin(date[4]) - 1;
tm.tm_year = bcd2bin(date[5]) + 100;
ret = rtc_valid_tm(&tm);
if (ret)
return ret;
return sprintf(buf, "%llu\n",
(unsigned long long)rtc_tm_to_time64(&tm));
};
static DEVICE_ATTR_RW(timestamp0);
static ssize_t timestamp0_count_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent);
int ret, count;
ret = regmap_read(rv3028->regmap, RV3028_TS_COUNT, &count);
if (ret)
return ret;
return sprintf(buf, "%u\n", count);
};
static DEVICE_ATTR_RO(timestamp0_count);
static struct attribute *rv3028_attrs[] = …;
static const struct attribute_group rv3028_attr_group = …;
static int rv3028_exit_eerd(struct rv3028_data *rv3028, u32 eerd)
{ … }
static int rv3028_enter_eerd(struct rv3028_data *rv3028, u32 *eerd)
{ … }
static int rv3028_update_eeprom(struct rv3028_data *rv3028, u32 eerd)
{ … }
static int rv3028_update_cfg(struct rv3028_data *rv3028, unsigned int reg,
unsigned int mask, unsigned int val)
{ … }
static irqreturn_t rv3028_handle_irq(int irq, void *dev_id)
{ … }
static int rv3028_get_time(struct device *dev, struct rtc_time *tm)
{ … }
static int rv3028_set_time(struct device *dev, struct rtc_time *tm)
{ … }
static int rv3028_get_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ … }
static int rv3028_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{ … }
static int rv3028_alarm_irq_enable(struct device *dev, unsigned int enabled)
{ … }
static int rv3028_read_offset(struct device *dev, long *offset)
{ … }
static int rv3028_set_offset(struct device *dev, long offset)
{ … }
static int rv3028_param_get(struct device *dev, struct rtc_param *param)
{ … }
static int rv3028_param_set(struct device *dev, struct rtc_param *param)
{ … }
static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{ … }
static int rv3028_nvram_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{ … }
static int rv3028_nvram_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{ … }
static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val,
size_t bytes)
{ … }
static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val,
size_t bytes)
{ … }
#ifdef CONFIG_COMMON_CLK
#define clkout_hw_to_rv3028(hw) …
static int clkout_rates[] = …;
static unsigned long rv3028_clkout_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{ … }
static long rv3028_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{ … }
static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{ … }
static int rv3028_clkout_prepare(struct clk_hw *hw)
{ … }
static void rv3028_clkout_unprepare(struct clk_hw *hw)
{ … }
static int rv3028_clkout_is_prepared(struct clk_hw *hw)
{ … }
static const struct clk_ops rv3028_clkout_ops = …;
static int rv3028_clkout_register_clk(struct rv3028_data *rv3028,
struct i2c_client *client)
{ … }
#endif
static const struct rtc_class_ops rv3028_rtc_ops = …;
static const struct regmap_config regmap_config = …;
static u8 rv3028_set_trickle_charger(struct rv3028_data *rv3028,
struct i2c_client *client)
{ … }
static int rv3028_probe(struct i2c_client *client)
{ … }
static const struct acpi_device_id rv3028_i2c_acpi_match[] = …;
MODULE_DEVICE_TABLE(acpi, rv3028_i2c_acpi_match);
static const __maybe_unused struct of_device_id rv3028_of_match[] = …;
MODULE_DEVICE_TABLE(of, rv3028_of_match);
static const struct i2c_device_id rv3028_id_table[] = …;
MODULE_DEVICE_TABLE(i2c, rv3028_id_table);
static struct i2c_driver rv3028_driver = …;
module_i2c_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;