0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/errno.h>
0014 #include <linux/module.h>
0015 #include <linux/types.h>
0016 #include <linux/slab.h>
0017 #include <linux/usb.h>
0018 #include <linux/i2c.h>
0019
0020 #define DRIVER_NAME "i2c-diolan-u2c"
0021
0022 #define USB_VENDOR_ID_DIOLAN 0x0abf
0023 #define USB_DEVICE_ID_DIOLAN_U2C 0x3370
0024
0025
0026
0027 #define CMD_I2C_READ 0x01
0028 #define CMD_I2C_WRITE 0x02
0029 #define CMD_I2C_SCAN 0x03
0030 #define CMD_I2C_RELEASE_SDA 0x04
0031 #define CMD_I2C_RELEASE_SCL 0x05
0032 #define CMD_I2C_DROP_SDA 0x06
0033 #define CMD_I2C_DROP_SCL 0x07
0034 #define CMD_I2C_READ_SDA 0x08
0035 #define CMD_I2C_READ_SCL 0x09
0036 #define CMD_GET_FW_VERSION 0x0a
0037 #define CMD_GET_SERIAL 0x0b
0038 #define CMD_I2C_START 0x0c
0039 #define CMD_I2C_STOP 0x0d
0040 #define CMD_I2C_REPEATED_START 0x0e
0041 #define CMD_I2C_PUT_BYTE 0x0f
0042 #define CMD_I2C_GET_BYTE 0x10
0043 #define CMD_I2C_PUT_ACK 0x11
0044 #define CMD_I2C_GET_ACK 0x12
0045 #define CMD_I2C_PUT_BYTE_ACK 0x13
0046 #define CMD_I2C_GET_BYTE_ACK 0x14
0047 #define CMD_I2C_SET_SPEED 0x1b
0048 #define CMD_I2C_GET_SPEED 0x1c
0049 #define CMD_I2C_SET_CLK_SYNC 0x24
0050 #define CMD_I2C_GET_CLK_SYNC 0x25
0051 #define CMD_I2C_SET_CLK_SYNC_TO 0x26
0052 #define CMD_I2C_GET_CLK_SYNC_TO 0x27
0053
0054 #define RESP_OK 0x00
0055 #define RESP_FAILED 0x01
0056 #define RESP_BAD_MEMADDR 0x04
0057 #define RESP_DATA_ERR 0x05
0058 #define RESP_NOT_IMPLEMENTED 0x06
0059 #define RESP_NACK 0x07
0060 #define RESP_TIMEOUT 0x09
0061
0062 #define U2C_I2C_SPEED_FAST 0
0063 #define U2C_I2C_SPEED_STD 1
0064 #define U2C_I2C_SPEED_2KHZ 242
0065 #define U2C_I2C_SPEED(f) ((DIV_ROUND_UP(1000000, (f)) - 10) / 2 + 1)
0066
0067 #define U2C_I2C_FREQ(s) (1000000 / (2 * (s - 1) + 10))
0068
0069 #define DIOLAN_USB_TIMEOUT 100
0070 #define DIOLAN_SYNC_TIMEOUT 20
0071
0072 #define DIOLAN_OUTBUF_LEN 128
0073 #define DIOLAN_FLUSH_LEN (DIOLAN_OUTBUF_LEN - 4)
0074 #define DIOLAN_INBUF_LEN 256
0075
0076
0077 struct i2c_diolan_u2c {
0078 u8 obuffer[DIOLAN_OUTBUF_LEN];
0079 u8 ibuffer[DIOLAN_INBUF_LEN];
0080 int ep_in, ep_out;
0081 struct usb_device *usb_dev;
0082 struct usb_interface *interface;
0083 struct i2c_adapter adapter;
0084 int olen;
0085 int ocount;
0086 };
0087
0088 static uint frequency = I2C_MAX_STANDARD_MODE_FREQ;
0089
0090 module_param(frequency, uint, S_IRUGO | S_IWUSR);
0091 MODULE_PARM_DESC(frequency, "I2C clock frequency in hertz");
0092
0093
0094
0095
0096 static int diolan_usb_transfer(struct i2c_diolan_u2c *dev)
0097 {
0098 int ret = 0;
0099 int actual;
0100 int i;
0101
0102 if (!dev->olen || !dev->ocount)
0103 return -EINVAL;
0104
0105 ret = usb_bulk_msg(dev->usb_dev,
0106 usb_sndbulkpipe(dev->usb_dev, dev->ep_out),
0107 dev->obuffer, dev->olen, &actual,
0108 DIOLAN_USB_TIMEOUT);
0109 if (!ret) {
0110 for (i = 0; i < dev->ocount; i++) {
0111 int tmpret;
0112
0113 tmpret = usb_bulk_msg(dev->usb_dev,
0114 usb_rcvbulkpipe(dev->usb_dev,
0115 dev->ep_in),
0116 dev->ibuffer,
0117 sizeof(dev->ibuffer), &actual,
0118 DIOLAN_USB_TIMEOUT);
0119
0120
0121
0122
0123
0124 if (ret < 0)
0125 continue;
0126 ret = tmpret;
0127 if (ret == 0 && actual > 0) {
0128 switch (dev->ibuffer[actual - 1]) {
0129 case RESP_NACK:
0130
0131
0132
0133
0134
0135 ret = i == 1 ? -ENXIO : -EIO;
0136 break;
0137 case RESP_TIMEOUT:
0138 ret = -ETIMEDOUT;
0139 break;
0140 case RESP_OK:
0141
0142 ret = actual - 1;
0143 break;
0144 default:
0145 ret = -EIO;
0146 break;
0147 }
0148 }
0149 }
0150 }
0151 dev->olen = 0;
0152 dev->ocount = 0;
0153 return ret;
0154 }
0155
0156 static int diolan_write_cmd(struct i2c_diolan_u2c *dev, bool flush)
0157 {
0158 if (flush || dev->olen >= DIOLAN_FLUSH_LEN)
0159 return diolan_usb_transfer(dev);
0160 return 0;
0161 }
0162
0163
0164 static int diolan_usb_cmd(struct i2c_diolan_u2c *dev, u8 command, bool flush)
0165 {
0166 dev->obuffer[dev->olen++] = command;
0167 dev->ocount++;
0168 return diolan_write_cmd(dev, flush);
0169 }
0170
0171
0172 static int diolan_usb_cmd_data(struct i2c_diolan_u2c *dev, u8 command, u8 data,
0173 bool flush)
0174 {
0175 dev->obuffer[dev->olen++] = command;
0176 dev->obuffer[dev->olen++] = data;
0177 dev->ocount++;
0178 return diolan_write_cmd(dev, flush);
0179 }
0180
0181
0182 static int diolan_usb_cmd_data2(struct i2c_diolan_u2c *dev, u8 command, u8 d1,
0183 u8 d2, bool flush)
0184 {
0185 dev->obuffer[dev->olen++] = command;
0186 dev->obuffer[dev->olen++] = d1;
0187 dev->obuffer[dev->olen++] = d2;
0188 dev->ocount++;
0189 return diolan_write_cmd(dev, flush);
0190 }
0191
0192
0193
0194
0195
0196
0197
0198 static void diolan_flush_input(struct i2c_diolan_u2c *dev)
0199 {
0200 int i;
0201
0202 for (i = 0; i < 10; i++) {
0203 int actual = 0;
0204 int ret;
0205
0206 ret = usb_bulk_msg(dev->usb_dev,
0207 usb_rcvbulkpipe(dev->usb_dev, dev->ep_in),
0208 dev->ibuffer, sizeof(dev->ibuffer), &actual,
0209 DIOLAN_USB_TIMEOUT);
0210 if (ret < 0 || actual == 0)
0211 break;
0212 }
0213 if (i == 10)
0214 dev_err(&dev->interface->dev, "Failed to flush input buffer\n");
0215 }
0216
0217 static int diolan_i2c_start(struct i2c_diolan_u2c *dev)
0218 {
0219 return diolan_usb_cmd(dev, CMD_I2C_START, false);
0220 }
0221
0222 static int diolan_i2c_repeated_start(struct i2c_diolan_u2c *dev)
0223 {
0224 return diolan_usb_cmd(dev, CMD_I2C_REPEATED_START, false);
0225 }
0226
0227 static int diolan_i2c_stop(struct i2c_diolan_u2c *dev)
0228 {
0229 return diolan_usb_cmd(dev, CMD_I2C_STOP, true);
0230 }
0231
0232 static int diolan_i2c_get_byte_ack(struct i2c_diolan_u2c *dev, bool ack,
0233 u8 *byte)
0234 {
0235 int ret;
0236
0237 ret = diolan_usb_cmd_data(dev, CMD_I2C_GET_BYTE_ACK, ack, true);
0238 if (ret > 0)
0239 *byte = dev->ibuffer[0];
0240 else if (ret == 0)
0241 ret = -EIO;
0242
0243 return ret;
0244 }
0245
0246 static int diolan_i2c_put_byte_ack(struct i2c_diolan_u2c *dev, u8 byte)
0247 {
0248 return diolan_usb_cmd_data(dev, CMD_I2C_PUT_BYTE_ACK, byte, false);
0249 }
0250
0251 static int diolan_set_speed(struct i2c_diolan_u2c *dev, u8 speed)
0252 {
0253 return diolan_usb_cmd_data(dev, CMD_I2C_SET_SPEED, speed, true);
0254 }
0255
0256
0257 static int diolan_set_clock_synch(struct i2c_diolan_u2c *dev, bool enable)
0258 {
0259 return diolan_usb_cmd_data(dev, CMD_I2C_SET_CLK_SYNC, enable, true);
0260 }
0261
0262
0263 static int diolan_set_clock_synch_timeout(struct i2c_diolan_u2c *dev, int ms)
0264 {
0265 int to_val = ms * 10;
0266
0267 return diolan_usb_cmd_data2(dev, CMD_I2C_SET_CLK_SYNC_TO,
0268 to_val & 0xff, (to_val >> 8) & 0xff, true);
0269 }
0270
0271 static void diolan_fw_version(struct i2c_diolan_u2c *dev)
0272 {
0273 int ret;
0274
0275 ret = diolan_usb_cmd(dev, CMD_GET_FW_VERSION, true);
0276 if (ret >= 2)
0277 dev_info(&dev->interface->dev,
0278 "Diolan U2C firmware version %u.%u\n",
0279 (unsigned int)dev->ibuffer[0],
0280 (unsigned int)dev->ibuffer[1]);
0281 }
0282
0283 static void diolan_get_serial(struct i2c_diolan_u2c *dev)
0284 {
0285 int ret;
0286 u32 serial;
0287
0288 ret = diolan_usb_cmd(dev, CMD_GET_SERIAL, true);
0289 if (ret >= 4) {
0290 serial = le32_to_cpu(*(u32 *)dev->ibuffer);
0291 dev_info(&dev->interface->dev,
0292 "Diolan U2C serial number %u\n", serial);
0293 }
0294 }
0295
0296 static int diolan_init(struct i2c_diolan_u2c *dev)
0297 {
0298 int speed, ret;
0299
0300 if (frequency >= 2 * I2C_MAX_STANDARD_MODE_FREQ) {
0301 speed = U2C_I2C_SPEED_FAST;
0302 frequency = I2C_MAX_FAST_MODE_FREQ;
0303 } else if (frequency >= I2C_MAX_STANDARD_MODE_FREQ || frequency == 0) {
0304 speed = U2C_I2C_SPEED_STD;
0305 frequency = I2C_MAX_STANDARD_MODE_FREQ;
0306 } else {
0307 speed = U2C_I2C_SPEED(frequency);
0308 if (speed > U2C_I2C_SPEED_2KHZ)
0309 speed = U2C_I2C_SPEED_2KHZ;
0310 frequency = U2C_I2C_FREQ(speed);
0311 }
0312
0313 dev_info(&dev->interface->dev,
0314 "Diolan U2C at USB bus %03d address %03d speed %d Hz\n",
0315 dev->usb_dev->bus->busnum, dev->usb_dev->devnum, frequency);
0316
0317 diolan_flush_input(dev);
0318 diolan_fw_version(dev);
0319 diolan_get_serial(dev);
0320
0321
0322 ret = diolan_set_speed(dev, speed);
0323 if (ret < 0)
0324 return ret;
0325
0326
0327 ret = diolan_set_clock_synch(dev, speed != U2C_I2C_SPEED_FAST);
0328 if (ret < 0)
0329 return ret;
0330
0331 if (speed != U2C_I2C_SPEED_FAST)
0332 ret = diolan_set_clock_synch_timeout(dev, DIOLAN_SYNC_TIMEOUT);
0333
0334 return ret;
0335 }
0336
0337
0338
0339 static int diolan_usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
0340 int num)
0341 {
0342 struct i2c_diolan_u2c *dev = i2c_get_adapdata(adapter);
0343 struct i2c_msg *pmsg;
0344 int i, j;
0345 int ret, sret;
0346
0347 ret = diolan_i2c_start(dev);
0348 if (ret < 0)
0349 return ret;
0350
0351 for (i = 0; i < num; i++) {
0352 pmsg = &msgs[i];
0353 if (i) {
0354 ret = diolan_i2c_repeated_start(dev);
0355 if (ret < 0)
0356 goto abort;
0357 }
0358 ret = diolan_i2c_put_byte_ack(dev,
0359 i2c_8bit_addr_from_msg(pmsg));
0360 if (ret < 0)
0361 goto abort;
0362 if (pmsg->flags & I2C_M_RD) {
0363 for (j = 0; j < pmsg->len; j++) {
0364 u8 byte;
0365 bool ack = j < pmsg->len - 1;
0366
0367
0368
0369
0370
0371 if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN))
0372 ack = true;
0373
0374 ret = diolan_i2c_get_byte_ack(dev, ack, &byte);
0375 if (ret < 0)
0376 goto abort;
0377
0378
0379
0380 if (j == 0 && (pmsg->flags & I2C_M_RECV_LEN)) {
0381 if (byte == 0
0382 || byte > I2C_SMBUS_BLOCK_MAX) {
0383 ret = -EPROTO;
0384 goto abort;
0385 }
0386 pmsg->len += byte;
0387 }
0388 pmsg->buf[j] = byte;
0389 }
0390 } else {
0391 for (j = 0; j < pmsg->len; j++) {
0392 ret = diolan_i2c_put_byte_ack(dev,
0393 pmsg->buf[j]);
0394 if (ret < 0)
0395 goto abort;
0396 }
0397 }
0398 }
0399 ret = num;
0400 abort:
0401 sret = diolan_i2c_stop(dev);
0402 if (sret < 0 && ret >= 0)
0403 ret = sret;
0404 return ret;
0405 }
0406
0407
0408
0409
0410 static u32 diolan_usb_func(struct i2c_adapter *a)
0411 {
0412 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
0413 I2C_FUNC_SMBUS_READ_BLOCK_DATA | I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
0414 }
0415
0416 static const struct i2c_algorithm diolan_usb_algorithm = {
0417 .master_xfer = diolan_usb_xfer,
0418 .functionality = diolan_usb_func,
0419 };
0420
0421
0422
0423 static const struct usb_device_id diolan_u2c_table[] = {
0424 { USB_DEVICE(USB_VENDOR_ID_DIOLAN, USB_DEVICE_ID_DIOLAN_U2C) },
0425 { }
0426 };
0427
0428 MODULE_DEVICE_TABLE(usb, diolan_u2c_table);
0429
0430 static void diolan_u2c_free(struct i2c_diolan_u2c *dev)
0431 {
0432 usb_put_dev(dev->usb_dev);
0433 kfree(dev);
0434 }
0435
0436 static int diolan_u2c_probe(struct usb_interface *interface,
0437 const struct usb_device_id *id)
0438 {
0439 struct usb_host_interface *hostif = interface->cur_altsetting;
0440 struct i2c_diolan_u2c *dev;
0441 int ret;
0442
0443 if (hostif->desc.bInterfaceNumber != 0
0444 || hostif->desc.bNumEndpoints < 2)
0445 return -ENODEV;
0446
0447
0448 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0449 if (dev == NULL) {
0450 ret = -ENOMEM;
0451 goto error;
0452 }
0453 dev->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
0454 dev->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
0455
0456 dev->usb_dev = usb_get_dev(interface_to_usbdev(interface));
0457 dev->interface = interface;
0458
0459
0460 usb_set_intfdata(interface, dev);
0461
0462
0463 dev->adapter.owner = THIS_MODULE;
0464 dev->adapter.class = I2C_CLASS_HWMON;
0465 dev->adapter.algo = &diolan_usb_algorithm;
0466 i2c_set_adapdata(&dev->adapter, dev);
0467 snprintf(dev->adapter.name, sizeof(dev->adapter.name),
0468 DRIVER_NAME " at bus %03d device %03d",
0469 dev->usb_dev->bus->busnum, dev->usb_dev->devnum);
0470
0471 dev->adapter.dev.parent = &dev->interface->dev;
0472
0473
0474 ret = diolan_init(dev);
0475 if (ret < 0) {
0476 dev_err(&interface->dev, "failed to initialize adapter\n");
0477 goto error_free;
0478 }
0479
0480
0481 ret = i2c_add_adapter(&dev->adapter);
0482 if (ret < 0)
0483 goto error_free;
0484
0485 dev_dbg(&interface->dev, "connected " DRIVER_NAME "\n");
0486
0487 return 0;
0488
0489 error_free:
0490 usb_set_intfdata(interface, NULL);
0491 diolan_u2c_free(dev);
0492 error:
0493 return ret;
0494 }
0495
0496 static void diolan_u2c_disconnect(struct usb_interface *interface)
0497 {
0498 struct i2c_diolan_u2c *dev = usb_get_intfdata(interface);
0499
0500 i2c_del_adapter(&dev->adapter);
0501 usb_set_intfdata(interface, NULL);
0502 diolan_u2c_free(dev);
0503
0504 dev_dbg(&interface->dev, "disconnected\n");
0505 }
0506
0507 static struct usb_driver diolan_u2c_driver = {
0508 .name = DRIVER_NAME,
0509 .probe = diolan_u2c_probe,
0510 .disconnect = diolan_u2c_disconnect,
0511 .id_table = diolan_u2c_table,
0512 };
0513
0514 module_usb_driver(diolan_u2c_driver);
0515
0516 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
0517 MODULE_DESCRIPTION(DRIVER_NAME " driver");
0518 MODULE_LICENSE("GPL");