RTC for 4.7

Subsystem wide cleanups:
  - Use IS_ENABLED() instead of checking for built-in or module
  - remove useless DRV_VERSION
  - remove CLK_IS_ROOT
  - remove UIE signaling
 
 Drivers:
  - ds1302: rewritten to be a proper SPI device driver
  - m41t80: huge cleanup, alarm, wakelarm ans oscialltor failure detection
  support
  - rv3029: switch to regmap to handle rv3049, alarm support, fixes
  - zynqmp: enable switching to battery power, fixes
  - small fixes for at91sam9, da9053, ds1307, ds1685, ds3232, r2025, sa1100,
  snvs, stmp3xxx, tps6586x
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCgAGBQJXQHoaAAoJENiigzvaE+LCqKkP/1EmY0R7yTLf0eL/gdbIeEqi
 ji39pqtmhZ9T2KIN3vk2LyrPRY4FUNVehK8MYb8GrBV3LxQR1QqCZTTNH60j5w2h
 mRdWNU7LvbKQTuhGGe68K/Re87V+hbUsgY56/YXqW3IzSzs0ROmDYYw2nYVNoT/T
 TFWA3lzlWbYNIPIVl8COU9OzWp/ejGyVSqaFrZmTeAyAco/BSMdA8z1zVtLF8O56
 KbCUAfssROZ+CiChzKwFUKHFj6f+qTzIg9SaEOsA+EsJJPexJdoV277ugzBdxBFf
 f9IDHOj6xaRrKeKKz2QLjS6cd0pnxoLaN3fL5nxoiqyj+nXKSD4DfiHIvhGcqdS/
 i8di0TAeHnTDOMZ48/LHQ1qCLduPhkEXeiI1BieVx5Nl05PhEysnWbC0wYF8JrJs
 9lm3Q9KI9eIcL/M2NGeO7pXYKQRuYZyZYvc5Qci0s3APJNC7wTp5Ee/9tUADLziM
 z7IfkRkPcQUHltCtKYgV3rTh1QCjY0/cGZuAzMLfNVXF4i79YuHokIRO0fDELumo
 JtzIIpk/Ume4yV5X/t6Xci+RBIBJwt0S4IbF9got0rAgPVDYu6yhd/szNPQsAFJU
 0ORf5XE9yDQbnXx/hjlTm3EALt5UqRmIS6McQ4MvU9meregl9+K5+27eBOkVsnSJ
 ZnI0++4IvqlZ8XpprEIH
 =iiOS
 -----END PGP SIGNATURE-----

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

Pull RTC updates from Alexandre Belloni:
 "Subsystem wide cleanups:
   - Use IS_ENABLED() instead of checking for built-in or module
   - remove useless DRV_VERSION
   - remove CLK_IS_ROOT
   - remove UIE signaling

  Drivers:
   - ds1302: rewritten to be a proper SPI device driver
   - m41t80: huge cleanup, alarm, wakelarm ans oscialltor failure
     detection support
   - rv3029: switch to regmap to handle rv3049, alarm support, fixes
   - zynqmp: enable switching to battery power, fixes
   - small fixes for at91sam9, da9053, ds1307, ds1685, ds3232, r2025,
     sa1100, snvs, stmp3xxx, tps6586x"

* tag 'rtc-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/abelloni/linux: (40 commits)
  rtc: tps6586x: rename so module can be autoloaded
  rtc: rv3029: hide unused i2c device table
  rtc: rs5c372: r2025: fix check for 'oscillator halted' condition
  rtc: rv3029: add alarm IRQ
  rtc: rv3029: fix set_time function
  rtc: rv3029: fix alarm support
  rtc: rv3029: Remove some checks and warnings
  rtc: rv3029: Add support of RV3049
  rtc: rv3029: convert to use regmap
  rtc: rv3029: remove 'i2c' in functions names
  rtc: stmp3xxx: print message on error
  rtc: Use IS_ENABLED() instead of checking for built-in or module
  rtc: ds3232: fix call trace when rtc->ops_lock is used as NULL
  rtc: snvs: return error in case enable_irq_wake fails
  rtc: zynqmp: Update seconds time programming logic
  rtc: sa1100: DT spelling s/interrupt-name/interrupt-names/
  rtc: mc13xxx: remove UIE signaling
  rtc: mxc: remove UIE signaling
  rtc: ds1307: Remove CLK_IS_ROOT
  rtc: hym8563: Remove CLK_IS_ROOT
  ...
This commit is contained in:
Linus Torvalds 2016-05-21 10:42:11 -07:00
commit 63d222b9d2
43 changed files with 1028 additions and 744 deletions

View File

@ -0,0 +1,46 @@
* Maxim/Dallas Semiconductor DS-1302 RTC
Simple device which could be used to store date/time between reboots.
The device uses the standard MicroWire half-duplex transfer timing.
Master output is set on low clock and sensed by the RTC on the rising
edge. Master input is set by the RTC on the trailing edge and is sensed
by the master on low clock.
Required properties:
- compatible : Should be "maxim,ds1302"
Required SPI properties:
- reg : Should be address of the device chip select within
the controller.
- spi-max-frequency : DS-1302 has 500 kHz if powered at 2.2V,
and 2MHz if powered at 5V.
- spi-3wire : The device has a shared signal IN/OUT line.
- spi-lsb-first : DS-1302 requires least significant bit first
transfers.
- spi-cs-high: DS-1302 has active high chip select line. This is
required unless inverted in hardware.
Example:
spi@901c {
#address-cells = <1>;
#size-cells = <0>;
compatible = "icpdas,lp8841-spi-rtc";
reg = <0x901c 0x1>;
rtc@0 {
compatible = "maxim,ds1302";
reg = <0>;
spi-max-frequency = <500000>;
spi-3wire;
spi-lsb-first;
spi-cs-high;
};
};

View File

@ -13,5 +13,5 @@ Example:
compatible = "mrvl,mmp-rtc";
reg = <0xd4010000 0x1000>;
interrupts = <5>, <6>;
interrupt-name = "rtc 1Hz", "rtc alarm";
interrupt-names = "rtc 1Hz", "rtc alarm";
};

View File

@ -573,24 +573,6 @@ config RTC_DRV_EM3027
This driver can also be built as a module. If so, the module
will be called rtc-em3027.
config RTC_DRV_RV3029C2
tristate "Micro Crystal RV3029"
help
If you say yes here you get support for the Micro Crystal
RV3029 RTC chips.
This driver can also be built as a module. If so, the module
will be called rtc-rv3029c2.
config RTC_DRV_RV3029_HWMON
bool "HWMON support for RV3029"
depends on RTC_DRV_RV3029C2 && HWMON
depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
default y
help
Say Y here if you want to expose temperature sensor data on
rtc-rv3029.
config RTC_DRV_RV8803
tristate "Micro Crystal RV8803"
help
@ -634,6 +616,15 @@ config RTC_DRV_M41T94
This driver can also be built as a module. If so, the module
will be called rtc-m41t94.
config RTC_DRV_DS1302
tristate "Dallas/Maxim DS1302"
depends on SPI
help
If you say yes here you get support for the Dallas DS1302 RTC chips.
This driver can also be built as a module. If so, the module
will be called rtc-ds1302.
config RTC_DRV_DS1305
tristate "Dallas/Maxim DS1305/DS1306"
help
@ -777,6 +768,25 @@ config RTC_DRV_PCF2127
This driver can also be built as a module. If so, the module
will be called rtc-pcf2127.
config RTC_DRV_RV3029C2
tristate "Micro Crystal RV3029/3049"
depends on RTC_I2C_AND_SPI
help
If you say yes here you get support for the Micro Crystal
RV3029 and RV3049 RTC chips.
This driver can also be built as a module. If so, the module
will be called rtc-rv3029c2.
config RTC_DRV_RV3029_HWMON
bool "HWMON support for RV3029/3049"
depends on RTC_DRV_RV3029C2 && HWMON
depends on !(RTC_DRV_RV3029C2=y && HWMON=m)
default y
help
Say Y here if you want to expose temperature sensor data on
rtc-rv3029.
comment "Platform RTC drivers"
# this 'CMOS' RTC driver is arch dependent because <asm-generic/rtc.h>
@ -834,12 +844,6 @@ config RTC_DRV_DS1286
help
If you say yes here you get support for the Dallas DS1286 RTC chips.
config RTC_DRV_DS1302
tristate "Dallas DS1302"
depends on SH_SECUREEDGE5410
help
If you say yes here you get support for the Dallas DS1302 RTC chips.
config RTC_DRV_DS1511
tristate "Dallas DS1511"
depends on HAS_IOMEM

View File

@ -268,7 +268,7 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct sam9_rtc *rtc = dev_get_drvdata(dev);
u32 mr = mr = rtt_readl(rtc, MR);
u32 mr = rtt_readl(rtc, MR);
seq_printf(seq, "update_IRQ\t: %s\n",
(mr & AT91_RTT_RTTINCIEN) ? "yes" : "no");

View File

@ -401,7 +401,7 @@ static int cmos_alarm_irq_enable(struct device *dev, unsigned int enabled)
return 0;
}
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
static int cmos_procfs(struct device *dev, struct seq_file *seq)
{

View File

@ -302,6 +302,13 @@ static int da9052_rtc_probe(struct platform_device *pdev)
if (ret != 0)
rtc_err(rtc, "Failed to disable TICKS: %d\n", ret);
device_init_wakeup(&pdev->dev, true);
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&da9052_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc->rtc))
return PTR_ERR(rtc->rtc);
ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM",
da9052_rtc_irq, rtc);
if (ret != 0) {
@ -309,11 +316,7 @@ static int da9052_rtc_probe(struct platform_device *pdev)
return ret;
}
device_init_wakeup(&pdev->dev, true);
rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
&da9052_rtc_ops, THIS_MODULE);
return PTR_ERR_OR_ZERO(rtc->rtc);
return 0;
}
static struct platform_driver da9052_rtc_driver = {

View File

@ -11,8 +11,6 @@
#include <linux/bcd.h>
#include <linux/slab.h>
#define DRV_VERSION "0.2"
struct ds1216_regs {
u8 tsec;
u8 sec;
@ -176,5 +174,4 @@ module_platform_driver_probe(ds1216_rtc_platform_driver, ds1216_rtc_probe);
MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
MODULE_DESCRIPTION("DS1216 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:rtc-ds1216");

View File

@ -20,8 +20,6 @@
#include <linux/io.h>
#include <linux/slab.h>
#define DRV_VERSION "1.0"
struct ds1286_priv {
struct rtc_device *rtc;
u32 __iomem *rtcregs;
@ -363,5 +361,4 @@ module_platform_driver(ds1286_platform_driver);
MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
MODULE_DESCRIPTION("DS1286 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:rtc-ds1286");

View File

@ -9,16 +9,16 @@
* this archive for more details.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/io.h>
#include <linux/bcd.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/rtc.h>
#include <linux/spi/spi.h>
#define DRV_NAME "rtc-ds1302"
#define DRV_VERSION "0.1.1"
#define RTC_CMD_READ 0x81 /* Read command */
#define RTC_CMD_WRITE 0x80 /* Write command */
@ -28,6 +28,8 @@
#define RTC_ADDR_RAM0 0x20 /* Address of RAM0 */
#define RTC_ADDR_TCR 0x08 /* Address of trickle charge register */
#define RTC_CLCK_BURST 0x1F /* Address of clock burst */
#define RTC_CLCK_LEN 0x08 /* Size of clock burst */
#define RTC_ADDR_CTRL 0x07 /* Address of control register */
#define RTC_ADDR_YEAR 0x06 /* Address of year register */
#define RTC_ADDR_DAY 0x05 /* Address of day of week register */
@ -37,219 +39,181 @@
#define RTC_ADDR_MIN 0x01 /* Address of minute register */
#define RTC_ADDR_SEC 0x00 /* Address of second register */
#ifdef CONFIG_SH_SECUREEDGE5410
#include <asm/rtc.h>
#include <mach/secureedge5410.h>
#define RTC_RESET 0x1000
#define RTC_IODATA 0x0800
#define RTC_SCLK 0x0400
#define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00)
#define get_dp() SECUREEDGE_READ_IOPORT()
#define ds1302_set_tx()
#define ds1302_set_rx()
static inline int ds1302_hw_init(void)
static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *time)
{
return 0;
struct spi_device *spi = dev_get_drvdata(dev);
u8 buf[1 + RTC_CLCK_LEN];
u8 *bp = buf;
int status;
/* Enable writing */
bp = buf;
*bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE;
*bp++ = RTC_CMD_WRITE_ENABLE;
status = spi_write_then_read(spi, buf, 2,
NULL, 0);
if (status)
return status;
/* Write registers starting at the first time/date address. */
bp = buf;
*bp++ = RTC_CLCK_BURST << 1 | RTC_CMD_WRITE;
*bp++ = bin2bcd(time->tm_sec);
*bp++ = bin2bcd(time->tm_min);
*bp++ = bin2bcd(time->tm_hour);
*bp++ = bin2bcd(time->tm_mday);
*bp++ = bin2bcd(time->tm_mon + 1);
*bp++ = time->tm_wday + 1;
*bp++ = bin2bcd(time->tm_year % 100);
*bp++ = RTC_CMD_WRITE_DISABLE;
/* use write-then-read since dma from stack is nonportable */
return spi_write_then_read(spi, buf, sizeof(buf),
NULL, 0);
}
static inline void ds1302_reset(void)
static int ds1302_rtc_get_time(struct device *dev, struct rtc_time *time)
{
set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK));
}
struct spi_device *spi = dev_get_drvdata(dev);
u8 addr = RTC_CLCK_BURST << 1 | RTC_CMD_READ;
u8 buf[RTC_CLCK_LEN - 1];
int status;
static inline void ds1302_clock(void)
{
set_dp(get_dp() | RTC_SCLK); /* clock high */
set_dp(get_dp() & ~RTC_SCLK); /* clock low */
}
/* Use write-then-read to get all the date/time registers
* since dma from stack is nonportable
*/
status = spi_write_then_read(spi, &addr, sizeof(addr),
buf, sizeof(buf));
if (status < 0)
return status;
static inline void ds1302_start(void)
{
set_dp(get_dp() | RTC_RESET);
}
/* Decode the registers */
time->tm_sec = bcd2bin(buf[RTC_ADDR_SEC]);
time->tm_min = bcd2bin(buf[RTC_ADDR_MIN]);
time->tm_hour = bcd2bin(buf[RTC_ADDR_HOUR]);
time->tm_wday = buf[RTC_ADDR_DAY] - 1;
time->tm_mday = bcd2bin(buf[RTC_ADDR_DATE]);
time->tm_mon = bcd2bin(buf[RTC_ADDR_MON]) - 1;
time->tm_year = bcd2bin(buf[RTC_ADDR_YEAR]) + 100;
static inline void ds1302_stop(void)
{
set_dp(get_dp() & ~RTC_RESET);
}
static inline void ds1302_txbit(int bit)
{
set_dp((get_dp() & ~RTC_IODATA) | (bit ? RTC_IODATA : 0));
}
static inline int ds1302_rxbit(void)
{
return !!(get_dp() & RTC_IODATA);
}
#else
#error "Add support for your platform"
#endif
static void ds1302_sendbits(unsigned int val)
{
int i;
ds1302_set_tx();
for (i = 8; (i); i--, val >>= 1) {
ds1302_txbit(val & 0x1);
ds1302_clock();
}
}
static unsigned int ds1302_recvbits(void)
{
unsigned int val;
int i;
ds1302_set_rx();
for (i = 0, val = 0; (i < 8); i++) {
val |= (ds1302_rxbit() << i);
ds1302_clock();
}
return val;
}
static unsigned int ds1302_readbyte(unsigned int addr)
{
unsigned int val;
ds1302_reset();
ds1302_start();
ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ);
val = ds1302_recvbits();
ds1302_stop();
return val;
}
static void ds1302_writebyte(unsigned int addr, unsigned int val)
{
ds1302_reset();
ds1302_start();
ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE);
ds1302_sendbits(val);
ds1302_stop();
}
static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
tm->tm_sec = bcd2bin(ds1302_readbyte(RTC_ADDR_SEC));
tm->tm_min = bcd2bin(ds1302_readbyte(RTC_ADDR_MIN));
tm->tm_hour = bcd2bin(ds1302_readbyte(RTC_ADDR_HOUR));
tm->tm_wday = bcd2bin(ds1302_readbyte(RTC_ADDR_DAY));
tm->tm_mday = bcd2bin(ds1302_readbyte(RTC_ADDR_DATE));
tm->tm_mon = bcd2bin(ds1302_readbyte(RTC_ADDR_MON)) - 1;
tm->tm_year = bcd2bin(ds1302_readbyte(RTC_ADDR_YEAR));
if (tm->tm_year < 70)
tm->tm_year += 100;
dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
__func__,
tm->tm_sec, tm->tm_min, tm->tm_hour,
tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday);
return rtc_valid_tm(tm);
}
static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_ENABLE);
/* Stop RTC */
ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);
ds1302_writebyte(RTC_ADDR_SEC, bin2bcd(tm->tm_sec));
ds1302_writebyte(RTC_ADDR_MIN, bin2bcd(tm->tm_min));
ds1302_writebyte(RTC_ADDR_HOUR, bin2bcd(tm->tm_hour));
ds1302_writebyte(RTC_ADDR_DAY, bin2bcd(tm->tm_wday));
ds1302_writebyte(RTC_ADDR_DATE, bin2bcd(tm->tm_mday));
ds1302_writebyte(RTC_ADDR_MON, bin2bcd(tm->tm_mon + 1));
ds1302_writebyte(RTC_ADDR_YEAR, bin2bcd(tm->tm_year % 100));
/* Start RTC */
ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
ds1302_writebyte(RTC_ADDR_CTRL, RTC_CMD_WRITE_DISABLE);
return 0;
}
static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd,
unsigned long arg)
{
switch (cmd) {
#ifdef RTC_SET_CHARGE
case RTC_SET_CHARGE:
{
int tcs_val;
if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int)))
return -EFAULT;
ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf));
return 0;
}
#endif
}
return -ENOIOCTLCMD;
/* Time may not be set */
return rtc_valid_tm(time);
}
static struct rtc_class_ops ds1302_rtc_ops = {
.read_time = ds1302_rtc_read_time,
.read_time = ds1302_rtc_get_time,
.set_time = ds1302_rtc_set_time,
.ioctl = ds1302_rtc_ioctl,
};
static int __init ds1302_rtc_probe(struct platform_device *pdev)
static int ds1302_probe(struct spi_device *spi)
{
struct rtc_device *rtc;
struct rtc_device *rtc;
u8 addr;
u8 buf[4];
u8 *bp = buf;
int status;
if (ds1302_hw_init()) {
dev_err(&pdev->dev, "Failed to init communication channel");
/* Sanity check board setup data. This may be hooked up
* in 3wire mode, but we don't care. Note that unless
* there's an inverter in place, this needs SPI_CS_HIGH!
*/
if (spi->bits_per_word && (spi->bits_per_word != 8)) {
dev_err(&spi->dev, "bad word length\n");
return -EINVAL;
} else if (spi->max_speed_hz > 2000000) {
dev_err(&spi->dev, "speed is too high\n");
return -EINVAL;
} else if (spi->mode & SPI_CPHA) {
dev_err(&spi->dev, "bad mode\n");
return -EINVAL;
}
/* Reset */
ds1302_reset();
/* Write a magic value to the DS1302 RAM, and see if it sticks. */
ds1302_writebyte(RTC_ADDR_RAM0, 0x42);
if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) {
dev_err(&pdev->dev, "Failed to probe");
return -ENODEV;
addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ;
status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1);
if (status < 0) {
dev_err(&spi->dev, "control register read error %d\n",
status);
return status;
}
rtc = devm_rtc_device_register(&pdev->dev, "ds1302",
&ds1302_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0) {
status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1);
if (status < 0) {
dev_err(&spi->dev, "control register read error %d\n",
status);
return status;
}
platform_set_drvdata(pdev, rtc);
if ((buf[0] & ~RTC_CMD_WRITE_DISABLE) != 0) {
dev_err(&spi->dev, "junk in control register\n");
return -ENODEV;
}
}
if (buf[0] == 0) {
bp = buf;
*bp++ = RTC_ADDR_CTRL << 1 | RTC_CMD_WRITE;
*bp++ = RTC_CMD_WRITE_DISABLE;
status = spi_write_then_read(spi, buf, 2, NULL, 0);
if (status < 0) {
dev_err(&spi->dev, "control register write error %d\n",
status);
return status;
}
addr = RTC_ADDR_CTRL << 1 | RTC_CMD_READ;
status = spi_write_then_read(spi, &addr, sizeof(addr), buf, 1);
if (status < 0) {
dev_err(&spi->dev,
"error %d reading control register\n",
status);
return status;
}
if (buf[0] != RTC_CMD_WRITE_DISABLE) {
dev_err(&spi->dev, "failed to detect chip\n");
return -ENODEV;
}
}
spi_set_drvdata(spi, spi);
rtc = devm_rtc_device_register(&spi->dev, "ds1302",
&ds1302_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc)) {
status = PTR_ERR(rtc);
dev_err(&spi->dev, "error %d registering rtc\n", status);
return status;
}
return 0;
}
static struct platform_driver ds1302_platform_driver = {
.driver = {
.name = DRV_NAME,
},
static int ds1302_remove(struct spi_device *spi)
{
spi_set_drvdata(spi, NULL);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id ds1302_dt_ids[] = {
{ .compatible = "maxim,ds1302", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ds1302_dt_ids);
#endif
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,
};
module_platform_driver_probe(ds1302_platform_driver, ds1302_rtc_probe);
module_spi_driver(ds1302_driver);
MODULE_DESCRIPTION("Dallas DS1302 RTC driver");
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("Paul Mundt, David McCullough");
MODULE_LICENSE("GPL v2");

View File

@ -275,9 +275,13 @@ static s32 ds1307_native_smbus_write_block_data(const struct i2c_client *client,
{
u8 suboffset = 0;
if (length <= I2C_SMBUS_BLOCK_MAX)
return i2c_smbus_write_i2c_block_data(client,
if (length <= I2C_SMBUS_BLOCK_MAX) {
s32 retval = i2c_smbus_write_i2c_block_data(client,
command, length, values);
if (retval < 0)
return retval;
return length;
}
while (suboffset < length) {
s32 retval = i2c_smbus_write_i2c_block_data(client,
@ -538,12 +542,8 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
buf[5] = 0;
buf[6] = 0;
/* optionally enable ALARM1 */
/* disable alarms */
buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
if (t->enabled) {
dev_dbg(dev, "alarm IRQ armed\n");
buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
}
buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
ret = ds1307->write_block_data(client,
@ -553,6 +553,13 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
return ret;
}
/* optionally enable ALARM1 */
if (t->enabled) {
dev_dbg(dev, "alarm IRQ armed\n");
buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
i2c_smbus_write_byte_data(client, DS1337_REG_CONTROL, buf[7]);
}
return 0;
}
@ -1144,12 +1151,10 @@ static struct clk_init_data ds3231_clks_init[] = {
[DS3231_CLK_SQW] = {
.name = "ds3231_clk_sqw",
.ops = &ds3231_clk_sqw_ops,
.flags = CLK_IS_ROOT,
},
[DS3231_CLK_32KHZ] = {
.name = "ds3231_clk_32khz",
.ops = &ds3231_clk_32khz_ops,
.flags = CLK_IS_ROOT,
},
};

View File

@ -24,7 +24,6 @@
#include <linux/pm_wakeirq.h>
#include <linux/slab.h>
#define DS1343_DRV_VERSION "01.00"
#define DALLAS_MAXIM_DS1343 0
#define DALLAS_MAXIM_DS1344 1
@ -747,4 +746,3 @@ MODULE_DESCRIPTION("DS1343 RTC SPI Driver");
MODULE_AUTHOR("Raghavendra Chandra Ganiga <ravi23ganiga@gmail.com>,"
"Ankur Srivastava <sankurece@gmail.com>");
MODULE_LICENSE("GPL v2");
MODULE_VERSION(DS1343_DRV_VERSION);

View File

@ -25,8 +25,6 @@
#include <linux/io.h>
#include <linux/module.h>
#define DRV_VERSION "0.6"
enum ds1511reg {
DS1511_SEC = 0x0,
DS1511_MIN = 0x1,
@ -537,4 +535,3 @@ module_platform_driver(ds1511_rtc_driver);
MODULE_AUTHOR("Andrew Sharp <andy.sharp@lsi.com>");
MODULE_DESCRIPTION("Dallas DS1511 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -20,8 +20,6 @@
#include <linux/io.h>
#include <linux/module.h>
#define DRV_VERSION "0.3"
#define RTC_REG_SIZE 0x2000
#define RTC_OFFSET 0x1ff0
@ -359,4 +357,3 @@ module_platform_driver(ds1553_rtc_driver);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("Dallas DS1553 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -13,8 +13,6 @@
#include <linux/rtc.h>
#include <linux/module.h>
#define DRV_VERSION "0.4"
/* Registers */
#define DS1672_REG_CNT_BASE 0
@ -165,8 +163,6 @@ static int ds1672_probe(struct i2c_client *client,
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rtc = devm_rtc_device_register(&client->dev, ds1672_driver.driver.name,
&ds1672_rtc_ops, THIS_MODULE);
@ -213,4 +209,3 @@ module_i2c_driver(ds1672_driver);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -32,8 +32,6 @@
#include <linux/proc_fs.h>
#endif
#define DRV_VERSION "0.42.0"
/* ----------------------------------------------------------------------- */
/* Standard read/write functions if platform does not provide overrides */
@ -2213,6 +2211,7 @@ ds1685_rtc_poweroff(struct platform_device *pdev)
(ctrl4a | RTC_CTRL_4A_PAB));
/* Spin ... we do not switch back to bank0. */
while(1);
unreachable();
}
}
@ -2224,5 +2223,4 @@ MODULE_AUTHOR("Joshua Kinard <kumba@gentoo.org>");
MODULE_AUTHOR("Matthias Fuchs <matthias.fuchs@esd-electronics.com>");
MODULE_DESCRIPTION("Dallas/Maxim DS1685/DS1687-series RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:rtc-ds1685");

View File

@ -24,8 +24,6 @@
#include <linux/io.h>
#include <linux/module.h>
#define DRV_VERSION "0.4"
#define RTC_SIZE 8
#define RTC_CONTROL 0
@ -239,5 +237,4 @@ module_platform_driver(ds1742_rtc_driver);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:rtc-ds1742");

View File

@ -369,6 +369,11 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
if (ret)
return ret;
ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
THIS_MODULE);
if (IS_ERR(ds3232->rtc))
return PTR_ERR(ds3232->rtc);
if (ds3232->irq > 0) {
ret = devm_request_threaded_irq(dev, ds3232->irq, NULL,
ds3232_irq,
@ -380,10 +385,8 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq,
} else
device_init_wakeup(dev, 1);
}
ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops,
THIS_MODULE);
return PTR_ERR_OR_ZERO(ds3232->rtc);
return 0;
}
#ifdef CONFIG_PM_SLEEP

View File

@ -28,8 +28,6 @@
#define EP93XX_RTC_SWCOMP_INT_MASK 0x0000ffff
#define EP93XX_RTC_SWCOMP_INT_SHIFT 0
#define DRV_VERSION "0.3"
/*
* struct device dev.platform_data is used to store our private data
* because struct rtc_device does not have a variable to hold it.
@ -184,5 +182,4 @@ module_platform_driver(ep93xx_rtc_driver);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("EP93XX RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:ep93xx-rtc");

View File

@ -28,7 +28,6 @@
#include <linux/module.h>
#define DRV_NAME "rtc-gemini"
#define DRV_VERSION "0.2"
MODULE_AUTHOR("Hans Ulli Kroll <ulli.kroll@googlemail.com>");
MODULE_DESCRIPTION("RTC driver for Gemini SoC");

View File

@ -413,7 +413,7 @@ static struct clk *hym8563_clkout_register_clk(struct hym8563 *hym8563)
init.name = "hym8563-clkout";
init.ops = &hym8563_clkout_ops;
init.flags = CLK_IS_ROOT;
init.flags = 0;
init.parent_names = NULL;
init.num_parents = 0;
hym8563->clkout_hw.init = &init;

View File

@ -20,8 +20,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
#define DRV_VERSION "0.1"
/* ISL register offsets */
#define ISL12022_REG_SC 0x00
#define ISL12022_REG_MN 0x01
@ -258,8 +256,6 @@ static int isl12022_probe(struct i2c_client *client,
if (!isl12022)
return -ENOMEM;
dev_dbg(&client->dev, "chip found, driver version " DRV_VERSION "\n");
i2c_set_clientdata(client, isl12022);
isl12022->rtc = devm_rtc_device_register(&client->dev,
@ -299,4 +295,3 @@ module_i2c_driver(isl12022_driver);
MODULE_AUTHOR("roman.fietze@telemotive.de");
MODULE_DESCRIPTION("ISL 12022 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -15,8 +15,6 @@
#include <linux/bcd.h>
#include <linux/rtc.h>
#define DRV_VERSION "0.3"
/* Register map */
/* rtc section */
#define ISL1208_REG_SC 0x00
@ -632,9 +630,6 @@ isl1208_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (isl1208_i2c_validate_client(client) < 0)
return -ENODEV;
dev_info(&client->dev,
"chip found, driver version " DRV_VERSION "\n");
if (client->irq > 0) {
rc = devm_request_threaded_irq(&client->dev, client->irq, NULL,
isl1208_rtc_interrupt,
@ -706,4 +701,3 @@ module_i2c_driver(isl1208_driver);
MODULE_AUTHOR("Herbert Valerio Riedel <hvr@gnu.org>");
MODULE_DESCRIPTION("Intersil ISL1208 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -32,41 +32,42 @@
#include <linux/watchdog.h>
#endif
#define M41T80_REG_SSEC 0
#define M41T80_REG_SEC 1
#define M41T80_REG_MIN 2
#define M41T80_REG_HOUR 3
#define M41T80_REG_WDAY 4
#define M41T80_REG_DAY 5
#define M41T80_REG_MON 6
#define M41T80_REG_YEAR 7
#define M41T80_REG_ALARM_MON 0xa
#define M41T80_REG_ALARM_DAY 0xb
#define M41T80_REG_ALARM_HOUR 0xc
#define M41T80_REG_ALARM_MIN 0xd
#define M41T80_REG_ALARM_SEC 0xe
#define M41T80_REG_FLAGS 0xf
#define M41T80_REG_SQW 0x13
#define M41T80_REG_SSEC 0x00
#define M41T80_REG_SEC 0x01
#define M41T80_REG_MIN 0x02
#define M41T80_REG_HOUR 0x03
#define M41T80_REG_WDAY 0x04
#define M41T80_REG_DAY 0x05
#define M41T80_REG_MON 0x06
#define M41T80_REG_YEAR 0x07
#define M41T80_REG_ALARM_MON 0x0a
#define M41T80_REG_ALARM_DAY 0x0b
#define M41T80_REG_ALARM_HOUR 0x0c
#define M41T80_REG_ALARM_MIN 0x0d
#define M41T80_REG_ALARM_SEC 0x0e
#define M41T80_REG_FLAGS 0x0f
#define M41T80_REG_SQW 0x13
#define M41T80_DATETIME_REG_SIZE (M41T80_REG_YEAR + 1)
#define M41T80_ALARM_REG_SIZE \
(M41T80_REG_ALARM_SEC + 1 - M41T80_REG_ALARM_MON)
#define M41T80_SEC_ST (1 << 7) /* ST: Stop Bit */
#define M41T80_ALMON_AFE (1 << 7) /* AFE: AF Enable Bit */
#define M41T80_ALMON_SQWE (1 << 6) /* SQWE: SQW Enable Bit */
#define M41T80_ALHOUR_HT (1 << 6) /* HT: Halt Update Bit */
#define M41T80_FLAGS_AF (1 << 6) /* AF: Alarm Flag Bit */
#define M41T80_FLAGS_BATT_LOW (1 << 4) /* BL: Battery Low Bit */
#define M41T80_WATCHDOG_RB2 (1 << 7) /* RB: Watchdog resolution */
#define M41T80_WATCHDOG_RB1 (1 << 1) /* RB: Watchdog resolution */
#define M41T80_WATCHDOG_RB0 (1 << 0) /* RB: Watchdog resolution */
#define M41T80_SEC_ST BIT(7) /* ST: Stop Bit */
#define M41T80_ALMON_AFE BIT(7) /* AFE: AF Enable Bit */
#define M41T80_ALMON_SQWE BIT(6) /* SQWE: SQW Enable Bit */
#define M41T80_ALHOUR_HT BIT(6) /* HT: Halt Update Bit */
#define M41T80_FLAGS_OF BIT(2) /* OF: Oscillator Failure Bit */
#define M41T80_FLAGS_AF BIT(6) /* AF: Alarm Flag Bit */
#define M41T80_FLAGS_BATT_LOW BIT(4) /* BL: Battery Low Bit */
#define M41T80_WATCHDOG_RB2 BIT(7) /* RB: Watchdog resolution */
#define M41T80_WATCHDOG_RB1 BIT(1) /* RB: Watchdog resolution */
#define M41T80_WATCHDOG_RB0 BIT(0) /* RB: Watchdog resolution */
#define M41T80_FEATURE_HT (1 << 0) /* Halt feature */
#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
#define M41T80_FEATURE_HT BIT(0) /* Halt feature */
#define M41T80_FEATURE_BL BIT(1) /* Battery low indicator */
#define M41T80_FEATURE_SQ BIT(2) /* Squarewave feature */
#define M41T80_FEATURE_WD BIT(3) /* Extra watchdog resolution */
#define M41T80_FEATURE_SQ_ALT BIT(4) /* RSx bits are in reg 4 */
static DEFINE_MUTEX(m41t80_rtc_mutex);
static const struct i2c_device_id m41t80_id[] = {
@ -90,27 +91,65 @@ struct m41t80_data {
struct rtc_device *rtc;
};
static irqreturn_t m41t80_handle_irq(int irq, void *dev_id)
{
struct i2c_client *client = dev_id;
struct m41t80_data *m41t80 = i2c_get_clientdata(client);
struct mutex *lock = &m41t80->rtc->ops_lock;
unsigned long events = 0;
int flags, flags_afe;
mutex_lock(lock);
flags_afe = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (flags_afe < 0) {
mutex_unlock(lock);
return IRQ_NONE;
}
flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (flags <= 0) {
mutex_unlock(lock);
return IRQ_NONE;
}
if (flags & M41T80_FLAGS_AF) {
flags &= ~M41T80_FLAGS_AF;
flags_afe &= ~M41T80_ALMON_AFE;
events |= RTC_AF;
}
if (events) {
rtc_update_irq(m41t80->rtc, 1, events);
i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS, flags);
i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
flags_afe);
}
mutex_unlock(lock);
return IRQ_HANDLED;
}
static int m41t80_get_datetime(struct i2c_client *client,
struct rtc_time *tm)
{
u8 buf[M41T80_DATETIME_REG_SIZE], dt_addr[1] = { M41T80_REG_SEC };
struct i2c_msg msgs[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = dt_addr,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
.buf = buf + M41T80_REG_SEC,
},
};
unsigned char buf[8];
int err, flags;
if (i2c_transfer(client->adapter, msgs, 2) < 0) {
dev_err(&client->dev, "read error\n");
flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (flags < 0)
return flags;
if (flags & M41T80_FLAGS_OF) {
dev_err(&client->dev, "Oscillator failure, data is invalid.\n");
return -EINVAL;
}
err = i2c_smbus_read_i2c_block_data(client, M41T80_REG_SSEC,
sizeof(buf), buf);
if (err < 0) {
dev_err(&client->dev, "Unable to read date\n");
return -EIO;
}
@ -129,70 +168,42 @@ static int m41t80_get_datetime(struct i2c_client *client,
/* Sets the given date and time to the real time clock. */
static int m41t80_set_datetime(struct i2c_client *client, struct rtc_time *tm)
{
u8 wbuf[1 + M41T80_DATETIME_REG_SIZE];
u8 *buf = &wbuf[1];
u8 dt_addr[1] = { M41T80_REG_SEC };
struct i2c_msg msgs_in[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = dt_addr,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = M41T80_DATETIME_REG_SIZE - M41T80_REG_SEC,
.buf = buf + M41T80_REG_SEC,
},
};
struct i2c_msg msgs[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1 + M41T80_DATETIME_REG_SIZE,
.buf = wbuf,
},
};
unsigned char buf[8];
int err, flags;
/* Read current reg values into buf[1..7] */
if (i2c_transfer(client->adapter, msgs_in, 2) < 0) {
dev_err(&client->dev, "read error\n");
return -EIO;
}
wbuf[0] = 0; /* offset into rtc's regs */
/* Merge time-data and register flags into buf[0..7] */
buf[M41T80_REG_SSEC] = 0;
buf[M41T80_REG_SEC] =
bin2bcd(tm->tm_sec) | (buf[M41T80_REG_SEC] & ~0x7f);
buf[M41T80_REG_MIN] =
bin2bcd(tm->tm_min) | (buf[M41T80_REG_MIN] & ~0x7f);
buf[M41T80_REG_HOUR] =
bin2bcd(tm->tm_hour) | (buf[M41T80_REG_HOUR] & ~0x3f);
buf[M41T80_REG_WDAY] =
(tm->tm_wday & 0x07) | (buf[M41T80_REG_WDAY] & ~0x07);
buf[M41T80_REG_DAY] =
bin2bcd(tm->tm_mday) | (buf[M41T80_REG_DAY] & ~0x3f);
buf[M41T80_REG_MON] =
bin2bcd(tm->tm_mon + 1) | (buf[M41T80_REG_MON] & ~0x1f);
/* assume 20YY not 19YY */
if (tm->tm_year < 100 || tm->tm_year > 199) {
dev_err(&client->dev, "Year must be between 2000 and 2099. It's %d.\n",
tm->tm_year + 1900);
if (tm->tm_year < 100 || tm->tm_year > 199)
return -EINVAL;
}
buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year % 100);
if (i2c_transfer(client->adapter, msgs, 1) != 1) {
dev_err(&client->dev, "write error\n");
buf[M41T80_REG_SSEC] = 0;
buf[M41T80_REG_SEC] = bin2bcd(tm->tm_sec);
buf[M41T80_REG_MIN] = bin2bcd(tm->tm_min);
buf[M41T80_REG_HOUR] = bin2bcd(tm->tm_hour);
buf[M41T80_REG_DAY] = bin2bcd(tm->tm_mday);
buf[M41T80_REG_MON] = bin2bcd(tm->tm_mon + 1);
buf[M41T80_REG_YEAR] = bin2bcd(tm->tm_year - 100);
buf[M41T80_REG_WDAY] = tm->tm_wday;
err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_SSEC,
sizeof(buf), buf);
if (err < 0) {
dev_err(&client->dev, "Unable to write to date registers\n");
return err;
}
/* Clear the OF bit of Flags Register */
flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (flags < 0)
return flags;
if (i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
flags & ~M41T80_FLAGS_OF)) {
dev_err(&client->dev, "Unable to write flags register\n");
return -EIO;
}
return 0;
return err;
}
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
{
struct i2c_client *client = to_i2c_client(dev);
@ -206,9 +217,6 @@ static int m41t80_rtc_proc(struct device *dev, struct seq_file *seq)
}
return 0;
}
#else
#define m41t80_rtc_proc NULL
#endif
static int m41t80_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
@ -220,19 +228,117 @@ static int m41t80_rtc_set_time(struct device *dev, struct rtc_time *tm)
return m41t80_set_datetime(to_i2c_client(dev), tm);
}
/*
* XXX - m41t80 alarm functionality is reported broken.
* until it is fixed, don't register alarm functions.
*/
static int m41t80_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
struct i2c_client *client = to_i2c_client(dev);
int flags, retval;
flags = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (flags < 0)
return flags;
if (enabled)
flags |= M41T80_ALMON_AFE;
else
flags &= ~M41T80_ALMON_AFE;
retval = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON, flags);
if (retval < 0) {
dev_info(dev, "Unable to enable alarm IRQ %d\n", retval);
return retval;
}
return 0;
}
static int m41t80_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct i2c_client *client = to_i2c_client(dev);
u8 alarmvals[5];
int ret, err;
alarmvals[0] = bin2bcd(alrm->time.tm_mon + 1);
alarmvals[1] = bin2bcd(alrm->time.tm_mday);
alarmvals[2] = bin2bcd(alrm->time.tm_hour);
alarmvals[3] = bin2bcd(alrm->time.tm_min);
alarmvals[4] = bin2bcd(alrm->time.tm_sec);
/* Clear AF and AFE flags */
ret = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (ret < 0)
return ret;
err = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
ret & ~(M41T80_ALMON_AFE));
if (err < 0) {
dev_err(dev, "Unable to clear AFE bit\n");
return err;
}
ret = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (ret < 0)
return ret;
err = i2c_smbus_write_byte_data(client, M41T80_REG_FLAGS,
ret & ~(M41T80_FLAGS_AF));
if (err < 0) {
dev_err(dev, "Unable to clear AF bit\n");
return err;
}
/* Write the alarm */
err = i2c_smbus_write_i2c_block_data(client, M41T80_REG_ALARM_MON,
5, alarmvals);
if (err)
return err;
/* Enable the alarm interrupt */
if (alrm->enabled) {
alarmvals[0] |= M41T80_ALMON_AFE;
err = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
alarmvals[0]);
if (err)
return err;
}
return 0;
}
static int m41t80_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct i2c_client *client = to_i2c_client(dev);
u8 alarmvals[5];
int flags, ret;
ret = i2c_smbus_read_i2c_block_data(client, M41T80_REG_ALARM_MON,
5, alarmvals);
if (ret != 5)
return ret < 0 ? ret : -EIO;
flags = i2c_smbus_read_byte_data(client, M41T80_REG_FLAGS);
if (flags < 0)
return flags;
alrm->time.tm_sec = bcd2bin(alarmvals[4] & 0x7f);
alrm->time.tm_min = bcd2bin(alarmvals[3] & 0x7f);
alrm->time.tm_hour = bcd2bin(alarmvals[2] & 0x3f);
alrm->time.tm_wday = -1;
alrm->time.tm_mday = bcd2bin(alarmvals[1] & 0x3f);
alrm->time.tm_mon = bcd2bin(alarmvals[0] & 0x3f);
alrm->time.tm_year = -1;
alrm->enabled = !!(alarmvals[0] & M41T80_ALMON_AFE);
alrm->pending = (flags & M41T80_FLAGS_AF) && alrm->enabled;
return 0;
}
static struct rtc_class_ops m41t80_rtc_ops = {
.read_time = m41t80_rtc_read_time,
.set_time = m41t80_rtc_set_time,
.proc = m41t80_rtc_proc,
};
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
static ssize_t m41t80_sysfs_show_flags(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t flags_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
int val;
@ -242,10 +348,10 @@ static ssize_t m41t80_sysfs_show_flags(struct device *dev,
return val;
return sprintf(buf, "%#x\n", val);
}
static DEVICE_ATTR(flags, S_IRUGO, m41t80_sysfs_show_flags, NULL);
static DEVICE_ATTR_RO(flags);
static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
struct device_attribute *attr, char *buf)
static ssize_t sqwfreq_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
@ -272,14 +378,19 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
}
return sprintf(buf, "%d\n", val);
}
static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
static ssize_t sqwfreq_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
int almon, sqw, reg_sqw, rc;
int val = simple_strtoul(buf, NULL, 0);
unsigned long val;
rc = kstrtoul(buf, 0, &val);
if (rc < 0)
return rc;
if (!(clientdata->features & M41T80_FEATURE_SQ))
return -EINVAL;
@ -308,7 +419,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
sqw = (sqw & 0x0f) | (val << 4);
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
almon & ~M41T80_ALMON_SQWE);
almon & ~M41T80_ALMON_SQWE);
if (rc < 0)
return rc;
@ -318,35 +429,24 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
return rc;
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
almon | M41T80_ALMON_SQWE);
if (rc <0)
almon | M41T80_ALMON_SQWE);
if (rc < 0)
return rc;
}
return count;
}
static DEVICE_ATTR(sqwfreq, S_IRUGO | S_IWUSR,
m41t80_sysfs_show_sqwfreq, m41t80_sysfs_set_sqwfreq);
static DEVICE_ATTR_RW(sqwfreq);
static struct attribute *attrs[] = {
&dev_attr_flags.attr,
&dev_attr_sqwfreq.attr,
NULL,
};
static struct attribute_group attr_group = {
.attrs = attrs,
};
static int m41t80_sysfs_register(struct device *dev)
{
return sysfs_create_group(&dev->kobj, &attr_group);
}
#else
static int m41t80_sysfs_register(struct device *dev)
{
return 0;
}
#endif
#ifdef CONFIG_RTC_DRV_M41T80_WDT
/*
*****************************************************************************
@ -394,7 +494,7 @@ static void wdt_ping(void)
/*
* WDS = 1 (0x80), mulitplier = WD_TIMO, resolution = 1s (0x02)
*/
i2c_data[1] = wdt_margin<<2 | 0x82;
i2c_data[1] = wdt_margin << 2 | 0x82;
/*
* M41T65 has three bits for watchdog resolution. Don't set bit 7, as
@ -636,49 +736,76 @@ static struct notifier_block wdt_notifier = {
*
*****************************************************************************
*/
static void m41t80_remove_sysfs_group(void *_dev)
{
struct device *dev = _dev;
sysfs_remove_group(&dev->kobj, &attr_group);
}
static int m41t80_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
int rc = 0;
struct rtc_device *rtc = NULL;
struct rtc_time tm;
struct m41t80_data *clientdata = NULL;
struct m41t80_data *m41t80_data = NULL;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C
| I2C_FUNC_SMBUS_BYTE_DATA))
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_err(&adapter->dev, "doesn't support I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_I2C_BLOCK\n");
return -ENODEV;
}
clientdata = devm_kzalloc(&client->dev, sizeof(*clientdata),
GFP_KERNEL);
if (!clientdata)
m41t80_data = devm_kzalloc(&client->dev, sizeof(*m41t80_data),
GFP_KERNEL);
if (!m41t80_data)
return -ENOMEM;
clientdata->features = id->driver_data;
i2c_set_clientdata(client, clientdata);
m41t80_data->features = id->driver_data;
i2c_set_clientdata(client, m41t80_data);
if (client->irq > 0) {
rc = devm_request_threaded_irq(&client->dev, client->irq,
NULL, m41t80_handle_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"m41t80", client);
if (rc) {
dev_warn(&client->dev, "unable to request IRQ, alarms disabled\n");
client->irq = 0;
} else {
m41t80_rtc_ops.read_alarm = m41t80_read_alarm;
m41t80_rtc_ops.set_alarm = m41t80_set_alarm;
m41t80_rtc_ops.alarm_irq_enable = m41t80_alarm_irq_enable;
/* Enable the wakealarm */
device_init_wakeup(&client->dev, true);
}
}
rtc = devm_rtc_device_register(&client->dev, client->name,
&m41t80_rtc_ops, THIS_MODULE);
&m41t80_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
clientdata->rtc = rtc;
m41t80_data->rtc = rtc;
/* Make sure HT (Halt Update) bit is cleared */
rc = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_HOUR);
if (rc >= 0 && rc & M41T80_ALHOUR_HT) {
if (clientdata->features & M41T80_FEATURE_HT) {
if (m41t80_data->features & M41T80_FEATURE_HT) {
m41t80_get_datetime(client, &tm);
dev_info(&client->dev, "HT bit was set!\n");
dev_info(&client->dev,
"Power Down at "
"%04i-%02i-%02i %02i:%02i:%02i\n",
"Power Down at %04i-%02i-%02i %02i:%02i:%02i\n",
tm.tm_year + 1900,
tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
tm.tm_min, tm.tm_sec);
}
rc = i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_HOUR,
rc & ~M41T80_ALHOUR_HT);
rc & ~M41T80_ALHOUR_HT);
}
if (rc < 0) {
@ -691,18 +818,30 @@ static int m41t80_probe(struct i2c_client *client,
if (rc >= 0 && rc & M41T80_SEC_ST)
rc = i2c_smbus_write_byte_data(client, M41T80_REG_SEC,
rc & ~M41T80_SEC_ST);
rc & ~M41T80_SEC_ST);
if (rc < 0) {
dev_err(&client->dev, "Can't clear ST bit\n");
return rc;
}
rc = m41t80_sysfs_register(&client->dev);
if (rc)
/* Export sysfs entries */
rc = sysfs_create_group(&(&client->dev)->kobj, &attr_group);
if (rc) {
dev_err(&client->dev, "Failed to create sysfs group: %d\n", rc);
return rc;
}
rc = devm_add_action(&client->dev, m41t80_remove_sysfs_group,
&client->dev);
if (rc) {
m41t80_remove_sysfs_group(&client->dev);
dev_err(&client->dev,
"Failed to add sysfs cleanup action: %d\n", rc);
return rc;
}
#ifdef CONFIG_RTC_DRV_M41T80_WDT
if (clientdata->features & M41T80_FEATURE_HT) {
if (m41t80_data->features & M41T80_FEATURE_HT) {
save_client = client;
rc = misc_register(&wdt_dev);
if (rc)

View File

@ -22,8 +22,6 @@
#include <linux/io.h>
#include <linux/err.h>
#define DRV_VERSION "1.0"
struct m48t35_rtc {
u8 pad[0x7ff8]; /* starts at 0x7ff8 */
u8 control;
@ -190,5 +188,4 @@ module_platform_driver(m48t35_platform_driver);
MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
MODULE_DESCRIPTION("M48T35 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:rtc-m48t35");

View File

@ -39,9 +39,6 @@
#define M48T86_REG_B_SET (1 << 7)
#define M48T86_REG_D_VRT (1 << 7)
#define DRV_VERSION "0.1"
static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
unsigned char reg;
@ -178,5 +175,4 @@ module_platform_driver(m48t86_rtc_platform_driver);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("M48T86 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:rtc-m48t86");

View File

@ -17,8 +17,6 @@
#include <linux/rtc.h>
#include <linux/delay.h>
#define DRV_VERSION "0.2"
/*
* register indices
*/
@ -218,8 +216,6 @@ max6900_probe(struct i2c_client *client, const struct i2c_device_id *id)
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rtc = devm_rtc_device_register(&client->dev, max6900_driver.driver.name,
&max6900_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
@ -249,4 +245,3 @@ module_i2c_driver(max6900_driver);
MODULE_DESCRIPTION("Maxim MAX6900 RTC driver");
MODULE_AUTHOR("Dale Farnsworth <dale@farnsworth.org>");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -250,18 +250,6 @@ static irqreturn_t mc13xxx_rtc_alarm_handler(int irq, void *dev)
return IRQ_HANDLED;
}
static irqreturn_t mc13xxx_rtc_update_handler(int irq, void *dev)
{
struct mc13xxx_rtc *priv = dev;
struct mc13xxx *mc13xxx = priv->mc13xxx;
rtc_update_irq(priv->rtc, 1, RTC_IRQF | RTC_UF);
mc13xxx_irq_ack(mc13xxx, irq);
return IRQ_HANDLED;
}
static const struct rtc_class_ops mc13xxx_rtc_ops = {
.read_time = mc13xxx_rtc_read_time,
.set_mmss64 = mc13xxx_rtc_set_mmss,
@ -307,11 +295,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
if (ret)
goto err_irq_request;
ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_1HZ,
mc13xxx_rtc_update_handler, DRIVER_NAME, priv);
if (ret)
goto err_irq_request;
ret = mc13xxx_irq_request_nounmask(mc13xxx, MC13XXX_IRQ_TODA,
mc13xxx_rtc_alarm_handler, DRIVER_NAME, priv);
if (ret)
@ -326,7 +309,6 @@ static int __init mc13xxx_rtc_probe(struct platform_device *pdev)
err_irq_request:
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_TODA, priv);
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_1HZ, priv);
mc13xxx_irq_free(mc13xxx, MC13XXX_IRQ_RTCRST, priv);
mc13xxx_unlock(mc13xxx);
@ -341,7 +323,6 @@ static int mc13xxx_rtc_remove(struct platform_device *pdev)
mc13xxx_lock(priv->mc13xxx);
mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_TODA, priv);
mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_1HZ, priv);
mc13xxx_irq_free(priv->mc13xxx, MC13XXX_IRQ_RTCRST, priv);
mc13xxx_unlock(priv->mc13xxx);

View File

@ -266,7 +266,7 @@ static int mrst_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
}
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
static int mrst_procfs(struct device *dev, struct seq_file *seq)
{

View File

@ -240,9 +240,6 @@ static irqreturn_t mxc_rtc_interrupt(int irq, void *dev_id)
mxc_rtc_irq_enable(&pdev->dev, RTC_ALM_BIT, 0);
}
if (status & RTC_1HZ_BIT)
events |= (RTC_UF | RTC_IRQF);
if (status & PIT_ALL_ON)
events |= (RTC_PF | RTC_IRQF);

View File

@ -46,8 +46,6 @@
#include <linux/module.h>
#include <linux/sysfs.h>
#define DRV_VERSION "0.6"
/* REGISTERS */
#define PCF2123_REG_CTRL1 (0x00) /* Control Register 1 */
#define PCF2123_REG_CTRL2 (0x01) /* Control Register 2 */
@ -395,7 +393,6 @@ static int pcf2123_probe(struct spi_device *spi)
}
}
dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
dev_info(&spi->dev, "spiclk %u KHz.\n",
(spi->max_speed_hz + 500) / 1000);
@ -474,4 +471,3 @@ module_spi_driver(pcf2123_driver);
MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -23,8 +23,6 @@
#include <linux/of.h>
#include <linux/err.h>
#define DRV_VERSION "0.4.4"
#define PCF8563_REG_ST1 0x00 /* status */
#define PCF8563_REG_ST2 0x01
#define PCF8563_BIT_AIE (1 << 1)
@ -535,7 +533,7 @@ static struct clk *pcf8563_clkout_register_clk(struct pcf8563 *pcf8563)
init.name = "pcf8563-clkout";
init.ops = &pcf8563_clkout_ops;
init.flags = CLK_IS_ROOT;
init.flags = 0;
init.parent_names = NULL;
init.num_parents = 0;
pcf8563->clkout_hw.init = &init;
@ -580,8 +578,6 @@ static int pcf8563_probe(struct i2c_client *client,
if (!pcf8563)
return -ENOMEM;
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
i2c_set_clientdata(client, pcf8563);
pcf8563->client = client;
device_set_wakeup_capable(&client->dev, 1);
@ -662,4 +658,3 @@ module_i2c_driver(pcf8563_driver);
MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("Philips PCF8563/Epson RTC8564 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -50,7 +50,6 @@
#include <linux/io.h>
#define DRV_NAME "rs5c313"
#define DRV_VERSION "1.13"
#ifdef CONFIG_SH_LANDISK
/*****************************************************/
@ -407,7 +406,6 @@ static void __exit rs5c313_rtc_exit(void)
module_init(rs5c313_rtc_init);
module_exit(rs5c313_rtc_exit);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
MODULE_LICENSE("GPL");

View File

@ -25,8 +25,6 @@
#include <linux/spi/spi.h>
#include <linux/module.h>
#define DRV_VERSION "0.2"
#define RS5C348_REG_SECS 0
#define RS5C348_REG_MINS 1
#define RS5C348_REG_HOURS 2
@ -171,7 +169,6 @@ static int rs5c348_probe(struct spi_device *spi)
goto kfree_exit;
}
dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
dev_info(&spi->dev, "spiclk %u KHz.\n",
(spi->max_speed_hz + 500) / 1000);
@ -230,5 +227,4 @@ module_spi_driver(rs5c348_driver);
MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("spi:rtc-rs5c348");

View File

@ -16,9 +16,6 @@
#include <linux/slab.h>
#include <linux/module.h>
#define DRV_VERSION "0.6"
/*
* Ricoh has a family of I2C based RTCs, which differ only slightly from
* each other. Differences center on pinout (e.g. how many interrupts,
@ -240,11 +237,11 @@ static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm)
return 0;
}
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
#define NEED_TRIM
#endif
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)
#define NEED_TRIM
#endif
@ -412,7 +409,7 @@ static int rs5c_set_alarm(struct device *dev, struct rtc_wkalrm *t)
return 0;
}
#if defined(CONFIG_RTC_INTF_PROC) || defined(CONFIG_RTC_INTF_PROC_MODULE)
#if IS_ENABLED(CONFIG_RTC_INTF_PROC)
static int rs5c372_rtc_proc(struct device *dev, struct seq_file *seq)
{
@ -441,7 +438,7 @@ static const struct rtc_class_ops rs5c372_rtc_ops = {
.alarm_irq_enable = rs5c_rtc_alarm_irq_enable,
};
#if defined(CONFIG_RTC_INTF_SYSFS) || defined(CONFIG_RTC_INTF_SYSFS_MODULE)
#if IS_ENABLED(CONFIG_RTC_INTF_SYSFS)
static ssize_t rs5c372_sysfs_show_trim(struct device *dev,
struct device_attribute *attr, char *buf)
@ -509,9 +506,9 @@ static int rs5c_oscillator_setup(struct rs5c372 *rs5c372)
int addr, i, ret = 0;
if (rs5c372->type == rtc_r2025sd) {
if (!(rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST))
if (rs5c372->regs[RS5C_REG_CTRL2] & R2025_CTRL2_XST)
return ret;
rs5c372->regs[RS5C_REG_CTRL2] &= ~R2025_CTRL2_XST;
rs5c372->regs[RS5C_REG_CTRL2] |= R2025_CTRL2_XST;
} else {
if (!(rs5c372->regs[RS5C_REG_CTRL2] & RS5C_CTRL2_XSTP))
return ret;
@ -640,7 +637,7 @@ static int rs5c372_probe(struct i2c_client *client,
if (rs5c372_get_datetime(client, &tm) < 0)
dev_warn(&client->dev, "clock needs to be set\n");
dev_info(&client->dev, "%s found, %s, driver version " DRV_VERSION "\n",
dev_info(&client->dev, "%s found, %s\n",
({ char *s; switch (rs5c372->type) {
case rtc_r2025sd: s = "r2025sd"; break;
case rtc_r2221tl: s = "r2221tl"; break;
@ -696,4 +693,3 @@ MODULE_AUTHOR(
"Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("Ricoh RS5C372 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -1,5 +1,5 @@
/*
* Micro Crystal RV-3029 rtc class driver
* Micro Crystal RV-3029 / RV-3049 rtc class driver
*
* Author: Gregory Hermant <gregory.hermant@calao-systems.com>
* Michael Buesch <m@bues.ch>
@ -14,13 +14,14 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/bcd.h>
#include <linux/rtc.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/regmap.h>
/* Register map */
/* control section */
@ -75,6 +76,7 @@
#define RV3029_A_DW 0x14
#define RV3029_A_MO 0x15
#define RV3029_A_YR 0x16
#define RV3029_A_AE_X BIT(7)
#define RV3029_ALARM_SECTION_LEN 0x07
/* timer section */
@ -116,85 +118,84 @@
#define RV3029_USR2_RAM_PAGE 0x3C
#define RV3029_USR2_SECTION_LEN 0x04
static int
rv3029_i2c_read_regs(struct i2c_client *client, u8 reg, u8 *buf,
unsigned len)
struct rv3029_data {
struct device *dev;
struct rtc_device *rtc;
struct regmap *regmap;
int irq;
};
static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
unsigned int len)
{
int ret;
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
(reg + len > RV3029_USR1_RAM_PAGE + 8))
(reg + len > RV3029_USR1_RAM_PAGE + 8))
return -EINVAL;
ret = i2c_smbus_read_i2c_block_data(client, reg, len, buf);
if (ret < 0)
return ret;
if (ret < len)
return -EIO;
return 0;
return regmap_bulk_read(rv3029->regmap, reg, buf, len);
}
static int
rv3029_i2c_write_regs(struct i2c_client *client, u8 reg, u8 const buf[],
unsigned len)
static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
unsigned int len)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
(reg + len > RV3029_USR1_RAM_PAGE + 8))
(reg + len > RV3029_USR1_RAM_PAGE + 8))
return -EINVAL;
return i2c_smbus_write_i2c_block_data(client, reg, len, buf);
return regmap_bulk_write(rv3029->regmap, reg, buf, len);
}
static int
rv3029_i2c_update_bits(struct i2c_client *client, u8 reg, u8 mask, u8 set)
static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
{
u8 buf;
int ret;
ret = rv3029_i2c_read_regs(client, reg, &buf, 1);
ret = rv3029_read_regs(dev, reg, &buf, 1);
if (ret < 0)
return ret;
buf &= ~mask;
buf |= set & mask;
ret = rv3029_i2c_write_regs(client, reg, &buf, 1);
ret = rv3029_write_regs(dev, reg, &buf, 1);
if (ret < 0)
return ret;
return 0;
}
static int
rv3029_i2c_get_sr(struct i2c_client *client, u8 *buf)
static int rv3029_get_sr(struct device *dev, u8 *buf)
{
int ret = rv3029_i2c_read_regs(client, RV3029_STATUS, buf, 1);
int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
if (ret < 0)
return -EIO;
dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
return 0;
}
static int
rv3029_i2c_set_sr(struct i2c_client *client, u8 val)
static int rv3029_set_sr(struct device *dev, u8 val)
{
u8 buf[1];
int sr;
buf[0] = val;
sr = rv3029_i2c_write_regs(client, RV3029_STATUS, buf, 1);
dev_dbg(&client->dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
if (sr < 0)
return -EIO;
return 0;
}
static int rv3029_eeprom_busywait(struct i2c_client *client)
static int rv3029_eeprom_busywait(struct device *dev)
{
int i, ret;
u8 sr;
for (i = 100; i > 0; i--) {
ret = rv3029_i2c_get_sr(client, &sr);
ret = rv3029_get_sr(dev, &sr);
if (ret < 0)
break;
if (!(sr & RV3029_STATUS_EEBUSY))
@ -202,28 +203,28 @@ static int rv3029_eeprom_busywait(struct i2c_client *client)
usleep_range(1000, 10000);
}
if (i <= 0) {
dev_err(&client->dev, "EEPROM busy wait timeout.\n");
dev_err(dev, "EEPROM busy wait timeout.\n");
return -ETIMEDOUT;
}
return ret;
}
static int rv3029_eeprom_exit(struct i2c_client *client)
static int rv3029_eeprom_exit(struct device *dev)
{
/* Re-enable eeprom refresh */
return rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
RV3029_ONOFF_CTRL_EERE,
RV3029_ONOFF_CTRL_EERE);
return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
RV3029_ONOFF_CTRL_EERE,
RV3029_ONOFF_CTRL_EERE);
}
static int rv3029_eeprom_enter(struct i2c_client *client)
static int rv3029_eeprom_enter(struct device *dev)
{
int ret;
u8 sr;
/* Check whether we are in the allowed voltage range. */
ret = rv3029_i2c_get_sr(client, &sr);
ret = rv3029_get_sr(dev, &sr);
if (ret < 0)
return ret;
if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
@ -232,129 +233,168 @@ static int rv3029_eeprom_enter(struct i2c_client *client)
*/
sr &= ~RV3029_STATUS_VLOW1;
sr &= ~RV3029_STATUS_VLOW2;
ret = rv3029_i2c_set_sr(client, sr);
ret = rv3029_set_sr(dev, sr);
if (ret < 0)
return ret;
usleep_range(1000, 10000);
ret = rv3029_i2c_get_sr(client, &sr);
ret = rv3029_get_sr(dev, &sr);
if (ret < 0)
return ret;
if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
dev_err(&client->dev,
dev_err(dev,
"Supply voltage is too low to safely access the EEPROM.\n");
return -ENODEV;
}
}
/* Disable eeprom refresh. */
ret = rv3029_i2c_update_bits(client, RV3029_ONOFF_CTRL,
RV3029_ONOFF_CTRL_EERE, 0);
ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
0);
if (ret < 0)
return ret;
/* Wait for any previous eeprom accesses to finish. */
ret = rv3029_eeprom_busywait(client);
ret = rv3029_eeprom_busywait(dev);
if (ret < 0)
rv3029_eeprom_exit(client);
rv3029_eeprom_exit(dev);
return ret;
}
static int rv3029_eeprom_read(struct i2c_client *client, u8 reg,
static int rv3029_eeprom_read(struct device *dev, u8 reg,
u8 buf[], size_t len)
{
int ret, err;
err = rv3029_eeprom_enter(client);
err = rv3029_eeprom_enter(dev);
if (err < 0)
return err;
ret = rv3029_i2c_read_regs(client, reg, buf, len);
ret = rv3029_read_regs(dev, reg, buf, len);
err = rv3029_eeprom_exit(client);
err = rv3029_eeprom_exit(dev);
if (err < 0)
return err;
return ret;
}
static int rv3029_eeprom_write(struct i2c_client *client, u8 reg,
static int rv3029_eeprom_write(struct device *dev, u8 reg,
u8 const buf[], size_t len)
{
int ret, err;
size_t i;
u8 tmp;
err = rv3029_eeprom_enter(client);
err = rv3029_eeprom_enter(dev);
if (err < 0)
return err;
for (i = 0; i < len; i++, reg++) {
ret = rv3029_i2c_read_regs(client, reg, &tmp, 1);
ret = rv3029_read_regs(dev, reg, &tmp, 1);
if (ret < 0)
break;
if (tmp != buf[i]) {
ret = rv3029_i2c_write_regs(client, reg, &buf[i], 1);
ret = rv3029_write_regs(dev, reg, &buf[i], 1);
if (ret < 0)
break;
}
ret = rv3029_eeprom_busywait(client);
ret = rv3029_eeprom_busywait(dev);
if (ret < 0)
break;
}
err = rv3029_eeprom_exit(client);
err = rv3029_eeprom_exit(dev);
if (err < 0)
return err;
return ret;
}
static int rv3029_eeprom_update_bits(struct i2c_client *client,
static int rv3029_eeprom_update_bits(struct device *dev,
u8 reg, u8 mask, u8 set)
{
u8 buf;
int ret;
ret = rv3029_eeprom_read(client, reg, &buf, 1);
ret = rv3029_eeprom_read(dev, reg, &buf, 1);
if (ret < 0)
return ret;
buf &= ~mask;
buf |= set & mask;
ret = rv3029_eeprom_write(client, reg, &buf, 1);
ret = rv3029_eeprom_write(dev, reg, &buf, 1);
if (ret < 0)
return ret;
return 0;
}
static int
rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
{
struct device *dev = dev_id;
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct mutex *lock = &rv3029->rtc->ops_lock;
unsigned long events = 0;
u8 flags, controls;
int ret;
mutex_lock(lock);
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret) {
dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
mutex_unlock(lock);
return IRQ_NONE;
}
ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
if (ret) {
dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
mutex_unlock(lock);
return IRQ_NONE;
}
if (flags & RV3029_IRQ_FLAGS_AF) {
flags &= ~RV3029_IRQ_FLAGS_AF;
controls &= ~RV3029_IRQ_CTRL_AIE;
events |= RTC_AF;
}
if (events) {
rtc_update_irq(rv3029->rtc, 1, events);
rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
}
mutex_unlock(lock);
return IRQ_HANDLED;
}
static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
{
u8 buf[1];
int ret;
u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
ret = rv3029_i2c_get_sr(client, buf);
ret = rv3029_get_sr(dev, buf);
if (ret < 0) {
dev_err(&client->dev, "%s: reading SR failed\n", __func__);
dev_err(dev, "%s: reading SR failed\n", __func__);
return -EIO;
}
ret = rv3029_i2c_read_regs(client, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
if (ret < 0) {
dev_err(&client->dev, "%s: reading RTC section failed\n",
__func__);
dev_err(dev, "%s: reading RTC section failed\n", __func__);
return ret;
}
tm->tm_sec = bcd2bin(regs[RV3029_W_SEC-RV3029_W_SEC]);
tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES-RV3029_W_SEC]);
tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
/* HR field has a more complex interpretation */
{
const u8 _hr = regs[RV3029_W_HOURS-RV3029_W_SEC];
const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
if (_hr & RV3029_REG_HR_12_24) {
/* 12h format */
@ -365,77 +405,86 @@ rv3029_i2c_read_time(struct i2c_client *client, struct rtc_time *tm)
tm->tm_hour = bcd2bin(_hr & 0x3f);
}
tm->tm_mday = bcd2bin(regs[RV3029_W_DATE-RV3029_W_SEC]);
tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS-RV3029_W_SEC]) - 1;
tm->tm_year = bcd2bin(regs[RV3029_W_YEARS-RV3029_W_SEC]) + 100;
tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS-RV3029_W_SEC]) - 1;
tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 100;
tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
return 0;
}
static int rv3029_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
return rv3029_i2c_read_time(to_i2c_client(dev), tm);
}
static int
rv3029_i2c_read_alarm(struct i2c_client *client, struct rtc_wkalrm *alarm)
static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct rtc_time *const tm = &alarm->time;
int ret;
u8 regs[8];
u8 regs[8], controls, flags;
ret = rv3029_i2c_get_sr(client, regs);
ret = rv3029_get_sr(dev, regs);
if (ret < 0) {
dev_err(&client->dev, "%s: reading SR failed\n", __func__);
dev_err(dev, "%s: reading SR failed\n", __func__);
return -EIO;
}
ret = rv3029_i2c_read_regs(client, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
if (ret < 0) {
dev_err(&client->dev, "%s: reading alarm section failed\n",
__func__);
dev_err(dev, "%s: reading alarm section failed\n", __func__);
return ret;
}
tm->tm_sec = bcd2bin(regs[RV3029_A_SC-RV3029_A_SC] & 0x7f);
tm->tm_min = bcd2bin(regs[RV3029_A_MN-RV3029_A_SC] & 0x7f);
tm->tm_hour = bcd2bin(regs[RV3029_A_HR-RV3029_A_SC] & 0x3f);
tm->tm_mday = bcd2bin(regs[RV3029_A_DT-RV3029_A_SC] & 0x3f);
tm->tm_mon = bcd2bin(regs[RV3029_A_MO-RV3029_A_SC] & 0x1f) - 1;
tm->tm_year = bcd2bin(regs[RV3029_A_YR-RV3029_A_SC] & 0x7f) + 100;
tm->tm_wday = bcd2bin(regs[RV3029_A_DW-RV3029_A_SC] & 0x07) - 1;
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret) {
dev_err(dev, "Read IRQ Control Register error %d\n", ret);
return ret;
}
ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
if (ret < 0) {
dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
return ret;
}
tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
tm->tm_hour = bcd2bin(regs[RV3029_A_HR - RV3029_A_SC] & 0x3f);
tm->tm_mday = bcd2bin(regs[RV3029_A_DT - RV3029_A_SC] & 0x3f);
tm->tm_mon = bcd2bin(regs[RV3029_A_MO - RV3029_A_SC] & 0x1f) - 1;
tm->tm_year = bcd2bin(regs[RV3029_A_YR - RV3029_A_SC] & 0x7f) + 100;
tm->tm_wday = bcd2bin(regs[RV3029_A_DW - RV3029_A_SC] & 0x07) - 1;
alarm->enabled = !!(controls & RV3029_IRQ_CTRL_AIE);
alarm->pending = (flags & RV3029_IRQ_FLAGS_AF) && alarm->enabled;
return 0;
}
static int
rv3029_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
return rv3029_i2c_read_alarm(to_i2c_client(dev), alarm);
}
static int rv3029_rtc_i2c_alarm_set_irq(struct i2c_client *client,
int enable)
static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
{
int ret;
u8 controls;
ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret < 0) {
dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
return ret;
}
/* enable/disable AIE irq */
ret = rv3029_i2c_update_bits(client, RV3029_IRQ_CTRL,
RV3029_IRQ_CTRL_AIE,
(enable ? RV3029_IRQ_CTRL_AIE : 0));
if (enable)
controls |= RV3029_IRQ_CTRL_AIE;
else
controls &= ~RV3029_IRQ_CTRL_AIE;
ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
if (ret < 0) {
dev_err(&client->dev, "can't update INT reg\n");
dev_err(dev, "can't update INT reg\n");
return ret;
}
return 0;
}
static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
struct rtc_wkalrm *alarm)
static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
struct rtc_time *const tm = &alarm->time;
int ret;
@ -449,57 +498,48 @@ static int rv3029_rtc_i2c_set_alarm(struct i2c_client *client,
if (tm->tm_year < 100)
return -EINVAL;
ret = rv3029_i2c_get_sr(client, regs);
ret = rv3029_get_sr(dev, regs);
if (ret < 0) {
dev_err(&client->dev, "%s: reading SR failed\n", __func__);
dev_err(dev, "%s: reading SR failed\n", __func__);
return -EIO;
}
regs[RV3029_A_SC-RV3029_A_SC] = bin2bcd(tm->tm_sec & 0x7f);
regs[RV3029_A_MN-RV3029_A_SC] = bin2bcd(tm->tm_min & 0x7f);
regs[RV3029_A_HR-RV3029_A_SC] = bin2bcd(tm->tm_hour & 0x3f);
regs[RV3029_A_DT-RV3029_A_SC] = bin2bcd(tm->tm_mday & 0x3f);
regs[RV3029_A_MO-RV3029_A_SC] = bin2bcd((tm->tm_mon & 0x1f) - 1);
regs[RV3029_A_DW-RV3029_A_SC] = bin2bcd((tm->tm_wday & 7) - 1);
regs[RV3029_A_YR-RV3029_A_SC] = bin2bcd((tm->tm_year & 0x7f) - 100);
ret = rv3029_i2c_write_regs(client, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
/* Activate all the alarms with AE_x bit */
regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
regs[RV3029_A_HR - RV3029_A_SC] = (bin2bcd(tm->tm_hour) & 0x3f)
| RV3029_A_AE_X;
regs[RV3029_A_DT - RV3029_A_SC] = (bin2bcd(tm->tm_mday) & 0x3f)
| RV3029_A_AE_X;
regs[RV3029_A_MO - RV3029_A_SC] = (bin2bcd(tm->tm_mon + 1) & 0x1f)
| RV3029_A_AE_X;
regs[RV3029_A_DW - RV3029_A_SC] = (bin2bcd(tm->tm_wday + 1) & 0x7)
| RV3029_A_AE_X;
regs[RV3029_A_YR - RV3029_A_SC] = (bin2bcd(tm->tm_year - 100))
| RV3029_A_AE_X;
/* Write the alarm */
ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
RV3029_ALARM_SECTION_LEN);
if (ret < 0)
return ret;
if (alarm->enabled) {
/* clear AF flag */
ret = rv3029_i2c_update_bits(client, RV3029_IRQ_FLAGS,
RV3029_IRQ_FLAGS_AF, 0);
if (ret < 0) {
dev_err(&client->dev, "can't clear alarm flag\n");
return ret;
}
/* enable AIE irq */
ret = rv3029_rtc_i2c_alarm_set_irq(client, 1);
ret = rv3029_alarm_irq_enable(dev, 1);
if (ret)
return ret;
dev_dbg(&client->dev, "alarm IRQ armed\n");
} else {
/* disable AIE irq */
ret = rv3029_rtc_i2c_alarm_set_irq(client, 0);
ret = rv3029_alarm_irq_enable(dev, 0);
if (ret)
return ret;
dev_dbg(&client->dev, "alarm IRQ disabled\n");
}
return 0;
}
static int rv3029_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
{
return rv3029_rtc_i2c_set_alarm(to_i2c_client(dev), alarm);
}
static int
rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
{
u8 regs[8];
int ret;
@ -512,39 +552,34 @@ rv3029_i2c_set_time(struct i2c_client *client, struct rtc_time const *tm)
if (tm->tm_year < 100)
return -EINVAL;
regs[RV3029_W_SEC-RV3029_W_SEC] = bin2bcd(tm->tm_sec);
regs[RV3029_W_MINUTES-RV3029_W_SEC] = bin2bcd(tm->tm_min);
regs[RV3029_W_HOURS-RV3029_W_SEC] = bin2bcd(tm->tm_hour);
regs[RV3029_W_DATE-RV3029_W_SEC] = bin2bcd(tm->tm_mday);
regs[RV3029_W_MONTHS-RV3029_W_SEC] = bin2bcd(tm->tm_mon+1);
regs[RV3029_W_DAYS-RV3029_W_SEC] = bin2bcd((tm->tm_wday & 7)+1);
regs[RV3029_W_YEARS-RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday);
regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1);
regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
ret = rv3029_i2c_write_regs(client, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
RV3029_WATCH_SECTION_LEN);
if (ret < 0)
return ret;
ret = rv3029_i2c_get_sr(client, regs);
ret = rv3029_get_sr(dev, regs);
if (ret < 0) {
dev_err(&client->dev, "%s: reading SR failed\n", __func__);
dev_err(dev, "%s: reading SR failed\n", __func__);
return ret;
}
/* clear PON bit */
ret = rv3029_i2c_set_sr(client, (regs[0] & ~RV3029_STATUS_PON));
ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
if (ret < 0) {
dev_err(&client->dev, "%s: reading SR failed\n", __func__);
dev_err(dev, "%s: reading SR failed\n", __func__);
return ret;
}
return 0;
}
static int rv3029_rtc_set_time(struct device *dev, struct rtc_time *tm)
{
return rv3029_i2c_set_time(to_i2c_client(dev), tm);
}
static const struct rv3029_trickle_tab_elem {
u32 r; /* resistance in ohms */
u8 conf; /* trickle config bits */
@ -602,9 +637,9 @@ static const struct rv3029_trickle_tab_elem {
},
};
static void rv3029_trickle_config(struct i2c_client *client)
static void rv3029_trickle_config(struct device *dev)
{
struct device_node *of_node = client->dev.of_node;
struct device_node *of_node = dev->of_node;
const struct rv3029_trickle_tab_elem *elem;
int i, err;
u32 ohms;
@ -626,27 +661,25 @@ static void rv3029_trickle_config(struct i2c_client *client)
break;
}
trickle_set_bits = elem->conf;
dev_info(&client->dev,
dev_info(dev,
"Trickle charger enabled at %d ohms resistance.\n",
elem->r);
}
err = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
RV3029_TRICKLE_MASK,
trickle_set_bits);
if (err < 0) {
dev_err(&client->dev,
"Failed to update trickle charger config\n");
}
if (err < 0)
dev_err(dev, "Failed to update trickle charger config\n");
}
#ifdef CONFIG_RTC_DRV_RV3029_HWMON
static int rv3029_read_temp(struct i2c_client *client, int *temp_mC)
static int rv3029_read_temp(struct device *dev, int *temp_mC)
{
int ret;
u8 temp;
ret = rv3029_i2c_read_regs(client, RV3029_TEMP_PAGE, &temp, 1);
ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
if (ret < 0)
return ret;
@ -659,10 +692,9 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct i2c_client *client = dev_get_drvdata(dev);
int ret, temp_mC;
ret = rv3029_read_temp(client, &temp_mC);
ret = rv3029_read_temp(dev, &temp_mC);
if (ret < 0)
return ret;
@ -674,7 +706,6 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
const char *buf,
size_t count)
{
struct i2c_client *client = dev_get_drvdata(dev);
unsigned long interval_ms;
int ret;
u8 th_set_bits = 0;
@ -688,7 +719,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
if (interval_ms >= 16000)
th_set_bits |= RV3029_EECTRL_THP;
}
ret = rv3029_eeprom_update_bits(client, RV3029_CONTROL_E2P_EECTRL,
ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
RV3029_EECTRL_THE | RV3029_EECTRL_THP,
th_set_bits);
if (ret < 0)
@ -701,11 +732,10 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct i2c_client *client = dev_get_drvdata(dev);
int ret, interval_ms;
u8 eectrl;
ret = rv3029_eeprom_read(client, RV3029_CONTROL_E2P_EECTRL,
ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
&eectrl, 1);
if (ret < 0)
return ret;
@ -735,34 +765,109 @@ static struct attribute *rv3029_hwmon_attrs[] = {
};
ATTRIBUTE_GROUPS(rv3029_hwmon);
static void rv3029_hwmon_register(struct i2c_client *client)
static void rv3029_hwmon_register(struct device *dev, const char *name)
{
struct rv3029_data *rv3029 = dev_get_drvdata(dev);
struct device *hwmon_dev;
hwmon_dev = devm_hwmon_device_register_with_groups(
&client->dev, client->name, client, rv3029_hwmon_groups);
hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, rv3029,
rv3029_hwmon_groups);
if (IS_ERR(hwmon_dev)) {
dev_warn(&client->dev,
"unable to register hwmon device %ld\n",
PTR_ERR(hwmon_dev));
dev_warn(dev, "unable to register hwmon device %ld\n",
PTR_ERR(hwmon_dev));
}
}
#else /* CONFIG_RTC_DRV_RV3029_HWMON */
static void rv3029_hwmon_register(struct i2c_client *client)
static void rv3029_hwmon_register(struct device *dev, const char *name)
{
}
#endif /* CONFIG_RTC_DRV_RV3029_HWMON */
static const struct rtc_class_ops rv3029_rtc_ops = {
.read_time = rv3029_rtc_read_time,
.set_time = rv3029_rtc_set_time,
.read_alarm = rv3029_rtc_read_alarm,
.set_alarm = rv3029_rtc_set_alarm,
static struct rtc_class_ops rv3029_rtc_ops = {
.read_time = rv3029_read_time,
.set_time = rv3029_set_time,
};
static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
const char *name)
{
struct rv3029_data *rv3029;
int rc = 0;
u8 buf[1];
rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
if (!rv3029)
return -ENOMEM;
rv3029->regmap = regmap;
rv3029->irq = irq;
rv3029->dev = dev;
dev_set_drvdata(dev, rv3029);
rc = rv3029_get_sr(dev, buf);
if (rc < 0) {
dev_err(dev, "reading status failed\n");
return rc;
}
rv3029_trickle_config(dev);
rv3029_hwmon_register(dev, name);
rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
THIS_MODULE);
if (IS_ERR(rv3029->rtc)) {
dev_err(dev, "unable to register the class device\n");
return PTR_ERR(rv3029->rtc);
}
if (rv3029->irq > 0) {
rc = devm_request_threaded_irq(dev, rv3029->irq,
NULL, rv3029_handle_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"rv3029", dev);
if (rc) {
dev_warn(dev, "unable to request IRQ, alarms disabled\n");
rv3029->irq = 0;
} else {
rv3029_rtc_ops.read_alarm = rv3029_read_alarm;
rv3029_rtc_ops.set_alarm = rv3029_set_alarm;
rv3029_rtc_ops.alarm_irq_enable = rv3029_alarm_irq_enable;
}
}
return 0;
}
#if IS_ENABLED(CONFIG_I2C)
static int rv3029_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regmap *regmap;
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
};
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_BYTE)) {
dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
return -ENODEV;
}
regmap = devm_regmap_init_i2c(client, &config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
__func__, PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return rv3029_probe(&client->dev, regmap, client->irq, client->name);
}
static struct i2c_device_id rv3029_id[] = {
{ "rv3029", 0 },
{ "rv3029c2", 0 },
@ -770,47 +875,116 @@ static struct i2c_device_id rv3029_id[] = {
};
MODULE_DEVICE_TABLE(i2c, rv3029_id);
static int rv3029_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct rtc_device *rtc;
int rc = 0;
u8 buf[1];
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_EMUL))
return -ENODEV;
rc = rv3029_i2c_get_sr(client, buf);
if (rc < 0) {
dev_err(&client->dev, "reading status failed\n");
return rc;
}
rv3029_trickle_config(client);
rv3029_hwmon_register(client);
rtc = devm_rtc_device_register(&client->dev, client->name,
&rv3029_rtc_ops, THIS_MODULE);
if (IS_ERR(rtc))
return PTR_ERR(rtc);
i2c_set_clientdata(client, rtc);
return 0;
}
static struct i2c_driver rv3029_driver = {
.driver = {
.name = "rtc-rv3029c2",
},
.probe = rv3029_probe,
.probe = rv3029_i2c_probe,
.id_table = rv3029_id,
};
module_i2c_driver(rv3029_driver);
static int rv3029_register_driver(void)
{
return i2c_add_driver(&rv3029_driver);
}
static void rv3029_unregister_driver(void)
{
i2c_del_driver(&rv3029_driver);
}
#else
static int rv3029_register_driver(void)
{
return 0;
}
static void rv3029_unregister_driver(void)
{
}
#endif
#if IS_ENABLED(CONFIG_SPI_MASTER)
static int rv3049_probe(struct spi_device *spi)
{
static const struct regmap_config config = {
.reg_bits = 8,
.val_bits = 8,
};
struct regmap *regmap;
regmap = devm_regmap_init_spi(spi, &config);
if (IS_ERR(regmap)) {
dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
__func__, PTR_ERR(regmap));
return PTR_ERR(regmap);
}
return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
}
static struct spi_driver rv3049_driver = {
.driver = {
.name = "rv3049",
},
.probe = rv3049_probe,
};
static int rv3049_register_driver(void)
{
return spi_register_driver(&rv3049_driver);
}
static void rv3049_unregister_driver(void)
{
spi_unregister_driver(&rv3049_driver);
}
#else
static int rv3049_register_driver(void)
{
return 0;
}
static void rv3049_unregister_driver(void)
{
}
#endif
static int __init rv30x9_init(void)
{
int ret;
ret = rv3029_register_driver();
if (ret) {
pr_err("Failed to register rv3029 driver: %d\n", ret);
return ret;
}
ret = rv3049_register_driver();
if (ret) {
pr_err("Failed to register rv3049 driver: %d\n", ret);
rv3029_unregister_driver();
}
return ret;
}
module_init(rv30x9_init)
static void __exit rv30x9_exit(void)
{
rv3049_unregister_driver();
rv3029_unregister_driver();
}
module_exit(rv30x9_exit)
MODULE_AUTHOR("Gregory Hermant <gregory.hermant@calao-systems.com>");
MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
MODULE_DESCRIPTION("Micro Crystal RV3029 RTC driver");
MODULE_DESCRIPTION("Micro Crystal RV3029/RV3049 RTC driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:rv3049");

View File

@ -18,8 +18,6 @@
#include <linux/rtc.h>
#include <linux/log2.h>
#define DRV_VERSION "0.1"
#define RX8581_REG_SC 0x00 /* Second in BCD */
#define RX8581_REG_MN 0x01 /* Minute in BCD */
#define RX8581_REG_HR 0x02 /* Hour in BCD */
@ -292,8 +290,6 @@ static int rx8581_probe(struct i2c_client *client,
rx8581->write_block_data = rx8581_write_block_data;
}
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rx8581->rtc = devm_rtc_device_register(&client->dev,
rx8581_driver.driver.name, &rx8581_rtc_ops, THIS_MODULE);
@ -325,4 +321,3 @@ module_i2c_driver(rx8581_driver);
MODULE_AUTHOR("Martyn Welch <martyn.welch@ge.com>");
MODULE_DESCRIPTION("Epson RX-8581 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -30,7 +30,6 @@
#include <asm/rtc.h>
#define DRV_NAME "sh-rtc"
#define DRV_VERSION "0.2.3"
#define RTC_REG(r) ((r) * rtc_reg_size)
@ -790,7 +789,6 @@ static struct platform_driver sh_rtc_platform_driver = {
module_platform_driver_probe(sh_rtc_platform_driver, sh_rtc_probe);
MODULE_DESCRIPTION("SuperH on-chip RTC driver");
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, "
"Jamie Lenehan <lenehan@twibble.org>, "
"Angelo Castello <angelo.castello@st.com>");

View File

@ -322,7 +322,7 @@ static int snvs_rtc_suspend(struct device *dev)
struct snvs_rtc_data *data = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
enable_irq_wake(data->irq);
return enable_irq_wake(data->irq);
return 0;
}

View File

@ -23,8 +23,6 @@
#include <linux/io.h>
#include <linux/module.h>
#define DRV_VERSION "0.1"
#define RTC_REG_SIZE 0x20000
#define RTC_OFFSET 0x1fff0
@ -366,4 +364,3 @@ module_platform_driver(stk17ta8_rtc_driver);
MODULE_AUTHOR("Thomas Hommel <thomas.hommel@ge.com>");
MODULE_DESCRIPTION("Simtek STK17TA8 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -107,14 +107,19 @@ static struct stmp3xxx_wdt_pdata wdt_pdata = {
static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)
{
int rc = -1;
struct platform_device *wdt_pdev =
platform_device_alloc("stmp3xxx_rtc_wdt", rtc_pdev->id);
if (wdt_pdev) {
wdt_pdev->dev.parent = &rtc_pdev->dev;
wdt_pdev->dev.platform_data = &wdt_pdata;
platform_device_add(wdt_pdev);
rc = platform_device_add(wdt_pdev);
}
if (rc)
dev_err(&rtc_pdev->dev,
"failed to register stmp3xxx_rtc_wdt\n");
}
#else
static void stmp3xxx_wdt_register(struct platform_device *rtc_pdev)

View File

@ -344,7 +344,7 @@ static struct platform_driver tps6586x_rtc_driver = {
};
module_platform_driver(tps6586x_rtc_driver);
MODULE_ALIAS("platform:rtc-tps6586x");
MODULE_ALIAS("platform:tps6586x-rtc");
MODULE_DESCRIPTION("TI TPS6586x RTC driver");
MODULE_AUTHOR("Laxman dewangan <ldewangan@nvidia.com>");
MODULE_LICENSE("GPL v2");

View File

@ -24,8 +24,6 @@
#include <linux/module.h>
#include <linux/bitops.h>
#define DRV_VERSION "1.0.8"
/* offsets into CCR area */
#define CCR_SEC 0
@ -634,8 +632,6 @@ static int x1205_probe(struct i2c_client *client,
if (x1205_validate_client(client) < 0)
return -ENODEV;
dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
rtc = devm_rtc_device_register(&client->dev, x1205_driver.driver.name,
&x1205_rtc_ops, THIS_MODULE);
@ -693,4 +689,3 @@ MODULE_AUTHOR(
"Alessandro Zummo <a.zummo@towertech.it>");
MODULE_DESCRIPTION("Xicor/Intersil X1205 RTC driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);

View File

@ -45,6 +45,7 @@
#define RTC_INT_SEC BIT(0)
#define RTC_INT_ALRM BIT(1)
#define RTC_OSC_EN BIT(24)
#define RTC_BATT_EN BIT(31)
#define RTC_CALIB_DEF 0x198233
#define RTC_CALIB_MASK 0x1FFFFF
@ -55,6 +56,7 @@ struct xlnx_rtc_dev {
void __iomem *reg_base;
int alarm_irq;
int sec_irq;
int calibval;
};
static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
@ -62,21 +64,63 @@ static int xlnx_rtc_set_time(struct device *dev, struct rtc_time *tm)
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
unsigned long new_time;
new_time = rtc_tm_to_time64(tm);
/*
* The value written will be updated after 1 sec into the
* seconds read register, so we need to program time +1 sec
* to get the correct time on read.
*/
new_time = rtc_tm_to_time64(tm) + 1;
if (new_time > RTC_SEC_MAX_VAL)
return -EINVAL;
/*
* Writing into calibration register will clear the Tick Counter and
* force the next second to be signaled exactly in 1 second period
*/
xrtcdev->calibval &= RTC_CALIB_MASK;
writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
writel(new_time, xrtcdev->reg_base + RTC_SET_TM_WR);
/*
* Clear the rtc interrupt status register after setting the
* time. During a read_time function, the code should read the
* RTC_INT_STATUS register and if bit 0 is still 0, it means
* that one second has not elapsed yet since RTC was set and
* the current time should be read from SET_TIME_READ register;
* otherwise, CURRENT_TIME register is read to report the time
*/
writel(RTC_INT_SEC, xrtcdev->reg_base + RTC_INT_STS);
return 0;
}
static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
u32 status;
unsigned long read_time;
struct xlnx_rtc_dev *xrtcdev = dev_get_drvdata(dev);
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
status = readl(xrtcdev->reg_base + RTC_INT_STS);
if (status & RTC_INT_SEC) {
/*
* RTC has updated the CURRENT_TIME with the time written into
* SET_TIME_WRITE register.
*/
rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
} else {
/*
* Time written in SET_TIME_WRITE has not yet updated into
* the seconds read register, so read the time from the
* SET_TIME_WRITE instead of CURRENT_TIME register.
* Since we add +1 sec while writing, we need to -1 sec while
* reading.
*/
read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;
rtc_time64_to_tm(read_time, tm);
}
return rtc_valid_tm(tm);
}
@ -120,16 +164,23 @@ static int xlnx_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
return 0;
}
static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev, u32 calibval)
static void xlnx_init_rtc(struct xlnx_rtc_dev *xrtcdev)
{
u32 rtc_ctrl;
/* Enable RTC switch to battery when VCC_PSAUX is not available */
rtc_ctrl = readl(xrtcdev->reg_base + RTC_CTRL);
rtc_ctrl |= RTC_BATT_EN;
writel(rtc_ctrl, xrtcdev->reg_base + RTC_CTRL);
/*
* Based on crystal freq of 33.330 KHz
* set the seconds counter and enable, set fractions counter
* to default value suggested as per design spec
* to correct RTC delay in frequency over period of time.
*/
calibval &= RTC_CALIB_MASK;
writel(calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
xrtcdev->calibval &= RTC_CALIB_MASK;
writel(xrtcdev->calibval, (xrtcdev->reg_base + RTC_CALIB_WR));
}
static const struct rtc_class_ops xlnx_rtc_ops = {
@ -150,11 +201,9 @@ static irqreturn_t xlnx_rtc_interrupt(int irq, void *id)
if (!(status & (RTC_INT_SEC | RTC_INT_ALRM)))
return IRQ_NONE;
/* Clear interrupt */
writel(status, xrtcdev->reg_base + RTC_INT_STS);
/* Clear RTC_INT_ALRM interrupt only */
writel(RTC_INT_ALRM, xrtcdev->reg_base + RTC_INT_STS);
if (status & RTC_INT_SEC)
rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_UF);
if (status & RTC_INT_ALRM)
rtc_update_irq(xrtcdev->rtc, 1, RTC_IRQF | RTC_AF);
@ -166,7 +215,6 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
struct xlnx_rtc_dev *xrtcdev;
struct resource *res;
int ret;
unsigned int calibvalue;
xrtcdev = devm_kzalloc(&pdev->dev, sizeof(*xrtcdev), GFP_KERNEL);
if (!xrtcdev)
@ -207,11 +255,11 @@ static int xlnx_rtc_probe(struct platform_device *pdev)
}
ret = of_property_read_u32(pdev->dev.of_node, "calibration",
&calibvalue);
&xrtcdev->calibval);
if (ret)
calibvalue = RTC_CALIB_DEF;
xrtcdev->calibval = RTC_CALIB_DEF;
xlnx_init_rtc(xrtcdev, calibvalue);
xlnx_init_rtc(xrtcdev);
device_init_wakeup(&pdev->dev, 1);