linux/drivers/rtc/rtc-pcf2127.c
<<
>>
Prefs
   1/*
   2 * An I2C and SPI driver for the NXP PCF2127/29 RTC
   3 * Copyright 2013 Til-Technologies
   4 *
   5 * Author: Renaud Cerrato <r.cerrato@til-technologies.fr>
   6 *
   7 * based on the other drivers in this same directory.
   8 *
   9 * Datasheet: http://cache.nxp.com/documents/data_sheet/PCF2127.pdf
  10 *
  11 * This program is free software; you can redistribute it and/or modify
  12 * it under the terms of the GNU General Public License version 2 as
  13 * published by the Free Software Foundation.
  14 */
  15
  16#include <linux/i2c.h>
  17#include <linux/spi/spi.h>
  18#include <linux/bcd.h>
  19#include <linux/rtc.h>
  20#include <linux/slab.h>
  21#include <linux/module.h>
  22#include <linux/of.h>
  23#include <linux/regmap.h>
  24
  25#define PCF2127_REG_CTRL1       (0x00)  /* Control Register 1 */
  26#define PCF2127_REG_CTRL2       (0x01)  /* Control Register 2 */
  27
  28#define PCF2127_REG_CTRL3       (0x02)  /* Control Register 3 */
  29#define PCF2127_REG_CTRL3_BLF           BIT(2)
  30
  31#define PCF2127_REG_SC          (0x03)  /* datetime */
  32#define PCF2127_REG_MN          (0x04)
  33#define PCF2127_REG_HR          (0x05)
  34#define PCF2127_REG_DM          (0x06)
  35#define PCF2127_REG_DW          (0x07)
  36#define PCF2127_REG_MO          (0x08)
  37#define PCF2127_REG_YR          (0x09)
  38
  39#define PCF2127_OSF             BIT(7)  /* Oscillator Fail flag */
  40
  41struct pcf2127 {
  42        struct rtc_device *rtc;
  43        struct regmap *regmap;
  44};
  45
  46/*
  47 * In the routines that deal directly with the pcf2127 hardware, we use
  48 * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch.
  49 */
  50static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm)
  51{
  52        struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
  53        unsigned char buf[10];
  54        int ret;
  55        int i;
  56
  57        for (i = 0; i <= PCF2127_REG_CTRL3; i++) {
  58                ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL1 + i,
  59                                  (unsigned int *)(buf + i));
  60                if (ret) {
  61                        dev_err(dev, "%s: read error\n", __func__);
  62                        return ret;
  63                }
  64        }
  65
  66        ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_SC,
  67                               (buf + PCF2127_REG_SC),
  68                               ARRAY_SIZE(buf) - PCF2127_REG_SC);
  69        if (ret) {
  70                dev_err(dev, "%s: read error\n", __func__);
  71                return ret;
  72        }
  73
  74        if (buf[PCF2127_REG_CTRL3] & PCF2127_REG_CTRL3_BLF)
  75                dev_info(dev,
  76                        "low voltage detected, check/replace RTC battery.\n");
  77
  78        if (buf[PCF2127_REG_SC] & PCF2127_OSF) {
  79                /*
  80                 * no need clear the flag here,
  81                 * it will be cleared once the new date is saved
  82                 */
  83                dev_warn(dev,
  84                         "oscillator stop detected, date/time is not reliable\n");
  85                return -EINVAL;
  86        }
  87
  88        dev_dbg(dev,
  89                "%s: raw data is cr1=%02x, cr2=%02x, cr3=%02x, "
  90                "sec=%02x, min=%02x, hr=%02x, "
  91                "mday=%02x, wday=%02x, mon=%02x, year=%02x\n",
  92                __func__,
  93                buf[0], buf[1], buf[2],
  94                buf[3], buf[4], buf[5],
  95                buf[6], buf[7], buf[8], buf[9]);
  96
  97
  98        tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F);
  99        tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F);
 100        tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); /* rtc hr 0-23 */
 101        tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F);
 102        tm->tm_wday = buf[PCF2127_REG_DW] & 0x07;
 103        tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
 104        tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]);
 105        if (tm->tm_year < 70)
 106                tm->tm_year += 100;     /* assume we are in 1970...2069 */
 107
 108        dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 109                "mday=%d, mon=%d, year=%d, wday=%d\n",
 110                __func__,
 111                tm->tm_sec, tm->tm_min, tm->tm_hour,
 112                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 113
 114        return 0;
 115}
 116
 117static int pcf2127_rtc_set_time(struct device *dev, struct rtc_time *tm)
 118{
 119        struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
 120        unsigned char buf[7];
 121        int i = 0, err;
 122
 123        dev_dbg(dev, "%s: secs=%d, mins=%d, hours=%d, "
 124                "mday=%d, mon=%d, year=%d, wday=%d\n",
 125                __func__,
 126                tm->tm_sec, tm->tm_min, tm->tm_hour,
 127                tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 128
 129        /* hours, minutes and seconds */
 130        buf[i++] = bin2bcd(tm->tm_sec); /* this will also clear OSF flag */
 131        buf[i++] = bin2bcd(tm->tm_min);
 132        buf[i++] = bin2bcd(tm->tm_hour);
 133        buf[i++] = bin2bcd(tm->tm_mday);
 134        buf[i++] = tm->tm_wday & 0x07;
 135
 136        /* month, 1 - 12 */
 137        buf[i++] = bin2bcd(tm->tm_mon + 1);
 138
 139        /* year */
 140        buf[i++] = bin2bcd(tm->tm_year % 100);
 141
 142        /* write register's data */
 143        err = regmap_bulk_write(pcf2127->regmap, PCF2127_REG_SC, buf, i);
 144        if (err) {
 145                dev_err(dev,
 146                        "%s: err=%d", __func__, err);
 147                return err;
 148        }
 149
 150        return 0;
 151}
 152
 153#ifdef CONFIG_RTC_INTF_DEV
 154static int pcf2127_rtc_ioctl(struct device *dev,
 155                                unsigned int cmd, unsigned long arg)
 156{
 157        struct pcf2127 *pcf2127 = dev_get_drvdata(dev);
 158        int touser;
 159        int ret;
 160
 161        switch (cmd) {
 162        case RTC_VL_READ:
 163                ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL3, &touser);
 164                if (ret)
 165                        return ret;
 166
 167                touser = touser & PCF2127_REG_CTRL3_BLF ? 1 : 0;
 168
 169                if (copy_to_user((void __user *)arg, &touser, sizeof(int)))
 170                        return -EFAULT;
 171                return 0;
 172        default:
 173                return -ENOIOCTLCMD;
 174        }
 175}
 176#else
 177#define pcf2127_rtc_ioctl NULL
 178#endif
 179
 180static const struct rtc_class_ops pcf2127_rtc_ops = {
 181        .ioctl          = pcf2127_rtc_ioctl,
 182        .read_time      = pcf2127_rtc_read_time,
 183        .set_time       = pcf2127_rtc_set_time,
 184};
 185
 186static int pcf2127_probe(struct device *dev, struct regmap *regmap,
 187                        const char *name)
 188{
 189        struct pcf2127 *pcf2127;
 190
 191        dev_dbg(dev, "%s\n", __func__);
 192
 193        pcf2127 = devm_kzalloc(dev, sizeof(*pcf2127), GFP_KERNEL);
 194        if (!pcf2127)
 195                return -ENOMEM;
 196
 197        pcf2127->regmap = regmap;
 198
 199        dev_set_drvdata(dev, pcf2127);
 200
 201        pcf2127->rtc = devm_rtc_device_register(dev, name, &pcf2127_rtc_ops,
 202                                                THIS_MODULE);
 203
 204        return PTR_ERR_OR_ZERO(pcf2127->rtc);
 205}
 206
 207#ifdef CONFIG_OF
 208static const struct of_device_id pcf2127_of_match[] = {
 209        { .compatible = "nxp,pcf2127" },
 210        { .compatible = "nxp,pcf2129" },
 211        {}
 212};
 213MODULE_DEVICE_TABLE(of, pcf2127_of_match);
 214#endif
 215
 216#if IS_ENABLED(CONFIG_I2C)
 217
 218static int pcf2127_i2c_write(void *context, const void *data, size_t count)
 219{
 220        struct device *dev = context;
 221        struct i2c_client *client = to_i2c_client(dev);
 222        int ret;
 223
 224        ret = i2c_master_send(client, data, count);
 225        if (ret != count)
 226                return ret < 0 ? ret : -EIO;
 227
 228        return 0;
 229}
 230
 231static int pcf2127_i2c_gather_write(void *context,
 232                                const void *reg, size_t reg_size,
 233                                const void *val, size_t val_size)
 234{
 235        struct device *dev = context;
 236        struct i2c_client *client = to_i2c_client(dev);
 237        int ret;
 238        void *buf;
 239
 240        if (WARN_ON(reg_size != 1))
 241                return -EINVAL;
 242
 243        buf = kmalloc(val_size + 1, GFP_KERNEL);
 244        if (!buf)
 245                return -ENOMEM;
 246
 247        memcpy(buf, reg, 1);
 248        memcpy(buf + 1, val, val_size);
 249
 250        ret = i2c_master_send(client, buf, val_size + 1);
 251        if (ret != val_size + 1)
 252                return ret < 0 ? ret : -EIO;
 253
 254        return 0;
 255}
 256
 257static int pcf2127_i2c_read(void *context, const void *reg, size_t reg_size,
 258                                void *val, size_t val_size)
 259{
 260        struct device *dev = context;
 261        struct i2c_client *client = to_i2c_client(dev);
 262        int ret;
 263
 264        if (WARN_ON(reg_size != 1))
 265                return -EINVAL;
 266
 267        ret = i2c_master_send(client, reg, 1);
 268        if (ret != 1)
 269                return ret < 0 ? ret : -EIO;
 270
 271        ret = i2c_master_recv(client, val, val_size);
 272        if (ret != val_size)
 273                return ret < 0 ? ret : -EIO;
 274
 275        return 0;
 276}
 277
 278/*
 279 * The reason we need this custom regmap_bus instead of using regmap_init_i2c()
 280 * is that the STOP condition is required between set register address and
 281 * read register data when reading from registers.
 282 */
 283static const struct regmap_bus pcf2127_i2c_regmap = {
 284        .write = pcf2127_i2c_write,
 285        .gather_write = pcf2127_i2c_gather_write,
 286        .read = pcf2127_i2c_read,
 287};
 288
 289static struct i2c_driver pcf2127_i2c_driver;
 290
 291static int pcf2127_i2c_probe(struct i2c_client *client,
 292                                const struct i2c_device_id *id)
 293{
 294        struct regmap *regmap;
 295        static const struct regmap_config config = {
 296                .reg_bits = 8,
 297                .val_bits = 8,
 298        };
 299
 300        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 301                return -ENODEV;
 302
 303        regmap = devm_regmap_init(&client->dev, &pcf2127_i2c_regmap,
 304                                        &client->dev, &config);
 305        if (IS_ERR(regmap)) {
 306                dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
 307                        __func__, PTR_ERR(regmap));
 308                return PTR_ERR(regmap);
 309        }
 310
 311        return pcf2127_probe(&client->dev, regmap,
 312                                pcf2127_i2c_driver.driver.name);
 313}
 314
 315static const struct i2c_device_id pcf2127_i2c_id[] = {
 316        { "pcf2127", 0 },
 317        { "pcf2129", 0 },
 318        { }
 319};
 320MODULE_DEVICE_TABLE(i2c, pcf2127_i2c_id);
 321
 322static struct i2c_driver pcf2127_i2c_driver = {
 323        .driver         = {
 324                .name   = "rtc-pcf2127-i2c",
 325                .of_match_table = of_match_ptr(pcf2127_of_match),
 326        },
 327        .probe          = pcf2127_i2c_probe,
 328        .id_table       = pcf2127_i2c_id,
 329};
 330
 331static int pcf2127_i2c_register_driver(void)
 332{
 333        return i2c_add_driver(&pcf2127_i2c_driver);
 334}
 335
 336static void pcf2127_i2c_unregister_driver(void)
 337{
 338        i2c_del_driver(&pcf2127_i2c_driver);
 339}
 340
 341#else
 342
 343static int pcf2127_i2c_register_driver(void)
 344{
 345        return 0;
 346}
 347
 348static void pcf2127_i2c_unregister_driver(void)
 349{
 350}
 351
 352#endif
 353
 354#if IS_ENABLED(CONFIG_SPI_MASTER)
 355
 356static struct spi_driver pcf2127_spi_driver;
 357
 358static int pcf2127_spi_probe(struct spi_device *spi)
 359{
 360        static const struct regmap_config config = {
 361                .reg_bits = 8,
 362                .val_bits = 8,
 363                .read_flag_mask = 0xa0,
 364                .write_flag_mask = 0x20,
 365        };
 366        struct regmap *regmap;
 367
 368        regmap = devm_regmap_init_spi(spi, &config);
 369        if (IS_ERR(regmap)) {
 370                dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
 371                        __func__, PTR_ERR(regmap));
 372                return PTR_ERR(regmap);
 373        }
 374
 375        return pcf2127_probe(&spi->dev, regmap, pcf2127_spi_driver.driver.name);
 376}
 377
 378static const struct spi_device_id pcf2127_spi_id[] = {
 379        { "pcf2127", 0 },
 380        { "pcf2129", 0 },
 381        { }
 382};
 383MODULE_DEVICE_TABLE(spi, pcf2127_spi_id);
 384
 385static struct spi_driver pcf2127_spi_driver = {
 386        .driver         = {
 387                .name   = "rtc-pcf2127-spi",
 388                .of_match_table = of_match_ptr(pcf2127_of_match),
 389        },
 390        .probe          = pcf2127_spi_probe,
 391        .id_table       = pcf2127_spi_id,
 392};
 393
 394static int pcf2127_spi_register_driver(void)
 395{
 396        return spi_register_driver(&pcf2127_spi_driver);
 397}
 398
 399static void pcf2127_spi_unregister_driver(void)
 400{
 401        spi_unregister_driver(&pcf2127_spi_driver);
 402}
 403
 404#else
 405
 406static int pcf2127_spi_register_driver(void)
 407{
 408        return 0;
 409}
 410
 411static void pcf2127_spi_unregister_driver(void)
 412{
 413}
 414
 415#endif
 416
 417static int __init pcf2127_init(void)
 418{
 419        int ret;
 420
 421        ret = pcf2127_i2c_register_driver();
 422        if (ret) {
 423                pr_err("Failed to register pcf2127 i2c driver: %d\n", ret);
 424                return ret;
 425        }
 426
 427        ret = pcf2127_spi_register_driver();
 428        if (ret) {
 429                pr_err("Failed to register pcf2127 spi driver: %d\n", ret);
 430                pcf2127_i2c_unregister_driver();
 431        }
 432
 433        return ret;
 434}
 435module_init(pcf2127_init)
 436
 437static void __exit pcf2127_exit(void)
 438{
 439        pcf2127_spi_unregister_driver();
 440        pcf2127_i2c_unregister_driver();
 441}
 442module_exit(pcf2127_exit)
 443
 444MODULE_AUTHOR("Renaud Cerrato <r.cerrato@til-technologies.fr>");
 445MODULE_DESCRIPTION("NXP PCF2127/29 RTC driver");
 446MODULE_LICENSE("GPL v2");
 447