cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

rtc-rx8581.c (9114B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * An I2C driver for the Epson RX8581 RTC
      4 *
      5 * Author: Martyn Welch <martyn.welch@ge.com>
      6 * Copyright 2008 GE Intelligent Platforms Embedded Systems, Inc.
      7 *
      8 * Based on: rtc-pcf8563.c (An I2C driver for the Philips PCF8563 RTC)
      9 * Copyright 2005-06 Tower Technologies
     10 */
     11
     12#include <linux/module.h>
     13#include <linux/i2c.h>
     14#include <linux/bcd.h>
     15#include <linux/of.h>
     16#include <linux/of_device.h>
     17#include <linux/regmap.h>
     18#include <linux/rtc.h>
     19#include <linux/log2.h>
     20
     21#define RX8581_REG_SC		0x00 /* Second in BCD */
     22#define RX8581_REG_MN		0x01 /* Minute in BCD */
     23#define RX8581_REG_HR		0x02 /* Hour in BCD */
     24#define RX8581_REG_DW		0x03 /* Day of Week */
     25#define RX8581_REG_DM		0x04 /* Day of Month in BCD */
     26#define RX8581_REG_MO		0x05 /* Month in BCD */
     27#define RX8581_REG_YR		0x06 /* Year in BCD */
     28#define RX8581_REG_RAM		0x07 /* RAM */
     29#define RX8581_REG_AMN		0x08 /* Alarm Min in BCD*/
     30#define RX8581_REG_AHR		0x09 /* Alarm Hour in BCD */
     31#define RX8581_REG_ADM		0x0A
     32#define RX8581_REG_ADW		0x0A
     33#define RX8581_REG_TMR0		0x0B
     34#define RX8581_REG_TMR1		0x0C
     35#define RX8581_REG_EXT		0x0D /* Extension Register */
     36#define RX8581_REG_FLAG		0x0E /* Flag Register */
     37#define RX8581_REG_CTRL		0x0F /* Control Register */
     38
     39
     40/* Flag Register bit definitions */
     41#define RX8581_FLAG_UF		0x20 /* Update */
     42#define RX8581_FLAG_TF		0x10 /* Timer */
     43#define RX8581_FLAG_AF		0x08 /* Alarm */
     44#define RX8581_FLAG_VLF		0x02 /* Voltage Low */
     45
     46/* Control Register bit definitions */
     47#define RX8581_CTRL_UIE		0x20 /* Update Interrupt Enable */
     48#define RX8581_CTRL_TIE		0x10 /* Timer Interrupt Enable */
     49#define RX8581_CTRL_AIE		0x08 /* Alarm Interrupt Enable */
     50#define RX8581_CTRL_STOP	0x02 /* STOP bit */
     51#define RX8581_CTRL_RESET	0x01 /* RESET bit */
     52
     53#define RX8571_USER_RAM		0x10
     54#define RX8571_NVRAM_SIZE	0x10
     55
     56struct rx8581 {
     57	struct regmap		*regmap;
     58	struct rtc_device	*rtc;
     59};
     60
     61struct rx85x1_config {
     62	struct regmap_config regmap;
     63	unsigned int num_nvram;
     64};
     65
     66/*
     67 * In the routines that deal directly with the rx8581 hardware, we use
     68 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
     69 */
     70static int rx8581_rtc_read_time(struct device *dev, struct rtc_time *tm)
     71{
     72	struct i2c_client *client = to_i2c_client(dev);
     73	unsigned char date[7];
     74	unsigned int data;
     75	int err;
     76	struct rx8581 *rx8581 = i2c_get_clientdata(client);
     77
     78	/* First we ensure that the "update flag" is not set, we read the
     79	 * time and date then re-read the "update flag". If the update flag
     80	 * has been set, we know that the time has changed during the read so
     81	 * we repeat the whole process again.
     82	 */
     83	err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
     84	if (err < 0)
     85		return err;
     86
     87	if (data & RX8581_FLAG_VLF) {
     88		dev_warn(dev,
     89			 "low voltage detected, date/time is not reliable.\n");
     90		return -EINVAL;
     91	}
     92
     93	do {
     94		/* If update flag set, clear it */
     95		if (data & RX8581_FLAG_UF) {
     96			err = regmap_write(rx8581->regmap, RX8581_REG_FLAG,
     97					  data & ~RX8581_FLAG_UF);
     98			if (err < 0)
     99				return err;
    100		}
    101
    102		/* Now read time and date */
    103		err = regmap_bulk_read(rx8581->regmap, RX8581_REG_SC, date,
    104				       sizeof(date));
    105		if (err < 0)
    106			return err;
    107
    108		/* Check flag register */
    109		err = regmap_read(rx8581->regmap, RX8581_REG_FLAG, &data);
    110		if (err < 0)
    111			return err;
    112	} while (data & RX8581_FLAG_UF);
    113
    114	dev_dbg(dev, "%s: raw data is sec=%02x, min=%02x, hr=%02x, "
    115		"wday=%02x, mday=%02x, mon=%02x, year=%02x\n",
    116		__func__,
    117		date[0], date[1], date[2], date[3], date[4], date[5], date[6]);
    118
    119	tm->tm_sec = bcd2bin(date[RX8581_REG_SC] & 0x7F);
    120	tm->tm_min = bcd2bin(date[RX8581_REG_MN] & 0x7F);
    121	tm->tm_hour = bcd2bin(date[RX8581_REG_HR] & 0x3F); /* rtc hr 0-23 */
    122	tm->tm_wday = ilog2(date[RX8581_REG_DW] & 0x7F);
    123	tm->tm_mday = bcd2bin(date[RX8581_REG_DM] & 0x3F);
    124	tm->tm_mon = bcd2bin(date[RX8581_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
    125	tm->tm_year = bcd2bin(date[RX8581_REG_YR]) + 100;
    126
    127	dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
    128		"mday=%d, mon=%d, year=%d, wday=%d\n",
    129		__func__,
    130		tm->tm_sec, tm->tm_min, tm->tm_hour,
    131		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
    132
    133	return 0;
    134}
    135
    136static int rx8581_rtc_set_time(struct device *dev, struct rtc_time *tm)
    137{
    138	struct i2c_client *client = to_i2c_client(dev);
    139	int err;
    140	unsigned char buf[7];
    141	struct rx8581 *rx8581 = i2c_get_clientdata(client);
    142
    143	dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
    144		"mday=%d, mon=%d, year=%d, wday=%d\n",
    145		__func__,
    146		tm->tm_sec, tm->tm_min, tm->tm_hour,
    147		tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
    148
    149	/* hours, minutes and seconds */
    150	buf[RX8581_REG_SC] = bin2bcd(tm->tm_sec);
    151	buf[RX8581_REG_MN] = bin2bcd(tm->tm_min);
    152	buf[RX8581_REG_HR] = bin2bcd(tm->tm_hour);
    153
    154	buf[RX8581_REG_DM] = bin2bcd(tm->tm_mday);
    155
    156	/* month, 1 - 12 */
    157	buf[RX8581_REG_MO] = bin2bcd(tm->tm_mon + 1);
    158
    159	/* year and century */
    160	buf[RX8581_REG_YR] = bin2bcd(tm->tm_year - 100);
    161	buf[RX8581_REG_DW] = (0x1 << tm->tm_wday);
    162
    163	/* Stop the clock */
    164	err = regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
    165				 RX8581_CTRL_STOP, RX8581_CTRL_STOP);
    166	if (err < 0)
    167		return err;
    168
    169	/* write register's data */
    170	err = regmap_bulk_write(rx8581->regmap, RX8581_REG_SC,
    171				buf, sizeof(buf));
    172	if (err < 0)
    173		return err;
    174
    175	/* get VLF and clear it */
    176	err = regmap_update_bits(rx8581->regmap, RX8581_REG_FLAG,
    177				 RX8581_FLAG_VLF, 0);
    178	if (err < 0)
    179		return err;
    180
    181	/* Restart the clock */
    182	return regmap_update_bits(rx8581->regmap, RX8581_REG_CTRL,
    183				 RX8581_CTRL_STOP, 0);
    184}
    185
    186static const struct rtc_class_ops rx8581_rtc_ops = {
    187	.read_time	= rx8581_rtc_read_time,
    188	.set_time	= rx8581_rtc_set_time,
    189};
    190
    191static int rx8571_nvram_read(void *priv, unsigned int offset, void *val,
    192			     size_t bytes)
    193{
    194	struct rx8581 *rx8581 = priv;
    195
    196	return regmap_bulk_read(rx8581->regmap, RX8571_USER_RAM + offset,
    197				val, bytes);
    198}
    199
    200static int rx8571_nvram_write(void *priv, unsigned int offset, void *val,
    201			      size_t bytes)
    202{
    203	struct rx8581 *rx8581 = priv;
    204
    205	return regmap_bulk_write(rx8581->regmap, RX8571_USER_RAM + offset,
    206				 val, bytes);
    207}
    208
    209static int rx85x1_nvram_read(void *priv, unsigned int offset, void *val,
    210			     size_t bytes)
    211{
    212	struct rx8581 *rx8581 = priv;
    213	unsigned int tmp_val;
    214	int ret;
    215
    216	ret = regmap_read(rx8581->regmap, RX8581_REG_RAM, &tmp_val);
    217	(*(unsigned char *)val) = (unsigned char) tmp_val;
    218
    219	return ret;
    220}
    221
    222static int rx85x1_nvram_write(void *priv, unsigned int offset, void *val,
    223			      size_t bytes)
    224{
    225	struct rx8581 *rx8581 = priv;
    226	unsigned char tmp_val;
    227
    228	tmp_val = *((unsigned char *)val);
    229	return regmap_write(rx8581->regmap, RX8581_REG_RAM,
    230				(unsigned int)tmp_val);
    231}
    232
    233static const struct rx85x1_config rx8581_config = {
    234	.regmap = {
    235		.reg_bits = 8,
    236		.val_bits = 8,
    237		.max_register = 0xf,
    238	},
    239	.num_nvram = 1
    240};
    241
    242static const struct rx85x1_config rx8571_config = {
    243	.regmap = {
    244		.reg_bits = 8,
    245		.val_bits = 8,
    246		.max_register = 0x1f,
    247	},
    248	.num_nvram = 2
    249};
    250
    251static int rx8581_probe(struct i2c_client *client,
    252			const struct i2c_device_id *id)
    253{
    254	struct rx8581 *rx8581;
    255	const struct rx85x1_config *config = &rx8581_config;
    256	const void *data = of_device_get_match_data(&client->dev);
    257	static struct nvmem_config nvmem_cfg[] = {
    258		{
    259			.name = "rx85x1-",
    260			.word_size = 1,
    261			.stride = 1,
    262			.size = 1,
    263			.reg_read = rx85x1_nvram_read,
    264			.reg_write = rx85x1_nvram_write,
    265		}, {
    266			.name = "rx8571-",
    267			.word_size = 1,
    268			.stride = 1,
    269			.size = RX8571_NVRAM_SIZE,
    270			.reg_read = rx8571_nvram_read,
    271			.reg_write = rx8571_nvram_write,
    272		},
    273	};
    274	int ret, i;
    275
    276	dev_dbg(&client->dev, "%s\n", __func__);
    277
    278	if (data)
    279		config = data;
    280
    281	rx8581 = devm_kzalloc(&client->dev, sizeof(struct rx8581), GFP_KERNEL);
    282	if (!rx8581)
    283		return -ENOMEM;
    284
    285	i2c_set_clientdata(client, rx8581);
    286
    287	rx8581->regmap = devm_regmap_init_i2c(client, &config->regmap);
    288	if (IS_ERR(rx8581->regmap))
    289		return PTR_ERR(rx8581->regmap);
    290
    291	rx8581->rtc = devm_rtc_allocate_device(&client->dev);
    292	if (IS_ERR(rx8581->rtc))
    293		return PTR_ERR(rx8581->rtc);
    294
    295	rx8581->rtc->ops = &rx8581_rtc_ops;
    296	rx8581->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
    297	rx8581->rtc->range_max = RTC_TIMESTAMP_END_2099;
    298	rx8581->rtc->start_secs = 0;
    299	rx8581->rtc->set_start_time = true;
    300
    301	ret = devm_rtc_register_device(rx8581->rtc);
    302
    303	for (i = 0; i < config->num_nvram; i++) {
    304		nvmem_cfg[i].priv = rx8581;
    305		devm_rtc_nvmem_register(rx8581->rtc, &nvmem_cfg[i]);
    306	}
    307
    308	return ret;
    309}
    310
    311static const struct i2c_device_id rx8581_id[] = {
    312	{ "rx8581", 0 },
    313	{ }
    314};
    315MODULE_DEVICE_TABLE(i2c, rx8581_id);
    316
    317static const __maybe_unused struct of_device_id rx8581_of_match[] = {
    318	{ .compatible = "epson,rx8571", .data = &rx8571_config },
    319	{ .compatible = "epson,rx8581", .data = &rx8581_config },
    320	{ /* sentinel */ }
    321};
    322MODULE_DEVICE_TABLE(of, rx8581_of_match);
    323
    324static struct i2c_driver rx8581_driver = {
    325	.driver		= {
    326		.name	= "rtc-rx8581",
    327		.of_match_table = of_match_ptr(rx8581_of_match),
    328	},
    329	.probe		= rx8581_probe,
    330	.id_table	= rx8581_id,
    331};
    332
    333module_i2c_driver(rx8581_driver);
    334
    335MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
    336MODULE_DESCRIPTION("Epson RX-8571/RX-8581 RTC driver");
    337MODULE_LICENSE("GPL");