blob: a264938500afd7b31243dc618a14eaa847977ddb [file] [log] [blame]
David Brownell1abb0dc2006-06-25 05:48:17 -07001/*
2 * rtc-ds1307.c - RTC driver for some mostly-compatible I2C chips.
3 *
4 * Copyright (C) 2005 James Chapman (ds1337 core)
5 * Copyright (C) 2006 David Brownell
Matthias Fuchsa2166852009-03-31 15:24:58 -07006 * Copyright (C) 2009 Matthias Fuchs (rx8025 support)
Bertrand Achardbc48b902013-04-29 16:19:26 -07007 * Copyright (C) 2012 Bertrand Achard (nvram access fixes)
David Brownell1abb0dc2006-06-25 05:48:17 -07008 *
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
Tin Huynh9c19b892016-11-30 09:57:31 +070014#include <linux/acpi.h>
David Brownell1abb0dc2006-06-25 05:48:17 -070015#include <linux/bcd.h>
Nishanth Menoneac72372015-06-23 11:15:12 -050016#include <linux/i2c.h>
17#include <linux/init.h>
18#include <linux/module.h>
Javier Martinez Canillas7ef6d2c2017-03-03 11:29:15 -030019#include <linux/of_device.h>
Wolfram Sangeb86c302012-05-29 15:07:38 -070020#include <linux/rtc/ds1307.h>
Nishanth Menoneac72372015-06-23 11:15:12 -050021#include <linux/rtc.h>
22#include <linux/slab.h>
23#include <linux/string.h>
Akinobu Mita445c0202016-01-25 00:22:16 +090024#include <linux/hwmon.h>
25#include <linux/hwmon-sysfs.h>
Akinobu Mita6c6ff142016-01-31 23:10:10 +090026#include <linux/clk-provider.h>
Heiner Kallweit11e58902017-03-10 18:52:34 +010027#include <linux/regmap.h>
David Brownell1abb0dc2006-06-25 05:48:17 -070028
David Anders40ce9722012-03-23 15:02:37 -070029/*
30 * We can't determine type by probing, but if we expect pre-Linux code
David Brownell1abb0dc2006-06-25 05:48:17 -070031 * to have set the chip up as a clock (turning on the oscillator and
32 * setting the date and time), Linux can ignore the non-clock features.
33 * That's a natural job for a factory or repair bench.
David Brownell1abb0dc2006-06-25 05:48:17 -070034 */
35enum ds_type {
David Brownell045e0e82007-07-17 04:04:55 -070036 ds_1307,
37 ds_1337,
38 ds_1338,
39 ds_1339,
40 ds_1340,
Joakim Tjernlund33df2ee2009-06-17 16:26:08 -070041 ds_1388,
Wolfram Sang97f902b2009-06-17 16:26:10 -070042 ds_3231,
Stefan Agner8566f702017-03-23 16:54:57 -070043 m41t0,
David Brownell045e0e82007-07-17 04:04:55 -070044 m41t00,
Tomas Novotnyf4199f82014-12-10 15:53:57 -080045 mcp794xx,
Matthias Fuchsa2166852009-03-31 15:24:58 -070046 rx_8025,
Wolfram Sang32d322b2012-03-23 15:02:36 -070047 last_ds_type /* always last */
David Anders40ce9722012-03-23 15:02:37 -070048 /* rs5c372 too? different address... */
David Brownell1abb0dc2006-06-25 05:48:17 -070049};
50
David Brownell1abb0dc2006-06-25 05:48:17 -070051
52/* RTC registers don't differ much, except for the century flag */
53#define DS1307_REG_SECS 0x00 /* 00-59 */
54# define DS1307_BIT_CH 0x80
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -070055# define DS1340_BIT_nEOSC 0x80
Tomas Novotnyf4199f82014-12-10 15:53:57 -080056# define MCP794XX_BIT_ST 0x80
David Brownell1abb0dc2006-06-25 05:48:17 -070057#define DS1307_REG_MIN 0x01 /* 00-59 */
Stefan Agner8566f702017-03-23 16:54:57 -070058# define M41T0_BIT_OF 0x80
David Brownell1abb0dc2006-06-25 05:48:17 -070059#define DS1307_REG_HOUR 0x02 /* 00-23, or 1-12{am,pm} */
David Brownellc065f352007-07-17 04:05:10 -070060# define DS1307_BIT_12HR 0x40 /* in REG_HOUR */
61# define DS1307_BIT_PM 0x20 /* in REG_HOUR */
David Brownell1abb0dc2006-06-25 05:48:17 -070062# define DS1340_BIT_CENTURY_EN 0x80 /* in REG_HOUR */
63# define DS1340_BIT_CENTURY 0x40 /* in REG_HOUR */
64#define DS1307_REG_WDAY 0x03 /* 01-07 */
Tomas Novotnyf4199f82014-12-10 15:53:57 -080065# define MCP794XX_BIT_VBATEN 0x08
David Brownell1abb0dc2006-06-25 05:48:17 -070066#define DS1307_REG_MDAY 0x04 /* 01-31 */
67#define DS1307_REG_MONTH 0x05 /* 01-12 */
68# define DS1337_BIT_CENTURY 0x80 /* in REG_MONTH */
69#define DS1307_REG_YEAR 0x06 /* 00-99 */
70
David Anders40ce9722012-03-23 15:02:37 -070071/*
72 * Other registers (control, status, alarms, trickle charge, NVRAM, etc)
David Brownell045e0e82007-07-17 04:04:55 -070073 * start at 7, and they differ a LOT. Only control and status matter for
74 * basic RTC date and time functionality; be careful using them.
David Brownell1abb0dc2006-06-25 05:48:17 -070075 */
David Brownell045e0e82007-07-17 04:04:55 -070076#define DS1307_REG_CONTROL 0x07 /* or ds1338 */
David Brownell1abb0dc2006-06-25 05:48:17 -070077# define DS1307_BIT_OUT 0x80
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -070078# define DS1338_BIT_OSF 0x20
David Brownell1abb0dc2006-06-25 05:48:17 -070079# define DS1307_BIT_SQWE 0x10
80# define DS1307_BIT_RS1 0x02
81# define DS1307_BIT_RS0 0x01
82#define DS1337_REG_CONTROL 0x0e
83# define DS1337_BIT_nEOSC 0x80
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -070084# define DS1339_BIT_BBSQI 0x20
Wolfram Sang97f902b2009-06-17 16:26:10 -070085# define DS3231_BIT_BBSQW 0x40 /* same as BBSQI */
David Brownell1abb0dc2006-06-25 05:48:17 -070086# define DS1337_BIT_RS2 0x10
87# define DS1337_BIT_RS1 0x08
88# define DS1337_BIT_INTCN 0x04
89# define DS1337_BIT_A2IE 0x02
90# define DS1337_BIT_A1IE 0x01
David Brownell045e0e82007-07-17 04:04:55 -070091#define DS1340_REG_CONTROL 0x07
92# define DS1340_BIT_OUT 0x80
93# define DS1340_BIT_FT 0x40
94# define DS1340_BIT_CALIB_SIGN 0x20
95# define DS1340_M_CALIBRATION 0x1f
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -070096#define DS1340_REG_FLAG 0x09
97# define DS1340_BIT_OSF 0x80
David Brownell1abb0dc2006-06-25 05:48:17 -070098#define DS1337_REG_STATUS 0x0f
99# define DS1337_BIT_OSF 0x80
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900100# define DS3231_BIT_EN32KHZ 0x08
David Brownell1abb0dc2006-06-25 05:48:17 -0700101# define DS1337_BIT_A2I 0x02
102# define DS1337_BIT_A1I 0x01
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700103#define DS1339_REG_ALARM1_SECS 0x07
Wolfram Sangeb86c302012-05-29 15:07:38 -0700104
105#define DS13XX_TRICKLE_CHARGER_MAGIC 0xa0
David Brownell1abb0dc2006-06-25 05:48:17 -0700106
Matthias Fuchsa2166852009-03-31 15:24:58 -0700107#define RX8025_REG_CTRL1 0x0e
108# define RX8025_BIT_2412 0x20
109#define RX8025_REG_CTRL2 0x0f
110# define RX8025_BIT_PON 0x10
111# define RX8025_BIT_VDET 0x40
112# define RX8025_BIT_XST 0x20
David Brownell1abb0dc2006-06-25 05:48:17 -0700113
114
115struct ds1307 {
Joakim Tjernlund33df2ee2009-06-17 16:26:08 -0700116 u8 offset; /* register's offset */
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700117 u8 regs[11];
Austin Boyle9eab0a72012-03-23 15:02:38 -0700118 u16 nvram_offset;
119 struct bin_attribute *nvram;
David Brownell1abb0dc2006-06-25 05:48:17 -0700120 enum ds_type type;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700121 unsigned long flags;
122#define HAS_NVRAM 0 /* bit 0 == sysfs file active */
123#define HAS_ALARM 1 /* bit 1 == irq claimed */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100124 struct device *dev;
125 struct regmap *regmap;
126 const char *name;
127 int irq;
David Brownell1abb0dc2006-06-25 05:48:17 -0700128 struct rtc_device *rtc;
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900129#ifdef CONFIG_COMMON_CLK
130 struct clk_hw clks[2];
131#endif
David Brownell1abb0dc2006-06-25 05:48:17 -0700132};
133
David Brownell045e0e82007-07-17 04:04:55 -0700134struct chip_desc {
David Brownell045e0e82007-07-17 04:04:55 -0700135 unsigned alarm:1;
Austin Boyle9eab0a72012-03-23 15:02:38 -0700136 u16 nvram_offset;
137 u16 nvram_size;
Wolfram Sangeb86c302012-05-29 15:07:38 -0700138 u16 trickle_charger_reg;
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700139 u8 trickle_charger_setup;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100140 u8 (*do_trickle_setup)(struct ds1307 *, uint32_t,
141 bool);
David Brownell045e0e82007-07-17 04:04:55 -0700142};
143
Heiner Kallweit11e58902017-03-10 18:52:34 +0100144static u8 do_trickle_setup_ds1339(struct ds1307 *, uint32_t ohms, bool diode);
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700145
146static struct chip_desc chips[last_ds_type] = {
Wolfram Sang32d322b2012-03-23 15:02:36 -0700147 [ds_1307] = {
Austin Boyle9eab0a72012-03-23 15:02:38 -0700148 .nvram_offset = 8,
149 .nvram_size = 56,
Wolfram Sang32d322b2012-03-23 15:02:36 -0700150 },
151 [ds_1337] = {
152 .alarm = 1,
153 },
154 [ds_1338] = {
Austin Boyle9eab0a72012-03-23 15:02:38 -0700155 .nvram_offset = 8,
156 .nvram_size = 56,
Wolfram Sang32d322b2012-03-23 15:02:36 -0700157 },
158 [ds_1339] = {
159 .alarm = 1,
Wolfram Sangeb86c302012-05-29 15:07:38 -0700160 .trickle_charger_reg = 0x10,
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700161 .do_trickle_setup = &do_trickle_setup_ds1339,
Wolfram Sangeb86c302012-05-29 15:07:38 -0700162 },
163 [ds_1340] = {
164 .trickle_charger_reg = 0x08,
165 },
166 [ds_1388] = {
167 .trickle_charger_reg = 0x0a,
Wolfram Sang32d322b2012-03-23 15:02:36 -0700168 },
169 [ds_3231] = {
170 .alarm = 1,
171 },
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800172 [mcp794xx] = {
Simon Guinot1d1945d2014-04-03 14:49:55 -0700173 .alarm = 1,
Austin Boyle9eab0a72012-03-23 15:02:38 -0700174 /* this is battery backed SRAM */
175 .nvram_offset = 0x20,
176 .nvram_size = 0x40,
177 },
Wolfram Sang32d322b2012-03-23 15:02:36 -0700178};
David Brownell045e0e82007-07-17 04:04:55 -0700179
Jean Delvare3760f732008-04-29 23:11:40 +0200180static const struct i2c_device_id ds1307_id[] = {
181 { "ds1307", ds_1307 },
182 { "ds1337", ds_1337 },
183 { "ds1338", ds_1338 },
184 { "ds1339", ds_1339 },
Joakim Tjernlund33df2ee2009-06-17 16:26:08 -0700185 { "ds1388", ds_1388 },
Jean Delvare3760f732008-04-29 23:11:40 +0200186 { "ds1340", ds_1340 },
Wolfram Sang97f902b2009-06-17 16:26:10 -0700187 { "ds3231", ds_3231 },
Stefan Agner8566f702017-03-23 16:54:57 -0700188 { "m41t0", m41t0 },
Jean Delvare3760f732008-04-29 23:11:40 +0200189 { "m41t00", m41t00 },
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800190 { "mcp7940x", mcp794xx },
191 { "mcp7941x", mcp794xx },
Priyanka Jain31c17712011-06-27 16:18:04 -0700192 { "pt7c4338", ds_1307 },
Matthias Fuchsa2166852009-03-31 15:24:58 -0700193 { "rx8025", rx_8025 },
Alexandre Belloni78aaa062016-07-13 02:36:41 +0200194 { "isl12057", ds_1337 },
Jean Delvare3760f732008-04-29 23:11:40 +0200195 { }
196};
197MODULE_DEVICE_TABLE(i2c, ds1307_id);
David Brownell1abb0dc2006-06-25 05:48:17 -0700198
Javier Martinez Canillas7ef6d2c2017-03-03 11:29:15 -0300199#ifdef CONFIG_OF
200static const struct of_device_id ds1307_of_match[] = {
201 {
202 .compatible = "dallas,ds1307",
203 .data = (void *)ds_1307
204 },
205 {
206 .compatible = "dallas,ds1337",
207 .data = (void *)ds_1337
208 },
209 {
210 .compatible = "dallas,ds1338",
211 .data = (void *)ds_1338
212 },
213 {
214 .compatible = "dallas,ds1339",
215 .data = (void *)ds_1339
216 },
217 {
218 .compatible = "dallas,ds1388",
219 .data = (void *)ds_1388
220 },
221 {
222 .compatible = "dallas,ds1340",
223 .data = (void *)ds_1340
224 },
225 {
226 .compatible = "maxim,ds3231",
227 .data = (void *)ds_3231
228 },
229 {
Alexandre Bellonidb2f8142017-04-08 17:22:02 +0200230 .compatible = "st,m41t0",
231 .data = (void *)m41t00
232 },
233 {
Javier Martinez Canillas7ef6d2c2017-03-03 11:29:15 -0300234 .compatible = "st,m41t00",
235 .data = (void *)m41t00
236 },
237 {
238 .compatible = "microchip,mcp7940x",
239 .data = (void *)mcp794xx
240 },
241 {
242 .compatible = "microchip,mcp7941x",
243 .data = (void *)mcp794xx
244 },
245 {
246 .compatible = "pericom,pt7c4338",
247 .data = (void *)ds_1307
248 },
249 {
250 .compatible = "epson,rx8025",
251 .data = (void *)rx_8025
252 },
253 {
254 .compatible = "isil,isl12057",
255 .data = (void *)ds_1337
256 },
257 { }
258};
259MODULE_DEVICE_TABLE(of, ds1307_of_match);
260#endif
261
Tin Huynh9c19b892016-11-30 09:57:31 +0700262#ifdef CONFIG_ACPI
263static const struct acpi_device_id ds1307_acpi_ids[] = {
264 { .id = "DS1307", .driver_data = ds_1307 },
265 { .id = "DS1337", .driver_data = ds_1337 },
266 { .id = "DS1338", .driver_data = ds_1338 },
267 { .id = "DS1339", .driver_data = ds_1339 },
268 { .id = "DS1388", .driver_data = ds_1388 },
269 { .id = "DS1340", .driver_data = ds_1340 },
270 { .id = "DS3231", .driver_data = ds_3231 },
Stefan Agner8566f702017-03-23 16:54:57 -0700271 { .id = "M41T0", .driver_data = m41t0 },
Tin Huynh9c19b892016-11-30 09:57:31 +0700272 { .id = "M41T00", .driver_data = m41t00 },
273 { .id = "MCP7940X", .driver_data = mcp794xx },
274 { .id = "MCP7941X", .driver_data = mcp794xx },
275 { .id = "PT7C4338", .driver_data = ds_1307 },
276 { .id = "RX8025", .driver_data = rx_8025 },
277 { .id = "ISL12057", .driver_data = ds_1337 },
278 { }
279};
280MODULE_DEVICE_TABLE(acpi, ds1307_acpi_ids);
281#endif
282
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700283/*
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700284 * The ds1337 and ds1339 both have two alarms, but we only use the first
285 * one (with a "seconds" field). For ds1337 we expect nINTA is our alarm
286 * signal; ds1339 chips have only one alarm signal.
287 */
Felipe Balbi2fb07a12015-06-23 11:15:10 -0500288static irqreturn_t ds1307_irq(int irq, void *dev_id)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700289{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100290 struct ds1307 *ds1307 = dev_id;
Felipe Balbi2fb07a12015-06-23 11:15:10 -0500291 struct mutex *lock = &ds1307->rtc->ops_lock;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100292 int stat, control, ret;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700293
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700294 mutex_lock(lock);
Heiner Kallweit11e58902017-03-10 18:52:34 +0100295 ret = regmap_read(ds1307->regmap, DS1337_REG_STATUS, &stat);
296 if (ret)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700297 goto out;
298
299 if (stat & DS1337_BIT_A1I) {
300 stat &= ~DS1337_BIT_A1I;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100301 regmap_write(ds1307->regmap, DS1337_REG_STATUS, stat);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700302
Heiner Kallweit11e58902017-03-10 18:52:34 +0100303 ret = regmap_read(ds1307->regmap, DS1337_REG_CONTROL, &control);
304 if (ret)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700305 goto out;
306
307 control &= ~DS1337_BIT_A1IE;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100308 regmap_write(ds1307->regmap, DS1337_REG_CONTROL, control);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700309
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700310 rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700311 }
312
313out:
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700314 mutex_unlock(lock);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700315
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700316 return IRQ_HANDLED;
317}
318
319/*----------------------------------------------------------------------*/
320
David Brownell1abb0dc2006-06-25 05:48:17 -0700321static int ds1307_get_time(struct device *dev, struct rtc_time *t)
322{
323 struct ds1307 *ds1307 = dev_get_drvdata(dev);
Heiner Kallweit11e58902017-03-10 18:52:34 +0100324 int tmp, ret;
David Brownell1abb0dc2006-06-25 05:48:17 -0700325
David Brownell045e0e82007-07-17 04:04:55 -0700326 /* read the RTC date and time registers all at once */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100327 ret = regmap_bulk_read(ds1307->regmap, ds1307->offset, ds1307->regs, 7);
328 if (ret) {
329 dev_err(dev, "%s error %d\n", "read", ret);
330 return ret;
David Brownell1abb0dc2006-06-25 05:48:17 -0700331 }
332
Andy Shevchenko01a4ca12013-02-21 16:44:22 -0800333 dev_dbg(dev, "%s: %7ph\n", "read", ds1307->regs);
David Brownell1abb0dc2006-06-25 05:48:17 -0700334
Stefan Agner8566f702017-03-23 16:54:57 -0700335 /* if oscillator fail bit is set, no data can be trusted */
336 if (ds1307->type == m41t0 &&
337 ds1307->regs[DS1307_REG_MIN] & M41T0_BIT_OF) {
338 dev_warn_once(dev, "oscillator failed, set time!\n");
339 return -EINVAL;
340 }
341
Adrian Bunkfe20ba72008-10-18 20:28:41 -0700342 t->tm_sec = bcd2bin(ds1307->regs[DS1307_REG_SECS] & 0x7f);
343 t->tm_min = bcd2bin(ds1307->regs[DS1307_REG_MIN] & 0x7f);
David Brownell1abb0dc2006-06-25 05:48:17 -0700344 tmp = ds1307->regs[DS1307_REG_HOUR] & 0x3f;
Adrian Bunkfe20ba72008-10-18 20:28:41 -0700345 t->tm_hour = bcd2bin(tmp);
346 t->tm_wday = bcd2bin(ds1307->regs[DS1307_REG_WDAY] & 0x07) - 1;
347 t->tm_mday = bcd2bin(ds1307->regs[DS1307_REG_MDAY] & 0x3f);
David Brownell1abb0dc2006-06-25 05:48:17 -0700348 tmp = ds1307->regs[DS1307_REG_MONTH] & 0x1f;
Adrian Bunkfe20ba72008-10-18 20:28:41 -0700349 t->tm_mon = bcd2bin(tmp) - 1;
Adrian Bunkfe20ba72008-10-18 20:28:41 -0700350 t->tm_year = bcd2bin(ds1307->regs[DS1307_REG_YEAR]) + 100;
David Brownell1abb0dc2006-06-25 05:48:17 -0700351
Alexandre Belloni50d6c0e2016-07-13 02:26:08 +0200352#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
353 switch (ds1307->type) {
354 case ds_1337:
355 case ds_1339:
356 case ds_3231:
357 if (ds1307->regs[DS1307_REG_MONTH] & DS1337_BIT_CENTURY)
358 t->tm_year += 100;
359 break;
360 case ds_1340:
361 if (ds1307->regs[DS1307_REG_HOUR] & DS1340_BIT_CENTURY)
362 t->tm_year += 100;
363 break;
364 default:
365 break;
366 }
367#endif
368
David Brownell1abb0dc2006-06-25 05:48:17 -0700369 dev_dbg(dev, "%s secs=%d, mins=%d, "
370 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
371 "read", t->tm_sec, t->tm_min,
372 t->tm_hour, t->tm_mday,
373 t->tm_mon, t->tm_year, t->tm_wday);
374
David Brownell045e0e82007-07-17 04:04:55 -0700375 /* initial clock setting can be undefined */
376 return rtc_valid_tm(t);
David Brownell1abb0dc2006-06-25 05:48:17 -0700377}
378
379static int ds1307_set_time(struct device *dev, struct rtc_time *t)
380{
381 struct ds1307 *ds1307 = dev_get_drvdata(dev);
382 int result;
383 int tmp;
384 u8 *buf = ds1307->regs;
385
386 dev_dbg(dev, "%s secs=%d, mins=%d, "
387 "hours=%d, mday=%d, mon=%d, year=%d, wday=%d\n",
Jeff Garzik11966ad2006-10-04 04:41:53 -0400388 "write", t->tm_sec, t->tm_min,
389 t->tm_hour, t->tm_mday,
390 t->tm_mon, t->tm_year, t->tm_wday);
David Brownell1abb0dc2006-06-25 05:48:17 -0700391
Alexandre Belloni50d6c0e2016-07-13 02:26:08 +0200392#ifdef CONFIG_RTC_DRV_DS1307_CENTURY
393 if (t->tm_year < 100)
394 return -EINVAL;
395
396 switch (ds1307->type) {
397 case ds_1337:
398 case ds_1339:
399 case ds_3231:
400 case ds_1340:
401 if (t->tm_year > 299)
402 return -EINVAL;
403 default:
404 if (t->tm_year > 199)
405 return -EINVAL;
406 break;
407 }
408#else
409 if (t->tm_year < 100 || t->tm_year > 199)
410 return -EINVAL;
411#endif
412
Adrian Bunkfe20ba72008-10-18 20:28:41 -0700413 buf[DS1307_REG_SECS] = bin2bcd(t->tm_sec);
414 buf[DS1307_REG_MIN] = bin2bcd(t->tm_min);
415 buf[DS1307_REG_HOUR] = bin2bcd(t->tm_hour);
416 buf[DS1307_REG_WDAY] = bin2bcd(t->tm_wday + 1);
417 buf[DS1307_REG_MDAY] = bin2bcd(t->tm_mday);
418 buf[DS1307_REG_MONTH] = bin2bcd(t->tm_mon + 1);
David Brownell1abb0dc2006-06-25 05:48:17 -0700419
420 /* assume 20YY not 19YY */
421 tmp = t->tm_year - 100;
Adrian Bunkfe20ba72008-10-18 20:28:41 -0700422 buf[DS1307_REG_YEAR] = bin2bcd(tmp);
David Brownell1abb0dc2006-06-25 05:48:17 -0700423
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -0700424 switch (ds1307->type) {
425 case ds_1337:
426 case ds_1339:
Wolfram Sang97f902b2009-06-17 16:26:10 -0700427 case ds_3231:
Alexandre Belloni50d6c0e2016-07-13 02:26:08 +0200428 if (t->tm_year > 199)
429 buf[DS1307_REG_MONTH] |= DS1337_BIT_CENTURY;
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -0700430 break;
431 case ds_1340:
Alexandre Belloni50d6c0e2016-07-13 02:26:08 +0200432 buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY_EN;
433 if (t->tm_year > 199)
434 buf[DS1307_REG_HOUR] |= DS1340_BIT_CENTURY;
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -0700435 break;
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800436 case mcp794xx:
David Anders40ce9722012-03-23 15:02:37 -0700437 /*
438 * these bits were cleared when preparing the date/time
439 * values and need to be set again before writing the
440 * buffer out to the device.
441 */
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800442 buf[DS1307_REG_SECS] |= MCP794XX_BIT_ST;
443 buf[DS1307_REG_WDAY] |= MCP794XX_BIT_VBATEN;
David Anders43fcb812011-11-02 13:37:53 -0700444 break;
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -0700445 default:
446 break;
447 }
David Brownell1abb0dc2006-06-25 05:48:17 -0700448
Andy Shevchenko01a4ca12013-02-21 16:44:22 -0800449 dev_dbg(dev, "%s: %7ph\n", "write", buf);
David Brownell1abb0dc2006-06-25 05:48:17 -0700450
Heiner Kallweit11e58902017-03-10 18:52:34 +0100451 result = regmap_bulk_write(ds1307->regmap, ds1307->offset, buf, 7);
452 if (result) {
BARRE Sebastienfed40b72009-01-07 18:07:13 -0800453 dev_err(dev, "%s error %d\n", "write", result);
454 return result;
David Brownell1abb0dc2006-06-25 05:48:17 -0700455 }
456 return 0;
457}
458
Jüri Reitel74d88eb2009-01-07 18:07:16 -0800459static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700460{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100461 struct ds1307 *ds1307 = dev_get_drvdata(dev);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700462 int ret;
463
464 if (!test_bit(HAS_ALARM, &ds1307->flags))
465 return -EINVAL;
466
467 /* read all ALARM1, ALARM2, and status registers at once */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100468 ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS,
469 ds1307->regs, 9);
470 if (ret) {
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700471 dev_err(dev, "%s error %d\n", "alarm read", ret);
Heiner Kallweit11e58902017-03-10 18:52:34 +0100472 return ret;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700473 }
474
Rasmus Villemoesff67abd2015-11-24 14:51:23 +0100475 dev_dbg(dev, "%s: %4ph, %3ph, %2ph\n", "alarm read",
476 &ds1307->regs[0], &ds1307->regs[4], &ds1307->regs[7]);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700477
David Anders40ce9722012-03-23 15:02:37 -0700478 /*
479 * report alarm time (ALARM1); assume 24 hour and day-of-month modes,
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700480 * and that all four fields are checked matches
481 */
482 t->time.tm_sec = bcd2bin(ds1307->regs[0] & 0x7f);
483 t->time.tm_min = bcd2bin(ds1307->regs[1] & 0x7f);
484 t->time.tm_hour = bcd2bin(ds1307->regs[2] & 0x3f);
485 t->time.tm_mday = bcd2bin(ds1307->regs[3] & 0x3f);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700486
487 /* ... and status */
488 t->enabled = !!(ds1307->regs[7] & DS1337_BIT_A1IE);
489 t->pending = !!(ds1307->regs[8] & DS1337_BIT_A1I);
490
491 dev_dbg(dev, "%s secs=%d, mins=%d, "
492 "hours=%d, mday=%d, enabled=%d, pending=%d\n",
493 "alarm read", t->time.tm_sec, t->time.tm_min,
494 t->time.tm_hour, t->time.tm_mday,
495 t->enabled, t->pending);
496
497 return 0;
498}
499
Jüri Reitel74d88eb2009-01-07 18:07:16 -0800500static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700501{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100502 struct ds1307 *ds1307 = dev_get_drvdata(dev);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700503 unsigned char *buf = ds1307->regs;
504 u8 control, status;
505 int ret;
506
507 if (!test_bit(HAS_ALARM, &ds1307->flags))
508 return -EINVAL;
509
510 dev_dbg(dev, "%s secs=%d, mins=%d, "
511 "hours=%d, mday=%d, enabled=%d, pending=%d\n",
512 "alarm set", t->time.tm_sec, t->time.tm_min,
513 t->time.tm_hour, t->time.tm_mday,
514 t->enabled, t->pending);
515
516 /* read current status of both alarms and the chip */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100517 ret = regmap_bulk_read(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9);
518 if (ret) {
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700519 dev_err(dev, "%s error %d\n", "alarm write", ret);
Heiner Kallweit11e58902017-03-10 18:52:34 +0100520 return ret;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700521 }
522 control = ds1307->regs[7];
523 status = ds1307->regs[8];
524
Rasmus Villemoesff67abd2015-11-24 14:51:23 +0100525 dev_dbg(dev, "%s: %4ph, %3ph, %02x %02x\n", "alarm set (old status)",
526 &ds1307->regs[0], &ds1307->regs[4], control, status);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700527
528 /* set ALARM1, using 24 hour and day-of-month modes */
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700529 buf[0] = bin2bcd(t->time.tm_sec);
530 buf[1] = bin2bcd(t->time.tm_min);
531 buf[2] = bin2bcd(t->time.tm_hour);
532 buf[3] = bin2bcd(t->time.tm_mday);
533
534 /* set ALARM2 to non-garbage */
535 buf[4] = 0;
536 buf[5] = 0;
537 buf[6] = 0;
538
Nicolas Boullis5919fb92016-04-10 13:23:05 +0200539 /* disable alarms */
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700540 buf[7] = control & ~(DS1337_BIT_A1IE | DS1337_BIT_A2IE);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700541 buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
542
Heiner Kallweit11e58902017-03-10 18:52:34 +0100543 ret = regmap_bulk_write(ds1307->regmap, DS1339_REG_ALARM1_SECS, buf, 9);
544 if (ret) {
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700545 dev_err(dev, "can't set alarm time\n");
BARRE Sebastienfed40b72009-01-07 18:07:13 -0800546 return ret;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700547 }
548
Nicolas Boullis5919fb92016-04-10 13:23:05 +0200549 /* optionally enable ALARM1 */
550 if (t->enabled) {
551 dev_dbg(dev, "alarm IRQ armed\n");
552 buf[7] |= DS1337_BIT_A1IE; /* only ALARM1 is used */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100553 regmap_write(ds1307->regmap, DS1337_REG_CONTROL, buf[7]);
Nicolas Boullis5919fb92016-04-10 13:23:05 +0200554 }
555
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700556 return 0;
557}
558
John Stultz16380c12011-02-02 17:02:41 -0800559static int ds1307_alarm_irq_enable(struct device *dev, unsigned int enabled)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700560{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100561 struct ds1307 *ds1307 = dev_get_drvdata(dev);
562 int control, ret;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700563
John Stultz16380c12011-02-02 17:02:41 -0800564 if (!test_bit(HAS_ALARM, &ds1307->flags))
565 return -ENOTTY;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700566
Heiner Kallweit11e58902017-03-10 18:52:34 +0100567 ret = regmap_read(ds1307->regmap, DS1337_REG_CONTROL, &control);
568 if (ret)
John Stultz16380c12011-02-02 17:02:41 -0800569 return ret;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700570
John Stultz16380c12011-02-02 17:02:41 -0800571 if (enabled)
Heiner Kallweit11e58902017-03-10 18:52:34 +0100572 control |= DS1337_BIT_A1IE;
John Stultz16380c12011-02-02 17:02:41 -0800573 else
Heiner Kallweit11e58902017-03-10 18:52:34 +0100574 control &= ~DS1337_BIT_A1IE;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700575
Heiner Kallweit11e58902017-03-10 18:52:34 +0100576 return regmap_write(ds1307->regmap, DS1337_REG_CONTROL, control);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -0700577}
578
David Brownellff8371a2006-09-30 23:28:17 -0700579static const struct rtc_class_ops ds13xx_rtc_ops = {
David Brownell1abb0dc2006-06-25 05:48:17 -0700580 .read_time = ds1307_get_time,
581 .set_time = ds1307_set_time,
Jüri Reitel74d88eb2009-01-07 18:07:16 -0800582 .read_alarm = ds1337_read_alarm,
583 .set_alarm = ds1337_set_alarm,
John Stultz16380c12011-02-02 17:02:41 -0800584 .alarm_irq_enable = ds1307_alarm_irq_enable,
David Brownell1abb0dc2006-06-25 05:48:17 -0700585};
586
David Brownell682d73f2007-11-14 16:58:32 -0800587/*----------------------------------------------------------------------*/
588
Simon Guinot1d1945d2014-04-03 14:49:55 -0700589/*
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800590 * Alarm support for mcp794xx devices.
Simon Guinot1d1945d2014-04-03 14:49:55 -0700591 */
592
Keerthye29385f2016-06-01 16:19:07 +0530593#define MCP794XX_REG_WEEKDAY 0x3
594#define MCP794XX_REG_WEEKDAY_WDAY_MASK 0x7
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800595#define MCP794XX_REG_CONTROL 0x07
596# define MCP794XX_BIT_ALM0_EN 0x10
597# define MCP794XX_BIT_ALM1_EN 0x20
598#define MCP794XX_REG_ALARM0_BASE 0x0a
599#define MCP794XX_REG_ALARM0_CTRL 0x0d
600#define MCP794XX_REG_ALARM1_BASE 0x11
601#define MCP794XX_REG_ALARM1_CTRL 0x14
602# define MCP794XX_BIT_ALMX_IF (1 << 3)
603# define MCP794XX_BIT_ALMX_C0 (1 << 4)
604# define MCP794XX_BIT_ALMX_C1 (1 << 5)
605# define MCP794XX_BIT_ALMX_C2 (1 << 6)
606# define MCP794XX_BIT_ALMX_POL (1 << 7)
607# define MCP794XX_MSK_ALMX_MATCH (MCP794XX_BIT_ALMX_C0 | \
608 MCP794XX_BIT_ALMX_C1 | \
609 MCP794XX_BIT_ALMX_C2)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700610
Felipe Balbi2fb07a12015-06-23 11:15:10 -0500611static irqreturn_t mcp794xx_irq(int irq, void *dev_id)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700612{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100613 struct ds1307 *ds1307 = dev_id;
Felipe Balbi2fb07a12015-06-23 11:15:10 -0500614 struct mutex *lock = &ds1307->rtc->ops_lock;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700615 int reg, ret;
616
Felipe Balbi2fb07a12015-06-23 11:15:10 -0500617 mutex_lock(lock);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700618
619 /* Check and clear alarm 0 interrupt flag. */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100620 ret = regmap_read(ds1307->regmap, MCP794XX_REG_ALARM0_CTRL, &reg);
621 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700622 goto out;
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800623 if (!(reg & MCP794XX_BIT_ALMX_IF))
Simon Guinot1d1945d2014-04-03 14:49:55 -0700624 goto out;
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800625 reg &= ~MCP794XX_BIT_ALMX_IF;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100626 ret = regmap_write(ds1307->regmap, MCP794XX_REG_ALARM0_CTRL, reg);
627 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700628 goto out;
629
630 /* Disable alarm 0. */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100631 ret = regmap_read(ds1307->regmap, MCP794XX_REG_CONTROL, &reg);
632 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700633 goto out;
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800634 reg &= ~MCP794XX_BIT_ALM0_EN;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100635 ret = regmap_write(ds1307->regmap, MCP794XX_REG_CONTROL, reg);
636 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700637 goto out;
638
639 rtc_update_irq(ds1307->rtc, 1, RTC_AF | RTC_IRQF);
640
641out:
Felipe Balbi2fb07a12015-06-23 11:15:10 -0500642 mutex_unlock(lock);
643
644 return IRQ_HANDLED;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700645}
646
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800647static int mcp794xx_read_alarm(struct device *dev, struct rtc_wkalrm *t)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700648{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100649 struct ds1307 *ds1307 = dev_get_drvdata(dev);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700650 u8 *regs = ds1307->regs;
651 int ret;
652
653 if (!test_bit(HAS_ALARM, &ds1307->flags))
654 return -EINVAL;
655
656 /* Read control and alarm 0 registers. */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100657 ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
658 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700659 return ret;
660
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800661 t->enabled = !!(regs[0] & MCP794XX_BIT_ALM0_EN);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700662
663 /* Report alarm 0 time assuming 24-hour and day-of-month modes. */
664 t->time.tm_sec = bcd2bin(ds1307->regs[3] & 0x7f);
665 t->time.tm_min = bcd2bin(ds1307->regs[4] & 0x7f);
666 t->time.tm_hour = bcd2bin(ds1307->regs[5] & 0x3f);
667 t->time.tm_wday = bcd2bin(ds1307->regs[6] & 0x7) - 1;
668 t->time.tm_mday = bcd2bin(ds1307->regs[7] & 0x3f);
669 t->time.tm_mon = bcd2bin(ds1307->regs[8] & 0x1f) - 1;
670 t->time.tm_year = -1;
671 t->time.tm_yday = -1;
672 t->time.tm_isdst = -1;
673
674 dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
675 "enabled=%d polarity=%d irq=%d match=%d\n", __func__,
676 t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
677 t->time.tm_wday, t->time.tm_mday, t->time.tm_mon, t->enabled,
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800678 !!(ds1307->regs[6] & MCP794XX_BIT_ALMX_POL),
679 !!(ds1307->regs[6] & MCP794XX_BIT_ALMX_IF),
680 (ds1307->regs[6] & MCP794XX_MSK_ALMX_MATCH) >> 4);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700681
682 return 0;
683}
684
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800685static int mcp794xx_set_alarm(struct device *dev, struct rtc_wkalrm *t)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700686{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100687 struct ds1307 *ds1307 = dev_get_drvdata(dev);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700688 unsigned char *regs = ds1307->regs;
689 int ret;
690
691 if (!test_bit(HAS_ALARM, &ds1307->flags))
692 return -EINVAL;
693
694 dev_dbg(dev, "%s, sec=%d min=%d hour=%d wday=%d mday=%d mon=%d "
695 "enabled=%d pending=%d\n", __func__,
696 t->time.tm_sec, t->time.tm_min, t->time.tm_hour,
697 t->time.tm_wday, t->time.tm_mday, t->time.tm_mon,
698 t->enabled, t->pending);
699
700 /* Read control and alarm 0 registers. */
Heiner Kallweit11e58902017-03-10 18:52:34 +0100701 ret = regmap_bulk_read(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
702 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700703 return ret;
704
705 /* Set alarm 0, using 24-hour and day-of-month modes. */
706 regs[3] = bin2bcd(t->time.tm_sec);
707 regs[4] = bin2bcd(t->time.tm_min);
708 regs[5] = bin2bcd(t->time.tm_hour);
Tero Kristo62c8c202015-10-23 09:29:57 +0300709 regs[6] = bin2bcd(t->time.tm_wday + 1);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700710 regs[7] = bin2bcd(t->time.tm_mday);
Tero Kristo62c8c202015-10-23 09:29:57 +0300711 regs[8] = bin2bcd(t->time.tm_mon + 1);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700712
713 /* Clear the alarm 0 interrupt flag. */
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800714 regs[6] &= ~MCP794XX_BIT_ALMX_IF;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700715 /* Set alarm match: second, minute, hour, day, date, month. */
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800716 regs[6] |= MCP794XX_MSK_ALMX_MATCH;
Nishanth Menone3edd672015-04-20 19:51:34 -0500717 /* Disable interrupt. We will not enable until completely programmed */
718 regs[0] &= ~MCP794XX_BIT_ALM0_EN;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700719
Heiner Kallweit11e58902017-03-10 18:52:34 +0100720 ret = regmap_bulk_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs, 10);
721 if (ret)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700722 return ret;
723
Nishanth Menone3edd672015-04-20 19:51:34 -0500724 if (!t->enabled)
725 return 0;
726 regs[0] |= MCP794XX_BIT_ALM0_EN;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100727 return regmap_write(ds1307->regmap, MCP794XX_REG_CONTROL, regs[0]);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700728}
729
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800730static int mcp794xx_alarm_irq_enable(struct device *dev, unsigned int enabled)
Simon Guinot1d1945d2014-04-03 14:49:55 -0700731{
Heiner Kallweit11e58902017-03-10 18:52:34 +0100732 struct ds1307 *ds1307 = dev_get_drvdata(dev);
733 int reg, ret;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700734
735 if (!test_bit(HAS_ALARM, &ds1307->flags))
736 return -EINVAL;
737
Heiner Kallweit11e58902017-03-10 18:52:34 +0100738 ret = regmap_read(ds1307->regmap, MCP794XX_REG_CONTROL, &reg);
739 if (ret)
740 return ret;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700741
742 if (enabled)
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800743 reg |= MCP794XX_BIT_ALM0_EN;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700744 else
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800745 reg &= ~MCP794XX_BIT_ALM0_EN;
Simon Guinot1d1945d2014-04-03 14:49:55 -0700746
Heiner Kallweit11e58902017-03-10 18:52:34 +0100747 return regmap_write(ds1307->regmap, MCP794XX_REG_CONTROL, reg);
Simon Guinot1d1945d2014-04-03 14:49:55 -0700748}
749
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800750static const struct rtc_class_ops mcp794xx_rtc_ops = {
Simon Guinot1d1945d2014-04-03 14:49:55 -0700751 .read_time = ds1307_get_time,
752 .set_time = ds1307_set_time,
Tomas Novotnyf4199f82014-12-10 15:53:57 -0800753 .read_alarm = mcp794xx_read_alarm,
754 .set_alarm = mcp794xx_set_alarm,
755 .alarm_irq_enable = mcp794xx_alarm_irq_enable,
Simon Guinot1d1945d2014-04-03 14:49:55 -0700756};
757
758/*----------------------------------------------------------------------*/
759
David Brownell682d73f2007-11-14 16:58:32 -0800760static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -0700761ds1307_nvram_read(struct file *filp, struct kobject *kobj,
762 struct bin_attribute *attr,
David Brownell682d73f2007-11-14 16:58:32 -0800763 char *buf, loff_t off, size_t count)
764{
David Brownell682d73f2007-11-14 16:58:32 -0800765 struct ds1307 *ds1307;
David Brownell682d73f2007-11-14 16:58:32 -0800766 int result;
767
Heiner Kallweit11e58902017-03-10 18:52:34 +0100768 ds1307 = dev_get_drvdata(kobj_to_dev(kobj));
David Brownell682d73f2007-11-14 16:58:32 -0800769
Heiner Kallweit11e58902017-03-10 18:52:34 +0100770 result = regmap_bulk_read(ds1307->regmap, ds1307->nvram_offset + off,
771 buf, count);
772 if (result)
773 dev_err(ds1307->dev, "%s error %d\n", "nvram read", result);
BARRE Sebastienfed40b72009-01-07 18:07:13 -0800774 return result;
David Brownell682d73f2007-11-14 16:58:32 -0800775}
776
777static ssize_t
Chris Wright2c3c8be2010-05-12 18:28:57 -0700778ds1307_nvram_write(struct file *filp, struct kobject *kobj,
779 struct bin_attribute *attr,
David Brownell682d73f2007-11-14 16:58:32 -0800780 char *buf, loff_t off, size_t count)
781{
Ed Swierk30e7b032009-03-31 15:24:56 -0700782 struct ds1307 *ds1307;
BARRE Sebastienfed40b72009-01-07 18:07:13 -0800783 int result;
David Brownell682d73f2007-11-14 16:58:32 -0800784
Heiner Kallweit11e58902017-03-10 18:52:34 +0100785 ds1307 = dev_get_drvdata(kobj_to_dev(kobj));
David Brownell682d73f2007-11-14 16:58:32 -0800786
Heiner Kallweit11e58902017-03-10 18:52:34 +0100787 result = regmap_bulk_write(ds1307->regmap, ds1307->nvram_offset + off,
788 buf, count);
789 if (result) {
790 dev_err(ds1307->dev, "%s error %d\n", "nvram write", result);
BARRE Sebastienfed40b72009-01-07 18:07:13 -0800791 return result;
792 }
793 return count;
David Brownell682d73f2007-11-14 16:58:32 -0800794}
795
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700796
David Brownell682d73f2007-11-14 16:58:32 -0800797/*----------------------------------------------------------------------*/
798
Heiner Kallweit11e58902017-03-10 18:52:34 +0100799static u8 do_trickle_setup_ds1339(struct ds1307 *ds1307,
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700800 uint32_t ohms, bool diode)
801{
802 u8 setup = (diode) ? DS1307_TRICKLE_CHARGER_DIODE :
803 DS1307_TRICKLE_CHARGER_NO_DIODE;
804
805 switch (ohms) {
806 case 250:
807 setup |= DS1307_TRICKLE_CHARGER_250_OHM;
808 break;
809 case 2000:
810 setup |= DS1307_TRICKLE_CHARGER_2K_OHM;
811 break;
812 case 4000:
813 setup |= DS1307_TRICKLE_CHARGER_4K_OHM;
814 break;
815 default:
Heiner Kallweit11e58902017-03-10 18:52:34 +0100816 dev_warn(ds1307->dev,
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700817 "Unsupported ohm value %u in dt\n", ohms);
818 return 0;
819 }
820 return setup;
821}
822
Heiner Kallweit11e58902017-03-10 18:52:34 +0100823static void ds1307_trickle_init(struct ds1307 *ds1307,
Tin Huynh9c19b892016-11-30 09:57:31 +0700824 struct chip_desc *chip)
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700825{
826 uint32_t ohms = 0;
827 bool diode = true;
828
829 if (!chip->do_trickle_setup)
830 goto out;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100831 if (device_property_read_u32(ds1307->dev, "trickle-resistor-ohms",
832 &ohms))
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700833 goto out;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100834 if (device_property_read_bool(ds1307->dev, "trickle-diode-disable"))
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700835 diode = false;
Heiner Kallweit11e58902017-03-10 18:52:34 +0100836 chip->trickle_charger_setup = chip->do_trickle_setup(ds1307,
Matti Vaittinen33b04b72014-10-13 15:52:48 -0700837 ohms, diode);
838out:
839 return;
840}
841
Akinobu Mita445c0202016-01-25 00:22:16 +0900842/*----------------------------------------------------------------------*/
843
844#ifdef CONFIG_RTC_DRV_DS1307_HWMON
845
846/*
847 * Temperature sensor support for ds3231 devices.
848 */
849
850#define DS3231_REG_TEMPERATURE 0x11
851
852/*
853 * A user-initiated temperature conversion is not started by this function,
854 * so the temperature is updated once every 64 seconds.
855 */
Zhuang Yuyao9a3dce62016-04-18 09:21:42 +0900856static int ds3231_hwmon_read_temp(struct device *dev, s32 *mC)
Akinobu Mita445c0202016-01-25 00:22:16 +0900857{
858 struct ds1307 *ds1307 = dev_get_drvdata(dev);
859 u8 temp_buf[2];
860 s16 temp;
861 int ret;
862
Heiner Kallweit11e58902017-03-10 18:52:34 +0100863 ret = regmap_bulk_read(ds1307->regmap, DS3231_REG_TEMPERATURE,
864 temp_buf, sizeof(temp_buf));
865 if (ret)
Akinobu Mita445c0202016-01-25 00:22:16 +0900866 return ret;
Akinobu Mita445c0202016-01-25 00:22:16 +0900867 /*
868 * Temperature is represented as a 10-bit code with a resolution of
869 * 0.25 degree celsius and encoded in two's complement format.
870 */
871 temp = (temp_buf[0] << 8) | temp_buf[1];
872 temp >>= 6;
873 *mC = temp * 250;
874
875 return 0;
876}
877
878static ssize_t ds3231_hwmon_show_temp(struct device *dev,
879 struct device_attribute *attr, char *buf)
880{
881 int ret;
Zhuang Yuyao9a3dce62016-04-18 09:21:42 +0900882 s32 temp;
Akinobu Mita445c0202016-01-25 00:22:16 +0900883
884 ret = ds3231_hwmon_read_temp(dev, &temp);
885 if (ret)
886 return ret;
887
888 return sprintf(buf, "%d\n", temp);
889}
890static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ds3231_hwmon_show_temp,
891 NULL, 0);
892
893static struct attribute *ds3231_hwmon_attrs[] = {
894 &sensor_dev_attr_temp1_input.dev_attr.attr,
895 NULL,
896};
897ATTRIBUTE_GROUPS(ds3231_hwmon);
898
899static void ds1307_hwmon_register(struct ds1307 *ds1307)
900{
901 struct device *dev;
902
903 if (ds1307->type != ds_3231)
904 return;
905
Heiner Kallweit11e58902017-03-10 18:52:34 +0100906 dev = devm_hwmon_device_register_with_groups(ds1307->dev, ds1307->name,
Akinobu Mita445c0202016-01-25 00:22:16 +0900907 ds1307, ds3231_hwmon_groups);
908 if (IS_ERR(dev)) {
Heiner Kallweit11e58902017-03-10 18:52:34 +0100909 dev_warn(ds1307->dev, "unable to register hwmon device %ld\n",
910 PTR_ERR(dev));
Akinobu Mita445c0202016-01-25 00:22:16 +0900911 }
912}
913
914#else
915
916static void ds1307_hwmon_register(struct ds1307 *ds1307)
917{
918}
919
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900920#endif /* CONFIG_RTC_DRV_DS1307_HWMON */
921
922/*----------------------------------------------------------------------*/
923
924/*
925 * Square-wave output support for DS3231
926 * Datasheet: https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
927 */
928#ifdef CONFIG_COMMON_CLK
929
930enum {
931 DS3231_CLK_SQW = 0,
932 DS3231_CLK_32KHZ,
933};
934
935#define clk_sqw_to_ds1307(clk) \
936 container_of(clk, struct ds1307, clks[DS3231_CLK_SQW])
937#define clk_32khz_to_ds1307(clk) \
938 container_of(clk, struct ds1307, clks[DS3231_CLK_32KHZ])
939
940static int ds3231_clk_sqw_rates[] = {
941 1,
942 1024,
943 4096,
944 8192,
945};
946
947static int ds1337_write_control(struct ds1307 *ds1307, u8 mask, u8 value)
948{
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900949 struct mutex *lock = &ds1307->rtc->ops_lock;
950 int control;
951 int ret;
952
953 mutex_lock(lock);
954
Heiner Kallweit11e58902017-03-10 18:52:34 +0100955 ret = regmap_read(ds1307->regmap, DS1337_REG_CONTROL, &control);
956 if (ret)
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900957 goto out;
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900958
959 control &= ~mask;
960 control |= value;
961
Heiner Kallweit11e58902017-03-10 18:52:34 +0100962 ret = regmap_write(ds1307->regmap, DS1337_REG_CONTROL, control);
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900963out:
964 mutex_unlock(lock);
965
966 return ret;
967}
968
969static unsigned long ds3231_clk_sqw_recalc_rate(struct clk_hw *hw,
970 unsigned long parent_rate)
971{
972 struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw);
Heiner Kallweit11e58902017-03-10 18:52:34 +0100973 int control, ret;
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900974 int rate_sel = 0;
975
Heiner Kallweit11e58902017-03-10 18:52:34 +0100976 ret = regmap_read(ds1307->regmap, DS1337_REG_CONTROL, &control);
977 if (ret)
978 return ret;
Akinobu Mita6c6ff142016-01-31 23:10:10 +0900979 if (control & DS1337_BIT_RS1)
980 rate_sel += 1;
981 if (control & DS1337_BIT_RS2)
982 rate_sel += 2;
983
984 return ds3231_clk_sqw_rates[rate_sel];
985}
986
987static long ds3231_clk_sqw_round_rate(struct clk_hw *hw, unsigned long rate,
988 unsigned long *prate)
989{
990 int i;
991
992 for (i = ARRAY_SIZE(ds3231_clk_sqw_rates) - 1; i >= 0; i--) {
993 if (ds3231_clk_sqw_rates[i] <= rate)
994 return ds3231_clk_sqw_rates[i];
995 }
996
997 return 0;
998}
999
1000static int ds3231_clk_sqw_set_rate(struct clk_hw *hw, unsigned long rate,
1001 unsigned long parent_rate)
1002{
1003 struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw);
1004 int control = 0;
1005 int rate_sel;
1006
1007 for (rate_sel = 0; rate_sel < ARRAY_SIZE(ds3231_clk_sqw_rates);
1008 rate_sel++) {
1009 if (ds3231_clk_sqw_rates[rate_sel] == rate)
1010 break;
1011 }
1012
1013 if (rate_sel == ARRAY_SIZE(ds3231_clk_sqw_rates))
1014 return -EINVAL;
1015
1016 if (rate_sel & 1)
1017 control |= DS1337_BIT_RS1;
1018 if (rate_sel & 2)
1019 control |= DS1337_BIT_RS2;
1020
1021 return ds1337_write_control(ds1307, DS1337_BIT_RS1 | DS1337_BIT_RS2,
1022 control);
1023}
1024
1025static int ds3231_clk_sqw_prepare(struct clk_hw *hw)
1026{
1027 struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw);
1028
1029 return ds1337_write_control(ds1307, DS1337_BIT_INTCN, 0);
1030}
1031
1032static void ds3231_clk_sqw_unprepare(struct clk_hw *hw)
1033{
1034 struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw);
1035
1036 ds1337_write_control(ds1307, DS1337_BIT_INTCN, DS1337_BIT_INTCN);
1037}
1038
1039static int ds3231_clk_sqw_is_prepared(struct clk_hw *hw)
1040{
1041 struct ds1307 *ds1307 = clk_sqw_to_ds1307(hw);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001042 int control, ret;
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001043
Heiner Kallweit11e58902017-03-10 18:52:34 +01001044 ret = regmap_read(ds1307->regmap, DS1337_REG_CONTROL, &control);
1045 if (ret)
1046 return ret;
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001047
1048 return !(control & DS1337_BIT_INTCN);
1049}
1050
1051static const struct clk_ops ds3231_clk_sqw_ops = {
1052 .prepare = ds3231_clk_sqw_prepare,
1053 .unprepare = ds3231_clk_sqw_unprepare,
1054 .is_prepared = ds3231_clk_sqw_is_prepared,
1055 .recalc_rate = ds3231_clk_sqw_recalc_rate,
1056 .round_rate = ds3231_clk_sqw_round_rate,
1057 .set_rate = ds3231_clk_sqw_set_rate,
1058};
1059
1060static unsigned long ds3231_clk_32khz_recalc_rate(struct clk_hw *hw,
1061 unsigned long parent_rate)
1062{
1063 return 32768;
1064}
1065
1066static int ds3231_clk_32khz_control(struct ds1307 *ds1307, bool enable)
1067{
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001068 struct mutex *lock = &ds1307->rtc->ops_lock;
1069 int status;
1070 int ret;
1071
1072 mutex_lock(lock);
1073
Heiner Kallweit11e58902017-03-10 18:52:34 +01001074 ret = regmap_read(ds1307->regmap, DS1337_REG_STATUS, &status);
1075 if (ret)
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001076 goto out;
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001077
1078 if (enable)
1079 status |= DS3231_BIT_EN32KHZ;
1080 else
1081 status &= ~DS3231_BIT_EN32KHZ;
1082
Heiner Kallweit11e58902017-03-10 18:52:34 +01001083 ret = regmap_write(ds1307->regmap, DS1337_REG_STATUS, status);
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001084out:
1085 mutex_unlock(lock);
1086
1087 return ret;
1088}
1089
1090static int ds3231_clk_32khz_prepare(struct clk_hw *hw)
1091{
1092 struct ds1307 *ds1307 = clk_32khz_to_ds1307(hw);
1093
1094 return ds3231_clk_32khz_control(ds1307, true);
1095}
1096
1097static void ds3231_clk_32khz_unprepare(struct clk_hw *hw)
1098{
1099 struct ds1307 *ds1307 = clk_32khz_to_ds1307(hw);
1100
1101 ds3231_clk_32khz_control(ds1307, false);
1102}
1103
1104static int ds3231_clk_32khz_is_prepared(struct clk_hw *hw)
1105{
1106 struct ds1307 *ds1307 = clk_32khz_to_ds1307(hw);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001107 int status, ret;
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001108
Heiner Kallweit11e58902017-03-10 18:52:34 +01001109 ret = regmap_read(ds1307->regmap, DS1337_REG_STATUS, &status);
1110 if (ret)
1111 return ret;
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001112
1113 return !!(status & DS3231_BIT_EN32KHZ);
1114}
1115
1116static const struct clk_ops ds3231_clk_32khz_ops = {
1117 .prepare = ds3231_clk_32khz_prepare,
1118 .unprepare = ds3231_clk_32khz_unprepare,
1119 .is_prepared = ds3231_clk_32khz_is_prepared,
1120 .recalc_rate = ds3231_clk_32khz_recalc_rate,
1121};
1122
1123static struct clk_init_data ds3231_clks_init[] = {
1124 [DS3231_CLK_SQW] = {
1125 .name = "ds3231_clk_sqw",
1126 .ops = &ds3231_clk_sqw_ops,
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001127 },
1128 [DS3231_CLK_32KHZ] = {
1129 .name = "ds3231_clk_32khz",
1130 .ops = &ds3231_clk_32khz_ops,
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001131 },
1132};
1133
1134static int ds3231_clks_register(struct ds1307 *ds1307)
1135{
Heiner Kallweit11e58902017-03-10 18:52:34 +01001136 struct device_node *node = ds1307->dev->of_node;
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001137 struct clk_onecell_data *onecell;
1138 int i;
1139
Heiner Kallweit11e58902017-03-10 18:52:34 +01001140 onecell = devm_kzalloc(ds1307->dev, sizeof(*onecell), GFP_KERNEL);
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001141 if (!onecell)
1142 return -ENOMEM;
1143
1144 onecell->clk_num = ARRAY_SIZE(ds3231_clks_init);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001145 onecell->clks = devm_kcalloc(ds1307->dev, onecell->clk_num,
1146 sizeof(onecell->clks[0]), GFP_KERNEL);
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001147 if (!onecell->clks)
1148 return -ENOMEM;
1149
1150 for (i = 0; i < ARRAY_SIZE(ds3231_clks_init); i++) {
1151 struct clk_init_data init = ds3231_clks_init[i];
1152
1153 /*
1154 * Interrupt signal due to alarm conditions and square-wave
1155 * output share same pin, so don't initialize both.
1156 */
1157 if (i == DS3231_CLK_SQW && test_bit(HAS_ALARM, &ds1307->flags))
1158 continue;
1159
1160 /* optional override of the clockname */
1161 of_property_read_string_index(node, "clock-output-names", i,
1162 &init.name);
1163 ds1307->clks[i].init = &init;
1164
Heiner Kallweit11e58902017-03-10 18:52:34 +01001165 onecell->clks[i] = devm_clk_register(ds1307->dev,
1166 &ds1307->clks[i]);
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001167 if (IS_ERR(onecell->clks[i]))
1168 return PTR_ERR(onecell->clks[i]);
1169 }
1170
1171 if (!node)
1172 return 0;
1173
1174 of_clk_add_provider(node, of_clk_src_onecell_get, onecell);
1175
1176 return 0;
1177}
1178
1179static void ds1307_clks_register(struct ds1307 *ds1307)
1180{
1181 int ret;
1182
1183 if (ds1307->type != ds_3231)
1184 return;
1185
1186 ret = ds3231_clks_register(ds1307);
1187 if (ret) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001188 dev_warn(ds1307->dev, "unable to register clock device %d\n",
1189 ret);
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001190 }
1191}
1192
1193#else
1194
1195static void ds1307_clks_register(struct ds1307 *ds1307)
1196{
1197}
1198
1199#endif /* CONFIG_COMMON_CLK */
Akinobu Mita445c0202016-01-25 00:22:16 +09001200
Heiner Kallweit11e58902017-03-10 18:52:34 +01001201static const struct regmap_config regmap_config = {
1202 .reg_bits = 8,
1203 .val_bits = 8,
1204 .max_register = 0x12,
1205};
1206
Greg Kroah-Hartman5a167f42012-12-21 13:09:38 -08001207static int ds1307_probe(struct i2c_client *client,
1208 const struct i2c_device_id *id)
David Brownell1abb0dc2006-06-25 05:48:17 -07001209{
1210 struct ds1307 *ds1307;
1211 int err = -ENODEV;
Keerthye29385f2016-06-01 16:19:07 +05301212 int tmp, wday;
Tin Huynh9c19b892016-11-30 09:57:31 +07001213 struct chip_desc *chip;
Peter Senna Tschudinc8b18da2013-11-12 15:10:59 -08001214 bool want_irq = false;
Michael Lange8bc2a402016-01-21 18:10:16 +01001215 bool ds1307_can_wakeup_device = false;
BARRE Sebastienfed40b72009-01-07 18:07:13 -08001216 unsigned char *buf;
Jingoo Han01ce8932013-11-12 15:10:41 -08001217 struct ds1307_platform_data *pdata = dev_get_platdata(&client->dev);
Keerthye29385f2016-06-01 16:19:07 +05301218 struct rtc_time tm;
1219 unsigned long timestamp;
1220
Felipe Balbi2fb07a12015-06-23 11:15:10 -05001221 irq_handler_t irq_handler = ds1307_irq;
1222
Wolfram Sang97f902b2009-06-17 16:26:10 -07001223 static const int bbsqi_bitpos[] = {
1224 [ds_1337] = 0,
1225 [ds_1339] = DS1339_BIT_BBSQI,
1226 [ds_3231] = DS3231_BIT_BBSQW,
1227 };
Simon Guinot1d1945d2014-04-03 14:49:55 -07001228 const struct rtc_class_ops *rtc_ops = &ds13xx_rtc_ops;
David Brownell1abb0dc2006-06-25 05:48:17 -07001229
Jingoo Hanedca66d2013-07-03 15:07:05 -07001230 ds1307 = devm_kzalloc(&client->dev, sizeof(struct ds1307), GFP_KERNEL);
David Anders40ce9722012-03-23 15:02:37 -07001231 if (!ds1307)
David Brownellc065f352007-07-17 04:05:10 -07001232 return -ENOMEM;
David Brownell045e0e82007-07-17 04:04:55 -07001233
Heiner Kallweit11e58902017-03-10 18:52:34 +01001234 dev_set_drvdata(&client->dev, ds1307);
1235 ds1307->dev = &client->dev;
1236 ds1307->name = client->name;
1237 ds1307->irq = client->irq;
Joakim Tjernlund33df2ee2009-06-17 16:26:08 -07001238
Heiner Kallweit11e58902017-03-10 18:52:34 +01001239 ds1307->regmap = devm_regmap_init_i2c(client, &regmap_config);
1240 if (IS_ERR(ds1307->regmap)) {
1241 dev_err(ds1307->dev, "regmap allocation failed\n");
1242 return PTR_ERR(ds1307->regmap);
1243 }
1244
1245 i2c_set_clientdata(client, ds1307);
Javier Martinez Canillas7ef6d2c2017-03-03 11:29:15 -03001246
1247 if (client->dev.of_node) {
1248 ds1307->type = (enum ds_type)
1249 of_device_get_match_data(&client->dev);
1250 chip = &chips[ds1307->type];
1251 } else if (id) {
Tin Huynh9c19b892016-11-30 09:57:31 +07001252 chip = &chips[id->driver_data];
1253 ds1307->type = id->driver_data;
1254 } else {
1255 const struct acpi_device_id *acpi_id;
Joakim Tjernlund33df2ee2009-06-17 16:26:08 -07001256
Tin Huynh9c19b892016-11-30 09:57:31 +07001257 acpi_id = acpi_match_device(ACPI_PTR(ds1307_acpi_ids),
Heiner Kallweit11e58902017-03-10 18:52:34 +01001258 ds1307->dev);
Tin Huynh9c19b892016-11-30 09:57:31 +07001259 if (!acpi_id)
1260 return -ENODEV;
1261 chip = &chips[acpi_id->driver_data];
1262 ds1307->type = acpi_id->driver_data;
1263 }
1264
1265 if (!pdata)
Heiner Kallweit11e58902017-03-10 18:52:34 +01001266 ds1307_trickle_init(ds1307, chip);
Tin Huynh9c19b892016-11-30 09:57:31 +07001267 else if (pdata->trickle_charger_setup)
Matti Vaittinen33b04b72014-10-13 15:52:48 -07001268 chip->trickle_charger_setup = pdata->trickle_charger_setup;
1269
1270 if (chip->trickle_charger_setup && chip->trickle_charger_reg) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001271 dev_dbg(ds1307->dev,
1272 "writing trickle charger info 0x%x to 0x%x\n",
Matti Vaittinen33b04b72014-10-13 15:52:48 -07001273 DS13XX_TRICKLE_CHARGER_MAGIC | chip->trickle_charger_setup,
1274 chip->trickle_charger_reg);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001275 regmap_write(ds1307->regmap, chip->trickle_charger_reg,
Matti Vaittinen33b04b72014-10-13 15:52:48 -07001276 DS13XX_TRICKLE_CHARGER_MAGIC |
1277 chip->trickle_charger_setup);
1278 }
Wolfram Sangeb86c302012-05-29 15:07:38 -07001279
BARRE Sebastienfed40b72009-01-07 18:07:13 -08001280 buf = ds1307->regs;
David Brownell045e0e82007-07-17 04:04:55 -07001281
Michael Lange8bc2a402016-01-21 18:10:16 +01001282#ifdef CONFIG_OF
1283/*
1284 * For devices with no IRQ directly connected to the SoC, the RTC chip
1285 * can be forced as a wakeup source by stating that explicitly in
1286 * the device's .dts file using the "wakeup-source" boolean property.
1287 * If the "wakeup-source" property is set, don't request an IRQ.
1288 * This will guarantee the 'wakealarm' sysfs entry is available on the device,
1289 * if supported by the RTC.
1290 */
1291 if (of_property_read_bool(client->dev.of_node, "wakeup-source")) {
1292 ds1307_can_wakeup_device = true;
1293 }
Alexandre Belloni78aaa062016-07-13 02:36:41 +02001294 /* Intersil ISL12057 DT backward compatibility */
1295 if (of_property_read_bool(client->dev.of_node,
1296 "isil,irq2-can-wakeup-machine")) {
1297 ds1307_can_wakeup_device = true;
1298 }
Michael Lange8bc2a402016-01-21 18:10:16 +01001299#endif
1300
David Brownell045e0e82007-07-17 04:04:55 -07001301 switch (ds1307->type) {
1302 case ds_1337:
1303 case ds_1339:
Wolfram Sang97f902b2009-06-17 16:26:10 -07001304 case ds_3231:
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001305 /* get registers that the "rtc" read below won't read... */
Heiner Kallweit11e58902017-03-10 18:52:34 +01001306 err = regmap_bulk_read(ds1307->regmap, DS1337_REG_CONTROL,
1307 buf, 2);
1308 if (err) {
1309 dev_dbg(ds1307->dev, "read error %d\n", err);
Jingoo Hanedca66d2013-07-03 15:07:05 -07001310 goto exit;
David Brownell1abb0dc2006-06-25 05:48:17 -07001311 }
1312
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001313 /* oscillator off? turn it on, so clock can tick. */
1314 if (ds1307->regs[0] & DS1337_BIT_nEOSC)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001315 ds1307->regs[0] &= ~DS1337_BIT_nEOSC;
1316
David Anders40ce9722012-03-23 15:02:37 -07001317 /*
Michael Lange8bc2a402016-01-21 18:10:16 +01001318 * Using IRQ or defined as wakeup-source?
1319 * Disable the square wave and both alarms.
Wolfram Sang97f902b2009-06-17 16:26:10 -07001320 * For some variants, be sure alarms can trigger when we're
1321 * running on Vbackup (BBSQI/BBSQW)
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001322 */
Heiner Kallweit11e58902017-03-10 18:52:34 +01001323 if (chip->alarm && (ds1307->irq > 0 ||
1324 ds1307_can_wakeup_device)) {
Wolfram Sang97f902b2009-06-17 16:26:10 -07001325 ds1307->regs[0] |= DS1337_BIT_INTCN
1326 | bbsqi_bitpos[ds1307->type];
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001327 ds1307->regs[0] &= ~(DS1337_BIT_A2IE | DS1337_BIT_A1IE);
Wolfram Sangb24a7262012-03-23 15:02:37 -07001328
1329 want_irq = true;
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001330 }
1331
Heiner Kallweit11e58902017-03-10 18:52:34 +01001332 regmap_write(ds1307->regmap, DS1337_REG_CONTROL,
1333 ds1307->regs[0]);
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001334
1335 /* oscillator fault? clear flag, and warn */
1336 if (ds1307->regs[1] & DS1337_BIT_OSF) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001337 regmap_write(ds1307->regmap, DS1337_REG_STATUS,
1338 ds1307->regs[1] & ~DS1337_BIT_OSF);
1339 dev_warn(ds1307->dev, "SET TIME!\n");
David Brownell1abb0dc2006-06-25 05:48:17 -07001340 }
David Brownell045e0e82007-07-17 04:04:55 -07001341 break;
Matthias Fuchsa2166852009-03-31 15:24:58 -07001342
1343 case rx_8025:
Heiner Kallweit11e58902017-03-10 18:52:34 +01001344 err = regmap_bulk_read(ds1307->regmap,
1345 RX8025_REG_CTRL1 << 4 | 0x08, buf, 2);
1346 if (err) {
1347 dev_dbg(ds1307->dev, "read error %d\n", err);
Jingoo Hanedca66d2013-07-03 15:07:05 -07001348 goto exit;
Matthias Fuchsa2166852009-03-31 15:24:58 -07001349 }
1350
1351 /* oscillator off? turn it on, so clock can tick. */
1352 if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
1353 ds1307->regs[1] |= RX8025_BIT_XST;
Heiner Kallweit11e58902017-03-10 18:52:34 +01001354 regmap_write(ds1307->regmap,
1355 RX8025_REG_CTRL2 << 4 | 0x08,
1356 ds1307->regs[1]);
1357 dev_warn(ds1307->dev,
Matthias Fuchsa2166852009-03-31 15:24:58 -07001358 "oscillator stop detected - SET TIME!\n");
1359 }
1360
1361 if (ds1307->regs[1] & RX8025_BIT_PON) {
1362 ds1307->regs[1] &= ~RX8025_BIT_PON;
Heiner Kallweit11e58902017-03-10 18:52:34 +01001363 regmap_write(ds1307->regmap,
1364 RX8025_REG_CTRL2 << 4 | 0x08,
1365 ds1307->regs[1]);
1366 dev_warn(ds1307->dev, "power-on detected\n");
Matthias Fuchsa2166852009-03-31 15:24:58 -07001367 }
1368
1369 if (ds1307->regs[1] & RX8025_BIT_VDET) {
1370 ds1307->regs[1] &= ~RX8025_BIT_VDET;
Heiner Kallweit11e58902017-03-10 18:52:34 +01001371 regmap_write(ds1307->regmap,
1372 RX8025_REG_CTRL2 << 4 | 0x08,
1373 ds1307->regs[1]);
1374 dev_warn(ds1307->dev, "voltage drop detected\n");
Matthias Fuchsa2166852009-03-31 15:24:58 -07001375 }
1376
1377 /* make sure we are running in 24hour mode */
1378 if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
1379 u8 hour;
1380
1381 /* switch to 24 hour mode */
Heiner Kallweit11e58902017-03-10 18:52:34 +01001382 regmap_write(ds1307->regmap,
1383 RX8025_REG_CTRL1 << 4 | 0x08,
1384 ds1307->regs[0] | RX8025_BIT_2412);
Matthias Fuchsa2166852009-03-31 15:24:58 -07001385
Heiner Kallweit11e58902017-03-10 18:52:34 +01001386 err = regmap_bulk_read(ds1307->regmap,
1387 RX8025_REG_CTRL1 << 4 | 0x08,
1388 buf, 2);
1389 if (err) {
1390 dev_dbg(ds1307->dev, "read error %d\n", err);
Jingoo Hanedca66d2013-07-03 15:07:05 -07001391 goto exit;
Matthias Fuchsa2166852009-03-31 15:24:58 -07001392 }
1393
1394 /* correct hour */
1395 hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
1396 if (hour == 12)
1397 hour = 0;
1398 if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
1399 hour += 12;
1400
Heiner Kallweit11e58902017-03-10 18:52:34 +01001401 regmap_write(ds1307->regmap,
1402 DS1307_REG_HOUR << 4 | 0x08, hour);
Matthias Fuchsa2166852009-03-31 15:24:58 -07001403 }
1404 break;
Joakim Tjernlund33df2ee2009-06-17 16:26:08 -07001405 case ds_1388:
1406 ds1307->offset = 1; /* Seconds starts at 1 */
1407 break;
Tomas Novotnyf4199f82014-12-10 15:53:57 -08001408 case mcp794xx:
1409 rtc_ops = &mcp794xx_rtc_ops;
David Lowe80663602017-04-22 18:28:00 +01001410 if (chip->alarm && (ds1307->irq > 0 ||
1411 ds1307_can_wakeup_device)) {
Felipe Balbi2fb07a12015-06-23 11:15:10 -05001412 irq_handler = mcp794xx_irq;
Simon Guinot1d1945d2014-04-03 14:49:55 -07001413 want_irq = true;
1414 }
1415 break;
David Brownell045e0e82007-07-17 04:04:55 -07001416 default:
1417 break;
1418 }
David Brownell1abb0dc2006-06-25 05:48:17 -07001419
1420read_rtc:
1421 /* read RTC registers */
Heiner Kallweit11e58902017-03-10 18:52:34 +01001422 err = regmap_bulk_read(ds1307->regmap, ds1307->offset, buf, 8);
1423 if (err) {
1424 dev_dbg(ds1307->dev, "read error %d\n", err);
Jingoo Hanedca66d2013-07-03 15:07:05 -07001425 goto exit;
David Brownell1abb0dc2006-06-25 05:48:17 -07001426 }
1427
David Anders40ce9722012-03-23 15:02:37 -07001428 /*
1429 * minimal sanity checking; some chips (like DS1340) don't
David Brownell1abb0dc2006-06-25 05:48:17 -07001430 * specify the extra bits as must-be-zero, but there are
1431 * still a few values that are clearly out-of-range.
1432 */
1433 tmp = ds1307->regs[DS1307_REG_SECS];
David Brownell045e0e82007-07-17 04:04:55 -07001434 switch (ds1307->type) {
1435 case ds_1307:
Stefan Agner8566f702017-03-23 16:54:57 -07001436 case m41t0:
David Brownell045e0e82007-07-17 04:04:55 -07001437 case m41t00:
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001438 /* clock halted? turn it on, so clock can tick. */
David Brownell045e0e82007-07-17 04:04:55 -07001439 if (tmp & DS1307_BIT_CH) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001440 regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
1441 dev_warn(ds1307->dev, "SET TIME!\n");
David Brownell045e0e82007-07-17 04:04:55 -07001442 goto read_rtc;
David Brownell1abb0dc2006-06-25 05:48:17 -07001443 }
David Brownell045e0e82007-07-17 04:04:55 -07001444 break;
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001445 case ds_1338:
1446 /* clock halted? turn it on, so clock can tick. */
David Brownell045e0e82007-07-17 04:04:55 -07001447 if (tmp & DS1307_BIT_CH)
Heiner Kallweit11e58902017-03-10 18:52:34 +01001448 regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001449
1450 /* oscillator fault? clear flag, and warn */
1451 if (ds1307->regs[DS1307_REG_CONTROL] & DS1338_BIT_OSF) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001452 regmap_write(ds1307->regmap, DS1307_REG_CONTROL,
1453 ds1307->regs[DS1307_REG_CONTROL] &
1454 ~DS1338_BIT_OSF);
1455 dev_warn(ds1307->dev, "SET TIME!\n");
Rodolfo Giomettibe5f59f2007-07-17 04:05:06 -07001456 goto read_rtc;
1457 }
David Brownell045e0e82007-07-17 04:04:55 -07001458 break;
frederic Rodofcd8db02008-02-06 01:38:55 -08001459 case ds_1340:
1460 /* clock halted? turn it on, so clock can tick. */
1461 if (tmp & DS1340_BIT_nEOSC)
Heiner Kallweit11e58902017-03-10 18:52:34 +01001462 regmap_write(ds1307->regmap, DS1307_REG_SECS, 0);
frederic Rodofcd8db02008-02-06 01:38:55 -08001463
Heiner Kallweit11e58902017-03-10 18:52:34 +01001464 err = regmap_read(ds1307->regmap, DS1340_REG_FLAG, &tmp);
1465 if (err) {
1466 dev_dbg(ds1307->dev, "read error %d\n", err);
Jingoo Hanedca66d2013-07-03 15:07:05 -07001467 goto exit;
frederic Rodofcd8db02008-02-06 01:38:55 -08001468 }
1469
1470 /* oscillator fault? clear flag, and warn */
1471 if (tmp & DS1340_BIT_OSF) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001472 regmap_write(ds1307->regmap, DS1340_REG_FLAG, 0);
1473 dev_warn(ds1307->dev, "SET TIME!\n");
frederic Rodofcd8db02008-02-06 01:38:55 -08001474 }
1475 break;
Tomas Novotnyf4199f82014-12-10 15:53:57 -08001476 case mcp794xx:
David Anders43fcb812011-11-02 13:37:53 -07001477 /* make sure that the backup battery is enabled */
Tomas Novotnyf4199f82014-12-10 15:53:57 -08001478 if (!(ds1307->regs[DS1307_REG_WDAY] & MCP794XX_BIT_VBATEN)) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001479 regmap_write(ds1307->regmap, DS1307_REG_WDAY,
1480 ds1307->regs[DS1307_REG_WDAY] |
1481 MCP794XX_BIT_VBATEN);
David Anders43fcb812011-11-02 13:37:53 -07001482 }
1483
1484 /* clock halted? turn it on, so clock can tick. */
Tomas Novotnyf4199f82014-12-10 15:53:57 -08001485 if (!(tmp & MCP794XX_BIT_ST)) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001486 regmap_write(ds1307->regmap, DS1307_REG_SECS,
1487 MCP794XX_BIT_ST);
1488 dev_warn(ds1307->dev, "SET TIME!\n");
David Anders43fcb812011-11-02 13:37:53 -07001489 goto read_rtc;
1490 }
1491
1492 break;
Wolfram Sang32d322b2012-03-23 15:02:36 -07001493 default:
David Brownell045e0e82007-07-17 04:04:55 -07001494 break;
David Brownell1abb0dc2006-06-25 05:48:17 -07001495 }
David Brownell045e0e82007-07-17 04:04:55 -07001496
David Brownell1abb0dc2006-06-25 05:48:17 -07001497 tmp = ds1307->regs[DS1307_REG_HOUR];
David Brownellc065f352007-07-17 04:05:10 -07001498 switch (ds1307->type) {
1499 case ds_1340:
Stefan Agner8566f702017-03-23 16:54:57 -07001500 case m41t0:
David Brownellc065f352007-07-17 04:05:10 -07001501 case m41t00:
David Anders40ce9722012-03-23 15:02:37 -07001502 /*
1503 * NOTE: ignores century bits; fix before deploying
David Brownellc065f352007-07-17 04:05:10 -07001504 * systems that will run through year 2100.
1505 */
1506 break;
Matthias Fuchsa2166852009-03-31 15:24:58 -07001507 case rx_8025:
1508 break;
David Brownellc065f352007-07-17 04:05:10 -07001509 default:
1510 if (!(tmp & DS1307_BIT_12HR))
1511 break;
1512
David Anders40ce9722012-03-23 15:02:37 -07001513 /*
1514 * Be sure we're in 24 hour mode. Multi-master systems
David Brownellc065f352007-07-17 04:05:10 -07001515 * take note...
1516 */
Adrian Bunkfe20ba72008-10-18 20:28:41 -07001517 tmp = bcd2bin(tmp & 0x1f);
David Brownellc065f352007-07-17 04:05:10 -07001518 if (tmp == 12)
1519 tmp = 0;
1520 if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
1521 tmp += 12;
Heiner Kallweit11e58902017-03-10 18:52:34 +01001522 regmap_write(ds1307->regmap, ds1307->offset + DS1307_REG_HOUR,
1523 bin2bcd(tmp));
David Brownell1abb0dc2006-06-25 05:48:17 -07001524 }
1525
Keerthye29385f2016-06-01 16:19:07 +05301526 /*
1527 * Some IPs have weekday reset value = 0x1 which might not correct
1528 * hence compute the wday using the current date/month/year values
1529 */
Heiner Kallweit11e58902017-03-10 18:52:34 +01001530 ds1307_get_time(ds1307->dev, &tm);
Keerthye29385f2016-06-01 16:19:07 +05301531 wday = tm.tm_wday;
1532 timestamp = rtc_tm_to_time64(&tm);
1533 rtc_time64_to_tm(timestamp, &tm);
1534
1535 /*
1536 * Check if reset wday is different from the computed wday
1537 * If different then set the wday which we computed using
1538 * timestamp
1539 */
1540 if (wday != tm.tm_wday) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001541 regmap_read(ds1307->regmap, MCP794XX_REG_WEEKDAY, &wday);
Keerthye29385f2016-06-01 16:19:07 +05301542 wday = wday & ~MCP794XX_REG_WEEKDAY_WDAY_MASK;
1543 wday = wday | (tm.tm_wday + 1);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001544 regmap_write(ds1307->regmap, MCP794XX_REG_WEEKDAY, wday);
Keerthye29385f2016-06-01 16:19:07 +05301545 }
1546
Simon Guinot3abb1ad2015-11-26 15:37:13 +01001547 if (want_irq) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001548 device_set_wakeup_capable(ds1307->dev, true);
Simon Guinot3abb1ad2015-11-26 15:37:13 +01001549 set_bit(HAS_ALARM, &ds1307->flags);
1550 }
Heiner Kallweit11e58902017-03-10 18:52:34 +01001551 ds1307->rtc = devm_rtc_device_register(ds1307->dev, ds1307->name,
Simon Guinot1d1945d2014-04-03 14:49:55 -07001552 rtc_ops, THIS_MODULE);
David Brownell1abb0dc2006-06-25 05:48:17 -07001553 if (IS_ERR(ds1307->rtc)) {
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001554 return PTR_ERR(ds1307->rtc);
David Brownell1abb0dc2006-06-25 05:48:17 -07001555 }
1556
Heiner Kallweit11e58902017-03-10 18:52:34 +01001557 if (ds1307_can_wakeup_device && ds1307->irq <= 0) {
Michael Lange8bc2a402016-01-21 18:10:16 +01001558 /* Disable request for an IRQ */
1559 want_irq = false;
Heiner Kallweit11e58902017-03-10 18:52:34 +01001560 dev_info(ds1307->dev,
1561 "'wakeup-source' is set, request for an IRQ is disabled!\n");
Michael Lange8bc2a402016-01-21 18:10:16 +01001562 /* We cannot support UIE mode if we do not have an IRQ line */
1563 ds1307->rtc->uie_unsupported = 1;
1564 }
1565
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001566 if (want_irq) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001567 err = devm_request_threaded_irq(ds1307->dev,
1568 ds1307->irq, NULL, irq_handler,
Nishanth Menonc5983192015-06-23 11:15:11 -05001569 IRQF_SHARED | IRQF_ONESHOT,
Heiner Kallweit11e58902017-03-10 18:52:34 +01001570 ds1307->rtc->name, ds1307);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001571 if (err) {
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001572 client->irq = 0;
Heiner Kallweit11e58902017-03-10 18:52:34 +01001573 device_set_wakeup_capable(ds1307->dev, false);
Simon Guinot3abb1ad2015-11-26 15:37:13 +01001574 clear_bit(HAS_ALARM, &ds1307->flags);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001575 dev_err(ds1307->dev, "unable to request IRQ!\n");
Simon Guinot3abb1ad2015-11-26 15:37:13 +01001576 } else
Heiner Kallweit11e58902017-03-10 18:52:34 +01001577 dev_dbg(ds1307->dev, "got IRQ %d\n", client->irq);
Rodolfo Giometticb49a5e2008-10-15 22:02:58 -07001578 }
1579
Austin Boyle9eab0a72012-03-23 15:02:38 -07001580 if (chip->nvram_size) {
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001581
Heiner Kallweit11e58902017-03-10 18:52:34 +01001582 ds1307->nvram = devm_kzalloc(ds1307->dev,
Jingoo Hanedca66d2013-07-03 15:07:05 -07001583 sizeof(struct bin_attribute),
1584 GFP_KERNEL);
Austin Boyle9eab0a72012-03-23 15:02:38 -07001585 if (!ds1307->nvram) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001586 dev_err(ds1307->dev,
1587 "cannot allocate memory for nvram sysfs\n");
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001588 } else {
1589
1590 ds1307->nvram->attr.name = "nvram";
1591 ds1307->nvram->attr.mode = S_IRUGO | S_IWUSR;
1592
1593 sysfs_bin_attr_init(ds1307->nvram);
1594
1595 ds1307->nvram->read = ds1307_nvram_read;
1596 ds1307->nvram->write = ds1307_nvram_write;
1597 ds1307->nvram->size = chip->nvram_size;
1598 ds1307->nvram_offset = chip->nvram_offset;
1599
Heiner Kallweit11e58902017-03-10 18:52:34 +01001600 err = sysfs_create_bin_file(&ds1307->dev->kobj,
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001601 ds1307->nvram);
1602 if (err) {
Heiner Kallweit11e58902017-03-10 18:52:34 +01001603 dev_err(ds1307->dev,
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001604 "unable to create sysfs file: %s\n",
1605 ds1307->nvram->attr.name);
1606 } else {
1607 set_bit(HAS_NVRAM, &ds1307->flags);
Heiner Kallweit11e58902017-03-10 18:52:34 +01001608 dev_info(ds1307->dev, "%zu bytes nvram\n",
Alessandro Zummo4071ea22014-04-03 14:49:36 -07001609 ds1307->nvram->size);
1610 }
David Brownell682d73f2007-11-14 16:58:32 -08001611 }
1612 }
1613
Akinobu Mita445c0202016-01-25 00:22:16 +09001614 ds1307_hwmon_register(ds1307);
Akinobu Mita6c6ff142016-01-31 23:10:10 +09001615 ds1307_clks_register(ds1307);
Akinobu Mita445c0202016-01-25 00:22:16 +09001616
David Brownell1abb0dc2006-06-25 05:48:17 -07001617 return 0;
1618
Jingoo Hanedca66d2013-07-03 15:07:05 -07001619exit:
David Brownell1abb0dc2006-06-25 05:48:17 -07001620 return err;
1621}
1622
Greg Kroah-Hartman5a167f42012-12-21 13:09:38 -08001623static int ds1307_remove(struct i2c_client *client)
David Brownell1abb0dc2006-06-25 05:48:17 -07001624{
David Anders40ce9722012-03-23 15:02:37 -07001625 struct ds1307 *ds1307 = i2c_get_clientdata(client);
David Brownell1abb0dc2006-06-25 05:48:17 -07001626
Jingoo Hanedca66d2013-07-03 15:07:05 -07001627 if (test_and_clear_bit(HAS_NVRAM, &ds1307->flags))
Heiner Kallweit11e58902017-03-10 18:52:34 +01001628 sysfs_remove_bin_file(&ds1307->dev->kobj, ds1307->nvram);
David Brownell682d73f2007-11-14 16:58:32 -08001629
David Brownell1abb0dc2006-06-25 05:48:17 -07001630 return 0;
1631}
1632
1633static struct i2c_driver ds1307_driver = {
1634 .driver = {
David Brownellc065f352007-07-17 04:05:10 -07001635 .name = "rtc-ds1307",
Javier Martinez Canillas7ef6d2c2017-03-03 11:29:15 -03001636 .of_match_table = of_match_ptr(ds1307_of_match),
Tin Huynh9c19b892016-11-30 09:57:31 +07001637 .acpi_match_table = ACPI_PTR(ds1307_acpi_ids),
David Brownell1abb0dc2006-06-25 05:48:17 -07001638 },
David Brownellc065f352007-07-17 04:05:10 -07001639 .probe = ds1307_probe,
Greg Kroah-Hartman5a167f42012-12-21 13:09:38 -08001640 .remove = ds1307_remove,
Jean Delvare3760f732008-04-29 23:11:40 +02001641 .id_table = ds1307_id,
David Brownell1abb0dc2006-06-25 05:48:17 -07001642};
1643
Axel Lin0abc9202012-03-23 15:02:31 -07001644module_i2c_driver(ds1307_driver);
David Brownell1abb0dc2006-06-25 05:48:17 -07001645
1646MODULE_DESCRIPTION("RTC driver for DS1307 and similar chips");
1647MODULE_LICENSE("GPL");