^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * hid-cp2112.c - Silicon Labs HID USB to SMBus master bridge
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2013,2014 Uplogix, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * David Barksdale <dbarksdale@uplogix.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * The Silicon Labs CP2112 chip is a USB HID device which provides an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * SMBus controller for talking to slave devices and 8 GPIO pins. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * host communicates with the CP2112 via raw HID reports.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Data Sheet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * https://www.silabs.com/Support%20Documents/TechnicalDocs/CP2112.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Programming Interface Specification:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * https://www.silabs.com/documents/public/application-notes/an495-cp2112-interface-specification.pdf
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/gpio/machine.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/gpio/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/hid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/hidraw.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/nls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/usb/ch9.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "hid-ids.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CP2112_REPORT_MAX_LENGTH 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CP2112_GPIO_CONFIG_LENGTH 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CP2112_GPIO_GET_LENGTH 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CP2112_GPIO_SET_LENGTH 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) CP2112_GPIO_CONFIG = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) CP2112_GPIO_GET = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) CP2112_GPIO_SET = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) CP2112_GET_VERSION_INFO = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) CP2112_SMBUS_CONFIG = 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) CP2112_DATA_READ_REQUEST = 0x10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) CP2112_DATA_WRITE_READ_REQUEST = 0x11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) CP2112_DATA_READ_FORCE_SEND = 0x12,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) CP2112_DATA_READ_RESPONSE = 0x13,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) CP2112_DATA_WRITE_REQUEST = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) CP2112_TRANSFER_STATUS_REQUEST = 0x15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) CP2112_TRANSFER_STATUS_RESPONSE = 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) CP2112_CANCEL_TRANSFER = 0x17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) CP2112_LOCK_BYTE = 0x20,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) CP2112_USB_CONFIG = 0x21,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) CP2112_MANUFACTURER_STRING = 0x22,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) CP2112_PRODUCT_STRING = 0x23,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) CP2112_SERIAL_STRING = 0x24,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) STATUS0_IDLE = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) STATUS0_BUSY = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) STATUS0_COMPLETE = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) STATUS0_ERROR = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) STATUS1_TIMEOUT_NACK = 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) STATUS1_TIMEOUT_BUS = 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) STATUS1_ARBITRATION_LOST = 0x02,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) STATUS1_READ_INCOMPLETE = 0x03,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) STATUS1_WRITE_INCOMPLETE = 0x04,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) STATUS1_SUCCESS = 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct cp2112_smbus_config_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u8 report; /* CP2112_SMBUS_CONFIG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __be32 clock_speed; /* Hz */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) u8 device_address; /* Stored in the upper 7 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) u8 auto_send_read; /* 1 = enabled, 0 = disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __be16 write_timeout; /* ms, 0 = no timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) __be16 read_timeout; /* ms, 0 = no timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) u8 scl_low_timeout; /* 1 = enabled, 0 = disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __be16 retry_time; /* # of retries, 0 = no limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct cp2112_usb_config_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) u8 report; /* CP2112_USB_CONFIG */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __le16 vid; /* Vendor ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) __le16 pid; /* Product ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) u8 max_power; /* Power requested in 2mA units */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u8 power_mode; /* 0x00 = bus powered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) 0x01 = self powered & regulator off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) 0x02 = self powered & regulator on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u8 release_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u8 release_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) u8 mask; /* What fields to program */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) struct cp2112_read_req_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) u8 report; /* CP2112_DATA_READ_REQUEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) u8 slave_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) __be16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct cp2112_write_read_req_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 report; /* CP2112_DATA_WRITE_READ_REQUEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) u8 slave_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) __be16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) u8 target_address_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 target_address[16];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct cp2112_write_req_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u8 report; /* CP2112_DATA_WRITE_REQUEST */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 slave_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) u8 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 data[61];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct cp2112_force_read_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) u8 report; /* CP2112_DATA_READ_FORCE_SEND */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) __be16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct cp2112_xfer_status_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u8 report; /* CP2112_TRANSFER_STATUS_RESPONSE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u8 status0; /* STATUS0_* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) u8 status1; /* STATUS1_* */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) __be16 retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) __be16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) struct cp2112_string_report {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) u8 dummy; /* force .string to be aligned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u8 report; /* CP2112_*_STRING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) u8 length; /* length in bytes of everyting after .report */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u8 type; /* USB_DT_STRING */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) wchar_t string[30]; /* UTF16_LITTLE_ENDIAN string */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* Number of times to request transfer status before giving up waiting for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) transfer to complete. This may need to be changed if SMBUS clock, retries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) or read/write/scl_low timeout settings are changed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static const int XFER_STATUS_RETRIES = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Time in ms to wait for a CP2112_DATA_READ_RESPONSE or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) CP2112_TRANSFER_STATUS_RESPONSE. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static const int RESPONSE_TIMEOUT = 50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static const struct hid_device_id cp2112_devices[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) { HID_USB_DEVICE(USB_VENDOR_ID_CYGNAL, USB_DEVICE_ID_CYGNAL_CP2112) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) MODULE_DEVICE_TABLE(hid, cp2112_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) struct cp2112_device {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) struct i2c_adapter adap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct hid_device *hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) wait_queue_head_t wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u8 read_data[61];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) u8 read_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u8 hwversion;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int xfer_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) atomic_t read_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) atomic_t xfer_avail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct gpio_chip gc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct irq_chip irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) u8 *in_out_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct gpio_desc *desc[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) bool gpio_poll;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) struct delayed_work gpio_poll_worker;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) unsigned long irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) u8 gpio_prev_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static int gpio_push_pull = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) module_param(gpio_push_pull, int, S_IRUGO | S_IWUSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) MODULE_PARM_DESC(gpio_push_pull, "GPIO push-pull configuration bitmask");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static int cp2112_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct cp2112_device *dev = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) u8 *buf = dev->in_out_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret != CP2112_GPIO_CONFIG_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) hid_err(hdev, "error requesting GPIO config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) buf[1] &= ~(1 << offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) buf[2] = gpio_push_pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (ret != CP2112_GPIO_CONFIG_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) hid_err(hdev, "error setting GPIO config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void cp2112_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct cp2112_device *dev = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) u8 *buf = dev->in_out_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) buf[0] = CP2112_GPIO_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) buf[1] = value ? 0xff : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) buf[2] = 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = hid_hw_raw_request(hdev, CP2112_GPIO_SET, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) CP2112_GPIO_SET_LENGTH, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) hid_err(hdev, "error setting GPIO values: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int cp2112_gpio_get_all(struct gpio_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct cp2112_device *dev = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) u8 *buf = dev->in_out_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ret = hid_hw_raw_request(hdev, CP2112_GPIO_GET, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) CP2112_GPIO_GET_LENGTH, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (ret != CP2112_GPIO_GET_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) hid_err(hdev, "error requesting GPIO values: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ret = ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ret = buf[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) static int cp2112_gpio_get(struct gpio_chip *chip, unsigned int offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = cp2112_gpio_get_all(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return (ret >> offset) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static int cp2112_gpio_direction_output(struct gpio_chip *chip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) unsigned offset, int value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct cp2112_device *dev = gpiochip_get_data(chip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u8 *buf = dev->in_out_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (ret != CP2112_GPIO_CONFIG_LENGTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) hid_err(hdev, "error requesting GPIO config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) buf[1] |= 1 << offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) buf[2] = gpio_push_pull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = hid_hw_raw_request(hdev, CP2112_GPIO_CONFIG, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) CP2112_GPIO_CONFIG_LENGTH, HID_FEATURE_REPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) hid_err(hdev, "error setting GPIO config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * Set gpio value when output direction is already set,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * as specified in AN495, Rev. 0.2, cpt. 4.4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) cp2112_gpio_set(chip, offset, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return ret < 0 ? ret : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) static int cp2112_hid_get(struct hid_device *hdev, unsigned char report_number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) u8 *data, size_t count, unsigned char report_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) buf = kmalloc(count, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) ret = hid_hw_raw_request(hdev, report_number, buf, count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) report_type, HID_REQ_GET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) memcpy(data, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int cp2112_hid_output(struct hid_device *hdev, u8 *data, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) unsigned char report_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u8 *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) buf = kmemdup(data, count, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (report_type == HID_OUTPUT_REPORT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) ret = hid_hw_output_report(hdev, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = hid_hw_raw_request(hdev, buf[0], buf, count, report_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) HID_REQ_SET_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) kfree(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) static int cp2112_wait(struct cp2112_device *dev, atomic_t *avail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* We have sent either a CP2112_TRANSFER_STATUS_REQUEST or a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * CP2112_DATA_READ_FORCE_SEND and we are waiting for the response to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * come in cp2112_raw_event or timeout. There will only be one of these
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * in flight at any one time. The timeout is extremely large and is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * last resort if the CP2112 has died. If we do timeout we don't expect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * to receive the response which would cause data races, it's not like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * we can do anything about it anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) ret = wait_event_interruptible_timeout(dev->wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) atomic_read(avail), msecs_to_jiffies(RESPONSE_TIMEOUT));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (-ERESTARTSYS == ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) atomic_set(avail, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) static int cp2112_xfer_status(struct cp2112_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) buf[0] = CP2112_TRANSFER_STATUS_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) buf[1] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) atomic_set(&dev->xfer_avail, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) hid_warn(hdev, "Error requesting status: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) ret = cp2112_wait(dev, &dev->xfer_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return dev->xfer_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static int cp2112_read(struct cp2112_device *dev, u8 *data, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct cp2112_force_read_report report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (size > sizeof(dev->read_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) size = sizeof(dev->read_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) report.report = CP2112_DATA_READ_FORCE_SEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) report.length = cpu_to_be16(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) atomic_set(&dev->read_avail, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) ret = cp2112_hid_output(hdev, &report.report, sizeof(report),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) hid_warn(hdev, "Error requesting data: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) ret = cp2112_wait(dev, &dev->read_avail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) hid_dbg(hdev, "read %d of %zd bytes requested\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) dev->read_length, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if (size > dev->read_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) size = dev->read_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) memcpy(data, dev->read_data, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) return dev->read_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int cp2112_read_req(void *buf, u8 slave_address, u16 length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct cp2112_read_req_report *report = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (length < 1 || length > 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) report->report = CP2112_DATA_READ_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) report->slave_address = slave_address << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) report->length = cpu_to_be16(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return sizeof(*report);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static int cp2112_write_read_req(void *buf, u8 slave_address, u16 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) u8 command, u8 *data, u8 data_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct cp2112_write_read_req_report *report = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (length < 1 || length > 512
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) || data_length > sizeof(report->target_address) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) report->report = CP2112_DATA_WRITE_READ_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) report->slave_address = slave_address << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) report->length = cpu_to_be16(length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) report->target_address_length = data_length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) report->target_address[0] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) memcpy(&report->target_address[1], data, data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return data_length + 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) static int cp2112_write_req(void *buf, u8 slave_address, u8 command, u8 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u8 data_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct cp2112_write_req_report *report = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) if (data_length > sizeof(report->data) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) report->report = CP2112_DATA_WRITE_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) report->slave_address = slave_address << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) report->length = data_length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) report->data[0] = command;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) memcpy(&report->data[1], data, data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return data_length + 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int cp2112_i2c_write_req(void *buf, u8 slave_address, u8 *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) u8 data_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) struct cp2112_write_req_report *report = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (data_length > sizeof(report->data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) report->report = CP2112_DATA_WRITE_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) report->slave_address = slave_address << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) report->length = data_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) memcpy(report->data, data, data_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return data_length + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) static int cp2112_i2c_write_read_req(void *buf, u8 slave_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) u8 *addr, int addr_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) int read_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct cp2112_write_read_req_report *report = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) if (read_length < 1 || read_length > 512 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) addr_length > sizeof(report->target_address))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) report->report = CP2112_DATA_WRITE_READ_REQUEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) report->slave_address = slave_address << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) report->length = cpu_to_be16(read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) report->target_address_length = addr_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) memcpy(report->target_address, addr, addr_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return addr_length + 5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static int cp2112_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int num)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) u8 buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ssize_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) ssize_t read_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u8 *read_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) unsigned int retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) hid_dbg(hdev, "I2C %d messages\n", num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (num == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) if (msgs->flags & I2C_M_RD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) hid_dbg(hdev, "I2C read %#04x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) msgs->addr, msgs->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) read_length = msgs->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) read_buf = msgs->buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) count = cp2112_read_req(buf, msgs->addr, msgs->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) hid_dbg(hdev, "I2C write %#04x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) msgs->addr, msgs->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) count = cp2112_i2c_write_req(buf, msgs->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) msgs->buf, msgs->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } else if (dev->hwversion > 1 && /* no repeated start in rev 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) num == 2 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) msgs[0].addr == msgs[1].addr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) !(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) hid_dbg(hdev, "I2C write-read %#04x wlen %d rlen %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) msgs[0].addr, msgs[0].len, msgs[1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) read_length = msgs[1].len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) read_buf = msgs[1].buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) count = cp2112_i2c_write_read_req(buf, msgs[0].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) msgs[0].buf, msgs[0].len, msgs[1].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) hid_err(hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) "Multi-message I2C transactions not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ret = hid_hw_power(hdev, PM_HINT_FULLON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) hid_err(hdev, "power management error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) ret = cp2112_hid_output(hdev, buf, count, HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) hid_warn(hdev, "Error starting transaction: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) for (retries = 0; retries < XFER_STATUS_RETRIES; ++retries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) ret = cp2112_xfer_status(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (-EBUSY == ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (XFER_STATUS_RETRIES <= retries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) hid_warn(hdev, "Transfer timed out, cancelling.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) buf[0] = CP2112_CANCEL_TRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) buf[1] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) hid_warn(hdev, "Error cancelling transaction: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) for (count = 0; count < read_length;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ret = cp2112_read(dev, read_buf + count, read_length - count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (ret == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) hid_err(hdev, "read returned 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) count += ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (count > read_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * The hardware returned too much data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * This is mostly harmless because cp2112_read()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * has a limit check so didn't overrun our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * buffer. Nevertheless, we return an error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * because something is seriously wrong and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * it shouldn't go unnoticed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) hid_err(hdev, "long read: %d > %zd\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) ret, read_length - count + ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* return the number of transferred messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) ret = num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) power_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) hid_hw_power(hdev, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) hid_dbg(hdev, "I2C transfer finished: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static int cp2112_xfer(struct i2c_adapter *adap, u16 addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) unsigned short flags, char read_write, u8 command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int size, union i2c_smbus_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct cp2112_device *dev = (struct cp2112_device *)adap->algo_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct hid_device *hdev = dev->hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) u8 buf[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) __le16 word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) ssize_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) size_t read_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) unsigned int retries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) hid_dbg(hdev, "%s addr 0x%x flags 0x%x cmd 0x%x size %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) read_write == I2C_SMBUS_WRITE ? "write" : "read",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) addr, flags, command, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) case I2C_SMBUS_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) read_length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (I2C_SMBUS_READ == read_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) count = cp2112_read_req(buf, addr, read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) count = cp2112_write_req(buf, addr, command, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) case I2C_SMBUS_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) read_length = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) if (I2C_SMBUS_READ == read_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) count = cp2112_write_read_req(buf, addr, read_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) command, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) count = cp2112_write_req(buf, addr, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) &data->byte, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) case I2C_SMBUS_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) read_length = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) word = cpu_to_le16(data->word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (I2C_SMBUS_READ == read_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) count = cp2112_write_read_req(buf, addr, read_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) command, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) count = cp2112_write_req(buf, addr, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) (u8 *)&word, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) case I2C_SMBUS_PROC_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) size = I2C_SMBUS_WORD_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) read_write = I2C_SMBUS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) read_length = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) word = cpu_to_le16(data->word);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) count = cp2112_write_read_req(buf, addr, read_length, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) (u8 *)&word, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case I2C_SMBUS_I2C_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (read_write == I2C_SMBUS_READ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) read_length = data->block[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) count = cp2112_write_read_req(buf, addr, read_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) command, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) count = cp2112_write_req(buf, addr, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) data->block + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) data->block[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) case I2C_SMBUS_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (I2C_SMBUS_READ == read_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) count = cp2112_write_read_req(buf, addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) I2C_SMBUS_BLOCK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) command, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) count = cp2112_write_req(buf, addr, command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) data->block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) data->block[0] + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) case I2C_SMBUS_BLOCK_PROC_CALL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) size = I2C_SMBUS_BLOCK_DATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) read_write = I2C_SMBUS_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) count = cp2112_write_read_req(buf, addr, I2C_SMBUS_BLOCK_MAX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) command, data->block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) data->block[0] + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) hid_warn(hdev, "Unsupported transaction %d\n", size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (count < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) ret = hid_hw_power(hdev, PM_HINT_FULLON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) hid_err(hdev, "power management error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ret = cp2112_hid_output(hdev, buf, count, HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) hid_warn(hdev, "Error starting transaction: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) for (retries = 0; retries < XFER_STATUS_RETRIES; ++retries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ret = cp2112_xfer_status(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) if (-EBUSY == ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (XFER_STATUS_RETRIES <= retries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) hid_warn(hdev, "Transfer timed out, cancelling.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) buf[0] = CP2112_CANCEL_TRANSFER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) buf[1] = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ret = cp2112_hid_output(hdev, buf, 2, HID_OUTPUT_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) hid_warn(hdev, "Error cancelling transaction: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) if (I2C_SMBUS_WRITE == read_write) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) if (I2C_SMBUS_BLOCK_DATA == size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) read_length = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) ret = cp2112_read(dev, buf, read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (ret != read_length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) hid_warn(hdev, "short read: %d < %zd\n", ret, read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case I2C_SMBUS_BYTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) case I2C_SMBUS_BYTE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) data->byte = buf[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case I2C_SMBUS_WORD_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) data->word = le16_to_cpup((__le16 *)buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) case I2C_SMBUS_I2C_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) memcpy(data->block + 1, buf, read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) case I2C_SMBUS_BLOCK_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (read_length > I2C_SMBUS_BLOCK_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) ret = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) goto power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) memcpy(data->block, buf, read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) power_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) hid_hw_power(hdev, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) hid_dbg(hdev, "transfer finished: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static u32 cp2112_functionality(struct i2c_adapter *adap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) return I2C_FUNC_I2C |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) I2C_FUNC_SMBUS_BYTE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) I2C_FUNC_SMBUS_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) I2C_FUNC_SMBUS_WORD_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) I2C_FUNC_SMBUS_BLOCK_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) I2C_FUNC_SMBUS_I2C_BLOCK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) I2C_FUNC_SMBUS_PROC_CALL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) I2C_FUNC_SMBUS_BLOCK_PROC_CALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) static const struct i2c_algorithm smbus_algorithm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) .master_xfer = cp2112_i2c_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) .smbus_xfer = cp2112_xfer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) .functionality = cp2112_functionality,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) static int cp2112_get_usb_config(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct cp2112_usb_config_report *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = cp2112_hid_get(hdev, CP2112_USB_CONFIG, (u8 *)cfg, sizeof(*cfg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (ret != sizeof(*cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) hid_err(hdev, "error reading usb config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static int cp2112_set_usb_config(struct hid_device *hdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct cp2112_usb_config_report *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) BUG_ON(cfg->report != CP2112_USB_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) ret = cp2112_hid_output(hdev, (u8 *)cfg, sizeof(*cfg),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (ret != sizeof(*cfg)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) hid_err(hdev, "error writing usb config: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) static void chmod_sysfs_attrs(struct hid_device *hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) #define CP2112_CONFIG_ATTR(name, store, format, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) static ssize_t name##_store(struct device *kdev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct device_attribute *attr, const char *buf, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) size_t count) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct hid_device *hdev = to_hid_device(kdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) struct cp2112_usb_config_report cfg; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) int ret = cp2112_get_usb_config(hdev, &cfg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) if (ret) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) return ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) store; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) ret = cp2112_set_usb_config(hdev, &cfg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) if (ret) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) return ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) chmod_sysfs_attrs(hdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return count; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static ssize_t name##_show(struct device *kdev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct device_attribute *attr, char *buf) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct hid_device *hdev = to_hid_device(kdev); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) struct cp2112_usb_config_report cfg; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) int ret = cp2112_get_usb_config(hdev, &cfg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (ret) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) return ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return scnprintf(buf, PAGE_SIZE, format, ##__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) static DEVICE_ATTR_RW(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) CP2112_CONFIG_ATTR(vendor_id, ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) u16 vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (sscanf(buf, "%hi", &vid) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) cfg.vid = cpu_to_le16(vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) cfg.mask = 0x01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }), "0x%04x\n", le16_to_cpu(cfg.vid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) CP2112_CONFIG_ATTR(product_id, ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) u16 pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (sscanf(buf, "%hi", &pid) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) cfg.pid = cpu_to_le16(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) cfg.mask = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }), "0x%04x\n", le16_to_cpu(cfg.pid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) CP2112_CONFIG_ATTR(max_power, ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) int mA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (sscanf(buf, "%i", &mA) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) cfg.max_power = (mA + 1) / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) cfg.mask = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }), "%u mA\n", cfg.max_power * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) CP2112_CONFIG_ATTR(power_mode, ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (sscanf(buf, "%hhi", &cfg.power_mode) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) cfg.mask = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }), "%u\n", cfg.power_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) CP2112_CONFIG_ATTR(release_version, ({
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (sscanf(buf, "%hhi.%hhi", &cfg.release_major, &cfg.release_minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) != 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) cfg.mask = 0x10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }), "%u.%u\n", cfg.release_major, cfg.release_minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) #undef CP2112_CONFIG_ATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct cp2112_pstring_attribute {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct device_attribute attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) unsigned char report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) static ssize_t pstr_store(struct device *kdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct device_attribute *kattr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) struct hid_device *hdev = to_hid_device(kdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) struct cp2112_pstring_attribute *attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) container_of(kattr, struct cp2112_pstring_attribute, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct cp2112_string_report report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) memset(&report, 0, sizeof(report));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) ret = utf8s_to_utf16s(buf, count, UTF16_LITTLE_ENDIAN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) report.string, ARRAY_SIZE(report.string));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) report.report = attr->report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) report.length = ret * sizeof(report.string[0]) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) report.type = USB_DT_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) ret = cp2112_hid_output(hdev, &report.report, report.length + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (ret != report.length + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) hid_err(hdev, "error writing %s string: %d\n", kattr->attr.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) chmod_sysfs_attrs(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) static ssize_t pstr_show(struct device *kdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct device_attribute *kattr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct hid_device *hdev = to_hid_device(kdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct cp2112_pstring_attribute *attr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) container_of(kattr, struct cp2112_pstring_attribute, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct cp2112_string_report report;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) u8 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) ret = cp2112_hid_get(hdev, attr->report, &report.report,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) sizeof(report) - 1, HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (ret < 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) hid_err(hdev, "error reading %s string: %d\n", kattr->attr.name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (report.length < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) hid_err(hdev, "invalid %s string length: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) kattr->attr.name, report.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) length = report.length > ret - 1 ? ret - 1 : report.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) length = (length - 2) / sizeof(report.string[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ret = utf16s_to_utf8s(report.string, length, UTF16_LITTLE_ENDIAN, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) PAGE_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) buf[ret++] = '\n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) #define CP2112_PSTR_ATTR(name, _report) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static struct cp2112_pstring_attribute dev_attr_##name = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) .attr = __ATTR(name, (S_IWUSR | S_IRUGO), pstr_show, pstr_store), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) .report = _report, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) CP2112_PSTR_ATTR(manufacturer, CP2112_MANUFACTURER_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) CP2112_PSTR_ATTR(product, CP2112_PRODUCT_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) CP2112_PSTR_ATTR(serial, CP2112_SERIAL_STRING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) #undef CP2112_PSTR_ATTR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static const struct attribute_group cp2112_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) .attrs = (struct attribute *[]){
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) &dev_attr_vendor_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) &dev_attr_product_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) &dev_attr_max_power.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) &dev_attr_power_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) &dev_attr_release_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) &dev_attr_manufacturer.attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) &dev_attr_product.attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) &dev_attr_serial.attr.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) /* Chmoding our sysfs attributes is simply a way to expose which fields in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) * PROM have already been programmed. We do not depend on this preventing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * writing to these attributes since the CP2112 will simply ignore writes to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * already-programmed fields. This is why there is no sense in fixing this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * racy behaviour.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void chmod_sysfs_attrs(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct attribute **attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) u8 buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ret = cp2112_hid_get(hdev, CP2112_LOCK_BYTE, buf, sizeof(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) if (ret != sizeof(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) hid_err(hdev, "error reading lock byte: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) for (attr = cp2112_attr_group.attrs; *attr; ++attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) umode_t mode = (buf[1] & 1) ? S_IWUSR | S_IRUGO : S_IRUGO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) ret = sysfs_chmod_file(&hdev->dev.kobj, *attr, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) hid_err(hdev, "error chmoding sysfs file %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) (*attr)->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) buf[1] >>= 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) static void cp2112_gpio_irq_ack(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static void cp2112_gpio_irq_mask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct cp2112_device *dev = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) __clear_bit(d->hwirq, &dev->irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) static void cp2112_gpio_irq_unmask(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) struct cp2112_device *dev = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) __set_bit(d->hwirq, &dev->irq_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void cp2112_gpio_poll_callback(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct cp2112_device *dev = container_of(work, struct cp2112_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) gpio_poll_worker.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct irq_data *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) u8 gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) u8 virqs = (u8)dev->irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) u32 irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) int irq, virq, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ret = cp2112_gpio_get_all(&dev->gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) if (ret == -ENODEV) /* the hardware has been disconnected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) gpio_mask = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) while (virqs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) virq = ffs(virqs) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) virqs &= ~BIT(virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (!dev->gc.to_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) irq = dev->gc.to_irq(&dev->gc, virq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) d = irq_get_irq_data(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) if (!d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) irq_type = irqd_get_trigger_type(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (gpio_mask & BIT(virq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) /* Level High */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (irq_type & IRQ_TYPE_LEVEL_HIGH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) handle_nested_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) if ((irq_type & IRQ_TYPE_EDGE_RISING) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) !(dev->gpio_prev_state & BIT(virq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) handle_nested_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) /* Level Low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (irq_type & IRQ_TYPE_LEVEL_LOW)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) handle_nested_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if ((irq_type & IRQ_TYPE_EDGE_FALLING) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) (dev->gpio_prev_state & BIT(virq)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) handle_nested_irq(irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) dev->gpio_prev_state = gpio_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (dev->gpio_poll)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) schedule_delayed_work(&dev->gpio_poll_worker, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static unsigned int cp2112_gpio_irq_startup(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) struct cp2112_device *dev = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) INIT_DELAYED_WORK(&dev->gpio_poll_worker, cp2112_gpio_poll_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (!dev->gpio_poll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) dev->gpio_poll = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) schedule_delayed_work(&dev->gpio_poll_worker, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) cp2112_gpio_irq_unmask(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) static void cp2112_gpio_irq_shutdown(struct irq_data *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) struct cp2112_device *dev = gpiochip_get_data(gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) cancel_delayed_work_sync(&dev->gpio_poll_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) static int cp2112_gpio_irq_type(struct irq_data *d, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) static int __maybe_unused cp2112_allocate_irq(struct cp2112_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) int pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) if (dev->desc[pin])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) dev->desc[pin] = gpiochip_request_own_desc(&dev->gc, pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) "HID/I2C:Event",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) GPIO_ACTIVE_HIGH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) if (IS_ERR(dev->desc[pin])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) dev_err(dev->gc.parent, "Failed to request GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return PTR_ERR(dev->desc[pin]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) ret = cp2112_gpio_direction_input(&dev->gc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) dev_err(dev->gc.parent, "Failed to set GPIO to input dir\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) goto err_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ret = gpiochip_lock_as_irq(&dev->gc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) dev_err(dev->gc.parent, "Failed to lock GPIO as interrupt\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) goto err_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ret = gpiod_to_irq(dev->desc[pin]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) dev_err(dev->gc.parent, "Failed to translate GPIO to IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) goto err_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) err_lock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) gpiochip_unlock_as_irq(&dev->gc, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) err_desc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) gpiochip_free_own_desc(dev->desc[pin]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) dev->desc[pin] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) static int cp2112_probe(struct hid_device *hdev, const struct hid_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) struct cp2112_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) u8 buf[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) struct cp2112_smbus_config_report config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) struct gpio_irq_chip *girq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) dev = devm_kzalloc(&hdev->dev, sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) dev->in_out_buffer = devm_kzalloc(&hdev->dev, CP2112_REPORT_MAX_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) if (!dev->in_out_buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) mutex_init(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) ret = hid_parse(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) hid_err(hdev, "parse failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) hid_err(hdev, "hw start failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) ret = hid_hw_open(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) hid_err(hdev, "hw open failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) goto err_hid_stop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) ret = hid_hw_power(hdev, PM_HINT_FULLON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) hid_err(hdev, "power management error: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) goto err_hid_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) ret = cp2112_hid_get(hdev, CP2112_GET_VERSION_INFO, buf, sizeof(buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (ret != sizeof(buf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) hid_err(hdev, "error requesting version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) goto err_power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) hid_info(hdev, "Part Number: 0x%02X Device Version: 0x%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) buf[1], buf[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) ret = cp2112_hid_get(hdev, CP2112_SMBUS_CONFIG, (u8 *)&config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) sizeof(config), HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (ret != sizeof(config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) hid_err(hdev, "error requesting SMBus config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) goto err_power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) config.retry_time = cpu_to_be16(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ret = cp2112_hid_output(hdev, (u8 *)&config, sizeof(config),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) HID_FEATURE_REPORT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) if (ret != sizeof(config)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) hid_err(hdev, "error setting SMBus config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) goto err_power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) hid_set_drvdata(hdev, (void *)dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) dev->hdev = hdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) dev->adap.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) dev->adap.class = I2C_CLASS_HWMON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) dev->adap.algo = &smbus_algorithm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) dev->adap.algo_data = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) dev->adap.dev.parent = &hdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) snprintf(dev->adap.name, sizeof(dev->adap.name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) "CP2112 SMBus Bridge on hidraw%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) ((struct hidraw *)hdev->hidraw)->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) dev->hwversion = buf[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) init_waitqueue_head(&dev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) hid_device_io_start(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) ret = i2c_add_adapter(&dev->adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) hid_device_io_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) hid_err(hdev, "error registering i2c adapter\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) goto err_power_normal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) hid_dbg(hdev, "adapter registered\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) dev->gc.label = "cp2112_gpio";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) dev->gc.direction_input = cp2112_gpio_direction_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) dev->gc.direction_output = cp2112_gpio_direction_output;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) dev->gc.set = cp2112_gpio_set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) dev->gc.get = cp2112_gpio_get;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) dev->gc.base = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) dev->gc.ngpio = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) dev->gc.can_sleep = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) dev->gc.parent = &hdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) dev->irq.name = "cp2112-gpio";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) dev->irq.irq_startup = cp2112_gpio_irq_startup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) dev->irq.irq_shutdown = cp2112_gpio_irq_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) dev->irq.irq_ack = cp2112_gpio_irq_ack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) dev->irq.irq_mask = cp2112_gpio_irq_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) dev->irq.irq_unmask = cp2112_gpio_irq_unmask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dev->irq.irq_set_type = cp2112_gpio_irq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) dev->irq.flags = IRQCHIP_MASK_ON_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) girq = &dev->gc.irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) girq->chip = &dev->irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /* The event comes from the outside so no parent handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) girq->parent_handler = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) girq->num_parents = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) girq->parents = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) girq->default_type = IRQ_TYPE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) girq->handler = handle_simple_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) ret = gpiochip_add_data(&dev->gc, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) hid_err(hdev, "error registering gpio chip\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) goto err_free_i2c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) ret = sysfs_create_group(&hdev->dev.kobj, &cp2112_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) hid_err(hdev, "error creating sysfs attrs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) goto err_gpiochip_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) chmod_sysfs_attrs(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) hid_hw_power(hdev, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) err_gpiochip_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) gpiochip_remove(&dev->gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) err_free_i2c:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) i2c_del_adapter(&dev->adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) err_power_normal:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) hid_hw_power(hdev, PM_HINT_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) err_hid_close:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) hid_hw_close(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) err_hid_stop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) static void cp2112_remove(struct hid_device *hdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) struct cp2112_device *dev = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) sysfs_remove_group(&hdev->dev.kobj, &cp2112_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) i2c_del_adapter(&dev->adap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (dev->gpio_poll) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) dev->gpio_poll = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) cancel_delayed_work_sync(&dev->gpio_poll_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) for (i = 0; i < ARRAY_SIZE(dev->desc); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) gpiochip_unlock_as_irq(&dev->gc, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) gpiochip_free_own_desc(dev->desc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) gpiochip_remove(&dev->gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) /* i2c_del_adapter has finished removing all i2c devices from our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) * adapter. Well behaved devices should no longer call our cp2112_xfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) * and should have waited for any pending calls to finish. It has also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) * waited for device_unregister(&adap->dev) to complete. Therefore we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) * can safely free our struct cp2112_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) hid_hw_close(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) hid_hw_stop(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) static int cp2112_raw_event(struct hid_device *hdev, struct hid_report *report,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) u8 *data, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) struct cp2112_device *dev = hid_get_drvdata(hdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) struct cp2112_xfer_status_report *xfer = (void *)data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) switch (data[0]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) case CP2112_TRANSFER_STATUS_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) hid_dbg(hdev, "xfer status: %02x %02x %04x %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) xfer->status0, xfer->status1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) be16_to_cpu(xfer->retries), be16_to_cpu(xfer->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) switch (xfer->status0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) case STATUS0_IDLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) dev->xfer_status = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) case STATUS0_BUSY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) dev->xfer_status = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) case STATUS0_COMPLETE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) dev->xfer_status = be16_to_cpu(xfer->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) case STATUS0_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) switch (xfer->status1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) case STATUS1_TIMEOUT_NACK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) case STATUS1_TIMEOUT_BUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) dev->xfer_status = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) dev->xfer_status = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) dev->xfer_status = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) atomic_set(&dev->xfer_avail, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) case CP2112_DATA_READ_RESPONSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) hid_dbg(hdev, "read response: %02x %02x\n", data[1], data[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) dev->read_length = data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) if (dev->read_length > sizeof(dev->read_data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) dev->read_length = sizeof(dev->read_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) memcpy(dev->read_data, &data[3], dev->read_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) atomic_set(&dev->read_avail, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) hid_err(hdev, "unknown report\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) wake_up_interruptible(&dev->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) static struct hid_driver cp2112_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) .name = "cp2112",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) .id_table = cp2112_devices,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) .probe = cp2112_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) .remove = cp2112_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) .raw_event = cp2112_raw_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) module_hid_driver(cp2112_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) MODULE_DESCRIPTION("Silicon Labs HID USB to SMBus master bridge");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) MODULE_AUTHOR("David Barksdale <dbarksdale@uplogix.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)