1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2011 5 * Ben Gray <ben.r.gray@gmail.com>. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * Texas Instruments TWL4030/TWL5030/TWL60x0/TPS659x0 Power Management and 35 * Audio CODEC devices. 36 * 37 * This code is based on the Linux TWL multifunctional device driver, which is 38 * copyright (C) 2005-2006 Texas Instruments, Inc. 39 * 40 * These chips are typically used as support ICs for the OMAP range of embedded 41 * ARM processes/SOC from Texas Instruments. They are typically used to control 42 * on board voltages, however some variants have other features like audio 43 * codecs, USB OTG transceivers, RTC, PWM, etc. 44 * 45 * This driver acts as a bus for more specific companion devices. 46 * 47 */ 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/kernel.h> 52 #include <sys/lock.h> 53 #include <sys/module.h> 54 #include <sys/bus.h> 55 #include <sys/resource.h> 56 #include <sys/rman.h> 57 #include <sys/sysctl.h> 58 #include <sys/mutex.h> 59 #include <sys/malloc.h> 60 61 #include <machine/bus.h> 62 #include <machine/resource.h> 63 #include <machine/intr.h> 64 65 #include <dev/iicbus/iicbus.h> 66 #include <dev/iicbus/iiconf.h> 67 68 #include <dev/ofw/openfirm.h> 69 #include <dev/ofw/ofw_bus.h> 70 #include <dev/ofw/ofw_bus_subr.h> 71 72 #include "arm/ti/twl/twl.h" 73 74 /* TWL device IDs */ 75 #define TWL_DEVICE_UNKNOWN 0xffff 76 #define TWL_DEVICE_4030 0x4030 77 #define TWL_DEVICE_6025 0x6025 78 #define TWL_DEVICE_6030 0x6030 79 80 /* Each TWL device typically has more than one I2C address */ 81 #define TWL_MAX_SUBADDRS 4 82 83 /* The maxium number of bytes that can be written in one call */ 84 #define TWL_MAX_IIC_DATA_SIZE 63 85 86 /* The TWL devices typically use 4 I2C address for the different internal 87 * register sets, plus one SmartReflex I2C address. 88 */ 89 #define TWL_CHIP_ID0 0x48 90 #define TWL_CHIP_ID1 0x49 91 #define TWL_CHIP_ID2 0x4A 92 #define TWL_CHIP_ID3 0x4B 93 94 #define TWL_SMARTREFLEX_CHIP_ID 0x12 95 96 #define TWL_INVALID_CHIP_ID 0xff 97 98 struct twl_softc { 99 device_t sc_dev; 100 struct mtx sc_mtx; 101 unsigned int sc_type; 102 103 uint8_t sc_subaddr_map[TWL_MAX_SUBADDRS]; 104 105 struct intr_config_hook sc_scan_hook; 106 107 device_t sc_vreg; 108 device_t sc_clks; 109 }; 110 111 /** 112 * Macros for driver mutex locking 113 */ 114 #define TWL_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 115 #define TWL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 116 #define TWL_LOCK_INIT(_sc) \ 117 mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->sc_dev), \ 118 "twl", MTX_DEF) 119 #define TWL_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); 120 #define TWL_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); 121 #define TWL_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); 122 123 124 /** 125 * twl_is_4030 - returns true if the device is TWL4030 126 * twl_is_6025 - returns true if the device is TWL6025 127 * twl_is_6030 - returns true if the device is TWL6030 128 * @sc: device soft context 129 * 130 * Returns a non-zero value if the device matches. 131 * 132 * RETURNS: 133 * Returns a non-zero value if the device matches, otherwise zero. 134 */ 135 int 136 twl_is_4030(device_t dev) 137 { 138 struct twl_softc *sc = device_get_softc(dev); 139 return (sc->sc_type == TWL_DEVICE_4030); 140 } 141 142 int 143 twl_is_6025(device_t dev) 144 { 145 struct twl_softc *sc = device_get_softc(dev); 146 return (sc->sc_type == TWL_DEVICE_6025); 147 } 148 149 int 150 twl_is_6030(device_t dev) 151 { 152 struct twl_softc *sc = device_get_softc(dev); 153 return (sc->sc_type == TWL_DEVICE_6030); 154 } 155 156 157 /** 158 * twl_read - read one or more registers from the TWL device 159 * @sc: device soft context 160 * @nsub: the sub-module to read from 161 * @reg: the register offset within the module to read 162 * @buf: buffer to store the bytes in 163 * @cnt: the number of bytes to read 164 * 165 * Reads one or more registers and stores the result in the suppled buffer. 166 * 167 * RETURNS: 168 * Zero on success or an error code on failure. 169 */ 170 int 171 twl_read(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt) 172 { 173 struct twl_softc *sc; 174 struct iic_msg msg[2]; 175 uint8_t addr; 176 int rc; 177 178 sc = device_get_softc(dev); 179 180 TWL_LOCK(sc); 181 addr = sc->sc_subaddr_map[nsub]; 182 TWL_UNLOCK(sc); 183 184 if (addr == TWL_INVALID_CHIP_ID) 185 return (EIO); 186 187 188 /* Set the address to read from */ 189 msg[0].slave = addr; 190 msg[0].flags = IIC_M_WR | IIC_M_NOSTOP; 191 msg[0].len = 1; 192 msg[0].buf = ® 193 /* Read the data back */ 194 msg[1].slave = addr; 195 msg[1].flags = IIC_M_RD; 196 msg[1].len = cnt; 197 msg[1].buf = buf; 198 199 rc = iicbus_transfer(dev, msg, 2); 200 if (rc != 0) { 201 device_printf(dev, "iicbus read failed (adr:0x%02x, reg:0x%02x)\n", 202 addr, reg); 203 return (EIO); 204 } 205 206 return (0); 207 } 208 209 /** 210 * twl_write - writes one or more registers to the TWL device 211 * @sc: device soft context 212 * @nsub: the sub-module to read from 213 * @reg: the register offset within the module to read 214 * @buf: data to write 215 * @cnt: the number of bytes to write 216 * 217 * Writes one or more registers. 218 * 219 * RETURNS: 220 * Zero on success or a negative error code on failure. 221 */ 222 int 223 twl_write(device_t dev, uint8_t nsub, uint8_t reg, uint8_t *buf, uint16_t cnt) 224 { 225 struct twl_softc *sc; 226 struct iic_msg msg; 227 uint8_t addr; 228 uint8_t tmp_buf[TWL_MAX_IIC_DATA_SIZE + 1]; 229 int rc; 230 231 if (cnt > TWL_MAX_IIC_DATA_SIZE) 232 return (ENOMEM); 233 234 /* Set the register address as the first byte */ 235 tmp_buf[0] = reg; 236 memcpy(&tmp_buf[1], buf, cnt); 237 238 sc = device_get_softc(dev); 239 240 TWL_LOCK(sc); 241 addr = sc->sc_subaddr_map[nsub]; 242 TWL_UNLOCK(sc); 243 244 if (addr == TWL_INVALID_CHIP_ID) 245 return (EIO); 246 247 248 /* Setup the transfer and execute it */ 249 msg.slave = addr; 250 msg.flags = IIC_M_WR; 251 msg.len = cnt + 1; 252 msg.buf = tmp_buf; 253 254 rc = iicbus_transfer(dev, &msg, 1); 255 if (rc != 0) { 256 device_printf(sc->sc_dev, "iicbus write failed (adr:0x%02x, reg:0x%02x)\n", 257 addr, reg); 258 return (EIO); 259 } 260 261 return (0); 262 } 263 264 /** 265 * twl_test_present - checks if a device with given address is present 266 * @sc: device soft context 267 * @addr: the address of the device to scan for 268 * 269 * Sends just the address byte and checks for an ACK. If no ACK then device 270 * is assumed to not be present. 271 * 272 * RETURNS: 273 * EIO if device is not present, otherwise 0 is returned. 274 */ 275 static int 276 twl_test_present(struct twl_softc *sc, uint8_t addr) 277 { 278 struct iic_msg msg; 279 uint8_t tmp; 280 281 /* Set the address to read from */ 282 msg.slave = addr; 283 msg.flags = IIC_M_RD; 284 msg.len = 1; 285 msg.buf = &tmp; 286 287 if (iicbus_transfer(sc->sc_dev, &msg, 1) != 0) 288 return (EIO); 289 290 return (0); 291 } 292 293 /** 294 * twl_scan - scans the i2c bus for sub modules 295 * @dev: the twl device 296 * 297 * TWL devices don't just have one i2c slave address, rather they have up to 298 * 5 other addresses, each is for separate modules within the device. This 299 * function scans the bus for 4 possible sub-devices and stores the info 300 * internally. 301 * 302 */ 303 static void 304 twl_scan(void *dev) 305 { 306 struct twl_softc *sc; 307 unsigned i; 308 uint8_t devs[TWL_MAX_SUBADDRS]; 309 uint8_t base = TWL_CHIP_ID0; 310 311 sc = device_get_softc((device_t)dev); 312 313 memset(devs, TWL_INVALID_CHIP_ID, TWL_MAX_SUBADDRS); 314 315 /* Try each of the addresses (0x48, 0x49, 0x4a & 0x4b) to determine which 316 * sub modules we have. 317 */ 318 for (i = 0; i < TWL_MAX_SUBADDRS; i++) { 319 if (twl_test_present(sc, (base + i)) == 0) { 320 devs[i] = (base + i); 321 device_printf(sc->sc_dev, "Found (sub)device at 0x%02x\n", (base + i)); 322 } 323 } 324 325 TWL_LOCK(sc); 326 memcpy(sc->sc_subaddr_map, devs, TWL_MAX_SUBADDRS); 327 TWL_UNLOCK(sc); 328 329 /* Finished with the interrupt hook */ 330 config_intrhook_disestablish(&sc->sc_scan_hook); 331 } 332 333 /** 334 * twl_probe - 335 * @dev: the twl device 336 * 337 * Scans the FDT for a match for the device, possible compatible device 338 * strings are; "ti,twl6030", "ti,twl6025", "ti,twl4030". 339 * 340 * The FDT compat string also determines the type of device (it is currently 341 * not possible to dynamically determine the device type). 342 * 343 */ 344 static int 345 twl_probe(device_t dev) 346 { 347 phandle_t node; 348 const char *compat; 349 int len, l; 350 struct twl_softc *sc; 351 352 if ((compat = ofw_bus_get_compat(dev)) == NULL) 353 return (ENXIO); 354 355 if ((node = ofw_bus_get_node(dev)) == 0) 356 return (ENXIO); 357 358 /* Get total 'compatible' prop len */ 359 if ((len = OF_getproplen(node, "compatible")) <= 0) 360 return (ENXIO); 361 362 sc = device_get_softc(dev); 363 sc->sc_dev = dev; 364 sc->sc_type = TWL_DEVICE_UNKNOWN; 365 366 while (len > 0) { 367 if (strncasecmp(compat, "ti,twl6030", 10) == 0) 368 sc->sc_type = TWL_DEVICE_6030; 369 else if (strncasecmp(compat, "ti,twl6025", 10) == 0) 370 sc->sc_type = TWL_DEVICE_6025; 371 else if (strncasecmp(compat, "ti,twl4030", 10) == 0) 372 sc->sc_type = TWL_DEVICE_4030; 373 374 if (sc->sc_type != TWL_DEVICE_UNKNOWN) 375 break; 376 377 /* Slide to the next sub-string. */ 378 l = strlen(compat) + 1; 379 compat += l; 380 len -= l; 381 } 382 383 switch (sc->sc_type) { 384 case TWL_DEVICE_4030: 385 device_set_desc(dev, "TI TWL4030/TPS659x0 Companion IC"); 386 break; 387 case TWL_DEVICE_6025: 388 device_set_desc(dev, "TI TWL6025 Companion IC"); 389 break; 390 case TWL_DEVICE_6030: 391 device_set_desc(dev, "TI TWL6030 Companion IC"); 392 break; 393 case TWL_DEVICE_UNKNOWN: 394 default: 395 return (ENXIO); 396 } 397 398 return (0); 399 } 400 401 static int 402 twl_attach(device_t dev) 403 { 404 struct twl_softc *sc; 405 406 sc = device_get_softc(dev); 407 sc->sc_dev = dev; 408 409 TWL_LOCK_INIT(sc); 410 411 /* We have to wait until interrupts are enabled. I2C read and write 412 * only works if the interrupts are available. 413 */ 414 sc->sc_scan_hook.ich_func = twl_scan; 415 sc->sc_scan_hook.ich_arg = dev; 416 417 if (config_intrhook_establish(&sc->sc_scan_hook) != 0) 418 return (ENOMEM); 419 420 /* FIXME: should be in DTS file */ 421 if ((sc->sc_vreg = device_add_child(dev, "twl_vreg", -1)) == NULL) 422 device_printf(dev, "could not allocate twl_vreg instance\n"); 423 if ((sc->sc_clks = device_add_child(dev, "twl_clks", -1)) == NULL) 424 device_printf(dev, "could not allocate twl_clks instance\n"); 425 426 return (bus_generic_attach(dev)); 427 } 428 429 static int 430 twl_detach(device_t dev) 431 { 432 struct twl_softc *sc; 433 434 sc = device_get_softc(dev); 435 436 if (sc->sc_vreg) 437 device_delete_child(dev, sc->sc_vreg); 438 if (sc->sc_clks) 439 device_delete_child(dev, sc->sc_clks); 440 441 442 TWL_LOCK_DESTROY(sc); 443 444 return (0); 445 } 446 447 static device_method_t twl_methods[] = { 448 DEVMETHOD(device_probe, twl_probe), 449 DEVMETHOD(device_attach, twl_attach), 450 DEVMETHOD(device_detach, twl_detach), 451 452 {0, 0}, 453 }; 454 455 static driver_t twl_driver = { 456 "twl", 457 twl_methods, 458 sizeof(struct twl_softc), 459 }; 460 static devclass_t twl_devclass; 461 462 DRIVER_MODULE(twl, iicbus, twl_driver, twl_devclass, 0, 0); 463 MODULE_VERSION(twl, 1); 464