diff options
Diffstat (limited to 'drivers/rtc/rtc-pcf2123.c')
-rw-r--r-- | drivers/rtc/rtc-pcf2123.c | 136 |
1 files changed, 68 insertions, 68 deletions
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index fb542a930bf0..c3691fa4210e 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c @@ -82,7 +82,7 @@ #define OSC_HAS_STOPPED BIT(7) /* Clock has been stopped */ /* PCF2123_REG_ALRM_XX BITS */ -#define ALRM_ENABLE BIT(7) /* MN, HR, DM, or DW alarm enable */ +#define ALRM_DISABLE BIT(7) /* MN, HR, DM, or DW alarm matching */ /* PCF2123_REG_TMR_CLKOUT BITS */ #define CD_TMR_4096KHZ (0) /* 4096 KHz countdown timer */ @@ -104,7 +104,7 @@ static struct spi_driver pcf2123_driver; -struct pcf2123_plat_data { +struct pcf2123_data { struct rtc_device *rtc; struct regmap *map; }; @@ -119,11 +119,11 @@ static const struct regmap_config pcf2123_regmap_config = { static int pcf2123_read_offset(struct device *dev, long *offset) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); int ret, val; unsigned int reg; - ret = regmap_read(pdata->map, PCF2123_REG_OFFSET, ®); + ret = regmap_read(pcf2123->map, PCF2123_REG_OFFSET, ®); if (ret) return ret; @@ -149,7 +149,7 @@ static int pcf2123_read_offset(struct device *dev, long *offset) */ static int pcf2123_set_offset(struct device *dev, long offset) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); s8 reg; if (offset > OFFSET_STEP * 127) @@ -169,16 +169,16 @@ static int pcf2123_set_offset(struct device *dev, long offset) reg |= OFFSET_COARSE; } - return regmap_write(pdata->map, PCF2123_REG_OFFSET, (unsigned int)reg); + return regmap_write(pcf2123->map, PCF2123_REG_OFFSET, (unsigned int)reg); } static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); u8 rxbuf[7]; int ret; - ret = regmap_bulk_read(pdata->map, PCF2123_REG_SC, rxbuf, + ret = regmap_bulk_read(pcf2123->map, PCF2123_REG_SC, rxbuf, sizeof(rxbuf)); if (ret) return ret; @@ -194,9 +194,7 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) tm->tm_mday = bcd2bin(rxbuf[3] & 0x3F); tm->tm_wday = rxbuf[4] & 0x07; tm->tm_mon = bcd2bin(rxbuf[5] & 0x1F) - 1; /* rtc mn 1-12 */ - tm->tm_year = bcd2bin(rxbuf[6]); - if (tm->tm_year < 70) - tm->tm_year += 100; /* assume we are in 1970...2069 */ + tm->tm_year = bcd2bin(rxbuf[6]) + 100; dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm); @@ -205,14 +203,14 @@ static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm) static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); u8 txbuf[7]; int ret; dev_dbg(dev, "%s: tm is %ptR\n", __func__, tm); /* Stop the counter first */ - ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP); + ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_STOP); if (ret) return ret; @@ -223,29 +221,37 @@ static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm) txbuf[3] = bin2bcd(tm->tm_mday & 0x3F); txbuf[4] = tm->tm_wday & 0x07; txbuf[5] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */ - txbuf[6] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100); + txbuf[6] = bin2bcd(tm->tm_year - 100); - ret = regmap_bulk_write(pdata->map, PCF2123_REG_SC, txbuf, + ret = regmap_bulk_write(pcf2123->map, PCF2123_REG_SC, txbuf, sizeof(txbuf)); if (ret) return ret; /* Start the counter */ - ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR); + ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_CLEAR); if (ret) return ret; return 0; } +static int pcf2123_rtc_alarm_irq_enable(struct device *dev, unsigned int en) +{ + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); + + return regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AIE, + en ? CTRL2_AIE : 0); +} + static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); u8 rxbuf[4]; int ret; unsigned int val = 0; - ret = regmap_bulk_read(pdata->map, PCF2123_REG_ALRM_MN, rxbuf, + ret = regmap_bulk_read(pcf2123->map, PCF2123_REG_ALRM_MN, rxbuf, sizeof(rxbuf)); if (ret) return ret; @@ -257,7 +263,7 @@ static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time); - ret = regmap_read(pdata->map, PCF2123_REG_CTRL2, &val); + ret = regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val); if (ret) return ret; @@ -268,19 +274,19 @@ static int pcf2123_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm) static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); u8 txbuf[4]; int ret; dev_dbg(dev, "%s: alm is %ptR\n", __func__, &alm->time); - /* Ensure alarm flag is clear */ - ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0); + /* Disable alarm interrupt */ + ret = regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0); if (ret) return ret; - /* Disable alarm interrupt */ - ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AIE, 0); + /* Ensure alarm flag is clear */ + ret = regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AF, 0); if (ret) return ret; @@ -288,42 +294,34 @@ static int pcf2123_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) txbuf[0] = bin2bcd(alm->time.tm_min & 0x7F); txbuf[1] = bin2bcd(alm->time.tm_hour & 0x3F); txbuf[2] = bin2bcd(alm->time.tm_mday & 0x3F); - txbuf[3] = bin2bcd(alm->time.tm_wday & 0x07); + txbuf[3] = ALRM_DISABLE; - ret = regmap_bulk_write(pdata->map, PCF2123_REG_ALRM_MN, txbuf, + ret = regmap_bulk_write(pcf2123->map, PCF2123_REG_ALRM_MN, txbuf, sizeof(txbuf)); if (ret) return ret; - /* Enable alarm interrupt */ - if (alm->enabled) { - ret = regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, - CTRL2_AIE, CTRL2_AIE); - if (ret) - return ret; - } - - return 0; + return pcf2123_rtc_alarm_irq_enable(dev, alm->enabled); } static irqreturn_t pcf2123_rtc_irq(int irq, void *dev) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); - struct mutex *lock = &pdata->rtc->ops_lock; + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); + struct mutex *lock = &pcf2123->rtc->ops_lock; unsigned int val = 0; int ret = IRQ_NONE; mutex_lock(lock); - regmap_read(pdata->map, PCF2123_REG_CTRL2, &val); + regmap_read(pcf2123->map, PCF2123_REG_CTRL2, &val); /* Alarm? */ if (val & CTRL2_AF) { ret = IRQ_HANDLED; /* Clear alarm flag */ - regmap_update_bits(pdata->map, PCF2123_REG_CTRL2, CTRL2_AF, 0); + regmap_update_bits(pcf2123->map, PCF2123_REG_CTRL2, CTRL2_AF, 0); - rtc_update_irq(pdata->rtc, 1, RTC_IRQF | RTC_AF); + rtc_update_irq(pcf2123->rtc, 1, RTC_IRQF | RTC_AF); } mutex_unlock(lock); @@ -333,23 +331,23 @@ static irqreturn_t pcf2123_rtc_irq(int irq, void *dev) static int pcf2123_reset(struct device *dev) { - struct pcf2123_plat_data *pdata = dev_get_platdata(dev); + struct pcf2123_data *pcf2123 = dev_get_drvdata(dev); int ret; unsigned int val = 0; - ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET); + ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_SW_RESET); if (ret) return ret; /* Stop the counter */ dev_dbg(dev, "stopping RTC\n"); - ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_STOP); + ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_STOP); if (ret) return ret; /* See if the counter was actually stopped */ dev_dbg(dev, "checking for presence of RTC\n"); - ret = regmap_read(pdata->map, PCF2123_REG_CTRL1, &val); + ret = regmap_read(pcf2123->map, PCF2123_REG_CTRL1, &val); if (ret) return ret; @@ -358,7 +356,7 @@ static int pcf2123_reset(struct device *dev) return -ENODEV; /* Start the counter */ - ret = regmap_write(pdata->map, PCF2123_REG_CTRL1, CTRL1_CLEAR); + ret = regmap_write(pcf2123->map, PCF2123_REG_CTRL1, CTRL1_CLEAR); if (ret) return ret; @@ -372,26 +370,27 @@ static const struct rtc_class_ops pcf2123_rtc_ops = { .set_offset = pcf2123_set_offset, .read_alarm = pcf2123_rtc_read_alarm, .set_alarm = pcf2123_rtc_set_alarm, + .alarm_irq_enable = pcf2123_rtc_alarm_irq_enable, }; static int pcf2123_probe(struct spi_device *spi) { struct rtc_device *rtc; struct rtc_time tm; - struct pcf2123_plat_data *pdata; + struct pcf2123_data *pcf2123; int ret = 0; - pdata = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_plat_data), + pcf2123 = devm_kzalloc(&spi->dev, sizeof(struct pcf2123_data), GFP_KERNEL); - if (!pdata) + if (!pcf2123) return -ENOMEM; - spi->dev.platform_data = pdata; - pdata->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config); + dev_set_drvdata(&spi->dev, pcf2123); - if (IS_ERR(pdata->map)) { + pcf2123->map = devm_regmap_init_spi(spi, &pcf2123_regmap_config); + if (IS_ERR(pcf2123->map)) { dev_err(&spi->dev, "regmap init failed.\n"); - goto kfree_exit; + return PTR_ERR(pcf2123->map); } ret = pcf2123_rtc_read_time(&spi->dev, &tm); @@ -399,7 +398,7 @@ static int pcf2123_probe(struct spi_device *spi) ret = pcf2123_reset(&spi->dev); if (ret < 0) { dev_err(&spi->dev, "chip not found\n"); - goto kfree_exit; + return ret; } } @@ -407,16 +406,11 @@ static int pcf2123_probe(struct spi_device *spi) (spi->max_speed_hz + 500) / 1000); /* Finalize the initialization */ - rtc = devm_rtc_device_register(&spi->dev, pcf2123_driver.driver.name, - &pcf2123_rtc_ops, THIS_MODULE); - - if (IS_ERR(rtc)) { - dev_err(&spi->dev, "failed to register.\n"); - ret = PTR_ERR(rtc); - goto kfree_exit; - } + rtc = devm_rtc_allocate_device(&spi->dev); + if (IS_ERR(rtc)) + return PTR_ERR(rtc); - pdata->rtc = rtc; + pcf2123->rtc = rtc; /* Register alarm irq */ if (spi->irq > 0) { @@ -434,19 +428,25 @@ static int pcf2123_probe(struct spi_device *spi) * support to this driver to generate interrupts more than once * per minute. */ - pdata->rtc->uie_unsupported = 1; + rtc->uie_unsupported = 1; + rtc->ops = &pcf2123_rtc_ops; + rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; + rtc->range_max = RTC_TIMESTAMP_END_2099; + rtc->set_start_time = true; - return 0; + ret = rtc_register_device(rtc); + if (ret) + return ret; -kfree_exit: - spi->dev.platform_data = NULL; - return ret; + return 0; } #ifdef CONFIG_OF static const struct of_device_id pcf2123_dt_ids[] = { - { .compatible = "nxp,rtc-pcf2123", }, + { .compatible = "nxp,pcf2123", }, { .compatible = "microcrystal,rv2123", }, + /* Deprecated, do not use */ + { .compatible = "nxp,rtc-pcf2123", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, pcf2123_dt_ids); |