1 /* 2 * Nano River Technologies viperboard i2c master driver 3 * 4 * (C) 2012 by Lemonage GmbH 5 * Author: Lars Poeschel <poeschel@lemonage.de> 6 * All rights reserved. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 * 13 */ 14 15 #include <linux/kernel.h> 16 #include <linux/errno.h> 17 #include <linux/module.h> 18 #include <linux/slab.h> 19 #include <linux/types.h> 20 #include <linux/mutex.h> 21 #include <linux/platform_device.h> 22 23 #include <linux/usb.h> 24 #include <linux/i2c.h> 25 26 #include <linux/mfd/viperboard.h> 27 28 struct vprbrd_i2c { 29 struct i2c_adapter i2c; 30 u8 bus_freq_param; 31 }; 32 33 /* i2c bus frequency module parameter */ 34 static u8 i2c_bus_param; 35 static unsigned int i2c_bus_freq = 100; 36 module_param(i2c_bus_freq, int, 0); 37 MODULE_PARM_DESC(i2c_bus_freq, 38 "i2c bus frequency in khz (default is 100) valid values: 10, 100, 200, 400, 1000, 3000, 6000"); 39 40 static int vprbrd_i2c_status(struct i2c_adapter *i2c, 41 struct vprbrd_i2c_status *status, bool prev_error) 42 { 43 u16 bytes_xfer; 44 int ret; 45 struct vprbrd *vb = (struct vprbrd *)i2c->algo_data; 46 47 /* check for protocol error */ 48 bytes_xfer = sizeof(struct vprbrd_i2c_status); 49 50 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0), 51 VPRBRD_USB_REQUEST_I2C, VPRBRD_USB_TYPE_IN, 0x0000, 0x0000, 52 status, bytes_xfer, VPRBRD_USB_TIMEOUT_MS); 53 54 if (ret != bytes_xfer) 55 prev_error = true; 56 57 if (prev_error) { 58 dev_err(&i2c->dev, "failure in usb communication\n"); 59 return -EREMOTEIO; 60 } 61 62 dev_dbg(&i2c->dev, " status = %d\n", status->status); 63 if (status->status != 0x00) { 64 dev_err(&i2c->dev, "failure: i2c protocol error\n"); 65 return -EPROTO; 66 } 67 return 0; 68 } 69 70 static int vprbrd_i2c_receive(struct usb_device *usb_dev, 71 struct vprbrd_i2c_read_msg *rmsg, int bytes_xfer) 72 { 73 int ret, bytes_actual; 74 int error = 0; 75 76 /* send the read request */ 77 ret = usb_bulk_msg(usb_dev, 78 usb_sndbulkpipe(usb_dev, VPRBRD_EP_OUT), rmsg, 79 sizeof(struct vprbrd_i2c_read_hdr), &bytes_actual, 80 VPRBRD_USB_TIMEOUT_MS); 81 82 if ((ret < 0) 83 || (bytes_actual != sizeof(struct vprbrd_i2c_read_hdr))) { 84 dev_err(&usb_dev->dev, "failure transmitting usb\n"); 85 error = -EREMOTEIO; 86 } 87 88 /* read the actual data */ 89 ret = usb_bulk_msg(usb_dev, 90 usb_rcvbulkpipe(usb_dev, VPRBRD_EP_IN), rmsg, 91 bytes_xfer, &bytes_actual, VPRBRD_USB_TIMEOUT_MS); 92 93 if ((ret < 0) || (bytes_xfer != bytes_actual)) { 94 dev_err(&usb_dev->dev, "failure receiving usb\n"); 95 error = -EREMOTEIO; 96 } 97 return error; 98 } 99 100 static int vprbrd_i2c_addr(struct usb_device *usb_dev, 101 struct vprbrd_i2c_addr_msg *amsg) 102 { 103 int ret, bytes_actual; 104 105 ret = usb_bulk_msg(usb_dev, 106 usb_sndbulkpipe(usb_dev, VPRBRD_EP_OUT), amsg, 107 sizeof(struct vprbrd_i2c_addr_msg), &bytes_actual, 108 VPRBRD_USB_TIMEOUT_MS); 109 110 if ((ret < 0) || 111 (sizeof(struct vprbrd_i2c_addr_msg) != bytes_actual)) { 112 dev_err(&usb_dev->dev, "failure transmitting usb\n"); 113 return -EREMOTEIO; 114 } 115 return 0; 116 } 117 118 static int vprbrd_i2c_read(struct vprbrd *vb, struct i2c_msg *msg) 119 { 120 int ret; 121 u16 remain_len, len1, len2, start = 0x0000; 122 struct vprbrd_i2c_read_msg *rmsg = 123 (struct vprbrd_i2c_read_msg *)vb->buf; 124 125 remain_len = msg->len; 126 rmsg->header.cmd = VPRBRD_I2C_CMD_READ; 127 while (remain_len > 0) { 128 rmsg->header.addr = cpu_to_le16(start + 0x4000); 129 if (remain_len <= 255) { 130 len1 = remain_len; 131 len2 = 0x00; 132 rmsg->header.len0 = remain_len; 133 rmsg->header.len1 = 0x00; 134 rmsg->header.len2 = 0x00; 135 rmsg->header.len3 = 0x00; 136 rmsg->header.len4 = 0x00; 137 rmsg->header.len5 = 0x00; 138 remain_len = 0; 139 } else if (remain_len <= 510) { 140 len1 = remain_len; 141 len2 = 0x00; 142 rmsg->header.len0 = remain_len - 255; 143 rmsg->header.len1 = 0xff; 144 rmsg->header.len2 = 0x00; 145 rmsg->header.len3 = 0x00; 146 rmsg->header.len4 = 0x00; 147 rmsg->header.len5 = 0x00; 148 remain_len = 0; 149 } else if (remain_len <= 512) { 150 len1 = remain_len; 151 len2 = 0x00; 152 rmsg->header.len0 = remain_len - 510; 153 rmsg->header.len1 = 0xff; 154 rmsg->header.len2 = 0xff; 155 rmsg->header.len3 = 0x00; 156 rmsg->header.len4 = 0x00; 157 rmsg->header.len5 = 0x00; 158 remain_len = 0; 159 } else if (remain_len <= 767) { 160 len1 = 512; 161 len2 = remain_len - 512; 162 rmsg->header.len0 = 0x02; 163 rmsg->header.len1 = 0xff; 164 rmsg->header.len2 = 0xff; 165 rmsg->header.len3 = remain_len - 512; 166 rmsg->header.len4 = 0x00; 167 rmsg->header.len5 = 0x00; 168 remain_len = 0; 169 } else if (remain_len <= 1022) { 170 len1 = 512; 171 len2 = remain_len - 512; 172 rmsg->header.len0 = 0x02; 173 rmsg->header.len1 = 0xff; 174 rmsg->header.len2 = 0xff; 175 rmsg->header.len3 = remain_len - 767; 176 rmsg->header.len4 = 0xff; 177 rmsg->header.len5 = 0x00; 178 remain_len = 0; 179 } else if (remain_len <= 1024) { 180 len1 = 512; 181 len2 = remain_len - 512; 182 rmsg->header.len0 = 0x02; 183 rmsg->header.len1 = 0xff; 184 rmsg->header.len2 = 0xff; 185 rmsg->header.len3 = remain_len - 1022; 186 rmsg->header.len4 = 0xff; 187 rmsg->header.len5 = 0xff; 188 remain_len = 0; 189 } else { 190 len1 = 512; 191 len2 = 512; 192 rmsg->header.len0 = 0x02; 193 rmsg->header.len1 = 0xff; 194 rmsg->header.len2 = 0xff; 195 rmsg->header.len3 = 0x02; 196 rmsg->header.len4 = 0xff; 197 rmsg->header.len5 = 0xff; 198 remain_len -= 1024; 199 start += 1024; 200 } 201 rmsg->header.tf1 = cpu_to_le16(len1); 202 rmsg->header.tf2 = cpu_to_le16(len2); 203 204 /* first read transfer */ 205 ret = vprbrd_i2c_receive(vb->usb_dev, rmsg, len1); 206 if (ret < 0) 207 return ret; 208 /* copy the received data */ 209 memcpy(msg->buf + start, rmsg, len1); 210 211 /* second read transfer if neccessary */ 212 if (len2 > 0) { 213 ret = vprbrd_i2c_receive(vb->usb_dev, rmsg, len2); 214 if (ret < 0) 215 return ret; 216 /* copy the received data */ 217 memcpy(msg->buf + start + 512, rmsg, len2); 218 } 219 } 220 return 0; 221 } 222 223 static int vprbrd_i2c_write(struct vprbrd *vb, struct i2c_msg *msg) 224 { 225 int ret, bytes_actual; 226 u16 remain_len, bytes_xfer, 227 start = 0x0000; 228 struct vprbrd_i2c_write_msg *wmsg = 229 (struct vprbrd_i2c_write_msg *)vb->buf; 230 231 remain_len = msg->len; 232 wmsg->header.cmd = VPRBRD_I2C_CMD_WRITE; 233 wmsg->header.last = 0x00; 234 wmsg->header.chan = 0x00; 235 wmsg->header.spi = 0x0000; 236 while (remain_len > 0) { 237 wmsg->header.addr = cpu_to_le16(start + 0x4000); 238 if (remain_len > 503) { 239 wmsg->header.len1 = 0xff; 240 wmsg->header.len2 = 0xf8; 241 remain_len -= 503; 242 bytes_xfer = 503 + sizeof(struct vprbrd_i2c_write_hdr); 243 start += 503; 244 } else if (remain_len > 255) { 245 wmsg->header.len1 = 0xff; 246 wmsg->header.len2 = (remain_len - 255); 247 bytes_xfer = remain_len + 248 sizeof(struct vprbrd_i2c_write_hdr); 249 remain_len = 0; 250 } else { 251 wmsg->header.len1 = remain_len; 252 wmsg->header.len2 = 0x00; 253 bytes_xfer = remain_len + 254 sizeof(struct vprbrd_i2c_write_hdr); 255 remain_len = 0; 256 } 257 memcpy(wmsg->data, msg->buf + start, 258 bytes_xfer - sizeof(struct vprbrd_i2c_write_hdr)); 259 260 ret = usb_bulk_msg(vb->usb_dev, 261 usb_sndbulkpipe(vb->usb_dev, 262 VPRBRD_EP_OUT), wmsg, 263 bytes_xfer, &bytes_actual, VPRBRD_USB_TIMEOUT_MS); 264 if ((ret < 0) || (bytes_xfer != bytes_actual)) 265 return -EREMOTEIO; 266 } 267 return 0; 268 } 269 270 static int vprbrd_i2c_xfer(struct i2c_adapter *i2c, struct i2c_msg *msgs, 271 int num) 272 { 273 struct i2c_msg *pmsg; 274 int i, ret, 275 error = 0; 276 struct vprbrd *vb = (struct vprbrd *)i2c->algo_data; 277 struct vprbrd_i2c_addr_msg *amsg = 278 (struct vprbrd_i2c_addr_msg *)vb->buf; 279 struct vprbrd_i2c_status *smsg = (struct vprbrd_i2c_status *)vb->buf; 280 281 dev_dbg(&i2c->dev, "master xfer %d messages:\n", num); 282 283 for (i = 0 ; i < num ; i++) { 284 pmsg = &msgs[i]; 285 286 dev_dbg(&i2c->dev, 287 " %d: %s (flags %d) %d bytes to 0x%02x\n", 288 i, pmsg->flags & I2C_M_RD ? "read" : "write", 289 pmsg->flags, pmsg->len, pmsg->addr); 290 291 /* msgs longer than 2048 bytes are not supported by adapter */ 292 if (pmsg->len > 2048) 293 return -EINVAL; 294 295 mutex_lock(&vb->lock); 296 /* directly send the message */ 297 if (pmsg->flags & I2C_M_RD) { 298 /* read data */ 299 amsg->cmd = VPRBRD_I2C_CMD_ADDR; 300 amsg->unknown2 = 0x00; 301 amsg->unknown3 = 0x00; 302 amsg->addr = pmsg->addr; 303 amsg->unknown1 = 0x01; 304 amsg->len = cpu_to_le16(pmsg->len); 305 /* send the addr and len, we're interested to board */ 306 ret = vprbrd_i2c_addr(vb->usb_dev, amsg); 307 if (ret < 0) 308 error = ret; 309 310 ret = vprbrd_i2c_read(vb, pmsg); 311 if (ret < 0) 312 error = ret; 313 314 ret = vprbrd_i2c_status(i2c, smsg, error); 315 if (ret < 0) 316 error = ret; 317 /* in case of protocol error, return the error */ 318 if (error < 0) 319 goto error; 320 } else { 321 /* write data */ 322 ret = vprbrd_i2c_write(vb, pmsg); 323 324 amsg->cmd = VPRBRD_I2C_CMD_ADDR; 325 amsg->unknown2 = 0x00; 326 amsg->unknown3 = 0x00; 327 amsg->addr = pmsg->addr; 328 amsg->unknown1 = 0x00; 329 amsg->len = cpu_to_le16(pmsg->len); 330 /* send the addr, the data goes to to board */ 331 ret = vprbrd_i2c_addr(vb->usb_dev, amsg); 332 if (ret < 0) 333 error = ret; 334 335 ret = vprbrd_i2c_status(i2c, smsg, error); 336 if (ret < 0) 337 error = ret; 338 339 if (error < 0) 340 goto error; 341 } 342 mutex_unlock(&vb->lock); 343 } 344 return 0; 345 error: 346 mutex_unlock(&vb->lock); 347 return error; 348 } 349 350 static u32 vprbrd_i2c_func(struct i2c_adapter *i2c) 351 { 352 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 353 } 354 355 /* This is the actual algorithm we define */ 356 static const struct i2c_algorithm vprbrd_algorithm = { 357 .master_xfer = vprbrd_i2c_xfer, 358 .functionality = vprbrd_i2c_func, 359 }; 360 361 static int vprbrd_i2c_probe(struct platform_device *pdev) 362 { 363 struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent); 364 struct vprbrd_i2c *vb_i2c; 365 int ret; 366 int pipe; 367 368 vb_i2c = devm_kzalloc(&pdev->dev, sizeof(*vb_i2c), GFP_KERNEL); 369 if (vb_i2c == NULL) 370 return -ENOMEM; 371 372 /* setup i2c adapter description */ 373 vb_i2c->i2c.owner = THIS_MODULE; 374 vb_i2c->i2c.class = I2C_CLASS_HWMON; 375 vb_i2c->i2c.algo = &vprbrd_algorithm; 376 vb_i2c->i2c.algo_data = vb; 377 /* save the param in usb capabable memory */ 378 vb_i2c->bus_freq_param = i2c_bus_param; 379 380 snprintf(vb_i2c->i2c.name, sizeof(vb_i2c->i2c.name), 381 "viperboard at bus %03d device %03d", 382 vb->usb_dev->bus->busnum, vb->usb_dev->devnum); 383 384 /* setting the bus frequency */ 385 if ((i2c_bus_param <= VPRBRD_I2C_FREQ_10KHZ) 386 && (i2c_bus_param >= VPRBRD_I2C_FREQ_6MHZ)) { 387 pipe = usb_sndctrlpipe(vb->usb_dev, 0); 388 ret = usb_control_msg(vb->usb_dev, pipe, 389 VPRBRD_USB_REQUEST_I2C_FREQ, VPRBRD_USB_TYPE_OUT, 390 0x0000, 0x0000, &vb_i2c->bus_freq_param, 1, 391 VPRBRD_USB_TIMEOUT_MS); 392 if (ret != 1) { 393 dev_err(&pdev->dev, 394 "failure setting i2c_bus_freq to %d\n", i2c_bus_freq); 395 return -EIO; 396 } 397 } else { 398 dev_err(&pdev->dev, 399 "invalid i2c_bus_freq setting:%d\n", i2c_bus_freq); 400 return -EIO; 401 } 402 403 vb_i2c->i2c.dev.parent = &pdev->dev; 404 405 /* attach to i2c layer */ 406 i2c_add_adapter(&vb_i2c->i2c); 407 408 platform_set_drvdata(pdev, vb_i2c); 409 410 return 0; 411 } 412 413 static int vprbrd_i2c_remove(struct platform_device *pdev) 414 { 415 struct vprbrd_i2c *vb_i2c = platform_get_drvdata(pdev); 416 417 i2c_del_adapter(&vb_i2c->i2c); 418 419 return 0; 420 } 421 422 static struct platform_driver vprbrd_i2c_driver = { 423 .driver.name = "viperboard-i2c", 424 .driver.owner = THIS_MODULE, 425 .probe = vprbrd_i2c_probe, 426 .remove = vprbrd_i2c_remove, 427 }; 428 429 static int __init vprbrd_i2c_init(void) 430 { 431 switch (i2c_bus_freq) { 432 case 6000: 433 i2c_bus_param = VPRBRD_I2C_FREQ_6MHZ; 434 break; 435 case 3000: 436 i2c_bus_param = VPRBRD_I2C_FREQ_3MHZ; 437 break; 438 case 1000: 439 i2c_bus_param = VPRBRD_I2C_FREQ_1MHZ; 440 break; 441 case 400: 442 i2c_bus_param = VPRBRD_I2C_FREQ_400KHZ; 443 break; 444 case 200: 445 i2c_bus_param = VPRBRD_I2C_FREQ_200KHZ; 446 break; 447 case 100: 448 i2c_bus_param = VPRBRD_I2C_FREQ_100KHZ; 449 break; 450 case 10: 451 i2c_bus_param = VPRBRD_I2C_FREQ_10KHZ; 452 break; 453 default: 454 pr_warn("invalid i2c_bus_freq (%d)\n", i2c_bus_freq); 455 i2c_bus_param = VPRBRD_I2C_FREQ_100KHZ; 456 } 457 458 return platform_driver_register(&vprbrd_i2c_driver); 459 } 460 subsys_initcall(vprbrd_i2c_init); 461 462 static void __exit vprbrd_i2c_exit(void) 463 { 464 platform_driver_unregister(&vprbrd_i2c_driver); 465 } 466 module_exit(vprbrd_i2c_exit); 467 468 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>"); 469 MODULE_DESCRIPTION("I2C master driver for Nano River Techs Viperboard"); 470 MODULE_LICENSE("GPL"); 471 MODULE_ALIAS("platform:viperboard-i2c"); 472