diff options
author | Balaji Rao <balajirrao@openmoko.org> | 2008-11-20 19:46:51 +0000 |
---|---|---|
committer | Andy Green <agreen@pads.home.warmcat.com> | 2008-11-20 19:46:51 +0000 |
commit | ad1e78fb2babc9cf9acd62923d62389ea28b1df2 (patch) | |
tree | dd37e7a75e654d38e601342cacd57a6b30cded8c /drivers/rtc | |
parent | 5557b3223d35dd25366d6ef047299b1dc94b17e6 (diff) |
pcf50633_mdc_related_changes.patch
Changes related to pcf50633_mfd.patch
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/rtc-pcf50633.c | 147 |
1 files changed, 73 insertions, 74 deletions
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c index 74b7e569d39..6b8ef2f4b8a 100644 --- a/drivers/rtc/rtc-pcf50633.c +++ b/drivers/rtc/rtc-pcf50633.c @@ -1,9 +1,9 @@ #include <linux/rtc.h> #include <linux/platform_device.h> #include <linux/bcd.h> -#include <linux/pcf50633.h> -#include <linux/rtc/pcf50633.h> -#include <linux/i2c.h> + +#include <linux/mfd/pcf50633/core.h> +#include <linux/mfd/pcf50633/rtc.h> enum pcf50633_time_indexes { PCF50633_TI_SEC = 0, @@ -46,69 +46,48 @@ static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc) static int pcf50633_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { - struct pcf50633_data *pcf = dev->platform_data; + struct pcf50633 *pcf; + + pcf = dev_get_drvdata(dev); switch (cmd) { case RTC_AIE_OFF: /* disable the alarm interrupt */ - pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_INT1M, - PCF50633_INT1_ALARM, PCF50633_INT1_ALARM); + pcf->rtc.alarm_enabled = 0; + pcf50633_irq_mask(pcf, PCF50633_IRQ_ALARM); return 0; case RTC_AIE_ON: /* enable the alarm interrupt */ - pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_ALARM); + pcf->rtc.alarm_enabled = 1; + pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM); return 0; case RTC_PIE_OFF: /* disable periodic interrupt (hz tick) */ - pcf->flags &= ~PCF50633_F_RTC_SECOND; - pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_INT1M, - PCF50633_INT1_SECOND, PCF50633_INT1_SECOND); + pcf->rtc.second_enabled = 0; + pcf50633_irq_mask(pcf, PCF50633_IRQ_SECOND); return 0; case RTC_PIE_ON: /* ensable periodic interrupt (hz tick) */ - pcf->flags |= PCF50633_F_RTC_SECOND; - pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M, PCF50633_INT1_SECOND); + pcf->rtc.second_enabled = 1; + pcf50633_irq_unmask(pcf, PCF50633_IRQ_SECOND); return 0; } return -ENOIOCTLCMD; } -#ifdef PCF50633_RTC -void pcf50633_rtc_handle_event(struct pcf50633_data *pcf, - enum pcf50633_rtc_event evt) -{ - switch(evt) { - case PCF50633_RTC_EVENT_ALARM: - rtc_update_irq(pcf->rtc, 1, RTC_AF | RTC_IRQF); - break; - case PCF50633_RTC_EVENT_SECOND: - rtc_update_irq(pcf->rtc, 1, RTC_PF | RTC_IRQF); - } -} -#else -void pcf50633_rtc_handle_event(struct pcf50633_data *pcf, - enum pcf50633_rtc_event evt) -{ - -} -#endif - static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct pcf50633_data *pcf = dev->platform_data; + struct pcf50633 *pcf; struct pcf50633_time pcf_tm; int ret; - mutex_lock(&pcf->lock); + pcf = dev_get_drvdata(dev); - ret = i2c_smbus_read_i2c_block_data(pcf->client, - PCF50633_REG_RTCSC, + ret = pcf50633_read_block(pcf, PCF50633_REG_RTCSC, PCF50633_TI_EXTENT, &pcf_tm.time[0]); if (ret != PCF50633_TI_EXTENT) - dev_err(dev, "Failed to read time :-(\n"); - - mutex_unlock(&pcf->lock); + dev_err(dev, "Failed to read time\n"); dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n", pcf_tm.time[PCF50633_TI_DAY], @@ -129,9 +108,12 @@ static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct pcf50633_data *pcf = dev->platform_data; + struct pcf50633 *pcf; struct pcf50633_time pcf_tm; int ret; + int second_masked, alarm_masked; + + pcf = dev_get_drvdata(dev); dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n", tm->tm_mday, tm->tm_mon, tm->tm_year, @@ -145,42 +127,46 @@ static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm) pcf_tm.time[PCF50633_TI_MIN], pcf_tm.time[PCF50633_TI_SEC]); - mutex_lock(&pcf->lock); - /* FIXME: disable second interrupt */ - ret = i2c_smbus_write_i2c_block_data(pcf->client, - PCF50633_REG_RTCSC, + second_masked = pcf50633_irq_mask_get(pcf, PCF50633_IRQ_SECOND); + alarm_masked = pcf50633_irq_mask_get(pcf, PCF50633_IRQ_ALARM); + + if (!second_masked) + pcf50633_irq_mask(pcf, PCF50633_IRQ_SECOND); + if (!alarm_masked) + pcf50633_irq_mask(pcf, PCF50633_IRQ_ALARM); + + ret = pcf50633_write_block(pcf, PCF50633_REG_RTCSC, PCF50633_TI_EXTENT, &pcf_tm.time[0]); if (ret) dev_err(dev, "Failed to set time %d\n", ret); - /* FIXME: re-enable second interrupt */ - mutex_unlock(&pcf->lock); + if (!second_masked) + pcf50633_irq_unmask(pcf, PCF50633_IRQ_SECOND); + if (!alarm_masked) + pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM); + return 0; } static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct pcf50633_data *pcf = dev->platform_data; + struct pcf50633 *pcf; struct pcf50633_time pcf_tm; int ret; - u_int8_t reg; - mutex_lock(&pcf->lock); - - pcf50633_read(pcf, PCF50633_REG_INT1M, 1, ®); - alrm->enabled = reg & PCF50633_INT1_ALARM ? 0 : 1; + pcf = dev_get_drvdata(dev); - ret = pcf50633_read(pcf, PCF50633_REG_RTCSCA, + alrm->enabled = pcf->rtc.alarm_enabled; + + ret = pcf50633_read_block(pcf, PCF50633_REG_RTCSCA, PCF50633_TI_EXTENT, &pcf_tm.time[0]); if (ret != PCF50633_TI_EXTENT) dev_err(dev, "Failed to read Alarm time :-(\n"); - mutex_unlock(&pcf->lock); - pcf2rtc_time(&alrm->time, &pcf_tm); return 0; @@ -188,35 +174,31 @@ static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { - struct pcf50633_data *pcf = dev->platform_data; + struct pcf50633 *pcf; struct pcf50633_time pcf_tm; - u_int8_t irqmask; - int ret; + int ret, alarm_masked; + + pcf = dev_get_drvdata(dev); rtc2pcf_time(&pcf_tm, &alrm->time); - mutex_lock(&pcf->lock); + printk("wkday is %x\n", alrm->time.tm_wday); + printk("wkday is %x\n", pcf_tm.time[PCF50633_TI_WKDAY]); + + alarm_masked = pcf50633_irq_mask_get(pcf, PCF50633_IRQ_ALARM); /* disable alarm interrupt */ - pcf50633_read(pcf, PCF50633_REG_INT1M, 1, &irqmask); - irqmask |= PCF50633_INT1_ALARM; - pcf50633_write(pcf, PCF50633_REG_INT1M, 1, &irqmask); + if (!alarm_masked) + pcf50633_irq_mask(pcf, PCF50633_IRQ_ALARM); - ret = pcf50633_write(pcf, PCF50633_REG_RTCSCA, + ret = pcf50633_write_block(pcf, PCF50633_REG_RTCSCA, PCF50633_TI_EXTENT, &pcf_tm.time[0]); if (ret) - dev_err(dev, "Failed to write alarm time :-( %d\n", ret); - - if (alrm->enabled) { - /* (re-)enaable alarm interrupt */ - pcf50633_read(pcf, PCF50633_REG_INT1M, 1, &irqmask); - irqmask &= ~PCF50633_INT1_ALARM; - pcf50633_write(pcf, PCF50633_REG_INT1M, 1, &irqmask); - } + dev_err(dev, "Failed to write alarm time %d\n", ret); - mutex_unlock(&pcf->lock); + if (!alarm_masked) + pcf50633_irq_unmask(pcf, PCF50633_IRQ_ALARM); - /* FIXME */ return 0; } static struct rtc_class_ops pcf50633_rtc_ops = { @@ -227,15 +209,32 @@ static struct rtc_class_ops pcf50633_rtc_ops = { .set_alarm = pcf50633_rtc_set_alarm, }; +static void pcf50633_rtc_irq(struct pcf50633 *pcf, int irq, void *unused) +{ + switch(irq) { + case PCF50633_IRQ_ALARM: + rtc_update_irq(pcf->rtc.rtc_dev, 1, RTC_AF | RTC_IRQF); + break; + } +} + static int pcf50633_rtc_probe(struct platform_device *pdev) { struct rtc_device *rtc; - + struct pcf50633 *pcf; + rtc = rtc_device_register("pcf50633", &pdev->dev, &pcf50633_rtc_ops, THIS_MODULE); if (IS_ERR(rtc)) return -ENODEV; + pcf = platform_get_drvdata(pdev); + + /* Set up IRQ handlers */ + pcf->irq_handler[PCF50633_IRQ_ALARM].handler = pcf50633_rtc_irq; + pcf->irq_handler[PCF50633_IRQ_SECOND].handler = pcf50633_rtc_irq; + + pcf->rtc.rtc_dev = rtc; return 0; } |