linux/drivers/hid/hid-ft260.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * hid-ft260.c - FTDI FT260 USB HID to I2C host bridge
 *
 * Copyright (c) 2021, Michael Zaidman <[email protected]>
 *
 * Data Sheet:
 *   https://www.ftdichip.com/Support/Documents/DataSheets/ICs/DS_FT260.pdf
 */

#include "hid-ids.h"
#include <linux/hidraw.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/usb.h>

#ifdef DEBUG
static int ft260_debug = 1;
#else
static int ft260_debug;
#endif
module_param_named(debug, ft260_debug, int, 0600);
MODULE_PARM_DESC();

#define ft260_dbg(format, arg...)

#define FT260_REPORT_MAX_LENGTH
#define FT260_I2C_DATA_REPORT_ID(len)

#define FT260_WAKEUP_NEEDED_AFTER_MS

/*
 * The ft260 input report format defines 62 bytes for the data payload, but
 * when requested 62 bytes, the controller returns 60 and 2 in separate input
 * reports. To achieve better performance with the multi-report read data
 * transfers, we set the maximum read payload length to a multiple of 60.
 * With a 100 kHz I2C clock, one 240 bytes read takes about 1/27 second,
 * which is excessive; On the other hand, some higher layer drivers like at24
 * or optoe limit the i2c reads to 128 bytes. To not block other drivers out
 * of I2C for potentially troublesome amounts of time, we select the maximum
 * read payload length to be 180 bytes.
*/
#define FT260_RD_DATA_MAX
#define FT260_WR_DATA_MAX

/*
 * Device interface configuration.
 * The FT260 has 2 interfaces that are controlled by DCNF0 and DCNF1 pins.
 * First implementes USB HID to I2C bridge function and
 * second - USB HID to UART bridge function.
 */
enum {};

/* Control pipe */
enum {};

/* Report IDs / Feature In */
enum {};

/* Feature Out */
enum {};

/* Response codes in I2C status report */
enum {};

/* I2C Conditions flags */
enum {};

#define FT260_SET_REQUEST_VALUE(report_id)

/* Feature In reports */

struct ft260_get_chip_version_report {} __packed;

struct ft260_get_system_status_report {} __packed;

struct ft260_get_i2c_status_report {} __packed;

/* Feature Out reports */

struct ft260_set_system_clock_report {} __packed;

struct ft260_set_i2c_mode_report {} __packed;

struct ft260_set_uart_mode_report {} __packed;

struct ft260_set_i2c_reset_report {} __packed;

struct ft260_set_i2c_speed_report {} __packed;

/* Data transfer reports */

struct ft260_i2c_write_request_report {} __packed;

struct ft260_i2c_read_request_report {} __packed;

struct ft260_i2c_input_report {} __packed;

static const struct hid_device_id ft260_devices[] =;
MODULE_DEVICE_TABLE(hid, ft260_devices);

struct ft260_device {};

static int ft260_hid_feature_report_get(struct hid_device *hdev,
					unsigned char report_id, u8 *data,
					size_t len)
{}

static int ft260_hid_feature_report_set(struct hid_device *hdev, u8 *data,
					size_t len)
{}

static int ft260_i2c_reset(struct hid_device *hdev)
{}

static int ft260_xfer_status(struct ft260_device *dev, u8 bus_busy)
{}

static int ft260_hid_output_report(struct hid_device *hdev, u8 *data,
				   size_t len)
{}

static int ft260_hid_output_report_check_status(struct ft260_device *dev,
						u8 *data, int len)
{}

static int ft260_i2c_write(struct ft260_device *dev, u8 addr, u8 *data,
			   int len, u8 flag)
{}

static int ft260_smbus_write(struct ft260_device *dev, u8 addr, u8 cmd,
			     u8 *data, u8 data_len, u8 flag)
{}

static int ft260_i2c_read(struct ft260_device *dev, u8 addr, u8 *data,
			  u16 len, u8 flag)
{}

/*
 * A random read operation is implemented as a dummy write operation, followed
 * by a current address read operation. The dummy write operation is used to
 * load the target byte address into the current byte address counter, from
 * which the subsequent current address read operation then reads.
 */
static int ft260_i2c_write_read(struct ft260_device *dev, struct i2c_msg *msgs)
{}

static int ft260_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
			  int num)
{}

static int ft260_smbus_xfer(struct i2c_adapter *adapter, u16 addr, u16 flags,
			    char read_write, u8 cmd, int size,
			    union i2c_smbus_data *data)
{}

static u32 ft260_functionality(struct i2c_adapter *adap)
{}

static const struct i2c_adapter_quirks ft260_i2c_quirks =;

static const struct i2c_algorithm ft260_i2c_algo =;

static int ft260_get_system_config(struct hid_device *hdev,
				   struct ft260_get_system_status_report *cfg)
{}

static int ft260_is_interface_enabled(struct hid_device *hdev)
{}

static int ft260_byte_show(struct hid_device *hdev, int id, u8 *cfg, int len,
			   u8 *field, u8 *buf)
{}

static int ft260_word_show(struct hid_device *hdev, int id, u8 *cfg, int len,
			   __le16 *field, u8 *buf)
{}

#define FT260_ATTR_SHOW(name, reptype, id, type, func)

#define FT260_SSTAT_ATTR_SHOW(name)

#define FT260_I2CST_ATTR_SHOW(name)

#define FT260_ATTR_STORE(name, reptype, id, req, type, ctype, func)

#define FT260_BYTE_ATTR_STORE(name, reptype, req)

#define FT260_WORD_ATTR_STORE(name, reptype, req)

FT260_SSTAT_ATTR_SHOW(chip_mode);
static DEVICE_ATTR_RO(chip_mode);

FT260_SSTAT_ATTR_SHOW(pwren_status);
static DEVICE_ATTR_RO(pwren_status);

FT260_SSTAT_ATTR_SHOW(suspend_status);
static DEVICE_ATTR_RO(suspend_status);

FT260_SSTAT_ATTR_SHOW(hid_over_i2c_en);
static DEVICE_ATTR_RO(hid_over_i2c_en);

FT260_SSTAT_ATTR_SHOW(power_saving_en);
static DEVICE_ATTR_RO(power_saving_en);

FT260_SSTAT_ATTR_SHOW(i2c_enable);
FT260_BYTE_ATTR_STORE(i2c_enable, ft260_set_i2c_mode_report,
		      FT260_SET_I2C_MODE);
static DEVICE_ATTR_RW(i2c_enable);

FT260_SSTAT_ATTR_SHOW(uart_mode);
FT260_BYTE_ATTR_STORE(uart_mode, ft260_set_uart_mode_report,
		      FT260_SET_UART_MODE);
static DEVICE_ATTR_RW(uart_mode);

FT260_SSTAT_ATTR_SHOW(clock_ctl);
FT260_BYTE_ATTR_STORE(clock_ctl, ft260_set_system_clock_report,
		      FT260_SET_CLOCK);
static DEVICE_ATTR_RW(clock_ctl);

FT260_I2CST_ATTR_SHOW(clock);
FT260_WORD_ATTR_STORE(clock, ft260_set_i2c_speed_report,
		      FT260_SET_I2C_CLOCK_SPEED);
static DEVICE_ATTR_RW(clock);

static ssize_t i2c_reset_store(struct device *kdev,
			       struct device_attribute *attr, const char *buf,
			       size_t count)
{}
static DEVICE_ATTR_WO(i2c_reset);

static const struct attribute_group ft260_attr_group =;

static int ft260_probe(struct hid_device *hdev, const struct hid_device_id *id)
{}

static void ft260_remove(struct hid_device *hdev)
{}

static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
			   u8 *data, int size)
{}

static struct hid_driver ft260_driver =;

module_hid_driver();
MODULE_DESCRIPTION();
MODULE_AUTHOR();
MODULE_LICENSE();