diff options
-rw-r--r-- | arch/arm/mach-ux500/board-mop500-mcde.c | 7 | ||||
-rwxr-xr-x | arch/arm/mach-ux500/board-mop500.c | 6 | ||||
-rw-r--r-- | drivers/video/av8100/Kconfig | 18 | ||||
-rw-r--r-- | drivers/video/av8100/Makefile | 3 | ||||
-rw-r--r-- | drivers/video/av8100/av8100.c | 1105 | ||||
-rwxr-xr-x | drivers/video/av8100/av8100_fw.h | 17 | ||||
-rwxr-xr-x | drivers/video/av8100/av8100_regs.h | 12 | ||||
-rw-r--r-- | drivers/video/av8100/av8100v2_fw.h | 1166 | ||||
-rwxr-xr-x[-rw-r--r--] | drivers/video/av8100/hdmi.c | 1819 | ||||
-rwxr-xr-x | drivers/video/av8100/hdmi_loc.h | 57 | ||||
-rwxr-xr-x | drivers/video/mcde/display-av8100.c | 244 | ||||
-rw-r--r-- | drivers/video/mcde/mcde_hw.c | 25 | ||||
-rwxr-xr-x | include/video/av8100.h | 128 | ||||
-rwxr-xr-x[-rw-r--r--] | include/video/hdmi.h | 157 | ||||
-rw-r--r-- | include/video/mcde.h | 1 |
15 files changed, 4128 insertions, 637 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-mcde.c b/arch/arm/mach-ux500/board-mop500-mcde.c index ef1a7274161..eb13cbf9a5e 100644 --- a/arch/arm/mach-ux500/board-mop500-mcde.c +++ b/arch/arm/mach-ux500/board-mop500-mcde.c @@ -61,6 +61,7 @@ static struct mcde_port port0 = { .virt_id = 0, .num_data_lanes = 2, .ui = DSI_UNIT_INTERVAL_0, + .clk_cont = false, }, }, }; @@ -112,6 +113,7 @@ static struct mcde_port subdisplay_port = { .virt_id = 0, .num_data_lanes = 2, .ui = DSI_UNIT_INTERVAL_1, + .clk_cont = false, }, }, @@ -277,17 +279,18 @@ static struct mcde_port port2 = { .pixel_format = MCDE_PORTPIXFMT_DSI_24BPP, .ifc = 1, .link = 2, -#ifdef AV8100_HW_TE_I2SDAT3 +#ifdef CONFIG_AV8100_HWTRIG_I2SDAT3 .sync_src = MCDE_SYNCSRC_TE1, #else .sync_src = MCDE_SYNCSRC_TE0, -#endif /* AV8100_HW_TE_I2SDAT3 */ +#endif /* CONFIG_AV8100_HWTRIG_I2SDAT3 */ .update_auto_trig = true, .phy = { .dsi = { .virt_id = 0, .num_data_lanes = 2, .ui = DSI_UNIT_INTERVAL_2, + .clk_cont = false, }, }, }; diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index 18fb1f853cf..ce173ed335e 100755 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -49,7 +49,6 @@ int href_v1_board; #define MOP500_PLATFORM_ID 0 #define HREF_PLATFORM_ID 1 -/*#define AV8100_HW_TE_I2SDAT3*/ /* REVIEW/TODO: remove? */ int platform_id = MOP500_PLATFORM_ID; /* we have equally similar boards with very minimal @@ -113,8 +112,13 @@ static struct gpio_altfun_data gpio_altfun_table[] = { "mcde tvout"), __GPIO_ALT(GPIO_ALT_LCD_PANELB, 150, 150, 0, NMK_GPIO_ALT_B, "mcde tvout"), +#ifdef CONFIG_AV8100_HWTRIG_I2SDAT3 + __GPIO_ALT(GPIO_ALT_LCD_PANELA, 69, 69, 0, NMK_GPIO_ALT_A, + "mcde tvout"), +#else __GPIO_ALT(GPIO_ALT_LCD_PANELA, 68, 68, 0, NMK_GPIO_ALT_A, "mcde tvout"), +#endif /* CONFIG_AV8100_HWTRIG_I2SDAT3 */ __GPIO_ALT(GPIO_ALT_MMIO_INIT_BOARD, 141, 142, 0, NMK_GPIO_ALT_B, "mmio"), __GPIO_ALT(GPIO_ALT_MMIO_CAM_SET_I2C, 8, 9, 0, NMK_GPIO_ALT_A, "mmio"), diff --git a/drivers/video/av8100/Kconfig b/drivers/video/av8100/Kconfig index 12e44e2c430..6fe0f88d9b8 100644 --- a/drivers/video/av8100/Kconfig +++ b/drivers/video/av8100/Kconfig @@ -3,3 +3,21 @@ config AV8100 default n help Please enable this feature if hdmi/tvout driver support is required. + +config AV8100_HWTRIG_I2SDAT3 + bool "AV8100 HW trig on I2SDAT3" + default n + depends on AV8100 + ---help--- + If you say Y here AV8100 will use HW triggering + from AV8100 I2SDAT3 to MCDE sync1. + If you say N here AV8100 will use HW triggering + method from AV8100 INT to MCDE sync0. + +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 + diff --git a/drivers/video/av8100/Makefile b/drivers/video/av8100/Makefile index d857753b4bc..2d3028b18ca 100644 --- a/drivers/video/av8100/Makefile +++ b/drivers/video/av8100/Makefile @@ -2,6 +2,9 @@ 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 index dd0fcaade23..e4df11441a1 100644 --- a/drivers/video/av8100/av8100.c +++ b/drivers/video/av8100/av8100.c @@ -29,17 +29,18 @@ #include <video/av8100.h> #include <video/hdmi.h> #include "av8100_fw.h" +#include "av8100v2_fw.h" #define AV8100_INT_EVENT 0x1 #define AV8100_TIMER_INT_EVENT 0x2 #define AV8100_TIMER_INTERRUPT_POLLING_TIME 250 -#define AV8100_DRIVER_MINOR_NUMBER 240 #define GPIO_AV8100_RSTN 196 #define AV8100_MASTER_CLOCK_TIMING 0x3 #define AV8100_ON_TIME 1 -#define AV8100_OFF_TIME 0 +#define AV8100_DENC_OFF_TIME 3 +#define AV8100_HDMI_OFF_TIME 0 #define AV8100_COMMAND_OFFSET 0x10 #define AV8100_COMMAND_MAX_LENGTH 0x81 @@ -57,17 +58,28 @@ #define HDMI_CEC_MESSAGE_WRITE_BUFFER_SIZE 16 #define HDMI_HDCP_SEND_KEY_SIZE 7 #define HDMI_INFOFRAME_DATA_SIZE 28 -#define HDMI_CEC_MESSAGE_READBACK_MAXSIZE 16 #define HDMI_FUSE_AES_KEY_SIZE 16 -#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 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_MUTEX(av8100_hw_mutex); +#define LOCK_AV8100_HW mutex_lock(&av8100_hw_mutex) +#define UNLOCK_AV8100_HW mutex_unlock(&av8100_hw_mutex) + +#define AV8100_DEBUG_EXTRA +#define AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS +#define CEC_ADDR_OFFSET 3 struct av8100_config_t { struct i2c_client *client; @@ -94,6 +106,21 @@ struct av8100_config_t { struct av8100_fuse_aes_key_format_cmd hdmi_fuse_aes_key_cmd; }; +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*/ +#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS + u8 hpds_old; + u8 cpds_old; + u8 cecrx_old; + u8 hdcps_old; +#endif + void (*hdmi_ev_cb)(enum av8100_hdmi_event); +}; + /** * struct av8100_cea - CEA(consumer electronic access) standard structure * @cea_id: @@ -142,13 +169,10 @@ enum av8100_command_size { AV8100_COMMAND_FUSE_AES_KEY_SIZE = 0x12, }; -DEFINE_MUTEX(av8100_hw_mutex); -#define LOCK_AV8100_HW mutex_lock(&av8100_hw_mutex) -#define UNLOCK_AV8100_HW mutex_unlock(&av8100_hw_mutex) - -#define AV8100_DEBUG_EXTRA -#define AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS - +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 hdcp_changed(void); 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, @@ -164,6 +188,10 @@ static struct timer_list av8100_timer; #endif 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_V2]; +struct device *av8100dev; static const struct file_operations av8100_fops = { .owner = THIS_MODULE, @@ -173,7 +201,7 @@ static const struct file_operations av8100_fops = { }; static struct miscdevice av8100_miscdev = { - AV8100_DRIVER_MINOR_NUMBER, + MISC_DYNAMIC_MINOR, "av8100", &av8100_fops }; @@ -301,6 +329,101 @@ struct av8100_cea av8100_all_cea[29] = { "-", 0, 0, 0, 0, 0} /*Settings to be define*/ }; +const struct av8100_color_space_conversion_format_cmd col_cvt_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 av8100_color_space_conversion_format_cmd + col_cvt_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 av8100_color_space_conversion_format_cmd col_cvt_yuv422_to_rgb = { + .c0 = 0x00ba, + .c1 = 0x007d, + .c2 = 0x0000, + .c3 = 0xffa1, + .c4 = 0x007d, + .c5 = 0xffd3, + .c6 = 0x0000, + .c7 = 0x007d, + .c8 = 0x00eb, + .aoffset = 0xff9b, + .boffset = 0x003e, + .coffset = 0xff82, + .lmax = 0xff, + .lmin = 0x00, + .cmax = 0xff, + .cmin = 0x00, +}; + +const struct av8100_color_space_conversion_format_cmd col_cvt_yuv422_to_denc = { + .c0 = 0x0000, + .c1 = 0x0000, + .c2 = 0x0100, + .c3 = 0x0000, + .c4 = 0x0100, + .c5 = 0x0000, + .c6 = 0x0100, + .c7 = 0x0000, + .c8 = 0x0000, + .aoffset = 0x0000, + .boffset = 0x0000, + .coffset = 0x0000, + .lmax = 0xeb, + .lmin = 0x10, + .cmax = 0xf0, + .cmin = 0x10, +}; + +const struct av8100_color_space_conversion_format_cmd col_cvt_rgb_to_denc = { + .c0 = 0xffda, + .c1 = 0xffb6, + .c2 = 0x0070, + .c3 = 0x0042, + .c4 = 0x0081, + .c5 = 0x0019, + .c6 = 0x0070, + .c7 = 0xffa2, + .c8 = 0xffee, + .aoffset = 0x007f, + .boffset = 0x0010, + .coffset = 0x007f, + .lmax = 0xff, + .lmin = 0x00, + .cmax = 0xff, + .cmin = 0x00, +}; static const struct i2c_device_id av8100_id[] = { { "av8100", 0 }, @@ -332,15 +455,16 @@ static void av8100_timer_int(unsigned long value) static int av8100_thread(void *p) { - u8 cpd = 0; - u8 stby = 0; u8 hpds = 0; u8 cpds = 0; - u8 mclkrng = 0; + u8 hdcps = 0; int ret = 0; #ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS - u8 hpds_old = 0xf; - u8 cpds_old = 0xf; + u8 cecrx; + u8 *hpds_old; + u8 *cpds_old; + u8 *cecrx_old; + u8 *hdcps_old; #else u8 sid = 0; u8 oni = 0; @@ -351,57 +475,65 @@ static int av8100_thread(void *p) while (1) { wait_event_interruptible(av8100_event, (av8100_flag != 0)); #ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS - if (av8100_flag & AV8100_TIMER_INT_EVENT) { - if (g_av8100_status.av8100_state >= - AV8100_OPMODE_STANDBY) { - /* STANDBY */ - ret = av8100_register_standby_read( - &cpd, - &stby, - &hpds, - &cpds, - &mclkrng); - if (ret != 0) - printk(KERN_DEBUG "av8100_register_" - "standby_read fail\n"); - - /* TVout plugin change */ - if ((cpds == 1) && (cpds != cpds_old)) { - cpds_old = 1; - - g_av8100_status.av8100_plugin_status |= - AV8100_CVBS_PLUGIN; + if ((av8100_flag & AV8100_TIMER_INT_EVENT) && + (g_av8100_status.av8100_state >= + AV8100_OPMODE_STANDBY)) { + hpds_old = &(av8100_globals->hpds_old); + cpds_old = &(av8100_globals->cpds_old); + cecrx_old = &(av8100_globals->cecrx_old); + hdcps_old = &(av8100_globals->hdcps_old); + + /* STANDBY reg */ + if (av8100_reg_stby_r( + NULL, + NULL, + &hpds, + &cpds, + NULL) != 0) + dev_dbg(av8100dev, "av8100_reg_" + "stby_r fail\n"); - /* TODO: notify */ - printk(KERN_DEBUG "TVout plugin detected\n"); - } else if ((cpds == 0) && (cpds != cpds_old)) { - cpds_old = 0; - - g_av8100_status.av8100_plugin_status &= - ~AV8100_CVBS_PLUGIN; + /* TVout plugin change */ + if ((cpds == 1) && (cpds != *cpds_old)) { + *cpds_old = 1; - /* TODO: notify */ - printk(KERN_DEBUG "TVout plugout detected\n"); - } + set_plug_status(AV8100_CVBS_PLUGIN); + } else if ((cpds == 0) && (cpds != *cpds_old)) { + *cpds_old = 0; - /* HDMI plugin change */ - if ((hpds == 1) && (hpds != hpds_old)) { - hpds_old = 1; + clr_plug_status(AV8100_CVBS_PLUGIN); + } - g_av8100_status.av8100_plugin_status |= - AV8100_HDMI_PLUGIN; + /* HDMI plugin change */ + if ((hpds == 1) && (hpds != *hpds_old)) { + *hpds_old = 1; - /* TODO: notify */ - printk(KERN_DEBUG "HDMI plugin detected\n"); - } else if ((hpds == 0) && (hpds != hpds_old)) { - hpds_old = 0; + set_plug_status(AV8100_HDMI_PLUGIN); + } else if ((hpds == 0) && (hpds != *hpds_old)) { + *hpds_old = 0; - g_av8100_status.av8100_plugin_status &= - ~AV8100_HDMI_PLUGIN; + clr_plug_status(AV8100_HDMI_PLUGIN); + } - /* TODO: notify */ - printk(KERN_DEBUG "HDMI plugout detected\n"); - } + /* GENERAL_STATUS reg */ + if (av8100_reg_gen_status_r( + &cecrx, + NULL, + NULL, + NULL, + &hdcps) != 0) + dev_dbg(av8100dev, "av8100_reg_" + "gen_status_r fail\n"); + else { + if ((cecrx == 1) && (cecrx != *cecrx_old)) + /* Report CEC event */ + cec_rx(); + *cecrx_old = cecrx; + + if (hdcps != *hdcps_old) + /* Report HDCP status change event */ + hdcp_changed(); + *hdcps_old = hdcps; } } #else @@ -413,7 +545,7 @@ static int av8100_thread(void *p) &sid); if (ret) - printk(KERN_DEBUG "av8100_register_standby_" + dev_dbg(av8100dev, "av8100_register_standby_" "pending_interrupt_read failed\n"); if (hpdi | cpdi | oni) { @@ -425,36 +557,22 @@ static int av8100_thread(void *p) &cpds, &mclkrng); if (ret) - printk(KERN_DEBUG "av8100_register_standby_" + dev_dbg(av8100dev, "av8100_register_standby_" "read fail\n"); } if (cpdi) { /* TVout plugin change */ if (cpds) - g_av8100_status.av8100_plugin_status |= - AV8100_CVBS_PLUGIN; + set_plug_status(AV8100_CVBS_PLUGIN); else - g_av8100_status.av8100_plugin_status &= - ~AV8100_CVBS_PLUGIN; - - /* TODO: notify */ - printk(KERN_DEBUG "TVout plugin: %d\n", ( - g_av8100_status.av8100_plugin_status & - AV8100_CVBS_PLUGIN) == AV8100_CVBS_PLUGIN); + clr_plug_status(AV8100_CVBS_PLUGIN); } else if (hpdi) { /* HDMI plugin change */ if (hpds) - g_av8100_status.av8100_plugin_status |= - AV8100_HDMI_PLUGIN; + set_plug_status(AV8100_HDMI_PLUGIN); else - g_av8100_status.av8100_plugin_status &= - ~AV8100_HDMI_PLUGIN; - - /* TODO: notify */ - printk(KERN_DEBUG "HDMI plugin: %d\n", ( - g_av8100_status.av8100_plugin_status & - AV8100_HDMI_PLUGIN) == AV8100_HDMI_PLUGIN); + clr_plug_status(AV8100_HDMI_PLUGIN); } if (hpdi | cpdi | oni) { @@ -464,7 +582,7 @@ static int av8100_thread(void *p) cpdi, oni); if (ret) - printk(KERN_DEBUG "av8100_register_standby_" + dev_dbg(av8100dev, "av8100_register_standby_" "read fail\n"); } #endif @@ -603,15 +721,14 @@ static int av8100_config_video_output_dep(enum av8100_output_CEA_VESA 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); -/* TODO: Dynamic test to detect AV8100 V1 or V2 */ -#ifdef AV8100_HW_TE_I2SDAT3 +#ifdef CONFIG_AV8100_HWTRIG_I2SDAT3 config.video_input_format.TE_config = AV8100_TE_GPIO_IT; #else config.video_input_format.TE_config = AV8100_TE_IT_LINE; #endif config.video_input_format.master_clock_freq = 0; - retval = av8100_configuration_prepare( + retval = av8100_conf_prep( AV8100_COMMAND_VIDEO_INPUT_FORMAT, &config); /* DENC */ @@ -639,11 +756,11 @@ static int av8100_config_init(void) int retval = 0; union av8100_configuration config; - printk(KERN_DEBUG "%s\n", __func__); + dev_dbg(av8100dev, "%s\n", __func__); av8100_config = kzalloc(sizeof(struct av8100_config_t), GFP_KERNEL); if (!av8100_config) { - pr_err("%s: Failed to allocate config\n", __func__); + dev_err(av8100dev, "%s: Failed to allocate config\n", __func__); return AV8100_FAIL; } @@ -651,24 +768,8 @@ static int av8100_config_init(void) memset(av8100_config, 0, sizeof(union av8100_configuration)); /* Color conversion */ - /* TODO: Magic numbers. Move to platform data? */ - config.color_space_conversion_format.c0 = 0x0100; - config.color_space_conversion_format.c1 = 0x0000; - config.color_space_conversion_format.c2 = 0x0000; - config.color_space_conversion_format.c3 = 0x0000; - config.color_space_conversion_format.c4 = 0x0100; - config.color_space_conversion_format.c5 = 0x0000; - config.color_space_conversion_format.c6 = 0x0000; - config.color_space_conversion_format.c7 = 0x0000; - config.color_space_conversion_format.c8 = 0x0100; - config.color_space_conversion_format.aoffset = 0x0000; - config.color_space_conversion_format.boffset = 0x0000; - config.color_space_conversion_format.coffset = 0x0000; - config.color_space_conversion_format.lmax = 0xff; - config.color_space_conversion_format.lmin = 0x00; - config.color_space_conversion_format.cmax = 0xff; - config.color_space_conversion_format.cmin = 0x00; - retval = av8100_configuration_prepare( + config.color_space_conversion_format = col_cvt_identity; + retval = av8100_conf_prep( AV8100_COMMAND_COLORSPACECONVERSION, &config); if (retval) return AV8100_FAIL; @@ -684,7 +785,7 @@ static int av8100_config_init(void) config.video_output_format.video_output_cea_vesa = AV8100_CEA4_1280X720P_60HZ; - retval = av8100_configuration_prepare( + retval = av8100_conf_prep( AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, &config); if (retval) return AV8100_FAIL; @@ -700,7 +801,7 @@ static int av8100_config_init(void) AV8100_PATTERN_GENERATOR; config.pattern_generator_format.pattern_video_format = AV8100_PATTERN_720P; - retval = av8100_configuration_prepare(AV8100_COMMAND_PATTERNGENERATOR, + retval = av8100_conf_prep(AV8100_COMMAND_PATTERNGENERATOR, &config); if (retval) return AV8100_FAIL; @@ -714,7 +815,7 @@ static int av8100_config_init(void) 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_configuration_prepare( + retval = av8100_conf_prep( AV8100_COMMAND_AUDIO_INPUT_FORMAT, &config); if (retval) return AV8100_FAIL; @@ -723,14 +824,14 @@ static int av8100_config_init(void) 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_configuration_prepare(AV8100_COMMAND_HDMI, &config); + retval = av8100_conf_prep(AV8100_COMMAND_HDMI, &config); if (retval) return AV8100_FAIL; /* EDID section readback */ config.edid_section_readback_format.address = 0xA0; config.edid_section_readback_format.block_number = 0; - retval = av8100_configuration_prepare( + retval = av8100_conf_prep( AV8100_COMMAND_EDID_SECTION_READBACK, &config); if (retval) return AV8100_FAIL; @@ -740,15 +841,105 @@ static int av8100_config_init(void) static void av8100_config_exit(void) { - printk(KERN_DEBUG "%s\n", __func__); + 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_LOW; + av8100_globals->cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_LOW; +#ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS + av8100_globals->hpds_old = 0xf; + av8100_globals->cpds_old = 0xf; + av8100_globals->cecrx_old = 0xf; + av8100_globals->hdcps_old = 0xf; +#endif + + 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->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->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->hdmi_ev_cb) + av8100_globals->hdmi_ev_cb(AV8100_HDMI_EVENT_CEC); +} + +static void hdcp_changed(void) +{ + if (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_STANDBY) { + clr_plug_status(AV8100_HDMI_PLUGIN); + clr_plug_status(AV8100_CVBS_PLUGIN); + g_av8100_status.hdmi_on = false; + } } /** @@ -767,7 +958,7 @@ static int write_single_byte(struct i2c_client *client, u8 reg, ret = i2c_smbus_write_byte_data(client, reg, data); if (ret < 0) - printk(KERN_DEBUG "i2c smbus write byte failed\n"); + dev_dbg(av8100dev, "i2c smbus write byte failed\n"); return ret; } @@ -788,7 +979,7 @@ static int read_single_byte(struct i2c_client *client, u8 reg, u8 *val) value = i2c_smbus_read_byte_data(client, reg); if (value < 0) { - printk(KERN_DEBUG "i2c smbus read byte failed,read data = %x " + dev_dbg(av8100dev, "i2c smbus read byte failed,read data = %x " "from offset:%x\n" , value, reg); return AV8100_FAIL; } @@ -814,7 +1005,7 @@ static int write_multi_byte(struct i2c_client *client, u8 reg, ret = i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf); if (ret < 0) - printk(KERN_DEBUG "i2c smbus write multi byte error\n"); + dev_dbg(av8100dev, "i2c smbus write multi byte error\n"); return ret; } @@ -1014,51 +1205,51 @@ static int configuration_colorspace_conversion_get(char *buffer, if (!av8100_config) return AV8100_FAIL; - buffer[0] = REG_10_8_MSB(av8100_config-> + buffer[0] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c0); buffer[1] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c0); - buffer[2] = REG_10_8_MSB(av8100_config-> + buffer[2] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c1); buffer[3] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c1); - buffer[4] = REG_10_8_MSB(av8100_config-> + buffer[4] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c2); buffer[5] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c2); - buffer[6] = REG_10_8_MSB(av8100_config-> + buffer[6] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c3); buffer[7] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c3); - buffer[8] = REG_10_8_MSB(av8100_config-> + buffer[8] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c4); buffer[9] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c4); - buffer[10] = REG_10_8_MSB(av8100_config-> + buffer[10] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c5); buffer[11] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c5); - buffer[12] = REG_10_8_MSB(av8100_config-> + buffer[12] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c6); buffer[13] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c6); - buffer[14] = REG_10_8_MSB(av8100_config-> + buffer[14] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c7); buffer[15] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c7); - buffer[16] = REG_10_8_MSB(av8100_config-> + buffer[16] = REG_12_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.c8); buffer[17] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.c8); - buffer[18] = REG_16_8_MSB(av8100_config-> + buffer[18] = REG_10_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.aoffset); buffer[19] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.aoffset); - buffer[20] = REG_16_8_MSB(av8100_config-> + buffer[20] = REG_10_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.boffset); buffer[21] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.boffset); - buffer[22] = REG_16_8_MSB(av8100_config-> + buffer[22] = REG_10_8_MSB(av8100_config-> hdmi_color_space_conversion_cmd.coffset); buffer[23] = REG_16_8_LSB(av8100_config-> hdmi_color_space_conversion_cmd.coffset); @@ -1132,11 +1323,10 @@ static int configuration_hdcp_sendkey_get(char *buffer, return AV8100_FAIL; buffer[0] = av8100_config->hdmi_hdcp_send_key_cmd.key_number; - buffer[1] = 0; - memcpy(&buffer[2], av8100_config->hdmi_hdcp_send_key_cmd.key, - HDMI_HDCP_SEND_KEY_SIZE); + memcpy(&buffer[1], av8100_config->hdmi_hdcp_send_key_cmd.data, + av8100_config->hdmi_hdcp_send_key_cmd.data_len); - *length = AV8100_COMMAND_HDCP_SENDKEY_SIZE - 1; + *length = av8100_config->hdmi_hdcp_send_key_cmd.data_len + 1; return 0; } @@ -1146,12 +1336,9 @@ static int configuration_hdcp_management_get(char *buffer, if (!av8100_config) return AV8100_FAIL; - buffer[0] = av8100_config->hdmi_hdcp_management_format_cmd. - request_hdcp_revocation_list; - buffer[1] = av8100_config->hdmi_hdcp_management_format_cmd. - request_encrypted_transmission; - buffer[2] = av8100_config->hdmi_hdcp_management_format_cmd. - oess_eess_encryption_use; + 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; @@ -1227,11 +1414,11 @@ static int get_command_return_data(struct i2c_client *i2c, /* Get the first return byte */ retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET, &val); if (retval) - goto get_command_return_data_fail; + goto get_command_return_data_fail1r; if (val != (0x80 | command_type)) { retval = AV8100_FAIL; - goto get_command_return_data_fail; + goto get_command_return_data_fail1v; } switch (command_type) { @@ -1250,11 +1437,11 @@ static int get_command_return_data(struct i2c_client *i2c, retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET + 1, &val); if (retval) - goto get_command_return_data_fail; + goto get_command_return_data_fail2r; if (val) { retval = AV8100_FAIL; - goto get_command_return_data_fail; + goto get_command_return_data_fail2v; } break; @@ -1266,27 +1453,31 @@ static int get_command_return_data(struct i2c_client *i2c, /* Get the return buffer length */ retval = read_single_byte(i2c, - AV8100_COMMAND_OFFSET + 3, &val); + AV8100_COMMAND_OFFSET + 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_MESSAGE_READBACK_MAXSIZE) { - printk(KERN_DEBUG "CEC size too large %d\n", + HDMI_CEC_READ_MAXSIZE) { + dev_dbg(av8100dev, "CEC size too large %d\n", *buffer_length); - *buffer_length = HDMI_CEC_MESSAGE_READBACK_MAXSIZE; + *buffer_length = HDMI_CEC_READ_MAXSIZE; } #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "return data: "); + dev_dbg(av8100dev, "return data: "); #endif /* Get the return buffer */ for (index = 0; index < *buffer_length; ++index) { retval = read_single_byte(i2c, - AV8100_COMMAND_OFFSET + 4 + index, + AV8100_COMMAND_OFFSET + CEC_ADDR_OFFSET + 1 + + index, &val); if (retval) { *buffer_length = 0; @@ -1294,33 +1485,31 @@ static int get_command_return_data(struct i2c_client *i2c, } else { *(buffer + index) = val; #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "%02x ", *(buffer + index)); + dev_dbg(av8100dev, "%02x ", *(buffer + index)); #endif } } #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "\n"); + dev_dbg(av8100dev, "\n"); #endif break; case AV8100_COMMAND_HDCP_MANAGEMENT: - if ((buffer == NULL) || (buffer_length == NULL) || - (command_buffer == NULL)) { - retval = AV8100_FAIL; - goto get_command_return_data_fail; - } - /* Get the second return byte */ retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET + 1, &val); if (retval) { - goto get_command_return_data_fail; + goto get_command_return_data_fail2r; } else { /* Check the second return byte */ if (val) - goto get_command_return_data_fail; + 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) { @@ -1330,7 +1519,7 @@ static int get_command_return_data(struct i2c_client *i2c, } #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "return data: "); + dev_dbg(av8100dev, "return data: "); #endif /* Get the return buffer */ for (index = 0; index < *buffer_length; ++index) { @@ -1343,12 +1532,12 @@ static int get_command_return_data(struct i2c_client *i2c, } else { *(buffer + index) = val; #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "%02x ", *(buffer + index)); + dev_dbg(av8100dev, "%02x ", *(buffer + index)); #endif } } #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "\n"); + dev_dbg(av8100dev, "\n"); #endif break; @@ -1362,7 +1551,7 @@ static int get_command_return_data(struct i2c_client *i2c, *buffer_length = 0x80; #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "return data: "); + dev_dbg(av8100dev, "return data: "); #endif /* Get the return buffer */ for (index = 0; index < *buffer_length; ++index) { @@ -1375,12 +1564,12 @@ static int get_command_return_data(struct i2c_client *i2c, } else { *(buffer + index) = val; #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "%02x ", *(buffer + index)); + dev_dbg(av8100dev, "%02x ", *(buffer + index)); #endif } } #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "\n"); + dev_dbg(av8100dev, "\n"); #endif break; @@ -1394,12 +1583,12 @@ static int get_command_return_data(struct i2c_client *i2c, retval = read_single_byte(i2c, AV8100_COMMAND_OFFSET + 1, &val); if (retval) - goto get_command_return_data_fail; + goto get_command_return_data_fail2r; /* Check the second return byte */ if (val) { retval = AV8100_FAIL; - goto get_command_return_data_fail; + goto get_command_return_data_fail2v; } /* Return buffer length is fixed */ @@ -1413,7 +1602,7 @@ static int get_command_return_data(struct i2c_client *i2c, *(buffer + 0) = val; #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "CRC:%02x ", val); + dev_dbg(av8100dev, "CRC:%02x ", val); #endif /* Get programmed status */ @@ -1424,7 +1613,7 @@ static int get_command_return_data(struct i2c_client *i2c, *(buffer + 1) = val; #ifdef AV8100_DEBUG_EXTRA - printk(KERN_DEBUG "programmed:%02x ", val); + dev_dbg(av8100dev, "programmed:%02x ", val); #endif break; @@ -1434,96 +1623,94 @@ static int get_command_return_data(struct i2c_client *i2c, } return retval; +get_command_return_data_fail1r: + dev_dbg(av8100dev, "%s Reading first return byte failed\n", __func__); + return retval; +get_command_return_data_fail1v: + dev_dbg(av8100dev, "%s First return byte is wrong:%x\n", __func__, val); + 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: - printk(KERN_DEBUG "get_command_return_data FAIL\n"); + dev_dbg(av8100dev, "%s FAIL\n", __func__); return retval; } -int av8100_powerup(void) +static int av8100_powerup1(void) { int retval = 0; - struct i2c_client *i2c; - u8 cpd; - u8 stby; - u8 hpds; - u8 cpds; - u8 mclkrng; - u8 off_time; - u8 on_time; - u8 fdl; - u8 hld; - u8 wa; - u8 ra; - - if (!av8100_config) - return AV8100_FAIL; - - i2c = av8100_config->client; /* Reset av8100 */ gpio_set_value(GPIO_AV8100_RSTN, 1); av8100_set_state(AV8100_OPMODE_STANDBY); - /* Master clock timing, running, search for plug */ - retval = av8100_register_standby_write(AV8100_STANDBY_CPD_HIGH, - AV8100_STANDBY_STBY_HIGH, AV8100_MASTER_CLOCK_TIMING); + /* Get chip version */ + retval = av8100_reg_stby_pend_int_r(NULL, NULL, NULL, &chip_version); if (retval) { - pr_err("Failed to write the value to av8100 register\n"); + dev_err(av8100dev, "Failed to read chip version\n"); return -EFAULT; } - retval = av8100_register_standby_read(&cpd, &stby, &hpds, &cpds, - &mclkrng); - if (retval) { - pr_err("Failed to read the value from av8100 register\n"); - return -EFAULT; - } else { - printk(KERN_DEBUG "STANDBY_REG register cpd:%d stby:%d " - "hpds:%d cpds:%d mclkrng:%0x\n", cpd, stby, hpds, - cpds, mclkrng); - } + dev_dbg(av8100dev, "av8100 chip version:%d\n", chip_version); - /* ON time & OFF time on 5v HDMI plug detect */ - retval = av8100_register_hdmi_5_volt_time_write(AV8100_OFF_TIME, - AV8100_ON_TIME); - if (retval) { - pr_err("Failed to write the value to av8100 register\n"); - return -EFAULT; - } + switch (chip_version) { + case AV8100_CHIPVER_1: + case AV8100_CHIPVER_2: + break; - retval = av8100_register_hdmi_5_volt_time_read(&off_time, &on_time); - if (retval) { - pr_err("Failed to read the value from av8100 register\n"); + default: + dev_err(av8100dev, "Unsupported av8100 chip version:%d\n", + chip_version); return -EFAULT; - } else { - printk(KERN_DEBUG "AV8100_5_VOLT_TIME_REG register " - "off_time:%0x on_time:%0x\n", off_time, on_time); + break; } - /* Device in hold mode, enable firmware download*/ - retval = av8100_register_general_control_write( - AV8100_GENERAL_CONTROL_FDL_HIGH, - AV8100_GENERAL_CONTROL_HLD_HIGH, - AV8100_GENERAL_CONTROL_WA_LOW, - AV8100_GENERAL_CONTROL_RA_LOW); + return retval; +} + +static int av8100_powerup2(void) +{ + int retval = 0; + + /* Master clock timing, running, search for plug */ + retval = av8100_reg_stby_w(AV8100_STANDBY_CPD_HIGH, + AV8100_STANDBY_STBY_HIGH, AV8100_MASTER_CLOCK_TIMING); if (retval) { - pr_err("Failed to write the value to av8100 register\n"); + dev_err(av8100dev, + "Failed to write the value to av8100 register\n"); return -EFAULT; } - retval = av8100_register_general_control_read(&fdl, &hld, &wa, &ra); + /* 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) { - pr_err("Failed to read the value from av8100 register\n"); + dev_err(av8100dev, + "Failed to write the value to av8100 register\n"); return -EFAULT; - } else { - printk(KERN_DEBUG "GENERAL_CONTROL_REG register fdl:%d " - "hld:%d wa:%d ra:%d\n", fdl, hld, wa, ra); } av8100_set_state(AV8100_OPMODE_SCAN); + return retval; } +int av8100_powerup(void) +{ + if (av8100_powerup1()) { + dev_err(av8100dev, "av8100_powerup1 fail\n"); + return -EFAULT; + } + + return av8100_powerup2(); +} + int av8100_powerdown(void) { gpio_set_value(GPIO_AV8100_RSTN, 0); @@ -1550,6 +1737,10 @@ int av8100_download_firmware(char *fw_buff, int nbytes, u8 uc; u8 onuvb; u8 hdcps; + u8 fdl; + u8 hld; + u8 wa; + u8 ra; if (!av8100_config) { retval = AV8100_FAIL; @@ -1557,13 +1748,44 @@ int av8100_download_firmware(char *fw_buff, int nbytes, } if (fw_buff == NULL) { - /* use default fw buffer */ - fw_buff = av8100_fw_buff; - nbytes = AV8100_FW_SIZE; + switch (chip_version) { + case AV8100_CHIPVER_1: + fw_buff = av8100_fw_buff_v1; + nbytes = AV8100_FW_SIZE_V1; + break; + + case AV8100_CHIPVER_2: + default: + fw_buff = av8100_fw_buff_v2; + nbytes = AV8100_FW_SIZE_V2; + break; + } } 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; @@ -1574,14 +1796,15 @@ int av8100_download_firmware(char *fw_buff, int nbytes, AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, increment); if (retval) { - printk(KERN_DEBUG "Failed to download the " + dev_dbg(av8100dev, "Failed to download the " "av8100 firmware\n"); retval = -EFAULT; UNLOCK_AV8100_HW; goto av8100_download_firmware_out; } } else if (if_type == DSI_INTERFACE) { - printk(KERN_DEBUG "DSI_INTERFACE is currently not supported\n"); + dev_dbg(av8100dev, + "DSI_INTERFACE is currently not supported\n"); UNLOCK_AV8100_HW; goto av8100_download_firmware_out; } else { @@ -1599,7 +1822,8 @@ int av8100_download_firmware(char *fw_buff, int nbytes, retval = write_multi_byte(i2c, AV8100_FIRMWARE_DOWNLOAD_ENTRY, fw_buff + size, temp); if (retval) { - printk(KERN_DEBUG "Failed to download the av8100 firmware\n"); + dev_dbg(av8100dev, + "Failed to download the av8100 firmware\n"); retval = -EFAULT; UNLOCK_AV8100_HW; goto av8100_download_firmware_out; @@ -1622,59 +1846,63 @@ int av8100_download_firmware(char *fw_buff, int nbytes, for (size = 0; size < nbytes; size++) { CheckSum = CheckSum ^ fw_buff[size]; if (av8100_receivetab[size] != fw_buff[size]) { - printk(KERN_DEBUG ">Fw download fail....i=%d\n", size); - printk(KERN_DEBUG "Transm = %x, Receiv = %x\n", + 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_register_firmware_download_entry_read(&val); + retval = av8100_reg_fw_dl_entry_r(&val); if (retval) { - printk(KERN_DEBUG "Failed to read the value from the av8100 register\n"); + dev_dbg(av8100dev, + "Failed to read the value from the av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_out; } - printk(KERN_DEBUG "CheckSum:%x,val:%x\n", CheckSum, val); + dev_dbg(av8100dev, "CheckSum:%x,val:%x\n", CheckSum, val); if (CheckSum != val) { - printk(KERN_DEBUG ">Fw downloading.... FAIL CheckSum issue\n"); - printk(KERN_DEBUG "Checksum = %d\n", CheckSum); - printk(KERN_DEBUG "Checksum read: %d\n", 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); retval = AV8100_FWDOWNLOAD_FAIL; goto av8100_download_firmware_out; } else { - printk(KERN_DEBUG ">Fw downloading.... success\n"); + dev_dbg(av8100dev, ">Fw downloading.... success\n"); } /* Set to idle mode */ - av8100_register_general_control_write(AV8100_GENERAL_CONTROL_FDL_LOW, + 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) { - printk(KERN_DEBUG "Failed to write the value to the av8100 registers\n"); + dev_dbg(av8100dev, + "Failed to write the value to the av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_out; } /* Wait Internal Micro controler ready */ cnt = 3; - retval = av8100_register_general_status_read(&cecrec, &cectrx, &uc, + retval = av8100_reg_gen_status_r(&cecrec, &cectrx, &uc, &onuvb, &hdcps); while ((retval == 0) && (uc != 0x1) && (cnt-- > 0)) { - printk(KERN_DEBUG "av8100 wait2\n"); + dev_dbg(av8100dev, "av8100 wait2\n"); /* TODO */ for (temp = 0; temp < 0xFFFFF; temp++) ; - retval = av8100_register_general_status_read(&cecrec, &cectrx, + retval = av8100_reg_gen_status_r(&cecrec, &cectrx, &uc, &onuvb, &hdcps); } if (retval) { - printk(KERN_DEBUG "Failed to read the value from the av8100 register\n"); + dev_dbg(av8100dev, + "Failed to read the value from the av8100 register\n"); retval = -EFAULT; goto av8100_download_firmware_out; } @@ -1697,17 +1925,18 @@ int av8100_disable_interrupt(void) i2c = av8100_config->client; - retval = av8100_register_standby_pending_interrupt_write( + 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) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_disable_interrupt_out; } - retval = av8100_register_general_interrupt_mask_write( + 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, @@ -1716,26 +1945,36 @@ int av8100_disable_interrupt(void) AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW, AV8100_GENERAL_INTERRUPT_MASK_TEM_LOW); if (retval) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_disable_interrupt_out; } - retval = av8100_register_standby_interrupt_mask_write( + 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) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_disable_interrupt_out; } #ifdef AV8100_PLUGIN_DETECT_VIA_TIMER_INTERRUPTS del_timer(&av8100_timer); + + if (av8100_globals) { + /* Reset to be able to detect changes */ + av8100_globals->hpds_old = HPDS_INVALID; + av8100_globals->cpds_old = CPDS_INVALID; + av8100_globals->cecrx_old = CECRX_INVALID; + } #endif + av8100_disable_interrupt_out: return retval; } @@ -1752,17 +1991,18 @@ int av8100_enable_interrupt(void) i2c = av8100_config->client; - retval = av8100_register_standby_pending_interrupt_write( + 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) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_enable_interrupt_out; } - retval = av8100_register_general_interrupt_mask_write( + 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, @@ -1771,18 +2011,20 @@ int av8100_enable_interrupt(void) AV8100_GENERAL_INTERRUPT_MASK_UOVBM_LOW, AV8100_GENERAL_INTERRUPT_MASK_TEM_HIGH); if (retval) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_enable_interrupt_out; } - retval = av8100_register_standby_interrupt_mask_write( - AV8100_STANDBY_INTERRUPT_MASK_HPDM_LOW, - AV8100_STANDBY_INTERRUPT_MASK_CPDM_LOW, + 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) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; goto av8100_enable_interrupt_out; } @@ -1814,7 +2056,8 @@ static int register_write_internal(u8 offset, u8 value) /* Write to register */ retval = write_single_byte(i2c, offset, value); if (retval) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; } @@ -1822,7 +2065,7 @@ av8100_register_write_out: return retval; } -int av8100_register_standby_write( +int av8100_reg_stby_w( u8 cpd, u8 stby, u8 mclkrng) { int retval; @@ -1840,24 +2083,39 @@ int av8100_register_standby_write( return retval; } -int av8100_register_hdmi_5_volt_time_write(u8 off_time, u8 on_time) +int av8100_reg_hdmi_5_volt_time_w(u8 denc_off, u8 hdmi_off, u8 on) { int retval; u8 val; LOCK_AV8100_HW; - /* Set register value */ - val = AV8100_HDMI_5_VOLT_TIME_OFF_TIME(off_time) | - AV8100_HDMI_5_VOLT_TIME_ON_TIME(on_time); + /* 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; } -int av8100_register_standby_interrupt_mask_write( +int av8100_reg_stby_int_mask_w( u8 hpdm, u8 cpdm, u8 stbygpiocfg, u8 ipol) { int retval; @@ -1873,11 +2131,15 @@ int av8100_register_standby_interrupt_mask_write( /* 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; } -int av8100_register_standby_pending_interrupt_write( +int av8100_reg_stby_pend_int_w( u8 hpdi, u8 cpdi, u8 oni) { int retval; @@ -1892,11 +2154,12 @@ int av8100_register_standby_pending_interrupt_write( /* Write to register */ retval = register_write_internal(AV8100_STANDBY_PENDING_INTERRUPT, val); + UNLOCK_AV8100_HW; return retval; } -int av8100_register_general_interrupt_mask_write( +int av8100_reg_gen_int_mask_w( u8 eocm, u8 vsim, u8 vsom, u8 cecm, u8 hdcpm, u8 uovbm, u8 tem) { int retval; @@ -1915,11 +2178,12 @@ int av8100_register_general_interrupt_mask_write( /* Write to register */ retval = register_write_internal(AV8100_GENERAL_INTERRUPT_MASK, val); + UNLOCK_AV8100_HW; return retval; } -int av8100_register_general_interrupt_write( +int av8100_reg_gen_int_w( u8 eoci, u8 vsii, u8 vsoi, u8 ceci, u8 hdcpi, u8 uovbi) { int retval; @@ -1941,7 +2205,7 @@ int av8100_register_general_interrupt_write( return retval; } -int av8100_register_gpio_configuration_write( +int av8100_reg_gpio_conf_w( u8 dat3dir, u8 dat3val, u8 dat2dir, u8 dat2val, u8 dat1dir, u8 dat1val, u8 ucdbg) { @@ -1965,7 +2229,7 @@ int av8100_register_gpio_configuration_write( return retval; } -int av8100_register_general_control_write( +int av8100_reg_gen_ctrl_w( u8 fdl, u8 hld, u8 wa, u8 ra) { int retval; @@ -1985,7 +2249,7 @@ int av8100_register_general_control_write( return retval; } -int av8100_register_firmware_download_entry_write( +int av8100_reg_fw_dl_entry_w( u8 mbyte_code_entry) { int retval; @@ -2003,7 +2267,7 @@ int av8100_register_firmware_download_entry_write( return retval; } -int av8100_register_write( +int av8100_reg_w( u8 offset, u8 value) { int retval = 0; @@ -2013,7 +2277,7 @@ int av8100_register_write( if (!av8100_config) { retval = AV8100_FAIL; - goto av8100_register_write_out; + goto av8100_reg_w_out; } i2c = av8100_config->client; @@ -2021,11 +2285,12 @@ int av8100_register_write( /* Write to register */ retval = write_single_byte(i2c, offset, value); if (retval) { - printk(KERN_DEBUG "Failed to write the value to av8100 register\n"); + dev_dbg(av8100dev, + "Failed to write the value to av8100 register\n"); retval = -EFAULT; } -av8100_register_write_out: +av8100_reg_w_out: UNLOCK_AV8100_HW; return retval; } @@ -2045,7 +2310,8 @@ int register_read_internal(u8 offset, u8 *value) /* Read from register */ retval = read_single_byte(i2c, offset, value); if (retval) { - printk(KERN_DEBUG "Failed to read the value from av8100 register\n"); + dev_dbg(av8100dev, + "Failed to read the value from av8100 register\n"); retval = -EFAULT; goto av8100_register_read_out; } @@ -2054,7 +2320,7 @@ av8100_register_read_out: return retval; } -int av8100_register_standby_read( +int av8100_reg_stby_r( u8 *cpd, u8 *stby, u8 *hpds, u8 *cpds, u8 *mclkrng) { int retval; @@ -2066,18 +2332,23 @@ int av8100_register_standby_read( retval = register_read_internal(AV8100_STANDBY, &val); /* Set return params */ - *cpd = AV8100_STANDBY_CPD_GET(val); - *stby = AV8100_STANDBY_STBY_GET(val); - *hpds = AV8100_STANDBY_HPDS_GET(val); - *cpds = AV8100_STANDBY_CPDS_GET(val); - *mclkrng = AV8100_STANDBY_MCLKRNG_GET(val); + 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; } -int av8100_register_hdmi_5_volt_time_read( - u8 *off_time, u8 *on_time) +int av8100_reg_hdmi_5_volt_time_r( + u8 *denc_off_time, u8 *hdmi_off_time, u8 *on_time) { int retval; u8 val; @@ -2088,14 +2359,29 @@ int av8100_register_hdmi_5_volt_time_read( retval = register_read_internal(AV8100_HDMI_5_VOLT_TIME, &val); /* Set return params */ - *off_time = AV8100_HDMI_5_VOLT_TIME_OFF_TIME_GET(val); - *on_time = AV8100_HDMI_5_VOLT_TIME_ON_TIME_GET(val); + 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; } -int av8100_register_standby_interrupt_mask_read( +int av8100_reg_stby_int_mask_r( u8 *hpdm, u8 *cpdm, u8 *stbygpiocfg, u8 *ipol) { int retval; @@ -2107,16 +2393,21 @@ int av8100_register_standby_interrupt_mask_read( retval = register_read_internal(AV8100_STANDBY_INTERRUPT_MASK, &val); /* Set return params */ - *hpdm = AV8100_STANDBY_INTERRUPT_MASK_HPDM_GET(val); - *cpdm = AV8100_STANDBY_INTERRUPT_MASK_CPDM_GET(val); - *stbygpiocfg = AV8100_STANDBY_INTERRUPT_MASK_STBYGPIOCFG_GET(val); - *ipol = AV8100_STANDBY_INTERRUPT_MASK_IPOL_GET(val); + 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; } -int av8100_register_standby_pending_interrupt_read( +int av8100_reg_stby_pend_int_r( u8 *hpdi, u8 *cpdi, u8 *oni, u8 *sid) { int retval; @@ -2125,19 +2416,24 @@ int av8100_register_standby_pending_interrupt_read( LOCK_AV8100_HW; /* Read from register */ - retval = register_read_internal(AV8100_STANDBY_PENDING_INTERRUPT, &val); + retval = register_read_internal(AV8100_STANDBY_PENDING_INTERRUPT, + &val); /* Set return params */ - *hpdi = AV8100_STANDBY_PENDING_INTERRUPT_HPDI_GET(val); - *cpdi = AV8100_STANDBY_PENDING_INTERRUPT_CPDI_GET(val); - *oni = AV8100_STANDBY_PENDING_INTERRUPT_ONI_GET(val); - *sid = AV8100_STANDBY_PENDING_INTERRUPT_SID_GET(val); + 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; } -int av8100_register_general_interrupt_mask_read( +int av8100_reg_gen_int_mask_r( u8 *eocm, u8 *vsim, u8 *vsom, @@ -2155,19 +2451,26 @@ int av8100_register_general_interrupt_mask_read( retval = register_read_internal(AV8100_GENERAL_INTERRUPT_MASK, &val); /* Set return params */ - *eocm = AV8100_GENERAL_INTERRUPT_MASK_EOCM_GET(val); - *vsim = AV8100_GENERAL_INTERRUPT_MASK_VSIM_GET(val); - *vsom = AV8100_GENERAL_INTERRUPT_MASK_VSOM_GET(val); - *cecm = AV8100_GENERAL_INTERRUPT_MASK_CECM_GET(val); - *hdcpm = AV8100_GENERAL_INTERRUPT_MASK_HDCPM_GET(val); - *uovbm = AV8100_GENERAL_INTERRUPT_MASK_UOVBM_GET(val); - *tem = AV8100_GENERAL_INTERRUPT_MASK_TEM_GET(val); + 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; } -int av8100_register_general_interrupt_read( +int av8100_reg_gen_int_r( u8 *eoci, u8 *vsii, u8 *vsoi, @@ -2185,19 +2488,26 @@ int av8100_register_general_interrupt_read( retval = register_read_internal(AV8100_GENERAL_INTERRUPT, &val); /* Set return params */ - *eoci = AV8100_GENERAL_INTERRUPT_EOCI_GET(val); - *vsii = AV8100_GENERAL_INTERRUPT_VSII_GET(val); - *vsoi = AV8100_GENERAL_INTERRUPT_VSOI_GET(val); - *ceci = AV8100_GENERAL_INTERRUPT_CECI_GET(val); - *hdcpi = AV8100_GENERAL_INTERRUPT_HDCPI_GET(val); - *uovbi = AV8100_GENERAL_INTERRUPT_UOVBI_GET(val); - *tei = AV8100_GENERAL_INTERRUPT_TEI_GET(val); + 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; } -int av8100_register_general_status_read( +int av8100_reg_gen_status_r( u8 *cecrec, u8 *cectrx, u8 *uc, @@ -2213,17 +2523,22 @@ int av8100_register_general_status_read( retval = register_read_internal(AV8100_GENERAL_STATUS, &val); /* Set return params */ - *cecrec = AV8100_GENERAL_STATUS_CECREC_GET(val); - *cectrx = AV8100_GENERAL_STATUS_CECTRX_GET(val); - *uc = AV8100_GENERAL_STATUS_UC_GET(val); - *onuvb = AV8100_GENERAL_STATUS_ONUVB_GET(val); - *hdcps = AV8100_GENERAL_STATUS_HDCPS_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; } -int av8100_register_gpio_configuration_read( +int av8100_reg_gpio_conf_r( u8 *dat3dir, u8 *dat3val, u8 *dat2dir, @@ -2241,19 +2556,26 @@ int av8100_register_gpio_configuration_read( retval = register_read_internal(AV8100_GPIO_CONFIGURATION, &val); /* Set return params */ - *dat3dir = AV8100_GPIO_CONFIGURATION_DAT3DIR_GET(val); - *dat3val = AV8100_GPIO_CONFIGURATION_DAT3VAL_GET(val); - *dat2dir = AV8100_GPIO_CONFIGURATION_DAT2DIR_GET(val); - *dat2val = AV8100_GPIO_CONFIGURATION_DAT2VAL_GET(val); - *dat1dir = AV8100_GPIO_CONFIGURATION_DAT1DIR_GET(val); - *dat1val = AV8100_GPIO_CONFIGURATION_DAT1VAL_GET(val); - *ucdbg = AV8100_GPIO_CONFIGURATION_UCDBG_GET(val); + 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; } -int av8100_register_general_control_read( +int av8100_reg_gen_ctrl_r( u8 *fdl, u8 *hld, u8 *wa, @@ -2267,16 +2589,20 @@ int av8100_register_general_control_read( /* Read from register */ retval = register_read_internal(AV8100_GENERAL_CONTROL, &val); /* Set return params */ - *fdl = AV8100_GENERAL_CONTROL_FDL_GET(val); - *hld = AV8100_GENERAL_CONTROL_HLD_GET(val); - *wa = AV8100_GENERAL_CONTROL_WA_GET(val); - *ra = AV8100_GENERAL_CONTROL_RA_GET(val); + 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; } -int av8100_register_firmware_download_entry_read( +int av8100_reg_fw_dl_entry_r( u8 *mbyte_code_entry) { int retval; @@ -2288,14 +2614,15 @@ int av8100_register_firmware_download_entry_read( retval = register_read_internal(AV8100_FIRMWARE_DOWNLOAD_ENTRY, &val); /* Set return params */ - *mbyte_code_entry = + if (mbyte_code_entry) + *mbyte_code_entry = AV8100_FIRMWARE_DOWNLOAD_ENTRY_MBYTE_CODE_ENTRY_GET(val); UNLOCK_AV8100_HW; return retval; } -int av8100_register_read( +int av8100_reg_r( u8 offset, u8 *value) { @@ -2314,7 +2641,8 @@ int av8100_register_read( /* Read from register */ retval = read_single_byte(i2c, offset, value); if (retval) { - printk(KERN_DEBUG "Failed to read the value from av8100 register\n"); + dev_dbg(av8100dev, + "Failed to read the value from av8100 register\n"); retval = -EFAULT; goto av8100_register_read_out; } @@ -2324,7 +2652,7 @@ av8100_register_read_out: return retval; } -int av8100_configuration_get(enum av8100_command_type command_type, +int av8100_conf_get(enum av8100_command_type command_type, union av8100_configuration *config) { if (!av8100_config || !config) @@ -2431,7 +2759,7 @@ int av8100_configuration_get(enum av8100_command_type command_type, return 0; } -int av8100_configuration_prepare(enum av8100_command_type command_type, +int av8100_conf_prep(enum av8100_command_type command_type, union av8100_configuration *config) { if (!av8100_config || !config) @@ -2542,7 +2870,7 @@ int av8100_configuration_prepare(enum av8100_command_type command_type, return 0; } -int av8100_configuration_write(enum av8100_command_type command_type, +int av8100_conf_w(enum av8100_command_type command_type, u8 *return_buffer_length, u8 *return_buffer, enum interface_type if_type) { @@ -2562,7 +2890,7 @@ int av8100_configuration_write(enum av8100_command_type command_type, memset(&cmd_buffer, 0x00, AV8100_COMMAND_MAX_LENGTH); #ifdef AV8100_DEBUG_EXTRA -#define PRNK_MODE(_m) printk(KERN_DEBUG "cmd: " #_m "\n"); +#define PRNK_MODE(_m) dev_dbg(av8100dev, "cmd: " #_m "\n"); #else #define PRNK_MODE(_m) #endif @@ -2651,7 +2979,7 @@ int av8100_configuration_write(enum av8100_command_type command_type, break; default: - printk(KERN_INFO "Invalid command type\n"); + dev_dbg(av8100dev, "Invalid command type\n"); retval = AV8100_INVALID_COMMAND; break; } @@ -2662,14 +2990,14 @@ int av8100_configuration_write(enum av8100_command_type command_type, #ifdef AV8100_DEBUG_EXTRA { int cnt = 0; - printk(KERN_DEBUG "av8100_configuration_write cmd_type:%02x length:%02x ", + dev_dbg(av8100dev, "av8100_conf_w cmd_type:%02x length:%02x ", command_type, cmd_length); - printk(KERN_DEBUG "buffer: "); + dev_dbg(av8100dev, "buffer: "); while (cnt < cmd_length) { - printk(KERN_DEBUG "%02x ", cmd_buffer[cnt]); + dev_dbg(av8100dev, "%02x ", cmd_buffer[cnt]); cnt++; } - printk(KERN_DEBUG "\n"); + dev_dbg(av8100dev, "\n"); } #endif @@ -2698,7 +3026,7 @@ int av8100_configuration_write(enum av8100_command_type command_type, /* TODO */ } else { retval = AV8100_INVALID_INTERFACE; - printk(KERN_INFO "Invalid command type\n"); + dev_dbg(av8100dev, "Invalid command type\n"); } if (command_type == AV8100_COMMAND_HDMI) { @@ -2711,7 +3039,7 @@ int av8100_configuration_write(enum av8100_command_type command_type, return retval; } -int av8100_configuration_write_raw(enum av8100_command_type command_type, +int av8100_conf_w_raw(enum av8100_command_type command_type, u8 buffer_length, u8 *buffer, u8 *return_buffer_length, @@ -2727,7 +3055,7 @@ int av8100_configuration_write_raw(enum av8100_command_type command_type, if (!av8100_config) { retval = AV8100_FAIL; - goto av8100_configuration_write_raw_out; + goto av8100_conf_w_raw_out; } i2c = av8100_config->client; @@ -2736,13 +3064,13 @@ int av8100_configuration_write_raw(enum av8100_command_type command_type, retval = write_multi_byte(i2c, AV8100_COMMAND_OFFSET + 1, buffer, buffer_length); if (retval) - goto av8100_configuration_write_raw_out; + goto av8100_conf_w_raw_out; /* Write the command */ retval = write_single_byte(i2c, AV8100_COMMAND_OFFSET, command_type); if (retval) - goto av8100_configuration_write_raw_out; + goto av8100_conf_w_raw_out; /* TODO */ mdelay(100); @@ -2750,7 +3078,7 @@ int av8100_configuration_write_raw(enum av8100_command_type command_type, retval = get_command_return_data(i2c, command_type, buffer, return_buffer_length, return_buffer); -av8100_configuration_write_raw_out: +av8100_conf_w_raw_out: UNLOCK_AV8100_HW; return retval; } @@ -2787,29 +3115,49 @@ enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres, av8100_all_cea[index].htotale / av8100_all_cea[index].vtotale; - printk(KERN_DEBUG "freq1:%ld freq2:%ld\n", freq1, freq2); + 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)) { - break; + 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; } +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; +} + +u8 av8100_ver_get(void) +{ + u8 ret; + + LOCK_AV8100_HW; + ret = chip_version; + UNLOCK_AV8100_HW; + + return ret; +} + static int av8100_open(struct inode *inode, struct file *filp) { - printk(KERN_DEBUG "av8100_open is called\n"); + dev_dbg(av8100dev, "av8100_open is called\n"); return 0; } static int av8100_release(struct inode *inode, struct file *filp) { - printk(KERN_DEBUG "av8100_release is called\n"); + dev_dbg(av8100dev, "av8100_release is called\n"); return 0; } @@ -2825,7 +3173,9 @@ static int __devinit av8100_probe(struct i2c_client *i2cClient, int ret = 0; struct av8100_platform_data *pdata = i2cClient->dev.platform_data; - printk(KERN_DEBUG "%s\n", __func__); + av8100dev = &i2cClient->dev; + + dev_dbg(av8100dev, "%s\n", __func__); g_av8100_status.av8100_state = AV8100_OPMODE_SHUTDOWN; g_av8100_status.av8100_plugin_status = AV8100_PLUGIN_NONE; @@ -2833,7 +3183,13 @@ static int __devinit av8100_probe(struct i2c_client *i2cClient, ret = av8100_config_init(); if (ret) { - pr_info("av8100_config_init failed\n"); + 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; } @@ -2841,7 +3197,7 @@ static int __devinit av8100_probe(struct i2c_client *i2cClient, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_READ_WORD_DATA)) { ret = -ENODEV; - pr_info("av8100 i2c_check_functionality failed\n"); + dev_info(av8100dev, "av8100 i2c_check_functionality failed\n"); goto err; } @@ -2851,17 +3207,21 @@ static int __devinit av8100_probe(struct i2c_client *i2cClient, av8100_config->id = (struct i2c_device_id *) id; i2c_set_clientdata(i2cClient, av8100_config); - kthread_run(av8100_thread, NULL, "hdmi_thread"); + kthread_run(av8100_thread, NULL, "av8100_thread"); ret = request_irq(pdata->irq, av8100_intr_handler, IRQF_TRIGGER_RISING, "av8100", av8100_config); if (ret) { - printk(KERN_ERR "av8100_hw request_irq %d failed %d\n", + dev_err(av8100dev, "av8100_hw request_irq %d failed %d\n", pdata->irq, ret); gpio_free(pdata->irq); goto err; } + /* Obtain the chip version */ + av8100_powerup1(); + av8100_powerdown(); + return ret; err: return ret; @@ -2869,9 +3229,10 @@ err: static int __devexit av8100_remove(struct i2c_client *i2cClient) { - printk(KERN_DEBUG "%s\n", __func__); + dev_dbg(av8100dev, "%s\n", __func__); av8100_config_exit(); + av8100_globals_exit(); return 0; } @@ -2880,17 +3241,17 @@ int av8100_init(void) { int ret; - printk(KERN_DEBUG "%s\n", __func__); + pr_debug("%s\n", __func__); ret = i2c_add_driver(&av8100_driver); if (ret) { - printk(KERN_DEBUG "av8100 i2c_add_driver failed\n"); + pr_err("av8100 i2c_add_driver failed\n"); goto av8100_init_err; } ret = misc_register(&av8100_miscdev); if (ret) { - printk(KERN_DEBUG "av8100 misc_register failed\n"); + pr_err("av8100 misc_register failed\n"); goto av8100_init_err; } @@ -2905,7 +3266,7 @@ module_init(av8100_init); void av8100_exit(void) { - printk(KERN_DEBUG "%s\n", __func__); + pr_debug("%s\n", __func__); hdmi_exit(); diff --git a/drivers/video/av8100/av8100_fw.h b/drivers/video/av8100/av8100_fw.h index 5c668476077..d2d666e63d9 100755 --- a/drivers/video/av8100/av8100_fw.h +++ b/drivers/video/av8100/av8100_fw.h @@ -1,18 +1,15 @@ /* - * Copyright (C) ST-Ericsson SA 2010 + * Copyright (C) ST-Ericsson AB 2010 * - * License terms: + * Author: Per Persson <per.xb.persson@stericsson.com> + * for ST-Ericsson. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. + * License terms: GNU General Public License (GPL), version 2. */ -/* AV8100 Firmware version : V4.0 HDCP 1.0 + 3D supported */ -#define AV8100_FW_SIZE 16384 -char av8100_receivetab[AV8100_FW_SIZE]; -char av8100_transmittab[AV8100_FW_SIZE]; -char av8100_fw_buff[AV8100_FW_SIZE] = { +/* AV8100v1 Firmware version : V4.0 HDCP 1.0 + 3D supported */ +#define AV8100_FW_SIZE_V1 16384 +char av8100_fw_buff_v1[AV8100_FW_SIZE_V1] = { 0x80, 0xfe, 0xcb, 0xfe, 0x8b, 0xf4, 0x42, 0xf6, 0x42, 0xf6, 0x98, 0xf7, 0x41, 0xf5, 0x9d, 0xf7, 0xe5, 0xf8, 0xa7, 0xfa, 0xbc, 0xfa, 0xcd, 0xfa, diff --git a/drivers/video/av8100/av8100_regs.h b/drivers/video/av8100/av8100_regs.h index 3660051d9ea..704a99a3a4e 100755 --- a/drivers/video/av8100/av8100_regs.h +++ b/drivers/video/av8100/av8100_regs.h @@ -46,6 +46,18 @@ 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) \ diff --git a/drivers/video/av8100/av8100v2_fw.h b/drivers/video/av8100/av8100v2_fw.h new file mode 100644 index 00000000000..8467dc86b58 --- /dev/null +++ b/drivers/video/av8100/av8100v2_fw.h @@ -0,0 +1,1166 @@ +/* + * 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. + */ + +/* AV8100v2 Firmware version : AV8100V2.1 V2.0cut2 */ +#define AV8100_FW_SIZE_V2 18432 +char av8100_fw_buff_v2[AV8100_FW_SIZE_V2] = { +0x80,0xfe,0xcb,0xfe,0x88,0xf3,0x3f,0xf5,0x3f,0xf5,0xd9,0xf6,0x3e,0xf4,0xde,0xf6, +0x26,0xf8,0xe8,0xf9,0xfd,0xf9,0x0e,0xfa,0x20,0xfa,0x33,0xfa,0x38,0xfa,0x3d,0xfa, +0x42,0xfa,0x47,0xfa,0x5c,0xfa,0x96,0xfa,0x2d,0xfb,0x82,0xf3,0x82,0xf3,0x83,0xf3, +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,0x52,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0xfb,0xfb,0xcc,0xcb,0xfc,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,0xfb,0xfb,0xcc, +0x83,0xfc,0xcd,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,0x41,0xfc,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,0xd0,0x01,0x5a,0x72,0xcf,0x01,0x5a,0x72,0x04,0x26,0xd0,0x01,0xc6, +0x0f,0x27,0xcf,0x01,0xca,0xd0,0x01,0xc6,0x98,0x01,0x5f,0x72,0xcf,0x01,0x5f,0x72, +0xd0,0x01,0x18,0x35,0x08,0x25,0x00,0xa2,0xcf,0x01,0xc6,0x19,0xa0,0xd0,0x01,0xc6, +0x18,0x20,0x98,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, +0x9b,0xc6,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,0xdd,0x01,0xc7,0x4a,0x05,0x20,0x1a,0x72,0x06,0x20,0x18,0x72,0x11,0x20,0xc7, +0x02,0xa6,0x80,0xdd,0x01,0xc7,0x05,0x20,0x1a,0x72,0x06,0x20,0x19,0x72,0x11,0x20, +0xc7,0x01,0xa6,0x80,0x04,0x88,0x00,0x35,0x05,0x88,0x30,0x35,0x06,0x88,0x00,0x35, +0x07,0x88,0x00,0x35,0x10,0x20,0x80,0x35,0x81,0xf9,0xfb,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,0xf9,0xfb,0xcd,0xa0,0xae,0xa4,0x00,0x84,0x35,0xcb,0xfc,0xcd,0x33,0xad,0x5b, +0xa0,0x3f,0xa1,0x3f,0xa2,0x1f,0x18,0xfc,0xcd,0xe8,0x01,0xce,0xe9,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,0xe8,0x01, +0xcf,0xe9,0x01,0xc7,0xf4,0xc6,0xcd,0xbc,0x00,0xce,0xbd,0x00,0xc6,0xea,0x01,0x3b, +0xeb,0x01,0x3b,0x0f,0x20,0xd8,0xc6,0xcd,0xbc,0x00,0xce,0xbd,0x00,0xc6,0xea,0x01, +0x3b,0xeb,0x01,0x3b,0x11,0x24,0x05,0xe2,0x72,0xea,0x01,0xc6,0x06,0xe0,0x72,0xeb, +0x01,0xc6,0x1f,0x24,0x05,0xe2,0x72,0xbc,0x00,0xc6,0x06,0xe0,0x72,0xbd,0x00,0xc6, +0x1c,0x25,0xea,0x01,0xc2,0x05,0x7b,0xeb,0x01,0xc0,0x06,0x7b,0x0c,0x24,0xbc,0x00, +0xc2,0x05,0x7b,0xbd,0x00,0xc0,0x06,0x7b,0x5c,0x20,0xe8,0x01,0xcf,0xbc,0x00,0xce, +0xe9,0x01,0xbd,0x00,0x55,0x0d,0x26,0x67,0x01,0xc6,0x0d,0x20,0xea,0x01,0xce,0xe9, +0x01,0xc7,0xeb,0x01,0xc6,0x0b,0x27,0x4a,0x66,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,0x66,0x01,0xc6,0xea,0x01,0x5f,0x72,0xeb,0x01, +0xc7,0x06,0xa6,0xde,0xf9,0xcd,0xa2,0xb7,0x18,0xaa,0xa2,0xb6,0x11,0xfd,0xcd,0xd6, +0xf9,0xcd,0x5b,0x12,0x20,0x0a,0xa6,0xde,0xf9,0xcd,0xa2,0x18,0x11,0xfd,0xcd,0xd6, +0xf9,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,0x67,0x01,0xc6,0x06,0x6b,0xa7,0x83,0xc6,0x05,0x6b,0xa6,0x83,0xc6, +0xe9,0x01,0x5f,0x72,0xe8,0x01,0x5f,0x72,0xeb,0x01,0x5f,0x72,0xea,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,0xde,0x01,0x5f,0x72,0xc6,0xcc,0xcd,0x20,0xad,0x05,0x26,0x4a, +0xde,0x01,0xc6,0x0b,0x26,0x03,0xa1,0x66,0x01,0xc6,0xe4,0x01,0x5c,0x72,0x04,0x27, +0x0f,0xa1,0xe4,0x01,0xc6,0x0b,0x20,0xdd,0x01,0x01,0x35,0x11,0x26,0xe4,0x01,0x5a, +0x72,0x17,0x27,0xe4,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, +0x6b,0xe2,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,0x44,0x01,0xce,0x45,0x01,0xc6,0x08,0x20,0x44,0x01, +0xce,0x45,0x01,0xc6,0x08,0x26,0x4a,0x3d,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,0xe6,0xf7,0xcc,0x84,0x84,0x84,0x84,0xaf,0x00,0x35,0x35,0xb0, +0x00,0x86,0x35,0xb1,0x00,0x37,0x35,0xb2,0x00,0xbd,0x35,0xe4,0x01,0x0f,0x35,0xe6, +0x01,0x01,0x35,0x15,0xf8,0xcd,0x10,0xc7,0xcd,0xb3,0x00,0x3b,0xb4,0x00,0x3b,0xb5, +0x00,0x3b,0xb6,0x00,0x3b,0x31,0x26,0xe6,0x01,0xc6,0x94,0xcc,0xcd,0x03,0x27,0xe4, +0x01,0xc6,0xfc,0xf7,0xcc,0x03,0x26,0x02,0xa1,0xdc,0x01,0xc6,0xe6,0xf7,0xcc,0x03, +0x27,0x02,0xa1,0x66,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,0x11,0xfd,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,0x84,0x84,0x84,0x51,0xce,0xcd,0x41,0x00, +0xa9,0x41,0xca,0xab,0x5f,0x52,0x21,0xae,0xc8,0x00,0xc6,0x02,0x4b,0x10,0x4b,0x00, +0x4b,0xc8,0x00,0x5c,0x72,0x04,0x20,0xc8,0x00,0x5f,0x72,0x06,0x26,0xa8,0xb1,0xa8, +0xbf,0x90,0x0d,0x26,0xa7,0xb3,0xa7,0x3f,0xc8,0x00,0xce,0x90,0x4a,0x5a,0x01,0x26, +0x4d,0x5f,0x3a,0x25,0x02,0xa1,0xc9,0x00,0xc6,0x54,0xcc,0xcd,0xdd,0x01,0x5f,0x72, +0x07,0x26,0x4a,0xdd,0x01,0xc6,0x06,0x27,0x4a,0x66,0x01,0xc6,0x2d,0xda,0xcd,0xdf, +0x01,0xc7,0x06,0x26,0x4a,0xdf,0x01,0xc6,0xf9,0xfb,0xcd,0xa4,0xbf,0x84,0xae,0xa3, +0x1a,0xce,0xf6,0xcd,0x5b,0x0a,0x20,0x04,0xae,0xa4,0x00,0x44,0x35,0xa0,0x3f,0xce, +0xf6,0xcd,0x5b,0x02,0x6b,0x08,0x84,0xc6,0x03,0x6b,0x09,0x84,0xc6,0x04,0x6b,0x0a, +0x84,0xc6,0x05,0x6b,0x0b,0x84,0xc6,0xf9,0xfb,0xcd,0xa4,0xbf,0x84,0xae,0xa3,0x1b, +0xce,0xf6,0xcd,0x5b,0x2f,0x27,0x68,0x01,0xc6,0x34,0x27,0xbf,0x00,0xc6,0x02,0x6b, +0x84,0x84,0xc6,0x03,0x6b,0x85,0x84,0xc6,0x04,0x6b,0x86,0x84,0xc6,0x05,0x6b,0x87, +0x84,0xc6,0x7c,0x01,0x5c,0x72,0x04,0x27,0x4c,0x7c,0x01,0xc6,0x0a,0x20,0x7c,0x01, +0x5f,0x72,0x06,0x27,0xe4,0x01,0xc6,0xe5,0x01,0x5c,0x72,0x04,0x24,0xff,0xa1,0xe5, +0x01,0xc6,0xde,0x01,0x01,0x35,0xf9,0xfb,0xcd,0xa0,0xae,0xa4,0x00,0x84,0x35,0xa0, +0x1f,0xce,0xf6,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,0x10,0xc7,0xcd, +0xb3,0x00,0x3b,0xb4,0x00,0x3b,0xb5,0x00,0x3b,0xb6,0x00,0x3b,0xe6,0x01,0x5f,0x72, +0x41,0x25,0x04,0xa1,0xe5,0x01,0xc6,0x65,0x27,0x4a,0x66,0x01,0xc6,0xf9,0xfb,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,0xf9,0xfb,0xcd,0x0c,0xae,0x27,0xad,0xf0,0xa4,0x01,0x7b,0x7d,0x01,0x5f,0x72, +0x05,0x20,0x16,0x72,0x06,0x20,0xc7,0x05,0xaa,0x06,0x20,0xc6,0x1b,0x27,0x04,0xa5, +0x01,0x7b,0xf9,0xfb,0xcd,0x0c,0xae,0x48,0xad,0xf0,0xa4,0x05,0x20,0x16,0x72,0x06, +0x20,0x14,0x72,0x11,0x20,0x7d,0x01,0x5a,0x72,0x2c,0xf4,0xcd,0x02,0xa6,0x05,0x26, +0x4a,0x05,0x20,0x4f,0x03,0x25,0x02,0xa1,0x7d,0x01,0xc6,0xf9,0xfb,0xcd,0x10,0xae, +0x71,0xad,0x7e,0x01,0xd6,0x22,0x27,0x7d,0x01,0xce,0x59,0x27,0x0f,0xa5,0x01,0x7b, +0xf9,0xfb,0xcd,0x0c,0xae,0x31,0xf5,0xcd,0x0f,0xa4,0x05,0x20,0x16,0x72,0x06,0x20, +0x12,0x72,0x6a,0x01,0x01,0x35,0x18,0x27,0x20,0xa5,0x01,0x7b,0x98,0xad,0x4f,0x05, +0x27,0x80,0xa5,0x01,0x7b,0x6c,0x01,0xd7,0x17,0x8c,0xc6,0x6b,0x01,0x5c,0x72,0x6b, +0x01,0xce,0x0f,0x27,0x80,0xa5,0x07,0x20,0x6b,0x01,0xcf,0x06,0x20,0x13,0x72,0x09, +0x27,0x10,0xa5,0x20,0x26,0x6a,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,0xf9,0xfb,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,0xde,0x01,0x01,0x35,0x01,0x6b,0x7f,0xa4,0x01,0x7b,0x0a,0x20,0x01,0x6b,0x80, +0xaa,0x01,0x7b,0x12,0x27,0x02,0xa1,0xdc,0x01,0xc6,0x0f,0x26,0x03,0xa1,0x04,0x27, +0x02,0xa1,0x66,0x01,0xc6,0x1a,0x27,0x67,0x01,0xc6,0x05,0x26,0x68,0x01,0xc6,0x01, +0x6b,0xa0,0x84,0xc6,0x02,0x6b,0xa1,0x84,0xc6,0x03,0x6b,0xa2,0x84,0xc6,0x04,0x6b, +0xa3,0x84,0xc6,0xe5,0x01,0x5f,0x72,0xdc,0x01,0xc7,0x03,0xa4,0x83,0x84,0xc6,0xa5, +0xc7,0xcd,0x03,0x26,0x4a,0xdb,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,0x18,0xf2, +0xcc,0x28,0x4b,0x85,0xcf,0xcd,0x1c,0xf2,0xcc,0xc1,0xa6,0x00,0x4b,0x08,0x4b,0xf0, +0xcf,0xcd,0x1c,0xf2,0xcc,0xe0,0xa6,0x01,0x4b,0xe0,0x4b,0x9d,0xf2,0xcc,0x03,0x26, +0x90,0x01,0x5a,0x72,0x81,0x84,0x84,0x90,0x01,0x02,0x35,0xbd,0xf1,0xcd,0xe0,0xa6, +0x01,0x4b,0xe0,0x4b,0x10,0x27,0x4d,0xdc,0xd3,0xcd,0x28,0x27,0x92,0x01,0xc5,0x94, +0x01,0xc6,0x1c,0xf2,0xcc,0xc1,0xa6,0x00,0x4b,0x28,0x4b,0x1a,0xf2,0xcc,0x01,0x4b, +0x90,0x4b,0x85,0xcf,0xcd,0x0a,0x27,0x92,0x01,0xc5,0x94,0x01,0xc6,0xc5,0x20,0x28, +0x4b,0x1c,0xf2,0xcc,0xe0,0xa6,0x01,0x4b,0x90,0x4b,0x4b,0xd0,0xcd,0x0c,0x27,0x92, +0x01,0xc5,0x94,0x01,0xc6,0xdd,0x20,0x08,0x4b,0x1c,0xf2,0xcc,0x82,0xa6,0x01,0x4b, +0x90,0x4b,0x91,0x01,0x5a,0x72,0xce,0x27,0x91,0x01,0xc6,0x12,0x26,0x4d,0x50,0xd3, +0xcd,0x1c,0xf2,0xcc,0xc0,0xa6,0x00,0x4b,0x50,0x4b,0xb7,0x27,0x4d,0xdc,0xd3,0xcd, +0xe8,0x26,0x4d,0x03,0xd1,0xcd,0x03,0xa6,0x26,0x20,0x91,0x01,0x0a,0x35,0xcb,0x27, +0x4d,0xdc,0xd3,0xcd,0xd3,0x20,0x60,0x4b,0x04,0x27,0x4d,0x03,0xd1,0xcd,0x83,0xa6, +0x18,0x27,0x4d,0x32,0xd3,0xcd,0x1c,0xf2,0xcc,0x81,0xa6,0x00,0x4b,0x60,0x4b,0xec, +0x26,0x4d,0x03,0xd1,0xcd,0x02,0xa6,0xb2,0xd2,0xcd,0x1c,0xf2,0xcc,0xa0,0xa6,0x00, +0x4b,0x08,0x4b,0x09,0x27,0x4d,0xec,0xd1,0xcd,0x06,0x26,0x4d,0x03,0xd1,0xcd,0x4c, +0x8c,0x20,0x80,0xa6,0x88,0x88,0x4f,0x93,0x20,0x40,0xa6,0x00,0x4b,0xa0,0x4b,0x08, +0x26,0x4d,0x5b,0xd1,0xcd,0x7a,0xf3,0xcc,0x3e,0xf3,0xcc,0x03,0x26,0x1f,0xa0,0x23, +0xf3,0xcc,0x03,0x26,0x4a,0x0b,0xf3,0xcc,0x03,0x26,0x20,0xa0,0xe0,0x27,0x1e,0xa0, +0xef,0xf2,0xcc,0x03,0x26,0x4a,0x60,0x27,0x4a,0x39,0x27,0x20,0xa0,0xc3,0x27,0x20, +0xa0,0x2c,0x27,0x20,0xa0,0x30,0x27,0x20,0xa0,0x7a,0xf3,0xcc,0x03,0x26,0x9e,0x01, +0xc6,0xdd,0x20,0x60,0xa6,0x00,0x4b,0x50,0x4b,0x85,0xcf,0xcd,0x03,0x25,0x61,0xa1, +0x9e,0x01,0xc6,0x12,0x27,0x11,0xa1,0x97,0x01,0xc6,0x07,0x27,0x95,0x01,0xc6,0x81, +0x84,0x84,0x9f,0xad,0x20,0xa6,0x00,0x4b,0x50,0x4b,0x0b,0x26,0x68,0x01,0xc6,0x05, +0x27,0x9e,0x01,0xc6,0x10,0x20,0x4f,0x00,0x4b,0xa0,0x4b,0x85,0xcf,0xcd,0x03,0x27, +0x9e,0x01,0xc6,0x0f,0x26,0x98,0x01,0xc6,0x81,0x84,0x84,0x84,0x92,0xc6,0xcd,0x06, +0xee,0x72,0x07,0x7b,0x9e,0x01,0xc7,0x03,0x7b,0x05,0x20,0x18,0x72,0x04,0x27,0x01, +0xe1,0x72,0xf0,0xa4,0x9e,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,0x12,0x00,0xc0,0x84,0x55,0x65,0x18,0xcd,0x11,0xb7,0x62,0xf0, +0xcd,0x65,0x18,0xcc,0x11,0xb7,0xfd,0xee,0xcd,0xd6,0x20,0xfd,0xee,0xcd,0x05,0x26, +0x04,0xa1,0x12,0xb6,0x06,0x27,0x02,0xa1,0x12,0xb6,0x11,0x26,0x02,0xa1,0x11,0xb6, +0xd2,0x20,0xe8,0xee,0xcd,0x1f,0x20,0x31,0xee,0xcd,0x24,0x20,0xb2,0xed,0xcd,0xe1, +0x20,0x11,0xb7,0xb2,0xed,0xcd,0x07,0x26,0x02,0xa1,0x11,0xb6,0x36,0x20,0x76,0xeb, +0xcd,0x3b,0x20,0xd8,0xea,0xcd,0x40,0x20,0x44,0xe8,0xcd,0x5a,0x18,0xcc,0xaf,0xe7, +0xcd,0x4b,0x20,0xd0,0xe7,0xcd,0x50,0x20,0xd7,0xe6,0xcd,0x55,0x20,0x81,0xe6,0xcd, +0x5a,0x20,0x41,0xe6,0xcd,0x5f,0x20,0xfe,0xe5,0xcd,0x64,0x20,0xf9,0xe4,0xcd,0x81, +0x88,0x00,0xf1,0xd6,0x88,0x01,0xf1,0xd6,0x58,0x97,0xac,0xf1,0xcc,0x03,0x25,0x0f, +0xa1,0x4a,0x9f,0xf1,0x80,0xf1,0x7b,0xf1,0x76,0xf1,0x64,0xf1,0x5f,0xf1,0x5a,0xf1, +0x55,0xf1,0x4f,0xf1,0x4a,0xf1,0x45,0xf1,0x40,0xf1,0x3b,0xf1,0x36,0xf1,0x31,0xf1, +0x81,0x11,0xfd,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,0xac,0xc6,0xcd,0x0a, +0xa6,0x9a,0x78,0x84,0xc7,0x02,0x7b,0x79,0x84,0xc7,0x03,0x7b,0x7a,0x84,0xc7,0x04, +0x7b,0x7b,0x84,0xc7,0x05,0x7b,0xf9,0xfb,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,0xbf,0xcd,0xcd,0x01,0xa6,0xbf,0xcd,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,0xa5,0xfb,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,0xf9, +0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0x81,0x11,0xfd,0xcd,0xa4,0xb7,0x00,0xa9, +0x41,0x01,0xab,0x81,0x85,0x85,0x85,0x85,0x85,0x05,0x7b,0xda,0x01,0x01,0x35,0x04, +0x27,0x02,0xa1,0x11,0xb6,0x0a,0x26,0x4a,0x13,0xb6,0x05,0x6b,0x01,0xa6,0xe1,0x20, +0x12,0x00,0xb5,0x01,0x55,0x09,0x20,0x3b,0xce,0xcd,0x05,0x27,0x85,0x85,0x4d,0x0b, +0xc5,0xcd,0x13,0xbe,0x14,0xb6,0x01,0x4b,0x00,0x4b,0x1e,0x20,0x4f,0x84,0x84,0xe6, +0xc5,0xcd,0x13,0xbe,0x14,0xb6,0x15,0x00,0x3b,0x01,0x4b,0x2f,0x20,0x3b,0xce,0xcd, +0x34,0x27,0x4d,0x48,0xc6,0xcd,0x3c,0x20,0x9a,0x61,0xad,0xa2,0x18,0x5a,0xad,0x5b, +0x9b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6, +0x04,0x6b,0xb7,0x84,0xc6,0xac,0xc6,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,0x58,0xf0,0xcd,0xa2,0x16, +0xa3,0x12,0x4d,0xf0,0xcd,0x5b,0x9b,0x01,0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84, +0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04,0x6b,0xb7,0x84,0xc6,0x32,0xf0,0xcc,0x16,0xf0, +0xcc,0x03,0x26,0x4a,0x79,0x27,0x4a,0x71,0x27,0x4a,0x0f,0x27,0x4a,0x12,0xb6,0x32, +0xf0,0xcc,0x03,0x27,0x02,0xa1,0x11,0xb6,0x36,0xf0,0xcc,0xde,0x01,0xc7,0x4c,0x9a, +0xf9,0xfb,0xcd,0x18,0xae,0xa4,0x00,0x84,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f, +0xa3,0xb7,0x12,0xb6,0x9b,0x36,0xf0,0xcc,0x03,0x27,0x03,0xa1,0x66,0x01,0xc6,0xe0, +0x01,0x5f,0x72,0xe1,0x01,0xc7,0x4c,0x08,0x20,0x05,0x6b,0x01,0xa6,0xe2,0x01,0x5f, +0x72,0x66,0x01,0x5f,0x72,0x0e,0x27,0x4a,0x11,0x27,0x4a,0x14,0x27,0x4a,0x17,0x27, +0x4a,0xe2,0x01,0xc7,0x7f,0xa4,0x12,0xb6,0x66,0x01,0x03,0x35,0x54,0x26,0x4a,0x11, +0xb6,0xda,0x01,0x5f,0x72,0x9a,0x18,0x84,0x00,0x35,0x19,0x84,0x00,0x35,0x1a,0x84, +0x00,0x35,0x1b,0x84,0x00,0x35,0x9b,0x66,0x01,0x5f,0x72,0x05,0x6b,0x4f,0x88,0x88, +0x88,0x88,0x88,0x81,0x4f,0x3b,0xce,0xcc,0x03,0x27,0x85,0x85,0x4d,0x0b,0xc5,0xcd, +0x11,0xbe,0x12,0xb6,0x80,0x4b,0x00,0x4b,0x81,0xca,0x00,0xd7,0x11,0xb6,0x97,0x52, +0x21,0xae,0x81,0x85,0x85,0x85,0x85,0x85,0x4f,0x84,0x84,0x84,0x51,0xce,0xcd,0x00, +0xae,0x11,0xa6,0x88,0x04,0x7b,0x88,0x04,0x7b,0x88,0x01,0x7b,0xc9,0x00,0x5c,0x72, +0x04,0x24,0x03,0xa1,0x08,0x26,0xc9,0x00,0xc1,0x04,0x7b,0xe2,0x22,0x05,0xe1,0x72, +0x13,0xb6,0x05,0x6b,0x4c,0x9f,0x90,0xcd,0x00,0xd7,0x14,0xe6,0x90,0x05,0xe6,0x72, +0x97,0x05,0xeb,0x72,0x52,0x21,0xae,0x04,0x7b,0x15,0x20,0x4f,0xcc,0x00,0xd7,0x13, +0xb6,0xcb,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,0xc9,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,0x94,0x01,0x01,0x35,0x95,0x01,0xc7,0x4c,0x08,0x20,0x17, +0xb7,0x0c,0x26,0x96,0x01,0xc6,0x16,0xb7,0x04,0x7b,0x01,0x6b,0x02,0x6b,0x03,0x6b, +0x4f,0x04,0x6b,0x99,0x01,0xc6,0x15,0xb7,0x01,0x7b,0x14,0xb7,0x02,0x7b,0x13,0xb7, +0x03,0x7b,0x12,0xb7,0x04,0x7b,0x01,0x6b,0x9a,0x01,0xc6,0x02,0x6b,0x9b,0x01,0xc6, +0x03,0x6b,0x9c,0x01,0xc6,0x04,0x6b,0x9d,0x01,0xc6,0x11,0x00,0x95,0x01,0x55,0x4a, +0x20,0x94,0x01,0x5f,0x72,0x95,0x01,0xc7,0x4c,0x54,0x20,0x94,0x01,0x5f,0x72,0x95, +0x01,0x5f,0x72,0x56,0x27,0x4a,0x17,0x27,0x4a,0x10,0x27,0x4a,0x11,0xb6,0x93,0x01, +0x08,0x35,0x04,0x27,0x12,0x3d,0x93,0x01,0x5f,0x72,0x88,0x88,0x88,0x88,0x81,0xf9, +0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0x81,0x11,0xfd,0xcd,0xa4,0xb7,0x00,0xa9, +0x41,0x01,0xab,0x81,0x10,0x4d,0x00,0x35,0x11,0x4d,0x00,0x35,0x12,0x4d,0x00,0x35, +0x81,0x03,0xd1,0xcd,0x01,0xa6,0x85,0xcf,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,0x97,0x01,0x18,0x72,0xa5,0x01,0x1e,0x00,0x55,0xa6,0x01,0x1f, +0x00,0x55,0xa7,0x01,0x20,0x00,0x55,0xa8,0x01,0x21,0x00,0x55,0xa1,0x01,0x1a,0x00, +0x55,0xa2,0x01,0x1b,0x00,0x55,0xa3,0x01,0x1c,0x00,0x55,0xa4,0x01,0x1d,0x00,0x55, +0xad,0x01,0x12,0x00,0x55,0xae,0x01,0x13,0x00,0x55,0xaf,0x01,0x14,0x00,0x55,0xb0, +0x01,0x15,0x00,0x55,0xa9,0x01,0x16,0x00,0x55,0xaa,0x01,0x17,0x00,0x55,0xab,0x01, +0x18,0x00,0x55,0xac,0x01,0x19,0x00,0x55,0x54,0x26,0x28,0xa1,0x11,0xb6,0x5a,0x20, +0x97,0x01,0xc7,0x10,0xa4,0x97,0x01,0xc6,0x64,0x20,0x97,0x01,0x10,0x72,0x06,0x26, +0x27,0xa1,0x11,0xb6,0xdc,0xfb,0xcd,0xa4,0xb7,0x48,0xa9,0x41,0x44,0xab,0x52,0x08, +0xae,0x11,0xb6,0xb8,0xfb,0xcd,0x12,0xae,0xdc,0xfb,0xcd,0xa4,0xb7,0x48,0xa9,0x41, +0x40,0xab,0x52,0x08,0xae,0x11,0xb6,0xb8,0xfb,0xcd,0x16,0xae,0x14,0x48,0xa5,0x01, +0x55,0x15,0x48,0xa6,0x01,0x55,0x16,0x48,0xa7,0x01,0x55,0x17,0x48,0xa8,0x01,0x55, +0x10,0x48,0xa1,0x01,0x55,0x11,0x48,0xa2,0x01,0x55,0x12,0x48,0xa3,0x01,0x55,0x13, +0x48,0xa4,0x01,0x55,0x73,0xed,0xcd,0xa1,0x1b,0x9d,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,0x12,0xed,0xcc,0x03,0x25,0x28,0xa1,0x11,0xb6,0x6c,0xed, +0xcc,0xa8,0xed,0xcd,0xa1,0x1b,0x9d,0xed,0xcd,0x5b,0xac,0xc6,0xcd,0x0a,0xa6,0x01, +0x6b,0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04,0x6b, +0xb7,0x84,0xc6,0x97,0x01,0x10,0x72,0x08,0xed,0xcc,0x03,0x27,0x91,0xa1,0x11,0xb6, +0x90,0xed,0xcd,0x13,0x4d,0x03,0x35,0x90,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, +0xa5,0xfb,0xcd,0xa0,0x3f,0xa1,0xb7,0x06,0xa4,0xa1,0xb6,0xa2,0x3f,0xa3,0x3f,0x9d, +0xed,0xcd,0x5b,0x01,0x6b,0x14,0x4d,0xc6,0x02,0x6b,0x15,0x4d,0xc6,0x03,0x6b,0x16, +0x4d,0xc6,0x04,0x6b,0x17,0x4d,0xc6,0xac,0xc6,0xcd,0x0f,0xa6,0x90,0xed,0xcd,0x13, +0x4d,0x03,0x35,0x90,0xed,0xcd,0x13,0x4d,0xc3,0x35,0x25,0x20,0x02,0x6b,0x03,0x6b, +0x04,0x6b,0x4f,0x73,0xed,0xcd,0xa1,0x1a,0x9d,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,0x82,0xec,0xcc,0x03, +0x24,0x80,0xa1,0x11,0xb6,0x9b,0x88,0x88,0x88,0x88,0x81,0x48,0x42,0x00,0x35,0x49, +0x42,0x00,0x35,0x4a,0x42,0x00,0x35,0x81,0x85,0x85,0x85,0x85,0x4f,0x9a,0x06,0xcb, +0xcd,0x68,0x01,0x01,0x35,0x21,0xc4,0xcd,0x03,0x27,0xbf,0x00,0xc6,0x16,0xad,0x4b, +0x42,0x05,0x35,0x04,0x20,0x4b,0x42,0x01,0x35,0x06,0x27,0x92,0x01,0xc6,0x75,0xc9, +0xcd,0xf9,0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa2,0x16,0x11,0xfd,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,0x15,0xdf,0xcd,0x50,0x20, +0x59,0xad,0x4b,0x42,0x05,0x35,0x04,0x20,0x4b,0x42,0x01,0x35,0x06,0x27,0x92,0x01, +0xc6,0x13,0x26,0x4a,0x68,0x01,0xc6,0x69,0x20,0x35,0xca,0xcd,0x15,0xc9,0xcd,0x08, +0x26,0x11,0x3d,0x9b,0x92,0x01,0x01,0x35,0x04,0x20,0x92,0x01,0x5f,0x72,0x06,0x26, +0x02,0xa1,0x11,0xb6,0x88,0x88,0x88,0x88,0x81,0xf9,0xfb,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,0x11,0xfd,0xcd, +0xa4,0xb7,0x00,0xa9,0x41,0x03,0xab,0x81,0x04,0x80,0x00,0x35,0x05,0x80,0x00,0x35, +0x06,0x80,0x00,0x35,0x81,0x85,0x85,0x85,0x85,0x85,0x85,0x4f,0x9a,0x35,0xca,0xcd, +0x67,0x01,0x5f,0x72,0xbc,0x84,0x00,0x35,0xbd,0x84,0x00,0x35,0xbe,0x84,0x18,0x35, +0xbf,0x84,0x00,0x35,0x45,0xad,0x1b,0x80,0x80,0x35,0x14,0x80,0x00,0x35,0x15,0x80, +0x00,0x35,0x16,0x80,0x00,0x35,0x17,0x80,0x00,0x35,0x4e,0xad,0x0b,0x80,0x00,0x35, +0x3c,0xad,0x07,0x80,0x00,0x35,0x00,0x80,0x00,0x35,0x01,0x80,0x00,0x35,0x02,0x80, +0x00,0x35,0x03,0x80,0x00,0x35,0xce,0xea,0xcd,0xa3,0xb7,0xf8,0xa4,0xa3,0xb6,0x68, +0xad,0x5b,0x03,0x6b,0x78,0x84,0xc6,0x04,0x6b,0x79,0x84,0xc6,0x05,0x6b,0x7a,0x84, +0xc6,0x06,0x6b,0x7b,0x84,0xc6,0x69,0x20,0x06,0xcb,0xcd,0x67,0x01,0x01,0x35,0xee, +0xdd,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,0xc1,0xea,0xcd,0x1b, +0x80,0x81,0x35,0xf9,0xfb,0xcd,0x14,0xae,0xa4,0x00,0x80,0x35,0x84,0xfb,0xcd,0x52, +0x80,0xae,0xb4,0xea,0xcd,0x0b,0x80,0x20,0x35,0x04,0x20,0x0b,0x80,0x60,0x35,0x06, +0x26,0xd1,0x01,0xc7,0x16,0xb6,0xd2,0x01,0x60,0x20,0x55,0xd3,0x01,0x61,0x20,0x55, +0xd4,0x01,0x62,0x20,0x55,0xd5,0x01,0x63,0x20,0x55,0x68,0x20,0x21,0x35,0x64,0x20, +0xd2,0x01,0x55,0x65,0x20,0xd3,0x01,0x55,0x66,0x20,0xd4,0x01,0x55,0x67,0x20,0xd5, +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,0x62,0x01,0x55,0x61,0x20,0x63,0x01,0x55,0x62,0x20,0x64,0x01,0x55,0x63, +0x20,0x65,0x01,0x55,0xd2,0x01,0xb1,0xf1,0x55,0xd3,0x01,0xb2,0xf1,0x55,0xd4,0x01, +0xb3,0xf1,0x55,0xd5,0x01,0xb4,0xf1,0x55,0xd6,0x01,0xc7,0xd7,0x01,0x21,0x35,0xd8, +0x01,0xe6,0x35,0xd9,0x01,0xf0,0x35,0x23,0x20,0xd2,0x01,0xb5,0xf1,0x55,0xd3,0x01, +0xb6,0xf1,0x55,0xd4,0x01,0xb7,0xf1,0x55,0xd5,0x01,0xb8,0xf1,0x55,0xd6,0x01,0xc7, +0xd7,0x01,0x21,0x35,0xd8,0x01,0xf0,0x35,0xd9,0x01,0x7c,0x35,0x48,0x20,0xd2,0x01, +0xb9,0xf1,0x55,0xd3,0x01,0xba,0xf1,0x55,0xd4,0x01,0xbb,0xf1,0x55,0xd5,0x01,0xbc, +0xf1,0x55,0xd6,0x01,0xc7,0xd7,0x01,0x21,0x35,0xd8,0x01,0xf6,0x35,0xd9,0x01,0x94, +0x35,0x6d,0x20,0x9c,0xea,0xcd,0x07,0x80,0xe0,0x35,0xd2,0x01,0xad,0xf1,0x55,0xd3, +0x01,0xae,0xf1,0x55,0xd4,0x01,0xaf,0xf1,0x55,0xd5,0x01,0xb0,0xf1,0x55,0xd6,0x01, +0x5f,0x72,0xd7,0x01,0x2a,0x35,0xd8,0x01,0x09,0x35,0xd9,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,0x9c,0xea,0xcd,0x07,0x80,0xc0,0x35, +0xf9,0xfb,0xcd,0x5f,0xa4,0x00,0x80,0x35,0x84,0xfb,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,0xce,0xea,0xcd,0xa3,0x10,0xa3,0x12, +0xa3,0x14,0xa9,0xea,0xcd,0x5b,0x03,0x6b,0x78,0x84,0xc6,0x04,0x6b,0x79,0x84,0xc6, +0x05,0x6b,0x7a,0x84,0xc6,0x06,0x6b,0x7b,0x84,0xc6,0xf9,0xfb,0xcd,0xb4,0xae,0xa4, +0x00,0x84,0x35,0xa2,0x16,0xa9,0xea,0xcd,0x5b,0x03,0x6b,0xb4,0x84,0xc6,0x04,0x6b, +0xb5,0x84,0xc6,0x05,0x6b,0xb6,0x84,0xc6,0x06,0x6b,0xb7,0x84,0xc6,0x2a,0xea,0xcc, +0x03,0x27,0x4a,0x13,0xb6,0x9b,0x88,0x88,0x88,0x88,0x88,0x88,0x81,0x85,0x4f,0x7d, +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,0x7d,0x01,0xc6, +0xf9,0xfb,0xcd,0x10,0xae,0xa4,0x00,0x8c,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f, +0xa3,0x00,0x7e,0x01,0x55,0xf9,0xfb,0xcd,0x1c,0xae,0xa4,0x00,0x8c,0x35,0x84,0xfb, +0xcd,0x5f,0x0f,0xa4,0x4e,0x7e,0x01,0xc6,0x9b,0x06,0x20,0xc7,0xfa,0xa4,0x06,0x20, +0xc6,0x52,0x27,0x7d,0x01,0xc6,0xef,0x25,0x7d,0x01,0xc1,0x01,0x6b,0x4c,0x9f,0x7e, +0x01,0xd7,0x12,0xe6,0x01,0xee,0x72,0x0a,0x20,0x4f,0x7d,0x01,0xc7,0x11,0xb6,0x88, +0x81,0x85,0x4f,0x6a,0x01,0x5f,0x72,0xef,0x25,0x6b,0x01,0xc1,0x01,0x6b,0x4c,0x9f, +0x14,0xe7,0x6c,0x01,0xd6,0x01,0xee,0x72,0x0a,0x20,0x4f,0x13,0x00,0x6b,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,0xf9,0xfb,0xcd,0x48,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x27,0xbe,0x28,0xb6,0xf9,0xfb,0xcd,0x44,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x25,0xbe,0x26,0xb6,0xf9,0xfb,0xcd,0x40,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x23,0xbe,0x24,0xb6,0xf9,0xfb,0xcd,0x3c,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x21,0xbe,0x22,0xb6,0xf9,0xfb,0xcd,0x38,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x1f,0xbe,0x20,0xb6,0xf9,0xfb,0xcd,0x34,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x1d,0xbe,0x1e,0xb6,0xf9,0xfb,0xcd,0x30,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x1b,0xbe,0x1c,0xb6,0xf9,0xfb,0xcd,0x2c,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x19,0xbe,0x1a,0xb6,0xf9,0xfb,0xcd,0x28,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x17,0xbe,0x18,0xb6,0xf9,0xfb,0xcd,0x24,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x15,0xbe,0x16,0xb6,0xf9,0xfb,0xcd,0x20,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x13,0xbe,0x14,0xb6,0xf9,0xfb,0xcd,0x1c,0xae,0xa4,0x00,0x84, +0x35,0x84,0xfb,0xcd,0x11,0xbe,0x12,0xb6,0x9b,0x81,0x4f,0xdf,0x01,0x01,0x35,0x3b, +0x01,0xcf,0x1f,0xbe,0x3c,0x01,0xc7,0x20,0xb6,0x39,0x01,0xcf,0x1d,0xbe,0x3a,0x01, +0xc7,0x1e,0xb6,0x37,0x01,0xcf,0x1b,0xbe,0x38,0x01,0xc7,0x1c,0xb6,0x35,0x01,0xcf, +0x19,0xbe,0x36,0x01,0xc7,0x1a,0xb6,0x33,0x01,0xcf,0x17,0xbe,0x34,0x01,0xc7,0x18, +0xb6,0x31,0x01,0xcf,0x15,0xbe,0x32,0x01,0xc7,0x16,0xb6,0x2f,0x01,0xcf,0x13,0xbe, +0x30,0x01,0xc7,0x14,0xb6,0x2d,0x01,0xcf,0x11,0xbe,0x2e,0x01,0xc7,0x12,0xb6,0x81, +0x4f,0x9a,0x30,0x42,0x00,0x35,0x31,0x42,0x00,0x35,0x32,0x42,0x00,0x35,0x33,0x42, +0x00,0x35,0x2d,0xda,0xcd,0x4f,0xdb,0xcd,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84, +0x8f,0xdf,0xcd,0x62,0x01,0x3b,0x63,0x01,0x3b,0x64,0x01,0x3b,0x65,0x01,0x3b,0x54, +0x01,0x3b,0x55,0x01,0x3b,0x56,0x01,0x3b,0x57,0x01,0x3b,0x7b,0xd7,0xcd,0x9b,0xc7, +0x20,0x9a,0x21,0xc4,0xcd,0x9b,0xce,0x27,0x68,0x01,0xc6,0xbf,0x00,0x01,0x35,0x9a, +0x00,0xc0,0xcd,0x9b,0xf1,0x25,0x01,0xe1,0x72,0x02,0x6b,0x4c,0x02,0x7b,0x9a,0x98, +0xc2,0xcd,0x9b,0x08,0x20,0x4f,0x01,0x6b,0x12,0xb6,0x02,0x20,0x04,0xa6,0x04,0x26, +0x02,0xa1,0x11,0xb6,0x81,0x85,0x85,0x4f,0xbf,0x00,0x5f,0x72,0x08,0x27,0x17,0x3d, +0x88,0x88,0x81,0x85,0x85,0x85,0x85,0x85,0x01,0x7b,0xde,0x01,0x01,0x35,0x9a,0xf9, +0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa3,0x1f,0x11,0xfd,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,0xc5,0xfc,0xcd,0xa4,0xb7,0x00,0xa9, +0x41,0x02,0xab,0x5b,0xa3,0x1e,0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x03,0xa4,0xa2,0xb6, +0xa3,0x3f,0x21,0xfc,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,0xe0,0xc7,0xcd,0x1c,0xbe,0x20,0xa6,0x9b, +0x62,0x01,0x22,0x00,0x55,0x63,0x01,0x23,0x00,0x55,0x64,0x01,0x24,0x00,0x55,0x65, +0x01,0x25,0x00,0x55,0x14,0x27,0xca,0xfb,0xcd,0x22,0xae,0x61,0x01,0xc7,0x12,0xb6, +0xbb,0x00,0xc7,0x21,0xb6,0xbc,0x00,0xcf,0x1f,0xbe,0xbd,0x00,0xc7,0x20,0xb6,0x5b, +0x01,0xcf,0x19,0xbe,0x5c,0x01,0xc7,0x1a,0xb6,0x5f,0x01,0xcf,0x17,0xbe,0x60,0x01, +0xc7,0x18,0xb6,0x59,0x01,0xcf,0x15,0xbe,0x5a,0x01,0xc7,0x16,0xb6,0x5d,0x01,0xcf, +0x13,0xbe,0x5e,0x01,0xc7,0x14,0xb6,0xf6,0xe5,0xcc,0xdb,0x01,0xc7,0x4c,0xf6,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,0x66,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,0x11,0xfd,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, +0xf9,0xfb,0xcd,0x30,0xae,0x1e,0xad,0x16,0x7b,0xf9,0xfb,0xcd,0x2c,0xae,0x27,0xad, +0x15,0x7b,0xf9,0xfb,0xcd,0x28,0xae,0x30,0xad,0x14,0x7b,0x7d,0xfc,0xcd,0xa4,0xb7, +0x00,0xa9,0x41,0x13,0xab,0x5b,0x11,0xfd,0xcd,0xd6,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,0xd2,0x01,0x55,0x61,0x20,0xd3,0x01,0x55,0x62,0x20,0xd4, +0x01,0x55,0x63,0x20,0xd5,0x01,0x55,0xf9,0xfb,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x0d, +0xab,0x5b,0xee,0xfc,0xcd,0xd7,0xe4,0xcd,0x5b,0xdf,0xe4,0xcd,0xf0,0x27,0x1b,0xea, +0x72,0x1c,0x7b,0xf7,0x26,0x4a,0xd1,0x01,0xc6,0xc0,0xe4,0xcc,0x03,0x27,0x4a,0x67, +0x01,0xc6,0x84,0x84,0x84,0x84,0x35,0xc7,0xcd,0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x88, +0x1a,0x7b,0x88,0x1a,0x7b,0x0f,0x20,0x10,0xc7,0xcd,0x88,0x1a,0x7b,0x88,0x1a,0x7b, +0x88,0x1a,0x7b,0x88,0x1a,0x7b,0x11,0x27,0xe4,0x01,0xc6,0xe6,0x01,0x5f,0x72,0x04, +0x20,0x7d,0xfc,0xcd,0xd7,0xe4,0xcd,0x5b,0xdf,0xe4,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,0xf9,0xfb,0xcd,0x60,0xae,0xa4,0x00,0x20,0x35,0x84,0xfb, +0xcd,0x1b,0xee,0x72,0x1c,0x7b,0xe5,0xe3,0xcc,0x03,0x26,0x1b,0xea,0x72,0x1c,0x7b, +0xf9,0xfb,0xcd,0xd7,0xe4,0xcd,0x5b,0xa0,0x3f,0x11,0xfd,0xcd,0x5f,0xa4,0x00,0x84, +0x35,0xf9,0xfb,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x09,0xab,0x5b,0x11,0xfd,0xcd,0xe9, +0xae,0xa4,0x00,0xe4,0x35,0x06,0x20,0xed,0xae,0xa4,0x00,0xe4,0x35,0x08,0x26,0x4c, +0x7c,0x01,0xc6,0x05,0x6b,0xf1,0xe4,0xc6,0x06,0x6b,0xf2,0xe4,0xc6,0x07,0x6b,0xf3, +0xe4,0xc6,0x08,0x6b,0xf4,0xe4,0xc6,0x01,0x6b,0xf5,0xe4,0xc6,0x02,0x6b,0xf6,0xe4, +0xc6,0x03,0x6b,0xf7,0xe4,0xc6,0x04,0x6b,0xf8,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,0x81,0x84,0x84,0x84,0x84,0xf9,0xfb,0xcd,0x10, +0xae,0xa4,0x00,0x84,0x35,0xa1,0x1e,0x11,0xfd,0xcd,0x13,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,0xf9,0xfb,0xcd,0x33,0xad,0x5b,0xcb,0xfc,0xcd, +0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x5b,0xa0,0xb7,0x03,0xa4,0xa0,0xb6,0xa1,0x3f, +0xa2,0x3f,0xa3,0x3f,0x11,0xfd,0xcd,0x50,0xad,0x5b,0x01,0x6b,0x10,0x84,0xc6,0x02, +0x6b,0x11,0x84,0xc6,0x03,0x6b,0x12,0x84,0xc6,0x04,0x6b,0x13,0x84,0xc6,0xc5,0xfc, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x5b,0x96,0xfb,0xcd,0x14,0xa6,0x61,0xe2, +0xcd,0x0b,0x6b,0x04,0xa6,0x02,0x20,0x03,0xa6,0x06,0x20,0x02,0xa6,0x0a,0x20,0x4c, +0x0b,0x20,0x09,0x27,0x08,0xa0,0x09,0x27,0x04,0xa0,0x0a,0x27,0x02,0xa0,0x1b,0x27, +0x02,0xa0,0x0b,0x7b,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,0xf9,0xfb,0xcd,0x64,0xae,0xa4,0x00,0x20,0x35,0x61, +0xe2,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,0xf9, +0xfb,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,0x96,0xfb,0xcd,0x18,0xa6,0xa0, +0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x01,0x7b,0xf9,0xfb,0xcd,0x14,0xae,0xa4, +0x00,0x84,0x35,0xa0,0xb7,0x3f,0xa4,0xa0,0xb6,0xa1,0x3f,0xa2,0x3f,0xa3,0x3f,0x96, +0xfb,0xcd,0x18,0xa6,0x11,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x04,0xab,0x5b,0x25, +0x24,0x0f,0xa1,0x07,0x7b,0xac,0xc6,0xcd,0x64,0xa6,0x84,0x84,0x84,0x84,0x10,0xc7, +0xcd,0xb3,0x00,0x3b,0xb4,0x00,0x3b,0xb5,0x00,0x3b,0xb6,0x00,0x3b,0x0f,0x20,0x35, +0xc7,0xcd,0xb3,0x00,0x3b,0xb4,0x00,0x3b,0xb5,0x00,0x3b,0xb6,0x00,0x3b,0x11,0x26, +0x4a,0x66,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, +0x33,0xe1,0xcd,0x67,0x20,0x28,0x35,0x09,0x20,0x01,0xa6,0x33,0xe1,0xcd,0x67,0x20, +0x14,0x35,0x0b,0x25,0x02,0xa2,0x08,0x7b,0xdd,0xa0,0x09,0x7b,0x1e,0x20,0x4f,0x33, +0xe1,0xcd,0x67,0x20,0x0a,0x35,0x0a,0x25,0x04,0xa2,0x08,0x7b,0xd9,0xa0,0x09,0x7b, +0x88,0x81,0x48,0x01,0xce,0x49,0x01,0xc6,0xf9,0xfb,0xcd,0x81,0x84,0x84,0xf9,0xfb, +0xcd,0x0c,0xae,0xa4,0x00,0x41,0x35,0x18,0xfc,0xcd,0x41,0x40,0x01,0xc9,0x41,0x41, +0x01,0xcb,0x17,0xad,0x08,0xae,0xa4,0x00,0x41,0x35,0x18,0xfc,0xcd,0x5c,0x01,0x26, +0x4c,0x26,0xad,0x04,0xae,0xa4,0x00,0x41,0x35,0x18,0xfc,0xcd,0x41,0x3e,0x01,0xc9, +0x41,0x3f,0x01,0xcb,0x41,0x01,0xe2,0x72,0x41,0x02,0xe0,0x72,0x46,0x01,0xce,0x47, +0x01,0xc6,0xf9,0xfb,0xcd,0x5f,0xa4,0x00,0x41,0x35,0x18,0xfc,0xcd,0x5c,0x01,0x26, +0x4c,0x41,0x01,0xe2,0x72,0x41,0x02,0xe0,0x72,0x46,0x01,0xce,0x47,0x01,0xc6,0x02, +0x6b,0x4b,0x01,0xc6,0x01,0x6b,0x4a,0x01,0xc6,0x88,0x88,0x81,0x4e,0x01,0xce,0x4f, +0x01,0xc6,0xf9,0xfb,0xcd,0x81,0x41,0x4a,0x01,0xc9,0x41,0x4b,0x01,0xcb,0x46,0x54, +0x42,0x01,0xce,0x43,0x01,0xc6,0x81,0x4a,0x01,0xce,0x4b,0x01,0xc6,0xf9,0xfb,0xcd, +0x81,0x96,0xfb,0xcd,0x10,0xa6,0x18,0xfc,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,0xf9,0xfb,0xcd,0x6c,0xae,0xa4,0x00,0x83, +0x35,0xcb,0xfc,0xcd,0x23,0xad,0x5b,0x2e,0xad,0x43,0xad,0xf9,0xfb,0xcd,0x2d,0xad, +0x5b,0x18,0xfc,0xcd,0x4e,0xad,0x0d,0x20,0x48,0xad,0x39,0xad,0x5b,0x18,0xfc,0xcd, +0x4a,0x01,0xce,0x4b,0x01,0xc6,0x10,0x26,0x4a,0x3d,0x01,0xc6,0xf9,0xfb,0xcd,0x68, +0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0x57,0xad,0x5b,0x62,0xad,0x6d,0xad,0x5e, +0xad,0x5b,0x18,0xfc,0xcd,0x75,0xad,0x64,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd, +0x6f,0xad,0x5b,0x7a,0xad,0x41,0x50,0x01,0xc9,0x41,0x51,0x01,0xcb,0x05,0xee,0x72, +0x06,0x7b,0xf9,0xfb,0xcd,0xdf,0xde,0xcd,0x5b,0x18,0xfc,0xcd,0x05,0xee,0x72,0x06, +0x7b,0xf9,0xfb,0xcd,0x60,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0xdf,0xde,0xcd, +0x5b,0xe7,0xde,0xcd,0x41,0x50,0x01,0xc9,0x41,0x51,0x01,0xcb,0x0b,0xdf,0xcd,0xdf, +0xde,0xcd,0x5b,0x18,0xfc,0xcd,0x0b,0xdf,0xcd,0x5c,0xae,0xa4,0x00,0x83,0x35,0x18, +0xfc,0xcd,0x46,0x54,0x42,0x01,0xce,0x43,0x01,0xc6,0x05,0xef,0x72,0x06,0x6b,0x4a, +0x5a,0x01,0x26,0x4d,0x4e,0x01,0xce,0x4f,0x01,0xc6,0x10,0x20,0x06,0x6b,0x4f,0x01, +0xc6,0x05,0x6b,0x4e,0x01,0xc6,0x0c,0x26,0x4a,0x3d,0x01,0xc6,0x88,0x88,0x88,0x88, +0x88,0x88,0x81,0x4e,0x01,0xce,0x4f,0x01,0xc6,0xf9,0xfb,0xcd,0x81,0x4d,0x41,0x40, +0x01,0xc9,0x41,0x41,0x01,0xcb,0x81,0x04,0xa0,0x41,0x3e,0x01,0xc9,0x41,0x3f,0x01, +0xcb,0x81,0x41,0x4a,0x01,0xc9,0x41,0x4b,0x01,0xcb,0x46,0x54,0x42,0x01,0xce,0x43, +0x01,0xc6,0x81,0x46,0x01,0xce,0x47,0x01,0xc6,0xf9,0xfb,0xcd,0x81,0x4a,0x01,0xce, +0x4b,0x01,0xc6,0xf9,0xfb,0xcd,0x81,0x96,0xfb,0xcd,0x10,0xa6,0x18,0xfc,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, +0xf9,0xfb,0xcd,0x3c,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0x25,0xad,0x5b,0x30, +0xad,0x4f,0xad,0xf9,0xfb,0xcd,0x2f,0xad,0x5b,0x18,0xfc,0xcd,0x5a,0xad,0x0d,0x20, +0x4a,0xad,0x3b,0xad,0x5b,0x18,0xfc,0xcd,0x4a,0x01,0xce,0x4b,0x01,0xc6,0x10,0x26, +0x4a,0x3d,0x01,0xc6,0xf9,0xfb,0xcd,0x38,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd, +0x59,0xad,0x5b,0x64,0xad,0x6f,0xad,0x60,0xad,0x5b,0x18,0xfc,0xcd,0x77,0xad,0x34, +0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0x71,0xad,0x5b,0x7c,0xad,0x41,0x50,0x01, +0xc9,0x41,0x51,0x01,0xcb,0x07,0xee,0x72,0x08,0x7b,0xf9,0xfb,0xcd,0x99,0xdd,0xcd, +0x5b,0x18,0xfc,0xcd,0x07,0xee,0x72,0x08,0x7b,0xf9,0xfb,0xcd,0x30,0xae,0xa4,0x00, +0x83,0x35,0xcb,0xfc,0xcd,0x99,0xdd,0xcd,0x5b,0xa1,0xdd,0xcd,0x41,0x50,0x01,0xc9, +0x41,0x51,0x01,0xcb,0xe4,0xdd,0xcd,0x99,0xdd,0xcd,0x5b,0x18,0xfc,0xcd,0xe4,0xdd, +0xcd,0x2c,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0x99,0xdd,0xcd,0x5b,0xa1,0xdd, +0xcd,0x41,0x4c,0x01,0xc9,0x41,0x4d,0x01,0xcb,0xaa,0xdd,0xcd,0x99,0xdd,0xcd,0x5b, +0x18,0xfc,0xcd,0xaa,0xdd,0xcd,0x10,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0x99, +0xdd,0xcd,0x5b,0xa1,0xdd,0xcd,0x4a,0x5a,0x01,0x26,0xda,0xdd,0xcd,0x0d,0xee,0x72, +0x0e,0x7b,0xf9,0xfb,0xcd,0x99,0xdd,0xcd,0x5b,0x18,0xfc,0xcd,0x5a,0x01,0x24,0xcf, +0xdd,0xcd,0xb4,0xdd,0xcd,0x0c,0xae,0xa4,0x00,0x83,0x35,0xcb,0xfc,0xcd,0x99,0xdd, +0xcd,0x5b,0xa1,0xdd,0xcd,0x0d,0xee,0x72,0x0e,0x7b,0xf9,0xfb,0xcd,0x99,0xdd,0xcd, +0x5b,0x18,0xfc,0xcd,0x5a,0x01,0x24,0x03,0xa0,0xb4,0xdd,0xcd,0x08,0xae,0xa4,0x00, +0x83,0x35,0xcb,0xfc,0xcd,0x99,0xdd,0xcd,0x5b,0xa1,0xdd,0xcd,0x4a,0x5a,0x01,0x26, +0xda,0xdd,0xcd,0x0d,0xee,0x72,0x0e,0x7b,0xf9,0xfb,0xcd,0x99,0xdd,0xcd,0x5b,0x18, +0xfc,0xcd,0x5a,0x01,0x24,0xcf,0xdd,0xcd,0xb4,0xdd,0xcd,0x04,0xae,0xa4,0x00,0x83, +0x35,0xcb,0xfc,0xcd,0x99,0xdd,0xcd,0x5b,0xa1,0xdd,0xcd,0x0d,0xee,0x72,0x0e,0x7b, +0xf9,0xfb,0xcd,0x99,0xdd,0xcd,0x5b,0x18,0xfc,0xcd,0x5a,0x01,0x24,0x03,0xa0,0xb4, +0xdd,0xcd,0x40,0xae,0xa4,0x00,0x83,0x35,0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x0f,0xa4, +0xa2,0xb6,0x18,0xfc,0xcd,0x05,0xee,0x72,0x06,0x7b,0xf9,0xfb,0xcd,0x28,0xae,0xa4, +0x00,0x83,0x35,0xa0,0x3f,0xa1,0x3f,0xa2,0xb7,0x1f,0xa4,0xa2,0xb6,0x18,0xfc,0xcd, +0x42,0x01,0xce,0x43,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,0x4e,0x01,0xce,0x4f,0x01,0xc6,0x06,0x6b,0x45,0x01,0xc6,0x05, +0x6b,0x44,0x01,0xc6,0x0a,0x6b,0x05,0xaa,0x0a,0x7b,0x20,0x20,0x08,0x6b,0x4f,0x01, +0xc6,0x07,0x6b,0x4e,0x01,0xc6,0x05,0xef,0x72,0x06,0x6b,0x59,0x48,0x44,0x01,0xce, +0x45,0x01,0xc6,0x0a,0x6b,0x01,0xaa,0x0a,0x7b,0x1f,0x26,0x4a,0x3d,0x01,0xc6,0x09, +0x6b,0x80,0xaa,0x09,0x7b,0x06,0x26,0x04,0xa1,0x61,0x01,0xc6,0x09,0x6b,0x20,0xa6, +0x0a,0x6b,0x0b,0x6b,0x0c,0x6b,0x4f,0x0d,0x6b,0x0e,0xef,0x72,0x4e,0x01,0xc9,0x41, +0x4f,0x01,0xcb,0x48,0x01,0xce,0x49,0x01,0xc6,0x8b,0x41,0x00,0xa2,0x41,0x0e,0xa0, +0x5b,0x81,0x84,0x84,0x84,0x84,0xdd,0x01,0x01,0x35,0xf9,0xfb,0xcd,0xb4,0xae,0xa4, +0x00,0x84,0x35,0xa0,0x16,0x11,0xfd,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,0xf9,0xfb,0xcd,0x78,0xae,0xa4, +0x00,0x84,0x35,0xcb,0xfc,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,0x96,0xfb, +0xcd,0x16,0xa6,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0x00,0x58,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,0xf9, +0xfb,0xcd,0x74,0xae,0xa4,0x00,0x84,0x35,0x18,0xfc,0xcd,0x3b,0x01,0xce,0x3c,0x01, +0xc6,0xf9,0xfb,0xcd,0x70,0xae,0xa4,0x00,0x84,0x35,0x18,0xfc,0xcd,0x39,0x01,0xce, +0x3a,0x01,0xc6,0xf9,0xfb,0xcd,0x6c,0xae,0xa4,0x00,0x84,0x35,0x18,0xfc,0xcd,0x37, +0x01,0xce,0x38,0x01,0xc6,0xf9,0xfb,0xcd,0x68,0xae,0xa4,0x00,0x84,0x35,0x18,0xfc, +0xcd,0x35,0x01,0xce,0x36,0x01,0xc6,0xf9,0xfb,0xcd,0x64,0xae,0xa4,0x00,0x84,0x35, +0x18,0xfc,0xcd,0x33,0x01,0xce,0x34,0x01,0xc6,0xf9,0xfb,0xcd,0x60,0xae,0xa4,0x00, +0x84,0x35,0x18,0xfc,0xcd,0x31,0x01,0xce,0x32,0x01,0xc6,0xf9,0xfb,0xcd,0x5c,0xae, +0xa4,0x00,0x84,0x35,0x18,0xfc,0xcd,0x2f,0x01,0xce,0x30,0x01,0xc6,0xf9,0xfb,0xcd, +0x58,0xae,0xa4,0x00,0x84,0x35,0x18,0xfc,0xcd,0x2d,0x01,0xce,0x2e,0x01,0xc6,0x88, +0x88,0x88,0x88,0x81,0xa4,0xc6,0x92,0xa5,0xbf,0xa4,0xb7,0x81,0xa4,0xd6,0x92,0xa5, +0x3f,0xa4,0xb7,0x81,0x84,0x3b,0x01,0xcf,0x33,0x01,0xce,0x3c,0x01,0xc7,0x34,0x01, +0xc6,0x33,0x01,0xcf,0x34,0x01,0xc7,0x4a,0x5a,0x01,0x26,0x4d,0x59,0x48,0x5b,0x01, +0xce,0x5c,0x01,0xc6,0x0b,0x20,0x0e,0x26,0x4d,0x5b,0x01,0xce,0x5c,0x01,0xc6,0x0b, +0x26,0x4a,0x3d,0x01,0xc6,0x39,0x01,0xcf,0x31,0x01,0xce,0x3a,0x01,0xc7,0x32,0x01, +0xc6,0x32,0x01,0x5f,0x72,0x31,0x01,0x5f,0x72,0x37,0x01,0xcf,0x2f,0x01,0xce,0x38, +0x01,0xc7,0x30,0x01,0xc6,0x2f,0x01,0xcf,0x30,0x01,0xc7,0x4a,0x5a,0x01,0x26,0x4d, +0xfa,0x26,0x5a,0x90,0x46,0x54,0x06,0x27,0x58,0x01,0xce,0x90,0x59,0x01,0xce,0x5a, +0x01,0xc6,0x35,0x01,0xcf,0x2d,0x01,0xce,0x36,0x01,0xc7,0x2e,0x01,0xc6,0x2e,0x01, +0x5f,0x72,0x2d,0x01,0x5f,0x72,0x58,0x01,0x5f,0x72,0x04,0x26,0x04,0xa1,0xe2,0x01, +0xc6,0x0b,0x26,0x03,0xa1,0x5b,0x01,0x40,0x01,0x55,0x5c,0x01,0x41,0x01,0x55,0x5f, +0x01,0x44,0x01,0x55,0x60,0x01,0x45,0x01,0x55,0x59,0x01,0x3e,0x01,0x55,0x5a,0x01, +0x3f,0x01,0x55,0x5d,0x01,0x42,0x01,0x55,0x5e,0x01,0x43,0x01,0x55,0x14,0xd8,0xcc, +0x25,0xda,0xcd,0xd4,0xa9,0x41,0x86,0xab,0x52,0x1c,0xae,0x01,0x7b,0xf9,0xfb,0xcd, +0x54,0xae,0xa4,0x00,0x01,0x35,0x50,0xfb,0xcd,0xa4,0xb7,0xd4,0xa9,0x41,0x82,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x53,0x01,0xc7,0x25,0xda,0xcd,0xd4,0xa9,0x41,0x81,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x52,0x01,0xc7,0x25,0xda,0xcd,0xd4,0xa9,0x41,0x80,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x51,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x50,0x01,0xc7, +0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x7e,0xab,0x52,0x1c,0xae,0x01,0x7b,0x4e,0x01,0x5f, +0x72,0x4f,0x01,0x01,0x35,0x4d,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x4c,0x01,0xc7, +0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x7a,0xab,0x52,0x1c,0xae,0x01,0x7b,0x4b,0x01,0xc7, +0xa4,0xd6,0x92,0xa5,0x3c,0x4a,0x01,0xc7,0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x78,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x49,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x48,0x01,0xc7, +0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x76,0xab,0x52,0x1c,0xae,0x01,0x7b,0x47,0x01,0xc7, +0xa4,0xd6,0x92,0xa5,0x3c,0x46,0x01,0xc7,0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x74,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x45,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x44,0x01,0xc7, +0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x72,0xab,0x52,0x1c,0xae,0x01,0x7b,0x43,0x01,0xc7, +0xa4,0xd6,0x92,0xa5,0x3c,0x42,0x01,0xc7,0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x70,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x41,0x01,0xc7,0xa4,0xd6,0x92,0xa5,0x3c,0x40,0x01,0xc7, +0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x6e,0xab,0x52,0x1c,0xae,0x01,0x7b,0x3f,0x01,0xc7, +0xa4,0xd6,0x92,0xa5,0x3c,0x3e,0x01,0xc7,0x1d,0xda,0xcd,0xd4,0xa9,0x41,0x6c,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x3d,0x01,0xc7,0x25,0xda,0xcd,0xd4,0xa9,0x41,0x6b,0xab, +0x52,0x1c,0xae,0x01,0x7b,0x63,0xd9,0xcc,0x8b,0xd9,0xcc,0x03,0x27,0x02,0xa1,0x63, +0xd9,0xcc,0x03,0x26,0x03,0xa1,0x66,0x01,0xc6,0x58,0x01,0xc7,0x29,0xb6,0x54,0x01, +0x2a,0x00,0x55,0x55,0x01,0x2b,0x00,0x55,0x56,0x01,0x2c,0x00,0x55,0x57,0x01,0x2d, +0x00,0x55,0x52,0x01,0xc7,0x13,0xb6,0x13,0xb6,0x50,0x01,0xcf,0x22,0xbe,0x51,0x01, +0xc7,0x23,0xb6,0x4e,0x01,0xcf,0x20,0xbe,0x4f,0x01,0xc7,0x21,0xb6,0x4c,0x01,0xcf, +0x1e,0xbe,0x4d,0x01,0xc7,0x1f,0xb6,0x4a,0x01,0xcf,0x1c,0xbe,0x4b,0x01,0xc7,0x1d, +0xb6,0x48,0x01,0xcf,0x26,0xbe,0x49,0x01,0xc7,0x27,0xb6,0x46,0x01,0xcf,0x24,0xbe, +0x47,0x01,0xc7,0x25,0xb6,0x44,0x01,0xcf,0x18,0xbe,0x45,0x01,0xc7,0x19,0xb6,0x42, +0x01,0xcf,0x14,0xbe,0x43,0x01,0xc7,0x15,0xb6,0x40,0x01,0xcf,0x1a,0xbe,0x41,0x01, +0xc7,0x1b,0xb6,0x3e,0x01,0xcf,0x16,0xbe,0x3f,0x01,0xc7,0x17,0xb6,0x3d,0x01,0xc7, +0x28,0xb6,0x2b,0xd8,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,0xb5,0x01,0xc1,0x05,0x7b,0x0b, +0x26,0x04,0xe1,0x72,0xb6,0x01,0xc6,0x08,0x27,0xb5,0x01,0xc6,0xb7,0x26,0x50,0xfc, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x02,0xab,0x5b,0x11,0xfd,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,0x0b,0xc5,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,0xab,0x20,0x80,0xaa,0x17,0xb7,0x02,0x7b,0x84,0x84,0x0b,0xc5, +0xcd,0x74,0xae,0x20,0xa6,0x14,0x4b,0x88,0x07,0xab,0x01,0x7b,0xf0,0x25,0x05,0xa1, +0x03,0x6b,0x4c,0x9f,0x18,0xe7,0xb5,0x01,0xd6,0x03,0xee,0x72,0x03,0x6b,0x12,0x26, +0x4a,0x02,0x7b,0x84,0x84,0x0b,0xc5,0xcd,0x74,0xae,0x43,0xa6,0x88,0x02,0x7b,0x07, +0x4b,0x10,0x27,0x02,0x7b,0x01,0x6b,0x52,0x05,0xae,0x05,0x24,0x14,0xa1,0x02,0x6b, +0x7f,0xa4,0xb5,0x01,0xc6,0x81,0x85,0x85,0x85,0x4f,0x05,0xb6,0x01,0x07,0x72,0x05, +0x20,0x02,0xb5,0x01,0x0f,0x72,0x84,0x84,0x0b,0xc5,0xcd,0x74,0xae,0x41,0xa6,0x02, +0x4b,0x00,0x4b,0x19,0x26,0x60,0xa1,0x60,0xa4,0xb5,0x01,0xc6,0x84,0x84,0x0b,0xc5, +0xcd,0x74,0xae,0x40,0xa6,0x01,0x4b,0x00,0x4b,0x01,0x6b,0x64,0xa6,0x88,0x88,0x88, +0x81,0x96,0x01,0xc6,0x96,0x01,0x01,0x35,0x04,0xb5,0x01,0x0d,0x72,0x84,0x84,0x0b, +0xc5,0xcd,0x74,0xae,0x40,0xa6,0x01,0x4b,0x00,0x4b,0x96,0x01,0x5f,0x72,0x81,0x85, +0x9a,0xf9,0xfb,0xcd,0x14,0xae,0xa4,0x00,0x48,0x35,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7, +0x4f,0xa3,0x00,0x99,0x01,0x55,0x10,0x48,0x9a,0x01,0x55,0x11,0x48,0x9b,0x01,0x55, +0x12,0x48,0x9c,0x01,0x55,0x13,0x48,0x9d,0x01,0x55,0x9b,0xcd,0x25,0x05,0xa1,0x01, +0x6b,0x4c,0x01,0x7b,0xc5,0xfc,0xcd,0x9a,0xae,0xa4,0x00,0x01,0x35,0x96,0xfb,0xcd, +0x48,0x48,0x48,0x9f,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0xb5,0x01,0xd6, +0x01,0xee,0x72,0x1f,0x20,0x99,0x01,0xb9,0x01,0x55,0x07,0x26,0x04,0xa1,0x01,0x6b, +0x4f,0x84,0x84,0x9a,0x01,0x5f,0x72,0x9b,0x01,0x5f,0x72,0x9c,0x01,0x5f,0x72,0x9d, +0x01,0x5f,0x72,0x0b,0xc5,0xcd,0x74,0xae,0x4f,0x05,0x4b,0x00,0x4b,0x88,0x81,0x84, +0x8b,0x41,0x00,0xa9,0x41,0x08,0xab,0x5b,0x09,0x6b,0x01,0x6b,0x85,0x85,0xe6,0xc5, +0xcd,0x74,0xae,0x10,0xa6,0x00,0x4b,0x05,0x4b,0xb9,0x01,0xc7,0x05,0x7b,0x02,0x6b, +0xad,0x01,0xc6,0x03,0x6b,0xae,0x01,0xc6,0x04,0x6b,0xaf,0x01,0xc6,0x05,0x6b,0xb0, +0x01,0xc6,0xb8,0x01,0xc7,0x02,0x7b,0xb7,0x01,0xc7,0x03,0x7b,0xb6,0x01,0xc7,0x04, +0x7b,0xb5,0x01,0xc7,0x05,0x7b,0x02,0x6b,0xa9,0x01,0xc6,0x03,0x6b,0xaa,0x01,0xc6, +0x04,0x6b,0xab,0x01,0xc6,0x05,0x6b,0xac,0x01,0xc6,0x01,0x6b,0x85,0x85,0xe6,0xc5, +0xcd,0x74,0xae,0x18,0xa6,0x00,0x4b,0x08,0x4b,0xbc,0x01,0xc7,0x06,0x7b,0xbb,0x01, +0xc7,0x07,0x7b,0xba,0x01,0xc7,0x08,0x7b,0xb9,0x01,0xc7,0x09,0x7b,0x06,0x6b,0x1c, +0x48,0xc6,0x07,0x6b,0x1d,0x48,0xc6,0x08,0x6b,0x1e,0x48,0xc6,0x09,0x6b,0x1f,0x48, +0xc6,0xb8,0x01,0xc7,0x06,0x7b,0xb7,0x01,0xc7,0x07,0x7b,0xb6,0x01,0xc7,0x08,0x7b, +0xb5,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,0xb5,0x01, +0x44,0x72,0x02,0x6b,0x4c,0x02,0x7b,0x05,0x20,0x03,0x6b,0x4c,0x03,0x7b,0x07,0x26, +0x01,0xa4,0xb5,0x01,0xd6,0x05,0xee,0x72,0x04,0x6b,0x4f,0x05,0x6b,0x4f,0x44,0x20, +0x4f,0x03,0x27,0x85,0x85,0x4d,0x0b,0xc5,0xcd,0x74,0xae,0x05,0x4b,0x00,0x4b,0x9a, +0x14,0x48,0xad,0x01,0x55,0x15,0x48,0xae,0x01,0x55,0x16,0x48,0xaf,0x01,0x55,0x17, +0x48,0xb0,0x01,0x55,0x10,0x48,0xa9,0x01,0x55,0x11,0x48,0xaa,0x01,0x55,0x12,0x48, +0xab,0x01,0x55,0x13,0x48,0xac,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,0xf9,0xfb,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,0xf9,0xfb,0xcd,0x5f,0x38,0xad,0x04,0x7b,0x9b, +0x02,0x6b,0x32,0xa6,0x01,0x6b,0x03,0x6b,0x4f,0x88,0x88,0x88,0x88,0x81,0x11,0xfd, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x05,0xab,0x81,0x84,0x84,0x84,0x84,0x84,0x84,0x84, +0x84,0x9a,0xf9,0xfb,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,0xf9,0xfb,0xcd,0x5f,0xa4,0x00,0x40,0x35,0xcb,0xfc,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x01,0xab,0x5b,0xa3,0x14,0x4f,0xad,0x5b,0xf9,0xfb,0xcd,0xa4,0xb7,0x00, +0xa9,0x41,0x01,0xab,0x5b,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0x00,0x93,0x01, +0x55,0x9b,0x05,0x6b,0x00,0x40,0xc6,0x06,0x6b,0x01,0x40,0xc6,0x07,0x6b,0x02,0x40, +0xc6,0x08,0x6b,0x03,0x40,0xc6,0x9a,0xf9,0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35, +0xa3,0x1a,0xa3,0x19,0xf8,0xd0,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,0x11,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab, +0x81,0x84,0x84,0x84,0x84,0x9a,0xf9,0xfb,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,0xf9,0xfb,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,0xf9,0xfb,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,0xf9,0xfb,0xcd, +0x5f,0xa4,0x00,0x40,0x35,0xa3,0x15,0x11,0xfd,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,0xdc,0xfb,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,0xf9,0xfb,0xcd,0x30,0xae,0xa4,0x00, +0x42,0x35,0xcb,0xfc,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0x96,0xfb,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,0xa2,0xce,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,0x11,0xfd,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,0x71,0xcf,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,0x79, +0xcf,0xcd,0x10,0xee,0x72,0x11,0x7b,0x11,0xfd,0xcd,0x71,0xcf,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,0x65,0x18,0xcd,0x81,0x84,0x84,0x84,0x84,0x84,0xfc,0xcc,0xcd,0xac,0x25, +0x10,0xa1,0x04,0x6b,0x4c,0x04,0x7b,0xc2,0x25,0x08,0xa1,0x05,0x6b,0x4c,0x05,0x7b, +0x44,0xcd,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,0x69,0xcd,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,0x44,0xcd,0xcd,0xfc,0xcc,0xcd,0x26,0xcd,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,0xac,0xc6,0xcc,0x03,0xad,0xb2,0x84,0x00,0x35,0xb3,0x84,0x00,0x35,0xac, +0xc6,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,0xac,0xc6,0xcc,0x64,0xa6,0xb0, +0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x00,0x35,0xb3,0x84,0x00,0x35,0xac, +0xc6,0xcd,0x0a,0xa6,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x10,0x35, +0xb3,0x84,0x00,0x35,0x81,0x84,0x84,0x84,0x84,0xdd,0x01,0x01,0x35,0xf9,0xfb,0xcd, +0x5f,0xa4,0x00,0x84,0x35,0xa0,0x1a,0x11,0xfd,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,0xf9, +0xfb,0xcd,0x5f,0xa4,0x00,0x84,0x35,0xa0,0x1b,0x11,0xfd,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,0xf9,0xfb,0xcd, +0x78,0xae,0xa4,0x00,0x84,0x35,0x81,0x11,0xfd,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,0x18,0xfc,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,0xc5,0xfc,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,0x67,0x01,0xc6,0x22,0x25,0x02, +0xa1,0xbb,0x00,0xc6,0x29,0x26,0x4a,0x66,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,0x66,0x01,0xc6,0x0d,0x27,0x4a,0x67,0x01,0xc6,0xf9,0xfb,0xcd,0x78,0xae,0xa4, +0x00,0x84,0x35,0xa0,0x1c,0x11,0xfd,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,0x66,0x01,0xc6,0xf9,0xfb,0xcd,0xa4, +0xae,0xa4,0x00,0x84,0x35,0xa2,0x1e,0xa0,0x3f,0xa1,0x3f,0xa2,0x1f,0x4a,0xcc,0xcd, +0x14,0x26,0x03,0xa1,0x04,0x27,0x01,0xa1,0xbb,0x00,0xc6,0x1f,0x26,0x4a,0x66,0x01, +0xc6,0xf9,0xfb,0xcd,0xa0,0xae,0xa4,0x00,0x84,0x35,0xa0,0x1f,0xa2,0x3f,0xa3,0x3f, +0x96,0xfb,0xcd,0x10,0xa6,0x18,0xfc,0xcd,0x5c,0x01,0x24,0x02,0xab,0x4e,0x01,0xce, +0x4f,0x01,0xc6,0x0b,0x20,0xe0,0x01,0xce,0xe1,0x01,0xc6,0x2a,0x26,0x4a,0x0b,0x27, +0x02,0xa0,0x66,0x01,0xc6,0xe6,0x01,0x5f,0x72,0xc6,0xcb,0xcc,0x03,0x27,0x68,0x01, +0xc6,0x08,0x27,0x67,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,0xc5,0xfc,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x5b,0xa2,0x1e, +0x18,0xfc,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,0x66,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,0x67,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, +0xf9,0xfb,0xcd,0x78,0xae,0xa4,0x00,0x84,0x35,0xa0,0x1d,0x11,0xfd,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,0xe6,0x01,0xc7,0x5f,0x26,0x67, +0x01,0xce,0x64,0x26,0x68,0x01,0xc6,0x88,0x88,0x88,0x88,0x81,0x11,0xfd,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,0xf9, +0xfb,0xcd,0x5f,0xa4,0x00,0x40,0x35,0xa0,0x1e,0x23,0xad,0x5b,0xf9,0xfb,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,0x53,0x01,0xc6,0x04,0x6b,0x10,0xaa,0x04,0x7b,0x06,0x26,0x52, +0x01,0xc6,0x01,0x6b,0x02,0x6b,0x03,0x6b,0x4f,0x04,0x6b,0x01,0xa6,0xf9,0xfb,0xcd, +0xb4,0xae,0xa4,0x00,0x84,0x35,0xa3,0x18,0xa2,0x18,0x2a,0xca,0xcd,0x5b,0x01,0x6b, +0xb4,0x84,0xc6,0x02,0x6b,0xb5,0x84,0xc6,0x03,0x6b,0xb6,0x84,0xc6,0x04,0x6b,0xb7, +0x84,0xc6,0xac,0xc6,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,0x68,0x01,0x5f, +0x72,0xf9,0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa2,0x19,0x11,0xfd,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,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,0x38,0xfb,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, +0xf9,0xfb,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,0xfb,0xc8,0xcd,0x03,0x88,0x00,0x35,0xf9, +0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa2,0x1e,0xa0,0x1e,0x11,0xfd,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,0x08,0xc9,0xcd,0xaf,0x84, +0x20,0x35,0xf9,0xfb,0xcd,0x7c,0xae,0xa4,0x00,0x84,0x35,0xa0,0x14,0xa1,0x1a,0xa1, +0x10,0xdd,0xc8,0xcd,0x09,0x20,0xa1,0x1a,0xa1,0x10,0xdd,0xc8,0xcd,0x12,0x20,0xa1, +0x10,0xdd,0xc8,0xcd,0x19,0x20,0xdd,0xc8,0xcd,0x27,0x20,0x17,0x27,0x4a,0x11,0x27, +0x4a,0x0d,0x27,0x4a,0x0b,0x27,0x4a,0x05,0x7b,0x08,0xc9,0xcd,0xaf,0x84,0x00,0x35, +0x7c,0x84,0x00,0x35,0x7d,0x84,0x00,0x35,0x7e,0x84,0x00,0x35,0x7f,0x84,0x00,0x35, +0xfb,0xc8,0xcd,0x03,0x88,0x00,0x35,0x5e,0xc7,0xcd,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,0xaf,0xad,0x66,0x01,0x5f,0x72,0xdb,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,0xf9,0xfb,0xcd,0xb4,0xae,0xa4,0x00,0x84,0x35,0xa1,0x1c,0x11, +0xfd,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,0x11,0xfd,0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x03,0xab,0xf9,0xfb,0xcc, +0x5f,0xa4,0x00,0x84,0x35,0xa0,0x00,0x30,0x35,0x0c,0xad,0x5b,0xf9,0xfb,0xcd,0x5f, +0xa4,0x00,0x84,0x35,0xa0,0x1a,0xa0,0x3f,0x1b,0xad,0x5b,0x81,0xa0,0x3f,0x11,0xfd, +0xcd,0xa4,0xb7,0x00,0xa9,0x41,0x03,0xab,0xf9,0xfb,0xcc,0x5f,0xa4,0x00,0x84,0x35, +0xa0,0x18,0x0a,0xad,0x5b,0xf9,0xfb,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,0x6d,0xfb,0xcd,0x03,0xae,0x90,0xa7, +0x3f,0x5f,0x88,0x88,0x81,0x41,0x20,0x40,0x35,0x48,0x20,0x5f,0x72,0x46,0x20,0x5f, +0x72,0x45,0x20,0x01,0x35,0x81,0x9a,0xcf,0x01,0xcf,0xd0,0x01,0xc7,0x9b,0x81,0x4f, +0x13,0xb7,0x53,0x20,0xc6,0x50,0x20,0x12,0x72,0x81,0x01,0xa6,0x03,0x27,0x4d,0x92, +0xc4,0xcd,0x88,0xa6,0x12,0xb7,0x53,0x20,0xc6,0x50,0x20,0x15,0x72,0x81,0x01,0xa6, +0x03,0x27,0x4d,0x92,0xc4,0xcd,0x88,0xa6,0x81,0x01,0xa6,0x03,0x27,0x4d,0xef,0xc4, +0xcd,0x41,0xa6,0x81,0x01,0xa6,0x03,0x27,0x4d,0xda,0xc4,0xcd,0xaa,0x00,0x5f,0x72, +0x50,0x20,0x20,0x35,0x52,0x20,0x09,0x35,0x81,0x4d,0x92,0xc4,0xcd,0x88,0xa6,0x50, +0x20,0x20,0x35,0x53,0x20,0xc7,0xcb,0x20,0x4f,0x50,0x20,0x12,0x72,0xec,0x25,0x07, +0xe1,0x72,0x01,0x6b,0x4c,0x01,0x7b,0xda,0x26,0x13,0xad,0xb5,0x01,0xd6,0x01,0xee, +0x72,0x0d,0x20,0x4f,0xac,0xc6,0xcd,0x05,0xa6,0xec,0x26,0x25,0xad,0x03,0x7b,0xf2, +0x26,0x4d,0x92,0xc4,0xcd,0x88,0xa6,0x81,0x85,0x85,0x85,0x01,0xa6,0x06,0x27,0x4d, +0xef,0xc4,0xcd,0x02,0x7b,0x08,0x26,0x4d,0xda,0xc4,0xcd,0xaa,0x00,0x5f,0x72,0x50, +0x20,0x20,0x35,0x52,0x20,0x09,0x35,0x88,0x89,0x88,0x81,0x4d,0x92,0xc4,0xcd,0x88, +0xa6,0x2b,0xc5,0xcc,0x4f,0xac,0xc6,0xcd,0x05,0xa6,0x95,0x25,0x06,0xe1,0x72,0x01, +0x7b,0xb5,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,0xac,0xc6,0xcd,0x05, +0xa6,0xda,0x26,0xdf,0xc5,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,0xdf,0xc5, +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,0xac,0xc6,0xcd,0x05,0xa6, +0x81,0x01,0xa6,0x03,0x27,0x4d,0xb7,0xad,0x82,0xa6,0x50,0x20,0x21,0x35,0x53,0x20, +0xc7,0x81,0x4f,0xac,0xc6,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,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,0xbe,0x00,0xc6,0x20,0x40,0x00,0x35,0x21,0x40,0x00,0x35,0x22, +0x40,0x00,0x35,0x23,0x40,0x01,0x35,0x04,0x44,0xc0,0x00,0x55,0x05,0x44,0xc1,0x00, +0x55,0x06,0x44,0xc2,0x00,0x55,0x07,0x44,0xc3,0x00,0x55,0x00,0x44,0xc4,0x00,0x55, +0x01,0x44,0xc5,0x00,0x55,0x02,0x44,0xc6,0x00,0x55,0x03,0x44,0xc7,0x00,0x55,0x81, +0xdc,0xfb,0xcd,0xa0,0x3f,0xa1,0x3f,0xa2,0x3f,0x81,0xdc,0xfb,0xcd,0xa4,0xb7,0x01, +0xaa,0x41,0x81,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x81,0xa4,0xc6,0x92, +0xa5,0xbf,0xa4,0xb7,0x81,0x1c,0xad,0xa3,0x3f,0xa4,0xb7,0x01,0xaa,0x81,0x84,0x84, +0x84,0xdf,0x26,0x03,0xe1,0x72,0x12,0xad,0x02,0xaa,0x41,0x03,0xaa,0x01,0xee,0x72, +0x02,0x7b,0xdc,0xfb,0xcd,0xa4,0xb7,0x02,0xaa,0x01,0x7b,0x02,0xee,0x72,0x32,0xad, +0x03,0x7b,0x10,0x20,0x03,0x6b,0x03,0xa6,0x02,0x20,0x83,0xa6,0x04,0x26,0x02,0xa1, +0x11,0xb6,0x59,0xad,0xa3,0x00,0x3d,0x35,0x02,0xee,0x72,0xa4,0xb7,0x01,0x7b,0x66, +0xad,0xa3,0x00,0x08,0x35,0xa4,0xb7,0x02,0xaa,0x41,0x24,0xaa,0x01,0xee,0x72,0x02, +0x7b,0x54,0xad,0x41,0x1c,0xaa,0x01,0xee,0x72,0x02,0x7b,0x5e,0xad,0x41,0x18,0xaa, +0x01,0xee,0x72,0x02,0x7b,0x68,0xad,0x41,0x14,0xaa,0x01,0xee,0x72,0x02,0x7b,0xdf, +0x26,0x03,0xe1,0x72,0xfc,0xc3,0xcd,0x01,0xaa,0x41,0x13,0xaa,0x01,0xee,0x72,0x02, +0x7b,0x0e,0xc4,0xcd,0x10,0xaa,0x01,0xee,0x72,0x02,0x7b,0x04,0xc4,0xcd,0x03,0x7b, +0x0f,0x20,0x03,0x6b,0xcf,0xa6,0x02,0x20,0x0f,0xa6,0x06,0x20,0x0c,0xa6,0x08,0x20, +0x06,0x27,0x4a,0x05,0x27,0x14,0xb6,0xda,0x26,0x03,0xe1,0x72,0xfc,0xc3,0xcd,0x01, +0xaa,0x41,0x0d,0xaa,0x01,0xee,0x72,0x02,0x7b,0x0e,0xc4,0xcd,0x0c,0xaa,0x01,0xee, +0x72,0x02,0x7b,0x96,0xfb,0xcd,0x10,0xa6,0x04,0xc4,0xcd,0x03,0x7b,0x14,0x20,0x03, +0x6b,0xfc,0xa6,0x02,0x20,0xf0,0xa6,0x06,0x20,0xcc,0xa6,0x0a,0x20,0xc0,0xa6,0x0e, +0x20,0x0c,0xa6,0x12,0x20,0x0f,0xa6,0x04,0x20,0x16,0x27,0x4a,0x15,0x27,0x4a,0x14, +0x27,0x4a,0x13,0x27,0x4a,0x12,0x27,0x4a,0x27,0x27,0x4a,0x14,0x27,0x13,0xb6,0xd1, +0x26,0x03,0xe1,0x72,0xfc,0xc3,0xcd,0x01,0xaa,0x41,0x0b,0xaa,0x01,0xee,0x72,0x02, +0x7b,0x0e,0xc4,0xcd,0x08,0xaa,0x01,0xee,0x72,0x02,0x7b,0xa0,0xb7,0x03,0xaa,0xa0, +0xb6,0xa1,0xb7,0xc3,0xaa,0xa0,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x03,0x7b,0x1d,0x20, +0x03,0x6b,0x4f,0x01,0x20,0x0c,0xa6,0x04,0x27,0x15,0x3d,0xf3,0xc3,0xcd,0x41,0x04, +0xaa,0x01,0xee,0x72,0x02,0x7b,0xf3,0xc3,0xcd,0x01,0x6b,0x02,0xef,0x72,0x50,0xaa, +0x41,0x4f,0x58,0x58,0x97,0x88,0x88,0x88,0x81,0x11,0xfd,0xcd,0xc4,0xae,0xa4,0x00, +0x00,0x35,0x81,0xa0,0xb7,0xa1,0xb7,0xa2,0xb7,0x4f,0xa3,0xb7,0x81,0x4d,0x5f,0x12, +0xb6,0x81,0xa4,0xb7,0x00,0xa9,0x41,0x01,0xab,0x81,0xa0,0xb7,0x03,0xa4,0xa0,0xb6, +0xa1,0x3f,0xa2,0x3f,0xa3,0x3f,0x96,0xfb,0xcd,0x18,0xa6,0x84,0xfb,0xcd,0x4a,0x81, +0xa4,0xb7,0x00,0xa9,0x41,0x07,0xab,0x81,0xc4,0x00,0x00,0x35,0xc5,0x00,0x00,0x35, +0xc6,0x00,0x18,0x35,0x81,0xa0,0x3f,0xa1,0xb7,0x3e,0xa4,0xa1,0xb6,0xa2,0x3f,0xa3, +0x3f,0x96,0xfb,0xcd,0x11,0xa6,0x4a,0xad,0x81,0x4d,0xad,0x18,0xa4,0x48,0x48,0x48, +0x4a,0x12,0xb6,0xf9,0xfb,0xcd,0x4d,0xad,0x81,0x8b,0x41,0x00,0xa9,0x41,0x0a,0xab, +0x5b,0xf9,0xfb,0xcd,0x0c,0xae,0xa4,0x00,0x84,0x35,0xa3,0x36,0xa2,0x36,0xa1,0x36, +0xa0,0x34,0x8e,0xc2,0xcd,0x0b,0x20,0xa0,0x39,0xa1,0x39,0xa2,0x39,0xa3,0x38,0x8e, +0xc2,0xcd,0x0d,0x26,0x02,0xa1,0x11,0xb6,0x84,0x84,0x84,0x84,0x84,0x40,0xe1,0xcd, +0x88,0x0b,0x7b,0x88,0x0b,0x7b,0x88,0x0b,0x7b,0x88,0x0b,0x7b,0x88,0x06,0x7b,0x06, +0x6b,0x44,0x44,0x06,0x7b,0xa6,0xfc,0xcd,0x02,0xa6,0x59,0xc2,0xcd,0x5b,0x0f,0x26, +0x02,0xa1,0x11,0xb6,0x06,0x6b,0x08,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0xbb,0xa6,0x09, +0x6b,0x80,0xa6,0x0a,0x6b,0xc4,0x00,0x00,0x35,0xc5,0x00,0x00,0x35,0xc6,0x00,0x60, +0x35,0xc7,0x00,0x00,0x35,0x18,0x20,0xac,0xa6,0x09,0x6b,0x44,0xa6,0x0a,0x6b,0xc4, +0x00,0x00,0x35,0xc5,0x00,0x00,0x35,0xc6,0x00,0x62,0x35,0xc7,0x00,0x00,0x35,0x39, +0x20,0x10,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x5d,0xa6,0x09,0x6b,0xc0,0xa6,0x0a,0x6b, +0xc4,0x00,0x00,0x35,0xc5,0x00,0x00,0x35,0xc6,0x00,0x30,0x35,0xc7,0x00,0x00,0x35, +0x18,0x20,0x56,0xa6,0x09,0x6b,0x22,0xa6,0x0a,0x6b,0xc4,0x00,0x00,0x35,0xc5,0x00, +0x00,0x35,0xc6,0x00,0x31,0x35,0xc7,0x00,0x00,0x35,0x74,0x20,0x20,0xa6,0x07,0x6b, +0x4f,0x08,0x6b,0x2e,0xa6,0x09,0x6b,0xe0,0xa6,0x0a,0x6b,0x4c,0xc2,0xcd,0xc7,0x00, +0x00,0x35,0xca,0xc1,0xcc,0x20,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x2b,0xa6,0x09,0x6b, +0x11,0xa6,0x0a,0x6b,0x4c,0xc2,0xcd,0xc7,0x00,0x80,0x35,0xca,0xc1,0xcc,0x20,0xa6, +0x07,0x6b,0x4f,0x08,0x6b,0x1f,0xa6,0x09,0x6b,0x40,0xa6,0x0a,0x6b,0xc4,0x00,0x00, +0x35,0xc5,0x00,0x00,0x35,0xc6,0x00,0x10,0x35,0xc7,0x00,0x00,0x35,0xca,0xc1,0xcc, +0x20,0xa6,0x07,0x6b,0x4f,0x08,0x6b,0x2e,0xa6,0x09,0x6b,0xe0,0xa6,0x0a,0x6b,0x4f, +0x4c,0xc2,0xcd,0xc7,0x00,0x00,0x35,0xab,0xc1,0xcc,0x03,0x26,0x4a,0x91,0xc1,0xcc, +0x03,0x26,0x4a,0x70,0xc1,0xcc,0x03,0x26,0x4a,0x56,0xc1,0xcc,0x03,0x26,0x4a,0x6d, +0x27,0x4a,0x57,0x27,0x4a,0x38,0x27,0x13,0xb6,0xf9,0xfb,0xcd,0xa4,0xbf,0x84,0xae, +0xa3,0x1a,0x11,0xfd,0xcd,0x59,0xc2,0xcd,0x5b,0xc5,0xfc,0xcd,0x59,0xc2,0xcd,0x5b, +0xcb,0xfc,0xcd,0x77,0xc2,0xcd,0x5b,0x28,0xc2,0xcd,0x5b,0x61,0xc2,0xcd,0x5a,0x01, +0x26,0x7f,0xc2,0xcd,0x14,0x20,0xa3,0x10,0xcb,0xfc,0xcd,0x77,0xc2,0xcd,0x5b,0x28, +0xc2,0xcd,0x5b,0x61,0xc2,0xcd,0x5a,0x01,0x26,0x7f,0xc2,0xcd,0x18,0x26,0x4a,0x11, +0xb6,0x38,0x20,0x08,0x6b,0x40,0xaa,0x08,0x7b,0x0a,0x6b,0x02,0xaa,0x0a,0x7b,0x0e, +0x26,0x02,0xa1,0x11,0xb6,0x36,0x20,0x39,0x26,0x7f,0xc2,0xcd,0x25,0x20,0x28,0x26, +0x7f,0xc2,0xcd,0x07,0x26,0x4a,0x11,0xb6,0x19,0x27,0x02,0xa1,0x11,0xb6,0x0a,0x6b, +0x04,0xaa,0x0a,0x7b,0x1f,0x27,0x16,0x3d,0xf9,0xfb,0xcd,0x59,0xc2,0xcd,0x5b,0xa2, +0x1e,0x38,0xc2,0xcd,0x05,0x7b,0x05,0x20,0xa0,0x14,0x38,0xc2,0xcd,0x05,0x7b,0x09, +0x27,0xda,0x01,0xc6,0xbe,0x00,0xc7,0x12,0xb6,0x02,0x20,0x04,0xa6,0x04,0x26,0x02, +0xa1,0x11,0xb6,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x20,0x8f,0xe3, +0x26,0x01,0x7b,0xf8,0xf1,0xcd,0x03,0x26,0xcf,0x01,0xca,0xd0,0x01,0xc6,0x1e,0xf1, +0xcd,0x03,0x24,0x20,0xa1,0x12,0x27,0x01,0x6b,0x28,0x18,0xcd,0x79,0x18,0xcd,0x88, +0x81,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,0x9b,0xc6,0xcd,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x84,0x8f,0xdf, +0xcd,0x62,0x01,0x3b,0x63,0x01,0x3b,0x64,0x01,0x3b,0x65,0x01,0x3b,0x01,0x4b,0x80, +0x4b,0x85,0x4b,0x80,0x4b,0xb0,0x84,0x00,0x35,0xb1,0x84,0x00,0x35,0xb2,0x84,0x00, +0x35,0xb3,0x84,0x15,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,0xa5,0xc7,0xcd,0x15,0xc9,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,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,0x3e,0x20,0x20,0x35,0x62,0x01,0x02, +0x35,0x63,0x01,0x49,0x35,0x64,0x01,0xf0,0x35,0x65,0x01,0xc7,0x0f,0x20,0x62,0x01, +0x01,0x35,0x63,0x01,0x9b,0x35,0x64,0x01,0xfc,0x35,0x65,0x01,0xc0,0x35,0x0c,0x20, +0x63,0x01,0x8c,0x35,0x64,0x01,0xba,0x35,0x65,0x01,0x80,0x35,0x1a,0x20,0x63,0x01, +0x24,0x35,0x64,0x01,0xf8,0x35,0x65,0x01,0xc7,0x3c,0x20,0x62,0x01,0x5f,0x72,0x63, +0x01,0x5f,0x72,0x64,0x01,0x5f,0x72,0x65,0x01,0x5f,0x72,0x3f,0x27,0x4a,0x30,0x27, +0x4a,0x25,0x27,0x4a,0x1b,0x27,0x0f,0xa4,0x08,0x20,0xc6,0xe7,0x01,0xc7,0x0f,0xa4, +0x4e,0x03,0x20,0xc6,0xf2,0x25,0x10,0xa1,0x01,0x6b,0x4c,0xbf,0x01,0x4f,0x72,0x01, +0xee,0x72,0x01,0x6b,0x4f,0xc8,0x00,0x5f,0x72,0xc9,0x00,0x5f,0x72,0xda,0x01,0x5f, +0x72,0xbb,0x00,0x5f,0x72,0xbd,0x00,0x5f,0x72,0xbc,0x00,0x5f,0x72,0xd0,0x01,0x5f, +0x72,0xcf,0x01,0x5f,0x72,0x91,0x01,0x0a,0x35,0x94,0x01,0x5f,0x72,0x95,0x01,0x5f, +0x72,0x9f,0x01,0x5f,0x72,0x96,0x01,0x5f,0x72,0x97,0x01,0x5f,0x72,0x98,0x01,0x5f, +0x72,0x7c,0x01,0x5f,0x72,0xdf,0x01,0x5f,0x72,0xe2,0x01,0x5f,0x72,0x67,0x01,0x5f, +0x72,0x68,0x01,0x5f,0x72,0xaa,0x00,0x5f,0x72,0x6a,0x01,0x5f,0x72,0x7d,0x01,0x5f, +0x72,0x6b,0x01,0x5f,0x72,0xbe,0x00,0x5f,0x72,0xbf,0x00,0x5f,0x72,0x66,0x01,0x5f, +0x72,0x11,0x3f,0x10,0x3f,0x69,0x01,0x5f,0x72,0xbd,0x01,0x5f,0x72,0xbe,0x01,0x5f, +0x72,0xe3,0x01,0x5f,0x72,0xe4,0x01,0xff,0x35,0xe6,0x01,0x5f,0x72,0xde,0x01,0x5f, +0x72,0x9b,0x06,0x20,0x5f,0x72,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,0xb0,0x1a,0xcc,0x8b,0xff,0xa6,0x04,0xae,0x81,0x85, +0x01,0x7b,0x9a,0xbd,0x01,0xc7,0x0f,0xa4,0xbd,0x01,0xc6,0xbf,0x01,0x4f,0x72,0xbd, +0x01,0x5c,0x72,0x01,0x6b,0xbf,0x01,0xd6,0xbd,0x01,0xce,0x18,0x27,0xbd,0x01,0xc1, +0xbe,0x01,0xc6,0x9b,0x01,0x6b,0x4f,0x88,0x81,0x84,0x9a,0xbe,0x01,0xc7,0x0f,0xa4, +0xbe,0x01,0xc6,0xbf,0x01,0xd7,0xbe,0x01,0x5c,0x72,0xbe,0x01,0xce,0x01,0x7b,0x14, +0x27,0x01,0xe1,0x72,0xbf,0x01,0xd6,0x97,0x0f,0xa4,0x4a,0xbe,0x01,0xc6,0x9b,0x88, +}; + diff --git a/drivers/video/av8100/hdmi.c b/drivers/video/av8100/hdmi.c index cb6d1077876..14b15dedbf2 100644..100755 --- a/drivers/video/av8100/hdmi.c +++ b/drivers/video/av8100/hdmi.c @@ -11,76 +11,1653 @@ #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/hdmi.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" -static int hdmi_open(struct inode *inode, struct file *filp) +#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_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 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_IWUSR, NULL, 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); + +/* Hex to int conversion */ +static unsigned int htoi(const char *ptr) { - int retval = 0; + 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) +{ + dev_dbg(hdmidev, "enable_event %d %02x\n", enable, ev); + if (enable) + 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; + } + + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_IDLE) { + av8100_disable_interrupt(); + av8100_enable_interrupt(); + } + + 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; + } + } + + if (data_len < 1) + 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 - 1); + + 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 = 1; + + 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) { + if ((crc == buf[0]) && (buf[1] == 1)) + /* OK */ + *result = 0; + } + + return 0; +} + +static int hdcploadaes(u8 block, u8 key_len, u8 *key, u8 *result) +{ + union av8100_configuration config; + struct av8100_status status; + + /* Default not OK */ + *result = 1; + + 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, + NULL, NULL, I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); + return -EINVAL; + } + + *result = 0; + + return 0; +} + +static int hdcpauthencr(u8 auth_type, u8 encr_type) +{ + 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_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, + NULL, NULL, 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; + + 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) + *(buf + index++) = '\0'; + + 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); + + 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); + } 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) + *(buf + index++) = '\0'; + + 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 status; + int index = 0; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + if (hdcpchkaesotp(&crc, &status)) + return -EINVAL; + + if (hdmi_driver_data->store_as_hextext) { + snprintf(buf + index, 3, "%02x", status); + index += 2; + } else { + *(buf + index++) = status; + } + + dev_dbg(hdmidev, "status:%02x\n", status); + + if (hdmi_driver_data->store_as_hextext) + *(buf + index++) = '\0'; + + 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); + + 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; + } 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; + + 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) + *(buf + index++) = '\0'; + + 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; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + /* Default not OK */ + hdmi_driver_data->loadaes_result = 1; + + if (hdmi_driver_data->store_as_hextext) { + if ((count != HDMI_HDCP_LOADAES_TEXT_SIZE) && + (count != HDMI_HDCP_LOADAES_TEXT_SIZE + 1)) + 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)) + return -EINVAL; + if (hdcp_loadaes.result) + return -EINVAL; + + 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)) + return -EINVAL; + + if (hdcp_loadaes.result) + return -EINVAL; + } else { + if (count != HDMI_HDCP_LOADAES_BIN_SIZE) + 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)) + return -EINVAL; + + if (hdcp_loadaes.result) + return -EINVAL; + } + + /* 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)) + return -EINVAL; + + if (hdcp_loadaes.result) + return -EINVAL; + } + + 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, "status:%02x\n", hdmi_driver_data->loadaes_result); + + if (hdmi_driver_data->store_as_hextext) + *(buf + index++) = '\0'; + + 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; + + dev_dbg(hdmidev, "%s\n", __func__); + + hdmi_driver_data = dev_get_drvdata(dev); + + 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)) + return -EINVAL; + + return count; +} + +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, &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) + *(buf + index++) = '\0'; + + 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 & 0xFF); + index += 2; + } else + *(buf + index++) = ev & 0xFF; + + if (hdmi_driver_data->store_as_hextext) + *(buf + index++) = '\0'; + + /* 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 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) { - int retval = 0; - return retval; + if (device_open) + device_open--; + + return 0; } +/* ioctl */ static int hdmi_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { - int retval = 0; - int value = 0; + 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); + 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; + + /* 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)) + return -EINVAL; + + if (hdcp_loadaesone.result) + return -EINVAL; + } + + /* 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)) + return -EINVAL; + + if (hdcp_loadaesone.result) + return -EINVAL; + + 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; + + if (hdcpauthencr(hdcp_authencr.auth_type, + hdcp_authencr.encr_type)) + return -EINVAL; + break; + + case IOC_HDCP_STATE_GET: + if (av8100_reg_gen_status_r(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; + + /* Internal */ case IOC_HDMI_POWER: /* Get desired power state on or off */ - if (copy_from_user(&value, (void *)arg, sizeof(int))) + if (copy_from_user(&value, (void *)arg, sizeof(u8))) return -EINVAL; if (value == 0) { - if (av8100_powerdown() != AV8100_OK) { - printk(KERN_ERR "av8100_powerdown FAIL\n"); + if (av8100_powerdown() != 0) { + dev_err(hdmidev, "av8100_powerdown FAIL\n"); return -EINVAL; } } else { - if (av8100_powerup() != AV8100_OK) { - printk(KERN_ERR "av8100_powerup FAIL\n"); + if (av8100_powerup() != 0) { + dev_err(hdmidev, "av8100_powerup FAIL\n"); return -EINVAL; } } break; case IOC_HDMI_ENABLE_INTERRUPTS: - if (av8100_enable_interrupt() != AV8100_OK) { - printk(KERN_ERR "av8100_configuration_get FAIL\n"); + 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) != - AV8100_OK) { - printk(KERN_ERR "av8100_configuration_get FAIL\n"); + 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(int))) + if (copy_from_user(&value, (void *)arg, sizeof(u8))) return -EFAULT; - if (av8100_configuration_get(AV8100_COMMAND_HDMI, &config) != - AV8100_OK) { - printk(KERN_ERR "av8100_configuration_get FAIL\n"); + if (av8100_conf_get(AV8100_COMMAND_HDMI, &config) != 0) { + dev_err(hdmidev, "av8100_conf_get FAIL\n"); return -EINVAL; } if (value == 0) @@ -88,14 +1665,13 @@ static int hdmi_ioctl(struct inode *inode, struct file *file, else config.hdmi_format.hdmi_mode = AV8100_HDMI_ON; - if (av8100_configuration_prepare(AV8100_COMMAND_HDMI, &config) - != AV8100_OK) { - printk(KERN_ERR "av8100_configuration_prepare FAIL\n"); + if (av8100_conf_prep(AV8100_COMMAND_HDMI, &config) != 0) { + dev_err(hdmidev, "av8100_conf_prep FAIL\n"); return -EINVAL; } - if (av8100_configuration_write(AV8100_COMMAND_HDMI, NULL, NULL, - I2C_INTERFACE) != AV8100_OK) { - printk(KERN_ERR "av8100_configuration_write FAIL\n"); + if (av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL, + I2C_INTERFACE) != 0) { + dev_err(hdmidev, "av8100_conf_w FAIL\n"); return -EINVAL; } break; @@ -106,9 +1682,8 @@ static int hdmi_ioctl(struct inode *inode, struct file *file, return -EINVAL; } - if (av8100_register_write(reg.offset, reg.value) != - AV8100_OK) { - printk(KERN_ERR "hdmi_register_write FAIL\n"); + if (av8100_reg_w(reg.offset, reg.value) != 0) { + dev_err(hdmidev, "hdmi_register_write FAIL\n"); return -EINVAL; } break; @@ -119,9 +1694,8 @@ static int hdmi_ioctl(struct inode *inode, struct file *file, return -EINVAL; } - if (av8100_register_read(reg.offset, ®.value) != - AV8100_OK) { - printk(KERN_ERR "hdmi_register_write FAIL\n"); + if (av8100_reg_r(reg.offset, ®.value) != 0) { + dev_err(hdmidev, "hdmi_register_write FAIL\n"); return -EINVAL; } @@ -143,18 +1717,18 @@ static int hdmi_ioctl(struct inode *inode, struct file *file, case IOC_HDMI_CONFIGURATION_WRITE: if (copy_from_user(&command_reg, (void *)arg, sizeof(struct hdmi_command_register)) != 0) { - printk(KERN_ERR "IOC_HDMI_CONFIGURATION_WRITE fail 1\n"); - command_reg.return_status = - HDMI_COMMAND_RETURN_STATUS_FAIL; + dev_err(hdmidev, "IOC_HDMI_CONFIGURATION_WRITE " + "fail 1\n"); + command_reg.return_status = EINVAL; } else { - if (av8100_configuration_write_raw(command_reg.cmd_id, + if (av8100_conf_w_raw(command_reg.cmd_id, command_reg.buf_len, command_reg.buf, &(command_reg.buf_len), - command_reg.buf) != AV8100_OK) { - printk(KERN_ERR "IOC_HDMI_CONFIGURATION_WRITE fail 1\n"); - command_reg.return_status = - HDMI_COMMAND_RETURN_STATUS_FAIL; + command_reg.buf) != 0) { + dev_err(hdmidev, "IOC_HDMI_CONFIGURATION_WRITE " + "fail 2\n"); + command_reg.return_status = EINVAL; } } @@ -168,28 +1742,183 @@ static int hdmi_ioctl(struct inode *inode, struct file *file, break; } - return retval; + 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 = hdmi_ioctl + .ioctl = hdmi_ioctl, + .poll = hdmi_poll }; static struct miscdevice hdmi_miscdev = { - HDMI_DRIVER_MINOR_NUMBER, + 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; + + 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); + } +} + int __init hdmi_init(void) { - return misc_register(&hdmi_miscdev); + 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; + + hdmidev->driver_data = + kzalloc(sizeof(struct hdmi_driver_data), GFP_KERNEL); + + if (!hdmidev->driver_data) + return -ENOMEM; + + hdmi_driver_data = dev_get_drvdata(hdmidev); + + /* 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"); + + /* Register event callback */ + av8100_hdmi_event_cb_set(hdmi_event); + +hdmi_init_out: + return ret; } void hdmi_exit(void) { + /* 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); + + kfree(hdmidev->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 100755 index 00000000000..8cd83f874bd --- /dev/null +++ b/drivers/video/av8100/hdmi_loc.h @@ -0,0 +1,57 @@ +/* + * 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 + +struct edid_data { + u8 buf_len; + u8 buf[EDID_BUF_LEN]; +}; + +struct hdmi_register { + unsigned char value; + unsigned char offset; +}; + +struct hdcp_loadaesone { + u8 key[16]; + u8 result; +}; + +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; + bool loadaes_result; +}; + +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_POWER _IOWR(HDMI_IOC_MAGIC, 31, int) +#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__ */ diff --git a/drivers/video/mcde/display-av8100.c b/drivers/video/mcde/display-av8100.c index 139c36f4d78..6de32c3ddf3 100755 --- a/drivers/video/mcde/display-av8100.c +++ b/drivers/video/mcde/display-av8100.c @@ -17,8 +17,8 @@ #include <video/mcde_display.h> #include <video/mcde_display-av8100.h> -#include <video/hdmi.h> #include <video/av8100.h> +#include <video/hdmi.h> static int hdmi_try_video_mode( struct mcde_display_device *ddev, struct mcde_video_mode *video_mode); @@ -139,6 +139,7 @@ static int hdmi_try_video_mode( if (found_index != -1) { res = 0; + memset(video_mode, 0, sizeof(struct mcde_video_mode)); memcpy(video_mode, &video_modes_supp[found_index], sizeof(struct mcde_video_mode)); @@ -165,7 +166,8 @@ static int hdmi_set_video_mode( int ret = -EINVAL; bool update = 0; union av8100_configuration av8100_config; - struct mcde_display_hdmi_platform_data *pdata; + struct mcde_display_hdmi_platform_data *pdata = dev->dev.platform_data; + struct av8100_status status; /* TODO check video_mode_params */ if (dev == NULL || video_mode == NULL) { @@ -173,8 +175,6 @@ static int hdmi_set_video_mode( goto out; } - pdata = dev->dev.platform_data; - dev_vdbg(&dev->dev, "%s:\n", __func__); dev_vdbg(&dev->dev, "%s:xres:%d yres:%d hbp:%d hfp:%d vbp1:%d vfp1:%d " "vbp2:%d vfp2:%d interlaced:%d\n", __func__, @@ -194,49 +194,56 @@ static int hdmi_set_video_mode( if (dev->port->pixel_format == MCDE_PORTPIXFMT_DSI_YCBCR422) mcde_chnl_set_col_convert(dev->chnl_state, &pdata->rgb_2_yCbCr_convert); - ret = mcde_chnl_set_video_mode(dev->chnl_state, &dev->video_mode); if (ret < 0) { dev_warn(&dev->dev, "Failed to set video mode\n"); goto out; } - /* Disable interrupts */ - ret = av8100_disable_interrupt(); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_disable_interrupt failed\n", + /* TODO: We shouldn't need to shutdown */ + status = av8100_status_get(); + if (status.av8100_state >= AV8100_OPMODE_STANDBY) { + /* Disable interrupts */ + ret = av8100_disable_interrupt(); + if (ret != AV8100_OK) { + dev_err(&dev->dev, + "%s:av8100_disable_interrupt failed\n", __func__); - goto out; - } + goto out; + } - /* TODO: We shouldn't need to shutdown */ - ret = av8100_powerdown(); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "av8100_powerdown failed\n"); - goto out; - } - /* TODO: What delay is needed here */ - msleep(10); + ret = av8100_powerdown(); + if (ret != AV8100_OK) { + dev_err(&dev->dev, "av8100_powerdown failed\n"); + goto out; + } - ret = av8100_powerup(); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "av8100_powerup failed\n"); - goto out; + /* TODO: What delay is needed here */ + msleep(10); } - ret = av8100_download_firmware(NULL, 0, I2C_INTERFACE); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "av8100_download_firmware failed\n"); - goto out; + status = av8100_status_get(); + if (status.av8100_state < AV8100_OPMODE_STANDBY) { + ret = av8100_powerup(); + if (ret != AV8100_OK) { + dev_err(&dev->dev, "av8100_powerup failed\n"); + goto out; + } + + ret = av8100_download_firmware(NULL, 0, I2C_INTERFACE); + if (ret != AV8100_OK) { + dev_err(&dev->dev, "av8100_download_firmware failed\n"); + goto out; + } } /* Get current av8100 video output format */ - ret = av8100_configuration_get(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, + ret = av8100_conf_get(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_get " - "AV8100_COMMAND_VIDEO_OUTPUT_FORMAT failed\n", - __func__); + dev_err(&dev->dev, "%s:av8100_conf_get " + "AV8100_COMMAND_VIDEO_OUTPUT_FORMAT failed\n", + __func__); goto out; } @@ -260,27 +267,26 @@ static int hdmi_set_video_mode( if (AV8100_VIDEO_OUTPUT_CEA_VESA_MAX == av8100_config.video_output_format.video_output_cea_vesa) { dev_err(&dev->dev, "%s:video output format not found " - "\n", __func__); + "\n", __func__); goto out; } - ret = av8100_configuration_prepare(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, + ret = av8100_conf_prep(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, - "%s:av8100_configuration_prepare " - "AV8100_COMMAND_VIDEO_OUTPUT_FORMAT failed\n", - __func__); + dev_err(&dev->dev, "%s:av8100_conf_prep " + "AV8100_COMMAND_VIDEO_OUTPUT_FORMAT failed\n", + __func__); goto out; } /* Get current av8100 video input format */ - ret = av8100_configuration_get(AV8100_COMMAND_VIDEO_INPUT_FORMAT, + ret = av8100_conf_get(AV8100_COMMAND_VIDEO_INPUT_FORMAT, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_get " - "AV8100_COMMAND_VIDEO_INPUT_FORMAT failed\n", - __func__); + dev_err(&dev->dev, "%s:av8100_conf_get " + "AV8100_COMMAND_VIDEO_INPUT_FORMAT failed\n", + __func__); goto out; } @@ -305,26 +311,32 @@ static int hdmi_set_video_mode( break; case MCDE_PORTPIXFMT_DSI_YCBCR422: av8100_config.video_input_format.input_pixel_format = - AV8100_INPUT_PIX_YCBCR422; + /* + * The following is expected: + * AV8100_INPUT_PIX_YCBCR422; + * However 565 is used for now and the colour converter + * is used to transform the correct colour. + */ + AV8100_INPUT_PIX_RGB565; break; } /* Set ui_x4 */ av8100_config.video_input_format.ui_x4 = dev->port->phy.dsi.ui; - ret = av8100_configuration_prepare(AV8100_COMMAND_VIDEO_INPUT_FORMAT, + ret = av8100_conf_prep(AV8100_COMMAND_VIDEO_INPUT_FORMAT, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_prepare " + dev_err(&dev->dev, "%s:av8100_conf_prep " "AV8100_COMMAND_VIDEO_INPUT_FORMAT failed\n", __func__); goto out; } - ret = av8100_configuration_write(AV8100_COMMAND_VIDEO_INPUT_FORMAT, + ret = av8100_conf_w(AV8100_COMMAND_VIDEO_INPUT_FORMAT, NULL, NULL, I2C_INTERFACE); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_write " + dev_err(&dev->dev, "%s:av8100_conf_w " "AV8100_COMMAND_VIDEO_INPUT_FORMAT failed\n", __func__); goto out; @@ -333,108 +345,65 @@ static int hdmi_set_video_mode( /* TODO: Remove #ifdefs in driver code. This is a dynamic property! */ #ifdef CONFIG_AV8100_SDTV if (dev->port->pixel_format != MCDE_PORTPIXFMT_DSI_YCBCR422) { - av8100_config.color_space_conversion_format.c0 = 0xFFDA; - av8100_config.color_space_conversion_format.c1 = 0xFFB6; - av8100_config.color_space_conversion_format.c2 = 0x0070; - av8100_config.color_space_conversion_format.c3 = 0x0042; - av8100_config.color_space_conversion_format.c4 = 0x0081; - av8100_config.color_space_conversion_format.c5 = 0x0019; - av8100_config.color_space_conversion_format.c6 = 0x0070; - av8100_config.color_space_conversion_format.c7 = 0xFFA2; - av8100_config.color_space_conversion_format.c8 = 0xFFEE; - av8100_config.color_space_conversion_format.aoffset = 0x007F; - av8100_config.color_space_conversion_format.boffset = 0x0010; - av8100_config.color_space_conversion_format.coffset = 0x007F; - av8100_config.color_space_conversion_format.lmax = 0xEB; - av8100_config.color_space_conversion_format.lmin = 0x10; - av8100_config.color_space_conversion_format.cmax = 0xF0; - av8100_config.color_space_conversion_format.cmin = 0x10; - - ret = av8100_configuration_prepare( - AV8100_COMMAND_COLORSPACECONVERSION, - &av8100_config); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_prepare " - "AV8100_COMMAND_COLORSPACECONVERSION failed\n", - __func__); - goto out; - } - - /* TODO make it possible to turn off conl conversion */ - ret = av8100_configuration_write( - AV8100_COMMAND_COLORSPACECONVERSION, - NULL, NULL, I2C_INTERFACE); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_write " - "AV8100_COMMAND_COLORSPACECONVERSION failed\n", - __func__); - goto out; - } - + av8100_config.color_space_conversion_format = + col_cvt_rgb_to_denc; + } else { + av8100_config.color_space_conversion_format = + col_cvt_yuv422_to_denc; } - /* TODO else turn off col converter (needed for dynamic switching */ #else if (dev->port->pixel_format == MCDE_PORTPIXFMT_DSI_YCBCR422) { - /* YUV to RGB: std */ - av8100_config.color_space_conversion_format.c0 = 0x012a; - av8100_config.color_space_conversion_format.c1 = 0x0000; - av8100_config.color_space_conversion_format.c2 = 0x0199; - av8100_config.color_space_conversion_format.c3 = 0x012a; - av8100_config.color_space_conversion_format.c4 = 0xff9c; - av8100_config.color_space_conversion_format.c5 = 0xff30; - av8100_config.color_space_conversion_format.c6 = 0x012a; - av8100_config.color_space_conversion_format.c7 = 0x0204; - av8100_config.color_space_conversion_format.c8 = 0x0000; - av8100_config.color_space_conversion_format.aoffset = 0xff21; - av8100_config.color_space_conversion_format.boffset = 0x0088; - av8100_config.color_space_conversion_format.coffset = 0xfeeb; - - ret = av8100_configuration_prepare( - AV8100_COMMAND_COLORSPACECONVERSION, &av8100_config); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_prepare " - "AV8100_COMMAND_COLORSPACECONVERSION failed\n", - __func__); - goto out; - } + av8100_config.color_space_conversion_format = + col_cvt_yuv422_to_rgb; + } else { + av8100_config.color_space_conversion_format = + col_cvt_identity; + } +#endif - ret = av8100_configuration_write( - AV8100_COMMAND_COLORSPACECONVERSION, - NULL, NULL, I2C_INTERFACE); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_write " - "AV8100_COMMAND_COLORSPACECONVERSION failed\n", - __func__); - goto out; - } + ret = av8100_conf_prep( + AV8100_COMMAND_COLORSPACECONVERSION, + &av8100_config); + if (ret != AV8100_OK) { + dev_err(&dev->dev, "%s:av8100_configuration_prepare " + "AV8100_COMMAND_COLORSPACECONVERSION failed\n", + __func__); + goto out; } - /* TODO else turn off col converter (needed for dynamic switching */ -#endif + ret = av8100_conf_w( + AV8100_COMMAND_COLORSPACECONVERSION, + NULL, NULL, I2C_INTERFACE); + if (ret != AV8100_OK) { + dev_err(&dev->dev, "%s:av8100_conf_w " + "AV8100_COMMAND_COLORSPACECONVERSION failed\n", + __func__); + goto out; + } /* Set video output format */ - ret = av8100_configuration_write(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, + ret = av8100_conf_w(AV8100_COMMAND_VIDEO_OUTPUT_FORMAT, NULL, NULL, I2C_INTERFACE); if (ret != AV8100_OK) { - dev_err(&dev->dev, "av8100_configuration_write failed\n"); + dev_err(&dev->dev, "av8100_conf_w failed\n"); goto out; } /* Set audio input format */ - ret = av8100_configuration_write(AV8100_COMMAND_AUDIO_INPUT_FORMAT, + ret = av8100_conf_w(AV8100_COMMAND_AUDIO_INPUT_FORMAT, NULL, NULL, I2C_INTERFACE); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_write " + dev_err(&dev->dev, "%s:av8100_conf_w " "AV8100_COMMAND_AUDIO_INPUT_FORMAT failed\n", __func__); goto out; } /* Get current av8100 video denc settings format */ - ret = av8100_configuration_get(AV8100_COMMAND_DENC, + ret = av8100_conf_get(AV8100_COMMAND_DENC, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_get " + dev_err(&dev->dev, "%s:av8100_conf_get " "AV8100_COMMAND_DENC failed\n", __func__); goto out; } @@ -457,19 +426,19 @@ static int hdmi_set_video_mode( #else av8100_config.denc_format.on_off = 0; #endif - ret = av8100_configuration_prepare(AV8100_COMMAND_DENC, + ret = av8100_conf_prep(AV8100_COMMAND_DENC, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_prepare " + dev_err(&dev->dev, "%s:av8100_conf_prep " "AV8100_COMMAND_DENC failed\n", __func__); goto out; } /* TODO: prepare depending on OUT fmt */ - ret = av8100_configuration_write(AV8100_COMMAND_DENC, + ret = av8100_conf_w(AV8100_COMMAND_DENC, NULL, NULL, I2C_INTERFACE); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_write " + dev_err(&dev->dev, "%s:av8100_conf_w " "AV8100_COMMAND_DENC failed\n", __func__); goto out; } @@ -494,10 +463,10 @@ static int hdmi_on_first_update(struct mcde_display_device *dev) av8100_config.hdmi_format.hdmi_format = AV8100_HDMI; av8100_config.hdmi_format.dvi_format = AV8100_DVI_CTRL_CTL0; - ret = av8100_configuration_prepare(AV8100_COMMAND_HDMI, + ret = av8100_conf_prep(AV8100_COMMAND_HDMI, &av8100_config); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_prepare " + dev_err(&dev->dev, "%s:av8100_conf_prep " "AV8100_COMMAND_HDMI failed\n", __func__); goto out; } @@ -510,10 +479,10 @@ static int hdmi_on_first_update(struct mcde_display_device *dev) goto out; } - ret = av8100_configuration_write(AV8100_COMMAND_HDMI, NULL, + ret = av8100_conf_w(AV8100_COMMAND_HDMI, NULL, NULL, I2C_INTERFACE); if (ret != AV8100_OK) { - dev_err(&dev->dev, "%s:av8100_configuration_write " + dev_err(&dev->dev, "%s:av8100_conf_w " "AV8100_COMMAND_HDMI failed\n", __func__); goto out; } @@ -540,19 +509,18 @@ static int __devinit hdmi_probe(struct mcde_display_device *dev) goto invalid_port_type; } + /* DSI use clock continous mode if AV8100_CHIPVER_1 > 1 */ + if (av8100_ver_get() > AV8100_CHIPVER_1) + dev->port->phy.dsi.clk_cont = true; + dev->prepare_for_update = NULL; dev->on_first_update = hdmi_on_first_update; dev->try_video_mode = hdmi_try_video_mode; dev->set_video_mode = hdmi_set_video_mode; - ret = av8100_powerup(); - if (ret != AV8100_OK) { - dev_err(&dev->dev, "av8100_powerup failed\n"); - goto out; - } - dev_info(&dev->dev, "HDMI display probed\n"); + ret = 0; goto out; invalid_port_type: no_pdata: diff --git a/drivers/video/mcde/mcde_hw.c b/drivers/video/mcde/mcde_hw.c index 0ec39e572c8..3a8f30aa91e 100644 --- a/drivers/video/mcde/mcde_hw.c +++ b/drivers/video/mcde/mcde_hw.c @@ -494,7 +494,7 @@ static u32 get_output_fifo_size(enum mcde_fifo fifo) { u32 ret = 1; /* Avoid div by zero */ - switch(fifo) { + switch (fifo) { case MCDE_FIFO_A: case MCDE_FIFO_B: ret = MCDE_FIFO_AB_SIZE; @@ -659,7 +659,8 @@ void update_channel_static_registers(struct mcde_chnl_state *chnl) dsi_wreg(lnk, DSI_MCTL_MAIN_PHY_CTL, DSI_MCTL_MAIN_PHY_CTL_WAIT_BURST_TIME(0xf) | DSI_MCTL_MAIN_PHY_CTL_LANE2_EN(true) | - DSI_MCTL_MAIN_PHY_CTL_CLK_CONTINUOUS(false)); + DSI_MCTL_MAIN_PHY_CTL_CLK_CONTINUOUS( + port->phy.dsi.clk_cont)); dsi_wreg(lnk, DSI_MCTL_ULPOUT_TIME, DSI_MCTL_ULPOUT_TIME_CKLANE_ULPOUT_TIME(1) | DSI_MCTL_ULPOUT_TIME_DATA_ULPOUT_TIME(1)); @@ -867,7 +868,14 @@ static void update_overlay_address_registers(u8 idx, struct ovly_regs *regs) static void disable_channel(struct mcde_chnl_state *chnl) { int i; + const struct mcde_port *port = &chnl->port; + dev_vdbg(&mcde_dev->dev, "%s\n", __func__); + + if (port->type == MCDE_PORTTYPE_DSI) + dsi_wfld(port->link, DSI_MCTL_MAIN_PHY_CTL, CLK_CONTINUOUS, + false); + switch (chnl->id) { case MCDE_CHNL_A: mcde_wfld(MCDE_CRA0, FLOEN, false); @@ -913,10 +921,17 @@ break_switch: #undef MCDE_FLOWEN_MAX_TRIAL } -static void enable_channel(enum mcde_chnl chnl_id) +static void enable_channel(struct mcde_chnl_state *chnl) { + const struct mcde_port *port = &chnl->port; + dev_vdbg(&mcde_dev->dev, "%s\n", __func__); - switch (chnl_id) { + + if (port->type == MCDE_PORTTYPE_DSI) + dsi_wfld(port->link, DSI_MCTL_MAIN_PHY_CTL, CLK_CONTINUOUS, + port->phy.dsi.clk_cont); + + switch (chnl->id) { case MCDE_CHNL_A: mcde_wfld(MCDE_CRA0, FLOEN, true); break; @@ -1506,7 +1521,7 @@ int mcde_chnl_update(struct mcde_chnl_state *chnl, else chnl_update_non_continous(chnl); - enable_channel(chnl->id); + enable_channel(chnl); dev_vdbg(&mcde_dev->dev, "Channel updated, chnl=%d\n", chnl->id); return 0; diff --git a/include/video/av8100.h b/include/video/av8100.h index 5a63d353456..59370ad79f4 100755 --- a/include/video/av8100.h +++ b/include/video/av8100.h @@ -14,6 +14,13 @@ /* Temp: TODO: remove (or move to menuconfig) */ /*#define CONFIG_AV8100_SDTV*/ +#define AV8100_CEC_MESSAGE_SIZE 16 +#define AV8100_HDCP_SEND_KEY_SIZE 16 +#define AV8100_INFOFRAME_SIZE 28 +#define AV8100_FUSE_KEY_SIZE 16 +#define AV8100_CHIPVER_1 1 +#define AV8100_CHIPVER_2 2 + struct av8100_platform_data { unsigned gpio_base; int irq; @@ -53,14 +60,12 @@ enum interface_type { }; enum av8100_dsi_mode { - AV8100_HDMI_DSI_OFF, AV8100_HDMI_DSI_COMMAND_MODE, AV8100_HDMI_DSI_VIDEO_MODE }; enum av8100_pixel_format { - AV8100_INPUT_PIX_RGB565, AV8100_INPUT_PIX_RGB666, AV8100_INPUT_PIX_RGB666P, @@ -278,9 +283,19 @@ struct av8100_color_space_conversion_format_cmd { unsigned char cmin; }; +const extern struct av8100_color_space_conversion_format_cmd col_cvt_identity; +const extern struct av8100_color_space_conversion_format_cmd + col_cvt_identity_clamp_yuv; +const extern struct av8100_color_space_conversion_format_cmd + col_cvt_yuv422_to_rgb; +const extern struct av8100_color_space_conversion_format_cmd + col_cvt_yuv422_to_denc; +const extern struct av8100_color_space_conversion_format_cmd + col_cvt_rgb_to_denc; + struct av8100_cec_message_write_format_cmd { unsigned char buffer_length; - unsigned char buffer[16]; + unsigned char buffer[AV8100_CEC_MESSAGE_SIZE]; }; struct av8100_cec_message_read_back_format_cmd { @@ -314,13 +329,31 @@ struct av8100_hdmi_cmd { struct av8100_hdcp_send_key_format_cmd { unsigned char key_number; - unsigned char key[7]; + unsigned char data_len; + unsigned char data[AV8100_HDCP_SEND_KEY_SIZE]; +}; + +enum av8100_hdcp_auth_req_type { + AV8100_HDCP_AUTH_REQ_OFF = 0, + AV8100_HDCP_AUTH_REQ_ON = 1, + AV8100_HDCP_REV_LIST_REQ = 2, + AV8100_HDCP_AUTH_CONT = 3, +}; + +enum av8100_hdcp_encr_req_type { + AV8100_HDCP_ENCR_REQ_OFF = 0, + AV8100_HDCP_ENCR_REQ_ON = 1, +}; + +enum av8100_hdcp_encr_use { + AV8100_HDCP_ENCR_USE_OESS = 0, + AV8100_HDCP_ENCR_USE_EESS = 1, }; struct av8100_hdcp_management_format_cmd { - unsigned char request_hdcp_revocation_list; - unsigned char request_encrypted_transmission; - unsigned char oess_eess_encryption_use; + unsigned char req_type; + unsigned char req_encr; + unsigned char encr_use; }; struct av8100_infoframes_format_cmd { @@ -328,7 +361,7 @@ struct av8100_infoframes_format_cmd { unsigned char version; unsigned char length; unsigned char crc; - unsigned char data[28]; + unsigned char data[AV8100_INFOFRAME_SIZE]; }; struct av8100_edid_section_readback_format_cmd { @@ -342,9 +375,14 @@ struct av8100_pattern_generator_format_cmd { enum av8100_pattern_audio pattern_audio_mode; }; +enum av8100_fuse_operation { + AV8100_FUSE_READ = 0, + AV8100_FUSE_WRITE = 1, +}; + struct av8100_fuse_aes_key_format_cmd { unsigned char fuse_operation; - unsigned char key[16]; + unsigned char key[AV8100_FUSE_KEY_SIZE]; }; union av8100_configuration { @@ -376,19 +414,27 @@ enum av8100_operating_mode { AV8100_OPMODE_SCAN, AV8100_OPMODE_INIT, AV8100_OPMODE_IDLE, - AV8100_OPMODE_VIDEO + AV8100_OPMODE_VIDEO, }; enum av8100_plugin_status { AV8100_PLUGIN_NONE = 0x0, AV8100_HDMI_PLUGIN = 0x1, - AV8100_CVBS_PLUGIN = 0x2 + AV8100_CVBS_PLUGIN = 0x2, +}; + +enum av8100_hdmi_event { + AV8100_HDMI_EVENT_NONE = 0x0, + AV8100_HDMI_EVENT_HDMI_PLUGIN = 0x1, + AV8100_HDMI_EVENT_HDMI_PLUGOUT = 0x2, + AV8100_HDMI_EVENT_CEC = 0x4, + AV8100_HDMI_EVENT_HDCP = 0x8, }; struct av8100_status { enum av8100_operating_mode av8100_state; enum av8100_plugin_status av8100_plugin_status; - int hdmi_on; + int hdmi_on; }; @@ -400,23 +446,24 @@ int av8100_disable_interrupt(void); int av8100_enable_interrupt(void); int av8100_download_firmware(char *fw_buff, int numOfBytes, enum interface_type if_type); -int av8100_register_standby_write( +int av8100_reg_stby_w( unsigned char cpd, unsigned char stby, unsigned char mclkrng); -int av8100_register_hdmi_5_volt_time_write( - unsigned char off_time, +int av8100_reg_hdmi_5_volt_time_w( + unsigned char denc_off_time, + unsigned char hdmi_off_time, unsigned char on_time); -int av8100_register_standby_interrupt_mask_write( +int av8100_reg_stby_int_mask_w( unsigned char hpdm, unsigned char cpdm, unsigned char stbygpiocfg, unsigned char ipol); -int av8100_register_standby_pending_interrupt_write( +int av8100_reg_stby_pend_int_w( unsigned char hpdi, unsigned char cpdi, unsigned char oni); -int av8100_register_general_interrupt_mask_write( +int av8100_reg_gen_int_mask_w( unsigned char eocm, unsigned char vsim, unsigned char vsom, @@ -424,14 +471,14 @@ int av8100_register_general_interrupt_mask_write( unsigned char hdcpm, unsigned char uovbm, unsigned char tem); -int av8100_register_general_interrupt_write( +int av8100_reg_gen_int_w( unsigned char eoci, unsigned char vsii, unsigned char vsoi, unsigned char ceci, unsigned char hdcpi, unsigned char uovbi); -int av8100_register_gpio_configuration_write( +int av8100_reg_gpio_conf_w( unsigned char dat3dir, unsigned char dat3val, unsigned char dat2dir, @@ -439,36 +486,37 @@ int av8100_register_gpio_configuration_write( unsigned char dat1dir, unsigned char dat1val, unsigned char ucdbg); -int av8100_register_general_control_write( +int av8100_reg_gen_ctrl_w( unsigned char fdl, unsigned char hld, unsigned char wa, unsigned char ra); -int av8100_register_firmware_download_entry_write( +int av8100_reg_fw_dl_entry_w( unsigned char mbyte_code_entry); -int av8100_register_write( +int av8100_reg_w( unsigned char offset, unsigned char value); -int av8100_register_standby_read( +int av8100_reg_stby_r( unsigned char *cpd, unsigned char *stby, unsigned char *hpds, unsigned char *cpds, unsigned char *mclkrng); -int av8100_register_hdmi_5_volt_time_read( - unsigned char *off_time, +int av8100_reg_hdmi_5_volt_time_r( + unsigned char *denc_off_time, + unsigned char *hdmi_off_time, unsigned char *on_time); -int av8100_register_standby_interrupt_mask_read( +int av8100_reg_stby_int_mask_r( unsigned char *hpdm, unsigned char *cpdm, unsigned char *stbygpiocfg, unsigned char *ipol); -int av8100_register_standby_pending_interrupt_read( +int av8100_reg_stby_pend_int_r( unsigned char *hpdi, unsigned char *cpdi, unsigned char *oni, unsigned char *sid); -int av8100_register_general_interrupt_mask_read( +int av8100_reg_gen_int_mask_r( unsigned char *eocm, unsigned char *vsim, unsigned char *vsom, @@ -476,7 +524,7 @@ int av8100_register_general_interrupt_mask_read( unsigned char *hdcpm, unsigned char *uovbm, unsigned char *tem); -int av8100_register_general_interrupt_read( +int av8100_reg_gen_int_r( unsigned char *eoci, unsigned char *vsii, unsigned char *vsoi, @@ -484,13 +532,13 @@ int av8100_register_general_interrupt_read( unsigned char *hdcpi, unsigned char *uovbi, unsigned char *tei); -int av8100_register_general_status_read( +int av8100_reg_gen_status_r( unsigned char *cecrec, unsigned char *cectrx, unsigned char *uc, unsigned char *onuvb, unsigned char *hdcps); -int av8100_register_gpio_configuration_read( +int av8100_reg_gpio_conf_r( unsigned char *dat3dir, unsigned char *dat3val, unsigned char *dat2dir, @@ -498,24 +546,24 @@ int av8100_register_gpio_configuration_read( unsigned char *dat1dir, unsigned char *dat1val, unsigned char *ucdbg); -int av8100_register_general_control_read( +int av8100_reg_gen_ctrl_r( unsigned char *fdl, unsigned char *hld, unsigned char *wa, unsigned char *ra); -int av8100_register_firmware_download_entry_read( +int av8100_reg_fw_dl_entry_r( unsigned char *mbyte_code_entry); -int av8100_register_read( +int av8100_reg_r( unsigned char offset, unsigned char *value); -int av8100_configuration_get(enum av8100_command_type command_type, +int av8100_conf_get(enum av8100_command_type command_type, union av8100_configuration *config); -int av8100_configuration_prepare(enum av8100_command_type command_type, +int av8100_conf_prep(enum av8100_command_type command_type, union av8100_configuration *config); -int av8100_configuration_write(enum av8100_command_type command_type, +int av8100_conf_w(enum av8100_command_type command_type, unsigned char *return_buffer_length, unsigned char *return_buffer, enum interface_type if_type); -int av8100_configuration_write_raw(enum av8100_command_type command_type, +int av8100_conf_w_raw(enum av8100_command_type command_type, unsigned char buffer_length, unsigned char *buffer, unsigned char *return_buffer_length, @@ -527,5 +575,7 @@ enum av8100_output_CEA_VESA av8100_video_output_format_get(int xres, int vtot, int pixelclk, bool interlaced); +void av8100_hdmi_event_cb_set(void (*event_callback)(enum av8100_hdmi_event)); +u8 av8100_ver_get(void); #endif /* __AV8100__H__ */ diff --git a/include/video/hdmi.h b/include/video/hdmi.h index 7745d80d147..7aeafb433eb 100644..100755 --- a/include/video/hdmi.h +++ b/include/video/hdmi.h @@ -1,7 +1,7 @@ /* * Copyright (C) ST-Ericsson AB 2010 * - * AV8100 driver + * HDMI driver * * Author: Per Persson <per.xb.persson@stericsson.com> * for ST-Ericsson. @@ -11,40 +11,147 @@ #ifndef __HDMI__H__ #define __HDMI__H__ -#define HDMI_DRIVER_MINOR_NUMBER 241 -struct hdmi_register { - unsigned char value; - unsigned char offset; -}; - -struct hdmi_command_register { - unsigned char cmd_id; /* input */ - unsigned char buf_len; /* input, output */ - unsigned char buf[128]; /* input, output */ - unsigned char return_status; /* output */ -}; +#define HDMI_CEC_READ_MAXSIZE 16 +#define HDMI_CEC_WRITE_MAXSIZE 15 +#define HDMI_INFOFRAME_MAX_SIZE 27 +#define HDMI_HDCP_FUSEAES_KEYSIZE 16 +#define HDMI_HDCP_AES_BLOCK_START 128 +#define HDMI_HDCP_KSV_BLOCK 40 +#define HDMI_HDCP_AES_NR_OF_BLOCKS 18 +#define HDMI_HDCP_AES_KEYSIZE 16 +#define HDMI_HDCP_AES_KSVSIZE 5 +#define HDMI_HDCP_AES_KSVZEROESSIZE 3 -/* IOCTL return status */ -#define HDMI_COMMAND_RETURN_STATUS_OK 0 -#define HDMI_COMMAND_RETURN_STATUS_FAIL 1 +#define HDMI_STOREASTEXT_TEXT_SIZE 2 +#define HDMI_STOREASTEXT_BIN_SIZE 1 +#define HDMI_PLUGDETEN_TEXT_SIZE 6 +#define HDMI_PLUGDETEN_BIN_SIZE 3 +#define HDMI_EDIDREAD_TEXT_SIZE 4 +#define HDMI_EDIDREAD_BIN_SIZE 2 +#define HDMI_CECEVEN_TEXT_SIZE 2 +#define HDMI_CECEVEN_BIN_SIZE 1 +#define HDMI_CECSEND_TEXT_SIZE_MAX 37 +#define HDMI_CECSEND_TEXT_SIZE_MIN 6 +#define HDMI_CECSEND_BIN_SIZE_MAX 18 +#define HDMI_CECSEND_BIN_SIZE_MIN 3 +#define HDMI_INFOFRSEND_TEXT_SIZE_MIN 8 +#define HDMI_INFOFRSEND_TEXT_SIZE_MAX 63 +#define HDMI_INFOFRSEND_BIN_SIZE_MIN 4 +#define HDMI_INFOFRSEND_BIN_SIZE_MAX 31 +#define HDMI_HDCPEVEN_TEXT_SIZE 2 +#define HDMI_HDCPEVEN_BIN_SIZE 1 +#define HDMI_HDCP_FUSEAES_TEXT_SIZE 34 +#define HDMI_HDCP_FUSEAES_BIN_SIZE 17 +#define HDMI_HDCP_LOADAES_TEXT_SIZE 586 +#define HDMI_HDCP_LOADAES_BIN_SIZE 293 +#define HDMI_HDCPAUTHENCR_TEXT_SIZE 4 +#define HDMI_HDCPAUTHENCR_BIN_SIZE 2 +#define HDMI_EVCLR_TEXT_SIZE 2 +#define HDMI_EVCLR_BIN_SIZE 1 +#define HDMI_AUDIOCFG_TEXT_SIZE 14 +#define HDMI_AUDIOCFG_BIN_SIZE 7 #define HDMI_IOC_MAGIC 0xcc /** IOCTL Operations */ -#define IOC_HDMI_POWER _IOWR(HDMI_IOC_MAGIC, 1, int) -#define IOC_HDMI_ENABLE_INTERRUPTS _IOWR(HDMI_IOC_MAGIC, 2, int) -#define IOC_HDMI_DOWNLOAD_FW _IOWR(HDMI_IOC_MAGIC, 3, int) -#define IOC_HDMI_ONOFF _IOWR(HDMI_IOC_MAGIC, 4, int) - -#define IOC_HDMI_REGISTER_WRITE _IOWR(HDMI_IOC_MAGIC, 5, int) -#define IOC_HDMI_REGISTER_READ _IOWR(HDMI_IOC_MAGIC, 6, int) -#define IOC_HDMI_STATUS_GET _IOWR(HDMI_IOC_MAGIC, 7, int) -#define IOC_HDMI_CONFIGURATION_WRITE _IOWR(HDMI_IOC_MAGIC, 8, int) +#define IOC_PLUG_DETECT_ENABLE _IOWR(HDMI_IOC_MAGIC, 1, int) +#define IOC_EDID_READ _IOWR(HDMI_IOC_MAGIC, 2, int) +#define IOC_CEC_EVENT_ENABLE _IOWR(HDMI_IOC_MAGIC, 3, int) +#define IOC_CEC_READ _IOWR(HDMI_IOC_MAGIC, 4, int) +#define IOC_CEC_SEND _IOWR(HDMI_IOC_MAGIC, 5, int) +#define IOC_INFOFRAME_SEND _IOWR(HDMI_IOC_MAGIC, 6, int) +#define IOC_HDCP_EVENT_ENABLE _IOWR(HDMI_IOC_MAGIC, 7, int) +#define IOC_HDCP_CHKAESOTP _IOWR(HDMI_IOC_MAGIC, 8, int) +#define IOC_HDCP_FUSEAES _IOWR(HDMI_IOC_MAGIC, 9, int) +#define IOC_HDCP_LOADAES _IOWR(HDMI_IOC_MAGIC, 10, int) +#define IOC_HDCP_AUTHENCR_REQ _IOWR(HDMI_IOC_MAGIC, 11, int) +#define IOC_HDCP_STATE_GET _IOWR(HDMI_IOC_MAGIC, 12, int) +#define IOC_REVOCATION_LIST_GET _IOWR(HDMI_IOC_MAGIC, 13, int) +#define IOC_REVOCATION_LIST_SET _IOWR(HDMI_IOC_MAGIC, 14, int) +#define IOC_EVENTS_READ _IOWR(HDMI_IOC_MAGIC, 15, int) +#define IOC_EVENTS_CLEAR _IOWR(HDMI_IOC_MAGIC, 16, int) +#define IOC_AUDIO_CFG _IOWR(HDMI_IOC_MAGIC, 17, int) /* HDMI driver */ +void hdmi_event(enum av8100_hdmi_event); int hdmi_init(void); void hdmi_exit(void); +enum hdmi_event { + HDMI_EVENT_NONE = 0x0, + HDMI_EVENT_HDMI_PLUGIN = 0x1, + HDMI_EVENT_HDMI_PLUGOUT = 0x2, + HDMI_EVENT_CEC = 0x4, + HDMI_EVENT_HDCP = 0x8, +}; + +enum hdmi_hdcp_auth_type { + HDMI_HDCP_AUTH_OFF = 0, + HDMI_HDCP_AUTH_START = 1, + HDMI_HDCP_AUTH_CONT = 2, +}; + +enum hdmi_hdcp_encr_type { + HDMI_HDCP_ENCR_OFF = 0, + HDMI_HDCP_ENCR_OESS = 1, + HDMI_HDCP_ENCR_EESS = 2, +}; + +struct plug_detect { + u8 hdmi_detect_enable; + u8 on_time; + u8 hdmi_off_time; +}; + +struct edid_read { + u8 address; + u8 block_nr; + u8 data_length; + u8 data[128]; +}; + +struct cec_rw { + u8 src; + u8 dest; + u8 length; + u8 data[15]; +}; + +struct info_fr { + u8 type; + u8 ver; + u8 crc; + u8 length; + u8 data[27]; +}; + +struct hdcp_fuseaes { + u8 key[16]; + u8 crc; + u8 result; +}; + +struct hdcp_loadaesall { + u8 ksv[5]; + u8 key[288]; + u8 result; +}; + +struct hdcp_authencr { + u8 auth_type; + u8 encr_type; +}; + +struct audio_cfg { + u8 if_format; + u8 i2s_entries; + u8 freq; + u8 word_length; + u8 format; + u8 if_mode; + u8 mute; +}; + #endif /* __HDMI__H__ */ diff --git a/include/video/mcde.h b/include/video/mcde.h index 415d9db960a..b682200edc7 100644 --- a/include/video/mcde.h +++ b/include/video/mcde.h @@ -163,6 +163,7 @@ struct mcde_port { u8 virt_id; u8 num_data_lanes; u8 ui; + bool clk_cont; } dsi; struct { bool chip_select;/* REVIEW: Used? Needed? */ |