1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright 2020 Michal Meloun <mmel@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/bus.h> 34 #include <sys/clock.h> 35 #include <sys/kernel.h> 36 #include <sys/module.h> 37 #include <sys/rman.h> 38 #include <sys/sx.h> 39 40 #include <dev/iicbus/iiconf.h> 41 #include <dev/iicbus/iicbus.h> 42 #include <dev/ofw/ofw_bus.h> 43 #include <dev/ofw/ofw_bus_subr.h> 44 45 #include "clock_if.h" 46 #include "ofw_iicbus_if.h" 47 #include "max77620.h" 48 49 #define MAX77620_RTC_INT 0x00 50 #define MAX77620_RTC_INTM 0x01 51 #define MAX77620_RTC_CONTROLM 0x02 52 #define MAX77620_RTC_CONTROL 0x03 53 #define RTC_CONTROL_MODE_24 (1 << 1) 54 #define RTC_CONTROL_BCD_EN (1 << 0) 55 56 #define MAX77620_RTC_UPDATE0 0x04 57 #define RTC_UPDATE0_RTC_RBUDR (1 << 4) 58 #define RTC_UPDATE0_RTC_UDR (1 << 0) 59 60 #define MAX77620_WTSR_SMPL_CNTL 0x06 61 #define MAX77620_RTC_SEC 0x07 62 #define MAX77620_RTC_MIN 0x08 63 #define MAX77620_RTC_HOUR 0x09 64 #define MAX77620_RTC_WEEKDAY 0x0A 65 #define MAX77620_RTC_MONTH 0x0B 66 #define MAX77620_RTC_YEAR 0x0C 67 #define MAX77620_RTC_DATE 0x0D 68 #define MAX77620_ALARM1_SEC 0x0E 69 #define MAX77620_ALARM1_MIN 0x0F 70 #define MAX77620_ALARM1_HOUR 0x10 71 #define MAX77620_ALARM1_WEEKDAY 0x11 72 #define MAX77620_ALARM1_MONTH 0x12 73 #define MAX77620_ALARM1_YEAR 0x13 74 #define MAX77620_ALARM1_DATE 0x14 75 #define MAX77620_ALARM2_SEC 0x15 76 #define MAX77620_ALARM2_MIN 0x16 77 #define MAX77620_ALARM2_HOUR 0x17 78 #define MAX77620_ALARM2_WEEKDAY 0x18 79 #define MAX77620_ALARM2_MONTH 0x19 80 #define MAX77620_ALARM2_YEAR 0x1A 81 #define MAX77620_ALARM2_DATE 0x1B 82 83 #define MAX77620_RTC_START_YEAR 2000 84 #define MAX77620_RTC_I2C_ADDR 0x68 85 86 #define LOCK(_sc) sx_xlock(&(_sc)->lock) 87 #define UNLOCK(_sc) sx_xunlock(&(_sc)->lock) 88 #define LOCK_INIT(_sc) sx_init(&(_sc)->lock, "max77620_rtc") 89 #define LOCK_DESTROY(_sc) sx_destroy(&(_sc)->lock); 90 91 struct max77620_rtc_softc { 92 device_t dev; 93 struct sx lock; 94 int bus_addr; 95 }; 96 97 char max77620_rtc_compat[] = "maxim,max77620_rtc"; 98 99 /* 100 * Raw register access function. 101 */ 102 static int 103 max77620_rtc_read(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t *val) 104 { 105 uint8_t addr; 106 int rv; 107 struct iic_msg msgs[2] = { 108 {0, IIC_M_WR, 1, &addr}, 109 {0, IIC_M_RD, 1, val}, 110 }; 111 112 msgs[0].slave = sc->bus_addr; 113 msgs[1].slave = sc->bus_addr; 114 addr = reg; 115 116 rv = iicbus_transfer(sc->dev, msgs, 2); 117 if (rv != 0) { 118 device_printf(sc->dev, 119 "Error when reading reg 0x%02X, rv: %d\n", reg, rv); 120 return (EIO); 121 } 122 123 return (0); 124 } 125 126 static int 127 max77620_rtc_read_buf(struct max77620_rtc_softc *sc, uint8_t reg, 128 uint8_t *buf, size_t size) 129 { 130 uint8_t addr; 131 int rv; 132 struct iic_msg msgs[2] = { 133 {0, IIC_M_WR, 1, &addr}, 134 {0, IIC_M_RD, size, buf}, 135 }; 136 137 msgs[0].slave = sc->bus_addr; 138 msgs[1].slave = sc->bus_addr; 139 addr = reg; 140 141 rv = iicbus_transfer(sc->dev, msgs, 2); 142 if (rv != 0) { 143 device_printf(sc->dev, 144 "Error when reading reg 0x%02X, rv: %d\n", reg, rv); 145 return (EIO); 146 } 147 148 return (0); 149 } 150 151 static int 152 max77620_rtc_write(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t val) 153 { 154 uint8_t data[2]; 155 int rv; 156 157 struct iic_msg msgs[1] = { 158 {0, IIC_M_WR, 2, data}, 159 }; 160 161 msgs[0].slave = sc->bus_addr; 162 data[0] = reg; 163 data[1] = val; 164 165 rv = iicbus_transfer(sc->dev, msgs, 1); 166 if (rv != 0) { 167 device_printf(sc->dev, 168 "Error when writing reg 0x%02X, rv: %d\n", reg, rv); 169 return (EIO); 170 } 171 return (0); 172 } 173 174 static int 175 max77620_rtc_write_buf(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t *buf, 176 size_t size) 177 { 178 uint8_t data[1]; 179 int rv; 180 struct iic_msg msgs[2] = { 181 {0, IIC_M_WR, 1, data}, 182 {0, IIC_M_WR | IIC_M_NOSTART, size, buf}, 183 }; 184 185 msgs[0].slave = sc->bus_addr; 186 msgs[1].slave = sc->bus_addr; 187 data[0] = reg; 188 189 rv = iicbus_transfer(sc->dev, msgs, 2); 190 if (rv != 0) { 191 device_printf(sc->dev, 192 "Error when writing reg 0x%02X, rv: %d\n", reg, rv); 193 return (EIO); 194 } 195 return (0); 196 } 197 198 static int 199 max77620_rtc_modify(struct max77620_rtc_softc *sc, uint8_t reg, uint8_t clear, 200 uint8_t set) 201 { 202 uint8_t val; 203 int rv; 204 205 rv = max77620_rtc_read(sc, reg, &val); 206 if (rv != 0) 207 return (rv); 208 209 val &= ~clear; 210 val |= set; 211 212 rv = max77620_rtc_write(sc, reg, val); 213 if (rv != 0) 214 return (rv); 215 216 return (0); 217 } 218 219 static int 220 max77620_rtc_update(struct max77620_rtc_softc *sc, bool for_read) 221 { 222 uint8_t reg; 223 int rv; 224 225 reg = for_read ? RTC_UPDATE0_RTC_RBUDR: RTC_UPDATE0_RTC_UDR; 226 rv = max77620_rtc_modify(sc, MAX77620_RTC_UPDATE0, reg, reg); 227 if (rv != 0) 228 return (rv); 229 230 DELAY(16000); 231 return (rv); 232 } 233 234 static int 235 max77620_rtc_gettime(device_t dev, struct timespec *ts) 236 { 237 struct max77620_rtc_softc *sc; 238 struct clocktime ct; 239 uint8_t buf[7]; 240 int rv; 241 242 sc = device_get_softc(dev); 243 244 LOCK(sc); 245 rv = max77620_rtc_update(sc, true); 246 if (rv != 0) { 247 UNLOCK(sc); 248 device_printf(sc->dev, "Failed to strobe RTC data\n"); 249 return (rv); 250 } 251 252 rv = max77620_rtc_read_buf(sc, MAX77620_RTC_SEC, buf, nitems(buf)); 253 UNLOCK(sc); 254 if (rv != 0) { 255 device_printf(sc->dev, "Failed to read RTC data\n"); 256 return (rv); 257 } 258 ct.nsec = 0; 259 ct.sec = bcd2bin(buf[0] & 0x7F); 260 ct.min = bcd2bin(buf[1] & 0x7F); 261 ct.hour = bcd2bin(buf[2] & 0x3F); 262 ct.dow = ffs(buf[3] & 07); 263 ct.mon = bcd2bin(buf[4] & 0x1F); 264 ct.year = bcd2bin(buf[5] & 0x7F) + MAX77620_RTC_START_YEAR; 265 ct.day = bcd2bin(buf[6] & 0x3F); 266 267 return (clock_ct_to_ts(&ct, ts)); 268 } 269 270 static int 271 max77620_rtc_settime(device_t dev, struct timespec *ts) 272 { 273 struct max77620_rtc_softc *sc; 274 struct clocktime ct; 275 uint8_t buf[7]; 276 int rv; 277 278 sc = device_get_softc(dev); 279 clock_ts_to_ct(ts, &ct); 280 281 if (ct.year < MAX77620_RTC_START_YEAR) 282 return (EINVAL); 283 284 buf[0] = bin2bcd(ct.sec); 285 buf[1] = bin2bcd(ct.min); 286 buf[2] = bin2bcd(ct.hour); 287 buf[3] = 1 << ct.dow; 288 buf[4] = bin2bcd(ct.mon); 289 buf[5] = bin2bcd(ct.year - MAX77620_RTC_START_YEAR); 290 buf[6] = bin2bcd(ct.day); 291 292 LOCK(sc); 293 rv = max77620_rtc_write_buf(sc, MAX77620_RTC_SEC, buf, nitems(buf)); 294 if (rv != 0) { 295 UNLOCK(sc); 296 device_printf(sc->dev, "Failed to write RTC data\n"); 297 return (rv); 298 } 299 rv = max77620_rtc_update(sc, false); 300 UNLOCK(sc); 301 if (rv != 0) { 302 device_printf(sc->dev, "Failed to update RTC data\n"); 303 return (rv); 304 } 305 306 return (0); 307 } 308 309 static int 310 max77620_rtc_probe(device_t dev) 311 { 312 const char *compat; 313 314 /* 315 * TODO: 316 * ofw_bus_is_compatible() should use compat string from devinfo cache 317 * maximum size of OFW property should be defined in public header 318 */ 319 if ((compat = ofw_bus_get_compat(dev)) == NULL) 320 return (ENXIO); 321 if (strncasecmp(compat, max77620_rtc_compat, 255) != 0) 322 return (ENXIO); 323 324 device_set_desc(dev, "MAX77620 RTC"); 325 return (BUS_PROBE_DEFAULT); 326 } 327 328 static int 329 max77620_rtc_attach(device_t dev) 330 { 331 struct max77620_rtc_softc *sc; 332 uint8_t reg; 333 int rv; 334 335 sc = device_get_softc(dev); 336 sc->dev = dev; 337 sc->bus_addr = iicbus_get_addr(dev); 338 339 LOCK_INIT(sc); 340 341 reg = RTC_CONTROL_MODE_24 | RTC_CONTROL_BCD_EN; 342 rv = max77620_rtc_modify(sc, MAX77620_RTC_CONTROLM, reg, reg); 343 if (rv != 0) { 344 device_printf(sc->dev, "Failed to configure RTC\n"); 345 goto fail; 346 } 347 348 rv = max77620_rtc_modify(sc, MAX77620_RTC_CONTROL, reg, reg); 349 if (rv != 0) { 350 device_printf(sc->dev, "Failed to configure RTC\n"); 351 goto fail; 352 } 353 rv = max77620_rtc_update(sc, false); 354 if (rv != 0) { 355 device_printf(sc->dev, "Failed to update RTC data\n"); 356 return (rv); 357 } 358 359 clock_register(sc->dev, 1000000); 360 361 return (bus_generic_attach(dev)); 362 363 fail: 364 LOCK_DESTROY(sc); 365 return (rv); 366 } 367 368 static int 369 max77620_rtc_detach(device_t dev) 370 { 371 struct max77620_softc *sc; 372 373 sc = device_get_softc(dev); 374 LOCK_DESTROY(sc); 375 376 return (bus_generic_detach(dev)); 377 } 378 379 /* 380 * The secondary address of MAX77620 (RTC function) is not in DT, 381 * add it manualy as subdevice 382 */ 383 int 384 max77620_rtc_create(struct max77620_softc *sc, phandle_t node) 385 { 386 device_t parent, child; 387 int rv; 388 389 parent = device_get_parent(sc->dev); 390 391 child = BUS_ADD_CHILD(parent, 0, NULL, -1); 392 if (child == NULL) { 393 device_printf(sc->dev, "Cannot create MAX77620 RTC device.\n"); 394 return (ENXIO); 395 } 396 397 rv = OFW_IICBUS_SET_DEVINFO(parent, child, -1, "rtc@68", 398 max77620_rtc_compat, MAX77620_RTC_I2C_ADDR << 1); 399 if (rv != 0) { 400 device_printf(sc->dev, "Cannot setup MAX77620 RTC device.\n"); 401 return (ENXIO); 402 } 403 404 return (0); 405 } 406 407 static device_method_t max77620_rtc_methods[] = { 408 /* Device interface */ 409 DEVMETHOD(device_probe, max77620_rtc_probe), 410 DEVMETHOD(device_attach, max77620_rtc_attach), 411 DEVMETHOD(device_detach, max77620_rtc_detach), 412 413 /* RTC interface */ 414 DEVMETHOD(clock_gettime, max77620_rtc_gettime), 415 DEVMETHOD(clock_settime, max77620_rtc_settime), 416 417 DEVMETHOD_END 418 }; 419 420 static DEFINE_CLASS_0(rtc, max77620_rtc_driver, max77620_rtc_methods, 421 sizeof(struct max77620_rtc_softc)); 422 EARLY_DRIVER_MODULE(max77620rtc_, iicbus, max77620_rtc_driver, NULL, NULL, 74); 423