Blame view

drivers/rtc/rtc-rx8010.c 10.5 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
2
3
4
5
6
  /*
   * Driver for the Epson RTC module RX-8010 SJ
   *
   * Copyright(C) Timesys Corporation 2015
   * Copyright(C) General Electric Company 2015
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
7
8
9
10
11
12
13
   */
  
  #include <linux/bcd.h>
  #include <linux/bitops.h>
  #include <linux/i2c.h>
  #include <linux/kernel.h>
  #include <linux/module.h>
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
14
  #include <linux/regmap.h>
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
15
  #include <linux/rtc.h>
e9e4c2dae   Bartosz Golaszewski   rtc: rx8010: use ...
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
  #define RX8010_SEC		0x10
  #define RX8010_MIN		0x11
  #define RX8010_HOUR		0x12
  #define RX8010_WDAY		0x13
  #define RX8010_MDAY		0x14
  #define RX8010_MONTH		0x15
  #define RX8010_YEAR		0x16
  #define RX8010_RESV17		0x17
  #define RX8010_ALMIN		0x18
  #define RX8010_ALHOUR		0x19
  #define RX8010_ALWDAY		0x1A
  #define RX8010_TCOUNT0		0x1B
  #define RX8010_TCOUNT1		0x1C
  #define RX8010_EXT		0x1D
  #define RX8010_FLAG		0x1E
  #define RX8010_CTRL		0x1F
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
32
  /* 0x20 to 0x2F are user registers */
e9e4c2dae   Bartosz Golaszewski   rtc: rx8010: use ...
33
34
35
  #define RX8010_RESV30		0x30
  #define RX8010_RESV31		0x31
  #define RX8010_IRQ		0x32
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
36

e9e4c2dae   Bartosz Golaszewski   rtc: rx8010: use ...
37
  #define RX8010_EXT_WADA		BIT(3)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
38

e9e4c2dae   Bartosz Golaszewski   rtc: rx8010: use ...
39
40
41
42
  #define RX8010_FLAG_VLF		BIT(1)
  #define RX8010_FLAG_AF		BIT(3)
  #define RX8010_FLAG_TF		BIT(4)
  #define RX8010_FLAG_UF		BIT(5)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
43

e9e4c2dae   Bartosz Golaszewski   rtc: rx8010: use ...
44
45
46
47
  #define RX8010_CTRL_AIE		BIT(3)
  #define RX8010_CTRL_UIE		BIT(5)
  #define RX8010_CTRL_STOP	BIT(6)
  #define RX8010_CTRL_TEST	BIT(7)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
48

e9e4c2dae   Bartosz Golaszewski   rtc: rx8010: use ...
49
  #define RX8010_ALARM_AE		BIT(7)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
50
51
52
53
54
55
  
  static const struct i2c_device_id rx8010_id[] = {
  	{ "rx8010", 0 },
  	{ }
  };
  MODULE_DEVICE_TABLE(i2c, rx8010_id);
81b779ce5   Javier Martinez Canillas   rtc: rx8010: Add ...
56
57
58
59
60
  static const struct of_device_id rx8010_of_match[] = {
  	{ .compatible = "epson,rx8010" },
  	{ }
  };
  MODULE_DEVICE_TABLE(of, rx8010_of_match);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
61
  struct rx8010_data {
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
62
  	struct regmap *regs;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
63
64
  	struct rtc_device *rtc;
  	u8 ctrlreg;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
65
66
67
68
69
70
  };
  
  static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id)
  {
  	struct i2c_client *client = dev_id;
  	struct rx8010_data *rx8010 = i2c_get_clientdata(client);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
71
  	int flagreg, err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
72

666b5d1e9   Fabien Lahoudere   rtc: rx8010: chan...
73
  	mutex_lock(&rx8010->rtc->ops_lock);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
74

9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
75
76
  	err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
  	if (err) {
666b5d1e9   Fabien Lahoudere   rtc: rx8010: chan...
77
  		mutex_unlock(&rx8010->rtc->ops_lock);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  		return IRQ_NONE;
  	}
  
  	if (flagreg & RX8010_FLAG_VLF)
  		dev_warn(&client->dev, "Frequency stop detected
  ");
  
  	if (flagreg & RX8010_FLAG_TF) {
  		flagreg &= ~RX8010_FLAG_TF;
  		rtc_update_irq(rx8010->rtc, 1, RTC_PF | RTC_IRQF);
  	}
  
  	if (flagreg & RX8010_FLAG_AF) {
  		flagreg &= ~RX8010_FLAG_AF;
  		rtc_update_irq(rx8010->rtc, 1, RTC_AF | RTC_IRQF);
  	}
  
  	if (flagreg & RX8010_FLAG_UF) {
  		flagreg &= ~RX8010_FLAG_UF;
  		rtc_update_irq(rx8010->rtc, 1, RTC_UF | RTC_IRQF);
  	}
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
99
  	err = regmap_write(rx8010->regs, RX8010_FLAG, flagreg);
666b5d1e9   Fabien Lahoudere   rtc: rx8010: chan...
100
  	mutex_unlock(&rx8010->rtc->ops_lock);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
101
  	return err ? IRQ_NONE : IRQ_HANDLED;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
102
103
104
105
106
  }
  
  static int rx8010_get_time(struct device *dev, struct rtc_time *dt)
  {
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
f702699c6   Bartosz Golaszewski   rtc: rx8010: don'...
107
  	u8 date[RX8010_YEAR - RX8010_SEC + 1];
756779719   Bartosz Golaszewski   rtc: rx8010: cons...
108
  	int flagreg, err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
109

9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
110
111
112
  	err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
  	if (err)
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
113
114
115
116
117
118
  
  	if (flagreg & RX8010_FLAG_VLF) {
  		dev_warn(dev, "Frequency stop detected
  ");
  		return -EINVAL;
  	}
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
119
120
121
  	err = regmap_bulk_read(rx8010->regs, RX8010_SEC, date, sizeof(date));
  	if (err)
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
122
123
124
125
126
127
128
129
  
  	dt->tm_sec = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
  	dt->tm_min = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
  	dt->tm_hour = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f);
  	dt->tm_mday = bcd2bin(date[RX8010_MDAY - RX8010_SEC] & 0x3f);
  	dt->tm_mon = bcd2bin(date[RX8010_MONTH - RX8010_SEC] & 0x1f) - 1;
  	dt->tm_year = bcd2bin(date[RX8010_YEAR - RX8010_SEC]) + 100;
  	dt->tm_wday = ffs(date[RX8010_WDAY - RX8010_SEC] & 0x7f);
22652ba72   Alexandre Belloni   rtc: stop validat...
130
  	return 0;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
131
132
133
134
135
  }
  
  static int rx8010_set_time(struct device *dev, struct rtc_time *dt)
  {
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
f702699c6   Bartosz Golaszewski   rtc: rx8010: don'...
136
  	u8 date[RX8010_YEAR - RX8010_SEC + 1];
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
137
  	int err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
138

ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
139
  	/* set STOP bit before changing clock/calendar */
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
140
141
  	err = regmap_set_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
  	if (err)
13952c9e3   Bartosz Golaszewski   rtc: rx8010: rena...
142
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
143
144
145
146
147
148
149
150
  
  	date[RX8010_SEC - RX8010_SEC] = bin2bcd(dt->tm_sec);
  	date[RX8010_MIN - RX8010_SEC] = bin2bcd(dt->tm_min);
  	date[RX8010_HOUR - RX8010_SEC] = bin2bcd(dt->tm_hour);
  	date[RX8010_MDAY - RX8010_SEC] = bin2bcd(dt->tm_mday);
  	date[RX8010_MONTH - RX8010_SEC] = bin2bcd(dt->tm_mon + 1);
  	date[RX8010_YEAR - RX8010_SEC] = bin2bcd(dt->tm_year - 100);
  	date[RX8010_WDAY - RX8010_SEC] = bin2bcd(1 << dt->tm_wday);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
151
152
  	err = regmap_bulk_write(rx8010->regs, RX8010_SEC, date, sizeof(date));
  	if (err)
13952c9e3   Bartosz Golaszewski   rtc: rx8010: rena...
153
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
154
155
  
  	/* clear STOP bit after changing clock/calendar */
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
156
157
  	err = regmap_clear_bits(rx8010->regs, RX8010_CTRL, RX8010_CTRL_STOP);
  	if (err)
13952c9e3   Bartosz Golaszewski   rtc: rx8010: rena...
158
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
159

9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
160
161
162
  	err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_VLF);
  	if (err)
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
163

ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
164
165
  	return 0;
  }
ba1bcafb2   Bartosz Golaszewski   rtc: rx8010: rena...
166
  static int rx8010_init(struct device *dev)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
167
  {
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
168
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
169
  	u8 ctrl[2];
b3ff7fd68   Bartosz Golaszewski   rtc: rx8010: drop...
170
  	int need_clear = 0, err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
171
172
  
  	/* Initialize reserved registers as specified in datasheet */
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
173
174
  	err = regmap_write(rx8010->regs, RX8010_RESV17, 0xD8);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
175
  		return err;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
176
177
  	err = regmap_write(rx8010->regs, RX8010_RESV30, 0x00);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
178
  		return err;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
179
180
  	err = regmap_write(rx8010->regs, RX8010_RESV31, 0x08);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
181
  		return err;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
182
183
  	err = regmap_write(rx8010->regs, RX8010_IRQ, 0x00);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
184
  		return err;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
185
186
187
  	err = regmap_bulk_read(rx8010->regs, RX8010_FLAG, ctrl, 2);
  	if (err)
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
188
189
  
  	if (ctrl[0] & RX8010_FLAG_VLF)
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
190
191
  		dev_warn(dev, "Frequency stop was detected
  ");
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
192
193
  
  	if (ctrl[0] & RX8010_FLAG_AF) {
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
194
195
  		dev_warn(dev, "Alarm was detected
  ");
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
196
197
198
199
200
201
202
203
204
205
206
  		need_clear = 1;
  	}
  
  	if (ctrl[0] & RX8010_FLAG_TF)
  		need_clear = 1;
  
  	if (ctrl[0] & RX8010_FLAG_UF)
  		need_clear = 1;
  
  	if (need_clear) {
  		ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
207
208
  		err = regmap_write(rx8010->regs, RX8010_FLAG, ctrl[0]);
  		if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
209
210
211
212
  			return err;
  	}
  
  	rx8010->ctrlreg = (ctrl[1] & ~RX8010_CTRL_TEST);
804a6cfeb   Akshay Bhat   rtc: rx8010: Fix ...
213
  	return 0;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
214
215
216
217
218
  }
  
  static int rx8010_read_alarm(struct device *dev, struct rtc_wkalrm *t)
  {
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
219
  	u8 alarmvals[3];
756779719   Bartosz Golaszewski   rtc: rx8010: cons...
220
  	int flagreg, err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
221

9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
222
223
224
  	err = regmap_bulk_read(rx8010->regs, RX8010_ALMIN, alarmvals, 3);
  	if (err)
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
225

9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
226
227
228
  	err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
  	if (err)
  		return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
229
230
231
232
  
  	t->time.tm_sec = 0;
  	t->time.tm_min = bcd2bin(alarmvals[0] & 0x7f);
  	t->time.tm_hour = bcd2bin(alarmvals[1] & 0x3f);
56d86a7e7   Uwe Kleine-König   rtc: simplify imp...
233
  	if (!(alarmvals[2] & RX8010_ALARM_AE))
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
234
  		t->time.tm_mday = bcd2bin(alarmvals[2] & 0x7f);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
235
236
  	t->enabled = !!(rx8010->ctrlreg & RX8010_CTRL_AIE);
  	t->pending = (flagreg & RX8010_FLAG_AF) && t->enabled;
804a6cfeb   Akshay Bhat   rtc: rx8010: Fix ...
237
  	return 0;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
238
239
240
241
  }
  
  static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t)
  {
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
242
243
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
  	u8 alarmvals[3];
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
244
  	int err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
245
246
247
  
  	if (rx8010->ctrlreg & (RX8010_CTRL_AIE | RX8010_CTRL_UIE)) {
  		rx8010->ctrlreg &= ~(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
248
249
  		err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
  		if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
250
  			return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
251
  	}
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
252
253
  	err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
254
255
256
257
258
  		return err;
  
  	alarmvals[0] = bin2bcd(t->time.tm_min);
  	alarmvals[1] = bin2bcd(t->time.tm_hour);
  	alarmvals[2] = bin2bcd(t->time.tm_mday);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
259
260
  	err = regmap_bulk_write(rx8010->regs, RX8010_ALMIN, alarmvals, 2);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
261
  		return err;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
262
263
  	err = regmap_clear_bits(rx8010->regs, RX8010_EXT, RX8010_EXT_WADA);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
264
265
266
267
  		return err;
  
  	if (alarmvals[2] == 0)
  		alarmvals[2] |= RX8010_ALARM_AE;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
268
269
  	err = regmap_write(rx8010->regs, RX8010_ALWDAY, alarmvals[2]);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
270
271
272
273
274
275
276
277
  		return err;
  
  	if (t->enabled) {
  		if (rx8010->rtc->uie_rtctimer.enabled)
  			rx8010->ctrlreg |= RX8010_CTRL_UIE;
  		if (rx8010->rtc->aie_timer.enabled)
  			rx8010->ctrlreg |=
  				(RX8010_CTRL_AIE | RX8010_CTRL_UIE);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
278
279
  		err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
  		if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
280
281
282
283
284
285
286
287
288
  			return err;
  	}
  
  	return 0;
  }
  
  static int rx8010_alarm_irq_enable(struct device *dev,
  				   unsigned int enabled)
  {
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
289
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
290
  	int err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
291
  	u8 ctrl;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
  
  	ctrl = rx8010->ctrlreg;
  
  	if (enabled) {
  		if (rx8010->rtc->uie_rtctimer.enabled)
  			ctrl |= RX8010_CTRL_UIE;
  		if (rx8010->rtc->aie_timer.enabled)
  			ctrl |= (RX8010_CTRL_AIE | RX8010_CTRL_UIE);
  	} else {
  		if (!rx8010->rtc->uie_rtctimer.enabled)
  			ctrl &= ~RX8010_CTRL_UIE;
  		if (!rx8010->rtc->aie_timer.enabled)
  			ctrl &= ~RX8010_CTRL_AIE;
  	}
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
306
307
  	err = regmap_clear_bits(rx8010->regs, RX8010_FLAG, RX8010_FLAG_AF);
  	if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
308
309
310
311
  		return err;
  
  	if (ctrl != rx8010->ctrlreg) {
  		rx8010->ctrlreg = ctrl;
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
312
313
  		err = regmap_write(rx8010->regs, RX8010_CTRL, rx8010->ctrlreg);
  		if (err)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
314
315
316
317
318
319
320
321
  			return err;
  	}
  
  	return 0;
  }
  
  static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
  {
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
322
  	struct rx8010_data *rx8010 = dev_get_drvdata(dev);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
323
  	int tmp, flagreg, err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
324
325
326
  
  	switch (cmd) {
  	case RTC_VL_READ:
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
327
328
329
  		err = regmap_read(rx8010->regs, RX8010_FLAG, &flagreg);
  		if (err)
  			return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
330

8049c1139   Alexandre Belloni   rtc: rx8010: retu...
331
332
  		tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
  		return put_user(tmp, (unsigned int __user *)arg);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
333

ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
334
335
336
337
  	default:
  		return -ENOIOCTLCMD;
  	}
  }
d3b14296d   Bartosz Golaszewski   rtc: rx8010: don'...
338
  static const struct rtc_class_ops rx8010_rtc_ops_default = {
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
339
340
341
342
  	.read_time = rx8010_get_time,
  	.set_time = rx8010_set_time,
  	.ioctl = rx8010_ioctl,
  };
d3b14296d   Bartosz Golaszewski   rtc: rx8010: don'...
343
344
345
346
347
348
349
350
  static const struct rtc_class_ops rx8010_rtc_ops_alarm = {
  	.read_time = rx8010_get_time,
  	.set_time = rx8010_set_time,
  	.ioctl = rx8010_ioctl,
  	.read_alarm = rx8010_read_alarm,
  	.set_alarm = rx8010_set_alarm,
  	.alarm_irq_enable = rx8010_alarm_irq_enable,
  };
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
351
352
353
354
355
  static const struct regmap_config rx8010_regmap_config = {
  	.name = "rx8010-rtc",
  	.reg_bits = 8,
  	.val_bits = 8,
  };
cee015d90   Bartosz Golaszewski   rtc: rx8010: swit...
356
  static int rx8010_probe(struct i2c_client *client)
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
357
  {
955a123c1   Bartosz Golaszewski   rtc: rx8010: use ...
358
  	struct device *dev = &client->dev;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
359
360
  	struct rx8010_data *rx8010;
  	int err = 0;
666f21413   Bartosz Golaszewski   rtc: rx8010: pref...
361
  	rx8010 = devm_kzalloc(dev, sizeof(*rx8010), GFP_KERNEL);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
362
363
  	if (!rx8010)
  		return -ENOMEM;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
364
  	i2c_set_clientdata(client, rx8010);
9868bc1ce   Bartosz Golaszewski   rtc: rx8010: conv...
365
366
367
  	rx8010->regs = devm_regmap_init_i2c(client, &rx8010_regmap_config);
  	if (IS_ERR(rx8010->regs))
  		return PTR_ERR(rx8010->regs);
ba1bcafb2   Bartosz Golaszewski   rtc: rx8010: rena...
368
  	err = rx8010_init(dev);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
369
370
  	if (err)
  		return err;
0ce627785   Bartosz Golaszewski   rtc: rx8010: swit...
371
372
373
  	rx8010->rtc = devm_rtc_allocate_device(dev);
  	if (IS_ERR(rx8010->rtc))
  		return PTR_ERR(rx8010->rtc);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
374
  	if (client->irq > 0) {
955a123c1   Bartosz Golaszewski   rtc: rx8010: use ...
375
376
377
  		dev_info(dev, "IRQ %d supplied
  ", client->irq);
  		err = devm_request_threaded_irq(dev, client->irq, NULL,
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
378
379
380
  						rx8010_irq_1_handler,
  						IRQF_TRIGGER_LOW | IRQF_ONESHOT,
  						"rx8010", client);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
381
  		if (err) {
955a123c1   Bartosz Golaszewski   rtc: rx8010: use ...
382
383
  			dev_err(dev, "unable to request IRQ
  ");
d3b14296d   Bartosz Golaszewski   rtc: rx8010: don'...
384
  			return err;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
385
  		}
d3b14296d   Bartosz Golaszewski   rtc: rx8010: don'...
386

0ce627785   Bartosz Golaszewski   rtc: rx8010: swit...
387
  		rx8010->rtc->ops = &rx8010_rtc_ops_alarm;
d3b14296d   Bartosz Golaszewski   rtc: rx8010: don'...
388
  	} else {
0ce627785   Bartosz Golaszewski   rtc: rx8010: swit...
389
  		rx8010->rtc->ops = &rx8010_rtc_ops_default;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
390
391
392
  	}
  
  	rx8010->rtc->max_user_freq = 1;
2fc1af309   Bartosz Golaszewski   rtc: rx8010: use ...
393
394
  	rx8010->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
  	rx8010->rtc->range_max = RTC_TIMESTAMP_END_2099;
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
395

0ce627785   Bartosz Golaszewski   rtc: rx8010: swit...
396
  	return rtc_register_device(rx8010->rtc);
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
397
398
399
400
401
  }
  
  static struct i2c_driver rx8010_driver = {
  	.driver = {
  		.name = "rtc-rx8010",
81b779ce5   Javier Martinez Canillas   rtc: rx8010: Add ...
402
  		.of_match_table = of_match_ptr(rx8010_of_match),
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
403
  	},
cee015d90   Bartosz Golaszewski   rtc: rx8010: swit...
404
  	.probe_new	= rx8010_probe,
ed13d89b0   Akshay Bhat   rtc: Add Epson RX...
405
406
407
408
409
410
411
412
  	.id_table	= rx8010_id,
  };
  
  module_i2c_driver(rx8010_driver);
  
  MODULE_AUTHOR("Akshay Bhat <akshay.bhat@timesys.com>");
  MODULE_DESCRIPTION("Epson RX8010SJ RTC driver");
  MODULE_LICENSE("GPL v2");