brintos

brintos / linux-shallow public Read only

0
0
Text · 11.6 KiB · ef913cf Raw
481 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * EPSON TOYOCOM RTC-7301SF/DG Driver4 *5 * Copyright (c) 2016 Akinobu Mita <akinobu.mita@gmail.com>6 *7 * Based on rtc-rp5c01.c8 *9 * Datasheet: http://www5.epsondevice.com/en/products/parallel/rtc7301sf.html10 */11 12#include <linux/io.h>13#include <linux/kernel.h>14#include <linux/module.h>15#include <linux/mod_devicetable.h>16#include <linux/delay.h>17#include <linux/property.h>18#include <linux/regmap.h>19#include <linux/platform_device.h>20#include <linux/rtc.h>21 22#define DRV_NAME "rtc-r7301"23 24#define RTC7301_1_SEC		0x0	/* Bank 0 and Band 1 */25#define RTC7301_10_SEC		0x1	/* Bank 0 and Band 1 */26#define RTC7301_AE		BIT(3)27#define RTC7301_1_MIN		0x2	/* Bank 0 and Band 1 */28#define RTC7301_10_MIN		0x3	/* Bank 0 and Band 1 */29#define RTC7301_1_HOUR		0x4	/* Bank 0 and Band 1 */30#define RTC7301_10_HOUR		0x5	/* Bank 0 and Band 1 */31#define RTC7301_DAY_OF_WEEK	0x6	/* Bank 0 and Band 1 */32#define RTC7301_1_DAY		0x7	/* Bank 0 and Band 1 */33#define RTC7301_10_DAY		0x8	/* Bank 0 and Band 1 */34#define RTC7301_1_MONTH		0x9	/* Bank 0 */35#define RTC7301_10_MONTH	0xa	/* Bank 0 */36#define RTC7301_1_YEAR		0xb	/* Bank 0 */37#define RTC7301_10_YEAR		0xc	/* Bank 0 */38#define RTC7301_100_YEAR	0xd	/* Bank 0 */39#define RTC7301_1000_YEAR	0xe	/* Bank 0 */40#define RTC7301_ALARM_CONTROL	0xe	/* Bank 1 */41#define RTC7301_ALARM_CONTROL_AIE	BIT(0)42#define RTC7301_ALARM_CONTROL_AF	BIT(1)43#define RTC7301_TIMER_CONTROL	0xe	/* Bank 2 */44#define RTC7301_TIMER_CONTROL_TIE	BIT(0)45#define RTC7301_TIMER_CONTROL_TF	BIT(1)46#define RTC7301_CONTROL		0xf	/* All banks */47#define RTC7301_CONTROL_BUSY		BIT(0)48#define RTC7301_CONTROL_STOP		BIT(1)49#define RTC7301_CONTROL_BANK_SEL_0	BIT(2)50#define RTC7301_CONTROL_BANK_SEL_1	BIT(3)51 52struct rtc7301_priv {53	struct regmap *regmap;54	int irq;55	spinlock_t lock;56	u8 bank;57};58 59/*60 * When the device is memory-mapped, some platforms pack the registers into61 * 32-bit access using the lower 8 bits at each 4-byte stride, while others62 * expose them as simply consecutive bytes.63 */64static const struct regmap_config rtc7301_regmap_32_config = {65	.reg_bits = 32,66	.val_bits = 8,67	.reg_stride = 4,68};69 70static const struct regmap_config rtc7301_regmap_8_config = {71	.reg_bits = 8,72	.val_bits = 8,73	.reg_stride = 1,74};75 76static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)77{78	int reg_stride = regmap_get_reg_stride(priv->regmap);79	unsigned int val;80 81	regmap_read(priv->regmap, reg_stride * reg, &val);82 83	return val & 0xf;84}85 86static void rtc7301_write(struct rtc7301_priv *priv, u8 val, unsigned int reg)87{88	int reg_stride = regmap_get_reg_stride(priv->regmap);89 90	regmap_write(priv->regmap, reg_stride * reg, val);91}92 93static void rtc7301_update_bits(struct rtc7301_priv *priv, unsigned int reg,94				u8 mask, u8 val)95{96	int reg_stride = regmap_get_reg_stride(priv->regmap);97 98	regmap_update_bits(priv->regmap, reg_stride * reg, mask, val);99}100 101static int rtc7301_wait_while_busy(struct rtc7301_priv *priv)102{103	int retries = 100;104 105	while (retries-- > 0) {106		u8 val;107 108		val = rtc7301_read(priv, RTC7301_CONTROL);109		if (!(val & RTC7301_CONTROL_BUSY))110			return 0;111 112		udelay(300);113	}114 115	return -ETIMEDOUT;116}117 118static void rtc7301_stop(struct rtc7301_priv *priv)119{120	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP,121			    RTC7301_CONTROL_STOP);122}123 124static void rtc7301_start(struct rtc7301_priv *priv)125{126	rtc7301_update_bits(priv, RTC7301_CONTROL, RTC7301_CONTROL_STOP, 0);127}128 129static void rtc7301_select_bank(struct rtc7301_priv *priv, u8 bank)130{131	u8 val = 0;132 133	if (bank == priv->bank)134		return;135 136	if (bank & BIT(0))137		val |= RTC7301_CONTROL_BANK_SEL_0;138	if (bank & BIT(1))139		val |= RTC7301_CONTROL_BANK_SEL_1;140 141	rtc7301_update_bits(priv, RTC7301_CONTROL,142			    RTC7301_CONTROL_BANK_SEL_0 |143			    RTC7301_CONTROL_BANK_SEL_1, val);144 145	priv->bank = bank;146}147 148static void rtc7301_get_time(struct rtc7301_priv *priv, struct rtc_time *tm,149			     bool alarm)150{151	int year;152 153	tm->tm_sec = rtc7301_read(priv, RTC7301_1_SEC);154	tm->tm_sec += (rtc7301_read(priv, RTC7301_10_SEC) & ~RTC7301_AE) * 10;155	tm->tm_min = rtc7301_read(priv, RTC7301_1_MIN);156	tm->tm_min += (rtc7301_read(priv, RTC7301_10_MIN) & ~RTC7301_AE) * 10;157	tm->tm_hour = rtc7301_read(priv, RTC7301_1_HOUR);158	tm->tm_hour += (rtc7301_read(priv, RTC7301_10_HOUR) & ~RTC7301_AE) * 10;159	tm->tm_mday = rtc7301_read(priv, RTC7301_1_DAY);160	tm->tm_mday += (rtc7301_read(priv, RTC7301_10_DAY) & ~RTC7301_AE) * 10;161 162	if (alarm) {163		tm->tm_wday = -1;164		tm->tm_mon = -1;165		tm->tm_year = -1;166		tm->tm_yday = -1;167		tm->tm_isdst = -1;168		return;169	}170 171	tm->tm_wday = (rtc7301_read(priv, RTC7301_DAY_OF_WEEK) & ~RTC7301_AE);172	tm->tm_mon = rtc7301_read(priv, RTC7301_10_MONTH) * 10 +173		     rtc7301_read(priv, RTC7301_1_MONTH) - 1;174	year = rtc7301_read(priv, RTC7301_1000_YEAR) * 1000 +175	       rtc7301_read(priv, RTC7301_100_YEAR) * 100 +176	       rtc7301_read(priv, RTC7301_10_YEAR) * 10 +177	       rtc7301_read(priv, RTC7301_1_YEAR);178 179	tm->tm_year = year - 1900;180}181 182static void rtc7301_write_time(struct rtc7301_priv *priv, struct rtc_time *tm,183			       bool alarm)184{185	int year;186 187	rtc7301_write(priv, tm->tm_sec % 10, RTC7301_1_SEC);188	rtc7301_write(priv, tm->tm_sec / 10, RTC7301_10_SEC);189 190	rtc7301_write(priv, tm->tm_min % 10, RTC7301_1_MIN);191	rtc7301_write(priv, tm->tm_min / 10, RTC7301_10_MIN);192 193	rtc7301_write(priv, tm->tm_hour % 10, RTC7301_1_HOUR);194	rtc7301_write(priv, tm->tm_hour / 10, RTC7301_10_HOUR);195 196	rtc7301_write(priv, tm->tm_mday % 10, RTC7301_1_DAY);197	rtc7301_write(priv, tm->tm_mday / 10, RTC7301_10_DAY);198 199	/* Don't care for alarm register */200	rtc7301_write(priv, alarm ? RTC7301_AE : tm->tm_wday,201		      RTC7301_DAY_OF_WEEK);202 203	if (alarm)204		return;205 206	rtc7301_write(priv, (tm->tm_mon + 1) % 10, RTC7301_1_MONTH);207	rtc7301_write(priv, (tm->tm_mon + 1) / 10, RTC7301_10_MONTH);208 209	year = tm->tm_year + 1900;210 211	rtc7301_write(priv, year % 10, RTC7301_1_YEAR);212	rtc7301_write(priv, (year / 10) % 10, RTC7301_10_YEAR);213	rtc7301_write(priv, (year / 100) % 10, RTC7301_100_YEAR);214	rtc7301_write(priv, year / 1000, RTC7301_1000_YEAR);215}216 217static void rtc7301_alarm_irq(struct rtc7301_priv *priv, unsigned int enabled)218{219	rtc7301_update_bits(priv, RTC7301_ALARM_CONTROL,220			    RTC7301_ALARM_CONTROL_AF |221			    RTC7301_ALARM_CONTROL_AIE,222			    enabled ? RTC7301_ALARM_CONTROL_AIE : 0);223}224 225static int rtc7301_read_time(struct device *dev, struct rtc_time *tm)226{227	struct rtc7301_priv *priv = dev_get_drvdata(dev);228	unsigned long flags;229	int err;230 231	spin_lock_irqsave(&priv->lock, flags);232 233	rtc7301_select_bank(priv, 0);234 235	err = rtc7301_wait_while_busy(priv);236	if (!err)237		rtc7301_get_time(priv, tm, false);238 239	spin_unlock_irqrestore(&priv->lock, flags);240 241	return err;242}243 244static int rtc7301_set_time(struct device *dev, struct rtc_time *tm)245{246	struct rtc7301_priv *priv = dev_get_drvdata(dev);247	unsigned long flags;248 249	spin_lock_irqsave(&priv->lock, flags);250 251	rtc7301_stop(priv);252	udelay(300);253	rtc7301_select_bank(priv, 0);254	rtc7301_write_time(priv, tm, false);255	rtc7301_start(priv);256 257	spin_unlock_irqrestore(&priv->lock, flags);258 259	return 0;260}261 262static int rtc7301_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)263{264	struct rtc7301_priv *priv = dev_get_drvdata(dev);265	unsigned long flags;266	u8 alrm_ctrl;267 268	if (priv->irq <= 0)269		return -EINVAL;270 271	spin_lock_irqsave(&priv->lock, flags);272 273	rtc7301_select_bank(priv, 1);274	rtc7301_get_time(priv, &alarm->time, true);275 276	alrm_ctrl = rtc7301_read(priv, RTC7301_ALARM_CONTROL);277 278	alarm->enabled = !!(alrm_ctrl & RTC7301_ALARM_CONTROL_AIE);279	alarm->pending = !!(alrm_ctrl & RTC7301_ALARM_CONTROL_AF);280 281	spin_unlock_irqrestore(&priv->lock, flags);282 283	return 0;284}285 286static int rtc7301_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)287{288	struct rtc7301_priv *priv = dev_get_drvdata(dev);289	unsigned long flags;290 291	if (priv->irq <= 0)292		return -EINVAL;293 294	spin_lock_irqsave(&priv->lock, flags);295 296	rtc7301_select_bank(priv, 1);297	rtc7301_write_time(priv, &alarm->time, true);298	rtc7301_alarm_irq(priv, alarm->enabled);299 300	spin_unlock_irqrestore(&priv->lock, flags);301 302	return 0;303}304 305static int rtc7301_alarm_irq_enable(struct device *dev, unsigned int enabled)306{307	struct rtc7301_priv *priv = dev_get_drvdata(dev);308	unsigned long flags;309 310	if (priv->irq <= 0)311		return -EINVAL;312 313	spin_lock_irqsave(&priv->lock, flags);314 315	rtc7301_select_bank(priv, 1);316	rtc7301_alarm_irq(priv, enabled);317 318	spin_unlock_irqrestore(&priv->lock, flags);319 320	return 0;321}322 323static const struct rtc_class_ops rtc7301_rtc_ops = {324	.read_time	= rtc7301_read_time,325	.set_time	= rtc7301_set_time,326	.read_alarm	= rtc7301_read_alarm,327	.set_alarm	= rtc7301_set_alarm,328	.alarm_irq_enable = rtc7301_alarm_irq_enable,329};330 331static irqreturn_t rtc7301_irq_handler(int irq, void *dev_id)332{333	struct rtc_device *rtc = dev_id;334	struct rtc7301_priv *priv = dev_get_drvdata(rtc->dev.parent);335	irqreturn_t ret = IRQ_NONE;336	u8 alrm_ctrl;337 338	spin_lock(&priv->lock);339 340	rtc7301_select_bank(priv, 1);341 342	alrm_ctrl = rtc7301_read(priv, RTC7301_ALARM_CONTROL);343	if (alrm_ctrl & RTC7301_ALARM_CONTROL_AF) {344		ret = IRQ_HANDLED;345		rtc7301_alarm_irq(priv, false);346		rtc_update_irq(rtc, 1, RTC_IRQF | RTC_AF);347	}348 349	spin_unlock(&priv->lock);350 351	return ret;352}353 354static void rtc7301_init(struct rtc7301_priv *priv)355{356	unsigned long flags;357 358	spin_lock_irqsave(&priv->lock, flags);359 360	rtc7301_select_bank(priv, 2);361	rtc7301_write(priv, 0, RTC7301_TIMER_CONTROL);362 363	spin_unlock_irqrestore(&priv->lock, flags);364}365 366static int __init rtc7301_rtc_probe(struct platform_device *dev)367{368	void __iomem *regs;369	struct rtc7301_priv *priv;370	struct rtc_device *rtc;371	static const struct regmap_config *mapconf;372	int ret;373	u32 val;374 375	priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);376	if (!priv)377		return -ENOMEM;378 379	regs = devm_platform_ioremap_resource(dev, 0);380	if (IS_ERR(regs))381		return PTR_ERR(regs);382 383	ret = device_property_read_u32(&dev->dev, "reg-io-width", &val);384	if (ret)385		/* Default to 32bit accesses */386		val = 4;387 388	switch (val) {389	case 1:390		mapconf = &rtc7301_regmap_8_config;391		break;392	case 4:393		mapconf = &rtc7301_regmap_32_config;394		break;395	default:396		dev_err(&dev->dev, "invalid reg-io-width %d\n", val);397		return -EINVAL;398	}399 400	priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,401					     mapconf);402	if (IS_ERR(priv->regmap))403		return PTR_ERR(priv->regmap);404 405	priv->irq = platform_get_irq(dev, 0);406 407	spin_lock_init(&priv->lock);408	priv->bank = -1;409 410	rtc7301_init(priv);411 412	platform_set_drvdata(dev, priv);413 414	rtc = devm_rtc_device_register(&dev->dev, DRV_NAME, &rtc7301_rtc_ops,415				       THIS_MODULE);416	if (IS_ERR(rtc))417		return PTR_ERR(rtc);418 419	if (priv->irq > 0) {420		ret = devm_request_irq(&dev->dev, priv->irq,421				       rtc7301_irq_handler, IRQF_SHARED,422				       dev_name(&dev->dev), rtc);423		if (ret) {424			priv->irq = 0;425			dev_err(&dev->dev, "unable to request IRQ\n");426		} else {427			device_set_wakeup_capable(&dev->dev, true);428		}429	}430 431	return 0;432}433 434#ifdef CONFIG_PM_SLEEP435 436static int rtc7301_suspend(struct device *dev)437{438	struct rtc7301_priv *priv = dev_get_drvdata(dev);439 440	if (device_may_wakeup(dev))441		enable_irq_wake(priv->irq);442 443	return 0;444}445 446static int rtc7301_resume(struct device *dev)447{448	struct rtc7301_priv *priv = dev_get_drvdata(dev);449 450	if (device_may_wakeup(dev))451		disable_irq_wake(priv->irq);452 453	return 0;454}455 456#endif457 458static SIMPLE_DEV_PM_OPS(rtc7301_pm_ops, rtc7301_suspend, rtc7301_resume);459 460static const struct of_device_id rtc7301_dt_match[] = {461	{ .compatible = "epson,rtc7301sf" },462	{ .compatible = "epson,rtc7301dg" },463	{}464};465MODULE_DEVICE_TABLE(of, rtc7301_dt_match);466 467static struct platform_driver rtc7301_rtc_driver = {468	.driver	= {469		.name = DRV_NAME,470		.of_match_table = rtc7301_dt_match,471		.pm = &rtc7301_pm_ops,472	},473};474 475module_platform_driver_probe(rtc7301_rtc_driver, rtc7301_rtc_probe);476 477MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>");478MODULE_LICENSE("GPL");479MODULE_DESCRIPTION("EPSON TOYOCOM RTC-7301SF/DG Driver");480MODULE_ALIAS("platform:rtc-r7301");481