brintos

brintos / linux-shallow public Read only

0
0
Text · 12.1 KiB · 7c423d6 Raw
514 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for the Epson RTC module RX-6110 SA4 *5 * Copyright(C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>6 * Copyright(C) SEIKO EPSON CORPORATION 2013. All rights reserved.7 */8 9#include <linux/bcd.h>10#include <linux/init.h>11#include <linux/kernel.h>12#include <linux/module.h>13#include <linux/regmap.h>14#include <linux/rtc.h>15#include <linux/of.h>16#include <linux/spi/spi.h>17#include <linux/i2c.h>18 19/* RX-6110 Register definitions */20#define RX6110_REG_SEC		0x1021#define RX6110_REG_MIN		0x1122#define RX6110_REG_HOUR		0x1223#define RX6110_REG_WDAY		0x1324#define RX6110_REG_MDAY		0x1425#define RX6110_REG_MONTH	0x1526#define RX6110_REG_YEAR		0x1627#define RX6110_REG_RES1		0x1728#define RX6110_REG_ALMIN	0x1829#define RX6110_REG_ALHOUR	0x1930#define RX6110_REG_ALWDAY	0x1A31#define RX6110_REG_TCOUNT0	0x1B32#define RX6110_REG_TCOUNT1	0x1C33#define RX6110_REG_EXT		0x1D34#define RX6110_REG_FLAG		0x1E35#define RX6110_REG_CTRL		0x1F36#define RX6110_REG_USER0	0x2037#define RX6110_REG_USER1	0x2138#define RX6110_REG_USER2	0x2239#define RX6110_REG_USER3	0x2340#define RX6110_REG_USER4	0x2441#define RX6110_REG_USER5	0x2542#define RX6110_REG_USER6	0x2643#define RX6110_REG_USER7	0x2744#define RX6110_REG_USER8	0x2845#define RX6110_REG_USER9	0x2946#define RX6110_REG_USERA	0x2A47#define RX6110_REG_USERB	0x2B48#define RX6110_REG_USERC	0x2C49#define RX6110_REG_USERD	0x2D50#define RX6110_REG_USERE	0x2E51#define RX6110_REG_USERF	0x2F52#define RX6110_REG_RES2		0x3053#define RX6110_REG_RES3		0x3154#define RX6110_REG_IRQ		0x3255 56#define RX6110_BIT_ALARM_EN		BIT(7)57 58/* Extension Register (1Dh) bit positions */59#define RX6110_BIT_EXT_TSEL0		BIT(0)60#define RX6110_BIT_EXT_TSEL1		BIT(1)61#define RX6110_BIT_EXT_TSEL2		BIT(2)62#define RX6110_BIT_EXT_WADA		BIT(3)63#define RX6110_BIT_EXT_TE		BIT(4)64#define RX6110_BIT_EXT_USEL		BIT(5)65#define RX6110_BIT_EXT_FSEL0		BIT(6)66#define RX6110_BIT_EXT_FSEL1		BIT(7)67 68/* Flag Register (1Eh) bit positions */69#define RX6110_BIT_FLAG_VLF		BIT(1)70#define RX6110_BIT_FLAG_AF		BIT(3)71#define RX6110_BIT_FLAG_TF		BIT(4)72#define RX6110_BIT_FLAG_UF		BIT(5)73 74/* Control Register (1Fh) bit positions */75#define RX6110_BIT_CTRL_TBKE		BIT(0)76#define RX6110_BIT_CTRL_TBKON		BIT(1)77#define RX6110_BIT_CTRL_TSTP		BIT(2)78#define RX6110_BIT_CTRL_AIE		BIT(3)79#define RX6110_BIT_CTRL_TIE		BIT(4)80#define RX6110_BIT_CTRL_UIE		BIT(5)81#define RX6110_BIT_CTRL_STOP		BIT(6)82#define RX6110_BIT_CTRL_TEST		BIT(7)83 84enum {85	RTC_SEC = 0,86	RTC_MIN,87	RTC_HOUR,88	RTC_WDAY,89	RTC_MDAY,90	RTC_MONTH,91	RTC_YEAR,92	RTC_NR_TIME93};94 95#define RX6110_DRIVER_NAME		"rx6110"96 97struct rx6110_data {98	struct rtc_device *rtc;99	struct regmap *regmap;100};101 102/**103 * rx6110_rtc_tm_to_data - convert rtc_time to native time encoding104 *105 * @tm: holds date and time106 * @data: holds the encoding in rx6110 native form107 */108static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *data)109{110	pr_debug("%s: date %ptRr\n", __func__, tm);111 112	/*113	 * The year in the RTC is a value between 0 and 99.114	 * Assume that this represents the current century115	 * and disregard all other values.116	 */117	if (tm->tm_year < 100 || tm->tm_year >= 200)118		return -EINVAL;119 120	data[RTC_SEC] = bin2bcd(tm->tm_sec);121	data[RTC_MIN] = bin2bcd(tm->tm_min);122	data[RTC_HOUR] = bin2bcd(tm->tm_hour);123	data[RTC_WDAY] = BIT(bin2bcd(tm->tm_wday));124	data[RTC_MDAY] = bin2bcd(tm->tm_mday);125	data[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);126	data[RTC_YEAR] = bin2bcd(tm->tm_year % 100);127 128	return 0;129}130 131/**132 * rx6110_data_to_rtc_tm - convert native time encoding to rtc_time133 *134 * @data: holds the encoding in rx6110 native form135 * @tm: holds date and time136 */137static int rx6110_data_to_rtc_tm(u8 *data, struct rtc_time *tm)138{139	tm->tm_sec = bcd2bin(data[RTC_SEC] & 0x7f);140	tm->tm_min = bcd2bin(data[RTC_MIN] & 0x7f);141	/* only 24-hour clock */142	tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);143	tm->tm_wday = ffs(data[RTC_WDAY] & 0x7f);144	tm->tm_mday = bcd2bin(data[RTC_MDAY] & 0x3f);145	tm->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1;146	tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100;147 148	pr_debug("%s: date %ptRr\n", __func__, tm);149 150	/*151	 * The year in the RTC is a value between 0 and 99.152	 * Assume that this represents the current century153	 * and disregard all other values.154	 */155	if (tm->tm_year < 100 || tm->tm_year >= 200)156		return -EINVAL;157 158	return 0;159}160 161/**162 * rx6110_set_time - set the current time in the rx6110 registers163 *164 * @dev: the rtc device in use165 * @tm: holds date and time166 *167 * BUG: The HW assumes every year that is a multiple of 4 to be a leap168 * year. Next time this is wrong is 2100, which will not be a leap year169 *170 * Note: If STOP is not set/cleared, the clock will start when the seconds171 *       register is written172 *173 */174static int rx6110_set_time(struct device *dev, struct rtc_time *tm)175{176	struct rx6110_data *rx6110 = dev_get_drvdata(dev);177	u8 data[RTC_NR_TIME];178	int ret;179 180	ret = rx6110_rtc_tm_to_data(tm, data);181	if (ret < 0)182		return ret;183 184	/* set STOP bit before changing clock/calendar */185	ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL,186				 RX6110_BIT_CTRL_STOP, RX6110_BIT_CTRL_STOP);187	if (ret)188		return ret;189 190	ret = regmap_bulk_write(rx6110->regmap, RX6110_REG_SEC, data,191				RTC_NR_TIME);192	if (ret)193		return ret;194 195	/* The time in the RTC is valid. Be sure to have VLF cleared. */196	ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG,197				 RX6110_BIT_FLAG_VLF, 0);198	if (ret)199		return ret;200 201	/* clear STOP bit after changing clock/calendar */202	ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL,203				 RX6110_BIT_CTRL_STOP, 0);204 205	return ret;206}207 208/**209 * rx6110_get_time - get the current time from the rx6110 registers210 * @dev: the rtc device in use211 * @tm: holds date and time212 */213static int rx6110_get_time(struct device *dev, struct rtc_time *tm)214{215	struct rx6110_data *rx6110 = dev_get_drvdata(dev);216	u8 data[RTC_NR_TIME];217	int flags;218	int ret;219 220	ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags);221	if (ret)222		return -EINVAL;223 224	/* check for VLF Flag (set at power-on) */225	if ((flags & RX6110_BIT_FLAG_VLF)) {226		dev_warn(dev, "Voltage low, data is invalid.\n");227		return -EINVAL;228	}229 230	/* read registers to date */231	ret = regmap_bulk_read(rx6110->regmap, RX6110_REG_SEC, data,232			       RTC_NR_TIME);233	if (ret)234		return ret;235 236	ret = rx6110_data_to_rtc_tm(data, tm);237	if (ret)238		return ret;239 240	dev_dbg(dev, "%s: date %ptRr\n", __func__, tm);241 242	return 0;243}244 245static const struct reg_sequence rx6110_default_regs[] = {246	{ RX6110_REG_RES1,   0xB8 },247	{ RX6110_REG_RES2,   0x00 },248	{ RX6110_REG_RES3,   0x10 },249	{ RX6110_REG_IRQ,    0x00 },250	{ RX6110_REG_ALMIN,  0x00 },251	{ RX6110_REG_ALHOUR, 0x00 },252	{ RX6110_REG_ALWDAY, 0x00 },253};254 255/**256 * rx6110_init - initialize the rx6110 registers257 *258 * @rx6110: pointer to the rx6110 struct in use259 *260 */261static int rx6110_init(struct rx6110_data *rx6110)262{263	struct rtc_device *rtc = rx6110->rtc;264	int flags;265	int ret;266 267	ret = regmap_update_bits(rx6110->regmap, RX6110_REG_EXT,268				 RX6110_BIT_EXT_TE, 0);269	if (ret)270		return ret;271 272	ret = regmap_register_patch(rx6110->regmap, rx6110_default_regs,273				    ARRAY_SIZE(rx6110_default_regs));274	if (ret)275		return ret;276 277	ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags);278	if (ret)279		return ret;280 281	/* check for VLF Flag (set at power-on) */282	if ((flags & RX6110_BIT_FLAG_VLF))283		dev_warn(&rtc->dev, "Voltage low, data loss detected.\n");284 285	/* check for Alarm Flag */286	if (flags & RX6110_BIT_FLAG_AF)287		dev_warn(&rtc->dev, "An alarm may have been missed.\n");288 289	/* check for Periodic Timer Flag */290	if (flags & RX6110_BIT_FLAG_TF)291		dev_warn(&rtc->dev, "Periodic timer was detected\n");292 293	/* check for Update Timer Flag */294	if (flags & RX6110_BIT_FLAG_UF)295		dev_warn(&rtc->dev, "Update timer was detected\n");296 297	/* clear all flags BUT VLF */298	ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG,299				 RX6110_BIT_FLAG_AF |300				 RX6110_BIT_FLAG_UF |301				 RX6110_BIT_FLAG_TF,302				 0);303 304	return ret;305}306 307static const struct rtc_class_ops rx6110_rtc_ops = {308	.read_time = rx6110_get_time,309	.set_time = rx6110_set_time,310};311 312static int rx6110_probe(struct rx6110_data *rx6110, struct device *dev)313{314	int err;315 316	rx6110->rtc = devm_rtc_device_register(dev,317					       RX6110_DRIVER_NAME,318					       &rx6110_rtc_ops, THIS_MODULE);319 320	if (IS_ERR(rx6110->rtc))321		return PTR_ERR(rx6110->rtc);322 323	err = rx6110_init(rx6110);324	if (err)325		return err;326 327	rx6110->rtc->max_user_freq = 1;328 329	return 0;330}331 332#if IS_ENABLED(CONFIG_SPI_MASTER)333static const struct regmap_config regmap_spi_config = {334	.reg_bits = 8,335	.val_bits = 8,336	.max_register = RX6110_REG_IRQ,337	.read_flag_mask = 0x80,338};339 340/**341 * rx6110_spi_probe - initialize rtc driver342 * @spi: pointer to spi device343 */344static int rx6110_spi_probe(struct spi_device *spi)345{346	struct rx6110_data *rx6110;347 348	if ((spi->bits_per_word && spi->bits_per_word != 8) ||349	    (spi->max_speed_hz > 2000000) ||350	    (spi->mode != (SPI_CS_HIGH | SPI_CPOL | SPI_CPHA))) {351		dev_warn(&spi->dev, "SPI settings: bits_per_word: %d, max_speed_hz: %d, mode: %xh\n",352			 spi->bits_per_word, spi->max_speed_hz, spi->mode);353		dev_warn(&spi->dev, "driving device in an unsupported mode");354	}355 356	rx6110 = devm_kzalloc(&spi->dev, sizeof(*rx6110), GFP_KERNEL);357	if (!rx6110)358		return -ENOMEM;359 360	rx6110->regmap = devm_regmap_init_spi(spi, &regmap_spi_config);361	if (IS_ERR(rx6110->regmap)) {362		dev_err(&spi->dev, "regmap init failed for rtc rx6110\n");363		return PTR_ERR(rx6110->regmap);364	}365 366	spi_set_drvdata(spi, rx6110);367 368	return rx6110_probe(rx6110, &spi->dev);369}370 371static const struct spi_device_id rx6110_spi_id[] = {372	{ "rx6110", 0 },373	{ }374};375MODULE_DEVICE_TABLE(spi, rx6110_spi_id);376 377static const __maybe_unused struct of_device_id rx6110_spi_of_match[] = {378	{ .compatible = "epson,rx6110" },379	{ },380};381MODULE_DEVICE_TABLE(of, rx6110_spi_of_match);382 383static struct spi_driver rx6110_spi_driver = {384	.driver = {385		.name = RX6110_DRIVER_NAME,386		.of_match_table = of_match_ptr(rx6110_spi_of_match),387	},388	.probe		= rx6110_spi_probe,389	.id_table	= rx6110_spi_id,390};391 392static int rx6110_spi_register(void)393{394	return spi_register_driver(&rx6110_spi_driver);395}396 397static void rx6110_spi_unregister(void)398{399	spi_unregister_driver(&rx6110_spi_driver);400}401#else402static int rx6110_spi_register(void)403{404	return 0;405}406 407static void rx6110_spi_unregister(void)408{409}410#endif /* CONFIG_SPI_MASTER */411 412#if IS_ENABLED(CONFIG_I2C)413static const struct regmap_config regmap_i2c_config = {414	.reg_bits = 8,415	.val_bits = 8,416	.max_register = RX6110_REG_IRQ,417	.read_flag_mask = 0x80,418};419 420static int rx6110_i2c_probe(struct i2c_client *client)421{422	struct i2c_adapter *adapter = client->adapter;423	struct rx6110_data *rx6110;424 425	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA426				| I2C_FUNC_SMBUS_I2C_BLOCK)) {427		dev_err(&adapter->dev,428			"doesn't support required functionality\n");429		return -EIO;430	}431 432	rx6110 = devm_kzalloc(&client->dev, sizeof(*rx6110), GFP_KERNEL);433	if (!rx6110)434		return -ENOMEM;435 436	rx6110->regmap = devm_regmap_init_i2c(client, &regmap_i2c_config);437	if (IS_ERR(rx6110->regmap)) {438		dev_err(&client->dev, "regmap init failed for rtc rx6110\n");439		return PTR_ERR(rx6110->regmap);440	}441 442	i2c_set_clientdata(client, rx6110);443 444	return rx6110_probe(rx6110, &client->dev);445}446 447static const struct acpi_device_id rx6110_i2c_acpi_match[] = {448	{ "SECC6110" },449	{ }450};451MODULE_DEVICE_TABLE(acpi, rx6110_i2c_acpi_match);452 453static const struct i2c_device_id rx6110_i2c_id[] = {454	{ "rx6110" },455	{ }456};457MODULE_DEVICE_TABLE(i2c, rx6110_i2c_id);458 459static struct i2c_driver rx6110_i2c_driver = {460	.driver = {461		.name = RX6110_DRIVER_NAME,462		.acpi_match_table = rx6110_i2c_acpi_match,463	},464	.probe		= rx6110_i2c_probe,465	.id_table	= rx6110_i2c_id,466};467 468static int rx6110_i2c_register(void)469{470	return i2c_add_driver(&rx6110_i2c_driver);471}472 473static void rx6110_i2c_unregister(void)474{475	i2c_del_driver(&rx6110_i2c_driver);476}477#else478static int rx6110_i2c_register(void)479{480	return 0;481}482 483static void rx6110_i2c_unregister(void)484{485}486#endif /* CONFIG_I2C */487 488static int __init rx6110_module_init(void)489{490	int ret;491 492	ret = rx6110_spi_register();493	if (ret)494		return ret;495 496	ret = rx6110_i2c_register();497	if (ret)498		rx6110_spi_unregister();499 500	return ret;501}502module_init(rx6110_module_init);503 504static void __exit rx6110_module_exit(void)505{506	rx6110_spi_unregister();507	rx6110_i2c_unregister();508}509module_exit(rx6110_module_exit);510 511MODULE_AUTHOR("Val Krutov <val.krutov@erd.epson.com>");512MODULE_DESCRIPTION("RX-6110 SA RTC driver");513MODULE_LICENSE("GPL");514