root/drivers/rtc/rtc-palmas.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. palmas_rtc_read_time
  2. palmas_rtc_set_time
  3. palmas_rtc_alarm_irq_enable
  4. palmas_rtc_read_alarm
  5. palmas_rtc_set_alarm
  6. palmas_clear_interrupts
  7. palmas_rtc_interrupt
  8. palmas_rtc_probe
  9. palmas_rtc_remove
  10. palmas_rtc_suspend
  11. palmas_rtc_resume

   1 /*
   2  * rtc-palmas.c -- Palmas Real Time Clock driver.
   3 
   4  * RTC driver for TI Palma series devices like TPS65913,
   5  * TPS65914 power management IC.
   6  *
   7  * Copyright (c) 2012, NVIDIA Corporation.
   8  *
   9  * Author: Laxman Dewangan <ldewangan@nvidia.com>
  10  *
  11  * This program is free software; you can redistribute it and/or
  12  * modify it under the terms of the GNU General Public License as
  13  * published by the Free Software Foundation version 2.
  14  *
  15  * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
  16  * whether express or implied; without even the implied warranty of
  17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18  * General Public License for more details.
  19  *
  20  * You should have received a copy of the GNU General Public License
  21  * along with this program; if not, write to the Free Software
  22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  23  * 02111-1307, USA
  24  */
  25 
  26 #include <linux/bcd.h>
  27 #include <linux/errno.h>
  28 #include <linux/init.h>
  29 #include <linux/interrupt.h>
  30 #include <linux/kernel.h>
  31 #include <linux/mfd/palmas.h>
  32 #include <linux/module.h>
  33 #include <linux/of.h>
  34 #include <linux/rtc.h>
  35 #include <linux/types.h>
  36 #include <linux/platform_device.h>
  37 #include <linux/pm.h>
  38 
  39 struct palmas_rtc {
  40         struct rtc_device       *rtc;
  41         struct device           *dev;
  42         unsigned int            irq;
  43 };
  44 
  45 /* Total number of RTC registers needed to set time*/
  46 #define PALMAS_NUM_TIME_REGS    (PALMAS_YEARS_REG - PALMAS_SECONDS_REG + 1)
  47 
  48 static int palmas_rtc_read_time(struct device *dev, struct rtc_time *tm)
  49 {
  50         unsigned char rtc_data[PALMAS_NUM_TIME_REGS];
  51         struct palmas *palmas = dev_get_drvdata(dev->parent);
  52         int ret;
  53 
  54         /* Copy RTC counting registers to static registers or latches */
  55         ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
  56                 PALMAS_RTC_CTRL_REG_GET_TIME, PALMAS_RTC_CTRL_REG_GET_TIME);
  57         if (ret < 0) {
  58                 dev_err(dev, "RTC CTRL reg update failed, err: %d\n", ret);
  59                 return ret;
  60         }
  61 
  62         ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG,
  63                         rtc_data, PALMAS_NUM_TIME_REGS);
  64         if (ret < 0) {
  65                 dev_err(dev, "RTC_SECONDS reg read failed, err = %d\n", ret);
  66                 return ret;
  67         }
  68 
  69         tm->tm_sec = bcd2bin(rtc_data[0]);
  70         tm->tm_min = bcd2bin(rtc_data[1]);
  71         tm->tm_hour = bcd2bin(rtc_data[2]);
  72         tm->tm_mday = bcd2bin(rtc_data[3]);
  73         tm->tm_mon = bcd2bin(rtc_data[4]) - 1;
  74         tm->tm_year = bcd2bin(rtc_data[5]) + 100;
  75 
  76         return ret;
  77 }
  78 
  79 static int palmas_rtc_set_time(struct device *dev, struct rtc_time *tm)
  80 {
  81         unsigned char rtc_data[PALMAS_NUM_TIME_REGS];
  82         struct palmas *palmas = dev_get_drvdata(dev->parent);
  83         int ret;
  84 
  85         rtc_data[0] = bin2bcd(tm->tm_sec);
  86         rtc_data[1] = bin2bcd(tm->tm_min);
  87         rtc_data[2] = bin2bcd(tm->tm_hour);
  88         rtc_data[3] = bin2bcd(tm->tm_mday);
  89         rtc_data[4] = bin2bcd(tm->tm_mon + 1);
  90         rtc_data[5] = bin2bcd(tm->tm_year - 100);
  91 
  92         /* Stop RTC while updating the RTC time registers */
  93         ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
  94                 PALMAS_RTC_CTRL_REG_STOP_RTC, 0);
  95         if (ret < 0) {
  96                 dev_err(dev, "RTC stop failed, err = %d\n", ret);
  97                 return ret;
  98         }
  99 
 100         ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE, PALMAS_SECONDS_REG,
 101                 rtc_data, PALMAS_NUM_TIME_REGS);
 102         if (ret < 0) {
 103                 dev_err(dev, "RTC_SECONDS reg write failed, err = %d\n", ret);
 104                 return ret;
 105         }
 106 
 107         /* Start back RTC */
 108         ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
 109                 PALMAS_RTC_CTRL_REG_STOP_RTC, PALMAS_RTC_CTRL_REG_STOP_RTC);
 110         if (ret < 0)
 111                 dev_err(dev, "RTC start failed, err = %d\n", ret);
 112         return ret;
 113 }
 114 
 115 static int palmas_rtc_alarm_irq_enable(struct device *dev, unsigned enabled)
 116 {
 117         struct palmas *palmas = dev_get_drvdata(dev->parent);
 118         u8 val;
 119 
 120         val = enabled ? PALMAS_RTC_INTERRUPTS_REG_IT_ALARM : 0;
 121         return palmas_write(palmas, PALMAS_RTC_BASE,
 122                 PALMAS_RTC_INTERRUPTS_REG, val);
 123 }
 124 
 125 static int palmas_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alm)
 126 {
 127         unsigned char alarm_data[PALMAS_NUM_TIME_REGS];
 128         u32 int_val;
 129         struct palmas *palmas = dev_get_drvdata(dev->parent);
 130         int ret;
 131 
 132         ret = palmas_bulk_read(palmas, PALMAS_RTC_BASE,
 133                         PALMAS_ALARM_SECONDS_REG,
 134                         alarm_data, PALMAS_NUM_TIME_REGS);
 135         if (ret < 0) {
 136                 dev_err(dev, "RTC_ALARM_SECONDS read failed, err = %d\n", ret);
 137                 return ret;
 138         }
 139 
 140         alm->time.tm_sec = bcd2bin(alarm_data[0]);
 141         alm->time.tm_min = bcd2bin(alarm_data[1]);
 142         alm->time.tm_hour = bcd2bin(alarm_data[2]);
 143         alm->time.tm_mday = bcd2bin(alarm_data[3]);
 144         alm->time.tm_mon = bcd2bin(alarm_data[4]) - 1;
 145         alm->time.tm_year = bcd2bin(alarm_data[5]) + 100;
 146 
 147         ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_INTERRUPTS_REG,
 148                         &int_val);
 149         if (ret < 0) {
 150                 dev_err(dev, "RTC_INTERRUPTS reg read failed, err = %d\n", ret);
 151                 return ret;
 152         }
 153 
 154         if (int_val & PALMAS_RTC_INTERRUPTS_REG_IT_ALARM)
 155                 alm->enabled = 1;
 156         return ret;
 157 }
 158 
 159 static int palmas_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
 160 {
 161         unsigned char alarm_data[PALMAS_NUM_TIME_REGS];
 162         struct palmas *palmas = dev_get_drvdata(dev->parent);
 163         int ret;
 164 
 165         ret = palmas_rtc_alarm_irq_enable(dev, 0);
 166         if (ret < 0) {
 167                 dev_err(dev, "Disable RTC alarm failed\n");
 168                 return ret;
 169         }
 170 
 171         alarm_data[0] = bin2bcd(alm->time.tm_sec);
 172         alarm_data[1] = bin2bcd(alm->time.tm_min);
 173         alarm_data[2] = bin2bcd(alm->time.tm_hour);
 174         alarm_data[3] = bin2bcd(alm->time.tm_mday);
 175         alarm_data[4] = bin2bcd(alm->time.tm_mon + 1);
 176         alarm_data[5] = bin2bcd(alm->time.tm_year - 100);
 177 
 178         ret = palmas_bulk_write(palmas, PALMAS_RTC_BASE,
 179                 PALMAS_ALARM_SECONDS_REG, alarm_data, PALMAS_NUM_TIME_REGS);
 180         if (ret < 0) {
 181                 dev_err(dev, "ALARM_SECONDS_REG write failed, err = %d\n", ret);
 182                 return ret;
 183         }
 184 
 185         if (alm->enabled)
 186                 ret = palmas_rtc_alarm_irq_enable(dev, 1);
 187         return ret;
 188 }
 189 
 190 static int palmas_clear_interrupts(struct device *dev)
 191 {
 192         struct palmas *palmas = dev_get_drvdata(dev->parent);
 193         unsigned int rtc_reg;
 194         int ret;
 195 
 196         ret = palmas_read(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
 197                                 &rtc_reg);
 198         if (ret < 0) {
 199                 dev_err(dev, "RTC_STATUS read failed, err = %d\n", ret);
 200                 return ret;
 201         }
 202 
 203         ret = palmas_write(palmas, PALMAS_RTC_BASE, PALMAS_RTC_STATUS_REG,
 204                         rtc_reg);
 205         if (ret < 0) {
 206                 dev_err(dev, "RTC_STATUS write failed, err = %d\n", ret);
 207                 return ret;
 208         }
 209         return 0;
 210 }
 211 
 212 static irqreturn_t palmas_rtc_interrupt(int irq, void *context)
 213 {
 214         struct palmas_rtc *palmas_rtc = context;
 215         struct device *dev = palmas_rtc->dev;
 216         int ret;
 217 
 218         ret = palmas_clear_interrupts(dev);
 219         if (ret < 0) {
 220                 dev_err(dev, "RTC interrupt clear failed, err = %d\n", ret);
 221                 return IRQ_NONE;
 222         }
 223 
 224         rtc_update_irq(palmas_rtc->rtc, 1, RTC_IRQF | RTC_AF);
 225         return IRQ_HANDLED;
 226 }
 227 
 228 static const struct rtc_class_ops palmas_rtc_ops = {
 229         .read_time      = palmas_rtc_read_time,
 230         .set_time       = palmas_rtc_set_time,
 231         .read_alarm     = palmas_rtc_read_alarm,
 232         .set_alarm      = palmas_rtc_set_alarm,
 233         .alarm_irq_enable = palmas_rtc_alarm_irq_enable,
 234 };
 235 
 236 static int palmas_rtc_probe(struct platform_device *pdev)
 237 {
 238         struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
 239         struct palmas_rtc *palmas_rtc = NULL;
 240         int ret;
 241         bool enable_bb_charging = false;
 242         bool high_bb_charging = false;
 243 
 244         if (pdev->dev.of_node) {
 245                 enable_bb_charging = of_property_read_bool(pdev->dev.of_node,
 246                                         "ti,backup-battery-chargeable");
 247                 high_bb_charging = of_property_read_bool(pdev->dev.of_node,
 248                                         "ti,backup-battery-charge-high-current");
 249         }
 250 
 251         palmas_rtc = devm_kzalloc(&pdev->dev, sizeof(struct palmas_rtc),
 252                         GFP_KERNEL);
 253         if (!palmas_rtc)
 254                 return -ENOMEM;
 255 
 256         /* Clear pending interrupts */
 257         ret = palmas_clear_interrupts(&pdev->dev);
 258         if (ret < 0) {
 259                 dev_err(&pdev->dev, "clear RTC int failed, err = %d\n", ret);
 260                 return ret;
 261         }
 262 
 263         palmas_rtc->dev = &pdev->dev;
 264         platform_set_drvdata(pdev, palmas_rtc);
 265 
 266         if (enable_bb_charging) {
 267                 unsigned reg = PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG;
 268 
 269                 if (high_bb_charging)
 270                         reg = 0;
 271 
 272                 ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
 273                         PALMAS_BACKUP_BATTERY_CTRL,
 274                         PALMAS_BACKUP_BATTERY_CTRL_BBS_BBC_LOW_ICHRG, reg);
 275                 if (ret < 0) {
 276                         dev_err(&pdev->dev,
 277                                 "BACKUP_BATTERY_CTRL update failed, %d\n", ret);
 278                         return ret;
 279                 }
 280 
 281                 ret = palmas_update_bits(palmas, PALMAS_PMU_CONTROL_BASE,
 282                         PALMAS_BACKUP_BATTERY_CTRL,
 283                         PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN,
 284                         PALMAS_BACKUP_BATTERY_CTRL_BB_CHG_EN);
 285                 if (ret < 0) {
 286                         dev_err(&pdev->dev,
 287                                 "BACKUP_BATTERY_CTRL update failed, %d\n", ret);
 288                         return ret;
 289                 }
 290         }
 291 
 292         /* Start RTC */
 293         ret = palmas_update_bits(palmas, PALMAS_RTC_BASE, PALMAS_RTC_CTRL_REG,
 294                         PALMAS_RTC_CTRL_REG_STOP_RTC,
 295                         PALMAS_RTC_CTRL_REG_STOP_RTC);
 296         if (ret < 0) {
 297                 dev_err(&pdev->dev, "RTC_CTRL write failed, err = %d\n", ret);
 298                 return ret;
 299         }
 300 
 301         palmas_rtc->irq = platform_get_irq(pdev, 0);
 302 
 303         device_init_wakeup(&pdev->dev, 1);
 304         palmas_rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name,
 305                                 &palmas_rtc_ops, THIS_MODULE);
 306         if (IS_ERR(palmas_rtc->rtc)) {
 307                 ret = PTR_ERR(palmas_rtc->rtc);
 308                 dev_err(&pdev->dev, "RTC register failed, err = %d\n", ret);
 309                 return ret;
 310         }
 311 
 312         ret = devm_request_threaded_irq(&pdev->dev, palmas_rtc->irq, NULL,
 313                         palmas_rtc_interrupt,
 314                         IRQF_TRIGGER_LOW | IRQF_ONESHOT,
 315                         dev_name(&pdev->dev), palmas_rtc);
 316         if (ret < 0) {
 317                 dev_err(&pdev->dev, "IRQ request failed, err = %d\n", ret);
 318                 return ret;
 319         }
 320 
 321         return 0;
 322 }
 323 
 324 static int palmas_rtc_remove(struct platform_device *pdev)
 325 {
 326         palmas_rtc_alarm_irq_enable(&pdev->dev, 0);
 327         return 0;
 328 }
 329 
 330 #ifdef CONFIG_PM_SLEEP
 331 static int palmas_rtc_suspend(struct device *dev)
 332 {
 333         struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev);
 334 
 335         if (device_may_wakeup(dev))
 336                 enable_irq_wake(palmas_rtc->irq);
 337         return 0;
 338 }
 339 
 340 static int palmas_rtc_resume(struct device *dev)
 341 {
 342         struct palmas_rtc *palmas_rtc = dev_get_drvdata(dev);
 343 
 344         if (device_may_wakeup(dev))
 345                 disable_irq_wake(palmas_rtc->irq);
 346         return 0;
 347 }
 348 #endif
 349 
 350 static SIMPLE_DEV_PM_OPS(palmas_rtc_pm_ops, palmas_rtc_suspend,
 351                          palmas_rtc_resume);
 352 
 353 #ifdef CONFIG_OF
 354 static const struct of_device_id of_palmas_rtc_match[] = {
 355         { .compatible = "ti,palmas-rtc"},
 356         { },
 357 };
 358 MODULE_DEVICE_TABLE(of, of_palmas_rtc_match);
 359 #endif
 360 
 361 static struct platform_driver palmas_rtc_driver = {
 362         .probe          = palmas_rtc_probe,
 363         .remove         = palmas_rtc_remove,
 364         .driver         = {
 365                 .name   = "palmas-rtc",
 366                 .pm     = &palmas_rtc_pm_ops,
 367                 .of_match_table = of_match_ptr(of_palmas_rtc_match),
 368         },
 369 };
 370 
 371 module_platform_driver(palmas_rtc_driver);
 372 
 373 MODULE_ALIAS("platform:palmas_rtc");
 374 MODULE_DESCRIPTION("TI PALMAS series RTC driver");
 375 MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");
 376 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */