brintos

brintos / linux-shallow public Read only

0
0
Text · 14.4 KiB · aabe62c Raw
593 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Driver for Epson's RTC module RX-8025 SA/NB4 *5 * Copyright (C) 2009 Wolfgang Grandegger <wg@grandegger.com>6 *7 * Copyright (C) 2005 by Digi International Inc.8 * All rights reserved.9 *10 * Modified by fengjh at rising.com.cn11 * <lm-sensors@lm-sensors.org>12 * 2006.1113 *14 * Code cleanup by Sergei Poselenov, <sposelenov@emcraft.com>15 * Converted to new style by Wolfgang Grandegger <wg@grandegger.com>16 * Alarm and periodic interrupt added by Dmitry Rakhchev <rda@emcraft.com>17 */18#include <linux/bcd.h>19#include <linux/bitops.h>20#include <linux/i2c.h>21#include <linux/kernel.h>22#include <linux/kstrtox.h>23#include <linux/module.h>24#include <linux/rtc.h>25 26/* Register definitions */27#define RX8025_REG_SEC		0x0028#define RX8025_REG_MIN		0x0129#define RX8025_REG_HOUR		0x0230#define RX8025_REG_WDAY		0x0331#define RX8025_REG_MDAY		0x0432#define RX8025_REG_MONTH	0x0533#define RX8025_REG_YEAR		0x0634#define RX8025_REG_DIGOFF	0x0735#define RX8025_REG_ALWMIN	0x0836#define RX8025_REG_ALWHOUR	0x0937#define RX8025_REG_ALWWDAY	0x0a38#define RX8025_REG_ALDMIN	0x0b39#define RX8025_REG_ALDHOUR	0x0c40/* 0x0d is reserved */41#define RX8025_REG_CTRL1	0x0e42#define RX8025_REG_CTRL2	0x0f43 44#define RX8025_BIT_CTRL1_CT	(7 << 0)45/* 1 Hz periodic level irq */46#define RX8025_BIT_CTRL1_CT_1HZ	447#define RX8025_BIT_CTRL1_TEST	BIT(3)48#define RX8025_BIT_CTRL1_1224	BIT(5)49#define RX8025_BIT_CTRL1_DALE	BIT(6)50#define RX8025_BIT_CTRL1_WALE	BIT(7)51 52#define RX8025_BIT_CTRL2_DAFG	BIT(0)53#define RX8025_BIT_CTRL2_WAFG	BIT(1)54#define RX8025_BIT_CTRL2_CTFG	BIT(2)55#define RX8025_BIT_CTRL2_PON	BIT(4)56#define RX8025_BIT_CTRL2_XST	BIT(5)57#define RX8025_BIT_CTRL2_VDET	BIT(6)58 59#define RX8035_BIT_HOUR_1224	BIT(7)60 61/* Clock precision adjustment */62#define RX8025_ADJ_RESOLUTION	3050 /* in ppb */63#define RX8025_ADJ_DATA_MAX	6264#define RX8025_ADJ_DATA_MIN	-6265 66enum rx_model {67	model_rx_unknown,68	model_rx_8025,69	model_rx_8035,70	model_last71};72 73static const struct i2c_device_id rx8025_id[] = {74	{ "rx8025", model_rx_8025 },75	{ "rx8035", model_rx_8035 },76	{ }77};78MODULE_DEVICE_TABLE(i2c, rx8025_id);79 80struct rx8025_data {81	struct rtc_device *rtc;82	enum rx_model model;83	u8 ctrl1;84	int is_24;85};86 87static s32 rx8025_read_reg(const struct i2c_client *client, u8 number)88{89	return i2c_smbus_read_byte_data(client, number << 4);90}91 92static int rx8025_read_regs(const struct i2c_client *client,93			    u8 number, u8 length, u8 *values)94{95	int ret = i2c_smbus_read_i2c_block_data(client, number << 4, length,96						values);97	if (ret != length)98		return ret < 0 ? ret : -EIO;99 100	return 0;101}102 103static s32 rx8025_write_reg(const struct i2c_client *client, u8 number,104			    u8 value)105{106	return i2c_smbus_write_byte_data(client, number << 4, value);107}108 109static s32 rx8025_write_regs(const struct i2c_client *client,110			     u8 number, u8 length, const u8 *values)111{112	return i2c_smbus_write_i2c_block_data(client, number << 4,113					      length, values);114}115 116static int rx8025_is_osc_stopped(enum rx_model model, int ctrl2)117{118	int xstp = ctrl2 & RX8025_BIT_CTRL2_XST;119	/* XSTP bit has different polarity on RX-8025 vs RX-8035.120	 * RX-8025: 0 == oscillator stopped121	 * RX-8035: 1 == oscillator stopped122	 */123 124	if (model == model_rx_8025)125		xstp = !xstp;126 127	return xstp;128}129 130static int rx8025_check_validity(struct device *dev)131{132	struct i2c_client *client = to_i2c_client(dev);133	struct rx8025_data *drvdata = dev_get_drvdata(dev);134	int ctrl2;135	int xstp;136 137	ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2);138	if (ctrl2 < 0)139		return ctrl2;140 141	if (ctrl2 & RX8025_BIT_CTRL2_VDET)142		dev_warn(dev, "power voltage drop detected\n");143 144	if (ctrl2 & RX8025_BIT_CTRL2_PON) {145		dev_warn(dev, "power-on reset detected, date is invalid\n");146		return -EINVAL;147	}148 149	xstp = rx8025_is_osc_stopped(drvdata->model, ctrl2);150	if (xstp) {151		dev_warn(dev, "crystal stopped, date is invalid\n");152		return -EINVAL;153	}154 155	return 0;156}157 158static int rx8025_reset_validity(struct i2c_client *client)159{160	struct rx8025_data *drvdata = i2c_get_clientdata(client);161	int ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2);162 163	if (ctrl2 < 0)164		return ctrl2;165 166	ctrl2 &= ~(RX8025_BIT_CTRL2_PON | RX8025_BIT_CTRL2_VDET);167 168	if (drvdata->model == model_rx_8025)169		ctrl2 |= RX8025_BIT_CTRL2_XST;170	else171		ctrl2 &= ~(RX8025_BIT_CTRL2_XST);172 173	return rx8025_write_reg(client, RX8025_REG_CTRL2,174				ctrl2);175}176 177static irqreturn_t rx8025_handle_irq(int irq, void *dev_id)178{179	struct i2c_client *client = dev_id;180	struct rx8025_data *rx8025 = i2c_get_clientdata(client);181	int status, xstp;182 183	rtc_lock(rx8025->rtc);184	status = rx8025_read_reg(client, RX8025_REG_CTRL2);185	if (status < 0)186		goto out;187 188	xstp = rx8025_is_osc_stopped(rx8025->model, status);189	if (xstp)190		dev_warn(&client->dev, "Oscillation stop was detected,"191			 "you may have to readjust the clock\n");192 193	if (status & RX8025_BIT_CTRL2_CTFG) {194		/* periodic */195		status &= ~RX8025_BIT_CTRL2_CTFG;196		rtc_update_irq(rx8025->rtc, 1, RTC_PF | RTC_IRQF);197	}198 199	if (status & RX8025_BIT_CTRL2_DAFG) {200		/* alarm */201		status &= RX8025_BIT_CTRL2_DAFG;202		if (rx8025_write_reg(client, RX8025_REG_CTRL1,203				     rx8025->ctrl1 & ~RX8025_BIT_CTRL1_DALE))204			goto out;205		rtc_update_irq(rx8025->rtc, 1, RTC_AF | RTC_IRQF);206	}207 208out:209	rtc_unlock(rx8025->rtc);210 211	return IRQ_HANDLED;212}213 214static int rx8025_get_time(struct device *dev, struct rtc_time *dt)215{216	struct i2c_client *client = to_i2c_client(dev);217	struct rx8025_data *rx8025 = dev_get_drvdata(dev);218	u8 date[7];219	int err;220 221	err = rx8025_check_validity(dev);222	if (err)223		return err;224 225	err = rx8025_read_regs(client, RX8025_REG_SEC, 7, date);226	if (err)227		return err;228 229	dev_dbg(dev, "%s: read %7ph\n", __func__, date);230 231	dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f);232	dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f);233	if (rx8025->is_24)234		dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f);235	else236		dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x1f) % 12237			+ (date[RX8025_REG_HOUR] & 0x20 ? 12 : 0);238 239	dt->tm_mday = bcd2bin(date[RX8025_REG_MDAY] & 0x3f);240	dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1;241	dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]) + 100;242 243	dev_dbg(dev, "%s: date %ptRr\n", __func__, dt);244 245	return 0;246}247 248static int rx8025_set_time(struct device *dev, struct rtc_time *dt)249{250	struct i2c_client *client = to_i2c_client(dev);251	struct rx8025_data *rx8025 = dev_get_drvdata(dev);252	u8 date[7];253	int ret;254 255	/*256	 * Here the read-only bits are written as "0".  I'm not sure if that257	 * is sound.258	 */259	date[RX8025_REG_SEC] = bin2bcd(dt->tm_sec);260	date[RX8025_REG_MIN] = bin2bcd(dt->tm_min);261	if (rx8025->is_24)262		date[RX8025_REG_HOUR] = bin2bcd(dt->tm_hour);263	else264		date[RX8025_REG_HOUR] = (dt->tm_hour >= 12 ? 0x20 : 0)265			| bin2bcd((dt->tm_hour + 11) % 12 + 1);266 267	date[RX8025_REG_WDAY] = bin2bcd(dt->tm_wday);268	date[RX8025_REG_MDAY] = bin2bcd(dt->tm_mday);269	date[RX8025_REG_MONTH] = bin2bcd(dt->tm_mon + 1);270	date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year - 100);271 272	dev_dbg(dev, "%s: write %7ph\n", __func__, date);273 274	ret = rx8025_write_regs(client, RX8025_REG_SEC, 7, date);275	if (ret < 0)276		return ret;277 278	return rx8025_reset_validity(client);279}280 281static int rx8025_init_client(struct i2c_client *client)282{283	struct rx8025_data *rx8025 = i2c_get_clientdata(client);284	u8 ctrl[2], ctrl2;285	int need_clear = 0;286	int hour_reg;287	int err;288 289	err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl);290	if (err)291		goto out;292 293	/* Keep test bit zero ! */294	rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST;295 296	if (ctrl[1] & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) {297		dev_warn(&client->dev, "Alarm was detected\n");298		need_clear = 1;299	}300 301	if (ctrl[1] & RX8025_BIT_CTRL2_CTFG)302		need_clear = 1;303 304	if (need_clear) {305		ctrl2 = ctrl[1];306		ctrl2 &= ~(RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG |307			   RX8025_BIT_CTRL2_DAFG);308 309		err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2);310	}311 312	if (rx8025->model == model_rx_8035) {313		/* In RX-8035, 12/24 flag is in the hour register */314		hour_reg = rx8025_read_reg(client, RX8025_REG_HOUR);315		if (hour_reg < 0)316			return hour_reg;317		rx8025->is_24 = (hour_reg & RX8035_BIT_HOUR_1224);318	} else {319		rx8025->is_24 = (ctrl[1] & RX8025_BIT_CTRL1_1224);320	}321out:322	return err;323}324 325/* Alarm support */326static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)327{328	struct i2c_client *client = to_i2c_client(dev);329	struct rx8025_data *rx8025 = dev_get_drvdata(dev);330	u8 ald[2];331	int ctrl2, err;332 333	err = rx8025_read_regs(client, RX8025_REG_ALDMIN, 2, ald);334	if (err)335		return err;336 337	ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2);338	if (ctrl2 < 0)339		return ctrl2;340 341	dev_dbg(dev, "%s: read alarm 0x%02x 0x%02x ctrl2 %02x\n",342		__func__, ald[0], ald[1], ctrl2);343 344	/* Hardware alarms precision is 1 minute! */345	t->time.tm_sec = 0;346	t->time.tm_min = bcd2bin(ald[0] & 0x7f);347	if (rx8025->is_24)348		t->time.tm_hour = bcd2bin(ald[1] & 0x3f);349	else350		t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12351			+ (ald[1] & 0x20 ? 12 : 0);352 353	dev_dbg(dev, "%s: date: %ptRr\n", __func__, &t->time);354	t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE);355	t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled;356 357	return err;358}359 360static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)361{362	struct i2c_client *client = to_i2c_client(dev);363	struct rx8025_data *rx8025 = dev_get_drvdata(dev);364	u8 ald[2];365	int err;366 367	ald[0] = bin2bcd(t->time.tm_min);368	if (rx8025->is_24)369		ald[1] = bin2bcd(t->time.tm_hour);370	else371		ald[1] = (t->time.tm_hour >= 12 ? 0x20 : 0)372			| bin2bcd((t->time.tm_hour + 11) % 12 + 1);373 374	dev_dbg(dev, "%s: write 0x%02x 0x%02x\n", __func__, ald[0], ald[1]);375 376	if (rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE) {377		rx8025->ctrl1 &= ~RX8025_BIT_CTRL1_DALE;378		err = rx8025_write_reg(client, RX8025_REG_CTRL1,379				       rx8025->ctrl1);380		if (err)381			return err;382	}383	err = rx8025_write_regs(client, RX8025_REG_ALDMIN, 2, ald);384	if (err)385		return err;386 387	if (t->enabled) {388		rx8025->ctrl1 |= RX8025_BIT_CTRL1_DALE;389		err = rx8025_write_reg(client, RX8025_REG_CTRL1,390				       rx8025->ctrl1);391		if (err)392			return err;393	}394 395	return 0;396}397 398static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)399{400	struct i2c_client *client = to_i2c_client(dev);401	struct rx8025_data *rx8025 = dev_get_drvdata(dev);402	u8 ctrl1;403	int err;404 405	ctrl1 = rx8025->ctrl1;406	if (enabled)407		ctrl1 |= RX8025_BIT_CTRL1_DALE;408	else409		ctrl1 &= ~RX8025_BIT_CTRL1_DALE;410 411	if (ctrl1 != rx8025->ctrl1) {412		rx8025->ctrl1 = ctrl1;413		err = rx8025_write_reg(client, RX8025_REG_CTRL1,414				       rx8025->ctrl1);415		if (err)416			return err;417	}418	return 0;419}420 421/*422 * According to the RX8025 SA/NB application manual the frequency and423 * temperature characteristics can be approximated using the following424 * equation:425 *426 *   df = a * (ut - t)**2427 *428 *   df: Frequency deviation in any temperature429 *   a : Coefficient = (-35 +-5) * 10**-9430 *   ut: Ultimate temperature in degree = +25 +-5 degree431 *   t : Any temperature in degree432 */433static int rx8025_read_offset(struct device *dev, long *offset)434{435	struct i2c_client *client = to_i2c_client(dev);436	int digoff;437 438	digoff = rx8025_read_reg(client, RX8025_REG_DIGOFF);439	if (digoff < 0)440		return digoff;441 442	*offset = digoff >= 64 ? digoff - 128 : digoff;443	if (*offset > 0)444		(*offset)--;445	*offset *= RX8025_ADJ_RESOLUTION;446 447	return 0;448}449 450static int rx8025_set_offset(struct device *dev, long offset)451{452	struct i2c_client *client = to_i2c_client(dev);453	u8 digoff;454 455	offset /= RX8025_ADJ_RESOLUTION;456	if (offset > RX8025_ADJ_DATA_MAX)457		offset = RX8025_ADJ_DATA_MAX;458	else if (offset < RX8025_ADJ_DATA_MIN)459		offset = RX8025_ADJ_DATA_MIN;460	else if (offset > 0)461		offset++;462	else if (offset < 0)463		offset += 128;464	digoff = offset;465 466	return rx8025_write_reg(client, RX8025_REG_DIGOFF, digoff);467}468 469static const struct rtc_class_ops rx8025_rtc_ops = {470	.read_time = rx8025_get_time,471	.set_time = rx8025_set_time,472	.read_alarm = rx8025_read_alarm,473	.set_alarm = rx8025_set_alarm,474	.alarm_irq_enable = rx8025_alarm_irq_enable,475	.read_offset = rx8025_read_offset,476	.set_offset = rx8025_set_offset,477};478 479static ssize_t rx8025_sysfs_show_clock_adjust(struct device *dev,480					      struct device_attribute *attr,481					      char *buf)482{483	long adj;484	int err;485 486	dev_warn_once(dev, "clock_adjust_ppb is deprecated, use offset\n");487	err = rx8025_read_offset(dev, &adj);488	if (err)489		return err;490 491	return sprintf(buf, "%ld\n", -adj);492}493 494static ssize_t rx8025_sysfs_store_clock_adjust(struct device *dev,495					       struct device_attribute *attr,496					       const char *buf, size_t count)497{498	long adj;499	int err;500 501	dev_warn_once(dev, "clock_adjust_ppb is deprecated, use offset\n");502	if (kstrtol(buf, 10, &adj) != 0)503		return -EINVAL;504 505	err = rx8025_set_offset(dev, -adj);506 507	return err ? err : count;508}509 510static DEVICE_ATTR(clock_adjust_ppb, S_IRUGO | S_IWUSR,511		   rx8025_sysfs_show_clock_adjust,512		   rx8025_sysfs_store_clock_adjust);513 514static struct attribute *rx8025_attrs[] = {515	&dev_attr_clock_adjust_ppb.attr,516	NULL517};518 519static const struct attribute_group rx8025_attr_group = {520	.attrs	= rx8025_attrs,521};522 523static int rx8025_probe(struct i2c_client *client)524{525	const struct i2c_device_id *id = i2c_match_id(rx8025_id, client);526	struct i2c_adapter *adapter = client->adapter;527	struct rx8025_data *rx8025;528	int err = 0;529 530	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA531				     | I2C_FUNC_SMBUS_I2C_BLOCK)) {532		dev_err(&adapter->dev,533			"doesn't support required functionality\n");534		return -EIO;535	}536 537	rx8025 = devm_kzalloc(&client->dev, sizeof(*rx8025), GFP_KERNEL);538	if (!rx8025)539		return -ENOMEM;540 541	i2c_set_clientdata(client, rx8025);542 543	if (id)544		rx8025->model = id->driver_data;545 546	err = rx8025_init_client(client);547	if (err)548		return err;549 550	rx8025->rtc = devm_rtc_allocate_device(&client->dev);551	if (IS_ERR(rx8025->rtc))552		return PTR_ERR(rx8025->rtc);553 554	rx8025->rtc->ops = &rx8025_rtc_ops;555	rx8025->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;556	rx8025->rtc->range_max = RTC_TIMESTAMP_END_2099;557 558	if (client->irq > 0) {559		dev_info(&client->dev, "IRQ %d supplied\n", client->irq);560		err = devm_request_threaded_irq(&client->dev, client->irq, NULL,561						rx8025_handle_irq,562						IRQF_ONESHOT,563						"rx8025", client);564		if (err)565			clear_bit(RTC_FEATURE_ALARM, rx8025->rtc->features);566	}567 568	rx8025->rtc->max_user_freq = 1;569 570	set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rx8025->rtc->features);571	clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rx8025->rtc->features);572 573	err = rtc_add_group(rx8025->rtc, &rx8025_attr_group);574	if (err)575		return err;576 577	return devm_rtc_register_device(rx8025->rtc);578}579 580static struct i2c_driver rx8025_driver = {581	.driver = {582		.name = "rtc-rx8025",583	},584	.probe		= rx8025_probe,585	.id_table	= rx8025_id,586};587 588module_i2c_driver(rx8025_driver);589 590MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");591MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver");592MODULE_LICENSE("GPL");593