linux/drivers/rtc/rtc-pcf2123.c
<<
>>
Prefs
   1/*
   2 * An SPI driver for the Philips PCF2123 RTC
   3 * Copyright 2009 Cyber Switching, Inc.
   4 *
   5 * Author: Chris Verges <chrisv@cyberswitching.com>
   6 * Maintainers: http://www.cyberswitching.com
   7 *
   8 * based on the RS5C348 driver in this same directory.
   9 *
  10 * Thanks to Christian Pellegrin <chripell@fsfe.org> for
  11 * the sysfs contributions to this driver.
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License version 2 as
  15 * published by the Free Software Foundation.
  16 *
  17 * Please note that the CS is active high, so platform data
  18 * should look something like:
  19 *
  20 * static struct spi_board_info ek_spi_devices[] = {
  21 *      ...
  22 *      {
  23 *              .modalias               = "rtc-pcf2123",
  24 *              .chip_select            = 1,
  25 *              .controller_data        = (void *)AT91_PIN_PA10,
  26 *              .max_speed_hz           = 1000 * 1000,
  27 *              .mode                   = SPI_CS_HIGH,
  28 *              .bus_num                = 0,
  29 *      },
  30 *      ...
  31 *};
  32 *
  33 */
  34
  35#include <linux/bcd.h>
  36#include <linux/delay.h>
  37#include <linux/device.h>
  38#include <linux/errno.h>
  39#include <linux/init.h>
  40#include <linux/kernel.h>
  41#include <linux/string.h>
  42#include <linux/slab.h>
  43#include <linux/rtc.h>
  44#include <linux/spi/spi.h>
  45#include <linux/module.h>
  46#include <linux/sysfs.h>
  47
  48#define DRV_VERSION "0.6"
  49
  50#define PCF2123_REG_CTRL1       (0x00)  /* Control Register 1 */
  51#define PCF2123_REG_CTRL2       (0x01)  /* Control Register 2 */
  52#define PCF2123_REG_SC          (0x02)  /* datetime */
  53#define PCF2123_REG_MN          (0x03)
  54#define PCF2123_REG_HR          (0x04)
  55#define PCF2123_REG_DM          (0x05)
  56#define PCF2123_REG_DW          (0x06)
  57#define PCF2123_REG_MO          (0x07)
  58#define PCF2123_REG_YR          (0x08)
  59
  60#define PCF2123_SUBADDR         (1 << 4)
  61#define PCF2123_WRITE           ((0 << 7) | PCF2123_SUBADDR)
  62#define PCF2123_READ            ((1 << 7) | PCF2123_SUBADDR)
  63
  64static struct spi_driver pcf2123_driver;
  65
  66struct pcf2123_sysfs_reg {
  67        struct device_attribute attr;
  68        char name[2];
  69};
  70
  71struct pcf2123_plat_data {
  72        struct rtc_device *rtc;
  73        struct pcf2123_sysfs_reg regs[16];
  74};
  75
  76/*
  77 * Causes a 30 nanosecond delay to ensure that the PCF2123 chip select
  78 * is released properly after an SPI write.  This function should be
  79 * called after EVERY read/write call over SPI.
  80 */
  81static inline void pcf2123_delay_trec(void)
  82{
  83        ndelay(30);
  84}
  85
  86static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr,
  87                            char *buffer)
  88{
  89        struct spi_device *spi = to_spi_device(dev);
  90        struct pcf2123_sysfs_reg *r;
  91        u8 txbuf[1], rxbuf[1];
  92        unsigned long reg;
  93        int ret;
  94
  95        r = container_of(attr, struct pcf2123_sysfs_reg, attr);
  96
  97        if (strict_strtoul(r->name, 16, &reg))
  98                return -EINVAL;
  99
 100        txbuf[0] = PCF2123_READ | reg;
 101        ret = spi_write_then_read(spi, txbuf, 1, rxbuf, 1);
 102        if (ret < 0)
 103                return -EIO;
 104        pcf2123_delay_trec();
 105        return sprintf(buffer, "0x%x\n", rxbuf[0]);
 106}
 107
 108static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
 109                             const char *buffer, size_t count) {
 110        struct spi_device *spi = to_spi_device(dev);
 111        struct pcf2123_sysfs_reg *r;
 112        u8 txbuf[2];
 113        unsigned long reg;
 114        unsigned long val;
 115
 116        int ret;
 117
 118        r = container_of(attr, struct pcf2123_sysfs_reg, attr);
 119
 120        if (strict_strtoul(r->name, 16, &reg)
 121                || strict_strtoul(buffer, 10, &val))
 122                return -EINVAL;
 123
 124        txbuf[0] = PCF2123_WRITE | reg;
 125        txbuf[1] = val;
 126        ret = spi_write(spi, txbuf, sizeof(txbuf));
 127        if (ret < 0)
 128                return -EIO;
 129        pcf2123_delay_trec();
 130        return count;
 131}
 132
 133static int pcf2123_rtc_read_time(struct device *dev, struct rtc_time *tm)
 134{
 135        struct spi_device *spi = to_spi_device(dev);
 136        u8 txbuf[1], rxbuf[7];
 137        int ret;
 138
 139        txbuf[0] = PCF2123_READ | PCF2123_REG_SC;
 140        ret = spi_write_then_read(spi, txbuf, sizeof(txbuf),
 141                        rxbuf, sizeof(rxbuf));
 142        if (ret < 0)
 143                return ret;
 144        pcf2123_delay_trec();
 145
 146        tm->tm_sec = bcd2bin(rxbuf[0] & 0x7F);
 147        tm->tm_min = bcd2bin(rxbuf[1] & 0x7F);
 148        tm->tm_hour = bcd2bin(rxbuf[2] & 0x3F); /* rtc hr 0-23 */
 149        tm->tm_mday = bcd2bin(rxbuf[3] & 0x3F);
 150        tm->tm_wday = rxbuf[4] & 0x07;
 151        tm->tm_mon = bcd2bin(rxbuf[5] & 0x1F) - 1; /* rtc mn 1-12 */
 152        tm->tm_year = bcd2bin(rxbuf[6]);
 153        if (tm->tm_year < 70)
 154                tm->tm_year += 100;     /* assume we are in 1970...2069 */
 155
 156        dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 157                        "mday=%d, mon=%d, year=%d, wday=%d\n",
 158                        __func__,
 159                        tm->tm_sec, tm->tm_min, tm->tm_hour,
 160                        tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 161
 162        /* the clock can give out invalid datetime, but we cannot return
 163         * -EINVAL otherwise hwclock will refuse to set the time on bootup.
 164         */
 165        if (rtc_valid_tm(tm) < 0)
 166                dev_err(dev, "retrieved date/time is not valid.\n");
 167
 168        return 0;
 169}
 170
 171static int pcf2123_rtc_set_time(struct device *dev, struct rtc_time *tm)
 172{
 173        struct spi_device *spi = to_spi_device(dev);
 174        u8 txbuf[8];
 175        int ret;
 176
 177        dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
 178                        "mday=%d, mon=%d, year=%d, wday=%d\n",
 179                        __func__,
 180                        tm->tm_sec, tm->tm_min, tm->tm_hour,
 181                        tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
 182
 183        /* Stop the counter first */
 184        txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
 185        txbuf[1] = 0x20;
 186        ret = spi_write(spi, txbuf, 2);
 187        if (ret < 0)
 188                return ret;
 189        pcf2123_delay_trec();
 190
 191        /* Set the new time */
 192        txbuf[0] = PCF2123_WRITE | PCF2123_REG_SC;
 193        txbuf[1] = bin2bcd(tm->tm_sec & 0x7F);
 194        txbuf[2] = bin2bcd(tm->tm_min & 0x7F);
 195        txbuf[3] = bin2bcd(tm->tm_hour & 0x3F);
 196        txbuf[4] = bin2bcd(tm->tm_mday & 0x3F);
 197        txbuf[5] = tm->tm_wday & 0x07;
 198        txbuf[6] = bin2bcd((tm->tm_mon + 1) & 0x1F); /* rtc mn 1-12 */
 199        txbuf[7] = bin2bcd(tm->tm_year < 100 ? tm->tm_year : tm->tm_year - 100);
 200
 201        ret = spi_write(spi, txbuf, sizeof(txbuf));
 202        if (ret < 0)
 203                return ret;
 204        pcf2123_delay_trec();
 205
 206        /* Start the counter */
 207        txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
 208        txbuf[1] = 0x00;
 209        ret = spi_write(spi, txbuf, 2);
 210        if (ret < 0)
 211                return ret;
 212        pcf2123_delay_trec();
 213
 214        return 0;
 215}
 216
 217static const struct rtc_class_ops pcf2123_rtc_ops = {
 218        .read_time      = pcf2123_rtc_read_time,
 219        .set_time       = pcf2123_rtc_set_time,
 220};
 221
 222static int pcf2123_probe(struct spi_device *spi)
 223{
 224        struct rtc_device *rtc;
 225        struct pcf2123_plat_data *pdata;
 226        u8 txbuf[2], rxbuf[2];
 227        int ret, i;
 228
 229        pdata = kzalloc(sizeof(struct pcf2123_plat_data), GFP_KERNEL);
 230        if (!pdata)
 231                return -ENOMEM;
 232        spi->dev.platform_data = pdata;
 233
 234        /* Send a software reset command */
 235        txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
 236        txbuf[1] = 0x58;
 237        dev_dbg(&spi->dev, "resetting RTC (0x%02X 0x%02X)\n",
 238                        txbuf[0], txbuf[1]);
 239        ret = spi_write(spi, txbuf, 2 * sizeof(u8));
 240        if (ret < 0)
 241                goto kfree_exit;
 242        pcf2123_delay_trec();
 243
 244        /* Stop the counter */
 245        txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
 246        txbuf[1] = 0x20;
 247        dev_dbg(&spi->dev, "stopping RTC (0x%02X 0x%02X)\n",
 248                        txbuf[0], txbuf[1]);
 249        ret = spi_write(spi, txbuf, 2 * sizeof(u8));
 250        if (ret < 0)
 251                goto kfree_exit;
 252        pcf2123_delay_trec();
 253
 254        /* See if the counter was actually stopped */
 255        txbuf[0] = PCF2123_READ | PCF2123_REG_CTRL1;
 256        dev_dbg(&spi->dev, "checking for presence of RTC (0x%02X)\n",
 257                        txbuf[0]);
 258        ret = spi_write_then_read(spi, txbuf, 1 * sizeof(u8),
 259                                        rxbuf, 2 * sizeof(u8));
 260        dev_dbg(&spi->dev, "received data from RTC (0x%02X 0x%02X)\n",
 261                        rxbuf[0], rxbuf[1]);
 262        if (ret < 0)
 263                goto kfree_exit;
 264        pcf2123_delay_trec();
 265
 266        if (!(rxbuf[0] & 0x20)) {
 267                dev_err(&spi->dev, "chip not found\n");
 268                ret = -ENODEV;
 269                goto kfree_exit;
 270        }
 271
 272        dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n");
 273        dev_info(&spi->dev, "spiclk %u KHz.\n",
 274                        (spi->max_speed_hz + 500) / 1000);
 275
 276        /* Start the counter */
 277        txbuf[0] = PCF2123_WRITE | PCF2123_REG_CTRL1;
 278        txbuf[1] = 0x00;
 279        ret = spi_write(spi, txbuf, sizeof(txbuf));
 280        if (ret < 0)
 281                goto kfree_exit;
 282        pcf2123_delay_trec();
 283
 284        /* Finalize the initialization */
 285        rtc = rtc_device_register(pcf2123_driver.driver.name, &spi->dev,
 286                        &pcf2123_rtc_ops, THIS_MODULE);
 287
 288        if (IS_ERR(rtc)) {
 289                dev_err(&spi->dev, "failed to register.\n");
 290                ret = PTR_ERR(rtc);
 291                goto kfree_exit;
 292        }
 293
 294        pdata->rtc = rtc;
 295
 296        for (i = 0; i < 16; i++) {
 297                sysfs_attr_init(&pdata->regs[i].attr.attr);
 298                sprintf(pdata->regs[i].name, "%1x", i);
 299                pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR;
 300                pdata->regs[i].attr.attr.name = pdata->regs[i].name;
 301                pdata->regs[i].attr.show = pcf2123_show;
 302                pdata->regs[i].attr.store = pcf2123_store;
 303                ret = device_create_file(&spi->dev, &pdata->regs[i].attr);
 304                if (ret) {
 305                        dev_err(&spi->dev, "Unable to create sysfs %s\n",
 306                                pdata->regs[i].name);
 307                        goto sysfs_exit;
 308                }
 309        }
 310
 311        return 0;
 312
 313sysfs_exit:
 314        for (i--; i >= 0; i--)
 315                device_remove_file(&spi->dev, &pdata->regs[i].attr);
 316
 317kfree_exit:
 318        kfree(pdata);
 319        spi->dev.platform_data = NULL;
 320        return ret;
 321}
 322
 323static int pcf2123_remove(struct spi_device *spi)
 324{
 325        struct pcf2123_plat_data *pdata = spi->dev.platform_data;
 326        int i;
 327
 328        if (pdata) {
 329                struct rtc_device *rtc = pdata->rtc;
 330
 331                if (rtc)
 332                        rtc_device_unregister(rtc);
 333                for (i = 0; i < 16; i++)
 334                        if (pdata->regs[i].name[0])
 335                                device_remove_file(&spi->dev,
 336                                                   &pdata->regs[i].attr);
 337                kfree(pdata);
 338        }
 339
 340        return 0;
 341}
 342
 343static struct spi_driver pcf2123_driver = {
 344        .driver = {
 345                        .name   = "rtc-pcf2123",
 346                        .owner  = THIS_MODULE,
 347        },
 348        .probe  = pcf2123_probe,
 349        .remove = pcf2123_remove,
 350};
 351
 352module_spi_driver(pcf2123_driver);
 353
 354MODULE_AUTHOR("Chris Verges <chrisv@cyberswitching.com>");
 355MODULE_DESCRIPTION("NXP PCF2123 RTC driver");
 356MODULE_LICENSE("GPL");
 357MODULE_VERSION(DRV_VERSION);
 358
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.