brintos

brintos / linux-shallow public Read only

0
0
Text · 6.2 KiB · 8d7737e Raw
250 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.4 * Based on "Real Time Clock driver for msb252x." that was contained5 * in various MStar kernels.6 *7 * (C) 2019 Daniel Palmer8 * (C) 2021 Romain Perier9 */10 11#include <linux/clk.h>12#include <linux/delay.h>13#include <linux/io.h>14#include <linux/module.h>15#include <linux/mod_devicetable.h>16#include <linux/platform_device.h>17#include <linux/rtc.h>18 19/* Registers */20#define REG_RTC_CTRL		0x0021#define REG_RTC_FREQ_CW_L	0x0422#define REG_RTC_FREQ_CW_H	0x0823#define REG_RTC_LOAD_VAL_L	0x0C24#define REG_RTC_LOAD_VAL_H	0x1025#define REG_RTC_MATCH_VAL_L	0x1426#define REG_RTC_MATCH_VAL_H	0x1827#define REG_RTC_STATUS_INT	0x1C28#define REG_RTC_CNT_VAL_L	0x2029#define REG_RTC_CNT_VAL_H	0x2430 31/* Control bits for REG_RTC_CTRL */32#define SOFT_RSTZ_BIT		BIT(0)33#define CNT_EN_BIT		BIT(1)34#define WRAP_EN_BIT		BIT(2)35#define LOAD_EN_BIT		BIT(3)36#define READ_EN_BIT		BIT(4)37#define INT_MASK_BIT		BIT(5)38#define INT_FORCE_BIT		BIT(6)39#define INT_CLEAR_BIT		BIT(7)40 41/* Control bits for REG_RTC_STATUS_INT */42#define RAW_INT_BIT		BIT(0)43#define ALM_INT_BIT		BIT(1)44 45struct msc313_rtc {46	struct rtc_device *rtc_dev;47	void __iomem *rtc_base;48};49 50static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)51{52	struct msc313_rtc *priv = dev_get_drvdata(dev);53	unsigned long seconds;54 55	seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)56			| ((unsigned long)readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);57 58	rtc_time64_to_tm(seconds, &alarm->time);59 60	if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))61		alarm->enabled = 1;62 63	return 0;64}65 66static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)67{68	struct msc313_rtc *priv = dev_get_drvdata(dev);69	u16 reg;70 71	reg = readw(priv->rtc_base + REG_RTC_CTRL);72	if (enabled)73		reg &= ~INT_MASK_BIT;74	else75		reg |= INT_MASK_BIT;76	writew(reg, priv->rtc_base + REG_RTC_CTRL);77	return 0;78}79 80static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)81{82	struct msc313_rtc *priv = dev_get_drvdata(dev);83	unsigned long seconds;84 85	seconds = rtc_tm_to_time64(&alarm->time);86	writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);87	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);88 89	msc313_rtc_alarm_irq_enable(dev, alarm->enabled);90 91	return 0;92}93 94static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)95{96	return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;97}98 99static void msc313_rtc_set_enabled(struct msc313_rtc *priv)100{101	u16 reg;102 103	reg = readw(priv->rtc_base + REG_RTC_CTRL);104	reg |= CNT_EN_BIT;105	writew(reg, priv->rtc_base + REG_RTC_CTRL);106}107 108static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)109{110	struct msc313_rtc *priv = dev_get_drvdata(dev);111	u32 seconds;112	u16 reg;113 114	if (!msc313_rtc_get_enabled(priv))115		return -EINVAL;116 117	reg = readw(priv->rtc_base + REG_RTC_CTRL);118	writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);119 120	/* Wait for HW latch done */121	while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)122		udelay(1);123 124	seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)125			| ((unsigned long)readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);126 127	rtc_time64_to_tm(seconds, tm);128 129	return 0;130}131 132static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)133{134	struct msc313_rtc *priv = dev_get_drvdata(dev);135	unsigned long seconds;136	u16 reg;137 138	seconds = rtc_tm_to_time64(tm);139	writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);140	writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);141 142	/* Enable load for loading value into internal RTC counter */143	reg = readw(priv->rtc_base + REG_RTC_CTRL);144	writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);145 146	/* Wait for HW latch done */147	while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)148		udelay(1);149	msc313_rtc_set_enabled(priv);150	return 0;151}152 153static const struct rtc_class_ops msc313_rtc_ops = {154	.read_time = msc313_rtc_read_time,155	.set_time = msc313_rtc_set_time,156	.read_alarm = msc313_rtc_read_alarm,157	.set_alarm = msc313_rtc_set_alarm,158	.alarm_irq_enable = msc313_rtc_alarm_irq_enable,159};160 161static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)162{163	struct msc313_rtc *priv = dev_get_drvdata(dev_id);164	u16 reg;165 166	reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);167	if (!(reg & ALM_INT_BIT))168		return IRQ_NONE;169 170	reg = readw(priv->rtc_base + REG_RTC_CTRL);171	reg |= INT_CLEAR_BIT;172	reg &= ~INT_FORCE_BIT;173	writew(reg, priv->rtc_base + REG_RTC_CTRL);174 175	rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);176 177	return IRQ_HANDLED;178}179 180static int msc313_rtc_probe(struct platform_device *pdev)181{182	struct device *dev = &pdev->dev;183	struct msc313_rtc *priv;184	unsigned long rate;185	struct clk *clk;186	int ret;187	int irq;188 189	priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);190	if (!priv)191		return -ENOMEM;192 193	priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);194	if (IS_ERR(priv->rtc_base))195		return PTR_ERR(priv->rtc_base);196 197	irq = platform_get_irq(pdev, 0);198	if (irq < 0)199		return -EINVAL;200 201	priv->rtc_dev = devm_rtc_allocate_device(dev);202	if (IS_ERR(priv->rtc_dev))203		return PTR_ERR(priv->rtc_dev);204 205	priv->rtc_dev->ops = &msc313_rtc_ops;206	priv->rtc_dev->range_max = U32_MAX;207 208	ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,209			       dev_name(&pdev->dev), &pdev->dev);210	if (ret) {211		dev_err(dev, "Could not request IRQ\n");212		return ret;213	}214 215	clk = devm_clk_get_enabled(dev, NULL);216	if (IS_ERR(clk)) {217		dev_err(dev, "No input reference clock\n");218		return PTR_ERR(clk);219	}220 221	rate = clk_get_rate(clk);222	writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);223	writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);224 225	platform_set_drvdata(pdev, priv);226 227	return devm_rtc_register_device(priv->rtc_dev);228}229 230static const struct of_device_id msc313_rtc_of_match_table[] = {231	{ .compatible = "mstar,msc313-rtc" },232	{ }233};234MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);235 236static struct platform_driver msc313_rtc_driver = {237	.probe = msc313_rtc_probe,238	.driver = {239		.name = "msc313-rtc",240		.of_match_table = msc313_rtc_of_match_table,241	},242};243 244module_platform_driver(msc313_rtc_driver);245 246MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>");247MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");248MODULE_DESCRIPTION("MStar RTC Driver");249MODULE_LICENSE("GPL v2");250