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-mcp795.c (11401B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * SPI Driver for Microchip MCP795 RTC
      4 *
      5 * Copyright (C) Josef Gajdusek <atx@atx.name>
      6 *
      7 * based on other Linux RTC drivers
      8 *
      9 * Device datasheet:
     10 * https://ww1.microchip.com/downloads/en/DeviceDoc/22280A.pdf
     11 */
     12
     13#include <linux/module.h>
     14#include <linux/kernel.h>
     15#include <linux/device.h>
     16#include <linux/printk.h>
     17#include <linux/spi/spi.h>
     18#include <linux/rtc.h>
     19#include <linux/of.h>
     20#include <linux/bcd.h>
     21#include <linux/delay.h>
     22
     23/* MCP795 Instructions, see datasheet table 3-1 */
     24#define MCP795_EEREAD	0x03
     25#define MCP795_EEWRITE	0x02
     26#define MCP795_EEWRDI	0x04
     27#define MCP795_EEWREN	0x06
     28#define MCP795_SRREAD	0x05
     29#define MCP795_SRWRITE	0x01
     30#define MCP795_READ	0x13
     31#define MCP795_WRITE	0x12
     32#define MCP795_UNLOCK	0x14
     33#define MCP795_IDWRITE	0x32
     34#define MCP795_IDREAD	0x33
     35#define MCP795_CLRWDT	0x44
     36#define MCP795_CLRRAM	0x54
     37
     38/* MCP795 RTCC registers, see datasheet table 4-1 */
     39#define MCP795_REG_SECONDS	0x01
     40#define MCP795_REG_DAY		0x04
     41#define MCP795_REG_MONTH	0x06
     42#define MCP795_REG_CONTROL	0x08
     43#define MCP795_REG_ALM0_SECONDS	0x0C
     44#define MCP795_REG_ALM0_DAY	0x0F
     45
     46#define MCP795_ST_BIT		BIT(7)
     47#define MCP795_24_BIT		BIT(6)
     48#define MCP795_LP_BIT		BIT(5)
     49#define MCP795_EXTOSC_BIT	BIT(3)
     50#define MCP795_OSCON_BIT	BIT(5)
     51#define MCP795_ALM0_BIT		BIT(4)
     52#define MCP795_ALM1_BIT		BIT(5)
     53#define MCP795_ALM0IF_BIT	BIT(3)
     54#define MCP795_ALM0C0_BIT	BIT(4)
     55#define MCP795_ALM0C1_BIT	BIT(5)
     56#define MCP795_ALM0C2_BIT	BIT(6)
     57
     58#define SEC_PER_DAY		(24 * 60 * 60)
     59
     60static int mcp795_rtcc_read(struct device *dev, u8 addr, u8 *buf, u8 count)
     61{
     62	struct spi_device *spi = to_spi_device(dev);
     63	int ret;
     64	u8 tx[2];
     65
     66	tx[0] = MCP795_READ;
     67	tx[1] = addr;
     68	ret = spi_write_then_read(spi, tx, sizeof(tx), buf, count);
     69
     70	if (ret)
     71		dev_err(dev, "Failed reading %d bytes from address %x.\n",
     72					count, addr);
     73
     74	return ret;
     75}
     76
     77static int mcp795_rtcc_write(struct device *dev, u8 addr, u8 *data, u8 count)
     78{
     79	struct spi_device *spi = to_spi_device(dev);
     80	int ret;
     81	u8 tx[257];
     82
     83	tx[0] = MCP795_WRITE;
     84	tx[1] = addr;
     85	memcpy(&tx[2], data, count);
     86
     87	ret = spi_write(spi, tx, 2 + count);
     88
     89	if (ret)
     90		dev_err(dev, "Failed to write %d bytes to address %x.\n",
     91					count, addr);
     92
     93	return ret;
     94}
     95
     96static int mcp795_rtcc_set_bits(struct device *dev, u8 addr, u8 mask, u8 state)
     97{
     98	int ret;
     99	u8 tmp;
    100
    101	ret = mcp795_rtcc_read(dev, addr, &tmp, 1);
    102	if (ret)
    103		return ret;
    104
    105	if ((tmp & mask) != state) {
    106		tmp = (tmp & ~mask) | state;
    107		ret = mcp795_rtcc_write(dev, addr, &tmp, 1);
    108	}
    109
    110	return ret;
    111}
    112
    113static int mcp795_stop_oscillator(struct device *dev, bool *extosc)
    114{
    115	int retries = 5;
    116	int ret;
    117	u8 data;
    118
    119	ret = mcp795_rtcc_set_bits(dev, MCP795_REG_SECONDS, MCP795_ST_BIT, 0);
    120	if (ret)
    121		return ret;
    122	ret = mcp795_rtcc_read(dev, MCP795_REG_CONTROL, &data, 1);
    123	if (ret)
    124		return ret;
    125	*extosc = !!(data & MCP795_EXTOSC_BIT);
    126	ret = mcp795_rtcc_set_bits(
    127				dev, MCP795_REG_CONTROL, MCP795_EXTOSC_BIT, 0);
    128	if (ret)
    129		return ret;
    130	/* wait for the OSCON bit to clear */
    131	do {
    132		usleep_range(700, 800);
    133		ret = mcp795_rtcc_read(dev, MCP795_REG_DAY, &data, 1);
    134		if (ret)
    135			break;
    136		if (!(data & MCP795_OSCON_BIT))
    137			break;
    138
    139	} while (--retries);
    140
    141	return !retries ? -EIO : ret;
    142}
    143
    144static int mcp795_start_oscillator(struct device *dev, bool *extosc)
    145{
    146	if (extosc) {
    147		u8 data = *extosc ? MCP795_EXTOSC_BIT : 0;
    148		int ret;
    149
    150		ret = mcp795_rtcc_set_bits(
    151			dev, MCP795_REG_CONTROL, MCP795_EXTOSC_BIT, data);
    152		if (ret)
    153			return ret;
    154	}
    155	return mcp795_rtcc_set_bits(
    156			dev, MCP795_REG_SECONDS, MCP795_ST_BIT, MCP795_ST_BIT);
    157}
    158
    159/* Enable or disable Alarm 0 in RTC */
    160static int mcp795_update_alarm(struct device *dev, bool enable)
    161{
    162	int ret;
    163
    164	dev_dbg(dev, "%s alarm\n", enable ? "Enable" : "Disable");
    165
    166	if (enable) {
    167		/* clear ALM0IF (Alarm 0 Interrupt Flag) bit */
    168		ret = mcp795_rtcc_set_bits(dev, MCP795_REG_ALM0_DAY,
    169					MCP795_ALM0IF_BIT, 0);
    170		if (ret)
    171			return ret;
    172		/* enable alarm 0 */
    173		ret = mcp795_rtcc_set_bits(dev, MCP795_REG_CONTROL,
    174					MCP795_ALM0_BIT, MCP795_ALM0_BIT);
    175	} else {
    176		/* disable alarm 0 and alarm 1 */
    177		ret = mcp795_rtcc_set_bits(dev, MCP795_REG_CONTROL,
    178					MCP795_ALM0_BIT | MCP795_ALM1_BIT, 0);
    179	}
    180	return ret;
    181}
    182
    183static int mcp795_set_time(struct device *dev, struct rtc_time *tim)
    184{
    185	int ret;
    186	u8 data[7];
    187	bool extosc;
    188
    189	/* Stop RTC and store current value of EXTOSC bit */
    190	ret = mcp795_stop_oscillator(dev, &extosc);
    191	if (ret)
    192		return ret;
    193
    194	/* Read first, so we can leave config bits untouched */
    195	ret = mcp795_rtcc_read(dev, MCP795_REG_SECONDS, data, sizeof(data));
    196
    197	if (ret)
    198		return ret;
    199
    200	data[0] = (data[0] & 0x80) | bin2bcd(tim->tm_sec);
    201	data[1] = (data[1] & 0x80) | bin2bcd(tim->tm_min);
    202	data[2] = bin2bcd(tim->tm_hour);
    203	data[3] = (data[3] & 0xF8) | bin2bcd(tim->tm_wday + 1);
    204	data[4] = bin2bcd(tim->tm_mday);
    205	data[5] = (data[5] & MCP795_LP_BIT) | bin2bcd(tim->tm_mon + 1);
    206
    207	if (tim->tm_year > 100)
    208		tim->tm_year -= 100;
    209
    210	data[6] = bin2bcd(tim->tm_year);
    211
    212	/* Always write the date and month using a separate Write command.
    213	 * This is a workaround for a know silicon issue that some combinations
    214	 * of date and month values may result in the date being reset to 1.
    215	 */
    216	ret = mcp795_rtcc_write(dev, MCP795_REG_SECONDS, data, 5);
    217	if (ret)
    218		return ret;
    219
    220	ret = mcp795_rtcc_write(dev, MCP795_REG_MONTH, &data[5], 2);
    221	if (ret)
    222		return ret;
    223
    224	/* Start back RTC and restore previous value of EXTOSC bit.
    225	 * There is no need to clear EXTOSC bit when the previous value was 0
    226	 * because it was already cleared when stopping the RTC oscillator.
    227	 */
    228	ret = mcp795_start_oscillator(dev, extosc ? &extosc : NULL);
    229	if (ret)
    230		return ret;
    231
    232	dev_dbg(dev, "Set mcp795: %ptR\n", tim);
    233
    234	return 0;
    235}
    236
    237static int mcp795_read_time(struct device *dev, struct rtc_time *tim)
    238{
    239	int ret;
    240	u8 data[7];
    241
    242	ret = mcp795_rtcc_read(dev, MCP795_REG_SECONDS, data, sizeof(data));
    243
    244	if (ret)
    245		return ret;
    246
    247	tim->tm_sec	= bcd2bin(data[0] & 0x7F);
    248	tim->tm_min	= bcd2bin(data[1] & 0x7F);
    249	tim->tm_hour	= bcd2bin(data[2] & 0x3F);
    250	tim->tm_wday	= bcd2bin(data[3] & 0x07) - 1;
    251	tim->tm_mday	= bcd2bin(data[4] & 0x3F);
    252	tim->tm_mon	= bcd2bin(data[5] & 0x1F) - 1;
    253	tim->tm_year	= bcd2bin(data[6]) + 100; /* Assume we are in 20xx */
    254
    255	dev_dbg(dev, "Read from mcp795: %ptR\n", tim);
    256
    257	return 0;
    258}
    259
    260static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
    261{
    262	struct rtc_time now_tm;
    263	time64_t now;
    264	time64_t later;
    265	u8 tmp[6];
    266	int ret;
    267
    268	/* Read current time from RTC hardware */
    269	ret = mcp795_read_time(dev, &now_tm);
    270	if (ret)
    271		return ret;
    272	/* Get the number of seconds since 1970 */
    273	now = rtc_tm_to_time64(&now_tm);
    274	later = rtc_tm_to_time64(&alm->time);
    275	if (later <= now)
    276		return -EINVAL;
    277	/* make sure alarm fires within the next one year */
    278	if ((later - now) >=
    279		(SEC_PER_DAY * (365 + is_leap_year(alm->time.tm_year))))
    280		return -EDOM;
    281	/* disable alarm */
    282	ret = mcp795_update_alarm(dev, false);
    283	if (ret)
    284		return ret;
    285	/* Read registers, so we can leave configuration bits untouched */
    286	ret = mcp795_rtcc_read(dev, MCP795_REG_ALM0_SECONDS, tmp, sizeof(tmp));
    287	if (ret)
    288		return ret;
    289
    290	alm->time.tm_year	= -1;
    291	alm->time.tm_isdst	= -1;
    292	alm->time.tm_yday	= -1;
    293
    294	tmp[0] = (tmp[0] & 0x80) | bin2bcd(alm->time.tm_sec);
    295	tmp[1] = (tmp[1] & 0x80) | bin2bcd(alm->time.tm_min);
    296	tmp[2] = (tmp[2] & 0xE0) | bin2bcd(alm->time.tm_hour);
    297	tmp[3] = (tmp[3] & 0x80) | bin2bcd(alm->time.tm_wday + 1);
    298	/* set alarm match: seconds, minutes, hour, day, date and month */
    299	tmp[3] |= (MCP795_ALM0C2_BIT | MCP795_ALM0C1_BIT | MCP795_ALM0C0_BIT);
    300	tmp[4] = (tmp[4] & 0xC0) | bin2bcd(alm->time.tm_mday);
    301	tmp[5] = (tmp[5] & 0xE0) | bin2bcd(alm->time.tm_mon + 1);
    302
    303	ret = mcp795_rtcc_write(dev, MCP795_REG_ALM0_SECONDS, tmp, sizeof(tmp));
    304	if (ret)
    305		return ret;
    306
    307	/* enable alarm if requested */
    308	if (alm->enabled) {
    309		ret = mcp795_update_alarm(dev, true);
    310		if (ret)
    311			return ret;
    312		dev_dbg(dev, "Alarm IRQ armed\n");
    313	}
    314	dev_dbg(dev, "Set alarm: %ptRdr(%d) %ptRt\n",
    315		&alm->time, alm->time.tm_wday, &alm->time);
    316	return 0;
    317}
    318
    319static int mcp795_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
    320{
    321	u8 data[6];
    322	int ret;
    323
    324	ret = mcp795_rtcc_read(
    325			dev, MCP795_REG_ALM0_SECONDS, data, sizeof(data));
    326	if (ret)
    327		return ret;
    328
    329	alm->time.tm_sec	= bcd2bin(data[0] & 0x7F);
    330	alm->time.tm_min	= bcd2bin(data[1] & 0x7F);
    331	alm->time.tm_hour	= bcd2bin(data[2] & 0x1F);
    332	alm->time.tm_wday	= bcd2bin(data[3] & 0x07) - 1;
    333	alm->time.tm_mday	= bcd2bin(data[4] & 0x3F);
    334	alm->time.tm_mon	= bcd2bin(data[5] & 0x1F) - 1;
    335	alm->time.tm_year	= -1;
    336	alm->time.tm_isdst	= -1;
    337	alm->time.tm_yday	= -1;
    338
    339	dev_dbg(dev, "Read alarm: %ptRdr(%d) %ptRt\n",
    340		&alm->time, alm->time.tm_wday, &alm->time);
    341	return 0;
    342}
    343
    344static int mcp795_alarm_irq_enable(struct device *dev, unsigned int enabled)
    345{
    346	return mcp795_update_alarm(dev, !!enabled);
    347}
    348
    349static irqreturn_t mcp795_irq(int irq, void *data)
    350{
    351	struct spi_device *spi = data;
    352	struct rtc_device *rtc = spi_get_drvdata(spi);
    353	int ret;
    354
    355	rtc_lock(rtc);
    356
    357	/* Disable alarm.
    358	 * There is no need to clear ALM0IF (Alarm 0 Interrupt Flag) bit,
    359	 * because it is done every time when alarm is enabled.
    360	 */
    361	ret = mcp795_update_alarm(&spi->dev, false);
    362	if (ret)
    363		dev_err(&spi->dev,
    364			"Failed to disable alarm in IRQ (ret=%d)\n", ret);
    365	rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
    366
    367	rtc_unlock(rtc);
    368
    369	return IRQ_HANDLED;
    370}
    371
    372static const struct rtc_class_ops mcp795_rtc_ops = {
    373		.read_time = mcp795_read_time,
    374		.set_time = mcp795_set_time,
    375		.read_alarm = mcp795_read_alarm,
    376		.set_alarm = mcp795_set_alarm,
    377		.alarm_irq_enable = mcp795_alarm_irq_enable
    378};
    379
    380static int mcp795_probe(struct spi_device *spi)
    381{
    382	struct rtc_device *rtc;
    383	int ret;
    384
    385	spi->mode = SPI_MODE_0;
    386	spi->bits_per_word = 8;
    387	ret = spi_setup(spi);
    388	if (ret) {
    389		dev_err(&spi->dev, "Unable to setup SPI\n");
    390		return ret;
    391	}
    392
    393	/* Start the oscillator but don't set the value of EXTOSC bit */
    394	mcp795_start_oscillator(&spi->dev, NULL);
    395	/* Clear the 12 hour mode flag*/
    396	mcp795_rtcc_set_bits(&spi->dev, 0x03, MCP795_24_BIT, 0);
    397
    398	rtc = devm_rtc_device_register(&spi->dev, "rtc-mcp795",
    399					&mcp795_rtc_ops, THIS_MODULE);
    400	if (IS_ERR(rtc))
    401		return PTR_ERR(rtc);
    402
    403	spi_set_drvdata(spi, rtc);
    404
    405	if (spi->irq > 0) {
    406		dev_dbg(&spi->dev, "Alarm support enabled\n");
    407
    408		/* Clear any pending alarm (ALM0IF bit) before requesting
    409		 * the interrupt.
    410		 */
    411		mcp795_rtcc_set_bits(&spi->dev, MCP795_REG_ALM0_DAY,
    412					MCP795_ALM0IF_BIT, 0);
    413		ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
    414				mcp795_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
    415				dev_name(&rtc->dev), spi);
    416		if (ret)
    417			dev_err(&spi->dev, "Failed to request IRQ: %d: %d\n",
    418						spi->irq, ret);
    419		else
    420			device_init_wakeup(&spi->dev, true);
    421	}
    422	return 0;
    423}
    424
    425#ifdef CONFIG_OF
    426static const struct of_device_id mcp795_of_match[] = {
    427	{ .compatible = "maxim,mcp795" },
    428	{ }
    429};
    430MODULE_DEVICE_TABLE(of, mcp795_of_match);
    431#endif
    432
    433static const struct spi_device_id mcp795_spi_ids[] = {
    434	{ .name = "mcp795" },
    435	{ }
    436};
    437MODULE_DEVICE_TABLE(spi, mcp795_spi_ids);
    438
    439static struct spi_driver mcp795_driver = {
    440		.driver = {
    441				.name = "rtc-mcp795",
    442				.of_match_table = of_match_ptr(mcp795_of_match),
    443		},
    444		.probe = mcp795_probe,
    445		.id_table = mcp795_spi_ids,
    446};
    447
    448module_spi_driver(mcp795_driver);
    449
    450MODULE_DESCRIPTION("MCP795 RTC SPI Driver");
    451MODULE_AUTHOR("Josef Gajdusek <atx@atx.name>");
    452MODULE_LICENSE("GPL");
    453MODULE_ALIAS("spi:mcp795");