diff options
Diffstat (limited to 'drivers/rtc/rtc-ds1685.c')
-rw-r--r-- | drivers/rtc/rtc-ds1685.c | 78 |
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; |