Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * rtc-palmas.c -- Palmas Real Time Clock driver.
0004 
0005  * RTC driver for TI Palma series devices like TPS65913,
0006  * TPS65914 power management IC.
0007  *
0008  * Copyright (c) 2012, NVIDIA Corporation.
0009  *
0010  * Author: Laxman Dewangan <ldewangan@nvidia.com>
0011  */
0012 
0013 #include <linux/bcd.h>
0014 #include <linux/errno.h>
0015 #include <linux/init.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/kernel.h>
0018 #include <linux/mfd/palmas.h>
0019 #include <linux/module.h>
0020 #include <linux/of.h>
0021 #include <linux/rtc.h>
0022 #include <linux/types.h>
0023 #include <linux/platform_device.h>
0024 #include <linux/pm.h>
0025 
0026 struct palmas_rtc {
0027     struct rtc_device   *rtc;
0028     struct device       *dev;
0029     unsigned int        irq;
0030 };
0031 
0032 /* Total number of RTC registers needed to set time*/
0033 #define PALMAS_NUM_TIME_REGS    (PALMAS_YEARS_REG - PALMAS_SECONDS_REG + 1)
0034 
0035 static int palmas_rtc_read_time(struct device *dev, struct rtc_time *tm)
0036 {
0037     unsigned char rtc_data[PALMAS_NUM_TIME_REGS];
0038     struct palmas *palmas = dev_get_drvdata(dev->parent);
0039     int ret;
0040 
0041     /* Copy RTC counting registers to static registers or latches */
0042     ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
0043         PALMAS_RTC_CTRL_REG_GET_TIME, PALMAS_RTC_CTRL_REG_GET_TIME);
0044     if (ret < 0) {
0045         dev_err(dev, "RTC CTRL reg update failed, err: %d\n", ret);
0046         return ret;
0047     }
0048 
0049     ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG,
0050             rtc_data, PALMAS_NUM_TIME_REGS);
0051     if (ret < 0) {
0052         dev_err(dev, "RTC_SECONDS reg read failed, err = %d\n", ret);
0053         return ret;
0054     }
0055 
0056     tm->tm_sec = bcd2bin(rtc_data[0]);
0057     tm->tm_min = bcd2bin(rtc_data[1]);
0058     tm->tm_hour = bcd2bin(rtc_data[2]);
0059     tm->tm_mday = bcd2bin(rtc_data[3]);
0060     tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
0061     tm->tm_year = bcd2bin(rtc_data[5]) + 100;
0062 
0063     return ret;
0064 }
0065 
0066 static int palmas_rtc_set_time(struct device *dev, struct rtc_time *tm)
0067 {
0068     unsigned char rtc_data[PALMAS_NUM_TIME_REGS];
0069     struct palmas *palmas = dev_get_drvdata(dev->parent);
0070     int ret;
0071 
0072     rtc_data[0] = bin2bcd(tm->tm_sec);
0073     rtc_data[1] = bin2bcd(tm->tm_min);
0074     rtc_data[2] = bin2bcd(tm->tm_hour);
0075     rtc_data[3] = bin2bcd(tm->tm_mday);
0076     rtc_data[4] = bin2bcd(tm->tm_mon + 1);
0077     rtc_data[5] = bin2bcd(tm->tm_year - 100);
0078 
0079     /* Stop RTC while updating the RTC time registers */
0080     ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
0081         PALMAS_RTC_CTRL_REG_STOP_RTC, 0);
0082     if (ret < 0) {
0083         dev_err(dev, "RTC stop failed, err = %d\n", ret);
0084         return ret;
0085     }
0086 
0087     ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG,
0088         rtc_data, PALMAS_NUM_TIME_REGS);
0089     if (ret < 0) {
0090         dev_err(dev, "RTC_SECONDS reg write failed, err = %d\n", ret);
0091         return ret;
0092     }
0093 
0094     /* Start back RTC */
0095     ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
0096         PALMAS_RTC_CTRL_REG_STOP_RTC, PALMAS_RTC_CTRL_REG_STOP_RTC);
0097     if (ret < 0)
0098         dev_err(dev, "RTC start failed, err = %d\n", ret);
0099     return ret;
0100 }
0101 
0102 static int palmas_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
0103 {
0104     struct palmas *palmas = dev_get_drvdata(dev->parent);
0105     u8 val;
0106 
0107     val = enabled ? PALMAS_RTC_INTERRUPTS_REG_IT_ALARM : 0;
0108     return palmas_write(palmas, PALMAS_RTC_BASE,
0109         PALMAS_RTC_INTERRUPTS_REG, val);
0110 }
0111 
0112 static int palmas_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
0113 {
0114     unsigned char alarm_data[PALMAS_NUM_TIME_REGS];
0115     u32 int_val;
0116     struct palmas *palmas = dev_get_drvdata(dev->parent);
0117     int ret;
0118 
0119     ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE,
0120             PALMAS_ALARM_SECONDS_REG,
0121             alarm_data, PALMAS_NUM_TIME_REGS);
0122     if (ret < 0) {
0123         dev_err(dev, "RTC_ALARM_SECONDS read failed, err = %d\n", ret);
0124         return ret;
0125     }
0126 
0127     alm->time.tm_sec = bcd2bin(alarm_data[0]);
0128     alm->time.tm_min = bcd2bin(alarm_data[1]);
0129     alm->time.tm_hour = bcd2bin(alarm_data[2]);
0130     alm->time.tm_mday = bcd2bin(alarm_data[3]);
0131     alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1;
0132     alm->time.tm_year = bcd2bin(alarm_data[5]) + 100;
0133 
0134     ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_INTERRUPTS_REG,
0135             &int_val);
0136     if (ret < 0) {
0137         dev_err(dev, "RTC_INTERRUPTS reg read failed, err = %d\n", ret);
0138         return ret;
0139     }
0140 
0141     if (int_val & PALMAS_RTC_INTERRUPTS_REG_IT_ALARM)
0142         alm->enabled = 1;
0143     return ret;
0144 }
0145 
0146 static int palmas_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
0147 {
0148     unsigned char alarm_data[PALMAS_NUM_TIME_REGS];
0149     struct palmas *palmas = dev_get_drvdata(dev->parent);
0150     int ret;
0151 
0152     ret = palmas_rtc_alarm_irq_enable(dev, 0);
0153     if (ret < 0) {
0154         dev_err(dev, "Disable RTC alarm failed\n");
0155         return ret;
0156     }
0157 
0158     alarm_data[0] = bin2bcd(alm->time.tm_sec);
0159     alarm_data[1] = bin2bcd(alm->time.tm_min);
0160     alarm_data[2] = bin2bcd(alm->time.tm_hour);
0161     alarm_data[3] = bin2bcd(alm->time.tm_mday);
0162     alarm_data[4] = bin2bcd(alm->time.tm_mon + 1);
0163     alarm_data[5] = bin2bcd(alm->time.tm_year - 100);
0164 
0165     ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE,
0166         PALMAS_ALARM_SECONDS_REG, alarm_data, PALMAS_NUM_TIME_REGS);
0167     if (ret < 0) {
0168         dev_err(dev, "ALARM_SECONDS_REG write failed, err = %d\n", ret);
0169         return ret;
0170     }
0171 
0172     if (alm->enabled)
0173         ret = palmas_rtc_alarm_irq_enable(dev, 1);
0174     return ret;
0175 }
0176 
0177 static int palmas_clear_interrupts(struct device *dev)
0178 {
0179     struct palmas *palmas = dev_get_drvdata(dev->parent);
0180     unsigned int rtc_reg;
0181     int ret;
0182 
0183     ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
0184                 &rtc_reg);
0185     if (ret < 0) {
0186         dev_err(dev, "RTC_STATUS read failed, err = %d\n", ret);
0187         return ret;
0188     }
0189 
0190     ret = palmas_write(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
0191             rtc_reg);
0192     if (ret < 0) {
0193         dev_err(dev, "RTC_STATUS write failed, err = %d\n", ret);
0194         return ret;
0195     }
0196     return 0;
0197 }
0198 
0199 static irqreturn_t palmas_rtc_interrupt(int irq, void *context)
0200 {
0201     struct palmas_rtc *palmas_rtc = context;
0202     struct device *dev = palmas_rtc->dev;
0203     int ret;
0204 
0205     ret = palmas_clear_interrupts(dev);
0206     if (ret < 0) {
0207         dev_err(dev, "RTC interrupt clear failed, err = %d\n", ret);
0208         return IRQ_NONE;
0209     }
0210 
0211     rtc_update_irq(palmas_rtc->rtc, 1, RTC_IRQF | RTC_AF);
0212     return IRQ_HANDLED;
0213 }
0214 
0215 static const struct rtc_class_ops palmas_rtc_ops = {
0216     .read_time  = palmas_rtc_read_time,
0217     .set_time   = palmas_rtc_set_time,
0218     .read_alarm = palmas_rtc_read_alarm,
0219     .set_alarm  = palmas_rtc_set_alarm,
0220     .alarm_irq_enable = palmas_rtc_alarm_irq_enable,
0221 };
0222 
0223 static int palmas_rtc_probe(struct platform_device *pdev)
0224 {
0225     struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
0226     struct palmas_rtc *palmas_rtc = NULL;
0227     int ret;
0228     bool enable_bb_charging = false;
0229     bool high_bb_charging = false;
0230 
0231     if (pdev->dev.of_node) {
0232         enable_bb_charging = of_property_read_bool(pdev->dev.of_node,
0233                     "ti,backup-battery-chargeable");
0234         high_bb_charging = of_property_read_bool(pdev->dev.of_node,
0235                     "ti,backup-battery-charge-high-current");
0236     }
0237 
0238     palmas_rtc = devm_kzalloc(&pdev->dev, sizeof(struct palmas_rtc),
0239             GFP_KERNEL);
0240     if (!palmas_rtc)
0241         return -ENOMEM;
0242 
0243     /* Clear pending interrupts */
0244     ret = palmas_clear_interrupts(&pdev->dev);
0245     if (ret < 0) {
0246         dev_err(&pdev->dev, "clear RTC int failed, err = %d\n", ret);
0247         return ret;
0248     }
0249 
0250     palmas_rtc->dev = &pdev->dev;
0251     platform_set_drvdata(pdev, palmas_rtc);
0252 
0253     if (enable_bb_charging) {
0254         unsigned reg = PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG;
0255 
0256         if (high_bb_charging)
0257             reg = 0;
0258 
0259         ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
0260             PALMAS_BACKUP_BATTERY_CTRL,
0261             PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG, reg);
0262         if (ret < 0) {
0263             dev_err(&pdev->dev,
0264                 "BACKUP_BATTERY_CTRL update failed, %d\n", ret);
0265             return ret;
0266         }
0267 
0268         ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
0269             PALMAS_BACKUP_BATTERY_CTRL,
0270             PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN,
0271             PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN);
0272         if (ret < 0) {
0273             dev_err(&pdev->dev,
0274                 "BACKUP_BATTERY_CTRL update failed, %d\n", ret);
0275             return ret;
0276         }
0277     }
0278 
0279     /* Start RTC */
0280     ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
0281             PALMAS_RTC_CTRL_REG_STOP_RTC,
0282             PALMAS_RTC_CTRL_REG_STOP_RTC);
0283     if (ret < 0) {
0284         dev_err(&pdev->dev, "RTC_CTRL write failed, err = %d\n", ret);
0285         return ret;
0286     }
0287 
0288     palmas_rtc->irq = platform_get_irq(pdev, 0);
0289 
0290     device_init_wakeup(&pdev->dev, 1);
0291     palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
0292                 &palmas_rtc_ops, THIS_MODULE);
0293     if (IS_ERR(palmas_rtc->rtc)) {
0294         ret = PTR_ERR(palmas_rtc->rtc);
0295         dev_err(&pdev->dev, "RTC register failed, err = %d\n", ret);
0296         return ret;
0297     }
0298 
0299     ret = devm_request_threaded_irq(&pdev->dev, palmas_rtc->irq, NULL,
0300             palmas_rtc_interrupt,
0301             IRQF_TRIGGER_LOW | IRQF_ONESHOT,
0302             dev_name(&pdev->dev), palmas_rtc);
0303     if (ret < 0) {
0304         dev_err(&pdev->dev, "IRQ request failed, err = %d\n", ret);
0305         return ret;
0306     }
0307 
0308     return 0;
0309 }
0310 
0311 static int palmas_rtc_remove(struct platform_device *pdev)
0312 {
0313     palmas_rtc_alarm_irq_enable(&pdev->dev, 0);
0314     return 0;
0315 }
0316 
0317 #ifdef CONFIG_PM_SLEEP
0318 static int palmas_rtc_suspend(struct device *dev)
0319 {
0320     struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev);
0321 
0322     if (device_may_wakeup(dev))
0323         enable_irq_wake(palmas_rtc->irq);
0324     return 0;
0325 }
0326 
0327 static int palmas_rtc_resume(struct device *dev)
0328 {
0329     struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev);
0330 
0331     if (device_may_wakeup(dev))
0332         disable_irq_wake(palmas_rtc->irq);
0333     return 0;
0334 }
0335 #endif
0336 
0337 static SIMPLE_DEV_PM_OPS(palmas_rtc_pm_ops, palmas_rtc_suspend,
0338              palmas_rtc_resume);
0339 
0340 #ifdef CONFIG_OF
0341 static const struct of_device_id of_palmas_rtc_match[] = {
0342     { .compatible = "ti,palmas-rtc"},
0343     { },
0344 };
0345 MODULE_DEVICE_TABLE(of, of_palmas_rtc_match);
0346 #endif
0347 
0348 static struct platform_driver palmas_rtc_driver = {
0349     .probe      = palmas_rtc_probe,
0350     .remove     = palmas_rtc_remove,
0351     .driver     = {
0352         .name   = "palmas-rtc",
0353         .pm = &palmas_rtc_pm_ops,
0354         .of_match_table = of_match_ptr(of_palmas_rtc_match),
0355     },
0356 };
0357 
0358 module_platform_driver(palmas_rtc_driver);
0359 
0360 MODULE_ALIAS("platform:palmas_rtc");
0361 MODULE_DESCRIPTION("TI PALMAS series RTC driver");
0362 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
0363 MODULE_LICENSE("GPL v2");