Revert "Merge commit 'main-jb-2012.08.03-B4' into t114-0806"
[linux-2.6.git] / drivers / rtc / rtc-ds1672.c
1 /*
2  * An rtc/i2c driver for the Dallas DS1672
3  * Copyright 2005-06 Tower Technologies
4  *
5  * Author: Alessandro Zummo <a.zummo@towertech.it>
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 version 2 as
9  * published by the Free Software Foundation.
10  */
11
12 #include <linux/i2c.h>
13 #include <linux/rtc.h>
14 #include <linux/module.h>
15
16 #define DRV_VERSION "0.4"
17
18 /* Registers */
19
20 #define DS1672_REG_CNT_BASE     0
21 #define DS1672_REG_CONTROL      4
22 #define DS1672_REG_TRICKLE      5
23
24 #define DS1672_REG_CONTROL_EOSC 0x80
25
26 static struct i2c_driver ds1672_driver;
27
28 /*
29  * In the routines that deal directly with the ds1672 hardware, we use
30  * rtc_time -- month 0-11, hour 0-23, yr = calendar year-epoch
31  * Epoch is initialized as 2000. Time is set to UTC.
32  */
33 static int ds1672_get_datetime(struct i2c_client *client, struct rtc_time *tm)
34 {
35         unsigned long time;
36         unsigned char addr = DS1672_REG_CNT_BASE;
37         unsigned char buf[4];
38
39         struct i2c_msg msgs[] = {
40                 {client->addr, 0, 1, &addr},    /* setup read ptr */
41                 {client->addr, I2C_M_RD, 4, buf},       /* read date */
42         };
43
44         /* read date registers */
45         if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
46                 dev_err(&client->dev, "%s: read error\n", __func__);
47                 return -EIO;
48         }
49
50         dev_dbg(&client->dev,
51                 "%s: raw read data - counters=%02x,%02x,%02x,%02x\n",
52                 __func__, buf[0], buf[1], buf[2], buf[3]);
53
54         time = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
55
56         rtc_time_to_tm(time, tm);
57
58         dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
59                 "mday=%d, mon=%d, year=%d, wday=%d\n",
60                 __func__, tm->tm_sec, tm->tm_min, tm->tm_hour,
61                 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
62
63         return 0;
64 }
65
66 static int ds1672_set_mmss(struct i2c_client *client, unsigned long secs)
67 {
68         int xfer;
69         unsigned char buf[6];
70
71         buf[0] = DS1672_REG_CNT_BASE;
72         buf[1] = secs & 0x000000FF;
73         buf[2] = (secs & 0x0000FF00) >> 8;
74         buf[3] = (secs & 0x00FF0000) >> 16;
75         buf[4] = (secs & 0xFF000000) >> 24;
76         buf[5] = 0;             /* set control reg to enable counting */
77
78         xfer = i2c_master_send(client, buf, 6);
79         if (xfer != 6) {
80                 dev_err(&client->dev, "%s: send: %d\n", __func__, xfer);
81                 return -EIO;
82         }
83
84         return 0;
85 }
86
87 static int ds1672_rtc_read_time(struct device *dev, struct rtc_time *tm)
88 {
89         return ds1672_get_datetime(to_i2c_client(dev), tm);
90 }
91
92 static int ds1672_rtc_set_mmss(struct device *dev, unsigned long secs)
93 {
94         return ds1672_set_mmss(to_i2c_client(dev), secs);
95 }
96
97 static int ds1672_get_control(struct i2c_client *client, u8 *status)
98 {
99         unsigned char addr = DS1672_REG_CONTROL;
100
101         struct i2c_msg msgs[] = {
102                 {client->addr, 0, 1, &addr},    /* setup read ptr */
103                 {client->addr, I2C_M_RD, 1, status},    /* read control */
104         };
105
106         /* read control register */
107         if ((i2c_transfer(client->adapter, &msgs[0], 2)) != 2) {
108                 dev_err(&client->dev, "%s: read error\n", __func__);
109                 return -EIO;
110         }
111
112         return 0;
113 }
114
115 /* following are the sysfs callback functions */
116 static ssize_t show_control(struct device *dev, struct device_attribute *attr,
117                             char *buf)
118 {
119         struct i2c_client *client = to_i2c_client(dev);
120         u8 control;
121         int err;
122
123         err = ds1672_get_control(client, &control);
124         if (err)
125                 return err;
126
127         return sprintf(buf, "%s\n", (control & DS1672_REG_CONTROL_EOSC)
128                        ? "disabled" : "enabled");
129 }
130
131 static DEVICE_ATTR(control, S_IRUGO, show_control, NULL);
132
133 static const struct rtc_class_ops ds1672_rtc_ops = {
134         .read_time = ds1672_rtc_read_time,
135         .set_mmss = ds1672_rtc_set_mmss,
136 };
137
138 static int ds1672_remove(struct i2c_client *client)
139 {
140         struct rtc_device *rtc = i2c_get_clientdata(client);
141
142         if (rtc)
143                 rtc_device_unregister(rtc);
144
145         return 0;
146 }
147
148 static int ds1672_probe(struct i2c_client *client,
149                         const struct i2c_device_id *id)
150 {
151         int err = 0;
152         u8 control;
153         struct rtc_device *rtc;
154
155         dev_dbg(&client->dev, "%s\n", __func__);
156
157         if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
158                 return -ENODEV;
159
160         dev_info(&client->dev, "chip found, driver version " DRV_VERSION "\n");
161
162         rtc = rtc_device_register(ds1672_driver.driver.name, &client->dev,
163                                   &ds1672_rtc_ops, THIS_MODULE);
164
165         if (IS_ERR(rtc))
166                 return PTR_ERR(rtc);
167
168         i2c_set_clientdata(client, rtc);
169
170         /* read control register */
171         err = ds1672_get_control(client, &control);
172         if (err)
173                 goto exit_devreg;
174
175         if (control & DS1672_REG_CONTROL_EOSC)
176                 dev_warn(&client->dev, "Oscillator not enabled. "
177                          "Set time to enable.\n");
178
179         /* Register sysfs hooks */
180         err = device_create_file(&client->dev, &dev_attr_control);
181         if (err)
182                 goto exit_devreg;
183
184         return 0;
185
186  exit_devreg:
187         rtc_device_unregister(rtc);
188         return err;
189 }
190
191 static struct i2c_device_id ds1672_id[] = {
192         { "ds1672", 0 },
193         { }
194 };
195
196 static struct i2c_driver ds1672_driver = {
197         .driver = {
198                    .name = "rtc-ds1672",
199                    },
200         .probe = &ds1672_probe,
201         .remove = &ds1672_remove,
202         .id_table = ds1672_id,
203 };
204
205 module_i2c_driver(ds1672_driver);
206
207 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
208 MODULE_DESCRIPTION("Dallas/Maxim DS1672 timekeeper driver");
209 MODULE_LICENSE("GPL");
210 MODULE_VERSION(DRV_VERSION);