linux/drivers/rtc/rtc-s5m.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2013-2014 Samsung Electronics Co., Ltd
   3 *      http://www.samsung.com
   4 *
   5 *  Copyright (C) 2013 Google, Inc
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License as published by
   9 *  the Free Software Foundation; either version 2 of the License, or
  10 *  (at your option) any later version.
  11 *
  12 *  This program is distributed in the hope that it will be useful,
  13 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 *  GNU General Public License for more details.
  16 */
  17
  18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  19
  20#include <linux/module.h>
  21#include <linux/i2c.h>
  22#include <linux/bcd.h>
  23#include <linux/regmap.h>
  24#include <linux/rtc.h>
  25#include <linux/platform_device.h>
  26#include <linux/mfd/samsung/core.h>
  27#include <linux/mfd/samsung/irq.h>
  28#include <linux/mfd/samsung/rtc.h>
  29#include <linux/mfd/samsung/s2mps14.h>
  30
  31/*
  32 * Maximum number of retries for checking changes in UDR field
  33 * of S5M_RTC_UDR_CON register (to limit possible endless loop).
  34 *
  35 * After writing to RTC registers (setting time or alarm) read the UDR field
  36 * in S5M_RTC_UDR_CON register. UDR is auto-cleared when data have
  37 * been transferred.
  38 */
  39#define UDR_READ_RETRY_CNT      5
  40
  41/* Registers used by the driver which are different between chipsets. */
  42struct s5m_rtc_reg_config {
  43        /* Number of registers used for setting time/alarm0/alarm1 */
  44        unsigned int regs_count;
  45        /* First register for time, seconds */
  46        unsigned int time;
  47        /* RTC control register */
  48        unsigned int ctrl;
  49        /* First register for alarm 0, seconds */
  50        unsigned int alarm0;
  51        /* First register for alarm 1, seconds */
  52        unsigned int alarm1;
  53        /*
  54         * Register for update flag (UDR). Typically setting UDR field to 1
  55         * will enable update of time or alarm register. Then it will be
  56         * auto-cleared after successful update.
  57         */
  58        unsigned int rtc_udr_update;
  59        /* Mask for UDR field in 'rtc_udr_update' register */
  60        unsigned int rtc_udr_mask;
  61};
  62
  63/* Register map for S5M8763 and S5M8767 */
  64static const struct s5m_rtc_reg_config s5m_rtc_regs = {
  65        .regs_count             = 8,
  66        .time                   = S5M_RTC_SEC,
  67        .ctrl                   = S5M_ALARM1_CONF,
  68        .alarm0                 = S5M_ALARM0_SEC,
  69        .alarm1                 = S5M_ALARM1_SEC,
  70        .rtc_udr_update         = S5M_RTC_UDR_CON,
  71        .rtc_udr_mask           = S5M_RTC_UDR_MASK,
  72};
  73
  74/*
  75 * Register map for S2MPS14.
  76 * It may be also suitable for S2MPS11 but this was not tested.
  77 */
  78static const struct s5m_rtc_reg_config s2mps_rtc_regs = {
  79        .regs_count             = 7,
  80        .time                   = S2MPS_RTC_SEC,
  81        .ctrl                   = S2MPS_RTC_CTRL,
  82        .alarm0                 = S2MPS_ALARM0_SEC,
  83        .alarm1                 = S2MPS_ALARM1_SEC,
  84        .rtc_udr_update         = S2MPS_RTC_UDR_CON,
  85        .rtc_udr_mask           = S2MPS_RTC_WUDR_MASK,
  86};
  87
  88struct s5m_rtc_info {
  89        struct device *dev;
  90        struct i2c_client *i2c;
  91        struct sec_pmic_dev *s5m87xx;
  92        struct regmap *regmap;
  93        struct rtc_device *rtc_dev;
  94        int irq;
  95        enum sec_device_type device_type;
  96        int rtc_24hr_mode;
  97        const struct s5m_rtc_reg_config *regs;
  98};
  99
 100static const struct regmap_config s5m_rtc_regmap_config = {
 101        .reg_bits = 8,
 102        .val_bits = 8,
 103
 104        .max_register = S5M_RTC_REG_MAX,
 105};
 106
 107static const struct regmap_config s2mps14_rtc_regmap_config = {
 108        .reg_bits = 8,
 109        .val_bits = 8,
 110
 111        .max_register = S2MPS_RTC_REG_MAX,
 112};
 113
 114static void s5m8767_data_to_tm(u8 *data, struct rtc_time *tm,
 115                               int rtc_24hr_mode)
 116{
 117        tm->tm_sec = data[RTC_SEC] & 0x7f;
 118        tm->tm_min = data[RTC_MIN] & 0x7f;
 119        if (rtc_24hr_mode) {
 120                tm->tm_hour = data[RTC_HOUR] & 0x1f;
 121        } else {
 122                tm->tm_hour = data[RTC_HOUR] & 0x0f;
 123                if (data[RTC_HOUR] & HOUR_PM_MASK)
 124                        tm->tm_hour += 12;
 125        }
 126
 127        tm->tm_wday = ffs(data[RTC_WEEKDAY] & 0x7f);
 128        tm->tm_mday = data[RTC_DATE] & 0x1f;
 129        tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1;
 130        tm->tm_year = (data[RTC_YEAR1] & 0x7f) + 100;
 131        tm->tm_yday = 0;
 132        tm->tm_isdst = 0;
 133}
 134
 135static int s5m8767_tm_to_data(struct rtc_time *tm, u8 *data)
 136{
 137        data[RTC_SEC] = tm->tm_sec;
 138        data[RTC_MIN] = tm->tm_min;
 139
 140        if (tm->tm_hour >= 12)
 141                data[RTC_HOUR] = tm->tm_hour | HOUR_PM_MASK;
 142        else
 143                data[RTC_HOUR] = tm->tm_hour & ~HOUR_PM_MASK;
 144
 145        data[RTC_WEEKDAY] = 1 << tm->tm_wday;
 146        data[RTC_DATE] = tm->tm_mday;
 147        data[RTC_MONTH] = tm->tm_mon + 1;
 148        data[RTC_YEAR1] = tm->tm_year > 100 ? (tm->tm_year - 100) : 0;
 149
 150        if (tm->tm_year < 100) {
 151                pr_err("RTC cannot handle the year %d\n",
 152                       1900 + tm->tm_year);
 153                return -EINVAL;
 154        } else {
 155                return 0;
 156        }
 157}
 158
 159/*
 160 * Read RTC_UDR_CON register and wait till UDR field is cleared.
 161 * This indicates that time/alarm update ended.
 162 */
 163static inline int s5m8767_wait_for_udr_update(struct s5m_rtc_info *info)
 164{
 165        int ret, retry = UDR_READ_RETRY_CNT;
 166        unsigned int data;
 167
 168        do {
 169                ret = regmap_read(info->regmap, info->regs->rtc_udr_update,
 170                                &data);
 171        } while (--retry && (data & info->regs->rtc_udr_mask) && !ret);
 172
 173        if (!retry)
 174                dev_err(info->dev, "waiting for UDR update, reached max number of retries\n");
 175
 176        return ret;
 177}
 178
 179static inline int s5m_check_peding_alarm_interrupt(struct s5m_rtc_info *info,
 180                struct rtc_wkalrm *alarm)
 181{
 182        int ret;
 183        unsigned int val;
 184
 185        switch (info->device_type) {
 186        case S5M8767X:
 187        case S5M8763X:
 188                ret = regmap_read(info->regmap, S5M_RTC_STATUS, &val);
 189                val &= S5M_ALARM0_STATUS;
 190                break;
 191        case S2MPS14X:
 192        case S2MPS13X:
 193                ret = regmap_read(info->s5m87xx->regmap_pmic, S2MPS14_REG_ST2,
 194                                &val);
 195                val &= S2MPS_ALARM0_STATUS;
 196                break;
 197        default:
 198                return -EINVAL;
 199        }
 200        if (ret < 0)
 201                return ret;
 202
 203        if (val)
 204                alarm->pending = 1;
 205        else
 206                alarm->pending = 0;
 207
 208        return 0;
 209}
 210
 211static inline int s5m8767_rtc_set_time_reg(struct s5m_rtc_info *info)
 212{
 213        int ret;
 214        unsigned int data;
 215
 216        ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
 217        if (ret < 0) {
 218                dev_err(info->dev, "failed to read update reg(%d)\n", ret);
 219                return ret;
 220        }
 221
 222        data |= info->regs->rtc_udr_mask;
 223        if (info->device_type == S5M8763X || info->device_type == S5M8767X)
 224                data |= S5M_RTC_TIME_EN_MASK;
 225
 226        ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
 227        if (ret < 0) {
 228                dev_err(info->dev, "failed to write update reg(%d)\n", ret);
 229                return ret;
 230        }
 231
 232        ret = s5m8767_wait_for_udr_update(info);
 233
 234        return ret;
 235}
 236
 237static inline int s5m8767_rtc_set_alarm_reg(struct s5m_rtc_info *info)
 238{
 239        int ret;
 240        unsigned int data;
 241
 242        ret = regmap_read(info->regmap, info->regs->rtc_udr_update, &data);
 243        if (ret < 0) {
 244                dev_err(info->dev, "%s: fail to read update reg(%d)\n",
 245                        __func__, ret);
 246                return ret;
 247        }
 248
 249        data |= info->regs->rtc_udr_mask;
 250        switch (info->device_type) {
 251        case S5M8763X:
 252        case S5M8767X:
 253                data &= ~S5M_RTC_TIME_EN_MASK;
 254                break;
 255        case S2MPS14X:
 256                data |= S2MPS_RTC_RUDR_MASK;
 257                break;
 258        case S2MPS13X:
 259                data |= S2MPS13_RTC_AUDR_MASK;
 260                break;
 261        default:
 262                return -EINVAL;
 263        }
 264
 265        ret = regmap_write(info->regmap, info->regs->rtc_udr_update, data);
 266        if (ret < 0) {
 267                dev_err(info->dev, "%s: fail to write update reg(%d)\n",
 268                        __func__, ret);
 269                return ret;
 270        }
 271
 272        ret = s5m8767_wait_for_udr_update(info);
 273
 274        /* On S2MPS13 the AUDR is not auto-cleared */
 275        if (info->device_type == S2MPS13X)
 276                regmap_update_bits(info->regmap, info->regs->rtc_udr_update,
 277                                   S2MPS13_RTC_AUDR_MASK, 0);
 278
 279        return ret;
 280}
 281
 282static void s5m8763_data_to_tm(u8 *data, struct rtc_time *tm)
 283{
 284        tm->tm_sec = bcd2bin(data[RTC_SEC]);
 285        tm->tm_min = bcd2bin(data[RTC_MIN]);
 286
 287        if (data[RTC_HOUR] & HOUR_12) {
 288                tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
 289                if (data[RTC_HOUR] & HOUR_PM)
 290                        tm->tm_hour += 12;
 291        } else {
 292                tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
 293        }
 294
 295        tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
 296        tm->tm_mday = bcd2bin(data[RTC_DATE]);
 297        tm->tm_mon = bcd2bin(data[RTC_MONTH]);
 298        tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
 299        tm->tm_year -= 1900;
 300}
 301
 302static void s5m8763_tm_to_data(struct rtc_time *tm, u8 *data)
 303{
 304        data[RTC_SEC] = bin2bcd(tm->tm_sec);
 305        data[RTC_MIN] = bin2bcd(tm->tm_min);
 306        data[RTC_HOUR] = bin2bcd(tm->tm_hour);
 307        data[RTC_WEEKDAY] = tm->tm_wday;
 308        data[RTC_DATE] = bin2bcd(tm->tm_mday);
 309        data[RTC_MONTH] = bin2bcd(tm->tm_mon);
 310        data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
 311        data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
 312}
 313
 314static int s5m_rtc_read_time(struct device *dev, struct rtc_time *tm)
 315{
 316        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 317        u8 data[info->regs->regs_count];
 318        int ret;
 319
 320        if (info->device_type == S2MPS14X || info->device_type == S2MPS13X) {
 321                ret = regmap_update_bits(info->regmap,
 322                                info->regs->rtc_udr_update,
 323                                S2MPS_RTC_RUDR_MASK, S2MPS_RTC_RUDR_MASK);
 324                if (ret) {
 325                        dev_err(dev,
 326                                "Failed to prepare registers for time reading: %d\n",
 327                                ret);
 328                        return ret;
 329                }
 330        }
 331        ret = regmap_bulk_read(info->regmap, info->regs->time, data,
 332                        info->regs->regs_count);
 333        if (ret < 0)
 334                return ret;
 335
 336        switch (info->device_type) {
 337        case S5M8763X:
 338                s5m8763_data_to_tm(data, tm);
 339                break;
 340
 341        case S5M8767X:
 342        case S2MPS14X:
 343        case S2MPS13X:
 344                s5m8767_data_to_tm(data, tm, info->rtc_24hr_mode);
 345                break;
 346
 347        default:
 348                return -EINVAL;
 349        }
 350
 351        dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
 352                1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
 353                tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
 354
 355        return rtc_valid_tm(tm);
 356}
 357
 358static int s5m_rtc_set_time(struct device *dev, struct rtc_time *tm)
 359{
 360        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 361        u8 data[info->regs->regs_count];
 362        int ret = 0;
 363
 364        switch (info->device_type) {
 365        case S5M8763X:
 366                s5m8763_tm_to_data(tm, data);
 367                break;
 368        case S5M8767X:
 369        case S2MPS14X:
 370        case S2MPS13X:
 371                ret = s5m8767_tm_to_data(tm, data);
 372                break;
 373        default:
 374                return -EINVAL;
 375        }
 376
 377        if (ret < 0)
 378                return ret;
 379
 380        dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
 381                1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday,
 382                tm->tm_hour, tm->tm_min, tm->tm_sec, tm->tm_wday);
 383
 384        ret = regmap_raw_write(info->regmap, info->regs->time, data,
 385                        info->regs->regs_count);
 386        if (ret < 0)
 387                return ret;
 388
 389        ret = s5m8767_rtc_set_time_reg(info);
 390
 391        return ret;
 392}
 393
 394static int s5m_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 395{
 396        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 397        u8 data[info->regs->regs_count];
 398        unsigned int val;
 399        int ret, i;
 400
 401        ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
 402                        info->regs->regs_count);
 403        if (ret < 0)
 404                return ret;
 405
 406        switch (info->device_type) {
 407        case S5M8763X:
 408                s5m8763_data_to_tm(data, &alrm->time);
 409                ret = regmap_read(info->regmap, S5M_ALARM0_CONF, &val);
 410                if (ret < 0)
 411                        return ret;
 412
 413                alrm->enabled = !!val;
 414                break;
 415
 416        case S5M8767X:
 417        case S2MPS14X:
 418        case S2MPS13X:
 419                s5m8767_data_to_tm(data, &alrm->time, info->rtc_24hr_mode);
 420                alrm->enabled = 0;
 421                for (i = 0; i < info->regs->regs_count; i++) {
 422                        if (data[i] & ALARM_ENABLE_MASK) {
 423                                alrm->enabled = 1;
 424                                break;
 425                        }
 426                }
 427                break;
 428
 429        default:
 430                return -EINVAL;
 431        }
 432
 433        dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
 434                1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
 435                alrm->time.tm_mday, alrm->time.tm_hour,
 436                alrm->time.tm_min, alrm->time.tm_sec,
 437                alrm->time.tm_wday);
 438
 439        ret = s5m_check_peding_alarm_interrupt(info, alrm);
 440
 441        return 0;
 442}
 443
 444static int s5m_rtc_stop_alarm(struct s5m_rtc_info *info)
 445{
 446        u8 data[info->regs->regs_count];
 447        int ret, i;
 448        struct rtc_time tm;
 449
 450        ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
 451                        info->regs->regs_count);
 452        if (ret < 0)
 453                return ret;
 454
 455        s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
 456        dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
 457                1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
 458                tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
 459
 460        switch (info->device_type) {
 461        case S5M8763X:
 462                ret = regmap_write(info->regmap, S5M_ALARM0_CONF, 0);
 463                break;
 464
 465        case S5M8767X:
 466        case S2MPS14X:
 467        case S2MPS13X:
 468                for (i = 0; i < info->regs->regs_count; i++)
 469                        data[i] &= ~ALARM_ENABLE_MASK;
 470
 471                ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
 472                                info->regs->regs_count);
 473                if (ret < 0)
 474                        return ret;
 475
 476                ret = s5m8767_rtc_set_alarm_reg(info);
 477
 478                break;
 479
 480        default:
 481                return -EINVAL;
 482        }
 483
 484        return ret;
 485}
 486
 487static int s5m_rtc_start_alarm(struct s5m_rtc_info *info)
 488{
 489        int ret;
 490        u8 data[info->regs->regs_count];
 491        u8 alarm0_conf;
 492        struct rtc_time tm;
 493
 494        ret = regmap_bulk_read(info->regmap, info->regs->alarm0, data,
 495                        info->regs->regs_count);
 496        if (ret < 0)
 497                return ret;
 498
 499        s5m8767_data_to_tm(data, &tm, info->rtc_24hr_mode);
 500        dev_dbg(info->dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
 501                1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
 502                tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_wday);
 503
 504        switch (info->device_type) {
 505        case S5M8763X:
 506                alarm0_conf = 0x77;
 507                ret = regmap_write(info->regmap, S5M_ALARM0_CONF, alarm0_conf);
 508                break;
 509
 510        case S5M8767X:
 511        case S2MPS14X:
 512        case S2MPS13X:
 513                data[RTC_SEC] |= ALARM_ENABLE_MASK;
 514                data[RTC_MIN] |= ALARM_ENABLE_MASK;
 515                data[RTC_HOUR] |= ALARM_ENABLE_MASK;
 516                data[RTC_WEEKDAY] &= ~ALARM_ENABLE_MASK;
 517                if (data[RTC_DATE] & 0x1f)
 518                        data[RTC_DATE] |= ALARM_ENABLE_MASK;
 519                if (data[RTC_MONTH] & 0xf)
 520                        data[RTC_MONTH] |= ALARM_ENABLE_MASK;
 521                if (data[RTC_YEAR1] & 0x7f)
 522                        data[RTC_YEAR1] |= ALARM_ENABLE_MASK;
 523
 524                ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
 525                                info->regs->regs_count);
 526                if (ret < 0)
 527                        return ret;
 528                ret = s5m8767_rtc_set_alarm_reg(info);
 529
 530                break;
 531
 532        default:
 533                return -EINVAL;
 534        }
 535
 536        return ret;
 537}
 538
 539static int s5m_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 540{
 541        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 542        u8 data[info->regs->regs_count];
 543        int ret;
 544
 545        switch (info->device_type) {
 546        case S5M8763X:
 547                s5m8763_tm_to_data(&alrm->time, data);
 548                break;
 549
 550        case S5M8767X:
 551        case S2MPS14X:
 552        case S2MPS13X:
 553                s5m8767_tm_to_data(&alrm->time, data);
 554                break;
 555
 556        default:
 557                return -EINVAL;
 558        }
 559
 560        dev_dbg(dev, "%s: %d/%d/%d %d:%d:%d(%d)\n", __func__,
 561                1900 + alrm->time.tm_year, 1 + alrm->time.tm_mon,
 562                alrm->time.tm_mday, alrm->time.tm_hour, alrm->time.tm_min,
 563                alrm->time.tm_sec, alrm->time.tm_wday);
 564
 565        ret = s5m_rtc_stop_alarm(info);
 566        if (ret < 0)
 567                return ret;
 568
 569        ret = regmap_raw_write(info->regmap, info->regs->alarm0, data,
 570                        info->regs->regs_count);
 571        if (ret < 0)
 572                return ret;
 573
 574        ret = s5m8767_rtc_set_alarm_reg(info);
 575        if (ret < 0)
 576                return ret;
 577
 578        if (alrm->enabled)
 579                ret = s5m_rtc_start_alarm(info);
 580
 581        return ret;
 582}
 583
 584static int s5m_rtc_alarm_irq_enable(struct device *dev,
 585                                    unsigned int enabled)
 586{
 587        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 588
 589        if (enabled)
 590                return s5m_rtc_start_alarm(info);
 591        else
 592                return s5m_rtc_stop_alarm(info);
 593}
 594
 595static irqreturn_t s5m_rtc_alarm_irq(int irq, void *data)
 596{
 597        struct s5m_rtc_info *info = data;
 598
 599        rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
 600
 601        return IRQ_HANDLED;
 602}
 603
 604static const struct rtc_class_ops s5m_rtc_ops = {
 605        .read_time = s5m_rtc_read_time,
 606        .set_time = s5m_rtc_set_time,
 607        .read_alarm = s5m_rtc_read_alarm,
 608        .set_alarm = s5m_rtc_set_alarm,
 609        .alarm_irq_enable = s5m_rtc_alarm_irq_enable,
 610};
 611
 612static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
 613{
 614        u8 data[2];
 615        int ret;
 616
 617        switch (info->device_type) {
 618        case S5M8763X:
 619        case S5M8767X:
 620                /* UDR update time. Default of 7.32 ms is too long. */
 621                ret = regmap_update_bits(info->regmap, S5M_RTC_UDR_CON,
 622                                S5M_RTC_UDR_T_MASK, S5M_RTC_UDR_T_450_US);
 623                if (ret < 0)
 624                        dev_err(info->dev, "%s: fail to change UDR time: %d\n",
 625                                        __func__, ret);
 626
 627                /* Set RTC control register : Binary mode, 24hour mode */
 628                data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
 629                data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
 630
 631                ret = regmap_raw_write(info->regmap, S5M_ALARM0_CONF, data, 2);
 632                break;
 633
 634        case S2MPS14X:
 635        case S2MPS13X:
 636                data[0] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT);
 637                ret = regmap_write(info->regmap, info->regs->ctrl, data[0]);
 638                break;
 639
 640        default:
 641                return -EINVAL;
 642        }
 643
 644        info->rtc_24hr_mode = 1;
 645        if (ret < 0) {
 646                dev_err(info->dev, "%s: fail to write controlm reg(%d)\n",
 647                        __func__, ret);
 648                return ret;
 649        }
 650
 651        return ret;
 652}
 653
 654static int s5m_rtc_probe(struct platform_device *pdev)
 655{
 656        struct sec_pmic_dev *s5m87xx = dev_get_drvdata(pdev->dev.parent);
 657        struct sec_platform_data *pdata = s5m87xx->pdata;
 658        struct s5m_rtc_info *info;
 659        const struct regmap_config *regmap_cfg;
 660        int ret, alarm_irq;
 661
 662        if (!pdata) {
 663                dev_err(pdev->dev.parent, "Platform data not supplied\n");
 664                return -ENODEV;
 665        }
 666
 667        info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL);
 668        if (!info)
 669                return -ENOMEM;
 670
 671        switch (platform_get_device_id(pdev)->driver_data) {
 672        case S2MPS14X:
 673        case S2MPS13X:
 674                regmap_cfg = &s2mps14_rtc_regmap_config;
 675                info->regs = &s2mps_rtc_regs;
 676                alarm_irq = S2MPS14_IRQ_RTCA0;
 677                break;
 678        case S5M8763X:
 679                regmap_cfg = &s5m_rtc_regmap_config;
 680                info->regs = &s5m_rtc_regs;
 681                alarm_irq = S5M8763_IRQ_ALARM0;
 682                break;
 683        case S5M8767X:
 684                regmap_cfg = &s5m_rtc_regmap_config;
 685                info->regs = &s5m_rtc_regs;
 686                alarm_irq = S5M8767_IRQ_RTCA1;
 687                break;
 688        default:
 689                dev_err(&pdev->dev,
 690                                "Device type %lu is not supported by RTC driver\n",
 691                                platform_get_device_id(pdev)->driver_data);
 692                return -ENODEV;
 693        }
 694
 695        info->i2c = i2c_new_dummy(s5m87xx->i2c->adapter, RTC_I2C_ADDR);
 696        if (!info->i2c) {
 697                dev_err(&pdev->dev, "Failed to allocate I2C for RTC\n");
 698                return -ENODEV;
 699        }
 700
 701        info->regmap = devm_regmap_init_i2c(info->i2c, regmap_cfg);
 702        if (IS_ERR(info->regmap)) {
 703                ret = PTR_ERR(info->regmap);
 704                dev_err(&pdev->dev, "Failed to allocate RTC register map: %d\n",
 705                                ret);
 706                goto err;
 707        }
 708
 709        info->dev = &pdev->dev;
 710        info->s5m87xx = s5m87xx;
 711        info->device_type = platform_get_device_id(pdev)->driver_data;
 712
 713        if (s5m87xx->irq_data) {
 714                info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
 715                if (info->irq <= 0) {
 716                        ret = -EINVAL;
 717                        dev_err(&pdev->dev, "Failed to get virtual IRQ %d\n",
 718                                alarm_irq);
 719                        goto err;
 720                }
 721        }
 722
 723        platform_set_drvdata(pdev, info);
 724
 725        ret = s5m8767_rtc_init_reg(info);
 726
 727        device_init_wakeup(&pdev->dev, 1);
 728
 729        info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
 730                                                 &s5m_rtc_ops, THIS_MODULE);
 731
 732        if (IS_ERR(info->rtc_dev)) {
 733                ret = PTR_ERR(info->rtc_dev);
 734                goto err;
 735        }
 736
 737        if (!info->irq) {
 738                dev_info(&pdev->dev, "Alarm IRQ not available\n");
 739                return 0;
 740        }
 741
 742        ret = devm_request_threaded_irq(&pdev->dev, info->irq, NULL,
 743                                        s5m_rtc_alarm_irq, 0, "rtc-alarm0",
 744                                        info);
 745        if (ret < 0) {
 746                dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
 747                        info->irq, ret);
 748                goto err;
 749        }
 750
 751        return 0;
 752
 753err:
 754        i2c_unregister_device(info->i2c);
 755
 756        return ret;
 757}
 758
 759static int s5m_rtc_remove(struct platform_device *pdev)
 760{
 761        struct s5m_rtc_info *info = platform_get_drvdata(pdev);
 762
 763        i2c_unregister_device(info->i2c);
 764
 765        return 0;
 766}
 767
 768#ifdef CONFIG_PM_SLEEP
 769static int s5m_rtc_resume(struct device *dev)
 770{
 771        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 772        int ret = 0;
 773
 774        if (info->irq && device_may_wakeup(dev))
 775                ret = disable_irq_wake(info->irq);
 776
 777        return ret;
 778}
 779
 780static int s5m_rtc_suspend(struct device *dev)
 781{
 782        struct s5m_rtc_info *info = dev_get_drvdata(dev);
 783        int ret = 0;
 784
 785        if (info->irq && device_may_wakeup(dev))
 786                ret = enable_irq_wake(info->irq);
 787
 788        return ret;
 789}
 790#endif /* CONFIG_PM_SLEEP */
 791
 792static SIMPLE_DEV_PM_OPS(s5m_rtc_pm_ops, s5m_rtc_suspend, s5m_rtc_resume);
 793
 794static const struct platform_device_id s5m_rtc_id[] = {
 795        { "s5m-rtc",            S5M8767X },
 796        { "s2mps13-rtc",        S2MPS13X },
 797        { "s2mps14-rtc",        S2MPS14X },
 798        { },
 799};
 800
 801static struct platform_driver s5m_rtc_driver = {
 802        .driver         = {
 803                .name   = "s5m-rtc",
 804                .pm     = &s5m_rtc_pm_ops,
 805        },
 806        .probe          = s5m_rtc_probe,
 807        .remove         = s5m_rtc_remove,
 808        .id_table       = s5m_rtc_id,
 809};
 810
 811module_platform_driver(s5m_rtc_driver);
 812
 813/* Module information */
 814MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
 815MODULE_DESCRIPTION("Samsung S5M/S2MPS14 RTC driver");
 816MODULE_LICENSE("GPL");
 817MODULE_ALIAS("platform:s5m-rtc");
 818