1108 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * hid-ft260.c - FTDI FT260 USB HID to I2C host bridge4 *5 * Copyright (c) 2021, Michael Zaidman <michaelz@xsightlabs.com>6 *7 * Data Sheet:8 * https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT260.pdf9 */10 11#include "hid-ids.h"12#include <linux/hidraw.h>13#include <linux/i2c.h>14#include <linux/module.h>15#include <linux/usb.h>16 17#ifdef DEBUG18static int ft260_debug = 1;19#else20static int ft260_debug;21#endif22module_param_named(debug, ft260_debug, int, 0600);23MODULE_PARM_DESC(debug, "Toggle FT260 debugging messages");24 25#define ft260_dbg(format, arg...) \26 do { \27 if (ft260_debug) \28 pr_info("%s: " format, __func__, ##arg); \29 } while (0)30 31#define FT260_REPORT_MAX_LENGTH (64)32#define FT260_I2C_DATA_REPORT_ID(len) (FT260_I2C_REPORT_MIN + (len - 1) / 4)33 34#define FT260_WAKEUP_NEEDED_AFTER_MS (4800) /* 5s minus 200ms margin */35 36/*37 * The ft260 input report format defines 62 bytes for the data payload, but38 * when requested 62 bytes, the controller returns 60 and 2 in separate input39 * reports. To achieve better performance with the multi-report read data40 * transfers, we set the maximum read payload length to a multiple of 60.41 * With a 100 kHz I2C clock, one 240 bytes read takes about 1/27 second,42 * which is excessive; On the other hand, some higher layer drivers like at2443 * or optoe limit the i2c reads to 128 bytes. To not block other drivers out44 * of I2C for potentially troublesome amounts of time, we select the maximum45 * read payload length to be 180 bytes.46*/47#define FT260_RD_DATA_MAX (180)48#define FT260_WR_DATA_MAX (60)49 50/*51 * Device interface configuration.52 * The FT260 has 2 interfaces that are controlled by DCNF0 and DCNF1 pins.53 * First implementes USB HID to I2C bridge function and54 * second - USB HID to UART bridge function.55 */56enum {57 FT260_MODE_ALL = 0x00,58 FT260_MODE_I2C = 0x01,59 FT260_MODE_UART = 0x02,60 FT260_MODE_BOTH = 0x03,61};62 63/* Control pipe */64enum {65 FT260_GET_RQST_TYPE = 0xA1,66 FT260_GET_REPORT = 0x01,67 FT260_SET_RQST_TYPE = 0x21,68 FT260_SET_REPORT = 0x09,69 FT260_FEATURE = 0x03,70};71 72/* Report IDs / Feature In */73enum {74 FT260_CHIP_VERSION = 0xA0,75 FT260_SYSTEM_SETTINGS = 0xA1,76 FT260_I2C_STATUS = 0xC0,77 FT260_I2C_READ_REQ = 0xC2,78 FT260_I2C_REPORT_MIN = 0xD0,79 FT260_I2C_REPORT_MAX = 0xDE,80 FT260_GPIO = 0xB0,81 FT260_UART_INTERRUPT_STATUS = 0xB1,82 FT260_UART_STATUS = 0xE0,83 FT260_UART_RI_DCD_STATUS = 0xE1,84 FT260_UART_REPORT = 0xF0,85};86 87/* Feature Out */88enum {89 FT260_SET_CLOCK = 0x01,90 FT260_SET_I2C_MODE = 0x02,91 FT260_SET_UART_MODE = 0x03,92 FT260_ENABLE_INTERRUPT = 0x05,93 FT260_SELECT_GPIO2_FUNC = 0x06,94 FT260_ENABLE_UART_DCD_RI = 0x07,95 FT260_SELECT_GPIOA_FUNC = 0x08,96 FT260_SELECT_GPIOG_FUNC = 0x09,97 FT260_SET_INTERRUPT_TRIGGER = 0x0A,98 FT260_SET_SUSPEND_OUT_POLAR = 0x0B,99 FT260_ENABLE_UART_RI_WAKEUP = 0x0C,100 FT260_SET_UART_RI_WAKEUP_CFG = 0x0D,101 FT260_SET_I2C_RESET = 0x20,102 FT260_SET_I2C_CLOCK_SPEED = 0x22,103 FT260_SET_UART_RESET = 0x40,104 FT260_SET_UART_CONFIG = 0x41,105 FT260_SET_UART_BAUD_RATE = 0x42,106 FT260_SET_UART_DATA_BIT = 0x43,107 FT260_SET_UART_PARITY = 0x44,108 FT260_SET_UART_STOP_BIT = 0x45,109 FT260_SET_UART_BREAKING = 0x46,110 FT260_SET_UART_XON_XOFF = 0x49,111};112 113/* Response codes in I2C status report */114enum {115 FT260_I2C_STATUS_SUCCESS = 0x00,116 FT260_I2C_STATUS_CTRL_BUSY = 0x01,117 FT260_I2C_STATUS_ERROR = 0x02,118 FT260_I2C_STATUS_ADDR_NO_ACK = 0x04,119 FT260_I2C_STATUS_DATA_NO_ACK = 0x08,120 FT260_I2C_STATUS_ARBITR_LOST = 0x10,121 FT260_I2C_STATUS_CTRL_IDLE = 0x20,122 FT260_I2C_STATUS_BUS_BUSY = 0x40,123};124 125/* I2C Conditions flags */126enum {127 FT260_FLAG_NONE = 0x00,128 FT260_FLAG_START = 0x02,129 FT260_FLAG_START_REPEATED = 0x03,130 FT260_FLAG_STOP = 0x04,131 FT260_FLAG_START_STOP = 0x06,132 FT260_FLAG_START_STOP_REPEATED = 0x07,133};134 135#define FT260_SET_REQUEST_VALUE(report_id) ((FT260_FEATURE << 8) | report_id)136 137/* Feature In reports */138 139struct ft260_get_chip_version_report {140 u8 report; /* FT260_CHIP_VERSION */141 u8 chip_code[4]; /* FTDI chip identification code */142 u8 reserved[8];143} __packed;144 145struct ft260_get_system_status_report {146 u8 report; /* FT260_SYSTEM_SETTINGS */147 u8 chip_mode; /* DCNF0 and DCNF1 status, bits 0-1 */148 u8 clock_ctl; /* 0 - 12MHz, 1 - 24MHz, 2 - 48MHz */149 u8 suspend_status; /* 0 - not suspended, 1 - suspended */150 u8 pwren_status; /* 0 - FT260 is not ready, 1 - ready */151 u8 i2c_enable; /* 0 - disabled, 1 - enabled */152 u8 uart_mode; /* 0 - OFF; 1 - RTS_CTS, 2 - DTR_DSR, */153 /* 3 - XON_XOFF, 4 - No flow control */154 u8 hid_over_i2c_en; /* 0 - disabled, 1 - enabled */155 u8 gpio2_function; /* 0 - GPIO, 1 - SUSPOUT, */156 /* 2 - PWREN, 4 - TX_LED */157 u8 gpioA_function; /* 0 - GPIO, 3 - TX_ACTIVE, 4 - TX_LED */158 u8 gpioG_function; /* 0 - GPIO, 2 - PWREN, */159 /* 5 - RX_LED, 6 - BCD_DET */160 u8 suspend_out_pol; /* 0 - active-high, 1 - active-low */161 u8 enable_wakeup_int; /* 0 - disabled, 1 - enabled */162 u8 intr_cond; /* Interrupt trigger conditions */163 u8 power_saving_en; /* 0 - disabled, 1 - enabled */164 u8 reserved[10];165} __packed;166 167struct ft260_get_i2c_status_report {168 u8 report; /* FT260_I2C_STATUS */169 u8 bus_status; /* I2C bus status */170 __le16 clock; /* I2C bus clock in range 60-3400 KHz */171 u8 reserved;172} __packed;173 174/* Feature Out reports */175 176struct ft260_set_system_clock_report {177 u8 report; /* FT260_SYSTEM_SETTINGS */178 u8 request; /* FT260_SET_CLOCK */179 u8 clock_ctl; /* 0 - 12MHz, 1 - 24MHz, 2 - 48MHz */180} __packed;181 182struct ft260_set_i2c_mode_report {183 u8 report; /* FT260_SYSTEM_SETTINGS */184 u8 request; /* FT260_SET_I2C_MODE */185 u8 i2c_enable; /* 0 - disabled, 1 - enabled */186} __packed;187 188struct ft260_set_uart_mode_report {189 u8 report; /* FT260_SYSTEM_SETTINGS */190 u8 request; /* FT260_SET_UART_MODE */191 u8 uart_mode; /* 0 - OFF; 1 - RTS_CTS, 2 - DTR_DSR, */192 /* 3 - XON_XOFF, 4 - No flow control */193} __packed;194 195struct ft260_set_i2c_reset_report {196 u8 report; /* FT260_SYSTEM_SETTINGS */197 u8 request; /* FT260_SET_I2C_RESET */198} __packed;199 200struct ft260_set_i2c_speed_report {201 u8 report; /* FT260_SYSTEM_SETTINGS */202 u8 request; /* FT260_SET_I2C_CLOCK_SPEED */203 __le16 clock; /* I2C bus clock in range 60-3400 KHz */204} __packed;205 206/* Data transfer reports */207 208struct ft260_i2c_write_request_report {209 u8 report; /* FT260_I2C_REPORT */210 u8 address; /* 7-bit I2C address */211 u8 flag; /* I2C transaction condition */212 u8 length; /* data payload length */213 u8 data[FT260_WR_DATA_MAX]; /* data payload */214} __packed;215 216struct ft260_i2c_read_request_report {217 u8 report; /* FT260_I2C_READ_REQ */218 u8 address; /* 7-bit I2C address */219 u8 flag; /* I2C transaction condition */220 __le16 length; /* data payload length */221} __packed;222 223struct ft260_i2c_input_report {224 u8 report; /* FT260_I2C_REPORT */225 u8 length; /* data payload length */226 u8 data[2]; /* data payload */227} __packed;228 229static const struct hid_device_id ft260_devices[] = {230 { HID_USB_DEVICE(USB_VENDOR_ID_FUTURE_TECHNOLOGY,231 USB_DEVICE_ID_FT260) },232 { /* END OF LIST */ }233};234MODULE_DEVICE_TABLE(hid, ft260_devices);235 236struct ft260_device {237 struct i2c_adapter adap;238 struct hid_device *hdev;239 struct completion wait;240 struct mutex lock;241 u8 write_buf[FT260_REPORT_MAX_LENGTH];242 unsigned long need_wakeup_at;243 u8 *read_buf;244 u16 read_idx;245 u16 read_len;246 u16 clock;247};248 249static int ft260_hid_feature_report_get(struct hid_device *hdev,250 unsigned char report_id, u8 *data,251 size_t len)252{253 u8 *buf;254 int ret;255 256 buf = kmalloc(len, GFP_KERNEL);257 if (!buf)258 return -ENOMEM;259 260 ret = hid_hw_raw_request(hdev, report_id, buf, len, HID_FEATURE_REPORT,261 HID_REQ_GET_REPORT);262 if (likely(ret == len))263 memcpy(data, buf, len);264 else if (ret >= 0)265 ret = -EIO;266 kfree(buf);267 return ret;268}269 270static int ft260_hid_feature_report_set(struct hid_device *hdev, u8 *data,271 size_t len)272{273 u8 *buf;274 int ret;275 276 buf = kmemdup(data, len, GFP_KERNEL);277 if (!buf)278 return -ENOMEM;279 280 buf[0] = FT260_SYSTEM_SETTINGS;281 282 ret = hid_hw_raw_request(hdev, buf[0], buf, len, HID_FEATURE_REPORT,283 HID_REQ_SET_REPORT);284 285 kfree(buf);286 return ret;287}288 289static int ft260_i2c_reset(struct hid_device *hdev)290{291 struct ft260_set_i2c_reset_report report;292 int ret;293 294 report.request = FT260_SET_I2C_RESET;295 296 ret = ft260_hid_feature_report_set(hdev, (u8 *)&report, sizeof(report));297 if (ret < 0) {298 hid_err(hdev, "failed to reset I2C controller: %d\n", ret);299 return ret;300 }301 302 ft260_dbg("done\n");303 return ret;304}305 306static int ft260_xfer_status(struct ft260_device *dev, u8 bus_busy)307{308 struct hid_device *hdev = dev->hdev;309 struct ft260_get_i2c_status_report report;310 int ret;311 312 if (time_is_before_jiffies(dev->need_wakeup_at)) {313 ret = ft260_hid_feature_report_get(hdev, FT260_I2C_STATUS,314 (u8 *)&report, sizeof(report));315 if (unlikely(ret < 0)) {316 hid_err(hdev, "failed to retrieve status: %d, no wakeup\n",317 ret);318 } else {319 dev->need_wakeup_at = jiffies +320 msecs_to_jiffies(FT260_WAKEUP_NEEDED_AFTER_MS);321 ft260_dbg("bus_status %#02x, wakeup\n",322 report.bus_status);323 }324 }325 326 ret = ft260_hid_feature_report_get(hdev, FT260_I2C_STATUS,327 (u8 *)&report, sizeof(report));328 if (unlikely(ret < 0)) {329 hid_err(hdev, "failed to retrieve status: %d\n", ret);330 return ret;331 }332 333 dev->clock = le16_to_cpu(report.clock);334 ft260_dbg("bus_status %#02x, clock %u\n", report.bus_status,335 dev->clock);336 337 if (report.bus_status & (FT260_I2C_STATUS_CTRL_BUSY | bus_busy))338 return -EAGAIN;339 340 /*341 * The error condition (bit 1) is a status bit reflecting any342 * error conditions. When any of the bits 2, 3, or 4 are raised343 * to 1, bit 1 is also set to 1.344 */345 if (report.bus_status & FT260_I2C_STATUS_ERROR) {346 hid_err(hdev, "i2c bus error: %#02x\n", report.bus_status);347 return -EIO;348 }349 350 return 0;351}352 353static int ft260_hid_output_report(struct hid_device *hdev, u8 *data,354 size_t len)355{356 u8 *buf;357 int ret;358 359 buf = kmemdup(data, len, GFP_KERNEL);360 if (!buf)361 return -ENOMEM;362 363 ret = hid_hw_output_report(hdev, buf, len);364 365 kfree(buf);366 return ret;367}368 369static int ft260_hid_output_report_check_status(struct ft260_device *dev,370 u8 *data, int len)371{372 u8 bus_busy;373 int ret, usec, try = 100;374 struct hid_device *hdev = dev->hdev;375 struct ft260_i2c_write_request_report *rep =376 (struct ft260_i2c_write_request_report *)data;377 378 ret = ft260_hid_output_report(hdev, data, len);379 if (ret < 0) {380 hid_err(hdev, "%s: failed to start transfer, ret %d\n",381 __func__, ret);382 ft260_i2c_reset(hdev);383 return ret;384 }385 386 /* transfer time = 1 / clock(KHz) * 9 bits * bytes */387 usec = len * 9000 / dev->clock;388 if (usec > 2000) {389 usec -= 1500;390 usleep_range(usec, usec + 100);391 ft260_dbg("wait %d usec, len %d\n", usec, len);392 }393 394 /*395 * Do not check the busy bit for combined transactions396 * since the controller keeps the bus busy between writing397 * and reading IOs to ensure an atomic operation.398 */399 if (rep->flag == FT260_FLAG_START)400 bus_busy = 0;401 else402 bus_busy = FT260_I2C_STATUS_BUS_BUSY;403 404 do {405 ret = ft260_xfer_status(dev, bus_busy);406 if (ret != -EAGAIN)407 break;408 } while (--try);409 410 if (ret == 0)411 return 0;412 413 ft260_i2c_reset(hdev);414 return -EIO;415}416 417static int ft260_i2c_write(struct ft260_device *dev, u8 addr, u8 *data,418 int len, u8 flag)419{420 int ret, wr_len, idx = 0;421 struct hid_device *hdev = dev->hdev;422 struct ft260_i2c_write_request_report *rep =423 (struct ft260_i2c_write_request_report *)dev->write_buf;424 425 if (len < 1)426 return -EINVAL;427 428 rep->flag = FT260_FLAG_START;429 430 do {431 if (len <= FT260_WR_DATA_MAX) {432 wr_len = len;433 if (flag == FT260_FLAG_START_STOP)434 rep->flag |= FT260_FLAG_STOP;435 } else {436 wr_len = FT260_WR_DATA_MAX;437 }438 439 rep->report = FT260_I2C_DATA_REPORT_ID(wr_len);440 rep->address = addr;441 rep->length = wr_len;442 443 memcpy(rep->data, &data[idx], wr_len);444 445 ft260_dbg("rep %#02x addr %#02x off %d len %d wlen %d flag %#x d[0] %#02x\n",446 rep->report, addr, idx, len, wr_len,447 rep->flag, data[0]);448 449 ret = ft260_hid_output_report_check_status(dev, (u8 *)rep,450 wr_len + 4);451 if (ret < 0) {452 hid_err(hdev, "%s: failed with %d\n", __func__, ret);453 return ret;454 }455 456 len -= wr_len;457 idx += wr_len;458 rep->flag = 0;459 460 } while (len > 0);461 462 return 0;463}464 465static int ft260_smbus_write(struct ft260_device *dev, u8 addr, u8 cmd,466 u8 *data, u8 data_len, u8 flag)467{468 int ret = 0;469 int len = 4;470 471 struct ft260_i2c_write_request_report *rep =472 (struct ft260_i2c_write_request_report *)dev->write_buf;473 474 if (data_len >= sizeof(rep->data))475 return -EINVAL;476 477 rep->address = addr;478 rep->data[0] = cmd;479 rep->length = data_len + 1;480 rep->flag = flag;481 len += rep->length;482 483 rep->report = FT260_I2C_DATA_REPORT_ID(len);484 485 if (data_len > 0)486 memcpy(&rep->data[1], data, data_len);487 488 ft260_dbg("rep %#02x addr %#02x cmd %#02x datlen %d replen %d\n",489 rep->report, addr, cmd, rep->length, len);490 491 ret = ft260_hid_output_report_check_status(dev, (u8 *)rep, len);492 493 return ret;494}495 496static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,497 u16 len, u8 flag)498{499 u16 rd_len;500 u16 rd_data_max = 60;501 int timeout, ret = 0;502 struct ft260_i2c_read_request_report rep;503 struct hid_device *hdev = dev->hdev;504 u8 bus_busy = 0;505 506 if ((flag & FT260_FLAG_START_REPEATED) == FT260_FLAG_START_REPEATED)507 flag = FT260_FLAG_START_REPEATED;508 else509 flag = FT260_FLAG_START;510 do {511 if (len <= rd_data_max) {512 rd_len = len;513 flag |= FT260_FLAG_STOP;514 } else {515 rd_len = rd_data_max;516 }517 rd_data_max = FT260_RD_DATA_MAX;518 519 rep.report = FT260_I2C_READ_REQ;520 rep.length = cpu_to_le16(rd_len);521 rep.address = addr;522 rep.flag = flag;523 524 ft260_dbg("rep %#02x addr %#02x len %d rlen %d flag %#x\n",525 rep.report, rep.address, len, rd_len, flag);526 527 reinit_completion(&dev->wait);528 529 dev->read_idx = 0;530 dev->read_buf = data;531 dev->read_len = rd_len;532 533 ret = ft260_hid_output_report(hdev, (u8 *)&rep, sizeof(rep));534 if (ret < 0) {535 hid_err(hdev, "%s: failed with %d\n", __func__, ret);536 goto ft260_i2c_read_exit;537 }538 539 timeout = msecs_to_jiffies(5000);540 if (!wait_for_completion_timeout(&dev->wait, timeout)) {541 ret = -ETIMEDOUT;542 ft260_i2c_reset(hdev);543 goto ft260_i2c_read_exit;544 }545 546 dev->read_buf = NULL;547 548 if (flag & FT260_FLAG_STOP)549 bus_busy = FT260_I2C_STATUS_BUS_BUSY;550 551 ret = ft260_xfer_status(dev, bus_busy);552 if (ret < 0) {553 ret = -EIO;554 ft260_i2c_reset(hdev);555 goto ft260_i2c_read_exit;556 }557 558 len -= rd_len;559 data += rd_len;560 flag = 0;561 562 } while (len > 0);563 564ft260_i2c_read_exit:565 dev->read_buf = NULL;566 return ret;567}568 569/*570 * A random read operation is implemented as a dummy write operation, followed571 * by a current address read operation. The dummy write operation is used to572 * load the target byte address into the current byte address counter, from573 * which the subsequent current address read operation then reads.574 */575static int ft260_i2c_write_read(struct ft260_device *dev, struct i2c_msg *msgs)576{577 int ret;578 int wr_len = msgs[0].len;579 int rd_len = msgs[1].len;580 struct hid_device *hdev = dev->hdev;581 u8 addr = msgs[0].addr;582 u16 read_off = 0;583 584 if (wr_len > 2) {585 hid_err(hdev, "%s: invalid wr_len: %d\n", __func__, wr_len);586 return -EOPNOTSUPP;587 }588 589 if (ft260_debug) {590 if (wr_len == 2)591 read_off = be16_to_cpu(*(__be16 *)msgs[0].buf);592 else593 read_off = *msgs[0].buf;594 595 pr_info("%s: off %#x rlen %d wlen %d\n", __func__,596 read_off, rd_len, wr_len);597 }598 599 ret = ft260_i2c_write(dev, addr, msgs[0].buf, wr_len,600 FT260_FLAG_START);601 if (ret < 0)602 return ret;603 604 ret = ft260_i2c_read(dev, addr, msgs[1].buf, rd_len,605 FT260_FLAG_START_STOP_REPEATED);606 if (ret < 0)607 return ret;608 609 return 0;610}611 612static int ft260_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,613 int num)614{615 int ret;616 struct ft260_device *dev = i2c_get_adapdata(adapter);617 struct hid_device *hdev = dev->hdev;618 619 mutex_lock(&dev->lock);620 621 ret = hid_hw_power(hdev, PM_HINT_FULLON);622 if (ret < 0) {623 hid_err(hdev, "failed to enter FULLON power mode: %d\n", ret);624 mutex_unlock(&dev->lock);625 return ret;626 }627 628 if (num == 1) {629 if (msgs->flags & I2C_M_RD)630 ret = ft260_i2c_read(dev, msgs->addr, msgs->buf,631 msgs->len, FT260_FLAG_START_STOP);632 else633 ret = ft260_i2c_write(dev, msgs->addr, msgs->buf,634 msgs->len, FT260_FLAG_START_STOP);635 if (ret < 0)636 goto i2c_exit;637 638 } else {639 /* Combined write then read message */640 ret = ft260_i2c_write_read(dev, msgs);641 if (ret < 0)642 goto i2c_exit;643 }644 645 ret = num;646i2c_exit:647 hid_hw_power(hdev, PM_HINT_NORMAL);648 mutex_unlock(&dev->lock);649 return ret;650}651 652static int ft260_smbus_xfer(struct i2c_adapter *adapter, u16 addr, u16 flags,653 char read_write, u8 cmd, int size,654 union i2c_smbus_data *data)655{656 int ret;657 struct ft260_device *dev = i2c_get_adapdata(adapter);658 struct hid_device *hdev = dev->hdev;659 660 ft260_dbg("smbus size %d\n", size);661 662 mutex_lock(&dev->lock);663 664 ret = hid_hw_power(hdev, PM_HINT_FULLON);665 if (ret < 0) {666 hid_err(hdev, "power management error: %d\n", ret);667 mutex_unlock(&dev->lock);668 return ret;669 }670 671 switch (size) {672 case I2C_SMBUS_BYTE:673 if (read_write == I2C_SMBUS_READ)674 ret = ft260_i2c_read(dev, addr, &data->byte, 1,675 FT260_FLAG_START_STOP);676 else677 ret = ft260_smbus_write(dev, addr, cmd, NULL, 0,678 FT260_FLAG_START_STOP);679 break;680 case I2C_SMBUS_BYTE_DATA:681 if (read_write == I2C_SMBUS_READ) {682 ret = ft260_smbus_write(dev, addr, cmd, NULL, 0,683 FT260_FLAG_START);684 if (ret)685 goto smbus_exit;686 687 ret = ft260_i2c_read(dev, addr, &data->byte, 1,688 FT260_FLAG_START_STOP_REPEATED);689 } else {690 ret = ft260_smbus_write(dev, addr, cmd, &data->byte, 1,691 FT260_FLAG_START_STOP);692 }693 break;694 case I2C_SMBUS_WORD_DATA:695 if (read_write == I2C_SMBUS_READ) {696 ret = ft260_smbus_write(dev, addr, cmd, NULL, 0,697 FT260_FLAG_START);698 if (ret)699 goto smbus_exit;700 701 ret = ft260_i2c_read(dev, addr, (u8 *)&data->word, 2,702 FT260_FLAG_START_STOP_REPEATED);703 } else {704 ret = ft260_smbus_write(dev, addr, cmd,705 (u8 *)&data->word, 2,706 FT260_FLAG_START_STOP);707 }708 break;709 case I2C_SMBUS_BLOCK_DATA:710 if (read_write == I2C_SMBUS_READ) {711 ret = ft260_smbus_write(dev, addr, cmd, NULL, 0,712 FT260_FLAG_START);713 if (ret)714 goto smbus_exit;715 716 ret = ft260_i2c_read(dev, addr, data->block,717 data->block[0] + 1,718 FT260_FLAG_START_STOP_REPEATED);719 } else {720 ret = ft260_smbus_write(dev, addr, cmd, data->block,721 data->block[0] + 1,722 FT260_FLAG_START_STOP);723 }724 break;725 case I2C_SMBUS_I2C_BLOCK_DATA:726 if (read_write == I2C_SMBUS_READ) {727 ret = ft260_smbus_write(dev, addr, cmd, NULL, 0,728 FT260_FLAG_START);729 if (ret)730 goto smbus_exit;731 732 ret = ft260_i2c_read(dev, addr, data->block + 1,733 data->block[0],734 FT260_FLAG_START_STOP_REPEATED);735 } else {736 ret = ft260_smbus_write(dev, addr, cmd, data->block + 1,737 data->block[0],738 FT260_FLAG_START_STOP);739 }740 break;741 default:742 hid_err(hdev, "unsupported smbus transaction size %d\n", size);743 ret = -EOPNOTSUPP;744 }745 746smbus_exit:747 hid_hw_power(hdev, PM_HINT_NORMAL);748 mutex_unlock(&dev->lock);749 return ret;750}751 752static u32 ft260_functionality(struct i2c_adapter *adap)753{754 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE |755 I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |756 I2C_FUNC_SMBUS_BLOCK_DATA | I2C_FUNC_SMBUS_I2C_BLOCK;757}758 759static const struct i2c_adapter_quirks ft260_i2c_quirks = {760 .flags = I2C_AQ_COMB_WRITE_THEN_READ,761 .max_comb_1st_msg_len = 2,762};763 764static const struct i2c_algorithm ft260_i2c_algo = {765 .master_xfer = ft260_i2c_xfer,766 .smbus_xfer = ft260_smbus_xfer,767 .functionality = ft260_functionality,768};769 770static int ft260_get_system_config(struct hid_device *hdev,771 struct ft260_get_system_status_report *cfg)772{773 int ret;774 int len = sizeof(struct ft260_get_system_status_report);775 776 ret = ft260_hid_feature_report_get(hdev, FT260_SYSTEM_SETTINGS,777 (u8 *)cfg, len);778 if (ret < 0) {779 hid_err(hdev, "failed to retrieve system status\n");780 return ret;781 }782 return 0;783}784 785static int ft260_is_interface_enabled(struct hid_device *hdev)786{787 struct ft260_get_system_status_report cfg;788 struct usb_interface *usbif = to_usb_interface(hdev->dev.parent);789 int interface = usbif->cur_altsetting->desc.bInterfaceNumber;790 int ret;791 792 ret = ft260_get_system_config(hdev, &cfg);793 if (ret < 0)794 return ret;795 796 ft260_dbg("interface: 0x%02x\n", interface);797 ft260_dbg("chip mode: 0x%02x\n", cfg.chip_mode);798 ft260_dbg("clock_ctl: 0x%02x\n", cfg.clock_ctl);799 ft260_dbg("i2c_enable: 0x%02x\n", cfg.i2c_enable);800 ft260_dbg("uart_mode: 0x%02x\n", cfg.uart_mode);801 802 switch (cfg.chip_mode) {803 case FT260_MODE_ALL:804 case FT260_MODE_BOTH:805 if (interface == 1)806 hid_info(hdev, "uart interface is not supported\n");807 else808 ret = 1;809 break;810 case FT260_MODE_UART:811 hid_info(hdev, "uart interface is not supported\n");812 break;813 case FT260_MODE_I2C:814 ret = 1;815 break;816 }817 return ret;818}819 820static int ft260_byte_show(struct hid_device *hdev, int id, u8 *cfg, int len,821 u8 *field, u8 *buf)822{823 int ret;824 825 ret = ft260_hid_feature_report_get(hdev, id, cfg, len);826 if (ret < 0)827 return ret;828 829 return scnprintf(buf, PAGE_SIZE, "%d\n", *field);830}831 832static int ft260_word_show(struct hid_device *hdev, int id, u8 *cfg, int len,833 __le16 *field, u8 *buf)834{835 int ret;836 837 ret = ft260_hid_feature_report_get(hdev, id, cfg, len);838 if (ret < 0)839 return ret;840 841 return scnprintf(buf, PAGE_SIZE, "%d\n", le16_to_cpu(*field));842}843 844#define FT260_ATTR_SHOW(name, reptype, id, type, func) \845 static ssize_t name##_show(struct device *kdev, \846 struct device_attribute *attr, char *buf) \847 { \848 struct reptype rep; \849 struct hid_device *hdev = to_hid_device(kdev); \850 type *field = &rep.name; \851 int len = sizeof(rep); \852 \853 return func(hdev, id, (u8 *)&rep, len, field, buf); \854 }855 856#define FT260_SSTAT_ATTR_SHOW(name) \857 FT260_ATTR_SHOW(name, ft260_get_system_status_report, \858 FT260_SYSTEM_SETTINGS, u8, ft260_byte_show)859 860#define FT260_I2CST_ATTR_SHOW(name) \861 FT260_ATTR_SHOW(name, ft260_get_i2c_status_report, \862 FT260_I2C_STATUS, __le16, ft260_word_show)863 864#define FT260_ATTR_STORE(name, reptype, id, req, type, ctype, func) \865 static ssize_t name##_store(struct device *kdev, \866 struct device_attribute *attr, \867 const char *buf, size_t count) \868 { \869 struct reptype rep; \870 struct hid_device *hdev = to_hid_device(kdev); \871 type name; \872 int ret; \873 \874 if (!func(buf, 10, (ctype *)&name)) { \875 rep.name = name; \876 rep.report = id; \877 rep.request = req; \878 ret = ft260_hid_feature_report_set(hdev, (u8 *)&rep, \879 sizeof(rep)); \880 if (!ret) \881 ret = count; \882 } else { \883 ret = -EINVAL; \884 } \885 return ret; \886 }887 888#define FT260_BYTE_ATTR_STORE(name, reptype, req) \889 FT260_ATTR_STORE(name, reptype, FT260_SYSTEM_SETTINGS, req, \890 u8, u8, kstrtou8)891 892#define FT260_WORD_ATTR_STORE(name, reptype, req) \893 FT260_ATTR_STORE(name, reptype, FT260_SYSTEM_SETTINGS, req, \894 __le16, u16, kstrtou16)895 896FT260_SSTAT_ATTR_SHOW(chip_mode);897static DEVICE_ATTR_RO(chip_mode);898 899FT260_SSTAT_ATTR_SHOW(pwren_status);900static DEVICE_ATTR_RO(pwren_status);901 902FT260_SSTAT_ATTR_SHOW(suspend_status);903static DEVICE_ATTR_RO(suspend_status);904 905FT260_SSTAT_ATTR_SHOW(hid_over_i2c_en);906static DEVICE_ATTR_RO(hid_over_i2c_en);907 908FT260_SSTAT_ATTR_SHOW(power_saving_en);909static DEVICE_ATTR_RO(power_saving_en);910 911FT260_SSTAT_ATTR_SHOW(i2c_enable);912FT260_BYTE_ATTR_STORE(i2c_enable, ft260_set_i2c_mode_report,913 FT260_SET_I2C_MODE);914static DEVICE_ATTR_RW(i2c_enable);915 916FT260_SSTAT_ATTR_SHOW(uart_mode);917FT260_BYTE_ATTR_STORE(uart_mode, ft260_set_uart_mode_report,918 FT260_SET_UART_MODE);919static DEVICE_ATTR_RW(uart_mode);920 921FT260_SSTAT_ATTR_SHOW(clock_ctl);922FT260_BYTE_ATTR_STORE(clock_ctl, ft260_set_system_clock_report,923 FT260_SET_CLOCK);924static DEVICE_ATTR_RW(clock_ctl);925 926FT260_I2CST_ATTR_SHOW(clock);927FT260_WORD_ATTR_STORE(clock, ft260_set_i2c_speed_report,928 FT260_SET_I2C_CLOCK_SPEED);929static DEVICE_ATTR_RW(clock);930 931static ssize_t i2c_reset_store(struct device *kdev,932 struct device_attribute *attr, const char *buf,933 size_t count)934{935 struct hid_device *hdev = to_hid_device(kdev);936 int ret = ft260_i2c_reset(hdev);937 938 if (ret)939 return ret;940 return count;941}942static DEVICE_ATTR_WO(i2c_reset);943 944static const struct attribute_group ft260_attr_group = {945 .attrs = (struct attribute *[]) {946 &dev_attr_chip_mode.attr,947 &dev_attr_pwren_status.attr,948 &dev_attr_suspend_status.attr,949 &dev_attr_hid_over_i2c_en.attr,950 &dev_attr_power_saving_en.attr,951 &dev_attr_i2c_enable.attr,952 &dev_attr_uart_mode.attr,953 &dev_attr_clock_ctl.attr,954 &dev_attr_i2c_reset.attr,955 &dev_attr_clock.attr,956 NULL957 }958};959 960static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)961{962 struct ft260_device *dev;963 struct ft260_get_chip_version_report version;964 int ret;965 966 if (!hid_is_usb(hdev))967 return -EINVAL;968 969 dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);970 if (!dev)971 return -ENOMEM;972 973 ret = hid_parse(hdev);974 if (ret) {975 hid_err(hdev, "failed to parse HID\n");976 return ret;977 }978 979 ret = hid_hw_start(hdev, 0);980 if (ret) {981 hid_err(hdev, "failed to start HID HW\n");982 return ret;983 }984 985 ret = hid_hw_open(hdev);986 if (ret) {987 hid_err(hdev, "failed to open HID HW\n");988 goto err_hid_stop;989 }990 991 ret = ft260_hid_feature_report_get(hdev, FT260_CHIP_VERSION,992 (u8 *)&version, sizeof(version));993 if (ret < 0) {994 hid_err(hdev, "failed to retrieve chip version\n");995 goto err_hid_close;996 }997 998 hid_info(hdev, "chip code: %02x%02x %02x%02x\n",999 version.chip_code[0], version.chip_code[1],1000 version.chip_code[2], version.chip_code[3]);1001 1002 ret = ft260_is_interface_enabled(hdev);1003 if (ret <= 0)1004 goto err_hid_close;1005 1006 hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n",1007 hdev->version >> 8, hdev->version & 0xff, hdev->name,1008 hdev->phys);1009 1010 hid_set_drvdata(hdev, dev);1011 dev->hdev = hdev;1012 dev->adap.owner = THIS_MODULE;1013 dev->adap.class = I2C_CLASS_HWMON;1014 dev->adap.algo = &ft260_i2c_algo;1015 dev->adap.quirks = &ft260_i2c_quirks;1016 dev->adap.dev.parent = &hdev->dev;1017 snprintf(dev->adap.name, sizeof(dev->adap.name),1018 "FT260 usb-i2c bridge");1019 1020 mutex_init(&dev->lock);1021 init_completion(&dev->wait);1022 1023 ret = ft260_xfer_status(dev, FT260_I2C_STATUS_BUS_BUSY);1024 if (ret)1025 ft260_i2c_reset(hdev);1026 1027 i2c_set_adapdata(&dev->adap, dev);1028 ret = i2c_add_adapter(&dev->adap);1029 if (ret) {1030 hid_err(hdev, "failed to add i2c adapter\n");1031 goto err_hid_close;1032 }1033 1034 ret = sysfs_create_group(&hdev->dev.kobj, &ft260_attr_group);1035 if (ret < 0) {1036 hid_err(hdev, "failed to create sysfs attrs\n");1037 goto err_i2c_free;1038 }1039 1040 return 0;1041 1042err_i2c_free:1043 i2c_del_adapter(&dev->adap);1044err_hid_close:1045 hid_hw_close(hdev);1046err_hid_stop:1047 hid_hw_stop(hdev);1048 return ret;1049}1050 1051static void ft260_remove(struct hid_device *hdev)1052{1053 struct ft260_device *dev = hid_get_drvdata(hdev);1054 1055 if (!dev)1056 return;1057 1058 sysfs_remove_group(&hdev->dev.kobj, &ft260_attr_group);1059 i2c_del_adapter(&dev->adap);1060 1061 hid_hw_close(hdev);1062 hid_hw_stop(hdev);1063}1064 1065static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,1066 u8 *data, int size)1067{1068 struct ft260_device *dev = hid_get_drvdata(hdev);1069 struct ft260_i2c_input_report *xfer = (void *)data;1070 1071 if (xfer->report >= FT260_I2C_REPORT_MIN &&1072 xfer->report <= FT260_I2C_REPORT_MAX) {1073 ft260_dbg("i2c resp: rep %#02x len %d\n", xfer->report,1074 xfer->length);1075 1076 if ((dev->read_buf == NULL) ||1077 (xfer->length > dev->read_len - dev->read_idx)) {1078 hid_err(hdev, "unexpected report %#02x, length %d\n",1079 xfer->report, xfer->length);1080 return -1;1081 }1082 1083 memcpy(&dev->read_buf[dev->read_idx], &xfer->data,1084 xfer->length);1085 dev->read_idx += xfer->length;1086 1087 if (dev->read_idx == dev->read_len)1088 complete(&dev->wait);1089 1090 } else {1091 hid_err(hdev, "unhandled report %#02x\n", xfer->report);1092 }1093 return 0;1094}1095 1096static struct hid_driver ft260_driver = {1097 .name = "ft260",1098 .id_table = ft260_devices,1099 .probe = ft260_probe,1100 .remove = ft260_remove,1101 .raw_event = ft260_raw_event,1102};1103 1104module_hid_driver(ft260_driver);1105MODULE_DESCRIPTION("FTDI FT260 USB HID to I2C host bridge");1106MODULE_AUTHOR("Michael Zaidman <michael.zaidman@gmail.com>");1107MODULE_LICENSE("GPL v2");1108