1 /* $OpenBSD: rkiic.c,v 1.3 2018/02/25 20:42:42 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2017 Mark Kettenis <kettenis@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/device.h> 21 22 #include <machine/intr.h> 23 #include <machine/bus.h> 24 #include <machine/fdt.h> 25 26 #define _I2C_PRIVATE 27 #include <dev/i2c/i2cvar.h> 28 29 #include <dev/ofw/openfirm.h> 30 #include <dev/ofw/ofw_clock.h> 31 #include <dev/ofw/ofw_pinctrl.h> 32 #include <dev/ofw/fdt.h> 33 34 /* Registers. */ 35 #define RKI2C_CON 0x0000 36 #define RKI2C_CON_ACT2NAK (1 << 6) 37 #define RKI2C_CON_ACK (0 << 5) 38 #define RKI2C_CON_NAK (1 << 5) 39 #define RKI2C_CON_STOP (1 << 4) 40 #define RKI2C_CON_START (1 << 3) 41 #define RKI2C_CON_I2C_MODE_MASK (3 << 1) 42 #define RKI2C_CON_I2C_MODE_TX (0 << 1) 43 #define RKI2C_CON_I2C_MODE_RRX (1 << 1) 44 #define RKI2C_CON_I2C_MODE_RX (2 << 1) 45 #define RKI2C_CON_I2C_MODE_BROKEN (3 << 1) 46 #define RKI2C_CON_I2C_EN (1 << 0) 47 #define RKI2C_CLKDIV 0x0004 48 #define RKI2C_MRXADDR 0x0008 49 #define RKI2C_MRXADDR_ADDLVLD (1 << 24) 50 #define RKI2C_MRXRADDR 0x000c 51 #define RKI2C_MRXRADDR_SRADDLVLD (1 << 24) 52 #define RKI2C_MTXCNT 0x0010 53 #define RKI2C_MRXCNT 0x0014 54 #define RKI2C_IEN 0x0018 55 #define RKI2C_IEN_START (1 << 4) 56 #define RKI2C_IPD 0x001c 57 #define RKI2C_IPD_STOP (1 << 5) 58 #define RKI2C_IPD_START (1 << 4) 59 #define RKI2C_IPD_MBRF (1 << 3) 60 #define RKI2C_IPD_MBTF (1 << 2) 61 #define RKI2C_IPD_ALL 0xff 62 #define RKI2C_FCNT 0x0020 63 #define RKI2C_SCL_OE_DB 0x0024 64 #define RKI2C_TXDATA0 0x0100 65 #define RKI2C_RXDATA0 0x0200 66 #define RKI2C_ST 0x0220 67 68 #define HREAD4(sc, reg) \ 69 (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) 70 #define HWRITE4(sc, reg, val) \ 71 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 72 #define HSET4(sc, reg, bits) \ 73 HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) 74 #define HCLR4(sc, reg, bits) \ 75 HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) 76 77 struct rkiic_softc { 78 struct device sc_dev; 79 bus_space_tag_t sc_iot; 80 bus_space_handle_t sc_ioh; 81 82 int sc_node; 83 struct i2c_controller sc_ic; 84 }; 85 86 int rkiic_match(struct device *, void *, void *); 87 void rkiic_attach(struct device *, struct device *, void *); 88 89 struct cfattach rkiic_ca = { 90 sizeof (struct rkiic_softc), rkiic_match, rkiic_attach 91 }; 92 93 struct cfdriver rkiic_cd = { 94 NULL, "rkiic", DV_DULL 95 }; 96 97 int rkiic_acquire_bus(void *, int); 98 void rkiic_release_bus(void *, int); 99 int rkiic_send_start(void *, int); 100 int rkiic_send_stop(void *, int); 101 int rkiic_exec(void *, i2c_op_t, i2c_addr_t, const void *, size_t, 102 void *, size_t, int); 103 104 void rkiic_bus_scan(struct device *, struct i2cbus_attach_args *, void *); 105 106 int 107 rkiic_match(struct device *parent, void *match, void *aux) 108 { 109 struct fdt_attach_args *faa = aux; 110 111 return (OF_is_compatible(faa->fa_node, "rockchip,rk3288-i2c") || 112 OF_is_compatible(faa->fa_node, "rockchip,rk3328-i2c") || 113 OF_is_compatible(faa->fa_node, "rockchip,rk3399-i2c")); 114 } 115 116 void 117 rkiic_attach(struct device *parent, struct device *self, void *aux) 118 { 119 struct rkiic_softc *sc = (struct rkiic_softc *)self; 120 struct fdt_attach_args *faa = aux; 121 struct i2cbus_attach_args iba; 122 uint32_t clock_speed, bus_speed; 123 uint32_t div, divl, divh; 124 uint32_t clkdivl, clkdivh; 125 126 if (faa->fa_nreg < 1) { 127 printf(": no registers\n"); 128 return; 129 } 130 131 sc->sc_iot = faa->fa_iot; 132 sc->sc_node = faa->fa_node; 133 134 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 135 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 136 printf(": can't map registers\n"); 137 return; 138 } 139 140 printf("\n"); 141 142 pinctrl_byname(sc->sc_node, "default"); 143 144 clock_enable(sc->sc_node, "i2c"); 145 clock_enable(sc->sc_node, "pclk"); 146 147 clock_speed = clock_get_frequency(sc->sc_node, "i2c"); 148 bus_speed = OF_getpropint(sc->sc_node, "clock-frequency", 100000); 149 150 div = 2; 151 while (clock_speed > div * bus_speed * 8) 152 div++; 153 divl = div / 2; 154 divh = div - divl; 155 clkdivl = (divl - 1) & 0xffff; 156 clkdivh = (divh - 1) & 0xffff; 157 HWRITE4(sc, RKI2C_CLKDIV, clkdivh << 16 | clkdivl); 158 159 sc->sc_ic.ic_cookie = sc; 160 sc->sc_ic.ic_acquire_bus = rkiic_acquire_bus; 161 sc->sc_ic.ic_release_bus = rkiic_release_bus; 162 sc->sc_ic.ic_exec = rkiic_exec; 163 164 /* Configure its children */ 165 memset(&iba, 0, sizeof(iba)); 166 iba.iba_name = "iic"; 167 iba.iba_tag = &sc->sc_ic; 168 iba.iba_bus_scan = rkiic_bus_scan; 169 iba.iba_bus_scan_arg = &sc->sc_node; 170 171 config_found(&sc->sc_dev, &iba, iicbus_print); 172 } 173 174 int 175 rkiic_acquire_bus(void *cookie, int flags) 176 { 177 struct rkiic_softc *sc = cookie; 178 179 HSET4(sc, RKI2C_CON, RKI2C_CON_I2C_EN); 180 return 0; 181 } 182 183 void 184 rkiic_release_bus(void *cookie, int flags) 185 { 186 struct rkiic_softc *sc = cookie; 187 188 HCLR4(sc, RKI2C_CON, RKI2C_CON_I2C_EN); 189 } 190 191 int 192 rkiic_send_start(void *cookie, int flags) 193 { 194 struct rkiic_softc *sc = cookie; 195 int timo; 196 197 HSET4(sc, RKI2C_IPD, RKI2C_IPD_START); 198 HSET4(sc, RKI2C_CON, RKI2C_CON_START); 199 for (timo = 1000; timo > 0; timo--) { 200 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_START) 201 break; 202 delay(10); 203 } 204 HCLR4(sc, RKI2C_CON, RKI2C_CON_START); 205 if (timo == 0) 206 return ETIMEDOUT; 207 return 0; 208 } 209 210 int 211 rkiic_send_stop(void *cookie, int flags) 212 { 213 struct rkiic_softc *sc = cookie; 214 int timo; 215 216 HSET4(sc, RKI2C_IPD, RKI2C_IPD_STOP); 217 HSET4(sc, RKI2C_CON, RKI2C_CON_STOP); 218 for (timo = 1000; timo > 0; timo--) { 219 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_STOP) 220 break; 221 delay(10); 222 } 223 HCLR4(sc, RKI2C_CON, RKI2C_CON_STOP); 224 if (timo == 0) 225 return ETIMEDOUT; 226 return 0; 227 } 228 229 int 230 rkiic_write(struct rkiic_softc *sc, i2c_addr_t addr, const void *cmd, 231 size_t cmdlen, void *buf, size_t buflen) 232 { 233 uint8_t txbuf[32]; 234 int len = 0; 235 int timo, i; 236 237 /* 238 * Lump slave address, command and data into one single buffer 239 * and transfer it in a single operation. 240 */ 241 txbuf[len++] = addr << 1; 242 for (i = 0; i < cmdlen; i++) 243 txbuf[len++] = ((uint8_t *)cmd)[i]; 244 for (i = 0; i < buflen; i++) 245 txbuf[len++] = ((uint8_t *)buf)[i]; 246 247 for (i = 0; i < len; i += 4) { 248 HWRITE4(sc, RKI2C_TXDATA0 + i, 249 *((uint32_t *)&txbuf[i])); 250 } 251 252 /* Start operation. */ 253 HWRITE4(sc, RKI2C_MTXCNT, len); 254 255 /* Wait for completion. */ 256 for (timo = 1000; timo > 0; timo--) { 257 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_MBTF) 258 break; 259 delay(10); 260 } 261 if (timo == 0) 262 return ETIMEDOUT; 263 264 return 0; 265 } 266 267 int 268 rkiic_read(struct rkiic_softc *sc, i2c_addr_t addr, const void *cmd, 269 size_t cmdlen, void *buf, size_t buflen) 270 { 271 uint32_t mrxraddr, rxdata; 272 int timo, i; 273 274 HWRITE4(sc, RKI2C_MRXADDR, (addr << 1) | RKI2C_MRXADDR_ADDLVLD); 275 276 /* Send the command as "register address". */ 277 mrxraddr = 0; 278 for (i = 0; i < cmdlen; i++) { 279 mrxraddr |= ((uint8_t *)cmd)[i] << (i * 8); 280 mrxraddr |= RKI2C_MRXRADDR_SRADDLVLD << i; 281 } 282 HWRITE4(sc, RKI2C_MRXRADDR, mrxraddr); 283 284 /* Indicate that we're done after this operation. */ 285 HSET4(sc, RKI2C_CON, RKI2C_CON_NAK); 286 287 /* Start operation. */ 288 HWRITE4(sc, RKI2C_MRXCNT, buflen); 289 290 /* Wait for completion. */ 291 for (timo = 1000; timo > 0; timo--) { 292 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_MBRF) 293 break; 294 delay(10); 295 } 296 if (timo == 0) 297 return ETIMEDOUT; 298 299 for (i = 0; i < buflen; i++) { 300 if (i % 4 == 0) 301 rxdata = HREAD4(sc, RKI2C_RXDATA0 + i); 302 ((uint8_t *)buf)[i] = rxdata; 303 rxdata >>= 8; 304 } 305 306 return 0; 307 } 308 309 int 310 rkiic_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd, 311 size_t cmdlen, void *buf, size_t buflen, int flags) 312 { 313 struct rkiic_softc *sc = cookie; 314 uint32_t con; 315 int error; 316 317 if (cmdlen > 3 || buflen > 28) 318 return EINVAL; 319 320 /* Clear interrupts. */ 321 HWRITE4(sc, RKI2C_IPD, RKI2C_IPD_ALL); 322 323 /* Configure transfer more. */ 324 con = HREAD4(sc, RKI2C_CON); 325 con &= ~RKI2C_CON_I2C_MODE_MASK; 326 if (I2C_OP_WRITE_P(op)) 327 con |= RKI2C_CON_I2C_MODE_TX; 328 else 329 con |= RKI2C_CON_I2C_MODE_RRX; 330 con &= ~RKI2C_CON_NAK; 331 con |= RKI2C_CON_ACT2NAK; 332 HWRITE4(sc, RKI2C_CON, con); 333 334 error = rkiic_send_start(sc, flags); 335 if (error) 336 return error; 337 338 if (I2C_OP_WRITE_P(op)) 339 error = rkiic_write(sc, addr, cmd, cmdlen, buf, buflen); 340 else 341 error = rkiic_read(sc, addr, cmd, cmdlen, buf, buflen); 342 343 if (I2C_OP_STOP_P(op)) 344 rkiic_send_stop(sc, flags); 345 346 return error; 347 } 348 349 void 350 rkiic_bus_scan(struct device *self, struct i2cbus_attach_args *iba, void *arg) 351 { 352 int iba_node = *(int *)arg; 353 struct i2c_attach_args ia; 354 char name[32]; 355 uint32_t reg[1]; 356 int node; 357 358 for (node = OF_child(iba_node); node; node = OF_peer(node)) { 359 memset(name, 0, sizeof(name)); 360 memset(reg, 0, sizeof(reg)); 361 362 if (OF_getprop(node, "compatible", name, sizeof(name)) == -1) 363 continue; 364 if (name[0] == '\0') 365 continue; 366 367 if (OF_getprop(node, "reg", ®, sizeof(reg)) != sizeof(reg)) 368 continue; 369 370 memset(&ia, 0, sizeof(ia)); 371 ia.ia_tag = iba->iba_tag; 372 ia.ia_addr = bemtoh32(®[0]); 373 ia.ia_name = name; 374 ia.ia_cookie = &node; 375 config_found(self, &ia, iic_print); 376 } 377 } 378