diff options
| author | Yuval Adam <_@yuv.al> | 2017-08-30 08:25:59 +0000 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2017-08-30 08:25:59 +0000 |
| commit | 8e4bff4cab0ddac6060645b0715210484d02ff40 (patch) | |
| tree | 3a5c3024371a04692a3a6d9974d001cdff8ebf84 /drivers/input/touchscreen/ist30xxa | |
Diffstat (limited to 'drivers/input/touchscreen/ist30xxa')
18 files changed, 10800 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/ist30xxa/Makefile b/drivers/input/touchscreen/ist30xxa/Makefile new file mode 100644 index 00000000..afb71927 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for the imagis kanas driver. +# + +# Each configuration option enables a list of files. + +obj-y += ist30xx.o ist30xx_misc.o ist30xx_sec.o ist30xx_sys.o ist30xx_tracking.o ist30xx_update.o ist30xx_cmcs.o diff --git a/drivers/input/touchscreen/ist30xxa/firmware/core_prime.h b/drivers/input/touchscreen/ist30xxa/firmware/core_prime.h new file mode 100644 index 00000000..3e2a6f7f --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/firmware/core_prime.h @@ -0,0 +1,2573 @@ +#ifndef __IST30XXB_FW_H__
+#define __IST30XXB_FW_H__
+
+/* ist30xxb binary: Core-Prime EELY, f/w 3(00050000) */
+static unsigned char ist30xxb_fw[] = {
+ 0x06,0x00,0x00,0xEA,0x1D,0x00,0x00,0xEA,0x1C,0x00,0x00,0xEA,0x1B,0x00,0x00,0xEA,
+ 0x1A,0x00,0x00,0xEA,0x19,0x00,0x00,0xEA,0x18,0x00,0x00,0xEA,0x29,0x00,0x00,0xEA,
+ 0x14,0x00,0x9F,0xE5,0x00,0x10,0xA0,0xE3,0x08,0x10,0x80,0xE5,0xFF,0x10,0xA0,0xE3,
+ 0x00,0x10,0x80,0xE5,0x00,0x00,0xA0,0xE1,0x00,0x00,0x00,0xEA,0x0C,0x20,0x00,0x40,
+ 0x00,0x00,0x0F,0xE1,0x1F,0x00,0xC0,0xE3,0xD1,0x10,0x80,0xE3,0x01,0xF0,0x2F,0xE1,
+ 0x1C,0xD0,0x9F,0xE5,0xD3,0x10,0x80,0xE3,0x01,0xF0,0x2F,0xE1,0x14,0xD0,0x9F,0xE5,
+ 0x00,0x00,0x0F,0xE1,0xC0,0x00,0xC0,0xE3,0x00,0xF0,0x2F,0xE1,0x08,0x00,0x9F,0xE5,
+ 0x10,0xFF,0x2F,0xE1,0xFC,0x0F,0x00,0x20,0xC0,0x0F,0x00,0x20,0xBD,0x3C,0x00,0x00,
+ 0x50,0x30,0x9F,0xE5,0x50,0x40,0x9F,0xE5,0x00,0x40,0x83,0xE5,0x58,0x00,0x1F,0xE5,
+ 0x00,0x10,0xA0,0xE3,0x08,0x10,0x80,0xE5,0x00,0x40,0x83,0xE5,0xFF,0x10,0xA0,0xE3,
+ 0x00,0x10,0x80,0xE5,0x03,0x00,0x00,0xEB,0xFE,0x10,0xA0,0xE3,0x00,0x10,0x80,0xE5,
+ 0x00,0x00,0x00,0xEB,0xF7,0xFF,0xFF,0xEA,0x01,0x29,0xA0,0xE3,0x01,0x20,0x52,0xE2,
+ 0xFD,0xFF,0xFF,0x1A,0x1E,0xFF,0x2F,0xE1,0xFF,0x40,0x2D,0xE9,0x37,0x0C,0x00,0xEB,
+ 0xFF,0x40,0xBD,0xE8,0x04,0xF0,0x5E,0xE2,0x1C,0x40,0x00,0x30,0x70,0xE9,0x1C,0xE1,
+ 0x00,0x00,0x0F,0xE1,0x80,0x00,0xC0,0xE3,0x00,0xF0,0x2F,0xE1,0x1E,0xFF,0x2F,0xE1,
+ 0x00,0x00,0x0F,0xE1,0x80,0x00,0x80,0xE3,0x00,0xF0,0x2F,0xE1,0x1E,0xFF,0x2F,0xE1,
+ 0x00,0x00,0x0F,0xE1,0x40,0x00,0xC0,0xE3,0x00,0xF0,0x2F,0xE1,0x1E,0xFF,0x2F,0xE1,
+ 0x00,0x00,0x0F,0xE1,0x40,0x00,0x80,0xE3,0x00,0xF0,0x2F,0xE1,0x1E,0xFF,0x2F,0xE1,
+ 0x78,0x47,0xC0,0x46,0x03,0x00,0x52,0xE3,0x2A,0x00,0x00,0x9A,0x03,0xC0,0x10,0xE2,
+ 0x08,0x00,0x00,0x0A,0x01,0x30,0xD1,0xE4,0x02,0x00,0x5C,0xE3,0x0C,0x20,0x82,0xE0,
+ 0x01,0xC0,0xD1,0x94,0x01,0x30,0xC0,0xE4,0x01,0x30,0xD1,0x34,0x01,0xC0,0xC0,0x94,
+ 0x04,0x20,0x42,0xE2,0x01,0x30,0xC0,0x34,0x03,0x30,0x11,0xE2,0xB2,0x00,0x00,0x0A,
+ 0x04,0x20,0x52,0xE2,0x1B,0x00,0x00,0x3A,0x03,0xC0,0x31,0xE7,0x02,0x00,0x53,0xE3,
+ 0x08,0x00,0x00,0x0A,0x0F,0x00,0x00,0x8A,0x2C,0x34,0xA0,0xE1,0x04,0xC0,0xB1,0xE5,
+ 0x04,0x20,0x52,0xE2,0x0C,0x3C,0x83,0xE1,0x04,0x30,0x80,0xE4,0xF9,0xFF,0xFF,0x2A,
+ 0x01,0x10,0x81,0xE2,0x0F,0x00,0x00,0xEA,0x2C,0x38,0xA0,0xE1,0x04,0xC0,0xB1,0xE5,
+ 0x04,0x20,0x52,0xE2,0x0C,0x38,0x83,0xE1,0x04,0x30,0x80,0xE4,0xF9,0xFF,0xFF,0x2A,
+ 0x02,0x10,0x81,0xE2,0x07,0x00,0x00,0xEA,0x2C,0x3C,0xA0,0xE1,0x04,0xC0,0xB1,0xE5,
+ 0x04,0x20,0x52,0xE2,0x0C,0x34,0x83,0xE1,0x04,0x30,0x80,0xE4,0xF9,0xFF,0xFF,0x2A,
+ 0x03,0x10,0x81,0xE2,0x00,0x00,0xA0,0xE1,0x82,0x2F,0xB0,0xE1,0x01,0x30,0xD1,0x24,
+ 0x01,0xC0,0xD1,0x24,0x01,0x20,0xD1,0x44,0x01,0x30,0xC0,0x24,0x01,0xC0,0xC0,0x24,
+ 0x01,0x20,0xC0,0x44,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0xC0,0x46,0x01,0x30,0x90,0xE1,
+ 0x4C,0x00,0x00,0x4A,0x00,0x20,0xB0,0xE3,0xA0,0x30,0x71,0xE0,0x43,0x00,0x00,0x3A,
+ 0x20,0x32,0x71,0xE0,0x34,0x00,0x00,0x3A,0x20,0x34,0x71,0xE0,0x26,0x00,0x00,0x3A,
+ 0x20,0x36,0x71,0xE0,0x17,0x00,0x00,0x3A,0x20,0x38,0x71,0xE0,0x09,0x00,0x00,0x3A,
+ 0x01,0x14,0xA0,0xE1,0x20,0x38,0x71,0xE0,0xFF,0x24,0x82,0xE3,0xFF,0x28,0x82,0x23,
+ 0x01,0x14,0xA0,0x21,0x20,0x36,0x71,0xE0,0x0E,0x00,0x00,0x3A,0x00,0x30,0x71,0xE2,
+ 0x6F,0x00,0x00,0x2A,0x21,0x14,0xA0,0x21,0xA0,0x37,0x71,0xE0,0x81,0x07,0x40,0x20,
+ 0x02,0x20,0xB2,0xE0,0x20,0x37,0x71,0xE0,0x01,0x07,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0xA0,0x36,0x71,0xE0,0x81,0x06,0x40,0x20,0x02,0x20,0xB2,0xE0,0x20,0x36,0x71,0xE0,
+ 0x01,0x06,0x40,0x20,0x02,0x20,0xB2,0xE0,0xA0,0x35,0x71,0xE0,0x81,0x05,0x40,0x20,
+ 0x02,0x20,0xB2,0xE0,0x20,0x35,0x71,0xE0,0x01,0x05,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0xA0,0x34,0x71,0xE0,0x81,0x04,0x40,0x20,0x02,0x20,0xB2,0xE0,0x20,0x34,0x71,0xE0,
+ 0x01,0x04,0x40,0x20,0x02,0x20,0xB2,0xE0,0xE5,0xFF,0xFF,0x2A,0xA0,0x33,0x71,0xE0,
+ 0x81,0x03,0x40,0x20,0x02,0x20,0xB2,0xE0,0x20,0x33,0x71,0xE0,0x01,0x03,0x40,0x20,
+ 0x02,0x20,0xB2,0xE0,0xA0,0x32,0x71,0xE0,0x81,0x02,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0x20,0x32,0x71,0xE0,0x01,0x02,0x40,0x20,0x02,0x20,0xB2,0xE0,0xA0,0x31,0x71,0xE0,
+ 0x81,0x01,0x40,0x20,0x02,0x20,0xB2,0xE0,0x20,0x31,0x71,0xE0,0x01,0x01,0x40,0x20,
+ 0x02,0x20,0xB2,0xE0,0xA0,0x30,0x71,0xE0,0x81,0x00,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0x01,0x10,0x50,0xE0,0x00,0x10,0xA0,0x31,0x02,0x00,0xA2,0xE0,0x1E,0xFF,0x2F,0xE1,
+ 0x01,0x10,0x50,0xE0,0x01,0x00,0xA0,0x23,0x1E,0xFF,0x2F,0x21,0x00,0x10,0xA0,0xE1,
+ 0x00,0x00,0xB0,0xE3,0x1E,0xFF,0x2F,0xE1,0x02,0x21,0x11,0xE2,0x00,0x10,0x61,0x42,
+ 0x40,0xC0,0x32,0xE0,0x00,0x00,0x60,0x22,0x20,0x32,0x71,0xE0,0x1D,0x00,0x00,0x3A,
+ 0x20,0x34,0x71,0xE0,0x0F,0x00,0x00,0x3A,0x01,0x13,0xA0,0xE1,0x20,0x34,0x71,0xE0,
+ 0x3F,0x23,0x82,0xE3,0x0B,0x00,0x00,0x3A,0x01,0x13,0xA0,0xE1,0x20,0x34,0x71,0xE0,
+ 0x3F,0x26,0x82,0xE3,0x07,0x00,0x00,0x3A,0x01,0x13,0xA0,0xE1,0x20,0x34,0x71,0xE0,
+ 0x3F,0x29,0x82,0xE3,0x01,0x13,0xA0,0x21,0x3F,0x2C,0x82,0x23,0x00,0x30,0x71,0xE2,
+ 0x1D,0x00,0x00,0x2A,0x21,0x13,0xA0,0x21,0xA0,0x33,0x71,0xE0,0x81,0x03,0x40,0x20,
+ 0x02,0x20,0xB2,0xE0,0x20,0x33,0x71,0xE0,0x01,0x03,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0xA0,0x32,0x71,0xE0,0x81,0x02,0x40,0x20,0x02,0x20,0xB2,0xE0,0x20,0x32,0x71,0xE0,
+ 0x01,0x02,0x40,0x20,0x02,0x20,0xB2,0xE0,0xA0,0x31,0x71,0xE0,0x81,0x01,0x40,0x20,
+ 0x02,0x20,0xB2,0xE0,0x20,0x31,0x71,0xE0,0x01,0x01,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0xEB,0xFF,0xFF,0x2A,0xA0,0x30,0x71,0xE0,0x81,0x00,0x40,0x20,0x02,0x20,0xB2,0xE0,
+ 0x01,0x10,0x50,0xE0,0x00,0x10,0xA0,0x31,0x02,0x00,0xA2,0xE0,0xCC,0xCF,0xB0,0xE1,
+ 0x00,0x00,0x60,0x42,0x00,0x10,0x61,0x22,0x1E,0xFF,0x2F,0xE1,0xCC,0xCF,0xB0,0xE1,
+ 0x00,0x00,0x60,0x42,0x01,0x40,0x2D,0xE9,0x00,0x00,0xB0,0xE3,0x01,0x00,0x00,0xEB,
+ 0x02,0x40,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,0x18,0x00,0x00,0xEA,0x10,0x40,0x2D,0xE9,
+ 0x20,0x20,0x52,0xE2,0x05,0x00,0x00,0x3A,0x18,0x50,0xB1,0xE8,0x20,0x20,0x52,0xE2,
+ 0x18,0x50,0xA0,0xE8,0x18,0x50,0xB1,0xE8,0x18,0x50,0xA0,0xE8,0xF9,0xFF,0xFF,0x2A,
+ 0x02,0xCE,0xB0,0xE1,0x18,0x50,0xB1,0x28,0x18,0x50,0xA0,0x28,0x18,0x00,0xB1,0x48,
+ 0x18,0x00,0xA0,0x48,0x10,0x40,0xBD,0xE8,0x02,0xCF,0xB0,0xE1,0x04,0x30,0x91,0x24,
+ 0x04,0x30,0x80,0x24,0x1E,0xFF,0x2F,0x01,0x82,0x2F,0xB0,0xE1,0xB2,0x30,0xD1,0x20,
+ 0x01,0x20,0xD1,0x44,0xB2,0x30,0xC0,0x20,0x01,0x20,0xC0,0x44,0x1E,0xFF,0x2F,0xE1,
+ 0x07,0x40,0x2D,0xE9,0x02,0x00,0xB0,0xE3,0x01,0x00,0x00,0xEB,0x07,0x40,0xBD,0xE8,
+ 0x1E,0xFF,0x2F,0xE1,0x01,0xC0,0x8F,0xE2,0x1C,0xFF,0x2F,0xE1,0x01,0x00,0x10,0xB5,
+ 0x02,0x20,0x06,0xF0,0x25,0xFE,0x10,0xBC,0x08,0xBC,0x18,0x47,0x78,0x47,0xC0,0x46,
+ 0x00,0x20,0xB0,0xE3,0x20,0x32,0x71,0xE0,0x87,0xFF,0xFF,0x3A,0x20,0x34,0x71,0xE0,
+ 0x79,0xFF,0xFF,0x3A,0x20,0x36,0x71,0xE0,0x6A,0xFF,0xFF,0x3A,0x20,0x38,0x71,0xE0,
+ 0x5C,0xFF,0xFF,0x3A,0x51,0xFF,0xFF,0xEA,0x78,0x47,0xC0,0x46,0x00,0xC0,0x9F,0xE5,
+ 0x1C,0xFF,0x2F,0xE1,0xAD,0x00,0x00,0x10,0x78,0x47,0xC0,0x46,0x00,0xC0,0x9F,0xE5,
+ 0x1C,0xFF,0x2F,0xE1,0x51,0x00,0x00,0x10,0x78,0x47,0xC0,0x46,0x04,0xF0,0x1F,0xE5,
+ 0x48,0x06,0x00,0x10,0x78,0x47,0xC0,0x46,0x04,0xF0,0x1F,0xE5,0xB0,0x05,0x00,0x10,
+ 0x78,0x47,0xC0,0x46,0x04,0xF0,0x1F,0xE5,0x0C,0x06,0x00,0x10,0x78,0x47,0xC0,0x46,
+ 0x04,0xF0,0x1F,0xE5,0xF0,0x05,0x00,0x10,0x78,0x47,0xC0,0x46,0x04,0xF0,0x1F,0xE5,
+ 0x88,0x06,0x00,0x10,0x04,0xF0,0x1F,0xE5,0xB0,0x05,0x00,0x10,0x78,0x47,0xC0,0x46,
+ 0x04,0xF0,0x1F,0xE5,0x28,0x06,0x00,0x10,0x78,0x47,0xC0,0x46,0x00,0xC0,0x9F,0xE5,
+ 0x1C,0xFF,0x2F,0xE1,0x01,0x00,0x00,0x10,0x04,0xF0,0x1F,0xE5,0x48,0x06,0x00,0x10,
+ 0x04,0xF0,0x1F,0xE5,0x88,0x06,0x00,0x10,0x78,0x47,0xC0,0x46,0x04,0xF0,0x1F,0xE5,
+ 0x04,0x07,0x00,0x10,0x78,0x47,0xC0,0x46,0x04,0xF0,0x1F,0xE5,0xA8,0x06,0x00,0x10,
+ 0x78,0x47,0xC0,0x46,0xB9,0xFE,0xFF,0xEA,0x02,0x48,0x01,0x68,0x02,0x4A,0x11,0x40,
+ 0x01,0x60,0x70,0x47,0x00,0xA0,0x00,0x40,0xFE,0xFF,0xEF,0xFF,0x07,0x49,0x10,0xB5,
+ 0x08,0x68,0x07,0x4A,0x10,0x43,0x08,0x60,0x0B,0x24,0x02,0xF0,0xD3,0xF8,0x64,0x1E,
+ 0x00,0x2C,0xFA,0xDC,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x00,0xA0,0x00,0x40,
+ 0x01,0x00,0x10,0x00,0x04,0x49,0x0A,0x68,0xF0,0x23,0x00,0x07,0x9A,0x43,0x00,0x0E,
+ 0x02,0x43,0x0A,0x60,0x70,0x47,0x00,0x00,0x00,0xA0,0x00,0x40,0xF8,0xB5,0x24,0x4D,
+ 0x24,0x48,0x2E,0x18,0xE3,0x20,0xC0,0x00,0x2F,0x18,0x0D,0x20,0xC0,0x01,0x28,0x18,
+ 0x00,0x7B,0xC0,0x07,0x26,0xD0,0x30,0x00,0x40,0x30,0x00,0x90,0x40,0x7F,0x00,0x28,
+ 0x15,0xD0,0x01,0x24,0x05,0xE0,0xE0,0x00,0x80,0x19,0x2C,0x30,0x06,0xF0,0xE6,0xF8,
+ 0x64,0x1C,0x00,0x98,0x40,0x7F,0xA0,0x42,0xF5,0xDA,0x38,0x68,0x00,0x02,0x40,0x0F,
+ 0x10,0xD0,0x38,0x00,0x20,0x30,0x81,0x7D,0x00,0x29,0x0B,0xD1,0x08,0xE0,0x38,0x00,
+ 0x20,0x30,0x81,0x7D,0x00,0x29,0x05,0xD1,0x00,0x99,0x89,0x7F,0x00,0x29,0x01,0xD0,
+ 0x01,0x21,0x81,0x75,0x40,0x36,0x70,0x7F,0xB0,0x77,0x38,0x68,0x01,0x04,0x00,0x02,
+ 0x09,0x0F,0x40,0x0F,0x08,0x18,0x08,0x49,0x01,0xD1,0x69,0x18,0x03,0xE0,0x69,0x18,
+ 0x0A,0x7F,0x90,0x42,0x00,0xD9,0x08,0x77,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0x40,0x00,0x00,0x20,0x64,0x06,0x00,0x00,0x20,0x03,0x00,0x00,0x15,0x4A,0x70,0xB4,
+ 0x13,0x00,0x40,0x33,0x5C,0x7F,0xE4,0x00,0xA2,0x18,0x13,0x4C,0x34,0x32,0xE4,0x88,
+ 0xE4,0x07,0x17,0xD1,0x04,0x79,0x14,0x71,0x04,0x88,0x14,0x80,0x44,0x88,0x54,0x80,
+ 0x51,0x71,0xC1,0x79,0x91,0x71,0x59,0x7F,0x49,0x1C,0x59,0x77,0xC0,0x79,0x81,0x07,
+ 0x08,0xD5,0x08,0x49,0x45,0x07,0x01,0x22,0x00,0x24,0x60,0x31,0x00,0x2D,0x03,0xDA,
+ 0xDA,0x77,0x0C,0x70,0x70,0xBC,0x70,0x47,0xC0,0x06,0x80,0x0F,0xFA,0xD0,0xDC,0x77,
+ 0x0A,0x70,0xF7,0xE7,0xA4,0x06,0x00,0x20,0x40,0x00,0x00,0x20,0xF0,0xB4,0x0A,0x24,
+ 0x0F,0x00,0x67,0x43,0x0C,0x4D,0x84,0x46,0xE8,0x1F,0x7C,0x19,0xFB,0x38,0x56,0x1C,
+ 0x3F,0x18,0x26,0x71,0xF8,0x89,0x20,0x80,0x38,0x8A,0x60,0x80,0xB8,0x7C,0x60,0x71,
+ 0x60,0x46,0xA3,0x71,0x46,0x54,0x49,0x1C,0xA8,0x18,0xE0,0x30,0x01,0x77,0x00,0x21,
+ 0x01,0x74,0xF0,0xBC,0x70,0x47,0x00,0x00,0x64,0x02,0x00,0x20,0x08,0x49,0x0F,0x23,
+ 0x0A,0x68,0x88,0x7E,0x52,0x1C,0x9B,0x06,0x00,0x07,0x00,0x0A,0x12,0x03,0xC0,0x18,
+ 0x12,0x0B,0x10,0x43,0x08,0x60,0x01,0x21,0x49,0x07,0x08,0x63,0x70,0x47,0x00,0x00,
+ 0x40,0x00,0x00,0x20,0xF0,0xB5,0xBB,0x4A,0xAF,0x23,0x12,0x68,0x99,0xB0,0x9B,0x5C,
+ 0xE3,0x24,0xE4,0x00,0x04,0x93,0xB8,0x4B,0x03,0x93,0x1B,0x19,0x02,0x93,0xB7,0x4C,
+ 0x03,0x9B,0x12,0x68,0x1D,0x19,0x12,0x05,0x10,0xD5,0x04,0x9A,0x01,0x2A,0x01,0xD8,
+ 0x00,0x2A,0x01,0xD1,0x01,0x22,0x04,0x92,0x00,0x28,0x0B,0xD1,0x00,0x29,0x05,0xD1,
+ 0x02,0x98,0x80,0x8E,0x00,0x28,0x01,0xD1,0x02,0xF0,0xF6,0xFF,0x19,0xB0,0xF0,0xBC,
+ 0x08,0xBC,0x18,0x47,0x00,0x20,0x6B,0x46,0xA9,0x4A,0x18,0x84,0x98,0x84,0x91,0x8B,
+ 0x49,0x1E,0xD9,0x84,0xD1,0x8B,0x64,0x22,0x49,0x1E,0x59,0x84,0x14,0x21,0x29,0x71,
+ 0x2A,0x80,0x69,0x71,0xC8,0x21,0x69,0x80,0x58,0x83,0x00,0x26,0x18,0x83,0x02,0x98,
+ 0x80,0x8E,0xF0,0x40,0xC0,0x07,0x03,0xD1,0x30,0x00,0x01,0xF0,0x41,0xFB,0x23,0xE1,
+ 0x02,0x99,0xB0,0x00,0x40,0x18,0x18,0x90,0x41,0x68,0x6B,0x46,0x08,0x02,0x00,0x0D,
+ 0x18,0x87,0x17,0x90,0x08,0x05,0x00,0x0D,0x58,0x87,0x16,0x90,0x15,0x90,0x0C,0x20,
+ 0x70,0x43,0x03,0x99,0x40,0x18,0x91,0x49,0x78,0x39,0x44,0x18,0x00,0x20,0x20,0x5E,
+ 0x00,0x28,0x07,0xDA,0x18,0x8F,0x20,0x80,0x15,0x99,0x61,0x80,0xA0,0x80,0x15,0x98,
+ 0xE0,0x80,0x01,0xE1,0x04,0x9A,0x00,0x20,0x52,0x1E,0x06,0xE0,0x81,0x00,0x09,0x19,
+ 0x8B,0x89,0x40,0x1C,0x0B,0x81,0xCB,0x89,0x4B,0x81,0x90,0x42,0xF6,0xDB,0x21,0x88,
+ 0x17,0x98,0x41,0x1A,0x04,0x98,0x80,0x00,0x00,0x19,0x81,0x80,0x62,0x88,0x16,0x99,
+ 0x89,0x1A,0x00,0x22,0x17,0x00,0xC1,0x80,0x10,0x00,0x08,0xE0,0x81,0x00,0x09,0x19,
+ 0x08,0x23,0xCB,0x5E,0xD2,0x18,0x0A,0x23,0xCB,0x5E,0xFF,0x18,0x40,0x1C,0x04,0x99,
+ 0x88,0x42,0xF3,0xDB,0x04,0x21,0x61,0x5E,0x17,0x98,0x47,0x1A,0x06,0x21,0x61,0x5E,
+ 0x16,0x98,0x40,0x1A,0x0C,0x90,0x38,0x1E,0x00,0xDC,0x78,0x42,0x0A,0x90,0x0C,0x98,
+ 0x00,0x28,0x00,0xDC,0x40,0x42,0x0B,0x90,0x06,0x22,0x29,0x00,0x68,0x46,0xFF,0xF7,
+ 0x3F,0xFC,0x0A,0x98,0x02,0x04,0x68,0x46,0x03,0xC8,0x12,0x14,0x05,0xF0,0x7D,0xFF,
+ 0x6B,0x46,0x98,0x83,0x14,0x90,0x06,0x22,0x29,0x00,0x68,0x46,0xFF,0xF7,0x30,0xFC,
+ 0x0B,0x98,0x02,0x04,0x68,0x46,0x03,0xC8,0x12,0x14,0x05,0xF0,0x6E,0xFF,0x6B,0x46,
+ 0xD8,0x83,0x13,0x90,0x03,0x98,0x0D,0x21,0x89,0x01,0x40,0x18,0x00,0x7C,0x02,0x28,
+ 0x05,0xD2,0x64,0x20,0x28,0x81,0xE8,0x80,0x32,0x20,0xA8,0x81,0x68,0x81,0x14,0x98,
+ 0x0A,0x21,0x48,0x43,0x06,0x21,0x0A,0x22,0x69,0x5E,0xAA,0x5E,0x00,0x04,0x00,0x14,
+ 0x89,0x18,0x2D,0x22,0x51,0x43,0x08,0x18,0x64,0x21,0xFF,0xF7,0x75,0xFC,0x01,0x04,
+ 0x09,0x14,0x6B,0x46,0x99,0x83,0x12,0x91,0x11,0x91,0x13,0x98,0x0A,0x21,0x48,0x43,
+ 0x08,0x21,0x0C,0x22,0x69,0x5E,0xAA,0x5E,0x00,0x04,0x00,0x14,0x89,0x18,0x2D,0x22,
+ 0x51,0x43,0x08,0x18,0x64,0x21,0xFF,0xF7,0x5F,0xFC,0x01,0x04,0x09,0x14,0x6B,0x46,
+ 0xD9,0x83,0x0F,0x91,0x10,0x91,0x11,0x99,0x0A,0x98,0x48,0x43,0x64,0x21,0xFF,0xF7,
+ 0x53,0xFC,0x0A,0x90,0x0F,0x99,0x0B,0x98,0x48,0x43,0x64,0x21,0xFF,0xF7,0x4C,0xFC,
+ 0x18,0x22,0x6B,0x46,0x9A,0x5E,0x11,0x99,0x91,0x42,0x01,0xDD,0x12,0x99,0x19,0x83,
+ 0x1A,0x22,0x6B,0x46,0x9A,0x5E,0x10,0x99,0x91,0x42,0x00,0xDD,0x59,0x83,0x01,0x21,
+ 0x0A,0x00,0x00,0x2F,0x00,0xDA,0x8A,0x1E,0x6B,0x46,0x1A,0x75,0x0C,0x9B,0x00,0x2B,
+ 0x01,0xDA,0x00,0x21,0xC9,0x43,0x6B,0x46,0x59,0x75,0x8C,0x46,0x71,0x00,0x49,0x19,
+ 0x0E,0x23,0xCB,0x56,0x9A,0x42,0x00,0xD1,0x17,0x00,0x0F,0x23,0xCB,0x56,0x9C,0x45,
+ 0x01,0xD1,0x62,0x46,0x0C,0x92,0x6B,0x46,0x9A,0x8A,0xCA,0x81,0xA1,0x88,0x34,0x22,
+ 0x00,0x2F,0x99,0x86,0xE1,0x88,0xD9,0x86,0x9A,0x5E,0x0A,0x99,0x00,0xDA,0x49,0x42,
+ 0x51,0x18,0x6B,0x46,0x99,0x86,0x36,0x21,0x59,0x5E,0x0C,0x9A,0x00,0x2A,0x00,0xDA,
+ 0x40,0x42,0x08,0x18,0x6B,0x46,0xD8,0x86,0x08,0xA9,0x06,0xC9,0x0D,0xA8,0x06,0xF0,
+ 0x3B,0xFB,0x6B,0x46,0x18,0x8F,0x17,0x49,0x20,0x80,0x15,0x98,0x60,0x80,0x98,0x8E,
+ 0xA0,0x80,0xD8,0x8E,0xE0,0x80,0x18,0x98,0x40,0x68,0x08,0x40,0x99,0x8E,0x09,0x05,
+ 0x09,0x0A,0x08,0x43,0x18,0x99,0x48,0x60,0xD9,0x8E,0x00,0x0B,0x00,0x03,0x09,0x05,
+ 0x09,0x0D,0x08,0x43,0x18,0x99,0x48,0x60,0x76,0x1C,0x0A,0x2E,0x00,0xDA,0xCE,0xE6,
+ 0xE8,0x88,0x6B,0x46,0x68,0x81,0x28,0x89,0xA8,0x81,0x18,0x8B,0xE8,0x80,0x58,0x8B,
+ 0x28,0x81,0xAB,0xE6,0xE8,0x07,0x00,0x20,0x40,0x00,0x00,0x20,0x42,0x06,0x00,0x00,
+ 0x9C,0x94,0x00,0x00,0xFF,0x0F,0x00,0xFF,0x7F,0xB5,0x05,0x00,0x1A,0x28,0x0A,0xD1,
+ 0x13,0x48,0x00,0x68,0x00,0x28,0x06,0xD1,0x12,0x4C,0x01,0xF0,0x71,0xFE,0x64,0x1E,
+ 0xFB,0xD2,0xFF,0x24,0x14,0xE0,0x04,0xF0,0x95,0xFF,0x05,0xF0,0xBF,0xFF,0x01,0xF0,
+ 0x9B,0xFD,0x01,0xF0,0xA1,0xFD,0x03,0xAA,0x01,0xA9,0x02,0xA8,0x04,0xF0,0xA8,0xF9,
+ 0x04,0x00,0x03,0x00,0x01,0x9A,0x02,0x99,0x03,0x98,0x00,0x95,0x00,0xF0,0x0C,0xF8,
+ 0x05,0xF0,0xFA,0xF8,0x20,0x00,0x04,0xB0,0x70,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0xC0,0x9F,0x00,0x00,0xE7,0x03,0x00,0x00,0xFF,0xB5,0x06,0x00,0x0D,0x00,0x91,0xB0,
+ 0x03,0xF0,0xBC,0xF8,0x1A,0x48,0x03,0x27,0x04,0x04,0x24,0x0C,0x3F,0x02,0x00,0x22,
+ 0x39,0x00,0x20,0x00,0xFF,0xF7,0x08,0xFD,0x16,0x49,0x3A,0x00,0x20,0x00,0x00,0x23,
+ 0xFF,0xF7,0x0A,0xFD,0x14,0x49,0x40,0x22,0x01,0xA8,0xFF,0xF7,0x0D,0xFD,0x14,0x99,
+ 0x30,0x04,0x09,0x03,0x08,0x43,0x11,0x49,0x08,0x43,0x04,0x90,0x13,0x99,0x28,0x04,
+ 0x08,0x43,0x02,0x90,0x0E,0x48,0x00,0x68,0x05,0x90,0x0B,0x48,0x80,0x68,0x40,0x1C,
+ 0x03,0x90,0x1A,0x98,0x1A,0x28,0x01,0xD1,0x00,0x20,0x01,0x90,0x01,0xA8,0x02,0xF0,
+ 0xB5,0xFB,0x01,0xA8,0x06,0xF0,0xEC,0xF9,0x15,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,
+ 0xC0,0x9C,0x00,0x00,0x00,0x00,0x10,0x40,0xC0,0x9F,0x00,0x00,0xAB,0x0C,0x00,0x80,
+ 0x08,0x08,0x00,0x20,0x04,0x49,0x0A,0x6A,0x02,0x60,0x4A,0x6A,0x42,0x60,0x4A,0x6B,
+ 0x82,0x60,0xC9,0x6A,0xC1,0x60,0x70,0x47,0x80,0x90,0x00,0x40,0x02,0x4A,0x51,0x69,
+ 0x81,0x43,0x51,0x61,0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x40,0x02,0x4A,0x51,0x69,
+ 0x01,0x43,0x51,0x61,0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x40,0x02,0x4A,0x11,0x69,
+ 0x01,0x43,0x11,0x61,0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x40,0x01,0x48,0x40,0x69,
+ 0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x40,0x01,0x48,0x80,0x6A,0x70,0x47,0x00,0x00,
+ 0x40,0x00,0x00,0x40,0x02,0x49,0x08,0x62,0x00,0x20,0x08,0x62,0x70,0x47,0x00,0x00,
+ 0x40,0x00,0x00,0x40,0x01,0x49,0x48,0x61,0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x40,
+ 0x07,0x49,0xFF,0x28,0x04,0xD1,0x01,0x20,0xC8,0x60,0x00,0x20,0x88,0x61,0x70,0x47,
+ 0x8A,0x69,0x12,0x07,0x12,0x0F,0x02,0x43,0x8A,0x61,0x02,0x20,0xC8,0x60,0x70,0x47,
+ 0x40,0x00,0x00,0x40,0xF0,0xB5,0x00,0x20,0xFF,0xB0,0xC0,0x43,0xB2,0xB0,0xA9,0x90,
+ 0x00,0x20,0xA7,0x90,0xFF,0x48,0x00,0x27,0x00,0x68,0x3E,0x00,0x60,0x30,0x41,0x7E,
+ 0x08,0x91,0x81,0x7E,0x07,0x91,0xC1,0x7E,0x06,0x91,0x00,0x7F,0x89,0x21,0x89,0x00,
+ 0x05,0x90,0xF9,0x48,0x45,0x18,0x03,0x90,0xFF,0x30,0x23,0x30,0x02,0x90,0xF7,0x49,
+ 0x03,0x98,0xEC,0x1D,0x40,0x18,0xF9,0x34,0x01,0x90,0x0D,0xE0,0x0A,0x20,0x70,0x43,
+ 0x40,0x19,0x7C,0x21,0x09,0x5C,0x00,0x29,0x05,0xD0,0x7E,0x30,0x02,0xF0,0x6E,0xFD,
+ 0x00,0x28,0x00,0xD0,0x7F,0x1C,0x76,0x1C,0x60,0x7D,0xB0,0x42,0xEE,0xDC,0x01,0x98,
+ 0x00,0x22,0x04,0x21,0x82,0x5E,0x41,0x5E,0x50,0x1A,0x00,0x28,0x00,0xDC,0x88,0x1A,
+ 0x02,0x04,0x12,0x14,0x6B,0x46,0x1A,0x80,0x01,0x98,0x02,0x21,0x06,0x23,0x41,0x5E,
+ 0xC3,0x5E,0xC8,0x1A,0x00,0x28,0x00,0xDC,0x58,0x1A,0x00,0x04,0x00,0x14,0x6B,0x46,
+ 0x58,0x80,0x01,0x99,0x00,0x26,0x00,0x2F,0x8E,0x75,0x12,0xD0,0xD9,0x49,0x09,0x68,
+ 0x80,0x31,0x0B,0x89,0x9A,0x42,0x0C,0xDA,0x4A,0x89,0x90,0x42,0x01,0xDA,0x01,0x21,
+ 0x05,0xE0,0x89,0x89,0x88,0x42,0x01,0xDA,0x02,0x21,0x00,0xE0,0x03,0x21,0x01,0x98,
+ 0x81,0x75,0x01,0x98,0x40,0x7D,0x00,0x28,0x1C,0xD1,0x01,0x98,0x80,0x7D,0x01,0x28,
+ 0x04,0xD1,0xCC,0x48,0x00,0x68,0x80,0x30,0x41,0x7D,0x05,0xE0,0x02,0x28,0x06,0xD1,
+ 0xC8,0x48,0x00,0x68,0x80,0x30,0x81,0x7D,0x08,0x98,0x08,0x18,0x07,0xE0,0x03,0x28,
+ 0x08,0xD1,0xC4,0x48,0x08,0x99,0x00,0x68,0x80,0x30,0xC0,0x7D,0x40,0x18,0x00,0x06,
+ 0x00,0x0E,0x08,0x90,0x0C,0x22,0x00,0x21,0xA2,0xA8,0xFF,0xF7,0x0B,0xFC,0x03,0x98,
+ 0xC0,0x88,0x00,0x06,0x40,0x0F,0x0D,0xD0,0x06,0xF0,0xD0,0xF8,0x01,0xF0,0xDA,0xF8,
+ 0x01,0xF0,0x08,0xF9,0x02,0xF0,0x38,0xFD,0x03,0x98,0x01,0x21,0xE0,0x30,0x81,0x74,
+ 0x30,0x00,0x27,0xE0,0x03,0x98,0x00,0x21,0xE0,0x30,0x81,0x74,0xA0,0x7D,0x00,0x28,
+ 0x01,0xD0,0x40,0x1E,0xA0,0x75,0x03,0x98,0x06,0x79,0x60,0x7D,0x00,0x2E,0x02,0xD1,
+ 0x00,0x28,0x16,0xD0,0x1C,0xE0,0x00,0x28,0x1A,0xD1,0x78,0x22,0x00,0x21,0xA8,0x18,
+ 0xFF,0xF7,0xE0,0xFB,0xA0,0x7D,0x00,0x28,0x0B,0xD1,0x00,0x25,0x06,0xE0,0x2A,0x00,
+ 0x29,0x00,0x14,0x23,0xA2,0xA8,0xFF,0xF7,0xC1,0xFC,0x6D,0x1C,0xB5,0x42,0xF6,0xDB,
+ 0x26,0x75,0x00,0x20,0xE0,0x75,0x7F,0xB0,0x32,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,
+ 0x0D,0x22,0x01,0x21,0x9E,0xA8,0xFF,0xF7,0xC5,0xFB,0x02,0x20,0x09,0x90,0x01,0xF0,
+ 0x23,0xFC,0xA5,0x90,0xE0,0x7D,0x00,0x28,0x05,0xD0,0x20,0x7E,0x01,0x28,0x02,0xD1,
+ 0xA5,0x98,0x40,0x00,0xA5,0x90,0xF9,0xE0,0x00,0x27,0x09,0x22,0xFF,0x43,0x92,0x01,
+ 0x39,0x00,0x0E,0xA8,0xFF,0xF7,0xAE,0xFB,0x0C,0x22,0x39,0x00,0x0B,0xA8,0xFF,0xF7,
+ 0xA9,0xFB,0x09,0x98,0x00,0x28,0x0B,0xD1,0x8A,0x48,0x00,0x68,0x60,0x30,0x07,0x7E,
+ 0xA5,0x98,0x39,0x00,0xFF,0xF7,0x10,0xFA,0x39,0x00,0xFF,0xF7,0x0D,0xFA,0xA5,0x90,
+ 0x00,0x20,0x44,0xE0,0xA5,0x98,0x00,0x27,0xA6,0x90,0x3B,0xE0,0x0A,0x20,0x78,0x43,
+ 0x40,0x19,0x78,0x30,0x04,0x90,0x00,0x79,0x00,0x28,0x32,0xD0,0x04,0x98,0x80,0x1D,
+ 0x02,0xF0,0x8C,0xFC,0x09,0x99,0x88,0x42,0x2B,0xD1,0x04,0x99,0x00,0x20,0x08,0x5E,
+ 0xAC,0x99,0x0A,0x22,0x51,0x43,0x02,0x9A,0x8B,0x18,0x0E,0x21,0x59,0x5E,0x42,0x1A,
+ 0x00,0x2A,0x00,0xDC,0x0A,0x1A,0x04,0x99,0x02,0x20,0x08,0x5E,0x10,0x21,0x59,0x5E,
+ 0x43,0x1A,0x00,0x2B,0x00,0xDC,0x0B,0x1A,0x10,0x00,0x19,0x00,0x50,0x43,0x59,0x43,
+ 0x40,0x18,0xA6,0x99,0x88,0x42,0x04,0xDA,0xAC,0x9B,0x79,0x1C,0x0B,0xAA,0xD1,0x54,
+ 0xA6,0x90,0xAC,0x99,0x30,0x22,0x51,0x43,0x0E,0xAA,0x89,0x18,0xBA,0x00,0x89,0x18,
+ 0x48,0x60,0x7F,0x1C,0x60,0x7D,0xB8,0x42,0xC0,0xDC,0xAC,0x98,0x40,0x1C,0xB0,0x42,
+ 0xAC,0x90,0xB7,0xDB,0x00,0x20,0x8D,0xE0,0x01,0x20,0x84,0x46,0xA5,0x9B,0x00,0x20,
+ 0x16,0xE0,0xA2,0xA9,0x09,0x5C,0x00,0x29,0x11,0xD1,0x0B,0xA9,0x0A,0x56,0x30,0x21,
+ 0x41,0x43,0x0E,0xAF,0xC9,0x19,0x97,0x00,0xC9,0x59,0x99,0x42,0x07,0xDA,0x00,0x29,
+ 0x05,0xDB,0x00,0x2A,0x03,0xDB,0x0B,0x00,0x00,0x21,0x8C,0x46,0xA9,0x90,0x40,0x1C,
+ 0xB0,0x42,0xE6,0xDB,0x60,0x46,0x00,0x28,0x6A,0xD1,0xA7,0x98,0x0A,0x21,0x40,0x1C,
+ 0xA7,0x90,0xA9,0x98,0x48,0x43,0x47,0x19,0xB0,0x90,0x38,0x79,0x00,0x28,0x5F,0xD1,
+ 0xA9,0x99,0x0B,0xA8,0x40,0x56,0x0A,0x21,0x0A,0x22,0x0A,0x90,0x48,0x43,0x41,0x19,
+ 0x6E,0x31,0x38,0x00,0xFF,0xF7,0x1C,0xFB,0x02,0x99,0xB0,0x98,0x40,0x18,0xC1,0x89,
+ 0x39,0x80,0x01,0x8A,0x79,0x80,0x80,0x7C,0x78,0x71,0xB8,0x79,0x08,0x99,0x49,0x1C,
+ 0x88,0x42,0x01,0xD2,0x40,0x1C,0xB8,0x71,0xB8,0x79,0x14,0x28,0x07,0xD3,0x07,0x99,
+ 0x14,0x22,0x89,0x1C,0x51,0x43,0x88,0x42,0x01,0xD2,0x14,0x30,0xB8,0x71,0x38,0x79,
+ 0xA9,0x9A,0xA2,0xA9,0x88,0x54,0xA9,0x98,0x3A,0x79,0x29,0x00,0x40,0x1C,0xFB,0x31,
+ 0x50,0x54,0x3A,0x79,0x00,0x20,0x0C,0x39,0x50,0x54,0x0A,0x9A,0x9E,0xA9,0x88,0x54,
+ 0x01,0x00,0x1F,0xE0,0x30,0x20,0x48,0x43,0x0E,0xAB,0xC0,0x18,0x0A,0x9B,0x00,0x22,
+ 0xD2,0x43,0x9B,0x00,0x84,0x46,0xC2,0x50,0xA2,0xA8,0x40,0x5C,0xA5,0x9B,0x00,0x28,
+ 0x0F,0xD1,0x0B,0xE0,0x82,0x00,0x62,0x44,0x52,0x68,0x00,0x2A,0x05,0xDB,0x9A,0x42,
+ 0x03,0xDA,0x43,0x1C,0x0B,0xAF,0x7B,0x54,0x13,0x00,0x40,0x1C,0x62,0x7D,0x82,0x42,
+ 0xF0,0xDC,0x49,0x1C,0xB1,0x42,0xDD,0xDB,0x60,0x7D,0xA7,0x99,0x88,0x42,0x05,0xDD,
+ 0xAA,0x98,0x40,0x1C,0xB0,0x42,0xAA,0x90,0x00,0xDA,0x6D,0xE7,0x09,0x98,0x41,0x1E,
+ 0x09,0x06,0x09,0x0E,0x00,0x28,0x09,0x91,0x00,0xD0,0xFD,0xE6,0xE0,0x75,0xA8,0x90,
+ 0xAB,0x90,0xAC,0x90,0x6B,0xE0,0x08,0x00,0x0A,0x21,0x48,0x43,0x47,0x19,0xAB,0x98,
+ 0x9E,0xA9,0x08,0x18,0x40,0x78,0x78,0x37,0x00,0x28,0x5D,0xD0,0xAC,0x98,0x30,0x18,
+ 0x0C,0x28,0xAA,0x90,0x5F,0xDA,0x39,0x79,0x28,0x00,0xEF,0x30,0xAF,0x90,0x08,0x5C,
+ 0x06,0x99,0x88,0x42,0x3C,0xD2,0xAC,0x98,0x0C,0x28,0x39,0xDA,0xB8,0x1D,0x02,0xF0,
+ 0x95,0xFB,0x05,0xE0,0xE8,0x07,0x00,0x20,0x40,0x00,0x00,0x20,0x3E,0x03,0x00,0x00,
+ 0x00,0x28,0x2D,0xD0,0x38,0x79,0xAF,0x99,0xAF,0x9A,0x41,0x5C,0x49,0x1C,0x81,0x54,
+ 0xAA,0x98,0x0A,0x21,0x48,0x43,0x40,0x19,0x0A,0x00,0x39,0x00,0xAE,0x90,0xFF,0xF7,
+ 0x7F,0xFA,0xF9,0x79,0xAE,0x98,0xC1,0x71,0x39,0x7A,0xAE,0x98,0x01,0x72,0x38,0x79,
+ 0xAA,0x9A,0xA2,0xA9,0x88,0x54,0xAA,0x98,0x3A,0x79,0x29,0x00,0x40,0x1C,0xFB,0x31,
+ 0x50,0x54,0xAC,0x98,0x40,0x1C,0xAC,0x90,0xA8,0x98,0x40,0x1C,0xA8,0x90,0x01,0x20,
+ 0xE0,0x75,0x03,0x99,0x89,0x7E,0x00,0x29,0x16,0xD1,0x03,0x99,0x88,0x76,0x13,0xE0,
+ 0xB8,0x1D,0x02,0xF0,0x5B,0xFB,0x00,0x28,0x0E,0xD0,0x01,0x99,0x01,0x20,0x08,0x75,
+ 0xB8,0x79,0x13,0x28,0x08,0xD9,0x60,0x7D,0x01,0x28,0x05,0xD1,0x03,0x98,0x04,0x21,
+ 0xC0,0x88,0x08,0x43,0x03,0x99,0xC8,0x80,0xAB,0x98,0x40,0x1C,0xAB,0x90,0x60,0x7D,
+ 0xAB,0x99,0x88,0x42,0x8F,0xDC,0x03,0x98,0xC0,0x88,0x40,0x07,0x07,0xD5,0x05,0x98,
+ 0x04,0x21,0xA0,0x75,0x03,0x98,0xC0,0x88,0x88,0x43,0x03,0x99,0xC8,0x80,0x00,0x27,
+ 0x27,0xE0,0xA2,0xA8,0xC0,0x5D,0x00,0x28,0x13,0xD1,0x00,0x22,0xA8,0x18,0xFC,0x21,
+ 0x09,0x5C,0x00,0x29,0x0A,0xD1,0xFF,0x30,0x01,0x30,0x00,0x7A,0x00,0x28,0x05,0xD1,
+ 0x39,0x00,0x01,0x23,0xA2,0xA8,0xFF,0xF7,0x09,0xFB,0x02,0xE0,0x52,0x1C,0x0C,0x2A,
+ 0xEC,0xDB,0xA0,0x7D,0x00,0x28,0x0B,0xD0,0x0A,0x20,0x78,0x43,0x40,0x19,0xAD,0x90,
+ 0x80,0x1D,0x02,0xF0,0x13,0xFB,0x00,0x28,0x02,0xD1,0xAD,0x99,0x01,0x20,0x88,0x71,
+ 0x7F,0x1C,0xB7,0x42,0xD5,0xDB,0xA8,0x98,0x30,0x18,0x20,0x75,0x33,0xE6,0x00,0x00,
+ 0xF3,0xB5,0x3A,0x48,0x85,0xB0,0x04,0x90,0x00,0x20,0x03,0x90,0x38,0x48,0xC0,0x7F,
+ 0x01,0x90,0x37,0x48,0x20,0x30,0x01,0x78,0x00,0x91,0x00,0x21,0x02,0x91,0xC0,0x78,
+ 0x00,0x28,0x02,0xD0,0x06,0x98,0x40,0x42,0x06,0x90,0x05,0xF0,0x91,0xFF,0x01,0xF0,
+ 0xC9,0xF9,0x01,0xF0,0x41,0xFA,0x00,0x24,0x27,0x00,0x38,0xE0,0x00,0x26,0x30,0xE0,
+ 0x31,0x00,0x38,0x00,0x02,0xF0,0x58,0xF8,0x00,0x28,0x28,0xD0,0x29,0x78,0x04,0x9A,
+ 0x79,0x43,0x89,0x19,0x89,0x00,0x51,0x58,0x09,0x05,0x09,0x0D,0x0D,0x1A,0x05,0x98,
+ 0x00,0x28,0x0D,0xD0,0x00,0x2D,0x1A,0xDA,0x06,0x9A,0x31,0x00,0x38,0x00,0x05,0xF0,
+ 0x7B,0xFB,0x40,0x1C,0x14,0xD1,0x00,0x98,0x28,0x18,0x10,0xD5,0x02,0x20,0x0D,0xE0,
+ 0x00,0x2D,0x0C,0xDD,0x06,0x9A,0x31,0x00,0x38,0x00,0x05,0xF0,0x6D,0xFB,0x40,0x1C,
+ 0x06,0xD1,0x01,0x98,0x28,0x1A,0x00,0x28,0x01,0xDD,0x03,0x20,0x03,0x90,0x64,0x1C,
+ 0x76,0x1C,0x13,0x4D,0x20,0x3D,0x28,0x78,0xB0,0x42,0xC9,0xD8,0x7F,0x1C,0x10,0x48,
+ 0x20,0x38,0x41,0x78,0xB9,0x42,0xC1,0xD8,0x01,0x00,0x48,0x78,0x09,0x78,0x48,0x43,
+ 0xA0,0x42,0x04,0xD1,0x03,0x98,0x07,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x02,0x98,
+ 0x41,0x1C,0x02,0x91,0x01,0x21,0x49,0x02,0x88,0x42,0xA6,0xD9,0x05,0x98,0x00,0x28,
+ 0x01,0xD0,0x02,0x20,0x00,0xE0,0x03,0x20,0x03,0x90,0xEC,0xE7,0xD4,0x02,0x10,0x40,
+ 0xBC,0x94,0x00,0x00,0xF0,0xB5,0x90,0x4A,0x87,0xB0,0x40,0x18,0x06,0x92,0x42,0x00,
+ 0x80,0x18,0x05,0x90,0x48,0x42,0x04,0x90,0x8C,0x48,0x8F,0x4C,0x80,0x7C,0x8C,0x4F,
+ 0x03,0x90,0x8C,0x48,0x01,0x90,0xE0,0x78,0x00,0x28,0x02,0xD1,0x04,0x98,0x40,0x42,
+ 0x04,0x90,0x8A,0x4A,0x00,0x21,0x38,0x00,0xFF,0xF7,0x78,0xF9,0x00,0x26,0x38,0xE0,
+ 0x00,0x25,0x30,0xE0,0x60,0x79,0xC0,0x07,0x15,0xD0,0x85,0x48,0x00,0x78,0x00,0x28,
+ 0x03,0x98,0x16,0xD0,0x86,0x42,0x0E,0xD1,0xA0,0x7A,0xA8,0x42,0x0B,0xD0,0xE0,0x7A,
+ 0xA8,0x42,0x08,0xD0,0x20,0x7B,0xA8,0x42,0x05,0xD0,0x60,0x7B,0xA8,0x42,0x02,0xD0,
+ 0xA0,0x7B,0xA8,0x42,0x16,0xD1,0x04,0x9A,0x29,0x00,0x30,0x00,0x05,0xF0,0xFC,0xFA,
+ 0x10,0xE0,0x85,0x42,0xF7,0xD1,0xA0,0x7A,0xB0,0x42,0xF4,0xD0,0xE0,0x7A,0xB0,0x42,
+ 0xF1,0xD0,0x20,0x7B,0xB0,0x42,0xEE,0xD0,0x60,0x7B,0xB0,0x42,0xEB,0xD0,0xA0,0x7B,
+ 0xB0,0x42,0xE8,0xD0,0x6D,0x1C,0x6C,0x48,0x40,0x38,0x00,0x78,0xA8,0x42,0xC9,0xD8,
+ 0x76,0x1C,0x69,0x48,0x40,0x38,0x40,0x78,0xB0,0x42,0xC1,0xD8,0x05,0xF0,0xD0,0xFE,
+ 0x01,0xF0,0x08,0xF9,0x01,0xF0,0x80,0xF9,0x00,0x26,0x2E,0xE0,0x00,0x25,0x26,0xE0,
+ 0x29,0x00,0x30,0x00,0x01,0xF0,0x98,0xFF,0x00,0x28,0x13,0xD0,0x5E,0x49,0x06,0x9B,
+ 0x40,0x39,0x09,0x78,0x71,0x43,0x4A,0x19,0x91,0x00,0x59,0x58,0x03,0x04,0x09,0x05,
+ 0x09,0x0D,0x1B,0x0C,0xCB,0x1A,0x00,0x2B,0x01,0xDD,0x08,0x1A,0x00,0xE0,0x40,0x1A,
+ 0x51,0x00,0x78,0x52,0x29,0x00,0x30,0x00,0x01,0xF0,0xC2,0xFF,0x52,0x49,0x01,0x9A,
+ 0x40,0x39,0x09,0x78,0x71,0x43,0x49,0x19,0x49,0x00,0x6D,0x1C,0x50,0x52,0x4E,0x48,
+ 0x40,0x38,0x00,0x78,0xA8,0x42,0xD3,0xD8,0x76,0x1C,0x4B,0x48,0x40,0x38,0x41,0x78,
+ 0xB1,0x42,0xCB,0xD8,0x00,0x21,0x02,0x91,0x01,0xF0,0x46,0xF9,0x00,0x26,0x54,0xE0,
+ 0x00,0x25,0x4C,0xE0,0x29,0x00,0x30,0x00,0x01,0xF0,0x5E,0xFF,0x00,0x28,0x45,0xD0,
+ 0x41,0x49,0x06,0x9B,0x40,0x39,0x09,0x78,0x71,0x43,0x4A,0x19,0x91,0x00,0x59,0x58,
+ 0x03,0x04,0x09,0x05,0x09,0x0D,0x1B,0x0C,0xCB,0x1A,0x00,0x2B,0x01,0xDD,0x08,0x1A,
+ 0x00,0xE0,0x40,0x1A,0x51,0x00,0x7A,0x5A,0x00,0x04,0x00,0x0C,0x82,0x42,0x0C,0xD9,
+ 0x78,0x52,0x29,0x00,0x30,0x00,0x01,0xF0,0x83,0xFF,0x33,0x49,0x01,0x9A,0x40,0x39,
+ 0x09,0x78,0x71,0x43,0x49,0x19,0x49,0x00,0x50,0x52,0x02,0x98,0x03,0x21,0xFF,0xF7,
+ 0x8D,0xF8,0x00,0x29,0x01,0xD0,0x02,0x29,0x0C,0xD1,0xE0,0x78,0x00,0x28,0x02,0xD1,
+ 0x00,0x22,0x43,0x1E,0x01,0xE0,0x01,0x22,0x00,0x23,0x29,0x00,0x30,0x00,0x05,0xF0,
+ 0x2D,0xFA,0x0B,0xE0,0x00,0x22,0xD2,0x43,0x00,0x23,0x29,0x00,0x30,0x00,0x05,0xF0,
+ 0x25,0xFA,0x00,0x28,0x02,0xD1,0x00,0x22,0x01,0x23,0xEE,0xE7,0x6D,0x1C,0x1E,0x48,
+ 0x40,0x38,0x00,0x78,0xA8,0x42,0xAD,0xD8,0x76,0x1C,0x1B,0x48,0x40,0x38,0x41,0x78,
+ 0xB1,0x42,0xA5,0xD8,0x02,0x99,0x49,0x1C,0x02,0x91,0x05,0x99,0x49,0x1E,0x05,0x91,
+ 0x1C,0xD2,0x00,0x25,0x06,0x00,0x0F,0xE0,0x00,0x24,0x09,0xE0,0x69,0x43,0x08,0x19,
+ 0x01,0x99,0x40,0x00,0x0A,0x5A,0x21,0x00,0x28,0x00,0x05,0xF0,0x1F,0xFA,0x64,0x1C,
+ 0x31,0x78,0xA1,0x42,0xF2,0xD8,0x6D,0x1C,0x70,0x78,0xA8,0x42,0xEC,0xD8,0x05,0xF0,
+ 0x17,0xFE,0x07,0xB0,0xF0,0xBC,0x08,0xBC,0x00,0x20,0x18,0x47,0x05,0xF0,0x10,0xFE,
+ 0x01,0xF0,0x48,0xF8,0x78,0xE7,0x00,0x00,0xD4,0x02,0x10,0x40,0xC0,0x06,0x00,0x20,
+ 0x00,0x00,0x00,0x10,0x2A,0x08,0x00,0x20,0xDC,0x94,0x00,0x00,0xD2,0x02,0x00,0x00,
+ 0xF4,0x07,0x00,0x20,0x1F,0xB5,0x68,0x46,0xFF,0xF7,0x6C,0xFB,0x00,0x20,0x05,0xF0,
+ 0x87,0xFA,0x00,0x22,0x11,0x00,0x10,0x00,0x00,0xF0,0x1C,0xFE,0x68,0x46,0x04,0xF0,
+ 0x63,0xFD,0x1F,0xBC,0x08,0xBC,0x18,0x47,0x15,0x48,0x10,0xB5,0x01,0x78,0x15,0x48,
+ 0x00,0x68,0x00,0x29,0x02,0xD0,0x14,0x49,0x49,0x89,0x00,0xE0,0x81,0x8B,0x13,0x4A,
+ 0x92,0x8B,0x53,0x18,0x12,0x49,0x13,0x4A,0x8C,0x89,0xA3,0x42,0x14,0xD9,0x12,0x4B,
+ 0x5B,0x7E,0x00,0x2B,0x10,0xD1,0xC9,0x88,0x17,0x23,0x5B,0x01,0x19,0x42,0x0B,0xD1,
+ 0xD1,0x68,0x49,0x1C,0xD1,0x60,0x80,0x7F,0x88,0x42,0x07,0xD2,0x01,0xF0,0x34,0xF8,
+ 0x01,0x20,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x20,0xD0,0x60,0x00,0x20,0xF8,0xE7,
+ 0xFA,0x07,0x00,0x20,0xE8,0x07,0x00,0x20,0x1C,0x95,0x00,0x00,0xC0,0x01,0x00,0x20,
+ 0x40,0x00,0x00,0x20,0x18,0x08,0x00,0x20,0x60,0x03,0x00,0x20,0xF3,0xB5,0x04,0x00,
+ 0x75,0x48,0x00,0x26,0x01,0x00,0x20,0x31,0x0A,0x7A,0x01,0x25,0x82,0xB0,0xD2,0x07,
+ 0x00,0x2A,0x86,0x46,0x01,0xD1,0xE5,0x71,0x5F,0xE0,0x80,0x8D,0x6F,0x4A,0x84,0x46,
+ 0x88,0x7A,0x1C,0x21,0x51,0x5E,0x13,0x00,0x1E,0x22,0x9A,0x5E,0x00,0x28,0x21,0xD0,
+ 0x69,0x4B,0x9B,0x8D,0x1F,0x04,0x3F,0x14,0x01,0x28,0x0F,0xD0,0x02,0x28,0x14,0xD0,
+ 0x03,0x28,0x4A,0xD1,0x65,0x48,0x6B,0x46,0x99,0x80,0x81,0x8B,0x60,0x46,0x08,0x18,
+ 0xD8,0x80,0x00,0x20,0x6B,0x46,0x18,0x80,0x5A,0x80,0x15,0xE0,0x00,0x20,0x6B,0x46,
+ 0x98,0x80,0xD9,0x80,0x18,0x80,0x5F,0x80,0x0E,0xE0,0x00,0x20,0x6B,0x46,0x98,0x80,
+ 0xDF,0x80,0xEF,0xE7,0x00,0x20,0x6B,0x46,0x98,0x80,0x58,0x48,0xD9,0x80,0x1A,0x80,
+ 0xC1,0x8B,0x60,0x46,0x08,0x18,0x58,0x80,0x00,0x20,0x04,0x22,0x6B,0x46,0x20,0x5E,
+ 0x9A,0x5E,0x02,0x21,0x61,0x5E,0x02,0x27,0x82,0x42,0x69,0xDC,0x06,0x22,0x9A,0x5E,
+ 0x90,0x42,0x65,0xDC,0x00,0x22,0x9A,0x5E,0x8A,0x42,0x61,0xDC,0xDA,0x5F,0x91,0x42,
+ 0x5E,0xDC,0x03,0x9A,0xFE,0x1E,0x00,0x2A,0x75,0xD0,0x01,0x2A,0x12,0xD0,0x02,0x2A,
+ 0x23,0xD0,0x04,0x2A,0x7C,0xD1,0xE2,0x79,0xD3,0x07,0x37,0xD0,0x50,0x07,0x80,0x0F,
+ 0x2B,0xD0,0x0A,0x20,0x00,0x26,0xE0,0x71,0x72,0xE0,0x00,0x20,0x04,0xB0,0xF0,0xBC,
+ 0x08,0xBC,0x18,0x47,0x72,0x46,0x40,0x32,0xD2,0x7F,0x00,0x2A,0x68,0xD1,0x00,0xF0,
+ 0x79,0xF8,0x05,0x00,0x06,0xD0,0x06,0x20,0xE0,0x71,0x29,0x00,0x20,0x00,0xFF,0xF7,
+ 0x45,0xF8,0x00,0xE0,0xE7,0x71,0x25,0x72,0x5A,0xE0,0xE2,0x79,0xD3,0x07,0xDD,0xD1,
+ 0x92,0x07,0x55,0xD5,0x00,0xF0,0x66,0xF8,0x00,0x28,0x09,0xD0,0x21,0x7A,0x00,0x29,
+ 0x06,0xD1,0x06,0x21,0xE1,0x71,0x20,0x72,0x03,0xE0,0x12,0x20,0xE0,0x71,0x47,0xE0,
+ 0xE7,0x71,0x01,0x00,0x20,0x00,0xFF,0xF7,0x29,0xF8,0x41,0xE0,0x92,0x07,0x3F,0xD5,
+ 0x00,0xF0,0x50,0xF8,0x21,0x7A,0x00,0x28,0x0A,0xD0,0x00,0x29,0x0C,0xD0,0x81,0x42,
+ 0x08,0xD1,0x0A,0x20,0xE0,0x71,0x20,0x00,0xFF,0xF7,0x18,0xF8,0xA5,0x71,0x04,0xE0,
+ 0x00,0x29,0x01,0xD0,0x12,0x20,0xF5,0xE7,0xE7,0x71,0x00,0x20,0x20,0x72,0x27,0xE0,
+ 0x03,0x98,0x00,0x28,0x23,0xD0,0x01,0x28,0x06,0xD0,0x02,0x28,0x06,0xD0,0x04,0x28,
+ 0x1E,0xD1,0xE0,0x79,0x80,0x07,0x0F,0xD4,0xE5,0x71,0x19,0xE0,0xE0,0x79,0x80,0x07,
+ 0xFA,0xD5,0x21,0x7A,0x00,0x29,0x04,0xD0,0x12,0x20,0xE0,0x71,0x20,0x00,0xFE,0xF7,
+ 0xF5,0xFF,0xE5,0x71,0x09,0xE0,0x0A,0xE0,0xE7,0x71,0x21,0x7A,0x00,0x29,0x04,0xD0,
+ 0x0A,0x20,0xE0,0x71,0x20,0x00,0xFE,0xF7,0xE9,0xFF,0xA5,0x71,0x00,0xE0,0xE7,0x71,
+ 0x07,0x49,0xC8,0x88,0x82,0x07,0x04,0xD1,0xE2,0x79,0x92,0x07,0x92,0x0F,0x10,0x43,
+ 0xC8,0x80,0x30,0x00,0x82,0xE7,0x00,0x00,0xA4,0x06,0x00,0x20,0x9C,0x94,0x00,0x00,
+ 0x40,0x00,0x00,0x20,0xF0,0xB4,0x13,0x4C,0x29,0x22,0x17,0x5D,0x00,0x2F,0x1F,0xD0,
+ 0x5C,0x22,0x12,0x5D,0x00,0x2A,0x1B,0xD1,0x18,0xE0,0xD5,0x00,0x2B,0x19,0x04,0x26,
+ 0x9E,0x5F,0xB0,0x42,0x0F,0xDB,0x06,0x26,0x9E,0x5F,0xB0,0x42,0x0B,0xDC,0x65,0x5F,
+ 0xA9,0x42,0x08,0xDB,0x02,0x25,0x5D,0x5F,0xA9,0x42,0x04,0xDC,0x52,0x1C,0x10,0x06,
+ 0x00,0x0E,0xF0,0xBC,0x70,0x47,0x52,0x1C,0x12,0x06,0x12,0x0E,0x97,0x42,0xE4,0xD8,
+ 0x00,0x20,0xF6,0xE7,0xA4,0x06,0x00,0x20,0xF0,0xB5,0x00,0x20,0x8F,0xB0,0x07,0x90,
+ 0xBB,0x48,0xBC,0x4C,0x00,0x68,0x26,0x00,0x01,0x68,0xFF,0x36,0x09,0x04,0x09,0x0C,
+ 0x06,0x91,0x5A,0x21,0x09,0x5C,0xA5,0x36,0x35,0x00,0x02,0x91,0x01,0x21,0x01,0x91,
+ 0x85,0x21,0x89,0x00,0x67,0x18,0x89,0x21,0x89,0x00,0x61,0x18,0x8E,0x46,0xE1,0x88,
+ 0x82,0x3D,0x8A,0x06,0x05,0xD5,0x22,0x79,0x00,0x2A,0x02,0xD1,0x20,0x22,0x91,0x43,
+ 0xE1,0x80,0x31,0x00,0x60,0x31,0x60,0x30,0x0E,0x91,0x02,0x8A,0xC9,0x88,0x94,0x46,
+ 0x91,0x42,0x04,0xD9,0x0E,0x9A,0x43,0x8A,0x12,0x89,0x9A,0x42,0x0D,0xD8,0x0E,0x9A,
+ 0x83,0x8A,0x52,0x89,0x9A,0x42,0x08,0xD8,0x61,0x45,0x04,0xD9,0x62,0x89,0x7D,0x23,
+ 0xDB,0x00,0x9A,0x42,0x01,0xD8,0x50,0x29,0x06,0xD9,0xE1,0x88,0x40,0x22,0x11,0x43,
+ 0xE1,0x80,0xC0,0x89,0x0E,0x99,0x05,0xE0,0x0E,0x99,0x0C,0x20,0x08,0x56,0x00,0x28,
+ 0x02,0xDD,0x40,0x1E,0x08,0x73,0x03,0xE0,0xE0,0x88,0x40,0x21,0x88,0x43,0xE0,0x80,
+ 0x06,0x98,0x80,0x04,0x7B,0xD5,0x70,0x46,0xFF,0x30,0x01,0x30,0x40,0x7D,0x00,0x28,
+ 0x03,0xD1,0x20,0x79,0x00,0x28,0x00,0xD1,0x01,0x90,0x00,0xF0,0x1D,0xF9,0x20,0x79,
+ 0x00,0x28,0x0D,0x90,0x34,0xD0,0x20,0x89,0x89,0x49,0x0C,0x90,0x09,0x68,0x40,0x31,
+ 0x0B,0x91,0x49,0x8A,0x88,0x42,0x2B,0xD2,0x0A,0x22,0x06,0x21,0x50,0x43,0x79,0x5E,
+ 0x0A,0x91,0xFE,0xF7,0xE9,0xFC,0x0B,0x99,0x09,0x7D,0x88,0x42,0x20,0xDA,0x0A,0x99,
+ 0x0C,0x98,0x40,0x1A,0x0A,0x21,0xFE,0xF7,0xDF,0xFC,0x0B,0x99,0x49,0x7D,0x88,0x42,
+ 0x16,0xDA,0x0B,0x98,0x39,0x88,0x80,0x7D,0x81,0x42,0x11,0xD9,0x0B,0x98,0xB9,0x68,
+ 0xC0,0x7D,0x81,0x42,0x0C,0xDA,0xEE,0x20,0x00,0x5D,0x00,0x28,0x08,0xD1,0x78,0x79,
+ 0x00,0x28,0x1B,0xD0,0x0B,0x99,0x49,0x7F,0x88,0x42,0x17,0xD8,0x40,0x1E,0x14,0xE0,
+ 0x6F,0x49,0xB8,0x68,0x09,0x68,0x40,0x31,0x0A,0x7E,0x90,0x42,0x0E,0xDB,0x0D,0x98,
+ 0x00,0x28,0x0B,0xD0,0xE0,0x88,0x00,0x06,0x08,0xD4,0x78,0x79,0xC9,0x7E,0x88,0x42,
+ 0x04,0xD2,0x02,0x99,0x88,0x42,0x01,0xD9,0x40,0x1C,0x78,0x71,0x78,0x79,0x02,0x99,
+ 0x80,0x22,0x88,0x42,0x0B,0xD8,0x01,0x98,0x01,0x28,0x08,0xD1,0xE0,0x88,0x10,0x43,
+ 0xE0,0x80,0x5F,0x48,0x00,0x68,0x40,0x30,0x00,0x7F,0x38,0x71,0x0F,0xE0,0xE0,0x88,
+ 0x01,0x06,0x0C,0xD5,0x39,0x79,0x00,0x29,0x07,0xD1,0x90,0x43,0xE0,0x80,0x58,0x48,
+ 0x00,0x68,0x40,0x30,0x40,0x7E,0x78,0x71,0x01,0xE0,0x49,0x1E,0x39,0x71,0x20,0x79,
+ 0x00,0x28,0x7E,0xD0,0x52,0x48,0x00,0x68,0x60,0x30,0x01,0x79,0x05,0x91,0xC1,0x78,
+ 0x04,0x91,0xE1,0x88,0x40,0x79,0xC9,0x06,0x08,0xD5,0x04,0x99,0x81,0x42,0x03,0xD9,
+ 0x08,0x1A,0x00,0x06,0x00,0x0E,0x00,0xE0,0x01,0x20,0x04,0x90,0x00,0x20,0x03,0x90,
+ 0x08,0x90,0xC0,0x00,0x84,0x46,0x80,0x19,0x09,0x90,0x81,0x88,0x00,0x29,0x74,0xD0,
+ 0x06,0x9A,0x00,0x20,0x92,0x07,0x08,0xD5,0x05,0x9A,0x91,0x42,0x05,0xD9,0x20,0x71,
+ 0xE0,0x88,0x20,0x21,0x08,0x43,0xE0,0x80,0x01,0x20,0x06,0x99,0x49,0x07,0x64,0xD5,
+ 0x00,0x28,0x62,0xD1,0x09,0x98,0x04,0x99,0x80,0x88,0x88,0x42,0x5D,0xD3,0x0E,0x98,
+ 0x81,0x88,0x37,0x48,0x00,0x68,0x60,0x30,0x80,0x78,0x81,0x42,0x55,0xD9,0x00,0x27,
+ 0x38,0x00,0x29,0xE0,0xC1,0x00,0x89,0x19,0x89,0x79,0x08,0x9A,0x49,0x1E,0x91,0x42,
+ 0x21,0xD1,0x0E,0x99,0x09,0x88,0xC1,0x40,0xC9,0x07,0x1C,0xD0,0x0A,0x21,0x41,0x43,
+ 0x7F,0x1C,0x49,0x19,0x89,0x7C,0x07,0x91,0x01,0x00,0x0D,0xE0,0x0A,0x22,0x4A,0x43,
+ 0x52,0x19,0x13,0x8B,0xD3,0x81,0x53,0x8B,0x13,0x82,0x13,0x7F,0x93,0x74,0xCA,0x00,
+ 0x92,0x19,0x93,0x7B,0x49,0x1C,0x93,0x71,0x22,0x79,0x8A,0x42,0xEE,0xDC,0x21,0x79,
+ 0x49,0x1E,0x40,0x1E,0x21,0x71,0x40,0x1C,0x21,0x79,0x81,0x42,0xD2,0xDC,0x00,0x2F,
+ 0x23,0xD0,0x01,0x2F,0x01,0xDD,0x01,0x20,0x03,0x90,0x20,0x79,0x0A,0x21,0x40,0x1C,
+ 0x07,0x06,0x3F,0x0E,0x60,0x46,0x27,0x71,0x30,0x5E,0xFE,0xF7,0x0D,0xFC,0x0A,0x21,
+ 0x00,0xE0,0x21,0xE0,0x4F,0x43,0x79,0x19,0x88,0x80,0x09,0x99,0x02,0x20,0x08,0x5E,
+ 0x0A,0x21,0xFE,0xF7,0x01,0xFC,0x21,0x79,0x0A,0x22,0x51,0x43,0x49,0x19,0xC8,0x80,
+ 0x20,0x79,0x07,0x99,0x50,0x43,0x40,0x19,0x01,0x72,0x08,0x98,0x40,0x1C,0x0C,0x28,
+ 0x08,0x90,0x00,0xDA,0x7D,0xE7,0x03,0x99,0x10,0x20,0x00,0x29,0xE1,0x88,0x01,0xD0,
+ 0x01,0x43,0x00,0xE0,0x81,0x43,0xE1,0x80,0x0F,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,
+ 0xE8,0x07,0x00,0x20,0x40,0x00,0x00,0x20,0xF0,0xB5,0x5F,0x48,0xBD,0xB0,0x01,0x90,
+ 0x5F,0x48,0x60,0x4C,0x00,0x68,0x5D,0x4E,0x40,0x30,0x01,0x7B,0x37,0x91,0x45,0x7B,
+ 0x49,0x00,0x36,0x95,0x60,0x78,0x40,0x1A,0x35,0x90,0x21,0x78,0x68,0x00,0x3C,0x90,
+ 0x08,0x1A,0x34,0x90,0x01,0x98,0x00,0x21,0xC1,0x80,0x01,0x98,0x81,0x60,0x33,0x91,
+ 0x32,0x91,0x60,0x21,0x1A,0xA8,0xFE,0xF7,0x5F,0xFD,0x60,0x21,0x02,0xA8,0xFE,0xF7,
+ 0x5B,0xFD,0x20,0x00,0x00,0x78,0x36,0x9D,0x39,0x90,0x40,0x1B,0x38,0x90,0x50,0xE0,
+ 0x69,0x00,0x3B,0x91,0x61,0x78,0x37,0x98,0x09,0x1A,0x3A,0x91,0x36,0x99,0x69,0x1A,
+ 0x8C,0x00,0x15,0xE0,0x39,0x99,0x43,0x00,0x41,0x43,0x9B,0x19,0x30,0x27,0x3B,0x9A,
+ 0xDF,0x5F,0x45,0x4B,0x49,0x19,0xB2,0x5E,0x49,0x00,0x59,0x5E,0xD2,0x19,0x51,0x18,
+ 0x33,0x9A,0x52,0x18,0x33,0x92,0x1A,0xAA,0x13,0x59,0x59,0x18,0x40,0x1C,0x11,0x51,
+ 0x3A,0x99,0x81,0x42,0xE6,0xDC,0x1A,0xAF,0x38,0x59,0x35,0x99,0xFE,0xF7,0x8C,0xFB,
+ 0x38,0x51,0x37,0x99,0x84,0x46,0x16,0xE0,0x39,0x98,0x37,0x4A,0x48,0x43,0x40,0x19,
+ 0x40,0x00,0x12,0x5E,0x60,0x46,0x12,0x1A,0x3B,0x98,0x33,0x5E,0x48,0x00,0x87,0x19,
+ 0x30,0x20,0x38,0x5E,0x18,0x18,0x12,0x18,0x17,0x00,0x57,0x43,0x02,0xA8,0x03,0x59,
+ 0xDA,0x19,0x49,0x1C,0x02,0x51,0x3A,0x98,0x88,0x42,0xE5,0xDC,0x35,0x99,0x02,0xAF,
+ 0x38,0x59,0x49,0x1E,0xFE,0xF7,0x68,0xFB,0x38,0x51,0x32,0x99,0x40,0x18,0x6D,0x1C,
+ 0x32,0x90,0x38,0x98,0x23,0x4C,0xA8,0x42,0xAA,0xDC,0x34,0x99,0x32,0x98,0xFE,0xF7,
+ 0x5B,0xFB,0x06,0x00,0x34,0xA8,0x03,0xC8,0x41,0x43,0x33,0x98,0xFE,0xF7,0x54,0xFB,
+ 0x05,0x04,0x01,0x98,0x2D,0x14,0x00,0x21,0x02,0xAA,0xC5,0x80,0x0A,0xE0,0x88,0x00,
+ 0x10,0x58,0x30,0x1A,0x03,0x00,0x43,0x43,0x01,0x98,0x80,0x68,0x18,0x18,0x01,0x9B,
+ 0x49,0x1C,0x98,0x60,0x20,0x78,0x3C,0x9B,0xC0,0x1A,0x88,0x42,0xEF,0xDC,0x01,0x98,
+ 0x34,0x99,0x80,0x68,0x49,0x1E,0xFE,0xF7,0x37,0xFB,0x01,0x99,0x88,0x60,0x22,0x78,
+ 0x36,0x99,0x63,0x78,0x51,0x1A,0x37,0x9A,0x9A,0x1A,0x92,0x02,0x51,0x43,0xFE,0xF7,
+ 0x2B,0xFB,0x01,0x99,0x00,0x2D,0x88,0x60,0x02,0xD1,0x01,0x98,0x6D,0x1C,0xC5,0x80,
+ 0x3D,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x54,0x02,0x00,0x20,0xCA,0x00,0x00,0x20,
+ 0xE8,0x07,0x00,0x20,0x9C,0x94,0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x48,0x00,0xB5,
+ 0x41,0x68,0x09,0x07,0x0D,0xD5,0xC1,0x68,0x00,0x29,0x0A,0xD0,0xC0,0x68,0x07,0x28,
+ 0x05,0xD1,0x01,0x21,0x49,0x07,0xC8,0x63,0x01,0x20,0x08,0xBC,0x18,0x47,0x04,0xF0,
+ 0x9B,0xF9,0x00,0x20,0xF9,0xE7,0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x20,0x70,0x47,
+ 0xF8,0xB5,0x40,0x4C,0x20,0x68,0x00,0x04,0x00,0x0C,0x05,0xF0,0xBF,0xF9,0x05,0xF0,
+ 0xA1,0xF9,0x01,0x27,0x7F,0x03,0x38,0x00,0xFE,0xF7,0xA8,0xFF,0xFE,0xF7,0xC6,0xFC,
+ 0x00,0x20,0x04,0xF0,0xD3,0xFC,0x01,0x20,0x04,0xF0,0x64,0xFC,0x00,0xF0,0xB4,0xFC,
+ 0x1F,0x20,0x01,0xF0,0x43,0xFC,0x34,0x4D,0x34,0x4E,0x5B,0xE0,0x20,0x68,0x00,0x04,
+ 0x00,0x0C,0x05,0xF0,0xA3,0xF9,0x80,0x20,0xFE,0xF7,0x90,0xFF,0x03,0x20,0x05,0xF0,
+ 0xD7,0xF8,0x38,0x00,0xFE,0xF7,0x8A,0xFF,0x00,0xF0,0x6E,0xFC,0x00,0xF0,0x2A,0xFC,
+ 0x00,0xF0,0x38,0xFC,0x01,0x20,0xFE,0xF7,0x89,0xFF,0x00,0xF0,0xAD,0xFC,0x00,0xF0,
+ 0x19,0xFC,0x01,0x20,0x80,0x03,0xFE,0xF7,0x79,0xFF,0x00,0xF0,0x2B,0xFC,0x00,0xF0,
+ 0xA3,0xFC,0xFE,0xF7,0x53,0xFD,0xFF,0xF7,0xA1,0xFF,0x00,0x28,0x35,0xD1,0x03,0xF0,
+ 0x81,0xF8,0x00,0x28,0x02,0xD0,0x01,0x20,0x30,0x70,0x01,0xE0,0xFF,0xF7,0xE2,0xFB,
+ 0x03,0x20,0x40,0x03,0xFE,0xF7,0x5A,0xFF,0x30,0x78,0x00,0x28,0x06,0xD0,0x18,0x48,
+ 0x00,0x78,0x00,0x09,0x04,0x28,0x20,0xD1,0x00,0x20,0x30,0x70,0x03,0x20,0x05,0xF0,
+ 0x79,0xF8,0x00,0x90,0x03,0x20,0x05,0xF0,0xAD,0xF8,0x80,0x20,0xFE,0xF7,0x46,0xFF,
+ 0x28,0x8C,0x00,0x28,0x02,0xD0,0x40,0x1E,0x28,0x84,0x0B,0xE0,0x0D,0x48,0x00,0x78,
+ 0x00,0x28,0x07,0xD1,0x0C,0x48,0x00,0x68,0x00,0x28,0x03,0xD0,0x00,0x99,0x00,0x20,
+ 0x03,0xF0,0xF4,0xFE,0x30,0x78,0x00,0x28,0xA0,0xD0,0x05,0xF0,0x39,0xF9,0xF8,0xBC,
+ 0x08,0xBC,0x18,0x47,0x14,0x08,0x00,0x20,0x40,0x00,0x00,0x20,0x18,0x08,0x00,0x20,
+ 0xFB,0x07,0x00,0x20,0xF5,0x07,0x00,0x20,0x0C,0x08,0x00,0x20,0xF0,0xB5,0x4F,0x49,
+ 0x0C,0x23,0x08,0x79,0x0A,0x00,0xFF,0x32,0x00,0x24,0x23,0x32,0x85,0xB0,0x00,0x28,
+ 0x84,0x46,0x00,0x93,0x10,0xD1,0x0A,0x23,0x43,0x43,0x9B,0x18,0x1C,0x88,0x40,0x1C,
+ 0x00,0x06,0x5C,0x80,0x00,0x9B,0x00,0x0E,0x98,0x42,0xF4,0xDB,0x08,0x79,0xC8,0x76,
+ 0x05,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x7E,0x20,0x80,0x5A,0x00,0x28,0x04,0x90,
+ 0x3A,0xD0,0xCB,0x7E,0x00,0x20,0x00,0x2B,0x03,0x93,0x35,0xD9,0x43,0x1C,0x01,0x26,
+ 0x04,0x9D,0x9E,0x40,0x35,0x42,0x02,0x93,0x28,0xD0,0x0A,0x23,0x58,0x43,0x86,0x18,
+ 0xB6,0x1C,0x00,0x20,0x63,0x46,0x00,0x2B,0x20,0xD9,0x33,0x78,0x01,0x93,0x5B,0x1E,
+ 0x9E,0x46,0x0A,0x23,0x43,0x43,0x9B,0x18,0x1D,0x78,0xAE,0x45,0x11,0xDC,0x01,0x9F,
+ 0x7F,0x1C,0xAF,0x42,0x0D,0xD3,0x75,0x78,0x5B,0x78,0x6F,0x1E,0x9F,0x42,0x08,0xDC,
+ 0x6D,0x1C,0x9D,0x42,0x05,0xD3,0x43,0x1C,0x01,0x25,0x9D,0x40,0x25,0x43,0x2C,0x04,
+ 0x24,0x0C,0x40,0x1C,0x00,0x06,0x00,0x0E,0x84,0x45,0xE2,0xD8,0x02,0x98,0x03,0x9B,
+ 0x00,0x06,0x00,0x0E,0x83,0x42,0xC9,0xD8,0x00,0x9B,0x00,0x20,0x00,0x2B,0x0A,0xDD,
+ 0x0A,0x23,0x43,0x43,0x9B,0x18,0x1D,0x88,0x40,0x1C,0x00,0x06,0x5D,0x80,0x00,0x9B,
+ 0x00,0x0E,0x98,0x42,0xF4,0xDB,0x0D,0x79,0x00,0x2D,0xCD,0x76,0x23,0xD0,0x20,0x00,
+ 0xE8,0x40,0xC0,0x07,0x1B,0xD0,0x60,0x46,0x00,0x28,0x03,0xD0,0x40,0x1E,0x00,0x06,
+ 0x00,0x0E,0x84,0x46,0x0B,0x79,0x28,0x00,0xAB,0x42,0x10,0xD9,0x0A,0x23,0x43,0x43,
+ 0x9B,0x18,0x1F,0x88,0x1E,0x00,0x40,0x3E,0xF7,0x86,0xDF,0x89,0x40,0x1C,0x00,0x06,
+ 0x9F,0x80,0x1E,0x8A,0x00,0x0E,0xDE,0x80,0x0B,0x79,0x83,0x42,0xEE,0xD8,0x6D,0x1E,
+ 0x2D,0x06,0x2D,0x0E,0xDB,0xD1,0x60,0x46,0x08,0x71,0x08,0x79,0x00,0x28,0x00,0xD0,
+ 0x7E,0xE7,0x88,0x81,0x05,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,
+ 0x0C,0x21,0x48,0x43,0x10,0x49,0x70,0xB5,0x40,0x18,0x10,0x49,0x10,0x4D,0x44,0x18,
+ 0x00,0x20,0xC0,0x43,0x20,0x80,0x60,0x80,0xA0,0x80,0xE0,0x80,0x08,0x22,0x00,0x21,
+ 0xA8,0x1D,0xFE,0xF7,0x47,0xFB,0x28,0x00,0x14,0x22,0x00,0x21,0x0E,0x30,0xFE,0xF7,
+ 0x41,0xFB,0x00,0x20,0x02,0x00,0x81,0x00,0x09,0x19,0x0A,0x81,0x40,0x1E,0x4A,0x81,
+ 0xF9,0xD5,0x70,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0xCA,0x05,0x00,0x00,
+ 0x82,0x06,0x00,0x20,0x10,0xB5,0x00,0xF0,0xA7,0xF8,0x00,0xF0,0x87,0xF8,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0xF8,0xB5,0x15,0x4D,0x15,0x4E,0x28,0x00,0x34,0x00,0xB4,0x34,
+ 0x0C,0x22,0x00,0x21,0xFC,0x30,0xFE,0xF7,0x1D,0xFB,0x78,0x22,0x00,0x21,0x28,0x00,
+ 0xFE,0xF7,0x18,0xFB,0x00,0x27,0xFF,0x20,0x15,0x30,0x47,0x55,0x30,0x00,0x28,0x22,
+ 0x39,0x00,0x34,0x30,0xFE,0xF7,0x0E,0xFB,0x5D,0x20,0x87,0x55,0x04,0x22,0x00,0x21,
+ 0x20,0x00,0xFE,0xF7,0x07,0xFB,0x30,0x22,0x00,0x21,0x20,0x1D,0xFE,0xF7,0x02,0xFB,
+ 0x36,0x20,0x07,0x55,0xA7,0x86,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x64,0x02,0x00,0x20,
+ 0xA4,0x06,0x00,0x20,0x10,0xB5,0x00,0x24,0x20,0x00,0x00,0xF0,0x07,0xF8,0x64,0x1C,
+ 0x0C,0x2C,0xF9,0xDB,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x12,0x49,0x10,0xB4,
+ 0x09,0x68,0x80,0x31,0xCC,0x7F,0x34,0x21,0x48,0x43,0x10,0x49,0x40,0x18,0x10,0x49,
+ 0x40,0x18,0x08,0x21,0x00,0x23,0x8A,0x00,0x12,0x18,0x93,0x80,0x49,0x1E,0xD3,0x80,
+ 0xF9,0xD5,0x01,0x00,0x01,0x22,0x20,0x31,0x0A,0x72,0x43,0x85,0x0C,0x73,0x4B,0x73,
+ 0x02,0x21,0x4A,0x00,0x12,0x18,0x49,0x1E,0xD3,0x85,0xFA,0xD5,0x00,0x21,0xC9,0x43,
+ 0x01,0x80,0x41,0x80,0x10,0xBC,0x70,0x47,0xE8,0x07,0x00,0x20,0x40,0x00,0x00,0x20,
+ 0x5A,0x03,0x00,0x00,0x78,0x47,0xC0,0x46,0x10,0x40,0x2D,0xE9,0x24,0x40,0x9F,0xE5,
+ 0x60,0x20,0xA0,0xE3,0x69,0x0F,0x84,0xE2,0x00,0x10,0xA0,0xE3,0x64,0xF9,0xFF,0xEB,
+ 0x00,0x00,0xA0,0xE3,0x22,0x1E,0xA0,0xE3,0xBE,0x01,0xC4,0xE1,0xB4,0x00,0x81,0xE1,
+ 0x10,0x40,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,0x40,0x00,0x00,0x20,0x78,0x47,0xC0,0x46,
+ 0x0C,0x00,0x9F,0xE5,0x00,0x10,0xA0,0xE3,0xF1,0x10,0xC0,0xE5,0xF0,0x10,0xC0,0xE5,
+ 0x1E,0xFF,0x2F,0xE1,0x40,0x00,0x00,0x20,0x10,0xB5,0x06,0x4C,0x78,0x22,0x20,0x00,
+ 0xFF,0x30,0x23,0x30,0x00,0x21,0xFE,0xF7,0x8D,0xFA,0x00,0x20,0x20,0x71,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0x10,0xB5,0x04,0x48,0x1C,0x22,0x00,0x21,
+ 0xFE,0xF7,0x80,0xFA,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x7E,0x03,0x00,0x20,
+ 0x10,0xB5,0x04,0xF0,0x43,0xFF,0x01,0xF0,0x67,0xFC,0x03,0xF0,0xDF,0xFF,0xFF,0xF7,
+ 0x79,0xFF,0x01,0xF0,0xA9,0xFB,0x03,0x49,0x00,0x20,0x48,0x71,0x88,0x76,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0x70,0xB5,0x01,0x25,0x6D,0x07,0x0D,0x4C,
+ 0x1C,0x21,0x28,0x00,0xFE,0xF7,0x70,0xFA,0x20,0x68,0x68,0x60,0x00,0x20,0x02,0x21,
+ 0x82,0x00,0x12,0x19,0x52,0x68,0x00,0x2A,0x03,0xD0,0x8B,0x00,0x5B,0x19,0x1A,0x60,
+ 0x49,0x1C,0x40,0x1C,0x0A,0x28,0xF3,0xD3,0x20,0x34,0xA0,0x7D,0x28,0x60,0x70,0xBC,
+ 0x08,0xBC,0x18,0x47,0x58,0x07,0x00,0x20,0x09,0x4B,0x10,0xB4,0x1B,0x68,0xA0,0x33,
+ 0x1B,0x7B,0x04,0x1E,0x00,0xDC,0x44,0x42,0x9C,0x42,0x06,0xDD,0x98,0x42,0x01,0xDD,
+ 0xC8,0x1A,0x00,0xE0,0xC8,0x18,0x02,0x04,0x12,0x0C,0x10,0xBC,0x10,0x00,0x70,0x47,
+ 0xE8,0x07,0x00,0x20,0xF7,0xB5,0x66,0x48,0xFF,0xB0,0x00,0x78,0xC1,0xB0,0x00,0x28,
+ 0x75,0xD0,0x64,0x4C,0xE0,0x78,0x00,0x28,0x03,0xD0,0x01,0x20,0xBC,0x90,0x00,0x20,
+ 0x02,0xE0,0x00,0x20,0xBC,0x90,0x01,0x20,0xBB,0x90,0x5F,0x48,0x00,0x27,0xBF,0x90,
+ 0x5C,0x48,0x20,0x30,0x41,0x8B,0x3E,0x00,0x04,0x91,0x81,0x8B,0x03,0x91,0xC1,0x8A,
+ 0x02,0x91,0x01,0x8B,0x01,0x91,0x80,0x8A,0xBA,0x90,0x58,0x48,0x80,0x7C,0xBE,0x97,
+ 0x00,0x90,0x71,0xE0,0x00,0x25,0x69,0xE0,0x70,0x43,0x40,0x19,0xBD,0x90,0x29,0x00,
+ 0x30,0x00,0x01,0xF0,0x79,0xF8,0x61,0x79,0xC9,0x07,0x2D,0xD0,0x50,0x49,0x09,0x78,
+ 0x00,0x29,0x00,0x99,0x11,0xD0,0x8E,0x42,0x26,0xD1,0xA1,0x7A,0xA9,0x42,0x1D,0xD0,
+ 0xE1,0x7A,0xA9,0x42,0x1A,0xD0,0x21,0x7B,0xA9,0x42,0x17,0xD0,0x61,0x7B,0xA9,0x42,
+ 0x14,0xD0,0xA1,0x7B,0xA9,0x42,0x48,0xD1,0x10,0xE0,0x8D,0x42,0x14,0xD1,0xA1,0x7A,
+ 0xB1,0x42,0x0B,0xD0,0xE1,0x7A,0xB1,0x42,0x08,0xD0,0x21,0x7B,0xB1,0x42,0x05,0xD0,
+ 0x61,0x7B,0xB1,0x42,0x02,0xD0,0xA1,0x7B,0xB1,0x42,0x36,0xD1,0x04,0x99,0x03,0x9A,
+ 0x41,0x18,0x09,0x04,0x09,0x0C,0x04,0xE0,0x02,0x99,0x01,0x9A,0x41,0x18,0x09,0x04,
+ 0x09,0x0C,0x80,0x1A,0x02,0x04,0xBD,0x98,0xBF,0x9B,0x80,0x00,0x18,0x58,0xC1,0x9B,
+ 0x12,0x0C,0x00,0x2B,0x02,0xD0,0x00,0x05,0x00,0x0D,0x01,0xE0,0x00,0x01,0x00,0x0D,
+ 0xC0,0x9B,0x05,0x2B,0x11,0xD8,0x90,0x42,0x02,0xDA,0xBC,0x9A,0x03,0xE0,0x4A,0xE0,
+ 0x88,0x42,0x12,0xDD,0xBB,0x9A,0x29,0x00,0x30,0x00,0x00,0xF0,0x8B,0xF8,0xBD,0x98,
+ 0x79,0x00,0x05,0xAA,0x7F,0x1C,0x50,0x52,0x07,0xE0,0xBD,0xA8,0x03,0xC8,0x05,0xAA,
+ 0x49,0x00,0x50,0x52,0xBE,0x98,0x40,0x1C,0xBE,0x90,0x6D,0x1C,0x1D,0x48,0x40,0x38,
+ 0x00,0x78,0xA8,0x42,0x90,0xDC,0x76,0x1C,0x1A,0x48,0x40,0x38,0x41,0x78,0xB1,0x42,
+ 0x88,0xDC,0xC0,0x98,0x05,0x28,0x03,0xD9,0x00,0x04,0xBE,0x9F,0x00,0x0C,0xBA,0x90,
+ 0x00,0x2F,0x20,0xDD,0x04,0xF0,0x2C,0xFF,0xC2,0x98,0x00,0x28,0x1B,0xD1,0x00,0xF0,
+ 0x61,0xF9,0x00,0xF0,0xD9,0xF9,0x7F,0x1E,0x15,0xD4,0x12,0x4C,0x05,0xAB,0x78,0x00,
+ 0x18,0x5A,0x82,0x00,0xBF,0x98,0x80,0x58,0x01,0x05,0xBA,0x98,0x09,0x0D,0x08,0x18,
+ 0x00,0x04,0x00,0x0C,0xA0,0x42,0x00,0xD9,0x20,0x00,0x00,0x04,0x08,0x43,0xBF,0x99,
+ 0x7F,0x1E,0x88,0x50,0xEB,0xD5,0x7F,0xB0,0x44,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,
+ 0xFC,0x07,0x00,0x20,0xDC,0x94,0x00,0x00,0xD4,0x02,0x10,0x40,0xC0,0x06,0x00,0x20,
+ 0xF4,0x07,0x00,0x20,0xFF,0x0F,0x00,0x00,0x7F,0xB5,0x18,0x48,0x00,0x78,0x80,0x28,
+ 0x28,0xD1,0x85,0x05,0x28,0x68,0x02,0x28,0x24,0xD1,0xAC,0x68,0x01,0xAA,0x20,0x05,
+ 0x00,0x0D,0x02,0x90,0x20,0x02,0x00,0x0D,0x03,0x90,0x02,0xA9,0x03,0xA8,0x6B,0x46,
+ 0x03,0xF0,0xFC,0xFF,0x40,0x1C,0x15,0xD0,0x0D,0x48,0x03,0x99,0x04,0x40,0x01,0x98,
+ 0x40,0x18,0x40,0x08,0x00,0x05,0x00,0x0A,0x04,0x43,0x00,0x98,0x02,0x99,0x40,0x00,
+ 0x40,0x18,0x03,0x21,0xFE,0xF7,0x02,0xF9,0x00,0x05,0x00,0x0D,0x21,0x0B,0x09,0x03,
+ 0x08,0x43,0xA8,0x60,0x7F,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0xFB,0x07,0x00,0x20,
+ 0xFF,0x0F,0x00,0xFF,0x30,0xB4,0x17,0x4D,0x15,0x4C,0x2D,0x78,0x45,0x43,0x68,0x18,
+ 0x45,0x00,0x60,0x5B,0x01,0x06,0x09,0x0E,0x00,0x0A,0x00,0x2B,0x07,0xD0,0x00,0x2A,
+ 0x02,0xD0,0xC9,0x18,0xC0,0x18,0x0F,0xE0,0xC0,0x1A,0xC9,0x1A,0x0C,0xE0,0x00,0x2A,
+ 0x05,0xD0,0x88,0x42,0x01,0xDD,0x49,0x1C,0x06,0xE0,0x40,0x1C,0x04,0xE0,0x88,0x42,
+ 0x01,0xDD,0x40,0x1E,0x00,0xE0,0x49,0x1E,0x4A,0x1E,0xFF,0x2A,0x05,0xD2,0x42,0x1E,
+ 0xFF,0x2A,0x02,0xD2,0x00,0x02,0x08,0x43,0x60,0x53,0x30,0xBC,0x70,0x47,0x00,0x00,
+ 0x00,0x00,0x10,0x40,0x9C,0x94,0x00,0x00,0xF0,0xB5,0x58,0x49,0x8D,0xB0,0x0F,0x78,
+ 0x55,0x4D,0x05,0x97,0x48,0x78,0x04,0x90,0x06,0x90,0x28,0x00,0x20,0x30,0x0C,0x90,
+ 0x00,0x7A,0xC2,0x07,0x0B,0xD0,0x80,0x07,0x03,0xD5,0x78,0x1E,0x03,0x22,0x05,0x90,
+ 0x03,0xE0,0x04,0x98,0x40,0x1E,0x00,0x22,0x04,0x90,0x0C,0x98,0x82,0x72,0x88,0x8B,
+ 0x0A,0x22,0x50,0x43,0x00,0x04,0x00,0x0C,0x01,0x90,0xC8,0x8B,0x50,0x43,0x00,0x04,
+ 0x00,0x0C,0x00,0x90,0x05,0x98,0x00,0x28,0x7E,0xD0,0x04,0x98,0x00,0x28,0x7E,0xD0,
+ 0x05,0x98,0x41,0x00,0x01,0x98,0xFD,0xF7,0x2F,0xFF,0x06,0x04,0x36,0x0C,0x00,0x24,
+ 0xBF,0x1C,0x0A,0xE0,0x01,0x98,0x05,0x99,0x60,0x43,0xFD,0xF7,0x25,0xFF,0x3C,0x4A,
+ 0x61,0x00,0x80,0x19,0x89,0x18,0x64,0x1C,0x48,0x84,0xBC,0x42,0xF2,0xDB,0x04,0x98,
+ 0x41,0x00,0x00,0x98,0xFD,0xF7,0x18,0xFF,0x07,0x04,0x06,0x98,0x3F,0x0C,0x00,0x24,
+ 0x80,0x1C,0x0B,0x90,0x0C,0xE0,0x00,0x98,0x04,0x99,0x60,0x43,0xFD,0xF7,0x0C,0xFF,
+ 0x2F,0x4A,0xC1,0x19,0x60,0x00,0x80,0x18,0x40,0x30,0xC1,0x82,0x0B,0x98,0x64,0x1C,
+ 0x84,0x42,0xF0,0xDB,0x0C,0x98,0x00,0x7A,0xC0,0x07,0x48,0xD0,0x00,0x24,0x40,0xE0,
+ 0x28,0x19,0x20,0x30,0xC1,0x7B,0x0C,0x98,0x00,0x7A,0x80,0x07,0x03,0xD5,0x05,0x98,
+ 0x02,0x96,0x03,0x91,0x03,0xE0,0x08,0x00,0x04,0x99,0x02,0x97,0x03,0x91,0x20,0x49,
+ 0x40,0x00,0x40,0x18,0x0A,0x90,0x40,0x8C,0x0A,0x21,0x80,0x1B,0xFD,0xF7,0xE4,0xFE,
+ 0xE1,0x00,0x09,0x91,0x49,0x19,0x08,0x91,0x88,0x80,0x03,0x98,0x18,0x49,0x40,0x00,
+ 0x40,0x18,0x40,0x30,0x07,0x90,0xC0,0x8A,0x0A,0x21,0xC0,0x1B,0xFD,0xF7,0xD4,0xFE,
+ 0x09,0x99,0x68,0x52,0x0A,0x98,0x0A,0x21,0x40,0x8C,0x80,0x19,0xFE,0xF7,0x2E,0xF8,
+ 0x08,0x99,0xC8,0x80,0x07,0x98,0x0A,0x21,0xC0,0x8A,0xC0,0x19,0xFE,0xF7,0x26,0xF8,
+ 0x08,0x99,0x48,0x80,0x02,0x98,0x0A,0x21,0x40,0x00,0xFE,0xF7,0x1F,0xF8,0x64,0x1C,
+ 0xA8,0x85,0x0C,0x98,0x40,0x7A,0x00,0xE0,0x01,0xE0,0xA0,0x42,0xB8,0xDC,0x0D,0xB0,
+ 0xF0,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0xA4,0x06,0x00,0x20,0x9C,0x94,0x00,0x00,
+ 0x40,0x00,0x00,0x20,0x02,0x49,0x08,0x68,0x04,0x22,0x90,0x43,0x08,0x60,0x70,0x47,
+ 0x00,0x90,0x00,0x40,0x02,0x48,0x01,0x68,0x04,0x22,0x11,0x43,0x01,0x60,0x70,0x47,
+ 0x00,0x90,0x00,0x40,0x02,0x48,0xC1,0x68,0x01,0x22,0x11,0x43,0xC1,0x60,0x70,0x47,
+ 0xC0,0x90,0x00,0x40,0x01,0x49,0xC8,0x68,0xC8,0x60,0x70,0x47,0x00,0x90,0x00,0x40,
+ 0x02,0x48,0x01,0x68,0x08,0x22,0x11,0x43,0x01,0x60,0x70,0x47,0x00,0x90,0x00,0x40,
+ 0xB5,0x22,0x10,0xB5,0x07,0x49,0x08,0x48,0x92,0x00,0xFE,0xF7,0x05,0xF8,0x07,0x48,
+ 0x07,0x4A,0x80,0x8F,0x01,0x04,0x01,0x43,0x06,0x48,0xFE,0xF7,0x0F,0xF8,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0xC0,0x9C,0x00,0x00,0x00,0x00,0x10,0x40,0x9C,0x94,0x00,0x00,
+ 0xA4,0x05,0x00,0x00,0xD4,0x02,0x10,0x40,0x02,0x48,0x81,0x6B,0x49,0x08,0x49,0x00,
+ 0x81,0x63,0x70,0x47,0x80,0x90,0x00,0x40,0x02,0x48,0x81,0x6B,0x01,0x22,0x11,0x43,
+ 0x81,0x63,0x70,0x47,0x80,0x90,0x00,0x40,0x10,0xB5,0x0A,0x49,0x0A,0x48,0xFC,0x22,
+ 0xFD,0xF7,0xDA,0xFF,0xFF,0x22,0x09,0x49,0x09,0x48,0xF1,0x32,0xFD,0xF7,0xD4,0xFF,
+ 0x71,0x22,0x08,0x49,0x08,0x48,0xD2,0x00,0xFD,0xF7,0xCE,0xFF,0x10,0xBC,0x08,0xBC,
+ 0x18,0x47,0x00,0x00,0xC4,0x95,0x00,0x00,0x04,0x90,0x00,0x40,0xC0,0x96,0x00,0x00,
+ 0x00,0xA0,0x00,0x40,0xC0,0x98,0x00,0x00,0x78,0x08,0x10,0x40,0x01,0x49,0x00,0x20,
+ 0x88,0x60,0x70,0x47,0x00,0x90,0x00,0x40,0x01,0x49,0x01,0x20,0x88,0x60,0x70,0x47,
+ 0x00,0x90,0x00,0x40,0x03,0x48,0x41,0x68,0x01,0x22,0x12,0x04,0x11,0x43,0x41,0x60,
+ 0x70,0x47,0x00,0x00,0x00,0xA0,0x00,0x40,0x02,0x48,0x01,0x68,0x01,0x22,0x11,0x43,
+ 0x01,0x60,0x70,0x47,0x00,0x90,0x00,0x40,0x02,0x48,0xC1,0x68,0xC9,0x07,0xFC,0xD0,
+ 0x70,0x47,0x00,0x00,0x00,0x90,0x00,0x40,0xFE,0xB5,0x5A,0x48,0x5A,0x4F,0x00,0x68,
+ 0x00,0x25,0x60,0x30,0xC0,0x8A,0x2E,0x00,0x58,0x4C,0x00,0x90,0xF8,0x1D,0xF9,0x30,
+ 0x01,0x90,0x10,0xE0,0x0A,0x20,0x70,0x43,0xC0,0x19,0x7C,0x21,0x09,0x5C,0x00,0x29,
+ 0x07,0xD0,0x7E,0x30,0x01,0xF0,0x8A,0xF8,0x00,0x28,0x02,0xD0,0x6D,0x1C,0x2D,0x06,
+ 0x2D,0x0E,0x01,0x98,0x76,0x1C,0x40,0x7D,0xB0,0x42,0xEB,0xDC,0x0C,0x20,0x20,0x5E,
+ 0x00,0x28,0x04,0xD1,0xE1,0x89,0x00,0x29,0x01,0xD1,0x0A,0x00,0x11,0xE0,0x08,0x22,
+ 0xA2,0x5E,0x11,0x1A,0x00,0x29,0x00,0xDC,0x81,0x1A,0x0A,0x22,0x0E,0x23,0xA2,0x5E,
+ 0xE3,0x5E,0x09,0x04,0x09,0x0C,0xD0,0x1A,0x00,0x28,0x00,0xDC,0x98,0x1A,0x02,0x04,
+ 0x12,0x0C,0x20,0x7E,0x00,0x28,0x04,0xD0,0xE0,0x7E,0xC8,0x28,0x01,0xD2,0x40,0x1C,
+ 0xE0,0x76,0x38,0x48,0xA6,0x7C,0x00,0x68,0x03,0x00,0x80,0x30,0x07,0x7D,0xBE,0x42,
+ 0x04,0xD2,0x26,0x7D,0x00,0x2E,0x01,0xD0,0x01,0x26,0x66,0x75,0x46,0x88,0x8E,0x42,
+ 0x01,0xD3,0x96,0x42,0x04,0xD2,0xE6,0x7C,0xC8,0x2E,0x01,0xD2,0x76,0x1C,0xE6,0x74,
+ 0x02,0x2D,0x0C,0xD2,0x46,0x88,0x8E,0x42,0x09,0xD9,0x96,0x42,0x07,0xD9,0x17,0x26,
+ 0x0F,0x27,0xA6,0x57,0xC7,0x57,0xBE,0x42,0x09,0xDA,0x76,0x1C,0x06,0xE0,0x17,0x26,
+ 0x10,0x27,0xA6,0x57,0xC7,0x57,0xBE,0x42,0x01,0xDD,0x76,0x1E,0xE6,0x75,0xE6,0x7E,
+ 0x01,0x2E,0x02,0xD9,0x7E,0x21,0xC9,0x5A,0x19,0xE0,0x02,0x2D,0x18,0xD2,0x17,0x26,
+ 0x11,0x27,0xA6,0x57,0xC7,0x57,0xBE,0x42,0x12,0xDD,0xE6,0x7C,0x87,0x7B,0xBE,0x42,
+ 0x0E,0xD2,0x86,0x88,0x8E,0x42,0x02,0xD2,0xC7,0x88,0x8F,0x42,0x04,0xD8,0x96,0x42,
+ 0x06,0xD2,0xC1,0x88,0x91,0x42,0x03,0xD9,0x7E,0x21,0xC9,0x5A,0x49,0x42,0x21,0x82,
+ 0x00,0x21,0x02,0x2D,0xA1,0x76,0x13,0xD2,0x10,0x21,0x60,0x33,0x61,0x5E,0xDA,0x8B,
+ 0xD1,0x42,0x04,0xD1,0x61,0x7E,0xC8,0x29,0x01,0xD2,0x49,0x1C,0x61,0x76,0x61,0x7E,
+ 0x82,0x7C,0x91,0x42,0x04,0xD9,0xC0,0x7C,0x81,0x42,0x01,0xD2,0x01,0x20,0xA0,0x76,
+ 0x10,0x21,0x61,0x5E,0x00,0x98,0x09,0x18,0x08,0x00,0x48,0x43,0xFE,0xBC,0x08,0xBC,
+ 0x18,0x47,0x00,0x00,0xE8,0x07,0x00,0x20,0x64,0x02,0x00,0x20,0x7E,0x03,0x00,0x20,
+ 0x78,0x47,0xC0,0x46,0xD1,0x00,0xA0,0xE3,0x01,0x00,0x50,0xE2,0xFD,0xFF,0xFF,0x2A,
+ 0x1E,0xFF,0x2F,0xE1,0x78,0x47,0xC0,0x46,0x10,0x00,0xA0,0xE3,0x01,0x00,0x50,0xE2,
+ 0xFD,0xFF,0xFF,0x2A,0x1E,0xFF,0x2F,0xE1,0x02,0x48,0x41,0x6B,0x01,0x22,0x11,0x43,
+ 0x41,0x63,0x70,0x47,0x00,0x70,0x00,0x40,0x02,0x49,0xC8,0x69,0xCA,0x13,0x90,0x43,
+ 0xC8,0x61,0x70,0x47,0x00,0x70,0x00,0x40,0x10,0x48,0x10,0xB5,0xC0,0x68,0x00,0x28,
+ 0x19,0xD0,0x01,0x06,0x09,0x0F,0x03,0x29,0x01,0xD0,0x04,0x29,0x02,0xD1,0x00,0xF0,
+ 0xB9,0xF8,0x08,0xE0,0xF0,0x21,0x01,0x40,0x20,0x29,0x02,0xD2,0x00,0xF0,0x10,0xF8,
+ 0x01,0xE0,0x03,0xF0,0xB1,0xFB,0x02,0x20,0x04,0xF0,0x2C,0xFB,0x02,0x20,0x04,0xF0,
+ 0x17,0xFB,0x04,0xF0,0xBF,0xFB,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x40,0x00,0x30,
+ 0xF1,0xB5,0x4E,0x4F,0x2E,0x20,0x78,0x60,0x78,0x69,0x80,0x06,0xFC,0xD4,0x00,0x98,
+ 0x01,0x25,0x6D,0x07,0xE8,0x63,0xBC,0x69,0x78,0x68,0x80,0x07,0xFC,0xD5,0x03,0xF0,
+ 0x93,0xFB,0x04,0xF0,0xB5,0xFB,0x00,0x98,0x45,0x49,0xFF,0x26,0x00,0x22,0x01,0x23,
+ 0x18,0x28,0x5E,0xD0,0x12,0xDC,0x10,0x28,0x49,0xD0,0x08,0xDC,0x07,0x28,0x21,0xD0,
+ 0x0A,0x28,0x22,0xD0,0x0B,0x28,0x1A,0xD0,0x0E,0x28,0x2E,0xD0,0x1E,0xE0,0x11,0x28,
+ 0x1E,0xD0,0x14,0x28,0x41,0xD0,0x16,0x28,0x45,0xD0,0x17,0xE0,0x1D,0x28,0x62,0xD0,
+ 0x06,0xDC,0x19,0x28,0x4B,0xD0,0x1A,0x28,0x12,0xD0,0x1C,0x28,0x55,0xD0,0x0D,0xE0,
+ 0x1E,0x28,0x5A,0xD0,0x1F,0x28,0x48,0xD0,0x50,0x28,0x58,0xD0,0x06,0xE0,0x0B,0x20,
+ 0xE8,0x63,0x1F,0xE0,0x00,0xF0,0xD6,0xF8,0x00,0xE0,0xCC,0x60,0xEE,0x63,0x19,0xE0,
+ 0x00,0x20,0xC0,0x43,0x03,0x21,0x09,0x07,0xC8,0x60,0x01,0x20,0x40,0x03,0xFE,0xF7,
+ 0x75,0xF9,0x00,0x98,0xFE,0xF7,0xE8,0xF8,0x0C,0xE0,0x00,0x21,0xC9,0x43,0x03,0x20,
+ 0x00,0x07,0xC1,0x60,0x01,0x20,0x40,0x03,0xFE,0xF7,0x68,0xF9,0x00,0xF0,0x6C,0xFD,
+ 0x00,0xF0,0xD3,0xF8,0x78,0x68,0x78,0x60,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x00,0x2C,
+ 0x01,0xD0,0x4B,0x70,0xDA,0xE7,0x4A,0x70,0xD8,0xE7,0x00,0x2C,0x01,0xD0,0x8B,0x70,
+ 0xD4,0xE7,0x8A,0x70,0xD2,0xE7,0x00,0x2C,0x01,0xD0,0x0B,0x71,0xCE,0xE7,0x0A,0x71,
+ 0xCC,0xE7,0x00,0x2C,0x01,0xD0,0x4B,0x71,0xC8,0xE7,0x4A,0x71,0xC6,0xE7,0x00,0x2C,
+ 0x01,0xD0,0x8B,0x71,0xC2,0xE7,0x8A,0x71,0xC0,0xE7,0x00,0x2C,0x01,0xD0,0xCC,0x71,
+ 0x00,0xE0,0xCA,0x71,0x03,0xF0,0xFE,0xFE,0xB8,0xE7,0x00,0x2C,0x01,0xD0,0x0B,0x72,
+ 0xB4,0xE7,0x0A,0x72,0xB2,0xE7,0xCC,0x61,0xB0,0xE7,0x8C,0x61,0xAE,0xE7,0x03,0x2C,
+ 0x01,0xD9,0x4A,0x72,0xAA,0xE7,0x4C,0x72,0xA8,0xE7,0x00,0x00,0x00,0x40,0x00,0x30,
+ 0xF4,0x07,0x00,0x20,0xF0,0xB5,0x35,0x4D,0x32,0x4E,0x29,0x78,0x03,0x00,0x32,0x4F,
+ 0x0C,0x04,0x69,0x78,0x32,0x48,0xB2,0x6B,0x0C,0x43,0x29,0x00,0x30,0x3B,0x40,0x31,
+ 0x04,0xF0,0xC0,0xFB,0x12,0x48,0x0A,0x0C,0x0E,0x12,0x16,0x19,0x14,0x1B,0x1F,0x2D,
+ 0x38,0x12,0x3B,0x40,0x48,0x44,0x47,0x48,0xF2,0x6B,0x3B,0xE0,0x7A,0x69,0x39,0xE0,
+ 0xA8,0x8B,0x02,0x04,0xE8,0x8B,0x23,0xE0,0x22,0x00,0x33,0xE0,0xF2,0x68,0x31,0xE0,
+ 0x24,0x48,0x42,0x68,0x2E,0xE0,0x72,0x6B,0x2C,0xE0,0x20,0x48,0x20,0x30,0x42,0x7A,
+ 0x28,0xE0,0x21,0x48,0x82,0x7C,0x48,0x79,0x89,0x79,0xC3,0x07,0xDB,0x09,0x80,0x07,
+ 0x09,0x04,0xC0,0x0F,0x00,0x02,0x1A,0x43,0x01,0x43,0x0A,0x43,0x1A,0xE0,0x88,0x7A,
+ 0x4A,0x7B,0x00,0x06,0x02,0x43,0xC8,0x7A,0x09,0x7B,0x00,0x04,0x09,0x02,0x08,0x43,
+ 0x02,0x43,0x0F,0xE0,0x88,0x7B,0x02,0x06,0x0C,0xE0,0x14,0x48,0x00,0x69,0xC2,0x07,
+ 0xD2,0x0F,0x07,0xE0,0x00,0x69,0x40,0x08,0x02,0x02,0x03,0xE0,0x00,0x69,0x42,0x08,
+ 0x00,0xE0,0x3A,0x69,0x0E,0x49,0xCA,0x61,0x5F,0x22,0x48,0x69,0x10,0x42,0xFC,0xD1,
+ 0x03,0xF0,0xA2,0xFA,0xFF,0x20,0x01,0x21,0x49,0x07,0xC8,0x63,0xF0,0xBC,0x08,0xBC,
+ 0x18,0x47,0x00,0x00,0xC0,0x9F,0x00,0x00,0xF4,0x07,0x00,0x20,0x9C,0x94,0x00,0x00,
+ 0x00,0x20,0x00,0x40,0xC0,0x91,0x00,0x00,0xC0,0x06,0x00,0x20,0xC0,0x95,0x00,0x00,
+ 0x00,0x40,0x00,0x30,0x70,0xB5,0x03,0x24,0x24,0x07,0xE5,0x68,0x00,0x20,0xC0,0x43,
+ 0xE0,0x60,0xFE,0xF7,0xB3,0xF8,0x06,0x00,0xC3,0x20,0xC0,0x01,0xFE,0xF7,0x9E,0xF8,
+ 0x02,0xF0,0xB8,0xFF,0x00,0xF0,0xCA,0xFC,0x02,0xF0,0xAA,0xFF,0x30,0x00,0xFE,0xF7,
+ 0xB9,0xF8,0xE5,0x60,0x70,0xBC,0x08,0xBC,0x18,0x47,0x00,0x20,0x03,0x21,0x10,0xB5,
+ 0xC0,0x43,0x09,0x07,0xC8,0x60,0x02,0xF0,0xA5,0xFF,0xFF,0xF7,0xAD,0xFD,0xFF,0xF7,
+ 0xB3,0xFD,0x01,0x20,0x40,0x07,0x04,0xF0,0x1A,0xFB,0x10,0xBC,0x08,0xBC,0x18,0x47,
+ 0xF0,0xB5,0x00,0x20,0x87,0xB0,0x01,0x90,0x00,0x90,0x5A,0x48,0x57,0x4C,0x00,0x68,
+ 0x57,0x4D,0x00,0x68,0xC0,0x06,0x75,0xD5,0xE0,0x1D,0xF9,0x30,0x06,0x90,0x02,0x7D,
+ 0x40,0x7D,0x01,0x21,0x82,0x42,0x00,0xD1,0x00,0x21,0x29,0x71,0x28,0x79,0x00,0x28,
+ 0x08,0xD0,0x06,0x98,0x00,0x7D,0x01,0x28,0x04,0xD1,0x21,0x88,0xE9,0x80,0x60,0x88,
+ 0x28,0x81,0x03,0xE0,0x06,0x98,0x00,0x7D,0x00,0x28,0x5B,0xD0,0x06,0x98,0x40,0x7D,
+ 0x00,0x28,0x57,0xD0,0x00,0x20,0x6E,0xE0,0x06,0x99,0x03,0x9F,0x4B,0x7D,0x0A,0x21,
+ 0x4F,0x43,0x00,0x20,0x3E,0x19,0x62,0xE0,0x0A,0x22,0x42,0x43,0x12,0x19,0x60,0x32,
+ 0x31,0x79,0x12,0x7F,0x91,0x42,0x59,0xD1,0x0A,0x21,0x48,0x43,0x01,0x19,0xE2,0x5F,
+ 0x60,0x31,0x18,0x20,0x05,0x91,0x04,0x91,0x08,0x5E,0x1A,0x23,0xCB,0x5E,0x10,0x1A,
+ 0x02,0x22,0xB2,0x5E,0xD1,0x1A,0x02,0x91,0x04,0x99,0x0A,0x8B,0xE1,0x5B,0xFF,0xF7,
+ 0xBB,0xFA,0xE0,0x53,0x04,0x99,0x02,0x98,0x4A,0x8B,0x71,0x88,0xFF,0xF7,0xB4,0xFA,
+ 0x00,0x04,0x00,0x14,0x70,0x80,0xE1,0x5F,0xFF,0x22,0xE1,0x32,0x91,0x42,0x38,0xDA,
+ 0x19,0x22,0x52,0x01,0x90,0x42,0x34,0xDA,0x06,0x9A,0x12,0x7D,0x01,0x2A,0x0D,0xD1,
+ 0x06,0x22,0xAA,0x5E,0x52,0x1A,0x0C,0x32,0x18,0x2A,0x05,0xD8,0x08,0x22,0xAA,0x5E,
+ 0x12,0x1A,0x0C,0x32,0x18,0x2A,0x01,0xD9,0x00,0x20,0x1D,0xE0,0x0A,0x00,0xFF,0x23,
+ 0x25,0x3A,0x98,0x33,0x9A,0x42,0x06,0xD3,0x1F,0x4A,0x90,0x42,0x03,0xDD,0x01,0x22,
+ 0x00,0x92,0x03,0xE0,0x2E,0xE0,0x00,0x9A,0x00,0x2A,0x12,0xD0,0x05,0x9B,0x18,0x22,
+ 0x9A,0x5E,0x51,0x1A,0x09,0x31,0x12,0x29,0x0B,0xD8,0x1A,0x21,0x59,0x5E,0x08,0x1A,
+ 0x00,0x1D,0x08,0x28,0x05,0xD8,0x01,0x20,0x01,0x90,0x02,0xE0,0x40,0x1C,0x83,0x42,
+ 0x9A,0xDC,0x03,0x98,0x40,0x1C,0x03,0x90,0x06,0x98,0x03,0x99,0x00,0x7D,0x88,0x42,
+ 0x8A,0xDC,0x01,0x98,0x00,0x28,0x08,0xD0,0x0C,0x48,0xFF,0x21,0x40,0x89,0x91,0x31,
+ 0x88,0x42,0x02,0xD2,0x28,0x68,0x40,0x1C,0x03,0xE0,0x28,0x68,0x00,0x28,0x01,0xD0,
+ 0x40,0x1E,0x28,0x60,0x07,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x64,0x02,0x00,0x20,
+ 0xDC,0x07,0x00,0x20,0xE8,0x07,0x00,0x20,0xAB,0x02,0x00,0x00,0x40,0x00,0x00,0x20,
+ 0xF0,0xB5,0x00,0x20,0xA9,0xB0,0x0E,0x90,0x0D,0x90,0x0C,0x90,0xFF,0x4B,0x0B,0x90,
+ 0x1A,0x68,0x10,0x00,0x80,0x30,0x41,0x7F,0x80,0x7F,0x09,0x90,0x10,0x00,0xA0,0x30,
+ 0xC4,0x7A,0x08,0x94,0x84,0x7A,0x07,0x94,0xF9,0x4C,0x05,0x94,0xFF,0x3C,0x1B,0x3C,
+ 0x04,0x94,0x12,0x68,0x12,0x07,0x25,0xD5,0x02,0x78,0x4A,0x43,0x23,0x92,0x42,0x78,
+ 0x4A,0x43,0x22,0x92,0x82,0x78,0x4A,0x43,0x21,0x92,0xC2,0x78,0x4A,0x43,0x20,0x92,
+ 0x02,0x79,0x4A,0x43,0x1F,0x92,0x42,0x79,0x4A,0x43,0x1E,0x92,0x82,0x79,0x4A,0x43,
+ 0x1D,0x92,0xC2,0x79,0x4A,0x43,0x1C,0x92,0x02,0x7A,0x4A,0x43,0x1B,0x92,0x40,0x7A,
+ 0x48,0x43,0x1A,0x90,0xE0,0x1D,0xF9,0x30,0x28,0x90,0x00,0x7D,0x00,0x28,0x05,0xD1,
+ 0xFF,0xF7,0x58,0xF9,0x29,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x00,0x20,0x24,0x90,
+ 0xE0,0x48,0x27,0x90,0x24,0x99,0x04,0x98,0x04,0x9A,0x41,0x18,0xFC,0x20,0x08,0x56,
+ 0x0A,0x21,0x41,0x43,0x8D,0x18,0x0A,0x3D,0x00,0x28,0x0B,0xD0,0x08,0x98,0x00,0x28,
+ 0x04,0xD1,0xA8,0x1D,0x00,0xF0,0x3A,0xFD,0x00,0x28,0x03,0xD0,0x05,0x98,0x80,0x7E,
+ 0x00,0x28,0x03,0xD0,0x24,0x98,0xFF,0xF7,0x41,0xF9,0x3F,0xE2,0x24,0x98,0x34,0x21,
+ 0x48,0x43,0xD0,0x49,0xE0,0x39,0x40,0x18,0xCF,0x49,0x44,0x18,0x07,0x20,0x81,0x00,
+ 0x09,0x19,0x8A,0x88,0x40,0x1E,0x0A,0x81,0xCA,0x88,0x4A,0x81,0xF7,0xD5,0xCB,0x48,
+ 0x00,0x22,0x81,0x8B,0xAA,0x5E,0x49,0x1E,0x8A,0x42,0xE6,0xDC,0xC0,0x8B,0x02,0x21,
+ 0x69,0x5E,0x40,0x1E,0x81,0x42,0xE0,0xDC,0x28,0x88,0x01,0x23,0xDB,0x02,0xA0,0x80,
+ 0x68,0x88,0x9C,0x46,0xE0,0x80,0x00,0x20,0x02,0x00,0x07,0x21,0x06,0x90,0x88,0x00,
+ 0x00,0x19,0x04,0x26,0x86,0x5F,0x00,0x2E,0x08,0xDD,0x06,0x9F,0xBE,0x42,0x01,0xDD,
+ 0x87,0x88,0x06,0x97,0x66,0x45,0x01,0xDA,0x86,0x88,0xB4,0x46,0x06,0x26,0x86,0x5F,
+ 0x00,0x2E,0x05,0xDD,0x96,0x42,0x00,0xDD,0xC2,0x88,0x9E,0x42,0x00,0xDA,0xC3,0x88,
+ 0x49,0x1E,0xE4,0xD5,0x06,0x99,0x60,0x46,0x0E,0x1A,0xAC,0x48,0x01,0x68,0x80,0x20,
+ 0x40,0x5A,0x86,0x42,0x02,0xDC,0xD7,0x1A,0x87,0x42,0x02,0xDD,0x05,0x9F,0x01,0x20,
+ 0x38,0x76,0xA0,0x31,0x48,0x8B,0x86,0x42,0x04,0xDA,0xD1,0x1A,0x81,0x42,0x01,0xDA,
+ 0x01,0x20,0x00,0xE0,0x00,0x20,0x27,0x99,0x26,0x00,0x20,0x36,0x08,0x74,0x30,0x7A,
+ 0x01,0x28,0x15,0xD9,0x04,0x22,0x08,0x21,0xA2,0x5E,0x61,0x5E,0x50,0x1A,0x00,0x28,
+ 0x00,0xDC,0x88,0x1A,0x00,0x04,0x00,0x14,0x0A,0x90,0x06,0x20,0x0A,0x22,0x20,0x5E,
+ 0xA2,0x5E,0x81,0x1A,0x00,0x29,0x00,0xDC,0x11,0x1A,0x0F,0x04,0x3F,0x14,0x01,0xE0,
+ 0x64,0x27,0x0A,0x97,0x08,0x21,0x04,0x20,0x61,0x5E,0x20,0x5E,0x03,0xF0,0xD0,0xF8,
+ 0x10,0x90,0x0A,0x21,0x06,0x20,0x61,0x5E,0x20,0x5E,0x03,0xF0,0xC9,0xF8,0x0F,0x90,
+ 0x0C,0x21,0x61,0x5E,0x10,0x98,0x03,0xF0,0xC3,0xF8,0x12,0x90,0x0E,0x21,0x61,0x5E,
+ 0x0F,0x98,0x03,0xF0,0xBD,0xF8,0x11,0x90,0x14,0x22,0x10,0x21,0xA2,0x5E,0x61,0x5E,
+ 0x12,0x98,0x03,0xF0,0xBB,0xF8,0x00,0x04,0x00,0x14,0x14,0x90,0x16,0x22,0x12,0x21,
+ 0xA2,0x5E,0x61,0x5E,0x11,0x98,0x03,0xF0,0xB1,0xF8,0x00,0x04,0x00,0x14,0x13,0x90,
+ 0x1C,0x22,0x18,0x21,0xA2,0x5E,0x61,0x5E,0x14,0x98,0x03,0xF0,0xA7,0xF8,0x00,0x04,
+ 0x00,0x14,0x16,0x90,0x1E,0x22,0x1A,0x21,0xA2,0x5E,0x61,0x5E,0x13,0x98,0x03,0xF0,
+ 0x9D,0xF8,0x00,0x04,0x00,0x14,0x15,0x90,0x24,0x22,0x20,0x21,0xA2,0x5E,0x61,0x5E,
+ 0x16,0x98,0x03,0xF0,0x93,0xF8,0x00,0x04,0x00,0x14,0x18,0x90,0x26,0x22,0x22,0x21,
+ 0xA2,0x5E,0x61,0x5E,0x15,0x98,0x03,0xF0,0x89,0xF8,0x00,0x04,0x00,0x14,0x17,0x90,
+ 0x0A,0x98,0x39,0x00,0x00,0xF0,0xFA,0xFE,0x02,0x00,0x01,0x20,0x41,0x00,0x09,0x19,
+ 0xCB,0x8D,0x40,0x1E,0x0B,0x86,0xF9,0xD5,0xE2,0x85,0x70,0x7B,0x00,0x22,0x01,0x1E,
+ 0x06,0xDB,0x43,0x00,0x1F,0x19,0x2E,0x23,0xFB,0x5E,0x9A,0x18,0x40,0x1E,0xF8,0xD5,
+ 0x49,0x1C,0x10,0x00,0xFD,0xF7,0xB0,0xF9,0x22,0x99,0x07,0x00,0x88,0x42,0x01,0xDC,
+ 0x01,0x20,0x0F,0xE0,0x20,0x98,0x87,0x42,0x01,0xDC,0x02,0x20,0x0A,0xE0,0x1E,0x98,
+ 0x87,0x42,0x01,0xDC,0x03,0x20,0x05,0xE0,0x1C,0x98,0x87,0x42,0x01,0xDC,0x04,0x20,
+ 0x00,0xE0,0x05,0x20,0x31,0x7B,0x09,0x9A,0x40,0x1A,0x52,0x42,0x00,0x28,0x08,0xDD,
+ 0x2A,0x20,0x20,0x5E,0x09,0x9B,0x98,0x42,0x01,0xD1,0x00,0x20,0x08,0xE0,0x40,0x1C,
+ 0x06,0xE0,0x00,0x28,0x4A,0x48,0x20,0x5E,0x04,0xDA,0x90,0x42,0xF5,0xD0,0x40,0x1E,
+ 0x60,0x85,0x02,0xE0,0x00,0x28,0xFA,0xDC,0xF1,0xDB,0x2A,0x20,0x20,0x5E,0x09,0x9B,
+ 0x98,0x42,0x03,0xD1,0x05,0x29,0x01,0xD2,0x49,0x1C,0x04,0xE0,0x90,0x42,0x03,0xD1,
+ 0x01,0x29,0x01,0xD9,0x49,0x1E,0x31,0x73,0x17,0xA8,0x05,0xC8,0x19,0x90,0x30,0x7A,
+ 0x01,0x00,0x26,0x90,0x25,0x90,0x10,0x00,0xFD,0xF7,0x66,0xF9,0x0C,0x90,0x0E,0x90,
+ 0x25,0x99,0x19,0x98,0xFD,0xF7,0x60,0xF9,0x0D,0x90,0x0B,0x90,0x30,0x7B,0x01,0x28,
+ 0x23,0xD1,0x0B,0xAA,0x0C,0xA9,0x6B,0x46,0x06,0xC3,0x17,0x9B,0x18,0x9A,0x26,0x98,
+ 0x09,0x21,0x03,0xF0,0xF3,0xFB,0x0D,0xAA,0x0E,0xA9,0x68,0x46,0x06,0xC0,0x30,0x7A,
+ 0x15,0x9B,0x16,0x9A,0x07,0x21,0x03,0xF0,0xE9,0xFB,0x2C,0x22,0x6B,0x46,0x9A,0x5E,
+ 0x30,0x21,0x34,0x20,0x59,0x5E,0x18,0x5E,0x03,0x92,0x01,0xAA,0x03,0xC2,0x38,0x22,
+ 0x9A,0x5E,0x22,0x9B,0x00,0x92,0x23,0x9A,0x96,0xE0,0x02,0x28,0x23,0xD1,0x0B,0xAA,
+ 0x0C,0xA9,0x6B,0x46,0x06,0xC3,0x15,0x9B,0x16,0x9A,0x26,0x98,0x07,0x21,0x03,0xF0,
+ 0xCD,0xFB,0x0D,0xAA,0x0E,0xA9,0x68,0x46,0x06,0xC0,0x30,0x7A,0x13,0x9B,0x14,0x9A,
+ 0x05,0x21,0x03,0xF0,0xC3,0xFB,0x2C,0x22,0x6B,0x46,0x9A,0x5E,0x30,0x21,0x34,0x20,
+ 0x59,0x5E,0x18,0x5E,0x03,0x92,0x01,0xAA,0x03,0xC2,0x38,0x22,0x9A,0x5E,0x20,0x9B,
+ 0x00,0x92,0x21,0x9A,0x70,0xE0,0x03,0x28,0x30,0xD1,0x0B,0xAA,0x0C,0xA9,0x6B,0x46,
+ 0x06,0xC3,0x13,0x9B,0x14,0x9A,0x26,0x98,0x05,0x21,0x03,0xF0,0xA7,0xFB,0x0D,0xAA,
+ 0x0E,0xA9,0x68,0x46,0x06,0xC0,0x30,0x7A,0x03,0x21,0x0B,0xE0,0xE8,0x07,0x00,0x20,
+ 0x7E,0x03,0x00,0x20,0x20,0x01,0x00,0x20,0x5A,0x03,0x00,0x00,0x9C,0x94,0x00,0x00,
+ 0x2A,0x00,0x00,0x00,0x11,0x9B,0x12,0x9A,0x03,0xF0,0x90,0xFB,0x2C,0x22,0x6B,0x46,
+ 0x9A,0x5E,0x30,0x21,0x34,0x20,0x59,0x5E,0x18,0x5E,0x03,0x92,0x01,0xAA,0x03,0xC2,
+ 0x38,0x22,0x9A,0x5E,0x00,0x92,0x1E,0x9B,0x1F,0x9A,0x3D,0xE0,0x04,0x28,0x23,0xD1,
+ 0x0B,0xAA,0x0C,0xA9,0x68,0x46,0x06,0xC0,0x11,0x9B,0x12,0x9A,0x26,0x98,0x03,0x21,
+ 0x03,0xF0,0x74,0xFB,0x0D,0xAA,0x0E,0xA9,0x68,0x46,0x06,0xC0,0x30,0x7A,0x0F,0x9B,
+ 0x10,0x9A,0x02,0x21,0x03,0xF0,0x6A,0xFB,0x2C,0x22,0x6B,0x46,0x9A,0x5E,0x30,0x21,
+ 0x34,0x20,0x59,0x5E,0x18,0x5E,0x03,0x92,0x01,0xAA,0x03,0xC2,0x38,0x22,0x9A,0x5E,
+ 0x1C,0x9B,0x00,0x92,0x1D,0x9A,0x17,0xE0,0x0D,0xAA,0x0E,0xA9,0x68,0x46,0x06,0xC0,
+ 0x0F,0x9B,0x10,0x9A,0x26,0x98,0x02,0x21,0x03,0xF0,0x50,0xFB,0x06,0x20,0x6B,0x46,
+ 0x20,0x5E,0x34,0x22,0x38,0x21,0x9A,0x5E,0x59,0x5E,0x01,0xAB,0x07,0xC3,0x04,0x22,
+ 0xA2,0x5E,0x1A,0x9B,0x00,0x92,0x1B,0x9A,0x39,0x00,0x28,0x00,0x03,0xF0,0x52,0xFB,
+ 0x30,0x7A,0x09,0x28,0x01,0xD2,0x40,0x1C,0x30,0x72,0x70,0x7B,0x02,0x28,0x01,0xD2,
+ 0x40,0x1C,0x70,0x73,0x28,0x79,0x34,0x21,0x40,0x1E,0x48,0x43,0x32,0x49,0x40,0x18,
+ 0x32,0x49,0x44,0x18,0x00,0x20,0x20,0x5E,0x00,0x28,0x23,0xDB,0x02,0x21,0x61,0x5E,
+ 0x00,0x29,0x1F,0xDB,0x07,0x9A,0x64,0x21,0x8E,0x1A,0x70,0x43,0xFD,0xF7,0x7C,0xF8,
+ 0x07,0x00,0x00,0x20,0x28,0x5E,0x07,0x99,0x48,0x43,0x64,0x21,0xFD,0xF7,0x74,0xF8,
+ 0x38,0x18,0x28,0x80,0x02,0x20,0x20,0x5E,0x64,0x21,0x70,0x43,0xFD,0xF7,0x6C,0xF8,
+ 0x06,0x00,0x02,0x20,0x28,0x5E,0x07,0x99,0x48,0x43,0x64,0x21,0xFD,0xF7,0x64,0xF8,
+ 0x30,0x18,0x68,0x80,0x28,0x88,0x20,0x80,0x68,0x88,0x60,0x80,0x24,0x98,0x40,0x1C,
+ 0x0C,0x28,0x24,0x90,0x00,0xDA,0x9D,0xE5,0x28,0x98,0x00,0x7D,0x01,0x28,0x18,0xD1,
+ 0x04,0x98,0x34,0x21,0x00,0x79,0x48,0x43,0x13,0x49,0x40,0x18,0x13,0x49,0x34,0x39,
+ 0x40,0x18,0x82,0x88,0x05,0x99,0x0A,0x81,0xC2,0x88,0x4A,0x81,0x02,0x89,0x05,0x99,
+ 0x8A,0x81,0x40,0x89,0xC8,0x81,0x04,0x99,0x05,0x98,0x0A,0x88,0x02,0x80,0x49,0x88,
+ 0x41,0x80,0x28,0x98,0x00,0x7D,0x02,0x28,0x00,0xD0,0x73,0xE5,0x04,0x99,0x05,0x98,
+ 0x0A,0x88,0x02,0x80,0x49,0x88,0x41,0x80,0x04,0x99,0x05,0x98,0x4A,0x89,0x82,0x80,
+ 0x89,0x89,0xC1,0x80,0x66,0xE5,0x00,0x00,0x40,0x00,0x00,0x20,0x5A,0x03,0x00,0x00,
+ 0x01,0xC0,0x8F,0xE2,0x1C,0xFF,0x2F,0xE1,0xF8,0xB5,0xFF,0x20,0xFD,0xF7,0x00,0xFD,
+ 0x03,0x25,0x0F,0x4E,0x2D,0x07,0x01,0x27,0xF0,0x6A,0x00,0x28,0x15,0xD0,0xF0,0x6B,
+ 0xE9,0x68,0x80,0x08,0x3C,0x00,0x84,0x40,0x21,0x43,0xE9,0x60,0x69,0x68,0x21,0x42,
+ 0x00,0xD0,0x34,0x63,0x81,0x00,0x07,0x48,0x40,0x58,0x00,0x28,0x01,0xD0,0x03,0xF0,
+ 0x56,0xFF,0xE8,0x68,0xA0,0x43,0xE8,0x60,0xE6,0xE7,0xF8,0xBC,0x08,0xBC,0x18,0x47,
+ 0x40,0x00,0x00,0x30,0x0C,0x71,0x00,0x00,0xF8,0xB5,0x1D,0x4A,0x93,0x8F,0x40,0x32,
+ 0x54,0x79,0xE4,0x07,0x32,0xD0,0x14,0x89,0x1A,0x4A,0x92,0x7C,0x96,0x46,0x1A,0x4A,
+ 0x16,0x78,0x17,0x4A,0x40,0x32,0x95,0x7A,0x00,0x2E,0x76,0x46,0xAC,0x46,0xD5,0x7A,
+ 0x00,0x95,0x15,0x7B,0x57,0x7B,0x92,0x7B,0x12,0xD0,0xB0,0x42,0x1E,0xD1,0x8C,0x45,
+ 0x08,0xD0,0x00,0x98,0x88,0x42,0x05,0xD0,0x8D,0x42,0x03,0xD0,0x8F,0x42,0x01,0xD0,
+ 0x8A,0x42,0x03,0xD1,0x20,0x00,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x00,0x20,0xFA,0xE7,
+ 0xB1,0x42,0x0B,0xD1,0x84,0x45,0xF5,0xD0,0x00,0x99,0x81,0x42,0xF2,0xD0,0x85,0x42,
+ 0xF0,0xD0,0x87,0x42,0xEE,0xD0,0x82,0x42,0xF0,0xD1,0xEB,0xE7,0x18,0x00,0xEA,0xE7,
+ 0x9C,0x94,0x00,0x00,0xC0,0x06,0x00,0x20,0xF4,0x07,0x00,0x20,0x70,0x47,0x00,0x00,
+ 0x04,0x4A,0x03,0x4B,0x12,0x78,0x42,0x43,0x50,0x18,0x40,0x00,0x18,0x5A,0x70,0x47,
+ 0x00,0x00,0x10,0x40,0x9C,0x94,0x00,0x00,0x70,0xB5,0x28,0x49,0x00,0x20,0x4A,0x78,
+ 0x27,0x49,0x00,0x2A,0x14,0xD1,0x0A,0x89,0x00,0x2A,0x0E,0xD0,0x25,0x49,0x8A,0x42,
+ 0x0B,0xD0,0x10,0x00,0x64,0x21,0x48,0x43,0xFD,0xF7,0xF8,0xF8,0x22,0x49,0x40,0x18,
+ 0xE1,0x21,0x89,0x00,0x88,0x42,0x00,0xD9,0x08,0x00,0x70,0xBC,0x08,0xBC,0x18,0x47,
+ 0x88,0x89,0x1A,0x49,0x40,0x39,0x4A,0x7F,0x19,0x49,0x89,0x89,0xFF,0x39,0x60,0x39,
+ 0x01,0x2A,0x0F,0xD1,0x18,0x4A,0x7D,0x25,0x63,0x32,0xED,0x00,0x91,0x42,0x04,0xD8,
+ 0x2C,0x1A,0x20,0x00,0x60,0x43,0x56,0x1C,0x0D,0xE0,0xA8,0x42,0xE5,0xD9,0x03,0x21,
+ 0x40,0x1B,0x17,0xE0,0x10,0x4A,0x11,0x4D,0xC7,0x32,0x91,0x42,0x0C,0xD8,0x2C,0x1A,
+ 0x20,0x00,0x60,0x43,0x56,0x1C,0x31,0x00,0xFD,0xF7,0xC8,0xF8,0x60,0x43,0x31,0x00,
+ 0xFD,0xF7,0xC4,0xF8,0x28,0x1A,0xD0,0xE7,0xA8,0x42,0xCE,0xD9,0x07,0x4A,0x03,0x21,
+ 0x52,0x42,0x80,0x18,0xFD,0xF7,0xBA,0xF8,0x40,0x19,0xC6,0xE7,0x00,0x07,0x00,0x20,
+ 0x40,0x00,0x00,0x20,0xFF,0x0F,0x00,0x00,0x26,0x02,0x00,0x00,0x4C,0x04,0x00,0x00,
+ 0x04,0x48,0x41,0x69,0x49,0x06,0x01,0xD5,0x10,0x20,0x70,0x47,0x40,0x69,0xC0,0x06,
+ 0xC0,0x0E,0x70,0x47,0x00,0x40,0x00,0x30,0x70,0xB5,0x12,0x4D,0x00,0x24,0x01,0x21,
+ 0x49,0x07,0x68,0x69,0x80,0x06,0xFC,0xD4,0xE8,0x68,0x6A,0x68,0x6A,0x60,0x05,0xE0,
+ 0x6A,0x69,0x92,0x06,0xFC,0xD4,0xAA,0x69,0x04,0xC1,0xA4,0x18,0x02,0x00,0x40,0x1E,
+ 0x01,0x2A,0xF5,0xD8,0x2E,0x20,0x68,0x60,0x68,0x68,0x80,0x07,0xFC,0xD5,0x02,0xF0,
+ 0xBB,0xFD,0x05,0x48,0xE8,0x61,0xEC,0x61,0x68,0x69,0x80,0x06,0xFC,0xD4,0x70,0xBC,
+ 0x08,0xBC,0x18,0x47,0x00,0x40,0x00,0x30,0xAB,0xFC,0xFF,0x8F,0x78,0x47,0xC0,0x46,
+ 0x10,0x40,0x2D,0xE9,0xB0,0x40,0x9F,0xE5,0x0C,0x00,0x94,0xE5,0x00,0x00,0x50,0xE3,
+ 0xFC,0xFF,0xFF,0x0A,0x04,0x00,0x94,0xE5,0x04,0x00,0x84,0xE5,0x04,0x00,0x94,0xE5,
+ 0x04,0x00,0x10,0xE3,0x10,0x00,0x00,0x0A,0x0C,0x00,0x94,0xE5,0x04,0x10,0x90,0xE4,
+ 0x1C,0x10,0x84,0xE5,0x02,0x12,0xA0,0xE3,0x38,0x10,0x91,0xE5,0x04,0x00,0x00,0xEA,
+ 0x04,0x20,0x90,0xE4,0x1C,0x20,0x84,0xE5,0x14,0x20,0x94,0xE5,0x40,0x00,0x12,0xE3,
+ 0xFC,0xFF,0xFF,0x1A,0x01,0x10,0x51,0xE2,0xF8,0xFF,0xFF,0x1A,0x14,0x00,0x94,0xE5,
+ 0x5F,0x00,0x10,0xE3,0xFC,0xFF,0xFF,0x1A,0x11,0x00,0x00,0xEA,0x04,0x00,0x94,0xE5,
+ 0x02,0x00,0x10,0xE3,0xE8,0xFF,0xFF,0x0A,0x14,0x00,0x94,0xE5,0x20,0x00,0x10,0xE3,
+ 0xE5,0xFF,0xFF,0x1A,0x0C,0x00,0x94,0xE5,0x08,0x00,0x50,0xE3,0x10,0x40,0xBD,0x08,
+ 0xAE,0x0A,0x00,0x0A,0x14,0x10,0x94,0xE5,0x5F,0x00,0x11,0xE3,0x18,0x10,0x94,0x15,
+ 0x04,0x10,0x80,0x14,0xFA,0xFF,0xFF,0x1A,0x04,0x00,0x94,0xE5,0x02,0x00,0x10,0xE3,
+ 0xFC,0xFF,0xFF,0x0A,0xA5,0x0A,0x00,0xEB,0xD2,0xFF,0xFF,0xEA,0x00,0x40,0x00,0x30,
+ 0x01,0x49,0x20,0x20,0x48,0x61,0x70,0x47,0x00,0x40,0x00,0x30,0x03,0x22,0x12,0x07,
+ 0xD3,0x68,0x01,0x21,0x81,0x40,0x0B,0x43,0xD3,0x60,0x50,0x68,0x08,0x42,0x01,0xD0,
+ 0x01,0x48,0x01,0x63,0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x30,0x03,0x23,0x1B,0x07,
+ 0xDA,0x68,0x01,0x21,0x81,0x40,0x8A,0x43,0xDA,0x60,0x70,0x47,0x10,0xB4,0x0F,0x24,
+ 0x03,0x23,0x1B,0x07,0x1C,0x60,0x05,0x4C,0x60,0x63,0x19,0x61,0x9A,0x60,0x00,0x20,
+ 0xC0,0x43,0xD8,0x60,0x00,0x20,0x18,0x60,0x10,0xBC,0x70,0x47,0x40,0x00,0x00,0x30,
+ 0x00,0xB5,0xFF,0xF7,0xE3,0xFF,0x08,0xBC,0x18,0x47,0x00,0x00,0xF8,0xB5,0x2A,0x4C,
+ 0x02,0xF0,0x5C,0xFA,0x00,0xF0,0xF8,0xF9,0x01,0xF0,0xD6,0xFC,0x03,0xF0,0x90,0xFA,
+ 0x02,0xF0,0x30,0xFB,0x00,0xF0,0x3A,0xFF,0x00,0xF0,0x34,0xFC,0xFE,0xF7,0x0C,0xF9,
+ 0xFD,0xF7,0x60,0xFB,0x19,0x20,0x40,0x01,0x20,0x18,0xC0,0x7E,0x00,0x25,0x26,0x00,
+ 0x00,0x28,0x04,0xD0,0x1D,0x20,0x80,0x01,0x20,0x18,0x85,0x73,0x30,0xE0,0x1B,0x48,
+ 0x00,0x68,0xA0,0x30,0x40,0x7B,0x00,0x28,0x04,0xD1,0xFF,0xF7,0x51,0xFB,0xFF,0xF7,
+ 0x8F,0xFA,0x03,0xE0,0xFF,0xF7,0x8C,0xFA,0xFF,0xF7,0x4A,0xFB,0x02,0xF0,0xD6,0xFE,
+ 0x02,0xF0,0x44,0xFD,0x03,0xF0,0xAE,0xFA,0xFE,0xF7,0x48,0xFB,0x07,0x00,0x02,0xF0,
+ 0x13,0xFD,0x37,0x20,0x40,0x01,0x20,0x18,0x81,0x7F,0x38,0x00,0xFD,0xF7,0xEA,0xF8,
+ 0x00,0xF0,0x3A,0xF8,0xFD,0xF7,0x32,0xF8,0x0F,0x20,0xC0,0x01,0x20,0x18,0xC1,0x69,
+ 0x32,0x29,0x03,0xD9,0x06,0x49,0xC5,0x61,0x01,0x20,0x08,0x70,0x02,0xF0,0xC4,0xF9,
+ 0x70,0x79,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0xE8,0x07,0x00,0x20,
+ 0x19,0x08,0x00,0x20,0x70,0xB5,0x02,0xF0,0xF5,0xF9,0x03,0xF0,0x11,0xFB,0x03,0xF0,
+ 0xF3,0xFA,0x03,0xF0,0x1B,0xFA,0x02,0xF0,0x5F,0xFF,0x09,0x48,0x00,0x21,0x00,0x78,
+ 0x03,0xF0,0x4C,0xFB,0x07,0x4C,0x00,0x25,0x25,0x70,0x02,0xF0,0x55,0xFA,0xFE,0xF7,
+ 0x0F,0xFB,0x20,0x78,0x00,0x28,0xF7,0xD0,0x02,0xF0,0x96,0xF8,0xF4,0xE7,0x00,0x00,
+ 0x1C,0x95,0x00,0x00,0x18,0x08,0x00,0x20,0xF0,0xB5,0x00,0x20,0x8D,0xB0,0x0C,0x90,
+ 0x44,0x48,0xD9,0x21,0xC9,0x00,0x44,0x18,0xE3,0x21,0xC9,0x00,0x45,0x18,0x30,0x22,
+ 0x00,0x21,0x68,0x46,0xFC,0xF7,0x7E,0xFF,0x28,0x00,0x20,0x30,0x07,0x00,0x80,0x7D,
+ 0x3D,0x4E,0x00,0x28,0x0B,0xD1,0xB0,0x7D,0x00,0x28,0x6F,0xD1,0x20,0x00,0x0C,0x22,
+ 0x00,0x21,0x38,0x30,0xFC,0xF7,0x6E,0xFF,0xB8,0x7D,0x00,0x28,0x66,0xD0,0xB0,0x7D,
+ 0x00,0x28,0x63,0xD0,0x00,0x22,0xA8,0x8E,0x00,0x23,0xD0,0x40,0xC0,0x07,0x34,0xD0,
+ 0x50,0x1C,0x00,0x06,0x00,0x0E,0x00,0x21,0x66,0x18,0x38,0x27,0xF7,0x57,0x87,0x42,
+ 0x01,0xD1,0x4B,0x1C,0x02,0xE0,0x49,0x1C,0x0C,0x29,0xF5,0xD3,0x00,0x2B,0x03,0xD0,
+ 0x49,0x1C,0x08,0x06,0x00,0x0E,0x0C,0xE0,0x00,0x21,0x63,0x18,0x20,0x33,0x1B,0x7E,
+ 0x00,0x2B,0x03,0xD1,0x63,0x18,0x20,0x33,0x18,0x76,0xF1,0xE7,0x49,0x1C,0x0C,0x29,
+ 0xF3,0xD3,0x41,0x1E,0x01,0x23,0x8B,0x40,0x0C,0x99,0x86,0x00,0x0B,0x43,0x19,0x04,
+ 0x09,0x0C,0x0C,0x91,0x91,0x00,0x49,0x19,0x49,0x68,0x6B,0x46,0xF3,0x18,0x09,0x01,
+ 0x40,0x3B,0x09,0x09,0x00,0x07,0x01,0x43,0xD9,0x63,0x52,0x1C,0x0C,0x2A,0xC2,0xD3,
+ 0x00,0x21,0x0B,0x00,0xA8,0x8E,0xC8,0x40,0xC0,0x07,0x0F,0xD1,0x48,0x1C,0x02,0x06,
+ 0x12,0x0E,0x01,0x20,0x26,0x18,0x38,0x27,0xF7,0x57,0x97,0x42,0x03,0xD1,0x20,0x18,
+ 0x20,0x30,0x03,0x76,0x02,0xE0,0x40,0x1C,0x0C,0x28,0xF3,0xD9,0x49,0x1C,0x0A,0x29,
+ 0xE8,0xD3,0x28,0x68,0x0C,0x99,0x80,0x0A,0x89,0x05,0x80,0x02,0x89,0x0D,0x08,0x43,
+ 0x28,0x60,0x30,0x22,0x28,0x1D,0x69,0x46,0xFC,0xF7,0x0A,0xFF,0x0D,0xB0,0xF0,0xBC,
+ 0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0x28,0x07,0x00,0x20,0x18,0x49,0x10,0xB4,
+ 0x09,0x68,0x18,0x4A,0x60,0x31,0x8C,0x7E,0x53,0x7D,0x49,0x7E,0x00,0x2B,0x11,0xD1,
+ 0x93,0x7D,0x13,0x4A,0x12,0x68,0x80,0x32,0x01,0x2B,0x01,0xD1,0x52,0x7D,0x06,0xE0,
+ 0x02,0x2B,0x01,0xD1,0x92,0x7D,0x02,0xE0,0x03,0x2B,0x03,0xD1,0xD2,0x7D,0x51,0x18,
+ 0x09,0x06,0x09,0x0E,0x02,0x78,0x00,0x2A,0x08,0xD0,0x8A,0x42,0x06,0xD3,0x14,0x2A,
+ 0x09,0xD3,0x64,0x1C,0x14,0x21,0x4C,0x43,0xA2,0x42,0x02,0xD2,0x00,0x20,0x10,0xBC,
+ 0x70,0x47,0xF0,0x21,0x00,0xE0,0x13,0x21,0x01,0x70,0x01,0x20,0xF7,0xE7,0x00,0x00,
+ 0xE8,0x07,0x00,0x20,0x7E,0x03,0x00,0x20,0x10,0xB5,0x09,0x24,0x20,0x00,0xFE,0xF7,
+ 0x67,0xFB,0x64,0x1E,0xFA,0xD5,0x10,0xBC,0x08,0xBC,0x18,0x47,0xF5,0x22,0x10,0xB5,
+ 0x05,0x48,0xD2,0x00,0x00,0x21,0xFC,0xF7,0xB5,0xFE,0x02,0xF0,0xE3,0xFE,0x00,0xF0,
+ 0xAD,0xF8,0x10,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0x10,0xB5,0x07,0x4C,
+ 0x07,0x48,0x22,0x00,0x00,0x21,0xFC,0xF7,0xA5,0xFE,0x06,0x48,0x22,0x00,0x00,0x21,
+ 0xFC,0xF7,0xA0,0xFE,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0xD2,0x02,0x00,0x00,
+ 0x00,0x00,0x00,0x10,0x2A,0x08,0x00,0x20,0xFF,0x20,0x10,0xB5,0xC9,0x30,0xFD,0xF7,
+ 0xBD,0xF9,0x10,0xBC,0x08,0xBC,0x18,0x47,0x14,0x48,0x10,0xB5,0x44,0x08,0x14,0x49,
+ 0x14,0x48,0x62,0x00,0xFC,0xF7,0xA2,0xFE,0x10,0x48,0xC0,0x07,0x08,0xD0,0x0F,0x48,
+ 0xC2,0x07,0x0F,0x48,0xD2,0x0F,0x01,0x19,0x0E,0x48,0x00,0x19,0xFC,0xF7,0x80,0xFE,
+ 0x0D,0x48,0x00,0x21,0x84,0x08,0x0D,0x48,0xA2,0x00,0xFC,0xF7,0x7F,0xFE,0x0A,0x48,
+ 0x80,0x07,0x07,0xD0,0x08,0x48,0x00,0x21,0x82,0x07,0x08,0x48,0x92,0x0F,0x00,0x19,
+ 0xFC,0xF7,0x68,0xFE,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x84,0x74,0x00,0x00,0x40,0x00,0x00,0x20,0xBC,0x0A,0x00,0x00,0x40,0x00,0x00,0x20,
+ 0x70,0xB5,0x00,0xF0,0x5D,0xFA,0x0F,0x48,0x01,0x25,0x41,0x7A,0x0E,0x48,0x40,0x22,
+ 0x81,0x70,0x00,0x21,0x41,0x70,0xC1,0x70,0x01,0x71,0x41,0x71,0x81,0x71,0xC1,0x71,
+ 0x05,0x72,0x41,0x72,0x09,0x49,0xD4,0x05,0x81,0x61,0xC1,0x61,0x00,0x21,0x20,0x00,
+ 0xFC,0xF7,0x40,0xFE,0x06,0x48,0xA5,0x63,0x60,0x63,0xFF,0x20,0xE0,0x63,0x70,0xBC,
+ 0x08,0xBC,0x18,0x47,0xC0,0x91,0x00,0x00,0xF4,0x07,0x00,0x20,0xFF,0xFF,0x00,0x00,
+ 0x40,0x00,0x00,0x20,0x33,0x21,0x09,0x05,0x01,0x20,0x80,0x07,0x41,0x62,0x04,0x49,
+ 0x81,0x62,0x04,0x48,0xFF,0x21,0xC1,0x60,0x00,0x21,0x41,0x61,0x70,0x47,0x00,0x00,
+ 0x88,0x88,0x88,0x88,0x00,0x20,0x00,0x40,0x04,0x48,0x01,0x21,0x89,0x07,0xC8,0x61,
+ 0x03,0x49,0x04,0x48,0x01,0x60,0x20,0x21,0x41,0x60,0x70,0x47,0x5C,0x0A,0x00,0x00,
+ 0xDE,0x10,0x05,0x00,0x00,0x40,0x00,0x30,0x10,0xB5,0xFE,0xF7,0xE3,0xFA,0xFE,0xF7,
+ 0x73,0xFB,0xFE,0xF7,0x47,0xFB,0x10,0xBC,0x08,0xBC,0x18,0x47,0x70,0xB5,0x0F,0x4C,
+ 0xFF,0xF7,0x54,0xFF,0x0E,0x48,0x00,0x7A,0x03,0xF0,0x78,0xF9,0xFE,0xF7,0x02,0xFB,
+ 0x0C,0x48,0x40,0x88,0x20,0x84,0x0C,0x48,0xFF,0x34,0x00,0x68,0xFF,0x34,0x40,0x30,
+ 0x40,0x7E,0x02,0x34,0x60,0x76,0xFF,0xF7,0x27,0xFF,0x00,0x25,0x25,0x74,0xFE,0xF7,
+ 0xFB,0xFC,0x06,0x48,0x05,0x70,0x70,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,
+ 0xC0,0x91,0x00,0x00,0x1C,0x95,0x00,0x00,0xE8,0x07,0x00,0x20,0x19,0x08,0x00,0x20,
+ 0x10,0xB5,0xFF,0x20,0xFD,0xF7,0x2C,0xF9,0x01,0xF0,0xD2,0xFF,0x01,0xF0,0xCA,0xFF,
+ 0x10,0xBC,0x08,0xBC,0x18,0x47,0x10,0xB5,0xFE,0xF7,0x06,0xFF,0xFE,0xF7,0xFC,0xFE,
+ 0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x38,0xB5,0x03,0x24,0x13,0x25,0x20,0x02,
+ 0xFD,0xF7,0x08,0xF9,0x0B,0x48,0x0A,0x21,0x00,0x69,0xFC,0xF7,0x8F,0xFD,0x02,0x00,
+ 0xFF,0x21,0x90,0x31,0x02,0x20,0x00,0x23,0x00,0x95,0x03,0xF0,0x11,0xFA,0x06,0x4A,
+ 0x27,0x21,0x03,0x20,0x00,0x23,0x00,0x94,0x03,0xF0,0x0A,0xFA,0x38,0xBC,0x08,0xBC,
+ 0x18,0x47,0x00,0x00,0x9C,0x94,0x00,0x00,0xE8,0xFD,0x00,0x00,0x00,0x22,0x10,0xB5,
+ 0x03,0x49,0xD2,0x43,0x00,0x20,0xFF,0xF7,0x79,0xFD,0x10,0xBC,0x08,0xBC,0x18,0x47,
+ 0x02,0x03,0x0F,0x0F,0x0A,0x48,0x10,0xB5,0x00,0x69,0x0A,0x49,0x0A,0x4C,0x88,0x42,
+ 0x05,0xD9,0x7D,0x21,0xC9,0x00,0xFC,0xF7,0x61,0xFD,0x64,0x30,0x01,0xE0,0xFF,0x20,
+ 0xF5,0x30,0x20,0x62,0x03,0xF0,0x9A,0xFA,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0x9C,0x94,0x00,0x00,0x07,0xA5,0x07,0x00,0xF4,0x07,0x00,0x20,0x10,0xB5,0x00,0xF0,
+ 0xFD,0xF8,0xFF,0xF7,0xE9,0xFE,0xFF,0xF7,0xB9,0xFE,0xFF,0xF7,0x19,0xFF,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0x10,0xB5,0xFE,0xF7,0x7F,0xFD,0xFE,0xF7,0x59,0xFD,0xFE,0xF7,
+ 0x83,0xFD,0xFE,0xF7,0x79,0xFD,0xFE,0xF7,0x4B,0xFD,0x04,0x48,0x80,0x78,0xFC,0xF7,
+ 0xC1,0xFD,0x02,0xF0,0x77,0xFA,0x10,0xBC,0x08,0xBC,0x18,0x47,0x9C,0x94,0x00,0x00,
+ 0x10,0xB5,0xFF,0xF7,0xC1,0xFE,0xFF,0xF7,0xB1,0xFF,0xFF,0xF7,0x8D,0xFF,0xFF,0xF7,
+ 0xB9,0xFF,0xFF,0xF7,0x80,0xFF,0xFF,0xF7,0x73,0xFF,0xFF,0xF7,0x1B,0xFF,0x02,0xF0,
+ 0x53,0xFA,0x10,0xBC,0x08,0xBC,0x18,0x47,0xF7,0xB5,0x86,0xB0,0x00,0x27,0x2F,0x48,
+ 0x04,0xAB,0x02,0x97,0x03,0x97,0x81,0xC3,0x2D,0x4E,0xFE,0xF7,0x1B,0xFD,0xFE,0xF7,
+ 0x93,0xFD,0x2C,0x48,0xC0,0x7F,0x01,0x90,0x2A,0x48,0x20,0x30,0x00,0x78,0x00,0x25,
+ 0x00,0x90,0x2C,0xE0,0x00,0x24,0x24,0xE0,0x21,0x00,0x28,0x00,0xFF,0xF7,0xA4,0xFB,
+ 0x00,0x28,0x1D,0xD0,0x23,0x49,0x04,0x9A,0x20,0x39,0x09,0x78,0x69,0x43,0x09,0x19,
+ 0x89,0x00,0x51,0x58,0x09,0x05,0x09,0x0D,0x08,0x1A,0x01,0x1E,0x00,0xDC,0x41,0x42,
+ 0x00,0x28,0x01,0xDB,0x01,0x98,0x00,0xE0,0x00,0x98,0x81,0x42,0x01,0xDD,0x01,0x22,
+ 0x05,0x92,0x08,0x1A,0xB0,0x42,0x03,0xDD,0x06,0x00,0x27,0x00,0x02,0x95,0x03,0x91,
+ 0x64,0x1C,0x14,0x48,0x20,0x38,0x00,0x78,0xA0,0x42,0xD5,0xD8,0x6D,0x1C,0x11,0x48,
+ 0x20,0x38,0x41,0x78,0xA9,0x42,0xCD,0xD8,0x08,0x99,0x03,0x98,0x08,0x60,0x0E,0x48,
+ 0x00,0x69,0xC0,0x07,0x05,0xD0,0x07,0x98,0x07,0x60,0x06,0x99,0x02,0x98,0x08,0x60,
+ 0x04,0xE0,0x07,0x99,0x02,0x98,0x08,0x60,0x06,0x98,0x07,0x60,0x05,0x98,0x00,0x28,
+ 0x00,0xD0,0x04,0x20,0x09,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0xD4,0x02,0x10,0x40,
+ 0x78,0xEC,0xFF,0xFF,0xBC,0x94,0x00,0x00,0x00,0x90,0x00,0x40,0x78,0x47,0xC0,0x46,
+ 0xA0,0xC0,0x9F,0xE5,0x00,0x00,0x9C,0xE5,0x9C,0x30,0x9F,0xE5,0x8C,0x06,0xD3,0xE5,
+ 0x01,0x1B,0x83,0xE2,0x99,0x1F,0x81,0xE2,0x01,0x00,0x00,0xE2,0x00,0x00,0x50,0xE3,
+ 0x29,0x20,0xD1,0x15,0x00,0x00,0xA0,0x13,0x00,0x00,0x52,0x13,0x1E,0xFF,0x2F,0x91,
+ 0xF0,0x01,0x2D,0xE9,0x74,0x50,0x9F,0xE5,0x74,0x60,0x9F,0xE5,0x74,0x40,0x9F,0xE5,
+ 0x28,0x70,0xD1,0xE5,0x00,0x20,0x81,0xE0,0x2F,0x20,0xD2,0xE5,0x02,0x00,0x17,0xE3,
+ 0x2E,0x70,0xD1,0xE5,0x00,0x80,0xD5,0xE5,0x97,0x28,0x22,0x00,0x98,0x72,0x22,0x10,
+ 0x00,0x70,0xD6,0xE5,0x00,0x00,0x57,0xE3,0x04,0x00,0x00,0x1A,0x02,0x21,0x9C,0xE7,
+ 0x80,0x70,0x83,0xE0,0x02,0x29,0xC2,0xE3,0xB0,0x21,0xC7,0xE1,0x03,0x00,0x00,0xEA,
+ 0x82,0x20,0x84,0xE0,0xB0,0x20,0xD2,0xE1,0x80,0x70,0x83,0xE0,0xB0,0x21,0xC7,0xE1,
+ 0x29,0x20,0xD1,0xE5,0x01,0x00,0x80,0xE2,0x00,0x00,0x52,0xE1,0xE7,0xFF,0xFF,0x8A,
+ 0xF0,0x01,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,0x00,0x10,0x10,0x40,0x40,0x00,0x00,0x20,
+ 0x9C,0x94,0x00,0x00,0x18,0x08,0x00,0x20,0x2A,0x08,0x00,0x20,0x06,0x4A,0x04,0x48,
+ 0x04,0x49,0x92,0x10,0x01,0xE0,0x08,0xC9,0x08,0xC0,0x52,0x1E,0xFB,0xD2,0x70,0x47,
+ 0xB0,0x05,0x00,0x10,0xDC,0x72,0x00,0x00,0xA8,0x01,0x00,0x00,0x06,0x4A,0x04,0x48,
+ 0x04,0x49,0x92,0x08,0x01,0xE0,0x08,0xC9,0x08,0xC0,0x52,0x1E,0xFB,0xD2,0x70,0x47,
+ 0x00,0x00,0x00,0x10,0xC8,0x71,0x00,0x00,0xEC,0x00,0x00,0x00,0x78,0x47,0xC0,0x46,
+ 0x01,0x00,0x50,0xE1,0x01,0x00,0xA0,0xB1,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0xC0,0x46,
+ 0x00,0xC0,0x9D,0xE5,0x01,0x00,0x50,0xE1,0x02,0x00,0x00,0xBA,0x02,0x00,0x50,0xE1,
+ 0x00,0x20,0xA0,0xA1,0x01,0x00,0x00,0xEA,0x02,0x00,0x51,0xE1,0x01,0x20,0xA0,0xA1,
+ 0x03,0x00,0x52,0xE1,0x02,0x00,0xA0,0xE1,0x03,0x00,0x00,0xBA,0x0C,0x00,0x50,0xE1,
+ 0x1E,0xFF,0x2F,0xA1,0x0C,0x00,0xA0,0xE1,0x1E,0xFF,0x2F,0xE1,0x0C,0x00,0x53,0xE1,
+ 0xFB,0xFF,0xFF,0xBA,0x03,0x00,0xA0,0xE1,0x1E,0xFF,0x2F,0xE1,0x10,0xB5,0xFF,0xF7,
+ 0xAD,0xFE,0xFF,0xF7,0xB7,0xFE,0xFF,0xF7,0xCB,0xFE,0x01,0xF0,0x95,0xFE,0xFF,0xF7,
+ 0x71,0xFC,0x10,0xBC,0x08,0xBC,0x00,0x20,0x18,0x47,0x00,0x22,0x03,0xE0,0x03,0x78,
+ 0x40,0x1C,0x9A,0x18,0x49,0x1E,0x00,0x29,0xF9,0xDC,0x10,0x06,0x00,0x0E,0x70,0x47,
+ 0x10,0xB5,0x01,0x24,0x64,0x07,0x61,0x68,0x03,0x22,0x92,0x02,0x11,0x43,0x61,0x60,
+ 0x61,0x68,0x09,0x02,0x09,0x0A,0x61,0x60,0x81,0x00,0x20,0x1D,0xFF,0xF7,0xE5,0xFF,
+ 0x61,0x68,0x00,0x06,0x01,0x43,0x61,0x60,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0x10,0xB5,0x11,0x4A,0x11,0x49,0x12,0x48,0xFC,0xF7,0xEE,0xFB,0x05,0x21,0x49,0x03,
+ 0x00,0x20,0xFC,0xF7,0x11,0xFC,0x0F,0x4B,0x0F,0x49,0x18,0x61,0x00,0x20,0xFC,0xF7,
+ 0x0B,0xFC,0x58,0x61,0x0D,0x49,0x0C,0x48,0xFC,0xF7,0x06,0xFC,0x59,0x69,0x00,0x04,
+ 0x08,0x43,0x58,0x61,0x0A,0x48,0xC1,0x6B,0x01,0x22,0x92,0x07,0x91,0x43,0xC1,0x63,
+ 0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x28,0x00,0x00,0x00,0xB4,0x72,0x00,0x00,
+ 0x00,0x00,0x00,0x10,0xF4,0x07,0x00,0x20,0xC0,0x91,0x00,0x00,0xC0,0x9C,0x00,0x00,
+ 0x00,0x70,0x00,0x40,0x78,0x47,0xC0,0x46,0xF0,0x4F,0x2D,0xE9,0xE4,0x25,0x9F,0xE5,
+ 0xAD,0xDF,0x4D,0xE2,0x00,0x00,0x92,0xE5,0x00,0x50,0xA0,0xE3,0x5E,0x40,0xD0,0xE5,
+ 0xD4,0x05,0x9F,0xE5,0xD4,0x75,0x9F,0xE5,0x69,0x6F,0x80,0xE2,0x0C,0x00,0x8D,0xE5,
+ 0x01,0x0C,0x80,0xE2,0x22,0x00,0x80,0xE2,0x08,0x00,0x8D,0xE5,0x0C,0x00,0x9D,0xE5,
+ 0x85,0x0F,0x80,0xE2,0x04,0x00,0x8D,0xE5,0xB0,0x50,0xC0,0xE1,0xA8,0x05,0x9F,0xE5,
+ 0x00,0x10,0x92,0xE5,0xB8,0x00,0xD0,0xE1,0x4E,0x10,0xD1,0xE5,0x91,0x00,0x00,0xE0,
+ 0x97,0x10,0x80,0xE0,0xA0,0x12,0xA0,0xE1,0x04,0x00,0x9D,0xE5,0xB2,0x10,0xC0,0xE1,
+ 0x04,0x00,0x9D,0xE5,0xB2,0x10,0xD0,0xE1,0x00,0x00,0x92,0xE5,0x0C,0x20,0xA0,0xE3,
+ 0xB0,0x05,0xD0,0xE1,0x00,0x00,0x51,0xE1,0x04,0x10,0x9D,0x35,0xB2,0x00,0xC1,0x31,
+ 0x00,0x10,0xA0,0xE3,0x12,0x0E,0x8D,0xE2,0xC9,0xF1,0xFF,0xEB,0x69,0x20,0xA0,0xE3,
+ 0x01,0x2C,0x82,0xE2,0x00,0x10,0xA0,0xE3,0x4B,0x0F,0x8D,0xE2,0xC4,0xF1,0xFF,0xEB,
+ 0xCC,0x20,0xA0,0xE3,0x00,0x10,0xA0,0xE3,0x54,0x00,0x8D,0xE2,0xC0,0xF1,0xFF,0xEB,
+ 0x44,0x20,0xA0,0xE3,0x00,0x10,0xA0,0xE3,0x10,0x00,0x8D,0xE2,0xBC,0xF1,0xFF,0xEB,
+ 0xB0,0x56,0xC6,0xE1,0x0C,0x00,0x9D,0xE5,0xB8,0x00,0xD0,0xE1,0x94,0x00,0x00,0xE0,
+ 0x97,0x10,0x80,0xE0,0xA0,0x02,0xA0,0xE1,0xB2,0x06,0xC6,0xE1,0x0C,0x10,0x9D,0xE5,
+ 0x00,0x40,0xA0,0xE3,0xBE,0x10,0xD1,0xE1,0x01,0x00,0x80,0xE0,0xB2,0x06,0xC6,0xE1,
+ 0x01,0x00,0xA0,0xE3,0x2A,0x1E,0x8D,0xE2,0x11,0x00,0x81,0xE8,0xF0,0x04,0x9F,0xE5,
+ 0x01,0x00,0xD0,0xE5,0x00,0x00,0x50,0xE3,0xBC,0x00,0x00,0xDA,0xE0,0x04,0x9F,0xE5,
+ 0x00,0x50,0xA0,0xE3,0x00,0x00,0xD0,0xE5,0x00,0x00,0x50,0xE3,0xAF,0x00,0x00,0xDA,
+ 0x0C,0x00,0x9D,0xE5,0xA4,0x12,0x9D,0xE5,0x81,0x00,0x80,0xE0,0xB0,0x02,0x8D,0xE5,
+ 0xFF,0x00,0x01,0xE2,0xAC,0x02,0x8D,0xE5,0xB4,0x04,0x9F,0xE5,0xA4,0x12,0x9D,0xE5,
+ 0x00,0x00,0xD0,0xE5,0xAC,0xA4,0x9F,0xE5,0x04,0x20,0x9D,0xE5,0x91,0x50,0x20,0xE0,
+ 0x00,0x08,0xA0,0xE1,0x20,0x08,0xA0,0xE1,0x9C,0x02,0x8D,0xE5,0x80,0x00,0x8A,0xE0,
+ 0xF0,0x10,0xD0,0xE1,0xB2,0x20,0xD2,0xE1,0x02,0x00,0x51,0xE1,0x04,0x00,0x00,0xDA,
+ 0x04,0x10,0x9D,0xE5,0x04,0x20,0x9D,0xE5,0xB0,0x10,0xD1,0xE1,0x01,0x10,0x81,0xE2,
+ 0xB0,0x10,0xC2,0xE1,0xF0,0x00,0xD0,0xE1,0xF2,0x16,0xD6,0xE1,0x01,0x00,0x50,0xE1,
+ 0x8D,0x00,0x00,0xDA,0x00,0x70,0xA0,0xE3,0x54,0xC4,0x9F,0xE5,0x98,0x72,0x8D,0xE5,
+ 0x00,0xC0,0xDC,0xE5,0x9C,0x12,0x9D,0xE5,0x07,0x90,0xA0,0xE1,0x05,0x00,0x5C,0xE1,
+ 0x07,0x80,0xA0,0xE1,0x07,0x20,0xA0,0xE1,0x07,0x30,0xA0,0xE1,0x07,0x00,0xA0,0xE1,
+ 0x5C,0x00,0x00,0xDA,0x01,0xA0,0x4C,0xE2,0xA8,0xA2,0x8D,0xE5,0x24,0xA4,0x9F,0xE5,
+ 0x81,0xA0,0x8A,0xE0,0xF0,0xB0,0xDA,0xE1,0xF2,0xA6,0xD6,0xE1,0x0A,0x00,0x5B,0xE1,
+ 0x54,0x00,0x00,0xDA,0xFF,0xE0,0x04,0xE2,0x4B,0xAF,0x8D,0xE2,0x01,0xE0,0xCA,0xE7,
+ 0xF2,0xA6,0xD6,0xE1,0x0A,0xA0,0x4B,0xE0,0x0C,0xB0,0x9D,0xE5,0x0A,0x90,0x89,0xE0,
+ 0x85,0xB0,0x8B,0xE0,0xB2,0xB2,0xDB,0xE1,0x9A,0x7B,0x27,0xE0,0xB0,0xB2,0x9D,0xE5,
+ 0xB6,0xB5,0xDB,0xE1,0x9A,0x8B,0x28,0xE0,0x98,0xA2,0x9D,0xE5,0x01,0xA0,0x8A,0xE2,
+ 0x01,0xA8,0xCA,0xE3,0x98,0xA2,0x8D,0xE5,0xA4,0xA2,0x9D,0xE5,0x00,0x00,0x5A,0xE3,
+ 0x3B,0x00,0x00,0x0A,0x00,0x00,0x52,0xE3,0x16,0x00,0x00,0x1A,0x0C,0xA0,0x41,0xE0,
+ 0x4B,0xEF,0x8D,0xE2,0x0A,0xB0,0xDE,0xE7,0x00,0x00,0x5B,0xE3,0x05,0x00,0x00,0x1A,
+ 0x00,0x00,0x55,0xE3,0x06,0x00,0x00,0x0A,0x0E,0xB0,0x8A,0xE0,0x01,0xB0,0x5B,0xE5,
+ 0x00,0x00,0x5B,0xE3,0x02,0x00,0x00,0x0A,0x01,0x20,0xA0,0xE3,0x0B,0x40,0xA0,0xE1,
+ 0x2B,0x00,0x00,0xEA,0xA8,0xB2,0x9D,0xE5,0x05,0x00,0x5B,0xE1,0x28,0x00,0x00,0x0A,
+ 0x0E,0xA0,0x8A,0xE0,0x01,0xA0,0xDA,0xE5,0x00,0x00,0x5A,0xE3,0x01,0x20,0xA0,0x13,
+ 0x0A,0x40,0xA0,0x11,0x22,0x00,0x00,0xEA,0x0C,0xB0,0x41,0xE0,0x4B,0xAF,0x8D,0xE2,
+ 0x0B,0xA0,0xDA,0xE7,0x00,0x00,0x5A,0xE3,0x04,0x00,0x5A,0x11,0x02,0x00,0x00,0x0A,
+ 0x01,0x30,0xA0,0xE3,0x0A,0x00,0xA0,0xE1,0x12,0x00,0x00,0xEA,0x00,0x00,0x55,0xE3,
+ 0x05,0x00,0x00,0x0A,0x4B,0xAF,0x8D,0xE2,0x0B,0xA0,0x8A,0xE0,0x01,0xA0,0x5A,0xE5,
+ 0x00,0x00,0x5A,0xE3,0x04,0x00,0x5A,0x11,0xF4,0xFF,0xFF,0x1A,0xA8,0xA2,0x9D,0xE5,
+ 0x05,0x00,0x5A,0xE1,0x05,0x00,0x00,0x0A,0x4B,0xAF,0x8D,0xE2,0x0B,0xA0,0x8A,0xE0,
+ 0x01,0xA0,0xDA,0xE5,0x00,0x00,0x5A,0xE3,0x04,0x00,0x5A,0x11,0xEB,0xFF,0xFF,0x1A,
+ 0x00,0x00,0x53,0xE3,0x06,0x00,0x00,0x0A,0x0C,0x00,0x50,0xE3,0x0C,0x00,0x54,0x33,
+ 0x03,0x00,0x00,0x2A,0x00,0x00,0x54,0xE1,0x12,0xAE,0x8D,0xE2,0x00,0xE0,0xCA,0x97,
+ 0x04,0x00,0xCA,0x87,0x01,0x50,0x85,0xE2,0x01,0x10,0x81,0xE2,0x05,0x00,0x5C,0xE1,
+ 0x01,0x18,0xC1,0xE3,0xA4,0xFF,0xFF,0xCA,0xA0,0x02,0x9D,0xE5,0x00,0x00,0x50,0xE3,
+ 0x11,0x00,0x50,0x13,0x20,0x00,0x00,0x2A,0x00,0x00,0x52,0xE3,0x00,0x40,0xA0,0x01,
+ 0x01,0x00,0x80,0x02,0x9C,0x12,0x9D,0xE5,0xA0,0x02,0x8D,0x05,0x4B,0x0F,0x8D,0xE2,
+ 0x01,0x00,0x80,0xE0,0x04,0x1C,0xA0,0xE1,0x98,0x22,0x9D,0xE5,0x41,0x1C,0xA0,0xE1,
+ 0x0F,0xF1,0xFF,0xEB,0x84,0x10,0x84,0xE0,0x54,0x00,0x8D,0xE2,0x01,0x01,0x80,0xE0,
+ 0x0C,0x10,0x10,0xE5,0x07,0x10,0x81,0xE0,0x0C,0x10,0x00,0xE5,0x08,0x10,0x10,0xE5,
+ 0x08,0x10,0x81,0xE0,0x08,0x10,0x00,0xE5,0x04,0x10,0x10,0xE5,0x09,0x10,0x81,0xE0,
+ 0x04,0x10,0x00,0xE5,0x10,0x00,0x8D,0xE2,0x04,0x01,0x80,0xE0,0xB4,0x10,0x50,0xE1,
+ 0x98,0x22,0x9D,0xE5,0x02,0x10,0x81,0xE0,0xB4,0x10,0x40,0xE1,0x01,0x10,0xA0,0xE3,
+ 0x02,0x10,0x40,0xE5,0xAC,0x12,0x9D,0xE5,0x01,0x10,0x40,0xE5,0x20,0x02,0x9F,0xE5,
+ 0x01,0x50,0x85,0xE2,0x00,0x00,0xD0,0xE5,0x05,0x00,0x50,0xE1,0x55,0xFF,0xFF,0xCA,
+ 0xA4,0x02,0x9D,0xE5,0x01,0x00,0x80,0xE2,0xA4,0x02,0x8D,0xE5,0x00,0x02,0x9F,0xE5,
+ 0xA4,0x12,0x9D,0xE5,0x01,0x00,0xD0,0xE5,0x01,0x00,0x50,0xE1,0x42,0xFF,0xFF,0xCA,
+ 0xA0,0x02,0x9D,0xE5,0x01,0x00,0x40,0xE2,0x10,0x00,0x50,0xE3,0x2C,0x00,0x00,0x8A,
+ 0xA0,0x02,0x9D,0xE5,0x01,0x40,0x40,0xE2,0x00,0x00,0x54,0xE3,0x28,0x00,0x00,0xDA,
+ 0x12,0x7E,0x8D,0xE2,0x10,0x80,0x8D,0xE2,0x54,0x90,0x8D,0xE2,0x04,0x20,0xD7,0xE7,
+ 0x01,0x00,0x42,0xE2,0x10,0x00,0x50,0xE3,0x1E,0x00,0x00,0x8A,0x82,0x00,0x82,0xE0,
+ 0x84,0x10,0x84,0xE0,0x00,0x01,0x89,0xE0,0x01,0x11,0x89,0xE0,0x0C,0x30,0x10,0xE5,
+ 0x0C,0xC0,0x11,0xE5,0x04,0xA1,0x88,0xE0,0x0C,0x30,0x83,0xE0,0x0C,0x30,0x00,0xE5,
+ 0x08,0x30,0x10,0xE5,0x08,0xC0,0x11,0xE5,0x11,0x50,0x64,0xE2,0x0C,0x30,0x83,0xE0,
+ 0x08,0x30,0x00,0xE5,0x04,0x30,0x10,0xE5,0x04,0xC0,0x11,0xE5,0x0C,0x30,0x83,0xE0,
+ 0x04,0x30,0x00,0xE5,0x02,0x01,0x88,0xE0,0xB4,0x20,0x50,0xE1,0xB4,0x30,0x5A,0xE1,
+ 0x03,0x20,0x82,0xE0,0xB4,0x20,0x40,0xE1,0x85,0x00,0x85,0xE0,0x00,0x21,0xA0,0xE1,
+ 0x0C,0x00,0x41,0xE2,0xCB,0xF0,0xFF,0xEB,0x05,0x21,0xA0,0xE1,0x04,0x00,0x4A,0xE2,
+ 0x0A,0x10,0xA0,0xE1,0xC7,0xF0,0xFF,0xEB,0x01,0x40,0x44,0xE2,0x00,0x00,0x54,0xE3,
+ 0xD9,0xFF,0xFF,0xCA,0x0C,0x00,0x9D,0xE5,0x00,0x40,0xA0,0xE3,0x04,0x00,0xD0,0xE5,
+ 0x00,0x00,0x50,0xE3,0x2A,0x00,0x00,0xDA,0x14,0xA1,0x9F,0xE5,0x4B,0x8F,0x8D,0xE2,
+ 0x10,0x90,0x8D,0xE2,0x54,0xB0,0x8D,0xE2,0x08,0x00,0x9D,0xE5,0x04,0x11,0x84,0xE0,
+ 0x81,0x10,0xF0,0xE7,0x01,0x20,0xD0,0xE5,0x00,0x30,0xDA,0xE5,0x84,0x71,0x86,0xE0,
+ 0x92,0x13,0x21,0xE0,0x01,0x18,0xC1,0xE3,0x01,0x10,0xD8,0xE7,0x06,0x10,0xC7,0xE5,
+ 0x04,0x11,0x89,0xE0,0xB0,0x20,0xD1,0xE1,0xB4,0x20,0xC7,0xE1,0x0A,0x20,0x80,0xE2,
+ 0xB0,0x00,0xD1,0xE1,0xFF,0x00,0x00,0xE2,0x08,0x00,0xC2,0xE5,0x0C,0x10,0x9D,0xE5,
+ 0xBE,0x11,0xD1,0xE1,0x01,0x00,0x50,0xE1,0x0C,0x10,0x9D,0x85,0xBE,0x01,0xC1,0x81,
+ 0x84,0x00,0x84,0xE0,0x00,0x51,0x8B,0xE0,0x08,0x10,0x95,0xE5,0x00,0x00,0x51,0xE3,
+ 0x01,0x10,0xA0,0x03,0x08,0x10,0x85,0xE5,0x00,0x01,0x9B,0xE7,0x73,0xF0,0xFF,0xEB,
+ 0xB0,0x00,0xC7,0xE1,0x03,0x00,0x95,0xE9,0x70,0xF0,0xFF,0xEB,0xB2,0x00,0xC7,0xE1,
+ 0x0C,0x00,0x9D,0xE5,0x01,0x40,0x84,0xE2,0x04,0x00,0xD0,0xE5,0x04,0x00,0x50,0xE1,
+ 0xD8,0xFF,0xFF,0xCA,0x0C,0x00,0x9D,0xE5,0x04,0x00,0xD0,0xE5,0x01,0x00,0x50,0xE3,
+ 0xAD,0xDF,0x8D,0xB2,0xF0,0x4F,0xBD,0xB8,0x1E,0xFF,0x2F,0xB1,0x01,0x30,0xA0,0xE3,
+ 0x80,0x21,0x86,0xE0,0x02,0x10,0x52,0xE5,0x00,0x00,0x51,0xE1,0x07,0x00,0x00,0x0A,
+ 0xB0,0x16,0xD6,0xE1,0x01,0xC0,0x40,0xE2,0x13,0x1C,0x81,0xE1,0xB0,0x16,0xC6,0xE1,
+ 0x02,0x20,0x52,0xE5,0x01,0x20,0x42,0xE2,0x13,0x12,0x81,0xE1,0xB0,0x16,0xC6,0xE1,
+ 0x01,0x00,0x40,0xE2,0x01,0x00,0x50,0xE3,0xF0,0xFF,0xFF,0xAA,0xAD,0xDF,0x8D,0xE2,
+ 0xF0,0x4F,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,0xE8,0x07,0x00,0x20,0x40,0x00,0x00,0x20,
+ 0x1F,0x85,0xEB,0x51,0x9C,0x94,0x00,0x00,0x00,0x00,0x00,0x10,0xF0,0xB5,0xD3,0xB0,
+ 0x37,0xA8,0x2B,0x90,0x00,0x20,0x11,0x90,0x10,0x90,0x0F,0x90,0x0D,0x90,0xFE,0x4C,
+ 0x0B,0x90,0x89,0x20,0x80,0x00,0x20,0x18,0x25,0x00,0x8A,0x35,0x06,0x90,0x28,0x00,
+ 0x98,0x30,0x05,0x90,0x2E,0x38,0x06,0x00,0x04,0x90,0xF8,0x48,0xB0,0x36,0x20,0x18,
+ 0x03,0x90,0x02,0x90,0x04,0x22,0x00,0x21,0x09,0xA8,0xFC,0xF7,0xA3,0xF8,0x2E,0x22,
+ 0x00,0x21,0x1F,0xA8,0xFC,0xF7,0x9E,0xF8,0xF1,0x48,0x00,0x21,0x20,0x81,0x61,0x81,
+ 0x60,0x35,0x30,0x00,0xA1,0x81,0x60,0x30,0x69,0x80,0x52,0x90,0x81,0x80,0x0E,0x20,
+ 0x20,0x5E,0xEC,0x49,0x0E,0x90,0x02,0x98,0x20,0x30,0x51,0x90,0x00,0x7A,0xC2,0x07,
+ 0x1C,0xD0,0x80,0x07,0x0D,0xD5,0x01,0x20,0x0D,0x90,0x08,0x78,0x08,0xAB,0x82,0x1E,
+ 0x1A,0x71,0x4A,0x78,0x52,0x1E,0x40,0x1E,0x5A,0x71,0x98,0x71,0x00,0x20,0xD8,0x71,
+ 0x0C,0xE0,0x02,0x20,0x0D,0x90,0x08,0x78,0x08,0xAB,0x40,0x1E,0x18,0x71,0x48,0x78,
+ 0x82,0x1E,0x5A,0x71,0x00,0x22,0x40,0x1E,0x9A,0x71,0xD8,0x71,0xDA,0x4B,0x18,0x68,
+ 0x00,0x68,0x42,0x04,0x01,0xD5,0xD9,0x4A,0x00,0xE0,0xD9,0x4A,0x00,0x04,0x08,0x92,
+ 0x01,0xD5,0xD6,0x48,0x00,0xE0,0xD6,0x48,0x07,0x90,0x00,0x20,0x3F,0x90,0xD1,0x48,
+ 0x40,0x78,0x00,0x28,0x00,0xDC,0x57,0xE3,0x20,0x00,0x40,0x30,0x50,0x90,0xCD,0x48,
+ 0x04,0x99,0x00,0x78,0x42,0x18,0x3F,0x99,0x08,0x31,0x51,0x5C,0x00,0x29,0x00,0xD1,
+ 0x3F,0xE3,0x00,0x25,0x00,0x28,0x00,0xDC,0x38,0xE3,0x3F,0x98,0x80,0x1E,0x00,0x06,
+ 0x00,0x16,0x4F,0x90,0x3F,0x98,0x00,0x06,0x00,0x0E,0x4E,0x90,0x3F,0x98,0x40,0x00,
+ 0x00,0x19,0x40,0x30,0x4D,0x90,0x04,0x98,0x40,0x19,0x00,0x7A,0x00,0x28,0x00,0xD1,
+ 0x1C,0xE3,0xBC,0x4E,0x3F,0x99,0x30,0x78,0x48,0x43,0x40,0x19,0x00,0x04,0x00,0x14,
+ 0xBB,0x49,0x1E,0x90,0x40,0x00,0x0A,0x5E,0xB7,0x49,0x09,0x68,0x60,0x31,0x09,0x88,
+ 0x8A,0x42,0x04,0xDD,0x52,0x99,0x52,0x9A,0x89,0x88,0x49,0x1C,0x91,0x80,0x1E,0x99,
+ 0x1F,0xAA,0xC9,0x10,0x4C,0x91,0x52,0x5C,0x1E,0x99,0x4B,0x07,0x5B,0x0F,0x01,0x21,
+ 0x99,0x40,0x0A,0x42,0x4B,0x91,0x7E,0xD1,0x0D,0x99,0x08,0xAB,0xC9,0x07,0x15,0xD0,
+ 0x99,0x79,0xA9,0x42,0x09,0xD1,0x01,0x21,0x0C,0x91,0xA8,0x49,0x02,0x22,0x08,0x5E,
+ 0x04,0x99,0x8A,0x5E,0x90,0x42,0x6E,0xDB,0x18,0xE0,0x08,0xAB,0x19,0x79,0xA9,0x42,
+ 0x01,0xD1,0x03,0x21,0x00,0xE0,0x02,0x21,0x0C,0x91,0x08,0xE0,0xD9,0x79,0x3F,0x9A,
+ 0x91,0x42,0xE8,0xD0,0x08,0xAB,0x59,0x79,0x91,0x42,0xF4,0xD1,0xF1,0xE7,0x9B,0x49,
+ 0x00,0x22,0x08,0x5E,0x04,0x99,0x8A,0x5E,0x90,0x42,0x54,0xDB,0x30,0x78,0x3F,0x99,
+ 0x4A,0x90,0x48,0x43,0x40,0x19,0x00,0x21,0x43,0x00,0x92,0x48,0x47,0x78,0x3F,0x9A,
+ 0x4A,0x9E,0x52,0x18,0x94,0x46,0x00,0x20,0x52,0x1E,0x56,0x43,0x49,0x96,0x2A,0x18,
+ 0x66,0x46,0x76,0x1E,0x52,0x1E,0x00,0x2E,0x0E,0xDB,0xB7,0x42,0x0C,0xDD,0x00,0x2A,
+ 0x0A,0xDB,0x4A,0x9E,0x96,0x42,0x07,0xDD,0x49,0x9E,0xB2,0x18,0x87,0x4E,0x52,0x00,
+ 0xB2,0x5E,0xF6,0x5E,0xB2,0x42,0x2E,0xDC,0x40,0x1C,0x00,0x04,0x00,0x14,0x03,0x28,
+ 0xE5,0xDB,0x49,0x1C,0x09,0x04,0x09,0x14,0x03,0x29,0xD8,0xDB,0x7F,0x48,0xA2,0x89,
+ 0xC0,0x5E,0x82,0x42,0x05,0xDC,0xA0,0x81,0x20,0x79,0x40,0x1C,0x00,0x06,0x00,0x0E,
+ 0x11,0x90,0x4C,0x98,0x1F,0xAA,0x10,0x5C,0x4B,0x99,0x08,0x43,0x4C,0x99,0x50,0x54,
+ 0x74,0x48,0x00,0x78,0x41,0x1E,0xA9,0x42,0x0B,0xD0,0x1E,0x9A,0x01,0x27,0x52,0x1C,
+ 0xD3,0x10,0x52,0x07,0x52,0x0F,0x1F,0xAE,0xF6,0x5C,0x97,0x40,0x3E,0x43,0x1F,0xAA,
+ 0xD6,0x54,0x6C,0x4A,0x00,0xE0,0x30,0xE1,0x52,0x78,0x3F,0x9B,0x52,0x1E,0x9A,0x42,
+ 0x28,0xD0,0x1E,0x9A,0x01,0x27,0x86,0x18,0xF2,0x10,0x76,0x07,0x76,0x0F,0x1F,0xAB,
+ 0x9B,0x5C,0xB7,0x40,0x3B,0x43,0x1F,0xAE,0x00,0x2D,0xB3,0x54,0x0C,0xD0,0x1E,0x9A,
+ 0x01,0x27,0x52,0x1E,0x86,0x18,0xF2,0x10,0x76,0x07,0x76,0x0F,0x1F,0xAB,0x9B,0x5C,
+ 0xB7,0x40,0x3B,0x43,0x1F,0xAE,0xB3,0x54,0xA9,0x42,0x0B,0xD0,0x1E,0x99,0x1F,0xAA,
+ 0x49,0x1C,0x41,0x18,0xC8,0x10,0x4E,0x07,0x13,0x5C,0x76,0x0F,0x01,0x21,0xB1,0x40,
+ 0x0B,0x43,0x13,0x54,0x28,0x06,0x00,0x0E,0x48,0x90,0x02,0xF0,0xA5,0xFC,0x4F,0x99,
+ 0x00,0x20,0x8C,0x46,0x00,0x21,0x3E,0x91,0xA9,0x1E,0x09,0x06,0x09,0x16,0x1C,0x90,
+ 0x0A,0x90,0x31,0xA8,0x47,0x91,0x3E,0x9B,0x06,0x26,0x5B,0x1E,0x46,0x93,0x3E,0x9B,
+ 0x00,0x22,0x73,0x43,0x2C,0xAF,0xDB,0x19,0x45,0x93,0x63,0x46,0x00,0x2B,0x08,0xDB,
+ 0x44,0x4E,0x73,0x78,0x63,0x45,0x04,0xDD,0x00,0x29,0x02,0xDB,0x33,0x78,0x8B,0x42,
+ 0x02,0xDC,0x00,0x23,0x03,0x80,0x26,0xE0,0x66,0x46,0x73,0x43,0x5B,0x18,0x1B,0x04,
+ 0x1B,0x14,0x5F,0x00,0x08,0x9B,0x0E,0x9E,0xDB,0x5B,0x9B,0x1B,0x1B,0x04,0x1B,0x14,
+ 0x03,0x80,0x01,0xD5,0x00,0x23,0x03,0x80,0x46,0x9B,0x03,0x2B,0x13,0xD2,0x53,0x1E,
+ 0x03,0x2B,0x10,0xD2,0x07,0x9B,0x0E,0x9E,0xDB,0x5B,0x57,0x00,0x9B,0x1B,0x45,0x9E,
+ 0xF6,0x19,0x20,0x3E,0x33,0x83,0x00,0x23,0xC3,0x5E,0x1C,0x9E,0x9B,0x19,0x1C,0x93,
+ 0x0A,0x9B,0x5B,0x1C,0x0A,0x93,0x52,0x1C,0x49,0x1C,0x12,0x04,0x09,0x06,0x80,0x1C,
+ 0x12,0x14,0x09,0x16,0x05,0x2A,0xC0,0xDB,0x3E,0x99,0x49,0x1C,0x09,0x04,0x09,0x14,
+ 0x3E,0x91,0x61,0x46,0x49,0x1C,0x09,0x06,0x09,0x16,0x8C,0x46,0x3E,0x99,0x05,0x29,
+ 0x01,0xDA,0x47,0x99,0xA7,0xE7,0x23,0x48,0x00,0x78,0x00,0x28,0x16,0xD1,0x0A,0x99,
+ 0x49,0x1E,0x01,0x29,0x00,0xDA,0x01,0x21,0x1C,0x98,0xFB,0xF7,0xBF,0xFE,0x0C,0x99,
+ 0x01,0x29,0x0B,0xD1,0x2B,0x9A,0x00,0x21,0x51,0x5E,0x0A,0x1A,0x16,0x48,0x00,0x68,
+ 0x43,0x8E,0x9A,0x42,0x02,0xD2,0x80,0x8E,0x81,0x42,0x7E,0xDB,0x12,0x49,0x38,0x20,
+ 0x09,0x68,0x20,0xAB,0x18,0x5E,0xC9,0x8D,0x48,0x43,0x02,0xF0,0x99,0xFC,0x08,0x04,
+ 0x0C,0x99,0x00,0x14,0x02,0x29,0x40,0xD0,0x0D,0x99,0xC9,0x07,0x27,0xD0,0x04,0x21,
+ 0x00,0x23,0x31,0xAE,0x0C,0x9A,0x01,0x2A,0x16,0xD1,0x0A,0x27,0x0A,0x00,0x7A,0x43,
+ 0xB3,0x52,0x92,0x19,0x53,0x80,0x15,0xE0,0x40,0x00,0x00,0x20,0x64,0x06,0x00,0x00,
+ 0xFF,0x0F,0x00,0x00,0x9C,0x94,0x00,0x00,0xE8,0x07,0x00,0x20,0x2A,0x08,0x00,0x20,
+ 0x00,0x00,0x00,0x10,0xFB,0x07,0x00,0x20,0x0A,0x27,0x0A,0x00,0x7A,0x43,0x92,0x19,
+ 0xD3,0x80,0x13,0x81,0x49,0x1E,0x09,0x04,0x09,0x14,0xDB,0xD5,0x15,0xE0,0x0D,0x99,
+ 0x89,0x07,0x12,0xD5,0x04,0x21,0x00,0x23,0x31,0xAE,0x0C,0x9A,0x01,0x2A,0x04,0xD1,
+ 0x4A,0x00,0xB3,0x52,0x92,0x19,0x53,0x81,0x03,0xE0,0x4A,0x00,0x92,0x19,0xD3,0x83,
+ 0x13,0x85,0x49,0x1E,0x09,0x04,0x09,0x14,0xEF,0xD5,0x2B,0x9A,0x00,0x21,0x51,0x5E,
+ 0x22,0x89,0x8A,0x42,0x00,0xDD,0x21,0x81,0x62,0x89,0x8A,0x42,0x00,0xDA,0x61,0x81,
+ 0x21,0x79,0x0A,0x23,0x49,0x1C,0x09,0x06,0x09,0x0E,0x21,0x71,0x59,0x43,0x05,0x9B,
+ 0x48,0x9A,0xC9,0x18,0x20,0x39,0x8A,0x75,0x21,0x79,0x0A,0x23,0x4E,0x9A,0x59,0x43,
+ 0x05,0x9B,0xC9,0x18,0x20,0x39,0xCA,0x75,0x36,0x22,0x20,0xAB,0x9A,0x5E,0x00,0x21,
+ 0x82,0x42,0x07,0xDC,0x30,0x22,0x9A,0x5E,0x82,0x42,0x03,0xDC,0x3C,0x22,0x9A,0x5E,
+ 0x82,0x42,0x00,0xDD,0x02,0x21,0x20,0xAB,0x00,0xE0,0x47,0xE1,0x3A,0x22,0x9A,0x5E,
+ 0x82,0x42,0x08,0xDC,0x34,0x22,0x9A,0x5E,0x82,0x42,0x04,0xDC,0x00,0x22,0x30,0xAB,
+ 0x9A,0x5E,0x82,0x42,0x01,0xDD,0x04,0x22,0x11,0x43,0x32,0x22,0x20,0xAB,0x9A,0x5E,
+ 0x82,0x42,0x07,0xDC,0x30,0x22,0x9A,0x5E,0x82,0x42,0x03,0xDC,0x34,0x22,0x9A,0x5E,
+ 0x82,0x42,0x01,0xDD,0x08,0x22,0x11,0x43,0x3E,0x22,0x20,0xAB,0x9A,0x5E,0x82,0x42,
+ 0x08,0xDC,0x3C,0x22,0x9A,0x5E,0x82,0x42,0x04,0xDC,0x00,0x22,0x30,0xAB,0x9A,0x5E,
+ 0x82,0x42,0x01,0xDD,0x10,0x20,0x01,0x43,0x04,0x20,0x00,0x23,0x31,0xAA,0x8E,0x07,
+ 0x02,0xD4,0x0A,0x26,0x46,0x43,0x93,0x53,0x4E,0x07,0x03,0xD4,0x0A,0x26,0x46,0x43,
+ 0xB6,0x18,0x33,0x81,0x0E,0x07,0x01,0xD4,0x46,0x00,0x93,0x53,0xCE,0x06,0x02,0xD4,
+ 0x46,0x00,0xB6,0x18,0x33,0x85,0x40,0x1E,0x00,0x04,0x00,0x14,0xE7,0xD5,0x0C,0x22,
+ 0x30,0xAB,0x9A,0x5E,0x0A,0x26,0x06,0x21,0x00,0x92,0x9E,0x5F,0x08,0x22,0x04,0x20,
+ 0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0x38,0xFB,0x16,0x22,0x30,0xAB,
+ 0x1A,0x90,0x9A,0x5E,0x14,0x26,0x10,0x21,0x00,0x92,0x9E,0x5F,0x12,0x22,0x0E,0x20,
+ 0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0x28,0xFB,0x20,0x22,0x30,0xAB,
+ 0x19,0x90,0x9A,0x5E,0x1E,0x26,0x1A,0x21,0x00,0x92,0x9E,0x5F,0x1C,0x22,0x18,0x20,
+ 0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0x18,0xFB,0x2A,0x22,0x30,0xAB,
+ 0x18,0x90,0x9A,0x5E,0x28,0x26,0x24,0x21,0x00,0x92,0x9E,0x5F,0x26,0x22,0x22,0x20,
+ 0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0x08,0xFB,0x34,0x22,0x30,0xAB,
+ 0x17,0x90,0x9A,0x5E,0x32,0x26,0x2E,0x21,0x00,0x92,0x9E,0x5F,0x30,0x22,0x2C,0x20,
+ 0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0xF8,0xFA,0x00,0x90,0x16,0x90,
+ 0x17,0x9B,0x18,0x9A,0x19,0x99,0x1A,0x98,0x01,0xF0,0xF0,0xFA,0x00,0x28,0x1B,0x90,
+ 0x09,0xD1,0x32,0x22,0x00,0x21,0x31,0xA8,0xFB,0xF7,0xB4,0xFD,0x2B,0x99,0x0A,0x20,
+ 0x18,0x90,0x08,0x80,0x1B,0x90,0x2C,0x22,0x30,0xAB,0x9A,0x5E,0x22,0x26,0x0E,0x21,
+ 0x00,0x92,0x9E,0x5F,0x18,0x22,0x04,0x20,0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,
+ 0x01,0xF0,0xD4,0xFA,0x69,0x00,0x09,0x19,0x0F,0x00,0x09,0x8C,0x2E,0x22,0x30,0xAB,
+ 0x48,0x43,0x15,0x90,0x9A,0x5E,0x24,0x26,0x10,0x21,0x00,0x92,0x9E,0x5F,0x1A,0x22,
+ 0x06,0x20,0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0xBF,0xFA,0x79,0x8C,
+ 0x30,0x22,0x30,0xAB,0x48,0x43,0x14,0x90,0x9A,0x5E,0x26,0x26,0x12,0x21,0x00,0x92,
+ 0x9E,0x5F,0x1C,0x22,0x08,0x20,0x9A,0x5E,0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,
+ 0xAD,0xFA,0xB9,0x8C,0x32,0x22,0x30,0xAB,0x48,0x43,0x13,0x90,0x9A,0x5E,0x28,0x26,
+ 0x14,0x21,0x00,0x92,0x9E,0x5F,0x1E,0x22,0x0A,0x20,0x9A,0x5E,0x59,0x5E,0x18,0x5E,
+ 0x33,0x00,0x01,0xF0,0x9B,0xFA,0xF9,0x8C,0x34,0x22,0x30,0xAB,0x48,0x43,0x12,0x90,
+ 0x9A,0x5E,0x2A,0x26,0x16,0x21,0x00,0x92,0x9E,0x5F,0x20,0x22,0x0C,0x20,0x9A,0x5E,
+ 0x59,0x5E,0x18,0x5E,0x33,0x00,0x01,0xF0,0x89,0xFA,0x39,0x8D,0x12,0x9B,0x13,0x9A,
+ 0x48,0x43,0x00,0x90,0x14,0x99,0x15,0x98,0x01,0xF0,0x80,0xFA,0x1B,0x99,0xFB,0xF7,
+ 0xBB,0xFB,0x61,0x8C,0x49,0x00,0x40,0x1A,0x00,0xD5,0x00,0x20,0x21,0x79,0x0A,0x22,
+ 0x51,0x43,0x05,0x9A,0x89,0x18,0x88,0x80,0x4D,0x98,0x1A,0x99,0x80,0x8A,0x19,0x9A,
+ 0x16,0x9F,0x48,0x43,0x4D,0x99,0xC9,0x8A,0x51,0x43,0x4D,0x9A,0x16,0x8B,0x18,0x9A,
+ 0x56,0x43,0x4D,0x9A,0x53,0x8B,0x17,0x9A,0x53,0x43,0x4D,0x9A,0x92,0x8B,0x7A,0x43,
+ 0x00,0x92,0x32,0x00,0x01,0xF0,0x5A,0xFA,0x1B,0x99,0xFB,0xF7,0x95,0xFB,0x50,0x99,
+ 0xC9,0x8A,0x49,0x00,0x40,0x1A,0x00,0xD5,0x00,0x20,0x21,0x79,0x0A,0x22,0x51,0x43,
+ 0x05,0x9A,0x89,0x18,0xC8,0x80,0x20,0x79,0x0C,0x28,0x15,0xD2,0xA4,0x48,0x6D,0x1C,
+ 0x00,0x78,0x2D,0x04,0x2D,0x14,0xA8,0x42,0x00,0xDD,0xD4,0xE4,0x10,0x98,0x00,0x28,
+ 0x0A,0xD1,0x3F,0x98,0x40,0x1C,0x00,0x04,0x00,0x14,0x3F,0x90,0x9C,0x48,0x3F,0x99,
+ 0x40,0x78,0x88,0x42,0x00,0xDD,0xAA,0xE4,0x9A,0x48,0x00,0x68,0x07,0x00,0x00,0x68,
+ 0x00,0x06,0x46,0xD5,0x20,0x79,0x00,0x28,0x0C,0xD1,0x05,0x98,0x60,0x30,0x41,0x8B,
+ 0x00,0x29,0x3A,0xD0,0x3D,0x22,0x01,0x7E,0xD2,0x5D,0x91,0x42,0x35,0xD2,0x49,0x1C,
+ 0x01,0x76,0x36,0xE0,0x05,0x9D,0x3E,0x00,0x60,0x35,0x20,0x36,0x68,0x7E,0xB1,0x7E,
+ 0x88,0x42,0x27,0xD8,0x40,0x1C,0x00,0x06,0x00,0x0E,0x68,0x76,0xF1,0x7E,0x81,0x42,
+ 0x03,0xD2,0xA2,0x89,0x0F,0x9B,0xD2,0x18,0x0F,0x92,0xB2,0x7E,0x90,0x42,0x19,0xD1,
+ 0x88,0x42,0x17,0xD0,0x41,0x1A,0x0F,0x98,0xFB,0xF7,0xA0,0xFC,0x00,0x21,0x69,0x83,
+ 0xF9,0x8F,0x81,0x42,0x0E,0xD2,0x04,0x99,0xC9,0x88,0x40,0x1A,0x31,0x7F,0x48,0x43,
+ 0x02,0xF0,0xA6,0xFA,0x09,0x04,0x09,0x0C,0x40,0x20,0x69,0x83,0xC0,0x5B,0x81,0x42,
+ 0x00,0xD9,0x68,0x83,0x00,0x20,0x28,0x76,0x03,0xE0,0x00,0x21,0x41,0x76,0x01,0x76,
+ 0x41,0x83,0xFD,0xF7,0xB3,0xF8,0x00,0x20,0x03,0x00,0x1D,0x90,0x20,0x79,0x01,0x22,
+ 0x01,0x28,0x57,0xDB,0x0A,0x20,0x50,0x43,0x05,0x99,0x6F,0x4B,0x41,0x18,0x04,0x20,
+ 0x08,0x5E,0x58,0x43,0x83,0x14,0xC0,0x17,0x18,0x1A,0x88,0x80,0x44,0x90,0x06,0x20,
+ 0x08,0x5E,0x69,0x4B,0x58,0x43,0x83,0x14,0xC0,0x17,0x18,0x1A,0xC8,0x80,0x51,0x9D,
+ 0x43,0x90,0x6D,0x7A,0x00,0x23,0x18,0x00,0x00,0x2D,0x42,0x95,0x34,0xDD,0x16,0x06,
+ 0x36,0x0E,0x5F,0x4D,0x20,0x39,0x8C,0x46,0x41,0x96,0x29,0x78,0x40,0x91,0x02,0x99,
+ 0xC6,0x00,0x71,0x18,0x04,0x27,0xCF,0x5F,0x44,0x9D,0xBD,0x42,0x1E,0xDB,0x06,0x27,
+ 0xCF,0x5F,0xBD,0x42,0x1A,0xDC,0x02,0x9F,0x43,0x9D,0xBE,0x5F,0xB5,0x42,0x15,0xDB,
+ 0x02,0x26,0x8E,0x5F,0xB5,0x42,0x11,0xDC,0x61,0x46,0xC9,0x7D,0x40,0x9D,0x69,0x43,
+ 0x65,0x46,0xAD,0x7D,0x49,0x19,0x51,0x4D,0x49,0x00,0x69,0x5E,0x1D,0x9D,0xA9,0x42,
+ 0x04,0xDD,0x1D,0x91,0x01,0x06,0x41,0x9B,0x09,0x0E,0x0B,0x91,0x40,0x1C,0x42,0x99,
+ 0x00,0x04,0x00,0x14,0x81,0x42,0xD2,0xDC,0x20,0x79,0x52,0x1C,0x12,0x04,0x12,0x14,
+ 0x90,0x42,0xA7,0xDA,0x0B,0x98,0x01,0x28,0x00,0xD0,0x00,0x20,0x18,0x42,0x1B,0xD0,
+ 0x3F,0x48,0x28,0x21,0x00,0x78,0x42,0x4A,0x1E,0x25,0x41,0x43,0x89,0x18,0x20,0x39,
+ 0x4D,0x5F,0x2A,0x21,0x48,0x43,0x80,0x18,0x20,0x38,0x1E,0x21,0x41,0x5E,0x8D,0x42,
+ 0x0A,0xDD,0x0A,0x20,0x58,0x43,0x05,0x99,0x40,0x18,0xC1,0x88,0x26,0x39,0xC1,0x80,
+ 0x20,0x38,0xC1,0x7D,0x49,0x1E,0xC1,0x75,0x61,0x89,0x1D,0x98,0x81,0x42,0x18,0xDC,
+ 0x00,0x2B,0x16,0xD0,0x0A,0x20,0x43,0x43,0x05,0x98,0x04,0x25,0x18,0x18,0x06,0x26,
+ 0x45,0x5F,0x86,0x5F,0x00,0x20,0x02,0x00,0x01,0x00,0x0A,0x23,0x59,0x43,0x05,0x9B,
+ 0x40,0x1C,0xC9,0x18,0x00,0x04,0x00,0x14,0x8A,0x80,0x0C,0x28,0xCA,0x80,0xF3,0xD3,
+ 0x24,0xE0,0x60,0x79,0x00,0x28,0x2B,0xD1,0x20,0x79,0x01,0x28,0x28,0xD9,0x06,0x98,
+ 0xFF,0x30,0x01,0x30,0x40,0x7D,0x00,0x28,0x22,0xD1,0x11,0x98,0x00,0x28,0x1F,0xD0,
+ 0x0A,0x21,0x48,0x43,0x05,0x99,0x04,0x25,0x40,0x18,0x06,0x26,0x45,0x5F,0x86,0x5F,
+ 0x00,0x20,0x02,0x00,0x01,0x00,0x0A,0x23,0x59,0x43,0x05,0x9B,0x40,0x1C,0xC9,0x18,
+ 0x00,0x04,0x00,0x14,0x8A,0x80,0x0C,0x28,0xCA,0x80,0xF3,0xD3,0x01,0x20,0x20,0x71,
+ 0x05,0x98,0x0A,0x21,0xC5,0x81,0x20,0x79,0x48,0x43,0x05,0x99,0x40,0x18,0xC6,0x80,
+ 0x03,0x98,0x60,0x30,0x01,0x78,0x00,0x29,0x0B,0xD0,0x0A,0x4A,0x00,0x23,0x23,0x71,
+ 0x12,0x68,0x41,0x78,0xC0,0x32,0x12,0x7B,0x91,0x42,0x00,0xD3,0x03,0x70,0x49,0x1C,
+ 0x41,0x70,0x20,0x79,0x60,0x71,0xA0,0x76,0x53,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,
+ 0x9C,0x94,0x00,0x00,0xE8,0x07,0x00,0x20,0x67,0x66,0x00,0x00,0x00,0x00,0x00,0x10,
+ 0x2A,0x08,0x00,0x20,0x0E,0x49,0x10,0xB5,0x0C,0x48,0x09,0x78,0x80,0x8B,0x00,0x24,
+ 0x00,0x29,0x02,0xD0,0x0B,0x49,0x49,0x89,0x02,0xE0,0x0B,0x49,0x09,0x68,0x89,0x8B,
+ 0x08,0x18,0x0A,0x49,0xC9,0x6B,0x49,0x04,0x49,0x0C,0x81,0x42,0x00,0xD3,0x01,0x24,
+ 0xFE,0xF7,0xCC,0xFE,0x20,0x00,0x10,0xBC,0x08,0xBC,0x18,0x47,0xC0,0x01,0x00,0x20,
+ 0xFA,0x07,0x00,0x20,0x1C,0x95,0x00,0x00,0xE8,0x07,0x00,0x20,0xC0,0x90,0x00,0x40,
+ 0xF7,0xB5,0x30,0x4B,0x00,0x20,0x82,0xB0,0x01,0x90,0x58,0x78,0x99,0x78,0x00,0x02,
+ 0x08,0x43,0x01,0xF0,0xB9,0xFD,0x58,0x79,0xC0,0x07,0x0A,0xD0,0x2A,0x48,0x01,0x78,
+ 0x2A,0x48,0x80,0x7B,0x00,0x29,0x02,0xD0,0x01,0xF0,0x56,0xFD,0x01,0xE0,0x01,0xF0,
+ 0x81,0xFD,0x02,0xF0,0x25,0xF9,0x00,0x26,0x77,0x1E,0x25,0x49,0x25,0x48,0x8A,0x69,
+ 0x02,0x62,0x49,0x6B,0x41,0x62,0x00,0x21,0xC1,0x62,0x05,0x24,0x01,0xE0,0x05,0x2C,
+ 0x02,0xD1,0x02,0x25,0xED,0x43,0x0E,0xE0,0x04,0x2C,0x01,0xD1,0x03,0x25,0x0A,0xE0,
+ 0x03,0x2C,0x03,0xD0,0x02,0x2C,0x05,0xD0,0x01,0x2C,0x01,0xD1,0x3D,0x00,0x02,0xE0,
+ 0x00,0x2C,0x00,0xD1,0x01,0x25,0xE0,0x07,0xC0,0x0F,0x29,0x00,0xFC,0xF7,0x58,0xF9,
+ 0x64,0x1E,0xE4,0xD5,0x12,0x48,0x13,0x49,0x00,0x6D,0xC8,0x62,0x0D,0x48,0x20,0x38,
+ 0x80,0x7F,0x01,0x00,0xFC,0xF7,0xC6,0xF9,0x01,0x24,0x02,0xA8,0x07,0xC8,0xFE,0xF7,
+ 0x03,0xFE,0x00,0x28,0x01,0xD1,0x00,0x24,0x26,0x00,0x64,0x1E,0xF5,0xD5,0x76,0x1E,
+ 0xC3,0xD5,0x01,0x99,0x00,0x29,0x00,0xD0,0x05,0x20,0x05,0xB0,0xF0,0xBC,0x08,0xBC,
+ 0x18,0x47,0x00,0x00,0xDC,0x94,0x00,0x00,0xF4,0x07,0x00,0x20,0xC4,0x06,0x00,0x20,
+ 0x44,0x95,0x00,0x00,0x80,0x90,0x00,0x40,0x78,0x47,0xC0,0x46,0xF0,0x4F,0x2D,0xE9,
+ 0x34,0x78,0x9F,0xE5,0x34,0x08,0x9F,0xE5,0x6F,0xDF,0x4D,0xE2,0x00,0x50,0x90,0xE5,
+ 0x00,0x80,0xA0,0xE3,0x69,0x6F,0x87,0xE2,0xB6,0x86,0xC6,0xE1,0x01,0x4C,0x87,0xE2,
+ 0xB8,0x86,0xC6,0xE1,0x22,0x40,0x84,0xE2,0x04,0x20,0xA0,0xE3,0x08,0x10,0xA0,0xE1,
+ 0x04,0x00,0x8D,0xE2,0xBA,0x86,0xC6,0xE1,0x91,0xED,0xFF,0xEB,0xBE,0x87,0xC4,0xE1,
+ 0x80,0x00,0xD4,0xE5,0xF8,0xB7,0x9F,0xE5,0x00,0x80,0xA0,0xE3,0x00,0x00,0x50,0xE3,
+ 0xB6,0x00,0xD7,0x01,0x02,0x0C,0xC0,0x03,0xB6,0x00,0xC7,0x01,0x01,0x00,0x40,0x12,
+ 0x80,0x00,0xC4,0x15,0x1B,0x00,0xD7,0xE5,0x00,0x00,0x50,0xE3,0x62,0x00,0x00,0xDA,
+ 0xD0,0xA7,0x9F,0xE5,0xD0,0xE7,0x9F,0xE5,0x00,0x30,0xA0,0xE3,0x7C,0x30,0xC4,0xE5,
+ 0x08,0x01,0x88,0xE0,0x7D,0x30,0xC4,0xE5,0x80,0x10,0xD4,0xE7,0x80,0xC0,0x84,0xE0,
+ 0x03,0x10,0x41,0xE2,0x01,0x1C,0xA0,0xE1,0x41,0x1C,0xA0,0xE1,0x06,0x10,0xCD,0xE5,
+ 0x80,0x20,0xD4,0xE7,0x00,0x00,0x51,0xE3,0x03,0x20,0x82,0xE2,0x02,0x2C,0xA0,0xE1,
+ 0x42,0x2C,0xA0,0xE1,0x07,0x20,0xCD,0xE5,0x01,0x00,0xDC,0xE5,0x03,0x00,0x40,0xE2,
+ 0x00,0x0C,0xA0,0xE1,0x40,0x0C,0xA0,0xE1,0x04,0x00,0xCD,0xE5,0x01,0xC0,0xDC,0xE5,
+ 0x03,0xC0,0x8C,0xE2,0x0C,0xCC,0xA0,0xE1,0x4C,0xCC,0xA0,0xE1,0x05,0xC0,0xCD,0xE5,
+ 0x06,0x30,0xCD,0xB5,0x00,0x10,0xDE,0xE5,0x01,0x00,0x52,0xE1,0x00,0x10,0xDE,0xA5,
+ 0x07,0x10,0xCD,0xA5,0x00,0x00,0x50,0xE3,0x04,0x30,0xCD,0xB5,0x01,0x00,0xDE,0xE5,
+ 0x01,0x00,0x40,0xE2,0x00,0x00,0x5C,0xE1,0x05,0x00,0xCD,0xA5,0xD4,0x00,0xDD,0xE1,
+ 0xD5,0x10,0xDD,0xE1,0x01,0x00,0x50,0xE1,0x23,0x00,0x00,0xCA,0xD6,0x10,0xDD,0xE1,
+ 0xD4,0x90,0xDD,0xE1,0x00,0x00,0xDE,0xE5,0xD7,0x20,0xDD,0xE1,0x99,0x10,0x20,0xE0,
+ 0x01,0x00,0x52,0xE1,0x15,0x00,0x00,0xBA,0x80,0x20,0x8B,0xE0,0xB0,0x20,0xD2,0xE1,
+ 0x80,0x30,0x8A,0xE0,0xB0,0x30,0xD3,0xE1,0x02,0x2A,0xA0,0xE1,0x22,0x2A,0xA0,0xE1,
+ 0x0F,0x3A,0xC3,0xE3,0x03,0xC0,0x42,0xE0,0x02,0x20,0x43,0xE0,0x32,0x00,0x52,0xE3,
+ 0x7C,0x20,0xD4,0xC5,0x01,0x10,0x81,0xE2,0x01,0x00,0x80,0xE2,0x01,0x20,0x82,0xC2,
+ 0x7C,0x20,0xC4,0xC5,0x4B,0x0F,0x5C,0xE3,0x7D,0x20,0xD4,0xC5,0x01,0x20,0x82,0xC2,
+ 0x7D,0x20,0xC4,0xC5,0xD7,0x20,0xDD,0xE1,0x01,0x00,0x52,0xE1,0xE9,0xFF,0xFF,0xAA,
+ 0x01,0x00,0x89,0xE2,0x00,0x0C,0xA0,0xE1,0x40,0x0C,0xA0,0xE1,0x04,0x00,0xCD,0xE5,
+ 0xD5,0x10,0xDD,0xE1,0x01,0x00,0x50,0xE1,0xDB,0xFF,0xFF,0xDA,0x7C,0x00,0xD4,0xE5,
+ 0x02,0x00,0x50,0xE3,0x0C,0x00,0x00,0x9A,0x7D,0x00,0xD4,0xE5,0x03,0x00,0x50,0xE3,
+ 0x09,0x00,0x00,0x2A,0xBE,0x07,0xD4,0xE1,0x01,0x10,0x88,0xE2,0x01,0x20,0xA0,0xE3,
+ 0x12,0x01,0x80,0xE1,0xBE,0x07,0xC4,0xE1,0xB6,0x00,0xD7,0xE1,0x02,0x0C,0x80,0xE3,
+ 0xB6,0x00,0xC7,0xE1,0x0A,0x00,0xA0,0xE3,0x80,0x00,0xC4,0xE5,0x1B,0x00,0xD7,0xE5,
+ 0x01,0x80,0x88,0xE2,0x08,0x00,0x50,0xE1,0x9E,0xFF,0xFF,0xCA,0x4C,0x06,0x9F,0xE5,
+ 0x00,0x80,0xA0,0xE3,0x00,0x00,0xD0,0xE5,0x00,0x00,0x50,0xE3,0x38,0x16,0x9F,0x15,
+ 0xFC,0x02,0xD5,0x01,0xF8,0x08,0xD1,0x11,0xBA,0x12,0xD5,0x01,0xB6,0x18,0xD1,0x11,
+ 0x91,0x00,0x00,0xE0,0xA4,0x11,0x8D,0xE5,0x24,0x16,0x9F,0xE5,0x91,0x20,0xC0,0xE0,
+ 0xC0,0x12,0xA0,0xE1,0xC0,0x0F,0x41,0xE0,0x00,0x08,0xA0,0xE1,0x40,0x08,0xA0,0xE1,
+ 0xA8,0x01,0x8D,0xE5,0x62,0x1F,0xA0,0xE3,0x1C,0x00,0x8D,0xE2,0x1C,0x80,0xC7,0xE5,
+ 0x16,0xED,0xFF,0xEB,0xE0,0xA5,0x9F,0xE5,0x00,0x40,0xA0,0xE3,0x08,0x90,0xA0,0xE1,
+ 0x38,0x20,0xA0,0xE3,0x04,0x10,0xA0,0xE1,0x76,0x0E,0x8A,0xE2,0x18,0x80,0x8D,0xE5,
+ 0x14,0x80,0x8D,0xE5,0x10,0x80,0x8D,0xE5,0x0C,0x80,0x8D,0xE5,0x08,0x80,0x8D,0xE5,
+ 0xFF,0xEC,0xFF,0xEB,0x0E,0x20,0xA0,0xE3,0x00,0x10,0xA0,0xE3,0x75,0x0E,0x8A,0xE2,
+ 0xFB,0xEC,0xFF,0xEB,0xB0,0x05,0x9F,0xE5,0x00,0xC0,0xA0,0xE3,0x01,0x00,0xD0,0xE5,
+ 0x00,0x00,0x50,0xE3,0x76,0x00,0x00,0xDA,0x02,0x0C,0x87,0xE2,0xB8,0x01,0x8D,0xE5,
+ 0x94,0x05,0x9F,0xE5,0x00,0x20,0xA0,0xE3,0x00,0x00,0xD0,0xE5,0x00,0x00,0x50,0xE3,
+ 0x60,0x00,0x00,0xDA,0x1C,0x00,0x8D,0xE2,0x0C,0x31,0x80,0xE0,0x70,0x05,0x9F,0xE5,
+ 0x84,0xA0,0x80,0xE0,0xB0,0x00,0xDA,0xE1,0x00,0x1A,0xA0,0xE1,0x64,0x05,0x9F,0xE5,
+ 0x21,0x1A,0xA0,0xE1,0x84,0x00,0x80,0xE0,0xB0,0x00,0xD0,0xE1,0x0F,0xBA,0xC0,0xE3,
+ 0x0B,0x00,0x41,0xE0,0x01,0x10,0x4B,0xE0,0x00,0x00,0x51,0xE3,0x0B,0x00,0x00,0xDA,
+ 0x32,0x00,0x51,0xE3,0x04,0x00,0x00,0xDA,0x2C,0xB5,0x9F,0xE5,0x02,0xB0,0x8B,0xE0,
+ 0x50,0xE7,0xDB,0xE5,0x01,0xE0,0x8E,0xE2,0x50,0xE7,0xCB,0xE5,0x18,0xB5,0x9F,0xE5,
+ 0x02,0xB1,0x8B,0xE0,0x60,0xE7,0x9B,0xE5,0x01,0x00,0x5E,0xE1,0x60,0x17,0x8B,0x35,
+ 0x00,0x00,0x50,0xE3,0x21,0x00,0x00,0xDA,0x1C,0x10,0x8D,0xE2,0xB0,0x00,0xCA,0xE1,
+ 0x02,0xA1,0x91,0xE7,0x00,0xA0,0x8A,0xE0,0x02,0xA1,0x81,0xE7,0x60,0x10,0x93,0xE5,
+ 0x00,0x10,0x81,0xE0,0x60,0x10,0x83,0xE5,0x10,0x10,0x9D,0xE5,0x00,0x00,0x51,0xE1,
+ 0x10,0x10,0x8D,0xB2,0x05,0x10,0x81,0xB8,0xB8,0x16,0xD5,0xE1,0x00,0x00,0x51,0xE1,
+ 0x07,0x00,0x00,0xAA,0xB6,0x16,0xD6,0xE1,0x01,0x10,0x81,0xE2,0xB6,0x16,0xC6,0xE1,
+ 0xBA,0x16,0xD5,0xE1,0x00,0x00,0x51,0xE1,0xBA,0x16,0xD6,0xB1,0x01,0x10,0x81,0xB2,
+ 0xBA,0x16,0xC6,0xB1,0xB6,0x1B,0xD5,0xE1,0x00,0x00,0x51,0xE1,0x23,0x00,0x00,0xAA,
+ 0x81,0x00,0x50,0xE1,0x08,0xA0,0x9D,0xE5,0x0C,0x00,0x9D,0xC5,0x01,0xA0,0x8A,0xE2,
+ 0x01,0x00,0x80,0xC2,0x08,0xA0,0x8D,0xE5,0x0C,0x00,0x8D,0xC5,0x1B,0x00,0x00,0xEA,
+ 0x00,0x00,0xA0,0xE3,0xB0,0x00,0xCA,0xE1,0x1C,0x00,0x8D,0xE2,0x02,0x01,0x80,0xE0,
+ 0xC0,0xA0,0x90,0xE5,0x01,0xA0,0x8A,0xE0,0xC0,0xA0,0x80,0xE5,0x20,0x01,0x93,0xE5,
+ 0x01,0x00,0x80,0xE0,0x20,0x01,0x83,0xE5,0xBC,0x06,0xD5,0xE1,0x01,0x00,0x50,0xE1,
+ 0xB8,0x06,0xD6,0xB1,0x01,0x00,0x80,0xB2,0xB8,0x06,0xC6,0xB1,0xB6,0x0B,0xD5,0xE1,
+ 0x01,0x00,0x50,0xE1,0x02,0x00,0x00,0xAA,0x80,0x00,0x51,0xE1,0x01,0x80,0x88,0xE2,
+ 0x01,0x90,0x89,0xC2,0x96,0x00,0x51,0xE3,0x04,0x00,0x00,0xDA,0xB8,0x01,0x9D,0xE5,
+ 0xB8,0x11,0x9D,0xE5,0xB0,0x02,0xD0,0xE1,0x01,0x00,0x80,0xE2,0xB0,0x02,0xC1,0xE1,
+ 0x14,0x04,0x9F,0xE5,0x01,0x20,0x82,0xE2,0x00,0x00,0xD0,0xE5,0x01,0x40,0x84,0xE2,
+ 0x02,0x00,0x50,0xE1,0xA0,0xFF,0xFF,0xCA,0x1C,0x00,0x8D,0xE2,0x0C,0x01,0x80,0xE0,
+ 0x9C,0x11,0x9D,0xE5,0x60,0x20,0x90,0xE5,0x01,0xC0,0x8C,0xE2,0x02,0x10,0x81,0xE0,
+ 0x9C,0x11,0x8D,0xE5,0xA0,0x11,0x9D,0xE5,0x20,0x01,0x90,0xE5,0x01,0x00,0x80,0xE0,
+ 0xA0,0x01,0x8D,0xE5,0xD0,0x03,0x9F,0xE5,0x01,0x00,0xD0,0xE5,0x0C,0x00,0x50,0xE1,
+ 0x8A,0xFF,0xFF,0xCA,0x05,0xFA,0xFF,0xEB,0xB8,0x02,0xD5,0xE1,0xBE,0x00,0xC7,0xE1,
+ 0x00,0x00,0x95,0xE5,0x01,0x00,0x10,0xE3,0x0E,0x00,0x00,0x0A,0xA4,0x01,0x9D,0xE5,
+ 0x9C,0x11,0x9D,0xE5,0x91,0x00,0x00,0xE0,0x9C,0x13,0x9F,0xE5,0x01,0x20,0xD1,0xE5,
+ 0x00,0x10,0xD1,0xE5,0x92,0x01,0x01,0xE0,0x64,0x20,0xA0,0xE3,0x92,0x01,0x01,0xE0,
+ 0x4E,0xEC,0xFF,0xEB,0xA8,0x11,0x9D,0xE5,0x01,0x00,0x80,0xE0,0xB8,0x12,0xD5,0xE1,
+ 0x00,0x00,0x51,0xE1,0xBE,0x00,0xC7,0x81,0x8A,0x60,0x87,0xE2,0x60,0x20,0xA0,0xE3,
+ 0x00,0x10,0xA0,0xE3,0x06,0x00,0xA0,0xE1,0x65,0xEC,0xFF,0xEB,0x58,0x03,0x9F,0xE5,
+ 0x00,0xA0,0xA0,0xE3,0xB0,0xA6,0xC6,0xE1,0x01,0x00,0xD0,0xE5,0x0A,0x40,0xA0,0xE1,
+ 0x00,0x00,0x50,0xE3,0x29,0x00,0x00,0xDA,0x1C,0x00,0x8D,0xE2,0x04,0x01,0x80,0xE0,
+ 0xB4,0x01,0x8D,0xE5,0x08,0x10,0xD5,0xE5,0x60,0x00,0x90,0xE5,0x64,0x20,0xA0,0xE3,
+ 0x91,0x00,0x00,0xE0,0x20,0x13,0x9F,0xE5,0x00,0x10,0xD1,0xE5,0x92,0x01,0x01,0xE0,
+ 0xB0,0x11,0x8D,0xE5,0x31,0xEC,0xFF,0xEB,0x00,0xB0,0xA0,0xE1,0xB4,0x01,0x9D,0xE5,
+ 0x09,0x10,0xD5,0xE5,0x20,0x01,0x90,0xE5,0x91,0x00,0x00,0xE0,0xB0,0x11,0x9D,0xE5,
+ 0x2A,0xEC,0xFF,0xEB,0xB0,0x11,0xD5,0xE1,0x0B,0x00,0x51,0xE1,0x01,0xB0,0xA0,0xB1,
+ 0xB2,0x11,0xD5,0xE1,0x00,0x00,0x51,0xE1,0x01,0x00,0xA0,0xB1,0xBC,0x10,0xD5,0xE1,
+ 0x00,0x00,0x4B,0xE0,0x91,0x00,0x00,0xE0,0x00,0x08,0xA0,0xE1,0x40,0x08,0xA0,0xE1,
+ 0x00,0x15,0x60,0xE0,0x01,0x11,0x81,0xE0,0x80,0x03,0x81,0xE0,0xC0,0x19,0xA0,0xE1,
+ 0xC0,0x0F,0x41,0xE0,0x84,0x10,0x86,0xE0,0xB0,0x03,0xC1,0xE1,0xA8,0x02,0x9F,0xE5,
+ 0x01,0x40,0x84,0xE2,0x01,0x00,0xD0,0xE5,0x04,0x00,0x50,0xE1,0xD5,0xFF,0xFF,0xCA,
+ 0x94,0x02,0x9F,0xE5,0x00,0x40,0xA0,0xE3,0x00,0x00,0xD0,0xE5,0x00,0x00,0x50,0xE3,
+ 0x28,0x00,0x00,0xDA,0x0A,0x10,0xD5,0xE5,0x1C,0x00,0x8D,0xE2,0x04,0x01,0x90,0xE7,
+ 0x64,0x20,0xA0,0xE3,0x91,0x00,0x00,0xE0,0x6C,0x12,0x9F,0xE5,0x01,0x10,0xD1,0xE5,
+ 0x92,0x01,0x01,0xE0,0xAC,0x11,0x8D,0xE5,0x04,0xEC,0xFF,0xEB,0x00,0xB0,0xA0,0xE1,
+ 0x1C,0x00,0x8D,0xE2,0x0B,0x10,0xD5,0xE5,0x04,0x01,0x80,0xE0,0xC0,0x00,0x90,0xE5,
+ 0x91,0x00,0x00,0xE0,0xAC,0x11,0x9D,0xE5,0xFC,0xEB,0xFF,0xEB,0xB4,0x11,0xD5,0xE1,
+ 0x0B,0x00,0x51,0xE1,0x01,0xB0,0xA0,0xB1,0xB6,0x11,0xD5,0xE1,0x00,0x00,0x51,0xE1,
+ 0x01,0x00,0xA0,0xB1,0xBE,0x10,0xD5,0xE1,0x00,0x00,0x4B,0xE0,0x91,0x00,0x00,0xE0,
+ 0x00,0x08,0xA0,0xE1,0x40,0x08,0xA0,0xE1,0x00,0x15,0x60,0xE0,0x01,0x11,0x81,0xE0,
+ 0x80,0x03,0x81,0xE0,0xC0,0x19,0xA0,0xE1,0xC0,0x0F,0x41,0xE0,0x84,0x10,0x86,0xE0,
+ 0xB0,0x00,0xC1,0xE1,0xF0,0x01,0x9F,0xE5,0x01,0x40,0x84,0xE2,0x00,0x00,0xD0,0xE5,
+ 0x04,0x00,0x50,0xE1,0xD6,0xFF,0xFF,0xCA,0x00,0x00,0x5A,0xE3,0x08,0x00,0x00,0xDA,
+ 0x14,0x00,0x9D,0xE5,0x80,0x00,0x86,0xE0,0xF0,0x10,0xD0,0xE1,0x18,0x00,0x9D,0xE5,
+ 0x80,0x00,0x86,0xE0,0xF0,0x03,0xD0,0xE1,0x01,0x00,0x80,0xE0,0x00,0xA0,0x5A,0xE0,
+ 0x00,0xA0,0xA0,0x43,0xB0,0x01,0x9F,0xE5,0xB0,0xA6,0xC6,0xE1,0x01,0x10,0xD0,0xE5,
+ 0x00,0x00,0xD0,0xE5,0x00,0x40,0xA0,0xE3,0x01,0x00,0x40,0xE2,0x90,0x01,0x01,0xE0,
+ 0xA0,0x01,0x9D,0xE5,0xD1,0xEB,0xFF,0xEB,0xA0,0x01,0x8D,0xE5,0x78,0x01,0x9F,0xE5,
+ 0xB6,0x00,0xD0,0xE1,0x08,0x00,0x10,0xE3,0xA0,0x01,0x9D,0xE5,0x0F,0x00,0x00,0x0A,
+ 0xFA,0x00,0x50,0xE3,0x08,0x00,0x9D,0xE5,0x01,0x40,0xA0,0x83,0x80,0x00,0x58,0xE1,
+ 0x01,0x40,0xA0,0xC3,0x23,0x00,0x59,0xE3,0x02,0x00,0x00,0xDA,0x0C,0x00,0x9D,0xE5,
+ 0x23,0x00,0x50,0xE3,0x01,0x40,0xA0,0xB3,0xB6,0x00,0xD7,0xE1,0x80,0x00,0x00,0xE2,
+ 0x00,0x00,0x50,0xE3,0x14,0x00,0x58,0x13,0x11,0x00,0x00,0xDA,0x0F,0x00,0x00,0xEA,
+ 0x96,0x00,0x50,0xE3,0x08,0x00,0x9D,0xE5,0x01,0x40,0xA0,0x83,0x00,0x00,0x58,0xE1,
+ 0x08,0x00,0x58,0xC3,0x01,0x40,0xA0,0xC3,0x14,0x00,0x59,0xE3,0x02,0x00,0x00,0xDA,
+ 0x0C,0x00,0x9D,0xE5,0x14,0x00,0x50,0xE3,0x01,0x40,0xA0,0xB3,0xB6,0x00,0xD7,0xE1,
+ 0x80,0x00,0x00,0xE2,0x00,0x00,0x50,0xE3,0x0A,0x00,0x58,0x13,0x00,0x00,0x00,0xDA,
+ 0x01,0x40,0xA0,0xE3,0xF0,0x10,0xD7,0xE5,0xEE,0x00,0x87,0xE2,0x00,0x00,0x51,0xE3,
+ 0x04,0x10,0xD0,0x05,0x00,0x00,0x51,0x03,0x03,0x10,0xD0,0xE5,0x03,0x00,0x00,0x0A,
+ 0xFF,0x00,0x51,0xE3,0x05,0x00,0x00,0x2A,0x01,0x10,0x81,0xE2,0x02,0x00,0x00,0xEA,
+ 0x00,0x00,0x51,0xE3,0x01,0x00,0x00,0x0A,0x01,0x10,0x41,0xE2,0x03,0x10,0xC0,0xE5,
+ 0x03,0x10,0xD0,0xE5,0xBC,0x20,0xD5,0xE5,0x02,0x00,0x51,0xE1,0x0A,0x00,0x00,0x9A,
+ 0x00,0x00,0x54,0xE3,0x08,0x00,0x00,0x0A,0x00,0x10,0xD0,0xE5,0xFF,0x00,0x51,0xE3,
+ 0x01,0x10,0x81,0x32,0x00,0x10,0xC0,0x35,0x01,0x10,0xD0,0xE5,0x00,0x00,0x51,0xE3,
+ 0x01,0x10,0x41,0x12,0x01,0x10,0xC0,0x15,0x0C,0x00,0x00,0xEA,0x01,0x10,0xD0,0xE5,
+ 0x01,0x10,0x81,0xE2,0xFF,0x10,0x01,0xE2,0x01,0x10,0xC0,0xE5,0xB9,0x20,0xD5,0xE5,
+ 0x02,0x00,0x51,0xE1,0x05,0x00,0x00,0x1A,0x00,0x10,0xA0,0xE3,0x01,0x10,0xC0,0xE5,
+ 0x00,0x10,0xD0,0xE5,0x00,0x00,0x51,0xE3,0x01,0x10,0x41,0x12,0x00,0x10,0xC0,0x15,
+ 0x03,0x10,0xD0,0xE5,0xBD,0x20,0xD5,0xE5,0x02,0x00,0x51,0xE1,0x6F,0xDF,0x8D,0x22,
+ 0xF0,0x4F,0xBD,0x28,0x1E,0xFF,0x2F,0x21,0x00,0x10,0xD0,0xE5,0x00,0x00,0x51,0xE3,
+ 0xBE,0x10,0xD5,0x15,0x00,0x10,0xC0,0x15,0x00,0x10,0xA0,0xE3,0x01,0x10,0xC0,0xE5,
+ 0x6F,0xDF,0x8D,0xE2,0xF0,0x4F,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,0x40,0x00,0x00,0x20,
+ 0xE8,0x07,0x00,0x20,0x00,0x00,0x00,0x10,0xD2,0x02,0x00,0x10,0x9C,0x94,0x00,0x00,
+ 0xFA,0x07,0x00,0x20,0x1F,0x85,0xEB,0x51,0xFE,0xB5,0x01,0x20,0x6E,0x4C,0x40,0x03,
+ 0xFB,0xF7,0x24,0xFA,0xFA,0xF7,0x28,0xFF,0xFC,0xF7,0xC4,0xFB,0x6B,0x4F,0x00,0x25,
+ 0x6B,0x48,0x7D,0x60,0xFD,0x60,0x00,0x68,0x5C,0x21,0x82,0x7F,0x06,0x00,0x60,0x36,
+ 0x00,0x92,0x0B,0x5C,0x20,0x30,0xF2,0x7E,0x31,0x7F,0x40,0x7F,0xFE,0xF7,0x8E,0xFA,
+ 0x06,0x00,0x64,0x48,0x00,0x68,0x00,0x04,0x00,0x0C,0x01,0xF0,0x17,0xFC,0x01,0xF0,
+ 0xF9,0xFB,0x01,0x20,0x40,0x03,0xFB,0xF7,0x01,0xFA,0xFA,0xF7,0x1F,0xFF,0x01,0x20,
+ 0x00,0xF0,0x2C,0xFF,0xFC,0xF7,0x0A,0xFF,0x25,0x71,0xE5,0x80,0xF6,0x1C,0x25,0x81,
+ 0x01,0x96,0x97,0xE0,0x57,0x48,0x00,0x68,0x00,0x04,0x00,0x0C,0x01,0xF0,0xFE,0xFB,
+ 0x80,0x20,0xFB,0xF7,0xEB,0xF9,0x03,0x20,0x01,0xF0,0x32,0xFB,0x01,0x20,0x40,0x03,
+ 0xFB,0xF7,0xE4,0xF9,0xFB,0xF7,0x70,0xFE,0x00,0x28,0x02,0xD0,0xFA,0xF7,0xE4,0xFE,
+ 0x01,0xE0,0xFC,0xF7,0xB9,0xFE,0x03,0x20,0x00,0xF0,0x9C,0xFE,0xFA,0xF7,0xE2,0xFE,
+ 0x49,0x48,0xC0,0x88,0x01,0x05,0x09,0xD5,0x00,0x07,0x48,0x48,0xFF,0x21,0x01,0x31,
+ 0x01,0x62,0x2B,0x21,0x41,0x62,0x05,0x21,0xC1,0x62,0x06,0xE0,0x00,0x07,0x01,0xD5,
+ 0x04,0x20,0x00,0xE0,0x03,0x20,0x01,0xF0,0xCB,0xF8,0xFC,0xF7,0x63,0xFE,0xFC,0xF7,
+ 0x71,0xFE,0xFD,0xF7,0x83,0xFE,0x00,0x28,0x02,0xD0,0x7D,0x60,0xBD,0x60,0x02,0xE0,
+ 0x78,0x68,0x40,0x1C,0x78,0x60,0xFC,0xF7,0xDF,0xFE,0xFC,0xF7,0x4B,0xFE,0x01,0x20,
+ 0x80,0x03,0xFB,0xF7,0xAB,0xF9,0xFC,0xF7,0x5D,0xFE,0xFC,0xF7,0x15,0xFC,0xFC,0xF7,
+ 0x23,0xFD,0x00,0xF0,0x51,0xFA,0x06,0x00,0xFC,0xF7,0xCE,0xFE,0xFA,0xF7,0x7E,0xFF,
+ 0xFC,0xF7,0xCC,0xF9,0x00,0x28,0x02,0xD0,0x28,0x48,0x45,0x70,0x40,0xE0,0x78,0x78,
+ 0x00,0x28,0x11,0xD0,0x27,0x48,0x00,0x68,0x00,0x04,0x00,0x0C,0x01,0xF0,0x9E,0xFB,
+ 0x27,0x48,0x01,0x21,0x00,0x78,0x40,0x08,0x01,0xF0,0x08,0xFA,0x1F,0x48,0x45,0x70,
+ 0x25,0x71,0xE5,0x80,0x25,0x81,0x2B,0xE0,0x03,0x20,0x40,0x03,0xFB,0xF7,0x76,0xF9,
+ 0x03,0x20,0x01,0xF0,0x9F,0xFA,0x07,0x00,0x03,0x20,0x01,0xF0,0xD3,0xFA,0x80,0x20,
+ 0xFB,0xF7,0x6C,0xF9,0x00,0x2E,0x07,0xD0,0x0A,0x20,0x70,0x43,0xA0,0x21,0x4E,0x43,
+ 0x38,0x1A,0x37,0x18,0xFF,0x3F,0x7D,0x3F,0x16,0x48,0x00,0x78,0x16,0x49,0x09,0x78,
+ 0x08,0x43,0x07,0xD1,0x15,0x48,0x00,0x68,0x00,0x28,0x03,0xD0,0x39,0x00,0x01,0x20,
+ 0x00,0xF0,0x14,0xF9,0x09,0x4F,0x01,0x99,0x78,0x68,0x88,0x42,0x00,0xD2,0x61,0xE7,
+ 0x07,0x48,0x00,0x68,0x40,0x30,0x41,0x7E,0x0D,0x48,0x41,0x76,0x01,0xF0,0x50,0xFB,
+ 0xFE,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0xDC,0x07,0x00,0x20,0x18,0x08,0x00,0x20,
+ 0xE8,0x07,0x00,0x20,0x14,0x08,0x00,0x20,0x40,0x00,0x00,0x20,0x80,0x90,0x00,0x40,
+ 0x1C,0x95,0x00,0x00,0x28,0x08,0x00,0x20,0xF5,0x07,0x00,0x20,0x10,0x08,0x00,0x20,
+ 0x40,0x02,0x00,0x20,0x00,0x20,0x01,0x21,0x89,0x07,0x48,0x60,0x70,0x47,0x00,0x00,
+ 0x03,0x48,0x04,0x49,0xC0,0x78,0x08,0x43,0x01,0x21,0x89,0x07,0x08,0x63,0x70,0x47,
+ 0x9C,0x94,0x00,0x00,0xC0,0x74,0x00,0x00,0x70,0xB5,0x14,0x4C,0x14,0x48,0x61,0x79,
+ 0x20,0x18,0x00,0x25,0x00,0x29,0x05,0xD0,0x81,0x7C,0xC8,0x29,0x0C,0xD2,0x49,0x1C,
+ 0x81,0x74,0x09,0xE0,0x0F,0x49,0x09,0x68,0x00,0x29,0x01,0xD1,0x85,0x76,0x03,0xE0,
+ 0x04,0x29,0x01,0xD9,0xFC,0xF7,0xAE,0xFA,0x0B,0x48,0x00,0x78,0x00,0x28,0x09,0xD0,
+ 0xFC,0xF7,0x5E,0xFB,0xE0,0x88,0xE0,0x21,0x88,0x43,0xE0,0x80,0x07,0x48,0x05,0x55,
+ 0xE0,0x34,0xA5,0x73,0x70,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x40,0x00,0x00,0x20,
+ 0x3E,0x03,0x00,0x00,0x1C,0x08,0x00,0x20,0x19,0x08,0x00,0x20,0x19,0x02,0x00,0x00,
+ 0x10,0xB5,0xFA,0xF7,0x01,0xFE,0x03,0x20,0x40,0x03,0xFB,0xF7,0xDF,0xF8,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0x03,0x20,0x10,0xB5,0x40,0x03,0xFB,0xF7,0xDF,0xF8,0xFA,0xF7,
+ 0xFD,0xFD,0xFC,0xF7,0x87,0xFD,0x10,0xBC,0x08,0xBC,0x18,0x47,0x0B,0x48,0x10,0xB4,
+ 0x83,0x7B,0x0B,0x48,0x09,0x49,0x00,0x68,0xE0,0x39,0xA0,0x30,0x04,0x7E,0xC8,0x88,
+ 0xFF,0x22,0x01,0x32,0xA3,0x42,0x06,0xD3,0x10,0x43,0xC8,0x80,0x05,0x49,0x01,0x20,
+ 0x08,0x70,0x10,0xBC,0x70,0x47,0x90,0x43,0xC8,0x80,0xFA,0xE7,0x20,0x01,0x00,0x20,
+ 0xE8,0x07,0x00,0x20,0x19,0x08,0x00,0x20,0xF8,0xB5,0xFB,0xF7,0xCD,0xF8,0x00,0x28,
+ 0x33,0xD1,0x1B,0x49,0x02,0x20,0x01,0xF0,0xF3,0xF9,0x02,0x20,0x01,0xF0,0xF8,0xF9,
+ 0x01,0xF0,0xA0,0xFA,0x17,0x4D,0x18,0x4E,0x18,0x4F,0x01,0x24,0x64,0x07,0x28,0x6A,
+ 0x00,0x04,0x00,0x0C,0x01,0xF0,0xB2,0xFA,0xE0,0x6B,0x0B,0x28,0x13,0xD0,0x70,0x68,
+ 0x00,0x07,0x01,0xD5,0xFC,0xF7,0xB0,0xFE,0xF8,0x68,0x11,0x49,0x88,0x42,0xEE,0xD9,
+ 0x10,0x48,0xC0,0x68,0xFF,0x28,0x06,0xD1,0x02,0x20,0x01,0xF0,0xEB,0xF9,0x02,0x20,
+ 0x01,0xF0,0xD6,0xF9,0xE3,0xE7,0x01,0xF0,0x8B,0xFA,0x02,0x20,0x01,0xF0,0xE2,0xF9,
+ 0x05,0x20,0xFD,0xF7,0x45,0xFD,0x0B,0x20,0xE0,0x63,0xF8,0xBC,0x08,0xBC,0x18,0x47,
+ 0xFF,0xFF,0x00,0x00,0xF4,0x07,0x00,0x20,0x00,0x40,0x00,0x30,0x00,0x40,0x00,0x40,
+ 0x50,0xC3,0x00,0x00,0xC0,0x9F,0x00,0x00,0xF8,0xB5,0x13,0x4F,0x01,0x25,0xFC,0x03,
+ 0xFF,0x26,0x17,0xE0,0x78,0x68,0x00,0x07,0x14,0xD5,0xA5,0x63,0xF8,0x68,0x07,0x28,
+ 0x08,0xD1,0x78,0x68,0x80,0x07,0xFC,0xD5,0x00,0xF0,0x3E,0xFA,0xFC,0xF7,0xB2,0xFF,
+ 0xE6,0x63,0x07,0xE0,0x0B,0x28,0x0B,0xD1,0xE0,0x63,0x78,0x68,0x80,0x07,0xFC,0xD5,
+ 0x00,0xF0,0x32,0xFA,0xE0,0x6B,0x0B,0x28,0xE4,0xD1,0xF8,0xBC,0x08,0xBC,0x18,0x47,
+ 0x78,0x68,0x80,0x07,0xFC,0xD5,0xF3,0xE7,0x00,0x40,0x00,0x30,0x70,0xB5,0x0C,0x00,
+ 0x00,0x28,0x01,0xD0,0x1E,0x48,0x0D,0xE0,0x1E,0x4D,0x69,0x68,0x68,0x69,0xFA,0xF7,
+ 0xE5,0xFC,0x1D,0x4A,0x91,0x68,0x4B,0x1C,0x88,0x42,0x93,0x60,0x01,0xD8,0xA8,0x69,
+ 0x01,0xE0,0x1A,0x48,0x00,0x68,0x04,0x1B,0xFF,0x20,0x91,0x30,0x84,0x42,0x21,0xDD,
+ 0xFF,0x25,0x01,0x35,0x28,0x00,0xFB,0xF7,0x29,0xF8,0x02,0x20,0x01,0xF0,0x82,0xF9,
+ 0x0A,0x21,0x20,0x00,0xFA,0xF7,0x68,0xFB,0x41,0x11,0x02,0x20,0x01,0xF0,0x60,0xF9,
+ 0x04,0x20,0xFB,0xF7,0x45,0xF8,0x02,0x20,0x01,0xF0,0x62,0xF9,0x01,0x20,0xFB,0xF7,
+ 0x1D,0xF8,0xFF,0x20,0xFB,0xF7,0x3C,0xF8,0x02,0x20,0x01,0xF0,0x6B,0xF9,0x28,0x00,
+ 0xFB,0xF7,0x04,0xF8,0x06,0x49,0x00,0x20,0x08,0x70,0x70,0xBC,0x08,0xBC,0x18,0x47,
+ 0x10,0x08,0x00,0x20,0x9C,0x94,0x00,0x00,0x18,0x08,0x00,0x20,0x0C,0x08,0x00,0x20,
+ 0x28,0x08,0x00,0x20,0x78,0x47,0xC0,0x46,0xF0,0x5F,0x2D,0xE9,0x00,0x41,0x9F,0xE5,
+ 0x26,0x20,0xA0,0xE3,0xF4,0x50,0x84,0xE2,0x00,0x10,0xA0,0xE3,0xFC,0x00,0x84,0xE2,
+ 0x6B,0xEA,0xFF,0xEB,0xEC,0x90,0x9F,0xE5,0x01,0x00,0xD9,0xE5,0x00,0x10,0xD9,0xE5,
+ 0x01,0x30,0x50,0xE2,0xF0,0x5F,0xBD,0x48,0x90,0x01,0x01,0xE0,0x01,0x10,0x41,0xE2,
+ 0x1E,0xFF,0x2F,0x41,0x00,0xA0,0xA0,0xE3,0x01,0x80,0xA0,0xE3,0xC8,0xB0,0x9F,0xE5,
+ 0x00,0x00,0xD9,0xE5,0x01,0x00,0x50,0xE2,0x29,0x00,0x00,0x4A,0x83,0x60,0x84,0xE0,
+ 0x08,0x70,0x83,0xE2,0x80,0x20,0x84,0xE0,0xFA,0x28,0xD2,0xE1,0xFA,0xCB,0xD6,0xE1,
+ 0x0C,0x20,0x82,0xE0,0x81,0xC0,0x8B,0xE0,0xF0,0xE0,0xDC,0xE1,0x02,0x20,0x4E,0xE0,
+ 0x00,0x00,0x52,0xE3,0xB0,0xA0,0xCC,0xD1,0x1A,0x00,0x00,0xDA,0xB0,0x20,0xCC,0xE1,
+ 0x88,0xC0,0x9F,0xE5,0x00,0xC0,0x9C,0xE5,0xBA,0xCC,0xDC,0xE1,0x02,0x00,0x5C,0xE1,
+ 0x09,0x00,0x00,0xCA,0x45,0x20,0xD9,0xE5,0x02,0x00,0x12,0xE3,0x06,0x00,0x00,0x0A,
+ 0x00,0x20,0xD9,0xE5,0x01,0x20,0x42,0xE2,0x00,0x00,0x52,0xE1,0x01,0x20,0xD9,0x05,
+ 0x01,0x20,0x42,0x02,0x03,0x00,0x52,0x01,0x1C,0x80,0xC4,0x15,0x50,0x20,0x9F,0xE5,
+ 0xB4,0xC0,0xD5,0xE1,0x81,0x20,0x82,0xE0,0xF0,0x20,0xD2,0xE1,0x0C,0x00,0x52,0xE1,
+ 0x04,0x00,0x00,0xDA,0x00,0x20,0x85,0xE0,0x08,0x80,0xC2,0xE5,0x00,0x20,0xD9,0xE5,
+ 0x05,0x20,0x82,0xE0,0x07,0x80,0xC2,0xE7,0x01,0x00,0x50,0xE2,0x01,0x10,0x41,0xE2,
+ 0xD7,0xFF,0xFF,0x5A,0x01,0x30,0x53,0xE2,0xD0,0xFF,0xFF,0x5A,0xF0,0x5F,0xBD,0xE8,
+ 0x1E,0xFF,0x2F,0xE1,0x40,0x00,0x00,0x20,0x9C,0x94,0x00,0x00,0x00,0x00,0x00,0x10,
+ 0xE8,0x07,0x00,0x20,0x2A,0x08,0x00,0x20,0x08,0x49,0x09,0x48,0xCA,0x68,0xC2,0x61,
+ 0x49,0x68,0xC1,0x61,0x07,0x49,0xCA,0x68,0x52,0x08,0x52,0x00,0xCA,0x60,0x41,0x69,
+ 0x89,0x06,0xFC,0xD5,0x41,0x68,0x89,0x07,0xFC,0xD5,0x70,0x47,0xC0,0x9F,0x00,0x00,
+ 0x00,0x40,0x00,0x30,0x00,0x20,0x00,0x40,0x70,0xB5,0x18,0x48,0xC0,0x68,0x07,0x28,
+ 0x04,0xD0,0x01,0x20,0x40,0x07,0x04,0x68,0x00,0x2C,0x03,0xD1,0x00,0x20,0x70,0xBC,
+ 0x08,0xBC,0x18,0x47,0xFF,0x25,0x01,0x35,0x28,0x00,0xFA,0xF7,0x3F,0xFF,0x02,0x20,
+ 0x01,0xF0,0x98,0xF8,0x20,0x00,0xFD,0xF7,0xFB,0xFF,0x00,0xF0,0x15,0xF9,0x05,0x2C,
+ 0x07,0xD8,0x0B,0x48,0x00,0x78,0x00,0x28,0x03,0xD1,0x20,0x00,0x00,0xF0,0x14,0xF8,
+ 0x02,0xE0,0x20,0x00,0x00,0xF0,0x70,0xF8,0x04,0x00,0x28,0x00,0xFA,0xF7,0x1E,0xFF,
+ 0x04,0x49,0x00,0x20,0x08,0x70,0x20,0x00,0xD9,0xE7,0x00,0x00,0x00,0x40,0x00,0x30,
+ 0xF7,0x07,0x00,0x20,0x28,0x08,0x00,0x20,0x70,0xB5,0x01,0x21,0x28,0x4C,0x4A,0x07,
+ 0x04,0xE0,0x8B,0x00,0x9B,0x18,0x1B,0x68,0xE3,0x61,0x49,0x1C,0x81,0x42,0xF8,0xD9,
+ 0x24,0x48,0x20,0x60,0x21,0x20,0x80,0x02,0x20,0x61,0x03,0x20,0xFD,0xF7,0xAE,0xFB,
+ 0x21,0x48,0x0A,0x21,0x00,0x69,0xFA,0xF7,0xA9,0xFB,0x01,0x09,0x02,0x20,0x01,0xF0,
+ 0x3F,0xF8,0x1E,0x4D,0xE8,0x68,0x40,0x08,0x40,0x00,0xE8,0x60,0x02,0x20,0x01,0xF0,
+ 0x3F,0xF8,0x03,0x20,0xFA,0xF7,0x1C,0xFF,0x01,0x20,0xFA,0xF7,0xF7,0xFE,0x03,0x21,
+ 0x09,0x07,0xC8,0x68,0x08,0x22,0x10,0x43,0xC8,0x60,0x02,0x20,0x01,0xF0,0x0A,0xF8,
+ 0x06,0x00,0x60,0x68,0x60,0x60,0x60,0x69,0x60,0x61,0xFD,0xF7,0x95,0xFD,0x02,0x20,
+ 0x01,0xF0,0x38,0xF8,0x03,0x20,0xFD,0xF7,0x71,0xFB,0xE8,0x68,0x01,0x21,0x08,0x43,
+ 0xE8,0x60,0x0B,0x48,0x00,0x78,0x00,0x28,0x05,0xD0,0x0A,0x48,0x00,0x68,0x00,0x04,
+ 0x00,0x0C,0x01,0xF0,0xDB,0xF8,0x30,0x00,0x70,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0x00,0x40,0x00,0x30,0xD0,0x10,0x05,0x00,0x9C,0x94,0x00,0x00,0x00,0x20,0x00,0x40,
+ 0x28,0x08,0x00,0x20,0x14,0x08,0x00,0x20,0xF8,0xB5,0x05,0x00,0x41,0x48,0x00,0x27,
+ 0x00,0x78,0x00,0x28,0x03,0xD0,0x6D,0x1C,0xFD,0xF7,0x4E,0xFA,0x07,0x00,0x3E,0x48,
+ 0x00,0x68,0x3E,0x4E,0xF0,0x61,0x3E,0x48,0x02,0x24,0x00,0x69,0x0A,0x21,0xFA,0xF7,
+ 0x4D,0xFB,0x01,0x00,0x02,0x20,0x00,0xF0,0xE3,0xFF,0x02,0x20,0x00,0xF0,0xE8,0xFF,
+ 0x38,0x48,0xC1,0x68,0x49,0x08,0x49,0x00,0xC1,0x60,0x32,0x48,0x21,0x07,0x00,0x78,
+ 0x1A,0xE0,0x72,0x69,0x52,0x06,0x0A,0xD4,0x00,0x28,0x01,0xD0,0xAC,0x42,0x04,0xD2,
+ 0xA2,0x00,0x52,0x18,0x12,0x68,0xF2,0x61,0x00,0xE0,0xF7,0x61,0x64,0x1C,0x2E,0x4A,
+ 0x12,0x78,0x00,0x2A,0x08,0xD0,0xFD,0xF7,0x13,0xFB,0x2C,0x48,0x00,0x68,0x00,0x04,
+ 0x00,0x0C,0x01,0xF0,0x8B,0xF8,0x01,0xE0,0xAC,0x42,0xE2,0xD9,0x02,0x20,0x00,0xF0,
+ 0xD1,0xFF,0x25,0x4D,0x28,0x78,0x00,0x28,0x31,0xD1,0xFD,0xF7,0x69,0xFA,0x00,0x28,
+ 0x2D,0xD0,0x1F,0x48,0x0A,0x21,0x00,0x69,0xFA,0xF7,0x10,0xFB,0x01,0x00,0x02,0x20,
+ 0x00,0xF0,0xA6,0xFF,0x02,0x20,0x00,0xF0,0xAB,0xFF,0x1C,0x4C,0x09,0xE0,0x28,0x78,
+ 0x00,0x28,0x06,0xD0,0xFD,0xF7,0xEC,0xFA,0x20,0x68,0x00,0x04,0x00,0x0C,0x01,0xF0,
+ 0x65,0xF8,0xFD,0xF7,0x4D,0xFA,0x00,0x28,0xF1,0xD1,0x70,0x68,0x70,0x60,0x08,0xE0,
+ 0x28,0x78,0x00,0x28,0x05,0xD0,0x20,0x68,0x00,0x04,0x00,0x0C,0x01,0xF0,0x56,0xF8,
+ 0x02,0xE0,0x70,0x68,0xC0,0x03,0xF3,0xD5,0x02,0x20,0x00,0xF0,0x9B,0xFF,0x00,0xF0,
+ 0x1B,0xF8,0x08,0x48,0xC1,0x68,0x01,0x22,0x11,0x43,0xC1,0x60,0xF8,0xBC,0x08,0xBC,
+ 0x00,0x20,0x18,0x47,0xF7,0x07,0x00,0x20,0x04,0x00,0x00,0x20,0x00,0x40,0x00,0x30,
+ 0x9C,0x94,0x00,0x00,0x00,0x20,0x00,0x40,0x28,0x08,0x00,0x20,0x14,0x08,0x00,0x20,
+ 0x01,0xC0,0x8F,0xE2,0x1C,0xFF,0x2F,0xE1,0x05,0x48,0x01,0x21,0x00,0xB5,0xC9,0x02,
+ 0x01,0x62,0x00,0x21,0x01,0x62,0xFD,0xF7,0xCF,0xFC,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0x40,0x00,0x00,0x40,0x70,0x47,0x00,0x00,0x04,0x49,0x02,0x68,0x0A,0x62,0x42,0x68,
+ 0x4A,0x62,0x82,0x68,0x4A,0x63,0xC0,0x68,0xC8,0x62,0x70,0x47,0x80,0x90,0x00,0x40,
+ 0x78,0x47,0xC0,0x46,0x01,0x00,0x80,0xE0,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0xC0,0x46,
+ 0x01,0x00,0x80,0xE0,0x02,0x00,0x80,0xE0,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0xC0,0x46,
+ 0x01,0x00,0x80,0xE0,0x00,0xC0,0x9D,0xE5,0x02,0x00,0x80,0xE0,0x03,0x00,0x80,0xE0,
+ 0x0C,0x00,0x80,0xE0,0x1E,0xFF,0x2F,0xE1,0x70,0xB5,0x06,0x00,0x11,0x49,0xD9,0x20,
+ 0xC0,0x00,0xE3,0x22,0x08,0x18,0xD2,0x00,0x89,0x18,0x0C,0x00,0x20,0x34,0xA2,0x7D,
+ 0x0D,0x4D,0x92,0x19,0x08,0xD0,0x38,0x22,0xFA,0xF7,0xB2,0xFA,0xA0,0x7D,0x80,0x19,
+ 0xA8,0x75,0x70,0xBC,0x08,0xBC,0x18,0x47,0xAA,0x7D,0x00,0x2A,0x05,0xD0,0x38,0x22,
+ 0xFA,0xF7,0xA6,0xFA,0x01,0x20,0xA0,0x75,0xF3,0xE7,0x38,0x22,0x00,0x21,0xFA,0xF7,
+ 0x99,0xFA,0xEE,0xE7,0x40,0x00,0x00,0x20,0x28,0x07,0x00,0x20,0xF8,0xB5,0x1D,0x4C,
+ 0x89,0x20,0x80,0x00,0x25,0x18,0x22,0x00,0x10,0x18,0xEE,0x1D,0x07,0x00,0xF9,0x36,
+ 0x31,0x7D,0xFF,0x30,0x09,0x30,0x78,0x37,0x00,0x29,0x00,0x90,0x0E,0xD0,0x78,0x22,
+ 0x29,0x00,0x38,0x00,0xFA,0xF7,0x84,0xFA,0x00,0x98,0x0C,0x22,0x31,0x1F,0xFA,0xF7,
+ 0x7F,0xFA,0x30,0x7D,0x70,0x75,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x0C,0x22,0x00,0x21,
+ 0xFA,0xF7,0x70,0xFA,0x78,0x22,0x00,0x21,0x38,0x00,0xFA,0xF7,0x6B,0xFA,0x28,0x00,
+ 0x0C,0x22,0x00,0x21,0xF0,0x30,0xFA,0xF7,0x65,0xFA,0x00,0x21,0x71,0x75,0xE0,0x88,
+ 0x13,0x22,0x90,0x43,0xE0,0x80,0x1B,0x20,0x80,0x01,0x20,0x18,0xC1,0x70,0x01,0x71,
+ 0xE1,0xE7,0x00,0x00,0x40,0x00,0x00,0x20,0xF0,0xB5,0x04,0x00,0x84,0x48,0x95,0xB0,
+ 0x01,0x90,0x84,0x48,0x84,0x49,0x00,0x78,0x00,0x28,0x83,0x48,0x16,0xD0,0x80,0x30,
+ 0xC2,0x89,0x18,0x27,0x09,0x92,0x02,0x8A,0x08,0x92,0x42,0x8A,0x07,0x92,0x1C,0x22,
+ 0x82,0x5E,0x06,0x92,0x1E,0x22,0x82,0x5E,0x05,0x92,0x1A,0x22,0x82,0x5E,0xC7,0x5F,
+ 0x04,0x92,0x14,0x22,0x16,0x23,0x82,0x5E,0xC3,0x5E,0x15,0xE0,0x20,0x30,0x80,0x7A,
+ 0x34,0x27,0x30,0x22,0x09,0x90,0x88,0x8D,0x08,0x90,0xC8,0x8D,0x07,0x90,0x38,0x20,
+ 0x08,0x5E,0x06,0x90,0x3A,0x20,0x08,0x5E,0x05,0x90,0x36,0x20,0x08,0x5E,0xCF,0x5F,
+ 0x32,0x23,0x04,0x90,0x8A,0x5E,0xCB,0x5E,0x20,0x88,0x6B,0x4D,0x02,0xA9,0x80,0x18,
+ 0x20,0x80,0x60,0x88,0xC0,0x18,0x60,0x80,0x00,0x20,0x6B,0x46,0x18,0x81,0x98,0x81,
+ 0xA8,0x8B,0x40,0x1E,0xD8,0x81,0xE8,0x8B,0x40,0x1E,0x58,0x81,0x06,0xC9,0x20,0x00,
+ 0x00,0xF0,0xB2,0xFF,0xA8,0x8B,0x64,0x21,0x0C,0x90,0xE8,0x8B,0x0B,0x90,0x0C,0x98,
+ 0x45,0x08,0x0B,0x98,0x46,0x08,0x08,0x98,0x64,0x38,0x00,0x28,0x01,0xDC,0x08,0x98,
+ 0x08,0x1A,0x12,0x90,0x07,0x98,0x64,0x38,0x00,0x28,0x01,0xDC,0x07,0x98,0x08,0x1A,
+ 0x11,0x90,0x55,0x48,0x01,0x78,0x40,0x78,0x0A,0x90,0x01,0x98,0x20,0x30,0x00,0x7A,
+ 0xC2,0x07,0x0A,0xD0,0x80,0x07,0x03,0xD5,0x49,0x1E,0x09,0x06,0x09,0x0E,0x04,0xE0,
+ 0x0A,0x98,0x40,0x1E,0x00,0x06,0x00,0x0E,0x0A,0x90,0x28,0x00,0xFA,0xF7,0x4C,0xF8,
+ 0x0C,0x99,0x08,0x1A,0x40,0x1E,0x0F,0x90,0x0A,0x99,0x30,0x00,0xFA,0xF7,0x44,0xF8,
+ 0x0B,0x99,0x08,0x1A,0x40,0x1E,0x39,0x1E,0x0E,0x90,0x00,0xDD,0xE9,0x1B,0x04,0x98,
+ 0x00,0x28,0x10,0x90,0x01,0xDD,0x30,0x1A,0x10,0x90,0x00,0x20,0x20,0x5E,0xA8,0x42,
+ 0x14,0x90,0x01,0xDB,0x40,0x1B,0x01,0xE0,0x40,0x1B,0x40,0x1C,0x00,0x28,0x00,0xDC,
+ 0x40,0x42,0x64,0x22,0x07,0x00,0x57,0x43,0x88,0x42,0x0D,0x97,0x0F,0xDD,0x42,0x1A,
+ 0x12,0x98,0x50,0x43,0xC7,0x19,0x10,0x00,0x50,0x43,0x12,0x9A,0x50,0x43,0x0F,0x9A,
+ 0x52,0x1B,0x51,0x1A,0xFA,0xF7,0x18,0xF8,0x0D,0x99,0x40,0x18,0x0D,0x90,0x06,0x98,
+ 0x00,0x28,0x01,0xD1,0x38,0x00,0x06,0xE0,0x01,0x28,0x01,0xD1,0x0D,0x98,0x02,0xE0,
+ 0x0D,0x99,0x78,0x00,0x40,0x1A,0x64,0x21,0xFA,0xF7,0x06,0xF8,0x09,0x99,0xC9,0x07,
+ 0x07,0xD0,0x14,0x99,0xA9,0x42,0x01,0xDB,0x28,0x18,0x01,0xE0,0x28,0x1A,0x40,0x1E,
+ 0x20,0x80,0x02,0x20,0x20,0x5E,0xB0,0x42,0x13,0x90,0x01,0xDB,0x80,0x1B,0x01,0xE0,
+ 0x80,0x1B,0x40,0x1C,0x00,0x28,0x00,0xDC,0x40,0x42,0x64,0x21,0x05,0x00,0x4D,0x43,
+ 0x10,0x99,0x2F,0x00,0x88,0x42,0x0E,0xDD,0x41,0x1A,0x11,0x98,0x10,0x9A,0x48,0x43,
+ 0x45,0x19,0x08,0x00,0x48,0x43,0x11,0x99,0x48,0x43,0x0E,0x99,0x89,0x1B,0x89,0x1A,
+ 0xF9,0xF7,0xDA,0xFF,0xC7,0x19,0x05,0x98,0x00,0x28,0x01,0xD1,0x28,0x00,0x05,0xE0,
+ 0x01,0x28,0x01,0xD1,0x38,0x00,0x01,0xE0,0x68,0x00,0xC0,0x1B,0x64,0x21,0xF9,0xF7,
+ 0xCB,0xFF,0x09,0x99,0x89,0x07,0x07,0xD5,0x13,0x99,0xB1,0x42,0x01,0xDB,0x30,0x18,
+ 0x01,0xE0,0x30,0x1A,0x40,0x1E,0x60,0x80,0x15,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,
+ 0xA4,0x06,0x00,0x20,0xFA,0x07,0x00,0x20,0x9C,0x94,0x00,0x00,0xFF,0xB5,0x00,0x68,
+ 0x8E,0x46,0x84,0x46,0x70,0x46,0x1B,0x4B,0x1B,0x49,0x05,0x68,0x00,0x22,0x19,0x4E,
+ 0x54,0x00,0x24,0x3E,0x34,0x5B,0x66,0x46,0x00,0x20,0x34,0x1B,0x26,0x00,0x74,0x43,
+ 0x46,0x00,0x9E,0x5B,0xAE,0x1B,0x37,0x00,0x77,0x43,0xE6,0x19,0x8E,0x42,0x18,0xD2,
+ 0x51,0x00,0x10,0x4A,0x40,0x00,0x24,0x3A,0x52,0x5A,0x02,0x99,0x0A,0x60,0x0D,0x49,
+ 0x03,0x9A,0x16,0x39,0x0C,0x5A,0x14,0x60,0x09,0x5A,0x72,0x46,0x12,0x68,0x18,0x5A,
+ 0x51,0x18,0x09,0x1A,0x70,0x46,0x01,0x60,0x01,0x20,0x04,0xB0,0xF0,0xBC,0x08,0xBC,
+ 0x18,0x47,0x40,0x1C,0x0B,0x28,0xDB,0xD3,0x52,0x1C,0x07,0x2A,0xCF,0xD3,0x00,0x20,
+ 0xC0,0x43,0xF2,0xE7,0xB0,0x71,0x00,0x00,0xD9,0x02,0x00,0x00,0xF0,0xB5,0x5B,0x48,
+ 0x89,0x21,0x89,0x00,0x46,0x18,0xD9,0x21,0xC9,0x00,0x45,0x18,0x85,0xB0,0x01,0x90,
+ 0x57,0x49,0x44,0x20,0x42,0x5D,0x08,0x7D,0x56,0x4B,0x00,0x24,0x00,0x2A,0x04,0x93,
+ 0x25,0xD1,0x00,0x28,0x23,0xD0,0x00,0x20,0x07,0x00,0x02,0x90,0x0A,0x20,0x78,0x43,
+ 0x80,0x19,0x00,0x90,0x80,0x1D,0xFD,0xF7,0xE9,0xF9,0x00,0x28,0x13,0xD0,0x04,0x98,
+ 0x00,0x7A,0xA0,0x42,0x12,0xD9,0x00,0x98,0x01,0x79,0x02,0x98,0x28,0x18,0x40,0x30,
+ 0x01,0x71,0x02,0x98,0x00,0x99,0x40,0x1C,0x02,0x90,0x01,0x20,0x00,0xF0,0x4E,0xF9,
+ 0x00,0x28,0x00,0xD1,0x64,0x1C,0x7F,0x1C,0x0C,0x2F,0xDF,0xDB,0x78,0xE0,0x49,0x7D,
+ 0x00,0x29,0x01,0xD1,0x00,0x28,0x73,0xD0,0x00,0x27,0xE9,0x19,0x44,0x20,0x08,0x56,
+ 0x40,0x1E,0x33,0xD4,0x31,0x18,0xFC,0x20,0x08,0x56,0x40,0x1E,0x06,0xD4,0x01,0x99,
+ 0x0D,0x22,0x92,0x01,0x89,0x18,0x09,0x7E,0x00,0x29,0x14,0xD0,0x0A,0x21,0x48,0x43,
+ 0x81,0x19,0x78,0x31,0x04,0x20,0x00,0xF0,0x29,0xF9,0x00,0x28,0x00,0xD1,0x64,0x1C,
+ 0x38,0x00,0x04,0xE0,0x29,0x18,0x40,0x31,0x4A,0x79,0x40,0x1C,0x0A,0x71,0x0C,0x28,
+ 0xF8,0xDB,0x7F,0x1E,0x0F,0xE0,0x0A,0x21,0x48,0x43,0x80,0x19,0x00,0x90,0x80,0x1D,
+ 0xFD,0xF7,0x9C,0xF9,0x00,0x28,0x06,0xD0,0x00,0x99,0x02,0x20,0x00,0xF0,0x0E,0xF9,
+ 0x00,0x28,0x00,0xD1,0x64,0x1C,0x7F,0x1C,0x0C,0x2F,0xC6,0xDB,0x01,0x98,0x0D,0x21,
+ 0x00,0x27,0x89,0x01,0x40,0x18,0x03,0x90,0x00,0x7E,0x00,0x28,0x30,0xD1,0xF1,0x19,
+ 0xFC,0x20,0x08,0x56,0x40,0x1E,0x25,0xD4,0x0A,0x21,0x48,0x43,0x80,0x19,0x00,0x90,
+ 0x80,0x1D,0xFD,0xF7,0x7B,0xF9,0x00,0x28,0x1C,0xD0,0x04,0x98,0x00,0x7A,0xA0,0x42,
+ 0x1E,0xD9,0x00,0x20,0x2A,0x18,0x44,0x21,0x51,0x56,0x4A,0x1E,0xBA,0x42,0x11,0xD0,
+ 0x49,0x1E,0x0C,0xD5,0x00,0x99,0x28,0x18,0x09,0x79,0x40,0x30,0x01,0x71,0x00,0x99,
+ 0x01,0x20,0x00,0xF0,0xDB,0xF8,0x00,0x28,0x04,0xD1,0x64,0x1C,0x02,0xE0,0x40,0x1C,
+ 0x0C,0x28,0xE7,0xDB,0x7F,0x1C,0x0C,0x2F,0x02,0xDA,0x03,0x98,0xCC,0xE7,0xFF,0xE7,
+ 0x00,0xF0,0xE4,0xFC,0x05,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,
+ 0x64,0x03,0x00,0x20,0xBC,0x94,0x00,0x00,0x10,0xB5,0xFC,0xF7,0x0B,0xF8,0xFC,0xF7,
+ 0x93,0xF8,0xFC,0xF7,0x99,0xF8,0x10,0xBC,0x08,0xBC,0x18,0x47,0x01,0x28,0x01,0xD1,
+ 0x0E,0x48,0x00,0xE0,0x0E,0x48,0x0F,0x49,0x00,0x68,0x82,0x68,0x4A,0x61,0xC2,0x68,
+ 0x8A,0x61,0x02,0x69,0x01,0x23,0x5B,0x05,0x9A,0x43,0xCA,0x61,0x42,0x69,0x0A,0x62,
+ 0x09,0x4A,0x92,0x79,0x00,0x2A,0x03,0xD0,0x08,0x48,0xC8,0x60,0x08,0x48,0x02,0xE0,
+ 0x02,0x68,0xCA,0x60,0x40,0x68,0x08,0x61,0x70,0x47,0x00,0x00,0xF0,0x07,0x00,0x20,
+ 0xEC,0x07,0x00,0x20,0xC0,0x90,0x00,0x40,0xF4,0x07,0x00,0x20,0x41,0x42,0x01,0x00,
+ 0x10,0x00,0x10,0x00,0x0C,0x49,0x01,0x28,0x01,0xD1,0x0C,0x48,0x00,0xE0,0x0C,0x48,
+ 0xFF,0x31,0x01,0x31,0x49,0x7D,0x00,0x68,0x02,0x29,0x01,0xD9,0x01,0x6A,0x04,0xE0,
+ 0x02,0x29,0x01,0xD1,0xC1,0x69,0x00,0xE0,0x81,0x69,0x06,0x4A,0x51,0x62,0x41,0x6A,
+ 0x91,0x62,0x80,0x6A,0x10,0x63,0x70,0x47,0x64,0x02,0x00,0x20,0xF0,0x07,0x00,0x20,
+ 0xEC,0x07,0x00,0x20,0xC0,0x90,0x00,0x40,0x01,0x28,0x01,0xD1,0x0A,0x48,0x00,0xE0,
+ 0x0A,0x48,0x0B,0x49,0x00,0x68,0xC2,0x6A,0x0A,0x61,0x02,0x6B,0x4A,0x61,0x42,0x6B,
+ 0x8A,0x61,0x82,0x6B,0xCA,0x61,0xC2,0x6B,0x0A,0x62,0x02,0x6C,0x4A,0x62,0x42,0x6C,
+ 0x8A,0x62,0x80,0x6C,0xC8,0x62,0x70,0x47,0xF0,0x07,0x00,0x20,0xEC,0x07,0x00,0x20,
+ 0x40,0xA1,0x00,0x40,0x12,0x49,0x10,0xB4,0x4A,0x79,0x10,0x48,0x02,0x72,0x8A,0x79,
+ 0x42,0x72,0x02,0x7A,0xD3,0x07,0x0D,0xD0,0x94,0x07,0x0E,0x4A,0x0E,0x4B,0x04,0xD5,
+ 0x12,0x78,0x52,0x1E,0x82,0x73,0x00,0x22,0x03,0xE0,0x52,0x78,0x52,0x1E,0x82,0x73,
+ 0x01,0x22,0x1A,0x70,0x8A,0x7A,0xC2,0x73,0xCA,0x7A,0x02,0x74,0x0A,0x7B,0x42,0x74,
+ 0x4A,0x7B,0x82,0x74,0x89,0x7B,0xC1,0x74,0x10,0xBC,0x70,0x47,0xC4,0x06,0x00,0x20,
+ 0xDC,0x94,0x00,0x00,0x9C,0x94,0x00,0x00,0xF4,0x07,0x00,0x20,0x0E,0x49,0x10,0xB5,
+ 0xC9,0x88,0x00,0x28,0x06,0xD0,0x03,0x24,0x08,0x07,0x01,0xD5,0x04,0x20,0x07,0xE0,
+ 0x03,0x20,0x05,0xE0,0x01,0x24,0x08,0x07,0x01,0xD5,0x02,0x20,0x00,0xE0,0x01,0x20,
+ 0x00,0xF0,0xC6,0xF9,0x20,0x00,0xFF,0xF7,0x9F,0xFF,0x20,0x00,0xFF,0xF7,0x4E,0xFF,
+ 0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x40,0x00,0x00,0x20,0xF3,0xB5,0x37,0x4F,
+ 0x89,0x20,0x80,0x00,0x3E,0x18,0xE3,0x20,0x0C,0x00,0xC0,0x00,0x3D,0x18,0x81,0xB0,
+ 0x01,0x99,0x20,0x00,0xFA,0xF7,0x6A,0xFF,0x00,0x28,0x5C,0xD1,0x0D,0x20,0xC0,0x01,
+ 0x38,0x18,0x00,0x7B,0xC0,0x07,0x01,0xD1,0x02,0x20,0xE0,0x71,0x01,0x98,0x80,0x07,
+ 0x80,0x0F,0x02,0xD1,0xE0,0x79,0x06,0x28,0x32,0xD1,0x20,0x79,0xA9,0x8E,0x01,0x22,
+ 0x40,0x1E,0x82,0x40,0x11,0x43,0xA9,0x86,0x29,0x68,0x10,0x22,0xD1,0x41,0x12,0x06,
+ 0x89,0x18,0x10,0x22,0xD1,0x41,0x29,0x60,0x80,0x00,0x40,0x19,0x41,0x68,0x22,0x79,
+ 0x09,0x01,0x09,0x09,0x12,0x07,0x11,0x43,0x1D,0x4A,0x41,0x60,0x11,0x40,0x22,0x88,
+ 0x12,0x05,0x12,0x0A,0x11,0x43,0x0B,0x0B,0x41,0x60,0x61,0x88,0x1B,0x03,0x09,0x05,
+ 0x09,0x0D,0x0B,0x43,0x0F,0x21,0x43,0x60,0x62,0x79,0x09,0x06,0x8B,0x43,0x0F,0x21,
+ 0x0F,0x2A,0x00,0xD9,0x11,0x00,0x09,0x07,0x09,0x09,0x0B,0x43,0x43,0x60,0x19,0xE0,
+ 0x0A,0x28,0x17,0xD1,0x00,0x20,0xF3,0x1D,0xF9,0x33,0x10,0xE0,0x0A,0x21,0x41,0x43,
+ 0x89,0x19,0x0A,0x00,0x60,0x31,0x25,0x79,0x0F,0x7F,0xBD,0x42,0x06,0xD1,0x40,0x32,
+ 0x15,0x8F,0x25,0x80,0x52,0x8F,0x62,0x80,0x49,0x7F,0x61,0x71,0x40,0x1C,0x59,0x7D,
+ 0x81,0x42,0xEB,0xDC,0x00,0x20,0xFE,0xBC,0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,
+ 0xFF,0x0F,0x00,0xFF,0x0F,0x49,0x10,0xB5,0xC8,0x79,0x00,0x28,0x11,0xD0,0x00,0x09,
+ 0x00,0x01,0x00,0x22,0x40,0x28,0x0B,0xD0,0x80,0x28,0x0A,0xD1,0x01,0x20,0xC8,0x70,
+ 0x09,0x4B,0x08,0x71,0x48,0x71,0x1B,0x79,0x00,0x2B,0x05,0xD1,0x8A,0x71,0x04,0xE0,
+ 0x8A,0x70,0x10,0xBC,0x08,0xBC,0x18,0x47,0x88,0x71,0x00,0x20,0x00,0xF0,0x6E,0xFA,
+ 0xF7,0xE7,0x00,0x00,0xF4,0x07,0x00,0x20,0x1C,0x95,0x00,0x00,0xF8,0xB5,0x06,0x9F,
+ 0x07,0x9D,0x0C,0x00,0x1E,0x00,0x88,0x42,0x09,0xD3,0x21,0x00,0x10,0x00,0xF9,0xF7,
+ 0x53,0xFD,0x38,0x80,0x21,0x00,0x30,0x00,0xF9,0xF7,0x4E,0xFD,0x28,0x80,0xF8,0xBC,
+ 0x08,0xBC,0x18,0x47,0xF8,0xB5,0x08,0xAD,0x60,0xCD,0x04,0x00,0x06,0x98,0x91,0x42,
+ 0x04,0xDA,0x25,0x80,0x66,0x80,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x99,0x42,0x02,0xDB,
+ 0x20,0x80,0x07,0x98,0x0F,0xE0,0x8F,0x1A,0x40,0x1B,0x78,0x43,0x99,0x1A,0x00,0x91,
+ 0xF9,0xF7,0x32,0xFD,0x40,0x19,0x20,0x80,0x07,0x98,0x00,0x99,0x80,0x1B,0x78,0x43,
+ 0xF9,0xF7,0x2A,0xFD,0x80,0x19,0x60,0x80,0xE5,0xE7,0x37,0xB5,0x00,0x2A,0x02,0xDA,
+ 0x50,0x42,0x02,0x04,0x12,0x14,0x6B,0x46,0x1C,0x79,0x58,0x79,0x94,0x42,0x04,0xDC,
+ 0x19,0x88,0x91,0x42,0x04,0xDA,0x02,0x20,0x18,0x5E,0x3E,0xBC,0x08,0xBC,0x18,0x47,
+ 0x5B,0x88,0x12,0x1B,0x09,0x1B,0x18,0x1A,0x50,0x43,0x00,0x04,0x00,0x14,0xF9,0xF7,
+ 0x0B,0xFD,0x20,0x18,0x00,0x04,0x00,0x14,0xEF,0xE7,0x00,0x00,0x82,0x79,0x0A,0x49,
+ 0x52,0x07,0x10,0xD5,0x0A,0x68,0x18,0x23,0xDA,0x41,0x01,0x23,0x5B,0x07,0xD2,0x18,
+ 0x08,0x23,0xDA,0x41,0x0A,0x60,0x43,0x79,0x01,0x20,0x5B,0x1E,0x98,0x40,0xC0,0x06,
+ 0xC0,0x0A,0x02,0x43,0x0A,0x60,0x70,0x47,0x58,0x07,0x00,0x20,0x30,0xB4,0x0E,0x4D,
+ 0x0C,0x4C,0x2D,0x78,0x45,0x43,0x68,0x18,0x45,0x00,0x60,0x5B,0x01,0x06,0x00,0x0A,
+ 0x09,0x0E,0x82,0x18,0xC9,0x18,0x00,0x20,0x4B,0x1E,0xC0,0x43,0xFF,0x2B,0x06,0xD2,
+ 0x53,0x1E,0xFF,0x2B,0x03,0xD2,0x10,0x02,0x08,0x43,0x60,0x53,0x00,0x20,0x30,0xBC,
+ 0x70,0x47,0x00,0x00,0x00,0x00,0x10,0x40,0x9C,0x94,0x00,0x00,0x10,0xB4,0x05,0x4C,
+ 0x03,0x4B,0x24,0x78,0x44,0x43,0x60,0x18,0x40,0x00,0x1A,0x52,0x10,0xBC,0x70,0x47,
+ 0x00,0x00,0x10,0x40,0x9C,0x94,0x00,0x00,0x30,0xB4,0x0E,0x4B,0x0C,0x4C,0x1B,0x78,
+ 0x43,0x43,0x58,0x18,0x43,0x00,0xE0,0x5A,0x01,0x06,0x09,0x0E,0x89,0x18,0x00,0x0A,
+ 0x82,0x18,0x00,0x20,0x4D,0x1E,0xC0,0x43,0xFF,0x2D,0x06,0xD2,0x55,0x1E,0xFF,0x2D,
+ 0x03,0xD2,0x10,0x02,0x08,0x43,0xE0,0x52,0x00,0x20,0x30,0xBC,0x70,0x47,0x00,0x00,
+ 0x00,0x00,0x10,0x40,0x9C,0x94,0x00,0x00,0xF0,0xB4,0x15,0x4A,0x00,0x21,0x13,0x79,
+ 0x14,0x00,0x40,0x3C,0x1E,0x02,0x1E,0x43,0x23,0x78,0x10,0x4D,0x43,0x43,0x12,0xE0,
+ 0x94,0x7A,0x8C,0x42,0x0D,0xD0,0xD4,0x7A,0x8C,0x42,0x0A,0xD0,0x14,0x7B,0x8C,0x42,
+ 0x07,0xD0,0x54,0x7B,0x8C,0x42,0x04,0xD0,0x94,0x7B,0x8C,0x42,0x01,0xD0,0x5C,0x00,
+ 0x2E,0x53,0x5B,0x1C,0x49,0x1C,0x06,0x4C,0x40,0x3C,0x24,0x78,0x27,0x00,0x47,0x43,
+ 0x3C,0x19,0x9C,0x42,0xE4,0xD8,0xF0,0xBC,0x70,0x47,0x00,0x00,0x00,0x00,0x10,0x40,
+ 0xDC,0x94,0x00,0x00,0xF0,0xB4,0x13,0x4A,0x00,0x21,0x14,0x79,0x15,0x00,0x10,0x4E,
+ 0x23,0x02,0x23,0x43,0x40,0x3D,0x13,0xE0,0x94,0x7A,0x8C,0x42,0x0D,0xD0,0xD4,0x7A,
+ 0x8C,0x42,0x0A,0xD0,0x14,0x7B,0x8C,0x42,0x07,0xD0,0x54,0x7B,0x8C,0x42,0x04,0xD0,
+ 0x94,0x7B,0x8C,0x42,0x01,0xD0,0x44,0x00,0x33,0x53,0x2C,0x78,0x20,0x18,0x49,0x1C,
+ 0x6C,0x78,0x2F,0x78,0x7C,0x43,0x84,0x42,0xE6,0xD8,0xF0,0xBC,0x70,0x47,0x00,0x00,
+ 0x00,0x00,0x10,0x40,0xDC,0x94,0x00,0x00,0x02,0x04,0x04,0x49,0x02,0x43,0x00,0x20,
+ 0x40,0x1C,0x04,0xC1,0xB5,0x28,0xFB,0xD3,0x70,0x47,0x00,0x00,0x00,0x00,0x10,0x40,
+ 0x70,0xB5,0x1C,0x49,0x1C,0x4A,0x0C,0x00,0x54,0x34,0x70,0xCC,0x03,0x00,0x00,0xF0,
+ 0x99,0xFB,0x06,0x04,0x0A,0x10,0x16,0x20,0x28,0x1D,0x08,0x68,0x10,0x62,0xC8,0x69,
+ 0x50,0x62,0x88,0x6B,0x22,0xE0,0x48,0x68,0x10,0x62,0x08,0x6A,0x50,0x62,0xC8,0x6B,
+ 0x0A,0xE0,0x88,0x68,0x10,0x62,0x48,0x6A,0x50,0x62,0x08,0x6C,0x0E,0xE0,0xC8,0x68,
+ 0x10,0x62,0x88,0x6A,0x50,0x62,0x48,0x6C,0xD0,0x62,0x55,0x63,0x70,0xBC,0x08,0xBC,
+ 0x18,0x47,0x08,0x69,0x10,0x62,0xC8,0x6A,0x50,0x62,0x88,0x6C,0xD0,0x62,0x56,0x63,
+ 0xF4,0xE7,0x48,0x69,0x10,0x62,0x08,0x6B,0x50,0x62,0xC8,0x6C,0xD0,0x62,0x54,0x63,
+ 0xEC,0xE7,0x00,0x00,0x44,0x95,0x00,0x00,0x80,0x90,0x00,0x40,0x0A,0x49,0x30,0xB4,
+ 0x0B,0x69,0xFF,0x20,0x00,0x02,0x83,0x43,0x08,0x48,0x00,0x68,0x02,0x79,0x44,0x79,
+ 0x85,0x79,0x12,0x02,0x1A,0x43,0x0A,0x61,0xC0,0x79,0x2A,0x04,0x23,0x02,0x1A,0x43,
+ 0x02,0x43,0x4A,0x60,0x30,0xBC,0x70,0x47,0x00,0x90,0x00,0x40,0xE8,0x07,0x00,0x20,
+ 0x70,0xB5,0x20,0x4C,0x19,0x21,0x49,0x01,0x61,0x18,0x4B,0x7E,0x1E,0x4D,0x20,0x00,
+ 0x29,0x68,0x00,0x22,0xF4,0x30,0x02,0x2B,0x01,0xD9,0x89,0x8C,0x02,0xE0,0x02,0x2B,
+ 0x15,0xD1,0x49,0x8C,0xC1,0x80,0xE1,0x88,0x89,0x05,0x00,0xD5,0x64,0x22,0xFF,0x21,
+ 0x9D,0x31,0xC3,0x88,0x09,0x5B,0x59,0x18,0x89,0x18,0x01,0x80,0x29,0x68,0xC9,0x8C,
+ 0x41,0x80,0x41,0x88,0x02,0x88,0x91,0x42,0x0A,0xD2,0x81,0x80,0x09,0xE0,0x0F,0x4B,
+ 0x1B,0x78,0x00,0x2B,0x02,0xD0,0x0E,0x49,0x89,0x89,0xE3,0xE7,0x09,0x8C,0xE1,0xE7,
+ 0x82,0x80,0x29,0x68,0x20,0x89,0x40,0x31,0x89,0x7F,0x48,0x43,0x00,0xF0,0x20,0xFB,
+ 0xE0,0x1D,0xFF,0x30,0xFA,0x30,0xC1,0x80,0xE2,0x89,0x89,0x18,0xC1,0x80,0x70,0xBC,
+ 0x08,0xBC,0x18,0x47,0x40,0x00,0x00,0x20,0xE8,0x07,0x00,0x20,0xFA,0x07,0x00,0x20,
+ 0x1C,0x95,0x00,0x00,0xF0,0xB5,0x33,0x4E,0xE3,0x20,0xC0,0x00,0x85,0xB0,0x30,0x18,
+ 0x00,0x90,0x00,0x21,0x6B,0x46,0x30,0x48,0x99,0x80,0x19,0x81,0x82,0x8B,0x52,0x1E,
+ 0x12,0x04,0x12,0x14,0x5A,0x81,0xC0,0x8B,0x40,0x1E,0x04,0x04,0x2B,0x48,0x24,0x14,
+ 0xDC,0x80,0x00,0x78,0x00,0x28,0x09,0xD1,0x27,0x48,0x20,0x30,0xC0,0x7A,0x09,0x18,
+ 0x19,0x81,0x11,0x1A,0x98,0x80,0x20,0x1A,0x59,0x81,0xD8,0x80,0x1D,0x20,0x00,0x24,
+ 0x80,0x01,0x37,0x18,0xB8,0x89,0xE0,0x40,0xC0,0x07,0x2B,0xD0,0x20,0x49,0xA0,0x00,
+ 0x80,0x19,0x45,0x18,0x28,0x68,0x6B,0x46,0x00,0x02,0x00,0x0D,0x98,0x81,0x28,0x68,
+ 0x00,0x05,0x00,0x0D,0xD8,0x81,0x19,0x48,0x00,0x78,0x00,0x28,0x02,0xD1,0x03,0xA8,
+ 0xFF,0xF7,0x92,0xFA,0x01,0xA9,0x06,0xC9,0x03,0xA8,0x00,0xF0,0x8D,0xFA,0x03,0xA8,
+ 0x00,0xF0,0x00,0xF9,0x13,0x49,0x28,0x68,0x6B,0x46,0x08,0x40,0x99,0x89,0x09,0x05,
+ 0x09,0x0A,0x08,0x43,0x28,0x60,0xD9,0x89,0x00,0x0B,0x00,0x03,0x09,0x05,0x09,0x0D,
+ 0x08,0x43,0x28,0x60,0x00,0x98,0x00,0x68,0x00,0x04,0x00,0x0F,0xA0,0x42,0x04,0xD9,
+ 0x64,0x1C,0x24,0x06,0x24,0x0E,0x0A,0x2C,0xC4,0xD3,0x05,0xB0,0xF0,0xBC,0x08,0xBC,
+ 0x18,0x47,0x00,0x00,0x40,0x00,0x00,0x20,0x9C,0x94,0x00,0x00,0xF9,0x07,0x00,0x20,
+ 0x1C,0x07,0x00,0x00,0xFF,0x0F,0x00,0xFF,0x09,0x48,0x0A,0x4A,0xC3,0x69,0x0A,0x49,
+ 0x93,0x42,0x07,0xD1,0x09,0x4B,0xDB,0x88,0x1B,0x07,0x01,0xD5,0xCB,0x68,0x00,0xE0,
+ 0x8B,0x68,0xC3,0x61,0x83,0x69,0x93,0x42,0x01,0xD1,0x49,0x68,0x81,0x61,0x70,0x47,
+ 0xF4,0x07,0x00,0x20,0xFF,0xFF,0x00,0x00,0x9C,0x94,0x00,0x00,0x40,0x00,0x00,0x20,
+ 0x08,0x48,0x10,0xB5,0xC4,0x68,0xE0,0x07,0x05,0xD0,0x07,0x48,0x40,0x78,0x00,0x28,
+ 0x01,0xD0,0x01,0x20,0x00,0xE0,0x00,0x20,0x00,0xF0,0x08,0xF8,0x20,0x0C,0x10,0xBC,
+ 0x08,0xBC,0x18,0x47,0xF4,0x07,0x00,0x20,0x1C,0x95,0x00,0x00,0x70,0xB4,0x0D,0x4A,
+ 0x0D,0x4C,0xD1,0x88,0x0D,0x4D,0x0E,0x4E,0x08,0x23,0x00,0x28,0x07,0xD0,0x0D,0x48,
+ 0x19,0x43,0xD1,0x80,0x20,0x60,0x0C,0x48,0x28,0x60,0x0C,0x48,0x06,0xE0,0x0C,0x48,
+ 0x99,0x43,0xD1,0x80,0x20,0x60,0x0B,0x48,0x28,0x60,0x0B,0x48,0x30,0x60,0x70,0xBC,
+ 0x70,0x47,0x00,0x00,0x40,0x00,0x00,0x20,0xE8,0x07,0x00,0x20,0xEC,0x07,0x00,0x20,
+ 0xF0,0x07,0x00,0x20,0x9C,0x92,0x00,0x00,0xB8,0x93,0x00,0x00,0x50,0x94,0x00,0x00,
+ 0xCC,0x91,0x00,0x00,0x6C,0x93,0x00,0x00,0x04,0x94,0x00,0x00,0xF0,0xB5,0x05,0x00,
+ 0x85,0xB0,0x36,0x4E,0x0F,0x00,0x68,0x46,0xF9,0xF7,0x64,0xFF,0x00,0x20,0xFF,0xF7,
+ 0x7F,0xFE,0xFB,0xF7,0x59,0xFC,0x2C,0x00,0x68,0x00,0x04,0x90,0x46,0xE0,0x68,0x1E,
+ 0x84,0x42,0x01,0xD1,0xFB,0xF7,0x86,0xFC,0xFB,0xF7,0x1C,0xFC,0xFB,0xF7,0x94,0xFC,
+ 0x00,0x2F,0x2E,0xD1,0xA8,0x00,0x05,0x21,0xF9,0xF7,0x08,0xFC,0xA0,0x42,0x03,0xD8,
+ 0x01,0x22,0x11,0x00,0x04,0x20,0x21,0xE0,0x68,0x00,0x28,0x18,0x05,0x21,0xF9,0xF7,
+ 0xFD,0xFB,0xA0,0x42,0x03,0xD8,0x01,0x22,0x11,0x00,0x03,0x20,0x16,0xE0,0x04,0x98,
+ 0x05,0x21,0xF9,0xF7,0xF3,0xFB,0xA0,0x42,0x03,0xD8,0x01,0x22,0x11,0x00,0x02,0x20,
+ 0x0C,0xE0,0x05,0x21,0x28,0x00,0xF9,0xF7,0xE9,0xFB,0xA0,0x42,0x03,0xD8,0x01,0x22,
+ 0x11,0x00,0x10,0x00,0x02,0xE0,0x01,0x22,0x11,0x00,0x00,0x20,0xFB,0xF7,0xDA,0xF9,
+ 0x0C,0xE0,0x04,0x98,0x03,0x21,0xF9,0xF7,0xD9,0xFB,0xA0,0x42,0xDB,0xD9,0x03,0x21,
+ 0x28,0x00,0xF9,0xF7,0xD3,0xFB,0xA0,0x42,0xE9,0xD8,0xDE,0xE7,0x64,0x1E,0xB6,0xD2,
+ 0x0B,0x48,0xC4,0x8B,0x03,0xE0,0xFB,0xF7,0xD5,0xFB,0xFB,0xF7,0x4D,0xFC,0x64,0x1E,
+ 0xF9,0xD2,0xFB,0xF7,0xF9,0xFB,0x68,0x46,0xFF,0xF7,0x06,0xF9,0x00,0x20,0x30,0x71,
+ 0xF0,0x80,0x30,0x81,0x05,0xB0,0xF0,0xBC,0x08,0xBC,0x18,0x47,0xDC,0x07,0x00,0x20,
+ 0xFC,0x94,0x00,0x00,0x15,0x49,0x18,0xB4,0x4A,0x7A,0x00,0x2A,0x23,0xD0,0x14,0x4B,
+ 0x92,0x07,0x04,0xD5,0x9A,0x8B,0x04,0x88,0x12,0x1B,0x52,0x1E,0x02,0x80,0x4A,0x7A,
+ 0x52,0x07,0x04,0xD5,0xDA,0x8B,0x43,0x88,0xD2,0x1A,0x52,0x1E,0x42,0x80,0x49,0x7A,
+ 0xC9,0x07,0x08,0xD0,0x01,0x88,0x6B,0x46,0x19,0x80,0x41,0x88,0x59,0x80,0x59,0x88,
+ 0x01,0x80,0x19,0x88,0x41,0x80,0x01,0x88,0x09,0x05,0x09,0x0D,0x01,0x80,0x41,0x88,
+ 0x09,0x05,0x09,0x0D,0x41,0x80,0x18,0xBC,0x70,0x47,0x00,0x00,0xBC,0x94,0x00,0x00,
+ 0x9C,0x94,0x00,0x00,0x02,0x49,0x00,0x03,0x40,0x18,0xC0,0x68,0x70,0x47,0x00,0x00,
+ 0x00,0x20,0x00,0x40,0x01,0x49,0x01,0x20,0x08,0x70,0x70,0x47,0x28,0x08,0x00,0x20,
+ 0x30,0xB4,0x05,0x03,0x05,0x48,0x02,0x9C,0x28,0x18,0x02,0x60,0x41,0x60,0x00,0x2B,
+ 0x00,0xD0,0x03,0x61,0x84,0x60,0x30,0xBC,0x70,0x47,0x00,0x00,0x00,0x20,0x00,0x40,
+ 0x02,0x4A,0x00,0x03,0x80,0x18,0x01,0x60,0x70,0x47,0x00,0x00,0x00,0x20,0x00,0x40,
+ 0x06,0x49,0x02,0x03,0x51,0x18,0x8A,0x68,0xFF,0x23,0x01,0x33,0x1A,0x43,0x8A,0x60,
+ 0x02,0x28,0x02,0xD1,0x02,0x49,0x00,0x20,0x08,0x70,0x70,0x47,0x00,0x20,0x00,0x40,
+ 0x28,0x08,0x00,0x20,0x01,0x03,0x04,0x48,0x08,0x18,0x81,0x68,0xFF,0x22,0x01,0x32,
+ 0x91,0x43,0x81,0x60,0x70,0x47,0x00,0x00,0x00,0x20,0x00,0x40,0xF0,0xB4,0x19,0x49,
+ 0x19,0x4D,0x08,0x68,0x2B,0x7A,0x00,0x04,0x00,0x22,0x00,0x0F,0x98,0x42,0x01,0xD8,
+ 0x08,0x68,0x1E,0xE0,0x00,0x20,0x06,0x00,0x01,0x27,0x8B,0x8E,0x1C,0x00,0xC4,0x40,
+ 0xE4,0x07,0x0B,0xD0,0x2C,0x7A,0x94,0x42,0x07,0xD2,0x3C,0x00,0x84,0x40,0xA3,0x43,
+ 0x8B,0x86,0x83,0x00,0x5B,0x18,0x9E,0x60,0x00,0xE0,0x52,0x1C,0x40,0x1C,0x0A,0x28,
+ 0xEB,0xD3,0x0F,0x23,0x08,0x68,0x1B,0x03,0x12,0x07,0x98,0x43,0x12,0x0C,0x10,0x43,
+ 0x08,0x60,0x00,0x04,0x02,0x0F,0x03,0xD0,0x00,0x0F,0x40,0x1C,0x20,0x31,0x88,0x75,
+ 0xF0,0xBC,0x70,0x47,0x58,0x07,0x00,0x20,0xBC,0x94,0x00,0x00,0xF8,0xB5,0x12,0x49,
+ 0xD9,0x20,0xC0,0x00,0x0C,0x18,0xE3,0x20,0xC0,0x00,0x0D,0x18,0x0F,0x48,0x00,0x27,
+ 0x0E,0x18,0xFF,0x43,0x20,0x00,0x0C,0x22,0x39,0x00,0x44,0x30,0xF9,0xF7,0x22,0xFB,
+ 0x20,0x00,0x0C,0x22,0x39,0x00,0x38,0x30,0xF9,0xF7,0x1C,0xFB,0x00,0x20,0x40,0x36,
+ 0x20,0x34,0xB0,0x77,0xA0,0x7D,0x00,0x28,0x02,0xD0,0x01,0x20,0x20,0x35,0xA8,0x75,
+ 0xF8,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x40,0x00,0x00,0x20,0x64,0x06,0x00,0x00,
+ 0x70,0xB5,0x05,0x00,0x08,0x48,0x00,0x22,0x04,0x04,0x24,0x0C,0x40,0x21,0x20,0x00,
+ 0xF9,0xF7,0xEA,0xFA,0x40,0x22,0x29,0x00,0x20,0x00,0x00,0x23,0xF9,0xF7,0xEC,0xFA,
+ 0x70,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0xC0,0x9F,0x00,0x00,0x02,0x4B,0x58,0x60,
+ 0x99,0x60,0x1A,0x60,0x70,0x47,0x00,0x00,0x00,0x30,0x00,0x40,0x01,0x04,0x00,0xB5,
+ 0x03,0x48,0x02,0x22,0x09,0x0C,0xFF,0xF7,0xF1,0xFF,0x08,0xBC,0x18,0x47,0x00,0x00,
+ 0xE1,0x04,0x00,0x00,0x04,0x48,0x00,0x78,0x00,0x28,0x04,0xD0,0x03,0x48,0x01,0x68,
+ 0x01,0x22,0x11,0x43,0x01,0x60,0x70,0x47,0xF6,0x07,0x00,0x20,0x00,0x30,0x00,0x40,
+ 0x04,0x48,0x00,0x78,0x00,0x28,0x04,0xD0,0x03,0x48,0x01,0x68,0x49,0x08,0x49,0x00,
+ 0x01,0x60,0x70,0x47,0xF6,0x07,0x00,0x20,0x00,0x30,0x00,0x40,0x04,0x49,0x09,0x78,
+ 0x00,0x29,0x03,0xD0,0x03,0x49,0x02,0x22,0x0A,0x61,0x88,0x60,0x70,0x47,0x00,0x00,
+ 0xF6,0x07,0x00,0x20,0x00,0x30,0x00,0x40,0xF8,0xB5,0x84,0x46,0x29,0x48,0x00,0x21,
+ 0x00,0x78,0x0C,0x00,0x0D,0x00,0x80,0x1E,0x00,0x06,0x00,0x0E,0x62,0x46,0x00,0x2A,
+ 0x8E,0x46,0x00,0xD0,0x49,0x1E,0x24,0x48,0x24,0x4F,0xC0,0x88,0x02,0x26,0x02,0x29,
+ 0x00,0x90,0x2B,0xDA,0x20,0x4A,0x60,0x46,0x40,0x18,0x1D,0x23,0x82,0x18,0x9B,0x01,
+ 0xD2,0x18,0x12,0x7C,0x05,0x2A,0x08,0xD2,0x83,0x00,0x1B,0x48,0x1B,0x18,0x1D,0x20,
+ 0x80,0x01,0x18,0x18,0x03,0x6A,0x96,0x2B,0x02,0xD3,0x01,0x20,0x86,0x46,0x05,0xE0,
+ 0xA2,0x42,0x00,0xD9,0x14,0x00,0xAB,0x42,0x00,0xD9,0x1D,0x00,0x49,0x1C,0x09,0x06,
+ 0x09,0x16,0xB1,0x42,0xDE,0xDB,0x70,0x46,0x00,0x28,0x07,0xD0,0x00,0x98,0x01,0x22,
+ 0x0D,0x49,0xD2,0x02,0x10,0x43,0xC8,0x80,0x00,0x20,0x03,0xE0,0x38,0x7E,0x0A,0x28,
+ 0x04,0xD2,0x40,0x1C,0x38,0x76,0xF8,0xBC,0x08,0xBC,0x18,0x47,0x00,0x98,0x01,0x22,
+ 0x05,0x49,0xD2,0x02,0x90,0x43,0xC8,0x80,0x00,0x20,0x38,0x76,0x08,0x83,0xF8,0xBC,
+ 0x08,0xBC,0x18,0x47,0x9C,0x94,0x00,0x00,0x40,0x00,0x00,0x20,0xC0,0x07,0x00,0x20,
+ 0x78,0x47,0xC0,0x46,0x1E,0xFF,0x2F,0xE1,0x07,0xB4,0x00,0x21,0x08,0x22,0x6B,0x46,
+ 0x41,0x5E,0x9A,0x5E,0x91,0x42,0x03,0xDB,0x0A,0x22,0x9A,0x5E,0x91,0x42,0x00,0xDD,
+ 0x02,0x80,0x02,0x21,0x04,0x22,0x6B,0x46,0x41,0x5E,0x9A,0x5E,0x91,0x42,0x03,0xDB,
+ 0x06,0x22,0x9A,0x5E,0x91,0x42,0x00,0xDD,0x42,0x80,0x03,0xB0,0x70,0x47,0x00,0x47,
+ 0x78,0x47,0xC0,0x46,0x14,0x30,0x9F,0xE5,0xC0,0x2F,0xA0,0xE1,0x93,0xC0,0xC1,0xE0,
+ 0x63,0x30,0xE0,0xE3,0xC1,0x12,0x62,0xE0,0x93,0x01,0x20,0xE0,0x1E,0xFF,0x2F,0xE1,
+ 0x1F,0x85,0xEB,0x51,0x78,0x47,0xC0,0x46,0x01,0xC0,0x5E,0xE5,0x0C,0x00,0x53,0xE1,
+ 0x03,0x30,0xDE,0x37,0x0C,0x30,0xDE,0x27,0x83,0xC0,0x8E,0xE0,0x1C,0xFF,0x2F,0xE1,
+ 0x78,0x47,0xC0,0x46,0x10,0x30,0x9F,0xE5,0x93,0x10,0x82,0xE0,0x63,0x30,0xE0,0xE3,
+ 0xA2,0x12,0xA0,0xE1,0x93,0x01,0x20,0xE0,0x1E,0xFF,0x2F,0xE1,0x1F,0x85,0xEB,0x51,
+ 0x10,0xB5,0xF9,0xF7,0x45,0xFA,0x10,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xC5,0x6D,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x00,0x6F,0x00,
+ 0xB9,0x00,0xF0,0x00,0x27,0x01,0x71,0x01,0xBB,0x01,0x27,0x00,0x73,0x00,0xBF,0x00,
+ 0x0B,0x01,0x57,0x01,0x90,0x01,0xC9,0x01,0x15,0x02,0x61,0x02,0xAD,0x02,0xF9,0x02,
+ 0x27,0x00,0x73,0x00,0xBF,0x00,0x0B,0x01,0x57,0x01,0x90,0x01,0xC9,0x01,0x15,0x02,
+ 0x61,0x02,0xAD,0x02,0xF9,0x02,0x00,0x00,0x38,0x48,0x41,0x6B,0xC9,0x07,0xFC,0xD0,
+ 0x41,0x6B,0x01,0x22,0x11,0x43,0x41,0x63,0x70,0x47,0x34,0x48,0xC2,0x69,0x41,0x14,
+ 0x8A,0x43,0xC2,0x61,0xC2,0x69,0x0A,0x43,0xC2,0x61,0xC2,0x69,0x8A,0x43,0xC2,0x61,
+ 0x70,0x47,0x10,0xB4,0x2D,0x4C,0x40,0x23,0x60,0x60,0x20,0x68,0x80,0x0A,0x80,0x02,
+ 0x10,0x43,0xA8,0x22,0x10,0x43,0x20,0x60,0x02,0xE0,0x08,0x78,0xA0,0x60,0x49,0x1C,
+ 0x5B,0x1E,0xFA,0xD2,0x10,0xBC,0x70,0x47,0xF0,0xB5,0x05,0x00,0x0E,0x00,0x1F,0x00,
+ 0x94,0x09,0x81,0x06,0x22,0x48,0x12,0xD1,0x91,0x06,0x10,0xD1,0x0C,0xE0,0x3A,0x00,
+ 0x31,0x00,0x28,0x00,0xFF,0xF7,0xDD,0xFF,0x40,0x35,0x2D,0x04,0x2D,0x0C,0x40,0x36,
+ 0xFF,0xF7,0xC2,0xFF,0xFF,0xF7,0xC9,0xFF,0x64,0x1E,0x60,0x1C,0xEF,0xD1,0xF0,0xBC,
+ 0x08,0xBC,0x18,0x47,0x15,0x4B,0x40,0x22,0x58,0x60,0x18,0x68,0x80,0x0A,0x80,0x02,
+ 0x08,0x43,0xA4,0x21,0x08,0x43,0x18,0x60,0x00,0x21,0x00,0xE0,0x99,0x60,0x52,0x1E,
+ 0xFC,0xD2,0x70,0x47,0x70,0xB5,0x05,0x00,0x16,0x00,0x8C,0x09,0x82,0x06,0x0C,0x48,
+ 0x10,0xD1,0x89,0x06,0x0E,0xD1,0x0A,0xE0,0x31,0x00,0x28,0x00,0xFF,0xF7,0xE2,0xFF,
+ 0x40,0x35,0x2D,0x04,0x2D,0x0C,0xFF,0xF7,0x97,0xFF,0xFF,0xF7,0x9E,0xFF,0x64,0x1E,
+ 0x60,0x1C,0xF1,0xD1,0x70,0xBC,0x08,0xBC,0x18,0x47,0x00,0x00,0x00,0x70,0x00,0x40,
+ 0xFF,0xFF,0xFF,0xFF,0x89,0x08,0x49,0x1E,0x49,0x04,0x01,0x22,0x49,0x08,0xD2,0x07,
+ 0x89,0x18,0x00,0x04,0x00,0x0C,0x01,0x43,0x03,0x48,0x41,0x61,0x41,0x69,0x00,0x29,
+ 0xFC,0xDB,0x80,0x6B,0x70,0x47,0x00,0x00,0x00,0x70,0x00,0x40,0x01,0x20,0x52,0xE2,
+ 0x1E,0xFF,0x2F,0x31,0xFF,0x10,0x01,0xE2,0x01,0x20,0x52,0xE2,0x01,0x10,0xC0,0xE4,
+ 0xFC,0xFF,0xFF,0x2A,0x1E,0xFF,0x2F,0xE1,0xC2,0x20,0xA0,0xE1,0x01,0x20,0x52,0xE2,
+ 0x1E,0xFF,0x2F,0x31,0x01,0x18,0xA0,0xE1,0x21,0x18,0xA0,0xE1,0x01,0x20,0x52,0xE2,
+ 0xB2,0x10,0xC0,0xE0,0xFC,0xFF,0xFF,0x2A,0x1E,0xFF,0x2F,0xE1,0x42,0x21,0xA0,0xE1,
+ 0x01,0x20,0x52,0xE2,0x1E,0xFF,0x2F,0x31,0x01,0x20,0x52,0xE2,0x04,0x10,0x80,0xE4,
+ 0xFC,0xFF,0xFF,0x2A,0x1E,0xFF,0x2F,0xE1,0x01,0x20,0x52,0xE2,0x1E,0xFF,0x2F,0x31,
+ 0x01,0x30,0xD1,0xE4,0x01,0x20,0x52,0xE2,0x01,0x30,0xC0,0xE4,0xFB,0xFF,0xFF,0x2A,
+ 0x1E,0xFF,0x2F,0xE1,0xC2,0x20,0xA0,0xE1,0x01,0x20,0x52,0xE2,0x1E,0xFF,0x2F,0x31,
+ 0xB2,0x30,0xD1,0xE0,0x01,0x20,0x52,0xE2,0xB2,0x30,0xC0,0xE0,0xFB,0xFF,0xFF,0x2A,
+ 0x1E,0xFF,0x2F,0xE1,0x42,0x21,0xA0,0xE1,0x01,0x20,0x52,0xE2,0x1E,0xFF,0x2F,0x31,
+ 0x04,0x30,0x91,0xE4,0x01,0x20,0x52,0xE2,0x04,0x30,0x80,0xE4,0xFB,0xFF,0xFF,0x2A,
+ 0x1E,0xFF,0x2F,0xE1,0xC2,0x20,0xA0,0xE1,0x01,0x20,0x52,0xE2,0x1E,0xFF,0x2F,0x31,
+ 0xB2,0x30,0xD1,0xE0,0x01,0x20,0x52,0xE2,0x04,0x30,0x80,0xE4,0xFB,0xFF,0xFF,0x2A,
+ 0x1E,0xFF,0x2F,0xE1,0x41,0x11,0xA0,0xE1,0x01,0x10,0x51,0xE2,0x1E,0xFF,0x2F,0x31,
+ 0x00,0x20,0xA0,0xE3,0x01,0x10,0x51,0xE2,0x04,0x20,0x80,0xE4,0xFC,0xFF,0xFF,0x2A,
+ 0x1E,0xFF,0x2F,0xE1,0x30,0x00,0x2D,0xE9,0x90,0xC0,0x9F,0xE5,0x88,0x40,0x9F,0xE5,
+ 0x00,0x00,0x9C,0xE5,0x88,0x00,0x9F,0xE5,0x01,0x10,0xD0,0xE5,0x00,0x00,0xD0,0xE5,
+ 0x91,0x00,0x00,0xE0,0x01,0x00,0x50,0xE2,0x30,0x00,0xBD,0x48,0x1E,0xFF,0x2F,0x41,
+ 0x70,0x30,0x9F,0xE5,0x70,0x20,0x9F,0xE5,0x00,0x11,0x9C,0xE7,0x80,0x50,0x83,0xE0,
+ 0xB0,0x10,0xC5,0xE1,0x00,0x11,0x94,0xE7,0x80,0x50,0x82,0xE0,0x01,0x00,0x50,0xE2,
+ 0xB0,0x10,0xC5,0xE1,0xF7,0xFF,0xFF,0x5A,0x30,0x00,0xBD,0xE8,0x1E,0xFF,0x2F,0xE1,
+ 0x3C,0x00,0x9F,0xE5,0x30,0x20,0x9F,0xE5,0x01,0x10,0xD0,0xE5,0x00,0x00,0xD0,0xE5,
+ 0x91,0x00,0x00,0xE0,0x01,0x00,0x50,0xE2,0x1E,0xFF,0x2F,0x41,0x2C,0x10,0x9F,0xE5,
+ 0x00,0x31,0x92,0xE7,0x80,0xC0,0x81,0xE0,0x23,0x38,0xA0,0xE1,0x01,0x00,0x50,0xE2,
+ 0xB0,0x30,0xCC,0xE1,0xF9,0xFF,0xFF,0x5A,0x1E,0xFF,0x2F,0xE1,0xD4,0x02,0x10,0x40,
+ 0x00,0x10,0x10,0x40,0x9C,0x94,0x00,0x00,0x2A,0x08,0x00,0x20,0x00,0x00,0x00,0x10,
+ 0xD2,0x02,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x01,0x01,0x00,0x01,0x9D,0x39,0x00,0x00,
+ 0x78,0x79,0x7A,0x00,0x64,0x32,0x64,0x32,0x19,0x00,0x4B,0x00,0x32,0x00,0x05,0x00,
+ 0x64,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x14,0x00,0x40,0x01,0xF4,0x01,
+ 0xF4,0x01,0xC2,0x01,0x2D,0x00,0x64,0x00,0x00,0x00,0x4B,0x00,0xFF,0x0F,0x32,0x00,
+ 0x19,0x00,0x01,0x00,0x0A,0x02,0x0A,0x01,0x32,0x0A,0x88,0x13,0xE8,0x03,0x00,0x96,
+ 0x96,0x96,0x96,0x00,0x96,0x96,0x96,0xB4,0x01,0x01,0x0A,0x00,0x50,0x00,0xF4,0x01,
+ 0xFF,0xFF,0x14,0x96,0x00,0x05,0x04,0x0A,0x0A,0x06,0x3C,0x00,0x2C,0x01,0x00,0x09,
+ 0x28,0x05,0x28,0x00,0x96,0x00,0x58,0x02,0x96,0x00,0x32,0x00,0x28,0x00,0x28,0x00,
+ 0x32,0x00,0x96,0x00,0x05,0x02,0x01,0x02,0x01,0x00,0x78,0x00,0xF0,0x00,0x14,0x00,
+ 0x50,0x00,0xDC,0x00,0x1E,0x00,0x32,0x00,0x64,0x00,0x14,0x04,0xFD,0x02,0x00,0x03,
+ 0x14,0x02,0x04,0x06,0x05,0x00,0x14,0x00,0x01,0x02,0x03,0x02,0x00,0x03,0x03,0x06,
+ 0x06,0x09,0x09,0x0C,0x0C,0x1E,0x55,0x01,0x03,0x00,0x05,0x02,0x05,0x0A,0x01,0x01,
+ 0x04,0x00,0x64,0x00,0x0C,0x05,0x1E,0x00,0x05,0x0A,0x01,0x00,0xA0,0x0F,0xD0,0x07,
+ 0xF4,0x01,0xC8,0x00,0xFF,0x00,0xC8,0x00,0x05,0x00,0x01,0x00,0x9D,0x39,0x00,0x00,
+ 0x78,0x79,0x7A,0x00,0x64,0x32,0x64,0x32,0x19,0x00,0x4B,0x00,0x32,0x00,0x05,0x00,
+ 0x64,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x18,0x01,0x14,0x00,0x68,0x01,0xF4,0x01,
+ 0xF4,0x01,0xC2,0x01,0x32,0x00,0x64,0x00,0x00,0x00,0x50,0x00,0xFF,0x0F,0x32,0x00,
+ 0x19,0x00,0x01,0x00,0x0A,0x02,0x0A,0x01,0x32,0x0A,0x88,0x13,0xF4,0x01,0x00,0x96,
+ 0x96,0x96,0x96,0x00,0xFF,0xFF,0xFF,0xFF,0x01,0x01,0x1E,0x00,0xC8,0x00,0xF4,0x01,
+ 0xFA,0xFA,0x0D,0xA0,0x00,0x05,0x04,0x0A,0x02,0x06,0x3C,0x00,0x2C,0x01,0x00,0x09,
+ 0x28,0x05,0x28,0x00,0x96,0x00,0x58,0x02,0x96,0x00,0x32,0x00,0x28,0x00,0x28,0x00,
+ 0x32,0x00,0x96,0x00,0x05,0x02,0x01,0x02,0x01,0x00,0x78,0x00,0xF0,0x00,0x14,0x00,
+ 0x50,0x00,0xDC,0x00,0x1E,0x00,0x32,0x00,0x64,0x00,0x14,0x04,0xFD,0x02,0x00,0x03,
+ 0x14,0x02,0x04,0x06,0x05,0x00,0x14,0x00,0x01,0x02,0x03,0x02,0x00,0x05,0x05,0x0A,
+ 0x0A,0x0F,0x0F,0x14,0x14,0x19,0x55,0x01,0x05,0x00,0x05,0x02,0x05,0x0A,0x01,0x01,
+ 0x04,0x00,0x64,0x00,0x0C,0x05,0x1E,0x00,0x05,0x0A,0x01,0x00,0xA0,0x0F,0xD0,0x07,
+ 0xF4,0x01,0xC8,0x00,0xFF,0x00,0xC8,0x00,0x05,0x00,0x2C,0x01,0x41,0x22,0x01,0x00,
+ 0x00,0x00,0x10,0x00,0xFF,0x00,0x30,0x00,0xFF,0x05,0xFF,0x03,0x18,0x18,0x88,0x00,
+ 0x30,0x7F,0x10,0x3F,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
+ 0x00,0x00,0x04,0x81,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x03,0xC8,0x40,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xC8,0x80,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x22,0x01,0x00,0x00,0x00,0x10,0x00,
+ 0xFF,0x00,0x30,0x00,0xFF,0x05,0xFF,0x03,0x10,0x10,0x88,0x00,0x30,0x7F,0x10,0x3F,
+ 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x04,0x81,
+ 0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x03,0xC8,0x40,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0xC8,0x80,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x41,0x22,0x01,0x00,0x00,0x00,0x10,0x00,0xFF,0x00,0x30,0x00,
+ 0xFF,0x05,0xFF,0x03,0x18,0x18,0x88,0x00,0x30,0x7F,0x10,0x3F,0x10,0x00,0x10,0x00,
+ 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x00,0x00,0x04,0x81,0x01,0x00,0x00,0x00,
+ 0x00,0x80,0x00,0x03,0xC8,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x80,0x00,0x00,0xC8,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x41,0x22,0x01,0x00,0x00,0x00,0x10,0x00,0xFF,0x00,0x30,0x00,0xFF,0x05,0xFF,0x03,
+ 0x10,0x10,0x88,0x00,0x30,0x7F,0x10,0x3F,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
+ 0x10,0x00,0x10,0x00,0x00,0x00,0x04,0x81,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x03,
+ 0xC8,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,
+ 0xC8,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x15,0x01,0x08,
+ 0x10,0x27,0x00,0x00,0x10,0x27,0x00,0x00,0x10,0x27,0x00,0x00,0xE0,0x93,0x04,0x00,
+ 0x80,0x96,0x98,0x00,0x30,0x75,0x00,0x00,0xE0,0x01,0x20,0x03,0x00,0x00,0x0C,0x00,
+ 0x00,0x00,0x05,0x00,0x05,0x00,0x03,0x02,0x7C,0x00,0x8C,0x00,0x00,0x00,0x03,0x00,
+ 0x30,0x00,0x50,0x00,0x00,0x00,0x00,0x00,0xDC,0x05,0x04,0xC8,0xC8,0x97,0x97,0x01,
+ 0x5A,0x03,0x02,0x00,0xDC,0x05,0x13,0x14,0xFF,0xFF,0xFF,0xDC,0x44,0x36,0x16,0x07,
+ 0x46,0x37,0x16,0x07,0x46,0x37,0x15,0x07,0x45,0x37,0x15,0x07,0x44,0x37,0x14,0x07,
+ 0x46,0x38,0x14,0x07,0x46,0x38,0x13,0x07,0x45,0x38,0x13,0x07,0x00,0x00,0x00,0x00,
+ 0x0A,0x00,0x32,0x00,0x50,0x00,0x32,0x00,0x50,0x00,0x0A,0x00,0x1E,0x01,0x14,0x00,
+ 0x00,0x00,0x2C,0x01,0x00,0x00,0x2C,0x01,0x5E,0x01,0x00,0x00,0x64,0x00,0x64,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5A,0x5A,0x5A,
+ 0x5A,0x00,0x00,0x00,0x01,0x02,0x00,0x00,0x01,0x02,0x00,0x00,0x00,0x01,0x00,0x00,
+ 0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x02,0x00,0x00,
+ 0x22,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x26,0x00,0x00,0x00,
+ 0x26,0x00,0x00,0x00,0x26,0x00,0x00,0x00,0x21,0x00,0x00,0x00,0x02,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
+ 0x04,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x0E,0x00,0x00,0x60,0x0F,0x00,0x00,
+ 0x60,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x41,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0xFF,0x0F,0x02,0x00,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x15,0x0E,0x15,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x00,0x00,0x28,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x60,0x0F,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x22,0x01,0x00,
+ 0x00,0x00,0x10,0x00,0xFF,0x00,0x30,0x00,0xFF,0x05,0xFF,0x03,0x18,0x18,0x88,0x00,
+ 0x30,0x7F,0x10,0x3F,0x10,0x00,0x10,0x00,0x00,0x00,0x04,0x81,0x00,0x00,0xFF,0x0F,
+ 0x01,0x00,0x00,0x00,0xFF,0x7F,0x00,0x00,0xC8,0x00,0x00,0x01,0x00,0x00,0x08,0x00,
+ 0x11,0x30,0x10,0x00,0x42,0x80,0x01,0x00,0xFF,0xFF,0xFF,0x10,0xFF,0xFF,0xFF,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x54,0x55,0x45,0x00,0x10,0x10,0x00,0x00,0x00,0x70,0x01,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x14,0x00,0x00,0x0C,0x0C,0x06,0x00,
+ 0x00,0x01,0x03,0x02,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x0F,0xC0,0xDA,0x00,0x00,
+ 0x50,0x31,0x20,0x01,0x50,0x38,0x20,0x08,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xD0,0x07,0x08,0x00,0x12,0x12,0xC8,0x01,0x90,0x81,0x0C,0x00,0x00,0x08,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x40,0x00,0x03,0xC8,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x40,0x00,0x00,0x64,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,
+ 0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,
+ 0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,
+ 0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,
+ 0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,0x50,0x31,0x20,0x01,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x3F,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x3F,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x3F,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x3F,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x3F,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x3F,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x3F,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x3F,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x3F,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x3F,0x26,0x26,0x26,0x26,
+ 0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x24,0x24,0x3F,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,0x24,
+ 0x24,0x24,0x24,0x3F,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,0x23,
+ 0x23,0x3F,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x26,0x3F,
+ 0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x3F,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x3F,0x27,0x27,0x27,0x27,
+ 0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x27,0x3F,0x28,0x28,0x28,0x28,0x28,0x28,
+ 0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x28,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
+ 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC8,0x61,0x14,0x04,
+ 0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,
+ 0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,
+ 0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,
+ 0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,
+ 0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x44,0xC8,0x61,0x14,0x44,
+ 0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0xC8,0x61,0x14,0x04,0x00,0xC0,0xA1,0xDF,
+ 0x21,0x2C,0xA2,0xDF,0x42,0xBC,0xA2,0xDF,0x63,0x28,0xA3,0xDF,0x84,0xB8,0xA3,0xDF,
+ 0xA5,0x24,0xA4,0xDF,0xC6,0xB4,0xA4,0xDF,0xE7,0x20,0xA5,0xDF,0x08,0xB1,0xA5,0xDF,
+ 0x29,0x9D,0xA8,0xDF,0x4A,0x01,0xA9,0xDF,0x6B,0x99,0xA9,0xDF,0x8C,0x05,0xAA,0xDF,
+ 0xAD,0x95,0xAA,0xDF,0xCE,0x09,0xA0,0xDF,0xEF,0x11,0xA0,0xDF,0x10,0x0E,0xA0,0xDF,
+ 0x31,0x46,0xA0,0xDF,0x52,0x52,0xA0,0xDF,0x73,0x4A,0xA0,0xDF,0x94,0x4E,0xA0,0xDF,
+ 0xB5,0x02,0xA0,0xDF,0xD6,0x02,0xA0,0xDF,0xF7,0x02,0xA0,0xDF,0x00,0x08,0x00,0x00,
+ 0x00,0x80,0x01,0x00,0x00,0x0C,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x06,0x00,0x00,
+ 0x00,0x60,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x30,0x00,0x00,0x80,0x01,0x00,0x00,
+ 0x01,0x10,0x00,0x00,0xC0,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x60,0x00,0x00,0x00,
+ 0x06,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x10,0x00,0x02,0x00,
+ 0x08,0x00,0x10,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x04,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x0F,0x1E,0x00,
+ 0xF8,0x0F,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x50,0x30,
+ 0x65,0x60,0x05,0x00,0x00,0x00,0x00,0x00,0x30,0x60,0x30,0x60,0x60,0x30,0x60,0x30,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
+ 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,0x38,
+ 0x01,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
+ 0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0B,0x38,0x30,0x00,0x00,0x00,0x05,0x00,
+ 0x49,0x53,0x54,0x56,0x31,0x54,0x41,0x47,0x00,0x00,0x00,0x00,0xC0,0x91,0x00,0x00,
+ 0xC0,0x9F,0x00,0x00,0x40,0x00,0x00,0x00,0xC0,0x91,0x00,0x00,0x00,0x04,0x00,0x00,
+ 0xC0,0x95,0x00,0x00,0x00,0x01,0x00,0x00,0xC0,0x96,0x00,0x00,0x00,0x02,0x00,0x00,
+ 0xC0,0x98,0x00,0x00,0x00,0x04,0x00,0x00,0x4F,0x00,0x94,0x00,0x00,0x00,0x00,0x00,
+ 0x1F,0x07,0xDE,0x07,0x14,0x24,0x0B,0x00,0x49,0x53,0x54,0x56,0x31,0x54,0x41,0x47
+};
+
+#endif // __IST30XXB_FW_H__
diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx.c b/drivers/input/touchscreen/ist30xxa/ist30xx.c new file mode 100644 index 00000000..21bb82ae --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx.c @@ -0,0 +1,1339 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/version.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/input.h> +#include <linux/interrupt.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/slab.h> + +#include <linux/platform_device.h> +#include <linux/device.h> +#include <linux/mutex.h> +#include <mach/gpio.h> +#include <linux/input/mt.h> + +#include "ist30xx.h" +#include "ist30xx_update.h" +#include "ist30xx_tracking.h" + +#ifdef CONFIG_OF +#include <linux/of_gpio.h> +#include <linux/of_device.h> +#endif + +#if IST30XX_DEBUG +#include "ist30xx_misc.h" +#endif +#if IST30XX_CMCS_TEST +#include "ist30xx_cmcs.h" +#endif +#if SEC_FACTORY_MODE +#include "ist30xx_sec.h" +extern int sec_touch_sysfs(struct ist30xx_data *data); +extern int sec_fac_cmd_init(struct ist30xx_data *data); +#endif + +#define MAX_ERR_CNT (100) + +#if IST30XX_USE_KEY +int ist30xx_key_code[] = { 0, KEY_MENU, KEY_BACK }; +#endif + +DEFINE_MUTEX(ist30xx_mutex); + +volatile bool ist30xx_irq_working = false; +static bool ist30xx_initialized = 0; +struct ist30xx_data *ts_data; +static struct delayed_work work_reset_check; +#if IST30XX_EVENT_MODE +static struct delayed_work work_noise_protect, work_debug_algorithm; +#endif + +static int ist30xx_power_status = -1; +static int ist30xx_ta_status = -1; +static int ist30xx_noise_mode = -1; + +#if IST30XX_INTERNAL_BIN && IST30XX_UPDATE_BY_WORKQUEUE +static struct delayed_work work_fw_update; +#endif + +int ist30xx_report_rate = -1; +int ist30xx_idle_rate = -1; + +u32 event_ms = 0, timer_ms = 0; +u32 ist30xx_scan_count = 0; +int ist30xx_scan_retry = 0; + +#if IST30XX_EVENT_MODE +static struct timer_list event_timer; +static struct timespec t_current; // ns +int timer_period_ms = 500; // 0.5sec +#define EVENT_TIMER_INTERVAL (HZ * timer_period_ms / 1000) +#endif // IST30XX_EVENT_MODE + +char *ist_vdd_name = "vddsim2"; + +#if IST30XX_DEBUG +extern TSP_INFO ist30xx_tsp_info; +extern TKEY_INFO ist30xx_tkey_info; +#endif + + +int ist30xx_dbg_level = IST30XX_DEBUG_LEVEL; +void tsp_printk(int level, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + int r; + + if (ist30xx_dbg_level < level) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + r = printk("%s %pV", IST30XX_DEBUG_TAG, &vaf); + + va_end(args); +} + +long get_milli_second(void) +{ +#if IST30XX_EVENT_MODE + ktime_get_ts(&t_current); + + return t_current.tv_sec * 1000 + t_current.tv_nsec / 1000000; +#else + return 0; +#endif // IST30XX_EVENT_MODE +} + +int ist30xx_intr_wait(long ms) +{ + long start_ms = get_milli_second(); + long curr_ms = 0; + + while (1) { + if (!ist30xx_irq_working) + break; + + curr_ms = get_milli_second(); + if ((curr_ms < 0) || (start_ms < 0) || (curr_ms - start_ms > ms)) { + tsp_info("%s() timeout(%dms)\n", __func__, ms); + return -EPERM; + } + + msleep(2); + } + return 0; +} + +void ist30xx_disable_irq(struct ist30xx_data *data) +{ + if (likely(data->irq_enabled)) { + ist30xx_tracking(TRACK_INTR_DISABLE); + disable_irq(data->client->irq); + data->irq_enabled = 0; + data->status.event_mode = false; + } +} + +void ist30xx_enable_irq(struct ist30xx_data *data) +{ + if (likely(!data->irq_enabled)) { + ist30xx_tracking(TRACK_INTR_ENABLE); + enable_irq(data->client->irq); + msleep(10); + data->irq_enabled = 1; + data->status.event_mode = true; + } +} + +int ist30xx_max_error_cnt = MAX_ERR_CNT; +int ist30xx_error_cnt = 0; +void ist30xx_scheduled_reset(void) +{ + if (likely(ist30xx_initialized)) + schedule_delayed_work(&work_reset_check, 0); +} + +static void ist30xx_request_reset(void) +{ + ist30xx_error_cnt++; + if (unlikely(ist30xx_error_cnt >= ist30xx_max_error_cnt)) { + tsp_info("%s()\n", __func__); + ist30xx_scheduled_reset(); + ist30xx_error_cnt = 0; + } +} + +#define NOISE_MODE_TA (0) +#define NOISE_MODE_CALL (1) +#define NOISE_MODE_COVER (2) +#define NOISE_MODE_POWER (8) +void ist30xx_start(struct ist30xx_data *data) +{ + if (ist30xx_initialized) { +#if IST30XX_EVENT_MODE + ist30xx_scan_count = 0; + ist30xx_scan_retry = 0; + mod_timer(&event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL * 2); +#endif + } + + ist30xx_tracking(ist30xx_ta_status ? + TRACK_CMD_TACON : TRACK_CMD_TADISCON); + + ist30xx_noise_mode &= ~(1 << NOISE_MODE_TA); + ist30xx_noise_mode |= (ist30xx_ta_status << NOISE_MODE_TA); + + ist30xx_noise_mode &= ~(1 << NOISE_MODE_POWER); + ist30xx_noise_mode |= (ist30xx_power_status << NOISE_MODE_POWER); + + ist30xx_noise_mode |= (TSP_LOCAL_CODE << 16); + ist30xx_write_cmd(data->client, CMD_SET_NOISE_MODE, ist30xx_noise_mode); + + tsp_info("%s(), local : %d, mode : 0x%x\n", __func__, + (ist30xx_noise_mode >> 16) & 0xFFFF, ist30xx_noise_mode & 0xFFFF); + + if (ist30xx_report_rate >= 0) { + ist30xx_write_cmd(data->client, CMD_SET_REPORT_RATE, + ist30xx_report_rate); + tsp_info(" reporting rate : %dus\n", ist30xx_report_rate); + } + + if (ist30xx_idle_rate >= 0) { + ist30xx_write_cmd(data->client, CMD_SET_IDLE_TIME, ist30xx_idle_rate); + tsp_info(" idle rate : %dus\n", ist30xx_idle_rate); + } + + ist30xx_cmd_start_scan(data->client); +} + + +int ist30xx_get_ver_info(struct ist30xx_data *data) +{ + int ret; + + data->fw.prev_core_ver = data->fw.core_ver; + data->fw.prev_param_ver = data->fw.param_ver; + data->fw.core_ver = data->fw.param_ver = 0; + + ret = ist30xx_read_cmd(data->client, CMD_GET_FW_VER, &data->fw.core_ver); + if (unlikely(ret)) + return ret; + + ret = ist30xx_read_cmd(data->client, CMD_GET_PARAM_VER, + &data->fw.param_ver); + if (unlikely(ret)) + return ret; + + ret = ist30xx_read_cmd(data->client, CMD_GET_SUB_VER, &data->fw.sub_ver); + if (unlikely(ret)) + return ret; + + tsp_info("IC version read core: %x, param: %x, sub: %x\n", + data->fw.core_ver, data->fw.param_ver, data->fw.sub_ver); + + return 0; +} + +#if IST30XX_DEBUG +void ist30xx_print_info(void) +{ + TSP_INFO *tsp = &ist30xx_tsp_info; + TKEY_INFO *tkey = &ist30xx_tkey_info; + + tsp_info("*** TSP/TKEY info ***\n"); + tsp_info("tscn finger num : %d\n", tsp->finger_num); + tsp_info("tscn dir swap: %d, flip x: %d, y: %d\n", + tsp->dir.swap_xy, tsp->dir.flip_x, tsp->dir.flip_y); + tsp_info("tscn ch_num tx: %d, rx: %d\n", + tsp->ch_num.tx, tsp->ch_num.rx); + tsp_info("tscn width: %d, height: %d\n", + tsp->width, tsp->height); + tsp_info("tkey enable: %d, key num: %d, axis rx: %d \n", + tkey->enable, tkey->key_num, tkey->axis_rx); + tsp_info("tkey ch_num[0] %d, [1] %d, [2] %d, [3] %d, [4] %d\n", + tkey->ch_num[0], tkey->ch_num[1], tkey->ch_num[2], + tkey->ch_num[3], tkey->ch_num[4]); +} +#endif + +#define CALIB_MSG_MASK (0xF0000FFF) +#define CALIB_MSG_VALID (0x80000CAB) +#define TRACKING_INTR_VALID (0x127EA597) +u32 tracking_intr_value = TRACKING_INTR_VALID; +int ist30xx_get_info(struct ist30xx_data *data) +{ + int ret; + u32 calib_msg; + u32 ms; + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(data); + +#if IST30XX_INTERNAL_BIN +#if IST30XX_DEBUG +#if IST30XX_UPDATE_BY_WORKQUEUE + ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size); +#endif + ist30xx_get_tsp_info(data); + ist30xx_get_tkey_info(data); +#endif // IST30XX_DEBUG +#else + + ret = ist30xx_get_ver_info(data); + if (unlikely(ret)) + goto get_info_end; + +#if IST30XX_DEBUG + ret = ist30xx_tsp_update_info(); + if (unlikely(ret)) + goto get_info_end; + + ret = ist30xx_tkey_update_info(); + if (unlikely(ret)) + goto get_info_end; +#endif // IST30XX_DEBUG +#endif // IST30XX_INTERNAL_BIN + +#if IST30XX_DEBUG + ist30xx_print_info(); + data->max_fingers = ist30xx_tsp_info.finger_num; + data->max_keys = ist30xx_tkey_info.key_num; +#endif // IST30XX_DEBUG + + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_CALIB_RESULT, &calib_msg); + if (likely(ret == 0)) { + tsp_info("calib status: 0x%08x\n", calib_msg); + ms = get_milli_second(); + ist30xx_put_track_ms(ms); + ist30xx_put_track(&tracking_intr_value, 1); + ist30xx_put_track(&calib_msg, 1); + if ((calib_msg & CALIB_MSG_MASK) != CALIB_MSG_VALID || + CALIB_TO_STATUS(calib_msg) > 0) { + ist30xx_calibrate(IST30XX_FW_UPDATE_RETRY); + ist30xx_reset(false); + } + } + +#if (IST30XX_EVENT_MODE && IST30XX_CHECK_CALIB) + if (likely(!data->status.update)) { + ret = ist30xx_cmd_check_calib(data->client); + if (likely(!ret)) { + data->status.calib = 1; + data->status.calib_msg = 0; + event_ms = (u32)get_milli_second(); + data->status.event_mode = true; + } + } +#else + ist30xx_start(ts_data); +#endif + +#if !(IST30XX_INTERNAL_BIN) +get_info_end: +#endif + if (likely(ret == 0)) + ist30xx_enable_irq(data); + mutex_unlock(&ist30xx_mutex); + + return ret; +} + +#define PRESS_MSG_MASK (0x01) +#define MULTI_MSG_MASK (0x02) +#define PRESS_MSG_KEY (0x6) +#define TOUCH_DOWN_MESSAGE ("p") +#define TOUCH_UP_MESSAGE ("r") +#define TOUCH_MOVE_MESSAGE (" ") +bool tsp_touched[IST30XX_MAX_MT_FINGERS] = { false, }; +bool tkey_pressed[IST30XX_MAX_KEYS] = { false, }; +void print_tsp_event(finger_info *finger) +{ + int idx = finger->bit_field.id - 1; + bool press; + + press = PRESSED_FINGER(ts_data->t_status, finger->bit_field.id); + + if (press) { + if (tsp_touched[idx] == false) { // touch down + tsp_notc("%s%d (%d, %d)\n", + TOUCH_DOWN_MESSAGE, finger->bit_field.id, + finger->bit_field.x, finger->bit_field.y); + tsp_touched[idx] = true; + } else { // touch move + tsp_debug("%s%d (%d, %d)\n", + TOUCH_MOVE_MESSAGE, finger->bit_field.id, + finger->bit_field.x, finger->bit_field.y); + } + } else { + if (tsp_touched[idx] == true) { // touch up + tsp_notc("%s%d\n", TOUCH_UP_MESSAGE, finger->bit_field.id); + tsp_touched[idx] = false; + } + } +} + +void print_tkey_event(int id) +{ + int idx = id - 1; + bool press = PRESSED_KEY(ts_data->t_status, id); + + if (press) { + if (tkey_pressed[idx] == false) { // tkey down + tsp_notc("k %s%d\n", TOUCH_DOWN_MESSAGE, id); + tkey_pressed[idx] = true; + } + } else { + if (tkey_pressed[idx] == true) { // tkey up + tsp_notc("k %s%d\n", TOUCH_UP_MESSAGE, id); + tkey_pressed[idx] = false; + } + } +} + +static void release_finger(int id) +{ + input_mt_slot(ts_data->input_dev, id - 1); + input_mt_report_slot_state(ts_data->input_dev, MT_TOOL_FINGER, false); + + ist30xx_tracking(TRACK_POS_FINGER + id); + tsp_info("%s() %d\n", __func__, id); + + tsp_touched[id - 1] = false; + + input_sync(ts_data->input_dev); +} + +#define CANCEL_KEY (0xFF) +#define RELEASE_KEY (0) +static void release_key(int id, u8 key_status) +{ + input_report_key(ts_data->input_dev, ist30xx_key_code[id], key_status); + + ist30xx_tracking(TRACK_POS_KEY + id); + tsp_info("%s() key%d, status: %d\n", __func__, id, key_status); + + tkey_pressed[id - 1] = false; + + input_sync(ts_data->input_dev); +} + +static void clear_input_data(struct ist30xx_data *data) +{ + int id = 1; + u32 status; + + status = PARSE_FINGER_STATUS(data->t_status); + while (status) { + if (status & 1) + release_finger(id); + status >>= 1; + id++; + } + + id = 1; + status = PARSE_KEY_STATUS(data->t_status); + while (status) { + if (status & 1) + release_key(id, RELEASE_KEY); + status >>= 1; + id++; + } + data->t_status = 0; +} + +static int check_report_fingers(struct ist30xx_data *data, int finger_counts) +{ + int i; + finger_info *fingers = (finger_info *)data->fingers; + + /* current finger info */ + for (i = 0; i < finger_counts; i++) { + if (unlikely((fingers[i].bit_field.x > IST30XX_MAX_X) || + (fingers[i].bit_field.y > IST30XX_MAX_Y))) { + tsp_warn("Invalid touch data - %d: %d(%d, %d), 0x%08x\n", i, + fingers[i].bit_field.id, + fingers[i].bit_field.x, + fingers[i].bit_field.y, + fingers[i].full_field); + + fingers[i].bit_field.id = 0; + ist30xx_tracking(TRACK_POS_UNKNOWN); + return -EPERM; + } + } + + return 0; +} + +static int check_valid_coord(u32 *msg, int cnt) +{ + int ret = 0; + u8 *buf = (u8 *)msg; + u8 chksum1 = msg[0] >> 24; + u8 chksum2 = 0; + + msg[0] &= 0x00FFFFFF; + + cnt *= IST30XX_DATA_LEN; + + while (cnt--) + chksum2 += *buf++; + + if (chksum1 != chksum2) { + tsp_err("intr chksum: %02x, %02x\n", chksum1, chksum2); + ret = -EPERM; + } + + return (chksum1 == chksum2) ? 0 : -EPERM; +} + +static void report_input_data(struct ist30xx_data *data, int finger_counts, + int key_counts) +{ + int id; + bool press = false; + finger_info *fingers = (finger_info *)data->fingers; + int idx = 0; + u32 status; + + status = PARSE_FINGER_STATUS(data->t_status); + for (id = 0; id < IST30XX_MAX_MT_FINGERS; id++) { + press = (status & (1 << id)) ? true : false; + + input_mt_slot(data->input_dev, id); + input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, press); + + fingers[idx].bit_field.id = id + 1; + print_tsp_event(&fingers[idx]); + + if (press == false) + continue; + + input_report_abs(data->input_dev, ABS_MT_POSITION_X, + fingers[idx].bit_field.x); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, + fingers[idx].bit_field.y); + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, + fingers[idx].bit_field.area); + idx++; + } + +#if IST30XX_USE_KEY + status = PARSE_KEY_STATUS(data->t_status); + for (id = 0; id < data->max_keys; id++) { + press = (status & (1 << id)) ? true : false; + + input_report_key(data->input_dev, ist30xx_key_code[id + 1], press); + + print_tkey_event(id + 1); + } +#endif // IST30XX_USE_KEY + + ist30xx_error_cnt = 0; + ist30xx_scan_retry = 0; + + input_sync(data->input_dev); +} + +/* + * CMD : CMD_GET_COORD + * + * 1st [31:24] [23:21] [20:16] [15:12] [11:10] [9:0] + * Checksum KeyCnt KeyStatus FingerCnt Rsvd. FingerStatus + * 2nd [31:28] [27:24] [23:12] [11:0] + * ID Area X Y + */ +u32 intr_debug_addr, intr_debug2_addr, intr_debug3_addr = 0; +u32 intr_debug_size, intr_debug2_size, intr_debug3_size = 0; +static irqreturn_t ist30xx_irq_thread(int irq, void *ptr) +{ + int i, ret; + int key_cnt, finger_cnt, read_cnt; + struct ist30xx_data *data = ts_data; + int offset = 1; + u32 msg[IST30XX_MAX_MT_FINGERS + offset]; + u32 ms; + + ist30xx_irq_working = true; + + if (unlikely(!data->irq_enabled)) + goto irq_end; + + ms = get_milli_second(); + + memset(msg, 0, sizeof(msg)); + + ret = ist30xx_get_position(data->client, msg, 1); + if (unlikely(ret)) + goto irq_err; + + tsp_verb("intr msg: 0x%08x\n", *msg); + + if (unlikely(*msg == 0xE11CE970)) // TSP IC Exception + goto irq_ic_err; + + if (unlikely(*msg == 0 || *msg == 0xFFFFFFFF)) // Unknown CMD + goto irq_err; + + event_ms = ms; + ist30xx_put_track_ms(event_ms); + ist30xx_put_track(&tracking_intr_value, 1); + ist30xx_put_track(msg, 1); + + if (unlikely((*msg & CALIB_MSG_MASK) == CALIB_MSG_VALID)) { + data->status.calib_msg = *msg; + tsp_info("calib status: 0x%08x\n", data->status.calib_msg); + + goto irq_end; +#if IST30XX_CHKIC + } else if (*msg == IST30XX_CHKIC_END) { + data->status.chkic_msg = *msg; + tsp_info("IC check status: 0x%08x\n", data->status.chkic_msg); + + goto irq_end; +#endif + } + +#if IST30XX_ENABLE_GESTURE + ret = PARSE_GESTURE_MESSAGE(*msg); + if (unlikely(ret > 0)) { + tsp_info("Gesture ID: %d (0x%08x)\n", ret, *msg); + ist30xx_gesture_cmd(data, ret); + + goto irq_end; + } +#endif + + memset(data->fingers, 0, sizeof(data->fingers)); + + /* Unknown interrupt data for extend coordinate */ + if (unlikely(!CHECK_INTR_STATUS(*msg))) + goto irq_err; + + data->t_status = *msg; + key_cnt = PARSE_KEY_CNT(data->t_status); + finger_cnt = PARSE_FINGER_CNT(data->t_status); + read_cnt = finger_cnt; + + if (unlikely((finger_cnt > data->max_fingers) || + (key_cnt > data->max_keys))) { + tsp_warn("Invalid touch count - finger: %d(%d), key: %d(%d)\n", + finger_cnt, data->max_fingers, key_cnt, data->max_keys); + goto irq_err; + } + + if (read_cnt > 0) { +#if I2C_BURST_MODE + ret = ist30xx_get_position(data->client, &msg[offset], read_cnt); + if (unlikely(ret)) + goto irq_err; + + for (i = 0; i < read_cnt; i++) + data->fingers[i].full_field = msg[i + offset]; +#else + for (i = 0; i < read_cnt; i++) { + ret = ist30xx_get_position(data->client, &msg[i + offset], 1); + if (unlikely(ret)) + goto irq_err; + + data->fingers[i].full_field = msg[i + offset]; + } +#endif // I2C_BURST_MODE + + ist30xx_put_track(msg + offset, read_cnt); + for (i = 0; i < read_cnt; i++) + tsp_verb("intr msg(%d): 0x%08x\n", i + offset, msg[i + offset]); + } + + ret = check_valid_coord(&msg[0], read_cnt + 1); + if (unlikely(ret < 0)) + goto irq_err; + + if (unlikely(check_report_fingers(data, finger_cnt))) + goto irq_end; + + report_input_data(data, finger_cnt, key_cnt); + + if (intr_debug2_addr > 0 && intr_debug2_size > 0) { + tsp_notc("Intr_debug2 (addr: 0x%08x)\n", intr_debug2_addr); + for (i = 0; i < intr_debug2_size; i++) { + ist30xx_read_buf(data->client, + intr_debug2_addr + IST30XX_DATA_LEN * i, &msg[i], 1); + + tsp_notc("\t%08x\n", msg[i]); + } + ist30xx_put_track(msg, intr_debug2_size); + } + + if (intr_debug3_addr > 0 && intr_debug3_size > 0) { + tsp_notc("Intr_debug3 (addr: 0x%08x)\n", intr_debug3_addr); + for (i = 0; i < intr_debug3_size; i++) { + ist30xx_read_buf(data->client, + intr_debug3_addr + IST30XX_DATA_LEN * i, &msg[i], 1); + + tsp_notc("\t%08x\n", msg[i]); + } + ist30xx_put_track(msg, intr_debug3_size); + } + + goto irq_end; + +irq_err: + tsp_err("intr msg: 0x%08x, ret: %d\n", msg[0], ret); + ist30xx_request_reset(); +irq_end: + ist30xx_irq_working = false; + event_ms = (u32)get_milli_second(); + return IRQ_HANDLED; + +irq_ic_err: + tsp_err("Occured IC exception\n"); + ist30xx_scheduled_reset(); + ist30xx_irq_working = false; + event_ms = (u32)get_milli_second(); + return IRQ_HANDLED; +} + +#ifdef CONFIG_HAS_EARLYSUSPEND +#define ist30xx_suspend NULL +#define ist30xx_resume NULL +static void ist30xx_early_suspend(struct early_suspend *h) +{ + struct ist30xx_data *data = container_of(h, struct ist30xx_data, + early_suspend); + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(data); + del_timer(&event_timer); + cancel_delayed_work_sync(&work_noise_protect); + cancel_delayed_work_sync(&work_reset_check); + cancel_delayed_work_sync(&work_debug_algorithm); + ist30xx_internal_suspend(data); + clear_input_data(data); + mutex_unlock(&ist30xx_mutex); +} +static void ist30xx_late_resume(struct early_suspend *h) +{ + struct ist30xx_data *data = container_of(h, struct ist30xx_data, + early_suspend); + + ist30xx_power_status = 1; + + mutex_lock(&ist30xx_mutex); + ist30xx_internal_resume(data); + ist30xx_start(data); + ist30xx_enable_irq(data); + mutex_unlock(&ist30xx_mutex); +} +#else +static int ist30xx_suspend(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ist30xx_data *data = i2c_get_clientdata(client); + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(data); + del_timer(&event_timer); + cancel_delayed_work_sync(&work_noise_protect); + cancel_delayed_work_sync(&work_reset_check); + cancel_delayed_work_sync(&work_debug_algorithm); + ist30xx_internal_suspend(data); + clear_input_data(data); + mutex_unlock(&ist30xx_mutex); + + return 0; +} +static int ist30xx_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct ist30xx_data *data = i2c_get_clientdata(client); + + ist30xx_power_status = 1; + + mutex_lock(&ist30xx_mutex); + ist30xx_internal_resume(data); + ist30xx_start(data); + ist30xx_enable_irq(data); + mutex_unlock(&ist30xx_mutex); + + return 0; +} +#endif // CONFIG_HAS_EARLYSUSPEND + +static void ist30xx_shutdown(struct i2c_client *client) +{ + struct ist30xx_data *data = i2c_get_clientdata(client); + + if(ist30xx_initialized) + { + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(data); + ist30xx_internal_suspend(data); + mutex_unlock(&ist30xx_mutex); + + del_timer_sync(&event_timer); + } + +} + +void ist30xx_set_ta_mode(bool charging) +{ + tsp_info("%s(), charging = %d\n", __func__, charging); + + if (unlikely(charging == ist30xx_ta_status)) + return; + + if (unlikely(ist30xx_noise_mode == -1)) { + ist30xx_ta_status = charging ? 1 : 0; + return; + } + + ist30xx_ta_status = charging ? 1 : 0; + + ist30xx_scheduled_reset(); +} +EXPORT_SYMBOL(ist30xx_set_ta_mode); + +void ist30xx_set_call_mode(int mode) +{ + tsp_info("%s(), mode = %d\n", __func__, mode); + + if (unlikely(mode == ((ist30xx_noise_mode >> NOISE_MODE_CALL) & 1))) + return; + + ist30xx_noise_mode &= ~(1 << NOISE_MODE_CALL); + if (mode) + ist30xx_noise_mode |= (1 << NOISE_MODE_CALL); + + ist30xx_scheduled_reset(); +} +EXPORT_SYMBOL(ist30xx_set_call_mode); + +void ist30xx_set_cover_mode(int mode) +{ + tsp_info("%s(), mode = %d\n", __func__, mode); + + if (unlikely(mode == ((ist30xx_noise_mode >> NOISE_MODE_COVER) & 1))) + return; + + ist30xx_noise_mode &= ~(1 << NOISE_MODE_COVER); + if (mode) + ist30xx_noise_mode |= (1 << NOISE_MODE_COVER); + + ist30xx_scheduled_reset(); +} +EXPORT_SYMBOL(ist30xx_set_cover_mode); + +void charger_enable(int enable) +{ + bool charging = enable ? true : false; + + ist30xx_set_ta_mode(charging); +} + +static void reset_work_func(struct work_struct *work) +{ + if (unlikely((ts_data == NULL) || (ts_data->client == NULL))) + return; + + tsp_info("Request reset function\n"); + + if (likely((ist30xx_initialized == 1) && (ts_data->status.power == 1) && + (ts_data->status.update != 1) && (ts_data->status.calib != 1))) { + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(ts_data); + clear_input_data(ts_data); + ist30xx_reset(false); + ist30xx_start(ts_data); + ist30xx_enable_irq(ts_data); + mutex_unlock(&ist30xx_mutex); + } +} + +#if IST30XX_INTERNAL_BIN && IST30XX_UPDATE_BY_WORKQUEUE +static void fw_update_func(struct work_struct *work) +{ + if (unlikely((ts_data == NULL) || (ts_data->client == NULL))) + return; + + tsp_info("FW update function\n"); + + if (likely(ist30xx_auto_bin_update(ts_data))) + ist30xx_disable_irq(ts_data); +} +#endif // IST30XX_INTERNAL_BIN && IST30XX_UPDATE_BY_WORKQUEUE + + +#if IST30XX_EVENT_MODE +u32 ist30xx_max_scan_retry = 2; +u32 ist30xx_algr_addr = 0, ist30xx_algr_size = 0; + +#define SCAN_STATUS_MAGIC (0x3C000000) +#define SCAN_STATUS_MASK (0xFF000000) +#define FINGER_CNT_MASK (0x00F00000) +#define SCAN_CNT_MASK (0x000FFFFF) +#define GET_FINGER_CNT(n) ((n & FINGER_CNT_MASK) >> 20) +#define GET_SCAN_CNT(n) (n & SCAN_CNT_MASK) +static void noise_work_func(struct work_struct *work) +{ +#if IST30XX_NOISE_MODE + int ret; + u32 scan_status = 0; + + ret = ist30xx_read_cmd(ts_data->client, IST30XXB_MEM_COUNT, &scan_status); + if (unlikely(ret)) { + tsp_warn("Mem scan count read fail!\n"); + goto retry_timer; + } + + ist30xx_put_track_ms(timer_ms); + ist30xx_put_track(&scan_status, 1); + + tsp_verb("scan status: 0x%x\n", scan_status); + + /* Check valid scan count */ + if (unlikely((scan_status & SCAN_STATUS_MASK) != SCAN_STATUS_MAGIC)) { + tsp_warn("Scan status is not corrected! (0x%08x)\n", scan_status); + goto retry_timer; + } + + /* Status of IC is idle */ + if (GET_FINGER_CNT(scan_status) == 0) { + if ((PARSE_FINGER_CNT(ts_data->t_status) > 0) || + (PARSE_KEY_CNT(ts_data->t_status) > 0)) + clear_input_data(ts_data); + } + + scan_status &= SCAN_CNT_MASK; + + /* Status of IC is lock-up */ + if (unlikely(scan_status == ist30xx_scan_count)) { + tsp_warn("TSP IC is not responded! (0x%08x)\n", scan_status); + goto retry_timer; + } else { + ist30xx_scan_retry = 0; + } + + ist30xx_scan_count = scan_status; + + return; + +retry_timer: + ist30xx_scan_retry++; + tsp_warn("Retry scan status!(%d)\n", ist30xx_scan_retry); + + if (unlikely(ist30xx_scan_retry == ist30xx_max_scan_retry)) { + ist30xx_scheduled_reset(); + ist30xx_scan_retry = 0; + } +#endif // IST30XX_NOISE_MODE +} + +static void debug_work_func(struct work_struct *work) +{ +#if IST30XX_ALGORITHM_MODE + int ret = -EPERM; + int i; + u32 *buf32; + + buf32 = kzalloc(ist30xx_algr_size, GFP_KERNEL); + + for (i = 0; i < ist30xx_algr_size; i++) { + ret = ist30xx_read_buf(ts_data->client, + ist30xx_algr_addr + IST30XX_DATA_LEN * i, &buf32[i], 1); + if (ret) { + tsp_warn("Algorithm mem addr read fail!\n"); + return; + } + } + + ist30xx_put_track(buf32, ist30xx_algr_size); + + tsp_debug(" 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", + buf32[0], buf32[1], buf32[2], buf32[3], buf32[4]); +#endif +} + +void timer_handler(unsigned long data) +{ + struct ist30xx_status *status = &ts_data->status; + + if (ist30xx_irq_working) + goto restart_timer; + + if (status->event_mode) { + if (likely((status->power == 1) && (status->update != 1))) { + timer_ms = (u32)get_milli_second(); + if (unlikely(status->calib == 1)) { // Check calibration + if ((status->calib_msg & CALIB_MSG_MASK) == CALIB_MSG_VALID) { + tsp_info("Calibration check OK!!\n"); + schedule_delayed_work(&work_reset_check, 0); + status->calib = 0; + } else if (timer_ms - event_ms >= 3000) { // 3second + tsp_info("calibration timeout over 3sec\n"); + schedule_delayed_work(&work_reset_check, 0); + status->calib = 0; + } + } else if (likely(status->noise_mode)) { + if (timer_ms - event_ms > 100) // 100ms after last interrupt + schedule_delayed_work(&work_noise_protect, 0); + } + +#if IST30XX_ALGORITHM_MODE + if ((ist30xx_algr_addr >= IST30XXB_ACCESS_ADDR) && + (ist30xx_algr_size > 0)) { + if (timer_ms - event_ms > 100) // 100ms after last interrupt + schedule_delayed_work(&work_debug_algorithm, 0); + } +#endif + } + } + +restart_timer: + mod_timer(&event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); +} +#endif // IST30XX_EVENT_MODE + +static int ist30xx_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + int retry = 3; + struct ist30xx_data *data; + struct input_dev *input_dev; + int ist_gpio = 0; + + tsp_info("##### IST30XX(Ver%d) Initialize #####\n", IST30XX_DD_VERSION); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + printk(KERN_INFO "i2c_check_functionality error\n"); + return -EIO; + } + tsp_info("%s(), the i2c addr=0x%x\n", __func__, client->addr); + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + +#ifdef CONFIG_OF + struct device_node *np = client->dev.of_node; + + tsp_info("the client->dev.of_node=0x%x\n", client->dev.of_node); + + if (client->dev.of_node){ + ist_gpio = of_get_gpio(np, 0); + of_property_read_string(np, "tsp_pwr_name", &ist_vdd_name); + tsp_info("gpio id=%d,power name:%s\n", ist_gpio,ist_vdd_name); + } +#endif + + input_dev = input_allocate_device(); + if (unlikely(!input_dev)) { + ret = -ENOMEM; + tsp_err("%s(), input_allocate_device failed (%d)\n", + __func__, ret); + goto err_alloc_dev; + } + +#ifndef CONFIG_OF + ist_gpio = 82; + ist_vdd_name = "vddsim2"; +#endif + + /* configure touchscreen interrupt gpio */ + ret = gpio_request(ist_gpio, "ist30xx_irq_gpio"); + printk("[TSP]request gpio id = %d\n", ist_gpio); + if (ret) { + tsp_err("unable to request gpio.(%s)\r\n",input_dev->name); + goto err_init_drv; + } + + client->irq = gpio_to_irq(ist_gpio); + printk("[TSP] client->irq : %d\n", client->irq); + + data->max_fingers = data->max_keys = IST30XX_MAX_MT_FINGERS; + data->irq_enabled = 1; + data->client = client; + data->input_dev = input_dev; + i2c_set_clientdata(client, data); + + input_mt_init_slots(input_dev, IST30XX_MAX_MT_FINGERS, 0); + + input_dev->name = "ist30xx_ts_input"; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = &client->dev; + + set_bit(EV_ABS, input_dev->evbit); + set_bit(INPUT_PROP_DIRECT, input_dev->propbit); + + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, IST30XX_MAX_X, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, IST30XX_MAX_Y, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, IST30XX_MAX_W, 0, 0); + +#if IST30XX_USE_KEY + { + int i; + set_bit(EV_KEY, input_dev->evbit); + set_bit(EV_SYN, input_dev->evbit); + for (i = 1; i < ARRAY_SIZE(ist30xx_key_code); i++) + set_bit(ist30xx_key_code[i], input_dev->keybit); + } +#endif + + input_set_drvdata(input_dev, data); + ret = input_register_device(input_dev); + if (unlikely(ret)) { + input_free_device(input_dev); + goto err_reg_dev; + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + data->early_suspend.suspend = ist30xx_early_suspend; + data->early_suspend.resume = ist30xx_late_resume; + register_early_suspend(&data->early_suspend); +#endif + + ts_data = data; + + ret = ist30xx_init_system(); + if (unlikely(ret)) { + tsp_err("chip initialization failed\n"); + goto err_init_drv; + } + + ret = ist30xx_init_update_sysfs(); + if (unlikely(ret)) + goto err_init_drv; + +#if IST30XX_DEBUG + ret = ist30xx_init_misc_sysfs(); + if (unlikely(ret)) + goto err_init_drv; +#endif + +#if IST30XX_CMCS_TEST + ret = ist30xx_init_cmcs_sysfs(); + if (unlikely(ret)) + goto err_init_drv; +#endif + +#if SEC_FACTORY_MODE + ret = sec_fac_cmd_init(data); + if (unlikely(ret)) + goto err_init_drv; + ret = sec_touch_sysfs(data); + if (unlikely(ret)) + goto err_init_drv; +#endif + +#if IST30XX_TRACKING_MODE + ret = ist30xx_init_tracking_sysfs(); + if (unlikely(ret)) + goto err_init_drv; +#endif + + ret = request_threaded_irq(client->irq, NULL, ist30xx_irq_thread, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "ist30xx_ts", data); + if (unlikely(ret)) + goto err_irq; + + ist30xx_disable_irq(data); + + while ((data->chip_id != IST30XXB_CHIP_ID) && + (data->chip_id != IST3038_CHIP_ID)) { + ret = ist30xx_read_cmd(data->client, IST30XXB_REG_CHIPID, + &data->chip_id); + if (unlikely(ret)) { + tsp_info("tspid: %x\n", data->chip_id); + ist30xx_reset(false); + } + + if (data->chip_id == 0x3000B) + data->chip_id = IST30XXB_CHIP_ID; + + if (data->chip_id == 0x3038B) + data->chip_id = IST3038_CHIP_ID; + + if (retry-- == 0) + break; + } + + retry = 3; + while (retry-- > 0) { + ret = ist30xx_read_cmd(data->client, IST30XXB_REG_TSPTYPE, + &data->tsp_type); + + tsp_info("tsptype: %x\n", data->tsp_type); + data->tsp_type = IST30XXB_PARSE_TSPTYPE(data->tsp_type); + + if (likely(ret == 0)) + break; + + if (unlikely(retry == 0)) + goto err_irq; + } + + tsp_info("TSP IC: %x, TSP Vendor: %x\n", data->chip_id, data->tsp_type); + + data->status.event_mode = false; + +#if IST30XX_INTERNAL_BIN +#if IST30XX_UPDATE_BY_WORKQUEUE + INIT_DELAYED_WORK(&work_fw_update, fw_update_func); + schedule_delayed_work(&work_fw_update, IST30XX_UPDATE_DELAY); +#else + ret = ist30xx_auto_bin_update(data); + if (unlikely(ret != 0)) + goto err_irq; +#endif +#endif // IST30XX_INTERNAL_BIN + + if (ist30xx_ta_status < 0) + ist30xx_ta_status = 0; + + if (ist30xx_power_status < 0) + ist30xx_power_status = 0; + + if (ist30xx_noise_mode < 0) + ist30xx_noise_mode = 0; + + ret = ist30xx_get_info(data); + tsp_info("Get info: %s\n", (ret == 0 ? "success" : "fail")); + + INIT_DELAYED_WORK(&work_reset_check, reset_work_func); +#if IST30XX_EVENT_MODE + INIT_DELAYED_WORK(&work_noise_protect, noise_work_func); + INIT_DELAYED_WORK(&work_debug_algorithm, debug_work_func); +#endif + +#if IST30XX_EVENT_MODE + init_timer(&event_timer); + event_timer.function = timer_handler; + event_timer.expires = jiffies_64 + (EVENT_TIMER_INTERVAL); + mod_timer(&event_timer, get_jiffies_64() + EVENT_TIMER_INTERVAL); +#endif + + ist30xx_initialized = 1; + tsp_info("Probe end\n"); + + return 0; + +err_irq: + tsp_info("ChipID: %x\n", data->chip_id); + ist30xx_disable_irq(data); + free_irq(client->irq, data); +err_init_drv: + data->status.event_mode = false; + tsp_err("Error, ist30xx init driver\n"); + ist30xx_power_off(); +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&data->early_suspend); +#endif + input_unregister_device(input_dev); + return 0; + +err_reg_dev: +err_alloc_dev: + tsp_err("Error, ist30xx mem free\n"); + kfree(data); + return 0; +} + + +static int __exit ist30xx_remove(struct i2c_client *client) +{ + struct ist30xx_data *data = i2c_get_clientdata(client); + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&data->early_suspend); +#endif + + ist30xx_disable_irq(data); + free_irq(client->irq, data); + ist30xx_power_off(); + + input_unregister_device(data->input_dev); + kfree(data); + + return 0; +} + + +static struct i2c_device_id ist30xx_idtable[] = { + { IST30XX_DEV_NAME, 0 }, + {}, +}; +MODULE_DEVICE_TABLE(i2c, ist30xx_idtable); + +#ifdef CONFIG_HAS_EARLYSUSPEND +static const struct dev_pm_ops ist30xx_pm_ops = { + .suspend = ist30xx_suspend, + .resume = ist30xx_resume, +}; +#endif + +#ifdef CONFIG_OF +static const struct of_device_id ist30xxb_ts_of_match[] = { + { .compatible = "Imagis,IST30XX", }, + { } +}; +#endif + +static struct i2c_driver ist30xx_i2c_driver = { + .id_table = ist30xx_idtable, + .probe = ist30xx_probe, + .remove = __exit_p(ist30xx_remove), + .shutdown = ist30xx_shutdown, + .driver = { + .owner = THIS_MODULE, + .name = IST30XX_DEV_NAME, +#ifdef CONFIG_HAS_EARLYSUSPEND + .pm = &ist30xx_pm_ops, +#endif + +#ifdef CONFIG_OF + .of_match_table = ist30xxb_ts_of_match, +#endif + }, +}; + +static int __init ist30xx_init(void) +{ + tsp_info("Imagis init called\n"); + return i2c_add_driver(&ist30xx_i2c_driver); +} + + +static void __exit ist30xx_exit(void) +{ + i2c_del_driver(&ist30xx_i2c_driver); +} + +module_init(ist30xx_init); +module_exit(ist30xx_exit); + +MODULE_DESCRIPTION("Imagis IST30XX touch driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx.h b/drivers/input/touchscreen/ist30xxa/ist30xx.h new file mode 100644 index 00000000..4c5bd332 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx.h @@ -0,0 +1,300 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XX_H__ +#define __IST30XX_H__ + +/* + * Support F/W ver : IST30xxB v5.0 + * Support IC : IST30xxB, IST3038 + * Release : 2014.06.13 by Sanghoon Kwak + */ + +#define IMAGIS_IST30XX (1) /* 3026, 3032 */ +#define IMAGIS_IST30XXB (2) /* 3026B, 3032B */ +#define IMAGIS_IST3038 (3) /* 3038 */ +#define IMAGIS_IST3044 (4) /* 3044 */ + +//#define IMAGIS_TSP_IC IMAGIS_IST30XXB +#define IMAGIS_TSP_IC IMAGIS_IST3038 + +#define I2C_BURST_MODE (1) +#define I2C_MONOPOLY_MODE (0) + +#define IST30XX_EVENT_MODE (1) +#if IST30XX_EVENT_MODE +# define IST30XX_NOISE_MODE (1) +# define IST30XX_TRACKING_MODE (1) +# define IST30XX_ALGORITHM_MODE (1) +#else +# define IST30XX_NOISE_MODE (0) +# define IST30XX_TRACKING_MODE (0) +# define IST30XX_ALGORITHM_MODE (0) +#endif + +#define IST30XX_USE_KEY (1) +#define IST30XX_DEBUG (1) +#define IST30XX_CMCS_TEST (1) +#define IST30XX_CHKIC (1) + +#define SEC_FACTORY_MODE (1) + +#define IST30XX_DEV_NAME "IST30XX" +#define IST30XX_CHIP_ID (0x30003000) +#define IST30XXA_CHIP_ID (0x300A300A) +#define IST30XXB_CHIP_ID (0x300B300B) +#define IST3038_CHIP_ID (0x30383038) + +#define IST30XX_DEV_ID (0xA0 >> 1) + +#define IST30XX_ADDR_LEN (4) +#define IST30XX_DATA_LEN (4) + +#define IST30XX_MAX_MT_FINGERS (10) +#define IST30XX_MAX_KEYS (5) + +#define IST30XX_MAX_X (480) +#define IST30XX_MAX_Y (800) +#define IST30XX_MAX_W (15) + +/* I2C Transfer msg number */ +#define WRITE_CMD_MSG_LEN (1) +#define READ_CMD_MSG_LEN (2) + +#define NORMAL_TEMPERATURE (0) +#define LOW_TEMPERATURE (1) +#define HIGH_TEMPERATURE (2) + +/* Local */ +#define TSP_LOCAL_EU (0) +#define TSP_LOCAL_EEU (1) +#define TSP_LOCAL_TD (11) +#define TSP_LOCAL_CMCC (12) +#define TSP_LOCAL_CU (13) +#define TSP_LOCAL_SPRD (14) +#define TSP_LOCAL_CTC (15) +#define TSP_LOCAL_INDIA (21) +#define TSP_LOCAL_SWASIA (22) +#define TSP_LOCAL_NA (31) +#define TSP_LOCAL_LA (32) +#define TSP_LOCAL_CODE TSP_LOCAL_EU + +/* Debug message */ +#define DEV_ERR (1) +#define DEV_WARN (2) +#define DEV_INFO (3) +#define DEV_NOTICE (4) +#define DEV_DEBUG (5) +#define DEV_VERB (6) + +#define IST30XX_DEBUG_TAG "[ TSP ]" +#define IST30XX_DEBUG_LEVEL DEV_INFO + +#define tsp_err(fmt, ...) tsp_printk(DEV_ERR, fmt, ## __VA_ARGS__) +#define tsp_warn(fmt, ...) tsp_printk(DEV_WARN, fmt, ## __VA_ARGS__) +#define tsp_info(fmt, ...) tsp_printk(DEV_INFO, fmt, ## __VA_ARGS__) +#define tsp_notc(fmt, ...) tsp_printk(DEV_NOTICE, fmt, ## __VA_ARGS__) +#define tsp_debug(fmt, ...) tsp_printk(DEV_DEBUG, fmt, ## __VA_ARGS__) +#define tsp_verb(fmt, ...) tsp_printk(DEV_VERB, fmt, ## __VA_ARGS__) + +enum ist30xx_commands { + CMD_ENTER_UPDATE = 0x02, + CMD_EXIT_UPDATE = 0x03, + CMD_UPDATE_SENSOR = 0x04, + CMD_UPDATE_CONFIG = 0x05, + CMD_ENTER_REG_ACCESS = 0x07, + CMD_EXIT_REG_ACCESS = 0x08, + CMD_SET_NOISE_MODE = 0x0A, + CMD_START_SCAN = 0x0B, + CMD_ENTER_FW_UPDATE = 0x0C, + CMD_RUN_DEVICE = 0x0D, + CMD_EXEC_MEM_CODE = 0x0E, + CMD_SET_TEST_MODE = 0x0F, + + CMD_CALIBRATE = 0x11, + CMD_USE_IDLE = 0x12, + CMD_USE_DEBUG = 0x13, + CMD_ZVALUE_MODE = 0x15, + CMD_SAME_POSITION = 0x16, + CMD_CHECK_CALIB = 0x1A, + CMD_SET_TEMPER_MODE = 0x1B, + CMD_USE_CORRECT_CP = 0x1C, + CMD_SET_REPORT_RATE = 0x1D, + CMD_SET_IDLE_TIME = 0x1E, + + CMD_GET_COORD = 0x20, + + CMD_GET_CHIP_ID = 0x30, + CMD_GET_FW_VER = 0x31, + CMD_GET_CHECKSUM = 0x32, + CMD_GET_LCD_RESOLUTION = 0x33, + CMD_GET_TSP_CHNUM1 = 0x34, + CMD_GET_PARAM_VER = 0x35, + CMD_GET_SUB_VER = 0x36, + CMD_GET_CALIB_RESULT = 0x37, + CMD_GET_TSP_SWAP_INFO = 0x38, + CMD_GET_KEY_INFO1 = 0x39, + CMD_GET_KEY_INFO2 = 0x3A, + CMD_GET_KEY_INFO3 = 0x3B, + CMD_GET_TSP_CHNUM2 = 0x3C, + CMD_GET_TSP_DIRECTION = 0x3D, + CMD_GET_TSP_VENDOR = 0x3E, + + CMD_GET_TSP_PANNEL_TYPE = 0x40, + CMD_GET_CHECKSUM_ALL = 0x41, + + CMD_SET_GESTURE_MODE = 0x50, + + CMD_DEFAULT = 0xFF, +}; + +#define CMD_FW_UPDATE_MAGIC (0x85FDAE8A) + +#define IST30XX_INTR_STATUS (0x00000C00) +#define CHECK_INTR_STATUS(n) (((n & IST30XX_INTR_STATUS) \ + == IST30XX_INTR_STATUS) ? 1 : 0) +#define PARSE_FINGER_CNT(n) ((n >> 12) & 0xF) +#define PARSE_KEY_CNT(n) ((n >> 21) & 0x7) +#define PARSE_FINGER_STATUS(n) (n & 0x3FF) /* Finger status: [9:0] */ +#define PARSE_KEY_STATUS(n) ((n >> 16) & 0x1F) /* Key status: [20:16] */ +#define PRESSED_FINGER(s, id) ((s & (1 << (id - 1))) ? true : false) +#define PRESSED_KEY(s, id) ((s & (1 << (16 + id - 1))) ? true : false) + +typedef union { + struct { + u32 y : 12; + u32 x : 12; + u32 area : 4; + u32 id : 4; + } bit_field; + u32 full_field; +} finger_info; + +struct ist30xx_status { + int power; + int update; + int calib; + int calib_msg; +#if IST30XX_CHKIC + int chkic_msg; +#endif + bool event_mode; + bool noise_mode; +}; + +struct ist30xx_fw { + u32 prev_core_ver; + u32 prev_param_ver; + u32 prev_sub_ver; + u32 core_ver; + u32 param_ver; + u32 sub_ver; + u32 index; + u32 size; + u32 chksum; + u32 buf_size; + u8 * buf; +}; + +#define IST30XX_TAG_MAGIC "ISTV1TAG" +struct ist30xx_tags { + char magic1[8]; + u32 fw_addr; + u32 fw_size; + u32 flag_addr; + u32 flag_size; + u32 cfg_addr; + u32 cfg_size; + u32 sensor1_addr; + u32 sensor1_size; + u32 sensor2_addr; + u32 sensor2_size; + u32 sensor3_addr; + u32 sensor3_size; + u32 chksum; + u32 reserved0; + u8 day; + u8 month; + u16 year; + u8 hour; + u8 min; + u8 sec; + u8 reserved1; + char magic2[8]; +}; + +#if SEC_FACTORY_MODE +#include "ist30xx_sec.h" +#endif +#ifdef CONFIG_HAS_EARLYSUSPEND +#include <linux/earlysuspend.h> +#endif +struct ist30xx_data { + struct i2c_client * client; + struct input_dev * input_dev; + struct ist30xx_platform_data * pdata; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + struct ist30xx_status status; + struct ist30xx_fw fw; + struct ist30xx_tags tags; +#if SEC_FACTORY_MODE + struct sec_factory sec; +#endif + u32 chip_id; + u32 tsp_type; + u32 max_fingers; + u32 max_keys; + u32 irq_enabled; + u32 t_status; + finger_info fingers[IST30XX_MAX_MT_FINGERS]; +}; + + +extern struct mutex ist30xx_mutex; +extern int ist30xx_dbg_level; + +void tsp_printk(int level, const char *fmt, ...); +int ist30xx_intr_wait(long ms); + +void ist30xx_enable_irq(struct ist30xx_data *data); +void ist30xx_disable_irq(struct ist30xx_data *data); +void ist30xx_set_ta_mode(bool charging); +void ist30xx_set_cover_mode(int mode); +void ist30xx_start(struct ist30xx_data *data); +int ist30xx_get_ver_info(struct ist30xx_data *data); + +int ist30xx_get_position(struct i2c_client *client, u32 *buf, u16 len); + +int ist30xx_read_cmd(struct i2c_client *client, u32 cmd, u32 *buf); +int ist30xx_write_cmd(struct i2c_client *client, u32 cmd, u32 val); + +int ist30xx_cmd_start_scan(struct i2c_client *client); +int ist30xx_cmd_calibrate(struct i2c_client *client); +int ist30xx_cmd_check_calib(struct i2c_client *client); +int ist30xx_cmd_update(struct i2c_client *client, int cmd); +int ist30xx_cmd_reg(struct i2c_client *client, int cmd); + +int ist30xx_power_on(bool download); +int ist30xx_power_off(void); +int ist30xx_reset(bool download); + +int ist30xx_internal_suspend(struct ist30xx_data *data); +int ist30xx_internal_resume(struct ist30xx_data *data); + +int ist30xx_init_system(void); + +#endif // __IST30XX_H__ diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_chkic_bin.h b/drivers/input/touchscreen/ist30xxa/ist30xx_chkic_bin.h new file mode 100644 index 00000000..d615bf37 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_chkic_bin.h @@ -0,0 +1,53 @@ +
+/* IST3038 Check IC Binary */
+
+unsigned char ist30xxb_chkic[] = {
+ 0x0D, 0x00, 0xA0, 0xE1, 0x10, 0xD0, 0x9F, 0xE5, 0x01, 0x40, 0x2D, 0xE9, 0x4E, 0x00, 0x00, 0xEB,
+ 0x01, 0x40, 0xBD, 0xE8, 0x00, 0xD0, 0xA0, 0xE1, 0x1E, 0xFF, 0x2F, 0xE1, 0xF0, 0x0F, 0x00, 0x20,
+ 0x0C, 0x00, 0x9F, 0xE5, 0x0C, 0x00, 0x90, 0xE5, 0x02, 0x07, 0x10, 0xE2, 0x01, 0x00, 0xA0, 0x13,
+ 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x90, 0x00, 0x40, 0x0C, 0x00, 0x9F, 0xE5, 0x0C, 0x00, 0x90, 0xE5,
+ 0x02, 0x00, 0x10, 0xE2, 0x01, 0x00, 0xA0, 0x13, 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x90, 0x00, 0x40,
+ 0x10, 0x40, 0x2D, 0xE9, 0x58, 0xE0, 0x9F, 0xE5, 0x00, 0x10, 0x9E, 0xE5, 0x54, 0x10, 0x9F, 0xE5,
+ 0x0F, 0xCA, 0xE0, 0xE3, 0x00, 0x10, 0x91, 0xE5, 0x01, 0x30, 0xA0, 0xE3, 0x01, 0x2A, 0xA0, 0xE1,
+ 0x21, 0x18, 0x0C, 0xE0, 0x22, 0x2A, 0xA0, 0xE1, 0x3C, 0xC0, 0x9F, 0xE5, 0x01, 0x40, 0x42, 0xE0,
+ 0x00, 0x10, 0xA0, 0xE3, 0x01, 0x21, 0x9E, 0xE7, 0x0C, 0x00, 0x51, 0xE1, 0xB2, 0x20, 0xC0, 0xE0,
+ 0x01, 0x00, 0x00, 0xAA, 0x04, 0x00, 0x52, 0xE1, 0xFF, 0x30, 0xA0, 0x13, 0x01, 0x10, 0x81, 0xE2,
+ 0x5A, 0x0F, 0x51, 0xE3, 0xF6, 0xFF, 0xFF, 0xDA, 0x10, 0x40, 0xBD, 0xE8, 0x03, 0x00, 0xA0, 0xE1,
+ 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x10, 0x10, 0x40, 0xF4, 0x02, 0x00, 0x20, 0x26, 0x01, 0x00, 0x00,
+ 0x14, 0x10, 0x9F, 0xE5, 0x00, 0x00, 0x50, 0xE3, 0x50, 0x01, 0x91, 0xE5, 0x03, 0x04, 0xC0, 0x03,
+ 0x13, 0x04, 0x80, 0x13, 0x50, 0x01, 0x81, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0xA0, 0x00, 0x40,
+ 0x14, 0x10, 0x9F, 0xE5, 0x00, 0x00, 0x50, 0xE3, 0x00, 0x00, 0x91, 0xE5, 0x02, 0x00, 0xC0, 0x03,
+ 0x02, 0x00, 0x80, 0x13, 0x00, 0x00, 0x81, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x90, 0x00, 0x40,
+ 0x0C, 0x00, 0x9F, 0xE5, 0x0C, 0x10, 0x90, 0xE5, 0x01, 0x00, 0x11, 0xE3, 0xFC, 0xFF, 0xFF, 0x0A,
+ 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x90, 0x00, 0x40, 0x0C, 0x00, 0x9F, 0xE5, 0xF8, 0x10, 0x90, 0xE5,
+ 0x0A, 0x18, 0x81, 0xE3, 0xF8, 0x10, 0x80, 0xE5, 0x1E, 0xFF, 0x2F, 0xE1, 0x00, 0x90, 0x00, 0x40,
+ 0x41, 0x11, 0xA0, 0xE1, 0x00, 0x20, 0xA0, 0xE3, 0x01, 0x10, 0x41, 0xE2, 0x01, 0x00, 0x71, 0xE3,
+ 0x04, 0x20, 0x80, 0x14, 0xFB, 0xFF, 0xFF, 0x1A, 0x1E, 0xFF, 0x2F, 0xE1, 0xF0, 0x43, 0x2D, 0xE9,
+ 0xF0, 0x60, 0x9F, 0xE5, 0xE9, 0xFF, 0xFF, 0xEB, 0xEC, 0x10, 0x9F, 0xE5, 0xEC, 0x00, 0x9F, 0xE5,
+ 0xF2, 0xFF, 0xFF, 0xEB, 0xE8, 0x10, 0x9F, 0xE5, 0x03, 0x04, 0xA0, 0xE3, 0x50, 0x01, 0x81, 0xE5,
+ 0x55, 0x0F, 0x81, 0xE2, 0x00, 0x10, 0xA0, 0xE3, 0x01, 0x80, 0xA0, 0xE1, 0x01, 0x10, 0x81, 0xE2,
+ 0x07, 0x00, 0x51, 0xE3, 0x04, 0x80, 0x80, 0xE4, 0xFB, 0xFF, 0xFF, 0xBA, 0xC4, 0x00, 0x9F, 0xE5,
+ 0xC4, 0x70, 0x9F, 0xE5, 0xCC, 0x00, 0x87, 0xE5, 0x41, 0x07, 0xA0, 0xE3, 0xE8, 0x00, 0x87, 0xE5,
+ 0xF0, 0x80, 0x87, 0xE5, 0x01, 0x40, 0xA0, 0xE3, 0xB0, 0x50, 0x9F, 0xE5, 0x04, 0x96, 0x64, 0xE0,
+ 0x01, 0x00, 0x00, 0xEA, 0x01, 0x00, 0x54, 0xE3, 0x01, 0x00, 0x00, 0x1A, 0x00, 0x90, 0x85, 0xE5,
+ 0x03, 0x00, 0x00, 0xEA, 0x02, 0x00, 0x54, 0xE3, 0x94, 0x00, 0x9F, 0x15, 0x00, 0x00, 0x85, 0x15,
+ 0x00, 0x80, 0x85, 0x05, 0x00, 0x00, 0xA0, 0xE3, 0x00, 0x10, 0x95, 0xE5, 0x00, 0x11, 0x86, 0xE7,
+ 0x01, 0x00, 0x80, 0xE2, 0x5A, 0x0F, 0x50, 0xE3, 0xFA, 0xFF, 0xFF, 0xDA, 0x3A, 0x00, 0x00, 0xEB,
+ 0x8A, 0xFF, 0xFF, 0xEB, 0x00, 0x00, 0x50, 0xE3, 0xFC, 0xFF, 0xFF, 0x0A, 0x0C, 0x00, 0x97, 0xE5,
+ 0x0C, 0x00, 0x87, 0xE5, 0xC3, 0xFF, 0xFF, 0xEB, 0x8A, 0xFF, 0xFF, 0xEB, 0x00, 0x00, 0x50, 0xE3,
+ 0xFC, 0xFF, 0xFF, 0x0A, 0x0C, 0x00, 0x97, 0xE5, 0x0C, 0x00, 0x87, 0xE5, 0xB5, 0x00, 0xA0, 0xE3,
+ 0x94, 0x00, 0x00, 0xE0, 0x24, 0x10, 0x9F, 0xE5, 0x00, 0x01, 0x81, 0xE0, 0xB5, 0x0F, 0x40, 0xE2,
+ 0x86, 0xFF, 0xFF, 0xEB, 0x01, 0x40, 0x84, 0xE2, 0x04, 0x00, 0x54, 0xE3, 0xDC, 0xFF, 0xFF, 0xBA,
+ 0xF0, 0x43, 0xBD, 0xE8, 0x07, 0x00, 0x00, 0xEA, 0xD4, 0x02, 0x10, 0x40, 0x7C, 0x08, 0x00, 0x00,
+ 0xF8, 0x02, 0x00, 0x20, 0x00, 0xA0, 0x00, 0x40, 0x03, 0x22, 0x01, 0x00, 0x00, 0x90, 0x00, 0x40,
+ 0xF4, 0x02, 0x00, 0x20, 0xFF, 0x0F, 0x00, 0xF4, 0x09, 0x28, 0xA0, 0xE3, 0x02, 0x10, 0xB0, 0xE1,
+ 0x01, 0x20, 0x42, 0xE2, 0xFC, 0xFF, 0xFF, 0x1A, 0x48, 0x20, 0x9F, 0xE5, 0x48, 0x10, 0x9F, 0xE5,
+ 0x1C, 0x20, 0x81, 0xE5, 0x1C, 0x00, 0x81, 0xE5, 0x40, 0x00, 0x9F, 0xE5, 0x0C, 0x20, 0x90, 0xE5,
+ 0x01, 0x20, 0xC2, 0xE3, 0x0C, 0x20, 0x80, 0xE5, 0x34, 0xC0, 0x9F, 0xE5, 0x34, 0x30, 0x9F, 0xE5,
+ 0x00, 0x00, 0xA0, 0xE3, 0x00, 0x21, 0x9C, 0xE7, 0x1C, 0x20, 0x81, 0xE5, 0x14, 0x20, 0x91, 0xE5,
+ 0x40, 0x00, 0x12, 0xE3, 0xFC, 0xFF, 0xFF, 0x1A, 0x01, 0x00, 0x80, 0xE2, 0x03, 0x00, 0x50, 0xE1,
+ 0xF7, 0xFF, 0xFF, 0xBA, 0xFE, 0xFF, 0xFF, 0xEA, 0xAB, 0x0F, 0xAB, 0x8F, 0x00, 0x40, 0x00, 0x30,
+ 0x00, 0x20, 0x00, 0x40, 0xF8, 0x02, 0x00, 0x20, 0x1F, 0x02, 0x00, 0x00, 0x01, 0x00, 0xA0, 0xE3,
+ 0x04, 0xE0, 0x2D, 0xE5, 0x7D, 0xFF, 0xFF, 0xEB, 0x04, 0xE0, 0x9D, 0xE4, 0x01, 0x00, 0xA0, 0xE3,
+ 0x72, 0xFF, 0xFF, 0xEA, 0x54, 0x29, 0xB5, 0xCB
+};
diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs.c b/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs.c new file mode 100644 index 00000000..0b39b20f --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs.c @@ -0,0 +1,1345 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/firmware.h> +#include <linux/stat.h> +#include <linux/uaccess.h> +#include <linux/fcntl.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/err.h> + +#include "ist30xx.h" +#include "ist30xx_update.h" +#include "ist30xx_misc.h" +#include "ist30xx_cmcs.h" + +#if IST30XX_INTERNAL_CMCS_BIN +#include "ist30xx_cmcs_bin.h" +#endif + +#define CMCS_PARSING_DEBUG (0) + +#define CMCS_READY (0) +#define CMCS_NOT_READY (-1) + +#define TSP_CH_UNUSED (0) +#define TSP_CH_SCREEN (1) +#define TSP_CH_KEY (2) +#define TSP_CH_UNKNOWN (-1) + +extern struct ist30xx_data *ts_data; + +int cmcs_ready = CMCS_READY; +u8 *ts_cmcs_bin = NULL; +u32 ts_cmcs_bin_size = 0; +CMCS_BIN_INFO ist30xx_cmcs_bin; +CMCS_BIN_INFO *ts_cmcs = (CMCS_BIN_INFO *)&ist30xx_cmcs_bin; +CMCS_BUF ist30xx_cmcs_buf; +CMCS_BUF *ts_cmcs_buf = (CMCS_BUF *)&ist30xx_cmcs_buf; + + +int ist30xx_parse_cmcs_bin(const u8 *buf, const u32 size) +{ + int ret = -EPERM; + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + memcpy(ts_cmcs->magic1, buf, sizeof(ts_cmcs->magic1)); + memcpy(ts_cmcs->magic2, &buf[size - sizeof(ts_cmcs->magic2)], + sizeof(ts_cmcs->magic2)); + memcpy(cmcs, &buf[sizeof(ts_cmcs->magic1)], sizeof(ts_cmcs->cmcs)); + + if (!strncmp(ts_cmcs->magic1, IST30XX_CMCS_MAGIC, sizeof(ts_cmcs->magic1)) + && !strncmp(ts_cmcs->magic2, IST30XX_CMCS_MAGIC, + sizeof(ts_cmcs->magic2))) { + int idx; + + idx = sizeof(ts_cmcs->magic1) + sizeof(ts_cmcs->cmcs); + ts_cmcs->buf_cmcs = (u8 *)&buf[idx]; + + idx += cmcs->cmd.cmcs_size; + ts_cmcs->buf_sensor = (u32 *)&buf[idx]; + + idx += (cmcs->sensor1_size + cmcs->sensor2_size + cmcs->sensor3_size); + ts_cmcs->buf_node = (u16 *)&buf[idx]; + + ret = 0; + } + + tsp_verb("Magic1: %s, Magic2: %s\n", ts_cmcs->magic1, ts_cmcs->magic2); + tsp_verb(" mode: 0x%x, base(screen: %d, key: %d)\n", + cmcs->cmd.mode, cmcs->cmd.base_screen, cmcs->cmd.base_key); + tsp_verb(" start_cp (cm: %d, cs: %d), vcmp (cm: %d, cs: %d)\n", + cmcs->cmd.start_cp_cm, cmcs->cmd.start_cp_cs, + cmcs->cmd.vcmp_cm, cmcs->cmd.vcmp_cs); + tsp_verb(" timeout: %d\n", cmcs->timeout); + tsp_verb(" baseline scrn: 0x%08x, key: 0x%08x\n", + cmcs->addr.base_screen, cmcs->addr.base_key); + tsp_verb(" start_cp: 0x%08x, vcmp: 0x%08x\n", + cmcs->addr.start_cp, cmcs->addr.vcmp); + tsp_verb(" sensor 1: 0x%08x, 2: 0x%08x, 3: 0x%08x\n", + cmcs->addr.sensor1, cmcs->addr.sensor2, cmcs->addr.sensor3); + tsp_verb(" tx: %d, rx:%d, key rx: %d, num(%d, %d, %d, %d, %d)\n", + cmcs->ch.tx_num, cmcs->ch.rx_num, cmcs->ch.key_rx, cmcs->ch.key1, + cmcs->ch.key2, cmcs->ch.key3, cmcs->ch.key4, cmcs->ch.key5); + tsp_verb(" cr: screen(%4d, %4d), key(%4d, %4d)\n", + cmcs->spec_cr.screen_min, cmcs->spec_cr.screen_max, + cmcs->spec_cr.key_min, cmcs->spec_cr.key_max); + tsp_verb(" cm: screen(%4d, %4d), key(%4d, %4d)\n", + cmcs->spec_cm.screen_min, cmcs->spec_cm.screen_max, + cmcs->spec_cm.key_min, cmcs->spec_cm.key_max); + tsp_verb(" cs0: screen(%4d, %4d), key(%4d, %4d)\n", + cmcs->spec_cs0.screen_min, cmcs->spec_cs0.screen_max, + cmcs->spec_cs0.key_min, cmcs->spec_cs0.key_max); + tsp_verb(" cs1: screen(%4d, %4d), key(%4d, %4d)\n", + cmcs->spec_cs1.screen_min, cmcs->spec_cs1.screen_max, + cmcs->spec_cs1.key_min, cmcs->spec_cs1.key_max); + tsp_verb(" slope - x(%d, %d), y(%d, %d), key(%d, %d)\n", + cmcs->slope.x_min, cmcs->slope.x_max, + cmcs->slope.y_min, cmcs->slope.y_max, + cmcs->slope.key_min, cmcs->slope.key_max); + tsp_verb(" size - cmcs(%d), sensor(%d, %d, %d)\n", + cmcs->cmd.cmcs_size, cmcs->sensor1_size, + cmcs->sensor2_size, cmcs->sensor3_size); + tsp_verb(" checksum - cmcs: 0x%08x, sensor: 0x%08x\n", + cmcs->cmcs_chksum, cmcs->sensor_chksum); + tsp_verb(" cmcs: %x, %x, %x, %x\n", ts_cmcs->buf_cmcs[0], + ts_cmcs->buf_cmcs[1], ts_cmcs->buf_cmcs[2], ts_cmcs->buf_cmcs[3]); + tsp_verb(" sensor: %x, %x, %x, %x\n", + ts_cmcs->buf_sensor[0], ts_cmcs->buf_sensor[1], + ts_cmcs->buf_sensor[2], ts_cmcs->buf_sensor[3]); + tsp_verb(" node: %x, %x, %x, %x\n", + ts_cmcs->buf_node[0], ts_cmcs->buf_node[1], + ts_cmcs->buf_node[2], ts_cmcs->buf_node[3]); + + return ret; +} + +int ist30xx_get_cmcs_info(const u8 *buf, const u32 size) +{ + int ret; + + cmcs_ready = CMCS_NOT_READY; + + ret = ist30xx_parse_cmcs_bin(buf, size); + if (unlikely(ret != TAGS_PARSE_OK)) + tsp_warn("Cannot find tags of CMCS, make a bin by 'cmcs2bin.exe'\n"); + + return ret; +} + +int ist30xx_set_cmcs_sensor(struct i2c_client *client, CMCS_INFO *cmcs, + u32 *buf32) +{ + int i, ret; + int len; + u32 waddr; + u32 *tmp32; + + tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); + + waddr = cmcs->addr.sensor1; + len = cmcs->sensor1_size / IST30XX_DATA_LEN; + + for (i = 0; i < len; i++) { + ret = ist30xx_write_cmd(client, waddr, *buf32++); + if (ret) + return ret; + + waddr += IST30XX_DATA_LEN; + } + + tmp32 = buf32; + tsp_verb("%08x %08x %08x %08x\n", tmp32[0], tmp32[1], tmp32[2], tmp32[3]); + + waddr = cmcs->addr.sensor2; + len = (cmcs->sensor2_size - 0x10) / IST30XX_DATA_LEN; + + for (i = 0; i < len; i++) { + ret = ist30xx_write_cmd(client, waddr, *buf32++); + if (ret) + return ret; + + waddr += IST30XX_DATA_LEN; + } + buf32 += (0x10 / IST30XX_DATA_LEN); + + tmp32 = buf32; + tsp_verb("%08x %08x %08x %08x\n", tmp32[0], tmp32[1], tmp32[2], tmp32[3]); + + waddr = cmcs->addr.sensor3; + len = cmcs->sensor3_size / IST30XX_DATA_LEN; + + for (i = 0; i < len; i++) { + ret = ist30xx_write_cmd(client, waddr, *buf32++); + if (ret) + return ret; + + waddr += IST30XX_DATA_LEN; + } + + return 0; +} + +int ist30xx_set_cmcs_cmd(struct i2c_client *client, CMCS_INFO *cmcs) +{ + int ret; + u32 val; + + val = (u32)(cmcs->cmd.base_screen | (cmcs->cmd.mode << 16)); + ret = ist30xx_write_cmd(client, cmcs->addr.base_screen, val); + if (ret) + return ret; + tsp_verb("Baseline screen(0x%08x): 0x%08x\n", cmcs->addr.base_screen, val); + + val = (u32)cmcs->cmd.base_key; + ret = ist30xx_write_cmd(client, cmcs->addr.base_key, val); + if (ret) + return ret; + tsp_verb("Baseline key(0x%08x): 0x%08x\n", cmcs->addr.base_key, val); + + val = cmcs->cmd.start_cp_cm | (cmcs->cmd.start_cp_cs << 16); + ret = ist30xx_write_cmd(client, cmcs->addr.start_cp, val); + if (ret) + return ret; + tsp_verb("StartCP(0x%08x): 0x%08x\n", cmcs->addr.start_cp, val); + + val = cmcs->cmd.vcmp_cm | (cmcs->cmd.vcmp_cs << 16); + ret = ist30xx_write_cmd(client, cmcs->addr.vcmp, val); + if (ret) + return ret; + tsp_verb("VCMP(0x%08x): 0x%08x\n", cmcs->addr.vcmp, val); + + return 0; +} + +int ist30xx_parse_cmcs_buf(CMCS_INFO *cmcs, s16 *buf) +{ + int i, j; + + tsp_info(" %d * %d\n", cmcs->ch.tx_num, cmcs->ch.rx_num); + for (i = 0; i < cmcs->ch.tx_num; i++) { + tsp_info(" "); + for (j = 0; j < cmcs->ch.rx_num; j++) + printk("%5d ", buf[i * cmcs->ch.rx_num + j]); + printk("\n"); + } + + return 0; +} + +int ist30xx_apply_cmcs_slope(CMCS_INFO *cmcs, CMCS_BUF *cmcs_buf) +{ + int i, j; + int idx1, idx2; + int ch_num = cmcs->ch.tx_num * cmcs->ch.rx_num; + int width = cmcs->ch.rx_num; + int height = cmcs->ch.tx_num; + s16 *pcm = (s16 *)cmcs_buf->cm; + s16 *pspec = (s16 *)cmcs_buf->spec; + s16 *pslope0 = (s16 *)cmcs_buf->slope0; + s16 *pslope1 = (s16 *)cmcs_buf->slope1; + + if (cmcs->ch.key_rx) + width -= 1; + else + height -= 1; + + memset(cmcs_buf->slope0, 0, sizeof(cmcs_buf->slope0)); + memset(cmcs_buf->slope1, 0, sizeof(cmcs_buf->slope1)); + + memcpy(cmcs_buf->spec, ts_cmcs->buf_node, (ch_num * sizeof(u16))); + + idx1 = 0; +#if CMCS_PARSING_DEBUG + tsp_info("# Node specific\n"); + for (i = 0; i < cmcs->ch.tx_num; i++) { + tsp_info(" "); + for (j = 0; j < cmcs->ch.rx_num; j++) + printk("%5d ", cmcs_buf->spec[idx1++]); + printk("\n"); + } +#endif + + tsp_verb("# Apply slope0_x\n"); + for (i = 0; i < height; i++) { + for (j = 0; j < width - 1; j++) { + idx1 = (i * cmcs->ch.rx_num) + j; + idx2 = idx1 + 1; + + pslope0[idx1] = (pcm[idx2] - pcm[idx1]); + pslope0[idx1] += (pspec[idx1] - pspec[idx2]); + } + } + + tsp_verb("# Apply slope1_y\n"); + for (i = 0; i < height - 1; i++) { + for (j = 0; j < width; j++) { + idx1 = (i * cmcs->ch.rx_num) + j; + idx2 = idx1 + cmcs->ch.rx_num; + + pslope1[idx1] = (pcm[idx2] - pcm[idx1]); + pslope1[idx1] += (pspec[idx1] - pspec[idx2]); + } + } + +#if CMCS_PARSING_DEBUG + tsp_info("# slope0_x\n"); + for (i = 0; i < height; i++) { + tsp_info(" "); + for (j = 0; j < width; j++) { + idx1 = (i * cmcs->ch.rx_num) + j; + printk("%5d ", pslope0[idx1]); + } + printk("\n"); + } + + tsp_info("# slope1_y\n"); + for (i = 0; i < height; i++) { + tsp_info(" "); + for (j = 0; j < width; j++) { + idx1 = (i * cmcs->ch.rx_num) + j; + printk("%5d ", pslope1[idx1]); + } + printk("\n"); + } +#endif + + return 0; +} + + +int ist30xx_get_cmcs_buf(struct i2c_client *client, CMCS_INFO *cmcs, s16 *buf) +{ + int ret; + u16 len = (IST30XX_CMCS_BUF_SIZE * sizeof(buf[0])) / IST30XX_DATA_LEN; + + ret = ist30xx_read_buf(client, CMD_DEFAULT, (u32 *)buf, len); + if (unlikely(ret)) + return ret; + +#if CMCS_PARSING_DEBUG + ret = ist30xx_parse_cmcs_buf(cmcs, buf); +#endif + + return ret; +} + + +extern int ist30xx_calib_wait(void); +#define cmcs_next_step(ret) { if (unlikely(ret)) goto end; msleep(10); } +int ist30xx_cmcs_test(const u8 *buf, int size) +{ + int ret; + int len; + u32 chksum = 0; + u32 *buf32; + struct i2c_client *client = (struct i2c_client *)ts_data->client; + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + tsp_info("*** CM/CS test ***\n"); + tsp_info(" mode: 0x%x, baseline(screen: %d, key: %d)\n", + cmcs->cmd.mode, cmcs->cmd.base_screen, cmcs->cmd.base_key); + tsp_info(" start_cp (cm: %d, cs: %d), vcmp (cm: %d, cs: %d)\n", + cmcs->cmd.start_cp_cm, cmcs->cmd.start_cp_cs, + cmcs->cmd.vcmp_cm, cmcs->cmd.vcmp_cs); + + ist30xx_disable_irq(ts_data); + + ist30xx_reset(false); + + ret = ist30xx_cmd_reg(client, CMD_ENTER_REG_ACCESS); + cmcs_next_step(ret); + + /* Set sensor register */ + buf32 = ts_cmcs->buf_sensor; + ret = ist30xx_set_cmcs_sensor(client, cmcs, buf32); + cmcs_next_step(ret); + + /* Set command */ + ret = ist30xx_set_cmcs_cmd(client, cmcs); + cmcs_next_step(ret); + + ret = ist30xx_cmd_reg(client, CMD_EXIT_REG_ACCESS); + cmcs_next_step(ret); + + /* Load cmcs test code */ + ret = ist30xx_write_cmd(client, CMD_EXEC_MEM_CODE, 0); + cmcs_next_step(ret); + + buf32 = (u32 *)ts_cmcs->buf_cmcs; + len = cmcs->cmd.cmcs_size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); + ret = ist30xx_write_buf(client, len, buf32, len); + cmcs_next_step(ret); + + /* Check checksum */ + ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); + cmcs_next_step(ret); + if (chksum != IST30XX_CMCS_LOAD_END) + goto end; + tsp_info("CM/CS code ready!!\n"); + + /* Check checksum */ + ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); + cmcs_next_step(ret); + tsp_info("CM/CS code chksum: %08x, %08x\n", chksum, cmcs->cmcs_chksum); + + ist30xx_enable_irq(ts_data); + /* Wait CMCS test result */ + if (ist30xx_calib_wait() == 1) + tsp_info("CM/CS test OK.\n"); + else + tsp_info("CM/CS test fail.\n"); + ist30xx_disable_irq(ts_data); + + /* Read CM/CS data*/ + if (ENABLE_CM_MODE(cmcs->cmd.mode)) { + /* Read CM data */ + memset(ts_cmcs_buf->cm, 0, sizeof(ts_cmcs_buf->cm)); + + ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cm); + cmcs_next_step(ret); + + ret = ist30xx_apply_cmcs_slope(cmcs, ts_cmcs_buf); + } + + if (ENABLE_CS_MODE(cmcs->cmd.mode)) { + /* Read CS0 data */ + memset(ts_cmcs_buf->cs0, 0, sizeof(ts_cmcs_buf->cs0)); + memset(ts_cmcs_buf->cs1, 0, sizeof(ts_cmcs_buf->cs1)); + + ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cs0); + cmcs_next_step(ret); + + /* Read CS1 data */ + ret = ist30xx_get_cmcs_buf(client, cmcs, ts_cmcs_buf->cs1); + cmcs_next_step(ret); + } + + ist30xx_reset(false); + + ist30xx_start(ts_data); + + cmcs_ready = CMCS_READY; + +end: + if (unlikely(ret)) { + tsp_warn("CM/CS test Fail!, ret=%d\n", ret); + } else if (unlikely(chksum != cmcs->cmcs_chksum)) { + tsp_warn("Error CheckSum: %x(%x)\n", chksum, cmcs->cmcs_chksum); + ret = -ENOEXEC; + } + + ist30xx_enable_irq(ts_data); + + return ret; +} + + +int check_tsp_type(int tx, int rx) +{ + struct CMCS_CH_INFO *ch = (struct CMCS_CH_INFO *)&ts_cmcs->cmcs.ch; + + int last_rx_ch = (int)ch->rx_num - 1; + int last_tx_ch = (int)ch->tx_num - 1; + + if ((rx > last_rx_ch) || (rx < 0) || (tx > last_tx_ch) || (tx < 0)) { + tsp_warn("TSP channel is not correct!! (%d * %d)\n", tx, rx); + return TSP_CH_UNKNOWN; + } + + if (ch->key_rx) { // Key on RX channel + if (rx == last_rx_ch) { + if ((tx == ch->key1) || (tx == ch->key2) || (tx == ch->key3) || + (tx == ch->key4) || (tx == ch->key5)) + return TSP_CH_KEY; + else + return TSP_CH_UNUSED; + } + } // Key on TX channel + else { + if (tx == last_tx_ch) { + if ((rx == ch->key1) || (rx == ch->key2) || (rx == ch->key3) || + (rx == ch->key4) || (rx == ch->key5)) + return TSP_CH_KEY; + else + return TSP_CH_UNUSED; + } + } + + return TSP_CH_SCREEN; +} + +int print_cmcs(s16 *buf16, char *buf) +{ + int i, j; + int idx; + int count = 0; + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + int tx_num = cmcs->ch.tx_num; + int rx_num = cmcs->ch.rx_num; + + for (i = 0; i < tx_num; i++) { + for (j = 0; j < rx_num; j++) { + idx = (i * cmcs->ch.rx_num) + j; + count += sprintf(msg, "%5d ", buf16[idx]); + strcat(buf, msg); + } + + count += sprintf(msg, "\n"); + strcat(buf, msg); + } + + return count; +} + +int print_line_cmcs(int mode, s16 *buf16, char *buf) +{ + int i, j; + int idx; + int type; + int count = 0; + int key_index[5] = { 0, }; + int key_cnt = 0; + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + int tx_num = cmcs->ch.tx_num; + int rx_num = cmcs->ch.rx_num; + + if ((mode == CMCS_FLAG_CM_SLOPE0) || (mode == CMCS_FLAG_CM_SLOPE1)) { + if (cmcs->ch.key_rx) + rx_num--; + else + tx_num--; + } + + for (i = 0; i < tx_num; i++) { + for (j = 0; j < rx_num; j++) { + type = check_tsp_type(i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; // Ignore + + if ((mode == CMCS_FLAG_CM_SLOPE0) && (j == (rx_num - 1))) + continue; + else if ((mode == CMCS_FLAG_CM_SLOPE1) && (i == (tx_num - 1))) + continue; + + idx = (i * cmcs->ch.rx_num) + j; + + if (type == TSP_CH_KEY) { + key_index[key_cnt++] = idx; + continue; + } + + count += sprintf(msg, "%5d ", buf16[idx]); + strcat(buf, msg); + } + } + + tsp_info("key cnt: %d\n", key_cnt); + if ((mode != CMCS_FLAG_CM_SLOPE0) && (mode != CMCS_FLAG_CM_SLOPE1)) { + tsp_info("key cnt: %d\n", key_cnt); + for (i = 0; i < key_cnt; i++) { + count += sprintf(msg, "%5d ", buf16[key_index[i]]); + strcat(buf, msg); + } + } + + count += sprintf(msg, "\n"); + strcat(buf, msg); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/info */ +ssize_t ist30xx_cmcs_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count; + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if (cmcs == NULL) + return sprintf(buf, "Unknown cmcs bin\n"); + + /* Mode */ + count = sprintf(msg, "%d ", cmcs->cmd.mode); + strcat(buf, msg); + + /* Channel */ + count += sprintf(msg, "%d %d %d %d %d %d %d %d ", + cmcs->ch.tx_num, cmcs->ch.rx_num, cmcs->ch.key_rx, cmcs->ch.key1, + cmcs->ch.key2, cmcs->ch.key3, cmcs->ch.key4, cmcs->ch.key5); + strcat(buf, msg); + + /* Slope */ + count += sprintf(msg, "%d %d %d %d %d %d", + cmcs->slope.x_min, cmcs->slope.x_max, + cmcs->slope.y_min, cmcs->slope.y_max, + cmcs->slope.key_min, cmcs->slope.key_max); + strcat(buf, msg); + + /* CM */ + count += sprintf(msg, "%d %d %d %d ", + cmcs->spec_cm.screen_min, cmcs->spec_cm.screen_max, + cmcs->spec_cm.key_min, cmcs->spec_cm.key_max); + strcat(buf, msg); + + /* CS0 */ + count += sprintf(msg, "%d %d %d %d ", + cmcs->spec_cs0.screen_min, cmcs->spec_cs0.screen_max, + cmcs->spec_cs0.key_min, cmcs->spec_cs0.key_max); + strcat(buf, msg); + + /* CS1 */ + count += sprintf(msg, "%d %d %d %d ", + cmcs->spec_cs1.screen_min, cmcs->spec_cs1.screen_max, + cmcs->spec_cs1.key_min, cmcs->spec_cs1.key_max); + strcat(buf, msg); + + /* CR */ + count += sprintf(msg, "%d %d %d %d ", + cmcs->spec_cr.screen_min, cmcs->spec_cr.screen_max, + cmcs->spec_cr.key_min, cmcs->spec_cr.key_max); + strcat(buf, msg); + + tsp_verb("%s\n", buf); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/cmcs_binary */ +ssize_t ist30xx_cmcs_binary_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + if ((ts_cmcs_bin == NULL) || (ts_cmcs_bin_size == 0)) + return sprintf(buf, "Binary is not correct(%d)\n", ts_cmcs_bin_size); + + ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_cmcs_test(ts_cmcs_bin, ts_cmcs_bin_size); + mutex_unlock(&ist30xx_mutex); + + return sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n")); +} + +/* sysfs: /sys/class/touch/cmcs/cmcs_custom */ +ssize_t ist30xx_cmcs_custom_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + int bin_size = 0; + u8 *bin = NULL; + const struct firmware *req_bin = NULL; + + ret = request_firmware(&req_bin, IST30XXB_CMCS_NAME, &ts_data->client->dev); + if (ret) + return sprintf(buf, "File not found, %s\n", IST30XXB_CMCS_NAME); + + bin = (u8 *)req_bin->data; + bin_size = (u32)req_bin->size; + + ist30xx_get_cmcs_info(bin, bin_size); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_cmcs_test(bin, bin_size); + mutex_unlock(&ist30xx_mutex); + + release_firmware(req_bin); + + tsp_info("size: %d\n", sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n"))); + + return sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n")); +} + +#define MAX_FILE_PATH 255 +/* sysfs: /sys/class/touch/cmcs/cmcs_sdcard */ +ssize_t ist30xx_cmcs_sdcard_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + int bin_size = 0; + u8 *bin = NULL; + const u8 *buff = 0; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + long fsize = 0, nread = 0; + char fw_path[MAX_FILE_PATH]; + + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/touch/firmware/%s", + IST30XXB_CMCS_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + tsp_info("file %s open error:%d\n", fw_path, (s32)fp); + ret = -ENOENT; + goto err_file_open; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + + buff = kzalloc((size_t)fsize, GFP_KERNEL); + if (!buff) { + tsp_info("fail to alloc buffer\n"); + ret = -ENOMEM; + goto err_alloc; + } + + nread = vfs_read(fp, (char __user *)buff, fsize, &fp->f_pos); + if (nread != fsize) { + tsp_info("mismatch fw size\n"); + + goto err_fw_size; + } + + bin = (u8 *)buff; + bin_size = (u32)fsize; + + filp_close(fp, current->files); + set_fs(old_fs); + tsp_info("firmware is loaded!!\n"); + + ist30xx_get_cmcs_info(bin, bin_size); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_cmcs_test(bin, bin_size); + mutex_unlock(&ist30xx_mutex); + + kfree(buff); + + tsp_info("size: %d\n", sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n"))); + + return sprintf(buf, (ret == 0 ? "OK\n" : "Fail\n")); + +err_fw_size: + if (buff) + kfree(buff); +err_alloc: + if (fp) + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + + return 0; +} + +/* sysfs: /sys/class/touch/cmcs/cm */ +ssize_t ist30xx_cm_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + tsp_verb("CM (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); + + return print_cmcs(ts_cmcs_buf->cm, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_spec */ +ssize_t ist30xx_cm_spec_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + tsp_verb("CM Spec (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); + + return print_cmcs(ts_cmcs_buf->spec, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope0 */ +ssize_t ist30xx_cm_slope0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + tsp_verb("CM Slope0_X (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); + + return print_cmcs(ts_cmcs_buf->slope0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope1 */ +ssize_t ist30xx_cm_slope1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + tsp_verb("CM Slope1_Y (%d * %d)\n", + ts_cmcs->cmcs.ch.tx_num, ts_cmcs->cmcs.ch.rx_num); + + return print_cmcs(ts_cmcs_buf->slope1, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cs0 */ +ssize_t ist30xx_cs0_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) + return 0; + + tsp_verb("CS0 (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); + + return print_cmcs(ts_cmcs_buf->cs0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cs1 */ +ssize_t ist30xx_cs1_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) + return 0; + + tsp_verb("CS1 (%d * %d)\n", cmcs->ch.tx_num, cmcs->ch.rx_num); + + return print_cmcs(ts_cmcs_buf->cs1, buf); +} + + +int print_cm_slope_result(u8 flag, s16 *buf16, char *buf) +{ + int i, j; + int type, idx; + int count = 0, err_cnt = 0; + int min_spec, max_spec; + + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + struct CMCS_SLOPE_INFO *spec = (struct CMCS_SLOPE_INFO *)&cmcs->slope; + + if (flag == CMCS_FLAG_CM_SLOPE0) { + min_spec = spec->x_min; + max_spec = spec->x_max; + } else if (flag == CMCS_FLAG_CM_SLOPE1) { + min_spec = spec->y_min; + max_spec = spec->y_max; + } else { + count = sprintf(msg, "Unknown flag: %d\n", flag); + strcat(buf, msg); + return count; + } + + min_spec *= -1; + + count = sprintf(msg, "Spec: %d ~ %d\n", min_spec, max_spec); + strcat(buf, msg); + + for (i = 0; i < cmcs->ch.tx_num; i++) { + for (j = 0; j < cmcs->ch.rx_num; j++) { + idx = (i * cmcs->ch.rx_num) + j; + + type = check_tsp_type(i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; // Ignore + + if ((buf16[idx] > min_spec) && (buf16[idx] < max_spec)) + continue; // OK + + count += sprintf(msg, "%2d,%2d:%4d\n", i, j, buf16[idx]); + strcat(buf, msg); + + err_cnt++; + } + } + + /* Check error count */ + if (err_cnt == 0) + count += sprintf(msg, "OK\n"); + else + count += sprintf(msg, "Fail, node count: %d\n", err_cnt); + strcat(buf, msg); + + return count; +} + +int print_cm_key_slope_result(s16 *buf16, char *buf, bool print) +{ + int i, j; + int type, idx; + int count = 0; + int min_spec, max_spec; + int key_num = 0; + s16 key_cm[5] = { 0, }; + s16 slope_result; + + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + struct CMCS_SLOPE_INFO *spec = (struct CMCS_SLOPE_INFO *)&cmcs->slope; + + min_spec = spec->key_min; + max_spec = spec->key_max; + + min_spec *= -1; + if (print) { + count = sprintf(msg, "Spec: %d ~ %d\n", min_spec, max_spec); + strcat(buf, msg); + } + + for (i = 0; i < cmcs->ch.tx_num; i++) { + for (j = 0; j < cmcs->ch.rx_num; j++) { + idx = (i * cmcs->ch.rx_num) + j; + + type = check_tsp_type(i, j); + if (type == TSP_CH_KEY) + key_cm[key_num++] = buf16[idx]; + } + } + + /* Check key slope */ + slope_result = key_cm[0] - key_cm[1]; + + if (print) { + if ((slope_result > min_spec) && (slope_result < max_spec)) + count += sprintf(msg, "OK (%d)\n", slope_result); + else + count += sprintf(msg, "Fail (%d)\n", slope_result); + } else { + count += sprintf(msg, "%d\n", + (slope_result > 0 ? slope_result : -slope_result)); + } + + strcat(buf, msg); + + return count; +} + +int print_cs_result(s16 *buf16, char *buf, int cs_num) +{ + int i, j; + int type, idx; + int count = 0, err_cnt = 0; + int min_spec, max_spec; + + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + struct CMCS_SPEC_INFO *spec; + + if (cs_num == 0) + spec = (struct CMCS_SPEC_INFO *)&cmcs->spec_cs0; + else + spec = (struct CMCS_SPEC_INFO *)&cmcs->spec_cs1; + + count = sprintf(msg, "Spec: screen(%d~%d), key(%d~%d)\n", + spec->screen_min, spec->screen_max, spec->key_min, spec->key_max); + strcat(buf, msg); + + for (i = 0; i < cmcs->ch.tx_num; i++) { + for (j = 0; j < cmcs->ch.rx_num; j++) { + idx = (i * cmcs->ch.rx_num) + j; + + type = check_tsp_type(i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; // Ignore + + if (type == TSP_CH_SCREEN) { + min_spec = spec->screen_min; + max_spec = spec->screen_max; + } else { // TSP_CH_KEY + min_spec = spec->key_min; + max_spec = spec->key_max; + } + + if ((buf16[idx] > min_spec) && (buf16[idx] < max_spec)) + continue; // OK + + count += sprintf(msg, "%2d,%2d:%4d\n", i, j, buf16[idx]); + strcat(buf, msg); + + err_cnt++; + } + } + + /* Check error count */ + if (err_cnt == 0) + count += sprintf(msg, "OK\n"); + else + count += sprintf(msg, "Fail, node count: %d\n", err_cnt); + strcat(buf, msg); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/cm_result */ +ssize_t ist30xx_cm_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int i, j; + int type, idx, err_cnt = 0; + int min_spec, max_spec; + int count = 0; + short cm; + char msg[128]; + + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + for (i = 0; i < cmcs->ch.tx_num; i++) { + for (j = 0; j < cmcs->ch.rx_num; j++) { + idx = (i * cmcs->ch.rx_num) + j; + + type = check_tsp_type(i, j); + if ((type == TSP_CH_UNKNOWN) || (type == TSP_CH_UNUSED)) + continue; + + min_spec = max_spec = ts_cmcs_buf->spec[idx]; + if (type == TSP_CH_SCREEN) { + min_spec -= (min_spec * cmcs->spec_cm.screen_min / 100); + max_spec += (min_spec * cmcs->spec_cm.screen_max / 100); + } else { // TSP_CH_KEY + min_spec -= (min_spec * cmcs->spec_cm.key_min / 100); + max_spec += (min_spec * cmcs->spec_cm.key_max / 100); + } + + cm = ts_cmcs_buf->cm[idx]; + if ((cm > min_spec) && (cm < max_spec)) + continue; // OK + + count += sprintf(msg, "%2d,%2d:%4d (%4d~%4d)\n", + i, j, cm, min_spec, max_spec); + strcat(buf, msg); + + err_cnt++; + } + } + + /* Check error count */ + if (err_cnt == 0) + count += sprintf(msg, "OK\n"); + else + count += sprintf(msg, "Fail, node count: %d\n", err_cnt); + strcat(buf, msg); + + return count; +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope0_result */ +ssize_t ist30xx_cm_slope0_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + return print_cm_slope_result(CMCS_FLAG_CM_SLOPE0, + ts_cmcs_buf->slope0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_slope1_result */ +ssize_t ist30xx_cm_slope1_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + return print_cm_slope_result(CMCS_FLAG_CM_SLOPE1, + ts_cmcs_buf->slope1, buf); +} +/* sysfs: /sys/class/touch/cmcs/cm_key_slope_result */ +ssize_t ist30xx_cm_key_slope_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + return print_cm_key_slope_result(ts_cmcs_buf->cm, buf, true); +} + +/* sysfs: /sys/class/touch/cmcs/cs0_result */ +ssize_t ist30xx_cs0_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) + return 0; + + return print_cs_result(ts_cmcs_buf->cs0, buf, 0); +} + +/* sysfs: /sys/class/touch/cmcs/cs1_result */ +ssize_t ist30xx_cs1_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) + return 0; + + return print_cs_result(ts_cmcs_buf->cs1, buf, 1); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm */ +ssize_t ist30xx_line_cm_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + return print_line_cmcs(CMCS_FLAG_CM, ts_cmcs_buf->cm, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm_slope0 */ +ssize_t ist30xx_line_cm_slope0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + return print_line_cmcs(CMCS_FLAG_CM_SLOPE0, ts_cmcs_buf->slope0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cm_slope1 */ +ssize_t ist30xx_line_cm_slope1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return 0; + + return print_line_cmcs(CMCS_FLAG_CM_SLOPE1, ts_cmcs_buf->slope1, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cs0 */ +ssize_t ist30xx_line_cs0_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) + return 0; + + return print_line_cmcs(CMCS_FLAG_CS0, ts_cmcs_buf->cs0, buf); +} + +/* sysfs: /sys/class/touch/cmcs/line_cs1 */ +ssize_t ist30xx_line_cs1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + CMCS_INFO *cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "CMCS test is not work!!\n"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CS)) + return 0; + + return print_line_cmcs(CMCS_FLAG_CS1, ts_cmcs_buf->cs1, buf); +} + +/* sysfs: /sys/class/touch/cmcs/cm_key_slope_value */ +ssize_t ist30xx_cm_key_slope_value_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + CMCS_INFO *cmcs; + + if ((ts_cmcs_bin == NULL) || (ts_cmcs_bin_size == 0)) + return sprintf(buf, "%s", "FFFF"); + + ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_cmcs_test(ts_cmcs_bin, ts_cmcs_bin_size); + mutex_unlock(&ist30xx_mutex); + + if (ret) + return sprintf(buf, "%s", "FFFF"); + + cmcs = (CMCS_INFO *)&ts_cmcs->cmcs; + + if (cmcs_ready == CMCS_NOT_READY) + return sprintf(buf, "%s", "FFFF"); + + if ((cmcs->cmd.mode) && !(cmcs->cmd.mode & FLAG_ENABLE_CM)) + return sprintf(buf, "%s", "FFFF"); + + return print_cm_key_slope_result(ts_cmcs_buf->cm, buf, false); +} + +/* sysfs : cmcs */ +static DEVICE_ATTR(info, S_IRUGO, ist30xx_cmcs_info_show, NULL); +static DEVICE_ATTR(cmcs_binary, S_IRUGO, ist30xx_cmcs_binary_show, NULL); +static DEVICE_ATTR(cmcs_custom, S_IRUGO, ist30xx_cmcs_custom_show, NULL); +static DEVICE_ATTR(cmcs_sdcard, S_IRUGO, ist30xx_cmcs_sdcard_show, NULL); +static DEVICE_ATTR(cm, S_IRUGO, ist30xx_cm_show, NULL); +static DEVICE_ATTR(cm_spec, S_IRUGO, ist30xx_cm_spec_show, NULL); +static DEVICE_ATTR(cm_slope0, S_IRUGO, ist30xx_cm_slope0_show, NULL); +static DEVICE_ATTR(cm_slope1, S_IRUGO, ist30xx_cm_slope1_show, NULL); +static DEVICE_ATTR(cs0, S_IRUGO, ist30xx_cs0_show, NULL); +static DEVICE_ATTR(cs1, S_IRUGO, ist30xx_cs1_show, NULL); +static DEVICE_ATTR(cm_result, S_IRUGO, ist30xx_cm_result_show, NULL); +static DEVICE_ATTR(cm_slope0_result, S_IRUGO, + ist30xx_cm_slope0_result_show, NULL); +static DEVICE_ATTR(cm_slope1_result, S_IRUGO, + ist30xx_cm_slope1_result_show, NULL); +static DEVICE_ATTR(cm_key_slope_result, S_IRUGO, + ist30xx_cm_key_slope_result_show, NULL); +static DEVICE_ATTR(cs0_result, S_IRUGO, ist30xx_cs0_result_show, NULL); +static DEVICE_ATTR(cs1_result, S_IRUGO, ist30xx_cs1_result_show, NULL); +static DEVICE_ATTR(line_cm, S_IRUGO, ist30xx_line_cm_show, NULL); +static DEVICE_ATTR(line_cm_slope0, S_IRUGO, ist30xx_line_cm_slope0_show, NULL); +static DEVICE_ATTR(line_cm_slope1, S_IRUGO, ist30xx_line_cm_slope1_show, NULL); +static DEVICE_ATTR(line_cs0, S_IRUGO, ist30xx_line_cs0_show, NULL); +static DEVICE_ATTR(line_cs1, S_IRUGO, ist30xx_line_cs1_show, NULL); +static DEVICE_ATTR(cm_key_slope_value, S_IRUGO, + ist30xx_cm_key_slope_value_show, NULL); + +static struct attribute *cmcs_attributes[] = { + &dev_attr_info.attr, + &dev_attr_cmcs_binary.attr, + &dev_attr_cmcs_custom.attr, + &dev_attr_cmcs_sdcard.attr, + &dev_attr_cm.attr, + &dev_attr_cm_spec.attr, + &dev_attr_cm_slope0.attr, + &dev_attr_cm_slope1.attr, + &dev_attr_cs0.attr, + &dev_attr_cs1.attr, + &dev_attr_cm_result.attr, + &dev_attr_cm_slope0_result.attr, + &dev_attr_cm_slope1_result.attr, + &dev_attr_cm_key_slope_result.attr, + &dev_attr_cs0_result.attr, + &dev_attr_cs1_result.attr, + &dev_attr_line_cm.attr, + &dev_attr_line_cm_slope0.attr, + &dev_attr_line_cm_slope1.attr, + &dev_attr_line_cs0.attr, + &dev_attr_line_cs1.attr, + &dev_attr_cm_key_slope_value.attr, + NULL, +}; + +static struct attribute_group cmcs_attr_group = { + .attrs = cmcs_attributes, +}; + +extern struct class *ist30xx_class; +struct device *ist30xx_cmcs_dev; + + +int ist30xx_init_cmcs_sysfs(void) +{ + /* /sys/class/touch/cmcs */ + ist30xx_cmcs_dev = device_create(ist30xx_class, NULL, 0, NULL, "cmcs"); + + /* /sys/class/touch/cmcs/... */ + if (unlikely(sysfs_create_group(&ist30xx_cmcs_dev->kobj, + &cmcs_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "cmcs"); + +#if IST30XX_INTERNAL_CMCS_BIN + ts_cmcs_bin = (u8 *)ist30xxb_cmcs; + ts_cmcs_bin_size = sizeof(ist30xxb_cmcs); + + ist30xx_get_cmcs_info(ts_cmcs_bin, ts_cmcs_bin_size); +#endif + + return 0; +} diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs.h b/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs.h new file mode 100644 index 00000000..418f30e9 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XX_CMCS_H__ +#define __IST30XX_CMCS_H__ + + +#define IST30XX_INTERNAL_CMCS_BIN (1) + +#define CMCS_FLAG_CM (1) +#define CMCS_FLAG_CM_SPEC (1 << 1) +#define CMCS_FLAG_CM_SLOPE0 (1 << 2) +#define CMCS_FLAG_CM_SLOPE1 (1 << 3) +#define CMCS_FLAG_CS0 (1 << 4) +#define CMCS_FLAG_CS1 (1 << 5) + +#define FLAG_ENABLE_CM (1) +#define FLAG_ENABLE_CS (2) +#define FLAG_ENABLE_CR (4) + +#define IST30XX_CMCS_LOAD_END (0x8FFFFCAB) +#if (IMAGIS_TSP_IC == IMAGIS_IST30XXB) +#define IST30XX_CMCS_BUF_SIZE (16 * 16) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3038) +#define IST30XX_CMCS_BUF_SIZE (((19 * 19) / 2 + 1) * 2) +#else +#error "Unknown TSP_IC" +#endif + +#define ENABLE_CM_MODE(n) (n & 1) +#define ENABLE_CS_MODE(n) ((n >> 1) & 1) + +#define IST30XXB_CMCS_NAME "ist30xxb.cms" + +#define IST30XX_CMCS_MAGIC "CMCS1TAG" +struct CMCS_ADDR_INFO { + u32 base_screen; + u32 base_key; + u32 start_cp; + u32 vcmp; + u32 sensor1; + u32 sensor2; + u32 sensor3; +}; +struct CMCS_CH_INFO { + u8 tx_num; + u8 rx_num; + u8 key_rx; + u8 key1; + u8 key2; + u8 key3; + u8 key4; + u8 key5; +}; +struct CMCS_SLOPE_INFO { + s16 x_min; + s16 x_max; + s16 y_min; + s16 y_max; + s16 key_min; + s16 key_max; +}; +struct CMCS_SPEC_INFO { + u16 screen_min; + u16 screen_max; + u16 key_min; + u16 key_max; +}; +struct CMCS_CMD { + u16 mode; // enable bit + u16 cmcs_size; + u16 base_screen; + u16 base_key; + u8 start_cp_cm; + u8 start_cp_cs; + u8 vcmp_cm; + u8 vcmp_cs; + u32 reserved; // for checksum of firmware +}; +typedef struct _CMCS_INFO { + u32 timeout; + struct CMCS_ADDR_INFO addr; + struct CMCS_CH_INFO ch; + struct CMCS_SPEC_INFO spec_cr; + struct CMCS_SPEC_INFO spec_cm; + struct CMCS_SPEC_INFO spec_cs0; + struct CMCS_SPEC_INFO spec_cs1; + struct CMCS_SLOPE_INFO slope; + u16 sensor1_size; + u16 sensor2_size; + u16 sensor3_size; + u16 reserved; + u32 cmcs_chksum; + u32 sensor_chksum; + struct CMCS_CMD cmd; +} CMCS_INFO; + +typedef struct _CMCS_BIN_INFO { + char magic1[8]; + CMCS_INFO cmcs; + u8 * buf_cmcs; + u32 * buf_sensor; + u16 * buf_node; + char magic2[8]; +} CMCS_BIN_INFO; + +typedef struct _CMCS_BUF { + s16 cm[IST30XX_CMCS_BUF_SIZE]; + s16 spec[IST30XX_CMCS_BUF_SIZE]; + s16 slope0[IST30XX_CMCS_BUF_SIZE]; + s16 slope1[IST30XX_CMCS_BUF_SIZE]; + s16 cs0[IST30XX_CMCS_BUF_SIZE]; + s16 cs1[IST30XX_CMCS_BUF_SIZE]; +} CMCS_BUF; + + +int ist30xx_init_cmcs_sysfs(void); + +#endif // __IST30XX_CMCS_H__ diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs_bin.h b/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs_bin.h new file mode 100644 index 00000000..b561de40 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_cmcs_bin.h @@ -0,0 +1,284 @@ +#ifndef __IST30XXB_CMCS_BIN_H__
+#define __IST30XXB_CMCS_BIN_H__
+
+/* ist30xxb cmcs binary: model( ) */
+static unsigned char ist30xxb_cmcs[] = {
+ 0x43, 0x4d, 0x43, 0x53, 0x31, 0x54, 0x41, 0x47, 0x10, 0x27, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x20,
+ 0xf4, 0x0f, 0x00, 0x20, 0xf8, 0x0f, 0x00, 0x20, 0xfc, 0x0f, 0x00, 0x20, 0x00, 0x90, 0x00, 0x40,
+ 0x00, 0xa0, 0x00, 0x40, 0x78, 0x08, 0x10, 0x40, 0x15, 0x0e, 0x01, 0x13, 0x14, 0xff, 0xff, 0xff,
+ 0xdf, 0x02, 0x55, 0x05, 0xdf, 0x02, 0x55, 0x05, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00, 0x19, 0x00,
+ 0x28, 0x0a, 0x80, 0x0c, 0x28, 0x0a, 0x80, 0x0c, 0x28, 0x0a, 0x80, 0x0c, 0x28, 0x0a, 0x80, 0x0c,
+ 0xc8, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0xc8, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x04, 0x00, 0x00, 0x8b, 0x37, 0xfa, 0x4a, 0xe3, 0xa7, 0x07, 0x3b, 0x01, 0x00, 0x64, 0x07,
+ 0xb8, 0x0b, 0xb8, 0x0b, 0x97, 0xc9, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0xa0, 0xe1,
+ 0x10, 0xd0, 0x9f, 0xe5, 0x01, 0x40, 0x2d, 0xe9, 0x27, 0x01, 0x00, 0xeb, 0x01, 0x40, 0xbd, 0xe8,
+ 0x00, 0xd0, 0xa0, 0xe1, 0x1e, 0xff, 0x2f, 0xe1, 0xf0, 0x0f, 0x00, 0x20, 0xf1, 0xb5, 0x79, 0x4c,
+ 0x79, 0x4d, 0x21, 0x78, 0x76, 0x4f, 0xa8, 0x6b, 0x00, 0x29, 0x83, 0xb0, 0x00, 0xd0, 0x00, 0x0c,
+ 0x00, 0x06, 0x00, 0x0e, 0x01, 0x02, 0x01, 0x43, 0x08, 0x04, 0x00, 0x0c, 0x00, 0xf0, 0x4c, 0xfb,
+ 0xe0, 0x78, 0x00, 0x28, 0x20, 0x79, 0x02, 0xd0, 0x00, 0xf0, 0x0c, 0xfb, 0x01, 0xe0, 0x00, 0xf0,
+ 0x27, 0xfb, 0x6e, 0x48, 0xc1, 0x6a, 0x00, 0x91, 0x00, 0x21, 0xc1, 0x62, 0x69, 0x49, 0xe8, 0x6b,
+ 0x0a, 0x78, 0x6b, 0x49, 0x00, 0x2a, 0x08, 0xd1, 0x6a, 0x4b, 0x1a, 0x62, 0x5a, 0x62, 0x4a, 0x68,
+ 0x00, 0x07, 0x12, 0x09, 0x12, 0x01, 0x00, 0x0f, 0x08, 0xe0, 0x66, 0x4b, 0x00, 0x22, 0x1a, 0x62,
+ 0x5a, 0x62, 0x4a, 0x68, 0x00, 0x03, 0x12, 0x09, 0x12, 0x01, 0x00, 0x0f, 0x02, 0x43, 0x4a, 0x60,
+ 0x03, 0x24, 0x26, 0x1f, 0x01, 0xe0, 0x03, 0x2c, 0x02, 0xd1, 0x01, 0x25, 0xed, 0x43, 0x09, 0xe0,
+ 0x02, 0x2c, 0x01, 0xd1, 0x01, 0x25, 0x05, 0xe0, 0x01, 0x2c, 0x01, 0xd1, 0x35, 0x00, 0x01, 0xe0,
+ 0x00, 0x2c, 0xf7, 0xd0, 0xe0, 0x07, 0xc0, 0x0f, 0x29, 0x00, 0x00, 0xf0, 0xb5, 0xf8, 0x64, 0x1e,
+ 0xe9, 0xd5, 0x02, 0x21, 0x03, 0x20, 0x00, 0xf0, 0xff, 0xf8, 0x50, 0x49, 0x00, 0x98, 0xc8, 0x62,
+ 0x4c, 0x48, 0x4c, 0x4d, 0x00, 0x78, 0x10, 0x35, 0x00, 0x28, 0x24, 0xd1, 0x09, 0x22, 0x00, 0xf0,
+ 0x07, 0xfb, 0x00, 0xf0, 0x33, 0xfb, 0x52, 0x1e, 0xf9, 0xd2, 0x46, 0x4c, 0x00, 0x21, 0x0e, 0xe0,
+ 0x00, 0x20, 0x08, 0xe0, 0x4a, 0x43, 0x12, 0x18, 0x93, 0x00, 0xfb, 0x58, 0x52, 0x00, 0x1b, 0x05,
+ 0x1b, 0x0d, 0x40, 0x1c, 0xab, 0x52, 0x62, 0x78, 0x90, 0x42, 0xf3, 0xd3, 0x49, 0x1c, 0xa0, 0x78,
+ 0x81, 0x42, 0xed, 0xd3, 0x20, 0x78, 0x00, 0x28, 0x05, 0xd1, 0x3e, 0x49, 0xa0, 0x68, 0x08, 0x62,
+ 0xe0, 0x68, 0x48, 0x62, 0x03, 0xe0, 0x37, 0x48, 0x81, 0x68, 0x3a, 0x48, 0x01, 0x62, 0x09, 0x22,
+ 0x00, 0xf0, 0xde, 0xfa, 0x00, 0xf0, 0x0a, 0xfb, 0x52, 0x1e, 0xf9, 0xd2, 0x36, 0x48, 0x00, 0x26,
+ 0x02, 0x90, 0x36, 0x48, 0x01, 0x90, 0x53, 0xe0, 0x00, 0x24, 0x4c, 0xe0, 0x21, 0x00, 0x30, 0x00,
+ 0x00, 0xf0, 0x78, 0xf9, 0x00, 0x28, 0x45, 0xd0, 0x2a, 0x49, 0x0a, 0x78, 0x00, 0x2a, 0x1a, 0xd1,
+ 0x49, 0x78, 0x71, 0x43, 0x0b, 0x19, 0x59, 0x00, 0x9b, 0x00, 0xfb, 0x58, 0x6a, 0x5a, 0x1b, 0x05,
+ 0x1b, 0x0d, 0x9a, 0x42, 0x01, 0xd8, 0x00, 0x20, 0x0b, 0xe0, 0x82, 0x42, 0x04, 0xd9, 0x12, 0x1a,
+ 0x12, 0x04, 0xd2, 0x0c, 0x80, 0x18, 0x03, 0xe0, 0x82, 0x1a, 0x12, 0x04, 0xd2, 0x0c, 0x80, 0x1a,
+ 0xc0, 0x1a, 0x68, 0x52, 0x26, 0xe0, 0x1b, 0x48, 0x21, 0x49, 0x40, 0x78, 0xff, 0x22, 0x91, 0x32,
+ 0x70, 0x43, 0x00, 0x19, 0x84, 0x46, 0x80, 0x00, 0x38, 0x58, 0x00, 0x05, 0x00, 0x0d, 0x41, 0x18,
+ 0x91, 0x42, 0x09, 0xd8, 0x1b, 0x4a, 0x11, 0x1a, 0x0b, 0x00, 0x4b, 0x43, 0x19, 0x0a, 0x90, 0x42,
+ 0x01, 0xd9, 0x88, 0x18, 0x00, 0xe0, 0x50, 0x1a, 0x03, 0x99, 0x00, 0x29, 0x03, 0xd0, 0x61, 0x46,
+ 0x02, 0x9a, 0x49, 0x00, 0x05, 0xe0, 0x0b, 0x49, 0x01, 0x9a, 0x89, 0x78, 0x61, 0x43, 0x89, 0x19,
+ 0x49, 0x00, 0x50, 0x52, 0x64, 0x1c, 0x07, 0x48, 0x40, 0x78, 0x84, 0x42, 0xae, 0xd3, 0x76, 0x1c,
+ 0x04, 0x48, 0x81, 0x78, 0x8e, 0x42, 0xa7, 0xd3, 0xff, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0x00,
+ 0xd4, 0x02, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20, 0xc0, 0x0f, 0x00, 0x20, 0x80, 0x90, 0x00, 0x40,
+ 0x00, 0xa0, 0x00, 0x40, 0x00, 0x0b, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10, 0xd4, 0x02, 0x00, 0x10,
+ 0x74, 0xf5, 0xff, 0xff, 0x54, 0x0b, 0x00, 0x00, 0xf3, 0xb5, 0x25, 0x48, 0x82, 0xb0, 0x0f, 0x00,
+ 0x01, 0x90, 0x00, 0x20, 0x00, 0x90, 0x39, 0xe0, 0x00, 0x25, 0x21, 0xe0, 0x29, 0x00, 0x30, 0x00,
+ 0x00, 0xf0, 0x00, 0xf9, 0x00, 0x28, 0x19, 0xd0, 0x1e, 0x49, 0x01, 0x9a, 0x49, 0x78, 0x71, 0x43,
+ 0x49, 0x19, 0x89, 0x00, 0x51, 0x58, 0x09, 0x05, 0x09, 0x0d, 0x08, 0x1a, 0x02, 0x99, 0x00, 0x29,
+ 0x02, 0xd0, 0x00, 0x28, 0x0a, 0xda, 0x01, 0xe0, 0x00, 0x28, 0x07, 0xdd, 0x3b, 0x00, 0x3a, 0x00,
+ 0x29, 0x00, 0x30, 0x00, 0x00, 0xf0, 0xc8, 0xf9, 0x40, 0x1c, 0x00, 0xd1, 0x64, 0x1c, 0x6d, 0x1c,
+ 0x10, 0x48, 0x40, 0x78, 0x85, 0x42, 0xd9, 0xd3, 0x76, 0x1c, 0x0e, 0x48, 0x81, 0x78, 0x8e, 0x42,
+ 0xd2, 0xd3, 0x01, 0x00, 0x88, 0x78, 0x49, 0x78, 0x48, 0x43, 0xa0, 0x42, 0x0d, 0xd0, 0x00, 0x98,
+ 0x41, 0x1c, 0x00, 0x91, 0x01, 0x21, 0x49, 0x02, 0x88, 0x42, 0x06, 0xd8, 0x00, 0xf0, 0x20, 0xfa,
+ 0x00, 0xf0, 0x4c, 0xfa, 0x00, 0x24, 0x26, 0x00, 0xe7, 0xe7, 0xff, 0xbc, 0x08, 0xbc, 0x18, 0x47,
+ 0xd4, 0x02, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20, 0xf0, 0xb5, 0x5a, 0x4a, 0x85, 0xb0, 0x40, 0x18,
+ 0x04, 0x92, 0x42, 0x00, 0x80, 0x18, 0x03, 0x90, 0x57, 0x48, 0x02, 0x91, 0x00, 0x90, 0x58, 0x48,
+ 0x56, 0x4f, 0x81, 0x78, 0x01, 0x91, 0x46, 0x78, 0xb5, 0x21, 0x89, 0x00, 0x38, 0x00, 0x00, 0xf0,
+ 0x3b, 0xf9, 0x00, 0x25, 0x0b, 0xe0, 0x00, 0x24, 0x06, 0xe0, 0x02, 0x9b, 0x21, 0x00, 0x1a, 0x00,
+ 0x28, 0x00, 0x00, 0xf0, 0x81, 0xf9, 0x64, 0x1c, 0xb4, 0x42, 0xf6, 0xd3, 0x6d, 0x1c, 0x01, 0x98,
+ 0x85, 0x42, 0xf0, 0xd3, 0x00, 0xf0, 0xec, 0xf9, 0x00, 0xf0, 0x18, 0xfa, 0x00, 0x25, 0x29, 0xe0,
+ 0x00, 0x24, 0x24, 0xe0, 0x21, 0x00, 0x28, 0x00, 0x00, 0xf0, 0x8c, 0xf8, 0x00, 0x28, 0x12, 0xd0,
+ 0x43, 0x49, 0x04, 0x9b, 0x49, 0x78, 0x69, 0x43, 0x0a, 0x19, 0x91, 0x00, 0x59, 0x58, 0x03, 0x04,
+ 0x09, 0x05, 0x09, 0x0d, 0x1b, 0x0c, 0xcb, 0x1a, 0x00, 0x2b, 0x01, 0xdd, 0x08, 0x1a, 0x00, 0xe0,
+ 0x40, 0x1a, 0x51, 0x00, 0x78, 0x52, 0x21, 0x00, 0x28, 0x00, 0x00, 0xf0, 0x9b, 0xf8, 0x38, 0x49,
+ 0x00, 0x9a, 0x49, 0x78, 0x69, 0x43, 0x09, 0x19, 0x49, 0x00, 0x64, 0x1c, 0x50, 0x52, 0xb4, 0x42,
+ 0xd8, 0xd3, 0x6d, 0x1c, 0x01, 0x98, 0x85, 0x42, 0xd2, 0xd3, 0x00, 0xf0, 0xe7, 0xf9, 0x00, 0x25,
+ 0x34, 0xe0, 0x00, 0x24, 0x2f, 0xe0, 0x21, 0x00, 0x28, 0x00, 0x00, 0xf0, 0x5b, 0xf8, 0x00, 0x28,
+ 0x28, 0xd0, 0x2b, 0x49, 0x04, 0x9b, 0x49, 0x78, 0x69, 0x43, 0x09, 0x19, 0x8a, 0x00, 0x9a, 0x58,
+ 0x03, 0x04, 0x12, 0x05, 0x12, 0x0d, 0x1b, 0x0c, 0xd3, 0x1a, 0x00, 0x2b, 0x01, 0xdd, 0x10, 0x1a,
+ 0x00, 0xe0, 0x80, 0x1a, 0x49, 0x00, 0x7b, 0x5a, 0x00, 0x04, 0x00, 0x0c, 0x83, 0x42, 0x0b, 0xd9,
+ 0x78, 0x52, 0x21, 0x00, 0x28, 0x00, 0x00, 0xf0, 0x65, 0xf8, 0x1d, 0x49, 0x00, 0x9a, 0x49, 0x78,
+ 0x69, 0x43, 0x09, 0x19, 0x49, 0x00, 0x50, 0x52, 0x00, 0x22, 0x53, 0x1e, 0x21, 0x00, 0x28, 0x00,
+ 0x00, 0xf0, 0x12, 0xf9, 0x64, 0x1c, 0xb4, 0x42, 0xcd, 0xd3, 0x6d, 0x1c, 0x01, 0x98, 0x85, 0x42,
+ 0xc7, 0xd3, 0x03, 0x98, 0x40, 0x1e, 0x03, 0x90, 0x19, 0xd2, 0x11, 0x4f, 0x00, 0x25, 0x0f, 0xe0,
+ 0x00, 0x24, 0x0a, 0xe0, 0x78, 0x78, 0x00, 0x99, 0x68, 0x43, 0x00, 0x19, 0x40, 0x00, 0x0a, 0x5a,
+ 0x21, 0x00, 0x28, 0x00, 0x00, 0xf0, 0x18, 0xf9, 0x64, 0x1c, 0xb4, 0x42, 0xf2, 0xd3, 0x6d, 0x1c,
+ 0x01, 0x98, 0x85, 0x42, 0xec, 0xd3, 0x05, 0xb0, 0xf0, 0xbc, 0x08, 0xbc, 0x18, 0x47, 0x00, 0xf0,
+ 0x5f, 0xf9, 0xa2, 0xe7, 0xd4, 0x02, 0x10, 0x40, 0x44, 0x0a, 0x00, 0x20, 0xd4, 0x02, 0x00, 0x10,
+ 0x60, 0x07, 0x00, 0x20, 0x70, 0xb4, 0x11, 0x4c, 0x11, 0x4e, 0x23, 0x6b, 0x35, 0x79, 0xf6, 0x78,
+ 0x02, 0x00, 0x1b, 0x04, 0x64, 0x6b, 0x00, 0x20, 0x1b, 0x0c, 0x00, 0x2e, 0x0c, 0xd0, 0xaa, 0x42,
+ 0x08, 0xd1, 0x13, 0x29, 0x03, 0xd0, 0x14, 0x29, 0x01, 0xd0, 0xff, 0x29, 0x00, 0xd1, 0x20, 0x00,
+ 0x70, 0xbc, 0x70, 0x47, 0x18, 0x00, 0xfb, 0xe7, 0xa9, 0x42, 0xfb, 0xd1, 0x13, 0x2a, 0xf6, 0xd0,
+ 0x14, 0x2a, 0xf4, 0xd0, 0xff, 0x2a, 0xf2, 0xd0, 0xf2, 0xe7, 0x00, 0x00, 0xc0, 0x0f, 0x00, 0x20,
+ 0x60, 0x07, 0x00, 0x20, 0x04, 0x4b, 0x03, 0x4a, 0x5b, 0x78, 0x58, 0x43, 0x40, 0x18, 0x40, 0x00,
+ 0x10, 0x5a, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20, 0x01, 0xc0, 0x8f, 0xe2,
+ 0x1c, 0xff, 0x2f, 0xe1, 0x70, 0xb5, 0x22, 0x48, 0x00, 0x6b, 0x04, 0x0c, 0x21, 0x48, 0x01, 0x6a,
+ 0x21, 0x4e, 0xb1, 0x60, 0x40, 0x6a, 0xb5, 0x21, 0xf0, 0x60, 0x20, 0x48, 0xc9, 0x00, 0x00, 0xf0,
+ 0x4b, 0xf8, 0xb5, 0x21, 0x30, 0x00, 0x89, 0x00, 0x10, 0x30, 0x00, 0xf0, 0x45, 0xf8, 0xe5, 0x07,
+ 0x00, 0x20, 0xed, 0x0f, 0x6d, 0x1e, 0x25, 0x40, 0xf0, 0x70, 0x02, 0xd1, 0x30, 0x70, 0x00, 0xf0,
+ 0x05, 0xf9, 0x17, 0x48, 0x17, 0x49, 0x08, 0x63, 0x00, 0x2c, 0x01, 0xd0, 0xa0, 0x07, 0x03, 0xd5,
+ 0x01, 0x20, 0x30, 0x70, 0x00, 0xf0, 0xfa, 0xf8, 0x13, 0x48, 0x14, 0x49, 0xc8, 0x61, 0x14, 0x48,
+ 0xc2, 0x68, 0x52, 0x08, 0x52, 0x00, 0xc2, 0x60, 0x00, 0x2d, 0x02, 0xd1, 0x0a, 0x48, 0x10, 0x30,
+ 0x00, 0xe0, 0x0a, 0x48, 0x0f, 0x4b, 0x04, 0xc8, 0xca, 0x61, 0x00, 0x2c, 0x01, 0xd0, 0x03, 0x2c,
+ 0x02, 0xd1, 0x98, 0x42, 0x00, 0xd1, 0x05, 0x48, 0x4a, 0x69, 0x52, 0x06, 0xfc, 0xd4, 0xf2, 0xe7,
+ 0xc0, 0x0f, 0x00, 0x20, 0x00, 0x0b, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20, 0x00, 0x00, 0x00, 0x10,
+ 0x60, 0x3a, 0x30, 0x0a, 0xc0, 0xa1, 0x00, 0x40, 0xab, 0xfc, 0xff, 0x8f, 0x00, 0x40, 0x00, 0x30,
+ 0x00, 0x20, 0x00, 0x40, 0x44, 0x0a, 0x00, 0x20, 0x89, 0x10, 0x00, 0x22, 0x00, 0xe0, 0x04, 0xc0,
+ 0x49, 0x1e, 0xfc, 0xd2, 0x70, 0x47, 0x00, 0x00, 0xf0, 0xb4, 0x19, 0x49, 0x01, 0x25, 0xc8, 0x78,
+ 0x18, 0x4e, 0x19, 0x4f, 0x68, 0x40, 0xc8, 0x70, 0x00, 0x20, 0x81, 0x00, 0x8c, 0x19, 0x61, 0x68,
+ 0x40, 0x1c, 0x0a, 0x03, 0x4b, 0x04, 0xdb, 0x0e, 0xd2, 0x0e, 0x39, 0x40, 0xdb, 0x03, 0x19, 0x43,
+ 0x92, 0x02, 0x11, 0x43, 0x18, 0x28, 0x61, 0x60, 0xef, 0xd3, 0x10, 0x49, 0x08, 0x69, 0x68, 0x40,
+ 0x08, 0x61, 0x0c, 0x48, 0x0e, 0x49, 0x40, 0x38, 0x81, 0x61, 0x0e, 0x49, 0x01, 0x63, 0x41, 0x63,
+ 0x08, 0x48, 0x0d, 0x49, 0xc0, 0x30, 0x41, 0x60, 0x03, 0x21, 0x89, 0x04, 0x81, 0x60, 0x07, 0x49,
+ 0x0a, 0x48, 0x40, 0x31, 0x08, 0x60, 0x0a, 0x48, 0x0a, 0x49, 0xc8, 0x60, 0xf0, 0xbc, 0x70, 0x47,
+ 0x60, 0x07, 0x00, 0x20, 0x40, 0x0a, 0x10, 0x40, 0xff, 0x03, 0xf0, 0xff, 0x00, 0x90, 0x00, 0x40,
+ 0xc8, 0x61, 0x14, 0x44, 0xc8, 0x61, 0x14, 0x04, 0xff, 0xff, 0x1f, 0x00, 0x0e, 0x15, 0x0e, 0x15,
+ 0xf8, 0x0f, 0xfe, 0x00, 0x00, 0xa0, 0x00, 0x40, 0x30, 0xb4, 0x0e, 0x4d, 0x0c, 0x4c, 0x6d, 0x78,
+ 0x68, 0x43, 0x40, 0x18, 0x45, 0x00, 0x60, 0x5b, 0x01, 0x06, 0x00, 0x0a, 0x09, 0x0e, 0x82, 0x18,
+ 0xc9, 0x18, 0x00, 0x20, 0x4b, 0x1e, 0xc0, 0x43, 0xff, 0x2b, 0x06, 0xd2, 0x53, 0x1e, 0xff, 0x2b,
+ 0x03, 0xd2, 0x10, 0x02, 0x08, 0x43, 0x60, 0x53, 0x00, 0x20, 0x30, 0xbc, 0x70, 0x47, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20, 0x10, 0xb4, 0x05, 0x4c, 0x03, 0x4b, 0x64, 0x78,
+ 0x60, 0x43, 0x40, 0x18, 0x40, 0x00, 0x1a, 0x52, 0x10, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40,
+ 0x60, 0x07, 0x00, 0x20, 0xf0, 0xb4, 0x0d, 0x4f, 0x00, 0x21, 0x7a, 0x78, 0x1e, 0x26, 0x0a, 0x4d,
+ 0x42, 0x43, 0x09, 0xe0, 0x13, 0x29, 0x05, 0xd0, 0x14, 0x29, 0x03, 0xd0, 0xff, 0x29, 0x01, 0xd0,
+ 0x53, 0x00, 0xee, 0x52, 0x52, 0x1c, 0x49, 0x1c, 0x7b, 0x78, 0x04, 0x00, 0x5c, 0x43, 0xe3, 0x18,
+ 0x93, 0x42, 0xef, 0xd8, 0xf0, 0xbc, 0x70, 0x47, 0x00, 0x00, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20,
+ 0x70, 0xb4, 0x00, 0x21, 0x0a, 0x4b, 0x0b, 0x4a, 0x1e, 0x24, 0x0a, 0xe0, 0x13, 0x29, 0x05, 0xd0,
+ 0x14, 0x29, 0x03, 0xd0, 0xff, 0x29, 0x01, 0xd0, 0x45, 0x00, 0x5c, 0x53, 0x55, 0x78, 0x40, 0x19,
+ 0x49, 0x1c, 0x95, 0x78, 0x56, 0x78, 0x75, 0x43, 0x85, 0x42, 0xef, 0xd8, 0x70, 0xbc, 0x70, 0x47,
+ 0x00, 0x00, 0x10, 0x40, 0x60, 0x07, 0x00, 0x20, 0x02, 0x04, 0x04, 0x49, 0x02, 0x43, 0x00, 0x20,
+ 0x40, 0x1c, 0x04, 0xc1, 0xb5, 0x28, 0xfb, 0xd3, 0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40,
+ 0x01, 0x48, 0xc1, 0x68, 0xc1, 0x60, 0x70, 0x47, 0x00, 0x90, 0x00, 0x40, 0x70, 0xb5, 0x11, 0x4e,
+ 0x11, 0x4c, 0x01, 0x25, 0x30, 0x68, 0x00, 0x04, 0x00, 0x0c, 0x01, 0x0a, 0x00, 0x06, 0x00, 0x0e,
+ 0x61, 0x70, 0xa0, 0x70, 0xe2, 0x78, 0x00, 0x2a, 0x02, 0xd1, 0x49, 0x1e, 0x21, 0x71, 0x01, 0xe0,
+ 0x40, 0x1e, 0x20, 0x71, 0x28, 0x00, 0xff, 0xf7, 0x79, 0xfc, 0x20, 0x78, 0x00, 0x28, 0x05, 0xd0,
+ 0x01, 0x2d, 0x03, 0xd1, 0xff, 0xf7, 0x20, 0xff, 0x00, 0x25, 0xe3, 0xe7, 0x70, 0xbc, 0x08, 0xbc,
+ 0x18, 0x47, 0x00, 0x00, 0x40, 0x90, 0x00, 0x40, 0x60, 0x07, 0x00, 0x20, 0x02, 0x48, 0xc1, 0x68,
+ 0xc9, 0x07, 0xfc, 0xd0, 0x70, 0x47, 0x00, 0x00, 0x00, 0x90, 0x00, 0x40, 0x8b, 0x37, 0xfa, 0x4a,
+ 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x02, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x15, 0x0e, 0x15, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x02, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x30, 0x00, 0xff, 0x05, 0xff, 0x03, 0x18, 0x10, 0x08, 0x00,
+ 0x00, 0x2c, 0x00, 0x2c, 0x64, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0xff, 0x0f,
+ 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0xc8, 0x00, 0x40, 0x06, 0x00, 0x00, 0x08, 0x20,
+ 0x11, 0x00, 0x10, 0x00, 0x48, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x54, 0x55, 0x45, 0x00, 0x10, 0x30, 0x00, 0x00, 0x00, 0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x14, 0x00, 0x00, 0x0c, 0x0c, 0x06, 0x00,
+ 0x00, 0x04, 0x7c, 0x78, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x0f, 0xc0, 0xda, 0x00, 0x00,
+ 0x60, 0x30, 0x30, 0x00, 0x60, 0x3c, 0x30, 0x0c, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xd0, 0x07, 0x08, 0x00, 0x12, 0x12, 0xc8, 0x01, 0x90, 0x81, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0xff, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0x0f, 0x01, 0x00,
+ 0x00, 0x00, 0x01, 0x00, 0xff, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xff, 0x0f, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00,
+ 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00,
+ 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00,
+ 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00,
+ 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00, 0x60, 0x30, 0x30, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0xc8, 0x61, 0x14, 0x04,
+ 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04,
+ 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04,
+ 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04,
+ 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04,
+ 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x44, 0xc8, 0x61, 0x14, 0x44,
+ 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0xc8, 0x61, 0x14, 0x04, 0x00, 0xc0, 0x91, 0xe7,
+ 0x21, 0x2c, 0x92, 0xe7, 0x42, 0xbc, 0x92, 0xe7, 0x63, 0x28, 0x93, 0xe7, 0x84, 0xb8, 0x93, 0xe7,
+ 0xa5, 0x24, 0x94, 0xe7, 0xc6, 0xb4, 0x94, 0xe7, 0xe7, 0x20, 0x95, 0xe7, 0x08, 0xb1, 0x95, 0xe7,
+ 0x29, 0x9d, 0x98, 0xe7, 0x4a, 0x01, 0x99, 0xe7, 0x6b, 0x99, 0x99, 0xe7, 0x8c, 0x05, 0x9a, 0xe7,
+ 0xad, 0x95, 0x9a, 0xe7, 0xce, 0x09, 0x90, 0xe7, 0xef, 0x11, 0x90, 0xe7, 0x10, 0x0e, 0x90, 0xe7,
+ 0x31, 0x46, 0x90, 0xe7, 0x52, 0x52, 0x90, 0xe7, 0x73, 0x4a, 0x90, 0xe7, 0x94, 0x4e, 0x90, 0xe7,
+ 0xb5, 0x02, 0x90, 0xe7, 0xd6, 0x02, 0x90, 0xe7, 0xf7, 0x02, 0x90, 0xe7, 0x00, 0x08, 0x00, 0x00,
+ 0x00, 0x80, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+ 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+ 0x01, 0x10, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+ 0x06, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x00,
+ 0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x1e, 0x00,
+ 0xf8, 0x0f, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x50, 0x30,
+ 0x32, 0x30, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x60, 0x30, 0x60, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x87, 0x07, 0x71, 0x07, 0x5f, 0x07, 0x47, 0x07, 0x38, 0x07, 0x1a, 0x07, 0x34, 0x07, 0x53, 0x07,
+ 0x64, 0x07, 0x79, 0x07, 0x8c, 0x07, 0x9c, 0x07, 0xa7, 0x07, 0x00, 0x00, 0x03, 0x08, 0xf8, 0x07,
+ 0xea, 0x07, 0xd8, 0x07, 0xcf, 0x07, 0xba, 0x07, 0xa0, 0x07, 0x91, 0x07, 0xb3, 0x07, 0xb5, 0x07,
+ 0xc4, 0x07, 0xce, 0x07, 0xc3, 0x07, 0x00, 0x00, 0xc3, 0x07, 0xd2, 0x07, 0xce, 0x07, 0xc7, 0x07,
+ 0xca, 0x07, 0xc2, 0x07, 0xc5, 0x07, 0xcf, 0x07, 0xd1, 0x07, 0xd6, 0x07, 0xd9, 0x07, 0xdb, 0x07,
+ 0xd7, 0x07, 0x00, 0x00, 0xdd, 0x07, 0xda, 0x07, 0xd7, 0x07, 0xd2, 0x07, 0xd2, 0x07, 0xcb, 0x07,
+ 0xc1, 0x07, 0xd0, 0x07, 0xc2, 0x07, 0xc5, 0x07, 0xc8, 0x07, 0xce, 0x07, 0xba, 0x07, 0x00, 0x00,
+ 0x73, 0x07, 0xa3, 0x07, 0xa9, 0x07, 0xa2, 0x07, 0xa6, 0x07, 0x9b, 0x07, 0x9f, 0x07, 0xa4, 0x07,
+ 0xa7, 0x07, 0xa9, 0x07, 0xaa, 0x07, 0xac, 0x07, 0xa2, 0x07, 0x00, 0x00, 0x8e, 0x07, 0x8a, 0x07,
+ 0x85, 0x07, 0x81, 0x07, 0x86, 0x07, 0x82, 0x07, 0x88, 0x07, 0x77, 0x07, 0x79, 0x07, 0x7b, 0x07,
+ 0x7d, 0x07, 0x7f, 0x07, 0x57, 0x07, 0x00, 0x00, 0x2a, 0x07, 0x54, 0x07, 0x53, 0x07, 0x50, 0x07,
+ 0x54, 0x07, 0x4e, 0x07, 0x46, 0x07, 0x4c, 0x07, 0x4e, 0x07, 0x55, 0x07, 0x57, 0x07, 0x53, 0x07,
+ 0x48, 0x07, 0x00, 0x00, 0x32, 0x07, 0x32, 0x07, 0x33, 0x07, 0x2d, 0x07, 0x33, 0x07, 0x41, 0x07,
+ 0x1d, 0x07, 0x22, 0x07, 0x24, 0x07, 0x25, 0x07, 0x26, 0x07, 0x24, 0x07, 0xf6, 0x06, 0x00, 0x00,
+ 0xf6, 0x06, 0x4c, 0x07, 0x3f, 0x07, 0x38, 0x07, 0x3f, 0x07, 0x3d, 0x07, 0x2a, 0x07, 0x2e, 0x07,
+ 0x32, 0x07, 0x34, 0x07, 0x33, 0x07, 0x34, 0x07, 0x2a, 0x07, 0x00, 0x00, 0x3e, 0x07, 0x38, 0x07,
+ 0x37, 0x07, 0x33, 0x07, 0x4b, 0x07, 0x2e, 0x07, 0x21, 0x07, 0x28, 0x07, 0x2a, 0x07, 0x2b, 0x07,
+ 0x2b, 0x07, 0x28, 0x07, 0xdb, 0x06, 0x00, 0x00, 0xf2, 0x06, 0x22, 0x07, 0x25, 0x07, 0x20, 0x07,
+ 0x25, 0x07, 0x1b, 0x07, 0x0e, 0x07, 0x13, 0x07, 0x15, 0x07, 0x16, 0x07, 0x15, 0x07, 0x13, 0x07,
+ 0x07, 0x07, 0x00, 0x00, 0x2c, 0x07, 0x23, 0x07, 0x27, 0x07, 0x38, 0x07, 0x26, 0x07, 0x1b, 0x07,
+ 0x0f, 0x07, 0x18, 0x07, 0x19, 0x07, 0x19, 0x07, 0x18, 0x07, 0x15, 0x07, 0xaf, 0x06, 0x00, 0x00,
+ 0xcb, 0x06, 0x2e, 0x07, 0x2f, 0x07, 0x2a, 0x07, 0x30, 0x07, 0x29, 0x07, 0x18, 0x07, 0x1e, 0x07,
+ 0x20, 0x07, 0x21, 0x07, 0x20, 0x07, 0x1d, 0x07, 0x19, 0x07, 0x00, 0x00, 0x4e, 0x07, 0x2c, 0x07,
+ 0x3f, 0x07, 0x26, 0x07, 0x2c, 0x07, 0x23, 0x07, 0x16, 0x07, 0x21, 0x07, 0x20, 0x07, 0x21, 0x07,
+ 0x20, 0x07, 0x1a, 0x07, 0x65, 0x06, 0x00, 0x00, 0x4a, 0x06, 0xfe, 0x06, 0x00, 0x07, 0xfc, 0x06,
+ 0x03, 0x07, 0xfd, 0x06, 0xec, 0x06, 0xf3, 0x06, 0xf4, 0x06, 0xf6, 0x06, 0xf5, 0x06, 0xf1, 0x06,
+ 0xfe, 0x06, 0x00, 0x00, 0x6d, 0x07, 0x26, 0x07, 0x0b, 0x07, 0x06, 0x07, 0x0d, 0x07, 0x04, 0x07,
+ 0xf7, 0x06, 0x02, 0x07, 0x00, 0x07, 0x02, 0x07, 0x00, 0x07, 0xf7, 0x06, 0xb8, 0x05, 0x00, 0x00,
+ 0x0a, 0x06, 0x1d, 0x07, 0x1f, 0x07, 0x1d, 0x07, 0x24, 0x07, 0x20, 0x07, 0x0e, 0x07, 0x17, 0x07,
+ 0x17, 0x07, 0x19, 0x07, 0x18, 0x07, 0x17, 0x07, 0x61, 0x07, 0x00, 0x00, 0xdc, 0x07, 0x09, 0x07,
+ 0xf8, 0x06, 0xf0, 0x06, 0xf7, 0x06, 0xf0, 0x06, 0xe2, 0x06, 0xef, 0x06, 0xf2, 0x06, 0x10, 0x07,
+ 0xfe, 0x06, 0xfc, 0x06, 0x47, 0x07, 0x00, 0x00, 0x0d, 0x07, 0xba, 0x06, 0xab, 0x06, 0xa2, 0x06,
+ 0xaa, 0x06, 0xa1, 0x06, 0x91, 0x06, 0xa0, 0x06, 0xa3, 0x06, 0xaa, 0x06, 0xac, 0x06, 0xb9, 0x06,
+ 0xc8, 0x07, 0x00, 0x00, 0x91, 0x07, 0xe9, 0x06, 0xe2, 0x06, 0xd9, 0x06, 0xe0, 0x06, 0xda, 0x06,
+ 0xc8, 0x06, 0xda, 0x06, 0xde, 0x06, 0xe5, 0x06, 0xfc, 0x06, 0xea, 0x06, 0x53, 0x07, 0xfd, 0x06,
+ 0x1a, 0x07, 0x88, 0x06, 0x83, 0x06, 0x79, 0x06, 0x81, 0x06, 0x78, 0x06, 0x63, 0x06, 0x73, 0x06,
+ 0x75, 0x06, 0x79, 0x06, 0x7f, 0x06, 0xa4, 0x06, 0x43, 0x07, 0x04, 0x07, 0x43, 0x4d, 0x43, 0x53,
+ 0x31, 0x54, 0x41, 0x47
+};
+
+#endif // __IST30XXB_CMCS_BIN_H__
diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_misc.c b/drivers/input/touchscreen/ist30xxa/ist30xx_misc.c new file mode 100644 index 00000000..aa6f3e51 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_misc.c @@ -0,0 +1,1582 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/firmware.h> +#include <linux/stat.h> + +#include "ist30xx.h" +#include "ist30xx_update.h" +#include "ist30xx_misc.h" + +#if IST30XX_CHKIC +#include "ist30xx_chkic_bin.h" +#endif + +#define TSP_CH_SCREEN (1) +#define TSP_CH_KEY (2) + +#define TOUCH_NODE_PARSING_DEBUG (0) + +extern struct ist30xx_data *ts_data; + +TSP_INFO ist30xx_tsp_info; +TKEY_INFO ist30xx_tkey_info; + +static u32 *ist30xx_frame_buf; +static u32 *ist30xx_frame_rawbuf; +static u32 *ist30xx_frame_fltbuf; + + +int ist30xx_tkey_update_info(void) +{ + int ret = 0; + u32 tkey_info1, tkey_info2, tkey_info3; + TKEY_INFO *tkey = &ist30xx_tkey_info; + + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_KEY_INFO1, &tkey_info1); + if (unlikely(ret)) + return ret; + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_KEY_INFO2, &tkey_info2); + if (unlikely(ret)) + return ret; + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_KEY_INFO3, &tkey_info3); + if (unlikely(ret)) + return ret; + + tkey->enable = ((tkey_info1 & (0xFF << 24)) ? true : false); + tkey->key_num = (tkey_info1 >> 16) & 0xFF; + tkey->ch_num[0] = (tkey_info2 >> 24) & 0xFF; + tkey->ch_num[1] = (tkey_info2 >> 16) & 0xFF; + tkey->ch_num[2] = (tkey_info2 >> 8) & 0xFF; + tkey->ch_num[3] = tkey_info2 & 0xFF; + tkey->ch_num[4] = (tkey_info3 >> 24) & 0xFF; + + return ret; +} + + +#define TSP_INFO_SWAP_XY (1 << 0) +#define TSP_INFO_FLIP_X (1 << 1) +#define TSP_INFO_FLIP_Y (1 << 2) +int ist30xx_tsp_update_info(void) +{ + int ret = 0; + u32 tsp_ch_num, tsp_swap, tsp_dir; + TSP_INFO *tsp = &ist30xx_tsp_info; + + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_TSP_SWAP_INFO, &tsp_swap); + if (unlikely(ret)) return ret; + + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_TSP_DIRECTION, &tsp_dir); + if (unlikely(ret)) return ret; + + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_TSP_CHNUM1, &tsp_ch_num); + if (unlikely(ret || !tsp_ch_num)) return ret; + + tsp->finger_num = IST30XX_MAX_MT_FINGERS; + + tsp->ch_num.rx = tsp_ch_num >> 16; + tsp->ch_num.tx = tsp_ch_num & 0xFFFF; + + tsp->dir.swap_xy = (tsp_swap & TSP_INFO_SWAP_XY ? true : false); + tsp->dir.flip_x = (tsp_swap & TSP_INFO_FLIP_X ? true : false); + tsp->dir.flip_y = (tsp_swap & TSP_INFO_FLIP_Y ? true : false); + + tsp->node.len = tsp->ch_num.tx * tsp->ch_num.rx; + tsp->height = (tsp->dir.swap_xy ? tsp->ch_num.rx : tsp->ch_num.tx); + tsp->width = (tsp->dir.swap_xy ? tsp->ch_num.tx : tsp->ch_num.rx); + + return ret; +} + +int ist30xx_check_valid_ch(int ch_tx, int ch_rx) +{ + TKEY_INFO *tkey = &ist30xx_tkey_info; + TSP_INFO *tsp = &ist30xx_tsp_info; + + if (unlikely((ch_tx > tsp->ch_num.tx) || (ch_rx > tsp->ch_num.rx))) + return 0; + + if (tkey->enable) { + if (tkey->axis_rx) { + tsp_verb("tx: %d, rx: %d\n", ch_tx, ch_rx); + if (ch_rx == tsp->ch_num.rx - 1) { + tsp_verb("ch_tx: %d\n", ch_tx); + if ((ch_tx == tkey->ch_num[0]) || (ch_tx == tkey->ch_num[1]) || + (ch_tx == tkey->ch_num[2]) || (ch_tx == tkey->ch_num[3]) || + (ch_tx == tkey->ch_num[4])) + return TSP_CH_KEY; + else + return 0; + } + } else { + if (ch_tx == tsp->ch_num.tx - 1) { + if ((ch_rx == tkey->ch_num[0]) || (ch_rx == tkey->ch_num[1]) || + (ch_rx == tkey->ch_num[2]) || (ch_rx == tkey->ch_num[3]) || + (ch_rx == tkey->ch_num[4])) + return TSP_CH_KEY; + else + return 0; + } + } + } + + return TSP_CH_SCREEN; +} + + +int ist30xx_parse_touch_node(u8 flag, struct TSP_NODE_BUF *node) +{ +#if TOUCH_NODE_PARSING_DEBUG + int j; + TSP_INFO *tsp = &ist30xx_tsp_info; +#endif + int i; + u16 *raw = (u16 *)&node->raw; + u16 *base = (u16 *)&node->base; + u16 *filter = (u16 *)&node->filter; + u32 *tmp_rawbuf = ist30xx_frame_rawbuf; + u32 *tmp_fltbuf = ist30xx_frame_fltbuf; + + for (i = 0; i < node->len; i++) { + if (flag & (NODE_FLAG_RAW | NODE_FLAG_BASE)) { + *raw++ = *tmp_rawbuf & 0xFFF; + *base++ = (*tmp_rawbuf >> 16) & 0xFFF; + + tmp_rawbuf++; + } + if (flag & NODE_FLAG_FILTER) + *filter++ = *tmp_fltbuf++ & 0xFFF; + } + +#if TOUCH_NODE_PARSING_DEBUG + tsp_info("RAW - %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + printk("\n[ TSP ] "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%4d ", node->raw[i][j]); + } + + tsp_info("BASE - %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + printk("\n[ TSP ] "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%4d ", node->base[i][j]); + } + + tsp_info("FILTER - %d * %d\n", tsp->ch_num.tx, tsp->ch_num.rx); + for (i = 0; i < tsp->ch_num.tx; i++) { + printk("\n[ TSP ] "); + for (j = 0; j < tsp->ch_num.rx; j++) + printk("%4d ", node->filter[i][j]); + } +#endif + + return 0; +} + +int print_touch_node(u8 flag, struct TSP_NODE_BUF *node, char *buf, bool ch_tsp) +{ + int i, j; + int count = 0; + int val = 0; + const int msg_len = 128; + char msg[msg_len]; + TSP_INFO *tsp = &ist30xx_tsp_info; + + if (tsp->dir.swap_xy) { + } else { + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + if (ch_tsp && (ist30xx_check_valid_ch(i, j) != TSP_CH_SCREEN)) + continue; + + if (flag == NODE_FLAG_RAW) + val = (int)node->raw[i][j]; + else if (flag == NODE_FLAG_BASE) + val = (int)node->base[i][j]; + else if (flag == NODE_FLAG_FILTER) + val = (int)node->filter[i][j]; + else if (flag == NODE_FLAG_DIFF) + val = (int)(node->raw[i][j] - node->base[i][j]); + else + return 0; + + if (val < 0) val = 0; + + count += snprintf(msg, msg_len, "%4d ", val); + strncat(buf, msg, msg_len); + } + + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + } + } + + return count; +} + +int parse_tsp_node(u8 flag, struct TSP_NODE_BUF *node, s16 *buf16) +{ + int i, j; + s16 val = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + + if (unlikely((flag != NODE_FLAG_RAW) && (flag != NODE_FLAG_BASE) && + (flag != NODE_FLAG_FILTER) && (flag != NODE_FLAG_DIFF))) + return -EPERM; + + if (tsp->dir.swap_xy) { + } else { + for (i = 0; i < tsp->ch_num.tx; i++) { + for (j = 0; j < tsp->ch_num.rx; j++) { + if (ist30xx_check_valid_ch(i, j) != TSP_CH_SCREEN) + continue; + + switch ((int)flag) { + case NODE_FLAG_RAW: + val = (s16)node->raw[i][j]; + break; + case NODE_FLAG_BASE: + val = (s16)node->base[i][j]; + break; + case NODE_FLAG_FILTER: + val = (s16)node->filter[i][j]; + break; + case NODE_FLAG_DIFF: + val = (s16)(node->raw[i][j] - node->base[i][j]); + break; + } + + if (val < 0) val = 0; + + *buf16++ = val; + } + } + } + + return 0; +} + +int ist30xx_read_touch_node(u8 flag, struct TSP_NODE_BUF *node) +{ + int ret = 0; + u32 addr = IST30XXB_RAW_ADDR; + + if (ts_data->chip_id == IST3038_CHIP_ID) + addr += 0xD4; + + ist30xx_disable_irq(ts_data); + + if (flag & NODE_FLAG_NO_CCP) { + ist30xx_reset(false); + + ret = ist30xx_write_cmd(ts_data->client, CMD_USE_CORRECT_CP, 0); + if (unlikely(ret)) + goto read_tsp_node_end; + } + + ret = ist30xx_cmd_reg(ts_data->client, CMD_ENTER_REG_ACCESS); + if (unlikely(ret)) + goto read_tsp_node_end; + + ret = ist30xx_write_cmd(ts_data->client, IST30XX_RX_CNT_ADDR, node->len); + if (unlikely(ret)) + goto reg_access_end; + + if (flag & (NODE_FLAG_RAW | NODE_FLAG_BASE)) { + tsp_info("Reg addr: %x, size: %d\n", addr, node->len); + ret = ist30xx_read_buf(ts_data->client, addr, + ist30xx_frame_rawbuf, node->len); + if (unlikely(ret)) + goto reg_access_end; + } + + if (flag & NODE_FLAG_FILTER) { + tsp_info("Reg addr: %x, size: %d\n", IST30XXB_FILTER_ADDR, node->len); + ret = ist30xx_read_buf(ts_data->client, IST30XXB_FILTER_ADDR, + ist30xx_frame_fltbuf, node->len); + if (unlikely(ret)) + goto reg_access_end; + } + +reg_access_end: + ist30xx_cmd_reg(ts_data->client, CMD_EXIT_REG_ACCESS); + ist30xx_cmd_start_scan(ts_data->client); + +read_tsp_node_end: + ist30xx_enable_irq(ts_data); + + return ret; +} + + +/* sysfs: /sys/class/touch/node/refresh */ +ssize_t ist30xx_frame_refresh(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + u8 flag = NODE_FLAG_RAW | NODE_FLAG_BASE | NODE_FLAG_FILTER; + + tsp_info("refresh\n"); + + ret = ist30xx_read_touch_node(flag, &tsp->node); + if (unlikely(ret)) { + tsp_err("cmd 1frame raw update fail\n"); + return sprintf(buf, "FAIL\n"); + } + + ist30xx_parse_touch_node(flag, &tsp->node); + + return sprintf(buf, "OK\n"); +} + + +/* sysfs: /sys/class/touch/node/read_nocp */ +ssize_t ist30xx_frame_nocp(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + u8 flag = NODE_FLAG_RAW | NODE_FLAG_BASE | NODE_FLAG_FILTER | + NODE_FLAG_NO_CCP; + + ret = ist30xx_read_touch_node(flag, &tsp->node); + if (unlikely(ret)) { + tsp_err("cmd 1frame raw update fail\n"); + return sprintf(buf, "FAIL\n"); + } + + ist30xx_parse_touch_node(flag, &tsp->node); + + return sprintf(buf, "OK\n"); +} + + +/* sysfs: /sys/class/touch/node/base */ +ssize_t ist30xx_base_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xxb baseline(%d)\n", tsp->node.len); + + count += print_touch_node(NODE_FLAG_BASE, &tsp->node, buf, false); + + return count; +} + + +/* sysfs: /sys/class/touch/node/raw */ +ssize_t ist30xx_raw_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xxb raw(%d)\n", tsp->node.len); + + count += print_touch_node(NODE_FLAG_RAW, &tsp->node, buf, false); + + return count; +} + + +/* sysfs: /sys/class/touch/node/diff */ +ssize_t ist30xx_diff_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xxb difference (%d)\n", tsp->node.len); + + count += print_touch_node(NODE_FLAG_DIFF, &tsp->node, buf, false); + + return count; +} + + +/* sysfs: /sys/class/touch/node/filter */ +ssize_t ist30xx_filter_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + + buf[0] = '\0'; + count = sprintf(buf, "dump ist30xxb filter (%d)\n", tsp->node.len); + + count += print_touch_node(NODE_FLAG_FILTER, &tsp->node, buf, false); + + return count; +} + + +extern int calib_ms_delay; +/* sysfs: /sys/class/touch/sys/clb_time */ +ssize_t ist30xx_calib_time_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int ms_delay; + + sscanf(buf, "%d", &ms_delay); + + if (ms_delay > 10 && ms_delay < 1000) // 1sec ~ 100sec + calib_ms_delay = ms_delay; + + tsp_info("Calibration wait time %dsec\n", calib_ms_delay / 10); + + return size; +} + +/* sysfs: /sys/class/touch/sys/clb */ +ssize_t ist30xx_calib_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + ist30xx_disable_irq(ts_data); + + ist30xx_reset(false); + + ist30xx_calibrate(1); + + ist30xx_start(ts_data); + + return 0; +} + +/* sysfs: /sys/class/touch/sys/clb_result */ +ssize_t ist30xx_calib_result_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + int count = 0; + u32 value; + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(ts_data); + ist30xx_reset(false); + + ret = ist30xx_read_cmd(ts_data->client, CMD_GET_CALIB_RESULT, &value); + if (unlikely(ret)) { + count = sprintf(buf, "Error Read Calibration Result\n"); + goto calib_show_end; + } + + count = sprintf(buf, + "Calibration Status : %d, Max raw gap : %d - (raw: %08x)\n", + CALIB_TO_STATUS(value), CALIB_TO_GAP(value), value); + +calib_show_end: + ist30xx_start(ts_data); + ist30xx_enable_irq(ts_data); + mutex_unlock(&ist30xx_mutex); + + return count; +} + +/* sysfs: /sys/class/touch/sys/power_on */ +ssize_t ist30xx_power_on_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + tsp_info("Power enable: %d\n", true); + + mutex_lock(&ist30xx_mutex); + ist30xx_internal_resume(ts_data); + ist30xx_enable_irq(ts_data); + mutex_unlock(&ist30xx_mutex); + + ist30xx_start(ts_data); + + return 0; +} + +/* sysfs: /sys/class/touch/sys/power_off */ +ssize_t ist30xx_power_off_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + tsp_info("Power enable: %d\n", false); + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(ts_data); + ist30xx_internal_suspend(ts_data); + mutex_unlock(&ist30xx_mutex); + + return 0; +} + +extern int ist30xx_max_error_cnt; +/* sysfs: /sys/class/touch/sys/errcnt */ +ssize_t ist30xx_errcnt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int err_cnt; + + sscanf(buf, "%d", &err_cnt); + + if (unlikely(err_cnt < 0)) + return size; + + tsp_info("Request reset error count: %d\n", err_cnt); + + ist30xx_max_error_cnt = err_cnt; + + return size; +} + +#if IST30XX_EVENT_MODE +extern int ist30xx_max_scan_retry; +/* sysfs: /sys/class/touch/sys/scancnt */ +ssize_t ist30xx_scancnt_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int retry; + + sscanf(buf, "%d", &retry); + + if (unlikely(retry < 0)) + return size; + + tsp_info("Timer scan count retry: %d\n", retry); + + ist30xx_max_scan_retry = retry; + + return size; +} + +extern int timer_period_ms; +/* sysfs: /sys/class/touch/sys/timerms */ +ssize_t ist30xx_timerms_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ms; + + sscanf(buf, "%d", &ms); + + if (unlikely((ms < 0) || (ms > 10000))) + return size; + + tsp_info("Timer period ms: %dms\n", ms); + + timer_period_ms = ms; + + return size; +} +#endif + +extern int ist30xx_dbg_level; +/* sysfs: /sys/class/touch/sys/printk */ +ssize_t ist30xx_printk_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int level; + + sscanf(buf, "%d", &level); + + if (unlikely((level < DEV_ERR) || (level > DEV_VERB))) + return size; + + tsp_info("prink log level: %d\n", level); + + ist30xx_dbg_level = level; + + return size; +} + +ssize_t ist30xx_printk_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "prink log level: %d\n", ist30xx_dbg_level); +} + +/* sysfs: /sys/class/touch/sys/printk5 */ +ssize_t ist30xx_printk5_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + tsp_info("prink log level:%d\n", DEV_DEBUG); + + ist30xx_dbg_level = DEV_DEBUG; + + return 0; +} + +/* sysfs: /sys/class/touch/sys/printk6 */ +ssize_t ist30xx_printk6_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + tsp_info("prink log level:%d\n", DEV_VERB); + + ist30xx_dbg_level = DEV_VERB; + + return 0; +} + +/* sysfs: /sys/class/touch/sys/max_touch */ +ssize_t ist30xx_touch_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int finger; + int key; + + sscanf(buf, "%d %d", &finger, &key); + + tsp_info("fingers : %d, keys : %d\n", finger, key); + + ts_data->max_fingers = finger; + ts_data->max_keys = key; + + return size; +} + +extern void ist30xx_scheduled_reset(void); +extern int ist30xx_report_rate; +/* sysfs: /sys/class/touch/sys/touch_rate */ +ssize_t ist30xx_touch_rate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int rate; + + sscanf(buf, "%d", &rate); // us + + if (unlikely(rate > 0xFFFF)) // over 65.5ms + return size; + + tsp_info("touch reporting rate: %d\n", rate); + + ist30xx_report_rate = rate; + + ist30xx_scheduled_reset(); + + return size; +} + +extern int ist30xx_idle_rate; +/* sysfs: /sys/class/touch/sys/idle_rate */ +ssize_t ist30xx_idle_scan_rate_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int rate; + + sscanf(buf, "%d", &rate); // us + + if (unlikely(rate > 0xFFFF)) // over 65.5ms + return size; + + tsp_info("touch idle scan rate: %d\n", rate); + + ist30xx_idle_rate = rate; + + ist30xx_scheduled_reset(); + + return size; +} + +extern void ist30xx_set_ta_mode(bool charging); +/* sysfs: /sys/class/touch/sys/mode_ta */ +ssize_t ist30xx_ta_mode_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int mode; + + sscanf(buf, "%d", &mode); + + if (unlikely((mode != 0) && (mode != 1))) // enable/disable + return size; + + ist30xx_set_ta_mode(mode); + + return size; +} + +extern void ist30xx_set_call_mode(int mode); +/* sysfs: /sys/class/touch/sys/mode_call */ +ssize_t ist30xx_call_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int mode; + + sscanf(buf, "%d", &mode); + + if (unlikely((mode != 0) && (mode != 1))) // enable/disable + return size; + + ist30xx_set_call_mode(mode); + + return size; +} + +extern void ist30xx_set_cover_mode(int mode); +/* sysfs: /sys/class/touch/sys/mode_cover */ +ssize_t ist30xx_cover_mode_store(struct device *dev, + struct device_attribute *attr, const char *buf, size_t size) +{ + int mode; + + sscanf(buf, "%d", &mode); + + if (unlikely((mode != 0) && (mode != 1))) // enable/disable + return size; + + ist30xx_set_cover_mode(mode); + + return size; +} + +#define TUNES_CMD_WRITE (1) +#define TUNES_CMD_READ (2) +#define TUNES_CMD_REG_ENTER (3) +#define TUNES_CMD_REG_EXIT (4) +#define TUNES_CMD_UPDATE_PARAM (5) +#define TUNES_CMD_UPDATE_FW (6) + +#define DIRECT_ADDR(n) (IST30XXB_DA_ADDR(n)) +#define DIRECT_CMD_WRITE ('w') +#define DIRECT_CMD_READ ('r') + +#pragma pack(1) +typedef struct { + u8 cmd; + u32 addr; + u16 len; +} TUNES_INFO; +#pragma pack() +#pragma pack(1) +typedef struct { + char cmd; + u32 addr; + u32 val; +} DIRECT_INFO; +#pragma pack() + +static TUNES_INFO ist30xx_tunes; +static DIRECT_INFO ist30xx_direct; +static bool tunes_cmd_done = false; +static bool ist30xx_reg_mode = false; + +/* sysfs: /sys/class/touch/sys/direct */ +ssize_t ist30xxb_direct_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = -EPERM; + DIRECT_INFO *direct = (DIRECT_INFO *)&ist30xx_direct; + + sscanf(buf, "%c %x %x", &direct->cmd, &direct->addr, &direct->val); + + tsp_debug("Direct cmd: %c, addr: %x, val: %x\n", + direct->cmd, direct->addr, direct->val); + + if (unlikely((direct->cmd != DIRECT_CMD_WRITE) && + (direct->cmd != DIRECT_CMD_READ))) { + tsp_warn("Direct cmd is not correct!\n"); + return size; + } + + if (ist30xx_intr_wait(30) < 0) + return size; + + ts_data->status.event_mode = false; + if (direct->cmd == DIRECT_CMD_WRITE) { + ret = ist30xx_write_cmd(ts_data->client, DIRECT_ADDR(direct->addr), + direct->val); + ret = ist30xx_read_cmd(ts_data->client, DIRECT_ADDR(direct->addr), + &direct->val); + tsp_debug("Direct write addr: %x, val: %x\n", + direct->addr, direct->val); + } + ts_data->status.event_mode = true; + + return size; +} + +#define DIRECT_BUF_COUNT (4) +ssize_t ist30xxb_direct_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i, ret, count = 0; + int len; + u32 addr; + u32 buf32[DIRECT_BUF_COUNT]; + int max_len = DIRECT_BUF_COUNT; + const int msg_len = 256; + char msg[msg_len]; + + DIRECT_INFO *direct = (DIRECT_INFO *)&ist30xx_direct; + + if (unlikely(direct->cmd != DIRECT_CMD_READ)) + return sprintf(buf, "ex) echo r addr len > direct\n"); + + len = direct->val; + addr = DIRECT_ADDR(direct->addr); + + if (ist30xx_intr_wait(30) < 0) + return 0; + ts_data->status.event_mode = false; + while (len > 0) { + if (len < max_len) max_len = len; + + memset(buf32, 0, sizeof(buf32)); + ret = ist30xxb_burst_read(ts_data->client, addr, buf32, max_len); + if (unlikely(ret)) { + count = sprintf(buf, "I2C Burst read fail, addr: %x\n", addr); + break; + } + + for (i = 0; i < max_len; i++) { + count += snprintf(msg, msg_len, "0x%08x ", buf32[i]); + strncat(buf, msg, msg_len); + } + count += snprintf(msg, msg_len, "\n"); + strncat(buf, msg, msg_len); + + addr += max_len * IST30XX_DATA_LEN; + len -= max_len; + } + ts_data->status.event_mode = true; + + tsp_debug("%s", buf); + + return count; +} + +/* sysfs: /sys/class/touch/tunes/node_info */ +ssize_t tunes_node_info_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int size; + TSP_INFO *tsp = &ist30xx_tsp_info; + TKEY_INFO *tkey = &ist30xx_tkey_info; + + size = sprintf(buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d ", + ts_data->chip_id, tsp->dir.swap_xy, tsp->ch_num.tx, tsp->ch_num.rx, + tsp->baseline, tkey->axis_rx, tkey->enable, tkey->baseline, + tkey->ch_num[0], tkey->ch_num[1], + tkey->ch_num[2], tkey->ch_num[3], tkey->ch_num[4]); + + return size; +} + +/* sysfs: /sys/class/touch/tunes/regcmd */ +ssize_t tunes_regcmd_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret = -1; + u32 *buf32; + + memcpy(&ist30xx_tunes, buf, sizeof(ist30xx_tunes)); + buf += sizeof(ist30xx_tunes); + buf32 = (u32 *)buf; + + tunes_cmd_done = false; + + switch (ist30xx_tunes.cmd) { + case TUNES_CMD_WRITE: + break; + case TUNES_CMD_READ: + break; + case TUNES_CMD_REG_ENTER: + ist30xx_disable_irq(ts_data); + ist30xx_reset(false); + + /* enter reg access mode */ + ret = ist30xx_cmd_reg(ts_data->client, CMD_ENTER_REG_ACCESS); + if (unlikely(ret)) + goto regcmd_fail; + + ist30xx_reg_mode = true; + + break; + case TUNES_CMD_REG_EXIT: + /* exit reg access mode */ + ret = ist30xx_cmd_reg(ts_data->client, CMD_EXIT_REG_ACCESS); + if (unlikely(ret)) + goto regcmd_fail; + + ret = ist30xx_cmd_start_scan(ts_data->client); + if (unlikely(ret)) + goto regcmd_fail; + + ist30xx_reg_mode = false; + + ist30xx_enable_irq(ts_data); + break; + default: + ist30xx_enable_irq(ts_data); + return size; + } + tunes_cmd_done = true; + + return size; + +regcmd_fail: + tsp_err("Tunes regcmd i2c_fail, ret=%d\n", ret); + return size; +} + +ssize_t tunes_regcmd_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int size; + + size = sprintf(buf, "cmd: 0x%02x, addr: 0x%08x, len: 0x%04x\n", + ist30xx_tunes.cmd, ist30xx_tunes.addr, ist30xx_tunes.len); + + return size; +} + +#define MAX_WRITE_LEN (1) +/* sysfs: /sys/class/touch/tunes/reg */ +ssize_t tunes_reg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + u32 *buf32 = (u32 *)buf; + int waddr, wcnt = 0, len = 0; + + if (unlikely(ist30xx_tunes.cmd != TUNES_CMD_WRITE)) { + tsp_err("error, IST30XX_REG_CMD is not correct!\n"); + return size; + } + + if (unlikely(!ist30xx_reg_mode)) { + tsp_err("error, IST30XX_REG_CMD is not ready!\n"); + return size; + } + + if (unlikely(!tunes_cmd_done)) { + tsp_err("error, IST30XX_REG_CMD is not ready!\n"); + return size; + } + + waddr = ist30xx_tunes.addr; + if (ist30xx_tunes.len >= MAX_WRITE_LEN) + len = MAX_WRITE_LEN; + else + len = ist30xx_tunes.len; + + while (wcnt < ist30xx_tunes.len) { + ret = ist30xx_write_buf(ts_data->client, waddr, buf32, len); + if (unlikely(ret)) { + tsp_err("Tunes regstore i2c_fail, ret=%d\n", ret); + return size; + } + + wcnt += len; + + if ((ist30xx_tunes.len - wcnt) < MAX_WRITE_LEN) + len = ist30xx_tunes.len - wcnt; + + buf32 += MAX_WRITE_LEN; + waddr += MAX_WRITE_LEN * IST30XX_DATA_LEN; + } + + tunes_cmd_done = false; + + return size; +} + +ssize_t tunes_reg_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + int size; + u32 *buf32 = (u32 *)buf; + +#if I2C_MONOPOLY_MODE + unsigned long flags; +#endif + + if (unlikely(ist30xx_tunes.cmd != TUNES_CMD_READ)) { + tsp_err("error, IST30XX_REG_CMD is not correct!\n"); + return 0; + } + + if (unlikely(!tunes_cmd_done)) { + tsp_err("error, IST30XX_REG_CMD is not ready!\n"); + return 0; + } + + size = ist30xx_tunes.len; + ret = ist30xx_write_cmd(ts_data->client, IST30XX_RX_CNT_ADDR, size); + if (unlikely(ret)) { + tsp_err("Tunes regshow i2c_fail, ret=%d\n", ret); + return 0; + } + +#if I2C_MONOPOLY_MODE + local_irq_save(flags); // Activated only when the GPIO I2C is used +#endif + ret = ist30xx_read_buf(ts_data->client, ist30xx_tunes.addr, buf32, size); +#if I2C_MONOPOLY_MODE + local_irq_restore(flags); // Activated only when the GPIO I2C is used +#endif + if (unlikely(ret)) { + tsp_err("Tunes regshow i2c_fail, ret=%d\n", ret); + return size; + } + + size = ist30xx_tunes.len * IST30XX_DATA_LEN; + + tunes_cmd_done = false; + + return size; +} + +/* sysfs: /sys/class/touch/tunes/adb */ +ssize_t tunes_adb_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + char *tmp, *ptr; + char token[9]; + u32 cmd, addr, len, val; + int write_len; + + sscanf(buf, "%x %x %x", &cmd, &addr, &len); + + switch (cmd) { + case TUNES_CMD_WRITE: /* write cmd */ + write_len = 0; + ptr = (char *)(buf + 15); + + while (write_len < len) { + memcpy(token, ptr, 8); + token[8] = 0; + val = simple_strtoul(token, &tmp, 16); + ret = ist30xx_write_buf(ts_data->client, addr, &val, 1); + if (unlikely(ret)) { + tsp_err("Tunes regstore i2c_fail, ret=%d\n", ret); + return size; + } + + ptr += 8; + write_len++; + addr += 4; + } + break; + + case TUNES_CMD_READ: /* read cmd */ + ist30xx_tunes.cmd = cmd; + ist30xx_tunes.addr = addr; + ist30xx_tunes.len = len; + break; + + case TUNES_CMD_REG_ENTER: /* enter */ + ist30xx_disable_irq(ts_data); + ist30xx_reset(false); + + ret = ist30xx_cmd_reg(ts_data->client, CMD_ENTER_REG_ACCESS); + if (unlikely(ret < 0)) + goto cmd_fail; + ist30xx_reg_mode = true; + break; + + case TUNES_CMD_REG_EXIT: /* exit */ + if (ist30xx_reg_mode == true) { + ret = ist30xx_cmd_reg(ts_data->client, CMD_EXIT_REG_ACCESS); + if (unlikely(ret < 0)) + goto cmd_fail; + + ret = ist30xx_cmd_start_scan(ts_data->client); + if (unlikely(ret < 0)) + goto cmd_fail; + ist30xx_reg_mode = false; + ist30xx_enable_irq(ts_data); + } + break; + + default: + break; + } + + return size; + +cmd_fail: + tsp_err("Tunes adb i2c_fail\n"); + return size; +} + +ssize_t tunes_adb_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + int i, len, size = 0; + char reg_val[10]; + +#if I2C_MONOPOLY_MODE + unsigned long flags; +#endif + + ret = ist30xx_write_cmd(ts_data->client, IST30XX_RX_CNT_ADDR, + ist30xx_tunes.len); + if (unlikely(ret)) { + tsp_err("Tunes adbshow i2c_fail, ret=%d\n", ret); + return size; + } + +#if I2C_MONOPOLY_MODE + local_irq_save(flags); +#endif + ret = ist30xx_read_buf(ts_data->client, ist30xx_tunes.addr, + ist30xx_frame_buf, ist30xx_tunes.len); +#if I2C_MONOPOLY_MODE + local_irq_restore(flags); +#endif + if (unlikely(ret)) { + tsp_err("Tunes adbshow i2c_fail, ret=%d\n", ret); + return size; + } + + size = 0; + buf[0] = 0; + len = sprintf(reg_val, "%08x", ist30xx_tunes.addr); + strcat(buf, reg_val); + size += len; + for (i = 0; i < ist30xx_tunes.len; i++) { + len = sprintf(reg_val, "%08x", ist30xx_frame_buf[i]); + strcat(buf, reg_val); + size += len; + } + + return size; +} + +#if IST30XX_ALGORITHM_MODE +/* sysfs: /sys/class/touch/tunes/algorithm */ +extern u32 ist30xx_algr_addr, ist30xx_algr_size; +ssize_t ist30xx_algr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + sscanf(buf, "%x %d", &ist30xx_algr_addr, &ist30xx_algr_size); + + tsp_info("Algorithm addr: 0x%x, count: %d\n", + ist30xx_algr_addr, ist30xx_algr_size); + + ist30xx_algr_addr |= IST30XXB_ACCESS_ADDR; + + return size; +} + +ssize_t ist30xx_algr_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int ret; + u32 algr_addr; + int count = 0; + + ret = ist30xx_read_cmd(ts_data->client, IST30XXB_MEM_ALGORITHM, &algr_addr); + if (unlikely(ret)) { + tsp_warn("Algorithm mem addr read fail!\n"); + return 0; + } + + tsp_info("algr_addr(0x%x): 0x%x\n", IST30XXB_MEM_ALGORITHM, algr_addr); + + count = sprintf(buf, "Algorithm addr : 0x%x\n", algr_addr); + + return count; +} +#endif // IST30XX_ALGORITHM_MODE + +/* sysfs: /sys/class/touch/tunes/intr_debug */ +extern u32 intr_debug_addr, intr_debug_size; +ssize_t intr_debug_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + sscanf(buf, "%x %d", &intr_debug_addr, &intr_debug_size); + tsp_info("Interrupt debug addr: 0x%x, count: %d\n", + intr_debug_addr, intr_debug_size); + + intr_debug_addr |= IST30XXB_ACCESS_ADDR; + + return size; +} + +ssize_t intr_debug_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + + tsp_info("intr_debug_addr(0x%x): %d\n", intr_debug_addr, intr_debug_size); + + count = sprintf(buf, "intr_debug_addr(0x%x): %d\n", + intr_debug_addr, intr_debug_size); + + return count; +} + +/* sysfs: /sys/class/touch/tunes/intr_debug2 */ +extern u32 intr_debug2_addr, intr_debug2_size; +ssize_t intr_debug2_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + sscanf(buf, "%x %d", &intr_debug2_addr, &intr_debug2_size); + tsp_info("Interrupt debug2 addr: 0x%x, count: %d\n", + intr_debug2_addr, intr_debug2_size); + + intr_debug2_addr |= IST30XXB_ACCESS_ADDR; + + return size; +} + +ssize_t intr_debug2_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + + tsp_info("intr_debug2_addr(0x%x): %d\n", + intr_debug2_addr, intr_debug2_size); + + count = sprintf(buf, "intr_debug2_addr(0x%x): %d\n", + intr_debug2_addr, intr_debug2_size); + + return count; +} + +/* sysfs: /sys/class/touch/tunes/intr_debug3 */ +extern u32 intr_debug3_addr, intr_debug3_size; +ssize_t intr_debug3_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + sscanf(buf, "%x %d", &intr_debug3_addr, &intr_debug3_size); + tsp_info("Interrupt debug3 addr: 0x%x, count: %d\n", + intr_debug3_addr, intr_debug3_size); + + intr_debug3_addr |= IST30XXB_ACCESS_ADDR; + + return size; +} + +ssize_t intr_debug3_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int count = 0; + + tsp_info("intr_debug3_addr(0x%x): %d\n", + intr_debug3_addr, intr_debug3_size); + + count = sprintf(buf, "intr_debug3_addr(0x%x): %d\n", + intr_debug3_addr, intr_debug3_size); + + return count; +} + +#if IST30XX_CHKIC +u8 *ts_chkic_bin = NULL; +u32 ts_chkic_bin_size = 0; +u32 ts_chkic_result = 0; + +int chkic_ms_delay = IST30XX_CHKIC_WAIT; +int ist30xx_chkic_wait(void) +{ + int cnt = chkic_ms_delay; + + ts_data->status.chkic_msg = 0; + while (cnt-- > 0) { + msleep(100); + + if (ts_data->status.chkic_msg) { + if (ts_data->status.chkic_msg == IST30XX_CHKIC_END) + return 0; + else + return -EAGAIN; + } + } + tsp_warn("Fault test time out\n"); + + return -EPERM; +} + +#define chkic_next_step(ret) { if (unlikely(ret)) goto end; msleep(5); } +int ist30xx_chkic_test(const u8 *buf, int size) +{ + int ret; + int len; + u32 chksum = 0; + u32 chkic_chksum = 0; + u32 *buf32; + struct i2c_client *client = (struct i2c_client *)ts_data->client; + + tsp_info("*** Check IC ***\n"); + + /* Result initial */ + ts_chkic_result = 0; + + /* Parse chkicsum */ + chkic_chksum = *((u32 *)&buf[size - IST30XX_CHECKSUM_SIZE]); + tsp_verb("Read binary info - chksum: 0x%08x size: 0x%x\n", + chkic_chksum, size); + + ist30xx_disable_irq(ts_data); + + ist30xx_reset(false); + + /* Load IC chkic test code */ + ret = ist30xx_write_cmd(client, CMD_EXEC_MEM_CODE, 0); + chkic_next_step(ret); + + buf32 = (u32 *)buf; + len = size / IST30XX_DATA_LEN; + tsp_verb("%08x %08x %08x %08x\n", buf32[0], buf32[1], buf32[2], buf32[3]); + ret = ist30xx_write_buf(client, len, buf32, len); + chkic_next_step(ret); + + /* Check load end */ + ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); + chkic_next_step(ret); + if (chksum != IST30XX_CHKIC_LOAD_END) + goto end; + tsp_info("Check ic code ready!!\n"); + + /* Check chksum */ + ret = ist30xx_read_cmd(client, CMD_DEFAULT, &chksum); + chkic_next_step(ret); + tsp_info("Check ic chksum: %08x, %08x\n", chksum, chkic_chksum); + + ist30xx_enable_irq(ts_data); + /* Wait IC chkic result */ + if (ist30xx_chkic_wait() != 0) + tsp_info("Check ic timeout!!\n"); + + ist30xx_disable_irq(ts_data); + + /* Read IC chkic result */ + ret = ist30xx_read_cmd(client, CMD_DEFAULT, &ts_chkic_result); + chkic_next_step(ret); + tsp_info("Read result value: %08x\n", ts_chkic_result); + + ist30xx_reset(false); + + ist30xx_start(ts_data); + +end: + if (unlikely(ret)) { + tsp_warn("Check ic error, ret=%d\n", ret); + } else if (unlikely(chksum != chkic_chksum)) { + tsp_warn("Chksum error, chksum=%x(%x)\n", chksum, chkic_chksum); + ret = -ENOEXEC; + } + + ist30xx_enable_irq(ts_data); + + return ret; +} + +/* sysfs: /sys/class/touch/chkic/chkic */ +static ssize_t ist30xx_chkic_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret; + + if ((ts_chkic_bin == NULL) || (ts_chkic_bin_size == 0)) + return sprintf(buf, "Binary is not correct(%d)\n", ts_chkic_bin_size); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_chkic_test(ts_chkic_bin, ts_chkic_bin_size); + mutex_unlock(&ist30xx_mutex); + + if (ts_chkic_result == IST30XX_CHKIC_OK) + return sprintf(buf, "Check IC : OK"); + else if (ts_chkic_result == IST30XX_CHKIC_FAIL) + return sprintf(buf, "Check IC : FAIL"); + else + return sprintf(buf, "Check IC : ERROR"); +} +#endif + +/* sysfs : node */ +static DEVICE_ATTR(refresh, S_IRWXUGO, ist30xx_frame_refresh, NULL); +static DEVICE_ATTR(nocp, S_IRWXUGO, ist30xx_frame_nocp, NULL); +static DEVICE_ATTR(filter, S_IRWXUGO, ist30xx_filter_show, NULL); +static DEVICE_ATTR(raw, S_IRWXUGO, ist30xx_raw_show, NULL); +static DEVICE_ATTR(base, S_IRWXUGO, ist30xx_base_show, NULL); +static DEVICE_ATTR(diff, S_IRWXUGO, ist30xx_diff_show, NULL); + +/* sysfs : sys */ +static DEVICE_ATTR(printk, S_IRWXUGO, + ist30xx_printk_show, ist30xx_printk_store); +static DEVICE_ATTR(printk5, S_IRWXUGO, ist30xx_printk5_show, NULL); +static DEVICE_ATTR(printk6, S_IRWXUGO, ist30xx_printk6_show, NULL); +static DEVICE_ATTR(direct, S_IRWXUGO, + ist30xxb_direct_show, ist30xxb_direct_store); +static DEVICE_ATTR(clb_time, S_IRWXUGO, NULL, ist30xx_calib_time_store); +static DEVICE_ATTR(clb, S_IRWXUGO, ist30xx_calib_show, NULL); +static DEVICE_ATTR(clb_result, S_IRWXUGO, ist30xx_calib_result_show, NULL); +static DEVICE_ATTR(tsp_power_on, S_IRWXUGO, ist30xx_power_on_show, NULL); +static DEVICE_ATTR(tsp_power_off, S_IRWXUGO, ist30xx_power_off_show, NULL); +static DEVICE_ATTR(errcnt, S_IRWXUGO, NULL, ist30xx_errcnt_store); +#if IST30XX_EVENT_MODE +static DEVICE_ATTR(scancnt, S_IRWXUGO, NULL, ist30xx_scancnt_store); +static DEVICE_ATTR(timerms, S_IRWXUGO, NULL, ist30xx_timerms_store); +#endif +static DEVICE_ATTR(report_rate, S_IRWXUGO, NULL, ist30xx_touch_rate_store); +static DEVICE_ATTR(idle_rate, S_IRWXUGO, NULL, ist30xx_idle_scan_rate_store); +static DEVICE_ATTR(mode_ta, S_IRWXUGO, NULL, ist30xx_ta_mode_store); +static DEVICE_ATTR(mode_call, S_IRWXUGO, NULL, ist30xx_call_mode_store); +static DEVICE_ATTR(mode_cover, S_IRWXUGO, NULL, ist30xx_cover_mode_store); +static DEVICE_ATTR(max_touch, S_IRWXUGO, NULL, ist30xx_touch_store); + +/* sysfs : tunes */ +static DEVICE_ATTR(node_info, S_IRWXUGO, tunes_node_info_show, NULL); +static DEVICE_ATTR(regcmd, S_IRWXUGO, tunes_regcmd_show, tunes_regcmd_store); +static DEVICE_ATTR(reg, S_IRWXUGO, tunes_reg_show, tunes_reg_store); +static DEVICE_ATTR(adb, S_IRWXUGO, tunes_adb_show, tunes_adb_store); +#if IST30XX_ALGORITHM_MODE +static DEVICE_ATTR(algorithm, S_IRWXUGO, ist30xx_algr_show, ist30xx_algr_store); +#endif +static DEVICE_ATTR(intr_debug, S_IRWXUGO, intr_debug_show, intr_debug_store); +static DEVICE_ATTR(intr_debug2, S_IRWXUGO, intr_debug2_show, intr_debug2_store); +static DEVICE_ATTR(intr_debug3, S_IRWXUGO, intr_debug3_show, intr_debug3_store); + +#if IST30XX_CHKIC +/* sysfs : chkic */ +static DEVICE_ATTR(chkic, S_IRUGO, ist30xx_chkic_show, NULL); +#endif + +static struct attribute *node_attributes[] = { + &dev_attr_refresh.attr, + &dev_attr_nocp.attr, + &dev_attr_filter.attr, + &dev_attr_raw.attr, + &dev_attr_base.attr, + &dev_attr_diff.attr, + NULL, +}; + +static struct attribute *sys_attributes[] = { + &dev_attr_printk.attr, + &dev_attr_printk5.attr, + &dev_attr_printk6.attr, + &dev_attr_direct.attr, + &dev_attr_clb_time.attr, + &dev_attr_clb.attr, + &dev_attr_clb_result.attr, + &dev_attr_tsp_power_on.attr, + &dev_attr_tsp_power_off.attr, + &dev_attr_errcnt.attr, +#if IST30XX_EVENT_MODE + &dev_attr_scancnt.attr, + &dev_attr_timerms.attr, +#endif + &dev_attr_report_rate.attr, + &dev_attr_idle_rate.attr, + &dev_attr_mode_ta.attr, + &dev_attr_mode_call.attr, + &dev_attr_mode_cover.attr, + &dev_attr_max_touch.attr, + NULL, +}; + +static struct attribute *tunes_attributes[] = { + &dev_attr_node_info.attr, + &dev_attr_regcmd.attr, + &dev_attr_reg.attr, + &dev_attr_adb.attr, +#if IST30XX_ALGORITHM_MODE + &dev_attr_algorithm.attr, +#endif + &dev_attr_intr_debug.attr, + &dev_attr_intr_debug2.attr, + &dev_attr_intr_debug3.attr, + NULL, +}; + +#if IST30XX_CHKIC +static struct attribute *chkic_attributes[] = { + &dev_attr_chkic.attr, + NULL, +}; +#endif + +static struct attribute_group node_attr_group = { + .attrs = node_attributes, +}; + +static struct attribute_group sys_attr_group = { + .attrs = sys_attributes, +}; + +static struct attribute_group tunes_attr_group = { + .attrs = tunes_attributes, +}; + +#if IST30XX_CHKIC +static struct attribute_group chkic_attr_group = { + .attrs = chkic_attributes, +}; +#endif + +extern struct class *ist30xx_class; +struct device *ist30xx_sys_dev; +struct device *ist30xx_tunes_dev; +struct device *ist30xx_node_dev; +#if IST30XX_CHKIC +struct device *ist30xx_chkic_dev; +#endif + +int ist30xx_init_misc_sysfs(void) +{ + /* /sys/class/touch/sys */ + ist30xx_sys_dev = device_create(ist30xx_class, NULL, 0, NULL, "sys"); + + /* /sys/class/touch/sys/... */ + if (unlikely(sysfs_create_group(&ist30xx_sys_dev->kobj, + &sys_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "sys"); + + /* /sys/class/touch/tunes */ + ist30xx_tunes_dev = device_create(ist30xx_class, NULL, 0, NULL, "tunes"); + + /* /sys/class/touch/tunes/... */ + if (unlikely(sysfs_create_group(&ist30xx_tunes_dev->kobj, + &tunes_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "tunes"); + + /* /sys/class/touch/node */ + ist30xx_node_dev = device_create(ist30xx_class, NULL, 0, NULL, "node"); + + /* /sys/class/touch/node/... */ + if (unlikely(sysfs_create_group(&ist30xx_node_dev->kobj, + &node_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "node"); + +#if IST30XX_CHKIC + /* /sys/class/touch/chkic */ + ist30xx_chkic_dev = device_create(ist30xx_class, NULL, 0, NULL, "chkic"); + + /* /sys/class/touch/chkic/... */ + if (unlikely(sysfs_create_group(&ist30xx_chkic_dev->kobj, + &chkic_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "chkic"); + + ts_chkic_bin = (u8 *)ist30xxb_chkic; + ts_chkic_bin_size = sizeof(ist30xxb_chkic); +#endif + + ist30xx_frame_buf = kmalloc(4096, GFP_KERNEL); + ist30xx_frame_rawbuf = kmalloc(4096, GFP_KERNEL); + ist30xx_frame_fltbuf = kmalloc(4096, GFP_KERNEL); + if (!ist30xx_frame_buf || !ist30xx_frame_rawbuf || !ist30xx_frame_fltbuf) + return -ENOMEM; + + return 0; +} diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_misc.h b/drivers/input/touchscreen/ist30xxa/ist30xx_misc.h new file mode 100644 index 00000000..9313f8b1 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_misc.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XX_MISC_H__ +#define __IST30XX_MISC_H__ + +#include "ist30xx_tsp.h" + +#define IST30XXB_RAW_ADDR (0x40100200) +#define IST30XXB_FILTER_ADDR (0x40101000) + +#define IST30XX_RX_CNT_ADDR (0x20000038) +#define IST30XX_CONFIG_ADDR (0x20000040) + +#define NODE_FLAG_RAW (1) +#define NODE_FLAG_BASE (1 << 1) +#define NODE_FLAG_FILTER (1 << 2) +#define NODE_FLAG_DIFF (1 << 3) +#define NODE_FLAG_ALL (0xF) +#define NODE_FLAG_NO_CCP (1 << 7) + +#if IST30XX_CHKIC +#define IST30XX_CHKIC_LOAD_END (0x8FFFFCAB) +#define IST30XX_CHKIC_END (0x8FAB0FAB) + +#define IST30XX_CHECKSUM_SIZE (4) +#define IST30XX_CHKIC_OK (0x00000001) +#define IST30XX_CHKIC_FAIL (0x000000FF) + +#define IST30XX_CHKIC_WAIT (30) // 3.0sec +#endif + +struct TSP_CH_NUM { + u8 tx; + u8 rx; +}; +struct TSP_NODE_BUF { + u16 raw[NODE_TX_NUM][NODE_RX_NUM]; + u16 base[NODE_TX_NUM][NODE_RX_NUM]; + u16 filter[NODE_TX_NUM][NODE_RX_NUM]; + u16 min_raw; + u16 max_raw; + u16 min_base; + u16 max_base; + u16 len; +}; +struct TSP_DIRECTION { + bool swap_xy; + bool flip_x; + bool flip_y; +}; +typedef struct _TSP_INFO { + struct TSP_CH_NUM ch_num; + struct TSP_DIRECTION dir; + struct TSP_NODE_BUF node; + int height; + int width; + int finger_num; + u16 baseline; +} TSP_INFO; +typedef struct _TKEY_INFO { + int key_num; + bool enable; + bool axis_rx; + u8 axis_chnum; + u8 ch_num[5]; + u16 baseline; +} TKEY_INFO; + +int ist30xx_parse_touch_node(u8 flag, struct TSP_NODE_BUF *node); +int ist30xx_read_touch_node(u8 flag, struct TSP_NODE_BUF *node); + +int ist30xx_tsp_update_info(void); +int ist30xx_tkey_update_info(void); + +int ist30xx_get_tsp_info(struct ist30xx_data *data); +int ist30xx_get_tkey_info(struct ist30xx_data *data); + +int ist30xx_init_misc_sysfs(void); + +#endif // __IST30XX_MISC_H__ diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_sec.c b/drivers/input/touchscreen/ist30xxa/ist30xx_sec.c new file mode 100644 index 00000000..e8fae499 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_sec.c @@ -0,0 +1,916 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + + +#include <linux/mutex.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/stat.h> +#include <linux/err.h> + +#include "ist30xx.h" +#include "ist30xx_update.h" +#include "ist30xx_misc.h" + + +static char IsfwUpdate[20] = { 0 }; + +#define FW_DOWNLOADING "Downloading" +#define FW_DOWNLOAD_COMPLETE "Complete" +#define FW_DOWNLOAD_FAIL "FAIL" + +#define FACTORY_BUF_SIZE (1024) +#define BUILT_IN (0) +#define UMS (1) + +#define CMD_STATE_WAITING (0) +#define CMD_STATE_RUNNING (1) +#define CMD_STATE_OK (2) +#define CMD_STATE_FAIL (3) +#define CMD_STATE_NA (4) + +#define TSP_NODE_DEBUG (1) + +static u16 node_value[TSP_TOTAL_NUM]; + +extern struct ist30xx_data *ts_data; +extern TSP_INFO ist30xx_tsp_info; +extern TKEY_INFO ist30xx_tkey_info; + + +#define TSP_CMD(name, func) .cmd_name = name, .cmd_func = func +struct tsp_cmd { + struct list_head list; + const char * cmd_name; + void (*cmd_func)(void *dev_data); +}; + +u32 ist30xxb_get_fw_ver(struct ist30xx_data *data) +{ + u32 addr = data->tags.cfg_addr + 4; + u32 len = 1; + u32 ver = 0; + int ret = -EPERM; + + ist30xx_disable_irq(data); + ret = ist30xx_cmd_reg(data->client, CMD_ENTER_REG_ACCESS); + if (unlikely(ret)) + goto get_fw_ver_fail; + + ret = ist30xx_write_cmd(data->client, IST30XX_RX_CNT_ADDR, len); + if (unlikely(ret)) + goto get_fw_ver_fail; + + ret = ist30xx_read_cmd(data->client, addr, &ver); + if (unlikely(ret)) + goto get_fw_ver_fail; + + tsp_debug("Reg addr: %x, ver: %x\n", addr, ver); + + ret = ist30xx_cmd_reg(data->client, CMD_EXIT_REG_ACCESS); + if (likely(ret == 0)) + goto get_fw_ver_end; + +get_fw_ver_fail: + ist30xx_reset(false); + +get_fw_ver_end: + ist30xx_cmd_start_scan(data->client); + ist30xx_enable_irq(data); + + return ver; +} + +u32 key_sensitivity = 0; +int ist30xxb_get_key_sensitivity(struct ist30xx_data *data, int id) +{ + u32 addr = IST30XXB_MEM_KEYSENSITIVITY + 4 * sizeof(u32); + u32 val = 0; + + if (unlikely(id >= ist30xx_tkey_info.key_num)) + return 0; + + if (ist30xx_intr_wait(30) < 0) + return 0; + + ist30xx_read_cmd(data->client, addr, &val); + if ((val & 0xFFF) == 0xFFF) + return (key_sensitivity >> (16 * id)) & 0xFFFF; + + key_sensitivity = val; + + tsp_debug("Reg addr: %x, val: %8x\n", addr, val); + + val >>= (16 * id); + + return (int)(val & 0xFFFF); +} + + +/* Factory CMD function */ +static void set_default_result(struct sec_factory *sec) +{ + char delim = ':'; + + memset(sec->cmd_result, 0, ARRAY_SIZE(sec->cmd_result)); + memcpy(sec->cmd_result, sec->cmd, strlen(sec->cmd)); + strncat(sec->cmd_result, &delim, CMD_STATE_RUNNING); +} + +static void set_cmd_result(struct sec_factory *sec, char *buf, int len) +{ + strncat(sec->cmd_result, buf, len); +} + +static void not_support_cmd(void *dev_data) +{ + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + snprintf(buf, sizeof(buf), "%s", "NA"); + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_NA; + dev_info(&data->client->dev, "%s: \"%s(%d)\"\n", __func__, + buf, strnlen(buf, sizeof(buf))); + return; +} + +static void get_chip_vendor(void *dev_data) +{ + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + snprintf(buf, sizeof(buf), "%s", TSP_CHIP_VENDOR); + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, + buf, strnlen(buf, sizeof(buf))); +} + +static void get_chip_name(void *dev_data) +{ + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + snprintf(buf, sizeof(buf), "%s", TSP_CHIP_NAME); + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, + buf, strnlen(buf, sizeof(buf))); +} + +static void get_chip_id(void *dev_data) +{ + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + snprintf(buf, sizeof(buf), "%#02x", data->chip_id); + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, + buf, strnlen(buf, sizeof(buf))); +} +#include <linux/uaccess.h> +#define MAX_FW_PATH 255 +extern u32 ist30xx_fw_ver; +extern u32 ist30xx_param_ver; +extern u32 ist30xx_sub_ver; +static void fw_update(void *dev_data) +{ + int ret; + char buf[16] = { 0 }; + mm_segment_t old_fs = {0}; + struct file *fp = NULL; + long fsize = 0, nread = 0; + u8 *fw; + char fw_path[MAX_FW_PATH+1]; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + tsp_info("%s(), %d\n", __func__, sec->cmd_param[0]); + + switch (sec->cmd_param[0]) { + case BUILT_IN: + sec->cmd_state = CMD_STATE_OK; + ret = ist30xx_fw_recovery(data); + if (ret < 0) + sec->cmd_state = CMD_STATE_FAIL; + break; + case UMS: + sec->cmd_state = CMD_STATE_OK; + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FW_PATH, "/sdcard/%s", IST30XXB_FW_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + tsp_warn("%s(), file %s open error:%d\n", __func__, + fw_path, (s32)fp); + sec->cmd_state= CMD_STATE_FAIL; + set_fs(old_fs); + break; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + if (fsize != data->fw.buf_size) { + tsp_warn("%s(), invalid fw size!!\n", __func__); + sec->cmd_state = CMD_STATE_FAIL; + set_fs(old_fs); + break; + } + fw = kzalloc((size_t)fsize, GFP_KERNEL); + if (!fw) { + tsp_warn("%s(), failed to alloc buffer for fw\n", __func__); + sec->cmd_state = CMD_STATE_FAIL; + filp_close(fp, NULL); + set_fs(old_fs); + break; + } + nread = vfs_read(fp, (char __user *)fw, fsize, &fp->f_pos); + if (nread != fsize) { + tsp_warn("%s(), failed to read fw\n", __func__); + sec->cmd_state = CMD_STATE_FAIL; + filp_close(fp, NULL); + set_fs(old_fs); + break; + } + + filp_close(fp, current->files); + set_fs(old_fs); + tsp_info("%s(), ums fw is loaded!!\n", __func__); + + ist30xx_get_update_info(ts_data, fw, fsize); + ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw); + ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw); + ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw); + + mutex_lock(&ist30xx_mutex); + ist30xx_fw_update(data->client, fw, fsize, true); + mutex_unlock(&ist30xx_mutex); + + ist30xx_calibrate(1); + break; + + default: + tsp_warn("%s(), Invalid fw file type!\n", __func__); + break; + } + + if (sec->cmd_state == CMD_STATE_OK) + snprintf(buf, sizeof(buf), "%s", "OK"); + else + snprintf(buf, sizeof(buf), "%s", "NG"); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); +} + + +static void get_fw_ver_bin(void *dev_data) +{ + u32 ver = 0; + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + ver = ist30xx_parse_ver(FLAG_PARAM, data->fw.buf); + snprintf(buf, sizeof(buf), "IM00%04x", ver); + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, + buf, strnlen(buf, sizeof(buf))); +} + +static void get_fw_ver_ic(void *dev_data) +{ + u32 ver = 0; + char msg[8]; + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + if (data->status.power == 1) + ver = ist30xxb_get_fw_ver(ts_data); + + snprintf(buf, sizeof(buf), "IM00%04x", ver & 0xFFFF); + + if (data->fw.sub_ver > 0) { + sprintf(msg, "(T%d)", data->fw.sub_ver); + strcat(buf, msg); + } + + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, + buf, strnlen(buf, sizeof(buf))); +} + +static void get_threshold(void *dev_data) +{ + char buf[16] = { 0 }; + int threshold; + u32 *cfg_buf; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + ist30xx_get_update_info(data, data->fw.buf, data->fw.buf_size); + cfg_buf = (u32 *)&data->fw.buf[data->tags.cfg_addr]; + + threshold = (int)(cfg_buf[0x2C / IST30XX_DATA_LEN] & 0xFFFF); + + snprintf(buf, sizeof(buf), "%d", threshold); + tsp_info("%s(), %s\n", __func__, buf); + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, + buf, strnlen(buf, sizeof(buf))); +} + +static void get_x_num(void *dev_data) +{ + int val = ist30xx_tsp_info.width; + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + if (val >= 0) { + snprintf(buf, sizeof(buf), "%u", val); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf, + strnlen(buf, sizeof(buf))); + } else { + snprintf(buf, sizeof(buf), "%s", "NG"); + sec->cmd_state = CMD_STATE_FAIL; + dev_info(&data->client->dev, + "%s: fail to read num of x (%d).\n", __func__, val); + } + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + tsp_info("%s(), %s\n", __func__, buf); +} + +static void get_y_num(void *dev_data) +{ + int val = ist30xx_tsp_info.height; + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + if (val >= 0) { + snprintf(buf, sizeof(buf), "%u", val); + sec->cmd_state = CMD_STATE_OK; + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf, + strnlen(buf, sizeof(buf))); + } else { + snprintf(buf, sizeof(buf), "%s", "NG"); + sec->cmd_state = CMD_STATE_FAIL; + dev_info(&data->client->dev, + "%s: fail to read num of x (%d).\n", __func__, val); + } + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + tsp_info("%s(), %s\n", __func__, buf); +} + +int check_tsp_channel(void *dev_data) +{ + int node = -EPERM; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + TSP_INFO *tsp = &ist30xx_tsp_info; + + if ((sec->cmd_param[0] < 0) || (sec->cmd_param[0] >= tsp->width) || + (sec->cmd_param[1] < 0) || (sec->cmd_param[1] >= tsp->height)) { + dev_info(&data->client->dev, "%s: parameter error: %u,%u\n", + __func__, sec->cmd_param[0], sec->cmd_param[1]); + } else { + node = sec->cmd_param[0] + sec->cmd_param[1] * tsp->width; + dev_info(&data->client->dev, "%s: node = %d\n", __func__, node); + } + + return node; +} + + +extern int parse_tsp_node(u8 flag, struct TSP_NODE_BUF *node, s16 *buf16); +void run_raw_read(void *dev_data) +{ + int i, ret; + int min_val, max_val; + char buf[16] = { 0 }; + u8 flag = NODE_FLAG_RAW; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + TSP_INFO *tsp = &ist30xx_tsp_info; + + set_default_result(sec); + + ret = ist30xx_read_touch_node(flag, &tsp->node); + if (ret) { + sec->cmd_state = CMD_STATE_FAIL; + tsp_warn("%s(), tsp node read fail!\n", __func__); + return; + } + ist30xx_parse_touch_node(flag, &tsp->node); + + ret = parse_tsp_node(flag, &tsp->node, node_value); + if (ret) { + sec->cmd_state = CMD_STATE_FAIL; + tsp_warn("%s(), tsp node parse fail - flag: %d\n", __func__, flag); + return; + } + + min_val = max_val = node_value[0]; + for (i = 0; i < tsp->width * tsp->height; i++) { +#if TSP_NODE_DEBUG + if ((i % tsp->width) == 0) + printk("\n%s %4d: ", IST30XX_DEBUG_TAG, i); + + printk("%4d ", node_value[i]); +#endif + + max_val = max(max_val, (int)node_value[i]); + min_val = min(min_val, (int)node_value[i]); + } + + snprintf(buf, sizeof(buf), "%d,%d", min_val, max_val); + tsp_info("%s(), %s\n", __func__, buf); + + sec->cmd_state = CMD_STATE_OK; + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf, + strnlen(buf, sizeof(buf))); +} + +void get_raw_value(void *dev_data) +{ + int idx = 0; + char buf[16] = { 0 }; + + struct ist30xx_data *data = (struct ist30xx_data *)dev_data; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + set_default_result(sec); + + idx = check_tsp_channel(data); + if (idx < 0) { // Parameter parsing fail + snprintf(buf, sizeof(buf), "%s", "NG"); + sec->cmd_state = CMD_STATE_FAIL; + } else { + snprintf(buf, sizeof(buf), "%d", node_value[idx]); + sec->cmd_state = CMD_STATE_OK; + } + + set_cmd_result(sec, buf, strnlen(buf, sizeof(buf))); + tsp_info("%s(), [%d][%d]: %s\n", __func__, + sec->cmd_param[0], sec->cmd_param[1], buf); + dev_info(&data->client->dev, "%s: %s(%d)\n", __func__, buf, + strnlen(buf, sizeof(buf))); +} + + + +/* sysfs: /sys/class/sec/tsp/close_tsp_test */ +static ssize_t show_close_tsp_test(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, FACTORY_BUF_SIZE, "%u\n", 0); +} + +/* sysfs: /sys/class/sec/tsp/cmd */ +static ssize_t store_cmd(struct device *dev, struct device_attribute + *devattr, const char *buf, size_t count) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + struct sec_factory *sec = (struct sec_factory *)&data->sec; + struct i2c_client *client = data->client; + + char *cur, *start, *end; + char msg[SEC_CMD_STR_LEN] = { 0 }; + int len, i; + struct tsp_cmd *tsp_cmd_ptr = NULL; + char delim = ','; + bool cmd_found = false; + int param_cnt = 0; + int ret; + + if (sec->cmd_is_running == true) { + dev_err(&client->dev, "tsp_cmd: other cmd is running.\n"); + tsp_err("tsp_cmd: other cmd is running.\n"); + goto err_out; + } + + /* check lock */ + mutex_lock(&sec->cmd_lock); + sec->cmd_is_running = true; + mutex_unlock(&sec->cmd_lock); + + sec->cmd_state = CMD_STATE_RUNNING; + + for (i = 0; i < ARRAY_SIZE(sec->cmd_param); i++) + sec->cmd_param[i] = 0; + + len = (int)count; + if (*(buf + len - 1) == '\n') + len--; + memset(sec->cmd, 0, ARRAY_SIZE(sec->cmd)); + memcpy(sec->cmd, buf, len); + + cur = strchr(buf, (int)delim); + if (cur) + memcpy(msg, buf, cur - buf); + else + memcpy(msg, buf, len); + /* find command */ + list_for_each_entry(tsp_cmd_ptr, &sec->cmd_list_head, list) { + if (!strcmp(msg, tsp_cmd_ptr->cmd_name)) { + cmd_found = true; + break; + } + } + + /* set not_support_cmd */ + if (!cmd_found) { + list_for_each_entry(tsp_cmd_ptr, &sec->cmd_list_head, list) { + if (!strcmp("not_support_cmd", tsp_cmd_ptr->cmd_name)) + break; + } + } + + /* parsing parameters */ + if (cur && cmd_found) { + cur++; + start = cur; + memset(msg, 0, ARRAY_SIZE(msg)); + do { + if (*cur == delim || cur - buf == len) { + end = cur; + memcpy(msg, start, end - start); + *(msg + strlen(msg)) = '\0'; + ret = kstrtoint(msg, 10, \ + sec->cmd_param + param_cnt); + start = cur + 1; + memset(msg, 0, ARRAY_SIZE(msg)); + param_cnt++; + } + cur++; + } while (cur - buf <= len); + } + dev_info(&client->dev, "cmd = %s\n", tsp_cmd_ptr->cmd_name); + tsp_info("SEC CMD = %s\n", tsp_cmd_ptr->cmd_name); + + for (i = 0; i < param_cnt; i++) + dev_info(&client->dev, "cmd param %d= %d\n", i, sec->cmd_param[i]); + + tsp_cmd_ptr->cmd_func(data); + +err_out: + return count; +} + +/* sysfs: /sys/class/sec/tsp/cmd_status */ +static ssize_t show_cmd_status(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + struct sec_factory *sec = (struct sec_factory *)&data->sec; + char msg[16] = { 0 }; + + dev_info(&data->client->dev, "tsp cmd: status:%d\n", sec->cmd_state); + + if (sec->cmd_state == CMD_STATE_WAITING) + snprintf(msg, sizeof(msg), "WAITING"); + else if (sec->cmd_state == CMD_STATE_RUNNING) + snprintf(msg, sizeof(msg), "RUNNING"); + else if (sec->cmd_state == CMD_STATE_OK) + snprintf(msg, sizeof(msg), "OK"); + else if (sec->cmd_state == CMD_STATE_FAIL) + snprintf(msg, sizeof(msg), "FAIL"); + else if (sec->cmd_state == CMD_STATE_NA) + snprintf(msg, sizeof(msg), "NOT_APPLICABLE"); + + return snprintf(buf, FACTORY_BUF_SIZE, "%s\n", msg); +} + +/* sysfs: /sys/class/sec/tsp/result */ +static ssize_t show_cmd_result(struct device *dev, struct device_attribute + *devattr, char *buf) +{ + struct ist30xx_data *data = dev_get_drvdata(dev); + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + dev_info(&data->client->dev, "tsp cmd: result: %s\n", sec->cmd_result); + + mutex_lock(&sec->cmd_lock); + sec->cmd_is_running = false; + mutex_unlock(&sec->cmd_lock); + + sec->cmd_state = CMD_STATE_WAITING; + + return snprintf(buf, FACTORY_BUF_SIZE, "%s\n", sec->cmd_result); +} + + + +/* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_version_phone */ +static ssize_t phone_firmware_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 ver = ist30xx_parse_ver(FLAG_PARAM, ts_data->fw.buf); + + tsp_info("%s(), IM00%04x\n", __func__, ver); + + return sprintf(buf, "IM00%04x", ver); +} + +/* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_version_panel */ +static ssize_t part_firmware_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u32 ver = 0; + + if (ts_data->status.power == 1) + ver = ist30xxb_get_fw_ver(ts_data); + + tsp_info("%s(), IM00%04x\n", __func__, ver); + + return sprintf(buf, "IM00%04x", ver); +} + +/* sysfs: /sys/class/sec/sec_touchscreen/tsp_threshold */ +static ssize_t threshold_firmware_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int threshold; + u32 *cfg_buf; + + ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size); + cfg_buf = (u32 *)&ts_data->fw.buf[ts_data->tags.cfg_addr]; + + threshold = (int)(cfg_buf[0x2C / IST30XX_DATA_LEN] & 0xFFFF); + + tsp_info("%s(), %d\n", __func__, threshold); + + return sprintf(buf, "%d", threshold); +} + +/* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_update */ +static ssize_t firmware_update(struct device *dev, + struct device_attribute *attr, char *buf) +{ + bool ret; + + sprintf(IsfwUpdate, "%s\n", FW_DOWNLOADING); + tsp_info("%s(), %s\n", __func__, IsfwUpdate); + + ret = ist30xx_fw_recovery(ts_data); + ret = (ret == 0 ? 1 : -1); + + sprintf(IsfwUpdate, "%s\n", + (ret > 0 ? FW_DOWNLOAD_COMPLETE : FW_DOWNLOAD_FAIL)); + tsp_info("%s(), %s\n", __func__, IsfwUpdate); + + return sprintf(buf, "%d", ret); +} + +/* sysfs: /sys/class/sec/sec_touchscreen/tsp_firm_update_status */ +static ssize_t firmware_update_status(struct device *dev, + struct device_attribute *attr, char *buf) +{ + tsp_info("%s(), %s\n", __func__, IsfwUpdate); + + return sprintf(buf, "%s\n", IsfwUpdate); +} + +/* sysfs: /sys/class/sec/sec_touchkey/touchkey_recent */ +static ssize_t recent_sensitivity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int sensitivity = ist30xxb_get_key_sensitivity(ts_data, 0); + + tsp_info("%s(), %d\n", __func__, sensitivity); + + return sprintf(buf, "%d", sensitivity); +} + +/* sysfs: /sys/class/sec/sec_touchkey/touchkey_back */ +static ssize_t back_sensitivity_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int sensitivity = ist30xxb_get_key_sensitivity(ts_data, 1); + + tsp_info("%s(), %d\n", __func__, sensitivity); + + return sprintf(buf, "%d", sensitivity); +} + +/* sysfs: /sys/class/sec/sec_touchkey/touchkey_threshold */ +static ssize_t touchkey_threshold_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int threshold; + u32 *cfg_buf; + + ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size); + cfg_buf = (u32 *)&ts_data->fw.buf[ts_data->tags.cfg_addr]; + + threshold = (int)(cfg_buf[0x30 / IST30XX_DATA_LEN] & 0xFFFF); + + tsp_info("%s(), %d\n", __func__, threshold); + + return snprintf(buf, sizeof(int), "%d\n", threshold); +} + +struct tsp_cmd tsp_cmds[] = { + { TSP_CMD("get_chip_vendor", get_chip_vendor), }, + { TSP_CMD("get_chip_name", get_chip_name), }, + { TSP_CMD("get_chip_id", get_chip_id), }, + { TSP_CMD("fw_update", fw_update), }, + { TSP_CMD("get_fw_ver_bin", get_fw_ver_bin), }, + { TSP_CMD("get_fw_ver_ic", get_fw_ver_ic), }, + { TSP_CMD("get_threshold", get_threshold), }, + { TSP_CMD("get_x_num", get_x_num), }, + { TSP_CMD("get_y_num", get_y_num), }, + { TSP_CMD("run_raw_read", run_raw_read), }, + { TSP_CMD("get_raw_value", get_raw_value), }, + { TSP_CMD("not_support_cmd", not_support_cmd), }, +}; + +#define SEC_DEFAULT_ATTR (S_IRUGO | S_IWUSR | S_IWOTH | S_IXOTH) +/* sysfs - touchscreen */ +static DEVICE_ATTR(tsp_firm_version_phone, SEC_DEFAULT_ATTR, + phone_firmware_show, NULL); +static DEVICE_ATTR(tsp_firm_version_panel, SEC_DEFAULT_ATTR, + part_firmware_show, NULL); +static DEVICE_ATTR(tsp_threshold, SEC_DEFAULT_ATTR, + threshold_firmware_show, NULL); +static DEVICE_ATTR(tsp_firm_update, SEC_DEFAULT_ATTR, + firmware_update, NULL); +static DEVICE_ATTR(tsp_firm_update_status, SEC_DEFAULT_ATTR, + firmware_update_status, NULL); + +/* sysfs - touchkey */ +static DEVICE_ATTR(touchkey_recent, SEC_DEFAULT_ATTR, + recent_sensitivity_show, NULL); +static DEVICE_ATTR(touchkey_back, SEC_DEFAULT_ATTR, + back_sensitivity_show, NULL); +static DEVICE_ATTR(touchkey_threshold, SEC_DEFAULT_ATTR, + touchkey_threshold_show, NULL); + +/* sysfs - tsp */ +static DEVICE_ATTR(close_tsp_test, S_IRUGO, show_close_tsp_test, NULL); +static DEVICE_ATTR(cmd, S_IWUSR | S_IWGRP, NULL, store_cmd); +static DEVICE_ATTR(cmd_status, S_IRUGO, show_cmd_status, NULL); +static DEVICE_ATTR(cmd_result, S_IRUGO, show_cmd_result, NULL); + +static struct attribute *sec_tsp_attributes[] = { + &dev_attr_tsp_firm_version_phone.attr, + &dev_attr_tsp_firm_version_panel.attr, + &dev_attr_tsp_threshold.attr, + &dev_attr_tsp_firm_update.attr, + &dev_attr_tsp_firm_update_status.attr, + NULL, +}; + +static struct attribute *sec_tkey_attributes[] = { + &dev_attr_touchkey_recent.attr, + &dev_attr_touchkey_back.attr, + &dev_attr_touchkey_threshold.attr, + NULL, +}; + +static struct attribute *sec_touch_facotry_attributes[] = { + &dev_attr_close_tsp_test.attr, + &dev_attr_cmd.attr, + &dev_attr_cmd_status.attr, + &dev_attr_cmd_result.attr, + NULL, +}; + +static struct attribute_group sec_tsp_attr_group = { + .attrs = sec_tsp_attributes, +}; + +static struct attribute_group sec_tkey_attr_group = { + .attrs = sec_tkey_attributes, +}; + +static struct attribute_group sec_touch_factory_attr_group = { + .attrs = sec_touch_facotry_attributes, +}; + +extern struct class *sec_class; +struct device *sec_touchscreen; +EXPORT_SYMBOL(sec_touchscreen); +struct device *sec_touchkey; +EXPORT_SYMBOL(sec_touchkey); +struct device *sec_fac_dev; + + +int sec_touch_sysfs(struct ist30xx_data *data) +{ + /* /sys/class/sec/sec_touchscreen */ + sec_touchscreen = device_create(sec_class, NULL, 0, NULL, + "sec_touchscreen"); + if (IS_ERR(sec_touchscreen)) { + tsp_err("Failed to create device (%s)!\n", "sec_touchscreen"); + return -ENODEV; + } + /* /sys/class/sec/sec_touchscreen/... */ + if (sysfs_create_group(&sec_touchscreen->kobj, &sec_tsp_attr_group)) + tsp_err("Failed to create sysfs group(%s)!\n", "sec_touchscreen"); + + /* /sys/class/sec/sec_touchkey */ + sec_touchkey = device_create(sec_class, NULL, 0, NULL, "sec_touchkey"); + if (IS_ERR(sec_touchkey)) { + tsp_err("Failed to create device (%s)!\n", "sec_touchkey"); + return -ENODEV; + } + /* /sys/class/sec/sec_touchkey/... */ + if (sysfs_create_group(&sec_touchkey->kobj, &sec_tkey_attr_group)) + tsp_err("Failed to create sysfs group(%s)!\n", "sec_touchkey"); + + /* /sys/class/sec/tsp */ + sec_fac_dev = device_create(sec_class, NULL, 0, data, "tsp"); + if (IS_ERR(sec_fac_dev)) { + tsp_err("Failed to create device (%s)!\n", "tsp"); + return -ENODEV; + } + /* /sys/class/sec/tsp/... */ + if (sysfs_create_group(&sec_fac_dev->kobj, &sec_touch_factory_attr_group)) + tsp_err("Failed to create sysfs group(%s)!\n", "tsp"); + + return 0; +} +EXPORT_SYMBOL(sec_touch_sysfs); +int sec_fac_cmd_init(struct ist30xx_data *data) +{ + int i; + struct sec_factory *sec = (struct sec_factory *)&data->sec; + + INIT_LIST_HEAD(&sec->cmd_list_head); + for (i = 0; i < ARRAY_SIZE(tsp_cmds); i++) + list_add_tail(&tsp_cmds[i].list, &sec->cmd_list_head); + + mutex_init(&sec->cmd_lock); + sec->cmd_is_running = false; + + return 0; +} +EXPORT_SYMBOL(sec_fac_cmd_init); diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_sec.h b/drivers/input/touchscreen/ist30xxa/ist30xx_sec.h new file mode 100644 index 00000000..517e14b8 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_sec.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XX_SEC_H__ +#define __IST30XX_SEC_H__ + + +#define SEC_CMD_STR_LEN 32 +#define SEC_CMD_RESULT_STR_LEN 512 +#define SEC_CMD_PARAM_NUM 8 + +#include "ist30xx_tsp.h" + +struct sec_factory { + struct list_head cmd_list_head; + unsigned char cmd_state; + char cmd[SEC_CMD_STR_LEN]; + int cmd_param[SEC_CMD_PARAM_NUM]; + char cmd_result[SEC_CMD_RESULT_STR_LEN]; + struct mutex cmd_lock; + bool cmd_is_running; +}; + +#endif // __IST30XX_SEC_H__ diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_sys.c b/drivers/input/touchscreen/ist30xxa/ist30xx_sys.c new file mode 100644 index 00000000..62bfba85 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_sys.c @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/i2c.h> +#include <linux/delay.h> +#include <asm/unaligned.h> +#include <asm/io.h> +#include <mach/gpio.h> + +#include "ist30xx.h" +#include "ist30xx_update.h" +#include "ist30xx_tracking.h" + +#include <linux/regulator/consumer.h> +#include <linux/regulator/machine.h> + +/****************************************************************************** + * Return value of Error + * EPERM : 1 (Operation not permitted) + * ENOENT : 2 (No such file or directory) + * EIO : 5 (I/O error) + * ENXIO : 6 (No such device or address) + * EINVAL : 22 (Invalid argument) + *****************************************************************************/ + +extern struct ist30xx_data *ts_data; +extern char *ist_vdd_name; + +const u32 pos_cmd = cpu_to_be32(CMD_GET_COORD); +struct i2c_msg pos_msg[READ_CMD_MSG_LEN] = { + { + .flags = 0, + .len = IST30XX_ADDR_LEN, + .buf = (u8 *)&pos_cmd, + }, + { .flags = I2C_M_RD, }, +}; + +int ist30xx_get_position(struct i2c_client *client, u32 *buf, u16 len) +{ + int ret, i; + + pos_msg[0].addr = client->addr; + pos_msg[1].addr = client->addr; + pos_msg[1].len = len * IST30XX_DATA_LEN, + pos_msg[1].buf = (u8 *)buf, + + ret = i2c_transfer(client->adapter, pos_msg, READ_CMD_MSG_LEN); + if (ret != READ_CMD_MSG_LEN) { + tsp_err("%s: i2c failed (%d)\n", __func__, ret); + return -EIO; + } + + for (i = 0; i < len; i++) + buf[i] = cpu_to_be32(buf[i]); + + return 0; +} + +int ist30xx_cmd_start_scan(struct i2c_client *client) +{ + int ret; + + ret = ist30xx_write_cmd(client, CMD_START_SCAN, 0); + + ist30xx_tracking(TRACK_CMD_SCAN); + + msleep(100); + + ts_data->status.noise_mode = true; + + return ret; +} + +int ist30xx_cmd_calibrate(struct i2c_client *client) +{ + int ret = ist30xx_write_cmd(client, CMD_CALIBRATE, 0); + + ist30xx_tracking(TRACK_CMD_CALIB); + + tsp_info("%s\n", __func__); + + msleep(100); + + return ret; +} + +int ist30xx_cmd_check_calib(struct i2c_client *client) +{ + int ret = ist30xx_write_cmd(client, CMD_CHECK_CALIB, 0); + + ist30xx_tracking(TRACK_CMD_CHECK_CALIB); + + tsp_info("*** Check Calibration cmd ***\n"); + + msleep(20); + + return ret; +} + +int ist30xx_cmd_update(struct i2c_client *client, int cmd) +{ + u32 val = (cmd == CMD_ENTER_FW_UPDATE ? CMD_FW_UPDATE_MAGIC : 0); + int ret = ist30xx_write_cmd(client, cmd, val); + + ist30xx_tracking(TRACK_CMD_FWUPDATE); + + msleep(10); + + return ret; +} + +int ist30xx_cmd_reg(struct i2c_client *client, int cmd) +{ + int ret = ist30xx_write_cmd(client, cmd, 0); + + if (cmd == CMD_ENTER_REG_ACCESS) { + ist30xx_tracking(TRACK_CMD_ENTER_REG); + msleep(100); + } else if (cmd == CMD_EXIT_REG_ACCESS) { + ist30xx_tracking(TRACK_CMD_EXIT_REG); + msleep(10); + } + + return ret; +} + + +int ist30xx_read_cmd(struct i2c_client *client, u32 cmd, u32 *buf) +{ + int ret; + u32 le_reg = cpu_to_be32(cmd); + + struct i2c_msg msg[READ_CMD_MSG_LEN] = { + { + .addr = client->addr, + .flags = 0, + .len = IST30XX_ADDR_LEN, + .buf = (u8 *)&le_reg, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = IST30XX_DATA_LEN, + .buf = (u8 *)buf, + }, + }; + + ret = i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN); + if (ret != READ_CMD_MSG_LEN) { + tsp_err("%s: i2c failed (%d), cmd: %x\n", __func__, ret, cmd); + return -EIO; + } + *buf = cpu_to_be32(*buf); + + return 0; +} + + +int ist30xx_write_cmd(struct i2c_client *client, u32 cmd, u32 val) +{ + int ret; + struct i2c_msg msg; + u8 msg_buf[IST30XX_ADDR_LEN + IST30XX_DATA_LEN]; + + put_unaligned_be32(cmd, msg_buf); + put_unaligned_be32(val, msg_buf + IST30XX_ADDR_LEN); + + msg.addr = client->addr; + msg.flags = 0; + msg.len = IST30XX_ADDR_LEN + IST30XX_DATA_LEN; + msg.buf = msg_buf; + + ret = i2c_transfer(client->adapter, &msg, WRITE_CMD_MSG_LEN); + if (ret != WRITE_CMD_MSG_LEN) { + tsp_err("%s: i2c failed (%d), cmd: %x(%x)\n", __func__, ret, cmd, val); + return -EIO; + } + + return 0; +} + +static void ts_power_enable(int en) +{ + int ret; + + tsp_info("%s %s\n", __func__, (en) ? "on" : "off"); + + static struct regulator *ts_vdd = NULL; + + if (ts_vdd == NULL) { + ts_vdd = regulator_get(NULL, ist_vdd_name); + + if (IS_ERR(ts_vdd)) { + pr_err("Get regulator of TSP error!\n"); + return; + } + } + + if (en) { + ret = regulator_set_voltage(ts_vdd, 3000000, 3000000); + regulator_enable(ts_vdd); + } + else if (regulator_is_enabled(ts_vdd)) { + regulator_disable(ts_vdd); + } +} + +int ist30xx_power_on(bool download) +{ + if (ts_data->status.power != 1) { + tsp_info("%s()\n", __func__); + ist30xx_tracking(TRACK_PWR_ON); + /* VDD enable */ + msleep(5); + /* VDDIO enable */ + ts_power_enable(1); + if (download) + msleep(8); + else + msleep(100); + ts_data->status.power = 1; + } + + return 0; +} + + +int ist30xx_power_off(void) +{ + if (ts_data->status.power != 0) { + tsp_info("%s()\n", __func__); + ist30xx_tracking(TRACK_PWR_OFF); + /* VDDIO disable */ + msleep(5); + /* VDD disable */ + ts_power_enable(0); + msleep(50); + ts_data->status.power = 0; + ts_data->status.noise_mode = false; + } + + return 0; +} + + +int ist30xx_reset(bool download) +{ + tsp_info("%s()\n", __func__); + ist30xx_power_off(); + msleep(10); + ist30xx_power_on(download); + + return 0; +} + + +int ist30xx_internal_suspend(struct ist30xx_data *data) +{ + ist30xx_power_off(); + return 0; +} + + +int ist30xx_internal_resume(struct ist30xx_data *data) +{ + ist30xx_power_on(false); + + return 0; +} + + +int ist30xx_init_system(void) +{ + int ret; + + // TODO : place additional code here. + ret = ist30xx_power_on(false); + if (ret) { + tsp_err("%s: ist30xx_init_system failed (%d)\n", __func__, ret); + return -EIO; + } + +#if 1 + ret = ist30xx_reset(false); + if (ret) { + tsp_err("%s: ist30xx_reset failed (%d)\n", __func__, ret); + return -EIO; + } +#endif + + return 0; +} diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_tracking.c b/drivers/input/touchscreen/ist30xxa/ist30xx_tracking.c new file mode 100644 index 00000000..543bed88 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_tracking.c @@ -0,0 +1,236 @@ +/*
+ * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/stat.h>
+
+#include "ist30xx.h"
+#include "ist30xx_update.h"
+#include "ist30xx_misc.h"
+#include "ist30xx_tracking.h"
+
+
+IST30XX_RING_BUF TrackBuf;
+IST30XX_RING_BUF *pTrackBuf;
+
+bool tracking_initialize = false;
+
+void ist30xx_tracking_init(void)
+{
+ if (tracking_initialize)
+ return;
+
+ pTrackBuf = &TrackBuf;
+
+ pTrackBuf->RingBufCtr = 0;
+ pTrackBuf->RingBufInIdx = 0;
+ pTrackBuf->RingBufOutIdx = 0;
+
+ tracking_initialize = true;
+}
+
+void ist30xx_tracking_deinit(void)
+{
+}
+
+static spinlock_t mr_lock = __SPIN_LOCK_UNLOCKED();
+int ist30xx_get_track(u32 *track, int cnt)
+{
+ int i;
+ u8 *buf = (u8 *)track;
+ unsigned long flags;
+
+
+ cnt *= sizeof(track[0]);
+
+ spin_lock_irqsave(&mr_lock, flags);
+
+ if (pTrackBuf->RingBufCtr < (u16)cnt) {
+ spin_unlock_irqrestore(&mr_lock, flags);
+ return IST30XX_RINGBUF_NOT_ENOUGH;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ if (pTrackBuf->RingBufOutIdx == IST30XX_MAX_LOG_SIZE)
+ pTrackBuf->RingBufOutIdx = 0;
+
+ *buf++ = (u8)pTrackBuf->LogBuf[pTrackBuf->RingBufOutIdx++];
+ pTrackBuf->RingBufCtr--;
+ }
+
+ spin_unlock_irqrestore(&mr_lock, flags);
+
+ return IST30XX_RINGBUF_NO_ERR;
+}
+
+u32 ist30xx_get_track_cnt(void)
+{
+ return pTrackBuf->RingBufCtr;
+}
+
+#if IST30XX_TRACKING_MODE
+int ist30xx_put_track(u32 *track, int cnt)
+{
+ int i;
+ u8 *buf = (u8 *)track;
+ unsigned long flags;
+
+ spin_lock_irqsave(&mr_lock, flags);
+
+ cnt *= sizeof(track[0]);
+
+ pTrackBuf->RingBufCtr += cnt;
+ if (pTrackBuf->RingBufCtr > IST30XX_MAX_LOG_SIZE) {
+ pTrackBuf->RingBufOutIdx +=
+ (pTrackBuf->RingBufCtr - IST30XX_MAX_LOG_SIZE);
+ if (pTrackBuf->RingBufOutIdx >= IST30XX_MAX_LOG_SIZE)
+ pTrackBuf->RingBufOutIdx -= IST30XX_MAX_LOG_SIZE;
+
+ pTrackBuf->RingBufCtr = IST30XX_MAX_LOG_SIZE;
+ }
+
+ for (i = 0; i < cnt; i++) {
+ if (pTrackBuf->RingBufInIdx == IST30XX_MAX_LOG_SIZE)
+ pTrackBuf->RingBufInIdx = 0;
+ pTrackBuf->LogBuf[pTrackBuf->RingBufInIdx++] = *buf++;
+ }
+
+ spin_unlock_irqrestore(&mr_lock, flags);
+
+ return IST30XX_RINGBUF_NO_ERR;
+}
+
+int ist30xx_put_track_ms(u32 ms)
+{
+ ms &= 0x0000FFFF;
+ ms |= IST30XX_TRACKING_MAGIC;
+
+ return ist30xx_put_track(&ms, 1);
+}
+
+static struct timespec t_track;
+int ist30xx_tracking(u32 status)
+{
+ u32 ms;
+
+ if (!tracking_initialize)
+ ist30xx_tracking_init();
+
+ ktime_get_ts(&t_track);
+ ms = t_track.tv_sec * 1000 + t_track.tv_nsec / 1000000;
+
+ ist30xx_put_track_ms(ms);
+ ist30xx_put_track(&status, 1);
+
+ return 0;
+}
+#else
+int ist30xx_put_track(u32 *track, int cnt)
+{
+ return 0;
+}
+int ist30xx_put_track_ms(u32 ms)
+{
+ return 0;
+}
+int ist30xx_tracking(u32 status)
+{
+ return 0;
+}
+#endif // IST30XX_TRACKING_MODE
+
+#define MAX_TRACKING_COUNT (1024)
+struct timespec t_curr; // ns
+
+/* sysfs: /sys/class/touch/tracking/track_frame */
+ssize_t ist30xx_track_frame_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int i, buf_cnt = 0;
+ u32 track_cnt = MAX_TRACKING_COUNT;
+ u32 track;
+ char msg[10];
+
+ mutex_lock(&ist30xx_mutex);
+
+ buf[0] = '\0';
+
+ if (track_cnt > ist30xx_get_track_cnt())
+ track_cnt = ist30xx_get_track_cnt();
+
+ track_cnt /= sizeof(track);
+
+ tsp_verb("num: %d of %d\n", track_cnt, ist30xx_get_track_cnt());
+
+ for (i = 0; i < track_cnt; i++) {
+ ist30xx_get_track(&track, 1);
+
+ tsp_verb("%08X\n", track);
+
+ buf_cnt += sprintf(msg, "%08x", track);
+ strcat(buf, msg);
+ }
+
+ mutex_unlock(&ist30xx_mutex);
+
+ return buf_cnt;
+}
+
+/* sysfs: /sys/class/touch/tracking/track_cnt */
+ssize_t ist30xx_track_cnt_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ u32 val = (u32)ist30xx_get_track_cnt();
+
+ tsp_verb("tracking cnt: %d\n", val);
+
+ return sprintf(buf, "%08x", val);
+}
+
+
+/* sysfs */
+static DEVICE_ATTR(track_frame, S_IRWXUGO, ist30xx_track_frame_show, NULL);
+static DEVICE_ATTR(track_cnt, S_IRWXUGO, ist30xx_track_cnt_show, NULL);
+
+static struct attribute *tracking_attributes[] = {
+ &dev_attr_track_frame.attr,
+ &dev_attr_track_cnt.attr,
+ NULL,
+};
+
+static struct attribute_group tracking_attr_group = {
+ .attrs = tracking_attributes,
+};
+
+extern struct class *ist30xx_class;
+struct device *ist30xx_tracking_dev;
+
+int ist30xx_init_tracking_sysfs(void)
+{
+ /* /sys/class/touch/tracking */
+ ist30xx_tracking_dev = device_create(ist30xx_class, NULL, 0, NULL,
+ "tracking");
+
+ /* /sys/class/touch/tracking/... */
+ if (sysfs_create_group(&ist30xx_tracking_dev->kobj, &tracking_attr_group))
+ tsp_err("[ TSP ] Failed to create sysfs group(%s)!\n", "tracking");
+
+ ist30xx_tracking_init();
+
+ return 0;
+}
diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_tracking.h b/drivers/input/touchscreen/ist30xxa/ist30xx_tracking.h new file mode 100644 index 00000000..a53175e2 --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_tracking.h @@ -0,0 +1,57 @@ +#ifndef __IST30XX_TRACKING_H__
+#define __IST30XX_TRACKING_H__
+
+
+#define IST30XX_RINGBUF_NO_ERR (0)
+#define IST30XX_RINGBUF_NOT_ENOUGH (1)
+#define IST30XX_RINGBUF_EMPTY (2)
+#define IST30XX_RINGBUF_FULL (3)
+#define IST30XX_RINGBUF_TIMEOUT (4)
+#define IST30XX_MAX_LOG_SIZE (4 * 100 * 1024) // 4bytes * 100Kbytes, Single touch: about 12minutes
+
+#define TRACK_PWR_ON (0x1)
+#define TRACK_PWR_OFF (0x2)
+#define TRACK_PWR_RESET (0x3)
+#define TRACK_INTR_ENABLE (0x4)
+#define TRACK_INTR_DISABLE (0x5)
+#define TRACK_CMD_RUN_DEVICE (0x10)
+#define TRACK_CMD_SCAN (0x11)
+#define TRACK_CMD_TACON (0x12)
+#define TRACK_CMD_TADISCON (0x13)
+#define TRACK_CMD_FWUPDATE (0x14)
+#define TRACK_CMD_PRUPDATE (0x15)
+#define TRACK_CMD_CALIB (0x16)
+#define TRACK_CMD_CHECK_CALIB (0x17)
+#define TRACK_CMD_CHKSUM (0x18)
+#define TRACK_CMD_CHKSUM_ALL (0x19)
+#define TRACK_CMD_ENTER_REG (0x1A)
+#define TRACK_CMD_EXIT_REG (0x1B)
+#define TRACK_POS_FINGER (0x20)
+#define TRACK_POS_KEY (0x30)
+#define TRACK_POS_UNKNOWN (0x3F)
+
+#define IST30XX_TRACKING_MAGIC (0x7750 << 16)
+
+
+typedef struct _IST30XX_RINGBUF {
+ u32 RingBufCtr; // Number of characters in the ring buffer
+ u32 RingBufInIdx;
+ u32 RingBufOutIdx;
+ u8 LogBuf[IST30XX_MAX_LOG_SIZE]; // Ring buffer for status
+} IST30XX_RING_BUF;
+
+
+void ist30xx_tracking_init(void);
+void ist30xx_tracking_deinit(void);
+
+int ist30xx_get_track(u32 *track, int cnt);
+int ist30xx_put_track(u32 *track, int cnt);
+int ist30xx_put_track_ms(u32 ms);
+
+u32 ist30xx_get_track_cnt(void);
+
+int ist30xx_tracking(u32 status);
+
+int ist30xx_init_tracking_sysfs(void);
+
+#endif // __IST30XX_TRACKING_H__
diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_tsp.h b/drivers/input/touchscreen/ist30xxa/ist30xx_tsp.h new file mode 100644 index 00000000..c6f2149b --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_tsp.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XX_TSP_H__ +#define __IST30XX_TSP_H__ + +#define IST30XX_DD_VERSION (5) + +#define IST30XX_MULTIPLE_TSP (0) + +#define TSP_CHIP_VENDOR ("IMAGIS") +#define TSP_CHIP_NAME ("IST3038") + +#define FLAG_NODE_Y (0) +#define FLAG_NODE_X (1) + +#define NODE_TX_NUM (21) +#define NODE_RX_NUM (14) +#define NODE_TOTAL_NUM (NODE_TX_NUM * NODE_RX_NUM) + +#define TSP_TX_NUM (21) +#define TSP_RX_NUM (13) +#define TSP_TOTAL_NUM (TSP_TX_NUM * TSP_RX_NUM) + +#define TSP_TYPE_UNKNOWN (0xF0) +#define TSP_TYPE_ALPS (0xF) +#define TSP_TYPE_EELY (0xE) +#define TSP_TYPE_TOP (0xD) +#define TSP_TYPE_MELFAS (0xC) +#define TSP_TYPE_ILJIN (0xB) +#define TSP_TYPE_SYNOPEX (0xA) +#define TSP_TYPE_SMAC (0x9) +#define TSP_TYPE_TAEYANG (0x8) +#define TSP_TYPE_TOVIS (0x7) +#define TSP_TYPE_ELK (0x6) +#define TSP_TYPE_OTHERS (0x5) + +#define IST30XXB_PARSE_TSPTYPE(n) ((n >> 1) & 0xF) + +#endif // __IST30XX_TSP_H__ diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_update.c b/drivers/input/touchscreen/ist30xxa/ist30xx_update.c new file mode 100644 index 00000000..ec36fb3a --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_update.c @@ -0,0 +1,1349 @@ +/* + * Copyright (C) 2010,Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include <linux/i2c.h> +#include <linux/delay.h> +#include <linux/slab.h> +#include <linux/firmware.h> +#include <linux/stat.h> +#include <asm/unaligned.h> +#include <linux/uaccess.h> +#include <linux/fcntl.h> +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/err.h> + +#include "ist30xx.h" +#include "ist30xx_update.h" +#include "ist30xx_tracking.h" + +#if IST30XX_DEBUG +#include "ist30xx_misc.h" +#endif + +#if IST30XX_INTERNAL_BIN +#include "./firmware/core_prime.h" +#if IST30XX_MULTIPLE_TSP +//#include "./firmware/core_prime.h" +#endif +#endif // IST30XX_INTERNAL_BIN + +struct ist30xx_tags *ts_tags; + +u32 ist30xx_fw_ver = 0; +u32 ist30xx_param_ver = 0; +u32 ist30xx_sub_ver = 0; + +extern struct ist30xx_data *ts_data; + +extern void ist30xx_disable_irq(struct ist30xx_data *data); +extern void ist30xx_enable_irq(struct ist30xx_data *data); + +int ist30xx_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, + int msg_num, u8 *cmd_buf) +{ + int ret = 0; + int idx = msg_num - 1; + int size = msgs[idx].len; + u8 *msg_buf = NULL; + u8 *pbuf = NULL; + int trans_size, max_size = 0; + + if (msg_num == WRITE_CMD_MSG_LEN) + max_size = I2C_MAX_WRITE_SIZE; + else if (msg_num == READ_CMD_MSG_LEN) + max_size = I2C_MAX_READ_SIZE; + + if (unlikely(max_size == 0)) { + tsp_err("%s() : transaction size(%d)\n", __func__, max_size); + return -EINVAL; + } + + if (msg_num == WRITE_CMD_MSG_LEN) { + msg_buf = kmalloc(max_size + IST30XX_ADDR_LEN, GFP_KERNEL); + if (!msg_buf) + return -ENOMEM; + memcpy(msg_buf, cmd_buf, IST30XX_ADDR_LEN); + pbuf = msgs[idx].buf; + } + + while (size > 0) { + trans_size = (size >= max_size ? max_size : size); + + msgs[idx].len = trans_size; + if (msg_num == WRITE_CMD_MSG_LEN) { + memcpy(&msg_buf[IST30XX_ADDR_LEN], pbuf, trans_size); + msgs[idx].buf = msg_buf; + msgs[idx].len += IST30XX_ADDR_LEN; + } + ret = i2c_transfer(adap, msgs, msg_num); + if (unlikely(ret != msg_num)) { + tsp_err("%s() : i2c_transfer failed(%d), num=%d\n", + __func__, ret, msg_num); + break; + } + + if (msg_num == WRITE_CMD_MSG_LEN) + pbuf += trans_size; + else + msgs[idx].buf += trans_size; + + size -= trans_size; + } + + if (msg_num == WRITE_CMD_MSG_LEN) + kfree(msg_buf); + + return ret; +} + +int ist30xx_read_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len) +{ + int ret, i; + u32 le_reg = cpu_to_be32(cmd); + + struct i2c_msg msg[READ_CMD_MSG_LEN] = { + { + .addr = client->addr, + .flags = 0, + .len = IST30XX_ADDR_LEN, + .buf = (u8 *)&le_reg, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = len * IST30XX_DATA_LEN, + .buf = (u8 *)buf, + }, + }; + + ret = ist30xx_i2c_transfer(client->adapter, msg, READ_CMD_MSG_LEN, NULL); + if (unlikely(ret != READ_CMD_MSG_LEN)) + return -EIO; + + for (i = 0; i < len; i++) + buf[i] = cpu_to_be32(buf[i]); + + return 0; +} + +int ist30xx_write_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len) +{ + int i; + int ret; + struct i2c_msg msg; + u8 cmd_buf[IST30XX_ADDR_LEN]; + u8 msg_buf[IST30XX_DATA_LEN * (len + 1)]; + + put_unaligned_be32(cmd, cmd_buf); + + if (likely(len > 0)) { + for (i = 0; i < len; i++) + put_unaligned_be32(buf[i], msg_buf + (i * IST30XX_DATA_LEN)); + } else { + /* then add dummy data(4byte) */ + put_unaligned_be32(0, msg_buf); + len = 1; + } + + msg.addr = client->addr; + msg.flags = 0; + msg.len = IST30XX_DATA_LEN * len; + msg.buf = msg_buf; + + ret = ist30xx_i2c_transfer(client->adapter, &msg, WRITE_CMD_MSG_LEN, + cmd_buf); + if (unlikely(ret != WRITE_CMD_MSG_LEN)) + return -EIO; + + return 0; +} + +int ist30xxb_burst_read(struct i2c_client *client, u32 addr, + u32 *buf32, int len) +{ + int ret = 0; + int i; + int max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN; + + addr |= IST30XXB_BURST_ACCESS; + + for (i = 0; i < len; i += max_len) { + if (len < max_len) max_len = len; + + ret = ist30xx_read_buf(client, addr, buf32, max_len); + if (unlikely(ret)) { + tsp_err("Burst fail, addr: %x\n", __func__, addr); + return ret; + } + + addr += max_len * IST30XX_DATA_LEN; + buf32 += max_len; + } + + return 0; +} + +#define IST30XXB_ISP_READ (1) +#define IST30XXB_ISP_WRITE (2) +#define IST30XXB_ISP_ERASE_ALL (3) +#define IST30XXB_ISP_ERASE_PAGE (4) + +int ist30xxb_isp_reset(void) +{ + int ret = 0; + +#if (IMAGIS_TSP_IC == IMAGIS_IST3038) + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPMODE, 0x180); + if (unlikely(ret)) + return ret; +#else + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPPWRCTRL, 0xB200); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPPWRCTRL, 0x9200); + if (unlikely(ret)) + return ret; +#endif + msleep(1); + + return ret; +} + +int ist30xxb_isp_enable(bool enable) +{ + int ret = 0; + + if (enable) { + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPISPEN, 0x1); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_LDOOSC, 0x74C8); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_CLKDIV, 0x3); + if (unlikely(ret)) + return ret; + +#if (IMAGIS_TSP_IC != IMAGIS_IST3038) + ret = ist30xx_write_cmd(ts_data->client, + IST30XXB_REG_PADCTRL, 0x03300000); + if (unlikely(ret)) + return ret; +#endif + + msleep(10); + + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_WDTCON, 0x0); + if (unlikely(ret)) + return ret; + } else { + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPISPEN, 0x0); + if (unlikely(ret)) + return ret; + + msleep(1); + } + + return 0; +} + +int ist30xxb_isp_mode(int mode) +{ + int ret = 0; + u32 val = 0; + + switch (mode) { + case IST30XXB_ISP_READ: + val = 0x1C0; + break; + case IST30XXB_ISP_WRITE: + val = 0x1A8; + break; + case IST30XXB_ISP_ERASE_ALL: + val = 0x1A7; + break; + case IST30XXB_ISP_ERASE_PAGE: + val = 0x1A3; + break; + default: + tsp_err("ISP fail, unknown mode\n"); + return -EINVAL; + } + + ret = ist30xx_write_cmd(ts_data->client, IST30XXB_REG_EEPMODE, val); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPMODE\n"); + return ret; + } + + return 0; +} + +int ist30xxb_isp_erase(struct i2c_client *client, int mode, u32 addr) +{ + int ret = 0; + u32 val = 0x1A0; + u8 buf[EEPROM_PAGE_SIZE] = { 0, }; + + ret = ist30xxb_isp_mode(mode); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(client, IST30XXB_REG_EEPADDR, addr); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPADDR\n"); + return ret; + } + + val = (EEPROM_PAGE_SIZE / IST30XX_DATA_LEN); + ret = ist30xx_write_buf(client, IST30XXB_REG_EEPWDAT, (u32 *)buf, val); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPWDAT\n"); + return ret; + } + + msleep(30); + + ist30xxb_isp_reset(); + + return 0; +} + +int ist30xxb_isp_write(struct i2c_client *client, u32 addr, + const u32 *buf32, int len) +{ + int ret = 0; + + ret = ist30xx_write_cmd(client, IST30XXB_REG_EEPADDR, addr); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPADDR\n"); + return ret; + } + + ret = ist30xx_write_buf(client, IST30XXB_REG_EEPWDAT, (u32 *)buf32, len); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPWDAT\n"); + return ret; + } + + return 0; +} + +int ist30xxb_isp_read(struct i2c_client *client, u32 addr, + u32 *buf32, int len) +{ + int ret = 0; + int i; + int max_len = I2C_MAX_READ_SIZE / IST30XX_DATA_LEN; + + for (i = 0; i < len; i += max_len) { + if (len < max_len) max_len = len; + + /* IST30xxB ISP read mode */ + ret = ist30xxb_isp_mode(IST30XXB_ISP_READ); + if (unlikely(ret)) + return ret; + + ret = ist30xx_write_cmd(client, IST30XXB_REG_EEPADDR, addr); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPADDR\n"); + return ret; + } + + ret = ist30xx_read_buf(client, IST30XXB_REG_EEPRDAT, buf32, max_len); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_EEPWDAT\n"); + return ret; + } + + addr += max_len * IST30XX_DATA_LEN; + buf32 += max_len; + } + + return 0; +} + +int ist30xxb_cmd_read_chksum(struct i2c_client *client, + u32 start_addr, u32 end_addr, u32 *chksum) +{ + int ret = 0; + u32 val = (1 << 31); // Chkecksum enable + + val |= start_addr; + val |= (end_addr / IST30XX_DATA_LEN - 1) << 16; + + ret = ist30xx_write_cmd(client, IST30XXB_REG_CHKSMOD, val); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_CHKSMOD (%x)\n", val); + return ret; + } + msleep(10); + + ret = ist30xx_read_cmd(client, IST30XXB_REG_CHKSDAT, chksum); + if (unlikely(ret)) { + tsp_err("ISP fail, IST30XXB_REG_CHKSDAT (%x)\n", chksum); + return ret; + } + + return 0; +} + +int ist30xxb_read_chksum(struct i2c_client *client, u32 *chksum) +{ + int ret = 0; + u32 start_addr, end_addr; + u32 chksum1 = 0, chksum2 = 0; + + start_addr = 0; + end_addr = ts_data->tags.fw_addr + ts_data->tags.fw_size; + ret = ist30xxb_cmd_read_chksum(client, start_addr, end_addr, &chksum1); + if (unlikely(ret)) + return ret; + + start_addr = ts_data->tags.cfg_addr; + end_addr = ts_data->tags.sensor3_addr + ts_data->tags.sensor3_size; + ret = ist30xxb_cmd_read_chksum(client, start_addr, end_addr, &chksum2); + if (unlikely(ret)) + return ret; + + *chksum = chksum1 | (chksum2 << 16); + + tsp_info("chksum: %x(%x~%x, %x~%x)\n", *chksum, + 0, ts_data->tags.fw_addr + ts_data->tags.fw_size, + start_addr, end_addr); + + return 0; +} + +int ist30xxb_read_chksum_all(struct i2c_client *client, u32 *chksum) +{ + int ret = 0; + u32 start_addr, end_addr; + + start_addr = 0; + end_addr = IST30XX_EEPROM_SIZE; + ret = ist30xxb_cmd_read_chksum(client, start_addr, end_addr, chksum); + if (unlikely(ret)) + return ret; + + tsp_info("chksum: %x(%x~%x)\n", *chksum, start_addr, end_addr); + + return 0; +} + +int ist30xxb_isp_fw_read(struct i2c_client *client, u32 *buf32) +{ + int ret = 0; + int i; + + u16 addr = EEPROM_BASE_ADDR; + int len = EEPROM_PAGE_SIZE / IST30XX_DATA_LEN; + + ist30xx_reset(true); + + /* IST30xxB ISP enable */ + ret = ist30xxb_isp_enable(true); + if (unlikely(ret)) + return ret; + + for (i = 0; i < IST30XX_EEPROM_SIZE; i += EEPROM_PAGE_SIZE) { + ret = ist30xxb_isp_read(client, addr, buf32, len); + if (unlikely(ret)) + goto isp_fw_read_end; + + addr += EEPROM_PAGE_SIZE; + buf32 += len; + } + +isp_fw_read_end: + /* IST30xxB ISP disable */ + ist30xxb_isp_enable(false); + return ret; +} + +int ist30xxb_isp_fw_update(struct i2c_client *client, const u8 *buf, + u32 *chksum) +{ + int ret = 0; + int i; + u32 page_cnt = IST30XX_EEPROM_SIZE / EEPROM_PAGE_SIZE; + u16 addr = EEPROM_BASE_ADDR; + int len = EEPROM_PAGE_SIZE / IST30XX_DATA_LEN; + + ist30xx_tracking(TRACK_CMD_FWUPDATE); + + /* IST30xxB ISP enable */ + ret = ist30xxb_isp_enable(true); + if (unlikely(ret)) + goto isp_fw_update_end; + + /* IST30xxB ISP erase */ + ret = ist30xxb_isp_erase(client, IST30XXB_ISP_ERASE_ALL, 0); + if (unlikely(ret)) + goto isp_fw_update_end; + +#if (IMAGIS_TSP_IC == IMAGIS_IST3038) + /* IST30xxB ISP read all checksum */ + ret = ist30xxb_read_chksum_all(client, chksum); + if (unlikely(ret)) + goto isp_fw_update_end; + + /* IST30xxB compare checksum */ + if (unlikely(*chksum != 0)) + goto isp_fw_update_end; +#endif + + /* IST30xxB power reset */ + ist30xx_reset(true); + + /* IST30xxB ISP enable */ + ret = ist30xxb_isp_enable(true); + if (unlikely(ret)) + goto isp_fw_update_end; + + for (i = 0; i < page_cnt; i++) { + /* IST30xxB ISP write mode */ + ret = ist30xxb_isp_mode(IST30XXB_ISP_WRITE); + if (unlikely(ret)) + goto isp_fw_update_end; + + ret = ist30xxb_isp_write(client, addr, (u32 *)buf, len); + if (unlikely(ret)) + goto isp_fw_update_end; + + addr += EEPROM_PAGE_SIZE; + buf += EEPROM_PAGE_SIZE; + + msleep(5); + + ist30xxb_isp_reset(); + } + +#if (IMAGIS_TSP_IC == IMAGIS_IST3038) + ist30xxb_read_chksum_all(client, chksum); +#endif + +isp_fw_update_end: + /* IST30xxB ISP disable */ + ist30xxb_isp_enable(false); + return ret; +} + +int ist30xx_fw_write(struct i2c_client *client, const u8 *buf) +{ + int ret; + int len; + u32 *buf32 = (u32 *)(buf + ts_data->fw.index); + u32 size = ts_data->fw.size; + + if (unlikely((size <= 0) || (size > IST30XX_EEPROM_SIZE))) + return -ENOEXEC; + + while (size > 0) { + len = (size >= EEPROM_PAGE_SIZE ? EEPROM_PAGE_SIZE : size); + + ret = ist30xx_write_buf(client, CMD_ENTER_FW_UPDATE, buf32, (len >> 2)); + if (unlikely(ret)) + return ret; + + buf32 += (len >> 2); + size -= len; + + msleep(5); + } + return 0; +} + + +u32 ist30xx_parse_ver(int flag, const u8 *buf) +{ + u32 ver = 0; + u32 *buf32 = (u32 *)buf; + + if (flag == FLAG_FW) + ver = (u32)buf32[(ts_data->tags.flag_addr + 60) >> 2]; + else if (flag == FLAG_SUB) + ver = (u32)buf32[(ts_data->tags.flag_addr + 52) >> 2]; + else if (flag == FLAG_PARAM) + ver = (u32)(buf32[(ts_data->tags.cfg_addr + 4) >> 2] & 0xFFFF); + else + tsp_warn("Parsing ver's flag is not corrent!\n"); + + return ver; +} + + +int calib_ms_delay = WAIT_CALIB_CNT; +int ist30xx_calib_wait(void) +{ + int cnt = calib_ms_delay; + + ts_data->status.calib_msg = 0; + while (cnt-- > 0) { + msleep(100); + + if (ts_data->status.calib_msg) { + tsp_info("Calibration status : %d, Max raw gap : %d - (%08x)\n", + CALIB_TO_STATUS(ts_data->status.calib_msg), + CALIB_TO_GAP(ts_data->status.calib_msg), + ts_data->status.calib_msg); + + if (CALIB_TO_OS_VALUE(ts_data->status.calib_msg) == 0xFFFF) + return 1; + else if (CALIB_TO_STATUS(ts_data->status.calib_msg) == 0) + return 0; // Calibrate success + else + return -EAGAIN; + } + } + tsp_warn("Calibration time out\n"); + + return -EPERM; +} + +int ist30xx_calibrate(int wait_cnt) +{ + int ret = -ENOEXEC; + + tsp_info("*** Calibrate %ds ***\n", calib_ms_delay / 10); + + ts_data->status.update = 1; + while (wait_cnt--) { + ist30xx_disable_irq(ts_data); + ist30xx_reset(false); + + ret = ist30xx_cmd_calibrate(ts_data->client); + if (unlikely(ret)) + continue; + + ist30xx_enable_irq(ts_data); + ret = ist30xx_calib_wait(); + if (likely(!ret)) + break; + } + + ist30xx_disable_irq(ts_data); + + ist30xx_reset(false); + + ts_data->status.update = 2; + + ist30xx_enable_irq(ts_data); + + return ret; +} + + +int ist30xx_parse_tags(struct ist30xx_data *data, const u8 *buf, const u32 size) +{ + int ret = -EPERM; + + ts_tags = (struct ist30xx_tags *)(&buf[size - sizeof(struct ist30xx_tags)]); + + if (!strncmp(ts_tags->magic1, IST30XX_TAG_MAGIC, sizeof(ts_tags->magic1)) + && !strncmp(ts_tags->magic2, IST30XX_TAG_MAGIC, sizeof(ts_tags->magic2)) + ) { + data->fw.index = ts_tags->fw_addr; + data->fw.size = ts_tags->flag_addr - ts_tags->fw_addr + + ts_tags->flag_size; + data->fw.chksum = ts_tags->chksum; + data->tags = *ts_tags; + + ret = 0; + } + + tsp_verb("Tagts magic1: %s, magic2: %s\n", + ts_tags->magic1, ts_tags->magic2); + tsp_verb(" fw: %x(%x)\n", ts_tags->fw_addr, ts_tags->fw_size); + tsp_verb(" flag: %x(%x)\n", ts_tags->flag_addr, ts_tags->flag_size); + tsp_verb(" cfg: %x(%x)\n", ts_tags->cfg_addr, ts_tags->cfg_size); + tsp_verb(" sensor1: %x(%x)\n", ts_tags->sensor1_addr, + ts_tags->sensor1_size); + tsp_verb(" sensor2: %x(%x)\n", ts_tags->sensor2_addr, + ts_tags->sensor2_size); + tsp_verb(" sensor3: %x(%x)\n", ts_tags->sensor3_addr, + ts_tags->sensor3_size); + tsp_verb(" chksum: %x\n", ts_tags->chksum); + tsp_verb(" build time : %04d/%02d/%02d (%02d:%02d:%02d)\n", + ts_tags->year, ts_tags->month, ts_tags->day, + ts_tags->hour, ts_tags->min, ts_tags->sec); + + return ret; +} + +void ist30xx_get_update_info(struct ist30xx_data *data, const u8 *buf, + const u32 size) +{ + int ret; + + ret = ist30xx_parse_tags(data, buf, size); + if (unlikely(ret != TAGS_PARSE_OK)) + tsp_warn("Cannot find tags of F/W, make a tags by 'tagts.exe'\n"); +} + +#if (IST30XX_DEBUG) && (IST30XX_INTERNAL_BIN) +extern TSP_INFO ist30xx_tsp_info; +extern TKEY_INFO ist30xx_tkey_info; +int ist30xx_get_tkey_info(struct ist30xx_data *data) +{ + int ret = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + TKEY_INFO *tkey = &ist30xx_tkey_info; + u8 *cfg_buf; + + cfg_buf = (u8 *)&data->fw.buf[data->tags.cfg_addr]; + + tkey->enable = (bool)(cfg_buf[0x321] & 1); + tkey->axis_rx = (bool)((cfg_buf[0x321] >> 1) & 1); + tkey->key_num = (u8)cfg_buf[0x322]; + tkey->baseline = (u16)((cfg_buf[0x324] << 8) | cfg_buf[0x323]); + tkey->ch_num[0] = (u8)cfg_buf[0x326]; + tkey->ch_num[1] = (u8)cfg_buf[0x327]; + tkey->ch_num[2] = (u8)cfg_buf[0x328]; + tkey->ch_num[3] = (u8)cfg_buf[0x329]; + tkey->ch_num[4] = (u8)cfg_buf[0x32A]; + + if (tkey->axis_rx) { + if (tsp->dir.swap_xy) + tsp->height -= 1; + else + tsp->width -= 1; + } else { + if (tsp->dir.swap_xy) + tsp->width -= 1; + else + tsp->height -= 1; + } + + return ret; +} + +#define TSP_INFO_SWAP_XY (1 << 0) +#define TSP_INFO_FLIP_X (1 << 1) +#define TSP_INFO_FLIP_Y (1 << 2) +int ist30xx_get_tsp_info(struct ist30xx_data *data) +{ + int ret = 0; + TSP_INFO *tsp = &ist30xx_tsp_info; + u8 *cfg_buf, *sensor_buf; + + cfg_buf = (u8 *)&data->fw.buf[data->tags.cfg_addr]; + sensor_buf = (u8 *)&data->fw.buf[data->tags.sensor1_addr]; + + tsp->finger_num = (u8)cfg_buf[0x304]; + tsp->dir.swap_xy = (bool)(cfg_buf[0x305] & TSP_INFO_SWAP_XY ? true : false); + tsp->dir.flip_x = (bool)(cfg_buf[0x305] & TSP_INFO_FLIP_X ? true : false); + tsp->dir.flip_y = (bool)(cfg_buf[0x305] & TSP_INFO_FLIP_Y ? true : false); + tsp->baseline = (u16)((cfg_buf[0x319] << 8) | cfg_buf[0x318]); + + tsp->ch_num.tx = (u8)sensor_buf[0x40]; + tsp->ch_num.rx = (u8)sensor_buf[0x41]; + + tsp->node.len = tsp->ch_num.tx * tsp->ch_num.rx; + tsp->height = (tsp->dir.swap_xy ? tsp->ch_num.rx : tsp->ch_num.tx); + tsp->width = (tsp->dir.swap_xy ? tsp->ch_num.tx : tsp->ch_num.rx); + + return ret; +} +#endif // (IST30XX_DEBUG) && (IST30XX_INTERNAL_BIN) + + +#define update_next_step(ret) { if (unlikely(ret)) goto end; } +int ist30xx_fw_update(struct i2c_client *client, const u8 *buf, int size, + bool mode) +{ + int ret = 0; + u32 chksum = 0; + struct ist30xx_fw *fw = &ts_data->fw; + + tsp_info("*** Firmware update ***\n"); + tsp_info(" core: %x, param: %x, sub: %x (addr: 0x%x ~ 0x%x)\n", + ist30xx_fw_ver, ist30xx_param_ver, ist30xx_sub_ver, + fw->index, (fw->index + fw->size)); + + ts_data->status.update = 1; + + ist30xx_disable_irq(ts_data); + + ist30xx_reset(true); + + if (mode) { /* ISP Mode */ + ret = ist30xxb_isp_fw_update(client, buf, &chksum); + update_next_step(ret); + } else { /* I2C SW Mode */ + ret = ist30xx_cmd_update(client, CMD_ENTER_FW_UPDATE); + update_next_step(ret); + + ret = ist30xx_fw_write(client, buf); + update_next_step(ret); + } + msleep(50); + + buf += IST30XX_EEPROM_SIZE; + size -= IST30XX_EEPROM_SIZE; + + ist30xx_reset(false); + + ret = ist30xx_read_cmd(client, CMD_GET_CHECKSUM, &chksum); + if (unlikely((ret) || (chksum != fw->chksum))) + goto end; + + ret = ist30xx_get_ver_info(ts_data); + update_next_step(ret); + +end: + if (unlikely(ret)) { + tsp_warn("Firmware update Fail!, ret=%d\n", ret); + } else if (unlikely(chksum != fw->chksum)) { + tsp_warn("Error CheckSum: %x(%x)\n", chksum, fw->chksum); + ret = -ENOEXEC; + } + + ist30xx_enable_irq(ts_data); + + ts_data->status.update = 2; + + return ret; +} + +int ist30xx_fw_recovery(struct ist30xx_data *data) +{ + int ret = -EPERM; + u8 *fw = data->fw.buf; + int fw_size = data->fw.buf_size; + + ist30xx_get_update_info(data, fw, fw_size); + ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw); + ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw); + ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_fw_update(data->client, fw, fw_size, true); + ist30xx_calibrate(1); + mutex_unlock(&ist30xx_mutex); + + ist30xx_start(data); + + return ret; +} + +#if IST30XX_INTERNAL_BIN +int ist30xx_check_fw(struct ist30xx_data *data, const u8 *buf) +{ + int ret; + u32 chksum; + + ret = ist30xx_read_cmd(data->client, CMD_GET_CHECKSUM, &chksum); + if (unlikely(ret)) + return ret; + + if (unlikely(chksum != data->fw.chksum)) { + tsp_warn("Checksum compare error, (IC: %08x, Bin: %08x)\n", + chksum, data->fw.chksum); + return -EPERM; + } + + return 0; +} + +bool ist30xx_check_valid_vendor(u32 tsp_vendor) +{ + switch (tsp_vendor) { + case TSP_TYPE_ALPS: + case TSP_TYPE_EELY: + case TSP_TYPE_TOP: + case TSP_TYPE_MELFAS: + case TSP_TYPE_ILJIN: + case TSP_TYPE_SYNOPEX: + case TSP_TYPE_SMAC: + case TSP_TYPE_TAEYANG: + case TSP_TYPE_TOVIS: + case TSP_TYPE_ELK: + case TSP_TYPE_OTHERS: + return true; + default: + return false; + } + + return false; +} + +#if IST30XX_MULTIPLE_TSP +void ist30xx_set_tsp_fw(struct ist30xx_data *data) +{ + char *str; + struct ist30xx_fw *fw = &data->fw; + + switch (data->tsp_type) { + case TSP_TYPE_ALPS: + case TSP_TYPE_ILJIN: + str = "ALPS/ILJIN"; + fw->buf = (u8 *)ist30xxb_fw; + fw->buf_size = sizeof(ist30xxb_fw); + break; + case TSP_TYPE_EELY: + str = "EELY"; + fw->buf = (u8 *)ist30xxb_fw2; + fw->buf_size = sizeof(ist30xxb_fw2); + break; + + case TSP_TYPE_UNKNOWN: + default: + str = "Unknown"; + tsp_warn("Unknown TSP vendor(0x%x)\n", data->tsp_type); + break; + } + tsp_info("TSP vendor : %s(%x)\n", str, data->tsp_type); + + ist30xx_get_update_info(ts_data, fw->buf, fw->buf_size); + ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw->buf); + ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw->buf); + ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw->buf); +} +#endif // IST30XX_MULTIPLE_TSP + +int ist30xx_check_auto_update(struct ist30xx_data *data) +{ + int ret = 0; + int retry = IST30XX_FW_UPDATE_RETRY; + u32 tsp_type = TSP_TYPE_UNKNOWN; + u32 chksum; + bool tsp_check = false; + struct ist30xx_fw *fw = &data->fw; + + while (retry--) { + ret = ist30xx_read_cmd(data->client, + CMD_GET_TSP_PANNEL_TYPE, &tsp_type); + if (likely(ret == 0)) { + if (likely(ist30xx_check_valid_vendor(tsp_type) == true)) + tsp_check = true; + break; + } + } + + retry = IST30XX_FW_UPDATE_RETRY; + + if (unlikely(!tsp_check)) + goto fw_check_end; + + ist30xx_get_ver_info(data); + + if (likely((fw->param_ver > 0) && (fw->param_ver < 0xFFFFFFFF))) { + if (unlikely(((fw->core_ver & MASK_FW_VER) != IST30XX_FW_VER3) && + ((fw->core_ver & MASK_FW_VER) != IST30XX_FW_VER4) && + ((fw->core_ver & MASK_FW_VER) != IST30XX_FW_VER5))) + goto fw_check_end; + + tsp_info("Version compare IC: %x(%x), BIN: %x(%x)\n", + fw->param_ver, fw->core_ver, ist30xx_param_ver, ist30xx_fw_ver); + + /* If FW version is same, check FW checksum */ + if (likely((fw->core_ver == ist30xx_fw_ver) && + (fw->param_ver == ist30xx_param_ver) && + (fw->sub_ver == 0))) { + ret = ist30xx_read_cmd(data->client, CMD_GET_CHECKSUM, &chksum); + if (unlikely((ret) || (chksum != fw->chksum))) { + tsp_warn("Checksum error, IC: %x, Bin: %x (ret: %d)\n", + chksum, fw->chksum, ret); + goto fw_check_end; + } + } + + /* + * fw->core_ver : FW core version in TSP IC + * fw->param_ver : FW version if TSP IC + * ist30xx_fw_ver : FW core version in FW Binary + * ist30xx_fw_ver : FW version in FW Binary + */ + /* If the ver of binary is higher than ver of IC, FW update operate. */ + + if (likely((fw->core_ver >= ist30xx_fw_ver) && + (fw->param_ver >= ist30xx_param_ver))) + return 0; + } + +fw_check_end: + return -EAGAIN; +} + +int ist30xx_auto_bin_update(struct ist30xx_data *data) +{ + int ret = 0; + int retry = IST30XX_FW_UPDATE_RETRY; + struct ist30xx_fw *fw = &data->fw; + + fw->buf = (u8 *)ist30xxb_fw; + fw->buf_size = sizeof(ist30xxb_fw); + +#if IST30XX_MULTIPLE_TSP + ist30xx_set_tsp_fw(data); +#else + ist30xx_get_update_info(data, fw->buf, fw->buf_size); + ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw->buf); + ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw->buf); + ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw->buf); +#endif + + tsp_info("IC: %x, Binary ver core: %x, param: %x, sub: %x\n", + data->chip_id, ist30xx_fw_ver, ist30xx_param_ver, ist30xx_sub_ver); + + mutex_lock(&ist30xx_mutex); + ret = ist30xx_check_auto_update(data); + mutex_unlock(&ist30xx_mutex); + + if (likely(ret >= 0)) + return ret; + +update_bin: // TSP is not ready / FW update + tsp_info("Update version. param(core): %x(%x, %x) -> %x(%x, %x)\n", + fw->param_ver, fw->core_ver, fw->sub_ver, + ist30xx_param_ver, ist30xx_fw_ver, ist30xx_sub_ver); + + mutex_lock(&ist30xx_mutex); + while (retry--) { + ret = ist30xx_fw_update(data->client, fw->buf, fw->buf_size, true); + if (unlikely(!ret)) + break; + } + mutex_unlock(&ist30xx_mutex); + + if (unlikely(ret)) + return ret; + + if (unlikely(retry > 0 && ist30xx_check_fw(data, fw->buf))) + goto update_bin; + + ist30xx_calibrate(IST30XX_FW_UPDATE_RETRY); + + return ret; +} +#endif // IST30XX_INTERNAL_BIN + +#define MAX_FILE_PATH 255 +/* sysfs: /sys/class/touch/firmware/firmware */ +ssize_t ist30xx_fw_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + int ret; + int fw_size = 0; + u8 *fw = NULL; + const u8 *buff = 0; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + long fsize = 0, nread = 0; + char fw_path[MAX_FILE_PATH]; + const struct firmware *request_fw = NULL; + int mode = 0; + int calib = 1; + + sscanf(buf, "%d %d", &mode, &calib); + + switch (mode) { + case MASK_UPDATE_INTERNAL: +#if IST30XX_INTERNAL_BIN + fw = ts_data->fw.buf; + fw_size = ts_data->fw.buf_size; +#else + tsp_warn("Not support internal bin!!\n", ); + return size; +#endif + break; + + case MASK_UPDATE_FW: + ret = request_firmware(&request_fw, IST30XXB_FW_NAME, + &ts_data->client->dev); + if (ret) { + tsp_warn("File not found, %s\n", IST30XXB_FW_NAME); + return size; + } + + fw = (u8 *)request_fw->data; + fw_size = (u32)request_fw->size; + break; + + case MASK_UPDATE_SDCARD: + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/touch/firmware/%s", + IST30XXB_FW_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + tsp_info("file %s open error:%d\n", fw_path, (s32)fp); + goto err_file_open; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + + buff = kzalloc((size_t)fsize, GFP_KERNEL); + if (!buff) { + tsp_info("fail to alloc buffer\n"); + goto err_alloc; + } + + nread = vfs_read(fp, (char __user *)buff, fsize, &fp->f_pos); + if (nread != fsize) { + tsp_info("mismatch fw size\n"); + goto err_fw_size; + } + + fw = (u8 *)buff; + fw_size = (u32)fsize; + + filp_close(fp, current->files); + tsp_info("firmware is loaded!!\n"); + break; + + case MASK_UPDATE_ERASE: + tsp_info("EEPROM all erase!!\n"); + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(ts_data); + ist30xxb_isp_enable(true); + ist30xxb_isp_erase(ts_data->client, IST30XXB_ISP_ERASE_ALL, 0); + ist30xxb_isp_enable(false); + ist30xx_reset(false); + ist30xx_enable_irq(ts_data); + mutex_unlock(&ist30xx_mutex); + + ist30xx_start(ts_data); + + default: + return size; + } + + ist30xx_get_update_info(ts_data, fw, fw_size); + ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw); + ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw); + ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw); + + mutex_lock(&ist30xx_mutex); + ist30xx_fw_update(ts_data->client, fw, fw_size, true); + + if (calib) + ist30xx_calibrate(1); + mutex_unlock(&ist30xx_mutex); + + ist30xx_start(ts_data); + + if (request_fw != NULL) + release_firmware(request_fw); + + if (fp != NULL) { +err_fw_size: + kfree(buff); +err_alloc: + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + } + + return size; +} + +/* sysfs: /sys/class/touch/firmware/fw_sdcard */ +ssize_t ist30xx_fw_sdcard_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int fw_size = 0; + u8 *fw = NULL; + const u8 *buff = 0; + mm_segment_t old_fs = { 0 }; + struct file *fp = NULL; + long fsize = 0, nread = 0; + char fw_path[MAX_FILE_PATH]; + + old_fs = get_fs(); + set_fs(get_ds()); + + snprintf(fw_path, MAX_FILE_PATH, "/sdcard/touch/firmware/%s", + IST30XXB_FW_NAME); + fp = filp_open(fw_path, O_RDONLY, 0); + if (IS_ERR(fp)) { + tsp_info("file %s open error:%d\n", fw_path, (s32)fp); + goto err_file_open; + } + + fsize = fp->f_path.dentry->d_inode->i_size; + + buff = kzalloc((size_t)fsize, GFP_KERNEL); + if (!buff) { + tsp_info("fail to alloc buffer\n"); + goto err_alloc; + } + + nread = vfs_read(fp, (char __user *)buff, fsize, &fp->f_pos); + if (nread != fsize) { + tsp_info("mismatch fw size\n"); + goto err_fw_size; + } + + fw = (u8 *)buff; + fw_size = (u32)fsize; + + filp_close(fp, current->files); + tsp_info("firmware is loaded!!\n"); + + ist30xx_get_update_info(ts_data, fw, fw_size); + ist30xx_fw_ver = ist30xx_parse_ver(FLAG_FW, fw); + ist30xx_param_ver = ist30xx_parse_ver(FLAG_PARAM, fw); + ist30xx_sub_ver = ist30xx_parse_ver(FLAG_SUB, fw); + + mutex_lock(&ist30xx_mutex); + ist30xx_fw_update(ts_data->client, fw, fw_size, true); + mutex_unlock(&ist30xx_mutex); + + ist30xx_start(ts_data); + +err_fw_size: + if (buff) + kfree(buff); +err_alloc: + if (fp) + filp_close(fp, NULL); +err_file_open: + set_fs(old_fs); + + return 0; +} + +/* sysfs: /sys/class/touch/firmware/firmware */ +ssize_t ist30xx_fw_status_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count; + + switch (ts_data->status.update) { + case 1: + count = sprintf(buf, "Downloading\n"); + break; + case 2: + count = sprintf(buf, "Update success, ver %x(%x) -> %x(%x, %x), " + "status : %d, gap : %d\n", + ts_data->fw.prev_param_ver, ts_data->fw.prev_core_ver, + ts_data->fw.param_ver, ts_data->fw.core_ver, + ts_data->fw.sub_ver, + CALIB_TO_STATUS(ts_data->status.calib_msg), + CALIB_TO_GAP(ts_data->status.calib_msg)); + break; + default: + count = sprintf(buf, "Pass\n"); + } + + return count; +} + +/* sysfs: /sys/class/touch/firmware/fw_read */ +u32 buf32_eeprom[IST30XX_EEPROM_SIZE / IST30XX_DATA_LEN]; +ssize_t ist30xx_fw_read_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + int i; + u8 *buf8 = (u8 *)buf32_eeprom;; + + mutex_lock(&ist30xx_mutex); + ist30xx_disable_irq(ts_data); + + ist30xxb_isp_fw_read(ts_data->client, buf32_eeprom); + for (i = 0; i < IST30XX_EEPROM_SIZE; i += 16) { + tsp_debug("%07x: %02x%02x %02x%02x %02x%02x %02x%02x " + "%02x%02x %02x%02x %02x%02x %02x%02x\n", i, + buf8[i], buf8[i + 1], buf8[i + 2], buf8[i + 3], + buf8[i + 4], buf8[i + 5], buf8[i + 6], buf8[i + 7], + buf8[i + 8], buf8[i + 9], buf8[i + 10], buf8[i + 11], + buf8[i + 12], buf8[i + 13], buf8[i + 14], buf8[i + 15]); + } + + ist30xx_reset(false); + ist30xx_enable_irq(ts_data); + mutex_unlock(&ist30xx_mutex); + + ist30xx_start(ts_data); + + return 0; +} + +/* sysfs: /sys/class/touch/firmware/version */ +ssize_t ist30xx_fw_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count; + + count = sprintf(buf, "ID: %x, f/w core: %x, param: %x, sub: %x\n", + ts_data->chip_id, ts_data->fw.core_ver, + ts_data->fw.param_ver, ts_data->fw.sub_ver); + +#if IST30XX_INTERNAL_BIN + { + char msg[128]; + + ist30xx_get_update_info(ts_data, ts_data->fw.buf, ts_data->fw.buf_size); + + count += snprintf(msg, sizeof(msg), + " Header - f/w ver: %x, param: %x, sub: %x\r\n", + ist30xx_parse_ver(FLAG_FW, ts_data->fw.buf), + ist30xx_parse_ver(FLAG_PARAM, ts_data->fw.buf), + ist30xx_parse_ver(FLAG_SUB, ts_data->fw.buf)); + strncat(buf, msg, sizeof(msg)); + } +#endif + + return count; +} + + +/* sysfs */ +static DEVICE_ATTR(fw_read, S_IRWXUGO, ist30xx_fw_read_show, NULL); +static DEVICE_ATTR(firmware, S_IRWXUGO, ist30xx_fw_status_show, + ist30xx_fw_store); +static DEVICE_ATTR(fw_sdcard, S_IRWXUGO, ist30xx_fw_sdcard_show, NULL); +static DEVICE_ATTR(version, S_IRWXUGO, ist30xx_fw_version_show, NULL); + +struct class *ist30xx_class; +struct device *ist30xx_fw_dev; + +static struct attribute *fw_attributes[] = { + &dev_attr_fw_read.attr, + &dev_attr_firmware.attr, + &dev_attr_fw_sdcard.attr, + &dev_attr_version.attr, + NULL, +}; + +static struct attribute_group fw_attr_group = { + .attrs = fw_attributes, +}; + +int ist30xx_init_update_sysfs(void) +{ + /* /sys/class/touch */ + ist30xx_class = class_create(THIS_MODULE, "touch"); + + /* /sys/class/touch/firmware */ + ist30xx_fw_dev = device_create(ist30xx_class, NULL, 0, NULL, "firmware"); + + /* /sys/class/touch/firmware/... */ + if (unlikely(sysfs_create_group(&ist30xx_fw_dev->kobj, &fw_attr_group))) + tsp_err("Failed to create sysfs group(%s)!\n", "firmware"); + + ts_data->status.update = 0; + ts_data->status.calib = 0; + + return 0; +} diff --git a/drivers/input/touchscreen/ist30xxa/ist30xx_update.h b/drivers/input/touchscreen/ist30xxa/ist30xx_update.h new file mode 100644 index 00000000..fa432b7a --- /dev/null +++ b/drivers/input/touchscreen/ist30xxa/ist30xx_update.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2010, Imagis Technology Co. Ltd. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __IST30XX_UPDATE_H__ +#define __IST30XX_UPDATE_H__ + +#include "ist30xx_tsp.h" + +#define IST30XX_INTERNAL_BIN (1) +#define IST30XX_CHECK_CALIB (0) + +#if IST30XX_INTERNAL_BIN +#define IST30XX_UPDATE_BY_WORKQUEUE (0) +#define IST30XX_UPDATE_DELAY (3 * HZ) +#endif // IST30XX_INTERNAL_BIN + +#if ((IMAGIS_TSP_IC == IMAGIS_IST30XX) || (IMAGIS_TSP_IC == IMAGIS_IST30XXB)) +#define IST30XX_EEPROM_SIZE (0x8000) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3038) +#define IST30XX_EEPROM_SIZE (0xA000) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3044) +#define IST30XX_EEPROM_SIZE (0x10000) +#endif +#define EEPROM_PAGE_SIZE (64) +#define EEPROM_BASE_ADDR (0) + +#define IST30XXB_ACCESS_ADDR (1 << 31) +#define IST30XXB_BURST_ACCESS (1 << 27) +#define IST30XXB_DA_ADDR(n) (n | IST30XXB_ACCESS_ADDR) + +#define IST30XXB_REG_TSPTYPE IST30XXB_DA_ADDR(0x40002010) + +#define IST30XXB_REG_WDTCON IST30XXB_DA_ADDR(0x40003000) +#define IST30XXB_REG_EEPMODE IST30XXB_DA_ADDR(0x40007000) +#define IST30XXB_REG_EEPADDR IST30XXB_DA_ADDR(0x40007004) +#define IST30XXB_REG_EEPWDAT IST30XXB_DA_ADDR(0x40007008) +#define IST30XXB_REG_EEPRDAT IST30XXB_DA_ADDR(0x4000700C) +#define IST30XXB_REG_EEPISPEN IST30XXB_DA_ADDR(0x40007010) +#define IST30XXB_REG_CHKSMOD IST30XXB_DA_ADDR(0x40007014) +#define IST30XXB_REG_EEPPWRCTRL IST30XXB_DA_ADDR(0x4000701C) +#define IST30XXB_REG_CHKSDAT IST30XXB_DA_ADDR(0x40007038) + +#define IST30XXB_REG_CHIPID IST30XXB_DA_ADDR(0x40000000) +#define IST30XXB_REG_PADCTRL IST30XXB_DA_ADDR(0x40000024) +#define IST30XXB_REG_LDOOSC IST30XXB_DA_ADDR(0x40000030) +#define IST30XXB_REG_CLKDIV IST30XXB_DA_ADDR(0x4000004C) + +#define IST30XXB_MEM_ADDR (0x20000000) +#define IST30XXB_MEM_ALGORITHM IST30XXB_DA_ADDR(IST30XXB_MEM_ADDR | 0x34) +#define IST30XXB_MEM_CMD IST30XXB_DA_ADDR(IST30XXB_MEM_ADDR | 0x3C) +#define IST30XXB_MEM_FINGERS IST30XXB_DA_ADDR(IST30XXB_MEM_ADDR | 0x4) + +#define IST30XXB_MEM_COUNT IST30XXB_DA_ADDR(IST30XXB_MEM_ADDR | 0x30) + +#if (IMAGIS_TSP_IC == IMAGIS_IST30XXB) +#define IST30XXB_MEM_KEYSENSITIVITY IST30XXB_DA_ADDR(IST30XXB_MEM_ADDR | 0x5F0) +#elif (IMAGIS_TSP_IC == IMAGIS_IST3038) +#define IST30XXB_MEM_KEYSENSITIVITY IST30XXB_DA_ADDR(IST30XXB_MEM_ADDR | 0x40) +#else +#error "Unknown IMAGIS_TSP_IC" +#endif + +#define IST30XX_FW_NAME "ist30xx.fw" +#define IST30XXB_FW_NAME "ist30xxb.fw" +#define IST30XXB_CURVE_NAME "ist30xxb.cv" + +#define MASK_FW_VER (0xFFFF0000) +#define IST30XX_FW_VER1 (0x00010000) +#define IST30XX_FW_VER2 (0x00020000) +#define IST30XX_FW_VER3 (0x00030000) +#define IST30XX_FW_VER4 (0x00040000) +#define IST30XX_FW_VER5 (0x00050000) + +#define IST30XX_FW_UPDATE_RETRY (3) + +#define WAIT_CALIB_CNT (50) +#define CALIB_THRESHOLD (100) + +#define CALIB_TO_GAP(n) ((n >> 16) & 0xFFF) +#define CALIB_TO_STATUS(n) ((n >> 12) & 0xF) + +#define CALIB_TO_OS_VALUE(n) ((n >> 12) & 0xFFFF) + +#define MASK_UPDATE_INTERNAL (1) +#define MASK_UPDATE_FW (2) +#define MASK_UPDATE_SDCARD (3) +#define MASK_UPDATE_ERASE (4) + +#define CHKSUM_FW (1) +#define CHKSUM_ALL (2) + +#define FLAG_FW (1) +#define FLAG_PARAM (2) +#define FLAG_SUB (3) + +#define TAGS_PARSE_OK (0) + +/* I2C Transaction size */ +#define I2C_MAX_WRITE_SIZE (64) /* bytes */ +#define I2C_MAX_READ_SIZE (8) /* bytes */ + +int ist30xx_read_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len); +int ist30xx_write_buf(struct i2c_client *client, u32 cmd, u32 *buf, u16 len); + +int ist30xxb_burst_read(struct i2c_client *client, u32 addr, u32 *buf32, int len); + +int ist30xxb_read_chksum(struct i2c_client *client, u32 *chksum); +int ist30xxb_read_chksum_all(struct i2c_client *client, u32 *chksum); + +void ist30xx_get_update_info(struct ist30xx_data *data, const u8 *buf, const u32 size); + +u32 ist30xx_parse_ver(int flag, const u8 *buf); + +int ist30xx_fw_update(struct i2c_client *client, const u8 *buf, int size, bool mode); +int ist30xx_fw_param_update(struct i2c_client *client, const u8 *buf); +int ist30xx_fw_recovery(struct ist30xx_data *data); + +int ist30xx_auto_fw_update(struct ist30xx_data *data); +int ist30xx_auto_param_update(struct ist30xx_data *data); +int ist30xx_auto_bin_update(struct ist30xx_data *data); + +int ist30xx_calibrate(int wait_cnt); +int ist30xx_calib_wait(void); + +int ist30xx_init_update_sysfs(void); + +#endif // __IST30XX_UPDATE_H__ |
