rtc-pcf2127.c (3d715ebaf006bd5a495e9a717cf0fc5c260ee738) | rtc-pcf2127.c (adb9675d74e403537150f025ed2b7a2e1ed0a7b4) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * An I2C and SPI driver for the NXP PCF2127/29/31 RTC 4 * Copyright 2013 Til-Technologies 5 * 6 * Author: Renaud Cerrato <r.cerrato@til-technologies.fr> 7 * 8 * Watchdog and tamper functions --- 66 unchanged lines hidden (view full) --- 75 * PCF2129/31 doesn't have this feature. 76 */ 77#define PCF2127_REG_RAM_ADDR_MSB 0x1A 78#define PCF2127_REG_RAM_WRT_CMD 0x1C 79#define PCF2127_REG_RAM_RD_CMD 0x1D 80 81/* Watchdog timer value constants */ 82#define PCF2127_WD_VAL_STOP 0 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * An I2C and SPI driver for the NXP PCF2127/29/31 RTC 4 * Copyright 2013 Til-Technologies 5 * 6 * Author: Renaud Cerrato <r.cerrato@til-technologies.fr> 7 * 8 * Watchdog and tamper functions --- 66 unchanged lines hidden (view full) --- 75 * PCF2129/31 doesn't have this feature. 76 */ 77#define PCF2127_REG_RAM_ADDR_MSB 0x1A 78#define PCF2127_REG_RAM_WRT_CMD 0x1C 79#define PCF2127_REG_RAM_RD_CMD 0x1D 80 81/* Watchdog timer value constants */ 82#define PCF2127_WD_VAL_STOP 0 |
83#define PCF2127_WD_VAL_MIN 2 84#define PCF2127_WD_VAL_MAX 255 85#define PCF2127_WD_VAL_DEFAULT 60 | 83/* PCF2127/29 watchdog timer value constants */ 84#define PCF2127_WD_CLOCK_HZ_X1000 1000 /* 1Hz */ 85#define PCF2127_WD_MIN_HW_HEARTBEAT_MS 500 86/* PCF2131 watchdog timer value constants */ 87#define PCF2131_WD_CLOCK_HZ_X1000 250 /* 1/4Hz */ 88#define PCF2131_WD_MIN_HW_HEARTBEAT_MS 4000 |
86 | 89 |
90#define PCF2127_WD_DEFAULT_TIMEOUT_S 60 91 |
|
87/* Mask for currently enabled interrupts */ 88#define PCF2127_CTRL1_IRQ_MASK (PCF2127_BIT_CTRL1_TSF1) 89#define PCF2127_CTRL2_IRQ_MASK ( \ 90 PCF2127_BIT_CTRL2_AF | \ 91 PCF2127_BIT_CTRL2_WDTF | \ 92 PCF2127_BIT_CTRL2_TSF2) 93 94#define PCF2127_MAX_TS_SUPPORTED 4 --- 86 unchanged lines hidden (view full) --- 181 unsigned int has_nvmem:1; 182 unsigned int has_bit_wd_ctl_cd0:1; 183 unsigned int has_int_a_b:1; /* PCF2131 supports two interrupt outputs. */ 184 u8 reg_time_base; /* Time/date base register. */ 185 u8 regs_alarm_base; /* Alarm function base registers. */ 186 u8 reg_wd_ctl; /* Watchdog control register. */ 187 u8 reg_wd_val; /* Watchdog value register. */ 188 u8 reg_clkout; /* Clkout register. */ | 92/* Mask for currently enabled interrupts */ 93#define PCF2127_CTRL1_IRQ_MASK (PCF2127_BIT_CTRL1_TSF1) 94#define PCF2127_CTRL2_IRQ_MASK ( \ 95 PCF2127_BIT_CTRL2_AF | \ 96 PCF2127_BIT_CTRL2_WDTF | \ 97 PCF2127_BIT_CTRL2_TSF2) 98 99#define PCF2127_MAX_TS_SUPPORTED 4 --- 86 unchanged lines hidden (view full) --- 186 unsigned int has_nvmem:1; 187 unsigned int has_bit_wd_ctl_cd0:1; 188 unsigned int has_int_a_b:1; /* PCF2131 supports two interrupt outputs. */ 189 u8 reg_time_base; /* Time/date base register. */ 190 u8 regs_alarm_base; /* Alarm function base registers. */ 191 u8 reg_wd_ctl; /* Watchdog control register. */ 192 u8 reg_wd_val; /* Watchdog value register. */ 193 u8 reg_clkout; /* Clkout register. */ |
194 int wdd_clock_hz_x1000; /* Watchdog clock in Hz multiplicated by 1000 */ 195 int wdd_min_hw_heartbeat_ms; |
|
189 unsigned int ts_count; 190 struct pcf21xx_ts_config ts[PCF2127_MAX_TS_SUPPORTED]; 191 struct attribute_group attribute_group; 192}; 193 194struct pcf2127 { 195 struct rtc_device *rtc; 196 struct watchdog_device wdd; --- 187 unchanged lines hidden (view full) --- 384 return regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD, 385 val, bytes); 386} 387 388/* watchdog driver */ 389 390static int pcf2127_wdt_ping(struct watchdog_device *wdd) 391{ | 196 unsigned int ts_count; 197 struct pcf21xx_ts_config ts[PCF2127_MAX_TS_SUPPORTED]; 198 struct attribute_group attribute_group; 199}; 200 201struct pcf2127 { 202 struct rtc_device *rtc; 203 struct watchdog_device wdd; --- 187 unchanged lines hidden (view full) --- 391 return regmap_bulk_write(pcf2127->regmap, PCF2127_REG_RAM_WRT_CMD, 392 val, bytes); 393} 394 395/* watchdog driver */ 396 397static int pcf2127_wdt_ping(struct watchdog_device *wdd) 398{ |
399 int wd_val; |
|
392 struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd); 393 | 400 struct pcf2127 *pcf2127 = watchdog_get_drvdata(wdd); 401 |
394 return regmap_write(pcf2127->regmap, pcf2127->cfg->reg_wd_val, wdd->timeout); | 402 /* 403 * Compute counter value of WATCHDG_TIM_VAL to obtain desired period 404 * in seconds, depending on the source clock frequency. 405 */ 406 wd_val = ((wdd->timeout * pcf2127->cfg->wdd_clock_hz_x1000) / 1000) + 1; 407 408 return regmap_write(pcf2127->regmap, pcf2127->cfg->reg_wd_val, wd_val); |
395} 396 397/* 398 * Restart watchdog timer if feature is active. 399 * 400 * Note: Reading CTRL2 register causes watchdog to stop which is unfortunate, 401 * since register also contain control/status flags for other features. 402 * Always call this function after reading CTRL2 register. --- 45 unchanged lines hidden (view full) --- 448static const struct watchdog_ops pcf2127_watchdog_ops = { 449 .owner = THIS_MODULE, 450 .start = pcf2127_wdt_start, 451 .stop = pcf2127_wdt_stop, 452 .ping = pcf2127_wdt_ping, 453 .set_timeout = pcf2127_wdt_set_timeout, 454}; 455 | 409} 410 411/* 412 * Restart watchdog timer if feature is active. 413 * 414 * Note: Reading CTRL2 register causes watchdog to stop which is unfortunate, 415 * since register also contain control/status flags for other features. 416 * Always call this function after reading CTRL2 register. --- 45 unchanged lines hidden (view full) --- 462static const struct watchdog_ops pcf2127_watchdog_ops = { 463 .owner = THIS_MODULE, 464 .start = pcf2127_wdt_start, 465 .stop = pcf2127_wdt_stop, 466 .ping = pcf2127_wdt_ping, 467 .set_timeout = pcf2127_wdt_set_timeout, 468}; 469 |
470/* 471 * Compute watchdog period, t, in seconds, from the WATCHDG_TIM_VAL register 472 * value, n, and the clock frequency, f1000, in Hz x 1000. 473 * 474 * The PCF2127/29 datasheet gives t as: 475 * t = n / f 476 * The PCF2131 datasheet gives t as: 477 * t = (n - 1) / f 478 * For both variants, the watchdog is triggered when the WATCHDG_TIM_VAL reaches 479 * the value 1, and not zero. Consequently, the equation from the PCF2131 480 * datasheet seems to be the correct one for both variants. 481 */ 482static int pcf2127_watchdog_get_period(int n, int f1000) 483{ 484 return (1000 * (n - 1)) / f1000; 485} 486 |
|
456static int pcf2127_watchdog_init(struct device *dev, struct pcf2127 *pcf2127) 457{ 458 u32 wdd_timeout; 459 int ret; 460 461 if (!IS_ENABLED(CONFIG_WATCHDOG) || 462 !device_property_read_bool(dev, "reset-source")) 463 return 0; 464 465 pcf2127->wdd.parent = dev; 466 pcf2127->wdd.info = &pcf2127_wdt_info; 467 pcf2127->wdd.ops = &pcf2127_watchdog_ops; | 487static int pcf2127_watchdog_init(struct device *dev, struct pcf2127 *pcf2127) 488{ 489 u32 wdd_timeout; 490 int ret; 491 492 if (!IS_ENABLED(CONFIG_WATCHDOG) || 493 !device_property_read_bool(dev, "reset-source")) 494 return 0; 495 496 pcf2127->wdd.parent = dev; 497 pcf2127->wdd.info = &pcf2127_wdt_info; 498 pcf2127->wdd.ops = &pcf2127_watchdog_ops; |
468 pcf2127->wdd.min_timeout = PCF2127_WD_VAL_MIN; 469 pcf2127->wdd.max_timeout = PCF2127_WD_VAL_MAX; 470 pcf2127->wdd.timeout = PCF2127_WD_VAL_DEFAULT; 471 pcf2127->wdd.min_hw_heartbeat_ms = 500; | 499 500 pcf2127->wdd.min_timeout = 501 pcf2127_watchdog_get_period( 502 2, pcf2127->cfg->wdd_clock_hz_x1000); 503 pcf2127->wdd.max_timeout = 504 pcf2127_watchdog_get_period( 505 255, pcf2127->cfg->wdd_clock_hz_x1000); 506 pcf2127->wdd.timeout = PCF2127_WD_DEFAULT_TIMEOUT_S; 507 508 dev_dbg(dev, "%s clock = %d Hz / 1000\n", __func__, 509 pcf2127->cfg->wdd_clock_hz_x1000); 510 511 pcf2127->wdd.min_hw_heartbeat_ms = pcf2127->cfg->wdd_min_hw_heartbeat_ms; |
472 pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 473 474 watchdog_set_drvdata(&pcf2127->wdd, pcf2127); 475 476 /* Test if watchdog timer is started by bootloader */ 477 ret = regmap_read(pcf2127->regmap, pcf2127->cfg->reg_wd_val, &wdd_timeout); 478 if (ret) 479 return ret; --- 400 unchanged lines hidden (view full) --- 880 .has_nvmem = 1, 881 .has_bit_wd_ctl_cd0 = 1, 882 .has_int_a_b = 0, 883 .reg_time_base = PCF2127_REG_TIME_BASE, 884 .regs_alarm_base = PCF2127_REG_ALARM_BASE, 885 .reg_wd_ctl = PCF2127_REG_WD_CTL, 886 .reg_wd_val = PCF2127_REG_WD_VAL, 887 .reg_clkout = PCF2127_REG_CLKOUT, | 512 pcf2127->wdd.status = WATCHDOG_NOWAYOUT_INIT_STATUS; 513 514 watchdog_set_drvdata(&pcf2127->wdd, pcf2127); 515 516 /* Test if watchdog timer is started by bootloader */ 517 ret = regmap_read(pcf2127->regmap, pcf2127->cfg->reg_wd_val, &wdd_timeout); 518 if (ret) 519 return ret; --- 400 unchanged lines hidden (view full) --- 920 .has_nvmem = 1, 921 .has_bit_wd_ctl_cd0 = 1, 922 .has_int_a_b = 0, 923 .reg_time_base = PCF2127_REG_TIME_BASE, 924 .regs_alarm_base = PCF2127_REG_ALARM_BASE, 925 .reg_wd_ctl = PCF2127_REG_WD_CTL, 926 .reg_wd_val = PCF2127_REG_WD_VAL, 927 .reg_clkout = PCF2127_REG_CLKOUT, |
928 .wdd_clock_hz_x1000 = PCF2127_WD_CLOCK_HZ_X1000, 929 .wdd_min_hw_heartbeat_ms = PCF2127_WD_MIN_HW_HEARTBEAT_MS, |
|
888 .ts_count = 1, 889 .ts[0] = { 890 .reg_base = PCF2127_REG_TS1_BASE, 891 .gnd_detect_reg = PCF2127_REG_CTRL1, 892 .gnd_detect_bit = PCF2127_BIT_CTRL1_TSF1, 893 .inter_detect_reg = PCF2127_REG_CTRL2, 894 .inter_detect_bit = PCF2127_BIT_CTRL2_TSF2, 895 .ie_reg = PCF2127_REG_CTRL2, --- 9 unchanged lines hidden (view full) --- 905 .has_nvmem = 0, 906 .has_bit_wd_ctl_cd0 = 0, 907 .has_int_a_b = 0, 908 .reg_time_base = PCF2127_REG_TIME_BASE, 909 .regs_alarm_base = PCF2127_REG_ALARM_BASE, 910 .reg_wd_ctl = PCF2127_REG_WD_CTL, 911 .reg_wd_val = PCF2127_REG_WD_VAL, 912 .reg_clkout = PCF2127_REG_CLKOUT, | 930 .ts_count = 1, 931 .ts[0] = { 932 .reg_base = PCF2127_REG_TS1_BASE, 933 .gnd_detect_reg = PCF2127_REG_CTRL1, 934 .gnd_detect_bit = PCF2127_BIT_CTRL1_TSF1, 935 .inter_detect_reg = PCF2127_REG_CTRL2, 936 .inter_detect_bit = PCF2127_BIT_CTRL2_TSF2, 937 .ie_reg = PCF2127_REG_CTRL2, --- 9 unchanged lines hidden (view full) --- 947 .has_nvmem = 0, 948 .has_bit_wd_ctl_cd0 = 0, 949 .has_int_a_b = 0, 950 .reg_time_base = PCF2127_REG_TIME_BASE, 951 .regs_alarm_base = PCF2127_REG_ALARM_BASE, 952 .reg_wd_ctl = PCF2127_REG_WD_CTL, 953 .reg_wd_val = PCF2127_REG_WD_VAL, 954 .reg_clkout = PCF2127_REG_CLKOUT, |
955 .wdd_clock_hz_x1000 = PCF2127_WD_CLOCK_HZ_X1000, 956 .wdd_min_hw_heartbeat_ms = PCF2127_WD_MIN_HW_HEARTBEAT_MS, |
|
913 .ts_count = 1, 914 .ts[0] = { 915 .reg_base = PCF2127_REG_TS1_BASE, 916 .gnd_detect_reg = PCF2127_REG_CTRL1, 917 .gnd_detect_bit = PCF2127_BIT_CTRL1_TSF1, 918 .inter_detect_reg = PCF2127_REG_CTRL2, 919 .inter_detect_bit = PCF2127_BIT_CTRL2_TSF2, 920 .ie_reg = PCF2127_REG_CTRL2, --- 9 unchanged lines hidden (view full) --- 930 .has_nvmem = 0, 931 .has_bit_wd_ctl_cd0 = 0, 932 .has_int_a_b = 1, 933 .reg_time_base = PCF2131_REG_TIME_BASE, 934 .regs_alarm_base = PCF2131_REG_ALARM_BASE, 935 .reg_wd_ctl = PCF2131_REG_WD_CTL, 936 .reg_wd_val = PCF2131_REG_WD_VAL, 937 .reg_clkout = PCF2131_REG_CLKOUT, | 957 .ts_count = 1, 958 .ts[0] = { 959 .reg_base = PCF2127_REG_TS1_BASE, 960 .gnd_detect_reg = PCF2127_REG_CTRL1, 961 .gnd_detect_bit = PCF2127_BIT_CTRL1_TSF1, 962 .inter_detect_reg = PCF2127_REG_CTRL2, 963 .inter_detect_bit = PCF2127_BIT_CTRL2_TSF2, 964 .ie_reg = PCF2127_REG_CTRL2, --- 9 unchanged lines hidden (view full) --- 974 .has_nvmem = 0, 975 .has_bit_wd_ctl_cd0 = 0, 976 .has_int_a_b = 1, 977 .reg_time_base = PCF2131_REG_TIME_BASE, 978 .regs_alarm_base = PCF2131_REG_ALARM_BASE, 979 .reg_wd_ctl = PCF2131_REG_WD_CTL, 980 .reg_wd_val = PCF2131_REG_WD_VAL, 981 .reg_clkout = PCF2131_REG_CLKOUT, |
982 .wdd_clock_hz_x1000 = PCF2131_WD_CLOCK_HZ_X1000, 983 .wdd_min_hw_heartbeat_ms = PCF2131_WD_MIN_HW_HEARTBEAT_MS, |
|
938 .ts_count = 4, 939 .ts[0] = { 940 .reg_base = PCF2131_REG_TS1_BASE, 941 .gnd_detect_reg = PCF2131_REG_CTRL4, 942 .gnd_detect_bit = PCF2131_BIT_CTRL4_TSF1, 943 .inter_detect_bit = 0, 944 .ie_reg = PCF2131_REG_CTRL5, 945 .ie_bit = PCF2131_BIT_CTRL5_TSIE1, --- 197 unchanged lines hidden (view full) --- 1143 if (ret < 0) 1144 return ret; 1145 1146 msleep(100); 1147 } 1148 1149 /* 1150 * Watchdog timer enabled and reset pin /RST activated when timed out. | 984 .ts_count = 4, 985 .ts[0] = { 986 .reg_base = PCF2131_REG_TS1_BASE, 987 .gnd_detect_reg = PCF2131_REG_CTRL4, 988 .gnd_detect_bit = PCF2131_BIT_CTRL4_TSF1, 989 .inter_detect_bit = 0, 990 .ie_reg = PCF2131_REG_CTRL5, 991 .ie_bit = PCF2131_BIT_CTRL5_TSIE1, --- 197 unchanged lines hidden (view full) --- 1189 if (ret < 0) 1190 return ret; 1191 1192 msleep(100); 1193 } 1194 1195 /* 1196 * Watchdog timer enabled and reset pin /RST activated when timed out. |
1151 * Select 1Hz clock source for watchdog timer. | 1197 * Select 1Hz clock source for watchdog timer (1/4Hz for PCF2131). |
1152 * Note: Countdown timer disabled and not available. 1153 * For pca2129, pcf2129 and pcf2131, only bit[7] is for Symbol WD_CD 1154 * of register watchdg_tim_ctl. The bit[6] is labeled 1155 * as T. Bits labeled as T must always be written with 1156 * logic 0. 1157 */ 1158 ret = regmap_update_bits(pcf2127->regmap, pcf2127->cfg->reg_wd_ctl, 1159 PCF2127_BIT_WD_CTL_CD1 | --- 330 unchanged lines hidden --- | 1198 * Note: Countdown timer disabled and not available. 1199 * For pca2129, pcf2129 and pcf2131, only bit[7] is for Symbol WD_CD 1200 * of register watchdg_tim_ctl. The bit[6] is labeled 1201 * as T. Bits labeled as T must always be written with 1202 * logic 0. 1203 */ 1204 ret = regmap_update_bits(pcf2127->regmap, pcf2127->cfg->reg_wd_ctl, 1205 PCF2127_BIT_WD_CTL_CD1 | --- 330 unchanged lines hidden --- |