linux/drivers/rtc/rtc-rx6110.c
<<
>>
Prefs
   1/*
   2 * Driver for the Epson RTC module RX-6110 SA
   3 *
   4 * Copyright(C) 2015 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>
   5 * Copyright(C) SEIKO EPSON CORPORATION 2013. All rights reserved.
   6 *
   7 * This driver software is distributed as is, without any warranty of any kind,
   8 * either express or implied as further specified in the GNU Public License.
   9 * This software may be used and distributed according to the terms of the GNU
  10 * Public License, version 2 as published by the Free Software Foundation.
  11 * See the file COPYING in the main directory of this archive for more details.
  12 *
  13 * You should have received a copy of the GNU General Public License along with
  14 * this program. If not, see <http://www.gnu.org/licenses/>.
  15 */
  16
  17#include <linux/bcd.h>
  18#include <linux/init.h>
  19#include <linux/kernel.h>
  20#include <linux/module.h>
  21#include <linux/of_gpio.h>
  22#include <linux/regmap.h>
  23#include <linux/rtc.h>
  24#include <linux/spi/spi.h>
  25
  26/* RX-6110 Register definitions */
  27#define RX6110_REG_SEC          0x10
  28#define RX6110_REG_MIN          0x11
  29#define RX6110_REG_HOUR         0x12
  30#define RX6110_REG_WDAY         0x13
  31#define RX6110_REG_MDAY         0x14
  32#define RX6110_REG_MONTH        0x15
  33#define RX6110_REG_YEAR         0x16
  34#define RX6110_REG_RES1         0x17
  35#define RX6110_REG_ALMIN        0x18
  36#define RX6110_REG_ALHOUR       0x19
  37#define RX6110_REG_ALWDAY       0x1A
  38#define RX6110_REG_TCOUNT0      0x1B
  39#define RX6110_REG_TCOUNT1      0x1C
  40#define RX6110_REG_EXT          0x1D
  41#define RX6110_REG_FLAG         0x1E
  42#define RX6110_REG_CTRL         0x1F
  43#define RX6110_REG_USER0        0x20
  44#define RX6110_REG_USER1        0x21
  45#define RX6110_REG_USER2        0x22
  46#define RX6110_REG_USER3        0x23
  47#define RX6110_REG_USER4        0x24
  48#define RX6110_REG_USER5        0x25
  49#define RX6110_REG_USER6        0x26
  50#define RX6110_REG_USER7        0x27
  51#define RX6110_REG_USER8        0x28
  52#define RX6110_REG_USER9        0x29
  53#define RX6110_REG_USERA        0x2A
  54#define RX6110_REG_USERB        0x2B
  55#define RX6110_REG_USERC        0x2C
  56#define RX6110_REG_USERD        0x2D
  57#define RX6110_REG_USERE        0x2E
  58#define RX6110_REG_USERF        0x2F
  59#define RX6110_REG_RES2         0x30
  60#define RX6110_REG_RES3         0x31
  61#define RX6110_REG_IRQ          0x32
  62
  63#define RX6110_BIT_ALARM_EN             BIT(7)
  64
  65/* Extension Register (1Dh) bit positions */
  66#define RX6110_BIT_EXT_TSEL0            BIT(0)
  67#define RX6110_BIT_EXT_TSEL1            BIT(1)
  68#define RX6110_BIT_EXT_TSEL2            BIT(2)
  69#define RX6110_BIT_EXT_WADA             BIT(3)
  70#define RX6110_BIT_EXT_TE               BIT(4)
  71#define RX6110_BIT_EXT_USEL             BIT(5)
  72#define RX6110_BIT_EXT_FSEL0            BIT(6)
  73#define RX6110_BIT_EXT_FSEL1            BIT(7)
  74
  75/* Flag Register (1Eh) bit positions */
  76#define RX6110_BIT_FLAG_VLF             BIT(1)
  77#define RX6110_BIT_FLAG_AF              BIT(3)
  78#define RX6110_BIT_FLAG_TF              BIT(4)
  79#define RX6110_BIT_FLAG_UF              BIT(5)
  80
  81/* Control Register (1Fh) bit positions */
  82#define RX6110_BIT_CTRL_TBKE            BIT(0)
  83#define RX6110_BIT_CTRL_TBKON           BIT(1)
  84#define RX6110_BIT_CTRL_TSTP            BIT(2)
  85#define RX6110_BIT_CTRL_AIE             BIT(3)
  86#define RX6110_BIT_CTRL_TIE             BIT(4)
  87#define RX6110_BIT_CTRL_UIE             BIT(5)
  88#define RX6110_BIT_CTRL_STOP            BIT(6)
  89#define RX6110_BIT_CTRL_TEST            BIT(7)
  90
  91enum {
  92        RTC_SEC = 0,
  93        RTC_MIN,
  94        RTC_HOUR,
  95        RTC_WDAY,
  96        RTC_MDAY,
  97        RTC_MONTH,
  98        RTC_YEAR,
  99        RTC_NR_TIME
 100};
 101
 102#define RX6110_DRIVER_NAME              "rx6110"
 103
 104struct rx6110_data {
 105        struct rtc_device *rtc;
 106        struct regmap *regmap;
 107};
 108
 109/**
 110 * rx6110_rtc_tm_to_data - convert rtc_time to native time encoding
 111 *
 112 * @tm: holds date and time
 113 * @data: holds the encoding in rx6110 native form
 114 */
 115static int rx6110_rtc_tm_to_data(struct rtc_time *tm, u8 *data)
 116{
 117        pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
 118                 tm->tm_sec, tm->tm_min, tm->tm_hour,
 119                 tm->tm_mday, tm->tm_mon, tm->tm_year);
 120
 121        /*
 122         * The year in the RTC is a value between 0 and 99.
 123         * Assume that this represents the current century
 124         * and disregard all other values.
 125         */
 126        if (tm->tm_year < 100 || tm->tm_year >= 200)
 127                return -EINVAL;
 128
 129        data[RTC_SEC] = bin2bcd(tm->tm_sec);
 130        data[RTC_MIN] = bin2bcd(tm->tm_min);
 131        data[RTC_HOUR] = bin2bcd(tm->tm_hour);
 132        data[RTC_WDAY] = BIT(bin2bcd(tm->tm_wday));
 133        data[RTC_MDAY] = bin2bcd(tm->tm_mday);
 134        data[RTC_MONTH] = bin2bcd(tm->tm_mon + 1);
 135        data[RTC_YEAR] = bin2bcd(tm->tm_year % 100);
 136
 137        return 0;
 138}
 139
 140/**
 141 * rx6110_data_to_rtc_tm - convert native time encoding to rtc_time
 142 *
 143 * @data: holds the encoding in rx6110 native form
 144 * @tm: holds date and time
 145 */
 146static int rx6110_data_to_rtc_tm(u8 *data, struct rtc_time *tm)
 147{
 148        tm->tm_sec = bcd2bin(data[RTC_SEC] & 0x7f);
 149        tm->tm_min = bcd2bin(data[RTC_MIN] & 0x7f);
 150        /* only 24-hour clock */
 151        tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
 152        tm->tm_wday = ffs(data[RTC_WDAY] & 0x7f);
 153        tm->tm_mday = bcd2bin(data[RTC_MDAY] & 0x3f);
 154        tm->tm_mon = bcd2bin(data[RTC_MONTH] & 0x1f) - 1;
 155        tm->tm_year = bcd2bin(data[RTC_YEAR]) + 100;
 156
 157        pr_debug("%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
 158                 tm->tm_sec, tm->tm_min, tm->tm_hour,
 159                 tm->tm_mday, tm->tm_mon, tm->tm_year);
 160
 161        /*
 162         * The year in the RTC is a value between 0 and 99.
 163         * Assume that this represents the current century
 164         * and disregard all other values.
 165         */
 166        if (tm->tm_year < 100 || tm->tm_year >= 200)
 167                return -EINVAL;
 168
 169        return 0;
 170}
 171
 172/**
 173 * rx6110_set_time - set the current time in the rx6110 registers
 174 *
 175 * @dev: the rtc device in use
 176 * @tm: holds date and time
 177 *
 178 * BUG: The HW assumes every year that is a multiple of 4 to be a leap
 179 * year. Next time this is wrong is 2100, which will not be a leap year
 180 *
 181 * Note: If STOP is not set/cleared, the clock will start when the seconds
 182 *       register is written
 183 *
 184 */
 185static int rx6110_set_time(struct device *dev, struct rtc_time *tm)
 186{
 187        struct rx6110_data *rx6110 = dev_get_drvdata(dev);
 188        u8 data[RTC_NR_TIME];
 189        int ret;
 190
 191        ret = rx6110_rtc_tm_to_data(tm, data);
 192        if (ret < 0)
 193                return ret;
 194
 195        /* set STOP bit before changing clock/calendar */
 196        ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL,
 197                                 RX6110_BIT_CTRL_STOP, RX6110_BIT_CTRL_STOP);
 198        if (ret)
 199                return ret;
 200
 201        ret = regmap_bulk_write(rx6110->regmap, RX6110_REG_SEC, data,
 202                                RTC_NR_TIME);
 203        if (ret)
 204                return ret;
 205
 206        /* The time in the RTC is valid. Be sure to have VLF cleared. */
 207        ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG,
 208                                 RX6110_BIT_FLAG_VLF, 0);
 209        if (ret)
 210                return ret;
 211
 212        /* clear STOP bit after changing clock/calendar */
 213        ret = regmap_update_bits(rx6110->regmap, RX6110_REG_CTRL,
 214                                 RX6110_BIT_CTRL_STOP, 0);
 215
 216        return ret;
 217}
 218
 219/**
 220 * rx6110_get_time - get the current time from the rx6110 registers
 221 * @dev: the rtc device in use
 222 * @tm: holds date and time
 223 */
 224static int rx6110_get_time(struct device *dev, struct rtc_time *tm)
 225{
 226        struct rx6110_data *rx6110 = dev_get_drvdata(dev);
 227        u8 data[RTC_NR_TIME];
 228        int flags;
 229        int ret;
 230
 231        ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags);
 232        if (ret)
 233                return -EINVAL;
 234
 235        /* check for VLF Flag (set at power-on) */
 236        if ((flags & RX6110_BIT_FLAG_VLF)) {
 237                dev_warn(dev, "Voltage low, data is invalid.\n");
 238                return -EINVAL;
 239        }
 240
 241        /* read registers to date */
 242        ret = regmap_bulk_read(rx6110->regmap, RX6110_REG_SEC, data,
 243                               RTC_NR_TIME);
 244        if (ret)
 245                return ret;
 246
 247        ret = rx6110_data_to_rtc_tm(data, tm);
 248        if (ret)
 249                return ret;
 250
 251        dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__,
 252                tm->tm_sec, tm->tm_min, tm->tm_hour,
 253                tm->tm_mday, tm->tm_mon, tm->tm_year);
 254
 255        return rtc_valid_tm(tm);
 256}
 257
 258static const struct reg_sequence rx6110_default_regs[] = {
 259        { RX6110_REG_RES1,   0xB8 },
 260        { RX6110_REG_RES2,   0x00 },
 261        { RX6110_REG_RES3,   0x10 },
 262        { RX6110_REG_IRQ,    0x00 },
 263        { RX6110_REG_ALMIN,  0x00 },
 264        { RX6110_REG_ALHOUR, 0x00 },
 265        { RX6110_REG_ALWDAY, 0x00 },
 266};
 267
 268/**
 269 * rx6110_init - initialize the rx6110 registers
 270 *
 271 * @rx6110: pointer to the rx6110 struct in use
 272 *
 273 */
 274static int rx6110_init(struct rx6110_data *rx6110)
 275{
 276        struct rtc_device *rtc = rx6110->rtc;
 277        int flags;
 278        int ret;
 279
 280        ret = regmap_update_bits(rx6110->regmap, RX6110_REG_EXT,
 281                                 RX6110_BIT_EXT_TE, 0);
 282        if (ret)
 283                return ret;
 284
 285        ret = regmap_register_patch(rx6110->regmap, rx6110_default_regs,
 286                                    ARRAY_SIZE(rx6110_default_regs));
 287        if (ret)
 288                return ret;
 289
 290        ret = regmap_read(rx6110->regmap, RX6110_REG_FLAG, &flags);
 291        if (ret)
 292                return ret;
 293
 294        /* check for VLF Flag (set at power-on) */
 295        if ((flags & RX6110_BIT_FLAG_VLF))
 296                dev_warn(&rtc->dev, "Voltage low, data loss detected.\n");
 297
 298        /* check for Alarm Flag */
 299        if (flags & RX6110_BIT_FLAG_AF)
 300                dev_warn(&rtc->dev, "An alarm may have been missed.\n");
 301
 302        /* check for Periodic Timer Flag */
 303        if (flags & RX6110_BIT_FLAG_TF)
 304                dev_warn(&rtc->dev, "Periodic timer was detected\n");
 305
 306        /* check for Update Timer Flag */
 307        if (flags & RX6110_BIT_FLAG_UF)
 308                dev_warn(&rtc->dev, "Update timer was detected\n");
 309
 310        /* clear all flags BUT VLF */
 311        ret = regmap_update_bits(rx6110->regmap, RX6110_REG_FLAG,
 312                                 RX6110_BIT_FLAG_AF |
 313                                 RX6110_BIT_FLAG_UF |
 314                                 RX6110_BIT_FLAG_TF,
 315                                 0);
 316
 317        return ret;
 318}
 319
 320static const struct rtc_class_ops rx6110_rtc_ops = {
 321        .read_time = rx6110_get_time,
 322        .set_time = rx6110_set_time,
 323};
 324
 325static struct regmap_config regmap_spi_config = {
 326        .reg_bits = 8,
 327        .val_bits = 8,
 328        .max_register = RX6110_REG_IRQ,
 329        .read_flag_mask = 0x80,
 330};
 331
 332/**
 333 * rx6110_probe - initialize rtc driver
 334 * @spi: pointer to spi device
 335 */
 336static int rx6110_probe(struct spi_device *spi)
 337{
 338        struct rx6110_data *rx6110;
 339        int err;
 340
 341        if ((spi->bits_per_word && spi->bits_per_word != 8) ||
 342            (spi->max_speed_hz > 2000000) ||
 343            (spi->mode != (SPI_CS_HIGH | SPI_CPOL | SPI_CPHA))) {
 344                dev_warn(&spi->dev, "SPI settings: bits_per_word: %d, max_speed_hz: %d, mode: %xh\n",
 345                         spi->bits_per_word, spi->max_speed_hz, spi->mode);
 346                dev_warn(&spi->dev, "driving device in an unsupported mode");
 347        }
 348
 349        rx6110 = devm_kzalloc(&spi->dev, sizeof(*rx6110), GFP_KERNEL);
 350        if (!rx6110)
 351                return -ENOMEM;
 352
 353        rx6110->regmap = devm_regmap_init_spi(spi, &regmap_spi_config);
 354        if (IS_ERR(rx6110->regmap)) {
 355                dev_err(&spi->dev, "regmap init failed for rtc rx6110\n");
 356                return PTR_ERR(rx6110->regmap);
 357        }
 358
 359        spi_set_drvdata(spi, rx6110);
 360
 361        rx6110->rtc = devm_rtc_device_register(&spi->dev,
 362                                               RX6110_DRIVER_NAME,
 363                                               &rx6110_rtc_ops, THIS_MODULE);
 364
 365        if (IS_ERR(rx6110->rtc))
 366                return PTR_ERR(rx6110->rtc);
 367
 368        err = rx6110_init(rx6110);
 369        if (err)
 370                return err;
 371
 372        rx6110->rtc->max_user_freq = 1;
 373
 374        return 0;
 375}
 376
 377static int rx6110_remove(struct spi_device *spi)
 378{
 379        return 0;
 380}
 381
 382static const struct spi_device_id rx6110_id[] = {
 383        { "rx6110", 0 },
 384        { }
 385};
 386MODULE_DEVICE_TABLE(spi, rx6110_id);
 387
 388static struct spi_driver rx6110_driver = {
 389        .driver = {
 390                .name = RX6110_DRIVER_NAME,
 391        },
 392        .probe          = rx6110_probe,
 393        .remove         = rx6110_remove,
 394        .id_table       = rx6110_id,
 395};
 396
 397module_spi_driver(rx6110_driver);
 398
 399MODULE_AUTHOR("Val Krutov <val.krutov@erd.epson.com>");
 400MODULE_DESCRIPTION("RX-6110 SA RTC driver");
 401MODULE_LICENSE("GPL");
 402