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-rx8010.c (10570B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Driver for the Epson RTC module RX-8010 SJ
      4 *
      5 * Copyright(C) Timesys Corporation 2015
      6 * Copyright(C) General Electric Company 2015
      7 */
      8
      9#include <linux/bcd.h>
     10#include <linux/bitops.h>
     11#include <linux/i2c.h>
     12#include <linux/kernel.h>
     13#include <linux/module.h>
     14#include <linux/regmap.h>
     15#include <linux/rtc.h>
     16
     17#define RX8010_SEC		0x10
     18#define RX8010_MIN		0x11
     19#define RX8010_HOUR		0x12
     20#define RX8010_WDAY		0x13
     21#define RX8010_MDAY		0x14
     22#define RX8010_MONTH		0x15
     23#define RX8010_YEAR		0x16
     24#define RX8010_RESV17		0x17
     25#define RX8010_ALMIN		0x18
     26#define RX8010_ALHOUR		0x19
     27#define RX8010_ALWDAY		0x1A
     28#define RX8010_TCOUNT0		0x1B
     29#define RX8010_TCOUNT1		0x1C
     30#define RX8010_EXT		0x1D
     31#define RX8010_FLAG		0x1E
     32#define RX8010_CTRL		0x1F
     33/* 0x20 to 0x2F are user registers */
     34#define RX8010_RESV30		0x30
     35#define RX8010_RESV31		0x31
     36#define RX8010_IRQ		0x32
     37
     38#define RX8010_EXT_WADA		BIT(3)
     39
     40#define RX8010_FLAG_VLF		BIT(1)
     41#define RX8010_FLAG_AF		BIT(3)
     42#define RX8010_FLAG_TF		BIT(4)
     43#define RX8010_FLAG_UF		BIT(5)
     44
     45#define RX8010_CTRL_AIE		BIT(3)
     46#define RX8010_CTRL_UIE		BIT(5)
     47#define RX8010_CTRL_STOP	BIT(6)
     48#define RX8010_CTRL_TEST	BIT(7)
     49
     50#define RX8010_ALARM_AE		BIT(7)
     51
     52static const struct i2c_device_id rx8010_id[] = {
     53	{ "rx8010", 0 },
     54	{ }
     55};
     56MODULE_DEVICE_TABLE(i2c, rx8010_id);
     57
     58static const __maybe_unused struct of_device_id rx8010_of_match[] = {
     59	{ .compatible = "epson,rx8010" },
     60	{ }
     61};
     62MODULE_DEVICE_TABLE(of, rx8010_of_match);
     63
     64struct rx8010_data {
     65	struct regmap *regs;
     66	struct rtc_device *rtc;
     67	u8 ctrlreg;
     68};
     69
     70static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
     71{
     72	struct i2c_client *client = dev_id;
     73	struct rx8010_data *rx8010 = i2c_get_clientdata(client);
     74	int flagreg, err;
     75
     76	rtc_lock(rx8010->rtc);
     77
     78	err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
     79	if (err) {
     80		rtc_unlock(rx8010->rtc);
     81		return IRQ_NONE;
     82	}
     83
     84	if (flagreg & RX8010_FLAG_VLF)
     85		dev_warn(&client->dev, "Frequency stop detected\n");
     86
     87	if (flagreg & RX8010_FLAG_TF) {
     88		flagreg &= ~RX8010_FLAG_TF;
     89		rtc_update_irq(rx8010->rtc, 1, RTC_PF | RTC_IRQF);
     90	}
     91
     92	if (flagreg & RX8010_FLAG_AF) {
     93		flagreg &= ~RX8010_FLAG_AF;
     94		rtc_update_irq(rx8010->rtc, 1, RTC_AF | RTC_IRQF);
     95	}
     96
     97	if (flagreg & RX8010_FLAG_UF) {
     98		flagreg &= ~RX8010_FLAG_UF;
     99		rtc_update_irq(rx8010->rtc, 1, RTC_UF | RTC_IRQF);
    100	}
    101
    102	err = regmap_write(rx8010->regs, RX8010_FLAG, flagreg);
    103	rtc_unlock(rx8010->rtc);
    104	return err ? IRQ_NONE : IRQ_HANDLED;
    105}
    106
    107static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
    108{
    109	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    110	u8 date[RX8010_YEAR - RX8010_SEC + 1];
    111	int flagreg, err;
    112
    113	err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
    114	if (err)
    115		return err;
    116
    117	if (flagreg & RX8010_FLAG_VLF) {
    118		dev_warn(dev, "Frequency stop detected\n");
    119		return -EINVAL;
    120	}
    121
    122	err = regmap_bulk_read(rx8010->regs, RX8010_SEC, date, sizeof(date));
    123	if (err)
    124		return err;
    125
    126	dt->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
    127	dt->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
    128	dt->tm_hour = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f);
    129	dt->tm_mday = bcd2bin(date[RX8010_MDAY - RX8010_SEC] & 0x3f);
    130	dt->tm_mon = bcd2bin(date[RX8010_MONTH - RX8010_SEC] & 0x1f) - 1;
    131	dt->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 100;
    132	dt->tm_wday = ffs(date[RX8010_WDAY - RX8010_SEC] & 0x7f);
    133
    134	return 0;
    135}
    136
    137static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
    138{
    139	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    140	u8 date[RX8010_YEAR - RX8010_SEC + 1];
    141	int err;
    142
    143	/* set STOP bit before changing clock/calendar */
    144	err = regmap_set_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
    145	if (err)
    146		return err;
    147
    148	date[RX8010_SEC - RX8010_SEC] = bin2bcd(dt->tm_sec);
    149	date[RX8010_MIN - RX8010_SEC] = bin2bcd(dt->tm_min);
    150	date[RX8010_HOUR - RX8010_SEC] = bin2bcd(dt->tm_hour);
    151	date[RX8010_MDAY - RX8010_SEC] = bin2bcd(dt->tm_mday);
    152	date[RX8010_MONTH - RX8010_SEC] = bin2bcd(dt->tm_mon + 1);
    153	date[RX8010_YEAR - RX8010_SEC] = bin2bcd(dt->tm_year - 100);
    154	date[RX8010_WDAY - RX8010_SEC] = bin2bcd(1 << dt->tm_wday);
    155
    156	err = regmap_bulk_write(rx8010->regs, RX8010_SEC, date, sizeof(date));
    157	if (err)
    158		return err;
    159
    160	/* clear STOP bit after changing clock/calendar */
    161	err = regmap_clear_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
    162	if (err)
    163		return err;
    164
    165	err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_VLF);
    166	if (err)
    167		return err;
    168
    169	return 0;
    170}
    171
    172static int rx8010_init(struct device *dev)
    173{
    174	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    175	u8 ctrl[2];
    176	int need_clear = 0, err;
    177
    178	/* Initialize reserved registers as specified in datasheet */
    179	err = regmap_write(rx8010->regs, RX8010_RESV17, 0xD8);
    180	if (err)
    181		return err;
    182
    183	err = regmap_write(rx8010->regs, RX8010_RESV30, 0x00);
    184	if (err)
    185		return err;
    186
    187	err = regmap_write(rx8010->regs, RX8010_RESV31, 0x08);
    188	if (err)
    189		return err;
    190
    191	err = regmap_write(rx8010->regs, RX8010_IRQ, 0x00);
    192	if (err)
    193		return err;
    194
    195	err = regmap_bulk_read(rx8010->regs, RX8010_FLAG, ctrl, 2);
    196	if (err)
    197		return err;
    198
    199	if (ctrl[0] & RX8010_FLAG_VLF)
    200		dev_warn(dev, "Frequency stop was detected\n");
    201
    202	if (ctrl[0] & RX8010_FLAG_AF) {
    203		dev_warn(dev, "Alarm was detected\n");
    204		need_clear = 1;
    205	}
    206
    207	if (ctrl[0] & RX8010_FLAG_TF)
    208		need_clear = 1;
    209
    210	if (ctrl[0] & RX8010_FLAG_UF)
    211		need_clear = 1;
    212
    213	if (need_clear) {
    214		ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
    215		err = regmap_write(rx8010->regs, RX8010_FLAG, ctrl[0]);
    216		if (err)
    217			return err;
    218	}
    219
    220	rx8010->ctrlreg = (ctrl[1] & ~RX8010_CTRL_TEST);
    221
    222	return 0;
    223}
    224
    225static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t)
    226{
    227	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    228	u8 alarmvals[3];
    229	int flagreg, err;
    230
    231	err = regmap_bulk_read(rx8010->regs, RX8010_ALMIN, alarmvals, 3);
    232	if (err)
    233		return err;
    234
    235	err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
    236	if (err)
    237		return err;
    238
    239	t->time.tm_sec = 0;
    240	t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
    241	t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
    242
    243	if (!(alarmvals[2] & RX8010_ALARM_AE))
    244		t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f);
    245
    246	t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE);
    247	t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled;
    248
    249	return 0;
    250}
    251
    252static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
    253{
    254	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    255	u8 alarmvals[3];
    256	int err;
    257
    258	if (rx8010->ctrlreg & (RX8010_CTRL_AIE | RX8010_CTRL_UIE)) {
    259		rx8010->ctrlreg &= ~(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
    260		err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
    261		if (err)
    262			return err;
    263	}
    264
    265	err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
    266	if (err)
    267		return err;
    268
    269	alarmvals[0] = bin2bcd(t->time.tm_min);
    270	alarmvals[1] = bin2bcd(t->time.tm_hour);
    271	alarmvals[2] = bin2bcd(t->time.tm_mday);
    272
    273	err = regmap_bulk_write(rx8010->regs, RX8010_ALMIN, alarmvals, 2);
    274	if (err)
    275		return err;
    276
    277	err = regmap_clear_bits(rx8010->regs, RX8010_EXT, RX8010_EXT_WADA);
    278	if (err)
    279		return err;
    280
    281	if (alarmvals[2] == 0)
    282		alarmvals[2] |= RX8010_ALARM_AE;
    283
    284	err = regmap_write(rx8010->regs, RX8010_ALWDAY, alarmvals[2]);
    285	if (err)
    286		return err;
    287
    288	if (t->enabled) {
    289		if (rx8010->rtc->uie_rtctimer.enabled)
    290			rx8010->ctrlreg |= RX8010_CTRL_UIE;
    291		if (rx8010->rtc->aie_timer.enabled)
    292			rx8010->ctrlreg |=
    293				(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
    294
    295		err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
    296		if (err)
    297			return err;
    298	}
    299
    300	return 0;
    301}
    302
    303static int rx8010_alarm_irq_enable(struct device *dev,
    304				   unsigned int enabled)
    305{
    306	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    307	int err;
    308	u8 ctrl;
    309
    310	ctrl = rx8010->ctrlreg;
    311
    312	if (enabled) {
    313		if (rx8010->rtc->uie_rtctimer.enabled)
    314			ctrl |= RX8010_CTRL_UIE;
    315		if (rx8010->rtc->aie_timer.enabled)
    316			ctrl |= (RX8010_CTRL_AIE | RX8010_CTRL_UIE);
    317	} else {
    318		if (!rx8010->rtc->uie_rtctimer.enabled)
    319			ctrl &= ~RX8010_CTRL_UIE;
    320		if (!rx8010->rtc->aie_timer.enabled)
    321			ctrl &= ~RX8010_CTRL_AIE;
    322	}
    323
    324	err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
    325	if (err)
    326		return err;
    327
    328	if (ctrl != rx8010->ctrlreg) {
    329		rx8010->ctrlreg = ctrl;
    330		err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
    331		if (err)
    332			return err;
    333	}
    334
    335	return 0;
    336}
    337
    338static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
    339{
    340	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
    341	int tmp, flagreg, err;
    342
    343	switch (cmd) {
    344	case RTC_VL_READ:
    345		err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
    346		if (err)
    347			return err;
    348
    349		tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
    350		return put_user(tmp, (unsigned int __user *)arg);
    351
    352	default:
    353		return -ENOIOCTLCMD;
    354	}
    355}
    356
    357static const struct rtc_class_ops rx8010_rtc_ops = {
    358	.read_time = rx8010_get_time,
    359	.set_time = rx8010_set_time,
    360	.ioctl = rx8010_ioctl,
    361	.read_alarm = rx8010_read_alarm,
    362	.set_alarm = rx8010_set_alarm,
    363	.alarm_irq_enable = rx8010_alarm_irq_enable,
    364};
    365
    366static const struct regmap_config rx8010_regmap_config = {
    367	.name = "rx8010-rtc",
    368	.reg_bits = 8,
    369	.val_bits = 8,
    370};
    371
    372static int rx8010_probe(struct i2c_client *client)
    373{
    374	struct device *dev = &client->dev;
    375	struct rx8010_data *rx8010;
    376	int err = 0;
    377
    378	rx8010 = devm_kzalloc(dev, sizeof(*rx8010), GFP_KERNEL);
    379	if (!rx8010)
    380		return -ENOMEM;
    381
    382	i2c_set_clientdata(client, rx8010);
    383
    384	rx8010->regs = devm_regmap_init_i2c(client, &rx8010_regmap_config);
    385	if (IS_ERR(rx8010->regs))
    386		return PTR_ERR(rx8010->regs);
    387
    388	err = rx8010_init(dev);
    389	if (err)
    390		return err;
    391
    392	rx8010->rtc = devm_rtc_allocate_device(dev);
    393	if (IS_ERR(rx8010->rtc))
    394		return PTR_ERR(rx8010->rtc);
    395
    396	if (client->irq > 0) {
    397		dev_info(dev, "IRQ %d supplied\n", client->irq);
    398		err = devm_request_threaded_irq(dev, client->irq, NULL,
    399						rx8010_irq_1_handler,
    400						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
    401						"rx8010", client);
    402		if (err) {
    403			dev_err(dev, "unable to request IRQ\n");
    404			return err;
    405		}
    406	} else {
    407		clear_bit(RTC_FEATURE_ALARM, rx8010->rtc->features);
    408	}
    409
    410	rx8010->rtc->ops = &rx8010_rtc_ops;
    411	rx8010->rtc->max_user_freq = 1;
    412	rx8010->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
    413	rx8010->rtc->range_max = RTC_TIMESTAMP_END_2099;
    414
    415	return devm_rtc_register_device(rx8010->rtc);
    416}
    417
    418static struct i2c_driver rx8010_driver = {
    419	.driver = {
    420		.name = "rtc-rx8010",
    421		.of_match_table = of_match_ptr(rx8010_of_match),
    422	},
    423	.probe_new	= rx8010_probe,
    424	.id_table	= rx8010_id,
    425};
    426
    427module_i2c_driver(rx8010_driver);
    428
    429MODULE_AUTHOR("Akshay Bhat <akshay.bhat@timesys.com>");
    430MODULE_DESCRIPTION("Epson RX8010SJ RTC driver");
    431MODULE_LICENSE("GPL v2");