linux/drivers/rtc/rtc-ab-b5ze-s3.c

// SPDX-License-Identifier: GPL-2.0+
/*
 * rtc-ab-b5ze-s3 - Driver for Abracon AB-RTCMC-32.768Khz-B5ZE-S3
 *                  I2C RTC / Alarm chip
 *
 * Copyright (C) 2014, Arnaud EBALARD <[email protected]>
 *
 * Detailed datasheet of the chip is available here:
 *
 *  https://www.abracon.com/realtimeclock/AB-RTCMC-32.768kHz-B5ZE-S3-Application-Manual.pdf
 *
 * This work is based on ISL12057 driver (drivers/rtc/rtc-isl12057.c).
 *
 */

#include <linux/module.h>
#include <linux/rtc.h>
#include <linux/i2c.h>
#include <linux/bcd.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/interrupt.h>

#define DRV_NAME

/* Control section */
#define ABB5ZES3_REG_CTRL1
#define ABB5ZES3_REG_CTRL1_CIE
#define ABB5ZES3_REG_CTRL1_AIE
#define ABB5ZES3_REG_CTRL1_SIE
#define ABB5ZES3_REG_CTRL1_PM
#define ABB5ZES3_REG_CTRL1_SR
#define ABB5ZES3_REG_CTRL1_STOP
#define ABB5ZES3_REG_CTRL1_CAP

#define ABB5ZES3_REG_CTRL2
#define ABB5ZES3_REG_CTRL2_CTBIE
#define ABB5ZES3_REG_CTRL2_CTAIE
#define ABB5ZES3_REG_CTRL2_WTAIE
#define ABB5ZES3_REG_CTRL2_AF
#define ABB5ZES3_REG_CTRL2_SF
#define ABB5ZES3_REG_CTRL2_CTBF
#define ABB5ZES3_REG_CTRL2_CTAF
#define ABB5ZES3_REG_CTRL2_WTAF

#define ABB5ZES3_REG_CTRL3
#define ABB5ZES3_REG_CTRL3_PM2
#define ABB5ZES3_REG_CTRL3_PM1
#define ABB5ZES3_REG_CTRL3_PM0
#define ABB5ZES3_REG_CTRL3_BSF
#define ABB5ZES3_REG_CTRL3_BLF
#define ABB5ZES3_REG_CTRL3_BSIE
#define ABB5ZES3_REG_CTRL3_BLIE

#define ABB5ZES3_CTRL_SEC_LEN

/* RTC section */
#define ABB5ZES3_REG_RTC_SC
#define ABB5ZES3_REG_RTC_SC_OSC
#define ABB5ZES3_REG_RTC_MN
#define ABB5ZES3_REG_RTC_HR
#define ABB5ZES3_REG_RTC_HR_PM
#define ABB5ZES3_REG_RTC_DT
#define ABB5ZES3_REG_RTC_DW
#define ABB5ZES3_REG_RTC_MO
#define ABB5ZES3_REG_RTC_YR

#define ABB5ZES3_RTC_SEC_LEN

/* Alarm section (enable bits are all active low) */
#define ABB5ZES3_REG_ALRM_MN
#define ABB5ZES3_REG_ALRM_MN_AE
#define ABB5ZES3_REG_ALRM_HR
#define ABB5ZES3_REG_ALRM_HR_AE
#define ABB5ZES3_REG_ALRM_DT
#define ABB5ZES3_REG_ALRM_DT_AE
#define ABB5ZES3_REG_ALRM_DW
#define ABB5ZES3_REG_ALRM_DW_AE

#define ABB5ZES3_ALRM_SEC_LEN

/* Frequency offset section */
#define ABB5ZES3_REG_FREQ_OF
#define ABB5ZES3_REG_FREQ_OF_MODE

/* CLOCKOUT section */
#define ABB5ZES3_REG_TIM_CLK
#define ABB5ZES3_REG_TIM_CLK_TAM
#define ABB5ZES3_REG_TIM_CLK_TBM
#define ABB5ZES3_REG_TIM_CLK_COF2
#define ABB5ZES3_REG_TIM_CLK_COF1
#define ABB5ZES3_REG_TIM_CLK_COF0
#define ABB5ZES3_REG_TIM_CLK_TAC1
#define ABB5ZES3_REG_TIM_CLK_TAC0
#define ABB5ZES3_REG_TIM_CLK_TBC

/* Timer A Section */
#define ABB5ZES3_REG_TIMA_CLK
#define ABB5ZES3_REG_TIMA_CLK_TAQ2
#define ABB5ZES3_REG_TIMA_CLK_TAQ1
#define ABB5ZES3_REG_TIMA_CLK_TAQ0
#define ABB5ZES3_REG_TIMA

#define ABB5ZES3_TIMA_SEC_LEN

/* Timer B Section */
#define ABB5ZES3_REG_TIMB_CLK
#define ABB5ZES3_REG_TIMB_CLK_TBW2
#define ABB5ZES3_REG_TIMB_CLK_TBW1
#define ABB5ZES3_REG_TIMB_CLK_TBW0
#define ABB5ZES3_REG_TIMB_CLK_TAQ2
#define ABB5ZES3_REG_TIMB_CLK_TAQ1
#define ABB5ZES3_REG_TIMB_CLK_TAQ0
#define ABB5ZES3_REG_TIMB
#define ABB5ZES3_TIMB_SEC_LEN

#define ABB5ZES3_MEM_MAP_LEN

struct abb5zes3_rtc_data {};

/*
 * Try and match register bits w/ fixed null values to see whether we
 * are dealing with an ABB5ZES3.
 */
static int abb5zes3_i2c_validate_chip(struct regmap *regmap)
{}

/* Clear alarm status bit. */
static int _abb5zes3_rtc_clear_alarm(struct device *dev)
{}

/* Enable or disable alarm (i.e. alarm interrupt generation) */
static int _abb5zes3_rtc_update_alarm(struct device *dev, bool enable)
{}

/* Enable or disable timer (watchdog timer A interrupt generation) */
static int _abb5zes3_rtc_update_timer(struct device *dev, bool enable)
{}

/*
 * Note: we only read, so regmap inner lock protection is sufficient, i.e.
 * we do not need driver's main lock protection.
 */
static int _abb5zes3_rtc_read_time(struct device *dev, struct rtc_time *tm)
{}

static int abb5zes3_rtc_set_time(struct device *dev, struct rtc_time *tm)
{}

/*
 * Set provided TAQ and Timer A registers (TIMA_CLK and TIMA) based on
 * given number of seconds.
 */
static inline void sec_to_timer_a(u8 secs, u8 *taq, u8 *timer_a)
{}

/*
 * Return current number of seconds in Timer A. As we only use
 * timer A with a 1Hz freq, this is what we expect to have.
 */
static inline int sec_from_timer_a(u8 *secs, u8 taq, u8 timer_a)
{}

/*
 * Read alarm currently configured via a watchdog timer using timer A. This
 * is done by reading current RTC time and adding remaining timer time.
 */
static int _abb5zes3_rtc_read_timer(struct device *dev,
				    struct rtc_wkalrm *alarm)
{}

/* Read alarm currently configured via a RTC alarm registers. */
static int _abb5zes3_rtc_read_alarm(struct device *dev,
				    struct rtc_wkalrm *alarm)
{}

/*
 * As the Alarm mechanism supported by the chip is only accurate to the
 * minute, we use the watchdog timer mechanism provided by timer A
 * (up to 256 seconds w/ a second accuracy) for low alarm values (below
 * 4 minutes). Otherwise, we use the common alarm mechanism provided
 * by the chip. In order for that to work, we keep track of currently
 * configured timer type via 'timer_alarm' flag in our private data
 * structure.
 */
static int abb5zes3_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{}

/*
 * Set alarm using chip alarm mechanism. It is only accurate to the
 * minute (not the second). The function expects alarm interrupt to
 * be disabled.
 */
static int _abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{}

/*
 * Set alarm using timer watchdog (via timer A) mechanism. The function expects
 * timer A interrupt to be disabled.
 */
static int _abb5zes3_rtc_set_timer(struct device *dev, struct rtc_wkalrm *alarm,
				   u8 secs)
{}

/*
 * The chip has an alarm which is only accurate to the minute. In order to
 * handle alarms below that limit, we use the watchdog timer function of
 * timer A. More precisely, the timer method is used for alarms below 240
 * seconds.
 */
static int abb5zes3_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{}

/* Enable or disable battery low irq generation */
static inline int _abb5zes3_rtc_battery_low_irq_enable(struct regmap *regmap,
						       bool enable)
{}

/*
 * Check current RTC status and enable/disable what needs to be. Return 0 if
 * everything went ok and a negative value upon error.
 */
static int abb5zes3_rtc_check_setup(struct device *dev)
{}

static int abb5zes3_rtc_alarm_irq_enable(struct device *dev,
					 unsigned int enable)
{}

static irqreturn_t _abb5zes3_rtc_interrupt(int irq, void *data)
{}

static const struct rtc_class_ops rtc_ops =;

static const struct regmap_config abb5zes3_rtc_regmap_config =;

static int abb5zes3_probe(struct i2c_client *client)
{}

#ifdef CONFIG_PM_SLEEP
static int abb5zes3_rtc_suspend(struct device *dev)
{}

static int abb5zes3_rtc_resume(struct device *dev)
{}
#endif

static SIMPLE_DEV_PM_OPS(abb5zes3_rtc_pm_ops, abb5zes3_rtc_suspend,
			 abb5zes3_rtc_resume);

#ifdef CONFIG_OF
static const struct of_device_id abb5zes3_dt_match[] =;
MODULE_DEVICE_TABLE(of, abb5zes3_dt_match);
#endif

static const struct i2c_device_id abb5zes3_id[] =;
MODULE_DEVICE_TABLE(i2c, abb5zes3_id);

static struct i2c_driver abb5zes3_driver =;
module_i2c_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();