mdss: mhl3: Add driver for MHL Transmitter
Code drop from https://github.com/siliconimageinc/sii8620 taken from commit 20b4c581d705cffce422bc79c2bacf7ed5363beb "Posting driver 1.03 release candidate. Version 1.03.19 Signed-off-by: Mikhail Amchislavsky <Mikhail.Amchislavsky@siliconimage.com>" Adding driver for SiI 8620 MHL transmitter. Integrated the files into drivers/video/msm/mdss/mhl3/. Removed unnecessary files: apq8074_kernel_update/apq8074-dragonboard.dtsi apq8074_kernel_update/board-8974-gpiomux.c apq8074_kernel_update/msm8974.dtsi apq8074_kernel_update/sii6031/msm_otg.c apq_build.sh build build_num.txt clean Moved files relating to SiI 6031: apq8074_kernel_update/sii6031/msm_otg.c apq8074_kernel_update/sii6031/si_6031_switch.h apq8074_kernel_update/sii6031/sii_6031/Kconfig apq8074_kernel_update/sii6031/sii_6031/Makefile apq8074_kernel_update/sii6031/sii_6031/si_6031_switch.c into drivers/video/fbdev/msm/mhl3/sii6031/. Change-Id: I29adf3bd4a02406bd9b47c0727d4093cdea94496 Signed-off-by: Casey Piper <cpiper@codeaurora.org> [cip@codeaurora.org: Moved new file locations] Signed-off-by: Clarence Ip <cip@codeaurora.org>
This commit is contained in:
parent
9d1c95d590
commit
3b9fec79f5
36 changed files with 36810 additions and 0 deletions
17
drivers/video/fbdev/msm/mhl3/Kconfig
Normal file
17
drivers/video/fbdev/msm/mhl3/Kconfig
Normal file
|
@ -0,0 +1,17 @@
|
|||
config MEDIA_DATA_TUNNEL_SUPPORT
|
||||
bool
|
||||
prompt "MHL Media Data Tunneling Support"
|
||||
default n
|
||||
---help---
|
||||
This option controls whether or not Silicon Image MHL transmitter
|
||||
drivers include support for Media Data Tunneling (MDT). MDT
|
||||
support enables HID events generated by HID devices attached to
|
||||
an MDT capable MHL sink to be passed over the MHL connection
|
||||
to the system.
|
||||
|
||||
config SII8620_MHL_TX
|
||||
tristate
|
||||
prompt "Silicon Image 8620 HDMI to MHL Tx"
|
||||
depends on I2C
|
||||
default n
|
||||
|
165
drivers/video/fbdev/msm/mhl3/Makefile
Normal file
165
drivers/video/fbdev/msm/mhl3/Makefile
Normal file
|
@ -0,0 +1,165 @@
|
|||
#
|
||||
# Makefile for the Silicon Image 8620 MHL TX device driver
|
||||
#
|
||||
# example invocations:
|
||||
# For regular Linux builds
|
||||
# make ARCH=arm CROSS_COMPILE=arm-angstrom-linux-gnueabi- clean debug
|
||||
# make ARCH=arm CROSS_COMPILE=arm-angstrom-linux-gnueabi- clean release
|
||||
# make ARCH=arm CROSS_COMPILE=arm-angstrom-linux-gnueabi- clean clean
|
||||
#
|
||||
# For Android driver builds - Specify different tool-chain and kernel revision
|
||||
# export PATH=~/rowboat-android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH
|
||||
# make ARCH=arm KERNELPATH=~/rowboat-android/kernel CROSS_COMPILE=arm-eabi- clean debug
|
||||
# make ARCH=arm KERNELPATH=~/rowboat-android/kernel CROSS_COMPILE=arm-eabi- clean release
|
||||
# make ARCH=arm KERNELPATH=~/rowboat-android/kernel CROSS_COMPILE=arm-eabi- clean clean
|
||||
#
|
||||
# For Android 4.0.3 (ICS):
|
||||
# export PATH=~/rowboat-android/TI-Android-ICS-4.0.3_AM37x_3.0.0/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin:$PATH
|
||||
# make ARCH=arm KERNELPATH=~/rowboat-android/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel CROSS_COMPILE=arm-eabi- clean debug
|
||||
# make ARCH=arm KERNELPATH=~/rowboat-android/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel CROSS_COMPILE=arm-eabi- clean release
|
||||
# make ARCH=arm KERNELPATH=~/rowboat-android/TI-Android-ICS-4.0.3_AM37x_3.0.0/kernel CROSS_COMPILE=arm-eabi- clean clean
|
||||
#
|
||||
# For Android 4.2.2 (JB) Linaro release 13.04 for PandaBoard:
|
||||
# export PATH=$PATH:~/Linaro-13.04/android/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.7-linaro/bin
|
||||
# make ARCH=arm KERNELPATH=~/Linaro-13.04/android/kernel/linaro/pandaboard CROSS_COMPILE=arm-eabi- clean debug
|
||||
# make ARCH=arm KERNELPATH=~/Linaro-13.04/android/kernel/linaro/pandaboard CROSS_COMPILE=arm-eabi- clean release
|
||||
# make ARCH=arm KERNELPATH=~/Linaro-13.04/android/kernel/linaro/pandaboard CROSS_COMPILE=arm-eabi- clean clean
|
||||
#
|
||||
|
||||
# Silicon Image uses DEVELOPER_BUILD_ID for sandbox build to be identified during testing.
|
||||
ifneq ($(DEVELOPER_BUILD_ID),)
|
||||
DEVELOPER_BUILD_COPY=cp sii$(MHL_PRODUCT_NUM)drv.ko sii$(MHL_PRODUCT_NUM)drv$(DEVELOPER_BUILD_ID).ko
|
||||
endif
|
||||
|
||||
ifneq ($(KERNELRELEASE),)
|
||||
# kbuild part of makefile
|
||||
|
||||
#
|
||||
# color annotations to use instead of leading newline chars
|
||||
ccflags-y += -DANSI_COLORS
|
||||
|
||||
ccflags-y += -DBUILD_NUM_STRING=\"$(MHL_BUILD_NUM)$(DEVELOPER_BUILD_ID)\"
|
||||
ccflags-y += -DMHL_PRODUCT_NUM=$(MHL_PRODUCT_NUM)
|
||||
ccflags-y += -DMHL_DRIVER_NAME=\"sii$(MHL_PRODUCT_NUM)drv\"
|
||||
ccflags-y += -DMHL_DEVICE_NAME=\"sii-$(MHL_PRODUCT_NUM)\"
|
||||
|
||||
# Support Device Tree?
|
||||
ifeq ($(DT_SUPPORT),1)
|
||||
ccflags-y += -DSIMG_USE_DTS
|
||||
endif
|
||||
|
||||
# Kernel level supported
|
||||
ccflags-y += -DLINUX_KERNEL_VER=$(LINUX_KERNEL_VER)
|
||||
#
|
||||
# FORCE_OCBUS_FOR_ECTS is used to identify code added for ECTS temporary fix that prohibits use of eCBUS.
|
||||
# in addition module parameter force_ocbus_for_ects needs to be set as 1 to achieve ECTS operation.
|
||||
ccflags-y += -DFORCE_OCBUS_FOR_ECTS
|
||||
#
|
||||
# PC_MODE_VIDEO_TIMING_SUPPORT is for cases where no VIC is available from either AVIF or VSIF.
|
||||
ccflags-y += -DPC_MODE_VIDEO_TIMING_SUPPORT
|
||||
#
|
||||
# MANUAL_INFO_FRAME_CLEAR_AT_HPD_DRIVEN_HIGH is to clear all infoframes
|
||||
# upon driving HPD high instead of when SCDT goes low.
|
||||
ccflags-y += -DMANUAL_INFO_FRAME_CLEAR_AT_HPD_DRIVEN_HIGH
|
||||
#
|
||||
# MEDIA_DATA_TUNNEL_SUPPORT
|
||||
# Default is enabled. Comment next line to disable.
|
||||
ccflags-y += -DMEDIA_DATA_TUNNEL_SUPPORT
|
||||
#
|
||||
# Include REMOTE BUTTON PROTOCOL code or not
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) += -DINCLUDE_RBP=1
|
||||
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) += -DINCLUDE_HID=$(INCLUDE_HID)
|
||||
|
||||
# Example of use of SiI6031 is wrapped under the following definition
|
||||
# It also illustrates how 8620 driver may be integrated into MSM platform
|
||||
# the flag should be disabled if not building for MSM
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) += -DINCLUDE_SII6031=$(INCLUDE_SII6031)
|
||||
#
|
||||
# MANUAL_EDID_FETCH uses DDC master directly, instead of h/w automated method.
|
||||
ccflags-y += -DMANUAL_EDID_FETCH
|
||||
|
||||
# If CI2CA pin is pulled HIGH, you must define the following flag
|
||||
#ccflags-y += -DALT_I2C_ADDR
|
||||
|
||||
# PRINT_DDC_ABORTS enables logging of all DDC_ABORTs. Default "disabled" - helps MHL2 hot plug.
|
||||
# Enable only if you must for debugging.
|
||||
#ccflags-y += -DPRINT_DDC_ABORTS
|
||||
|
||||
# CoC_FSM_MONITORING exports CoC state machine to GPIO pins
|
||||
# Enable only if you must for debugging.
|
||||
ccflags-y += -DCoC_FSM_MONITORING -DBIST_MONITORING
|
||||
|
||||
#BIST_DONE_DEBUG adds register dump prior to RAP{CBUS_MODE_UP}
|
||||
#ccflags-y += -DBIST_DONE_DEBUG
|
||||
|
||||
# For si_emsc_hid-mt.c
|
||||
ccflags-y += -Idrivers/hid
|
||||
|
||||
# Optimzations and/or workaround
|
||||
ccflags-y += -DDISABLE_SPI_DMA
|
||||
ccflags-y += -DUSE_SPIOPTIMIZE
|
||||
ccflags-y += -DGCS_QUIRKS_FOR_SIMG
|
||||
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) += -DDEBUG
|
||||
|
||||
# Enable VBUS sense and related operations
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) += -DENABLE_VBUS_SENSE
|
||||
|
||||
#support for DVI sources and sinks in MHL3 mode.
|
||||
ccflags-$(CONFIG_DEBUG_DRIVER) += -DMHL3_DVI_SUPPORT
|
||||
|
||||
#add HDMI VSDB to upstream EDID when downstream sink is DVI
|
||||
#ccflags-$(CONFIG_DEBUG_DRIVER) += -DMHL3_DVI_SUPPORT_FORCE_HDMI
|
||||
#
|
||||
# the next lines are optional - they enable greater verbosity in debug output
|
||||
#ccflags-$(CONFIG_DEBUG_DRIVER) += -DENABLE_EDID_DEBUG_PRINT
|
||||
#ccflags-$(CONFIG_DEBUG_DRIVER) += -DENABLE_DUMP_INFOFRAME
|
||||
#
|
||||
# uncomment next line to prevent EDID parsing. Useful for debugging.
|
||||
#ccflags-$(CONFIG_DEBUG_DRIVER) += -DEDID_PASSTHROUGH
|
||||
|
||||
obj-$(CONFIG_SII$(MHL_PRODUCT_NUM)_MHL_TX) += sii$(MHL_PRODUCT_NUM)drv.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += platform.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += mhl_linux_tx.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += mhl_rcp_inputdev.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += mhl_rbp_inputdev.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += mhl_supp.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += si_8620_drv.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += si_mhl2_edid_3d.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += si_mdt_inputdev.o
|
||||
ifeq ($(INCLUDE_HID),1)
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += si_emsc_hid.o
|
||||
sii$(MHL_PRODUCT_NUM)drv-objs += si_emsc_hid-mt.o
|
||||
endif
|
||||
else
|
||||
|
||||
# Normal Makefile
|
||||
|
||||
# If a kernel is not specified, default to the kernel used with Android Ice Cream Sandwich
|
||||
ifneq ($(KERNELPATH),)
|
||||
KERNELDIR=$(KERNELPATH)
|
||||
else
|
||||
KERNELDIR=~/src/linux-2.6.36
|
||||
#KERNELDIR=~/src/Android_ICS/kernel
|
||||
endif
|
||||
ARCH=arm
|
||||
|
||||
PWD := $(shell pwd)
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
release:
|
||||
make -C $(KERNELDIR) M=$(PWD) CONFIG_SII$(MHL_PRODUCT_NUM)_MHL_TX=m CONFIG_MEDIA_DATA_TUNNEL_SUPPORT=y modules
|
||||
$(CROSS_COMPILE)strip --strip-debug sii$(MHL_PRODUCT_NUM)drv.ko
|
||||
$(DEVELOPER_BUILD_COPY)
|
||||
|
||||
debug:
|
||||
rm -f platform.o
|
||||
make -C $(KERNELDIR) M=$(PWD) CONFIG_SII$(MHL_PRODUCT_NUM)_MHL_TX=m CONFIG_MEDIA_DATA_TUNNEL_SUPPORT=y CONFIG_DEBUG_DRIVER=y modules
|
||||
$(DEVELOPER_BUILD_COPY)
|
||||
|
||||
clean:
|
||||
make -C $(KERNELDIR) M=$(PWD) CONFIG_SII$(MHL_PRODUCT_NUM)_MHL_TX=m clean
|
||||
|
||||
endif
|
39
drivers/video/fbdev/msm/mhl3/mhl_device_cfg.h
Normal file
39
drivers/video/fbdev/msm/mhl3/mhl_device_cfg.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(MHL_DEVICE_CFG_H)
|
||||
#define MHL_DEVICE_CFG_H
|
||||
|
||||
#include "si_app_devcap.h"
|
||||
|
||||
/*
|
||||
* This file contains SiI8620 driver and device configuration information
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Determine XDEVCAPS configurations allowed by this driver
|
||||
*/
|
||||
|
||||
#if (INCLUDE_HID == 1)
|
||||
#define XDEVCAP_VAL_DEV_ROLES (MHL_XDC_DEV_HOST | MHL_XDC_HID_HOST)
|
||||
#else
|
||||
#define XDEVCAP_VAL_DEV_ROLES MHL_XDC_DEV_HOST
|
||||
#endif
|
||||
|
||||
#define XDEVCAP_VAL_LOG_DEV_MAPX MHL_XDC_LD_PHONE
|
||||
|
||||
#endif /* if !defined(MHL_DEVICE_CFG_H) */
|
5717
drivers/video/fbdev/msm/mhl3/mhl_linux_tx.c
Normal file
5717
drivers/video/fbdev/msm/mhl3/mhl_linux_tx.c
Normal file
File diff suppressed because it is too large
Load diff
455
drivers/video/fbdev/msm/mhl3/mhl_linux_tx.h
Normal file
455
drivers/video/fbdev/msm/mhl3/mhl_linux_tx.h
Normal file
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(MHL_LINUX_TX_H)
|
||||
#define MHL_LINUX_TX_H
|
||||
|
||||
#if (INCLUDE_HID == 1)
|
||||
#include "si_emsc_hid.h"
|
||||
#endif
|
||||
#include "si_app_devcap.h"
|
||||
|
||||
/*
|
||||
* EMSC Block Transaction stuff
|
||||
*/
|
||||
#define EMSC_RCV_BUFFER_DEFAULT 256
|
||||
#define EMSC_BLK_MAX_LENGTH 256
|
||||
#define EMSC_BLK_STD_HDR_LEN 2
|
||||
#define EMSC_BLK_CMD_MAX_LEN (EMSC_BLK_MAX_LENGTH - \
|
||||
EMSC_BLK_STD_HDR_LEN)
|
||||
#define LOCAL_BLK_RCV_BUFFER_SIZE 288
|
||||
|
||||
/*
|
||||
* Event codes
|
||||
*
|
||||
*/
|
||||
/* No event worth reporting */
|
||||
#define MHL_TX_EVENT_NONE 0x00
|
||||
|
||||
/* MHL connection has been lost */
|
||||
#define MHL_TX_EVENT_DISCONNECTION 0x01
|
||||
|
||||
/* MHL connection has been established */
|
||||
#define MHL_TX_EVENT_CONNECTION 0x02
|
||||
|
||||
/* Received an RCP key code */
|
||||
#define MHL_TX_EVENT_RCP_RECEIVED 0x04
|
||||
|
||||
/* Received an RCPK message */
|
||||
#define MHL_TX_EVENT_RCPK_RECEIVED 0x05
|
||||
|
||||
/* Received an RCPE message */
|
||||
#define MHL_TX_EVENT_RCPE_RECEIVED 0x06
|
||||
|
||||
/* Received an UTF-8 key code */
|
||||
#define MHL_TX_EVENT_UCP_RECEIVED 0x07
|
||||
|
||||
/* Received an UCPK message */
|
||||
#define MHL_TX_EVENT_UCPK_RECEIVED 0x08
|
||||
|
||||
/* Received an UCPE message */
|
||||
#define MHL_TX_EVENT_UCPE_RECEIVED 0x09
|
||||
|
||||
/* Scratch Pad Data received */
|
||||
#define MHL_TX_EVENT_SPAD_RECEIVED 0x0A
|
||||
|
||||
/* Peer's power capability has changed */
|
||||
#define MHL_TX_EVENT_POW_BIT_CHG 0x0B
|
||||
|
||||
/* Received a Request Action Protocol (RAP) message */
|
||||
#define MHL_TX_EVENT_RAP_RECEIVED 0x0C
|
||||
|
||||
#if (INCLUDE_RBP == 1)
|
||||
/* Received an RBP button code */
|
||||
#define MHL_TX_EVENT_RBP_RECEIVED 0x0D
|
||||
|
||||
/* Received an RBPK message */
|
||||
#define MHL_TX_EVENT_RBPK_RECEIVED 0x0E
|
||||
|
||||
/* Received an RBPE message */
|
||||
#define MHL_TX_EVENT_RBPE_RECEIVED 0x0F
|
||||
#endif
|
||||
|
||||
/* Received a BIST_READY message */
|
||||
#define MHL_TX_EVENT_BIST_READY_RECEIVED 0x10
|
||||
|
||||
/* A triggered BIST test has completed */
|
||||
#define MHL_TX_EVENT_BIST_TEST_DONE 0x11
|
||||
|
||||
/* Received a BIST_STATUS message */
|
||||
#define MHL_TX_EVENT_BIST_STATUS_RECEIVED 0x12
|
||||
|
||||
/* T_RAP_MAX expired */
|
||||
#define MHL_TX_EVENT_T_RAP_MAX_EXPIRED 0x13
|
||||
|
||||
/* peer sent AUD_DELAY burst */
|
||||
#define MHL_EVENT_AUD_DELAY_RCVD 0x14
|
||||
|
||||
#define ADOPTER_ID_SIZE 2
|
||||
#define MAX_SCRATCH_PAD_TRANSFER_SIZE 16
|
||||
#define SCRATCH_PAD_SIZE 64
|
||||
|
||||
#define SCRATCHPAD_SIZE 16
|
||||
union scratch_pad_u {
|
||||
struct MHL2_video_format_data_t videoFormatData;
|
||||
struct MHL3_hev_vic_data_t hev_vic_data;
|
||||
struct MHL3_hev_dtd_a_data_t hev_dtd_a_data;
|
||||
struct MHL3_hev_dtd_b_data_t hev_dtd_b_data;
|
||||
uint8_t asBytes[SCRATCHPAD_SIZE];
|
||||
};
|
||||
|
||||
struct timer_obj {
|
||||
struct list_head list_link;
|
||||
struct work_struct work_item;
|
||||
struct hrtimer hr_timer;
|
||||
struct mhl_dev_context *dev_context;
|
||||
uint8_t flags;
|
||||
#define TIMER_OBJ_FLAG_WORK_IP 0x01
|
||||
#define TIMER_OBJ_FLAG_DEL_REQ 0x02
|
||||
void *callback_param;
|
||||
void (*timer_callback_handler) (void *callback_param);
|
||||
};
|
||||
|
||||
union misc_flags_u {
|
||||
struct {
|
||||
unsigned rcv_scratchpad_busy:1;
|
||||
unsigned req_wrt_pending:1;
|
||||
unsigned write_burst_pending:1;
|
||||
unsigned have_complete_devcap:1;
|
||||
|
||||
unsigned sent_dcap_rdy:1;
|
||||
unsigned sent_path_en:1;
|
||||
unsigned rap_content_on:1;
|
||||
unsigned mhl_hpd:1;
|
||||
|
||||
unsigned mhl_rsen:1;
|
||||
unsigned edid_loop_active:1;
|
||||
unsigned cbus_abort_delay_active:1;
|
||||
unsigned have_complete_xdevcap:1;
|
||||
|
||||
unsigned bist_role_TE:1;
|
||||
|
||||
unsigned reserved:19;
|
||||
} flags;
|
||||
uint32_t as_uint32;
|
||||
};
|
||||
|
||||
struct mhl_device_status {
|
||||
uint8_t write_stat[3];
|
||||
uint8_t write_xstat[4];
|
||||
};
|
||||
|
||||
/*
|
||||
* structure used by interrupt handler to return
|
||||
* information about an interrupt.
|
||||
*/
|
||||
struct interrupt_info {
|
||||
uint16_t flags;
|
||||
/* Flags returned by low level driver interrupt handler */
|
||||
#define DRV_INTR_MSC_DONE 0x0001 /* message send done */
|
||||
#define DRV_INTR_MSC_RECVD 0x0002 /* MSC message received */
|
||||
#define DRV_INTR_MSC_NAK 0x0004 /* message send unsuccessful */
|
||||
#define DRV_INTR_WRITE_STAT 0x0008 /* write stat msg received */
|
||||
#define DRV_INTR_SET_INT 0x0010 /* set int message received */
|
||||
#define DRV_INTR_WRITE_BURST 0x0020 /* write burst received */
|
||||
#define DRV_INTR_HPD_CHANGE 0x0040 /* Hot plug detect change */
|
||||
#define DRV_INTR_CONNECT 0x0080 /* MHL connection established */
|
||||
#define DRV_INTR_DISCONNECT 0x0100 /* MHL connection lost */
|
||||
#define DRV_INTR_CBUS_ABORT 0x0200 /* CBUS msg transfer aborted */
|
||||
#define DRV_INTR_COC_CAL 0x0400 /* CoC Calibration done */
|
||||
#define DRV_INTR_TDM_SYNC 0x0800 /* TDM Sync Complete */
|
||||
#define DRV_INTR_EMSC_INCOMING 0x1000
|
||||
|
||||
void *edid_parser_context;
|
||||
uint8_t msc_done_data;
|
||||
uint8_t hpd_status; /* status of hot plug detect */
|
||||
/* received write stat data for CONNECTED_RDY and/or LINK_MODE,
|
||||
* and/or MHL_VERSION_STAT
|
||||
*/
|
||||
struct mhl_device_status dev_status;
|
||||
uint8_t msc_msg[2]; /* received msc message data */
|
||||
uint8_t int_msg[2]; /* received SET INT message data */
|
||||
};
|
||||
|
||||
enum tdm_vc_assignments {
|
||||
TDM_VC_CBUS1 = 0,
|
||||
TDM_VC_E_MSC = 1,
|
||||
TDM_VC_T_CBUS = 2,
|
||||
TDM_VC_MAX = TDM_VC_T_CBUS + 1
|
||||
};
|
||||
|
||||
/* allow for two WRITE_STAT, and one SET_INT immediately upon MHL_EST */
|
||||
#define NUM_CBUS_EVENT_QUEUE_EVENTS 16
|
||||
|
||||
#define MHL_DEV_CONTEXT_SIGNATURE \
|
||||
(('M' << 24) | ('H' << 16) | ('L' << 8) | ' ')
|
||||
|
||||
struct mhl_dev_context {
|
||||
uint32_t signature; /* identifies an instance of
|
||||
this struct */
|
||||
struct mhl_drv_info const *drv_info;
|
||||
#if (INCLUDE_SII6031 == 1)
|
||||
struct completion sem_mhl_discovery_complete;
|
||||
bool mhl_discovery_in_progress;
|
||||
bool mhl_detected;
|
||||
void (*notify_mhl)(int mhl_detected);
|
||||
void *usb_ctxt;
|
||||
#endif
|
||||
struct i2c_client *client;
|
||||
struct cdev mhl_cdev;
|
||||
struct device *mhl_dev;
|
||||
struct interrupt_info intr_info;
|
||||
void *edid_parser_context;
|
||||
u8 dev_flags;
|
||||
#define DEV_FLAG_SHUTDOWN 0x01 /* Device is shutting down */
|
||||
#define DEV_FLAG_COMM_MODE 0x02 /* Halt INTR processing */
|
||||
|
||||
u16 mhl_flags; /* various state flags */
|
||||
#define MHL_STATE_FLAG_CONNECTED 0x0001 /* MHL connection
|
||||
established */
|
||||
#define MHL_STATE_FLAG_RCP_SENT 0x0002 /* last RCP event was a key
|
||||
send */
|
||||
#define MHL_STATE_FLAG_RCP_RECEIVED 0x0004 /* last RCP event was a key
|
||||
code receive */
|
||||
#define MHL_STATE_FLAG_RCP_ACK 0x0008 /* last RCP key code sent was
|
||||
ACK'd */
|
||||
#define MHL_STATE_FLAG_RCP_NAK 0x0010 /* last RCP key code sent was
|
||||
NAK'd */
|
||||
#define MHL_STATE_FLAG_UCP_SENT 0x0020 /* last UCP event was a key
|
||||
send */
|
||||
#define MHL_STATE_FLAG_UCP_RECEIVED 0x0040 /* last UCP event was a key
|
||||
code receive */
|
||||
#define MHL_STATE_FLAG_UCP_ACK 0x0080 /* last UCP key code sent was
|
||||
ACK'd */
|
||||
#define MHL_STATE_FLAG_UCP_NAK 0x0100 /* last UCP key code sent was
|
||||
NAK'd */
|
||||
#if (INCLUDE_RBP == 1)
|
||||
#define MHL_STATE_FLAG_RBP_RECEIVED 0x0200 /* last RBP event was a button
|
||||
code receive */
|
||||
#define MHL_STATE_FLAG_RBP_ACK 0x0400 /* last RBP event was a button
|
||||
code receive */
|
||||
#define MHL_STATE_FLAG_RBP_NAK 0x0800 /* last RBP event was a button
|
||||
code receive */
|
||||
#define MHL_STATE_FLAG_RBP_SENT 0x1000 /* last RBP event was a button
|
||||
send */
|
||||
#endif
|
||||
#define MHL_STATE_FLAG_SPAD_SENT 0x2000 /* scratch pad send in
|
||||
process */
|
||||
#define MHL_STATE_APPLICATION_RAP_BUSY 0x4000 /* application has indicated
|
||||
that it is processing an
|
||||
outstanding request */
|
||||
u8 dev_cap_local_offset;
|
||||
u8 dev_cap_remote_offset;
|
||||
u8 rap_in_sub_command;
|
||||
u8 rap_in_status;
|
||||
u8 rap_out_sub_command;
|
||||
u8 rap_out_status;
|
||||
u8 rcp_in_key_code;
|
||||
u8 rcp_out_key_code;
|
||||
u8 rcp_err_code;
|
||||
u8 rcp_send_status;
|
||||
u8 ucp_in_key_code;
|
||||
u8 ucp_out_key_code;
|
||||
u8 ucp_err_code;
|
||||
u8 ucp_send_status;
|
||||
#if (INCLUDE_RBP == 1)
|
||||
u8 rbp_in_button_code;
|
||||
u8 rbp_out_button_code;
|
||||
u8 rbp_err_code;
|
||||
u8 rbp_send_status;
|
||||
#endif
|
||||
u8 spad_offset;
|
||||
u8 spad_xfer_length;
|
||||
u8 spad_send_status;
|
||||
u8 debug_i2c_address;
|
||||
u8 debug_i2c_offset;
|
||||
u8 debug_i2c_xfer_length;
|
||||
|
||||
#ifdef MEDIA_DATA_TUNNEL_SUPPORT
|
||||
struct mdt_inputdevs mdt_devs;
|
||||
#endif
|
||||
|
||||
#if (INCLUDE_HID == 1)
|
||||
struct mhl3_hid_global_data mhl_ghid;
|
||||
struct mhl3_hid_data *mhl_hid[16];
|
||||
struct workqueue_struct *hid_work_queue;
|
||||
#endif
|
||||
|
||||
u8 error_key;
|
||||
struct input_dev *rcp_input_dev;
|
||||
#if (INCLUDE_RBP == 1)
|
||||
struct input_dev *rbp_input_dev;
|
||||
#endif
|
||||
struct semaphore isr_lock; /* semaphore used to prevent driver
|
||||
* access from user mode from colliding
|
||||
* with the threaded interrupt handler
|
||||
*/
|
||||
|
||||
u8 status_0; /* Received status from peer saved here */
|
||||
u8 status_1;
|
||||
u8 peer_mhl3_version;
|
||||
u8 xstatus_1;
|
||||
u8 xstatus_3;
|
||||
bool msc_msg_arrived;
|
||||
u8 msc_msg_sub_command;
|
||||
u8 msc_msg_data;
|
||||
|
||||
u8 msc_msg_last_data;
|
||||
u8 msc_save_rcp_key_code;
|
||||
#if (INCLUDE_RBP == 1)
|
||||
u8 msc_save_rbp_button_code;
|
||||
#endif
|
||||
u8 msc_save_ucp_key_code;
|
||||
u8 link_mode; /* outgoing MHL LINK_MODE register value */
|
||||
bool mhl_connection_event;
|
||||
u8 mhl_connected;
|
||||
struct workqueue_struct *timer_work_queue;
|
||||
struct list_head timer_list;
|
||||
struct list_head cbus_queue;
|
||||
struct list_head cbus_free_list;
|
||||
struct cbus_req cbus_req_entries[NUM_CBUS_EVENT_QUEUE_EVENTS];
|
||||
struct cbus_req *current_cbus_req;
|
||||
int sequence;
|
||||
void *cbus_abort_timer;
|
||||
void *dcap_rdy_timer;
|
||||
void *dcap_chg_timer;
|
||||
void *t_rap_max_timer;
|
||||
union MHLDevCap_u dev_cap_cache;
|
||||
union MHLXDevCap_u xdev_cap_cache;
|
||||
u8 preferred_clk_mode;
|
||||
union scratch_pad_u incoming_scratch_pad;
|
||||
union scratch_pad_u outgoing_scratch_pad;
|
||||
|
||||
uint8_t virt_chan_slot_counts[TDM_VC_MAX];
|
||||
uint8_t prev_virt_chan_slot_counts[TDM_VC_MAX];
|
||||
|
||||
void *cbus_mode_up_timer;
|
||||
|
||||
void *bist_timer;
|
||||
uint32_t bist_timeout_value;
|
||||
uint32_t bist_timeout_total;
|
||||
struct bist_setup_info bist_setup;
|
||||
struct bist_setup_info sysfs_bist_setup;
|
||||
struct bist_stat_info bist_stat;
|
||||
uint8_t bist_trigger_info;
|
||||
uint8_t bist_ready_status;
|
||||
union misc_flags_u misc_flags;
|
||||
|
||||
struct {
|
||||
int sequence;
|
||||
unsigned long local_blk_rx_buffer_size;
|
||||
struct list_head queue;
|
||||
struct list_head free_list;
|
||||
#define NUM_BLOCK_QUEUE_REQUESTS 4
|
||||
struct block_req *marshalling_req;
|
||||
struct block_req req_entries[NUM_BLOCK_QUEUE_REQUESTS];
|
||||
} block_protocol;
|
||||
|
||||
bool sii_adopter_id;
|
||||
bool edid_valid;
|
||||
uint8_t numEdidExtensions;
|
||||
#ifndef OLD_KEYMAP_TABLE
|
||||
void *timer_T_press_mode;
|
||||
void *timer_T_hold_maintain;
|
||||
#endif
|
||||
|
||||
void *drv_context; /* pointer aligned start of mhl
|
||||
transmitter driver context area */
|
||||
};
|
||||
|
||||
#define PACKED_PIXEL_AVAILABLE(dev_context) \
|
||||
((MHL_DEV_VID_LINK_SUPP_PPIXEL & \
|
||||
dev_context->dev_cap_cache.devcap_cache[DEVCAP_OFFSET_VID_LINK_MODE]) \
|
||||
&& (MHL_DEV_VID_LINK_SUPP_PPIXEL & DEVCAP_VAL_VID_LINK_MODE))
|
||||
|
||||
#define _16_BPP_AVAILABLE(dev_context) \
|
||||
((MHL_DEV_VID_LINK_SUPP_16BPP & \
|
||||
dev_context->dev_cap_cache.devcap_cache[DEVCAP_OFFSET_VID_LINK_MODE]) \
|
||||
&& (MHL_DEV_VID_LINK_SUPP_16BPP & DEVCAP_VAL_VID_LINK_MODE))
|
||||
|
||||
enum scratch_pad_status {
|
||||
SCRATCHPAD_FAIL = -4,
|
||||
SCRATCHPAD_BAD_PARAM = -3,
|
||||
SCRATCHPAD_NOT_SUPPORTED = -2,
|
||||
SCRATCHPAD_BUSY = -1,
|
||||
SCRATCHPAD_SUCCESS = 0
|
||||
};
|
||||
|
||||
struct drv_hw_context;
|
||||
|
||||
struct mhl_drv_info {
|
||||
int drv_context_size;
|
||||
struct {
|
||||
uint8_t major:4;
|
||||
uint8_t minor:4;
|
||||
} mhl_version_support;
|
||||
int irq;
|
||||
|
||||
/* APIs required to be supported by the low level MHL TX driver */
|
||||
int (*mhl_device_initialize) (struct drv_hw_context *hw_context);
|
||||
void (*mhl_device_isr) (struct drv_hw_context *hw_context,
|
||||
struct interrupt_info *intr_info);
|
||||
int (*mhl_device_dbg_i2c_reg_xfer) (void *dev_context, u8 page,
|
||||
u8 offset, u16 count, bool rw_flag, u8 *buffer);
|
||||
int (*mhl_device_get_aksv) (struct drv_hw_context *hw_context,
|
||||
u8 *buffer);
|
||||
};
|
||||
|
||||
/* APIs provided by the Linux layer to the lower level driver */
|
||||
int mhl_handle_power_change_request(struct device *parent_dev, bool power_up);
|
||||
|
||||
int mhl_tx_init(struct mhl_drv_info const *drv_info, struct device *parent_dev);
|
||||
|
||||
int mhl_tx_remove(struct device *parent_dev);
|
||||
|
||||
void mhl_event_notify(struct mhl_dev_context *dev_context, u32 event,
|
||||
u32 event_param, void *data);
|
||||
|
||||
struct mhl_dev_context *get_mhl_device_context(void *context);
|
||||
|
||||
void *si_mhl_tx_get_drv_context(void *dev_context);
|
||||
|
||||
int mhl_tx_create_timer(void *context,
|
||||
void (*callback_handler) (void *callback_param), void *callback_param,
|
||||
void **timer_handle);
|
||||
|
||||
int mhl_tx_delete_timer(void *context, void **timer_handle);
|
||||
|
||||
int mhl_tx_start_timer(void *context, void *timer_handle, uint32_t time_msec);
|
||||
|
||||
int mhl_tx_stop_timer(void *context, void *timer_handle);
|
||||
void mhl_tx_stop_all_timers(struct mhl_dev_context *dev_context);
|
||||
|
||||
void si_mhl_tx_request_first_edid_block(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_handle_atomic_hw_edid_read_complete(struct edid_3d_data_t
|
||||
*mhl_edid_3d_data);
|
||||
|
||||
/* APIs used within the Linux layer of the driver. */
|
||||
uint8_t si_mhl_tx_get_peer_dev_cap_entry(struct mhl_dev_context *dev_context,
|
||||
uint8_t index, uint8_t *data);
|
||||
|
||||
enum scratch_pad_status si_get_scratch_pad_vector(struct mhl_dev_context
|
||||
*dev_context, uint8_t offset, uint8_t length, uint8_t *data);
|
||||
|
||||
#if (INCLUDE_SII6031 == 1)
|
||||
void mhl_tx_notify_otg(struct mhl_dev_context *dev_context, bool mhl_detected);
|
||||
|
||||
int otg_register_mhl_discovery(void *mhl_ctx, int (*mhl_discover_device)
|
||||
(void *, int, void (*)(void *, int online), void *));
|
||||
int otg_unregister_mhl_discovery(void);
|
||||
void otg_mhl_notify(void *ctxt, int on);
|
||||
|
||||
#endif
|
||||
#endif /* if !defined(MHL_LINUX_TX_H) */
|
350
drivers/video/fbdev/msm/mhl3/mhl_rbp_inputdev.c
Normal file
350
drivers/video/fbdev/msm/mhl3/mhl_rbp_inputdev.c
Normal file
|
@ -0,0 +1,350 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
#if (INCLUDE_RBP == 1)
|
||||
#include <linux/input.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include "si_fw_macros.h"
|
||||
#include "si_infoframe.h"
|
||||
#include "si_edid.h"
|
||||
#include "si_mhl_defs.h"
|
||||
#include "si_mhl2_edid_3d_api.h"
|
||||
#include "si_mhl_tx_hw_drv_api.h"
|
||||
#ifdef MEDIA_DATA_TUNNEL_SUPPORT
|
||||
#include "si_mdt_inputdev.h"
|
||||
#endif
|
||||
#include "mhl_linux_tx.h"
|
||||
#include "platform.h"
|
||||
#include "mhl_rbp_inputdev.h"
|
||||
|
||||
enum rbp_state_e {
|
||||
ph0_idle,
|
||||
ph3_press_and_hold_button,
|
||||
ph8_hold_mode,
|
||||
num_rbp_states
|
||||
};
|
||||
|
||||
static char *state_strings[num_rbp_states] = {
|
||||
"idle",
|
||||
"press_and_hold_button",
|
||||
"hold_mode"
|
||||
};
|
||||
|
||||
enum rbp_event_e {
|
||||
rbp_normal_button_press,
|
||||
rbp_normal_button_press_same,
|
||||
rbp_normal_button_release,
|
||||
rbp_normal_button_release_same,
|
||||
rbp_press_and_hold_button_press,
|
||||
rbp_press_and_hold_button_press_same,
|
||||
rbp_press_and_hold_button_release,
|
||||
rbp_press_and_hold_button_release_same,
|
||||
rbp_T_hold_maintain_expired,
|
||||
rbp_T_press_mode_expired,
|
||||
num_rbp_events
|
||||
};
|
||||
|
||||
static char *event_strings[num_rbp_events] = {
|
||||
"normal_button_press",
|
||||
"normal_button_press_same",
|
||||
"normal_button_release",
|
||||
"normal_button_release_same",
|
||||
"press_and_hold_button_press",
|
||||
"press_and_hold_button_press_same",
|
||||
"press_and_hold_button_release",
|
||||
"press_and_hold_button_release_same",
|
||||
"rbp_T_hold_maintain_expired",
|
||||
"rbp_T_press_mode_expired"
|
||||
};
|
||||
|
||||
enum rbp_state_e current_rbp_state = ph0_idle;
|
||||
uint8_t rbp_previous_button = 0, rbp_current_button = 0;
|
||||
|
||||
static int rbp_trigger_button_action(struct mhl_dev_context *dev_context,
|
||||
uint8_t index, bool press_release)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
if (dev_context->rbp_input_dev) {
|
||||
input_report_key(dev_context->rbp_input_dev, index,
|
||||
press_release);
|
||||
input_sync(dev_context->rbp_input_dev);
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int handle_rbp_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t current_button, uint8_t prev_button, enum rbp_event_e event)
|
||||
{
|
||||
int status = 0;
|
||||
uint8_t current_index = current_button & MHL_RBP_BUTTON_ID_MASK;
|
||||
uint8_t prev_index = prev_button & MHL_RBP_BUTTON_ID_MASK;
|
||||
|
||||
MHL_TX_DBG_ERR("received 0x%02x: %s(%d) in state: %s(%d)\n",
|
||||
current_button, event_strings[event], event,
|
||||
state_strings[current_rbp_state], current_rbp_state);
|
||||
/* now process the event according to the current state */
|
||||
switch (current_rbp_state) {
|
||||
case ph0_idle:
|
||||
switch (event) {
|
||||
case rbp_normal_button_press:
|
||||
case rbp_normal_button_press_same:
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 1);
|
||||
/* no update for current_rbp_state */
|
||||
break;
|
||||
case rbp_normal_button_release:
|
||||
case rbp_normal_button_release_same:
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 0);
|
||||
/* no update for current_rbp_state */
|
||||
break;
|
||||
case rbp_press_and_hold_button_press:
|
||||
case rbp_press_and_hold_button_press_same:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_press_mode,
|
||||
T_PRESS_MODE);
|
||||
current_rbp_state = ph3_press_and_hold_button;
|
||||
break;
|
||||
|
||||
case rbp_press_and_hold_button_release:
|
||||
case rbp_press_and_hold_button_release_same:
|
||||
MHL_TX_DBG_ERR("unexpected %s(%d) in state: %s(%d)\n",
|
||||
event_strings[event], event,
|
||||
state_strings[current_rbp_state],
|
||||
current_rbp_state);
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("unexpected event: %d in state: %d\n",
|
||||
event, current_rbp_state);
|
||||
/* no update for current_rbp_state */
|
||||
status = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case ph3_press_and_hold_button:
|
||||
switch (event) {
|
||||
case rbp_normal_button_press:
|
||||
case rbp_normal_button_press_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
rbp_trigger_button_action(dev_context, prev_index, 0);
|
||||
/* OK to overwrite status */
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 1);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_normal_button_release:
|
||||
case rbp_normal_button_release_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
rbp_trigger_button_action(dev_context, prev_index, 0);
|
||||
rbp_trigger_button_action(dev_context, current_index,
|
||||
1);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 0);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_press_and_hold_button_press:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_press_mode,
|
||||
T_PRESS_MODE);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
1);
|
||||
/* no update for current_rbp_state */
|
||||
break;
|
||||
case rbp_press_and_hold_button_press_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain,
|
||||
T_HOLD_MAINTAIN);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
1);
|
||||
current_rbp_state = ph8_hold_mode;
|
||||
break;
|
||||
case rbp_press_and_hold_button_release:
|
||||
case rbp_press_and_hold_button_release_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
0);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_T_press_mode_expired:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain,
|
||||
T_HOLD_MAINTAIN);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
0);
|
||||
current_rbp_state = ph8_hold_mode;
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("unexpected event: %d in state: %d\n",
|
||||
event, current_rbp_state);
|
||||
/* no update for current_rbp_state */
|
||||
status = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case ph8_hold_mode:
|
||||
switch (event) {
|
||||
case rbp_normal_button_press:
|
||||
case rbp_normal_button_press_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
rbp_trigger_button_action(dev_context, prev_index, 0);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 1);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_normal_button_release:
|
||||
case rbp_normal_button_release_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
rbp_trigger_button_action(dev_context, prev_index, 0);
|
||||
rbp_trigger_button_action(dev_context, current_index,
|
||||
1);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 0);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_press_and_hold_button_press:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_press_mode,
|
||||
T_PRESS_MODE);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
1);
|
||||
current_rbp_state = ph3_press_and_hold_button;
|
||||
break;
|
||||
case rbp_press_and_hold_button_press_same:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain,
|
||||
T_HOLD_MAINTAIN);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
1);
|
||||
/* no update for current_rbp_state */
|
||||
break;
|
||||
case rbp_press_and_hold_button_release:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
rbp_trigger_button_action(dev_context, prev_index, 0);
|
||||
rbp_trigger_button_action(dev_context, current_index,
|
||||
1);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context,
|
||||
current_index, 0);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_press_and_hold_button_release_same:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
0);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
case rbp_T_hold_maintain_expired:
|
||||
status =
|
||||
rbp_trigger_button_action(dev_context, prev_index,
|
||||
0);
|
||||
current_rbp_state = ph0_idle;
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("unexpected event: %d in state: %d\n",
|
||||
event, current_rbp_state);
|
||||
/* no update for current_rbp_state */
|
||||
status = -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("irrational state value:%d\n",
|
||||
current_rbp_state);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int generate_rbp_input_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t rbp_buttoncode)
|
||||
{
|
||||
/*
|
||||
Since, in MHL, bit 7 == 1 indicates button release,
|
||||
and, in Linux, zero means button release,
|
||||
we use XOR (^) to invert the sense.
|
||||
*/
|
||||
enum rbp_event_e event;
|
||||
int mhl_button_press;
|
||||
int status = -EINVAL;
|
||||
int index = rbp_buttoncode & MHL_RBP_BUTTON_ID_MASK;
|
||||
|
||||
switch (index) {
|
||||
case RBP_CALL_ANSWER:
|
||||
case RBP_CALL_END:
|
||||
case RBP_CALL_TOGGLE:
|
||||
case RBP_CALL_MUTE:
|
||||
case RBP_CALL_DECLINE:
|
||||
case RBP_OCTOTHORPE:
|
||||
case RBP_ASTERISK:
|
||||
case RBP_ROTATE_CLKWISE:
|
||||
case RBP_ROTATE_COUNTERCLKWISE:
|
||||
case RBP_SCREEN_PAGE_NEXT:
|
||||
case RBP_SCREEN_PAGE_PREV:
|
||||
case RBP_SCREEN_PAGE_UP:
|
||||
case RBP_SCREEN_PAGE_DN:
|
||||
case RBP_SCREEN_PAGE_LEFT:
|
||||
case RBP_SCREEN_PAGE_RIGHT:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
mhl_button_press =
|
||||
(rbp_buttoncode & MHL_RBP_BUTTON_RELEASED_MASK) ? 0 : 1;
|
||||
|
||||
if (mhl_button_press) {
|
||||
if (index == rbp_previous_button)
|
||||
event = rbp_press_and_hold_button_press_same;
|
||||
else
|
||||
event = rbp_press_and_hold_button_press;
|
||||
} else {
|
||||
if (index == rbp_previous_button)
|
||||
event = rbp_press_and_hold_button_release_same;
|
||||
else
|
||||
event = rbp_press_and_hold_button_release;
|
||||
}
|
||||
|
||||
status = handle_rbp_event(dev_context, rbp_buttoncode,
|
||||
rbp_current_button, event);
|
||||
|
||||
rbp_previous_button = rbp_current_button;
|
||||
rbp_current_button = rbp_buttoncode;
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
40
drivers/video/fbdev/msm/mhl3/mhl_rbp_inputdev.h
Normal file
40
drivers/video/fbdev/msm/mhl3/mhl_rbp_inputdev.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _MHL_RBP_INPUTDEV_H_
|
||||
#define _MHL_RBP_INPUTDEV_H_
|
||||
|
||||
struct mhl_dev_context;
|
||||
|
||||
#define RBP_CALL_ANSWER 0x01
|
||||
#define RBP_CALL_END 0x02
|
||||
#define RBP_CALL_TOGGLE 0x03
|
||||
#define RBP_CALL_MUTE 0x04
|
||||
#define RBP_CALL_DECLINE 0x05
|
||||
#define RBP_OCTOTHORPE 0x06
|
||||
#define RBP_ASTERISK 0x07
|
||||
#define RBP_ROTATE_CLKWISE 0x20
|
||||
#define RBP_ROTATE_COUNTERCLKWISE 0x21
|
||||
#define RBP_SCREEN_PAGE_NEXT 0x30
|
||||
#define RBP_SCREEN_PAGE_PREV 0x31
|
||||
#define RBP_SCREEN_PAGE_UP 0x32
|
||||
#define RBP_SCREEN_PAGE_DN 0x33
|
||||
#define RBP_SCREEN_PAGE_LEFT 0x34
|
||||
#define RBP_SCREEN_PAGE_RIGHT 0x35
|
||||
|
||||
int generate_rbp_input_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t rbp_buttoncode);
|
||||
|
||||
#endif /* #ifndef _MHL_RBP_INPUTDEV_H_ */
|
845
drivers/video/fbdev/msm/mhl3/mhl_rcp_inputdev.c
Normal file
845
drivers/video/fbdev/msm/mhl3/mhl_rcp_inputdev.c
Normal file
|
@ -0,0 +1,845 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include "si_fw_macros.h"
|
||||
#include "si_infoframe.h"
|
||||
#include "si_edid.h"
|
||||
#include "si_mhl_defs.h"
|
||||
#include "si_mhl2_edid_3d_api.h"
|
||||
#include "si_mhl_tx_hw_drv_api.h"
|
||||
#ifdef MEDIA_DATA_TUNNEL_SUPPORT
|
||||
#include "si_mdt_inputdev.h"
|
||||
#endif
|
||||
#include "mhl_linux_tx.h"
|
||||
#include "platform.h"
|
||||
#include "mhl_rcp_inputdev.h"
|
||||
|
||||
enum rcp_state_e {
|
||||
PH0_IDLE,
|
||||
PH3_PRESS_AND_HOLD_KEY,
|
||||
ph8_hold_mode,
|
||||
num_rcp_states
|
||||
};
|
||||
|
||||
static char *state_strings[num_rcp_states] = {
|
||||
"idle",
|
||||
"press_and_hold_key",
|
||||
"hold_mode"
|
||||
};
|
||||
|
||||
enum rcp_event_e {
|
||||
RCP_NORMAL_KEY_PRESS,
|
||||
RCP_NORMAL_KEY_PRESS_SAME,
|
||||
RCP_NORMAL_KEY_RELEASE,
|
||||
RCP_NORMAL_KEY_RELEASE_SAME,
|
||||
RCP_HOLD_KEY_PRESS,
|
||||
RCP_HOLD_KEY_PRESS_SAME,
|
||||
RCP_HOLD_KEY_RELEASE,
|
||||
RCP_HOLD_KEY_RELEASE_SAME,
|
||||
RCP_T_HOLD_MAINTAIN_EXPIRED,
|
||||
RCP_T_PRESS_MODE_EXPIRED,
|
||||
NUM_RCP_EVENTS
|
||||
};
|
||||
|
||||
static char *event_strings[NUM_RCP_EVENTS] = {
|
||||
"normal_key_press",
|
||||
"normal_key_press_same",
|
||||
"normal_key_release",
|
||||
"normal_key_release_same",
|
||||
"press_and_hold_key_press",
|
||||
"press_and_hold_key_press_same",
|
||||
"press_and_hold_key_release",
|
||||
"press_and_hold_key_release_same",
|
||||
"rcp_T_hold_maintain_expired",
|
||||
"rcp_T_press_mode_expired"
|
||||
};
|
||||
|
||||
enum rcp_state_e current_rcp_state = PH0_IDLE;
|
||||
uint8_t rcp_previous_key = 0, rcp_current_key = 0;
|
||||
|
||||
struct rcp_keymap_t rcpSupportTable[MHL_NUM_RCP_KEY_CODES] = {
|
||||
{0, 0, 0, {KEY_SELECT, 0}, (MHL_DEV_LD_GUI)}, /* 0x00 */
|
||||
{0, 1, 0, {KEY_UP, 0}, (MHL_DEV_LD_GUI)}, /* 0x01 */
|
||||
{0, 1, 0, {KEY_DOWN, 0}, (MHL_DEV_LD_GUI)}, /* 0x02 */
|
||||
{0, 1, 0, {KEY_LEFT, 0}, (MHL_DEV_LD_GUI)}, /* 0x03 */
|
||||
{0, 1, 0, {KEY_RIGHT, 0}, (MHL_DEV_LD_GUI)}, /* 0x04 */
|
||||
|
||||
{1, 1, 0, {KEY_RIGHT, KEY_UP}, (MHL_DEV_LD_GUI)}, /* 0x05 */
|
||||
{1, 1, 0, {KEY_RIGHT, KEY_DOWN}, (MHL_DEV_LD_GUI)}, /* 0x06 */
|
||||
{1, 1, 0, {KEY_LEFT, KEY_UP}, (MHL_DEV_LD_GUI)}, /* 0x07 */
|
||||
{1, 1, 0, {KEY_LEFT, KEY_DOWN}, (MHL_DEV_LD_GUI)}, /* 0x08 */
|
||||
|
||||
{0, 0, 0, {KEY_MENU, 0}, (MHL_DEV_LD_GUI)}, /* 0x09 */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0}, /* 0x0A */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0}, /* 0x0B */
|
||||
{0, 0, 0, {KEY_BOOKMARKS, 0}, 0}, /* 0x0C */
|
||||
{0, 0, 0, {KEY_EXIT, 0}, (MHL_DEV_LD_GUI)}, /* 0x0D */
|
||||
|
||||
/* 0x0E - 0x1F Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x20 Numeric 0 */
|
||||
{0, 0, 0, {KEY_NUMERIC_0, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x21 Numeric 1 */
|
||||
{0, 0, 0, {KEY_NUMERIC_1, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x22 Numeric 2 */
|
||||
{0, 0, 0, {KEY_NUMERIC_2, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x23 Numeric 3 */
|
||||
{0, 0, 0, {KEY_NUMERIC_3, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x24 Numeric 4 */
|
||||
{0, 0, 0, {KEY_NUMERIC_4, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x25 Numeric 5 */
|
||||
{0, 0, 0, {KEY_NUMERIC_5, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x26 Numeric 6 */
|
||||
{0, 0, 0, {KEY_NUMERIC_6, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x27 Numeric 7 */
|
||||
{0, 0, 0, {KEY_NUMERIC_7, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x28 Numeric 8 */
|
||||
{0, 0, 0, {KEY_NUMERIC_8, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x29 Numeric 9 */
|
||||
{0, 0, 0, {KEY_NUMERIC_9, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
|
||||
/* 0x2A Dot */
|
||||
{0, 0, 0, {KEY_DOT, 0}, 0},
|
||||
|
||||
/* 0x2B Enter */
|
||||
{0, 0, 0, {KEY_ENTER, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
/* 0x2C Clear */
|
||||
{0, 0, 0, {KEY_CLEAR, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO |
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_TUNER)},
|
||||
|
||||
/* 0x2D - 0x2F Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x30 Channel Up */
|
||||
{0, 1, 0, {KEY_CHANNELUP, 0}, (MHL_DEV_LD_TUNER)},
|
||||
/* 0x31 Channel Down */
|
||||
{0, 1, 0, {KEY_CHANNELDOWN, 0}, (MHL_DEV_LD_TUNER)},
|
||||
/* 0x32 Previous Channel */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, (MHL_DEV_LD_TUNER)},
|
||||
/* 0x33 Sound Select */
|
||||
{0, 0, 0, {KEY_SOUND, 0}, (MHL_DEV_LD_AUDIO)},
|
||||
/* 0x34 Input Select */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0},
|
||||
/* 0x35 Show Information */
|
||||
{0, 0, 0, {KEY_PROGRAM, 0}, 0},
|
||||
/* 0x36 Help */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0},
|
||||
/* 0x37 Page Up */
|
||||
{0, 1, 0, {KEY_PAGEUP, 0}, 0},
|
||||
/* 0x38 Page Down */
|
||||
{0, 1, 0, {KEY_PAGEDOWN, 0}, 0},
|
||||
|
||||
/* 0x39 - 0x40 Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x41 Volume Up */
|
||||
{0, 1, 0, {KEY_VOLUMEUP, 0}, (MHL_DEV_LD_SPEAKER)},
|
||||
/* 0x42 Volume Down */
|
||||
{0, 1, 0, {KEY_VOLUMEDOWN, 0}, (MHL_DEV_LD_SPEAKER)},
|
||||
/* 0x43 Mute */
|
||||
{0, 0, 0, {KEY_MUTE, 0}, (MHL_DEV_LD_SPEAKER)},
|
||||
/* 0x44 Play */
|
||||
{0, 0, 0, {KEY_PLAY, 0}, (MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO)},
|
||||
/* 0x45 Stop */
|
||||
{0, 0, 0, {KEY_STOP, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO | MHL_DEV_LD_RECORD)},
|
||||
/* 0x46 Pause */
|
||||
{0, 0, 0, {KEY_PLAYPAUSE, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO | MHL_DEV_LD_RECORD)},
|
||||
/* 0x47 Record */
|
||||
{0, 0, 0, {KEY_RECORD, 0}, (MHL_DEV_LD_RECORD)},
|
||||
/* 0x48 Rewind */
|
||||
{0, 1, 0, {KEY_REWIND, 0}, (MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO)},
|
||||
/* 0x49 Fast Forward */
|
||||
{0, 1, 0, {KEY_FASTFORWARD, 0}, (MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO)},
|
||||
/* 0x4A Eject */
|
||||
{0, 0, 0, {KEY_EJECTCD, 0}, (MHL_DEV_LD_MEDIA)},
|
||||
/* 0x4B Forward */
|
||||
{0, 1, 0, {KEY_NEXTSONG, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO | MHL_DEV_LD_MEDIA)},
|
||||
/* 0x4C Backward */
|
||||
{0, 1, 0, {KEY_PREVIOUSSONG, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO | MHL_DEV_LD_MEDIA)},
|
||||
|
||||
/* 0x4D - 0x4F Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x50 = Angle */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0},
|
||||
/* 0x51 = Subpicture */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0},
|
||||
|
||||
/* 0x52 - 0x5F Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x60 Play */
|
||||
{0, 0, 0, {KEY_PLAYPAUSE, 0}, (MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO)},
|
||||
/* 0x60 = Pause the Play */
|
||||
{0, 0, 0, {KEY_PLAYPAUSE, 0}, (MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO)},
|
||||
/* 0x62 = Record */
|
||||
{0, 0, 0, {KEY_RECORD, 0}, (MHL_DEV_LD_RECORD)},
|
||||
/* 0x63 = Pause the Record */
|
||||
{0, 0, 0, {KEY_PAUSE, 0}, (MHL_DEV_LD_RECORD)},
|
||||
/* 0x64 = Stop */
|
||||
{0, 0, 0, {KEY_STOP, 0},
|
||||
(MHL_DEV_LD_VIDEO | MHL_DEV_LD_AUDIO | MHL_DEV_LD_RECORD)},
|
||||
/* 0x65 = Mute */
|
||||
{0, 0, 0, {KEY_MUTE, 0}, (MHL_DEV_LD_SPEAKER)},
|
||||
/* 0x66 = Restore Mute */
|
||||
{0, 0, 0, {KEY_MUTE, 0}, (MHL_DEV_LD_SPEAKER)},
|
||||
|
||||
/* 0x67 - 0x68 Undefined */
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0},
|
||||
{0, 0, 0, {KEY_UNKNOWN, 0}, 0},
|
||||
|
||||
/* 0x69 - 0x70 Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x71 - 0x75 F1 - F5 */
|
||||
{0, 0, 0, {KEY_F1, 0}, 0},
|
||||
{0, 0, 0, {KEY_F2, 0}, 0},
|
||||
{0, 0, 0, {KEY_F3, 0}, 0},
|
||||
{0, 0, 0, {KEY_F4, 0}, 0},
|
||||
{0, 0, 0, {KEY_F5, 0}, 0},
|
||||
|
||||
/* 0x76 - 0x7D Reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0},
|
||||
|
||||
/* 0x7E Vendor */
|
||||
{0, 0, 0, {KEY_VENDOR, 0}, 0},
|
||||
|
||||
/* 0x7F reserved */
|
||||
{0, 0, 0, {KEY_RESERVED, 0}, 0}
|
||||
};
|
||||
|
||||
static u16 rcp_def_keymap[MHL_NUM_RCP_KEY_CODES]
|
||||
#ifdef OLD_KEYMAP_TABLE
|
||||
= {
|
||||
KEY_SELECT,
|
||||
KEY_UP,
|
||||
KEY_DOWN,
|
||||
KEY_LEFT,
|
||||
KEY_RIGHT,
|
||||
KEY_UNKNOWN, /* right-up */
|
||||
KEY_UNKNOWN, /* right-down */
|
||||
KEY_UNKNOWN, /* left-up */
|
||||
KEY_UNKNOWN, /* left-down */
|
||||
KEY_MENU,
|
||||
KEY_UNKNOWN, /* setup */
|
||||
KEY_UNKNOWN, /* contents */
|
||||
KEY_UNKNOWN, /* favorite */
|
||||
KEY_EXIT,
|
||||
KEY_RESERVED, /* 0x0e */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x1F */
|
||||
KEY_NUMERIC_0,
|
||||
KEY_NUMERIC_1,
|
||||
KEY_NUMERIC_2,
|
||||
KEY_NUMERIC_3,
|
||||
KEY_NUMERIC_4,
|
||||
KEY_NUMERIC_5,
|
||||
KEY_NUMERIC_6,
|
||||
KEY_NUMERIC_7,
|
||||
KEY_NUMERIC_8,
|
||||
KEY_NUMERIC_9,
|
||||
KEY_DOT,
|
||||
KEY_ENTER,
|
||||
KEY_CLEAR,
|
||||
KEY_RESERVED, /* 0x2D */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x2F */
|
||||
KEY_UNKNOWN, /* channel up */
|
||||
KEY_UNKNOWN, /* channel down */
|
||||
KEY_UNKNOWN, /* previous channel */
|
||||
KEY_UNKNOWN, /* sound select */
|
||||
KEY_UNKNOWN, /* input select */
|
||||
KEY_UNKNOWN, /* show information */
|
||||
KEY_UNKNOWN, /* help */
|
||||
KEY_UNKNOWN, /* page up */
|
||||
KEY_UNKNOWN, /* page down */
|
||||
KEY_RESERVED, /* 0x39 */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x3F */
|
||||
KEY_RESERVED, /* 0x40 */
|
||||
KEY_UNKNOWN, /* volume up */
|
||||
KEY_UNKNOWN, /* volume down */
|
||||
KEY_UNKNOWN, /* mute */
|
||||
KEY_PLAY,
|
||||
KEY_STOP,
|
||||
KEY_PLAYPAUSE,
|
||||
KEY_UNKNOWN, /* record */
|
||||
KEY_REWIND,
|
||||
KEY_FASTFORWARD,
|
||||
KEY_UNKNOWN, /* eject */
|
||||
KEY_NEXTSONG,
|
||||
KEY_PREVIOUSSONG,
|
||||
KEY_RESERVED, /* 0x4D */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x4F */
|
||||
KEY_UNKNOWN, /* angle */
|
||||
KEY_UNKNOWN, /* subtitle */
|
||||
KEY_RESERVED, /* 0x52 */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x5F */
|
||||
KEY_PLAY,
|
||||
KEY_PAUSE,
|
||||
KEY_UNKNOWN, /* record_function */
|
||||
KEY_UNKNOWN, /* pause_record_function */
|
||||
KEY_STOP,
|
||||
KEY_UNKNOWN, /* mute_function */
|
||||
KEY_UNKNOWN, /* restore_volume_function */
|
||||
KEY_UNKNOWN, /* tune_function */
|
||||
KEY_UNKNOWN, /* select_media_function */
|
||||
KEY_RESERVED, /* 0x69 */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x70 */
|
||||
KEY_UNKNOWN, /* F1 */
|
||||
KEY_UNKNOWN, /* F2 */
|
||||
KEY_UNKNOWN, /* F3 */
|
||||
KEY_UNKNOWN, /* F4 */
|
||||
KEY_UNKNOWN, /* F5 */
|
||||
KEY_RESERVED, /* 0x76 */
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED,
|
||||
KEY_RESERVED, /* 0x7D */
|
||||
KEY_VENDOR,
|
||||
KEY_RESERVED, /* 0x7F */
|
||||
}
|
||||
#endif
|
||||
;
|
||||
|
||||
#ifdef OLD_KEYMAP_TABLE
|
||||
int generate_rcp_input_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t rcp_keycode)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
if (dev_context->rcp_input_dev) {
|
||||
if (rcp_keycode < ARRAY_SIZE(rcp_def_keymap) &&
|
||||
rcp_def_keymap[rcp_keycode] != KEY_UNKNOWN &&
|
||||
rcp_def_keymap[rcp_keycode] != KEY_RESERVED) {
|
||||
|
||||
input_report_key(dev_context->rcp_input_dev,
|
||||
rcp_keycode, 1);
|
||||
input_report_key(dev_context->rcp_input_dev,
|
||||
rcp_keycode, 0);
|
||||
input_sync(dev_context->rcp_input_dev);
|
||||
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#else
|
||||
|
||||
static int rcp_trigger_key_action(struct mhl_dev_context *dev_context,
|
||||
uint8_t index, bool press_release)
|
||||
{
|
||||
int status = -EINVAL;
|
||||
|
||||
index &= MHL_RCP_KEY_ID_MASK;
|
||||
|
||||
if (dev_context->rcp_input_dev) {
|
||||
input_report_key(dev_context->rcp_input_dev,
|
||||
rcpSupportTable[index].map[0], press_release);
|
||||
MHL_TX_DBG_ERR("input_report_key(0x%x,%d)\n",
|
||||
rcpSupportTable[index].map[0], press_release)
|
||||
if (rcpSupportTable[index].multicode) {
|
||||
input_report_key(dev_context->rcp_input_dev,
|
||||
rcpSupportTable[index].map[1], press_release);
|
||||
MHL_TX_DBG_ERR("input_report_key(0x%x,%d)\n",
|
||||
rcpSupportTable[index].map[1], press_release)
|
||||
}
|
||||
|
||||
input_sync(dev_context->rcp_input_dev);
|
||||
status = 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static int handle_rcp_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t current_key, uint8_t prev_key, enum rcp_event_e event)
|
||||
{
|
||||
int status = 0;
|
||||
uint8_t current_index = current_key & MHL_RCP_KEY_ID_MASK;
|
||||
uint8_t prev_index = prev_key & MHL_RCP_KEY_ID_MASK;
|
||||
|
||||
MHL_TX_DBG_ERR("received 0x%02x: %s(%d) in state: %s(%d)\n",
|
||||
current_key, event_strings[event], event,
|
||||
state_strings[current_rcp_state], current_rcp_state);
|
||||
/* now process the event according to the current state */
|
||||
switch (current_rcp_state) {
|
||||
case PH0_IDLE:
|
||||
switch (event) {
|
||||
case RCP_NORMAL_KEY_PRESS:
|
||||
case RCP_NORMAL_KEY_PRESS_SAME:
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
1);
|
||||
/* no update for current_rcp_state */
|
||||
break;
|
||||
case RCP_NORMAL_KEY_RELEASE:
|
||||
case RCP_NORMAL_KEY_RELEASE_SAME:
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
0);
|
||||
/* no update for current_rcp_state */
|
||||
break;
|
||||
case RCP_HOLD_KEY_PRESS:
|
||||
case RCP_HOLD_KEY_PRESS_SAME:
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
1);
|
||||
/* no break here */
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_press_mode,
|
||||
T_PRESS_MODE);
|
||||
current_rcp_state = PH3_PRESS_AND_HOLD_KEY;
|
||||
break;
|
||||
|
||||
case RCP_HOLD_KEY_RELEASE:
|
||||
case RCP_HOLD_KEY_RELEASE_SAME:
|
||||
MHL_TX_DBG_ERR("unexpected %s(%d) in state: %s(%d)\n",
|
||||
event_strings[event], event,
|
||||
state_strings[current_rcp_state],
|
||||
current_rcp_state);
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("unexpected event: %d in state: %d\n",
|
||||
event, current_rcp_state);
|
||||
/* no update for current_rcp_state */
|
||||
status = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case PH3_PRESS_AND_HOLD_KEY:
|
||||
switch (event) {
|
||||
case RCP_NORMAL_KEY_PRESS:
|
||||
case RCP_NORMAL_KEY_PRESS_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
/* OK to overwrite status */
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
1);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_NORMAL_KEY_RELEASE:
|
||||
case RCP_NORMAL_KEY_RELEASE_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
rcp_trigger_key_action(dev_context, current_index, 1);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
0);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_HOLD_KEY_PRESS:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_press_mode,
|
||||
T_PRESS_MODE);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 1);
|
||||
/* no update for current_rcp_state */
|
||||
break;
|
||||
case RCP_HOLD_KEY_PRESS_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain,
|
||||
T_HOLD_MAINTAIN);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 1);
|
||||
current_rcp_state = ph8_hold_mode;
|
||||
break;
|
||||
case RCP_HOLD_KEY_RELEASE:
|
||||
case RCP_HOLD_KEY_RELEASE_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_press_mode);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_T_PRESS_MODE_EXPIRED:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain,
|
||||
T_HOLD_MAINTAIN);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
current_rcp_state = ph8_hold_mode;
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("unexpected event: %d in state: %d\n",
|
||||
event, current_rcp_state);
|
||||
/* no update for current_rcp_state */
|
||||
status = -EINVAL;
|
||||
}
|
||||
break;
|
||||
case ph8_hold_mode:
|
||||
switch (event) {
|
||||
case RCP_NORMAL_KEY_PRESS:
|
||||
case RCP_NORMAL_KEY_PRESS_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
1);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_NORMAL_KEY_RELEASE:
|
||||
case RCP_NORMAL_KEY_RELEASE_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
rcp_trigger_key_action(dev_context, current_index, 1);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
0);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_HOLD_KEY_PRESS:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_press_mode,
|
||||
T_PRESS_MODE);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 1);
|
||||
current_rcp_state = PH3_PRESS_AND_HOLD_KEY;
|
||||
break;
|
||||
case RCP_HOLD_KEY_PRESS_SAME:
|
||||
mhl_tx_start_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain,
|
||||
T_HOLD_MAINTAIN);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 1);
|
||||
/* no update for current_rcp_state */
|
||||
break;
|
||||
case RCP_HOLD_KEY_RELEASE:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
rcp_trigger_key_action(dev_context, current_index, 1);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, current_index,
|
||||
0);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_HOLD_KEY_RELEASE_SAME:
|
||||
mhl_tx_stop_timer(dev_context,
|
||||
dev_context->timer_T_hold_maintain);
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
case RCP_T_HOLD_MAINTAIN_EXPIRED:
|
||||
status =
|
||||
rcp_trigger_key_action(dev_context, prev_index, 0);
|
||||
current_rcp_state = PH0_IDLE;
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("unexpected event: %d in state: %d\n",
|
||||
event, current_rcp_state);
|
||||
/* no update for current_rcp_state */
|
||||
status = -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MHL_TX_DBG_ERR("irrational state value:%d\n",
|
||||
current_rcp_state);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void timer_callback_T_hold_maintain_handler(void *param)
|
||||
{
|
||||
struct mhl_dev_context *dev_context = (struct mhl_dev_context *)param;
|
||||
handle_rcp_event(dev_context, rcp_current_key, rcp_previous_key,
|
||||
RCP_T_HOLD_MAINTAIN_EXPIRED);
|
||||
}
|
||||
|
||||
static void timer_callback_T_press_mode_handler(void *param)
|
||||
{
|
||||
struct mhl_dev_context *dev_context = (struct mhl_dev_context *)param;
|
||||
handle_rcp_event(dev_context, rcp_current_key, rcp_previous_key,
|
||||
RCP_T_PRESS_MODE_EXPIRED);
|
||||
}
|
||||
|
||||
int generate_rcp_input_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t rcp_keycode)
|
||||
{
|
||||
/*
|
||||
Since, in MHL, bit 7 == 1 indicates key release,
|
||||
and, in Linux, zero means key release,
|
||||
we use XOR (^) to invert the sense.
|
||||
*/
|
||||
int status = -EINVAL;
|
||||
int index = rcp_keycode & MHL_RCP_KEY_ID_MASK;
|
||||
|
||||
if (rcp_def_keymap[index] != KEY_UNKNOWN &&
|
||||
rcp_def_keymap[index] != KEY_RESERVED) {
|
||||
|
||||
enum rcp_event_e event;
|
||||
int mhl_key_press =
|
||||
(rcp_keycode & MHL_RCP_KEY_RELEASED_MASK) ? 0 : 1;
|
||||
|
||||
if (mhl_key_press) {
|
||||
if (rcpSupportTable[index].press_and_hold_key) {
|
||||
if (index == rcp_previous_key)
|
||||
event = RCP_HOLD_KEY_PRESS_SAME;
|
||||
else
|
||||
event = RCP_HOLD_KEY_PRESS;
|
||||
} else {
|
||||
if (index == rcp_previous_key)
|
||||
event = RCP_NORMAL_KEY_PRESS_SAME;
|
||||
else
|
||||
event = RCP_NORMAL_KEY_PRESS;
|
||||
}
|
||||
} else {
|
||||
if (rcpSupportTable[index].press_and_hold_key) {
|
||||
if (index == rcp_previous_key)
|
||||
event = RCP_HOLD_KEY_RELEASE_SAME;
|
||||
else
|
||||
event = RCP_HOLD_KEY_RELEASE;
|
||||
} else {
|
||||
if (index == rcp_previous_key)
|
||||
event = RCP_NORMAL_KEY_RELEASE_SAME;
|
||||
else
|
||||
event = RCP_NORMAL_KEY_RELEASE;
|
||||
}
|
||||
}
|
||||
status =
|
||||
handle_rcp_event(dev_context, rcp_keycode, rcp_current_key,
|
||||
event);
|
||||
}
|
||||
|
||||
rcp_previous_key = rcp_current_key;
|
||||
rcp_current_key = rcp_keycode;
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif
|
||||
|
||||
int init_rcp_input_dev(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
unsigned int i;
|
||||
struct input_dev *rcp_input_dev;
|
||||
int ret;
|
||||
|
||||
if (dev_context->rcp_input_dev != NULL) {
|
||||
MHL_TX_DBG_INFO("RCP input device already exists!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rcp_input_dev = input_allocate_device();
|
||||
if (!rcp_input_dev) {
|
||||
MHL_TX_DBG_ERR("Failed to allocate RCP input device\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
set_bit(EV_KEY, rcp_input_dev->evbit);
|
||||
|
||||
rcp_input_dev->name = "MHL Remote Control";
|
||||
rcp_input_dev->keycode = rcp_def_keymap;
|
||||
rcp_input_dev->keycodesize = sizeof(u16);
|
||||
rcp_input_dev->keycodemax = ARRAY_SIZE(rcp_def_keymap);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(rcp_def_keymap); i++) {
|
||||
#ifdef OLD_KEYMAP_TABLE
|
||||
u16 keycode = rcp_def_keymap[i];
|
||||
#else
|
||||
u16 keycode = rcpSupportTable[i].map[0];
|
||||
rcp_def_keymap[i] = keycode;
|
||||
#endif
|
||||
if (keycode != KEY_UNKNOWN && keycode != KEY_RESERVED)
|
||||
set_bit(keycode, rcp_input_dev->keybit);
|
||||
}
|
||||
|
||||
rcp_input_dev->id.bustype = BUS_VIRTUAL;
|
||||
|
||||
ret = input_register_device(rcp_input_dev);
|
||||
if (ret) {
|
||||
MHL_TX_DBG_ERR("Failed to register device\n");
|
||||
input_free_device(rcp_input_dev);
|
||||
return ret;
|
||||
}
|
||||
ret = mhl_tx_create_timer(dev_context,
|
||||
timer_callback_T_press_mode_handler,
|
||||
dev_context, &dev_context->timer_T_press_mode);
|
||||
if (ret != 0) {
|
||||
MHL_TX_DBG_ERR("failed in created timer_T_press_mode!\n");
|
||||
} else {
|
||||
ret = mhl_tx_create_timer(dev_context,
|
||||
timer_callback_T_hold_maintain_handler,
|
||||
dev_context, &dev_context->timer_T_hold_maintain);
|
||||
if (ret != 0) {
|
||||
MHL_TX_DBG_ERR
|
||||
("failed to create timer_T_hold_maintain!\n");
|
||||
} else {
|
||||
MHL_TX_DBG_INFO("device created\n");
|
||||
dev_context->rcp_input_dev = rcp_input_dev;
|
||||
return 0;
|
||||
}
|
||||
mhl_tx_delete_timer(dev_context,
|
||||
&dev_context->timer_T_press_mode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void destroy_rcp_input_dev(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
if (dev_context->timer_T_press_mode) {
|
||||
mhl_tx_delete_timer(dev_context,
|
||||
&dev_context->timer_T_press_mode);
|
||||
}
|
||||
if (dev_context->timer_T_hold_maintain) {
|
||||
mhl_tx_delete_timer(dev_context,
|
||||
&dev_context->timer_T_hold_maintain);
|
||||
}
|
||||
if (dev_context->rcp_input_dev) {
|
||||
input_unregister_device(dev_context->rcp_input_dev);
|
||||
dev_context->rcp_input_dev = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void rcp_input_dev_one_time_init(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MHL_NUM_RCP_KEY_CODES; ++i)
|
||||
rcp_def_keymap[i] = rcpSupportTable[i].map[0];
|
||||
}
|
42
drivers/video/fbdev/msm/mhl3/mhl_rcp_inputdev.h
Normal file
42
drivers/video/fbdev/msm/mhl3/mhl_rcp_inputdev.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _MHL_RCP_INPUTDEV_H_
|
||||
#define _MHL_RCP_INPUTDEV_H_
|
||||
|
||||
struct mhl_dev_context;
|
||||
|
||||
struct rcp_keymap_t {
|
||||
unsigned multicode:1;
|
||||
unsigned press_and_hold_key:1;
|
||||
unsigned reserved:6;
|
||||
uint16_t map[2];
|
||||
uint8_t rcp_support;
|
||||
};
|
||||
|
||||
#define MHL_LOGICAL_DEVICE_MAP (MHL_DEV_LD_AUDIO | MHL_DEV_LD_VIDEO | \
|
||||
MHL_DEV_LD_MEDIA | MHL_DEV_LD_GUI)
|
||||
|
||||
#define MHL_NUM_RCP_KEY_CODES 0x80
|
||||
extern struct rcp_keymap_t rcpSupportTable[MHL_NUM_RCP_KEY_CODES];
|
||||
|
||||
int generate_rcp_input_event(struct mhl_dev_context *dev_context,
|
||||
uint8_t rcp_keycode);
|
||||
|
||||
int init_rcp_input_dev(struct mhl_dev_context *dev_context);
|
||||
void destroy_rcp_input_dev(struct mhl_dev_context *dev_context);
|
||||
void rcp_input_dev_one_time_init(struct mhl_dev_context *dev_context);
|
||||
|
||||
#endif /* #ifndef _MHL_RCP_INPUTDEV_H_ */
|
4700
drivers/video/fbdev/msm/mhl3/mhl_supp.c
Normal file
4700
drivers/video/fbdev/msm/mhl3/mhl_supp.c
Normal file
File diff suppressed because it is too large
Load diff
108
drivers/video/fbdev/msm/mhl3/mhl_supp.h
Normal file
108
drivers/video/fbdev/msm/mhl3/mhl_supp.h
Normal file
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(MHL_SUPP_H)
|
||||
#define MHL_SUPP_H
|
||||
|
||||
/* APIs exported from mhl_supp.c */
|
||||
|
||||
int si_mhl_tx_get_num_block_reqs(void);
|
||||
int si_mhl_tx_initialize(struct mhl_dev_context *dev_context);
|
||||
int si_mhl_tx_reserve_resources(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_initialize_block_transport(struct mhl_dev_context *dev_context);
|
||||
void process_cbus_abort(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_drive_states(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_push_block_transactions(struct mhl_dev_context *dev_context);
|
||||
|
||||
bool invalid_bist_te_parms(struct mhl_dev_context *dev_context,
|
||||
struct bist_setup_info *setup_info);
|
||||
|
||||
void initiate_bist_test(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_process_events(struct mhl_dev_context *dev_context);
|
||||
uint8_t si_mhl_tx_set_preferred_pixel_format(struct mhl_dev_context
|
||||
*dev_context, uint8_t clkMode);
|
||||
void si_mhl_tx_process_write_burst_data(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_msc_command_done(struct mhl_dev_context *dev_context,
|
||||
uint8_t data1);
|
||||
void si_mhl_tx_notify_downstream_hpd_change(struct mhl_dev_context *dev_context,
|
||||
uint8_t downstream_hpd);
|
||||
void si_mhl_tx_got_mhl_status(struct mhl_dev_context *dev_context,
|
||||
struct mhl_device_status *write_stat);
|
||||
void si_mhl_tx_got_mhl_intr(struct mhl_dev_context *dev_context,
|
||||
uint8_t intr_0, uint8_t intr_1);
|
||||
void si_mhl_tx_bist_cleanup(struct mhl_dev_context *dev_context);
|
||||
enum scratch_pad_status si_mhl_tx_request_write_burst(
|
||||
struct mhl_dev_context *dev_context, uint8_t reg_offset,
|
||||
uint8_t length, uint8_t *data);
|
||||
bool si_mhl_tx_send_msc_msg(struct mhl_dev_context *dev_context,
|
||||
uint8_t command, uint8_t cmdData,
|
||||
struct cbus_req *(*completion)(struct mhl_dev_context *dev_context,
|
||||
struct cbus_req *req, uint8_t data1));
|
||||
bool si_mhl_tx_rcp_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rcpKeyCode);
|
||||
bool si_mhl_tx_rcpk_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rcp_key_code);
|
||||
bool si_mhl_tx_rcpe_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rcpe_error_code);
|
||||
bool si_mhl_tx_rbp_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rbpButtonCode);
|
||||
bool si_mhl_tx_rbpk_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rbp_button_code);
|
||||
bool si_mhl_tx_rbpe_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rbpe_error_code);
|
||||
bool si_mhl_tx_ucp_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t ucp_key_code);
|
||||
bool si_mhl_tx_ucpk_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t ucp_key_code);
|
||||
bool si_mhl_tx_ucpe_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t ucpe_error_code);
|
||||
bool si_mhl_tx_rap_send(struct mhl_dev_context *dev_context,
|
||||
uint8_t rap_action_code);
|
||||
struct cbus_req *peek_next_cbus_transaction(struct mhl_dev_context
|
||||
*dev_context);
|
||||
bool si_mhl_tx_send_3d_req_or_feat_req(struct mhl_dev_context *dev_context);
|
||||
void send_bist_ready(struct mhl_dev_context *dev_context);
|
||||
enum bist_cmd_status {
|
||||
BIST_STATUS_NO_ERROR,
|
||||
BIST_STATUS_NOT_IN_OCBUS,
|
||||
BIST_STATUS_NOT_IN_ECBUS,
|
||||
BIST_STATUS_INVALID_SETUP,
|
||||
BIST_STATUS_INVALID_TRIGGER,
|
||||
BIST_STATUS_DUT_NOT_READY,
|
||||
BIST_STATUS_NO_RESOURCES,
|
||||
BIST_STATUS_TEST_IP,
|
||||
BIST_STATUS_NO_TEST_IP
|
||||
};
|
||||
enum bist_cmd_status si_mhl_tx_bist_setup(struct mhl_dev_context *dev_context,
|
||||
struct bist_setup_info *setup);
|
||||
enum bist_cmd_status si_mhl_tx_bist_trigger(struct mhl_dev_context *dev_context,
|
||||
uint8_t trigger_operand);
|
||||
void si_mhl_tx_execute_bist(struct mhl_dev_context *dev_context,
|
||||
struct bist_setup_info *setup_info);
|
||||
void start_bist_initiator_test(struct mhl_dev_context *dev_context);
|
||||
enum bist_cmd_status si_mhl_tx_bist_stop(struct mhl_dev_context *dev_context);
|
||||
enum bist_cmd_status si_mhl_tx_bist_request_stat(struct mhl_dev_context
|
||||
*dev_context,
|
||||
uint8_t request_operand);
|
||||
int si_mhl_tx_shutdown(struct mhl_dev_context *dev_context);
|
||||
int si_mhl_tx_ecbus_started(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_send_blk_rcv_buf_info(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_initialize_block_transport(struct mhl_dev_context *dev_context);
|
||||
|
||||
void si_mhl_tx_set_bist_timer_impl(struct mhl_dev_context *dev_context,
|
||||
const char *caller, int line_num);
|
||||
#define si_mhl_tx_set_bist_timer(dev_context) \
|
||||
si_mhl_tx_set_bist_timer_impl(dev_context, __func__, __LINE__)
|
||||
#endif /* #if !defined(MHL_SUPP_H) */
|
2181
drivers/video/fbdev/msm/mhl3/platform.c
Normal file
2181
drivers/video/fbdev/msm/mhl3/platform.c
Normal file
File diff suppressed because it is too large
Load diff
236
drivers/video/fbdev/msm/mhl3/platform.h
Normal file
236
drivers/video/fbdev/msm/mhl3/platform.h
Normal file
|
@ -0,0 +1,236 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(PLATFORM_H)
|
||||
#define PLATFORM_H
|
||||
|
||||
#define DEVICE_ID_8620 0x8620
|
||||
|
||||
#define DEBUG_I2C_WRITE 1
|
||||
#define DEBUG_I2C_READ 0
|
||||
#define MAX_DEBUG_TRANSFER_SIZE 32
|
||||
|
||||
enum dbg_msg_level {
|
||||
DBG_MSG_LEVEL_ERR,
|
||||
DBG_MSG_LEVEL_WARN,
|
||||
DBG_MSG_LEVEL_INFO,
|
||||
DBG_MSG_LEVEL_GPIO,
|
||||
DBG_MSG_LEVEL_EDID_INFO,
|
||||
DBG_MSG_LEVEL_COMM_INFO
|
||||
};
|
||||
|
||||
enum tx_interface_types {
|
||||
TX_INTERFACE_TYPE_I2C,
|
||||
TX_INTERFACE_TYPE_SPI
|
||||
};
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
void print_formatted_debug_msg(char *file_spec, const char *func_name,
|
||||
int line_num, char *fmt, ...);
|
||||
|
||||
void dump_transfer(enum tx_interface_types if_type,
|
||||
u8 page, u8 offset, u16 count, u8 *values, bool write);
|
||||
|
||||
#define MHL_TX_PROXY_DBG_PRINT(level, function, iLine, ...) \
|
||||
{ \
|
||||
if ((level) <= debug_level) \
|
||||
print_formatted_debug_msg(NULL, function, iLine, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define MHL_TX_GENERIC_DBG_PRINT(level, ...) \
|
||||
{ \
|
||||
if ((level) <= debug_level) \
|
||||
print_formatted_debug_msg(NULL, __func__, __LINE__, \
|
||||
__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define MHL_TX_COMM_INFO(...) \
|
||||
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_COMM_INFO, __VA_ARGS__)
|
||||
|
||||
#define MHL_TX_EDID_INFO(...) \
|
||||
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_EDID_INFO, __VA_ARGS__)
|
||||
|
||||
#define MHL_TX_DBG_GPIO(...) \
|
||||
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_GPIO, __VA_ARGS__)
|
||||
|
||||
#define MHL_TX_DBG_INFO(...) \
|
||||
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_INFO, __VA_ARGS__)
|
||||
|
||||
#define MHL_TX_DBG_WARN(...) \
|
||||
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_WARN, __VA_ARGS__)
|
||||
|
||||
#define MHL_TX_DBG_ERR(...) \
|
||||
MHL_TX_GENERIC_DBG_PRINT(DBG_MSG_LEVEL_ERR, __VA_ARGS__)
|
||||
|
||||
#define DUMP_I2C_TRANSFER(page, offset, count, values, write_flag) \
|
||||
dump_transfer(TX_INTERFACE_TYPE_I2C, page, offset, \
|
||||
count, values, write_flag);
|
||||
|
||||
#define DUMP_SPI_TRANSFER(page, offset, count, values, write_flag) \
|
||||
dump_transfer(TX_INTERFACE_TYPE_SPI, page, offset, \
|
||||
count, values, write_flag);
|
||||
#else
|
||||
|
||||
#define MHL_TX_PROXY_DBG_PRINT(level, function, iLine, ...)
|
||||
#define MHL_TX_GENERIC_DBG_PRINT(level, ...)
|
||||
#define MHL_TX_COMM_INFO(fmt, ...)
|
||||
#define MHL_TX_EDID_INFO(fmt, ...)
|
||||
#define MHL_TX_DBG_GPIO(fmt, ...)
|
||||
#define MHL_TX_DBG_INFO(fmt, ...)
|
||||
#define MHL_TX_DBG_WARN(fmt, ...)
|
||||
#define MHL_TX_DBG_ERR(fmt, ...)
|
||||
|
||||
#define DUMP_I2C_TRANSFER(page, offset, count, values, write_flag)
|
||||
#define DUMP_SPI_TRANSFER(page, offset, count, values, write_flag)
|
||||
|
||||
#endif
|
||||
|
||||
void push_debug_level(int new_verbosity);
|
||||
void pop_debug_level(void);
|
||||
|
||||
enum vbus_power_state {
|
||||
VBUS_OFF,
|
||||
VBUS_ON
|
||||
};
|
||||
|
||||
enum hpd_control_mode {
|
||||
HPD_CTRL_MODE_ERROR = -1,
|
||||
HPD_CTRL_OPEN_DRAIN,
|
||||
HPD_CTRL_PUSH_PULL
|
||||
};
|
||||
|
||||
enum hpd_control_mode platform_get_hpd_control_mode(void);
|
||||
void platform_mhl_tx_hw_reset(uint32_t reset_period, uint32_t reset_delay);
|
||||
void mhl_tx_vbus_control(enum vbus_power_state power_state);
|
||||
void mhl_tx_vbus_current_ctl(uint16_t max_current_in_milliamps);
|
||||
|
||||
struct platform_reg_pair {
|
||||
uint8_t slave_addr;
|
||||
uint8_t offset;
|
||||
};
|
||||
|
||||
struct platform_signals_list {
|
||||
char *name;
|
||||
int16_t gpio_number;
|
||||
struct platform_reg_pair gpio_reg_PCA950x;
|
||||
uint8_t gpio_mask_PCA950x;
|
||||
uint8_t *gpio_bank_value;
|
||||
bool *param;
|
||||
};
|
||||
struct block_buffer_info_t {
|
||||
uint8_t *buffer;
|
||||
uint8_t payload_offset;
|
||||
size_t req_size;
|
||||
};
|
||||
void si_mhl_tx_platform_get_block_buffer_info(
|
||||
struct block_buffer_info_t *block_buffer_info);
|
||||
int mhl_tx_write_block_spi_emsc(void *drv_context, struct block_req *req);
|
||||
int mhl_tx_read_spi_emsc(void *drv_context, u16 count, u8 *values);
|
||||
void mhl_tx_clear_emsc_read_err(void *drv_context);
|
||||
|
||||
int mhl_tx_write_reg(void *drv_context, u16 address, u8 value);
|
||||
int mhl_tx_read_reg(void *drv_context, u16 address);
|
||||
int mhl_tx_write_reg_block(void *drv_context, u16 address, u16 count,
|
||||
u8 *values);
|
||||
int mhl_tx_read_reg_block(void *drv_context, u16 address, u16 count,
|
||||
u8 *values);
|
||||
int mhl_tx_modify_reg(void *drv_context, u16 address, u8 mask, u8 value);
|
||||
|
||||
#ifdef DEBUG
|
||||
int si_8620_power_control(bool power_up);
|
||||
#endif
|
||||
|
||||
uint32_t platform_get_flags(void);
|
||||
#define PLATFORM_FLAG_HEARTBEAT_MASK 0x00000030
|
||||
#define PLATFORM_VALUE_ISSUE_HEARTBEAT 0x00000010
|
||||
#define PLATFORM_VALUE_DISCONN_HEARTBEAT 0x00000020
|
||||
#define PLATFORM_FLAG_LINK_SPEED 0x000000C0
|
||||
#define PLATFORM_FLAG_6GBPS 0x000000C0
|
||||
#define PLATFORM_FLAG_3GBPS 0x00000080
|
||||
#define PLATFORM_FLAG_1_5GBPS 0x00000040
|
||||
|
||||
int is_interrupt_asserted(void);
|
||||
int get_config(void *dev_context, int config_idx);
|
||||
|
||||
#define GPIO_LED_ON 0
|
||||
#define GPIO_LED_OFF 1
|
||||
void set_pin_impl(/*void *dev_context,*/ int pin_idx, int value,
|
||||
const char *function_name, int line_num);
|
||||
#define set_pin(/*dev_context,*/ pin_idx, value) \
|
||||
set_pin_impl(/*dev_context,*/ pin_idx, value, __func__, __LINE__)
|
||||
|
||||
extern bool source_vbus_on;
|
||||
extern bool bpp_on_wb;
|
||||
extern bool use_spi;
|
||||
extern bool wait_for_user_intr;
|
||||
extern int debug_level;
|
||||
extern bool debug_reg_dump;
|
||||
extern bool force_ocbus_for_ects;
|
||||
extern int crystal_khz;
|
||||
extern int gpio_index;
|
||||
extern int hdcp_content_type;
|
||||
extern bool input_dev_rap;
|
||||
#if (INCLUDE_RBP == 1)
|
||||
extern bool input_dev_rbp;
|
||||
#endif
|
||||
extern bool input_dev_rcp;
|
||||
extern bool input_dev_ucp;
|
||||
|
||||
/* Starter kit board signal control index definitions */
|
||||
#define TX_HW_RESET 0
|
||||
#define TX_FW_WAKE 1
|
||||
#define CHG_DET 2
|
||||
#define XO3_SINK_VBUS_SENSE 3
|
||||
#define TWELVE_VOLT_PS_SENSE 4
|
||||
#define EEPROM_WR_EN 5
|
||||
#define TX2MHLRX_PWR 6
|
||||
#define M2U_VBUS_CTRL 7
|
||||
#define LED_3D 8
|
||||
#define LED_PACKED_PIXEL 9
|
||||
#define LED_HDCP 10
|
||||
#define LED_USB_MODE 11
|
||||
#define LED_SPARE_2 12
|
||||
#define LED_SPARE_3 13
|
||||
#define LED_SPARE_4 14
|
||||
#define X02_USB_SW_CTRL 15
|
||||
#define X02_USB_SW_CTRL0 16
|
||||
#define X02_USB_SW_CTRL1 17
|
||||
#define X02_USB_LED15_AMBER 18
|
||||
#define X02_USB_LED15_GREEN 19
|
||||
|
||||
#ifdef ANSI_COLORS
|
||||
#define ANSI_ESC_RESET_TEXT "\x1b[0m"
|
||||
#define ANSI_ESC_YELLOW_BG "\x1b[43m"
|
||||
#define ANSI_ESC_WHITE_BG "\x1b[47m"
|
||||
#define ANSI_ESC_RED_TEXT "\x1b[31m"
|
||||
#define ANSI_ESC_YELLOW_TEXT "\x1b[33m"
|
||||
#define ANSI_ESC_GREEN_TEXT "\x1b[32m"
|
||||
#define ANSI_ESC_BLACK_TEXT "\1b[30m"
|
||||
#define ANSI_ESC_WHITE_TEXT "\x1b[37m\x1b[1m"
|
||||
#define ANSI_ESC_MAGENTA_TEXT "\x1b[35m"
|
||||
#define ANSI_ESC_CYAN_TEXT "\x1b[36m"
|
||||
#else
|
||||
#define ANSI_ESC_RESET_TEXT ""
|
||||
#define ANSI_ESC_WHITE_BG ""
|
||||
#define ANSI_ESC_RED_TEXT "\n\n"
|
||||
#define ANSI_ESC_YELLOW_TEXT "\n\n"
|
||||
#define ANSI_ESC_GREEN_TEXT "\n\n"
|
||||
#define ANSI_ESC_BLACK_TEXT ""
|
||||
#define ANSI_ESC_WHITE_TEXT ""
|
||||
#define ANSI_ESC_MAGENTA_TEXT ""
|
||||
#define ANSI_ESC_CYAN_TEXT ""
|
||||
#endif
|
||||
#endif /* if !defined(PLATFORM_H) */
|
1
drivers/video/fbdev/msm/mhl3/si_8620.lnt
Normal file
1
drivers/video/fbdev/msm/mhl3/si_8620.lnt
Normal file
|
@ -0,0 +1 @@
|
|||
-DMHL_BUILD_NUM=$BUILD_NUM -DI2C_BUS_NUM=4 -DMHL_PRODUCT_NUM=8620 mhl_linux_tx.c mhl_rcp_inputdev.c mhl_supp.c platform.c si_8620_drv.c si_mdt_inputdev.c si_mhl2_edid_3d.c
|
7638
drivers/video/fbdev/msm/mhl3/si_8620_drv.c
Normal file
7638
drivers/video/fbdev/msm/mhl3/si_8620_drv.c
Normal file
File diff suppressed because it is too large
Load diff
113
drivers/video/fbdev/msm/mhl3/si_8620_drv.h
Normal file
113
drivers/video/fbdev/msm/mhl3/si_8620_drv.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(SI_8620_DRV_H)
|
||||
#define SI_8620_DRV_H
|
||||
|
||||
extern uint8_t dev_cap_values[16];
|
||||
|
||||
enum pp_16bpp_override_t {
|
||||
pp_16bpp_automatic = 0x00,
|
||||
pp_16bpp_override_24bpp = 0x01,
|
||||
pp_16bpp_override_16bpp = 0x02
|
||||
};
|
||||
struct drv_hw_context {
|
||||
struct interrupt_info *intr_info;
|
||||
uint8_t chip_rev_id;
|
||||
uint16_t chip_device_id;
|
||||
uint8_t cbus_status;
|
||||
uint8_t gen2_write_burst_rcv;
|
||||
uint8_t gen2_write_burst_xmit;
|
||||
uint8_t hawb_write_pending;
|
||||
enum {
|
||||
CBUS1_IDLE_RCV_DISABLED,
|
||||
CBUS1_IDLE_RCV_ENABLED,
|
||||
CBUS1_IDLE_RCV_PEND,
|
||||
CBUS1_MSC_PEND_DLY_RCV_EN,
|
||||
CBUS1_MSC_PEND_DLY_RCV_DIS,
|
||||
CBUS1_XMIT_PEND_XMIT_RCV_EN,
|
||||
CBUS1_XMIT_PEND_XMIT_RCV_PEND
|
||||
} cbus1_state;
|
||||
uint8_t delayed_hawb_enable_reg_val;
|
||||
uint8_t video_path;
|
||||
uint8_t video_ready;
|
||||
uint8_t mhl_peer_version_stat;
|
||||
enum cbus_mode_e cbus_mode;
|
||||
uint8_t current_edid_req_blk;
|
||||
uint8_t edid_fifo_block_number;
|
||||
uint8_t valid_vsif;
|
||||
#ifdef NEVER_USED
|
||||
uint8_t valid_avif;
|
||||
#endif
|
||||
uint8_t rx_hdmi_ctrl2_defval;
|
||||
uint8_t aksv[5];
|
||||
struct avi_info_frame_t current_avi_info_frame;
|
||||
union SI_PACK_THIS_STRUCT vsif_mhl3_or_hdmi_u current_vsif;
|
||||
union hw_avi_payload_t outgoingAviPayLoad;
|
||||
struct mhl3_vsif_t outgoing_mhl3_vsif;
|
||||
uint8_t write_burst_data[MHL_SCRATCHPAD_SIZE];
|
||||
struct cbus_req current_cbus_req;
|
||||
uint8_t tdm_virt_chan_slot_counts[VC_MAX];
|
||||
struct {
|
||||
uint16_t received_byte_count;
|
||||
unsigned long peer_blk_rx_buf_avail;
|
||||
unsigned long peer_blk_rx_buf_max;
|
||||
|
||||
#define NUM_BLOCK_INPUT_BUFFERS 8
|
||||
uint8_t input_buffers[NUM_BLOCK_INPUT_BUFFERS][256];
|
||||
int input_buffer_lengths[NUM_BLOCK_INPUT_BUFFERS];
|
||||
uint16_t head;
|
||||
uint16_t tail;
|
||||
} block_protocol;
|
||||
struct si_mhl_callback_api_t callbacks;
|
||||
union avif_or_cea_861_dtd_u avif_or_dtd_from_callback;
|
||||
union vsif_mhl3_or_hdmi_u vsif_mhl3_or_hdmi_from_callback;
|
||||
int hpd_high_callback_status;
|
||||
#ifdef MANUAL_EDID_FETCH
|
||||
uint8_t edid_block[EDID_BLOCK_SIZE];
|
||||
#endif
|
||||
void *input_field_rate_measurement_timer;
|
||||
uint8_t idx_pixel_clock_history;
|
||||
uint32_t pixel_clock_history[16];
|
||||
bool hdcp2_started;
|
||||
enum pp_16bpp_override_t pp_16bpp_override;
|
||||
uint8_t prev_bist_coc_status[6];
|
||||
};
|
||||
|
||||
bool si_mhl_tx_set_status(struct mhl_dev_context *dev_context,
|
||||
bool xstat, uint8_t reg_to_write, uint8_t value);
|
||||
void *si_mhl_tx_get_sub_payload_buffer(struct mhl_dev_context *dev_context,
|
||||
uint8_t size);
|
||||
bool si_mhl_tx_send_write_burst(struct mhl_dev_context *dev_context,
|
||||
void *buffer);
|
||||
int si_mhl_tx_drv_cbus_ready_for_edid(struct mhl_dev_context *dev_context);
|
||||
int si_mhl_tx_drv_set_display_mode(struct mhl_dev_context *dev_context,
|
||||
enum hpd_high_callback_status status);
|
||||
int si_mhl_tx_drv_sample_edid_buffer(struct drv_hw_context *hw_context,
|
||||
uint8_t *edid_buffer);
|
||||
|
||||
void si_set_cbus_mode_leds_impl(enum cbus_mode_e mode_sel,
|
||||
const char *func_name, int line_num);
|
||||
#define si_set_cbus_mode_leds(mode_sel) \
|
||||
si_set_cbus_mode_leds_impl(mode_sel, \
|
||||
__func__, __LINE__)
|
||||
void si_dump_important_regs(struct drv_hw_context *hw_context);
|
||||
|
||||
int si_mhl_tx_drv_get_pp_16bpp_override(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_drv_set_pp_16bpp_override(struct mhl_dev_context *dev_context,
|
||||
int override);
|
||||
int si_mhl_tx_drv_get_hpd_status(struct mhl_dev_context *dev_context);
|
||||
uint32_t si_mhl_tx_drv_get_hdcp2_status(struct mhl_dev_context *dev_context);
|
||||
#endif /* if !defined(SI_8620_DRV_H) */
|
30
drivers/video/fbdev/msm/mhl3/si_8620_internal_api.h
Normal file
30
drivers/video/fbdev/msm/mhl3/si_8620_internal_api.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
struct drv_hw_context;
|
||||
|
||||
void si_mhl_tx_drv_skip_to_next_edid_block(struct drv_hw_context *hw_context);
|
||||
int si_mhl_tx_drv_get_edid_fifo_partial_block(struct drv_hw_context *hw_context,
|
||||
uint8_t start, uint8_t length, uint8_t *edid_buf);
|
||||
int si_mhl_tx_drv_get_edid_fifo_next_block(struct drv_hw_context *hw_context,
|
||||
uint8_t *edid_buf);
|
||||
int si_mhl_tx_drv_set_upstream_edid(struct drv_hw_context *hw_context,
|
||||
uint8_t *edid, uint16_t length);
|
||||
void setup_sans_cbus1(struct mhl_dev_context *dev_context);
|
||||
uint8_t si_get_peer_mhl_version(struct mhl_dev_context *drv_context);
|
||||
int si_peer_supports_packed_pixel(void *drv_context);
|
||||
|
||||
uint16_t si_mhl_tx_drv_get_incoming_timing(struct drv_hw_context *hw_context,
|
||||
struct si_incoming_timing_t *p_timing);
|
1988
drivers/video/fbdev/msm/mhl3/si_8620_regs.h
Normal file
1988
drivers/video/fbdev/msm/mhl3/si_8620_regs.h
Normal file
File diff suppressed because it is too large
Load diff
67
drivers/video/fbdev/msm/mhl3/si_app_devcap.h
Normal file
67
drivers/video/fbdev/msm/mhl3/si_app_devcap.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SI_APP_DEVCAP_H_
|
||||
#define _SI_APP_DEVCAP_H_
|
||||
|
||||
#define DEVCAP_VAL_DEV_STATE 0
|
||||
#define DEVCAP_VAL_MHL_VERSION MHL_VERSION
|
||||
|
||||
#define DEVCAP_VAL_DEV_CAT (MHL_DEV_CAT_SOURCE | \
|
||||
MHL_DEV_CATEGORY_POW_BIT)
|
||||
|
||||
#define DEVCAP_VAL_ADOPTER_ID_H (uint8_t)(SILICON_IMAGE_ADOPTER_ID >> 8)
|
||||
#define DEVCAP_VAL_ADOPTER_ID_L (uint8_t)(SILICON_IMAGE_ADOPTER_ID & 0xFF)
|
||||
|
||||
#define DEVCAP_VAL_VID_LINK_MODE (MHL_DEV_VID_LINK_SUPP_RGB444 | \
|
||||
MHL_DEV_VID_LINK_SUPP_YCBCR422 | MHL_DEV_VID_LINK_SUPP_YCBCR444 | \
|
||||
MHL_DEV_VID_LINK_SUPP_PPIXEL | MHL_DEV_VID_LINK_SUPP_ISLANDS | \
|
||||
MHL_DEV_VID_LINK_SUPP_VGA | MHL_DEV_VID_LINK_SUPP_16BPP)
|
||||
|
||||
#define DEVCAP_VAL_AUD_LINK_MODE (MHL_DEV_AUD_LINK_2CH | \
|
||||
MHL_DEV_AUD_LINK_8CH)
|
||||
|
||||
#define DEVCAP_VAL_VIDEO_TYPE 0
|
||||
#define DEVCAP_VAL_LOG_DEV_MAP MHL_LOGICAL_DEVICE_MAP
|
||||
#define DEVCAP_VAL_BANDWIDTH 0x0F
|
||||
|
||||
#define DEVCAP_VAL_FEATURE_FLAG_UCP_SEND MHL_FEATURE_UCP_SEND_SUPPORT
|
||||
#define DEVCAP_VAL_FEATURE_FLAG_UCP_RECV MHL_FEATURE_UCP_RECV_SUPPORT
|
||||
|
||||
#if (INCLUDE_RBP == 1)
|
||||
#define DEVCAP_VAL_FEATURE_FLAG_RBP MHL_FEATURE_RBP_SUPPORT
|
||||
#else
|
||||
#define DEVCAP_VAL_FEATURE_FLAG_RBP 0
|
||||
#endif
|
||||
|
||||
#define DEVCAP_VAL_FEATURE_FLAG (MHL_FEATURE_RCP_SUPPORT | \
|
||||
MHL_FEATURE_RAP_SUPPORT | \
|
||||
MHL_FEATURE_SP_SUPPORT | \
|
||||
DEVCAP_VAL_FEATURE_FLAG_UCP_SEND | \
|
||||
DEVCAP_VAL_FEATURE_FLAG_UCP_RECV | \
|
||||
DEVCAP_VAL_FEATURE_FLAG_RBP) \
|
||||
|
||||
#define DEVCAP_VAL_SCRATCHPAD_SIZE MHL_SCRATCHPAD_SIZE
|
||||
#define DEVCAP_VAL_INT_STAT_SIZE MHL_INT_AND_STATUS_SIZE
|
||||
#define DEVCAP_VAL_RESERVED 0
|
||||
|
||||
#define XDEVCAP_VAL_ECBUS_SPEEDS (MHL_XDC_ECBUS_S_075 | \
|
||||
MHL_XDC_ECBUS_S_8BIT | MHL_XDC_ECBUS_S_12BIT)
|
||||
|
||||
#define XDEVCAP_VAL_TMDS_SPEEDS (MHL_XDC_TMDS_150 | \
|
||||
MHL_XDC_TMDS_300 | MHL_XDC_TMDS_600)
|
||||
|
||||
|
||||
#endif
|
667
drivers/video/fbdev/msm/mhl3/si_edid.h
Normal file
667
drivers/video/fbdev/msm/mhl3/si_edid.h
Normal file
|
@ -0,0 +1,667 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(SI_EDID_H)
|
||||
#define SI_EDID_H
|
||||
|
||||
SI_PUSH_STRUCT_PACKING
|
||||
|
||||
struct SI_PACK_THIS_STRUCT two_bytes_t {
|
||||
unsigned char low;
|
||||
unsigned char high;
|
||||
};
|
||||
|
||||
#define EDID_EXTENSION_TAG 0x02
|
||||
#define EDID_EXTENSION_BLOCK_MAP 0xF0
|
||||
#define EDID_REV_THREE 0x03
|
||||
#define EDID_BLOCK_0 0x00
|
||||
#define EDID_BLOCK_2_3 0x01
|
||||
|
||||
enum data_block_tag_code_e {
|
||||
DBTC_TERMINATOR,
|
||||
DBTC_AUDIO_DATA_BLOCK,
|
||||
DBTC_VIDEO_DATA_BLOCK,
|
||||
DBTC_VENDOR_SPECIFIC_DATA_BLOCK,
|
||||
DBTC_SPEAKER_ALLOCATION_DATA_BLOCK,
|
||||
DBTC_VESA_DTC_DATA_BLOCK,
|
||||
/* reserved = 6 */
|
||||
DBTC_USE_EXTENDED_TAG = 7
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT data_block_header_fields_t {
|
||||
uint8_t length_following_header:5;
|
||||
enum data_block_tag_code_e tag_code:3;
|
||||
};
|
||||
|
||||
union SI_PACK_THIS_STRUCT data_block_header_byte_t {
|
||||
struct data_block_header_fields_t fields;
|
||||
uint8_t as_byte;
|
||||
};
|
||||
|
||||
enum extended_tag_code_e {
|
||||
ETC_VIDEO_CAPABILITY_DATA_BLOCK,
|
||||
ETC_VENDOR_SPECIFIC_VIDEO_DATA_BLOCK,
|
||||
ETC_VESA_VIDEO_DISPLAY_DEVICE_INFORMATION_DATA_BLOCK,
|
||||
ETC_VESA_VIDEO_DATA_BLOCK,
|
||||
ETC_HDMI_VIDEO_DATA_BLOCK,
|
||||
ETC_COLORIMETRY_DATA_BLOCK,
|
||||
ETC_VIDEO_RELATED,
|
||||
ETC_CEA_MISC_AUDIO_FIELDS = 16,
|
||||
ETC_VENDOR_SPECIFIC_AUDIO_DATA_BLOCK,
|
||||
ETC_HDMI_AUDIO_DATA_BLOCK,
|
||||
ETC_AUDIO_RELATED,
|
||||
ETC_GENERAL = 32
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT extended_tag_code_t {
|
||||
enum extended_tag_code_e etc:8;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT cea_short_descriptor_t {
|
||||
unsigned char VIC:7;
|
||||
unsigned char native:1;
|
||||
};
|
||||
|
||||
#if 0
|
||||
struct SI_PACK_THIS_STRUCT MHL_short_desc_t {
|
||||
cea_short_descriptor_t cea_short_desc;
|
||||
MHL2_video_descriptor_t mhl_vid_desc;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct SI_PACK_THIS_STRUCT video_data_block_t {
|
||||
union data_block_header_byte_t header;
|
||||
struct cea_short_descriptor_t short_descriptors[1]; /*open ended */
|
||||
};
|
||||
|
||||
enum AudioFormatCodes_e {
|
||||
/* reserved = 0 */
|
||||
afd_linear_PCM_IEC60958 = 1,
|
||||
afd_AC3,
|
||||
afd_MPEG1_layers_1_2,
|
||||
afd_MPEG1_layer_3,
|
||||
|
||||
afdMPEG2_MultiChannel,
|
||||
afd_AAC,
|
||||
afd_DTS,
|
||||
afd_ATRAC,
|
||||
|
||||
afd_one_bit_audio,
|
||||
afd_dolby_digital,
|
||||
afd_DTS_HD,
|
||||
afd_MAT_MLP,
|
||||
|
||||
afd_DST,
|
||||
afd_WMA_Pro
|
||||
/* reserved = 15 */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_short_audio_descriptor_t {
|
||||
unsigned char max_channels_minus_one:3;
|
||||
enum AudioFormatCodes_e audio_format_code:4;
|
||||
unsigned char F17:1;
|
||||
unsigned char freq_32_Khz:1;
|
||||
unsigned char freq_44_1_KHz:1;
|
||||
unsigned char freq_48_KHz:1;
|
||||
unsigned char freq_88_2_KHz:1;
|
||||
unsigned char freq_96_KHz:1;
|
||||
unsigned char freq_176_4_KHz:1;
|
||||
unsigned char freq_192_KHz:1;
|
||||
unsigned char F27:1;
|
||||
|
||||
union {
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned res_16_bit:1;
|
||||
unsigned res_20_bit:1;
|
||||
unsigned res_24_bit:1;
|
||||
unsigned F33_37:5;
|
||||
} audio_code_1_LPCM;
|
||||
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
uint8_t max_bit_rate_div_by_8_KHz;
|
||||
} audio_codes_2_8;
|
||||
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
uint8_t default_zero;
|
||||
} audio_codes_9_15;
|
||||
} byte3;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT audio_data_block_t {
|
||||
union data_block_header_byte_t header;
|
||||
/* open ended */
|
||||
struct CEA_short_audio_descriptor_t short_audio_descriptors[1];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT speaker_allocation_flags_t {
|
||||
unsigned char spk_front_left_front_right:1;
|
||||
unsigned char spk_LFE:1;
|
||||
unsigned char spk_front_center:1;
|
||||
unsigned char spk_rear_left_rear_right:1;
|
||||
unsigned char spk_rear_center:1;
|
||||
unsigned char spk_front_left_center_front_right_center:1;
|
||||
unsigned char spk_rear_left_center_rear_right_center:1;
|
||||
unsigned char spk_reserved:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT speaker_allocation_data_block_payload_t {
|
||||
struct speaker_allocation_flags_t speaker_alloc_flags;
|
||||
uint8_t reserved[2];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT speaker_allocation_data_block_t {
|
||||
union data_block_header_byte_t header;
|
||||
struct speaker_allocation_data_block_payload_t payload;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_BA_t {
|
||||
unsigned char B:4;
|
||||
unsigned char A:4;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_DC_t {
|
||||
unsigned char D:4;
|
||||
unsigned char C:4;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_Byte6_t {
|
||||
unsigned char DVI_dual:1;
|
||||
unsigned char reserved:2;
|
||||
unsigned char DC_Y444:1;
|
||||
unsigned char DC_30bit:1;
|
||||
unsigned char DC_36bit:1;
|
||||
unsigned char DC_48bit:1;
|
||||
unsigned char supports_AI:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_byte8_t {
|
||||
unsigned char CNC0_adjacent_pixels_independent:1;
|
||||
unsigned char CNC1_specific_processing_still_pictures:1;
|
||||
unsigned char CNC2_specific_processing_cinema_content:1;
|
||||
unsigned char CNC3_specific_processing_low_AV_latency:1;
|
||||
unsigned char reserved:1;
|
||||
unsigned char HDMI_video_present:1;
|
||||
unsigned char I_latency_fields_present:1;
|
||||
unsigned char latency_fields_present:1;
|
||||
};
|
||||
|
||||
enum image_size_e {
|
||||
imsz_NO_ADDITIONAL,
|
||||
imsz_ASPECT_RATIO_CORRECT_BUT_NO_GUARRANTEE_OF_CORRECT_SIZE,
|
||||
imsz_CORRECT_SIZES_ROUNDED_TO_NEAREST_1_CM,
|
||||
imsz_CORRECT_SIZES_DIVIDED_BY_5_ROUNDED_TO_NEAREST_5_CM
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_Byte13_t {
|
||||
unsigned char reserved:3;
|
||||
enum image_size_e image_size:2;
|
||||
unsigned char _3D_multi_present:2;
|
||||
unsigned char _3D_present:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_Byte14_t {
|
||||
unsigned char HDMI_3D_len:5;
|
||||
unsigned char HDMI_VIC_len:3;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT VSDB_byte_13_through_byte_15_t {
|
||||
struct HDMI_LLC_Byte13_t byte13;
|
||||
struct HDMI_LLC_Byte14_t byte14;
|
||||
uint8_t vicList[1]; /* variable length list base on HDMI_VIC_len */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT VSDB_all_fields_b9_thru_b15_t {
|
||||
uint8_t video_latency;
|
||||
uint8_t audio_latency;
|
||||
uint8_t interlaced_video_latency;
|
||||
uint8_t interlaced_audio_latency;
|
||||
struct VSDB_byte_13_through_byte_15_t byte_13_through_byte_15;
|
||||
/* There must be no fields after here */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT
|
||||
VSDB_all_fields_b9_thru_b15_sans_progressive_latency_t {
|
||||
uint8_t interlaced_video_latency;
|
||||
uint8_t interlaced_audio_latency;
|
||||
struct VSDB_byte_13_through_byte_15_t byte_13_through_byte_15;
|
||||
/* There must be no fields after here */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT
|
||||
VSDB_all_fields_b9_thru_b15_sans_interlaced_latency_t {
|
||||
uint8_t video_latency;
|
||||
uint8_t audio_latency;
|
||||
struct VSDB_byte_13_through_byte_15_t byte_13_through_byte_15;
|
||||
/* There must be no fields after here */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT
|
||||
VSDB_all_fields_b9_thru_b15_sans_all_latency_t {
|
||||
struct VSDB_byte_13_through_byte_15_t byte_13_through_byte_15;
|
||||
/* There must be no fields after here */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_LLC_vsdb_payload_t {
|
||||
struct HDMI_LLC_BA_t B_A;
|
||||
struct HDMI_LLC_DC_t D_C;
|
||||
struct HDMI_LLC_Byte6_t byte6;
|
||||
uint8_t maxTMDSclock;
|
||||
struct HDMI_LLC_byte8_t byte8;
|
||||
|
||||
union {
|
||||
struct VSDB_all_fields_b9_thru_b15_sans_all_latency_t
|
||||
vsdb_b9_to_b15_no_latency;
|
||||
struct VSDB_all_fields_b9_thru_b15_sans_progressive_latency_t
|
||||
vsdb_b9_to_b15_no_p_latency;
|
||||
struct VSDB_all_fields_b9_thru_b15_sans_interlaced_latency_t
|
||||
vsdb_b9_to_b15_no_i_latency;
|
||||
struct VSDB_all_fields_b9_thru_b15_t vsdb_all_fields_b9_thru_b15;
|
||||
} vsdb_fields_b9_thru_b15;
|
||||
/* There must be no fields after here */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_structure_all_15_8_t {
|
||||
uint8_t frame_packing:1;
|
||||
uint8_t reserved1:5;
|
||||
uint8_t top_bottom:1;
|
||||
uint8_t reserved2:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_structure_all_7_0_t {
|
||||
uint8_t side_by_side:1;
|
||||
uint8_t reserved:7;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_structure_all_t {
|
||||
struct _3D_structure_all_15_8_t _3D_structure_all_15_8;
|
||||
struct _3D_structure_all_7_0_t _3D_structure_all_7_0;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_mask_t {
|
||||
uint8_t _3D_mask_15_8;
|
||||
uint8_t _3D_mask_7_0;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _2D_VIC_order_3D_structure_t {
|
||||
enum _3D_structure_e _3D_structure:4; /* definition from infoframe */
|
||||
unsigned _2D_VIC_order:4;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_detail_t {
|
||||
unsigned char reserved:4;
|
||||
unsigned char _3D_detail:4;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_structure_and_detail_entry_sans_byte1_t {
|
||||
struct _2D_VIC_order_3D_structure_t byte0;
|
||||
/*see HDMI 1.4 spec w.r.t. contents of 3D_structure_X */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT _3D_structure_and_detail_entry_with_byte1_t {
|
||||
struct _2D_VIC_order_3D_structure_t byte0;
|
||||
struct _3D_detail_t byte1;
|
||||
};
|
||||
|
||||
union _3D_structure_and_detail_entry_u {
|
||||
struct _3D_structure_and_detail_entry_sans_byte1_t sans_byte1;
|
||||
struct _3D_structure_and_detail_entry_with_byte1_t with_byte1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_3D_sub_block_sans_all_AND_mask_t {
|
||||
union _3D_structure_and_detail_entry_u
|
||||
_3D_structure_and_detail_list[1];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_3D_sub_block_sans_mask_t {
|
||||
struct _3D_structure_all_t _3D_structure_all;
|
||||
union _3D_structure_and_detail_entry_u _3D_structure_and_detail_list[1];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT HDMI_3D_sub_block_with_all_AND_mask_t {
|
||||
struct _3D_structure_all_t _3D_structure_all;
|
||||
struct _3D_mask_t _3D_mask;
|
||||
union _3D_structure_and_detail_entry_u
|
||||
_3D_structure_and_detail_list[1];
|
||||
};
|
||||
|
||||
union HDMI_3D_sub_block_t {
|
||||
struct HDMI_3D_sub_block_sans_all_AND_mask_t
|
||||
HDMI_3D_sub_block_sans_all_AND_mask;
|
||||
struct HDMI_3D_sub_block_sans_mask_t HDMI_3D_sub_block_sans_mask;
|
||||
struct HDMI_3D_sub_block_with_all_AND_mask_t
|
||||
HDMI_3D_sub_block_with_all_AND_mask;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT vsdb_t {
|
||||
union data_block_header_byte_t header;
|
||||
uint8_t IEEE_OUI[3];
|
||||
union {
|
||||
struct HDMI_LLC_vsdb_payload_t HDMI_LLC;
|
||||
uint8_t payload[1]; /* open ended */
|
||||
} payload_u;
|
||||
};
|
||||
|
||||
enum colorimetry_xvYCC_e {
|
||||
xvYCC_601 = 1,
|
||||
xvYCC_709 = 2
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT colorimetry_xvYCC_t {
|
||||
enum colorimetry_xvYCC_e xvYCC:2;
|
||||
unsigned char reserved1:6;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT colorimetry_meta_data_t {
|
||||
unsigned char meta_data:3;
|
||||
unsigned char reserved2:5;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT colorimetry_data_payload_t {
|
||||
struct colorimetry_xvYCC_t ci_data;
|
||||
struct colorimetry_meta_data_t cm_meta_data;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT colorimetry_data_block_t {
|
||||
union data_block_header_byte_t header;
|
||||
struct extended_tag_code_t extended_tag;
|
||||
struct colorimetry_data_payload_t payload;
|
||||
};
|
||||
|
||||
enum CE_overscan_underscan_behavior_e {
|
||||
ceou_NEITHER,
|
||||
ceou_ALWAYS_OVERSCANNED,
|
||||
ceou_ALWAYS_UNDERSCANNED,
|
||||
ceou_BOTH
|
||||
};
|
||||
|
||||
enum IT_overscan_underscan_behavior_e {
|
||||
itou_NEITHER,
|
||||
itou_ALWAYS_OVERSCANNED,
|
||||
itou_ALWAYS_UNDERSCANNED,
|
||||
itou_BOTH
|
||||
};
|
||||
|
||||
enum PT_overscan_underscan_behavior_e {
|
||||
ptou_NEITHER,
|
||||
ptou_ALWAYS_OVERSCANNED,
|
||||
ptou_ALWAYS_UNDERSCANNED,
|
||||
ptou_BOTH,
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT video_capability_data_payload_t {
|
||||
enum CE_overscan_underscan_behavior_e S_CE:2;
|
||||
enum IT_overscan_underscan_behavior_e S_IT:2;
|
||||
enum PT_overscan_underscan_behavior_e S_PT:2;
|
||||
unsigned QS:1;
|
||||
unsigned quantization_range_selectable:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT video_capability_data_block_t {
|
||||
union data_block_header_byte_t header;
|
||||
struct extended_tag_code_t extended_tag;
|
||||
struct video_capability_data_payload_t payload;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_data_block_collection_t {
|
||||
union data_block_header_byte_t header;
|
||||
union {
|
||||
struct extended_tag_code_t extended_tag;
|
||||
struct cea_short_descriptor_t short_descriptor;
|
||||
} payload_u;
|
||||
/* open ended array of cea_short_descriptor_t starts here */
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_extension_version_1_t {
|
||||
uint8_t reservedMustBeZero;
|
||||
uint8_t reserved[123];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_extension_2_3_misc_support_t {
|
||||
uint8_t total_number_native_dtds_in_entire_EDID:4;
|
||||
uint8_t YCrCb422_support:1;
|
||||
uint8_t YCrCb444_support:1;
|
||||
uint8_t basic_audio_support:1;
|
||||
uint8_t underscan_IT_formats_by_default:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_extension_version_2_t {
|
||||
struct CEA_extension_2_3_misc_support_t misc_support;
|
||||
uint8_t reserved[123];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_extension_version_3_t {
|
||||
struct CEA_extension_2_3_misc_support_t misc_support;
|
||||
union {
|
||||
uint8_t data_block_collection[123];
|
||||
uint8_t reserved[123];
|
||||
} Offset4_u;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT block_map_t {
|
||||
uint8_t tag;
|
||||
uint8_t block_tags[126];
|
||||
uint8_t checksum;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT CEA_extension_t {
|
||||
uint8_t tag;
|
||||
uint8_t revision;
|
||||
uint8_t byte_offset_to_18_byte_descriptors;
|
||||
union {
|
||||
struct CEA_extension_version_1_t version1;
|
||||
struct CEA_extension_version_2_t version2;
|
||||
struct CEA_extension_version_3_t version3;
|
||||
} version_u;
|
||||
uint8_t checksum;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT detailed_timing_descriptor_t {
|
||||
uint8_t pixel_clock_low;
|
||||
uint8_t pixel_clock_high;
|
||||
uint8_t horz_active_7_0;
|
||||
uint8_t horz_blanking_7_0;
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned char horz_blanking_11_8:4;
|
||||
unsigned char horz_active_11_8:4;
|
||||
} horz_active_blanking_high;
|
||||
uint8_t vert_active_7_0;
|
||||
uint8_t vert_blanking_7_0;
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned char vert_blanking_11_8:4;
|
||||
unsigned char vert_active_11_8:4;
|
||||
} vert_active_blanking_high;
|
||||
uint8_t horz_sync_offset_7_0;
|
||||
uint8_t horz_sync_pulse_width7_0;
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned char vert_sync_pulse_width_3_0:4;
|
||||
unsigned char vert_sync_offset_3_0:4;
|
||||
} vert_sync_offset_width;
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned char vert_sync_pulse_width_5_4:2;
|
||||
unsigned char vert_sync_offset_5_4:2;
|
||||
unsigned char horz_sync_pulse_width_9_8:2;
|
||||
unsigned char horz_sync_offset_9_8:2;
|
||||
} hs_vs_offset_pulse_width;
|
||||
uint8_t horz_image_size_in_mm_7_0;
|
||||
uint8_t vert_image_size_in_mm_7_0;
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned char vert_image_size_in_mm_11_8:4;
|
||||
unsigned char horz_image_size_in_mm_11_8:4;
|
||||
} image_size_high;
|
||||
uint8_t horz_border_in_lines;
|
||||
uint8_t vert_border_in_pixels;
|
||||
struct SI_PACK_THIS_STRUCT {
|
||||
unsigned char stereo_bit_0:1;
|
||||
unsigned char sync_signal_options:2;
|
||||
unsigned char sync_signal_type:2;
|
||||
unsigned char stereo_bits_2_1:2;
|
||||
unsigned char interlaced:1;
|
||||
} flags;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT red_green_bits_1_0_t {
|
||||
unsigned char green_y:2;
|
||||
unsigned char green_x:2;
|
||||
unsigned char red_y:2;
|
||||
unsigned char red_x:2;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT blue_white_bits_1_0_t {
|
||||
unsigned char white_y:2;
|
||||
unsigned char white_x:2;
|
||||
unsigned char blue_y:2;
|
||||
unsigned char blue_x:2;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT established_timings_I_t {
|
||||
unsigned char et800x600_60p:1;
|
||||
unsigned char et800x600_56p:1;
|
||||
unsigned char et640x480_75p:1;
|
||||
unsigned char et640x480_72p:1;
|
||||
unsigned char et640x480_67p:1;
|
||||
unsigned char et640x480_60p:1;
|
||||
unsigned char et720x400_88p:1;
|
||||
unsigned char et720x400_70p:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT established_timings_II_t {
|
||||
unsigned char et1280x1024_75p:1;
|
||||
unsigned char et1024x768_75p:1;
|
||||
unsigned char et1024x768_70p:1;
|
||||
unsigned char et1024x768_60p:1;
|
||||
unsigned char et1024x768_87i:1;
|
||||
unsigned char et832x624_75p:1;
|
||||
unsigned char et800x600_75p:1;
|
||||
unsigned char et800x600_72p:1;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT manufacturers_timings_t {
|
||||
unsigned char reserved:7;
|
||||
unsigned char et1152x870_75p:1;
|
||||
};
|
||||
|
||||
enum image_aspect_ratio_e {
|
||||
iar_16_to_10,
|
||||
iar_4_to_3,
|
||||
iar_5_to_4,
|
||||
iar_16_to_9
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT standard_timing_t {
|
||||
unsigned char horz_pix_div_8_minus_31;
|
||||
unsigned char field_refresh_rate_minus_60:6;
|
||||
enum image_aspect_ratio_e image_aspect_ratio:2;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT EDID_block0_t {
|
||||
unsigned char header_data[8];
|
||||
struct two_bytes_t id_manufacturer_name;
|
||||
struct two_bytes_t id_product_code;
|
||||
unsigned char serial_number[4];
|
||||
unsigned char week_of_manufacture;
|
||||
unsigned char year_of_manufacture;
|
||||
unsigned char EDID_version;
|
||||
unsigned char EDID_revision;
|
||||
unsigned char video_input_definition;
|
||||
unsigned char horz_screen_size_or_aspect_ratio;
|
||||
unsigned char vert_screen_size_or_aspect_ratio;
|
||||
unsigned char display_transfer_characteristic;
|
||||
unsigned char feature_support;
|
||||
struct red_green_bits_1_0_t red_green_bits_1_0;
|
||||
struct blue_white_bits_1_0_t blue_white_bits_1_0;
|
||||
unsigned char red_x;
|
||||
unsigned char red_y;
|
||||
unsigned char green_x;
|
||||
unsigned char green_y;
|
||||
unsigned char blue_x;
|
||||
unsigned char blue_y;
|
||||
unsigned char white_x;
|
||||
unsigned char white_y;
|
||||
struct established_timings_I_t established_timings_I;
|
||||
struct established_timings_II_t established_timings_II;
|
||||
struct manufacturers_timings_t manufacturers_timings;
|
||||
struct standard_timing_t standard_timings[8];
|
||||
struct detailed_timing_descriptor_t detailed_timing_descriptors[4];
|
||||
unsigned char extension_flag;
|
||||
unsigned char checksum;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT monitor_name_t {
|
||||
uint8_t flag_required[2];
|
||||
uint8_t flag_reserved;
|
||||
uint8_t data_type_tag;
|
||||
uint8_t flag;
|
||||
uint8_t ascii_name[13];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT monitor_range_limits_t {
|
||||
uint8_t flag_required[2];
|
||||
uint8_t flag_reserved;
|
||||
uint8_t data_type_tag;
|
||||
uint8_t flag;
|
||||
uint8_t min_vertical_rate_in_Hz;
|
||||
uint8_t max_vertical_rate_in_Hz;
|
||||
uint8_t min_horizontal_rate_in_KHz;
|
||||
uint8_t max_horizontal_rate_in_KHz;
|
||||
uint8_t max_pixel_clock_in_MHz_div_10;
|
||||
uint8_t tag_secondary_formula;
|
||||
uint8_t filler[7];
|
||||
};
|
||||
|
||||
union _18_byte_descriptor_u {
|
||||
struct detailed_timing_descriptor_t dtd;
|
||||
struct monitor_name_t name;
|
||||
struct monitor_range_limits_t range_limits;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT display_mode_3D_info_t {
|
||||
unsigned char dmi_3D_supported:1;
|
||||
unsigned char dmi_sufficient_bandwidth:1;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_EDID_DEBUG_PRINT
|
||||
void dump_EDID_block_impl(const char *pszFunction, int iLineNum,
|
||||
uint8_t override, uint8_t *pData, uint16_t length);
|
||||
|
||||
void clear_EDID_block_impl(uint8_t *pData);
|
||||
|
||||
#define DUMP_EDID_BLOCK(override, pData, length) \
|
||||
dump_EDID_block_impl(__func__, __LINE__, override, (uint8_t *)pData, \
|
||||
length)
|
||||
#define CLEAR_EDID_BLOCK(pData) clear_EDID_block_impl(pData)
|
||||
#else
|
||||
#define DUMP_EDID_BLOCK(override, pData, length) /* nothing to do */
|
||||
#define CLEAR_EDID_BLOCK(pData) /* nothing to do */
|
||||
#endif
|
||||
|
||||
enum EDID_error_codes {
|
||||
EDID_OK,
|
||||
EDID_INCORRECT_HEADER,
|
||||
EDID_CHECKSUM_ERROR,
|
||||
EDID_NO_861_EXTENSIONS,
|
||||
EDID_SHORT_DESCRIPTORS_OK,
|
||||
EDID_LONG_DESCRIPTORS_OK,
|
||||
EDID_EXT_TAG_ERROR,
|
||||
EDID_REV_ADDR_ERROR,
|
||||
EDID_V_DESCR_OVERFLOW,
|
||||
EDID_UNKNOWN_TAG_CODE,
|
||||
EDID_NO_DETAILED_DESCRIPTORS,
|
||||
EDID_DDC_BUS_REQ_FAILURE,
|
||||
EDID_DDC_BUS_RELEASE_FAILURE,
|
||||
EDID_READ_TIMEOUT
|
||||
};
|
||||
|
||||
SI_POP_STRUCT_PACKING
|
||||
#endif /* #if !defined(SI_EDID_H) */
|
1919
drivers/video/fbdev/msm/mhl3/si_emsc_hid-mt.c
Normal file
1919
drivers/video/fbdev/msm/mhl3/si_emsc_hid-mt.c
Normal file
File diff suppressed because it is too large
Load diff
1531
drivers/video/fbdev/msm/mhl3/si_emsc_hid.c
Normal file
1531
drivers/video/fbdev/msm/mhl3/si_emsc_hid.c
Normal file
File diff suppressed because it is too large
Load diff
278
drivers/video/fbdev/msm/mhl3/si_emsc_hid.h
Normal file
278
drivers/video/fbdev/msm/mhl3/si_emsc_hid.h
Normal file
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* 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_ */
|
40
drivers/video/fbdev/msm/mhl3/si_fw_macros.h
Normal file
40
drivers/video/fbdev/msm/mhl3/si_fw_macros.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SI_FW_MACROS_H_
|
||||
#define _SI_FW_MACROS_H_
|
||||
|
||||
/*
|
||||
* Define Linux versions of macros used to cross compile driver code for other
|
||||
* platforms.
|
||||
*/
|
||||
|
||||
#define PLACE_IN_CODE_SEG
|
||||
|
||||
#define SI_PUSH_STRUCT_PACKING
|
||||
#define SI_POP_STRUCT_PACKING
|
||||
#define SI_PACK_THIS_STRUCT __attribute__((__packed__))
|
||||
|
||||
#define SII_OFFSETOF offsetof
|
||||
|
||||
#define SII_ASSERT(cond, ...) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
printk(__VA_ARGS__); \
|
||||
BUG(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
219
drivers/video/fbdev/msm/mhl3/si_infoframe.h
Normal file
219
drivers/video/fbdev/msm/mhl3/si_infoframe.h
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(SI_INFOFRAME_H)
|
||||
#define SI_INFOFRAME_H
|
||||
|
||||
struct __attribute__ ((__packed__)) info_frame_header_t {
|
||||
uint8_t type_code;
|
||||
uint8_t version_number;
|
||||
uint8_t length;
|
||||
};
|
||||
|
||||
enum AviColorSpace_e {
|
||||
acsRGB,
|
||||
acsYCbCr422,
|
||||
acsYCbCr444,
|
||||
acsYCbCr420
|
||||
};
|
||||
|
||||
enum avi_quant_range_e {
|
||||
aqr_default = 0,
|
||||
aqr_limited_range,
|
||||
aqr_full_range,
|
||||
aqr_reserved
|
||||
};
|
||||
|
||||
/*
|
||||
* AVI Info Frame Structure
|
||||
*/
|
||||
struct __attribute__ ((__packed__)) avi_info_frame_data_byte_1_t {
|
||||
uint8_t ScanInfo:2;
|
||||
uint8_t BarInfo:2;
|
||||
uint8_t ActiveFormatInfoPresent:1;
|
||||
enum AviColorSpace_e colorSpace:2;
|
||||
uint8_t futureMustBeZero:1;
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) avi_info_frame_data_byte_2_t {
|
||||
uint8_t ActiveFormatAspectRatio:4;
|
||||
uint8_t PictureAspectRatio:2;
|
||||
uint8_t Colorimetry:2;
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) avi_info_frame_data_byte_3_t {
|
||||
uint8_t NonUniformPictureScaling:2;
|
||||
uint8_t RGBQuantizationRange:2;
|
||||
uint8_t ExtendedColorimetry:3;
|
||||
uint8_t ITContent:1;
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) avi_info_frame_data_byte_4_t {
|
||||
uint8_t VIC:7;
|
||||
uint8_t futureMustBeZero:1;
|
||||
};
|
||||
|
||||
enum BitsContent_e {
|
||||
cnGraphics,
|
||||
cnPhoto,
|
||||
cnCinema,
|
||||
cnGame
|
||||
};
|
||||
|
||||
enum AviQuantization_e {
|
||||
aqLimitedRange,
|
||||
aqFullRange,
|
||||
aqReserved0,
|
||||
aqReserved1
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) avi_info_frame_data_byte_5_t {
|
||||
uint8_t pixelRepetionFactor:4;
|
||||
enum BitsContent_e content:2;
|
||||
enum AviQuantization_e quantization:2;
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) hw_avi_named_payload_t {
|
||||
uint8_t checksum;
|
||||
union {
|
||||
struct __attribute__ ((__packed__)) {
|
||||
struct avi_info_frame_data_byte_1_t pb1;
|
||||
struct avi_info_frame_data_byte_2_t
|
||||
colorimetryAspectRatio;
|
||||
struct avi_info_frame_data_byte_3_t pb3;
|
||||
struct avi_info_frame_data_byte_4_t VIC;
|
||||
struct avi_info_frame_data_byte_5_t pb5;
|
||||
uint8_t LineNumEndTopBarLow;
|
||||
uint8_t LineNumEndTopBarHigh;
|
||||
uint8_t LineNumStartBottomBarLow;
|
||||
uint8_t LineNumStartBottomBarHigh;
|
||||
uint8_t LineNumEndLeftBarLow;
|
||||
uint8_t LineNumEndLeftBarHigh;
|
||||
uint8_t LineNumStartRightBarLow;
|
||||
uint8_t LineNumStartRightBarHigh;
|
||||
} bitFields;
|
||||
uint8_t infoFrameData[13];
|
||||
} ifData_u;
|
||||
};
|
||||
|
||||
/* this union overlays the TPI HW for AVI InfoFrames,
|
||||
* starting at REG_TPI_AVI_CHSUM.
|
||||
*/
|
||||
union hw_avi_payload_t {
|
||||
struct hw_avi_named_payload_t namedIfData;
|
||||
uint8_t ifData[14];
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) avi_payload_t {
|
||||
union hw_avi_payload_t hwPayLoad;
|
||||
uint8_t byte_14;
|
||||
uint8_t byte_15;
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) avi_info_frame_t {
|
||||
struct info_frame_header_t header;
|
||||
struct avi_payload_t payLoad;
|
||||
};
|
||||
|
||||
/* these values determine the interpretation of PB5 */
|
||||
enum HDMI_Video_Format_e {
|
||||
hvfNoAdditionalHDMIVideoFormatPresent,
|
||||
hvfExtendedResolutionFormatPresent,
|
||||
hvf3DFormatIndicationPresent
|
||||
};
|
||||
|
||||
enum _3D_structure_e {
|
||||
tdsFramePacking,
|
||||
tdsTopAndBottom = 0x06,
|
||||
tdsSideBySide = 0x08
|
||||
};
|
||||
|
||||
enum ThreeDExtData_e {
|
||||
tdedHorizontalSubSampling,
|
||||
tdedQuincunxOddLeftOddRight = 0x04,
|
||||
tdedQuincunxOddLeftEvenRight,
|
||||
tdedQuincunxEvenLeftOddRight,
|
||||
tdedQuincunxEvenLeftEvenRight
|
||||
};
|
||||
|
||||
enum ThreeDMetaDataType_e {
|
||||
tdmdParallaxIso23022_3Section6_x_2_2
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) hdmi_vendor_specific_payload_t {
|
||||
struct __attribute__ ((__packed__)) {
|
||||
unsigned reserved:5;
|
||||
enum HDMI_Video_Format_e HDMI_Video_Format:3;
|
||||
} pb4;
|
||||
union {
|
||||
uint8_t HDMI_VIC;
|
||||
struct __attribute__ ((__packed__)) _ThreeDStructure {
|
||||
unsigned reserved:3;
|
||||
unsigned ThreeDMetaPresent:1;
|
||||
enum _3D_structure_e threeDStructure:4;
|
||||
} ThreeDStructure;
|
||||
} pb5;
|
||||
struct __attribute__ ((__packed__)) {
|
||||
uint8_t reserved:4;
|
||||
uint8_t threeDExtData:4; /* ThreeDExtData_e */
|
||||
} pb6;
|
||||
struct __attribute__ ((__packed__)) _PB7 {
|
||||
uint8_t threeDMetaDataLength:5;
|
||||
uint8_t threeDMetaDataType:3; /* ThreeDMetaDataType_e */
|
||||
} pb7;
|
||||
};
|
||||
|
||||
#define IEEE_OUI_HDMI 0x000C03
|
||||
#define VSIF_COMMON_FIELDS \
|
||||
struct info_frame_header_t header; \
|
||||
uint8_t checksum; \
|
||||
uint8_t ieee_oui[3];
|
||||
|
||||
struct __attribute__ ((__packed__)) hdmi_vsif_t{
|
||||
VSIF_COMMON_FIELDS
|
||||
struct hdmi_vendor_specific_payload_t payLoad;
|
||||
};
|
||||
|
||||
struct __attribute__ ((__packed__)) vsif_common_header_t {
|
||||
VSIF_COMMON_FIELDS
|
||||
};
|
||||
/*
|
||||
* MPEG Info Frame Structure
|
||||
* Table 8-11 on page 141 of HDMI Spec v1.4
|
||||
*/
|
||||
struct __attribute__ ((__packed__)) unr_info_frame_t {
|
||||
struct info_frame_header_t header;
|
||||
uint8_t checksum;
|
||||
uint8_t byte_1;
|
||||
uint8_t byte_2;
|
||||
uint8_t byte_3;
|
||||
uint8_t byte_4;
|
||||
uint8_t byte_5;
|
||||
uint8_t byte_6;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_DUMP_INFOFRAME
|
||||
|
||||
void DumpIncomingInfoFrameImpl(char *pszId, char *pszFile, int iLine,
|
||||
info_frame_t *pInfoFrame, uint8_t length);
|
||||
|
||||
#define DumpIncomingInfoFrame(pData, length) \
|
||||
DumpIncomingInfoFrameImpl(#pData, __FILE__, __LINE__, \
|
||||
(info_frame_t *)pData, length)
|
||||
#else
|
||||
#define DumpIncomingInfoFrame(pData, length) /* do nothing */
|
||||
#endif
|
||||
|
||||
#endif /* if !defined(SI_INFOFRAME_H) */
|
851
drivers/video/fbdev/msm/mhl3/si_mdt_inputdev.c
Normal file
851
drivers/video/fbdev/msm/mhl3/si_mdt_inputdev.c
Normal file
|
@ -0,0 +1,851 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef MEDIA_DATA_TUNNEL_SUPPORT
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include "si_fw_macros.h"
|
||||
#include "si_infoframe.h"
|
||||
#include "si_edid.h"
|
||||
#include "si_mhl_defs.h"
|
||||
#include "si_mhl2_edid_3d_api.h"
|
||||
#include "si_mhl_tx_hw_drv_api.h"
|
||||
#include "si_mdt_inputdev.h"
|
||||
#include "mhl_linux_tx.h"
|
||||
#include "platform.h"
|
||||
#ifdef KERNEL_2_6_38_AND_LATER
|
||||
#include <linux/input/mt.h>
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
#include <linux/kernel.h>
|
||||
#endif
|
||||
/* keycode map from usbkbd.c */
|
||||
uint8_t usb_kbd_keycode[256] = {
|
||||
0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38,
|
||||
50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3,
|
||||
4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26,
|
||||
27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64,
|
||||
65, 66, 67, 68, 87, 88, 99, 70, 119, 110, 102, 104, 111, 107, 109, 106,
|
||||
105, 108, 103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71,
|
||||
72, 73, 82, 83, 86, 127, 116, 117, 183, 184, 185, 186, 187, 188, 189,
|
||||
190,
|
||||
191, 192, 193, 194, 134, 138, 130, 132, 128, 129, 131, 137, 133, 135,
|
||||
136, 113,
|
||||
115, 114, 0, 0, 0, 121, 0, 89, 93, 124, 92, 94, 95, 0, 0, 0,
|
||||
122, 123, 90, 91, 85, 0, 0, 0, 0, 0, 150, 155, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
200, 201, 207, 208, 213, 215, 216, 217, 226, 139, 172, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
29, 42, 56, 125, 97, 54, 100, 126, 164, 166, 165, 163, 161, 115, 114,
|
||||
113,
|
||||
150, 158, 159, 128, 136, 177, 178, 176, 142, 152, 173, 140
|
||||
};
|
||||
|
||||
static bool is_mdt_dev_active(struct mhl_dev_context *dev_context,
|
||||
enum mdt_dev_types_e dev_type)
|
||||
{
|
||||
if (dev_context->mdt_devs.is_dev_registered[dev_type] == INPUT_ACTIVE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_mdt_dev_waiting(struct mhl_dev_context *dev_context,
|
||||
enum mdt_dev_types_e dev_type)
|
||||
{
|
||||
if (dev_context->mdt_devs.is_dev_registered[dev_type] ==
|
||||
INPUT_WAITING_FOR_REGISTRATION)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void destroy_mouse(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
if (dev_context->mdt_devs.dev_mouse == NULL)
|
||||
return;
|
||||
|
||||
MHL_TX_DBG_INFO("Unregistering mouse: %p\n",
|
||||
dev_context->mdt_devs.dev_mouse);
|
||||
input_unregister_device(dev_context->mdt_devs.dev_mouse);
|
||||
MHL_TX_DBG_INFO("Freeing mouse: %p\n", dev_context->mdt_devs.dev_mouse);
|
||||
input_free_device(dev_context->mdt_devs.dev_mouse);
|
||||
dev_context->mdt_devs.dev_mouse = NULL;
|
||||
}
|
||||
|
||||
static void destroy_keyboard(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
if (dev_context->mdt_devs.dev_keyboard == NULL)
|
||||
return;
|
||||
|
||||
MHL_TX_DBG_INFO("Unregistering keyboard: %p\n",
|
||||
dev_context->mdt_devs.dev_keyboard);
|
||||
input_unregister_device(dev_context->mdt_devs.dev_keyboard);
|
||||
MHL_TX_DBG_INFO("Freeing keyboard: %p\n",
|
||||
dev_context->mdt_devs.dev_keyboard);
|
||||
input_free_device(dev_context->mdt_devs.dev_keyboard);
|
||||
dev_context->mdt_devs.dev_keyboard = NULL;
|
||||
}
|
||||
|
||||
static void destroy_touchscreen(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
if (dev_context->mdt_devs.dev_touchscreen == NULL)
|
||||
return;
|
||||
|
||||
MHL_TX_DBG_INFO("Unregistering mouse: %p\n",
|
||||
dev_context->mdt_devs.dev_touchscreen);
|
||||
input_unregister_device(dev_context->mdt_devs.dev_touchscreen);
|
||||
MHL_TX_DBG_INFO("Freeing mouse: %p\n",
|
||||
dev_context->mdt_devs.dev_touchscreen);
|
||||
input_free_device(dev_context->mdt_devs.dev_touchscreen);
|
||||
dev_context->mdt_devs.dev_touchscreen = NULL;
|
||||
memset(dev_context->mdt_devs.prior_touch_events, 0,
|
||||
MAX_TOUCH_CONTACTS *
|
||||
sizeof(dev_context->mdt_devs.prior_touch_events[0]));
|
||||
}
|
||||
|
||||
int init_mdt_keyboard(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
int i;
|
||||
uint8_t error;
|
||||
struct input_dev *dev_keyboard;
|
||||
|
||||
dev_keyboard = input_allocate_device();
|
||||
if (!dev_keyboard) {
|
||||
MHL_TX_DBG_ERR("Not enough memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
MHL_TX_DBG_INFO("Allocated keyboard: %p\n", dev_keyboard);
|
||||
|
||||
set_bit(EV_KEY, dev_keyboard->evbit);
|
||||
set_bit(EV_REP, dev_keyboard->evbit);
|
||||
|
||||
dev_keyboard->phys = "mdt_kbd/input0";
|
||||
dev_keyboard->name = "MDTkeyboard";
|
||||
dev_keyboard->keycode = usb_kbd_keycode;
|
||||
dev_keyboard->keycodesize = sizeof(unsigned char);
|
||||
dev_keyboard->keycodemax = ARRAY_SIZE(usb_kbd_keycode);
|
||||
|
||||
for (i = 1; i < 256; i++)
|
||||
set_bit(usb_kbd_keycode[i], dev_keyboard->keybit);
|
||||
|
||||
dev_keyboard->id.bustype = BUS_VIRTUAL;
|
||||
dev_keyboard->id.vendor = 0x1095;
|
||||
dev_keyboard->id.product = MHL_PRODUCT_NUM;
|
||||
|
||||
/* Use version to distinguish between devices */
|
||||
dev_keyboard->id.version = 0xA;
|
||||
|
||||
error = input_register_device(dev_keyboard);
|
||||
if (error) {
|
||||
MHL_TX_DBG_ERR("Failed to register device\n");
|
||||
input_free_device(dev_keyboard);
|
||||
return error;
|
||||
}
|
||||
|
||||
MHL_TX_DBG_INFO("Registered keyboard: %p\n", dev_keyboard);
|
||||
|
||||
dev_context->mdt_devs.dev_keyboard = dev_keyboard;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_mdt_mouse(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
uint8_t error;
|
||||
struct input_dev *dev_mouse;
|
||||
|
||||
dev_mouse = input_allocate_device();
|
||||
if (!dev_mouse) {
|
||||
MHL_TX_DBG_ERR("Not enough memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
MHL_TX_DBG_INFO("Allocated mouse: %p\n", dev_mouse);
|
||||
|
||||
set_bit(EV_REL, dev_mouse->evbit);
|
||||
set_bit(EV_KEY, dev_mouse->evbit);
|
||||
set_bit(BTN_LEFT, dev_mouse->keybit);
|
||||
set_bit(BTN_RIGHT, dev_mouse->keybit);
|
||||
set_bit(BTN_MIDDLE, dev_mouse->keybit);
|
||||
set_bit(BTN_SIDE, dev_mouse->keybit);
|
||||
set_bit(BTN_EXTRA, dev_mouse->keybit);
|
||||
set_bit(REL_X, dev_mouse->relbit);
|
||||
set_bit(REL_Y, dev_mouse->relbit);
|
||||
set_bit(REL_WHEEL, dev_mouse->relbit);
|
||||
#if (RIGHT_MOUSE_BUTTON_IS_ESC == 1)
|
||||
set_bit(KEY_ESC, dev_mouse->keybit);
|
||||
dev_context->mdt_devs.prior_right_button = 0;
|
||||
#endif
|
||||
|
||||
dev_mouse->phys = "mdt_mouse/input0";
|
||||
dev_mouse->name = "MDTmouse";
|
||||
dev_mouse->id.bustype = BUS_VIRTUAL;
|
||||
dev_mouse->id.vendor = 0x1095;
|
||||
dev_mouse->id.product = MHL_PRODUCT_NUM;
|
||||
|
||||
/* Use version to distinguish between devices */
|
||||
dev_mouse->id.version = 0xB;
|
||||
|
||||
error = input_register_device(dev_mouse);
|
||||
if (error) {
|
||||
MHL_TX_DBG_ERR("Failed to register device\n");
|
||||
input_free_device(dev_mouse);
|
||||
return error;
|
||||
}
|
||||
|
||||
MHL_TX_DBG_INFO("Registered mouse: %p\n", dev_mouse);
|
||||
|
||||
dev_context->mdt_devs.dev_mouse = dev_mouse;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_mdt_touchscreen(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
uint8_t error;
|
||||
struct input_dev *dev_touchscreen;
|
||||
|
||||
dev_touchscreen = input_allocate_device();
|
||||
if (!dev_touchscreen) {
|
||||
MHL_TX_DBG_ERR("Not enough memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
MHL_TX_DBG_INFO("Allocated touch screen: %p\n", dev_touchscreen);
|
||||
|
||||
#if !defined(SINGLE_TOUCH) && defined(KERNEL_2_6_38_AND_LATER)
|
||||
input_mt_init_slots(dev_touchscreen, MAX_TOUCH_CONTACTS);
|
||||
#endif
|
||||
|
||||
dev_touchscreen->phys = "mdt_touch/input0";
|
||||
dev_touchscreen->name = "MDTtouchscreen";
|
||||
dev_touchscreen->id.bustype = BUS_VIRTUAL;
|
||||
dev_touchscreen->id.vendor = 0x1095;
|
||||
dev_touchscreen->id.product = MHL_PRODUCT_NUM;
|
||||
|
||||
/* use version to distinguish between devices */
|
||||
dev_touchscreen->id.version = 0xC;
|
||||
|
||||
#if defined(SINGLE_TOUCH)
|
||||
__set_bit(EV_ABS, dev_touchscreen->evbit);
|
||||
__set_bit(ABS_X, dev_touchscreen->absbit);
|
||||
__set_bit(ABS_Y, dev_touchscreen->absbit);
|
||||
__set_bit(EV_KEY, dev_touchscreen->evbit);
|
||||
#if (CORNER_BUTTON == 1)
|
||||
__set_bit(KEY_ESC, dev_touchscreen->keybit);
|
||||
#endif
|
||||
__set_bit(BTN_TOUCH, dev_touchscreen->keybit);
|
||||
#ifdef KERNEL_2_6_38_AND_LATER
|
||||
__set_bit(INPUT_PROP_DIRECT, dev_touchscreen->propbit);
|
||||
#endif
|
||||
input_set_abs_params(dev_touchscreen, ABS_X, 0,
|
||||
dev_context->mdt_devs.x_max, 0, 0);
|
||||
input_set_abs_params(dev_touchscreen, ABS_Y, 0,
|
||||
dev_context->mdt_devs.y_max, 0, 0);
|
||||
#else
|
||||
|
||||
__set_bit(EV_ABS, dev_touchscreen->evbit);
|
||||
__set_bit(EV_KEY, dev_touchscreen->evbit);
|
||||
#ifdef KERNEL_2_6_38_AND_LATER
|
||||
__set_bit(EV_SYN, dev_touchscreen->evbit);
|
||||
__set_bit(MT_TOOL_FINGER, dev_touchscreen->keybit);
|
||||
__set_bit(INPUT_PROP_DIRECT, dev_touchscreen->propbit);
|
||||
input_mt_init_slots(dev_touchscreen, MAX_TOUCH_CONTACTS);
|
||||
#else
|
||||
__set_bit(BTN_TOUCH, dev_touchscreen->keybit);
|
||||
input_set_abs_params(dev_touchscreen, ABS_MT_WIDTH_MAJOR, 0, 3, 0, 0);
|
||||
input_set_abs_params(dev_touchscreen, ABS_MT_TRACKING_ID, 0, 3, 0, 0);
|
||||
#endif
|
||||
#if (CORNER_BUTTON == 1)
|
||||
__set_bit(KEY_ESC, dev_touchscreen->keybit);
|
||||
#endif
|
||||
input_set_abs_params(dev_touchscreen, ABS_MT_TOUCH_MAJOR, 0, 30, 0, 0);
|
||||
input_set_abs_params(dev_touchscreen, ABS_MT_PRESSURE, 0, 255, 0, 0);
|
||||
input_set_abs_params(dev_touchscreen, ABS_MT_POSITION_X, 0,
|
||||
dev_context->mdt_devs.x_max, 0, 0);
|
||||
input_set_abs_params(dev_touchscreen, ABS_MT_POSITION_Y, 0,
|
||||
dev_context->mdt_devs.y_max, 0, 0);
|
||||
|
||||
#endif
|
||||
|
||||
#if (JB_421 == 1) && (ICS_BAR == 1)
|
||||
#if (Y_BUTTON_RECENTAPPS_TOP != 0)
|
||||
__set_bit(KEY_MENU, dev_touchscreen->keybit);
|
||||
#endif
|
||||
#if (Y_BUTTON_HOME_TOP != 0)
|
||||
__set_bit(KEY_HOMEPAGE, dev_touchscreen->keybit);
|
||||
#endif
|
||||
#if (Y_BUTTON_BACK_TOP != 0)
|
||||
__set_bit(KEY_BACK, dev_touchscreen->keybit);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
error = input_register_device(dev_touchscreen);
|
||||
if (error) {
|
||||
MHL_TX_DBG_ERR("Failed to register device\n");
|
||||
input_free_device(dev_touchscreen);
|
||||
return error;
|
||||
}
|
||||
MHL_TX_DBG_INFO("Registered touchscreen: %p\n", dev_touchscreen);
|
||||
|
||||
dev_context->mdt_devs.dev_touchscreen = dev_touchscreen;
|
||||
|
||||
/* initialize history; in parcitular initialize state elements with
|
||||
* MDT_TOUCH_INACTIVE
|
||||
*/
|
||||
memset(dev_context->mdt_devs.prior_touch_events, 0,
|
||||
MAX_TOUCH_CONTACTS *
|
||||
sizeof(dev_context->mdt_devs.prior_touch_events[0]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int destroy_device(struct mhl_dev_context *dev_context,
|
||||
enum mdt_dev_types_e mdt_device_type)
|
||||
{
|
||||
if ((mdt_device_type >= MDT_TYPE_COUNT) ||
|
||||
(is_mdt_dev_active(dev_context, mdt_device_type) == 0)) {
|
||||
MHL_TX_DBG_INFO("FAILURE. Invalid disconnect request.\n",
|
||||
mdt_device_type);
|
||||
return REGISTRATION_ERROR;
|
||||
}
|
||||
|
||||
switch (mdt_device_type) {
|
||||
case MDT_TYPE_MOUSE:
|
||||
destroy_mouse(dev_context);
|
||||
break;
|
||||
case MDT_TYPE_KEYBOARD:
|
||||
destroy_keyboard(dev_context);
|
||||
break;
|
||||
case MDT_TYPE_TOUCHSCREEN:
|
||||
destroy_touchscreen(dev_context);
|
||||
break;
|
||||
default:
|
||||
/* redundant check to pacify the compiler */
|
||||
break;
|
||||
}
|
||||
|
||||
dev_context->mdt_devs.is_dev_registered[mdt_device_type] =
|
||||
INPUT_WAITING_FOR_REGISTRATION;
|
||||
|
||||
MHL_TX_DBG_INFO
|
||||
("SUCCESS. Disconnect event handled for %d device type.\n",
|
||||
mdt_device_type);
|
||||
|
||||
return REGISTRATION_SUCCESS;
|
||||
}
|
||||
|
||||
/* The recursive piece of the registration function. */
|
||||
static int registration_helper(struct mhl_dev_context *dev_context,
|
||||
enum mdt_dev_types_e mdt_device_type)
|
||||
{
|
||||
switch (mdt_device_type) {
|
||||
case MDT_TYPE_KEYBOARD:
|
||||
if (dev_context->mdt_devs.dev_keyboard != 0)
|
||||
return REGISTRATION_SUCCESS;
|
||||
return init_mdt_keyboard(dev_context);
|
||||
break;
|
||||
case MDT_TYPE_MOUSE:
|
||||
if (dev_context->mdt_devs.dev_mouse != 0)
|
||||
return REGISTRATION_SUCCESS;
|
||||
if (init_mdt_mouse(dev_context) != REGISTRATION_SUCCESS)
|
||||
return REGISTRATION_ERROR;
|
||||
|
||||
/* Do not support both a pointer and touch. */
|
||||
destroy_device(dev_context, MDT_TYPE_TOUCHSCREEN);
|
||||
break;
|
||||
case MDT_TYPE_TOUCHSCREEN:
|
||||
if (dev_context->mdt_devs.dev_touchscreen != 0)
|
||||
return REGISTRATION_SUCCESS;
|
||||
if (init_mdt_touchscreen(dev_context) != REGISTRATION_SUCCESS)
|
||||
return REGISTRATION_ERROR;
|
||||
|
||||
/* Do not support both a pointer and touch. */
|
||||
destroy_device(dev_context, MDT_TYPE_MOUSE);
|
||||
break;
|
||||
case MDT_TYPE_COUNT:
|
||||
/*
|
||||
* This case is out of range.
|
||||
* Code is included to avoid compiler warning.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
return REGISTRATION_SUCCESS;
|
||||
}
|
||||
|
||||
static int register_device(struct mhl_dev_context *dev_context,
|
||||
enum mdt_dev_types_e mdt_device_type)
|
||||
{
|
||||
uint8_t error = 0;
|
||||
|
||||
if ((mdt_device_type >= MDT_TYPE_COUNT) ||
|
||||
(is_mdt_dev_waiting(dev_context, mdt_device_type) == false))
|
||||
return REGISTRATION_ERROR;
|
||||
|
||||
/* Call recursive part of the function.
|
||||
Don't update is_dev_registered there. */
|
||||
error = registration_helper(dev_context, mdt_device_type);
|
||||
|
||||
if (error != REGISTRATION_SUCCESS) {
|
||||
dev_context->mdt_devs.is_dev_registered[mdt_device_type] =
|
||||
INPUT_DISABLED;
|
||||
MHL_TX_DBG_INFO("SUCCESS. Device type %d registered.\n",
|
||||
mdt_device_type);
|
||||
} else {
|
||||
dev_context->mdt_devs.is_dev_registered[mdt_device_type] =
|
||||
INPUT_ACTIVE;
|
||||
MHL_TX_DBG_INFO
|
||||
("FAILURE. Device type %d registration failed.\n",
|
||||
mdt_device_type);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void generate_event_keyboard(struct mhl_dev_context *dev_context,
|
||||
struct mdt_packet *keyboard_packet)
|
||||
{
|
||||
struct input_dev *dev_keyboard = dev_context->mdt_devs.dev_keyboard;
|
||||
uint8_t *keycodes_new = dev_context->mdt_devs.keycodes_new;
|
||||
uint8_t *keycodes_old = dev_context->mdt_devs.keycodes_old;
|
||||
int i;
|
||||
|
||||
register_device(dev_context, MDT_TYPE_KEYBOARD);
|
||||
|
||||
memcpy(keycodes_new, &keyboard_packet->header, HID_INPUT_REPORT_CNT);
|
||||
MHL_TX_DBG_INFO("Key (scancode %02X) asserted.\n", keycodes_new[1]);
|
||||
|
||||
if (dev_keyboard == 0) {
|
||||
MHL_TX_DBG_INFO("MDT_ERR_NOKEY\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* following code was copied from usbkbd.c */
|
||||
/* generate events for CRL, SHIFT, and ALT keys */
|
||||
for (i = 0; i < 3; i++)
|
||||
input_report_key(dev_keyboard,
|
||||
usb_kbd_keycode[i + 224],
|
||||
(keycodes_new[0] >> i) & 1);
|
||||
|
||||
/*
|
||||
* Generate key press/release events for the
|
||||
* remaining bytes in the input packet
|
||||
*/
|
||||
for (i = 1; i < 7; i++) {
|
||||
/* If keycode in pervious HID payload doesn't appear
|
||||
* in NEW HID payload, generate de-assertion event
|
||||
*/
|
||||
if ((keycodes_old[i] > 3) &&
|
||||
((uint8_t *) memscan(keycodes_new + 1, keycodes_old[i], 6)
|
||||
== ((uint8_t *) (keycodes_new) + 7))) {
|
||||
if (usb_kbd_keycode[keycodes_old[i]]) {
|
||||
input_report_key(dev_keyboard,
|
||||
usb_kbd_keycode[keycodes_old
|
||||
[i]], 0);
|
||||
} else {
|
||||
MHL_TX_DBG_INFO("Unknown key (scancode %#x) "
|
||||
"released.\n", keycodes_old[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If keycode in NEW HID paylaod doesn't appear in previous
|
||||
* HID payload, generate assertion event
|
||||
*/
|
||||
if (keycodes_new[i] > 3 &&
|
||||
memscan(keycodes_old + 1, keycodes_new[i],
|
||||
6) == keycodes_old + 7) {
|
||||
if (usb_kbd_keycode[keycodes_new[i]]) {
|
||||
input_report_key(dev_keyboard,
|
||||
usb_kbd_keycode[keycodes_new
|
||||
[i]], 1);
|
||||
} else {
|
||||
MHL_TX_DBG_INFO("Unknown key (scancode %#x) "
|
||||
"pressed.\n", keycodes_new[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
input_sync(dev_keyboard);
|
||||
|
||||
/* NEW HID payload is now OLD */
|
||||
memcpy(keycodes_old, keycodes_new, HID_INPUT_REPORT_CNT);
|
||||
}
|
||||
|
||||
static void mdt_toggle_keycode(struct input_dev *hid_device,
|
||||
unsigned char keycode)
|
||||
{
|
||||
if (NULL == hid_device)
|
||||
return;
|
||||
|
||||
input_report_key(hid_device, keycode, KEY_PRESSED);
|
||||
input_sync(hid_device);
|
||||
|
||||
input_report_key(hid_device, keycode, KEY_RELEASED);
|
||||
input_sync(hid_device);
|
||||
}
|
||||
|
||||
void mdt_toggle_keyboard_keycode(struct mhl_dev_context *dev_context,
|
||||
unsigned char keycode)
|
||||
{
|
||||
mdt_toggle_keycode(dev_context->mdt_devs.dev_keyboard, keycode);
|
||||
}
|
||||
|
||||
void generate_event_mouse(struct mhl_dev_context *dev_context,
|
||||
struct mdt_packet *mousePacket)
|
||||
{
|
||||
struct input_dev *dev_mouse = dev_context->mdt_devs.dev_mouse;
|
||||
|
||||
register_device(dev_context, MDT_TYPE_MOUSE);
|
||||
|
||||
MHL_TX_DBG_INFO("mouse buttons (0x%02x)\n",
|
||||
mousePacket->header & MDT_HDR_MOUSE_BUTTON_MASK);
|
||||
|
||||
if (dev_mouse == 0) {
|
||||
MHL_TX_DBG_ERR("MDT_ERR_NOMOUSE\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Translate and report mouse button changes */
|
||||
input_report_key(dev_mouse, BTN_LEFT,
|
||||
mousePacket->header & MDT_HDR_MOUSE_BUTTON_1);
|
||||
|
||||
#if (RIGHT_MOUSE_BUTTON_IS_ESC == 1)
|
||||
if (mousePacket->header & MDT_HDR_MOUSE_BUTTON_2) {
|
||||
if (!dev_context->mdt_devs.prior_right_button) {
|
||||
dev_context->mdt_devs.prior_right_button = 1;
|
||||
mdt_toggle_keycode(dev_mouse, KEY_ESC);
|
||||
}
|
||||
} else
|
||||
dev_context->mdt_devs.prior_right_button = 0;
|
||||
#else
|
||||
input_report_key(dev_mouse, BTN_RIGHT,
|
||||
mousePacket->header & MDT_HDR_MOUSE_BUTTON_2);
|
||||
#endif
|
||||
input_report_key(dev_mouse, BTN_MIDDLE,
|
||||
mousePacket->header & MDT_HDR_MOUSE_BUTTON_3);
|
||||
|
||||
input_report_rel(dev_mouse, REL_X,
|
||||
mousePacket->event.mouse.x_displacement);
|
||||
|
||||
input_report_rel(dev_mouse, REL_Y,
|
||||
mousePacket->event.mouse.y_displacement);
|
||||
|
||||
input_report_rel(dev_mouse, REL_WHEEL,
|
||||
mousePacket->event.mouse.z_displacement);
|
||||
|
||||
input_sync(dev_mouse);
|
||||
}
|
||||
|
||||
static uint8_t process_touch_packet(struct mhl_dev_context *dev_context,
|
||||
struct mdt_packet *touchPacket)
|
||||
{
|
||||
struct mdt_touch_history_t *prior_event;
|
||||
int abs_x, abs_y;
|
||||
uint8_t isTouched = (touchPacket->header & 0x01);
|
||||
uint8_t contactID = ((touchPacket->header & 0x06) >> 1);
|
||||
|
||||
prior_event =
|
||||
(struct mdt_touch_history_t *)&(dev_context->mdt_devs.
|
||||
prior_touch_events[contactID]);
|
||||
|
||||
abs_x = touchPacket->event.touch_pad.x_abs_coordinate[MDT_TOUCH_X_LOW] |
|
||||
(touchPacket->event.touch_pad.
|
||||
x_abs_coordinate[MDT_TOUCH_X_HIGH] << 8);
|
||||
abs_y =
|
||||
touchPacket->event.touch_pad.
|
||||
y_abs_coordinate[MDT_TOUCH_Y_LOW] | (touchPacket->event.touch_pad.
|
||||
y_abs_coordinate
|
||||
[MDT_TOUCH_Y_HIGH] << 8);
|
||||
|
||||
#if (CORNER_BUTTON == 1)
|
||||
/* Handle LOWER RIGHT corner like a EXIT button (ESC key) */
|
||||
if ((abs_x > X_CORNER_RIGHT_LOWER) && (abs_y > Y_CORNER_RIGHT_LOWER)) {
|
||||
if (isTouched != dev_context->mdt_devs.prior_touch_button) {
|
||||
dev_context->mdt_devs.prior_touch_button = isTouched;
|
||||
if (isTouched)
|
||||
mdt_toggle_keycode(dev_context->mdt_devs.
|
||||
dev_touchscreen, KEY_ESC);
|
||||
}
|
||||
return 0xFF;
|
||||
}
|
||||
#elif (ICS_BAR == 1)
|
||||
/* JB421 doesn't allow this driver to trigger buttons on the bar.
|
||||
implement custom buttons to workaround the problem. */
|
||||
if ((isTouched != dev_context->mdt_devs.prior_touch_button)
|
||||
&& (abs_x >= X_BUTTON_BAR_START)) {
|
||||
if ((abs_y > Y_BUTTON_RECENTAPPS_TOP)
|
||||
&& (abs_y < Y_BUTTON_RECENTAPPS_BOTTOM))
|
||||
mdt_toggle_keycode(dev_context->mdt_devs.
|
||||
dev_touchscreen, KEY_MENU);
|
||||
else if ((abs_y > Y_BUTTON_HOME_TOP)
|
||||
&& (abs_y < Y_BUTTON_HOME_BOTTOM))
|
||||
mdt_toggle_keycode(dev_context->mdt_devs.
|
||||
dev_touchscreen, KEY_HOMEPAGE);
|
||||
else if ((abs_y > Y_BUTTON_BACK_TOP)
|
||||
&& (abs_y < Y_BUTTON_BACK_BOTTOM))
|
||||
mdt_toggle_keycode(dev_context->mdt_devs.
|
||||
dev_touchscreen, KEY_BACK);
|
||||
return 0xFF;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* support dynamic configuration through ATTRIBUTES */
|
||||
if (dev_context->mdt_devs.swap_xy != 0) {
|
||||
prior_event->abs_x = abs_y;
|
||||
prior_event->abs_y = abs_x;
|
||||
} else {
|
||||
prior_event->abs_x = abs_x;
|
||||
prior_event->abs_y = abs_y;
|
||||
}
|
||||
|
||||
if ((dev_context->mdt_devs.x_raw != 0) &&
|
||||
(dev_context->mdt_devs.x_screen != 0) &&
|
||||
(prior_event->abs_x != 0)) {
|
||||
prior_event->abs_x *= dev_context->mdt_devs.x_screen;
|
||||
prior_event->abs_x /= dev_context->mdt_devs.x_raw;
|
||||
}
|
||||
|
||||
if ((dev_context->mdt_devs.y_raw != 0) &&
|
||||
(dev_context->mdt_devs.y_screen != 0) &&
|
||||
(prior_event->abs_y != 0)) {
|
||||
prior_event->abs_y *= dev_context->mdt_devs.y_screen;
|
||||
prior_event->abs_y /= dev_context->mdt_devs.y_raw;
|
||||
}
|
||||
|
||||
if ((dev_context->mdt_devs.swap_leftright) &&
|
||||
(dev_context->mdt_devs.x_max >= prior_event->abs_x))
|
||||
prior_event->abs_x =
|
||||
(dev_context->mdt_devs.x_max - prior_event->abs_x);
|
||||
|
||||
if ((dev_context->mdt_devs.swap_updown) &&
|
||||
(dev_context->mdt_devs.y_max >= prior_event->abs_y))
|
||||
prior_event->abs_y =
|
||||
(dev_context->mdt_devs.y_max - prior_event->abs_y);
|
||||
|
||||
prior_event->abs_x += dev_context->mdt_devs.x_shift;
|
||||
prior_event->abs_y += dev_context->mdt_devs.y_shift;
|
||||
|
||||
if (isTouched == 0) {
|
||||
if (prior_event->isTouched == 0)
|
||||
/* Multiple release events;
|
||||
* declare contact inactive & ignore
|
||||
*/
|
||||
prior_event->state = MDT_TOUCH_INACTIVE;
|
||||
} else {
|
||||
prior_event->state = MDT_TOUCH_ACTIVE;
|
||||
}
|
||||
prior_event->isTouched = isTouched;
|
||||
|
||||
return contactID;
|
||||
}
|
||||
|
||||
#if defined(SINGLE_TOUCH)
|
||||
static void submit_touchscreen_events_as_single_touch(
|
||||
struct mhl_dev_context *dev_context)
|
||||
{
|
||||
struct input_dev *dev_ts = dev_context->mdt_devs.dev_touchscreen;
|
||||
struct mdt_touch_history_t *prior_event;
|
||||
|
||||
prior_event = &(dev_context->mdt_devs.prior_touch_events[0]);
|
||||
input_report_key(dev_ts, BTN_TOUCH, prior_event->isTouched);
|
||||
input_report_abs(dev_ts, ABS_X, prior_event->abs_x);
|
||||
input_report_abs(dev_ts, ABS_Y, prior_event->abs_y);
|
||||
}
|
||||
#elif defined(KERNEL_2_6_38_AND_LATER)
|
||||
static void submit_touchscreen_events_with_proto_B(
|
||||
struct mhl_dev_context *dev_context, uint8_t contactID)
|
||||
{
|
||||
struct input_dev *dev_ts = dev_context->mdt_devs.dev_touchscreen;
|
||||
struct mdt_touch_history_t *prior_event;
|
||||
uint8_t i;
|
||||
uint8_t counter = 0;
|
||||
|
||||
for (i = 0; i < MAX_TOUCH_CONTACTS; i++) {
|
||||
|
||||
prior_event = &(dev_context->mdt_devs.prior_touch_events[i]);
|
||||
|
||||
if (prior_event->state == MDT_TOUCH_INACTIVE)
|
||||
continue;
|
||||
|
||||
input_mt_slot(dev_ts, i);
|
||||
input_mt_report_slot_state(dev_ts, MT_TOOL_FINGER,
|
||||
prior_event->isTouched);
|
||||
|
||||
/* Event already handled; don't handle it again. */
|
||||
if (prior_event->isTouched == 0) {
|
||||
prior_event->state = MDT_TOUCH_INACTIVE;
|
||||
} else {
|
||||
counter++;
|
||||
input_report_abs(dev_ts, ABS_MT_TOUCH_MAJOR, 15);
|
||||
input_report_abs(dev_ts, ABS_MT_PRESSURE, 50);
|
||||
input_report_abs(dev_ts, ABS_MT_POSITION_X,
|
||||
prior_event->abs_x);
|
||||
input_report_abs(dev_ts, ABS_MT_POSITION_Y,
|
||||
prior_event->abs_y);
|
||||
}
|
||||
|
||||
/* BTN_TOUCH breaks support brokend as of JB42 */
|
||||
#if !defined(JB_421)
|
||||
if (counter == 1)
|
||||
input_report_key(dev_ts, BTN_TOUCH, 1);
|
||||
else
|
||||
input_report_key(dev_ts, BTN_TOUCH, 0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void submit_touchscreen_events_with_proto_A(
|
||||
struct mhl_dev_context *dev_context, uint8_t contactID)
|
||||
{
|
||||
struct input_dev *dev_ts = dev_context->mdt_devs.dev_touchscreen;
|
||||
struct mdt_touch_history_t *prior_event;
|
||||
uint8_t i;
|
||||
uint8_t count = 0;
|
||||
|
||||
for (i = 0; i < MAX_TOUCH_CONTACTS; i++) {
|
||||
prior_event = &(dev_context->mdt_devs.prior_touch_events[i]);
|
||||
|
||||
if (prior_event->state == MDT_TOUCH_INACTIVE)
|
||||
continue;
|
||||
|
||||
count++;
|
||||
|
||||
if (prior_event->isTouched == 0)
|
||||
/* Event handled; don't handle it again. */
|
||||
prior_event->state = MDT_TOUCH_INACTIVE;
|
||||
|
||||
input_report_key(dev_ts, BTN_TOUCH, prior_event->isTouched);
|
||||
input_report_abs(dev_ts, ABS_MT_TOUCH_MAJOR,
|
||||
prior_event->isTouched);
|
||||
input_report_abs(dev_ts, ABS_MT_TRACKING_ID, i);
|
||||
input_report_abs(dev_ts, ABS_MT_WIDTH_MAJOR, 1);
|
||||
input_report_abs(dev_ts, ABS_MT_POSITION_X, prior_event->abs_x);
|
||||
input_report_abs(dev_ts, ABS_MT_POSITION_Y, prior_event->abs_y);
|
||||
input_mt_sync(dev_ts);
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
input_mt_sync(dev_ts);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void generate_event_touchscreen(struct mhl_dev_context *dev_context,
|
||||
struct mdt_packet *touchPacket)
|
||||
{
|
||||
struct input_dev *dev_ts = dev_context->mdt_devs.dev_touchscreen;
|
||||
uint8_t contactID;
|
||||
|
||||
register_device(dev_context, MDT_TYPE_TOUCHSCREEN);
|
||||
|
||||
if (dev_ts == 0) {
|
||||
MHL_TX_DBG_ERR("MDT_ERR_NOTOUCHSCREEN\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* process touch packet into prior_touch_events */
|
||||
contactID = process_touch_packet(dev_context, touchPacket);
|
||||
if (contactID == 0xFF)
|
||||
return;
|
||||
|
||||
#if defined(SINGLE_TOUCH)
|
||||
submit_touchscreen_events_as_single_touch(dev_context);
|
||||
#elif defined(KERNEL_2_6_38_AND_LATER)
|
||||
submit_touchscreen_events_with_proto_B(dev_context, contactID);
|
||||
#else
|
||||
submit_touchscreen_events_with_proto_A(dev_context, contactID);
|
||||
#endif
|
||||
/* generate touchscreen assertion */
|
||||
input_sync(dev_ts);
|
||||
}
|
||||
|
||||
static bool process_hotplug_packet(struct mhl_dev_context *dev_context,
|
||||
struct mdt_packet *hotplug_packet)
|
||||
{
|
||||
/* 'M' previoulsy found to be in the header byte */
|
||||
if ((hotplug_packet->event.hotplug.sub_header_d != D_CHAR) &&
|
||||
(hotplug_packet->event.hotplug.sub_header_t != T_CHAR) &&
|
||||
(hotplug_packet->event.hotplug.mdt_version != MDT_VERSION))
|
||||
return false;
|
||||
|
||||
/* in the future, support response with ACK or NACK */
|
||||
MHL_TX_DBG_INFO("HP packet. Device type: %02x. Event: %02x.\n",
|
||||
hotplug_packet->event.hotplug.device_type,
|
||||
hotplug_packet->event.hotplug.event_code);
|
||||
switch (hotplug_packet->event.hotplug.event_code) {
|
||||
case NOTICE_DEV_PLUG:
|
||||
register_device(dev_context,
|
||||
hotplug_packet->event.hotplug.device_type);
|
||||
break;
|
||||
case NOTICE_DEV_UNPLUG:
|
||||
destroy_device(dev_context,
|
||||
hotplug_packet->event.hotplug.device_type);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool si_mhl_tx_mdt_process_packet(struct mhl_dev_context *dev_context,
|
||||
void *packet)
|
||||
{
|
||||
struct mdt_packet *mdt_event_packet = (struct mdt_packet *)packet;
|
||||
|
||||
if (!(MDT_HDR_IS_HID & mdt_event_packet->header)) {
|
||||
if (M_CHAR == mdt_event_packet->header)
|
||||
return process_hotplug_packet(dev_context,
|
||||
mdt_event_packet);
|
||||
|
||||
MHL_TX_DBG_INFO("Ignoring non-HID packet\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (MDT_HDR_IS_KEYBOARD & mdt_event_packet->header) {
|
||||
generate_event_keyboard(dev_context, mdt_event_packet);
|
||||
|
||||
} else if (!(MDT_HDR_IS_KEYBOARD & mdt_event_packet->header) &&
|
||||
(!(MDT_HDR_IS_NOT_MOUSE & mdt_event_packet->header))) {
|
||||
generate_event_mouse(dev_context, mdt_event_packet);
|
||||
|
||||
} else if (!(MDT_HDR_IS_KEYBOARD & mdt_event_packet->header) &&
|
||||
(MDT_HDR_IS_NOT_MOUSE & mdt_event_packet->header)) {
|
||||
generate_event_touchscreen(dev_context, mdt_event_packet);
|
||||
|
||||
} else if (!(MDT_HDR_IS_KEYBOARD & mdt_event_packet->header) &&
|
||||
(MDT_HDR_IS_NOT_MOUSE & mdt_event_packet->header) &&
|
||||
(MDT_HDR_IS_NOT_LAST & mdt_event_packet->header)) {
|
||||
|
||||
MHL_TX_DBG_INFO("Unsupported gaming controller "
|
||||
"event received\n");
|
||||
} else {
|
||||
MHL_TX_DBG_INFO("Event is either not an HID event or "
|
||||
"is an an unknown HID event type\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Consume the write burst event as an MDT event */
|
||||
return true;
|
||||
}
|
||||
|
||||
void mdt_destroy(struct mhl_dev_context *dev_context)
|
||||
{
|
||||
destroy_device(dev_context, MDT_TYPE_KEYBOARD);
|
||||
destroy_device(dev_context, MDT_TYPE_MOUSE);
|
||||
destroy_device(dev_context, MDT_TYPE_TOUCHSCREEN);
|
||||
}
|
||||
#endif
|
216
drivers/video/fbdev/msm/mhl3/si_mdt_inputdev.h
Normal file
216
drivers/video/fbdev/msm/mhl3/si_mdt_inputdev.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SI_MDT_INPUTDEV_H_
|
||||
#define _SI_MDT_INPUTDEV_H_
|
||||
|
||||
#define HID_INPUT_REPORT_CNT 7
|
||||
#define MAX_TOUCH_CONTACTS 4
|
||||
|
||||
/* MDT header byte bit definitions */
|
||||
#define REGISTRATION_SUCCESS 0
|
||||
#define REGISTRATION_ERROR 1
|
||||
#define KEY_PRESSED 1
|
||||
#define KEY_RELEASED 0
|
||||
#define MDT_TOUCH_INACTIVE 1
|
||||
#define MDT_TOUCH_ACTIVE 2
|
||||
|
||||
/* Common header bit definitions */
|
||||
#define MDT_HDR_IS_HID 0x80
|
||||
#define MDT_HDR_IS_PORT_B 0x40
|
||||
#define MDT_HDR_IS_KEYBOARD 0x20
|
||||
#define MDT_HDR_IS_NOT_LAST 0x10
|
||||
#define MDT_HDR_IS_NOT_MOUSE 0x08
|
||||
|
||||
/* Keyboard event specific header bit definitions */
|
||||
#define MDT_HDR_KBD_LEFT_ALT 0x04
|
||||
#define MDT_HDR_KBD_LEFT_SHIFT 0x02
|
||||
#define MDT_HDR_KBD_LEFT_CTRL 0x01
|
||||
|
||||
/* Mouse event specific header bit definitions */
|
||||
#define MDT_HDR_MOUSE_BUTTON_3 0x04
|
||||
#define MDT_HDR_MOUSE_BUTTON_2 0x02
|
||||
#define MDT_HDR_MOUSE_BUTTON_1 0x01
|
||||
#define MDT_HDR_MOUSE_BUTTON_MASK 0x07
|
||||
|
||||
/* Touch pad event specific header bit definitions */
|
||||
#define MDT_HDR_TOUCH_IS_TOUCHED 0x01
|
||||
#define MDT_HDR_TOUCH_CONTACT_ID_MASK 0x06
|
||||
|
||||
/* Game controller event specific header bit definitions */
|
||||
#define MDT_HDR_GAME_BUTTON_3 0x04
|
||||
#define MDT_HDR_GAME_BUTTON_2 0x02
|
||||
#define MDT_HDR_GAME_BUTTON_1 0x01
|
||||
|
||||
/* MDT hot-plug prefix and event information */
|
||||
#define MDT_VERSION 1
|
||||
#define M_CHAR 'M'
|
||||
#define D_CHAR 'D'
|
||||
#define T_CHAR 'T'
|
||||
#define NOTICE_DEV_PLUG 'R'
|
||||
#define NOTICE_DEV_UNPLUG 'U'
|
||||
#define RESPONSE_ACK 'A'
|
||||
#define RESPONSE_NACK 'N'
|
||||
|
||||
/* MDT Touch screen resources and parameters */
|
||||
|
||||
#define MDT_TOUCH_X 0
|
||||
#define MDT_TOUCH_Y 1
|
||||
#define BYTE_LOW 0
|
||||
#define BYTE_HIGH 1
|
||||
#define MDT_TOUCH_X_LOW BYTE_LOW
|
||||
#define MDT_TOUCH_X_HIGH BYTE_HIGH
|
||||
#define MDT_TOUCH_Y_LOW BYTE_LOW
|
||||
#define MDT_TOUCH_Y_HIGH BYTE_HIGH
|
||||
|
||||
/* support 11 bit absolute addressing */
|
||||
#define X_CORNER_RIGHT_LOWER 1870
|
||||
#define Y_CORNER_RIGHT_LOWER 1870
|
||||
#define ICS_BeagleboardxM 1
|
||||
#define X_MAX 1920
|
||||
#define Y_MAX 1920
|
||||
#define SCALE_X_RAW 0
|
||||
#define SCALE_X_SCREEN 0
|
||||
#define SCALE_Y_RAW 0
|
||||
#define SCALE_Y_SCREEN 0
|
||||
#define X_SHIFT 0
|
||||
#define Y_SHIFT 0
|
||||
#define SWAP_LEFTRIGHT 0
|
||||
#define SWAP_UPDOWN 0
|
||||
#define SWAP_XY 0
|
||||
#define SINGLE_TOUCH 1
|
||||
#define CORNER_BUTTON 1
|
||||
#define ICS_BAR 0
|
||||
#define RIGHT_MOUSE_BUTTON_IS_ESC 1
|
||||
/* requires installation of IDC file */
|
||||
/* #define KERNEL_2_6_38_AND_LATER */
|
||||
/* as of JB the IDC file is needed but, doesn't
|
||||
guarantee acess to virtual buttons. */
|
||||
#define JB_421 0
|
||||
#if (JB_421 == 1)
|
||||
#define X_BUTTON_BAR_START 0x4F0
|
||||
#define Y_BUTTON_RECENTAPPS_TOP 0x050
|
||||
#define Y_BUTTON_RECENTAPPS_BOTTOM 0x165
|
||||
#define Y_BUTTON_HOME_TOP 0x185
|
||||
#define Y_BUTTON_HOME_BOTTOM 0x2C0
|
||||
#define Y_BUTTON_BACK_TOP 0x2E0
|
||||
#define Y_BUTTON_BACK_BOTTOM 0x3E0
|
||||
#endif
|
||||
|
||||
enum mdt_dev_state_e {
|
||||
INPUT_DISABLED,
|
||||
INPUT_WAITING_FOR_REGISTRATION,
|
||||
INPUT_ACTIVE
|
||||
};
|
||||
|
||||
enum mdt_dev_types_e {
|
||||
MDT_TYPE_MOUSE,
|
||||
MDT_TYPE_KEYBOARD,
|
||||
MDT_TYPE_TOUCHSCREEN,
|
||||
MDT_TYPE_COUNT
|
||||
};
|
||||
|
||||
struct mdt_touch_history_t {
|
||||
uint32_t abs_x;
|
||||
uint32_t abs_y;
|
||||
uint8_t isTouched;
|
||||
uint8_t state;
|
||||
};
|
||||
|
||||
struct mdt_inputdevs {
|
||||
/* Prior HID input report */
|
||||
uint8_t keycodes_old[HID_INPUT_REPORT_CNT];
|
||||
/* Current HID input report */
|
||||
uint8_t keycodes_new[HID_INPUT_REPORT_CNT];
|
||||
struct input_dev *dev_keyboard;
|
||||
struct input_dev *dev_mouse;
|
||||
struct input_dev *dev_touchscreen;
|
||||
/* Instance tracking variable */
|
||||
uint8_t is_dev_registered[MDT_TYPE_COUNT];
|
||||
struct mdt_touch_history_t prior_touch_events[MAX_TOUCH_CONTACTS];
|
||||
unsigned char prior_touch_button;
|
||||
|
||||
#if (RIGHT_MOUSE_BUTTON_IS_ESC == 1)
|
||||
unsigned char prior_right_button;
|
||||
#endif
|
||||
/* ser overrides to allow runtime calibration */
|
||||
uint32_t x_max, y_max;
|
||||
uint32_t x_screen, x_raw, x_shift;
|
||||
uint32_t y_screen, y_raw, y_shift;
|
||||
uint32_t swap_xy, swap_updown, swap_leftright;
|
||||
};
|
||||
|
||||
struct keyboard_event_data {
|
||||
uint8_t first_key[3];
|
||||
uint8_t second_key[3];
|
||||
};
|
||||
|
||||
struct mouse_event_data {
|
||||
int8_t x_displacement;
|
||||
int8_t y_displacement;
|
||||
int8_t z_displacement;
|
||||
uint8_t vendor_specific[2];
|
||||
uint8_t vendor_specific_game_flag;
|
||||
};
|
||||
|
||||
struct touch_pad_event_data {
|
||||
uint8_t x_abs_coordinate[2];
|
||||
uint8_t y_abs_coordinate[2];
|
||||
uint8_t vendor_specific;
|
||||
uint8_t vendor_specific_game_flag;
|
||||
};
|
||||
|
||||
struct gaming_controller {
|
||||
int8_t x_rel_displacement;
|
||||
int8_t y_rel_displacement;
|
||||
int8_t z_rel_displacement;
|
||||
int8_t y2_rel_displacement;
|
||||
uint8_t buttons_ext;
|
||||
uint8_t id_dpad;
|
||||
};
|
||||
|
||||
struct mdt_hotplug_data {
|
||||
uint8_t sub_header_d;
|
||||
uint8_t sub_header_t;
|
||||
uint8_t event_code;
|
||||
uint8_t device_type;
|
||||
uint8_t mdt_version;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
struct mdt_packet {
|
||||
uint8_t adopter_id_h;
|
||||
uint8_t adopter_id_l;
|
||||
uint8_t header;
|
||||
union {
|
||||
struct keyboard_event_data keyboard;
|
||||
struct mouse_event_data mouse;
|
||||
struct touch_pad_event_data touch_pad;
|
||||
struct gaming_controller game_controller;
|
||||
struct mdt_hotplug_data hotplug;
|
||||
uint8_t bytes[6];
|
||||
} event;
|
||||
};
|
||||
|
||||
struct mhl_dev_context;
|
||||
extern struct attribute_group mdt_attr_group;
|
||||
void mdt_toggle_keyboard_keycode(struct mhl_dev_context *dev_context,
|
||||
unsigned char keycode);
|
||||
bool si_mhl_tx_mdt_process_packet(struct mhl_dev_context *dev_context,
|
||||
void *packet);
|
||||
|
||||
void mdt_destroy(struct mhl_dev_context *dev_context);
|
||||
|
||||
#endif /* #ifndef _SI_MDT_INPUTDEV_H_ */
|
4562
drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c
Normal file
4562
drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d.c
Normal file
File diff suppressed because it is too large
Load diff
183
drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d_api.h
Normal file
183
drivers/video/fbdev/msm/mhl3/si_mhl2_edid_3d_api.h
Normal file
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SI_MHL2_EDID_3D_API_H_
|
||||
#define _SI_MHL2_EDID_3D_API_H_
|
||||
|
||||
#define EDID_BLOCK_SIZE 128
|
||||
#define BIT_EDID_FIELD_FORMAT_HDMI_TO_RGB 0x00
|
||||
#define BIT_EDID_FIELD_FORMAT_YCbCr422 0x01
|
||||
#define BIT_EDID_FIELD_FORMAT_YCbCr444 0x02
|
||||
#define BIT_EDID_FIELD_FORMAT_DVI_TO_RGB 0x03
|
||||
|
||||
struct edid_3d_flags_t {
|
||||
unsigned parse_3d_in_progress:1;
|
||||
unsigned FLAGS_SENT_3D_REQ:1;
|
||||
unsigned FLAGS_BURST_3D_VIC_DONE:1;
|
||||
unsigned FLAGS_BURST_3D_DTD_DONE:1;
|
||||
|
||||
unsigned FLAGS_BURST_3D_DTD_VESA_DONE:1;
|
||||
unsigned FLAGS_BURST_3D_DONE:1;
|
||||
unsigned FLAGS_EDID_READ_DONE:1;
|
||||
unsigned reserved:1;
|
||||
};
|
||||
|
||||
#define MAX_V_DESCRIPTORS 21
|
||||
#define MAX_A_DESCRIPTORS 10
|
||||
#define MAX_SPEAKER_CONFIGURATIONS 4
|
||||
#define AUDIO_DESCR_SIZE 3
|
||||
|
||||
#define NUM_VIDEO_DATA_BLOCKS_LIMIT 3
|
||||
|
||||
struct edid_parse_data_t {
|
||||
struct edid_3d_flags_t flags;
|
||||
struct vsdb_t *p_HDMI_vsdb;
|
||||
struct video_data_block_t *
|
||||
p_video_data_blocks_2d[NUM_VIDEO_DATA_BLOCKS_LIMIT];
|
||||
struct video_capability_data_block_t *p_video_capability_data_block;
|
||||
struct VSDB_byte_13_through_byte_15_t *p_byte_13_through_byte_15;
|
||||
struct _3D_mask_t *p_3d_mask;
|
||||
union _3D_structure_and_detail_entry_u *p_three_d;
|
||||
uint8_t *p_3d_limit;
|
||||
/* counter for initial EDID parsing, persists afterwards */
|
||||
uint8_t num_video_data_blocks;
|
||||
/* counter for 3D write burst parsing. */
|
||||
uint8_t video_data_block_index;
|
||||
uint8_t burst_entry_count_3d_vic;
|
||||
uint8_t vic_2d_index;
|
||||
uint8_t vic_3d_index;
|
||||
uint8_t burst_entry_count_3d_dtd;
|
||||
uint8_t vesa_dtd_index;
|
||||
uint8_t cea_861_dtd_index;
|
||||
uint8_t num_vesa_timing_dtds;
|
||||
uint8_t num_cea_861_timing_dtds;
|
||||
/* maximum number of audio descriptors */
|
||||
struct CEA_short_audio_descriptor_t
|
||||
audio_descriptors[MAX_A_DESCRIPTORS];
|
||||
/* maximum number of speaker configurations */
|
||||
uint8_t speaker_alloc[MAX_SPEAKER_CONFIGURATIONS];
|
||||
/* "1" if DTV monitor underscans IT video formats by default */
|
||||
bool underscan;
|
||||
bool basic_audio; /* Sink supports Basic Audio */
|
||||
bool YCbCr_4_4_4; /* Sink supports YCbCr 4:4:4 */
|
||||
bool YCbCr_4_2_2; /* Sink supports YCbCr 4:2:2 */
|
||||
bool HDMI_sink; /* "1" if HDMI signature found */
|
||||
/* CEC Physical address. See HDMI 1.3 Table 8-6 */
|
||||
uint8_t CEC_A_B;
|
||||
uint8_t CEC_C_D;
|
||||
uint8_t video_capability_flags;
|
||||
/* IEC 61966-2-4 colorimetry support: 1 - xvYCC601; 2 - xvYCC709 */
|
||||
uint8_t colorimetry_support_flags;
|
||||
uint8_t meta_data_profile;
|
||||
bool _3D_supported;
|
||||
uint8_t num_EDID_extensions;
|
||||
};
|
||||
|
||||
struct mhl_dev_context;
|
||||
|
||||
struct item_alloc_info_t {
|
||||
size_t num_items;
|
||||
size_t num_items_allocated;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
struct edid_3d_data_t {
|
||||
struct mhl_dev_context *dev_context;
|
||||
struct drv_hw_context *drv_context;
|
||||
struct MHL3_hev_dtd_item_t hev_dtd_payload;
|
||||
struct MHL3_hev_dtd_item_t *hev_dtd_list;
|
||||
struct item_alloc_info_t hev_dtd_info;
|
||||
struct MHL3_hev_vic_item_t *hev_vic_list;
|
||||
struct item_alloc_info_t hev_vic_info;
|
||||
struct MHL3_3d_dtd_item_t *_3d_dtd_list;
|
||||
struct item_alloc_info_t _3d_dtd_info;
|
||||
struct MHL3_3d_vic_item_t *_3d_vic_list;
|
||||
struct item_alloc_info_t _3d_vic_info;
|
||||
struct edid_parse_data_t parse_data;
|
||||
uint8_t num_emsc_edid_extensions;
|
||||
uint8_t num_edid_emsc_blocks;
|
||||
uint8_t cur_edid_emsc_block;
|
||||
uint8_t *p_edid_emsc;
|
||||
uint8_t EDID_block_data[4 * EDID_BLOCK_SIZE];
|
||||
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT si_incoming_timing_t {
|
||||
uint32_t calculated_pixel_clock;
|
||||
uint16_t h_total;
|
||||
uint16_t v_total;
|
||||
uint16_t columns;
|
||||
uint16_t rows;
|
||||
uint16_t field_rate;
|
||||
uint8_t mhl3_vic;
|
||||
};
|
||||
|
||||
struct mhl_dev_context *si_edid_create_context(
|
||||
struct mhl_dev_context *dev_context,
|
||||
struct drv_hw_context *drv_context);
|
||||
|
||||
void *si_edid_get_processed_edid(struct edid_3d_data_t *mhl_edid_3d_data);
|
||||
void si_edid_destroy_context(struct edid_3d_data_t *mhl_edid_3d_data);
|
||||
void si_mhl_tx_initiate_edid_sequence(struct edid_3d_data_t *mhl_edid_3d_data);
|
||||
void si_mhl_tx_process_3d_vic_burst(void *context,
|
||||
struct MHL2_video_format_data_t *pWriteBurstData);
|
||||
void si_mhl_tx_process_3d_dtd_burst(void *context,
|
||||
struct MHL2_video_format_data_t *pWriteBurstData);
|
||||
void si_mhl_tx_process_hev_vic_burst(struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
struct MHL3_hev_vic_data_t *p_write_burst_data);
|
||||
void si_mhl_tx_process_hev_dtd_a_burst(struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
struct MHL3_hev_dtd_a_data_t *p_burst);
|
||||
void si_mhl_tx_process_hev_dtd_b_burst(struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
struct MHL3_hev_dtd_b_data_t *p_burst);
|
||||
uint32_t si_mhl_tx_find_timings_from_totals(
|
||||
struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
struct si_incoming_timing_t *p_timing);
|
||||
int si_edid_sink_is_hdmi(void *context);
|
||||
int si_edid_quantization_range_selectable(void *context);
|
||||
int si_edid_sink_supports_YCbCr422(void *context);
|
||||
int si_edid_sink_supports_YCbCr444(void *context);
|
||||
int si_edid_find_pixel_clock_from_HDMI_VIC(void *context, uint8_t vic);
|
||||
int si_edid_find_pixel_clock_from_AVI_VIC(void *context, uint8_t vic);
|
||||
uint8_t si_edid_map_hdmi_vic_to_mhl3_vic(void *context, uint8_t vic);
|
||||
|
||||
enum NumExtensions_e {
|
||||
ne_NO_HPD = -4,
|
||||
ne_BAD_DATA = -3,
|
||||
ne_BAD_CHECKSUM = ne_BAD_DATA,
|
||||
ne_BAD_HEADER = -2,
|
||||
ne_BAD_HEADER_OFFSET_BY_1 = -1,
|
||||
ne_SUCCESS = 0
|
||||
};
|
||||
|
||||
#ifdef MANUAL_EDID_FETCH
|
||||
bool si_mhl_tx_check_edid_header(struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
void *pdata);
|
||||
#endif
|
||||
int si_mhl_tx_get_num_cea_861_extensions(void *context, uint8_t block_number);
|
||||
int si_edid_read_done(void *context);
|
||||
void si_edid_reset(struct edid_3d_data_t *mhl_edid_3d_data);
|
||||
uint8_t qualify_pixel_clock_for_mhl(struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
uint32_t pixel_clock_frequency, uint8_t bits_per_pixel);
|
||||
uint8_t calculate_generic_checksum(void *infoFrameData, uint8_t checkSum,
|
||||
uint8_t length);
|
||||
uint32_t si_edid_find_pixel_clock_from_HEV_DTD(
|
||||
struct edid_3d_data_t *mhl_edid_3d_data,
|
||||
struct MHL_high_low_t hev_fmt);
|
||||
void si_mhl_tx_display_timing_enumeration_end(
|
||||
struct edid_3d_data_t *mhl_edid_3d_data);
|
||||
|
||||
int process_emsc_edid_sub_payload(struct edid_3d_data_t *edid_context,
|
||||
struct si_adopter_id_data *p_burst);
|
||||
#endif
|
243
drivers/video/fbdev/msm/mhl3/si_mhl_callback_api.h
Normal file
243
drivers/video/fbdev/msm/mhl3/si_mhl_callback_api.h
Normal file
|
@ -0,0 +1,243 @@
|
|||
#ifndef _SI_MHL_CALLBACK_API_H_
|
||||
#define _SI_MHL_CALLBACK_API_H_
|
||||
|
||||
union __attribute__((__packed__)) avif_or_cea_861_dtd_u
|
||||
{
|
||||
struct detailed_timing_descriptor_t cea_861_dtd;
|
||||
struct avi_info_frame_t avif;
|
||||
};
|
||||
|
||||
enum hpd_high_callback_status {
|
||||
/* successful return values for hpd_driven_high(): */
|
||||
|
||||
/* a DTD has been written to the p_avif_or_dtd buffer instead of an AVI
|
||||
* infoframe
|
||||
*/
|
||||
HH_FMT_DVI = 0x00000000,
|
||||
/* No Vendor Specific InfoFrame provided */
|
||||
HH_FMT_HDMI_VSIF_NONE = 0x00000001,
|
||||
/* HDMI vsif has been filled into p_vsif */
|
||||
HH_FMT_HDMI_VSIF_HDMI = 0x00000002,
|
||||
/* MHL3 vsif has been filled into p_vsif */
|
||||
HH_FMT_HDMI_VSIF_MHL3 = 0x00000003,
|
||||
/* a DTD has been written to the DTD buffer instead of an AVI infoframe
|
||||
* and 8620 shall expect HDCP enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_DVI_HDCP_ON = 0x00000004,
|
||||
/* No Vendor Specific InfoFrame provided and 8620 shall expect HDCP
|
||||
* enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_HDMI_VSIF_NONE_HDCP_ON = 0x00000005,
|
||||
/* HDMI vsif has been filled into p_vsif and 8620 shall expect HDCP
|
||||
* enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_HDMI_VSIF_HDMI_HDCP_ON = 0x00000006,
|
||||
/* MHL3 vsif has been filled into p_vsif and 8620 shall expect HDCP
|
||||
* enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_HDMI_VSIF_MHL3_HDCP_ON = 0x00000007,
|
||||
/* a DTD has been written to the DTD buffer instead of an AVI
|
||||
* infoframe
|
||||
*/
|
||||
HH_FMT_DVI_NOT_RPT = 0x00000008,
|
||||
/* No Vendor Specific InfoFrame provided */
|
||||
HH_FMT_HDMI_VSIF_NONE_NOT_RPT = 0x00000009,
|
||||
/* HDMI vsif has been filled into p_vsif */
|
||||
HH_FMT_HDMI_VSIF_HDMI_NOT_RPT = 0x0000000A,
|
||||
/* MHL3 vsif has been filled into p_vsif */
|
||||
HH_FMT_HDMI_VSIF_MHL3_NOT_RPT = 0x0000000B,
|
||||
/* a DTD has been written to the DTD buffer instead of an AVI infoframe
|
||||
* and 8620 shall expect HDCP enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_DVI_HDCP_ON_NOT_RPT = 0x0000000C,
|
||||
/* No Vendor Specific InfoFrame provided and 8620 shall expect HDCP
|
||||
* enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_HDMI_VSIF_NONE_HDCP_ON_NOT_RPT = 0x0000000D,
|
||||
/* HDMI vsif has been filled into p_vsif and 8620 shall expect HDCP
|
||||
* enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_HDMI_VSIF_HDMI_HDCP_ON_NOT_RPT = 0x0000000E,
|
||||
/* MHL3 vsif has been filled into p_vsif and 8620 shall expect HDCP
|
||||
* enabled on its HDMI input
|
||||
*/
|
||||
HH_FMT_HDMI_VSIF_MHL3_HDCP_ON_NOT_RPT = 0x0000000F,
|
||||
|
||||
/* failure return values for hpd_driven_high(): */
|
||||
|
||||
/* avi_max_length not large enough for AVI info frame data. */
|
||||
HH_AVI_BUFFER_TOO_SMALL = 0x80000001,
|
||||
/* vsif_max_length not large enough for info frame data. */
|
||||
HH_VSIF_BUFFER_TOO_SMALL = 0x80000002,
|
||||
/* The callee is not ready to start video */
|
||||
HH_VIDEO_NOT_RDY = 0x80000004
|
||||
};
|
||||
|
||||
struct __attribute__((__packed__)) si_mhl_callback_api_t {
|
||||
void *context;
|
||||
#if 1
|
||||
int (*display_timing_enum_begin) (void *context);
|
||||
int (*display_timing_enum_item) (void *context, uint16_t columns,
|
||||
uint16_t rows, uint8_t bits_per_pixel,
|
||||
uint32_t vertical_refresh_rate_in_milliHz, uint16_t burst_id,
|
||||
union video_burst_descriptor_u *p_descriptor);
|
||||
int (*display_timing_enum_end) (void *context);
|
||||
#endif
|
||||
/*
|
||||
hpd_driven_low:
|
||||
This gets called in response to CLR_HPD messages from the MHL sink.
|
||||
The upstream client that registers this callback should disable
|
||||
video and all DDC access before returning.
|
||||
*/
|
||||
void (*hpd_driven_low) (void *context);
|
||||
|
||||
/*
|
||||
hpd_driven_high:
|
||||
This gets called when the driver is ready for upstream video
|
||||
activity. The upstream client that registers this callback should
|
||||
respond in the same way in which it would respond to a rising HPD
|
||||
signal (which happens prior to the call).
|
||||
Parameters:
|
||||
*p_edid:
|
||||
|
||||
The processed EDID block(s) that the MHL driver has derived
|
||||
from the downstream EDID and WRITE_BURST info associated with the
|
||||
sink's responses to 3D_REQ (MHL 2.x) or FEAT_REQ (MHL 3.x and newer).
|
||||
|
||||
edid_length:
|
||||
|
||||
*p_emsc_edid:
|
||||
The unprocessed EDID transferred via eMSC BLOCK
|
||||
using SILICON_IMAGE_ADOPTER_ID
|
||||
|
||||
emsc_edid_length:
|
||||
The length, in bytes of the data in *p_emsc_edid
|
||||
|
||||
The length, in bytes, of the data in *p_edid
|
||||
|
||||
*p_hev_dtd:
|
||||
The processed result of all the HEV_DTDA/HEV_DTDB WRITE_BURSTs
|
||||
including the associated 3D_DTD VDI for each HEV_DTD pair.
|
||||
|
||||
num_hev_dtds:
|
||||
The number of MHL3_hev_dtd_t elements in *p_hev_dtd.
|
||||
|
||||
p_hev_vic:
|
||||
The processed result of all the HEV_VIC WRITE_BURSTs including
|
||||
the associated 3D_VIC VDI for each HEV_DTD pair.
|
||||
|
||||
num_hev_vic_items:
|
||||
The number of MHL3_hev_vic_item_t elements in p_hev_vic.
|
||||
|
||||
*p_3d_dtd_items:
|
||||
The processed result of all the 3D_DTD WRITE_BURSTs including
|
||||
the associated DTD from the EDID when VDI_H.HEV_FMT is zero.
|
||||
|
||||
num_3d_dtd_items:
|
||||
The number of MHL3_3d_dtd_item_t elements in p_3d_dtd_items;
|
||||
|
||||
*p_3d_vic:
|
||||
The processed result of all the 3D_VIC WRITE_BURSTs including
|
||||
the associated VIC code from the EDID.
|
||||
|
||||
num_3d_vic_items:
|
||||
The number of MHL3_3d_vic_item_t elements in p_3d_vic.
|
||||
|
||||
p_avif_or_dtd:
|
||||
|
||||
If the callee sends HDMI content, it shall fill in *p_avif_or_dtd
|
||||
with the contents of its outgoing AVI info frame, including the
|
||||
checksum byte, and return one of the values described under the
|
||||
parameter p_vsif.
|
||||
|
||||
If the callee, sends DVI content, is shall fill in *p_avif_or_dtd
|
||||
with a Detailed Timing Descriptor (defined in CEA-861D) that
|
||||
accurately describes the timing parameters of the video which is
|
||||
presented at the 8620's HDMI input and return one of:
|
||||
HH_FMT_DVI
|
||||
HH_FMT_DVI_HDCP_ON
|
||||
HH_FMT_DVI_NOT_REPEATABLE
|
||||
HH_FMT_DVI_HDCP_ON_NOT_REPEATABLE.
|
||||
|
||||
This buffer will be pre-initialized to zeroes prior to the call.
|
||||
|
||||
avi_max_length:
|
||||
|
||||
The length of the buffer pointed to by p_avif_or_dtd.
|
||||
|
||||
p_vsif:
|
||||
|
||||
A buffer into which the upstream driver should
|
||||
write the contents of its outgoing vendor specific
|
||||
info frame, if any, including the checksum byte. This
|
||||
buffer will be pre-initialized to zeroes prior to the call.
|
||||
|
||||
If the callee chooses to write an HDMI vendor specific info frame
|
||||
into p_vsif, it shall return one of:
|
||||
HH_FMT_HDMI_VSIF_HDMI
|
||||
HH_FMT_HDMI_VSIF_HDMI_HDCP_ON
|
||||
HH_FMT_HDMI_VSIF_HDMI_NOT_REPEATABLE
|
||||
HH_FMT_HDMI_VSIF_HDMI_HDCP_ON_NOT_REPEATABLE.
|
||||
|
||||
If the callee chooses to write an MHL3 vendor specific info frame
|
||||
into p_vsif, it shall return one of:
|
||||
HH_FMT_HDMI_VSIF_MHL3
|
||||
HH_FMT_HDMI_VSIF_MHL3_HDCP_ON
|
||||
HH_FMT_HDMI_VSIF_MHL3_NOT_REPEATABLE
|
||||
HH_FMT_HDMI_VSIF_MHL3_HDCP_ON_NOT_REPEATABLE.
|
||||
|
||||
If the callee does not write a vendor specific
|
||||
info frame into this buffer, the callee shall return one of:
|
||||
HH_FMT_HDMI_VSIF_NONE
|
||||
HH_FMT_HDMI_VSIF_NONE_HDCP_ON
|
||||
HH_FMT_HDMI_VSIF_NONE_NOT_RPT
|
||||
HH_FMT_HDMI_VSIF_NONE_HDCP_ON_NOT_RPT
|
||||
and the 8620 will infer the contents of the outgoing MHL3 VSIF from
|
||||
the contents of the HDMI VSIF (if any) presented at the 8620's HDMI
|
||||
input.
|
||||
|
||||
vsif_max_length:
|
||||
|
||||
The length of the buffer pointed to by p_vsif.
|
||||
|
||||
Return values for hpd_driven_high():
|
||||
|
||||
If the callee enabled video during the duration of this call, then
|
||||
the callee shall return one of the values in
|
||||
hpd_high_callback_status that do not have the sign bit set,
|
||||
indicating the usage of parameters.
|
||||
|
||||
If the callee did not enable video during the duration of this call,
|
||||
then the callee shall indicate specific reasons for not starting
|
||||
video by returning the bitwise OR of the values in
|
||||
hpd_high_callback_status that do have the sign bit set.
|
||||
|
||||
*/
|
||||
enum hpd_high_callback_status(*hpd_driven_high) (void *context,
|
||||
uint8_t *p_edid, size_t edid_length,
|
||||
uint8_t *p_emsc_edid, size_t emsc_edid_length,
|
||||
struct MHL3_hev_dtd_item_t *p_hev_dtd, size_t num_hev_dtds,
|
||||
struct MHL3_hev_vic_item_t *p_hev_vic, size_t num_hev_vic_items,
|
||||
struct MHL3_3d_dtd_item_t *p_3d_dtd_items,
|
||||
size_t num_3d_dtd_items,
|
||||
struct MHL3_3d_vic_item_t *p_3d_vic, size_t num_3d_vic_items,
|
||||
union avif_or_cea_861_dtd_u *p_avif_or_dtd,
|
||||
size_t avif_or_dtd_max_length,
|
||||
union vsif_mhl3_or_hdmi_u *p_vsif,
|
||||
size_t vsif_max_length);
|
||||
};
|
||||
|
||||
/* call this function to register the callback structure */
|
||||
int si_8620_register_callbacks(struct si_mhl_callback_api_t *p_callbacks);
|
||||
|
||||
/* call this function to change video modes */
|
||||
int si_8620_info_frame_change(enum hpd_high_callback_status status,
|
||||
union avif_or_cea_861_dtd_u *p_avif_or_dtd,
|
||||
size_t avif_or_dtd_max_length,
|
||||
union vsif_mhl3_or_hdmi_u *p_vsif,
|
||||
size_t vsif_max_length);
|
||||
|
||||
/* call this function to query downstream HPD status */
|
||||
int si_8620_get_hpd_status(int *hpd_status);
|
||||
int si_8620_get_hdcp2_status(uint32_t *hdcp2_status);
|
||||
#endif
|
961
drivers/video/fbdev/msm/mhl3/si_mhl_defs.h
Normal file
961
drivers/video/fbdev/msm/mhl3/si_mhl_defs.h
Normal file
|
@ -0,0 +1,961 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _SI_MHL_DEFS_H_
|
||||
#define _SI_MHL_DEFS_H_
|
||||
|
||||
/*
|
||||
* This file contains MHL Specs related definitions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DEVCAP offsets
|
||||
*/
|
||||
|
||||
enum {
|
||||
DEVCAP_OFFSET_DEV_STATE,
|
||||
DEVCAP_OFFSET_MHL_VERSION,
|
||||
DEVCAP_OFFSET_DEV_CAT,
|
||||
DEVCAP_OFFSET_ADOPTER_ID_H,
|
||||
DEVCAP_OFFSET_ADOPTER_ID_L,
|
||||
DEVCAP_OFFSET_VID_LINK_MODE,
|
||||
DEVCAP_OFFSET_AUD_LINK_MODE,
|
||||
DEVCAP_OFFSET_VIDEO_TYPE,
|
||||
DEVCAP_OFFSET_LOG_DEV_MAP,
|
||||
DEVCAP_OFFSET_BANDWIDTH,
|
||||
DEVCAP_OFFSET_FEATURE_FLAG,
|
||||
DEVCAP_OFFSET_DEVICE_ID_H,
|
||||
DEVCAP_OFFSET_DEVICE_ID_L,
|
||||
DEVCAP_OFFSET_SCRATCHPAD_SIZE,
|
||||
DEVCAP_OFFSET_INT_STAT_SIZE,
|
||||
DEVCAP_OFFSET_RESERVED,
|
||||
/* this one must be last */
|
||||
DEVCAP_SIZE
|
||||
};
|
||||
|
||||
SI_PUSH_STRUCT_PACKING
|
||||
struct SI_PACK_THIS_STRUCT MHLDevCap_t {
|
||||
uint8_t state;
|
||||
uint8_t mhl_version;
|
||||
uint8_t deviceCategory;
|
||||
uint8_t adopterIdHigh;
|
||||
uint8_t adopterIdLow;
|
||||
uint8_t vid_link_mode;
|
||||
uint8_t audLinkMode;
|
||||
uint8_t videoType;
|
||||
uint8_t logicalDeviceMap;
|
||||
uint8_t bandWidth;
|
||||
uint8_t featureFlag;
|
||||
uint8_t deviceIdHigh;
|
||||
uint8_t deviceIdLow;
|
||||
uint8_t scratchPadSize;
|
||||
uint8_t int_state_size;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
union MHLDevCap_u {
|
||||
struct MHLDevCap_t mdc;
|
||||
uint8_t devcap_cache[DEVCAP_SIZE];
|
||||
};
|
||||
|
||||
/* Version that this chip supports */
|
||||
#define MHL_VER_MAJOR 0x30
|
||||
#define MHL_VER_MINOR 0x02
|
||||
#define MHL_VERSION (MHL_VER_MAJOR | MHL_VER_MINOR)
|
||||
|
||||
/* Device Category */
|
||||
#define MHL_DEV_CATEGORY_OFFSET DEVCAP_OFFSET_DEV_CAT
|
||||
#define MHL_DEV_CATEGORY_POW_BIT 0x10
|
||||
#define MHL_DEV_CATEGORY_PLIM2_0 0xE0
|
||||
|
||||
#define I_VBUS_PRE_DISCOVERY 100
|
||||
#define I_VBUS_SOURCE_TO_DONGLE 200
|
||||
#define I_VBUS_POST_DISCOVERY 500
|
||||
|
||||
#define MHL_DEV_CAT_SINK 0x01
|
||||
#define MHL_DEV_CAT_SOURCE 0x02
|
||||
#define MHL_DEV_CAT_DONGLE 0x03
|
||||
#define MHL_DEV_CAT_SELF_POWERED_DONGLE 0x13
|
||||
|
||||
/* Video Link Mode */
|
||||
#define MHL_DEV_VID_LINK_SUPP_RGB444 0x01
|
||||
#define MHL_DEV_VID_LINK_SUPP_YCBCR444 0x02
|
||||
#define MHL_DEV_VID_LINK_SUPP_YCBCR422 0x04
|
||||
#define MHL_DEV_VID_LINK_SUPP_PPIXEL 0x08
|
||||
#define MHL_DEV_VID_LINK_SUPP_ISLANDS 0x10
|
||||
#define MHL_DEV_VID_LINK_SUPP_VGA 0x20
|
||||
#define MHL_DEV_VID_LINK_SUPP_16BPP 0x40
|
||||
|
||||
/* Audio Link Mode Support */
|
||||
#define MHL_DEV_AUD_LINK_2CH 0x01
|
||||
#define MHL_DEV_AUD_LINK_8CH 0x02
|
||||
|
||||
/* Feature Flag in the devcap */
|
||||
#define MHL_DEV_FEATURE_FLAG_OFFSET DEVCAP_OFFSET_FEATURE_FLAG
|
||||
#define MHL_FEATURE_RCP_SUPPORT 0x01
|
||||
#define MHL_FEATURE_RAP_SUPPORT 0x02
|
||||
#define MHL_FEATURE_SP_SUPPORT 0x04
|
||||
#define MHL_FEATURE_UCP_SEND_SUPPORT 0x08
|
||||
#define MHL_FEATURE_UCP_RECV_SUPPORT 0x10
|
||||
#define MHL_FEATURE_RBP_SUPPORT 0x40
|
||||
|
||||
/* VIDEO TYPES */
|
||||
#define MHL_VT_GRAPHICS 0x00
|
||||
#define MHL_VT_PHOTO 0x02
|
||||
#define MHL_VT_CINEMA 0x04
|
||||
#define MHL_VT_GAMES 0x08
|
||||
#define MHL_SUPP_VT 0x80
|
||||
|
||||
/* Logical Dev Map */
|
||||
#define MHL_DEV_LD_DISPLAY 0x01
|
||||
#define MHL_DEV_LD_VIDEO 0x02
|
||||
#define MHL_DEV_LD_AUDIO 0x04
|
||||
#define MHL_DEV_LD_MEDIA 0x08
|
||||
#define MHL_DEV_LD_TUNER 0x10
|
||||
#define MHL_DEV_LD_RECORD 0x20
|
||||
#define MHL_DEV_LD_SPEAKER 0x40
|
||||
#define MHL_DEV_LD_GUI 0x80
|
||||
|
||||
/* Bandwidth */
|
||||
#define MHL_BANDWIDTH_LIMIT 22 /* 225 MHz */
|
||||
|
||||
#define MHL_STATUS_REG_CONNECTED_RDY 0x30
|
||||
#define MHL_STATUS_REG_LINK_MODE 0x31
|
||||
#define MHL_STATUS_REG_VERSION_STAT 0x32
|
||||
|
||||
#define MHL_STATUS_DCAP_RDY 0x01
|
||||
#define MHL_STATUS_XDEVCAPP_SUPP 0x02
|
||||
#define MHL_STATUS_POW_STAT 0x04
|
||||
#define MHL_STATUS_PLIM_STAT_MASK 0x38
|
||||
|
||||
#define MHL_STATUS_CLK_MODE_MASK 0x07
|
||||
#define MHL_STATUS_CLK_MODE_PACKED_PIXEL 0x02
|
||||
#define MHL_STATUS_CLK_MODE_NORMAL 0x03
|
||||
#define MHL_STATUS_PATH_EN_MASK 0x08
|
||||
#define MHL_STATUS_PATH_ENABLED 0x08
|
||||
#define MHL_STATUS_PATH_DISABLED 0x00
|
||||
#define MHL_STATUS_MUTED_MASK 0x10
|
||||
|
||||
#define MHL_RCHANGE_INT 0x20
|
||||
#define MHL_DCHANGE_INT 0x21
|
||||
|
||||
#define MHL_INT_DCAP_CHG 0x01
|
||||
#define MHL_INT_DSCR_CHG 0x02
|
||||
#define MHL_INT_REQ_WRT 0x04
|
||||
#define MHL_INT_GRT_WRT 0x08
|
||||
#define MHL2_INT_3D_REQ 0x10
|
||||
#define MHL3_INT_FEAT_REQ 0x20
|
||||
#define MHL3_INT_FEAT_COMPLETE 0x40
|
||||
|
||||
/* On INTR_1 the EDID_CHG is located at BIT 0 */
|
||||
#define MHL_INT_EDID_CHG 0x02
|
||||
|
||||
/* This contains one nibble each - max offset */
|
||||
#define MHL_INT_AND_STATUS_SIZE 0x33
|
||||
#define MHL_SCRATCHPAD_SIZE 16
|
||||
/* manually define highest number */
|
||||
#define MHL_MAX_BUFFER_SIZE MHL_SCRATCHPAD_SIZE
|
||||
|
||||
#define SILICON_IMAGE_ADOPTER_ID 322
|
||||
|
||||
enum BurstId_e {
|
||||
MHL_TEST_ADOPTER_ID = 0x0000,
|
||||
burst_id_3D_VIC = 0x0010,
|
||||
burst_id_3D_DTD = 0x0011,
|
||||
burst_id_HEV_VIC = 0x0020,
|
||||
burst_id_HEV_DTDA = 0x0021,
|
||||
burst_id_HEV_DTDB = 0x0022,
|
||||
burst_id_VC_ASSIGN = 0x0038,
|
||||
burst_id_VC_CONFIRM = 0x0039,
|
||||
burst_id_AUD_DELAY = 0x0040,
|
||||
burst_id_ADT_BURSTID = 0x0041,
|
||||
burst_id_BIST_SETUP = 0x0051,
|
||||
burst_id_BIST_RETURN_STAT = 0x0052,
|
||||
burst_id_BIST_DISCARD = 0x0053,
|
||||
burst_id_BIST_ECHO_REQUEST = 0x0054,
|
||||
burst_id_BIST_ECHO_RESPONSE = 0x0055,
|
||||
burst_id_EMSC_SUPPORT = 0x0061,
|
||||
burst_id_HID_PAYLOAD = 0x0062,
|
||||
burst_id_BLK_RCV_BUFFER_INFO = 0x0063,
|
||||
burst_id_BITS_PER_PIXEL_FMT = 0x0064,
|
||||
adopter_id_RANGE_START = 0x0080,
|
||||
LOCAL_ADOPTER_ID = SILICON_IMAGE_ADOPTER_ID,
|
||||
/* add new burst ID's above here */
|
||||
|
||||
/* Burst ID's are a 16-bit big-endian quantity. */
|
||||
burst_id_16_BITS_REQUIRED = 0x8000
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL_high_low_t {
|
||||
uint8_t high;
|
||||
uint8_t low;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL_burst_id_t {
|
||||
uint8_t high;
|
||||
uint8_t low;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT EMSC_BLK_ADOPT_ID_PAYLD_HDR {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t remaining_length;
|
||||
};
|
||||
|
||||
#define ENDIAN_CONVERT_16(a) \
|
||||
((((uint16_t)((a).high))<<8)|((uint16_t)((a).low)))
|
||||
#define BURST_ID(bid) (enum BurstId_e)ENDIAN_CONVERT_16(bid)
|
||||
|
||||
#define HIGH_BYTE_16(x) (uint8_t)((x >> 8) & 0xFF)
|
||||
#define LOW_BYTE_16(x) (uint8_t)(x & 0xFF)
|
||||
#define ENCODE_BURST_ID(id) {HIGH_BYTE_16(id), LOW_BYTE_16(id)}
|
||||
|
||||
struct SI_PACK_THIS_STRUCT standard_transport_header_t {
|
||||
uint8_t rx_unload_ack;
|
||||
uint8_t length_remaining;
|
||||
};
|
||||
|
||||
#define STD_TRANSPORT_HDR_SIZE \
|
||||
sizeof(struct SI_PACK_THIS_STRUCT standard_transport_header_t)
|
||||
|
||||
struct SI_PACK_THIS_STRUCT block_rcv_buffer_info_t {
|
||||
/* use the BURST_ID macro to access this */
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t blk_rcv_buffer_size_low;
|
||||
uint8_t blk_rcv_buffer_size_high;
|
||||
};
|
||||
|
||||
/* see MHL2.0 spec section 5.9.1.2 */
|
||||
struct SI_PACK_THIS_STRUCT MHL2_video_descriptor_t {
|
||||
uint8_t reserved_high;
|
||||
unsigned char frame_sequential:1; /*FB_SUPP*/
|
||||
unsigned char top_bottom:1; /*TB_SUPP*/
|
||||
unsigned char left_right:1; /*LR_SUPP*/
|
||||
unsigned char reserved_low:5;
|
||||
};
|
||||
|
||||
struct MHL3_vdi_l_t {
|
||||
unsigned char frame_sequential:1; /*FB_SUPP*/
|
||||
unsigned char top_bottom:1; /*TB_SUPP*/
|
||||
unsigned char left_right:1; /*LR_SUPP*/
|
||||
unsigned char reserved_low:5;
|
||||
};
|
||||
|
||||
struct MHL3_vdi_h_t {
|
||||
unsigned char reserved;
|
||||
};
|
||||
|
||||
/* see MHL3.0 spec section 5.11 */
|
||||
struct SI_PACK_THIS_STRUCT MHL3_video_descriptor_t {
|
||||
/* VDI_H comes before VDI_L. See Table 5-5 */
|
||||
struct MHL3_vdi_h_t vdi_h;
|
||||
struct MHL3_vdi_l_t vdi_l;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_burst_header_t {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t checksum;
|
||||
uint8_t total_entries;
|
||||
uint8_t sequence_index;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL2_video_format_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
uint8_t num_entries_this_burst;
|
||||
struct MHL2_video_descriptor_t video_descriptors[5];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_vic_descriptor_t {
|
||||
uint8_t reserved;
|
||||
uint8_t vic_cea861f;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_vic_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
uint8_t num_entries_this_burst;
|
||||
struct MHL3_hev_vic_descriptor_t video_descriptors[5];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_dtd_a_payload_t {
|
||||
struct MHL_high_low_t pixel_clock_in_MHz;
|
||||
struct MHL_high_low_t h_active_in_pixels;
|
||||
struct MHL_high_low_t h_blank_in_pixels;
|
||||
struct MHL_high_low_t h_front_porch_in_pixels;
|
||||
struct MHL_high_low_t h_sync_width_in_pixels;
|
||||
uint8_t h_flags;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_dtd_b_payload_t {
|
||||
struct MHL_high_low_t v_total_in_lines;
|
||||
uint8_t v_blank_in_lines; /* note 7 for table 5-16 is wrong */
|
||||
uint8_t v_front_porch_in_lines; /* note 7 for table 5-16 is wrong */
|
||||
uint8_t v_sync_width_in_lines; /* note 7 for table 5-16 is wrong */
|
||||
uint8_t v_refresh_rate_in_fields_per_second;
|
||||
uint8_t v_flags;
|
||||
uint8_t reserved[4];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_dtd_a_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
struct MHL3_hev_dtd_a_payload_t payload;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_dtd_b_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
struct MHL3_hev_dtd_b_payload_t payload;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_hev_dtd_item_t {
|
||||
uint8_t sequence_index;
|
||||
struct MHL3_hev_dtd_a_payload_t a;
|
||||
struct MHL3_hev_dtd_b_payload_t b;
|
||||
struct MHL3_video_descriptor_t _3d_info;
|
||||
};
|
||||
|
||||
struct MHL3_hev_vic_item_t {
|
||||
struct MHL3_hev_vic_descriptor_t mhl3_hev_vic_descriptor;
|
||||
struct MHL3_video_descriptor_t _3d_info;
|
||||
};
|
||||
|
||||
struct MHL3_3d_vic_item_t {
|
||||
struct cea_short_descriptor_t svd;
|
||||
struct MHL3_video_descriptor_t _3d_info;
|
||||
};
|
||||
|
||||
struct MHL3_3d_dtd_item_t {
|
||||
uint8_t index;
|
||||
struct detailed_timing_descriptor_t dtd_cea_861;
|
||||
struct MHL3_video_descriptor_t _3d_info;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_speaker_allocation_data_block_t {
|
||||
uint8_t cea861f_spkr_alloc[3];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_adt_payload_t {
|
||||
uint8_t format_flags;
|
||||
union {
|
||||
uint8_t short_descs[9];
|
||||
struct MHL3_speaker_allocation_data_block_t spkr_alloc_db[3];
|
||||
} descriptors;
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_audio_delay_burst_t {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t checksum;
|
||||
uint8_t delay_h;
|
||||
uint8_t delay_m;
|
||||
uint8_t delay_l;
|
||||
uint8_t reserved[10];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_adt_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
struct MHL3_adt_payload_t payload;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_emsc_support_payload_t {
|
||||
struct MHL_burst_id_t burst_ids[5];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_emsc_support_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
uint8_t num_entries_this_burst;
|
||||
struct MHL3_emsc_support_payload_t payload;
|
||||
};
|
||||
|
||||
enum view_pixel_fmt_e {
|
||||
VIEW_PIX_FMT_24BPP,
|
||||
VIEW_PIX_FMT_16BPP
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL3_bits_per_pixel_fmt_descriptor_t {
|
||||
uint8_t stream_id;
|
||||
uint8_t stream_pixel_format;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT MHL_bits_per_pixel_fmt_data_t {
|
||||
struct MHL3_burst_header_t header;
|
||||
uint8_t num_entries_this_burst;
|
||||
|
||||
/* reserve 5 for use with WRITE_BURST
|
||||
actual length is variable, indicated by
|
||||
num_entries_this_burst
|
||||
*/
|
||||
/* todo change this to 1 when WRITE_BURST OPTION is removed */
|
||||
struct MHL3_bits_per_pixel_fmt_descriptor_t descriptors[5];
|
||||
};
|
||||
|
||||
union SI_PACK_THIS_STRUCT video_burst_descriptor_u {
|
||||
struct MHL2_video_descriptor_t mhl2_3d_descriptor;
|
||||
struct MHL3_video_descriptor_t mhl3_3d_descriptor;
|
||||
struct MHL3_hev_vic_descriptor_t mhl3_hev_vic_descriptor;
|
||||
struct MHL3_hev_dtd_item_t mhl3_hev_dtd;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT mhl3_vsif_t {
|
||||
VSIF_COMMON_FIELDS
|
||||
uint8_t pb4;
|
||||
uint8_t pb5_reserved;
|
||||
uint8_t pb6;
|
||||
struct MHL_high_low_t mhl_hev_fmt_type;
|
||||
uint8_t pb9;
|
||||
|
||||
struct MHL_high_low_t av_delay_sync;
|
||||
};
|
||||
|
||||
/* the enum's in the following section are
|
||||
defined "in position" to avoid
|
||||
shifting on the fly
|
||||
*/
|
||||
#define MHL3_VSIF_TYPE 0x81
|
||||
#define MHL3_VSIF_VERSION 0x03
|
||||
#define IEEE_OUI_MHL 0x7CA61D
|
||||
|
||||
#define PB4_MASK_MHL_VID_FMT 0x03
|
||||
enum mhl_vid_fmt_e {
|
||||
mhl_vid_fmt_no_additional,
|
||||
mhl_vid_fmt_3d_fmt_present,
|
||||
mhl_vid_fmt_multi_view,
|
||||
mhl_vid_fmt_dual_3d
|
||||
};
|
||||
|
||||
#define PB4_MASK_MHL_3D_FMT_TYPE 0x1C
|
||||
enum mhl_3d_fmt_type_e {
|
||||
MHL_3D_FMT_TYPE_FS, /* Frame Sequential */
|
||||
MHL_3D_FMT_TYPE_TB = 0x04, /* Top-Bottom */
|
||||
MHL_3D_FMT_TYPE_LR = 0x08, /* Left-Right */
|
||||
MHL_3D_FMT_TYPE_FS_TB = 0x0C, /* Frame Sequential Top-Bottom */
|
||||
MHL_3D_FMT_TYPE_FS_LR = 0x10, /* Frame Sequential Left-Right */
|
||||
MHL_3D_FMT_TYPE_TBLR = 0x14 /* Top-Bottom-Left-Right */
|
||||
};
|
||||
|
||||
#define PB4_MASK_SEP_AUD 0x20
|
||||
enum mhl_sep_audio_e {
|
||||
mhl_sep_audio_not_available,
|
||||
mhl_sep_audio_available = 0x20
|
||||
};
|
||||
|
||||
#define PB4_MASK_RESERVED 0xC0
|
||||
|
||||
#define MHL3_VSIF_PB4(vid_fmt, _3d_fmt_type, sep_aud) \
|
||||
(uint8_t)(((vid_fmt)&PB4_MASK_MHL_VID_FMT) | \
|
||||
((_3d_fmt_type)&PB4_MASK_MHL_3D_FMT_TYPE) | \
|
||||
((sep_aud)&PB4_MASK_SEP_AUD))
|
||||
|
||||
#define PB6_MASK_MHL_HEV_FMT 0x03
|
||||
enum mhl_hev_fmt_e {
|
||||
mhl_hev_fmt_no_additional,
|
||||
mhl_hev_fmt_hev_present,
|
||||
mhl_hev_fmt_reserved_2,
|
||||
mhl_hev_fmt_reserved_3
|
||||
};
|
||||
|
||||
#define PB6_MASK_RESERVED 0xFC
|
||||
#define MHL3_VSIF_PB6(hev_fmt) (uint8_t)((hev_fmt) & PB6_MASK_MHL_HEV_FMT)
|
||||
|
||||
#define PB9_MASK_AV_DELAY_SYNC_19_16 0x0F
|
||||
|
||||
#define PB9_MASK_AV_DELAY_DIR 0x10
|
||||
enum mhl_av_delay_dir_e {
|
||||
mhl_av_delay_dir_audio_earlier,
|
||||
mhl_av_delay_dir_video_earlier = 0x10
|
||||
};
|
||||
|
||||
#define PB9_MASK_RESERVED 0xE0
|
||||
|
||||
#define MHL3_VSIF_PB9(delay_sync, delay_dir) \
|
||||
(uint8_t)((((delay_sync) >> 16) & PB9_MASK_AV_DELAY_SYNC_19_16) | \
|
||||
((delay_dir) & PB9_MASK_AV_DELAY_DIR))
|
||||
|
||||
struct SI_PACK_THIS_STRUCT info_frame_t {
|
||||
union {
|
||||
struct info_frame_header_t header;
|
||||
struct avi_info_frame_t avi;
|
||||
struct hdmi_vsif_t vendorSpecific;
|
||||
struct mhl3_vsif_t mhl3_vsif;
|
||||
struct unr_info_frame_t unr;
|
||||
} body;
|
||||
};
|
||||
|
||||
union SI_PACK_THIS_STRUCT vsif_mhl3_or_hdmi_u {
|
||||
struct SI_PACK_THIS_STRUCT vsif_common_header_t common;
|
||||
struct SI_PACK_THIS_STRUCT hdmi_vsif_t hdmi;
|
||||
struct SI_PACK_THIS_STRUCT mhl3_vsif_t mhl3;
|
||||
};
|
||||
enum InfoFrameType_e {
|
||||
InfoFrameType_AVI,
|
||||
InfoFrameType_VendorSpecific,
|
||||
InfoFrameType_VendorSpecific_MHL3,
|
||||
InfoFrameType_Audio
|
||||
};
|
||||
|
||||
SI_POP_STRUCT_PACKING
|
||||
enum {
|
||||
MHL_MSC_MSG_RCP = 0x10, /* RCP sub-command */
|
||||
MHL_MSC_MSG_RCPK = 0x11, /* RCP Acknowledge sub-command */
|
||||
MHL_MSC_MSG_RCPE = 0x12, /* RCP Error sub-command */
|
||||
MHL_MSC_MSG_RAP = 0x20, /* Mode Change Warning sub-command */
|
||||
MHL_MSC_MSG_RAPK = 0x21, /* MCW Acknowledge sub-command */
|
||||
MHL_MSC_MSG_RBP = 0x22, /* Remote Button Protocol sub-command */
|
||||
MHL_MSC_MSG_RBPK = 0x23, /* RBP Acknowledge sub-command */
|
||||
MHL_MSC_MSG_RBPE = 0x24, /* RBP Error sub-command */
|
||||
MHL_MSC_MSG_UCP = 0x30, /* UCP sub-command */
|
||||
MHL_MSC_MSG_UCPK = 0x31, /* UCP Acknowledge sub-command */
|
||||
MHL_MSC_MSG_UCPE = 0x32, /* UCP Error sub-command */
|
||||
MHL_MSC_MSG_RUSB = 0x40, /* Request USB host role */
|
||||
MHL_MSC_MSG_RUSBK = 0x41, /* Acknowledge request for USB host role */
|
||||
MHL_MSC_MSG_RHID = 0x42, /* Request HID host role */
|
||||
MHL_MSC_MSG_RHIDK = 0x43, /* Acknowledge request for HID host role */
|
||||
MHL_MSC_MSG_ATT = 0x50, /* Request attention sub-command */
|
||||
MHL_MSC_MSG_ATTK = 0x51, /* ATT Acknowledge sub-command */
|
||||
MHL_MSC_MSG_BIST_TRIGGER = 0x60,
|
||||
MHL_MSC_MSG_BIST_REQUEST_STAT = 0x61,
|
||||
MHL_MSC_MSG_BIST_READY = 0x62,
|
||||
MHL_MSC_MSG_BIST_STOP = 0x63,
|
||||
};
|
||||
|
||||
#define BIST_TRIGGER_E_CBUS_TX 0x01
|
||||
#define BIST_TRIGGER_E_CBUS_RX 0x02
|
||||
#define BIST_TRIGGER_E_CBUS_TYPE_MASK 0x08
|
||||
#define BIST_TRIGGER_TEST_E_CBUS_S 0x00
|
||||
#define BIST_TRIGGER_TEST_E_CBUS_D 0x08
|
||||
#define BIST_TRIGGER_AVLINK_TX 0x10
|
||||
#define BIST_TRIGGER_AVLINK_RX 0x20
|
||||
#define BIST_TRIGGER_IMPEDANCE_TEST 0x40
|
||||
|
||||
#define BIST_TRIGGER_ECBUS_AV_LINK_MASK (BIST_TRIGGER_AVLINK_TX | \
|
||||
BIST_TRIGGER_AVLINK_RX)
|
||||
#define BIST_TRIGGER_ECBUS_TX_RX_MASK (BIST_TRIGGER_E_CBUS_TX | \
|
||||
BIST_TRIGGER_E_CBUS_RX)
|
||||
|
||||
#define BIST_TRIGGER_OPERAND_VALID_MASK 0x7B
|
||||
|
||||
#define BIST_READY_E_CBUS_READY 0x01
|
||||
#define BIST_READY_AVLINK_READY 0x02
|
||||
#define BIST_READY_TERM_READY 0x04
|
||||
#define BIST_READY_E_CBUS_ERROR 0x10
|
||||
#define BIST_READY_AVLINK_ERROR 0x20
|
||||
#define BIST_READY_TERM_ERROR 0x40
|
||||
|
||||
#define RCPE_NO_ERROR 0x00
|
||||
#define RCPE_INEFFECTIVE_KEY_CODE 0x01
|
||||
#define RCPE_BUSY 0x02
|
||||
|
||||
#define MHL_RCP_KEY_RELEASED_MASK 0x80
|
||||
#define MHL_RCP_KEY_ID_MASK 0x7F
|
||||
|
||||
#define RBPE_NO_ERROR 0x00
|
||||
#define RBPE_INEFFECTIVE_BUTTON_CODE 0x01
|
||||
#define RBPE_BUSY 0x02
|
||||
|
||||
#define MHL_RBP_BUTTON_RELEASED_MASK 0x80
|
||||
#define MHL_RBP_BUTTON_ID_MASK 0x7F
|
||||
|
||||
#define T_PRESS_MODE 300
|
||||
|
||||
#define T_HOLD_MAINTAIN 2000
|
||||
#define T_RAP_WAIT_MIN 100
|
||||
#define T_RAP_WAIT_MAX 1000
|
||||
|
||||
enum {
|
||||
/* Command or Data byte acknowledge */
|
||||
MHL_ACK = 0x33,
|
||||
/* Command or Data byte not acknowledge */
|
||||
MHL_NACK = 0x34,
|
||||
/* Transaction abort */
|
||||
MHL_ABORT = 0x35,
|
||||
/* Write one status register strip top bit */
|
||||
MHL_WRITE_STAT = 0x60 | 0x80,
|
||||
/* Write one interrupt register */
|
||||
MHL_SET_INT = 0x60,
|
||||
/* Read one register */
|
||||
MHL_READ_DEVCAP_REG = 0x61,
|
||||
/* Read CBUS revision level from follower */
|
||||
MHL_GET_STATE = 0x62,
|
||||
/* Read vendor ID value from follower */
|
||||
MHL_GET_VENDOR_ID = 0x63,
|
||||
/* Set Hot Plug Detect in follower */
|
||||
MHL_SET_HPD = 0x64,
|
||||
/* Clear Hot Plug Detect in follower */
|
||||
MHL_CLR_HPD = 0x65,
|
||||
/* Set Capture ID for downstream device */
|
||||
MHL_SET_CAP_ID = 0x66,
|
||||
/* Get Capture ID from downstream device */
|
||||
MHL_GET_CAP_ID = 0x67,
|
||||
/* VS command to send RCP sub-commands */
|
||||
MHL_MSC_MSG = 0x68,
|
||||
/* Get Vendor-Specific command error code */
|
||||
MHL_GET_SC1_ERRORCODE = 0x69,
|
||||
/* Get DDC channel command error code */
|
||||
MHL_GET_DDC_ERRORCODE = 0x6A,
|
||||
/* Get MSC command error code */
|
||||
MHL_GET_MSC_ERRORCODE = 0x6B,
|
||||
/* Write 1-16 bytes to responder's scratchpad */
|
||||
MHL_WRITE_BURST = 0x6C,
|
||||
/* Get channel 3 command error code */
|
||||
MHL_GET_SC3_ERRORCODE = 0x6D,
|
||||
/* Write one extended status register */
|
||||
MHL_WRITE_XSTAT = 0x70,
|
||||
/* Read one extended devcap register */
|
||||
MHL_READ_XDEVCAP_REG = 0x71,
|
||||
/* let the rest of these float, they are software specific */
|
||||
MHL_READ_EDID_BLOCK,
|
||||
MHL_SEND_3D_REQ_OR_FEAT_REQ,
|
||||
MHL_READ_DEVCAP,
|
||||
MHL_READ_XDEVCAP
|
||||
};
|
||||
|
||||
/* RAP action codes */
|
||||
#define MHL_RAP_POLL 0x00 /* Just do an ack */
|
||||
#define MHL_RAP_CONTENT_ON 0x10 /* Turn content stream ON */
|
||||
#define MHL_RAP_CONTENT_OFF 0x11 /* Turn content stream OFF */
|
||||
#define MHL_RAP_CBUS_MODE_DOWN 0x20
|
||||
#define MHL_RAP_CBUS_MODE_UP 0x21
|
||||
|
||||
/* RAPK status codes */
|
||||
#define MHL_RAPK_NO_ERR 0x00 /* RAP action recognized & supported */
|
||||
#define MHL_RAPK_UNRECOGNIZED 0x01 /* Unknown RAP action code received */
|
||||
#define MHL_RAPK_UNSUPPORTED 0x02 /* Rcvd RAP action code not supported */
|
||||
#define MHL_RAPK_BUSY 0x03 /* Responder too busy to respond */
|
||||
|
||||
/*
|
||||
* Error status codes for RCPE messages
|
||||
*/
|
||||
/* No error. (Not allowed in RCPE messages) */
|
||||
#define MHL_RCPE_STATUS_NO_ERROR 0x00
|
||||
/* Unsupported/unrecognized key code */
|
||||
#define MHL_RCPE_STATUS_INEFFECTIVE_KEY_CODE 0x01
|
||||
/* Responder busy. Initiator may retry message */
|
||||
#define MHL_RCPE_STATUS_BUSY 0x02
|
||||
|
||||
/*
|
||||
* Error status codes for RBPE messages
|
||||
*/
|
||||
/* No error. (Not allowed in RBPE messages) */
|
||||
#define MHL_RBPE_STATUS_NO_ERROR 0x00
|
||||
/* Unsupported/unrecognized button code */
|
||||
#define MHL_RBPE_STATUS_INEFFECTIVE_BUTTON_CODE 0x01
|
||||
/* Responder busy. Initiator may retry message */
|
||||
#define MHL_RBPE_STATUS_BUSY 0x02
|
||||
|
||||
/*
|
||||
* Error status codes for UCPE messages
|
||||
*/
|
||||
/* No error. (Not allowed in UCPE messages) */
|
||||
#define MHL_UCPE_STATUS_NO_ERROR 0x00
|
||||
/* Unsupported/unrecognized key code */
|
||||
#define MHL_UCPE_STATUS_INEFFECTIVE_KEY_CODE 0x01
|
||||
|
||||
/* Extended Device Capability Registers 7.12.1 */
|
||||
enum {
|
||||
XDEVCAP_START = 0x80,
|
||||
XDEVCAP_ADDR_ECBUS_SPEEDS = XDEVCAP_START,
|
||||
XDEVCAP_ADDR_TMDS_SPEEDS = 0x81,
|
||||
XDEVCAP_ADDR_ECBUS_DEV_ROLES = 0x82,
|
||||
XDEVCAP_ADDR_LOG_DEV_MAPX = 0x83,
|
||||
XDEVCAP_LIMIT, /* don't hard-code this one */
|
||||
XDEVCAP_ADDR_RESERVED_4 = 0x84,
|
||||
XDEVCAP_ADDR_RESERVED_5 = 0x85,
|
||||
XDEVCAP_ADDR_RESERVED_6 = 0x86,
|
||||
XDEVCAP_ADDR_RESERVED_7 = 0x87,
|
||||
XDEVCAP_ADDR_RESERVED_8 = 0x88,
|
||||
XDEVCAP_ADDR_RESERVED_9 = 0x89,
|
||||
XDEVCAP_ADDR_RESERVED_A = 0x8A,
|
||||
XDEVCAP_ADDR_RESERVED_B = 0x8B,
|
||||
XDEVCAP_ADDR_RESERVED_C = 0x8C,
|
||||
XDEVCAP_ADDR_RESERVED_D = 0x8D,
|
||||
XDEVCAP_ADDR_RESERVED_E = 0x8E,
|
||||
XDEVCAP_ADDR_RESERVED_F = 0x8F,
|
||||
XDEVCAP_ADDR_LAST, /* this one must be last */
|
||||
XDEVCAP_SIZE = XDEVCAP_ADDR_LAST - XDEVCAP_START
|
||||
};
|
||||
|
||||
#define XDEVCAP_OFFSET(reg) (reg - XDEVCAP_ADDR_ECBUS_SPEEDS)
|
||||
SI_PUSH_STRUCT_PACKING
|
||||
struct SI_PACK_THIS_STRUCT MHLXDevCap_t {
|
||||
uint8_t ecbus_speeds;
|
||||
uint8_t tmds_speeds;
|
||||
uint8_t ecbus_dev_roles;
|
||||
uint8_t log_dev_mapx;
|
||||
uint8_t reserved_4;
|
||||
uint8_t reserved_5;
|
||||
uint8_t reserved_6;
|
||||
uint8_t reserved_7;
|
||||
uint8_t reserved_8;
|
||||
uint8_t reserved_9;
|
||||
uint8_t reserved_a;
|
||||
uint8_t reserved_b;
|
||||
uint8_t reserved_c;
|
||||
uint8_t reserved_d;
|
||||
uint8_t reserved_e;
|
||||
uint8_t reserved_f;
|
||||
};
|
||||
|
||||
union MHLXDevCap_u {
|
||||
struct MHLXDevCap_t mxdc;
|
||||
uint8_t xdevcap_cache[XDEVCAP_SIZE];
|
||||
};
|
||||
SI_POP_STRUCT_PACKING
|
||||
|
||||
/* XDEVCAP - eCBUS Speeds 7.12.1.1 */
|
||||
#define MHL_XDC_ECBUS_S_075 0x01
|
||||
#define MHL_XDC_ECBUS_S_8BIT 0x02
|
||||
#define MHL_XDC_ECBUS_S_12BIT 0x04
|
||||
#define MHL_XDC_ECBUS_D_150 0x10
|
||||
#define MHL_XDC_ECBUS_D_8BIT 0x20
|
||||
|
||||
/* XDEVCAP - TMDS Speeds 7.12.1.2 */
|
||||
#define MHL_XDC_TMDS_000 0x00
|
||||
#define MHL_XDC_TMDS_150 0x01
|
||||
#define MHL_XDC_TMDS_300 0x02
|
||||
#define MHL_XDC_TMDS_600 0x04
|
||||
|
||||
/* XDEVCAP - Device Roles 7.12.1.3 */
|
||||
#define MHL_XDC_DEV_HOST 0x01
|
||||
#define MHL_XDC_DEV_DEVICE 0x02
|
||||
#define MHL_XDC_DEV_CHARGER 0x04
|
||||
#define MHL_XDC_HID_HOST 0x08
|
||||
#define MHL_XDC_HID_DEVICE 0x10
|
||||
|
||||
/* XDEVCAP - Extended Logical Device Map 7.12.1.4 */
|
||||
#define MHL_XDC_LD_PHONE 0x01
|
||||
|
||||
/* Extended Device Status Registers 7.12.2 */
|
||||
enum {
|
||||
XDEVSTAT_OFFSET_CURR_ECBUS_MODE,
|
||||
XDEVSTAT_OFFSET_AVLINK_MODE_STATUS,
|
||||
XDEVSTAT_OFFSET_AVLINK_MODE_CONTROL,
|
||||
XDEVSTAT_OFFSET_MULTI_SINK_STATUS,
|
||||
XDEVSTAT_OFFSET_RESERVED_04,
|
||||
XDEVSTAT_OFFSET_RESERVED_05,
|
||||
XDEVSTAT_OFFSET_RESERVED_06,
|
||||
XDEVSTAT_OFFSET_RESERVED_07,
|
||||
XDEVSTAT_OFFSET_RESERVED_08,
|
||||
XDEVSTAT_OFFSET_RESERVED_09,
|
||||
XDEVSTAT_OFFSET_RESERVED_0A,
|
||||
XDEVSTAT_OFFSET_RESERVED_0B,
|
||||
XDEVSTAT_OFFSET_RESERVED_0C,
|
||||
XDEVSTAT_OFFSET_RESERVED_0D,
|
||||
XDEVSTAT_OFFSET_RESERVED_0E,
|
||||
XDEVSTAT_OFFSET_RESERVED_0F,
|
||||
XDEVSTAT_OFFSET_RESERVED_10,
|
||||
XDEVSTAT_OFFSET_RESERVED_11,
|
||||
XDEVSTAT_OFFSET_RESERVED_12,
|
||||
XDEVSTAT_OFFSET_RESERVED_13,
|
||||
XDEVSTAT_OFFSET_RESERVED_14,
|
||||
XDEVSTAT_OFFSET_RESERVED_15,
|
||||
XDEVSTAT_OFFSET_RESERVED_16,
|
||||
XDEVSTAT_OFFSET_RESERVED_17,
|
||||
XDEVSTAT_OFFSET_RESERVED_18,
|
||||
XDEVSTAT_OFFSET_RESERVED_19,
|
||||
XDEVSTAT_OFFSET_RESERVED_1A,
|
||||
XDEVSTAT_OFFSET_RESERVED_1B,
|
||||
XDEVSTAT_OFFSET_RESERVED_1C,
|
||||
XDEVSTAT_OFFSET_RESERVED_1D,
|
||||
XDEVSTAT_OFFSET_RESERVED_1E,
|
||||
XDEVSTAT_OFFSET_RESERVED_1F,
|
||||
/* this one must be last */
|
||||
XDEVSTAT_SIZE
|
||||
};
|
||||
|
||||
/* XDEVSTAT - Current eCBUS Mode 7.12.2.1 */
|
||||
#define MHL_XSTATUS_REG_CBUS_MODE 0x90
|
||||
#define MHL_XDS_SLOT_MODE_8BIT 0x00
|
||||
#define MHL_XDS_SLOT_MODE_6BIT 0x01
|
||||
#define MHL_XDS_ECBUS_S 0x04
|
||||
#define MHL_XDS_ECBUS_D 0x08
|
||||
|
||||
#define MHL_XDS_LINK_CLOCK_75MHZ 0x00
|
||||
#define MHL_XDS_LINK_CLOCK_150MHZ 0x10
|
||||
#define MHL_XDS_LINK_CLOCK_300MHZ 0x20
|
||||
#define MHL_XDS_LINK_CLOCK_600MHZ 0x30
|
||||
|
||||
/* XDEVSTAT - AV Link Mode Status 7.12.2.2 */
|
||||
#define MHL_XDS_LINK_STATUS_NO_SIGNAL 0x00
|
||||
#define MHL_XDS_LINK_STATUS_CRU_LOCKED 0x01
|
||||
#define MHL_XDS_LINK_STATUS_TMDS_NORMAL 0x02
|
||||
#define MHL_XDS_LINK_STATUS_TMDS_RESERVED 0x03
|
||||
|
||||
/* XDEVSTAT - AV Link Mode Control 7.12.2.3 */
|
||||
#define MHL_STATUS_REG_AV_LINK_MODE_CONTROL 0x92
|
||||
#define MHL_XDS_LINK_RATE_1_5_GBPS 0x00
|
||||
#define MHL_XDS_LINK_RATE_3_0_GBPS 0x01
|
||||
#define MHL_XDS_LINK_RATE_6_0_GBPS 0x02
|
||||
#define MHL_XDS_ATT_CAPABLE 0x08
|
||||
|
||||
/* XDEVSTAT - Multi-Sink Status 7.12.2.4 */
|
||||
#define MHL_XDS_SINK_STATUS_1_HPD_LOW 0x00
|
||||
#define MHL_XDS_SINK_STATUS_1_HPD_HIGH 0x01
|
||||
#define MHL_XDS_SINK_STATUS_2_HPD_LOW 0x00
|
||||
#define MHL_XDS_SINK_STATUS_2_HPD_HIGH 0x04
|
||||
#define MHL_XDS_SINK_STATUS_3_HPD_LOW 0x00
|
||||
#define MHL_XDS_SINK_STATUS_3_HPD_HIGH 0x10
|
||||
#define MHL_XDS_SINK_STATUS_4_HPD_LOW 0x00
|
||||
#define MHL_XDS_SINK_STATUS_4_HPD_HIGH 0x40
|
||||
|
||||
/*
|
||||
* Define format of Write Burst used in MHL 3
|
||||
* to assign TDM slots to virtual channels.
|
||||
*/
|
||||
struct SI_PACK_THIS_STRUCT virt_chan_info {
|
||||
uint8_t vc_num;
|
||||
uint8_t feature_id;
|
||||
#define FEATURE_ID_E_MSC 0x00
|
||||
#define FEATURE_ID_USB 0x01
|
||||
#define FEATURE_ID_AUDIO 0x02
|
||||
#define FEATURE_ID_IP 0x03
|
||||
#define FEATURE_ID_COMP_VIDEO 0x04
|
||||
#define FEATURE_ID_HID 0x05
|
||||
#define FEATURE_ID_LAST FEATURE_ID_HID
|
||||
union {
|
||||
uint8_t channel_size;
|
||||
uint8_t response;
|
||||
#define VC_RESPONSE_ACCEPT 0x00
|
||||
#define VC_RESPONSE_BAD_VC_NUM 0x01
|
||||
#define VC_RESPONSE_BAD_FEATURE_ID 0x02
|
||||
#define VC_RESPONSE_BAD_CHANNEL_SIZE 0x03
|
||||
} req_resp;
|
||||
};
|
||||
|
||||
#define MAX_VC_ENTRIES 3
|
||||
struct SI_PACK_THIS_STRUCT tdm_alloc_burst {
|
||||
struct MHL3_burst_header_t header;
|
||||
uint8_t num_entries_this_burst;
|
||||
struct virt_chan_info vc_info[MAX_VC_ENTRIES];
|
||||
uint8_t reserved;
|
||||
};
|
||||
|
||||
/* BIST_SETUP WRITE_BURST 15.1.1 */
|
||||
#define BIST_ECBUS_PATTERN_UNSPECIFIED 0x00
|
||||
#define BIST_ECBUS_PATTERN_PRBS 0x01
|
||||
#define BIST_ECBUS_PATTERN_FIXED_8 0x02
|
||||
#define BIST_ECBUS_PATTERN_FIXED_10 0x03
|
||||
#define BIST_ECBUS_PATTERN_MAX BIST_ECBUS_PATTERN_FIXED_10
|
||||
|
||||
#define BIST_AVLINK_DATA_RATE_UNSPECIFIED 0x00
|
||||
#define BIST_AVLINK_DATA_RATE_1500MBPS 0x01
|
||||
#define BIST_AVLINK_DATA_RATE_3000MBPS 0x02
|
||||
#define BIST_AVLINK_DATA_RATE_6000MBPS 0x03
|
||||
#define BIST_AVLINK_DATA_RATE_MAX BIST_AVLINK_DATA_RATE_6000MBPS
|
||||
|
||||
#define BIST_AVLINK_PATTERN_UNSPECIFIED 0x00
|
||||
#define BIST_AVLINK_PATTERN_PRBS 0x01
|
||||
#define BIST_AVLINK_PATTERN_FIXED_8 0x02
|
||||
#define BIST_AVLINK_PATTERN_FIXED_10 0x03
|
||||
#define BIST_AVLINK_PATTERN_MAX BIST_AVLINK_PATTERN_FIXED_10
|
||||
|
||||
#define BIST_IMPEDANCE_MODE_AVLINK_TX_LOW 0x00
|
||||
#define BIST_IMPEDANCE_MODE_AVLINK_TX_HIGH 0x01
|
||||
#define BIST_IMPEDANCE_MODE_AVLINK_RX 0x02
|
||||
#define BIST_IMPEDANCE_MODE_RESERVED_1 0x03
|
||||
#define BIST_IMPEDANCE_MODE_ECBUS_D_TX_LOW 0x04
|
||||
#define BIST_IMPEDANCE_MODE_ECBUS_D_TX_HIGH 0x05
|
||||
#define BIST_IMPEDANCE_MODE_ECBUS_D_RX 0x06
|
||||
#define BIST_IMPEDANCE_MODE_RESERVED_2 0x07
|
||||
#define BIST_IMPEDANCE_MODE_ECBUS_S_TX_LOW 0x08
|
||||
#define BIST_IMPEDANCE_MODE_ECBUS_S_TX_HIGH 0x09
|
||||
#define BIST_IMPEDANCE_MODE_ECBUS_S_RX 0x0A
|
||||
#define BIST_IMPEDANCE_MODE_MAX BIST_IMPEDANCE_MODE_ECBUS_S_RX
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_setup_burst {
|
||||
uint8_t burst_id_h;
|
||||
uint8_t burst_id_l;
|
||||
uint8_t checksum;
|
||||
uint8_t e_cbus_duration;
|
||||
uint8_t e_cbus_pattern;
|
||||
uint8_t e_cbus_fixed_h;
|
||||
uint8_t e_cbus_fixed_l;
|
||||
uint8_t reserved;
|
||||
uint8_t avlink_data_rate;
|
||||
uint8_t avlink_pattern;
|
||||
uint8_t avlink_video_mode;
|
||||
uint8_t avlink_duration;
|
||||
uint8_t avlink_fixed_h;
|
||||
uint8_t avlink_fixed_l;
|
||||
uint8_t avlink_randomizer;
|
||||
uint8_t impedance_mode;
|
||||
};
|
||||
|
||||
/* BIST_RETURN_STAT WRITE_BURST 15.1.2 */
|
||||
struct SI_PACK_THIS_STRUCT bist_return_stat_burst {
|
||||
uint8_t burst_id_h;
|
||||
uint8_t burst_id_l;
|
||||
uint8_t checksum;
|
||||
uint8_t reserved[9];
|
||||
uint8_t e_cbus_stat_h;
|
||||
uint8_t e_cbus_stat_l;
|
||||
uint8_t avlink_stat_h;
|
||||
uint8_t avlink_stat_l;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_discard_burst_hdr {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t remaining_length;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_discard_burst {
|
||||
struct bist_discard_burst_hdr hdr;
|
||||
uint8_t payload[13];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_echo_request_burst_hdr {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t remaining_length;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_echo_request_burst {
|
||||
struct bist_echo_request_burst_hdr hdr;
|
||||
uint8_t payload[13];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_echo_response_burst_hdr {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t remaining_length;
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT bist_echo_response_burst {
|
||||
struct bist_echo_response_burst_hdr hdr;
|
||||
uint8_t payload[13];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT si_adopter_id_sub_payload_hdr {
|
||||
struct MHL_burst_id_t burst_id;
|
||||
uint8_t remaining_length;
|
||||
uint8_t checksum;
|
||||
uint8_t op_code;
|
||||
};
|
||||
enum si_adopter_id_opcode {
|
||||
EDID_BLOCK = 0,
|
||||
EDID_STOP = 1,
|
||||
};
|
||||
struct SI_PACK_THIS_STRUCT si_opcode_data_edid_block {
|
||||
uint8_t block_num;
|
||||
uint8_t data[128];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT si_adopter_id_data {
|
||||
struct SI_PACK_THIS_STRUCT si_adopter_id_sub_payload_hdr hdr;
|
||||
union {
|
||||
struct SI_PACK_THIS_STRUCT si_opcode_data_edid_block edid_blk;
|
||||
/* more members to come later */
|
||||
} opcode_data;
|
||||
};
|
||||
|
||||
#define MHL_T_src_vbus_cbus_stable_min 100
|
||||
#define T_BIST_MODE_DOWN_MAX 5000
|
||||
#define T_BIST_MODE_DOWN_MIN 2000
|
||||
|
||||
#endif
|
222
drivers/video/fbdev/msm/mhl3/si_mhl_tx_hw_drv_api.h
Normal file
222
drivers/video/fbdev/msm/mhl3/si_mhl_tx_hw_drv_api.h
Normal file
|
@ -0,0 +1,222 @@
|
|||
/*
|
||||
* SiI8620 Linux Driver
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if !defined(SI_MHL_TX_DRV_API_H)
|
||||
#define SI_MHL_TX_DRV_API_H
|
||||
|
||||
/*
|
||||
* Structure to hold command details from upper layer to CBUS module
|
||||
*/
|
||||
struct cbus_req {
|
||||
struct list_head link;
|
||||
union {
|
||||
struct {
|
||||
uint8_t cancel:1; /* this command has been canceled */
|
||||
uint8_t resvd:7;
|
||||
} flags;
|
||||
uint8_t as_uint8;
|
||||
} status;
|
||||
uint8_t retry_count;
|
||||
uint8_t command; /* VS_CMD or RCP opcode */
|
||||
uint8_t reg;
|
||||
uint8_t reg_data;
|
||||
uint8_t burst_offset; /* register offset */
|
||||
uint8_t length; /* Only applicable to write burst */
|
||||
uint8_t msg_data[16]; /* scratch pad data area. */
|
||||
const char *function;
|
||||
int line;
|
||||
int sequence;
|
||||
struct cbus_req *(*completion)(struct mhl_dev_context *dev_context,
|
||||
struct cbus_req *req,
|
||||
uint8_t data1);
|
||||
};
|
||||
struct SI_PACK_THIS_STRUCT tport_hdr_and_burst_id_t {
|
||||
/* waste two bytes to save on memory copying when submitting BLOCK
|
||||
* transactions
|
||||
*/
|
||||
struct SI_PACK_THIS_STRUCT standard_transport_header_t tport_hdr;
|
||||
|
||||
/* sub-payloads start here */
|
||||
struct MHL_burst_id_t burst_id;
|
||||
};
|
||||
union SI_PACK_THIS_STRUCT emsc_payload_t {
|
||||
struct SI_PACK_THIS_STRUCT tport_hdr_and_burst_id_t hdr_and_burst_id;
|
||||
uint8_t as_bytes[256];
|
||||
};
|
||||
|
||||
struct SI_PACK_THIS_STRUCT block_req {
|
||||
struct list_head link;
|
||||
const char *function;
|
||||
int line;
|
||||
int sequence;
|
||||
uint16_t count; /* (size - 1) see MHL spec section 13.5.7.2 */
|
||||
uint8_t space_remaining;
|
||||
uint8_t sub_payload_size;
|
||||
uint8_t *platform_header;
|
||||
union SI_PACK_THIS_STRUCT emsc_payload_t *payload;
|
||||
};
|
||||
|
||||
enum quantization_settings_e {
|
||||
qs_auto_select_by_color_space,
|
||||
qs_full_range,
|
||||
qs_limited_range,
|
||||
qs_reserved
|
||||
};
|
||||
|
||||
struct bist_setup_info {
|
||||
uint8_t e_cbus_duration;
|
||||
uint8_t e_cbus_pattern;
|
||||
uint16_t e_cbus_fixed_pat;
|
||||
uint8_t avlink_data_rate;
|
||||
uint8_t avlink_pattern;
|
||||
uint8_t avlink_video_mode;
|
||||
uint8_t avlink_duration;
|
||||
uint16_t avlink_fixed_pat;
|
||||
uint8_t avlink_randomizer;
|
||||
uint8_t impedance_mode;
|
||||
uint8_t bist_trigger_parm;
|
||||
uint8_t bist_stat_parm;
|
||||
uint32_t t_bist_mode_down;
|
||||
};
|
||||
|
||||
struct bist_stat_info {
|
||||
uint16_t e_cbus_remote_stat;
|
||||
int32_t e_cbus_next_local_stat;
|
||||
int32_t e_cbus_local_stat;
|
||||
int32_t e_cbus_prev_local_stat;
|
||||
uint16_t avlink_stat;
|
||||
};
|
||||
|
||||
/*
|
||||
* The APIs listed below must be implemented by the MHL transmitter
|
||||
* hardware support module.
|
||||
*/
|
||||
|
||||
struct drv_hw_context;
|
||||
struct interrupt_info;
|
||||
|
||||
int si_mhl_tx_chip_initialize(struct drv_hw_context *hw_context);
|
||||
void si_mhl_tx_drv_device_isr(struct drv_hw_context *hw_context,
|
||||
struct interrupt_info *intr_info);
|
||||
void si_mhl_tx_drv_disable_video_path(struct drv_hw_context *hw_context);
|
||||
void si_mhl_tx_drv_enable_video_path(struct drv_hw_context *hw_context);
|
||||
|
||||
void si_mhl_tx_drv_content_on(struct drv_hw_context *hw_context);
|
||||
void si_mhl_tx_drv_content_off(struct drv_hw_context *hw_context);
|
||||
uint8_t si_mhl_tx_drv_send_cbus_command(struct drv_hw_context *hw_context,
|
||||
struct cbus_req *req);
|
||||
|
||||
void mhl_tx_drv_send_block(struct drv_hw_context *hw_context,
|
||||
struct block_req *req);
|
||||
int si_mhl_tx_drv_get_scratch_pad(struct drv_hw_context *hw_context,
|
||||
uint8_t start_reg, uint8_t *data, uint8_t length);
|
||||
void si_mhl_tx_read_devcap_fifo(struct drv_hw_context *hw_context,
|
||||
union MHLDevCap_u *dev_cap_buf);
|
||||
void si_mhl_tx_read_xdevcap_fifo(struct drv_hw_context *hw_context,
|
||||
union MHLXDevCap_u *xdev_cap_buf);
|
||||
int si_mhl_tx_drv_get_aksv(struct drv_hw_context *hw_context, uint8_t *buffer);
|
||||
|
||||
void si_mhl_tx_drv_start_avlink_bist(struct mhl_dev_context *dev_context,
|
||||
struct bist_setup_info *test_info);
|
||||
void si_mhl_tx_drv_stop_avlink_bist(struct drv_hw_context *hw_context);
|
||||
void si_mhl_tx_drv_start_ecbus_bist(struct drv_hw_context *hw_context,
|
||||
struct bist_setup_info *test_info);
|
||||
|
||||
uint8_t si_mhl_tx_drv_ecbus_connected(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_drv_continue_ecbus_bist(
|
||||
struct mhl_dev_context *dev_context);
|
||||
int32_t si_mhl_tx_drv_get_ecbus_bist_status(
|
||||
struct mhl_dev_context *dev_context,
|
||||
uint8_t *rx_run_done,
|
||||
uint8_t *tx_run_done);
|
||||
#define BIST_LOCAL_COUNT_INVALID -2
|
||||
void si_mhl_tx_drv_stop_ecbus_bist(struct drv_hw_context *hw_context,
|
||||
struct bist_setup_info *test_info);
|
||||
int si_mhl_tx_drv_start_impedance_bist(struct drv_hw_context *hw_context,
|
||||
struct bist_setup_info *test_info);
|
||||
void si_mhl_tx_drv_stop_impedance_bist(struct drv_hw_context *hw_context,
|
||||
struct bist_setup_info *test_info);
|
||||
|
||||
void si_mhl_tx_drv_shutdown(struct drv_hw_context *hw_context);
|
||||
|
||||
int si_mhl_tx_drv_connection_is_mhl3(struct mhl_dev_context *dev_context);
|
||||
|
||||
int si_mhl_tx_drv_get_highest_tmds_link_speed(
|
||||
struct mhl_dev_context *dev_context);
|
||||
|
||||
uint8_t si_mhl_tx_drv_hawb_xfifo_avail(struct mhl_dev_context *dev_context);
|
||||
|
||||
uint8_t si_mhl_tx_drv_get_pending_hawb_write_status(
|
||||
struct mhl_dev_context *dev_context);
|
||||
|
||||
enum cbus_mode_e {
|
||||
CM_NO_CONNECTION,
|
||||
CM_NO_CONNECTION_BIST_SETUP,
|
||||
CM_NO_CONNECTION_BIST_STAT,
|
||||
CM_oCBUS_PEER_VERSION_PENDING,
|
||||
CM_oCBUS_PEER_VERSION_PENDING_BIST_SETUP,
|
||||
CM_oCBUS_PEER_VERSION_PENDING_BIST_STAT,
|
||||
CM_oCBUS_PEER_IS_MHL1_2,
|
||||
CM_oCBUS_PEER_IS_MHL3_BIST_SETUP,
|
||||
CM_oCBUS_PEER_IS_MHL3_BIST_SETUP_SENT,
|
||||
CM_oCBUS_PEER_IS_MHL3_BIST_SETUP_PEER_READY,
|
||||
CM_oCBUS_PEER_IS_MHL3_BIST_STAT,
|
||||
CM_oCBUS_PEER_IS_MHL3,
|
||||
CM_TRANSITIONAL_TO_eCBUS_S_BIST,
|
||||
CM_TRANSITIONAL_TO_eCBUS_D_BIST,
|
||||
CM_TRANSITIONAL_TO_eCBUS_S,
|
||||
CM_TRANSITIONAL_TO_eCBUS_D,
|
||||
CM_TRANSITIONAL_TO_eCBUS_S_CAL_BIST,
|
||||
CM_TRANSITIONAL_TO_eCBUS_D_CAL_BIST,
|
||||
CM_TRANSITIONAL_TO_eCBUS_S_CALIBRATED,
|
||||
CM_TRANSITIONAL_TO_eCBUS_D_CALIBRATED,
|
||||
CM_eCBUS_S_BIST,
|
||||
CM_eCBUS_D_BIST,
|
||||
CM_BIST_DONE_PENDING_DISCONNECT,
|
||||
CM_eCBUS_S,
|
||||
CM_eCBUS_D,
|
||||
CM_eCBUS_S_AV_BIST,
|
||||
CM_eCBUS_D_AV_BIST,
|
||||
|
||||
NUM_CM_MODES
|
||||
};
|
||||
|
||||
enum cbus_mode_e si_mhl_tx_drv_get_cbus_mode(
|
||||
struct mhl_dev_context *dev_context);
|
||||
char *si_mhl_tx_drv_get_cbus_mode_str(enum cbus_mode_e cbus_mode);
|
||||
|
||||
uint16_t si_mhl_tx_drv_get_blk_rcv_buf_size(void);
|
||||
|
||||
void si_mhl_tx_drv_start_cp(struct mhl_dev_context *dev_context);
|
||||
void si_mhl_tx_drv_shut_down_HDCP2(struct drv_hw_context *hw_context);
|
||||
|
||||
bool si_mhl_tx_drv_support_e_cbus_d(struct drv_hw_context *hw_context);
|
||||
|
||||
int si_mhl_tx_drv_switch_cbus_mode(struct drv_hw_context *hw_context,
|
||||
enum cbus_mode_e mode_sel);
|
||||
void si_mhl_tx_drv_free_block_input_buffer(struct mhl_dev_context *dev_context);
|
||||
int si_mhl_tx_drv_peek_block_input_buffer(struct mhl_dev_context *dev_context,
|
||||
uint8_t **buffer, int *length);
|
||||
|
||||
enum tdm_vc_num {
|
||||
VC_CBUS1,
|
||||
VC_E_MSC,
|
||||
VC_T_CBUS,
|
||||
VC_MAX
|
||||
};
|
||||
int si_mhl_tx_drv_set_tdm_slot_allocation(struct drv_hw_context *hw_context,
|
||||
uint8_t *vc_slot_counts, bool program);
|
||||
|
||||
#endif /* if !defined(SI_MHL_TX_DRV_API_H) */
|
13
drivers/video/fbdev/msm/mhl3/sii6031/Kconfig
Normal file
13
drivers/video/fbdev/msm/mhl3/sii6031/Kconfig
Normal file
|
@ -0,0 +1,13 @@
|
|||
comment "Driver for Silicon Image SiI6031 MHL/USB switch (Stark)"
|
||||
|
||||
config SII6031_MHL_SWITCH
|
||||
bool "SIMG GPIO support"
|
||||
depends on GPIOLIB
|
||||
default y
|
||||
help
|
||||
yes links this driver.
|
||||
This driver is required by Qualcomm APQ8074 platform
|
||||
with modified usb otg driver (msm_otg.c) for SiI6031 switch.
|
||||
|
||||
If unsure, say N.
|
||||
|
2
drivers/video/fbdev/msm/mhl3/sii6031/Makefile
Normal file
2
drivers/video/fbdev/msm/mhl3/sii6031/Makefile
Normal file
|
@ -0,0 +1,2 @@
|
|||
obj-$(CONFIG_SII6031_MHL_SWITCH) +=si_6031_switch.o
|
||||
#si_6031_switch-objs := si_6031_switch.o
|
151
drivers/video/fbdev/msm/mhl3/sii6031/si_6031_switch.c
Normal file
151
drivers/video/fbdev/msm/mhl3/sii6031/si_6031_switch.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* SIMG SiI6031 MHL-USB Switch driver
|
||||
*
|
||||
* Copyright 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 version 2
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/si_6031_switch.h>
|
||||
|
||||
struct gpio stark_gpio_ctrl[3] = {
|
||||
{0, GPIOF_OUT_INIT_HIGH, "MHL_USB_0"},
|
||||
{0, GPIOF_OUT_INIT_HIGH, "MHL_USB_1"},
|
||||
{0, GPIOF_OUT_INIT_HIGH, "MHL_VBUS"}
|
||||
};
|
||||
|
||||
void sii_switch_to_mhl(bool switch_to_mhl)
|
||||
{
|
||||
if(switch_to_mhl)
|
||||
{
|
||||
printk("%s(): SIMG: switch to MHL gpio [%d, %d] \n", __func__,
|
||||
stark_gpio_ctrl[MHL_USB_0].gpio,
|
||||
stark_gpio_ctrl[MHL_USB_1].gpio);
|
||||
gpio_set_value(stark_gpio_ctrl[MHL_USB_0].gpio, 1);
|
||||
gpio_set_value(stark_gpio_ctrl[MHL_USB_1].gpio, 1);
|
||||
}
|
||||
else {
|
||||
printk("%s(): SIMG: switch to USB gpio [%d, %d] \n", __func__,
|
||||
stark_gpio_ctrl[MHL_USB_0].gpio,
|
||||
stark_gpio_ctrl[MHL_USB_1].gpio);
|
||||
gpio_set_value(stark_gpio_ctrl[MHL_USB_0].gpio, 0);
|
||||
gpio_set_value(stark_gpio_ctrl[MHL_USB_1].gpio, 0);
|
||||
}
|
||||
/*gpio_set_value(stark_gpio_ctrl[MHL_USB_VBUS].gpio, 1);*/
|
||||
printk("%s(): exit\n", __func__);
|
||||
}
|
||||
EXPORT_SYMBOL(sii_switch_to_mhl);
|
||||
|
||||
int sii6031_gpio_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
printk("%s(): called\n", __func__);
|
||||
ret = gpio_request_array(stark_gpio_ctrl, ARRAY_SIZE(stark_gpio_ctrl));
|
||||
if (ret < 0)
|
||||
printk("%s(): gpio_request_array failed, error code %d\n",__func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sii6031_parse_dt(struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
int value;
|
||||
|
||||
value = of_get_named_gpio_flags(np, "simg,gpio_sel0", 0, NULL);
|
||||
if (value >= 0)
|
||||
stark_gpio_ctrl[MHL_USB_0].gpio = value;
|
||||
|
||||
value = of_get_named_gpio_flags(np, "simg,gpio_sel1", 0, NULL);
|
||||
if (value >= 0)
|
||||
stark_gpio_ctrl[MHL_USB_1].gpio = value;
|
||||
|
||||
value = of_get_named_gpio_flags(np, "simg,gpio_vbus", 0, NULL);
|
||||
if (value >= 0)
|
||||
stark_gpio_ctrl[MHL_USB_VBUS].gpio = value;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int __devinit sii6031_probe(struct platform_device *pdev)
|
||||
{
|
||||
int ret =0;
|
||||
|
||||
|
||||
if(pdev->dev.of_node)
|
||||
ret = sii6031_parse_dt(&pdev->dev);
|
||||
|
||||
|
||||
if(ret)
|
||||
return -1;
|
||||
|
||||
|
||||
ret = sii6031_gpio_init();
|
||||
|
||||
if(ret)
|
||||
return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
static int __devexit sii6031_remove(struct platform_device *pdev)
|
||||
{
|
||||
gpio_free_array(stark_gpio_ctrl,ARRAY_SIZE(stark_gpio_ctrl));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id sii6031_gpio_match[] = {
|
||||
{ .compatible = "simg,sii-6031", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sii6031_gpio_match);
|
||||
|
||||
static struct platform_driver sii6031_driver = {
|
||||
.probe = sii6031_probe,
|
||||
.remove = __devexit_p(sii6031_remove),
|
||||
.driver = {
|
||||
.name = "simg,sii-6031",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(sii6031_gpio_match),
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sii6031_init(void)
|
||||
{
|
||||
return platform_driver_register(&sii6031_driver);
|
||||
}
|
||||
|
||||
static void __exit sii6031_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&sii6031_driver);
|
||||
}
|
||||
module_init(sii6031_init);
|
||||
module_exit(sii6031_exit);
|
||||
|
||||
MODULE_AUTHOR("Praveen Kumar Vuppala<praveen.vuppala@siliconimage.com>");
|
||||
MODULE_DESCRIPTION("SiI6031 Switch driver");
|
||||
MODULE_LICENSE("GPL");
|
20
drivers/video/fbdev/msm/mhl3/sii6031/si_6031_switch.h
Normal file
20
drivers/video/fbdev/msm/mhl3/sii6031/si_6031_switch.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef __MHL_8620_H
|
||||
#define __MHL_8620_H
|
||||
|
||||
|
||||
#define MHL_USB_0 0
|
||||
#define MHL_USB_1 1
|
||||
#define MHL_USB_VBUS 2
|
||||
|
||||
void sii_switch_to_mhl(bool switch_to_mhl);
|
||||
/*#ifdef CONFIG_SII8061_MHL_SWITCH
|
||||
void sii_switch_to_mhl(bool switch_to_mhl);
|
||||
#else
|
||||
void inline sii_switch_to_mhl(bool switch_to_mhl)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
#endif
|
Loading…
Add table
Reference in a new issue