diff options
Diffstat (limited to 'drivers/video/av8100')
-rw-r--r-- | drivers/video/av8100/Kconfig | 48 | ||||
-rw-r--r-- | drivers/video/av8100/Makefile | 10 | ||||
-rw-r--r-- | drivers/video/av8100/av8100.c | 3617 | ||||
-rw-r--r-- | drivers/video/av8100/av8100_fw.h | 1165 | ||||
-rw-r--r-- | drivers/video/av8100/av8100_regs.h | 340 | ||||
-rw-r--r-- | drivers/video/av8100/hdmi.c | 2220 | ||||
-rw-r--r-- | drivers/video/av8100/hdmi_loc.h | 67 |
7 files changed, 7467 insertions, 0 deletions
diff --git a/drivers/video/av8100/Kconfig b/drivers/video/av8100/Kconfig new file mode 100644 index 00000000000..40b9943aaa9 --- /dev/null +++ b/drivers/video/av8100/Kconfig @@ -0,0 +1,48 @@ +config AV8100 + tristate "AV8100 driver support(HDMI/CVBS)" + default n + help + Please enable this feature if hdmi/tvout driver support is required. + +config HDMI_AV8100_DEBUG + bool "HDMI and AV8100 debug messages" + default n + depends on AV8100 + ---help--- + Say Y here if you want the HDMI and AV8100 driver to + output debug messages. + +choice + prompt "AV8100 HW trig method" + default AV8100_HWTRIG_DSI_TE + +config AV8100_HWTRIG_INT + bool "AV8100 HW trig on INT" + depends on AV8100 + ---help--- + If you say Y here AV8100 will use HW triggering + from AV8100 INT to MCDE sync0. + +config AV8100_HWTRIG_I2SDAT3 + bool "AV8100 HW trig on I2SDAT3" + depends on AV8100 + ---help--- + If you say Y here AV8100 will use HW triggering + from AV8100 I2SDAT3 to MCDE sync1. + +config AV8100_HWTRIG_DSI_TE + bool "AV8100 HW trig on DSI" + depends on AV8100 + ---help--- + If you say Y here AV8100 will use HW triggering + using DSI TE polling between AV8100 and MCDE. + +config AV8100_HWTRIG_NONE + bool "AV8100 SW trig" + depends on AV8100 + ---help--- + If you say Y here AV8100 will use SW triggering + between AV8100 and MCDE. + +endchoice + diff --git a/drivers/video/av8100/Makefile b/drivers/video/av8100/Makefile new file mode 100644 index 00000000000..2d3028b18ca --- /dev/null +++ b/drivers/video/av8100/Makefile @@ -0,0 +1,10 @@ +# Make file for compiling and loadable module HDMI + +obj-$(CONFIG_AV8100) += av8100.o hdmi.o + +ifdef CONFIG_HDMI_AV8100_DEBUG +EXTRA_CFLAGS += -DDEBUG +endif + +clean-files := av8100.o hdmi.o built-in.o modules.order + diff --git a/drivers/video/av8100/av8100.c b/drivers/video/av8100/av8100.c new file mode 100644 index 00000000000..6bacded36df --- /dev/null +++ b/drivers/video/av8100/av8100.c @@ -0,0 +1,3617 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * + * AV8100 driver + * + * Author: Per Persson <per.xb.persson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL), version 2. + */ + + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/device.h> +#include <linux/miscdevice.h> +#include <linux/platform_device.h> +#include <linux/i2c.h> +#include <linux/fs.h> +#include <linux/gpio.h> +#include <linux/delay.h> +#include <linux/kthread.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/timer.h> +#include <linux/mutex.h> +#include <linux/slab.h> +#include <linux/clk.h> +#include <linux/regulator/consumer.h> +#include <mach/prcmu-fw-api.h> + +#include "av8100_regs.h" +#include <video/av8100.h> +#include <video/hdmi.h> +#include "av8100_fw.h" + +/* Interrupts */ +#define AV8100_INT_EVENT 0x1 +#define AV8100_PLUGSTARTUP_EVENT 0x4 + +#define AV8100_PLUGSTARTUP_TIME 100 + +/* Standby search time */ +#define AV8100_ON_TIME 1 /* 20 ms step */ +#define AV8100_DENC_OFF_TIME 3 /* 640 ms step if > V1. Not used if V1 */ +#define AV8100_HDMI_OFF_TIME 2 /* 320 ms step if V2. 80 ms step if V1 */ + +/* Command offsets */ +#define AV8100_COMMAND_OFFSET 0x10 +#define AV8100_COMMAND_MAX_LENGTH 0x81 +#define AV8100_CMD_BUF_OFFSET (AV8100_COMMAND_OFFSET + 1) +#define AV8100_2ND_RET_BYTE_OFFSET (AV8100_COMMAND_OFFSET + 1) +#define AV8100_CEC_RET_BUF_OFFSET (AV8100_COMMAND_OFFSET + 4) +#define AV8100_HDCP_RET_BUF_OFFSET (AV8100_COMMAND_OFFSET + 2) +#define AV8100_EDID_RET_BUF_OFFSET (AV8100_COMMAND_OFFSET + 1) +#define AV8100_FUSE_CRC_OFFSET (AV8100_COMMAND_OFFSET + 2) +#define AV8100_FUSE_PRGD_OFFSET (AV8100_COMMAND_OFFSET + 3) +#define AV8100_CRC32_OFFSET (AV8100_COMMAND_OFFSET + 2) +#define AV8100_CEC_ADDR_OFFSET (AV8100_COMMAND_OFFSET + 3) + +/* Tearing effect line numbers */ +#define AV8100_TE_LINE_NB_14 14 +#define AV8100_TE_LINE_NB_17 17 +#define AV8100_TE_LINE_NB_18 18 +#define AV8100_TE_LINE_NB_21 21 +#define AV8100_TE_LINE_NB_22 22 +#define AV8100_TE_LINE_NB_30 30 +#define AV8100_TE_LINE_NB_38 38 +#define AV8100_TE_LINE_NB_40 40 +#define AV8100_UI_X4_DEFAULT 6 + +#define HDMI_REQUEST_FOR_REVOCATION_LIST_INPUT 2 +#define HDMI_CEC_MESSAGE_WRITE_BUFFER_SIZE 16 +#define HDMI_HDCP_SEND_KEY_SIZE 7 +#define HDMI_INFOFRAME_DATA_SIZE 28 +#define HDMI_FUSE_AES_KEY_SIZE 16 +#define HDMI_FUSE_AES_KEY_RET_SIZE 2 +#define HDMI_LOADAES_END_BLK_NR 145 +#define HDMI_CRC32_SIZE 4 +#define HDMI_REVOC_LIST_SIZE 30 +#define HDMI_EDIDREAD_SIZE 0x7F + +#define HPDS_INVALID 0xF +#define CPDS_INVALID 0xF +#define CECRX_INVALID 0xF + +#define REG_16_8_LSB(p) ((u8)(p & 0xFF)) +#define REG_16_8_MSB(p) ((u8)((p & 0xFF00)>>8)) +#define REG_32_8_MSB(p) ((u8)((p & 0xFF000000)>>24)) +#define REG_32_8_MMSB(p) ((u8)((p & 0x00FF0000)>>16)) +#define REG_32_8_MLSB(p) ((u8)((p & 0x0000FF00)>>8)) +#define REG_32_8_LSB(p) ((u8)(p & 0x000000FF)) +#define REG_10_8_MSB(p) ((u8)((p & 0x300)>>8)) +#define REG_12_8_MSB(p) ((u8)((p & 0xf00)>>8)) + +#define AV8100_POWERON_WAITTIME1_MS 1 +#define AV8100_POWERON_WAITTIME2_MS 1 +#define AV8100_CMD_RET_WAITTIME_MS 1 +#define AV8100_CMD_RET_TRIES 10 +#define AV8100_FWDL_WAITTIME1 10 +#define AV8100_FWDL_WAITTIME2 1 +#define AV8100_FWDL_TRIES 10 + +/* Master clock timing */ +#define MCLK_RNG_17_22 0 /* Use with 19.2 MHZ clock */ +#define MCLK_RNG_22_27 1 +#define MCLK_RNG_27_33 2 +#define MCLK_RNG_31_38 3 /* Use with 38.4 MHZ clock */ +#define MCLK_RNG_36_44 4 +#define MCLK_RNG_40_49 5 +#define MCLK_RNG_45_55 6 +#define MCLK_RNG_49_60 7 +#define MCLK_RNG_54_66 8 +#define MCLK_RNG_58_71 9 +#define MCLK_RNG_63_77 10 +#define MCLK_RNG_67_82 11 +#define MCLK_RNG_72_88 12 +#define MCLK_RNG_76_93 13 +#define MCLK_RNG_85_104 14 +#define MCLK_RNG_94_115 15 +/* + * Until there is an API for obtaining the input master clock + * frequency, the register value is hard coded. + */ +#define MCLK_FREQ MCLK_RNG_31_38 + +DEFINE_MUTEX(av8100_hw_mutex); +#define LOCK_AV8100_HW mutex_lock(&av8100_hw_mutex) +#define UNLOCK_AV8100_HW mutex_unlock(&av8100_hw_mutex) + +struct color_conversion_cmd { + unsigned short c0; + unsigned short c1; + unsigned short c2; + unsigned short c3; + unsigned short c4; + unsigned short c5; + unsigned short c6; + unsigned short c7; + unsigned short c8; + unsigned short aoffset; + unsigned short boffset; + unsigned short coffset; + unsigned char lmax; + unsigned char lmin; + unsigned char cmax; + unsigned char cmin; +}; + +struct av8100_config_t { + struct i2c_client *client; + struct i2c_device_id *id; + struct av8100_video_input_format_cmd hdmi_video_input_cmd; + struct av8100_audio_input_format_cmd hdmi_audio_input_cmd; + struct av8100_video_output_format_cmd hdmi_video_output_cmd; + struct av8100_video_scaling_format_cmd hdmi_video_scaling_cmd; + enum av8100_color_transform color_transform; + struct av8100_cec_message_write_format_cmd + hdmi_cec_message_write_cmd; + struct av8100_cec_message_read_back_format_cmd + hdmi_cec_message_read_back_cmd; + struct av8100_denc_format_cmd hdmi_denc_cmd; + struct av8100_hdmi_cmd hdmi_cmd; + struct av8100_hdcp_send_key_format_cmd hdmi_hdcp_send_key_cmd; + struct av8100_hdcp_management_format_cmd + hdmi_hdcp_management_format_cmd; + struct av8100_infoframes_format_cmd hdmi_infoframes_cmd; + struct av8100_edid_section_readback_format_cmd + hdmi_edid_section_readback_cmd; + struct av8100_pattern_generator_format_cmd hdmi_pattern_generator_cmd; + struct av8100_fuse_aes_key_format_cmd hdmi_fuse_aes_key_cmd; +}; + +enum av8100_plug_state { + AV8100_UNPLUGGED, + AV8100_PLUGGED_STARTUP, + AV8100_PLUGGED +}; + +struct av8100_globals_t { + int denc_off_time;/* 5 volt time */ + int hdmi_off_time;/* 5 volt time */ + int on_time;/* 5 volt time */ + u8 hpdm;/*stby_int_mask*/ + u8 cpdm;/*stby_int_mask*/ + u8 cecm;/*gen_int_mask*/ + u8 hdcpm;/*gen_int_mask*/ + void (*hdmi_ev_cb)(enum av8100_hdmi_event); + enum av8100_plug_state plug_state; + struct clk *inputclk; + bool inputclk_requested; + bool opp_requested; + struct regulator *regulator_pwr; + bool regulator_requested; +}; + +/** + * struct av8100_cea - CEA(consumer electronic access) standard structure + * @cea_id: + * @cea_nb: + * @vtotale: + **/ + +struct av8100_cea { + char cea_id[40]; + int cea_nb; + int vtotale; + int vactive; + int vsbp; + int vslen; + int vsfp; + char vpol[5]; + int htotale; + int hactive; + int hbp; + int hslen; + int hfp; + int frequence; + char hpol[5]; + int reg_line_duration; + int blkoel_duration; + int uix4; + int pll_mult; + int pll_div; +}; + +enum av8100_command_size { + AV8100_COMMAND_VIDEO_INPUT_FORMAT_SIZE = 0x17, + AV8100_COMMAND_AUDIO_INPUT_FORMAT_SIZE = 0x8, + AV8100_COMMAND_VIDEO_OUTPUT_FORMAT_SIZE = 0x1E, + AV8100_COMMAND_VIDEO_SCALING_FORMAT_SIZE = 0x11, + AV8100_COMMAND_COLORSPACECONVERSION_SIZE = 0x1D, + AV8100_COMMAND_CEC_MESSAGE_WRITE_SIZE = 0x12, + AV8100_COMMAND_CEC_MESSAGE_READ_BACK_SIZE = 0x1, + AV8100_COMMAND_DENC_SIZE = 0x6, + AV8100_COMMAND_HDMI_SIZE = 0x4, + AV8100_COMMAND_HDCP_SENDKEY_SIZE = 0xA, + AV8100_COMMAND_HDCP_MANAGEMENT_SIZE = 0x4, + AV8100_COMMAND_INFOFRAMES_SIZE = 0x21, + AV8100_COMMAND_EDID_SECTION_READBACK_SIZE = 0x3, + AV8100_COMMAND_PATTERNGENERATOR_SIZE = 0x4, + AV8100_COMMAND_FUSE_AES_KEY_SIZE = 0x12, + AV8100_COMMAND_FUSE_AES_CHK_SIZE = 0x2, +}; + +static void clr_plug_status(enum av8100_plugin_status status); +static void set_plug_status(enum av8100_plugin_status status); +static void cec_rx(void); +static void cec_txerr(void); +static void hdcp_changed(void); +static const struct color_conversion_cmd *get_color_transform_cmd( + enum av8100_color_transform transform); +static int av8100_open(struct inode *inode, struct file *filp); +static int av8100_release(struct inode *inode, struct file *filp); +static int av8100_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); +static int __devinit av8100_probe(struct i2c_client *i2cClient, + const struct i2c_device_id *id); +static int __devexit av8100_remove(struct i2c_client *i2cClient); + +static struct av8100_config_t *av8100_config; +static struct av8100_status g_av8100_status = {0}; +static struct timer_list av8100_plugtimer; +static wait_queue_head_t av8100_event; +static int av8100_flag = 0x0; +static struct av8100_globals_t *av8100_globals; +static u8 chip_version; +static char av8100_receivetab[AV8100_FW_SIZE]; +struct device *av8100dev; + +static const struct file_operations av8100_fops = { + .owner = THIS_MODULE, + .open = av8100_open, + .release = av8100_release, + //.ioctl is no longer in use - needs fixing + //.ioctl = av8100_ioctl +}; + +static struct miscdevice av8100_miscdev = { + MISC_DYNAMIC_MINOR, + "av8100", + &av8100_fops +}; + +struct av8100_cea av8100_all_cea[29] = { +/* cea id + * cea_nr vtot vact vsbpp vslen + * vsfp vpol htot hact hbp hslen hfp freq + * hpol rld bd uix4 pm pd */ +{ "0 CUSTOM ", + 0, 0, 0, 0, 0, + 0, "-", 800, 640, 16, 96, 10, 25200000, + "-", 0, 0, 0, 0, 0},/*Settings to be defined*/ +{ "1 CEA 1 VESA 4 640x480p @ 60 Hz ", + 1, 525, 480, 33, 2, + 10, "-", 800, 640, 49, 290, 146, 25200000, + "-", 2438, 1270, 6, 32, 1},/*RGB888*/ +{ "2 CEA 2 - 3 720x480p @ 60 Hz 4:3 ", + 2, 525, 480, 30, 6, + 9, "-", 858, 720, 34, 130, 128, 27027000, + "-", 1828, 0x3C0, 8, 24, 1},/*RGB565*/ +{ "3 CEA 4 1280x720p @ 60 Hz ", + 4, 750, 720, 20, 5, + 5, "+", 1650, 1280, 114, 39, 228, 74250000, + "+", 1706, 164, 6, 32, 1},/*RGB565*/ +{ "4 CEA 5 1920x1080i @ 60 Hz ", + 5, 1125, 540, 20, 5, + 0, "+", 2200, 1920, 88, 44, 10, 74250000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "5 CEA 6-7 480i (NTSC) ", + 6, 525, 240, 44, 5, + 0, "-", 858, 720, 12, 64, 10, 13513513, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "6 CEA 14-15 480p @ 60 Hz ", + 14, 525, 480, 44, 5, + 0, "-", 858, 720, 12, 64, 10, 27027000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "7 CEA 16 1920x1080p @ 60 Hz ", + 16, 1125, 1080, 36, 5, + 0, "+", 1980, 1280, 440, 40, 10, 133650000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "8 CEA 17-18 720x576p @ 50 Hz ", + 17, 625, 576, 44, 5, + 0, "-", 864, 720, 12, 64, 10, 27000000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "9 CEA 19 1280x720p @ 50 Hz ", + 19, 750, 720, 25, 5, + 0, "+", 1980, 1280, 440, 40, 10, 74250000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "10 CEA 20 1920 x 1080i @ 50 Hz ", + 20, 1125, 540, 20, 5, + 0, "+", 2640, 1920, 528, 44, 10, 74250000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "11 CEA 21-22 576i (PAL) ", + 21, 625, 288, 44, 5, + 0, "-", 1728, 1440, 12, 64, 10, 27000000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "12 CEA 29/30 576p ", + 29, 625, 576, 44, 5, + 0, "-", 864, 720, 12, 64, 10, 27000000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "13 CEA 31 1080p 50Hz ", + 31, 1125, 1080, 44, 5, + 0, "-", 2640, 1920, 12, 64, 10, 148500000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "14 CEA 32 1920x1080p @ 24 Hz ", + 32, 1125, 1080, 36, 5, + 4, "+", 2750, 1920, 660, 44, 153, 74250000, + "+", 2844, 0x530, 6, 32, 1},/*RGB565*/ +{ "15 CEA 33 1920x1080p @ 25 Hz ", + 33, 1125, 1080, 36, 5, + 4, "+", 2640, 1920, 528, 44, 10, 74250000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "16 CEA 34 1920x1080p @ 30Hz ", + 34, 1125, 1080, 36, 5, + 4, "+", 2200, 1920, 91, 44, 153, 74250000, + "+", 2275, 0xAB, 6, 32, 1},/*RGB565*/ +{ "17 CEA 60 1280x720p @ 24 Hz ", + 60, 750, 720, 20, 5, + 5, "+", 3300, 1280, 284, 50, 2276, 59400000, + "+", 4266, 0xAD0, 5, 32, 1},/*RGB565*/ +{ "18 CEA 61 1280x720p @ 25 Hz ", + 61, 750, 720, 20, 5, + 5, "+", 3960, 1280, 228, 39, 2503, 74250000, + "+", 4096, 0x500, 5, 32, 1},/*RGB565*/ +{ "19 CEA 62 1280x720p @ 30 Hz ", + 62, 750, 720, 20, 5, + 5, "+", 3300, 1280, 228, 39, 1820, 74250000, + "+", 3413, 0x770, 5, 32, 1},/*RGB565*/ +{ "20 VESA 9 800x600 @ 60 Hz ", + 109, 628, 600, 28, 4, + 0, "+", 1056, 800, 40, 128, 10, 20782080, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "21 VESA 14 848x480 @ 60 Hz ", + 114, 500, 480, 20, 5, + 0, "+", 1056, 848, 24, 80, 10, 31680000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "22 VESA 16 1024x768 @ 60 Hz ", + 116, 806, 768, 38, 6, + 0, "-", 1344, 1024, 24, 135, 10, 65000000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "23 VESA 22 1280x768 @ 60 Hz ", + 122, 802, 768, 34, 4, + 0, "+", 1688, 1280, 48, 160, 10, 81250000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "24 VESA 23 1280x768 @ 60 Hz ", + 123, 798, 768, 30, 7, + 0, "+", 1664, 1280, 64, 128, 10, 79500000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "25 VESA 27 1280x800 @ 60 Hz ", + 127, 823, 800, 23, 6, + 0, "+", 1440, 1280, 48, 32, 10, 71000000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "26 VESA 28 1280x800 @ 60 Hz ", + 128, 831, 800, 31, 6, + 0, "+", 1680, 1280, 72, 128, 10, 83500000, + "-", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "27 VESA 39 1360x768 @ 60 Hz ", + 139, 790, 768, 22, 5, + 0, "-", 1520, 1360, 48, 32, 10, 72000000, + "+", 0, 0, 0, 0, 0},/*Settings to be define*/ +{ "28 VESA 81 1360x768 @ 60 Hz ", + 181, 798, 768, 30, 5, + 0, "+", 1776, 1360, 72, 136, 10, 84750000, + "-", 0, 0, 0, 0, 0} /*Settings to be define*/ +}; + +const struct color_conversion_cmd col_trans_identity = { + .c0 = 0x0100, .c1 = 0x0000, .c2 = 0x0000, + .c3 = 0x0000, .c4 = 0x0100, .c5 = 0x0000, + .c6 = 0x0000, .c7 = 0x0000, .c8 = 0x0100, + .aoffset = 0x0000, .boffset = 0x0000, .coffset = 0x0000, + .lmax = 0xff, + .lmin = 0x00, + .cmax = 0xff, + .cmin = 0x00, +}; + +const struct color_conversion_cmd col_trans_identity_clamp_yuv = { + .c0 = 0x0100, .c1 = 0x0000, .c2 = 0x0000, + .c3 = 0x0000, .c4 = 0x0100, .c5 = 0x0000, + .c6 = 0x0000, .c7 = 0x0000, .c8 = 0x0100, + .aoffset = 0x0000, .boffset = 0x0000, .coffset = 0x0000, + .lmax = 0xeb, + .lmin = 0x10, + .cmax = 0xf0, + .cmin = 0x10, +}; + +const struct color_conversion_cmd col_trans_yuv_to_rgb_v1 = { + .c0 = 0x0087, .c1 = 0x0000, .c2 = 0x00ba, + .c3 = 0x0087, .c4 = 0xffd3, .c5 = 0xffa1, + .c6 = 0x0087, .c7 = 0x00eb, .c8 = 0x0000, + .aoffset = 0xffab, .boffset = 0x004e, .coffset = 0xff92, + .lmax = 0xff, + .lmin = 0x00, + .cmax = 0xff, + .cmin = 0x00, +}; + +const struct color_conversion_cmd col_trans_yuv_to_rgb_v2 = { + .c0 = 0x0204, .c1 = 0x012a, .c2 = 0x0000, + .c3 = 0xff9c, .c4 = 0x012a, .c5 = 0xff30, + .c6 = 0x0000, .c7 = 0x012a, .c8 = 0x0198, + .aoffset = 0xfeeb, .boffset = 0x0088, .coffset = 0xff21, + .lmax = 0xff, + .lmin = 0x00, + .cmax = 0xff, + .cmin = 0x00, +}; + +const struct color_conversion_cmd col_trans_yuv_to_denc = { + .c0 = 0x0100, .c1 = 0x0000, .c2 = 0x0000, + .c3 = 0x0000, .c4 = 0x0100, .c5 = 0x0000, + .c6 = 0x0000, .c7 = 0x0000, .c8 = 0x0100, + .aoffset = 0x0000, .boffset = 0x0000, .coffset = 0x0000, + .lmax = 0xeb, + .lmin = 0x10, + .cmax = 0xf0, + .cmin = 0x10, +}; + +const struct color_conversion_cmd col_trans_rgb_to_denc = { + .c0 = 0x0070, .c1 = 0xffb6, .c2 = 0xffda, + .c3 = 0x0019, .c4 = 0x0081, .c5 = 0x0042, + .c6 = 0xffee, .c7 = 0xffa2, .c8 = 0x0070, + .aoffset = 0x007f, .boffset = 0x0010, .coffset = 0x007f, + .lmax = 0xff, + .lmin = 0x00, + .cmax = 0xff, + .cmin = 0x00, +}; + +static const struct i2c_device_id av8100_id[] = { + { "av8100", 0 }, + { } +}; + +static struct i2c_driver av8100_driver = { + .probe = av8100_probe, + .remove = av8100_remove, + .driver = { + .name = "av8100", + }, + .id_table = av8100_id, +}; + +static void av8100_plugtimer_int(unsigned long value) +{ + av8100_flag |= AV8100_PLUGSTARTUP_EVENT; + wake_up_interruptible(&av8100_event); + del_timer(&av8100_plugtimer); +} + +static int av8100_int_event_handle(void) +{ + u8 hpdi = 0; + u8 cpdi = 0; + u8 hdcpi = 0; + u8 ceci = 0; + u8 hpds = 0; + u8 cpds = 0; + u8 hdcps = 0; + u8 cectxerr = 0; + u8 cecrx = 0; + u8 cectx = 0; + + if (!av8100_globals) + return -EINVAL; + + /* STANDBY_PENDING_INTERRUPT reg */ + if (av8100_reg_stby_pend_int_r(&hpdi, &cpdi, NULL, NULL)) { + dev_dbg(av8100dev, "av8100_reg_stby_pend_int_r failed\n"); + goto av8100_int_event_handle_1; + } + + /* Plug event */ + if (hpdi | cpdi) { + /* Clear pending interrupts */ + (void)av8100_reg_stby_pend_int_w(1, 1, 1); + + /* STANDBY reg */ + if (av8100_reg_stby_r(NULL, NULL, &hpds, &cpds, NULL)) { + dev_dbg(av8100dev, "av8100_reg_stby_r failed\n"); + goto av8100_int_event_handle_1; + } + } + + if (cpdi & av8100_globals->cpdm) { + /* TVout plugin change */ + if (cpds) { + dev_dbg(av8100dev, "cpds 1\n"); + set_plug_status(AV8100_CVBS_PLUGIN); + } else { + dev_dbg(av8100dev, "cpds 0\n"); + clr_plug_status(AV8100_CVBS_PLUGIN); + } + } + + if (hpdi & av8100_globals->hpdm) { + /* HDMI plugin change */ + if (hpds) { + dev_dbg(av8100dev, "hpds 1\n"); + set_plug_status(AV8100_HDMI_PLUGIN); + } else { + dev_dbg(av8100dev, "hpds 0\n"); + clr_plug_status(AV8100_HDMI_PLUGIN); + } + } + +av8100_int_event_handle_1: + /* GENERAL_INTERRUPT reg */ + if (av8100_reg_gen_int_r(NULL, NULL, NULL, &ceci, + &hdcpi, NULL, NULL)) { + dev_dbg(av8100dev, "av8100_reg_stby_pend_int_r failed\n"); + return -EINVAL; + } + + /* CEC or HDCP event */ + if (ceci | hdcpi) { + /* Clear pending interrupts */ + av8100_reg_gen_int_w(1, 1, 1, 1, 1, 1); + + /* GENERAL_STATUS reg */ + if (av8100_reg_gen_status_r(&cectxerr, &cecrx, &cectx, NULL, + NULL, &hdcps) != 0) { + dev_dbg(av8100dev, "av8100_reg_gen_status_r fail\n"); + return -EINVAL; + } + } + + /* CEC received */ + if (ceci && cecrx) { + dev_dbg(av8100dev, "cecrx\n"); + /* Report CEC event */ + cec_rx(); + } + + /* CEC tx error */ + if (ceci && cectx && cectxerr) { + dev_dbg(av8100dev, "cectxerr\n"); + /* Report CEC tx error event */ + cec_txerr(); + } + + /* HDCP event */ + if (hdcpi) { + dev_dbg(av8100dev, "hdcpch:%0x\n", hdcps); + /* Report HDCP status change event */ + hdcp_changed(); + } + + return 0; +} + +static int av8100_plugstartup_event_handle(void) +{ + u8 hpds = 0; + u8 cpds = 0; + + if (!av8100_globals) + return -EINVAL; + + switch (av8100_globals->plug_state) { + case AV8100_UNPLUGGED: + case AV8100_PLUGGED: + default: + break; + + case AV8100_PLUGGED_STARTUP: + /* Unmask interrupt */ + av8100_globals->hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; + if (av8100_reg_stby_int_mask_w(av8100_globals->hpdm, + av8100_globals->cpdm, + AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, + AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW)) { + dev_dbg(av8100dev, + "av8100_reg_stby_int_mask_w fail\n"); + } + + /* Get actual plug status */ + if (av8100_reg_stby_r(NULL, NULL, &hpds, &cpds, NULL)) + dev_dbg(av8100dev, "av8100_reg_stby_r fail\n"); + + /* Set plugstate */ + if (hpds) { + av8100_globals->plug_state = AV8100_PLUGGED; + dev_dbg(av8100dev, "plug_state:2\n"); + } else { + av8100_globals->plug_state = AV8100_UNPLUGGED; + dev_dbg(av8100dev, "plug_state:0\n"); + } + break; + } + + return 0; +} + +static int av8100_thread(void *p) +{ + u8 flags; + + while (1) { + wait_event_interruptible(av8100_event, (av8100_flag != 0)); + flags = av8100_flag; + av8100_flag = 0; + + if (!av8100_globals || + g_av8100_status.av8100_state < AV8100_OPMODE_STANDBY) + continue; + + if (flags & AV8100_INT_EVENT) + (void)av8100_int_event_handle(); + + if (flags & AV8100_PLUGSTARTUP_EVENT) + (void)av8100_plugstartup_event_handle(); + } + + return 0; +} + +static irqreturn_t av8100_intr_handler(int irq, void *p) +{ + av8100_flag |= AV8100_INT_EVENT; + wake_up_interruptible(&av8100_event); + return IRQ_HANDLED; +} + +static u16 av8100_get_te_line_nb( + enum av8100_output_CEA_VESA output_video_format) +{ + u16 retval; + + switch (output_video_format) { + case AV8100_CEA1_640X480P_59_94HZ: + case AV8100_CEA2_3_720X480P_59_94HZ: + retval = AV8100_TE_LINE_NB_30; + break; + + case AV8100_CEA5_1920X1080I_60HZ: + case AV8100_CEA6_7_NTSC_60HZ: + case AV8100_CEA20_1920X1080I_50HZ: + case AV8100_CEA21_22_576I_PAL_50HZ: + retval = AV8100_TE_LINE_NB_18; + break; + + case AV8100_CEA4_1280X720P_60HZ: + retval = AV8100_TE_LINE_NB_21; + break; + + case AV8100_CEA17_18_720X576P_50HZ: + retval = AV8100_TE_LINE_NB_40; + break; + + case AV8100_CEA19_1280X720P_50HZ: + retval = AV8100_TE_LINE_NB_22; + break; + + case AV8100_CEA32_1920X1080P_24HZ: + case AV8100_CEA33_1920X1080P_25HZ: + case AV8100_CEA34_1920X1080P_30HZ: + retval = AV8100_TE_LINE_NB_38; + break; + + case AV8100_CEA60_1280X720P_24HZ: + case AV8100_CEA62_1280X720P_30HZ: + retval = AV8100_TE_LINE_NB_21; + break; + + case AV8100_CEA14_15_480p_60HZ: + case AV8100_VESA14_848X480P_60HZ: + case AV8100_CEA61_1280X720P_25HZ: + case AV8100_CEA16_1920X1080P_60HZ: + case AV8100_CEA31_1920x1080P_50Hz: + case AV8100_CEA29_30_576P_50HZ: + case AV8100_VESA9_800X600P_60_32HZ: + case AV8100_VESA16_1024X768P_60HZ: + case AV8100_VESA22_1280X768P_59_99HZ: + case AV8100_VESA23_1280X768P_59_87HZ: + case AV8100_VESA27_1280X800P_59_91HZ: + case AV8100_VESA28_1280X800P_59_81HZ: + case AV8100_VESA39_1360X768P_60_02HZ: + case AV8100_VESA81_1366X768P_59_79HZ: + default: + /* TODO */ + retval = AV8100_TE_LINE_NB_14; + break; + } + + return retval; +} + +static u16 av8100_get_ui_x4( + enum av8100_output_CEA_VESA output_video_format) +{ + return AV8100_UI_X4_DEFAULT; +} + +static int av8100_config_video_output_dep(enum av8100_output_CEA_VESA + output_format) +{ + int retval; + union av8100_configuration config; + + /* video input */ + config.video_input_format.dsi_input_mode = + AV8100_HDMI_DSI_COMMAND_MODE; + config.video_input_format.input_pixel_format = AV8100_INPUT_PIX_RGB565; + config.video_input_format.total_horizontal_pixel = + av8100_all_cea[output_format].htotale; + config.video_input_format.total_horizontal_active_pixel = + av8100_all_cea[output_format].hactive; + config.video_input_format.total_vertical_lines = + av8100_all_cea[output_format].vtotale; + config.video_input_format.total_vertical_active_lines = + av8100_all_cea[output_format].vactive; + + switch (output_format) { + case AV8100_CEA5_1920X1080I_60HZ: + case AV8100_CEA20_1920X1080I_50HZ: + case AV8100_CEA21_22_576I_PAL_50HZ: + case AV8100_CEA6_7_NTSC_60HZ: + config.video_input_format.video_mode = + AV8100_VIDEO_INTERLACE; + break; + + default: + config.video_input_format.video_mode = + AV8100_VIDEO_PROGRESSIVE; + break; + } + + config.video_input_format.nb_data_lane = + AV8100_DATA_LANES_USED_2; + config.video_input_format.nb_virtual_ch_command_mode = 0; + config.video_input_format.nb_virtual_ch_video_mode = 0; + config.video_input_format.ui_x4 = av8100_get_ui_x4(output_format); + config.video_input_format.TE_line_nb = av8100_get_te_line_nb( + output_format); + config.video_input_format.TE_config = AV8100_TE_OFF; + config.video_input_format.master_clock_freq = 0; + + retval = av8100_conf_prep( + AV8100_COMMAND_VIDEO_INPUT_FORMAT, &config); + if (retval) + return -EFAULT; + + /* DENC */ + switch (output_format) { + case AV8100_CEA21_22_576I_PAL_50HZ: + config.denc_format.cvbs_video_format = AV8100_CVBS_625; + config.denc_format.standard_selection = AV8100_PAL_BDGHI; + break; + + case AV8100_CEA6_7_NTSC_60HZ: + config.denc_format.cvbs_video_format = AV8100_CVBS_525; + config.denc_format.standard_selection = AV8100_NTSC_M; + break; + + default: + /* Not supported */ + break; + } + + return 0; +} + +static int av8100_config_init(void) +{ + int retval; + union av8100_configuration config; + + dev_dbg(av8100dev, "%s\n", __func__); + + av8100_config = kzalloc(sizeof(struct av8100_config_t), GFP_KERNEL); + if (!av8100_config) { + dev_err(av8100dev, "%s: Failed to allocate config\n", __func__); + return AV8100_FAIL; + } + + memset(&config, 0, sizeof(union av8100_configuration)); + memset(av8100_config, 0, sizeof(union av8100_configuration)); + + /* Color conversion */ + config.color_transform = AV8100_COLOR_TRANSFORM_INDENTITY; + retval = av8100_conf_prep( + AV8100_COMMAND_COLORSPACECONVERSION, &config); + if (retval) + return -EFAULT; + + /* DENC */ + config.denc_format.cvbs_video_format = AV8100_CVBS_625; + config.denc_format.standard_selection = AV8100_PAL_BDGHI; + config.denc_format.enable = 0; + config.denc_format.macrovision_enable = 0; + config.denc_format.internal_generator = 0; + + /* Video output */ + config.video_output_format.video_output_cea_vesa = + AV8100_CEA4_1280X720P_60HZ; + + retval = av8100_conf_prep( + AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, &config); + if (retval) + return -EFAULT; + + /* Video input */ + av8100_config_video_output_dep( + config.video_output_format.video_output_cea_vesa); + + /* Pattern generator */ + config.pattern_generator_format.pattern_audio_mode = + AV8100_PATTERN_AUDIO_OFF; + config.pattern_generator_format.pattern_type = + AV8100_PATTERN_GENERATOR; + config.pattern_generator_format.pattern_video_format = + AV8100_PATTERN_720P; + retval = av8100_conf_prep(AV8100_COMMAND_PATTERNGENERATOR, + &config); + if (retval) + return -EFAULT; + + /* Audio input */ + config.audio_input_format.audio_input_if_format = + AV8100_AUDIO_I2SDELAYED_MODE; + config.audio_input_format.i2s_input_nb = 1; + config.audio_input_format.sample_audio_freq = AV8100_AUDIO_FREQ_48KHZ; + config.audio_input_format.audio_word_lg = AV8100_AUDIO_16BITS; + config.audio_input_format.audio_format = AV8100_AUDIO_LPCM_MODE; + config.audio_input_format.audio_if_mode = AV8100_AUDIO_MASTER; + config.audio_input_format.audio_mute = AV8100_AUDIO_MUTE_DISABLE; + retval = av8100_conf_prep( + AV8100_COMMAND_AUDIO_INPUT_FORMAT, &config); + if (retval) + return -EFAULT; + + /* HDMI mode */ + config.hdmi_format.hdmi_mode = AV8100_HDMI_ON; + config.hdmi_format.hdmi_format = AV8100_HDMI; + config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0; + retval = av8100_conf_prep(AV8100_COMMAND_HDMI, &config); + if (retval) + return -EFAULT; + + /* EDID section readback */ + config.edid_section_readback_format.address = 0xA0; + config.edid_section_readback_format.block_number = 0; + retval = av8100_conf_prep( + AV8100_COMMAND_EDID_SECTION_READBACK, &config); + if (retval) + return -EFAULT; + + return 0; +} + +static void av8100_config_exit(void) +{ + dev_dbg(av8100dev, "%s\n", __func__); + + kfree(av8100_config); + av8100_config = NULL; +} + +static int av8100_globals_init(void) +{ + dev_dbg(av8100dev, "%s\n", __func__); + + av8100_globals = kzalloc(sizeof(struct av8100_globals_t), GFP_KERNEL); + if (!av8100_globals) { + dev_err(av8100dev, "%s: Alloc failure\n", __func__); + return AV8100_FAIL; + } + + av8100_globals->denc_off_time = AV8100_DENC_OFF_TIME; + av8100_globals->hdmi_off_time = AV8100_HDMI_OFF_TIME; + av8100_globals->on_time = AV8100_ON_TIME; + + av8100_globals->hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH; + av8100_globals->cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_HIGH; + av8100_globals->hdcpm = AV8100_GENERAL_INTERRUPT_MASK_HDCPM_HIGH; + av8100_globals->cecm = AV8100_GENERAL_INTERRUPT_MASK_CECM_HIGH; + + av8100_globals->plug_state = AV8100_UNPLUGGED; + av8100_globals->inputclk = NULL; + av8100_globals->inputclk_requested = false; + av8100_globals->opp_requested = false; + av8100_globals->regulator_requested = false; + + return 0; +} + +static void av8100_globals_exit(void) +{ + dev_dbg(av8100dev, "%s\n", __func__); + + kfree(av8100_globals); + av8100_globals = NULL; +} + +static void clr_plug_status(enum av8100_plugin_status status) +{ + g_av8100_status.av8100_plugin_status &= ~status; + + switch (status) { + case AV8100_HDMI_PLUGIN: + if (!av8100_globals) + return; + + switch (av8100_globals->plug_state) { + case AV8100_UNPLUGGED: + case AV8100_PLUGGED_STARTUP: + default: + break; + + case AV8100_PLUGGED: + av8100_globals->plug_state = + AV8100_UNPLUGGED; + dev_dbg(av8100dev, "plug_state:0\n"); + break; + } + + if (av8100_globals->hdmi_ev_cb) + av8100_globals->hdmi_ev_cb( + AV8100_HDMI_EVENT_HDMI_PLUGOUT); + break; + + case AV8100_CVBS_PLUGIN: + /* TODO */ + break; + + default: + break; + } +} + +static void set_plug_status(enum av8100_plugin_status status) +{ + g_av8100_status.av8100_plugin_status |= status; + + switch (status) { + case AV8100_HDMI_PLUGIN: + if (!av8100_globals) + return; + + switch (av8100_globals->plug_state) { + case AV8100_UNPLUGGED: + av8100_globals->plug_state = + AV8100_PLUGGED_STARTUP; + + dev_dbg(av8100dev, "plug_state:1\n"); + + /* + * Mask interrupts to avoid plug detect during + * startup + * */ + av8100_globals->hpdm = + AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW; + if (av8100_reg_stby_int_mask_w( + av8100_globals->hpdm, + av8100_globals->cpdm, + AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, + AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW)) { + dev_dbg(av8100dev, + "av8100_reg_stby_int_mask_w" + "fail\n"); + } + + /* Set plug startup timer */ + init_timer(&av8100_plugtimer); + av8100_plugtimer.expires = jiffies + + AV8100_PLUGSTARTUP_TIME; + av8100_plugtimer.function = + av8100_plugtimer_int; + av8100_plugtimer.data = 0; + add_timer(&av8100_plugtimer); + break; + + case AV8100_PLUGGED_STARTUP: + case AV8100_PLUGGED: + default: + break; + } + + if (av8100_globals->hdmi_ev_cb) + av8100_globals->hdmi_ev_cb( + AV8100_HDMI_EVENT_HDMI_PLUGIN); + break; + + case AV8100_CVBS_PLUGIN: + /* TODO */ + break; + + default: + break; + } +} + +static void cec_rx(void) +{ + if (av8100_globals && av8100_globals->hdmi_ev_cb) + av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_CEC); +} + +static void cec_txerr(void) +{ + if (av8100_globals && av8100_globals->hdmi_ev_cb) + av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_CECTXERR); +} + +static void hdcp_changed(void) +{ + if (av8100_globals && av8100_globals->hdmi_ev_cb) + av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_HDCP); +} + +static void av8100_set_state(enum av8100_operating_mode state) +{ + g_av8100_status.av8100_state = state; + + if (state == AV8100_OPMODE_UNDEFINED) + g_av8100_status.hdmi_on = false; + + if (state == AV8100_OPMODE_STANDBY) { + clr_plug_status(AV8100_HDMI_PLUGIN); + clr_plug_status(AV8100_CVBS_PLUGIN); + g_av8100_status.hdmi_on = false; + } +} + +/** + * write_single_byte() - Write a single byte to av8100 + * through i2c interface. + * @client: i2c client structure + * @reg: register offset + * @data: data byte to be written + * + * This funtion uses smbus byte write API to write a single byte to av8100 + **/ +static int write_single_byte(struct i2c_client *client, u8 reg, + u8 data) +{ + int ret; + + ret = i2c_smbus_write_byte_data(client, reg, data); + if (ret < 0) + dev_dbg(av8100dev, "i2c smbus write byte failed\n"); + + return ret; +} + +/** + * read_single_byte() - read single byte from av8100 + * through i2c interface + * @client: i2c client structure + * @reg: register offset + * @val: register value + * + * This funtion uses smbus read block API to read single byte from the reg + * offset. + **/ +static int read_single_byte(struct i2c_client *client, u8 reg, u8 *val) +{ + int value; + + value = i2c_smbus_read_byte_data(client, reg); + if (value < 0) { + dev_dbg(av8100dev, "i2c smbus read byte failed,read data = %x " + "from offset:%x\n" , value, reg); + return AV8100_FAIL; + } + + *val = (u8) value; + return 0; +} + +/** + * write_multi_byte() - Write a multiple bytes to av8100 through + * i2c interface. + * @client: i2c client structure + * @buf: buffer to be written + * @nbytes: nunmber of bytes to be written + * + * This funtion uses smbus block write API's to write n number of bytes to the + * av8100 + **/ +static int write_multi_byte(struct i2c_client *client, u8 reg, + u8 *buf, u8 nbytes) +{ + int ret; + + ret = i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf); + if (ret < 0) + dev_dbg(av8100dev, "i2c smbus write multi byte error\n"); + + return ret; +} + +static int configuration_video_input_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_video_input_cmd.dsi_input_mode; + buffer[1] = av8100_config->hdmi_video_input_cmd.input_pixel_format; + buffer[2] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + total_horizontal_pixel); + buffer[3] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + total_horizontal_pixel); + buffer[4] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + total_horizontal_active_pixel); + buffer[5] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + total_horizontal_active_pixel); + buffer[6] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + total_vertical_lines); + buffer[7] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + total_vertical_lines); + buffer[8] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + total_vertical_active_lines); + buffer[9] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + total_vertical_active_lines); + buffer[10] = av8100_config->hdmi_video_input_cmd.video_mode; + buffer[11] = av8100_config->hdmi_video_input_cmd.nb_data_lane; + buffer[12] = av8100_config->hdmi_video_input_cmd. + nb_virtual_ch_command_mode; + buffer[13] = av8100_config->hdmi_video_input_cmd. + nb_virtual_ch_video_mode; + buffer[14] = REG_16_8_MSB(av8100_config->hdmi_video_input_cmd. + TE_line_nb); + buffer[15] = REG_16_8_LSB(av8100_config->hdmi_video_input_cmd. + TE_line_nb); + buffer[16] = av8100_config->hdmi_video_input_cmd.TE_config; + buffer[17] = REG_32_8_MSB(av8100_config->hdmi_video_input_cmd. + master_clock_freq); + buffer[18] = REG_32_8_MMSB(av8100_config->hdmi_video_input_cmd. + master_clock_freq); + buffer[19] = REG_32_8_MLSB(av8100_config->hdmi_video_input_cmd. + master_clock_freq); + buffer[20] = REG_32_8_LSB(av8100_config->hdmi_video_input_cmd. + master_clock_freq); + buffer[21] = av8100_config->hdmi_video_input_cmd.ui_x4; + + *length = AV8100_COMMAND_VIDEO_INPUT_FORMAT_SIZE - 1; + return 0; + +} + +static int configuration_audio_input_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_audio_input_cmd. + audio_input_if_format; + buffer[1] = av8100_config->hdmi_audio_input_cmd.i2s_input_nb; + buffer[2] = av8100_config->hdmi_audio_input_cmd.sample_audio_freq; + buffer[3] = av8100_config->hdmi_audio_input_cmd.audio_word_lg; + buffer[4] = av8100_config->hdmi_audio_input_cmd.audio_format; + buffer[5] = av8100_config->hdmi_audio_input_cmd.audio_if_mode; + buffer[6] = av8100_config->hdmi_audio_input_cmd.audio_mute; + + *length = AV8100_COMMAND_AUDIO_INPUT_FORMAT_SIZE - 1; + return 0; +} + +static int configuration_video_output_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_video_output_cmd. + video_output_cea_vesa; + + if (buffer[0] == AV8100_CUSTOM) { + buffer[1] = av8100_config->hdmi_video_output_cmd. + vsync_polarity; + buffer[2] = av8100_config->hdmi_video_output_cmd. + hsync_polarity; + buffer[3] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.total_horizontal_pixel); + buffer[4] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.total_horizontal_pixel); + buffer[5] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.total_horizontal_active_pixel); + buffer[6] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.total_horizontal_active_pixel); + buffer[7] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.total_vertical_in_half_lines); + buffer[8] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.total_vertical_in_half_lines); + buffer[9] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd. + total_vertical_active_in_half_lines); + buffer[10] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd. + total_vertical_active_in_half_lines); + buffer[11] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.hsync_start_in_pixel); + buffer[12] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.hsync_start_in_pixel); + buffer[13] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.hsync_length_in_pixel); + buffer[14] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.hsync_length_in_pixel); + buffer[15] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.vsync_start_in_half_line); + buffer[16] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.vsync_start_in_half_line); + buffer[17] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.vsync_length_in_half_line); + buffer[18] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.vsync_length_in_half_line); + buffer[19] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.hor_video_start_pixel); + buffer[20] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.hor_video_start_pixel); + buffer[21] = REG_16_8_MSB(av8100_config-> + hdmi_video_output_cmd.vert_video_start_pixel); + buffer[22] = REG_16_8_LSB(av8100_config-> + hdmi_video_output_cmd.vert_video_start_pixel); + buffer[23] = av8100_config-> + hdmi_video_output_cmd.video_type; + buffer[24] = av8100_config-> + hdmi_video_output_cmd.pixel_repeat; + buffer[25] = REG_32_8_MSB(av8100_config-> + hdmi_video_output_cmd.pixel_clock_freq_Hz); + buffer[26] = REG_32_8_MMSB(av8100_config-> + hdmi_video_output_cmd.pixel_clock_freq_Hz); + buffer[27] = REG_32_8_MLSB(av8100_config-> + hdmi_video_output_cmd.pixel_clock_freq_Hz); + buffer[28] = REG_32_8_LSB(av8100_config-> + hdmi_video_output_cmd.pixel_clock_freq_Hz); + + *length = AV8100_COMMAND_VIDEO_OUTPUT_FORMAT_SIZE - 1; + } else { + *length = 1; + } + + return 0; +} + +static int configuration_video_scaling_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + h_start_in_pixel); + buffer[1] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + h_start_in_pixel); + buffer[2] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + h_stop_in_pixel); + buffer[3] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + h_stop_in_pixel); + buffer[4] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + v_start_in_line); + buffer[5] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + v_start_in_line); + buffer[6] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + v_stop_in_line); + buffer[7] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + v_stop_in_line); + buffer[8] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + h_start_out_pixel); + buffer[9] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd + .h_start_out_pixel); + buffer[10] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + h_stop_out_pixel); + buffer[11] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + h_stop_out_pixel); + buffer[12] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + v_start_out_line); + buffer[13] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + v_start_out_line); + buffer[14] = REG_16_8_MSB(av8100_config->hdmi_video_scaling_cmd. + v_stop_out_line); + buffer[15] = REG_16_8_LSB(av8100_config->hdmi_video_scaling_cmd. + v_stop_out_line); + + *length = AV8100_COMMAND_VIDEO_SCALING_FORMAT_SIZE - 1; + return 0; +} + +static int configuration_colorspace_conversion_get(char *buffer, + unsigned int *length) +{ + const struct color_conversion_cmd *hdmi_color_space_conversion_cmd; + if (!av8100_config) + return AV8100_FAIL; + + hdmi_color_space_conversion_cmd = + get_color_transform_cmd(av8100_config->color_transform); + + buffer[0] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c0); + buffer[1] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c0); + buffer[2] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c1); + buffer[3] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c1); + buffer[4] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c2); + buffer[5] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c2); + buffer[6] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c3); + buffer[7] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c3); + buffer[8] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c4); + buffer[9] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c4); + buffer[10] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c5); + buffer[11] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c5); + buffer[12] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c6); + buffer[13] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c6); + buffer[14] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c7); + buffer[15] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c7); + buffer[16] = REG_12_8_MSB(hdmi_color_space_conversion_cmd->c8); + buffer[17] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->c8); + buffer[18] = REG_10_8_MSB(hdmi_color_space_conversion_cmd->aoffset); + buffer[19] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->aoffset); + buffer[20] = REG_10_8_MSB(hdmi_color_space_conversion_cmd->boffset); + buffer[21] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->boffset); + buffer[22] = REG_10_8_MSB(hdmi_color_space_conversion_cmd->coffset); + buffer[23] = REG_16_8_LSB(hdmi_color_space_conversion_cmd->coffset); + buffer[24] = hdmi_color_space_conversion_cmd->lmax; + buffer[25] = hdmi_color_space_conversion_cmd->lmin; + buffer[26] = hdmi_color_space_conversion_cmd->cmax; + buffer[27] = hdmi_color_space_conversion_cmd->cmin; + + *length = AV8100_COMMAND_COLORSPACECONVERSION_SIZE - 1; + return 0; +} + +static int configuration_cec_message_write_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_cec_message_write_cmd.buffer_length; + memcpy(&buffer[1], av8100_config->hdmi_cec_message_write_cmd.buffer, + HDMI_CEC_MESSAGE_WRITE_BUFFER_SIZE); + + *length = AV8100_COMMAND_CEC_MESSAGE_WRITE_SIZE - 1; + return 0; +} + +static int configuration_cec_message_read_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + /* No buffer data */ + *length = AV8100_COMMAND_CEC_MESSAGE_READ_BACK_SIZE - 1; + return 0; +} + +static int configuration_denc_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_denc_cmd.cvbs_video_format; + buffer[1] = av8100_config->hdmi_denc_cmd.standard_selection; + buffer[2] = av8100_config->hdmi_denc_cmd.enable; + buffer[3] = av8100_config->hdmi_denc_cmd.macrovision_enable; + buffer[4] = av8100_config->hdmi_denc_cmd.internal_generator; + + *length = AV8100_COMMAND_DENC_SIZE - 1; + return 0; +} + +static int configuration_hdmi_get(char *buffer, unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_cmd.hdmi_mode; + buffer[1] = av8100_config->hdmi_cmd.hdmi_format; + buffer[2] = av8100_config->hdmi_cmd.dvi_format; + + *length = AV8100_COMMAND_HDMI_SIZE - 1; + return 0; +} + +static int configuration_hdcp_sendkey_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_hdcp_send_key_cmd.key_number; + memcpy(&buffer[1], av8100_config->hdmi_hdcp_send_key_cmd.data, + av8100_config->hdmi_hdcp_send_key_cmd.data_len); + + *length = av8100_config->hdmi_hdcp_send_key_cmd.data_len + 1; + return 0; +} + +static int configuration_hdcp_management_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_hdcp_management_format_cmd.req_type; + buffer[1] = av8100_config->hdmi_hdcp_management_format_cmd.req_encr; + buffer[2] = av8100_config->hdmi_hdcp_management_format_cmd.encr_use; + + *length = AV8100_COMMAND_HDCP_MANAGEMENT_SIZE - 1; + return 0; +} + +static int configuration_infoframe_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_infoframes_cmd.type; + buffer[1] = av8100_config->hdmi_infoframes_cmd.version; + buffer[2] = av8100_config->hdmi_infoframes_cmd.length; + buffer[3] = av8100_config->hdmi_infoframes_cmd.crc; + memcpy(&buffer[4], av8100_config->hdmi_infoframes_cmd.data, + HDMI_INFOFRAME_DATA_SIZE); + + *length = AV8100_COMMAND_INFOFRAMES_SIZE - 1; + return 0; +} + +static int av8100_edid_section_readback_get(char *buffer, unsigned int *length) +{ + buffer[0] = av8100_config->hdmi_edid_section_readback_cmd.address; + buffer[1] = av8100_config->hdmi_edid_section_readback_cmd. + block_number; + + *length = AV8100_COMMAND_EDID_SECTION_READBACK_SIZE - 1; + return 0; +} + +static int configuration_pattern_generator_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_pattern_generator_cmd.pattern_type; + buffer[1] = av8100_config->hdmi_pattern_generator_cmd. + pattern_video_format; + buffer[2] = av8100_config->hdmi_pattern_generator_cmd. + pattern_audio_mode; + + *length = AV8100_COMMAND_PATTERNGENERATOR_SIZE - 1; + return 0; +} + +static int configuration_fuse_aes_key_get(char *buffer, + unsigned int *length) +{ + if (!av8100_config) + return AV8100_FAIL; + + buffer[0] = av8100_config->hdmi_fuse_aes_key_cmd.fuse_operation; + if (av8100_config->hdmi_fuse_aes_key_cmd.fuse_operation) { + /* Write key command */ + memcpy(&buffer[1], av8100_config->hdmi_fuse_aes_key_cmd.key, + HDMI_FUSE_AES_KEY_SIZE); + + *length = AV8100_COMMAND_FUSE_AES_KEY_SIZE - 1; + } else { + /* Check key command */ + *length = AV8100_COMMAND_FUSE_AES_CHK_SIZE - 1; + } + return 0; +} + +static int get_command_return_first(struct i2c_client *i2c, + enum av8100_command_type command_type) { + int retval = 0; + char val; + + retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET, &val); + if (retval) { + dev_dbg(av8100dev, "%s 1st ret failed\n", __func__); + return retval; + } + + if (val != (0x80 | command_type)) { + dev_dbg(av8100dev, "%s 1st ret wrong:%x\n", __func__, val); + return -EFAULT; + } + + return 0; +} + +static int get_command_return_data(struct i2c_client *i2c, + enum av8100_command_type command_type, + u8 *command_buffer, + u8 *buffer_length, + u8 *buffer) +{ + int retval = 0; + char val; + int index = 0; + + if (buffer_length) + *buffer_length = 0; + + switch (command_type) { + case AV8100_COMMAND_VIDEO_INPUT_FORMAT: + case AV8100_COMMAND_AUDIO_INPUT_FORMAT: + case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: + case AV8100_COMMAND_VIDEO_SCALING_FORMAT: + case AV8100_COMMAND_COLORSPACECONVERSION: + case AV8100_COMMAND_CEC_MESSAGE_WRITE: + case AV8100_COMMAND_DENC: + case AV8100_COMMAND_HDMI: + case AV8100_COMMAND_INFOFRAMES: + case AV8100_COMMAND_PATTERNGENERATOR: + /* Get the second return byte */ + retval = read_single_byte(i2c, + AV8100_2ND_RET_BYTE_OFFSET, &val); + if (retval) + goto get_command_return_data_fail2r; + + if (val) { + retval = AV8100_FAIL; + goto get_command_return_data_fail2v; + } + break; + + case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: + if ((buffer == NULL) || (buffer_length == NULL)) { + retval = AV8100_FAIL; + goto get_command_return_data_fail; + } + + /* Get the return buffer length */ + retval = read_single_byte(i2c, AV8100_CEC_ADDR_OFFSET, &val); + if (retval) + goto get_command_return_data_fail; + + /* TODO: buffer_length is always zero */ + /* *buffer_length = val;*/ + dev_dbg(av8100dev, "cec buflen:%d\n", val); + *buffer_length = val; + + if (*buffer_length > + HDMI_CEC_READ_MAXSIZE) { + dev_dbg(av8100dev, "CEC size too large %d\n", + *buffer_length); + *buffer_length = HDMI_CEC_READ_MAXSIZE; + } + + dev_dbg(av8100dev, "return data: "); + + /* Get the return buffer */ + for (index = 0; index < *buffer_length; ++index) { + retval = read_single_byte(i2c, + AV8100_CEC_RET_BUF_OFFSET + index, &val); + if (retval) { + *buffer_length = 0; + goto get_command_return_data_fail; + } else { + *(buffer + index) = val; + dev_dbg(av8100dev, "%02x ", *(buffer + index)); + } + } + + dev_dbg(av8100dev, "\n"); + break; + + case AV8100_COMMAND_HDCP_MANAGEMENT: + /* Get the second return byte */ + retval = read_single_byte(i2c, + AV8100_2ND_RET_BYTE_OFFSET, &val); + if (retval) { + goto get_command_return_data_fail2r; + } else { + /* Check the second return byte */ + if (val) + goto get_command_return_data_fail2v; + } + + if ((buffer == NULL) || (buffer_length == NULL)) + /* Ignore return data */ + break; + + /* Get the return buffer length */ + if (command_buffer[0] == + HDMI_REQUEST_FOR_REVOCATION_LIST_INPUT) { + *buffer_length = HDMI_REVOC_LIST_SIZE; + } else { + *buffer_length = 0x0; + } + + dev_dbg(av8100dev, "return data: "); + + /* Get the return buffer */ + for (index = 0; index < *buffer_length; ++index) { + retval = read_single_byte(i2c, + AV8100_HDCP_RET_BUF_OFFSET + index, &val); + if (retval) { + *buffer_length = 0; + goto get_command_return_data_fail; + } else { + *(buffer + index) = val; + dev_dbg(av8100dev, "%02x ", *(buffer + index)); + } + } + + dev_dbg(av8100dev, "\n"); + break; + + case AV8100_COMMAND_EDID_SECTION_READBACK: + if ((buffer == NULL) || (buffer_length == NULL)) { + retval = AV8100_FAIL; + goto get_command_return_data_fail; + } + + /* Return buffer length is fixed */ + *buffer_length = HDMI_EDIDREAD_SIZE; + + dev_dbg(av8100dev, "return data: "); + + /* Get the return buffer */ + for (index = 0; index < *buffer_length; ++index) { + retval = read_single_byte(i2c, + AV8100_EDID_RET_BUF_OFFSET + index, &val); + if (retval) { + *buffer_length = 0; + goto get_command_return_data_fail; + } else { + *(buffer + index) = val; + dev_dbg(av8100dev, "%02x ", *(buffer + index)); + } + } + + dev_dbg(av8100dev, "\n"); + break; + + case AV8100_COMMAND_FUSE_AES_KEY: + if ((buffer == NULL) || (buffer_length == NULL)) { + retval = AV8100_FAIL; + goto get_command_return_data_fail; + } + + /* Get the second return byte */ + retval = read_single_byte(i2c, + AV8100_2ND_RET_BYTE_OFFSET, &val); + + if (retval) + goto get_command_return_data_fail2r; + + /* Check the second return byte */ + if (val) { + retval = AV8100_FAIL; + goto get_command_return_data_fail2v; + } + + /* Return buffer length is fixed */ + *buffer_length = HDMI_FUSE_AES_KEY_RET_SIZE; + + /* Get CRC */ + retval = read_single_byte(i2c, + AV8100_FUSE_CRC_OFFSET, &val); + if (retval) + goto get_command_return_data_fail; + + *buffer = val; + dev_dbg(av8100dev, "CRC:%02x ", val); + + /* Get programmed status */ + retval = read_single_byte(i2c, + AV8100_FUSE_PRGD_OFFSET, &val); + if (retval) + goto get_command_return_data_fail; + + *(buffer + 1) = val; + + dev_dbg(av8100dev, "programmed:%02x ", val); + break; + + case AV8100_COMMAND_HDCP_SENDKEY: + if ((command_buffer[0] == HDMI_LOADAES_END_BLK_NR) && + ((buffer == NULL) || (buffer_length == NULL))) { + retval = AV8100_FAIL; + goto get_command_return_data_fail; + } + + /* Get the second return byte */ + retval = read_single_byte(i2c, + AV8100_2ND_RET_BYTE_OFFSET, &val); + if (retval) + goto get_command_return_data_fail2r; + + if (val) { + retval = AV8100_FAIL; + goto get_command_return_data_fail2v; + } + + if (command_buffer[0] == HDMI_LOADAES_END_BLK_NR) { + /* Return CRC32 if last AES block */ + int cnt; + + dev_dbg(av8100dev, "CRC32:"); + for (cnt = 0; cnt < HDMI_CRC32_SIZE; cnt++) { + if (read_single_byte(i2c, + AV8100_CRC32_OFFSET + cnt, &val)) + goto get_command_return_data_fail; + *(buffer + cnt) = val; + dev_dbg(av8100dev, "%02x", val); + } + + *buffer_length = HDMI_CRC32_SIZE; + } + break; + + default: + retval = AV8100_INVALID_COMMAND; + break; + } + + return retval; +get_command_return_data_fail2r: + dev_dbg(av8100dev, "%s Reading 2nd return byte failed\n", __func__); + return retval; +get_command_return_data_fail2v: + dev_dbg(av8100dev, "%s 2nd return byte is wrong:%x\n", __func__, val); + return retval; +get_command_return_data_fail: + dev_dbg(av8100dev, "%s FAIL\n", __func__); + return retval; +} + +static int av8100_powerup1(void) +{ + int retval; + struct av8100_platform_data *pdata = av8100dev->platform_data; + + /* Regulator enable */ + if ((av8100_globals->regulator_pwr) && + (av8100_globals->regulator_requested == false)) { + retval = regulator_enable(av8100_globals->regulator_pwr); + if (retval < 0) { + dev_warn(av8100dev, "%s: regulator_enable failed\n", + __func__); + return retval; + } + dev_dbg(av8100dev, "regulator_enable ok\n"); + av8100_globals->regulator_requested = true; + } + + /* Reset av8100 */ + gpio_set_value(pdata->reset, 1); + + /* Need to wait before proceeding */ + mdelay(AV8100_POWERON_WAITTIME1_MS); + + av8100_set_state(AV8100_OPMODE_STANDBY); + + /* Get chip version */ + retval = av8100_reg_stby_pend_int_r(NULL, NULL, NULL, &chip_version); + if (retval) { + dev_err(av8100dev, "Failed to read chip version\n"); + return -EFAULT; + } + + dev_info(av8100dev, "chip version:%d\n", chip_version); + + switch (chip_version) { + case AV8100_CHIPVER_1: + case AV8100_CHIPVER_2: + break; + + default: + dev_err(av8100dev, "Unsupported chip version:%d\n", + chip_version); + return -EFAULT; + break; + } + + return 0; +} + +static int av8100_powerup2(void) +{ + int retval; + + /* Master clock timing, running, search for plug */ + retval = av8100_reg_stby_w(AV8100_STANDBY_CPD_HIGH, + AV8100_STANDBY_STBY_HIGH, MCLK_FREQ); + if (retval) { + dev_err(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + /* ON time & OFF time on 5v HDMI plug detect */ + retval = av8100_reg_hdmi_5_volt_time_w( + av8100_globals->denc_off_time, + av8100_globals->hdmi_off_time, + av8100_globals->on_time); + if (retval) { + dev_err(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + /* Need to wait before proceeding */ + mdelay(AV8100_POWERON_WAITTIME2_MS); + + av8100_set_state(AV8100_OPMODE_SCAN); + + return 0; +} + +int av8100_powerup(void) +{ + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (av8100_powerup1()) { + dev_err(av8100dev, "av8100_powerup1 fail\n"); + return -EFAULT; + } + + return av8100_powerup2(); +} +EXPORT_SYMBOL(av8100_powerup); + +int av8100_powerdown(void) +{ + struct av8100_platform_data *pdata = av8100dev->platform_data; + + if (gpio_get_value(pdata->reset) == 0) + return 0; + + /* Remove APE OPP requirement */ + if (av8100_globals->opp_requested) { + prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, + (char *)av8100_miscdev.name); + av8100_globals->opp_requested = false; + } + + /* Clock disable */ + if (av8100_globals->inputclk && av8100_globals->inputclk_requested) { + clk_disable(av8100_globals->inputclk); + av8100_globals->inputclk_requested = false; + } + + /* Regulator disable */ + if ((av8100_globals->regulator_pwr) && + (av8100_globals->regulator_requested)) { + dev_dbg(av8100dev, "regulator_disable\n"); + regulator_disable(av8100_globals->regulator_pwr); + av8100_globals->regulator_requested = false; + } + + gpio_set_value(pdata->reset, 0); + av8100_set_state(AV8100_OPMODE_SHUTDOWN); + + return 0; +} +EXPORT_SYMBOL(av8100_powerdown); + +int av8100_download_firmware(char *fw_buff, int nbytes, + enum interface_type if_type) +{ + int retval; + int temp = 0x0; + int increment = 15; + int index = 0; + int size = 0x0; + int tempnext = 0x0; + char val = 0x0; + char CheckSum = 0; + int cnt = 10; + struct i2c_client *i2c; + u8 uc; + u8 fdl; + u8 hld; + u8 wa; + u8 ra; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (!av8100_config) + return -EINVAL; + + /* Clock enable */ + if (av8100_globals->inputclk && + av8100_globals->inputclk_requested == false) { + if (clk_enable(av8100_globals->inputclk)) { + dev_err(av8100dev, "inputclk en failed\n"); + return -EFAULT; + } + + av8100_globals->inputclk_requested = true; + } + + /* Request 100% APE OPP */ + if (av8100_globals->opp_requested == false) { + if (prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, + (char *)av8100_miscdev.name, 100)) { + dev_err(av8100dev, "OPP 100 failed\n"); + return -EFAULT; + } + + av8100_globals->opp_requested = true; + } + + msleep(AV8100_FWDL_WAITTIME1); + + fw_buff = av8100_fw_buff; + nbytes = AV8100_FW_SIZE; + + i2c = av8100_config->client; + + /* Enable firmware download */ + retval = av8100_reg_gen_ctrl_w( + AV8100_GENERAL_CONTROL_FDL_HIGH, + AV8100_GENERAL_CONTROL_HLD_HIGH, + AV8100_GENERAL_CONTROL_WA_LOW, + AV8100_GENERAL_CONTROL_RA_LOW); + if (retval) { + dev_err(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + retval = av8100_reg_gen_ctrl_r(&fdl, &hld, &wa, &ra); + if (retval) { + dev_err(av8100dev, + "Failed to read the value from av8100 register\n"); + return -EFAULT; + } else { + dev_dbg(av8100dev, "GENERAL_CONTROL_REG register fdl:%d " + "hld:%d wa:%d ra:%d\n", fdl, hld, wa, ra); + } + + LOCK_AV8100_HW; + + temp = nbytes % increment; + for (size = 0; size < (nbytes-temp); size = size + increment, + index += increment) { + if (if_type == I2C_INTERFACE) { + retval = write_multi_byte(i2c, + AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, + increment); + if (retval) { + dev_dbg(av8100dev, "Failed to download the " + "av8100 firmware\n"); + UNLOCK_AV8100_HW; + return -EFAULT; + } + } else if (if_type == DSI_INTERFACE) { + dev_dbg(av8100dev, + "DSI_INTERFACE is currently not supported\n"); + UNLOCK_AV8100_HW; + return -EINVAL; + } else { + UNLOCK_AV8100_HW; + return -EINVAL; + } + + for (tempnext = size; tempnext < (increment+size); tempnext++) + av8100_receivetab[tempnext] = fw_buff[tempnext]; + } + + /* Transfer last firmware bytes */ + if (if_type == I2C_INTERFACE) { + retval = write_multi_byte(i2c, + AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, temp); + if (retval) { + dev_dbg(av8100dev, + "Failed to download the av8100 firmware\n"); + UNLOCK_AV8100_HW; + return -EFAULT; + } + } else if (if_type == DSI_INTERFACE) { + /* TODO: Add support for DSI firmware download */ + UNLOCK_AV8100_HW; + return -EINVAL; + } else { + UNLOCK_AV8100_HW; + return -EINVAL; + } + + for (tempnext = size; tempnext < (size+temp); tempnext++) + av8100_receivetab[tempnext] = fw_buff[tempnext]; + + /* check transfer*/ + for (size = 0; size < nbytes; size++) { + CheckSum = CheckSum ^ fw_buff[size]; + if (av8100_receivetab[size] != fw_buff[size]) { + dev_dbg(av8100dev, ">Fw download fail....i=%d\n", size); + dev_dbg(av8100dev, "Transm = %x, Receiv = %x\n", + fw_buff[size], av8100_receivetab[size]); + } + } + + UNLOCK_AV8100_HW; + + retval = av8100_reg_fw_dl_entry_r(&val); + if (retval) { + dev_dbg(av8100dev, + "Failed to read the value from the av8100 register\n"); + return -EFAULT; + } + + dev_dbg(av8100dev, "CheckSum:%x,val:%x\n", CheckSum, val); + + if (CheckSum != val) { + dev_dbg(av8100dev, + ">Fw downloading.... FAIL CheckSum issue\n"); + dev_dbg(av8100dev, "Checksum = %d\n", CheckSum); + dev_dbg(av8100dev, "Checksum read: %d\n", val); + return -EFAULT; + } else { + dev_dbg(av8100dev, ">Fw downloading.... success\n"); + } + + /* Set to idle mode */ + av8100_reg_gen_ctrl_w(AV8100_GENERAL_CONTROL_FDL_LOW, + AV8100_GENERAL_CONTROL_HLD_LOW, AV8100_GENERAL_CONTROL_WA_LOW, + AV8100_GENERAL_CONTROL_RA_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to the av8100 register\n"); + return -EFAULT; + } + + /* Wait Internal Micro controler ready */ + cnt = AV8100_FWDL_TRIES; + retval = av8100_reg_gen_status_r(NULL, NULL, NULL, &uc, + NULL, NULL); + while ((retval == 0) && (uc != 0x1) && (cnt-- > 0)) { + mdelay(AV8100_FWDL_WAITTIME2); + retval = av8100_reg_gen_status_r(NULL, NULL, NULL, + &uc, NULL, NULL); + } + dev_dbg(av8100dev, "av8100 fwdl cnt:%d\n", cnt); + + if (retval) { + dev_dbg(av8100dev, + "Failed to read the value from the av8100 register\n"); + return -EFAULT; + } + + if (uc != 0x1) + dev_dbg(av8100dev, "UC is not ready\n"); + + av8100_set_state(AV8100_OPMODE_IDLE); + + return 0; +} +EXPORT_SYMBOL(av8100_download_firmware); + +int av8100_disable_interrupt(void) +{ + int retval; + struct i2c_client *i2c; + u8 hpdm = 0; + u8 cpdm = 0; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (!av8100_config) + return -EINVAL; + + i2c = av8100_config->client; + + retval = av8100_reg_stby_pend_int_w( + AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW, + AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW, + AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + retval = av8100_reg_gen_int_mask_w( + AV8100_GENERAL_INTERRUPT_MASK_EOCM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_VSIM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_VSOM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_CECM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_HDCPM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + if (av8100_globals) { + hpdm = av8100_globals->hpdm; + cpdm = av8100_globals->cpdm; + } + + retval = av8100_reg_stby_int_mask_w( + AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW, + AV8100_STANDBY_INTERRUPT_MASK_CPDM_LOW, + AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, + AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + if (av8100_globals) { + av8100_globals->hpdm = hpdm; + av8100_globals->cpdm = cpdm; + } + + return 0; +} +EXPORT_SYMBOL(av8100_disable_interrupt); + +int av8100_enable_interrupt(void) +{ + int retval; + struct i2c_client *i2c; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (!av8100_globals || !av8100_config) + return -EINVAL; + + i2c = av8100_config->client; + + retval = av8100_reg_stby_pend_int_w( + AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW, + AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW, + AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + retval = av8100_reg_gen_int_mask_w( + AV8100_GENERAL_INTERRUPT_MASK_EOCM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_VSIM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_VSOM_LOW, + av8100_globals->cecm, + av8100_globals->hdcpm, + AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW, + AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + retval = av8100_reg_stby_int_mask_w( + av8100_globals->hpdm, + av8100_globals->cpdm, + AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT, + AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + return 0; +} +EXPORT_SYMBOL(av8100_enable_interrupt); + +static int register_write_internal(u8 offset, u8 value) +{ + int retval; + struct i2c_client *i2c; + + if (!av8100_config) + return -EINVAL; + + i2c = av8100_config->client; + + /* Write to register */ + retval = write_single_byte(i2c, offset, value); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + return -EFAULT; + } + + return 0; +} +EXPORT_SYMBOL(register_write_internal); + +int av8100_reg_stby_w( + u8 cpd, u8 stby, u8 mclkrng) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_STANDBY_CPD(cpd) | AV8100_STANDBY_STBY(stby) | + AV8100_STANDBY_MCLKRNG(mclkrng); + + /* Write to register */ + retval = register_write_internal(AV8100_STANDBY, val); + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_stby_w); + +int av8100_reg_hdmi_5_volt_time_w(u8 denc_off, u8 hdmi_off, u8 on) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value. + * chip_version == 1 have one common off time + * chip_version > 1 support different off time for hdmi and tvout. */ + if (chip_version == 1) + val = AV8100_HDMI_5_VOLT_TIME_OFF_TIME(hdmi_off) | + AV8100_HDMI_5_VOLT_TIME_ON_TIME(on); + else + val = AV8100_HDMI_5_VOLT_TIME_DAC_OFF_TIME(denc_off) | + AV8100_HDMI_5_VOLT_TIME_SU_OFF_TIME(hdmi_off) | + AV8100_HDMI_5_VOLT_TIME_ON_TIME(on); + + /* Write to register */ + retval = register_write_internal(AV8100_HDMI_5_VOLT_TIME, val); + + /* Set vars */ + if (chip_version > 1) + av8100_globals->denc_off_time = denc_off; + + av8100_globals->hdmi_off_time = hdmi_off; + av8100_globals->on_time = on; + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_hdmi_5_volt_time_w); + +int av8100_reg_stby_int_mask_w( + u8 hpdm, u8 cpdm, u8 stbygpiocfg, u8 ipol) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_STANDBY_INTERRUPT_MASK_HPDM(hpdm) | + AV8100_STANDBY_INTERRUPT_MASK_CPDM(cpdm) | + AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG(stbygpiocfg) | + AV8100_STANDBY_INTERRUPT_MASK_IPOL(ipol); + + /* Write to register */ + retval = register_write_internal(AV8100_STANDBY_INTERRUPT_MASK, val); + + av8100_globals->hpdm = hpdm; + av8100_globals->cpdm = cpdm; + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_stby_int_mask_w); + +int av8100_reg_stby_pend_int_w( + u8 hpdi, u8 cpdi, u8 oni) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_STANDBY_PENDING_INTERRUPT_HPDI(hpdi) | + AV8100_STANDBY_PENDING_INTERRUPT_CPDI(cpdi) | + AV8100_STANDBY_PENDING_INTERRUPT_ONI(oni); + + /* Write to register */ + retval = register_write_internal(AV8100_STANDBY_PENDING_INTERRUPT, val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_stby_pend_int_w); + +int av8100_reg_gen_int_mask_w( + u8 eocm, u8 vsim, u8 vsom, u8 cecm, u8 hdcpm, u8 uovbm, u8 tem) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_GENERAL_INTERRUPT_MASK_EOCM(eocm) | + AV8100_GENERAL_INTERRUPT_MASK_VSIM(vsim) | + AV8100_GENERAL_INTERRUPT_MASK_VSOM(vsom) | + AV8100_GENERAL_INTERRUPT_MASK_CECM(cecm) | + AV8100_GENERAL_INTERRUPT_MASK_HDCPM(hdcpm) | + AV8100_GENERAL_INTERRUPT_MASK_UOVBM(uovbm) | + AV8100_GENERAL_INTERRUPT_MASK_TEM(tem); + + /* Write to register */ + retval = register_write_internal(AV8100_GENERAL_INTERRUPT_MASK, val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_int_mask_w); + +int av8100_reg_gen_int_w( + u8 eoci, u8 vsii, u8 vsoi, u8 ceci, u8 hdcpi, u8 uovbi) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_GENERAL_INTERRUPT_EOCI(eoci) | + AV8100_GENERAL_INTERRUPT_VSII(vsii) | + AV8100_GENERAL_INTERRUPT_VSOI(vsoi) | + AV8100_GENERAL_INTERRUPT_CECI(ceci) | + AV8100_GENERAL_INTERRUPT_HDCPI(hdcpi) | + AV8100_GENERAL_INTERRUPT_UOVBI(uovbi); + + /* Write to register */ + retval = register_write_internal(AV8100_GENERAL_INTERRUPT, val); + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_int_w); + +int av8100_reg_gpio_conf_w( + u8 dat3dir, u8 dat3val, u8 dat2dir, u8 dat2val, u8 dat1dir, + u8 dat1val, u8 ucdbg) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_GPIO_CONFIGURATION_DAT3DIR(dat3dir) | + AV8100_GPIO_CONFIGURATION_DAT3VAL(dat3val) | + AV8100_GPIO_CONFIGURATION_DAT2DIR(dat2dir) | + AV8100_GPIO_CONFIGURATION_DAT2VAL(dat2val) | + AV8100_GPIO_CONFIGURATION_DAT1DIR(dat1dir) | + AV8100_GPIO_CONFIGURATION_DAT1VAL(dat1val) | + AV8100_GPIO_CONFIGURATION_UCDBG(ucdbg); + + /* Write to register */ + retval = register_write_internal(AV8100_GPIO_CONFIGURATION, val); + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gpio_conf_w); + +int av8100_reg_gen_ctrl_w( + u8 fdl, u8 hld, u8 wa, u8 ra) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_GENERAL_CONTROL_FDL(fdl) | + AV8100_GENERAL_CONTROL_HLD(hld) | + AV8100_GENERAL_CONTROL_WA(wa) | + AV8100_GENERAL_CONTROL_RA(ra); + + /* Write to register */ + retval = register_write_internal(AV8100_GENERAL_CONTROL, val); + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_ctrl_w); + +int av8100_reg_fw_dl_entry_w( + u8 mbyte_code_entry) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Set register value */ + val = AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY( + mbyte_code_entry); + + /* Write to register */ + retval = register_write_internal(AV8100_FIRMWARE_DOWNLOAD_ENTRY, val); + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_fw_dl_entry_w); + +int av8100_reg_w( + u8 offset, u8 value) +{ + int retval = 0; + struct i2c_client *i2c; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + if (!av8100_config) { + UNLOCK_AV8100_HW; + return -EINVAL; + } + + i2c = av8100_config->client; + + /* Write to register */ + retval = write_single_byte(i2c, offset, value); + if (retval) { + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); + UNLOCK_AV8100_HW; + return -EFAULT; + } + + UNLOCK_AV8100_HW; + return 0; +} +EXPORT_SYMBOL(av8100_reg_w); + +int register_read_internal(u8 offset, u8 *value) +{ + int retval = 0; + struct i2c_client *i2c; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (!av8100_config) + return -EINVAL; + + i2c = av8100_config->client; + + /* Read from register */ + retval = read_single_byte(i2c, offset, value); + if (retval) { + dev_dbg(av8100dev, + "Failed to read the value from av8100 register\n"); + return -EFAULT; + } + + return retval; +} +EXPORT_SYMBOL(register_read_internal); + +int av8100_reg_stby_r( + u8 *cpd, u8 *stby, u8 *hpds, u8 *cpds, u8 *mclkrng) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_STANDBY, &val); + + /* Set return params */ + if (cpd) + *cpd = AV8100_STANDBY_CPD_GET(val); + if (stby) + *stby = AV8100_STANDBY_STBY_GET(val); + if (hpds) + *hpds = AV8100_STANDBY_HPDS_GET(val); + if (cpds) + *cpds = AV8100_STANDBY_CPDS_GET(val); + if (mclkrng) + *mclkrng = AV8100_STANDBY_MCLKRNG_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_stby_r); + +int av8100_reg_hdmi_5_volt_time_r( + u8 *denc_off_time, u8 *hdmi_off_time, u8 *on_time) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_HDMI_5_VOLT_TIME, &val); + + /* Set return params */ + if (chip_version == 1) { + if (denc_off_time) + *denc_off_time = 0; + if (hdmi_off_time) + *hdmi_off_time = + AV8100_HDMI_5_VOLT_TIME_OFF_TIME_GET(val); + } else { + if (denc_off_time) + *denc_off_time = + AV8100_HDMI_5_VOLT_TIME_DAC_OFF_TIME_GET(val); + if (hdmi_off_time) + *hdmi_off_time = + AV8100_HDMI_5_VOLT_TIME_SU_OFF_TIME_GET(val); + } + + if (on_time) + *on_time = AV8100_HDMI_5_VOLT_TIME_ON_TIME_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_hdmi_5_volt_time_r); + +int av8100_reg_stby_int_mask_r( + u8 *hpdm, u8 *cpdm, u8 *stbygpiocfg, u8 *ipol) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_STANDBY_INTERRUPT_MASK, &val); + + /* Set return params */ + if (hpdm) + *hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_GET(val); + if (cpdm) + *cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_GET(val); + if (stbygpiocfg) + *stbygpiocfg = + AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_GET(val); + if (ipol) + *ipol = AV8100_STANDBY_INTERRUPT_MASK_IPOL_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_stby_int_mask_r); + +int av8100_reg_stby_pend_int_r( + u8 *hpdi, u8 *cpdi, u8 *oni, u8 *sid) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_STANDBY_PENDING_INTERRUPT, + &val); + + /* Set return params */ + if (hpdi) + *hpdi = AV8100_STANDBY_PENDING_INTERRUPT_HPDI_GET(val); + if (cpdi) + *cpdi = AV8100_STANDBY_PENDING_INTERRUPT_CPDI_GET(val); + if (oni) + *oni = AV8100_STANDBY_PENDING_INTERRUPT_ONI_GET(val); + if (sid) + *sid = AV8100_STANDBY_PENDING_INTERRUPT_SID_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_stby_pend_int_r); + +int av8100_reg_gen_int_mask_r( + u8 *eocm, + u8 *vsim, + u8 *vsom, + u8 *cecm, + u8 *hdcpm, + u8 *uovbm, + u8 *tem) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_GENERAL_INTERRUPT_MASK, &val); + + /* Set return params */ + if (eocm) + *eocm = AV8100_GENERAL_INTERRUPT_MASK_EOCM_GET(val); + if (vsim) + *vsim = AV8100_GENERAL_INTERRUPT_MASK_VSIM_GET(val); + if (vsom) + *vsom = AV8100_GENERAL_INTERRUPT_MASK_VSOM_GET(val); + if (cecm) + *cecm = AV8100_GENERAL_INTERRUPT_MASK_CECM_GET(val); + if (hdcpm) + *hdcpm = AV8100_GENERAL_INTERRUPT_MASK_HDCPM_GET(val); + if (uovbm) + *uovbm = AV8100_GENERAL_INTERRUPT_MASK_UOVBM_GET(val); + if (tem) + *tem = AV8100_GENERAL_INTERRUPT_MASK_TEM_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_int_mask_r); + +int av8100_reg_gen_int_r( + u8 *eoci, + u8 *vsii, + u8 *vsoi, + u8 *ceci, + u8 *hdcpi, + u8 *uovbi, + u8 *tei) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_GENERAL_INTERRUPT, &val); + + /* Set return params */ + if (eoci) + *eoci = AV8100_GENERAL_INTERRUPT_EOCI_GET(val); + if (vsii) + *vsii = AV8100_GENERAL_INTERRUPT_VSII_GET(val); + if (vsoi) + *vsoi = AV8100_GENERAL_INTERRUPT_VSOI_GET(val); + if (ceci) + *ceci = AV8100_GENERAL_INTERRUPT_CECI_GET(val); + if (hdcpi) + *hdcpi = AV8100_GENERAL_INTERRUPT_HDCPI_GET(val); + if (uovbi) + *uovbi = AV8100_GENERAL_INTERRUPT_UOVBI_GET(val); + if (tei) + *tei = AV8100_GENERAL_INTERRUPT_TEI_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_int_r); + +int av8100_reg_gen_status_r( + u8 *cectxerr, + u8 *cecrec, + u8 *cectrx, + u8 *uc, + u8 *onuvb, + u8 *hdcps) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_GENERAL_STATUS, &val); + + /* Set return params */ + if (cectxerr) + *cectxerr = AV8100_GENERAL_STATUS_CECTXERR_GET(val); + if (cecrec) + *cecrec = AV8100_GENERAL_STATUS_CECREC_GET(val); + if (cectrx) + *cectrx = AV8100_GENERAL_STATUS_CECTRX_GET(val); + if (uc) + *uc = AV8100_GENERAL_STATUS_UC_GET(val); + if (onuvb) + *onuvb = AV8100_GENERAL_STATUS_ONUVB_GET(val); + if (hdcps) + *hdcps = AV8100_GENERAL_STATUS_HDCPS_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_status_r); + +int av8100_reg_gpio_conf_r( + u8 *dat3dir, + u8 *dat3val, + u8 *dat2dir, + u8 *dat2val, + u8 *dat1dir, + u8 *dat1val, + u8 *ucdbg) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_GPIO_CONFIGURATION, &val); + + /* Set return params */ + if (dat3dir) + *dat3dir = AV8100_GPIO_CONFIGURATION_DAT3DIR_GET(val); + if (dat3val) + *dat3val = AV8100_GPIO_CONFIGURATION_DAT3VAL_GET(val); + if (dat2dir) + *dat2dir = AV8100_GPIO_CONFIGURATION_DAT2DIR_GET(val); + if (dat2val) + *dat2val = AV8100_GPIO_CONFIGURATION_DAT2VAL_GET(val); + if (dat1dir) + *dat1dir = AV8100_GPIO_CONFIGURATION_DAT1DIR_GET(val); + if (dat1val) + *dat1val = AV8100_GPIO_CONFIGURATION_DAT1VAL_GET(val); + if (ucdbg) + *ucdbg = AV8100_GPIO_CONFIGURATION_UCDBG_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gpio_conf_r); + +int av8100_reg_gen_ctrl_r( + u8 *fdl, + u8 *hld, + u8 *wa, + u8 *ra) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_GENERAL_CONTROL, &val); + /* Set return params */ + if (fdl) + *fdl = AV8100_GENERAL_CONTROL_FDL_GET(val); + if (hld) + *hld = AV8100_GENERAL_CONTROL_HLD_GET(val); + if (wa) + *wa = AV8100_GENERAL_CONTROL_WA_GET(val); + if (ra) + *ra = AV8100_GENERAL_CONTROL_RA_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_gen_ctrl_r); + +int av8100_reg_fw_dl_entry_r( + u8 *mbyte_code_entry) +{ + int retval; + u8 val; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + /* Read from register */ + retval = register_read_internal(AV8100_FIRMWARE_DOWNLOAD_ENTRY, &val); + + /* Set return params */ + if (mbyte_code_entry) + *mbyte_code_entry = + AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY_GET(val); + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_fw_dl_entry_r); + +int av8100_reg_r( + u8 offset, + u8 *value) +{ + int retval = 0; + struct i2c_client *i2c; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + if (!av8100_config) { + retval = AV8100_FAIL; + goto av8100_register_read_out; + } + + i2c = av8100_config->client; + + /* Read from register */ + retval = read_single_byte(i2c, offset, value); + if (retval) { + dev_dbg(av8100dev, + "Failed to read the value from av8100 register\n"); + retval = -EFAULT; + goto av8100_register_read_out; + } + +av8100_register_read_out: + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_reg_r); + +int av8100_conf_get(enum av8100_command_type command_type, + union av8100_configuration *config) +{ + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (!av8100_config || !config) + return AV8100_FAIL; + + /* Put configuration data to the corresponding data struct depending + * on command type */ + switch (command_type) { + case AV8100_COMMAND_VIDEO_INPUT_FORMAT: + memcpy(&config->video_input_format, + &av8100_config->hdmi_video_input_cmd, + sizeof(struct av8100_video_input_format_cmd)); + break; + + case AV8100_COMMAND_AUDIO_INPUT_FORMAT: + memcpy(&config->audio_input_format, + &av8100_config->hdmi_audio_input_cmd, + sizeof(struct av8100_audio_input_format_cmd)); + break; + + case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: + memcpy(&config->video_output_format, + &av8100_config->hdmi_video_output_cmd, + sizeof(struct av8100_video_output_format_cmd)); + break; + + case AV8100_COMMAND_VIDEO_SCALING_FORMAT: + memcpy(&config->video_scaling_format, + &av8100_config->hdmi_video_scaling_cmd, + sizeof(struct av8100_video_scaling_format_cmd)); + break; + + case AV8100_COMMAND_COLORSPACECONVERSION: + config->color_transform = av8100_config->color_transform; + break; + + case AV8100_COMMAND_CEC_MESSAGE_WRITE: + memcpy(&config->cec_message_write_format, + &av8100_config->hdmi_cec_message_write_cmd, + sizeof(struct av8100_cec_message_write_format_cmd)); + break; + + case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: + memcpy(&config->cec_message_read_back_format, + &av8100_config->hdmi_cec_message_read_back_cmd, + sizeof(struct av8100_cec_message_read_back_format_cmd)); + break; + + case AV8100_COMMAND_DENC: + memcpy(&config->denc_format, &av8100_config->hdmi_denc_cmd, + sizeof(struct av8100_denc_format_cmd)); + break; + + case AV8100_COMMAND_HDMI: + memcpy(&config->hdmi_format, &av8100_config->hdmi_cmd, + sizeof(struct av8100_hdmi_cmd)); + break; + + case AV8100_COMMAND_HDCP_SENDKEY: + memcpy(&config->hdcp_send_key_format, + &av8100_config->hdmi_hdcp_send_key_cmd, + sizeof(struct av8100_hdcp_send_key_format_cmd)); + break; + + case AV8100_COMMAND_HDCP_MANAGEMENT: + memcpy(&config->hdcp_management_format, + &av8100_config->hdmi_hdcp_management_format_cmd, + sizeof(struct av8100_hdcp_management_format_cmd)); + break; + + case AV8100_COMMAND_INFOFRAMES: + memcpy(&config->infoframes_format, + &av8100_config->hdmi_infoframes_cmd, + sizeof(struct av8100_infoframes_format_cmd)); + break; + + case AV8100_COMMAND_EDID_SECTION_READBACK: + memcpy(&config->edid_section_readback_format, + &av8100_config->hdmi_edid_section_readback_cmd, + sizeof(struct + av8100_edid_section_readback_format_cmd)); + break; + + case AV8100_COMMAND_PATTERNGENERATOR: + memcpy(&config->pattern_generator_format, + &av8100_config->hdmi_pattern_generator_cmd, + sizeof(struct av8100_pattern_generator_format_cmd)); + break; + + case AV8100_COMMAND_FUSE_AES_KEY: + memcpy(&config->fuse_aes_key_format, + &av8100_config->hdmi_fuse_aes_key_cmd, + sizeof(struct av8100_fuse_aes_key_format_cmd)); + break; + + default: + return AV8100_FAIL; + break; + } + + return 0; +} +EXPORT_SYMBOL(av8100_conf_get); + +int av8100_conf_prep(enum av8100_command_type command_type, + union av8100_configuration *config) +{ + if (!av8100_config || !config) + return AV8100_FAIL; + + /* Put configuration data to the corresponding data struct depending + * on command type */ + switch (command_type) { + case AV8100_COMMAND_VIDEO_INPUT_FORMAT: + memcpy(&av8100_config->hdmi_video_input_cmd, + &config->video_input_format, + sizeof(struct av8100_video_input_format_cmd)); + break; + + case AV8100_COMMAND_AUDIO_INPUT_FORMAT: + memcpy(&av8100_config->hdmi_audio_input_cmd, + &config->audio_input_format, + sizeof(struct av8100_audio_input_format_cmd)); + break; + + case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: + memcpy(&av8100_config->hdmi_video_output_cmd, + &config->video_output_format, + sizeof(struct av8100_video_output_format_cmd)); + + /* Set params that depend on video output */ + av8100_config_video_output_dep(av8100_config-> + hdmi_video_output_cmd.video_output_cea_vesa); + break; + + case AV8100_COMMAND_VIDEO_SCALING_FORMAT: + memcpy(&av8100_config->hdmi_video_scaling_cmd, + &config->video_scaling_format, + sizeof(struct av8100_video_scaling_format_cmd)); + break; + + case AV8100_COMMAND_COLORSPACECONVERSION: + av8100_config->color_transform = config->color_transform; + break; + + case AV8100_COMMAND_CEC_MESSAGE_WRITE: + memcpy(&av8100_config->hdmi_cec_message_write_cmd, + &config->cec_message_write_format, + sizeof(struct av8100_cec_message_write_format_cmd)); + break; + + case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: + memcpy(&av8100_config->hdmi_cec_message_read_back_cmd, + &config->cec_message_read_back_format, + sizeof(struct av8100_cec_message_read_back_format_cmd)); + break; + + case AV8100_COMMAND_DENC: + memcpy(&av8100_config->hdmi_denc_cmd, &config->denc_format, + sizeof(struct av8100_denc_format_cmd)); + break; + + case AV8100_COMMAND_HDMI: + memcpy(&av8100_config->hdmi_cmd, &config->hdmi_format, + sizeof(struct av8100_hdmi_cmd)); + break; + + case AV8100_COMMAND_HDCP_SENDKEY: + memcpy(&av8100_config->hdmi_hdcp_send_key_cmd, + &config->hdcp_send_key_format, + sizeof(struct av8100_hdcp_send_key_format_cmd)); + break; + + case AV8100_COMMAND_HDCP_MANAGEMENT: + memcpy(&av8100_config->hdmi_hdcp_management_format_cmd, + &config->hdcp_management_format, + sizeof(struct av8100_hdcp_management_format_cmd)); + break; + + case AV8100_COMMAND_INFOFRAMES: + memcpy(&av8100_config->hdmi_infoframes_cmd, + &config->infoframes_format, + sizeof(struct av8100_infoframes_format_cmd)); + break; + + case AV8100_COMMAND_EDID_SECTION_READBACK: + memcpy(&av8100_config->hdmi_edid_section_readback_cmd, + &config->edid_section_readback_format, + sizeof(struct + av8100_edid_section_readback_format_cmd)); + break; + + case AV8100_COMMAND_PATTERNGENERATOR: + memcpy(&av8100_config->hdmi_pattern_generator_cmd, + &config->pattern_generator_format, + sizeof(struct av8100_pattern_generator_format_cmd)); + break; + + case AV8100_COMMAND_FUSE_AES_KEY: + memcpy(&av8100_config->hdmi_fuse_aes_key_cmd, + &config->fuse_aes_key_format, + sizeof(struct av8100_fuse_aes_key_format_cmd)); + break; + + default: + return AV8100_FAIL; + break; + } + + return 0; +} +EXPORT_SYMBOL(av8100_conf_prep); + +int av8100_conf_w(enum av8100_command_type command_type, + u8 *return_buffer_length, + u8 *return_buffer, enum interface_type if_type) +{ + int retval = 0; + u8 cmd_buffer[AV8100_COMMAND_MAX_LENGTH]; + u32 cmd_length = 0; + struct i2c_client *i2c; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + if (return_buffer_length) + *return_buffer_length = 0; + + if (!av8100_config) + return AV8100_FAIL; + + i2c = av8100_config->client; + + memset(&cmd_buffer, 0x00, AV8100_COMMAND_MAX_LENGTH); + +#define PRNK_MODE(_m) dev_dbg(av8100dev, "cmd: " #_m "\n"); + + /* Fill the command buffer with configuration data */ + switch (command_type) { + case AV8100_COMMAND_VIDEO_INPUT_FORMAT: + PRNK_MODE(AV8100_COMMAND_VIDEO_INPUT_FORMAT); + configuration_video_input_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_AUDIO_INPUT_FORMAT: + PRNK_MODE(AV8100_COMMAND_AUDIO_INPUT_FORMAT); + configuration_audio_input_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_VIDEO_OUTPUT_FORMAT: + PRNK_MODE(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT); + configuration_video_output_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_VIDEO_SCALING_FORMAT: + PRNK_MODE(AV8100_COMMAND_VIDEO_SCALING_FORMAT); + configuration_video_scaling_get(cmd_buffer, + &cmd_length); + break; + + case AV8100_COMMAND_COLORSPACECONVERSION: + PRNK_MODE(AV8100_COMMAND_COLORSPACECONVERSION); + configuration_colorspace_conversion_get(cmd_buffer, + &cmd_length); + break; + + case AV8100_COMMAND_CEC_MESSAGE_WRITE: + PRNK_MODE(AV8100_COMMAND_CEC_MESSAGE_WRITE); + configuration_cec_message_write_get(cmd_buffer, + &cmd_length); + break; + + case AV8100_COMMAND_CEC_MESSAGE_READ_BACK: + PRNK_MODE(AV8100_COMMAND_CEC_MESSAGE_READ_BACK); + configuration_cec_message_read_get(cmd_buffer, + &cmd_length); + break; + + case AV8100_COMMAND_DENC: + PRNK_MODE(AV8100_COMMAND_DENC); + configuration_denc_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_HDMI: + PRNK_MODE(AV8100_COMMAND_HDMI); + configuration_hdmi_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_HDCP_SENDKEY: + PRNK_MODE(AV8100_COMMAND_HDCP_SENDKEY); + configuration_hdcp_sendkey_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_HDCP_MANAGEMENT: + PRNK_MODE(AV8100_COMMAND_HDCP_MANAGEMENT); + configuration_hdcp_management_get(cmd_buffer, + &cmd_length); + break; + + case AV8100_COMMAND_INFOFRAMES: + PRNK_MODE(AV8100_COMMAND_INFOFRAMES); + configuration_infoframe_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_EDID_SECTION_READBACK: + PRNK_MODE(AV8100_COMMAND_EDID_SECTION_READBACK); + av8100_edid_section_readback_get(cmd_buffer, &cmd_length); + break; + + case AV8100_COMMAND_PATTERNGENERATOR: + PRNK_MODE(AV8100_COMMAND_PATTERNGENERATOR); + configuration_pattern_generator_get(cmd_buffer, + &cmd_length); + break; + + case AV8100_COMMAND_FUSE_AES_KEY: + PRNK_MODE(AV8100_COMMAND_FUSE_AES_KEY); + configuration_fuse_aes_key_get(cmd_buffer, &cmd_length); + break; + + default: + dev_dbg(av8100dev, "Invalid command type\n"); + retval = AV8100_INVALID_COMMAND; + break; + } + + LOCK_AV8100_HW; + + if (if_type == I2C_INTERFACE) { + int cnt = 0; + dev_dbg(av8100dev, "av8100_conf_w cmd_type:%02x length:%02x ", + command_type, cmd_length); + dev_dbg(av8100dev, "buffer: "); + while (cnt < cmd_length) { + dev_dbg(av8100dev, "%02x ", cmd_buffer[cnt]); + cnt++; + } + + /* Write the command buffer */ + retval = write_multi_byte(i2c, + AV8100_CMD_BUF_OFFSET, cmd_buffer, cmd_length); + if (retval) { + UNLOCK_AV8100_HW; + return retval; + } + + /* Write the command */ + retval = write_single_byte(i2c, AV8100_COMMAND_OFFSET, + command_type); + if (retval) { + UNLOCK_AV8100_HW; + return retval; + } + + + /* Get the first return byte */ + mdelay(AV8100_CMD_RET_WAITTIME_MS); + cnt = AV8100_CMD_RET_TRIES; + retval = get_command_return_first(i2c, command_type); + while (retval && (cnt-- > 0)) { + mdelay(AV8100_CMD_RET_WAITTIME_MS); + retval = get_command_return_first(i2c, command_type); + } + dev_dbg(av8100dev, "first return cnt:%d\n", cnt); + + if (retval) { + UNLOCK_AV8100_HW; + return retval; + } + + retval = get_command_return_data(i2c, command_type, cmd_buffer, + return_buffer_length, return_buffer); + } else if (if_type == DSI_INTERFACE) { + /* TODO */ + } else { + retval = AV8100_INVALID_INTERFACE; + dev_dbg(av8100dev, "Invalid command type\n"); + } + + if (command_type == AV8100_COMMAND_HDMI) { + g_av8100_status.hdmi_on = ((av8100_config->hdmi_cmd. + hdmi_mode == AV8100_HDMI_ON) && + (av8100_config->hdmi_cmd.hdmi_format == AV8100_HDMI)); + } + + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_conf_w); + +int av8100_conf_w_raw(enum av8100_command_type command_type, + u8 buffer_length, + u8 *buffer, + u8 *return_buffer_length, + u8 *return_buffer) +{ + int retval = 0; + struct i2c_client *i2c; + int cnt; + + if (av8100_status_get().av8100_state == AV8100_OPMODE_UNDEFINED) + return -EINVAL; + + LOCK_AV8100_HW; + + if (return_buffer_length) + *return_buffer_length = 0; + + if (!av8100_config) { + retval = AV8100_FAIL; + goto av8100_conf_w_raw_out; + } + + i2c = av8100_config->client; + + /* Write the command buffer */ + retval = write_multi_byte(i2c, + AV8100_CMD_BUF_OFFSET, buffer, buffer_length); + if (retval) + goto av8100_conf_w_raw_out; + + /* Write the command */ + retval = write_single_byte(i2c, AV8100_COMMAND_OFFSET, + command_type); + if (retval) + goto av8100_conf_w_raw_out; + + + /* Get the first return byte */ + mdelay(AV8100_CMD_RET_WAITTIME_MS); + cnt = AV8100_CMD_RET_TRIES; + retval = get_command_return_first(i2c, command_type); + while (retval && (cnt-- > 0)) { + mdelay(AV8100_CMD_RET_WAITTIME_MS); + retval = get_command_return_first(i2c, command_type); + } + dev_dbg(av8100dev, "first return cnt:%d\n", cnt); + if (retval) + goto av8100_conf_w_raw_out; + + retval = get_command_return_data(i2c, command_type, buffer, + return_buffer_length, return_buffer); + +av8100_conf_w_raw_out: + UNLOCK_AV8100_HW; + return retval; +} +EXPORT_SYMBOL(av8100_conf_w_raw); + +struct av8100_status av8100_status_get(void) +{ + return g_av8100_status; +} +EXPORT_SYMBOL(av8100_status_get); + +enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres, + int yres, + int htot, + int vtot, + int pixelclk, + bool interlaced) +{ + enum av8100_output_CEA_VESA index = 1; + int yres_div = !interlaced ? 1 : 2; + int hres_div = 1; + long freq1; + long freq2; + + /* + * 720_576_I need a divider for hact and htot since + * these params need to be twice as large as expected in av8100_all_cea, + * which is used as input parameter to video input config. + */ + if ((xres == 720) && (yres == 576) && (interlaced == true)) + hres_div = 2; + + freq1 = 1000000 / htot * 1000000 / vtot / pixelclk + 1; + while (index < sizeof(av8100_all_cea)/sizeof(struct av8100_cea)) { + freq2 = av8100_all_cea[index].frequence / + av8100_all_cea[index].htotale / + av8100_all_cea[index].vtotale; + + dev_dbg(av8100dev, "freq1:%ld freq2:%ld\n", freq1, freq2); + if ((xres == av8100_all_cea[index].hactive / hres_div) && + (yres == av8100_all_cea[index].vactive * yres_div) && + (htot == av8100_all_cea[index].htotale / hres_div) && + (vtot == av8100_all_cea[index].vtotale) && + (abs(freq1 - freq2) < 2)) { + goto av8100_video_output_format_get_out; + } + index++; + } + +av8100_video_output_format_get_out: + dev_dbg(av8100dev, "av8100_video_output_format_get %d %d %d %d %d\n", + xres, yres, htot, vtot, index); + return index; +} +EXPORT_SYMBOL(av8100_video_output_format_get); + +void av8100_hdmi_event_cb_set(void (*hdmi_ev_cb)(enum av8100_hdmi_event)) +{ + if (av8100_globals) + av8100_globals->hdmi_ev_cb = hdmi_ev_cb; +} +EXPORT_SYMBOL(av8100_hdmi_event_cb_set); + +u8 av8100_ver_get(void) +{ + u8 ret; + + LOCK_AV8100_HW; + ret = chip_version; + UNLOCK_AV8100_HW; + + return ret; +} +EXPORT_SYMBOL(av8100_ver_get); + +static const struct color_conversion_cmd *get_color_transform_cmd( + enum av8100_color_transform transform) +{ + const struct color_conversion_cmd *result; + + switch (transform) { + case AV8100_COLOR_TRANSFORM_INDENTITY: + result = &col_trans_identity; + break; + case AV8100_COLOR_TRANSFORM_INDENTITY_CLAMP_YUV: + result = &col_trans_identity_clamp_yuv; + break; + case AV8100_COLOR_TRANSFORM_YUV_TO_RGB: + if (chip_version == AV8100_CHIPVER_1) + result = &col_trans_yuv_to_rgb_v1; + else + result = &col_trans_yuv_to_rgb_v2; + break; + case AV8100_COLOR_TRANSFORM_YUV_TO_DENC: + result = &col_trans_yuv_to_denc; + break; + case AV8100_COLOR_TRANSFORM_RGB_TO_DENC: + result = &col_trans_rgb_to_denc; + break; + default: + dev_warn(av8100dev, "Unknown color space transform\n"); + result = &col_trans_identity; + break; + } + return result; +} + +static int av8100_open(struct inode *inode, struct file *filp) +{ + dev_dbg(av8100dev, "av8100_open is called\n"); + return 0; +} + +static int av8100_release(struct inode *inode, struct file *filp) +{ + dev_dbg(av8100dev, "av8100_release is called\n"); + return 0; +} + +static int av8100_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static int __devinit av8100_probe(struct i2c_client *i2cClient, + const struct i2c_device_id *id) +{ + int ret = 0; + struct av8100_platform_data *pdata = i2cClient->dev.platform_data; + + av8100dev = &i2cClient->dev; + + dev_dbg(av8100dev, "%s\n", __func__); + + av8100_set_state(AV8100_OPMODE_UNDEFINED); + + ret = av8100_config_init(); + if (ret) { + dev_info(av8100dev, "av8100_config_init failed\n"); + goto err; + } + + ret = av8100_globals_init(); + if (ret) { + dev_info(av8100dev, "av8100_globals_init failed\n"); + goto err; + } + + if (!i2c_check_functionality(i2cClient->adapter, + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + ret = -ENODEV; + dev_info(av8100dev, "av8100 i2c_check_functionality failed\n"); + goto err; + } + + init_waitqueue_head(&av8100_event); + + av8100_config->client = i2cClient; + av8100_config->id = (struct i2c_device_id *) id; + i2c_set_clientdata(i2cClient, av8100_config); + + kthread_run(av8100_thread, NULL, "av8100_thread"); + + ret = request_irq(pdata->irq, av8100_intr_handler, + IRQF_TRIGGER_RISING, "av8100", av8100_config); + if (ret) { + dev_err(av8100dev, "av8100_hw request_irq %d failed %d\n", + pdata->irq, ret); + gpio_free(pdata->irq); + goto err; + } + + /* Get regulator resource */ + if (pdata->regulator_pwr_id) { + av8100_globals->regulator_pwr = regulator_get(av8100dev, + pdata->regulator_pwr_id); + if (IS_ERR(av8100_globals->regulator_pwr)) { + ret = PTR_ERR(av8100_globals->regulator_pwr); + dev_warn(av8100dev, + "%s: Failed to get regulator '%s'\n", + __func__, pdata->regulator_pwr_id); + av8100_globals->regulator_pwr = NULL; + return ret; + } + } + + /* Get clock resource */ + av8100_globals->inputclk = clk_get(NULL, pdata->inputclk_id); + if (IS_ERR(av8100_globals->inputclk)) { + av8100_globals->inputclk = NULL; + dev_warn(av8100dev, "%s: Failed to get clock '%s'\n", + __func__, pdata->inputclk_id); + } + + av8100_set_state(AV8100_OPMODE_SHUTDOWN); + + /* Obtain the chip version */ + av8100_powerup1(); + av8100_powerdown(); + +err: + return ret; +} + +static int __devexit av8100_remove(struct i2c_client *i2cClient) +{ + dev_dbg(av8100dev, "%s\n", __func__); + + av8100_config_exit(); + av8100_globals_exit(); + if (av8100_globals->inputclk) + clk_put(av8100_globals->inputclk); + + /* Release regulator resource */ + if (av8100_globals->regulator_pwr) + regulator_put(av8100_globals->regulator_pwr); + + return 0; +} + +int av8100_init(void) +{ + int ret; + + pr_debug("%s\n", __func__); + + ret = i2c_add_driver(&av8100_driver); + if (ret) { + pr_err("av8100 i2c_add_driver failed\n"); + goto av8100_init_err; + } + + ret = misc_register(&av8100_miscdev); + if (ret) { + pr_err("av8100 misc_register failed\n"); + goto av8100_init_err; + } + + return ret; + +av8100_init_err: + return ret; +} +module_init(av8100_init); + +void av8100_exit(void) +{ + pr_debug("%s\n", __func__); + + misc_deregister(&av8100_miscdev); + i2c_del_driver(&av8100_driver); +} +module_exit(av8100_exit); + +MODULE_AUTHOR("Per Persson <per.xb.persson@stericsson.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("ST-Ericsson hdmi display driver"); diff --git a/drivers/video/av8100/av8100_fw.h b/drivers/video/av8100/av8100_fw.h new file mode 100644 index 00000000000..2beb0736922 --- /dev/null +++ b/drivers/video/av8100/av8100_fw.h @@ -0,0 +1,1165 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * + * Author: Per Persson <per.xb.persson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL), version 2. + */ + +/* AV8100 Firmware version : Unified version V2.2 for av8100v1 and av8100v2.x */ +#define AV8100_FW_SIZE 18432 +char av8100_fw_buff[AV8100_FW_SIZE] = { +0x80,0xfe,0xcb,0xfe,0x6b,0xf4,0x22,0xf6,0x22,0xf6,0xb9,0xf7,0x21,0xf5,0xbe,0xf7, +0x06,0xf9,0xc8,0xfa,0xe5,0xfa,0xf6,0xfa,0x08,0xfb,0x1b,0xfb,0x20,0xfb,0x25,0xfb, +0x2a,0xfb,0x2f,0xfb,0x44,0xfb,0x7e,0xfb,0x23,0xfc,0x65,0xf4,0x65,0xf4,0x66,0xf4, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xea,0xad,0xec,0xad, +0x38,0x20,0x1b,0x72,0x80,0x81,0x4d,0x51,0x4d,0x51,0x4d,0x51,0x4d,0x51,0x4d,0x51, +0x4d,0x51,0xb4,0x20,0xf4,0x2a,0x5a,0x90,0x82,0xfe,0xcd,0x80,0x00,0xaf,0x72,0x93, +0xa3,0x20,0x5f,0x90,0x80,0x80,0x97,0x90,0x8d,0x20,0x0f,0xab,0x01,0xa6,0x88,0x89, +0x90,0x96,0xad,0x97,0x90,0x9a,0xad,0x8b,0x93,0x9e,0xad,0x97,0x90,0xa2,0xad,0x80, +0xb7,0xa6,0xad,0x81,0xb7,0xaa,0xad,0x82,0xb7,0xae,0xad,0x26,0x31,0x20,0x08,0x72, +0x82,0xb7,0x21,0xa6,0x81,0xb7,0xc2,0xa6,0x80,0xb7,0x01,0xa6,0xb4,0x20,0xf5,0x2a, +0x5a,0x90,0x80,0x00,0xa7,0x72,0x93,0xcc,0xad,0x49,0x27,0x97,0x90,0x5d,0x90,0xd4, +0xad,0x82,0xb7,0xd8,0xad,0x81,0xb7,0xdc,0xad,0x80,0xb7,0xe0,0xad,0xff,0xae,0x90, +0x81,0x59,0x29,0xea,0x26,0x5a,0xfb,0x38,0x20,0x07,0x72,0x4d,0x38,0x20,0x1a,0x72, +0x49,0x00,0x38,0x20,0x05,0x72,0xbc,0xff,0xcd,0x08,0xae,0xf3,0x20,0x79,0x24,0x49, +0x44,0x24,0x49,0x23,0x24,0x49,0x0b,0xad,0x82,0xfe,0xcd,0x9e,0x82,0xfe,0xcd,0x9f, +0x5b,0x82,0xfe,0xcd,0x80,0xb6,0x82,0xfe,0xcd,0x81,0xb6,0x82,0xfe,0xcd,0x82,0xb6, +0x82,0xad,0x9f,0x90,0x86,0xad,0x85,0x90,0x84,0x42,0x8c,0x20,0x9f,0x90,0x01,0xab, +0x0f,0xa6,0x2a,0x31,0x20,0x08,0x72,0xfb,0x38,0x20,0x07,0x72,0x4d,0x38,0x20,0x1a, +0x72,0xbc,0xff,0xcd,0xfb,0x38,0x20,0x07,0x72,0x30,0x20,0x10,0x72,0x31,0x20,0x1e, +0x72,0x30,0x20,0x1c,0x72,0x95,0x05,0xa0,0x9e,0x3d,0x18,0xcc,0x5f,0x90,0x5f,0x4f, +0x07,0x38,0x20,0x05,0x72,0x0c,0x39,0x20,0x05,0x72,0x81,0x41,0x29,0x38,0x20,0x18, +0x72,0xd5,0x26,0x5a,0xfb,0x38,0x20,0x07,0x72,0x9d,0x9d,0x4d,0x38,0x20,0x1a,0x72, +0x4d,0xae,0xff,0xcd,0x4d,0xae,0xff,0xcd,0x38,0x20,0x1b,0x72,0x4d,0x4d,0x4d,0x4d, +0x4d,0x38,0x20,0x19,0x72,0x04,0x25,0x49,0x38,0x20,0x18,0x72,0x08,0xae,0x34,0x20, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x81,0xa5,0xbe,0x84,0xa3,0xb7,0xa4,0xd6,0x92,0x5c,0xa2,0xb7,0xa4, +0xd6,0x92,0x5c,0xa1,0xb7,0xa4,0xd6,0x92,0x01,0xae,0xa0,0xb7,0xa4,0xc6,0x92,0x88, +0xa5,0xbf,0x81,0xa0,0xb7,0xa4,0xc2,0x92,0xa0,0xb6,0xa1,0xb7,0xa4,0xd2,0x92,0x5a, +0xa1,0xb6,0xa2,0xb7,0xa4,0xd2,0x92,0x5a,0xa2,0xb6,0xa3,0xb7,0xa4,0xd0,0x92,0xa3, +0xb6,0x03,0xae,0xa5,0xbf,0x81,0xa3,0xb7,0xa4,0xda,0x92,0x5c,0xa3,0xb6,0xa2,0xb7, +0xa4,0xda,0x92,0x5c,0xa2,0xb6,0xa1,0xb7,0xa4,0xda,0x92,0x01,0xae,0xa1,0xb6,0xa0, +0xb7,0xa4,0xca,0x92,0xa0,0xb6,0xa5,0xbf,0xf1,0xfc,0xcc,0xd8,0xfd,0xcd,0x81,0xa5, +0xbe,0xe9,0x26,0x4a,0xa4,0x00,0x39,0x72,0xa4,0x00,0x69,0x72,0x5a,0xa4,0x00,0x69, +0x72,0x5a,0xa4,0x00,0x68,0x72,0x03,0xae,0xa5,0xbf,0x1b,0x27,0x4d,0x81,0xa0,0xb7, +0xa4,0xc9,0x92,0xa0,0xb6,0xa1,0xb7,0xa4,0xd9,0x92,0x5a,0xa1,0xb6,0xa2,0xb7,0xa4, +0xd9,0x92,0x5a,0xa2,0xb6,0xa3,0xb7,0xa4,0xdb,0x92,0xa3,0xb6,0x03,0xae,0xa5,0xbf, +0xf1,0xfc,0xcc,0x90,0xfd,0xcd,0x81,0xf1,0x20,0x01,0xab,0xa4,0xd6,0x92,0x07,0x2b, +0x5a,0x0a,0x24,0xa4,0xd7,0x92,0xa4,0xdb,0x92,0x03,0xae,0xa5,0xbf,0x81,0x01,0xa6, +0x02,0x20,0xff,0xa6,0x04,0x24,0x08,0x27,0xa4,0xd1,0x92,0xa3,0xb6,0xa5,0x3c,0x09, +0x26,0xa4,0xd1,0x92,0xa2,0xb6,0xa5,0x3c,0x12,0x26,0xa4,0xd1,0x92,0xa1,0xb6,0xa5, +0x3c,0x23,0x26,0xa4,0xd1,0x92,0xa0,0xb6,0xa5,0x3f,0x81,0xa0,0x3c,0x02,0x24,0xa1, +0xb7,0xa1,0xb9,0x9f,0xa2,0xb7,0xa2,0xbb,0x42,0x93,0x0f,0x27,0x4d,0x84,0x37,0xfd, +0xcd,0xa8,0xb6,0x05,0x27,0xa7,0xbe,0xa3,0xb7,0xa2,0xbf,0x42,0x93,0xa8,0xb6,0xa1, +0xb7,0xa0,0xbf,0x42,0xa7,0xb6,0x89,0xa8,0xb7,0x81,0xa0,0x3f,0xa1,0x3f,0xa2,0xbf, +0xa3,0xb7,0x81,0xa5,0xbe,0x84,0xa4,0xd7,0x92,0xa3,0xb6,0x5c,0xa4,0xd7,0x92,0xa2, +0xb6,0x5c,0xa4,0xd7,0x92,0xa1,0xb6,0x01,0xae,0xa4,0xc7,0x92,0xa0,0xb6,0x88,0xa5, +0xbf,0x81,0xa5,0xbe,0xa4,0xd7,0x92,0xa3,0xb6,0x5c,0xa4,0xd7,0x92,0xa2,0xb6,0x5c, +0xa4,0xd7,0x92,0xa1,0xb6,0x01,0xae,0xa4,0xc7,0x92,0xa0,0xb6,0xa5,0xbf,0x81,0x01, +0xa6,0x02,0x27,0x03,0x6d,0x04,0x26,0x02,0x6d,0x08,0x26,0x01,0x6d,0x0e,0x26,0x7d, +0x81,0x84,0xa3,0xb7,0x03,0xe6,0xa2,0xb7,0x02,0xe6,0xa1,0xb7,0x01,0xe6,0xa0,0xb7, +0xf6,0x88,0x81,0x01,0xa6,0x02,0x27,0xa3,0x3d,0x04,0x26,0xa2,0x3d,0x08,0x26,0xa1, +0x3d,0x0e,0x26,0xa0,0x3d,0x81,0xf5,0x26,0x4a,0xa0,0x39,0xa1,0x39,0xa2,0x39,0xa3, +0x38,0x0b,0x27,0x4d,0x81,0xa0,0x3f,0xa1,0x3f,0x81,0xa0,0xb7,0xa1,0xb7,0xff,0xa6, +0x07,0x2a,0xa2,0xbf,0xa3,0xb7,0x81,0x41,0xa8,0xbb,0x41,0x52,0x93,0x84,0xa8,0xb7, +0xa8,0xbb,0x52,0x01,0x7b,0xa7,0xbe,0xa8,0xb7,0x52,0x9f,0x90,0x88,0x81,0xa5,0xbe, +0xa3,0xb7,0xa4,0xd6,0x92,0x5c,0xa2,0xb7,0xa4,0xd6,0x92,0x5c,0xa1,0xb7,0xa4,0xd6, +0x92,0x01,0xae,0xa0,0xb7,0xa4,0xc6,0x92,0xa5,0xbf,0x81,0xa0,0x3f,0xa2,0xb7,0xa1, +0xbf,0x5c,0x01,0x24,0xa2,0xbb,0x42,0x93,0xa0,0xb6,0xa3,0xb7,0xa2,0xbf,0x42,0x93, +0xa0,0xbf,0x80,0xaa,0x00,0xc7,0x51,0x20,0xc6,0x50,0x20,0x11,0x72,0x80,0x85,0x90, +0xa6,0x00,0x32,0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00,0x32,0xa8,0x00,0x32,0xa7, +0x00,0x32,0x84,0x84,0x84,0x84,0x00,0x18,0xcd,0x63,0xa6,0x05,0x20,0xda,0x01,0x5a, +0x72,0xd9,0x01,0x5a,0x72,0x04,0x26,0xda,0x01,0xc6,0x0f,0x27,0xd9,0x01,0xca,0xda, +0x01,0xc6,0x00,0x18,0xcd,0x12,0xa6,0xc0,0x00,0x5f,0x72,0x09,0x27,0xc0,0x00,0xc6, +0xa2,0x01,0x5f,0x72,0xd9,0x01,0x5f,0x72,0xda,0x01,0x18,0x35,0x08,0x25,0x00,0xa2, +0xd9,0x01,0xc6,0x19,0xa0,0xda,0x01,0xc6,0x18,0x20,0xa2,0x01,0x01,0x35,0x06,0x27, +0x10,0xa5,0x04,0x7b,0x01,0x6b,0x10,0x40,0xc6,0x02,0x6b,0x11,0x40,0xc6,0x03,0x6b, +0x12,0x40,0xc6,0x04,0x6b,0x13,0x40,0xc6,0xe8,0xc4,0xcd,0x46,0x20,0xc7,0x46,0x20, +0xc6,0x41,0x20,0x5f,0x72,0x0a,0x42,0x20,0x0d,0x72,0x88,0x88,0x88,0x88,0xa7,0x00, +0x3b,0xa8,0x00,0x3b,0xa9,0x00,0x3b,0xa4,0x00,0x3b,0xa5,0x00,0x3b,0xa6,0x00,0x3b, +0x89,0x90,0x80,0x85,0x90,0xa6,0x00,0x32,0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00, +0x32,0xa8,0x00,0x32,0xa7,0x00,0x32,0x00,0x18,0xcd,0x15,0x20,0x10,0x72,0x07,0x27, +0x09,0x2b,0x10,0xb6,0x12,0x20,0x01,0x35,0xa7,0x00,0x3b,0xa8,0x00,0x3b,0xa9,0x00, +0x3b,0xa4,0x00,0x3b,0xa5,0x00,0x3b,0xa6,0x00,0x3b,0x89,0x90,0x80,0x0c,0x40,0x00, +0x35,0x0d,0x40,0x00,0x35,0x0e,0x40,0x00,0x35,0x0f,0x40,0x04,0x35,0x11,0x20,0x80, +0x35,0x80,0x11,0x20,0x40,0x35,0x80,0x11,0x20,0x20,0x35,0x80,0x11,0x20,0x10,0x35, +0x80,0x11,0x20,0x08,0x35,0x80,0x17,0x20,0x14,0x72,0x80,0x17,0x20,0x15,0x72,0x05, +0x17,0x20,0x05,0x72,0x11,0x20,0x04,0x35,0x80,0xe7,0x01,0xc7,0x4a,0x05,0x20,0x1a, +0x72,0x06,0x20,0x18,0x72,0x11,0x20,0xc7,0x02,0xa6,0x80,0xe7,0x01,0xc7,0x05,0x20, +0x1a,0x72,0x06,0x20,0x19,0x72,0x11,0x20,0xc7,0x01,0xa6,0x80,0x07,0x20,0x01,0x35, +0x04,0x88,0x00,0x35,0x05,0x88,0x30,0x35,0x06,0x88,0x00,0x35,0x07,0x88,0x00,0x35, +0x10,0x20,0x80,0x35,0x07,0x20,0x03,0x35,0x81,0xef,0xfc,0xcd,0xbc,0xae,0xa4,0x00, +0x84,0x35,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x80,0x85,0x90,0xa6,0x00,0x32, +0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00,0x32,0xa8,0x00,0x32,0xa7,0x00,0x32,0xa3, +0x00,0x32,0xa2,0x00,0x32,0xa1,0x00,0x32,0xa0,0x00,0x32,0x84,0x84,0x84,0x84,0x84, +0x84,0xef,0xfc,0xcd,0xa0,0xae,0xa4,0x00,0x84,0x35,0xd8,0xfd,0xcd,0x33,0xad,0x5b, +0xa0,0x3f,0xa1,0x3f,0xa2,0x1f,0x0e,0xfd,0xcd,0xf4,0x01,0xce,0xf5,0x01,0xc6,0x03, +0x6b,0x80,0xa4,0x03,0x7b,0x04,0x6b,0x4f,0x01,0x6b,0xa0,0x84,0xc6,0x02,0x6b,0xa1, +0x84,0xc6,0x03,0x6b,0xa2,0x84,0xc6,0x04,0x6b,0xa3,0x84,0xc6,0x84,0x84,0xf4,0x01, +0xcf,0xf5,0x01,0xc7,0x4d,0xc5,0xcd,0xbc,0x00,0xce,0xbd,0x00,0xc6,0xf6,0x01,0x3b, +0xf7,0x01,0x3b,0x0f,0x20,0x31,0xc5,0xcd,0xbc,0x00,0xce,0xbd,0x00,0xc6,0xf6,0x01, +0x3b,0xf7,0x01,0x3b,0x11,0x24,0x05,0xe2,0x72,0xf6,0x01,0xc6,0x06,0xe0,0x72,0xf7, +0x01,0xc6,0x1f,0x24,0x05,0xe2,0x72,0xbc,0x00,0xc6,0x06,0xe0,0x72,0xbd,0x00,0xc6, +0x1c,0x25,0xf6,0x01,0xc2,0x05,0x7b,0xf7,0x01,0xc0,0x06,0x7b,0x0c,0x24,0xbc,0x00, +0xc2,0x05,0x7b,0xbd,0x00,0xc0,0x06,0x7b,0x5c,0x20,0xf4,0x01,0xcf,0xbc,0x00,0xce, +0xf5,0x01,0xbd,0x00,0x55,0x0d,0x26,0x71,0x01,0xc6,0x0d,0x20,0xf6,0x01,0xce,0xf5, +0x01,0xc7,0xf7,0x01,0xc6,0x0b,0x27,0x4a,0x70,0x01,0xc6,0x07,0x20,0x01,0x35,0x07, +0x20,0x03,0x35,0x08,0x26,0x04,0xa1,0x05,0x20,0x1d,0x72,0x05,0x20,0x1c,0x72,0x08, +0x25,0x02,0xa1,0xbb,0x00,0xc6,0x1b,0x26,0xbc,0x00,0xc1,0x05,0x7b,0x22,0x26,0xbd, +0x00,0xc1,0x06,0x7b,0x29,0x26,0x4a,0x70,0x01,0xc6,0xf6,0x01,0x5f,0x72,0xf7,0x01, +0xc7,0x06,0xa6,0xbe,0xfa,0xcd,0xa2,0xb7,0x18,0xaa,0xa2,0xb6,0x1e,0xfe,0xcd,0xb6, +0xfa,0xcd,0x5b,0x12,0x20,0x0a,0xa6,0xbe,0xfa,0xcd,0xa2,0x18,0x1e,0xfe,0xcd,0xb6, +0xfa,0xcd,0x5b,0x10,0x24,0x00,0xa2,0x05,0x7b,0x0a,0xa0,0x06,0x7b,0x1a,0x25,0x00, +0xa2,0x05,0x7b,0x06,0xa0,0x06,0x7b,0x03,0x6b,0xc7,0xa4,0x03,0x7b,0x01,0x6b,0xbc, +0x84,0xc6,0x02,0x6b,0xbd,0x84,0xc6,0x03,0x6b,0xbe,0x84,0xc6,0x04,0x6b,0xbf,0x84, +0xc6,0x57,0x27,0x71,0x01,0xc6,0x06,0x6b,0xa7,0x83,0xc6,0x05,0x6b,0xa6,0x83,0xc6, +0xf5,0x01,0x5f,0x72,0xf4,0x01,0x5f,0x72,0xf7,0x01,0x5f,0x72,0xf6,0x01,0x5f,0x72, +0x10,0x20,0x40,0x35,0x88,0x88,0x88,0x88,0x88,0x88,0xa0,0x00,0x3b,0xa1,0x00,0x3b, +0xa2,0x00,0x3b,0xa3,0x00,0x3b,0xa7,0x00,0x3b,0xa8,0x00,0x3b,0xa9,0x00,0x3b,0xa4, +0x00,0x3b,0xa5,0x00,0x3b,0xa6,0x00,0x3b,0x89,0x90,0x81,0x48,0x83,0x00,0x35,0x49, +0x83,0x00,0x35,0x4a,0x83,0x00,0x35,0x4b,0x83,0x0f,0x35,0x80,0x85,0x90,0xa6,0x00, +0x32,0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00,0x32,0xa8,0x00,0x32,0xa7,0x00,0x32, +0x84,0x84,0x84,0x84,0xe8,0x01,0x5f,0x72,0x48,0xcb,0xcd,0x20,0xad,0x05,0x26,0x4a, +0xe8,0x01,0xc6,0x0b,0x26,0x03,0xa1,0x70,0x01,0xc6,0xf0,0x01,0x5c,0x72,0x04,0x27, +0x0f,0xa1,0xf0,0x01,0xc6,0x0b,0x20,0xe7,0x01,0x01,0x35,0x11,0x26,0xf0,0x01,0x5a, +0x72,0x17,0x27,0xf0,0x01,0xc6,0x11,0x26,0x03,0xea,0x72,0x04,0x7b,0x07,0x27,0x4c, +0x03,0x7b,0x05,0x26,0x4c,0x04,0x7b,0x11,0x27,0x03,0x7b,0x04,0x26,0x4a,0x04,0x7b, +0x74,0xe1,0xcd,0x03,0xee,0x72,0x9f,0x03,0x6b,0x04,0xef,0x72,0x03,0xe2,0x72,0x41, +0x04,0xe0,0x72,0x5f,0x01,0xa6,0x03,0x6b,0x01,0xe2,0x72,0x03,0x7b,0x04,0x6b,0x02, +0xe0,0x72,0x04,0x7b,0x0e,0x24,0x03,0xe2,0x72,0x9f,0x04,0xe0,0x72,0x46,0x54,0x01, +0xef,0x72,0x02,0x6b,0x46,0x54,0x4e,0x01,0xce,0x4f,0x01,0xc6,0x08,0x20,0x4e,0x01, +0xce,0x4f,0x01,0xc6,0x08,0x26,0x4a,0x47,0x01,0xc6,0xe3,0x26,0x03,0xe1,0x72,0xa6, +0x83,0xc6,0xeb,0x26,0x04,0xe1,0x72,0xa7,0x83,0xc6,0x04,0x6b,0xa7,0x83,0xc6,0x03, +0x6b,0xa6,0x83,0xc6,0xc6,0xf8,0xcc,0x84,0x84,0x84,0x84,0xaf,0x00,0x35,0x35,0xb0, +0x00,0x86,0x35,0xb1,0x00,0x37,0x35,0xb2,0x00,0xbd,0x35,0xf0,0x01,0x0f,0x35,0xf2, +0x01,0x01,0x35,0xf5,0xf8,0xcd,0x69,0xc5,0xcd,0xb3,0x00,0x3b,0xb4,0x00,0x3b,0xb5, +0x00,0x3b,0xb6,0x00,0x3b,0x31,0x26,0xf2,0x01,0xc6,0x16,0xcb,0xcd,0x03,0x27,0xf0, +0x01,0xc6,0xdc,0xf8,0xcc,0x03,0x26,0x02,0xa1,0xe6,0x01,0xc6,0xc6,0xf8,0xcc,0x03, +0x27,0x02,0xa1,0x70,0x01,0xc6,0x10,0x20,0x20,0x35,0x88,0x88,0x88,0x88,0xa7,0x00, +0x3b,0xa8,0x00,0x3b,0xa9,0x00,0x3b,0xa4,0x00,0x3b,0xa5,0x00,0x3b,0xa6,0x00,0x3b, +0x89,0x90,0x80,0x10,0x20,0x08,0x35,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41, +0x02,0xab,0x80,0x85,0x90,0xa6,0x00,0x32,0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00, +0x32,0xa8,0x00,0x32,0xa7,0x00,0x32,0xa3,0x00,0x32,0xa2,0x00,0x32,0xa1,0x00,0x32, +0xa0,0x00,0x32,0x84,0x84,0x84,0x84,0x84,0xef,0xfc,0xcd,0xa4,0xbf,0x84,0xae,0xa3, +0x1a,0x2f,0xad,0x5b,0x09,0x20,0x04,0xae,0xa4,0x00,0x44,0x35,0xa0,0x3f,0x3c,0xad, +0x5b,0x02,0x6b,0x08,0x84,0xc6,0x03,0x6b,0x09,0x84,0xc6,0x04,0x6b,0x0a,0x84,0xc6, +0x05,0x6b,0x0b,0x84,0xc6,0xef,0xfc,0xcd,0xa4,0xbf,0x84,0xae,0xa3,0x1b,0x5c,0xad, +0x5b,0x2d,0x27,0x72,0x01,0xc6,0x32,0x27,0xc2,0x00,0xc6,0x02,0x6b,0x84,0x84,0xc6, +0x03,0x6b,0x85,0x84,0xc6,0x04,0x6b,0x86,0x84,0xc6,0x05,0x6b,0x87,0x84,0xc6,0x84, +0x84,0x84,0xd3,0xcc,0xcd,0x41,0x00,0xa9,0x41,0xd4,0xab,0x5f,0x52,0x21,0xae,0xd2, +0x00,0xc6,0x02,0x4b,0x10,0x4b,0x00,0x4b,0xd2,0x00,0x5c,0x72,0x04,0x20,0xd2,0x00, +0x5f,0x72,0x06,0x26,0xa8,0xb1,0xa8,0xbf,0x90,0x0d,0x26,0xa7,0xb3,0xa7,0x3f,0xd2, +0x00,0xce,0x90,0x4a,0x5a,0x01,0x26,0x4d,0x5f,0x3a,0x25,0x02,0xa1,0xd3,0x00,0xc6, +0xd6,0xca,0xcd,0xe7,0x01,0x5f,0x72,0x07,0x26,0x4a,0xe7,0x01,0xc6,0x06,0x27,0x4a, +0x70,0x01,0xc6,0xc6,0xd8,0xcd,0xe9,0x01,0xc7,0x06,0x26,0x4a,0xe9,0x01,0xc6,0x86, +0x01,0x5c,0x72,0x04,0x27,0x4c,0x86,0x01,0xc6,0x0a,0x20,0x86,0x01,0x5f,0x72,0x06, +0x27,0xf0,0x01,0xc6,0xf1,0x01,0x5c,0x72,0x04,0x24,0xff,0xa1,0xf1,0x01,0xc6,0xe8, +0x01,0x01,0x35,0xef,0xfc,0xcd,0xa0,0xae,0xa4,0x00,0x84,0x35,0xa0,0x1f,0xae,0xf7, +0xcd,0x5b,0x02,0x6b,0xa0,0x84,0xc6,0x03,0x6b,0xa1,0x84,0xc6,0x04,0x6b,0xa2,0x84, +0xc6,0x05,0x6b,0xa3,0x84,0xc6,0x84,0x84,0x84,0x84,0x69,0xc5,0xcd,0xb3,0x00,0x3b, +0xb4,0x00,0x3b,0xb5,0x00,0x3b,0xb6,0x00,0x3b,0xf2,0x01,0x5f,0x72,0x41,0x25,0x04, +0xa1,0xf1,0x01,0xc6,0x65,0x27,0x4a,0x70,0x01,0xc6,0xef,0xfc,0xcd,0x9c,0xae,0xa4, +0x00,0x83,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x01,0x6b,0x9f,0x83, +0xc6,0x05,0x20,0x14,0x72,0x10,0x20,0x06,0x35,0x88,0x88,0x88,0x88,0x88,0xa0,0x00, +0x3b,0xa1,0x00,0x3b,0xa2,0x00,0x3b,0xa3,0x00,0x3b,0xa7,0x00,0x3b,0xa8,0x00,0x3b, +0xa9,0x00,0x3b,0xa4,0x00,0x3b,0xa5,0x00,0x3b,0xa6,0x00,0x3b,0x89,0x90,0x81,0xa4, +0x00,0x8c,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x80,0x85,0x90,0xa6, +0x00,0x32,0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00,0x32,0xa8,0x00,0x32,0xa7,0x00, +0x32,0xa3,0x00,0x32,0xa2,0x00,0x32,0xa1,0x00,0x32,0xa0,0x00,0x32,0x84,0xef,0xfc, +0xcd,0x0c,0xae,0x27,0xad,0xf0,0xa4,0x01,0x7b,0x87,0x01,0x5f,0x72,0x05,0x20,0x16, +0x72,0x06,0x20,0xc7,0x05,0xaa,0x06,0x20,0xc6,0x1b,0x27,0x04,0xa5,0x01,0x7b,0xef, +0xfc,0xcd,0x0c,0xae,0x48,0xad,0xf0,0xa4,0x05,0x20,0x16,0x72,0x06,0x20,0x14,0x72, +0x11,0x20,0x87,0x01,0x5a,0x72,0x0f,0xf5,0xcd,0x02,0xa6,0x05,0x26,0x4a,0x05,0x20, +0x4f,0x03,0x25,0x02,0xa1,0x87,0x01,0xc6,0xef,0xfc,0xcd,0x10,0xae,0x71,0xad,0x88, +0x01,0xd6,0x22,0x27,0x87,0x01,0xce,0x59,0x27,0x0f,0xa5,0x01,0x7b,0xef,0xfc,0xcd, +0x0c,0xae,0x14,0xf6,0xcd,0x0f,0xa4,0x05,0x20,0x16,0x72,0x06,0x20,0x12,0x72,0x74, +0x01,0x01,0x35,0x18,0x27,0x20,0xa5,0x01,0x7b,0x98,0xad,0x4f,0x05,0x27,0x80,0xa5, +0x01,0x7b,0x76,0x01,0xd7,0x17,0x8c,0xc6,0x75,0x01,0x5c,0x72,0x75,0x01,0xce,0x0f, +0x27,0x80,0xa5,0x07,0x20,0x75,0x01,0xcf,0x06,0x20,0x13,0x72,0x09,0x27,0x10,0xa5, +0x20,0x26,0x74,0x01,0xce,0x01,0x6b,0x0f,0x8c,0xc6,0x10,0x20,0x10,0x35,0x88,0xa0, +0x00,0x3b,0xa1,0x00,0x3b,0xa2,0x00,0x3b,0xa3,0x00,0x3b,0xa7,0x00,0x3b,0xa8,0x00, +0x3b,0xa9,0x00,0x3b,0xa4,0x00,0x3b,0xa5,0x00,0x3b,0xa6,0x00,0x3b,0x89,0x90,0xef, +0xfc,0xcc,0x0c,0xae,0xa4,0x00,0x8c,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3, +0xb7,0x80,0x85,0x90,0xa6,0x00,0x32,0xa5,0x00,0x32,0xa4,0x00,0x32,0xa9,0x00,0x32, +0xa8,0x00,0x32,0xa7,0x00,0x32,0x84,0x84,0x84,0x84,0xa0,0x84,0xc7,0x01,0x7b,0xa1, +0x84,0xc7,0x02,0x7b,0xa2,0x84,0xc7,0x03,0x7b,0xa3,0x84,0xc7,0x04,0x7b,0xe8,0x01, +0x01,0x35,0x01,0x6b,0x7f,0xa4,0x01,0x7b,0x0a,0x20,0x01,0x6b,0x80,0xaa,0x01,0x7b, +0x12,0x27,0x02,0xa1,0xe6,0x01,0xc6,0x0f,0x26,0x03,0xa1,0x04,0x27,0x02,0xa1,0x70, +0x01,0xc6,0x1a,0x27,0x71,0x01,0xc6,0x05,0x26,0x72,0x01,0xc6,0x01,0x6b,0xa0,0x84, +0xc6,0x02,0x6b,0xa1,0x84,0xc6,0x03,0x6b,0xa2,0x84,0xc6,0x04,0x6b,0xa3,0x84,0xc6, +0xf1,0x01,0x5f,0x72,0xe6,0x01,0xc7,0x03,0xa4,0x83,0x84,0xc6,0xfe,0xc5,0xcd,0x03, +0x26,0x4a,0xe5,0x01,0xc6,0x05,0x20,0x12,0x72,0x10,0x20,0x01,0x35,0x88,0x88,0x88, +0x88,0xa7,0x00,0x3b,0xa8,0x00,0x3b,0xa9,0x00,0x3b,0xa4,0x00,0x3b,0xa5,0x00,0x3b, +0xa6,0x00,0x3b,0x89,0x90,0x80,0x12,0x20,0x10,0x35,0x80,0xfb,0xf2,0xcc,0x28,0x4b, +0x07,0xce,0xcd,0xff,0xf2,0xcc,0xc1,0xa6,0x00,0x4b,0x08,0x4b,0x72,0xce,0xcd,0xff, +0xf2,0xcc,0xe0,0xa6,0x01,0x4b,0xe0,0x4b,0x80,0xf3,0xcc,0x03,0x26,0x9a,0x01,0x5a, +0x72,0x81,0x84,0x84,0x9a,0x01,0x02,0x35,0xa0,0xf2,0xcd,0xe0,0xa6,0x01,0x4b,0xe0, +0x4b,0x10,0x27,0x4d,0x56,0xd2,0xcd,0x28,0x27,0x9c,0x01,0xc5,0x9e,0x01,0xc6,0xff, +0xf2,0xcc,0xc1,0xa6,0x00,0x4b,0x28,0x4b,0xfd,0xf2,0xcc,0x01,0x4b,0x90,0x4b,0x07, +0xce,0xcd,0x0a,0x27,0x9c,0x01,0xc5,0x9e,0x01,0xc6,0xc5,0x20,0x28,0x4b,0xff,0xf2, +0xcc,0xe0,0xa6,0x01,0x4b,0x90,0x4b,0xcd,0xce,0xcd,0x0c,0x27,0x9c,0x01,0xc5,0x9e, +0x01,0xc6,0xdd,0x20,0x08,0x4b,0xff,0xf2,0xcc,0x82,0xa6,0x01,0x4b,0x90,0x4b,0x9b, +0x01,0x5a,0x72,0xce,0x27,0x9b,0x01,0xc6,0x12,0x26,0x4d,0xcc,0xd1,0xcd,0xff,0xf2, +0xcc,0xc0,0xa6,0x00,0x4b,0x50,0x4b,0xb7,0x27,0x4d,0x56,0xd2,0xcd,0xe8,0x26,0x4d, +0x85,0xcf,0xcd,0x03,0xa6,0x26,0x20,0x9b,0x01,0x0a,0x35,0xcb,0x27,0x4d,0x56,0xd2, +0xcd,0xd3,0x20,0x60,0x4b,0x04,0x27,0x4d,0x85,0xcf,0xcd,0x83,0xa6,0x18,0x27,0x4d, +0xae,0xd1,0xcd,0xff,0xf2,0xcc,0x81,0xa6,0x00,0x4b,0x60,0x4b,0xec,0x26,0x4d,0x85, +0xcf,0xcd,0x02,0xa6,0x2e,0xd1,0xcd,0xff,0xf2,0xcc,0xa0,0xa6,0x00,0x4b,0x08,0x4b, +0x09,0x27,0x4d,0x6e,0xd0,0xcd,0x06,0x26,0x4d,0x85,0xcf,0xcd,0x4c,0x8c,0x20,0x80, +0xa6,0x88,0x88,0x4f,0x93,0x20,0x40,0xa6,0x00,0x4b,0xa0,0x4b,0x08,0x26,0x4d,0xdd, +0xcf,0xcd,0x5d,0xf4,0xcc,0x21,0xf4,0xcc,0x03,0x26,0x1f,0xa0,0x06,0xf4,0xcc,0x03, +0x26,0x4a,0xee,0xf3,0xcc,0x03,0x26,0x20,0xa0,0xe0,0x27,0x1e,0xa0,0xd2,0xf3,0xcc, +0x03,0x26,0x4a,0x60,0x27,0x4a,0x39,0x27,0x20,0xa0,0xc3,0x27,0x20,0xa0,0x2c,0x27, +0x20,0xa0,0x30,0x27,0x20,0xa0,0x5d,0xf4,0xcc,0x03,0x26,0xa8,0x01,0xc6,0xdd,0x20, +0x60,0xa6,0x00,0x4b,0x50,0x4b,0x07,0xce,0xcd,0x03,0x25,0x61,0xa1,0xa8,0x01,0xc6, +0x12,0x27,0x11,0xa1,0xa1,0x01,0xc6,0x07,0x27,0x9f,0x01,0xc6,0x81,0x84,0x84,0x9f, +0xad,0x20,0xa6,0x00,0x4b,0x50,0x4b,0x0b,0x26,0x72,0x01,0xc6,0x05,0x27,0xa8,0x01, +0xc6,0x10,0x20,0x4f,0x00,0x4b,0xa0,0x4b,0x07,0xce,0xcd,0x03,0x27,0xa8,0x01,0xc6, +0x0f,0x26,0xa2,0x01,0xc6,0x81,0x84,0x84,0x84,0xdf,0xc4,0xcd,0x06,0xee,0x72,0x07, +0x7b,0xa8,0x01,0xc7,0x03,0x7b,0x05,0x20,0x18,0x72,0x04,0x27,0x01,0xe1,0x72,0xf0, +0xa4,0xa8,0x01,0xc6,0x01,0x6b,0xf0,0xa4,0x03,0x7b,0x06,0x20,0xc7,0x02,0x6b,0x02, +0xea,0x72,0xe0,0xa4,0x03,0x7b,0x02,0x6b,0x1f,0xa4,0x06,0x20,0xc6,0x88,0x88,0x88, +0xfe,0xce,0x80,0x3d,0xe1,0xb7,0x80,0x3d,0xab,0x93,0x80,0x3d,0x25,0x6e,0x9f,0x3d, +0x81,0x13,0x00,0x01,0x35,0x04,0x27,0x12,0xb7,0xc0,0x84,0xc6,0x50,0x18,0xcd,0x11, +0xb7,0x11,0xf1,0xcd,0x50,0x18,0xcc,0x11,0xb7,0x01,0xa6,0x07,0x24,0x20,0xa1,0xf3, +0x01,0xc6,0x09,0x20,0x5f,0xef,0xcd,0xd6,0x20,0x5f,0xef,0xcd,0x05,0x26,0x04,0xa1, +0x12,0xb6,0x06,0x27,0x02,0xa1,0x12,0xb6,0x11,0x26,0x02,0xa1,0x11,0xb6,0xb3,0x20, +0x4a,0xef,0xcd,0x2a,0x20,0x93,0xee,0xcd,0x2f,0x20,0x0e,0xee,0xcd,0xc2,0x20,0x11, +0xb7,0x0e,0xee,0xcd,0x07,0x26,0x02,0xa1,0x11,0xb6,0x81,0x12,0x00,0x18,0x4d,0x55, +0x13,0x00,0x19,0x4d,0x55,0x14,0x00,0x1a,0x4d,0x55,0x15,0x00,0x1b,0x4d,0x55,0x6e, +0x25,0x20,0xa1,0xf3,0x01,0xc6,0x50,0x18,0xcd,0x11,0xb7,0xc0,0xeb,0xcd,0x65,0x20, +0x22,0xeb,0xcd,0x6a,0x20,0xe1,0xe7,0xcd,0x45,0x18,0xcc,0x40,0xe7,0xcd,0x75,0x20, +0x61,0xe7,0xcd,0x7a,0x20,0x68,0xe6,0xcd,0x77,0xf2,0xcc,0x12,0xe6,0xcd,0x77,0xf2, +0xcc,0xd2,0xe5,0xcd,0x77,0xf2,0xcc,0x25,0xe5,0xcd,0x77,0xf2,0xcc,0x02,0xe4,0xcd, +0x81,0x88,0xaf,0xf1,0xd6,0x88,0xb0,0xf1,0xd6,0x58,0x97,0x8f,0xf2,0xcc,0x03,0x25, +0x0f,0xa1,0x4a,0x6e,0xf2,0x52,0xf2,0x4d,0xf2,0x48,0xf2,0x36,0xf2,0x12,0xf2,0x0d, +0xf2,0x08,0xf2,0x02,0xf2,0xfd,0xf1,0xf8,0xf1,0xf2,0xf1,0xec,0xf1,0xe6,0xf1,0xe0, +0xf1,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x02,0xab,0xf6,0x20,0x01,0xa6, +0x81,0x85,0x85,0x85,0x85,0x85,0x06,0x26,0x11,0xbe,0x04,0x20,0x4f,0x05,0xc5,0xcd, +0x0a,0xa6,0x9a,0x78,0x84,0xc7,0x02,0x7b,0x79,0x84,0xc7,0x03,0x7b,0x7a,0x84,0xc7, +0x04,0x7b,0x7b,0x84,0xc7,0x05,0x7b,0xef,0xfc,0xcd,0x78,0xae,0xa4,0x00,0x84,0x35, +0xa0,0x18,0x36,0xad,0x5b,0x02,0x6b,0x78,0x84,0xc6,0x03,0x6b,0x79,0x84,0xc6,0x04, +0x6b,0x7a,0x84,0xc6,0x05,0x6b,0x7b,0x84,0xc6,0x41,0xcc,0xcd,0x01,0xa6,0x41,0xcc, +0xcd,0x4f,0x9b,0x49,0x27,0x01,0xe4,0x72,0x4f,0x01,0x20,0x4c,0x03,0x26,0x4a,0x11, +0xb6,0x01,0x6b,0x4f,0x01,0x20,0x01,0xa6,0x04,0x26,0x9b,0xfc,0xcd,0xa1,0x3f,0xa2, +0x3f,0xa3,0x3f,0x77,0xad,0x5b,0x02,0x6b,0xc0,0x84,0xc6,0x03,0x6b,0xc1,0x84,0xc6, +0x04,0x6b,0xc2,0x84,0xc6,0x05,0x6b,0xc3,0x84,0xc6,0x88,0x88,0x88,0x88,0x88,0x81, +0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x01,0xab,0x81,0x85,0x85,0x85,0x85,0x85,0x05,0x7b,0xe4,0x01,0x01,0x35, +0x04,0x27,0x02,0xa1,0x11,0xb6,0x0a,0x26,0x4a,0x13,0xb6,0x05,0x6b,0x01,0xa6,0x04, +0x20,0x12,0x00,0xbf,0x01,0x55,0x09,0x20,0xbd,0xcc,0xcd,0x05,0x27,0x85,0x85,0x4d, +0xc0,0x1b,0xcd,0x13,0xbe,0x14,0xb6,0x01,0x4b,0x00,0x4b,0x1e,0x20,0x85,0x9b,0x1c, +0xcd,0x13,0xbe,0x14,0xb6,0x01,0x4b,0xbf,0x01,0xc7,0x15,0xb6,0x21,0x20,0x33,0x27, +0x4d,0x03,0x1d,0xcd,0x39,0x20,0x9a,0x5e,0xad,0xa2,0x18,0x57,0xad,0x5b,0x9b,0x01, +0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04,0x6b, +0xb7,0x84,0xc6,0x05,0xc5,0xcd,0xfa,0xa6,0x9a,0x18,0x84,0x00,0x35,0x19,0x84,0x03, +0x35,0x1a,0x84,0x83,0x35,0x1b,0x84,0x00,0x35,0x14,0x45,0x00,0x35,0x15,0x45,0x00, +0x35,0x16,0x45,0x00,0x35,0x17,0x45,0x02,0x35,0x07,0xf1,0xcd,0xa2,0x16,0xa3,0x12, +0xfc,0xf0,0xcd,0x5b,0x9b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03, +0x6b,0xb6,0x84,0xc6,0x04,0x6b,0xb7,0x84,0xc6,0x84,0x84,0x84,0x84,0x84,0x84,0x84, +0x84,0x65,0xde,0xcd,0x6c,0x01,0x3b,0x6d,0x01,0x3b,0x6e,0x01,0x3b,0x6f,0x01,0x3b, +0x04,0x4b,0xc4,0x4b,0xb4,0x4b,0x00,0x4b,0xe1,0xf0,0xcc,0xc5,0xf0,0xcc,0x03,0x26, +0x4a,0xb4,0xf0,0xcc,0x03,0x26,0x4a,0xac,0xf0,0xcc,0x03,0x26,0x4a,0x15,0x27,0x4a, +0x12,0xb6,0xe1,0xf0,0xcc,0x03,0x27,0x02,0xa1,0x11,0xb6,0xe5,0xf0,0xcc,0xe8,0x01, +0xc7,0x4c,0x9a,0xef,0xfc,0xcd,0x18,0xae,0xa4,0x00,0x84,0x35,0xa0,0xb7,0xa1,0xb7, +0xa2,0xb7,0x4f,0xa3,0xb7,0x12,0xb6,0x9b,0xe5,0xf0,0xcc,0x03,0x27,0x03,0xa1,0x70, +0x01,0xc6,0x05,0x6b,0x01,0xa6,0xee,0x01,0x5f,0x72,0x70,0x01,0x5f,0x72,0x0c,0x27, +0x4a,0x0f,0x27,0x4a,0x12,0x27,0x4a,0x15,0x27,0x4a,0xee,0x01,0xc6,0xec,0x01,0x5f, +0x72,0xed,0x01,0x01,0x35,0x23,0x20,0xec,0x01,0x5f,0x72,0xed,0x01,0xc7,0x02,0xa6, +0x02,0x20,0x0a,0xa6,0x26,0x20,0x06,0x27,0x4a,0x05,0x27,0x4a,0x0c,0x27,0x4a,0xee, +0x01,0xc6,0x1d,0x24,0x20,0xa1,0xf3,0x01,0xc6,0xee,0x01,0xc7,0x7f,0xa4,0x12,0xb6, +0x70,0x01,0x03,0x35,0x79,0x26,0x4a,0x11,0xb6,0xe4,0x01,0x5f,0x72,0x9a,0x18,0x84, +0x00,0x35,0x19,0x84,0x00,0x35,0x1a,0x84,0x00,0x35,0x1b,0x84,0x00,0x35,0x9b,0x70, +0x01,0x5f,0x72,0x1a,0x27,0x02,0xa1,0x11,0xb6,0x05,0x6b,0x4f,0x88,0x88,0x88,0x88, +0x88,0x81,0x4f,0xbd,0xcc,0xcc,0x03,0x27,0x85,0x85,0x4d,0xc0,0x1b,0xcd,0x11,0xbe, +0x12,0xb6,0x80,0x4b,0x00,0x4b,0x81,0xd4,0x00,0xd7,0x11,0xb6,0x97,0x52,0x21,0xae, +0x81,0x85,0x85,0x85,0x85,0x85,0x4f,0x84,0x84,0x84,0xd3,0xcc,0xcd,0x00,0xae,0x11, +0xa6,0x88,0x04,0x7b,0x88,0x04,0x7b,0x88,0x01,0x7b,0xd3,0x00,0x5c,0x72,0x04,0x24, +0x03,0xa1,0x08,0x26,0xd3,0x00,0xc1,0x04,0x7b,0xe2,0x22,0x05,0xe1,0x72,0x13,0xb6, +0x05,0x6b,0x4c,0x9f,0x90,0xd7,0x00,0xd7,0x14,0xe6,0x90,0x05,0xe6,0x72,0x97,0x05, +0xeb,0x72,0x52,0x21,0xae,0x04,0x7b,0x15,0x20,0x4f,0xd6,0x00,0xd7,0x13,0xb6,0xd5, +0x00,0xd7,0x12,0xb6,0x54,0xad,0x3c,0x24,0x03,0xa1,0x04,0x7b,0xef,0x25,0x03,0xa1, +0x05,0x6b,0x4c,0x05,0x7b,0x04,0x6b,0x05,0x7b,0x04,0x27,0x6b,0xad,0x05,0x6b,0x4f, +0x04,0x6b,0xd3,0x00,0xc6,0x03,0x6b,0x10,0xa6,0x02,0x6b,0x02,0xa6,0x63,0x20,0x02, +0x6b,0x03,0xef,0x72,0x06,0xa9,0x41,0x00,0xab,0x59,0x48,0x59,0x48,0x59,0x48,0x59, +0x48,0x59,0x48,0x4a,0x5a,0x01,0x26,0x4d,0x5f,0x01,0x6b,0x0f,0xa4,0x11,0xb6,0x22, +0x25,0x81,0xa1,0x11,0xb6,0x01,0x6b,0x4f,0x88,0x88,0x88,0x88,0x88,0x81,0x85,0x85, +0x85,0x85,0x4f,0x9e,0x01,0x01,0x35,0x9f,0x01,0xc7,0x4c,0x08,0x20,0x17,0xb7,0x0c, +0x26,0xa0,0x01,0xc6,0x16,0xb7,0x04,0x7b,0x01,0x6b,0x02,0x6b,0x03,0x6b,0x4f,0x04, +0x6b,0xa3,0x01,0xc6,0x15,0xb7,0x01,0x7b,0x14,0xb7,0x02,0x7b,0x13,0xb7,0x03,0x7b, +0x12,0xb7,0x04,0x7b,0x01,0x6b,0xa4,0x01,0xc6,0x02,0x6b,0xa5,0x01,0xc6,0x03,0x6b, +0xa6,0x01,0xc6,0x04,0x6b,0xa7,0x01,0xc6,0x11,0xb7,0x4f,0x01,0x20,0x4c,0x03,0x26, +0x9f,0x01,0xce,0x50,0x20,0x9e,0x01,0x5f,0x72,0x9f,0x01,0xc7,0x4c,0x5a,0x20,0x9e, +0x01,0x5f,0x72,0x9f,0x01,0x5f,0x72,0x5c,0x27,0x4a,0x17,0x27,0x4a,0x10,0x27,0x4a, +0x11,0xb6,0x9d,0x01,0x08,0x35,0x04,0x27,0x12,0x3d,0x9d,0x01,0x5f,0x72,0x88,0x88, +0x88,0x88,0x81,0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0x81,0x1e,0xfe,0xcd, +0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81,0x10,0x4d,0x00,0x35,0x11,0x4d,0x00,0x35, +0x12,0x4d,0x00,0x35,0x81,0x85,0xcf,0xcd,0x01,0xa6,0x07,0xce,0xcd,0x04,0x48,0x00, +0x35,0x05,0x48,0x00,0x35,0x06,0x48,0x00,0x35,0x07,0x48,0x00,0x35,0x31,0xad,0xa3, +0x1a,0x81,0x85,0x85,0x85,0x85,0x4f,0x9a,0xa1,0x01,0x18,0x72,0xaf,0x01,0x1a,0x00, +0x55,0xb0,0x01,0x1b,0x00,0x55,0xb1,0x01,0x1c,0x00,0x55,0xb2,0x01,0x1d,0x00,0x55, +0xab,0x01,0x1e,0x00,0x55,0xac,0x01,0x1f,0x00,0x55,0xad,0x01,0x20,0x00,0x55,0xae, +0x01,0x21,0x00,0x55,0xb7,0x01,0x12,0x00,0x55,0xb8,0x01,0x13,0x00,0x55,0xb9,0x01, +0x14,0x00,0x55,0xba,0x01,0x15,0x00,0x55,0xb3,0x01,0x16,0x00,0x55,0xb4,0x01,0x17, +0x00,0x55,0xb5,0x01,0x18,0x00,0x55,0xb6,0x01,0x19,0x00,0x55,0x54,0x26,0x28,0xa1, +0x11,0xb6,0x5a,0x20,0xa1,0x01,0xc7,0x10,0xa4,0xa1,0x01,0xc6,0x64,0x20,0xa1,0x01, +0x10,0x72,0x06,0x26,0x27,0xa1,0x11,0xb6,0xd2,0xfc,0xcd,0xa4,0xb7,0x48,0xa9,0x41, +0x44,0xab,0x52,0x08,0xae,0x11,0xb6,0xae,0xfc,0xcd,0x12,0xae,0xd2,0xfc,0xcd,0xa4, +0xb7,0x48,0xa9,0x41,0x40,0xab,0x52,0x08,0xae,0x11,0xb6,0xae,0xfc,0xcd,0x16,0xae, +0x14,0x48,0xaf,0x01,0x55,0x15,0x48,0xb0,0x01,0x55,0x16,0x48,0xb1,0x01,0x55,0x17, +0x48,0xb2,0x01,0x55,0x10,0x48,0xab,0x01,0x55,0x11,0x48,0xac,0x01,0x55,0x12,0x48, +0xad,0x01,0x55,0x13,0x48,0xae,0x01,0x55,0xcf,0xed,0xcd,0xa1,0x1b,0xf9,0xed,0xcd, +0x5b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6, +0x04,0x6b,0xb7,0x84,0xc6,0x45,0x26,0x11,0x3d,0x6e,0xed,0xcc,0x03,0x25,0x28,0xa1, +0x11,0xb6,0xc8,0xed,0xcc,0x04,0xee,0xcd,0xa1,0x1b,0xf9,0xed,0xcd,0x5b,0x05,0xc5, +0xcd,0x0a,0xa6,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6, +0x84,0xc6,0x04,0x6b,0xb7,0x84,0xc6,0xa1,0x01,0x10,0x72,0x64,0xed,0xcc,0x03,0x27, +0x91,0xa1,0x11,0xb6,0xec,0xed,0xcd,0x13,0x4d,0x03,0x35,0xec,0xed,0xcd,0x13,0x4d, +0x43,0x35,0x0c,0x4d,0x1e,0x00,0x55,0x0d,0x4d,0x1f,0x00,0x55,0x0e,0x4d,0x20,0x00, +0x55,0x0f,0x4d,0x21,0x00,0x55,0x08,0x4d,0x1a,0x00,0x55,0x09,0x4d,0x1b,0x00,0x55, +0x0a,0x4d,0x1c,0x00,0x55,0x0b,0x4d,0x1d,0x00,0x55,0x04,0x4d,0x16,0x00,0x55,0x05, +0x4d,0x17,0x00,0x55,0x06,0x4d,0x18,0x00,0x55,0x07,0x4d,0x19,0x00,0x55,0x00,0x4d, +0x12,0x00,0x55,0x01,0x4d,0x13,0x00,0x55,0x02,0x4d,0x14,0x00,0x55,0x03,0x4d,0x15, +0x00,0x55,0xc4,0x27,0x9b,0xfc,0xcd,0xa0,0x3f,0xa1,0xb7,0x06,0xa4,0xa1,0xb6,0xa2, +0x3f,0xa3,0x3f,0xf9,0xed,0xcd,0x5b,0x01,0x6b,0x14,0x4d,0xc6,0x02,0x6b,0x15,0x4d, +0xc6,0x03,0x6b,0x16,0x4d,0xc6,0x04,0x6b,0x17,0x4d,0xc6,0x05,0xc5,0xcd,0x0f,0xa6, +0xec,0xed,0xcd,0x13,0x4d,0x03,0x35,0xec,0xed,0xcd,0x13,0x4d,0xc3,0x35,0x25,0x20, +0x02,0x6b,0x03,0x6b,0x04,0x6b,0x4f,0xcf,0xed,0xcd,0xa1,0x1a,0xf9,0xed,0xcd,0x5b, +0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04, +0x6b,0xb7,0x84,0xc6,0x62,0x26,0x80,0xa1,0x11,0xb6,0xf7,0x24,0x92,0xa1,0x11,0xb6, +0xde,0xec,0xcc,0x03,0x24,0x80,0xa1,0x11,0xb6,0x9b,0xca,0xed,0xcc,0x01,0xa6,0x05, +0x24,0x20,0xa1,0xf3,0x01,0xc6,0x0c,0x25,0x80,0xa1,0x11,0xb6,0x88,0x88,0x88,0x88, +0x81,0x48,0x42,0x00,0x35,0x49,0x42,0x00,0x35,0x4a,0x42,0x00,0x35,0x81,0x85,0x85, +0x85,0x85,0x4f,0x9a,0x88,0xc9,0xcd,0x72,0x01,0x01,0x35,0x6e,0xc4,0xcd,0x03,0x27, +0xc2,0x00,0xc6,0x16,0xad,0x4b,0x42,0x05,0x35,0x04,0x20,0x4b,0x42,0x01,0x35,0x06, +0x27,0x9c,0x01,0xc6,0xf7,0xc7,0xcd,0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35, +0xa2,0x16,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0x01,0x6b,0xb4, +0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04,0x6b,0xb7,0x84, +0xc6,0xeb,0xdd,0xcd,0x50,0x20,0x59,0xad,0x4b,0x42,0x05,0x35,0x04,0x20,0x4b,0x42, +0x01,0x35,0x06,0x27,0x9c,0x01,0xc6,0x13,0x26,0x4a,0x72,0x01,0xc6,0x69,0x20,0xb7, +0xc8,0xcd,0x97,0xc7,0xcd,0x08,0x26,0x11,0x3d,0x9b,0x9c,0x01,0x01,0x35,0x04,0x20, +0x9c,0x01,0x5f,0x72,0x06,0x26,0x02,0xa1,0x11,0xb6,0x88,0x88,0x88,0x88,0x81,0xef, +0xfc,0xcd,0x78,0xae,0xa4,0x00,0x84,0x35,0x81,0x18,0x80,0x00,0x35,0x19,0x80,0x00, +0x35,0x1a,0x80,0x00,0x35,0x81,0x08,0x80,0x00,0x35,0x09,0x80,0x00,0x35,0x0a,0x80, +0x00,0x35,0x81,0x04,0x80,0x00,0x35,0x05,0x80,0x00,0x35,0x06,0x80,0x00,0x35,0x81, +0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x81,0x84,0x8b,0x41,0x00,0xa9, +0x41,0x09,0xab,0x5b,0x0a,0x6b,0x4f,0x9a,0xb7,0xc8,0xcd,0x71,0x01,0x5f,0x72,0xbc, +0x84,0x00,0x35,0xbd,0x84,0x00,0x35,0xbe,0x84,0x18,0x35,0xbf,0x84,0x00,0x35,0x4a, +0xad,0x1b,0x80,0x80,0x35,0x14,0x80,0x00,0x35,0x15,0x80,0x00,0x35,0x16,0x80,0x00, +0x35,0x17,0x80,0x00,0x35,0x53,0xad,0x0b,0x80,0x00,0x35,0x4c,0xad,0x07,0x80,0x00, +0x35,0x00,0x80,0x00,0x35,0x01,0x80,0x00,0x35,0x02,0x80,0x00,0x35,0x03,0x80,0x00, +0x35,0x18,0xeb,0xcd,0xa3,0xb7,0xf8,0xa4,0xa3,0xb6,0x60,0xad,0x5b,0x07,0x6b,0x78, +0x84,0xc6,0x08,0x6b,0x79,0x84,0xc6,0x09,0x6b,0x7a,0x84,0xc6,0x0a,0x6b,0x7b,0x84, +0xc6,0x69,0x20,0x88,0xc9,0xcd,0x71,0x01,0x01,0x35,0x90,0x84,0xc7,0x03,0x7b,0x91, +0x84,0xc7,0x04,0x7b,0x92,0x84,0xc7,0x05,0x7b,0x93,0x84,0xc7,0x06,0x7b,0xd2,0xfd, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x03,0xab,0x5b,0xa0,0x1e,0xe6,0xea,0xcd,0x5b,0x05, +0x6b,0x06,0x6b,0x4f,0xb3,0xfd,0xcd,0x10,0xa6,0xa4,0xb7,0x00,0xa9,0x41,0x03,0xab, +0x5b,0x03,0x6b,0x94,0x84,0xc6,0x04,0x6b,0x95,0x84,0xc6,0x05,0x6b,0x96,0x84,0xc6, +0x06,0x6b,0x97,0x84,0xc6,0x73,0xfd,0xcd,0x01,0xa6,0xa4,0xb7,0x00,0xa9,0x41,0x07, +0xab,0x5b,0x07,0x6b,0x08,0x6b,0x4f,0x07,0x6b,0x98,0x84,0xc6,0x08,0x6b,0x99,0x84, +0xc6,0x09,0x6b,0x9a,0x84,0xc6,0x0a,0x6b,0x9b,0x84,0xc6,0x71,0x24,0x23,0xa1,0xf3, +0x01,0xc6,0xc4,0xdc,0xcd,0xbc,0x84,0x00,0x35,0xbd,0x84,0x00,0x35,0xbe,0x84,0x1b, +0x35,0xbf,0x84,0x40,0x35,0x04,0x20,0xbf,0x84,0x41,0x35,0x06,0x26,0x14,0x3d,0x0b, +0xeb,0xcd,0x1b,0x80,0x81,0x35,0xef,0xfc,0xcd,0x14,0xae,0xa4,0x00,0x80,0x35,0x7a, +0xfc,0xcd,0x52,0x80,0xae,0xfe,0xea,0xcd,0x0b,0x80,0x20,0x35,0x04,0x20,0x0b,0x80, +0x60,0x35,0x06,0x26,0xdb,0x01,0xc7,0x16,0xb6,0xdc,0x01,0x60,0x20,0x55,0xdd,0x01, +0x61,0x20,0x55,0xde,0x01,0x62,0x20,0x55,0xdf,0x01,0x63,0x20,0x55,0x68,0x20,0x21, +0x35,0x64,0x20,0xdc,0x01,0x55,0x65,0x20,0xdd,0x01,0x55,0x66,0x20,0xde,0x01,0x55, +0x67,0x20,0xdf,0x01,0x55,0x9d,0x9d,0x68,0x20,0x27,0x35,0x68,0x20,0x52,0x35,0x64, +0x20,0x00,0x35,0x65,0x20,0x0f,0x35,0x66,0x20,0x42,0x35,0x67,0x20,0x40,0x35,0x68, +0x20,0x22,0x35,0x60,0x20,0x6c,0x01,0x55,0x61,0x20,0x6d,0x01,0x55,0x62,0x20,0x6e, +0x01,0x55,0x63,0x20,0x6f,0x01,0x55,0xdc,0x01,0x94,0xf2,0x55,0xdd,0x01,0x95,0xf2, +0x55,0xde,0x01,0x96,0xf2,0x55,0xdf,0x01,0x97,0xf2,0x55,0xe0,0x01,0xc7,0xe1,0x01, +0x21,0x35,0xe2,0x01,0xe6,0x35,0xe3,0x01,0xf0,0x35,0x23,0x20,0xdc,0x01,0x98,0xf2, +0x55,0xdd,0x01,0x99,0xf2,0x55,0xde,0x01,0x9a,0xf2,0x55,0xdf,0x01,0x9b,0xf2,0x55, +0xe0,0x01,0xc7,0xe1,0x01,0x21,0x35,0xe2,0x01,0xf0,0x35,0xe3,0x01,0x7c,0x35,0x48, +0x20,0xdc,0x01,0x9c,0xf2,0x55,0xdd,0x01,0x9d,0xf2,0x55,0xde,0x01,0x9e,0xf2,0x55, +0xdf,0x01,0x9f,0xf2,0x55,0xe0,0x01,0xc7,0xe1,0x01,0x21,0x35,0xe2,0x01,0xf6,0x35, +0xe3,0x01,0x94,0x35,0x6d,0x20,0xf1,0xea,0xcd,0x07,0x80,0xe0,0x35,0xdc,0x01,0x90, +0xf2,0x55,0xdd,0x01,0x91,0xf2,0x55,0xde,0x01,0x92,0xf2,0x55,0xdf,0x01,0x93,0xf2, +0x55,0xe0,0x01,0x5f,0x72,0xe1,0x01,0x2a,0x35,0xe2,0x01,0x09,0x35,0xe3,0x01,0x8b, +0x35,0x77,0x27,0x4a,0x55,0x27,0x4a,0x33,0x27,0x4a,0x12,0xb6,0x10,0x80,0x00,0x35, +0x11,0x80,0x00,0x35,0x12,0x80,0x00,0x35,0x13,0x80,0x08,0x35,0xf1,0xea,0xcd,0x07, +0x80,0xc0,0x35,0xef,0xfc,0xcd,0x5f,0xa4,0x00,0x80,0x35,0x7a,0xfc,0xcd,0x06,0xaa, +0x41,0x01,0xea,0x72,0x41,0x02,0xea,0x72,0x5f,0x28,0xaa,0xc0,0xa4,0x52,0x40,0xae, +0x12,0xb6,0x01,0xef,0x72,0x02,0x6b,0x52,0x10,0xae,0x15,0xb6,0x18,0xeb,0xcd,0xa3, +0x10,0xa3,0x12,0xa3,0x14,0xe6,0xea,0xcd,0x5b,0x07,0x6b,0x78,0x84,0xc6,0x08,0x6b, +0x79,0x84,0xc6,0x09,0x6b,0x7a,0x84,0xc6,0x0a,0x6b,0x7b,0x84,0xc6,0xef,0xfc,0xcd, +0xb4,0xae,0xa4,0x00,0x84,0x35,0xa2,0x16,0xe6,0xea,0xcd,0x5b,0x07,0x6b,0xb4,0x84, +0xc6,0x08,0x6b,0xb5,0x84,0xc6,0x09,0x6b,0xb6,0x84,0xc6,0x0a,0x6b,0xb7,0x84,0xc6, +0x6f,0xea,0xcc,0x03,0x27,0x4a,0x13,0xb6,0x9b,0xda,0xea,0xcc,0x01,0xa6,0x05,0x27, +0x9b,0xfc,0xcd,0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x40,0xa4,0xa2,0xb6,0xa3,0x3f,0xe6, +0xea,0xcd,0x5b,0x07,0x6b,0x94,0x84,0xc6,0x08,0x6b,0x95,0x84,0xc6,0x09,0x6b,0x96, +0x84,0xc6,0x0a,0x6b,0x97,0x84,0xc6,0x8b,0x41,0x00,0xa2,0x41,0x0a,0xa0,0x5b,0x81, +0x85,0x4f,0x87,0x01,0x5a,0x72,0x9a,0x0c,0x8c,0x00,0x35,0x0d,0x8c,0x00,0x35,0x0e, +0x8c,0x00,0x35,0x0f,0x8c,0x01,0x35,0x04,0x20,0x0f,0x8c,0x03,0x35,0x06,0x26,0x4a, +0x87,0x01,0xc6,0xef,0xfc,0xcd,0x10,0xae,0xa4,0x00,0x8c,0x35,0xa0,0xb7,0xa1,0xb7, +0xa2,0xb7,0x4f,0xa3,0x00,0x88,0x01,0x55,0xef,0xfc,0xcd,0x1c,0xae,0xa4,0x00,0x8c, +0x35,0x7a,0xfc,0xcd,0x5f,0x0f,0xa4,0x4e,0x88,0x01,0xc6,0x9b,0x06,0x20,0xc7,0xfa, +0xa4,0x06,0x20,0xc6,0x52,0x27,0xe6,0x25,0x87,0x01,0xc6,0x87,0x01,0xc1,0x01,0x6b, +0x4c,0x9f,0x90,0x88,0x01,0xd7,0x12,0xe6,0x90,0x01,0xe6,0x72,0x97,0x01,0xe0,0x72, +0x10,0x20,0x01,0xa6,0x88,0x01,0xc7,0x12,0xb6,0x87,0x01,0xc7,0x11,0xb6,0x88,0x81, +0x85,0x4f,0x74,0x01,0x5f,0x72,0xef,0x25,0x75,0x01,0xc1,0x01,0x6b,0x4c,0x9f,0x14, +0xe7,0x76,0x01,0xd6,0x01,0xee,0x72,0x0a,0x20,0x4f,0x13,0x00,0x75,0x01,0x55,0x88, +0x81,0x4f,0x9a,0xa8,0x84,0x29,0x00,0x55,0xa9,0x84,0x2a,0x00,0x55,0xaa,0x84,0x2b, +0x00,0x55,0xab,0x84,0x2c,0x00,0x55,0xef,0xfc,0xcd,0x48,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x27,0xbe,0x28,0xb6,0xef,0xfc,0xcd,0x44,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x25,0xbe,0x26,0xb6,0xef,0xfc,0xcd,0x40,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x23,0xbe,0x24,0xb6,0xef,0xfc,0xcd,0x3c,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x21,0xbe,0x22,0xb6,0xef,0xfc,0xcd,0x38,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x1f,0xbe,0x20,0xb6,0xef,0xfc,0xcd,0x34,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x1d,0xbe,0x1e,0xb6,0xef,0xfc,0xcd,0x30,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x1b,0xbe,0x1c,0xb6,0xef,0xfc,0xcd,0x2c,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x19,0xbe,0x1a,0xb6,0xef,0xfc,0xcd,0x28,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x17,0xbe,0x18,0xb6,0xef,0xfc,0xcd,0x24,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x15,0xbe,0x16,0xb6,0xef,0xfc,0xcd,0x20,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x13,0xbe,0x14,0xb6,0xef,0xfc,0xcd,0x1c,0xae,0xa4,0x00,0x84,0x35, +0x7a,0xfc,0xcd,0x11,0xbe,0x12,0xb6,0x9b,0x81,0x4f,0xe9,0x01,0x01,0x35,0x45,0x01, +0xcf,0x1f,0xbe,0x46,0x01,0xc7,0x20,0xb6,0x43,0x01,0xcf,0x1d,0xbe,0x44,0x01,0xc7, +0x1e,0xb6,0x41,0x01,0xcf,0x1b,0xbe,0x42,0x01,0xc7,0x1c,0xb6,0x3f,0x01,0xcf,0x19, +0xbe,0x40,0x01,0xc7,0x1a,0xb6,0x3d,0x01,0xcf,0x17,0xbe,0x3e,0x01,0xc7,0x18,0xb6, +0x3b,0x01,0xcf,0x15,0xbe,0x3c,0x01,0xc7,0x16,0xb6,0x39,0x01,0xcf,0x13,0xbe,0x3a, +0x01,0xc7,0x14,0xb6,0x37,0x01,0xcf,0x11,0xbe,0x38,0x01,0xc7,0x12,0xb6,0x81,0x4f, +0x9a,0x30,0x42,0x00,0x35,0x31,0x42,0x00,0x35,0x32,0x42,0x00,0x35,0x33,0x42,0x00, +0x35,0xc6,0xd8,0xcd,0x22,0xda,0xcd,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x65, +0xde,0xcd,0x6c,0x01,0x3b,0x6d,0x01,0x3b,0x6e,0x01,0x3b,0x6f,0x01,0x3b,0x5e,0x01, +0x3b,0x5f,0x01,0x3b,0x60,0x01,0x3b,0x61,0x01,0x3b,0xf5,0xd5,0xcd,0x9b,0x81,0x85, +0x85,0x85,0x85,0x85,0x4f,0xc2,0x00,0x01,0x35,0x9a,0x84,0x84,0xc7,0x02,0x7b,0x85, +0x84,0xc7,0x03,0x7b,0x86,0x84,0xc7,0x04,0x7b,0x87,0x84,0xc7,0x9b,0x05,0x6b,0xfb, +0xa4,0x05,0x7b,0x04,0x20,0x04,0xaa,0x05,0x7b,0x06,0x27,0x01,0x7b,0x02,0x6b,0x84, +0x84,0xc6,0x03,0x6b,0x85,0x84,0xc6,0x04,0x6b,0x86,0x84,0xc6,0x05,0x6b,0x87,0x84, +0xc6,0x9a,0x6e,0xc4,0xcd,0x9b,0x05,0x27,0x72,0x01,0xc6,0x00,0xc0,0xcd,0x5a,0xc4, +0xcd,0xbf,0x00,0xc7,0x12,0xb6,0x02,0x20,0x04,0xa6,0x04,0x26,0x02,0xa1,0x11,0xb6, +0x9a,0xef,0xfc,0xcd,0xa4,0xbf,0x84,0xae,0xa3,0x1b,0x1e,0xfe,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x02,0xab,0x5b,0x9b,0x05,0x6b,0x04,0xaa,0x05,0x7b,0x02,0x6b,0x84,0x84, +0xc6,0x03,0x6b,0x85,0x84,0xc6,0x04,0x6b,0x86,0x84,0xc6,0x05,0x6b,0x87,0x84,0xc6, +0x16,0x00,0x01,0x35,0x01,0x6b,0x16,0xb6,0xc1,0x00,0x5f,0x72,0x04,0x20,0xc1,0x00, +0x01,0x35,0x06,0x27,0x17,0x3d,0x88,0x88,0x88,0x88,0x88,0x81,0x85,0x85,0x85,0x85, +0x85,0x01,0x7b,0xe8,0x01,0x01,0x35,0x9a,0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84, +0x35,0xa3,0x1f,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x02,0xab,0x5b,0xb4,0x84, +0xc7,0x02,0x7b,0xb5,0x84,0xc7,0x03,0x7b,0xb6,0x84,0xc7,0x04,0x7b,0xb7,0x84,0xc7, +0x05,0x7b,0xd2,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x02,0xab,0x5b,0xa3,0x1e,0xa0, +0x3f,0xa1,0x3f,0xa2,0xb7,0x03,0xa4,0xa2,0xb6,0xa3,0x3f,0x17,0xfd,0xcd,0x5f,0x90, +0xa7,0x00,0x01,0x35,0x5f,0x12,0xb6,0x04,0x6b,0xfc,0xa4,0x04,0x7b,0x02,0x6b,0xb4, +0x84,0xc6,0x03,0x6b,0xb5,0x84,0xc6,0x04,0x6b,0xb6,0x84,0xc6,0x05,0x6b,0xb7,0x84, +0xc6,0xcc,0x84,0x00,0x35,0xcd,0x84,0x00,0x35,0xce,0x84,0x4a,0x35,0xcf,0x84,0x00, +0x35,0x10,0x25,0x20,0xa1,0xf3,0x01,0xc6,0x17,0x26,0x03,0xa1,0x6b,0x01,0xc6,0x40, +0xc6,0xcd,0x1c,0xbe,0x20,0xa6,0x9b,0x6c,0x01,0x22,0x00,0x55,0x6d,0x01,0x23,0x00, +0x55,0x6e,0x01,0x24,0x00,0x55,0x6f,0x01,0x25,0x00,0x55,0x14,0x27,0xc0,0xfc,0xcd, +0x22,0xae,0x6b,0x01,0xc7,0x12,0xb6,0xbb,0x00,0xc7,0x21,0xb6,0xbc,0x00,0xcf,0x1f, +0xbe,0xbd,0x00,0xc7,0x20,0xb6,0x65,0x01,0xcf,0x19,0xbe,0x66,0x01,0xc7,0x1a,0xb6, +0x69,0x01,0xcf,0x17,0xbe,0x6a,0x01,0xc7,0x18,0xb6,0x63,0x01,0xcf,0x15,0xbe,0x64, +0x01,0xc7,0x16,0xb6,0x67,0x01,0xcf,0x13,0xbe,0x68,0x01,0xc7,0x14,0xb6,0x1d,0xe5, +0xcc,0xe5,0x01,0xc7,0x4c,0x1d,0xe5,0xcc,0x01,0x6b,0x01,0xa6,0x45,0x27,0x4a,0x11, +0x27,0x4a,0x0d,0x27,0x4d,0xbb,0x00,0x5f,0x72,0xbd,0x00,0x5f,0x72,0xbc,0x00,0x5f, +0x72,0x70,0x01,0xc7,0x11,0xb6,0x01,0x6b,0x4f,0x88,0x88,0x88,0x88,0x88,0x00,0x00, +0xba,0x42,0x00,0x00,0xb8,0x41,0x0a,0xd7,0x23,0x3c,0x00,0x00,0x80,0x3f,0x81,0x1e, +0xfe,0xcd,0xb3,0xae,0xa4,0x00,0x00,0x35,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x17,0xab, +0x81,0xa4,0x00,0x80,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x81,0x8b, +0x41,0x00,0xa9,0x41,0x1c,0xab,0x5b,0x20,0x80,0x00,0x35,0x21,0x80,0x00,0x35,0x22, +0x80,0x00,0x35,0x23,0x80,0x40,0x35,0xef,0xfc,0xcd,0x30,0xae,0x1e,0xad,0x16,0x7b, +0xef,0xfc,0xcd,0x2c,0xae,0x27,0xad,0x15,0x7b,0xef,0xfc,0xcd,0x28,0xae,0x30,0xad, +0x14,0x7b,0x8a,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x13,0xab,0x5b,0x1e,0xfe,0xcd, +0xe0,0xae,0xa4,0x00,0x01,0x35,0x13,0x6b,0x60,0x20,0xc6,0x14,0x6b,0x61,0x20,0xc6, +0x15,0x6b,0x62,0x20,0xc6,0x16,0x6b,0x63,0x20,0xc6,0x68,0x20,0x26,0x35,0x68,0x20, +0x21,0x35,0x68,0x20,0x52,0x35,0x64,0x20,0xc7,0x0d,0x7b,0x65,0x20,0xc7,0x0e,0x7b, +0x66,0x20,0xc7,0x0f,0x7b,0x67,0x20,0xc7,0x10,0x7b,0x60,0x20,0xdc,0x01,0x55,0x61, +0x20,0xdd,0x01,0x55,0x62,0x20,0xde,0x01,0x55,0x63,0x20,0xdf,0x01,0x55,0xef,0xfc, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x0d,0xab,0x5b,0xfb,0xfd,0xcd,0xe0,0xe3,0xcd,0x5b, +0xe8,0xe3,0xcd,0xf0,0x27,0x1b,0xea,0x72,0x1c,0x7b,0xf7,0x26,0x4a,0xdb,0x01,0xc6, +0xc9,0xe3,0xcc,0x03,0x27,0x4a,0x71,0x01,0xc6,0x84,0x84,0x84,0x84,0x8e,0xc5,0xcd, +0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x0f,0x20,0x69,0xc5, +0xcd,0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x11,0x27,0xf0, +0x01,0xc6,0xf2,0x01,0x5f,0x72,0x04,0x20,0x8a,0xfd,0xcd,0xe0,0xe3,0xcd,0x5b,0xe8, +0xe3,0xcd,0x0c,0x2b,0xff,0xa2,0x11,0x7b,0xfd,0xa0,0x12,0x7b,0x0a,0x2b,0x00,0xa2, +0x11,0x7b,0x04,0xa0,0x12,0x6b,0x18,0x7b,0x11,0x6b,0x17,0x7b,0x17,0x6b,0x60,0x20, +0xc6,0x18,0x6b,0x61,0x20,0xc6,0x19,0x6b,0x62,0x20,0xc6,0x1a,0x6b,0x63,0x20,0xc6, +0x68,0x20,0x26,0x35,0x68,0x20,0x24,0x35,0x64,0x20,0xab,0x00,0x55,0x65,0x20,0xac, +0x00,0x55,0x66,0x20,0xad,0x00,0x55,0x67,0x20,0xae,0x00,0x55,0x68,0x20,0x21,0x35, +0x64,0x20,0xc7,0x05,0x7b,0x65,0x20,0xc7,0x06,0x7b,0x66,0x20,0xc7,0x07,0x7b,0x67, +0x20,0xc7,0x08,0x7b,0x60,0x20,0xaf,0x00,0x55,0x61,0x20,0xb0,0x00,0x55,0x62,0x20, +0xb1,0x00,0x55,0x63,0x20,0xb2,0x00,0x55,0xab,0x00,0x60,0x20,0x55,0xac,0x00,0x61, +0x20,0x55,0xad,0x00,0x62,0x20,0x55,0xae,0x00,0x63,0x20,0x55,0x68,0x20,0x21,0x35, +0x64,0x20,0xc7,0x01,0x7b,0x65,0x20,0xc7,0x02,0x7b,0x66,0x20,0xc7,0x03,0x7b,0x67, +0x20,0xc7,0x04,0x7b,0xaf,0x00,0x64,0x20,0x55,0xb0,0x00,0x65,0x20,0x55,0xb1,0x00, +0x66,0x20,0x55,0xb2,0x00,0x67,0x20,0x55,0x68,0x20,0x64,0x35,0x64,0x20,0xaf,0x00, +0x55,0x65,0x20,0xb0,0x00,0x55,0x66,0x20,0xb1,0x00,0x55,0x67,0x20,0xb2,0x00,0x55, +0x68,0x20,0x21,0x35,0x64,0x20,0xc7,0x09,0x7b,0x65,0x20,0xc7,0x0a,0x7b,0x66,0x20, +0xc7,0x0b,0x7b,0x67,0x20,0xc7,0x0c,0x7b,0x68,0x20,0x22,0x35,0xef,0xfc,0xcd,0x60, +0xae,0xa4,0x00,0x20,0x35,0x7a,0xfc,0xcd,0x1b,0xee,0x72,0x1c,0x7b,0xee,0xe2,0xcc, +0x03,0x26,0x1b,0xea,0x72,0x1c,0x7b,0xef,0xfc,0xcd,0xe0,0xe3,0xcd,0x5b,0xa0,0x3f, +0x1e,0xfe,0xcd,0x5f,0xa4,0x00,0x84,0x35,0xef,0xfc,0xcd,0xa4,0xb7,0x00,0xa9,0x41, +0x09,0xab,0x5b,0x1e,0xfe,0xcd,0xf2,0xae,0xa4,0x00,0xe3,0x35,0x06,0x20,0xf6,0xae, +0xa4,0x00,0xe3,0x35,0x08,0x26,0x4c,0x86,0x01,0xc6,0x05,0x6b,0xfa,0xe3,0xc6,0x06, +0x6b,0xfb,0xe3,0xc6,0x07,0x6b,0xfc,0xe3,0xc6,0x08,0x6b,0xfd,0xe3,0xc6,0x01,0x6b, +0xfe,0xe3,0xc6,0x02,0x6b,0xff,0xe3,0xc6,0x03,0x6b,0x00,0xe4,0xc6,0x04,0x6b,0x01, +0xe4,0xc6,0x8b,0x41,0x00,0xa2,0x41,0x1a,0xa0,0x5b,0x89,0x88,0x81,0xa0,0xb7,0xa1, +0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0xd9,0xe0, +0xcc,0x03,0xa6,0xd9,0xe0,0xcc,0x02,0xa6,0x81,0x20,0x4c,0x81,0x84,0x84,0x84,0x84, +0xef,0xfc,0xcd,0x10,0xae,0xa4,0x00,0x84,0x35,0xa1,0x1e,0x1e,0xfe,0xcd,0x20,0xad, +0x5b,0x10,0x84,0xc7,0x01,0x7b,0x11,0x84,0xc7,0x02,0x7b,0x12,0x84,0xc7,0x03,0x7b, +0x13,0x84,0xc7,0x04,0x7b,0x02,0x6b,0x7f,0xa4,0x02,0x7b,0xef,0xfc,0xcd,0x40,0xad, +0x5b,0xd8,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x5b,0xa0,0xb7,0x03,0xa4, +0xa0,0xb6,0xa1,0x3f,0xa2,0x3f,0xa3,0x3f,0x1e,0xfe,0xcd,0x5d,0xad,0x5b,0x01,0x6b, +0x10,0x84,0xc6,0x02,0x6b,0x11,0x84,0xc6,0x03,0x6b,0x12,0x84,0xc6,0x04,0x6b,0x13, +0x84,0xc6,0xd2,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x5b,0x8c,0xfc,0xcd, +0x14,0xa6,0x6a,0xe1,0xcd,0x0b,0x6b,0x04,0xa6,0x5d,0xe1,0xcc,0x03,0x26,0x08,0xa0, +0x58,0xe1,0xcc,0x03,0x26,0x04,0xa0,0x55,0xe1,0xcc,0x03,0x26,0x02,0xa0,0x17,0x27, +0x02,0xa0,0x1b,0x20,0x4c,0x1e,0x20,0x06,0xa6,0x22,0x20,0x02,0xa6,0x26,0x20,0x07, +0xa6,0x0c,0x27,0x10,0xa0,0x0c,0x27,0x08,0xa0,0x0c,0x27,0x04,0xa0,0x34,0x27,0x02, +0xa0,0x3a,0x27,0x02,0xa0,0x23,0x24,0x0b,0x7b,0x20,0xa1,0xf3,0x01,0xc6,0x07,0x6b, +0x60,0x20,0xc6,0x08,0x6b,0x61,0x20,0xc6,0x09,0x6b,0x62,0x20,0xc6,0x0a,0x6b,0x63, +0x20,0xc6,0x68,0x20,0x26,0x35,0x68,0x20,0x21,0x35,0x68,0x20,0x52,0x35,0x64,0x20, +0x00,0x35,0x65,0x20,0x00,0x35,0x66,0x20,0x80,0x35,0x67,0x20,0x00,0x35,0x9d,0x9d, +0x68,0x20,0x27,0x35,0x60,0x20,0xb7,0x00,0x55,0x61,0x20,0xb8,0x00,0x55,0x62,0x20, +0xb9,0x00,0x55,0x63,0x20,0xba,0x00,0x55,0x68,0x20,0x61,0x35,0x68,0x20,0x52,0x35, +0xef,0xfc,0xcd,0x64,0xae,0xa4,0x00,0x20,0x35,0x6a,0xe1,0xcd,0x0b,0x7b,0x68,0x20, +0x22,0x35,0x60,0x20,0xc7,0x07,0x7b,0x61,0x20,0xc7,0x08,0x7b,0x62,0x20,0xc7,0x09, +0x7b,0x63,0x20,0xc7,0x0a,0x7b,0x88,0x88,0x88,0x88,0x81,0x64,0x20,0x00,0x35,0x65, +0x20,0x00,0x35,0x66,0x20,0x00,0x35,0x81,0x84,0xef,0xfc,0xcd,0x10,0xae,0xa4,0x00, +0x84,0x35,0xa2,0xb7,0x55,0xaa,0xa2,0xb6,0xa3,0xb7,0x55,0xaa,0xa3,0xb6,0xa1,0xb7, +0x55,0xaa,0xa1,0xb6,0x8c,0xfc,0xcd,0x18,0xa6,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f, +0xa3,0xb7,0x01,0x7b,0xef,0xfc,0xcd,0x14,0xae,0xa4,0x00,0x84,0x35,0xa0,0xb7,0x3f, +0xa4,0xa0,0xb6,0xa1,0x3f,0xa2,0x3f,0xa3,0x3f,0x8c,0xfc,0xcd,0x18,0xa6,0x1e,0xfe, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x04,0xab,0x5b,0x25,0x24,0x0f,0xa1,0x07,0x7b,0x05, +0xc5,0xcd,0x64,0xa6,0x84,0x84,0x84,0x84,0x69,0xc5,0xcd,0xb3,0x00,0x3b,0xb4,0x00, +0x3b,0xb5,0x00,0x3b,0xb6,0x00,0x3b,0x0f,0x20,0x8e,0xc5,0xcd,0xb3,0x00,0x3b,0xb4, +0x00,0x3b,0xb5,0x00,0x3b,0xb6,0x00,0x3b,0x11,0x26,0x4a,0x70,0x01,0xc6,0x14,0x84, +0x0f,0x35,0x15,0x84,0x00,0x35,0x16,0x84,0x00,0x35,0x17,0x84,0x00,0x35,0x04,0x6b, +0x60,0x20,0xc6,0x05,0x6b,0x61,0x20,0xc6,0x06,0x6b,0x62,0x20,0xc6,0x07,0x6b,0x63, +0x20,0xc6,0x68,0x20,0xc7,0x4a,0x9d,0x9d,0x68,0x20,0xc7,0x27,0xa6,0x68,0x20,0x52, +0x35,0x64,0x20,0x05,0x35,0x65,0x20,0xf5,0x35,0x66,0x20,0xe1,0x35,0x67,0x20,0x00, +0x35,0x60,0x20,0xb7,0x00,0x55,0x61,0x20,0xb8,0x00,0x55,0x62,0x20,0xb9,0x00,0x55, +0x63,0x20,0xba,0x00,0x55,0xb3,0x00,0x60,0x20,0x55,0xb4,0x00,0x61,0x20,0x55,0xb5, +0x00,0x62,0x20,0x55,0xb6,0x00,0x63,0x20,0x55,0x68,0x20,0x26,0x35,0x68,0x20,0x21, +0x35,0x68,0x20,0x52,0x35,0x64,0x20,0x00,0x35,0x65,0x20,0x00,0x35,0x66,0x20,0x80, +0x35,0x67,0x20,0x00,0x35,0x68,0x20,0x27,0x35,0xb7,0x00,0x60,0x20,0x55,0xb8,0x00, +0x61,0x20,0x55,0xb9,0x00,0x62,0x20,0x55,0xba,0x00,0x63,0x20,0x55,0x68,0x20,0x52, +0x35,0x64,0x20,0xc7,0x04,0x7b,0x65,0x20,0xc7,0x05,0x7b,0x66,0x20,0xc7,0x06,0x7b, +0x67,0x20,0xc7,0x07,0x7b,0x68,0x20,0xc7,0x4a,0x68,0x20,0xc7,0x22,0xa6,0x60,0x20, +0xc7,0x08,0x7b,0x61,0x20,0xc7,0x09,0x7b,0x62,0x20,0xc7,0x0a,0x7b,0x63,0x20,0xc7, +0x0b,0x7b,0x68,0x20,0x52,0x35,0x10,0x84,0x02,0x35,0x11,0x84,0x55,0x35,0x12,0x84, +0x55,0x35,0x13,0x84,0x55,0x35,0x01,0x6b,0x02,0xa6,0x09,0xe0,0xcd,0x67,0x20,0x28, +0x35,0x09,0x20,0x01,0xa6,0x09,0xe0,0xcd,0x67,0x20,0x14,0x35,0x0b,0x25,0x02,0xa2, +0x08,0x7b,0xdd,0xa0,0x09,0x7b,0x1e,0x20,0x4f,0x09,0xe0,0xcd,0x67,0x20,0x0a,0x35, +0x0a,0x25,0x04,0xa2,0x08,0x7b,0xd9,0xa0,0x09,0x7b,0x88,0x81,0x52,0x01,0xce,0x53, +0x01,0xc6,0xef,0xfc,0xcd,0x81,0x84,0x84,0xef,0xfc,0xcd,0x0c,0xae,0xa4,0x00,0x41, +0x35,0x0e,0xfd,0xcd,0x41,0x4a,0x01,0xc9,0x41,0x4b,0x01,0xcb,0x17,0xad,0x08,0xae, +0xa4,0x00,0x41,0x35,0x0e,0xfd,0xcd,0x5c,0x01,0x26,0x4c,0x26,0xad,0x04,0xae,0xa4, +0x00,0x41,0x35,0x0e,0xfd,0xcd,0x41,0x48,0x01,0xc9,0x41,0x49,0x01,0xcb,0x41,0x01, +0xe2,0x72,0x41,0x02,0xe0,0x72,0x50,0x01,0xce,0x51,0x01,0xc6,0xef,0xfc,0xcd,0x5f, +0xa4,0x00,0x41,0x35,0x0e,0xfd,0xcd,0x5c,0x01,0x26,0x4c,0x41,0x01,0xe2,0x72,0x41, +0x02,0xe0,0x72,0x50,0x01,0xce,0x51,0x01,0xc6,0x02,0x6b,0x55,0x01,0xc6,0x01,0x6b, +0x54,0x01,0xc6,0x88,0x88,0x81,0x58,0x01,0xce,0x59,0x01,0xc6,0xef,0xfc,0xcd,0x81, +0x41,0x54,0x01,0xc9,0x41,0x55,0x01,0xcb,0x46,0x54,0x4c,0x01,0xce,0x4d,0x01,0xc6, +0x81,0x54,0x01,0xce,0x55,0x01,0xc6,0xef,0xfc,0xcd,0x81,0x8c,0xfc,0xcd,0x10,0xa6, +0x0e,0xfd,0xcd,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81,0x84,0x84,0x84,0x84, +0x84,0x84,0x7c,0x83,0x00,0x35,0x7d,0x83,0x00,0x35,0x7e,0x83,0x0f,0x35,0x7f,0x83, +0xff,0x35,0xef,0xfc,0xcd,0x6c,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x23,0xad, +0x5b,0x2e,0xad,0x43,0xad,0xef,0xfc,0xcd,0x2d,0xad,0x5b,0x0e,0xfd,0xcd,0x4e,0xad, +0x0d,0x20,0x48,0xad,0x39,0xad,0x5b,0x0e,0xfd,0xcd,0x54,0x01,0xce,0x55,0x01,0xc6, +0x10,0x26,0x4a,0x47,0x01,0xc6,0xef,0xfc,0xcd,0x68,0xae,0xa4,0x00,0x83,0x35,0xd8, +0xfd,0xcd,0x57,0xad,0x5b,0x62,0xad,0x6d,0xad,0x5e,0xad,0x5b,0x0e,0xfd,0xcd,0x75, +0xad,0x64,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x6f,0xad,0x5b,0x7a,0xad,0x41, +0x5a,0x01,0xc9,0x41,0x5b,0x01,0xcb,0x05,0xee,0x72,0x06,0x7b,0xef,0xfc,0xcd,0xb5, +0xdd,0xcd,0x5b,0x0e,0xfd,0xcd,0x05,0xee,0x72,0x06,0x7b,0xef,0xfc,0xcd,0x60,0xae, +0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0xb5,0xdd,0xcd,0x5b,0xbd,0xdd,0xcd,0x41,0x5a, +0x01,0xc9,0x41,0x5b,0x01,0xcb,0xe1,0xdd,0xcd,0xb5,0xdd,0xcd,0x5b,0x0e,0xfd,0xcd, +0xe1,0xdd,0xcd,0x5c,0xae,0xa4,0x00,0x83,0x35,0x0e,0xfd,0xcd,0x46,0x54,0x4c,0x01, +0xce,0x4d,0x01,0xc6,0x05,0xef,0x72,0x06,0x6b,0x4a,0x5a,0x01,0x26,0x4d,0x58,0x01, +0xce,0x59,0x01,0xc6,0x10,0x20,0x06,0x6b,0x59,0x01,0xc6,0x05,0x6b,0x58,0x01,0xc6, +0x0c,0x26,0x4a,0x47,0x01,0xc6,0x88,0x88,0x88,0x88,0x88,0x88,0x81,0x50,0x01,0xce, +0x51,0x01,0xc6,0xef,0xfc,0xcd,0x81,0x58,0x01,0xce,0x59,0x01,0xc6,0xef,0xfc,0xcd, +0x81,0x4d,0x41,0x4a,0x01,0xc9,0x41,0x4b,0x01,0xcb,0x81,0x41,0x54,0x01,0xc9,0x41, +0x55,0x01,0xcb,0x46,0x54,0x4c,0x01,0xce,0x4d,0x01,0xc6,0x81,0x0e,0xfd,0xcd,0x41, +0xea,0x01,0xc2,0x41,0xeb,0x01,0xc0,0x31,0xad,0x81,0x4d,0x41,0xea,0x01,0xc2,0x41, +0xeb,0x01,0xc0,0x41,0x48,0x01,0xc9,0x41,0x49,0x01,0xcb,0x45,0xad,0x81,0x54,0x01, +0xce,0x55,0x01,0xc6,0xef,0xfc,0xcd,0x81,0x8c,0xfc,0xcd,0x10,0xa6,0x0e,0xfd,0xcd, +0x81,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81,0x8b,0x41,0x00,0xa9,0x41,0x0e,0xab, +0x5b,0x98,0x83,0x00,0x35,0x99,0x83,0x00,0x35,0x9a,0x83,0x00,0x35,0x9b,0x83,0x18, +0x35,0xef,0xfc,0xcd,0x3c,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x25,0xad,0x5b, +0x30,0xad,0x67,0xad,0xef,0xfc,0xcd,0x2f,0xad,0x5b,0x0e,0xfd,0xcd,0x72,0xad,0x0d, +0x20,0x4a,0xad,0x3b,0xad,0x5b,0x0e,0xfd,0xcd,0x54,0x01,0xce,0x55,0x01,0xc6,0x10, +0x26,0x4a,0x47,0x01,0xc6,0xef,0xfc,0xcd,0x38,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd, +0xcd,0x59,0xad,0x5b,0x64,0xad,0x6f,0xad,0x60,0xad,0x5b,0x0e,0xfd,0xcd,0x77,0xad, +0x34,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x71,0xad,0x5b,0x7c,0xad,0x41,0x5a, +0x01,0xc9,0x41,0x5b,0x01,0xcb,0x07,0xee,0x72,0x08,0x7b,0xef,0xfc,0xcd,0x58,0xdc, +0xcd,0x5b,0x0e,0xfd,0xcd,0x07,0xee,0x72,0x08,0x7b,0xef,0xfc,0xcd,0x30,0xae,0xa4, +0x00,0x83,0x35,0xd8,0xfd,0xcd,0x58,0xdc,0xcd,0x5b,0x60,0xdc,0xcd,0x41,0x5a,0x01, +0xc9,0x41,0x5b,0x01,0xcb,0xb0,0xdc,0xcd,0x58,0xdc,0xcd,0x5b,0x0e,0xfd,0xcd,0xb0, +0xdc,0xcd,0x2c,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x58,0xdc,0xcd,0x5b,0x60, +0xdc,0xcd,0x41,0x56,0x01,0xc9,0x41,0x57,0x01,0xcb,0x69,0xdc,0xcd,0x58,0xdc,0xcd, +0x5b,0x0e,0xfd,0xcd,0x69,0xdc,0xcd,0x10,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd, +0x58,0xdc,0xcd,0x5b,0x60,0xdc,0xcd,0x4a,0x5a,0x01,0x26,0xa6,0xdc,0xcd,0x0d,0xee, +0x72,0x0e,0x7b,0xef,0xfc,0xcd,0x58,0xdc,0xcd,0x5b,0x0e,0xfd,0xcd,0x4a,0x5a,0x01, +0x26,0x73,0xdc,0xcd,0x0c,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x58,0xdc,0xcd, +0x5b,0x60,0xdc,0xcd,0x0d,0xee,0x72,0x0e,0x7b,0xef,0xfc,0xcd,0x58,0xdc,0xcd,0x5b, +0x87,0xdc,0xcd,0x08,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x58,0xdc,0xcd,0x5b, +0x60,0xdc,0xcd,0x4a,0x5a,0x01,0x26,0xa6,0xdc,0xcd,0x0d,0xee,0x72,0x0e,0x7b,0xef, +0xfc,0xcd,0x58,0xdc,0xcd,0x5b,0x0e,0xfd,0xcd,0x4a,0x5a,0x01,0x26,0x73,0xdc,0xcd, +0x04,0xae,0xa4,0x00,0x83,0x35,0xd8,0xfd,0xcd,0x58,0xdc,0xcd,0x5b,0x60,0xdc,0xcd, +0x0d,0xee,0x72,0x0e,0x7b,0xef,0xfc,0xcd,0x58,0xdc,0xcd,0x5b,0x87,0xdc,0xcd,0x40, +0xae,0xa4,0x00,0x83,0x35,0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x0f,0xa4,0xa2,0xb6,0x0e, +0xfd,0xcd,0x05,0xee,0x72,0x06,0x7b,0xef,0xfc,0xcd,0x28,0xae,0xa4,0x00,0x83,0x35, +0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x1f,0xa4,0xa2,0xb6,0x0e,0xfd,0xcd,0x4c,0x01,0xce, +0x4d,0x01,0xc6,0x78,0x84,0xc7,0x09,0x7b,0x79,0x84,0xc7,0x0a,0x7b,0x7a,0x84,0xc7, +0x0b,0x7b,0x7b,0x84,0xc7,0x0c,0x7b,0x07,0xef,0x72,0x08,0x6b,0x4a,0x5a,0x01,0x26, +0x4d,0x58,0x01,0xce,0x59,0x01,0xc6,0x06,0x6b,0x4f,0x01,0xc6,0x05,0x6b,0x4e,0x01, +0xc6,0x0a,0x6b,0x05,0xaa,0x0a,0x7b,0x20,0x20,0x08,0x6b,0x59,0x01,0xc6,0x07,0x6b, +0x58,0x01,0xc6,0x05,0xef,0x72,0x06,0x6b,0x59,0x48,0x4e,0x01,0xce,0x4f,0x01,0xc6, +0x0a,0x6b,0x01,0xaa,0x0a,0x7b,0x1f,0x26,0x4a,0x47,0x01,0xc6,0x09,0x6b,0x80,0xaa, +0x09,0x7b,0x06,0x26,0x04,0xa1,0x6b,0x01,0xc6,0x09,0x6b,0x20,0xa6,0x0a,0x6b,0x0b, +0x6b,0x0c,0x6b,0x4f,0x0d,0x6b,0x0e,0xef,0x72,0x58,0x01,0xc9,0x41,0x59,0x01,0xcb, +0x52,0x01,0xce,0x53,0x01,0xc6,0x8b,0x41,0x00,0xa2,0x41,0x0e,0xa0,0x5b,0x81,0x84, +0x84,0x84,0x84,0xe7,0x01,0x01,0x35,0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35, +0xa0,0x16,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0x01,0x6b,0xe3, +0xa4,0x01,0x7b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6, +0x84,0xc6,0x04,0x6b,0xb7,0x84,0xc6,0x30,0x25,0x20,0xa1,0xf3,0x01,0xc6,0xef,0xfc, +0xcd,0x78,0xae,0xa4,0x00,0x84,0x35,0xd8,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01, +0xab,0x5b,0xa0,0xb7,0x03,0xa4,0xa0,0xb6,0xa1,0xb7,0xc0,0xa4,0xa1,0xb6,0xa2,0x3f, +0xa3,0x3f,0x8c,0xfc,0xcd,0x16,0xa6,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0x00, +0x62,0x01,0x55,0x01,0x6b,0xfc,0xa4,0x01,0x7b,0x02,0x6b,0x3f,0xa4,0x02,0x7b,0x01, +0x6b,0x78,0x84,0xc6,0x02,0x6b,0x79,0x84,0xc6,0x03,0x6b,0x7a,0x84,0xc6,0x04,0x6b, +0x7b,0x84,0xc6,0xef,0xfc,0xcd,0x74,0xae,0xa4,0x00,0x84,0x35,0x0e,0xfd,0xcd,0x45, +0x01,0xce,0x46,0x01,0xc6,0xef,0xfc,0xcd,0x70,0xae,0xa4,0x00,0x84,0x35,0x0e,0xfd, +0xcd,0x43,0x01,0xce,0x44,0x01,0xc6,0xef,0xfc,0xcd,0x6c,0xae,0xa4,0x00,0x84,0x35, +0x0e,0xfd,0xcd,0x41,0x01,0xce,0x42,0x01,0xc6,0xef,0xfc,0xcd,0x68,0xae,0xa4,0x00, +0x84,0x35,0x0e,0xfd,0xcd,0x3f,0x01,0xce,0x40,0x01,0xc6,0xef,0xfc,0xcd,0x64,0xae, +0xa4,0x00,0x84,0x35,0x0e,0xfd,0xcd,0x3d,0x01,0xce,0x3e,0x01,0xc6,0x12,0x20,0x64, +0x84,0x00,0x35,0x65,0x84,0x00,0x35,0x66,0x84,0x02,0x35,0x67,0x84,0xcb,0x35,0x12, +0x25,0x02,0xa2,0x3d,0x01,0xc6,0xcb,0xa0,0x3e,0x01,0xc6,0x1e,0x26,0x02,0xa1,0xee, +0x01,0xc6,0x25,0x26,0x03,0xa1,0x70,0x01,0xc6,0x2c,0x24,0x20,0xa1,0xf3,0x01,0xc6, +0xef,0xfc,0xcd,0x60,0xae,0xa4,0x00,0x84,0x35,0x0e,0xfd,0xcd,0x3b,0x01,0xce,0x3c, +0x01,0xc6,0xef,0xfc,0xcd,0x5c,0xae,0xa4,0x00,0x84,0x35,0x0e,0xfd,0xcd,0x39,0x01, +0xce,0x3a,0x01,0xc6,0xef,0xfc,0xcd,0x58,0xae,0xa4,0x00,0x84,0x35,0x0e,0xfd,0xcd, +0x37,0x01,0xce,0x38,0x01,0xc6,0x88,0x88,0x88,0x88,0x81,0xa4,0xc6,0x92,0xa5,0xbf, +0xa4,0xb7,0x81,0xa4,0xd6,0x92,0xa5,0x3f,0xa4,0xb7,0x81,0x84,0x45,0x01,0xcf,0x3d, +0x01,0xce,0x46,0x01,0xc7,0x3e,0x01,0xc6,0x3d,0x01,0xcf,0x3e,0x01,0xc7,0x4a,0x5a, +0x01,0x26,0x4d,0x59,0x48,0x65,0x01,0xce,0x66,0x01,0xc6,0x0b,0x20,0x0e,0x26,0x4d, +0x65,0x01,0xce,0x66,0x01,0xc6,0x0b,0x26,0x4a,0x47,0x01,0xc6,0x43,0x01,0xcf,0x3b, +0x01,0xce,0x44,0x01,0xc7,0x3c,0x01,0xc6,0x3c,0x01,0x5f,0x72,0x3b,0x01,0x5f,0x72, +0x41,0x01,0xcf,0x39,0x01,0xce,0x42,0x01,0xc7,0x3a,0x01,0xc6,0x39,0x01,0xcf,0x3a, +0x01,0xc7,0x4a,0x5a,0x01,0x26,0x4d,0xfa,0x26,0x5a,0x90,0x46,0x54,0x06,0x27,0x62, +0x01,0xce,0x90,0x63,0x01,0xce,0x64,0x01,0xc6,0x3f,0x01,0xcf,0x37,0x01,0xce,0x40, +0x01,0xc7,0x38,0x01,0xc6,0x38,0x01,0x5f,0x72,0x37,0x01,0x5f,0x72,0x62,0x01,0x5f, +0x72,0x04,0x26,0x04,0xa1,0xee,0x01,0xc6,0x0b,0x26,0x03,0xa1,0x0f,0x20,0x52,0x01, +0x5f,0x72,0x53,0x01,0x23,0x35,0x19,0x26,0x03,0xa1,0xee,0x01,0xc6,0x20,0x26,0x03, +0xa1,0x15,0x24,0x70,0x01,0xc6,0x20,0xa1,0xf3,0x01,0xc6,0x65,0x01,0x4a,0x01,0x55, +0x66,0x01,0x4b,0x01,0x55,0x69,0x01,0x4e,0x01,0x55,0x6a,0x01,0x4f,0x01,0x55,0x63, +0x01,0x48,0x01,0x55,0x64,0x01,0x49,0x01,0x55,0x67,0x01,0x4c,0x01,0x55,0x68,0x01, +0x4d,0x01,0x55,0x8e,0xd6,0xcc,0xbe,0xd8,0xcd,0xd3,0xa9,0x41,0x00,0xab,0x52,0x1c, +0xae,0x01,0x7b,0xef,0xfc,0xcd,0x5e,0xae,0xa4,0x00,0x01,0x35,0x46,0xfc,0xcd,0xa4, +0xb7,0xd2,0xa9,0x41,0xfc,0xab,0x52,0x1c,0xae,0x01,0x7b,0x5d,0x01,0xc7,0xbe,0xd8, +0xcd,0xd2,0xa9,0x41,0xfb,0xab,0x52,0x1c,0xae,0x01,0x7b,0x5c,0x01,0xc7,0xbe,0xd8, +0xcd,0xd2,0xa9,0x41,0xfa,0xab,0x52,0x1c,0xae,0x01,0x7b,0x5b,0x01,0xc7,0xa4,0xd6, +0x92,0xa5,0x3c,0x5a,0x01,0xc7,0xb6,0xd8,0xcd,0xd2,0xa9,0x41,0xf8,0xab,0x52,0x1c, +0xae,0x01,0x7b,0x58,0x01,0x5f,0x72,0x59,0x01,0x01,0x35,0x57,0x01,0xc7,0xa4,0xd6, +0x92,0xa5,0x3c,0x56,0x01,0xc7,0xb6,0xd8,0xcd,0xd2,0xa9,0x41,0xf4,0xab,0x52,0x1c, +0xae,0x01,0x7b,0x55,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x54,0x01,0xc7,0xb6,0xd8, +0xcd,0xd2,0xa9,0x41,0xf2,0xab,0x52,0x1c,0xae,0x01,0x7b,0x53,0x01,0xc7,0xa4,0xd6, +0x92,0xa5,0x3c,0x52,0x01,0xc7,0xb6,0xd8,0xcd,0xd2,0xa9,0x41,0xf0,0xab,0x52,0x1c, +0xae,0x01,0x7b,0x51,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x50,0x01,0xc7,0xb6,0xd8, +0xcd,0xd2,0xa9,0x41,0xee,0xab,0x52,0x1c,0xae,0x01,0x7b,0x4f,0x01,0xc7,0xa4,0xd6, +0x92,0xa5,0x3c,0x4e,0x01,0xc7,0xb6,0xd8,0xcd,0xd2,0xa9,0x41,0xec,0xab,0x52,0x1c, +0xae,0x01,0x7b,0x4d,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x4c,0x01,0xc7,0xb6,0xd8, +0xcd,0xd2,0xa9,0x41,0xea,0xab,0x52,0x1c,0xae,0x01,0x7b,0x4b,0x01,0xc7,0xa4,0xd6, +0x92,0xa5,0x3c,0x4a,0x01,0xc7,0xb6,0xd8,0xcd,0xd2,0xa9,0x41,0xe8,0xab,0x52,0x1c, +0xae,0x01,0x7b,0x49,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x48,0x01,0xc7,0xb6,0xd8, +0xcd,0xd2,0xa9,0x41,0xe6,0xab,0x52,0x1c,0xae,0x01,0x7b,0x47,0x01,0xc7,0xbe,0xd8, +0xcd,0xd2,0xa9,0x41,0xe5,0xab,0x52,0x1c,0xae,0x01,0x7b,0xdd,0xd7,0xcc,0x05,0xd8, +0xcc,0x03,0x27,0x02,0xa1,0xdd,0xd7,0xcc,0x03,0x26,0x03,0xa1,0x70,0x01,0xc6,0x62, +0x01,0xc7,0x29,0xb6,0x5e,0x01,0x2a,0x00,0x55,0x5f,0x01,0x2b,0x00,0x55,0x60,0x01, +0x2c,0x00,0x55,0x61,0x01,0x2d,0x00,0x55,0x5c,0x01,0xc7,0x13,0xb6,0x13,0xb6,0x5a, +0x01,0xcf,0x22,0xbe,0x5b,0x01,0xc7,0x23,0xb6,0x58,0x01,0xcf,0x20,0xbe,0x59,0x01, +0xc7,0x21,0xb6,0x56,0x01,0xcf,0x1e,0xbe,0x57,0x01,0xc7,0x1f,0xb6,0x54,0x01,0xcf, +0x1c,0xbe,0x55,0x01,0xc7,0x1d,0xb6,0x52,0x01,0xcf,0x26,0xbe,0x53,0x01,0xc7,0x27, +0xb6,0x50,0x01,0xcf,0x24,0xbe,0x51,0x01,0xc7,0x25,0xb6,0x4e,0x01,0xcf,0x18,0xbe, +0x4f,0x01,0xc7,0x19,0xb6,0x4c,0x01,0xcf,0x14,0xbe,0x4d,0x01,0xc7,0x15,0xb6,0x4a, +0x01,0xcf,0x1a,0xbe,0x4b,0x01,0xc7,0x1b,0xb6,0x48,0x01,0xcf,0x16,0xbe,0x49,0x01, +0xc7,0x17,0xb6,0x47,0x01,0xc7,0x28,0xb6,0xa5,0xd6,0xcc,0x03,0x24,0x1d,0xa1,0x11, +0xb6,0x09,0x27,0x11,0x3d,0x01,0x6b,0x4a,0x11,0xb6,0x88,0x00,0xf0,0x70,0x1c,0x05, +0x01,0x01,0x03,0x00,0x03,0x00,0x8f,0x00,0x46,0x00,0x1b,0x00,0xaa,0x01,0x1e,0x03, +0x00,0x07,0x00,0x03,0x50,0x05,0x01,0x00,0x60,0xa0,0x18,0x05,0x01,0x01,0x06,0x00, +0x03,0x00,0x70,0x00,0x40,0x00,0x18,0x00,0xb0,0x01,0x1b,0x03,0x00,0x07,0x00,0x03, +0x50,0x05,0x01,0x00,0xe0,0x1b,0xfa,0x04,0x01,0x00,0x06,0x00,0x03,0x00,0x80,0x00, +0x48,0x00,0x1c,0x00,0x90,0x01,0x3f,0x03,0x90,0x06,0x20,0x03,0x00,0x05,0x01,0x00, +0xc0,0x5f,0x3b,0x04,0x00,0x01,0x06,0x00,0x03,0x00,0x20,0x00,0x30,0x00,0x14,0x00, +0xa0,0x00,0x37,0x03,0xa0,0x05,0x20,0x03,0x00,0x05,0x01,0x00,0xe0,0x12,0xbd,0x04, +0x01,0x00,0x07,0x00,0x03,0x00,0x80,0x00,0x40,0x00,0x1b,0x00,0x80,0x01,0x1e,0x03, +0x80,0x06,0x00,0x03,0x00,0x05,0x01,0x00,0x90,0x69,0x11,0x04,0x00,0x01,0x07,0x00, +0x03,0x00,0x20,0x00,0x30,0x00,0x13,0x00,0xa0,0x00,0x16,0x03,0xa0,0x05,0x00,0x03, +0x00,0x05,0x01,0x00,0x40,0xd2,0xdf,0x03,0x00,0x00,0x06,0x00,0x03,0x00,0x88,0x00, +0x18,0x00,0x23,0x00,0x40,0x01,0x26,0x03,0x40,0x05,0x00,0x03,0x00,0x04,0x01,0x00, +0xf0,0xfb,0x02,0x02,0x01,0x01,0x08,0x00,0x06,0x00,0x70,0x00,0x10,0x00,0x1f,0x00, +0xf0,0x00,0x05,0x02,0x40,0x04,0xe0,0x01,0x50,0x03,0x01,0x00,0x00,0x5a,0x62,0x02, +0x01,0x01,0x04,0x00,0x01,0x00,0x80,0x00,0x28,0x00,0x1b,0x00,0x00,0x01,0x74,0x02, +0x20,0x04,0x58,0x02,0x20,0x03,0x01,0x00,0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00, +0x01,0x00,0x28,0x00,0xe0,0x06,0x19,0x00,0xe4,0x07,0xee,0x02,0xe4,0x0c,0xd0,0x02, +0x00,0x05,0x01,0x00,0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00,0x01,0x00,0x28,0x00, +0x74,0x09,0x19,0x00,0x78,0x0a,0xee,0x02,0x78,0x0f,0xd0,0x02,0x00,0x05,0x01,0x00, +0x40,0x5f,0x8a,0x03,0x01,0x01,0x05,0x00,0x01,0x00,0x28,0x00,0xe0,0x06,0x19,0x00, +0xe4,0x07,0xee,0x02,0xe4,0x0c,0xd0,0x02,0x00,0x05,0x01,0x00,0x10,0xf7,0x6c,0x04, +0x01,0x01,0x05,0x00,0x01,0x00,0x2c,0x00,0x58,0x00,0x29,0x00,0x18,0x01,0x65,0x04, +0x98,0x08,0x38,0x04,0x80,0x07,0x01,0x00,0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00, +0x01,0x00,0x2c,0x00,0x10,0x02,0x29,0x00,0xd0,0x02,0x65,0x04,0x50,0x0a,0x38,0x04, +0x80,0x07,0x01,0x00,0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00,0x01,0x00,0x2c,0x00, +0x7e,0x02,0x29,0x00,0x3e,0x03,0x65,0x04,0xbe,0x0a,0x38,0x04,0x80,0x07,0x01,0x00, +0x20,0xee,0xd9,0x08,0x01,0x01,0x05,0x00,0x01,0x00,0x2c,0x00,0x10,0x02,0x29,0x00, +0xd0,0x02,0x65,0x04,0x50,0x0a,0x38,0x04,0x80,0x07,0x01,0x00,0x80,0xf9,0x37,0x03, +0x00,0x00,0x05,0x00,0x01,0x00,0x80,0x00,0x18,0x00,0x2c,0x00,0x20,0x01,0x71,0x02, +0xc0,0x06,0x40,0x02,0xa0,0x05,0x01,0x01,0xc0,0xfc,0x9b,0x01,0x00,0x00,0x03,0x00, +0x01,0x00,0x7e,0x00,0x18,0x00,0x16,0x00,0x20,0x01,0x71,0x02,0xc0,0x06,0x20,0x01, +0xa0,0x05,0x00,0x00,0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00,0x01,0x00,0x2c,0x00, +0x10,0x02,0x14,0x00,0xd0,0x02,0x65,0x04,0x50,0x0a,0x1c,0x02,0x80,0x07,0x00,0x00, +0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00,0x01,0x00,0x28,0x00,0xb8,0x01,0x19,0x00, +0xbc,0x02,0xee,0x02,0xbc,0x07,0xd0,0x02,0x00,0x05,0x01,0x00,0xc0,0xfc,0x9b,0x01, +0x00,0x00,0x05,0x00,0x01,0x00,0x40,0x00,0x0c,0x00,0x2c,0x00,0x90,0x00,0x71,0x02, +0x60,0x03,0x40,0x02,0xd0,0x02,0x01,0x00,0x20,0xee,0xd9,0x08,0x01,0x01,0x05,0x00, +0x01,0x00,0x2c,0x00,0x58,0x00,0x29,0x00,0x18,0x01,0x65,0x04,0x98,0x08,0x38,0x04, +0x80,0x07,0x01,0x00,0x80,0xf9,0x37,0x03,0x00,0x00,0x06,0x00,0x07,0x00,0x7c,0x00, +0x20,0x00,0x24,0x00,0x14,0x01,0x0d,0x02,0xb4,0x06,0xe0,0x01,0xa0,0x05,0x01,0x01, +0xc0,0xfc,0x9b,0x01,0x00,0x00,0x03,0x00,0x04,0x00,0x7c,0x00,0x26,0x00,0x12,0x00, +0x14,0x01,0x0d,0x02,0xb4,0x06,0xf0,0x00,0xa0,0x05,0x00,0x00,0x10,0xf7,0x6c,0x04, +0x01,0x01,0x05,0x00,0x01,0x00,0x2c,0x00,0x58,0x00,0x14,0x00,0x18,0x01,0x65,0x04, +0x98,0x08,0x1c,0x02,0x80,0x07,0x00,0x00,0x10,0xf7,0x6c,0x04,0x01,0x01,0x05,0x00, +0x01,0x00,0x28,0x00,0x6e,0x00,0x19,0x00,0x72,0x01,0xee,0x02,0x72,0x06,0xd0,0x02, +0x00,0x05,0x01,0x00,0xc0,0xfc,0x9b,0x01,0x00,0x00,0x06,0x00,0x07,0x00,0x3e,0x00, +0x10,0x00,0x24,0x00,0x8a,0x00,0x0d,0x02,0x5a,0x03,0xe0,0x01,0xd0,0x02,0x01,0x00, +0x80,0x85,0x80,0x01,0x00,0x00,0x02,0x00,0x01,0x00,0x60,0x00,0x10,0x00,0x23,0x00, +0xa0,0x00,0x0d,0x02,0x20,0x03,0xe0,0x01,0x80,0x02,0x01,0x81,0x84,0x8b,0x41,0x00, +0xa9,0x41,0x08,0xab,0x5b,0x09,0x6b,0x01,0x6b,0x4f,0x01,0x20,0x01,0xa6,0x04,0x26, +0xbf,0x01,0xc1,0x05,0x7b,0x0b,0x26,0x04,0xe1,0x72,0xc0,0x01,0xc6,0x08,0x27,0xbf, +0x01,0xc6,0xb7,0x26,0x46,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x02,0xab,0x5b,0x1e, +0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x06,0xab,0x5b,0x06,0x6b,0x30,0x48,0xc6,0x07, +0x6b,0x31,0x48,0xc6,0x08,0x6b,0x32,0x48,0xc6,0x09,0x6b,0x33,0x48,0xc6,0x84,0x84, +0xc0,0x1b,0xcd,0x74,0xae,0x08,0xa6,0x02,0x4b,0x00,0x4b,0x02,0x6b,0x06,0x7b,0x03, +0x6b,0x07,0x7b,0x04,0x6b,0x08,0x7b,0x05,0x6b,0x09,0x7b,0x06,0x6b,0x30,0x48,0xc6, +0x07,0x6b,0x31,0x48,0xc6,0x08,0x6b,0x32,0x48,0xc6,0x09,0x6b,0x33,0x48,0xc6,0x01, +0x6b,0x4f,0x8b,0x41,0x00,0xa2,0x41,0x09,0xa0,0x5b,0xa9,0x20,0x17,0xb6,0x17,0xb7, +0x80,0xaa,0x02,0x7b,0x84,0x84,0xc0,0x1b,0xcd,0x74,0xae,0x20,0xa6,0x14,0x4b,0x88, +0x07,0xab,0x01,0x7b,0xf0,0x25,0x05,0xa1,0x03,0x6b,0x4c,0x9f,0x18,0xe7,0xbf,0x01, +0xd6,0x03,0xee,0x72,0x03,0x6b,0x12,0x26,0x4a,0x02,0x7b,0x84,0x84,0xc0,0x1b,0xcd, +0x74,0xae,0x43,0xa6,0x88,0x02,0x7b,0x07,0x4b,0x25,0x27,0x02,0x7b,0x01,0x6b,0x52, +0x05,0xae,0xf0,0x24,0x14,0xa1,0x02,0x6b,0x7f,0xa4,0xbf,0x01,0xc6,0x81,0x85,0x85, +0x85,0x4f,0x05,0xc0,0x01,0x07,0x72,0x05,0x20,0x02,0xbf,0x01,0x0f,0x72,0x84,0x84, +0xc0,0x1b,0xcd,0x74,0xae,0x41,0xa6,0x02,0x4b,0x00,0x4b,0x19,0x26,0x60,0xa1,0x60, +0xa4,0xbf,0x01,0xc6,0x84,0x84,0xc0,0x1b,0xcd,0x74,0xae,0x40,0xa6,0x01,0x4b,0x00, +0x4b,0x88,0x88,0x88,0x81,0xa0,0x01,0xc6,0xa0,0x01,0x01,0x35,0x04,0xbf,0x01,0x0d, +0x72,0x84,0x84,0xc0,0x1b,0xcd,0x74,0xae,0x40,0xa6,0x01,0x4b,0x00,0x4b,0xa0,0x01, +0x5f,0x72,0x81,0x85,0x9a,0xef,0xfc,0xcd,0x14,0xae,0xa4,0x00,0x48,0x35,0xa0,0xb7, +0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0x00,0xa3,0x01,0x55,0x10,0x48,0xa4,0x01,0x55,0x11, +0x48,0xa5,0x01,0x55,0x12,0x48,0xa6,0x01,0x55,0x13,0x48,0xa7,0x01,0x55,0x9b,0xcd, +0x25,0x05,0xa1,0x01,0x6b,0x4c,0x01,0x7b,0xd2,0xfd,0xcd,0xa4,0xae,0xa4,0x00,0x01, +0x35,0x8c,0xfc,0xcd,0x48,0x48,0x48,0x9f,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3, +0xb7,0xbf,0x01,0xd6,0x01,0xee,0x72,0x1f,0x20,0xa3,0x01,0xc3,0x01,0x55,0x07,0x26, +0x04,0xa1,0x01,0x6b,0x4f,0x84,0x84,0xa4,0x01,0x5f,0x72,0xa5,0x01,0x5f,0x72,0xa6, +0x01,0x5f,0x72,0xa7,0x01,0x5f,0x72,0xc0,0x1b,0xcd,0x74,0xae,0x4f,0x05,0x4b,0x00, +0x4b,0x88,0x81,0x84,0x8b,0x41,0x00,0xa9,0x41,0x08,0xab,0x5b,0x09,0x6b,0x01,0x6b, +0x85,0x9b,0x1c,0xcd,0x74,0xae,0x10,0xa6,0x05,0x4b,0xc3,0x01,0xc7,0x05,0x7b,0x02, +0x6b,0xb7,0x01,0xc6,0x03,0x6b,0xb8,0x01,0xc6,0x04,0x6b,0xb9,0x01,0xc6,0x05,0x6b, +0xba,0x01,0xc6,0xc2,0x01,0xc7,0x02,0x7b,0xc1,0x01,0xc7,0x03,0x7b,0xc0,0x01,0xc7, +0x04,0x7b,0xbf,0x01,0xc7,0x05,0x7b,0x02,0x6b,0xb3,0x01,0xc6,0x03,0x6b,0xb4,0x01, +0xc6,0x04,0x6b,0xb5,0x01,0xc6,0x05,0x6b,0xb6,0x01,0xc6,0x01,0x6b,0x85,0x9b,0x1c, +0xcd,0x74,0xae,0x18,0xa6,0x08,0x4b,0xc6,0x01,0xc7,0x06,0x7b,0xc5,0x01,0xc7,0x07, +0x7b,0xc4,0x01,0xc7,0x08,0x7b,0xc3,0x01,0xc7,0x09,0x7b,0x06,0x6b,0x1c,0x48,0xc6, +0x07,0x6b,0x1d,0x48,0xc6,0x08,0x6b,0x1e,0x48,0xc6,0x09,0x6b,0x1f,0x48,0xc6,0xc2, +0x01,0xc7,0x06,0x7b,0xc1,0x01,0xc7,0x07,0x7b,0xc0,0x01,0xc7,0x08,0x7b,0xbf,0x01, +0xc7,0x09,0x7b,0x06,0x6b,0x18,0x48,0xc6,0x07,0x6b,0x19,0x48,0xc6,0x08,0x6b,0x1a, +0x48,0xc6,0x09,0x6b,0x1b,0x48,0xc6,0x01,0x6b,0x4f,0x8b,0x41,0x00,0xa2,0x41,0x09, +0xa0,0x5b,0x81,0x85,0x85,0x85,0x85,0x85,0x01,0x7b,0x01,0x6b,0x01,0xa6,0x04,0x26, +0x14,0xa1,0x02,0x7b,0x0a,0x26,0x14,0xa1,0x03,0x7b,0xd1,0x25,0x05,0xa1,0x05,0x6b, +0x4c,0x05,0x7b,0xdd,0x25,0x08,0xa1,0x04,0x6b,0x4c,0x04,0x7b,0xbf,0x01,0x44,0x72, +0x02,0x6b,0x4c,0x02,0x7b,0x05,0x20,0x03,0x6b,0x4c,0x03,0x7b,0x07,0x26,0x01,0xa4, +0xbf,0x01,0xd6,0x05,0xee,0x72,0x04,0x6b,0x4f,0x05,0x6b,0x4f,0x44,0x20,0x4f,0x03, +0x27,0x85,0x85,0x4d,0xc0,0x1b,0xcd,0x74,0xae,0x05,0x4b,0x00,0x4b,0x9a,0x14,0x48, +0xb7,0x01,0x55,0x15,0x48,0xb8,0x01,0x55,0x16,0x48,0xb9,0x01,0x55,0x17,0x48,0xba, +0x01,0x55,0x10,0x48,0xb3,0x01,0x55,0x11,0x48,0xb4,0x01,0x55,0x12,0x48,0xb5,0x01, +0x55,0x13,0x48,0xb6,0x01,0x55,0x9b,0x03,0x6b,0x02,0x6b,0x01,0x6b,0x4f,0x88,0x88, +0x88,0x88,0x88,0x81,0xa4,0x00,0x48,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3, +0xb7,0x81,0x85,0x85,0x85,0x85,0x01,0x7b,0x9a,0xef,0xfc,0xcd,0x0c,0xae,0x0d,0xad, +0x03,0x7b,0x9b,0x01,0x6b,0x01,0xa6,0x04,0x26,0x02,0x7b,0x04,0x26,0x4a,0x03,0x7b, +0xee,0x26,0x02,0x7b,0x06,0x26,0x03,0x7b,0x02,0x6b,0x4a,0x02,0x7b,0x03,0x6b,0x0f, +0x48,0xc6,0x0a,0x20,0x9a,0xef,0xfc,0xcd,0x5f,0x38,0xad,0x04,0x7b,0x9b,0x02,0x6b, +0x32,0xa6,0x01,0x6b,0x03,0x6b,0x4f,0x88,0x88,0x88,0x88,0x81,0x1e,0xfe,0xcd,0xa4, +0xb7,0x00,0xa9,0x41,0x05,0xab,0x81,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x9a, +0xef,0xfc,0xcd,0x04,0xae,0xa4,0x00,0x48,0x35,0xa3,0x15,0xa0,0xb7,0xa1,0xb7,0xa2, +0xb7,0x4f,0xa3,0xb7,0x03,0xaa,0x3f,0xa4,0x08,0x7b,0x9b,0x05,0x6b,0x04,0x48,0xc6, +0x06,0x6b,0x05,0x48,0xc6,0x07,0x6b,0x06,0x48,0xc6,0x08,0x6b,0x07,0x48,0xc6,0x9a, +0xef,0xfc,0xcd,0x5f,0xa4,0x00,0x40,0x35,0xd8,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41, +0x01,0xab,0x5b,0xa3,0x14,0x4f,0xad,0x5b,0xef,0xfc,0xcd,0xa4,0xb7,0x00,0xa9,0x41, +0x01,0xab,0x5b,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0x00,0x9d,0x01,0x55,0x9b, +0x05,0x6b,0x00,0x40,0xc6,0x06,0x6b,0x01,0x40,0xc6,0x07,0x6b,0x02,0x40,0xc6,0x08, +0x6b,0x03,0x40,0xc6,0x9a,0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa3,0x1a, +0xa3,0x19,0x7a,0xcf,0xcd,0x5b,0x9b,0x05,0x6b,0xb4,0x84,0xc6,0x06,0x6b,0xb5,0x84, +0xc6,0x07,0x6b,0xb6,0x84,0xc6,0x08,0x6b,0xb7,0x84,0xc6,0x88,0x88,0x88,0x88,0x88, +0x88,0x88,0x88,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81,0x84, +0x84,0x84,0x84,0x9a,0xef,0xfc,0xcd,0x04,0xae,0xa4,0x00,0x48,0x35,0xa3,0x14,0x11, +0xad,0x5b,0x9b,0x01,0x6b,0x04,0x48,0xc6,0x02,0x6b,0x05,0x48,0xc6,0x03,0x6b,0x06, +0x48,0xc6,0x04,0x6b,0x07,0x48,0xc6,0x9a,0xef,0xfc,0xcd,0x5f,0xa4,0x00,0x40,0x35, +0xa3,0x15,0x34,0xad,0x5b,0x9b,0x01,0x6b,0x00,0x40,0xc6,0x02,0x6b,0x01,0x40,0xc6, +0x03,0x6b,0x02,0x40,0xc6,0x04,0x6b,0x03,0x40,0xc6,0x88,0x88,0x88,0x88,0x81,0x85, +0x85,0x85,0x85,0x4f,0x9a,0xef,0xfc,0xcd,0x04,0xae,0xa4,0x00,0x48,0x35,0xa0,0x3f, +0xa1,0x3f,0xa2,0x3f,0xa3,0xb7,0x30,0xa4,0xa3,0xb6,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7, +0x4f,0xa3,0xb7,0x04,0x7b,0x9b,0x01,0x6b,0x04,0x48,0xc6,0x02,0x6b,0x05,0x48,0xc6, +0x03,0x6b,0x06,0x48,0xc6,0x04,0x6b,0x07,0x48,0xc6,0x9a,0xef,0xfc,0xcd,0x5f,0xa4, +0x00,0x40,0x35,0xa3,0x15,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b, +0x9b,0x01,0x6b,0x00,0x40,0xc6,0x02,0x6b,0x01,0x40,0xc6,0x03,0x6b,0x02,0x40,0xc6, +0x04,0x6b,0x03,0x40,0xc6,0x88,0x88,0x88,0x88,0x81,0x9a,0xd2,0xfc,0xcd,0xa4,0xb7, +0x40,0xa9,0x41,0x00,0xab,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x81,0x8b,0x41, +0x00,0xa9,0x41,0x0d,0xab,0x5b,0x9a,0xef,0xfc,0xcd,0x30,0xae,0xa4,0x00,0x42,0x35, +0xd8,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0x8c,0xfc,0xcd,0x48,0x48, +0x12,0x7b,0xa0,0x3f,0xa1,0x3f,0xa2,0x3f,0xa3,0x00,0x03,0x35,0x9b,0x01,0x6b,0x30, +0x42,0xc6,0x02,0x6b,0x31,0x42,0xc6,0x03,0x6b,0x32,0x42,0xc6,0x04,0x6b,0x33,0x42, +0xc6,0x24,0xcd,0xcc,0x03,0x25,0x06,0xe1,0x72,0xa4,0xd6,0x92,0x02,0xae,0xa5,0xb7, +0x0d,0x7b,0xa4,0xb7,0x0c,0x7b,0x06,0x6b,0x04,0xab,0x06,0x7b,0x67,0xad,0x5c,0x01, +0x24,0x06,0xeb,0x72,0x10,0xee,0x72,0x11,0x7b,0x1e,0xfe,0xcd,0x6f,0xad,0x5b,0x9b, +0xaf,0x25,0x04,0xa1,0x0b,0x6b,0x4c,0x0b,0x7b,0xa4,0xc7,0x92,0xa5,0xbf,0x85,0xa4, +0x00,0x32,0xa4,0xd6,0x92,0x03,0xae,0xa5,0xbf,0xa4,0xb7,0x0e,0xe9,0x72,0x41,0x0f, +0xeb,0x72,0x5f,0x4a,0x07,0x6b,0x4c,0x07,0x7b,0xa4,0x00,0x3b,0x89,0xa4,0x3c,0x02, +0x24,0x97,0xa5,0xbb,0x0b,0xe0,0x72,0x03,0xa6,0xa5,0xbf,0xf3,0xcd,0xcd,0x5b,0x36, +0x25,0x05,0xe1,0x72,0xa4,0xd6,0x92,0x02,0xae,0xa5,0xb7,0x0d,0x7b,0xa4,0xb7,0x0c, +0x7b,0x0b,0x6b,0x07,0x6b,0x08,0x6b,0x09,0x6b,0x0a,0x6b,0x4f,0x74,0x20,0x05,0x6b, +0x4f,0x10,0x6b,0x00,0xa9,0x10,0x7b,0x11,0x6b,0x04,0xab,0x11,0x7b,0xfb,0xcd,0xcd, +0x10,0xee,0x72,0x11,0x7b,0x1e,0xfe,0xcd,0xf3,0xcd,0xcd,0x5b,0x9b,0x07,0x6b,0x4f, +0x08,0x6b,0xa4,0xd6,0x92,0x5c,0x09,0x6b,0xa4,0xd6,0x92,0x01,0xae,0xa5,0xb7,0x0d, +0x7b,0xa4,0xb7,0x0c,0x7b,0x0a,0x6b,0xa4,0xc6,0x92,0xa5,0xb7,0x0d,0x7b,0xa4,0xbf, +0x0c,0xee,0x72,0x8b,0x41,0x00,0xa2,0x41,0x0b,0xa0,0x5b,0x89,0x88,0x81,0x01,0xa6, +0x15,0x00,0xde,0x35,0x14,0x00,0xc0,0x35,0x13,0x00,0xad,0x35,0x12,0x00,0xde,0x35, +0x50,0x18,0xcd,0x81,0x84,0x84,0x84,0x84,0x84,0x7e,0xcb,0xcd,0xac,0x25,0x10,0xa1, +0x04,0x6b,0x4c,0x04,0x7b,0xc2,0x25,0x08,0xa1,0x05,0x6b,0x4c,0x05,0x7b,0xc6,0xcb, +0xcd,0x03,0x27,0x5d,0x03,0x26,0x4d,0x41,0x01,0xe4,0x72,0x41,0x02,0xe4,0x72,0xfa, +0x26,0x5a,0x90,0x59,0x48,0x06,0x27,0x05,0xe6,0x72,0x01,0xa6,0x01,0xef,0x72,0x02, +0x6b,0x5f,0x03,0x7b,0xeb,0xcb,0xcd,0x03,0x20,0x9a,0xad,0x04,0x26,0x05,0x7b,0x08, +0x26,0x04,0x7b,0x05,0x6b,0x4f,0x03,0x6b,0x12,0xe6,0x97,0x04,0xe0,0x72,0x0f,0xa6, +0x04,0x6b,0x4f,0xf5,0x25,0x10,0xa1,0x04,0x6b,0x4c,0x04,0x7b,0x97,0xad,0x04,0x6b, +0x4f,0xc6,0xcb,0xcd,0x7e,0xcb,0xcd,0xa8,0xcb,0xcd,0x88,0x88,0x88,0x88,0x88,0x81, +0xb3,0x84,0x00,0x35,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0x81,0xb0,0x84,0x00, +0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x00,0x35,0x0d,0xad,0xb2,0x84,0x03,0x35,0x13, +0xad,0xb2,0x84,0x02,0x35,0x19,0xad,0xb2,0x84,0x00,0x35,0xb3,0x84,0x00,0x35,0x81, +0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x00,0x35,0xb3,0x84,0x00,0x35, +0x81,0x01,0xad,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x01,0x35,0xb3, +0x84,0x00,0x35,0x13,0xad,0x81,0x64,0xa6,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35, +0x05,0xc5,0xcc,0x03,0xad,0xb2,0x84,0x00,0x35,0xb3,0x84,0x00,0x35,0x05,0xc5,0xcd, +0x10,0xad,0xb2,0x84,0x04,0x35,0xb3,0x84,0x00,0x35,0x81,0xad,0x84,0x00,0x35,0xae, +0x84,0x00,0x35,0xaf,0x84,0x00,0x35,0x81,0xac,0x84,0x00,0x35,0x05,0xad,0x81,0xac, +0x84,0x80,0x35,0x0c,0xad,0x07,0x27,0x4d,0x05,0xc5,0xcc,0x64,0xa6,0xb0,0x84,0x00, +0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x00,0x35,0xb3,0x84,0x00,0x35,0x05,0xc5,0xcd, +0x0a,0xa6,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x10,0x35,0xb3,0x84, +0x00,0x35,0x81,0x84,0x84,0x84,0x84,0xe7,0x01,0x01,0x35,0xef,0xfc,0xcd,0x5f,0xa4, +0x00,0x84,0x35,0xa0,0x1a,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b, +0x01,0x6b,0x00,0x84,0xc6,0x02,0x6b,0x01,0x84,0xc6,0x03,0x6b,0x02,0x84,0xc6,0x04, +0x6b,0x03,0x84,0xc6,0x88,0x88,0x88,0x88,0x81,0x84,0x84,0x84,0x84,0xef,0xfc,0xcd, +0x5f,0xa4,0x00,0x84,0x35,0xa0,0x1b,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01, +0xab,0x5b,0x01,0x6b,0x00,0x84,0xc6,0x02,0x6b,0x01,0x84,0xc6,0x03,0x6b,0x02,0x84, +0xc6,0x04,0x6b,0x03,0x84,0xc6,0x88,0x88,0x88,0x88,0x81,0xef,0xfc,0xcd,0x78,0xae, +0xa4,0x00,0x84,0x35,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81, +0x84,0x84,0x84,0x84,0x10,0xad,0xa3,0x1d,0x09,0xad,0x5b,0x17,0xad,0xa3,0x1c,0x10, +0xad,0x5b,0x01,0x6b,0x78,0x84,0xc6,0x02,0x6b,0x79,0x84,0xc6,0x03,0x6b,0x7a,0x84, +0xc6,0x04,0x6b,0x7b,0x84,0xc6,0x88,0x88,0x88,0x88,0x81,0x0e,0xfd,0xcd,0xbc,0x00, +0xce,0xbd,0x00,0xc6,0x81,0x84,0x84,0x84,0x84,0xa0,0x84,0xc7,0x01,0x7b,0xa1,0x84, +0xc7,0x02,0x7b,0xa2,0x84,0xc7,0x03,0x7b,0xa3,0x84,0xc7,0x04,0x7b,0x03,0x6b,0x80, +0xaa,0x03,0x7b,0x04,0x6b,0x06,0xaa,0x04,0x7b,0x0c,0x20,0xd2,0xfd,0xcd,0xa4,0xb7, +0x00,0xa9,0x41,0x01,0xab,0x5b,0xa2,0x1e,0x34,0xad,0x11,0x24,0x00,0xa2,0xbc,0x00, +0xc6,0x06,0xa0,0xbd,0x00,0xc6,0x0c,0x27,0x71,0x01,0xc6,0x22,0x25,0x02,0xa1,0xbb, +0x00,0xc6,0x29,0x26,0x4a,0x70,0x01,0xc6,0x03,0x6b,0x80,0xa4,0x03,0x7b,0x04,0x6b, +0x4f,0x01,0x6b,0xa0,0x84,0xc6,0x02,0x6b,0xa1,0x84,0xc6,0x03,0x6b,0xa2,0x84,0xc6, +0x04,0x6b,0xa3,0x84,0xc6,0x6c,0x25,0x02,0xa1,0xbb,0x00,0xc6,0x73,0x26,0x4a,0x70, +0x01,0xc6,0x0d,0x27,0x4a,0x71,0x01,0xc6,0xef,0xfc,0xcd,0x78,0xae,0xa4,0x00,0x84, +0x35,0xa0,0x1c,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0x01,0x6b, +0x78,0x84,0xc6,0x02,0x6b,0x79,0x84,0xc6,0x03,0x6b,0x7a,0x84,0xc6,0x04,0x6b,0x7b, +0x84,0xc6,0x48,0x83,0x00,0x35,0x49,0x83,0x00,0x35,0x4a,0x83,0x00,0x35,0x4b,0x83, +0x0f,0x35,0x10,0x26,0x4a,0x24,0x83,0x00,0x35,0x25,0x83,0x00,0x35,0x26,0x83,0x00, +0x35,0x27,0x83,0x00,0x35,0x4d,0x27,0x70,0x01,0xc6,0xef,0xfc,0xcd,0xa4,0xae,0xa4, +0x00,0x84,0x35,0xa2,0x1e,0xa0,0x3f,0xa1,0x3f,0xa2,0x1f,0xcc,0xca,0xcd,0x14,0x26, +0x03,0xa1,0x04,0x27,0x01,0xa1,0xbb,0x00,0xc6,0x1f,0x26,0x4a,0x70,0x01,0xc6,0xef, +0xfc,0xcd,0xa0,0xae,0xa4,0x00,0x84,0x35,0xa0,0x1f,0xa2,0x3f,0xa3,0x3f,0x8c,0xfc, +0xcd,0x10,0xa6,0x0e,0xfd,0xcd,0x5c,0x01,0x24,0x02,0xab,0x58,0x01,0xce,0x59,0x01, +0xc6,0x0b,0x20,0xec,0x01,0xce,0xed,0x01,0xc6,0x2a,0x26,0x4a,0x0b,0x27,0x02,0xa0, +0x70,0x01,0xc6,0xf2,0x01,0x5f,0x72,0x48,0xca,0xcc,0x03,0x27,0x72,0x01,0xc6,0x08, +0x27,0x71,0x01,0xc6,0x88,0x88,0x88,0x88,0x81,0x84,0x84,0x84,0x84,0xa0,0x84,0xc7, +0x01,0x7b,0xa1,0x84,0xc7,0x02,0x7b,0xa2,0x84,0xc7,0x03,0x7b,0xa3,0x84,0xc7,0x04, +0x7b,0xd2,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0xa2,0x1e,0x0e,0xfd, +0xcd,0xbc,0x00,0xce,0xbd,0x00,0xc6,0x03,0x6b,0x80,0xa4,0x03,0x7b,0x04,0x6b,0x4f, +0x1f,0x25,0x02,0xa1,0xbb,0x00,0xc6,0x26,0x26,0x4a,0x70,0x01,0xc6,0x03,0x6b,0x7f, +0xa4,0x03,0x7b,0x01,0x6b,0xa0,0x84,0xc6,0x02,0x6b,0xa1,0x84,0xc6,0x03,0x6b,0xa2, +0x84,0xc6,0x04,0x6b,0xa3,0x84,0xc6,0x5a,0x26,0x71,0x01,0xc6,0x5f,0x20,0x24,0x83, +0x00,0x35,0x25,0x83,0x00,0x35,0x26,0x83,0x02,0x35,0x27,0x83,0x00,0x35,0xa0,0x84, +0x00,0x35,0xa1,0x84,0x00,0x35,0xa2,0x84,0x00,0x35,0xa3,0x84,0x00,0x35,0xa4,0x84, +0x00,0x35,0xa5,0x84,0x00,0x35,0xa6,0x84,0x00,0x35,0xa7,0x84,0x00,0x35,0xef,0xfc, +0xcd,0x78,0xae,0xa4,0x00,0x84,0x35,0xa0,0x1d,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9, +0x41,0x01,0xab,0x5b,0x01,0x6b,0x78,0x84,0xc6,0x02,0x6b,0x79,0x84,0xc6,0x03,0x6b, +0x7a,0x84,0xc6,0x04,0x6b,0x7b,0x84,0xc6,0xf2,0x01,0xc7,0x5f,0x26,0x71,0x01,0xce, +0x64,0x26,0x72,0x01,0xc6,0x88,0x88,0x88,0x88,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x01,0xab,0x81,0x84,0x84,0x84,0x84,0x00,0x40,0xc7,0x01,0x7b,0x01,0x40, +0xc7,0x02,0x7b,0x02,0x40,0xc7,0x03,0x7b,0x03,0x40,0xc7,0x04,0x7b,0xef,0xfc,0xcd, +0x5f,0xa4,0x00,0x40,0x35,0xa0,0x1e,0x23,0xad,0x5b,0xef,0xfc,0xcd,0x1c,0xae,0xa4, +0x00,0x40,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x13,0xb6,0x14,0x20, +0x1c,0x40,0x00,0x35,0x1d,0x40,0x00,0x35,0x1e,0x40,0x00,0x35,0x1f,0x40,0x00,0x35, +0x04,0x6b,0x02,0xaa,0x04,0x7b,0x18,0x26,0x12,0x3d,0x04,0x6b,0x40,0xaa,0x04,0x7b, +0x06,0x26,0x5d,0x01,0xc6,0x04,0x6b,0x10,0xaa,0x04,0x7b,0x06,0x26,0x5c,0x01,0xc6, +0x01,0x6b,0x02,0x6b,0x03,0x6b,0x4f,0x04,0x6b,0x01,0xa6,0xef,0xfc,0xcd,0xb4,0xae, +0xa4,0x00,0x84,0x35,0xa3,0x18,0xa2,0x18,0xac,0xc8,0xcd,0x5b,0x01,0x6b,0xb4,0x84, +0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04,0x6b,0xb7,0x84,0xc6, +0x05,0xc5,0xcd,0xfa,0xa6,0x14,0x45,0x00,0x35,0x15,0x45,0x00,0x35,0x16,0x45,0x00, +0x35,0x17,0x45,0x02,0x35,0x88,0x88,0x88,0x88,0x81,0x01,0x40,0x00,0x35,0x02,0x40, +0x00,0x35,0x03,0x40,0x00,0x35,0x81,0x84,0x84,0x84,0x84,0x72,0x01,0x5f,0x72,0xef, +0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa2,0x19,0x1e,0xfe,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x01,0xab,0x5b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03, +0x6b,0xb6,0x84,0xc6,0x04,0x6b,0xb7,0x84,0xc6,0x14,0x45,0x00,0x35,0x15,0x45,0x00, +0x35,0x16,0x45,0x00,0x35,0x17,0x45,0x01,0x35,0x00,0x40,0x00,0x35,0x47,0xad,0x00, +0x40,0x80,0x35,0x4d,0xad,0x88,0x88,0x88,0x88,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x01,0xab,0x81,0xac,0x84,0x00,0x35,0xad,0x84,0x00,0x35,0xae,0x84,0x00, +0x35,0x81,0x00,0x88,0x00,0x35,0x01,0x88,0x00,0x35,0x02,0x88,0x00,0x35,0x81,0xa2, +0x14,0xa3,0x14,0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x01,0xa4,0xa2,0xb6,0xa3,0xb7,0xf8, +0xa4,0xa3,0xb6,0x2e,0xfc,0xcd,0x08,0xae,0x90,0x5f,0x26,0xb6,0x81,0x84,0x84,0x84, +0x84,0x84,0x84,0x25,0xad,0x03,0x88,0x01,0x35,0x08,0x88,0x00,0x35,0x09,0x88,0x30, +0x35,0x0a,0x88,0x00,0x35,0x0b,0x88,0x00,0x35,0xef,0xfc,0xcd,0x0c,0xae,0xa4,0x00, +0x88,0x35,0xa3,0x1e,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x07,0xa4,0x05, +0x7b,0x18,0x88,0x00,0x35,0x19,0x88,0x00,0x35,0x1a,0x88,0xff,0x35,0x1b,0x88,0xff, +0x35,0x14,0x88,0x00,0x35,0x15,0x88,0x00,0x35,0x16,0x88,0xff,0x35,0x17,0x88,0xff, +0x35,0x10,0x88,0x00,0x35,0x11,0x88,0x5f,0x35,0x12,0x88,0xff,0x35,0x13,0x88,0xff, +0x35,0x72,0xc7,0xcd,0x03,0x88,0x00,0x35,0xef,0xfc,0xcd,0xb4,0xae,0xa4,0x00,0x84, +0x35,0xa2,0x1e,0xa0,0x1e,0x8c,0xc7,0xcd,0x5b,0x11,0x26,0x21,0xa1,0x0a,0x20,0xa0, +0xb7,0x60,0xaa,0xa0,0xb6,0x8c,0xc7,0xcd,0x5b,0x0c,0x25,0x22,0xa1,0xf3,0x01,0xc6, +0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04, +0x6b,0xb7,0x84,0xc6,0x7f,0xc7,0xcd,0xaf,0x84,0x20,0x35,0xef,0xfc,0xcd,0x7c,0xae, +0xa4,0x00,0x84,0x35,0xa0,0x14,0xa1,0x1a,0xa1,0x10,0x54,0xc7,0xcd,0x09,0x20,0xa1, +0x1a,0xa1,0x10,0x54,0xc7,0xcd,0x12,0x20,0xa1,0x10,0x54,0xc7,0xcd,0x19,0x20,0x54, +0xc7,0xcd,0x27,0x20,0x17,0x27,0x4a,0x11,0x27,0x4a,0x0d,0x27,0x4a,0x0b,0x27,0x4a, +0x05,0x7b,0x7f,0xc7,0xcd,0xaf,0x84,0x00,0x35,0x7c,0x84,0x00,0x35,0x7d,0x84,0x00, +0x35,0x7e,0x84,0x00,0x35,0x7f,0x84,0x00,0x35,0x72,0xc7,0xcd,0x03,0x88,0x00,0x35, +0xb7,0xc5,0xcd,0x21,0x25,0x20,0xa1,0xf3,0x01,0xc6,0x88,0x88,0x88,0x88,0x89,0x88, +0x81,0xac,0x84,0x00,0x35,0xad,0x84,0x00,0x35,0xae,0x84,0x00,0x35,0xaf,0x84,0x00, +0x35,0x7c,0x84,0x00,0x35,0x7d,0x84,0x00,0x35,0x7e,0x84,0x00,0x35,0x7f,0x84,0x00, +0x35,0x00,0x88,0x00,0x35,0x01,0x88,0x00,0x35,0x02,0x88,0x00,0x35,0x03,0x88,0x00, +0x35,0xa8,0xad,0x02,0x25,0x20,0xa1,0xf3,0x01,0xc6,0x70,0x01,0x5f,0x72,0xe5,0x01, +0x5f,0x72,0x81,0x84,0x84,0x84,0x84,0xb4,0x84,0xc7,0x01,0x7b,0xb5,0x84,0xc7,0x02, +0x7b,0xb6,0x84,0xc7,0x03,0x7b,0xb7,0x84,0xc7,0x04,0x7b,0xef,0xfc,0xcd,0xb4,0xae, +0xa4,0x00,0x84,0x35,0xa1,0x1c,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab, +0x5b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6, +0x04,0x6b,0xb7,0x84,0xc6,0x88,0x88,0x88,0x88,0x81,0x1e,0xfe,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x03,0xab,0xef,0xfc,0xcc,0x5f,0xa4,0x00,0x84,0x35,0xa0,0x00,0x30,0x35, +0x0c,0xad,0x5b,0xef,0xfc,0xcd,0x5f,0xa4,0x00,0x84,0x35,0xa0,0x1a,0xa0,0x3f,0x1b, +0xad,0x5b,0x81,0xa0,0x3f,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x03,0xab,0xef, +0xfc,0xcc,0x5f,0xa4,0x00,0x84,0x35,0xa0,0x18,0x0a,0xad,0x5b,0xef,0xfc,0xcd,0x5f, +0xa4,0x00,0x84,0x35,0x15,0xad,0x5b,0x81,0x85,0x90,0x85,0x90,0x01,0xee,0x72,0x02, +0x7b,0x05,0x20,0x05,0xee,0x72,0x06,0x7b,0x07,0x24,0x05,0xe2,0x72,0x9f,0x06,0xe0, +0x72,0x89,0x88,0x81,0x85,0x90,0x85,0x90,0x05,0xee,0x72,0x06,0x7b,0x05,0x20,0x01, +0xee,0x72,0x02,0x7b,0x07,0x24,0x05,0xe2,0x72,0x9f,0x06,0xe0,0x72,0x89,0x88,0x81, +0x84,0x84,0xe9,0x26,0xa4,0xb6,0xed,0x26,0x5d,0x01,0x6b,0x00,0xa2,0xa4,0xb7,0x01, +0x7b,0x02,0x6b,0x01,0xa0,0x97,0x02,0x7b,0x9d,0x01,0x20,0x01,0xef,0x72,0x02,0x6b, +0x63,0xfc,0xcd,0x03,0xae,0x90,0xa7,0x3f,0x5f,0x88,0x88,0x81,0x41,0x20,0x40,0x35, +0x48,0x20,0x5f,0x72,0x46,0x20,0x5f,0x72,0x45,0x20,0xc7,0x01,0xa6,0x02,0x20,0xd8, +0xa6,0x04,0x24,0x20,0xa1,0xf3,0x01,0xc6,0x81,0x9a,0xd9,0x01,0xcf,0xda,0x01,0xc7, +0x9b,0x81,0x44,0x42,0x00,0x35,0x45,0x42,0x00,0x35,0x46,0x42,0x00,0x35,0x47,0x42, +0x00,0x35,0x00,0x42,0x00,0x35,0x01,0x42,0x00,0x35,0x02,0x42,0x01,0x35,0x03,0x42, +0x01,0x35,0x10,0x20,0x00,0x42,0x08,0x35,0x01,0x42,0x00,0x35,0x02,0x42,0x01,0x35, +0x03,0x42,0x00,0x35,0x12,0x26,0x4a,0xbf,0x00,0xc6,0x20,0x40,0x00,0x35,0x21,0x40, +0x00,0x35,0x22,0x40,0x00,0x35,0x23,0x40,0x01,0x35,0x04,0x44,0xc3,0x00,0x55,0x05, +0x44,0xc4,0x00,0x55,0x06,0x44,0xc5,0x00,0x55,0x07,0x44,0xc6,0x00,0x55,0x00,0x44, +0xc7,0x00,0x55,0x01,0x44,0xc8,0x00,0x55,0x02,0x44,0xc9,0x00,0x55,0x03,0x44,0xca, +0x00,0x55,0x81,0x85,0x4f,0xf3,0x25,0xbf,0x00,0xc1,0x01,0x6b,0x4c,0x01,0x7b,0x76, +0xc2,0xcd,0x06,0x20,0x4f,0x88,0x81,0x9a,0xd2,0xfc,0xcd,0xa0,0x3f,0xa1,0x3f,0xa2, +0x3f,0x81,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x81,0x9a,0xd2,0xfc,0xcd, +0xa4,0xb7,0x01,0xaa,0x41,0x81,0xa4,0xc6,0x92,0xa5,0xbf,0xa4,0xb7,0x81,0x1d,0xad, +0xa3,0x3f,0xa4,0xb7,0x01,0xaa,0x33,0xc3,0xcc,0x4f,0x29,0xad,0xa3,0x00,0x3d,0x35, +0x03,0xee,0x72,0xa4,0xb7,0x02,0x7b,0x9b,0x37,0xad,0xa3,0x00,0x08,0x35,0xa4,0xb7, +0x02,0xaa,0x41,0x24,0xaa,0x02,0xee,0x72,0x03,0x7b,0x9b,0xd3,0x26,0x04,0xe1,0x72, +0x33,0xad,0x02,0xaa,0x41,0x03,0xaa,0x02,0xee,0x72,0x03,0x7b,0x32,0xc3,0xcc,0x03, +0x26,0x01,0x6b,0x4a,0x01,0x7b,0x9a,0xd2,0xfc,0xcd,0xa4,0xb7,0x02,0xaa,0x02,0x7b, +0x03,0xee,0x72,0x68,0xad,0x04,0x7b,0x9b,0x1c,0x20,0x01,0x6b,0xff,0xa6,0x04,0x6b, +0x80,0xaa,0x04,0x7b,0x06,0x26,0x02,0xa1,0x11,0xb6,0x04,0x6b,0x03,0xa6,0x02,0x20, +0x01,0xa6,0x06,0x20,0x02,0xa6,0x04,0x27,0x15,0x3d,0x0c,0x27,0xc1,0x00,0xc6,0x79, +0xad,0x41,0x1c,0xaa,0x02,0xee,0x72,0x03,0x7b,0x9b,0x2a,0xc4,0xcd,0x41,0x18,0xaa, +0x02,0xee,0x72,0x03,0x7b,0x9b,0x2a,0xc4,0xcd,0x41,0x14,0xaa,0x02,0xee,0x72,0x03, +0x7b,0x9b,0xd7,0x26,0x04,0xe1,0x72,0x33,0xc4,0xcd,0x01,0xaa,0x41,0x13,0xaa,0x02, +0xee,0x72,0x03,0x7b,0xb6,0x27,0x01,0x6b,0x4a,0x01,0x7b,0x3b,0xc4,0xcd,0x10,0xaa, +0x02,0xee,0x72,0x03,0x7b,0x45,0xc4,0xcd,0x04,0x7b,0x9b,0x17,0x20,0x01,0x6b,0xff, +0xa6,0x04,0x6b,0xcf,0xa6,0x02,0x20,0x0f,0xa6,0x06,0x20,0x0c,0xa6,0x08,0x20,0x06, +0x27,0x4a,0x05,0x27,0x14,0xb6,0xcc,0x26,0x04,0xe1,0x72,0x33,0xc4,0xcd,0x01,0xaa, +0x41,0x0d,0xaa,0x02,0xee,0x72,0x03,0x7b,0x81,0x85,0x85,0x85,0x85,0x4c,0x06,0x26, +0x01,0x6b,0x4a,0x01,0x7b,0x3b,0xc4,0xcd,0x0c,0xaa,0x02,0xee,0x72,0x03,0x7b,0x8c, +0xfc,0xcd,0x10,0xa6,0x45,0xc4,0xcd,0x04,0x7b,0x9b,0x22,0x20,0x01,0x6b,0xff,0xa6, +0x04,0x6b,0xfc,0xa6,0x02,0x20,0xf0,0xa6,0x06,0x20,0xcc,0xa6,0x0a,0x20,0xc0,0xa6, +0x0e,0x20,0x0c,0xa6,0x12,0x20,0x0f,0xa6,0x16,0x20,0x0c,0xa6,0x18,0x27,0x4a,0x17, +0x27,0x4a,0x16,0x27,0x4a,0x15,0x27,0x4a,0x14,0x27,0x4a,0x29,0x27,0x4a,0x16,0x27, +0x13,0xb6,0xc9,0x26,0x04,0xe1,0x72,0x33,0xc4,0xcd,0x01,0xaa,0x41,0x0b,0xaa,0x02, +0xee,0x72,0x03,0x7b,0x66,0x27,0x01,0x6b,0x4a,0x01,0x7b,0x3b,0xc4,0xcd,0x08,0xaa, +0x02,0xee,0x72,0x03,0x7b,0xa0,0xb7,0x03,0xaa,0xa0,0xb6,0xa1,0xb7,0xc3,0xaa,0xa0, +0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x04,0x7b,0x9b,0x25,0x20,0x01,0x6b,0xff,0xa6,0x04, +0x6b,0x4f,0x01,0x20,0x0c,0xa6,0x04,0x27,0x15,0x3d,0x2a,0xc4,0xcd,0x41,0x04,0xaa, +0x02,0xee,0x72,0x03,0x7b,0x9b,0x2a,0xc4,0xcd,0x9b,0x02,0x6b,0x03,0xef,0x72,0x50, +0xaa,0x41,0x4f,0x58,0x58,0x97,0x88,0x88,0x88,0x88,0x81,0x1e,0xfe,0xcd,0xc7,0xae, +0xa4,0x00,0x00,0x35,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81,0xa0,0xb7,0xa1, +0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x81,0xa0,0xb7,0x03,0xa4,0xa0,0xb6,0xa1,0x3f,0xa2, +0x3f,0xa3,0x3f,0x8c,0xfc,0xcd,0x18,0xa6,0x7a,0xfc,0xcd,0x4a,0x81,0xa4,0xb7,0x00, +0xa9,0x41,0x07,0xab,0x81,0xc7,0x00,0x00,0x35,0xc8,0x00,0x00,0x35,0xc9,0x00,0x18, +0x35,0x81,0x2c,0xad,0x18,0xa4,0x48,0x48,0x48,0x4a,0x12,0xb6,0xef,0xfc,0xcd,0x43, +0xad,0x81,0x8b,0x41,0x00,0xa9,0x41,0x0a,0xab,0x5b,0xef,0xfc,0xcd,0x0c,0xae,0xa4, +0x00,0x84,0x35,0xa3,0x36,0xa2,0x36,0xa1,0x36,0xa0,0x34,0x67,0xad,0x0a,0x20,0xa0, +0x39,0xa1,0x39,0xa2,0x39,0xa3,0x38,0x73,0xad,0x0c,0x26,0x02,0xa1,0x11,0xb6,0x84, +0x84,0x84,0x84,0x84,0x16,0xe0,0xcd,0x88,0x0b,0x7b,0x88,0x0b,0x7b,0x88,0x0b,0x7b, +0x88,0x0b,0x7b,0x88,0x06,0x7b,0x06,0x6b,0x44,0x44,0x06,0x7b,0xb3,0xfd,0xcd,0x02, +0xa6,0x6d,0xad,0x5b,0x0e,0x26,0x02,0xa1,0x11,0xb6,0x06,0x6b,0x08,0xa6,0x07,0x6b, +0x4f,0x08,0x6b,0xbb,0xa6,0x09,0x6b,0x80,0xa6,0x0a,0x6b,0xc7,0x00,0x00,0x35,0xc8, +0x00,0x00,0x35,0xc9,0x00,0x60,0x35,0xca,0x00,0x00,0x35,0x18,0x20,0xac,0xa6,0x09, +0x6b,0x44,0xa6,0x0a,0x6b,0xc7,0x00,0x00,0x35,0xc8,0x00,0x00,0x35,0xc9,0x00,0x62, +0x35,0xca,0x00,0x00,0x35,0x39,0x20,0x10,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x5d,0xa6, +0x09,0x6b,0xc0,0xa6,0x0a,0x6b,0xc7,0x00,0x00,0x35,0xc8,0x00,0x00,0x35,0xc9,0x00, +0x30,0x35,0xca,0x00,0x00,0x35,0x18,0x20,0x56,0xa6,0x09,0x6b,0x22,0xa6,0x0a,0x6b, +0xc7,0x00,0x00,0x35,0xc8,0x00,0x00,0x35,0xc9,0x00,0x31,0x35,0xca,0x00,0x00,0x35, +0x74,0x20,0x20,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x2e,0xa6,0x09,0x6b,0xe0,0xa6,0x0a, +0x6b,0x2f,0xc2,0xcd,0xca,0x00,0x00,0x35,0xc4,0xc1,0xcc,0x20,0xa6,0x07,0x6b,0x4f, +0x08,0x6b,0x2b,0xa6,0x09,0x6b,0x11,0xa6,0x0a,0x6b,0x2f,0xc2,0xcd,0xca,0x00,0x80, +0x35,0xc4,0xc1,0xcc,0x20,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x1f,0xa6,0x09,0x6b,0x40, +0xa6,0x0a,0x6b,0xc7,0x00,0x00,0x35,0xc8,0x00,0x00,0x35,0xc9,0x00,0x10,0x35,0xca, +0x00,0x00,0x35,0xc4,0xc1,0xcc,0x20,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x2e,0xa6,0x09, +0x6b,0xe0,0xa6,0x0a,0x6b,0x4f,0x2f,0xc2,0xcd,0xca,0x00,0x00,0x35,0xa5,0xc1,0xcc, +0x03,0x26,0x4a,0x8b,0xc1,0xcc,0x03,0x26,0x4a,0x6a,0xc1,0xcc,0x03,0x26,0x4a,0x50, +0xc1,0xcc,0x03,0x26,0x4a,0x6d,0x27,0x4a,0x57,0x27,0x4a,0x38,0x27,0x13,0xb6,0x9a, +0xef,0xfc,0xcd,0xa4,0xbf,0x84,0xae,0xa3,0x1a,0x1e,0xfe,0xcd,0x3c,0xc2,0xcd,0x5b, +0x9b,0xd2,0xfd,0xcd,0x3c,0xc2,0xcd,0x5b,0xd8,0xfd,0xcd,0x64,0xc2,0xcd,0x5b,0x1f, +0xc2,0xcd,0x5b,0x44,0xc2,0xcd,0x5a,0x01,0x26,0x4d,0x5f,0x12,0xb6,0x15,0x20,0xa3, +0x10,0xd8,0xfd,0xcd,0x64,0xc2,0xcd,0x5b,0x1f,0xc2,0xcd,0x5b,0x44,0xc2,0xcd,0x5a, +0x01,0x26,0x4d,0x5f,0x12,0xb6,0x19,0x26,0x4a,0x11,0xb6,0x3a,0x20,0x08,0x6b,0x40, +0xaa,0x08,0x7b,0x0a,0x6b,0x02,0xaa,0x0a,0x7b,0x0e,0x26,0x02,0xa1,0x11,0xb6,0x0a, +0x6b,0x04,0xaa,0x0a,0x7b,0x06,0x27,0x16,0x3d,0xef,0xfc,0xcd,0x3c,0xc2,0xcd,0x5b, +0xa2,0x1e,0xa0,0xbf,0xa1,0xb7,0x3e,0xa4,0xa1,0xb6,0xa2,0xbf,0xa3,0xbf,0x8c,0xfc, +0xcd,0x11,0xa6,0x5a,0xc2,0xcd,0x14,0x20,0xa0,0x14,0xa0,0x3f,0xa1,0xb7,0x3e,0xa4, +0xa1,0xb6,0xa2,0x3f,0xa3,0x3f,0x8c,0xfc,0xcd,0x11,0xa6,0x5a,0xc2,0xcd,0x18,0x27, +0xe4,0x01,0xce,0x05,0x6b,0x18,0xa6,0x02,0x20,0x14,0xa6,0x06,0x20,0x10,0xa6,0x08, +0x20,0x06,0x27,0x4a,0x05,0x27,0x14,0xb6,0x8b,0x41,0x00,0xa2,0x41,0x0a,0xa0,0x5b, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x81,0x4f,0x13,0xb7,0x53,0x20,0xc6,0x50,0x20,0x12,0x72,0x81,0x01, +0xa6,0x03,0x27,0x4d,0x47,0x1b,0xcd,0x88,0xa6,0x12,0xb7,0x53,0x20,0xc6,0x50,0x20, +0x15,0x72,0x81,0x01,0xa6,0x03,0x27,0x4d,0x47,0x1b,0xcd,0x88,0xa6,0x81,0x01,0xa6, +0x03,0x27,0x4d,0xa4,0x1b,0xcd,0x41,0xa6,0x81,0x01,0xa6,0x03,0x27,0x4d,0x8f,0x1b, +0xcd,0xaa,0x00,0x5f,0x72,0x50,0x20,0x20,0x35,0x52,0x20,0x09,0x35,0x81,0x4d,0x47, +0x1b,0xcd,0x88,0xa6,0x50,0x20,0x20,0x35,0x53,0x20,0xc7,0xc5,0x20,0x4f,0x50,0x20, +0x12,0x72,0xec,0x25,0x06,0xe1,0x72,0x01,0x6b,0x4c,0x01,0x7b,0xd4,0x26,0x13,0xad, +0xbf,0x01,0xd6,0x01,0xee,0x72,0x0d,0x20,0x4f,0x17,0x27,0x60,0xa1,0x02,0x7b,0x05, +0xc5,0xcd,0x05,0xa6,0xec,0x26,0x2b,0xad,0x03,0x7b,0xf2,0x26,0x4d,0x47,0x1b,0xcd, +0x88,0xa6,0x81,0x85,0x85,0x85,0x01,0xa6,0x06,0x27,0x4d,0xa4,0x1b,0xcd,0x02,0x7b, +0x08,0x26,0x4d,0x8f,0x1b,0xcd,0xaa,0x00,0x5f,0x72,0x50,0x20,0x20,0x35,0x52,0x20, +0x09,0x35,0x88,0x89,0x88,0x81,0x4d,0x47,0x1b,0xcd,0x88,0xa6,0xe0,0x1b,0xcc,0x4f, +0x05,0xc5,0xcd,0x05,0xa6,0x95,0x25,0x06,0xe1,0x72,0x01,0x7b,0xbf,0x01,0xd7,0x53, +0x20,0xc6,0x01,0x6b,0x4c,0x9f,0x01,0xee,0x72,0x0d,0x20,0x11,0xe7,0x53,0x20,0xc6, +0x97,0x07,0xeb,0x72,0x4a,0x01,0x6b,0x4c,0x01,0x7b,0x11,0x25,0x09,0xa1,0x06,0x7b, +0x50,0x20,0x22,0x35,0x04,0x26,0xa8,0xb1,0xa8,0xbf,0x90,0x0b,0x26,0xa7,0xb3,0xa7, +0x3f,0x01,0xe6,0x72,0x4a,0x5a,0x01,0x26,0x4d,0x5f,0x06,0x7b,0x50,0x20,0x15,0x72, +0x04,0x26,0xa8,0xb1,0xa8,0xbf,0x90,0x0b,0x26,0xa7,0xb3,0xa7,0x3f,0x01,0xe6,0x72, +0x5a,0x01,0x24,0x02,0xa0,0x5f,0x1a,0x25,0x02,0xa1,0x06,0x7b,0xba,0x26,0x72,0xad, +0x50,0x20,0x15,0x72,0x04,0x26,0x4a,0x06,0x7b,0xc7,0x26,0x4d,0x90,0xad,0x01,0xaa, +0x02,0x7b,0xd0,0x26,0x4d,0x84,0xad,0x05,0xc5,0xcd,0x05,0xa6,0xda,0x26,0x94,0x1c, +0xcd,0x50,0x20,0x20,0x35,0x53,0x20,0xc7,0x03,0x7b,0x02,0x20,0x52,0x80,0xae,0x03, +0x7b,0x07,0x26,0x80,0xa1,0x06,0x7b,0xf5,0x26,0x94,0x1c,0xcd,0x81,0x85,0x85,0x85, +0x01,0xa6,0x06,0x27,0x4d,0xc9,0xad,0x02,0x7b,0x07,0x26,0x4d,0xbb,0xad,0xaa,0x00, +0x5f,0x72,0x01,0x6b,0x4f,0x50,0x20,0x20,0x35,0x52,0x20,0x09,0x35,0x88,0x89,0x88, +0x81,0x4f,0x50,0x20,0x24,0x35,0x05,0xc5,0xcd,0x05,0xa6,0x81,0x01,0xa6,0x03,0x27, +0x4d,0xb7,0xad,0x82,0xa6,0x50,0x20,0x21,0x35,0x53,0x20,0xc7,0x81,0x4f,0x05,0xc5, +0xcd,0x05,0xa6,0x81,0x01,0xa6,0x03,0x27,0x4d,0xcf,0xad,0x81,0xa6,0x50,0x20,0x29, +0x35,0x81,0x85,0x4f,0xaa,0x00,0x5f,0x72,0x81,0x85,0x01,0xa6,0xaa,0x00,0x5f,0x72, +0x50,0x20,0x22,0x35,0x0c,0xaa,0x00,0x0d,0x72,0x05,0x26,0x01,0xe1,0x72,0x01,0xe4, +0x72,0xfa,0x27,0xaa,0x00,0xc6,0x8f,0x01,0x20,0x88,0x81,0x85,0x4f,0x81,0x85,0x01, +0xa6,0x50,0x20,0x05,0x35,0x08,0x27,0x01,0xe1,0x72,0x01,0xe4,0x72,0x51,0x20,0xc6, +0xfa,0x51,0x20,0x0f,0x72,0x9d,0x01,0x20,0x88,0xe0,0x20,0x8f,0xe3,0x26,0x01,0x7b, +0xdb,0xf2,0xcd,0x03,0x26,0xd9,0x01,0xca,0xda,0x01,0xc6,0xcd,0xf1,0xcd,0x03,0x24, +0x20,0xa1,0x12,0x27,0x01,0x6b,0x13,0x18,0xcd,0x64,0x18,0xcd,0x88,0x81,0x84,0x84, +0x84,0x84,0x84,0x06,0x20,0x08,0x35,0x9a,0x1a,0x20,0x10,0x72,0x15,0x20,0xc7,0xee, +0xa4,0x15,0x20,0xc6,0x14,0x20,0xc7,0x7c,0xa4,0x14,0x20,0xc6,0x13,0x20,0xc7,0x08, +0xa4,0x13,0x20,0xc6,0xe8,0xc4,0xcd,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x65, +0xde,0xcd,0x6c,0x01,0x3b,0x6d,0x01,0x3b,0x6e,0x01,0x3b,0x6f,0x01,0x3b,0x01,0x4b, +0x80,0x4b,0x85,0x4b,0x80,0x4b,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84, +0x00,0x35,0xb3,0x84,0x13,0x35,0xa4,0x84,0x00,0x35,0xa5,0x84,0x00,0x35,0xa6,0x84, +0x00,0x35,0xa7,0x84,0x00,0x35,0xa0,0x84,0x00,0x35,0xa1,0x84,0x00,0x35,0xa2,0x84, +0x00,0x35,0xa3,0x84,0x00,0x35,0x0c,0x8c,0x00,0x35,0x0d,0x8c,0x00,0x35,0x0e,0x8c, +0x00,0x35,0x0f,0x8c,0x00,0x35,0x18,0x8c,0x00,0x35,0x19,0x8c,0x00,0x35,0x1a,0x8c, +0x00,0x35,0x1b,0x8c,0x03,0x35,0x04,0x8c,0x00,0x35,0x05,0x8c,0x00,0x35,0x06,0x8c, +0x00,0x35,0x07,0x8c,0x0a,0x35,0x00,0x8c,0x00,0x35,0x01,0x8c,0x00,0x35,0x02,0x8c, +0x00,0x35,0x03,0x8c,0x00,0x35,0x1c,0x8c,0x00,0x35,0x1d,0x8c,0x00,0x35,0x1e,0x8c, +0x00,0x35,0x1f,0x8c,0x04,0x35,0xfe,0xc5,0xcd,0x97,0xc7,0xcd,0x24,0x83,0x00,0x35, +0x25,0x83,0x00,0x35,0x26,0x83,0x02,0x35,0x27,0x83,0x00,0x35,0x84,0x84,0x00,0x35, +0x85,0x84,0x00,0x35,0x86,0x84,0x00,0x35,0x87,0x84,0x20,0x35,0xb4,0x84,0x00,0x35, +0xb5,0x84,0x20,0x35,0xb6,0x84,0x00,0x35,0xb7,0x84,0xa0,0x35,0x0c,0x20,0xb5,0x84, +0x00,0x35,0xb6,0x84,0x00,0x35,0xb7,0x84,0x80,0x35,0x0e,0x24,0x20,0xa1,0xf3,0x01, +0xc6,0x18,0x84,0x00,0x35,0x19,0x84,0x00,0x35,0x1a,0x84,0x00,0x35,0x1b,0x84,0x00, +0x35,0x78,0x84,0x00,0x35,0x79,0x84,0x00,0x35,0x7a,0x84,0x00,0x35,0x7b,0x84,0x00, +0x35,0x3f,0x20,0x01,0x35,0x3d,0x20,0xc7,0xff,0xa6,0x3c,0x20,0xc7,0x04,0xa6,0x6c, +0x01,0x01,0x35,0x6d,0x01,0x86,0x35,0x6e,0x01,0xa0,0x35,0x6f,0x01,0xc7,0x0f,0x20, +0x6c,0x01,0x02,0x35,0x6d,0x01,0x49,0x35,0x6e,0x01,0xf0,0x35,0x6f,0x01,0xc7,0x1c, +0x20,0x6d,0x01,0x9b,0x35,0x6e,0x01,0xfc,0x35,0x6f,0x01,0xc0,0x35,0x2a,0x20,0x6d, +0x01,0x8c,0x35,0x6e,0x01,0xba,0x35,0x6f,0x01,0x80,0x35,0x38,0x20,0x6d,0x01,0x24, +0x35,0x6e,0x01,0xf8,0x35,0x6f,0x01,0xc7,0x49,0x20,0x6c,0x01,0x5f,0x72,0x6d,0x01, +0x5f,0x72,0x6e,0x01,0x5f,0x72,0x6f,0x01,0x5f,0x72,0x4c,0x27,0x08,0xa0,0x3f,0x27, +0x4a,0x34,0x27,0x4a,0x29,0x27,0x4a,0x1f,0x27,0x0f,0xa4,0x08,0x20,0xc6,0xea,0x01, +0x5f,0x72,0xeb,0x01,0xc7,0x01,0xa6,0x3e,0x20,0xfe,0x35,0xf3,0x01,0x10,0x35,0x0a, +0x20,0x03,0xa6,0x3e,0x20,0x20,0x35,0xf3,0x01,0xc7,0x21,0xa6,0x11,0x3f,0x04,0x20, +0x22,0xa6,0x11,0x00,0x01,0x35,0x08,0x27,0x9b,0xfc,0xcd,0xa0,0x3f,0xa1,0x3f,0xa2, +0xb7,0x02,0xa4,0xa2,0xb6,0xa3,0x3f,0x1e,0xfe,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01, +0xab,0x5b,0x01,0x6b,0x94,0x84,0xc6,0x02,0x6b,0x95,0x84,0xc6,0x03,0x6b,0x96,0x84, +0xc6,0x04,0x6b,0x97,0x84,0xc6,0x47,0x25,0x10,0xa1,0x03,0x20,0xc6,0xf2,0x25,0x10, +0xa1,0x05,0x6b,0x4c,0xc9,0x01,0x4f,0x72,0x05,0xee,0x72,0x05,0x6b,0x4f,0xd2,0x00, +0x5f,0x72,0xd3,0x00,0x5f,0x72,0xe4,0x01,0x5f,0x72,0xbb,0x00,0x5f,0x72,0xbd,0x00, +0x5f,0x72,0xbc,0x00,0x5f,0x72,0xda,0x01,0x5f,0x72,0xd9,0x01,0x5f,0x72,0x9b,0x01, +0x0a,0x35,0x9e,0x01,0x5f,0x72,0x9f,0x01,0x5f,0x72,0xa9,0x01,0x5f,0x72,0xa0,0x01, +0x5f,0x72,0xa1,0x01,0x5f,0x72,0xa2,0x01,0x5f,0x72,0x86,0x01,0x5f,0x72,0xe9,0x01, +0x5f,0x72,0xee,0x01,0x5f,0x72,0x71,0x01,0x5f,0x72,0x72,0x01,0x5f,0x72,0xaa,0x00, +0x5f,0x72,0x74,0x01,0x5f,0x72,0x87,0x01,0x5f,0x72,0x75,0x01,0x5f,0x72,0xbf,0x00, +0x5f,0x72,0xc0,0x00,0x5f,0x72,0xc1,0x00,0x5f,0x72,0xc2,0x00,0x5f,0x72,0x70,0x01, +0x5f,0x72,0x11,0x3f,0x10,0x3f,0x73,0x01,0x5f,0x72,0xc7,0x01,0x5f,0x72,0xc8,0x01, +0x5f,0x72,0xef,0x01,0x5f,0x72,0xf0,0x01,0xff,0x35,0xf2,0x01,0x5f,0x72,0xe8,0x01, +0x5f,0x72,0x9b,0x06,0x20,0x5f,0x72,0x88,0x88,0x88,0x88,0x88,0x81,0x84,0xe3,0xad, +0xf4,0x25,0x40,0xa1,0x01,0x6b,0x4c,0x12,0x6f,0x01,0xee,0x72,0x01,0x6b,0x4f,0x88, +0x81,0x05,0x20,0x10,0x72,0x15,0x20,0x11,0x72,0x10,0x1e,0x23,0x1b,0xcc,0x8b,0xff, +0xa6,0x04,0xae,0x81,0x85,0x01,0x7b,0x9a,0xc7,0x01,0xc7,0x0f,0xa4,0xc7,0x01,0xc6, +0xc9,0x01,0x4f,0x72,0xc7,0x01,0x5c,0x72,0x01,0x6b,0xc9,0x01,0xd6,0xc7,0x01,0xce, +0x18,0x27,0xc7,0x01,0xc1,0xc8,0x01,0xc6,0x9b,0x01,0x6b,0x4f,0x88,0x81,0xc8,0x01, +0xc7,0x0f,0xa4,0xc8,0x01,0xc6,0xc9,0x01,0xd7,0xc8,0x01,0x5c,0x72,0xc8,0x01,0xce, +}; diff --git a/drivers/video/av8100/av8100_regs.h b/drivers/video/av8100/av8100_regs.h new file mode 100644 index 00000000000..7e3dc21895e --- /dev/null +++ b/drivers/video/av8100/av8100_regs.h @@ -0,0 +1,340 @@ + +#define AV8100_VAL2REG(__reg, __fld, __val) \ + (((__val) << __reg##_##__fld##_SHIFT) & __reg##_##__fld##_MASK) +#define AV8100_REG2VAL(__reg, __fld, __val) \ + (((__val) & __reg##_##__fld##_MASK) >> __reg##_##__fld##_SHIFT) + +#define AV8100_STANDBY 0x00000000 +#define AV8100_STANDBY_CPD_SHIFT 0 +#define AV8100_STANDBY_CPD_MASK 0x00000001 +#define AV8100_STANDBY_CPD_HIGH 1 +#define AV8100_STANDBY_CPD_LOW 0 +#define AV8100_STANDBY_CPD(__x) \ + AV8100_VAL2REG(AV8100_STANDBY, CPD, __x) +#define AV8100_STANDBY_CPD_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY, CPD, __x) +#define AV8100_STANDBY_STBY_SHIFT 1 +#define AV8100_STANDBY_STBY_MASK 0x00000002 +#define AV8100_STANDBY_STBY_HIGH 1 +#define AV8100_STANDBY_STBY_LOW 0 +#define AV8100_STANDBY_STBY(__x) \ + AV8100_VAL2REG(AV8100_STANDBY, STBY, __x) +#define AV8100_STANDBY_STBY_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY, STBY, __x) +#define AV8100_STANDBY_HPDS_SHIFT 2 +#define AV8100_STANDBY_HPDS_MASK 0x00000004 +#define AV8100_STANDBY_HPDS(__x) \ + AV8100_VAL2REG(AV8100_STANDBY, HPDS, __x) +#define AV8100_STANDBY_HPDS_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY, HPDS, __x) +#define AV8100_STANDBY_CPDS_SHIFT 3 +#define AV8100_STANDBY_CPDS_MASK 0x00000008 +#define AV8100_STANDBY_CPDS(__x) \ + AV8100_VAL2REG(AV8100_STANDBY, CPDS, __x) +#define AV8100_STANDBY_CPDS_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY, CPDS, __x) +#define AV8100_STANDBY_MCLKRNG_SHIFT 4 +#define AV8100_STANDBY_MCLKRNG_MASK 0x000000F0 +#define AV8100_STANDBY_MCLKRNG(__x) \ + AV8100_VAL2REG(AV8100_STANDBY, MCLKRNG, __x) +#define AV8100_STANDBY_MCLKRNG_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY, MCLKRNG, __x) +#define AV8100_HDMI_5_VOLT_TIME 0x00000001 +#define AV8100_HDMI_5_VOLT_TIME_OFF_TIME_SHIFT 0 +#define AV8100_HDMI_5_VOLT_TIME_OFF_TIME_MASK 0x0000001F +#define AV8100_HDMI_5_VOLT_TIME_OFF_TIME(__x) \ + AV8100_VAL2REG(AV8100_HDMI_5_VOLT_TIME, OFF_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_OFF_TIME_GET(__x) \ + AV8100_REG2VAL(AV8100_HDMI_5_VOLT_TIME, OFF_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_DAC_OFF_TIME_SHIFT 0 +#define AV8100_HDMI_5_VOLT_TIME_DAC_OFF_TIME_MASK 0x00000003 +#define AV8100_HDMI_5_VOLT_TIME_DAC_OFF_TIME(__x) \ + AV8100_VAL2REG(AV8100_HDMI_5_VOLT_TIME, DAC_OFF_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_DAC_OFF_TIME_GET(__x) \ + AV8100_REG2VAL(AV8100_HDMI_5_VOLT_TIME, DAC_OFF_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_SU_OFF_TIME_SHIFT 2 +#define AV8100_HDMI_5_VOLT_TIME_SU_OFF_TIME_MASK 0x0000001C +#define AV8100_HDMI_5_VOLT_TIME_SU_OFF_TIME(__x) \ + AV8100_VAL2REG(AV8100_HDMI_5_VOLT_TIME, SU_OFF_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_SU_OFF_TIME_GET(__x) \ + AV8100_REG2VAL(AV8100_HDMI_5_VOLT_TIME, SU_OFF_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_ON_TIME_SHIFT 5 +#define AV8100_HDMI_5_VOLT_TIME_ON_TIME_MASK 0x000000E0 +#define AV8100_HDMI_5_VOLT_TIME_ON_TIME(__x) \ + AV8100_VAL2REG(AV8100_HDMI_5_VOLT_TIME, ON_TIME, __x) +#define AV8100_HDMI_5_VOLT_TIME_ON_TIME_GET(__x) \ + AV8100_REG2VAL(AV8100_HDMI_5_VOLT_TIME, ON_TIME, __x) +#define AV8100_STANDBY_INTERRUPT_MASK 0x00000002 +#define AV8100_STANDBY_INTERRUPT_MASK_HPDM_SHIFT 0 +#define AV8100_STANDBY_INTERRUPT_MASK_HPDM_MASK 0x00000001 +#define AV8100_STANDBY_INTERRUPT_MASK_HPDM_HIGH 1 +#define AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW 0 +#define AV8100_STANDBY_INTERRUPT_MASK_HPDM(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_INTERRUPT_MASK, HPDM, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_HPDM_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_INTERRUPT_MASK, HPDM, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_CPDM_SHIFT 1 +#define AV8100_STANDBY_INTERRUPT_MASK_CPDM_MASK 0x00000002 +#define AV8100_STANDBY_INTERRUPT_MASK_CPDM_HIGH 1 +#define AV8100_STANDBY_INTERRUPT_MASK_CPDM_LOW 0 +#define AV8100_STANDBY_INTERRUPT_MASK_CPDM(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_INTERRUPT_MASK, CPDM, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_CPDM_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_INTERRUPT_MASK, CPDM, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_SHIFT 2 +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_MASK 0x0000000C +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_INPUT 0x00 +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_ALT 0x01 +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_OUTPUT0 0x02 +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_OUTPUT1 0x03 +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_INTERRUPT_MASK, STBYGPIOCFG, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_INTERRUPT_MASK, STBYGPIOCFG, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_IPOL_SHIFT 7 +#define AV8100_STANDBY_INTERRUPT_MASK_IPOL_MASK 0x00000080 +#define AV8100_STANDBY_INTERRUPT_MASK_IPOL_HIGH 1 +#define AV8100_STANDBY_INTERRUPT_MASK_IPOL_LOW 0 +#define AV8100_STANDBY_INTERRUPT_MASK_IPOL(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_INTERRUPT_MASK, IPOL, __x) +#define AV8100_STANDBY_INTERRUPT_MASK_IPOL_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_INTERRUPT_MASK, IPOL, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT 0x00000003 +#define AV8100_STANDBY_PENDING_INTERRUPT_HPDI_SHIFT 0 +#define AV8100_STANDBY_PENDING_INTERRUPT_HPDI_MASK 0x00000001 +#define AV8100_STANDBY_PENDING_INTERRUPT_HPDI_HIGH 1 +#define AV8100_STANDBY_PENDING_INTERRUPT_HPDI_LOW 0 +#define AV8100_STANDBY_PENDING_INTERRUPT_HPDI(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_PENDING_INTERRUPT, HPDI, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_HPDI_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_PENDING_INTERRUPT, HPDI, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_CPDI_SHIFT 1 +#define AV8100_STANDBY_PENDING_INTERRUPT_CPDI_MASK 0x00000002 +#define AV8100_STANDBY_PENDING_INTERRUPT_CPDI_HIGH 1 +#define AV8100_STANDBY_PENDING_INTERRUPT_CPDI_LOW 0 +#define AV8100_STANDBY_PENDING_INTERRUPT_CPDI(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_PENDING_INTERRUPT, CPDI, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_CPDI_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_PENDING_INTERRUPT, CPDI, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_ONI_SHIFT 2 +#define AV8100_STANDBY_PENDING_INTERRUPT_ONI_MASK 0x00000004 +#define AV8100_STANDBY_PENDING_INTERRUPT_ONI_HIGH 1 +#define AV8100_STANDBY_PENDING_INTERRUPT_ONI_LOW 0 +#define AV8100_STANDBY_PENDING_INTERRUPT_ONI(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_PENDING_INTERRUPT, ONI, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_ONI_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_PENDING_INTERRUPT, ONI, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_SID_SHIFT 4 +#define AV8100_STANDBY_PENDING_INTERRUPT_SID_MASK 0x000000F0 +#define AV8100_STANDBY_PENDING_INTERRUPT_SID(__x) \ + AV8100_VAL2REG(AV8100_STANDBY_PENDING_INTERRUPT, SID, __x) +#define AV8100_STANDBY_PENDING_INTERRUPT_SID_GET(__x) \ + AV8100_REG2VAL(AV8100_STANDBY_PENDING_INTERRUPT, SID, __x) +#define AV8100_GENERAL_INTERRUPT_MASK 0x00000004 +#define AV8100_GENERAL_INTERRUPT_MASK_EOCM_SHIFT 0 +#define AV8100_GENERAL_INTERRUPT_MASK_EOCM_MASK 0x00000001 +#define AV8100_GENERAL_INTERRUPT_MASK_EOCM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_EOCM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_EOCM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, EOCM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_EOCM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, EOCM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_VSIM_SHIFT 1 +#define AV8100_GENERAL_INTERRUPT_MASK_VSIM_MASK 0x00000002 +#define AV8100_GENERAL_INTERRUPT_MASK_VSIM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_VSIM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_VSIM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, VSIM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_VSIM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, VSIM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_VSOM_SHIFT 2 +#define AV8100_GENERAL_INTERRUPT_MASK_VSOM_MASK 0x00000004 +#define AV8100_GENERAL_INTERRUPT_MASK_VSOM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_VSOM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_VSOM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, VSOM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_VSOM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, VSOM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_CECM_SHIFT 3 +#define AV8100_GENERAL_INTERRUPT_MASK_CECM_MASK 0x00000008 +#define AV8100_GENERAL_INTERRUPT_MASK_CECM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_CECM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_CECM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, CECM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_CECM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, CECM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_HDCPM_SHIFT 4 +#define AV8100_GENERAL_INTERRUPT_MASK_HDCPM_MASK 0x00000010 +#define AV8100_GENERAL_INTERRUPT_MASK_HDCPM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_HDCPM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_HDCPM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, HDCPM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_HDCPM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, HDCPM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_UOVBM_SHIFT 5 +#define AV8100_GENERAL_INTERRUPT_MASK_UOVBM_MASK 0x00000020 +#define AV8100_GENERAL_INTERRUPT_MASK_UOVBM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_UOVBM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, UOVBM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_UOVBM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, UOVBM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_TEM_SHIFT 6 +#define AV8100_GENERAL_INTERRUPT_MASK_TEM_MASK 0x00000040 +#define AV8100_GENERAL_INTERRUPT_MASK_TEM_HIGH 1 +#define AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW 0 +#define AV8100_GENERAL_INTERRUPT_MASK_TEM(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT_MASK, TEM, __x) +#define AV8100_GENERAL_INTERRUPT_MASK_TEM_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT_MASK, TEM, __x) +#define AV8100_GENERAL_INTERRUPT 0x00000005 +#define AV8100_GENERAL_INTERRUPT_EOCI_SHIFT 0 +#define AV8100_GENERAL_INTERRUPT_EOCI_MASK 0x00000001 +#define AV8100_GENERAL_INTERRUPT_EOCI(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, EOCI, __x) +#define AV8100_GENERAL_INTERRUPT_EOCI_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, EOCI, __x) +#define AV8100_GENERAL_INTERRUPT_VSII_SHIFT 1 +#define AV8100_GENERAL_INTERRUPT_VSII_MASK 0x00000002 +#define AV8100_GENERAL_INTERRUPT_VSII(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, VSII, __x) +#define AV8100_GENERAL_INTERRUPT_VSII_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, VSII, __x) +#define AV8100_GENERAL_INTERRUPT_VSOI_SHIFT 2 +#define AV8100_GENERAL_INTERRUPT_VSOI_MASK 0x00000004 +#define AV8100_GENERAL_INTERRUPT_VSOI(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, VSOI, __x) +#define AV8100_GENERAL_INTERRUPT_VSOI_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, VSOI, __x) +#define AV8100_GENERAL_INTERRUPT_CECI_SHIFT 3 +#define AV8100_GENERAL_INTERRUPT_CECI_MASK 0x00000008 +#define AV8100_GENERAL_INTERRUPT_CECI(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, CECI, __x) +#define AV8100_GENERAL_INTERRUPT_CECI_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, CECI, __x) +#define AV8100_GENERAL_INTERRUPT_HDCPI_SHIFT 4 +#define AV8100_GENERAL_INTERRUPT_HDCPI_MASK 0x00000010 +#define AV8100_GENERAL_INTERRUPT_HDCPI(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, HDCPI, __x) +#define AV8100_GENERAL_INTERRUPT_HDCPI_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, HDCPI, __x) +#define AV8100_GENERAL_INTERRUPT_UOVBI_SHIFT 5 +#define AV8100_GENERAL_INTERRUPT_UOVBI_MASK 0x00000020 +#define AV8100_GENERAL_INTERRUPT_UOVBI(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, UOVBI, __x) +#define AV8100_GENERAL_INTERRUPT_UOVBI_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, UOVBI, __x) +#define AV8100_GENERAL_INTERRUPT_TEI_SHIFT 6 +#define AV8100_GENERAL_INTERRUPT_TEI_MASK 0x00000040 +#define AV8100_GENERAL_INTERRUPT_TEI(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_INTERRUPT, TEI, __x) +#define AV8100_GENERAL_INTERRUPT_TEI_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_INTERRUPT, TEI, __x) +#define AV8100_GENERAL_STATUS 0x00000006 +#define AV8100_GENERAL_STATUS_CECTXERR_SHIFT 0 +#define AV8100_GENERAL_STATUS_CECTXERR_MASK 0x00000001 +#define AV8100_GENERAL_STATUS_CECTXERR_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_STATUS, CECTXERR, __x) +#define AV8100_GENERAL_STATUS_CECREC_SHIFT 1 +#define AV8100_GENERAL_STATUS_CECREC_MASK 0x00000002 +#define AV8100_GENERAL_STATUS_CECREC_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_STATUS, CECREC, __x) +#define AV8100_GENERAL_STATUS_CECTRX_SHIFT 2 +#define AV8100_GENERAL_STATUS_CECTRX_MASK 0x00000004 +#define AV8100_GENERAL_STATUS_CECTRX_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_STATUS, CECTRX, __x) +#define AV8100_GENERAL_STATUS_UC_SHIFT 3 +#define AV8100_GENERAL_STATUS_UC_MASK 0x00000008 +#define AV8100_GENERAL_STATUS_UC_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_STATUS, UC, __x) +#define AV8100_GENERAL_STATUS_ONUVB_SHIFT 4 +#define AV8100_GENERAL_STATUS_ONUVB_MASK 0x00000010 +#define AV8100_GENERAL_STATUS_ONUVB_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_STATUS, ONUVB, __x) +#define AV8100_GENERAL_STATUS_HDCPS_SHIFT 5 +#define AV8100_GENERAL_STATUS_HDCPS_MASK 0x000000E0 +#define AV8100_GENERAL_STATUS_HDCPS_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_STATUS, HDCPS, __x) +#define AV8100_GPIO_CONFIGURATION 0x00000007 +#define AV8100_GPIO_CONFIGURATION_DAT3DIR_SHIFT 0 +#define AV8100_GPIO_CONFIGURATION_DAT3DIR_MASK 0x00000001 +#define AV8100_GPIO_CONFIGURATION_DAT3DIR(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, DAT3DIR, __x) +#define AV8100_GPIO_CONFIGURATION_DAT3DIR_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, DAT3DIR, __x) +#define AV8100_GPIO_CONFIGURATION_DAT3VAL_SHIFT 1 +#define AV8100_GPIO_CONFIGURATION_DAT3VAL_MASK 0x00000002 +#define AV8100_GPIO_CONFIGURATION_DAT3VAL(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, DAT3VAL, __x) +#define AV8100_GPIO_CONFIGURATION_DAT3VAL_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, DAT3VAL, __x) +#define AV8100_GPIO_CONFIGURATION_DAT2DIR_SHIFT 2 +#define AV8100_GPIO_CONFIGURATION_DAT2DIR_MASK 0x00000004 +#define AV8100_GPIO_CONFIGURATION_DAT2DIR(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, DAT2DIR, __x) +#define AV8100_GPIO_CONFIGURATION_DAT2DIR_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, DAT2DIR, __x) +#define AV8100_GPIO_CONFIGURATION_DAT2VAL_SHIFT 3 +#define AV8100_GPIO_CONFIGURATION_DAT2VAL_MASK 0x00000008 +#define AV8100_GPIO_CONFIGURATION_DAT2VAL(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, DAT2VAL, __x) +#define AV8100_GPIO_CONFIGURATION_DAT2VAL_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, DAT2VAL, __x) +#define AV8100_GPIO_CONFIGURATION_DAT1DIR_SHIFT 4 +#define AV8100_GPIO_CONFIGURATION_DAT1DIR_MASK 0x00000010 +#define AV8100_GPIO_CONFIGURATION_DAT1DIR(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, DAT1DIR, __x) +#define AV8100_GPIO_CONFIGURATION_DAT1DIR_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, DAT1DIR, __x) +#define AV8100_GPIO_CONFIGURATION_DAT1VAL_SHIFT 5 +#define AV8100_GPIO_CONFIGURATION_DAT1VAL_MASK 0x00000020 +#define AV8100_GPIO_CONFIGURATION_DAT1VAL(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, DAT1VAL, __x) +#define AV8100_GPIO_CONFIGURATION_DAT1VAL_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, DAT1VAL, __x) +#define AV8100_GPIO_CONFIGURATION_UCDBG_SHIFT 6 +#define AV8100_GPIO_CONFIGURATION_UCDBG_MASK 0x00000040 +#define AV8100_GPIO_CONFIGURATION_UCDBG(__x) \ + AV8100_VAL2REG(AV8100_GPIO_CONFIGURATION, UCDBG, __x) +#define AV8100_GPIO_CONFIGURATION_UCDBG_GET(__x) \ + AV8100_REG2VAL(AV8100_GPIO_CONFIGURATION, UCDBG, __x) +#define AV8100_GENERAL_CONTROL 0x00000008 +#define AV8100_GENERAL_CONTROL_FDL_SHIFT 4 +#define AV8100_GENERAL_CONTROL_FDL_MASK 0x00000010 +#define AV8100_GENERAL_CONTROL_FDL_HIGH 1 +#define AV8100_GENERAL_CONTROL_FDL_LOW 0 +#define AV8100_GENERAL_CONTROL_FDL(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_CONTROL, FDL, __x) +#define AV8100_GENERAL_CONTROL_FDL_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_CONTROL, FDL, __x) +#define AV8100_GENERAL_CONTROL_HLD_SHIFT 5 +#define AV8100_GENERAL_CONTROL_HLD_MASK 0x00000020 +#define AV8100_GENERAL_CONTROL_HLD_HIGH 1 +#define AV8100_GENERAL_CONTROL_HLD_LOW 0 +#define AV8100_GENERAL_CONTROL_HLD(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_CONTROL, HLD, __x) +#define AV8100_GENERAL_CONTROL_HLD_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_CONTROL, HLD, __x) +#define AV8100_GENERAL_CONTROL_WA_SHIFT 6 +#define AV8100_GENERAL_CONTROL_WA_MASK 0x00000040 +#define AV8100_GENERAL_CONTROL_WA_HIGH 1 +#define AV8100_GENERAL_CONTROL_WA_LOW 0 +#define AV8100_GENERAL_CONTROL_WA(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_CONTROL, WA, __x) +#define AV8100_GENERAL_CONTROL_WA_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_CONTROL, WA, __x) +#define AV8100_GENERAL_CONTROL_RA_SHIFT 7 +#define AV8100_GENERAL_CONTROL_RA_MASK 0x00000080 +#define AV8100_GENERAL_CONTROL_RA_HIGH 1 +#define AV8100_GENERAL_CONTROL_RA_LOW 0 +#define AV8100_GENERAL_CONTROL_RA(__x) \ + AV8100_VAL2REG(AV8100_GENERAL_CONTROL, RA, __x) +#define AV8100_GENERAL_CONTROL_RA_GET(__x) \ + AV8100_REG2VAL(AV8100_GENERAL_CONTROL, RA, __x) +#define AV8100_FIRMWARE_DOWNLOAD_ENTRY 0x0000000F +#define AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY_SHIFT 0 +#define AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY_MASK 0x000000FF +#define AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY(__x) \ + AV8100_VAL2REG(AV8100_FIRMWARE_DOWNLOAD_ENTRY, MBYTE_CODE_ENTRY, __x) +#define AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY_GET(__x) \ + AV8100_REG2VAL(AV8100_FIRMWARE_DOWNLOAD_ENTRY, MBYTE_CODE_ENTRY, __x) diff --git a/drivers/video/av8100/hdmi.c b/drivers/video/av8100/hdmi.c new file mode 100644 index 00000000000..0c7468a09a1 --- /dev/null +++ b/drivers/video/av8100/hdmi.c @@ -0,0 +1,2220 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * + * ST-Ericsson HDMI driver + * + * Author: Per Persson <per.xb.persson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL), version 2. + */ + +#include <linux/kernel.h> +#include <linux/miscdevice.h> +#include <linux/device.h> +#include <linux/fs.h> +#include <linux/ioctl.h> +#include <linux/uaccess.h> +#include <video/av8100.h> +#include <video/hdmi.h> +#include <linux/poll.h> +#include <linux/mutex.h> +#include <linux/ctype.h> +#include "hdmi_loc.h" +#include <linux/slab.h> +#include <linux/sched.h> + +#define SYSFS_EVENT_FILENAME "evread" + +DEFINE_MUTEX(hdmi_events_mutex); +#define LOCK_HDMI_EVENTS mutex_lock(&hdmi_events_mutex) +#define UNLOCK_HDMI_EVENTS mutex_unlock(&hdmi_events_mutex) +#define EVENTS_MASK 0xFF + +static int device_open; +static int events; +static int events_mask; +static bool events_received; +static wait_queue_head_t hdmi_event_wq; +struct device *hdmidev; + +static ssize_t store_storeastext(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t store_plugdeten(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t store_edidread(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_edidread(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t store_ceceven(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_cecread(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t store_cecsend(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t store_infofrsend(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t store_hdcpeven(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_hdcpchkaesotp(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t store_hdcpfuseaes(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_hdcpfuseaes(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t store_hdcploadaes(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_hdcploadaes(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t store_hdcpauthencr(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_hdcpauthencr(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t show_hdcpstateget(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t show_evread(struct device *dev, struct device_attribute *attr, + char *buf); +static ssize_t store_evclr(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t store_audiocfg(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); +static ssize_t show_plugstatus(struct device *dev, + struct device_attribute *attr, char *buf); +static ssize_t store_poweronoff(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count); + +static DEVICE_ATTR(storeastext, S_IWUSR, NULL, store_storeastext); +static DEVICE_ATTR(plugdeten, S_IWUSR, NULL, store_plugdeten); +static DEVICE_ATTR(edidread, S_IRUGO | S_IWUSR, show_edidread, store_edidread); +static DEVICE_ATTR(ceceven, S_IWUSR, NULL, store_ceceven); +static DEVICE_ATTR(cecread, S_IRUGO, show_cecread, NULL); +static DEVICE_ATTR(cecsend, S_IWUSR, NULL, store_cecsend); +static DEVICE_ATTR(infofrsend, S_IWUSR, NULL, store_infofrsend); +static DEVICE_ATTR(hdcpeven, S_IWUSR, NULL, store_hdcpeven); +static DEVICE_ATTR(hdcpchkaesotp, S_IRUGO, show_hdcpchkaesotp, NULL); +static DEVICE_ATTR(hdcpfuseaes, S_IRUGO | S_IWUSR, show_hdcpfuseaes, + store_hdcpfuseaes); +static DEVICE_ATTR(hdcploadaes, S_IRUGO | S_IWUSR, show_hdcploadaes, + store_hdcploadaes); +static DEVICE_ATTR(hdcpauthencr, S_IRUGO | S_IWUSR, show_hdcpauthencr, + store_hdcpauthencr); +static DEVICE_ATTR(hdcpstateget, S_IRUGO, show_hdcpstateget, NULL); +static DEVICE_ATTR(evread, S_IRUGO, show_evread, NULL); +static DEVICE_ATTR(evclr, S_IWUSR, NULL, store_evclr); +static DEVICE_ATTR(audiocfg, S_IWUSR, NULL, store_audiocfg); +static DEVICE_ATTR(plugstatus, S_IRUGO, show_plugstatus, NULL); +static DEVICE_ATTR(poweronoff, S_IWUSR, NULL, store_poweronoff); + +/* Hex to int conversion */ +static unsigned int htoi(const char *ptr) +{ + unsigned int value = 0; + char ch = *ptr; + + if (!ptr) + return 0; + + if (isdigit(ch)) + value = ch - '0'; + else + value = toupper(ch) - 'A' + 10; + + value <<= 4; + ch = *(++ptr); + + if (isdigit(ch)) + value += ch - '0'; + else + value += toupper(ch) - 'A' + 10; + + return value; +} + +static int event_enable(bool enable, enum hdmi_event ev) +{ + struct av8100_status status; + + dev_dbg(hdmidev, "enable_event %d %02x\n", enable, ev); + if (enable) { + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_IDLE) { + av8100_disable_interrupt(); + av8100_enable_interrupt(); + } + + events_mask |= ev; + } else + events_mask &= ~ev; + + return 0; +} + +static int plugdeten(struct plug_detect *pldet) +{ + struct av8100_status status; + u8 denc_off_time = 0; + int retval; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + av8100_reg_hdmi_5_volt_time_r(&denc_off_time, NULL, NULL); + + retval = av8100_reg_hdmi_5_volt_time_w( + denc_off_time, + pldet->hdmi_off_time, + pldet->on_time); + + if (retval) { + dev_err(hdmidev, "Failed to write the value to av8100 " + "register\n"); + return -EFAULT; + } + + event_enable(pldet->hdmi_detect_enable != 0, + HDMI_EVENT_HDMI_PLUGIN); + event_enable(pldet->hdmi_detect_enable != 0, + HDMI_EVENT_HDMI_PLUGOUT); + + return retval; +} + +static int edidread(struct edid_read *edidread, u8 *len, u8 *data) +{ + union av8100_configuration config; + struct av8100_status status; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + config.edid_section_readback_format.address = edidread->address; + config.edid_section_readback_format.block_number = edidread->block_nr; + + dev_dbg(hdmidev, "addr:%0x blnr:%0x", + config.edid_section_readback_format.address, + config.edid_section_readback_format.block_number); + + if (av8100_conf_prep(AV8100_COMMAND_EDID_SECTION_READBACK, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_EDID_SECTION_READBACK, + len, data, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + dev_dbg(hdmidev, "len:%0x\n", *len); + + return 0; +} + +static int cecread(u8 *src, u8 *dest, u8 *data_len, u8 *data) +{ + union av8100_configuration config; + struct av8100_status status; + u8 buf_len; + u8 buff[HDMI_CEC_READ_MAXSIZE]; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + if (av8100_conf_prep(AV8100_COMMAND_CEC_MESSAGE_READ_BACK, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_CEC_MESSAGE_READ_BACK, + &buf_len, buff, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + if (buf_len > 0) { + *src = (buff[0] & 0xF0) >> 4; + *dest = buff[0] & 0x0F; + *data_len = buf_len - 1; + memcpy(data, &buff[1], buf_len - 1); + } else + *data_len = 0; + + return 0; +} + +static int cecsend(u8 src, u8 dest, u8 data_len, u8 *data) +{ + union av8100_configuration config; + struct av8100_status status; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + config.cec_message_write_format.buffer[0] = ((src & 0x0F) << 4) + + (dest & 0x0F); + config.cec_message_write_format.buffer_length = data_len + 1; + memcpy(&config.cec_message_write_format.buffer[1], data, data_len); + + if (av8100_conf_prep(AV8100_COMMAND_CEC_MESSAGE_WRITE, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_CEC_MESSAGE_WRITE, + NULL, NULL, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + return 0; +} + +static int infofrsend(u8 type, u8 version, u8 crc, u8 data_len, u8 *data) +{ + union av8100_configuration config; + struct av8100_status status; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + if ((data_len < 1) || (data_len > HDMI_INFOFRAME_MAX_SIZE)) + return -EINVAL; + + config.infoframes_format.type = type; + config.infoframes_format.version = version; + config.infoframes_format.crc = crc; + config.infoframes_format.length = data_len; + memcpy(&config.infoframes_format.data, data, data_len); + if (av8100_conf_prep(AV8100_COMMAND_INFOFRAMES, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_INFOFRAMES, + NULL, NULL, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + return 0; +} + +static int hdcpchkaesotp(u8 *crc, u8 *progged) +{ + union av8100_configuration config; + struct av8100_status status; + u8 buf_len; + u8 buf[2]; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != + 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + config.fuse_aes_key_format.fuse_operation = AV8100_FUSE_READ; + memset(config.fuse_aes_key_format.key, 0, AV8100_FUSE_KEY_SIZE); + if (av8100_conf_prep(AV8100_COMMAND_FUSE_AES_KEY, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_FUSE_AES_KEY, + &buf_len, buf, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + if (buf_len == 2) { + *crc = buf[0]; + *progged = buf[1]; + } + + return 0; +} + +static int hdcpfuseaes(u8 *key, u8 crc, u8 *result) +{ + union av8100_configuration config; + struct av8100_status status; + u8 buf_len; + u8 buf[2]; + + /* Default not OK */ + *result = HDMI_RESULT_NOT_OK; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != + 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + config.fuse_aes_key_format.fuse_operation = AV8100_FUSE_WRITE; + memcpy(config.fuse_aes_key_format.key, key, AV8100_FUSE_KEY_SIZE); + if (av8100_conf_prep(AV8100_COMMAND_FUSE_AES_KEY, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_FUSE_AES_KEY, + &buf_len, buf, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + if (buf_len == 2) { + dev_dbg(hdmidev, "buf[0]:%02x buf[1]:%02x\n", buf[0], buf[1]); + if ((crc == buf[0]) && (buf[1] == 1)) + /* OK */ + *result = HDMI_RESULT_OK; + else + *result = HDMI_RESULT_CRC_MISMATCH; + } + + return 0; +} + +static int hdcploadaes(u8 block, u8 key_len, u8 *key, u8 *result, u8 *crc32) +{ + union av8100_configuration config; + struct av8100_status status; + u8 buf_len; + u8 buf[CRC32_SIZE]; + + /* Default not OK */ + *result = HDMI_RESULT_NOT_OK; + + dev_dbg(hdmidev, "%s block:%d\n", __func__, block); + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + config.hdcp_send_key_format.key_number = block; + config.hdcp_send_key_format.data_len = key_len; + memcpy(config.hdcp_send_key_format.data, key, key_len); + if (av8100_conf_prep(AV8100_COMMAND_HDCP_SENDKEY, &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_HDCP_SENDKEY, + &buf_len, buf, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + if ((buf_len == CRC32_SIZE) && (crc32)) { + memcpy(crc32, buf, CRC32_SIZE); + dev_dbg(hdmidev, "crc32:%02x%02x%02x%02x\n", + crc32[0], crc32[1], crc32[2], crc32[3]); + } + + *result = HDMI_RESULT_OK; + + return 0; +} + +static int hdcpauthencr(u8 auth_type, u8 encr_type, u8 *len, u8 *data) +{ + union av8100_configuration config; + struct av8100_status status; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + switch (auth_type) { + case HDMI_HDCP_AUTH_OFF: + default: + config.hdcp_management_format.req_type = + AV8100_HDCP_AUTH_REQ_OFF; + break; + + case HDMI_HDCP_AUTH_START: + config.hdcp_management_format.req_type = + AV8100_HDCP_AUTH_REQ_ON; + break; + + case HDMI_HDCP_AUTH_REV_LIST_REQ: + config.hdcp_management_format.req_type = + AV8100_HDCP_REV_LIST_REQ; + break; + case HDMI_HDCP_AUTH_CONT: + config.hdcp_management_format.req_type = + AV8100_HDCP_AUTH_CONT; + break; + } + + switch (encr_type) { + case HDMI_HDCP_ENCR_OFF: + config.hdcp_management_format.req_encr = + AV8100_HDCP_ENCR_REQ_OFF; + config.hdcp_management_format.encr_use = + AV8100_HDCP_ENCR_USE_OESS; + break; + + case HDMI_HDCP_ENCR_OESS: + config.hdcp_management_format.req_encr = + AV8100_HDCP_ENCR_REQ_ON; + config.hdcp_management_format.encr_use = + AV8100_HDCP_ENCR_USE_OESS; + break; + + case HDMI_HDCP_ENCR_EESS: + config.hdcp_management_format.req_encr = + AV8100_HDCP_ENCR_REQ_ON; + config.hdcp_management_format.encr_use = + AV8100_HDCP_ENCR_USE_EESS; + break; + } + + if (av8100_conf_prep(AV8100_COMMAND_HDCP_MANAGEMENT, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_HDCP_MANAGEMENT, + len, data, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + return 0; +} + +static u8 events_read(void) +{ + int ret; + + LOCK_HDMI_EVENTS; + ret = events; + dev_dbg(hdmidev, "%s %02x\n", __func__, events); + UNLOCK_HDMI_EVENTS; + + return ret; +} + +static int events_clear(u8 ev) +{ + dev_dbg(hdmidev, "%s %02x\n", __func__, ev); + + LOCK_HDMI_EVENTS; + events &= ~ev & EVENTS_MASK; + UNLOCK_HDMI_EVENTS; + + return 0; +} + +static int audiocfg(struct audio_cfg *cfg) +{ + union av8100_configuration config; + struct av8100_status status; + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup failed\n"); + return -EINVAL; + } + } + + if (status.av8100_state < AV8100_OPMODE_INIT) { + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + } + + config.audio_input_format.audio_input_if_format = cfg->if_format; + config.audio_input_format.i2s_input_nb = cfg->i2s_entries; + config.audio_input_format.sample_audio_freq = cfg->freq; + config.audio_input_format.audio_word_lg = cfg->word_length; + config.audio_input_format.audio_format = cfg->format; + config.audio_input_format.audio_if_mode = cfg->if_mode; + config.audio_input_format.audio_mute = cfg->mute; + + if (av8100_conf_prep(AV8100_COMMAND_AUDIO_INPUT_FORMAT, + &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + + if (av8100_conf_w(AV8100_COMMAND_AUDIO_INPUT_FORMAT, + NULL, NULL, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + return 0; +} + +/* sysfs */ +static ssize_t store_storeastext(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if ((count != HDMI_STOREASTEXT_BIN_SIZE) && + (count != HDMI_STOREASTEXT_TEXT_SIZE) && + (count != HDMI_STOREASTEXT_TEXT_SIZE + 1)) + return -EINVAL; + + if ((count == HDMI_STOREASTEXT_BIN_SIZE) && (*buf == 0x1)) + hdmi_driver_data->store_as_hextext = true; + else if (((count == HDMI_STOREASTEXT_TEXT_SIZE) || + (count == HDMI_STOREASTEXT_TEXT_SIZE + 1)) && (*buf == '0') && + (*(buf + 1) == '1')) { + hdmi_driver_data->store_as_hextext = true; + } else { + hdmi_driver_data->store_as_hextext = false; + } + + dev_dbg(hdmidev, "store_as_hextext:%0d\n", + hdmi_driver_data->store_as_hextext); + + return count; +} + +static ssize_t store_plugdeten(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct plug_detect plug_detect; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_PLUGDETEN_TEXT_SIZE) && + (count != HDMI_PLUGDETEN_TEXT_SIZE + 1)) + return -EINVAL; + plug_detect.hdmi_detect_enable = htoi(buf + index); + index += 2; + plug_detect.on_time = htoi(buf + index); + index += 2; + plug_detect.hdmi_off_time = htoi(buf + index); + index += 2; + } else { + if (count != HDMI_PLUGDETEN_BIN_SIZE) + return -EINVAL; + plug_detect.hdmi_detect_enable = *(buf + index++); + plug_detect.on_time = *(buf + index++); + plug_detect.hdmi_off_time = *(buf + index++); + } + + if (plugdeten(&plug_detect)) + return -EINVAL; + + return count; +} + +static ssize_t store_edidread(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct edid_read edid_read; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + dev_dbg(hdmidev, "count:%d\n", count); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_EDIDREAD_TEXT_SIZE) && + (count != HDMI_EDIDREAD_TEXT_SIZE + 1)) + return -EINVAL; + edid_read.address = htoi(buf + index); + index += 2; + edid_read.block_nr = htoi(buf + index); + index += 2; + } else { + if (count != HDMI_EDIDREAD_BIN_SIZE) + return -EINVAL; + edid_read.address = *(buf + index++); + edid_read.block_nr = *(buf + index++); + } + + if (edidread(&edid_read, &hdmi_driver_data->edid_data.buf_len, + hdmi_driver_data->edid_data.buf)) + return -EINVAL; + + return count; +} + +static ssize_t show_edidread(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + int len; + int index = 0; + int cnt; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + len = hdmi_driver_data->edid_data.buf_len; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", len); + index += 2; + } else + *(buf + index++) = len; + + dev_dbg(hdmidev, "len:%02x\n", len); + + cnt = 0; + while (cnt < len) { + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", + hdmi_driver_data->edid_data.buf[cnt]); + index += 2; + } else + *(buf + index++) = + hdmi_driver_data->edid_data.buf[cnt]; + + dev_dbg(hdmidev, "%02x ", + hdmi_driver_data->edid_data.buf[cnt]); + + cnt++; + } + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t store_ceceven(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + bool enable = false; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_CECEVEN_TEXT_SIZE) && + (count != HDMI_CECEVEN_TEXT_SIZE + 1)) + return -EINVAL; + if ((*buf == '0') && (*(buf + 1) == '1')) + enable = true; + } else { + if (count != HDMI_CECEVEN_BIN_SIZE) + return -EINVAL; + if (*buf == 0x01) + enable = true; + } + + event_enable(enable, HDMI_EVENT_CEC | HDMI_EVENT_CECTXERR); + + return count; +} + +static ssize_t show_cecread(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct cec_rw cec_read; + int index = 0; + int cnt; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (cecread(&cec_read.src, &cec_read.dest, &cec_read.length, + cec_read.data)) + return -EINVAL; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", cec_read.src); + index += 2; + snprintf(buf + index, 3, "%02x", cec_read.dest); + index += 2; + snprintf(buf + index, 3, "%02x", cec_read.length); + index += 2; + } else { + *(buf + index++) = cec_read.src; + *(buf + index++) = cec_read.dest; + *(buf + index++) = cec_read.length; + } + + dev_dbg(hdmidev, "len:%02x\n", cec_read.length); + + cnt = 0; + while (cnt < cec_read.length) { + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", cec_read.data[cnt]); + index += 2; + } else + *(buf + index++) = cec_read.data[cnt]; + + dev_dbg(hdmidev, "%02x ", cec_read.data[cnt]); + + cnt++; + } + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t store_cecsend(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct cec_rw cec_w; + int index = 0; + int cnt; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count < HDMI_CECSEND_TEXT_SIZE_MIN) || + (count > HDMI_CECSEND_TEXT_SIZE_MAX)) + return -EINVAL; + + cec_w.src = htoi(buf + index); + index += 2; + cec_w.dest = htoi(buf + index); + index += 2; + cec_w.length = htoi(buf + index); + index += 2; + if (cec_w.length > HDMI_CEC_WRITE_MAXSIZE) + return -EINVAL; + cnt = 0; + while (cnt < cec_w.length) { + cec_w.data[cnt] = htoi(buf + index); + index += 2; + dev_dbg(hdmidev, "%02x ", cec_w.data[cnt]); + cnt++; + } + } else { + if ((count < HDMI_CECSEND_BIN_SIZE_MIN) || + (count > HDMI_CECSEND_BIN_SIZE_MAX)) + return -EINVAL; + + cec_w.src = *(buf + index++); + cec_w.dest = *(buf + index++); + cec_w.length = *(buf + index++); + if (cec_w.length > HDMI_CEC_WRITE_MAXSIZE) + return -EINVAL; + memcpy(cec_w.data, buf + index, cec_w.length); + } + + if (cecsend(cec_w.src, + cec_w.dest, + cec_w.length, + cec_w.data)) + return -EINVAL; + + return count; +} + +static ssize_t store_infofrsend(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct info_fr info_fr; + int index = 0; + int cnt; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count < HDMI_INFOFRSEND_TEXT_SIZE_MIN) || + (count > HDMI_INFOFRSEND_TEXT_SIZE_MAX)) + return -EINVAL; + + info_fr.type = htoi(&buf[index]); + index += 2; + info_fr.ver = htoi(&buf[index]); + index += 2; + info_fr.crc = htoi(&buf[index]); + index += 2; + info_fr.length = htoi(&buf[index]); + index += 2; + + if (info_fr.length > HDMI_INFOFRAME_MAX_SIZE) + return -EINVAL; + cnt = 0; + while (cnt < info_fr.length) { + info_fr.data[cnt] = htoi(buf + index); + index += 2; + dev_dbg(hdmidev, "%02x ", info_fr.data[cnt]); + cnt++; + } + } else { + if ((count < HDMI_INFOFRSEND_BIN_SIZE_MIN) || + (count > HDMI_INFOFRSEND_BIN_SIZE_MAX)) + return -EINVAL; + + info_fr.type = *(buf + index++); + info_fr.ver = *(buf + index++); + info_fr.crc = *(buf + index++); + info_fr.length = *(buf + index++); + + if (info_fr.length > HDMI_INFOFRAME_MAX_SIZE) + return -EINVAL; + memcpy(info_fr.data, buf + index, info_fr.length); + } + + if (infofrsend(info_fr.type, info_fr.ver, info_fr.crc, + info_fr.length, info_fr.data)) + return -EINVAL; + + return count; +} + +static ssize_t store_hdcpeven(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + bool enable = false; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_HDCPEVEN_TEXT_SIZE) && + (count != HDMI_HDCPEVEN_TEXT_SIZE + 1)) + return -EINVAL; + if ((*buf == '0') && (*(buf + 1) == '1')) + enable = true; + } else { + if (count != HDMI_HDCPEVEN_BIN_SIZE) + return -EINVAL; + if (*buf == 0x01) + enable = true; + } + + event_enable(enable, HDMI_EVENT_HDCP); + + return count; +} + +static ssize_t show_hdcpchkaesotp(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + u8 crc; + u8 progged; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdcpchkaesotp(&crc, &progged)) + return -EINVAL; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", progged); + index += 2; + } else { + *(buf + index++) = progged; + } + + dev_dbg(hdmidev, "progged:%02x\n", progged); + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t store_hdcpfuseaes(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct hdcp_fuseaes hdcp_fuseaes; + int index = 0; + int cnt; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + /* Default not OK */ + hdmi_driver_data->fuse_result = HDMI_RESULT_NOT_OK; + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_HDCP_FUSEAES_TEXT_SIZE) && + (count != HDMI_HDCP_FUSEAES_TEXT_SIZE + 1)) + return -EINVAL; + + cnt = 0; + while (cnt < HDMI_HDCP_FUSEAES_KEYSIZE) { + hdcp_fuseaes.key[cnt] = htoi(buf + index); + index += 2; + dev_dbg(hdmidev, "%02x ", hdcp_fuseaes.key[cnt]); + cnt++; + } + hdcp_fuseaes.crc = htoi(&buf[index]); + index += 2; + dev_dbg(hdmidev, "%02x ", hdcp_fuseaes.crc); + } else { + if (count != HDMI_HDCP_FUSEAES_BIN_SIZE) + return -EINVAL; + + memcpy(hdcp_fuseaes.key, buf + index, + HDMI_HDCP_FUSEAES_KEYSIZE); + index += HDMI_HDCP_FUSEAES_KEYSIZE; + hdcp_fuseaes.crc = *(buf + index++); + } + + if (hdcpfuseaes(hdcp_fuseaes.key, hdcp_fuseaes.crc, + &hdcp_fuseaes.result)) + return -EINVAL; + + dev_dbg(hdmidev, "fuseresult:%02x ", hdcp_fuseaes.result); + + hdmi_driver_data->fuse_result = hdcp_fuseaes.result; + + return count; +} + +static ssize_t show_hdcpfuseaes(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", + hdmi_driver_data->fuse_result); + index += 2; + } else + *(buf + index++) = hdmi_driver_data->fuse_result; + + dev_dbg(hdmidev, "status:%02x\n", hdmi_driver_data->fuse_result); + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t store_hdcploadaes(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct hdcp_loadaesone hdcp_loadaes; + int index = 0; + int block_cnt; + int cnt; + u8 crc32_rcvd[CRC32_SIZE]; + u8 crc; + u8 progged; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + /* Default not OK */ + hdmi_driver_data->loadaes_result = HDMI_RESULT_NOT_OK; + + if (hdcpchkaesotp(&crc, &progged)) + return -EINVAL; + + if (!progged) { + /* AES is not fused */ + hdcp_loadaes.result = HDMI_AES_NOT_FUSED; + goto store_hdcploadaes_err; + } + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_HDCP_LOADAES_TEXT_SIZE) && + (count != HDMI_HDCP_LOADAES_TEXT_SIZE + 1)) { + dev_err(hdmidev, "%s", "count mismatch\n"); + return -EINVAL; + } + + /* AES */ + block_cnt = 0; + while (block_cnt < HDMI_HDCP_AES_NR_OF_BLOCKS) { + cnt = 0; + while (cnt < HDMI_HDCP_AES_KEYSIZE) { + hdcp_loadaes.key[cnt] = htoi(buf + index); + index += 2; + dev_dbg(hdmidev, "%02x ", + hdcp_loadaes.key[cnt]); + cnt++; + } + + if (hdcploadaes(block_cnt + HDMI_HDCP_AES_BLOCK_START, + HDMI_HDCP_AES_KEYSIZE, + hdcp_loadaes.key, + &hdcp_loadaes.result, + crc32_rcvd)) { + dev_err(hdmidev, "%s %d\n", + "hdcploadaes err aes block", + block_cnt + HDMI_HDCP_AES_BLOCK_START); + return -EINVAL; + } + + if (hdcp_loadaes.result) + goto store_hdcploadaes_err; + + block_cnt++; + } + + /* KSV */ + memset(hdcp_loadaes.key, 0, HDMI_HDCP_AES_KSVZEROESSIZE); + cnt = HDMI_HDCP_AES_KSVZEROESSIZE; + while (cnt < HDMI_HDCP_AES_KSVSIZE + + HDMI_HDCP_AES_KSVZEROESSIZE) { + hdcp_loadaes.key[cnt] = + htoi(&buf[index]); + index += 2; + dev_dbg(hdmidev, "%02x ", hdcp_loadaes.key[cnt]); + cnt++; + } + + if (hdcploadaes(HDMI_HDCP_KSV_BLOCK, + HDMI_HDCP_AES_KSVSIZE + + HDMI_HDCP_AES_KSVZEROESSIZE, + hdcp_loadaes.key, + &hdcp_loadaes.result, + NULL)) { + dev_err(hdmidev, "%s %d\n", "hdcploadaes err in ksv\n", + block_cnt + HDMI_HDCP_AES_BLOCK_START); + return -EINVAL; + } + + if (hdcp_loadaes.result) + goto store_hdcploadaes_err; + + /* CRC32 */ + for (cnt = 0; cnt < CRC32_SIZE; cnt++) { + hdcp_loadaes.crc32[cnt] = htoi(buf + index); + index += 2; + } + + if (memcmp(hdcp_loadaes.crc32, crc32_rcvd, CRC32_SIZE)) { + dev_dbg(hdmidev, "crc32exp:%02x%02x%02x%02x\n", + hdcp_loadaes.crc32[0], + hdcp_loadaes.crc32[1], + hdcp_loadaes.crc32[2], + hdcp_loadaes.crc32[3]); + hdcp_loadaes.result = HDMI_RESULT_CRC_MISMATCH; + goto store_hdcploadaes_err; + } + } else { + if (count != HDMI_HDCP_LOADAES_BIN_SIZE) { + dev_err(hdmidev, "%s", "count mismatch\n"); + return -EINVAL; + } + + /* AES */ + block_cnt = 0; + while (block_cnt < HDMI_HDCP_AES_NR_OF_BLOCKS) { + memcpy(hdcp_loadaes.key, buf + index, + HDMI_HDCP_AES_KEYSIZE); + index += HDMI_HDCP_AES_KEYSIZE; + + if (hdcploadaes(block_cnt + HDMI_HDCP_AES_BLOCK_START, + HDMI_HDCP_AES_KEYSIZE, + hdcp_loadaes.key, + &hdcp_loadaes.result, + crc32_rcvd)) { + dev_err(hdmidev, "%s %d\n", + "hdcploadaes err aes block", + block_cnt + HDMI_HDCP_AES_BLOCK_START); + return -EINVAL; + } + + if (hdcp_loadaes.result) + goto store_hdcploadaes_err; + + block_cnt++; + } + + /* KSV */ + memset(hdcp_loadaes.key, 0, HDMI_HDCP_AES_KSVZEROESSIZE); + memcpy(hdcp_loadaes.key + HDMI_HDCP_AES_KSVZEROESSIZE, + buf + index, + HDMI_HDCP_AES_KSVSIZE); + index += HDMI_HDCP_AES_KSVSIZE; + + if (hdcploadaes(HDMI_HDCP_KSV_BLOCK, + HDMI_HDCP_AES_KSVSIZE + + HDMI_HDCP_AES_KSVZEROESSIZE, + hdcp_loadaes.key, + &hdcp_loadaes.result, + NULL)) { + dev_err(hdmidev, "%s %d\n", "hdcploadaes err in ksv\n", + block_cnt + HDMI_HDCP_AES_BLOCK_START); + return -EINVAL; + } + + memcpy(hdcp_loadaes.crc32, buf + index, CRC32_SIZE); + index += CRC32_SIZE; + + /* CRC32 */ + if (memcmp(hdcp_loadaes.crc32, crc32_rcvd, CRC32_SIZE)) { + dev_dbg(hdmidev, "crc32exp:%02x%02x%02x%02x\n", + hdcp_loadaes.crc32[0], + hdcp_loadaes.crc32[1], + hdcp_loadaes.crc32[2], + hdcp_loadaes.crc32[3]); + hdcp_loadaes.result = HDMI_RESULT_CRC_MISMATCH; + } + } + +store_hdcploadaes_err: + hdmi_driver_data->loadaes_result = hdcp_loadaes.result; + return count; +} + +static ssize_t show_hdcploadaes(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", + hdmi_driver_data->loadaes_result); + index += 2; + } else + *(buf + index++) = hdmi_driver_data->loadaes_result; + + dev_dbg(hdmidev, "result:%02x\n", hdmi_driver_data->loadaes_result); + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t store_hdcpauthencr(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct hdcp_authencr hdcp_authencr; + int index = 0; + u8 crc; + u8 progged; + int result = HDMI_RESULT_OK; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + /* Default not OK */ + hdmi_driver_data->authencr.result = HDMI_RESULT_NOT_OK; + + if (hdcpchkaesotp(&crc, &progged)) + return -EINVAL; + + if (!progged) { + /* AES is not fused */ + result = HDMI_AES_NOT_FUSED; + goto store_hdcpauthencr_err; + } + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_HDCPAUTHENCR_TEXT_SIZE) && + (count != HDMI_HDCPAUTHENCR_TEXT_SIZE + 1)) + return -EINVAL; + + hdcp_authencr.auth_type = htoi(buf + index); + index += 2; + hdcp_authencr.encr_type = htoi(buf + index); + index += 2; + } else { + if (count != HDMI_HDCPAUTHENCR_BIN_SIZE) + return -EINVAL; + + hdcp_authencr.auth_type = *(buf + index++); + hdcp_authencr.encr_type = *(buf + index++); + } + + if (hdcpauthencr(hdcp_authencr.auth_type, hdcp_authencr.encr_type, + &hdmi_driver_data->authencr.buf_len, + hdmi_driver_data->authencr.buf)) + return -EINVAL; + +store_hdcpauthencr_err: + hdmi_driver_data->authencr.result = result; + return count; +} + +static ssize_t show_hdcpauthencr(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + int len; + int index = 0; + int cnt; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + len = hdmi_driver_data->authencr.buf_len; + if (len > AUTH_BUF_LEN) + len = AUTH_BUF_LEN; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", + hdmi_driver_data->authencr.result); + index += 2; + } else + *(buf + index++) = hdmi_driver_data->authencr.result; + + cnt = 0; + while (cnt < len) { + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", + hdmi_driver_data->authencr.buf[cnt]); + index += 2; + + dev_dbg(hdmidev, "%02x ", + hdmi_driver_data->authencr.buf[cnt]); + + } else + *(buf + index++) = hdmi_driver_data->authencr.buf[cnt]; + + cnt++; + } + + dev_dbg(hdmidev, "result:%02x\n", hdmi_driver_data->authencr.result); + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t show_hdcpstateget(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + u8 hdcp_state; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (av8100_reg_gen_status_r(NULL, NULL, NULL, NULL, NULL, &hdcp_state)) + return -EINVAL; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", hdcp_state); + index += 2; + } else + *(buf + index++) = hdcp_state; + + dev_dbg(hdmidev, "status:%02x\n", hdcp_state); + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t show_evread(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + int index = 0; + u8 ev; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + ev = events_read(); + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", ev); + index += 2; + } else + *(buf + index++) = ev; + + if (hdmi_driver_data->store_as_hextext) + index++; + + /* Events are read: clear events */ + events_clear(EVENTS_MASK); + + return index; +} + +static ssize_t store_evclr(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + u8 ev; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_EVCLR_TEXT_SIZE) && + (count != HDMI_EVCLR_TEXT_SIZE + 1)) + return -EINVAL; + + ev = htoi(&buf[index]); + index += 2; + } else { + if (count != HDMI_EVCLR_BIN_SIZE) + return -EINVAL; + + ev = *(buf + index++); + } + + events_clear(ev); + + return count; +} + +static ssize_t store_audiocfg(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + struct audio_cfg audio_cfg; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_AUDIOCFG_TEXT_SIZE) && + (count != HDMI_AUDIOCFG_TEXT_SIZE + 1)) + return -EINVAL; + + audio_cfg.if_format = htoi(&buf[index]); + index += 2; + audio_cfg.i2s_entries = htoi(&buf[index]); + index += 2; + audio_cfg.freq = htoi(&buf[index]); + index += 2; + audio_cfg.word_length = htoi(&buf[index]); + index += 2; + audio_cfg.format = htoi(&buf[index]); + index += 2; + audio_cfg.if_mode = htoi(&buf[index]); + index += 2; + audio_cfg.mute = htoi(&buf[index]); + index += 2; + } else { + if (count != HDMI_AUDIOCFG_BIN_SIZE) + return -EINVAL; + + audio_cfg.if_format = *(buf + index++); + audio_cfg.i2s_entries = *(buf + index++); + audio_cfg.freq = *(buf + index++); + audio_cfg.word_length = *(buf + index++); + audio_cfg.format = *(buf + index++); + audio_cfg.if_mode = *(buf + index++); + audio_cfg.mute = *(buf + index++); + } + + audiocfg(&audio_cfg); + + return count; +} + +static ssize_t show_plugstatus(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hdmi_driver_data *hdmi_driver_data; + int index = 0; + struct av8100_status av8100_status; + u8 plstat; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + av8100_status = av8100_status_get(); + plstat = av8100_status.av8100_plugin_status == AV8100_HDMI_PLUGIN; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", plstat); + index += 2; + } else + *(buf + index++) = plstat; + + if (hdmi_driver_data->store_as_hextext) + index++; + + return index; +} + +static ssize_t store_poweronoff(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct hdmi_driver_data *hdmi_driver_data; + bool enable = false; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_POWERONOFF_TEXT_SIZE) && + (count != HDMI_POWERONOFF_TEXT_SIZE + 1)) + return -EINVAL; + if ((*buf == '0') && (*(buf + 1) == '1')) + enable = true; + } else { + if (count != HDMI_POWERONOFF_BIN_SIZE) + return -EINVAL; + if (*buf == 0x01) + enable = true; + } + + if (enable == 0) { + if (av8100_powerdown() != 0) { + dev_err(hdmidev, "av8100_powerdown FAIL\n"); + return -EINVAL; + } + } else { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup FAIL\n"); + return -EINVAL; + } + } + + return count; +} + +static int hdmi_open(struct inode *inode, struct file *filp) +{ + if (device_open) + return -EBUSY; + + device_open++; + + return 0; +} + +static int hdmi_release(struct inode *inode, struct file *filp) +{ + if (device_open) + device_open--; + + return 0; +} + +/* ioctl */ +static int hdmi_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + u8 value = 0; + struct plug_detect plug_detect; + struct edid_read edid_read; + struct cec_rw cec_read; + struct cec_rw cec_send; + struct info_fr info_fr; + struct hdcp_fuseaes hdcp_fuseaes; + struct hdcp_loadaesall hdcp_loadaesall; + int block_cnt; + struct hdcp_loadaesone hdcp_loadaesone; + struct hdcp_authencr hdcp_authencr; + struct audio_cfg audio_cfg; + union av8100_configuration config; + struct hdmi_register reg; + struct hdmi_command_register command_reg; + struct av8100_status status; + u8 aes_status; + + switch (cmd) { + + case IOC_PLUG_DETECT_ENABLE: + if (copy_from_user(&plug_detect, (void *)arg, + sizeof(struct plug_detect))) + return -EINVAL; + + if (plugdeten(&plug_detect)) + return -EINVAL; + break; + + case IOC_EDID_READ: + if (copy_from_user(&edid_read, (void *)arg, + sizeof(struct edid_read))) + return -EINVAL; + + if (edidread(&edid_read, &edid_read.data_length, + edid_read.data)) + return -EINVAL; + + if (copy_to_user((void *)arg, (void *)&edid_read, + sizeof(struct edid_read))) { + return -EINVAL; + } + break; + + case IOC_CEC_EVENT_ENABLE: + if (copy_from_user(&value, (void *)arg, sizeof(u8))) + return -EINVAL; + + event_enable(value != 0, HDMI_EVENT_CEC | HDMI_EVENT_CECTXERR); + break; + + case IOC_CEC_READ: + if (cecread(&cec_read.src, &cec_read.dest, &cec_read.length, + cec_read.data)) + return -EINVAL; + + if (copy_to_user((void *)arg, (void *)&cec_read, + sizeof(struct cec_rw))) { + return -EINVAL; + } + break; + + case IOC_CEC_SEND: + if (copy_from_user(&cec_send, (void *)arg, + sizeof(struct cec_rw))) + return -EINVAL; + + if (cecsend(cec_send.src, + cec_send.dest, + cec_send.length, + cec_send.data)) + return -EINVAL; + break; + + case IOC_INFOFRAME_SEND: + if (copy_from_user(&info_fr, (void *)arg, + sizeof(struct info_fr))) + return -EINVAL; + + if (infofrsend(info_fr.type, info_fr.ver, info_fr.crc, + info_fr.length, info_fr.data)) + return -EINVAL; + break; + + case IOC_HDCP_EVENT_ENABLE: + if (copy_from_user(&value, (void *)arg, sizeof(u8))) + return -EINVAL; + + event_enable(value != 0, HDMI_EVENT_HDCP); + break; + + case IOC_HDCP_CHKAESOTP: + if (hdcpchkaesotp(&value, &aes_status)) + return -EINVAL; + + if (copy_to_user((void *)arg, (void *)&aes_status, + sizeof(u8))) { + return -EINVAL; + } + break; + + case IOC_HDCP_FUSEAES: + if (copy_from_user(&hdcp_fuseaes, (void *)arg, + sizeof(struct hdcp_fuseaes))) + return -EINVAL; + + if (hdcpfuseaes(hdcp_fuseaes.key, hdcp_fuseaes.crc, + &hdcp_fuseaes.result)) + return -EINVAL; + + if (copy_to_user((void *)arg, (void *)&hdcp_fuseaes, + sizeof(struct hdcp_fuseaes))) { + return -EINVAL; + } + break; + + case IOC_HDCP_LOADAES: + if (copy_from_user(&hdcp_loadaesall, (void *)arg, + sizeof(struct hdcp_loadaesall))) + return -EINVAL; + + if (hdcpchkaesotp(&value, &aes_status)) + return -EINVAL; + + if (!aes_status) { + /* AES is not fused */ + hdcp_loadaesone.result = HDMI_AES_NOT_FUSED; + goto ioc_hdcploadaes_err; + } + + /* AES */ + block_cnt = 0; + while (block_cnt < HDMI_HDCP_AES_NR_OF_BLOCKS) { + memcpy(hdcp_loadaesone.key, hdcp_loadaesall.key + + block_cnt * HDMI_HDCP_AES_KEYSIZE, + HDMI_HDCP_AES_KEYSIZE); + + if (hdcploadaes(block_cnt + HDMI_HDCP_AES_BLOCK_START, + HDMI_HDCP_AES_KEYSIZE, + hdcp_loadaesone.key, + &hdcp_loadaesone.result, + hdcp_loadaesone.crc32)) + return -EINVAL; + + if (hdcp_loadaesone.result) + return -EINVAL; + + block_cnt++; + } + + /* KSV */ + memset(hdcp_loadaesone.key, 0, HDMI_HDCP_AES_KSVZEROESSIZE); + memcpy(hdcp_loadaesone.key + HDMI_HDCP_AES_KSVZEROESSIZE, + hdcp_loadaesall.ksv, HDMI_HDCP_AES_KSVSIZE); + + if (hdcploadaes(HDMI_HDCP_KSV_BLOCK, + HDMI_HDCP_AES_KSVSIZE + + HDMI_HDCP_AES_KSVZEROESSIZE, + hdcp_loadaesone.key, + &hdcp_loadaesone.result, + NULL)) + return -EINVAL; + + if (hdcp_loadaesone.result) + return -EINVAL; + + /* CRC32 */ + if (memcmp(hdcp_loadaesall.crc32, hdcp_loadaesone.crc32, + CRC32_SIZE)) { + dev_dbg(hdmidev, "crc32exp:%02x%02x%02x%02x\n", + hdcp_loadaesall.crc32[0], + hdcp_loadaesall.crc32[1], + hdcp_loadaesall.crc32[2], + hdcp_loadaesall.crc32[3]); + hdcp_loadaesone.result = HDMI_RESULT_CRC_MISMATCH; + goto ioc_hdcploadaes_err; + } + +ioc_hdcploadaes_err: + hdcp_loadaesall.result = hdcp_loadaesone.result; + + if (copy_to_user((void *)arg, (void *)&hdcp_loadaesall, + sizeof(struct hdcp_loadaesall))) { + return -EINVAL; + } + break; + + case IOC_HDCP_AUTHENCR_REQ: + if (copy_from_user(&hdcp_authencr, (void *)arg, + sizeof(struct hdcp_authencr))) + return -EINVAL; + + /* Default not OK */ + hdcp_authencr.result = HDMI_RESULT_NOT_OK; + + if (hdcpchkaesotp(&value, &aes_status)) + return -EINVAL; + + if (!aes_status) { + /* AES is not fused */ + hdcp_authencr.result = HDMI_AES_NOT_FUSED; + break; + } + + if (hdcpauthencr(hdcp_authencr.auth_type, + hdcp_authencr.encr_type, + &value, + hdcp_authencr.revoc_list)) + return -EINVAL; + + hdcp_authencr.result = HDMI_RESULT_OK; + break; + + case IOC_HDCP_STATE_GET: + if (av8100_reg_gen_status_r(NULL, NULL, NULL, NULL, NULL, + &value)) + return -EINVAL; + + if (copy_to_user((void *)arg, (void *)&value, + sizeof(u8))) { + return -EINVAL; + } + break; + + case IOC_EVENTS_READ: + value = events_read(); + + if (copy_to_user((void *)arg, (void *)&value, + sizeof(u8))) { + return -EINVAL; + } + + /* Events are read: clear events */ + events_clear(EVENTS_MASK); + break; + + case IOC_EVENTS_CLEAR: + if (copy_from_user(&value, (void *)arg, sizeof(u8))) + return -EINVAL; + + events_clear(value); + break; + + case IOC_AUDIO_CFG: + if (copy_from_user(&audio_cfg, (void *)arg, + sizeof(struct audio_cfg))) + return -EINVAL; + + audiocfg(&audio_cfg); + break; + + case IOC_PLUG_STATUS: + status = av8100_status_get(); + value = status.av8100_plugin_status == AV8100_HDMI_PLUGIN; + + if (copy_to_user((void *)arg, (void *)&value, + sizeof(u8))) { + return -EINVAL; + } + break; + + case IOC_POWERONOFF: + /* Get desired power state on or off */ + if (copy_from_user(&value, (void *)arg, sizeof(u8))) + return -EINVAL; + + if (value == 0) { + if (av8100_powerdown() != 0) { + dev_err(hdmidev, "av8100_powerdown FAIL\n"); + return -EINVAL; + } + } else { + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup FAIL\n"); + return -EINVAL; + } + } + break; + + /* Internal */ + case IOC_HDMI_ENABLE_INTERRUPTS: + av8100_disable_interrupt(); + if (av8100_enable_interrupt() != 0) { + dev_err(hdmidev, "av8100_conf_get FAIL\n"); + return -EINVAL; + } + break; + + case IOC_HDMI_DOWNLOAD_FW: + if (av8100_download_firmware(NULL, 0, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100 dl fw FAIL\n"); + return -EINVAL; + } + break; + + case IOC_HDMI_ONOFF: + /* Get desired HDMI mode on or off */ + if (copy_from_user(&value, (void *)arg, sizeof(u8))) + return -EFAULT; + + if (av8100_conf_get(AV8100_COMMAND_HDMI, &config) != 0) { + dev_err(hdmidev, "av8100_conf_get FAIL\n"); + return -EINVAL; + } + if (value == 0) + config.hdmi_format.hdmi_mode = AV8100_HDMI_OFF; + else + config.hdmi_format.hdmi_mode = AV8100_HDMI_ON; + + if (av8100_conf_prep(AV8100_COMMAND_HDMI, &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); + return -EINVAL; + } + if (av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL, + I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + break; + + case IOC_HDMI_REGISTER_WRITE: + if (copy_from_user(®, (void *)arg, + sizeof(struct hdmi_register))) { + return -EINVAL; + } + + if (av8100_reg_w(reg.offset, reg.value) != 0) { + dev_err(hdmidev, "hdmi_register_write FAIL\n"); + return -EINVAL; + } + break; + + case IOC_HDMI_REGISTER_READ: + if (copy_from_user(®, (void *)arg, + sizeof(struct hdmi_register))) { + return -EINVAL; + } + + if (av8100_reg_r(reg.offset, ®.value) != 0) { + dev_err(hdmidev, "hdmi_register_write FAIL\n"); + return -EINVAL; + } + + if (copy_to_user((void *)arg, (void *)®, + sizeof(struct hdmi_register))) { + return -EINVAL; + } + break; + + case IOC_HDMI_STATUS_GET: + status = av8100_status_get(); + + if (copy_to_user((void *)arg, (void *)&status, + sizeof(struct av8100_status))) { + return -EINVAL; + } + break; + + case IOC_HDMI_CONFIGURATION_WRITE: + if (copy_from_user(&command_reg, (void *)arg, + sizeof(struct hdmi_command_register)) != 0) { + dev_err(hdmidev, "IOC_HDMI_CONFIGURATION_WRITE " + "fail 1\n"); + command_reg.return_status = EINVAL; + } else { + if (av8100_conf_w_raw(command_reg.cmd_id, + command_reg.buf_len, + command_reg.buf, + &(command_reg.buf_len), + command_reg.buf) != 0) { + dev_err(hdmidev, "IOC_HDMI_CONFIGURATION_WRITE " + "fail 2\n"); + command_reg.return_status = EINVAL; + } + } + + if (copy_to_user((void *)arg, (void *)&command_reg, + sizeof(struct hdmi_command_register)) != 0) { + return -EINVAL; + } + break; + + default: + break; + } + + return 0; +} + +static unsigned int +hdmi_poll(struct file *filp, poll_table *wait) +{ + unsigned int mask = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + poll_wait(filp, &hdmi_event_wq , wait); + + LOCK_HDMI_EVENTS; + if (events_received == true) { + events_received = false; + mask = POLLIN | POLLRDNORM; + } + UNLOCK_HDMI_EVENTS; + + return mask; +} + +static const struct file_operations hdmi_fops = { + .owner = THIS_MODULE, + .open = hdmi_open, + .release = hdmi_release, + //.ioctl is no longer in use - needs fixing + //.ioctl = hdmi_ioctl, + .poll = hdmi_poll +}; + +static struct miscdevice hdmi_miscdev = { + MISC_DYNAMIC_MINOR, + "hdmi", + &hdmi_fops +}; + +/* Event callback function called by hw driver */ +void hdmi_event(enum av8100_hdmi_event ev) +{ + int events_old; + int events_new; + struct kobject *kobj = &hdmidev->kobj; + + dev_dbg(hdmidev, "hdmi_event %02x\n", ev); + + LOCK_HDMI_EVENTS; + + events_old = events; + + /* Set event */ + switch (ev) { + case AV8100_HDMI_EVENT_HDMI_PLUGIN: + events |= events_mask & HDMI_EVENT_HDMI_PLUGIN; + break; + + case AV8100_HDMI_EVENT_HDMI_PLUGOUT: + events |= events_mask & HDMI_EVENT_HDMI_PLUGOUT; + break; + + case AV8100_HDMI_EVENT_CEC: + events |= events_mask & HDMI_EVENT_CEC; + break; + + case AV8100_HDMI_EVENT_HDCP: + events |= events_mask & HDMI_EVENT_HDCP; + break; + + case AV8100_HDMI_EVENT_CECTXERR: + events |= events_mask & HDMI_EVENT_CECTXERR; + break; + + default: + break; + } + + events_new = events; + + UNLOCK_HDMI_EVENTS; + + dev_dbg(hdmidev, "hdmi events:%02x, events_old:%02x mask:%02x\n", + events_new, events_old, events_mask); + + if (events_new != events_old) { + /* Wake up application waiting for event via call to poll() */ + sysfs_notify(kobj, NULL, SYSFS_EVENT_FILENAME); + + LOCK_HDMI_EVENTS; + events_received = true; + UNLOCK_HDMI_EVENTS; + + wake_up_interruptible(&hdmi_event_wq); + } +} +EXPORT_SYMBOL(hdmi_event); + +int __init hdmi_init(void) +{ + int ret; + struct hdmi_driver_data *hdmi_driver_data; + + ret = misc_register(&hdmi_miscdev); + if (ret) + goto hdmi_init_out; + + hdmidev = hdmi_miscdev.this_device; + + hdmi_driver_data = + kzalloc(sizeof(struct hdmi_driver_data), GFP_KERNEL); + + if (!hdmi_driver_data) + return -ENOMEM; + + dev_set_drvdata(hdmidev, hdmi_driver_data); + + /* Default sysfs file format is hextext */ + hdmi_driver_data->store_as_hextext = true; + + init_waitqueue_head(&hdmi_event_wq); + + if (device_create_file(hdmidev, &dev_attr_storeastext)) + dev_info(hdmidev, "Unable to create storeastext attribute\n"); + if (device_create_file(hdmidev, &dev_attr_plugdeten)) + dev_info(hdmidev, "Unable to create plugdeten attribute\n"); + if (device_create_file(hdmidev, &dev_attr_edidread)) + dev_info(hdmidev, "Unable to create edidread attribute\n"); + if (device_create_file(hdmidev, &dev_attr_ceceven)) + dev_info(hdmidev, "Unable to create ceceven attribute\n"); + if (device_create_file(hdmidev, &dev_attr_cecread)) + dev_info(hdmidev, "Unable to create cecread attribute\n"); + if (device_create_file(hdmidev, &dev_attr_cecsend)) + dev_info(hdmidev, "Unable to create cecsend attribute\n"); + if (device_create_file(hdmidev, &dev_attr_infofrsend)) + dev_info(hdmidev, "Unable to create infofrsend attribute\n"); + if (device_create_file(hdmidev, &dev_attr_hdcpeven)) + dev_info(hdmidev, "Unable to create hdcpeven attribute\n"); + if (device_create_file(hdmidev, &dev_attr_hdcpchkaesotp)) + dev_info(hdmidev, "Unable to create hdcpchkaesotp attribute\n"); + if (device_create_file(hdmidev, &dev_attr_hdcpfuseaes)) + dev_info(hdmidev, "Unable to create hdcpfuseaes attribute\n"); + if (device_create_file(hdmidev, &dev_attr_hdcploadaes)) + dev_info(hdmidev, "Unable to create hdcploadaes attribute\n"); + if (device_create_file(hdmidev, &dev_attr_hdcpauthencr)) + dev_info(hdmidev, "Unable to create hdcpauthreq attribute\n"); + if (device_create_file(hdmidev, &dev_attr_hdcpstateget)) + dev_info(hdmidev, "Unable to create hdcpstateget attribute\n"); + if (device_create_file(hdmidev, &dev_attr_evread)) + dev_info(hdmidev, "Unable to create evread attribute\n"); + if (device_create_file(hdmidev, &dev_attr_evclr)) + dev_info(hdmidev, "Unable to create evclr attribute\n"); + if (device_create_file(hdmidev, &dev_attr_audiocfg)) + dev_info(hdmidev, "Unable to create audiocfg attribute\n"); + if (device_create_file(hdmidev, &dev_attr_plugstatus)) + dev_info(hdmidev, "Unable to create plugstatus attribute\n"); + if (device_create_file(hdmidev, &dev_attr_poweronoff)) + dev_info(hdmidev, "Unable to create poweronoff attribute\n"); + + /* Register event callback */ + av8100_hdmi_event_cb_set(hdmi_event); + +hdmi_init_out: + return ret; +} +late_initcall(hdmi_init); + +void hdmi_exit(void) +{ + struct hdmi_driver_data *hdmi_driver_data; + + /* Deregister event callback */ + av8100_hdmi_event_cb_set(NULL); + + device_remove_file(hdmidev, &dev_attr_storeastext); + device_remove_file(hdmidev, &dev_attr_plugdeten); + device_remove_file(hdmidev, &dev_attr_edidread); + device_remove_file(hdmidev, &dev_attr_ceceven); + device_remove_file(hdmidev, &dev_attr_cecread); + device_remove_file(hdmidev, &dev_attr_cecsend); + device_remove_file(hdmidev, &dev_attr_infofrsend); + device_remove_file(hdmidev, &dev_attr_hdcpeven); + device_remove_file(hdmidev, &dev_attr_hdcpchkaesotp); + device_remove_file(hdmidev, &dev_attr_hdcpfuseaes); + device_remove_file(hdmidev, &dev_attr_hdcploadaes); + device_remove_file(hdmidev, &dev_attr_hdcpauthencr); + device_remove_file(hdmidev, &dev_attr_hdcpstateget); + device_remove_file(hdmidev, &dev_attr_evread); + device_remove_file(hdmidev, &dev_attr_evclr); + device_remove_file(hdmidev, &dev_attr_audiocfg); + device_remove_file(hdmidev, &dev_attr_plugstatus); + device_remove_file(hdmidev, &dev_attr_poweronoff); + + hdmi_driver_data = dev_get_drvdata(hdmidev); + kfree(hdmi_driver_data); + + misc_deregister(&hdmi_miscdev); +} diff --git a/drivers/video/av8100/hdmi_loc.h b/drivers/video/av8100/hdmi_loc.h new file mode 100644 index 00000000000..5db30e7526b --- /dev/null +++ b/drivers/video/av8100/hdmi_loc.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) ST-Ericsson AB 2010 + * + * Author: Per Persson <per.xb.persson@stericsson.com> + * for ST-Ericsson. + * + * License terms: GNU General Public License (GPL), version 2. + */ +#ifndef __HDMI_LOC__H__ +#define __HDMI_LOC__H__ + +#define EDID_BUF_LEN 128 +#define COMMAND_BUF_LEN 128 +#define AES_KEY_SIZE 16 +#define CRC32_SIZE 4 +#define AUTH_BUF_LEN 30 + +struct edid_data { + u8 buf_len; + u8 buf[EDID_BUF_LEN]; +}; + +struct authencr { + int result; + u8 buf_len; + u8 buf[AUTH_BUF_LEN]; +}; + +struct hdmi_register { + unsigned char value; + unsigned char offset; +}; + +struct hdcp_loadaesone { + u8 key[AES_KEY_SIZE]; + u8 result; + u8 crc32[CRC32_SIZE]; +}; + +struct hdmi_driver_data { + bool store_as_hextext; + struct plug_detect plug_detect; + bool enable_cec_event; + struct edid_data edid_data; + struct cec_rw cec_read; + bool fuse_result; + int loadaes_result; + struct authencr authencr; +}; + +struct hdmi_command_register { + unsigned char cmd_id; /* input */ + unsigned char buf_len; /* input, output */ + unsigned char buf[COMMAND_BUF_LEN]; /* input, output */ + unsigned char return_status; /* output */ +}; + +/* Internal */ +#define IOC_HDMI_ENABLE_INTERRUPTS _IOWR(HDMI_IOC_MAGIC, 32, int) +#define IOC_HDMI_DOWNLOAD_FW _IOWR(HDMI_IOC_MAGIC, 33, int) +#define IOC_HDMI_ONOFF _IOWR(HDMI_IOC_MAGIC, 34, int) +#define IOC_HDMI_REGISTER_WRITE _IOWR(HDMI_IOC_MAGIC, 35, int) +#define IOC_HDMI_REGISTER_READ _IOWR(HDMI_IOC_MAGIC, 36, int) +#define IOC_HDMI_STATUS_GET _IOWR(HDMI_IOC_MAGIC, 37, int) +#define IOC_HDMI_CONFIGURATION_WRITE _IOWR(HDMI_IOC_MAGIC, 38, int) + +#endif /* __HDMI_LOC__H__ */ |