1 /* $OpenBSD: rkiic.c,v 1.2 2017/10/08 07:58:23 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,rk3399-i2c")); 113 } 114 115 void 116 rkiic_attach(struct device *parent, struct device *self, void *aux) 117 { 118 struct rkiic_softc *sc = (struct rkiic_softc *)self; 119 struct fdt_attach_args *faa = aux; 120 struct i2cbus_attach_args iba; 121 uint32_t clock_speed, bus_speed; 122 uint32_t div, divl, divh; 123 uint32_t clkdivl, clkdivh; 124 125 if (faa->fa_nreg < 1) { 126 printf(": no registers\n"); 127 return; 128 } 129 130 sc->sc_iot = faa->fa_iot; 131 sc->sc_node = faa->fa_node; 132 133 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 134 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 135 printf(": can't map registers\n"); 136 return; 137 } 138 139 printf("\n"); 140 141 pinctrl_byname(sc->sc_node, "default"); 142 143 clock_enable(sc->sc_node, "i2c"); 144 clock_enable(sc->sc_node, "pclk"); 145 146 clock_speed = clock_get_frequency(sc->sc_node, "i2c"); 147 bus_speed = OF_getpropint(sc->sc_node, "clock-frequency", 100000); 148 149 div = 2; 150 while (clock_speed > div * bus_speed * 8) 151 div++; 152 divl = div / 2; 153 divh = div - divl; 154 clkdivl = (divl - 1) & 0xffff; 155 clkdivh = (divh - 1) & 0xffff; 156 HWRITE4(sc, RKI2C_CLKDIV, clkdivh << 16 | clkdivl); 157 158 sc->sc_ic.ic_cookie = sc; 159 sc->sc_ic.ic_acquire_bus = rkiic_acquire_bus; 160 sc->sc_ic.ic_release_bus = rkiic_release_bus; 161 sc->sc_ic.ic_exec = rkiic_exec; 162 163 /* Configure its children */ 164 memset(&iba, 0, sizeof(iba)); 165 iba.iba_name = "iic"; 166 iba.iba_tag = &sc->sc_ic; 167 iba.iba_bus_scan = rkiic_bus_scan; 168 iba.iba_bus_scan_arg = &sc->sc_node; 169 170 config_found(&sc->sc_dev, &iba, iicbus_print); 171 } 172 173 int 174 rkiic_acquire_bus(void *cookie, int flags) 175 { 176 struct rkiic_softc *sc = cookie; 177 178 HSET4(sc, RKI2C_CON, RKI2C_CON_I2C_EN); 179 return 0; 180 } 181 182 void 183 rkiic_release_bus(void *cookie, int flags) 184 { 185 struct rkiic_softc *sc = cookie; 186 187 HCLR4(sc, RKI2C_CON, RKI2C_CON_I2C_EN); 188 } 189 190 int 191 rkiic_send_start(void *cookie, int flags) 192 { 193 struct rkiic_softc *sc = cookie; 194 int timo; 195 196 HSET4(sc, RKI2C_IPD, RKI2C_IPD_START); 197 HSET4(sc, RKI2C_CON, RKI2C_CON_START); 198 for (timo = 1000; timo > 0; timo--) { 199 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_START) 200 break; 201 delay(10); 202 } 203 HCLR4(sc, RKI2C_CON, RKI2C_CON_START); 204 if (timo == 0) 205 return ETIMEDOUT; 206 return 0; 207 } 208 209 int 210 rkiic_send_stop(void *cookie, int flags) 211 { 212 struct rkiic_softc *sc = cookie; 213 int timo; 214 215 HSET4(sc, RKI2C_IPD, RKI2C_IPD_STOP); 216 HSET4(sc, RKI2C_CON, RKI2C_CON_STOP); 217 for (timo = 1000; timo > 0; timo--) { 218 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_STOP) 219 break; 220 delay(10); 221 } 222 HCLR4(sc, RKI2C_CON, RKI2C_CON_STOP); 223 if (timo == 0) 224 return ETIMEDOUT; 225 return 0; 226 } 227 228 int 229 rkiic_write(struct rkiic_softc *sc, i2c_addr_t addr, const void *cmd, 230 size_t cmdlen, void *buf, size_t buflen) 231 { 232 uint8_t txbuf[32]; 233 int len = 0; 234 int timo, i; 235 236 /* 237 * Lump slave address, command and data into one single buffer 238 * and transfer it in a single operation. 239 */ 240 txbuf[len++] = addr << 1; 241 for (i = 0; i < cmdlen; i++) 242 txbuf[len++] = ((uint8_t *)cmd)[i]; 243 for (i = 0; i < buflen; i++) 244 txbuf[len++] = ((uint8_t *)buf)[i]; 245 246 for (i = 0; i < len; i += 4) { 247 HWRITE4(sc, RKI2C_TXDATA0 + i, 248 *((uint32_t *)&txbuf[i])); 249 } 250 251 /* Start operation. */ 252 HWRITE4(sc, RKI2C_MTXCNT, len); 253 254 /* Wait for completion. */ 255 for (timo = 1000; timo > 0; timo--) { 256 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_MBTF) 257 break; 258 delay(10); 259 } 260 if (timo == 0) 261 return ETIMEDOUT; 262 263 return 0; 264 } 265 266 int 267 rkiic_read(struct rkiic_softc *sc, i2c_addr_t addr, const void *cmd, 268 size_t cmdlen, void *buf, size_t buflen) 269 { 270 uint32_t mrxraddr, rxdata; 271 int timo, i; 272 273 HWRITE4(sc, RKI2C_MRXADDR, (addr << 1) | RKI2C_MRXADDR_ADDLVLD); 274 275 /* Send the command as "register address". */ 276 mrxraddr = 0; 277 for (i = 0; i < cmdlen; i++) { 278 mrxraddr |= ((uint8_t *)cmd)[i] << (i * 8); 279 mrxraddr |= RKI2C_MRXRADDR_SRADDLVLD << i; 280 } 281 HWRITE4(sc, RKI2C_MRXRADDR, mrxraddr); 282 283 /* Indicate that we're done after this operation. */ 284 HSET4(sc, RKI2C_CON, RKI2C_CON_NAK); 285 286 /* Start operation. */ 287 HWRITE4(sc, RKI2C_MRXCNT, buflen); 288 289 /* Wait for completion. */ 290 for (timo = 1000; timo > 0; timo--) { 291 if (HREAD4(sc, RKI2C_IPD) & RKI2C_IPD_MBRF) 292 break; 293 delay(10); 294 } 295 if (timo == 0) 296 return ETIMEDOUT; 297 298 for (i = 0; i < buflen; i++) { 299 if (i % 4 == 0) 300 rxdata = HREAD4(sc, RKI2C_RXDATA0 + i); 301 ((uint8_t *)buf)[i] = rxdata; 302 rxdata >>= 8; 303 } 304 305 return 0; 306 } 307 308 int 309 rkiic_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, const void *cmd, 310 size_t cmdlen, void *buf, size_t buflen, int flags) 311 { 312 struct rkiic_softc *sc = cookie; 313 uint32_t con; 314 int error; 315 316 if (cmdlen > 3 || buflen > 28) 317 return EINVAL; 318 319 /* Clear interrupts. */ 320 HWRITE4(sc, RKI2C_IPD, RKI2C_IPD_ALL); 321 322 /* Configure transfer more. */ 323 con = HREAD4(sc, RKI2C_CON); 324 con &= ~RKI2C_CON_I2C_MODE_MASK; 325 if (I2C_OP_WRITE_P(op)) 326 con |= RKI2C_CON_I2C_MODE_TX; 327 else 328 con |= RKI2C_CON_I2C_MODE_RRX; 329 con &= ~RKI2C_CON_NAK; 330 con |= RKI2C_CON_ACT2NAK; 331 HWRITE4(sc, RKI2C_CON, con); 332 333 error = rkiic_send_start(sc, flags); 334 if (error) 335 return error; 336 337 if (I2C_OP_WRITE_P(op)) 338 error = rkiic_write(sc, addr, cmd, cmdlen, buf, buflen); 339 else 340 error = rkiic_read(sc, addr, cmd, cmdlen, buf, buflen); 341 342 if (I2C_OP_STOP_P(op)) 343 rkiic_send_stop(sc, flags); 344 345 return error; 346 } 347 348 void 349 rkiic_bus_scan(struct device *self, struct i2cbus_attach_args *iba, void *arg) 350 { 351 int iba_node = *(int *)arg; 352 struct i2c_attach_args ia; 353 char name[32]; 354 uint32_t reg[1]; 355 int node; 356 357 for (node = OF_child(iba_node); node; node = OF_peer(node)) { 358 memset(name, 0, sizeof(name)); 359 memset(reg, 0, sizeof(reg)); 360 361 if (OF_getprop(node, "compatible", name, sizeof(name)) == -1) 362 continue; 363 if (name[0] == '\0') 364 continue; 365 366 if (OF_getprop(node, "reg", ®, sizeof(reg)) != sizeof(reg)) 367 continue; 368 369 memset(&ia, 0, sizeof(ia)); 370 ia.ia_tag = iba->iba_tag; 371 ia.ia_addr = bemtoh32(®[0]); 372 ia.ia_name = name; 373 ia.ia_cookie = &node; 374 config_found(self, &ia, iic_print); 375 } 376 } 377