linux/drivers/rtc/rtc-em3027.c
<<
>>
Prefs
   1/*
   2 * An rtc/i2c driver for the EM Microelectronic EM3027
   3 * Copyright 2011 CompuLab, Ltd.
   4 *
   5 * Author: Mike Rapoport <mike@compulab.co.il>
   6 *
   7 * Based on rtc-ds1672.c by Alessandro Zummo <a.zummo@towertech.it>
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 */
  13
  14#include <linux/i2c.h>
  15#include <linux/rtc.h>
  16#include <linux/bcd.h>
  17#include <linux/module.h>
  18
  19/* Registers */
  20#define EM3027_REG_ON_OFF_CTRL  0x00
  21#define EM3027_REG_IRQ_CTRL     0x01
  22#define EM3027_REG_IRQ_FLAGS    0x02
  23#define EM3027_REG_STATUS       0x03
  24#define EM3027_REG_RST_CTRL     0x04
  25
  26#define EM3027_REG_WATCH_SEC    0x08
  27#define EM3027_REG_WATCH_MIN    0x09
  28#define EM3027_REG_WATCH_HOUR   0x0a
  29#define EM3027_REG_WATCH_DATE   0x0b
  30#define EM3027_REG_WATCH_DAY    0x0c
  31#define EM3027_REG_WATCH_MON    0x0d
  32#define EM3027_REG_WATCH_YEAR   0x0e
  33
  34#define EM3027_REG_ALARM_SEC    0x10
  35#define EM3027_REG_ALARM_MIN    0x11
  36#define EM3027_REG_ALARM_HOUR   0x12
  37#define EM3027_REG_ALARM_DATE   0x13
  38#define EM3027_REG_ALARM_DAY    0x14
  39#define EM3027_REG_ALARM_MON    0x15
  40#define EM3027_REG_ALARM_YEAR   0x16
  41
  42static struct i2c_driver em3027_driver;
  43
  44static int em3027_get_time(struct device *dev, struct rtc_time *tm)
  45{
  46        struct i2c_client *client = to_i2c_client(dev);
  47
  48        unsigned char addr = EM3027_REG_WATCH_SEC;
  49        unsigned char buf[7];
  50
  51        struct i2c_msg msgs[] = {
  52                {/* setup read addr */
  53                        .addr = client->addr,
  54                        .len = 1,
  55                        .buf = &addr
  56                },
  57                {/* read time/date */
  58                        .addr = client->addr,
  59                        .flags = I2C_M_RD,
  60                        .len = 7,
  61                        .buf = buf
  62                },
  63        };
  64
  65        /* read time/date registers */
  66        if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
  67                dev_err(&client->dev, "%s: read error\n", __func__);
  68                return -EIO;
  69        }
  70
  71        tm->tm_sec      = bcd2bin(buf[0]);
  72        tm->tm_min      = bcd2bin(buf[1]);
  73        tm->tm_hour     = bcd2bin(buf[2]);
  74        tm->tm_mday     = bcd2bin(buf[3]);
  75        tm->tm_wday     = bcd2bin(buf[4]);
  76        tm->tm_mon      = bcd2bin(buf[5]);
  77        tm->tm_year     = bcd2bin(buf[6]) + 100;
  78
  79        return 0;
  80}
  81
  82static int em3027_set_time(struct device *dev, struct rtc_time *tm)
  83{
  84        struct i2c_client *client = to_i2c_client(dev);
  85        unsigned char buf[8];
  86
  87        struct i2c_msg msg = {
  88                .addr = client->addr,
  89                .len = 8,
  90                .buf = buf,     /* write time/date */
  91        };
  92
  93        buf[0] = EM3027_REG_WATCH_SEC;
  94        buf[1] = bin2bcd(tm->tm_sec);
  95        buf[2] = bin2bcd(tm->tm_min);
  96        buf[3] = bin2bcd(tm->tm_hour);
  97        buf[4] = bin2bcd(tm->tm_mday);
  98        buf[5] = bin2bcd(tm->tm_wday);
  99        buf[6] = bin2bcd(tm->tm_mon);
 100        buf[7] = bin2bcd(tm->tm_year % 100);
 101
 102        /* write time/date registers */
 103        if ((i2c_transfer(client->adapter, &msg, 1)) != 1) {
 104                dev_err(&client->dev, "%s: write error\n", __func__);
 105                return -EIO;
 106        }
 107
 108        return 0;
 109}
 110
 111static const struct rtc_class_ops em3027_rtc_ops = {
 112        .read_time = em3027_get_time,
 113        .set_time = em3027_set_time,
 114};
 115
 116static int em3027_probe(struct i2c_client *client,
 117                        const struct i2c_device_id *id)
 118{
 119        struct rtc_device *rtc;
 120
 121        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
 122                return -ENODEV;
 123
 124        rtc = devm_rtc_device_register(&client->dev, em3027_driver.driver.name,
 125                                  &em3027_rtc_ops, THIS_MODULE);
 126        if (IS_ERR(rtc))
 127                return PTR_ERR(rtc);
 128
 129        i2c_set_clientdata(client, rtc);
 130
 131        return 0;
 132}
 133
 134static struct i2c_device_id em3027_id[] = {
 135        { "em3027", 0 },
 136        { }
 137};
 138
 139static struct i2c_driver em3027_driver = {
 140        .driver = {
 141                   .name = "rtc-em3027",
 142        },
 143        .probe = &em3027_probe,
 144        .id_table = em3027_id,
 145};
 146
 147module_i2c_driver(em3027_driver);
 148
 149MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 150MODULE_DESCRIPTION("EM Microelectronic EM3027 RTC driver");
 151MODULE_LICENSE("GPL");
 152
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.