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-max6900.c (6160B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * rtc class driver for the Maxim MAX6900 chip
      4 *
      5 * Copyright (c) 2007 MontaVista, Software, Inc.
      6 *
      7 * Author: Dale Farnsworth <dale@farnsworth.org>
      8 *
      9 * based on previously existing rtc class drivers
     10 */
     11
     12#include <linux/module.h>
     13#include <linux/i2c.h>
     14#include <linux/bcd.h>
     15#include <linux/rtc.h>
     16#include <linux/delay.h>
     17
     18/*
     19 * register indices
     20 */
     21#define MAX6900_REG_SC			0	/* seconds      00-59 */
     22#define MAX6900_REG_MN			1	/* minutes      00-59 */
     23#define MAX6900_REG_HR			2	/* hours        00-23 */
     24#define MAX6900_REG_DT			3	/* day of month 00-31 */
     25#define MAX6900_REG_MO			4	/* month        01-12 */
     26#define MAX6900_REG_DW			5	/* day of week   1-7  */
     27#define MAX6900_REG_YR			6	/* year         00-99 */
     28#define MAX6900_REG_CT			7	/* control */
     29						/* register 8 is undocumented */
     30#define MAX6900_REG_CENTURY		9	/* century */
     31#define MAX6900_REG_LEN			10
     32
     33#define MAX6900_BURST_LEN		8	/* can burst r/w first 8 regs */
     34
     35#define MAX6900_REG_CT_WP		(1 << 7)	/* Write Protect */
     36
     37/*
     38 * register read/write commands
     39 */
     40#define MAX6900_REG_CONTROL_WRITE	0x8e
     41#define MAX6900_REG_CENTURY_WRITE	0x92
     42#define MAX6900_REG_CENTURY_READ	0x93
     43#define MAX6900_REG_RESERVED_READ	0x96
     44#define MAX6900_REG_BURST_WRITE		0xbe
     45#define MAX6900_REG_BURST_READ		0xbf
     46
     47#define MAX6900_IDLE_TIME_AFTER_WRITE	3	/* specification says 2.5 mS */
     48
     49static struct i2c_driver max6900_driver;
     50
     51static int max6900_i2c_read_regs(struct i2c_client *client, u8 *buf)
     52{
     53	u8 reg_burst_read[1] = { MAX6900_REG_BURST_READ };
     54	u8 reg_century_read[1] = { MAX6900_REG_CENTURY_READ };
     55	struct i2c_msg msgs[4] = {
     56		{
     57		 .addr = client->addr,
     58		 .flags = 0,	/* write */
     59		 .len = sizeof(reg_burst_read),
     60		 .buf = reg_burst_read}
     61		,
     62		{
     63		 .addr = client->addr,
     64		 .flags = I2C_M_RD,
     65		 .len = MAX6900_BURST_LEN,
     66		 .buf = buf}
     67		,
     68		{
     69		 .addr = client->addr,
     70		 .flags = 0,	/* write */
     71		 .len = sizeof(reg_century_read),
     72		 .buf = reg_century_read}
     73		,
     74		{
     75		 .addr = client->addr,
     76		 .flags = I2C_M_RD,
     77		 .len = sizeof(buf[MAX6900_REG_CENTURY]),
     78		 .buf = &buf[MAX6900_REG_CENTURY]
     79		 }
     80	};
     81	int rc;
     82
     83	rc = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
     84	if (rc != ARRAY_SIZE(msgs)) {
     85		dev_err(&client->dev, "%s: register read failed\n", __func__);
     86		return -EIO;
     87	}
     88	return 0;
     89}
     90
     91static int max6900_i2c_write_regs(struct i2c_client *client, u8 const *buf)
     92{
     93	u8 i2c_century_buf[1 + 1] = { MAX6900_REG_CENTURY_WRITE };
     94	struct i2c_msg century_msgs[1] = {
     95		{
     96		 .addr = client->addr,
     97		 .flags = 0,	/* write */
     98		 .len = sizeof(i2c_century_buf),
     99		 .buf = i2c_century_buf}
    100	};
    101	u8 i2c_burst_buf[MAX6900_BURST_LEN + 1] = { MAX6900_REG_BURST_WRITE };
    102	struct i2c_msg burst_msgs[1] = {
    103		{
    104		 .addr = client->addr,
    105		 .flags = 0,	/* write */
    106		 .len = sizeof(i2c_burst_buf),
    107		 .buf = i2c_burst_buf}
    108	};
    109	int rc;
    110
    111	/*
    112	 * We have to make separate calls to i2c_transfer because of
    113	 * the need to delay after each write to the chip.  Also,
    114	 * we write the century byte first, since we set the write-protect
    115	 * bit as part of the burst write.
    116	 */
    117	i2c_century_buf[1] = buf[MAX6900_REG_CENTURY];
    118
    119	rc = i2c_transfer(client->adapter, century_msgs,
    120			  ARRAY_SIZE(century_msgs));
    121	if (rc != ARRAY_SIZE(century_msgs))
    122		goto write_failed;
    123
    124	msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
    125
    126	memcpy(&i2c_burst_buf[1], buf, MAX6900_BURST_LEN);
    127
    128	rc = i2c_transfer(client->adapter, burst_msgs, ARRAY_SIZE(burst_msgs));
    129	if (rc != ARRAY_SIZE(burst_msgs))
    130		goto write_failed;
    131	msleep(MAX6900_IDLE_TIME_AFTER_WRITE);
    132
    133	return 0;
    134
    135 write_failed:
    136	dev_err(&client->dev, "%s: register write failed\n", __func__);
    137	return -EIO;
    138}
    139
    140static int max6900_rtc_read_time(struct device *dev, struct rtc_time *tm)
    141{
    142	struct i2c_client *client = to_i2c_client(dev);
    143	int rc;
    144	u8 regs[MAX6900_REG_LEN];
    145
    146	rc = max6900_i2c_read_regs(client, regs);
    147	if (rc < 0)
    148		return rc;
    149
    150	tm->tm_sec = bcd2bin(regs[MAX6900_REG_SC]);
    151	tm->tm_min = bcd2bin(regs[MAX6900_REG_MN]);
    152	tm->tm_hour = bcd2bin(regs[MAX6900_REG_HR] & 0x3f);
    153	tm->tm_mday = bcd2bin(regs[MAX6900_REG_DT]);
    154	tm->tm_mon = bcd2bin(regs[MAX6900_REG_MO]) - 1;
    155	tm->tm_year = bcd2bin(regs[MAX6900_REG_YR]) +
    156		      bcd2bin(regs[MAX6900_REG_CENTURY]) * 100 - 1900;
    157	tm->tm_wday = bcd2bin(regs[MAX6900_REG_DW]);
    158
    159	return 0;
    160}
    161
    162static int max6900_i2c_clear_write_protect(struct i2c_client *client)
    163{
    164	return i2c_smbus_write_byte_data(client, MAX6900_REG_CONTROL_WRITE, 0);
    165}
    166
    167static int max6900_rtc_set_time(struct device *dev, struct rtc_time *tm)
    168{
    169	struct i2c_client *client = to_i2c_client(dev);
    170	u8 regs[MAX6900_REG_LEN];
    171	int rc;
    172
    173	rc = max6900_i2c_clear_write_protect(client);
    174	if (rc < 0)
    175		return rc;
    176
    177	regs[MAX6900_REG_SC] = bin2bcd(tm->tm_sec);
    178	regs[MAX6900_REG_MN] = bin2bcd(tm->tm_min);
    179	regs[MAX6900_REG_HR] = bin2bcd(tm->tm_hour);
    180	regs[MAX6900_REG_DT] = bin2bcd(tm->tm_mday);
    181	regs[MAX6900_REG_MO] = bin2bcd(tm->tm_mon + 1);
    182	regs[MAX6900_REG_DW] = bin2bcd(tm->tm_wday);
    183	regs[MAX6900_REG_YR] = bin2bcd(tm->tm_year % 100);
    184	regs[MAX6900_REG_CENTURY] = bin2bcd((tm->tm_year + 1900) / 100);
    185	/* set write protect */
    186	regs[MAX6900_REG_CT] = MAX6900_REG_CT_WP;
    187
    188	rc = max6900_i2c_write_regs(client, regs);
    189	if (rc < 0)
    190		return rc;
    191
    192	return 0;
    193}
    194
    195static const struct rtc_class_ops max6900_rtc_ops = {
    196	.read_time = max6900_rtc_read_time,
    197	.set_time = max6900_rtc_set_time,
    198};
    199
    200static int
    201max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
    202{
    203	struct rtc_device *rtc;
    204
    205	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
    206		return -ENODEV;
    207
    208	rtc = devm_rtc_device_register(&client->dev, max6900_driver.driver.name,
    209					&max6900_rtc_ops, THIS_MODULE);
    210	if (IS_ERR(rtc))
    211		return PTR_ERR(rtc);
    212
    213	i2c_set_clientdata(client, rtc);
    214
    215	return 0;
    216}
    217
    218static const struct i2c_device_id max6900_id[] = {
    219	{ "max6900", 0 },
    220	{ }
    221};
    222MODULE_DEVICE_TABLE(i2c, max6900_id);
    223
    224static struct i2c_driver max6900_driver = {
    225	.driver = {
    226		   .name = "rtc-max6900",
    227		   },
    228	.probe = max6900_probe,
    229	.id_table = max6900_id,
    230};
    231
    232module_i2c_driver(max6900_driver);
    233
    234MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
    235MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
    236MODULE_LICENSE("GPL");