hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/drivers/rtc/rtc-abx80x.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /*
23 * A driver for the I2C members of the Abracon AB x8xx RTC family,
34 * and compatible: AB 1805 and AB 0805
....@@ -5,18 +6,16 @@
56 * Copyright 2014-2015 Macq S.A.
67 *
78 * Author: Philippe De Muyter <phdm@macqel.be>
8
- * Author: Alexandre Belloni <alexandre.belloni@free-electrons.com>
9
- *
10
- * This program is free software; you can redistribute it and/or modify
11
- * it under the terms of the GNU General Public License version 2 as
12
- * published by the Free Software Foundation.
9
+ * Author: Alexandre Belloni <alexandre.belloni@bootlin.com>
1310 *
1411 */
1512
1613 #include <linux/bcd.h>
1714 #include <linux/i2c.h>
1815 #include <linux/module.h>
16
+#include <linux/of_device.h>
1917 #include <linux/rtc.h>
18
+#include <linux/watchdog.h>
2019
2120 #define ABX8XX_REG_HTH 0x00
2221 #define ABX8XX_REG_SC 0x01
....@@ -37,11 +36,16 @@
3736
3837 #define ABX8XX_REG_STATUS 0x0f
3938 #define ABX8XX_STATUS_AF BIT(2)
39
+#define ABX8XX_STATUS_BLF BIT(4)
40
+#define ABX8XX_STATUS_WDT BIT(6)
4041
4142 #define ABX8XX_REG_CTRL1 0x10
4243 #define ABX8XX_CTRL_WRITE BIT(0)
4344 #define ABX8XX_CTRL_ARST BIT(2)
4445 #define ABX8XX_CTRL_12_24 BIT(6)
46
+
47
+#define ABX8XX_REG_CTRL2 0x11
48
+#define ABX8XX_CTRL2_RSVD BIT(5)
4549
4650 #define ABX8XX_REG_IRQ 0x12
4751 #define ABX8XX_IRQ_AIE BIT(2)
....@@ -61,11 +65,22 @@
6165 #define ABX8XX_OSS_OF BIT(1)
6266 #define ABX8XX_OSS_OMODE BIT(4)
6367
68
+#define ABX8XX_REG_WDT 0x1b
69
+#define ABX8XX_WDT_WDS BIT(7)
70
+#define ABX8XX_WDT_BMB_MASK 0x7c
71
+#define ABX8XX_WDT_BMB_SHIFT 2
72
+#define ABX8XX_WDT_MAX_TIME (ABX8XX_WDT_BMB_MASK >> ABX8XX_WDT_BMB_SHIFT)
73
+#define ABX8XX_WDT_WRB_MASK 0x03
74
+#define ABX8XX_WDT_WRB_1HZ 0x02
75
+
6476 #define ABX8XX_REG_CFG_KEY 0x1f
6577 #define ABX8XX_CFG_KEY_OSC 0xa1
6678 #define ABX8XX_CFG_KEY_MISC 0x9d
6779
6880 #define ABX8XX_REG_ID0 0x28
81
+
82
+#define ABX8XX_REG_OUT_CTRL 0x30
83
+#define ABX8XX_OUT_CTRL_EXDS BIT(4)
6984
7085 #define ABX8XX_REG_TRICKLE 0x20
7186 #define ABX8XX_TRICKLE_CHARGE_ENABLE 0xa0
....@@ -75,23 +90,31 @@
7590 static u8 trickle_resistors[] = {0, 3, 6, 11};
7691
7792 enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
78
- AB1801, AB1803, AB1804, AB1805, ABX80X};
93
+ AB1801, AB1803, AB1804, AB1805, RV1805, ABX80X};
7994
8095 struct abx80x_cap {
8196 u16 pn;
8297 bool has_tc;
98
+ bool has_wdog;
8399 };
84100
85101 static struct abx80x_cap abx80x_caps[] = {
86102 [AB0801] = {.pn = 0x0801},
87103 [AB0803] = {.pn = 0x0803},
88
- [AB0804] = {.pn = 0x0804, .has_tc = true},
89
- [AB0805] = {.pn = 0x0805, .has_tc = true},
104
+ [AB0804] = {.pn = 0x0804, .has_tc = true, .has_wdog = true},
105
+ [AB0805] = {.pn = 0x0805, .has_tc = true, .has_wdog = true},
90106 [AB1801] = {.pn = 0x1801},
91107 [AB1803] = {.pn = 0x1803},
92
- [AB1804] = {.pn = 0x1804, .has_tc = true},
93
- [AB1805] = {.pn = 0x1805, .has_tc = true},
108
+ [AB1804] = {.pn = 0x1804, .has_tc = true, .has_wdog = true},
109
+ [AB1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
110
+ [RV1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
94111 [ABX80X] = {.pn = 0}
112
+};
113
+
114
+struct abx80x_priv {
115
+ struct rtc_device *rtc;
116
+ struct i2c_client *client;
117
+ struct watchdog_device wdog;
95118 };
96119
97120 static int abx80x_is_rc_mode(struct i2c_client *client)
....@@ -218,7 +241,8 @@
218241 static irqreturn_t abx80x_handle_irq(int irq, void *dev_id)
219242 {
220243 struct i2c_client *client = dev_id;
221
- struct rtc_device *rtc = i2c_get_clientdata(client);
244
+ struct abx80x_priv *priv = i2c_get_clientdata(client);
245
+ struct rtc_device *rtc = priv->rtc;
222246 int status;
223247
224248 status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
....@@ -227,6 +251,13 @@
227251
228252 if (status & ABX8XX_STATUS_AF)
229253 rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF);
254
+
255
+ /*
256
+ * It is unclear if we'll get an interrupt before the external
257
+ * reset kicks in.
258
+ */
259
+ if (status & ABX8XX_STATUS_WDT)
260
+ dev_alert(&client->dev, "watchdog timeout interrupt.\n");
230261
231262 i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
232263
....@@ -371,7 +402,7 @@
371402 return -EINVAL;
372403 }
373404
374
- retval = abx80x_rtc_set_autocalibration(dev, autocalibration);
405
+ retval = abx80x_rtc_set_autocalibration(dev->parent, autocalibration);
375406
376407 return retval ? retval : count;
377408 }
....@@ -381,7 +412,7 @@
381412 {
382413 int autocalibration = 0;
383414
384
- autocalibration = abx80x_rtc_get_autocalibration(dev);
415
+ autocalibration = abx80x_rtc_get_autocalibration(dev->parent);
385416 if (autocalibration < 0) {
386417 dev_err(dev, "Failed to read RTC autocalibration\n");
387418 sprintf(buf, "0\n");
....@@ -397,7 +428,7 @@
397428 struct device_attribute *attr,
398429 const char *buf, size_t count)
399430 {
400
- struct i2c_client *client = to_i2c_client(dev);
431
+ struct i2c_client *client = to_i2c_client(dev->parent);
401432 int retval, flags, rc_mode = 0;
402433
403434 if (strncmp(buf, "rc", 2) == 0) {
....@@ -439,7 +470,7 @@
439470 struct device_attribute *attr, char *buf)
440471 {
441472 int rc_mode = 0;
442
- struct i2c_client *client = to_i2c_client(dev);
473
+ struct i2c_client *client = to_i2c_client(dev->parent);
443474
444475 rc_mode = abx80x_is_rc_mode(client);
445476
....@@ -482,16 +513,51 @@
482513 return err;
483514 }
484515
516
+static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
517
+{
518
+ struct i2c_client *client = to_i2c_client(dev);
519
+ int status, tmp;
520
+
521
+ switch (cmd) {
522
+ case RTC_VL_READ:
523
+ status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
524
+ if (status < 0)
525
+ return status;
526
+
527
+ tmp = status & ABX8XX_STATUS_BLF ? RTC_VL_BACKUP_LOW : 0;
528
+
529
+ return put_user(tmp, (unsigned int __user *)arg);
530
+
531
+ case RTC_VL_CLR:
532
+ status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
533
+ if (status < 0)
534
+ return status;
535
+
536
+ status &= ~ABX8XX_STATUS_BLF;
537
+
538
+ tmp = i2c_smbus_write_byte_data(client, ABX8XX_REG_STATUS, 0);
539
+ if (tmp < 0)
540
+ return tmp;
541
+
542
+ return 0;
543
+
544
+ default:
545
+ return -ENOIOCTLCMD;
546
+ }
547
+}
548
+
485549 static const struct rtc_class_ops abx80x_rtc_ops = {
486550 .read_time = abx80x_rtc_read_time,
487551 .set_time = abx80x_rtc_set_time,
488552 .read_alarm = abx80x_read_alarm,
489553 .set_alarm = abx80x_set_alarm,
490554 .alarm_irq_enable = abx80x_alarm_irq_enable,
555
+ .ioctl = abx80x_ioctl,
491556 };
492557
493
-static int abx80x_dt_trickle_cfg(struct device_node *np)
558
+static int abx80x_dt_trickle_cfg(struct i2c_client *client)
494559 {
560
+ struct device_node *np = client->dev.of_node;
495561 const char *diode;
496562 int trickle_cfg = 0;
497563 int i, ret;
....@@ -501,12 +567,14 @@
501567 if (ret)
502568 return ret;
503569
504
- if (!strcmp(diode, "standard"))
570
+ if (!strcmp(diode, "standard")) {
505571 trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE;
506
- else if (!strcmp(diode, "schottky"))
572
+ } else if (!strcmp(diode, "schottky")) {
507573 trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE;
508
- else
574
+ } else {
575
+ dev_dbg(&client->dev, "Invalid tc-diode value: %s\n", diode);
509576 return -EINVAL;
577
+ }
510578
511579 ret = of_property_read_u32(np, "abracon,tc-resistor", &tmp);
512580 if (ret)
....@@ -516,24 +584,102 @@
516584 if (trickle_resistors[i] == tmp)
517585 break;
518586
519
- if (i == sizeof(trickle_resistors))
587
+ if (i == sizeof(trickle_resistors)) {
588
+ dev_dbg(&client->dev, "Invalid tc-resistor value: %u\n", tmp);
520589 return -EINVAL;
590
+ }
521591
522592 return (trickle_cfg | i);
523593 }
524594
525
-static void rtc_calib_remove_sysfs_group(void *_dev)
526
-{
527
- struct device *dev = _dev;
595
+#ifdef CONFIG_WATCHDOG
528596
529
- sysfs_remove_group(&dev->kobj, &rtc_calib_attr_group);
597
+static inline u8 timeout_bits(unsigned int timeout)
598
+{
599
+ return ((timeout << ABX8XX_WDT_BMB_SHIFT) & ABX8XX_WDT_BMB_MASK) |
600
+ ABX8XX_WDT_WRB_1HZ;
530601 }
602
+
603
+static int __abx80x_wdog_set_timeout(struct watchdog_device *wdog,
604
+ unsigned int timeout)
605
+{
606
+ struct abx80x_priv *priv = watchdog_get_drvdata(wdog);
607
+ u8 val = ABX8XX_WDT_WDS | timeout_bits(timeout);
608
+
609
+ /*
610
+ * Writing any timeout to the WDT register resets the watchdog timer.
611
+ * Writing 0 disables it.
612
+ */
613
+ return i2c_smbus_write_byte_data(priv->client, ABX8XX_REG_WDT, val);
614
+}
615
+
616
+static int abx80x_wdog_set_timeout(struct watchdog_device *wdog,
617
+ unsigned int new_timeout)
618
+{
619
+ int err = 0;
620
+
621
+ if (watchdog_hw_running(wdog))
622
+ err = __abx80x_wdog_set_timeout(wdog, new_timeout);
623
+
624
+ if (err == 0)
625
+ wdog->timeout = new_timeout;
626
+
627
+ return err;
628
+}
629
+
630
+static int abx80x_wdog_ping(struct watchdog_device *wdog)
631
+{
632
+ return __abx80x_wdog_set_timeout(wdog, wdog->timeout);
633
+}
634
+
635
+static int abx80x_wdog_start(struct watchdog_device *wdog)
636
+{
637
+ return __abx80x_wdog_set_timeout(wdog, wdog->timeout);
638
+}
639
+
640
+static int abx80x_wdog_stop(struct watchdog_device *wdog)
641
+{
642
+ return __abx80x_wdog_set_timeout(wdog, 0);
643
+}
644
+
645
+static const struct watchdog_info abx80x_wdog_info = {
646
+ .identity = "abx80x watchdog",
647
+ .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
648
+};
649
+
650
+static const struct watchdog_ops abx80x_wdog_ops = {
651
+ .owner = THIS_MODULE,
652
+ .start = abx80x_wdog_start,
653
+ .stop = abx80x_wdog_stop,
654
+ .ping = abx80x_wdog_ping,
655
+ .set_timeout = abx80x_wdog_set_timeout,
656
+};
657
+
658
+static int abx80x_setup_watchdog(struct abx80x_priv *priv)
659
+{
660
+ priv->wdog.parent = &priv->client->dev;
661
+ priv->wdog.ops = &abx80x_wdog_ops;
662
+ priv->wdog.info = &abx80x_wdog_info;
663
+ priv->wdog.min_timeout = 1;
664
+ priv->wdog.max_timeout = ABX8XX_WDT_MAX_TIME;
665
+ priv->wdog.timeout = ABX8XX_WDT_MAX_TIME;
666
+
667
+ watchdog_set_drvdata(&priv->wdog, priv);
668
+
669
+ return devm_watchdog_register_device(&priv->client->dev, &priv->wdog);
670
+}
671
+#else
672
+static int abx80x_setup_watchdog(struct abx80x_priv *priv)
673
+{
674
+ return 0;
675
+}
676
+#endif
531677
532678 static int abx80x_probe(struct i2c_client *client,
533679 const struct i2c_device_id *id)
534680 {
535681 struct device_node *np = client->dev.of_node;
536
- struct rtc_device *rtc;
682
+ struct abx80x_priv *priv;
537683 int i, data, err, trickle_cfg = -EINVAL;
538684 char buf[7];
539685 unsigned int part = id->driver_data;
....@@ -577,6 +723,62 @@
577723 return -EIO;
578724 }
579725
726
+ /* Configure RV1805 specifics */
727
+ if (part == RV1805) {
728
+ /*
729
+ * Avoid accidentally entering test mode. This can happen
730
+ * on the RV1805 in case the reserved bit 5 in control2
731
+ * register is set. RV-1805-C3 datasheet indicates that
732
+ * the bit should be cleared in section 11h - Control2.
733
+ */
734
+ data = i2c_smbus_read_byte_data(client, ABX8XX_REG_CTRL2);
735
+ if (data < 0) {
736
+ dev_err(&client->dev,
737
+ "Unable to read control2 register\n");
738
+ return -EIO;
739
+ }
740
+
741
+ err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CTRL2,
742
+ data & ~ABX8XX_CTRL2_RSVD);
743
+ if (err < 0) {
744
+ dev_err(&client->dev,
745
+ "Unable to write control2 register\n");
746
+ return -EIO;
747
+ }
748
+
749
+ /*
750
+ * Avoid extra power leakage. The RV1805 uses smaller
751
+ * 10pin package and the EXTI input is not present.
752
+ * Disable it to avoid leakage.
753
+ */
754
+ data = i2c_smbus_read_byte_data(client, ABX8XX_REG_OUT_CTRL);
755
+ if (data < 0) {
756
+ dev_err(&client->dev,
757
+ "Unable to read output control register\n");
758
+ return -EIO;
759
+ }
760
+
761
+ /*
762
+ * Write the configuration key register to enable access to
763
+ * the config2 register
764
+ */
765
+ err = i2c_smbus_write_byte_data(client, ABX8XX_REG_CFG_KEY,
766
+ ABX8XX_CFG_KEY_MISC);
767
+ if (err < 0) {
768
+ dev_err(&client->dev,
769
+ "Unable to write configuration key\n");
770
+ return -EIO;
771
+ }
772
+
773
+ err = i2c_smbus_write_byte_data(client, ABX8XX_REG_OUT_CTRL,
774
+ data | ABX8XX_OUT_CTRL_EXDS);
775
+ if (err < 0) {
776
+ dev_err(&client->dev,
777
+ "Unable to write output control register\n");
778
+ return -EIO;
779
+ }
780
+ }
781
+
580782 /* part autodetection */
581783 if (part == ABX80X) {
582784 for (i = 0; abx80x_caps[i].pn; i++)
....@@ -597,7 +799,7 @@
597799 }
598800
599801 if (np && abx80x_caps[part].has_tc)
600
- trickle_cfg = abx80x_dt_trickle_cfg(np);
802
+ trickle_cfg = abx80x_dt_trickle_cfg(client);
601803
602804 if (trickle_cfg > 0) {
603805 dev_info(&client->dev, "Enabling trickle charger: %02x\n",
....@@ -610,13 +812,24 @@
610812 if (err)
611813 return err;
612814
613
- rtc = devm_rtc_allocate_device(&client->dev);
614
- if (IS_ERR(rtc))
615
- return PTR_ERR(rtc);
815
+ priv = devm_kzalloc(&client->dev, sizeof(*priv), GFP_KERNEL);
816
+ if (priv == NULL)
817
+ return -ENOMEM;
616818
617
- rtc->ops = &abx80x_rtc_ops;
819
+ priv->rtc = devm_rtc_allocate_device(&client->dev);
820
+ if (IS_ERR(priv->rtc))
821
+ return PTR_ERR(priv->rtc);
618822
619
- i2c_set_clientdata(client, rtc);
823
+ priv->rtc->ops = &abx80x_rtc_ops;
824
+ priv->client = client;
825
+
826
+ i2c_set_clientdata(client, priv);
827
+
828
+ if (abx80x_caps[part].has_wdog) {
829
+ err = abx80x_setup_watchdog(priv);
830
+ if (err)
831
+ return err;
832
+ }
620833
621834 if (client->irq > 0) {
622835 dev_info(&client->dev, "IRQ %d supplied\n", client->irq);
....@@ -631,32 +844,14 @@
631844 }
632845 }
633846
634
- /* Export sysfs entries */
635
- err = sysfs_create_group(&(&client->dev)->kobj, &rtc_calib_attr_group);
847
+ err = rtc_add_group(priv->rtc, &rtc_calib_attr_group);
636848 if (err) {
637849 dev_err(&client->dev, "Failed to create sysfs group: %d\n",
638850 err);
639851 return err;
640852 }
641853
642
- err = devm_add_action_or_reset(&client->dev,
643
- rtc_calib_remove_sysfs_group,
644
- &client->dev);
645
- if (err) {
646
- dev_err(&client->dev,
647
- "Failed to add sysfs cleanup action: %d\n",
648
- err);
649
- return err;
650
- }
651
-
652
- err = rtc_register_device(rtc);
653
-
654
- return err;
655
-}
656
-
657
-static int abx80x_remove(struct i2c_client *client)
658
-{
659
- return 0;
854
+ return rtc_register_device(priv->rtc);
660855 }
661856
662857 static const struct i2c_device_id abx80x_id[] = {
....@@ -669,23 +864,70 @@
669864 { "ab1803", AB1803 },
670865 { "ab1804", AB1804 },
671866 { "ab1805", AB1805 },
672
- { "rv1805", AB1805 },
867
+ { "rv1805", RV1805 },
673868 { }
674869 };
675870 MODULE_DEVICE_TABLE(i2c, abx80x_id);
676871
872
+#ifdef CONFIG_OF
873
+static const struct of_device_id abx80x_of_match[] = {
874
+ {
875
+ .compatible = "abracon,abx80x",
876
+ .data = (void *)ABX80X
877
+ },
878
+ {
879
+ .compatible = "abracon,ab0801",
880
+ .data = (void *)AB0801
881
+ },
882
+ {
883
+ .compatible = "abracon,ab0803",
884
+ .data = (void *)AB0803
885
+ },
886
+ {
887
+ .compatible = "abracon,ab0804",
888
+ .data = (void *)AB0804
889
+ },
890
+ {
891
+ .compatible = "abracon,ab0805",
892
+ .data = (void *)AB0805
893
+ },
894
+ {
895
+ .compatible = "abracon,ab1801",
896
+ .data = (void *)AB1801
897
+ },
898
+ {
899
+ .compatible = "abracon,ab1803",
900
+ .data = (void *)AB1803
901
+ },
902
+ {
903
+ .compatible = "abracon,ab1804",
904
+ .data = (void *)AB1804
905
+ },
906
+ {
907
+ .compatible = "abracon,ab1805",
908
+ .data = (void *)AB1805
909
+ },
910
+ {
911
+ .compatible = "microcrystal,rv1805",
912
+ .data = (void *)RV1805
913
+ },
914
+ { }
915
+};
916
+MODULE_DEVICE_TABLE(of, abx80x_of_match);
917
+#endif
918
+
677919 static struct i2c_driver abx80x_driver = {
678920 .driver = {
679921 .name = "rtc-abx80x",
922
+ .of_match_table = of_match_ptr(abx80x_of_match),
680923 },
681924 .probe = abx80x_probe,
682
- .remove = abx80x_remove,
683925 .id_table = abx80x_id,
684926 };
685927
686928 module_i2c_driver(abx80x_driver);
687929
688930 MODULE_AUTHOR("Philippe De Muyter <phdm@macqel.be>");
689
-MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@free-electrons.com>");
931
+MODULE_AUTHOR("Alexandre Belloni <alexandre.belloni@bootlin.com>");
690932 MODULE_DESCRIPTION("Abracon ABX80X RTC driver");
691933 MODULE_LICENSE("GPL v2");