2121
2222#include <asm/byteorder.h>
2323
24- /* ISL register offsets */
24+ /* RTC - Real time clock registers */
2525#define ISL12022_REG_SC 0x00
2626#define ISL12022_REG_MN 0x01
2727#define ISL12022_REG_HR 0x02
3030#define ISL12022_REG_YR 0x05
3131#define ISL12022_REG_DW 0x06
3232
33+ /* CSR - Control and status registers */
3334#define ISL12022_REG_SR 0x07
3435#define ISL12022_REG_INT 0x08
35-
3636#define ISL12022_REG_PWR_VBAT 0x0a
37-
3837#define ISL12022_REG_BETA 0x0d
38+
39+ /* ALARM - Alarm registers */
40+ #define ISL12022_REG_SCA0 0x10
41+ #define ISL12022_REG_MNA0 0x11
42+ #define ISL12022_REG_HRA0 0x12
43+ #define ISL12022_REG_DTA0 0x13
44+ #define ISL12022_REG_MOA0 0x14
45+ #define ISL12022_REG_DWA0 0x15
46+ #define ISL12022_ALARM ISL12022_REG_SCA0
47+ #define ISL12022_ALARM_LEN (ISL12022_REG_DWA0 - ISL12022_REG_SCA0 + 1)
48+
49+ /* TEMP - Temperature sensor registers */
3950#define ISL12022_REG_TEMP_L 0x28
4051
4152/* ISL register bits */
4253#define ISL12022_HR_MIL (1 << 7) /* military or 24 hour time */
4354
55+ #define ISL12022_SR_ALM (1 << 4)
4456#define ISL12022_SR_LBAT85 (1 << 2)
4557#define ISL12022_SR_LBAT75 (1 << 1)
4658
59+ #define ISL12022_INT_ARST (1 << 7)
4760#define ISL12022_INT_WRTC (1 << 6)
61+ #define ISL12022_INT_IM (1 << 5)
62+ #define ISL12022_INT_FOBATB (1 << 4)
4863#define ISL12022_INT_FO_MASK GENMASK(3, 0)
4964#define ISL12022_INT_FO_OFF 0x0
5065#define ISL12022_INT_FO_32K 0x1
5166
5267#define ISL12022_REG_VB85_MASK GENMASK(5, 3)
5368#define ISL12022_REG_VB75_MASK GENMASK(2, 0)
5469
70+ #define ISL12022_ALARM_ENABLE (1 << 7) /* for all ALARM registers */
71+
5572#define ISL12022_BETA_TSE (1 << 7)
5673
74+ static struct i2c_driver isl12022_driver ;
75+
5776struct isl12022 {
77+ struct rtc_device * rtc ;
5878 struct regmap * regmap ;
79+ int irq ;
80+ bool irq_enabled ;
5981};
6082
6183static umode_t isl12022_hwmon_is_visible (const void * data ,
@@ -215,6 +237,194 @@ static int isl12022_rtc_set_time(struct device *dev, struct rtc_time *tm)
215237 return regmap_bulk_write (regmap , ISL12022_REG_SC , buf , sizeof (buf ));
216238}
217239
240+ static int isl12022_rtc_read_alarm (struct device * dev , struct rtc_wkalrm * alarm )
241+ {
242+ struct rtc_time * tm = & alarm -> time ;
243+ struct isl12022 * isl12022 = dev_get_drvdata (dev );
244+ struct regmap * regmap = isl12022 -> regmap ;
245+ u8 buf [ISL12022_ALARM_LEN ];
246+ unsigned int i , yr ;
247+ int ret ;
248+
249+ ret = regmap_bulk_read (regmap , ISL12022_ALARM , buf , sizeof (buf ));
250+ if (ret ) {
251+ dev_dbg (dev , "%s: reading ALARM registers failed\n" ,
252+ __func__ );
253+ return ret ;
254+ }
255+
256+ /* The alarm doesn't store the year so get it from the rtc section */
257+ ret = regmap_read (regmap , ISL12022_REG_YR , & yr );
258+ if (ret ) {
259+ dev_dbg (dev , "%s: reading YR register failed\n" , __func__ );
260+ return ret ;
261+ }
262+
263+ dev_dbg (dev ,
264+ "%s: sc=%02x, mn=%02x, hr=%02x, dt=%02x, mo=%02x, dw=%02x yr=%u\n" ,
265+ __func__ , buf [0 ], buf [1 ], buf [2 ], buf [3 ], buf [4 ], buf [5 ], yr );
266+
267+ tm -> tm_sec = bcd2bin (buf [ISL12022_REG_SCA0 - ISL12022_ALARM ] & 0x7F );
268+ tm -> tm_min = bcd2bin (buf [ISL12022_REG_MNA0 - ISL12022_ALARM ] & 0x7F );
269+ tm -> tm_hour = bcd2bin (buf [ISL12022_REG_HRA0 - ISL12022_ALARM ] & 0x3F );
270+ tm -> tm_mday = bcd2bin (buf [ISL12022_REG_DTA0 - ISL12022_ALARM ] & 0x3F );
271+ tm -> tm_mon = bcd2bin (buf [ISL12022_REG_MOA0 - ISL12022_ALARM ] & 0x1F ) - 1 ;
272+ tm -> tm_wday = buf [ISL12022_REG_DWA0 - ISL12022_ALARM ] & 0x07 ;
273+ tm -> tm_year = bcd2bin (yr ) + 100 ;
274+
275+ for (i = 0 ; i < ISL12022_ALARM_LEN ; i ++ ) {
276+ if (buf [i ] & ISL12022_ALARM_ENABLE ) {
277+ alarm -> enabled = 1 ;
278+ break ;
279+ }
280+ }
281+
282+ dev_dbg (dev , "%s: %ptR\n" , __func__ , tm );
283+
284+ return 0 ;
285+ }
286+
287+ static int isl12022_rtc_set_alarm (struct device * dev , struct rtc_wkalrm * alarm )
288+ {
289+ struct rtc_time * alarm_tm = & alarm -> time ;
290+ struct isl12022 * isl12022 = dev_get_drvdata (dev );
291+ struct regmap * regmap = isl12022 -> regmap ;
292+ u8 regs [ISL12022_ALARM_LEN ] = { 0 , };
293+ struct rtc_time rtc_tm ;
294+ int ret , enable , dw ;
295+
296+ ret = isl12022_rtc_read_time (dev , & rtc_tm );
297+ if (ret )
298+ return ret ;
299+
300+ /* If the alarm time is before the current time disable the alarm */
301+ if (!alarm -> enabled || rtc_tm_sub (alarm_tm , & rtc_tm ) <= 0 )
302+ enable = 0 ;
303+ else
304+ enable = ISL12022_ALARM_ENABLE ;
305+
306+ /*
307+ * Set non-matching day of the week to safeguard against early false
308+ * matching while setting all the alarm registers (this rtc lacks a
309+ * general alarm/irq enable/disable bit).
310+ */
311+ ret = regmap_read (regmap , ISL12022_REG_DW , & dw );
312+ if (ret ) {
313+ dev_dbg (dev , "%s: reading DW failed\n" , __func__ );
314+ return ret ;
315+ }
316+ /* ~4 days into the future should be enough to avoid match */
317+ dw = ((dw + 4 ) % 7 ) | ISL12022_ALARM_ENABLE ;
318+ ret = regmap_write (regmap , ISL12022_REG_DWA0 , dw );
319+ if (ret ) {
320+ dev_dbg (dev , "%s: writing DWA0 failed\n" , __func__ );
321+ return ret ;
322+ }
323+
324+ /* Program the alarm and enable it for each setting */
325+ regs [ISL12022_REG_SCA0 - ISL12022_ALARM ] = bin2bcd (alarm_tm -> tm_sec ) | enable ;
326+ regs [ISL12022_REG_MNA0 - ISL12022_ALARM ] = bin2bcd (alarm_tm -> tm_min ) | enable ;
327+ regs [ISL12022_REG_HRA0 - ISL12022_ALARM ] = bin2bcd (alarm_tm -> tm_hour ) | enable ;
328+ regs [ISL12022_REG_DTA0 - ISL12022_ALARM ] = bin2bcd (alarm_tm -> tm_mday ) | enable ;
329+ regs [ISL12022_REG_MOA0 - ISL12022_ALARM ] = bin2bcd (alarm_tm -> tm_mon + 1 ) | enable ;
330+ regs [ISL12022_REG_DWA0 - ISL12022_ALARM ] = bin2bcd (alarm_tm -> tm_wday & 7 ) | enable ;
331+
332+ /* write ALARM registers */
333+ ret = regmap_bulk_write (regmap , ISL12022_ALARM , & regs , sizeof (regs ));
334+ if (ret ) {
335+ dev_dbg (dev , "%s: writing ALARM registers failed\n" , __func__ );
336+ return ret ;
337+ }
338+
339+ return 0 ;
340+ }
341+
342+ static irqreturn_t isl12022_rtc_interrupt (int irq , void * data )
343+ {
344+ struct isl12022 * isl12022 = data ;
345+ struct rtc_device * rtc = isl12022 -> rtc ;
346+ struct device * dev = & rtc -> dev ;
347+ struct regmap * regmap = isl12022 -> regmap ;
348+ u32 val = 0 ;
349+ unsigned long events = 0 ;
350+ int ret ;
351+
352+ ret = regmap_read (regmap , ISL12022_REG_SR , & val );
353+ if (ret ) {
354+ dev_dbg (dev , "%s: reading SR failed\n" , __func__ );
355+ return IRQ_HANDLED ;
356+ }
357+
358+ if (val & ISL12022_SR_ALM )
359+ events |= RTC_IRQF | RTC_AF ;
360+
361+ if (events & RTC_AF )
362+ dev_dbg (dev , "alarm!\n" );
363+
364+ if (!events )
365+ return IRQ_NONE ;
366+
367+ rtc_update_irq (rtc , 1 , events );
368+ return IRQ_HANDLED ;
369+ }
370+
371+ static int isl12022_rtc_alarm_irq_enable (struct device * dev ,
372+ unsigned int enabled )
373+ {
374+ struct isl12022 * isl12022 = dev_get_drvdata (dev );
375+
376+ /* Make sure enabled is 0 or 1 */
377+ enabled = !!enabled ;
378+
379+ if (isl12022 -> irq_enabled == enabled )
380+ return 0 ;
381+
382+ if (enabled )
383+ enable_irq (isl12022 -> irq );
384+ else
385+ disable_irq (isl12022 -> irq );
386+
387+ isl12022 -> irq_enabled = enabled ;
388+
389+ return 0 ;
390+ }
391+
392+ static int isl12022_setup_irq (struct device * dev , int irq )
393+ {
394+ struct isl12022 * isl12022 = dev_get_drvdata (dev );
395+ struct regmap * regmap = isl12022 -> regmap ;
396+ unsigned int reg_mask , reg_val ;
397+ u8 buf [ISL12022_ALARM_LEN ] = { 0 , };
398+ int ret ;
399+
400+ /* Clear and disable all alarm registers */
401+ ret = regmap_bulk_write (regmap , ISL12022_ALARM , buf , sizeof (buf ));
402+ if (ret )
403+ return ret ;
404+
405+ /*
406+ * Enable automatic reset of ALM bit and enable single event interrupt
407+ * mode.
408+ */
409+ reg_mask = ISL12022_INT_ARST | ISL12022_INT_IM | ISL12022_INT_FO_MASK ;
410+ reg_val = ISL12022_INT_ARST | ISL12022_INT_FO_OFF ;
411+ ret = regmap_write_bits (regmap , ISL12022_REG_INT ,
412+ reg_mask , reg_val );
413+ if (ret )
414+ return ret ;
415+
416+ ret = devm_request_threaded_irq (dev , irq , NULL ,
417+ isl12022_rtc_interrupt ,
418+ IRQF_SHARED | IRQF_ONESHOT ,
419+ isl12022_driver .driver .name ,
420+ isl12022 );
421+ if (ret )
422+ return dev_err_probe (dev , ret , "Unable to request irq %d\n" , irq );
423+
424+ isl12022 -> irq = irq ;
425+ return 0 ;
426+ }
427+
218428static int isl12022_rtc_ioctl (struct device * dev , unsigned int cmd , unsigned long arg )
219429{
220430 struct isl12022 * isl12022 = dev_get_drvdata (dev );
@@ -246,6 +456,9 @@ static const struct rtc_class_ops isl12022_rtc_ops = {
246456 .ioctl = isl12022_rtc_ioctl ,
247457 .read_time = isl12022_rtc_read_time ,
248458 .set_time = isl12022_rtc_set_time ,
459+ .read_alarm = isl12022_rtc_read_alarm ,
460+ .set_alarm = isl12022_rtc_set_alarm ,
461+ .alarm_irq_enable = isl12022_rtc_alarm_irq_enable ,
249462};
250463
251464static const struct regmap_config regmap_config = {
@@ -349,10 +562,8 @@ static int isl12022_probe(struct i2c_client *client)
349562 return - ENOMEM ;
350563
351564 regmap = devm_regmap_init_i2c (client , & regmap_config );
352- if (IS_ERR (regmap )) {
353- dev_err (& client -> dev , "regmap allocation failed\n" );
354- return PTR_ERR (regmap );
355- }
565+ if (IS_ERR (regmap ))
566+ return dev_err_probe (& client -> dev , PTR_ERR (regmap ), "regmap allocation failed\n" );
356567 isl12022 -> regmap = regmap ;
357568
358569 dev_set_drvdata (& client -> dev , isl12022 );
@@ -367,11 +578,20 @@ static int isl12022_probe(struct i2c_client *client)
367578 rtc = devm_rtc_allocate_device (& client -> dev );
368579 if (IS_ERR (rtc ))
369580 return PTR_ERR (rtc );
581+ isl12022 -> rtc = rtc ;
370582
371583 rtc -> ops = & isl12022_rtc_ops ;
372584 rtc -> range_min = RTC_TIMESTAMP_BEGIN_2000 ;
373585 rtc -> range_max = RTC_TIMESTAMP_END_2099 ;
374586
587+ if (client -> irq > 0 ) {
588+ ret = isl12022_setup_irq (& client -> dev , client -> irq );
589+ if (ret )
590+ return ret ;
591+ } else {
592+ clear_bit (RTC_FEATURE_ALARM , rtc -> features );
593+ }
594+
375595 return devm_rtc_register_device (rtc );
376596}
377597
0 commit comments