RTC for 5.16

Subsystem:
  - Add new ioctl to get and set extra RTC parameters, this includes backup
    switch mode
  - Expose available features to userspace, in particular, when alarmas have a
    resolution of one minute instead of a second.
  - Let the core handle those alarms with a minute resolution
 
 New driver:
  - MSTAR MSC313 RTC
 
 Drivers:
  - Add SPI ID table where necessary
  - Add BSM support for rv3028, rv3032 and pcf8523
  - s3c: set RTC range
  - rx8025: set range, implement .set_offset and .read_offset
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEBqsFVZXh8s/0O5JiY6TcMGxwOjIFAmGNm7AACgkQY6TcMGxw
 OjJBeA/+PHmLq0v1olnG2kx0Ch7nzYzonCO+3tvPi5xoPKUZln5TpdSqAECqDC6g
 PizHUdJaBNTc3Y7GMUkryuuWq67kYlzx1N7EHZqgARk7s6hus+SJmQb7kiCbiawD
 pP62na7ZJDCs6S70WD9VMCJQ21xokwwTWzL7nVD98LN1qkQCj4cSuoDPBEJQyeG2
 S5Xi1CePW84c9eKx4Sy//bzLnCpSqb6tDHfsexwmLFTk5WN0onZRZSYD0/loY8N+
 EEMX0Ts/9ERqM5QALDMB4YQNWvRCtGP7Fl0QPtVRXC2MXyg/GYhdC2F2SvQmYCRC
 VZoZwCJ82x4Pa2UTdg2L3WD0uKrvycnRaAYV71CME5PkAw1hQqLz3HZwjYXkITvp
 crhZQvCGHn9w2UOEAKnWWnCLsl3paWXkN0zGeFhYYGeAIf79fRnIGc3cGubjSgiv
 9WU9oRL8EzY5bL07fP5P81leknzROZmK3Re6vefI5o2A4qY0qP9mU6zVKxZy/iHd
 7GiE5jNact0oUB7Vhakh4wUchyOJCPZSFxfeNqPJzs6FlVUR74Ulw05Sywnz+W7a
 oXtODF0cmJPVeUJYmo5EKfLAId4iPmcq8Fh16ayw4595pwc6iHE+GRL6j7Zjk+AX
 u9UA2qXqYhE5PgcxC6pd/hMV29p1S81BKdjyf0HF7oxWgBoT1lc=
 =pTlj
 -----END PGP SIGNATURE-----

Merge tag 'rtc-5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux

Pull RTC updates from Alexandre Belloni:
 "This includes new ioctls to get and set parameters and in particular
  the backup switch mode that is needed for some RTCs to actually enable
  the backup voltage (and have a useful RTC).

  The same interface can also be used to get the actual features
  supported by the RTC so userspace has a better way than trying and
  failing.

  Summary:

  Subsystem:
   - Add new ioctl to get and set extra RTC parameters, this includes
     backup switch mode
   - Expose available features to userspace, in particular, when alarmas
     have a resolution of one minute instead of a second.
   - Let the core handle those alarms with a minute resolution

  New driver:
   - MSTAR MSC313 RTC

  Drivers:
   - Add SPI ID table where necessary
   - Add BSM support for rv3028, rv3032 and pcf8523
   - s3c: set RTC range
   - rx8025: set range, implement .set_offset and .read_offset"

* tag 'rtc-5.16' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (50 commits)
  rtc: rx8025: use .set_offset/.read_offset
  rtc: rx8025: use rtc_add_group
  rtc: rx8025: clear RTC_FEATURE_ALARM when alarm are not supported
  rtc: rx8025: set range
  rtc: rx8025: let the core handle the alarm resolution
  rtc: rx8025: switch to devm_rtc_allocate_device
  rtc: ab8500: let the core handle the alarm resolution
  rtc: ab-eoz9: support UIE when available
  rtc: ab-eoz9: use RTC_FEATURE_UPDATE_INTERRUPT
  rtc: rv3032: let the core handle the alarm resolution
  rtc: s35390a: let the core handle the alarm resolution
  rtc: handle alarms with a minute resolution
  rtc: pcf85063: silence cppcheck warning
  rtc: rv8803: fix writing back ctrl in flag register
  rtc: s3c: Add time range
  rtc: s3c: Extract read/write IO into separate functions
  rtc: s3c: Remove usage of devm_rtc_device_register()
  rtc: tps80031: Remove driver
  rtc: sun6i: Allow probing without an early clock provider
  rtc: pcf8523: add BSM support
  ...
This commit is contained in:
Linus Torvalds 2021-11-12 11:44:31 -08:00
commit 3b81bf78b7
31 changed files with 984 additions and 763 deletions

View File

@ -0,0 +1,49 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/rtc/mstar,msc313-rtc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mstar MSC313e RTC Device Tree Bindings
allOf:
- $ref: "rtc.yaml#"
maintainers:
- Daniel Palmer <daniel@0x0f.com>
- Romain Perier <romain.perier@gmail.com>
properties:
compatible:
enum:
- mstar,msc313-rtc
reg:
maxItems: 1
interrupts:
maxItems: 1
start-year: true
clocks:
maxItems: 1
required:
- compatible
- reg
- interrupts
- clocks
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
rtc@2400 {
compatible = "mstar,msc313-rtc";
reg = <0x2400 0x40>;
clocks = <&xtal_div2>;
interrupts-extended = <&intc_irq GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
};
...

View File

@ -13,10 +13,19 @@ Optional property:
expressed in femto Farad (fF). Valid values are 7000 and 12500.
Default value (if no value is specified) is 7000fF.
Optional child node:
- clock: Provide this if the square wave pin is used as boot-enabled fixed clock.
Example:
pcf85063: rtc@51 {
compatible = "nxp,pcf85063";
reg = <0x51>;
quartz-load-femtofarads = <12500>;
clock {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <32768>;
};
};

View File

@ -2283,6 +2283,7 @@ F: arch/arm/boot/dts/mstar-*
F: arch/arm/mach-mstar/
F: drivers/clk/mstar/
F: drivers/gpio/gpio-msc313.c
F: drivers/rtc/rtc-msc313.c
F: drivers/watchdog/msc313e_wdt.c
F: include/dt-bindings/clock/mstar-*
F: include/dt-bindings/gpio/msc313-gpio.h

View File

@ -441,6 +441,7 @@ config RTC_DRV_X1205
config RTC_DRV_PCF8523
tristate "NXP PCF8523"
select REGMAP_I2C
help
If you say yes here you get support for the NXP PCF8523 RTC
chips.
@ -582,14 +583,6 @@ config RTC_DRV_TPS65910
This driver can also be built as a module. If so, the module
will be called rtc-tps65910.
config RTC_DRV_TPS80031
tristate "TI TPS80031/TPS80032 RTC driver"
depends on MFD_TPS80031
help
TI Power Management IC TPS80031 supports RTC functionality
along with alarm. This driver supports the RTC driver for
the TPS80031 RTC module.
config RTC_DRV_RC5T583
tristate "RICOH 5T583 RTC driver"
depends on MFD_RC5T583
@ -1929,4 +1922,14 @@ config RTC_DRV_WILCO_EC
This can also be built as a module. If so, the module will
be named "rtc_wilco_ec".
config RTC_DRV_MSC313
tristate "MStar MSC313 RTC"
depends on ARCH_MSTARV7 || COMPILE_TEST
help
If you say yes here you get support for the Mstar MSC313e On-Chip
Real Time Clock.
This driver can also be built as a module, if so, the module
will be called "rtc-msc313".
endif # RTC_CLASS

View File

@ -103,6 +103,7 @@ obj-$(CONFIG_RTC_DRV_MCP795) += rtc-mcp795.o
obj-$(CONFIG_RTC_DRV_MESON) += rtc-meson.o
obj-$(CONFIG_RTC_DRV_MOXART) += rtc-moxart.o
obj-$(CONFIG_RTC_DRV_MPC5121) += rtc-mpc5121.o
obj-$(CONFIG_RTC_DRV_MSC313) += rtc-msc313.o
obj-$(CONFIG_RTC_DRV_MSM6242) += rtc-msm6242.o
obj-$(CONFIG_RTC_DRV_MT2712) += rtc-mt2712.o
obj-$(CONFIG_RTC_DRV_MT6397) += rtc-mt6397.o
@ -169,7 +170,6 @@ obj-$(CONFIG_RTC_DRV_TEGRA) += rtc-tegra.o
obj-$(CONFIG_RTC_DRV_TEST) += rtc-test.o
obj-$(CONFIG_RTC_DRV_TPS6586X) += rtc-tps6586x.o
obj-$(CONFIG_RTC_DRV_TPS65910) += rtc-tps65910.o
obj-$(CONFIG_RTC_DRV_TPS80031) += rtc-tps80031.o
obj-$(CONFIG_RTC_DRV_TWL4030) += rtc-twl.o
obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o

View File

@ -232,6 +232,7 @@ static struct rtc_device *rtc_allocate_device(void)
rtc->pie_enabled = 0;
set_bit(RTC_FEATURE_ALARM, rtc->features);
set_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
return rtc;
}
@ -334,7 +335,8 @@ static void devm_rtc_unregister_device(void *data)
* letting any rtc_class_open() users access it again
*/
rtc_proc_del_device(rtc);
cdev_device_del(&rtc->char_dev, &rtc->dev);
if (!test_bit(RTC_NO_CDEV, &rtc->flags))
cdev_device_del(&rtc->char_dev, &rtc->dev);
rtc->ops = NULL;
mutex_unlock(&rtc->ops_lock);
}
@ -363,7 +365,9 @@ struct rtc_device *devm_rtc_allocate_device(struct device *dev)
rtc->id = id;
rtc->dev.parent = dev;
dev_set_name(&rtc->dev, "rtc%d", id);
err = dev_set_name(&rtc->dev, "rtc%d", id);
if (err)
return ERR_PTR(err);
err = devm_add_action_or_reset(dev, devm_rtc_release_device, rtc);
if (err)
@ -386,6 +390,12 @@ int __devm_rtc_register_device(struct module *owner, struct rtc_device *rtc)
if (!rtc->ops->set_alarm)
clear_bit(RTC_FEATURE_ALARM, rtc->features);
if (rtc->uie_unsupported)
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
if (rtc->ops->set_offset)
set_bit(RTC_FEATURE_CORRECTION, rtc->features);
rtc->owner = owner;
rtc_device_get_offset(rtc);
@ -397,12 +407,14 @@ int __devm_rtc_register_device(struct module *owner, struct rtc_device *rtc)
rtc_dev_prepare(rtc);
err = cdev_device_add(&rtc->char_dev, &rtc->dev);
if (err)
if (err) {
set_bit(RTC_NO_CDEV, &rtc->flags);
dev_warn(rtc->dev.parent, "failed to add char device %d:%d\n",
MAJOR(rtc->dev.devt), rtc->id);
else
} else {
dev_dbg(rtc->dev.parent, "char device (%d:%d)\n",
MAJOR(rtc->dev.devt), rtc->id);
}
rtc_proc_add_device(rtc);

View File

@ -208,6 +208,7 @@ static long rtc_dev_ioctl(struct file *file,
const struct rtc_class_ops *ops = rtc->ops;
struct rtc_time tm;
struct rtc_wkalrm alarm;
struct rtc_param param;
void __user *uarg = (void __user *)arg;
err = mutex_lock_interruptible(&rtc->ops_lock);
@ -221,6 +222,7 @@ static long rtc_dev_ioctl(struct file *file,
switch (cmd) {
case RTC_EPOCH_SET:
case RTC_SET_TIME:
case RTC_PARAM_SET:
if (!capable(CAP_SYS_TIME))
err = -EACCES;
break;
@ -382,6 +384,69 @@ static long rtc_dev_ioctl(struct file *file,
err = -EFAULT;
return err;
case RTC_PARAM_GET:
if (copy_from_user(&param, uarg, sizeof(param))) {
mutex_unlock(&rtc->ops_lock);
return -EFAULT;
}
switch(param.param) {
long offset;
case RTC_PARAM_FEATURES:
if (param.index != 0)
err = -EINVAL;
param.uvalue = rtc->features[0];
break;
case RTC_PARAM_CORRECTION:
mutex_unlock(&rtc->ops_lock);
if (param.index != 0)
return -EINVAL;
err = rtc_read_offset(rtc, &offset);
mutex_lock(&rtc->ops_lock);
if (err == 0)
param.svalue = offset;
break;
default:
if (rtc->ops->param_get)
err = rtc->ops->param_get(rtc->dev.parent, &param);
else
err = -EINVAL;
}
if (!err)
if (copy_to_user(uarg, &param, sizeof(param)))
err = -EFAULT;
break;
case RTC_PARAM_SET:
if (copy_from_user(&param, uarg, sizeof(param))) {
mutex_unlock(&rtc->ops_lock);
return -EFAULT;
}
switch(param.param) {
case RTC_PARAM_FEATURES:
err = -EINVAL;
break;
case RTC_PARAM_CORRECTION:
mutex_unlock(&rtc->ops_lock);
if (param.index != 0)
return -EINVAL;
return rtc_set_offset(rtc, param.svalue);
default:
if (rtc->ops->param_set)
err = rtc->ops->param_set(rtc->dev.parent, &param);
else
err = -EINVAL;
}
break;
default:
/* Finally try the driver's ioctl interface */
if (ops->ioctl) {

View File

@ -423,6 +423,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (err)
return err;
now = rtc_tm_to_time64(&tm);
if (scheduled <= now)
return -ETIME;
/*
@ -447,6 +448,7 @@ static int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
{
ktime_t alarm_time;
int err;
if (!rtc->ops)
@ -468,7 +470,15 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
if (rtc->aie_timer.enabled)
rtc_timer_remove(rtc, &rtc->aie_timer);
rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time);
alarm_time = rtc_tm_to_ktime(alarm->time);
/*
* Round down so we never miss a deadline, checking for past deadline is
* done in __rtc_set_alarm
*/
if (test_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features))
alarm_time = ktime_sub_ns(alarm_time, (u64)alarm->time.tm_sec * NSEC_PER_SEC);
rtc->aie_timer.node.expires = alarm_time;
rtc->aie_timer.period = 0;
if (alarm->enabled)
err = rtc_timer_enqueue(rtc, &rtc->aie_timer);
@ -561,7 +571,8 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled)
if (rtc->uie_rtctimer.enabled == enabled)
goto out;
if (rtc->uie_unsupported || !test_bit(RTC_FEATURE_ALARM, rtc->features)) {
if (!test_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features) ||
!test_bit(RTC_FEATURE_ALARM, rtc->features)) {
mutex_unlock(&rtc->ops_lock);
#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
return rtc_dev_update_irq_enable_emul(rtc, enabled);

View File

@ -534,7 +534,6 @@ static int abeoz9_probe(struct i2c_client *client,
data->rtc->ops = &rtc_ops;
data->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
data->rtc->range_max = RTC_TIMESTAMP_END_2099;
data->rtc->uie_unsupported = 1;
clear_bit(RTC_FEATURE_ALARM, data->rtc->features);
if (client->irq > 0) {
@ -546,6 +545,8 @@ static int abeoz9_probe(struct i2c_client *client,
dev_err(dev, "failed to request alarm irq\n");
return ret;
}
} else {
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, data->rtc->features);
}
if (client->irq > 0 || device_property_read_bool(dev, "wakeup-source")) {

View File

@ -184,25 +184,9 @@ static int ab8500_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
int retval, i;
unsigned char buf[ARRAY_SIZE(ab8500_rtc_alarm_regs)];
unsigned long mins, secs = 0, cursec = 0;
struct rtc_time curtm;
unsigned long mins;
/* Get the number of seconds since 1970 */
secs = rtc_tm_to_time64(&alarm->time);
/*
* Check whether alarm is set less than 1min.
* Since our RTC doesn't support alarm resolution less than 1min,
* return -EINVAL, so UIE EMUL can take it up, incase of UIE_ON
*/
ab8500_rtc_read_time(dev, &curtm); /* Read current time */
cursec = rtc_tm_to_time64(&curtm);
if ((secs - cursec) < 59) {
dev_dbg(dev, "Alarm less than 1 minute not supported\r\n");
return -EINVAL;
}
mins = secs / 60;
mins = (unsigned long)rtc_tm_to_time64(&alarm->time) / 60;
buf[2] = mins & 0xFF;
buf[1] = (mins >> 8) & 0xFF;
@ -394,7 +378,8 @@ static int ab8500_rtc_probe(struct platform_device *pdev)
dev_pm_set_wake_irq(&pdev->dev, irq);
platform_set_drvdata(pdev, rtc);
rtc->uie_unsupported = 1;
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rtc->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rtc->features);
rtc->range_max = (1ULL << 24) * 60 - 1; // 24-bit minutes + 59 secs
rtc->start_secs = RTC_TIMESTAMP_BEGIN_2000;

View File

@ -199,11 +199,18 @@ static const struct of_device_id ds1302_dt_ids[] = {
MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
#endif
static const struct spi_device_id ds1302_spi_ids[] = {
{ .name = "ds1302", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(spi, ds1302_spi_ids);
static struct spi_driver ds1302_driver = {
.driver.name = "rtc-ds1302",
.driver.of_match_table = of_match_ptr(ds1302_dt_ids),
.probe = ds1302_probe,
.remove = ds1302_remove,
.id_table = ds1302_spi_ids,
};
module_spi_driver(ds1302_driver);

View File

@ -219,12 +219,19 @@ static const struct of_device_id ds1390_of_match[] = {
};
MODULE_DEVICE_TABLE(of, ds1390_of_match);
static const struct spi_device_id ds1390_spi_ids[] = {
{ .name = "ds1390" },
{}
};
MODULE_DEVICE_TABLE(spi, ds1390_spi_ids);
static struct spi_driver ds1390_driver = {
.driver = {
.name = "rtc-ds1390",
.of_match_table = of_match_ptr(ds1390_of_match),
},
.probe = ds1390_probe,
.id_table = ds1390_spi_ids,
};
module_spi_driver(ds1390_driver);

View File

@ -557,7 +557,7 @@ static struct clk *m41t80_sqw_register_clk(struct m41t80_data *m41t80)
* registered automatically when being referenced.
*/
of_node_put(fixed_clock);
return 0;
return NULL;
}
/* First disable the clock */

View File

@ -430,12 +430,19 @@ static const struct of_device_id mcp795_of_match[] = {
MODULE_DEVICE_TABLE(of, mcp795_of_match);
#endif
static const struct spi_device_id mcp795_spi_ids[] = {
{ .name = "mcp795" },
{ }
};
MODULE_DEVICE_TABLE(spi, mcp795_spi_ids);
static struct spi_driver mcp795_driver = {
.driver = {
.name = "rtc-mcp795",
.of_match_table = of_match_ptr(mcp795_of_match),
},
.probe = mcp795_probe,
.id_table = mcp795_spi_ids,
};
module_spi_driver(mcp795_driver);

259
drivers/rtc/rtc-msc313.c Normal file
View File

@ -0,0 +1,259 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Real time clocks driver for MStar/SigmaStar ARMv7 SoCs.
* Based on "Real Time Clock driver for msb252x." that was contained
* in various MStar kernels.
*
* (C) 2019 Daniel Palmer
* (C) 2021 Romain Perier
*/
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
/* Registers */
#define REG_RTC_CTRL 0x00
#define REG_RTC_FREQ_CW_L 0x04
#define REG_RTC_FREQ_CW_H 0x08
#define REG_RTC_LOAD_VAL_L 0x0C
#define REG_RTC_LOAD_VAL_H 0x10
#define REG_RTC_MATCH_VAL_L 0x14
#define REG_RTC_MATCH_VAL_H 0x18
#define REG_RTC_STATUS_INT 0x1C
#define REG_RTC_CNT_VAL_L 0x20
#define REG_RTC_CNT_VAL_H 0x24
/* Control bits for REG_RTC_CTRL */
#define SOFT_RSTZ_BIT BIT(0)
#define CNT_EN_BIT BIT(1)
#define WRAP_EN_BIT BIT(2)
#define LOAD_EN_BIT BIT(3)
#define READ_EN_BIT BIT(4)
#define INT_MASK_BIT BIT(5)
#define INT_FORCE_BIT BIT(6)
#define INT_CLEAR_BIT BIT(7)
/* Control bits for REG_RTC_STATUS_INT */
#define RAW_INT_BIT BIT(0)
#define ALM_INT_BIT BIT(1)
struct msc313_rtc {
struct rtc_device *rtc_dev;
void __iomem *rtc_base;
};
static int msc313_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct msc313_rtc *priv = dev_get_drvdata(dev);
unsigned long seconds;
seconds = readw(priv->rtc_base + REG_RTC_MATCH_VAL_L)
| ((unsigned long)readw(priv->rtc_base + REG_RTC_MATCH_VAL_H) << 16);
rtc_time64_to_tm(seconds, &alarm->time);
if (!(readw(priv->rtc_base + REG_RTC_CTRL) & INT_MASK_BIT))
alarm->enabled = 1;
return 0;
}
static int msc313_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct msc313_rtc *priv = dev_get_drvdata(dev);
u16 reg;
reg = readw(priv->rtc_base + REG_RTC_CTRL);
if (enabled)
reg &= ~INT_MASK_BIT;
else
reg |= INT_MASK_BIT;
writew(reg, priv->rtc_base + REG_RTC_CTRL);
return 0;
}
static int msc313_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct msc313_rtc *priv = dev_get_drvdata(dev);
unsigned long seconds;
seconds = rtc_tm_to_time64(&alarm->time);
writew((seconds & 0xFFFF), priv->rtc_base + REG_RTC_MATCH_VAL_L);
writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_MATCH_VAL_H);
msc313_rtc_alarm_irq_enable(dev, alarm->enabled);
return 0;
}
static bool msc313_rtc_get_enabled(struct msc313_rtc *priv)
{
return readw(priv->rtc_base + REG_RTC_CTRL) & CNT_EN_BIT;
}
static void msc313_rtc_set_enabled(struct msc313_rtc *priv)
{
u16 reg;
reg = readw(priv->rtc_base + REG_RTC_CTRL);
reg |= CNT_EN_BIT;
writew(reg, priv->rtc_base + REG_RTC_CTRL);
}
static int msc313_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct msc313_rtc *priv = dev_get_drvdata(dev);
u32 seconds;
u16 reg;
if (!msc313_rtc_get_enabled(priv))
return -EINVAL;
reg = readw(priv->rtc_base + REG_RTC_CTRL);
writew(reg | READ_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
/* Wait for HW latch done */
while (readw(priv->rtc_base + REG_RTC_CTRL) & READ_EN_BIT)
udelay(1);
seconds = readw(priv->rtc_base + REG_RTC_CNT_VAL_L)
| ((unsigned long)readw(priv->rtc_base + REG_RTC_CNT_VAL_H) << 16);
rtc_time64_to_tm(seconds, tm);
return 0;
}
static int msc313_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct msc313_rtc *priv = dev_get_drvdata(dev);
unsigned long seconds;
u16 reg;
seconds = rtc_tm_to_time64(tm);
writew(seconds & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_L);
writew((seconds >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_LOAD_VAL_H);
/* Enable load for loading value into internal RTC counter */
reg = readw(priv->rtc_base + REG_RTC_CTRL);
writew(reg | LOAD_EN_BIT, priv->rtc_base + REG_RTC_CTRL);
/* Wait for HW latch done */
while (readw(priv->rtc_base + REG_RTC_CTRL) & LOAD_EN_BIT)
udelay(1);
msc313_rtc_set_enabled(priv);
return 0;
}
static const struct rtc_class_ops msc313_rtc_ops = {
.read_time = msc313_rtc_read_time,
.set_time = msc313_rtc_set_time,
.read_alarm = msc313_rtc_read_alarm,
.set_alarm = msc313_rtc_set_alarm,
.alarm_irq_enable = msc313_rtc_alarm_irq_enable,
};
static irqreturn_t msc313_rtc_interrupt(s32 irq, void *dev_id)
{
struct msc313_rtc *priv = dev_get_drvdata(dev_id);
u16 reg;
reg = readw(priv->rtc_base + REG_RTC_STATUS_INT);
if (!(reg & ALM_INT_BIT))
return IRQ_NONE;
reg = readw(priv->rtc_base + REG_RTC_CTRL);
reg |= INT_CLEAR_BIT;
reg &= ~INT_FORCE_BIT;
writew(reg, priv->rtc_base + REG_RTC_CTRL);
rtc_update_irq(priv->rtc_dev, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
static int msc313_rtc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct msc313_rtc *priv;
unsigned long rate;
struct clk *clk;
int ret;
int irq;
priv = devm_kzalloc(&pdev->dev, sizeof(struct msc313_rtc), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->rtc_base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(priv->rtc_base))
return PTR_ERR(priv->rtc_base);
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return -EINVAL;
priv->rtc_dev = devm_rtc_allocate_device(dev);
if (IS_ERR(priv->rtc_dev))
return PTR_ERR(priv->rtc_dev);
priv->rtc_dev->ops = &msc313_rtc_ops;
priv->rtc_dev->range_max = U32_MAX;
ret = devm_request_irq(dev, irq, msc313_rtc_interrupt, IRQF_SHARED,
dev_name(&pdev->dev), &pdev->dev);
if (ret) {
dev_err(dev, "Could not request IRQ\n");
return ret;
}
clk = devm_clk_get(dev, NULL);
if (IS_ERR(clk)) {
dev_err(dev, "No input reference clock\n");
return PTR_ERR(clk);
}
ret = clk_prepare_enable(clk);
if (ret) {
dev_err(dev, "Failed to enable the reference clock, %d\n", ret);
return ret;
}
ret = devm_add_action_or_reset(dev, (void (*) (void *))clk_disable_unprepare, clk);
if (ret)
return ret;
rate = clk_get_rate(clk);
writew(rate & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_L);
writew((rate >> 16) & 0xFFFF, priv->rtc_base + REG_RTC_FREQ_CW_H);
platform_set_drvdata(pdev, priv);
return devm_rtc_register_device(priv->rtc_dev);
}
static const struct of_device_id msc313_rtc_of_match_table[] = {
{ .compatible = "mstar,msc313-rtc" },
{ }
};
MODULE_DEVICE_TABLE(of, msc313_rtc_of_match_table);
static struct platform_driver msc313_rtc_driver = {
.probe = msc313_rtc_probe,
.driver = {
.name = "msc313-rtc",
.of_match_table = msc313_rtc_of_match_table,
},
};
module_platform_driver(msc313_rtc_driver);
MODULE_AUTHOR("Daniel Palmer <daniel@thingy.jp>");
MODULE_AUTHOR("Romain Perier <romain.perier@gmail.com>");
MODULE_DESCRIPTION("MStar RTC Driver");
MODULE_LICENSE("GPL v2");

View File

@ -1029,6 +1029,5 @@ static struct platform_driver omap_rtc_driver = {
module_platform_driver(omap_rtc_driver);
MODULE_ALIAS("platform:omap_rtc");
MODULE_AUTHOR("George G. Davis (and others)");
MODULE_LICENSE("GPL");

View File

@ -451,12 +451,21 @@ static const struct of_device_id pcf2123_dt_ids[] = {
MODULE_DEVICE_TABLE(of, pcf2123_dt_ids);
#endif
static const struct spi_device_id pcf2123_spi_ids[] = {
{ .name = "pcf2123", },
{ .name = "rv2123", },
{ .name = "rtc-pcf2123", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(spi, pcf2123_spi_ids);
static struct spi_driver pcf2123_driver = {
.driver = {
.name = "rtc-pcf2123",
.of_match_table = of_match_ptr(pcf2123_dt_ids),
},
.probe = pcf2123_probe,
.id_table = pcf2123_spi_ids,
};
module_spi_driver(pcf2123_driver);

View File

@ -34,6 +34,7 @@
#define PCF85063_REG_CTRL1 0x00 /* status */
#define PCF85063_REG_CTRL1_CAP_SEL BIT(0)
#define PCF85063_REG_CTRL1_STOP BIT(5)
#define PCF85063_REG_CTRL1_EXT_TEST BIT(7)
#define PCF85063_REG_CTRL2 0x01
#define PCF85063_CTRL2_AF BIT(6)
@ -117,6 +118,7 @@ static int pcf85063_rtc_set_time(struct device *dev, struct rtc_time *tm)
* reset state until all time/date registers are written
*/
rc = regmap_update_bits(pcf85063->regmap, PCF85063_REG_CTRL1,
PCF85063_REG_CTRL1_EXT_TEST |
PCF85063_REG_CTRL1_STOP,
PCF85063_REG_CTRL1_STOP);
if (rc)
@ -297,7 +299,7 @@ static int pcf85063_ioctl(struct device *dev, unsigned int cmd,
if (ret < 0)
return ret;
status = status & PCF85063_REG_SC_OS ? RTC_VL_DATA_INVALID : 0;
status = (status & PCF85063_REG_SC_OS) ? RTC_VL_DATA_INVALID : 0;
return put_user(status, (unsigned int __user *)arg);
@ -479,6 +481,18 @@ static struct clk *pcf85063_clkout_register_clk(struct pcf85063 *pcf85063)
struct clk *clk;
struct clk_init_data init;
struct device_node *node = pcf85063->rtc->dev.parent->of_node;
struct device_node *fixed_clock;
fixed_clock = of_get_child_by_name(node, "clock");
if (fixed_clock) {
/*
* skip registering square wave clock when a fixed
* clock has been registered. The fixed clock is
* registered automatically when being referenced.
*/
of_node_put(fixed_clock);
return NULL;
}
init.name = "pcf85063-clkout";
init.ops = &pcf85063_clkout_ops;

View File

@ -4,8 +4,10 @@
*/
#include <linux/bcd.h>
#include <linux/bitfield.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/rtc.h>
#include <linux/of.h>
#include <linux/pm_wakeirq.h>
@ -19,11 +21,10 @@
#define PCF8523_CONTROL2_AF BIT(3)
#define PCF8523_REG_CONTROL3 0x02
#define PCF8523_CONTROL3_PM_BLD BIT(7) /* battery low detection disabled */
#define PCF8523_CONTROL3_PM_VDD BIT(6) /* switch-over disabled */
#define PCF8523_CONTROL3_PM_DSM BIT(5) /* direct switching mode */
#define PCF8523_CONTROL3_PM_MASK 0xe0
#define PCF8523_CONTROL3_PM GENMASK(7,5)
#define PCF8523_PM_STANDBY 0x7
#define PCF8523_CONTROL3_BLF BIT(2) /* battery low bit, read-only */
#define PCF8523_CONTROL3_BSF BIT(3)
#define PCF8523_REG_SECONDS 0x03
#define PCF8523_SECONDS_OS BIT(7)
@ -48,127 +49,45 @@
struct pcf8523 {
struct rtc_device *rtc;
struct i2c_client *client;
struct regmap *regmap;
};
static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep)
static int pcf8523_load_capacitance(struct pcf8523 *pcf8523, struct device_node *node)
{
struct i2c_msg msgs[2];
u8 value = 0;
int err;
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = sizeof(reg);
msgs[0].buf = &reg;
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = sizeof(value);
msgs[1].buf = &value;
err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (err < 0)
return err;
*valuep = value;
return 0;
}
static int pcf8523_write(struct i2c_client *client, u8 reg, u8 value)
{
u8 buffer[2] = { reg, value };
struct i2c_msg msg;
int err;
msg.addr = client->addr;
msg.flags = 0;
msg.len = sizeof(buffer);
msg.buf = buffer;
err = i2c_transfer(client->adapter, &msg, 1);
if (err < 0)
return err;
return 0;
}
static int pcf8523_voltage_low(struct i2c_client *client)
{
u8 value;
int err;
err = pcf8523_read(client, PCF8523_REG_CONTROL3, &value);
if (err < 0)
return err;
return !!(value & PCF8523_CONTROL3_BLF);
}
static int pcf8523_load_capacitance(struct i2c_client *client)
{
u32 load;
u8 value;
int err;
err = pcf8523_read(client, PCF8523_REG_CONTROL1, &value);
if (err < 0)
return err;
u32 load, value = 0;
load = 12500;
of_property_read_u32(client->dev.of_node, "quartz-load-femtofarads",
&load);
of_property_read_u32(node, "quartz-load-femtofarads", &load);
switch (load) {
default:
dev_warn(&client->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 12500",
dev_warn(&pcf8523->rtc->dev, "Unknown quartz-load-femtofarads value: %d. Assuming 12500",
load);
fallthrough;
case 12500:
value |= PCF8523_CONTROL1_CAP_SEL;
break;
case 7000:
value &= ~PCF8523_CONTROL1_CAP_SEL;
break;
}
err = pcf8523_write(client, PCF8523_REG_CONTROL1, value);
return err;
}
static int pcf8523_set_pm(struct i2c_client *client, u8 pm)
{
u8 value;
int err;
err = pcf8523_read(client, PCF8523_REG_CONTROL3, &value);
if (err < 0)
return err;
value = (value & ~PCF8523_CONTROL3_PM_MASK) | pm;
err = pcf8523_write(client, PCF8523_REG_CONTROL3, value);
if (err < 0)
return err;
return 0;
return regmap_update_bits(pcf8523->regmap, PCF8523_REG_CONTROL1,
PCF8523_CONTROL1_CAP_SEL, value);
}
static irqreturn_t pcf8523_irq(int irq, void *dev_id)
{
struct pcf8523 *pcf8523 = i2c_get_clientdata(dev_id);
u8 value;
struct pcf8523 *pcf8523 = dev_id;
u32 value;
int err;
err = pcf8523_read(pcf8523->client, PCF8523_REG_CONTROL2, &value);
err = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL2, &value);
if (err < 0)
return IRQ_HANDLED;
if (value & PCF8523_CONTROL2_AF) {
value &= ~PCF8523_CONTROL2_AF;
pcf8523_write(pcf8523->client, PCF8523_REG_CONTROL2, value);
regmap_write(pcf8523->regmap, PCF8523_REG_CONTROL2, value);
rtc_update_irq(pcf8523->rtc, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
@ -177,68 +96,14 @@ static irqreturn_t pcf8523_irq(int irq, void *dev_id)
return IRQ_NONE;
}
static int pcf8523_stop_rtc(struct i2c_client *client)
{
u8 value;
int err;
err = pcf8523_read(client, PCF8523_REG_CONTROL1, &value);
if (err < 0)
return err;
value |= PCF8523_CONTROL1_STOP;
err = pcf8523_write(client, PCF8523_REG_CONTROL1, value);
if (err < 0)
return err;
return 0;
}
static int pcf8523_start_rtc(struct i2c_client *client)
{
u8 value;
int err;
err = pcf8523_read(client, PCF8523_REG_CONTROL1, &value);
if (err < 0)
return err;
value &= ~PCF8523_CONTROL1_STOP;
err = pcf8523_write(client, PCF8523_REG_CONTROL1, value);
if (err < 0)
return err;
return 0;
}
static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
u8 start = PCF8523_REG_SECONDS, regs[7];
struct i2c_msg msgs[2];
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
u8 regs[7];
int err;
err = pcf8523_voltage_low(client);
if (err < 0) {
return err;
} else if (err > 0) {
dev_err(dev, "low voltage detected, time is unreliable\n");
return -EINVAL;
}
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = &start;
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = sizeof(regs);
msgs[1].buf = regs;
err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_SECONDS, regs,
sizeof(regs));
if (err < 0)
return err;
@ -258,63 +123,50 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm)
static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_msg msg;
u8 regs[8];
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
u8 regs[7];
int err;
err = pcf8523_stop_rtc(client);
err = regmap_update_bits(pcf8523->regmap, PCF8523_REG_CONTROL1,
PCF8523_CONTROL1_STOP, PCF8523_CONTROL1_STOP);
if (err < 0)
return err;
regs[0] = PCF8523_REG_SECONDS;
/* This will purposely overwrite PCF8523_SECONDS_OS */
regs[1] = bin2bcd(tm->tm_sec);
regs[2] = bin2bcd(tm->tm_min);
regs[3] = bin2bcd(tm->tm_hour);
regs[4] = bin2bcd(tm->tm_mday);
regs[5] = tm->tm_wday;
regs[6] = bin2bcd(tm->tm_mon + 1);
regs[7] = bin2bcd(tm->tm_year - 100);
regs[0] = bin2bcd(tm->tm_sec);
regs[1] = bin2bcd(tm->tm_min);
regs[2] = bin2bcd(tm->tm_hour);
regs[3] = bin2bcd(tm->tm_mday);
regs[4] = tm->tm_wday;
regs[5] = bin2bcd(tm->tm_mon + 1);
regs[6] = bin2bcd(tm->tm_year - 100);
msg.addr = client->addr;
msg.flags = 0;
msg.len = sizeof(regs);
msg.buf = regs;
err = i2c_transfer(client->adapter, &msg, 1);
err = regmap_bulk_write(pcf8523->regmap, PCF8523_REG_SECONDS, regs,
sizeof(regs));
if (err < 0) {
/*
* If the time cannot be set, restart the RTC anyway. Note
* that errors are ignored if the RTC cannot be started so
* that we have a chance to propagate the original error.
*/
pcf8523_start_rtc(client);
regmap_update_bits(pcf8523->regmap, PCF8523_REG_CONTROL1,
PCF8523_CONTROL1_STOP, 0);
return err;
}
return pcf8523_start_rtc(client);
return regmap_update_bits(pcf8523->regmap, PCF8523_REG_CONTROL1,
PCF8523_CONTROL1_STOP, 0);
}
static int pcf8523_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
struct i2c_client *client = to_i2c_client(dev);
u8 start = PCF8523_REG_MINUTE_ALARM, regs[4];
struct i2c_msg msgs[2];
u8 value;
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
u8 regs[4];
u32 value;
int err;
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = 1;
msgs[0].buf = &start;
msgs[1].addr = client->addr;
msgs[1].flags = I2C_M_RD;
msgs[1].len = sizeof(regs);
msgs[1].buf = regs;
err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
err = regmap_bulk_read(pcf8523->regmap, PCF8523_REG_MINUTE_ALARM, regs,
sizeof(regs));
if (err < 0)
return err;
@ -324,12 +176,12 @@ static int pcf8523_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
tm->time.tm_mday = bcd2bin(regs[2] & 0x3F);
tm->time.tm_wday = bcd2bin(regs[3] & 0x7);
err = pcf8523_read(client, PCF8523_REG_CONTROL1, &value);
err = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL1, &value);
if (err < 0)
return err;
tm->enabled = !!(value & PCF8523_CONTROL1_AIE);
err = pcf8523_read(client, PCF8523_REG_CONTROL2, &value);
err = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL2, &value);
if (err < 0)
return err;
tm->pending = !!(value & PCF8523_CONTROL2_AF);
@ -339,30 +191,16 @@ static int pcf8523_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
static int pcf8523_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
u8 value;
int err;
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
err = pcf8523_read(client, PCF8523_REG_CONTROL1, &value);
if (err < 0)
return err;
value &= PCF8523_CONTROL1_AIE;
if (enabled)
value |= PCF8523_CONTROL1_AIE;
err = pcf8523_write(client, PCF8523_REG_CONTROL1, value);
if (err < 0)
return err;
return 0;
return regmap_update_bits(pcf8523->regmap, PCF8523_REG_CONTROL1,
PCF8523_CONTROL1_AIE, enabled ?
PCF8523_CONTROL1_AIE : 0);
}
static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
{
struct i2c_client *client = to_i2c_client(dev);
struct i2c_msg msg;
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
u8 regs[5];
int err;
@ -370,7 +208,7 @@ static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
if (err)
return err;
err = pcf8523_write(client, PCF8523_REG_CONTROL2, 0);
err = regmap_write(pcf8523->regmap, PCF8523_REG_CONTROL2, 0);
if (err < 0)
return err;
@ -382,16 +220,13 @@ static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
rtc_time64_to_tm(alarm_time, &tm->time);
}
regs[0] = PCF8523_REG_MINUTE_ALARM;
regs[1] = bin2bcd(tm->time.tm_min);
regs[2] = bin2bcd(tm->time.tm_hour);
regs[3] = bin2bcd(tm->time.tm_mday);
regs[4] = ALARM_DIS;
msg.addr = client->addr;
msg.flags = 0;
msg.len = sizeof(regs);
msg.buf = regs;
err = i2c_transfer(client->adapter, &msg, 1);
regs[0] = bin2bcd(tm->time.tm_min);
regs[1] = bin2bcd(tm->time.tm_hour);
regs[2] = bin2bcd(tm->time.tm_mday);
regs[3] = ALARM_DIS;
err = regmap_bulk_write(pcf8523->regmap, PCF8523_REG_MINUTE_ALARM, regs,
sizeof(regs));
if (err < 0)
return err;
@ -401,24 +236,101 @@ static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm)
return 0;
}
#ifdef CONFIG_RTC_INTF_DEV
static int pcf8523_param_get(struct device *dev, struct rtc_param *param)
{
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
int ret;
switch(param->param) {
u32 value;
case RTC_PARAM_BACKUP_SWITCH_MODE:
ret = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL3, &value);
if (ret < 0)
return ret;
value = FIELD_GET(PCF8523_CONTROL3_PM, value);
switch(value) {
case 0x0:
case 0x4:
param->uvalue = RTC_BSM_LEVEL;
break;
case 0x1:
case 0x5:
param->uvalue = RTC_BSM_DIRECT;
break;
case PCF8523_PM_STANDBY:
param->uvalue = RTC_BSM_STANDBY;
break;
default:
param->uvalue = RTC_BSM_DISABLED;
}
break;
default:
return -EINVAL;
}
return 0;
}
static int pcf8523_param_set(struct device *dev, struct rtc_param *param)
{
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
switch(param->param) {
u8 mode;
case RTC_PARAM_BACKUP_SWITCH_MODE:
switch (param->uvalue) {
case RTC_BSM_DISABLED:
mode = 0x2;
break;
case RTC_BSM_DIRECT:
mode = 0x1;
break;
case RTC_BSM_LEVEL:
mode = 0x0;
break;
case RTC_BSM_STANDBY:
mode = PCF8523_PM_STANDBY;
break;
default:
return -EINVAL;
}
return regmap_update_bits(pcf8523->regmap, PCF8523_REG_CONTROL3,
PCF8523_CONTROL3_PM,
FIELD_PREP(PCF8523_CONTROL3_PM, mode));
break;
default:
return -EINVAL;
}
return 0;
}
static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
unsigned int flags = 0;
u8 value;
u32 value;
int ret;
switch (cmd) {
case RTC_VL_READ:
ret = pcf8523_voltage_low(client);
ret = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL3, &value);
if (ret < 0)
return ret;
if (ret)
if (value & PCF8523_CONTROL3_BLF)
flags |= RTC_VL_BACKUP_LOW;
ret = pcf8523_read(client, PCF8523_REG_SECONDS, &value);
ret = regmap_read(pcf8523->regmap, PCF8523_REG_SECONDS, &value);
if (ret < 0)
return ret;
@ -431,18 +343,15 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
return -ENOIOCTLCMD;
}
}
#else
#define pcf8523_rtc_ioctl NULL
#endif
static int pcf8523_rtc_read_offset(struct device *dev, long *offset)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
int err;
u8 value;
u32 value;
s8 val;
err = pcf8523_read(client, PCF8523_REG_OFFSET, &value);
err = regmap_read(pcf8523->regmap, PCF8523_REG_OFFSET, &value);
if (err < 0)
return err;
@ -455,9 +364,9 @@ static int pcf8523_rtc_read_offset(struct device *dev, long *offset)
static int pcf8523_rtc_set_offset(struct device *dev, long offset)
{
struct i2c_client *client = to_i2c_client(dev);
struct pcf8523 *pcf8523 = dev_get_drvdata(dev);
long reg_m0, reg_m1;
u8 value;
u32 value;
reg_m0 = clamp(DIV_ROUND_CLOSEST(offset, 4340), -64L, 63L);
reg_m1 = clamp(DIV_ROUND_CLOSEST(offset, 4069), -64L, 63L);
@ -467,7 +376,7 @@ static int pcf8523_rtc_set_offset(struct device *dev, long offset)
else
value = (reg_m1 & 0x7f) | PCF8523_OFFSET_MODE;
return pcf8523_write(client, PCF8523_REG_OFFSET, value);
return regmap_write(pcf8523->regmap, PCF8523_REG_OFFSET, value);
}
static const struct rtc_class_ops pcf8523_rtc_ops = {
@ -479,6 +388,14 @@ static const struct rtc_class_ops pcf8523_rtc_ops = {
.ioctl = pcf8523_rtc_ioctl,
.read_offset = pcf8523_rtc_read_offset,
.set_offset = pcf8523_rtc_set_offset,
.param_get = pcf8523_param_get,
.param_set = pcf8523_param_set,
};
static const struct regmap_config regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x13,
};
static int pcf8523_probe(struct i2c_client *client,
@ -487,6 +404,7 @@ static int pcf8523_probe(struct i2c_client *client,
struct pcf8523 *pcf8523;
struct rtc_device *rtc;
bool wakeup_source = false;
u32 value;
int err;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
@ -496,46 +414,60 @@ static int pcf8523_probe(struct i2c_client *client,
if (!pcf8523)
return -ENOMEM;
pcf8523->regmap = devm_regmap_init_i2c(client, &regmap_config);
if (IS_ERR(pcf8523->regmap))
return PTR_ERR(pcf8523->regmap);
i2c_set_clientdata(client, pcf8523);
pcf8523->client = client;
err = pcf8523_load_capacitance(client);
if (err < 0)
dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
err);
err = pcf8523_set_pm(client, 0);
if (err < 0)
return err;
rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
pcf8523->rtc = rtc;
err = pcf8523_load_capacitance(pcf8523, client->dev.of_node);
if (err < 0)
dev_warn(&client->dev, "failed to set xtal load capacitance: %d",
err);
err = regmap_read(pcf8523->regmap, PCF8523_REG_SECONDS, &value);
if (err < 0)
return err;
if (value & PCF8523_SECONDS_OS) {
err = regmap_read(pcf8523->regmap, PCF8523_REG_CONTROL3, &value);
if (err < 0)
return err;
if (FIELD_GET(PCF8523_CONTROL3_PM, value) == PCF8523_PM_STANDBY) {
err = regmap_write(pcf8523->regmap, PCF8523_REG_CONTROL3,
value & ~PCF8523_CONTROL3_PM);
if (err < 0)
return err;
}
}
rtc->ops = &pcf8523_rtc_ops;
rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rtc->range_max = RTC_TIMESTAMP_END_2099;
rtc->uie_unsupported = 1;
if (client->irq > 0) {
err = pcf8523_write(client, PCF8523_TMR_CLKOUT_CTRL, 0x38);
err = regmap_write(pcf8523->regmap, PCF8523_TMR_CLKOUT_CTRL, 0x38);
if (err < 0)
return err;
err = devm_request_threaded_irq(&client->dev, client->irq,
NULL, pcf8523_irq,
IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW,
dev_name(&rtc->dev), client);
dev_name(&rtc->dev), pcf8523);
if (err)
return err;
dev_pm_set_wake_irq(&client->dev, client->irq);
}
#ifdef CONFIG_OF
wakeup_source = of_property_read_bool(client->dev.of_node, "wakeup-source");
#endif
if (client->irq > 0 || wakeup_source)
device_init_wakeup(&client->dev, true);
@ -548,19 +480,17 @@ static const struct i2c_device_id pcf8523_id[] = {
};
MODULE_DEVICE_TABLE(i2c, pcf8523_id);
#ifdef CONFIG_OF
static const struct of_device_id pcf8523_of_match[] = {
{ .compatible = "nxp,pcf8523" },
{ .compatible = "microcrystal,rv8523" },
{ }
};
MODULE_DEVICE_TABLE(of, pcf8523_of_match);
#endif
static struct i2c_driver pcf8523_driver = {
.driver = {
.name = "rtc-pcf8523",
.of_match_table = of_match_ptr(pcf8523_of_match),
.of_match_table = pcf8523_of_match,
},
.probe = pcf8523_probe,
.id_table = pcf8523_id,

View File

@ -10,6 +10,7 @@
#include <linux/clk-provider.h>
#include <linux/bcd.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
@ -80,6 +81,10 @@
#define RV3028_BACKUP_TCE BIT(5)
#define RV3028_BACKUP_TCR_MASK GENMASK(1,0)
#define RV3028_BACKUP_BSM GENMASK(3,2)
#define RV3028_BACKUP_BSM_DSM 0x1
#define RV3028_BACKUP_BSM_LSM 0x3
#define OFFSET_STEP_PPT 953674
@ -512,6 +517,71 @@ exit_eerd:
}
static int rv3028_param_get(struct device *dev, struct rtc_param *param)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev);
int ret;
switch(param->param) {
u32 value;
case RTC_PARAM_BACKUP_SWITCH_MODE:
ret = regmap_read(rv3028->regmap, RV3028_BACKUP, &value);
if (ret < 0)
return ret;
value = FIELD_GET(RV3028_BACKUP_BSM, value);
switch(value) {
case RV3028_BACKUP_BSM_DSM:
param->uvalue = RTC_BSM_DIRECT;
break;
case RV3028_BACKUP_BSM_LSM:
param->uvalue = RTC_BSM_LEVEL;
break;
default:
param->uvalue = RTC_BSM_DISABLED;
}
break;
default:
return -EINVAL;
}
return 0;
}
static int rv3028_param_set(struct device *dev, struct rtc_param *param)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev);
switch(param->param) {
u8 mode;
case RTC_PARAM_BACKUP_SWITCH_MODE:
switch (param->uvalue) {
case RTC_BSM_DISABLED:
mode = 0;
break;
case RTC_BSM_DIRECT:
mode = RV3028_BACKUP_BSM_DSM;
break;
case RTC_BSM_LEVEL:
mode = RV3028_BACKUP_BSM_LSM;
break;
default:
return -EINVAL;
}
return rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_BSM,
FIELD_PREP(RV3028_BACKUP_BSM, mode));
default:
return -EINVAL;
}
return 0;
}
static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rv3028_data *rv3028 = dev_get_drvdata(dev);
@ -776,6 +846,8 @@ static const struct rtc_class_ops rv3028_rtc_ops = {
.read_offset = rv3028_read_offset,
.set_offset = rv3028_set_offset,
.ioctl = rv3028_ioctl,
.param_get = rv3028_param_get,
.param_set = rv3028_param_set,
};
static const struct regmap_config regmap_config = {
@ -878,6 +950,8 @@ static int rv3028_probe(struct i2c_client *client)
if (ret)
return ret;
set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3028->rtc->features);
rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099;
rv3028->rtc->ops = &rv3028_rtc_ops;

View File

@ -106,6 +106,7 @@
struct rv3032_data {
struct regmap *regmap;
struct rtc_device *rtc;
bool trickle_charger_set;
#ifdef CONFIG_COMMON_CLK
struct clk_hw clkout_hw;
#endif
@ -310,14 +311,6 @@ static int rv3032_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
u8 ctrl = 0;
int ret;
/* The alarm has no seconds, round up to nearest minute */
if (alrm->time.tm_sec) {
time64_t alarm_time = rtc_tm_to_time64(&alrm->time);
alarm_time += 60 - alrm->time.tm_sec;
rtc_time64_to_tm(alarm_time, &alrm->time);
}
ret = regmap_update_bits(rv3032->regmap, RV3032_CTRL2,
RV3032_CTRL2_AIE | RV3032_CTRL2_UIE, 0);
if (ret)
@ -402,6 +395,75 @@ static int rv3032_set_offset(struct device *dev, long offset)
FIELD_PREP(RV3032_OFFSET_MSK, offset));
}
static int rv3032_param_get(struct device *dev, struct rtc_param *param)
{
struct rv3032_data *rv3032 = dev_get_drvdata(dev);
int ret;
switch(param->param) {
u32 value;
case RTC_PARAM_BACKUP_SWITCH_MODE:
ret = regmap_read(rv3032->regmap, RV3032_PMU, &value);
if (ret < 0)
return ret;
value = FIELD_GET(RV3032_PMU_BSM, value);
switch(value) {
case RV3032_PMU_BSM_DSM:
param->uvalue = RTC_BSM_DIRECT;
break;
case RV3032_PMU_BSM_LSM:
param->uvalue = RTC_BSM_LEVEL;
break;
default:
param->uvalue = RTC_BSM_DISABLED;
}
break;
default:
return -EINVAL;
}
return 0;
}
static int rv3032_param_set(struct device *dev, struct rtc_param *param)
{
struct rv3032_data *rv3032 = dev_get_drvdata(dev);
switch(param->param) {
u8 mode;
case RTC_PARAM_BACKUP_SWITCH_MODE:
if (rv3032->trickle_charger_set)
return -EINVAL;
switch (param->uvalue) {
case RTC_BSM_DISABLED:
mode = 0;
break;
case RTC_BSM_DIRECT:
mode = RV3032_PMU_BSM_DSM;
break;
case RTC_BSM_LEVEL:
mode = RV3032_PMU_BSM_LSM;
break;
default:
return -EINVAL;
}
return rv3032_update_cfg(rv3032, RV3032_PMU, RV3032_PMU_BSM,
FIELD_PREP(RV3032_PMU_BSM, mode));
default:
return -EINVAL;
}
return 0;
}
static int rv3032_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
{
struct rv3032_data *rv3032 = dev_get_drvdata(dev);
@ -541,6 +603,8 @@ static int rv3032_trickle_charger_setup(struct device *dev, struct rv3032_data *
return 0;
}
rv3032->trickle_charger_set = true;
return rv3032_update_cfg(rv3032, RV3032_PMU,
RV3032_PMU_TCR | RV3032_PMU_TCM | RV3032_PMU_BSM,
val | FIELD_PREP(RV3032_PMU_TCR, i));
@ -617,11 +681,11 @@ static int rv3032_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
ret = rv3032_enter_eerd(rv3032, &eerd);
if (ret)
goto exit_eerd;
return ret;
ret = regmap_write(rv3032->regmap, RV3032_CLKOUT1, hfd & 0xff);
if (ret)
return ret;
goto exit_eerd;
ret = regmap_write(rv3032->regmap, RV3032_CLKOUT2, RV3032_CLKOUT2_OS |
FIELD_PREP(RV3032_CLKOUT2_HFD_MSK, hfd >> 8));
@ -813,6 +877,8 @@ static const struct rtc_class_ops rv3032_rtc_ops = {
.read_alarm = rv3032_get_alarm,
.set_alarm = rv3032_set_alarm,
.alarm_irq_enable = rv3032_alarm_irq_enable,
.param_get = rv3032_param_get,
.param_set = rv3032_param_set,
};
static const struct regmap_config regmap_config = {
@ -883,6 +949,9 @@ static int rv3032_probe(struct i2c_client *client)
rv3032_trickle_charger_setup(&client->dev, rv3032);
set_bit(RTC_FEATURE_BACKUP_SWITCH_MODE, rv3032->rtc->features);
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rv3032->rtc->features);
rv3032->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
rv3032->rtc->range_max = RTC_TIMESTAMP_END_2099;
rv3032->rtc->ops = &rv3032_rtc_ops;

View File

@ -340,8 +340,8 @@ static int rv8803_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
}
}
ctrl[1] &= ~RV8803_FLAG_AF;
err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[1]);
ctrl[0] &= ~RV8803_FLAG_AF;
err = rv8803_write_reg(rv8803->client, RV8803_FLAG, ctrl[0]);
mutex_unlock(&rv8803->flags_lock);
if (err)
return err;

View File

@ -422,7 +422,7 @@ static struct regmap_config regmap_i2c_config = {
static int rx6110_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct i2c_adapter *adapter = client->adapter;
struct rx6110_data *rx6110;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA

View File

@ -248,9 +248,6 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
u8 date[7];
int ret;
if ((dt->tm_year < 100) || (dt->tm_year > 199))
return -EINVAL;
/*
* Here the read-only bits are written as "0". I'm not sure if that
* is sound.
@ -318,9 +315,6 @@ static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
u8 ald[2];
int ctrl2, err;
if (client->irq <= 0)
return -EINVAL;
err = rx8025_read_regs(client, RX8025_REG_ALDMIN, 2, ald);
if (err)
return err;
@ -355,20 +349,6 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
u8 ald[2];
int err;
if (client->irq <= 0)
return -EINVAL;
/*
* Hardware alarm precision is 1 minute!
* round up to nearest minute
*/
if (t->time.tm_sec) {
time64_t alarm_time = rtc_tm_to_time64(&t->time);
alarm_time += 60 - t->time.tm_sec;
rtc_time64_to_tm(alarm_time, &t->time);
}
ald[0] = bin2bcd(t->time.tm_min);
if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224)
ald[1] = bin2bcd(t->time.tm_hour);
@ -423,17 +403,7 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
static const struct rtc_class_ops rx8025_rtc_ops = {
.read_time = rx8025_get_time,
.set_time = rx8025_set_time,
.read_alarm = rx8025_read_alarm,
.set_alarm = rx8025_set_alarm,
.alarm_irq_enable = rx8025_alarm_irq_enable,
};
/*
* Clock precision adjustment support
*
* According to the RX8025 SA/NB application manual the frequency and
* temperature characteristics can be approximated using the following
* equation:
@ -444,11 +414,8 @@ static const struct rtc_class_ops rx8025_rtc_ops = {
* a : Coefficient = (-35 +-5) * 10**-9
* ut: Ultimate temperature in degree = +25 +-5 degree
* t : Any temperature in degree
*
* Note that the clock adjustment in ppb must be entered (which is
* the negative value of the deviation).
*/
static int rx8025_get_clock_adjust(struct device *dev, int *adj)
static int rx8025_read_offset(struct device *dev, long *offset)
{
struct i2c_client *client = to_i2c_client(dev);
int digoff;
@ -457,63 +424,75 @@ static int rx8025_get_clock_adjust(struct device *dev, int *adj)
if (digoff < 0)
return digoff;
*adj = digoff >= 64 ? digoff - 128 : digoff;
if (*adj > 0)
(*adj)--;
*adj *= -RX8025_ADJ_RESOLUTION;
*offset = digoff >= 64 ? digoff - 128 : digoff;
if (*offset > 0)
(*offset)--;
*offset *= RX8025_ADJ_RESOLUTION;
return 0;
}
static int rx8025_set_clock_adjust(struct device *dev, int adj)
static int rx8025_set_offset(struct device *dev, long offset)
{
struct i2c_client *client = to_i2c_client(dev);
u8 digoff;
int err;
adj /= -RX8025_ADJ_RESOLUTION;
if (adj > RX8025_ADJ_DATA_MAX)
adj = RX8025_ADJ_DATA_MAX;
else if (adj < RX8025_ADJ_DATA_MIN)
adj = RX8025_ADJ_DATA_MIN;
else if (adj > 0)
adj++;
else if (adj < 0)
adj += 128;
digoff = adj;
offset /= RX8025_ADJ_RESOLUTION;
if (offset > RX8025_ADJ_DATA_MAX)
offset = RX8025_ADJ_DATA_MAX;
else if (offset < RX8025_ADJ_DATA_MIN)
offset = RX8025_ADJ_DATA_MIN;
else if (offset > 0)
offset++;
else if (offset < 0)
offset += 128;
digoff = offset;
err = rx8025_write_reg(client, RX8025_REG_DIGOFF, digoff);
if (err)
return err;
dev_dbg(dev, "%s: write 0x%02x\n", __func__, digoff);
return 0;
}
static const struct rtc_class_ops rx8025_rtc_ops = {
.read_time = rx8025_get_time,
.set_time = rx8025_set_time,
.read_alarm = rx8025_read_alarm,
.set_alarm = rx8025_set_alarm,
.alarm_irq_enable = rx8025_alarm_irq_enable,
.read_offset = rx8025_read_offset,
.set_offset = rx8025_set_offset,
};
static ssize_t rx8025_sysfs_show_clock_adjust(struct device *dev,
struct device_attribute *attr,
char *buf)
{
int err, adj;
long adj;
int err;
err = rx8025_get_clock_adjust(dev, &adj);
dev_warn_once(dev, "clock_adjust_ppb is deprecated, use offset\n");
err = rx8025_read_offset(dev, &adj);
if (err)
return err;
return sprintf(buf, "%d\n", adj);
return sprintf(buf, "%ld\n", -adj);
}
static ssize_t rx8025_sysfs_store_clock_adjust(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
int adj, err;
long adj;
int err;
if (sscanf(buf, "%i", &adj) != 1)
dev_warn_once(dev, "clock_adjust_ppb is deprecated, use offset\n");
if (kstrtol(buf, 10, &adj) != 0)
return -EINVAL;
err = rx8025_set_clock_adjust(dev, adj);
err = rx8025_set_offset(dev, -adj);
return err ? err : count;
}
@ -522,15 +501,14 @@ static DEVICE_ATTR(clock_adjust_ppb, S_IRUGO | S_IWUSR,
rx8025_sysfs_show_clock_adjust,
rx8025_sysfs_store_clock_adjust);
static int rx8025_sysfs_register(struct device *dev)
{
return device_create_file(dev, &dev_attr_clock_adjust_ppb);
}
static struct attribute *rx8025_attrs[] = {
&dev_attr_clock_adjust_ppb.attr,
NULL
};
static void rx8025_sysfs_unregister(struct device *dev)
{
device_remove_file(dev, &dev_attr_clock_adjust_ppb);
}
static const struct attribute_group rx8025_attr_group = {
.attrs = rx8025_attrs,
};
static int rx8025_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@ -559,12 +537,13 @@ static int rx8025_probe(struct i2c_client *client,
if (err)
return err;
rx8025->rtc = devm_rtc_device_register(&client->dev, client->name,
&rx8025_rtc_ops, THIS_MODULE);
if (IS_ERR(rx8025->rtc)) {
dev_err(&client->dev, "unable to register the class device\n");
rx8025->rtc = devm_rtc_allocate_device(&client->dev);
if (IS_ERR(rx8025->rtc))
return PTR_ERR(rx8025->rtc);
}
rx8025->rtc->ops = &rx8025_rtc_ops;
rx8025->rtc->range_min = RTC_TIMESTAMP_BEGIN_1900;
rx8025->rtc->range_max = RTC_TIMESTAMP_END_2099;
if (client->irq > 0) {
dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
@ -572,25 +551,20 @@ static int rx8025_probe(struct i2c_client *client,
rx8025_handle_irq,
IRQF_ONESHOT,
"rx8025", client);
if (err) {
dev_err(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0;
}
if (err)
clear_bit(RTC_FEATURE_ALARM, rx8025->rtc->features);
}
rx8025->rtc->max_user_freq = 1;
/* the rx8025 alarm only supports a minute accuracy */
rx8025->rtc->uie_unsupported = 1;
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, rx8025->rtc->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, rx8025->rtc->features);
err = rx8025_sysfs_register(&client->dev);
return err;
}
err = rtc_add_group(rx8025->rtc, &rx8025_attr_group);
if (err)
return err;
static int rx8025_remove(struct i2c_client *client)
{
rx8025_sysfs_unregister(&client->dev);
return 0;
return devm_rtc_register_device(rx8025->rtc);
}
static struct i2c_driver rx8025_driver = {
@ -598,7 +572,6 @@ static struct i2c_driver rx8025_driver = {
.name = "rtc-rx8025",
},
.probe = rx8025_probe,
.remove = rx8025_remove,
.id_table = rx8025_id,
};

View File

@ -285,9 +285,6 @@ static int s35390a_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday,
alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday);
if (alm->time.tm_sec != 0)
dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n");
/* disable interrupt (which deasserts the irq line) */
err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts));
if (err < 0)
@ -491,8 +488,8 @@ static int s35390a_probe(struct i2c_client *client,
s35390a->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
s35390a->rtc->range_max = RTC_TIMESTAMP_END_2099;
/* supports per-minute alarms only, therefore set uie_unsupported */
s35390a->rtc->uie_unsupported = 1;
set_bit(RTC_FEATURE_ALARM_RES_MINUTE, s35390a->rtc->features);
clear_bit(RTC_FEATURE_UPDATE_INTERRUPT, s35390a->rtc->features );
if (status1 & S35390A_FLAG_INT2)
rtc_update_irq(s35390a->rtc, 1, RTC_AF);

View File

@ -127,10 +127,9 @@ static int s3c_rtc_setaie(struct device *dev, unsigned int enabled)
return ret;
}
/* Time read/write */
static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
/* Read time from RTC and convert it from BCD */
static int s3c_rtc_read_time(struct s3c_rtc *info, struct rtc_time *tm)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
unsigned int have_retried = 0;
int ret;
@ -139,54 +138,40 @@ static int s3c_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm)
return ret;
retry_get_time:
rtc_tm->tm_min = readb(info->base + S3C2410_RTCMIN);
rtc_tm->tm_hour = readb(info->base + S3C2410_RTCHOUR);
rtc_tm->tm_mday = readb(info->base + S3C2410_RTCDATE);
rtc_tm->tm_mon = readb(info->base + S3C2410_RTCMON);
rtc_tm->tm_year = readb(info->base + S3C2410_RTCYEAR);
rtc_tm->tm_sec = readb(info->base + S3C2410_RTCSEC);
tm->tm_min = readb(info->base + S3C2410_RTCMIN);
tm->tm_hour = readb(info->base + S3C2410_RTCHOUR);
tm->tm_mday = readb(info->base + S3C2410_RTCDATE);
tm->tm_mon = readb(info->base + S3C2410_RTCMON);
tm->tm_year = readb(info->base + S3C2410_RTCYEAR);
tm->tm_sec = readb(info->base + S3C2410_RTCSEC);
/* the only way to work out whether the system was mid-update
/*
* The only way to work out whether the system was mid-update
* when we read it is to check the second counter, and if it
* is zero, then we re-try the entire read
*/
if (rtc_tm->tm_sec == 0 && !have_retried) {
if (tm->tm_sec == 0 && !have_retried) {
have_retried = 1;
goto retry_get_time;
}
rtc_tm->tm_sec = bcd2bin(rtc_tm->tm_sec);
rtc_tm->tm_min = bcd2bin(rtc_tm->tm_min);
rtc_tm->tm_hour = bcd2bin(rtc_tm->tm_hour);
rtc_tm->tm_mday = bcd2bin(rtc_tm->tm_mday);
rtc_tm->tm_mon = bcd2bin(rtc_tm->tm_mon);
rtc_tm->tm_year = bcd2bin(rtc_tm->tm_year);
s3c_rtc_disable_clk(info);
rtc_tm->tm_year += 100;
rtc_tm->tm_mon -= 1;
tm->tm_sec = bcd2bin(tm->tm_sec);
tm->tm_min = bcd2bin(tm->tm_min);
tm->tm_hour = bcd2bin(tm->tm_hour);
tm->tm_mday = bcd2bin(tm->tm_mday);
tm->tm_mon = bcd2bin(tm->tm_mon);
tm->tm_year = bcd2bin(tm->tm_year);
dev_dbg(dev, "read time %ptR\n", rtc_tm);
return 0;
}
static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
/* Convert time to BCD and write it to RTC */
static int s3c_rtc_write_time(struct s3c_rtc *info, const struct rtc_time *tm)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
int year = tm->tm_year - 100;
int ret;
dev_dbg(dev, "set time %ptR\n", tm);
/* we get around y2k by simply not supporting it */
if (year < 0 || year >= 100) {
dev_err(dev, "rtc only supports 100 years\n");
return -EINVAL;
}
ret = s3c_rtc_enable_clk(info);
if (ret)
return ret;
@ -195,14 +180,48 @@ static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
writeb(bin2bcd(tm->tm_min), info->base + S3C2410_RTCMIN);
writeb(bin2bcd(tm->tm_hour), info->base + S3C2410_RTCHOUR);
writeb(bin2bcd(tm->tm_mday), info->base + S3C2410_RTCDATE);
writeb(bin2bcd(tm->tm_mon + 1), info->base + S3C2410_RTCMON);
writeb(bin2bcd(year), info->base + S3C2410_RTCYEAR);
writeb(bin2bcd(tm->tm_mon), info->base + S3C2410_RTCMON);
writeb(bin2bcd(tm->tm_year), info->base + S3C2410_RTCYEAR);
s3c_rtc_disable_clk(info);
return 0;
}
static int s3c_rtc_gettime(struct device *dev, struct rtc_time *tm)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
int ret;
ret = s3c_rtc_read_time(info, tm);
if (ret)
return ret;
/* Convert internal representation to actual date/time */
tm->tm_year += 100;
tm->tm_mon -= 1;
dev_dbg(dev, "read time %ptR\n", tm);
return 0;
}
static int s3c_rtc_settime(struct device *dev, struct rtc_time *tm)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
struct rtc_time rtc_tm = *tm;
dev_dbg(dev, "set time %ptR\n", tm);
/*
* Convert actual date/time to internal representation.
* We get around Y2K by simply not supporting it.
*/
rtc_tm.tm_year -= 100;
rtc_tm.tm_mon += 1;
return s3c_rtc_write_time(info, &rtc_tm);
}
static int s3c_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct s3c_rtc *info = dev_get_drvdata(dev);
@ -447,15 +466,20 @@ static int s3c_rtc_probe(struct platform_device *pdev)
device_init_wakeup(&pdev->dev, 1);
/* register RTC and exit */
info->rtc = devm_rtc_device_register(&pdev->dev, "s3c", &s3c_rtcops,
THIS_MODULE);
info->rtc = devm_rtc_allocate_device(&pdev->dev);
if (IS_ERR(info->rtc)) {
dev_err(&pdev->dev, "cannot attach rtc\n");
ret = PTR_ERR(info->rtc);
goto err_nortc;
}
info->rtc->ops = &s3c_rtcops;
info->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
info->rtc->range_max = RTC_TIMESTAMP_END_2099;
ret = devm_rtc_register_device(info->rtc);
if (ret)
goto err_nortc;
ret = devm_request_irq(&pdev->dev, info->irq_alarm, s3c_rtc_alarmirq,
0, "s3c2410-rtc alarm", info);
if (ret) {

View File

@ -861,4 +861,3 @@ module_platform_driver(s5m_rtc_driver);
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_DESCRIPTION("Samsung S5M/S2MPS14 RTC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:s5m-rtc");

View File

@ -673,8 +673,17 @@ static int sun6i_rtc_probe(struct platform_device *pdev)
struct sun6i_rtc_dev *chip = sun6i_rtc;
int ret;
if (!chip)
return -ENODEV;
if (!chip) {
chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
spin_lock_init(&chip->lock);
chip->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(chip->base))
return PTR_ERR(chip->base);
}
platform_set_drvdata(pdev, chip);

View File

@ -1,324 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* rtc-tps80031.c -- TI TPS80031/TPS80032 RTC driver
*
* RTC driver for TI TPS80031/TPS80032 Fully Integrated
* Power Management with Power Path and Battery Charger
*
* Copyright (c) 2012, NVIDIA Corporation.
*
* Author: Laxman Dewangan <ldewangan@nvidia.com>
*/
#include <linux/bcd.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mfd/tps80031.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/rtc.h>
#include <linux/slab.h>
#define ENABLE_ALARM_INT 0x08
#define ALARM_INT_STATUS 0x40
/**
* Setting bit to 1 in STOP_RTC will run the RTC and
* setting this bit to 0 will freeze RTC.
*/
#define STOP_RTC 0x1
/* Power on reset Values of RTC registers */
#define TPS80031_RTC_POR_YEAR 0
#define TPS80031_RTC_POR_MONTH 1
#define TPS80031_RTC_POR_DAY 1
/* Numbers of registers for time and alarms */
#define TPS80031_RTC_TIME_NUM_REGS 7
#define TPS80031_RTC_ALARM_NUM_REGS 6
/**
* PMU RTC have only 2 nibbles to store year information, so using an
* offset of 100 to set the base year as 2000 for our driver.
*/
#define RTC_YEAR_OFFSET 100
struct tps80031_rtc {
struct rtc_device *rtc;
int irq;
};
static int tps80031_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
u8 buff[TPS80031_RTC_TIME_NUM_REGS];
int ret;
ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_SECONDS_REG, TPS80031_RTC_TIME_NUM_REGS, buff);
if (ret < 0) {
dev_err(dev, "reading RTC_SECONDS_REG failed, err = %d\n", ret);
return ret;
}
tm->tm_sec = bcd2bin(buff[0]);
tm->tm_min = bcd2bin(buff[1]);
tm->tm_hour = bcd2bin(buff[2]);
tm->tm_mday = bcd2bin(buff[3]);
tm->tm_mon = bcd2bin(buff[4]) - 1;
tm->tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET;
tm->tm_wday = bcd2bin(buff[6]);
return 0;
}
static int tps80031_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
u8 buff[7];
int ret;
buff[0] = bin2bcd(tm->tm_sec);
buff[1] = bin2bcd(tm->tm_min);
buff[2] = bin2bcd(tm->tm_hour);
buff[3] = bin2bcd(tm->tm_mday);
buff[4] = bin2bcd(tm->tm_mon + 1);
buff[5] = bin2bcd(tm->tm_year % RTC_YEAR_OFFSET);
buff[6] = bin2bcd(tm->tm_wday);
/* Stop RTC while updating the RTC time registers */
ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_CTRL_REG, STOP_RTC);
if (ret < 0) {
dev_err(dev->parent, "Stop RTC failed, err = %d\n", ret);
return ret;
}
ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_SECONDS_REG,
TPS80031_RTC_TIME_NUM_REGS, buff);
if (ret < 0) {
dev_err(dev, "writing RTC_SECONDS_REG failed, err %d\n", ret);
return ret;
}
ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_CTRL_REG, STOP_RTC);
if (ret < 0)
dev_err(dev->parent, "Start RTC failed, err = %d\n", ret);
return ret;
}
static int tps80031_rtc_alarm_irq_enable(struct device *dev,
unsigned int enable)
{
int ret;
if (enable)
ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT);
else
ret = tps80031_clr_bits(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_INTERRUPTS_REG, ENABLE_ALARM_INT);
if (ret < 0) {
dev_err(dev, "Update on RTC_INT failed, err = %d\n", ret);
return ret;
}
return 0;
}
static int tps80031_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
u8 buff[TPS80031_RTC_ALARM_NUM_REGS];
int ret;
buff[0] = bin2bcd(alrm->time.tm_sec);
buff[1] = bin2bcd(alrm->time.tm_min);
buff[2] = bin2bcd(alrm->time.tm_hour);
buff[3] = bin2bcd(alrm->time.tm_mday);
buff[4] = bin2bcd(alrm->time.tm_mon + 1);
buff[5] = bin2bcd(alrm->time.tm_year % RTC_YEAR_OFFSET);
ret = tps80031_writes(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_ALARM_SECONDS_REG,
TPS80031_RTC_ALARM_NUM_REGS, buff);
if (ret < 0) {
dev_err(dev, "Writing RTC_ALARM failed, err %d\n", ret);
return ret;
}
return tps80031_rtc_alarm_irq_enable(dev, alrm->enabled);
}
static int tps80031_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
u8 buff[6];
int ret;
ret = tps80031_reads(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_ALARM_SECONDS_REG,
TPS80031_RTC_ALARM_NUM_REGS, buff);
if (ret < 0) {
dev_err(dev->parent,
"reading RTC_ALARM failed, err = %d\n", ret);
return ret;
}
alrm->time.tm_sec = bcd2bin(buff[0]);
alrm->time.tm_min = bcd2bin(buff[1]);
alrm->time.tm_hour = bcd2bin(buff[2]);
alrm->time.tm_mday = bcd2bin(buff[3]);
alrm->time.tm_mon = bcd2bin(buff[4]) - 1;
alrm->time.tm_year = bcd2bin(buff[5]) + RTC_YEAR_OFFSET;
return 0;
}
static int clear_alarm_int_status(struct device *dev, struct tps80031_rtc *rtc)
{
int ret;
u8 buf;
/**
* As per datasheet, A dummy read of this RTC_STATUS_REG register
* is necessary before each I2C read in order to update the status
* register value.
*/
ret = tps80031_read(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_STATUS_REG, &buf);
if (ret < 0) {
dev_err(dev, "reading RTC_STATUS failed. err = %d\n", ret);
return ret;
}
/* clear Alarm status bits.*/
ret = tps80031_set_bits(dev->parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_STATUS_REG, ALARM_INT_STATUS);
if (ret < 0) {
dev_err(dev, "clear Alarm INT failed, err = %d\n", ret);
return ret;
}
return 0;
}
static irqreturn_t tps80031_rtc_irq(int irq, void *data)
{
struct device *dev = data;
struct tps80031_rtc *rtc = dev_get_drvdata(dev);
int ret;
ret = clear_alarm_int_status(dev, rtc);
if (ret < 0)
return ret;
rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF);
return IRQ_HANDLED;
}
static const struct rtc_class_ops tps80031_rtc_ops = {
.read_time = tps80031_rtc_read_time,
.set_time = tps80031_rtc_set_time,
.set_alarm = tps80031_rtc_set_alarm,
.read_alarm = tps80031_rtc_read_alarm,
.alarm_irq_enable = tps80031_rtc_alarm_irq_enable,
};
static int tps80031_rtc_probe(struct platform_device *pdev)
{
struct tps80031_rtc *rtc;
struct rtc_time tm;
int ret;
rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
if (!rtc)
return -ENOMEM;
rtc->irq = platform_get_irq(pdev, 0);
platform_set_drvdata(pdev, rtc);
/* Start RTC */
ret = tps80031_set_bits(pdev->dev.parent, TPS80031_SLAVE_ID1,
TPS80031_RTC_CTRL_REG, STOP_RTC);
if (ret < 0) {
dev_err(&pdev->dev, "failed to start RTC. err = %d\n", ret);
return ret;
}
/* If RTC have POR values, set time 01:01:2000 */
tps80031_rtc_read_time(&pdev->dev, &tm);
if ((tm.tm_year == RTC_YEAR_OFFSET + TPS80031_RTC_POR_YEAR) &&
(tm.tm_mon == (TPS80031_RTC_POR_MONTH - 1)) &&
(tm.tm_mday == TPS80031_RTC_POR_DAY)) {
tm.tm_year = 2000;
tm.tm_mday = 1;
tm.tm_mon = 1;
ret = tps80031_rtc_set_time(&pdev->dev, &tm);
if (ret < 0) {
dev_err(&pdev->dev,
"RTC set time failed, err = %d\n", ret);
return ret;
}
}
/* Clear alarm intretupt status if it is there */
ret = clear_alarm_int_status(&pdev->dev, rtc);
if (ret < 0) {
dev_err(&pdev->dev, "Clear alarm int failed, err = %d\n", ret);
return ret;
}
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&tps80031_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc)) {
ret = PTR_ERR(rtc->rtc);
dev_err(&pdev->dev, "RTC registration failed, err %d\n", ret);
return ret;
}
ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
tps80031_rtc_irq,
IRQF_ONESHOT,
dev_name(&pdev->dev), rtc);
if (ret < 0) {
dev_err(&pdev->dev, "request IRQ:%d failed, err = %d\n",
rtc->irq, ret);
return ret;
}
device_set_wakeup_capable(&pdev->dev, 1);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tps80031_rtc_suspend(struct device *dev)
{
struct tps80031_rtc *rtc = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
enable_irq_wake(rtc->irq);
return 0;
}
static int tps80031_rtc_resume(struct device *dev)
{
struct tps80031_rtc *rtc = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
disable_irq_wake(rtc->irq);
return 0;
};
#endif
static SIMPLE_DEV_PM_OPS(tps80031_pm_ops, tps80031_rtc_suspend,
tps80031_rtc_resume);
static struct platform_driver tps80031_rtc_driver = {
.driver = {
.name = "tps80031-rtc",
.pm = &tps80031_pm_ops,
},
.probe = tps80031_rtc_probe,
};
module_platform_driver(tps80031_rtc_driver);
MODULE_ALIAS("platform:tps80031-rtc");
MODULE_DESCRIPTION("TI TPS80031/TPS80032 RTC driver");
MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
MODULE_LICENSE("GPL v2");

View File

@ -66,6 +66,8 @@ struct rtc_class_ops {
int (*alarm_irq_enable)(struct device *, unsigned int enabled);
int (*read_offset)(struct device *, long *offset);
int (*set_offset)(struct device *, long offset);
int (*param_get)(struct device *, struct rtc_param *param);
int (*param_set)(struct device *, struct rtc_param *param);
};
struct rtc_device;
@ -80,6 +82,7 @@ struct rtc_timer {
/* flags */
#define RTC_DEV_BUSY 0
#define RTC_NO_CDEV 1
struct rtc_device {
struct device dev;

View File

@ -14,6 +14,7 @@
#include <linux/const.h>
#include <linux/ioctl.h>
#include <linux/types.h>
/*
* The struct used to pass data via the following ioctl. Similar to the
@ -66,6 +67,17 @@ struct rtc_pll_info {
long pll_clock; /* base PLL frequency */
};
struct rtc_param {
__u64 param;
union {
__u64 uvalue;
__s64 svalue;
__u64 ptr;
};
__u32 index;
__u32 __pad;
};
/*
* ioctl calls that are permitted to the /dev/rtc interface, if
* any of the RTC drivers are enabled.
@ -95,6 +107,9 @@ struct rtc_pll_info {
#define RTC_PLL_GET _IOR('p', 0x11, struct rtc_pll_info) /* Get PLL correction */
#define RTC_PLL_SET _IOW('p', 0x12, struct rtc_pll_info) /* Set PLL correction */
#define RTC_PARAM_GET _IOW('p', 0x13, struct rtc_param) /* Get parameter */
#define RTC_PARAM_SET _IOW('p', 0x14, struct rtc_param) /* Set parameter */
#define RTC_VL_DATA_INVALID _BITUL(0) /* Voltage too low, RTC data is invalid */
#define RTC_VL_BACKUP_LOW _BITUL(1) /* Backup voltage is low */
#define RTC_VL_BACKUP_EMPTY _BITUL(2) /* Backup empty or not present */
@ -114,7 +129,21 @@ struct rtc_pll_info {
#define RTC_FEATURE_ALARM 0
#define RTC_FEATURE_ALARM_RES_MINUTE 1
#define RTC_FEATURE_NEED_WEEK_DAY 2
#define RTC_FEATURE_CNT 3
#define RTC_FEATURE_ALARM_RES_2S 3
#define RTC_FEATURE_UPDATE_INTERRUPT 4
#define RTC_FEATURE_CORRECTION 5
#define RTC_FEATURE_BACKUP_SWITCH_MODE 6
#define RTC_FEATURE_CNT 7
/* parameter list */
#define RTC_PARAM_FEATURES 0
#define RTC_PARAM_CORRECTION 1
#define RTC_PARAM_BACKUP_SWITCH_MODE 2
#define RTC_BSM_DISABLED 0
#define RTC_BSM_DIRECT 1
#define RTC_BSM_LEVEL 2
#define RTC_BSM_STANDBY 3
#define RTC_MAX_FREQ 8192