1 /*- 2 * Copyright (c) 2021 Beckhoff Automation GmbH & Co. KG 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 */ 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/bus.h> 30 #include <sys/malloc.h> 31 32 #include <dev/iicbus/iicbus.h> 33 #include <dev/iicbus/iiconf.h> 34 35 #include <linux/device.h> 36 #include <linux/i2c.h> 37 #include <linux/i2c-algo-bit.h> 38 #include <linux/list.h> 39 #include <linux/pci.h> 40 41 #include "iicbus_if.h" 42 #include "iicbb_if.h" 43 #include "lkpi_iic_if.h" 44 45 static int lkpi_i2c_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs); 46 static int lkpi_i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr); 47 48 struct lkpi_iic_softc { 49 device_t iicbus; 50 struct i2c_adapter *adapter; 51 }; 52 53 static struct sx lkpi_sx_i2c; 54 55 static void 56 lkpi_sysinit_i2c(void *arg __unused) 57 { 58 59 sx_init(&lkpi_sx_i2c, "lkpi-i2c"); 60 } 61 62 static void 63 lkpi_sysuninit_i2c(void *arg __unused) 64 { 65 66 sx_destroy(&lkpi_sx_i2c); 67 } 68 69 SYSINIT(lkpi_i2c, SI_SUB_DRIVERS, SI_ORDER_ANY, 70 lkpi_sysinit_i2c, NULL); 71 SYSUNINIT(lkpi_i2c, SI_SUB_DRIVERS, SI_ORDER_ANY, 72 lkpi_sysuninit_i2c, NULL); 73 74 static int 75 lkpi_iic_probe(device_t dev) 76 { 77 78 device_set_desc(dev, "LinuxKPI I2C"); 79 return (BUS_PROBE_NOWILDCARD); 80 } 81 82 static int 83 lkpi_iic_attach(device_t dev) 84 { 85 struct lkpi_iic_softc *sc; 86 87 sc = device_get_softc(dev); 88 sc->iicbus = device_add_child(dev, "iicbus", -1); 89 if (sc->iicbus == NULL) { 90 device_printf(dev, "Couldn't add iicbus child, aborting\n"); 91 return (ENXIO); 92 } 93 bus_generic_attach(dev); 94 return (0); 95 } 96 97 static int 98 lkpi_iic_detach(device_t dev) 99 { 100 struct lkpi_iic_softc *sc; 101 102 sc = device_get_softc(dev); 103 if (sc->iicbus) 104 device_delete_child(dev, sc->iicbus); 105 return (0); 106 } 107 108 static int 109 lkpi_iic_add_adapter(device_t dev, struct i2c_adapter *adapter) 110 { 111 struct lkpi_iic_softc *sc; 112 113 sc = device_get_softc(dev); 114 sc->adapter = adapter; 115 116 return (0); 117 } 118 119 static struct i2c_adapter * 120 lkpi_iic_get_adapter(device_t dev) 121 { 122 struct lkpi_iic_softc *sc; 123 124 sc = device_get_softc(dev); 125 return (sc->adapter); 126 } 127 128 static device_method_t lkpi_iic_methods[] = { 129 /* device interface */ 130 DEVMETHOD(device_probe, lkpi_iic_probe), 131 DEVMETHOD(device_attach, lkpi_iic_attach), 132 DEVMETHOD(device_detach, lkpi_iic_detach), 133 DEVMETHOD(device_suspend, bus_generic_suspend), 134 DEVMETHOD(device_resume, bus_generic_resume), 135 136 /* iicbus interface */ 137 DEVMETHOD(iicbus_transfer, lkpi_i2c_transfer), 138 DEVMETHOD(iicbus_reset, lkpi_i2c_reset), 139 DEVMETHOD(iicbus_callback, iicbus_null_callback), 140 141 /* lkpi_iic interface */ 142 DEVMETHOD(lkpi_iic_add_adapter, lkpi_iic_add_adapter), 143 DEVMETHOD(lkpi_iic_get_adapter, lkpi_iic_get_adapter), 144 145 DEVMETHOD_END 146 }; 147 148 driver_t lkpi_iic_driver = { 149 "lkpi_iic", 150 lkpi_iic_methods, 151 sizeof(struct lkpi_iic_softc), 152 }; 153 154 DRIVER_MODULE(lkpi_iic, drmn, lkpi_iic_driver, 0, 0); 155 DRIVER_MODULE(lkpi_iic, drm, lkpi_iic_driver, 0, 0); 156 DRIVER_MODULE(iicbus, lkpi_iic, iicbus_driver, 0, 0); 157 MODULE_DEPEND(linuxkpi, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER); 158 159 static int 160 lkpi_i2c_reset(device_t dev, u_char speed, u_char addr, u_char *oldaddr) 161 { 162 163 /* That doesn't seems to be supported in linux */ 164 return (0); 165 } 166 167 static int i2c_check_for_quirks(struct i2c_adapter *adapter, 168 struct iic_msg *msgs, uint32_t nmsgs) 169 { 170 const struct i2c_adapter_quirks *quirks; 171 device_t dev; 172 int i, max_nmsgs; 173 bool check_len; 174 175 dev = adapter->dev.parent->bsddev; 176 quirks = adapter->quirks; 177 if (quirks == NULL) 178 return (0); 179 180 check_len = true; 181 max_nmsgs = quirks->max_num_msgs; 182 183 if (quirks->flags & I2C_AQ_COMB) { 184 max_nmsgs = 2; 185 186 if (nmsgs == 2) { 187 if (quirks->flags & I2C_AQ_COMB_WRITE_FIRST && 188 msgs[0].flags & IIC_M_RD) { 189 device_printf(dev, 190 "Error: " 191 "first combined message must be write\n"); 192 return (EOPNOTSUPP); 193 } 194 if (quirks->flags & I2C_AQ_COMB_READ_SECOND && 195 !(msgs[1].flags & IIC_M_RD)) { 196 device_printf(dev, 197 "Error: " 198 "second combined message must be read\n"); 199 return (EOPNOTSUPP); 200 } 201 202 if (quirks->flags & I2C_AQ_COMB_SAME_ADDR && 203 msgs[0].slave != msgs[1].slave) { 204 device_printf(dev, 205 "Error: " 206 "combined message must be use the same " 207 "address\n"); 208 return (EOPNOTSUPP); 209 } 210 211 if (quirks->max_comb_1st_msg_len && 212 msgs[0].len > quirks->max_comb_1st_msg_len) { 213 device_printf(dev, 214 "Error: " 215 "message too long: %hu > %hu max\n", 216 msgs[0].len, 217 quirks->max_comb_1st_msg_len); 218 return (EOPNOTSUPP); 219 } 220 if (quirks->max_comb_2nd_msg_len && 221 msgs[1].len > quirks->max_comb_2nd_msg_len) { 222 device_printf(dev, 223 "Error: " 224 "message too long: %hu > %hu max\n", 225 msgs[1].len, 226 quirks->max_comb_2nd_msg_len); 227 return (EOPNOTSUPP); 228 } 229 230 check_len = false; 231 } 232 } 233 234 if (max_nmsgs && nmsgs > max_nmsgs) { 235 device_printf(dev, 236 "Error: too many messages: %d > %d max\n", 237 nmsgs, max_nmsgs); 238 return (EOPNOTSUPP); 239 } 240 241 for (i = 0; i < nmsgs; i++) { 242 if (msgs[i].flags & IIC_M_RD) { 243 if (check_len && quirks->max_read_len && 244 msgs[i].len > quirks->max_read_len) { 245 device_printf(dev, 246 "Error: " 247 "message %d too long: %hu > %hu max\n", 248 i, msgs[i].len, quirks->max_read_len); 249 return (EOPNOTSUPP); 250 } 251 if (quirks->flags & I2C_AQ_NO_ZERO_LEN_READ && 252 msgs[i].len == 0) { 253 device_printf(dev, 254 "Error: message %d of length 0\n", i); 255 return (EOPNOTSUPP); 256 } 257 } else { 258 if (check_len && quirks->max_write_len && 259 msgs[i].len > quirks->max_write_len) { 260 device_printf(dev, 261 "Message %d too long: %hu > %hu max\n", 262 i, msgs[i].len, quirks->max_write_len); 263 return (EOPNOTSUPP); 264 } 265 if (quirks->flags & I2C_AQ_NO_ZERO_LEN_WRITE && 266 msgs[i].len == 0) { 267 device_printf(dev, 268 "Error: message %d of length 0\n", i); 269 return (EOPNOTSUPP); 270 } 271 } 272 } 273 274 return (0); 275 } 276 277 static int 278 lkpi_i2c_transfer(device_t dev, struct iic_msg *msgs, uint32_t nmsgs) 279 { 280 struct lkpi_iic_softc *sc; 281 struct i2c_msg *linux_msgs; 282 int i, ret = 0; 283 284 sc = device_get_softc(dev); 285 if (sc->adapter == NULL) 286 return (ENXIO); 287 ret = i2c_check_for_quirks(sc->adapter, msgs, nmsgs); 288 if (ret != 0) 289 return (ret); 290 linux_set_current(curthread); 291 292 linux_msgs = malloc(sizeof(struct i2c_msg) * nmsgs, 293 M_DEVBUF, M_WAITOK | M_ZERO); 294 295 for (i = 0; i < nmsgs; i++) { 296 linux_msgs[i].addr = msgs[i].slave >> 1; 297 linux_msgs[i].len = msgs[i].len; 298 linux_msgs[i].buf = msgs[i].buf; 299 if (msgs[i].flags & IIC_M_RD) { 300 linux_msgs[i].flags |= I2C_M_RD; 301 for (int j = 0; j < msgs[i].len; j++) 302 msgs[i].buf[j] = 0; 303 } 304 if (msgs[i].flags & IIC_M_NOSTART) 305 linux_msgs[i].flags |= I2C_M_NOSTART; 306 } 307 ret = i2c_transfer(sc->adapter, linux_msgs, nmsgs); 308 free(linux_msgs, M_DEVBUF); 309 310 if (ret < 0) 311 return (-ret); 312 return (0); 313 } 314 315 int 316 lkpi_i2c_add_adapter(struct i2c_adapter *adapter) 317 { 318 device_t lkpi_iic; 319 int error; 320 321 if (adapter->name[0] == '\0') 322 return (-EINVAL); 323 if (bootverbose) 324 device_printf(adapter->dev.parent->bsddev, 325 "Adding i2c adapter %s\n", adapter->name); 326 sx_xlock(&lkpi_sx_i2c); 327 lkpi_iic = device_add_child(adapter->dev.parent->bsddev, "lkpi_iic", -1); 328 if (lkpi_iic == NULL) { 329 device_printf(adapter->dev.parent->bsddev, "Couldn't add lkpi_iic\n"); 330 sx_xunlock(&lkpi_sx_i2c); 331 return (ENXIO); 332 } 333 334 bus_topo_lock(); 335 error = bus_generic_attach(adapter->dev.parent->bsddev); 336 bus_topo_unlock(); 337 if (error) { 338 device_printf(adapter->dev.parent->bsddev, 339 "failed to attach child: error %d\n", error); 340 sx_xunlock(&lkpi_sx_i2c); 341 return (ENXIO); 342 } 343 LKPI_IIC_ADD_ADAPTER(lkpi_iic, adapter); 344 sx_xunlock(&lkpi_sx_i2c); 345 return (0); 346 } 347 348 int 349 lkpi_i2c_del_adapter(struct i2c_adapter *adapter) 350 { 351 device_t child; 352 int unit, rv; 353 354 if (adapter == NULL) 355 return (-EINVAL); 356 if (bootverbose) 357 device_printf(adapter->dev.parent->bsddev, 358 "Removing i2c adapter %s\n", adapter->name); 359 sx_xlock(&lkpi_sx_i2c); 360 unit = 0; 361 while ((child = device_find_child(adapter->dev.parent->bsddev, "lkpi_iic", unit++)) != NULL) { 362 363 if (adapter == LKPI_IIC_GET_ADAPTER(child)) { 364 bus_topo_lock(); 365 device_delete_child(adapter->dev.parent->bsddev, child); 366 bus_topo_unlock(); 367 rv = 0; 368 goto out; 369 } 370 } 371 372 unit = 0; 373 while ((child = device_find_child(adapter->dev.parent->bsddev, "lkpi_iicbb", unit++)) != NULL) { 374 375 if (adapter == LKPI_IIC_GET_ADAPTER(child)) { 376 bus_topo_lock(); 377 device_delete_child(adapter->dev.parent->bsddev, child); 378 bus_topo_unlock(); 379 rv = 0; 380 goto out; 381 } 382 } 383 rv = -EINVAL; 384 out: 385 sx_xunlock(&lkpi_sx_i2c); 386 return (rv); 387 } 388