[coreboot-gerrit] Change in coreboot[master]: drivers/i2c: Add new driver for RTC type RX6110 SA

Patrick Georgi (Code Review) gerrit at coreboot.org
Thu May 11 16:46:19 CEST 2017


Patrick Georgi has submitted this change and it was merged. ( https://review.coreboot.org/19625 )

Change subject: drivers/i2c: Add new driver for RTC type RX6110 SA
......................................................................


drivers/i2c: Add new driver for RTC type RX6110 SA

This driver enables the usage of the external RTC chip RX6110 SA
(http://www5.epsondevice.com/en/products/i2c/rx6110sab.html) which is
connected to the I2C bus. The I2C address of this device is fixed. One
can change parameters in the device tree so that the used setup can be
adapted to match the configuration of the device on the mainboard.

Change-Id: I1290a10c2d5ad76a317c99c8b92a013309a605d6
Signed-off-by: Mario Scheithauer <mario.scheithauer at siemens.com>
Reviewed-on: https://review.coreboot.org/19625
Tested-by: build bot (Jenkins) <no-reply at coreboot.org>
Reviewed-by: Werner Zeh <werner.zeh at siemens.com>
---
A src/drivers/i2c/rx6110sa/Kconfig
A src/drivers/i2c/rx6110sa/Makefile.inc
A src/drivers/i2c/rx6110sa/chip.h
A src/drivers/i2c/rx6110sa/rx6110sa.c
A src/drivers/i2c/rx6110sa/rx6110sa.h
5 files changed, 237 insertions(+), 0 deletions(-)

Approvals:
  Werner Zeh: Looks good to me, approved
  build bot (Jenkins): Verified



diff --git a/src/drivers/i2c/rx6110sa/Kconfig b/src/drivers/i2c/rx6110sa/Kconfig
new file mode 100644
index 0000000..a5608f8
--- /dev/null
+++ b/src/drivers/i2c/rx6110sa/Kconfig
@@ -0,0 +1,5 @@
+config DRIVERS_I2C_RX6110SA
+	bool
+	default n
+	help
+	  Enable support for external RTC chip RX6110 SA.
diff --git a/src/drivers/i2c/rx6110sa/Makefile.inc b/src/drivers/i2c/rx6110sa/Makefile.inc
new file mode 100644
index 0000000..44c76a3
--- /dev/null
+++ b/src/drivers/i2c/rx6110sa/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_I2C_RX6110SA) += rx6110sa.c
diff --git a/src/drivers/i2c/rx6110sa/chip.h b/src/drivers/i2c/rx6110sa/chip.h
new file mode 100644
index 0000000..b90a529
--- /dev/null
+++ b/src/drivers/i2c/rx6110sa/chip.h
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include "rx6110sa.h"
+
+struct drivers_i2c_rx6110sa_config {
+	/* The day (of the week) is indicated by 7 bits, bit 0 to bit 6. */
+	unsigned char user_weekday;	/* User day of the week to set */
+	unsigned char user_day;		/* User day to set */
+	unsigned char user_month;	/* User month to set */
+	unsigned char user_year;	/* User year to set */
+	unsigned char set_user_date;	/* Use user date from device tree */
+	unsigned char cof_selection;	/* Set up "clock out" frequency */
+};
diff --git a/src/drivers/i2c/rx6110sa/rx6110sa.c b/src/drivers/i2c/rx6110sa/rx6110sa.c
new file mode 100644
index 0000000..743b708
--- /dev/null
+++ b/src/drivers/i2c/rx6110sa/rx6110sa.c
@@ -0,0 +1,146 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 Siemens AG.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/i2c.h>
+#include <device/device.h>
+#include <version.h>
+#include <console/console.h>
+#include <bcd.h>
+#include "chip.h"
+#include "rx6110sa.h"
+
+#define I2C_BUS_NUM	(dev->bus->secondary - 1)
+#define I2C_DEV_NUM	(dev->path.i2c.device)
+
+/* Set RTC date from coreboot build date. */
+static void rx6110sa_set_build_date(struct device *dev)
+{
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, YEAR_REG,
+			coreboot_build_date.year);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, MONTH_REG,
+			coreboot_build_date.month);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, DAY_REG,
+			coreboot_build_date.day);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, WEEK_REG,
+			(1 << coreboot_build_date.weekday));
+}
+
+/* Set RTC date from user defined date (available in e.g. device tree). */
+static void rx6110sa_set_user_date(struct device *dev)
+{
+	struct drivers_i2c_rx6110sa_config *config = dev->chip_info;
+
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, YEAR_REG,
+			bin2bcd(config->user_year));
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, MONTH_REG,
+			bin2bcd(config->user_month));
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, DAY_REG,
+			bin2bcd(config->user_day));
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, WEEK_REG,
+			(1 << config->user_weekday));
+}
+
+static void rx6110sa_final(struct device *dev)
+{
+	uint8_t hour, minute, second, year, month, day;
+
+	/* Read back current RTC date and time and print it to the console. */
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, HOUR_REG, &hour);
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, MINUTE_REG, &minute);
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, SECOND_REG, &second);
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, YEAR_REG, &year);
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, MONTH_REG, &month);
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, DAY_REG, &day);
+
+	printk(BIOS_INFO, "%s: Current date %02d.%02d.%02d %02d:%02d:%02d\n",
+		dev->chip_ops->name, bcd2bin(month), bcd2bin(day),
+		bcd2bin(year), bcd2bin(hour), bcd2bin(minute), bcd2bin(second));
+}
+
+static void rx6110sa_init(struct device *dev)
+{
+	struct drivers_i2c_rx6110sa_config *config = dev->chip_info;
+	uint8_t reg;
+
+	/* Do a dummy read first. */
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, SECOND_REG, &reg);
+
+	/*
+	 * Check VLF-bit which indicates the RTC data loss, such as due to a
+	 * supply voltage drop.
+	 */
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, FLAG_REGISTER, &reg);
+
+	if (!(reg & VLF_BIT))
+		/* No voltage low detected, everything is well. */
+		return;
+
+	/*
+	 * Voltage low detected, initialize RX6110 SA again.
+	 * Set first some registers to known state.
+	 */
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, BATTERY_BACKUP_REG, 0x00);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, RESERVED_BIT_REG, RTC_INIT_VALUE);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, DIGITAL_REG, 0x00);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, IRQ_CONTROL_REG, 0x00);
+
+	/* Clear timer enable bit and set frequency of clock output. */
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, EXTENSION_REG, &reg);
+	reg &= ~(FSEL_MASK | TE_BIT);
+	reg |= (config->cof_selection << 6);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, EXTENSION_REG, reg);
+
+	/* Clear voltage low detect bit. */
+	i2c_readb(I2C_BUS_NUM, I2C_DEV_NUM, FLAG_REGISTER, &reg);
+	reg &= ~VLF_BIT;
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, FLAG_REGISTER, reg);
+
+	/* Before setting the clock stop oscillator. */
+	i2c_writeb(I2C_BUS_NUM,	I2C_DEV_NUM, CTRL_REG, STOP_BIT);
+	if (config->set_user_date) {
+		/* Set user date defined in device tree. */
+		printk(BIOS_DEBUG, "%s: Set to user date\n",
+				dev->chip_ops->name);
+		rx6110sa_set_user_date(dev);
+	} else {
+		/* Set date from coreboot build. */
+		printk(BIOS_DEBUG, "%s: Set to coreboot build date\n",
+				dev->chip_ops->name);
+		rx6110sa_set_build_date(dev);
+	}
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, HOUR_REG, 1);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, MINUTE_REG, 0);
+	i2c_writeb(I2C_BUS_NUM, I2C_DEV_NUM, SECOND_REG, 0);
+	/* Start oscillator again as the RTC is set up now. */
+	i2c_writeb(I2C_BUS_NUM,	I2C_DEV_NUM, CTRL_REG, 0x00);
+}
+
+static struct device_operations rx6110sa_ops = {
+	.read_resources		= DEVICE_NOOP,
+	.set_resources		= DEVICE_NOOP,
+	.enable_resources	= DEVICE_NOOP,
+	.init			= rx6110sa_init,
+	.final			= rx6110sa_final
+};
+
+static void rx6110sa_enable(struct device *dev)
+{
+	dev->ops = &rx6110sa_ops;
+}
+
+struct chip_operations drivers_i2c_rx6110sa_ops = {
+	CHIP_NAME("RX6110 SA")
+	.enable_dev = rx6110sa_enable
+};
diff --git a/src/drivers/i2c/rx6110sa/rx6110sa.h b/src/drivers/i2c/rx6110sa/rx6110sa.h
new file mode 100644
index 0000000..99527e0
--- /dev/null
+++ b/src/drivers/i2c/rx6110sa/rx6110sa.h
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2017 Siemens AG
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _I2C_RX6110SA_H_
+#define _I2C_RX6110SA_H_
+
+/* The address of this RTC is fixed. */
+#define RX6110SA_SLAVE_ADR		0x32
+#define RX6110SA_I2C_CONTROLLER		0
+
+/* Register layout */
+#define SECOND_REG			0x10
+#define MINUTE_REG			0x11
+#define HOUR_REG			0x12
+#define WEEK_REG			0x13
+#define DAY_REG				0x14
+#define MONTH_REG			0x15
+#define YEAR_REG			0x16
+#define RESERVED_BIT_REG		0x17
+#define  RTC_INIT_VALUE			0x28
+#define ALARM_MINUTE_REG		0x18
+#define ALARM_HOUR_REG			0x19
+#define ALARM_WEEKDAY_REG		0x1A
+#define TMR_COUNTER_0_REG		0x1B
+#define TMR_COUNTER_1_REG		0x1C
+#define EXTENSION_REG			0x1D
+#define  TE_BIT				(1 << 4)
+#define  FSEL_MASK			0xC0
+#define FLAG_REGISTER			0x1E
+#define  VLF_BIT			(1 << 1)
+#define CTRL_REG			0x1F
+#define  AIE_BIT			(1 << 3)
+#define  TIE_BIT			(1 << 4)
+#define  UIE_BIT			(1 << 5)
+#define  STOP_BIT			(1 << 6)
+#define  TEST_BIT			(1 << 7)
+#define DIGITAL_REG			0x30
+#define BATTERY_BACKUP_REG		0x31
+#define IRQ_CONTROL_REG			0x32
+
+/* Define CLKOUT frequency divider values valid for parameter cof_selection */
+#define COF_OFF				0x00
+#define COF_1_HZ			0x01
+#define COF_1024_HZ			0x02
+#define COF_32768_HZ			0x03
+
+#endif /* _I2C_RX6110SA_H_ */

-- 
To view, visit https://review.coreboot.org/19625
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I1290a10c2d5ad76a317c99c8b92a013309a605d6
Gerrit-PatchSet: 3
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Mario Scheithauer <mario.scheithauer at siemens.com>
Gerrit-Reviewer: Mario Scheithauer <mario.scheithauer at siemens.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi at google.com>
Gerrit-Reviewer: Paul Menzel <paulepanter at users.sourceforge.net>
Gerrit-Reviewer: Philippe Mathieu-Daudé <philippe.mathieu.daude at gmail.com>
Gerrit-Reviewer: Werner Zeh <werner.zeh at siemens.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply at coreboot.org>



More information about the coreboot-gerrit mailing list