Commit a73610d2c6dbfbc7383ae9d694b1412f57a3f398

Authored by Philipp Tomsich
1 parent a3716b5f3f

rtc: rv3029: update to support DM and sync with Linux 4.17

The "Flamingo" carrier-board for the RK3399-Q7 has a RV3029 populated
and the application will use the off-module RV3029 RTC including the
battery backed SRAM.

To support this use case, this commit includes the following changes:
 * updates the rv3029 driver to use DM
 * implements the read8/write8 operations

This syncs the implementation with the Linux code (based on 4.17),
porting the trickle-charger support from there (with improvements to
avoid unnecessary EEPROM updates) and adheres to the Linux DTS
binding.

Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Tested-by: Klaus Goger <klaus.goger@theobroma-systems.com>

Showing 2 changed files with 443 additions and 138 deletions Side-by-side Diff

drivers/rtc/rv3029.c
1 1 // SPDX-License-Identifier: GPL-2.0+
2 2 /*
3   - * (C) Copyright 2010
4   - * Heiko Schocher, DENX Software Engineering, hs@denx.de
  3 + * (C) Copyright 2018 Theobroma Systems Design und Consulting GmbH
  4 + *
  5 + * Based on a the Linux rtc-rv3029c2.c driver written by:
  6 + * Gregory Hermant <gregory.hermant@calao-systems.com>
  7 + * Michael Buesch <m@bues.ch>
5 8 */
  9 +
6 10 #include <common.h>
7 11 #include <command.h>
  12 +#include <dm.h>
8 13 #include <i2c.h>
9 14 #include <rtc.h>
10 15  
11   -#define RTC_RV3029_CTRL1 0x00
12   -#define RTC_RV3029_CTRL1_EERE (1 << 3)
  16 +#define RTC_RV3029_PAGE_LEN 7
13 17  
14   -#define RTC_RV3029_CTRL_STATUS 0x03
15   -#define RTC_RV3029_CTRLS_EEBUSY (1 << 7)
  18 +/* control section */
  19 +#define RV3029_ONOFF_CTRL 0x00
  20 +#define RV3029_ONOFF_CTRL_WE BIT(0)
  21 +#define RV3029_ONOFF_CTRL_TE BIT(1)
  22 +#define RV3029_ONOFF_CTRL_TAR BIT(2)
  23 +#define RV3029_ONOFF_CTRL_EERE BIT(3)
  24 +#define RV3029_ONOFF_CTRL_SRON BIT(4)
  25 +#define RV3029_ONOFF_CTRL_TD0 BIT(5)
  26 +#define RV3029_ONOFF_CTRL_TD1 BIT(6)
  27 +#define RV3029_ONOFF_CTRL_CLKINT BIT(7)
  28 +#define RV3029_IRQ_CTRL 0x01
  29 +#define RV3029_IRQ_CTRL_AIE BIT(0)
  30 +#define RV3029_IRQ_CTRL_TIE BIT(1)
  31 +#define RV3029_IRQ_CTRL_V1IE BIT(2)
  32 +#define RV3029_IRQ_CTRL_V2IE BIT(3)
  33 +#define RV3029_IRQ_CTRL_SRIE BIT(4)
  34 +#define RV3029_IRQ_FLAGS 0x02
  35 +#define RV3029_IRQ_FLAGS_AF BIT(0)
  36 +#define RV3029_IRQ_FLAGS_TF BIT(1)
  37 +#define RV3029_IRQ_FLAGS_V1IF BIT(2)
  38 +#define RV3029_IRQ_FLAGS_V2IF BIT(3)
  39 +#define RV3029_IRQ_FLAGS_SRF BIT(4)
  40 +#define RV3029_STATUS 0x03
  41 +#define RV3029_STATUS_VLOW1 BIT(2)
  42 +#define RV3029_STATUS_VLOW2 BIT(3)
  43 +#define RV3029_STATUS_SR BIT(4)
  44 +#define RV3029_STATUS_PON BIT(5)
  45 +#define RV3029_STATUS_EEBUSY BIT(7)
  46 +#define RV3029_RST_CTRL 0x04
  47 +#define RV3029_RST_CTRL_SYSR BIT(4)
  48 +#define RV3029_CONTROL_SECTION_LEN 0x05
16 49  
17   -#define RTC_RV3029_CTRL_RESET 0x04
18   -#define RTC_RV3029_CTRL_SYS_R (1 << 4)
  50 +/* watch section */
  51 +#define RV3029_W_SEC 0x08
  52 +#define RV3029_W_MINUTES 0x09
  53 +#define RV3029_W_HOURS 0x0A
  54 +#define RV3029_REG_HR_12_24 BIT(6) /* 24h/12h mode */
  55 +#define RV3029_REG_HR_PM BIT(5) /* PM/AM bit in 12h mode */
  56 +#define RV3029_W_DATE 0x0B
  57 +#define RV3029_W_DAYS 0x0C
  58 +#define RV3029_W_MONTHS 0x0D
  59 +#define RV3029_W_YEARS 0x0E
19 60  
20   -#define RTC_RV3029_CLOCK_PAGE 0x08
21   -#define RTC_RV3029_PAGE_LEN 7
  61 +/* eeprom control section */
  62 +#define RV3029_CONTROL_E2P_EECTRL 0x30
  63 +#define RV3029_TRICKLE_1K BIT(4) /* 1.5K resistance */
  64 +#define RV3029_TRICKLE_5K BIT(5) /* 5K resistance */
  65 +#define RV3029_TRICKLE_20K BIT(6) /* 20K resistance */
  66 +#define RV3029_TRICKLE_80K BIT(7) /* 80K resistance */
  67 +#define RV3029_TRICKLE_MASK (RV3029_TRICKLE_1K |\
  68 + RV3029_TRICKLE_5K |\
  69 + RV3029_TRICKLE_20K |\
  70 + RV3029_TRICKLE_80K)
  71 +#define RV3029_TRICKLE_SHIFT 4
22 72  
23   -#define RV3029C2_W_SECONDS 0x00
24   -#define RV3029C2_W_MINUTES 0x01
25   -#define RV3029C2_W_HOURS 0x02
26   -#define RV3029C2_W_DATE 0x03
27   -#define RV3029C2_W_DAYS 0x04
28   -#define RV3029C2_W_MONTHS 0x05
29   -#define RV3029C2_W_YEARS 0x06
30 73  
31   -#define RV3029C2_REG_HR_12_24 (1 << 6) /* 24h/12h mode */
32   -#define RV3029C2_REG_HR_PM (1 << 5) /* PM/AM bit in 12h mode */
33   -
34   -#define RTC_RV3029_EEPROM_CTRL 0x30
35   -#define RTC_RV3029_TRICKLE_1K (1 << 4)
36   -#define RTC_RV3029_TRICKLE_5K (1 << 5)
37   -#define RTC_RV3029_TRICKLE_20K (1 << 6)
38   -#define RTC_RV3029_TRICKLE_80K (1 << 7)
39   -
40   -int rtc_get( struct rtc_time *tmp )
  74 +static int rv3029_rtc_get(struct udevice *dev, struct rtc_time *tm)
41 75 {
42   - int ret;
43   - unsigned char buf[RTC_RV3029_PAGE_LEN];
  76 + u8 regs[RTC_RV3029_PAGE_LEN];
  77 + int ret;
44 78  
45   - ret = i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1, buf, \
46   - RTC_RV3029_PAGE_LEN);
47   - if (ret) {
  79 + ret = dm_i2c_read(dev, RV3029_W_SEC, regs, sizeof(regs));
  80 + if (ret < 0) {
48 81 printf("%s: error reading RTC: %x\n", __func__, ret);
49   - return -1;
  82 + return -EIO;
50 83 }
51   - tmp->tm_sec = bcd2bin( buf[RV3029C2_W_SECONDS] & 0x7f);
52   - tmp->tm_min = bcd2bin( buf[RV3029C2_W_MINUTES] & 0x7f);
53   - if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_12_24) {
54   - /* 12h format */
55   - tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x1f);
56   - if (buf[RV3029C2_W_HOURS] & RV3029C2_REG_HR_PM)
57   - /* PM flag set */
58   - tmp->tm_hour += 12;
59   - } else
60   - tmp->tm_hour = bcd2bin(buf[RV3029C2_W_HOURS] & 0x3f);
61 84  
62   - tmp->tm_mday = bcd2bin( buf[RV3029C2_W_DATE] & 0x3F );
63   - tmp->tm_mon = bcd2bin( buf[RV3029C2_W_MONTHS] & 0x1F );
64   - tmp->tm_wday = bcd2bin( buf[RV3029C2_W_DAYS] & 0x07 );
  85 + tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
  86 + tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
  87 +
  88 + /* HR field has a more complex interpretation */
  89 + {
  90 + const u8 _hr = regs[RV3029_W_HOURS - RV3029_W_SEC];
  91 +
  92 + if (_hr & RV3029_REG_HR_12_24) {
  93 + /* 12h format */
  94 + tm->tm_hour = bcd2bin(_hr & 0x1f);
  95 + if (_hr & RV3029_REG_HR_PM) /* PM flag set */
  96 + tm->tm_hour += 12;
  97 + } else {
  98 + /* 24h format */
  99 + tm->tm_hour = bcd2bin(_hr & 0x3f);
  100 + }
  101 + }
  102 +
  103 + tm->tm_mday = bcd2bin(regs[RV3029_W_DATE - RV3029_W_SEC]);
  104 + tm->tm_mon = bcd2bin(regs[RV3029_W_MONTHS - RV3029_W_SEC]) - 1;
65 105 /* RTC supports only years > 1999 */
66   - tmp->tm_year = bcd2bin( buf[RV3029C2_W_YEARS]) + 2000;
67   - tmp->tm_yday = 0;
68   - tmp->tm_isdst = 0;
  106 + tm->tm_year = bcd2bin(regs[RV3029_W_YEARS - RV3029_W_SEC]) + 2000;
  107 + tm->tm_wday = bcd2bin(regs[RV3029_W_DAYS - RV3029_W_SEC]) - 1;
69 108  
70   - debug( "Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
71   - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
72   - tmp->tm_hour, tmp->tm_min, tmp->tm_sec );
  109 + tm->tm_yday = 0;
  110 + tm->tm_isdst = 0;
73 111  
  112 + debug("%s: %4d-%02d-%02d (wday=%d) %2d:%02d:%02d\n",
  113 + __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
  114 + tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
  115 +
74 116 return 0;
75 117 }
76 118  
77   -int rtc_set( struct rtc_time *tmp )
  119 +static int rv3029_rtc_set(struct udevice *dev, const struct rtc_time *tm)
78 120 {
79   - int ret;
80   - unsigned char buf[RTC_RV3029_PAGE_LEN];
  121 + u8 regs[RTC_RV3029_PAGE_LEN];
81 122  
82   - debug( "Set DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n",
83   - tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
84   - tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
  123 + debug("%s: %4d-%02d-%02d (wday=%d( %2d:%02d:%02d\n",
  124 + __func__, tm->tm_year, tm->tm_mon, tm->tm_mday,
  125 + tm->tm_wday, tm->tm_hour, tm->tm_min, tm->tm_sec);
85 126  
86   - if (tmp->tm_year < 2000) {
87   - printf("RTC: year %d < 2000 not possible\n", tmp->tm_year);
88   - return -1;
  127 +
  128 + if (tm->tm_year < 2000) {
  129 + printf("%s: year %d (before 2000) not supported\n",
  130 + __func__, tm->tm_year);
  131 + return -EINVAL;
89 132 }
90   - buf[RV3029C2_W_SECONDS] = bin2bcd(tmp->tm_sec);
91   - buf[RV3029C2_W_MINUTES] = bin2bcd(tmp->tm_min);
92   - buf[RV3029C2_W_HOURS] = bin2bcd(tmp->tm_hour);
93   - /* set 24h format */
94   - buf[RV3029C2_W_HOURS] &= ~RV3029C2_REG_HR_12_24;
95   - buf[RV3029C2_W_DATE] = bin2bcd(tmp->tm_mday);
96   - buf[RV3029C2_W_DAYS] = bin2bcd(tmp->tm_wday);
97   - buf[RV3029C2_W_MONTHS] = bin2bcd(tmp->tm_mon);
98   - tmp->tm_year -= 2000;
99   - buf[RV3029C2_W_YEARS] = bin2bcd(tmp->tm_year);
100   - ret = i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CLOCK_PAGE, 1,
101   - buf, RTC_RV3029_PAGE_LEN);
102 133  
103   - /* give the RTC some time to update */
104   - udelay(1000);
105   - return ret;
  134 + regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
  135 + regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
  136 + regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
  137 + regs[RV3029_W_DATE - RV3029_W_SEC] = bin2bcd(tm->tm_mday);
  138 + regs[RV3029_W_MONTHS - RV3029_W_SEC] = bin2bcd(tm->tm_mon + 1);
  139 + regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
  140 + regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 2000);
  141 +
  142 + return dm_i2c_write(dev, RV3029_W_SEC, regs, sizeof(regs));
106 143 }
107 144  
108   -/* sets EERE-Bit (automatic EEPROM refresh) */
109   -static void set_eere_bit(int state)
  145 +static int rv3029_rtc_reset(struct udevice *dev)
110 146 {
111   - unsigned char reg_ctrl1;
  147 + u8 ctrl = RV3029_RST_CTRL_SYSR;
  148 + unsigned long start;
  149 + const unsigned long timeout_ms = 10000;
  150 + int ret;
112 151  
113   - (void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
114   - &reg_ctrl1, 1);
  152 + /* trigger the system-reset */
  153 + ret = dm_i2c_write(dev, RV3029_RST_CTRL, &ctrl, 1);
  154 + if (ret < 0)
  155 + return -EIO;
115 156  
116   - if (state)
117   - reg_ctrl1 |= RTC_RV3029_CTRL1_EERE;
118   - else
119   - reg_ctrl1 &= (~RTC_RV3029_CTRL1_EERE);
  157 + /* wait for the system-reset to complete */
  158 + start = get_timer(0);
  159 + do {
  160 + if (get_timer(start) > timeout_ms)
  161 + return -ETIMEDOUT;
120 162  
121   - (void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL1, 1,
122   - &reg_ctrl1, 1);
  163 + ret = dm_i2c_read(dev, RV3029_RST_CTRL, &ctrl, 1);
  164 + if (ret < 0)
  165 + return -EIO;
  166 + } while (ctrl & RV3029_RST_CTRL_SYSR);
  167 +
  168 + return 0;
123 169 }
124 170  
125   -/* waits until EEPROM page is no longer busy (times out after 10ms*loops) */
126   -static int wait_eebusy(int loops)
  171 +static int rv3029_rtc_read8(struct udevice *dev, unsigned int reg)
127 172 {
128   - int i;
129   - unsigned char ctrl_status;
  173 + u8 data;
  174 + int ret;
130 175  
131   - for (i = 0; i < loops; i++) {
132   - (void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_STATUS,
133   - 1, &ctrl_status, 1);
  176 + ret = dm_i2c_read(dev, reg, &data, sizeof(data));
  177 + return ret < 0 ? ret : data;
  178 +}
134 179  
135   - if ((ctrl_status & RTC_RV3029_CTRLS_EEBUSY) == 0)
  180 +static int rv3029_rtc_write8(struct udevice *dev, unsigned int reg, int val)
  181 +{
  182 + u8 data = val;
  183 +
  184 + return dm_i2c_write(dev, reg, &data, 1);
  185 +}
  186 +
  187 +#if defined(OF_CONTROL)
  188 +static int rv3029_get_sr(struct udevice *dev, u8 *buf)
  189 +{
  190 + int ret = dm_i2c_read(dev, RV3029_STATUS, buf, 1);
  191 +
  192 + if (ret < 0)
  193 + return -EIO;
  194 +
  195 + dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
  196 + return 0;
  197 +}
  198 +
  199 +static int rv3029_set_sr(struct udevice *dev, u8 val)
  200 +{
  201 + int ret;
  202 +
  203 + ret = dm_i2c_read(dev, RV3029_STATUS, &val, 1);
  204 + if (ret < 0)
  205 + return -EIO;
  206 +
  207 + dev_dbg(dev, "status = 0x%.2x (%d)\n", val, val);
  208 + return 0;
  209 +}
  210 +
  211 +static int rv3029_eeprom_busywait(struct udevice *dev)
  212 +{
  213 + int i, ret;
  214 + u8 sr;
  215 +
  216 + for (i = 100; i > 0; i--) {
  217 + ret = rv3029_get_sr(dev, &sr);
  218 + if (ret < 0)
136 219 break;
  220 + if (!(sr & RV3029_STATUS_EEBUSY))
  221 + break;
137 222 udelay(10000);
138 223 }
139   - return i;
  224 + if (i <= 0) {
  225 + dev_err(dev, "EEPROM busy wait timeout.\n");
  226 + return -ETIMEDOUT;
  227 + }
  228 +
  229 + return ret;
140 230 }
141 231  
142   -void rtc_reset (void)
  232 +static int rv3029_update_bits(struct udevice *dev, u8 reg, u8 mask, u8 set)
143 233 {
144   - unsigned char buf[RTC_RV3029_PAGE_LEN];
  234 + u8 buf;
  235 + int ret;
145 236  
146   - buf[0] = RTC_RV3029_CTRL_SYS_R;
147   - (void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_CTRL_RESET, 1,
148   - buf, 1);
  237 + ret = dm_i2c_read(dev, reg, &buf, 1);
  238 + if (ret < 0)
  239 + return ret;
149 240  
150   -#if defined(CONFIG_SYS_RV3029_TCR)
151   - /*
152   - * because EEPROM_CTRL register is in EEPROM page it is necessary to
153   - * disable automatic EEPROM refresh and check if EEPROM is busy
154   - * before EEPORM_CTRL register may be accessed
155   - */
156   - set_eere_bit(0);
157   - wait_eebusy(100);
158   - /* read current trickle charger setting */
159   - (void)i2c_read(CONFIG_SYS_I2C_RTC_ADDR, RTC_RV3029_EEPROM_CTRL,
160   - 1, buf, 1);
161   - /* enable automatic EEPROM refresh again */
162   - set_eere_bit(1);
  241 + if ((buf & mask) == (set && mask))
  242 + return 0;
163 243  
164   - /*
165   - * to minimize EEPROM access write trickle charger setting only if it
166   - * differs from current value
167   - */
168   - if ((buf[0] & 0xF0) != CONFIG_SYS_RV3029_TCR) {
169   - buf[0] = (buf[0] & 0x0F) | CONFIG_SYS_RV3029_TCR;
170   - /*
171   - * write trickle charger setting (disable autom. EEPROM
172   - * refresh and wait until EEPROM is idle)
  244 + buf = (buf & ~mask) | (set & mask);
  245 + ret = dm_i2c_read(dev, reg, &buf, 1);
  246 + if (ret < 0)
  247 + return ret;
  248 +
  249 + return 0;
  250 +}
  251 +
  252 +static int rv3029_eeprom_exit(struct udevice *dev)
  253 +{
  254 + /* Re-enable eeprom refresh */
  255 + return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
  256 + RV3029_ONOFF_CTRL_EERE,
  257 + RV3029_ONOFF_CTRL_EERE);
  258 +}
  259 +
  260 +static int rv3029_eeprom_enter(struct udevice *dev)
  261 +{
  262 + int ret;
  263 + u8 sr;
  264 +
  265 + /* Check whether we are in the allowed voltage range. */
  266 + ret = rv3029_get_sr(dev, &sr);
  267 + if (ret < 0)
  268 + return ret;
  269 + if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
  270 + /* We clear the bits and retry once just in case
  271 + * we had a brown out in early startup.
173 272 */
174   - set_eere_bit(0);
175   - wait_eebusy(100);
176   - (void)i2c_write(CONFIG_SYS_I2C_RTC_ADDR,
177   - RTC_RV3029_EEPROM_CTRL, 1, buf, 1);
178   - /*
179   - * it is necessary to wait 10ms before EEBUSY-Bit may be read
180   - * (this is not documented in the data sheet yet, but the
181   - * manufacturer recommends it)
182   - */
  273 + sr &= ~RV3029_STATUS_VLOW1;
  274 + sr &= ~RV3029_STATUS_VLOW2;
  275 + ret = rv3029_set_sr(dev, sr);
  276 + if (ret < 0)
  277 + return ret;
183 278 udelay(10000);
184   - /* wait until EEPROM write access is finished */
185   - wait_eebusy(100);
186   - set_eere_bit(1);
  279 + ret = rv3029_get_sr(dev, &sr);
  280 + if (ret < 0)
  281 + return ret;
  282 + if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
  283 + dev_err(dev, "Supply voltage is too low to safely access the EEPROM.\n");
  284 + return -ENODEV;
  285 + }
187 286 }
  287 +
  288 + /* Disable eeprom refresh. */
  289 + ret = rv3029_update_bits(dev,
  290 + RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE, 0);
  291 + if (ret < 0)
  292 + return ret;
  293 +
  294 + /* Wait for any previous eeprom accesses to finish. */
  295 + ret = rv3029_eeprom_busywait(dev);
  296 + if (ret < 0)
  297 + rv3029_eeprom_exit(dev);
  298 +
  299 + return ret;
  300 +}
  301 +
  302 +static int rv3029_eeprom_read(struct udevice *dev, u8 reg,
  303 + u8 buf[], size_t len)
  304 +{
  305 + int ret, err;
  306 +
  307 + err = rv3029_eeprom_enter(dev);
  308 + if (err < 0)
  309 + return err;
  310 +
  311 + ret = dm_i2c_read(dev, reg, buf, len);
  312 +
  313 + err = rv3029_eeprom_exit(dev);
  314 + if (err < 0)
  315 + return err;
  316 +
  317 + return ret;
  318 +}
  319 +
  320 +static int rv3029_eeprom_write(struct udevice *dev, u8 reg,
  321 + u8 const buf[], size_t len)
  322 +{
  323 + int ret;
  324 + size_t i;
  325 + u8 tmp;
  326 +
  327 + ret = rv3029_eeprom_enter(dev);
  328 + if (ret < 0)
  329 + return ret;
  330 +
  331 + for (i = 0; i < len; i++, reg++) {
  332 + ret = dm_i2c_read(dev, reg, &tmp, 1);
  333 + if (ret < 0)
  334 + break;
  335 + if (tmp != buf[i]) {
  336 + ret = dm_i2c_write(dev, reg, &buf[i], 1);
  337 + if (ret < 0)
  338 + break;
  339 + }
  340 + ret = rv3029_eeprom_busywait(dev);
  341 + if (ret < 0)
  342 + break;
  343 + }
  344 +
  345 + ret = rv3029_eeprom_exit(dev);
  346 + if (ret < 0)
  347 + return ret;
  348 +
  349 + return 0;
  350 +}
  351 +
  352 +static int rv3029_eeprom_update_bits(struct udevice *dev,
  353 + u8 reg, u8 mask, u8 set)
  354 +{
  355 + u8 buf;
  356 + int ret;
  357 +
  358 + ret = rv3029_eeprom_read(dev, reg, &buf, 1);
  359 + if (ret < 0)
  360 + return ret;
  361 +
  362 + /*
  363 + * If the EEPROM already reads the correct bitpattern, we don't need
  364 + * to update it.
  365 + */
  366 + if ((buf & mask) == (set & mask))
  367 + return 0;
  368 +
  369 + buf = (buf & ~mask) | (set & mask);
  370 + ret = rv3029_eeprom_write(dev, reg, &buf, 1);
  371 + if (ret < 0)
  372 + return ret;
  373 +
  374 + return 0;
  375 +}
  376 +
  377 +static void rv3029_trickle_config(struct udevice *dev)
  378 +{
  379 + static const struct rv3029_trickle_tab_elem {
  380 + u32 r; /* resistance in ohms */
  381 + u8 conf; /* trickle config bits */
  382 + } rv3029_trickle_tab[] = {
  383 + {
  384 + .r = 1076,
  385 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
  386 + RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
  387 + }, {
  388 + .r = 1091,
  389 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
  390 + RV3029_TRICKLE_20K,
  391 + }, {
  392 + .r = 1137,
  393 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K |
  394 + RV3029_TRICKLE_80K,
  395 + }, {
  396 + .r = 1154,
  397 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_5K,
  398 + }, {
  399 + .r = 1371,
  400 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K |
  401 + RV3029_TRICKLE_80K,
  402 + }, {
  403 + .r = 1395,
  404 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_20K,
  405 + }, {
  406 + .r = 1472,
  407 + .conf = RV3029_TRICKLE_1K | RV3029_TRICKLE_80K,
  408 + }, {
  409 + .r = 1500,
  410 + .conf = RV3029_TRICKLE_1K,
  411 + }, {
  412 + .r = 3810,
  413 + .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K |
  414 + RV3029_TRICKLE_80K,
  415 + }, {
  416 + .r = 4000,
  417 + .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_20K,
  418 + }, {
  419 + .r = 4706,
  420 + .conf = RV3029_TRICKLE_5K | RV3029_TRICKLE_80K,
  421 + }, {
  422 + .r = 5000,
  423 + .conf = RV3029_TRICKLE_5K,
  424 + }, {
  425 + .r = 16000,
  426 + .conf = RV3029_TRICKLE_20K | RV3029_TRICKLE_80K,
  427 + }, {
  428 + .r = 20000,
  429 + .conf = RV3029_TRICKLE_20K,
  430 + }, {
  431 + .r = 80000,
  432 + .conf = RV3029_TRICKLE_80K,
  433 + },
  434 + };
  435 + int err;
  436 + u32 ohms;
  437 + u8 trickle_set_bits = 0;
  438 +
  439 + /* Configure the trickle charger. */
  440 + err = dev_read_u32(dev, "trickle-resistor-ohms", &ohms);
  441 +
  442 + if (!err) {
  443 + /* Find trickle-charger config */
  444 + for (int i = 0; i < ARRAY_SIZE(rv3029_trickle_tab); i++)
  445 + if (rv3029_trickle_tab[i].r >= ohms) {
  446 + dev_dbg(dev, "trickle charger at %d ohms\n",
  447 + rv3029_trickle_tab[i].r);
  448 + trickle_set_bits = rv3029_trickle_tab[i].conf;
  449 + break;
  450 + }
  451 + }
  452 +
  453 + dev_dbg(dev, "trickle charger config 0x%x\n", trickle_set_bits);
  454 + err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
  455 + RV3029_TRICKLE_MASK,
  456 + trickle_set_bits);
  457 + if (err < 0)
  458 + dev_dbg(dev, "failed to update trickle charger\n");
  459 +}
  460 +#else
  461 +static inline void rv3029_trickle_config(struct udevice *dev)
  462 +{
  463 +}
188 464 #endif
  465 +
  466 +static int rv3029_probe(struct udevice *dev)
  467 +{
  468 + i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
  469 + DM_I2C_CHIP_WR_ADDRESS);
  470 +
  471 + rv3029_trickle_config(dev);
  472 + return 0;
189 473 }
  474 +
  475 +static const struct rtc_ops rv3029_rtc_ops = {
  476 + .get = rv3029_rtc_get,
  477 + .set = rv3029_rtc_set,
  478 + .read8 = rv3029_rtc_read8,
  479 + .write8 = rv3029_rtc_write8,
  480 + .reset = rv3029_rtc_reset,
  481 +};
  482 +
  483 +static const struct udevice_id rv3029_rtc_ids[] = {
  484 + { .compatible = "mc,rv3029" },
  485 + { .compatible = "mc,rv3029c2" },
  486 + { }
  487 +};
  488 +
  489 +U_BOOT_DRIVER(rtc_rv3029) = {
  490 + .name = "rtc-rv3029",
  491 + .id = UCLASS_RTC,
  492 + .probe = rv3029_probe,
  493 + .of_match = rv3029_rtc_ids,
  494 + .ops = &rv3029_rtc_ops,
  495 +};
scripts/config_whitelist.txt
... ... @@ -4054,7 +4054,6 @@
4054 4054 CONFIG_SYS_RTC_OSCILLATOR
4055 4055 CONFIG_SYS_RTC_REG_BASE_ADDR
4056 4056 CONFIG_SYS_RTC_SETUP
4057   -CONFIG_SYS_RV3029_TCR
4058 4057 CONFIG_SYS_RX_ETH_BUFFER
4059 4058 CONFIG_SYS_SATA
4060 4059 CONFIG_SYS_SATA1