linux/drivers/rtc/rtc-max8998.c
<<
>>
Prefs
   1/*
   2 * RTC driver for Maxim MAX8998
   3 *
   4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
   5 * Author: Minkyu Kang <mk7.kang@samsung.com>
   6 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
   7 *
   8 *  This program is free software; you can redistribute  it and/or modify it
   9 *  under  the terms of  the GNU General  Public License as published by the
  10 *  Free Software Foundation;  either version 2 of the  License, or (at your
  11 *  option) any later version.
  12 *
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/i2c.h>
  17#include <linux/slab.h>
  18#include <linux/bcd.h>
  19#include <linux/rtc.h>
  20#include <linux/platform_device.h>
  21#include <linux/mfd/max8998.h>
  22#include <linux/mfd/max8998-private.h>
  23#include <linux/delay.h>
  24
  25#define MAX8998_RTC_SEC                 0x00
  26#define MAX8998_RTC_MIN                 0x01
  27#define MAX8998_RTC_HOUR                0x02
  28#define MAX8998_RTC_WEEKDAY             0x03
  29#define MAX8998_RTC_DATE                0x04
  30#define MAX8998_RTC_MONTH               0x05
  31#define MAX8998_RTC_YEAR1               0x06
  32#define MAX8998_RTC_YEAR2               0x07
  33#define MAX8998_ALARM0_SEC              0x08
  34#define MAX8998_ALARM0_MIN              0x09
  35#define MAX8998_ALARM0_HOUR             0x0a
  36#define MAX8998_ALARM0_WEEKDAY          0x0b
  37#define MAX8998_ALARM0_DATE             0x0c
  38#define MAX8998_ALARM0_MONTH            0x0d
  39#define MAX8998_ALARM0_YEAR1            0x0e
  40#define MAX8998_ALARM0_YEAR2            0x0f
  41#define MAX8998_ALARM1_SEC              0x10
  42#define MAX8998_ALARM1_MIN              0x11
  43#define MAX8998_ALARM1_HOUR             0x12
  44#define MAX8998_ALARM1_WEEKDAY          0x13
  45#define MAX8998_ALARM1_DATE             0x14
  46#define MAX8998_ALARM1_MONTH            0x15
  47#define MAX8998_ALARM1_YEAR1            0x16
  48#define MAX8998_ALARM1_YEAR2            0x17
  49#define MAX8998_ALARM0_CONF             0x18
  50#define MAX8998_ALARM1_CONF             0x19
  51#define MAX8998_RTC_STATUS              0x1a
  52#define MAX8998_WTSR_SMPL_CNTL          0x1b
  53#define MAX8998_TEST                    0x1f
  54
  55#define HOUR_12                         (1 << 7)
  56#define HOUR_PM                         (1 << 5)
  57#define ALARM0_STATUS                   (1 << 1)
  58#define ALARM1_STATUS                   (1 << 2)
  59
  60enum {
  61        RTC_SEC = 0,
  62        RTC_MIN,
  63        RTC_HOUR,
  64        RTC_WEEKDAY,
  65        RTC_DATE,
  66        RTC_MONTH,
  67        RTC_YEAR1,
  68        RTC_YEAR2,
  69};
  70
  71struct max8998_rtc_info {
  72        struct device           *dev;
  73        struct max8998_dev      *max8998;
  74        struct i2c_client       *rtc;
  75        struct rtc_device       *rtc_dev;
  76        int irq;
  77        bool lp3974_bug_workaround;
  78};
  79
  80static void max8998_data_to_tm(u8 *data, struct rtc_time *tm)
  81{
  82        tm->tm_sec = bcd2bin(data[RTC_SEC]);
  83        tm->tm_min = bcd2bin(data[RTC_MIN]);
  84        if (data[RTC_HOUR] & HOUR_12) {
  85                tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x1f);
  86                if (data[RTC_HOUR] & HOUR_PM)
  87                        tm->tm_hour += 12;
  88        } else
  89                tm->tm_hour = bcd2bin(data[RTC_HOUR] & 0x3f);
  90
  91        tm->tm_wday = data[RTC_WEEKDAY] & 0x07;
  92        tm->tm_mday = bcd2bin(data[RTC_DATE]);
  93        tm->tm_mon = bcd2bin(data[RTC_MONTH]);
  94        tm->tm_year = bcd2bin(data[RTC_YEAR1]) + bcd2bin(data[RTC_YEAR2]) * 100;
  95        tm->tm_year -= 1900;
  96}
  97
  98static void max8998_tm_to_data(struct rtc_time *tm, u8 *data)
  99{
 100        data[RTC_SEC] = bin2bcd(tm->tm_sec);
 101        data[RTC_MIN] = bin2bcd(tm->tm_min);
 102        data[RTC_HOUR] = bin2bcd(tm->tm_hour);
 103        data[RTC_WEEKDAY] = tm->tm_wday;
 104        data[RTC_DATE] = bin2bcd(tm->tm_mday);
 105        data[RTC_MONTH] = bin2bcd(tm->tm_mon);
 106        data[RTC_YEAR1] = bin2bcd(tm->tm_year % 100);
 107        data[RTC_YEAR2] = bin2bcd((tm->tm_year + 1900) / 100);
 108}
 109
 110static int max8998_rtc_read_time(struct device *dev, struct rtc_time *tm)
 111{
 112        struct max8998_rtc_info *info = dev_get_drvdata(dev);
 113        u8 data[8];
 114        int ret;
 115
 116        ret = max8998_bulk_read(info->rtc, MAX8998_RTC_SEC, 8, data);
 117        if (ret < 0)
 118                return ret;
 119
 120        max8998_data_to_tm(data, tm);
 121
 122        return rtc_valid_tm(tm);
 123}
 124
 125static int max8998_rtc_set_time(struct device *dev, struct rtc_time *tm)
 126{
 127        struct max8998_rtc_info *info = dev_get_drvdata(dev);
 128        u8 data[8];
 129        int ret;
 130
 131        max8998_tm_to_data(tm, data);
 132
 133        ret = max8998_bulk_write(info->rtc, MAX8998_RTC_SEC, 8, data);
 134
 135        if (info->lp3974_bug_workaround)
 136                msleep(2000);
 137
 138        return ret;
 139}
 140
 141static int max8998_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 142{
 143        struct max8998_rtc_info *info = dev_get_drvdata(dev);
 144        u8 data[8];
 145        u8 val;
 146        int ret;
 147
 148        ret = max8998_bulk_read(info->rtc, MAX8998_ALARM0_SEC, 8, data);
 149        if (ret < 0)
 150                return ret;
 151
 152        max8998_data_to_tm(data, &alrm->time);
 153
 154        ret = max8998_read_reg(info->rtc, MAX8998_ALARM0_CONF, &val);
 155        if (ret < 0)
 156                return ret;
 157
 158        alrm->enabled = !!val;
 159
 160        ret = max8998_read_reg(info->rtc, MAX8998_RTC_STATUS, &val);
 161        if (ret < 0)
 162                return ret;
 163
 164        if (val & ALARM0_STATUS)
 165                alrm->pending = 1;
 166        else
 167                alrm->pending = 0;
 168
 169        return 0;
 170}
 171
 172static int max8998_rtc_stop_alarm(struct max8998_rtc_info *info)
 173{
 174        int ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, 0);
 175
 176        if (info->lp3974_bug_workaround)
 177                msleep(2000);
 178
 179        return ret;
 180}
 181
 182static int max8998_rtc_start_alarm(struct max8998_rtc_info *info)
 183{
 184        int ret;
 185        u8 alarm0_conf = 0x77;
 186
 187        /* LP3974 with delay bug chips has rtc alarm bugs with "MONTH" field */
 188        if (info->lp3974_bug_workaround)
 189                alarm0_conf = 0x57;
 190
 191        ret = max8998_write_reg(info->rtc, MAX8998_ALARM0_CONF, alarm0_conf);
 192
 193        if (info->lp3974_bug_workaround)
 194                msleep(2000);
 195
 196        return ret;
 197}
 198
 199static int max8998_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
 200{
 201        struct max8998_rtc_info *info = dev_get_drvdata(dev);
 202        u8 data[8];
 203        int ret;
 204
 205        max8998_tm_to_data(&alrm->time, data);
 206
 207        ret = max8998_rtc_stop_alarm(info);
 208        if (ret < 0)
 209                return ret;
 210
 211        ret = max8998_bulk_write(info->rtc, MAX8998_ALARM0_SEC, 8, data);
 212        if (ret < 0)
 213                return ret;
 214
 215        if (info->lp3974_bug_workaround)
 216                msleep(2000);
 217
 218        if (alrm->enabled)
 219                ret = max8998_rtc_start_alarm(info);
 220
 221        return ret;
 222}
 223
 224static int max8998_rtc_alarm_irq_enable(struct device *dev,
 225                                        unsigned int enabled)
 226{
 227        struct max8998_rtc_info *info = dev_get_drvdata(dev);
 228
 229        if (enabled)
 230                return max8998_rtc_start_alarm(info);
 231        else
 232                return max8998_rtc_stop_alarm(info);
 233}
 234
 235static irqreturn_t max8998_rtc_alarm_irq(int irq, void *data)
 236{
 237        struct max8998_rtc_info *info = data;
 238
 239        rtc_update_irq(info->rtc_dev, 1, RTC_IRQF | RTC_AF);
 240
 241        return IRQ_HANDLED;
 242}
 243
 244static const struct rtc_class_ops max8998_rtc_ops = {
 245        .read_time = max8998_rtc_read_time,
 246        .set_time = max8998_rtc_set_time,
 247        .read_alarm = max8998_rtc_read_alarm,
 248        .set_alarm = max8998_rtc_set_alarm,
 249        .alarm_irq_enable = max8998_rtc_alarm_irq_enable,
 250};
 251
 252static int __devinit max8998_rtc_probe(struct platform_device *pdev)
 253{
 254        struct max8998_dev *max8998 = dev_get_drvdata(pdev->dev.parent);
 255        struct max8998_platform_data *pdata = dev_get_platdata(max8998->dev);
 256        struct max8998_rtc_info *info;
 257        int ret;
 258
 259        info = kzalloc(sizeof(struct max8998_rtc_info), GFP_KERNEL);
 260        if (!info)
 261                return -ENOMEM;
 262
 263        info->dev = &pdev->dev;
 264        info->max8998 = max8998;
 265        info->rtc = max8998->rtc;
 266        info->irq = max8998->irq_base + MAX8998_IRQ_ALARM0;
 267
 268        platform_set_drvdata(pdev, info);
 269
 270        info->rtc_dev = rtc_device_register("max8998-rtc", &pdev->dev,
 271                        &max8998_rtc_ops, THIS_MODULE);
 272
 273        if (IS_ERR(info->rtc_dev)) {
 274                ret = PTR_ERR(info->rtc_dev);
 275                dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret);
 276                goto out_rtc;
 277        }
 278
 279        ret = request_threaded_irq(info->irq, NULL, max8998_rtc_alarm_irq, 0,
 280                        "rtc-alarm0", info);
 281
 282        if (ret < 0)
 283                dev_err(&pdev->dev, "Failed to request alarm IRQ: %d: %d\n",
 284                        info->irq, ret);
 285
 286        dev_info(&pdev->dev, "RTC CHIP NAME: %s\n", pdev->id_entry->name);
 287        if (pdata->rtc_delay) {
 288                info->lp3974_bug_workaround = true;
 289                dev_warn(&pdev->dev, "LP3974 with RTC REGERR option."
 290                                " RTC updates will be extremely slow.\n");
 291        }
 292
 293        return 0;
 294
 295out_rtc:
 296        platform_set_drvdata(pdev, NULL);
 297        kfree(info);
 298        return ret;
 299}
 300
 301static int __devexit max8998_rtc_remove(struct platform_device *pdev)
 302{
 303        struct max8998_rtc_info *info = platform_get_drvdata(pdev);
 304
 305        if (info) {
 306                free_irq(info->irq, info);
 307                rtc_device_unregister(info->rtc_dev);
 308                kfree(info);
 309        }
 310
 311        return 0;
 312}
 313
 314static const struct platform_device_id max8998_rtc_id[] = {
 315        { "max8998-rtc", TYPE_MAX8998 },
 316        { "lp3974-rtc", TYPE_LP3974 },
 317        { }
 318};
 319
 320static struct platform_driver max8998_rtc_driver = {
 321        .driver         = {
 322                .name   = "max8998-rtc",
 323                .owner  = THIS_MODULE,
 324        },
 325        .probe          = max8998_rtc_probe,
 326        .remove         = __devexit_p(max8998_rtc_remove),
 327        .id_table       = max8998_rtc_id,
 328};
 329
 330module_platform_driver(max8998_rtc_driver);
 331
 332MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
 333MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
 334MODULE_DESCRIPTION("Maxim MAX8998 RTC driver");
 335MODULE_LICENSE("GPL");
 336
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.