summaryrefslogtreecommitdiff
path: root/drivers/rtc/rtc-ds1685.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/rtc/rtc-ds1685.c')
-rw-r--r--drivers/rtc/rtc-ds1685.c78
1 files changed, 52 insertions, 26 deletions
diff --git a/drivers/rtc/rtc-ds1685.c b/drivers/rtc/rtc-ds1685.c
index 349a8d1caca1..98d06b3ee913 100644
--- a/drivers/rtc/rtc-ds1685.c
+++ b/drivers/rtc/rtc-ds1685.c
@@ -31,7 +31,10 @@
/* ----------------------------------------------------------------------- */
-/* Standard read/write functions if platform does not provide overrides */
+/*
+ * Standard read/write
+ * all registers are mapped in CPU address space
+ */
/**
* ds1685_read - read a value from an rtc register.
@@ -59,6 +62,35 @@ ds1685_write(struct ds1685_priv *rtc, int reg, u8 value)
}
/* ----------------------------------------------------------------------- */
+/*
+ * Indirect read/write functions
+ * access happens via address and data register mapped in CPU address space
+ */
+
+/**
+ * ds1685_indirect_read - read a value from an rtc register.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @reg: the register address to read.
+ */
+static u8
+ds1685_indirect_read(struct ds1685_priv *rtc, int reg)
+{
+ writeb(reg, rtc->regs);
+ return readb(rtc->data);
+}
+
+/**
+ * ds1685_indirect_write - write a value to an rtc register.
+ * @rtc: pointer to the ds1685 rtc structure.
+ * @reg: the register address to write.
+ * @value: value to write to the register.
+ */
+static void
+ds1685_indirect_write(struct ds1685_priv *rtc, int reg, u8 value)
+{
+ writeb(reg, rtc->regs);
+ writeb(value, rtc->data);
+}
/* ----------------------------------------------------------------------- */
/* Inlined functions */
@@ -1062,42 +1094,36 @@ ds1685_rtc_probe(struct platform_device *pdev)
if (!rtc)
return -ENOMEM;
- /*
- * Allocate/setup any IORESOURCE_MEM resources, if required. Not all
- * platforms put the RTC in an easy-access place. Like the SGI Octane,
- * which attaches the RTC to a "ByteBus", hooked to a SuperIO chip
- * that sits behind the IOC3 PCI metadevice.
- */
- if (pdata->alloc_io_resources) {
+ /* Setup resources and access functions */
+ switch (pdata->access_type) {
+ case ds1685_reg_direct:
+ rtc->regs = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(rtc->regs))
+ return PTR_ERR(rtc->regs);
+ rtc->read = ds1685_read;
+ rtc->write = ds1685_write;
+ break;
+ case ds1685_reg_indirect:
rtc->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(rtc->regs))
return PTR_ERR(rtc->regs);
+ rtc->data = devm_platform_ioremap_resource(pdev, 1);
+ if (IS_ERR(rtc->data))
+ return PTR_ERR(rtc->data);
+ rtc->read = ds1685_indirect_read;
+ rtc->write = ds1685_indirect_write;
+ break;
}
+ if (!rtc->read || !rtc->write)
+ return -ENXIO;
+
/* Get the register step size. */
if (pdata->regstep > 0)
rtc->regstep = pdata->regstep;
else
rtc->regstep = 1;
- /* Platform read function, else default if mmio setup */
- if (pdata->plat_read)
- rtc->read = pdata->plat_read;
- else
- if (pdata->alloc_io_resources)
- rtc->read = ds1685_read;
- else
- return -ENXIO;
-
- /* Platform write function, else default if mmio setup */
- if (pdata->plat_write)
- rtc->write = pdata->plat_write;
- else
- if (pdata->alloc_io_resources)
- rtc->write = ds1685_write;
- else
- return -ENXIO;
-
/* Platform pre-shutdown function, if defined. */
if (pdata->plat_prepare_poweroff)
rtc->prepare_poweroff = pdata->plat_prepare_poweroff;