Lines Matching +full:combined +full:- +full:power +full:- +full:req
1 // SPDX-License-Identifier: GPL-2.0-only
3 * hid-ft260.c - FTDI FT260 USB HID to I2C host bridge
11 #include "hid-ids.h"
32 #define FT260_I2C_DATA_REPORT_ID(len) (FT260_I2C_REPORT_MIN + (len - 1) / 4)
45 * second - USB HID to UART bridge function.
138 u8 chip_mode; /* DCNF0 and DCNF1 status, bits 0-1 */
139 u8 clock_ctl; /* 0 - 12MHz, 1 - 24MHz, 2 - 48MHz */
140 u8 suspend_status; /* 0 - not suspended, 1 - suspended */
141 u8 pwren_status; /* 0 - FT260 is not ready, 1 - ready */
142 u8 i2c_enable; /* 0 - disabled, 1 - enabled */
143 u8 uart_mode; /* 0 - OFF; 1 - RTS_CTS, 2 - DTR_DSR, */
144 /* 3 - XON_XOFF, 4 - No flow control */
145 u8 hid_over_i2c_en; /* 0 - disabled, 1 - enabled */
146 u8 gpio2_function; /* 0 - GPIO, 1 - SUSPOUT, */
147 /* 2 - PWREN, 4 - TX_LED */
148 u8 gpioA_function; /* 0 - GPIO, 3 - TX_ACTIVE, 4 - TX_LED */
149 u8 gpioG_function; /* 0 - GPIO, 2 - PWREN, */
150 /* 5 - RX_LED, 6 - BCD_DET */
151 u8 suspend_out_pol; /* 0 - active-high, 1 - active-low */
152 u8 enable_wakeup_int; /* 0 - disabled, 1 - enabled */
154 u8 power_saving_en; /* 0 - disabled, 1 - enabled */
161 __le16 clock; /* I2C bus clock in range 60-3400 KHz */
170 u8 clock_ctl; /* 0 - 12MHz, 1 - 24MHz, 2 - 48MHz */
176 u8 i2c_enable; /* 0 - disabled, 1 - enabled */
182 u8 uart_mode; /* 0 - OFF; 1 - RTS_CTS, 2 - DTR_DSR, */
183 /* 3 - XON_XOFF, 4 - No flow control */
194 __le16 clock; /* I2C bus clock in range 60-3400 KHz */
201 u8 address; /* 7-bit I2C address */
209 u8 address; /* 7-bit I2C address */
248 return -ENOMEM; in ft260_hid_feature_report_get()
255 ret = -EIO; in ft260_hid_feature_report_get()
268 return -ENOMEM; in ft260_hid_feature_report_set()
298 struct hid_device *hdev = dev->hdev; in ft260_xfer_status()
309 dev->clock = le16_to_cpu(report.clock); in ft260_xfer_status()
311 dev->clock); in ft260_xfer_status()
314 return -EAGAIN; in ft260_xfer_status()
317 return -EBUSY; in ft260_xfer_status()
320 return -EIO; in ft260_xfer_status()
322 ret = -EIO; in ft260_xfer_status()
347 return -ENOMEM; in ft260_hid_output_report()
359 struct hid_device *hdev = dev->hdev; in ft260_hid_output_report_check_status()
370 usec = 10000 / dev->clock * len; in ft260_hid_output_report_check_status()
375 if (ret != -EAGAIN) in ft260_hid_output_report_check_status()
377 } while (--try); in ft260_hid_output_report_check_status()
379 if (ret == 0 || ret == -EBUSY) in ft260_hid_output_report_check_status()
383 return -EIO; in ft260_hid_output_report_check_status()
390 struct hid_device *hdev = dev->hdev; in ft260_i2c_write()
392 (struct ft260_i2c_write_request_report *)dev->write_buf; in ft260_i2c_write()
400 rep->report = FT260_I2C_DATA_REPORT_ID(len); in ft260_i2c_write()
401 rep->address = addr; in ft260_i2c_write()
402 rep->length = len; in ft260_i2c_write()
403 rep->flag = flag; in ft260_i2c_write()
405 memcpy(rep->data, &data[idx], len); in ft260_i2c_write()
408 rep->report, addr, idx, len, data[0]); in ft260_i2c_write()
418 data_len -= len; in ft260_i2c_write()
433 (struct ft260_i2c_write_request_report *)dev->write_buf; in ft260_smbus_write()
435 if (data_len >= sizeof(rep->data)) in ft260_smbus_write()
436 return -EINVAL; in ft260_smbus_write()
438 rep->address = addr; in ft260_smbus_write()
439 rep->data[0] = cmd; in ft260_smbus_write()
440 rep->length = data_len + 1; in ft260_smbus_write()
441 rep->flag = flag; in ft260_smbus_write()
442 len += rep->length; in ft260_smbus_write()
444 rep->report = FT260_I2C_DATA_REPORT_ID(len); in ft260_smbus_write()
447 memcpy(&rep->data[1], data, data_len); in ft260_smbus_write()
450 rep->report, addr, cmd, rep->length, len); in ft260_smbus_write()
461 struct hid_device *hdev = dev->hdev; in ft260_i2c_read()
467 return -EINVAL; in ft260_i2c_read()
470 dev->read_idx = 0; in ft260_i2c_read()
471 dev->read_buf = data; in ft260_i2c_read()
472 dev->read_len = len; in ft260_i2c_read()
482 reinit_completion(&dev->wait); in ft260_i2c_read()
492 if (!wait_for_completion_timeout(&dev->wait, timeout)) { in ft260_i2c_read()
494 return -ETIMEDOUT; in ft260_i2c_read()
502 return -EIO; in ft260_i2c_read()
518 struct hid_device *hdev = dev->hdev; in ft260_i2c_write_read()
523 return -EOPNOTSUPP; in ft260_i2c_write_read()
547 left_len -= len; in ft260_i2c_write_read()
561 struct hid_device *hdev = dev->hdev; in ft260_i2c_xfer()
563 mutex_lock(&dev->lock); in ft260_i2c_xfer()
567 hid_err(hdev, "failed to enter FULLON power mode: %d\n", ret); in ft260_i2c_xfer()
568 mutex_unlock(&dev->lock); in ft260_i2c_xfer()
573 if (msgs->flags & I2C_M_RD) in ft260_i2c_xfer()
574 ret = ft260_i2c_read(dev, msgs->addr, msgs->buf, in ft260_i2c_xfer()
575 msgs->len, FT260_FLAG_START_STOP); in ft260_i2c_xfer()
577 ret = ft260_i2c_write(dev, msgs->addr, msgs->buf, in ft260_i2c_xfer()
578 msgs->len, FT260_FLAG_START_STOP); in ft260_i2c_xfer()
583 /* Combined write then read message */ in ft260_i2c_xfer()
592 mutex_unlock(&dev->lock); in ft260_i2c_xfer()
602 struct hid_device *hdev = dev->hdev; in ft260_smbus_xfer()
606 mutex_lock(&dev->lock); in ft260_smbus_xfer()
610 hid_err(hdev, "power management error: %d\n", ret); in ft260_smbus_xfer()
611 mutex_unlock(&dev->lock); in ft260_smbus_xfer()
618 ret = ft260_i2c_read(dev, addr, &data->byte, 0, in ft260_smbus_xfer()
626 ret = ft260_i2c_read(dev, addr, &data->byte, 1, in ft260_smbus_xfer()
639 ret = ft260_i2c_read(dev, addr, &data->byte, 1, in ft260_smbus_xfer()
642 ret = ft260_smbus_write(dev, addr, cmd, &data->byte, 1, in ft260_smbus_xfer()
653 ret = ft260_i2c_read(dev, addr, (u8 *)&data->word, 2, in ft260_smbus_xfer()
657 (u8 *)&data->word, 2, in ft260_smbus_xfer()
668 ret = ft260_i2c_read(dev, addr, data->block, in ft260_smbus_xfer()
669 data->block[0] + 1, in ft260_smbus_xfer()
672 ret = ft260_smbus_write(dev, addr, cmd, data->block, in ft260_smbus_xfer()
673 data->block[0] + 1, in ft260_smbus_xfer()
684 ret = ft260_i2c_read(dev, addr, data->block + 1, in ft260_smbus_xfer()
685 data->block[0], in ft260_smbus_xfer()
688 ret = ft260_smbus_write(dev, addr, cmd, data->block + 1, in ft260_smbus_xfer()
689 data->block[0], in ft260_smbus_xfer()
695 ret = -EOPNOTSUPP; in ft260_smbus_xfer()
700 mutex_unlock(&dev->lock); in ft260_smbus_xfer()
740 struct usb_interface *usbif = to_usb_interface(hdev->dev.parent); in ft260_is_interface_enabled()
741 int interface = usbif->cur_altsetting->desc.bInterfaceNumber; in ft260_is_interface_enabled()
816 #define FT260_ATTR_STORE(name, reptype, id, req, type, func) \ argument
829 rep.request = req; \
835 ret = -EINVAL; \
840 #define FT260_BYTE_ATTR_STORE(name, reptype, req) \ argument
841 FT260_ATTR_STORE(name, reptype, FT260_SYSTEM_SETTINGS, req, \
844 #define FT260_WORD_ATTR_STORE(name, reptype, req) \ argument
845 FT260_ATTR_STORE(name, reptype, FT260_SYSTEM_SETTINGS, req, \
918 dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL); in ft260_probe()
920 return -ENOMEM; in ft260_probe()
956 dev->hdev = hdev; in ft260_probe()
957 dev->adap.owner = THIS_MODULE; in ft260_probe()
958 dev->adap.class = I2C_CLASS_HWMON; in ft260_probe()
959 dev->adap.algo = &ft260_i2c_algo; in ft260_probe()
960 dev->adap.quirks = &ft260_i2c_quirks; in ft260_probe()
961 dev->adap.dev.parent = &hdev->dev; in ft260_probe()
962 snprintf(dev->adap.name, sizeof(dev->adap.name), in ft260_probe()
963 "FT260 usb-i2c bridge on hidraw%d", in ft260_probe()
964 ((struct hidraw *)hdev->hidraw)->minor); in ft260_probe()
966 mutex_init(&dev->lock); in ft260_probe()
967 init_completion(&dev->wait); in ft260_probe()
969 ret = i2c_add_adapter(&dev->adap); in ft260_probe()
975 i2c_set_adapdata(&dev->adap, dev); in ft260_probe()
977 ret = sysfs_create_group(&hdev->dev.kobj, &ft260_attr_group); in ft260_probe()
990 i2c_del_adapter(&dev->adap); in ft260_probe()
1005 sysfs_remove_group(&hdev->dev.kobj, &ft260_attr_group); in ft260_remove()
1006 i2c_del_adapter(&dev->adap); in ft260_remove()
1018 if (xfer->report >= FT260_I2C_REPORT_MIN && in ft260_raw_event()
1019 xfer->report <= FT260_I2C_REPORT_MAX) { in ft260_raw_event()
1020 ft260_dbg("i2c resp: rep %#02x len %d\n", xfer->report, in ft260_raw_event()
1021 xfer->length); in ft260_raw_event()
1023 memcpy(&dev->read_buf[dev->read_idx], &xfer->data, in ft260_raw_event()
1024 xfer->length); in ft260_raw_event()
1025 dev->read_idx += xfer->length; in ft260_raw_event()
1027 if (dev->read_idx == dev->read_len) in ft260_raw_event()
1028 complete(&dev->wait); in ft260_raw_event()
1031 hid_err(hdev, "unknown report: %#02x\n", xfer->report); in ft260_raw_event()