linux/drivers/rtc/rtc-rv3028.c

// SPDX-License-Identifier: GPL-2.0
/*
 * RTC driver for the Micro Crystal RV3028
 *
 * Copyright (C) 2019 Micro Crystal SA
 *
 * Alexandre Belloni <[email protected]>
 *
 */

#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();