M7350/kernel/drivers/video/msm/mdss/mhl3/si_emsc_hid.h
2024-09-09 08:57:42 +00:00

279 lines
7.9 KiB
C

/*
* SiI8620 Linux Driver eMSC HID stuff
Copyright (C) 2013-2014 Silicon Image, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation version 2.
This program is distributed AS-IS WITHOUT ANY WARRANTY of any
kind, whether express or implied; INCLUDING without the implied warranty
of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE or NON-INFRINGEMENT.
See the GNU General Public License for more details at
http://www.gnu.org/licenses/gpl-2.0.html.
*/
/*
@file si_emsc_hid.h
*/
#ifndef _SI_EMSC_HID_H_
#define _SI_EMSC_HID_H_
#include <linux/mod_devicetable.h>
#include <linux/hid.h>
#include "si_fw_macros.h"
#include "si_app_devcap.h"
#include "si_infoframe.h"
#include "si_edid.h"
#include "si_mhl_defs.h"
#include "si_mhl2_edid_3d_api.h"
#include "si_8620_internal_api.h"
#include "si_mhl_tx_hw_drv_api.h"
#include "platform.h"
extern int debug_level;
#define MHL3_HID_DBG_ERR(...) \
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_ERR, __VA_ARGS__)
#define MHL3_HID_DBG_WARN(...) \
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_WARN, __VA_ARGS__)
#define MHL3_HID_DBG_INFO(...) \
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_INFO, __VA_ARGS__)
/* mhl3_hid_data.flags */
#define MHL3_HID_STARTED (1 << 0)
#define MHL3_HID_CONNECTED (1 << 1)
#define HID_FLAGS_WQ_ACTIVE (1 << 2)
#define HID_FLAGS_WQ_CANCEL (1 << 3)
#define MHL3_HID_PWR_ON 0x00
#define MHL3_HID_PWR_SLEEP 0x01
#define MHL3_HID_MAX_DESC_STR_LEN 256
#define MAX_HID_MESSAGE_CHANNELS 16
/* TODO: Start
* The following belongs in the kernel mod_devicetable.h file, along
* with updating the scripts/mod/file2alias.c file to match
*/
#define MHL3_NAME_SIZE 20
#define MHL3_MODULE_PREFIX "mhl3:"
struct mhl3_device_id {
char name[MHL3_NAME_SIZE];
kernel_ulong_t driver_data; /* Data private to the driver */
};
/* TODO: End */
#define HID_BURST_ID_LEN (2 + 1)
#define HID_MSG_HEADER_LEN 2
#define HID_MSG_CHKSUM_LEN 2
#define HID_FRAG_HEADER_LEN 1
#define HID_ACK_PACKET_LEN 2
#define HID_FRAG_LEN_MAX (EMSC_BLK_MAX_LENGTH - \
(EMSC_BLK_STD_HDR_LEN + \
HID_BURST_ID_LEN + \
HID_FRAG_HEADER_LEN))
#define HID_FRAG_HB0_TYPE 0x80
#define HID_FRAG_HB0_TYPE_ACK 0x80
#define HID_FRAG_HB0_CNT_MSK 0x7F
#define HID_HB0_DEV_ID_MSK 0xF0
#define HID_HB0_ACHID_MSK 0x01
#define HID_ACHID_INT 0x01
#define EMSC_HID_HB1_ACK 0x80
#define EMSC_HID_HB1_MSG_CNT_FLD 0x7F
/* HID tunneling message IDs */
#define MHL3_HID_ACK 0x00
#define MHL3_REPORT 0x01
#define MHL3_GET_REPORT_DSCRPT 0x02
#define MHL3_REPORT_DSCRPT 0x03
#define MHL3_GET_MHID_DSCRPT 0x04
#define MHL3_MHID_DSCRPT 0x05
#define MHL3_GET_REPORT 0x06
#define MHL3_SET_REPORT 0x07
#define MHL3_DSCRPT_UPDATE 0x08
/* HID_ACK values */
#define HID_ACK_SUCCESS 0x00
#define HID_ACK_NODEV 0x01
#define HID_ACK_NODATA 0x02
#define HID_ACK_WAIT 0x03
#define HID_ACK_TIMEOUT 0x04
#define HID_ACK_PROTV 0x05
#define HID_ACK_WRTYPE 0x06
#define HID_ACK_WRID 0x07
#define HID_ACK_WRFMT 0x08
#define HID_ACK_WRMFMT 0x09
/* RHID Operand Codes */
#define MHL_RHID_REQUEST_HOST 0x00
#define MHL_RHID_RELINQUISH_HOST 0x01
/* RHIDK status codes */
#define MHL_RHID_NO_ERR 0x00
#define MHL_RHID_INVALID 0x01
#define MHL_RHID_DENY 0x02
#define OP_STATE_IDLE 0x00
#define OP_STATE_WAIT_MHID_DSCRPT 0x01
#define OP_STATE_WAIT_REPORT_DSCRPT 0x02
#define OP_STATE_WAIT_REPORT 0x03
#define OP_STATE_CONNECTED 0x04
/*
* This structure cannot be directly loaded from the MHL3 HID
* MHID_DSCRPT message data because the strings are variable length
* up to 255 characters each, not the full 255 UNICODE character buffer
* defined here. Note that the structure I derived this from in the
* USB driver used __le16 in place of the __u16 used below.
*/
struct mhl3_hid_desc {
__u8 bMHL3HIDmessageID;
__u16 wHIDVendorID;
__u16 wHIDProductID;
__u8 bCountryCode;
__u16 wBcdHID;
__u16 bBcdDevice;
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u16 wLanguageID;
__u8 bProductNameSize;
__u8 bManufacturerNameSize;
__u8 bSerialNumberSize;
} __packed;
static DEFINE_MUTEX(mhl3_hid_open_mutex);
struct mhl3_hid_global_data {
/* RHID/RHIDK host-device negotiation */
uint8_t is_host; /* 1- Successfully negotiated as host */
uint8_t is_device; /* 1- Relinquished host role */
uint8_t want_host; /* 1- Want the host role */
int hid_receive_state;
uint8_t hb0;
uint8_t hb1;
uint8_t in_buf[4096]; /* This buffer is shared by all
* MHL3 HID devices. This is
* OK because device messages
* must be sent sequentially
* if it is a multi-fragment
* message so that they will
* not get mixed up. */
int msg_length;
};
struct hid_add_work_struct {
struct work_struct work;
struct mhl3_hid_data *mhid;
};
struct wq_indata_t {
uint8_t *ptr;
int buffer_size;
};
#define MAX_HID_INQUEUE 4
/* The main HID Tunneling device structure */
struct mhl3_hid_data {
struct mhl_dev_context *mdev; /* MHL driver */
struct hid_device *hid; /* pointer to HID dev */
uint8_t *in_report_buf; /* Input report buffer. */
int bufsize; /* Size of report buffer */
/* MHL3 MHID_DSCRPT message in multiple parts */
struct mhl3_hid_desc *hdesc; /* The fixed length part */
__u8 desc_product_name[MHL3_HID_MAX_DESC_STR_LEN];
__u8 desc_mfg_name[MHL3_HID_MAX_DESC_STR_LEN];
__u8 desc_serial_number[MHL3_HID_MAX_DESC_STR_LEN];
uint8_t id; /* MHL HID device ID (0-15) */
uint8_t msg_count[2]; /* MSG_CNT for each channel */
unsigned long flags; /* device flags */
/* TODO: Lee - make this a constant of the correct size or
* make this an allocated buffer.
*/
uint8_t report_desc[1024];/* Device report descriptor */
uint8_t in_data[4096]; /* Contains the last HID message
* received if it was not
* consumed directly. */
int in_data_length;
uint8_t out_data[4096]; /* Holds the MHL3 HID wrapped
* version of the HID message
* to be sent. */
int opState; /* Determines the type of HID
* messages that will be
* accepted */
/* For deferred processing */
struct hid_add_work_struct mhl3_work;
struct semaphore data_wait_lock; /* Semaphore to wait for data
* requested from the remote
* device */
};
struct SI_PACK_THIS_STRUCT mhl_hid_report_msg {
uint8_t msg_id;
uint8_t type;
uint8_t id; /* According to MHL spec 3.2, this
* byte is ONLY present for numbered
* reports, but our driver has no way
* of determining if the reports are
* numbered or not, so we ALWAYS
* use it.
*/
uint8_t len_lo;
uint8_t len_hi;
uint8_t data; /* Actually the start of variable length
* report data of length specified in
* len_hi / len_lo
*/
};
void mhl_tx_hid_host_role_request(struct mhl_dev_context *context, int request);
void mhl_tx_hid_host_negotiation(struct mhl_dev_context *context);
int mhl3_hid_report_desc_parse(struct mhl3_hid_data *mhid);
void build_received_hid_message(struct mhl_dev_context *context,
uint8_t *pmsg, int length);
void mhl3_hid_remove_all(struct mhl_dev_context *context);
int mhl3_mt_event(struct hid_device *hid, struct hid_field *field,
struct hid_usage *usage, __s32 value);
int mhl3_mt_add(struct mhl3_hid_data *mhid, struct hid_device_id *id);
int mhl3_mt_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max);
int mhl3_mt_input_mapped(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max);
void mt_feature_mapping(struct hid_device *hdev,
struct hid_field *field, struct hid_usage *usage);
void dump_array(int level, char *ptitle, uint8_t *pdata, int count);
#if (LINUX_KERNEL_VER >= 311)
void mt_input_configured(struct hid_device *hdev, struct hid_input *hi);
void mt_report(struct hid_device *hid, struct hid_report *report);
#endif
#endif /* #ifndef _SI_EMSC_HID_H_ */