From 742868f7b04c7e37eabfff92b548e197ffc81af5 Mon Sep 17 00:00:00 2001 From: Sharath Chandra Vurukala Date: Fri, 4 Sep 2020 20:20:25 +0530 Subject: [PATCH 01/96] net:sockev: hold file reference till the sock event is sent hold file reference till the sock event is sent. Change-Id: I14d581f210c86e5771bec22a9aca7c78630e9ac1 Signed-off-by: Sharath Chandra Vurukala --- net/socket.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/net/socket.c b/net/socket.c index f16035c7ad33..4fac892daba9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -1426,9 +1426,10 @@ SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) (struct sockaddr *) &address, addrlen); } - fput_light(sock->file, fput_needed); if (!err) sockev_notify(SOCKEV_BIND, sock); + + fput_light(sock->file, fput_needed); } return err; } @@ -1455,9 +1456,10 @@ SYSCALL_DEFINE2(listen, int, fd, int, backlog) if (!err) err = sock->ops->listen(sock, backlog); - fput_light(sock->file, fput_needed); if (!err) sockev_notify(SOCKEV_LISTEN, sock); + + fput_light(sock->file, fput_needed); } return err; } -- GitLab From 2bcad4f4dffaad441f9fa3a4e38b6624f7f77199 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Thu, 10 Jun 2021 13:03:44 +0530 Subject: [PATCH 02/96] msm: adsprpc: Fix race condition in internal_control Protect add and update qos request with mutex to avoid race condition when multiple threads try to add or update request simultaneously. Change-Id: Id33b81bf85246ec69c72bad59cca068e627bb21d Acked-by: Deepika Singh Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index c7aa94f6b2ad..e7cccb1bebb4 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -407,6 +407,7 @@ struct fastrpc_file { struct mutex perf_mutex; struct pm_qos_request pm_qos_req; int qos_request; + struct mutex pm_qos_mutex; struct mutex map_mutex; struct mutex fl_map_mutex; int refcount; @@ -3110,6 +3111,7 @@ static int fastrpc_file_free(struct fastrpc_file *fl) mutex_destroy(&fl->perf_mutex); mutex_destroy(&fl->fl_map_mutex); mutex_destroy(&fl->map_mutex); + mutex_destroy(&fl->pm_qos_mutex); kfree(fl); return 0; } @@ -3611,6 +3613,7 @@ static int fastrpc_device_open(struct inode *inode, struct file *filp) hlist_add_head(&fl->hn, &me->drivers); spin_unlock(&me->hlock); mutex_init(&fl->perf_mutex); + mutex_init(&fl->pm_qos_mutex); return 0; } @@ -3709,12 +3712,14 @@ static int fastrpc_internal_control(struct fastrpc_file *fl, VERIFY(err, latency != 0); if (err) goto bail; + mutex_lock(&fl->pm_qos_mutex); if (!fl->qos_request) { pm_qos_add_request(&fl->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, latency); fl->qos_request = 1; } else pm_qos_update_request(&fl->pm_qos_req, latency); + mutex_unlock(&fl->pm_qos_mutex); break; case FASTRPC_CONTROL_SMMU: if (!me->legacy) -- GitLab From 0e25733be02b29b736720f2efbcc1a28b35a7141 Mon Sep 17 00:00:00 2001 From: Swathi K Date: Wed, 14 Jul 2021 17:51:10 +0530 Subject: [PATCH 03/96] msm: adsprpc: Handle UAF in process shell memory Added flag to indicate memory used in process initialization. And, this memory would not removed in internal unmap to avoid UAF or double free. Change-Id: Ifa621dee171b3d1f98b82302c847f4d767f3e736 Signed-off-by: Swathi K --- drivers/char/adsprpc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index c7aa94f6b2ad..d063fe0c0f0c 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -352,6 +352,7 @@ struct fastrpc_mmap { int uncached; int secure; uintptr_t attr; + bool is_filemap; /*flag to indicate map used in process init*/ }; enum fastrpc_perfkeys { @@ -700,9 +701,10 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, spin_lock(&me->hlock); hlist_for_each_entry_safe(map, n, &me->maps, hn) { - if (map->raddr == va && + if (map->refs == 1 && map->raddr == va && map->raddr + map->len == va + len && - map->refs == 1) { + /*Remove map if not used in process initialization*/ + !map->is_filemap) { match = map; hlist_del_init(&map->hn); break; @@ -714,9 +716,10 @@ static int fastrpc_mmap_remove(struct fastrpc_file *fl, uintptr_t va, return 0; } hlist_for_each_entry_safe(map, n, &fl->maps, hn) { - if (map->raddr == va && + if (map->refs == 1 && map->raddr == va && map->raddr + map->len == va + len && - map->refs == 1) { + /*Remove map if not used in process initialization*/ + !map->is_filemap) { match = map; hlist_del_init(&map->hn); break; @@ -858,6 +861,7 @@ static int fastrpc_mmap_create(struct fastrpc_file *fl, int fd, map->fl = fl; map->fd = fd; map->attr = attr; + map->is_filemap = false; if (mflags == ADSP_MMAP_HEAP_ADDR || mflags == ADSP_MMAP_REMOTE_HEAP_ADDR) { unsigned long dma_attrs = DMA_ATTR_SKIP_ZEROING | @@ -2243,6 +2247,8 @@ static int fastrpc_init_process(struct fastrpc_file *fl, mutex_lock(&fl->fl_map_mutex); VERIFY(err, !fastrpc_mmap_create(fl, init->filefd, 0, init->file, init->filelen, mflags, &file)); + if (file) + file->is_filemap = true; mutex_unlock(&fl->fl_map_mutex); if (err) goto bail; -- GitLab From 768ec57eb66c709519e20fd9895f597f6e24095e Mon Sep 17 00:00:00 2001 From: Krishna Manikandan Date: Thu, 8 Jul 2021 11:17:16 +0530 Subject: [PATCH 04/96] disp: msm: sde: add null check for drm file in msm_release Drm file is not set to NULL after freeing it from drm release. This can result in use-after-free issues in some scenarios. Add a mutex lock and other proper null checks to prevent such issues. Change-Id: Ic35b0a76166b0f47a354b1737e6f4c3ac1437ed4 Signed-off-by: Nirmal Abraham Signed-off-by: Althaf Neelanchirayil Signed-off-by: vbejawad --- drivers/gpu/drm/msm/msm_drv.c | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index ff8c1cd9aba8..ce090d69d9e2 100755 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -57,6 +57,8 @@ #define MSM_VERSION_MINOR 2 #define MSM_VERSION_PATCHLEVEL 0 +static DEFINE_MUTEX(msm_release_lock); + static void msm_fb_output_poll_changed(struct drm_device *dev) { struct msm_drm_private *priv = NULL; @@ -1420,13 +1422,25 @@ void msm_mode_object_event_notify(struct drm_mode_object *obj, static int msm_release(struct inode *inode, struct file *filp) { struct drm_file *file_priv = filp->private_data; - struct drm_minor *minor = file_priv->minor; - struct drm_device *dev = minor->dev; - struct msm_drm_private *priv = dev->dev_private; + struct drm_minor *minor; + struct drm_device *dev; + struct msm_drm_private *priv; struct msm_drm_event *node, *temp, *tmp_node; u32 count; unsigned long flags; LIST_HEAD(tmp_head); + int ret = 0; + + mutex_lock(&msm_release_lock); + + if (!file_priv) { + ret = -EINVAL; + goto end; + } + + minor = file_priv->minor; + dev = minor->dev; + priv = dev->dev_private; spin_lock_irqsave(&dev->event_lock, flags); list_for_each_entry_safe(node, temp, &priv->client_event_list, @@ -1454,7 +1468,11 @@ static int msm_release(struct inode *inode, struct file *filp) kfree(node); } - return drm_release(inode, filp); + ret = drm_release(inode, filp); + filp->private_data = NULL; +end: + mutex_unlock(&msm_release_lock); + return ret; } /** -- GitLab From 336ada18f8411cea110e44cbe514ad3d6ed9e303 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Thu, 18 Mar 2021 14:04:49 +0530 Subject: [PATCH 05/96] msm: adsprpc: overflow vulnerability by race condition in adsprpc driver Create local copy of current->comm to avoid the possibility of modification in race condition. Change-Id: Ie10f6577ed7edb9279a36039348e7a1ad25239f9 Acked-by: Nishant Chaubey Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index c7aa94f6b2ad..0f179f00573f 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -3618,22 +3618,26 @@ static int fastrpc_set_process_info(struct fastrpc_file *fl) { int err = 0, buf_size = 0; char strpid[PID_SIZE]; + char cur_comm[TASK_COMM_LEN]; + memcpy(cur_comm, current->comm, TASK_COMM_LEN); + cur_comm[TASK_COMM_LEN-1] = '\0'; fl->tgid = current->tgid; snprintf(strpid, PID_SIZE, "%d", current->pid); - buf_size = strlen(current->comm) + strlen("_") + strlen(strpid) + 1; + buf_size = strlen(cur_comm) + strlen("_") + strlen(strpid) + 1; fl->debug_buf = kzalloc(buf_size, GFP_KERNEL); if (!fl->debug_buf) { err = -ENOMEM; return err; } - snprintf(fl->debug_buf, UL_SIZE, "%.10s%s%d", - current->comm, "_", current->pid); + snprintf(fl->debug_buf, buf_size, "%.10s%s%d", + cur_comm, "_", current->pid); fl->debugfs_file = debugfs_create_file(fl->debug_buf, 0644, debugfs_root, fl, &debugfs_fops); if (!fl->debugfs_file) pr_warn("Error: %s: %s: failed to create debugfs file %s\n", - current->comm, __func__, fl->debug_buf); + cur_comm, __func__, fl->debug_buf); + return err; } -- GitLab From 056794d452d3ef74f2b6ead501a2f2d6381d3ce8 Mon Sep 17 00:00:00 2001 From: Kamal Agrawal Date: Mon, 13 Sep 2021 15:59:25 +0530 Subject: [PATCH 06/96] msm: kgsl: Fix out of bound write in adreno_profile_submit_time Make sure there is enough room in the memory descriptor to store the entire profiling buffer object. Change-Id: I1e1c73097bb2bba9645b0a3c66fdbbc71d8ba8fa Signed-off-by: Kamal Agrawal --- drivers/gpu/msm/kgsl_drawobj.c | 35 +++++++++++----------------------- 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/msm/kgsl_drawobj.c b/drivers/gpu/msm/kgsl_drawobj.c index 1bfc9050bb47..b0dd4ac598b3 100644 --- a/drivers/gpu/msm/kgsl_drawobj.c +++ b/drivers/gpu/msm/kgsl_drawobj.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved. +/* Copyright (c) 2016-2019,2021, The Linux Foundation. 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 version 2 and @@ -569,6 +569,7 @@ static void add_profiling_buffer(struct kgsl_device *device, { struct kgsl_mem_entry *entry; struct kgsl_drawobj *drawobj = DRAWOBJ(cmdobj); + u64 start; if (!(drawobj->flags & KGSL_DRAWOBJ_PROFILING)) return; @@ -585,7 +586,14 @@ static void add_profiling_buffer(struct kgsl_device *device, gpuaddr); if (entry != NULL) { - if (!kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) { + start = id ? (entry->memdesc.gpuaddr + offset) : gpuaddr; + /* + * Make sure there is enough room in the object to store the + * entire profiling buffer object + */ + if (!kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size) || + !kgsl_gpuaddr_in_memdesc(&entry->memdesc, start, + sizeof(struct kgsl_drawobj_profiling_buffer))) { kgsl_mem_entry_put(entry); entry = NULL; } @@ -598,28 +606,7 @@ static void add_profiling_buffer(struct kgsl_device *device, return; } - - if (!id) { - cmdobj->profiling_buffer_gpuaddr = gpuaddr; - } else { - u64 off = offset + sizeof(struct kgsl_drawobj_profiling_buffer); - - /* - * Make sure there is enough room in the object to store the - * entire profiling buffer object - */ - if (off < offset || off >= entry->memdesc.size) { - dev_err(device->dev, - "ignore invalid profile offset ctxt %d id %d offset %lld gpuaddr %llx size %lld\n", - drawobj->context->id, id, offset, gpuaddr, size); - kgsl_mem_entry_put(entry); - return; - } - - cmdobj->profiling_buffer_gpuaddr = - entry->memdesc.gpuaddr + offset; - } - + cmdobj->profiling_buffer_gpuaddr = start; cmdobj->profiling_buf_entry = entry; } -- GitLab From 8a9ed440fbc4edf9285d9c892613bc82c16ff4b0 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Tue, 9 Feb 2021 02:35:41 -0800 Subject: [PATCH 07/96] msm: adsprpc: null pointer check for fl Adding a null pointer check for fl before dereferencing. Change-Id: I1691a406f819d740b5649da40c41989c0943f9ce Acked-by: Krishnaiah Tadakamalla Signed-off-by: Jeya R --- drivers/char/adsprpc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 233c3c53bca2..ac69b3ddaf5e 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -743,9 +743,13 @@ static void fastrpc_mmap_free(struct fastrpc_mmap *map, uint32_t flags) if (!map) return; fl = map->fl; - if (!fl) + /* remote heap and dynamic loading memory + * maps expected to initialize with NULL + */ + if (!fl && !(map->flags == ADSP_MMAP_HEAP_ADDR || + map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) return; - if (!(map->flags == ADSP_MMAP_HEAP_ADDR || + if (fl && !(map->flags == ADSP_MMAP_HEAP_ADDR || map->flags == ADSP_MMAP_REMOTE_HEAP_ADDR)) { cid = fl->cid; VERIFY(err, cid >= ADSP_DOMAIN_ID && cid < NUM_CHANNELS); -- GitLab From 61b3349abda245df755f0955c4e071273c2efa49 Mon Sep 17 00:00:00 2001 From: Akhil P Oommen Date: Wed, 20 Oct 2021 12:50:29 +0530 Subject: [PATCH 08/96] msm: kgsl: Update register protection config Update the register protection configuration as per the latest recommendation. Change-Id: I70365268e8e4c7ee4ff28538f22e970822e4edf0 Signed-off-by: Akhil P Oommen Signed-off-by: Pranav Patel --- drivers/gpu/msm/adreno_a6xx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/msm/adreno_a6xx.c b/drivers/gpu/msm/adreno_a6xx.c index 754e41987fe6..5a3a26d0083f 100644 --- a/drivers/gpu/msm/adreno_a6xx.c +++ b/drivers/gpu/msm/adreno_a6xx.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2017-2018,2020 The Linux Foundation. All rights reserved. +/* Copyright (c) 2017-2018,2020-2021, The Linux Foundation. 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 version 2 and @@ -277,6 +277,7 @@ static struct a6xx_protected_regs { { 0x8D0, 0x23, 0 }, { 0x980, 0x4, 0 }, { 0xA630, 0x0, 1 }, + { 0x1b400, 0x1fff, 1 }, }; /* IFPC & Preemption static powerup restore list */ -- GitLab From a38c9cb7cb46ad2d7124c20e033e047d8829128e Mon Sep 17 00:00:00 2001 From: Vamsi Krishna Gattupalli Date: Thu, 11 Nov 2021 17:19:03 +0530 Subject: [PATCH 09/96] msm: adsprpc: Allocate buffer taking NULL byte into consideration When attaching to audiopd on ADSP, allocate one extra byte for the process name so that it is null terminated when data is copied from file pointer in the userspace. Change-Id: I98ac64a4c16f44fa4fd0e09da1648b9d78d65a82 Signed-off-by: Vamsi Krishna Gattupalli --- drivers/char/adsprpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index ac69b3ddaf5e..4398d60dc6d4 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2332,7 +2332,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (!init->filelen) goto bail; - proc_name = kzalloc(init->filelen, GFP_KERNEL); + proc_name = kzalloc(init->filelen + 1, GFP_KERNEL); VERIFY(err, !IS_ERR_OR_NULL(proc_name)); if (err) goto bail; -- GitLab From b31640aa5ce837e6274c74d36495aa642b4cf6b0 Mon Sep 17 00:00:00 2001 From: srikanthreddy ponogoti Date: Wed, 20 Oct 2021 16:41:38 +0530 Subject: [PATCH 10/96] disp: msm: sde: protect file private structure with mutex lock Access file private data structures inside the mutex lock only to avoid use-after-free issues. Change-Id: Ibae25aa31eeb7a7afada3dd0ecc236615223dfc9 Signed-off-by: srikanthreddy ponogoti --- drivers/gpu/drm/msm/msm_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index ce090d69d9e2..d9708d1811be 100755 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -1421,7 +1421,7 @@ void msm_mode_object_event_notify(struct drm_mode_object *obj, static int msm_release(struct inode *inode, struct file *filp) { - struct drm_file *file_priv = filp->private_data; + struct drm_file *file_priv; struct drm_minor *minor; struct drm_device *dev; struct msm_drm_private *priv; @@ -1433,6 +1433,7 @@ static int msm_release(struct inode *inode, struct file *filp) mutex_lock(&msm_release_lock); + file_priv = filp->private_data; if (!file_priv) { ret = -EINVAL; goto end; -- GitLab From f7efd5496fafefbd6e7fbeb7414bc5d7ccd8dffc Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Thu, 3 Dec 2020 02:25:05 +0100 Subject: [PATCH 11/96] tty: Fix ->session locking commit c8bcd9c5be24fb9e6132e97da5a35e55a83e36b9 upstream. Currently, locking of ->session is very inconsistent; most places protect it using the legacy tty mutex, but disassociate_ctty(), __do_SAK(), tiocspgrp() and tiocgsid() don't. Two of the writers hold the ctrl_lock (because they already need it for ->pgrp), but __proc_set_tty() doesn't do that yet. On a PREEMPT=y system, an unprivileged user can theoretically abuse this broken locking to read 4 bytes of freed memory via TIOCGSID if tiocgsid() is preempted long enough at the right point. (Other things might also go wrong, especially if root-only ioctls are involved; I'm not sure about that.) Change the locking on ->session such that: - tty_lock() is held by all writers: By making disassociate_ctty() hold it. This should be fine because the same lock can already be taken through the call to tty_vhangup_session(). The tricky part is that we need to shorten the area covered by siglock to be able to take tty_lock() without ugly retry logic; as far as I can tell, this should be fine, since nothing in the signal_struct is touched in the `if (tty)` branch. - ctrl_lock is held by all writers: By changing __proc_set_tty() to hold the lock a little longer. - All readers that aren't holding tty_lock() hold ctrl_lock: By adding locking to tiocgsid() and __do_SAK(), and expanding the area covered by ctrl_lock in tiocspgrp(). Cc: stable@kernel.org Signed-off-by: Jann Horn Reviewed-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 5d64f8bacf47f7f46abf0d2a6fd8238859d8fdee) Issue: FP3SEC-45 Change-Id: I0c3c49edf32a9c3a8b0a92adc32f482faba206e0 --- drivers/tty/tty_io.c | 51 ++++++++++++++++++++++++++++++++------------ include/linux/tty.h | 4 ++++ 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 08e47dec0901..d78334283819 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -544,8 +544,8 @@ static void __proc_set_tty(struct tty_struct *tty) put_pid(tty->session); put_pid(tty->pgrp); tty->pgrp = get_pid(task_pgrp(current)); - spin_unlock_irqrestore(&tty->ctrl_lock, flags); tty->session = get_pid(task_session(current)); + spin_unlock_irqrestore(&tty->ctrl_lock, flags); if (current->signal->tty) { tty_debug(tty, "current tty %s not NULL!!\n", current->signal->tty->name); @@ -935,21 +935,24 @@ void disassociate_ctty(int on_exit) spin_lock_irq(¤t->sighand->siglock); put_pid(current->signal->tty_old_pgrp); current->signal->tty_old_pgrp = NULL; - tty = tty_kref_get(current->signal->tty); + spin_unlock_irq(¤t->sighand->siglock); + if (tty) { unsigned long flags; + + tty_lock(tty); spin_lock_irqsave(&tty->ctrl_lock, flags); put_pid(tty->session); put_pid(tty->pgrp); tty->session = NULL; tty->pgrp = NULL; spin_unlock_irqrestore(&tty->ctrl_lock, flags); + tty_unlock(tty); tty_kref_put(tty); } else tty_debug_hangup(tty, "no current tty\n"); - spin_unlock_irq(¤t->sighand->siglock); /* Now clear signal->tty under the lock */ read_lock(&tasklist_lock); session_clear_tty(task_session(current)); @@ -2632,14 +2635,19 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t return -ENOTTY; if (retval) return retval; - if (!current->signal->tty || - (current->signal->tty != real_tty) || - (real_tty->session != task_session(current))) - return -ENOTTY; + if (get_user(pgrp_nr, p)) return -EFAULT; if (pgrp_nr < 0) return -EINVAL; + + spin_lock_irq(&real_tty->ctrl_lock); + if (!current->signal->tty || + (current->signal->tty != real_tty) || + (real_tty->session != task_session(current))) { + retval = -ENOTTY; + goto out_unlock_ctrl; + } rcu_read_lock(); pgrp = find_vpid(pgrp_nr); retval = -ESRCH; @@ -2649,12 +2657,12 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t if (session_of_pgrp(pgrp) != task_session(current)) goto out_unlock; retval = 0; - spin_lock_irq(&tty->ctrl_lock); put_pid(real_tty->pgrp); real_tty->pgrp = get_pid(pgrp); - spin_unlock_irq(&tty->ctrl_lock); out_unlock: rcu_read_unlock(); +out_unlock_ctrl: + spin_unlock_irq(&real_tty->ctrl_lock); return retval; } @@ -2666,21 +2674,31 @@ static int tiocspgrp(struct tty_struct *tty, struct tty_struct *real_tty, pid_t * * Obtain the session id of the tty. If there is no session * return an error. - * - * Locking: none. Reference to current->signal->tty is safe. */ static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p) { + unsigned long flags; + pid_t sid; + /* * (tty == real_tty) is a cheap way of * testing if the tty is NOT a master pty. */ if (tty == real_tty && current->signal->tty != real_tty) return -ENOTTY; + + spin_lock_irqsave(&real_tty->ctrl_lock, flags); if (!real_tty->session) - return -ENOTTY; - return put_user(pid_vnr(real_tty->session), p); + goto err; + sid = pid_vnr(real_tty->session); + spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); + + return put_user(sid, p); + +err: + spin_unlock_irqrestore(&real_tty->ctrl_lock, flags); + return -ENOTTY; } /** @@ -3098,10 +3116,14 @@ void __do_SAK(struct tty_struct *tty) struct task_struct *g, *p; struct pid *session; int i; + unsigned long flags; if (!tty) return; - session = tty->session; + + spin_lock_irqsave(&tty->ctrl_lock, flags); + session = get_pid(tty->session); + spin_unlock_irqrestore(&tty->ctrl_lock, flags); tty_ldisc_flush(tty); @@ -3133,6 +3155,7 @@ void __do_SAK(struct tty_struct *tty) task_unlock(p); } while_each_thread(g, p); read_unlock(&tasklist_lock); + put_pid(session); #endif } diff --git a/include/linux/tty.h b/include/linux/tty.h index 31c9bbce4778..c67ef6fa6e95 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -293,6 +293,10 @@ struct tty_struct { struct termiox *termiox; /* May be NULL for unsupported */ char name[64]; struct pid *pgrp; /* Protected by ctrl lock */ + /* + * Writes protected by both ctrl lock and legacy mutex, readers must use + * at least one of them. + */ struct pid *session; unsigned long flags; int count; -- GitLab From b851f5b802aa96dc37dab47871b4e9e996cd259d Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 12 Mar 2021 08:59:48 -0800 Subject: [PATCH 12/96] net: qrtr: fix a kernel-infoleak in qrtr_recvmsg() commit 50535249f624d0072cd885bcdce4e4b6fb770160 upstream. struct sockaddr_qrtr has a 2-byte hole, and qrtr_recvmsg() currently does not clear it before copying kernel data to user space. It might be too late to name the hole since sockaddr_qrtr structure is uapi. BUG: KMSAN: kernel-infoleak in kmsan_copy_to_user+0x9c/0xb0 mm/kmsan/kmsan_hooks.c:249 CPU: 0 PID: 29705 Comm: syz-executor.3 Not tainted 5.11.0-rc7-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Call Trace: __dump_stack lib/dump_stack.c:79 [inline] dump_stack+0x21c/0x280 lib/dump_stack.c:120 kmsan_report+0xfb/0x1e0 mm/kmsan/kmsan_report.c:118 kmsan_internal_check_memory+0x202/0x520 mm/kmsan/kmsan.c:402 kmsan_copy_to_user+0x9c/0xb0 mm/kmsan/kmsan_hooks.c:249 instrument_copy_to_user include/linux/instrumented.h:121 [inline] _copy_to_user+0x1ac/0x270 lib/usercopy.c:33 copy_to_user include/linux/uaccess.h:209 [inline] move_addr_to_user+0x3a2/0x640 net/socket.c:237 ____sys_recvmsg+0x696/0xd50 net/socket.c:2575 ___sys_recvmsg net/socket.c:2610 [inline] do_recvmmsg+0xa97/0x22d0 net/socket.c:2710 __sys_recvmmsg net/socket.c:2789 [inline] __do_sys_recvmmsg net/socket.c:2812 [inline] __se_sys_recvmmsg+0x24a/0x410 net/socket.c:2805 __x64_sys_recvmmsg+0x62/0x80 net/socket.c:2805 do_syscall_64+0x9f/0x140 arch/x86/entry/common.c:48 entry_SYSCALL_64_after_hwframe+0x44/0xa9 RIP: 0033:0x465f69 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f43659d6188 EFLAGS: 00000246 ORIG_RAX: 000000000000012b RAX: ffffffffffffffda RBX: 000000000056bf60 RCX: 0000000000465f69 RDX: 0000000000000008 RSI: 0000000020003e40 RDI: 0000000000000003 RBP: 00000000004bfa8f R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000010060 R11: 0000000000000246 R12: 000000000056bf60 R13: 0000000000a9fb1f R14: 00007f43659d6300 R15: 0000000000022000 Local variable ----addr@____sys_recvmsg created at: ____sys_recvmsg+0x168/0xd50 net/socket.c:2550 ____sys_recvmsg+0x168/0xd50 net/socket.c:2550 Bytes 2-3 of 12 are uninitialized Memory access of size 12 starts at ffff88817c627b40 Data copied to user address 0000000020000140 Fixes: bdabad3e363d ("net: Add Qualcomm IPC router") Signed-off-by: Eric Dumazet Cc: Courtney Cavin Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ab29b020bc29aecaa05e29063cddea83df393023) Issue: FP3SEC-66 Change-Id: I264291af8e2ad302a07a2fdb93fbc7cc985f41a3 --- net/qrtr/qrtr.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/net/qrtr/qrtr.c b/net/qrtr/qrtr.c index c72d59ebb906..853abe3c06a1 100644 --- a/net/qrtr/qrtr.c +++ b/net/qrtr/qrtr.c @@ -714,6 +714,11 @@ static int qrtr_recvmsg(struct socket *sock, struct msghdr *msg, rc = copied; if (addr) { + /* There is an anonymous 2-byte hole after sq_family, + * make sure to clear it. + */ + memset(addr, 0, sizeof(*addr)); + addr->sq_family = AF_QIPCRTR; addr->sq_node = le32_to_cpu(phdr->src_node_id); addr->sq_port = le32_to_cpu(phdr->src_port_id); -- GitLab From b30f0869c3c579b06a224335be67b28d1f725718 Mon Sep 17 00:00:00 2001 From: Jeya R Date: Fri, 9 Apr 2021 13:22:31 +0530 Subject: [PATCH 13/96] msm: adsprpc: Allocate buffer taking NULL byte into consideration When attaching to audiopd on ADSP, allocate one extra byte for the process name so that it is null terminated when data is copied from file pointer in the userspace. Change-Id: Iffb9ef5cb0198ff7cbf44d0f3be03a1c9f29a90f Acked-by: Vishnu Karthik D Signed-off-by: Jeya R (cherry picked from commit 4d5a6020f9fc49c83e7808a63a2a8088225cde81) Issue: FP3SEC-88 --- drivers/char/adsprpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index cd481f49be3e..642bd4a47fd5 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -2361,7 +2361,7 @@ static int fastrpc_init_process(struct fastrpc_file *fl, if (!init->filelen) goto bail; - proc_name = kzalloc(init->filelen, GFP_KERNEL); + proc_name = kzalloc(init->filelen + 1, GFP_KERNEL); VERIFY(err, !IS_ERR_OR_NULL(proc_name)); if (err) goto bail; -- GitLab From 05030f5cc6e997084865e23e2f67815b5e2ac552 Mon Sep 17 00:00:00 2001 From: Hridya Valsaraju Date: Sun, 25 Jul 2021 20:49:06 -0700 Subject: [PATCH 14/96] ANDROID: staging: ion: move buffer kmap from begin/end_cpu_access() Since dma_buf_begin/end_cpu_access() calls always used to bracket dma_buf_kmap/kunmap calls, ION performed kmap/kunmap invocations for the buffer during dma_buf_begin/end_cpu_access() calls and cached the results with a kmap counter. However, dma_buf_begin/end_cpu_access() invocations can be triggered from the userspace using the DMA_BUF_IOC_SYNC ioctl as well. This means that a mapping that was created by a device driver using by a dma_buf_kmap() call or an ion_map_kernel() call could be unmapped from userspace if a client accidentally(or maliciously) invoked DMA_BUF_IOCTL_SYNC IOCTL with 'DMA_BUF_SYNC_END' argument since this would inturn invoke dma_buf_end_cpu_access() which would then decrement the kmap counter and invoke kunmap() when the counter gets to 0. This patch moves the kmap/kunmap operations from the begin/end_cpu_access() DMA-BUF ops to the map/unmap DMA-BUF ops to prevent the issue. Bug: 187527909 Change-Id: I00dc8eefefb1f3aab99e770f90d624011f7740f0 [hridya: minor conflicts during cherry-picking] Signed-off-by: Hridya Valsaraju Issue: FP3SEC-110 (cherry picked from commit 41a097c0ed6658bf451c5cf993ab0469eb1ce4a5) (cherry picked from commit 4673c6b76ea9008e2219415a10af2b9b0764e00f) --- drivers/staging/android/ion/ion.c | 43 +++++++++++++++++-------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 7fec28cf3850..46decb1669c9 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1349,42 +1349,45 @@ static void ion_dma_buf_release(struct dma_buf *dmabuf) static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset) { struct ion_buffer *buffer = dmabuf->priv; + void *vaddr; + + if (!buffer->heap->ops->map_kernel) { + pr_err("%s: map kernel is not implemented by this heap.\n", + __func__); + return ERR_PTR(-ENOTTY); + } + mutex_lock(&buffer->lock); + vaddr = ion_buffer_kmap_get(buffer); + mutex_unlock(&buffer->lock); - return buffer->vaddr + offset * PAGE_SIZE; + if (IS_ERR(vaddr)) + return vaddr; + + return vaddr + offset * PAGE_SIZE; } static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset, void *ptr) { + struct ion_buffer *buffer = dmabuf->priv; + + if (buffer->heap->ops->map_kernel) { + mutex_lock(&buffer->lock); + ion_buffer_kmap_put(buffer); + mutex_unlock(&buffer->lock); + } + } static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { - struct ion_buffer *buffer = dmabuf->priv; - void *vaddr; - - if (!buffer->heap->ops->map_kernel) { - pr_err("%s: map kernel is not implemented by this heap.\n", - __func__); - return -ENODEV; - } - - mutex_lock(&buffer->lock); - vaddr = ion_buffer_kmap_get(buffer); - mutex_unlock(&buffer->lock); - return PTR_ERR_OR_ZERO(vaddr); + return 0; } static int ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, enum dma_data_direction direction) { - struct ion_buffer *buffer = dmabuf->priv; - - mutex_lock(&buffer->lock); - ion_buffer_kmap_put(buffer); - mutex_unlock(&buffer->lock); - return 0; } -- GitLab From 8516b37d4f3cba609273b63ad22fef3de1ae07d6 Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Tue, 4 Feb 2020 13:40:29 -0500 Subject: [PATCH 15/96] skbuff: fix a data race in skb_queue_len() [ Upstream commit 86b18aaa2b5b5bb48e609cd591b3d2d0fdbe0442 ] sk_buff.qlen can be accessed concurrently as noticed by KCSAN, BUG: KCSAN: data-race in __skb_try_recv_from_queue / unix_dgram_sendmsg read to 0xffff8a1b1d8a81c0 of 4 bytes by task 5371 on cpu 96: unix_dgram_sendmsg+0x9a9/0xb70 include/linux/skbuff.h:1821 net/unix/af_unix.c:1761 ____sys_sendmsg+0x33e/0x370 ___sys_sendmsg+0xa6/0xf0 __sys_sendmsg+0x69/0xf0 __x64_sys_sendmsg+0x51/0x70 do_syscall_64+0x91/0xb47 entry_SYSCALL_64_after_hwframe+0x49/0xbe write to 0xffff8a1b1d8a81c0 of 4 bytes by task 1 on cpu 99: __skb_try_recv_from_queue+0x327/0x410 include/linux/skbuff.h:2029 __skb_try_recv_datagram+0xbe/0x220 unix_dgram_recvmsg+0xee/0x850 ____sys_recvmsg+0x1fb/0x210 ___sys_recvmsg+0xa2/0xf0 __sys_recvmsg+0x66/0xf0 __x64_sys_recvmsg+0x51/0x70 do_syscall_64+0x91/0xb47 entry_SYSCALL_64_after_hwframe+0x49/0xbe Since only the read is operating as lockless, it could introduce a logic bug in unix_recvq_full() due to the load tearing. Fix it by adding a lockless variant of skb_queue_len() and unix_recvq_full() where READ_ONCE() is on the read while WRITE_ONCE() is on the write similar to the commit d7d16a89350a ("net: add skb_queue_empty_lockless()"). Signed-off-by: Qian Cai Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (cherry picked from commit ce5d34a31676bb33b578577d64dcf4111a03eceb) Change-Id: Ia72d1e605cb54a5d1f8ecf359b590120c3607cc4 (cherry picked from commit a12e9436663b4689e5c35c144b384c97428ca1bc) --- include/linux/skbuff.h | 14 +++++++++++++- net/unix/af_unix.c | 11 +++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fdde51a16c87..55466725d352 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1553,6 +1553,18 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_) return list_->qlen; } +/** + * skb_queue_len_lockless - get queue length + * @list_: list to measure + * + * Return the length of an &sk_buff queue. + * This variant can be used in lockless contexts. + */ +static inline __u32 skb_queue_len_lockless(const struct sk_buff_head *list_) +{ + return READ_ONCE(list_->qlen); +} + /** * __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head * @list: queue to initialize @@ -1756,7 +1768,7 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list) { struct sk_buff *next, *prev; - list->qlen--; + WRITE_ONCE(list->qlen, list->qlen - 1); next = skb->next; prev = skb->prev; skb->next = skb->prev = NULL; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e7012a509035..3aaf209cf7a1 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -191,11 +191,17 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk) return unix_peer(osk) == NULL || unix_our_peer(sk, osk); } -static inline int unix_recvq_full(struct sock const *sk) +static inline int unix_recvq_full(const struct sock *sk) { return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; } +static inline int unix_recvq_full_lockless(const struct sock *sk) +{ + return skb_queue_len_lockless(&sk->sk_receive_queue) > + READ_ONCE(sk->sk_max_ack_backlog); +} + struct sock *unix_peer_get(struct sock *s) { struct sock *peer; @@ -1793,7 +1799,8 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg, * - unix_peer(sk) == sk by time of get but disconnected before lock */ if (other != sk && - unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { + unlikely(unix_peer(other) != sk && + unix_recvq_full_lockless(other))) { if (timeo) { timeo = unix_wait_for_peer(other, timeo); -- GitLab From cdb44dd05c4e5b2bf10a53a9a272031a12f222fc Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 16 Jun 2021 07:47:15 -0700 Subject: [PATCH 16/96] net/af_unix: fix a data-race in unix_dgram_sendmsg / unix_release_sock [ Upstream commit a494bd642d9120648b06bb7d28ce6d05f55a7819 ] While unix_may_send(sk, osk) is called while osk is locked, it appears unix_release_sock() can overwrite unix_peer() after this lock has been released, making KCSAN unhappy. Changing unix_release_sock() to access/change unix_peer() before lock is released should fix this issue. BUG: KCSAN: data-race in unix_dgram_sendmsg / unix_release_sock write to 0xffff88810465a338 of 8 bytes by task 20852 on cpu 1: unix_release_sock+0x4ed/0x6e0 net/unix/af_unix.c:558 unix_release+0x2f/0x50 net/unix/af_unix.c:859 __sock_release net/socket.c:599 [inline] sock_close+0x6c/0x150 net/socket.c:1258 __fput+0x25b/0x4e0 fs/file_table.c:280 ____fput+0x11/0x20 fs/file_table.c:313 task_work_run+0xae/0x130 kernel/task_work.c:164 tracehook_notify_resume include/linux/tracehook.h:189 [inline] exit_to_user_mode_loop kernel/entry/common.c:175 [inline] exit_to_user_mode_prepare+0x156/0x190 kernel/entry/common.c:209 __syscall_exit_to_user_mode_work kernel/entry/common.c:291 [inline] syscall_exit_to_user_mode+0x20/0x40 kernel/entry/common.c:302 do_syscall_64+0x56/0x90 arch/x86/entry/common.c:57 entry_SYSCALL_64_after_hwframe+0x44/0xae read to 0xffff88810465a338 of 8 bytes by task 20888 on cpu 0: unix_may_send net/unix/af_unix.c:189 [inline] unix_dgram_sendmsg+0x923/0x1610 net/unix/af_unix.c:1712 sock_sendmsg_nosec net/socket.c:654 [inline] sock_sendmsg net/socket.c:674 [inline] ____sys_sendmsg+0x360/0x4d0 net/socket.c:2350 ___sys_sendmsg net/socket.c:2404 [inline] __sys_sendmmsg+0x315/0x4b0 net/socket.c:2490 __do_sys_sendmmsg net/socket.c:2519 [inline] __se_sys_sendmmsg net/socket.c:2516 [inline] __x64_sys_sendmmsg+0x53/0x60 net/socket.c:2516 do_syscall_64+0x4a/0x90 arch/x86/entry/common.c:47 entry_SYSCALL_64_after_hwframe+0x44/0xae value changed: 0xffff888167905400 -> 0x0000000000000000 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 20888 Comm: syz-executor.0 Not tainted 5.13.0-rc5-syzkaller #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller Signed-off-by: Sasha Levin (cherry picked from commit a1461c0d7c155c969395d2757e17795bd7e7f5e0) Change-Id: I2c599ba822c2fe7790929255da45e8c72fdb21d3 (cherry picked from commit 0c36db775727849c12f788043fa20f2abae30cb2) --- net/unix/af_unix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 3aaf209cf7a1..43a17fb9f290 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -534,12 +534,14 @@ static void unix_release_sock(struct sock *sk, int embrion) u->path.mnt = NULL; state = sk->sk_state; sk->sk_state = TCP_CLOSE; + + skpair = unix_peer(sk); + unix_peer(sk) = NULL; + unix_state_unlock(sk); wake_up_interruptible_all(&u->peer_wait); - skpair = unix_peer(sk); - if (skpair != NULL) { if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { unix_state_lock(skpair); @@ -554,7 +556,6 @@ static void unix_release_sock(struct sock *sk, int embrion) unix_dgram_peer_wake_disconnect(sk, skpair); sock_put(skpair); /* It may now die */ - unix_peer(sk) = NULL; } /* Try to flush out this socket. Throw out buffers at least */ -- GitLab From f19406b09f4f0ae9c1e60f5ad29aa6f76c559e14 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 8 Feb 2019 09:01:44 -0700 Subject: [PATCH 17/96] net: split out functions related to registering inflight socket files commit f4e65870e5cede5ca1ec0006b6c9803994e5f7b8 upstream. We need this functionality for the io_uring file registration, but we cannot rely on it since CONFIG_UNIX can be modular. Move the helpers to a separate file, that's always builtin to the kernel if CONFIG_UNIX is m/y. No functional changes in this patch, just moving code around. Reviewed-by: Hannes Reinecke Acked-by: David S. Miller Signed-off-by: Jens Axboe [ backported to older kernels to get access to unix_gc_lock - gregkh ] Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 1f02ba8b5b42fe25cab3d8e6f400e10c4c688700) Change-Id: I40583ea11ea321bde97ee49545a10936ade3260d (cherry picked from commit e32d008da8e2cc1941ec0252a9662b1257cf20d6) --- include/net/af_unix.h | 1 + net/Makefile | 2 +- net/unix/Kconfig | 5 ++ net/unix/Makefile | 2 + net/unix/af_unix.c | 76 +------------------- net/unix/garbage.c | 68 +----------------- net/unix/scm.c | 161 ++++++++++++++++++++++++++++++++++++++++++ net/unix/scm.h | 10 +++ 8 files changed, 184 insertions(+), 141 deletions(-) create mode 100644 net/unix/scm.c create mode 100644 net/unix/scm.h diff --git a/include/net/af_unix.h b/include/net/af_unix.h index fd60eccb59a6..79f2e1ccfcfb 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -8,6 +8,7 @@ void unix_inflight(struct user_struct *user, struct file *fp); void unix_notinflight(struct user_struct *user, struct file *fp); +void unix_destruct_scm(struct sk_buff *skb); void unix_gc(void); void wait_for_unix_gc(void); struct sock *unix_get_socket(struct file *filp); diff --git a/net/Makefile b/net/Makefile index c84a3470ad8d..83e91dcafec0 100644 --- a/net/Makefile +++ b/net/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_NET) += ethernet/ 802/ sched/ netlink/ obj-$(CONFIG_NETFILTER) += netfilter/ obj-$(CONFIG_INET) += ipv4/ obj-$(CONFIG_XFRM) += xfrm/ -obj-$(CONFIG_UNIX) += unix/ +obj-$(CONFIG_UNIX_SCM) += unix/ obj-$(CONFIG_NET) += ipv6/ obj-$(CONFIG_PACKET) += packet/ obj-$(CONFIG_NET_KEY) += key/ diff --git a/net/unix/Kconfig b/net/unix/Kconfig index 8b31ab85d050..3b9e450656a4 100644 --- a/net/unix/Kconfig +++ b/net/unix/Kconfig @@ -19,6 +19,11 @@ config UNIX Say Y unless you know what you are doing. +config UNIX_SCM + bool + depends on UNIX + default y + config UNIX_DIAG tristate "UNIX: socket monitoring interface" depends on UNIX diff --git a/net/unix/Makefile b/net/unix/Makefile index b663c607b1c6..dc686c6757fb 100644 --- a/net/unix/Makefile +++ b/net/unix/Makefile @@ -9,3 +9,5 @@ unix-$(CONFIG_SYSCTL) += sysctl_net_unix.o obj-$(CONFIG_UNIX_DIAG) += unix_diag.o unix_diag-y := diag.o + +obj-$(CONFIG_UNIX_SCM) += scm.o diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 43a17fb9f290..f280a70c41d7 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -118,6 +118,8 @@ #include #include +#include "scm.h" + struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE]; EXPORT_SYMBOL_GPL(unix_socket_table); DEFINE_SPINLOCK(unix_table_lock); @@ -1505,80 +1507,6 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ return err; } -static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) -{ - int i; - - scm->fp = UNIXCB(skb).fp; - UNIXCB(skb).fp = NULL; - - for (i = scm->fp->count-1; i >= 0; i--) - unix_notinflight(scm->fp->user, scm->fp->fp[i]); -} - -static void unix_destruct_scm(struct sk_buff *skb) -{ - struct scm_cookie scm; - memset(&scm, 0, sizeof(scm)); - scm.pid = UNIXCB(skb).pid; - if (UNIXCB(skb).fp) - unix_detach_fds(&scm, skb); - - /* Alas, it calls VFS */ - /* So fscking what? fput() had been SMP-safe since the last Summer */ - scm_destroy(&scm); - sock_wfree(skb); -} - -/* - * The "user->unix_inflight" variable is protected by the garbage - * collection lock, and we just read it locklessly here. If you go - * over the limit, there might be a tiny race in actually noticing - * it across threads. Tough. - */ -static inline bool too_many_unix_fds(struct task_struct *p) -{ - struct user_struct *user = current_user(); - - if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE))) - return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); - return false; -} - -#define MAX_RECURSION_LEVEL 4 - -static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) -{ - int i; - unsigned char max_level = 0; - - if (too_many_unix_fds(current)) - return -ETOOMANYREFS; - - for (i = scm->fp->count - 1; i >= 0; i--) { - struct sock *sk = unix_get_socket(scm->fp->fp[i]); - - if (sk) - max_level = max(max_level, - unix_sk(sk)->recursion_level); - } - if (unlikely(max_level > MAX_RECURSION_LEVEL)) - return -ETOOMANYREFS; - - /* - * Need to duplicate file references for the sake of garbage - * collection. Otherwise a socket in the fps might become a - * candidate for GC while the skb is not yet queued. - */ - UNIXCB(skb).fp = scm_fp_dup(scm->fp); - if (!UNIXCB(skb).fp) - return -ENOMEM; - - for (i = scm->fp->count - 1; i >= 0; i--) - unix_inflight(scm->fp->user, scm->fp->fp[i]); - return max_level; -} - static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) { int err = 0; diff --git a/net/unix/garbage.c b/net/unix/garbage.c index c36757e72844..8bbe1b8e4ff7 100644 --- a/net/unix/garbage.c +++ b/net/unix/garbage.c @@ -86,77 +86,13 @@ #include #include +#include "scm.h" + /* Internal data structures and random procedures: */ -static LIST_HEAD(gc_inflight_list); static LIST_HEAD(gc_candidates); -static DEFINE_SPINLOCK(unix_gc_lock); static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait); -unsigned int unix_tot_inflight; - -struct sock *unix_get_socket(struct file *filp) -{ - struct sock *u_sock = NULL; - struct inode *inode = file_inode(filp); - - /* Socket ? */ - if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) { - struct socket *sock = SOCKET_I(inode); - struct sock *s = sock->sk; - - /* PF_UNIX ? */ - if (s && sock->ops && sock->ops->family == PF_UNIX) - u_sock = s; - } - return u_sock; -} - -/* Keep the number of times in flight count for the file - * descriptor if it is for an AF_UNIX socket. - */ - -void unix_inflight(struct user_struct *user, struct file *fp) -{ - struct sock *s = unix_get_socket(fp); - - spin_lock(&unix_gc_lock); - - if (s) { - struct unix_sock *u = unix_sk(s); - - if (atomic_long_inc_return(&u->inflight) == 1) { - BUG_ON(!list_empty(&u->link)); - list_add_tail(&u->link, &gc_inflight_list); - } else { - BUG_ON(list_empty(&u->link)); - } - unix_tot_inflight++; - } - user->unix_inflight++; - spin_unlock(&unix_gc_lock); -} - -void unix_notinflight(struct user_struct *user, struct file *fp) -{ - struct sock *s = unix_get_socket(fp); - - spin_lock(&unix_gc_lock); - - if (s) { - struct unix_sock *u = unix_sk(s); - - BUG_ON(!atomic_long_read(&u->inflight)); - BUG_ON(list_empty(&u->link)); - - if (atomic_long_dec_and_test(&u->inflight)) - list_del_init(&u->link); - unix_tot_inflight--; - } - user->unix_inflight--; - spin_unlock(&unix_gc_lock); -} - static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), struct sk_buff_head *hitlist) { diff --git a/net/unix/scm.c b/net/unix/scm.c new file mode 100644 index 000000000000..df8f636ab1d8 --- /dev/null +++ b/net/unix/scm.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scm.h" + +unsigned int unix_tot_inflight; +EXPORT_SYMBOL(unix_tot_inflight); + +LIST_HEAD(gc_inflight_list); +EXPORT_SYMBOL(gc_inflight_list); + +DEFINE_SPINLOCK(unix_gc_lock); +EXPORT_SYMBOL(unix_gc_lock); + +struct sock *unix_get_socket(struct file *filp) +{ + struct sock *u_sock = NULL; + struct inode *inode = file_inode(filp); + + /* Socket ? */ + if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) { + struct socket *sock = SOCKET_I(inode); + struct sock *s = sock->sk; + + /* PF_UNIX ? */ + if (s && sock->ops && sock->ops->family == PF_UNIX) + u_sock = s; + } + return u_sock; +} +EXPORT_SYMBOL(unix_get_socket); + +/* Keep the number of times in flight count for the file + * descriptor if it is for an AF_UNIX socket. + */ +void unix_inflight(struct user_struct *user, struct file *fp) +{ + struct sock *s = unix_get_socket(fp); + + spin_lock(&unix_gc_lock); + + if (s) { + struct unix_sock *u = unix_sk(s); + + if (atomic_long_inc_return(&u->inflight) == 1) { + BUG_ON(!list_empty(&u->link)); + list_add_tail(&u->link, &gc_inflight_list); + } else { + BUG_ON(list_empty(&u->link)); + } + unix_tot_inflight++; + } + user->unix_inflight++; + spin_unlock(&unix_gc_lock); +} + +void unix_notinflight(struct user_struct *user, struct file *fp) +{ + struct sock *s = unix_get_socket(fp); + + spin_lock(&unix_gc_lock); + + if (s) { + struct unix_sock *u = unix_sk(s); + + BUG_ON(!atomic_long_read(&u->inflight)); + BUG_ON(list_empty(&u->link)); + + if (atomic_long_dec_and_test(&u->inflight)) + list_del_init(&u->link); + unix_tot_inflight--; + } + user->unix_inflight--; + spin_unlock(&unix_gc_lock); +} + +/* + * The "user->unix_inflight" variable is protected by the garbage + * collection lock, and we just read it locklessly here. If you go + * over the limit, there might be a tiny race in actually noticing + * it across threads. Tough. + */ +static inline bool too_many_unix_fds(struct task_struct *p) +{ + struct user_struct *user = current_user(); + + if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE))) + return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); + return false; +} + +#define MAX_RECURSION_LEVEL 4 + +int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) +{ + int i; + unsigned char max_level = 0; + + if (too_many_unix_fds(current)) + return -ETOOMANYREFS; + + for (i = scm->fp->count - 1; i >= 0; i--) { + struct sock *sk = unix_get_socket(scm->fp->fp[i]); + + if (sk) + max_level = max(max_level, + unix_sk(sk)->recursion_level); + } + if (unlikely(max_level > MAX_RECURSION_LEVEL)) + return -ETOOMANYREFS; + + /* + * Need to duplicate file references for the sake of garbage + * collection. Otherwise a socket in the fps might become a + * candidate for GC while the skb is not yet queued. + */ + UNIXCB(skb).fp = scm_fp_dup(scm->fp); + if (!UNIXCB(skb).fp) + return -ENOMEM; + + for (i = scm->fp->count - 1; i >= 0; i--) + unix_inflight(scm->fp->user, scm->fp->fp[i]); + return max_level; +} +EXPORT_SYMBOL(unix_attach_fds); + +void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb) +{ + int i; + + scm->fp = UNIXCB(skb).fp; + UNIXCB(skb).fp = NULL; + + for (i = scm->fp->count-1; i >= 0; i--) + unix_notinflight(scm->fp->user, scm->fp->fp[i]); +} +EXPORT_SYMBOL(unix_detach_fds); + +void unix_destruct_scm(struct sk_buff *skb) +{ + struct scm_cookie scm; + + memset(&scm, 0, sizeof(scm)); + scm.pid = UNIXCB(skb).pid; + if (UNIXCB(skb).fp) + unix_detach_fds(&scm, skb); + + /* Alas, it calls VFS */ + /* So fscking what? fput() had been SMP-safe since the last Summer */ + scm_destroy(&scm); + sock_wfree(skb); +} +EXPORT_SYMBOL(unix_destruct_scm); diff --git a/net/unix/scm.h b/net/unix/scm.h new file mode 100644 index 000000000000..5a255a477f16 --- /dev/null +++ b/net/unix/scm.h @@ -0,0 +1,10 @@ +#ifndef NET_UNIX_SCM_H +#define NET_UNIX_SCM_H + +extern struct list_head gc_inflight_list; +extern spinlock_t unix_gc_lock; + +int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb); +void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb); + +#endif -- GitLab From e1c03270f9b11513cf905b3c9a196ec30f552434 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 28 Jul 2021 14:47:20 +0200 Subject: [PATCH 18/96] af_unix: fix garbage collect vs MSG_PEEK commit cbcf01128d0a92e131bd09f1688fe032480b65ca upstream. unix_gc() assumes that candidate sockets can never gain an external reference (i.e. be installed into an fd) while the unix_gc_lock is held. Except for MSG_PEEK this is guaranteed by modifying inflight count under the unix_gc_lock. MSG_PEEK does not touch any variable protected by unix_gc_lock (file count is not), yet it needs to be serialized with garbage collection. Do this by locking/unlocking unix_gc_lock: 1) increment file count 2) lock/unlock barrier to make sure incremented file count is visible to garbage collection 3) install file into fd This is a lock barrier (unlike smp_mb()) that ensures that garbage collection is run completely before or completely after the barrier. Cc: Signed-off-by: Miklos Szeredi Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Issue: FP3SEC-122 (cherry picked from commit a805a7bd94644207d762d9c287078fecfcf52b3e) Change-Id: I905b16f8d08324541f3281427d3f633bc5373769 (cherry picked from commit 97106c23a056b030778b59b5231fcf56e3634f42) --- net/unix/af_unix.c | 51 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f280a70c41d7..fa4f39e8ee0c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1507,6 +1507,53 @@ static int unix_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_ return err; } +static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb) +{ + scm->fp = scm_fp_dup(UNIXCB(skb).fp); + + /* + * Garbage collection of unix sockets starts by selecting a set of + * candidate sockets which have reference only from being in flight + * (total_refs == inflight_refs). This condition is checked once during + * the candidate collection phase, and candidates are marked as such, so + * that non-candidates can later be ignored. While inflight_refs is + * protected by unix_gc_lock, total_refs (file count) is not, hence this + * is an instantaneous decision. + * + * Once a candidate, however, the socket must not be reinstalled into a + * file descriptor while the garbage collection is in progress. + * + * If the above conditions are met, then the directed graph of + * candidates (*) does not change while unix_gc_lock is held. + * + * Any operations that changes the file count through file descriptors + * (dup, close, sendmsg) does not change the graph since candidates are + * not installed in fds. + * + * Dequeing a candidate via recvmsg would install it into an fd, but + * that takes unix_gc_lock to decrement the inflight count, so it's + * serialized with garbage collection. + * + * MSG_PEEK is special in that it does not change the inflight count, + * yet does install the socket into an fd. The following lock/unlock + * pair is to ensure serialization with garbage collection. It must be + * done between incrementing the file count and installing the file into + * an fd. + * + * If garbage collection starts after the barrier provided by the + * lock/unlock, then it will see the elevated refcount and not mark this + * as a candidate. If a garbage collection is already in progress + * before the file count was incremented, then the lock/unlock pair will + * ensure that garbage collection is finished before progressing to + * installing the fd. + * + * (*) A -> B where B is on the queue of A or B is on the queue of C + * which is on the queue of listening socket A. + */ + spin_lock(&unix_gc_lock); + spin_unlock(&unix_gc_lock); +} + static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds) { int err = 0; @@ -2140,7 +2187,7 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, sk_peek_offset_fwd(sk, size); if (UNIXCB(skb).fp) - scm.fp = scm_fp_dup(UNIXCB(skb).fp); + unix_peek_fds(&scm, skb); } err = (flags & MSG_TRUNC) ? skb->len - skip : size; @@ -2385,7 +2432,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state, /* It is questionable, see note in unix_dgram_recvmsg. */ if (UNIXCB(skb).fp) - scm.fp = scm_fp_dup(UNIXCB(skb).fp); + unix_peek_fds(&scm, skb); sk_peek_offset_fwd(sk, chunk); -- GitLab From 72e1a0a7a2aa07a506ea8530f5709651ca3be87c Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 5 Feb 2021 09:28:30 +0530 Subject: [PATCH 19/96] Adjust AndroidKernel.mk to match newer versions Few MAKE commands are modified in accordance with the use of BoardConfigKernel.mk file in device projects. Issue: FP3-A11#4 Issue: FP3-A11#202 Change-Id: Ib562f3f542bdf98a39de70d110500c207af1691d --- AndroidKernel.mk | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index d48eecd6cb04..3d0669f4a746 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -42,13 +42,6 @@ KERNEL_CONFIG_OVERRIDE := CONFIG_ANDROID_BINDER_IPC_32BIT=y endif endif -TARGET_KERNEL_CROSS_COMPILE_PREFIX := $(strip $(TARGET_KERNEL_CROSS_COMPILE_PREFIX)) -ifeq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),) -KERNEL_CROSS_COMPILE := arm-eabi- -else -KERNEL_CROSS_COMPILE := $(TARGET_KERNEL_CROSS_COMPILE_PREFIX) -endif - ifeq ($(KERNEL_LLVM_SUPPORT), true) ifeq ($(KERNEL_SD_LLVM_SUPPORT), true) #Using sd-llvm compiler ifeq ($(shell echo $(SDCLANG_PATH) | head -c 1),/) @@ -177,6 +170,14 @@ $(TARGET_PREBUILT_INT_KERNEL_VM): $(KERNEL_VM_USR) endif endif +TARGET_KERNEL_CLANG_PATH ?= $(BUILD_TOP)/prebuilts/clang/host/$(HOST_OS)-x86/$(KERNEL_CLANG_VERSION) +PATH_OVERRIDE := PATH=$(TARGET_KERNEL_CLANG_PATH)/bin:$$PATH LD_LIBRARY_PATH=$(TARGET_KERNEL_CLANG_PATH)/lib64:$$LD_LIBRARY_PATH + +PATH_OVERRIDE += PATH=$(KERNEL_TOOLCHAIN_PATH_gcc)/bin:$$PATH + +# System tools are no longer allowed on 10+ +PATH_OVERRIDE += $(TOOLS_PATH_OVERRIDE) + ifneq ($(KERNEL_VM_DEFCONFIG),) $(KERNEL_VM_OUT): mkdir -p $(KERNEL_VM_OUT); @@ -208,7 +209,7 @@ $(KERNEL_OUT): mkdir -p $(KERNEL_OUT) $(KERNEL_CONFIG): $(KERNEL_OUT) - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_DEFCONFIG) + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_DEFCONFIG) $(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \ echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \ echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ @@ -219,16 +220,16 @@ TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) $(hide) echo "Building kernel modules..." - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) Image - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) Image + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules_install $(mv-modules) $(clean-module-folder) $(TARGET_PREBUILT_INT_KERNEL): $(TARGET_PREBUILT_INT_KERNEL_IMAGE) $(hide) echo "Building kernel..." $(hide) rm -rf $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_CFLAGS) else TARGET_PREBUILT_INT_KERNEL_IMAGE := $(TARGET_PREBUILT_INT_KERNEL) $(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) @@ -243,8 +244,8 @@ endif $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) $(hide) if [ ! -z "$(KERNEL_HEADER_DEFCONFIG)" ]; then \ rm -f $(BUILD_ROOT_LOC)$(KERNEL_CONFIG); \ - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_HEADER_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_HEADER_DEFCONFIG); \ - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_HEADER_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) headers_install;\ + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD)$(KERNEL_HEADER_DEFCONFIG); \ + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) headers_install;\ if [ -d "$(KERNEL_HEADERS_INSTALL)/include/bringup_headers" ]; then \ cp -Rf $(KERNEL_HEADERS_INSTALL)/include/bringup_headers/* $(KERNEL_HEADERS_INSTALL)/include/ ;\ fi ;\ @@ -252,22 +253,22 @@ $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) $(hide) if [ "$(KERNEL_HEADER_DEFCONFIG)" != "$(KERNEL_DEFCONFIG)" ]; then \ echo "Used a different defconfig for header generation"; \ rm -f $(BUILD_ROOT_LOC)$(KERNEL_CONFIG); \ - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_DEFCONFIG); fi + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_DEFCONFIG); fi $(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \ echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \ echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) oldconfig; fi .PHONY: kerneltags kerneltags: $(KERNEL_OUT) $(KERNEL_CONFIG) - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) tags + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) tags .PHONY: kernelconfig kernelconfig: $(KERNEL_OUT) $(KERNEL_CONFIG) env KCONFIG_NOTIMESTAMP=true \ - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) menuconfig + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) menuconfig env KCONFIG_NOTIMESTAMP=true \ - $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) savedefconfig + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) savedefconfig cp $(KERNEL_OUT)/defconfig $(TARGET_KERNEL_SOURCE)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_DEFCONFIG) endif -- GitLab From 4eb6c23bda7a22179a5c8c5d26370891a2e5d601 Mon Sep 17 00:00:00 2001 From: Bharath Date: Wed, 10 Mar 2021 15:42:32 +0530 Subject: [PATCH 20/96] Adjust partition slots for FP3 FP3 does not have recovery partition and hence remove it. Issue: FP3-A11#21 Issue: FP3-A11#202 Change-Id: I96f388da19470fe477899bfe1a72eb2767ec21c1 --- arch/arm64/boot/dts/qcom/msm8953.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index 1d78b6b36aa7..8488d3a45453 100644 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -42,7 +42,7 @@ compatible = "android,firmware"; vbmeta { compatible = "android,vbmeta"; - parts = "vbmeta,boot,system,vendor,dtbo,recovery"; + parts = "vbmeta,boot,system,vendor,dtbo"; }; fstab { @@ -52,7 +52,7 @@ dev = "/dev/block/platform/soc/7824900.sdhci/by-name/vendor"; type = "ext4"; mnt_flags = "ro,barrier=1,discard"; - fsmgr_flags = "wait,avb"; + fsmgr_flags = "wait,slotselect,avb"; status = "ok"; }; -- GitLab From 516635ccff61c6c387ee5741a403a541dd8711dc Mon Sep 17 00:00:00 2001 From: jialongjhan Date: Tue, 21 Apr 2020 20:24:23 +0800 Subject: [PATCH 21/96] Add display drivers for FP3 Includes all display related driver changes. Issue: FP3-A11#21 Issue: FP3-A11#202 Change-Id: Idd7fdf53a98f1917649f48da10de99f3d09145a7 (cherry picked from commit 711c0e2252b71a0eacc9fc6bdc89f2894c9211ea) --- .../dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi | 154 ++++++++++++++++++ .../qcom/dsi-hx83112b-truly-1080p-video.dtsi | 152 +++++++++++++++++ .../boot/dts/qcom/msm8953-mdss-panels.dtsi | 28 ++++ arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 22 ++- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 16 +- arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi | 8 +- .../boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi | 4 - arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi | 20 --- drivers/regulator/qpnp-lcdb-regulator.c | 4 + drivers/video/fbdev/msm/mdss_dsi.c | 79 +++++++++ drivers/video/fbdev/msm/mdss_dsi_panel.c | 56 ++++++- drivers/video/fbdev/msm/mdss_io_util.c | 11 ++ 12 files changed, 510 insertions(+), 44 deletions(-) create mode 100755 arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi create mode 100755 arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi mode change 100644 => 100755 drivers/regulator/qpnp-lcdb-regulator.c mode change 100644 => 100755 drivers/video/fbdev/msm/mdss_dsi.c mode change 100644 => 100755 drivers/video/fbdev/msm/mdss_dsi_panel.c mode change 100644 => 100755 drivers/video/fbdev/msm/mdss_io_util.c diff --git a/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi b/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi new file mode 100755 index 000000000000..54e4d6c547ac --- /dev/null +++ b/arch/arm64/boot/dts/qcom/dsi-hx83112b-djn-1080p-cmd.dtsi @@ -0,0 +1,154 @@ +/* Copyright (c) 2017, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&mdss_mdp { + dsi_djn_hx83112b_1080p_cmd: qcom,mdss_dsi_djn_hx83112b_1080p_cmd { + qcom,mdss-dsi-panel-name = + "djn hx83112b 1080p cmd mode dsi panel"; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2160>; + qcom,mdss-dsi-h-front-porch = <40>; + qcom,mdss-dsi-h-back-porch = <12>; + qcom,mdss-dsi-h-pulse-width = <4>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <2>; + qcom,mdss-dsi-v-front-porch = <32>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-tear-check-sync-init-val = <2160>; + qcom,mdss-tear-check-sync-threshold-start = <4>; + qcom,mdss-tear-check-sync-threshold-continue = <4>; + qcom,mdss-tear-check-start-pos = <2160>; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + qcom,mdss-dsi-hsa-power-mode; + qcom,mdss-pan-physical-width-dimension=<65>; + qcom,mdss-pan-physical-height-dimension=<128>; + qcom,mdss-dsi-panel-timings = [e6 38 26 00 68 6e 2a + 3c 44 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x0d>; + qcom,mdss-dsi-t-clk-pre = <0x2f>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 B9 83 11 2B + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 03 C2 08 70 + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 05 B2 04 38 08 70 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 0B B1 F8 27 27 00 00 0B 0E 0B 0E 33 + 39 01 00 00 00 00 03 D2 2D 2D + 39 01 00 00 00 00 0C B2 80 02 18 80 70 00 08 1C 08 11 05 + 39 01 00 00 00 00 02 E9 D1 + 39 01 00 00 00 00 03 B2 00 08 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 03 B2 B5 0A + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 09 DD 00 00 08 1C 08 34 34 88 + 39 01 00 00 00 00 19 B4 65 6B 00 00 D0 D4 36 CF 06 CE 00 CE 00 00 00 07 00 2A 07 01 07 00 00 2A + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 02 E9 C3 + 39 01 00 00 00 00 04 B4 01 67 2A + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 C1 01 + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00 + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00 + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 C2 C8 + 39 01 00 00 00 00 02 CC 08 + 39 01 00 00 00 00 26 D3 81 00 00 00 00 01 00 04 00 01 13 40 04 09 09 0B 0B 32 10 08 00 08 32 10 08 00 08 32 10 08 00 08 00 00 0A 08 7B + 39 01 00 00 00 00 02 E9 C5 + 39 01 00 00 00 00 02 C6 F7 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 E9 D4 + 39 01 00 00 00 00 02 C6 6E + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 E9 EF + 39 01 00 00 00 00 02 D3 0C + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 02 E9 C8 + 39 01 00 00 00 00 02 D3 A1 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 39 D5 18 18 19 18 18 20 18 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18 FC FC 00 00 FC FC 00 00 + 39 01 00 00 00 00 31 D6 18 18 19 18 18 20 19 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18 + 39 01 00 00 00 00 19 D8 AA AA AA AF EA AA AA AA AA AF EA AA AA AA AB AF EF AA AA AA AA AF EA AA + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 0D D8 AA AA AB AF EA AA AA AA AE AF EA AA + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 0D D8 AA AA AA AF EA AA AA AA AA AF EA AA + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 19 D8 BA AA AA AF EA AA AA AA AA AF EA AA BA AA AA AF EA AA AA AA AA AF EA AA + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 E9 E4 + 39 01 00 00 00 00 03 E7 17 69 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 1A E7 09 09 00 07 E8 00 26 00 07 00 00 E8 32 00 E9 0A 0A 00 00 00 01 01 00 12 04 + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 0A E7 02 00 01 20 01 18 08 A8 09 + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 04 E7 20 20 00 + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 07 E7 00 DC 11 70 00 20 + 39 01 00 00 00 00 02 E9 C9 + 39 01 00 00 00 00 07 E7 2A CE 02 70 01 04 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 D1 27 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 14 00 02 29 00 + 39 01 00 00 00 00 03 51 00 00 + 39 01 00 00 00 00 02 53 24]; + qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-dstb-command = [ + 39 01 00 00 00 00 04 B9 83 11 2A + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 50 00 02 B1 09]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-post-init-delay = <1>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi b/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi new file mode 100755 index 000000000000..bbb4716bb505 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/dsi-hx83112b-truly-1080p-video.dtsi @@ -0,0 +1,152 @@ +/* Copyright (c) 2017, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ + +&mdss_mdp { + dsi_hx83112b_truly_1080p_video: qcom,mdss_dsi_hx83112b_truly_1080p_video { + qcom,mdss-dsi-panel-name = + "hx83112b truly 1080p video mode dsi panel"; + qcom,mdss-dsi-panel-type = "dsi_cmd_mode"; + qcom,mdss-dsi-panel-framerate = <60>; + qcom,mdss-dsi-virtual-channel-id = <0>; + qcom,mdss-dsi-stream = <0>; + qcom,mdss-dsi-panel-width = <1080>; + qcom,mdss-dsi-panel-height = <2160>; + qcom,mdss-dsi-h-front-porch = <40>; + qcom,mdss-dsi-h-back-porch = <12>; + qcom,mdss-dsi-h-pulse-width = <4>; + qcom,mdss-dsi-h-sync-skew = <0>; + qcom,mdss-dsi-v-back-porch = <2>; + qcom,mdss-dsi-v-front-porch = <32>; + qcom,mdss-dsi-v-pulse-width = <2>; + qcom,mdss-dsi-h-left-border = <0>; + qcom,mdss-dsi-h-right-border = <0>; + qcom,mdss-dsi-v-top-border = <0>; + qcom,mdss-dsi-v-bottom-border = <0>; + qcom,mdss-dsi-bpp = <24>; + qcom,mdss-dsi-underflow-color = <0xff>; + qcom,mdss-dsi-border-color = <0>; + qcom,mdss-dsi-te-pin-select = <1>; + qcom,mdss-dsi-te-dcs-command = <1>; + qcom,mdss-dsi-te-check-enable; + qcom,mdss-dsi-te-using-te-pin; + qcom,mdss-dsi-h-sync-pulse = <0>; + qcom,mdss-dsi-traffic-mode = "burst_mode"; + qcom,mdss-dsi-bllp-eof-power-mode; + qcom,mdss-dsi-bllp-power-mode; + qcom,mdss-dsi-lane-0-state; + qcom,mdss-dsi-lane-1-state; + qcom,mdss-dsi-lane-2-state; + qcom,mdss-dsi-lane-3-state; + //qcom,mdss-dsi-hfp-power-mode; + //qcom,mdss-dsi-hbp-power-mode; + qcom,mdss-dsi-hsa-power-mode; + qcom,mdss-pan-physical-width-dimension=<65>; + qcom,mdss-pan-physical-height-dimension=<128>; + qcom,mdss-dsi-panel-timings = [e6 38 26 00 68 6e 2a + 3c 44 03 04 00]; + qcom,mdss-dsi-t-clk-post = <0x0d>; + qcom,mdss-dsi-t-clk-pre = <0x2f>; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,mdss-dsi-dma-trigger = "trigger_sw"; + qcom,mdss-dsi-mdp-trigger = "none"; + qcom,mdss-dsi-on-command = [39 01 00 00 00 00 04 B9 83 11 2B + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 03 C2 08 70 + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 05 B2 04 38 08 70 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 0B B1 F8 27 27 00 00 0B 0E 0B 0E 33 + 39 01 00 00 00 00 03 D2 2D 2D + 39 01 00 00 00 00 0C B2 80 02 18 80 70 00 08 1C 08 11 05 + 39 01 00 00 00 00 02 E9 D1 + 39 01 00 00 00 00 03 B2 00 08 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 03 B2 B5 0A + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 09 DD 00 00 08 1C 08 34 34 88 + 39 01 00 00 00 00 19 B4 65 6B 00 00 D0 D4 36 CF 06 CE 00 CE 00 00 00 07 00 2A 07 01 07 00 00 2A + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 02 E9 C3 + 39 01 00 00 00 00 04 B4 01 67 2A + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 C1 01 + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00 + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00 + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 3A C1 FF FB F9 F6 F4 F1 EF EA E7 E5 E2 DF DD DA D8 D5 D2 CF CC C5 BE B7 B0 A8 A0 98 8E 85 7B 72 69 5E 53 48 3E 35 2B 22 17 0D 09 07 05 01 00 26 F0 86 25 6E B6 DD F3 D8 CC 9B 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 C2 C8 + 39 01 00 00 00 00 02 CC 08 + 39 01 00 00 00 00 26 D3 81 00 00 00 00 01 00 04 00 01 13 40 04 09 09 0B 0B 32 10 08 00 08 32 10 08 00 08 32 10 08 00 08 00 00 0A 08 7B + 39 01 00 00 00 00 02 E9 C5 + 39 01 00 00 00 00 02 C6 F7 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 E9 D4 + 39 01 00 00 00 00 02 C6 6E + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 E9 EF + 39 01 00 00 00 00 02 D3 0C + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 02 E9 C8 + 39 01 00 00 00 00 02 D3 A1 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 39 D5 18 18 19 18 18 20 18 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18 FC FC 00 00 FC FC 00 00 + 39 01 00 00 00 00 31 D6 18 18 19 18 18 20 19 18 18 10 10 18 18 00 00 18 18 01 01 18 18 28 28 18 18 18 18 18 2F 2F 30 30 31 31 35 35 36 36 37 37 18 18 18 18 18 18 18 18 + 39 01 00 00 00 00 19 D8 AA AA AA AF EA AA AA AA AA AF EA AA AA AA AB AF EF AA AA AA AA AF EA AA + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 0D D8 AA AA AB AF EA AA AA AA AE AF EA AA + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 0D D8 AA AA AA AF EA AA AA AA AA AF EA AA + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 19 D8 BA AA AA AF EA AA AA AA AA AF EA AA BA AA AA AF EA AA AA AA AA AF EA AA + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 E9 E4 + 39 01 00 00 00 00 03 E7 17 69 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 1A E7 09 09 00 07 E8 00 26 00 07 00 00 E8 32 00 E9 0A 0A 00 00 00 01 01 00 12 04 + 39 01 00 00 00 00 02 BD 01 + 39 01 00 00 00 00 0A E7 02 00 01 20 01 18 08 A8 09 + 39 01 00 00 00 00 02 BD 02 + 39 01 00 00 00 00 04 E7 20 20 00 + 39 01 00 00 00 00 02 BD 03 + 39 01 00 00 00 00 07 E7 00 DC 11 70 00 20 + 39 01 00 00 00 00 02 E9 C9 + 39 01 00 00 00 00 07 E7 2A CE 02 70 01 04 + 39 01 00 00 00 00 02 E9 00 + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 00 00 02 D1 27 + 05 01 00 00 78 00 02 11 00 + 05 01 00 00 14 00 02 29 00 + 39 01 00 00 00 00 03 51 00 00 + 39 01 00 00 00 00 02 53 24]; + qcom,mdss-dsi-off-command = [05 01 00 00 14 00 02 28 00 + 05 01 00 00 78 00 02 10 00]; + qcom,mdss-dsi-off-dstb-command = [ + 39 01 00 00 00 00 04 B9 83 11 2A + 39 01 00 00 00 00 02 BD 00 + 39 01 00 00 50 00 02 B1 09]; + qcom,mdss-dsi-on-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-off-command-state = "dsi_lp_mode"; + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-reset-sequence = <1 10>, <0 10>, <1 10>; + qcom,mdss-dsi-tx-eot-append; + qcom,mdss-dsi-lp11-init; + qcom,mdss-dsi-post-init-delay = <1>; + }; +}; diff --git a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi old mode 100644 new mode 100755 index fa218ca617eb..a4f4851ba5ad --- a/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mdss-panels.dtsi @@ -28,6 +28,8 @@ #include "dsi-panel-boent51021-1200p-video.dtsi" #include "dsi-panel-hx8394d-wxga-video.dtsi" #include "dsi-panel-inxnt51021-1200p-video.dtsi" +#include "dsi-hx83112b-truly-1080p-video.dtsi" +#include "dsi-hx83112b-djn-1080p-cmd.dtsi" &soc { dsi_panel_pwr_supply: dsi_panel_pwr_supply { @@ -71,6 +73,32 @@ }; }; +&dsi_hx83112b_truly_1080p_video { + qcom,mdss-dsi-panel-timings-phy-v2 = [24 1e 08 09 05 03 04 a0 + 24 1e 08 09 05 03 04 a0 + 24 1e 08 09 05 03 04 a0 + 24 1e 08 09 05 03 04 a0 + 24 1a 08 09 05 03 04 a0]; + qcom,mdss-dsi-min-refresh-rate = <48>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; +}; + +&dsi_djn_hx83112b_1080p_cmd { + qcom,mdss-dsi-panel-timings-phy-v2 = [24 1e 08 09 05 03 04 a0 + 24 1e 08 09 05 03 04 a0 + 24 1e 08 09 05 03 04 a0 + 24 1e 08 09 05 03 04 a0 + 24 1a 08 09 05 03 04 a0]; + qcom,mdss-dsi-min-refresh-rate = <48>; + qcom,mdss-dsi-max-refresh-rate = <60>; + qcom,mdss-dsi-pan-enable-dynamic-fps; + qcom,mdss-dsi-pan-fps-update = "dfps_immediate_porch_mode_vfp"; + qcom,mdss-dsi-panel-status-command-state = "dsi_hs_mode"; +}; + &dsi_truly_1080_vid { qcom,mdss-dsi-panel-timings-phy-v2 = [23 1e 08 09 05 03 04 a0 23 1e 08 09 05 03 04 a0 diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi old mode 100644 new mode 100755 index 69cf52ebc606..4ff1f756aa7b --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -127,14 +127,18 @@ }; &mdss_dsi0 { + #if 1 + qcom,dsi-pref-prim-pan = <&dsi_djn_hx83112b_1080p_cmd>; + #else qcom,dsi-pref-prim-pan = <&dsi_truly_1080_vid>; + #endif pinctrl-names = "mdss_default", "mdss_sleep"; pinctrl-0 = <&mdss_dsi_active &mdss_te_active>; pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; qcom,platform-te-gpio = <&tlmm 24 0>; - qcom,platform-reset-gpio = <&tlmm 61 0>; - qcom,platform-bklight-en-gpio = <&tlmm 59 0>; + qcom,platform-reset-gpio = <&tlmm 61 0>; + qcom,platform-bklight-en-gpio = <&tlmm 96 0>; }; &mdss_dsi1 { @@ -150,6 +154,20 @@ qcom,platform-bklight-en-gpio = <&tlmm 59 0>; }; +&dsi_hx83112b_truly_1080p_video { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + +&dsi_djn_hx83112b_1080p_cmd { + qcom,mdss-dsi-bl-pmic-control-type = "bl_ctrl_dcs"; + qcom,mdss-dsi-bl-min-level = <1>; + qcom,mdss-dsi-bl-max-level = <4095>; + qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; +}; + &dsi_truly_1080_vid { qcom,panel-supply-entries = <&dsi_panel_pwr_supply>; qcom,mdss-dsi-pan-enable-dynamic-fps; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi old mode 100644 new mode 100755 index 9da42f99b317..469edb3ea5df --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -400,14 +400,15 @@ }; pmx_mdss: pmx_mdss { + mdss_dsi_active: mdss_dsi_active { mux { - pins = "gpio61", "gpio59"; + pins = "gpio61", "gpio96"; function = "gpio"; }; config { - pins = "gpio61", "gpio59"; + pins = "gpio61", "gpio96"; drive-strength = <8>; /* 8 mA */ bias-disable = <0>; /* no pull */ output-high; @@ -416,16 +417,17 @@ mdss_dsi_suspend: mdss_dsi_suspend { mux { - pins = "gpio61", "gpio59"; + pins = "gpio61", "gpio96"; function = "gpio"; }; config { - pins = "gpio61", "gpio59"; + pins = "gpio61", "gpio96"; drive-strength = <2>; /* 2 mA */ bias-pull-down; /* pull down */ }; }; + mdss_dsi_gpio: mdss_dsi_gpio { mux { pins = "gpio141"; @@ -1260,12 +1262,10 @@ wsa_reset { wsa_reset_on: wsa_reset_on { mux { - pins = "gpio96"; function = "gpio"; }; config { - pins = "gpio96"; drive-strength = <2>; /* 2 MA */ output-high; }; @@ -1273,14 +1273,12 @@ wsa_reset_off: wsa_reset_off { mux { - pins = "gpio96"; function = "gpio"; }; config { - pins = "gpio96"; drive-strength = <2>; /* 2 MA */ - output-low; + output-high; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi old mode 100644 new mode 100755 index 86f5323779e7..00521c454f0a --- a/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-wsa881x.dtsi @@ -20,27 +20,27 @@ #size-cells = <0>; wsa881x_211: wsa881x@20170211 { + status = "disabled"; compatible = "qcom,wsa881x"; reg = <0x00 0x20170211>; - qcom,spkr-sd-n-gpio = <&tlmm 96 0>; }; wsa881x_212: wsa881x@20170212 { + status = "disabled"; compatible = "qcom,wsa881x"; reg = <0x00 0x20170212>; - qcom,spkr-sd-n-gpio = <&tlmm 96 0>; }; wsa881x_213: wsa881x@21170213 { + status = "disabled"; compatible = "qcom,wsa881x"; reg = <0x00 0x21170213>; - qcom,spkr-sd-n-gpio = <&tlmm 96 0>; }; wsa881x_214: wsa881x@21170214 { + status = "disabled"; compatible = "qcom,wsa881x"; reg = <0x00 0x21170214>; - qcom,spkr-sd-n-gpio = <&tlmm 96 0>; }; }; }; diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi old mode 100644 new mode 100755 index 1afea684eaeb..c253ac47c9b6 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632-mtp-s3.dtsi @@ -24,10 +24,6 @@ &mdss_dsi0 { qcom,dsi-pref-prim-pan = <&dsi_hx8399c_truly_vid>; pinctrl-names = "mdss_default", "mdss_sleep"; - pinctrl-0 = <&mdss_dsi_active &mdss_te_active &bklt_en_default>; - pinctrl-1 = <&mdss_dsi_suspend &mdss_te_suspend>; - - qcom,platform-bklight-en-gpio = <&pm8953_gpios 4 0>; lab-supply = <&lcdb_ldo_vreg>; ibb-supply = <&lcdb_ncp_vreg>; diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi old mode 100644 new mode 100755 index 6e3932790614..e14fa9ab2234 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi @@ -373,23 +373,3 @@ }; }; -&tlmm { - pmx_mdss { - mdss_dsi_active: mdss_dsi_active { - mux { - pins = "gpio61"; - }; - config { - pins = "gpio61"; - }; - }; - mdss_dsi_suspend: mdss_dsi_suspend { - mux { - pins = "gpio61"; - }; - config { - pins = "gpio61"; - }; - }; - }; -}; diff --git a/drivers/regulator/qpnp-lcdb-regulator.c b/drivers/regulator/qpnp-lcdb-regulator.c old mode 100644 new mode 100755 index e3786e58104d..472ca6ad167d --- a/drivers/regulator/qpnp-lcdb-regulator.c +++ b/drivers/regulator/qpnp-lcdb-regulator.c @@ -12,6 +12,7 @@ */ #define pr_fmt(fmt) "LCDB: %s: " fmt, __func__ +#define LCDB_PWRUP_PWRDN_CTL_REG 0x66 #include #include @@ -2315,6 +2316,7 @@ static int qpnp_lcdb_regulator_probe(struct platform_device *pdev) int rc; struct device_node *node; struct qpnp_lcdb *lcdb; + u8 val = 0xF; // 0xF==1111==VSN delay 8ms; VSP delay 8ms node = pdev->dev.of_node; if (!node) { @@ -2367,6 +2369,8 @@ static int qpnp_lcdb_regulator_probe(struct platform_device *pdev) lcdb->lcdb_enabled, lcdb->ldo.voltage_mv, lcdb->ncp.voltage_mv, lcdb->bst.voltage_mv); + rc = qpnp_lcdb_write(lcdb, lcdb->base + LCDB_PWRUP_PWRDN_CTL_REG , &val, 1); + return rc; } diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c old mode 100644 new mode 100755 index 234a90360ad2..3fb7de989ba0 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -37,6 +37,8 @@ #include "mdss_dba_utils.h" #include "mdss_smmu.h" +#include + #define XO_CLK_RATE 19200000 #define CMDLINE_DSI_CTL_NUM_STRING_LEN 2 @@ -411,6 +413,8 @@ static int mdss_dsi_panel_power_on(struct mdss_panel_data *pdata) int ret = 0; struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; + gpio_direction_output(64, 1); + if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); return -EINVAL; @@ -3297,6 +3301,77 @@ static int mdss_dsi_get_bridge_chip_params(struct mdss_panel_info *pinfo, return rc; } +extern void seq_printf(struct seq_file *m, const char *f, ...); +extern int single_open(struct file *, int (*)(struct seq_file *, void *), void *); +extern ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); +extern loff_t seq_lseek(struct file *, loff_t, int); +extern int single_release(struct inode *, struct file *); + +static int proc_lcm_vendor_show(struct seq_file *m, void *v) +{ + int lcm_id; + + lcm_id = gpio_request(59, "lcm_id"); + + if(lcm_id == 1) + { + //For another's LCM module + seq_printf(m, "2nd LCM\n"); + } + else + { //DJN's LCM module id is 0. + seq_printf(m, "DJN , HX83112B\n"); + } + + return 0; +} + +static int proc_lcm_vendor_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lcm_vendor_show, NULL); +} + +static const struct file_operations proc_lcm_vendor_fops = { + .open = proc_lcm_vendor_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + +static int proc_lcm_revision_show(struct seq_file *m, void *v) +{ + int lcm_id; + extern int RDDID_HWINFO[3]; + + lcm_id = gpio_request(59, "lcm_id"); + + if(lcm_id == 1) + { + //For another's LCM module + seq_printf(m, "2nd Source not ready.\n"); + } + else + { //DJN's LCM module id is 0. + seq_printf(m, "DJN , HX%x%x%x\n", RDDID_HWINFO[0],RDDID_HWINFO[1],RDDID_HWINFO[2]); + } + + return 0; +} + +static int proc_lcm_revision_fops_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lcm_revision_show, NULL); +} + +static const struct file_operations proc_lcm_revision_fops = { + .open = proc_lcm_revision_fops_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + + static int mdss_dsi_ctrl_probe(struct platform_device *pdev) { int rc = 0; @@ -3488,6 +3563,10 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) mdss_dsi_debug_bus_init(mdss_dsi_res); + proc_create("lcm_vendor", 0, NULL, &proc_lcm_vendor_fops); + + proc_create("lcm_revision", 0666, NULL, &proc_lcm_revision_fops); + return 0; error_shadow_clk_deinit: diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c old mode 100644 new mode 100755 index 7d3009bd34e3..91a76bd889a0 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -212,17 +212,17 @@ static void mdss_dsi_panel_cmds_send(struct mdss_dsi_ctrl_pdata *ctrl, mdss_dsi_cmdlist_put(ctrl, &cmdreq); } - -static char led_pwm1[2] = {0x51, 0x0}; /* DTYPE_DCS_WRITE1 */ +static char led_pwm1[3] = {0x51, 0x00,0x00}; /* DTYPE_DCS_WRITE1 */ static struct dsi_cmd_desc backlight_cmd = { - {DTYPE_DCS_WRITE1, 1, 0, 0, 1, sizeof(led_pwm1)}, - led_pwm1 + {DTYPE_DCS_LWRITE, 1, 0, 0, 1, sizeof(led_pwm1)}, led_pwm1 }; static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level) { struct dcs_cmd_req cmdreq; struct mdss_panel_info *pinfo; + +int para_1,para_2; pinfo = &(ctrl->panel_data.panel_info); if (pinfo->dcs_cmd_by_left) { @@ -232,7 +232,13 @@ static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level) pr_debug("%s: level=%d\n", __func__, level); - led_pwm1[1] = (unsigned char)level; + //led_pwm1[1] = (unsigned char)level; + para_1 = (level>>8)&0x0F; + para_2 = level&0xFF; + + led_pwm1[1] = (unsigned char)para_1; + led_pwm1[2] = (unsigned char)para_2; + memset(&cmdreq, 0, sizeof(cmdreq)); cmdreq.cmds = &backlight_cmd; @@ -523,6 +529,17 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) gpio_free(ctrl_pdata->disp_en_gpio); } gpio_set_value((ctrl_pdata->rst_gpio), 0); + + //Move "pull low TP reset pin" from mdss_dsi.c, + //it have to same with LCM reset pin pull low + + /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off start*/ + //TP reset pin pull low with LCD reset pin at same time. + gpio_direction_output(64, 0); + /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off end*/ + + msleep(1); + gpio_free(ctrl_pdata->rst_gpio); if (gpio_is_valid(ctrl_pdata->mode_gpio)) gpio_free(ctrl_pdata->mode_gpio); @@ -824,11 +841,18 @@ static void mdss_dsi_panel_switch_mode(struct mdss_panel_data *pdata, mdss_dsi_panel_dsc_pps_send(ctrl_pdata, &pdata->panel_info); } +static char RDDID[4] = {0x04, 0x00, 0x00, 0x00}; +static struct dsi_cmd_desc cmd_RDDID = { + {DTYPE_DCS_READ, 1, 0, 1, 5, sizeof(RDDID)}, RDDID}; +int RDDID_HWINFO[3]; +int RDDID_read_count =0; + static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, u32 bl_level) { struct mdss_dsi_ctrl_pdata *ctrl_pdata = NULL; struct mdss_dsi_ctrl_pdata *sctrl = NULL; + struct dcs_cmd_req cmdreq2; if (pdata == NULL) { pr_err("%s: Invalid input data\n", __func__); @@ -838,6 +862,28 @@ static void mdss_dsi_panel_bl_ctrl(struct mdss_panel_data *pdata, ctrl_pdata = container_of(pdata, struct mdss_dsi_ctrl_pdata, panel_data); + if(RDDID_read_count==0){ + memset(&cmdreq2, 0, sizeof(cmdreq2)); + cmdreq2.cmds = &cmd_RDDID; + cmdreq2.cmds_cnt = 1; + cmdreq2.flags = CMD_REQ_COMMIT | CMD_REQ_RX;; + cmdreq2.rlen = 3;//return 3 values + cmdreq2.cb = NULL; /* call back */ + cmdreq2.rbuf = ctrl_pdata->rx_buf.data; + + mdss_dsi_cmdlist_put(ctrl_pdata, &cmdreq2); + + if(ctrl_pdata->rx_buf.len>0){ + RDDID_HWINFO[0]=(int)*(ctrl_pdata->rx_buf.data); + RDDID_HWINFO[1]=(int)*(ctrl_pdata->rx_buf.data+1); + RDDID_HWINFO[2]=(int)*(ctrl_pdata->rx_buf.data+2); + //pr_err("[Jialong] ctrl->rx_buf.data data =0x%x\n",*(ctrl_pdata->rx_buf.data)); + RDDID_read_count++; + } + } + + mdelay(1); + /* * Some backlight controllers specify a minimum duty cycle * for the backlight brightness. If the brightness is less diff --git a/drivers/video/fbdev/msm/mdss_io_util.c b/drivers/video/fbdev/msm/mdss_io_util.c old mode 100644 new mode 100755 index 2f70ad37e227..d3f3bf2760a6 --- a/drivers/video/fbdev/msm/mdss_io_util.c +++ b/drivers/video/fbdev/msm/mdss_io_util.c @@ -286,6 +286,12 @@ int msm_mdss_enable_vreg(struct mdss_vreg *in_vreg, int num_vreg, int enable) goto vreg_set_opt_mode_fail; } rc = regulator_enable(in_vreg[i].vreg); + + if(!strcmp(in_vreg[i].vreg_name,"vddio")){ + msleep(10); + } + + if (in_vreg[i].post_on_sleep && need_sleep) usleep_range((in_vreg[i].post_on_sleep * 1000), (in_vreg[i].post_on_sleep * 1000) + 10); @@ -304,6 +310,11 @@ int msm_mdss_enable_vreg(struct mdss_vreg *in_vreg, int num_vreg, int enable) regulator_set_load(in_vreg[i].vreg, in_vreg[i].load[DSS_REG_MODE_DISABLE]); + if(!strcmp(in_vreg[i].vreg_name,"vddio")){ + msleep(10); + } + + if (regulator_is_enabled(in_vreg[i].vreg)) regulator_disable(in_vreg[i].vreg); -- GitLab From 76fb69a07427ac5bb34f4ca776a10a2ff392a340 Mon Sep 17 00:00:00 2001 From: louisliu Date: Thu, 23 Apr 2020 16:01:11 +0800 Subject: [PATCH 22/96] Add Fingerprint drivers for FP3 Enable the fingerprint config and add all necessary driver components for fingerprint sensor. Issue: FP3-A11#202 Change-Id: Id231c4ee49de5cd25fbdc452bfc4e806f4429597 (cherry picked from commit a7d618acd620ff7c83062dc24ab250650fb9edf7) --- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 54 ++ arch/arm64/boot/dts/qcom/msm8953.dtsi | 11 + arch/arm64/configs/msm8953-perf_defconfig | 1 + arch/arm64/configs/msm8953_defconfig | 1 + drivers/input/Kconfig | 9 + drivers/input/Makefile | 2 + drivers/input/fingerprint/Makefile | 2 + drivers/input/fingerprint/elan_fp_qcom_tee.c | 683 ++++++++++++++++++ drivers/input/fingerprint/elan_fp_qcom_tee.h | 26 + 9 files changed, 789 insertions(+) mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953.dtsi mode change 100644 => 100755 drivers/input/Kconfig mode change 100644 => 100755 drivers/input/Makefile create mode 100755 drivers/input/fingerprint/Makefile create mode 100755 drivers/input/fingerprint/elan_fp_qcom_tee.c create mode 100755 drivers/input/fingerprint/elan_fp_qcom_tee.h diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 469edb3ea5df..04f108000a63 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -399,6 +399,60 @@ }; + fps { + fps_int_active: fps_int_active { + mux { + pins = "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio48"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + fps_int_suspend: fps_int_suspend { + mux { + pins = "gpio48"; + function = "gpio"; + }; + + config { + pins = "gpio48"; + drive-strength = <2>; + bias-pull-down; + }; + }; + + fps_reset_active: fps_reset_active { + mux { + pins = "gpio140"; + function = "gpio"; + }; + + config { + pins = "gpio140"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + fps_reset_suspend1: fps_reset_suspend1 { + mux { + pins = "gpio140"; + function = "gpio"; + }; + + config { + pins = "gpio140"; + drive-strength = <2>; + bias-pull-down; + }; + }; + }; + pmx_mdss: pmx_mdss { mdss_dsi_active: mdss_dsi_active { diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi old mode 100644 new mode 100755 index 8488d3a45453..8d256f319318 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -2319,3 +2319,14 @@ &gdsc_usb30 { status = "okay"; }; + +&soc { + elan { + compatible = "elan,elan_fp"; + interrupt-parent = <&tlmm>; + interrupts = <48 0>; + elan,irq-gpio = <&tlmm 48 0>; + elan,rst-gpio = <&tlmm 140 0>; + elan,vdd-gpio = <&tlmm 90 0>; + }; +}; diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index b1ac51887c44..f461419ddebf 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -684,3 +684,4 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y +CONFIG_ELAN_FINGERPRINT=y diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 99f879ef9c94..bcf163e7481f 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -748,3 +748,4 @@ CONFIG_CRYPTO_AES_ARM64_CE_BLK=y CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y +CONFIG_ELAN_FINGERPRINT=y diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig old mode 100644 new mode 100755 index de41b16afe65..411bf8e5dbbf --- a/drivers/input/Kconfig +++ b/drivers/input/Kconfig @@ -200,6 +200,15 @@ config INPUT_KEYCOMBO ---help--- Say Y here if you want to take action when some keys are pressed; +config ELAN_FINGERPRINT + tristate "ELAN Fingerprint" + default n + ---help--- + Fingerprint qualcomm driver enable/disable in the kernel. + Say Y here if you want to use qualcomm fingerprint driver, + fingerprint driver will support fingerprint function in TEE, + it supports ELNA's all fingerprint device. + comment "Input Device Drivers" source "drivers/input/keyboard/Kconfig" diff --git a/drivers/input/Makefile b/drivers/input/Makefile old mode 100644 new mode 100755 index 7ff1b70fd8cb..9d9d2222d263 --- a/drivers/input/Makefile +++ b/drivers/input/Makefile @@ -34,3 +34,5 @@ obj-$(CONFIG_RMI4_CORE) += rmi4/ obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o obj-$(CONFIG_INPUT_KEYCOMBO) += keycombo.o obj-$(CONFIG_SMI130) += sensors/smi130/ + +obj-$(CONFIG_ELAN_FINGERPRINT) +=fingerprint/ diff --git a/drivers/input/fingerprint/Makefile b/drivers/input/fingerprint/Makefile new file mode 100755 index 000000000000..4b4eb3a794b2 --- /dev/null +++ b/drivers/input/fingerprint/Makefile @@ -0,0 +1,2 @@ + +obj-$(CONFIG_ELAN_FINGERPRINT)=elan_fp_qcom_tee.o \ No newline at end of file diff --git a/drivers/input/fingerprint/elan_fp_qcom_tee.c b/drivers/input/fingerprint/elan_fp_qcom_tee.c new file mode 100755 index 000000000000..b9efba4802bf --- /dev/null +++ b/drivers/input/fingerprint/elan_fp_qcom_tee.c @@ -0,0 +1,683 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "elan_fp_qcom_tee.h" + +#define VERSION_LOG "2.2.1" + +static int elan_debug = 1; +#define ELAN_DEBUG(format, args ...) \ +do { \ + if (elan_debug) \ + printk("[ELAN] " format, ##args); \ + } while(0) + +#define KEY_FP_INT KEY_POWER //KEY_WAKEUP // change by customer & framework support +#define KEY_FP_INT2 KEY_1 // change by customer & framework support +#define SET_SPI_OWNER (0) +#if SET_SPI_OWNER +#include +#endif + +#if defined(CONFIG_FB) +#include +#include +#include +#endif + +static int factory_status = 0; +static DEFINE_MUTEX(elan_factory_mutex); +static DECLARE_WAIT_QUEUE_HEAD(elan_poll_wq); +static int elan_work_flag = 0; +#if defined(CONFIG_FB) +static struct notifier_block fb_notif; +static int pid_fp = -1; +static int display_status = -1; +#endif +#define VDD_POWER_GPIO 1 +struct elan_data { + int int_gpio; + int irq; + int rst_gpio; + int irq_is_disable; + struct miscdevice elan_dev; /* char device for ioctl */ + struct platform_device *pdev; + struct input_dev *input_dev; + spinlock_t irq_lock; + struct wakeup_source wake_lock; //struct wake_lock wake_lock; + struct wakeup_source hal_wake_lock; //struct wake_lock hal_wake_lock; +#if VDD_POWER_GPIO + int vdd_gpio; +#endif +}; + +void elan_irq_enable(void *_fp) +{ + struct elan_data *fp = _fp; + unsigned long irqflags = 0; + ELAN_DEBUG("IRQ Enable = %d.\n", fp->irq); + + spin_lock_irqsave(&fp->irq_lock, irqflags); + if (fp->irq_is_disable) + { + enable_irq(fp->irq); + fp->irq_is_disable = 0; + } + spin_unlock_irqrestore(&fp->irq_lock, irqflags); +} + +void elan_irq_disable(void *_fp) +{ + struct elan_data *fp = _fp; + unsigned long irqflags; + ELAN_DEBUG("IRQ Disable = %d.\n", fp->irq); + + spin_lock_irqsave(&fp->irq_lock, irqflags); + if (!fp->irq_is_disable) + { + fp->irq_is_disable = 1; + disable_irq_nosync(fp->irq); + } + spin_unlock_irqrestore(&fp->irq_lock, irqflags); +} + +static ssize_t show_drv_version_value(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", VERSION_LOG); +} +static DEVICE_ATTR(drv_version, S_IRUGO, show_drv_version_value, NULL); + +static ssize_t elan_debug_value(struct device *dev, struct device_attribute *attr, char *buf) +{ + if(elan_debug){ + elan_debug=0; + } else { + elan_debug=1; + } + return sprintf(buf, "[ELAN] elan debug %d\n", elan_debug); +} +static DEVICE_ATTR(elan_debug, S_IRUGO, elan_debug_value, NULL); + +static struct attribute *elan_attributes[] = { + &dev_attr_drv_version.attr, + &dev_attr_elan_debug.attr, + NULL +}; + +static struct attribute_group elan_attr_group = { + .attrs = elan_attributes, +}; + +static void elan_reset(struct elan_data *fp) +{ + /* Developement platform */ + gpio_set_value(fp->rst_gpio, 0); + mdelay(5); + gpio_set_value(fp->rst_gpio, 1); + mdelay(50); +} + +#if defined(CONFIG_FB) + +static int send_sig_to_pid(int sig, pid_t pid) +{ + struct siginfo info; + + info.si_signo = sig; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = get_current()->pid; + info.si_uid = from_kuid_munged(current_user_ns(), current_uid()); + + return kill_proc_info(sig, &info, pid); +} + +static int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank ; + + if (event != 0x10) + return 0; + + if(evdata == NULL) + { + pr_err("%s data is NULL\n",__func__); + return 0; + } + blank = evdata->data; + if(blank == NULL) + { + pr_err("%s blank is NULL\n",__func__); + return 0; + } + ELAN_DEBUG("%s fb notifier callback event = %lu, evdata->data = %d\n",__func__, event, *blank); + if (evdata && evdata->data) { + if (event == 0x10) { + if (*blank == FB_BLANK_UNBLANK) { + display_status = 0; + if(pid_fp != -1) + send_sig_to_pid(SIGUSR2,pid_fp); + ELAN_DEBUG("Display On\n"); + } + else if (*blank == FB_BLANK_POWERDOWN) { + display_status = 1; + if(pid_fp != -1) + send_sig_to_pid(SIGUSR2,pid_fp); + ELAN_DEBUG("Display Off\n"); + } + } + } + return 0; +} +#endif + +static long elan_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct elan_data *fp = filp->private_data; + int keycode; + int wake_lock_arg; + + ELAN_DEBUG("%s() : cmd = [%04X]\n", __func__, cmd); + + switch(cmd) + { + case ID_IOCTL_RESET: //6 + elan_reset(fp); + ELAN_DEBUG("[IOCTL] RESET\n"); + break; + + case ID_IOCTL_POLL_INIT: //20 + elan_work_flag = 0; + ELAN_DEBUG("[IOCTL] POLL INIT\n"); + break; + + case ID_IOCTL_POLL_EXIT: //23 + elan_work_flag = 1; + wake_up(&elan_poll_wq); + ELAN_DEBUG("[IOCTL] POLL EXIT\n"); + break; + + case ID_IOCTL_INPUT_KEYCODE: //22 + keycode =(int __user)arg; + ELAN_DEBUG("[IOCTL] KEYCODE DOWN & UP, keycode = %d \n", keycode); + if (!keycode) { + ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg); + break ; + } + input_report_key(fp->input_dev, keycode, 1); // Added for KEY Event + input_sync(fp->input_dev); + input_report_key(fp->input_dev, keycode, 0); // Added for KEY Event + input_sync(fp->input_dev); + break; + + case ID_IOCTL_SET_KEYCODE: //24 + keycode =(int __user)arg; + ELAN_DEBUG("[IOCTL] SET KEYCODE, keycode = %d \n", keycode); + if (!keycode) { + ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg); + break ; + } + input_set_capability(fp->input_dev, EV_KEY, keycode); + set_bit(keycode, fp->input_dev->keybit); + break; + + case ID_IOCTL_INPUT_KEYCODE_DOWN: //28 + keycode =(int __user)arg; + ELAN_DEBUG("[IOCTL] KEYCODE DOWN, keycode = %d \n", keycode); + if(!keycode) { + ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg); + break ; + } + input_report_key(fp->input_dev, keycode, 1); + input_sync(fp->input_dev); + break; + + case ID_IOCTL_INPUT_KEYCODE_UP: //29 + keycode =(int __user)arg; + ELAN_DEBUG("[IOCTL] KEYCODE UP, keycode = %d \n", keycode); + if(!keycode) { + ELAN_DEBUG("Keycode %d not defined, ignored\n", (int __user)arg); + break ; + } + input_report_key(fp->input_dev, keycode, 0); + input_sync(fp->input_dev); + break; + + case ID_IOCTL_READ_FACTORY_STATUS: //26 + mutex_lock(&elan_factory_mutex); + ELAN_DEBUG("[IOCTL] READ factory_status = %d\n", factory_status); + mutex_unlock(&elan_factory_mutex); + return factory_status; + break; + + case ID_IOCTL_WRITE_FACTORY_STATUS: //27 + mutex_lock(&elan_factory_mutex); + factory_status = (int __user)arg; + ELAN_DEBUG("[IOCTL] WRITE factory_status = %d\n", factory_status); + mutex_unlock(&elan_factory_mutex); + break; + + case ID_IOCTL_INT_STATUS: //40 + return gpio_get_value(fp->int_gpio); + + case ID_IOCTL_WAKE_LOCK_UNLOCK: //41 + wake_lock_arg = (int __user)arg; + if(!wake_lock_arg) + { + __pm_relax(&fp->hal_wake_lock); //wake_unlock(&fp->hal_wake_lock); + ELAN_DEBUG("[IOCTL] HAL WAKE UNLOCK = %d\n", wake_lock_arg); + } + else if(wake_lock_arg) + { + __pm_stay_awake(&fp->hal_wake_lock); //wake_lock(&fp->hal_wake_lock); + ELAN_DEBUG("[IOCTL] HAL WAKE LOCK = %d\n", wake_lock_arg); + } + else + ELAN_DEBUG("[IOCTL] ERROR WAKE LOCK ARGUMENT\n"); + break; + + case ID_IOCTL_EN_IRQ: //55 + elan_irq_enable(fp); + ELAN_DEBUG("[IOCTL] ENABLE IRQ\n"); + break; + + case ID_IOCTL_DIS_IRQ: //66 + elan_irq_disable(fp); + ELAN_DEBUG("[IOCTL] DISABLE IRQ\n"); + break; + + case ID_IOCTL_SET_IRQ_TYPE: //91 + ELAN_DEBUG("[IOCTL] SET IRQ TYPE\n"); + irq_set_irq_type(fp->irq, IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND | IRQF_ONESHOT); + break; + + case ID_IOCTL_DISPLAY_STATUS: //93 + ELAN_DEBUG("[IOCTL] DISPLAY_STATUS = %d\n", display_status); + return display_status; + + case ID_IOCTL_DISPLAY_NOTIFY: //94 + break; + + case ID_IOCTL_SET_PID: //94 + pid_fp = (int __user)arg; + ELAN_DEBUG("[IOCTL] ID_IOCTL_SET_PID = %d\n", pid_fp); + break; + + default: + ELAN_DEBUG("INVALID COMMAND\n"); + break; + } + return 0; +} + +static unsigned int elan_poll(struct file *file, poll_table *wait) +{ + int mask=0; + ELAN_DEBUG("%s()\n",__func__); + + wait_event_interruptible(elan_poll_wq, elan_work_flag > 0); + if(elan_work_flag > 0) + mask = elan_work_flag; + + elan_work_flag = 0; + return mask; +} + +static int elan_open(struct inode *inode, struct file *filp) +{ + struct elan_data *fp = container_of(filp->private_data, struct elan_data, elan_dev); + filp->private_data = fp; + ELAN_DEBUG("%s()\n", __func__); + return 0; +} + +static int elan_close(struct inode *inode, struct file *filp) +{ + ELAN_DEBUG("%s()\n", __func__); + return 0; +} + +static const struct file_operations elan_fops = { + .owner = THIS_MODULE, + .open = elan_open, + .unlocked_ioctl = elan_ioctl, + .poll = elan_poll, + .release = elan_close, +}; + +#if SET_SPI_OWNER +static int set_pipe_ownership(void) +{ + const u32 TZ_BLSP_MODIFY_OWNERSHIP_ID = 3; + const u32 TZBSP_TZ_ID = 3; + int rc; + struct scm_desc desc = { + .arginfo = SCM_ARGS(2), + .args[0] = 3, + .args[1] = TZBSP_TZ_ID, + }; + + rc = scm_call2(SCM_SIP_FNID(SCM_SVC_TZ, TZ_BLSP_MODIFY_OWNERSHIP_ID), &desc); + + if(rc || desc.ret[0]) + { + ELAN_DEBUG("%s() FAIL\n", __func__); + return -EINVAL; + } + ELAN_DEBUG("%s() Success\n", __func__); + return 0; +} +#endif + +static irqreturn_t elan_irq_handler(int irq, void *dev_id) +{ + struct elan_data *fp = (struct elan_data *)dev_id; + + ELAN_DEBUG("%s()\n", __func__); + __pm_wakeup_event(&fp->wake_lock, msecs_to_jiffies(1000)); //wake_lock_timeout(&fp->wake_lock, msecs_to_jiffies(1000)); + if(fp == NULL) + return IRQ_NONE; + elan_work_flag = 1; + wake_up(&elan_poll_wq); + + return IRQ_HANDLED; +} + +static int elan_setup_cdev(struct elan_data *fp) +{ + + fp->elan_dev.minor = MISC_DYNAMIC_MINOR; + fp->elan_dev.name = "elan_fp"; + fp->elan_dev.fops = &elan_fops; + fp->elan_dev.mode = S_IFREG|S_IRWXUGO; + if (misc_register(&fp->elan_dev) < 0) { + ELAN_DEBUG("misc_register failed\n"); + return -1; + } + else { + ELAN_DEBUG("misc_register finished\n"); + } + return 0; +} + +static int elan_sysfs_create(struct elan_data *sysfs) +{ + struct elan_data *fp = platform_get_drvdata(sysfs->pdev); + int ret = 0; + + /* Register sysfs */ + ret = sysfs_create_group(&fp->pdev->dev.kobj, &elan_attr_group); + if (ret) { + ELAN_DEBUG("create sysfs attributes failed, ret = %d\n", ret); + goto fail_un; + } + return 0; +fail_un: + /* Remove sysfs */ + sysfs_remove_group(&fp->pdev->dev.kobj, &elan_attr_group); + + return ret; +} + +static int elan_gpio_config(struct elan_data *fp) +{ + int ret = 0; + + // Configure INT GPIO (Input) + ret = gpio_request(fp->int_gpio, "elan-irq"); + if (ret < 0) + ELAN_DEBUG("interrupt pin request gpio failed, ret = %d\n", ret); + else { + gpio_direction_input(fp->int_gpio); + fp->irq = gpio_to_irq(fp->int_gpio); + if(fp->irq < 0) { + ELAN_DEBUG("gpio to irq failed, irq = %d\n", fp->irq); + ret = -1; + } + else + ELAN_DEBUG("gpio to irq success, irq = %d\n",fp->irq); + } + + // Configure RST GPIO (Output) + ret = gpio_request(fp->rst_gpio, "elan-rst"); + if (ret < 0) { + gpio_free(fp->int_gpio); + free_irq(fp->irq, fp); + ELAN_DEBUG("reset pin request gpio failed, ret = %d\n", ret); + } + else + gpio_direction_output(fp->rst_gpio, 1); +#if VDD_POWER_GPIO + // Configure VDD GPIO (Output) + ret = gpio_request(fp->vdd_gpio, "elan-vdd"); + if (ret < 0) { + gpio_free(fp->rst_gpio); + gpio_free(fp->int_gpio); + free_irq(fp->irq, fp); + ELAN_DEBUG("reset pin request gpio failed, ret = %d\n", ret); + } + else + gpio_direction_output(fp->vdd_gpio, 1); +#endif + return ret; +} + +static int elan_dts_init(struct elan_data *fp, struct device_node *np) +{ + fp->rst_gpio = of_get_named_gpio(np, "elan,rst-gpio", 0); + ELAN_DEBUG("rst_gpio = %d\n", fp->rst_gpio); + if (fp->rst_gpio < 0) + return fp->rst_gpio; + + fp->int_gpio = of_get_named_gpio(np, "elan,irq-gpio", 0); + ELAN_DEBUG("int_gpio = %d\n", fp->int_gpio); + if (fp->int_gpio < 0) + return fp->int_gpio; +#if VDD_POWER_GPIO + fp->vdd_gpio = of_get_named_gpio(np, "elan,vdd-gpio", 0); + ELAN_DEBUG("vdd_gpio = %d\n", fp->vdd_gpio); + if (fp->vdd_gpio < 0) + return fp->vdd_gpio; +#endif + return 0; +} + +static int elan_probe(struct platform_device *pdev) +{ + struct elan_data *fp = NULL; + struct input_dev *input_dev = NULL; + int ret = 0; + + ELAN_DEBUG("%s(), version = %s\n", __func__, VERSION_LOG); + + /* Allocate Device Data */ + fp = devm_kzalloc(&pdev->dev, sizeof(struct elan_data), GFP_KERNEL); + if(!fp) + ELAN_DEBUG("kzmalloc elan data failed\n"); + + /* Init Input Device */ + input_dev = input_allocate_device(); + if (!input_dev) + ELAN_DEBUG("alloc input_dev failed\n"); + + fp->pdev = pdev; + + platform_set_drvdata(pdev, fp); + + input_dev->name = "elan"; + input_dev->id.bustype = BUS_SPI; + input_dev->dev.parent = &pdev->dev; + input_set_drvdata(input_dev, fp); + + input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY); + input_set_capability(input_dev, EV_KEY, KEY_FP_INT); // change by customer, send key event to framework. KEY_xxx could be changed. + input_set_capability(input_dev, EV_KEY, KEY_FP_INT2); // change by customer, send key event to framework. KEY_xxx could be changed. + + fp->input_dev = input_dev; + + /* Init Sysfs */ + ret = elan_sysfs_create(fp); + if(ret < 0) + ELAN_DEBUG("sysfs create failed, ret = %d\n", ret); + + /* Init Char Device */ + ret = elan_setup_cdev(fp); + if(ret < 0) + ELAN_DEBUG("setup device failed, ret = %d\n", ret); + + /* Register Input Device */ + ret = input_register_device(input_dev); + if(ret) + ELAN_DEBUG("register input device failed, ret = %d\n", ret); + + ret = elan_dts_init(fp, pdev->dev.of_node); + if(ret < 0) + ELAN_DEBUG("device tree initial failed, ret = %d\n", ret); + + ret = elan_gpio_config(fp); + if(ret < 0) + ELAN_DEBUG("gpio config failed, ret = %d\n", ret); + + wakeup_source_init(&fp->wake_lock, "fp_wake_lock"); //wake_lock_init(&fp->wake_lock, WAKE_LOCK_SUSPEND, "fp_wake_lock"); + wakeup_source_init(&fp->hal_wake_lock, "hal_fp_wake_lock"); //wake_lock_init(&fp->hal_wake_lock, WAKE_LOCK_SUSPEND, "hal_fp_wake_lock"); + + ret = request_irq(fp->irq, elan_irq_handler, + IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING | IRQF_ONESHOT, + pdev->dev.driver->name, fp); + if(ret) + ELAN_DEBUG("request irq failed, ret = %d\n", ret); + + irq_set_irq_wake(fp->irq, 1); + + spin_lock_init(&fp->irq_lock); + +#if defined(CONFIG_FB) + fb_notif.notifier_call = fb_notifier_callback; + fb_register_client(&fb_notif); +#endif + + /* Set Spi to TZ */ +#if SET_SPI_OWNER + ret = set_pipe_ownership(); +#endif + + ELAN_DEBUG("%s() End\n", __func__); + return 0; +} + +static int elan_remove(struct platform_device *pdev) +{ + struct elan_data *fp = platform_get_drvdata(pdev); + + if (fp->irq) + free_irq(fp->irq, fp); +#if VDD_POWER_GPIO + gpio_free(fp->vdd_gpio); +#endif + gpio_free(fp->int_gpio); + gpio_free(fp->rst_gpio); + + misc_deregister(&fp->elan_dev); + input_free_device(fp->input_dev); + +#if defined(CONFIG_FB) + fb_unregister_client(&fb_notif); +#endif + + kfree(fp); + + platform_set_drvdata(pdev, NULL); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int elan_suspend(struct device *dev) +{ + ELAN_DEBUG("elan suspend!\n"); + return 0; +} + +static int elan_resume(struct device *dev) +{ + ELAN_DEBUG("elan resume!\n"); + return 0; +} +#endif + +static SIMPLE_DEV_PM_OPS(elan_pm_ops, elan_suspend, elan_resume); + +#ifdef CONFIG_OF +static struct of_device_id elan_metallica_table[] = { + { .compatible = "elan,elan_fp",}, + { }, +}; +#else +#define elan_metallica_table NULL +#endif + +static struct platform_driver elan_driver = { + .driver = { + .name = "elan", + .owner = THIS_MODULE, + .pm = &elan_pm_ops, + .of_match_table = elan_metallica_table, + }, + .probe = elan_probe, + .remove = elan_remove, +}; + +static int __init elan_init(void) +{ + int ret = 0; + ELAN_DEBUG("%s() Start\n", __func__); + + ret = platform_driver_register(&elan_driver); + if(ret < 0) + ELAN_DEBUG("%s FAIL !\n", __func__); + + ELAN_DEBUG("%s() End\n", __func__); + return 0; +} + +static void __exit elan_exist(void) +{ + platform_driver_unregister(&elan_driver); +} + +module_init(elan_init); +module_exit(elan_exist); + +MODULE_AUTHOR("Elan"); +MODULE_DESCRIPTION("ELAN SPI FingerPrint driver"); +MODULE_VERSION(VERSION_LOG); +MODULE_LICENSE("GPL"); diff --git a/drivers/input/fingerprint/elan_fp_qcom_tee.h b/drivers/input/fingerprint/elan_fp_qcom_tee.h new file mode 100755 index 000000000000..a7a74fcec8e6 --- /dev/null +++ b/drivers/input/fingerprint/elan_fp_qcom_tee.h @@ -0,0 +1,26 @@ +#ifndef _LINUX_ELAN_FP_H +#define _LINUX_ELAN_FP_H + +#define FINGERPRINT_IOCTL 0x80 +#define ID_IOCTL_RESET _IOW(FINGERPRINT_IOCTL, 6, int) +#define ID_IOCTL_POLL_INIT _IOW(FINGERPRINT_IOCTL, 20, int) +#define ID_IOCTL_INPUT_KEYCODE _IOW(FINGERPRINT_IOCTL, 22, int) +#define ID_IOCTL_POLL_EXIT _IOW(FINGERPRINT_IOCTL, 23, int) +#define ID_IOCTL_SET_KEYCODE _IOW(FINGERPRINT_IOCTL, 24, int) +#define ID_IOCTL_READ_FACTORY_STATUS _IOW(FINGERPRINT_IOCTL, 26, int) +#define ID_IOCTL_WRITE_FACTORY_STATUS _IOW(FINGERPRINT_IOCTL, 27, int) +#define ID_IOCTL_INPUT_KEYCODE_DOWN _IOW(FINGERPRINT_IOCTL, 28, int) +#define ID_IOCTL_INPUT_KEYCODE_UP _IOW(FINGERPRINT_IOCTL, 29, int) +#define ID_IOCTL_INT_STATUS _IOW(FINGERPRINT_IOCTL, 40, int) +#define ID_IOCTL_WAKE_LOCK_UNLOCK _IOW(FINGERPRINT_IOCTL, 41, int) +#define ID_IOCTL_EN_IRQ _IOW(FINGERPRINT_IOCTL, 55, int) +#define ID_IOCTL_DIS_IRQ _IOW(FINGERPRINT_IOCTL, 66, int) +#define ID_IOCTL_SET_IRQ_TYPE _IOW(FINGERPRINT_IOCTL, 91, int) +#define ID_IOCTL_DISPLAY_STATUS _IOW(FINGERPRINT_IOCTL, 93, int) +#define ID_IOCTL_DISPLAY_NOTIFY _IOW(FINGERPRINT_IOCTL, 94, int) +#define ID_IOCTL_SET_PID _IOW(FINGERPRINT_IOCTL, 95, int) + +#define CUSTOMER_IOCTLID 0xD0 //For customer define + +#endif /* _LINUX_ELAN_FP_H */ + -- GitLab From 3515162f03cb7953212358a6313f81a60048d010 Mon Sep 17 00:00:00 2001 From: tracychui Date: Wed, 29 Apr 2020 16:24:36 +0800 Subject: [PATCH 23/96] Add Touch drivers for FP3 Include the config and add all touch related drivers and functions. Issue: FP3-A11#202 Change-Id: I410640b03f15c06b9f67e6096aea4daa19a23a30 (cherry picked from commit 8a9834c32dfd19660c7b283bf74704625c93e0b6) --- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 60 - arch/arm64/boot/dts/qcom/msm8953.dtsi | 30 +- arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi | 16 + arch/arm64/configs/msm8953-perf_defconfig | 9 +- arch/arm64/configs/msm8953_defconfig | 9 +- drivers/input/touchscreen/Kconfig | 7 +- drivers/input/touchscreen/Makefile | 3 +- .../FP_DJN_Arima_CID0804_D02_C14_20190903.i | 4096 +++++++++++++++++ .../input/touchscreen/hxchipset83112b/Kconfig | 27 + .../touchscreen/hxchipset83112b/Makefile | 4 + .../hxchipset83112b/himax_common.c | 2398 ++++++++++ .../hxchipset83112b/himax_common.h | 440 ++ .../touchscreen/hxchipset83112b/himax_debug.c | 3351 ++++++++++++++ .../touchscreen/hxchipset83112b/himax_debug.h | 213 + .../touchscreen/hxchipset83112b/himax_ic.c | 3224 +++++++++++++ .../touchscreen/hxchipset83112b/himax_ic.h | 80 + .../hxchipset83112b/himax_platform.c | 813 ++++ .../hxchipset83112b/himax_platform.h | 130 + 18 files changed, 14808 insertions(+), 102 deletions(-) mode change 100644 => 100755 drivers/input/touchscreen/Kconfig mode change 100644 => 100755 drivers/input/touchscreen/Makefile create mode 100755 drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i create mode 100755 drivers/input/touchscreen/hxchipset83112b/Kconfig create mode 100755 drivers/input/touchscreen/hxchipset83112b/Makefile create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_common.c create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_common.h create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_debug.c create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_debug.h create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_ic.c create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_ic.h create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_platform.c create mode 100755 drivers/input/touchscreen/hxchipset83112b/himax_platform.h diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 04f108000a63..2232b0f2b32c 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -1421,66 +1421,6 @@ }; }; - spi3 { - spi3_default: spi3_default { - /* active state */ - mux { - /* MOSI, MISO, CLK */ - pins = "gpio8", "gpio9", "gpio11"; - function = "blsp_spi3"; - }; - - config { - pins = "gpio8", "gpio9", "gpio11"; - drive-strength = <12>; /* 12 MA */ - bias-disable = <0>; /* No PULL */ - }; - }; - - spi3_sleep: spi3_sleep { - /* suspended state */ - mux { - /* MOSI, MISO, CLK */ - pins = "gpio8", "gpio9", "gpio11"; - function = "gpio"; - }; - - config { - pins = "gpio8", "gpio9", "gpio11"; - drive-strength = <2>; /* 2 MA */ - bias-pull-down; /* PULL Down */ - }; - }; - - spi3_cs0_active: cs0_active { - /* CS */ - mux { - pins = "gpio10"; - function = "blsp_spi3"; - }; - - config { - pins = "gpio10"; - drive-strength = <2>; - bias-disable = <0>; - }; - }; - - spi3_cs0_sleep: cs0_sleep { - /* CS */ - mux { - pins = "gpio10"; - function = "gpio"; - }; - - config { - pins = "gpio10"; - drive-strength = <2>; - bias-disable = <0>; - }; - }; - }; - spi6 { spi6_default: spi6_default { /* active state */ diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index 8d256f319318..871b1d4b1270 100755 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -188,7 +188,7 @@ i2c2 = &i2c_2; i2c3 = &i2c_3; i2c5 = &i2c_5; - spi3 = &spi_3; +// spi3 = &spi_3; spi6 = &spi_6; }; @@ -687,32 +687,6 @@ qcom,summing-threshold = <10>; }; - spi_3: spi@78b7000 { /* BLSP1 QUP3 */ - compatible = "qcom,spi-qup-v2"; - #address-cells = <1>; - #size-cells = <0>; - reg-names = "spi_physical", "spi_bam_physical"; - reg = <0x78b7000 0x600>, - <0x7884000 0x1f000>; - interrupt-names = "spi_irq", "spi_bam_irq"; - interrupts = <0 97 0>, <0 238 0>; - spi-max-frequency = <19200000>; - pinctrl-names = "spi_default", "spi_sleep"; - pinctrl-0 = <&spi3_default &spi3_cs0_active>; - pinctrl-1 = <&spi3_sleep &spi3_cs0_sleep>; - clocks = <&clock_gcc clk_gcc_blsp1_ahb_clk>, - <&clock_gcc clk_gcc_blsp1_qup3_spi_apps_clk>; - clock-names = "iface_clk", "core_clk"; - qcom,infinite-mode = <0>; - qcom,use-bam; - qcom,use-pinctrl; - qcom,ver-reg-exists; - qcom,bam-consumer-pipe-index = <8>; - qcom,bam-producer-pipe-index = <9>; - qcom,master-id = <86>; - status = "disabled"; - }; - spi_6: spi@7af6000 { /* BLSP2 QUP2 */ compatible = "qcom,spi-qup-v2"; #address-cells = <1>; @@ -813,7 +787,7 @@ dmas = <&dma_blsp1 8 64 0x20000020 0x20>, <&dma_blsp1 9 32 0x20000020 0x20>; dma-names = "tx", "rx"; - status = "disabled"; + status = "ok"; }; i2c_5: i2c@7af5000 { /* BLSP2 QUP1 */ diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi index e14fa9ab2234..4eb5f2521f5e 100755 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi @@ -373,3 +373,19 @@ }; }; +&i2c_3 { + status = "ok"; + himax_ts@48 { + compatible = "himax,hxcommon"; + reg = <0x48>; + interrupt-parent = <&tlmm>; + interrupts = <65 0x2008>; + vcc_i2c-supply = <&pm8953_l6>; + vdd-ana-supply = <&pm8953_l10>; + himax,display-coords = <0 1080 0 2160>; + himax,panel-coords = <0 1080 0 2160>; + himax,irq-gpio = <&tlmm 65 0x2008>; + himax,rst-gpio = <&tlmm 64 0x00>; + report_type = <1>; + }; +}; diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index f461419ddebf..f5d85ba62bca 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -320,12 +320,11 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y -CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y -CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y -CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26=y +CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y +CONFIG_TOUCHSCREEN_HIMAX_I2C=y +CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y CONFIG_INPUT_MISC=y -CONFIG_INPUT_HBTP_INPUT=y +# CONFIG_INPUT_HBTP_INPUT=y CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index bcf163e7481f..cba4f0cd7c47 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -327,12 +327,11 @@ CONFIG_KEYBOARD_GPIO=y # CONFIG_INPUT_MOUSE is not set CONFIG_INPUT_JOYSTICK=y CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_CORE_v26=y -CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI_DEV_v26=y -CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE_v26=y -CONFIG_SECURE_TOUCH_SYNAPTICS_DSX_V26=y +CONFIG_TOUCHSCREEN_HIMAX_CHIPSET=y +CONFIG_TOUCHSCREEN_HIMAX_I2C=y +CONFIG_TOUCHSCREEN_HIMAX_DEBUG=y CONFIG_INPUT_MISC=y -CONFIG_INPUT_HBTP_INPUT=y +# CONFIG_INPUT_HBTP_INPUT=y CONFIG_INPUT_QPNP_POWER_ON=y CONFIG_INPUT_UINPUT=y # CONFIG_SERIO_SERPORT is not set diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig old mode 100644 new mode 100755 index 1e620a99b386..6caf213d21f7 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -11,7 +11,7 @@ menuconfig INPUT_TOUCHSCREEN if INPUT_TOUCHSCREEN -source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig" +#source "drivers/input/touchscreen/synaptics_dsx_2.6/Kconfig" config TOUCHSCREEN_PROPERTIES def_tristate INPUT @@ -1373,7 +1373,7 @@ config TOUCHSCREEN_SYNAPTICS_DSX If unsure, say N. -source "drivers/input/touchscreen/synaptics_dsx/Kconfig" +#source "drivers/input/touchscreen/synaptics_dsx/Kconfig" source "drivers/input/touchscreen/focaltech_touch/Kconfig" config TOUCHSCREEN_FT5X06 @@ -1432,7 +1432,8 @@ config TOUCHSCREEN_HIMAX_CHIPSET If unsure, say N. -source "drivers/input/touchscreen/hxchipset/Kconfig" +#source "drivers/input/touchscreen/hxchipset/Kconfig" +source "drivers/input/touchscreen/hxchipset83112b/Kconfig" config TOUCHSCREEN_EKTF3XXX_CHIPSET bool "Elan EKTF3XXX touchpanel CHIPSET" diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile old mode 100644 new mode 100755 index 59cf96765296..24f1dcd56cda --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -106,6 +106,7 @@ obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_touch/ obj-$(CONFIG_TOUCHSCREEN_GT9XX_v28) += gt9xx_v2.8/ -obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset/ +# obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset/ +obj-$(CONFIG_TOUCHSCREEN_HIMAX_CHIPSET) += hxchipset83112b/ obj-$(CONFIG_TOUCHSCREEN_EKTF3XXX_CHIPSET) += ektf3xxx/ obj-$(CONFIG_TOUCHSCREEN_RAYDIUM_CHIPSET) += raydium_wt030/ diff --git a/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i new file mode 100755 index 000000000000..fdb82bfacb2a --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C14_20190903.i @@ -0,0 +1,4096 @@ +0x48,0x00,0x01,0x94,0x48,0x00,0x00,0x30,0x48,0x00,0x00,0x2E,0x48,0x00,0x00,0x2C, +0x48,0x00,0x00,0x2A,0x48,0x00,0x00,0x49,0x48,0x00,0x00,0x69,0x48,0x00,0x00,0x89, +0x48,0x00,0x00,0xA9,0x48,0x00,0x00,0xDE,0x48,0x00,0x01,0x38,0x48,0x00,0x01,0x3A, +0x48,0x00,0x01,0x3C,0x48,0x00,0x01,0x3E,0x48,0x00,0x01,0x2C,0x48,0x00,0x01,0x3E, +0x50,0x03,0x00,0x40,0x50,0x03,0x00,0x40,0x50,0x03,0x00,0x40,0x8E,0x03,0x00,0x40, +0x96,0x03,0x00,0x40,0x9E,0x03,0x00,0x40,0xA4,0x03,0x00,0x40,0xAC,0x03,0x00,0x40, +0xB2,0x03,0x00,0x40,0xD5,0x00,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E, +0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,0x64,0x22, +0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08, +0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x46,0xF4,0x00,0x00,0x58,0xF7, +0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC, +0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02, +0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00, +0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x05,0x46,0xF4, +0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,0x3A,0x0F,0x94,0x3C, +0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02, +0x64,0x12,0xA4,0x02,0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02, +0x00,0x03,0x64,0x00,0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F, +0x84,0x06,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00, +0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C, +0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C, +0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF, +0x88,0x09,0xB6,0x5F,0x84,0x07,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00, +0x3C,0x00,0x3A,0x1F,0xA4,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x6E,0x80,0x20,0x3A,0x6F, +0x98,0x3C,0x64,0x62,0x00,0x02,0x64,0x72,0xA4,0x02,0x9D,0xFC,0x64,0x82,0x04,0x02, +0x3A,0x6F,0xA0,0x3C,0x9F,0xB2,0x64,0x62,0x00,0x03,0x64,0x00,0x00,0x08,0x80,0xDF, +0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0xDF,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50, +0x4B,0xE0,0x3C,0x01,0x05,0xFF,0x80,0x00,0x3A,0x6F,0xA0,0x04,0x64,0x62,0x00,0x03, +0x64,0x00,0x00,0x08,0x64,0x72,0xA4,0x03,0x64,0x82,0x04,0x03,0x3A,0x6F,0x98,0x04, +0x42,0x6E,0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x1F,0xA4,0x04,0x64,0x00,0x00,0x04, +0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C, +0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x00,0x46,0x14,0x00,0x00, +0x58,0x10,0x83,0x8E,0xDD,0x21,0x05,0xFF,0x80,0x00,0x3A,0x2F,0x88,0x04,0x42,0x2E, +0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x0F,0x94,0x04,0x64,0x00,0x00,0x04,0x3A,0x1F, +0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x12, +0x00,0x02,0x64,0x22,0xA4,0x02,0x64,0x32,0x04,0x02,0x3A,0x1F,0x8C,0x3C,0x9E,0x4A, +0x64,0x12,0x00,0x03,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x46,0x14, +0x00,0x00,0x58,0x10,0x80,0x4C,0x38,0x10,0x82,0x02,0xDD,0x21,0x05,0xFF,0x80,0x00, +0x3A,0x0F,0x88,0x04,0x64,0x02,0x00,0x43,0x64,0x00,0x00,0x08,0x64,0x02,0x00,0x03, +0x64,0x12,0xA4,0x03,0x64,0x22,0x04,0x03,0x3A,0x2F,0x88,0x04,0x42,0x2E,0x80,0x21, +0x3A,0xFF,0xEF,0x84,0x3A,0x1F,0x94,0x04,0x3A,0x0F,0x80,0x04,0x64,0x00,0x00,0x04, +0x3A,0x0F,0x80,0x3C,0x84,0x05,0xD5,0xC4,0x3A,0x0F,0x80,0x3C,0x84,0x01,0xD5,0xC0, +0x3A,0x0F,0x80,0x3C,0x84,0x02,0xD5,0xBC,0x3A,0x0F,0x80,0x3C,0x84,0x03,0xD5,0xB8, +0x3A,0x0F,0x80,0x3C,0x84,0x04,0xD5,0xB4,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC, +0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02, +0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00, +0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x0F,0x46,0x14, +0x00,0x00,0x58,0x10,0x83,0x50,0xDD,0x21,0x05,0xFF,0x80,0x00,0x3A,0x0F,0x88,0x04, +0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,0x64,0x12,0xA4,0x03,0x64,0x22,0x04,0x03, +0x3A,0x2F,0x88,0x04,0x42,0x2E,0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x0F,0x94,0x04, +0x64,0x00,0x00,0x04,0x40,0x00,0x00,0x09,0x47,0xD4,0x00,0x0B,0x59,0xDE,0x82,0x08, +0x3E,0x0F,0xF5,0x0C,0x42,0x0E,0x00,0x21,0x3F,0xC8,0x00,0x00,0x3F,0xF8,0x0D,0xF8, +0x49,0x00,0x00,0x1E,0x49,0x00,0x00,0x18,0x49,0x00,0x11,0xA6,0xD5,0x00,0x92,0x00, +0xD5,0x00,0x84,0x00,0x64,0x05,0xE4,0x03,0x46,0x04,0x00,0x00,0x58,0x00,0x00,0x00, +0x64,0x02,0x24,0x03,0x64,0x02,0x00,0x02,0x66,0x00,0x00,0x06,0x64,0x02,0x00,0x03, +0xEA,0x5C,0xDD,0x9E,0xFC,0x00,0x49,0xFF,0xFF,0xEE,0xFC,0x80,0x46,0x04,0x00,0x00, +0x58,0x00,0x00,0x00,0xEA,0x37,0x64,0x04,0xC0,0x03,0xEA,0x5C,0xDD,0x9E,0xFC,0x00, +0x49,0x00,0x44,0xF2,0xFC,0x80,0xFC,0x00,0x49,0x00,0x4A,0x1C,0xFC,0x80,0x40,0x00, +0x00,0x09,0xDD,0x9E,0xFC,0x00,0x49,0x00,0x45,0x49,0xFC,0x80,0x40,0x00,0x00,0x09, +0xDD,0x9E,0xFC,0x00,0x49,0x00,0x47,0xEA,0xFC,0x80,0x00,0x00,0x80,0xA0,0x94,0x91, +0x88,0x02,0x92,0x00,0x1A,0x12,0x80,0x01,0xD8,0xFE,0xDD,0x9E,0x80,0xA0,0x80,0x62, +0x96,0x8F,0x8A,0x62,0xC2,0x06,0x88,0x02,0x18,0x12,0x80,0x01,0xD8,0xFE,0x8A,0x02, +0xC3,0x06,0x88,0x02,0x88,0x03,0x3A,0x12,0x84,0x24,0xD8,0xFE,0xDD,0x9E,0x80,0xA2, +0x80,0x60,0x96,0x0F,0x8A,0x60,0xC0,0x08,0x88,0x02,0x28,0x42,0x80,0x01,0x18,0x40, +0x80,0x01,0xD8,0xFC,0x8A,0x02,0xC3,0x08,0x88,0x02,0x88,0x03,0x3A,0x42,0x90,0x04, +0x3A,0x40,0x90,0x24,0xD8,0xFC,0xDD,0x9E,0xFC,0x01,0xF0,0x81,0xF0,0x01,0x8E,0x01, +0xF0,0x81,0xC0,0x03,0xEA,0x6E,0xD5,0xFB,0xFC,0x81,0xFC,0x01,0xF0,0x81,0xF0,0x01, +0x8E,0x01,0xF0,0x81,0xC0,0x05,0xEA,0x33,0xC0,0x03,0xEA,0x6E,0xD5,0xF9,0xFC,0x81, +0xFC,0x01,0x84,0xCE,0xF0,0x81,0xF0,0x01,0x8E,0xC1,0xDD,0x4A,0x97,0xB0,0x84,0x05, +0xDD,0x50,0xCE,0xFA,0xFC,0x81,0x80,0x3F,0x3E,0x08,0x03,0x08,0x9A,0x08,0x5C,0xF0, +0x00,0x3D,0xE8,0x05,0x3C,0x1F,0xFF,0x7F,0x84,0x01,0xDD,0x9E,0x3E,0x08,0x0D,0xF8, +0x8A,0x01,0x3C,0x1D,0xFF,0x7F,0xE2,0x20,0xE8,0x03,0x3C,0x0F,0xFF,0x7F,0x84,0x00, +0xDD,0x9E,0xFC,0x00,0xDD,0x4B,0x5A,0x00,0x08,0x18,0x5A,0x00,0x06,0x16,0xEA,0xB2, +0xEB,0x22,0xEB,0x2F,0xEB,0x57,0xEA,0x67,0xDD,0x48,0x2E,0x07,0xFD,0x71,0x3E,0x07, +0xFD,0x77,0x46,0x21,0x00,0x05,0x58,0x21,0x08,0x88,0xEA,0x5A,0x46,0x11,0x00,0x05, +0x58,0x10,0x86,0xD8,0xD5,0x06,0xEA,0x5A,0xEB,0x22,0xEB,0x2F,0xEB,0x57,0xEA,0x67, +0xDD,0x48,0x84,0x00,0xDD,0x55,0xDD,0x4B,0x5A,0x00,0x08,0x17,0x5A,0x00,0x06,0x15, +0x84,0xA0,0x80,0x05,0xEB,0x6F,0x58,0x31,0x81,0x44,0xDD,0x4F,0x50,0x12,0x8F,0x34, +0x88,0x23,0xA4,0x48,0x8C,0xA2,0xE6,0x21,0x88,0x0F,0x96,0x01,0xDA,0xF8,0x5C,0xF0, +0x00,0xD9,0xE9,0x02,0xD5,0x00,0xFC,0x80,0xFC,0x41,0x3F,0xCF,0xFD,0xD8,0x84,0x00, +0x3E,0x07,0xFD,0x0A,0x49,0x00,0x4B,0xB8,0x3E,0x07,0xFD,0x17,0x84,0x20,0xF1,0x81, +0x4E,0x02,0x00,0xB6,0xEB,0x5A,0x02,0x50,0x80,0x00,0x44,0x10,0xA5,0x5A,0x46,0x71, +0x00,0x00,0x58,0x73,0x80,0x00,0x4C,0x50,0x80,0xAB,0xEB,0x5A,0x02,0x50,0x80,0x00, +0x44,0x10,0xA3,0x3A,0x4C,0x50,0x80,0xA4,0x9E,0x41,0xE6,0x27,0xE9,0x04,0x5A,0x08, +0x09,0x14,0xD5,0x06,0x84,0x21,0x3E,0x17,0xFD,0x0A,0x5A,0x08,0x01,0x0E,0xB8,0x00, +0x5A,0x00,0x08,0x07,0x5A,0x00,0x06,0x05,0xEB,0x54,0xEA,0xAC,0xD5,0x03,0xEB,0x51, +0xEA,0xFA,0xF0,0x81,0xD5,0x0E,0x54,0x10,0x00,0xF7,0x5A,0x18,0x02,0x05,0xEB,0x54, +0xEA,0x72,0xD5,0xF8,0x5A,0x18,0x03,0x04,0xB8,0x1A,0xD5,0xF4,0x5A,0x00,0x08,0xFE, +0xB0,0x41,0x3E,0x0F,0xFD,0x17,0x49,0x00,0x07,0x09,0xF5,0x01,0x46,0x11,0x00,0x04, +0x58,0x10,0x84,0xB8,0x84,0xC1,0xD1,0x07,0x50,0x10,0x85,0xF0,0x40,0x62,0x84,0x03, +0x5C,0x63,0x00,0x01,0xEA,0xAE,0xEA,0xD1,0x84,0x20,0xFE,0x84,0xEB,0x81,0x58,0x00, +0x00,0x04,0x94,0x91,0xDD,0x42,0xB8,0x00,0x5A,0x08,0x08,0x08,0xEA,0x5A,0xEB,0x5A, +0xEB,0x30,0xF2,0x01,0xDD,0x48,0xD5,0x46,0x5A,0x00,0x06,0xFA,0x84,0x00,0xF1,0x01, +0x49,0x00,0x07,0x18,0xC8,0xF4,0xF1,0x01,0xB8,0x1A,0x4C,0x10,0x40,0x0E,0x46,0x91, +0x00,0x04,0x58,0x94,0x8A,0xA8,0xF0,0x01,0x80,0x29,0x84,0x40,0x49,0x00,0x41,0x48, +0x14,0x9F,0x80,0x01,0xD5,0x09,0xEB,0x54,0xEA,0x72,0x4C,0x10,0x3F,0xF2,0x84,0x01, +0x49,0x00,0x07,0x00,0xC8,0xED,0x2F,0x30,0x00,0x11,0x2F,0x10,0x00,0x10,0x50,0x03, +0x00,0x12,0x94,0x41,0x42,0x60,0x98,0x73,0x94,0x82,0x84,0x00,0x05,0x2F,0x80,0x01, +0x40,0x98,0x84,0x08,0x95,0xB1,0x80,0xA0,0x80,0x80,0x9C,0x6C,0xE2,0x93,0x41,0x03, +0x84,0x00,0xE8,0x10,0x98,0xC6,0x88,0x72,0x84,0x20,0xE2,0x31,0xE8,0x07,0x38,0xA1, +0x85,0x01,0x38,0xA8,0x05,0x09,0x8C,0x21,0xD5,0xF9,0x8C,0x81,0x88,0xA9,0x88,0x02, +0xD5,0xED,0xEA,0xAE,0x2E,0x10,0x00,0x10,0x42,0x01,0x04,0x24,0x88,0x41,0x8C,0x02, +0x40,0x03,0x80,0x20,0x84,0x20,0x94,0x91,0xDD,0x42,0xEA,0x84,0x54,0x00,0x00,0xF7, +0x5A,0x08,0x01,0x04,0x49,0x00,0x00,0xCC,0x49,0x00,0x4B,0x66,0xFC,0xC1,0xFC,0x00, +0xDD,0x4D,0x96,0x04,0xC0,0x09,0xEA,0x33,0xC0,0x08,0x2E,0x07,0xFE,0x79,0xC8,0x05, +0x49,0x00,0x4A,0x6E,0xD5,0x02,0xEA,0x6D,0xFC,0x80,0x2E,0x17,0xFD,0x1C,0xFE,0x0C, +0x96,0x01,0xDD,0x9E,0xFC,0x60,0xDD,0x57,0x04,0x70,0x00,0x3F,0x92,0xF8,0x96,0x78, +0x5A,0x10,0xAA,0x06,0x5A,0x10,0xCC,0x04,0x5A,0x18,0xDD,0x46,0x04,0x60,0x00,0x3F, +0x40,0x03,0x40,0x09,0xEA,0xEB,0x96,0x31,0x40,0x90,0x20,0x09,0x97,0xB0,0xEA,0x4A, +0x5A,0x70,0xCC,0x19,0x5A,0x70,0xDD,0x28,0x5A,0x78,0xAA,0x2D,0x84,0xE0,0x46,0xC1, +0x00,0x07,0x58,0xC6,0x0F,0x80,0x96,0x38,0xE2,0x06,0xE8,0x24,0x50,0xB3,0x80,0x01, +0x80,0x0A,0x80,0x29,0x40,0x25,0x80,0x13,0xEA,0x3A,0x38,0x06,0x1C,0x08,0x80,0xEB, +0xD5,0xF3,0x84,0x40,0x46,0xB1,0x00,0x07,0x58,0xB5,0x8F,0x80,0x96,0x10,0xE2,0x06, +0xE8,0x11,0x9D,0xD1,0x38,0x35,0x88,0x00,0x80,0x0A,0x96,0xB9,0x80,0x29,0xDD,0x4E, +0x80,0x47,0xD5,0xF5,0xEB,0x61,0x00,0x30,0x0F,0x80,0x80,0x29,0x80,0x0A,0x80,0x46, +0xDD,0x4E,0xEA,0x3E,0x83,0x81,0xB8,0x3F,0x46,0x2B,0xB0,0x00,0xEA,0xB1,0x40,0x01, +0x01,0x15,0xB8,0xBF,0xFC,0xE0,0xFC,0x00,0xDD,0x52,0x4E,0x00,0x4C,0x03,0x84,0x62, +0xDD,0x4E,0xF8,0x24,0x84,0x42,0xDD,0x4E,0xF8,0x21,0x84,0x43,0xDD,0x4E,0xF8,0x15, +0xDD,0x4E,0x84,0x0A,0xDD,0x50,0xF8,0x1A,0x84,0x44,0xDD,0x4E,0xF8,0x1D,0xEA,0x3A, +0x3E,0x07,0xFD,0x1B,0xF8,0x13,0x84,0x41,0xDD,0x4E,0x4E,0x00,0x4B,0xF3,0xFA,0x64, +0xDD,0x4E,0xF8,0x0C,0x84,0x43,0xDD,0x4E,0x84,0x20,0x84,0x44,0x44,0x30,0x00,0x80, +0xDD,0x53,0x83,0xFF,0xDD,0x4E,0x84,0x0A,0xDD,0x50,0x84,0x20,0x80,0x61,0xDD,0x53, +0x83,0xFF,0x84,0x44,0xDD,0x4E,0x84,0x20,0x84,0x45,0xDD,0x53,0x83,0xFF,0xEA,0x3A, +0x3E,0x07,0xFD,0x04,0xFC,0x80,0xFC,0x00,0x84,0x0E,0xDD,0x40,0xC8,0x1B,0xFA,0x02, +0xDD,0x40,0xC8,0x18,0xFA,0x06,0xDD,0x40,0xC8,0x15,0x84,0x0A,0xDD,0x40,0xC8,0x12, +0xFA,0x0A,0xDD,0x40,0xC8,0x0F,0xFA,0x13,0xDD,0x40,0xC8,0x0C,0xFA,0x0E,0xDD,0x40, +0xC8,0x09,0xFA,0x18,0xDD,0x40,0xC8,0x06,0xFA,0x1C,0xDD,0x40,0xC8,0x03,0xDD,0x47, +0xDD,0x40,0xEA,0x28,0x02,0x00,0x80,0x9C,0x02,0x10,0x80,0x0A,0x8A,0x01,0x44,0x10, +0x06,0x5C,0xFE,0x0C,0x84,0x2A,0xEA,0xDD,0x92,0x04,0xFC,0x80,0xFC,0x40,0x3F,0xCF, +0xFD,0xD8,0xEB,0x51,0x00,0x20,0x02,0xC0,0xC2,0x04,0xEB,0x51,0x10,0x20,0x02,0xC1, +0xBD,0x11,0x5A,0x58,0x05,0x06,0x84,0x00,0xEB,0x78,0x10,0x00,0x82,0xC1,0x2E,0x47, +0xFD,0x4B,0xEB,0x43,0x44,0x30,0x03,0xE8,0x44,0x10,0x27,0x10,0xFE,0x1C,0x42,0x02, +0x04,0x73,0xB9,0x0C,0x84,0x8A,0x88,0x01,0x42,0x02,0x90,0x73,0xEB,0x84,0x96,0x01, +0x12,0x00,0x87,0xA2,0x2E,0x57,0xFD,0x65,0xEB,0x61,0x00,0x00,0x00,0x80,0xEA,0x2A, +0xFE,0x24,0x42,0x02,0x84,0x73,0x2E,0x57,0xFD,0x50,0x96,0x91,0x88,0x05,0x96,0x01, +0xEB,0x5F,0x12,0x02,0x87,0xA3,0xEB,0x4E,0xEA,0xA4,0xEB,0x5F,0x12,0x02,0x87,0xA5, +0xEB,0x64,0x02,0x00,0x00,0x5E,0xEB,0x5F,0x92,0x01,0x12,0x02,0x87,0xA6,0xEB,0x64, +0x02,0x00,0x00,0x64,0xEB,0x5F,0x92,0x01,0x12,0x02,0x87,0xA7,0xEA,0x40,0xEB,0x5F, +0x12,0x02,0x87,0xA8,0xB8,0x19,0xEB,0x5F,0x96,0x01,0x12,0x02,0x87,0xA9,0x3C,0x03, +0xFF,0x1A,0xEB,0x5F,0x12,0x02,0x87,0xAA,0xEA,0xE3,0xEB,0x5F,0x12,0x02,0x87,0xAB, +0xEA,0xC9,0xEB,0x5F,0x12,0x02,0x87,0xAC,0x3C,0x03,0xFE,0xFE,0xEB,0x5F,0x12,0x02, +0x87,0xB0,0x2E,0x07,0xFD,0x43,0xEB,0x5F,0x12,0x02,0x87,0xB1,0xEB,0x61,0x12,0x20, +0x07,0xB2,0xEB,0x51,0x00,0x00,0x02,0xC1,0xEB,0x72,0x12,0x01,0x07,0xB3,0x2E,0x27, +0xFD,0x29,0xEA,0xE6,0xEB,0x01,0xEB,0x72,0x12,0x01,0x07,0xB4,0x2E,0x27,0xFD,0x6C, +0xEB,0x61,0x02,0x00,0x07,0xB5,0xEB,0x01,0xEB,0x72,0x96,0x01,0x12,0x01,0x07,0xB5, +0x2E,0x27,0xFD,0x6E,0xEA,0x2B,0xFE,0x1C,0x42,0x01,0x10,0x73,0xEB,0x72,0x96,0x01, +0x12,0x01,0x07,0xB6,0x3C,0x03,0xFF,0x38,0xEB,0x72,0x12,0x01,0x07,0xB7,0x3C,0x03, +0xFF,0x36,0xEB,0x72,0x12,0x01,0x07,0xB8,0xBA,0x10,0x2E,0x07,0xFD,0x22,0xEB,0x01, +0xEB,0x72,0x96,0x01,0x12,0x01,0x07,0xB9,0xEB,0x61,0x02,0x20,0x07,0xBA,0x2E,0x47, +0xFD,0x68,0x2E,0x07,0xFD,0x55,0xFE,0x0C,0x42,0x02,0x0C,0x73,0x88,0x02,0x96,0x01, +0xEB,0x72,0x12,0x01,0x07,0xBA,0xEB,0x72,0x3C,0x03,0xFE,0xFC,0x12,0x01,0x07,0xBE, +0x3C,0x03,0xFE,0xC3,0x12,0x01,0x07,0xBE,0x2E,0x27,0xFF,0xA4,0x42,0x01,0x18,0x0B, +0xC0,0x0B,0x2E,0x38,0x02,0xD4,0x2E,0x08,0x02,0xD5,0x42,0x01,0x84,0x73,0xEB,0x84, +0x96,0x01,0x12,0x00,0x87,0xBF,0xEB,0x4E,0x02,0x00,0x02,0xD5,0xEB,0x84,0x96,0x92, +0x12,0x00,0x81,0xD8,0x4E,0x25,0x00,0x17,0x2E,0x00,0x00,0x65,0x92,0x07,0x4E,0x02, +0x00,0x76,0xEB,0x4A,0xEA,0xD1,0xEB,0x57,0x58,0x21,0x00,0x00,0xFE,0x44,0xEB,0x4D, +0x8C,0x22,0x40,0x11,0x04,0x20,0xEB,0x72,0x58,0x21,0x0F,0x44,0xDD,0x48,0x48,0x00, +0x00,0x66,0x84,0x0E,0xDD,0x40,0xC8,0xE9,0xFA,0x02,0xDD,0x40,0xC8,0xE6,0xFA,0x06, +0xDD,0x40,0xC8,0xE3,0x84,0x0A,0xDD,0x40,0xC8,0xE0,0xFA,0x0A,0xDD,0x40,0xC8,0xDD, +0xFA,0x13,0xDD,0x40,0xC8,0xDA,0xFA,0x0E,0xDD,0x40,0xC8,0xD7,0xFA,0x18,0xDD,0x40, +0xC8,0xD4,0xFA,0x1C,0xDD,0x40,0xC8,0xD1,0xDD,0x47,0xDD,0x40,0xC8,0xCE,0xB8,0x12, +0x5A,0x08,0x01,0xCC,0x2E,0x60,0x00,0x10,0xB8,0x00,0x46,0x41,0x00,0x00,0x58,0x42, +0x00,0x00,0x5A,0x08,0x08,0x0C,0x2E,0x30,0x00,0x11,0x42,0x21,0x98,0x24,0x9C,0x52, +0x8A,0x46,0x40,0x12,0x04,0x20,0x8C,0x42,0xD5,0x09,0x2E,0x00,0x00,0x65,0x96,0x37, +0xFE,0x34,0x8C,0x02,0x40,0x12,0x00,0x20,0x98,0x86,0x40,0x62,0x08,0x20,0xEB,0x4D, +0xEB,0x72,0x58,0x21,0x0F,0x44,0xDD,0x48,0x46,0x97,0xFF,0xFF,0x80,0x26,0xEB,0x4D, +0xEB,0x72,0x58,0x21,0x03,0xB0,0xDD,0x48,0x84,0xC0,0x50,0x94,0x8F,0xFF,0x46,0xA1, +0x00,0x00,0x58,0xA5,0x00,0x04,0xEA,0xB0,0xE2,0xC0,0x4E,0xF2,0xFF,0x97,0xEA,0x3C, +0x40,0x70,0x24,0x00,0x42,0x73,0x00,0x73,0x80,0x06,0x40,0x75,0x1C,0x20,0x49,0x00, +0x23,0xF1,0x8C,0xC1,0xAC,0x38,0x97,0xB0,0xD5,0xEF,0xFC,0xC0,0xFC,0x60,0x84,0x07, +0x46,0x11,0x00,0x07,0x10,0x00,0x8B,0x0E,0x46,0x11,0x00,0x07,0x10,0x00,0x8B,0x22, +0x46,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x5A,0x00,0xA5,0x04,0x48,0x00,0x01,0x87, +0xEB,0x61,0x04,0x50,0x03,0xC0,0xEB,0x04,0x97,0x69,0x4C,0x50,0x00,0xDA,0xEB,0x7E, +0x00,0x00,0x08,0x3B,0xEB,0x5D,0x10,0x00,0x8B,0x8B,0xEB,0x7E,0x00,0x00,0x08,0x3C, +0xEB,0x5D,0x10,0x00,0x8B,0x8C,0xEB,0x7E,0x00,0x00,0x08,0x3D,0xEB,0x5D,0x10,0x00, +0x8B,0x8D,0xEB,0x7E,0x00,0x00,0x08,0x3E,0xEB,0x5D,0x10,0x00,0x8B,0x8E,0xEB,0x7E, +0x00,0x00,0x08,0x3F,0xEB,0x5D,0x10,0x00,0x8B,0x8F,0xEB,0x7E,0x02,0x00,0x04,0x0F, +0xEB,0x5D,0x12,0x00,0x85,0xB7,0xEB,0x7E,0x02,0x00,0x04,0x10,0xEB,0x5D,0x12,0x00, +0x85,0xB8,0xEB,0x7E,0x02,0x00,0x04,0x11,0xEB,0x5D,0x12,0x00,0x85,0xB9,0xEB,0x7E, +0x04,0x00,0x01,0xF8,0xEB,0x5D,0x14,0x00,0x82,0xCC,0xEB,0x7E,0x02,0x00,0x04,0x0D, +0xEB,0x5D,0x12,0x00,0x85,0xB5,0xEB,0x7E,0x02,0x00,0x04,0x0E,0xEB,0x5D,0x12,0x00, +0x85,0xB6,0xEB,0x7E,0x00,0x00,0x09,0xE7,0xEB,0x5D,0x10,0x00,0x8D,0x37,0xEB,0x7E, +0x00,0x00,0x09,0xE8,0xEB,0x5D,0x10,0x00,0x8D,0x38,0xEB,0x7E,0x00,0x00,0x09,0xE9, +0xEB,0x5D,0x10,0x00,0x8D,0x39,0xEB,0x7E,0x00,0x00,0x09,0xEA,0xEB,0x5D,0x10,0x00, +0x8D,0x3A,0xEB,0x7E,0x00,0x00,0x09,0xEB,0xEB,0x5D,0x10,0x00,0x8D,0x3B,0xEB,0x7E, +0x02,0x00,0x04,0xE5,0xEB,0x5D,0x12,0x00,0x86,0x8D,0xEB,0x7E,0x02,0x00,0x04,0xE6, +0xEB,0x5D,0x12,0x00,0x86,0x8E,0xEB,0x7E,0x02,0x00,0x04,0xE7,0xEB,0x5D,0x12,0x00, +0x86,0x8F,0xEB,0x7E,0x04,0x00,0x02,0x63,0xEB,0x5D,0x14,0x00,0x83,0x37,0xEB,0x7E, +0x02,0x00,0x04,0xE3,0xEB,0x5D,0x12,0x00,0x86,0x8B,0xEB,0x7E,0x02,0x00,0x04,0xE4, +0xEB,0x5D,0x12,0x00,0x86,0x8C,0x44,0x20,0xC0,0x00,0x44,0x00,0x00,0x80,0x46,0x11, +0x00,0x07,0x58,0x10,0x80,0x00,0xDD,0x48,0x44,0x00,0x01,0x80,0x46,0x11,0x00,0x07, +0x58,0x10,0x80,0x86,0x44,0x20,0xC1,0x00,0xDD,0x48,0xFA,0x1A,0x46,0x11,0x00,0x07, +0x58,0x10,0x82,0x66,0x44,0x20,0xC2,0xE0,0xDD,0x48,0x44,0x00,0x00,0x38,0x46,0x11, +0x00,0x07,0x58,0x10,0x83,0x48,0x44,0x20,0xCA,0x48,0xDD,0x48,0xDD,0x47,0x46,0x11, +0x00,0x07,0x58,0x10,0x83,0x80,0x44,0x20,0xCA,0x80,0xDD,0x48,0xFA,0x08,0x46,0x11, +0x00,0x07,0x58,0x10,0x82,0x06,0x44,0x20,0xC2,0x80,0xDD,0x48,0xFA,0x08,0x46,0x11, +0x00,0x07,0x58,0x10,0x82,0x36,0x44,0x20,0xC2,0xB0,0xDD,0x48,0xFA,0x08,0x46,0x11, +0x00,0x07,0x58,0x10,0x82,0x1E,0x44,0x20,0xC2,0x98,0xDD,0x48,0xFA,0x08,0x46,0x11, +0x00,0x07,0x58,0x10,0x82,0x4E,0x44,0x20,0xC2,0xC8,0xDD,0x48,0x46,0x00,0x00,0x0C, +0x04,0x00,0x00,0xCF,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xA5,0xD5,0x04,0xEB,0x61, +0x04,0x00,0x00,0xA5,0x3C,0x0F,0xFF,0x88,0x84,0x08,0x46,0x11,0x00,0x07,0x10,0x00, +0x80,0x02,0x84,0x04,0x46,0x11,0x00,0x07,0x10,0x00,0x80,0x03,0x46,0x21,0x00,0x07, +0x58,0x21,0x00,0x86,0x44,0x00,0x01,0x80,0xEA,0x4C,0xDD,0x48,0x2E,0x00,0x00,0x11, +0x3E,0x00,0x01,0x29,0x2E,0x10,0x00,0x10,0x88,0x01,0x3E,0x10,0x01,0x28,0x2E,0x20, +0x00,0x12,0x84,0xA0,0x3E,0x00,0x01,0x31,0x45,0x00,0xE0,0x00,0xEB,0x61,0x3E,0x20, +0x01,0x2B,0x14,0x50,0x00,0xB1,0x80,0x45,0x44,0x90,0xFF,0xFF,0x81,0x50,0x44,0xB0, +0x00,0x48,0x46,0xC1,0x00,0x07,0x58,0xC6,0x05,0x00,0x44,0x40,0x00,0x6C,0x86,0x23, +0x45,0x20,0x00,0xD8,0x44,0xDF,0xFF,0x94,0x45,0x30,0x05,0x10,0x38,0x08,0x14,0x01, +0x4C,0x04,0x80,0x32,0x80,0xCC,0x42,0x61,0x2C,0x73,0x84,0x60,0x40,0xE5,0x14,0x00, +0x38,0x17,0x0D,0x01,0x95,0xD9,0x9E,0x09,0x41,0x40,0x12,0x96,0x40,0x8A,0x46,0x96, +0x5C,0xF0,0x81,0x45,0x40,0x8A,0x00,0x13,0xE8,0x05,0x42,0x04,0x34,0x73,0x96,0x01, +0xD5,0x11,0x52,0x00,0x82,0x88,0x40,0x10,0x10,0x16,0x50,0x00,0x00,0x6C,0x96,0x01, +0x4E,0x83,0x00,0x07,0x50,0x1A,0x00,0x02,0x42,0x00,0xC8,0x73,0xD5,0x05,0x5A,0x80, +0x02,0x04,0x42,0x04,0x48,0x73,0x8C,0x61,0x38,0x03,0x1C,0x09,0x5A,0x38,0x24,0xDA, +0x8C,0x41,0x96,0x91,0x50,0x52,0x80,0x48,0x4C,0x59,0xFF,0xCA,0x46,0x00,0x00,0x0C, +0x04,0x00,0x02,0xC3,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF7,0x46,0x00,0x00,0x0C, +0x02,0x00,0x05,0x85,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xED,0x46,0x00,0x00,0x0C, +0x02,0x00,0x05,0x84,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xEC,0x46,0x00,0x00,0x0C, +0x04,0x00,0x02,0xC1,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF5,0x46,0x00,0x00,0x0C, +0x46,0x11,0x00,0x07,0x04,0x00,0x02,0xC0,0x14,0x00,0x83,0xF4,0xEA,0x9B,0x44,0x00, +0x72,0xC0,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB0,0xFC,0xE0,0xFC,0x21,0x46,0x69, +0x00,0x08,0x44,0x70,0x35,0xCA,0x12,0x73,0x00,0x08,0xEA,0x4A,0xC8,0x20,0x12,0x73, +0x00,0x08,0x46,0x10,0x00,0x0C,0x00,0x10,0x81,0x03,0xEA,0x5B,0xC1,0x13,0xF0,0x81, +0x49,0xFF,0xFC,0xAB,0x46,0x00,0x00,0x0C,0x00,0x10,0x01,0x06,0xF0,0x01,0xC9,0x04, +0x44,0x00,0xE8,0x00,0xD5,0x05,0x5A,0x18,0x02,0x06,0x44,0x00,0xEC,0x00,0x49,0x00, +0x3B,0x57,0xEA,0xE9,0x12,0x13,0x00,0x08,0x96,0x00,0xD5,0x03,0x44,0x00,0x00,0xF0, +0xFC,0xA1,0xFC,0x00,0x46,0x09,0x00,0x08,0xEA,0xE9,0x12,0x10,0x00,0x08,0xEA,0xB9, +0x02,0x01,0x00,0x72,0x42,0x30,0x0C,0x0B,0xCB,0x34,0x02,0x11,0x00,0x72,0x42,0x00, +0x90,0x0B,0xC8,0x31,0x02,0x11,0x00,0x72,0xEA,0xD7,0xC9,0x2E,0x2E,0x17,0xFF,0xA3, +0x42,0x00,0x88,0x0B,0xC8,0x03,0xEB,0x2B,0xD5,0x06,0x49,0x00,0x3B,0xF8,0x44,0x00, +0x00,0xF1,0xD5,0x22,0xB4,0x02,0x96,0x16,0xC0,0xFE,0x46,0x09,0x00,0x08,0x44,0x20, +0x35,0xCA,0x12,0x20,0x00,0x08,0x42,0x20,0x8C,0x0B,0x80,0x20,0xCA,0x04,0xEA,0xB9, +0xEB,0x2B,0xD5,0x06,0x49,0x00,0x3B,0xEC,0x44,0x00,0x00,0xF2,0xD5,0x0D,0xB4,0x02, +0x92,0x0C,0x96,0x0F,0x5A,0x08,0x03,0xFD,0x44,0x00,0x35,0xCA,0x12,0x00,0x80,0x08, +0x84,0x00,0xD5,0x02,0x80,0x03,0xFC,0x80,0xFC,0x00,0x5C,0xF0,0x00,0x31,0x4E,0xF2, +0x01,0x56,0x3E,0xFF,0x5C,0xB8,0x38,0x07,0x81,0x01,0x40,0xF0,0x3C,0x00,0xDD,0x0F, +0x62,0x00,0x68,0x00,0x72,0x00,0x7C,0x00,0x86,0x00,0x90,0x00,0x9A,0x00,0xAC,0x00, +0xB6,0x00,0xC0,0x00,0xCA,0x00,0xDC,0x00,0xE6,0x00,0xF0,0x00,0xFA,0x00,0x06,0x01, +0x10,0x01,0x1A,0x01,0x26,0x01,0x32,0x01,0x3C,0x01,0x46,0x01,0x50,0x01,0x5E,0x01, +0x68,0x01,0x72,0x01,0x7C,0x01,0x92,0x01,0x9C,0x01,0xA6,0x01,0xB0,0x01,0xC8,0x01, +0x9A,0x02,0xD4,0x01,0xDE,0x01,0xE8,0x01,0xFE,0x01,0x9A,0x02,0x08,0x02,0x12,0x02, +0x1C,0x02,0x32,0x02,0x3C,0x02,0x46,0x02,0x50,0x02,0x5E,0x02,0x68,0x02,0x72,0x02, +0x80,0x02,0xEB,0x61,0xDD,0x5E,0xF8,0x5E,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x76,0xF7, +0xF8,0x59,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x66,0x67,0xF8,0xAB,0xEB,0x61,0xDD,0x5E, +0x50,0x00,0x7E,0xFF,0xF8,0x4F,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x7E,0x6F,0xF8,0x4A, +0xEB,0x61,0xDD,0x44,0x44,0x0F,0x6E,0x6F,0xF8,0x9C,0x84,0x04,0xDD,0x40,0x80,0xC0, +0xC0,0x04,0x85,0xE1,0x48,0x00,0x00,0xFC,0x84,0x05,0xF8,0x8D,0xEB,0x61,0xDD,0x5E, +0x50,0x00,0x5D,0xDE,0xF8,0x37,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x5B,0xDC,0xF8,0x32, +0xEB,0x61,0xDD,0x44,0x44,0x0F,0xBB,0xBC,0xF8,0x84,0x84,0x07,0xDD,0x40,0xC8,0xEA, +0x84,0x08,0xDD,0x40,0x80,0xC0,0x84,0x09,0xCE,0xE5,0xF8,0x75,0xEB,0x61,0xDD,0x44, +0x44,0x0F,0x55,0x56,0xF8,0x76,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x53,0x54,0xF8,0x71, +0xEB,0x61,0xDD,0x44,0x44,0x0F,0x33,0x34,0xF8,0x6C,0x84,0x0C,0xDD,0x40,0x80,0xC0, +0x84,0x0D,0xCE,0xD0,0xF8,0x60,0xEB,0x61,0xDD,0x5E,0x50,0x00,0x6E,0xEF,0xF8,0x0A, +0xEB,0x61,0xDD,0x5E,0x50,0x00,0x6C,0xED,0xF8,0x05,0xEB,0x61,0xDD,0x5E,0x50,0x00, +0x4C,0xCD,0x48,0x00,0x00,0xAD,0xFA,0x00,0xDD,0x40,0x80,0xC0,0xC8,0xBB,0xFA,0x01, +0xF8,0x4A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x88,0x89,0xF8,0x4B,0xEB,0x61,0xDD,0x44, +0x44,0x0F,0x87,0x88,0xF8,0x46,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x77,0x78,0xF8,0x41, +0xFA,0x04,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0xA6,0xFA,0x05,0xF8,0x34,0xEB,0x61, +0xDD,0x44,0x44,0x0F,0xAA,0xAB,0xF8,0x35,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xA9,0xAA, +0xF8,0x30,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x99,0x9A,0xF8,0x2B,0xFA,0x07,0xDD,0x40, +0x4E,0x03,0xFF,0x91,0xFA,0x08,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x8C,0xFA,0x09, +0xF8,0x1A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAE,0xAF,0xF8,0x1B,0xEB,0x61,0xDD,0x44, +0x44,0x0F,0xAE,0x9F,0xF8,0x16,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x9E,0x9F,0xF8,0x11, +0xFA,0x0B,0xDD,0x40,0x4E,0x03,0xFF,0x77,0xFA,0x0C,0xDD,0x40,0x80,0xC0,0x4E,0x03, +0xFF,0x72,0xFA,0x0D,0x48,0x00,0x00,0x68,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAF,0xB0, +0x48,0x00,0x00,0x55,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAF,0xA0,0xD5,0x4F,0xEB,0x61, +0xDD,0x44,0x44,0x0F,0x9F,0xA0,0xD5,0x4A,0xFA,0x0F,0xDD,0x40,0x4E,0x03,0xFF,0x5B, +0xFA,0x11,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x56,0xFA,0x12,0xD5,0x4C,0xEB,0x61, +0xDD,0x44,0x44,0x0F,0xAD,0xAE,0xD5,0x3A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAD,0x9E, +0xD5,0x35,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x9D,0x9E,0xD5,0x30,0xFA,0x14,0xDD,0x40, +0x4E,0x03,0xFF,0x41,0xFA,0x16,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x3C,0xFA,0x17, +0xD5,0x32,0xEB,0x61,0xDD,0x44,0x44,0x0F,0xAC,0xAD,0xD5,0x20,0xEB,0x61,0xDD,0x44, +0x44,0x0F,0xAC,0x9D,0xD5,0x1B,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x9C,0x9D,0xD5,0x16, +0xFA,0x1A,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x26,0xFA,0x1B,0xD5,0x1C,0xEB,0x61, +0xDD,0x44,0x44,0x0F,0x44,0x45,0xD5,0x0A,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x40,0x41, +0xD5,0x05,0xEB,0x61,0xDD,0x44,0x44,0x0F,0x00,0x01,0x88,0x01,0xE6,0x01,0xD5,0x0F, +0xFA,0x1D,0xDD,0x40,0x4E,0x03,0xFF,0x0F,0xFA,0x1E,0xDD,0x40,0x80,0xC0,0x4E,0x03, +0xFF,0x0A,0xFA,0x1F,0xDD,0x40,0xE2,0xC0,0xD5,0x02,0x85,0xE0,0x80,0x0F,0xFC,0x80, +0x92,0x00,0xFC,0x00,0x84,0x00,0xDD,0x40,0xC8,0x43,0x84,0x0B,0xDD,0x40,0xC0,0x04, +0x44,0x00,0xAC,0xAC,0xD5,0x3F,0x84,0x0F,0xDD,0x40,0xC0,0x04,0x44,0x00,0x13,0x13, +0xD5,0x39,0xFA,0x03,0xDD,0x40,0xC0,0x04,0x44,0x00,0x78,0x78,0xD5,0x33,0x84,0x07, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x22,0x22,0xD5,0x2D,0xFA,0x07,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x55,0x55,0xD5,0x27,0xFA,0x0B,0xDD,0x40,0xC0,0x04,0x44,0x00,0x51,0x51, +0xD5,0x21,0xFA,0x0F,0xDD,0x40,0xC0,0x04,0x44,0x00,0x50,0x50,0xD5,0x1B,0xFA,0x14, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x52,0x52,0xD5,0x15,0xFA,0x19,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x53,0x63,0xD5,0x0F,0xFA,0x1D,0xDD,0x40,0xC0,0x04,0x44,0x00,0xBB,0xBB, +0xD5,0x09,0x84,0x03,0xDD,0x40,0xC0,0x04,0x44,0x00,0x01,0x91,0xD5,0x03,0x44,0x00, +0x09,0x09,0x46,0x11,0x00,0x07,0xEA,0x30,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xF8, +0xEB,0x81,0x58,0x00,0x06,0x04,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3E,0x07, +0xFD,0x51,0x84,0x20,0xB9,0x80,0xEB,0x6A,0x46,0x27,0x2C,0x80,0x14,0x21,0x80,0xB2, +0x3E,0x17,0xFD,0x3F,0x3E,0x07,0xFD,0x63,0xB8,0x0A,0x44,0x10,0x72,0xC8,0x40,0x50, +0x40,0x09,0xD9,0x07,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFD,0x3F,0xD5,0x09, +0x44,0x10,0x7F,0x0C,0xD9,0x06,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFD,0x63, +0xB8,0x0A,0x44,0x10,0xFF,0xFE,0x8E,0x01,0xE2,0x20,0xE8,0x03,0x84,0x01,0xB8,0x8A, +0x84,0x0E,0xDD,0x40,0xC0,0x06,0xDD,0x4D,0x96,0x37,0x3E,0x07,0xFF,0xA3,0xD5,0x1F, +0xFA,0x02,0xDD,0x40,0xC8,0xF9,0xFA,0x06,0xDD,0x40,0xC8,0xF6,0x84,0x0A,0xDD,0x40, +0xC8,0xF3,0xFA,0x0A,0xDD,0x40,0xC8,0xF0,0xFA,0x13,0xDD,0x40,0xC8,0xED,0xFA,0x0E, +0xDD,0x40,0xC8,0xEA,0xFA,0x18,0xDD,0x40,0xC8,0xE7,0xFA,0x1C,0xDD,0x40,0xC8,0xE4, +0xDD,0x47,0xDD,0x40,0xC8,0xE1,0xB8,0x0A,0x5A,0x08,0x01,0xDF,0xDD,0x47,0xDD,0x40, +0xC0,0x0B,0xEB,0x64,0xDD,0x5D,0x84,0x20,0xDD,0x4F,0xEB,0x1F,0xEB,0x54,0xEA,0x72, +0x84,0x3F,0xDD,0x4F,0xEB,0x1F,0xFC,0x80,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC3, +0xEA,0x40,0x2E,0x10,0x00,0x0E,0xE2,0x01,0x56,0x07,0x80,0x01,0xEA,0xAA,0xEA,0x40, +0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xA5,0xDD,0x9E,0xFC,0x00,0x84,0x0E,0xDD,0x40, +0xC0,0x07,0x84,0x0C,0xDD,0x40,0xC0,0x0B,0x44,0x00,0xCC,0xCC,0xD5,0x13,0xFA,0x02, +0xDD,0x40,0xC8,0xF8,0xFA,0x06,0xDD,0x40,0xC8,0xF5,0xD5,0x12,0xFA,0x00,0xDD,0x40, +0xC0,0x04,0x44,0x00,0x33,0x33,0xD5,0x06,0xFA,0x04,0xDD,0x40,0xC0,0x3D,0x44,0x00, +0x88,0x88,0x46,0x11,0x00,0x07,0xEA,0x30,0x84,0x01,0xDD,0x55,0xD5,0x35,0x84,0x0A, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x44,0x44,0xD5,0x2C,0xFA,0x0A,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x66,0x66,0xD5,0x26,0xFA,0x0E,0xDD,0x40,0xC0,0x04,0x44,0x00,0x61,0x61, +0xD5,0x20,0xFA,0x13,0xDD,0x40,0xC0,0x04,0x44,0x00,0x60,0x60,0xD5,0x1A,0xFA,0x18, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x62,0x62,0xD5,0x14,0xFA,0x1C,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x63,0x63,0xD5,0x0E,0xDD,0x47,0xDD,0x40,0xC0,0x03,0xEA,0x29,0xD5,0x09, +0x84,0x06,0xDD,0x40,0xC0,0x04,0x44,0x00,0x91,0x91,0xD5,0x03,0x44,0x00,0x99,0x99, +0x46,0x11,0x00,0x07,0xEA,0x30,0xFC,0x80,0xFC,0x00,0xA6,0x00,0x80,0xC1,0x5A,0x08, +0x0A,0x0E,0x84,0x0E,0xDD,0x40,0xC8,0x07,0xFA,0x02,0xDD,0x40,0xC8,0x04,0xFA,0x06, +0xDD,0x40,0xC0,0x26,0xEB,0x54,0xEA,0x72,0xD5,0x22,0x5A,0x08,0x0B,0x04,0xDD,0x47, +0xD5,0xF8,0x5A,0x08,0x0C,0x18,0xFA,0x0A,0xDD,0x40,0xC0,0x05,0xEB,0x64,0xDD,0x5D, +0xB6,0x06,0xD5,0x0A,0xFA,0x13,0xDD,0x40,0xC8,0xFA,0xFA,0x0E,0xDD,0x40,0xC8,0xF7, +0xFA,0x18,0xDD,0x40,0xC8,0xF4,0xDD,0x47,0xDD,0x40,0xC0,0x0A,0xEB,0x64,0xDD,0x5D, +0xD5,0x06,0x5A,0x08,0x0F,0x06,0xEB,0x81,0x58,0x00,0x06,0x04,0xB6,0x06,0xFC,0x80, +0xC0,0x04,0x5A,0x00,0x01,0x1A,0xD5,0x29,0xFC,0x00,0xFA,0x13,0x80,0xC1,0xDD,0x40, +0xC0,0x07,0xEB,0x64,0xDD,0x5D,0x4C,0x60,0x40,0x04,0x84,0x01,0xD5,0x20,0xFA,0x18, +0xDD,0x40,0xC0,0x1D,0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x40,0x03,0x0C,0x03, +0x5C,0x00,0x00,0x01,0xD5,0x14,0x46,0x21,0x00,0x03,0x58,0x21,0x00,0x78,0x4C,0x11, +0x00,0x10,0x50,0x01,0x75,0xE0,0x4C,0x10,0x00,0x0C,0x50,0x21,0x70,0xD0,0x40,0x00, +0x88,0x03,0x5C,0x00,0x00,0x01,0xDD,0x9E,0x84,0x00,0xDD,0x9E,0xFC,0x80,0x84,0x01, +0xDD,0x9E,0xEA,0x4C,0x00,0x00,0x80,0x70,0x00,0x10,0x80,0x71,0x8C,0x01,0x42,0x00, +0x80,0x73,0x96,0x01,0x2E,0x37,0xFD,0x3F,0x9E,0x86,0xEB,0x5A,0x58,0x10,0x80,0x00, +0xEA,0xBD,0xEB,0x6A,0x9E,0x85,0x02,0x31,0x81,0x64,0xEA,0xBD,0x46,0x21,0x00,0x07, +0x04,0x21,0x03,0xF2,0x9E,0xC4,0x96,0x91,0x38,0x20,0x8D,0x09,0x9E,0x83,0x3C,0x33, +0xFE,0xFC,0xEA,0xBD,0x9E,0x82,0x3C,0x33,0xFF,0x10,0xEA,0xBD,0x46,0x21,0x00,0x07, +0x04,0x21,0x03,0xC1,0x9E,0xC1,0x96,0x91,0x92,0x48,0x38,0x20,0x8D,0x09,0x46,0x21, +0x00,0x07,0x04,0x21,0x03,0xC1,0x96,0x90,0x38,0x20,0x81,0x09,0xDD,0x9E,0x44,0x10, +0x22,0xB8,0x50,0x00,0x7C,0x18,0xFE,0x0C,0x44,0x11,0x86,0xA0,0xEA,0xDD,0x50,0x00, +0x00,0x56,0x96,0x01,0xDD,0x9E,0xFC,0x00,0xFA,0x02,0xDD,0x40,0xC0,0x05,0x2E,0x10, +0x00,0xD9,0xDD,0x5C,0xD5,0x0E,0xFA,0x06,0xDD,0x40,0xC0,0x0F,0x49,0x00,0x43,0xBC, +0xEA,0x2A,0x5A,0x08,0x0C,0x05,0x2E,0x00,0x00,0xDB,0xD5,0x03,0x2E,0x00,0x00,0xDA, +0xFE,0x0C,0x49,0xFF,0xFF,0xDE,0xD5,0x03,0x49,0xFF,0xF9,0x4F,0x46,0x11,0x00,0x07, +0x14,0x00,0x83,0xF2,0xFC,0x80,0xFC,0x00,0x84,0xA0,0x97,0x29,0xE2,0x81,0xE8,0x10, +0xA5,0x18,0x38,0x61,0x15,0x01,0x5A,0x08,0x01,0x06,0xE2,0x86,0x40,0x43,0x3C,0x1B, +0xD5,0x03,0x42,0x42,0x18,0x01,0x1A,0x41,0x80,0x01,0x8C,0xA1,0xD5,0xEF,0xFC,0x80, +0xFC,0x20,0x2F,0x17,0xFD,0x63,0x84,0x60,0xFB,0x94,0x2E,0x20,0x01,0x29,0xE2,0x62, +0xE8,0x22,0x42,0x71,0xC0,0x24,0x84,0x40,0x2E,0x40,0x01,0x28,0xE2,0x44,0xE8,0x18, +0x99,0x57,0x40,0x60,0x94,0x20,0x22,0x43,0x00,0x00,0x38,0x50,0x15,0x11,0x4F,0x12, +0x00,0x0A,0x43,0x32,0x00,0x03,0x42,0xF2,0x80,0x03,0xE1,0xEF,0x40,0x42,0xBC,0x1B, +0xD5,0x03,0x42,0x42,0x90,0x00,0x8C,0x41,0xAD,0x30,0x96,0x90,0xD5,0xE6,0x8C,0x61, +0x96,0xD8,0xD5,0xDC,0xFC,0xA0,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x10,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05,0xEB,0x51, +0xEA,0xFA,0xD5,0x05,0xEB,0x46,0xC8,0x06,0xEB,0x54,0xEA,0xAC,0xEB,0x5A,0xEA,0x8C, +0xEB,0x13,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x02, +0xEA,0x53,0xFC,0x80,0xFC,0x00,0x3C,0x0D,0xFF,0x88,0x3C,0x2D,0xFF,0x7E,0xE2,0x40, +0xE8,0x19,0xEB,0x61,0x04,0x00,0x00,0xB2,0x96,0x81,0xE2,0x41,0xE8,0x13,0x96,0x49, +0x92,0x10,0xEB,0x49,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB2,0xEB,0x46,0x5A,0x08, +0x01,0x0A,0xEA,0xB2,0xEB,0x5A,0xEA,0x8C,0x46,0x21,0x00,0x03,0x58,0x21,0x0A,0x98, +0xDD,0x48,0xFC,0x80,0x46,0x38,0x00,0x30,0x4E,0x00,0x42,0xE9,0xCA,0xFE,0x4E,0x00, +0x42,0xEC,0xDD,0x9E,0xFC,0x63,0x3F,0xCF,0xFD,0xD4,0x81,0x20,0xB1,0x81,0x3E,0x0F, +0xFB,0x28,0x3B,0x00,0x4C,0x04,0x80,0xE1,0x80,0x26,0x3B,0x00,0xCC,0x24,0xA4,0x00, +0xAC,0x08,0x2E,0x80,0x00,0xD5,0x81,0x42,0x40,0x04,0x00,0x10,0x85,0x81,0x4E,0x04, +0x00,0x04,0x44,0xC0,0xFF,0xFF,0xEA,0x28,0x02,0x00,0x80,0x9C,0x02,0x30,0x80,0x0A, +0x40,0xB0,0x0C,0x01,0x84,0x0E,0xDD,0x40,0x40,0xB5,0xA4,0x08,0x84,0x60,0xC8,0x09, +0x54,0x44,0x00,0x7F,0x44,0x50,0x00,0x64,0xFF,0x2C,0x42,0x46,0x10,0x24,0x96,0xE3, +0x88,0x6B,0xBB,0x80,0x3C,0x0D,0xFF,0x75,0xFE,0x02,0xB8,0x84,0x84,0x04,0x49,0xFF, +0xFF,0xC3,0xB9,0x04,0xEB,0x57,0xEA,0x67,0x80,0x09,0x49,0x00,0x42,0xBF,0x84,0x06, +0x42,0x64,0x80,0x73,0x40,0x25,0x00,0x13,0x84,0x00,0x46,0x41,0x00,0x00,0x58,0x42, +0x0B,0x14,0x44,0x30,0x01,0xB0,0x38,0x13,0x00,0x00,0x81,0x27,0x42,0x90,0x8C,0x73, +0x38,0x52,0x09,0x01,0x38,0x54,0x89,0x09,0x99,0x70,0xA7,0x69,0x81,0x27,0x50,0x11, +0x00,0x6C,0x42,0x92,0x8C,0x73,0x39,0x02,0x05,0x01,0x50,0x21,0x00,0x24,0x8C,0x02, +0x39,0x04,0x85,0x09,0x96,0x91,0x5A,0x08,0x06,0xE8,0xFC,0xE3,0x46,0x10,0x00,0xE0, +0xDD,0x43,0x8C,0x27,0xEA,0xCB,0x46,0x10,0x01,0xC0,0x8C,0x35,0x14,0x10,0x01,0x60, +0x46,0x10,0x02,0xA0,0x50,0x10,0x80,0x23,0x14,0x10,0x01,0x61,0x84,0x20,0x14,0x10, +0x01,0x62,0x14,0x10,0x01,0x63,0x14,0x10,0x01,0x64,0x14,0x10,0x01,0x65,0x14,0x10, +0x01,0x66,0x14,0x10,0x01,0x67,0x14,0x10,0x01,0x68,0xDD,0x9E,0xFC,0x60,0xEE,0xE0, +0x3E,0x1F,0xFB,0x3C,0x80,0xE0,0x50,0xAF,0x80,0x30,0x3E,0x0F,0xFB,0x60,0xB1,0x83, +0x3B,0x00,0xE0,0x00,0x44,0x20,0x00,0xF0,0x3B,0x03,0x60,0x20,0x84,0x20,0x3B,0x00, +0x48,0x00,0x80,0x0A,0x3B,0x0F,0xC8,0x20,0xDD,0x42,0x84,0x20,0x80,0x0A,0xA8,0x41, +0xA8,0x42,0xA8,0x43,0xA8,0x44,0xA8,0x45,0xA8,0x46,0xF1,0x8C,0xFA,0x22,0x40,0x13, +0x84,0x57,0x96,0x90,0x81,0x3F,0x94,0x91,0x86,0x67,0x44,0x00,0x00,0x55,0x46,0xE3, +0x00,0x00,0x45,0x43,0x00,0x00,0xE6,0x42,0xE8,0x0A,0x38,0x53,0x08,0x00,0x84,0x20, +0x40,0x50,0x14,0x0C,0xF8,0x12,0x82,0x21,0x82,0x41,0xD5,0x3D,0xE6,0x48,0xE8,0x07, +0xEA,0xBE,0x41,0x20,0x04,0x0C,0xF8,0x08,0x82,0x21,0xD5,0x0C,0xE6,0x4E,0xE8,0x0C, +0xEA,0xBE,0x41,0x10,0x04,0x0C,0x84,0x20,0x80,0x61,0x80,0xE1,0x82,0x01,0x83,0xFF, +0x82,0x41,0x80,0xA1,0xD5,0x28,0xE6,0x54,0xE8,0x08,0xEA,0xBE,0x41,0x00,0x04,0x0C, +0x84,0x20,0x80,0x61,0x80,0xE1,0xD5,0x14,0xE6,0x5A,0xE8,0x08,0x38,0x73,0x08,0x00, +0x84,0x20,0x40,0x70,0x1C,0x0C,0x80,0x61,0xD5,0x0A,0x5C,0xF1,0x00,0x20,0xE8,0x0A, +0x38,0x33,0x08,0x00,0x84,0x20,0x40,0x30,0x0C,0x0C,0x80,0xE1,0x82,0x01,0x82,0x21, +0xD5,0xE0,0xEA,0xBE,0x84,0x60,0x40,0x10,0x04,0x0C,0x80,0xE3,0x82,0x03,0x82,0x23, +0x82,0x43,0x80,0xA3,0x80,0x93,0x85,0x60,0x88,0xAE,0x88,0x34,0x38,0x84,0xAE,0x02, +0x50,0xC2,0x00,0x01,0xEA,0x56,0x89,0x05,0x38,0x85,0x12,0x0A,0x39,0x25,0x32,0x0A, +0x50,0xC2,0x00,0x02,0xEA,0x56,0x39,0x15,0x32,0x0A,0x50,0xC2,0x00,0x03,0xEA,0x56, +0x39,0x05,0x32,0x0A,0x50,0xC2,0x00,0x04,0xEA,0x56,0x38,0x75,0x32,0x0A,0x50,0xD2, +0x00,0x05,0x50,0xC2,0x00,0x06,0xEA,0x56,0x54,0xD6,0x80,0xFF,0x8C,0x87,0x8D,0x61, +0x38,0x35,0x36,0x0A,0x97,0x20,0x38,0x15,0x32,0x0A,0x5A,0xB8,0x03,0xD9,0x50,0x19, +0x80,0x15,0x8C,0x41,0x55,0x30,0x80,0xFF,0x96,0x91,0x5B,0x30,0x31,0x04,0x48,0xFF, +0xFF,0x84,0x84,0x00,0x46,0x32,0x00,0x00,0x40,0x15,0x00,0x00,0x5A,0x00,0xC8,0x0A, +0x98,0x83,0xB4,0x81,0xB6,0x82,0xB4,0xA2,0xB4,0x81,0xDC,0xFC,0x8C,0x04,0xD5,0xF5, +0xED,0x20,0xFC,0xE0,0xFC,0x00,0x80,0xC0,0x5A,0x08,0x01,0x0C,0xDD,0x43,0x84,0x22, +0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x59,0xC8,0x04,0xEA,0x42,0xE6,0x01,0xEA,0x66, +0x9E,0x31,0x96,0x40,0xE6,0x26,0xE8,0x18,0x84,0x43,0x40,0x10,0x08,0x16,0xE2,0x46, +0x2E,0x27,0xFD,0x51,0x96,0x00,0x40,0x27,0x88,0x20,0xEB,0x22,0xEB,0x2F,0x96,0x90, +0x49,0xFF,0xFE,0xA2,0x5A,0x68,0x06,0x16,0xEA,0x59,0x5A,0x08,0x11,0x13,0xEA,0x24, +0x96,0x00,0xDD,0x55,0xD5,0x0E,0x5A,0x68,0x08,0x0D,0xEA,0x59,0x8C,0x01,0x96,0x00, +0xE6,0x12,0xE9,0x02,0x84,0x00,0x3E,0x07,0xFD,0x51,0xEA,0x59,0x49,0xFF,0xFF,0x10, +0xFC,0x80,0xFC,0x00,0x2E,0x17,0xFD,0x24,0x2E,0x07,0xFF,0xDB,0xFE,0x0C,0x3C,0x0F, +0xFF,0x8D,0x84,0x00,0x3C,0x0F,0xFF,0x87,0x49,0x00,0x2C,0xAD,0xFC,0x80,0xFC,0x40, +0x2E,0x47,0xFF,0xA9,0x84,0x20,0xFF,0x04,0x2F,0x20,0x01,0x29,0x2F,0x30,0x01,0x28, +0x80,0x41,0x84,0x01,0x80,0xA1,0x45,0x10,0x00,0x48,0x47,0x01,0x00,0x00,0x59,0x08, +0x06,0x04,0x44,0x90,0x00,0x64,0x4C,0x59,0x00,0x19,0x80,0xF0,0x42,0x72,0xC4,0x73, +0x84,0x60,0x97,0x98,0xE2,0xD3,0xE8,0x0E,0x38,0x63,0x8D,0x11,0x42,0xF3,0x24,0x24, +0xE0,0x8F,0xE8,0x04,0x8C,0x21,0x96,0x48,0x84,0x00,0x42,0x23,0x08,0x00,0x8C,0x61, +0xD5,0xF1,0x8C,0xA1,0x97,0x68,0xD5,0xE8,0x96,0x91,0x46,0x31,0x00,0x07,0x12,0x21, +0x87,0x99,0x96,0x49,0x46,0x21,0x00,0x07,0x12,0x11,0x07,0x9A,0xFC,0xC0,0x46,0x11, +0x00,0x07,0x04,0x20,0x80,0xB2,0xEA,0x2A,0x96,0xD1,0xFE,0xCC,0x2E,0x47,0xFF,0xB6, +0x2E,0x17,0xFF,0xAF,0xFE,0x64,0xFE,0x0C,0xE2,0x03,0xE8,0x04,0x84,0x21,0x84,0x00, +0xD5,0x03,0x84,0x20,0x84,0x01,0x96,0x91,0x46,0x31,0x00,0x07,0x12,0x21,0x87,0x99, +0x96,0x49,0x46,0x21,0x00,0x07,0x12,0x11,0x07,0x9A,0xDD,0x9E,0xFC,0x42,0x44,0x00, +0x87,0x87,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xC6,0x3C,0x2D,0xFF,0x90,0x84,0x00, +0x12,0x0F,0x80,0x07,0x12,0x0F,0x80,0x03,0x12,0x0F,0x80,0x02,0x12,0x0F,0x80,0x01, +0x84,0x1F,0x12,0x0F,0x80,0x06,0x12,0x0F,0x80,0x05,0x12,0x0F,0x80,0x04,0xEB,0x61, +0x00,0x70,0x0F,0x1C,0xEB,0x61,0x00,0x60,0x0F,0x1D,0xEB,0x61,0x00,0x00,0x0F,0x20, +0x97,0xF8,0x97,0xB0,0x54,0x90,0x00,0xFF,0x84,0xA0,0x44,0x10,0x05,0x10,0x98,0x15, +0xA4,0x00,0x96,0x01,0x12,0x0F,0x80,0x07,0xEA,0x26,0x02,0x3F,0x80,0x01,0xE2,0x60, +0xEA,0x26,0xE8,0x05,0x96,0x01,0x12,0x0F,0x80,0x01,0xD5,0x1F,0x02,0x3F,0x80,0x02, +0xE2,0x60,0xE8,0x0A,0xEA,0x23,0xEA,0xD2,0x4C,0x30,0x00,0x07,0xEA,0x26,0x96,0x01, +0x12,0x0F,0x80,0x02,0xD5,0x12,0xEA,0x26,0x02,0x3F,0x80,0x03,0xE2,0x60,0xE8,0x0D, +0xEA,0x23,0xEA,0xD2,0x4C,0x30,0x00,0x0A,0xEA,0x23,0xEA,0xD3,0x4C,0x30,0x00,0x06, +0xEA,0x26,0x96,0x01,0x12,0x0F,0x80,0x03,0xEA,0x23,0xEA,0x81,0xE2,0x60,0xE8,0x06, +0xEA,0x26,0x96,0x01,0x12,0x0F,0x80,0x04,0xD5,0x1F,0xEA,0x23,0xEA,0xE5,0xE2,0x60, +0xE8,0x0A,0xEA,0x23,0xEA,0x81,0x4C,0x30,0x00,0x07,0xEA,0x26,0x96,0x01,0x12,0x0F, +0x80,0x05,0xD5,0x12,0xEA,0x23,0x02,0x0F,0x80,0x06,0xE2,0x60,0xE8,0x0D,0xEA,0x23, +0xEA,0x81,0x4C,0x30,0x00,0x0A,0xEA,0x23,0xEA,0xE5,0x4C,0x30,0x00,0x06,0xEA,0x26, +0x96,0x01,0x12,0x0F,0x80,0x06,0x8C,0xA2,0xD9,0xAB,0x84,0x20,0xFA,0x44,0xEB,0x61, +0x58,0x00,0x0F,0x24,0xDD,0x42,0x49,0xFF,0xF6,0x60,0xFF,0xC4,0xEA,0x2A,0x40,0x73, +0x84,0xF7,0x02,0x2F,0x80,0x01,0x97,0xF9,0xE2,0xE2,0xE9,0x09,0xFF,0x84,0x02,0x2F, +0x80,0x04,0x40,0x63,0x04,0xD7,0x97,0xB1,0xE2,0x46,0xE8,0x07,0xEB,0x61,0xEA,0xE2, +0x46,0x11,0x00,0x07,0xEA,0x37,0xEA,0xE1,0xEB,0x46,0xC0,0x05,0x80,0x09,0x49,0xFF, +0xFF,0x40,0xD5,0x04,0x80,0x09,0x49,0xFF,0xFF,0x04,0xC8,0x07,0xEB,0x61,0xEA,0xE2, +0x46,0x11,0x00,0x07,0xEB,0x05,0xEA,0xE1,0xEB,0x61,0xEA,0xE2,0xC8,0x06,0x44,0x0F, +0xAA,0xAA,0x46,0x11,0x00,0x07,0xEA,0xE1,0xEA,0xD2,0x46,0x11,0x00,0x07,0x96,0x01, +0x12,0x00,0x87,0x93,0xEA,0xD3,0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x94, +0x02,0x0F,0x80,0x03,0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x95,0xEA,0x81, +0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x96,0xEA,0xE5,0x46,0x11,0x00,0x07, +0x96,0x01,0x12,0x00,0x87,0x97,0x02,0x0F,0x80,0x06,0x46,0x11,0x00,0x07,0x96,0x01, +0x12,0x00,0x87,0x98,0x84,0x00,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0x9B,0x44,0x00, +0xA6,0x6A,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xC6,0xFC,0xC2,0x46,0x08,0x00,0x20, +0x04,0x10,0x00,0x0E,0x42,0x10,0xD4,0x08,0xEB,0x1A,0x4E,0x00,0x3D,0x27,0x4E,0x00, +0x3D,0x2C,0x4E,0x00,0x3D,0x28,0x44,0x10,0xFB,0xFF,0x4E,0x00,0x3D,0x26,0x4E,0x00, +0x3D,0x2C,0x46,0x11,0x00,0x07,0x02,0x10,0x80,0x40,0x84,0x45,0xE6,0x22,0x46,0x19, +0x00,0x68,0xE9,0x02,0x84,0x4F,0x10,0x20,0x89,0x04,0x02,0x10,0x00,0x1E,0x84,0x44, +0x58,0x10,0x80,0x01,0xEA,0x32,0x02,0x10,0x00,0x1E,0xEA,0xB3,0xEA,0x32,0x84,0x20, +0xEA,0x75,0xEA,0x61,0xEB,0x2D,0xEA,0xDF,0xEA,0x3E,0x10,0x20,0x80,0x28,0xF8,0x76, +0xDD,0x9E,0xFC,0x20,0x46,0x68,0x00,0x20,0x10,0x03,0x00,0x48,0x05,0x03,0x00,0x0E, +0x46,0x7F,0xFE,0x3F,0x84,0x07,0x50,0x73,0x8F,0xFF,0xFE,0x46,0x40,0x78,0x1C,0x02, +0x83,0x86,0x40,0x73,0x86,0x44,0xBF,0x8E,0xB9,0x0E,0xFE,0x86,0x66,0x10,0x80,0x38, +0x40,0x20,0x88,0x64,0xBA,0x8E,0x12,0x33,0x00,0x9C,0x12,0x43,0x00,0x8A,0x12,0x53, +0x00,0x0A,0xFC,0xA0,0xFC,0x00,0xEA,0x4C,0x00,0x50,0x81,0x2C,0x84,0x0A,0xFF,0x44, +0x00,0x10,0x81,0x39,0x80,0x65,0xDD,0x5C,0x42,0x30,0x80,0x73,0x84,0x46,0x96,0xD9, +0xFA,0x01,0x84,0x27,0x84,0x81,0xF8,0x17,0xFC,0x80,0xFC,0x00,0xEA,0x4C,0x00,0x40, +0x81,0x2D,0x84,0x0A,0xFF,0x04,0x00,0x30,0x81,0x3A,0x80,0xA4,0xDD,0x5C,0x00,0x20, +0x81,0x2F,0x42,0x51,0x80,0x73,0x00,0x00,0x81,0x2E,0x96,0xE9,0x40,0x11,0x10,0x09, +0x80,0xA4,0x96,0x9F,0x49,0xFF,0xFF,0xB7,0xFC,0x80,0xFC,0x01,0x84,0x20,0xF0,0x81, +0x46,0x09,0x00,0x68,0x10,0x10,0x09,0x04,0x84,0x0E,0xDD,0x40,0xC0,0x35,0x84,0x0E, +0xDD,0x40,0xC0,0x39,0xDD,0x43,0xEB,0x0F,0x44,0x10,0xFF,0xDF,0x4E,0x00,0x3C,0xA5, +0x44,0x10,0xFE,0xFF,0x4E,0x00,0x3C,0xA1,0x4E,0x00,0x3C,0x9D,0x44,0x10,0xFB,0xFF, +0xFE,0x56,0xEA,0x32,0x51,0xC0,0x00,0x38,0xB9,0x7F,0x2E,0x20,0x00,0xBF,0x66,0x10, +0x8F,0x00,0x96,0x9F,0x40,0x10,0x89,0x04,0xB9,0xFF,0x44,0x10,0x00,0x32,0x12,0x10, +0x00,0x9A,0x83,0xFF,0x84,0x21,0xEA,0x75,0xB4,0x5C,0x46,0x1F,0xFE,0x3F,0xEA,0x7F, +0xFE,0x56,0x42,0x10,0xC8,0x08,0xB6,0x3C,0xB4,0x3C,0x66,0x10,0x80,0x38,0x58,0x10, +0x80,0x08,0xB6,0x3C,0xD5,0x18,0xFA,0x02,0xDD,0x40,0xC8,0xCA,0xFA,0x06,0xDD,0x40, +0xC8,0xC7,0xD5,0x17,0xFA,0x02,0xDD,0x40,0xC0,0x06,0xF8,0x08,0xF0,0x01,0x49,0xFF, +0xFF,0x8B,0xD5,0x09,0xFA,0x06,0xDD,0x40,0xC0,0x06,0x49,0xFF,0xFF,0x31,0xF0,0x01, +0x49,0xFF,0xFF,0x95,0xF0,0x01,0x49,0xFF,0xFC,0xCB,0xEA,0x59,0x49,0xFF,0xFC,0xE8, +0xDD,0x47,0xDD,0x40,0xEA,0x28,0xC0,0x02,0x84,0x01,0x10,0x00,0x80,0x68,0x10,0x00, +0x80,0x6C,0xFC,0x81,0xFC,0x00,0x84,0x07,0xDD,0x40,0xC0,0x1F,0xDD,0x4B,0x5A,0x00, +0x07,0x05,0x66,0x10,0x00,0x02,0xC9,0x04,0x49,0xFF,0xFD,0xC5,0xD5,0x1C,0x2E,0x10, +0x00,0xDF,0xEA,0x5B,0xC1,0x0C,0x5A,0x00,0x06,0x0B,0xDD,0x43,0x84,0x26,0xEB,0x31, +0x84,0x20,0xEB,0x32,0x44,0x1F,0xFC,0x78,0x4E,0x00,0x40,0xA9,0x44,0x00,0x24,0x24, +0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x07,0x84,0x08,0xDD,0x40,0xC0,0x03,0xF9,0x85, +0xD5,0x02,0xF9,0x49,0xFC,0x80,0xEA,0x35,0x96,0x04,0xC0,0x09,0xFC,0x00,0x49,0x00, +0x34,0x48,0xC8,0xFE,0x49,0x00,0x34,0x2A,0xC8,0xFE,0xFC,0x80,0xDD,0x9E,0xFC,0x00, +0xFA,0x13,0xDD,0x40,0xC0,0x0F,0xEB,0x51,0x58,0x00,0x04,0x74,0x3C,0x0F,0xFF,0x90, +0x84,0x21,0x84,0x08,0xEA,0x34,0x84,0x01,0xEB,0x3C,0xEB,0x0C,0x84,0x00,0xEB,0x2E, +0xD5,0x0B,0xFA,0x18,0xDD,0x40,0xC8,0xF0,0xEB,0x64,0xEB,0x47,0x3C,0x0F,0xFF,0x90, +0x84,0x07,0x84,0x21,0xEA,0x34,0xFC,0x80,0xEA,0x35,0x96,0x04,0xC0,0x09,0xFC,0x00, +0x49,0x00,0x34,0x0D,0xC8,0xFE,0x49,0x00,0x34,0x13,0xC8,0xFE,0xFC,0x80,0xDD,0x9E, +0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x58,0x00,0x00,0x10,0xAE,0x0B,0x4E,0x00,0x04,0xC0, +0x46,0x11,0x00,0x07,0xEA,0x70,0xF8,0xBF,0xFC,0x80,0xFC,0x00,0x80,0xC0,0xFA,0x08, +0xDD,0x40,0xC0,0x0D,0xEA,0x35,0xEA,0x8A,0xC0,0x0A,0x40,0x03,0x10,0x09,0xEA,0x28, +0x12,0x00,0x82,0xB8,0x50,0x00,0x00,0x64,0x12,0x00,0x80,0xB6,0xFA,0x11,0xDD,0x40, +0xC0,0x0C,0xEA,0x35,0xEA,0x8A,0xC0,0x09,0x92,0xC1,0xDD,0x43,0x12,0x60,0x02,0xB8, +0x50,0x63,0x00,0x64,0x12,0x60,0x00,0xB6,0xFC,0x80,0xFC,0x00,0xEB,0x7B,0x58,0x10, +0x86,0x58,0xEA,0xB2,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0xD8,0xFA,0x07,0xDD,0x40,0xC0,0x05,0xEA,0x50,0x44,0x00,0x56,0x56,0xD5,0x21, +0xFA,0x08,0xDD,0x40,0xC0,0x18,0xB8,0x00,0x5A,0x08,0x07,0x30,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x08,0x49,0xFF,0xFF,0xE3,0xEB,0x54,0xEA,0xAC,0xEB,0x5A,0xEA,0x8C, +0xEB,0x13,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x1D, +0xEB,0x39,0xD5,0x11,0xFA,0x0B,0xDD,0x40,0xC0,0x08,0xEA,0x50,0x44,0x00,0x51,0x61, +0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x11,0xFA,0x0C,0xDD,0x40,0xC0,0x06,0xB8,0x00, +0x5A,0x08,0x07,0x0C,0xEA,0x53,0xD5,0x09,0xFA,0x0D,0xDD,0x40,0xC0,0xFC,0xB8,0x00, +0x5A,0x08,0x07,0x04,0x49,0xFF,0xFF,0xBB,0xFC,0x80,0xFC,0x00,0xEB,0x7B,0x58,0x10, +0x86,0x58,0xEA,0x5A,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0xD8,0xFA,0x0F,0xDD,0x40,0xC0,0x05,0xEA,0x50,0x44,0x00,0x50,0x60,0xD5,0x24, +0xFA,0x11,0xDD,0x40,0xC0,0x1B,0xB8,0x00,0x5A,0x08,0x08,0x33,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x0A,0x49,0xFF,0xFF,0xE3,0x49,0x00,0x2A,0x54,0xEB,0x51,0xEA,0xFA, +0xEB,0x5A,0xEA,0x8C,0xEB,0x13,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x03,0x8C,0x01, +0xB8,0x88,0xBD,0x08,0xD9,0x1D,0xEB,0x39,0xD5,0x11,0xFA,0x14,0xDD,0x40,0xC0,0x08, +0xEA,0x50,0x44,0x00,0x52,0x62,0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x11,0xFA,0x16, +0xDD,0x40,0xC0,0x06,0xB8,0x00,0x5A,0x08,0x08,0x0C,0xEA,0x53,0xD5,0x09,0xFA,0x17, +0xDD,0x40,0xC0,0xFC,0xB8,0x00,0x5A,0x08,0x08,0x04,0x49,0xFF,0xFF,0xB8,0xFC,0x80, +0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x66,0x00,0x00,0x10,0xAE,0x0B,0x84,0x00,0x46,0x11, +0x00,0x07,0xEA,0x70,0x49,0xFF,0xFF,0x01,0xF8,0x46,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0xD8,0xFA,0x1D,0xDD,0x40,0xC0,0x0B,0xEA,0x35,0x96,0x04,0xC0,0x02,0xEA,0x50, +0x44,0x00,0xBF,0xBF,0x46,0x11,0x00,0x07,0xEA,0x30,0xD5,0x30,0xFA,0x1E,0xDD,0x40, +0xC0,0x2C,0xEA,0x35,0x96,0x04,0xC0,0x04,0xB8,0x00,0x5A,0x08,0x07,0x28,0xB8,0x12, +0xB9,0x08,0xE2,0x20,0xE8,0x17,0x84,0x01,0x44,0x10,0x02,0x88,0xEB,0x57,0xEA,0x67, +0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x49,0xFF,0xFA,0x7F,0x84,0x00,0x44,0x10, +0x02,0x88,0xEB,0x57,0xEA,0x67,0x46,0x31,0x00,0x03,0x58,0x31,0x80,0x78,0x49,0xFF, +0xFA,0x74,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x06, +0xEA,0x35,0x96,0x04,0xC0,0x02,0xEB,0x39,0xEA,0x53,0xFC,0x80,0xFC,0x00,0x84,0x0E, +0xDD,0x40,0xC0,0x03,0xEA,0x53,0xF8,0x0C,0xFA,0x02,0xDD,0x40,0xC8,0xFC,0xFA,0x06, +0xDD,0x40,0xC8,0xF9,0x84,0x0A,0xDD,0x40,0xC0,0x05,0x49,0xFF,0xFE,0x85,0x48,0x00, +0x00,0x3A,0xFA,0x0A,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x12,0xD5,0x33,0xFA,0x0E, +0xDD,0x40,0xC8,0xFB,0xFA,0x13,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x51,0xD5,0x2A, +0xFA,0x18,0xDD,0x40,0xC8,0xFB,0xFA,0x1C,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x8A, +0xD5,0x21,0xDD,0x47,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x92,0xD5,0x1B,0x84,0x06, +0xDD,0x40,0xC0,0x0B,0xEA,0x6A,0x66,0x00,0x00,0x08,0x3E,0x07,0xFF,0xA2,0x84,0x00, +0xEB,0x3C,0x84,0x00,0x3C,0x0F,0xFF,0x8D,0x49,0xFF,0xFA,0x67,0xEB,0x61,0x04,0x50, +0x03,0xC6,0x44,0x00,0x6A,0xA6,0xD8,0x06,0x84,0x02,0xDD,0x40,0xC0,0x03,0x49,0xFF, +0xFC,0x7F,0xFC,0x80,0xFC,0x00,0xDD,0x4D,0x96,0x04,0xC0,0x16,0xEA,0x33,0xC0,0x07, +0x2E,0x07,0xFE,0x79,0x2E,0x17,0xFF,0xF1,0xE2,0x01,0xE9,0x05,0x84,0x00,0x3E,0x07, +0xFE,0x79,0xD5,0x0C,0x8C,0x01,0x3E,0x07,0xFE,0x79,0x2E,0x07,0xFE,0x78,0x8C,0x01, +0x3E,0x07,0xFE,0x78,0xD5,0x03,0x84,0x02,0xEA,0x6D,0xFC,0x80,0xFC,0x40,0xEA,0x2C, +0x84,0x24,0x9D,0x82,0x8E,0x01,0xEA,0xDD,0x46,0x90,0x0F,0xFF,0x88,0xC0,0x97,0xB0, +0x84,0xE0,0x50,0x94,0x8F,0xFF,0xC6,0x12,0x5A,0x68,0x01,0x09,0x52,0x73,0xFE,0x03, +0x97,0xF9,0x40,0x04,0x9F,0x04,0xDD,0x4A,0xD5,0x06,0x84,0x1F,0x50,0x73,0x83,0xFC, +0xDD,0x4A,0x97,0xF9,0x8E,0xC1,0x97,0xB0,0xD5,0xEF,0x3E,0x67,0xFD,0x1A,0xFC,0xC0, +0xFC,0x60,0x80,0xC0,0x3C,0xCD,0xFF,0x93,0x2E,0x87,0xFD,0x28,0x3C,0x9D,0xFF,0x82, +0xEA,0x45,0xEA,0xEB,0x3C,0x0D,0xFF,0x8A,0xC0,0x04,0x00,0x73,0x00,0x92,0xC7,0x03, +0x2E,0x77,0xFD,0x68,0x85,0x60,0x81,0xA6,0x81,0xCB,0xEA,0x2C,0x40,0xF7,0x00,0x06, +0xE8,0x34,0x2E,0x00,0x00,0x14,0xEA,0xA3,0xC0,0x0B,0x04,0x16,0x80,0x01,0x96,0x09, +0xEA,0xB1,0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0xB4,0x2D,0xD5,0x0A,0xB4,0x2D, +0x96,0x09,0xEA,0xB1,0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0x04,0x16,0x80,0x01, +0x96,0x09,0xEA,0xB1,0x96,0x01,0x96,0x49,0x40,0x10,0x05,0x15,0x40,0x01,0x06,0x00, +0xDD,0x4A,0xB4,0x2D,0x04,0x26,0x80,0x01,0x96,0x08,0x40,0x10,0x05,0x1C,0x89,0x61, +0x40,0xB5,0x89,0x1C,0x96,0x90,0x40,0x05,0x88,0x00,0x40,0xB0,0x00,0x13,0x50,0xE7, +0x00,0x01,0x50,0xD6,0x80,0x0C,0xD5,0xCA,0x00,0x03,0x00,0x20,0x00,0x23,0x00,0x14, +0x00,0x13,0x00,0x08,0xEA,0xE8,0x40,0x00,0x09,0x00,0x88,0x01,0x00,0x13,0x00,0x2C, +0xEA,0x87,0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x2C,0xE6,0x05,0xE9,0x11,0x00,0x03, +0x00,0x50,0x00,0x23,0x00,0x44,0x00,0x13,0x00,0x38,0xEA,0xE8,0x40,0x00,0x09,0x00, +0x88,0x01,0x00,0x13,0x00,0x5C,0xEA,0x87,0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x2C, +0xE6,0x09,0xE9,0x0A,0x00,0x13,0x00,0x74,0x00,0x03,0x00,0x68,0x40,0x00,0x05,0x00, +0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0xDB,0x84,0x20,0x84,0x6C,0xE2,0x22,0xE8,0x0B, +0x80,0x06,0x42,0x00,0x8C,0x73,0x8C,0x21,0x00,0x00,0x00,0x08,0x88,0x0B,0x40,0xB0, +0x00,0x13,0xD5,0xF5,0xEA,0x69,0xEA,0x8A,0xC0,0x15,0xEA,0xFD,0xEA,0x2B,0xE3,0x0C, +0x94,0x05,0x40,0xA0,0x28,0x64,0x40,0xA5,0x04,0x24,0x8F,0x23,0x40,0x85,0x3C,0x04, +0xE7,0x21,0x40,0xF4,0x3C,0x44,0x40,0x77,0x9C,0x84,0x12,0x73,0x00,0x48,0x3E,0x17, +0xFD,0x5E,0x02,0x23,0x00,0x48,0x00,0x13,0x00,0x92,0x40,0x31,0x20,0x09,0x96,0x10, +0x96,0x90,0x88,0x43,0x58,0x10,0x80,0xF0,0x40,0x00,0x81,0x00,0x88,0x22,0x40,0x00, +0x0E,0x00,0x89,0x61,0x40,0x00,0x2F,0x01,0xDD,0x4A,0xFC,0xE0,0xFC,0x00,0xEA,0x51, +0x5A,0x08,0x01,0x04,0x49,0x00,0x2C,0x21,0x49,0x00,0x2C,0x1A,0x80,0xC0,0xEA,0x51, +0xC0,0x07,0xEA,0x51,0x5A,0x08,0x01,0x0A,0xEA,0x52,0x5A,0x08,0x01,0x07,0x3C,0x03, +0xFE,0xC3,0x8C,0x01,0x3C,0x0B,0xFE,0xC3,0xEA,0x84,0xC8,0x1B,0xEA,0x51,0xC0,0x07, +0xEA,0x51,0x5A,0x08,0x01,0x17,0xEA,0x52,0x5A,0x08,0x01,0x14,0x84,0x01,0x3E,0x07, +0xFD,0x07,0x49,0xFF,0xFE,0xE9,0xEA,0x33,0xC8,0x0C,0xEA,0xEE,0xC0,0x05,0x80,0x06, +0x49,0xFF,0xFF,0x20,0xD5,0x05,0x2E,0x07,0xFE,0x7A,0xC0,0x03,0xEA,0xB7,0xEA,0xC4, +0xEA,0xEE,0x3E,0x07,0xFE,0x7A,0xFC,0x80,0xFC,0x40,0x3F,0xCF,0xFD,0xD8,0x80,0xC0, +0x49,0xFF,0xFE,0xD2,0xEA,0x33,0x81,0x20,0x49,0x00,0x3C,0xDA,0x4E,0x02,0x00,0xF3, +0x5C,0x94,0x80,0x01,0x4E,0x92,0x00,0x07,0x2E,0x07,0xFD,0x1A,0xC0,0x03,0xEA,0xB7, +0xEA,0xF6,0xBA,0x00,0x9E,0x17,0xE6,0x02,0xEA,0x7B,0xE8,0x08,0xC9,0x07,0x5A,0x20, +0x07,0x03,0xEA,0xF6,0x49,0x00,0x18,0x5F,0xEA,0xF6,0x4E,0x12,0x00,0x50,0x84,0x3F, +0x3E,0x17,0xFE,0x24,0x2E,0x17,0xFD,0x0A,0xC9,0x49,0x4E,0x92,0x00,0x48,0xDD,0x4D, +0x96,0x04,0xC8,0x02,0xEA,0x6D,0x2E,0x07,0xFD,0x08,0x44,0x10,0xA5,0x5A,0xEB,0x49, +0xEA,0x7B,0xEA,0x87,0xDD,0x4A,0x2E,0x67,0xFD,0x08,0x44,0x2F,0xA5,0x5A,0x44,0x10, +0x00,0x3D,0x88,0x46,0xEA,0x84,0xFF,0x8C,0x40,0x21,0x01,0x00,0x8C,0xC2,0xEB,0x81, +0x58,0x00,0x00,0x00,0x40,0x60,0x18,0x20,0x96,0x91,0x80,0xA6,0x50,0x03,0x00,0x7A, +0x0A,0x12,0x80,0x01,0x88,0x41,0x96,0x91,0xD8,0xFC,0xFE,0x92,0x40,0x71,0x40,0x08, +0x85,0x40,0xA4,0x30,0x5A,0xA8,0x1E,0x05,0x8C,0xC2,0x88,0x07,0xD5,0x05,0xA4,0x71, +0x8C,0xC4,0x40,0x00,0x06,0x00,0xDD,0x4A,0x8D,0x41,0xFA,0x0E,0xDD,0x50,0x5A,0xA8, +0x1F,0xF2,0x2E,0x07,0xFD,0x08,0x8C,0x01,0x96,0x00,0xEA,0xC2,0x2E,0x17,0xFD,0x11, +0xE2,0x01,0xE9,0x21,0x84,0x00,0xEA,0xC2,0xD5,0x1E,0x00,0x23,0x00,0x92,0x4E,0x23, +0x00,0x7A,0xEA,0xF4,0xEA,0x5B,0xC1,0x09,0x2E,0x57,0xFD,0x65,0x2E,0x17,0xFD,0x5E, +0xD1,0x04,0xE6,0x02,0x4E,0xF2,0x00,0x6F,0xEA,0x52,0xC8,0x0D,0xB8,0x14,0xC8,0x04, +0x2E,0x07,0xFD,0x0A,0xC0,0x08,0x4E,0x92,0x00,0x04,0xEA,0xB7,0xD5,0x04,0x84,0x01, +0x3E,0x07,0xFD,0x1A,0x2E,0x07,0xFD,0x0A,0x4E,0x02,0x00,0x6D,0x4E,0x92,0x00,0x6B, +0xDD,0x4D,0x96,0x04,0xC8,0x02,0xEA,0x6D,0x2E,0x07,0xFD,0x09,0x8C,0x01,0x96,0x00, +0x3E,0x07,0xFD,0x09,0x2E,0x17,0xFD,0x0C,0xE2,0x20,0xE8,0x04,0x84,0x01,0x3E,0x07, +0xFD,0x09,0x2E,0x07,0xFD,0x09,0x2E,0x77,0xFD,0x10,0x9E,0x41,0x92,0xE1,0xFF,0xCC, +0xEB,0x5A,0xEB,0x30,0x40,0x70,0x9C,0x20,0x2E,0x17,0xFD,0x34,0xC1,0x11,0x44,0x10, +0xA3,0x3A,0xEB,0x49,0xEA,0x7B,0xEA,0x87,0xDD,0x4A,0x2E,0x17,0xFD,0x09,0x44,0x0F, +0xA3,0x3A,0x88,0x01,0xEA,0x7B,0x40,0x00,0x05,0x00,0x96,0x01,0xD5,0x07,0x46,0x00, +0x40,0x30,0x50,0x00,0x02,0x01,0xDD,0x4A,0x84,0x0A,0x2E,0x27,0xFD,0x10,0x84,0x20, +0x92,0x41,0xE2,0x22,0xE8,0x07,0x38,0x33,0x85,0x01,0x8C,0x21,0x88,0x03,0x96,0x01, +0xD5,0xF9,0xFE,0x02,0x40,0x60,0x40,0x08,0x85,0x20,0x2E,0x17,0xFD,0x10,0x8C,0x22, +0x90,0x22,0xE3,0x21,0xE8,0x1F,0x8E,0x21,0xA4,0x38,0x4C,0x90,0xC0,0x05,0x8C,0xE2, +0x88,0x06,0xD5,0x05,0xA4,0x79,0x8C,0xE4,0x40,0x00,0x06,0x00,0xDD,0x4A,0x8D,0x21, +0xD5,0xED,0x5A,0x90,0x01,0x04,0x48,0xFF,0xFF,0x9F,0xEA,0x52,0x4E,0x03,0xFF,0x9C, +0xB8,0x14,0xC0,0x03,0x4E,0x22,0xFF,0x93,0x80,0x06,0x49,0xFF,0xFE,0x1B,0x48,0xFF, +0xFF,0x93,0xFC,0xC0,0xFC,0x20,0x80,0xE0,0x80,0xC1,0x49,0x00,0x27,0xB9,0xDD,0x4B, +0x84,0x20,0x49,0x00,0x29,0xAB,0xEA,0xAE,0x3E,0x20,0x01,0x29,0x84,0x00,0xEA,0xD6, +0x3E,0x07,0xFD,0x14,0xEB,0x5A,0x10,0x00,0x86,0x01,0xFA,0x00,0x3E,0x07,0xFD,0x03, +0xFA,0x14,0xFA,0x30,0x49,0x00,0x3B,0x0E,0xEA,0xDB,0x84,0x25,0xFE,0x8C,0x96,0x90, +0x54,0x01,0x00,0x03,0xC8,0x03,0x8C,0x44,0xD5,0x02,0x8C,0x48,0x96,0x90,0x66,0x21, +0x00,0x03,0x52,0x21,0x00,0x7A,0x96,0x90,0x3E,0x27,0xFD,0x10,0x2E,0x40,0x01,0x29, +0x2E,0x30,0x01,0x28,0x2E,0x10,0x01,0x31,0x42,0x12,0x0C,0x73,0x92,0x41,0x40,0x20, +0x88,0x17,0x96,0x90,0xC0,0x02,0x8C,0x41,0x3E,0x27,0xFD,0x0C,0x44,0x20,0x00,0x3D, +0x40,0x20,0x88,0x37,0x96,0x90,0xC1,0x02,0x8C,0x41,0x3E,0x27,0xFD,0x11,0x84,0x00, +0xEA,0xC2,0x2E,0x17,0xFF,0xAF,0x3E,0x17,0xFD,0x1C,0x3E,0x07,0xFD,0x1A,0x2E,0x00, +0x00,0x16,0x2E,0x20,0x00,0x17,0x40,0x21,0x01,0x04,0x3C,0x2E,0x00,0x48,0x2E,0x00, +0x00,0x18,0x2E,0x10,0x00,0x19,0x40,0x10,0x81,0x04,0x3C,0x1E,0x00,0x49,0x40,0x21, +0x0C,0x57,0x40,0x10,0x90,0x37,0x3E,0x20,0x01,0x32,0x3E,0x10,0x01,0x33,0x8C,0x82, +0x3E,0x47,0xFD,0x16,0x8C,0x62,0x3E,0x37,0xFD,0x05,0x84,0x00,0x3C,0x0B,0xFE,0xC1, +0xCF,0x21,0xEB,0x61,0x14,0x70,0x03,0xF1,0xDD,0x4D,0x96,0x04,0xC0,0x05,0x84,0x01, +0xEB,0x48,0x84,0x02,0xEA,0x6D,0xEB,0x61,0x58,0x00,0x0F,0x44,0x84,0x20,0x44,0x20, +0x00,0x3C,0xDD,0x42,0xCE,0x08,0xEB,0x61,0x58,0x00,0x03,0xB0,0x80,0x26,0x44,0x20, +0x00,0x3C,0xDD,0x42,0xEB,0x61,0x58,0x00,0x0F,0x80,0x84,0x20,0x44,0x20,0x00,0x40, +0xDD,0x42,0x46,0x19,0x00,0x08,0xA4,0x08,0x96,0x01,0x3C,0x0B,0xFE,0xBE,0x92,0x01, +0x3C,0x0B,0xFE,0xBF,0xA4,0x0A,0x3C,0x0B,0xFE,0xBD,0x49,0x00,0x05,0x0B,0x84,0x1F, +0x3E,0x07,0xFE,0x24,0x84,0x00,0xEA,0xC8,0x3E,0x07,0xFD,0x0B,0x84,0x00,0x3C,0x0B, +0xFE,0xC3,0xFC,0xA0,0xFC,0x61,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07, +0x96,0x01,0xDD,0x58,0xEA,0x37,0xDD,0x45,0x46,0x01,0x00,0x07,0x04,0x50,0x03,0xF0, +0x44,0x00,0xA1,0x1A,0x92,0xB0,0xD8,0x03,0x49,0x00,0x2F,0xE4,0x49,0x00,0x3B,0x8E, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0xEB,0x03, +0xDD,0x45,0x49,0x00,0x35,0x0D,0xC8,0xFE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11, +0x00,0x07,0x96,0x01,0xDD,0x58,0x58,0x00,0x00,0x03,0xDD,0x45,0x49,0x00,0x3B,0xB8, +0x49,0xFF,0xF3,0x6E,0xC0,0x02,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xA1, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0xEB,0x05, +0xDD,0x45,0xFA,0x4F,0x44,0x00,0x00,0xE7,0x84,0x22,0x44,0x30,0x00,0xF8,0xDD,0x4E, +0x49,0xFF,0xF1,0xBE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01, +0xDD,0x58,0x58,0x00,0x00,0x05,0xDD,0x45,0x84,0x01,0x44,0x10,0x01,0xE0,0x84,0x45, +0x44,0x30,0x02,0x58,0x49,0x00,0x34,0x84,0x80,0xC0,0xC8,0xF7,0x84,0x45,0x84,0x01, +0x44,0x10,0x00,0x80,0x49,0x00,0x34,0xB9,0x46,0x01,0x00,0x07,0xEA,0xBA,0x96,0x49, +0xEA,0x6F,0x58,0x10,0x80,0x06,0xEA,0x7C,0x49,0xFF,0xF4,0xFD,0x49,0xFF,0xF5,0x47, +0x4E,0x00,0x33,0x6E,0x80,0x06,0xEA,0x5B,0xEA,0xAB,0x84,0x21,0xEB,0x81,0x12,0x60, +0x00,0x00,0x80,0x41,0x44,0x00,0x00,0xE7,0xEA,0x3A,0x96,0x01,0x46,0x11,0x00,0x07, +0x12,0x00,0x87,0xAF,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01, +0xDD,0x58,0x58,0x00,0x00,0x07,0xDD,0x45,0xFA,0x0A,0xDD,0x40,0xC8,0x19,0xFA,0x0E, +0xDD,0x40,0xC8,0x16,0xFA,0x13,0xDD,0x40,0xC8,0x13,0xFA,0x18,0xDD,0x40,0xC8,0x10, +0x46,0x01,0x00,0x07,0xEA,0x63,0x4E,0x00,0x33,0x04,0xD8,0x08,0xEA,0x21,0xEA,0x20, +0x83,0xFF,0x46,0x11,0x00,0x07,0xEA,0x70,0xD5,0x03,0x49,0xFF,0xF3,0x24,0x49,0x00, +0x3B,0xA6,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58, +0x58,0x00,0x00,0x08,0xDD,0x45,0x84,0x00,0xDD,0x55,0x84,0xC0,0x3C,0x6F,0xFF,0x7C, +0x46,0x01,0x00,0x07,0xEA,0xBA,0x84,0x41,0x96,0x49,0xEA,0x6F,0x10,0x2F,0x80,0x00, +0x10,0x2F,0x80,0x01,0x10,0x2F,0x80,0x02,0x10,0x2F,0x80,0x03,0x10,0x2F,0x80,0x04, +0x58,0x10,0x80,0x09,0xEA,0x7C,0x3A,0x0F,0x84,0x00,0x49,0x00,0x2F,0x3C,0x80,0x06, +0x84,0x26,0x49,0x00,0x3A,0x62,0x46,0x00,0x0E,0xD0,0x46,0x10,0x20,0x0C,0x50,0x00, +0x00,0x40,0x8C,0x26,0x49,0x00,0x3A,0x54,0x46,0x09,0x00,0x20,0xB4,0x20,0x66,0x10, +0x80,0x40,0xB6,0x20,0xEA,0xF4,0xEA,0x8B,0xC1,0x05,0xA0,0x41,0x58,0x10,0x80,0x08, +0xA8,0x41,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58, +0x58,0x00,0x00,0x0A,0xDD,0x45,0x84,0x41,0x44,0x00,0x00,0xBC,0x84,0x20,0x84,0x66, +0x46,0x78,0x00,0x20,0x46,0x9A,0x33,0xAA,0xDD,0x4E,0x84,0xC0,0x50,0xA3,0x84,0xF4, +0x50,0x94,0x83,0x3A,0x46,0xB9,0x00,0x90,0x84,0x07,0x49,0x00,0x2D,0x55,0x8C,0x05, +0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF9,0xEA,0x42,0x4E,0x02,0x00,0xC7,0xEA,0x93, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0x58,0x00, +0x00,0x0B,0xDD,0x45,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x84,0x00,0xDD,0x55,0xD5,0x0C, +0xFA,0x02,0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40, +0xC8,0xF5,0x49,0xFF,0xED,0xD0,0x49,0x00,0x02,0xD1,0xC8,0x1E,0x46,0x01,0x00,0x07, +0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x58,0x58,0x00,0x00,0x0C,0xDD,0x45, +0x84,0x0E,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xF4,0xE1,0xF8,0x0C,0xFA,0x02,0xDD,0x40, +0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,0xC8,0xF5,0x49,0x00, +0x02,0x09,0x48,0x00,0x00,0x83,0x84,0x00,0x3E,0x07,0xFD,0x00,0x3E,0x07,0xFD,0x07, +0x46,0x01,0x00,0x07,0xEA,0xBA,0x96,0x49,0xEA,0x6F,0x58,0x10,0x80,0x0D,0xEA,0x7C, +0x84,0x0E,0xDD,0x40,0xC8,0x28,0xFA,0x02,0xDD,0x40,0xC8,0x25,0xFA,0x06,0xDD,0x40, +0xC8,0x22,0xDD,0x47,0xDD,0x40,0xC8,0x1F,0xDD,0x4B,0x5A,0x00,0x08,0x15,0x5A,0x00, +0x06,0x13,0xDD,0x59,0x5A,0x08,0x01,0x06,0xF8,0x4C,0xC8,0x03,0x49,0x00,0x29,0x4D, +0xEB,0x21,0xC8,0x0D,0x49,0x00,0x11,0xE8,0x49,0x00,0x2A,0x7E,0x49,0x00,0x27,0xB0, +0x80,0xC0,0xD5,0x05,0x49,0x00,0x25,0x46,0x49,0x00,0x25,0x22,0xEB,0x21,0xC8,0x03, +0x49,0x00,0x02,0x48,0x49,0xFF,0xFB,0x64,0x49,0xFF,0xED,0xB0,0x84,0x01,0x3E,0x07, +0xFD,0x00,0x80,0x06,0x49,0xFF,0xFC,0xD2,0xEA,0xEE,0x49,0x00,0x28,0xD4,0xEA,0x52, +0xC8,0x02,0xEA,0xC4,0x49,0x00,0x01,0x9F,0x84,0x0E,0xDD,0x40,0xC8,0x36,0xFA,0x02, +0xDD,0x40,0xC8,0x33,0xFA,0x06,0xDD,0x40,0xC8,0x30,0x84,0x0A,0xDD,0x40,0xC8,0x2D, +0xFA,0x0A,0xDD,0x40,0xC8,0x2A,0xFA,0x13,0xDD,0x40,0xC8,0x27,0xFA,0x0E,0xDD,0x40, +0xC8,0x24,0xFA,0x18,0xDD,0x40,0xC8,0x21,0xFA,0x1C,0xDD,0x40,0xC8,0x1E,0xDD,0x47, +0xDD,0x40,0xC8,0x1B,0x3C,0x0D,0xFF,0x88,0x5A,0x08,0x01,0x18,0xEB,0x21,0xC8,0x13, +0xEA,0xDC,0x5A,0x08,0x01,0x09,0x00,0x05,0x00,0x00,0x96,0x04,0xC8,0x04,0x49,0x00, +0x24,0x8B,0xD5,0x07,0x00,0x05,0x00,0x00,0x96,0x0E,0xC8,0x03,0x49,0x00,0x24,0x3B, +0x49,0x00,0x25,0x48,0x49,0x00,0x29,0xE6,0x46,0x01,0x00,0x07,0xEA,0xBA,0x96,0x49, +0xEA,0x6F,0x58,0x10,0x80,0x0E,0xEA,0x7C,0xDD,0x4B,0x5A,0x08,0x07,0x07,0x00,0x53, +0x83,0x40,0xEA,0x57,0xD8,0x19,0xD5,0x0C,0x5A,0x08,0x08,0x17,0x00,0x53,0x83,0x40, +0xEA,0x82,0xD8,0x12,0x00,0x05,0x80,0x00,0xC8,0xFE,0x49,0x00,0x33,0x93,0x49,0x00, +0x34,0x4E,0x46,0x01,0x00,0x07,0xEA,0x63,0x4C,0x54,0xC0,0x07,0x84,0x21,0xDD,0x4B, +0xEA,0x34,0x84,0x00,0xEA,0xC8,0x84,0x0E,0xDD,0x40,0xC8,0x13,0xFA,0x02,0xDD,0x40, +0xC8,0x10,0xFA,0x06,0xDD,0x40,0xC8,0x0D,0x84,0x0A,0xDD,0x40,0xC8,0x0A,0xFA,0x0A, +0xDD,0x40,0xC8,0x07,0xFA,0x13,0xDD,0x40,0xC8,0x04,0xDD,0x47,0xDD,0x40,0xC0,0x05, +0x84,0x01,0xF8,0x05,0xC8,0xFE,0xF8,0x06,0x2E,0x07,0xFD,0x0D,0x49,0x00,0x2E,0x98, +0xC8,0xFC,0x48,0xFF,0xFE,0xF3,0xFC,0x00,0x46,0x61,0x00,0x03,0x58,0x63,0x0A,0x98, +0x80,0x06,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x50,0x03,0x05,0x10,0x84,0x20,0xDD,0x4F, +0xDD,0x42,0x50,0x03,0x10,0x10,0x84,0x20,0x44,0x20,0x05,0xF0,0xDD,0x42,0x50,0x03, +0x16,0x00,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3C,0x0F,0xFF,0x8F,0xFC,0x80, +0xFC,0x20,0x3F,0xCF,0xFD,0xD8,0xB8,0x00,0x5A,0x00,0x08,0x05,0x84,0xC3,0x5A,0x08, +0x06,0x03,0x84,0xC1,0xB9,0x19,0x2E,0x27,0xFD,0x2F,0x2E,0x07,0xFD,0x40,0x88,0x02, +0xE2,0x20,0x4E,0xF2,0x00,0x5B,0xB9,0x19,0xC9,0x05,0xEB,0x4E,0xEA,0x62,0xDD,0x4F, +0xDD,0x42,0xB9,0x19,0x2E,0x07,0xFD,0x2F,0x84,0x80,0xE2,0x20,0xE8,0x2D,0x2E,0x37, +0xFF,0xA9,0x2E,0x07,0xFF,0xDF,0x44,0x10,0x00,0xD8,0x88,0x60,0xFE,0x74,0xBD,0x1A, +0x94,0xDA,0x46,0x21,0x00,0x05,0x58,0x21,0x00,0x98,0x40,0x12,0x84,0x20,0x84,0x80, +0x45,0x00,0x6D,0x60,0x45,0x10,0xDA,0xC0,0xD1,0x17,0x02,0x01,0x6F,0xF0,0xA5,0xE8, +0x8A,0x07,0x96,0x01,0x97,0xC3,0x42,0x73,0x80,0x03,0xE0,0xE3,0xE8,0x04,0xA5,0xD0, +0x88,0x07,0xAC,0x10,0x2A,0x01,0x00,0x01,0x88,0x10,0x96,0x01,0xE3,0xA0,0xE8,0x02, +0x84,0x81,0x8C,0xA2,0xD5,0xEA,0xB8,0x19,0x8C,0x01,0xB8,0x99,0x5A,0x48,0x01,0x1E, +0x44,0x20,0x00,0xD8,0xFE,0xB4,0xBD,0x1A,0x46,0x31,0x00,0x05,0x58,0x31,0x80,0x98, +0x40,0x22,0x88,0x20,0x84,0x80,0xD2,0x0F,0xA5,0xE8,0xB8,0x19,0x22,0x11,0x80,0x00, +0x96,0x03,0x40,0x00,0x80,0x16,0x88,0x07,0x96,0x01,0x1A,0x02,0x80,0x01,0x1A,0x41, +0x80,0x01,0xD5,0xF2,0x84,0x00,0xB8,0x99,0xB9,0x19,0x2E,0x47,0xFD,0x2F,0x2E,0x07, +0xFD,0x40,0x88,0x04,0xE2,0x20,0xE9,0x3A,0x84,0x40,0xBA,0x99,0xBD,0x1A,0x44,0x00, +0x00,0xD8,0x42,0x13,0x00,0x24,0x46,0x31,0x00,0x05,0x58,0x31,0x80,0x98,0x40,0x12, +0x84,0x20,0xD1,0x0D,0x22,0x01,0x80,0x00,0xA5,0xA8,0x40,0x00,0x10,0x16,0x88,0x06, +0x96,0x01,0x1A,0x02,0x80,0x01,0x1A,0x21,0x80,0x01,0xD5,0xF4,0xB8,0x00,0x5A,0x08, +0x02,0x1E,0x2E,0x07,0xFD,0x22,0x2E,0x10,0x00,0x70,0xE2,0x20,0xE8,0x05,0x84,0x01, +0xB8,0x90,0x84,0x00,0xD5,0x11,0x2E,0x2F,0xFF,0xA3,0x4E,0x24,0x00,0x10,0x3C,0x33, +0xFE,0xE2,0xBA,0x26,0xE2,0x62,0xE9,0x0A,0x3C,0x33,0xFE,0xE7,0xBA,0x25,0xE2,0x62, +0xE9,0x05,0xC1,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x22,0xFC,0xA0,0xFC,0x20,0x3C,0x1D, +0xFF,0x90,0xEA,0x40,0x2E,0x37,0xFD,0x64,0xE2,0x03,0xE8,0x48,0xEB,0x27,0x5A,0x08, +0x01,0x2C,0x2E,0x57,0xFD,0x48,0x9E,0x19,0xD8,0x27,0x2E,0x70,0x00,0x0A,0x84,0xA0, +0x47,0x01,0x00,0x02,0x59,0x08,0x01,0x44,0x44,0x60,0x05,0x10,0x50,0x22,0x8F,0x34, +0x99,0x0D,0x88,0x50,0xA4,0x20,0x03,0x11,0x00,0x00,0xE3,0xA0,0xE8,0x04,0xA4,0x20, +0xA4,0x90,0xD5,0x03,0xA4,0x10,0xA4,0xA0,0x8A,0x02,0xE0,0xE0,0xE8,0x05,0x84,0x00, +0x3E,0x07,0xFD,0x30,0xD5,0x03,0x8C,0xA2,0xDE,0xEA,0xEB,0x27,0x5A,0x08,0x01,0x05, +0x3E,0x37,0xFD,0x45,0xD5,0x1D,0xEB,0x27,0xC8,0x1B,0xDD,0x4B,0x8E,0x02,0xE6,0x07, +0xE8,0x17,0x3E,0xFF,0x7A,0xC8,0x38,0x07,0x80,0x00,0xEA,0xAF,0x4A,0x00,0x3C,0x00, +0x08,0x1E,0x1E,0x1E,0x0C,0x08,0x0C,0x00,0xEA,0xB2,0xD5,0x02,0xEA,0x5A,0x46,0x21, +0x00,0x03,0x58,0x21,0x00,0x78,0xDD,0x48,0xD5,0x03,0x49,0xFF,0xFF,0x03,0xFC,0xA0, +0x92,0x00,0xFC,0x00,0xEB,0x38,0xC0,0x1C,0x2E,0x07,0xFD,0x4D,0x2E,0x17,0xFF,0xDE, +0xE2,0x01,0xE9,0x10,0x84,0x00,0x3E,0x07,0xFD,0x3B,0x84,0x20,0x3C,0x1F,0xFF,0x8F, +0x2E,0x07,0xFD,0x47,0x3E,0x07,0xFD,0x2F,0xEB,0x4E,0xEA,0x62,0xDD,0x4F,0xDD,0x42, +0xD5,0x07,0x3C,0x1D,0xFF,0x87,0xC9,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x4D,0xFC,0x80, +0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0x2E,0x17,0xFD,0x48,0x2E,0x07,0xFD,0x45,0xE2,0x20, +0xE9,0x05,0x84,0x01,0xEA,0xAA,0x84,0x0A,0xD5,0x03,0x84,0x00,0xEA,0xAA,0x3E,0x07, +0xFD,0x40,0x2E,0x07,0xFD,0x34,0xC0,0x2A,0x84,0x01,0xEB,0x25,0x84,0x01,0x3E,0x07, +0xFD,0x30,0x84,0x02,0xEA,0xF9,0xBE,0x00,0x5A,0x68,0x02,0x18,0x2E,0x07,0xFD,0x5F, +0x5A,0x08,0x01,0x14,0xEA,0x2B,0xE6,0x01,0x3E,0xF7,0xFD,0x79,0x80,0x06,0x80,0x26, +0xEA,0x34,0x3E,0x67,0xFD,0x5F,0xEA,0x2B,0xC0,0x04,0xEB,0x64,0xDD,0x5D,0xD5,0x03, +0xEB,0x64,0xEA,0xB6,0xB8,0x9A,0xD5,0x2B,0x84,0x00,0x3E,0x07,0xFD,0x59,0x2E,0x07, +0xFD,0x43,0x8C,0x01,0x3E,0x07,0xFD,0x43,0xD5,0x08,0x49,0xFF,0xFF,0x51,0x2E,0x07, +0xFD,0x59,0x8C,0x01,0x3E,0x07,0xFD,0x59,0xEB,0x81,0x02,0x50,0x03,0x01,0xEB,0x04, +0xD0,0x09,0x2E,0x0F,0xFF,0xA2,0x4E,0x04,0x00,0x06,0xB8,0x00,0x8E,0x07,0xE6,0x02, +0xE8,0x06,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC3,0xD5,0x09,0xEB,0x81,0x00,0x00, +0x06,0x01,0xEB,0x5A,0x8C,0x01,0x96,0x00,0x10,0x00,0x86,0x01,0xFC,0x80,0xFC,0x20, +0x3C,0x7D,0xFF,0x90,0x84,0xA0,0xEB,0x19,0xEB,0x24,0x84,0x63,0xDD,0x4F,0x98,0x7D, +0x50,0x02,0x8F,0x34,0xA5,0x08,0x88,0x06,0xA4,0x00,0x42,0x02,0x0C,0x73,0x8C,0xA2, +0x90,0x02,0x96,0x01,0xAC,0x08,0xDA,0xF4,0x84,0x03,0x3C,0x0F,0xFF,0x86,0xFC,0xA0, +0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05, +0xEB,0x4E,0xEA,0xA4,0xD5,0x04,0xB8,0x11,0xC8,0x04,0xEA,0x96,0xE6,0x01,0xD5,0x02, +0x85,0xE0,0x3E,0xF7,0xFD,0x50,0xEA,0x6A,0xEA,0xA3,0xC0,0x0F,0x2E,0x07,0xFD,0x50, +0xC0,0x0C,0xB8,0x10,0x5A,0x00,0x02,0x0A,0x49,0xFF,0xFE,0x4C,0x84,0x00,0x3E,0x07, +0xFD,0x2D,0x84,0x00,0xEA,0x64,0xD5,0x10,0x84,0xC0,0xBE,0x99,0x80,0x26,0xEB,0x4E, +0xEA,0x62,0xDD,0x4F,0xDD,0x42,0xB8,0x10,0x5A,0x08,0x02,0x05,0x49,0xFF,0xFF,0xB9, +0xD5,0x03,0x3E,0x67,0xFD,0x22,0xFC,0x80,0x2E,0x07,0xFD,0x34,0xDD,0x9E,0xFC,0x60, +0x3D,0x3C,0x00,0x49,0x2E,0x90,0x00,0x8A,0x2E,0x47,0xFF,0xA5,0x92,0x84,0x3C,0x2C, +0x00,0x48,0x4E,0x42,0x00,0xF1,0x3F,0x18,0x02,0x5C,0x38,0x38,0x80,0x00,0x5A,0x38, +0x01,0x13,0xEA,0xC6,0xFF,0x04,0x44,0x30,0xFF,0xFF,0x99,0xCC,0xA1,0xBE,0x4C,0x61, +0xC0,0x0B,0xA1,0x7B,0xDE,0x08,0x38,0x30,0x90,0x02,0x4C,0x32,0xC0,0x05,0x84,0x60, +0x38,0x38,0x80,0x08,0xEA,0xC6,0x42,0x30,0x10,0x24,0xEA,0x89,0x99,0xCB,0xB4,0xA7, +0x8E,0x41,0x8F,0xE1,0xDC,0x54,0x50,0x41,0x80,0x0C,0x88,0x81,0xB5,0x84,0x4D,0x02, +0x80,0x4F,0x51,0x21,0x80,0x18,0x89,0xC1,0xB4,0xD2,0x4C,0x62,0x80,0x49,0xA0,0xE1, +0x40,0x18,0x04,0x08,0xE0,0x26,0x04,0x09,0x00,0x01,0x95,0xD9,0xE9,0x0B,0xE0,0xE0, +0xE8,0x19,0x40,0x18,0x18,0x01,0xFE,0x5C,0x9A,0x83,0x40,0x10,0x88,0x36,0x88,0x30, +0xD5,0x02,0x84,0x20,0xE0,0xE0,0xB6,0x24,0xE8,0x04,0x84,0x00,0xA8,0x21,0xF8,0x2D, +0x9A,0x18,0x42,0x18,0x00,0x24,0x40,0x53,0x40,0x01,0x40,0x00,0x94,0x16,0x99,0x58, +0xD5,0x23,0x99,0x72,0xE0,0xA1,0x41,0x10,0x4C,0x00,0xE9,0x0F,0xE1,0xA7,0x4E,0xF2, +0x00,0x9B,0x40,0x58,0x18,0x01,0x40,0x11,0xCC,0x01,0xFE,0x6C,0x9B,0x43,0x40,0x10, +0x94,0x36,0x88,0x30,0xB6,0x24,0xD5,0x02,0xB6,0x44,0xE1,0xA7,0xE8,0x04,0x15,0x32, +0x00,0x01,0xF8,0x0B,0x40,0x58,0x08,0x01,0x9A,0x18,0xFE,0x2C,0x40,0x53,0x40,0x01, +0x40,0x50,0x14,0xB6,0x88,0xA3,0xA9,0x61,0x48,0x00,0x00,0x7E,0x46,0x41,0x00,0x01, +0x58,0x42,0x0D,0x80,0x40,0x42,0x00,0x20,0xA7,0x21,0x5A,0x40,0xFE,0x0D,0x2E,0x47, +0xFD,0x67,0xCC,0x71,0xEA,0x89,0xD4,0x6F,0xA1,0xBB,0x4C,0x62,0x00,0x6D,0xA1,0xBE, +0x4C,0x62,0x40,0x6A,0x8C,0x6C,0x38,0xB8,0x80,0x00,0x88,0x61,0xB5,0x83,0x05,0x21, +0x80,0x01,0xA0,0x79,0x4E,0xB3,0x00,0x60,0x40,0x68,0x04,0x08,0x40,0x33,0x24,0x01, +0xE0,0x65,0x40,0x39,0x04,0x08,0xE9,0x10,0x40,0x41,0xA4,0x01,0xE0,0x81,0xE8,0x1B, +0x40,0x28,0x14,0x01,0x42,0x29,0x08,0x24,0x40,0x40,0xC8,0x01,0x40,0x21,0x10,0x56, +0x88,0x50,0xA8,0xBE,0xD5,0x03,0x14,0xB3,0x80,0x06,0x8A,0x69,0xE0,0x61,0xE9,0x3C, +0x40,0x39,0x04,0x01,0x42,0x38,0x0C,0x24,0x8A,0xB0,0x40,0x21,0x94,0x56,0x40,0x59, +0x08,0x00,0xD5,0x30,0x99,0x2A,0x8A,0x89,0xE0,0x86,0x40,0xA0,0xCC,0x00,0xE9,0x06, +0x40,0x45,0x24,0x01,0xE0,0x83,0xE9,0x04,0xD5,0x2E,0xA8,0xBE,0xD5,0x11,0x40,0x68, +0x14,0x01,0x40,0x49,0x4C,0x01,0xFF,0x34,0x40,0x60,0xC8,0x01,0x40,0x42,0x18,0x96, +0x88,0x90,0x4E,0x45,0x00,0x04,0xA9,0x3E,0xD5,0x03,0x14,0xB3,0x80,0x06,0x40,0x95, +0x24,0x01,0xE1,0x23,0xE8,0x04,0x15,0x33,0x80,0x07,0xD5,0x12,0x40,0x38,0x08,0x01, +0x40,0x29,0x04,0x01,0xFE,0x9C,0x8A,0xB0,0x40,0x51,0x14,0xB6,0x88,0xB2,0x4E,0x55, +0x00,0x04,0xA9,0x7F,0xD5,0x05,0x50,0x13,0x80,0x18,0x84,0x40,0xA8,0x89,0x84,0x21, +0x38,0x18,0x80,0x08,0xFC,0xE0,0x3E,0x18,0x02,0x5C,0x38,0x00,0x80,0x00,0xDD,0x9E, +0xFC,0x20,0x3F,0xCF,0xFE,0x00,0x3E,0x68,0x01,0x40,0x84,0x1F,0x84,0xE0,0x12,0x03, +0x00,0x44,0x12,0x03,0x00,0x45,0x84,0x20,0x50,0x03,0x00,0x60,0x84,0x4C,0x12,0x73, +0x00,0x42,0x12,0x73,0x00,0x43,0xDD,0x42,0x80,0x06,0x44,0x10,0xFF,0xFF,0x44,0x20, +0x00,0x60,0xDD,0x42,0x50,0x03,0x00,0x78,0x84,0x20,0x84,0x4C,0xDD,0x42,0x46,0x11, +0x41,0x41,0x50,0x03,0x00,0x6C,0x50,0x10,0x84,0x14,0x84,0x4C,0xDD,0x42,0x46,0x01, +0x00,0x07,0x58,0x00,0x02,0x66,0xA6,0x40,0xA6,0x81,0xEA,0x31,0xB9,0x81,0xA6,0x42, +0xA6,0x83,0xEA,0x31,0xB9,0x8E,0xA6,0x45,0xA6,0x86,0xEA,0x31,0xB9,0x80,0xA6,0x47, +0xEB,0x0E,0xEA,0x31,0xB9,0x94,0x00,0x10,0x00,0x0A,0x00,0x20,0x00,0x0B,0xEA,0x31, +0xB9,0x96,0x00,0x10,0x00,0x0C,0x00,0x20,0x00,0x0D,0xEA,0x31,0xB9,0x97,0x00,0x10, +0x00,0x0F,0x00,0x20,0x00,0x10,0xEA,0x31,0xB9,0x8C,0x00,0x10,0x00,0x11,0x00,0x00, +0x00,0x12,0x40,0x00,0x05,0x04,0xB8,0x85,0x3C,0x7B,0xFE,0xDA,0x84,0x20,0x3E,0x08, +0x02,0xA4,0xFA,0x48,0xDD,0x42,0xFC,0xA0,0xFC,0x20,0x46,0x71,0x00,0x07,0x58,0x73, +0x83,0x48,0x82,0x00,0x46,0x51,0x00,0x01,0x58,0x52,0x8F,0xF4,0x84,0x00,0x47,0x11, +0x00,0x01,0x59,0x18,0x8D,0x68,0x00,0x68,0x00,0x00,0x38,0x43,0x98,0x00,0x5A,0x40, +0xFF,0x18,0x41,0x23,0x98,0x00,0x41,0x32,0x10,0x09,0x01,0x29,0x00,0x01,0x4C,0x29, +0xC0,0x0C,0x97,0x1F,0xE2,0x64,0xE9,0x08,0x38,0x48,0x84,0x00,0x38,0x42,0x92,0x02, +0xE2,0x92,0xE9,0x02,0x84,0x01,0x8C,0xC2,0x10,0x68,0x00,0x00,0xD5,0xE5,0xFC,0xA0, +0x46,0x31,0x00,0x07,0x58,0x31,0x83,0x48,0xA6,0x80,0x38,0x41,0x88,0x00,0x8C,0x41, +0x5A,0x48,0xFF,0x04,0xAE,0x80,0xDD,0x9E,0xC9,0xFE,0xAE,0x80,0xD5,0xF6,0x3C,0x3D, +0xFF,0x87,0x84,0x28,0x3E,0x08,0x01,0xFC,0xEA,0x89,0xEB,0x0E,0xC2,0x08,0xCB,0x04, +0x10,0x30,0x00,0x08,0xD5,0x04,0x8E,0x41,0x10,0x20,0x00,0x08,0xEB,0x0E,0xCA,0x03, +0xB6,0x80,0xA9,0x01,0x8E,0x21,0x96,0x48,0x8C,0x0C,0xC9,0xF0,0xDD,0x9E,0xFC,0x01, +0x84,0x6C,0xEA,0x38,0x80,0x5F,0x84,0x00,0x3E,0x48,0x01,0xFC,0x80,0x24,0x42,0x10, +0x0C,0x73,0x00,0x50,0x80,0x08,0xCD,0x0A,0x46,0x01,0x00,0x07,0x3B,0x01,0x44,0x00, +0x00,0x00,0x02,0x7A,0xEA,0xEA,0xEA,0xFB,0xD5,0x04,0x8C,0x01,0x5A,0x08,0x08,0xF0, +0xFC,0x81,0xFC,0x21,0xEA,0x38,0x80,0x80,0x46,0x01,0x00,0x07,0x00,0x60,0x02,0x7D, +0x46,0x01,0x00,0x07,0x00,0x70,0x02,0x7E,0x46,0x01,0x00,0x07,0x80,0xA1,0x01,0x00, +0x02,0x7A,0x3E,0x18,0x01,0xFC,0x84,0x68,0x84,0x00,0x00,0x20,0x80,0x08,0xC2,0x14, +0xB4,0x41,0xE2,0x82,0xE8,0x03,0x8A,0x44,0xD5,0x02,0x9A,0xA2,0xE2,0x46,0xE8,0x0C, +0xA0,0x89,0xE2,0xA2,0xE8,0x03,0x8A,0x45,0xD5,0x02,0x9A,0xAA,0xE2,0x47,0xE8,0x04, +0x11,0x00,0x80,0x08,0x84,0x01,0x8E,0x61,0x96,0xD8,0x8C,0x2C,0xCB,0xE7,0xFC,0xA1, +0xFC,0x01,0xEA,0x38,0x80,0xC0,0x80,0x01,0x2E,0x17,0xFD,0x6D,0xC1,0x04,0x84,0x21, +0x84,0xA2,0xD5,0x03,0x84,0x22,0x84,0xA1,0x3E,0x48,0x01,0x40,0x38,0x32,0x0B,0x02, +0xE2,0x66,0xE8,0x03,0x9A,0xF3,0xD5,0x02,0x8A,0x66,0x46,0x61,0x00,0x07,0x00,0x63, +0x02,0x7F,0xFF,0x74,0xE2,0xA3,0xE9,0x0D,0x40,0x32,0x08,0x60,0xA0,0x99,0xE2,0x40, +0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40,0xFE,0x74,0x40,0x00,0x88,0x06,0xD5,0x02, +0x84,0x01,0xFC,0x81,0xFC,0x20,0x84,0x00,0x3C,0x0B,0xFE,0xD4,0x3C,0x0B,0xFE,0xE0, +0x3C,0x0B,0xFE,0xDE,0x46,0x11,0x00,0x07,0x04,0x70,0x83,0xCF,0x46,0x11,0x00,0x07, +0x00,0x60,0x82,0x6A,0x46,0x11,0x00,0x07,0x00,0x50,0x82,0x6F,0x46,0x11,0x00,0x07, +0x00,0x40,0x82,0x74,0x46,0x11,0x00,0x07,0x00,0x30,0x82,0x79,0x46,0x11,0x00,0x07, +0x00,0x20,0x82,0x88,0x46,0x1A,0x11,0xAA,0x50,0x10,0x81,0x1A,0x4C,0x70,0x80,0x0C, +0x46,0x11,0x00,0x07,0x04,0x70,0x83,0xCF,0x46,0x1A,0x33,0xAA,0x50,0x10,0x83,0x3A, +0x4C,0x70,0xC0,0x26,0x84,0x00,0x3E,0x07,0xFD,0x6D,0x44,0x00,0x00,0x96,0x3C,0x0B, +0xFE,0xDD,0x44,0x00,0x00,0x32,0x3C,0x0B,0xFE,0xDF,0x3C,0x6B,0xFE,0xD8,0x3C,0x5B, +0xFE,0xDC,0x3C,0x4B,0xFE,0xD3,0x3C,0x3B,0xFE,0xDB,0x46,0x01,0x00,0x07,0x00,0x00, +0x02,0x82,0x3C,0x0B,0xFE,0xD5,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x83,0x94,0x01, +0x3C,0x0B,0xFE,0xD7,0x3C,0x2B,0xFE,0xD9,0x84,0x00,0xD5,0x21,0x84,0x21,0x3E,0x17, +0xFD,0x6D,0x44,0x10,0x00,0x32,0x3C,0x1B,0xFE,0xDD,0x3C,0x1B,0xFE,0xDF,0x3C,0x6B, +0xFE,0xD8,0x3C,0x5B,0xFE,0xDC,0x3C,0x4B,0xFE,0xD3,0x3C,0x3B,0xFE,0xDB,0x46,0x11, +0x00,0x07,0x00,0x10,0x82,0x84,0x3C,0x1B,0xFE,0xD5,0x46,0x11,0x00,0x07,0x00,0x10, +0x82,0x85,0x94,0x49,0x3C,0x1B,0xFE,0xD7,0x3C,0x2B,0xFE,0xD9,0x3C,0x0B,0xFE,0xD6, +0xFC,0xA0,0xFC,0x01,0x3F,0xC8,0x01,0x20,0x46,0x21,0x00,0x07,0x04,0x51,0x03,0xCF, +0x46,0x3A,0x11,0xAA,0xEA,0x38,0x50,0x31,0x81,0x1A,0x80,0x20,0x3C,0x23,0xFE,0xD7, +0xF0,0x01,0xDB,0x03,0xE2,0x02,0xD5,0x0D,0x46,0x31,0x00,0x07,0x04,0x51,0x83,0xCF, +0x46,0x3A,0x33,0xAA,0x50,0x31,0x83,0x3A,0xDB,0x0A,0xBB,0x01,0x9A,0x9A,0xE2,0x40, +0xE8,0x15,0x3C,0x03,0xFE,0xD5,0xE2,0x20,0xE8,0x0A,0xD5,0x0E,0xE2,0x02,0xE9,0x05, +0xBB,0x01,0x9A,0x9A,0xE2,0x40,0xE8,0x0A,0x3C,0x03,0xFE,0xD5,0xBA,0x00,0x9A,0x10, +0x40,0x00,0x04,0x06,0xD5,0x04,0x84,0x01,0xD5,0x02,0x84,0x00,0xFC,0x81,0xFC,0x21, +0x80,0xE0,0x3A,0x1F,0x88,0x20,0x3A,0x0F,0x84,0x00,0x80,0x47,0x80,0xDF,0x49,0xFF, +0xFF,0xC2,0x5A,0x08,0x01,0x0A,0x3C,0x13,0xFE,0xDA,0x40,0x20,0x1C,0x0C,0xFE,0x57, +0x3C,0x1B,0xFE,0xDA,0xD5,0x02,0x84,0x00,0xB4,0x5F,0x3E,0x18,0x02,0x8C,0x38,0x20, +0x9D,0x09,0xA0,0xB1,0x3E,0x18,0x02,0xBC,0x38,0x20,0x9D,0x09,0xFC,0xA1,0xEB,0x78, +0xEA,0x71,0x38,0x00,0x80,0x00,0x3E,0x18,0x01,0xCC,0x40,0x10,0x80,0x40,0xA6,0x0A, +0xA6,0x4B,0x8A,0x01,0x96,0x01,0xDD,0x9E,0xEB,0x78,0xEA,0x71,0x38,0x20,0x80,0x00, +0x3E,0x18,0x01,0xCC,0x40,0x00,0x88,0x40,0xA6,0x01,0x38,0x10,0x8A,0x00,0x8A,0x01, +0x96,0x01,0xDD,0x9E,0xEB,0x78,0xEA,0x71,0x38,0x30,0x80,0x00,0x46,0x01,0x00,0x01, +0x58,0x00,0x0F,0xDC,0x40,0x10,0x0C,0x20,0xA6,0x49,0x80,0x80,0xE6,0x22,0xE8,0x18, +0x38,0x00,0x0D,0x00,0xE6,0x02,0xE8,0x14,0xEB,0x54,0x22,0xF0,0x05,0x4C,0xF8,0x08, +0xEB,0x54,0x22,0xF0,0x05,0x70,0xF8,0x04,0xEB,0x54,0x22,0xF0,0x05,0x4D,0xDD,0x5F, +0x4E,0xF3,0x00,0x79,0x83,0xFF,0xEB,0x54,0x22,0xF0,0x05,0x71,0xD5,0x3D,0xEA,0x3C, +0x9E,0x82,0xE0,0x22,0x4E,0xF3,0x00,0x6D,0x38,0x52,0x0D,0x00,0xE6,0xA2,0xE8,0x15, +0x46,0x11,0x00,0x02,0xEB,0x17,0x40,0x20,0x80,0x20,0x22,0xF1,0x0C,0xA9,0xDD,0x5F, +0xE9,0x61,0x22,0xF1,0x0C,0xCD,0xDD,0x5F,0xE9,0x5D,0x22,0xF1,0x0C,0xA8,0xDD,0x5F, +0xE9,0x59,0x22,0xF1,0x0C,0xCC,0xD5,0x20,0xE6,0x22,0xE8,0x20,0xEA,0xB0,0x38,0x12, +0x0D,0x00,0x9F,0x42,0xE0,0x25,0xE9,0x4E,0x9E,0x41,0xEB,0x64,0x58,0x00,0x01,0x44, +0x44,0x20,0x00,0x48,0x80,0x60,0x42,0x30,0x88,0x73,0x22,0xF1,0x8C,0xAA,0xDD,0x5F, +0xE9,0x41,0x42,0x02,0x88,0x73,0xF8,0x23,0xE9,0x3D,0x22,0xF1,0x8C,0xAB,0xDD,0x5F, +0xE9,0x39,0x22,0xF0,0x0C,0xAB,0xF8,0x2C,0xDD,0x9E,0xFC,0x00,0x2E,0x10,0x01,0x29, +0x9F,0x8A,0xE0,0xA6,0xE9,0x2B,0x8E,0x21,0xFA,0x74,0xFE,0x5C,0x8E,0x01,0x46,0x41, +0x00,0x02,0x58,0x42,0x01,0x44,0x99,0x48,0x40,0x52,0x14,0x20,0x22,0xF2,0x8C,0xAA, +0xDD,0x5F,0xE9,0x1C,0xFE,0xF4,0x88,0x03,0x40,0x02,0x00,0x20,0x22,0xF0,0x0C,0xAA, +0xDD,0x5F,0x83,0xFF,0xE9,0x13,0x88,0x22,0x40,0x12,0x04,0x20,0x22,0xF0,0x8C,0xAA, +0xDD,0x5F,0xE9,0x0C,0x88,0x43,0x40,0x22,0x08,0x20,0x22,0xF1,0x0C,0xAA,0x44,0x00, +0x00,0x96,0x40,0x00,0x3C,0x07,0x83,0xFF,0xD5,0x07,0x84,0x00,0xD5,0x05,0xE6,0x22, +0xE9,0xAE,0x84,0x00,0xDD,0x9E,0xFC,0x80,0xFC,0x62,0x3F,0xC8,0x01,0x20,0xEA,0x38, +0x81,0x20,0x80,0x02,0x80,0xE2,0x81,0x41,0x49,0xFF,0xFF,0x43,0x54,0xB0,0x00,0xFF, +0x80,0xC0,0x80,0x07,0x49,0xFF,0xFF,0x4A,0x54,0xC0,0x00,0xFF,0x80,0x80,0x46,0xE1, +0x00,0x01,0x58,0xE7,0x0D,0x68,0x84,0x00,0x10,0x0F,0x80,0x0F,0xEA,0xCA,0x46,0xD1, +0x00,0x01,0x58,0xD6,0x8F,0xF4,0xEB,0x37,0x42,0xF6,0x2C,0x24,0xE2,0x0F,0xE8,0x07, +0x97,0xB0,0x97,0x20,0xFF,0x34,0x9B,0xA0,0x97,0xB1,0xD5,0x03,0x44,0x60,0x00,0xFF, +0x46,0x01,0x00,0x07,0x00,0x10,0x02,0x7C,0xE3,0x41,0xE9,0x06,0xB8,0x01,0x85,0x00, +0x8A,0x01,0xE2,0x0A,0xE8,0x09,0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x86, +0x85,0x00,0x40,0x84,0x00,0x06,0xEA,0x39,0x80,0x28,0xEA,0xBF,0x46,0x01,0x00,0x07, +0x00,0x00,0x02,0x7C,0xE3,0x40,0xE9,0x05,0xB9,0x01,0x8A,0x20,0xE2,0x2A,0xE8,0x19, +0xE3,0x20,0xE9,0x05,0xB9,0x00,0x9A,0x08,0xE2,0x09,0xE8,0x13,0xEA,0xCA,0xEB,0x37, +0xE2,0x06,0xE8,0x0F,0x9A,0x30,0xE6,0x03,0xE9,0x0C,0x80,0x07,0x49,0xFF,0xFF,0x0C, +0xC0,0x08,0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x86,0xC0,0x02,0x85,0x01, +0xEA,0x39,0x80,0x28,0xEA,0xBF,0x2E,0x07,0xFD,0x6D,0xC8,0x33,0x46,0x01,0x00,0x07, +0x00,0x10,0x02,0x7C,0xE3,0x21,0xE9,0x05,0xB8,0x00,0x8A,0x01,0xE2,0x09,0xE8,0x08, +0xEA,0x39,0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x86,0xC0,0x02,0x85,0x01,0xEA,0x39, +0x80,0x28,0xEA,0xBF,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x7C,0xE3,0x40,0xE9,0x05, +0xB9,0x01,0x8A,0x20,0xE2,0x2A,0xE8,0x15,0xE3,0x20,0xE9,0x05,0xB9,0x00,0x9A,0x08, +0xE2,0x09,0xE8,0x0F,0xEA,0xCA,0xEB,0x37,0xE2,0x06,0xE8,0x0B,0x8A,0xC0,0xE6,0xC4, +0xE9,0x08,0xEA,0x39,0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x86,0xC0,0x02,0x85,0x01, +0x80,0x08,0xFC,0xE2,0x40,0x00,0x04,0x0E,0x96,0x04,0xDD,0x9E,0x84,0x41,0x40,0x11, +0x04,0x0C,0xA4,0x80,0xFE,0x57,0xAC,0x40,0xDD,0x9E,0x44,0x2E,0xFF,0xFF,0x40,0x11, +0x04,0x0C,0xA4,0x80,0x40,0x11,0x06,0x1E,0xAC,0x40,0xDD,0x9E,0xFC,0x20,0x3E,0x78, +0x01,0x40,0x80,0xC0,0x84,0x20,0x98,0x38,0x10,0x10,0x00,0x6C,0x50,0x03,0x80,0x84, +0x80,0x26,0xF8,0x7E,0x50,0x03,0x80,0x86,0x80,0x26,0xF8,0x7A,0x50,0x03,0x80,0x8A, +0x80,0x26,0xF8,0x76,0x50,0x03,0x80,0x88,0x80,0x26,0xF8,0x72,0xFC,0xA0,0xFC,0x41, +0xEA,0x38,0x84,0x01,0x3C,0x10,0x00,0xE3,0x40,0x00,0x08,0x0C,0x96,0x03,0x80,0xC2, +0xFE,0x47,0x3C,0x18,0x00,0xE3,0x3C,0x10,0x00,0xE2,0x3E,0x98,0x01,0x40,0xFE,0x0F, +0x3C,0x08,0x00,0xE2,0x40,0x04,0x98,0x00,0x84,0x3F,0xEA,0x2F,0x50,0x04,0x80,0x8A, +0x80,0x26,0x80,0xE3,0xF8,0x55,0x50,0x04,0x80,0x88,0x80,0x26,0xF8,0x51,0xC7,0x07, +0x40,0x64,0x98,0x60,0x3B,0x0F,0xC4,0x00,0x3B,0x03,0x44,0x20,0xFC,0xC1,0xFC,0x62, +0xB6,0x1F,0x50,0x9F,0x80,0x08,0x3A,0x14,0x88,0x20,0xEA,0xDB,0x3C,0x83,0xFE,0xDA, +0x46,0x01,0x00,0x07,0x00,0xA0,0x02,0x7C,0xEB,0x3D,0x84,0xC0,0x40,0xC0,0x28,0x01, +0xEA,0xB8,0x50,0xB1,0x80,0x0C,0x40,0xD0,0x28,0x01,0x80,0xE6,0x4C,0x71,0x00,0x1D, +0x80,0x08,0x80,0x27,0xF2,0x81,0xF8,0x21,0x04,0xE5,0x80,0x00,0x05,0xC5,0x80,0x01, +0xF2,0x01,0xC8,0x0D,0xE3,0x4E,0xE8,0x0B,0x40,0xF7,0x30,0x06,0xE8,0x08,0xE3,0x5C, +0xE8,0x06,0x40,0xFE,0x34,0x06,0xE8,0x03,0x8C,0xC1,0x97,0xB0,0x8C,0xE1,0x97,0xF8, +0x50,0xB5,0x80,0x30,0xD5,0xE4,0xC6,0x07,0x80,0x08,0xB4,0x3F,0xF8,0x06,0x84,0xC0, +0x40,0x63,0x00,0x06,0x80,0x08,0xB4,0x3F,0xDD,0x56,0xC0,0x0B,0x3A,0x04,0x84,0x00, +0xB4,0x5F,0x49,0xFF,0xFD,0x1F,0xC0,0x05,0x3E,0x0F,0xFD,0xB4,0xB4,0x3F,0xEA,0x4E, +0x80,0x06,0xFC,0xE2,0xFC,0x63,0x3F,0xCF,0xFE,0x00,0xEB,0x45,0x42,0x10,0x98,0x0B, +0x4E,0x12,0x02,0x43,0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x87,0x5A,0x18,0xFF,0x07, +0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x81,0xD5,0x02,0x96,0x49,0xF1,0x82,0x81,0x80, +0x84,0xC0,0x49,0xFF,0xFC,0x9E,0x44,0xD0,0xFF,0xFF,0x49,0xFF,0xFD,0x25,0x3E,0x78, +0x01,0x40,0x50,0xAF,0x80,0x10,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0D,0x08,0xEA,0x2C, +0xE2,0xC0,0x4E,0xF2,0x01,0xD1,0x81,0x6C,0xDD,0x47,0x42,0xB3,0x00,0x73,0x8D,0x6C, +0xB5,0x2B,0x4C,0x96,0xC0,0x60,0x54,0x93,0x00,0xFF,0xEB,0x28,0x80,0x29,0xDD,0x56, +0xC0,0x1F,0xEA,0xA9,0x80,0x29,0xDD,0x56,0xC8,0x1B,0x98,0x3E,0x00,0x10,0x00,0x60, +0xF2,0x02,0xE2,0x22,0xE8,0x2A,0xE6,0x24,0xE9,0x28,0x46,0x11,0x00,0x07,0x00,0x10, +0x82,0x86,0x10,0x10,0x00,0x78,0x94,0x33,0x98,0x78,0xEA,0x6B,0x3B,0x05,0xC4,0x20, +0xEA,0x2A,0x14,0x15,0x80,0x02,0x88,0x0E,0x3B,0x05,0xC4,0x00,0xD5,0x11,0x98,0x7E, +0x00,0x00,0x80,0x78,0xC0,0x12,0x8E,0x01,0x10,0x00,0x80,0x78,0x94,0x33,0x98,0x78, +0xEA,0x6B,0xEA,0x2A,0x3B,0x05,0xC4,0x20,0x14,0x15,0x80,0x02,0x88,0x0E,0x3B,0x00, +0x44,0x20,0xB8,0x11,0x8C,0x01,0xB8,0x91,0x98,0x3E,0x00,0x00,0x00,0x78,0xC8,0x06, +0xEB,0x44,0x38,0xD3,0x9B,0x0A,0x14,0xD0,0x00,0x01,0x98,0x3E,0x84,0x20,0xEA,0x2F, +0xFA,0x24,0x10,0x10,0x00,0x6C,0x80,0x29,0x3E,0x08,0x01,0xC8,0xEA,0xF2,0x80,0x29, +0x3E,0x08,0x01,0xCA,0xEA,0xF2,0x80,0x29,0x3E,0x08,0x01,0xC4,0xEA,0x4E,0x80,0x29, +0x3E,0x08,0x01,0xC6,0xEA,0x4E,0x3E,0x0F,0xFD,0xB4,0x80,0x29,0xEA,0x4E,0x48,0x00, +0x01,0x67,0x96,0x30,0x3B,0x05,0xC4,0x00,0xF0,0x81,0x3C,0x00,0x00,0xE4,0xF1,0x01, +0x3B,0x05,0x44,0x20,0x81,0x11,0xDD,0x56,0xC0,0x1A,0x14,0x9F,0x80,0x04,0x14,0x8F, +0x80,0x05,0xEA,0x2E,0x49,0xFF,0xFC,0x47,0xC0,0x06,0xEA,0x2E,0xF2,0x01,0x84,0x61, +0xEA,0xF7,0xD5,0x0D,0xEA,0x2E,0xF2,0x01,0x49,0xFF,0xFE,0x18,0xC0,0x08,0xEA,0x2E, +0xF2,0x01,0x84,0x61,0xEA,0xF7,0xEA,0x2E,0x49,0xFF,0xFC,0x1B,0x2E,0x17,0xFD,0x6D, +0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x7C,0xC9,0x07,0xE2,0x09,0xE8,0x10,0xEA,0xDE, +0x9A,0x08,0xE3,0x20,0xD5,0x07,0xE2,0x08,0xE8,0x0A,0x3C,0x1C,0x00,0x49,0x9A,0x08, +0xE3,0x00,0xE8,0x05,0x3E,0x08,0x01,0xC8,0xF1,0x01,0xEA,0x4E,0x14,0x9F,0x80,0x04, +0x14,0x8F,0x80,0x05,0xEA,0x2E,0x49,0xFF,0xFC,0x16,0xEA,0xA9,0xF1,0x01,0xDD,0x56, +0xC0,0x09,0xEA,0x2E,0xF2,0x01,0x49,0xFF,0xFC,0x3D,0xC0,0x04,0xF0,0x01,0x49,0xFF, +0xFE,0x97,0x3C,0x00,0x00,0xE5,0xF1,0x01,0xDD,0x56,0xC0,0x44,0x3A,0x15,0x08,0x00, +0xF0,0x01,0x49,0xFF,0xFD,0x06,0xB9,0x01,0xE2,0x29,0xE8,0x08,0xB9,0x0E,0xE3,0x21, +0xE8,0x05,0x3C,0x13,0xFE,0xD8,0xE3,0x01,0xE9,0x26,0xB9,0x00,0xE2,0x29,0xE8,0x0B, +0xB9,0x14,0xE3,0x21,0xE8,0x08,0x3C,0x23,0xFE,0xDC,0x3C,0x1C,0x00,0x49,0x8A,0x22, +0xE2,0x28,0xE9,0x19,0xB9,0x16,0xE2,0x28,0xE8,0x08,0xB9,0x17,0xE3,0x01,0xE8,0x05, +0x3C,0x13,0xFE,0xD3,0xE3,0x21,0xE9,0x0F,0xB9,0x0C,0xE2,0x28,0xE8,0x0A,0xB9,0x05, +0xE3,0x01,0xE8,0x07,0x3C,0x23,0xFE,0xDB,0xEA,0xDE,0x8A,0x22,0xE2,0x29,0xE9,0x03, +0x96,0x04,0xC0,0x0C,0xEB,0x44,0xB7,0x20,0x14,0x80,0x00,0x01,0xF1,0x01,0x3E,0x08, +0x01,0xC4,0xEA,0xF2,0x98,0x3E,0x84,0x20,0xEA,0x2F,0x3E,0x08,0x01,0xCA,0xF1,0x01, +0xEA,0x4E,0xEB,0x28,0xF1,0x01,0xDD,0x56,0xC0,0x33,0xEA,0xA9,0xF1,0x01,0xDD,0x56, +0xC8,0x2F,0x98,0x7E,0x00,0x00,0x80,0x60,0x5A,0x00,0xFF,0x05,0x8C,0x01,0x10,0x00, +0x80,0x60,0x38,0x03,0x9B,0x02,0xE2,0x09,0xE8,0x04,0x40,0x04,0x80,0x01,0xD5,0x02, +0x8A,0x09,0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x80,0xE2,0x20,0xE9,0x16,0xEB,0x44, +0xA0,0x01,0xE2,0x08,0xE8,0x04,0x40,0x04,0x00,0x01,0xD5,0x02,0x8A,0x08,0xE2,0x20, +0xE9,0x0C,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x87,0x5A,0x00,0xFF,0x0A,0x98,0x7E, +0x00,0x10,0x80,0x60,0xE2,0x01,0xE8,0x04,0xF0,0x01,0x49,0xFF,0xFE,0x19,0xF0,0x01, +0x3A,0x15,0x08,0x00,0x80,0x6C,0x49,0xFF,0xFE,0x54,0x5A,0x08,0x01,0x06,0xEA,0x2E, +0xF2,0x01,0x84,0x60,0xEA,0xF7,0xEB,0x28,0xF1,0x01,0xDD,0x56,0x80,0x80,0xC0,0x1A, +0xF0,0x83,0xEA,0xA9,0xF1,0x01,0xDD,0x56,0xF4,0x03,0xC8,0x14,0x3C,0x13,0xFE,0xD9, +0xE3,0x01,0xE9,0x0D,0xEA,0xB8,0x8A,0x01,0xE2,0x08,0xE9,0x09,0x3C,0x13,0xFE,0xD6, +0xE3,0x21,0xE9,0x05,0xEB,0x3D,0x8A,0x01,0xE2,0x09,0xE8,0x04,0x98,0x3E,0x84,0x20, +0xEA,0x2F,0x98,0x3E,0x00,0x20,0x00,0x6C,0xE6,0x54,0xE8,0x61,0x8C,0x41,0x96,0x90, +0x46,0x11,0x00,0x07,0x10,0x20,0x00,0x6C,0x00,0x10,0x82,0x87,0x00,0x00,0x00,0x60, +0x94,0xF3,0xE2,0x01,0xE8,0x3D,0x5A,0x10,0xFF,0x3C,0x38,0x53,0x9B,0x01,0x3D,0x1C, +0x00,0x48,0x98,0x3B,0x40,0x28,0x94,0x01,0xA4,0x02,0x3D,0x0C,0x00,0x49,0x96,0x91, +0x40,0x18,0x00,0x01,0xE2,0xA2,0x96,0x49,0xE8,0x08,0xE2,0xA0,0xE8,0x06,0xE2,0xA1, +0xE8,0x04,0x86,0x40,0x39,0x23,0x9B,0x0A,0xE2,0x45,0xE8,0x08,0xE2,0x40,0xE8,0x06, +0xE2,0x41,0xE8,0x04,0x8F,0xA1,0x39,0x13,0x9B,0x0A,0xE2,0x05,0xE8,0x0A,0xE2,0x02, +0xE8,0x08,0xE2,0x01,0xE8,0x06,0x41,0x13,0x8C,0x00,0x86,0x40,0x15,0x28,0x80,0x01, +0xE2,0x25,0xE8,0x09,0xE2,0x22,0xE8,0x07,0xE2,0x20,0xE8,0x05,0x98,0x3B,0x8F,0x81, +0x15,0x00,0x00,0x01,0x88,0x67,0xB5,0x23,0x04,0x81,0x80,0x01,0xD5,0x12,0x38,0x03, +0x9B,0x02,0xFA,0xA4,0x40,0x14,0x80,0x01,0xFE,0x54,0x88,0x67,0x40,0x90,0x95,0x36, +0x89,0x20,0xA0,0x19,0x40,0x14,0x00,0x01,0xFE,0x54,0x40,0x80,0x95,0x16,0x89,0x00, +0x98,0x3E,0x84,0x3F,0xB7,0x2B,0x14,0x85,0x80,0x01,0xEA,0x2F,0xC4,0x08,0x84,0x00, +0x14,0xD5,0x80,0x00,0x14,0xD5,0x80,0x01,0x14,0x05,0x80,0x02,0x8C,0xC1,0x97,0xB1, +0x48,0xFF,0xFE,0x2F,0x84,0x00,0x49,0xFF,0xFC,0x14,0x46,0x11,0x00,0x07,0x12,0x00, +0x81,0xDF,0x84,0x00,0x49,0xFF,0xFC,0x1A,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xE0, +0x46,0x01,0x00,0x01,0x00,0x10,0x0D,0x68,0x46,0x01,0x00,0x01,0x58,0x00,0x0F,0xF4, +0x38,0x00,0x06,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xE1,0x3C,0x40,0x00,0xE2, +0x46,0x11,0x00,0x07,0x3C,0x30,0x00,0xE3,0x84,0x00,0x12,0x00,0x81,0xE2,0x46,0x11, +0x00,0x07,0x12,0x00,0x81,0xE3,0x84,0xAA,0x84,0x25,0x84,0x01,0x46,0x21,0x00,0x07, +0x02,0x21,0x01,0xE2,0x97,0xA4,0x42,0x20,0x18,0x73,0x46,0x61,0x00,0x07,0x96,0x91, +0x12,0x23,0x01,0xE2,0x46,0x21,0x00,0x07,0x97,0x9C,0x02,0x21,0x01,0xE3,0x42,0x20, +0x18,0x73,0x8E,0x21,0xFE,0x2C,0x96,0x91,0x46,0x61,0x00,0x07,0x96,0x49,0x12,0x23, +0x01,0xE3,0x92,0x81,0x92,0x61,0x96,0x01,0xC9,0xE2,0x2E,0x00,0x01,0xA0,0x46,0x11, +0x00,0x07,0x12,0x00,0x81,0xE4,0xFC,0xE3,0x3E,0x18,0x01,0x40,0x88,0x01,0x00,0x00, +0x00,0x78,0xDD,0x9E,0xFC,0x60,0x47,0x01,0x00,0x07,0x59,0x08,0x02,0x4E,0x47,0x21, +0x00,0x07,0x59,0x29,0x02,0x1E,0x2E,0x90,0x01,0x2B,0x8C,0x04,0x84,0x80,0xEA,0xB5, +0x46,0x71,0x00,0x01,0x58,0x73,0x8E,0x38,0x81,0x50,0x47,0x11,0x00,0x07,0x59,0x18, +0x82,0x36,0x81,0x72,0x47,0x31,0x00,0x07,0x59,0x39,0x82,0x06,0x96,0x60,0xE2,0x29, +0xE8,0x4B,0x04,0x50,0x7F,0xFF,0xD6,0x45,0xB4,0x20,0x4C,0x13,0x00,0x43,0x40,0x23, +0x90,0x60,0x38,0x53,0x93,0x0A,0xA8,0x51,0xEB,0x45,0xEB,0x34,0xC1,0x1B,0x84,0x41, +0x38,0x89,0x09,0x01,0xE3,0x05,0xE8,0x04,0x8C,0x41,0x96,0x90,0xD5,0xFA,0x9E,0x51, +0x96,0x48,0x38,0x39,0x85,0x01,0x38,0xF5,0x85,0x01,0x38,0x19,0x89,0x01,0x8A,0xAF, +0x8A,0x23,0xFE,0x6C,0x40,0x54,0x3C,0x01,0x40,0x50,0x94,0xB7,0x88,0xA3,0x14,0x50, +0x7F,0xFF,0xEB,0x45,0xEA,0x8B,0xC1,0x1D,0xB4,0x40,0x84,0x61,0x38,0x18,0x0D,0x01, +0xE2,0x22,0xE8,0x04,0x8C,0x61,0x96,0xD8,0xD5,0xFA,0x9F,0x59,0x54,0xC2,0x80,0xFF, +0x38,0xF5,0x31,0x01,0x38,0x58,0xB1,0x01,0x40,0x81,0x3C,0x01,0x38,0x28,0x8D,0x01, +0x8A,0x2F,0x8A,0x45,0x42,0x24,0x08,0x24,0x40,0x11,0x04,0x37,0x88,0x25,0xB6,0x20, +0x8C,0x81,0x8C,0x0C,0xD5,0xB4,0xFC,0xE0,0x3C,0x1D,0xFF,0x82,0x5A,0x18,0x02,0x07, +0x2E,0x37,0xFD,0x54,0x2E,0x47,0xFD,0x6A,0xD5,0x05,0x2E,0x37,0xFD,0x5A,0x2E,0x47, +0xFD,0x1D,0x2E,0x27,0xFD,0x4B,0xC8,0x12,0x5A,0x28,0x01,0x22,0x2E,0x17,0xFE,0x7C, +0x8C,0x21,0x96,0x48,0xE2,0x24,0x3E,0x17,0xFE,0x7C,0xE9,0x19,0x3E,0x07,0xFD,0x4B, +0x3E,0x07,0xFE,0x7C,0x3E,0x07,0xFE,0x7B,0xD5,0x12,0x5A,0x08,0x01,0x11,0xCA,0x0F, +0x2E,0x17,0xFE,0x7B,0x8C,0x21,0x96,0x48,0xE2,0x23,0x3E,0x17,0xFE,0x7B,0xE9,0x07, +0x3E,0x07,0xFD,0x4B,0x3E,0x27,0xFE,0x7C,0x3E,0x27,0xFE,0x7B,0x2E,0x57,0xFD,0x4B, +0xD8,0x06,0x84,0x00,0x3E,0x07,0xFE,0x7C,0x3E,0x07,0xFE,0x7B,0xDD,0x9E,0xFC,0x69, +0x3F,0xCF,0xFE,0x1C,0x2E,0x77,0xFD,0x4B,0xB8,0x00,0x8E,0xE1,0xE6,0x02,0x5C,0x73, +0x80,0x01,0x84,0xC0,0xE9,0x04,0x9F,0x81,0xFF,0x84,0x92,0xC1,0x50,0x8F,0x80,0x3C, +0x80,0x08,0x84,0x20,0x84,0x4C,0xDD,0x42,0x46,0xD1,0x00,0x02,0x58,0xD6,0x80,0xB4, +0x85,0x60,0x46,0x51,0x00,0x01,0x58,0x52,0x8F,0xDC,0x46,0xA1,0x00,0x02,0x58,0xA5, +0x00,0x24,0x81,0x2D,0x80,0x6B,0x81,0x85,0x85,0xDF,0x47,0x31,0x00,0x01,0x59,0x39, +0x8F,0xF4,0xB8,0x00,0xE2,0x60,0xE8,0x68,0x38,0x14,0x0C,0x00,0x51,0x01,0x80,0x01, +0xC9,0x3C,0x3D,0x13,0xFE,0xD1,0x41,0x21,0x84,0x08,0x80,0x90,0x41,0x48,0x84,0x08, +0x41,0x59,0x14,0x00,0x4C,0x40,0x00,0x32,0x41,0x72,0x04,0x08,0x40,0x26,0x5C,0x00, +0x00,0x1A,0x80,0x01,0xA6,0x91,0x8A,0x22,0xEB,0x14,0x96,0x48,0xE6,0x2C,0xE8,0x05, +0xFE,0x4C,0x55,0x60,0x80,0xFF,0xD5,0x03,0x45,0x60,0x00,0x79,0x38,0x26,0x48,0x00, +0x38,0x16,0x5C,0x00,0x9A,0x51,0xEB,0x14,0x96,0x48,0xE6,0x2C,0xE8,0x04,0xFE,0x4C, +0x96,0x48,0xD5,0x03,0x44,0x10,0x00,0x79,0x88,0x36,0x96,0x48,0xE3,0xA1,0xE9,0x07, +0x38,0xE4,0x0C,0x08,0x84,0xE1,0x38,0xE4,0x10,0x08,0xD5,0x05,0x40,0xFA,0x04,0x07, +0xE8,0x02,0x8D,0x61,0x8C,0x81,0xD5,0xCF,0x2E,0x07,0xFF,0xCF,0x38,0x19,0x8E,0x02, +0xE2,0x20,0xE9,0x10,0x80,0x49,0x80,0x6A,0xA0,0x52,0xA0,0x1A,0x88,0x01,0xA8,0x12, +0xB4,0x29,0xB4,0x0A,0x88,0x01,0xB6,0x09,0xA0,0x51,0xA0,0x19,0x88,0x01,0xA8,0x11, +0xD5,0x0F,0x96,0x18,0x15,0x3F,0x80,0x03,0xF5,0x82,0x15,0x0F,0x80,0x01,0x49,0x00, +0x00,0xDF,0x05,0x0F,0x80,0x01,0xF5,0x02,0x05,0x3F,0x80,0x03,0xC8,0xE4,0x80,0x70, +0x8D,0x2C,0x8D,0x4C,0xD5,0x97,0x4C,0xB3,0x40,0x03,0x84,0xE0,0x80,0x07,0x49,0xFF, +0xFF,0x2D,0xBF,0x00,0xCF,0x05,0x3E,0x77,0xFD,0x35,0x3E,0x77,0xFD,0x4A,0x3C,0x9C, +0x00,0x48,0xEA,0x3C,0xF0,0x86,0x3C,0xAC,0x00,0x49,0xEA,0xB0,0xF0,0x87,0x50,0x04, +0xFF,0xFF,0xF0,0x81,0x50,0x05,0x7F,0xFF,0xF0,0x82,0x2E,0x00,0x00,0x14,0x46,0x81, +0x00,0x01,0x58,0x84,0x0D,0x98,0x96,0x44,0xEA,0x8A,0xF0,0x8A,0x2E,0x07,0xFD,0x5C, +0xF0,0x8B,0x2E,0x60,0x00,0x8B,0xF1,0x88,0x54,0x03,0x00,0xF0,0xF0,0x83,0x40,0x05, +0x00,0x01,0xF0,0x8C,0x95,0xB4,0x2E,0x07,0xFD,0x35,0x97,0xB0,0xF0,0x85,0x40,0x04, +0x98,0x01,0xF0,0x8D,0x2E,0x17,0xFD,0x6B,0x2E,0x07,0xFD,0x4A,0xF1,0x89,0xF0,0x84, +0x85,0x60,0x81,0x88,0x4C,0xB3,0x80,0x71,0xB4,0x0D,0x04,0xE6,0x80,0x02,0xF2,0x06, +0x84,0x60,0x42,0x00,0x24,0x69,0xEA,0x68,0x80,0x4E,0x84,0x60,0xEA,0x68,0xF2,0x06, +0x40,0x24,0x88,0x57,0x92,0x41,0xC9,0x04,0xC9,0x05,0xE2,0x40,0xE8,0x03,0x8A,0x02, +0xD5,0x02,0x84,0x00,0xB6,0x08,0x04,0x06,0x80,0x01,0xF2,0x07,0x84,0x60,0x42,0x00, +0x28,0x69,0xEA,0x68,0x80,0x4E,0x84,0x60,0xEA,0x68,0xF2,0x07,0x40,0x25,0x08,0x57, +0x92,0x41,0xC9,0x04,0xC9,0x05,0xE2,0x40,0xE8,0x03,0x8A,0x02,0xD5,0x02,0x84,0x00, +0x14,0x04,0x00,0x01,0xB4,0x08,0xE2,0x09,0xE9,0x03,0xF0,0x01,0xB6,0x08,0x04,0x04, +0x00,0x01,0xE2,0x0A,0xE9,0x04,0xF0,0x02,0x14,0x04,0x00,0x01,0xF0,0x08,0xC0,0x05, +0xB4,0x08,0xF1,0x01,0x9A,0x08,0xB6,0x08,0xB4,0x08,0xF1,0x09,0xEB,0x75,0x58,0x21, +0x0E,0xA4,0x40,0x10,0x04,0x37,0x38,0x11,0x2C,0x08,0xF1,0x0A,0xC1,0x06,0x80,0x68, +0xA0,0x59,0xF2,0x02,0x9A,0x51,0xA8,0x59,0x04,0x14,0x00,0x01,0xF2,0x0B,0xEB,0x67, +0x58,0x31,0x8E,0x98,0x40,0x20,0x88,0x57,0x38,0x21,0xAC,0x08,0xF2,0x03,0xE2,0x41, +0xE8,0x06,0xF2,0x0C,0xE2,0x22,0xE8,0x03,0x84,0x21,0xF1,0x85,0xE2,0xC0,0xE8,0x06, +0xF1,0x0D,0xE2,0x01,0xE8,0x03,0x84,0x01,0xF0,0x84,0x8D,0x61,0x8D,0x08,0x50,0xD6, +0x80,0x0C,0x48,0xFF,0xFF,0x91,0x00,0x1F,0x80,0x14,0x3E,0x17,0xFD,0x35,0x00,0x1F, +0x80,0x10,0x3E,0x17,0xFD,0x4A,0x46,0x01,0x00,0x01,0x02,0x00,0x06,0xCC,0x46,0x11, +0x00,0x07,0x12,0x00,0x87,0xAD,0x46,0x01,0x00,0x01,0x02,0x00,0x06,0xCE,0x46,0x11, +0x00,0x07,0x12,0x00,0x87,0xAE,0xEA,0x29,0xE6,0xEC,0xE8,0x08,0x40,0x16,0x1C,0x60, +0x38,0x06,0x1F,0x0A,0xA8,0x09,0x8C,0xE1,0xD5,0xF8,0xFC,0xE9,0x46,0x31,0x00,0x01, +0x58,0x31,0x8F,0xDC,0x40,0x41,0x80,0x20,0x2E,0x20,0x01,0x28,0xA7,0x21,0x8E,0x41, +0xE6,0x82,0x96,0x90,0x2E,0x10,0x01,0x29,0xE9,0x0C,0xE2,0x44,0xE9,0x0A,0x38,0x01, +0x81,0x00,0xE6,0x02,0xE9,0x06,0x8E,0x21,0x96,0x48,0x40,0x00,0x80,0x06,0xDD,0x9E, +0x84,0x01,0xDD,0x9E,0xFC,0x00,0x3F,0xCF,0xFE,0x08,0x2E,0x07,0xFD,0x5D,0xC0,0x05, +0x84,0x00,0xB8,0x85,0x48,0x00,0x00,0x83,0xBE,0x0F,0xCE,0x34,0xB9,0x05,0x8E,0x21, +0xE6,0x23,0xE8,0x30,0xDD,0x59,0x5A,0x08,0x01,0x0C,0x80,0x06,0x49,0xFF,0xFF,0xD0, +0xC0,0x04,0x2E,0x07,0xFF,0xB7,0xD5,0x06,0x2E,0x07,0xFF,0xB6,0xD5,0x03,0x2E,0x07, +0xFF,0xBA,0xB9,0x00,0x5A,0x10,0x03,0x05,0xEA,0xBB,0x5A,0x18,0x01,0x06,0x2E,0x17, +0xFF,0xB8,0x88,0x01,0x96,0x01,0xDD,0x49,0xEA,0x94,0xC1,0x0B,0x84,0x00,0x49,0xFF, +0xFF,0xB7,0x2E,0x10,0x00,0x54,0xC0,0x04,0x40,0x00,0x84,0x09,0xD5,0x02,0x96,0x09, +0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x2F,0x92,0x21,0xE2,0x20,0xE8,0x03,0x84,0x00, +0xB8,0x85,0xEA,0x96,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x2F,0xC8,0x07,0x3C,0x03, +0xFE,0xCF,0x40,0x00,0x80,0x17,0x3E,0x07,0xFD,0x46,0xB8,0x05,0x92,0x21,0x49,0xFF, +0xEA,0x03,0xB8,0x05,0xE6,0x02,0xE9,0x3A,0xB9,0x0F,0xE2,0x20,0xE8,0x37,0x3C,0x63, +0xFE,0xD2,0xEB,0x08,0xC8,0x04,0x40,0x13,0x04,0x09,0xD5,0x03,0x94,0x71,0x96,0x49, +0xEA,0x49,0xC0,0x09,0x2E,0x07,0xFF,0xB4,0xDD,0x49,0x80,0xC0,0x2E,0x07,0xFF,0xB5, +0xDD,0x49,0x80,0x20,0xEA,0x45,0xC0,0x0A,0x2E,0x00,0x00,0x61,0xDD,0x49,0x80,0xC0, +0x2E,0x00,0x00,0x61,0xDD,0x49,0x94,0x01,0x96,0x41,0xBA,0x0F,0xBB,0x05,0x84,0x8C, +0x46,0x51,0x00,0x02,0x58,0x52,0x80,0xB4,0xE2,0x43,0xE8,0x10,0x80,0x05,0x42,0x01, +0x10,0x73,0xE6,0x42,0xA0,0x02,0x82,0x01,0x92,0x01,0x41,0x03,0x3C,0x1B,0xE2,0x10, +0xE8,0x03,0xBA,0x85,0xD5,0x03,0x8C,0x41,0xD5,0xF0,0xFC,0x80,0xFC,0x60,0x2E,0x07, +0xFD,0x60,0x5A,0x08,0x01,0x0D,0x2E,0x07,0xFD,0x37,0xE6,0x15,0xE9,0x05,0x84,0x00, +0x3E,0x07,0xFD,0x60,0xD5,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x37,0x3C,0x03,0xFE,0xC4, +0xE6,0x1F,0x2F,0x30,0x01,0x2B,0xE8,0x14,0x2E,0x47,0xFD,0x60,0x2E,0x37,0xFD,0x37, +0x84,0x00,0xEB,0x78,0x58,0x10,0x8C,0xCC,0x46,0x51,0x00,0x01,0x58,0x52,0x8D,0x98, +0xEA,0xB5,0x80,0xE0,0x47,0x01,0x00,0x01,0x59,0x08,0x0D,0x74,0xD5,0x1B,0xEB,0x3B, +0xC8,0xEC,0xEB,0x78,0x58,0x10,0x8C,0x6C,0xEA,0xC7,0xE2,0x13,0xE8,0xE6,0x40,0x30, +0x80,0x60,0x38,0x20,0x83,0x0A,0xA8,0x99,0x8C,0x01,0xD5,0xF8,0x38,0x22,0x83,0x02, +0x4C,0x23,0x40,0x13,0xA6,0x88,0x8E,0x41,0xE6,0x53,0xE9,0x07,0xAF,0xC8,0x8C,0x01, +0x8C,0x21,0xE2,0x13,0xE9,0xF4,0xD5,0x0E,0x38,0x28,0x00,0x00,0x5A,0x28,0x01,0xF8, +0x80,0x82,0x84,0x60,0xD5,0xF4,0xA6,0x88,0x5A,0x20,0xFF,0xF3,0x8C,0x41,0xAE,0x88, +0xD5,0xEF,0x3E,0x47,0xFD,0x60,0x46,0xA1,0x00,0x01,0x58,0xA5,0x0B,0xA0,0x3E,0x37, +0xFD,0x37,0xEB,0x78,0x58,0x10,0x8B,0xAC,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x98, +0x46,0x71,0x00,0x01,0x58,0x73,0x8D,0x74,0x80,0xCA,0x45,0x20,0xFF,0xFF,0x85,0x20, +0x85,0x61,0x40,0x03,0x28,0x01,0xE2,0x13,0xE8,0x50,0xB4,0x43,0x4C,0x29,0x40,0x08, +0xB7,0xC1,0x10,0xB3,0x80,0x00,0x10,0xB3,0x00,0x00,0xD5,0x26,0xA6,0x38,0x5A,0x08, +0x01,0x24,0xB4,0xA1,0x4C,0x59,0x40,0x06,0x3B,0x01,0xC4,0x00,0xEA,0xEA,0xD5,0x1C, +0xE2,0xA2,0xE8,0x03,0x9A,0x15,0xD5,0x02,0x9A,0x2A,0xA1,0x59,0xA1,0x09,0xE2,0x85, +0xE8,0x03,0x9B,0x2C,0xD5,0x02,0x8A,0x85,0xFE,0x04,0x42,0x02,0x10,0x73,0x81,0xE0, +0x2E,0x50,0x01,0x32,0x2E,0x40,0x01,0x33,0xFF,0x2C,0xE2,0x8F,0xE8,0x05,0x10,0x93, +0x80,0x00,0x3E,0x97,0xFD,0x60,0xB4,0xA1,0x4C,0x59,0x00,0x1B,0x4C,0x29,0x00,0x19, +0xA6,0x30,0x5A,0x08,0x01,0x16,0xE2,0xA2,0xE8,0x03,0x9B,0x55,0xD5,0x02,0x8A,0xA2, +0xA0,0x99,0xA0,0x09,0xE2,0x02,0xE8,0x03,0x9A,0x10,0xD5,0x02,0x8A,0x02,0xFF,0x6C, +0x42,0x50,0x00,0x73,0x5C,0xF2,0xB8,0x41,0xE9,0x03,0x10,0x93,0x00,0x00,0x8C,0xC1, +0x8C,0x28,0x8C,0x68,0x8C,0xE1,0xD5,0xAE,0xFC,0xE0,0xFC,0x61,0x3F,0xCF,0xFE,0x44, +0x46,0x71,0x00,0x01,0x58,0x73,0x8D,0x98,0x46,0xB1,0x00,0x01,0x58,0xB5,0x8B,0x88, +0x46,0x91,0x00,0x01,0x58,0x94,0x8B,0x94,0x84,0xC0,0x81,0x47,0x44,0x80,0xFF,0xFF, +0x46,0xC1,0x00,0x01,0x58,0xC6,0x0D,0x80,0x44,0xDF,0xFF,0x80,0x46,0xE1,0x00,0x01, +0x58,0xE7,0x0D,0x08,0x46,0x31,0x00,0x01,0x58,0x31,0x8C,0x6C,0x44,0x10,0xFF,0xFE, +0xEA,0x2C,0xE2,0xC0,0xE8,0x52,0x96,0x30,0xF1,0x81,0xB6,0x7F,0x49,0xFF,0xF6,0x2D, +0xB4,0x7F,0xF1,0x01,0x5A,0x08,0x01,0x05,0x2E,0x07,0xFD,0x67,0xEA,0x91,0xB4,0xA7, +0x4C,0x54,0x40,0x1C,0x00,0x04,0x80,0x00,0x2E,0x27,0xFD,0x67,0xE2,0x02,0xE8,0x06, +0x8C,0x01,0xEA,0x91,0xB6,0x27,0xA8,0x79,0xD5,0x33,0x84,0x00,0x38,0x57,0x1B,0x02, +0xEA,0xC0,0x84,0x1F,0xEA,0x91,0x94,0x33,0x4C,0x54,0x00,0x2B,0x98,0x98,0x88,0x0E, +0x3B,0x00,0x44,0x00,0xEA,0x9E,0xD5,0x24,0xEA,0xE6,0xC0,0x0E,0xC6,0x0D,0x46,0x01, +0x00,0x01,0x04,0x00,0x03,0x36,0x5C,0xF0,0x00,0xC9,0xE9,0x06,0x2E,0x27,0xFF,0xFB, +0x3E,0xD7,0xFD,0x58,0xD5,0x03,0x2E,0x27,0xFD,0x23,0x00,0x05,0x80,0x00,0xE2,0x02, +0xE8,0x0B,0x8C,0x01,0xEA,0xC0,0x84,0x5F,0x40,0x06,0x18,0x20,0xB7,0x07,0x14,0x83, +0x80,0x01,0xAE,0x81,0xD5,0x05,0x84,0x00,0xEA,0x91,0x84,0x1F,0xEA,0xC0,0x8C,0xC1, +0x8D,0x61,0x8D,0x21,0x8C,0xE8,0xD5,0xAD,0x84,0xC0,0xBE,0x80,0x84,0x3F,0x46,0x01, +0x00,0x01,0x58,0x00,0x0D,0x80,0xFA,0x48,0xDD,0x42,0x80,0x06,0x46,0x41,0x00,0x01, +0x58,0x42,0x0D,0x98,0xEA,0xB5,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x08,0x46,0x71, +0x00,0x01,0x58,0x73,0x8C,0xD8,0x82,0x40,0x45,0x30,0xFF,0xFE,0x46,0x91,0x00,0x01, +0x58,0x94,0x8D,0x80,0x85,0x7E,0x38,0x55,0x02,0x02,0x94,0x42,0xD6,0x0F,0xBA,0x00, +0x8C,0x41,0xBA,0x80,0x4C,0x59,0xC0,0x0D,0x98,0xA1,0x88,0x23,0xEA,0x6B,0x40,0x10, +0x24,0x00,0xEA,0x9E,0x10,0xB0,0x80,0x01,0xD5,0x07,0x39,0x23,0x81,0x0A,0x98,0x99, +0x88,0x2A,0xEA,0x6B,0xEA,0x9E,0x8C,0x02,0x5A,0x08,0x18,0xE7,0x49,0xFF,0xFE,0x90, +0xFC,0xE1,0xFC,0x60,0x3F,0xCF,0xFE,0x1C,0xB8,0x0B,0xC0,0x03,0x84,0x00,0xD5,0x04, +0x2E,0x07,0xFF,0xA5,0x92,0x04,0x3E,0x07,0xFD,0x2B,0xEB,0x16,0xB9,0x04,0x8C,0x01, +0xE2,0x20,0x46,0x21,0x00,0x01,0x58,0x21,0x09,0x48,0x2E,0x90,0x01,0x2B,0xE9,0x21, +0x84,0xEC,0x42,0x60,0x1C,0x24,0x84,0x74,0x84,0xA0,0x46,0xB1,0x00,0x01,0x58,0xB5, +0x8D,0x98,0xB8,0x84,0x88,0x46,0xEB,0x78,0x58,0x10,0x89,0x54,0x43,0x30,0x0C,0x24, +0x88,0xC3,0x81,0x05,0x46,0xA1,0x00,0x01,0x58,0xA5,0x0D,0x68,0x46,0xC1,0x00,0x02, +0x58,0xC6,0x00,0xB4,0x3E,0xD8,0x02,0xD4,0xEA,0x89,0x81,0xCB,0x86,0x87,0xD5,0x4E, +0x84,0x60,0x44,0x60,0x00,0x30,0xE0,0x69,0xE8,0xDC,0x80,0x22,0x42,0x11,0x98,0x73, +0x84,0x81,0x8C,0x2C,0xE0,0x80,0x8C,0x2C,0xE8,0x09,0x50,0x50,0xFF,0xF4,0x3B,0x02, +0xC8,0x00,0x8C,0x81,0x3B,0x00,0xC8,0x20,0xD5,0xF6,0x8C,0x61,0xD5,0xED,0x50,0xF1, +0xFF,0xF4,0x3B,0x01,0xC8,0x00,0x51,0x5A,0x80,0x01,0x3B,0x07,0xC8,0x20,0x40,0xFA, +0x80,0x07,0x8C,0x6C,0xE9,0xF5,0x2E,0x37,0xFF,0xA4,0x43,0x21,0x98,0x0B,0x38,0x35, +0x14,0x00,0x4F,0x22,0x00,0x29,0x38,0x36,0x8C,0x10,0x39,0x15,0x97,0x02,0x41,0x02, +0x8C,0x08,0x4D,0x12,0x00,0x2B,0x2F,0x17,0xFD,0x3A,0xE3,0xA3,0x40,0x38,0xBC,0x1B, +0x89,0x8E,0x3B,0x08,0x44,0x00,0xEA,0x9E,0x4F,0x23,0x00,0x07,0x05,0x01,0x00,0x02, +0x42,0x3A,0x40,0x73,0x92,0x63,0xA8,0xD2,0x04,0x30,0xFF,0xFD,0x4C,0x32,0x00,0x18, +0x8C,0xA1,0x50,0x10,0x80,0x30,0x50,0x21,0x00,0x30,0xE0,0xA9,0xE8,0x2F,0x80,0x61, +0x86,0xA0,0xD5,0xC6,0x81,0xEC,0x42,0xF1,0x9C,0x73,0x80,0x6F,0x2E,0xF7,0xFD,0x52, +0xA0,0xDA,0x40,0x31,0xBC,0x0D,0xD5,0xD2,0x84,0x60,0xD5,0xDB,0xB4,0x61,0x4C,0x32, +0x3F,0xE9,0x5A,0x00,0x01,0xE7,0xBB,0x00,0xE6,0x63,0xE8,0x05,0xA0,0xCB,0x4C,0x32, +0x40,0x5A,0xD5,0x20,0xA0,0xCB,0x4C,0x32,0x00,0x07,0x5A,0x08,0x03,0xF9,0xA0,0xCE, +0x4C,0x32,0x7F,0xF6,0x80,0x61,0x86,0x01,0x8D,0x81,0xE0,0x10,0xB6,0x83,0xA9,0x19, +0x14,0x81,0x80,0x02,0x8C,0x6C,0xE8,0xF9,0xD5,0xEA,0x84,0xC0,0xEA,0x2C,0xE0,0xC0, +0xE8,0x45,0x96,0x30,0xEB,0x78,0x58,0x10,0x89,0x48,0x49,0xFF,0xF3,0xEA,0x8C,0xC1, +0xD5,0xF6,0x84,0x61,0x5A,0x08,0x03,0xBE,0x05,0x00,0x80,0x06,0x4D,0x02,0x3F,0xBA, +0xCB,0xB8,0xB4,0x61,0xB5,0xA2,0x05,0x01,0x00,0x01,0x41,0x58,0x8C,0x01,0xA0,0xC9, +0x40,0xF8,0x0C,0x01,0x2E,0x30,0x01,0x32,0x42,0xF7,0xBC,0x24,0x41,0x21,0x88,0x09, +0x2E,0x30,0x01,0x33,0x42,0xFA,0xD4,0x73,0x92,0x62,0xFE,0xDC,0x42,0x39,0x48,0x73, +0x40,0xF7,0x8C,0x07,0xE8,0x9E,0x41,0x21,0x4C,0x00,0x38,0x39,0x18,0x02,0x89,0xC6, +0x89,0xA3,0x04,0x39,0x00,0x01,0x93,0xA1,0x88,0x70,0x92,0x61,0x82,0x01,0x86,0x41, +0x8D,0xC1,0xE0,0x12,0xB7,0xB0,0x14,0x38,0x00,0x01,0x8D,0x8C,0xE8,0xFA,0x48,0xFF, +0xFF,0x89,0x84,0x60,0x5A,0x00,0x03,0xCA,0xD5,0xCD,0xFC,0xE0,0xFC,0x64,0x81,0x80, +0x84,0x00,0x12,0x06,0x00,0x48,0x10,0x06,0x00,0x92,0x2E,0x17,0xFD,0x4B,0x2E,0x47, +0xFF,0xC2,0x2E,0x07,0xFF,0xC1,0xC9,0x05,0xEA,0xBB,0xC9,0x03,0xEA,0x94,0xC1,0x06, +0x58,0x12,0x00,0x0F,0xB6,0x3F,0x92,0x04,0xD5,0x05,0x97,0x1F,0x94,0x63,0xB6,0x3F, +0x96,0x1F,0x8C,0x01,0x85,0x48,0x42,0xA0,0x28,0x01,0x2E,0x07,0xFD,0x1F,0xE2,0x0A, +0xE8,0x03,0x8C,0x01,0xD5,0x04,0xE3,0x40,0xE8,0x03,0x8E,0x01,0xEA,0xEB,0x40,0x05, +0x04,0x09,0x96,0x00,0xF0,0x82,0x84,0xC0,0x46,0x81,0x00,0x01,0x58,0x84,0x06,0x30, +0x3C,0xDD,0xFE,0xDB,0x46,0xE1,0x00,0x01,0x58,0xE7,0x06,0x24,0xEA,0x2C,0xE2,0xC0, +0x4E,0xF2,0x01,0x5A,0x94,0x73,0x46,0x01,0x00,0x01,0x58,0x00,0x0E,0x38,0x39,0x10, +0x1B,0x02,0x88,0x01,0xF1,0x81,0xA1,0x41,0xEB,0x78,0x58,0x10,0x89,0x48,0xDD,0x47, +0xEB,0x0D,0x38,0x44,0x18,0x00,0x80,0x01,0x8C,0x0C,0xA1,0xCB,0x04,0x90,0x00,0x01, +0xEA,0x29,0x46,0x21,0x00,0x01,0x58,0x21,0x06,0x3C,0x4C,0x70,0x40,0x0D,0x4C,0x93, +0xC0,0x0B,0x44,0x0F,0xFF,0xB4,0x38,0x07,0x18,0x08,0x84,0x00,0x38,0x01,0x18,0x08, +0x48,0x00,0x01,0x1D,0x00,0x06,0x00,0x92,0x84,0x21,0x8C,0x01,0x10,0x06,0x00,0x92, +0x02,0x06,0x00,0x48,0x40,0x30,0x98,0x0C,0xFE,0x1F,0x12,0x06,0x00,0x48,0x38,0x01, +0x18,0x00,0x47,0xC1,0x00,0x01,0x59,0xCE,0x06,0x48,0xC8,0x14,0x46,0x21,0x00,0x01, +0x58,0x21,0x06,0x3C,0x38,0x11,0x18,0x08,0x94,0xB6,0x40,0x1E,0x00,0x00,0x38,0x70, +0x88,0x0A,0x8C,0x08,0x88,0x22,0x14,0x90,0x80,0x01,0x5A,0x08,0x40,0xF8,0x48,0x00, +0x00,0xF8,0xE3,0xA7,0xE8,0x04,0x41,0x33,0xC4,0x01,0xD5,0x03,0x41,0x38,0x9C,0x01, +0xE2,0xA9,0xE8,0x04,0x41,0x24,0x94,0x01,0xD5,0x03,0x41,0x22,0xA4,0x01,0x42,0x19, +0xCC,0x24,0x42,0x19,0x48,0x73,0x38,0x07,0x18,0x00,0x92,0x21,0xC8,0x06,0x2E,0x27, +0xFF,0xBB,0x2E,0x37,0xFF,0xBC,0xD5,0x05,0x2E,0x27,0xFF,0xBF,0x2E,0x37,0xFF,0xC0, +0x2E,0xF7,0xFD,0x6E,0x47,0x61,0x00,0x01,0x59,0x6B,0x0D,0x68,0xE9,0x10,0x38,0xFB, +0x18,0x00,0x47,0x01,0x00,0x01,0x59,0x08,0x0F,0xF4,0x2E,0xB7,0xFD,0x49,0x39,0x08, +0x3E,0x02,0xE3,0x70,0xE9,0x04,0x2E,0xF7,0xFD,0x68,0xE8,0x07,0x86,0x03,0x42,0x21, +0x40,0x24,0xEA,0xEF,0x96,0x90,0x96,0xD8,0xC8,0x15,0xE2,0xE2,0xE9,0x09,0x3D,0x0C, +0x00,0x48,0x8F,0x81,0x8B,0x82,0xE3,0x87,0x40,0x20,0x3C,0x1B,0xD5,0x02,0x80,0x40, +0xE3,0x23,0xE9,0x07,0x3D,0x0C,0x00,0x49,0x8F,0x81,0x8B,0x83,0xE3,0x89,0xE8,0x02, +0x84,0x60,0x46,0xB1,0x00,0x02,0x58,0xB5,0x80,0xB4,0x38,0xFB,0x18,0x00,0x86,0x0C, +0x82,0x8B,0x43,0x47,0xC0,0x73,0x04,0xFA,0x00,0x02,0xE9,0x02,0xC0,0x0F,0xE3,0xE2, +0xE8,0x03,0xE3,0xC3,0xE9,0x09,0x84,0x00,0x46,0x21,0x00,0x01,0x58,0x21,0x06,0x24, +0x38,0x01,0x18,0x08,0xD5,0x03,0x81,0x25,0x80,0xF1,0xB4,0x1F,0x92,0x22,0x40,0x10, +0x80,0x37,0x8C,0x21,0xE6,0x31,0xE9,0x02,0xFA,0x20,0xB4,0x1F,0xC0,0x41,0xEB,0x16, +0xC0,0x09,0xDD,0x47,0x80,0x4D,0x42,0x23,0x00,0x73,0xEA,0x29,0xA0,0x96,0x4C,0x20, +0x00,0x38,0x80,0x06,0x15,0x6F,0x80,0x07,0xF1,0x86,0xF5,0x85,0x15,0x1F,0x80,0x04, +0xF4,0x83,0xF8,0x41,0xF4,0x03,0x05,0x1F,0x80,0x04,0xF5,0x05,0xF1,0x06,0x05,0x6F, +0x80,0x07,0xC8,0x26,0x38,0x2B,0x18,0x00,0x84,0x0C,0x42,0xB1,0x00,0x73,0x04,0x05, +0x80,0x02,0xC0,0x1E,0x52,0x00,0x80,0x10,0x42,0x20,0x44,0x24,0x42,0x23,0x84,0x73, +0x95,0xFC,0x82,0x22,0x3C,0x2C,0x00,0x48,0xFF,0x44,0x40,0x73,0x88,0xF7,0x42,0x54, +0x84,0x73,0x40,0x04,0x90,0x08,0x3C,0x9C,0x00,0x49,0x97,0xF8,0x40,0x00,0x24,0x17, +0x96,0x00,0x89,0xA7,0x88,0xA0,0x40,0x78,0x90,0x09,0x40,0x92,0x90,0x09,0xF0,0x01, +0xE6,0x2D,0x88,0x04,0x40,0x0E,0x00,0x60,0xB6,0xE0,0x14,0x90,0x00,0x01,0xE9,0x09, +0xDD,0x47,0x80,0x2D,0xEB,0x0D,0xEA,0x29,0xA1,0x4E,0xD8,0x03,0xEB,0x16,0xC8,0x23, +0x80,0x06,0xF4,0x83,0x49,0xFF,0xF3,0x51,0xF4,0x03,0xC8,0x1D,0x80,0xE0,0x80,0xA0, +0x4C,0x55,0x00,0x13,0xF1,0x01,0x88,0x24,0x38,0x2E,0x07,0x02,0x40,0x1E,0x04,0x60, +0xA0,0x49,0x88,0xE2,0x88,0x01,0xC4,0x04,0x9E,0x61,0x97,0x08,0xD5,0x02,0x84,0x87, +0x8C,0xA1,0x97,0x68,0xD5,0xEE,0xF1,0x02,0x88,0xE1,0x88,0x01,0x40,0x73,0xA8,0xF7, +0x40,0x90,0x29,0x37,0x46,0x01,0x00,0x01,0x58,0x00,0x06,0x30,0x38,0x00,0x18,0x00, +0x8C,0x01,0x96,0x00,0x5A,0x08,0x08,0x03,0x84,0x00,0x38,0x04,0x18,0x08,0x84,0x0C, +0x80,0x2C,0xEB,0x0D,0x80,0x4D,0xB6,0xE1,0x14,0x90,0x80,0x01,0x80,0x01,0x44,0x10, +0x00,0x30,0x42,0x23,0x04,0x73,0x8C,0xC1,0xA0,0x55,0x10,0x10,0x00,0x08,0x97,0xB0, +0x48,0xFF,0xFE,0xA6,0x3E,0xA7,0xFD,0x1F,0xFC,0xE4,0xEA,0x69,0x42,0x00,0x18,0x0B, +0x4E,0x02,0x01,0x69,0x84,0x00,0x3E,0x18,0x02,0xD4,0x84,0x41,0x38,0x20,0x80,0x08, +0x8C,0x01,0x5A,0x08,0x0C,0xFD,0xFC,0x66,0xEB,0x3B,0xF0,0x83,0xEB,0x3D,0xF0,0x81, +0xEA,0x3C,0xF0,0x84,0xEA,0xB8,0xF0,0x82,0xEA,0xB0,0xF0,0x85,0x2E,0x00,0x01,0x02, +0xF0,0x86,0x2E,0x00,0x01,0x03,0x85,0x80,0xF0,0x87,0x3E,0x68,0x02,0xD4,0x3E,0xA8, +0x01,0xCC,0x84,0xE1,0x81,0x6C,0xF0,0x03,0x4C,0xB0,0x01,0x44,0x00,0x15,0x00,0x00, +0x01,0x05,0x00,0x01,0x01,0x15,0x00,0x02,0x40,0x00,0xC0,0x00,0x40,0x80,0x04,0x0A, +0x00,0x05,0x00,0x03,0x40,0x28,0x80,0x00,0x41,0x41,0x04,0x0A,0xC1,0x08,0x4F,0x02, +0x00,0x09,0x4F,0x12,0x00,0x09,0x40,0x70,0x00,0x1A,0xD5,0x06,0x80,0xE1,0xD5,0x04, +0x80,0xF0,0xD5,0x02,0x80,0xF1,0x44,0x20,0x00,0x48,0x42,0x40,0x08,0x24,0x84,0x60, +0x40,0x42,0x04,0x20,0x44,0x20,0x00,0x4A,0x42,0x43,0x88,0x75,0x80,0xA1,0x82,0x63, +0x81,0x23,0x82,0x43,0x83,0x03,0xE3,0x85,0xE9,0x24,0x41,0x51,0x90,0x00,0x46,0x21, +0x00,0x02,0x58,0x21,0x01,0x44,0x41,0x5A,0x88,0x00,0x81,0xA0,0x85,0xC0,0x40,0x22, +0xA0,0x06,0xE3,0xAD,0xE9,0x13,0x40,0xFA,0xB8,0x00,0x22,0xF7,0x8C,0xAA,0xC2,0x05, +0x89,0xCF,0x43,0x37,0x94,0x73,0xD5,0x05,0x41,0x8C,0x3C,0x00,0x42,0x97,0x94,0x73, +0x50,0xD6,0x80,0x01,0x50,0xE7,0x00,0x48,0xD5,0xED,0x8C,0xA1,0x8C,0x62,0xD5,0xDC, +0x84,0x60,0x83,0x83,0x81,0xA3,0x81,0xC3,0x81,0x03,0xE3,0x81,0xE9,0x23,0x99,0x5C, +0x46,0x21,0x00,0x02,0x58,0x21,0x01,0x44,0x41,0x62,0x88,0x00,0x86,0xA0,0x80,0xA0, +0xE3,0xA5,0xE9,0x15,0xE2,0xB4,0x41,0x7B,0x54,0x00,0xE8,0x07,0x22,0xFB,0x8C,0xAA, +0x89,0x0F,0x42,0xD7,0x94,0x73,0xD5,0x07,0x22,0xFB,0x8C,0xAA,0x40,0xE7,0x3C,0x00, +0x43,0xC7,0x94,0x73,0x8C,0xA1,0x51,0x5A,0x80,0x48,0xD5,0xEB,0x8C,0x21,0x8C,0x62, +0xD5,0xDD,0xF0,0x01,0xF1,0x04,0x80,0x58,0x40,0x40,0x04,0x97,0x84,0x60,0x42,0x04, +0x90,0x69,0x15,0x3F,0x80,0x0B,0x15,0x2F,0x80,0x0A,0xF4,0x88,0xF8,0x36,0xF4,0x08, +0x81,0x20,0x40,0x52,0x04,0x09,0x05,0x2F,0x80,0x0A,0x05,0x3F,0x80,0x0B,0xC9,0x05, +0xC9,0x03,0xE2,0xA0,0xE9,0x02,0x85,0x20,0x42,0x09,0x90,0x69,0x80,0x52,0x84,0x60, +0xF5,0x88,0xF8,0x23,0x80,0x80,0xF5,0x08,0xC9,0x05,0xC9,0x03,0xE2,0xA0,0xE9,0x02, +0x84,0x80,0xF0,0x02,0xF1,0x05,0x80,0x4E,0x40,0x50,0x04,0xB7,0x84,0x60,0x42,0x0E, +0x14,0x69,0xF4,0x8A,0xF5,0x88,0xF8,0x11,0xF5,0x08,0x81,0xC0,0x41,0xC2,0x84,0x09, +0xF4,0x0A,0xC9,0x06,0xC9,0x04,0x40,0xFE,0x00,0x06,0xE9,0x02,0x85,0xC0,0x80,0x48, +0x42,0x06,0x94,0x69,0x84,0x60,0xF4,0x88,0xEA,0x68,0x80,0x40,0xF4,0x08,0xC9,0x05, +0xC9,0x06,0x40,0xFE,0x00,0x06,0xE8,0x03,0x80,0x02,0xD5,0x02,0x84,0x00,0x4E,0x92, +0x00,0x0C,0xC4,0x0A,0xE2,0x89,0xE8,0x04,0x40,0x44,0x90,0x01,0xD5,0x02,0x8A,0x89, +0x40,0x92,0x00,0x13,0xD5,0x02,0x85,0x21,0x4E,0xE2,0x00,0x0B,0xC0,0x09,0xE2,0x0E, +0xE8,0x04,0x40,0x07,0x00,0x01,0xD5,0x02,0x8A,0x0E,0x96,0x01,0xD5,0x02,0x84,0x01, +0xF8,0x11,0xF8,0x12,0xF8,0x1E,0x84,0x40,0x46,0x34,0x05,0x0C,0xF8,0x1A,0xFD,0x20, +0xF0,0x88,0xF0,0x02,0xF5,0x89,0xF8,0x1B,0xF8,0x1C,0xF8,0x20,0xF8,0x21,0x81,0x00, +0x80,0x09,0x49,0x00,0x2C,0xF7,0x46,0x2F,0x5C,0x28,0x46,0x34,0x00,0x15,0x50,0x21, +0x0F,0x5C,0x50,0x31,0x8C,0x28,0x83,0xFF,0xF8,0x04,0x84,0x40,0x46,0x34,0x06,0x28, +0x49,0x00,0x2A,0x6C,0xFD,0x20,0xF0,0x88,0xF0,0x01,0xF5,0x89,0x49,0x00,0x2D,0x08, +0xF4,0x08,0xF5,0x09,0xFD,0x10,0xFD,0x02,0x83,0xFF,0x49,0x00,0x2B,0x4F,0x49,0x00, +0x2C,0xB3,0xE3,0x00,0x40,0x04,0x3C,0x1A,0x96,0x42,0xE4,0x34,0xE9,0x02,0x85,0x81, +0xEB,0x78,0x58,0x10,0x8F,0xF4,0x88,0x0C,0x38,0x10,0xAE,0x02,0x96,0x02,0xE2,0x20, +0x80,0x46,0xAE,0x30,0xE8,0x02,0xAE,0x70,0xF0,0x06,0xE2,0x20,0xE9,0x0A,0x46,0x01, +0x00,0x01,0x58,0x00,0x0C,0xCC,0x38,0x00,0x2C,0x00,0xF1,0x07,0xE2,0x01,0xE8,0x05, +0x20,0x03,0x00,0x00,0x90,0x01,0xAE,0x30,0x20,0x01,0x00,0x00,0x8C,0xC1,0x4E,0x06, +0x00,0x05,0x84,0x01,0x10,0x03,0x7F,0xFF,0x8D,0x61,0x8D,0x44,0x48,0xFF,0xFE,0xBD, +0xFC,0xE6,0xDD,0x9E,0xFC,0x60,0x3F,0xCF,0xFE,0x08,0x46,0x01,0x00,0x01,0x58,0x00, +0x00,0x28,0x84,0x20,0xFA,0x54,0xDD,0x42,0xEA,0x6A,0xEA,0xF0,0xC0,0x1F,0xDD,0x59, +0x5A,0x08,0x01,0x12,0xEB,0x38,0xC8,0x0C,0xEB,0x23,0x2E,0x07,0xFF,0xDF,0xC1,0x03, +0x2E,0x00,0x00,0x72,0xEA,0x94,0xC1,0x09,0x2E,0x00,0x00,0x55,0xD5,0x06,0x2E,0x07, +0xFF,0xE2,0xD5,0x03,0x2E,0x07,0xFF,0xE0,0xB9,0x00,0x5A,0x18,0x03,0x04,0x2E,0x07, +0xFF,0xE3,0xEA,0xBB,0xC1,0x03,0x2E,0x00,0x00,0x73,0xEA,0xF5,0xEA,0x8B,0xC1,0x18, +0xB9,0x00,0x5A,0x18,0x02,0x06,0x2E,0x27,0xFD,0x6E,0x5A,0x20,0x01,0x05,0x2E,0x27, +0xFD,0x4F,0xC2,0x04,0x2E,0x17,0xFF,0xE8,0xD5,0x0B,0x5A,0x10,0x03,0x05,0xEA,0xBB, +0x5A,0x18,0x01,0x05,0x2E,0x17,0xFF,0xE7,0xD5,0x03,0x2E,0x17,0xFF,0xE6,0x46,0x21, +0x00,0x07,0x12,0x01,0x07,0xA4,0x2E,0x27,0xFD,0x46,0x2E,0x30,0x00,0xE7,0xE2,0x62, +0xE8,0x03,0x8A,0x43,0xD5,0x02,0x84,0x40,0x3E,0x27,0xFD,0x46,0x2F,0x37,0xFD,0x46, +0x46,0x21,0x00,0x07,0x02,0x21,0x07,0xA4,0x40,0x99,0x80,0x13,0x88,0x49,0x96,0x91, +0x46,0x31,0x00,0x07,0x12,0x21,0x87,0xA4,0x46,0x21,0x00,0x01,0x96,0x03,0x12,0x11, +0x00,0x13,0x46,0x21,0x00,0x01,0x12,0x01,0x00,0x12,0x84,0x00,0x46,0x21,0x00,0x05, +0x12,0x01,0x02,0xD6,0x2F,0x10,0x01,0x29,0x2F,0x20,0x01,0x28,0x3C,0x8D,0xFF,0x90, +0x46,0x71,0x00,0x03,0x58,0x73,0x80,0x78,0x46,0x01,0x00,0x01,0x58,0x00,0x00,0x28, +0x84,0x80,0x81,0x80,0x44,0xE0,0x00,0x48,0x46,0xD1,0x00,0x07,0x58,0xD6,0x85,0x00, +0x44,0xA0,0x00,0x4C,0x51,0x43,0xF0,0xCC,0xE2,0x91,0xE8,0x3B,0x81,0x6D,0x42,0xB2, +0x38,0x73,0x43,0x02,0x28,0x24,0x84,0x60,0xE2,0x72,0xE8,0x29,0x38,0x55,0x8D,0x01, +0x40,0x68,0x0C,0x20,0x38,0x23,0x95,0x01,0x38,0x54,0x15,0x01,0x88,0xD4,0x8A,0x45, +0x96,0x91,0x97,0x53,0x12,0x53,0x14,0xB2,0xA5,0x80,0xE0,0xC5,0xE8,0x02,0xAC,0x80, +0x4E,0x57,0x00,0x14,0x46,0x61,0x00,0x05,0x02,0x63,0x02,0xD6,0xE0,0xC5,0xE8,0x0D, +0x46,0x51,0x00,0x05,0x12,0x22,0x82,0xD6,0x46,0x21,0x00,0x05,0x10,0x41,0x05,0xAE, +0x46,0x21,0x00,0x05,0x10,0x31,0x05,0xAF,0x8C,0x61,0xD5,0xD7,0xC9,0x03,0xAC,0x40, +0xD5,0x05,0xA4,0x80,0x40,0x21,0x04,0x57,0xAC,0x80,0x8C,0x81,0x8C,0x02,0xD5,0xC5, +0xEB,0x4E,0x46,0x21,0x00,0x05,0x02,0x10,0x02,0xD6,0x00,0x21,0x05,0xAE,0x46,0x01, +0x00,0x01,0x02,0x00,0x00,0x12,0x38,0x26,0x09,0x01,0x96,0x03,0x88,0x02,0xE0,0x01, +0xEB,0x19,0xEB,0x24,0xE8,0x0C,0x46,0x01,0x00,0x01,0x02,0x00,0x00,0x12,0x96,0x03, +0x88,0x40,0x8A,0x22,0xEB,0x4E,0x12,0x10,0x02,0xD6,0xD5,0x06,0x84,0x00,0x46,0x11, +0x00,0x05,0x12,0x00,0x82,0xD6,0xEB,0x4E,0xEB,0x1C,0x84,0x40,0x40,0xA0,0x04,0x09, +0x2E,0x87,0xFF,0xAC,0x2F,0x40,0x00,0x15,0x46,0x01,0x00,0x01,0x00,0x70,0x02,0xC0, +0x2E,0xB7,0xFD,0x4C,0x80,0x82,0x80,0x62,0x44,0xE0,0x00,0x4C,0x80,0xA2,0x53,0x59, +0x80,0x00,0xE2,0x71,0xE8,0x52,0x80,0x06,0x42,0x01,0xB8,0x73,0x40,0xD1,0x84,0x08, +0x50,0x00,0x29,0x64,0x86,0x00,0xE3,0x92,0xE8,0x46,0x22,0x10,0x00,0x00,0x4E,0x15, +0x00,0x13,0xEA,0x85,0xEA,0x99,0x39,0x66,0x34,0x01,0xEA,0x7E,0x40,0xFB,0x3C,0x00, +0x40,0xF7,0x84,0x07,0xE8,0x14,0xEA,0x85,0xEA,0x99,0xEA,0x7E,0x40,0xFB,0x3C,0x00, +0x8A,0x2F,0xD5,0x0B,0xEA,0x85,0xEA,0x99,0xEA,0x7E,0x52,0xF7,0x80,0x00,0xE0,0x2F, +0xE8,0x06,0xEA,0x85,0xEA,0x99,0x88,0x2F,0xAC,0x40,0xD5,0x02,0xAD,0x40,0x22,0x10, +0x00,0x00,0x4E,0x17,0x00,0x08,0xE0,0x2A,0xE8,0x0B,0xE1,0xE1,0xE8,0x08,0x8A,0x29, +0xD5,0x04,0xE0,0x35,0xE8,0x04,0x88,0x29,0xAC,0x40,0xD5,0x02,0xAD,0x40,0x2A,0x10, +0x00,0x01,0x40,0xF0,0xA0,0x00,0x4E,0xF4,0x00,0x09,0x8C,0x81,0x97,0x21,0xE2,0x94, +0xE9,0x04,0x58,0x73,0x80,0x01,0x85,0x61,0x4E,0x14,0x00,0x04,0x8A,0x41,0x96,0x91, +0x8D,0x81,0xD5,0xBA,0x8C,0x61,0xD5,0xAE,0x46,0x01,0x00,0x01,0x10,0x70,0x02,0xC0, +0x3E,0xB7,0xFD,0x4C,0x2E,0x00,0x00,0x46,0x94,0x05,0xE0,0x02,0xE8,0x07,0x96,0x38, +0xEB,0x03,0xEB,0x78,0xEA,0xEC,0x84,0x01,0xEA,0x76,0x46,0x01,0x00,0x07,0x04,0x10, +0x03,0xF2,0xEB,0x4E,0xEB,0x1C,0xE2,0x20,0xE8,0x11,0x46,0x01,0x00,0x01,0x00,0x00, +0x02,0xC0,0xEB,0x78,0xEB,0x05,0xEA,0xEC,0x84,0x21,0x3E,0x17,0xFD,0x4C,0x2E,0x07, +0xFD,0x28,0x8C,0x01,0xB8,0x91,0x3E,0x17,0xFD,0x5D,0xB8,0x00,0x5A,0x08,0x03,0x05, +0x84,0xA1,0x84,0xE4,0xD5,0x03,0x84,0xA0,0x84,0xE1,0xEB,0x08,0x5A,0x08,0x01,0x04, +0x80,0xA0,0x84,0xE2,0x40,0x03,0x94,0x20,0x54,0x90,0x00,0xFF,0x2F,0x67,0xFD,0x6E, +0x2F,0x37,0xFD,0x78,0x84,0x80,0x51,0x79,0xFF,0xFF,0x80,0x44,0x45,0x50,0x00,0x26, +0x45,0x40,0x00,0x24,0x44,0xE0,0x00,0x48,0x44,0xDF,0xFF,0xB8,0xE2,0x51,0xE8,0x41, +0x42,0xA1,0x38,0x24,0x52,0x12,0x29,0x64,0x50,0x35,0x19,0x54,0x42,0xB1,0x54,0x24, +0x42,0x81,0x50,0x24,0x88,0x26,0x88,0x66,0x42,0xC1,0x34,0x24,0x86,0x00,0xE3,0x92, +0xE8,0x2C,0x40,0xF0,0x90,0x00,0x4F,0x62,0x00,0x0D,0x4F,0x32,0x00,0x0B,0x38,0x07, +0xAD,0x11,0x22,0xF0,0xFD,0x2F,0x42,0x07,0xDC,0x73,0x40,0x00,0x4C,0x16,0xD5,0x12, +0x40,0x01,0xB0,0x00,0x38,0x00,0x21,0x11,0x39,0x87,0xAD,0x11,0x40,0xF7,0xA8,0x00, +0xFE,0x2C,0x22,0xF7,0xFA,0x80,0x42,0x0C,0x1C,0x73,0x42,0x07,0x94,0x73,0x40,0x00, +0x24,0x16,0x12,0x00,0xFD,0x2F,0xA4,0x18,0x12,0x01,0x82,0x88,0x2A,0x00,0x80,0x01, +0x1A,0x01,0x80,0x01,0x8D,0x81,0xD5,0xD4,0x8C,0x41,0x50,0x42,0x7F,0xB4,0xD5,0xBF, +0x46,0x01,0x00,0x04,0x58,0x00,0x0A,0xA8,0x44,0x10,0x00,0xFD,0x44,0x20,0x02,0xF8, +0xEB,0x1F,0x2E,0x08,0x00,0x14,0x4E,0x04,0x00,0xAC,0x2E,0x07,0xFD,0x35,0xC8,0x04, +0x2F,0x00,0x00,0x8C,0xD5,0x03,0x45,0x00,0x00,0xFF,0x2E,0x07,0xFD,0x4A,0xC8,0x04, +0x2E,0x70,0x00,0x8C,0xD5,0x02,0xEA,0xE4,0x2E,0x50,0x01,0x29,0xEA,0x3C,0x9D,0x29, +0x50,0x90,0x7F,0xFF,0x51,0x10,0x00,0x01,0x46,0x11,0x00,0x04,0x58,0x10,0x85,0x04, +0x84,0x61,0x86,0x40,0xE2,0x64,0xE8,0x20,0x22,0x20,0x80,0x01,0x23,0x30,0x80,0x02, +0xE1,0xE2,0xE8,0x06,0x8A,0x53,0xFE,0xBC,0x90,0x48,0xAC,0x88,0xD5,0x03,0x13,0x20, +0x80,0x00,0x38,0x20,0x81,0x11,0x39,0x30,0xA5,0x11,0xE1,0xE2,0xE8,0x07,0x8A,0x53, +0xFE,0xBC,0x90,0x48,0x38,0x20,0xC5,0x09,0xD5,0x03,0x39,0x20,0xC5,0x09,0x8C,0x61, +0x50,0x10,0x80,0x4C,0xD5,0xE0,0x44,0x70,0x00,0x4C,0xFF,0xEC,0x9C,0x81,0x46,0x11, +0x00,0x04,0x58,0x10,0x84,0xBA,0x51,0x23,0x80,0x4C,0x86,0x21,0x86,0x60,0xE3,0xA2, +0xE8,0x21,0x22,0x30,0x80,0x26,0x22,0x90,0x80,0x4C,0xE1,0x23,0xE8,0x06,0x8A,0x69, +0xEA,0xEF,0x90,0x68,0xAC,0xC8,0xD5,0x03,0x13,0x30,0x80,0x00,0x40,0x90,0x9C,0x00, +0x38,0x30,0x9C,0x11,0x22,0x94,0xFF,0xDA,0xE1,0x23,0xE8,0x07,0x8A,0x69,0xEA,0xEF, +0x90,0x68,0x38,0x30,0xC8,0x09,0xD5,0x03,0x39,0x30,0xC8,0x09,0x8D,0xA1,0x8C,0x22, +0xD5,0xDF,0x46,0x11,0x00,0x04,0x22,0x30,0x82,0x5D,0x46,0x11,0x00,0x04,0x22,0x10, +0x82,0x82,0x44,0x70,0x00,0x4C,0x88,0x23,0x90,0x21,0x46,0x31,0x00,0x04,0x12,0x11, +0x82,0x5C,0x80,0x66,0x80,0x26,0x42,0x32,0x1C,0x73,0x42,0x12,0x9C,0x73,0x23,0x01, +0x91,0xBB,0x22,0x10,0x91,0xBA,0x88,0x30,0x90,0x21,0x12,0x11,0x91,0xBA,0x40,0x33, +0x08,0x20,0x40,0x13,0x00,0x20,0x22,0x70,0x91,0xBA,0x22,0x11,0x91,0xE0,0x88,0x27, +0x90,0x21,0x12,0x11,0x91,0xBA,0xFA,0x76,0xFF,0x1C,0x98,0x62,0x42,0x22,0x8C,0x73, +0x88,0x04,0x40,0x03,0x00,0x20,0x40,0x13,0x04,0x20,0x40,0x63,0x08,0x20,0x22,0x40, +0x11,0xBA,0x22,0x03,0x11,0xBA,0x88,0x04,0x90,0x01,0x12,0x00,0x91,0xBA,0xFC,0xE0, +0xEB,0x78,0x58,0x10,0x80,0x28,0x38,0x00,0x81,0x01,0xDD,0x9E,0xFC,0x40,0x82,0x40, +0x2E,0x47,0xFE,0xA1,0x3D,0x0C,0x00,0x48,0x3D,0x1C,0x00,0x49,0x84,0x00,0x80,0xE0, +0x80,0x40,0x86,0x6C,0x44,0x90,0xFF,0xFF,0x85,0x41,0x2E,0x30,0x01,0x2B,0xE2,0x43, +0xE8,0x2D,0x80,0x72,0x42,0x31,0x4C,0x73,0xB4,0xA3,0xA0,0xD9,0x4C,0x54,0x80,0x24, +0x40,0x62,0x08,0x0E,0x97,0xB4,0xC6,0x15,0x46,0x61,0x00,0x07,0x00,0x63,0x03,0x99, +0x40,0xF8,0x18,0x01,0xE2,0xAF,0xE8,0x17,0xE2,0xC5,0xE8,0x15,0x46,0x61,0x00,0x07, +0x00,0x63,0x03,0x9A,0x40,0xF8,0x98,0x01,0xE2,0x6F,0xE8,0x0D,0xE2,0xC3,0xE8,0x0B, +0xCF,0x03,0xA9,0x49,0xB6,0x61,0x40,0x35,0x08,0x0C,0x40,0x42,0x0C,0x12,0x9C,0xC1, +0x96,0x18,0x84,0xE1,0x8C,0x41,0x96,0x90,0xD5,0xD1,0x3E,0x47,0xFE,0xA1,0xFC,0xC0, +0xFC,0x00,0x84,0x1F,0x3E,0x07,0xFE,0xA1,0x84,0x00,0x3C,0x0B,0xFF,0xC1,0x3C,0x0B, +0xFF,0xC0,0x84,0x3F,0x3C,0x1B,0xFF,0xBF,0x3C,0x1B,0xFF,0xBE,0x3E,0x2F,0xFF,0x78, +0xAC,0x10,0xAC,0x11,0x3E,0x2F,0xFF,0x74,0xAC,0x10,0xAC,0x11,0x3E,0x2F,0xFF,0x70, +0xAC,0x50,0xAC,0x51,0x3E,0x2F,0xFF,0x6C,0xAC,0x50,0xAC,0x51,0x3E,0x07,0xFF,0x14, +0xEA,0xD5,0x46,0x01,0x00,0x07,0x58,0x00,0x03,0x80,0xA6,0x46,0xA6,0x87,0xEA,0x79, +0x3C,0x1B,0xFF,0x61,0x00,0x10,0x00,0x08,0x00,0x20,0x00,0x09,0xEA,0x79,0x3C,0x1B, +0xFF,0x60,0x00,0x10,0x00,0x0A,0x00,0x20,0x00,0x0B,0xEA,0x79,0x3C,0x1B,0xFF,0x5F, +0x00,0x10,0x00,0x0C,0x3E,0x17,0xFE,0xBD,0x00,0x10,0x00,0x0D,0x3E,0x17,0xFE,0xBC, +0x00,0x10,0x00,0x0E,0x3E,0x17,0xFE,0xBB,0x00,0x10,0x00,0x0F,0x3E,0x17,0xFE,0xBA, +0x3E,0x18,0x01,0x20,0xA4,0x8A,0x00,0x30,0x00,0x10,0x9B,0x13,0x3C,0x4B,0xFF,0x5C, +0x3C,0x3B,0xFF,0x5B,0xA4,0x48,0x00,0x30,0x00,0x11,0x9B,0x0B,0x3C,0x4B,0xFF,0x5A, +0x3C,0x3B,0xFF,0x59,0x00,0x30,0x00,0x12,0x8A,0x43,0x3C,0x2B,0xFF,0x58,0x3C,0x3B, +0xFF,0x57,0x00,0x20,0x00,0x13,0x8A,0x22,0x3C,0x1B,0xFF,0x56,0x3C,0x2B,0xFF,0x55, +0x00,0x10,0x00,0x14,0x00,0x20,0x00,0x15,0xEA,0x79,0x3C,0x1B,0xFF,0x54,0x00,0x10, +0x00,0x16,0x3C,0x1B,0xFF,0x53,0x00,0x10,0x00,0x17,0x3C,0x1B,0xFF,0x52,0x00,0x00, +0x00,0x18,0x3C,0x0B,0xFF,0x51,0xFA,0x44,0x3E,0x0F,0xFF,0x00,0x84,0x20,0xDD,0x42, +0x3E,0x6F,0xFF,0x20,0x3E,0x0F,0xFE,0xEC,0x84,0x20,0xFA,0x44,0xDD,0x42,0x80,0x06, +0x84,0x3F,0x44,0x20,0x00,0x4C,0xDD,0x42,0x80,0x06,0x84,0x3F,0x44,0x20,0x00,0x4C, +0xDD,0x42,0xEA,0xD9,0x84,0x20,0xFA,0x56,0xDD,0x42,0x46,0x01,0x00,0x01,0xEA,0xD8, +0x84,0x20,0xFA,0x43,0xDD,0x42,0x3E,0x0F,0xFF,0x18,0x84,0x20,0x84,0x48,0xDD,0x42, +0xFC,0x80,0xFC,0x00,0xEA,0x33,0x2E,0x67,0xFE,0x24,0x9E,0x71,0x96,0x48,0x5C,0xF0, +0x80,0xFE,0xE8,0x23,0xC8,0x22,0x40,0x03,0x40,0x08,0x40,0x00,0x19,0x00,0x88,0x06, +0x40,0x00,0x1B,0x00,0x95,0xB2,0xDD,0x4A,0x52,0x63,0x7F,0xF0,0x44,0x00,0x44,0xCC, +0x40,0x00,0x1B,0x00,0xDD,0x4A,0x84,0xCC,0x8E,0xC1,0x84,0x1F,0x97,0xB0,0xDD,0x4A, +0xCE,0xFC,0x84,0x0A,0x49,0xFF,0xD7,0xCA,0x3E,0x0F,0xFE,0x24,0x84,0x3F,0x84,0x41, +0xDD,0x42,0x84,0x01,0x3E,0x07,0xFE,0xA0,0xFC,0x80,0x5A,0x08,0x08,0x14,0x5A,0x10, +0x0C,0x1D,0xE6,0x2D,0xE8,0x08,0xE6,0x25,0xE9,0x17,0xE6,0x27,0xE9,0x0F,0x5A,0x10, +0x09,0x15,0xD5,0x12,0x5A,0x10,0x2F,0x12,0x5A,0x10,0x79,0x0D,0x5A,0x10,0x1F,0x0E, +0xD5,0x0B,0x5A,0x10,0xFF,0x0B,0x5A,0x10,0x79,0x06,0x5A,0x18,0x0D,0x07,0x84,0x27, +0xD5,0x04,0x84,0x29,0xD5,0x02,0x84,0x28,0x80,0x01,0xDD,0x9E,0x2E,0x07,0xFE,0xA0, +0xDD,0x9E,0x84,0x00,0x3E,0x07,0xFE,0xA0,0xDD,0x9E,0xE2,0x20,0xE8,0x03,0x8A,0x01, +0xD5,0x02,0x9A,0x08,0x96,0x01,0xDD,0x9E,0xFC,0x60,0x80,0xE0,0xEA,0x5F,0x80,0xC1, +0xE6,0x02,0xE8,0x0A,0x84,0x20,0x3E,0x17,0xFE,0x9F,0x3E,0x17,0xFE,0x9E,0x3E,0x17, +0xFE,0x9D,0x3E,0x17,0xFE,0x9C,0x3C,0x13,0xFF,0xBC,0xE2,0x27,0xE8,0x07,0x3C,0x7B, +0xFF,0xBC,0x3C,0x6B,0xFF,0xBD,0x3C,0x0B,0xFF,0x8F,0xEA,0xA2,0xE2,0xE1,0xE8,0x07, +0x3C,0x7B,0xFF,0xB8,0x3C,0x6B,0xFF,0xB9,0x3C,0x0B,0xFF,0x8D,0x3C,0x13,0xFF,0xBB, +0xE2,0x26,0xE8,0x07,0x3C,0x7B,0xFF,0xBA,0x3C,0x6B,0xFF,0xBB,0x3C,0x0B,0xFF,0x8E, +0xEA,0xA0,0xE2,0xC1,0xE8,0x07,0x3C,0x7B,0xFF,0xB6,0x3C,0x6B,0xFF,0xB7,0x3C,0x0B, +0xFF,0x8C,0x3C,0xA3,0xFF,0xBF,0x80,0x07,0x80,0x2A,0xDD,0x41,0x81,0x60,0x3C,0x93, +0xFF,0xBE,0x80,0x06,0x80,0x29,0xDD,0x41,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x81, +0xE2,0x2B,0xE9,0x04,0xE2,0x20,0x4E,0xF2,0x00,0x58,0xE3,0x47,0x2E,0x0F,0xFE,0x9D, +0xE8,0x0B,0x2E,0x37,0xFE,0x9F,0xEB,0x42,0xEA,0x9C,0xE4,0x02,0x8C,0x21,0xEA,0x9F, +0xE8,0x11,0x8C,0x01,0xD5,0x0D,0xE2,0xEA,0xE8,0x0D,0x2E,0x37,0xFE,0x9F,0xEB,0x42, +0xEA,0x9C,0x5E,0xF0,0x7F,0xFF,0x8E,0x21,0xEA,0x9F,0xE9,0x04,0x8E,0x01,0x3E,0x07, +0xFE,0x9D,0xE3,0x26,0x2E,0x0F,0xFE,0x9C,0xE8,0x0C,0x2E,0x37,0xFE,0x9E,0x3E,0x2F, +0xFE,0xEC,0xEA,0x9C,0xE4,0x02,0x8C,0x21,0xEA,0x9F,0xE8,0x12,0x8C,0x01,0xD5,0x0E, +0xE2,0xC9,0xE8,0x0E,0x2E,0x37,0xFE,0x9E,0x3E,0x2F,0xFE,0xEC,0xEA,0x9C,0x5E,0xF0, +0x7F,0xFF,0x8E,0x21,0xEA,0x9F,0xE9,0x04,0x8E,0x01,0x3E,0x07,0xFE,0x9C,0x2E,0x0F, +0xFE,0x9D,0xC8,0x0C,0x4C,0x75,0x00,0x0B,0x2E,0x07,0xFE,0x9F,0x8C,0x01,0x96,0x00, +0xE6,0x0A,0xE9,0x02,0x84,0x09,0x3E,0x07,0xFE,0x9F,0x2E,0x0F,0xFE,0x9C,0xC8,0x0C, +0x4C,0x64,0x80,0x0B,0x2E,0x07,0xFE,0x9E,0x8C,0x01,0x96,0x00,0xE6,0x0A,0xE9,0x02, +0x84,0x09,0x3E,0x07,0xFE,0x9E,0xFC,0xE0,0xFC,0x61,0x83,0x80,0xEA,0x5F,0x81,0x41, +0xE6,0x02,0x46,0xD1,0x00,0x01,0x58,0xD6,0x81,0x90,0x46,0xC1,0x00,0x01,0x58,0xC6, +0x00,0x60,0xE8,0x13,0x84,0x40,0x3E,0x1F,0xFE,0x88,0x80,0x02,0x82,0x42,0xD5,0x11, +0x38,0x02,0x0D,0x09,0x38,0x03,0x8D,0x09,0x80,0x66,0x5A,0x68,0x08,0x10,0x8C,0x50, +0x19,0x20,0x80,0x01,0x5A,0x29,0x30,0x06,0x3E,0x8F,0xFE,0x88,0x85,0x20,0xD5,0x0E, +0x84,0x60,0x40,0x46,0x88,0x00,0x40,0x76,0x08,0x00,0x9D,0x99,0xCB,0xEA,0x39,0xC6, +0x88,0x09,0x38,0xA6,0x08,0x09,0x80,0x66,0xD5,0xF9,0x46,0x01,0x00,0x01,0xEA,0xD8, +0x38,0x60,0x24,0x00,0x40,0xB4,0x8C,0x08,0x40,0x05,0x98,0x00,0x38,0x16,0x01,0x01, +0x38,0x76,0x81,0x01,0xF1,0x81,0x3E,0x1F,0xFB,0x70,0x38,0xE0,0x80,0x00,0x80,0x1C, +0x80,0x27,0xDD,0x41,0xE6,0x06,0xE9,0x0B,0x5A,0xE8,0x01,0x05,0x40,0x7E,0x1C,0x06, +0xD5,0x07,0x5A,0xE8,0x03,0x05,0x40,0x73,0xF0,0x06,0xD5,0x02,0xEA,0xE4,0x80,0x0A, +0xF1,0x01,0xDD,0x41,0xE6,0x06,0xE9,0x0D,0x5A,0xE8,0x02,0x06,0xF0,0x01,0x40,0x75, +0x00,0x06,0xD5,0x07,0x5A,0xE8,0x04,0x06,0xF0,0x01,0xE2,0x0A,0xE9,0x04,0xD5,0x18, +0x5A,0x78,0x01,0x16,0x00,0x04,0x00,0x00,0x8C,0x01,0x96,0x00,0x5A,0x08,0x02,0x18, +0x8C,0xC1,0x84,0x00,0x96,0xB0,0x40,0x65,0x88,0x00,0x10,0x04,0x00,0x00,0x46,0x01, +0x00,0x01,0xEA,0xD8,0x38,0x20,0x24,0x08,0xF8,0x04,0xD5,0x0B,0xCF,0x0A,0x88,0xCB, +0x39,0xC6,0x99,0x09,0x38,0xA6,0x19,0x09,0x83,0xFF,0x84,0x00,0x10,0x04,0x00,0x00, +0x8D,0x21,0x8D,0x01,0x5A,0x98,0x13,0xAB,0xFC,0xE1,0xFC,0x65,0x80,0xC0,0x3C,0xD3, +0xFF,0xBF,0x3C,0xA3,0xFF,0xBE,0xEA,0x5F,0x80,0xE1,0xE6,0x02,0xE8,0x04,0x84,0x1F, +0x3E,0x07,0xFE,0x87,0x40,0xF6,0x98,0x06,0xE9,0x04,0x44,0x90,0x00,0x40,0xD5,0x03, +0x44,0x90,0x00,0x60,0x80,0x06,0x80,0x2D,0xDD,0x41,0xE3,0x47,0x81,0x60,0x85,0x00, +0xE8,0x02,0xFB,0x10,0x80,0x07,0x80,0x2A,0xDD,0x41,0x80,0x80,0x46,0x01,0x00,0x07, +0x00,0x00,0x03,0x80,0xB6,0x1F,0x02,0x5F,0x80,0x00,0xE2,0xAB,0xE9,0x03,0xE2,0xA4, +0xE8,0x09,0x2E,0x07,0xFE,0x87,0x5A,0x08,0xFF,0x06,0xE2,0x8B,0xE8,0x1D,0x3E,0x97, +0xFE,0x87,0xE2,0xCD,0x14,0xFF,0x80,0x02,0x40,0x16,0x98,0x06,0xF1,0x83,0xE3,0x47, +0x2E,0x07,0xFE,0x87,0x14,0xFF,0x80,0x04,0xE2,0xEA,0xF0,0x81,0x3E,0xCF,0xFE,0xC4, +0x3F,0xCF,0xFF,0x20,0x80,0x04,0x82,0xAB,0x85,0xC0,0x86,0x8C,0x14,0xFF,0x80,0x05, +0x44,0xD0,0x00,0xFF,0xD5,0x06,0xE3,0x64,0xE8,0xE5,0x3E,0x87,0xFE,0x87,0xD5,0xE2, +0x02,0xA6,0x00,0x00,0x5A,0xA0,0xFF,0x2A,0x02,0x1E,0x00,0x00,0xE2,0x26,0xE9,0x04, +0x44,0x90,0x00,0x40,0xD5,0x03,0x44,0x90,0x00,0x60,0x80,0x06,0x15,0x4F,0x80,0x08, +0xF5,0x87,0xF4,0x86,0xDD,0x41,0x02,0x1E,0x00,0x01,0x82,0xA0,0xE2,0x27,0xF4,0x06, +0xF5,0x07,0x05,0x4F,0x80,0x08,0x85,0x00,0xE8,0x02,0xFB,0x10,0x80,0x07,0x15,0x4F, +0x80,0x09,0xF5,0x88,0xF4,0x87,0x15,0x5F,0x80,0x06,0xDD,0x41,0x05,0x4F,0x80,0x09, +0xF5,0x08,0xF4,0x07,0x05,0x5F,0x80,0x06,0x80,0x2A,0x42,0x17,0x50,0x73,0xEA,0xA8, +0x38,0x11,0x04,0x00,0x40,0xF0,0x9C,0x09,0x5A,0xF8,0x01,0x19,0x5A,0xA0,0xFF,0x17, +0x55,0x60,0x80,0x60,0x96,0x67,0xC1,0x05,0xB4,0x5F,0xFE,0x54,0x96,0x48,0xD5,0x02, +0x80,0x2F,0x4D,0x64,0xC0,0x04,0xE2,0x35,0xD5,0x04,0x4D,0x64,0x40,0x08,0xE2,0x20, +0xE8,0x05,0x50,0x25,0x00,0x01,0x12,0x26,0x00,0x00,0x02,0x16,0x00,0x00,0xC1,0x1E, +0x5A,0x10,0xFF,0x1D,0xEA,0xA8,0x42,0x27,0x50,0x73,0xF8,0x33,0xC9,0x03,0xF1,0x05, +0xD5,0x04,0x5A,0x18,0x20,0x06,0xF1,0x04,0xC1,0x11,0xCC,0x0C,0xD5,0x0F,0x5A,0x18, +0x60,0x04,0xF1,0x03,0xD5,0x04,0x5A,0x18,0x40,0x0A,0xF1,0x02,0xC1,0x07,0x4E,0xB2, +0x00,0x06,0x12,0x6E,0x00,0x00,0x12,0x7E,0x00,0x01,0x42,0x17,0x50,0x24,0xEA,0xA8, +0x38,0x11,0x04,0x00,0xF2,0x01,0x54,0x10,0x80,0x60,0xFE,0x55,0x5A,0x18,0x20,0x04, +0x12,0xD6,0x00,0x00,0x0A,0x16,0x00,0x01,0x42,0xA7,0x50,0x24,0xEA,0xA8,0x40,0x35, +0x04,0x00,0x38,0x31,0x0C,0x00,0x92,0x67,0xCB,0x18,0x5A,0x10,0xFF,0x17,0x88,0x4A, +0x88,0x22,0x00,0x10,0xFF,0xFF,0x54,0x10,0x80,0x60,0x83,0xFF,0x40,0x24,0x04,0x03, +0x5A,0x28,0x20,0x04,0xE2,0xA0,0xE9,0x07,0x40,0x14,0x84,0x03,0x5A,0x18,0x20,0x06, +0xE2,0xB5,0xE8,0x03,0x12,0xD6,0x7F,0xFF,0x50,0xE7,0x00,0x01,0x51,0xCE,0x00,0x04, +0x5A,0xE0,0x13,0x04,0x48,0xFF,0xFF,0x5E,0xFC,0xE5,0xFC,0x60,0x80,0xA0,0x46,0x01, +0x00,0x07,0x02,0x60,0x01,0xDC,0x46,0x01,0x00,0x07,0x02,0x70,0x01,0xDD,0xE6,0x42, +0x81,0x41,0x81,0x22,0x97,0xB1,0x97,0xF9,0xE9,0x17,0x84,0x05,0x44,0x20,0x27,0x10, +0xDD,0x5A,0x40,0x03,0x08,0x57,0x44,0x10,0x03,0xE8,0x96,0x91,0x40,0x21,0x04,0x57, +0x44,0x0F,0xFC,0x18,0x42,0x61,0x00,0x73,0x8C,0x41,0x84,0x0A,0x40,0x21,0x00,0x16, +0x42,0x60,0x04,0x73,0x97,0xB1,0x2E,0x07,0xFE,0x86,0xC0,0x20,0x5A,0x00,0x05,0x1F, +0x5A,0x00,0x04,0x07,0x3C,0x03,0xFF,0x42,0x8C,0x01,0x3C,0x0B,0xFF,0x42,0xEB,0x40, +0x3C,0x13,0xFF,0x5B,0xE2,0x20,0x4E,0xF2,0x00,0xE1,0x3C,0x13,0xFF,0x5C,0xE2,0x01, +0x4E,0xF2,0x00,0xDC,0xEB,0x3F,0x3C,0x13,0xFF,0x59,0xE2,0x20,0x4E,0xF2,0x00,0xD6, +0x3C,0x13,0xFF,0x5A,0xE2,0x01,0x4E,0xF2,0x00,0xD1,0x2E,0x27,0xFE,0x86,0xCA,0x15, +0x5A,0x90,0x01,0x03,0xF8,0x4E,0xEA,0x29,0x4C,0x50,0x00,0xAE,0x3E,0x97,0xFE,0x86, +0x3C,0x5B,0xFF,0x41,0x3C,0xAB,0xFF,0x40,0x3C,0x2B,0xFF,0x42,0x3C,0x2B,0xFF,0x3F, +0x84,0x1F,0x3E,0x07,0xFC,0xF8,0xF8,0x3D,0x54,0x01,0x00,0xFD,0x5A,0x00,0x01,0x04, +0x48,0x00,0x00,0x55,0x5A,0x98,0x01,0x38,0x80,0x25,0xEB,0x40,0xDD,0x41,0x2E,0xB7, +0xFE,0xBA,0xE3,0x60,0xE9,0x06,0xEB,0x3F,0x80,0x2A,0xDD,0x41,0xE3,0x60,0xE8,0x13, +0x84,0x05,0xDD,0x5A,0xDD,0x5C,0x40,0x13,0x00,0x17,0x84,0x2A,0x96,0x01,0x40,0x00, +0x04,0x17,0x84,0x56,0x42,0x60,0x08,0x73,0x8C,0x01,0x40,0x00,0x04,0x56,0x42,0x60, +0x88,0x73,0xD5,0x16,0x3C,0x13,0xFF,0x42,0x3C,0x23,0xFF,0x3F,0x2E,0x07,0xFE,0xBD, +0x88,0x02,0xE0,0x01,0x4E,0xF2,0x00,0x70,0x84,0x05,0xDD,0x5A,0x84,0x0A,0x40,0x23, +0x00,0x37,0x96,0x49,0x8A,0xC1,0x8C,0x21,0x40,0x00,0x80,0x36,0x88,0xC1,0x97,0xB1, +0x48,0x00,0x00,0x62,0x4E,0x93,0x00,0x60,0x3C,0x03,0xFF,0x42,0x3C,0x33,0xFF,0x3F, +0xE2,0x60,0xE8,0x11,0x2E,0x17,0xFE,0xBD,0x88,0x23,0xE0,0x20,0xE9,0x0C,0x84,0x22, +0x5A,0x20,0x01,0x05,0x5A,0x28,0x03,0x05,0x84,0x24,0x3E,0x17,0xFE,0x86,0x3C,0x0B, +0xFF,0x3F,0xD5,0x49,0x84,0x05,0xDD,0x5A,0xD5,0x46,0x5A,0x28,0x02,0x45,0x3C,0xB3, +0xFF,0x42,0x3C,0x83,0xFF,0x3F,0xE3,0x68,0xE9,0x32,0x2E,0x07,0xFE,0xBC,0x88,0x08, +0xE1,0x60,0xE8,0x2D,0x5A,0x98,0x01,0x38,0xEA,0x29,0xD0,0x35,0x80,0x25,0xEB,0x40, +0xDD,0x41,0x2E,0xC7,0xFE,0xBA,0xE2,0x0C,0xE8,0x10,0xEB,0x3F,0x80,0x2A,0xDD,0x41, +0xE2,0x0C,0xE8,0x0B,0x2E,0x07,0xFE,0xBB,0x88,0x08,0xE1,0x60,0xE9,0x06,0x84,0x03, +0xDD,0x5A,0x3C,0xBB,0xFF,0x3F,0xD5,0x1F,0x84,0x05,0xDD,0x5A,0xDD,0x5C,0x40,0x13, +0x80,0x17,0x84,0x2A,0x96,0x01,0x40,0x00,0x04,0x17,0x84,0x56,0x42,0x70,0x08,0x73, +0x8C,0x01,0x40,0x00,0x04,0x56,0x42,0x70,0x88,0x73,0xD5,0x0C,0x84,0x05,0xDD,0x5A, +0x84,0x0A,0x40,0x23,0x80,0x37,0x96,0x49,0x8A,0xE1,0x8C,0x21,0x40,0x00,0x80,0x36, +0x88,0xE1,0x97,0xF9,0x2E,0x07,0xFE,0x86,0x5A,0x08,0x04,0x09,0x44,0x0F,0xFF,0x80, +0x3E,0x07,0xFC,0xF8,0x84,0x00,0xDD,0x5A,0xD5,0x07,0x5A,0x08,0x05,0x06,0x4E,0x93, +0x00,0x04,0x3E,0x97,0xFE,0x86,0x46,0x01,0x00,0x07,0x12,0x60,0x01,0xDC,0x46,0x01, +0x00,0x07,0x12,0x70,0x01,0xDD,0xFC,0xE0,0x84,0x05,0x44,0x30,0x03,0xE8,0xDD,0x5A, +0x40,0x03,0x0C,0x77,0xEA,0x2A,0x96,0xD9,0x40,0x31,0x84,0x77,0x44,0x0F,0xFF,0x9C, +0x42,0x61,0x80,0x73,0x8C,0x61,0x84,0x0A,0x40,0x31,0x80,0x16,0x42,0x60,0x04,0x73, +0x97,0xB1,0x48,0xFF,0xFF,0x1C,0xFC,0x00,0x84,0x00,0x3E,0x6F,0xFF,0x00,0x3E,0x5F, +0xFE,0xEC,0x80,0x20,0x80,0x40,0x2A,0x43,0x00,0x01,0xC4,0x0E,0x22,0x33,0x00,0x00, +0xC3,0x0B,0x42,0x42,0x00,0x03,0xE4,0x85,0xE9,0x07,0x42,0x31,0x80,0x03,0xE4,0x65, +0xE9,0x03,0x8C,0x21,0x96,0x48,0x2A,0x42,0x80,0x01,0xC4,0x0E,0x22,0x32,0x80,0x00, +0xC3,0x0B,0x42,0x42,0x00,0x03,0xE4,0x85,0xE9,0x07,0x42,0x31,0x80,0x03,0xE4,0x65, +0xE9,0x03,0x8C,0x01,0x96,0x00,0x8C,0x41,0x96,0x90,0x5A,0x28,0x09,0xDE,0x8E,0x21, +0xE6,0x22,0xE8,0x5C,0x8E,0x01,0xE6,0x02,0xE8,0x59,0xEA,0x36,0x3C,0x63,0xFF,0xBF, +0xE2,0xC0,0xE8,0x03,0x9A,0x86,0xD5,0x02,0x9A,0xB0,0x46,0x11,0x00,0x07,0x00,0x10, +0x83,0x82,0x46,0x31,0x00,0x07,0x00,0x31,0x83,0x83,0x40,0xF1,0x85,0x00,0xE0,0x4F, +0xE8,0x45,0x3C,0x23,0xFF,0xC0,0xEA,0x9A,0xE2,0x22,0xE8,0x03,0x9A,0x51,0xD5,0x02, +0x8A,0x22,0x46,0x21,0x00,0x07,0x00,0x21,0x03,0x84,0x46,0x31,0x00,0x07,0x00,0x31, +0x83,0x85,0x40,0xF1,0x89,0x00,0xE0,0x2F,0xE8,0x31,0xEA,0xA2,0xDD,0x41,0x5C,0xF0, +0x00,0x64,0xE8,0x08,0x80,0x06,0x3C,0x13,0xFF,0xBC,0xDD,0x41,0x5C,0xF0,0x00,0x64, +0xE9,0x25,0x3C,0x43,0xFF,0x8F,0x3C,0x33,0xFF,0x8C,0x84,0x00,0x3E,0x2F,0xFF,0x18, +0x80,0x20,0x40,0x31,0x90,0x06,0x5A,0x10,0x03,0x07,0xA5,0x10,0xA5,0x51,0xE2,0xA4, +0xE8,0x05,0xD5,0x02,0xC3,0x03,0x8C,0x01,0xD5,0x02,0x8E,0x01,0x8C,0x21,0x96,0x48, +0x96,0x02,0x8C,0x42,0x5A,0x18,0x04,0xF1,0x4E,0x07,0x00,0x04,0x84,0x01,0xD5,0x02, +0x84,0x00,0x3E,0x07,0xFF,0x14,0x84,0x08,0xD5,0x02,0xEA,0x8D,0xFC,0x80,0xFC,0x60, +0x80,0xE0,0x81,0x21,0x3C,0xA3,0xFF,0x5F,0x5A,0x10,0x0B,0x04,0x5A,0x18,0x07,0x1F, +0x3C,0x07,0xFF,0x80,0xE4,0x05,0xE9,0x15,0x3C,0xF7,0xFF,0x81,0x5E,0xF7,0xFF,0xFC, +0xE8,0x10,0x3C,0x07,0xFF,0x82,0xE4,0x05,0xE9,0x0C,0x3C,0x67,0xFF,0x83,0xCE,0x09, +0x3C,0x07,0xFF,0x84,0xC8,0x07,0x3C,0x67,0xFF,0x85,0x5C,0x63,0x00,0x01,0xD5,0x02, +0x84,0xC0,0xEA,0x36,0xEB,0x09,0xE2,0x20,0xF8,0x71,0xEB,0x78,0x58,0x10,0x81,0x90, +0x94,0x3C,0x98,0x81,0x80,0x81,0x5A,0x98,0x0D,0x12,0x3C,0x13,0xFF,0xC1,0x3C,0x03, +0xFF,0xBF,0xE2,0x20,0x4E,0xF2,0x02,0x3F,0xA4,0x50,0xA4,0x11,0xE2,0x20,0x4E,0xF2, +0x02,0x3A,0xA4,0x52,0xA4,0x13,0x48,0x00,0x00,0xE5,0xEB,0x78,0x58,0x10,0x80,0x60, +0x98,0xC1,0x5A,0x90,0x06,0x06,0x5A,0x90,0x09,0x04,0x48,0x00,0x00,0x52,0x38,0xA0, +0x80,0x01,0xA4,0x19,0xE2,0x0A,0xE9,0x1C,0x3C,0x83,0xFF,0xBE,0x3C,0x63,0xFF,0xBB, +0x80,0x08,0x80,0x26,0xDD,0x41,0x81,0x80,0x3C,0xB3,0xFF,0xB7,0x80,0x08,0x80,0x2B, +0xDD,0x41,0xE2,0x0C,0xE9,0x0D,0x3C,0x83,0xFF,0xC0,0x80,0x26,0x80,0x08,0xDD,0x41, +0x80,0xC0,0x80,0x2B,0x80,0x08,0xDD,0x41,0x40,0x63,0x00,0x06,0xD5,0x02,0x84,0xC1, +0x5A,0x98,0x06,0x10,0xEA,0xFF,0xE3,0x40,0xE8,0x04,0x40,0x05,0x00,0x11,0xD5,0x02, +0x96,0x03,0x96,0x01,0xEA,0xA0,0xDD,0x41,0xE6,0x1A,0x4E,0xF3,0x01,0xFA,0xF8,0x9A, +0x5A,0x90,0x09,0x03,0xF9,0xAB,0x3C,0xB3,0xFF,0xBC,0x3C,0x93,0xFF,0xC1,0x80,0x0B, +0x80,0x29,0xDD,0x41,0x81,0x80,0x3C,0xA3,0xFF,0xB8,0x80,0x29,0x80,0x0A,0xDD,0x41, +0xE2,0x0C,0x4E,0xF3,0x01,0xE8,0x3C,0x93,0xFF,0xBF,0x80,0x0B,0x80,0x29,0xDD,0x41, +0x81,0x60,0x80,0x29,0x80,0x0A,0xDD,0x41,0xE3,0x60,0x48,0x00,0x00,0xFD,0x5A,0x98, +0x79,0x3A,0x3C,0xA3,0xFF,0xBC,0x3C,0x63,0xFF,0xC1,0x80,0x0A,0x80,0x26,0xDD,0x41, +0x81,0x60,0x3C,0x93,0xFF,0xB8,0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0B,0x4E,0xF3, +0x01,0xCA,0x3C,0x63,0xFF,0xBF,0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x40,0x80,0x26, +0x80,0x09,0xDD,0x41,0xE3,0x40,0x4E,0xF3,0x01,0xBE,0x3C,0x93,0xFF,0xB7,0x3C,0x63, +0xFF,0xC0,0x80,0x09,0x80,0x26,0xDD,0x41,0x81,0x60,0x3C,0xA3,0xFF,0xBB,0x80,0x26, +0x80,0x0A,0xDD,0x41,0xE2,0x0B,0x4E,0xF3,0x01,0xAE,0x3C,0x63,0xFF,0xBE,0x80,0x0A, +0x80,0x26,0xDD,0x41,0x81,0x40,0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0A,0x48,0x00, +0x01,0x9E,0x5A,0x98,0x3D,0x1F,0x84,0x40,0x80,0x22,0x80,0x02,0x3E,0x4F,0xFE,0xEC, +0x38,0x32,0x09,0x11,0x4E,0x37,0x00,0x05,0x88,0x03,0x96,0x03,0xD5,0x03,0x88,0x23, +0x96,0x4B,0x8C,0x41,0x5A,0x28,0x0A,0xF6,0x42,0xF0,0x00,0x03,0x42,0x20,0x80,0x03, +0xE0,0x4F,0xE8,0x04,0x4E,0x13,0x01,0x87,0xF8,0xE4,0x4E,0x03,0x01,0x84,0xF8,0xE1, +0x5A,0x98,0x05,0x24,0xEB,0x42,0x84,0x29,0x84,0x00,0x2A,0x41,0x00,0x01,0xC4,0x15, +0x22,0x31,0x00,0x00,0xC3,0x12,0x42,0x52,0x00,0x03,0xE4,0xA5,0xE9,0x0E,0x42,0x51, +0x80,0x03,0xE4,0xA5,0xE9,0x0A,0xC8,0x06,0x4E,0x44,0x00,0x08,0x40,0x00,0x0C,0x07, +0xD5,0x04,0x5A,0x08,0x01,0x03,0x84,0x05,0x8E,0x21,0x96,0x48,0xC9,0xE7,0x5A,0x00, +0x01,0x04,0x48,0x00,0x01,0x60,0xF8,0xBD,0x5A,0x98,0x0E,0x0E,0xA4,0x50,0xEA,0x36, +0xE2,0x01,0x4E,0xF3,0x01,0x58,0xA4,0x12,0xE2,0x20,0x4E,0xF2,0x01,0x54,0xA4,0x51, +0xE2,0x20,0xF8,0x49,0x5A,0x98,0x1F,0x21,0xA5,0x51,0xA5,0x12,0xE2,0x85,0x4E,0xF2, +0x01,0x4A,0xA5,0x13,0x3C,0x63,0xFF,0xC1,0xE2,0xC4,0x4E,0xF2,0x01,0x44,0xA5,0x1C, +0xEA,0xE0,0xE2,0x04,0x4E,0xF2,0x01,0x3F,0xA4,0x19,0xE2,0x04,0x4E,0xF2,0x01,0x3B, +0xA4,0x1A,0xE2,0x04,0x4E,0xF2,0x01,0x37,0xA4,0x1B,0xE2,0x04,0x4E,0xF2,0x01,0x33, +0xA4,0x15,0xE2,0x05,0xF8,0x28,0x5A,0x98,0x2F,0x29,0x3C,0x53,0xFF,0xC1,0x38,0x42, +0x00,0x01,0xE2,0x85,0x4E,0xF2,0x01,0x27,0x3C,0x43,0xFF,0xC0,0xEA,0xE0,0xE2,0x80, +0x4E,0xF2,0x01,0x21,0xA5,0x59,0xE2,0x05,0x4E,0xF2,0x01,0x1D,0xA4,0x12,0xA4,0x51, +0xE2,0x01,0x4E,0xF2,0x01,0x18,0xA4,0x5A,0xE2,0x25,0x4E,0xF2,0x01,0x14,0x3C,0x23, +0xFF,0xBF,0xE2,0x02,0x4E,0xF2,0x01,0x0F,0x3C,0x03,0xFF,0xBE,0xE2,0x01,0x4E,0xF2, +0x01,0x0A,0xE2,0x80,0x48,0x00,0x00,0x64,0x5A,0x98,0x0C,0x29,0xEA,0xE0,0xA5,0x19, +0x02,0xC1,0x80,0x02,0xE2,0x80,0x3C,0xA3,0xFF,0xC1,0x3C,0x83,0xFF,0xBF,0xE8,0x07, +0xE2,0x8C,0xE8,0x05,0xE3,0x48,0x56,0x67,0x80,0x01,0xD5,0x02,0x84,0xC1,0xA4,0x52, +0x80,0x0A,0xDD,0x41,0x81,0x20,0x3C,0xB3,0xFF,0xC0,0x80,0x2C,0x80,0x0B,0xDD,0x41, +0x89,0x20,0x80,0x28,0x80,0x0A,0xDD,0x41,0x81,0x40,0xEA,0x9A,0x80,0x0B,0xDD,0x41, +0x88,0x0A,0xE0,0x09,0x4E,0xF3,0x00,0xDF,0xF8,0x91,0x5A,0x90,0x0A,0x04,0x5A,0x98, +0x1D,0x1C,0x84,0x40,0x80,0x22,0x80,0x02,0x3E,0x4F,0xFF,0x00,0x38,0x32,0x09,0x11, +0x4E,0x37,0x00,0x05,0x88,0x03,0x96,0x03,0xD5,0x03,0x88,0x23,0x96,0x4B,0x8C,0x41, +0x5A,0x28,0x0A,0xF6,0x42,0x00,0x00,0x03,0xEB,0x14,0xE0,0x20,0xE8,0x03,0xE4,0x24, +0xD5,0x1E,0xE0,0x01,0xD5,0x19,0x5A,0x98,0x2D,0x1F,0x84,0x40,0x80,0x02,0x80,0x22, +0x3E,0x3F,0xFE,0xEC,0x38,0xF1,0x89,0x11,0x4E,0xF7,0x00,0x05,0x88,0x2F,0x96,0x4B, +0xD5,0x03,0x88,0x0F,0x96,0x03,0x8C,0x41,0x5A,0x28,0x0A,0xF6,0x42,0x00,0x00,0x03, +0x42,0xF0,0x80,0x03,0xE0,0x0F,0x4E,0xF2,0x00,0xAB,0xE4,0x04,0x4E,0xF2,0x00,0xA3, +0x48,0x00,0x00,0xA6,0x8F,0x21,0xE7,0x24,0x4E,0xF2,0x00,0xA2,0x84,0x00,0x80,0xC0, +0x81,0x20,0x81,0x60,0x81,0x00,0x3E,0x4F,0xFF,0x00,0x3E,0x5F,0xFE,0xEC,0x38,0x32, +0x01,0x11,0x94,0x41,0xE4,0x65,0xE9,0x05,0x88,0x6B,0x40,0xB1,0x80,0x11,0xD5,0x07, +0x5E,0xF1,0xFF,0xFC,0xE8,0x04,0x88,0x69,0x40,0x91,0x80,0x11,0x38,0x12,0x84,0x11, +0xE4,0x25,0xE9,0x06,0x40,0x20,0xA0,0x00,0x40,0x81,0x00,0x11,0xD5,0x06,0x5E,0xF0, +0xFF,0xFC,0xE8,0x03,0x88,0xC1,0x97,0xB3,0x8C,0x01,0x5A,0x08,0x0A,0xE2,0xEA,0xD9, +0x38,0x10,0x1D,0x01,0x84,0x4C,0x3E,0x0F,0xFC,0x08,0x42,0x03,0x88,0x73,0x88,0x01, +0x00,0x00,0x7F,0xFF,0x54,0x00,0x00,0x60,0xC8,0x1B,0xEA,0x9A,0xEA,0xFF,0xE2,0x20, +0x4E,0xF2,0x00,0x61,0xDD,0x41,0x3C,0x13,0xFF,0x60,0xE2,0x20,0x4E,0xF2,0x00,0x5B, +0x3C,0x03,0xFF,0xBC,0xEA,0xA2,0xDD,0x41,0xE2,0x0A,0x4E,0xF2,0x00,0x54,0x4E,0x83, +0x00,0x52,0x8C,0xC3,0x97,0xB1,0x5C,0x63,0x00,0x07,0x48,0x00,0x00,0x4A,0x5A,0x08, +0x20,0x18,0xEA,0xFF,0xEA,0x9A,0xE2,0x01,0x4E,0xF2,0x00,0x45,0xDD,0x41,0x3C,0x13, +0xFF,0x60,0xE2,0x20,0xE8,0x3F,0x3C,0x03,0xFF,0xBC,0xEA,0xA2,0xDD,0x41,0xE2,0x0A, +0xE8,0x39,0xE5,0x04,0xE9,0x37,0x84,0x20,0x40,0x60,0x98,0x06,0xD5,0x31,0x5A,0x08, +0x60,0x17,0xEB,0x09,0xEA,0x36,0xE2,0x01,0xE8,0x2D,0xDD,0x41,0x3C,0x13,0xFF,0x61, +0xE2,0x20,0xE8,0x28,0x3C,0x03,0xFF,0xBB,0xEA,0xA0,0xDD,0x41,0xE2,0x0A,0xE8,0x22, +0xE5,0x64,0xE9,0x20,0x84,0x20,0x40,0x60,0xA4,0x06,0xD5,0x1A,0x5A,0x08,0x40,0x20, +0xEA,0x36,0xEB,0x09,0xE2,0x20,0xE8,0x16,0xDD,0x41,0x3C,0x13,0xFF,0x61,0xE2,0x20, +0xE8,0x11,0x3C,0x03,0xFF,0xBB,0xEA,0xA0,0xDD,0x41,0xE2,0x0A,0xE8,0x0B,0x4E,0xB3, +0x00,0x0A,0x50,0x64,0x80,0x03,0x97,0xB1,0xE6,0xC7,0xE9,0x04,0xD5,0x08,0x5A,0x68, +0x01,0x07,0x44,0x10,0x00,0xFF,0xEA,0xD9,0x38,0x10,0x1D,0x09,0xFC,0xE0,0xFC,0x64, +0x84,0x20,0xB0,0x02,0xFA,0x48,0xDD,0x42,0x84,0x00,0x3E,0x4F,0xFE,0xC4,0x3E,0x3F, +0xFC,0x08,0x84,0xAC,0x38,0x12,0x01,0x01,0x3E,0xDF,0xFE,0xC4,0x5A,0x10,0xFF,0x13, +0x42,0x20,0x14,0x24,0x99,0x91,0x38,0x61,0x98,0x10,0x4E,0x65,0x00,0x0C,0x88,0x43, +0x88,0x22,0xA6,0x89,0xB0,0x42,0x38,0x10,0x88,0x00,0xB1,0x82,0x8C,0x21,0x38,0x13, +0x08,0x08,0x8C,0x01,0x5A,0x08,0x13,0xE8,0x84,0x00,0xB0,0x42,0x38,0x10,0x80,0x00, +0x97,0x00,0xC1,0x0A,0x84,0xC0,0x81,0x26,0xEA,0xE4,0x3F,0xCF,0xFE,0xC4,0x3E,0xBF, +0xFC,0x08,0x85,0xCC,0xD5,0x12,0x8C,0x01,0x5A,0x08,0x18,0xF1,0xEA,0x8D,0xD5,0x35, +0x42,0xC3,0x38,0x24,0x40,0x06,0x08,0x00,0x38,0x15,0x80,0x00,0x96,0x0A,0x4E,0x04, +0x00,0x0D,0x8C,0xC1,0x5A,0x60,0x13,0x23,0x38,0x26,0x99,0x01,0x54,0x83,0x00,0xFF, +0x94,0xF1,0x5A,0x28,0xFF,0xEF,0xD5,0xF6,0x40,0x05,0xB0,0x00,0x88,0x40,0xA7,0x51, +0xDC,0xF1,0x80,0x08,0xF3,0x81,0xB6,0x9F,0x49,0xFF,0xFD,0x33,0xF3,0x01,0xB4,0x9F, +0x38,0x2E,0x0C,0x01,0x5A,0x20,0xFF,0xE7,0x50,0x14,0x80,0x01,0x88,0x4C,0x54,0x90, +0x80,0xFF,0x38,0x75,0x88,0x00,0x81,0x48,0xD5,0xDD,0x5A,0x98,0x01,0xD1,0x38,0x06, +0xA9,0x01,0x5A,0x00,0xFF,0xCD,0x80,0x07,0xFC,0xE4,0xFC,0x42,0xB0,0xC2,0x97,0x81, +0x97,0xC9,0x3A,0x01,0x84,0x20,0x81,0x42,0xFD,0x03,0x49,0xFF,0xFB,0x58,0x5A,0xA8, +0x01,0x3C,0x9E,0x31,0x96,0x01,0x44,0x10,0xFF,0xFD,0xE2,0x20,0x4E,0xF3,0x00,0x50, +0xEA,0x36,0xC8,0x15,0x3C,0x93,0xFF,0xC0,0x4E,0x93,0x00,0x12,0xF8,0x5F,0x80,0x09, +0x3E,0x1F,0xFF,0x20,0x38,0x60,0x80,0x09,0x98,0x81,0x8C,0x04,0xAD,0xD1,0x5A,0x08, +0x4C,0xFB,0x3C,0x6B,0xFF,0xC1,0x3C,0x7B,0xFF,0xC0,0xD5,0x19,0x46,0x11,0x00,0x07, +0x00,0x10,0x83,0x9B,0x46,0x21,0x00,0x07,0xEA,0x5F,0x00,0x21,0x03,0x9C,0x40,0xF1, +0x05,0x00,0xE0,0x0F,0xE8,0x03,0x8C,0x01,0xEA,0xD5,0xFD,0x03,0x49,0xFF,0xF9,0x06, +0xFD,0x03,0x49,0xFF,0xFA,0x2C,0xFD,0x03,0x49,0xFF,0xF9,0xA0,0x3C,0x6B,0xFF,0xBF, +0x3C,0x7B,0xFF,0xBE,0xD5,0x1C,0x4E,0xA3,0x00,0x1F,0xEA,0x96,0xC0,0x09,0x2E,0x07, +0xFC,0xF8,0x5A,0x00,0xFF,0x16,0x84,0x3F,0x3E,0x17,0xFC,0xF8,0xD5,0x11,0xEA,0x36, +0xC0,0xF7,0x49,0xFF,0xFC,0x3A,0xB6,0x1F,0x49,0xFF,0xFF,0x3B,0xF0,0x81,0xF1,0x01, +0xB4,0x1F,0x49,0xFF,0xF8,0xB4,0x5A,0x08,0xFF,0x04,0xD5,0xEA,0xEA,0x8D,0xEA,0xFD, +0x5A,0x18,0x01,0x12,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x9B,0x46,0x21,0x00,0x07, +0xEA,0x5F,0x00,0x21,0x03,0x9C,0x40,0xF1,0x05,0x00,0xE0,0x0F,0xE8,0x03,0x8C,0x01, +0xEA,0xD5,0xEA,0x8D,0x4E,0xA3,0x00,0x06,0xB6,0x1F,0x49,0xFF,0xF7,0xCB,0xB4,0x1F, +0xFC,0xC2,0x3E,0x1F,0xFE,0x64,0xA6,0x08,0xFA,0x56,0xA6,0x49,0x8E,0x01,0x42,0x10, +0x08,0x73,0xEB,0x64,0x58,0x00,0x01,0x44,0x50,0x40,0x91,0xB8,0x40,0x40,0x10,0x20, +0xA5,0x62,0x3E,0x28,0x02,0xF4,0x97,0x6B,0xAD,0x50,0x9C,0xE4,0xA5,0x21,0x50,0x10, +0x94,0xB0,0x97,0x23,0xAD,0x15,0xA5,0x19,0x40,0x00,0x04,0x20,0x97,0x23,0xAD,0x16, +0x02,0x41,0x80,0x26,0x3E,0x18,0x02,0xE0,0x97,0x23,0xAD,0x14,0x02,0x41,0x80,0x25, +0x97,0x23,0xAD,0x12,0x02,0x41,0x80,0x27,0x97,0x23,0xAD,0x13,0x02,0x41,0x80,0x4C, +0x97,0x23,0xAD,0x11,0x02,0x41,0x80,0x4B,0x97,0x23,0xAD,0x17,0x02,0x31,0x80,0x4D, +0x96,0xDB,0x12,0x31,0x00,0x08,0xA4,0xC2,0x9C,0x84,0x96,0xDB,0xAC,0xC8,0xA4,0x01, +0x96,0x03,0xAC,0x0D,0xA4,0x11,0x96,0x03,0xAC,0x0E,0x02,0x01,0x00,0x26,0x96,0x03, +0xAC,0x0C,0x02,0x01,0x00,0x25,0x96,0x03,0xAC,0x0A,0x02,0x01,0x00,0x27,0x96,0x03, +0xAC,0x0B,0x02,0x01,0x00,0x4C,0x96,0x03,0xAC,0x09,0x02,0x01,0x00,0x4B,0x96,0x03, +0xAC,0x0F,0x02,0x01,0x00,0x4D,0x96,0x03,0x12,0x00,0x80,0x08,0xDD,0x9E,0x00,0x00, +0x46,0x21,0x00,0x01,0x58,0x21,0x0F,0xDC,0x38,0x31,0x05,0x00,0x38,0x31,0x01,0x08, +0x40,0x31,0x04,0x20,0xA6,0xD9,0x40,0x21,0x00,0x20,0xAE,0xD1,0x46,0x21,0x00,0x01, +0xEB,0x36,0x38,0x31,0x06,0x02,0x38,0x31,0x02,0x0A,0x84,0x4C,0x42,0x30,0x08,0x24, +0xFE,0x8C,0x46,0x41,0x00,0x02,0x58,0x42,0x00,0xB4,0x99,0x63,0x88,0x82,0x3B,0x02, +0x48,0x00,0x46,0x41,0x00,0x02,0x58,0x42,0x00,0x24,0x88,0x44,0x3B,0x02,0xC8,0x20, +0x88,0x64,0x3B,0x01,0x48,0x00,0x3E,0x28,0x01,0xCC,0x3B,0x01,0xC8,0x20,0x40,0x11, +0x04,0x40,0xEA,0xDA,0x3A,0x10,0x84,0x00,0x3A,0x10,0x04,0x20,0xDD,0x9E,0x92,0x00, +0x84,0x20,0x46,0x21,0x00,0x01,0xEB,0x36,0x38,0x11,0x02,0x0A,0x84,0x4C,0xFE,0x84, +0x46,0x31,0x00,0x02,0x58,0x31,0x80,0xB4,0x88,0x62,0xB6,0x23,0xA8,0x59,0xA8,0x5A, +0x46,0x31,0x00,0x02,0x58,0x31,0x80,0x24,0x88,0x43,0xB6,0x22,0xA8,0x51,0xA8,0x52, +0x2E,0x37,0xFD,0x05,0x3E,0x28,0x01,0xCC,0x38,0x31,0x02,0x08,0xEA,0xDA,0xAE,0x41, +0xAE,0x42,0x2E,0x17,0xFD,0x16,0xAE,0x43,0xDD,0x9E,0x92,0x00,0x3B,0xFF,0xFC,0xBC, +0x51,0xFF,0xFF,0xFC,0x49,0xFF,0xFF,0x3F,0x3C,0x00,0x01,0x7E,0x96,0x03,0x4E,0x05, +0x00,0xAF,0x3C,0x20,0x01,0x7E,0x80,0xA2,0x46,0x11,0x00,0x01,0x2E,0x07,0xFE,0x65, +0x00,0x10,0x8F,0xF3,0xE2,0x20,0xE8,0x49,0x9A,0x41,0xE4,0x22,0x4E,0xF3,0x00,0x4A, +0x2E,0x17,0xFE,0x64,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x2C,0x98,0x93,0x46,0x31, +0x00,0x02,0x04,0x41,0x80,0x2A,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x2B,0xF8,0x52, +0x46,0x51,0x00,0x02,0x14,0x22,0x80,0x2C,0x46,0x21,0x00,0x02,0x14,0x41,0x00,0x2A, +0x46,0x21,0x00,0x02,0x14,0x31,0x00,0x2B,0x2E,0x20,0x01,0xF9,0xE2,0x40,0xE8,0x5D, +0x3E,0x00,0x01,0xF9,0x2E,0x20,0x01,0xFA,0xE2,0x41,0xE8,0x4F,0x3E,0x10,0x01,0xFA, +0xFA,0x56,0x42,0x00,0x88,0x73,0x46,0x11,0x00,0x02,0xEB,0x17,0x50,0x00,0x14,0xB0, +0x94,0x01,0x88,0x01,0x22,0x10,0x00,0x02,0x5A,0x10,0xFE,0x50,0xEA,0x4F,0x2E,0x27, +0xFE,0x64,0xAC,0xC2,0x2E,0x17,0xFE,0x65,0x3E,0x27,0xFE,0x60,0xEC,0x04,0x3E,0x17, +0xFE,0x61,0x3B,0xFF,0xFC,0x84,0xDD,0x9E,0x8A,0x20,0xE4,0x22,0x4E,0xF2,0xFF,0xBA, +0x46,0x31,0x00,0x01,0x2E,0x17,0xFE,0x64,0x00,0x31,0x8F,0xF2,0xE2,0x61,0xE8,0x53, +0x9A,0xCB,0xE4,0x62,0x4E,0xF2,0xFF,0xB0,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x50, +0x88,0x43,0x46,0x31,0x00,0x02,0x04,0x41,0x80,0x4E,0x46,0x31,0x00,0x02,0x04,0x31, +0x80,0x4F,0x42,0x42,0x80,0x73,0x42,0x32,0x84,0x73,0x4A,0x00,0x00,0x60,0x46,0x51, +0x00,0x02,0x14,0x22,0x80,0x50,0x46,0x21,0x00,0x02,0x14,0x41,0x00,0x4E,0x46,0x21, +0x00,0x02,0x14,0x31,0x00,0x4F,0xD5,0xA9,0x2E,0x20,0x01,0xFB,0xE2,0x22,0xE8,0xB1, +0x3E,0x10,0x01,0xFB,0x48,0xFF,0xFF,0xAE,0x2E,0x20,0x01,0xF8,0xE2,0x02,0xE8,0xA3, +0x3E,0x00,0x01,0xF8,0x48,0xFF,0xFF,0xA0,0x2E,0x27,0xFD,0x36,0x46,0x11,0x00,0x02, +0x04,0x10,0x80,0x08,0x8C,0x21,0xEA,0x4F,0xAC,0xC2,0xE2,0x41,0xEB,0x64,0x14,0x10, +0x00,0x08,0xE8,0x17,0x2E,0x17,0xFE,0x64,0x2E,0x07,0xFE,0x65,0x3E,0x17,0xFE,0x60, +0xEC,0x04,0x3E,0x07,0xFE,0x61,0x3B,0xFF,0xFC,0x84,0xDD,0x9E,0x84,0xA0,0x84,0x40, +0x48,0xFF,0xFF,0x54,0x8A,0x61,0xE4,0x62,0x4E,0xF2,0xFF,0x5E,0x48,0xFF,0xFF,0xAE, +0x49,0xFF,0xCE,0xF3,0xC8,0xE8,0xDD,0x5B,0xC1,0x1C,0x3C,0x00,0x01,0x70,0xEA,0xA6, +0x97,0x43,0xD2,0x17,0xEA,0x22,0xEA,0x80,0xEB,0x1E,0x4E,0x00,0x00,0x56,0xE9,0x11, +0x8E,0x21,0xDD,0x51,0x49,0xFF,0xFF,0x2C,0x2E,0x07,0xFE,0x60,0x50,0x00,0x00,0x01, +0x2E,0x17,0xFE,0x61,0x3E,0x07,0xFE,0x64,0xEA,0x7A,0xEA,0x2D,0x2E,0x17,0xFE,0x64, +0xEA,0xE7,0x8E,0x01,0xE0,0x20,0xE8,0x19,0x3C,0x00,0x01,0x71,0xEA,0xA6,0x97,0x43, +0xD2,0x14,0xEA,0x22,0xEA,0x80,0xEB,0x1D,0xF8,0x37,0xE9,0x0F,0x9C,0x49,0xDD,0x51, +0x49,0xFF,0xFF,0x0E,0x2E,0x07,0xFE,0x60,0x50,0x00,0x7F,0xFF,0x2E,0x17,0xFE,0x61, +0x3E,0x07,0xFE,0x64,0xEA,0x7A,0xEA,0x2D,0xEA,0xCC,0xC1,0x19,0x3C,0x00,0x01,0x72, +0xEA,0xA6,0x97,0x43,0xD2,0x14,0xEA,0x22,0xEA,0x80,0x3C,0x30,0x01,0x7C,0xF8,0x1C, +0xE9,0x0E,0x9E,0x49,0xEA,0x7A,0xEA,0x25,0xEA,0x44,0xEA,0x41,0x50,0x00,0x00,0x01, +0xDD,0x51,0xEA,0x46,0x49,0xFF,0xFE,0x2F,0x2E,0x17,0xFE,0x65,0xEA,0xC5,0x8E,0x01, +0xE0,0x20,0xE8,0x1B,0x3C,0x00,0x01,0x73,0xEA,0xA6,0x97,0x43,0xD2,0x16,0xEA,0x22, +0xEA,0x80,0x3C,0x30,0x01,0x7D,0x96,0x03,0x96,0xDB,0x88,0x02,0xE0,0x03,0x83,0xFF, +0xE9,0x0C,0x9C,0x49,0xEA,0x7A,0xEA,0x25,0xEA,0x44,0xEA,0x41,0x50,0x00,0x7F,0xFF, +0xDD,0x51,0xEA,0x46,0x49,0xFF,0xFE,0x0F,0xDD,0x5B,0x4E,0x12,0x00,0x51,0xEA,0x83, +0xC2,0x20,0x3C,0x00,0x01,0x75,0xEA,0x4F,0x97,0x43,0xD3,0x1B,0xEA,0x22,0xEA,0x78, +0xEB,0x1E,0xF8,0x75,0xE9,0x16,0xEA,0xA1,0x3C,0x00,0x01,0x7C,0xF8,0x7A,0xE9,0x11, +0x3C,0x00,0x01,0x7A,0x3C,0x40,0x01,0x7C,0x3C,0x50,0x01,0x7F,0x97,0x23,0x96,0x03, +0xEA,0xA7,0x88,0x04,0x88,0x03,0x97,0x2B,0x40,0xF0,0x10,0x07,0x4E,0xF2,0x00,0xA6, +0xEA,0xC5,0x8E,0x01,0xE0,0x40,0xE8,0x2B,0x3C,0x00,0x01,0x76,0xEA,0x4F,0x97,0x43, +0xD3,0x26,0xEA,0x22,0xEA,0x78,0xEB,0x1E,0xF8,0x52,0xE9,0x21,0xEA,0xA1,0x3C,0x00, +0x01,0x7D,0xF8,0x57,0xE9,0x1C,0x3C,0x00,0x01,0x7A,0x3C,0x40,0x01,0x7D,0x3C,0x50, +0x01,0x80,0x97,0x23,0x96,0x03,0xEA,0xA7,0x4E,0x00,0x00,0x5C,0xE9,0x10,0x8E,0x21, +0x8C,0x41,0xDD,0x51,0xEA,0xBC,0xEA,0x25,0xEA,0x41,0xEA,0x44,0x8C,0x21,0x8E,0x01, +0xDD,0x51,0xEA,0x46,0x49,0xFF,0xFD,0xBF,0x2E,0x17,0xFE,0x64,0xEA,0xE7,0x8E,0x01, +0xE0,0x20,0x4E,0xF2,0xFF,0x21,0xEA,0x83,0xC2,0x1C,0x3C,0x00,0x01,0x77,0xEA,0x4F, +0x97,0x43,0xD3,0x17,0xEA,0x22,0xEA,0x78,0xEB,0x1D,0xF8,0x21,0xE9,0x12,0xEA,0xA1, +0x3C,0x00,0x01,0x7C,0xF8,0x26,0xE9,0x0D,0x3C,0x00,0x01,0x7B,0x3C,0x40,0x01,0x7C, +0x3C,0x50,0x01,0x81,0x97,0x23,0x96,0x03,0xEA,0xA7,0x4E,0x00,0x00,0x2B,0xE8,0x3D, +0xEA,0xC5,0x8E,0x01,0xE0,0x40,0x4E,0xF2,0xFE,0xFF,0x3C,0x00,0x01,0x78,0xEA,0x4F, +0x97,0x43,0x4C,0x51,0xBE,0xF9,0xEA,0x22,0xEA,0x78,0xEB,0x1D,0x96,0x03,0x96,0xDB, +0x88,0x04,0xE0,0x03,0x83,0xFF,0x4E,0xF3,0xFE,0xEF,0xEA,0xA1,0x3C,0x00,0x01,0x7D, +0x96,0xDB,0x97,0x43,0x98,0x23,0xE0,0x05,0x83,0xFF,0x4E,0xF3,0xFE,0xE5,0x3C,0x00, +0x01,0x7B,0x3C,0x40,0x01,0x7D,0x3C,0x50,0x01,0x82,0x97,0x23,0x96,0x03,0xEA,0xA7, +0x88,0x04,0x88,0x03,0x97,0x2B,0xE0,0x04,0x83,0xFF,0x4E,0xF3,0xFE,0xD5,0x8C,0x21, +0x9C,0x91,0xDD,0x51,0xEA,0xBC,0xEA,0x25,0xEA,0x41,0xEA,0x44,0x8E,0x21,0x8E,0x01, +0xDD,0x51,0xEA,0x46,0x48,0xFF,0xFE,0xC8,0x8C,0x21,0x8E,0x41,0xDD,0x51,0xEA,0xBC, +0x49,0xFF,0xFE,0x16,0xEA,0x41,0xEA,0x44,0x8E,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x46, +0x49,0xFF,0xFD,0x51,0xEA,0xE7,0xDD,0x5B,0x8E,0x01,0x40,0x00,0x80,0x07,0x4E,0x02, +0xFE,0xB3,0xEA,0x83,0x48,0xFF,0xFF,0xAE,0x8E,0x21,0x50,0x21,0x7F,0xFF,0xDD,0x51, +0xEA,0xBC,0xEA,0x25,0xEA,0x41,0xEA,0x44,0x8C,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x46, +0x49,0xFF,0xFD,0x39,0xDD,0x5B,0x4E,0x12,0xFF,0x7B,0xEA,0x83,0x48,0xFF,0xFF,0x4A, +0x84,0x00,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD4,0x46,0x11,0x00,0x05,0x12,0x00, +0x82,0xD5,0x2E,0x20,0x01,0x29,0x2E,0x10,0x01,0x28,0x2E,0x37,0xFD,0x2A,0x3A,0x6F, +0xB4,0x3C,0x2F,0x37,0xFD,0x26,0x84,0x80,0x44,0x90,0x00,0x48,0x47,0x11,0x00,0x02, +0x59,0x18,0x81,0x44,0x44,0xA0,0x00,0x4C,0x44,0xB0,0x00,0xFE,0x47,0x21,0x00,0x01, +0x59,0x29,0x0E,0xB0,0x96,0x20,0xE2,0x02,0xE8,0x36,0x80,0xD1,0x80,0xF1,0x42,0x62, +0x24,0x73,0x42,0x72,0x28,0x73,0x50,0x63,0x19,0x54,0x50,0x73,0xA9,0xB2,0x84,0xA0, +0x51,0x00,0x00,0x01,0xD1,0x1E,0xA4,0x30,0x8C,0xA1,0x96,0x03,0xE0,0x60,0xE8,0x15, +0x12,0xB3,0x80,0x00,0xEB,0x4E,0xEA,0xA4,0x40,0xC9,0x00,0x20,0x5C,0xF0,0x00,0x95, +0x39,0x09,0x01,0x08,0x10,0x56,0x00,0x01,0xE8,0x04,0x8C,0x01,0x40,0x00,0x00,0x13, +0x46,0xC1,0x00,0x05,0x12,0x06,0x02,0xD4,0x8C,0xC2,0x97,0x68,0x8C,0xE2,0xD5,0xE3, +0xEB,0x4E,0xEA,0xA4,0x8C,0x81,0xE2,0x13,0xE9,0xCE,0x84,0x01,0xEA,0xF8,0x44,0x00, +0x00,0x00,0xEA,0x64,0x2E,0x60,0x00,0xFF,0x4E,0x63,0x00,0x0E,0xEB,0x4E,0x02,0x50, +0x02,0xD5,0xEA,0xD1,0x9F,0x01,0x2E,0x00,0x00,0x11,0x8E,0x01,0xFE,0x24,0xE0,0xA0, +0xE9,0x26,0xD5,0x23,0x44,0x00,0x00,0x64,0xFF,0x84,0x41,0x00,0x84,0x08,0xEB,0x54, +0xEA,0xAC,0x84,0xA0,0xD2,0xEC,0x80,0x80,0x41,0x10,0x40,0x00,0x4C,0x48,0x80,0x11, +0xA5,0xE0,0x97,0xFB,0xE0,0xC7,0xE8,0x0A,0x46,0x71,0x00,0x05,0x02,0x73,0x82,0xD5, +0x46,0x91,0x00,0x05,0x8C,0xE1,0x12,0x74,0x82,0xD5,0x8C,0x82,0xD5,0xF0,0x8C,0xA1, +0x97,0x68,0x50,0x00,0x00,0x48,0xD5,0xE7,0x48,0x00,0x00,0x00,0x2E,0x08,0x00,0x14, +0x4E,0x04,0x00,0x4E,0x46,0x51,0x00,0x02,0x58,0x52,0x81,0x44,0x9D,0xC9,0x84,0x00, +0x8C,0x41,0x45,0x00,0x00,0x4C,0x82,0x25,0x44,0x60,0x00,0xFC,0xFB,0xD6,0xE0,0x40, +0xE9,0x1A,0x80,0x85,0x42,0x40,0x40,0x73,0x22,0xF2,0x11,0xBA,0xE0,0x6F,0xE8,0x03, +0x12,0x62,0x14,0xB2,0x80,0x87,0x42,0x40,0x48,0x73,0x41,0x38,0x90,0x20,0x22,0xF9, +0x91,0xBA,0xE0,0x6F,0xE8,0x05,0x40,0x42,0x90,0x20,0x12,0x62,0x14,0xB2,0x8C,0x01, +0x96,0x00,0xD5,0xE6,0x46,0x41,0x00,0x02,0x58,0x42,0x01,0x44,0xFA,0xB6,0x8C,0x21, +0x84,0x00,0x80,0xE4,0x44,0x60,0x00,0xFC,0xFE,0xAC,0xE0,0x20,0xE9,0x18,0x40,0x52, +0x00,0x20,0x22,0xF2,0x91,0xBA,0xE0,0x6F,0xE8,0x03,0x12,0x62,0x94,0xB2,0x99,0x50, +0x41,0x03,0x94,0x20,0x22,0xF8,0x11,0xBA,0xE0,0x6F,0xE8,0x05,0x40,0x52,0x14,0x20, +0x12,0x62,0x94,0xB2,0x8C,0x01,0x96,0x00,0x48,0xFF,0xFF,0xE9,0x3A,0x6F,0xB4,0x04, +0xDD,0x9E,0x92,0x00,0x3A,0x6F,0xBA,0xBC,0xEF,0xFC,0x3F,0xCF,0xFE,0x1C,0x84,0xC0, +0x80,0x06,0x8C,0xC1,0x54,0x63,0x00,0xFF,0x49,0xFF,0xFC,0xDC,0x5A,0x68,0x0C,0xFA, +0x84,0x20,0xB9,0x80,0xB9,0x8E,0xEB,0x4E,0x02,0x20,0x02,0xD4,0x2E,0x07,0xFD,0x36, +0x92,0x01,0xE2,0x40,0xE8,0x24,0x3C,0x03,0xFE,0xC7,0x8C,0x01,0x96,0x01,0xEA,0x64, +0x2E,0x47,0xFF,0xC3,0x84,0x6A,0xFE,0xE4,0xE0,0x60,0xE8,0x19,0x3C,0x1B,0xFE,0xC7, +0x3E,0x17,0xFD,0x57,0x3E,0x17,0xFD,0x65,0xC2,0x13,0x84,0xC0,0x46,0xB1,0x00,0x02, +0x58,0xB5,0x80,0xB4,0x80,0xE6,0x46,0x91,0x00,0x01,0x58,0x94,0x8E,0xB0,0x46,0xA1, +0x00,0x02,0x58,0xA5,0x01,0x44,0x81,0x8B,0x48,0x00,0x00,0x5F,0xCA,0x06,0x84,0x00, +0xEA,0x64,0x3E,0x07,0xFD,0x57,0xEA,0xF8,0xEA,0x96,0xC0,0xE8,0xEA,0x6A,0x96,0x04, +0xC0,0xE5,0x84,0x00,0x3E,0x07,0xFD,0x68,0x48,0x00,0x00,0x9E,0x40,0x24,0x84,0x20, +0xA7,0x11,0x38,0x34,0x85,0x00,0x80,0x44,0x42,0x21,0xC0,0x73,0x41,0x15,0x08,0x20, +0x23,0x18,0x94,0xB2,0x5B,0x10,0xFE,0x4C,0x8C,0x21,0x96,0x48,0xE2,0x25,0xE9,0xEF, +0x4E,0x02,0x00,0x74,0x46,0x01,0x00,0x01,0x10,0x70,0x0F,0xF2,0x46,0x01,0x00,0x01, +0x10,0x60,0x0F,0xF3,0x3E,0x77,0xFE,0x64,0x3E,0x67,0xFE,0x65,0x49,0xFF,0xFC,0xA0, +0x2E,0x17,0xFD,0x36,0xEB,0x64,0x04,0x00,0x00,0x08,0xE2,0x20,0xE8,0x06,0x84,0x01, +0x3E,0x07,0xFD,0x57,0x84,0x00,0xEA,0x64,0x2E,0x07,0xFF,0xA2,0x96,0x04,0xC8,0x31, +0xB8,0x00,0xC0,0x4E,0x9E,0x41,0x84,0x4C,0x80,0x6B,0x42,0x30,0x88,0x73,0x46,0x11, +0x00,0x02,0xA0,0xDA,0x04,0x10,0x80,0x50,0xE2,0x61,0xE8,0x42,0x96,0x00,0x81,0xC2, +0x4E,0x03,0x00,0x2A,0xB8,0x00,0xE6,0x0B,0xE8,0x04,0x9C,0x01,0x3C,0x0F,0xFF,0x87, +0xB8,0x0E,0x8C,0x01,0xB8,0x8E,0x84,0x0B,0x49,0xFF,0xFC,0x4C,0x46,0x01,0x00,0x05, +0x02,0x50,0x02,0xD4,0x84,0x00,0x80,0x20,0xFB,0x96,0xD5,0xB9,0x40,0x25,0x08,0x20, +0x22,0x21,0x11,0xBA,0xE0,0x02,0xE8,0xB1,0x96,0x11,0x80,0xC4,0x80,0xE3,0xD5,0xAD, +0x2E,0x07,0xFD,0x57,0xC0,0xCE,0xEA,0x45,0x96,0x00,0xC8,0xCB,0xB8,0x80,0x84,0x01, +0xEA,0xF8,0xD5,0x31,0x50,0xD0,0x7F,0xFF,0x80,0x2C,0x42,0x16,0xB8,0x73,0xA0,0x8A, +0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x50,0xE2,0x41,0xE8,0xCD,0x80,0x2D,0xEA,0xFE, +0x80,0x0D,0x44,0x10,0x00,0x0B,0xEA,0xFE,0x54,0x06,0x80,0xFF,0xD5,0xC2,0x84,0x2B, +0x49,0xFF,0xFB,0xE0,0x48,0xFF,0xFF,0xC0,0x3C,0x2D,0xFF,0x87,0x2E,0x37,0xFD,0x49, +0x46,0x41,0x00,0x01,0x58,0x42,0x0F,0xF4,0x80,0x20,0xE2,0x22,0xE8,0x0A,0x38,0x52, +0x06,0x02,0xE2,0x65,0xE8,0x03,0x8C,0x01,0x96,0x00,0x8C,0x21,0x96,0x48,0xD5,0xF6, +0x3E,0x07,0xFD,0x4F,0xEC,0x04,0x3A,0x6F,0xBA,0x84,0xDD,0x9E,0xFC,0x60,0x51,0xFF, +0xFB,0xA0,0x3D,0x3D,0xFF,0x87,0x4F,0x32,0x02,0xEB,0x46,0x37,0xFF,0xFF,0x84,0x20, +0xB1,0x50,0xB1,0xDC,0xB1,0xA8,0x51,0x1F,0x80,0xD0,0x51,0x2F,0x81,0x00,0x50,0x2F, +0x81,0x30,0x50,0xBF,0x81,0x60,0x50,0x31,0x8F,0xFF,0x84,0x00,0xB1,0x04,0x38,0x02, +0x06,0x0A,0x50,0x4F,0x81,0x90,0x38,0x02,0x06,0x0A,0x50,0x9F,0x82,0x20,0xEA,0xC6, +0x42,0x90,0x90,0x73,0x38,0x02,0x86,0x0A,0x38,0x03,0x86,0x0A,0x38,0x03,0x06,0x0A, +0x38,0x08,0x86,0x0A,0x38,0x09,0x06,0x0A,0x38,0x01,0x06,0x0A,0x38,0x05,0x86,0x0A, +0x80,0x89,0x38,0x32,0x02,0x0A,0x8C,0x01,0x5A,0x08,0x0C,0xFD,0x8C,0x21,0x5A,0x18, +0x0C,0xDE,0x3C,0x9D,0xFF,0x91,0x84,0x80,0xE3,0x33,0x80,0x13,0x47,0x97,0xFF,0xFF, +0x40,0x04,0xBC,0x1A,0x80,0x64,0x46,0xC1,0x00,0x01,0x58,0xC6,0x0D,0x08,0x45,0xE0, +0xFF,0xFF,0x51,0x9C,0x8F,0xFF,0x46,0xD1,0x00,0x01,0x58,0xD6,0x8D,0x98,0x40,0x99, +0xA4,0x06,0x47,0x51,0x00,0x01,0x59,0x5A,0x8C,0x0C,0x47,0x61,0x00,0x01,0x59,0x6B, +0x0C,0x3C,0x38,0xE6,0x13,0x02,0x94,0x63,0x4C,0xEF,0x00,0x41,0x50,0xAF,0x82,0x20, +0x40,0xA5,0x0C,0x40,0x40,0x80,0xB0,0x00,0x41,0x42,0x08,0x08,0x86,0x00,0xE1,0x80, +0xE8,0x31,0xE3,0x93,0xE8,0x29,0x38,0x16,0xC3,0x02,0x04,0xF4,0x00,0x01,0x41,0x80, +0xB8,0x01,0x40,0x16,0xC0,0x60,0xA0,0x49,0x40,0xF0,0xBC,0x01,0x43,0x77,0xBC,0x24, +0x2E,0x17,0xFD,0x27,0x43,0x7C,0x60,0x73,0x15,0x75,0x00,0x00,0xC9,0x17,0x4E,0x92, +0x00,0x16,0x38,0x1A,0xD0,0x02,0x43,0x8C,0x04,0x24,0x38,0x1B,0x50,0x02,0x42,0x17, +0x84,0x24,0xE0,0x38,0xE8,0x04,0x40,0x1C,0x04,0x01,0xD5,0x02,0x8A,0x38,0x94,0x4D, +0x88,0x37,0xB6,0x2A,0xD5,0x03,0x15,0x95,0x00,0x00,0x8D,0x81,0x50,0xA5,0x00,0x30, +0xD5,0xCF,0xEB,0x10,0x38,0x40,0x8E,0x0A,0x8C,0x61,0x8C,0x81,0x5A,0x48,0x0C,0xBB, +0x46,0x47,0xFF,0xFF,0x45,0x30,0x00,0x30,0x50,0x42,0x0F,0xFF,0xE0,0x60,0xE8,0x10, +0x50,0x1F,0x82,0x20,0x41,0x00,0x8C,0x40,0x84,0x20,0xE0,0x20,0xE8,0x07,0x42,0x90, +0xCC,0x24,0x8C,0x21,0x38,0x48,0x24,0x0A,0xD5,0xF9,0x8C,0x61,0xD5,0xF0,0x84,0x20, +0x46,0x37,0xFF,0xFF,0x84,0x9F,0x82,0x01,0x50,0x31,0x8F,0xFF,0xE0,0x20,0xE8,0x0B, +0x38,0x42,0x86,0x0A,0x38,0x43,0x86,0x0A,0x39,0x09,0x06,0x0A,0x38,0x31,0x06,0x0A, +0x8C,0x21,0xD5,0xF5,0x51,0x0F,0x82,0x20,0x80,0x30,0x86,0x60,0x44,0xA0,0x00,0x30, +0xE1,0xE0,0xE8,0x1D,0xB4,0x81,0x84,0x61,0xE0,0x60,0xE8,0x09,0x42,0x91,0xA8,0x24, +0x8C,0x61,0x38,0x90,0xA4,0x02,0x42,0x42,0x24,0x01,0xD5,0xF7,0xC4,0x0D,0x84,0x60, +0xE0,0x60,0xE8,0x0A,0x42,0xC1,0xA8,0x24,0x8C,0x61,0x38,0x90,0xB0,0x02,0x8B,0x24, +0x38,0x90,0xB0,0x0A,0xD5,0xF6,0x8D,0xE1,0x8C,0x24,0xD5,0xE3,0x85,0x80,0x80,0x2C, +0x85,0x5F,0xE0,0x20,0xE8,0x2B,0xB5,0xF0,0x84,0x61,0xE0,0x60,0xE8,0x07,0x38,0x98, +0x0E,0x02,0x8C,0x61,0x43,0x39,0xA4,0x01,0xD5,0xF9,0x39,0x38,0x86,0x0A,0x84,0x60, +0xE0,0x60,0xE8,0x11,0x38,0x98,0x0E,0x02,0x4D,0x34,0xC0,0x0C,0x38,0x92,0x8E,0x02, +0x4E,0x94,0x00,0x08,0xB1,0x04,0x38,0x32,0x06,0x0A,0x38,0x12,0x8E,0x0A,0xD5,0x0A, +0x8C,0x61,0xD5,0xEF,0xB0,0xC4,0x38,0x13,0x32,0x0A,0x38,0xA1,0x86,0x0A,0x50,0xC6, +0x00,0x01,0x8C,0x21,0x51,0x08,0x00,0x30,0xD5,0xD5,0x82,0xEC,0x4E,0xC3,0x00,0x0C, +0x84,0x00,0x50,0xDF,0x81,0xC0,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x98,0xEA,0xC7, +0x48,0x00,0x00,0xAC,0x47,0x37,0xFF,0xFF,0x51,0x39,0x8F,0xFF,0x80,0x6C,0x85,0x40, +0x44,0xC0,0x00,0x30,0x81,0xB3,0x85,0x1F,0x86,0x80,0x40,0xFA,0x0C,0x07,0xE8,0x2D, +0x39,0x03,0x52,0x02,0x51,0x5F,0x82,0x20,0x39,0x68,0xC2,0x02,0x43,0x58,0x30,0x73, +0x84,0x20,0xE0,0x20,0xE8,0x1F,0xEB,0x35,0xE8,0x1B,0x38,0x9A,0x86,0x02,0x40,0xE4, +0xD8,0x01,0x38,0x49,0x06,0x02,0x88,0x8E,0xE0,0x8F,0xE8,0x12,0xCC,0x0D,0x38,0xE2, +0x86,0x02,0x4E,0xE5,0x00,0x59,0x38,0xE3,0x0E,0x0A,0x38,0x41,0x06,0x0A,0x39,0x03, +0x86,0x0A,0x8C,0x61,0xD5,0x05,0x38,0x41,0x06,0x0A,0x39,0x05,0x86,0x0A,0x8C,0x21, +0xD5,0xE1,0x51,0x4A,0x00,0x01,0xD5,0xD2,0x81,0xCD,0x84,0x20,0xE0,0x20,0xE8,0x07, +0xEB,0x35,0xE8,0x03,0x42,0xE7,0x3C,0x01,0x8C,0x21,0xD5,0xF9,0x86,0x00,0xE1,0x83, +0xE8,0x0A,0x38,0x93,0x42,0x02,0x8D,0x81,0x38,0x18,0xA6,0x02,0x88,0x2E,0x38,0x18, +0xA6,0x0A,0xD5,0xF6,0x43,0x41,0xA8,0x00,0x84,0x20,0xE0,0x20,0xE8,0xB7,0xEB,0x35, +0x50,0x90,0x80,0x01,0xE8,0x21,0x40,0xF7,0xB8,0x01,0x38,0xF1,0x06,0x0A,0xE9,0x21, +0x38,0xF2,0x86,0x02,0x39,0x05,0x86,0x02,0x4E,0xF4,0x00,0x11,0x80,0x69,0xE0,0x60, +0xE8,0x1A,0x38,0xF1,0x0E,0x02,0xE9,0x08,0x50,0x4F,0x81,0x00,0x38,0x92,0x0E,0x02, +0x89,0x2E,0x38,0x92,0x0E,0x0A,0x8C,0x61,0xD5,0xF3,0x38,0xF3,0x0E,0x0A,0x39,0x03, +0x86,0x0A,0x8C,0x61,0xD5,0x06,0x39,0x09,0x06,0x02,0x89,0x8E,0x39,0x09,0x06,0x0A, +0x80,0x29,0xD5,0xD4,0xB0,0xC4,0x38,0x31,0xC2,0x02,0xB1,0x04,0x38,0x12,0x42,0x0A, +0x39,0x02,0x86,0x0A,0x4E,0x35,0x00,0x06,0x39,0x03,0x8E,0x02,0x80,0x23,0xD5,0xF3, +0x51,0x7B,0xFF,0xFF,0x4F,0x72,0xFF,0x66,0x84,0x20,0xE0,0x20,0xE8,0x07,0x38,0x83, +0x86,0x0A,0x39,0x31,0x06,0x0A,0x8C,0x21,0xD5,0xF9,0x84,0x60,0x80,0x23,0xE0,0x20, +0x4E,0xF2,0xFF,0x6C,0xB1,0x04,0x39,0x02,0x06,0x02,0x4F,0x04,0x00,0x05,0x38,0x13, +0x0E,0x0A,0x8C,0x61,0x8C,0x21,0xD5,0xF4,0x98,0x58,0xEA,0x6B,0x40,0x40,0x34,0x00, +0x38,0x21,0x80,0x0A,0x8C,0x08,0x3B,0x02,0x44,0x20,0xA8,0x89,0x47,0x41,0x00,0x01, +0x59,0x4A,0x0D,0x98,0x5A,0x08,0x60,0xF2,0x84,0xE0,0x47,0x61,0x00,0x01,0x59,0x6B, +0x0D,0x08,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0C,0x3C,0x47,0x51,0x00,0x01,0x59,0x5A, +0x8C,0x6C,0x3D,0x3D,0xFF,0x87,0xE2,0xF3,0x4E,0xF2,0x00,0xFA,0x2E,0x57,0xFD,0x61, +0xB0,0x44,0x38,0x20,0x9E,0x02,0x3C,0x1D,0xFF,0x91,0x2E,0x37,0xFD,0x56,0xE2,0x41, +0x2E,0x00,0x01,0x32,0x4E,0xF2,0x00,0x77,0xEB,0x10,0x38,0x60,0x8A,0x02,0x46,0xC1, +0x00,0x01,0x58,0xC6,0x0C,0xD8,0x38,0x16,0x1A,0x02,0xC9,0x03,0xFF,0x44,0xD5,0x03, +0x44,0x50,0x00,0x64,0x46,0x21,0x00,0x01,0xEB,0x1B,0x38,0x21,0x1B,0x02,0x39,0x06, +0x9F,0x02,0x40,0x83,0x8C,0x08,0x40,0x98,0x08,0x01,0x40,0x26,0xA0,0x00,0x05,0x11, +0x00,0x01,0x46,0x21,0x00,0x01,0xEB,0x1B,0x40,0x21,0x18,0x60,0xA0,0x91,0x40,0xA8, +0x88,0x01,0x46,0x21,0x00,0x01,0x58,0x21,0x0D,0x74,0x38,0x21,0x18,0x00,0x42,0xB5, +0x28,0x24,0x42,0xB4,0xA4,0x73,0x5A,0x28,0x01,0x2B,0x2F,0xE0,0x01,0x2B,0x3C,0x23, +0xFE,0xC9,0x84,0x80,0x41,0x21,0x04,0x08,0x3C,0x23,0xFE,0xC5,0x41,0x71,0x04,0x08, +0xE0,0x9E,0xE8,0x1D,0x38,0x2A,0x93,0x02,0x41,0x82,0x0C,0x08,0xE3,0x82,0xE8,0x03, +0x8A,0x50,0xD5,0x03,0x40,0x28,0x08,0x01,0xE2,0x52,0xE8,0x0F,0x46,0x21,0x00,0x01, +0x58,0x21,0x0C,0x6C,0x88,0x58,0xA0,0x91,0xE3,0xA2,0xE8,0x03,0x8A,0x51,0xD5,0x03, +0x40,0x28,0x88,0x01,0xE2,0x57,0xE9,0x4B,0x8C,0x81,0xD5,0xE3,0x84,0x41,0x96,0xDF, +0x8C,0x67,0xFE,0x1C,0x88,0x25,0x85,0xE7,0x40,0x15,0x84,0x37,0x40,0xF0,0x3D,0xF6, +0xE2,0x2F,0xE9,0x42,0x2E,0x07,0xFD,0x4E,0x2E,0x47,0xFD,0x60,0xEB,0x78,0x58,0x10, +0x8C,0xCC,0x9D,0x43,0x84,0x7D,0x38,0x10,0x98,0x00,0x42,0x52,0x0C,0x73,0xE0,0x25, +0xE9,0x30,0x84,0x00,0xEA,0xC7,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x08,0x38,0x51, +0x83,0x02,0x94,0x43,0xDA,0x1E,0x44,0x20,0xFF,0xFD,0x46,0x31,0x00,0x01,0x58,0x31, +0x8C,0x0C,0x38,0x2B,0x03,0x0A,0x84,0x40,0x38,0x21,0x82,0x0A,0x40,0x36,0x9C,0x60, +0x88,0x34,0x3B,0x01,0xC4,0x00,0xEA,0xEA,0xEB,0x78,0xEA,0x71,0x38,0x70,0x80,0x08, +0xEB,0x78,0x58,0x10,0x8C,0xD8,0x38,0x27,0x02,0x0A,0x38,0x20,0x82,0x0A,0xD5,0x04, +0x8C,0x01,0x5A,0x08,0x0C,0xDA,0x8C,0xE1,0x48,0xFF,0xFF,0x4D,0x84,0x42,0xD5,0xB8, +0xE7,0xE3,0xE8,0xD0,0xC0,0xCF,0x96,0x30,0x15,0x5F,0x80,0x03,0x15,0x6F,0x80,0x02, +0x15,0x4F,0x80,0x01,0xB6,0x5F,0x49,0xFF,0xE5,0x69,0xB4,0x5F,0x05,0x4F,0x80,0x01, +0x05,0x6F,0x80,0x02,0x05,0x5F,0x80,0x03,0xC8,0xBD,0x3C,0x33,0xFE,0xC9,0x3C,0x13, +0xFE,0xC5,0xFE,0x5C,0xFE,0x8C,0xE2,0x4B,0xE8,0x09,0xEB,0x78,0x58,0x10,0x8C,0x0C, +0x38,0x07,0x1A,0x0A,0x38,0x00,0x9A,0x0A,0xD5,0xD7,0xB0,0x04,0x38,0x00,0x1E,0x02, +0xEB,0x10,0x38,0x00,0x82,0x02,0x89,0x0D,0x40,0x0A,0x00,0x60,0x3B,0x04,0x44,0x00, +0x3B,0x00,0x44,0x20,0x46,0x01,0x00,0x01,0x58,0x00,0x0D,0x68,0x38,0x70,0x18,0x08, +0x2E,0x07,0xFD,0x27,0xC8,0xC1,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x0C,0x38,0x97, +0x1A,0x0A,0x38,0xA0,0x1A,0x0A,0x38,0xB6,0x1A,0x0A,0xD5,0xB6,0x51,0xFF,0x84,0x60, +0xFC,0xE0,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB9,0x00,0x2E,0x07,0xFF,0xD8,0x5A,0x18, +0x07,0x03,0x92,0x01,0x3E,0x07,0xFD,0x24,0xB8,0x11,0xC0,0x05,0x2E,0x07,0xFD,0x20, +0x5A,0x08,0x01,0x37,0x2E,0x37,0xFD,0x24,0x2E,0x27,0xFF,0xDB,0xB8,0x17,0xFE,0x9C, +0xE2,0x02,0xE8,0x07,0xEA,0xF5,0x42,0x10,0x8C,0x0B,0xC1,0x2C,0x8C,0x01,0xD5,0x29, +0x84,0x01,0xEB,0x3C,0x84,0x00,0xEB,0x0C,0x84,0x00,0xB8,0x8E,0x84,0x01,0xB8,0x9C, +0x84,0x08,0x5A,0x10,0x07,0x09,0x5A,0x18,0x02,0x0A,0x2E,0x07,0xFF,0xA7,0x5A,0x08, +0x03,0x06,0x84,0x06,0x2E,0x17,0xFD,0x31,0xEA,0x34,0x84,0x00,0xEB,0x25,0x2E,0x07, +0xFD,0x31,0xC0,0x03,0x84,0x00,0xEB,0x2E,0xB8,0x00,0x5A,0x00,0x06,0x04,0x5A,0x08, +0x08,0x0A,0x46,0x01,0x00,0x01,0x58,0x00,0x04,0x74,0xB8,0x9A,0xD5,0x03,0x84,0x00, +0xB8,0x97,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0xB9,0x11,0xB8,0x00,0xC9,0x0F, +0x5A,0x08,0x08,0x08,0x46,0x11,0x00,0x05,0x02,0x10,0x82,0xD4,0xC9,0x08,0xD5,0x03, +0x5A,0x00,0x06,0xFA,0x2E,0x17,0xFD,0x20,0x5A,0x18,0x01,0x32,0x84,0x20,0x3E,0x17, +0xFD,0x3D,0x84,0x20,0xB9,0x97,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x20,0xB9,0x8E, +0x5A,0x08,0x08,0x04,0x84,0x07,0xD5,0x04,0x5A,0x08,0x06,0x06,0x84,0x02,0x2E,0x17, +0xFD,0x20,0xEA,0x34,0x84,0x00,0xEB,0x25,0xB8,0x00,0x5A,0x08,0x07,0x05,0xEB,0x64, +0xEB,0x47,0xD5,0x05,0xEA,0x2B,0xC8,0x05,0xEB,0x64,0xEA,0xB6,0xB8,0x9A,0xD5,0x1E, +0x5A,0x08,0x01,0x1D,0xEB,0x64,0xDD,0x5D,0xD5,0xFA,0x8E,0x03,0xE6,0x03,0xE8,0x16, +0xEA,0x43,0xB4,0x01,0x58,0x00,0x04,0x00,0xB6,0x01,0xD5,0x10,0x2E,0x27,0xFF,0xDA, +0xFA,0x2E,0xFE,0x54,0x2E,0x27,0xFF,0xDB,0xB8,0x0E,0xFE,0x54,0xE2,0x01,0xE8,0x04, +0x8C,0x01,0xB8,0x8E,0xD5,0x03,0x84,0x01,0xEB,0x0C,0xFC,0x80,0xDD,0x4B,0x5A,0x08, +0x08,0x05,0x2E,0x27,0xFF,0xAE,0xD5,0x06,0x84,0x40,0x5A,0x08,0x06,0x04,0x2E,0x27, +0xFF,0xB9,0x84,0x20,0x80,0x01,0x46,0x31,0x00,0x01,0x58,0x31,0x82,0xC4,0x38,0xF1, +0x85,0x11,0xE0,0x4F,0xE8,0x06,0x5C,0xF0,0x00,0x95,0xE8,0x03,0x8C,0x01,0x96,0x01, +0x8C,0x21,0x5A,0x18,0xD8,0xF6,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD4,0xDD,0x9E, +0xFC,0x20,0xDD,0x4B,0x5A,0x08,0x08,0x09,0x2E,0x17,0xFF,0xAE,0x94,0x49,0x96,0x4B, +0x2E,0x57,0xFF,0xE5,0xD5,0x0C,0x5A,0x08,0x06,0x09,0x2E,0x17,0xFF,0xB9,0x94,0x49, +0x96,0x4B,0x2E,0x57,0xFF,0xE1,0xD5,0x03,0x84,0x20,0x80,0xA1,0x84,0x40,0x3C,0x6D, +0xFF,0x90,0x80,0x82,0x46,0x71,0x00,0x02,0x58,0x73,0x81,0x44,0x82,0x02,0x47,0x11, +0x00,0x01,0x59,0x18,0x82,0xC4,0x98,0x17,0x02,0x00,0x07,0x9A,0x38,0x33,0x08,0x01, +0x9A,0xC3,0x96,0xD9,0x96,0x1B,0x4E,0x05,0x00,0x07,0xE0,0xA0,0x84,0x00,0xE8,0x07, +0x9A,0x1D,0xD5,0x04,0x88,0x05,0x42,0x00,0x40,0x01,0x96,0x03,0x38,0x08,0x88,0x09, +0x88,0x01,0x4E,0x04,0x00,0x04,0x8C,0x81,0x97,0x21,0x8C,0x42,0x5A,0x29,0xB0,0xE5, +0x2E,0x00,0x00,0x15,0xE2,0x04,0xE8,0x0A,0x46,0x01,0x00,0x01,0x00,0x00,0x02,0xC0, +0xEB,0x78,0xEA,0x37,0xEA,0xEC,0x84,0x01,0xEA,0x76,0xFC,0xA0,0xEB,0x43,0xDD,0x9E, +0xEB,0x3B,0xC0,0x04,0x84,0x00,0x3C,0x0F,0xFF,0x92,0xDD,0x9E,0xFC,0x40,0x3F,0xCF, +0xFD,0xF4,0x80,0xE1,0x84,0x20,0x80,0xC0,0x46,0x41,0x00,0x01,0x58,0x42,0x09,0x48, +0x80,0xA1,0x44,0x30,0xFF,0xFF,0x50,0x00,0x80,0x08,0x88,0x04,0x84,0x40,0x8C,0x41, +0xB6,0xA0,0x14,0x30,0x7F,0xFE,0x14,0x30,0x7F,0xFF,0x8C,0x0C,0x5A,0x28,0x04,0xF9, +0x50,0x10,0x80,0x30,0x5A,0x1A,0x40,0xF1,0x84,0x00,0x46,0x21,0x00,0x01,0xEB,0x1B, +0x44,0x10,0xFF,0xFF,0x38,0x11,0x00,0x0A,0x98,0xC2,0x8C,0x08,0xA8,0x59,0x5A,0x08, +0x60,0xFB,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x3C,0x84,0x20,0xEA,0xED,0xDD,0x42, +0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x0C,0x84,0x20,0xEA,0xED,0xDD,0x42,0xC6,0x04, +0x2E,0x00,0x00,0x0B,0xD5,0x07,0xC7,0x04,0x2E,0x00,0x00,0x0D,0xD5,0x03,0x2E,0x00, +0x00,0x0F,0x8C,0x01,0xEA,0xF9,0x2E,0x07,0xFD,0x64,0x5A,0x08,0x01,0x04,0x84,0x02, +0xEA,0xF9,0xEA,0xCF,0x85,0x20,0xEB,0x15,0x3E,0x97,0xFD,0x57,0x3E,0x97,0xFD,0x65, +0x3E,0x97,0xFD,0x5E,0x84,0x40,0x3E,0x97,0xFD,0x27,0xBA,0x8A,0xBA,0x98,0xEB,0x4E, +0x12,0x20,0x02,0xD4,0xBA,0x94,0xBA,0x8D,0xBA,0x96,0x3E,0x27,0xFD,0x50,0xBA,0x92, +0x3E,0x97,0xFD,0x5B,0xBA,0x90,0xEA,0xDE,0x92,0x27,0x8C,0x21,0x96,0x48,0x3E,0x17, +0xFD,0x6B,0xEA,0xB8,0x92,0x07,0x8C,0x01,0x96,0x00,0x3E,0x07,0xFD,0x5C,0x2E,0x27, +0xFF,0xBE,0x2E,0x40,0x01,0x32,0x3E,0x27,0xFD,0x56,0x54,0x31,0x00,0x0F,0x42,0x51, +0x90,0x24,0x92,0x44,0x40,0x12,0x84,0x36,0x3C,0x1B,0xFE,0xC6,0x2E,0x10,0x01,0x33, +0xFF,0x14,0xFE,0xCC,0xFE,0x8C,0x40,0x01,0x80,0x16,0x3C,0x0B,0xFE,0xCE,0x3C,0x4B, +0xFE,0xC9,0x3C,0x2B,0xFE,0xC5,0x2E,0x07,0xFF,0xBD,0x54,0x10,0x00,0x0F,0x3E,0x17, +0xFD,0x4E,0x92,0x04,0x3E,0x07,0xFD,0x61,0x2E,0x07,0xFF,0xA5,0x92,0x04,0x3E,0x07, +0xFD,0x2B,0x84,0x02,0xB8,0x85,0x2E,0x07,0xFF,0xA8,0xDD,0x49,0x3C,0x0B,0xFE,0xC8, +0x2E,0x07,0xFF,0xB2,0xDD,0x49,0x3C,0x0B,0xFE,0xCC,0x2E,0x07,0xFF,0xB3,0xDD,0x49, +0x3C,0x0B,0xFE,0xCD,0x3E,0x97,0xFD,0x41,0x3E,0x97,0xFD,0x66,0x3E,0x97,0xFD,0x42, +0x2E,0x07,0xFF,0xC6,0xEA,0x98,0x2E,0x07,0xFF,0xC7,0xEA,0xAD,0x2E,0x07,0xFF,0xC9, +0x40,0x10,0x10,0x09,0x3E,0x17,0xFD,0x52,0x96,0x1F,0x84,0x2A,0xFE,0x0C,0x3E,0x07, +0xFD,0x3A,0x2E,0x07,0xFF,0xD3,0x3C,0x0B,0xFE,0xD1,0xC7,0x0B,0x2E,0x07,0xFF,0xCE, +0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x38,0x92,0x04,0x3E,0x07,0xFD,0x2C,0xD5,0x13, +0x2E,0x07,0xFF,0xCC,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x38,0x92,0x04,0x3E,0x07, +0xFD,0x2C,0x2E,0x07,0xFF,0xCD,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x21,0x92,0x04, +0x3E,0x07,0xFD,0x39,0x49,0xFF,0xEF,0x2F,0x46,0x01,0x00,0x01,0x58,0x00,0x0B,0x94, +0x84,0x3F,0x84,0x4C,0xDD,0x42,0x84,0x00,0x3E,0x07,0xFD,0x4D,0x2E,0x17,0xFF,0xDE, +0x84,0x00,0x40,0x00,0x04,0x06,0x3E,0x07,0xFD,0x3B,0x2E,0x27,0xFF,0xD6,0x3E,0x27, +0xFD,0x28,0x2E,0x37,0xFF,0xD7,0xFA,0x24,0x42,0x21,0x84,0x73,0x96,0x90,0x3E,0x27, +0xFD,0x47,0xC0,0x02,0x84,0x44,0x3E,0x27,0xFD,0x2F,0x2E,0x07,0xFF,0xD8,0x84,0x40, +0x3E,0x07,0xFD,0x24,0x3E,0x27,0xFD,0x46,0x3E,0x27,0xFD,0x68,0x3E,0x27,0xFD,0x55, +0x3E,0x27,0xFD,0x1E,0x3E,0x27,0xFD,0x3E,0x3E,0x27,0xFD,0x25,0x84,0x00,0x3C,0x0B, +0xFE,0xCB,0x3E,0x07,0xFD,0x4F,0x2E,0x07,0xFF,0xC8,0x3E,0x07,0xFD,0x49,0x2E,0x00, +0x01,0x00,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x54,0x92,0x04,0x3E,0x07,0xFD,0x6A, +0x2E,0x00,0x01,0x01,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x5A,0x92,0x04,0x3E,0x07, +0xFD,0x1D,0x3E,0x27,0xFD,0x6E,0xCE,0x03,0x3E,0x27,0xFD,0x79,0x3E,0x27,0xFD,0x72, +0x3E,0x27,0xFD,0x77,0x3E,0x27,0xFD,0x6F,0x3E,0x27,0xFD,0x71,0x3E,0x27,0xFD,0x73, +0x3E,0x27,0xFD,0x76,0x84,0x00,0xB8,0x9F,0xB8,0x9E,0x2E,0x4F,0xFF,0xA3,0x4E,0x45, +0x00,0x03,0x84,0x02,0x84,0x40,0x3E,0x07,0xFD,0x5F,0x86,0x00,0x3E,0x27,0xFD,0x74, +0x84,0xA0,0x3D,0x0B,0xFE,0xE6,0xBD,0x9D,0x2E,0x30,0x00,0x6A,0xEA,0x2A,0xFE,0xCC, +0x3C,0x3B,0xFE,0xE5,0x2E,0x30,0x00,0x6B,0xFE,0xCC,0x3C,0x3B,0xFE,0xE8,0x2E,0x30, +0x00,0x6C,0xFE,0xCC,0x3C,0x3B,0xFE,0xE2,0x2E,0x30,0x00,0x6D,0xFE,0x5C,0x3C,0x1B, +0xFE,0xE7,0x2E,0x10,0x00,0x6E,0x3C,0x1B,0xFE,0xE3,0x2E,0x10,0x00,0x6F,0x3E,0x17, +0xFD,0x75,0x2E,0x10,0x00,0x71,0x3E,0x17,0xFD,0x78,0x3F,0x07,0xFD,0x70,0x3E,0x27, +0xFD,0x22,0xBD,0x89,0x3E,0x27,0xFD,0x69,0x3E,0x27,0xFD,0x6C,0x3E,0x27,0xFD,0x29, +0x2E,0x10,0x00,0x62,0x40,0x30,0x90,0x09,0x3E,0x37,0xFD,0x32,0x96,0x5F,0x3E,0x17, +0xFD,0x53,0xCE,0x10,0x3E,0x27,0xFD,0x3D,0xEB,0x78,0x10,0x20,0x82,0xC0,0xEB,0x78, +0x10,0x20,0x82,0xC1,0x84,0x21,0x3E,0x17,0xFD,0x30,0x3E,0x27,0xFD,0x59,0xBE,0x80, +0xBE,0x86,0xC7,0x04,0xEB,0x64,0xEB,0x47,0xD5,0x12,0x4E,0x44,0x00,0x0C,0xC8,0x08, +0xEA,0x2B,0xE6,0x01,0x3E,0xF7,0xFD,0x79,0x84,0x01,0x3E,0x07,0xFD,0x5F,0xEA,0x2B, +0xC8,0x04,0xEB,0x64,0xEA,0xB6,0xD5,0x03,0xEB,0x64,0xDD,0x5D,0xB8,0x93,0x84,0xE0, +0x44,0x20,0x05,0x10,0x3E,0x77,0xFD,0x40,0x84,0x20,0xEB,0x4E,0xEA,0x62,0xDD,0x42, +0x3E,0x77,0xFD,0x3D,0x84,0x01,0xEB,0x2E,0x84,0xC0,0x3E,0x77,0xFD,0x20,0xBE,0x87, +0x49,0xFF,0xDC,0x28,0xEB,0x4E,0x12,0x60,0x02,0xD6,0x3C,0x6B,0xFE,0xC7,0x3E,0x67, +0xFD,0x5D,0x3C,0x6B,0xFE,0xC3,0x46,0x01,0x00,0x05,0x10,0x60,0x06,0xD6,0x46,0x01, +0x00,0x05,0x12,0x60,0x03,0x6A,0x46,0x01,0x00,0x05,0x10,0x60,0x06,0x42,0x46,0x01, +0x00,0x05,0x12,0x60,0x03,0x20,0x46,0x31,0x00,0x05,0x58,0x31,0x86,0x44,0xEA,0x29, +0x46,0x21,0x00,0x05,0x58,0x21,0x05,0xB0,0x98,0x73,0x38,0x01,0x98,0x0A,0x38,0x01, +0x18,0x0A,0xA8,0x09,0x10,0x70,0x80,0x08,0x98,0x72,0x8C,0xCC,0xA8,0x09,0x10,0x70, +0x80,0x08,0x5A,0x68,0x90,0xF3,0xFC,0xC0,0x2E,0x27,0xFD,0x64,0x5A,0x18,0x02,0x05, +0x3E,0x27,0xFD,0x45,0xD5,0x0E,0x8E,0x07,0xE6,0x02,0xE8,0x05,0x2E,0x00,0x00,0x0C, +0xEA,0xDA,0xD5,0x05,0x2E,0x10,0x00,0x0E,0x40,0x01,0x04,0x40,0x3E,0x07,0xFD,0x45, +0x84,0x00,0x3E,0x07,0xFD,0x2E,0xEA,0xAA,0xEA,0xC3,0xDD,0x9E,0xFC,0x0B,0x3F,0xCF, +0xFD,0xD8,0x2E,0x07,0xFD,0x4B,0xC8,0x12,0xB8,0x0C,0x5A,0x00,0x02,0x09,0x2E,0x07, +0xFF,0xD0,0xDD,0x49,0xEA,0x3D,0x2E,0x07,0xFF,0xD1,0xD5,0x0E,0x2E,0x07,0xFF,0xD4, +0xDD,0x49,0xEA,0x3D,0x2E,0x07,0xFF,0xD5,0xD5,0x07,0xEA,0x9D,0x96,0x1F,0xDD,0x49, +0xEA,0x3D,0xEA,0x9D,0x92,0x04,0xDD,0x49,0xEA,0x65,0xEA,0x45,0xC0,0x09,0x2E,0x00, +0x00,0x63,0xDD,0x49,0xEA,0x3D,0x2E,0x00,0x00,0x63,0xDD,0x49,0xEA,0x65,0xEA,0x49, +0xC0,0x07,0xEA,0xE3,0x94,0x01,0xEA,0x3D,0xEA,0xC9,0x94,0x01,0xEA,0x65,0xDD,0x59, +0x5A,0x08,0x01,0x04,0x49,0x00,0x03,0x31,0xEB,0x11,0xEB,0x2A,0xDD,0x4D,0x42,0x00, +0x18,0x0B,0xC0,0x06,0xDD,0x59,0x5A,0x08,0x01,0x04,0x49,0x00,0x04,0x64,0xB8,0x1B, +0xB9,0x11,0xE2,0x01,0xE8,0x0C,0xC0,0x0B,0xEA,0x45,0xC0,0x09,0xEA,0xE3,0x94,0x01, +0xEA,0x3D,0xEA,0xC9,0x94,0x01,0xEA,0x65,0xEB,0x11,0xEB,0x2A,0x84,0x00,0x3E,0x07, +0xFD,0x58,0xDD,0x4D,0x42,0x00,0x18,0x0B,0xBA,0x11,0xC0,0x33,0xB8,0x14,0x5A,0x08, +0x01,0x31,0xE6,0x42,0xE9,0x2E,0x46,0x01,0x00,0x01,0x00,0x10,0x0F,0xDC,0x46,0x01, +0x00,0x01,0x00,0x00,0x0F,0xDE,0xE2,0x01,0xE8,0x03,0x9A,0x08,0xD5,0x02,0x8A,0x01, +0x2E,0x37,0xFF,0xFA,0xE0,0x03,0xE8,0x1D,0x46,0x01,0x00,0x01,0x00,0x10,0x0F,0xDD, +0x46,0x01,0x00,0x01,0x00,0x00,0x0F,0xDF,0xE2,0x01,0xE8,0x03,0x9A,0x08,0xD5,0x02, +0x8A,0x01,0xE0,0x03,0xE8,0x0E,0xEB,0x64,0x04,0x00,0x00,0x2F,0x46,0x11,0x00,0x02, +0x04,0x10,0x80,0x32,0x92,0x01,0xE2,0x20,0xE8,0x04,0x84,0x01,0x3E,0x07,0xFD,0x58, +0xB8,0x1B,0xE2,0x40,0xE8,0x12,0x2E,0x07,0xFD,0x4B,0xC0,0x0F,0xEA,0x45,0xC8,0x0D, +0xEA,0xE6,0xC8,0x0B,0xEA,0x9D,0x96,0x1F,0xDD,0x49,0xEA,0x3D,0xEA,0x9D,0x92,0x04, +0xDD,0x49,0xEA,0x65,0xEB,0x11,0xEB,0x2A,0xB8,0x11,0xC0,0x1E,0x46,0x11,0x00,0x01, +0x00,0x10,0x8F,0xDC,0x46,0x01,0x00,0x01,0x8E,0x21,0x00,0x00,0x0F,0xDD,0xFA,0x54, +0x42,0x00,0x88,0x73,0x46,0x11,0x00,0x02,0xEB,0x17,0x40,0x00,0x80,0x20,0x22,0xF0, +0x0C,0xA9,0x2E,0x07,0xFF,0xAA,0x94,0x01,0xE0,0x0F,0xE8,0x06,0x84,0x00,0xEB,0x15, +0xEA,0xFD,0xC1,0x11,0xD5,0x0E,0x3C,0x03,0xFE,0xC4,0x5C,0xF0,0x03,0xE8,0xE8,0x0B, +0x8C,0x01,0xEB,0x15,0x3C,0x03,0xFE,0xC0,0x5C,0xF0,0x00,0xC8,0xE8,0x04,0x8C,0x01, +0x3C,0x0B,0xFE,0xC0,0x46,0x01,0x00,0x07,0xEA,0x63,0xEA,0x21,0xEA,0x20,0xD8,0x17, +0x49,0xFF,0xE3,0x62,0x49,0xFF,0xE1,0xDD,0x49,0xFF,0xF9,0x12,0x49,0xFF,0xE7,0xEF, +0x49,0xFF,0xE4,0xA5,0x49,0xFF,0xE5,0x57,0xDD,0x59,0x5A,0x08,0x01,0x10,0x46,0x01, +0x00,0x01,0x58,0x00,0x09,0x48,0x49,0xFF,0xDE,0xD7,0xD5,0x08,0xDD,0x4D,0xEA,0xF0, +0xC8,0xE8,0xDD,0x59,0x5A,0x08,0x01,0x30,0xD5,0xE4,0x46,0x01,0x00,0x05,0xEA,0x54, +0x49,0xFF,0xE6,0x3E,0x46,0x01,0x00,0x05,0xEA,0x54,0x49,0xFF,0xE1,0x15,0xB8,0x00, +0x5A,0x08,0x07,0x1F,0xB1,0x82,0x80,0x26,0x46,0x21,0x00,0x01,0xEB,0x36,0x46,0x01, +0x00,0x05,0xEA,0x54,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x68,0x49,0xFF,0xEB,0xC8, +0xF0,0x81,0xF2,0x01,0x3A,0x03,0x04,0x00,0x49,0xFF,0xF3,0xC1,0x5A,0x00,0xFF,0x09, +0x3E,0x07,0xFE,0x24,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xDB,0x84,0x00, +0x3E,0x07,0xFD,0x27,0x46,0x01,0x00,0x05,0xEA,0x54,0xFC,0x8B,0x46,0x01,0x00,0x05, +0x58,0x00,0x05,0xB0,0xDD,0x9E,0x46,0x11,0x00,0x05,0x58,0x10,0x85,0xB0,0x46,0x01, +0x00,0x05,0xEA,0x54,0x3B,0x00,0x64,0x04,0xF8,0x01,0x3B,0x00,0xE4,0x24,0x3B,0x00, +0x64,0x04,0x83,0xFF,0x3B,0x00,0xE4,0x24,0x3B,0x00,0x58,0x00,0x3B,0x00,0xD8,0x20, +0xDD,0x9E,0x3C,0x0F,0xFF,0x8A,0xDD,0x9E,0x3C,0x13,0xFE,0xE4,0x3C,0x53,0xFE,0xE3, +0xD9,0x07,0x84,0x00,0x3E,0x07,0xFD,0x6E,0x84,0x00,0xEA,0xCD,0xDD,0x9E,0xC8,0x06, +0xEA,0x49,0xC0,0x04,0x8C,0x21,0x3C,0x1B,0xFE,0xE4,0xDD,0x9E,0xFC,0x00,0x84,0x01, +0x3E,0x07,0xFD,0x72,0x3E,0x07,0xFD,0x74,0x84,0x00,0x3C,0x0B,0xFE,0xE6,0x84,0x21, +0x3C,0x1F,0xFF,0x9A,0xEA,0xCD,0xFC,0x80,0xFC,0x00,0x3C,0x1D,0xFF,0x9A,0x5A,0x18, +0x01,0x1F,0x2E,0x17,0xFD,0x72,0x5A,0x18,0x01,0x14,0x84,0x40,0x3E,0x27,0xFD,0x72, +0x2E,0x37,0xFD,0x79,0xCB,0x04,0x3E,0x17,0xFD,0x79,0xD5,0x06,0x5A,0x38,0x01,0x09, +0x3E,0x27,0xFD,0x79,0x84,0x20,0x49,0x00,0x06,0xA9,0x49,0x00,0x0A,0xEF,0x2E,0x07, +0xFD,0x73,0x8C,0x01,0x3E,0x07,0xFD,0x73,0x84,0x02,0xD5,0x07,0x84,0x03,0x5A,0x10, +0x02,0x05,0x5A,0x18,0x03,0x05,0x84,0x00,0x3C,0x0F,0xFF,0x9A,0xFC,0x80,0xFC,0x00, +0x3C,0x1F,0xFF,0x90,0x84,0x20,0x3C,0x1F,0xFF,0x8F,0xDD,0x4F,0x46,0x01,0x00,0x05, +0xEA,0x62,0xDD,0x42,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFE,0x18,0xEB,0x23,0xC9,0x04, +0x3C,0x63,0xFE,0xE5,0xD5,0x07,0x5A,0x18,0x01,0x05,0x3C,0x63,0xFE,0xE8,0xD5,0x02, +0xEA,0xB5,0x84,0x40,0x80,0x02,0x46,0x41,0x00,0x05,0x58,0x42,0x06,0xD8,0x38,0x32, +0x09,0x01,0x8C,0x41,0x88,0x03,0x5A,0x28,0xD8,0xFC,0x44,0x20,0x7F,0xFF,0x92,0x04, +0xE2,0x40,0x40,0x01,0x3C,0x1B,0x2E,0x27,0xFD,0x77,0xCA,0x03,0xB8,0x96,0xD5,0x02, +0xB8,0x95,0x2E,0x07,0xFD,0x76,0xE6,0x0A,0xE8,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x76, +0x2E,0x07,0xFD,0x76,0xE6,0x02,0x4E,0xF3,0x00,0x7C,0xC9,0x43,0x3C,0x23,0xFE,0xE2, +0xB8,0x16,0xE2,0x40,0xE8,0x07,0x84,0x01,0x3E,0x07,0xFD,0x6E,0x3C,0x1B,0xFE,0xE4, +0xD5,0x04,0xB8,0x01,0x49,0xFF,0xFF,0x6A,0xB8,0x15,0x88,0xC0,0xB8,0x16,0xE2,0xC0, +0xE8,0x03,0xEA,0x49,0xC8,0x05,0xB8,0x00,0xEB,0x12,0x5A,0x08,0x01,0x12,0x2E,0x0F, +0xFF,0xA3,0x4E,0x04,0x00,0x0E,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x48,0xEA,0x3F, +0xD0,0x07,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x21,0xEA,0x20,0xD8,0x08,0x46,0x01, +0x00,0x07,0xEA,0x27,0xEA,0x21,0xEA,0x20,0x4C,0x50,0x40,0x4B,0xEB,0x0A,0x46,0x01, +0x00,0x02,0xEA,0xB6,0x50,0x10,0x05,0x10,0x49,0xFF,0xFF,0x8B,0xB8,0x00,0x5A,0x08, +0x01,0x04,0x84,0x02,0xD5,0x04,0x5A,0x08,0x03,0x3C,0x84,0x00,0xB8,0x80,0xD5,0x38, +0x5A,0x18,0x01,0x37,0x3C,0x23,0xFE,0xE7,0xB8,0x15,0xE2,0x40,0xE8,0x06,0x3E,0x17, +0xFD,0x6E,0x84,0x00,0xEA,0xCD,0xD5,0x04,0xB8,0x01,0x49,0xFF,0xFF,0x27,0xB8,0x16, +0x88,0xC0,0xB8,0x15,0xE2,0xC0,0xE8,0x03,0xEA,0x49,0xC8,0x05,0xB8,0x00,0xEB,0x12, +0x5A,0x08,0x01,0x12,0x2E,0x0F,0xFF,0xA3,0x4E,0x04,0x00,0x0E,0x46,0x01,0x00,0x07, +0xEA,0x27,0xEA,0x48,0xEA,0x3F,0xD0,0x07,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x21, +0xEA,0x20,0xD8,0x07,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x48,0xEA,0x3F,0xD8,0x08, +0xEB,0x0A,0x46,0x01,0x00,0x02,0xDD,0x5D,0x50,0x10,0x7A,0xF0,0xD5,0xBE,0xB8,0x04, +0xC8,0x2F,0xEA,0x2B,0x5A,0x08,0x01,0x2D,0x2E,0x17,0xFD,0x3D,0xC9,0x29,0x3C,0x03, +0xFE,0xE2,0xBA,0x16,0xE2,0x40,0xE8,0x24,0x3C,0x03,0xFE,0xE7,0xBA,0x15,0xE2,0x40, +0xE8,0x1F,0x46,0x01,0x00,0x07,0xEA,0x27,0xEA,0x21,0xEA,0x20,0xD0,0x19,0x46,0x01, +0x00,0x07,0xEA,0x27,0xEA,0x48,0xEA,0x3F,0xD0,0x13,0x2E,0x07,0xFD,0x70,0x5C,0xF0, +0x00,0xC8,0xE8,0x03,0x8C,0x01,0xD5,0x0D,0x3E,0x17,0xFD,0x70,0xEB,0x0A,0x46,0x01, +0x00,0x02,0xDD,0x5D,0x50,0x10,0x7A,0xF0,0x49,0xFF,0xFF,0x1B,0xD5,0x04,0x84,0x00, +0x3E,0x07,0xFD,0x70,0xB9,0x01,0x2E,0x07,0xFD,0x74,0xC0,0x0F,0xC9,0x0E,0x3C,0x03, +0xFE,0xE6,0x2E,0x27,0xFD,0x75,0xE2,0x40,0xE8,0x06,0x3E,0x17,0xFD,0x74,0x3C,0x1B, +0xFE,0xE6,0xD5,0x06,0x8C,0x01,0xD5,0x02,0x84,0x00,0x3C,0x0B,0xFE,0xE6,0xFC,0x80, +0xFC,0x00,0x3F,0xCF,0xFE,0x1C,0x3C,0x13,0xFE,0xE2,0xB8,0x15,0xE2,0x20,0xE9,0x06, +0x3C,0x13,0xFE,0xE7,0xB8,0x14,0xE2,0x20,0xE8,0x05,0x2E,0x07,0xFD,0x5D,0xC8,0x02, +0xEA,0x76,0x2E,0x07,0xFD,0x4C,0xC0,0x2D,0x84,0x00,0xEA,0x76,0x2E,0x17,0xFD,0x28, +0xB8,0x0C,0xE2,0x20,0xEA,0xF5,0xE8,0x22,0x42,0x20,0x84,0x0B,0xC2,0x1F,0xBA,0x00, +0xC2,0x04,0x2E,0x27,0xFD,0x5D,0xC2,0x1A,0xDD,0x59,0x5C,0x10,0x00,0x01,0x84,0x01, +0xEA,0xAB,0xDD,0x59,0x5A,0x00,0x01,0x04,0x84,0x07,0xD5,0x02,0x84,0x02,0x84,0x22, +0xEA,0x34,0xDD,0x59,0x80,0xC0,0x5A,0x08,0x01,0x0E,0xEA,0x33,0xC8,0x04,0xEA,0xB7, +0xEA,0xC4,0xD5,0x08,0x3E,0x67,0xFD,0x1A,0xD5,0x05,0xEA,0x5B,0xC1,0x03,0x8C,0x01, +0xB8,0x8C,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0x46,0x01,0x00,0x07,0x04,0x50, +0x03,0xCE,0xEA,0x21,0xEA,0x20,0xD8,0x03,0x84,0x03,0xD5,0x1E,0x46,0x01,0x00,0x05, +0xEB,0x1C,0x3C,0x13,0xFE,0xC8,0xE2,0x20,0x84,0x20,0xBA,0x0C,0xE8,0x0B,0xB9,0x8D, +0xB8,0x07,0xE6,0x03,0xE8,0x04,0x8C,0x01,0xB8,0x87,0xD5,0x0F,0xC2,0x0E,0xB9,0x8C, +0xD5,0x0C,0xB9,0x87,0xB8,0x0D,0xE6,0x0F,0xE8,0x04,0x8C,0x01,0xB8,0x8D,0xD5,0x05, +0x5A,0x20,0x02,0x04,0x84,0x02,0xB8,0x8C,0xB8,0x0C,0xC8,0x0A,0x2E,0x07,0xFF,0xA9, +0xEA,0x4B,0x3C,0x03,0xFE,0xCC,0xEA,0xB4,0x2E,0x07,0xFD,0x38,0xD5,0x22,0x5A,0x08, +0x02,0x17,0x2E,0x07,0xFF,0xAA,0xEA,0x4B,0x3C,0x03,0xFE,0xCD,0xEA,0xB4,0x2E,0x07, +0xFD,0x38,0xEA,0x97,0x2E,0x07,0xFD,0x39,0xEA,0x90,0x2E,0x07,0xFF,0xC6,0xEA,0x98, +0x2E,0x07,0xFF,0xC7,0xEA,0xAD,0x2E,0x00,0x00,0xE6,0xD5,0x16,0x5A,0x08,0x03,0x18, +0x2E,0x07,0xFF,0xAB,0xEA,0x4B,0x3C,0x03,0xFE,0xCC,0xEA,0xB4,0x2E,0x07,0xFD,0x2C, +0xEA,0x97,0xEB,0x02,0xEA,0x90,0x2E,0x07,0xFF,0xC4,0xEA,0x98,0x2E,0x07,0xFF,0xC5, +0xEA,0xAD,0x2E,0x00,0x00,0xE5,0xDD,0x49,0x3C,0x0B,0xFE,0xCF,0xEB,0x08,0xC0,0x1C, +0xEB,0x38,0xC8,0x1A,0x2E,0x00,0x00,0x52,0xEA,0x4B,0x2E,0x00,0x00,0x54,0xEA,0xB4, +0x2E,0x00,0x00,0x57,0x40,0x10,0x10,0x09,0x3E,0x17,0xFD,0x23,0xB9,0x1B,0x5A,0x18, +0x01,0x04,0x96,0x1F,0xD5,0x02,0xEB,0x02,0xEA,0x90,0x2E,0x07,0xFF,0xC4,0xEA,0x98, +0x2E,0x00,0x00,0x56,0xEA,0xAD,0xB8,0x00,0x5A,0x08,0x07,0x05,0x2E,0x07,0xFF,0xAD, +0xEA,0x4B,0xEB,0x43,0xC0,0x04,0x2E,0x07,0xFF,0xB9,0xEA,0x4B,0xEA,0x49,0xC0,0x07, +0x2E,0x07,0xFD,0x2C,0xEA,0x97,0xEB,0x02,0x8C,0x02,0xEA,0x90,0xB8,0x1C,0xC0,0x03, +0x84,0x00,0xEA,0x97,0xFC,0x80,0xFC,0x40,0x2E,0x50,0x00,0x58,0x40,0x62,0x90,0x09, +0x4E,0x62,0x01,0x38,0x46,0x01,0x00,0x07,0x04,0x10,0x03,0xC5,0xEA,0x21,0xEA,0x20, +0x4C,0x10,0x00,0x06,0xDD,0x4D,0xEB,0x18,0x4E,0x02,0x01,0x2C,0xEA,0x94,0x3C,0x0D, +0xFF,0x8A,0x4E,0x13,0x01,0x0E,0xE6,0x02,0x4E,0xF2,0x01,0x0B,0x2E,0x37,0xFD,0x65, +0x4E,0x33,0x01,0x07,0x2E,0x20,0x00,0x5C,0x2E,0x70,0x01,0x29,0x54,0x01,0x00,0x0F, +0x8C,0xE1,0x9C,0x41,0x8A,0xE0,0xEA,0x3C,0x92,0x44,0x51,0x00,0x00,0x01,0x51,0x21, +0x00,0x01,0x8B,0x82,0x80,0x03,0x80,0x43,0xFB,0xF6,0x46,0x91,0x00,0x04,0x58,0x94, +0x84,0xB8,0xE0,0x27,0xE8,0x19,0x42,0xA0,0xCC,0x24,0x80,0x92,0xE0,0x90,0xE8,0x11, +0x41,0x12,0x28,0x00,0x41,0x14,0xC4,0x20,0x02,0xF8,0x80,0x00,0xEA,0x7E,0xE0,0x0F, +0xE8,0x05,0x02,0x08,0x80,0x00,0x80,0x61,0x80,0x44,0x8C,0x81,0x97,0x20,0xD5,0xEF, +0x8C,0x21,0x96,0x48,0xD5,0xE7,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBB,0x2E,0x40, +0x00,0x83,0x2E,0x10,0x00,0x84,0xE2,0x04,0x40,0x10,0x80,0x06,0x41,0x07,0x84,0x02, +0x3F,0x07,0xFD,0x55,0x2E,0x10,0x00,0x5A,0xE2,0x20,0xE8,0x0D,0x2E,0x10,0x00,0x59, +0xE2,0x01,0xE8,0x09,0x3C,0x43,0xFE,0xC4,0x2E,0x70,0x00,0x5B,0x84,0x2A,0xFE,0x7C, +0xE0,0x24,0xE9,0x03,0x4F,0x02,0x00,0xB0,0xFA,0x96,0xFF,0x1C,0x47,0x11,0x00,0x04, +0x59,0x18,0x84,0xB8,0x99,0xE2,0x95,0xF9,0x8E,0xE2,0x40,0x13,0xC4,0x00,0xA4,0x48, +0x8C,0xE4,0x88,0xF1,0x41,0x20,0x80,0x11,0xA4,0x78,0x50,0x72,0x7F,0xDA,0x96,0x4B, +0x88,0xE2,0x95,0xF9,0x88,0x32,0x88,0x01,0x40,0x13,0xC4,0x00,0xA4,0x48,0x88,0x01, +0x50,0x12,0x00,0x26,0x88,0x22,0x94,0x49,0x40,0x40,0xC4,0x00,0xA5,0x20,0x88,0x04, +0x9F,0x3A,0x88,0x91,0xA5,0x20,0x8C,0xE2,0x88,0xF1,0x88,0x04,0xA5,0x38,0x88,0x04, +0x9F,0x0A,0x88,0x91,0x8C,0x22,0xA5,0x20,0x88,0x31,0xA4,0x48,0x88,0x04,0x88,0x01, +0x96,0x01,0x92,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBC,0x2E,0x10,0x00,0x5D, +0xE2,0x20,0xE8,0x03,0x4F,0x02,0x00,0x0E,0x2E,0x10,0x00,0x86,0xE2,0x20,0x4E,0xF2, +0x00,0x84,0x2E,0x10,0x00,0x85,0xE2,0x01,0x4E,0xF2,0x00,0x7F,0x4F,0x02,0x00,0x7D, +0xEA,0x92,0x5A,0x08,0xFF,0x04,0x48,0x00,0x00,0x7D,0xC8,0x08,0x3E,0x27,0xFD,0x3E, +0x3E,0x37,0xFD,0x25,0x3E,0x07,0xFD,0x33,0xD5,0x4F,0x2E,0x07,0xFD,0x3E,0xE2,0x40, +0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40,0x2E,0x07,0xFD,0x25,0x96,0x90,0xE2,0x60, +0xE8,0x03,0x9A,0xC3,0xD5,0x02,0x8A,0x60,0xDD,0x5C,0x96,0xD8,0x80,0x82,0x42,0x41, +0x80,0x73,0x97,0x5F,0x80,0x04,0x46,0x41,0x00,0x07,0x12,0x02,0x07,0xBD,0x9C,0x69, +0x2E,0x00,0x00,0x5E,0x5A,0x68,0x01,0x0F,0x96,0x1F,0xE0,0x02,0xE9,0x03,0xE0,0x03, +0xE8,0x03,0x84,0x1F,0xEA,0x8F,0x2E,0x57,0xFD,0x1E,0xD9,0x26,0x84,0x01,0xEA,0xFC, +0xD5,0x23,0x92,0x04,0xE2,0x02,0xE9,0x03,0xE2,0x03,0xE8,0x04,0x84,0x1F,0xEA,0x8F, +0xD5,0x1B,0x98,0x1A,0x2E,0x47,0xFD,0x33,0x96,0x00,0xE2,0x04,0xE8,0x07,0x8A,0x80, +0xE4,0x83,0xE9,0x04,0x84,0x1F,0xEA,0x8F,0xD5,0x03,0x3E,0x07,0xFD,0x33,0xFE,0x94, +0x42,0x21,0x8C,0x73,0xFE,0x4C,0x96,0x90,0xE0,0x22,0xE8,0x06,0xEA,0x92,0x90,0xA1, +0xE0,0xA0,0xE9,0xDD,0xD5,0xE4,0xEA,0x92,0x5C,0xF0,0x00,0xF0,0xE8,0x1D,0x8C,0x01, +0xEA,0x8F,0xD5,0x1A,0x5A,0x60,0x03,0x19,0x3F,0x07,0xFD,0x1E,0xD5,0x15,0x84,0x20, +0x3E,0x17,0xFD,0x1E,0xC8,0x0E,0x2E,0x20,0x00,0x5F,0x3C,0x13,0xFE,0xCB,0x94,0x91, +0xE0,0x22,0xE8,0x05,0x8C,0x21,0x3C,0x1B,0xFE,0xCB,0xD5,0x06,0xEA,0xFC,0xD5,0x02, +0x84,0x00,0x3C,0x0B,0xFE,0xCB,0xEA,0x92,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBA, +0xFC,0xC0,0xFC,0x20,0x3F,0xCF,0xFE,0x1C,0x2E,0x50,0x01,0xCD,0x2E,0x40,0x01,0xCC, +0x84,0x22,0x9A,0xAC,0x8C,0x41,0x40,0x21,0x04,0x56,0x2F,0x00,0x01,0xCE,0x88,0x44, +0x2E,0x70,0x01,0xCF,0x96,0x10,0x46,0x21,0x00,0x01,0x00,0x21,0x0F,0xDD,0x46,0x61, +0x00,0x07,0x9A,0x82,0x42,0x31,0x00,0x03,0x40,0x28,0x1C,0x01,0x8C,0x41,0x40,0x11, +0x04,0x36,0x46,0x21,0x00,0x01,0x88,0x27,0x00,0x21,0x0F,0xDC,0x96,0x48,0x9A,0x8A, +0x42,0x21,0x00,0x03,0x88,0x43,0x96,0xD1,0x12,0x33,0x07,0xB5,0x2E,0x37,0xFD,0x29, +0xCB,0x21,0xB8,0x00,0xC0,0x57,0x46,0x01,0x00,0x01,0x00,0x10,0x0B,0xA0,0xC9,0x52, +0x2E,0x00,0x00,0x60,0xE0,0x02,0xE8,0x13,0x2E,0x07,0xFD,0x6C,0x8C,0x01,0x96,0x00, +0x3E,0x07,0xFD,0x6C,0x2E,0x07,0xFD,0x6C,0x2E,0x27,0xFD,0x32,0xE2,0x40,0xE8,0x42, +0x84,0x01,0x3E,0x07,0xFD,0x29,0x3E,0x17,0xFD,0x68,0xD5,0x3C,0x3E,0x17,0xFD,0x6C, +0xD5,0x39,0xBA,0x03,0xCA,0x07,0xBA,0x00,0xCA,0x05,0x3E,0x27,0xFD,0x6C,0x3E,0x27, +0xFD,0x29,0x2E,0x30,0x00,0x64,0x46,0x21,0x00,0x01,0x04,0x21,0x03,0xFD,0xE2,0x62, +0xE8,0x29,0xFA,0x76,0x80,0x40,0x42,0x23,0x8C,0x73,0xEB,0x19,0xEB,0x24,0x40,0x23, +0x08,0x20,0x22,0x21,0x14,0xB2,0x5A,0x20,0xFD,0x1E,0x42,0x08,0x0C,0x73,0x40,0x23, +0x00,0x20,0x22,0x01,0x14,0xB2,0x5A,0x00,0xFD,0x16,0xFE,0x5C,0x98,0x0C,0x40,0x03, +0x00,0x20,0x22,0x00,0x14,0xB2,0x5A,0x00,0xFD,0x0E,0x88,0xA1,0x40,0x53,0x14,0x20, +0x22,0x02,0x94,0xB2,0x5A,0x00,0xFD,0x07,0x84,0x00,0x3E,0x07,0xFD,0x6C,0x3E,0x07, +0xFD,0x29,0xFC,0xA0,0x46,0x19,0x00,0x00,0x04,0x00,0x80,0x30,0xEA,0x37,0x14,0x00, +0x80,0x30,0xDD,0x9E,0x46,0x19,0x00,0x28,0xA4,0xCA,0x84,0x41,0x40,0x21,0x00,0x0C, +0x40,0x21,0x88,0x12,0xAC,0x8A,0x50,0x10,0x80,0x74,0x40,0x10,0x80,0x40,0xA6,0x08, +0xDD,0x9E,0x46,0x09,0x00,0x88,0x84,0x21,0x10,0x10,0x00,0xA8,0x44,0x1F,0xFF,0xA5, +0x10,0x10,0x00,0xE0,0x46,0x02,0xB1,0x18,0x50,0x00,0x03,0x00,0x46,0x13,0x00,0xB9, +0xB6,0x01,0x46,0x06,0x65,0x5F,0x50,0x00,0x0F,0x00,0x46,0x13,0x00,0xEB,0xB6,0x01, +0xDD,0x9E,0xFC,0x40,0x80,0xE1,0x81,0x20,0x80,0xC2,0xDD,0x52,0x46,0x33,0x00,0x00, +0x88,0x67,0x4E,0x92,0x00,0x04,0xB6,0xC3,0xD5,0x03,0x97,0xB0,0xAF,0x98,0xDD,0x57, +0x04,0x00,0x00,0x3A,0x92,0x0C,0x96,0x0F,0x5A,0x08,0x03,0x06,0x84,0x20,0x46,0x03, +0x00,0xB9,0xB6,0x20,0x84,0x20,0xEA,0x5D,0x10,0x10,0x00,0xA8,0xFC,0xC0,0xFC,0x00, +0xF8,0x32,0x80,0x43,0xDD,0x4C,0xFC,0x80,0xFC,0x20,0x80,0xE0,0x80,0xC1,0xDD,0x52, +0x46,0x23,0x00,0x00,0xC7,0x13,0x98,0x32,0xA6,0x40,0x9C,0x11,0x88,0x06,0xA7,0x00, +0x9C,0x12,0x88,0x06,0x9C,0xD3,0xA6,0x00,0x98,0xB3,0xA6,0x90,0xEA,0xE8,0x40,0x00, +0x0B,0x04,0xFE,0x0F,0x40,0x00,0x11,0x04,0xD5,0x04,0x88,0x46,0xA6,0x10,0x96,0x00, +0xEA,0x3E,0x04,0x10,0x80,0x3A,0x92,0x2C,0x96,0x4F,0x5A,0x18,0x03,0x06,0x84,0x40, +0x46,0x13,0x00,0xB9,0xB6,0x41,0x84,0x40,0x46,0x19,0x00,0x88,0x10,0x20,0x80,0xA8, +0xFC,0xA0,0xFC,0x00,0x40,0x10,0xA8,0x08,0x40,0x10,0x81,0x80,0x88,0x22,0x84,0x00, +0x83,0xFF,0xEA,0x60,0x96,0x00,0xFC,0x80,0x46,0x38,0x00,0x00,0x84,0x40,0x50,0x31, +0x80,0x34,0xB4,0x03,0x46,0x18,0x00,0x00,0x96,0x04,0xC0,0x06,0x5A,0x20,0x64,0x2E, +0x8C,0x41,0x96,0x90,0xD5,0xF7,0x5A,0x20,0x64,0x29,0xA8,0x0C,0xA0,0x8C,0x50,0x40, +0x80,0x20,0x58,0x21,0x00,0x80,0xA8,0x8C,0xA0,0x8C,0x66,0x21,0x1F,0x00,0x58,0x21, +0x07,0x00,0xA8,0x8C,0xA0,0xCC,0x44,0x2C,0xFF,0xFF,0xFE,0x9E,0x42,0x21,0x44,0x08, +0xA8,0x8C,0xB6,0x04,0xB4,0x64,0x46,0x2F,0x0F,0xFF,0x50,0x21,0x0F,0xFF,0xFE,0x9E, +0x46,0x30,0x70,0x00,0xFE,0x9F,0xB6,0x44,0xB4,0x44,0x42,0x21,0x78,0x08,0xB6,0x44, +0x84,0x44,0x10,0x20,0x80,0x24,0xDD,0x9E,0xFA,0x11,0xDD,0x9E,0xFC,0x63,0xF0,0x81, +0xEB,0x5A,0xEB,0x30,0x44,0x00,0x04,0x00,0xF2,0x01,0xDD,0x48,0xEA,0x9B,0x81,0x60, +0x4E,0x03,0x00,0x9B,0x46,0xEF,0xF0,0x0F,0x81,0x80,0x50,0x07,0x0F,0xFF,0x84,0xC1, +0x85,0xA4,0xF0,0x84,0xEB,0x81,0x58,0x00,0x00,0x04,0x38,0x70,0x34,0x00,0x8C,0x01, +0x38,0xA6,0x80,0x00,0x4E,0x72,0x00,0x89,0x54,0x05,0x00,0xFB,0x85,0x00,0xF0,0x83, +0xE3,0x07,0x4E,0xF2,0x00,0x7B,0x40,0x04,0x34,0x00,0xEB,0x5A,0x58,0x10,0x80,0x00, +0x88,0x01,0x00,0x90,0x00,0x06,0x5A,0xA0,0xBD,0x6B,0x5A,0xA8,0xE9,0x0C,0x54,0x04, +0x80,0xC0,0x5A,0x08,0xC0,0x05,0x54,0xE4,0x80,0x3F,0xD5,0x0F,0x85,0xC1,0xC0,0x0D, +0xD5,0x0B,0x5A,0xA8,0xC1,0x08,0x2E,0x07,0xFD,0x1B,0x81,0xC6,0x5A,0x08,0x01,0x06, +0xD5,0x58,0x5A,0xA0,0xB6,0x0A,0x81,0xC6,0x88,0xC8,0x96,0x30,0xF0,0x81,0xEA,0xD3, +0x84,0xC3,0xF0,0x82,0xD5,0x07,0x2E,0x07,0xFD,0x04,0x5A,0x00,0xFF,0xF6,0x81,0xC6, +0xD5,0x48,0x80,0x0A,0x80,0x2C,0xF2,0x02,0x80,0x69,0xDD,0x54,0x5A,0xA0,0xB9,0x42, +0xF0,0x03,0x5A,0x00,0xB2,0x3F,0x5A,0xA0,0xE9,0x3D,0x80,0x0A,0x80,0x2C,0xF2,0x02, +0xEA,0x3A,0xF0,0x85,0x4C,0x90,0x00,0x36,0x44,0x00,0x00,0x32,0xDD,0x50,0x9E,0x31, +0x97,0x80,0xF3,0x05,0xCE,0xE7,0x46,0x01,0x00,0x07,0x04,0x20,0x03,0xF0,0xF1,0x04, +0x66,0x21,0x00,0xFF,0x40,0x25,0x08,0x04,0x14,0x20,0x03,0xF0,0x04,0x00,0x03,0xF0, +0x44,0x2F,0x00,0xFF,0xFE,0x86,0x40,0x21,0x31,0x04,0x46,0x01,0x00,0x07,0x14,0x20, +0x03,0xF0,0x04,0x00,0x03,0xF0,0x81,0x6A,0xFE,0x0E,0xF1,0x01,0x40,0x60,0x06,0x04, +0x46,0x01,0x00,0x07,0x14,0x60,0x03,0xF0,0x04,0x10,0x03,0xF0,0x40,0x10,0xA0,0x08, +0x92,0x28,0x40,0x10,0x8F,0x04,0x14,0x10,0x03,0xF0,0xD5,0x03,0x81,0xC6,0x81,0x89, +0x8D,0x01,0x80,0xCE,0x48,0xFF,0xFF,0x86,0x8C,0xE2,0x40,0xD6,0x9C,0x00,0x5C,0xF6, +0x84,0x00,0x4E,0xF3,0xFF,0x71,0x80,0x0B,0xFC,0xE3,0x46,0x09,0x00,0x08,0x02,0x50, +0x00,0x08,0xEA,0xE9,0xD1,0x03,0x12,0x10,0x00,0x08,0xDD,0x9E,0xFC,0x00,0xEA,0x93, +0x46,0x10,0x30,0x00,0xEA,0xB9,0x8C,0x21,0xEB,0x2B,0xB4,0x02,0x96,0x04,0xC0,0x04, +0x8E,0x21,0xC9,0xFC,0xFA,0x14,0xFC,0x80,0xFC,0x00,0xDD,0x52,0x84,0x00,0x44,0x11, +0x00,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,0xFC,0x00,0xDD,0x52,0x84,0x00, +0x44,0x11,0x10,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,0xFC,0x00,0xDD,0x52, +0x84,0x00,0x44,0x12,0x90,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80,0xFC,0x00, +0xDD,0x52,0x84,0x00,0x44,0x12,0x80,0x00,0x80,0x40,0xDD,0x4C,0xEA,0x4A,0xFC,0x80, +0x46,0x09,0x00,0x08,0xA5,0x46,0x44,0x10,0xAC,0x53,0xD1,0x04,0x44,0x1F,0xAC,0x53, +0xAC,0x46,0xDD,0x9E,0x46,0x09,0x00,0x08,0xA4,0x46,0xC1,0x03,0x84,0x20,0xAC,0x46, +0xDD,0x9E,0xFC,0x01,0xEA,0x38,0x00,0x1F,0x80,0x00,0x84,0x01,0x40,0x30,0x80,0x02, +0x00,0x1F,0x80,0x01,0x00,0x2F,0x80,0x04,0xFE,0x46,0x40,0x11,0x84,0x20,0x00,0x3F, +0x80,0x02,0xFE,0xC6,0x40,0x10,0x8C,0x60,0x00,0x3F,0x80,0x03,0xFE,0xC6,0x40,0x10, +0x8C,0x80,0xFE,0x16,0x40,0x00,0x80,0xA0,0xEB,0x3E,0xEB,0x3A,0xEA,0x5C,0xFC,0x81, +0x9E,0x41,0xE6,0x23,0xE8,0x1B,0xEA,0x28,0x84,0x40,0x10,0x20,0x80,0x94,0x84,0x41, +0x10,0x20,0x80,0x94,0xEA,0x3E,0x5A,0x00,0x02,0x08,0x5A,0x00,0x03,0x0A,0xEA,0xD0, +0x12,0x00,0x80,0x0A,0xD5,0x09,0x44,0x00,0x00,0xA5,0xAC,0x0E,0xD5,0x05,0x44,0x00, +0x00,0x55,0x12,0x00,0x80,0x0C,0x84,0x00,0xDD,0x9E,0xFA,0x02,0xDD,0x9E,0x46,0x20, +0x4C,0x4B,0x50,0x21,0x04,0x00,0xE2,0x41,0xE9,0x18,0xE6,0x04,0xE8,0x16,0xFC,0x01, +0xF0,0x81,0x80,0xC1,0x84,0x00,0xF1,0x01,0xEA,0x3B,0x3C,0x1D,0xFF,0xE3,0xFA,0x44, +0xFF,0x8C,0x84,0x00,0xF1,0x01,0x40,0x23,0x08,0x57,0xF8,0x2C,0x84,0x00,0xF1,0x01, +0x84,0x48,0xF8,0x2D,0x84,0x00,0xFC,0x81,0xFA,0x02,0xDD,0x9E,0xE6,0x04,0xE8,0x2B, +0xFC,0x40,0x80,0xE0,0x81,0x21,0x84,0x01,0x80,0x27,0xEA,0x3B,0x46,0x49,0x00,0x80, +0x8C,0x84,0x40,0x42,0x1C,0xA0,0x44,0x10,0x00,0x65,0x8E,0x21,0x96,0x48,0xB4,0x64, +0xB4,0x04,0xC1,0x1B,0x40,0x60,0x0C,0x04,0xCE,0xF9,0x40,0x24,0x88,0x09,0xDD,0x5C, +0x42,0x11,0x00,0x24,0x2E,0x27,0xFD,0xEA,0x84,0x01,0x40,0x20,0x88,0x57,0x80,0x27, +0x88,0x40,0x49,0x00,0x0A,0x6E,0x84,0x01,0x80,0x40,0x80,0x27,0x49,0x00,0x0A,0x74, +0x80,0x06,0xD5,0x04,0xFA,0x02,0xDD,0x9E,0xFA,0x14,0xFC,0xC0,0x46,0x18,0x00,0x60, +0x00,0x00,0x80,0x14,0xEB,0x03,0x10,0x00,0x80,0x14,0xDD,0x9E,0x46,0x08,0x00,0x60, +0x00,0x10,0x00,0x10,0x84,0x01,0x40,0x00,0x04,0x12,0xDD,0x9E,0xFC,0x01,0x10,0x0F, +0x80,0x07,0x00,0x0F,0x80,0x07,0x96,0x00,0xE6,0x06,0xE8,0x47,0x3E,0xFF,0xD5,0xF4, +0x38,0x07,0x80,0x00,0x40,0xF0,0x3C,0x00,0x4A,0x00,0x3C,0x00,0x22,0x06,0x0A,0x10, +0x16,0x1C,0xEB,0x0B,0xD5,0x0E,0x44,0x60,0x00,0x66,0xD5,0x0B,0x44,0x60,0x00,0x77, +0xD5,0x08,0x44,0x60,0x00,0x99,0xD5,0x05,0x44,0x60,0x00,0xAA,0xD5,0x02,0x84,0xC0, +0x46,0x19,0x00,0x78,0x00,0x0F,0x80,0x07,0xF8,0x03,0x46,0x19,0x00,0x70,0x00,0x00, +0x80,0x08,0xEA,0x37,0xEA,0xFB,0x83,0xFF,0x2E,0x07,0xFD,0x02,0xC0,0x02,0xEB,0x0B, +0xEA,0x69,0xEA,0xA3,0xC8,0x11,0xEA,0xA5,0xC8,0x0F,0x49,0xFF,0xE6,0x49,0xC8,0x0C, +0xEA,0x3E,0x04,0x00,0x80,0x10,0x42,0x00,0x44,0x0B,0xC8,0x06,0x04,0x00,0x80,0x10, +0x42,0x00,0x48,0x0B,0xC0,0x02,0xEB,0x0B,0x97,0xB1,0xDD,0x57,0x12,0x60,0x00,0x50, +0x64,0x00,0x00,0x00,0x84,0x00,0xD5,0x02,0xFA,0x02,0xFC,0x81,0xFC,0x20,0x84,0xA0, +0x50,0x21,0x00,0x24,0x80,0x85,0x45,0x20,0x00,0x48,0x47,0x11,0x00,0x07,0x59,0x18, +0x85,0x00,0x2E,0x30,0x01,0x29,0xE0,0x83,0xE8,0x18,0x82,0x11,0x43,0x02,0x48,0x73, +0x84,0x60,0x2E,0x60,0x01,0x28,0xE0,0x66,0xE8,0x0D,0x38,0x78,0x0D,0x01,0x99,0x9D, +0x40,0x70,0x1C,0x20,0xA5,0xF8,0x40,0x60,0x98,0x20,0x97,0xFB,0xAD,0xF0,0x8C,0x61, +0xD5,0xF1,0x8C,0x81,0x88,0xA2,0xD5,0xE6,0xFC,0xA0,0xFC,0x21,0x3F,0xCF,0xFD,0xD4, +0xF0,0x81,0xDD,0x47,0x80,0xE1,0x80,0xC2,0xDD,0x40,0xC0,0x02,0x84,0xC4,0xEA,0x24, +0xC0,0x1A,0xDD,0x43,0x02,0x30,0x00,0x9C,0x02,0x00,0x00,0x0A,0x8A,0x60,0x40,0x31, +0xA4,0x08,0xBB,0x80,0x3C,0x3D,0xFF,0x75,0xFE,0xDA,0xBB,0x84,0x80,0x06,0x49,0x00, +0x09,0x7C,0xB9,0x04,0xF0,0x01,0x44,0x20,0x01,0xB0,0x42,0x70,0x08,0x73,0x80,0x47, +0x49,0x00,0x09,0x8C,0xFC,0xA1,0x00,0x00,0xFC,0x00,0xE6,0x28,0x4E,0xF2,0x01,0x89, +0x9E,0x82,0xE6,0x47,0x4E,0xF2,0x01,0x85,0x44,0x30,0x01,0xAC,0x3E,0xFF,0xD7,0x34, +0x38,0x27,0x88,0x00,0x40,0xF1,0x3C,0x00,0x4A,0x00,0x3C,0x00,0x08,0x08,0x08,0x08, +0x08,0x0E,0x0E,0x00,0x44,0x20,0xD6,0xB0,0xD5,0x03,0x44,0x20,0xD3,0x58,0x42,0x20, +0x8C,0x73,0x00,0x31,0x01,0x88,0x80,0x22,0xEA,0xB9,0x10,0x31,0x00,0x28,0x3C,0x3D, +0xFF,0x76,0x8E,0x67,0xE6,0x62,0xE8,0x0F,0x46,0x31,0x00,0x07,0x04,0x51,0x83,0xC4, +0x46,0x3A,0x55,0xAA,0x50,0x31,0x85,0x5A,0xD3,0x06,0x2E,0x37,0xFF,0xA3,0x42,0x31, +0x90,0x0B,0xC3,0x05,0x04,0x30,0x80,0x59,0x14,0x31,0x00,0x30,0x46,0x28,0x00,0x20, +0x00,0x30,0x81,0x89,0x10,0x31,0x02,0xBC,0x00,0x30,0x81,0x8A,0x10,0x31,0x00,0x2C, +0x00,0x30,0x81,0x8B,0x10,0x31,0x02,0x38,0x04,0x30,0x80,0x4B,0x14,0x31,0x00,0x8D, +0x04,0x30,0x80,0x4C,0x14,0x31,0x00,0x0E,0x00,0x30,0x81,0x8C,0x10,0x31,0x00,0x40, +0x00,0x30,0x81,0x8D,0x10,0x31,0x00,0x44,0x00,0x30,0x81,0x8E,0x10,0x31,0x00,0x48, +0x00,0x30,0x81,0x8F,0x10,0x31,0x00,0x4C,0x00,0x30,0x81,0x90,0x10,0x31,0x00,0x50, +0x00,0x30,0x81,0x91,0x10,0x31,0x00,0x54,0x00,0x30,0x81,0x92,0x10,0x31,0x00,0x58, +0x00,0x30,0x81,0x93,0x10,0x31,0x00,0x64,0x02,0x30,0x80,0xB4,0x12,0x31,0x00,0x12, +0x02,0x30,0x80,0xB5,0x12,0x31,0x00,0x8A,0x02,0x30,0x80,0xB6,0x12,0x31,0x00,0x1E, +0x00,0x30,0x81,0x94,0x10,0x31,0x00,0x28,0x00,0x30,0x81,0x95,0x10,0x31,0x00,0x34, +0x00,0x30,0x81,0x96,0x10,0x31,0x02,0xAC,0x00,0x30,0x81,0x97,0x10,0x31,0x00,0x18, +0x00,0x30,0x81,0x98,0x10,0x31,0x05,0x68,0x00,0x30,0x81,0x99,0x10,0x31,0x05,0x78, +0x00,0x30,0x81,0x9A,0x10,0x31,0x01,0x30,0x00,0x30,0x81,0x9B,0x10,0x31,0x01,0x2C, +0x00,0x30,0x81,0x9C,0x10,0x31,0x01,0xDC,0x00,0x30,0x81,0x9D,0x10,0x31,0x02,0x9C, +0x00,0x30,0x81,0x9E,0x10,0x31,0x01,0xD8,0x02,0x30,0x80,0xB7,0x12,0x31,0x00,0x9A, +0x02,0x30,0x80,0xB8,0x12,0x31,0x00,0x9C,0x02,0x30,0x80,0xB9,0x12,0x31,0x00,0x0A, +0x02,0x30,0x80,0xBA,0x12,0x31,0x00,0xF8,0x02,0x30,0x80,0xBB,0x12,0x31,0x00,0xFC, +0x02,0x30,0x80,0xBC,0x12,0x31,0x00,0xFE,0x02,0x30,0x80,0xBD,0x12,0x31,0x01,0x00, +0x00,0x30,0x81,0x9F,0x10,0x31,0x02,0x04,0x04,0x30,0x80,0x4D,0x14,0x31,0x00,0x38, +0x04,0x30,0x80,0x4E,0x14,0x31,0x00,0x39,0x00,0x30,0x81,0xA0,0x10,0x31,0x00,0xCC, +0x00,0x30,0x81,0xA1,0x10,0x31,0x00,0xD0,0x02,0x30,0x80,0xBE,0x12,0x31,0x00,0xF6, +0x04,0x30,0x80,0x4F,0x14,0x31,0x00,0x78,0x04,0x30,0x80,0x50,0x14,0x31,0x00,0x79, +0x02,0x30,0x80,0xBF,0x12,0x31,0x00,0xF4,0x02,0x30,0x80,0xC0,0x12,0x31,0x02,0xB8, +0x02,0x30,0x80,0xC1,0x12,0x31,0x00,0xB6,0x04,0x30,0x80,0x51,0x14,0x31,0x00,0xB1, +0x04,0x30,0x80,0x52,0x14,0x31,0x00,0xB3,0x04,0x30,0x80,0x53,0x14,0x31,0x00,0xB4, +0x04,0x30,0x80,0x3F,0x14,0x31,0x01,0x5F,0x04,0x30,0x80,0x40,0x14,0x31,0x01,0x60, +0x04,0x30,0x80,0x41,0x14,0x31,0x01,0x61,0x04,0x30,0x80,0x42,0x14,0x31,0x01,0x62, +0x04,0x30,0x80,0x43,0x14,0x31,0x01,0x63,0x04,0x30,0x80,0x44,0x14,0x31,0x01,0x64, +0x04,0x30,0x80,0x45,0x14,0x31,0x01,0x65,0x04,0x30,0x80,0x46,0x14,0x31,0x01,0x66, +0x04,0x30,0x80,0x47,0x14,0x31,0x01,0x67,0x04,0x30,0x80,0x48,0x14,0x31,0x01,0x68, +0x04,0x30,0x80,0x49,0x14,0x31,0x01,0x69,0x04,0x30,0x80,0x4A,0x14,0x31,0x01,0x6A, +0x00,0x30,0x81,0xA2,0x10,0x31,0x00,0xD8,0x04,0x30,0x80,0x54,0x14,0x31,0x00,0x30, +0x04,0x30,0x80,0x55,0x14,0x31,0x00,0x31,0x04,0x30,0x80,0x56,0x14,0x31,0x00,0x32, +0x00,0x30,0x81,0xA3,0x10,0x31,0x00,0xB0,0x00,0x30,0x81,0xA4,0x10,0x31,0x00,0xB4, +0x00,0x30,0x81,0xA5,0x10,0x31,0x05,0xBC,0x04,0x30,0x80,0x57,0x14,0x31,0x00,0xB2, +0x04,0x30,0x80,0x58,0x14,0x31,0x00,0xB0,0x00,0x30,0x81,0xA6,0x10,0x31,0x01,0x58, +0x00,0x30,0x81,0xA7,0x10,0x31,0x01,0x5C,0x02,0x30,0x80,0xC2,0x46,0x52,0x00,0x00, +0x12,0x31,0x00,0x94,0x50,0x22,0x80,0xFC,0xB4,0x61,0xB6,0x65,0xB4,0x85,0xB4,0x61, +0x4C,0x41,0xFF,0xFC,0x8C,0xA4,0x8C,0x24,0xDA,0xF8,0x49,0xFF,0xC8,0x68,0x49,0xFF, +0xC4,0x7C,0x46,0x00,0x00,0x0D,0x00,0x00,0x04,0xF9,0x8E,0x01,0x96,0x00,0x3E,0x07, +0xFD,0x0E,0x46,0x00,0x00,0x0D,0x00,0x00,0x06,0xA5,0x8E,0x01,0x96,0x00,0x3E,0x07, +0xFD,0x15,0xEA,0x9B,0x80,0xC0,0xC8,0x0E,0xDD,0x5C,0xDD,0x50,0xDD,0x4B,0x8E,0x07, +0xE6,0x02,0xE8,0x08,0x84,0x21,0xDD,0x43,0x10,0x10,0x02,0xA0,0xD5,0x03,0xFA,0x02, +0xD5,0x02,0x80,0x06,0xFC,0x80,0x92,0x00,0xFC,0x40,0x84,0xC0,0x80,0x26,0x84,0x01, +0xEA,0x3B,0x80,0x26,0x8C,0xC1,0x84,0x00,0x97,0xB0,0xEA,0x3B,0x5A,0x68,0x04,0xF8, +0x84,0xE0,0x3E,0x77,0xFD,0x19,0x46,0x68,0x00,0x20,0x85,0x21,0x3E,0x97,0xFD,0x01, +0x10,0x73,0x01,0x68,0x44,0x00,0x01,0xF4,0x10,0x73,0x02,0x14,0x10,0x73,0x02,0xA0, +0x10,0x73,0x00,0xB0,0x10,0x73,0x00,0x84,0x10,0x73,0x01,0x00,0x10,0x73,0x00,0x8C, +0x10,0x73,0x00,0x1C,0x10,0x73,0x00,0x20,0xDD,0x50,0x10,0x93,0x00,0x20,0xDD,0x5C, +0x10,0x73,0x00,0x94,0xEA,0x6E,0x8E,0x01,0xC8,0xFE,0x84,0x21,0x46,0x28,0x00,0x30, +0x10,0x13,0x00,0x94,0x12,0x01,0x00,0xE4,0x10,0x13,0x00,0x90,0x46,0x19,0x00,0x68, +0xAE,0x08,0xDD,0x4B,0x8E,0x07,0xE6,0x02,0xE8,0x0B,0x46,0x01,0x00,0x07,0xEA,0x63, +0xEA,0x21,0xEA,0x20,0xD0,0x04,0xDD,0x4D,0xEA,0xF0,0xC0,0x02,0xEA,0x5E,0x84,0x20, +0xEA,0x73,0xAE,0x40,0xDD,0x4F,0x46,0x01,0x00,0x00,0x58,0x00,0x0B,0x14,0x84,0x20, +0xDD,0x42,0xFC,0xC0,0xFC,0x00,0x3F,0xCF,0xFD,0xD8,0x46,0x10,0x00,0xE7,0x84,0x00, +0x50,0x10,0x8C,0x15,0x44,0x20,0x00,0x68,0xDD,0x4C,0xDD,0x43,0x84,0x21,0x46,0x20, +0xFF,0xFF,0xEA,0x47,0x50,0x21,0x0F,0xFF,0x10,0x10,0x00,0x1C,0x10,0x10,0x00,0x84, +0x10,0x10,0x00,0x80,0xEB,0x4C,0xB4,0xA0,0xEA,0x28,0xDA,0xFE,0x84,0xC1,0x84,0x00, +0x10,0x60,0x80,0xFC,0x10,0x60,0x81,0x00,0x10,0x00,0x80,0x90,0xB8,0x00,0x8E,0x07, +0xE6,0x02,0xE8,0x08,0xEA,0x5E,0xEA,0x5D,0xEB,0x00,0xEA,0x43,0xB4,0x01,0xEA,0xF3, +0xB6,0x01,0x84,0x01,0xEA,0x55,0xB8,0x00,0x8E,0x02,0xE6,0x04,0xE8,0x05,0xFA,0x38, +0xDD,0x43,0x10,0x10,0x00,0xD8,0xB8,0x00,0x5A,0x08,0x02,0x05,0x84,0x03,0x49,0x00, +0x08,0xB8,0xB8,0x00,0x5A,0x08,0x06,0x07,0x44,0x10,0xFF,0xEE,0xDD,0x43,0x14,0x10, +0x00,0xAD,0xFC,0x80,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00, +0xDD,0x45,0xDD,0x57,0xF8,0x07,0xC1,0x31,0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFE, +0xEA,0xDF,0x04,0x10,0x00,0x15,0x92,0x30,0x96,0x48,0x83,0xFF,0x5A,0x18,0x33,0x26, +0xEB,0x2C,0x8E,0x27,0xE6,0x22,0xE8,0x21,0x04,0x10,0x00,0x15,0x92,0x38,0x5A,0x18, +0x11,0x05,0x3E,0x17,0xFD,0x06,0xD5,0x08,0x04,0x00,0x00,0x15,0x92,0x18,0x5A,0x08, +0x22,0x04,0x3E,0x07,0xFD,0x06,0x2E,0x07,0xFD,0x06,0x5A,0x08,0x22,0x09,0xEA,0x48, +0xEA,0x3F,0x83,0xFF,0x46,0x11,0x00,0x07,0xEA,0x70,0xD5,0x07,0x2E,0x07,0xFD,0x06, +0x5A,0x08,0x11,0x04,0x84,0x01,0xEA,0xC8,0xDD,0x57,0x04,0x10,0x00,0x16,0x4E,0x00, +0xFF,0xD4,0xC1,0x06,0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFD,0xEA,0xDF,0x04,0x00, +0x00,0x17,0x5A,0x08,0xA5,0x11,0xFC,0x00,0x44,0x10,0x00,0x87,0xDD,0x57,0x14,0x10, +0x00,0x17,0xF9,0x9A,0x84,0x00,0xEB,0x3E,0xEB,0x3A,0xEA,0x5C,0xEA,0x93,0xEA,0xCF, +0xDD,0x50,0xD5,0xFD,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00, +0x58,0x00,0x01,0x00,0xDD,0x45,0xDD,0x9E,0xFC,0x00,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x30,0x00,0xDD,0x45,0xDD,0x57,0x04,0x10, +0x00,0x3A,0x83,0xFF,0x42,0x10,0xE0,0x0B,0xC1,0x08,0x44,0x10,0x00,0x49,0x12,0x10, +0x00,0x0E,0x84,0x20,0x12,0x10,0x00,0x0E,0x04,0x00,0x00,0x3A,0x42,0x00,0x68,0x0B, +0xC0,0x04,0x84,0x02,0x49,0xFF,0xFC,0x36,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11, +0x00,0x07,0x96,0x00,0x58,0x00,0x31,0x00,0xDD,0x45,0xFC,0x80,0xFC,0x01,0x80,0xC0, +0x46,0x09,0x00,0x20,0xA0,0x84,0xB6,0x46,0xA0,0x05,0xB6,0x01,0xB4,0x66,0x42,0x11, +0xC4,0x0B,0xC9,0x04,0x42,0x21,0xC0,0x0B,0xD5,0x03,0x84,0x41,0x80,0x22,0x42,0x01, +0xC8,0x0B,0xC0,0x03,0x84,0x41,0x84,0x22,0x42,0x01,0xCC,0x0B,0xC0,0x03,0x84,0x41, +0x84,0x23,0x42,0x01,0xD0,0x0B,0xC0,0x03,0x84,0x40,0x80,0x22,0x42,0x31,0xD4,0x0B, +0xC3,0x08,0xEA,0x24,0x96,0x00,0xDD,0x55,0x49,0xFF,0xCA,0x02,0x84,0x40,0x84,0x21, +0xB4,0x06,0x42,0x00,0x58,0x0B,0xC0,0x18,0x3C,0x0D,0xFF,0x77,0x5A,0x08,0x01,0x13, +0xDD,0x4B,0x5A,0x08,0x06,0x10,0x84,0x25,0x84,0x02,0xEA,0x8E,0x2E,0x17,0xFD,0x13, +0x8C,0x21,0x96,0x48,0x3E,0x17,0xFD,0x13,0x8C,0x21,0x94,0x09,0x54,0x00,0x00,0xFE, +0xEB,0x20,0x84,0x40,0x84,0x22,0xB4,0x06,0x84,0xC1,0x42,0x00,0x5C,0x0B,0xC0,0x07, +0xDD,0x4D,0xFE,0x36,0xC0,0x19,0x80,0x06,0xEB,0x48,0xD5,0x16,0xC2,0x10,0x5A,0x18, +0x02,0x0B,0xF1,0x81,0xEA,0x93,0xF1,0x01,0x80,0x01,0x44,0x10,0x07,0xD0,0x49,0xFF, +0xFC,0x0F,0xD5,0x0C,0x80,0x06,0xEA,0x3B,0xEB,0x41,0xD5,0x08,0x5A,0x10,0x02,0x07, +0x84,0x00,0xEA,0x3B,0xD5,0x03,0x84,0x23,0xD5,0xFC,0xFC,0x81,0xFC,0x20,0x46,0x60, +0x00,0xCB,0x50,0x73,0x08,0x02,0xDD,0x52,0x80,0x27,0x84,0x00,0xEA,0x60,0x54,0x20, +0x00,0x7F,0x80,0x27,0x84,0x00,0xDD,0x4C,0x50,0x13,0x08,0x05,0x84,0x00,0xEA,0x60, +0x96,0x00,0x92,0x03,0xFC,0xA0,0xFC,0x40,0x46,0x60,0x00,0xCB,0x50,0xA3,0x08,0x05, +0x80,0x2A,0x80,0xE0,0x84,0x00,0xEA,0x60,0x50,0x63,0x08,0x02,0x81,0x20,0xDD,0x52, +0x80,0x26,0x84,0x00,0xEA,0x60,0x54,0x20,0x00,0x7F,0x80,0x26,0x84,0x00,0xDD,0x4C, +0x54,0x24,0x80,0x07,0x40,0x21,0x1C,0x64,0x84,0x00,0x80,0x2A,0x96,0x90,0xDD,0x4C, +0xFC,0xC0,0x2E,0x07,0xFF,0x88,0xC0,0x34,0xFC,0x00,0xEA,0x73,0xA1,0x83,0x49,0xFF, +0xFF,0xC7,0x46,0x21,0x00,0x00,0x02,0x51,0x03,0x01,0x44,0x20,0xA5,0x5A,0x80,0x20, +0xDA,0x09,0x46,0x21,0x00,0x00,0x00,0x51,0x06,0x00,0xD0,0x04,0x00,0x01,0x06,0x00, +0xD5,0x1C,0x3C,0x2D,0xFF,0xE6,0xE2,0x46,0xE8,0x04,0xC0,0x12,0x8E,0x01,0xD5,0x08, +0x3C,0x2D,0xFF,0xE7,0xE2,0xC2,0xE8,0x06,0xE6,0x1F,0xE8,0x0A,0x8C,0x01,0x96,0x40, +0xD5,0x07,0x44,0x0F,0xA5,0x5A,0x46,0x21,0x00,0x00,0x12,0x01,0x03,0x01,0x46,0x01, +0x00,0x00,0x10,0x10,0x06,0x00,0x80,0x01,0x49,0xFF,0xFF,0xAF,0xFC,0x80,0xDD,0x9E, +0x46,0x09,0x00,0x90,0xEB,0x29,0x58,0x10,0x80,0x04,0xEB,0x07,0x84,0x20,0x10,0x10, +0x00,0x68,0xEB,0x4B,0x54,0x10,0x80,0xFB,0xEA,0x61,0xDD,0x9E,0xC3,0x20,0xFC,0x00, +0x3E,0x07,0xFF,0x88,0x3C,0x1F,0xFF,0xE3,0x46,0x50,0x00,0xF4,0x3C,0x2F,0xFF,0xE4, +0x99,0x8A,0x3C,0x3F,0xFF,0xE5,0x8A,0x22,0x50,0x42,0x82,0x40,0x42,0x53,0x10,0x24, +0xFF,0x0C,0x40,0x52,0x8C,0xB7,0x40,0x32,0x0C,0x77,0x3C,0x5F,0xFF,0xE6,0x3C,0x3F, +0xFF,0xE7,0xC0,0x07,0x49,0xFF,0xFF,0xD6,0x84,0x00,0xD5,0x03,0xFA,0x00,0xDD,0x9E, +0xFC,0x80,0x46,0x09,0x00,0x90,0xEB,0x29,0xEA,0xB3,0xEB,0x07,0x84,0x20,0x10,0x10, +0x00,0x64,0xEB,0x4B,0x54,0x10,0x80,0xFD,0xEA,0x61,0xDD,0x9E,0x46,0x09,0x00,0x90, +0xEB,0x29,0x58,0x10,0x80,0x01,0xEB,0x07,0x84,0x2F,0xEA,0x2F,0xEB,0x4B,0x54,0x10, +0x80,0xFE,0xEA,0x61,0xDD,0x9E,0x3E,0x07,0xFD,0xE8,0x84,0x60,0x3E,0x37,0xFD,0xE9, +0x3E,0x17,0xFD,0xEA,0x3E,0x17,0xFD,0xEB,0x3E,0x27,0xFD,0xEC,0xC0,0x07,0xFC,0x00, +0x49,0xFF,0xFF,0xD9,0x49,0xFF,0xFF,0xE4,0xFC,0x80,0xDD,0x9E,0xFC,0x20,0x46,0x08, +0x00,0x50,0x46,0x69,0x00,0x00,0x84,0xE0,0xB4,0x00,0x12,0x73,0x00,0x4C,0x46,0x00, +0x00,0x0F,0x04,0x00,0x02,0xC0,0xEA,0x9B,0xC8,0x2F,0x3E,0x77,0xFF,0x88,0x44,0x10, +0x01,0xF4,0x3C,0x1F,0xFF,0xE3,0x84,0x2A,0x3C,0x1F,0xFF,0xE4,0x44,0x10,0x02,0x58, +0x3C,0x1F,0xFF,0xE5,0x46,0x10,0x00,0xCF,0x50,0x10,0x88,0x50,0x3C,0x1F,0xFF,0xE6, +0x46,0x10,0x00,0xC7,0x50,0x10,0x86,0x1A,0x3C,0x1F,0xFF,0xE7,0x44,0x10,0x00,0x80, +0x84,0x45,0x49,0xFF,0xFF,0xC2,0x49,0xFF,0xFD,0x79,0x49,0x00,0x05,0x44,0x84,0x09, +0xEB,0x3E,0xEB,0x3A,0xEA,0x5C,0xEA,0x4A,0xC8,0x07,0x44,0x10,0x00,0xDA,0x12,0x13, +0x00,0x1A,0x12,0x13,0x00,0x1E,0xFC,0xA0,0x2E,0x07,0xFD,0xE8,0xC0,0x09,0x46,0x19, +0x00,0x90,0xA6,0x08,0xEA,0x37,0xAE,0x08,0x84,0x01,0x3E,0x07,0xFD,0xE9,0xDD,0x9E, +0x2E,0x07,0xFD,0xE8,0xC0,0x10,0xEB,0x2C,0xEA,0x73,0x5A,0x18,0x08,0x09,0xA0,0x41, +0x84,0x20,0x3E,0x17,0xFD,0xE9,0x00,0x00,0x00,0x60,0xD5,0x05,0xA0,0x02,0x84,0x00, +0x3E,0x07,0xFD,0xE9,0x84,0x00,0xDD,0x9E,0x46,0x28,0x00,0x20,0x02,0x11,0x00,0x9C, +0x02,0x31,0x00,0x0A,0x02,0x01,0x00,0x0A,0x8A,0x23,0x96,0x4B,0x8E,0x09,0x96,0x01, +0x9E,0xC9,0x12,0x01,0x00,0x94,0x84,0x80,0x46,0x09,0x00,0x68,0x96,0xD9,0xAF,0x00, +0xAC,0xC2,0x10,0x40,0x00,0x08,0x84,0x83,0x10,0x40,0x00,0x0C,0x02,0x41,0x00,0x9A, +0x46,0x22,0x00,0x00,0x40,0x21,0x10,0x56,0x8C,0x41,0x90,0x41,0xA8,0x85,0xEA,0xED, +0x10,0x20,0x00,0x20,0x46,0x20,0x40,0x00,0x40,0x11,0x04,0x36,0x8C,0x21,0x90,0x21, +0x14,0x10,0x00,0x09,0x84,0x21,0x12,0x30,0x00,0x14,0xAE,0x40,0xDD,0x9E,0x00,0x00, +0xFC,0x01,0x3F,0xCF,0xFD,0xD8,0xF1,0x81,0xBA,0x00,0xBA,0x82,0xB8,0x80,0xB6,0x1F, +0x2E,0x27,0xFF,0xA2,0x92,0x47,0x3E,0x27,0xFF,0x88,0x84,0x41,0x3E,0x27,0xFD,0x0D, +0x3E,0x27,0xFD,0x0B,0x49,0xFF,0xFD,0x02,0xF1,0x01,0xB4,0x1F,0xC1,0x03,0x49,0xFF, +0xF3,0x35,0xB8,0x00,0x9E,0x42,0xE6,0x27,0xE8,0x20,0x3E,0xFF,0xE0,0x50,0x38,0x17, +0x84,0x00,0x40,0xF0,0xBC,0x00,0xDD,0x0F,0x08,0x08,0x08,0x08,0x16,0x1E,0x26,0x00, +0xEB,0x4A,0xEA,0x74,0x2E,0x27,0xFD,0x79,0x84,0x20,0xE2,0x22,0xD5,0x0C,0x84,0x26, +0xEA,0x74,0x85,0xE2,0xD5,0x08,0xEB,0x4A,0xEA,0x74,0x85,0xE0,0xD5,0x04,0x84,0x26, +0xEA,0x74,0x85,0xE1,0x3C,0xFF,0xFF,0x7C,0xEA,0xF4,0xEA,0x8B,0xC1,0x03,0x84,0x22, +0xB9,0x81,0xB9,0x06,0x49,0xFF,0xFB,0x42,0xC8,0x2F,0xB9,0x00,0x8E,0x27,0xE6,0x22, +0xE8,0x25,0x46,0x11,0x00,0x07,0x04,0x50,0x83,0xC4,0x46,0x1A,0x55,0xAA,0x50,0x10, +0x85,0x5A,0xD1,0x1C,0x2E,0x17,0xFF,0xA3,0xEB,0x34,0xC9,0x18,0x46,0x01,0x00,0x07, +0xEA,0x63,0xEA,0x48,0xEA,0x3F,0xD8,0x06,0x44,0x11,0xFF,0x00,0xDD,0x57,0x14,0x10, +0x00,0x30,0x84,0x05,0xEA,0x55,0xEA,0x93,0x84,0x20,0xDD,0x43,0xEA,0xF1,0x44,0x10, +0x07,0xD0,0x84,0x02,0x49,0xFF,0xFA,0x3C,0xD5,0x07,0xB6,0x1F,0x49,0xFF,0xFF,0x5E, +0x49,0xFF,0xFC,0xFA,0xB4,0x1F,0xFC,0x81,0x92,0x00,0x46,0x18,0x00,0x20,0x50,0x10, +0x85,0xC8,0xA6,0x88,0xDD,0x43,0xCA,0xFE,0xFC,0x00,0x84,0x21,0x10,0x10,0x02,0xA0, +0xEB,0x2C,0x5A,0x18,0x07,0x0C,0x46,0x10,0x00,0x0D,0x02,0x10,0x82,0x6C,0xEA,0xF1, +0x46,0x10,0x00,0x0D,0x02,0x10,0x82,0x6D,0xD5,0x0C,0x5A,0x18,0x08,0x0D,0x46,0x10, +0x00,0x0D,0x02,0x10,0x83,0x42,0xEA,0xF1,0x46,0x10,0x00,0x0D,0x02,0x10,0x83,0x43, +0x12,0x10,0x00,0xB6,0xEA,0x28,0x02,0x00,0x82,0xB8,0x02,0x10,0x80,0xB6,0x49,0xFF, +0xC5,0x86,0xEA,0x9B,0xFC,0x80,0x46,0x08,0x00,0x20,0x00,0x10,0x00,0xF8,0xEB,0x4C, +0xEA,0xB3,0x10,0x10,0x7D,0xBC,0xEA,0xC1,0xEA,0x7F,0xB4,0xA0,0xD9,0xFF,0xDD,0x9E, +0xC0,0x04,0xFC,0x00,0xEA,0x5E,0xFC,0x80,0xEA,0x3E,0x04,0x00,0x80,0x30,0x66,0x00, +0x00,0x01,0x14,0x00,0x80,0x30,0xDD,0x9E,0xFC,0x21,0x3F,0xCF,0xFD,0xD8,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x50,0x00,0xDD,0x45, +0x46,0x69,0x00,0x20,0x04,0x03,0x00,0x0A,0xB6,0x1F,0xB4,0x1F,0xEB,0x12,0xB6,0x1F, +0xF0,0x81,0xF0,0x01,0x66,0x00,0x00,0x04,0xF0,0x81,0xB6,0x1F,0xB4,0x3F,0x84,0x00, +0x49,0x00,0x04,0x9B,0x80,0x1F,0xB0,0x41,0x49,0xFF,0xFD,0x62,0xB4,0x1F,0x42,0x00, +0x2C,0x0B,0xC0,0x19,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00, +0x58,0x00,0x51,0x00,0xDD,0x45,0xB4,0x06,0x66,0x00,0x08,0x00,0xB6,0x06,0xB8,0x00, +0x8E,0x07,0xE6,0x02,0xE8,0x08,0x84,0x00,0x49,0xFF,0xFF,0xBC,0xEA,0x5D,0x84,0x21, +0x10,0x10,0x00,0xA0,0xB4,0x1F,0x42,0x00,0x28,0x0B,0xC0,0x33,0x46,0x01,0x00,0x07, +0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x52,0x00,0xDD,0x45,0xEA,0x43, +0xB4,0x01,0x66,0x00,0x04,0x00,0xB6,0x01,0xB8,0x00,0x5A,0x08,0x02,0x09,0xEA,0xDC, +0x5A,0x08,0x01,0x06,0x84,0x06,0xB8,0x80,0x84,0x04,0xD5,0x0A,0xEA,0xDC,0xC8,0x0A, +0xB8,0x00,0x8E,0x03,0xE6,0x03,0xE8,0x06,0x84,0x02,0xB8,0x80,0x84,0x03,0x49,0x00, +0x05,0x40,0xB8,0x01,0x5A,0x08,0x02,0x0E,0xB8,0x00,0x5A,0x08,0x06,0x05,0xB8,0x02, +0x5A,0x00,0x02,0x04,0x2E,0x07,0xFD,0x03,0x49,0xFF,0xFD,0x8F,0x84,0x00,0xB8,0x81, +0xB4,0x1F,0x42,0x00,0x4C,0x0B,0xC0,0x0D,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11, +0x00,0x07,0x96,0x00,0x58,0x00,0x53,0x00,0xDD,0x45,0x84,0x00,0x49,0xFF,0xFF,0x72, +0xF0,0x01,0x42,0x00,0x38,0x0B,0xC0,0x04,0x49,0xFF,0xF8,0xF4,0xD5,0x07,0xF0,0x01, +0x42,0x00,0x3C,0x0B,0xC0,0x03,0x49,0xFF,0xF8,0xF7,0xF0,0x01,0x84,0xC1,0x42,0x00, +0x0C,0x0B,0xC0,0x16,0xDD,0x43,0x00,0x00,0x03,0x40,0xB9,0x00,0x96,0x00,0x5A,0x18, +0x06,0x10,0x54,0x00,0x00,0xFB,0xC8,0x0C,0xB8,0x01,0x5A,0x00,0x02,0x0A,0x84,0x25, +0x84,0x02,0xEA,0x8E,0x3E,0x67,0xFD,0x13,0x84,0x04,0xEB,0x20,0xBE,0x81,0xF6,0x01, +0x84,0xE1,0x42,0x63,0x04,0x0B,0x4E,0x62,0x00,0x39,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x54,0x00,0xDD,0x45,0x84,0x00,0x80,0x27, +0xEA,0xAB,0x49,0xFF,0xF9,0x5D,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xC4,0x71, +0xD5,0x20,0xFA,0x02,0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0x84,0x0A, +0xDD,0x40,0xC8,0xF5,0xFA,0x0A,0xDD,0x40,0xC8,0xF2,0xFA,0x13,0xDD,0x40,0xC8,0xEF, +0xFA,0x0E,0xDD,0x40,0xC8,0xEC,0xFA,0x18,0xDD,0x40,0xC8,0xE9,0xFA,0x1C,0xDD,0x40, +0xC8,0xE6,0xDD,0x47,0xDD,0x40,0xC8,0xE3,0x84,0x07,0x84,0x21,0x49,0xFF,0xFE,0x62, +0x84,0x00,0x3E,0x07,0xFF,0x87,0xD5,0x24,0xF0,0x01,0xEA,0xA3,0xC0,0x21,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x55,0x00,0xDD,0x45, +0x3E,0x67,0xFD,0x0F,0x80,0x26,0x3E,0x67,0xFD,0x14,0x80,0x06,0xEA,0xAB,0x49,0xFF, +0xF9,0x1F,0x80,0x27,0x2E,0x07,0xFF,0xA6,0x49,0xFF,0xFE,0x44,0xDD,0x52,0x46,0x10, +0x00,0xBC,0x80,0x06,0x8C,0x21,0x84,0x46,0xDD,0x4C,0x3E,0x77,0xFF,0x87,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x56,0x00,0xDD,0x45, +0xFC,0xA1,0xFC,0x00,0xE6,0x04,0xE8,0x03,0x8E,0x01,0xD5,0x1B,0x5A,0x00,0x04,0x04, +0x5A,0x08,0x08,0x14,0x84,0x00,0x46,0x11,0x00,0x05,0x58,0x10,0x88,0x88,0x84,0x44, +0xF8,0x17,0xEA,0x24,0xC0,0x16,0x2E,0x07,0xFD,0x6F,0x3E,0x07,0xFD,0x71,0x8C,0x01, +0x96,0x04,0x3E,0x07,0xFD,0x6F,0xD5,0x0D,0x8E,0x05,0x96,0x40,0xE6,0x23,0xE8,0x09, +0x84,0x23,0x40,0x10,0x04,0x16,0x84,0x44,0x96,0x00,0xEB,0x5A,0xEA,0x77,0xEA,0x7D, +0xFC,0x80,0xFC,0x00,0x54,0x10,0x00,0xFB,0x5A,0x10,0x03,0x04,0x48,0x00,0x00,0x71, +0xF8,0x75,0xB4,0xA2,0xDD,0x43,0xD9,0xFE,0xEB,0x0F,0x44,0x10,0xFE,0xFF,0x83,0xFF, +0xF8,0x03,0x44,0x10,0xFD,0xFF,0xFE,0x56,0xEA,0x32,0xEB,0x0F,0x83,0xFF,0x44,0x10, +0xFB,0xFF,0x4E,0x00,0xFF,0xFA,0x44,0x10,0xF7,0xFF,0xFE,0x56,0xEA,0x32,0x83,0xFF, +0xFA,0x20,0xEA,0x61,0x10,0x10,0x00,0x48,0xEB,0x2D,0x2E,0x17,0xFD,0x6F,0xC1,0x22, +0x5A,0x10,0x01,0x03,0xF8,0x51,0xEB,0x6D,0x02,0x51,0x06,0x8E,0xEB,0x6D,0x02,0x41, +0x06,0x8F,0xEB,0x6D,0x02,0x31,0x06,0x8D,0xEB,0x6D,0x02,0x21,0x06,0x8B,0xF8,0x1E, +0xEB,0x6D,0x04,0x21,0x03,0x37,0x83,0x80,0xBA,0x8E,0x84,0x40,0x10,0x20,0x02,0x38, +0x46,0x20,0x08,0x09,0x50,0x21,0x0A,0x12,0xBA,0x8E,0x50,0x00,0x01,0x9C,0xAE,0x40, +0xD5,0x2A,0xEB,0x6D,0x02,0x51,0x05,0xB8,0xEB,0x6D,0x02,0x41,0x05,0xB9,0xEB,0x6D, +0x02,0x31,0x05,0xB7,0xEB,0x6D,0x02,0x21,0x05,0xB5,0x12,0x50,0x00,0x9C,0x12,0x40, +0x00,0x0A,0x12,0x30,0x00,0x9A,0x12,0x20,0x00,0x8A,0x83,0xFF,0xEB,0x6D,0x04,0x21, +0x02,0xCC,0x83,0x80,0xBA,0x8E,0xEA,0x75,0x46,0x10,0x08,0x09,0x50,0x10,0x8A,0x12, +0xB9,0x8E,0x84,0x21,0x10,0x10,0x01,0x9C,0x50,0x00,0x01,0x9C,0xA6,0x40,0x5A,0x10, +0x01,0xFF,0xF8,0x04,0xA6,0x40,0x5A,0x10,0x01,0xFF,0x48,0x00,0x00,0x6F,0x5A,0x00, +0x04,0x06,0x5A,0x00,0x08,0x04,0x48,0x00,0x00,0x6B,0x46,0x28,0x00,0x20,0xEA,0xC1, +0x50,0x21,0x03,0x3C,0xEA,0x7F,0x83,0xFF,0xB4,0xA2,0xDD,0x43,0xD9,0xFE,0x83,0x80, +0xB9,0x0E,0x42,0x10,0xD4,0x09,0xB9,0x8E,0xEB,0x23,0xC9,0x24,0xEB,0x5D,0x00,0x30, +0x8B,0x8D,0xEB,0x5D,0x00,0x20,0x8B,0x8E,0xEB,0x5D,0x00,0x10,0x8B,0x8F,0xF8,0x23, +0xEB,0x5D,0x02,0x40,0x85,0xB8,0xEB,0x5D,0x02,0x30,0x85,0xB9,0xEB,0x5D,0x02,0x20, +0x85,0xB7,0xEB,0x5D,0x02,0x10,0x85,0xB5,0xF8,0x28,0xEB,0x5D,0x04,0x10,0x82,0xCC, +0xEB,0x1A,0xEB,0x5D,0x02,0x10,0x85,0xB6,0xEA,0x32,0xEB,0x5D,0x00,0x10,0x8B,0x8B, +0xD5,0x30,0xEB,0x5D,0x00,0x30,0x8D,0x39,0xEB,0x5D,0x00,0x20,0x8D,0x3A,0xEB,0x5D, +0x00,0x10,0x8D,0x3B,0x10,0x30,0x00,0x44,0x10,0x20,0x00,0x48,0xEB,0x2D,0x83,0xFF, +0xEB,0x5D,0x02,0x40,0x86,0x8E,0xEB,0x5D,0x02,0x30,0x86,0x8F,0xEB,0x5D,0x02,0x20, +0x86,0x8D,0xEB,0x5D,0x02,0x10,0x86,0x8B,0x12,0x40,0x00,0x9C,0x12,0x30,0x00,0x0A, +0x12,0x20,0x00,0x9A,0x12,0x10,0x00,0x8A,0x83,0xFF,0xEB,0x5D,0x04,0x10,0x83,0x37, +0xEB,0x1A,0xEB,0x5D,0x02,0x10,0x86,0x8C,0xEA,0x32,0xEB,0x5D,0x00,0x10,0x8D,0x37, +0xEA,0x75,0x84,0x21,0x10,0x10,0x01,0x9C,0x49,0xFF,0xFC,0xF0,0xFC,0x80,0x00,0x00, +0xFC,0x20,0x3F,0xCF,0xFD,0xD8,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07, +0x96,0x00,0x58,0x00,0x10,0x00,0xDD,0x45,0xDD,0x43,0x84,0x20,0x10,0x10,0x00,0x88, +0x00,0x60,0x03,0x40,0xEA,0x69,0x97,0xB0,0xEB,0x18,0xC0,0x0B,0xB8,0x00,0x5A,0x08, +0x06,0x09,0x84,0x22,0x84,0x00,0xEA,0x3B,0x84,0x02,0xEB,0x20,0x84,0x00,0xB8,0x81, +0xDD,0x4B,0x8E,0x02,0xE6,0x07,0x4E,0xF2,0x01,0xA2,0x3E,0xFF,0xE6,0x20,0x38,0x07, +0x81,0x01,0x40,0xF0,0x3C,0x00,0xDD,0x0F,0x0E,0x00,0x32,0x03,0x32,0x03,0x32,0x03, +0x7C,0x01,0xAA,0x01,0x6E,0x02,0xDD,0x57,0x04,0x10,0x00,0x3A,0x9F,0xF1,0xEA,0xD7, +0x84,0x01,0xC1,0x09,0x46,0x11,0x00,0x07,0xEA,0xD4,0x40,0x00,0x1C,0x0C,0x40,0x00, +0x80,0x12,0xD5,0x08,0x46,0x11,0x00,0x07,0xEA,0xD4,0x40,0x00,0x1C,0x0C,0xFE,0x0F, +0x96,0x01,0x46,0x11,0x00,0x07,0xEA,0x95,0x46,0x01,0x00,0x07,0x02,0x10,0x07,0xF4, +0x44,0x00,0xDF,0xFF,0xFE,0x0E,0x46,0x11,0x00,0x07,0xEA,0x95,0xEA,0xD4,0x44,0x00, +0xBF,0xFF,0xFE,0x0E,0x46,0x11,0x00,0x07,0xEA,0x95,0x02,0x00,0x87,0xF4,0x54,0x00, +0x7F,0xFF,0xEA,0x95,0x84,0x00,0x3E,0x07,0xFF,0x86,0x84,0x0E,0xDD,0x40,0xC0,0x05, +0x80,0x06,0x49,0xFF,0xC0,0x09,0xEA,0x6C,0xFA,0x02,0xDD,0x40,0xC8,0xFA,0xFA,0x06, +0xDD,0x40,0xC8,0xF7,0x5A,0x60,0x01,0x04,0x48,0x00,0x01,0x53,0xDD,0x43,0x84,0x22, +0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x97,0xF8,0xE6,0xE8, +0xE8,0x04,0x80,0x06,0x49,0xFF,0xFE,0x6F,0x9E,0x33,0xE6,0x02,0xE9,0x08,0x9E,0x37, +0xE6,0x02,0xE9,0x05,0x5A,0x60,0x08,0x03,0xEA,0x6C,0xD5,0x0F,0x80,0x06,0x49,0xFF, +0xFE,0x8A,0x5A,0x60,0x04,0x05,0x5A,0x60,0x08,0x03,0xEA,0x6C,0xB8,0x00,0x49,0xFF, +0xF1,0x4D,0x5A,0x60,0x04,0x13,0xD5,0xEF,0x84,0x01,0x44,0x10,0x04,0xA6,0xEA,0x8E, +0x2E,0x07,0xFD,0x0F,0xC8,0x1A,0xEA,0x73,0xA6,0x40,0xEA,0xB3,0xAE,0x40,0xA6,0x40, +0x58,0x10,0x80,0x04,0xAE,0x40,0xD5,0x11,0xEA,0x24,0x96,0x00,0xDD,0x55,0x49,0xFF, +0xC4,0xD7,0xEA,0xDC,0x5A,0x00,0x01,0x04,0x48,0x00,0x00,0x4A,0xEA,0x43,0xB4,0x01, +0x58,0x00,0x04,0x00,0xB6,0x01,0xD5,0x43,0x2E,0x07,0xFD,0x0F,0x8C,0x01,0x96,0x00, +0xE6,0x04,0xE8,0x03,0xEA,0xD6,0xD5,0x3B,0x84,0x00,0xEA,0xD6,0xDD,0x43,0x00,0x10, +0x03,0x20,0x5A,0x10,0x10,0x06,0x00,0x10,0x03,0x20,0x5A,0x18,0x06,0x31,0xEA,0xC1, +0xEB,0x4C,0xEA,0x7F,0xB4,0xA0,0xD9,0xFF,0x46,0x19,0x00,0x90,0xA6,0x08,0xC8,0xFF, +0x49,0xFF,0xFB,0x21,0xEA,0x69,0xEB,0x18,0xC0,0x09,0x2E,0x0F,0xFF,0xA2,0x4E,0x04, +0x00,0x06,0x49,0xFF,0xFA,0xE5,0x3E,0x07,0xFD,0x03,0x49,0xFF,0xFB,0xF3,0xC0,0x17, +0x48,0x00,0x00,0xE5,0x8E,0xC1,0xE6,0xC2,0x4E,0xF2,0x00,0xCE,0xDD,0x43,0x84,0x22, +0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x84,0x44,0x84,0x00, +0xEB,0x5A,0xEA,0x77,0xEA,0x7D,0xEA,0x24,0x96,0x00,0xDD,0x55,0x49,0xFF,0xB6,0x6C, +0xEA,0x6C,0x5A,0x68,0x01,0x0A,0xDD,0x43,0x84,0x22,0xEA,0x58,0x84,0x23,0xEA,0x47, +0xEA,0x42,0xE6,0x01,0xEA,0x66,0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x00, +0x00,0xBC,0xA6,0x40,0xC9,0xFF,0xEA,0x57,0xE6,0x03,0xEA,0x57,0xE9,0x0C,0x8E,0x02, +0xE0,0xC0,0xE9,0x11,0xEA,0x57,0xE2,0x06,0xE9,0x0E,0x2E,0x17,0xFD,0x0E,0x9C,0x32, +0x8A,0x01,0xD5,0x04,0xE2,0x06,0xE9,0x07,0x9E,0x31,0x96,0x00,0xEB,0x5A,0xEA,0x77, +0x84,0x44,0xEA,0x7D,0xEA,0x57,0x4C,0x60,0x40,0x35,0x84,0xC1,0xDD,0x43,0x12,0x60, +0x02,0xE0,0xEA,0x24,0x96,0x00,0xDD,0x55,0xEA,0x5E,0xEA,0x5D,0xEB,0x00,0xEA,0x43, +0xB4,0x01,0xEA,0xF3,0xB6,0x01,0x2E,0x07,0xFF,0x86,0xE6,0x09,0xE9,0x04,0x84,0x04, +0xEA,0x55,0xD5,0x02,0xEB,0x41,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D,0x80,0x26, +0x44,0x20,0x00,0xAA,0x84,0x00,0xDD,0x4C,0x44,0x00,0x02,0xBC,0xDD,0x50,0x84,0x00, +0x80,0x26,0x44,0x20,0x00,0xBA,0xDD,0x4C,0x2E,0x07,0xFF,0x86,0xE6,0x14,0xE8,0x04, +0x8C,0x01,0x3E,0x07,0xFF,0x86,0xEA,0xA5,0x4E,0x02,0x00,0x5E,0x84,0x01,0xD5,0x02, +0x84,0x02,0xEA,0x55,0xEA,0x6C,0xEA,0x82,0x4C,0x60,0x40,0x56,0x49,0xFF,0xFB,0x66, +0x2E,0x17,0xFD,0x15,0xDD,0x43,0x5A,0x10,0x01,0x05,0x84,0x22,0x10,0x10,0x00,0xB4, +0x84,0xC1,0x84,0x22,0x10,0x60,0x01,0xCC,0xEA,0x58,0x84,0x23,0xEA,0x47,0xEA,0x5E, +0xEA,0x5D,0xEB,0x00,0xEA,0x43,0xB4,0x01,0xEA,0xF3,0xB6,0x01,0xEA,0x82,0x5A,0x08, +0x01,0x18,0xB8,0x00,0x5A,0x08,0x08,0x15,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D, +0x49,0xFF,0xFC,0x3B,0x80,0x26,0x44,0x20,0x00,0xAA,0x84,0x00,0xDD,0x4C,0x44,0x00, +0x02,0xBC,0xDD,0x50,0x84,0x00,0x80,0x26,0x44,0x20,0x00,0xBA,0xDD,0x4C,0xEA,0x42, +0xE6,0x01,0xEA,0x66,0x84,0x44,0x84,0x00,0xEB,0x5A,0xEA,0x77,0xEA,0x7D,0xEA,0x82, +0x5A,0x00,0x01,0x0E,0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x10,0x00,0xBC, +0xA6,0x08,0x96,0x00,0xC8,0xFE,0xEA,0x28,0x10,0x00,0x80,0xB4,0xDD,0x43,0x84,0xC1, +0x12,0x60,0x02,0xE0,0xEA,0x24,0x96,0x00,0xDD,0x55,0x84,0x04,0xEA,0x55,0xEA,0xA5, +0xC0,0x02,0xEB,0x41,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00, +0x58,0x00,0x11,0x00,0xDD,0x45,0x84,0x00,0xD5,0x09,0xFA,0x02,0xD5,0x07,0x5A,0x60, +0x05,0x04,0x48,0xFF,0xFE,0xB5,0x48,0xFF,0xFE,0xB0,0xFC,0xA0,0xFC,0x00,0x84,0x00, +0xEB,0x48,0x2E,0x27,0xFF,0xF0,0x84,0x2A,0xFE,0x54,0x84,0x03,0xEA,0x8E,0xFC,0x80, +0x2E,0x07,0xFF,0x87,0xDD,0x9E,0x8E,0x01,0xC0,0x03,0xEA,0x6E,0xD5,0xFD,0xDD,0x9E, +0xFC,0x01,0x10,0x0F,0x80,0x07,0x10,0x1F,0x80,0x06,0x46,0x08,0x00,0x30,0x84,0x20, +0x10,0x2F,0x80,0x05,0x10,0x10,0x00,0x0C,0x10,0x10,0x00,0x10,0x84,0x21,0x10,0x10, +0x00,0x14,0x00,0x1F,0x80,0x07,0x96,0x48,0x10,0x10,0x00,0x34,0x00,0x1F,0x80,0x06, +0x96,0x48,0x10,0x10,0x00,0x38,0x00,0x1F,0x80,0x05,0x96,0x48,0x10,0x10,0x00,0x3C, +0xFC,0x81,0x84,0x00,0x46,0x21,0x00,0x05,0x58,0x21,0x0A,0x38,0x96,0x40,0x38,0x11, +0x00,0x08,0x50,0x30,0x00,0x6C,0x56,0x10,0x80,0x80,0x8C,0x01,0x38,0x11,0x0C,0x08, +0x5A,0x08,0x6C,0xF6,0xDD,0x9E,0x46,0x38,0x00,0x30,0xA6,0x98,0x46,0x18,0x00,0x30, +0x96,0x90,0x83,0xFF,0xCA,0xFB,0xFA,0x6C,0x10,0x20,0x81,0xB4,0xAE,0xCC,0x10,0x00, +0x80,0xC4,0x84,0x05,0x10,0x20,0x80,0x18,0x10,0x20,0x81,0x18,0x10,0x00,0x80,0x0C, +0x84,0x01,0xEA,0xFB,0x83,0xFF,0xDD,0x9E,0x46,0x08,0x00,0x30,0x14,0x10,0x00,0x32, +0x44,0x1F,0xFF,0xD8,0x10,0x10,0x00,0x34,0x10,0x10,0x00,0x38,0x84,0x20,0x10,0x10, +0x00,0xC0,0x46,0x11,0x00,0x05,0x58,0x10,0x8A,0x38,0x12,0x10,0x00,0x5C,0x96,0x91, +0x84,0x21,0x12,0x20,0x00,0x5E,0xAE,0x40,0xA6,0x40,0xC9,0xFF,0xDD,0x9E,0x46,0x19, +0x00,0x28,0x10,0x00,0x80,0x68,0xDD,0x9E,0x96,0x00,0x46,0x19,0x00,0x28,0x10,0x00, +0x80,0x60,0xDD,0x9E,0x46,0x08,0x00,0x20,0x00,0x00,0x04,0xB4,0xDD,0x9E,0xE6,0x24, +0xE8,0x09,0x94,0x4D,0xC0,0x03,0xEB,0x33,0xD5,0x03,0x46,0x09,0x00,0x10,0x88,0x20, +0xB6,0x41,0xDD,0x9E,0xE6,0x24,0xE8,0x0C,0x94,0x4D,0x96,0x90,0xC0,0x04,0xEB,0x33, +0x8C,0x10,0xD5,0x04,0x46,0x09,0x00,0x10,0x8C,0x08,0x88,0x20,0xAE,0x88,0xDD,0x9E, +0xE6,0x24,0xE8,0x1C,0x94,0x4D,0xC0,0x10,0xEB,0x33,0x50,0x30,0x00,0x10,0x88,0x61, +0x84,0x42,0xAE,0x98,0xA6,0x98,0x96,0x90,0xCA,0xFE,0x8C,0x0C,0x88,0x20,0xAE,0x88, +0xA6,0x08,0xC8,0xFF,0xDD,0x9E,0x46,0x29,0x00,0x10,0x8C,0x48,0x88,0x22,0xAE,0x08, +0x44,0x00,0x00,0x40,0xAE,0x08,0xA6,0x08,0xC8,0xFF,0xDD,0x9E,0x46,0x29,0x00,0x20, +0xB6,0x02,0xA8,0x51,0xDD,0x9E,0x46,0x29,0x00,0x20,0x14,0x01,0x00,0x09,0x14,0x11, +0x00,0x0A,0xDD,0x9E,0x46,0x18,0x00,0x60,0xB6,0x01,0xDD,0x9E,0x46,0x01,0x00,0x00, +0xEA,0x4D,0xEB,0x04,0xD0,0x16,0x46,0x01,0x00,0x00,0xEA,0x4D,0x44,0x00,0xA3,0x3A, +0xD0,0x10,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x06,0xD0,0x0B,0x46,0x01,0x00,0x00, +0x02,0x00,0x00,0x00,0x84,0x20,0x50,0x00,0x45,0x5D,0x40,0x00,0x80,0x06,0xDD,0x9E, +0x84,0x00,0xDD,0x9E,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x06,0xD0,0x07,0x46,0x01, +0x00,0x00,0xEA,0x4D,0x44,0x00,0x3A,0xA3,0xD8,0x3F,0xEA,0x84,0xC0,0x3D,0xFC,0x20, +0x49,0xFF,0xBB,0x81,0xEA,0xAE,0xEA,0x3C,0x84,0xA0,0x98,0x50,0x42,0x11,0x00,0x73, +0x2E,0x00,0x00,0x02,0x46,0x31,0x00,0x00,0x58,0x31,0x80,0x04,0x88,0x20,0x3C,0x23, +0xFE,0xC1,0x44,0x60,0x5A,0xA5,0x80,0x05,0xD1,0x11,0x46,0x41,0x00,0x00,0x02,0x42, +0x00,0x00,0x4C,0x43,0x00,0x06,0x99,0x2A,0x40,0x42,0x04,0xF7,0xAD,0xD8,0x0A,0x41, +0x80,0x01,0x8C,0xA1,0x88,0x04,0x96,0x01,0xD5,0xF0,0xFE,0x02,0x96,0x01,0xEB,0x5A, +0x12,0x00,0x80,0x01,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x06,0xD8,0x04,0x44,0x0F, +0xA5,0x5A,0xD5,0x03,0x44,0x0F,0xA3,0x3A,0xEB,0x5A,0x12,0x00,0x80,0x00,0x8C,0x41, +0x3C,0x2B,0xFE,0xC1,0xFC,0xA0,0xDD,0x9E,0xFC,0x00,0xF8,0x15,0x42,0x10,0x8C,0x0B, +0xC9,0x08,0xF8,0x1C,0xC9,0x06,0x02,0x00,0x00,0x72,0x42,0x00,0x28,0x0B,0xC0,0x36, +0xDD,0x4D,0x96,0x04,0xC0,0x08,0x46,0x09,0x00,0x28,0x84,0x21,0x10,0x10,0x00,0x68, +0x84,0x22,0xEA,0x2F,0xDD,0x57,0x02,0x10,0x00,0x72,0x83,0xFF,0xEA,0xD7,0xC1,0x06, +0x46,0x0E,0xBE,0xBE,0x50,0x00,0x0B,0xEB,0xD5,0x14,0x02,0x10,0x00,0x72,0xEB,0x34, +0x83,0xFF,0xC1,0x06,0x46,0x0E,0xCE,0xCE,0x50,0x00,0x0C,0xEC,0xD5,0x0A,0x02,0x00, +0x00,0x72,0x42,0x00,0x0C,0x0B,0xC0,0x07,0x46,0x0E,0xDE,0xDE,0x50,0x00,0x0D,0xED, +0x49,0xFF,0xB3,0x00,0xDD,0x4D,0x96,0x04,0xC0,0x05,0xEA,0xA5,0xC0,0x03,0x49,0xFF, +0xFE,0x8F,0x44,0x00,0x13,0x88,0x49,0xFF,0xB2,0xEA,0xFC,0x80,0xFC,0x00,0xEA,0x4A, +0xDD,0x52,0xEA,0xCE,0x84,0x20,0x84,0x41,0xEA,0x3A,0x5A,0x08,0xEE,0x04,0x84,0x00, +0xD5,0x20,0xEA,0xCE,0x84,0x20,0x84,0x41,0xEA,0x3A,0x5A,0x08,0xDE,0x04,0x84,0x01, +0xD5,0x18,0xEA,0xCE,0x84,0x20,0x84,0x41,0xEA,0x3A,0x5A,0x08,0xCE,0x17,0x44,0x00, +0x00,0xE8,0x84,0x20,0x84,0x46,0xEA,0x3A,0x5A,0x08,0x03,0x04,0x84,0x02,0xD5,0x09, +0x44,0x00,0x00,0xE8,0x84,0x20,0x84,0x46,0xEA,0x3A,0x5A,0x08,0x04,0x07,0x84,0x03, +0x46,0x11,0x00,0x07,0x12,0x00,0x80,0x40,0xEA,0x3E,0x46,0x21,0x00,0x07,0x04,0x00, +0x80,0x34,0x00,0x21,0x00,0x80,0xFE,0x17,0x14,0x00,0x80,0x74,0xFC,0x80,0x5A,0x00, +0x05,0x0B,0x5A,0x00,0x06,0x14,0x5A,0x08,0x03,0x29,0xF8,0x10,0x44,0x10,0xFF,0x00, +0xF8,0x15,0xD5,0x1F,0xF8,0x0B,0x84,0x30,0xF8,0x11,0x46,0x13,0x11,0x50,0x50,0x10, +0x8E,0x07,0xEA,0xCB,0x14,0x10,0x01,0x60,0xD5,0x14,0xDD,0x43,0x84,0x20,0xEB,0x31, +0xEB,0x32,0x83,0xFF,0xEB,0x31,0xEB,0x32,0x84,0x3A,0x14,0x10,0x00,0xAD,0x84,0x27, +0x10,0x10,0x02,0xAC,0x83,0xFF,0x46,0x10,0x03,0x10,0x50,0x10,0x80,0x31,0xEA,0xCB, +0x84,0x21,0xDD,0x43,0x10,0x10,0x01,0xCC,0xDD,0x9E,0xFC,0x40,0xDD,0x52,0xF8,0x03, +0xFA,0x72,0xDD,0x54,0xDD,0x53,0x84,0x20,0x84,0x4D,0x83,0xFF,0xFA,0x73,0xDD,0x54, +0xEA,0xCF,0x49,0xFF,0xFE,0x22,0x84,0xE0,0x46,0x91,0x00,0x07,0x58,0x94,0x82,0x98, +0xDD,0x53,0x84,0x20,0x84,0x41,0x83,0xFF,0x84,0x65,0xDD,0x54,0x50,0x33,0xFF,0xF3, +0xDD,0x53,0x84,0x20,0x84,0x42,0x83,0xFF,0x96,0xD8,0xDD,0x54,0xDD,0x53,0x84,0x20, +0x84,0x44,0x44,0x30,0x00,0x80,0xDD,0x54,0x44,0x60,0x00,0x64,0xEA,0x6E,0x8E,0xC1, +0x97,0xB1,0xCE,0xFD,0xDD,0x53,0x80,0x26,0x84,0x44,0x80,0x66,0xDD,0x54,0xDD,0x53, +0x80,0x26,0x84,0x45,0xEA,0x3A,0x38,0x04,0x9C,0x08,0x8C,0xE1,0x5A,0x78,0x0D,0xDA, +0x44,0x00,0x72,0xC4,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB1,0x84,0x41,0x80,0x26, +0xDD,0x53,0x44,0x30,0x00,0x40,0xDD,0x54,0xDD,0x53,0x80,0x26,0x80,0x47,0xFA,0x70, +0xDD,0x54,0xFC,0xC0,0xFC,0x00,0x84,0x22,0x80,0xC0,0x80,0x41,0xEA,0xD0,0x84,0x61, +0xDD,0x54,0x84,0x67,0x40,0x31,0x98,0x64,0xEA,0xD0,0x84,0x22,0x84,0x45,0x96,0xD8, +0xDD,0x54,0xFC,0x80,0x84,0x80,0xD5,0x2D,0x41,0x41,0x40,0x09,0x97,0x41,0x92,0x10, +0x40,0x40,0xD0,0x37,0x96,0xD1,0x40,0x10,0xC0,0x08,0xFE,0x47,0x42,0x02,0x0C,0x24, +0xE2,0x20,0xE8,0x09,0x9F,0x21,0x98,0x4A,0xE2,0x22,0xE9,0x05,0xE2,0x20,0xE8,0x03, +0x9F,0x21,0x98,0x4A,0x9A,0x48,0x40,0x10,0xD0,0x17,0x40,0x00,0x40,0x08,0xFE,0x2F, +0xFE,0xCC,0xE2,0x03,0xE8,0x09,0x98,0x02,0x9E,0x49,0xE2,0x02,0xE9,0x05,0xE2,0x03, +0xE8,0x03,0x98,0x02,0x9E,0x49,0x9A,0x03,0x40,0x42,0x40,0x08,0xFE,0x67,0xDD,0x9E, +0x3B,0xFF,0xFE,0xBC,0xFD,0x80,0xFD,0x91,0x83,0x84,0xCB,0x4D,0xE3,0xB2,0xE8,0x19, +0x42,0x09,0x00,0x07,0x82,0xA0,0xC0,0x0D,0x41,0x29,0x00,0x0C,0x52,0x50,0x00,0x20, +0x40,0x58,0x14,0x0D,0x41,0x18,0x80,0x0C,0x41,0x18,0x94,0x04,0x41,0x08,0x00,0x0C, +0xFD,0x08,0x80,0x52,0x49,0xFF,0xFF,0xBA,0x82,0xC1,0x82,0x00,0x86,0xE0,0xD5,0x23, +0xC2,0x28,0x42,0x09,0x00,0x07,0x82,0xA0,0xC8,0x04,0x8B,0xB2,0x86,0xE1,0xD5,0x14, +0x52,0xF0,0x00,0x20,0x41,0x29,0x00,0x0C,0x80,0x52,0x40,0x48,0x3C,0x0D,0x40,0x58, +0x80,0x0C,0x41,0x08,0x00,0x0C,0x40,0x02,0x90,0x04,0x40,0x18,0xBC,0x0D,0x49,0xFF, +0xFF,0x9D,0x82,0xE1,0x82,0x20,0xFD,0x08,0x80,0x52,0x49,0xFF,0xFF,0x97,0x82,0xC1, +0x51,0x00,0x00,0x00,0x4F,0xC2,0x00,0x53,0x86,0x20,0x41,0x08,0x54,0x0D,0xD5,0x4B, +0x41,0x19,0x4A,0x17,0x84,0x20,0x84,0x00,0x4F,0xC2,0x00,0x4C,0xB7,0x9C,0x15,0x1E, +0x00,0x01,0xD5,0x47,0xE3,0xB3,0xE9,0xF7,0x42,0x09,0x80,0x07,0x82,0xA0,0xC0,0x44, +0x52,0x40,0x00,0x20,0x40,0x59,0x10,0x0D,0x40,0x29,0x80,0x0C,0xFE,0xAF,0x82,0x62, +0x41,0x29,0x00,0x0C,0x40,0x38,0x10,0x0D,0x41,0x08,0x00,0x0C,0x40,0x08,0x80,0x0C, +0x40,0x18,0x90,0x0D,0xFE,0x1F,0x49,0xFF,0xFF,0x69,0x82,0xC1,0x82,0x20,0x42,0x00, +0xC8,0x69,0xE3,0xA1,0xE9,0x05,0x4C,0x18,0xC0,0x0C,0xE3,0x80,0xE8,0x09,0x51,0x6B, +0x7F,0xFF,0x8A,0x33,0x40,0x30,0x48,0x01,0xE2,0x03,0x8A,0x2F,0x80,0x03,0x86,0xE0, +0x4F,0xC2,0x00,0x15,0x40,0x08,0x00,0x01,0x40,0x18,0x84,0x01,0xE3,0x80,0x8A,0x2F, +0x52,0x4A,0x80,0x20,0x41,0x10,0x90,0x0C,0x41,0x00,0x54,0x0D,0x41,0x08,0x44,0x04, +0x41,0x10,0xD4,0x0D,0xB7,0x9C,0x15,0x1E,0x00,0x01,0x80,0x16,0x50,0x1B,0x80,0x00, +0x3B,0xFF,0xFE,0x84,0xDD,0x9E,0xE3,0xF1,0xE9,0x03,0xE3,0x92,0xE9,0x09,0x86,0xC1, +0x40,0x48,0x48,0x01,0x8B,0xB3,0xE3,0x84,0x8B,0xAF,0x82,0x04,0xD5,0x02,0x86,0xC0, +0x86,0xE0,0x4F,0xC3,0xFF,0xE9,0xD5,0xEA,0xFC,0x42,0x95,0x09,0x92,0x95,0x40,0x70, +0xAC,0x08,0x40,0x60,0x54,0x09,0xFF,0xF7,0x40,0x60,0x2C,0x08,0x47,0xC8,0x00,0x00, +0x95,0x59,0x92,0xB5,0x40,0x91,0xAC,0x08,0x40,0x81,0x54,0x09,0x40,0x94,0xA0,0x04, +0x40,0x81,0x2C,0x08,0xFE,0xCD,0x40,0xA1,0xF0,0x02,0x44,0x30,0x07,0xFF,0xC4,0x58, +0x4C,0x32,0x00,0x75,0x40,0x73,0xF0,0x04,0x4E,0x52,0x00,0x87,0x4C,0x32,0x80,0x79, +0x40,0x94,0xF0,0x04,0x14,0xAF,0x80,0x03,0x50,0x02,0xFC,0x02,0x99,0x20,0x42,0x23, +0xA4,0x69,0x42,0x03,0x24,0x69,0x40,0x91,0x04,0x00,0xE3,0x21,0x40,0xA1,0xBC,0x00, +0x42,0x23,0xA0,0x69,0x99,0xD0,0xE2,0xE0,0x89,0x2F,0xE3,0x2F,0x89,0x4F,0x89,0x23, +0xE3,0x23,0x89,0x4F,0x42,0x03,0x20,0x69,0x99,0xF9,0xE2,0xE1,0x89,0x2F,0xE3,0x2F, +0x40,0x15,0x3C,0x00,0xFF,0xC7,0x58,0x04,0x80,0x01,0x40,0x04,0x9C,0x1A,0xE4,0x20, +0xE9,0x07,0x81,0xE0,0x98,0x00,0xE2,0x0F,0x98,0x49,0x88,0x2F,0x9F,0x21,0x04,0xAF, +0x80,0x03,0x4E,0x47,0x00,0x71,0x52,0x52,0x07,0xFF,0x4E,0x57,0x00,0x46,0x50,0x00, +0x04,0x00,0x5C,0xF0,0x04,0x00,0xE8,0x04,0x88,0x2F,0xE2,0x2F,0x88,0x8F,0x40,0x20, +0x2C,0x09,0x96,0x94,0x9A,0x02,0x92,0x0B,0x40,0x20,0xD4,0x08,0xFE,0x17,0x94,0x49, +0x92,0x2C,0x40,0x52,0x50,0x08,0xFE,0x6F,0x40,0x10,0xA8,0x04,0xFC,0xC2,0x40,0xF3, +0x98,0x04,0xE8,0x19,0x40,0xF3,0x7C,0x09,0x99,0xFF,0x88,0xEF,0x99,0xB6,0xCF,0x05, +0x80,0xE6,0x84,0xC0,0x50,0x42,0x7F,0xE0,0x42,0x03,0x80,0x07,0xC0,0x9E,0x9B,0x20, +0x52,0x20,0x00,0x20,0x40,0x23,0x08,0x0D,0x40,0x63,0x00,0x0C,0x40,0x73,0x80,0x0C, +0xFF,0xD7,0xD5,0x93,0xD3,0x15,0x80,0x2A,0xFC,0xC2,0xFF,0xF7,0x4C,0x7E,0x40,0x11, +0xCD,0x06,0x40,0x24,0x84,0x08,0x40,0x21,0x20,0x04,0xC2,0x0A,0xDB,0x05,0x40,0x94, +0xA0,0x04,0x4C,0x9E,0x40,0x06,0x84,0x00,0x46,0x17,0xFF,0x00,0xD5,0xCE,0x84,0x00, +0x44,0x18,0x00,0x00,0xFC,0xC2,0x40,0x04,0xA0,0x04,0xC0,0xE6,0x40,0xF4,0x7C,0x09, +0x89,0x29,0x89,0x2F,0x89,0x08,0x4E,0x93,0x00,0x06,0x81,0x28,0x85,0x00,0x50,0x52, +0xFF,0xE0,0x42,0x04,0x80,0x07,0x4E,0x02,0xFF,0x6F,0x9B,0x68,0x52,0x20,0x00,0x20, +0x40,0x24,0x08,0x0D,0x40,0x84,0x00,0x0C,0x40,0x94,0x80,0x0C,0x40,0x94,0x88,0x04, +0x48,0xFF,0xFF,0x62,0x84,0xC0,0x52,0x32,0x00,0x01,0x5C,0xF1,0x80,0x20,0xE9,0x0A, +0x80,0xC0,0x80,0x01,0x84,0x20,0x50,0x31,0xFF,0xE0,0xC0,0x04,0x5C,0xF1,0x80,0x20, +0xE8,0x1A,0xC3,0x10,0x52,0x21,0x80,0x20,0x40,0x70,0x88,0x0C,0x40,0x50,0x08,0x0C, +0x40,0x00,0x0C,0x0D,0x40,0x10,0x8C,0x0D,0xFE,0x3F,0xFF,0xAF,0xC6,0x03,0x58,0x00, +0x00,0x01,0x50,0x00,0x04,0x00,0x5C,0xF0,0x04,0x00,0x88,0x2F,0x40,0x40,0xFC,0x09, +0x48,0xFF,0xFF,0x77,0x84,0x00,0xD5,0xA0,0xFC,0x42,0x95,0x09,0x92,0x95,0x40,0x70, +0xAC,0x08,0x40,0x60,0x54,0x09,0xFF,0xF7,0x40,0x60,0x2C,0x08,0x47,0xC8,0x00,0x00, +0x95,0x59,0x92,0xB5,0x40,0x91,0xAC,0x08,0x40,0x81,0x54,0x09,0x40,0x94,0xA0,0x04, +0x40,0x81,0x2C,0x08,0xFE,0xCD,0x40,0xA1,0xF0,0x02,0x44,0x30,0x07,0xFF,0x4E,0x42, +0x00,0xC5,0x4C,0x32,0x00,0xEF,0x40,0x73,0xF0,0x04,0x4E,0x52,0x00,0xFB,0x4C,0x32, +0x80,0xF3,0x40,0x94,0xF0,0x04,0x9B,0x25,0x50,0x42,0x03,0xFF,0x92,0xC1,0x40,0x13, +0xFC,0x08,0xFF,0x8F,0x92,0xE1,0x40,0x24,0xC0,0x09,0x40,0x33,0x88,0xF7,0x40,0x14, +0x80,0x13,0x42,0x50,0x8C,0x24,0x40,0x73,0xC0,0x08,0x40,0x03,0x40,0x09,0xFF,0xC7, +0x80,0x07,0x9B,0xFD,0xE2,0x07,0xE8,0x05,0x9E,0xD9,0x88,0xE9,0xE2,0xE9,0xE8,0xFD, +0x40,0x23,0x88,0xF7,0x42,0x50,0x88,0x24,0x40,0x73,0xC0,0x08,0x96,0x31,0xFF,0xC7, +0x80,0x07,0x9B,0xFD,0xE2,0x07,0xE8,0x05,0x9E,0x91,0x88,0xE9,0xE2,0xE9,0xE8,0xFD, +0x40,0x31,0xC0,0x08,0x98,0xDA,0x42,0x01,0xA0,0x69,0xFF,0x82,0x80,0x07,0x9B,0xF9, +0xE2,0x07,0xC6,0x05,0x80,0x07,0x9F,0xF9,0xE9,0x03,0xE2,0x07,0xE8,0x0C,0x9E,0xD9, +0x88,0xC8,0x40,0x03,0x20,0x06,0x88,0xE9,0xE2,0xE9,0xC0,0x04,0x9D,0xF9,0xE9,0x03, +0xE6,0xE1,0xE8,0xF6,0x4C,0x74,0xC0,0x07,0x80,0x28,0x80,0xE6,0x84,0x40,0x84,0x00, +0xD5,0x2B,0x40,0x14,0xC0,0x09,0x40,0x23,0x84,0xF7,0x40,0x04,0x80,0x13,0x42,0xF0, +0x08,0x24,0x40,0x73,0xC0,0x08,0x40,0x53,0x40,0x09,0xFF,0xEF,0x80,0xA7,0x8A,0xEF, +0xE2,0xA7,0xE8,0x05,0x9E,0x91,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,0x40,0x13,0x84,0xF7, +0x42,0x50,0x04,0x24,0x40,0x73,0xC0,0x08,0x96,0x31,0xFF,0xC7,0x80,0x07,0x9B,0xFD, +0xE2,0x07,0xE8,0x05,0x9E,0x49,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,0x40,0x21,0x40,0x08, +0x98,0x91,0x42,0x01,0x20,0x69,0xFF,0x82,0x80,0x07,0x9B,0xF9,0xE2,0x07,0xC6,0x05, +0x80,0x07,0x9F,0xF9,0xE9,0x03,0xE2,0x07,0xE8,0x0C,0x9E,0x91,0x88,0xC8,0x40,0x03, +0x20,0x06,0x88,0xE9,0xE2,0xE9,0xC0,0x04,0x9D,0xF9,0xE9,0x03,0xE6,0xE1,0xE8,0xF6, +0xE4,0x60,0xE9,0x07,0x81,0xE2,0x98,0x92,0xE2,0x4F,0x98,0xDB,0x88,0x6F,0x9F,0x21, +0xFF,0xF7,0x58,0x01,0x00,0x01,0x40,0x01,0x1C,0x1A,0x80,0x23,0x4E,0x47,0x00,0x79, +0x52,0x52,0x07,0xFF,0x4E,0x57,0x00,0x4A,0x50,0x00,0x04,0x00,0x5C,0xF0,0x04,0x00, +0xE8,0x04,0x88,0x2F,0xE2,0x2F,0x88,0x8F,0x40,0x20,0x2C,0x09,0x96,0x94,0x9A,0x02, +0x92,0x0B,0x40,0x20,0xD4,0x08,0xFE,0x17,0x94,0x49,0x92,0x2C,0x40,0x52,0x50,0x08, +0xFE,0x6F,0x40,0x10,0xA8,0x04,0xFC,0xC2,0x40,0xF3,0x98,0x04,0xE8,0x1B,0x40,0xF3, +0x7C,0x09,0x99,0xFF,0x88,0xEF,0x99,0xB6,0xCF,0x05,0x80,0xE6,0x84,0xC0,0x50,0x42, +0x7F,0xE0,0x42,0x03,0x80,0x07,0x4E,0x02,0xFF,0x32,0x9B,0x20,0x52,0x20,0x00,0x20, +0x40,0x23,0x08,0x0D,0x40,0x63,0x00,0x0C,0x40,0x73,0x80,0x0C,0xFF,0xD7,0x48,0xFF, +0xFF,0x26,0xD3,0x07,0xCD,0x04,0x40,0xF4,0xA0,0x04,0xE8,0x07,0x80,0x2A,0xFC,0xC2, +0x40,0x94,0xA0,0x04,0x4C,0x9E,0x3F,0xFC,0x84,0x00,0x44,0x18,0x00,0x00,0xFC,0xC2, +0xFF,0xF7,0x4C,0x7E,0x7F,0xFB,0xD3,0xF9,0x84,0x00,0x46,0x17,0xFF,0x00,0x40,0x10, +0xA8,0x04,0xFC,0xC2,0x40,0x94,0xA0,0x04,0x4C,0x9E,0x7F,0xF0,0x84,0x00,0xD5,0xE7, +0x40,0xF4,0xA0,0x04,0xE8,0xF2,0x40,0xF4,0x7C,0x09,0x89,0x29,0x89,0x2F,0x89,0x08, +0x4E,0x93,0x00,0x06,0x81,0x28,0x85,0x00,0x50,0x52,0xFF,0xE0,0x42,0x04,0x80,0x07, +0x4E,0x02,0xFE,0xFB,0x9B,0x68,0x52,0x20,0x00,0x20,0x40,0x24,0x08,0x0D,0x40,0x84, +0x00,0x0C,0x40,0x94,0x80,0x0C,0x40,0x94,0x88,0x04,0x48,0xFF,0xFE,0xEE,0x84,0xC0, +0x52,0x32,0x00,0x01,0x5C,0xF1,0x80,0x20,0xE9,0x0A,0x80,0xC0,0x80,0x01,0x84,0x20, +0x50,0x31,0xFF,0xE0,0xC0,0x04,0x5C,0xF1,0x80,0x20,0xE8,0x1A,0xC3,0x10,0x52,0x21, +0x80,0x20,0x40,0x70,0x88,0x0C,0x40,0x50,0x08,0x0C,0x40,0x00,0x0C,0x0D,0x40,0x10, +0x8C,0x0D,0xFE,0x3F,0xFF,0xAF,0xC6,0x03,0x58,0x00,0x00,0x01,0x50,0x00,0x04,0x00, +0x5C,0xF0,0x04,0x00,0x88,0x2F,0x40,0x40,0xFC,0x09,0x48,0xFF,0xFF,0x6F,0x84,0x00, +0xD5,0x9E,0x92,0x00,0x40,0x30,0xAC,0x08,0x40,0x40,0x54,0x09,0xFE,0xE7,0x46,0x48, +0x00,0x00,0xFE,0xE7,0x95,0x09,0x92,0x95,0x52,0x22,0x04,0x1E,0xE4,0x40,0xE9,0x0C, +0xFA,0x90,0xE2,0x44,0xE9,0x02,0x84,0x60,0x40,0x31,0x88,0x0D,0xE4,0x20,0xE8,0x02, +0xFE,0xDA,0x80,0x03,0xDD,0x9E,0xC0,0x03,0x58,0x10,0x80,0x01,0x46,0x47,0xFF,0x00, +0xE2,0x81,0xE8,0x04,0x46,0x08,0x00,0x00,0xDD,0x9E,0x84,0x1F,0xDD,0x9E,0x92,0x00, +0x3A,0x6F,0x98,0x3C,0x84,0x20,0x80,0xA1,0x80,0x61,0x80,0x40,0xC2,0x10,0xE4,0x40, +0xE8,0x07,0x46,0x58,0x00,0x00,0xFE,0x92,0xC1,0x03,0xFE,0x4A,0x8E,0x41,0x44,0x30, +0x04,0x1E,0x42,0x41,0x00,0x07,0x9A,0xDC,0x40,0x21,0x10,0x0C,0x40,0x40,0xAC,0x09, +0x40,0x61,0x54,0x08,0xFF,0x37,0x95,0x91,0x92,0xCC,0xFF,0x77,0x40,0x61,0xD0,0x08, +0xFF,0x77,0x80,0x04,0x80,0x25,0x3A,0x6F,0x98,0x04,0xDD,0x9E,0x3A,0x6F,0x98,0x3C, +0x84,0x20,0x80,0x61,0x80,0x40,0xC2,0x08,0x44,0x30,0x04,0x1E,0x42,0x51,0x00,0x07, +0x9A,0xDD,0x40,0x21,0x14,0x0C,0x40,0x40,0xAC,0x09,0x40,0x61,0x54,0x08,0xFF,0x37, +0x95,0x51,0x92,0xAC,0x40,0x61,0xD0,0x08,0xFF,0x77,0x80,0x04,0x80,0x25,0x3A,0x6F, +0x98,0x04,0xDD,0x9E,0x49,0x00,0x07,0x54,0x49,0x00,0x2A,0x75,0x49,0x00,0x01,0xE6, +0x46,0x08,0x00,0x20,0x04,0x10,0x03,0xC1,0x12,0x00,0x87,0xA0,0x02,0x00,0x07,0xA0, +0x44,0x00,0x00,0x30,0x49,0x00,0x01,0xF7,0x49,0x00,0x03,0x4D,0x49,0x00,0x4E,0x82, +0x3C,0x0D,0xFF,0x76,0x49,0x00,0x41,0xC9,0x2E,0x07,0xFF,0xA3,0x49,0x00,0x41,0xE7, +0x44,0x20,0x05,0x10,0x49,0x00,0x4D,0xC3,0x3E,0x17,0xFE,0x64,0x49,0x00,0x41,0xB1, +0x44,0x00,0x00,0xBB,0x49,0x00,0x41,0xE7,0x3E,0x07,0xFD,0x19,0x49,0x00,0x1B,0x8A, +0x46,0x09,0x00,0x00,0x66,0x00,0x00,0xFF,0x49,0x00,0x4D,0xC0,0x3E,0x07,0xFE,0x86, +0x2E,0x17,0xFE,0x64,0x44,0x00,0x00,0x64,0x58,0x00,0x06,0x58,0x04,0x00,0x03,0xC1, +0x5E,0xF7,0x80,0x97,0x50,0x00,0x05,0x5A,0x46,0x0A,0x55,0xAA,0x3C,0x00,0x01,0x7E, +0x02,0x3F,0x80,0x07,0x2E,0x07,0xFD,0x01,0x49,0x00,0x32,0x76,0x02,0x0F,0x80,0x07, +0x04,0x50,0x03,0xF1,0x46,0x18,0x00,0x20,0x44,0x00,0xFF,0xFF,0x44,0x10,0x00,0x64, +0x2E,0x07,0xFD,0x79,0x2E,0x00,0x01,0x2B,0x49,0x00,0x31,0xB9,0x3A,0x05,0x04,0x00, +0x10,0x10,0x00,0x60,0x14,0x00,0x83,0xC1,0x40,0x11,0x05,0x04,0x12,0x10,0x00,0x1E, +0x49,0x00,0x43,0xE6,0x49,0x00,0x49,0x08,0x2E,0x00,0x00,0xDF,0x3C,0x03,0xFF,0xC1, +0x58,0x00,0x00,0x01,0x3A,0x0F,0x84,0x20,0x50,0x0F,0x80,0x0F,0x49,0x00,0x42,0x19, +0x49,0x00,0x4E,0x58,0x2E,0x00,0x01,0x28,0x3C,0x0B,0xFE,0xD0,0x46,0x19,0x00,0x00, +0x50,0x00,0x03,0x3A,0x2E,0x07,0xFD,0x48,0x2E,0x17,0xFE,0x60,0x2E,0x07,0xFD,0x19, +0x46,0x19,0x00,0x20,0x2E,0x07,0xFE,0x61,0x2E,0x07,0xFD,0x29,0x3E,0x07,0xFE,0x65, +0x10,0x10,0x00,0x8C,0x46,0x0A,0x33,0xAA,0x2E,0x07,0xFD,0x6E,0x49,0x00,0x43,0x0E, +0x3E,0x07,0xFD,0x2A,0x3E,0x1F,0xFF,0xA0,0x02,0x50,0x00,0x00,0x49,0x00,0x1B,0x95, +0x3C,0x3D,0xFF,0x95,0x49,0x00,0x0F,0x20,0x2E,0x07,0xFD,0x00,0x2E,0x07,0xFD,0x07, +0x49,0x00,0x09,0x75,0x58,0x00,0x06,0x44,0x3E,0x07,0xFD,0x0D,0x54,0xC6,0x00,0xFF, +0x2E,0x07,0xFD,0x0E,0x10,0x10,0x01,0x68,0x2E,0x07,0xFD,0x51,0x44,0x00,0x01,0xB0, +0x42,0x10,0x84,0x0B,0x64,0x00,0x00,0x08,0x46,0x09,0x00,0x88,0x49,0x00,0x41,0x9A, +0x3C,0x03,0xFF,0xC2,0x49,0x00,0x41,0xEC,0x10,0x10,0x00,0x44,0x58,0x00,0x00,0x98, +0x04,0x50,0x03,0xC4,0x3C,0x0B,0xFE,0xC7,0x3C,0x0B,0xFE,0xCA,0x3E,0xF7,0xFD,0x01, +0x58,0x21,0x0B,0x14,0x49,0x00,0x4F,0xF2,0x2E,0x07,0xFF,0xA4,0x2E,0x07,0xFF,0xA2, +0x3B,0x00,0xC4,0x00,0x48,0x00,0x4D,0xA2,0x49,0x00,0x4E,0x34,0x40,0x00,0x00,0x09, +0x66,0x10,0x80,0xFF,0x14,0x00,0x83,0xC4,0x58,0x10,0x8D,0x68,0x58,0x00,0x00,0x78, +0x46,0x09,0x00,0x90,0x3E,0x10,0x01,0x29,0x10,0x10,0x02,0x38,0x3E,0x07,0xFD,0x4C, +0x58,0x10,0x8B,0x14,0x3C,0x43,0xFE,0xD0,0x40,0x11,0x05,0x00,0x3E,0x17,0xFE,0x65, +0x2E,0x17,0xFD,0x17,0x12,0x10,0x07,0xA0,0x49,0x00,0x44,0x65,0x40,0xF7,0x80,0x11, +0x50,0x10,0x8F,0xFF,0x3C,0x23,0xFE,0xD0,0x02,0x0F,0x80,0x04,0x2E,0x07,0xFD,0x15, +0x2E,0x27,0xFE,0x65,0x2E,0x07,0xFD,0x17,0x46,0xF1,0x00,0x01,0x49,0x00,0x18,0xA4, +0x40,0x00,0x07,0x00,0x49,0x00,0x42,0x19,0x44,0x40,0xFF,0xFF,0x42,0x00,0x04,0x0B, +0x42,0x10,0x94,0x0B,0x58,0x10,0x86,0x04,0x44,0x00,0x00,0xFF,0x49,0x00,0x43,0x8F, +0x3E,0x07,0xFD,0x1E,0x3E,0x07,0xFD,0x67,0x10,0x04,0x80,0x00,0x2E,0x07,0xFD,0x1E, +0x49,0x00,0x43,0x05,0x2E,0x17,0xFD,0x68,0x12,0x00,0x87,0xF4,0x2E,0x07,0xFD,0x65, +0x3E,0x07,0xFD,0x23,0x3E,0x07,0xFD,0x26,0x02,0xF7,0x80,0x12,0x3C,0x13,0xFF,0xBE, +0x49,0x00,0x42,0x24,0x38,0x11,0x0D,0x01,0x2E,0x07,0xFF,0xD2,0x3B,0x01,0x44,0x20, +0x38,0x11,0x0D,0x09,0x3C,0x13,0xFF,0xB7,0x3C,0x30,0x01,0x7E,0x3C,0x13,0xFF,0xB8, +0x42,0x00,0x08,0x0B,0x02,0x00,0x02,0xD4,0x49,0x00,0x43,0xE6,0x3C,0x2D,0xFF,0x95, +0x3C,0x33,0xFE,0xCA,0x3E,0x2F,0xFC,0x08,0x3C,0x00,0x00,0xE3,0x3E,0x07,0xFD,0x34, +0x49,0x00,0x12,0xA2,0x58,0x00,0x0A,0x98,0x3E,0x07,0xFD,0x36,0x2E,0x20,0x00,0x11, +0x40,0xF0,0x3C,0x00,0x2E,0x00,0x01,0x29,0x40,0x00,0x20,0x08,0x44,0x00,0x05,0x10, +0x58,0x10,0x80,0x02,0x3C,0x0B,0xFE,0xD2,0x44,0x60,0xFF,0xFF,0x58,0x00,0x01,0x48, +0x49,0x00,0x10,0x96,0x3C,0x0C,0x00,0x49,0x46,0x29,0x00,0x00,0x02,0x10,0x07,0xA0, +0x2E,0x17,0xFD,0x6E,0x3E,0x27,0xFE,0x65,0x38,0x30,0x89,0x09,0x38,0x13,0x08,0x00, +0x49,0x00,0x18,0xD0,0x10,0x05,0x80,0x00,0x46,0x10,0xFF,0xFF,0x3E,0x07,0xFD,0x08, +0x3E,0x07,0xFD,0x48,0x49,0x00,0x03,0x3F,0x2E,0x07,0xFD,0x05,0x44,0x40,0x00,0x30, +0x44,0x20,0xFF,0xFF,0x3E,0x07,0xFD,0x02,0x3C,0x03,0xFE,0xCA,0x38,0x07,0x1C,0x00, +0x14,0x10,0x01,0x5F,0x2E,0x17,0xFE,0x65,0x3C,0x0B,0xFE,0xE4,0x44,0x00,0x00,0xC6, +0x44,0x00,0x03,0xE8,0x44,0x00,0x00,0xCB,0x2E,0x00,0x00,0x10,0x02,0x0F,0x80,0x01, +0x02,0x0F,0x80,0x02,0x02,0x10,0x87,0xF4,0x3C,0x0B,0xFF,0xC2,0x3E,0x07,0xFD,0x0F, +0x42,0x10,0xA8,0x0B,0x58,0x00,0x00,0x4C,0x3E,0x0F,0xFE,0xC4,0x40,0x01,0x00,0x40, +0x2E,0x20,0x01,0x2B,0x49,0x00,0x3A,0x56,0x40,0x00,0x04,0x16,0x3C,0x1C,0x00,0x48, +0x10,0x10,0x00,0x50,0x38,0x00,0x80,0x01,0x12,0x00,0x87,0x92,0x02,0x00,0x07,0x92, +0x3C,0x03,0xFE,0xD0,0x44,0x70,0x00,0xFF,0x02,0x0F,0x80,0x05,0x2E,0x07,0xFD,0x58, +0x2E,0x07,0xFD,0x16,0x40,0x00,0x40,0x08,0x44,0x10,0x35,0xCA,0x3B,0x00,0xC4,0x20, +0x54,0xA0,0x00,0xFF,0x10,0x00,0x82,0xC0,0x44,0x20,0x00,0x30,0x00,0x03,0x00,0x92, +0x42,0x31,0xC0,0x24,0x42,0x00,0x10,0x0B,0x12,0x10,0x02,0xB8,0x49,0x00,0x1B,0x8E, +0x58,0x00,0x08,0x00,0x2E,0x17,0xFF,0xA4,0x2E,0x17,0xFF,0xA2,0x48,0x00,0x12,0xA1, +0x49,0x00,0x1B,0xB7,0x3E,0x07,0xFD,0x65,0x3E,0x07,0xFD,0x64,0x58,0x00,0x02,0xC4, +0x10,0x00,0x80,0x08,0x3E,0x07,0xFD,0x68,0x2E,0x17,0xFD,0x65,0x49,0x00,0x32,0x18, +0x3C,0x03,0xFF,0xC0,0x10,0x60,0x00,0xA0,0x42,0x01,0x04,0x73,0x2E,0x07,0xFD,0x21, +0x58,0x00,0x00,0x02,0x44,0x00,0xA5,0x5A,0x58,0x00,0x00,0x04,0x44,0x00,0x5A,0xA5, +0x10,0x10,0x00,0x40,0x2E,0x07,0xFD,0x68,0x3C,0x13,0xFF,0xBF,0x49,0x00,0x3D,0xBE, +0x44,0x60,0x00,0x55,0x3E,0x07,0xFD,0x20,0x42,0x13,0x00,0x73,0x00,0x20,0x00,0x08, +0x02,0x20,0x00,0x1E,0x50,0x1F,0x81,0x90,0x49,0x00,0x34,0x88,0x66,0x00,0x00,0x02, +0x49,0x00,0x0A,0xA8,0x42,0x10,0x80,0x03,0x3C,0x0B,0xFE,0xC4,0x2E,0x07,0xFD,0x2B, +0x58,0x10,0x81,0x44,0x42,0x00,0x14,0x0B,0x46,0x61,0x00,0x02,0x14,0x10,0x00,0x0E, +0x58,0x21,0x0D,0x08,0x02,0x00,0x02,0xD6,0x3C,0x30,0x01,0x7B,0x3C,0x30,0x01,0x7A, +0x49,0x00,0x01,0xDE,0x49,0x00,0x4F,0xE2,0x3C,0x0D,0xFF,0x9A,0x46,0x11,0x00,0x03, +0x2E,0x17,0xFD,0x79,0x58,0x63,0x01,0x44,0x49,0x00,0x15,0x5B,0x00,0x00,0x02,0x7C, +0x2E,0x07,0xFD,0x30,0x3C,0x00,0x00,0xE2,0x00,0x10,0x00,0x40,0x49,0x00,0x35,0x6A, +0x50,0x21,0x00,0xE8,0x3C,0x1D,0xFF,0x76,0x10,0x10,0x00,0x4C,0x3E,0x07,0xFD,0x31, +0x58,0x10,0x80,0x78,0x58,0x10,0x80,0x04,0x14,0x10,0x01,0x6D,0x14,0x10,0x01,0x6E, +0x46,0x09,0x00,0x80,0x42,0x10,0x90,0x0B,0x38,0xF1,0x06,0x02,0x58,0x21,0x0F,0xF4, +0x38,0x06,0x82,0x02,0x2E,0x07,0xFD,0x3B,0x49,0x00,0x0F,0x14,0x64,0x12,0x00,0x43, +0x3C,0x0D,0xFF,0x87,0x3E,0x07,0xFD,0x3D,0x3C,0x0C,0x00,0x48,0x64,0x03,0x00,0x03, +0x3C,0x03,0xFF,0x40,0x3C,0x03,0xFF,0x41,0x3E,0x67,0xFD,0x0D,0x3E,0x2F,0xFF,0x00, +0x2E,0x07,0xFD,0x3D,0x40,0x03,0x98,0x60,0x2E,0x10,0x00,0x14,0x2E,0x07,0xFD,0x3F, +0x58,0x00,0x0B,0x68,0x49,0x00,0x4E,0x2F,0x40,0x00,0x82,0x00,0x2E,0x10,0x00,0x11, +0x00,0x10,0x00,0x44,0x50,0x00,0x03,0x3C,0x44,0x00,0x00,0x3C,0x46,0x01,0x00,0x05, +0x46,0x01,0x00,0x06,0x46,0x01,0x00,0x07,0x46,0x01,0x00,0x01,0x46,0x01,0x00,0x02, +0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x04,0x46,0x01,0x00,0x05, +0x46,0x21,0x00,0x00,0x46,0x21,0x00,0x01,0x46,0x21,0x00,0x02,0x46,0x11,0x00,0x00, +0x46,0x11,0x00,0x01,0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x06,0x46,0x11,0x00,0x07, +0x46,0x51,0x00,0x07,0x46,0x51,0x00,0x08,0x46,0x01,0x00,0x07,0x46,0x01,0x00,0x08, +0x46,0x01,0x00,0x09,0x46,0x01,0x00,0x02,0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x04, +0x46,0x31,0x00,0x01,0x46,0x31,0x00,0x02,0x46,0x31,0x00,0x03,0x46,0x31,0x00,0x07, +0x46,0x31,0x00,0x08,0x46,0x31,0x00,0x09,0x46,0x21,0x00,0x06,0x46,0x21,0x00,0x07, +0x46,0x31,0x00,0x02,0x46,0x31,0x00,0x03,0x46,0x31,0x00,0x04,0x46,0x21,0x00,0x07, +0x46,0x21,0x00,0x08,0x46,0x21,0x00,0x09,0x46,0x21,0x00,0x01,0x46,0x21,0x00,0x02, +0x46,0x21,0x00,0x03,0x46,0x11,0x00,0x01,0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x03, +0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x03,0x46,0x11,0x00,0x04,0x46,0x00,0x00,0x0D, +0x46,0x00,0x00,0x0E,0x46,0x00,0x00,0x0F,0x46,0x01,0x00,0x00,0x46,0x01,0x00,0x01, +0x46,0x01,0x00,0x02,0x46,0x11,0x00,0x07,0x46,0x11,0x00,0x08,0x46,0x11,0x00,0x09, +0x00,0x01,0x02,0x00,0x01,0x02,0x01,0x00,0x00,0x02,0x02,0x01,0x02,0x02,0x01,0x01, +0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09, +0x10,0x11,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01, +0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,0x00,0xA1,0x28,0x04,0x00,0x0A,0x85,0x02, +0x00,0x54,0x50,0x01,0x48,0x19,0x00,0x10,0x02,0x04,0x02,0x00,0x00,0x00,0x00,0x00, +0x04,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x02,0x04,0x00,0x00,0x00,0x00, +0x04,0x02,0x01,0x04,0x03,0x02,0x00,0x00,0x02,0x01,0x04,0x03,0x01,0x02,0x00,0x00, +0x03,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x03,0x02,0x00,0x00,0x00,0x00, +0x04,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00, +0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xA2,0x82,0xA2,0x82,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0xA1,0x81,0xA1, +0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA2,0x82,0xA2,0x82,0xA2,0x0D,0x00,0x00, +0x00,0x00,0x00,0x00,0xC1,0xA1,0xE1,0x81,0xA1,0x85,0xC5,0xA5,0xE5,0x0E,0x00,0x00, +0xE5,0x85,0xC5,0xAA,0xC1,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0xA2,0xC1,0x82, +0xE1,0x2F,0x00,0x00,0x00,0x00,0x00,0x00,0xE3,0x83,0xC3,0xA3,0xE3,0x0C,0x00,0x00, +0x00,0x00,0x00,0x00,0xC5,0xA5,0xE5,0x05,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xEA,0xCA,0xEA,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0xE5,0xC5,0x85, +0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCA,0x09,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xAA,0x8A,0x0A,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x8A,0xAA,0x1D,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEA,0xCA,0x2D,0x02, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0x3D,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x81,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xA1,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0x03,0x03,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE1,0x04,0x03,0x00,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xA5,0x5A,0x08,0x04,0x06,0x02,0x09,0x52,0x44,0x4A,0x4E,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x46,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x41,0x72,0x69,0x6D,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x39,0x30,0x39,0x30,0x33,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x14,0x02,0x3F,0x82,0xC2,0x10,0x02,0x03,0x37,0x64,0x30,0x96,0xC8,0x3C,0xFF,0x0A, +0x14,0x14,0x28,0x14,0x32,0x32,0x25,0x20,0x05,0x40,0x25,0x14,0x14,0x82,0x82,0x16, +0x16,0x53,0x75,0x0A,0x78,0x46,0x64,0x3C,0x0F,0x0C,0x00,0x00,0x11,0x00,0x00,0x08, +0x0F,0x0A,0x96,0x10,0x09,0x06,0x0A,0x04,0x14,0x64,0xFF,0x14,0x00,0x00,0x1E,0x8C, +0x64,0x64,0x78,0x90,0x08,0x00,0x0F,0x06,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,0x80,0x00,0x00,0x00, +0x00,0x0C,0x00,0x00,0x00,0x1E,0x20,0x22,0x24,0x00,0x50,0x02,0x02,0x0A,0x02,0x05, +0x24,0x12,0x0A,0x06,0xE5,0x00,0x08,0x70,0x04,0x38,0x00,0x7F,0x03,0x44,0x47,0x34, +0x00,0x04,0x56,0x0D,0xD4,0x53,0x0F,0x00,0x00,0x7F,0x03,0x44,0x47,0x34,0x00,0x04, +0x56,0x0D,0xD4,0x53,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x28,0x00,0x00, +0x00,0x00,0x00,0x16,0x0A,0x14,0x0A,0x0A,0x14,0x64,0x14,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x0B,0x0C,0x1B,0x15,0x50,0x25,0x02,0x50,0x0F,0x03,0x00,0x28,0xB2,0x64, +0x04,0x3C,0x35,0x1E,0x32,0x80,0x0E,0x07,0x23,0x0A,0xB4,0x78,0x96,0x5A,0x64,0x32, +0x00,0x00,0x64,0x64,0x00,0x14,0x03,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09, +0x06,0x0A,0x0A,0x78,0x3C,0x96,0x32,0x00,0x00,0x00,0x00,0x88,0x30,0x00,0x00,0x00, +0x00,0x0A,0x0A,0x50,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x06,0x00,0x00,0x00, +0x1E,0x00,0x00,0x00,0x00,0x02,0xD0,0x05,0x00,0x0A,0x05,0xFF,0x0A,0x03,0xE8,0x03, +0xE8,0x03,0x02,0x01,0xF4,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0F, +0x14,0x14,0x0A,0x0A,0x1C,0x30,0x00,0x00,0x11,0x11,0x0A,0x05,0x3D,0x0A,0x1B,0x33, +0x00,0x00,0x11,0x0A,0x05,0x85,0x14,0x15,0x14,0x10,0x15,0x14,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x01,0x0A,0x06,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x6F,0x08,0x6F,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x5C,0x08,0x6F,0x08, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xED,0x00,0x36,0x01,0xE2,0x02,0x2D,0x03,0x37,0x04,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0x00,0x40,0x01,0xDF,0x02, +0x34,0x03,0x37,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x08,0x70,0x14,0x00,0x00,0x08,0x70,0x14,0x00,0x00,0x04,0x38,0x0A,0x00, +0x00,0x04,0x38,0x0A,0x64,0x0C,0x64,0xFF,0x96,0x96,0x64,0x3C,0xC8,0xFF,0xB4,0x5A, +0x05,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40, +0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x65,0x67,0x65,0x67,0x65,0x67,0x65,0x67,0x64,0x65,0x64,0x65, +0x00,0x65,0x00,0x65,0x00,0x65,0x00,0x65,0x64,0x65,0x64,0x65,0x65,0x67,0x65,0x67, +0x65,0x67,0x65,0x67,0x00,0x00,0x00,0x00,0x26,0x00,0x39,0x00,0x24,0x0C,0x36,0x0C, +0xFF,0x34,0x00,0x45,0x00,0xFF,0x37,0x00,0x26,0x00,0xFF,0x36,0x00,0x24,0x00,0xFF, +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, +0x05,0x02,0x00,0xFA,0x00,0xFA,0x01,0xC2,0x03,0x20,0x01,0x2C,0x19,0x20,0x00,0x4B, +0x32,0x32,0x00,0x00,0x01,0xF4,0x00,0x96,0xC8,0x18,0x18,0x01,0xF4,0x20,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFE,0xF7,0x9B,0x3C,0xFF,0xFF,0x07,0x80,0x4B,0x00,0xEF,0x0F,0x0C,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0x5A, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE3,0x64, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00, +0x07,0x0E,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x0A,0xBA,0x90,0x00,0x20,0x00,0x00,0x00,0xDC,0x05,0x00,0x00,0xC9,0x00,0x00,0x00, +0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00, +0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00, +0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x81,0x02,0x20,0x47,0x81,0x02, +0x85,0x0C,0x81,0x02,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00, +0x00,0x00,0x00,0x00,0x78,0x02,0x00,0x00,0x03,0x5D,0x08,0x02,0x1F,0x06,0x11,0x1B, +0x0C,0x11,0x1F,0x09,0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15, +0x00,0x04,0x30,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,0x07,0x0E,0x15,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0A,0xBA,0x90,0x00, +0x20,0x00,0x00,0x00,0xDC,0x05,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00, +0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA, +0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x04,0x81,0x02,0x20,0x47,0x81,0x02,0x85,0x0C,0x81,0x02, +0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00, +0x78,0x02,0x00,0x00,0x03,0x5D,0x08,0x02,0x1F,0x06,0x11,0x1B,0x0C,0x11,0x1F,0x09, +0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,0x00,0x04,0x30,0x03, +0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x22,0x9A,0x80,0x00,0x20,0x00,0x00,0x00, +0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00, +0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, +0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x03,0x00,0x00, +0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00, +0x5E,0x01,0x5E,0x01,0xC8,0x00,0x14,0x00,0x29,0x0E,0x5B,0x0E,0x97,0x00,0x00,0x00, +0x04,0x5D,0x08,0x04,0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x03,0x02,0x03, +0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,0x00,0x04,0x30,0x03,0x02,0x00,0x03,0x03, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0x38,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x00,0x00,0x00,0x3A,0x9A,0x84,0x00,0x20,0x00,0x00,0x00,0xF4,0x01,0x00,0x00, +0xC9,0x00,0x00,0x00,0x00,0x41,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00, +0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, +0x02,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x04,0xA0,0x00, +0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01, +0xC8,0x00,0x14,0x00,0xA4,0x38,0xD6,0x38,0x97,0x00,0x00,0x00,0x04,0x5D,0x08,0x04, +0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x04,0x02,0x03,0x00,0x02,0x03,0x03, +0x01,0x00,0x15,0x15,0x00,0x03,0x30,0x03,0x00,0x01,0x03,0x03,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x0E,0x00, +0x15,0x00,0x31,0x00,0x1C,0x00,0x23,0x00,0x2A,0x00,0x31,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x22,0x9A,0x80,0x00,0x20,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00, +0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00, +0xAA,0xAA,0xAA,0xA2,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00, +0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00, +0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00, +0x00,0x00,0x00,0x00,0x97,0x00,0x00,0x00,0x04,0x05,0x08,0x04,0x1F,0x06,0x10,0x1A, +0x0B,0x10,0x15,0x09,0x00,0x03,0x00,0x03,0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15, +0x00,0x04,0x30,0x01,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x0E,0x00,0x15,0x00,0x31,0x00, +0x1C,0x00,0x23,0x00,0x2A,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x3A,0xBA,0x84,0x00, +0x20,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00, +0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xA2, +0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x04,0xA0,0x00,0x20,0x47,0x64,0x00,0x34,0x08,0x64,0x00, +0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00, +0x97,0x00,0x00,0x00,0x04,0x05,0x08,0x07,0x1F,0x08,0x11,0x18,0x0C,0x11,0x16,0x09, +0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,0x00,0x04,0x30,0x01, +0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0x31,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x3A,0x9A,0x84,0x00,0x20,0x00,0x00,0x00, +0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00, +0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, +0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00, +0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x97,0x00,0x00,0x00, +0x04,0x05,0x08,0x04,0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x04,0x07,0x03, +0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,0x00,0x04,0x30,0x01,0x00,0x00,0x03,0x03, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x65,0x02,0x66,0x02,0x67,0x02,0x68,0x02,0x69,0x02,0x6A,0x02,0x6B,0x02,0x6C,0x02, +0x6D,0x02,0x6E,0x02,0x6F,0x02,0x70,0x02,0x71,0x02,0x72,0x02,0x73,0x02,0x74,0x02, +0x75,0x02,0x76,0x02,0x77,0x02,0x78,0x02,0x79,0x02,0x7A,0x02,0x7B,0x02,0x7C,0x02, +0x7D,0x02,0x7E,0x02,0x7F,0x02,0x80,0x02,0x81,0x02,0x82,0x02,0x83,0x02,0x84,0x02, +0x85,0x02,0x86,0x02,0x87,0x02,0x88,0x02,0x41,0x02,0x42,0x02,0x43,0x02,0x44,0x02, +0x45,0x02,0x46,0x02,0x47,0x02,0x48,0x02,0x49,0x02,0x4A,0x02,0x4B,0x02,0x4C,0x02, +0x4D,0x02,0x4E,0x02,0x4F,0x02,0x50,0x02,0x51,0x02,0x52,0x02,0x53,0x02,0x54,0x02, +0x55,0x02,0x56,0x02,0x57,0x02,0x58,0x02,0x59,0x02,0x5A,0x02,0x5B,0x02,0x5C,0x02, +0x5D,0x02,0x5E,0x02,0x5F,0x02,0x60,0x02,0x61,0x02,0x62,0x02,0x63,0x02,0x64,0x02, +0x1D,0x02,0x1E,0x02,0x1F,0x02,0x20,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x24,0x02, +0x25,0x02,0x26,0x02,0x27,0x02,0x28,0x02,0x29,0x02,0x2A,0x02,0x2B,0x02,0x2C,0x02, +0x2D,0x02,0x2E,0x02,0x2F,0x02,0x30,0x02,0x31,0x02,0x32,0x02,0x33,0x02,0x34,0x02, +0x35,0x02,0x36,0x02,0x37,0x02,0x38,0x02,0x39,0x02,0x3A,0x02,0x3B,0x02,0x3C,0x02, +0x3D,0x02,0x3E,0x02,0x3F,0x02,0x40,0x02,0xF9,0x01,0xFA,0x01,0xFB,0x01,0xFC,0x01, +0xFD,0x01,0xFE,0x01,0xFF,0x01,0x00,0x02,0x01,0x02,0x02,0x02,0x03,0x02,0x04,0x02, +0x05,0x02,0x06,0x02,0x07,0x02,0x08,0x02,0x09,0x02,0x0A,0x02,0x0B,0x02,0x0C,0x02, +0x0D,0x02,0x0E,0x02,0x0F,0x02,0x10,0x02,0x11,0x02,0x12,0x02,0x13,0x02,0x14,0x02, +0x15,0x02,0x16,0x02,0x17,0x02,0x18,0x02,0x19,0x02,0x1A,0x02,0x1B,0x02,0x1C,0x02, +0xD5,0x01,0xD6,0x01,0xD7,0x01,0xD8,0x01,0xD9,0x01,0xDA,0x01,0xDB,0x01,0xDC,0x01, +0xDD,0x01,0xDE,0x01,0xDF,0x01,0xE0,0x01,0xE1,0x01,0xE2,0x01,0xE3,0x01,0xE4,0x01, +0xE5,0x01,0xE6,0x01,0xE7,0x01,0xE8,0x01,0xE9,0x01,0xEA,0x01,0xEB,0x01,0xEC,0x01, +0xED,0x01,0xEE,0x01,0xEF,0x01,0xF0,0x01,0xF1,0x01,0xF2,0x01,0xF3,0x01,0xF4,0x01, +0xF5,0x01,0xF6,0x01,0xF7,0x01,0xF8,0x01,0xB1,0x01,0xB2,0x01,0xB3,0x01,0xB4,0x01, +0xB5,0x01,0xB6,0x01,0xB7,0x01,0xB8,0x01,0xB9,0x01,0xBA,0x01,0xBB,0x01,0xBC,0x01, +0xBD,0x01,0xBE,0x01,0xBF,0x01,0xC0,0x01,0xC1,0x01,0xC2,0x01,0xC3,0x01,0xC4,0x01, +0xC5,0x01,0xC6,0x01,0xC7,0x01,0xC8,0x01,0xC9,0x01,0xCA,0x01,0xCB,0x01,0xCC,0x01, +0xCD,0x01,0xCE,0x01,0xCF,0x01,0xD0,0x01,0xD1,0x01,0xD2,0x01,0xD3,0x01,0xD4,0x01, +0x8D,0x01,0x8E,0x01,0x8F,0x01,0x90,0x01,0x91,0x01,0x92,0x01,0x93,0x01,0x94,0x01, +0x95,0x01,0x96,0x01,0x97,0x01,0x98,0x01,0x99,0x01,0x9A,0x01,0x9B,0x01,0x9C,0x01, +0x9D,0x01,0x9E,0x01,0x9F,0x01,0xA0,0x01,0xA1,0x01,0xA2,0x01,0xA3,0x01,0xA4,0x01, +0xA5,0x01,0xA6,0x01,0xA7,0x01,0xA8,0x01,0xA9,0x01,0xAA,0x01,0xAB,0x01,0xAC,0x01, +0xAD,0x01,0xAE,0x01,0xAF,0x01,0xB0,0x01,0x69,0x01,0x6A,0x01,0x6B,0x01,0x6C,0x01, +0x6D,0x01,0x6E,0x01,0x6F,0x01,0x70,0x01,0x71,0x01,0x72,0x01,0x73,0x01,0x74,0x01, +0x75,0x01,0x76,0x01,0x77,0x01,0x78,0x01,0x79,0x01,0x7A,0x01,0x7B,0x01,0x7C,0x01, +0x7D,0x01,0x7E,0x01,0x7F,0x01,0x80,0x01,0x81,0x01,0x82,0x01,0x83,0x01,0x84,0x01, +0x85,0x01,0x86,0x01,0x87,0x01,0x88,0x01,0x89,0x01,0x8A,0x01,0x8B,0x01,0x8C,0x01, +0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4A,0x01,0x4B,0x01,0x4C,0x01, +0x4D,0x01,0x4E,0x01,0x4F,0x01,0x50,0x01,0x51,0x01,0x52,0x01,0x53,0x01,0x54,0x01, +0x55,0x01,0x56,0x01,0x57,0x01,0x58,0x01,0x59,0x01,0x5A,0x01,0x5B,0x01,0x5C,0x01, +0x5D,0x01,0x5E,0x01,0x5F,0x01,0x60,0x01,0x61,0x01,0x62,0x01,0x63,0x01,0x64,0x01, +0x65,0x01,0x66,0x01,0x67,0x01,0x68,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01, +0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2A,0x01,0x2B,0x01,0x2C,0x01, +0x2D,0x01,0x2E,0x01,0x2F,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01, +0x35,0x01,0x36,0x01,0x37,0x01,0x38,0x01,0x39,0x01,0x3A,0x01,0x3B,0x01,0x3C,0x01, +0x3D,0x01,0x3E,0x01,0x3F,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01, +0xFD,0x00,0xFE,0x00,0xFF,0x00,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01, +0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0A,0x01,0x0B,0x01,0x0C,0x01, +0x0D,0x01,0x0E,0x01,0x0F,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01, +0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1A,0x01,0x1B,0x01,0x1C,0x01, +0x1D,0x01,0x1E,0x01,0x1F,0x01,0x20,0x01,0xD9,0x00,0xDA,0x00,0xDB,0x00,0xDC,0x00, +0xDD,0x00,0xDE,0x00,0xDF,0x00,0xE0,0x00,0xE1,0x00,0xE2,0x00,0xE3,0x00,0xE4,0x00, +0xE5,0x00,0xE6,0x00,0xE7,0x00,0xE8,0x00,0xE9,0x00,0xEA,0x00,0xEB,0x00,0xEC,0x00, +0xED,0x00,0xEE,0x00,0xEF,0x00,0xF0,0x00,0xF1,0x00,0xF2,0x00,0xF3,0x00,0xF4,0x00, +0xF5,0x00,0xF6,0x00,0xF7,0x00,0xF8,0x00,0xF9,0x00,0xFA,0x00,0xFB,0x00,0xFC,0x00, +0xB5,0x00,0xB6,0x00,0xB7,0x00,0xB8,0x00,0xB9,0x00,0xBA,0x00,0xBB,0x00,0xBC,0x00, +0xBD,0x00,0xBE,0x00,0xBF,0x00,0xC0,0x00,0xC1,0x00,0xC2,0x00,0xC3,0x00,0xC4,0x00, +0xC5,0x00,0xC6,0x00,0xC7,0x00,0xC8,0x00,0xC9,0x00,0xCA,0x00,0xCB,0x00,0xCC,0x00, +0xCD,0x00,0xCE,0x00,0xCF,0x00,0xD0,0x00,0xD1,0x00,0xD2,0x00,0xD3,0x00,0xD4,0x00, +0xD5,0x00,0xD6,0x00,0xD7,0x00,0xD8,0x00,0x91,0x00,0x92,0x00,0x93,0x00,0x94,0x00, +0x95,0x00,0x96,0x00,0x97,0x00,0x98,0x00,0x99,0x00,0x9A,0x00,0x9B,0x00,0x9C,0x00, +0x9D,0x00,0x9E,0x00,0x9F,0x00,0xA0,0x00,0xA1,0x00,0xA2,0x00,0xA3,0x00,0xA4,0x00, +0xA5,0x00,0xA6,0x00,0xA7,0x00,0xA8,0x00,0xA9,0x00,0xAA,0x00,0xAB,0x00,0xAC,0x00, +0xAD,0x00,0xAE,0x00,0xAF,0x00,0xB0,0x00,0xB1,0x00,0xB2,0x00,0xB3,0x00,0xB4,0x00, +0x6D,0x00,0x6E,0x00,0x6F,0x00,0x70,0x00,0x71,0x00,0x72,0x00,0x73,0x00,0x74,0x00, +0x75,0x00,0x76,0x00,0x77,0x00,0x78,0x00,0x79,0x00,0x7A,0x00,0x7B,0x00,0x7C,0x00, +0x7D,0x00,0x7E,0x00,0x7F,0x00,0x80,0x00,0x81,0x00,0x82,0x00,0x83,0x00,0x84,0x00, +0x85,0x00,0x86,0x00,0x87,0x00,0x88,0x00,0x89,0x00,0x8A,0x00,0x8B,0x00,0x8C,0x00, +0x8D,0x00,0x8E,0x00,0x8F,0x00,0x90,0x00,0x49,0x00,0x4A,0x00,0x4B,0x00,0x4C,0x00, +0x4D,0x00,0x4E,0x00,0x4F,0x00,0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00, +0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,0x5A,0x00,0x5B,0x00,0x5C,0x00, +0x5D,0x00,0x5E,0x00,0x5F,0x00,0x60,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x64,0x00, +0x65,0x00,0x66,0x00,0x67,0x00,0x68,0x00,0x69,0x00,0x6A,0x00,0x6B,0x00,0x6C,0x00, +0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2A,0x00,0x2B,0x00,0x2C,0x00, +0x2D,0x00,0x2E,0x00,0x2F,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00, +0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3A,0x00,0x3B,0x00,0x3C,0x00, +0x3D,0x00,0x3E,0x00,0x3F,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00, +0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00, +0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0A,0x00,0x0B,0x00,0x0C,0x00, +0x0D,0x00,0x0E,0x00,0x0F,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00, +0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1A,0x00,0x1B,0x00,0x1C,0x00, +0x1D,0x00,0x1E,0x00,0x1F,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0x00,0x00,0x03,0xB9,0x83,0x11,0x2B,0x01,0xBD,0x01,0x02,0xC2,0x08,0x70, +0x01,0xBD,0x03,0x04,0xB2,0x04,0x38,0x08,0x70,0x01,0xBD,0x00,0x0A,0xB1,0xF8,0x27, +0x27,0x00,0x00,0x0B,0x0E,0x0B,0x0E,0x33,0x02,0xD2,0x2D,0x2D,0x0B,0xB2,0x80,0x02, +0x18,0x80,0x70,0x00,0x08,0x1C,0x08,0x11,0x05,0x01,0xE9,0xD1,0x02,0xB2,0x00,0x08, +0x01,0xE9,0x00,0x01,0xBD,0x02,0x02,0xB2,0xB5,0x0A,0x01,0xBD,0x00,0x08,0xDD,0x00, +0x00,0x08,0x1C,0x08,0x34,0x34,0x88,0x18,0xB4,0x65,0x6B,0x00,0x00,0xD0,0xD4,0x36, +0xCF,0x06,0xCE,0x00,0xCE,0x00,0x00,0x00,0x07,0x00,0x2A,0x07,0x01,0x07,0x00,0x00, +0x2A,0x01,0xBD,0x03,0x01,0xE9,0xC3,0x03,0xB4,0x01,0x67,0x2A,0x01,0xE9,0x00,0x01, +0xBD,0x00,0x01,0xC1,0x01,0x01,0xBD,0x01,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1, +0xEF,0xEA,0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7, +0xB0,0xA8,0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22, +0x17,0x0D,0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8, +0xCC,0x9B,0x00,0x01,0xBD,0x02,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA, +0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8, +0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D, +0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B, +0x00,0x01,0xBD,0x03,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,0xE7,0xE5, +0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,0xA0,0x98, +0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,0x09,0x07, +0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,0x00,0x01, +0xBD,0x00,0x01,0xC2,0xC8,0x01,0xCC,0x08,0x25,0xD3,0x81,0x00,0x00,0x00,0x00,0x01, +0x00,0x04,0x00,0x01,0x13,0x40,0x04,0x09,0x09,0x0B,0x0B,0x32,0x10,0x08,0x00,0x08, +0x32,0x10,0x08,0x00,0x08,0x32,0x10,0x08,0x00,0x08,0x00,0x00,0x0A,0x08,0x7B,0x01, +0xE9,0xC5,0x01,0xC6,0xF7,0x01,0xE9,0x00,0x01,0xE9,0xD4,0x01,0xC6,0x6E,0x01,0xE9, +0x00,0x01,0xE9,0xEF,0x01,0xD3,0x0C,0x01,0xE9,0x00,0x01,0xBD,0x01,0x01,0xE9,0xC8, +0x01,0xD3,0xA1,0x01,0xE9,0x00,0x01,0xBD,0x00,0x38,0xD5,0x18,0x18,0x19,0x18,0x18, +0x20,0x18,0x18,0x18,0x10,0x10,0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18, +0x28,0x28,0x18,0x18,0x18,0x18,0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36, +0x36,0x37,0x37,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0xFC, +0xFC,0x00,0x00,0x30,0xD6,0x18,0x18,0x19,0x18,0x18,0x20,0x19,0x18,0x18,0x10,0x10, +0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,0x28,0x28,0x18,0x18,0x18,0x18, +0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,0x36,0x37,0x37,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA, +0xAF,0xEA,0xAA,0xAA,0xAA,0xAB,0xAF,0xEF,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01, +0xBD,0x01,0x0C,0xD8,0xAA,0xAA,0xAB,0xAF,0xEA,0xAA,0xAA,0xAA,0xAE,0xAF,0xEA,0xAA, +0x01,0xBD,0x02,0x0C,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA, +0xAA,0x01,0xBD,0x03,0x18,0xD8,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF, +0xEA,0xAA,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,0xBD, +0x00,0x01,0xE9,0xE4,0x02,0xE7,0x17,0x69,0x01,0xE9,0x00,0x19,0xE7,0x09,0x09,0x00, +0x07,0xE8,0x00,0x26,0x00,0x07,0x00,0x00,0xE8,0x32,0x00,0xE9,0x0A,0x0A,0x00,0x00, +0x00,0x01,0x01,0x00,0x12,0x04,0x01,0xBD,0x01,0x09,0xE7,0x02,0x00,0x01,0x20,0x01, +0x18,0x08,0xA8,0x09,0x01,0xBD,0x02,0x03,0xE7,0x20,0x20,0x00,0x01,0xBD,0x03,0x06, +0xE7,0x00,0xDC,0x11,0x70,0x00,0x20,0x01,0xE9,0xC9,0x06,0xE7,0x2A,0xCE,0x02,0x70, +0x01,0x04,0x01,0xE9,0x00,0x01,0xBD,0x00,0x01,0xD1,0x27,0x04,0xC9,0x04,0x0C,0x6D, +0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0x00,0x00,0x03,0xB9,0x83,0x11,0x2B,0x01,0xBD,0x01,0x02,0xC2,0x08,0x70, +0x01,0xBD,0x03,0x04,0xB2,0x04,0x38,0x08,0x70,0x01,0xBD,0x00,0x0A,0xB1,0xF8,0x27, +0x27,0x00,0x00,0x0B,0x0E,0x0B,0x0E,0x33,0x02,0xD2,0x2D,0x2D,0x0B,0xB2,0x80,0x02, +0x18,0x80,0x70,0x00,0x08,0x1C,0x08,0x11,0x05,0x01,0xE9,0xD1,0x02,0xB2,0x00,0x08, +0x01,0xE9,0x00,0x01,0xBD,0x02,0x02,0xB2,0xB5,0x0A,0x01,0xBD,0x00,0x08,0xDD,0x00, +0x00,0x08,0x1C,0x08,0x34,0x34,0x88,0x18,0xB4,0x65,0x6B,0x00,0x00,0xD0,0xD4,0x36, +0xCF,0x06,0xCE,0x00,0xCE,0x00,0x00,0x00,0x07,0x00,0x2A,0x07,0x01,0x07,0x00,0x00, +0x2A,0x01,0xBD,0x03,0x01,0xE9,0xC3,0x03,0xB4,0x01,0x67,0x2A,0x01,0xE9,0x00,0x01, +0xBD,0x00,0x01,0xC1,0x01,0x01,0xBD,0x01,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1, +0xEF,0xEA,0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7, +0xB0,0xA8,0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22, +0x17,0x0D,0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8, +0xCC,0x9B,0x00,0x01,0xBD,0x02,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA, +0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8, +0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D, +0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B, +0x00,0x01,0xBD,0x03,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,0xE7,0xE5, +0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,0xA0,0x98, +0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,0x09,0x07, +0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,0x00,0x01, +0xBD,0x00,0x01,0xC2,0xC8,0x01,0xCC,0x08,0x25,0xD3,0x81,0x00,0x00,0x00,0x00,0x01, +0x00,0x04,0x00,0x01,0x13,0x40,0x04,0x09,0x09,0x0B,0x0B,0x32,0x10,0x08,0x00,0x08, +0x32,0x10,0x08,0x00,0x08,0x32,0x10,0x08,0x00,0x08,0x00,0x00,0x0A,0x08,0x7B,0x01, +0xE9,0xC5,0x01,0xC6,0xF7,0x01,0xE9,0x00,0x01,0xE9,0xD4,0x01,0xC6,0x6E,0x01,0xE9, +0x00,0x01,0xE9,0xEF,0x01,0xD3,0x0C,0x01,0xE9,0x00,0x01,0xBD,0x01,0x01,0xE9,0xC8, +0x01,0xD3,0xA1,0x01,0xE9,0x00,0x01,0xBD,0x00,0x38,0xD5,0x18,0x18,0x19,0x18,0x18, +0x20,0x18,0x18,0x18,0x10,0x10,0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18, +0x28,0x28,0x18,0x18,0x18,0x18,0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36, +0x36,0x37,0x37,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0xFC, +0xFC,0x00,0x00,0x30,0xD6,0x18,0x18,0x19,0x18,0x18,0x20,0x19,0x18,0x18,0x10,0x10, +0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,0x28,0x28,0x18,0x18,0x18,0x18, +0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,0x36,0x37,0x37,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA, +0xAF,0xEA,0xAA,0xAA,0xAA,0xAB,0xAF,0xEF,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01, +0xBD,0x01,0x0C,0xD8,0xAA,0xAA,0xAB,0xAF,0xEA,0xAA,0xAA,0xAA,0xAE,0xAF,0xEA,0xAA, +0x01,0xBD,0x02,0x0C,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA, +0xAA,0x01,0xBD,0x03,0x18,0xD8,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF, +0xEA,0xAA,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,0xBD, +0x00,0x01,0xE9,0xE4,0x02,0xE7,0x17,0x69,0x01,0xE9,0x00,0x19,0xE7,0x09,0x09,0x00, +0x07,0xE8,0x00,0x26,0x00,0x07,0x00,0x00,0xE8,0x32,0x00,0xE9,0x0A,0x0A,0x00,0x00, +0x00,0x01,0x01,0x00,0x12,0x04,0x01,0xBD,0x01,0x09,0xE7,0x02,0x00,0x01,0x20,0x01, +0x18,0x08,0xA8,0x09,0x01,0xBD,0x02,0x03,0xE7,0x20,0x20,0x00,0x01,0xBD,0x03,0x06, +0xE7,0x00,0xDC,0x11,0x70,0x00,0x20,0x01,0xE9,0xC9,0x06,0xE7,0x2A,0xCE,0x02,0x70, +0x01,0x04,0x01,0xE9,0x00,0x01,0xBD,0x00,0x01,0xD1,0x27,0x04,0xC9,0x04,0x0C,0x6D, +0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x30,0xC3,0x1B,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x08,0x78,0x56,0xE7,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x0C,0x2B,0xDF,0x15 diff --git a/drivers/input/touchscreen/hxchipset83112b/Kconfig b/drivers/input/touchscreen/hxchipset83112b/Kconfig new file mode 100755 index 000000000000..2efd9c3eea89 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/Kconfig @@ -0,0 +1,27 @@ +# +# Himax Touchscreen driver configuration +# + +config TOUCHSCREEN_HIMAX_I2C + tristate "HIMAX chipset i2c touchscreen" + depends on TOUCHSCREEN_HIMAX_CHIPSET + help + This enables support for HIMAX CHIPSET over I2C based touchscreens. + +config TOUCHSCREEN_HIMAX_DEBUG + tristate "HIMAX debug function" + depends on TOUCHSCREEN_HIMAX_I2C + help + This enables support for HIMAX debug function. + +config TOUCHSCREEN_HIMAX_ITO_TEST + tristate "HIMAX driver test over Dragon Board" + depends on TOUCHSCREEN_HIMAX_I2C + help + This enables support for HIMAX driver test over Dragon Board. + +config HMX_DB + tristate "HIMAX driver test over Dragon Board" + depends on TOUCHSCREEN_HIMAX_I2C + help + This enables support for HIMAX driver test over Dragon Board. diff --git a/drivers/input/touchscreen/hxchipset83112b/Makefile b/drivers/input/touchscreen/hxchipset83112b/Makefile new file mode 100755 index 000000000000..522907a48956 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/Makefile @@ -0,0 +1,4 @@ +# Makefile for the Himax touchscreen drivers. + +obj-$(CONFIG_TOUCHSCREEN_HIMAX_I2C) += himax_platform.o himax_ic.o himax_common.o himax_debug.o +obj-$(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) += himax_ito_test.o \ No newline at end of file diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_common.c b/drivers/input/touchscreen/hxchipset83112b/himax_common.c new file mode 100755 index 000000000000..5f1a98fde846 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.c @@ -0,0 +1,2398 @@ +/* Himax Android Driver Sample Code for common functions +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 "himax_common.h" +#include "himax_ic.h" + +#define SUPPORT_FINGER_DATA_CHECKSUM 0x0F +#define TS_WAKE_LOCK_TIMEOUT (2 * HZ) +#define FRAME_COUNT 5 + +#ifdef HX_RST_PIN_FUNC +extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off); +#endif +#if defined(HX_AUTO_UPDATE_FW) + +unsigned char i_CTPM_FW_HX83112A[]= +{ + 0 +}; +unsigned char i_CTPM_FW_HX83112B[]= +{ +#include "FP_DJN_Arima_CID0804_D02_C14_20190903.i" +}; + +#endif + +static void himax_release_all_finger(void); + +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +extern void himax_resend_cmd_func(bool suspended); +extern void himax_rst_cmd_recovery_func(bool suspended); +#endif + +#ifdef HX_RST_PIN_FUNC +int reset_flag =1; +#endif + +struct himax_ts_data *private_ts; +struct himax_ic_data *ic_data; +struct himax_report_data *hx_touch_data; + +static int HX_TOUCH_INFO_POINT_CNT = 0; + +unsigned long FW_VER_MAJ_FLASH_ADDR; +unsigned long FW_VER_MIN_FLASH_ADDR; +unsigned long CFG_VER_MAJ_FLASH_ADDR; +unsigned long CFG_VER_MIN_FLASH_ADDR; +unsigned long CID_VER_MAJ_FLASH_ADDR; +unsigned long CID_VER_MIN_FLASH_ADDR; +//unsigned long PANEL_VERSION_ADDR; + +unsigned long FW_VER_MAJ_FLASH_LENG; +unsigned long FW_VER_MIN_FLASH_LENG; +unsigned long CFG_VER_MAJ_FLASH_LENG; +unsigned long CFG_VER_MIN_FLASH_LENG; +unsigned long CID_VER_MAJ_FLASH_LENG; +unsigned long CID_VER_MIN_FLASH_LENG; +//unsigned long PANEL_VERSION_LENG; + +unsigned long FW_CFG_VER_FLASH_ADDR; + +#ifdef HX_AUTO_UPDATE_FW +int g_i_FW_VER = 0; +int g_i_CFG_VER = 0; +int g_i_CID_MAJ = 0; //GUEST ID +int g_i_CID_MIN = 0; //VER for GUEST +#endif + +unsigned char IC_TYPE = 11; +unsigned char IC_CHECKSUM = 0; + +#ifdef HX_ESD_RECOVERY +u8 HX_ESD_RESET_ACTIVATE = 0; +int hx_EB_event_flag = 0; +int hx_EC_event_flag = 0; +int hx_ED_event_flag = 0; +extern int g_zero_event_count; +#endif +u8 HX_HW_RESET_ACTIVATE = 0; + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) +extern int himax_touch_proc_init(void); +extern void himax_touch_proc_deinit(void); +//PROC-START +#ifdef HX_TP_PROC_FLASH_DUMP +extern void himax_ts_flash_func(void); +extern void setFlashBuffer(void); +extern bool getFlashDumpGoing(void); +extern uint8_t getSysOperation(void); +extern void setSysOperation(uint8_t operation); +#endif +#ifdef HX_TP_PROC_GUEST_INFO +extern int himax_guest_info_get_status(void); +extern void himax_guest_info_set_status(int setting); +extern int himax_read_project_id(void); +#endif + +#if defined(HX_PLATFOME_DEFINE_KEY) +extern void himax_platform_key(void); +#endif + +#ifdef HX_TP_PROC_DIAG +extern void himax_ts_diag_func(void); + +extern int16_t *getMutualBuffer(void); +extern int16_t *getMutualNewBuffer(void); +extern int16_t *getMutualOldBuffer(void); +extern int16_t *getSelfBuffer(void); +extern uint8_t getXChannel(void); +extern uint8_t getYChannel(void); +extern uint8_t getDiagCommand(void); +extern void setXChannel(uint8_t x); +extern void setYChannel(uint8_t y); +extern void setMutualBuffer(void); +extern void setMutualNewBuffer(void); +extern void setMutualOldBuffer(void); +extern uint8_t diag_coor[128]; +extern int himax_set_diag_cmd(struct himax_ic_data *ic_data,struct himax_report_data *hx_touch_data); +#ifdef HX_TP_PROC_2T2R +extern bool Is_2T2R; +extern int16_t *getMutualBuffer_2(void); +extern uint8_t getXChannel_2(void); +extern uint8_t getYChannel_2(void); +extern void setXChannel_2(uint8_t x); +extern void setYChannel_2(uint8_t y); +extern void setMutualBuffer_2(void); +#endif +#endif +//PROC-END +#endif + +extern int himax_parse_dt(struct himax_ts_data *ts, + struct himax_i2c_platform_data *pdata); +extern bool himax_calculateChecksum(struct i2c_client *client, bool change_iref); +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) +static uint8_t vk_press = 0x00; +#endif +static uint8_t AA_press = 0x00; +static uint8_t EN_NoiseFilter = 0x00; +static uint8_t Last_EN_NoiseFilter = 0x00; +static int hx_point_num = 0; // for himax_ts_work_func use +static int p_point_num = 0xFFFF; +static int tpd_key = 0x00; +static int tpd_key_old = 0x00; +static int probe_fail_flag = 0; +#ifdef HX_USB_DETECT_GLOBAL +//bool USB_detect_flag = 0; +#endif + +#if defined(CONFIG_FB) +int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data); +#elif defined(CONFIG_HAS_EARLYSUSPEND) +static void himax_ts_early_suspend(struct early_suspend *h); +static void himax_ts_late_resume(struct early_suspend *h); +#endif + +#if defined(HX_PALM_REPORT) +int himax_palm_detect(uint8_t *buf); +#endif + +#ifdef HX_GESTURE_TRACK +static int gest_pt_cnt; +static int gest_pt_x[GEST_PT_MAX_NUM]; +static int gest_pt_y[GEST_PT_MAX_NUM]; +static int gest_start_x=0,gest_start_y=0,gest_end_x=0,gest_end_y=0; +static int gest_width=0,gest_height=0,gest_mid_x=0,gest_mid_y=0; +static int gn_gesture_coor[16]; +#endif + +#ifdef HX_CHIP_STATUS_MONITOR +struct chip_monitor_data *g_chip_monitor_data; +#endif + +#if defined(HX_TP_PROC_SELF_TEST)|| defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) +extern int g_self_test_entered; +#endif + +int himax_report_data_init(void); +extern int himax_get_touch_data_size(void); +//void himax_HW_reset(uint8_t loadconfig,uint8_t int_off); +extern void himax_log_touch_data(uint8_t *buf,struct himax_report_data *hx_touch_data); +extern void himax_log_touch_event(int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched); +extern void himax_log_touch_event_detail(struct himax_ts_data *ts,int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched,uint16_t old_finger); + +#if defined(HX_ESD_RECOVERY) +extern void himax_esd_ic_reset(void); +extern int himax_ic_esd_recovery(int hx_esd_event,int hx_zero_event,int length); +#endif + +extern int himax_dev_set(struct himax_ts_data *ts); +extern int himax_input_register_device(struct input_dev *input_dev); + + +#ifdef HX_ZERO_FLASH +extern void himax_0f_operation(struct work_struct *work); +#endif + +int himax_input_register(struct himax_ts_data *ts) +{ + int ret = 0; + + ret = himax_dev_set(ts); + if(ret < 0) + goto input_device_fail; + + set_bit(EV_SYN, ts->input_dev->evbit); + set_bit(EV_ABS, ts->input_dev->evbit); + set_bit(EV_KEY, ts->input_dev->evbit); + +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) +#if defined(HX_PLATFOME_DEFINE_KEY) + himax_platform_key(); +#else + set_bit(KEY_BACK, ts->input_dev->keybit); + set_bit(KEY_HOME, ts->input_dev->keybit); + set_bit(KEY_MENU, ts->input_dev->keybit); + set_bit(KEY_SEARCH, ts->input_dev->keybit); + set_bit(KEY_APP_SWITCH, ts->input_dev->keybit); +#endif +#endif + +#if defined(HX_SMART_WAKEUP) || defined(HX_PALM_REPORT) + set_bit(KEY_POWER, ts->input_dev->keybit); +#endif +#if defined(HX_SMART_WAKEUP) + set_bit(KEY_CUST_01, ts->input_dev->keybit); + set_bit(KEY_CUST_02, ts->input_dev->keybit); + set_bit(KEY_CUST_03, ts->input_dev->keybit); + set_bit(KEY_CUST_04, ts->input_dev->keybit); + set_bit(KEY_CUST_05, ts->input_dev->keybit); + set_bit(KEY_CUST_06, ts->input_dev->keybit); + set_bit(KEY_CUST_07, ts->input_dev->keybit); + set_bit(KEY_CUST_08, ts->input_dev->keybit); + set_bit(KEY_CUST_09, ts->input_dev->keybit); + set_bit(KEY_CUST_10, ts->input_dev->keybit); + set_bit(KEY_CUST_11, ts->input_dev->keybit); + set_bit(KEY_CUST_12, ts->input_dev->keybit); + set_bit(KEY_CUST_13, ts->input_dev->keybit); + set_bit(KEY_CUST_14, ts->input_dev->keybit); + set_bit(KEY_CUST_15, ts->input_dev->keybit); +#endif + set_bit(BTN_TOUCH, ts->input_dev->keybit); + set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit); + +#ifdef HX_PROTOCOL_A + //ts->input_dev->mtsize = ts->nFinger_support; + input_set_abs_params(ts->input_dev, ABS_MT_TRACKING_ID, + 0, 3, 0, 0); +#else + set_bit(MT_TOOL_FINGER, ts->input_dev->keybit); +#if defined(HX_PROTOCOL_B_3PA) + input_mt_init_slots(ts->input_dev, ts->nFinger_support,0); +#else + input_mt_init_slots(ts->input_dev, ts->nFinger_support); +#endif +#endif + + I("input_set_abs_params: mix_x %d, max_x %d, min_y %d, max_y %d\n", + ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); + + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X,ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_x_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y,ts->pdata->abs_y_min, ts->pdata->abs_y_max, ts->pdata->abs_y_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0); +#ifndef HX_PROTOCOL_A + input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE,ts->pdata->abs_pressure_min, ts->pdata->abs_pressure_max, ts->pdata->abs_pressure_fuzz, 0); + input_set_abs_params(ts->input_dev, ABS_MT_WIDTH_MAJOR,ts->pdata->abs_width_min, ts->pdata->abs_width_max, ts->pdata->abs_pressure_fuzz, 0); +#endif +// input_set_abs_params(ts->input_dev, ABS_MT_AMPLITUDE, 0, ((ts->pdata->abs_pressure_max << 16) | ts->pdata->abs_width_max), 0, 0); +// input_set_abs_params(ts->input_dev, ABS_MT_POSITION, 0, (BIT(31) | (ts->pdata->abs_x_max << 16) | ts->pdata->abs_y_max), 0, 0); + + + if(himax_input_register_device(ts->input_dev) == 0) + return NO_ERR; + else + ret = INPUT_REGISTER_FAIL; + +input_device_fail: + I("%s, input device register fail!\n",__func__); + return ret; +} + +static void calcDataSize(uint8_t finger_num) +{ + struct himax_ts_data *ts_data = private_ts; + ts_data->coord_data_size = 4 * finger_num; + ts_data->area_data_size = ((finger_num / 4) + (finger_num % 4 ? 1 : 0)) * 4; + //printk("allenyu : area_data_size = %d \n",ts_data->area_data_size ); + ts_data->coordInfoSize = ts_data->coord_data_size + ts_data->area_data_size + 4; + ts_data->raw_data_frame_size = 128 - ts_data->coord_data_size - ts_data->area_data_size - 4 - 4 - 1; + if(ts_data->raw_data_frame_size == 0) + { + E("%s: could NOT calculate! \n", __func__); + return; + } + ts_data->raw_data_nframes = ((uint32_t)ts_data->x_channel * ts_data->y_channel + + ts_data->x_channel + ts_data->y_channel) / ts_data->raw_data_frame_size + + (((uint32_t)ts_data->x_channel * ts_data->y_channel + + ts_data->x_channel + ts_data->y_channel) % ts_data->raw_data_frame_size)? 1 : 0; + I("%s: coord_data_size: %d, area_data_size:%d, raw_data_frame_size:%d, raw_data_nframes:%d", __func__, ts_data->coord_data_size, ts_data->area_data_size, ts_data->raw_data_frame_size, ts_data->raw_data_nframes); +} + +void calculate_point_number(void) +{ + HX_TOUCH_INFO_POINT_CNT = ic_data->HX_MAX_PT * 4 ; + + if ( (ic_data->HX_MAX_PT % 4) == 0) + HX_TOUCH_INFO_POINT_CNT += (ic_data->HX_MAX_PT / 4) * 4 ; + else + HX_TOUCH_INFO_POINT_CNT += ((ic_data->HX_MAX_PT / 4) +1) * 4 ; +} + +#ifdef HX_AUTO_UPDATE_FW +static int i_update_FW(void) +{ + int upgrade_times = 0; + //unsigned char* ImageBuffer = i_CTPM_FW; + //int fullFileLength = sizeof(i_CTPM_FW); + unsigned char* ImageBuffer = NULL; + int fullFileLength = 0; + uint8_t ret = 0, result = 0; + +if(IC_TYPE == HX_83112A_SERIES_PWON) + { + ImageBuffer = i_CTPM_FW_HX83112A; + fullFileLength = sizeof(i_CTPM_FW_HX83112A); + } + else/*HX_83112B_SERIES_PWON*/ + { + //printk("%s: (%d)No upgrade 2nd source fw\n", __func__, __LINE__); + //return false; + ImageBuffer = i_CTPM_FW_HX83112B; + fullFileLength = sizeof(i_CTPM_FW_HX83112B); + } + I("%s: i_fullFileLength = %d\n", __func__,fullFileLength); + + himax_int_enable(private_ts->client->irq,0); +update_retry: + if(fullFileLength == FW_SIZE_32k) + { + ret = fts_ctpm_fw_upgrade_with_sys_fs_32k(private_ts->client,ImageBuffer,fullFileLength,false); + } + else if(fullFileLength == FW_SIZE_60k) + { + ret = fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,ImageBuffer,fullFileLength,false); + } + else if (fullFileLength == FW_SIZE_64k) + { + ret = fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,ImageBuffer,fullFileLength,false); + } + else if (fullFileLength == FW_SIZE_124k) + { + ret = fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,ImageBuffer,fullFileLength,false); + } + else if (fullFileLength == FW_SIZE_128k) + { + ret = fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,ImageBuffer,fullFileLength,false); + } + if(ret == 0) + { + upgrade_times++; + E("%s: TP upgrade error, upgrade_times = %d\n", __func__, upgrade_times); + if(upgrade_times < 3) + goto update_retry; + else + result = -1;//upgrade fail + } + else + { + ic_data->vendor_fw_ver = g_i_FW_VER; + ic_data->vendor_config_ver = g_i_CFG_VER; + result = 1;//upgrade success + I("%s: TP upgrade OK\n", __func__); + } +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(true,false); +#endif + himax_int_enable(private_ts->client->irq,1); + return result; +} +#endif + +int himax_loadSensorConfig(struct i2c_client *client, struct himax_i2c_platform_data *pdata) +{ + + if (!client) + { + E("%s: Necessary parameters client are null!\n", __func__); + return -1; + } + + I("%s: initialization complete\n", __func__); + + return NO_ERR; +} + +#ifdef HX_ESD_RECOVERY +void himax_esd_hw_reset(void) +{ + I("START_Himax TP: ESD - Reset\n"); +#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) + if (g_self_test_entered == 1) + { + I("In self test ,not TP: ESD - Reset\n"); + return; + } +#endif + HX_ESD_RESET_ACTIVATE = 1; +#if defined(HX_CHIP_STATUS_MONITOR) + g_chip_monitor_data->HX_CHIP_POLLING_COUNT=0; +#endif + himax_esd_ic_reset(); + + I("END_Himax TP: ESD - Reset\n"); +} +#endif + +#ifdef HX_CHIP_STATUS_MONITOR +static void himax_chip_monitor_function(struct work_struct *work) //for ESD solution +{ + int ret=0; + + I(" %s: POLLING_COUNT=%x, STATUS=%x\n", __func__,g_chip_monitor_data->HX_CHIP_POLLING_COUNT,ret); + if(g_chip_monitor_data->HX_CHIP_POLLING_COUNT >= (g_chip_monitor_data->HX_POLLING_TIMES-1))//POLLING TIME + { + g_chip_monitor_data->HX_ON_HAND_SHAKING=1; + ret = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail + g_chip_monitor_data->HX_ON_HAND_SHAKING=0; + if(ret == 2) + { + I(" %s: I2C Fail \n", __func__); + himax_esd_hw_reset(); + } + else if(ret == 1) + { + I(" %s: MCU Stop \n", __func__); + himax_esd_hw_reset(); + } + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0;//clear polling counter + } + else + g_chip_monitor_data->HX_CHIP_POLLING_COUNT++; + + + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; + queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); + + return; +} +#endif + +#ifdef HX_SMART_WAKEUP +#ifdef HX_GESTURE_TRACK +static void gest_pt_log_coordinate(int rx, int tx) +{ + //driver report x y with range 0 - 255 , we scale it up to x/y pixel + gest_pt_x[gest_pt_cnt] = rx*(ic_data->HX_X_RES)/255; + gest_pt_y[gest_pt_cnt] = tx*(ic_data->HX_Y_RES)/255; +} +#endif +static int himax_parse_wake_event(struct himax_ts_data *ts) +{ + uint8_t *buf; +#ifdef HX_GESTURE_TRACK + int tmp_max_x=0x00,tmp_min_x=0xFFFF,tmp_max_y=0x00,tmp_min_y=0xFFFF; + int gest_len; +#endif + int i=0, check_FC = 0, gesture_flag = 0; + + buf = kzalloc(hx_touch_data->event_size*sizeof(uint8_t),GFP_KERNEL); + memcpy(buf,hx_touch_data->hx_event_buf,hx_touch_data->event_size); + + for(i=0; igest_pt_x[i]) + tmp_min_x=gest_pt_x[i]; + if(tmp_max_ygest_pt_y[i]) + tmp_min_y=gest_pt_y[i]; + } + I("gest_point x_min= %d, x_max= %d, y_min= %d, y_max= %d\n",tmp_min_x,tmp_max_x,tmp_min_y,tmp_max_y); + gest_start_x=gest_pt_x[0]; + gn_gesture_coor[0] = gest_start_x; + gest_start_y=gest_pt_y[0]; + gn_gesture_coor[1] = gest_start_y; + gest_end_x=gest_pt_x[gest_pt_cnt-1]; + gn_gesture_coor[2] = gest_end_x; + gest_end_y=gest_pt_y[gest_pt_cnt-1]; + gn_gesture_coor[3] = gest_end_y; + gest_width = tmp_max_x - tmp_min_x; + gn_gesture_coor[4] = gest_width; + gest_height = tmp_max_y - tmp_min_y; + gn_gesture_coor[5] = gest_height; + gest_mid_x = (tmp_max_x + tmp_min_x)/2; + gn_gesture_coor[6] = gest_mid_x; + gest_mid_y = (tmp_max_y + tmp_min_y)/2; + gn_gesture_coor[7] = gest_mid_y; + gn_gesture_coor[8] = gest_mid_x;//gest_up_x + gn_gesture_coor[9] = gest_mid_y-gest_height/2;//gest_up_y + gn_gesture_coor[10] = gest_mid_x;//gest_down_x + gn_gesture_coor[11] = gest_mid_y+gest_height/2; //gest_down_y + gn_gesture_coor[12] = gest_mid_x-gest_width/2; //gest_left_x + gn_gesture_coor[13] = gest_mid_y; //gest_left_y + gn_gesture_coor[14] = gest_mid_x+gest_width/2; //gest_right_x + gn_gesture_coor[15] = gest_mid_y; //gest_right_y + + } + + } +#endif + if(gesture_flag != 0x80) + { + if(!ts->gesture_cust_en[gesture_flag]) + { + I("%s NOT report customer key \n ",__func__); + return 0;//NOT report customer key + } + } + else + { + if(!ts->gesture_cust_en[0]) + { + I("%s NOT report report double click \n",__func__); + return 0;//NOT report power key + } + } + + if(gesture_flag == 0x80) + return EV_GESTURE_PWR; + else + return gesture_flag; +} + +void himax_wake_check_func(void) +{ + int ret_event = 0, KEY_EVENT = 0; + + ret_event = himax_parse_wake_event(private_ts); + switch (ret_event) + { + case EV_GESTURE_PWR: + KEY_EVENT = KEY_POWER; + break; + case EV_GESTURE_01: + KEY_EVENT = KEY_CUST_01; + break; + case EV_GESTURE_02: + KEY_EVENT = KEY_CUST_02; + break; + case EV_GESTURE_03: + KEY_EVENT = KEY_CUST_03; + break; + case EV_GESTURE_04: + KEY_EVENT = KEY_CUST_04; + break; + case EV_GESTURE_05: + KEY_EVENT = KEY_CUST_05; + break; + case EV_GESTURE_06: + KEY_EVENT = KEY_CUST_06; + break; + case EV_GESTURE_07: + KEY_EVENT = KEY_CUST_07; + break; + case EV_GESTURE_08: + KEY_EVENT = KEY_CUST_08; + break; + case EV_GESTURE_09: + KEY_EVENT = KEY_CUST_09; + break; + case EV_GESTURE_10: + KEY_EVENT = KEY_CUST_10; + break; + case EV_GESTURE_11: + KEY_EVENT = KEY_CUST_11; + break; + case EV_GESTURE_12: + KEY_EVENT = KEY_CUST_12; + break; + case EV_GESTURE_13: + KEY_EVENT = KEY_CUST_13; + break; + case EV_GESTURE_14: + KEY_EVENT = KEY_CUST_14; + break; + case EV_GESTURE_15: + KEY_EVENT = KEY_CUST_15; + break; + } + if(ret_event) + { + I(" %s SMART WAKEUP KEY event %x press\n",__func__,KEY_EVENT); + input_report_key(private_ts->input_dev, KEY_EVENT, 1); + input_sync(private_ts->input_dev); + //msleep(100); + I(" %s SMART WAKEUP KEY event %x release\n",__func__,KEY_EVENT); + input_report_key(private_ts->input_dev, KEY_EVENT, 0); + input_sync(private_ts->input_dev); + FAKE_POWER_KEY_SEND=true; +#ifdef HX_GESTURE_TRACK + I("gest_start_x= %d, gest_start_y= %d, gest_end_x= %d, gest_end_y= %d\n",gest_start_x,gest_start_y, + gest_end_x,gest_end_y); + I("gest_width= %d, gest_height= %d, gest_mid_x= %d, gest_mid_y= %d\n",gest_width,gest_height, + gest_mid_x,gest_mid_y); + I("gest_up_x= %d, gest_up_y= %d, gest_down_x= %d, gest_down_y= %d\n",gn_gesture_coor[8],gn_gesture_coor[9], + gn_gesture_coor[10],gn_gesture_coor[11]); + I("gest_left_x= %d, gest_left_y= %d, gest_right_x= %d, gest_right_y= %d\n",gn_gesture_coor[12],gn_gesture_coor[13], + gn_gesture_coor[14],gn_gesture_coor[15]); +#endif + } +} + +#endif + +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) +static void himax_ts_button_func(int tp_key_index,struct himax_ts_data *ts) +{ + uint16_t x_position = 0, y_position = 0; + if ( tp_key_index != 0x00) + { + I("virtual key index =%x\n",tp_key_index); + if ( tp_key_index == 0x01) + { + vk_press = 1; + I("back key pressed\n"); + if (ts->pdata->virtual_key) + { + if (ts->button[0].index) + { + x_position = (ts->button[0].x_range_min + ts->button[0].x_range_max) / 2; + y_position = (ts->button[0].y_range_min + ts->button[0].y_range_max) / 2; + } +#ifdef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); + input_mt_sync(ts->input_dev); +#else + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, + 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); +#endif + } + else + input_report_key(ts->input_dev, KEY_BACK, 1); + } + else if ( tp_key_index == 0x02) + { + vk_press = 1; + I("home key pressed\n"); + if (ts->pdata->virtual_key) + { + if (ts->button[1].index) + { + x_position = (ts->button[1].x_range_min + ts->button[1].x_range_max) / 2; + y_position = (ts->button[1].y_range_min + ts->button[1].y_range_max) / 2; + } +#ifdef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); + input_mt_sync(ts->input_dev); +#else + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, + 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); +#endif + } + else + input_report_key(ts->input_dev, KEY_HOME, 1); + } + else if ( tp_key_index == 0x04) + { + vk_press = 1; + I("APP_switch key pressed\n"); + if (ts->pdata->virtual_key) + { + if (ts->button[2].index) + { + x_position = (ts->button[2].x_range_min + ts->button[2].x_range_max) / 2; + y_position = (ts->button[2].y_range_min + ts->button[2].y_range_max) / 2; + } +#ifdef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, 0); + + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); + input_mt_sync(ts->input_dev); +#else + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, + 1); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, + 100); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, + 100); + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, + x_position); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, + y_position); +#endif + } + else + input_report_key(ts->input_dev, KEY_APP_SWITCH, 1); + } + input_sync(ts->input_dev); + } + else/*tp_key_index =0x00*/ + { + I("virtual key released\n"); + vk_press = 0; +#ifndef HX_PROTOCOL_A + input_mt_slot(ts->input_dev, 0); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); +#else + input_mt_sync(ts->input_dev); +#endif + input_report_key(ts->input_dev, KEY_BACK, 0); + input_report_key(ts->input_dev, KEY_HOME, 0); + input_report_key(ts->input_dev, KEY_APP_SWITCH, 0); +#ifndef HX_PROTOCOL_A + input_sync(ts->input_dev); +#endif + } +} + +void himax_report_key(struct himax_ts_data *ts) +{ + if(hx_point_num!=0) + { + //Touch KEY + if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) + { + //temp_x[0] = 0xFFFF; + //temp_y[0] = 0xFFFF; + //temp_x[1] = 0xFFFF; + //temp_y[1] = 0xFFFF; + hx_touch_data->finger_on = 0; +#ifdef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + himax_ts_button_func(tpd_key,ts); + } +#ifndef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + input_sync(ts->input_dev); + } + else + { + if (tpd_key != 0x00) + { + hx_touch_data->finger_on = 1; +#ifdef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + himax_ts_button_func(tpd_key,ts); + + } + else if ((tpd_key_old != 0x00)&&(tpd_key == 0x00)) + { + hx_touch_data->finger_on = 0; +#ifdef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + himax_ts_button_func(tpd_key,ts); + + } +#ifndef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + input_sync(ts->input_dev); + } + tpd_key_old = tpd_key; + Last_EN_NoiseFilter = EN_NoiseFilter; +} +#endif + +int himax_report_data_init(void) +{ + if(hx_touch_data->hx_coord_buf!=NULL) + { + kfree(hx_touch_data->hx_coord_buf); + } +#ifdef HX_TP_PROC_DIAG + if(hx_touch_data->hx_rawdata_buf!=NULL) + { + kfree(hx_touch_data->hx_rawdata_buf); + } +#endif + +#if defined(HX_SMART_WAKEUP) + hx_touch_data->event_size = himax_get_touch_data_size(); + if(hx_touch_data->hx_event_buf!=NULL) + { + kfree(hx_touch_data->hx_event_buf); + } +#endif + + hx_touch_data->touch_all_size = himax_get_touch_data_size(); + hx_touch_data->raw_cnt_max = ic_data->HX_MAX_PT/4; + hx_touch_data->raw_cnt_rmd = ic_data->HX_MAX_PT%4; + + if (hx_touch_data->raw_cnt_rmd != 0x00) //more than 4 fingers + { + hx_touch_data->rawdata_size = cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max); + hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT+hx_touch_data->raw_cnt_max+2)*4; + } + else //less than 4 fingers + { + hx_touch_data->rawdata_size = cal_data_len(hx_touch_data->raw_cnt_rmd, ic_data->HX_MAX_PT, hx_touch_data->raw_cnt_max); + hx_touch_data->touch_info_size = (ic_data->HX_MAX_PT+hx_touch_data->raw_cnt_max+1)*4; + } + if((ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) % hx_touch_data->rawdata_size == 0) + hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size; + else + hx_touch_data->rawdata_frame_size = (ic_data->HX_TX_NUM * ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + ic_data->HX_RX_NUM) / hx_touch_data->rawdata_size + 1; + I("%s: rawdata_frame_size = %d ",__func__,hx_touch_data->rawdata_frame_size); + I("%s: ic_data->HX_MAX_PT:%d,hx_raw_cnt_max:%d,hx_raw_cnt_rmd:%d,g_hx_rawdata_size:%d,hx_touch_data->touch_info_size:%d\n",__func__,ic_data->HX_MAX_PT,hx_touch_data->raw_cnt_max,hx_touch_data->raw_cnt_rmd,hx_touch_data->rawdata_size,hx_touch_data->touch_info_size); + + hx_touch_data->hx_coord_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->touch_info_size),GFP_KERNEL); + if(hx_touch_data->hx_coord_buf == NULL) + goto mem_alloc_fail; +#ifdef HX_TP_PROC_DIAG + hx_touch_data->hx_rawdata_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->touch_all_size - hx_touch_data->touch_info_size),GFP_KERNEL); + if(hx_touch_data->hx_rawdata_buf == NULL) + goto mem_alloc_fail; +#endif + +#if defined(HX_SMART_WAKEUP) + hx_touch_data->hx_event_buf = kzalloc(sizeof(uint8_t)*(hx_touch_data->event_size),GFP_KERNEL); + if(hx_touch_data->hx_event_buf == NULL) + goto mem_alloc_fail; +#endif + + return NO_ERR; + +mem_alloc_fail: + kfree(hx_touch_data->hx_coord_buf); +#if defined(HX_TP_PROC_DIAG) + kfree(hx_touch_data->hx_rawdata_buf); +#endif +#if defined(HX_SMART_WAKEUP) + kfree(hx_touch_data->hx_event_buf); +#endif + + I("%s: Memory allocate fail!\n",__func__); + return MEM_ALLOC_FAIL; + +} + + +#if defined(HX_USB_DETECT_GLOBAL) +void himax_read_file_func(char *pFilePath, u8 *pBuf, u16 nLength) +{ + struct file *pFile = NULL; + mm_segment_t old_fs; + ssize_t nReadBytes = 0; + + old_fs = get_fs(); + set_fs(get_ds()); + + pFile = filp_open(pFilePath, O_RDONLY, 0); + + if (IS_ERR(pFile)) { + printk ( "[Tracy]Open file failed: %s\n", pFilePath); + return; + } + + pFile->f_op->llseek(pFile, 0, SEEK_SET); + nReadBytes = pFile->f_op->read(pFile, pBuf, nLength, &pFile->f_pos); + + set_fs(old_fs); + + filp_close(pFile, NULL); + +} + +void himax_cable_detect_func(bool force_renew) +{ + struct himax_ts_data *ts; + u32 connect_status = 0; + u8 szChargerStatus[20] = {0}; + + ts = private_ts; + + if (ts->suspended==false) + { + himax_read_file_func(POWER_SUPPLY_BATTERY_STATUS_PATCH, szChargerStatus, 20); + if (strstr(szChargerStatus, "Charging") != NULL || strstr(szChargerStatus, "Full") != NULL || strstr(szChargerStatus, "Fully charged") != NULL) // Charging + { + connect_status=1; + } + else + { + connect_status=0; + } + } + + if (ts->cable_config) + { + if (((!!connect_status) != ts->usb_connected) || force_renew) + { + if (!!connect_status) + { + ts->cable_config[1] = 0x01; + ts->usb_connected = 0x01; + } + else + { + ts->cable_config[1] = 0x00; + ts->usb_connected = 0x00; + } + himax_usb_detect_set(ts->client,ts->cable_config); + printk("%s: Cable status change: 0x%2.2X\n", __func__, ts->usb_connected); + } + } +} +#endif + + +void himax_report_points(struct himax_ts_data *ts) +{ + int x = 0; + int y = 0; + int w = 0; + int base = 0; + int32_t loop_i = 0; + uint16_t old_finger = 0; + + //I("%s:Entering\n",__func__); + + /* finger on/press */ + if (hx_point_num != 0 ) + { + old_finger = ts->pre_finger_mask; + ts->pre_finger_mask = 0; + hx_touch_data->finger_num = hx_touch_data->hx_coord_buf[ts->coordInfoSize - 4] & 0x0F; + hx_touch_data->finger_on = 1; + AA_press = 1; + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) + { + base = loop_i * 4; + x = hx_touch_data->hx_coord_buf[base] << 8 | hx_touch_data->hx_coord_buf[base + 1]; + y = (hx_touch_data->hx_coord_buf[base + 2] << 8 | hx_touch_data->hx_coord_buf[base + 3]); + w = hx_touch_data->hx_coord_buf[(ts->nFinger_support * 4) + loop_i]; + //x = ic_data->HX_X_RES - x; + //y = ic_data->HX_Y_RES - y; + //printk("allenyu:abs_x_max = %d \n",ts->pdata->abs_x_max); + //printk("allenyu:abs_y_max = %d \n",ts->pdata->abs_y_max); + if(x >= 0 && x <= ts->pdata->abs_x_max && y >= 0 && y <= ts->pdata->abs_y_max) + { + //printk("allenyu_010\n"); + hx_touch_data->finger_num--; + if ((ts->debug_log_level & BIT(3)) > 0) + { + himax_log_touch_event_detail(ts,x,y,w,loop_i,EN_NoiseFilter,HX_FINGER_ON,old_finger); + } +#ifndef HX_PROTOCOL_A + + input_mt_slot(ts->input_dev, loop_i); +#endif + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); + input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, loop_i); +#ifndef HX_PROTOCOL_A + input_report_abs(ts->input_dev, ABS_MT_WIDTH_MAJOR, w); + input_report_abs(ts->input_dev, ABS_MT_PRESSURE, w); +#endif + input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x); + input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); + +#ifndef HX_PROTOCOL_A + ts->last_slot = loop_i; + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 1); +#else + input_mt_sync(ts->input_dev); +#endif + + if (!ts->first_pressed) + { + ts->first_pressed = 1; + I("S1@%d, %d\n", x, y); + } + + ts->pre_finger_data[loop_i][0] = x; + ts->pre_finger_data[loop_i][1] = y; + if (ts->debug_log_level & BIT(1)) + himax_log_touch_event(x, y, w,loop_i,EN_NoiseFilter,HX_FINGER_ON); + + ts->pre_finger_mask = ts->pre_finger_mask + (1 << loop_i); + } + /* report coordinates */ + else + { + //printk("allenyu_020\n"); +#ifndef HX_PROTOCOL_A + input_mt_slot(ts->input_dev, loop_i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); +#endif + + if (loop_i == 0 && ts->first_pressed == 1) + { + ts->first_pressed = 2; + I("E1@%d, %d\n", + ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]); + } + if ((ts->debug_log_level & BIT(3)) > 0) + { + himax_log_touch_event_detail(ts,x,y,w,loop_i,Last_EN_NoiseFilter,HX_FINGER_LEAVE,old_finger); + } + } + } +#ifndef HX_PROTOCOL_A + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); +#endif + input_sync(ts->input_dev); + } + + /* finger leave/release */ + else + { +#if defined(HX_PALM_REPORT) + if(himax_palm_detect(hx_touch_data->hx_coord_buf) == NO_ERR) + { + I(" %s HX_PALM_REPORT KEY power event press\n",__func__); + input_report_key(ts->input_dev, KEY_POWER, 1); + input_sync(ts->input_dev); + msleep(100); + I(" %s HX_PALM_REPORT KEY power event release\n",__func__); + input_report_key(ts->input_dev, KEY_POWER, 0); + input_sync(ts->input_dev); + return; + } +#endif + hx_touch_data->finger_on = 0; + AA_press = 0; +#ifdef HX_PROTOCOL_A + input_mt_sync(ts->input_dev); +#endif + + for (loop_i = 0; loop_i < ts->nFinger_support; loop_i++) + { + if (((ts->pre_finger_mask >> loop_i) & 1) == 1) + { +#ifndef HX_PROTOCOL_A + input_mt_slot(ts->input_dev, loop_i); + input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0); +#endif + } + if(ts->pre_finger_mask > 0 && (ts->debug_log_level & BIT(3)) > 0) + { + if (((ts->pre_finger_mask >> loop_i) & 1) == 1) + { + if (ts->useScreenRes) + { + I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS, + ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter); + } + else + { + I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter); + } + } + } + } + if (ts->pre_finger_mask > 0) + { + /*for (loop_i = 0; loop_i < ts->nFinger_support && (ts->debug_log_level & BIT(3)) > 0; loop_i++) + { + if (((ts->pre_finger_mask >> loop_i) & 1) == 1) + { + if (ts->useScreenRes) + { + I("status:%X, Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", 0, loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS, + ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, Last_EN_NoiseFilter); + } + else + { + I("status:%X, Raw:F:%02d Up, X:%d, Y:%d, N:%d\n",0, loop_i+1, ts->pre_finger_data[loop_i][0],ts->pre_finger_data[loop_i][1], Last_EN_NoiseFilter); + } + } + }*/ + ts->pre_finger_mask = 0; + } + + if (ts->first_pressed == 1) + { + ts->first_pressed = 2; + I("E1@%d, %d\n",ts->pre_finger_data[0][0], ts->pre_finger_data[0][1]); + } + + if (ts->debug_log_level & BIT(1)) + himax_log_touch_event(x, y, w,loop_i,EN_NoiseFilter,HX_FINGER_LEAVE); + + input_report_key(ts->input_dev, BTN_TOUCH, hx_touch_data->finger_on); + input_sync(ts->input_dev); + } + Last_EN_NoiseFilter = EN_NoiseFilter; + + //I("%s:End\n",__func__); +} + +int himax_touch_get(struct himax_ts_data *ts,uint8_t *buf,int ts_status) +{ + int ret = 0; + + switch(ts_status) + { + /*normal*/ + case 1: +#ifdef HX_TP_PROC_DIAG + hx_touch_data->diag_cmd = getDiagCommand(); + + if((hx_touch_data->diag_cmd) + || (HX_HW_RESET_ACTIVATE) +#ifdef HX_ESD_RECOVERY + || (HX_ESD_RESET_ACTIVATE) +#endif + ) + { + ret = himax_read_event_stack(ts->client, buf, 128); + } + else + { + ret = himax_read_event_stack(ts->client, buf, hx_touch_data->touch_info_size); + } + + if (!ret) +#else + if(!himax_read_event_stack(ts->client, buf, hx_touch_data->touch_info_size)) +#endif + { + E("%s: can't read data from chip!\n", __func__); + goto err_workqueue_out; + } + break; +#if defined(HX_SMART_WAKEUP) + /*SMWP*/ + case 2: + himax_burst_enable(ts->client, 0); + if(!himax_read_event_stack(ts->client,buf,hx_touch_data->event_size)) + { + E("%s: can't read data from chip!\n", __func__); + goto err_workqueue_out; + } + break; +#endif + default: + break; + } + return NO_ERR; + +err_workqueue_out: + return I2C_FAIL; + +} + +int himax_checksum_cal(struct himax_ts_data *ts,uint8_t *buf,int ts_status) +{ +#if defined(HX_ESD_RECOVERY) + int hx_EB_event = 0; + int hx_EC_event = 0; + int hx_ED_event = 0; + int hx_esd_event = 0; + int hx_zero_event = 0; + int shaking_ret = 0; +#endif + uint16_t check_sum_cal = 0; + int32_t loop_i = 0; + int length = 0; + + /* Normal */ + if(ts_status == HX_REPORT_COORD) + length = hx_touch_data->touch_info_size; +#if defined(HX_SMART_WAKEUP) + /* SMWP */ + else if(ts_status == HX_REPORT_SMWP_EVENT) + length = (GEST_PTLG_ID_LEN+GEST_PTLG_HDR_LEN); +#endif + else + { + I("%s, Neither Normal Nor SMWP error!\n",__func__); + } + //I("Now status=%d,length=%d\n",ts_status,length); + for (loop_i = 0; loop_i < length; loop_i++) + { + check_sum_cal+=buf[loop_i]; + + /*if (ts->debug_log_level & BIT(0)) + { + I("P %d = 0x%2.2X ", loop_i, hx_touch_data->hx_coord_buf[loop_i]); + if (loop_i % 8 == 7) + I("\n"); + }*/ + +#ifdef HX_ESD_RECOVERY + if(ts_status == HX_REPORT_COORD) + { + /* case 1 ESD recovery flow */ + if(buf[loop_i] == 0xEB) + hx_EB_event++; + else if(buf[loop_i] == 0xEC) + hx_EC_event++; + else if(buf[loop_i] == 0xED) + hx_ED_event++; + /* case 2 ESD recovery flow-Disable */ + else if(buf[loop_i] == 0x00) + hx_zero_event++; + else + { + hx_EB_event = 0; + hx_EC_event = 0; + hx_ED_event = 0; + hx_zero_event = 0; + g_zero_event_count = 0; + } + + if(hx_EB_event == length) + { + hx_esd_event = length; + hx_EB_event_flag ++; + I("[HIMAX TP MSG]: ESD event checked - ALL 0xEB.\n"); + } + else if(hx_EC_event == length) + { + hx_esd_event = length; + hx_EC_event_flag ++; + I("[HIMAX TP MSG]: ESD event checked - ALL 0xEC.\n"); + } + else if(hx_ED_event == length) + { + hx_esd_event = length; + hx_ED_event_flag ++; + I("[HIMAX TP MSG]: ESD event checked - ALL 0xED.\n"); + } + else + { + hx_esd_event = 0; + } + } +#endif + } + + if(ts_status == HX_REPORT_COORD) + { +#ifdef HX_ESD_RECOVERY + if ((hx_esd_event == length || hx_zero_event == length) + && (HX_HW_RESET_ACTIVATE == 0) + && (HX_ESD_RESET_ACTIVATE == 0) +#if defined(HX_TP_PROC_DIAG) + && (hx_touch_data->diag_cmd == 0) +#endif +#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) + && (g_self_test_entered == 0) +#endif + ) + { + shaking_ret = himax_ic_esd_recovery(hx_esd_event,hx_zero_event,length); + if(shaking_ret == CHECKSUM_FAIL) + { + himax_esd_hw_reset(); + goto checksum_fail; + } + else if(shaking_ret == ERR_WORK_OUT) + goto err_workqueue_out; + else + { + //I("I2C running. Nothing to be done!\n"); + goto workqueue_out; + } + } + else if (HX_ESD_RESET_ACTIVATE) + { +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +#ifdef HX_RESUME_SEND_CMD +#if 0 + himax_resend_cmd_func(ts->suspended); +#endif + himax_rst_cmd_recovery_func(ts->suspended); +#endif +#endif + /* drop 1st interrupts after chip reset */ + HX_ESD_RESET_ACTIVATE = 0; + I("[HX_ESD_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__); + goto checksum_fail; + } + + else if (HX_HW_RESET_ACTIVATE) +#else + if (HX_HW_RESET_ACTIVATE) +#endif + { +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +#ifdef HX_RESUME_SEND_CMD +#if 0 + himax_resend_cmd_func(ts->suspended); +#endif + himax_rst_cmd_recovery_func(ts->suspended); +#endif +#endif + /* drop 1st interrupts after chip reset */ + HX_HW_RESET_ACTIVATE = 0; + I("[HX_HW_RESET_ACTIVATE]:%s: Back from reset, ready to serve.\n", __func__); + goto ready_to_serve; + } + } + + if ((check_sum_cal % 0x100 != 0) ) + { + I("[HIMAX TP MSG] checksum fail : check_sum_cal: 0x%02X\n", check_sum_cal); + goto checksum_fail; + } + + /* I("%s:End\n",__func__); */ + return NO_ERR; + +ready_to_serve: + return READY_TO_SERVE; +checksum_fail: + return CHECKSUM_FAIL; +#ifdef HX_ESD_RECOVERY +err_workqueue_out: + return ERR_WORK_OUT; +workqueue_out: + return WORK_OUT; +#endif +} + +int himax_ts_work_status(struct himax_ts_data *ts) +{ + /* 1: normal, 2:SMWP */ + int result = HX_REPORT_COORD; + uint8_t diag_cmd = 0; + +#ifdef HX_TP_PROC_DIAG + diag_cmd = getDiagCommand(); +#endif + +#ifdef HX_SMART_WAKEUP + if (atomic_read(&ts->suspend_mode)&&(!FAKE_POWER_KEY_SEND)&&(ts->SMWP_enable)&&(!diag_cmd)) + { + result = HX_REPORT_SMWP_EVENT; + } +#endif + /* I("Now Status is %d\n",result); */ + return result; +} + +void himax_assign_touch_data(uint8_t *buf,int ts_status) +{ + uint8_t hx_state_info_pos = hx_touch_data->touch_info_size - 3; + + if(ts_status == HX_REPORT_COORD) + { + memcpy(hx_touch_data->hx_coord_buf,&buf[0],hx_touch_data->touch_info_size); + if(buf[hx_state_info_pos] != 0xFF && buf[hx_state_info_pos + 1] != 0xFF ) + memcpy(hx_touch_data->hx_state_info,&buf[hx_state_info_pos],2); + else + memset(hx_touch_data->hx_state_info, 0x00, sizeof(hx_touch_data->hx_state_info)); + } +#if defined(HX_SMART_WAKEUP) + else + memcpy(hx_touch_data->hx_event_buf,buf,hx_touch_data->event_size); +#endif + +#ifdef HX_TP_PROC_DIAG + if((hx_touch_data->diag_cmd) + || (HX_HW_RESET_ACTIVATE) +#ifdef HX_ESD_RECOVERY + || (HX_ESD_RESET_ACTIVATE) +#endif + ) + { + memcpy(hx_touch_data->hx_rawdata_buf,&buf[hx_touch_data->touch_info_size],hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); + } +#endif + +} + +void himax_coord_report(struct himax_ts_data *ts) +{ + +#if defined(HX_TP_PROC_DIAG) + //touch monitor raw data fetch + if(himax_set_diag_cmd(ic_data,hx_touch_data)) + I("%s: coordinate dump fail and bypass with checksum err\n",__func__); +#endif + EN_NoiseFilter = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT+2]>>3); + //I("EN_NoiseFilter=%d\n",EN_NoiseFilter); + EN_NoiseFilter = EN_NoiseFilter & 0x01; + //I("EN_NoiseFilter2=%d\n",EN_NoiseFilter); + +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) + tpd_key = (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT+2]>>4); + /* All (VK+AA)leave */ + if (tpd_key == 0x0F) + { + tpd_key = 0x00; + } + //I("[DEBUG] tpd_key: %x\r\n", tpd_key); +#else + tpd_key = 0x00; +#endif + + p_point_num = hx_point_num; + + if (hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] == 0xff) + hx_point_num = 0; + else + hx_point_num= hx_touch_data->hx_coord_buf[HX_TOUCH_INFO_POINT_CNT] & 0x0f; + + /* Touch Point information */ + if(!tpd_key && !tpd_key_old) + himax_report_points(ts); +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) + else + himax_report_key(ts); +#endif + /* I("%s:END\n",__func__); */ + +} + +void himax_ts_work(struct himax_ts_data *ts) +{ + uint8_t hw_reset_check[2]; + uint8_t buf[128]; + int check_sum_cal = 0; + //int loop_i = 0; + int ts_status = 0; +#ifdef HX_CHIP_STATUS_MONITOR + int j=0; +#endif + +#if defined(HX_USB_DETECT_GLOBAL) + himax_cable_detect_func(false); +#endif + +#if defined(HX_CHIP_STATUS_MONITOR) + g_chip_monitor_data->HX_CHIP_POLLING_COUNT=0; + if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking + { + for(j=0; j<100; j++) + { + if(g_chip_monitor_data->HX_ON_HAND_SHAKING==0)//chip on hand shaking end + { + I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,j); + break; + } + else + msleep(1); + } + if(j==100) + { + E("%s:HX_ON_HAND_SHAKING timeout reject interrupt\n",__func__); + return; + } + } +#endif + + ts_status = himax_ts_work_status(ts); + if(ts_status > HX_REPORT_SMWP_EVENT || ts_status < HX_REPORT_COORD) + goto neither_normal_nor_smwp; + + memset(buf, 0x00, sizeof(buf)); + memset(hw_reset_check, 0x00, sizeof(hw_reset_check)); + + //I("New Method for ts_work\n"); + + if(himax_touch_get(ts,buf,ts_status)) + goto err_workqueue_out; + + if (ts->debug_log_level & BIT(0)) + { + + himax_log_touch_data(buf,hx_touch_data); + + } + + check_sum_cal = himax_checksum_cal(ts,buf,ts_status); + if (check_sum_cal == CHECKSUM_FAIL) + goto checksum_fail; + else if (check_sum_cal == READY_TO_SERVE) + goto ready_to_serve; + else if (check_sum_cal == ERR_WORK_OUT) + goto err_workqueue_out; + else if (check_sum_cal == WORK_OUT) + goto workqueue_out; + /* checksum calculate pass and assign data to global touch data*/ + else + himax_assign_touch_data(buf,ts_status); + + if(ts_status == HX_REPORT_COORD) + himax_coord_report(ts); +#if defined(HX_SMART_WAKEUP) + else + { + //wake_lock_timeout(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT); + __pm_wakeup_event(&ts->ts_SMWP_wake_lock, TS_WAKE_LOCK_TIMEOUT); + msleep(200); + himax_wake_check_func(); + } +#endif + +checksum_fail: +workqueue_out: +ready_to_serve: +neither_normal_nor_smwp: + return; + +err_workqueue_out: + I("%s: Now reset the Touch chip.\n", __func__); + +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,true); +#endif + + goto workqueue_out; +} +enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer) +{ + struct himax_ts_data *ts; + + ts = container_of(timer, struct himax_ts_data, timer); + queue_work(ts->himax_wq, &ts->work); + hrtimer_start(&ts->timer, ktime_set(0, 12500000), HRTIMER_MODE_REL); + return HRTIMER_NORESTART; +} + +#if defined( HX_USB_DETECT_CALLBACK) +static void himax_cable_tp_status_handler_func(int connect_status) +{ + struct himax_ts_data *ts; + I("Touch: cable change to %d\n", connect_status); + ts = private_ts; + if (ts->cable_config) + { + if (!atomic_read(&ts->suspend_mode)) + { + if ((!!connect_status) != ts->usb_connected) + { + if (!!connect_status) + { + ts->cable_config[1] = 0x01; + ts->usb_connected = 0x01; + } + else + { + ts->cable_config[1] = 0x00; + ts->usb_connected = 0x00; + } + + i2c_himax_master_write(ts->client, ts->cable_config, + sizeof(ts->cable_config), DEFAULT_RETRY_CNT); + + I("%s: Cable status change: 0x%2.2X\n", __func__, ts->cable_config[1]); + } + else + I("%s: Cable status is the same as previous one, ignore.\n", __func__); + } + else + { + if (connect_status) + ts->usb_connected = 0x01; + else + ts->usb_connected = 0x00; + I("%s: Cable status remembered: 0x%2.2X\n", __func__, ts->usb_connected); + } + } +} + +static struct t_cable_status_notifier himax_cable_status_handler = +{ + .name = "usb_tp_connected", + .func = himax_cable_tp_status_handler_func, +}; + +#endif + +#ifdef HX_AUTO_UPDATE_FW +static void himax_update_register(struct work_struct *work) +{ + I(" %s in", __func__); +#if defined(HX_CHIP_STATUS_MONITOR) + I("Cancel Chip monitor during auto-updating!\n"); + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; + cancel_delayed_work_sync(&private_ts->himax_chip_monitor); +#endif + if(i_update_FW() == false) + I("NOT Have new FW=NOT UPDATE=\n"); + else + I("Have new FW=UPDATE=\n"); +#ifdef HX_CHIP_STATUS_MONITOR + I("Auto-updating over, now chip monitor working!\n"); + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; + queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); +#endif +} +#endif + +#ifdef CONFIG_FB +static void himax_fb_register(struct work_struct *work) +{ + int ret = 0; + struct himax_ts_data *ts = container_of(work, struct himax_ts_data, + work_att.work); + I(" %s in\n", __func__); + + ts->fb_notif.notifier_call = fb_notifier_callback; +//ParisKuong modified Mutex initialization +++ + mutex_init(&ts->ops_lock); +//ParisKuong modified Mutex initialization --- + ret = fb_register_client(&ts->fb_notif); + if (ret) + E(" Unable to register fb_notifier: %d\n", ret); +} +#endif + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) +static void himax_ito_test_work(struct work_struct *work) +{ + I(" %s in\n", __func__); + himax_ito_test(); +} +#endif + +#ifdef HX_TP_PROC_FLASH_DUMP +static void himax_ts_flash_work_func(struct work_struct *work) +{ + himax_ts_flash_func(); +} +#endif +#ifdef HX_TP_PROC_GUEST_INFO +static void himax_ts_guest_info_work_func(struct work_struct *work) +{ + + himax_read_project_id(); + +} +#endif +#ifdef HX_TP_PROC_DIAG +static void himax_ts_diag_work_func(struct work_struct *work) +{ + himax_ts_diag_func(); +} +#endif + +static void himax_release_all_finger(void) +{ + struct input_dev *input_dev = private_ts->input_dev; + u32 finger_count = 0; + + + I("%s: enter \n", __func__); + mutex_lock(&private_ts->report_mutex); + for (finger_count = 0; finger_count < private_ts->nFinger_support; finger_count++) { + input_mt_slot(input_dev, finger_count); + input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0); + } + input_report_key(input_dev, BTN_TOUCH, 0); + input_sync(input_dev); + mutex_unlock(&private_ts->report_mutex); + I("%s: exit \n", __func__); +} + +int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + int ret = 0, err = 0; + bool auto_update_flag = false; + struct himax_ts_data *ts; + struct himax_i2c_platform_data *pdata; + + printk("himax probe enter \n"); + + //Check I2C functionality + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + { + E("%s: i2c check functionality error\n", __func__); + err = -ENODEV; + goto err_check_functionality_failed; + } + + ts = kzalloc(sizeof(struct himax_ts_data), GFP_KERNEL); + if (ts == NULL) + { + E("%s: allocate himax_ts_data failed\n", __func__); + err = -ENOMEM; + goto err_alloc_data_failed; + } + + i2c_set_clientdata(client, ts); + ts->client = client; + ts->dev = &client->dev; + mutex_init(&ts->rw_lock); + + pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); + if (pdata == NULL) /*Allocate Platform data space*/ + { + err = -ENOMEM; + goto err_dt_platform_data_fail; + } + + ic_data = kzalloc(sizeof(*ic_data), GFP_KERNEL); + if (ic_data == NULL) /*Allocate IC data space*/ + { + err = -ENOMEM; + goto err_dt_ic_data_fail; + } + + /* allocate report data */ + hx_touch_data = kzalloc(sizeof(struct himax_report_data),GFP_KERNEL); + if(hx_touch_data == NULL) + { + err = -ENOMEM; + goto err_alloc_data_failed; + } + + if (himax_parse_dt(ts, pdata) < 0) + { + I(" pdata is NULL for DT\n"); + goto err_alloc_dt_pdata_failed; + } + +#ifdef HX_RST_PIN_FUNC + ts->rst_gpio = pdata->gpio_reset; +#endif + + himax_gpio_power_config(ts->client, pdata); + +#ifndef CONFIG_OF + if (pdata->power) + { + ret = pdata->power(1); + if (ret < 0) + { + E("%s: power on failed\n", __func__); + goto err_power_failed; + } + } +#endif + private_ts = ts; + + if (himax_ic_package_check(ts->client) == false) + { + E("Himax chip doesn NOT EXIST"); + goto err_ic_package_failed; + } + + if (pdata->virtual_key) + ts->button = pdata->virtual_key; +#ifdef HX_TP_PROC_FLASH_DUMP + ts->flash_wq = create_singlethread_workqueue("himax_flash_wq"); + if (!ts->flash_wq) + { + E("%s: create flash workqueue failed\n", __func__); + err = -ENOMEM; + goto err_create_wq_failed; + } + + INIT_WORK(&ts->flash_work, himax_ts_flash_work_func); + + setSysOperation(0); + setFlashBuffer(); +#endif +#ifdef HX_TP_PROC_GUEST_INFO + ts->guest_info_wq = create_singlethread_workqueue("himax_guest_info_wq"); + if (!ts->guest_info_wq) + { + E("%s: create guest info workqueue failed\n", __func__); + err = -ENOMEM; + goto err_create_guest_info_wq_failed; + } + INIT_WORK(&ts->guest_info_work, himax_ts_guest_info_work_func); +#endif +#ifdef HX_TP_PROC_DIAG + ts->himax_diag_wq = create_singlethread_workqueue("himax_diag"); + if (!ts->himax_diag_wq) + { + E("%s: create diag workqueue failed\n", __func__); + err = -ENOMEM; + goto err_create_wq_failed; + } + INIT_DELAYED_WORK(&ts->himax_diag_delay_wrok, himax_ts_diag_work_func); +#endif + + himax_read_FW_ver(client); + auto_update_flag = !himax_calculateChecksum(client, false); +#ifdef HX_AUTO_UPDATE_FW +#if 0 + auto_update_flag |= (( ic_data->vendor_fw_ver < g_i_FW_VER ) || ( ic_data->vendor_config_ver < g_i_CFG_VER )); + /* Not sure to do */ + auto_update_flag |= ((ic_data->vendor_cid_maj_ver != g_i_CID_MAJ) || (ic_data->vendor_cid_min_ver < g_i_CID_MIN)); + auto_update_flag |= (( ic_data->vendor_touch_cfg_ver < ((g_i_CFG_VER >> 8)&0xff) ) || ( ic_data->vendor_display_cfg_ver < ((g_i_CFG_VER)&0xff) )); +#endif + +/*wrong FW in IC cases need to force FW upgrade*/ + if (IC_TYPE == HX_83112A_SERIES_PWON) + { + if (ic_data->vendor_hx_ic_id == 0x51) + { + if (( ic_data->vendor_touch_cfg_ver < ((g_i_CFG_VER >> 8)&0xff) ) || ( ic_data->vendor_display_cfg_ver < ((g_i_CFG_VER)&0xff) )) + { + auto_update_flag |= true; + } + else + { + auto_update_flag |= false; + } + } + else + { + auto_update_flag |= true; + } + } + else if (IC_TYPE == HX_83112B_SERIES_PWON) + { + if (ic_data->vendor_hx_ic_id == 0x52) + { + if (( ic_data->vendor_touch_cfg_ver < ((g_i_CFG_VER >> 8)&0xff) ) || ( ic_data->vendor_display_cfg_ver < ((g_i_CFG_VER)&0xff) )) + { + auto_update_flag |= true; + } + else + { + auto_update_flag |= false; + } + } + else + { + auto_update_flag |= true; + } + } + if (auto_update_flag) + { + ts->himax_update_wq = create_singlethread_workqueue("HMX_update_reuqest"); + if (!ts->himax_update_wq) + { + E(" allocate syn_update_wq failed\n"); + err = -ENOMEM; + goto err_update_wq_failed; + } + INIT_DELAYED_WORK(&ts->work_update, himax_update_register); + queue_delayed_work(ts->himax_update_wq, &ts->work_update, msecs_to_jiffies(2000)); + } +#endif + +#ifdef HX_ZERO_FLASH + ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_0f_update_reuqest"); + INIT_DELAYED_WORK(&ts->work_0f_update, himax_0f_operation); + queue_delayed_work(ts->himax_0f_update_wq, &ts->work_0f_update, msecs_to_jiffies(2000)); +#endif + //Himax Power On and Load Config + if (himax_loadSensorConfig(client, pdata)) + { + E("%s: Load Sesnsor configuration failed, unload driver.\n", __func__); + goto err_detect_failed; + } + himax_power_on_init(client); + + calculate_point_number(); +#ifdef HX_TP_PROC_DIAG + setXChannel(ic_data->HX_RX_NUM); // X channel + setYChannel(ic_data->HX_TX_NUM); // Y channel + + setMutualBuffer(); + setMutualNewBuffer(); + setMutualOldBuffer(); + if (getMutualBuffer() == NULL) + { + E("%s: mutual buffer allocate fail failed\n", __func__); + return -1; + } +#ifdef HX_TP_PROC_2T2R + if(Is_2T2R) + { + setXChannel_2(ic_data->HX_RX_NUM_2); // X channel + setYChannel_2(ic_data->HX_TX_NUM_2); // Y channel + + setMutualBuffer_2(); + + if (getMutualBuffer_2() == NULL) + { + E("%s: mutual buffer 2 allocate fail failed\n", __func__); + return -1; + } + } +#endif +#endif +#ifdef CONFIG_OF + ts->power = pdata->power; +#endif + ts->pdata = pdata; + + ts->x_channel = ic_data->HX_RX_NUM; + ts->y_channel = ic_data->HX_TX_NUM; + ts->nFinger_support = ic_data->HX_MAX_PT; + //calculate the i2c data size + calcDataSize(ts->nFinger_support); + I("%s: calcDataSize complete\n", __func__); +#ifdef CONFIG_OF + ts->pdata->abs_pressure_min = 0; + ts->pdata->abs_pressure_max = 200; + ts->pdata->abs_width_min = 0; + ts->pdata->abs_width_max = 200; + pdata->cable_config[0] = 0xF0; + pdata->cable_config[1] = 0x00; +#endif + ts->suspended = false; +#if defined( HX_USB_DETECT_CALLBACK)||defined(HX_USB_DETECT_GLOBAL) + ts->usb_connected = 0x00; + ts->cable_config = pdata->cable_config; +#endif +#ifdef HX_PROTOCOL_A + ts->protocol_type = PROTOCOL_TYPE_A; +#else + ts->protocol_type = PROTOCOL_TYPE_B; +#endif + I("%s: Use Protocol Type %c\n", __func__, + ts->protocol_type == PROTOCOL_TYPE_A ? 'A' : 'B'); + + ret = himax_input_register(ts); + if (ret) + { + E("%s: Unable to register %s input device\n", + __func__, ts->input_dev->name); + goto err_input_register_device_failed; + } +#ifdef CONFIG_FB + ts->himax_att_wq = create_singlethread_workqueue("HMX_ATT_reuqest"); + if (!ts->himax_att_wq) + { + E(" allocate syn_att_wq failed\n"); + err = -ENOMEM; + goto err_get_intr_bit_failed; + } + INIT_DELAYED_WORK(&ts->work_att, himax_fb_register); + queue_delayed_work(ts->himax_att_wq, &ts->work_att, msecs_to_jiffies(15000)); +#endif + + mutex_init(&ts->report_mutex); + +#if defined(HX_CHIP_STATUS_MONITOR)//for ESD solution + I("Enter HX_CHIP_STATUS_MONITOR! \n"); + + g_chip_monitor_data = kzalloc(sizeof(struct chip_monitor_data),GFP_KERNEL); + if(g_chip_monitor_data == NULL) + { + err = -ENOMEM; + goto err_alloc_monitor_data; + } + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_POLLING_TIMER = 5;//unit:sec + g_chip_monitor_data->HX_POLLING_TIMES = 2;//ex:5(timer)x2(times)=10sec(polling time) + g_chip_monitor_data->HX_ON_HAND_SHAKING = 0;// + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; + + ts->himax_chip_monitor_wq = create_singlethread_workqueue("himax_chip_monitor_wq"); + if (!ts->himax_chip_monitor_wq) + { + E(" %s: create workqueue failed\n", __func__); + err = -ENOMEM; + goto err_create_chip_monitor_wq_failed; + } + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; + + INIT_DELAYED_WORK(&ts->himax_chip_monitor, himax_chip_monitor_function); + + queue_delayed_work(ts->himax_chip_monitor_wq, &ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); + +#endif + +#ifdef HX_SMART_WAKEUP + ts->SMWP_enable=0; + //wake_lock_init(&ts->ts_SMWP_wake_lock, WAKE_LOCK_SUSPEND, HIMAX_common_NAME); + wakeup_source_init(&ts->ts_SMWP_wake_lock, HIMAX_common_NAME); +#endif +#ifdef HX_HIGH_SENSE + ts->HSEN_enable=0; +#endif + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) + ts->ito_test_wq = create_singlethread_workqueue("himax_ito_test_wq"); + if (!ts->ito_test_wq) + { + E("%s: ito test workqueue failed\n", __func__); + err = -ENOMEM; + goto err_ito_test_wq_failed; + } + + INIT_WORK(&ts->ito_test_work, himax_ito_test_work); +#endif + + //touch data init + err=himax_report_data_init(); + if(err) + goto err_report_data_init_failed; + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) + himax_touch_proc_init(); +#endif + +#if defined( HX_USB_DETECT_CALLBACK) + if (ts->cable_config) + cable_detect_register_notifier(&himax_cable_status_handler); +#endif + + err = himax_ts_register_interrupt(ts->client); + if (err) + goto err_register_interrupt_failed; + +#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH) + if (auto_update_flag) + { + himax_int_enable(client->irq,0); + } +#endif + + return 0; + +err_register_interrupt_failed: +err_report_data_init_failed: + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) +err_ito_test_wq_failed: +#endif +#ifdef HX_SMART_WAKEUP + //wake_lock_destroy(&ts->ts_SMWP_wake_lock); + wakeup_source_trash(&ts->ts_SMWP_wake_lock); +#endif +#ifdef HX_CHIP_STATUS_MONITOR + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; + cancel_delayed_work_sync(&ts->himax_chip_monitor); + destroy_workqueue(ts->himax_chip_monitor_wq); +err_create_chip_monitor_wq_failed: +err_alloc_monitor_data: + kfree(g_chip_monitor_data); +#endif +#ifdef CONFIG_FB +err_get_intr_bit_failed: +#endif +err_input_register_device_failed: + input_free_device(ts->input_dev); +err_detect_failed: +#ifdef HX_AUTO_UPDATE_FW +err_update_wq_failed: +#endif +#ifdef HX_TP_PROC_GUEST_INFO +err_create_guest_info_wq_failed: +#endif +#ifdef HX_TP_PROC_FLASH_DUMP +err_create_wq_failed: +#endif +err_ic_package_failed: + + if (gpio_is_valid(pdata->gpio_irq)) + gpio_free(pdata->gpio_irq); +#ifdef HX_RST_PIN_FUNC + if (gpio_is_valid(pdata->gpio_reset)) + gpio_free(pdata->gpio_reset); +#endif + +err_alloc_dt_pdata_failed: +#ifndef CONFIG_OF +err_power_failed: +#endif + + kfree(ic_data); + +err_dt_ic_data_fail: + kfree(pdata); + +err_dt_platform_data_fail: + kfree(ts); + +err_alloc_data_failed: + kfree(hx_touch_data); + +err_check_functionality_failed: + probe_fail_flag = 1; + return err; + +} + +int himax_chip_common_remove(struct i2c_client *client) +{ + struct himax_ts_data *ts = i2c_get_clientdata(client); +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) + himax_touch_proc_deinit(); +#endif +#ifdef HX_CHIP_STATUS_MONITOR + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; + cancel_delayed_work_sync(&ts->himax_chip_monitor); + destroy_workqueue(ts->himax_chip_monitor_wq); + kfree(g_chip_monitor_data); +#endif +#ifdef CONFIG_FB + if (fb_unregister_client(&ts->fb_notif)) + dev_err(&client->dev, "Error occurred while unregistering fb_notifier.\n"); +#endif + + if (!ts->use_irq) + hrtimer_cancel(&ts->timer); + + destroy_workqueue(ts->himax_wq); + +#ifndef HX_PROTOCOL_A + input_mt_destroy_slots(ts->input_dev); +#endif + + input_unregister_device(ts->input_dev); + +#ifdef HX_SMART_WAKEUP + //wake_lock_destroy(&ts->ts_SMWP_wake_lock); + wakeup_source_trash(&ts->ts_SMWP_wake_lock); +#endif + kfree(ts); + + return 0; + +} + +int himax_chip_common_suspend(struct himax_ts_data *ts) +{ + int ret; +#ifdef HX_CHIP_STATUS_MONITOR + int t = 0; +#endif + + if(ts->suspended) + { + I("%s: Already suspended. Skipped. \n", __func__); + return 0; + } + else + { + ts->suspended = true; + I("%s: enter \n", __func__); + } + +#ifdef HX_TP_PROC_FLASH_DUMP + if (getFlashDumpGoing()) + { + I("[himax] %s: Flash dump is going, reject suspend\n",__func__); + return 0; + } +#endif +#ifdef HX_TP_PROC_GUEST_INFO + if (himax_guest_info_get_status()) + { + I("[himax] %s: GUEST INFO dump is going, reject suspend\n",__func__); + return 0; + } +#endif +#ifdef HX_CHIP_STATUS_MONITOR + if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking + { + for(t=0; t<100; t++) + { + if(g_chip_monitor_data->HX_ON_HAND_SHAKING==0)//chip on hand shaking end + { + I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,t); + break; + } + else + msleep(1); + } + if(t==100) + { + E("%s:HX_ON_HAND_SHAKING timeout reject suspend\n",__func__); + return 0; + } + } + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + cancel_delayed_work_sync(&ts->himax_chip_monitor); +#endif + +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +#ifndef HX_RESUME_SEND_CMD + himax_resend_cmd_func(ts->suspended); +#endif +#endif + +#ifdef HX_SMART_WAKEUP + if(ts->SMWP_enable) + { + atomic_set(&ts->suspend_mode, 1); + ts->pre_finger_mask = 0; + FAKE_POWER_KEY_SEND=false; + I("[himax] %s: SMART_WAKEUP enable, reject suspend\n",__func__); + return 0; + } +#endif + + himax_int_enable(ts->client->irq,0); +#ifdef HX_RST_PIN_FUNC + reset_flag = 0; +#endif + himax_suspend_ic_action(ts->client); + + if (!ts->use_irq) + { + ret = cancel_work_sync(&ts->work); + if (ret) + himax_int_enable(ts->client->irq,1); + } + + //ts->first_pressed = 0; + atomic_set(&ts->suspend_mode, 1); + ts->pre_finger_mask = 0; + if (ts->pdata->powerOff3V3 && ts->pdata->power) + ts->pdata->power(0); + I("%s: END \n", __func__); + return 0; +} + +int himax_chip_common_resume(struct himax_ts_data *ts) +{ + +#ifdef HX_CHIP_STATUS_MONITOR + int t=0; +#endif + + I("%s: enter \n", __func__); + if(ts->suspended == false) + { + I("%s: It had entered resume,skip this step \n", __func__); + return 0; + } + else + ts->suspended = false; + + atomic_set(&ts->suspend_mode, 0); + + himax_release_all_finger(); + + if (ts->pdata->powerOff3V3 && ts->pdata->power) + ts->pdata->power(1); + +#ifdef HX_CHIP_STATUS_MONITOR + if(g_chip_monitor_data->HX_ON_HAND_SHAKING)//chip on hand shaking,wait hand shaking + { + for(t=0; t<100; t++) + { + if(g_chip_monitor_data->HX_ON_HAND_SHAKING == 0)//chip on hand shaking end + { + I("%s:HX_ON_HAND_SHAKING OK check %d times\n",__func__,t); + break; + } + else + msleep(1); + } + if(t==100) + { + E("%s:HX_ON_HAND_SHAKING timeout reject resume\n",__func__); + return 0; + } + } +#endif + +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +#if defined(HX_RESUME_SEND_CMD) + himax_resend_cmd_func(ts->suspended); +#endif +#elif defined(HX_RESUME_HW_RESET) + himax_ic_reset(false,false); +#endif + + himax_resume_ic_action(ts->client); + + himax_int_enable(ts->client->irq,1); +#ifdef HX_RST_PIN_FUNC + reset_flag = 1; +#endif +#ifdef HX_CHIP_STATUS_MONITOR + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; + queue_delayed_work(ts->himax_chip_monitor_wq, &ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMER*HZ); //for ESD solution +#endif + I("%s: END \n", __func__); + return 0; +} + diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_common.h b/drivers/input/touchscreen/hxchipset83112b/himax_common.h new file mode 100755 index 000000000000..5e12bc9d4f58 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.h @@ -0,0 +1,440 @@ +/* Himax Android Driver Sample Code for common functions +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 HIMAX_COMMON_H +#define HIMAX_COMMON_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include "himax_platform.h" +#include +#if defined(CONFIG_FB) +#include +#include +#include +#elif defined(CONFIG_HAS_EARLYSUSPEND) +#include +#endif + +#ifdef CONFIG_OF +#include +#endif +//#define HIMAX_DRIVER_VER "0.1.95.0_ABCD1234_01" +#define HIMAX_DRIVER_VER "1.2.2.69_ABCD1234_01" + +#define FLASH_DUMP_FILE "/sdcard/HX_Flash_Dump.bin" + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) + +#define HX_TP_PROC_DIAG +#define HX_TP_PROC_REGISTER +#define HX_TP_PROC_DEBUG +#define HX_TP_PROC_FLASH_DUMP +#define HX_TP_PROC_SELF_TEST +#define HX_TP_PROC_RESET +#define HX_TP_PROC_SENSE_ON_OFF +#define HX_TP_PROC_2T2R + +#ifdef HX_TP_PROC_SELF_TEST +//#define HX_TP_SELF_TEST_DRIVER //if enable, selftest works in driver +#endif + +int himax_touch_proc_init(void); +void himax_touch_proc_deinit(void); +#endif +//===========Himax Option function============= +#define HX_RST_PIN_FUNC +#define HX_AUTO_UPDATE_FW +//#define HX_ESD_RECOVERY +//#define HX_CHIP_STATUS_MONITOR /*for ESD 2nd solution,it does not support incell,default off*/ +//#define HX_SMART_WAKEUP +//#define HX_GESTURE_TRACK +//#define HX_HIGH_SENSE +//#define HX_PALM_REPORT +#define HX_USB_DETECT_GLOBAL +//#define HX_USB_DETECT_CALLBACK +//#define HX_PROTOCOL_A /* for MTK special platform.If turning on,it will report to system by using specific format. */ +//#define HX_RESUME_HW_RESET +//#define HX_RESUME_SEND_CMD +#define HX_PROTOCOL_B_3PA +#define HX_FIX_TOUCH_INFO /* if open, you need to change the touch info in the fix_touch_info*/ +//#define HX_EN_SEL_BUTTON /* Support Self Virtual key ,default is close*/ +//#define HX_EN_MUT_BUTTON /* Support Mutual Virtual Key ,default is close*/ + +#if defined(HX_EN_SEL_BUTTON) || defined(HX_EN_MUT_BUTTON) +//#define HX_PLATFOME_DEFINE_KEY /* for specfic platform to set key(button) */ +#endif + +#ifdef HX_USB_DETECT_GLOBAL +#define POWER_SUPPLY_BATTERY_STATUS_PATCH "/sys/class/power_supply/battery/status" +#endif + +#define HX_KEY_MAX_COUNT 4 +#define DEFAULT_RETRY_CNT 3 + +#define HX_85XX_A_SERIES_PWON 1 +#define HX_85XX_B_SERIES_PWON 2 +#define HX_85XX_C_SERIES_PWON 3 +#define HX_85XX_D_SERIES_PWON 4 +#define HX_85XX_E_SERIES_PWON 5 +#define HX_85XX_ES_SERIES_PWON 6 +#define HX_85XX_F_SERIES_PWON 7 +#define HX_85XX_G_SERIES_PWON 8 +#define HX_85XX_H_SERIES_PWON 9 +#define HX_83100A_SERIES_PWON 10 +#define HX_83102A_SERIES_PWON 11 +#define HX_83102B_SERIES_PWON 12 +#define HX_83110A_SERIES_PWON 13 +#define HX_83110B_SERIES_PWON 14 +#define HX_83111B_SERIES_PWON 15 +#define HX_83112A_SERIES_PWON 16 +#define HX_83112B_SERIES_PWON 17 + +#define HX_TP_BIN_CHECKSUM_SW 1 +#define HX_TP_BIN_CHECKSUM_HW 2 +#define HX_TP_BIN_CHECKSUM_CRC 3 + +#define SHIFTBITS 5 + +#define FW_SIZE_32k 32768 +#define FW_SIZE_60k 61440 +#define FW_SIZE_64k 65536 +#define FW_SIZE_124k 126976 +#define FW_SIZE_128k 131072 + +#define NO_ERR 0 +#define READY_TO_SERVE 1 +#define WORK_OUT 2 +#define I2C_FAIL -1 +#define MEM_ALLOC_FAIL -2 +#define CHECKSUM_FAIL -3 +#define GESTURE_DETECT_FAIL -4 +#define INPUT_REGISTER_FAIL -5 +#define FW_NOT_READY -6 +#define LENGTH_FAIL -7 +#define OPEN_FILE_FAIL -8 +#define ERR_WORK_OUT -10 + +#define HX_FINGER_ON 1 +#define HX_FINGER_LEAVE 2 + +#define HX_REPORT_COORD 1 +#define HX_REPORT_SMWP_EVENT 2 +#ifdef HX_FIX_TOUCH_INFO +enum fix_touch_info +{ + FIX_HX_RX_NUM = 30, + FIX_HX_TX_NUM = 18, + FIX_HX_BT_NUM = 0, + FIX_HX_X_RES = 1080, + FIX_HX_Y_RES = 2160, + FIX_HX_MAX_PT = 10, + FIX_HX_XY_REVERSE = true, + FIX_HX_INT_IS_EDGE = false, +#ifdef HX_TP_PROC_2T2R + FIX_HX_RX_NUM_2 = 0, + FIX_HX_TX_NUM_2 = 0, +#endif + SEC_FIX_HX_RX_NUM = 36, + SEC_FIX_HX_TX_NUM = 18, + SEC_FIX_HX_BT_NUM = 0, + SEC_FIX_HX_X_RES = 1080, + SEC_FIX_HX_Y_RES = 2160, + SEC_FIX_HX_MAX_PT = 10, + SEC_FIX_HX_XY_REVERSE = true, + SEC_FIX_HX_INT_IS_EDGE = false, +#ifdef HX_TP_PROC_2T2R + SEC_FIX_HX_RX_NUM_2 = 0, + SEC_FIX_HX_TX_NUM_2 = 0 +#endif +}; +#endif +#ifdef HX_ZERO_FLASH +#define HX_0F_DEBUG +#endif + +struct himax_ic_data +{ + int vendor_fw_ver; + int vendor_config_ver; + int vendor_touch_cfg_ver; + int vendor_display_cfg_ver; + int vendor_cid_maj_ver; + int vendor_cid_min_ver; + int vendor_panel_ver; + int vendor_sensor_id; + int vendor_hx_ic_id; + int HX_RX_NUM; + int HX_TX_NUM; + int HX_BT_NUM; + int HX_X_RES; + int HX_Y_RES; + int HX_MAX_PT; + bool HX_XY_REVERSE; + bool HX_INT_IS_EDGE; +#ifdef HX_TP_PROC_2T2R + int HX_RX_NUM_2; + int HX_TX_NUM_2; +#endif +}; + +struct himax_virtual_key +{ + int index; + int keycode; + int x_range_min; + int x_range_max; + int y_range_min; + int y_range_max; +}; + +struct himax_report_data +{ + int touch_all_size; + int raw_cnt_max; + int raw_cnt_rmd; + int touch_info_size; + uint8_t finger_num; + uint8_t finger_on; + uint8_t *hx_coord_buf; + uint8_t hx_state_info[2]; +#if defined(HX_SMART_WAKEUP) + int event_size; + uint8_t *hx_event_buf; +#endif +#if defined(HX_TP_PROC_DIAG) + int rawdata_size; + uint8_t diag_cmd; + uint8_t *hx_rawdata_buf; + uint8_t rawdata_frame_size; +#endif +}; + +struct himax_ts_data +{ + bool suspended; + atomic_t suspend_mode; + uint8_t x_channel; + uint8_t y_channel; + uint8_t useScreenRes; + uint8_t diag_command; + + uint8_t protocol_type; + uint8_t first_pressed; + uint8_t coord_data_size; + uint8_t area_data_size; + uint8_t coordInfoSize; + uint8_t raw_data_frame_size; + uint8_t raw_data_nframes; + uint8_t nFinger_support; + uint8_t irq_enabled; + uint8_t diag_self[50]; + + uint16_t finger_pressed; + uint16_t last_slot; + uint16_t pre_finger_mask; + + uint32_t debug_log_level; + uint32_t widthFactor; + uint32_t heightFactor; + uint32_t tw_x_min; + uint32_t tw_x_max; + uint32_t tw_y_min; + uint32_t tw_y_max; + uint32_t pl_x_min; + uint32_t pl_x_max; + uint32_t pl_y_min; + uint32_t pl_y_max; + + int rst_gpio; + int use_irq; + int (*power)(int on); + int pre_finger_data[10][2]; + + struct device *dev; + struct workqueue_struct *himax_wq; + struct work_struct work; + struct input_dev *input_dev; + struct hrtimer timer; + struct i2c_client *client; + struct himax_i2c_platform_data *pdata; + struct himax_virtual_key *button; + struct mutex rw_lock; + struct mutex report_mutex; + +#if defined(CONFIG_FB) + struct notifier_block fb_notif; + struct workqueue_struct *himax_att_wq; + struct delayed_work work_att; + struct mutex ops_lock; +#elif defined(CONFIG_HAS_EARLYSUSPEND) + struct early_suspend early_suspend; +#endif +#ifdef HX_CHIP_STATUS_MONITOR + struct workqueue_struct *himax_chip_monitor_wq; + struct delayed_work himax_chip_monitor; +#endif +#ifdef HX_TP_PROC_FLASH_DUMP + struct workqueue_struct *flash_wq; + struct work_struct flash_work; +#endif + +#ifdef HX_AUTO_UPDATE_FW + struct workqueue_struct *himax_update_wq; + struct delayed_work work_update; +#endif + +#ifdef HX_ZERO_FLASH + struct workqueue_struct *himax_0f_update_wq; + struct delayed_work work_0f_update; +#endif + +#ifdef HX_TP_PROC_DIAG + struct workqueue_struct *himax_diag_wq; + struct delayed_work himax_diag_delay_wrok; +#endif + +#ifdef HX_SMART_WAKEUP + uint8_t SMWP_enable; + uint8_t gesture_cust_en[16]; + //struct wake_lock ts_SMWP_wake_lock; + struct wakeup_source ts_SMWP_wake_lock; +#endif + +#ifdef HX_HIGH_SENSE + uint8_t HSEN_enable; +#endif + +#if defined(HX_USB_DETECT_CALLBACK)||defined(HX_USB_DETECT_GLOBAL) + uint8_t usb_connected; + uint8_t *cable_config; +#endif + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) + struct workqueue_struct *ito_test_wq; + struct work_struct ito_test_work; +#endif + +}; + +#ifdef HX_CHIP_STATUS_MONITOR +struct chip_monitor_data +{ + int HX_CHIP_POLLING_COUNT; + int HX_POLLING_TIMER;//unit:sec + int HX_POLLING_TIMES;//ex:5(timer)x2(times)=10sec(polling time) + int HX_ON_HAND_SHAKING;// + int HX_CHIP_MONITOR_EN; +}; +#endif + + +enum input_protocol_type +{ + PROTOCOL_TYPE_A = 0x00, + PROTOCOL_TYPE_B = 0x01, +}; + +#ifdef HX_HIGH_SENSE +void himax_set_HSEN_func(struct i2c_client *client,uint8_t HSEN_enable); +#endif + +#ifdef HX_SMART_WAKEUP +#define GEST_PTLG_ID_LEN (4) +#define GEST_PTLG_HDR_LEN (4) +#define GEST_PTLG_HDR_ID1 (0xCC) +#define GEST_PTLG_HDR_ID2 (0x44) +#define GEST_PT_MAX_NUM (128) + +void himax_set_SMWP_func(struct i2c_client *client,uint8_t SMWP_enable); +extern bool FAKE_POWER_KEY_SEND; + +enum gesture_event_type +{ + EV_GESTURE_01 = 0x01, + EV_GESTURE_02, + EV_GESTURE_03, + EV_GESTURE_04, + EV_GESTURE_05, + EV_GESTURE_06, + EV_GESTURE_07, + EV_GESTURE_08, + EV_GESTURE_09, + EV_GESTURE_10, + EV_GESTURE_11, + EV_GESTURE_12, + EV_GESTURE_13, + EV_GESTURE_14, + EV_GESTURE_15, + EV_GESTURE_PWR = 0x80, +}; + +#define KEY_CUST_01 251 +#define KEY_CUST_02 252 +#define KEY_CUST_03 253 +#define KEY_CUST_04 254 +#define KEY_CUST_05 255 +#define KEY_CUST_06 256 +#define KEY_CUST_07 257 +#define KEY_CUST_08 258 +#define KEY_CUST_09 259 +#define KEY_CUST_10 260 +#define KEY_CUST_11 261 +#define KEY_CUST_12 262 +#define KEY_CUST_13 263 +#define KEY_CUST_14 264 +#define KEY_CUST_15 265 +#endif + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) +extern uint8_t himax_ito_test(void); +#endif + +extern int irq_enable_count; + +//void himax_HW_reset(uint8_t loadconfig,uint8_t int_off); + +#ifdef QCT +irqreturn_t himax_ts_thread(int irq, void *ptr); +int himax_input_register(struct himax_ts_data *ts); +#endif + +extern int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id); +extern int himax_chip_common_remove(struct i2c_client *client); +extern int himax_chip_common_suspend(struct himax_ts_data *ts); +extern int himax_chip_common_resume(struct himax_ts_data *ts); + +#endif + diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_debug.c b/drivers/input/touchscreen/hxchipset83112b/himax_debug.c new file mode 100755 index 000000000000..33e6a082e29e --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_debug.c @@ -0,0 +1,3351 @@ +/* Himax Android Driver Sample Code for debug nodes +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 "himax_debug.h" +#include "himax_ic.h" + +//struct himax_debug_data* debug_data; + +extern struct himax_ic_data* ic_data; +extern struct himax_ts_data *private_ts; +extern unsigned char IC_TYPE; +extern unsigned char IC_CHECKSUM; +extern int himax_input_register(struct himax_ts_data *ts); +#ifdef HX_CHIP_STATUS_MONITOR +extern struct chip_monitor_data *g_chip_monitor_data; +#endif + +#ifdef HX_RST_PIN_FUNC +extern void himax_ic_reset(uint8_t loadconfig,uint8_t int_off); +#endif + +#ifdef HX_TP_PROC_DIAG +#ifdef HX_TP_PROC_2T2R +extern bool Is_2T2R; +int HX_RX_NUM_2 = 0; +int HX_TX_NUM_2 = 0; +#endif +uint8_t g_diag_arr_num = 0; +#endif + +#ifdef HX_SMART_WAKEUP +bool FAKE_POWER_KEY_SEND; +#endif + +int g_max_mutual = 0; +int g_min_mutual = 255; +int g_max_self = 0; +int g_min_self = 255; + +#if defined(HX_TP_PROC_SELF_TEST) || defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) +int g_self_test_entered = 0; +#endif + +struct timespec timeStart, timeEnd, timeDelta; +int g_switch_mode = 0; +extern void himax_idle_mode(struct i2c_client *client,int disable); +extern int himax_switch_mode(struct i2c_client *client,int mode); +extern void himax_return_event_stack(struct i2c_client *client); + +#ifdef HX_ZERO_FLASH +extern void himax_0f_operation(struct work_struct *work); +extern void himax_0f_operation_check(void); +extern void himax_sys_reset(void); +#endif + +//============================================================================================================= +// +// Segment : Himax PROC Debug Function +// +//============================================================================================================= +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) + +static ssize_t himax_ito_test_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + ssize_t ret = 0; + uint8_t result = 0; + uint8_t status = 0; + + if(!HX_PROC_SEND_FLAG) + { + status = ito_get_step_status(); + + switch(status) + { + case 0: + ret += sprintf(buf + ret, "Step : START_TEST\n"); + break; + case 1: + ret += sprintf(buf + ret, "Step : RAW_DATA\n"); + break; + case 2: + ret += sprintf(buf + ret, "Step : PERCENT_TEST\n"); + break; + case 3: + ret += sprintf(buf + ret, "Step : DEV_TEST\n"); + break; + case 4: + ret += sprintf(buf + ret, "Step : NOISE_TEST\n"); + break; + case 9: + ret += sprintf(buf + ret, "Step : END_TEST\n"); + break; + default: + ret += sprintf(buf + ret, "Step : Null\n"); + } + + result = ito_get_result_status(); + if(result == 0xF) + ret += sprintf(buf + ret, "ITO test is On-going! \n"); + else if(result == 0) + ret += sprintf(buf + ret, "ITO test is Pass! \n"); + else if(result == 2) + ret += sprintf(buf + ret, "Open config file fail! \n"); + else + ret += sprintf(buf + ret, "ITO test is Fail! \n"); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + + return ret; +} + +static ssize_t himax_ito_test_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + uint8_t result = 0; + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + result = ito_get_result_status(); + I("%s: buf = %s, result = %d.\n", __func__, buf, result); + + if(buf[0] == '1' && result != 0xF) + { + I("%s: buf[0] = %c.\n", __func__, buf[0]); + ito_set_step_status(0); + queue_work(ts->ito_test_wq, &ts->ito_test_work); + } + + return len; +} + +static struct file_operations himax_proc_ito_test_ops = +{ + .owner = THIS_MODULE, + .read = himax_ito_test_read, + .write = himax_ito_test_write, +}; +#endif + +static ssize_t himax_CRC_test_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + ssize_t ret = 0; + uint8_t result = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + himax_sense_off(private_ts->client); + msleep(20); + result = himax_calculateChecksum(private_ts->client, false); + himax_sense_on(private_ts->client, 0x01); + if(result) + ret += sprintf(temp_buf + ret, "CRC test is Pass! \n"); + else + ret += sprintf(temp_buf + ret, "CRC test is Fail! \n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + + return ret; +} + +static struct file_operations himax_proc_CRC_test_ops = +{ + .owner = THIS_MODULE, + .read = himax_CRC_test_read, +}; + +static ssize_t himax_vendor_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + ssize_t count = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { +#if 1 + if((IC_TYPE >= 8)&&(ic_data->vendor_cid_maj_ver >= 0 || ic_data->vendor_cid_min_ver >= 0)) + { + if(IC_TYPE == HX_83112A_SERIES_PWON) + { + count += sprintf(temp_buf + count, "Truly Himax CID0%2.2X_D%2.2X_C%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver),ic_data->vendor_display_cfg_ver,ic_data->vendor_touch_cfg_ver); + } + else + { + count += sprintf(temp_buf + count, "DJN Himax CID0%2.2X_D%2.2X_C%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver),ic_data->vendor_display_cfg_ver,ic_data->vendor_touch_cfg_ver); + } + } + else + { + count += sprintf(temp_buf + count, "Himax null\n"); + } +#else + count += sprintf(temp_buf + count, "FW_VER = 0x%2.2X \n",ic_data->vendor_fw_ver); + + if(IC_TYPE < 8) + count += sprintf(temp_buf + count, "CONFIG_VER = 0x%2.2X \n",ic_data->vendor_config_ver); + else + { + count += sprintf(temp_buf + count, "TOUCH_VER = 0x%2.2X \n",ic_data->vendor_touch_cfg_ver); + count += sprintf(temp_buf + count, "DISPLAY_VER = 0x%2.2X \n",ic_data->vendor_display_cfg_ver); + } + if(ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0) + count += sprintf(temp_buf + count, "CID_VER = NULL\n"); + else + count += sprintf(temp_buf + count, "CID_VER = 0x%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); + + if(ic_data->vendor_panel_ver < 0) + count += sprintf(temp_buf + count, "PANEL_VER = NULL\n"); + else + count += sprintf(temp_buf + count, "PANEL_VER = 0x%2.2X \n",ic_data->vendor_panel_ver); + + count += sprintf(temp_buf + count, "\n"); + + count += sprintf(temp_buf + count, "Himax Touch Driver Version:\n"); + count += sprintf(temp_buf + count, "%s \n", HIMAX_DRIVER_VER); +#endif + HX_PROC_SEND_FLAG=1; + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + } + else + HX_PROC_SEND_FLAG=0; + + return count; +} + +static struct file_operations himax_proc_vendor_ops = +{ + .owner = THIS_MODULE, + .read = himax_vendor_read, +}; + +static ssize_t himax_attn_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + ssize_t ret = 0; + struct himax_ts_data *ts_data; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + ts_data = private_ts; + + if(!HX_PROC_SEND_FLAG) + { + ret += sprintf(temp_buf, "attn = %x\n", himax_int_gpio_read(ts_data->pdata->gpio_irq)); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + + return ret; +} + + +static struct file_operations himax_proc_attn_ops = +{ + .owner = THIS_MODULE, + .read = himax_attn_read, +}; + +static ssize_t himax_int_en_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + size_t count = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + count += sprintf(temp_buf + count, "%d ", ts->irq_enabled); + count += sprintf(temp_buf + count, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return count; +} + +static ssize_t himax_int_en_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + char buf_tmp[12]= {0}; + int value, ret=0; + + if (len >= 12) + { + I("%s: no command exceeds 12 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf_tmp, buff, len)) + { + return -EFAULT; + } + + if (buf_tmp[0] == '0') + value = false; + else if (buf_tmp[0] == '1') + value = true; + else + return -EINVAL; + + if (value) + { + ret = himax_int_en_set(ts->client); + if (ret == 0) + { + ts->irq_enabled = 1; + irq_enable_count = 1; + } + } + else + { + himax_int_enable(ts->client->irq,0); + free_irq(ts->client->irq, ts); + ts->irq_enabled = 0; + } + + return len; +} + +static struct file_operations himax_proc_int_en_ops = +{ + .owner = THIS_MODULE, + .read = himax_int_en_read, + .write = himax_int_en_write, +}; + +static ssize_t himax_layout_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + size_t count = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_x_min); + count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_x_max); + count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_y_min); + count += sprintf(temp_buf + count, "%d ", ts->pdata->abs_y_max); + count += sprintf(temp_buf + count, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + + return count; +} + +static ssize_t himax_layout_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + char buf_tmp[5]; + int i = 0, j = 0, k = 0, ret; + unsigned long value; + int layout[4] = {0}; + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + for (i = 0; i < 20; i++) + { + if (buf[i] == ',' || buf[i] == '\n') + { + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + if (i - j <= 5) + memcpy(buf_tmp, buf + j, i - j); + else + { + I("buffer size is over 5 char\n"); + return len; + } + j = i + 1; + if (k < 4) + { + ret = kstrtoul(buf_tmp, 10, &value); + layout[k++] = value; + } + } + } + if (k == 4) + { + ts->pdata->abs_x_min=layout[0]; + ts->pdata->abs_x_max=layout[1]; + ts->pdata->abs_y_min=layout[2]; + ts->pdata->abs_y_max=layout[3]; + I("%d, %d, %d, %d\n", + ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); + input_unregister_device(ts->input_dev); + himax_input_register(ts); + } + else + I("ERR@%d, %d, %d, %d\n", + ts->pdata->abs_x_min, ts->pdata->abs_x_max, ts->pdata->abs_y_min, ts->pdata->abs_y_max); + return len; +} + +static struct file_operations himax_proc_layout_ops = +{ + .owner = THIS_MODULE, + .read = himax_layout_read, + .write = himax_layout_write, +}; + +static ssize_t himax_debug_level_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts_data; + size_t count = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + ts_data = private_ts; + + if(!HX_PROC_SEND_FLAG) + { + count += sprintf(temp_buf, "%d\n", ts_data->debug_log_level); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } + else + HX_PROC_SEND_FLAG=0; + + return count; +} + +static ssize_t himax_debug_level_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts; + char buf_tmp[11]; + int i; + ts = private_ts; + + if (len >= 12) + { + I("%s: no command exceeds 12 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf_tmp, buff, len)) + { + return -EFAULT; + } + + ts->debug_log_level = 0; + for(i=0; i='0' && buf_tmp[i]<='9' ) + ts->debug_log_level |= (buf_tmp[i]-'0'); + else if( buf_tmp[i]>='A' && buf_tmp[i]<='F' ) + ts->debug_log_level |= (buf_tmp[i]-'A'+10); + else if( buf_tmp[i]>='a' && buf_tmp[i]<='f' ) + ts->debug_log_level |= (buf_tmp[i]-'a'+10); + + if(i!=len-2) + ts->debug_log_level <<= 4; + } + + if (ts->debug_log_level & BIT(3)) + { + if (ts->pdata->screenWidth > 0 && ts->pdata->screenHeight > 0 && + (ts->pdata->abs_x_max - ts->pdata->abs_x_min) > 0 && + (ts->pdata->abs_y_max - ts->pdata->abs_y_min) > 0) + { + ts->widthFactor = (ts->pdata->screenWidth << SHIFTBITS)/(ts->pdata->abs_x_max - ts->pdata->abs_x_min); + ts->heightFactor = (ts->pdata->screenHeight << SHIFTBITS)/(ts->pdata->abs_y_max - ts->pdata->abs_y_min); + if (ts->widthFactor > 0 && ts->heightFactor > 0) + ts->useScreenRes = 1; + else + { + ts->heightFactor = 0; + ts->widthFactor = 0; + ts->useScreenRes = 0; + } + } + else + I("Enable finger debug with raw position mode!\n"); + } + else + { + ts->useScreenRes = 0; + ts->widthFactor = 0; + ts->heightFactor = 0; + } + + return len; +} + +static struct file_operations himax_proc_debug_level_ops = +{ + .owner = THIS_MODULE, + .read = himax_debug_level_read, + .write = himax_debug_level_write, +}; + +#ifdef HX_TP_PROC_REGISTER +static ssize_t himax_proc_register_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int ret = 0; + uint16_t loop_i; + uint8_t data[128]; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + memset(data, 0x00, sizeof(data)); + + if(!HX_PROC_SEND_FLAG) + { + I("himax_register_show: %02X,%02X,%02X,%02X\n", register_command[3],register_command[2],register_command[1],register_command[0]); + himax_register_read(private_ts->client, register_command, 128, data, cfg_flag); + + ret += sprintf(temp_buf, "command: %02X,%02X,%02X,%02X\n", register_command[3],register_command[2],register_command[1],register_command[0]); + + for (loop_i = 0; loop_i < 128; loop_i++) + { + ret += sprintf(temp_buf + ret, "0x%2.2X ", data[loop_i]); + if ((loop_i % 16) == 15) + ret += sprintf(temp_buf + ret, "\n"); + } + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return ret; +} + +static ssize_t himax_proc_register_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + char buf[80] = {0}; + char buf_tmp[16]; + uint8_t length = 0; + unsigned long result = 0; + uint8_t loop_i = 0; + uint16_t base = 2; + char *data_str = NULL; + uint8_t w_data[20]; + uint8_t x_pos[20]; + uint8_t count = 0; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + memset(w_data, 0x0, sizeof(w_data)); + memset(x_pos, 0x0, sizeof(x_pos)); + + I("himax %s \n",buf); + + if ((buf[0] == 'r' || buf[0] == 'w') && buf[1] == ':' && buf[2] == 'x') + { + + length = strlen(buf); + + //I("%s: length = %d.\n", __func__,length); + for (loop_i = 0; loop_i < length; loop_i++) //find postion of 'x' + { + if(buf[loop_i] == 'x') + { + x_pos[count] = loop_i; + count++; + } + } + + data_str = strrchr(buf, 'x'); + I("%s: %s.\n", __func__,data_str); + length = strlen(data_str+1) - 1; + + if (buf[0] == 'r') + { + if (buf[3] == 'F' && buf[4] == 'E' && length == 4) + { + length = length - base; + cfg_flag = true; + memcpy(buf_tmp, data_str + base +1, length); + } + else + { + cfg_flag = false; + memcpy(buf_tmp, data_str + 1, length); + } + + byte_length = length/2; + if (!kstrtoul(buf_tmp, 16, &result)) + { + for (loop_i = 0 ; loop_i < byte_length ; loop_i++) + { + register_command[loop_i] = (uint8_t)(result >> loop_i*8); + } + } + } + else if (buf[0] == 'w') + { + if (buf[3] == 'F' && buf[4] == 'E') + { + cfg_flag = true; + memcpy(buf_tmp, buf + base + 3, length); + } + else + { + cfg_flag = false; + memcpy(buf_tmp, buf + 3, length); + } + if(count < 3) + { + byte_length = length/2; + if (!kstrtoul(buf_tmp, 16, &result)) //command + { + for (loop_i = 0 ; loop_i < byte_length ; loop_i++) + { + register_command[loop_i] = (uint8_t)(result >> loop_i*8); + } + } + if (!kstrtoul(data_str+1, 16, &result)) //data + { + for (loop_i = 0 ; loop_i < byte_length ; loop_i++) + { + w_data[loop_i] = (uint8_t)(result >> loop_i*8); + } + } + himax_register_write(private_ts->client, register_command, byte_length, w_data, cfg_flag); + } + else + { + byte_length = x_pos[1] - x_pos[0] - 2; + for (loop_i = 0; loop_i < count; loop_i++) //parsing addr after 'x' + { + memcpy(buf_tmp, buf + x_pos[loop_i] + 1, byte_length); + //I("%s: buf_tmp = %s\n", __func__,buf_tmp); + if (!kstrtoul(buf_tmp, 16, &result)) + { + if(loop_i == 0) + { + register_command[loop_i] = (uint8_t)(result); + //I("%s: register_command = %X\n", __func__,register_command[0]); + } + else + { + w_data[loop_i - 1] = (uint8_t)(result); + //I("%s: w_data[%d] = %2X\n", __func__,loop_i - 1,w_data[loop_i - 1]); + } + } + } + + byte_length = count - 1; + himax_register_write(private_ts->client, register_command, byte_length, &w_data[0], cfg_flag); + } + } + else + return len; + + } + return len; +} + +static struct file_operations himax_proc_register_ops = +{ + .owner = THIS_MODULE, + .read = himax_proc_register_read, + .write = himax_proc_register_write, +}; +#endif + +#ifdef HX_TP_PROC_DIAG +int32_t *getMutualBuffer(void) +{ + return diag_mutual; +} +int32_t *getMutualNewBuffer(void) +{ + return diag_mutual_new; +} +int32_t *getMutualOldBuffer(void) +{ + return diag_mutual_old; +} +int32_t *getSelfBuffer(void) +{ + return &diag_self[0]; +} +uint8_t getXChannel(void) +{ + return x_channel; +} +uint8_t getYChannel(void) +{ + return y_channel; +} +uint8_t getDiagCommand(void) +{ + return g_diag_command; +} +void setXChannel(uint8_t x) +{ + x_channel = x; +} +void setYChannel(uint8_t y) +{ + y_channel = y; +} +void setMutualBuffer(void) +{ + diag_mutual = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL); +} +void setMutualNewBuffer(void) +{ + diag_mutual_new = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL); +} +void setMutualOldBuffer(void) +{ + diag_mutual_old = kzalloc(x_channel * y_channel * sizeof(int32_t), GFP_KERNEL); +} + +#ifdef HX_TP_PROC_2T2R +int32_t *getMutualBuffer_2(void) +{ + return diag_mutual_2; +} +uint8_t getXChannel_2(void) +{ + return x_channel_2; +} +uint8_t getYChannel_2(void) +{ + return y_channel_2; +} +void setXChannel_2(uint8_t x) +{ + x_channel_2 = x; +} +void setYChannel_2(uint8_t y) +{ + y_channel_2 = y; +} +void setMutualBuffer_2(void) +{ + diag_mutual_2 = kzalloc(x_channel_2 * y_channel_2 * sizeof(int32_t), GFP_KERNEL); +} +#endif + +#ifdef HX_TP_PROC_DIAG +int himax_set_diag_cmd(struct himax_ic_data *ic_data,struct himax_report_data *hx_touch_data) +{ + int32_t *mutual_data; + int32_t *self_data; + int mul_num; + int self_num; + //int RawDataLen = 0; + + hx_touch_data->diag_cmd = getDiagCommand(); + if (hx_touch_data->diag_cmd >= 1 && hx_touch_data->diag_cmd <= 7) + { + //Check event stack CRC + if(!diag_check_sum(hx_touch_data)) + { + goto bypass_checksum_failed_packet; + } +#ifdef HX_TP_PROC_2T2R + if(Is_2T2R && (hx_touch_data->diag_cmd >= 4 && hx_touch_data->diag_cmd <= 6)) + { + mutual_data = getMutualBuffer_2(); + self_data = getSelfBuffer(); + + // initiallize the block number of mutual and self + mul_num = getXChannel_2() * getYChannel_2(); + +#ifdef HX_EN_SEL_BUTTON + self_num = getXChannel_2() + getYChannel_2() + ic_data->HX_BT_NUM; +#else + self_num = getXChannel_2() + getYChannel_2(); +#endif + } + else +#endif + { + mutual_data = getMutualBuffer(); + self_data = getSelfBuffer(); + + // initiallize the block number of mutual and self + mul_num = getXChannel() * getYChannel(); + +#ifdef HX_EN_SEL_BUTTON + self_num = getXChannel() + getYChannel() + ic_data->HX_BT_NUM; +#else + self_num = getXChannel() + getYChannel(); +#endif + } + + diag_parse_raw_data(hx_touch_data,mul_num, self_num,hx_touch_data->diag_cmd, mutual_data,self_data); + + } + else if (hx_touch_data->diag_cmd == 8) + { + memset(diag_coor, 0x00, sizeof(diag_coor)); + memcpy(&(diag_coor[0]), &hx_touch_data->hx_coord_buf[0], hx_touch_data->touch_info_size); + } + //assign state info data + memcpy(&(hx_state_info[0]), &hx_touch_data->hx_state_info[0], 2); + + return NO_ERR; + +bypass_checksum_failed_packet: + return 1; +} +#endif +//#if defined(HX_DEBUG_LEVEL) +void himax_log_touch_data(uint8_t *buf,struct himax_report_data *hx_touch_data) +{ + int loop_i = 0; + int print_size = 0; + + if(!hx_touch_data->diag_cmd) + print_size = hx_touch_data->touch_info_size; + else + print_size = hx_touch_data->touch_all_size; + + for (loop_i = 0; loop_i < print_size; loop_i+=8) + { + if((loop_i + 7) >= print_size) + { + I("%s: over flow\n",__func__); + break; + } + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i, buf[loop_i], loop_i + 1, buf[loop_i + 1]); + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 2, buf[loop_i + 2], loop_i + 3, buf[loop_i + 3]); + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 4, buf[loop_i + 4], loop_i + 5, buf[loop_i + 5]); + I("P %2d = 0x%2.2X P %2d = 0x%2.2X ", loop_i + 6, buf[loop_i + 6], loop_i + 7, buf[loop_i + 7]); + I("\n"); + } +} +void himax_log_touch_event(int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched) +{ + if(touched == HX_FINGER_ON) + I("Finger %d=> X:%d, Y:%d W:%d, Z:%d, F:%d, N:%d\n",loop_i + 1, x, y, w, w, loop_i + 1, EN_NoiseFilter); + else if(touched == HX_FINGER_LEAVE) + I("All Finger leave\n"); + else + I("%s : wrong input!\n",__func__); +} +void himax_log_touch_int_devation(int touched) +{ + + + if(touched == HX_FINGER_ON) + { + getnstimeofday(&timeStart); + /* I(" Irq start time = %ld.%06ld s\n", + timeStart.tv_sec, timeStart.tv_nsec/1000); */ + } + else if(touched == HX_FINGER_LEAVE) + { + getnstimeofday(&timeEnd); + timeDelta.tv_nsec = (timeEnd.tv_sec*1000000000+timeEnd.tv_nsec) - (timeStart.tv_sec*1000000000+timeStart.tv_nsec); + /*I("Irq finish time = %ld.%06ld s\n", + timeEnd.tv_sec, timeEnd.tv_nsec/1000);*/ + I("Touch latency = %ld us\n", timeDelta.tv_nsec/1000); + } + else + I("%s : wrong input!\n",__func__); +} +void himax_log_touch_event_detail(struct himax_ts_data *ts,int x,int y,int w,int loop_i,uint8_t EN_NoiseFilter,int touched,uint16_t old_finger) +{ + + if (touched == HX_FINGER_ON) + { + if (old_finger >> loop_i == 0) + { + if (ts->useScreenRes) + { + I("status: Screen:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n", + loop_i+1, x * ts->widthFactor >> SHIFTBITS, + y * ts->heightFactor >> SHIFTBITS, w, EN_NoiseFilter); + } + else + { + I("status: Raw:F:%02d Down, X:%d, Y:%d, W:%d, N:%d\n", + loop_i+1, x, y, w, EN_NoiseFilter); + } + } + } + else if(touched == HX_FINGER_LEAVE)//if (old_finger >> loop_i == 1) + { + if (old_finger >> loop_i == 1) + { + if (ts->useScreenRes) + { + I("status: Screen:F:%02d Up, X:%d, Y:%d, N:%d\n", + loop_i+1, ts->pre_finger_data[loop_i][0] * ts->widthFactor >> SHIFTBITS, + ts->pre_finger_data[loop_i][1] * ts->heightFactor >> SHIFTBITS, EN_NoiseFilter); //Last_EN_NoiseFilter + } + else + { + I("status: Raw:F:%02d Up, X:%d, Y:%d, N:%d\n", + loop_i+1, ts->pre_finger_data[loop_i][0], + ts->pre_finger_data[loop_i][1], EN_NoiseFilter); //Last_EN_NoiseFilter + } + } + } + else + { + I("%s : wrong input!\n",__func__); + } +} +//#endif +static ssize_t himax_diag_arrange_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + g_diag_arr_num = buf[0] - '0'; + I("%s: g_diag_arr_num = %d \n", __func__,g_diag_arr_num); + + return len; +} + +void himax_get_mutual_edge(void) +{ + int i = 0; + for(i = 0; i < (x_channel * y_channel); i++) + { + if(diag_mutual[i] > g_max_mutual) + g_max_mutual = diag_mutual[i]; + if(diag_mutual[i] < g_min_mutual) + g_min_mutual = diag_mutual[i]; + } +} + +void himax_get_self_edge(void) +{ + int i = 0; + for(i = 0; i < (x_channel + y_channel); i++) + { + if(diag_self[i] > g_max_self) + g_max_self = diag_self[i]; + if(diag_self[i] < g_min_self) + g_min_self = diag_self[i]; + } +} + +/* print first step which is row */ +static struct file_operations himax_proc_diag_arrange_ops = +{ + .owner = THIS_MODULE, + .write = himax_diag_arrange_write, +}; +static void print_state_info(struct seq_file *s) +{ + //seq_printf(s, "State_info_2bytes:%3d, %3d\n",hx_state_info[0],hx_state_info[1]); + seq_printf(s, "ReCal = %d\t",hx_state_info[0] & 0x01); + seq_printf(s, "Palm = %d\t",hx_state_info[0]>>1 & 0x01); + seq_printf(s, "AC mode = %d\t",hx_state_info[0]>>2 & 0x01); + seq_printf(s, "Water = %d\n",hx_state_info[0]>>3 & 0x01); + seq_printf(s, "Glove = %d\t",hx_state_info[0]>>4 & 0x01); + seq_printf(s, "TX Hop = %d\t",hx_state_info[0]>>5 & 0x01 ); + seq_printf(s, "Base Line = %d\t",hx_state_info[0]>>6 & 0x01); + seq_printf(s, "OSR Hop = %d\t",hx_state_info[1]>>3 & 0x01); + seq_printf(s, "KEY = %d\n",hx_state_info[1]>>4 & 0x0F); +} + +static void himax_diag_arrange_print(struct seq_file *s, int i, int j, int transpose) +{ + + if(transpose) + seq_printf(s, "%6d", diag_mutual[ j + i*x_channel]); + else + seq_printf(s, "%6d", diag_mutual[ i + j*x_channel]); +} + +/* ready to print second step which is column*/ +static void himax_diag_arrange_inloop(struct seq_file *s, int in_init,int out_init,bool transpose, int j) +{ + int i; + int in_max = 0; + + if(transpose) + in_max = y_channel; + else + in_max = x_channel; + + if (in_init > 0) //bit0 = 1 + { + for(i = in_init-1; i >= 0; i--) + { + himax_diag_arrange_print(s, i, j, transpose); + } + if(transpose) + { + if(out_init > 0) + seq_printf(s, " %5d\n", diag_self[j]); + else + seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]); + } + } + else //bit0 = 0 + { + for (i = 0; i < in_max; i++) + { + himax_diag_arrange_print(s, i, j, transpose); + } + if(transpose) + { + if(out_init > 0) + seq_printf(s, " %5d\n", diag_self[x_channel - j - 1]); + else + seq_printf(s, " %5d\n", diag_self[j]); + } + } +} + +/* print first step which is row */ +static void himax_diag_arrange_outloop(struct seq_file *s, int transpose, int out_init, int in_init) +{ + int j; + int out_max = 0; + int self_cnt = 0; + + if(transpose) + out_max = x_channel; + else + out_max = y_channel; + + if(out_init > 0) //bit1 = 1 + { + self_cnt = 1; + for(j = out_init-1; j >= 0; j--) + { + seq_printf(s, "%3c%02d%c",'[', j + 1,']'); + himax_diag_arrange_inloop(s, in_init, out_init, transpose, j); + if(!transpose) + { + seq_printf(s, " %5d\n", diag_self[y_channel + x_channel - self_cnt]); + self_cnt++; + } + } + } + else //bit1 = 0 + { + //self_cnt = x_channel; + for(j = 0; j < out_max; j++) + { + seq_printf(s, "%3c%02d%c",'[', j + 1,']'); + himax_diag_arrange_inloop(s, in_init, out_init, transpose, j); + if(!transpose) + { + seq_printf(s, " %5d\n", diag_self[j + x_channel]); + } + } + } +} + +/* determin the output format of diag */ +static void himax_diag_arrange(struct seq_file *s) +{ + int bit2,bit1,bit0; + int i; + + /* rotate bit */ + bit2 = g_diag_arr_num >> 2; + /* reverse Y */ + bit1 = g_diag_arr_num >> 1 & 0x1; + /* reverse X */ + bit0 = g_diag_arr_num & 0x1; + + if (g_diag_arr_num < 4) + { + for (i = 0 ; i <= x_channel; i++) + seq_printf(s, "%3c%02d%c",'[', i,']'); + seq_printf(s,"\n"); + himax_diag_arrange_outloop(s, bit2, bit1 * y_channel, bit0 * x_channel); + seq_printf(s, "%6c",' '); + if(bit0 == 1) + { + for (i = x_channel - 1; i >= 0; i--) + seq_printf(s, "%6d", diag_self[i]); + } + else + { + for (i = 0; i < x_channel; i++) + seq_printf(s, "%6d", diag_self[i]); + } + } + else + { + for (i = 0 ; i <= y_channel; i++) + seq_printf(s, "%3c%02d%c",'[', i,']'); + seq_printf(s,"\n"); + himax_diag_arrange_outloop(s, bit2, bit1 * x_channel, bit0 * y_channel); + seq_printf(s, "%6c",' '); + if(bit1 == 1) + { + for (i = x_channel + y_channel - 1; i >= x_channel; i--) + { + seq_printf(s, "%6d", diag_self[i]); + } + } + else + { + for (i = x_channel; i < x_channel + y_channel; i++) + { + seq_printf(s, "%6d", diag_self[i]); + } + } + } +} + +static void *himax_diag_seq_start(struct seq_file *s, loff_t *pos) +{ + if (*pos>=1) return NULL; + return (void *)((unsigned long) *pos+1); +} + +static void *himax_diag_seq_next(struct seq_file *s, void *v, loff_t *pos) +{ + return NULL; +} +static void himax_diag_seq_stop(struct seq_file *s, void *v) +{ +} +static int himax_diag_seq_read(struct seq_file *s, void *v) +{ + size_t count = 0; + uint32_t loop_i; + uint16_t mutual_num, self_num, width; + int dsram_type = 0; + + dsram_type = g_diag_command/10; + +#ifdef HX_TP_PROC_2T2R + if(Is_2T2R &&(g_diag_command >= 4 && g_diag_command <= 6)) + { + mutual_num = x_channel_2 * y_channel_2; + self_num = x_channel_2 + y_channel_2; //don't add KEY_COUNT + width = x_channel_2; + seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel_2, y_channel_2); + } + else +#endif + { + mutual_num = x_channel * y_channel; + self_num = x_channel + y_channel; //don't add KEY_COUNT + width = x_channel; + seq_printf(s, "ChannelStart: %4d, %4d\n\n", x_channel, y_channel); + } + + // start to show out the raw data in adb shell + if ((g_diag_command >= 1 && g_diag_command <= 3) || (g_diag_command == 7)) + { + himax_diag_arrange(s); + seq_printf(s, "\n"); +#ifdef HX_EN_SEL_BUTTON + seq_printf(s, "\n"); + for (loop_i = 0; loop_i < ic_data->HX_BT_NUM; loop_i++) + seq_printf(s, "%6d", diag_self[ic_data->HX_RX_NUM + ic_data->HX_TX_NUM + loop_i]); +#endif + seq_printf(s, "ChannelEnd"); + seq_printf(s, "\n"); + } +#ifdef HX_TP_PROC_2T2R + else if(Is_2T2R && g_diag_command >= 4 && g_diag_command <= 6) + { + for (loop_i = 0; loop_i < mutual_num; loop_i++) + { + seq_printf(s, "%4d", diag_mutual_2[loop_i]); + if ((loop_i % width) == (width - 1)) + seq_printf(s, " %4d\n", diag_self[width + loop_i/width]); + } + seq_printf(s, "\n"); + for (loop_i = 0; loop_i < width; loop_i++) + { + seq_printf(s, "%4d", diag_self[loop_i]); + if (((loop_i) % width) == (width - 1)) + seq_printf(s, "\n"); + } + +#ifdef HX_EN_SEL_BUTTON + seq_printf(s, "\n"); + for (loop_i = 0; loop_i < HX_BT_NUM; loop_i++) + seq_printf(s, "%4d", diag_self[ic_data->HX_RX_NUM_2 + ic_data->HX_TX_NUM_2 + loop_i]); +#endif + seq_printf(s, "ChannelEnd"); + seq_printf(s, "\n"); + } +#endif + else if (g_diag_command == 8) + { + for (loop_i = 0; loop_i < 128 ; loop_i++) + { + if ((loop_i % 16) == 0) + seq_printf(s, "LineStart:"); + seq_printf(s, "%4x", diag_coor[loop_i]); + if ((loop_i % 16) == 15) + seq_printf(s, "\n"); + } + } + else if (dsram_type > 0 && dsram_type <= 8) + { + himax_diag_arrange(s); + seq_printf(s, "ChannelEnd"); + seq_printf(s, "\n"); + } + if((g_diag_command >= 1 && g_diag_command <= 7) || dsram_type > 0) + { + /* print Mutual/Slef Maximum and Minimum */ + himax_get_mutual_edge(); + himax_get_self_edge(); + seq_printf(s, "Mutual Max:%3d, Min:%3d\n",g_max_mutual,g_min_mutual); + seq_printf(s, "Self Max:%3d, Min:%3d\n",g_max_self,g_min_self); + + /* recovery status after print*/ + g_max_mutual = 0; + g_min_mutual = 255; + g_max_self = 0; + g_min_self = 255; + } + /*pring state info*/ + print_state_info(s); + return count; +} +static struct seq_operations himax_diag_seq_ops = +{ + .start = himax_diag_seq_start, + .next = himax_diag_seq_next, + .stop = himax_diag_seq_stop, + .show = himax_diag_seq_read, +}; +static int himax_diag_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &himax_diag_seq_ops); +}; +bool DSRAM_Flag = false; + +//DSRAM thread +void himax_ts_diag_func(void) +{ + int i=0, j=0; + unsigned int index = 0; + int total_size = ic_data->HX_TX_NUM * ic_data->HX_RX_NUM * 2; + uint8_t info_data[total_size]; + int32_t *mutual_data; + int32_t *mutual_data_new; + int32_t *mutual_data_old; + int32_t new_data; + /* 1:common dsram,2:100 frame Max,3:N-(N-1)frame */ + int dsram_type = 0; + char temp_buf[20]; + char write_buf[total_size*3]; + + mutual_data = NULL; + mutual_data_new = NULL; + mutual_data_old = NULL; + memset(write_buf, '\0', sizeof(write_buf)); + + dsram_type = g_diag_command/10; + + I("%s:Entering g_diag_command=%d\n!",__func__,g_diag_command); + + if(dsram_type == 8) + { + dsram_type = 1; + I("%s Sorting Mode run sram type1 ! \n",__func__); + } + + himax_burst_enable(private_ts->client, 1); + if(dsram_type == 1 || dsram_type == 2 || dsram_type == 4) + { + mutual_data = getMutualBuffer(); + } + else if(dsram_type == 3) + { + mutual_data = getMutualBuffer(); + mutual_data_new = getMutualNewBuffer(); + mutual_data_old = getMutualOldBuffer(); + } + himax_get_DSRAM_data(private_ts->client, info_data); + + index = 0; + for (i = 0; i < ic_data->HX_TX_NUM; i++) + { + for (j = 0; j < ic_data->HX_RX_NUM; j++) + { + new_data = (info_data[index + 1] << 8 | info_data[index]); + if(dsram_type == 1 || dsram_type == 4) + { + mutual_data[i*ic_data->HX_RX_NUM+j] = new_data; + } + else if(dsram_type == 2) + { + //Keep max data for 100 frame + if(mutual_data[i * ic_data->HX_RX_NUM + j] < new_data) + mutual_data[i * ic_data->HX_RX_NUM + j] = new_data; + } + else if(dsram_type == 3) + { + //Cal data for [N]-[N-1] frame + mutual_data_new[i * ic_data->HX_RX_NUM + j] = new_data; + mutual_data[i * ic_data->HX_RX_NUM + j] = mutual_data_new[i * ic_data->HX_RX_NUM + j] - mutual_data_old[i * ic_data->HX_RX_NUM + j]; + } + index += 2; + } + } + if(dsram_type == 3) + { + memcpy(mutual_data_old,mutual_data_new,x_channel * y_channel * sizeof(int16_t)); //copy N data to N-1 array + } + diag_max_cnt++; + if(dsram_type == 1 || dsram_type == 3 ) + { + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ); + } + else if(dsram_type == 4) + { + for(i = 0; i < x_channel * y_channel; i++) + { + memset(temp_buf, '\0', sizeof(temp_buf)); + if(i == (x_channel * y_channel - 1)) + snprintf(temp_buf, sizeof(temp_buf), "%4d\n\n", mutual_data[i]); + //I("%s :temp_buf = %s\n",__func__,temp_buf); + else if(i % x_channel == (x_channel - 1)) + snprintf(temp_buf, sizeof(temp_buf), "%4d\n", mutual_data[i]); + else + snprintf(temp_buf, sizeof(temp_buf), "%4d\t", mutual_data[i]); + //I("%s :mutual_data[%d] = %d, temp_buf = %s\n",__func__, i, mutual_data[i], temp_buf); + strcat(write_buf, temp_buf); + } + + //save raw data in file + if (!IS_ERR(diag_sram_fn)) + { + I("%s create file and ready to write\n",__func__); + diag_sram_fn->f_op->write(diag_sram_fn, write_buf, sizeof(write_buf), &diag_sram_fn->f_pos); + write_counter++; + if(write_counter < write_max_count) + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ); + else + { + filp_close(diag_sram_fn,NULL); + write_counter = 0; + } + } + } + else if(dsram_type == 2) + { + if(diag_max_cnt > 100) //count for 100 frame + { + //Clear DSRAM flag + DSRAM_Flag = false; + + //Enable ISR + himax_int_enable(private_ts->client->irq,1); + + //===================================== + // test result command : 0x8002_0324 ==> 0x00 + //===================================== + himax_diag_register_set(private_ts->client, 0x00); + } + else + { + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 1/10*HZ); + } + } +} + +static ssize_t himax_diag_write(struct file *filp, const char __user *buff, size_t len, loff_t *data) +{ + char messages[80] = {0}; + + uint8_t command[2] = {0x00, 0x00}; + uint8_t receive[1]; + + /* 0: common , other: dsram*/ + int storage_type = 0; + /* 1:IIR,2:DC,3:Bank,4:IIR2,5:IIR2_N,6:FIR2,7:Baseline,8:dump coord */ + int rawdata_type = 0; + + memset(receive, 0x00, sizeof(receive)); + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(messages, buff, len)) + { + return -EFAULT; + } + + I("%s:g_switch_mode = %d\n",__func__,g_switch_mode); + + if (messages[1] == 0x0A) + { + g_diag_command =messages[0] - '0'; + } + else + { + g_diag_command =(messages[0] - '0')*10 + (messages[1] - '0'); + } + + storage_type = himax_determin_diag_storage(g_diag_command); + rawdata_type = himax_determin_diag_rawdata(g_diag_command); + + if(g_diag_command > 0 && rawdata_type == 0) + { + I("[Himax]g_diag_command=0x%x ,storage_type=%d, rawdata_type=%d! Maybe no support!\n" + ,g_diag_command,storage_type,rawdata_type); + g_diag_command = 0x00; + } + else + I("[Himax]g_diag_command=0x%x ,storage_type=%d, rawdata_type=%d\n",g_diag_command,storage_type,rawdata_type); + + if (storage_type == 0 && rawdata_type > 0 && rawdata_type < 8) + { + I("%s,common\n",__func__); + if(DSRAM_Flag) + { + //1. Clear DSRAM flag + DSRAM_Flag = false; + //2. Stop DSRAM thread + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + //3. Enable ISR + himax_int_enable(private_ts->client->irq,1); + + /*(4) FW leave sram and return to event stack*/ + himax_return_event_stack(private_ts->client); + } + + if(g_switch_mode == 2) + { + himax_idle_mode(private_ts->client,0); + g_switch_mode = himax_switch_mode(private_ts->client,0); + } + + if(g_diag_command == 0x04) + { +#if defined(HX_TP_PROC_2T2R) + command[0] = g_diag_command; +#else + g_diag_command = 0x00; + command[0] = 0x00; +#endif + } + else + command[0] = g_diag_command; + himax_diag_register_set(private_ts->client, command[0]); + } + else if (storage_type > 0 && storage_type < 8 && rawdata_type > 0 && rawdata_type < 8) + { + I("%s,dsram\n",__func__); + + diag_max_cnt = 0; + memset(diag_mutual, 0x00, x_channel * y_channel * sizeof(int32_t)); //Set data 0 everytime + + //0. set diag flag + if(DSRAM_Flag) + { + //(1) Clear DSRAM flag + DSRAM_Flag = false; + + //(2) Stop DSRAM thread + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + //(3) Enable ISR + himax_int_enable(private_ts->client->irq,1); + + /*(4) FW leave sram and return to event stack*/ + himax_return_event_stack(private_ts->client); + } + /* close sorting if turn on*/ + if(g_switch_mode == 2) + { + himax_idle_mode(private_ts->client,0); + g_switch_mode = himax_switch_mode(private_ts->client,0); + } + + switch(rawdata_type) + { + case 1: + command[0] = 0x09; //IIR + break; + case 2: + command[0] = 0x0A; //RAWDATA + break; + case 7: + command[0] = 0x0B; //DC + break; + default: + command[0] = 0x00; + E("%s: Sram no support this type !\n",__func__); + break; + } + himax_diag_register_set(private_ts->client, command[0]); + + //1. Disable ISR + himax_int_enable(private_ts->client->irq,0); + + //Open file for save raw data log + if (storage_type == 4) + { + switch (rawdata_type) + { + case 1: + diag_sram_fn = filp_open(IIR_DUMP_FILE,O_CREAT | O_WRONLY,0); + break; + case 2: + diag_sram_fn = filp_open(DC_DUMP_FILE,O_CREAT | O_WRONLY,0); + break; + case 3: + diag_sram_fn = filp_open(BANK_DUMP_FILE,O_CREAT | O_WRONLY,0); + break; + default: + I("%s raw data type is not true. raw data type is %d \n",__func__, rawdata_type); + } + } + + //2. Start DSRAM thread + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100); + + I("%s: Start get raw data in DSRAM\n", __func__); + if (storage_type == 4) + msleep(6000); + //3. Set DSRAM flag + DSRAM_Flag = true; + + + } + else if(storage_type == 8) + { + I("Soritng mode!\n"); + + if(DSRAM_Flag) + { + //1. Clear DSRAM flag + DSRAM_Flag = false; + //2. Stop DSRAM thread + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + //3. Enable ISR + himax_int_enable(private_ts->client->irq,1); + + /*(4) FW leave sram and return to event stack*/ + himax_return_event_stack(private_ts->client); + } + + himax_idle_mode(private_ts->client,1); + g_switch_mode = himax_switch_mode(private_ts->client,1); + if(g_switch_mode == 2) + { + if(rawdata_type == 1) + command[0] = 0x09; //IIR + else if(rawdata_type == 2) + command[0] = 0x0A; //DC + else if(rawdata_type == 7) + command[0] = 0x08; //BASLINE + else + { + command[0] = 0x00; + E("%s: Now Sorting Mode does not support this command=%d\n",__func__,g_diag_command); + } + himax_diag_register_set(private_ts->client, command[0]); + } + + queue_delayed_work(private_ts->himax_diag_wq, &private_ts->himax_diag_delay_wrok, 2*HZ/100); + DSRAM_Flag = true; + + } + else + { + //set diag flag + if(DSRAM_Flag) + { + I("return and cancel sram thread!\n"); + //(1) Clear DSRAM flag + DSRAM_Flag = false; + + //(2) Stop DSRAM thread + cancel_delayed_work(&private_ts->himax_diag_delay_wrok); + //(3) Enable ISR + himax_int_enable(private_ts->client->irq,1); + + /*(4) FW leave sram and return to event stack*/ + himax_return_event_stack(private_ts->client); + } + + if(g_switch_mode == 2) + { + himax_idle_mode(private_ts->client,0); + g_switch_mode = himax_switch_mode(private_ts->client,0); + } + + if(g_diag_command != 0x00) + { + + E("[Himax]g_diag_command error!diag_command=0x%x so reset\n",g_diag_command); + command[0] = 0x00; + if(g_diag_command != 0x08) + g_diag_command = 0x00; + himax_diag_register_set(private_ts->client, command[0]); + } + else + { + command[0] = 0x00; + g_diag_command = 0x00; + himax_diag_register_set(private_ts->client, command[0]); + I("return to normal g_diag_command=0x%x\n",g_diag_command); + } + } + return len; +} + +static struct file_operations himax_proc_diag_ops = +{ + .owner = THIS_MODULE, + .open = himax_diag_proc_open, + .read = seq_read, + .write = himax_diag_write, +}; +#endif + +#ifdef HX_TP_PROC_RESET +static ssize_t himax_reset_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + char buf_tmp[12]; + + if (len >= 12) + { + I("%s: no command exceeds 12 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf_tmp, buff, len)) + { + return -EFAULT; + } +#ifdef HX_RST_PIN_FUNC + if (buf_tmp[0] == '1') + himax_ic_reset(false,false); + else if (buf_tmp[0] == '2') + himax_ic_reset(false,true); + else if (buf_tmp[0] == '3') + himax_ic_reset(true,false); + else if (buf_tmp[0] == '4') + himax_ic_reset(true,true); + //else if (buf_tmp[0] == '5') + // ESD_HW_REST(); +#endif + return len; +} + +static struct file_operations himax_proc_reset_ops = +{ + .owner = THIS_MODULE, + .write = himax_reset_write, +}; +#endif + +#ifdef HX_TP_PROC_DEBUG +static ssize_t himax_debug_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + size_t count = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + if (debug_level_cmd == 't') + { + if (fw_update_complete) + { + count += sprintf(temp_buf, "FW Update Complete "); + } + else + { + count += sprintf(temp_buf, "FW Update Fail "); + } + } + else if (debug_level_cmd == 'h') + { + if (handshaking_result == 0) + { + count += sprintf(temp_buf, "Handshaking Result = %d (MCU Running)\n",handshaking_result); + } + else if (handshaking_result == 1) + { + count += sprintf(temp_buf, "Handshaking Result = %d (MCU Stop)\n",handshaking_result); + } + else if (handshaking_result == 2) + { + count += sprintf(temp_buf, "Handshaking Result = %d (I2C Error)\n",handshaking_result); + } + else + { + count += sprintf(temp_buf, "Handshaking Result = error \n"); + } + } + else if (debug_level_cmd == 'v') + { + count += sprintf(temp_buf + count, "FW_VER = 0x%2.2X \n",ic_data->vendor_fw_ver); + + if(IC_TYPE < 8) + count += sprintf(temp_buf + count, "CONFIG_VER = 0x%2.2X \n",ic_data->vendor_config_ver); + else + { + count += sprintf(temp_buf + count, "TOUCH_VER = 0x%2.2X \n",ic_data->vendor_touch_cfg_ver); + count += sprintf(temp_buf + count, "DISPLAY_VER = 0x%2.2X \n",ic_data->vendor_display_cfg_ver); + } + if(ic_data->vendor_cid_maj_ver < 0 && ic_data->vendor_cid_min_ver < 0) + count += sprintf(temp_buf + count, "CID_VER = NULL\n"); + else + count += sprintf(temp_buf + count, "CID_VER = 0x%2.2X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); + + if(ic_data->vendor_panel_ver < 0) + count += sprintf(temp_buf + count, "PANEL_VER = NULL\n"); + else + count += sprintf(temp_buf + count, "PANEL_VER = 0x%2.2X \n",ic_data->vendor_panel_ver); + + count += sprintf(temp_buf + count, "\n"); + + count += sprintf(temp_buf + count, "Himax Touch Driver Version:\n"); + count += sprintf(temp_buf + count, "%s \n", HIMAX_DRIVER_VER); + } + else if (debug_level_cmd == 'd') + { + count += sprintf(temp_buf + count, "Himax Touch IC Information :\n"); + switch(IC_TYPE) + { + case HX_85XX_D_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX852xD\n"); + break; + case HX_85XX_E_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX852xE\n"); + break; + case HX_85XX_ES_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX852xES\n"); + break; + case HX_85XX_F_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX852xF\n"); + break; + case HX_83100A_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83100A\n"); + break; + case HX_83102A_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83102A\n"); + break; + case HX_83102B_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83102B\n"); + break; + case HX_83110A_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83110A\n"); + break; + case HX_83110B_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83110B\n"); + break; + case HX_83111B_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83111B\n"); + break; + case HX_83112A_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83112A\n"); + break; + case HX_83112B_SERIES_PWON: + count += sprintf(temp_buf + count, "IC Type : HX83112B\n"); + break; + default: + count += sprintf(temp_buf + count, "IC Type error.\n"); + } + switch(IC_CHECKSUM) + { + case HX_TP_BIN_CHECKSUM_SW: + count += sprintf(temp_buf + count, "IC Checksum : SW\n"); + break; + case HX_TP_BIN_CHECKSUM_HW: + count += sprintf(temp_buf + count, "IC Checksum : HW\n"); + break; + case HX_TP_BIN_CHECKSUM_CRC: + count += sprintf(temp_buf + count, "IC Checksum : CRC\n"); + break; + default: + count += sprintf(temp_buf + count, "IC Checksum error.\n"); + } + + if (ic_data->HX_INT_IS_EDGE) + { + count += sprintf(temp_buf + count, "Driver register Interrupt : EDGE TIRGGER\n"); + } + else + { + count += sprintf(temp_buf + count, "Driver register Interrupt : LEVEL TRIGGER\n"); + } + if (private_ts->protocol_type == PROTOCOL_TYPE_A) + { + count += sprintf(temp_buf + count, "Protocol : TYPE_A\n"); + } + else + { + count += sprintf(temp_buf + count, "Protocol : TYPE_B\n"); + } + count += sprintf(temp_buf + count, "RX Num : %d\n",ic_data->HX_RX_NUM); + count += sprintf(temp_buf + count, "TX Num : %d\n",ic_data->HX_TX_NUM); + count += sprintf(temp_buf + count, "BT Num : %d\n",ic_data->HX_BT_NUM); + count += sprintf(temp_buf + count, "X Resolution : %d\n",ic_data->HX_X_RES); + count += sprintf(temp_buf + count, "Y Resolution : %d\n",ic_data->HX_Y_RES); + count += sprintf(temp_buf + count, "Max Point : %d\n",ic_data->HX_MAX_PT); + count += sprintf(temp_buf + count, "XY reverse : %d\n",ic_data->HX_XY_REVERSE); +#ifdef HX_TP_PROC_2T2R + if(Is_2T2R) + { + count += sprintf(temp_buf + count, "2T2R panel\n"); + count += sprintf(temp_buf + count, "RX Num_2 : %d\n",HX_RX_NUM_2); + count += sprintf(temp_buf + count, "TX Num_2 : %d\n",HX_TX_NUM_2); + } +#endif + } + else if (debug_level_cmd == 'i') + { + if(himax_read_i2c_status(private_ts->client)) + count += sprintf(temp_buf + count, "I2C communication is bad.\n"); + else + count += sprintf(temp_buf + count, "I2C communication is good.\n"); + } + else if (debug_level_cmd == 'n') + { + if(himax_read_ic_trigger_type(private_ts->client) == 1) //Edgd = 1, Level = 0 + count += sprintf(temp_buf + count, "IC Interrupt type is edge trigger.\n"); + else if(himax_read_ic_trigger_type(private_ts->client) == 0) + count += sprintf(temp_buf + count, "IC Interrupt type is level trigger.\n"); + else + count += sprintf(temp_buf + count, "Unkown IC trigger type.\n"); + if (ic_data->HX_INT_IS_EDGE) + count += sprintf(temp_buf + count, "Driver register Interrupt : EDGE TIRGGER\n"); + else + count += sprintf(temp_buf + count, "Driver register Interrupt : LEVEL TRIGGER\n"); + } +#if defined(HX_CHIP_STATUS_MONITOR) + else if(debug_level_cmd=='c') + { + count += sprintf(temp_buf + count, "chip_monitor :%d\n", g_chip_monitor_data->HX_CHIP_MONITOR_EN); + } +#endif + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return count; +} + +static ssize_t himax_debug_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct file* filp = NULL; + mm_segment_t oldfs; + int result = 0; + char fileName[128]; + char buf[80] = {0}; + int fw_type = 0; + struct inode *inode; + loff_t file_len = 0; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + if ( buf[0] == 'h') //handshaking + { + debug_level_cmd = buf[0]; + + himax_int_enable(private_ts->client->irq,0); + + handshaking_result = himax_hand_shaking(private_ts->client); //0:Running, 1:Stop, 2:I2C Fail + + himax_int_enable(private_ts->client->irq,1); + + return len; + } + + else if ( buf[0] == 'v') //firmware version + { + himax_int_enable(private_ts->client->irq,0); +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,false); +#endif + debug_level_cmd = buf[0]; + himax_read_FW_ver(private_ts->client); +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(true,false); +#endif + himax_int_enable(private_ts->client->irq,1); + //himax_check_chip_version(); + return len; + } + + else if ( buf[0] == 'd') //ic information + { + debug_level_cmd = buf[0]; + return len; + } + + else if (buf[0] == 't') + { + + himax_int_enable(private_ts->client->irq,0); + +#ifdef HX_CHIP_STATUS_MONITOR + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; + cancel_delayed_work_sync(&private_ts->himax_chip_monitor); +#endif + + debug_level_cmd = buf[0]; + fw_update_complete = false; + + memset(fileName, 0, 128); + // parse the file name + snprintf(fileName, len-2, "%s", &buf[2]); + I("%s: upgrade from file(%s) start!\n", __func__, fileName); + // open file + filp = filp_open(fileName, O_RDONLY, 0); + if (IS_ERR(filp)) + { + E("%s: open firmware file failed\n", __func__); + goto firmware_upgrade_done; + //return len; + } + inode = filp->f_inode; + file_len = inode->i_size; + oldfs = get_fs(); + set_fs(get_ds()); + + // read the latest firmware binary file + result=vfs_read(filp,upgrade_fw,file_len, &filp->f_pos); + if (result < 0) + { + E("%s: read firmware file failed\n", __func__); + goto firmware_upgrade_done; + //return len; + } + + set_fs(oldfs); + filp_close(filp, NULL); + + I("%s: FW image,len %d: %02X, %02X, %02X, %02X\n", __func__, result, upgrade_fw[0], upgrade_fw[1], upgrade_fw[2], upgrade_fw[3]); + + if (result > 0) + { + fw_type = result/1024; + // start to upgrade + himax_int_enable(private_ts->client->irq,0); + I("Now FW size is : %dk\n",fw_type); + switch(fw_type) + { + case 32: + if (fts_ctpm_fw_upgrade_with_sys_fs_32k(private_ts->client,upgrade_fw, result, false) == 0) + { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } + else + { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + case 60: + if (fts_ctpm_fw_upgrade_with_sys_fs_60k(private_ts->client,upgrade_fw, result, false) == 0) + { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } + else + { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + case 64: + if (fts_ctpm_fw_upgrade_with_sys_fs_64k(private_ts->client,upgrade_fw, result, false) == 0) + { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } + else + { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + case 124: + if (fts_ctpm_fw_upgrade_with_sys_fs_124k(private_ts->client,upgrade_fw, result, false) == 0) + { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } + else + { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + case 128: + if (fts_ctpm_fw_upgrade_with_sys_fs_128k(private_ts->client,upgrade_fw, result, false) == 0) + { + E("%s: TP upgrade error, line: %d\n", __func__, __LINE__); + fw_update_complete = false; + } + else + { + I("%s: TP upgrade OK, line: %d\n", __func__, __LINE__); + fw_update_complete = true; + } + break; + default: + E("%s: Flash command fail: %d\n", __func__, __LINE__); + fw_update_complete = false; + break; + } + goto firmware_upgrade_done; + //return count; + } + } + else if (buf[0] == 'i' && buf[1] == '2' && buf[2] == 'c') //i2c commutation + { + debug_level_cmd = 'i'; + return len; + } + + else if (buf[0] == 'i' && buf[1] == 'n' && buf[2] == 't') //INT trigger + { + debug_level_cmd = 'n'; + return len; + } +#if defined(HX_CHIP_STATUS_MONITOR) + else if(buf[0] == 'c') + { + debug_level_cmd = buf[0]; + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 0; + cancel_delayed_work_sync(&private_ts->himax_chip_monitor); + return len; + } +#endif +#ifdef HX_ZERO_FLASH + else if(buf[0] == 'z') + { + himax_0f_operation_check(); + return len; + } + else if(buf[0] == 'p') + { + I("NOW debug echo r!\n"); + //himax_program_sram(); + private_ts->himax_0f_update_wq = create_singlethread_workqueue("HMX_update_0f_reuqest_write"); + if (!private_ts->himax_0f_update_wq) + E(" allocate syn_update_wq failed\n"); + + INIT_DELAYED_WORK(&private_ts->work_0f_update, himax_0f_operation); + queue_delayed_work(private_ts->himax_0f_update_wq, &private_ts->work_0f_update, msecs_to_jiffies(100)); + return len; + } + else if(buf[0] == 'x') + { + himax_sys_reset(); + return len; + } +#endif + /* others,do nothing */ + else + { + debug_level_cmd = 0; + return len; + } + +firmware_upgrade_done: + +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(true,false); +#endif + himax_int_enable(private_ts->client->irq,1); + +#ifdef HX_CHIP_STATUS_MONITOR + g_chip_monitor_data->HX_CHIP_POLLING_COUNT = 0; + g_chip_monitor_data->HX_CHIP_MONITOR_EN = 1; + queue_delayed_work(private_ts->himax_chip_monitor_wq, &private_ts->himax_chip_monitor, g_chip_monitor_data->HX_POLLING_TIMES*HZ); +#endif + + //todo himax_chip->tp_firmware_upgrade_proceed = 0; + //todo himax_chip->suspend_state = 0; + //todo enable_irq(himax_chip->irq); + return len; +} + +static struct file_operations himax_proc_debug_ops = +{ + .owner = THIS_MODULE, + .read = himax_debug_read, + .write = himax_debug_write, +}; + +static ssize_t himax_proc_FW_debug_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int ret = 0; + uint8_t loop_i = 0; + uint8_t tmp_data[64]; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + cmd_set[0] = 0x01; + if(himax_read_FW_status(cmd_set, tmp_data) == NO_ERR) + { + ret += sprintf(temp_buf + ret, "0x%02X%02X%02X%02X :\t",cmd_set[5],cmd_set[4],cmd_set[3],cmd_set[2]); + for (loop_i = 0; loop_i < cmd_set[1]; loop_i++) + { + ret += sprintf(temp_buf+ ret, "%5d\t", tmp_data[loop_i]); + } + ret += sprintf(temp_buf + ret, "\n"); + } + cmd_set[0] = 0x02; + if(himax_read_FW_status(cmd_set, tmp_data) == NO_ERR) + { + for (loop_i = 0; loop_i < cmd_set[1]; loop_i = loop_i + 2) + { + if ((loop_i % 16) == 0) + ret += sprintf(temp_buf + ret, "0x%02X%02X%02X%02X :\t", + cmd_set[5],cmd_set[4],cmd_set[3]+(((cmd_set[2]+ loop_i)>>8)&0xFF), (cmd_set[2] + loop_i)&0xFF); + ret += sprintf(temp_buf + ret, "%5d\t", tmp_data[loop_i] + (tmp_data[loop_i + 1] << 8)); + if ((loop_i % 16) == 14) + ret += sprintf(temp_buf + ret, "\n"); + } + + } + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return ret; +} + +static struct file_operations himax_proc_fw_debug_ops = +{ + .owner = THIS_MODULE, + .read = himax_proc_FW_debug_read, +}; + +static ssize_t himax_proc_DD_debug_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int ret = 0; + uint8_t tmp_data[64]; + uint8_t loop_i = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + if(mutual_set_flag == 1) + { + if(himax_read_DD_status(cmd_set, tmp_data) == NO_ERR) + { + for (loop_i = 0; loop_i < cmd_set[0]; loop_i++) + { + if ((loop_i % 8) == 0) + ret += sprintf(temp_buf + ret, "0x%02X : ", loop_i); + ret += sprintf(temp_buf + ret, "0x%02X ", tmp_data[loop_i]); + if ((loop_i % 8) == 7) + ret += sprintf(temp_buf + ret, "\n"); + } + } + } + //else + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return ret; +} + +static ssize_t himax_proc_DD_debug_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + uint8_t i = 0; + uint8_t cnt = 2; + unsigned long result = 0; + char buf_tmp[20]; + char buf_tmp2[4]; + + if (len >= 20) + { + I("%s: no command exceeds 20 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf_tmp, buff, len)) + { + return -EFAULT; + } + memset(buf_tmp2, 0x0, sizeof(buf_tmp2)); + + if (buf_tmp[2] == 'x' && buf_tmp[6] == 'x' && buf_tmp[10] == 'x') + { + mutual_set_flag = 1; + for (i = 3; i < 12; i = i + 4) + { + memcpy(buf_tmp2, buf_tmp + i, 2); + if (!kstrtoul(buf_tmp2, 16, &result)) + cmd_set[cnt] = (uint8_t)result; + else + I("String to oul is fail in cnt = %d, buf_tmp2 = %s",cnt, buf_tmp2); + cnt--; + } + I("cmd_set[2] = %02X, cmd_set[1] = %02X, cmd_set[0] = %02X\n",cmd_set[2],cmd_set[1],cmd_set[0]); + } + else + mutual_set_flag = 0; + + return len; +} + +static struct file_operations himax_proc_dd_debug_ops = +{ + .owner = THIS_MODULE, + .read = himax_proc_DD_debug_read, + .write = himax_proc_DD_debug_write, +}; + +#endif + +#ifdef HX_TP_PROC_FLASH_DUMP + +uint8_t getFlashCommand(void) +{ + return flash_command; +} + +static uint8_t getFlashDumpProgress(void) +{ + return flash_progress; +} + +static uint8_t getFlashDumpComplete(void) +{ + return flash_dump_complete; +} + +static uint8_t getFlashDumpFail(void) +{ + return flash_dump_fail; +} + +uint8_t getSysOperation(void) +{ + return sys_operation; +} + +static uint8_t getFlashReadStep(void) +{ + return flash_read_step; +} + +bool getFlashDumpGoing(void) +{ + return flash_dump_going; +} + +void setFlashBuffer(void) +{ + flash_buffer = kzalloc(Flash_Size * sizeof(uint8_t), GFP_KERNEL); + memset(flash_buffer,0x00,Flash_Size); +} + +void setSysOperation(uint8_t operation) +{ + sys_operation = operation; +} + +void setFlashDumpProgress(uint8_t progress) +{ + flash_progress = progress; + //I("setFlashDumpProgress : progress = %d ,flash_progress = %d \n",progress,flash_progress); +} + +void setFlashDumpComplete(uint8_t status) +{ + flash_dump_complete = status; +} + +void setFlashDumpFail(uint8_t fail) +{ + flash_dump_fail = fail; +} + +static void setFlashCommand(uint8_t command) +{ + flash_command = command; +} + +static void setFlashReadStep(uint8_t step) +{ + flash_read_step = step; +} + +void setFlashDumpGoing(bool going) +{ + flash_dump_going = going; +} + +static ssize_t himax_proc_flash_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int ret = 0; + int loop_i; + uint8_t local_flash_read_step=0; + uint8_t local_flash_complete = 0; + uint8_t local_flash_progress = 0; + uint8_t local_flash_command = 0; + uint8_t local_flash_fail = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + local_flash_complete = getFlashDumpComplete(); + local_flash_progress = getFlashDumpProgress(); + local_flash_command = getFlashCommand(); + local_flash_fail = getFlashDumpFail(); + + I("flash_progress = %d \n",local_flash_progress); + if(!HX_PROC_SEND_FLAG) + { + if (local_flash_fail) + { + ret += sprintf(temp_buf + ret, "FlashStart:Fail \n"); + ret += sprintf(temp_buf + ret, "FlashEnd"); + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + return ret; + } + + if (!local_flash_complete) + { + ret += sprintf(temp_buf + ret, "FlashStart:Ongoing:0x%2.2x \n",flash_progress); + ret += sprintf(temp_buf + ret, "FlashEnd"); + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + return ret; + } + + if (local_flash_command == 1 && local_flash_complete) + { + ret += sprintf(temp_buf + ret, "FlashStart:Complete \n"); + ret += sprintf(temp_buf + ret, "FlashEnd"); + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + return ret; + } + + if (local_flash_command == 3 && local_flash_complete) + { + ret += sprintf(temp_buf + ret, "FlashStart: \n"); + for(loop_i = 0; loop_i < 128; loop_i++) + { + ret += sprintf(temp_buf + ret, "x%2.2x", flash_buffer[loop_i]); + if ((loop_i % 16) == 15) + { + ret += sprintf(temp_buf + ret, "\n"); + } + } + ret += sprintf(temp_buf + ret, "FlashEnd"); + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + return ret; + } + + //flash command == 0 , report the data + local_flash_read_step = getFlashReadStep(); + + ret += sprintf(temp_buf + ret, "FlashStart:%2.2x \n",local_flash_read_step); + + for (loop_i = 0; loop_i < 1024; loop_i++) + { + ret += sprintf(temp_buf + ret, "x%2.2X", flash_buffer[local_flash_read_step*1024 + loop_i]); + + if ((loop_i % 16) == 15) + { + ret += sprintf(temp_buf + ret, "\n"); + } + } + + ret += sprintf(temp_buf + ret, "FlashEnd"); + ret += sprintf(temp_buf + ret, "\n"); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return ret; +} + +static ssize_t himax_proc_flash_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + char buf_tmp[6]; + unsigned long result = 0; + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + + I("%s: buf = %s\n", __func__, buf); + + if (getSysOperation() == 1) + { + E("%s: PROC is busy , return!\n", __func__); + return len; + } + + if (buf[0] == '0') + { + setFlashCommand(0); + if (buf[1] == ':' && buf[2] == 'x') + { + memcpy(buf_tmp, buf + 3, 2); + I("%s: read_Step = %s\n", __func__, buf_tmp); + if (!kstrtoul(buf_tmp, 16, &result)) + { + I("%s: read_Step = %lu \n", __func__, result); + setFlashReadStep(result); + } + } + } + else if (buf[0] == '1')// 1_32,1_60,1_64,1_24,1_28 for flash size 32k,60k,64k,124k,128k + { + setSysOperation(1); + setFlashCommand(1); + setFlashDumpProgress(0); + setFlashDumpComplete(0); + setFlashDumpFail(0); + if ((buf[1] == '_' ) && (buf[2] == '3' ) && (buf[3] == '2' )) + { + Flash_Size = FW_SIZE_32k; + } + else if ((buf[1] == '_' ) && (buf[2] == '6' )) + { + if (buf[3] == '0') + { + Flash_Size = FW_SIZE_60k; + } + else if (buf[3] == '4') + { + Flash_Size = FW_SIZE_64k; + } + } + else if ((buf[1] == '_' ) && (buf[2] == '2' )) + { + if (buf[3] == '4') + { + Flash_Size = FW_SIZE_124k; + } + else if (buf[3] == '8') + { + Flash_Size = FW_SIZE_128k; + } + } + queue_work(private_ts->flash_wq, &private_ts->flash_work); + } + else if (buf[0] == '2') // 2_32,2_60,2_64,2_24,2_28 for flash size 32k,60k,64k,124k,128k + { + setSysOperation(1); + setFlashCommand(2); + setFlashDumpProgress(0); + setFlashDumpComplete(0); + setFlashDumpFail(0); + if ((buf[1] == '_' ) && (buf[2] == '3' ) && (buf[3] == '2' )) + { + Flash_Size = FW_SIZE_32k; + } + else if ((buf[1] == '_' ) && (buf[2] == '6' )) + { + if (buf[3] == '0') + { + Flash_Size = FW_SIZE_60k; + } + else if (buf[3] == '4') + { + Flash_Size = FW_SIZE_64k; + } + } + else if ((buf[1] == '_' ) && (buf[2] == '2' )) + { + if (buf[3] == '4') + { + Flash_Size = FW_SIZE_124k; + } + else if (buf[3] == '8') + { + Flash_Size = FW_SIZE_128k; + } + } + queue_work(private_ts->flash_wq, &private_ts->flash_work); + } + return len; +} + +static struct file_operations himax_proc_flash_ops = +{ + .owner = THIS_MODULE, + .read = himax_proc_flash_read, + .write = himax_proc_flash_write, +}; + +void himax_ts_flash_func(void) +{ + uint8_t local_flash_command = 0; + + himax_int_enable(private_ts->client->irq,0); + setFlashDumpGoing(true); + + //sector = getFlashDumpSector(); + //page = getFlashDumpPage(); + + local_flash_command = getFlashCommand(); + + msleep(100); + + I("%s: local_flash_command = %d enter.\n", __func__,local_flash_command); + + if ((local_flash_command == 1 || local_flash_command == 2)|| (local_flash_command==0x0F)) + { + himax_flash_dump_func(private_ts->client, local_flash_command,Flash_Size, flash_buffer); + } + + I("Complete~~~~~~~~~~~~~~~~~~~~~~~\n"); + + if (local_flash_command == 2) + { + struct file *fn; + + fn = filp_open(FLASH_DUMP_FILE,O_CREAT | O_WRONLY,0); + if (!IS_ERR(fn)) + { + I("%s create file and ready to write\n",__func__); + fn->f_op->write(fn,flash_buffer,Flash_Size*sizeof(uint8_t),&fn->f_pos); + filp_close(fn,NULL); + } + } + + himax_int_enable(private_ts->client->irq,1); + setFlashDumpGoing(false); + + setFlashDumpComplete(1); + setSysOperation(0); + return; + + /* Flash_Dump_i2c_transfer_error: + + himax_int_enable(private_ts->client->irq,1); + setFlashDumpGoing(false); + setFlashDumpComplete(0); + setFlashDumpFail(1); + setSysOperation(0); + return; + */ +} + +#endif + +#ifdef HX_TP_PROC_SELF_TEST +static ssize_t himax_self_test_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int val=0x00; + int ret = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + I("%s: enter, %d \n", __func__, __LINE__); + if(!HX_PROC_SEND_FLAG) + { + himax_int_enable(private_ts->client->irq,0);//disable irq + g_self_test_entered = 1; + val = himax_chip_self_test(private_ts->client); +#ifdef HX_ESD_RECOVERY + HX_ESD_RESET_ACTIVATE = 1; +#endif + himax_int_enable(private_ts->client->irq,1);//enable irq + + if (val == 0x01) + { + ret += sprintf(temp_buf + ret, "Self_Test Pass\n"); + } + else + { + ret += sprintf(temp_buf + ret, "Self_Test Fail\n"); + } + g_self_test_entered = 0; + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return ret; +} + +/* +static ssize_t himax_chip_self_test_store(struct device *dev,struct device_attribute *attr, const char *buf, size_t count) +{ + char buf_tmp[2]; + unsigned long result = 0; + + memset(buf_tmp, 0x0, sizeof(buf_tmp)); + memcpy(buf_tmp, buf, 2); + if(!kstrtoul(buf_tmp, 16, &result)) + { + sel_type = (uint8_t)result; + } + I("sel_type = %x \r\n", sel_type); + return count; +} +*/ + +static struct file_operations himax_proc_self_test_ops = +{ + .owner = THIS_MODULE, + .read = himax_self_test_read, +}; +#endif + +#ifdef HX_TP_PROC_SENSE_ON_OFF +static ssize_t himax_sense_on_off_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + if(buf[0] == '0') + { + himax_sense_off(private_ts->client); + I("Sense off \n"); + } + else if(buf[0] == '1') + { + if(buf[1] == 's') + { + himax_sense_on(private_ts->client, 0x00); + I("Sense on re-map on, run sram \n"); + } + else + { + himax_sense_on(private_ts->client, 0x01); + I("Sense on re-map off, run flash \n"); + } + } + else + { + I("Do nothing \n"); + } + return len; +} + +static struct file_operations himax_proc_sense_on_off_ops = +{ + .owner = THIS_MODULE, + .write = himax_sense_on_off_write, +}; +#endif + +#ifdef HX_HIGH_SENSE +static ssize_t himax_HSEN_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + size_t count = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + count = snprintf(temp_buf, PAGE_SIZE, "%d\n", ts->HSEN_enable); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return count; +} + +static ssize_t himax_HSEN_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + char buf[80] = {0}; + + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + if (buf[0] == '0') + { + ts->HSEN_enable = 0; + } + else if (buf[0] == '1') + { + ts->HSEN_enable = 1; + } + else + return -EINVAL; + + himax_set_HSEN_enable(ts->client, ts->HSEN_enable, ts->suspended); + + I("%s: HSEN_enable = %d.\n", __func__, ts->HSEN_enable); + + return len; +} + +static struct file_operations himax_proc_HSEN_ops = +{ + .owner = THIS_MODULE, + .read = himax_HSEN_read, + .write = himax_HSEN_write, +}; +#endif + +#ifdef HX_SMART_WAKEUP +static ssize_t himax_SMWP_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + size_t count = 0; + struct himax_ts_data *ts = private_ts; + + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + if(!HX_PROC_SEND_FLAG) + { + count = snprintf(temp_buf, PAGE_SIZE, "%d\n", ts->SMWP_enable); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + + return count; +} + +static ssize_t himax_SMWP_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + + if (buf[0] == '0') + { + ts->SMWP_enable = 0; + } + else if (buf[0] == '1') + { + ts->SMWP_enable = 1; + } + else + return -EINVAL; + + himax_set_SMWP_enable(ts->client, ts->SMWP_enable, ts->suspended); + + HX_SMWP_EN = ts->SMWP_enable; + I("%s: SMART_WAKEUP_enable = %d.\n", __func__, HX_SMWP_EN); + + return len; +} + +static struct file_operations himax_proc_SMWP_ops = +{ + .owner = THIS_MODULE, + .read = himax_SMWP_read, + .write = himax_SMWP_write, +}; + +static ssize_t himax_GESTURE_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + int i =0; + int ret = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + if(!HX_PROC_SEND_FLAG) + { + for(i=0; i<16; i++) + ret += sprintf(temp_buf + ret, "ges_en[%d]=%d \n",i,ts->gesture_cust_en[i]); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG = 1; + } + else + { + HX_PROC_SEND_FLAG = 0; + ret = 0; + } + return ret; +} + +static ssize_t himax_GESTURE_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + struct himax_ts_data *ts = private_ts; + int i =0; + char buf[80] = {0}; + + if (len >= 80) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + I("himax_GESTURE_store= %s \n",buf); + for (i=0; i<16; i++) + { + if (buf[i] == '0') + ts->gesture_cust_en[i]= 0; + else if (buf[i] == '1') + ts->gesture_cust_en[i]= 1; + else + ts->gesture_cust_en[i]= 0; + I("gesture en[%d]=%d \n", i, ts->gesture_cust_en[i]); + } + return len; +} + +static struct file_operations himax_proc_Gesture_ops = +{ + .owner = THIS_MODULE, + .read = himax_GESTURE_read, + .write = himax_GESTURE_write, +}; +#endif + +#ifdef HX_ESD_RECOVERY +static ssize_t himax_esd_cnt_read(struct file *file, char *buf, + size_t len, loff_t *pos) +{ + int ret = 0; + char *temp_buf; + + temp_buf = kzalloc(len,GFP_KERNEL); + + I("%s: enter, %d \n", __func__, __LINE__); + if(!HX_PROC_SEND_FLAG) + { + ret += sprintf(temp_buf + ret, "EB_cnt = %d, EC_cnt = %d, ED_cnt = %d\n",hx_EB_event_flag, hx_EC_event_flag, hx_ED_event_flag); + if(copy_to_user(buf, temp_buf, len)) + I("%s,here:%d\n",__func__,__LINE__); + kfree(temp_buf); + HX_PROC_SEND_FLAG=1; + } + else + HX_PROC_SEND_FLAG=0; + return ret; +} + +static ssize_t himax_esd_cnt_write(struct file *file, const char *buff, + size_t len, loff_t *pos) +{ + int i =0; + char buf[12] = {0}; + + if (len >= 12) + { + I("%s: no command exceeds 80 chars.\n", __func__); + return -EFAULT; + } + if (copy_from_user(buf, buff, len)) + { + return -EFAULT; + } + + I("Clear ESD Flag \n"); + if (buf[i] == '0') + { + hx_EB_event_flag = 0; + hx_EC_event_flag = 0; + hx_ED_event_flag = 0; + } + + return len; +} + +static struct file_operations himax_proc_esd_cnt_ops = +{ + .owner = THIS_MODULE, + .read = himax_esd_cnt_read, + .write = himax_esd_cnt_write, +}; +#endif + +int himax_touch_proc_init(void) +{ + himax_touch_proc_dir = proc_mkdir( HIMAX_PROC_TOUCH_FOLDER, NULL); + if (himax_touch_proc_dir == NULL) + { + E(" %s: himax_touch_proc_dir file create failed!\n", __func__); + return -ENOMEM; + } + + himax_proc_debug_level_file = proc_create(HIMAX_PROC_DEBUG_LEVEL_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_debug_level_ops); + if (himax_proc_debug_level_file == NULL) + { + E(" %s: proc debug_level file create failed!\n", __func__); + goto fail_1; + } + + himax_proc_vendor_file = proc_create(HIMAX_PROC_VENDOR_FILE, (S_IRUGO), + himax_touch_proc_dir, &himax_proc_vendor_ops); + if(himax_proc_vendor_file == NULL) + { + E(" %s: proc vendor file create failed!\n", __func__); + goto fail_2; + } + + himax_proc_attn_file = proc_create(HIMAX_PROC_ATTN_FILE, (S_IRUGO), + himax_touch_proc_dir, &himax_proc_attn_ops); + if(himax_proc_attn_file == NULL) + { + E(" %s: proc attn file create failed!\n", __func__); + goto fail_3; + } + + himax_proc_int_en_file = proc_create(HIMAX_PROC_INT_EN_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_int_en_ops); + if(himax_proc_int_en_file == NULL) + { + E(" %s: proc int en file create failed!\n", __func__); + goto fail_4; + } + + himax_proc_layout_file = proc_create(HIMAX_PROC_LAYOUT_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_layout_ops); + if(himax_proc_layout_file == NULL) + { + E(" %s: proc layout file create failed!\n", __func__); + goto fail_5; + } + +#ifdef HX_TP_PROC_RESET + himax_proc_reset_file = proc_create(HIMAX_PROC_RESET_FILE, (S_IWUSR), + himax_touch_proc_dir, &himax_proc_reset_ops); + if(himax_proc_reset_file == NULL) + { + E(" %s: proc reset file create failed!\n", __func__); + goto fail_6; + } +#endif + +#ifdef HX_TP_PROC_DIAG + himax_proc_diag_file = proc_create(HIMAX_PROC_DIAG_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_diag_ops); + if(himax_proc_diag_file == NULL) + { + E(" %s: proc diag file create failed!\n", __func__); + goto fail_7; + } + himax_proc_diag_arrange_file = proc_create(HIMAX_PROC_DIAG_ARR_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_diag_arrange_ops); + if(himax_proc_diag_arrange_file == NULL) + { + E(" %s: proc diag file create failed!\n", __func__); + goto fail_7_1; + } +#endif + +#ifdef HX_TP_PROC_REGISTER + himax_proc_register_file = proc_create(HIMAX_PROC_REGISTER_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_register_ops); + if(himax_proc_register_file == NULL) + { + E(" %s: proc register file create failed!\n", __func__); + goto fail_8; + } +#endif + +#ifdef HX_TP_PROC_DEBUG + himax_proc_debug_file = proc_create(HIMAX_PROC_DEBUG_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_debug_ops); + if(himax_proc_debug_file == NULL) + { + E(" %s: proc debug file create failed!\n", __func__); + goto fail_9; + } + + himax_proc_fw_debug_file = proc_create(HIMAX_PROC_FW_DEBUG_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_fw_debug_ops); + if(himax_proc_fw_debug_file == NULL) + { + E(" %s: proc fw debug file create failed!\n", __func__); + goto fail_9_1; + } + + himax_proc_dd_debug_file = proc_create(HIMAX_PROC_DD_DEBUG_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_dd_debug_ops); + if(himax_proc_dd_debug_file == NULL) + { + E(" %s: proc DD debug file create failed!\n", __func__); + goto fail_9_2; + } +#endif + +#ifdef HX_TP_PROC_FLASH_DUMP + himax_proc_flash_dump_file = proc_create(HIMAX_PROC_FLASH_DUMP_FILE, (S_IWUSR|S_IRUGO), + himax_touch_proc_dir, &himax_proc_flash_ops); + if(himax_proc_flash_dump_file == NULL) + { + E(" %s: proc flash dump file create failed!\n", __func__); + goto fail_10; + } +#endif + +#ifdef HX_TP_PROC_SELF_TEST + himax_proc_self_test_file = proc_create(HIMAX_PROC_SELF_TEST_FILE, (S_IRUGO), + himax_touch_proc_dir, &himax_proc_self_test_ops); + if(himax_proc_self_test_file == NULL) + { + E(" %s: proc self_test file create failed!\n", __func__); + goto fail_11; + } +#endif + +#ifdef HX_HIGH_SENSE + himax_proc_HSEN_file = proc_create(HIMAX_PROC_HSEN_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), + himax_touch_proc_dir, &himax_proc_HSEN_ops); + if(himax_proc_HSEN_file == NULL) + { + E(" %s: proc HSEN file create failed!\n", __func__); + goto fail_13; + } +#endif + +#ifdef HX_SMART_WAKEUP + himax_proc_SMWP_file = proc_create(HIMAX_PROC_SMWP_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), + himax_touch_proc_dir, &himax_proc_SMWP_ops); + if(himax_proc_SMWP_file == NULL) + { + E(" %s: proc SMWP file create failed!\n", __func__); + goto fail_14; + } + himax_proc_GESTURE_file = proc_create(HIMAX_PROC_GESTURE_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), + himax_touch_proc_dir, &himax_proc_Gesture_ops); + if(himax_proc_GESTURE_file == NULL) + { + E(" %s: proc GESTURE file create failed!\n", __func__); + goto fail_15; + } +#endif + +#ifdef HX_TP_PROC_SENSE_ON_OFF + himax_proc_SENSE_ON_OFF_file = proc_create(HIMAX_PROC_SENSE_ON_OFF_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), + himax_touch_proc_dir, &himax_proc_sense_on_off_ops); + if(himax_proc_SENSE_ON_OFF_file == NULL) + { + E(" %s: proc SENSE_ON_OFF file create failed!\n", __func__); + goto fail_16; + } +#endif +#ifdef HX_ESD_RECOVERY + himax_proc_ESD_cnt_file = proc_create(HIMAX_PROC_ESD_CNT_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), + himax_touch_proc_dir, &himax_proc_esd_cnt_ops); + if(himax_proc_ESD_cnt_file == NULL) + { + E(" %s: proc ESD cnt file create failed!\n", __func__); + goto fail_17; + } +#endif + himax_proc_CRC_test_file = proc_create(HIMAX_PROC_CRC_TEST_FILE, (S_IWUSR|S_IRUGO|S_IWUGO), + himax_touch_proc_dir, &himax_proc_CRC_test_ops); + if(himax_proc_CRC_test_file == NULL) + { + E(" %s: proc CRC test file create failed!\n", __func__); + goto fail_18; + } + return 0 ; + +fail_18: +#ifdef HX_ESD_RECOVERY + remove_proc_entry( HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir ); +fail_17: +#endif +#ifdef HX_TP_PROC_SENSE_ON_OFF + remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir ); +fail_16: +#endif +#ifdef HX_SMART_WAKEUP + remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir ); +fail_15: + remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir ); +fail_14: +#endif +#ifdef HX_HIGH_SENSE + remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir ); +fail_13: +#endif +#ifdef HX_TP_PROC_SELF_TEST + remove_proc_entry( HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir ); +fail_11: +#endif +#ifdef HX_TP_PROC_FLASH_DUMP + remove_proc_entry( HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir ); +fail_10: +#endif +#ifdef HX_TP_PROC_DEBUG + remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir ); +fail_9: + remove_proc_entry( HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir ); +fail_9_1: + remove_proc_entry( HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir ); +fail_9_2: +#endif +#ifdef HX_TP_PROC_REGISTER + remove_proc_entry( HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir ); +fail_8: +#endif +#ifdef HX_TP_PROC_DIAG + remove_proc_entry( HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir ); +fail_7: + remove_proc_entry( HIMAX_PROC_DIAG_ARR_FILE, himax_touch_proc_dir ); +fail_7_1: +#endif +#ifdef HX_TP_PROC_RESET + remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir ); +fail_6: +#endif + remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir ); +fail_5: + remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir ); +fail_4: + remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir ); +fail_3: + remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir ); +fail_2: + remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir ); +fail_1: + remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL ); + return -ENOMEM; +} + +void himax_touch_proc_deinit(void) +{ + remove_proc_entry( HIMAX_PROC_CRC_TEST_FILE, himax_touch_proc_dir ); +#ifdef HX_ESD_RECOVERY + remove_proc_entry( HIMAX_PROC_ESD_CNT_FILE, himax_touch_proc_dir ); +#endif +#ifdef HX_TP_PROC_SENSE_ON_OFF + remove_proc_entry( HIMAX_PROC_SENSE_ON_OFF_FILE, himax_touch_proc_dir ); +#endif +#ifdef HX_SMART_WAKEUP + remove_proc_entry( HIMAX_PROC_GESTURE_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_SMWP_FILE, himax_touch_proc_dir ); +#endif +#ifdef HX_DOT_VIEW + remove_proc_entry( HIMAX_PROC_HSEN_FILE, himax_touch_proc_dir ); +#endif +#ifdef HX_TP_PROC_SELF_TEST + remove_proc_entry(HIMAX_PROC_SELF_TEST_FILE, himax_touch_proc_dir); +#endif +#ifdef HX_TP_PROC_FLASH_DUMP + remove_proc_entry(HIMAX_PROC_FLASH_DUMP_FILE, himax_touch_proc_dir); +#endif +#ifdef HX_TP_PROC_DEBUG + remove_proc_entry( HIMAX_PROC_DEBUG_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_FW_DEBUG_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_DD_DEBUG_FILE, himax_touch_proc_dir ); +#endif +#ifdef HX_TP_PROC_REGISTER + remove_proc_entry(HIMAX_PROC_REGISTER_FILE, himax_touch_proc_dir); +#endif +#ifdef HX_TP_PROC_DIAG + remove_proc_entry(HIMAX_PROC_DIAG_FILE, himax_touch_proc_dir); +#endif +#ifdef HX_TP_PROC_RESET + remove_proc_entry( HIMAX_PROC_RESET_FILE, himax_touch_proc_dir ); +#endif + remove_proc_entry( HIMAX_PROC_LAYOUT_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_INT_EN_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_ATTN_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_VENDOR_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_DEBUG_LEVEL_FILE, himax_touch_proc_dir ); + remove_proc_entry( HIMAX_PROC_TOUCH_FOLDER, NULL ); +} +#endif diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_debug.h b/drivers/input/touchscreen/hxchipset83112b/himax_debug.h new file mode 100755 index 000000000000..925d5e0f43e2 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_debug.h @@ -0,0 +1,213 @@ +/* Himax Android Driver Sample Code for debug nodes +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 H_HIMAX_DEBUG +#define H_HIMAX_DEBUG + +#include "himax_platform.h" +#include "himax_common.h" + + +#ifdef HX_ESD_RECOVERY +extern u8 HX_ESD_RESET_ACTIVATE; +extern int hx_EB_event_flag; +extern int hx_EC_event_flag; +extern int hx_ED_event_flag; +#endif + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) +#define HIMAX_PROC_TOUCH_FOLDER "android_touch" +#define HIMAX_PROC_DEBUG_LEVEL_FILE "debug_level" +#define HIMAX_PROC_VENDOR_FILE "vendor" +#define HIMAX_PROC_ATTN_FILE "attn" +#define HIMAX_PROC_INT_EN_FILE "int_en" +#define HIMAX_PROC_LAYOUT_FILE "layout" +#define HIMAX_PROC_CRC_TEST_FILE "CRC_test" + +static struct proc_dir_entry *himax_touch_proc_dir = NULL; +static struct proc_dir_entry *himax_proc_debug_level_file = NULL; +static struct proc_dir_entry *himax_proc_vendor_file = NULL; +static struct proc_dir_entry *himax_proc_attn_file = NULL; +static struct proc_dir_entry *himax_proc_int_en_file = NULL; +static struct proc_dir_entry *himax_proc_layout_file = NULL; +static struct proc_dir_entry *himax_proc_CRC_test_file = NULL; + +uint8_t HX_PROC_SEND_FLAG; + +extern int himax_touch_proc_init(void); +extern void himax_touch_proc_deinit(void); +bool getFlashDumpGoing(void); + +extern int himax_int_en_set(struct i2c_client *client); + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_ITO_TEST) +#define HIMAX_PROC_ITO_TEST_FILE "ITO_test" +static struct proc_dir_entry *himax_proc_ito_test_file = NULL; + +extern void ito_set_step_status(uint8_t status); +extern uint8_t ito_get_step_status(void); +extern void ito_set_result_status(uint8_t status); +extern uint8_t ito_get_result_status(void); + +#endif + +#ifdef HX_TP_PROC_REGISTER +#define HIMAX_PROC_REGISTER_FILE "register" +struct proc_dir_entry *himax_proc_register_file = NULL; +uint8_t byte_length = 0; +uint8_t register_command[4]; +bool cfg_flag = false; +#endif + +#ifdef HX_TP_PROC_DIAG +#define HIMAX_PROC_DIAG_FILE "diag" +struct proc_dir_entry *himax_proc_diag_file = NULL; +#define HIMAX_PROC_DIAG_ARR_FILE "diag_arr" +struct proc_dir_entry *himax_proc_diag_arrange_file = NULL; +struct file *diag_sram_fn; +uint8_t write_counter = 0; +uint8_t write_max_count = 30; +#define IIR_DUMP_FILE "/sdcard/HX_IIR_Dump.txt" +#define DC_DUMP_FILE "/sdcard/HX_DC_Dump.txt" +#define BANK_DUMP_FILE "/sdcard/HX_BANK_Dump.txt" + +#ifdef HX_TP_PROC_2T2R +static uint8_t x_channel_2 = 0; +static uint8_t y_channel_2 = 0; +static uint32_t *diag_mutual_2 = NULL; + +int32_t *getMutualBuffer_2(void); +uint8_t getXChannel_2(void); +uint8_t getYChannel_2(void); + +void setMutualBuffer_2(void); +void setXChannel_2(uint8_t x); +void setYChannel_2(uint8_t y); +#endif +uint8_t x_channel = 0; +uint8_t y_channel = 0; + int32_t *diag_mutual = NULL; + int32_t *diag_mutual_new = NULL; + int32_t *diag_mutual_old = NULL; +uint8_t diag_max_cnt = 0; +uint8_t hx_state_info[2] = {0}; + +int g_diag_command = 0; +uint8_t diag_coor[128];// = {0xFF}; + int32_t diag_self[100] = {0}; + + int32_t *getMutualBuffer(void); + int32_t *getMutualNewBuffer(void); + int32_t *getMutualOldBuffer(void); + int32_t *getSelfBuffer(void); +uint8_t getDiagCommand(void); +uint8_t getXChannel(void); +uint8_t getYChannel(void); + +void setMutualBuffer(void); +void setMutualNewBuffer(void); +void setMutualOldBuffer(void); +void setXChannel(uint8_t x); +void setYChannel(uint8_t y); +#endif + +#ifdef HX_TP_PROC_DEBUG +#define HIMAX_PROC_DEBUG_FILE "debug" +struct proc_dir_entry *himax_proc_debug_file = NULL; +#define HIMAX_PROC_FW_DEBUG_FILE "FW_debug" +struct proc_dir_entry *himax_proc_fw_debug_file = NULL; +#define HIMAX_PROC_DD_DEBUG_FILE "DD_debug" +struct proc_dir_entry *himax_proc_dd_debug_file = NULL; + +bool fw_update_complete = false; +int handshaking_result = 0; +unsigned char debug_level_cmd = 0; +unsigned char upgrade_fw[128*1024]; +uint8_t cmd_set[8]; +uint8_t mutual_set_flag = 0; +#endif + +#ifdef HX_TP_PROC_FLASH_DUMP +#define HIMAX_PROC_FLASH_DUMP_FILE "flash_dump" +struct proc_dir_entry *himax_proc_flash_dump_file = NULL; + +static int Flash_Size = 131072; +static uint8_t *flash_buffer = NULL; +static uint8_t flash_command = 0; +static uint8_t flash_read_step = 0; +static uint8_t flash_progress = 0; +static uint8_t flash_dump_complete = 0; +static uint8_t flash_dump_fail = 0; +static uint8_t sys_operation = 0; +static bool flash_dump_going = false; + +static uint8_t getFlashDumpComplete(void); +static uint8_t getFlashDumpFail(void); +static uint8_t getFlashDumpProgress(void); +static uint8_t getFlashReadStep(void); +uint8_t getFlashCommand(void); +uint8_t getSysOperation(void); + +static void setFlashCommand(uint8_t command); +static void setFlashReadStep(uint8_t step); + +void setFlashBuffer(void); +void setFlashDumpComplete(uint8_t complete); +void setFlashDumpFail(uint8_t fail); +void setFlashDumpProgress(uint8_t progress); +void setSysOperation(uint8_t operation); +void setFlashDumpGoing(bool going); + +#endif + +#ifdef HX_TP_PROC_SELF_TEST +#define HIMAX_PROC_SELF_TEST_FILE "self_test" +struct proc_dir_entry *himax_proc_self_test_file = NULL; +uint32_t **raw_data_array; +uint8_t X_NUM = 0, Y_NUM = 0; +uint8_t sel_type = 0x0D; +#endif + +#ifdef HX_TP_PROC_RESET +#define HIMAX_PROC_RESET_FILE "reset" +struct proc_dir_entry *himax_proc_reset_file = NULL; +#endif + +#ifdef HX_HIGH_SENSE +#define HIMAX_PROC_HSEN_FILE "HSEN" +struct proc_dir_entry *himax_proc_HSEN_file = NULL; +#endif + +#ifdef HX_TP_PROC_SENSE_ON_OFF +#define HIMAX_PROC_SENSE_ON_OFF_FILE "SenseOnOff" +struct proc_dir_entry *himax_proc_SENSE_ON_OFF_file = NULL; +#endif + +#ifdef HX_SMART_WAKEUP +#define HIMAX_PROC_SMWP_FILE "SMWP" +struct proc_dir_entry *himax_proc_SMWP_file = NULL; +#define HIMAX_PROC_GESTURE_FILE "GESTURE" +struct proc_dir_entry *himax_proc_GESTURE_file = NULL; +uint8_t HX_SMWP_EN = 0; +//extern bool FAKE_POWER_KEY_SEND; +#endif + +#ifdef HX_ESD_RECOVERY +#define HIMAX_PROC_ESD_CNT_FILE "ESD_cnt" +struct proc_dir_entry *himax_proc_ESD_cnt_file = NULL; +#endif + +#endif + +#endif diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_ic.c b/drivers/input/touchscreen/hxchipset83112b/himax_ic.c new file mode 100755 index 000000000000..e0922d798e21 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_ic.c @@ -0,0 +1,3224 @@ +/* Himax Android Driver Sample Code for HX83112 chipset +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 "himax_ic.h" +#include "himax_common.h" + +extern int i2c_error_count; +extern int reset_flag; + +extern unsigned long FW_VER_MAJ_FLASH_ADDR; +extern unsigned long FW_VER_MIN_FLASH_ADDR; +extern unsigned long CFG_VER_MAJ_FLASH_ADDR; +extern unsigned long CFG_VER_MIN_FLASH_ADDR; +extern unsigned long CID_VER_MAJ_FLASH_ADDR; +extern unsigned long CID_VER_MIN_FLASH_ADDR; + +extern unsigned long FW_VER_MAJ_FLASH_LENG; +extern unsigned long FW_VER_MIN_FLASH_LENG; +extern unsigned long CFG_VER_MAJ_FLASH_LENG; +extern unsigned long CFG_VER_MIN_FLASH_LENG; +extern unsigned long CID_VER_MAJ_FLASH_LENG; +extern unsigned long CID_VER_MIN_FLASH_LENG; + +#ifdef HX_AUTO_UPDATE_FW +extern int g_i_FW_VER; +extern int g_i_CFG_VER; +extern int g_i_CID_MAJ; +extern int g_i_CID_MIN; +//extern unsigned char i_CTPM_FW[]; +extern unsigned char i_CTPM_FW_HX83112A[]; +extern unsigned char i_CTPM_FW_HX83112B[]; +#endif + +extern unsigned char IC_TYPE; +extern unsigned char IC_CHECKSUM; + +extern bool DSRAM_Flag; + +extern struct himax_ic_data* ic_data; +extern struct himax_ts_data *private_ts; + +int himax_touch_data_size = 128; + +#ifdef HX_TP_PROC_2T2R +bool Is_2T2R = false; +#endif + +#ifdef HX_USB_DETECT_GLOBAL +//extern kal_bool upmu_is_chr_det(void); +extern void himax_cable_detect_func(bool force_renew); +#endif + +int himax_get_touch_data_size(void) +{ + return himax_touch_data_size; +} + +#ifdef HX_RST_PIN_FUNC +extern void himax_rst_gpio_set(int pinnum, uint8_t value); +extern int himax_report_data_init(void); +extern u8 HX_HW_RESET_ACTIVATE; + +void himax_pin_reset(void) +{ + I("%s: Now reset the Touch chip.\n", __func__); + himax_rst_gpio_set(private_ts->rst_gpio, 0); + msleep(20); + himax_rst_gpio_set(private_ts->rst_gpio, 1); +#if 0 + msleep(20); +#endif +} + +void himax_reload_config(void) +{ + if(himax_report_data_init()) + E("%s: allocate data fail\n",__func__); + + himax_sense_on(private_ts->client, 0x00); +} + +void himax_irq_switch(int switch_on) +{ + int ret = 0; + if(switch_on) + { + + if (private_ts->use_irq) + himax_int_enable(private_ts->client->irq,switch_on); + else + hrtimer_start(&private_ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + } + else + { + if (private_ts->use_irq) + himax_int_enable(private_ts->client->irq,switch_on); + else + { + hrtimer_cancel(&private_ts->timer); + ret = cancel_work_sync(&private_ts->work); + } + } +} + +void himax_ic_reset(uint8_t loadconfig,uint8_t int_off) +{ +#ifdef HX_RST_PIN_FUNC +if (reset_flag ==1){ + struct himax_ts_data *ts = private_ts; + + HX_HW_RESET_ACTIVATE = 1; + + I("%s,status: loadconfig=%d,int_off=%d\n",__func__,loadconfig,int_off); + + if (ts->rst_gpio) + { + if(int_off) + { + himax_irq_switch(0); + } + + himax_pin_reset(); + if(loadconfig) + { + himax_reload_config(); + } + if(int_off) + { + himax_irq_switch(1); + } + } +} +#endif +} +#endif + +#if defined(HX_ESD_RECOVERY) +int g_zero_event_count = 0; +int himax_ic_esd_recovery(int hx_esd_event,int hx_zero_event,int length) +{ + if(g_zero_event_count > 5) + { + g_zero_event_count = 0; + I("[HIMAX TP MSG]: ESD event checked - ALL Zero.\n"); + goto checksum_fail; + } + + if(hx_esd_event == length) + { + g_zero_event_count = 0; + goto checksum_fail; + } + else if(hx_zero_event == length) + { + g_zero_event_count++; + I("[HIMAX TP MSG]: ALL Zero event is %d times.\n",g_zero_event_count); + goto err_workqueue_out; + } + +checksum_fail: + return CHECKSUM_FAIL; +err_workqueue_out: + return WORK_OUT; +} +void himax_esd_ic_reset(void) +{ + /*Nothing to do in incell,need to follow display reset*/ +} +#endif + +int himax_hand_shaking(struct i2c_client *client) //0:Running, 1:Stop, 2:I2C Fail +{ + int result = 0; + + return result; +} + +void himax_idle_mode(struct i2c_client *client,int disable) +{ + int retry = 20; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t switch_cmd = 0x00; + + I("%s:entering\n",__func__); + do + { + + I("%s,now %d times\n!",__func__,retry); + + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x70; + tmp_addr[0] = 0x88; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + if(disable) + switch_cmd = 0x17; + else + switch_cmd = 0x1F; + + tmp_data[0] = switch_cmd; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + himax_register_read(client, tmp_addr, 4, tmp_data, false); + I("%s:After turn ON/OFF IDLE Mode [0] = 0x%02X,[1] = 0x%02X,[2] = 0x%02X,[3] = 0x%02X\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); + + retry--; + msleep(10); + + } + while((tmp_data[0] != switch_cmd) && retry > 0); + + I("%s: setting OK!\n",__func__); + +} + +int himax_write_read_reg(struct i2c_client *client,uint8_t *tmp_addr,uint8_t *tmp_data,uint8_t hb,uint8_t lb) +{ + int cnt = 0; + + do + { + himax_flash_write_burst(client, tmp_addr, tmp_data); + + msleep(10); + himax_register_read(client, tmp_addr, 4, tmp_data, false); + //I("%s:Now tmp_data[0]=0x%02X,[1]=0x%02X,[2]=0x%02X,[3]=0x%02X\n",__func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3]); + } + while((tmp_data[1] != hb && tmp_data[0] != lb) && cnt++ < 100); + + if(cnt == 99) + return -1; + + I("Now register 0x%08X : high byte=0x%02X,low byte=0x%02X\n",tmp_addr[3],tmp_data[1],tmp_data[0]); + return NO_ERR; +} + +int himax_determin_diag_rawdata(int diag_command) +{ + return diag_command%10; +} + +int himax_determin_diag_storage(int diag_command) +{ + return diag_command/10; +} + +void himax_reload_disable(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + I("%s:entering\n",__func__); + + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xA5; tmp_data[0] = 0x5A; + + himax_flash_write_burst(client, tmp_addr, tmp_data); + + I("%s: setting OK!\n",__func__); +} + +int himax_switch_mode(struct i2c_client *client,int mode) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t mode_wirte_cmd; + uint8_t mode_read_cmd; + int result = -1; + int retry = 200; + + I("%s: Entering\n",__func__); + + if(mode == 0) /*normal mode*/ + { + mode_wirte_cmd = 0x00; + mode_read_cmd = 0x99; + } + else /*sorting mode*/ + { + mode_wirte_cmd = 0xAA; + mode_read_cmd = 0xCC; + } + + himax_sense_off(client); + + //himax_interface_on(client); + + /* */ + + /* clean up FW status */ + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + //msleep(30); + + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x04; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = mode_wirte_cmd; + tmp_data[0] = mode_wirte_cmd; + himax_flash_write_burst(client, tmp_addr, tmp_data); + //msleep(30); + + himax_idle_mode(client,1); + himax_reload_disable(client); + + // To stable the sorting //skip frames + if(mode) + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x70; + tmp_addr[0] = 0xF4; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x08; + himax_flash_write_burst(client, tmp_addr, tmp_data); + } + else + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x72; + tmp_addr[0] = 0x94; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x50;/*0x50 normal mode 80 frame*/ + /* N Frame Sorting*/ + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x70; + tmp_addr[0] = 0xF4; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x14; + himax_flash_write_burst(client, tmp_addr, tmp_data); + } + + himax_sense_on(client,0x01); + I("mode_wirte_cmd(0)=0x%2.2X,mode_wirte_cmd(1)=0x%2.2X\n",tmp_data[0],tmp_data[1]); + while(retry!=0) + { + I("[%d]Read 10007F04!\n",retry); + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x04; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + msleep(100); + I("mode_read_cmd(0)=0x%2.2X,mode_read_cmd(1)=0x%2.2X\n",tmp_data[0],tmp_data[1]); + if(tmp_data[0] == mode_read_cmd && tmp_data[1] == mode_read_cmd) + { + I("Read OK!\n"); + result = 0; + break; + } + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0xA8; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + if(tmp_data[0] == 0x00 && tmp_data[1] == 0x00 && tmp_data[2] == 0x00 && tmp_data[3] == 0x00) + { + E("%s,: FW Stop!\n",__func__); + break; + } + retry--; + } + + if(result == 0) + { + if(mode == 0) + return 1; //normal mode + else + return 2; //sorting mode + } + else + return -1; //change mode fail +} + +void himax_return_event_stack(struct i2c_client *client) +{ + int retry = 20; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + I("%s:entering\n",__func__); + do + { + + I("%s,now %d times\n!",__func__,retry); + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + himax_register_read(client, tmp_addr, 4, tmp_data, false); + retry--; + msleep(10); + + } + while((tmp_data[1] != 0x00 && tmp_data[0] != 0x00) && retry > 0); + + I("%s: End of setting!\n",__func__); + +} + +void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + I("diag_command = %d\n", diag_command ); + + himax_interface_on(client); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x02; + tmp_addr[1] = 0x04; + tmp_addr[0] = 0xB4; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = diag_command; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + himax_register_read(client, tmp_addr, 4, tmp_data, false); + I("%s: tmp_data[3]=0x%02X,tmp_data[2]=0x%02X,tmp_data[1]=0x%02X,tmp_data[0]=0x%02X!\n", + __func__,tmp_data[3],tmp_data[2],tmp_data[1],tmp_data[0]); + +} + +void himax_init_psl(struct i2c_client *client) //power saving level +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + //============================================================== + // SCU_Power_State_PW : 0x9000_00A0 ==> 0x0000_0000 (Reset PSL) + //============================================================== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0xA0; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_register_write(client, tmp_addr, 4, tmp_data, false); + + I("%s: power saving level reset OK!\n",__func__); +} + +void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer) +{ + uint8_t tmp_addr[4]; + uint8_t buffer[256]; + int page_prog_start = 0; + + himax_sense_off(client); + himax_burst_enable(client, 1); + + for (page_prog_start = 0; page_prog_start < Flash_Size; page_prog_start = page_prog_start + 128) + { + + tmp_addr[0] = page_prog_start % 0x100; + tmp_addr[1] = (page_prog_start >> 8) % 0x100; + tmp_addr[2] = (page_prog_start >> 16) % 0x100; + tmp_addr[3] = page_prog_start / 0x1000000; + himax_register_read(client, tmp_addr,128,buffer,false); + memcpy(&flash_buffer[page_prog_start],buffer,128); + } + + himax_burst_enable(client, 0); + himax_sense_on(client, 0x01); + + return; + +} + +int himax_chip_self_test(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[128]; + uint8_t self_test_info[24]; + int pf_value=0x00; + uint8_t test_result_id = 0; + int i; + + memset(tmp_addr, 0x00, sizeof(tmp_addr)); + memset(tmp_data, 0x00, sizeof(tmp_data)); + + himax_interface_on(client); + himax_sense_off(client); + + + himax_burst_enable(client, 1); + + // 0x10007f18 -> 0x00006AA6 + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x6A; + tmp_data[0] = 0xA6; + himax_flash_write_burst(client, tmp_addr, tmp_data); + //Set criteria 0x10007F1C [0,1]=aa/up,down=, [2-3]=key/up,down, [4-5]=avg/up,down + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x1C; + if(IC_TYPE == HX_83112A_SERIES_PWON) + { + tmp_data[3] = 0x00; + tmp_data[2] = 0x64; + tmp_data[1] = 0x08; + tmp_data[0] = 0x32; + tmp_data[7] = 0x00; + tmp_data[6] = 0x00; + tmp_data[5] = 0x00; + tmp_data[4] = 0x64; + } + else/*HX_83112B_SERIES_PWON*/ + { + tmp_data[3] = 0x00; + tmp_data[2] = 0x64; + tmp_data[1] = 0x0F; + tmp_data[0] = 0x46; + tmp_data[7] = 0x00; + tmp_data[6] = 0x00; + tmp_data[5] = 0x00; + tmp_data[4] = 0x64; + } + himax_flash_write_burst_lenth(client, tmp_addr, tmp_data, 8); + // 0x10007294 -> 0x0000190 //SET IIR_MAX FRAMES + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x01; + tmp_data[0] = 0x90; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //Disable IDLE Mode + himax_idle_mode(client,1); + + // 0x10007f00 -> 0x0000A55A //Diable Flash Reload + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0xA5; + tmp_data[0] = 0x5A; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + + //start selftest // leave safe mode + himax_sense_on(client, 1); + + //Hand shaking -> 0x100007f8 waiting 0xA66A + for(i = 0; i < 1000; i++) + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x18; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3],i); + msleep(10); + if(tmp_data[1] == 0xA6 && tmp_data[0] == 0x6A ) + { + I("%s Data ready goto moving data\n", __func__); + break; + } + } + + himax_sense_off(client); + msleep(20); + + //===================================== + // Read test result ID : 0x10007f24 ==> bit[2][1][0] = [key][AA][avg] => 0xF = PASS + //===================================== + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x24; + himax_register_read(client, tmp_addr, 24, self_test_info, false); + + test_result_id = self_test_info[0]; + + I("%s: check test result, test_result_id=%x, test_result=%x\n", __func__ + ,test_result_id,self_test_info[0]); + + I("raw top 1 = %d\n",self_test_info[3]*256+self_test_info[2]); + I("raw top 2 = %d\n",self_test_info[5]*256+self_test_info[4]); + I("raw top 3 = %d\n",self_test_info[7]*256+self_test_info[6]); + + I("raw last 1 = %d\n",self_test_info[9]*256+self_test_info[8]); + I("raw last 2 = %d\n",self_test_info[11]*256+self_test_info[10]); + I("raw last 3 = %d\n",self_test_info[13]*256+self_test_info[12]); + + I("raw key 1 = %d\n",self_test_info[15]*256+self_test_info[14]); + I("raw key 2 = %d\n",self_test_info[17]*256+self_test_info[16]); + I("raw key 3 = %d\n",self_test_info[19]*256+self_test_info[18]); + + if (test_result_id==0xAA) + { + I("[Himax]: self-test pass\n"); + pf_value = 0x1; + } + else + { + E("[Himax]: self-test fail\n"); + /* E("[Himax]: bank_avg = %d, bank_max = %d,%d,%d, bank_min = %d,%d,%d, key = %d,%d,%d\n", + tmp_data[1],tmp_data[2],tmp_data[3],tmp_data[4],tmp_data[5],tmp_data[6],tmp_data[7], + tmp_data[8],tmp_data[9],tmp_data[10]); */ + pf_value = 0x0; + } + + //Enable IDLE Mode + himax_idle_mode(client,0); + + // 0x10007f00 -> 0x00000000 //Enable Flash Reload //recovery + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + himax_sense_on(client, 0); + msleep(120); + + return pf_value; +} + +void himax_set_HSEN_enable(struct i2c_client *client, uint8_t HSEN_enable, bool suspended) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t back_data[4]; + uint8_t retry_cnt = 0; + + himax_sense_off(client); + + //Enable:0x10007F14 = 0xA55AA55A + do + { + if(HSEN_enable) + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x14; + tmp_data[3] = 0xA5; + tmp_data[2] = 0x5A; + tmp_data[1] = 0xA5; + tmp_data[0] = 0x5A; + himax_flash_write_burst(client, tmp_addr, tmp_data); + back_data[3] = 0XA5; + back_data[2] = 0X5A; + back_data[1] = 0XA5; + back_data[0] = 0X5A; + } + else + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x14; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + back_data[3] = 0X00; + back_data[2] = 0X00; + back_data[1] = 0X00; + back_data[0] = 0x00; + } + himax_register_read(client, tmp_addr, 4, tmp_data, false); + //I("%s: tmp_data[0]=%d, HSEN_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],HSEN_enable,retry_cnt); + retry_cnt++; + } + while((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0] ) && retry_cnt < HIMAX_REG_RETRY_TIMES); + + himax_sense_on(client,0); +} + +int himax_palm_detect(uint8_t *buf) +{ + + return GESTURE_DETECT_FAIL; + +} + +void himax_set_SMWP_enable(struct i2c_client *client, uint8_t SMWP_enable, bool suspended) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t back_data[4]; + uint8_t retry_cnt = 0; + + himax_sense_off(client); + + //Enable:0x10007F10 = 0xA55AA55A + do + { + if(SMWP_enable) + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x10; + tmp_data[3] = 0xA5; + tmp_data[2] = 0x5A; + tmp_data[1] = 0xA5; + tmp_data[0] = 0x5A; + himax_flash_write_burst(client, tmp_addr, tmp_data); + back_data[3] = 0XA5; + back_data[2] = 0X5A; + back_data[1] = 0XA5; + back_data[0] = 0X5A; + } + else + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x10; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + back_data[3] = 0X00; + back_data[2] = 0X00; + back_data[1] = 0X00; + back_data[0] = 0x00; + } + himax_register_read(client, tmp_addr, 4, tmp_data, false); + //I("%s: tmp_data[0]=%d, SMWP_enable=%d, retry_cnt=%d \n", __func__, tmp_data[0],SMWP_enable,retry_cnt); + retry_cnt++; + } + while((tmp_data[3] != back_data[3] || tmp_data[2] != back_data[2] || tmp_data[1] != back_data[1] || tmp_data[0] != back_data[0] ) && retry_cnt < HIMAX_REG_RETRY_TIMES); + + himax_sense_on(client,0); + +} + +void himax_usb_detect_set(struct i2c_client *client,uint8_t *cable_config) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + //Enable:0x10007F38 = 0xA55AA55A + + if(cable_config[1] == 0x01) + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x38; + tmp_data[3] = 0xA5; + tmp_data[2] = 0x5A; + tmp_data[1] = 0xA5; + tmp_data[0] = 0x5A; + himax_flash_write_burst(client, tmp_addr, tmp_data); + } + else + { + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x7F; + tmp_addr[0] = 0x38; + tmp_data[3] = 0x77; + tmp_data[2] = 0x88; + tmp_data[1] = 0x77; + tmp_data[0] = 0x88; + himax_flash_write_burst(client, tmp_addr, tmp_data); + } +} + +void himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte) +{ + uint8_t tmp_data[4]; + + tmp_data[0] = 0x31; + if ( i2c_himax_write(client, 0x13,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + + tmp_data[0] = (0x10 | auto_add_4_byte); + if ( i2c_himax_write(client, 0x0D,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + + //isBusrtOn = true; +} + +void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data, bool cfg_flag) +{ + uint8_t tmp_data[4]; + int i = 0; + int address = 0; + if(cfg_flag == false) + { + if(read_length>256) + { + E("%s: read len over 256!\n", __func__); + return; + } + if (read_length > 4) + himax_burst_enable(client, 1); + else + himax_burst_enable(client, 0); + + address = (read_addr[3] << 24) + (read_addr[2] << 16) + (read_addr[1] << 8) + read_addr[0]; + i = address; + tmp_data[0] = (uint8_t)i; + tmp_data[1] = (uint8_t)(i >> 8); + tmp_data[2] = (uint8_t)(i >> 16); + tmp_data[3] = (uint8_t)(i >> 24); + if ( i2c_himax_write(client, 0x00,tmp_data, 4, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + tmp_data[0] = 0x00; + if ( i2c_himax_write(client, 0x0C,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + + if ( i2c_himax_read(client, 0x08,read_data, read_length, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + if (read_length > 4) + himax_burst_enable(client, 0); + } + else if(cfg_flag == true) + { + if(i2c_himax_read(client, read_addr[0], read_data,read_length,DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + } + else + { + E("%s: cfg_flag = %d, value is wrong!\n", __func__,cfg_flag); + return; + } +} + +void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data) +{ + uint8_t data_byte[8]; + int i = 0, j = 0; + + for (i = 0; i < 4; i++) + { + data_byte[i] = reg_byte[i]; + } + for (j = 4; j < 8; j++) + { + data_byte[j] = write_data[j-4]; + } + + if ( i2c_himax_write(client, 0x00,data_byte, 8, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + +} + +void himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length) +{ + uint8_t data_byte[256]; + int i = 0, j = 0; + + for (i = 0; i < 4; i++) + { + data_byte[i] = reg_byte[i]; + } + for (j = 4; j < length + 4; j++) + { + data_byte[j] = write_data[j - 4]; + } + + if ( i2c_himax_write(client, 0x00,data_byte, length + 4, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } +} + +void himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data, bool cfg_flag) +{ + int i =0, address = 0; + if(cfg_flag == false) + { + address = (write_addr[3] << 24) + (write_addr[2] << 16) + (write_addr[1] << 8) + write_addr[0]; + + for (i = address; i < address + write_length; i++) + { + if (write_length > 4) + { + himax_burst_enable(client, 1); + } + else + { + himax_burst_enable(client, 0); + } + himax_flash_write_burst_lenth(client, write_addr, write_data, write_length); + } + } + else if(cfg_flag == true) + { + if(i2c_himax_write(client, write_addr[0], write_data,write_length,DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + } + else + { + E("%s: cfg_flag = %d, value is wrong!\n", __func__,cfg_flag); + return; + } +} + +bool himax_sense_off(struct i2c_client *client) +{ + uint8_t cnt = 0; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + /*1225 for power on test*/ + //===================================== + // FW ISR=0 + //===================================== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x5C; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0xA5; + himax_flash_write_burst(client, tmp_addr, tmp_data); + msleep(20); + /*1225 for power on test*/ + do + { + //=========================================== + // 0x31 ==> 0x27 + //=========================================== + tmp_data[0] = 0x27; + if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + //=========================================== + // 0x32 ==> 0x95 + //=========================================== + tmp_data[0] = 0x95; + if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + + // ====================== + // Check enter_save_mode + // ====================== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0xA8; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + I("%s: Check enter_save_mode data[0]=%X \n", __func__,tmp_data[0]); + + if (tmp_data[0] == 0x0C) + { + //===================================== + // Reset TCON + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x02; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + msleep(1); + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x01; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // Reset ADC + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x02; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x94; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + msleep(1); + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x01; + himax_flash_write_burst(client, tmp_addr, tmp_data); + return true; + } + else + { + msleep(10); +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,false); +#endif + } + } + while (cnt++ < 15); + + return false; +} +bool himax_enter_safe_mode(struct i2c_client *client) +{ + uint8_t cnt = 0; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + do + { + //=========================================== + // 0x31 ==> 0x27 + //=========================================== + tmp_data[0] = 0x27; + if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + //=========================================== + // 0x32 ==> 0x95 + //=========================================== + tmp_data[0] = 0x95; + if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + + //=========================================== + // 0x31 ==> 0x00 + //=========================================== + tmp_data[0] = 0x00; + if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + msleep(10); + //=========================================== + // 0x31 ==> 0x27 + //=========================================== + tmp_data[0] = 0x27; + if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + //=========================================== + // 0x32 ==> 0x95 + //=========================================== + tmp_data[0] = 0x95; + if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return false; + } + + // ====================== + // Check enter_save_mode + // ====================== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0xA8; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + I("%s: Check enter_save_mode data[0]=%X \n", __func__,tmp_data[0]); + + if (tmp_data[0] == 0x0C) + { + //===================================== + // Reset TCON + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x02; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + msleep(1); + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x01; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // Reset ADC + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x02; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x94; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + msleep(1); + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x01; + himax_flash_write_burst(client, tmp_addr, tmp_data); + return true; + } + else + { + msleep(10); +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,false); +#endif + } + } + while (cnt++ < 15); + + return false; +} +void himax_interface_on(struct i2c_client *client) +{ + uint8_t tmp_data[5]; + uint8_t tmp_data2[2]; + int cnt = 0; + + //Read a dummy register to wake up I2C. + if ( i2c_himax_read(client, 0x08, tmp_data,4,DEFAULT_RETRY_CNT) < 0) // to knock I2C + { + E("%s: i2c access fail!\n", __func__); + return; + } + + do + { + //=========================================== + // Enable continuous burst mode : 0x13 ==> 0x31 + //=========================================== + tmp_data[0] = 0x31; + if ( i2c_himax_write(client, 0x13,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + //=========================================== + // AHB address auto +4 : 0x0D ==> 0x11 + // Do not AHB address auto +4 : 0x0D ==> 0x10 + //=========================================== + tmp_data[0] = (0x10); + if ( i2c_himax_write(client, 0x0D,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + + // Check cmd + i2c_himax_read(client, 0x13, tmp_data,1,DEFAULT_RETRY_CNT); + i2c_himax_read(client, 0x0D, tmp_data2,1,DEFAULT_RETRY_CNT); + + if (tmp_data[0] == 0x31 && tmp_data2[0] == 0x10) + { + //isBusrtOn = true; + break; + } + msleep(1); + } + while (++cnt < 10); + + if (cnt > 0) + I("%s:Polling burst mode: %d times", __func__,cnt); + +} + +bool wait_wip(struct i2c_client *client, int Timing) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t in_buffer[10]; + //uint8_t out_buffer[20]; + int retry_cnt = 0; + + //===================================== + // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x10; + tmp_data[3] = 0x00; + tmp_data[2] = 0x02; + tmp_data[1] = 0x07; + tmp_data[0] = 0x80; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + in_buffer[0] = 0x01; + + do + { + //===================================== + // SPI Transfer Control : 0x8000_0020 ==> 0x4200_0003 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x42; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x03; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // SPI Command : 0x8000_0024 ==> 0x0000_0005 + // read 0x8000_002C for 0x01, means wait success + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x05; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + in_buffer[0] = in_buffer[1] = in_buffer[2] = in_buffer[3] = 0xFF; + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x2C; + himax_register_read(client, tmp_addr, 4, in_buffer, false); + + if ((in_buffer[0] & 0x01) == 0x00) + return true; + + retry_cnt++; + + if (in_buffer[0] != 0x00 || in_buffer[1] != 0x00 || in_buffer[2] != 0x00 || in_buffer[3] != 0x00) + I("%s:Wait wip retry_cnt:%d, buffer[0]=%d, buffer[1]=%d, buffer[2]=%d, buffer[3]=%d \n", __func__, + retry_cnt,in_buffer[0],in_buffer[1],in_buffer[2],in_buffer[3]); + + if (retry_cnt > 100) + { + E("%s: Wait wip error!\n", __func__); + return false; + } + msleep(Timing); + } + while ((in_buffer[0] & 0x01) == 0x01); + return true; +} + +void himax_sense_on(struct i2c_client *client, uint8_t FlashMode) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + int retry = 0; + + I("Enter %s \n", __func__); + + himax_interface_on(client); + + if(!FlashMode) + { +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,false); +#else + //===AHBI2C_SystemReset========== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x55; + himax_register_write(client, tmp_addr, 4, tmp_data, false); +#endif + } + else + { + do + { + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x98; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x53; + himax_register_write(client, tmp_addr, 4, tmp_data, false); + + tmp_addr[0] = 0xE4; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + I("%s:Read status from IC = %X,%X\n", __func__, tmp_data[0],tmp_data[1]); + + } + while((tmp_data[1] != 0x01 || tmp_data[0] != 0x00) && retry++ < 5); + + if(retry >= 5) + { + E("%s: Fail:\n", __func__); +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,false); +#else + //===AHBI2C_SystemReset========== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x55; + himax_register_write(client, tmp_addr, 4, tmp_data, false); +#endif + } + else + { + I("%s:OK and Read status from IC = %X,%X\n", __func__, tmp_data[0],tmp_data[1]); + + /* reset code*/ + tmp_data[0] = 0x00; + if ( i2c_himax_write(client, 0x31,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + } + if ( i2c_himax_write(client, 0x32,tmp_data, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + } + + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x98; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_register_write(client, tmp_addr, 4, tmp_data, false); + } + } +} + +void himax_chip_erase(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + himax_interface_on(client); + + /* init psl */ + himax_init_psl(client); + + //===================================== + // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x10; + tmp_data[3] = 0x00; + tmp_data[2] = 0x02; + tmp_data[1] = 0x07; + tmp_data[0] = 0x80; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // Chip Erase + // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000 + // 2. 0x8000_0024 ==> 0x0000_0006 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x47; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x06; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // Chip Erase + // Erase Command : 0x8000_0024 ==> 0x0000_00C7 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0xC7; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + msleep(2000); + + if (!wait_wip(client, 100)) + E("%s:83112_Chip_Erase Fail\n", __func__); + +} + +bool himax_block_erase(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + himax_burst_enable(client, 0); + + //===================================== + // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x10; + tmp_data[3] = 0x00; + tmp_data[2] = 0x02; + tmp_data[1] = 0x07; + tmp_data[0] = 0x80; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // Chip Erase + // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000 + // 2. 0x8000_0024 ==> 0x0000_0006 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x47; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x06; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //===================================== + // Block Erase + // Erase Command : 0x8000_0028 ==> 0x0000_0000 //SPI addr + // 0x8000_0020 ==> 0x6700_0000 //control + // 0x8000_0024 ==> 0x0000_0052 //BE + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x28; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x67; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x52; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + msleep(1000); + + if (!wait_wip(client, 100)) + { + E("%s:83112_Erase Fail\n", __func__); + return false; + } + else + { + return true; + } + +} + +bool himax_sector_erase(struct i2c_client *client, int start_addr) +{ + return true; +} + +void himax_sram_write(struct i2c_client *client, uint8_t *FW_content) +{ + +} + +bool himax_sram_verify(struct i2c_client *client, uint8_t *FW_File, int FW_Size) +{ + return true; +} + +void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size) +{ + int page_prog_start = 0; + int program_length = 48; + int i = 0, j = 0, k = 0; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t buring_data[256]; // Read for flash data, 128K + // 4 bytes for 0x80002C padding + + himax_interface_on(client); + + //===================================== + // SPI Transfer Format : 0x8000_0010 ==> 0x0002_0780 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x10; + tmp_data[3] = 0x00; + tmp_data[2] = 0x02; + tmp_data[1] = 0x07; + tmp_data[0] = 0x80; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + for (page_prog_start = 0; page_prog_start < FW_Size; page_prog_start = page_prog_start + 256) + { + //msleep(5); + //===================================== + // Write Enable : 1. 0x8000_0020 ==> 0x4700_0000 + // 2. 0x8000_0024 ==> 0x0000_0006 + //===================================== + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x47; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x06; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //================================= + // SPI Transfer Control + // Set 256 bytes page write : 0x8000_0020 ==> 0x610F_F000 + // Set read start address : 0x8000_0028 ==> 0x0000_0000 + //================================= + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + tmp_data[3] = 0x61; + tmp_data[2] = 0x0F; + tmp_data[1] = 0xF0; + tmp_data[0] = 0x00; + // data bytes should be 0x6100_0000 + ((word_number)*4-1)*4096 = 0x6100_0000 + 0xFF000 = 0x610F_F000 + // Programmable size = 1 page = 256 bytes, word_number = 256 byte / 4 = 64 + himax_flash_write_burst(client, tmp_addr, tmp_data); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x28; + //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x00; // Flash start address 1st : 0x0000_0000 + + if (page_prog_start < 0x100) + { + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = (uint8_t)page_prog_start; + } + else if (page_prog_start >= 0x100 && page_prog_start < 0x10000) + { + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = (uint8_t)(page_prog_start >> 8); + tmp_data[0] = (uint8_t)page_prog_start; + } + else if (page_prog_start >= 0x10000 && page_prog_start < 0x1000000) + { + tmp_data[3] = 0x00; + tmp_data[2] = (uint8_t)(page_prog_start >> 16); + tmp_data[1] = (uint8_t)(page_prog_start >> 8); + tmp_data[0] = (uint8_t)page_prog_start; + } + + himax_flash_write_burst(client, tmp_addr, tmp_data); + + + //================================= + // Send 16 bytes data : 0x8000_002C ==> 16 bytes data + //================================= + buring_data[0] = 0x2C; + buring_data[1] = 0x00; + buring_data[2] = 0x00; + buring_data[3] = 0x80; + + for (i = /*0*/page_prog_start, j = 0; i < 16 + page_prog_start/**/; i++, j++) /// <------ bin file + { + buring_data[j + 4] = FW_content[i]; + } + + + if ( i2c_himax_write(client, 0x00,buring_data, 20, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + //================================= + // Write command : 0x8000_0024 ==> 0x0000_0002 + //================================= + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x24; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x02; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + //================================= + // Send 240 bytes data : 0x8000_002C ==> 240 bytes data + //================================= + + for (j = 0; j < 5; j++) + { + for (i = (page_prog_start + 16 + (j * 48)), k = 0; i < (page_prog_start + 16 + (j * 48)) + program_length; i++, k++) /// <------ bin file + { + buring_data[k+4] = FW_content[i];//(byte)i; + } + + if ( i2c_himax_write(client, 0x00,buring_data, program_length+4, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return; + } + + } + + if (!wait_wip(client, 1)) + E("%s:83112_Flash_Programming Fail\n", __func__); + } +} + + +bool himax_check_chip_version(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t ret_data = false; + int i = 0; + + for (i = 0; i < 5; i++) + { + // Product ID + // Touch + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0xD0; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + I("%s:Read driver IC ID = %X,%X,%X\n", __func__, tmp_data[3],tmp_data[2],tmp_data[1]); + if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2a)) + { + IC_TYPE = HX_83112A_SERIES_PWON; + ret_data = true; + break; + } + else if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2b)) + { + IC_TYPE = HX_83112B_SERIES_PWON; + ret_data = true; + break; + } + else + { + ret_data = false; + E("%s:Read driver ID register Fail:\n", __func__); + } + } + + return ret_data; +} + +bool Calculate_CRC_with_AP(unsigned char *FW_content, int CRC_from_FW, int mode) +{ + return true; +} + +uint32_t himax_hw_check_CRC(struct i2c_client *client, uint8_t *start_addr, int reload_length) +{ + uint32_t result = 0; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + int cnt = 0; + int length = reload_length / 4; + + //CRC4 // 0x8005_0020 <= from, 0x8005_0028 <= 0x0099_length + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x05; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x20; + //tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0xFB; tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, start_addr); + + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x05; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x28; + tmp_data[3] = 0x00; + tmp_data[2] = 0x99; + tmp_data[1] = (length >> 8); + tmp_data[0] = length; + himax_flash_write_burst(client, tmp_addr, tmp_data); + + cnt = 0; + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x05; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + do + { + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + if ((tmp_data[0] & 0x01) != 0x01) + { + tmp_addr[3] = 0x80; + tmp_addr[2] = 0x05; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x18; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + I("%s: tmp_data[3]=%X, tmp_data[2]=%X, tmp_data[1]=%X, tmp_data[0]=%X \n", __func__, tmp_data[3], tmp_data[2], tmp_data[1], tmp_data[0]); + result = ((tmp_data[3] << 24) + (tmp_data[2] << 16) + (tmp_data[1] << 8) + tmp_data[0]); + break; + } + } + while (cnt++ < 100); + + return result; +} + +void himax_flash_page_write(struct i2c_client *client, uint8_t *write_addr, uint8_t *write_data) +{ + +} + +void himax_set_reload_cmd(uint8_t *write_data, int idx, uint32_t cmd_from, uint32_t cmd_to, uint32_t cmd_beat) +{ + int index = idx * 12; + int i; + for (i = 3; i >= 0; i--) + { + write_data[index + i] = (cmd_from >> (8 * i)); + write_data[index + 4 + i] = (cmd_to >> (8 * i)); + write_data[index + 8 + i] = (cmd_beat >> (8 * i)); + } +} + +bool himax_program_reload(struct i2c_client *client) +{ + return true; +} + +int fts_ctpm_fw_upgrade_with_sys_fs_32k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) //Alice - Un +{ + + //int CRC_from_FW = 0; + int burnFW_success = 0; + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + if (len != FW_SIZE_64k) //64k + { + E("%s: The file size is not 64K bytes\n", __func__); + return false; + } + +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(false,false); +#else + //===AHBI2C_SystemReset========== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x55; + himax_register_write(client, tmp_addr, 4, tmp_data, false); +#endif + + himax_enter_safe_mode(client); + himax_chip_erase(client); + himax_flash_programming(client, fw, FW_SIZE_64k); + + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + + if(himax_hw_check_CRC(client,tmp_data, FW_SIZE_64k) == 0) + { + burnFW_success = 1; + } + else + { + burnFW_success = 0; + } + /*RawOut select initial*/ + tmp_addr[3] = 0x80;tmp_addr[2] = 0x02;tmp_addr[1] = 0x04;tmp_addr[0] = 0xB4; + tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; + himax_register_write(client,tmp_addr, 4, tmp_data, false); + + /*DSRAM func initial*/ + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x07;tmp_addr[0] = 0xFC; + tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; + himax_register_write(client,tmp_addr, 4, tmp_data, false); + +#ifdef HX_RST_PIN_FUNC + himax_ic_reset(true,false); +#else + //===AHBI2C_SystemReset========== + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x55; + himax_register_write(client, tmp_addr, 4, tmp_data, false); +#endif + msleep(800); + himax_read_FW_ver(private_ts->client); + return burnFW_success; + +} + +int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref) +{ + /* Not use */ + return 0; +} + +void himax_touch_information(struct i2c_client *client) +{ +#ifndef HX_FIX_TOUCH_INFO + uint8_t cmd[4]; + char data[12] = {0}; + + I("%s:IC_TYPE =%d\n", __func__,IC_TYPE); + + //if(IC_TYPE == HX_83112A_SERIES_PWON) + if((IC_TYPE == HX_83112A_SERIES_PWON)||(IC_TYPE == HX_83112B_SERIES_PWON)) + { + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0xF4; + himax_register_read(client, cmd, 8, data, false); + ic_data->HX_RX_NUM = data[2]; + ic_data->HX_TX_NUM = data[3]; + ic_data->HX_MAX_PT = data[4]; + //I("%s : HX_RX_NUM=%d,ic_data->HX_TX_NUM=%d,ic_data->HX_MAX_PT=%d\n",__func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT); + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0xFA; + himax_register_read(client, cmd, 4, data, false); + //I("%s : c_data->HX_XY_REVERSE=0x%2.2X\n",__func__,data[1]); + if((data[1] & 0x04) == 0x04) + { + ic_data->HX_XY_REVERSE = true; + } + else + { + ic_data->HX_XY_REVERSE = false; + } + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0xFC; + himax_register_read(client, cmd, 4, data, false); + ic_data->HX_Y_RES = data[0]*256; + ic_data->HX_Y_RES = ic_data->HX_Y_RES + data[1]; + ic_data->HX_X_RES = data[2]*256 + data[3]; + //I("%s : ic_data->HX_Y_RES=%d,ic_data->HX_X_RES=%d \n",__func__,ic_data->HX_Y_RES,ic_data->HX_X_RES); + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0x89; + himax_register_read(client, cmd, 4, data, false); + //I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]); + //I("data[0] & 0x01 = %d\n",(data[0] & 0x01)); + if((data[0] & 0x01) == 1) + { + ic_data->HX_INT_IS_EDGE = true; + } + else + { + ic_data->HX_INT_IS_EDGE = false; + } + + if (ic_data->HX_RX_NUM > 40) + ic_data->HX_RX_NUM = 32; + if (ic_data->HX_TX_NUM > 20) + ic_data->HX_TX_NUM = 18; + if (ic_data->HX_MAX_PT > 10) + ic_data->HX_MAX_PT = 10; + if (ic_data->HX_Y_RES > 2000) + ic_data->HX_Y_RES = 1280; + if (ic_data->HX_X_RES > 2000) + ic_data->HX_X_RES = 720; + + /*Read number of MKey R100070E8H*/ + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0xE8; + himax_register_read(client, cmd, 4,data, false); + //I("%s: data[0] = 0x%02X,data[1] = 0x%02X,data[2] = 0x%02X,data[3] = 0x%02X\n", __func__,data[0],data[1],data[2],data[3]); + ic_data->HX_BT_NUM = data[0] & 0x03; + } + else + { + ic_data->HX_RX_NUM = 0; + ic_data->HX_TX_NUM = 0; + ic_data->HX_BT_NUM = 0; + ic_data->HX_X_RES = 0; + ic_data->HX_Y_RES = 0; + ic_data->HX_MAX_PT = 0; + ic_data->HX_XY_REVERSE = false; + ic_data->HX_INT_IS_EDGE = false; + } +#else + if(IC_TYPE == HX_83112A_SERIES_PWON) { + ic_data->HX_RX_NUM = FIX_HX_RX_NUM; + ic_data->HX_TX_NUM = FIX_HX_TX_NUM; + ic_data->HX_BT_NUM = FIX_HX_BT_NUM; + ic_data->HX_X_RES = FIX_HX_X_RES; + ic_data->HX_Y_RES = FIX_HX_Y_RES; + ic_data->HX_MAX_PT = FIX_HX_MAX_PT; + ic_data->HX_XY_REVERSE = FIX_HX_XY_REVERSE; + ic_data->HX_INT_IS_EDGE = FIX_HX_INT_IS_EDGE; + } + else { + ic_data->HX_RX_NUM = SEC_FIX_HX_RX_NUM; + ic_data->HX_TX_NUM = SEC_FIX_HX_TX_NUM; + ic_data->HX_BT_NUM = SEC_FIX_HX_BT_NUM; + ic_data->HX_X_RES = SEC_FIX_HX_X_RES; + ic_data->HX_Y_RES = SEC_FIX_HX_Y_RES; + ic_data->HX_MAX_PT = SEC_FIX_HX_MAX_PT; + ic_data->HX_XY_REVERSE = SEC_FIX_HX_XY_REVERSE; + ic_data->HX_INT_IS_EDGE = SEC_FIX_HX_INT_IS_EDGE; + } +#endif + I("%s:HX_RX_NUM =%d,HX_TX_NUM =%d,HX_MAX_PT=%d \n", __func__,ic_data->HX_RX_NUM,ic_data->HX_TX_NUM,ic_data->HX_MAX_PT); + I("%s:HX_XY_REVERSE =%d,HX_Y_RES =%d,HX_X_RES=%d \n", __func__,ic_data->HX_XY_REVERSE,ic_data->HX_Y_RES,ic_data->HX_X_RES); + I("%s:HX_INT_IS_EDGE =%d \n", __func__,ic_data->HX_INT_IS_EDGE); +} + +int himax_read_i2c_status(struct i2c_client *client) +{ + return i2c_error_count; // +} + +int himax_read_ic_trigger_type(struct i2c_client *client) +{ + uint8_t cmd[4]; + char data[12] = {0}; + int trigger_type = false; + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0x89; + himax_register_read(client, cmd, 4, data, false); + if((data[0] & 0x01) == 1) + { + trigger_type = true; + } + else + { + trigger_type = false; + } + + return trigger_type; +} + +void himax_read_FW_ver(struct i2c_client *client) +{ + uint8_t cmd[4]; + uint8_t data[64]; + uint8_t cmd_2[4]; + uint8_t data_2[64]; + int retry = 20; + int reload_status = 0; + while(reload_status == 0) + { + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x7f; + cmd[0] = 0x00; + himax_register_read(client, cmd, 4, data, false); + + cmd_2[3] = 0x10; + cmd_2[2] = 0x00; + cmd_2[1] = 0x72; + cmd_2[0] = 0xc0; + himax_register_read(client, cmd_2, 4, data_2, false); + + if((data[3]==0x00 && data[2]==0x00 && data[1]==0x3A && data[0]==0xA3 ) + ||(data_2[3]==0x00 && data_2[2]==0x00 && data_2[1]==0x72 && data_2[0]==0xC0 )) + { + I("reload OK! \n"); + reload_status = 1; + break; + } + else if(retry == 0) + { + E("reload 20 times! fail \n"); + ic_data->vendor_panel_ver = 0; + ic_data->vendor_fw_ver = 0; + ic_data->vendor_config_ver = 0; + ic_data->vendor_touch_cfg_ver = 0; + ic_data->vendor_display_cfg_ver = 0; + ic_data->vendor_cid_maj_ver = 0; + ic_data->vendor_cid_min_ver = 0; + return; + } + else + { + I("%s: 0x10007f00, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]); + I("%s: 0x100072c0, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data_2[0],data_2[1],data_2[2],data_2[3]); + + cmd[3] = 0x90; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xA8; + himax_register_read(client, cmd, 4, data, false); + I("%s: 0x900000A8, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]); + + cmd[3] = 0x90; cmd[2] = 0x00; cmd[1] = 0x00; cmd[0] = 0xE4; + himax_register_read(client, cmd, 4, data, false); + I("%s: 0x900000E4, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]); + + cmd[3] = 0x10; cmd[2] = 0x00; cmd[1] = 0x7F; cmd[0] = 0x40; + himax_register_read(client, cmd, 4, data, false); + I("%s: 0x10007F40, data[0]=%x,data[1]=%x,data[2]=%x,data[3]=%x \n", __func__, data[0],data[1],data[2],data[3]); + + retry --; + msleep(10); + I("reload fail ,delay 10ms retry=%d\n",retry); + } + } + I("%s : data[0]=0x%2.2X,data[1]=0x%2.2X,data[2]=0x%2.2X,data[3]=0x%2.2X\n",__func__,data[0],data[1],data[2],data[3]); + I("reload_status=%d\n",reload_status); + + himax_sense_off(client); + + //===================================== + // Read FW version : 0x1000_7004 but 05,06 are the real addr for FW Version + //===================================== + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0x04; + himax_register_read(client, cmd, 4, data, false); + + ic_data->vendor_panel_ver = data[0]; + ic_data->vendor_fw_ver = data[1] << 8 | data[2]; + ic_data->vendor_hx_ic_id = data[3]; + + I("PANEL_VER : %X \n",ic_data->vendor_panel_ver); + I("FW_VER : %X \n",ic_data->vendor_fw_ver); + I("IC_ID : %X \n",ic_data->vendor_hx_ic_id); + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0x84; + himax_register_read(client, cmd, 4, data, false); + + ic_data->vendor_config_ver = data[2] << 8 | data[3]; + //I("CFG_VER : %X \n",ic_data->vendor_config_ver); + ic_data->vendor_touch_cfg_ver = data[2]; + I("TOUCH_VER : %X \n",ic_data->vendor_touch_cfg_ver); + ic_data->vendor_display_cfg_ver = data[3]; + I("DISPLAY_VER : %X \n",ic_data->vendor_display_cfg_ver); + + + cmd[3] = 0x10; + cmd[2] = 0x00; + cmd[1] = 0x70; + cmd[0] = 0x00; + himax_register_read(client, cmd, 4, data, false); + + ic_data->vendor_cid_maj_ver = data[2] ; + ic_data->vendor_cid_min_ver = data[3]; + + I("CID_VER : %X \n",(ic_data->vendor_cid_maj_ver << 8 | ic_data->vendor_cid_min_ver)); + return; +} + +bool himax_ic_package_check(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + uint8_t ret_data = 0x00; + int i = 0; + + himax_enter_safe_mode(client); + for (i = 0; i < 5; i++) + { +// Product ID + // Touch + tmp_addr[3] = 0x90; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0xD0; + himax_register_read(client, tmp_addr, 4, tmp_data, false); + + I("%s:Read driver IC ID = %X,%X,%X\n", __func__, tmp_data[3],tmp_data[2],tmp_data[1]); + if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && ((tmp_data[1] == 0x2a)||(tmp_data[1] == 0x2b))) + { + IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC; + //Himax: Set FW and CFG Flash Address + FW_VER_MAJ_FLASH_ADDR = 49157; //0x00C005 + FW_VER_MAJ_FLASH_LENG = 1; + FW_VER_MIN_FLASH_ADDR = 49158; //0x00C006 + FW_VER_MIN_FLASH_LENG = 1; + CFG_VER_MAJ_FLASH_ADDR = 49408; //0x00C100 + CFG_VER_MAJ_FLASH_LENG = 1; + CFG_VER_MIN_FLASH_ADDR = 49409; //0x00C101 + CFG_VER_MIN_FLASH_LENG = 1; + CID_VER_MAJ_FLASH_ADDR = 49154; //0x00C002 + CID_VER_MAJ_FLASH_LENG = 1; + CID_VER_MIN_FLASH_ADDR = 49155; //0x00C003 + CID_VER_MIN_FLASH_LENG = 1; + //PANEL_VERSION_ADDR = 49156; //0x00C004 + //PANEL_VERSION_LENG = 1; + if ((tmp_data[3] == 0x83) && (tmp_data[2] == 0x11) && (tmp_data[1] == 0x2a)) + { + IC_TYPE = HX_83112A_SERIES_PWON; +#ifdef HX_AUTO_UPDATE_FW + g_i_FW_VER = i_CTPM_FW_HX83112A[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112A[FW_VER_MIN_FLASH_ADDR]; + g_i_CFG_VER = i_CTPM_FW_HX83112A[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112A[CFG_VER_MIN_FLASH_ADDR]; + g_i_CID_MAJ = i_CTPM_FW_HX83112A[CID_VER_MAJ_FLASH_ADDR]; + g_i_CID_MIN = i_CTPM_FW_HX83112A[CID_VER_MIN_FLASH_ADDR]; +#endif + } + else + { + IC_TYPE = HX_83112B_SERIES_PWON; +#ifdef HX_AUTO_UPDATE_FW + printk("%s: (%d)No need check 2nd ic package\n", __func__, __LINE__); + g_i_FW_VER = i_CTPM_FW_HX83112B[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112B[FW_VER_MIN_FLASH_ADDR]; + g_i_CFG_VER = i_CTPM_FW_HX83112B[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW_HX83112B[CFG_VER_MIN_FLASH_ADDR]; + g_i_CID_MAJ = i_CTPM_FW_HX83112B[CID_VER_MAJ_FLASH_ADDR]; + g_i_CID_MIN = i_CTPM_FW_HX83112B[CID_VER_MIN_FLASH_ADDR]; +#endif + } +#if 0 + IC_CHECKSUM = HX_TP_BIN_CHECKSUM_CRC; + //Himax: Set FW and CFG Flash Address + FW_VER_MAJ_FLASH_ADDR = 49157; //0x00C005 + FW_VER_MAJ_FLASH_LENG = 1; + FW_VER_MIN_FLASH_ADDR = 49158; //0x00C006 + FW_VER_MIN_FLASH_LENG = 1; + CFG_VER_MAJ_FLASH_ADDR = 49408; //0x00C100 + CFG_VER_MAJ_FLASH_LENG = 1; + CFG_VER_MIN_FLASH_ADDR = 49409; //0x00C101 + CFG_VER_MIN_FLASH_LENG = 1; + CID_VER_MAJ_FLASH_ADDR = 49154; //0x00C002 + CID_VER_MAJ_FLASH_LENG = 1; + CID_VER_MIN_FLASH_ADDR = 49155; //0x00C003 + CID_VER_MIN_FLASH_LENG = 1; + //PANEL_VERSION_ADDR = 49156; //0x00C004 + //PANEL_VERSION_LENG = 1; +#endif +#if 0 + g_i_FW_VER = i_CTPM_FW[FW_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[FW_VER_MIN_FLASH_ADDR]; + g_i_CFG_VER = i_CTPM_FW[CFG_VER_MAJ_FLASH_ADDR]<<8 |i_CTPM_FW[CFG_VER_MIN_FLASH_ADDR]; + g_i_CID_MAJ = i_CTPM_FW[CID_VER_MAJ_FLASH_ADDR]; + g_i_CID_MIN = i_CTPM_FW[CID_VER_MIN_FLASH_ADDR]; +#endif + I("Himax IC package 83112_in\n"); + ret_data = true; + himax_sense_on(client, 0); + break; + } + else + { + ret_data = false; + E("%s:Read driver ID register Fail:\n", __func__); + } + } + + return ret_data; +} + +void himax_power_on_init(struct i2c_client *client) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + I("%s:\n", __func__); + himax_touch_information(client); + + /*RawOut select initial*/ + tmp_addr[3] = 0x80;tmp_addr[2] = 0x02;tmp_addr[1] = 0x04;tmp_addr[0] = 0xB4; + tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; + himax_register_write(client,tmp_addr, 4, tmp_data, false); + + /*DSRAM func initial*/ + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x07;tmp_addr[0] = 0xFC; + tmp_data[3] = 0x00;tmp_data[2] = 0x00;tmp_data[1] = 0x00;tmp_data[0] = 0x00; + himax_register_write(client,tmp_addr, 4, tmp_data, false); + + himax_sense_on(client, 0x00); +} + +bool himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length) //Alice - Un +{ + uint8_t cmd[4]; + + // AHB_I2C Burst Read Off + cmd[0] = 0x00; + if ( i2c_himax_write(client, 0x11,cmd, 1, DEFAULT_RETRY_CNT) < 0) + { + E("%s: i2c access fail!\n", __func__); + return 0; + } + + i2c_himax_read(client, 0x30, buf, length,DEFAULT_RETRY_CNT); + + // AHB_I2C Burst Read On + cmd[0] = 0x01; + if ( i2c_himax_write(client, 0x11,cmd, 1, 3) < 0) + { + E("%s: i2c access fail!\n", __func__); + return 0; + } + return 1; +} + +void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data) +{ + int i = 0; + //int cnt = 0; + unsigned char tmp_addr[4]; + unsigned char tmp_data[4]; + uint8_t max_i2c_size = 128; + uint8_t x_num = ic_data->HX_RX_NUM; + uint8_t y_num = ic_data->HX_TX_NUM; + int m_key_num = 0; + int total_size = (x_num * y_num + x_num + y_num) * 2 + 4; + int total_size_temp; + int mutual_data_size = x_num * y_num * 2; + int total_read_times = 0; + int address = 0; + uint8_t *temp_info_data; //max mkey size = 8 + uint16_t check_sum_cal = 0; + int fw_run_flag = -1; + //uint16_t temp_check_sum_cal = 0; + + temp_info_data = kzalloc(sizeof(uint8_t)*(total_size + 8),GFP_KERNEL); + + /*1. Read number of MKey R100070E8H to determin data size*/ + m_key_num = ic_data->HX_BT_NUM; + //I("%s,m_key_num=%d\n",__func__,m_key_num); + total_size += m_key_num*2; + + /* 2. Start DSRAM Rawdata and Wait Data Ready */ + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x5A; + tmp_data[0] = 0xA5; + fw_run_flag = himax_write_read_reg(client,tmp_addr,tmp_data,0xA5,0x5A); + + if(fw_run_flag < 0) + { + I("%s Data NOT ready => bypass \n", __func__); + kfree(temp_info_data); + return; + } + + /* 3. Read RawData */ + total_size_temp = total_size; + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + + if (total_size % max_i2c_size == 0) + { + total_read_times = total_size / max_i2c_size; + } + else + { + total_read_times = total_size / max_i2c_size + 1; + } + + for (i = 0; i < (total_read_times); i++) + { + if ( total_size_temp >= max_i2c_size) + { + himax_register_read(client, tmp_addr, max_i2c_size, &temp_info_data[i*max_i2c_size], false); + total_size_temp = total_size_temp - max_i2c_size; + } + else + { + //I("last total_size_temp=%d\n",total_size_temp); + himax_register_read(client, tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i*max_i2c_size], false); + } + + address = ((i+1)*max_i2c_size); + tmp_addr[1] = (uint8_t)((address>>8)&0x00FF); + tmp_addr[0] = (uint8_t)((address)&0x00FF); + } + + /* 4. FW stop outputing */ + //I("DSRAM_Flag=%d\n",DSRAM_Flag); + if(DSRAM_Flag == false) + { + //I("Return to Event Stack!\n"); + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + himax_flash_write_burst(client, tmp_addr, tmp_data); + } + else + { + //I("Continue to SRAM!\n"); + tmp_addr[3] = 0x10; + tmp_addr[2] = 0x00; + tmp_addr[1] = 0x00; + tmp_addr[0] = 0x00; + tmp_data[3] = 0x11; + tmp_data[2] = 0x22; + tmp_data[1] = 0x33; + tmp_data[0] = 0x44; + himax_flash_write_burst(client, tmp_addr, tmp_data); + } + + /* 5. Data Checksum Check */ + for (i = 2; i < total_size; i=i+2)/* 2:PASSWORD NOT included */ + { + check_sum_cal += (temp_info_data[i+1]*256 + temp_info_data[i]); + } + + if (check_sum_cal % 0x10000 != 0) + { + I("%s check_sum_cal fail=%2X \n", __func__, check_sum_cal); + kfree(temp_info_data); + return; + } + else + { + memcpy(info_data, &temp_info_data[4], mutual_data_size * sizeof(uint8_t)); + //I("%s checksum PASS \n", __func__); + } + kfree(temp_info_data); +} + +bool himax_calculateChecksum(struct i2c_client *client, bool change_iref) +{ + uint8_t CRC_result = 0; + uint8_t tmp_data[4]; + + tmp_data[3] = 0x00; + tmp_data[2] = 0x00; + tmp_data[1] = 0x00; + tmp_data[0] = 0x00; + + CRC_result = himax_hw_check_CRC(client,tmp_data, FW_SIZE_64k); + + msleep(50); + + return !CRC_result; +} + +//ts_work +int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max) +{ + int RawDataLen; + if (raw_cnt_rmd != 0x00) + { + RawDataLen = 128 - ((HX_MAX_PT+raw_cnt_max+3)*4) - 1; + } + else + { + RawDataLen = 128 - ((HX_MAX_PT+raw_cnt_max+2)*4) - 1; + } + return RawDataLen; +} + +bool diag_check_sum( struct himax_report_data *hx_touch_data ) //return checksum value +{ + uint16_t check_sum_cal = 0; + int i; + + //Check 128th byte CRC + for (i = 0, check_sum_cal = 0; i < (hx_touch_data->touch_all_size - hx_touch_data->touch_info_size); i=i+2) + { + check_sum_cal += (hx_touch_data->hx_rawdata_buf[i+1]*256 + hx_touch_data->hx_rawdata_buf[i]); + } + if (check_sum_cal % 0x10000 != 0) + { + I("%s fail=%2X \n", __func__, check_sum_cal); + return 0; + //goto bypass_checksum_failed_packet; + } + + return 1; +} + + +void diag_parse_raw_data(struct himax_report_data *hx_touch_data,int mul_num, int self_num,uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data) +{ + int RawDataLen_word; + int index = 0; + int temp1, temp2,i; + + if (hx_touch_data->hx_rawdata_buf[0] == 0x3A + && hx_touch_data->hx_rawdata_buf[1] == 0xA3 + && hx_touch_data->hx_rawdata_buf[2] > 0 + && hx_touch_data->hx_rawdata_buf[3] == diag_cmd ) + { + RawDataLen_word = hx_touch_data->rawdata_size/2; + index = (hx_touch_data->hx_rawdata_buf[2] - 1) * RawDataLen_word; + //I("Header[%d]: %x, %x, %x, %x, mutual: %d, self: %d\n", index, buf[56], buf[57], buf[58], buf[59], mul_num, self_num); + //I("RawDataLen=%d , RawDataLen_word=%d , hx_touch_info_size=%d\n", RawDataLen, RawDataLen_word, hx_touch_info_size); + for (i = 0; i < RawDataLen_word; i++) + { + temp1 = index + i; + + if (temp1 < mul_num) + { + //mutual + mutual_data[index + i] = hx_touch_data->hx_rawdata_buf[i*2 + 4 + 1]*256 + hx_touch_data->hx_rawdata_buf[i*2 + 4]; //4: RawData Header, 1:HSB + } + else + { + //self + temp1 = i + index; + temp2 = self_num + mul_num; + + if (temp1 >= temp2) + { + break; + } + self_data[i+index-mul_num] = hx_touch_data->hx_rawdata_buf[i*2 + 4]; //4: RawData Header + self_data[i+index-mul_num+1] = hx_touch_data->hx_rawdata_buf[i*2 + 4 + 1]; + } + } + } + +} +uint8_t himax_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data) +{ + int cnt = 0; + uint8_t req_size = cmd_set[0]; + uint8_t cmd_addr[4] = {0xFC, 0x00, 0x00, 0x90}; //0x900000FC -> cmd and hand shaking + uint8_t tmp_addr[4] = {0x80, 0x7F, 0x00, 0x10}; //0x10007F80 -> data space + + cmd_set[3] = 0xAA; + himax_register_write(private_ts->client, cmd_addr, 4, cmd_set, 0); + + I("%s: cmd_set[0] = 0x%02X,cmd_set[1] = 0x%02X,cmd_set[2] = 0x%02X,cmd_set[3] = 0x%02X\n", __func__,cmd_set[0],cmd_set[1],cmd_set[2],cmd_set[3]); + + for (cnt = 0; cnt < 100; cnt++) //doing hand shaking 0xAA -> 0xBB + { + himax_register_read(private_ts->client, cmd_addr, 4, tmp_data, false); + //I("%s: tmp_data[0] = 0x%02X,tmp_data[1] = 0x%02X,tmp_data[2] = 0x%02X,tmp_data[3] = 0x%02X, cnt=%d\n", __func__,tmp_data[0],tmp_data[1],tmp_data[2],tmp_data[3],cnt); + msleep(10); + if(tmp_data[3] == 0xBB) + { + I("%s Data ready goto moving data\n", __func__); + break; + } + else if(cnt >= 99) + { + I("%s Data not ready in FW \n", __func__); + return FW_NOT_READY; + } + } + himax_register_read(private_ts->client, tmp_addr, req_size, tmp_data, false); + return NO_ERR; +} + +int himax_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr) +{ + uint8_t req_size = 0; + uint8_t status_addr[4] = {0x44, 0x7F, 0x00, 0x10}; //0x10007F44 + uint8_t cmd_addr[4] = {0xF8, 0x00, 0x00, 0x90}; //0x900000F8 + + if(state_addr[0]==0x01) + { + state_addr[1]= 0x04; + state_addr[2]= status_addr[0];state_addr[3]= status_addr[1];state_addr[4]= status_addr[2];state_addr[5]= status_addr[3]; + req_size = 0x04; + himax_sense_off(private_ts->client); + himax_register_read(private_ts->client, status_addr, req_size, tmp_addr, false); + himax_sense_on(private_ts->client,1); + } + else if(state_addr[0]==0x02) + { + state_addr[1]= 0x30; + state_addr[2]= cmd_addr[0];state_addr[3]= cmd_addr[1];state_addr[4]= cmd_addr[2];state_addr[5]= cmd_addr[3]; + req_size = 0x30; + himax_register_read(private_ts->client, cmd_addr, req_size, tmp_addr, false); + } + + return NO_ERR; +} + +#if defined(HX_SMART_WAKEUP)||defined(HX_HIGH_SENSE)||defined(HX_USB_DETECT_GLOBAL) +void himax_resend_cmd_func(bool suspended) +{ + struct himax_ts_data *ts; + + ts = private_ts; + +#ifdef HX_SMART_WAKEUP + himax_set_SMWP_enable(ts->client,ts->SMWP_enable,suspended); +#endif +#ifdef HX_HIGH_SENSE + himax_set_HSEN_enable(ts->client,ts->HSEN_enable,suspended); +#endif +#ifdef HX_USB_DETECT_GLOBAL + himax_cable_detect_func(true); +#endif +} +#endif + +void himax_resume_ic_action(struct i2c_client *client) +{ + return; +} + +void himax_suspend_ic_action(struct i2c_client *client) +{ + return; +} + +#ifdef HX_ZERO_FLASH +int G_POWERONOF = 1; +void himax_sys_reset(void) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + // 0x10007f00 -> 0x0000A55A //Diable Flash Reload + tmp_addr[3] = 0x10; tmp_addr[2] = 0x00; tmp_addr[1] = 0x7F; tmp_addr[0] = 0x00; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x9A; tmp_data[0] = 0xA9; + himax_flash_write_burst(private_ts->client,tmp_addr, tmp_data); + + msleep(100); + + tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x55; + himax_register_write(private_ts->client,tmp_addr, 4, tmp_data, false); +} +void himax_clean_sram_0f(uint8_t *addr,int write_len,int type) +{ + int total_read_times = 0; + int max_bus_size = 128; + int total_size_temp = 0; + int total_size = 0; + int address = 0; + int i = 0; + + uint8_t fix_data = 0x00; + uint8_t tmp_addr[4]; + uint8_t tmp_data[128]={0}; + + I("%s,Entering \n",__func__); + + total_size = write_len; + + total_size_temp = write_len; + + I("[log]enable start!\n"); + himax_burst_enable(private_ts->client,1); + I("[log]enable end!\n"); + + tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; + I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); + + + switch(type) + { + case 0: + fix_data = 0x00; + break; + case 1: + fix_data = 0xAA; + break; + case 2: + fix_data = 0xBB; + break; + } + + for(i = 0;i<128;i++) + { + tmp_data[i] = fix_data; + } + + + I("%s, total size=%d\n",__func__,total_size); + + if (total_size_temp % max_bus_size == 0) + { + total_read_times = total_size_temp / max_bus_size; + } + else + { + total_read_times = total_size_temp / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) + { + I("[log]write %d time start!\n",i); + if ( total_size_temp >= max_bus_size) + { + himax_flash_write_burst_lenth(private_ts->client,tmp_addr,tmp_data, max_bus_size); + total_size_temp = total_size_temp - max_bus_size; + } + else + { + I("last total_size_temp=%d\n",total_size_temp); + himax_flash_write_burst_lenth(private_ts->client,tmp_addr,tmp_data, total_size_temp % max_bus_size); + } + address = ((i+1)*max_bus_size); + tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); + tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); + + msleep(10); + } + + I("%s,END \n",__func__); +} + +void himax_write_sram_0f(const struct firmware *fw_entry,uint8_t *addr,int start_index,int write_len) +{ + int total_read_times = 0; + int max_bus_size = 128; + int total_size_temp = 0; + int total_size = 0; + int address = 0; + int i = 0; + + uint8_t tmp_addr[4]; + uint8_t *tmp_data; + uint32_t now_addr; + + I("%s,Entering \n",__func__); + + total_size = 65536; + + total_size_temp = write_len; + + I("[log]enable start!\n"); + himax_burst_enable(private_ts->client,1); + I("[log]enable end!\n"); + + tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; + I("%s, write addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); + now_addr = (addr[3] << 24) + (addr[2] << 16) + (addr[1] << 8) + addr[0]; + I("now addr= 0x%08X\n",now_addr); + + I("%s, total size=%d\n",__func__,total_size); + + //I("[log]locate start!\n"); + tmp_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL); + //I("[log]enable end!\n"); + //I("[log]memcpy start!\n"); + memcpy(tmp_data,fw_entry->data,total_size); + //I("[log]memcpy end!\n"); + + I("tmp_data size=%d\n",(int)sizeof(tmp_data)); + + for(i = 0;i<10;i++) + { + I("[%d] 0x%2.2X",i,tmp_data[i]); + } + I("\n"); + if (total_size_temp % max_bus_size == 0) + { + total_read_times = total_size_temp / max_bus_size; + } + else + { + total_read_times = total_size_temp / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) + { + I("[log]write %d time start!\n",i); + if ( total_size_temp >= max_bus_size) + { + himax_flash_write_burst_lenth(private_ts->client,tmp_addr,&(tmp_data[start_index+i*max_bus_size]), max_bus_size); + total_size_temp = total_size_temp - max_bus_size; + } + else + { + I("last total_size_temp=%d\n",total_size_temp); + himax_flash_write_burst_lenth(private_ts->client,tmp_addr,&(tmp_data[start_index+i*max_bus_size]), total_size_temp % max_bus_size); + } + I("[log]write %d time end!\n",i); + address = ((i+1)*max_bus_size); + tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); + if(tmp_addr[0] < addr[0]) + tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF) + 1; + else + tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); + + + msleep(10); + } + I("%s,END \n",__func__); + kfree(tmp_data); +} + +void himax_firmware_update_0f(const struct firmware *fw_entry) +{ + uint8_t tmp_addr[4]; + uint8_t tmp_data[4]; + + I("%s,Entering \n",__func__); + + tmp_addr[3] = 0x90; tmp_addr[2] = 0x00; tmp_addr[1] = 0x00; tmp_addr[0] = 0x18; + tmp_data[3] = 0x00; tmp_data[2] = 0x00; tmp_data[1] = 0x00; tmp_data[0] = 0x55; + himax_register_write(private_ts->client,tmp_addr, 4, tmp_data, false); + + himax_sense_off(private_ts->client); + + himax_chip_erase(private_ts->client); + + /* first 48K */ + tmp_addr[3] = 0x08;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; + himax_write_sram_0f(fw_entry,tmp_addr,0,0xC000); + + + /* clean */ + if(G_POWERONOF == 1) + { + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; + himax_clean_sram_0f(tmp_addr,32768,0); + } + + /*last 16k*/ + /*config info*/ + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x00; + if(G_POWERONOF == 1) + himax_write_sram_0f(fw_entry,tmp_addr,0xC000,132); + else + himax_clean_sram_0f(tmp_addr,132,2); + /*FW config*/ + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x84; + if(G_POWERONOF == 1) + himax_write_sram_0f(fw_entry,tmp_addr,0xC0FE,512); //0xc100-2 + else + himax_clean_sram_0f(tmp_addr,512,1); + /*ADC config*/ + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x78;tmp_addr[0] = 0x00; + if(G_POWERONOF == 1) + himax_write_sram_0f(fw_entry,tmp_addr,0xD000,376); + else + himax_clean_sram_0f(tmp_addr,376,2); + + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x79;tmp_addr[0] = 0x78; + if(G_POWERONOF == 1) + himax_write_sram_0f(fw_entry,tmp_addr,0xD178,376); + else + himax_clean_sram_0f(tmp_addr,376,2); + + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x7A;tmp_addr[0] = 0xF0; + if(G_POWERONOF == 1) + himax_write_sram_0f(fw_entry,tmp_addr,0xD000,376); + else + himax_clean_sram_0f(tmp_addr,376,2); + + //G_POWERONOF = 0; + + I("%s,END \n",__func__); +} +void himax_0f_operation(struct work_struct *work) +{ + int err = NO_ERR; + const struct firmware *fw_entry = NULL; + char *firmware_name = "himax.bin"; + uint8_t tmp_data[4]; + + I("%s,Entering \n",__func__); + I("file name = %s\n",firmware_name); + err = request_firmware(&fw_entry, firmware_name, private_ts->dev); + if (err < 0) { + E("%s,fail in line%d error code=%d\n",__func__,__LINE__,err); + //goto err_request_firmware; + return ; + } + himax_firmware_update_0f(fw_entry); + release_firmware(fw_entry); + + tmp_data[0] = 0x00;tmp_data[1] = 0x00;tmp_data[2] = 0x00;tmp_data[3] = 0x08; + if(himax_hw_check_CRC(private_ts->client,tmp_data, 0xC000) == 0) + { + I("%s,HW CRC OK!\n",__func__); + } + else + { + E("%s,HW CRC FAIL!\n",__func__); + } + + msleep(100); + himax_sys_reset(); + msleep(100); + himax_int_enable(private_ts->client->irq,1); + + I("%s,END \n",__func__); + return ; +} + +#ifdef HX_0F_DEBUG +void himax_read_sram_0f(const struct firmware *fw_entry,uint8_t *addr,int start_index,int read_len) +{ + int total_read_times = 0; + int max_i2c_size = 128; + int total_size_temp = 0; + int total_size = 0; + int address = 0; + int i = 0,j = 0; + int not_same = 0; + + uint8_t tmp_addr[4]; + uint8_t *temp_info_data; + int *not_same_buff; + + I("%s,Entering \n",__func__); + + himax_burst_enable(private_ts->client,1); + + total_size = read_len; + + total_size_temp = read_len; + + temp_info_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL); + not_same_buff = kzalloc(sizeof(int)*total_size,GFP_KERNEL); + + + tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; + I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); + + I("%s, total size=%d\n",__func__,total_size); + + himax_burst_enable(private_ts->client,1); + + if (total_size % max_i2c_size == 0) + { + total_read_times = total_size / max_i2c_size; + } + else + { + total_read_times = total_size / max_i2c_size + 1; + } + + for (i = 0; i < (total_read_times); i++) + { + if ( total_size_temp >= max_i2c_size) + { + himax_register_read(private_ts->client,tmp_addr, max_i2c_size, &temp_info_data[i*max_i2c_size], false); + total_size_temp = total_size_temp - max_i2c_size; + } + else + { + //I("last total_size_temp=%d\n",total_size_temp); + himax_register_read(private_ts->client,tmp_addr, total_size_temp % max_i2c_size, &temp_info_data[i*max_i2c_size], false); + } + + address = ((i+1)*max_i2c_size); + tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); + if(tmp_addr[0] < addr[0]) + tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF) + 1; + else + tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); + + msleep(10); + } + I("%s,READ Start \n",__func__); + I("%s,start_index = %d \n",__func__,start_index); + j = start_index; + for(i = 0;i < read_len;i++,j++) + { + if(fw_entry->data[j] != temp_info_data[i]) + { + not_same++; + not_same_buff[i] = 1; + } + + + + + I("0x%2.2X,",temp_info_data[i]); + + if (i > 0 && i%16 == 15) + printk("\n"); + } + I("%s,READ END \n",__func__); + I("%s,Not Same count=%d\n",__func__,not_same); + if(not_same != 0) + { + j = start_index; + for(i = 0;idata[j]); + } + for(i = 0;iclient,1); + + total_size = read_len; + + total_size_temp = read_len; + + temp_info_data = kzalloc(sizeof(uint8_t)*total_size,GFP_KERNEL); + + + tmp_addr[3] = addr[3]; tmp_addr[2] = addr[2]; tmp_addr[1] = addr[1]; tmp_addr[0] = addr[0]; + I("%s, read addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); + + I("%s, total size=%d\n",__func__,total_size); + + if (total_size % max_bus_size == 0) + { + total_read_times = total_size / max_bus_size; + } + else + { + total_read_times = total_size / max_bus_size + 1; + } + + for (i = 0; i < (total_read_times); i++) + { + if ( total_size_temp >= max_bus_size) + { + himax_register_read(private_ts->client,tmp_addr, max_bus_size, &temp_info_data[i*max_bus_size], false); + total_size_temp = total_size_temp - max_bus_size; + } + else + { + //I("last total_size_temp=%d\n",total_size_temp); + himax_register_read(private_ts->client,tmp_addr, total_size_temp % max_bus_size, &temp_info_data[i*max_bus_size], false); + } + + address = ((i+1)*max_bus_size); + tmp_addr[1] = addr[1] + (uint8_t)((address>>8)&0x00FF); + tmp_addr[0] = addr[0] + (uint8_t)((address)&0x00FF); + + msleep(10); + } + I("%s, NOW addr tmp_addr[3]=0x%2.2X, tmp_addr[2]=0x%2.2X, tmp_addr[1]=0x%2.2X, tmp_addr[0]=0x%2.2X\n",__func__,tmp_addr[3],tmp_addr[2],tmp_addr[1],tmp_addr[0]); + /*for(i = 0;i 0 && i%16 == 15) + printk("\n"); + }*/ + + + I("Now Write File start!\n"); + fn = filp_open("/sdcard/dump_dsram.txt",O_CREAT | O_WRONLY ,0); + if (!IS_ERR(fn)) + { + I("%s create file and ready to write\n",__func__); + fn->f_op->write(fn,temp_info_data,read_len*sizeof(uint8_t),&fn->f_pos); + filp_close(fn,NULL); + } + I("Now Write File End!\n"); + + + I("%s,END \n",__func__); + + kfree(temp_info_data); +} + +void himax_firmware_read_0f(const struct firmware *fw_entry) +{ + uint8_t tmp_addr[4]; + + I("%s,Entering \n",__func__); + /* first 48K */ + tmp_addr[3] = 0x08;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; + himax_read_sram_0f(fw_entry,tmp_addr,0,0xC000); + + /*last 16k*/ + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x00; + himax_read_sram_0f(fw_entry,tmp_addr,0xC000,132); + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x70;tmp_addr[0] = 0x84; + himax_read_sram_0f(fw_entry,tmp_addr,0xC0FE,512);//0xc100-2 + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x78;tmp_addr[0] = 0x00; + himax_read_sram_0f(fw_entry,tmp_addr,0xD000,376); + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x79;tmp_addr[0] = 0x78; + himax_read_sram_0f(fw_entry,tmp_addr,0xD178,376); + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x7A;tmp_addr[0] = 0xF0; + himax_read_sram_0f(fw_entry,tmp_addr,0xD000,376); + + tmp_addr[3] = 0x10;tmp_addr[2] = 0x00;tmp_addr[1] = 0x00;tmp_addr[0] = 0x00; + himax_read_all_sram(tmp_addr,32768); + I("%s,END \n",__func__); +} + +void himax_0f_operation_check(void) +{ + int err = NO_ERR; + const struct firmware *fw_entry = NULL; + char *firmware_name = "himax.bin"; + + + I("%s,Entering \n",__func__); + I("file name = %s\n",firmware_name); + + err = request_firmware(&fw_entry, firmware_name, private_ts->dev); + if (err < 0) { + E("%s,fail in line%d error code=%d\n",__func__,__LINE__,err); + //goto err_request_firmware; + return ; + } + + I("first 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[0],fw_entry->data[1],fw_entry->data[2],fw_entry->data[3]); + I("next 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[4],fw_entry->data[5],fw_entry->data[6],fw_entry->data[7]); + I("and next 4 bytes 0x%2X,0x%2X,0x%2X,0x%2X !\n",fw_entry->data[8],fw_entry->data[9],fw_entry->data[10],fw_entry->data[11]); + + himax_firmware_read_0f(fw_entry); + + release_firmware(fw_entry); + I("%s,END \n",__func__); + return ; +} +#endif + +#endif diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_ic.h b/drivers/input/touchscreen/hxchipset83112b/himax_ic.h new file mode 100755 index 000000000000..2654ac2666c4 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_ic.h @@ -0,0 +1,80 @@ +/* Himax Android Driver Sample Code for HX83112 chipset +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 "himax_platform.h" +#include "himax_common.h" +#include + +#define HIMAX_REG_RETRY_TIMES 5 + +enum fw_image_type +{ + fw_image_32k = 0x01, + fw_image_48k, + fw_image_60k, + fw_image_64k, + fw_image_124k, + fw_image_128k, +}; + +int himax_hand_shaking(struct i2c_client *client); +void himax_set_SMWP_enable(struct i2c_client *client,uint8_t SMWP_enable, bool suspended); +void himax_set_HSEN_enable(struct i2c_client *client,uint8_t HSEN_enable, bool suspended); +void himax_usb_detect_set(struct i2c_client *client,uint8_t *cable_config); +int himax_determin_diag_rawdata(int diag_command); +int himax_determin_diag_storage(int diag_command); +void himax_diag_register_set(struct i2c_client *client, uint8_t diag_command); +void himax_flash_dump_func(struct i2c_client *client, uint8_t local_flash_command, int Flash_Size, uint8_t *flash_buffer); +int himax_chip_self_test(struct i2c_client *client); +void himax_burst_enable(struct i2c_client *client, uint8_t auto_add_4_byte); ////himax_83110_BURST_INC0_EN +void himax_register_read(struct i2c_client *client, uint8_t *read_addr, int read_length, uint8_t *read_data, bool cfg_flag); ////RegisterRead83110 +void himax_flash_read(struct i2c_client *client, uint8_t *reg_byte, uint8_t *read_data); ////himax_83110_Flash_Read +void himax_flash_write_burst(struct i2c_client *client, uint8_t * reg_byte, uint8_t * write_data); ////himax_83110_Flash_Write_Burst +void himax_flash_write_burst_lenth(struct i2c_client *client, uint8_t *reg_byte, uint8_t *write_data, int length); ////himax_83110_Flash_Write_Burst_lenth +void himax_register_write(struct i2c_client *client, uint8_t *write_addr, int write_length, uint8_t *write_data, bool cfg_flag); ////RegisterWrite83110 +bool himax_sense_off(struct i2c_client *client); ////himax_83110_SenseOff +bool himax_enter_safe_mode(struct i2c_client *client); +void himax_interface_on(struct i2c_client *client); ////himax_83110_Interface_on +bool wait_wip(struct i2c_client *client, int Timing); +void himax_sense_on(struct i2c_client *client, uint8_t FlashMode); ////himax_83110_SenseOn +void himax_chip_erase(struct i2c_client *client); ////himax_83110_Chip_Erase +bool himax_block_erase(struct i2c_client *client); ////himax_83110_Block_Erase +void himax_flash_programming(struct i2c_client *client, uint8_t *FW_content, int FW_Size); ////himax_83110_Flash_Programming +bool himax_check_chip_version(struct i2c_client *client); ////himax_83110_CheckChipVersion +int himax_check_CRC(struct i2c_client *client, int mode); ////himax_83110_Check_CRC +int fts_ctpm_fw_upgrade_with_sys_fs_32k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); +int fts_ctpm_fw_upgrade_with_sys_fs_60k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); +int fts_ctpm_fw_upgrade_with_sys_fs_64k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); +int fts_ctpm_fw_upgrade_with_sys_fs_124k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); +int fts_ctpm_fw_upgrade_with_sys_fs_128k(struct i2c_client *client, unsigned char *fw, int len, bool change_iref); +void himax_touch_information(struct i2c_client *client); +int himax_read_i2c_status(struct i2c_client *client); +int himax_read_ic_trigger_type(struct i2c_client *client); +void himax_read_FW_ver(struct i2c_client *client); +bool himax_ic_package_check(struct i2c_client *client); +void himax_power_on_init(struct i2c_client *client); +bool himax_read_event_stack(struct i2c_client *client, uint8_t *buf, uint8_t length); +void himax_get_DSRAM_data(struct i2c_client *client, uint8_t *info_data); +bool himax_calculateChecksum(struct i2c_client *client, bool change_iref); +bool himax_program_reload(struct i2c_client *client);//5442 Program_Reload +uint8_t himax_read_DD_status(uint8_t *cmd_set, uint8_t *tmp_data); +int himax_read_FW_status(uint8_t *state_addr, uint8_t *tmp_addr); +void himax_resume_ic_action(struct i2c_client *client); +void himax_suspend_ic_action(struct i2c_client *client); + +//ts_work +int cal_data_len(int raw_cnt_rmd, int HX_MAX_PT, int raw_cnt_max); +bool diag_check_sum(struct himax_report_data *hx_touch_data); //return checksum value +void diag_parse_raw_data(struct himax_report_data *hx_touch_data,int mul_num, int self_num,uint8_t diag_cmd, int32_t *mutual_data, int32_t *self_data); diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_platform.c b/drivers/input/touchscreen/hxchipset83112b/himax_platform.c new file mode 100755 index 000000000000..38e19ea933e5 --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_platform.c @@ -0,0 +1,813 @@ +/* Himax Android Driver Sample Code for QCT platform +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 "himax_platform.h" +#include "himax_common.h" +#include "himax_ic.h" + +int i2c_error_count = 0; +int irq_enable_count = 0; + +extern struct himax_ic_data* ic_data; +extern struct himax_ts_data *private_ts; +extern void himax_ts_work(struct himax_ts_data *ts); +extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer); + +#ifdef HX_TP_PROC_DIAG +extern uint8_t getDiagCommand(void); +#endif + +extern void himax_log_touch_int_devation(int touched); + + +int himax_dev_set(struct himax_ts_data *ts) +{ + int ret = 0; + + ts->input_dev = input_allocate_device(); + if (ts->input_dev == NULL) + { + ret = -ENOMEM; + E("%s: Failed to allocate input device\n", __func__); + return ret; + } + ts->input_dev->name = "himax-touchscreen"; + + return ret; +} +int himax_input_register_device(struct input_dev *input_dev) +{ + return input_register_device(input_dev); +} + +#if defined(HX_PLATFOME_DEFINE_KEY) +void himax_platform_key(void) +{ + I("Nothing to be done! Plz cancel it!\n"); +} +#endif + +void himax_vk_parser(struct device_node *dt, + struct himax_i2c_platform_data *pdata) +{ + u32 data = 0; + uint8_t cnt = 0, i = 0; + uint32_t coords[4] = {0}; + struct device_node *node, *pp = NULL; + struct himax_virtual_key *vk; + + node = of_parse_phandle(dt, "virtualkey", 0); + if (node == NULL) + { + I(" DT-No vk info in DT"); + return; + } + else + { + while ((pp = of_get_next_child(node, pp))) + cnt++; + if (!cnt) + return; + + vk = kzalloc(cnt * (sizeof *vk), GFP_KERNEL); + pp = NULL; + while ((pp = of_get_next_child(node, pp))) + { + if (of_property_read_u32(pp, "idx", &data) == 0) + vk[i].index = data; + if (of_property_read_u32_array(pp, "range", coords, 4) == 0) + { + vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1]; + vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3]; + } + else + I(" range faile"); + i++; + } + pdata->virtual_key = vk; + for (i = 0; i < cnt; i++) + I(" vk[%d] idx:%d x_min:%d, y_max:%d", i,pdata->virtual_key[i].index, + pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max); + } +} + +int himax_parse_dt(struct himax_ts_data *ts, + struct himax_i2c_platform_data *pdata) +{ + int rc, coords_size = 0; + uint32_t coords[4] = {0}; + struct property *prop; + struct device_node *dt = ts->client->dev.of_node; + u32 data = 0; + //printk("AllenYu_7-1\n"); + prop = of_find_property(dt, "himax,panel-coords", NULL); + if (prop) + { + coords_size = prop->length / sizeof(u32); + if (coords_size != 4) + D(" %s:Invalid panel coords size %d", __func__, coords_size); + } + //printk("AllenYu_7-2\n"); + if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0) + { + pdata->abs_x_min = coords[0], pdata->abs_x_max = coords[1]; + pdata->abs_y_min = coords[2], pdata->abs_y_max = coords[3]; + I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min, + pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max); + } + //printk("AllenYu_7-3\n"); + prop = of_find_property(dt, "himax,display-coords", NULL); + if (prop) + { + coords_size = prop->length / sizeof(u32); + if (coords_size != 4) + D(" %s:Invalid display coords size %d", __func__, coords_size); + } + //printk("AllenYu_7-4\n"); + rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size); + if (rc && (rc != -EINVAL)) + { + D(" %s:Fail to read display-coords %d\n", __func__, rc); + return rc; + } + //printk("AllenYu_7-5\n"); + pdata->screenWidth = coords[1]; + pdata->screenHeight = coords[3]; + I(" DT-%s:display-coords = (%d, %d)", __func__, pdata->screenWidth, + pdata->screenHeight); + //printk("AllenYu_7-6\n"); + pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0); + if (!gpio_is_valid(pdata->gpio_irq)) + { + I(" DT:gpio_irq value is not valid\n"); + } + //printk("AllenYu_7-7\n"); + pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0); + if (!gpio_is_valid(pdata->gpio_reset)) + { + I(" DT:gpio_rst value is not valid\n"); + } + //printk("AllenYu_7-8\n"); + pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0); + if (!gpio_is_valid(pdata->gpio_3v3_en)) + { + I(" DT:gpio_3v3_en value is not valid\n"); + } + I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en); + + if (of_property_read_u32(dt, "report_type", &data) == 0) + { + pdata->protocol_type = data; + I(" DT:protocol_type=%d", pdata->protocol_type); + } + //printk("AllenYu_7-9\n"); + himax_vk_parser(dt, pdata); + + return 0; +} + +int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry) +{ + int retry; + struct i2c_msg msg[] = + { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &command, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = data, + } + }; + + mutex_lock(&private_ts->rw_lock); + for (retry = 0; retry < toRetry; retry++) + { + if (i2c_transfer(client->adapter, msg, 2) == 2) + break; + msleep(20); + } + if (retry == toRetry) + { + E("%s: i2c_read_block retry over %d\n", + __func__, toRetry); + i2c_error_count = toRetry; + mutex_unlock(&private_ts->rw_lock); + return -EIO; + } + mutex_unlock(&private_ts->rw_lock); + return 0; + +} + +int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry) +{ + int retry/*, loop_i*/; + uint8_t buf[length + 1]; + + struct i2c_msg msg[] = + { + { + .addr = client->addr, + .flags = 0, + .len = length + 1, + .buf = buf, + } + }; + + mutex_lock(&private_ts->rw_lock); + buf[0] = command; + memcpy(buf+1, data, length); + + for (retry = 0; retry < toRetry; retry++) + { + if (i2c_transfer(client->adapter, msg, 1) == 1) + break; + msleep(20); + } + + if (retry == toRetry) + { + E("%s: i2c_write_block retry over %d\n", + __func__, toRetry); + i2c_error_count = toRetry; + mutex_unlock(&private_ts->rw_lock); + return -EIO; + } + mutex_unlock(&private_ts->rw_lock); + return 0; + +} + +int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry) +{ + return i2c_himax_write(client, command, NULL, 0, toRetry); +} + +int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry) +{ + int retry/*, loop_i*/; + uint8_t buf[length]; + + struct i2c_msg msg[] = + { + { + .addr = client->addr, + .flags = 0, + .len = length, + .buf = buf, + } + }; + mutex_lock(&private_ts->rw_lock); + memcpy(buf, data, length); + + for (retry = 0; retry < toRetry; retry++) + { + if (i2c_transfer(client->adapter, msg, 1) == 1) + break; + msleep(20); + } + + if (retry == toRetry) + { + E("%s: i2c_write_block retry over %d\n", + __func__, toRetry); + i2c_error_count = toRetry; + mutex_unlock(&private_ts->rw_lock); + return -EIO; + } + mutex_unlock(&private_ts->rw_lock); + return 0; +} + +void himax_int_enable(int irqnum, int enable) +{ + if (enable == 1 && irq_enable_count == 0) + { + enable_irq(irqnum); + irq_enable_count++; + private_ts->irq_enabled = 1; + } + else if (enable == 0 && irq_enable_count == 1) + { + disable_irq_nosync(irqnum); + irq_enable_count--; + private_ts->irq_enabled = 0; + } + I("irq_enable_count = %d", irq_enable_count); +} + +#ifdef HX_RST_PIN_FUNC +void himax_rst_gpio_set(int pinnum, uint8_t value) +{ + // gpio_direction_output(pinnum, value); // old + gpio_set_value(pinnum, value); +} +#endif + +uint8_t himax_int_gpio_read(int pinnum) +{ + return gpio_get_value(pinnum); +} + +#if defined(CONFIG_HMX_DB) +static int himax_regulator_configure(struct i2c_client *client,struct himax_i2c_platform_data *pdata) +{ + int retval; + pdata->vcc_dig = regulator_get(&client->dev, + "vdd"); + if (IS_ERR(pdata->vcc_dig)) + { + E("%s: Failed to get regulator vdd\n", + __func__); + retval = PTR_ERR(pdata->vcc_dig); + return retval; + } + pdata->vcc_ana = regulator_get(&client->dev, + "avdd"); + if (IS_ERR(pdata->vcc_ana)) + { + E("%s: Failed to get regulator avdd\n", + __func__); + retval = PTR_ERR(pdata->vcc_ana); + regulator_put(pdata->vcc_ana); + return retval; + } + + return 0; +}; + +static int himax_power_on(struct himax_i2c_platform_data *pdata, bool on) +{ + int retval; + + if (on) + { + retval = regulator_enable(pdata->vcc_dig); + if (retval) + { + E("%s: Failed to enable regulator vdd\n", + __func__); + return retval; + } + msleep(100); + retval = regulator_enable(pdata->vcc_ana); + if (retval) + { + E("%s: Failed to enable regulator avdd\n", + __func__); + regulator_disable(pdata->vcc_dig); + return retval; + } + } + else + { + regulator_disable(pdata->vcc_dig); + regulator_disable(pdata->vcc_ana); + } + + return 0; +} + +int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata) +{ + int error; + + error = himax_regulator_configure(client, pdata); + if (error) + { + E("Failed to intialize hardware\n"); + goto err_regulator_not_on; + } + +#ifdef HX_RST_PIN_FUNC + if (gpio_is_valid(pdata->gpio_reset)) + { + /* configure touchscreen reset out gpio */ + error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio"); + if (error) + { + E("unable to request gpio [%d]\n", + pdata->gpio_reset); + goto err_regulator_on; + } + + error = gpio_direction_output(pdata->gpio_reset, 0); + if (error) + { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + goto err_gpio_reset_req; + } + } +#endif + + error = himax_power_on(pdata, true); + if (error) + { + E("Failed to power on hardware\n"); + goto err_gpio_reset_req; + } + + if (gpio_is_valid(pdata->gpio_irq)) + { + /* configure touchscreen irq gpio */ + error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq"); + if (error) + { + E("unable to request gpio [%d]\n", + pdata->gpio_irq); + goto err_power_on; + } + error = gpio_direction_input(pdata->gpio_irq); + if (error) + { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_irq); + goto err_gpio_irq_req; + } + client->irq = gpio_to_irq(pdata->gpio_irq); + } + else + { + E("irq gpio not provided\n"); + goto err_power_on; + } + + msleep(20); +#ifdef HX_RST_PIN_FUNC + if (gpio_is_valid(pdata->gpio_reset)) + { + error = gpio_direction_output(pdata->gpio_reset, 1); + if (error) + { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + goto err_gpio_irq_req; + } + } +#endif + return 0; + +err_gpio_irq_req: + if (gpio_is_valid(pdata->gpio_irq)) + gpio_free(pdata->gpio_irq); +err_power_on: + himax_power_on(pdata, false); +err_gpio_reset_req: +#ifdef HX_RST_PIN_FUNC + if (gpio_is_valid(pdata->gpio_reset)) + gpio_free(pdata->gpio_reset); +err_regulator_on: +#endif +err_regulator_not_on: + + return error; +} + +#else +int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata) +{ + int error=0; + +#ifdef HX_RST_PIN_FUNC + if (pdata->gpio_reset >= 0) + { + error = gpio_request(pdata->gpio_reset, "himax-reset"); + if (error < 0) + { + E("%s: request reset pin failed\n", __func__); + return error; + } + error = gpio_direction_output(pdata->gpio_reset, 0); + if (error) + { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + return error; + } + } +#endif + if (pdata->gpio_3v3_en >= 0) + { + error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en"); + if (error < 0) + { + E("%s: request 3v3_en pin failed\n", __func__); + return error; + } + gpio_direction_output(pdata->gpio_3v3_en, 1); + I("3v3_en pin =%d\n", gpio_get_value(pdata->gpio_3v3_en)); + } + if (gpio_is_valid(pdata->gpio_irq)) + { + /* configure touchscreen irq gpio */ + error = gpio_request(pdata->gpio_irq, "himax_gpio_irq"); + if (error) + { + E("unable to request gpio [%d]\n",pdata->gpio_irq); + return error; + } + error = gpio_direction_input(pdata->gpio_irq); + if (error) + { + E("unable to set direction for gpio [%d]\n",pdata->gpio_irq); + return error; + } + client->irq = gpio_to_irq(pdata->gpio_irq); + } + else + { + E("irq gpio not provided\n"); + return error; + } + msleep(20); + +#ifdef HX_RST_PIN_FUNC + if (pdata->gpio_reset >= 0) + { + error = gpio_direction_output(pdata->gpio_reset, 1); + if (error) + { + E("unable to set direction for gpio [%d]\n", + pdata->gpio_reset); + return error; + } + } +#if 0 + msleep(20); +#endif +#endif + + return error; +} + +#endif + +static void himax_ts_isr_func(struct himax_ts_data *ts) +{ + himax_ts_work(ts); +} + +irqreturn_t himax_ts_thread(int irq, void *ptr) +{ + struct himax_ts_data *ts = ptr; + + if (ts->debug_log_level & BIT(2)) + { + himax_log_touch_int_devation(HX_FINGER_ON); + } + + himax_ts_isr_func((struct himax_ts_data *)ptr); + + if(ts->debug_log_level & BIT(2)) + { + himax_log_touch_int_devation(HX_FINGER_LEAVE); + } + return IRQ_HANDLED; +} + +static void himax_ts_work_func(struct work_struct *work) +{ + struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work); + himax_ts_work(ts); +} + +int himax_int_register_trigger(struct i2c_client *client) +{ + int ret = 0; + struct himax_ts_data *ts = i2c_get_clientdata(client); + + if(ic_data->HX_INT_IS_EDGE) + { + I("%s edge triiger falling\n ",__func__); + ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts); + } + else + { + I("%s level trigger low\n ",__func__); + ret = request_threaded_irq(client->irq, NULL, himax_ts_thread,IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts); + } + return ret; +} + +int himax_int_en_set(struct i2c_client *client) +{ + int ret = NO_ERR; + ret = himax_int_register_trigger(client); + return ret; +} + +int himax_ts_register_interrupt(struct i2c_client *client) +{ + struct himax_ts_data *ts = i2c_get_clientdata(client); + int ret = 0; + + ts->irq_enabled = 0; + //Work functon + if (client->irq) /*INT mode*/ + { + ts->use_irq = 1; + ret = himax_int_register_trigger(client); + if (ret == 0) + { + ts->irq_enabled = 1; + irq_enable_count = 1; + I("%s: irq enabled at qpio: %d\n", __func__, client->irq); +#ifdef HX_SMART_WAKEUP + irq_set_irq_wake(client->irq, 1); +#endif + } + else + { + ts->use_irq = 0; + E("%s: request_irq failed\n", __func__); + } + } + else + { + I("%s: client->irq is empty, use polling mode.\n", __func__); + } + + if (!ts->use_irq) /*if use polling mode need to disable HX_ESD_RECOVERY function*/ + { + ts->himax_wq = create_singlethread_workqueue("himax_touch"); + + INIT_WORK(&ts->work, himax_ts_work_func); + + hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + ts->timer.function = himax_ts_timer_func; + hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL); + I("%s: polling mode enabled\n", __func__); + } + return ret; +} + +static int himax_common_suspend(struct device *dev) +{ + struct himax_ts_data *ts = dev_get_drvdata(dev); + + I("%s: enter \n", __func__); + + himax_chip_common_suspend(ts); + return 0; +} + +static int himax_common_resume(struct device *dev) +{ + struct himax_ts_data *ts = dev_get_drvdata(dev); + + I("%s: enter \n", __func__); + + himax_chip_common_resume(ts); + return 0; +} + +#if defined(CONFIG_FB) +int fb_notifier_callback(struct notifier_block *self, + unsigned long event, void *data) +{ + struct fb_event *evdata = data; + int *blank; + struct himax_ts_data *ts; + if (event != FB_EVENT_BLANK) + return 0; + + ts=container_of(self, struct himax_ts_data, fb_notif); +//ParisKuong modified Mutex initialization +++ +#if 0 + mutex_init(&ts->ops_lock); +#endif +//ParisKuong modified Mutex initialization --- + mutex_lock(&ts->ops_lock); + + if(evdata == NULL) + { + E("%s(%d) evdata is NULL\n",__func__, __LINE__); + } + //I(" %s(%d)\n", __func__, __LINE__); + if (evdata && evdata->data && event == FB_EVENT_BLANK && ts && ts->client) + { + //I(" %s(%d)\n", __func__, __LINE__); + blank = evdata->data; + if(blank == NULL) + { + E("%s(%d) blank is NULL\n",__func__, __LINE__); + } +//I("blank = %d %s(%d)\n", *blank, __func__, __LINE__); + switch (*blank) + { + case FB_BLANK_UNBLANK: + case FB_BLANK_NORMAL: + himax_common_resume(&ts->client->dev); + break; + + case FB_BLANK_POWERDOWN: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_VSYNC_SUSPEND: +#if 0 + case FB_BLANK_NORMAL: +#endif + himax_common_suspend(&ts->client->dev); + break; + } + } + mutex_unlock(&ts->ops_lock); + return 0; +} +#endif + +static const struct i2c_device_id himax_common_ts_id[] = +{ + {HIMAX_common_NAME, 0 }, + {} +}; + +static const struct dev_pm_ops himax_common_pm_ops = +{ +#if (!defined(CONFIG_FB)) + .suspend = himax_common_suspend, + .resume = himax_common_resume, +#endif +}; + +//#ifdef CONFIG_OF +#if 1 +static struct of_device_id himax_match_table[] = +{ + {.compatible = "himax,hxcommon", }, + {}, +}; +#else +#define himax_match_table NULL +#endif + +static struct i2c_driver himax_common_driver = { + //.id_table = himax_common_ts_id, + .probe = himax_chip_common_probe, + .remove = himax_chip_common_remove, + .driver = { + .name = HIMAX_common_NAME, + .owner = THIS_MODULE, + .of_match_table = himax_match_table, +#ifdef CONFIG_PM + .pm = &himax_common_pm_ops, +#endif + }, + .id_table = himax_common_ts_id, +}; + +//static void __init himax_common_init_async(void *unused, async_cookie_t cookie) +//{ +// I("%s:Enter \n", __func__); +// i2c_add_driver(&himax_common_driver); +//} + +static int __init himax_common_init(void) +{ + int ret = -1; + I("Enter Himax common touch panel driver init 83112-B\n"); + + + ret = i2c_add_driver(&himax_common_driver); + printk("Himax ret : %d \n",ret); + + if ( ret != 0 ) { + printk("Himax ret : %d \n",ret); + I("Focaltech touch screen driver init failed!"); + } + //async_schedule(himax_common_init_async, NULL); + + I("Exit Himax common touch panel driver init 83112-B\n"); + //return i2c_add_driver(&himax_common_driver); + return ret; +} + +static void __exit himax_common_exit(void) +{ + i2c_del_driver(&himax_common_driver); +} + +module_init(himax_common_init); +module_exit(himax_common_exit); + +MODULE_DESCRIPTION("Himax_common driver"); +MODULE_LICENSE("GPL"); + diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_platform.h b/drivers/input/touchscreen/hxchipset83112b/himax_platform.h new file mode 100755 index 000000000000..70def61909fa --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/himax_platform.h @@ -0,0 +1,130 @@ +/* Himax Android Driver Sample Code for QCT platform +* +* Copyright (C) 2017 Himax Corporation. +* +* This software is licensed under the terms of the GNU General Public +* License version 2, as published by the Free Software Foundation, and +* may be copied, distributed, and modified under those terms. +* +* 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 HIMAX_PLATFORM_H +#define HIMAX_PLATFORM_H + +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_HMX_DB) +#include +#endif + +#define QCT + +#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG) +#define D(x...) printk("[HXTP] " x) +#define I(x...) printk("[HXTP] " x) +#define W(x...) printk("[HXTP][WARNING] " x) +#define E(x...) printk("[HXTP][ERROR] " x) +#define DIF(x...) \ + if (debug_flag) \ + printk("[HXTP][DEBUG] " x) \ +} while(0) +#else +#define D(x...) +#define I(x...) +#define W(x...) +#define E(x...) +#define DIF(x...) +#endif + +#if defined(CONFIG_HMX_DB) +/* Analog voltage @2.7 V */ +#define HX_VTG_MIN_UV 2700000 +#define HX_VTG_MAX_UV 3300000 +#define HX_ACTIVE_LOAD_UA 15000 +#define HX_LPM_LOAD_UA 10 +/* Digital voltage @1.8 V */ +#define HX_VTG_DIG_MIN_UV 1800000 +#define HX_VTG_DIG_MAX_UV 1800000 +#define HX_ACTIVE_LOAD_DIG_UA 10000 +#define HX_LPM_LOAD_DIG_UA 10 + +#define HX_I2C_VTG_MIN_UV 1800000 +#define HX_I2C_VTG_MAX_UV 1800000 +#define HX_I2C_LOAD_UA 10000 +#define HX_I2C_LPM_LOAD_UA 10 +#endif + +#define HIMAX_common_NAME "himax_tp" +#define HIMAX_I2C_ADDR 0x48 +#define INPUT_DEV_NAME "himax-touchscreen" + +struct himax_i2c_platform_data +{ + int abs_x_min; + int abs_x_max; + int abs_x_fuzz; + int abs_y_min; + int abs_y_max; + int abs_y_fuzz; + int abs_pressure_min; + int abs_pressure_max; + int abs_pressure_fuzz; + int abs_width_min; + int abs_width_max; + int screenWidth; + int screenHeight; + uint8_t fw_version; + uint8_t tw_id; + uint8_t powerOff3V3; + uint8_t cable_config[2]; + uint8_t protocol_type; + int gpio_irq; + int gpio_reset; + int gpio_3v3_en; + int (*power)(int on); + void (*reset)(void); + struct himax_virtual_key *virtual_key; + struct kobject *vk_obj; + struct kobj_attribute *vk2Use; + + int hx_config_size; +#if defined(CONFIG_HMX_DB) + bool i2c_pull_up; + bool digital_pwr_regulator; + int reset_gpio; + u32 reset_gpio_flags; + int irq_gpio; + u32 irq_gpio_flags; + + struct regulator *vcc_ana; //For Dragon Board + struct regulator *vcc_dig; //For Dragon Board + struct regulator *vcc_i2c; //For Dragon Board +#endif +}; + + +extern int irq_enable_count; +extern int i2c_himax_read(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry); +extern int i2c_himax_write(struct i2c_client *client, uint8_t command, uint8_t *data, uint8_t length, uint8_t toRetry); +extern int i2c_himax_write_command(struct i2c_client *client, uint8_t command, uint8_t toRetry); +extern int i2c_himax_master_write(struct i2c_client *client, uint8_t *data, uint8_t length, uint8_t toRetry); +extern void himax_int_enable(int irqnum, int enable); +extern int himax_ts_register_interrupt(struct i2c_client *client); +extern uint8_t himax_int_gpio_read(int pinnum); + +extern int himax_gpio_power_config(struct i2c_client *client,struct himax_i2c_platform_data *pdata); + +#if defined(CONFIG_FB) +extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data); +#endif + +#endif -- GitLab From 56520267648d31f011fe7e38a3bca880f721c9df Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Thu, 14 May 2020 18:02:17 +0800 Subject: [PATCH 24/96] Add Audio drivers for FP3 [1/4] Enable the config and add all audio driver components for 'aw8898' codec. Issue: FP3-A11#202 Change-Id: I96364baea71fe221eaa9086a312e131e66f1d75c (cherry picked from commit 327728b215c33dcc18766f9980b5f2e88b314b3e) --- arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi | 15 +- arch/arm64/boot/dts/qcom/msm8953-audio.dtsi | 74 +- arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 13 + arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 179 +- arch/arm64/boot/dts/qcom/msm8953.dtsi | 91 +- arch/arm64/configs/msm8953-perf_defconfig | 1 + arch/arm64/configs/msm8953_defconfig | 1 + drivers/base/firmware_class.c | 1 + drivers/video/fbdev/msm/mdss_dsi_panel.c | 2 - sound/soc/codecs/Kconfig | 6 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/aw/aw8898.c | 1612 +++++++++++++++++ sound/soc/codecs/aw/aw8898.h | 72 + sound/soc/codecs/aw/aw8898_reg.h | 448 +++++ 14 files changed, 2263 insertions(+), 254 deletions(-) mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953-audio.dtsi mode change 100644 => 100755 drivers/base/firmware_class.c mode change 100644 => 100755 sound/soc/codecs/Kconfig mode change 100644 => 100755 sound/soc/codecs/Makefile create mode 100755 sound/soc/codecs/aw/aw8898.c create mode 100755 sound/soc/codecs/aw/aw8898.h create mode 100755 sound/soc/codecs/aw/aw8898_reg.h diff --git a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi old mode 100644 new mode 100755 index bb05a2e86926..bd1c2320aa0c --- a/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi +++ b/arch/arm64/boot/dts/qcom/msm-audio-lpass.dtsi @@ -115,19 +115,20 @@ qcom,msm-mi2s-tx-lines = <2>; }; - dai_mi2s4: qcom,msm-dai-q6-mi2s-quin { + dai_mi2s4: qcom,msm-dai-q6-mi2s-senary { compatible = "qcom,msm-dai-q6-mi2s"; qcom,msm-dai-q6-mi2s-dev-id = <4>; - qcom,msm-mi2s-rx-lines = <1>; - qcom,msm-mi2s-tx-lines = <2>; + qcom,msm-mi2s-rx-lines = <3>; + qcom,msm-mi2s-tx-lines = <0>; }; - dai_mi2s5: qcom,msm-dai-q6-mi2s-senary { + dai_mi2s5: qcom,msm-dai-q6-mi2s-quin { compatible = "qcom,msm-dai-q6-mi2s"; - qcom,msm-dai-q6-mi2s-dev-id = <6>; - qcom,msm-mi2s-rx-lines = <0>; - qcom,msm-mi2s-tx-lines = <3>; + qcom,msm-dai-q6-mi2s-dev-id = <4>; + qcom,msm-mi2s-rx-lines = <3>; + qcom,msm-mi2s-tx-lines = <0>; }; + }; lsm: qcom,msm-lsm-client { diff --git a/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi b/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi old mode 100644 new mode 100755 index 9e0753426fa7..b812f890aa04 --- a/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-audio.dtsi @@ -36,7 +36,7 @@ }; int_codec: sound { - status = "okay"; + status = "disabled"; compatible = "qcom,msm8952-audio-codec"; qcom,model = "msm8953-snd-card-mtp"; reg = <0xc051000 0x4>, @@ -76,10 +76,10 @@ "WSA_SPK OUT", "VDD_WSA_SWITCH", "SpkrMono WSA_IN", "WSA_SPK OUT"; - qcom,cdc-us-euro-gpios = <&tlmm 63 0>; - qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>; - qcom,cdc-comp-gpios = <&cdc_comp_gpios>; - qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>; + //qcom,cdc-us-euro-gpios = <&tlmm 63 0>; + //qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>; + //qcom,cdc-comp-gpios = <&cdc_comp_gpios>; + //qcom,pri-mi2s-gpios = <&cdc_pri_mi2s_gpios>; qcom,quin-mi2s-gpios = <&cdc_quin_mi2s_gpios>; qcom,afe-rxtx-lb; @@ -136,14 +136,8 @@ qcom,msm-vdd-wsa-switch-current = <10000>; }; - cdc_us_euro_sw: msm_cdc_pinctrl_us_euro_sw { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&cross_conn_det_act>; - pinctrl-1 = <&cross_conn_det_sus>; - }; - cdc_comp_gpios: cdc_comp_pinctrl { + status = "disabled"; compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&cdc_pdm_comp_lines_act>; @@ -151,6 +145,7 @@ }; cdc_pri_mi2s_gpios: msm_cdc_pinctrl_pri { + status = "disabled"; compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&cdc_pdm_lines_act &cdc_pdm_lines_2_act>; @@ -170,7 +165,7 @@ #address-cells = <1>; #size-cells = <0>; wsa881x_i2c_f: wsa881x-i2c-codec@f { - status = "okay"; + status = "disabled"; compatible = "qcom,wsa881x-i2c-codec"; reg = <0x0f>; qcom,wsa-analog-vi-gpio = <&wsa881x_analog_vi_gpio>; @@ -179,7 +174,7 @@ <&wsa881x_analog_reset_gpio>; }; wsa881x_i2c_45: wsa881x-i2c-codec@45 { - status = "okay"; + status = "disabled"; compatible = "qcom,wsa881x-i2c-codec"; reg = <0x45>; }; @@ -198,25 +193,34 @@ pinctrl-1 = <&wsa_clk_off>; }; wsa881x_analog_reset_gpio: wsa881x_analog_reset_pctrl { - compatible = "qcom,msm-cdc-pinctrl"; - pinctrl-names = "aud_active", "aud_sleep"; - pinctrl-0 = <&wsa_reset_on>; - pinctrl-1 = <&wsa_reset_off>; + status = "disabled"; + //compatible = "qcom,msm-cdc-pinctrl"; + //pinctrl-names = "aud_active", "aud_sleep"; + //pinctrl-0 = <&wsa_reset_on>; + //pinctrl-1 = <&wsa_reset_off>; }; ext_codec: sound-9335 { - status = "disabled"; + status = "okay"; compatible = "qcom,msm8952-audio-slim-codec"; qcom,model = "msm8953-tasha-snd-card"; reg = <0xc051000 0x4>, <0xc051004 0x4>, <0xc055000 0x4>, - <0xc052000 0x4>; + <0xc052000 0x4>, + <0x0c056000 0x4>, + <0x0c054000 0x4>, + <0x0c053000 0x4>; reg-names = "csr_gp_io_mux_mic_ctl", "csr_gp_io_mux_spkr_ctl", "csr_gp_io_lpaif_pri_pcm_pri_mode_muxsel", - "csr_gp_io_mux_quin_ctl"; + "csr_gp_io_mux_quin_ctl", + "csr_gp_io_lpaif_qui_pcm_sec_mode_muxsel", + "csr_gp_io_mux_mic_ext_clk_ctl", + "csr_gp_io_mux_sec_tlmm_ctl"; + + qcom,msm-ext-pa = "quinary"; qcom,audio-routing = "AIF4 VI", "MCLK", @@ -254,10 +258,8 @@ "SpkrRight IN", "SPK2 OUT"; qcom,tasha-mclk-clk-freq = <9600000>; - qcom,cdc-us-euro-gpios = <&tlmm 63 0>; - qcom,msm-mbhc-hphl-swh = <0>; - qcom,msm-mbhc-gnd-swh = <0>; - qcom,cdc-us-eu-gpios = <&cdc_us_euro_sw>; + qcom,msm-mbhc-hphl-swh = <1>; + qcom,msm-mbhc-gnd-swh = <1>; qcom,quin-mi2s-gpios = <&cdc_quin_mi2s_gpios>; asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>, @@ -302,10 +304,10 @@ "msm-dai-q6-dev.12293", "msm-dai-q6-dev.16396", "msm-dai-q6-dev.8194", "msm-dai-q6-dev.8195"; - asoc-codec = <&stub_codec>, <&hdmi_dba>; - asoc-codec-names = "msm-stub-codec.1", "msm-hdmi-dba-codec-rx"; + asoc-codec = <&stub_codec>, <&dai_mi2s5>; + asoc-codec-names = "msm-stub-codec.1", "msm-dai-q6-mi2s.5"; - qcom,wsa-max-devs = <2>; + qcom,wsa-max-devs = <0>; qcom,wsa-devs = <&wsa881x_211>, <&wsa881x_212>, <&wsa881x_213>, <&wsa881x_214>; qcom,wsa-aux-dev-prefix = "SpkrLeft", "SpkrRight", @@ -317,7 +319,7 @@ }; wcd9xxx_intc: wcd9xxx-irq { - status = "disabled"; + status = "okay"; compatible = "qcom,wcd9xxx-irq"; interrupt-controller; #interrupt-cells = <1>; @@ -328,7 +330,7 @@ }; clock_audio: audio_ext_clk { - status = "disabled"; + status = "okay"; compatible = "qcom,audio-ref-clk"; clock-names = "osr_clk"; qcom,node_has_rpm_clock; @@ -341,7 +343,7 @@ }; wcd_rst_gpio: msm_cdc_pinctrl@67 { - status = "disabled"; + status = "okay"; compatible = "qcom,msm-cdc-pinctrl"; pinctrl-names = "aud_active", "aud_sleep"; pinctrl-0 = <&cdc_reset_active>; @@ -350,16 +352,16 @@ }; &slim_msm { - status = "disabled"; + status = "okay"; dai_slim: msm_dai_slim { - status = "disabled"; + status = "okay"; compatible = "qcom,msm-dai-slim"; elemental-addr = [ff ff ff fe 17 02]; }; wcd9335: tasha_codec { - status = "disabled"; + status = "okay"; compatible = "qcom,tasha-slim-pgd"; elemental-addr = [00 01 A0 01 17 02]; @@ -385,7 +387,7 @@ qcom,cdc-on-demand-supplies = "cdc-vdd-mic-bias"; qcom,cdc-micbias1-mv = <1800>; - qcom,cdc-micbias2-mv = <1800>; + qcom,cdc-micbias2-mv = <2800>; qcom,cdc-micbias3-mv = <1800>; qcom,cdc-micbias4-mv = <1800>; @@ -442,7 +444,7 @@ &pm8953_1 { pmic_analog_codec: analog-codec@f000 { - status = "okay"; + status = "disabled"; compatible = "qcom,pmic-analog-codec"; reg = <0xf000 0x200>; #address-cells = <2>; diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi index 4ff1f756aa7b..70050ef01987 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -58,6 +58,19 @@ }; }; +&i2c_6 { /* BLSP2 QUP2 (smart amp) */ + status = "ok"; + /* AWINIC AW8898 Smart PA */ + aw8898_smartpa@34{ + compatible = "awinic,aw8898_smartpa"; + reg = <0x34>; + reset-gpio = <&tlmm 21 0>; + irq-gpio = <&tlmm 20 0>; + status = "okay"; + }; + /* AWINIC AW8898 Smart PA End */ +}; + &sdhc_1 { /* device core power supply */ vdd-supply = <&pm8953_l8>; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 2232b0f2b32c..7c74b29e8fbd 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -50,32 +50,6 @@ bias-pull-down; }; }; - - uart1_console_active: uart1_console_active { - mux { - pins = "gpio20", "gpio21"; - function = "blsp_uart6"; - }; - - config { - pins = "gpio20", "gpio21"; - drive-strength = <2>; - bias-disable; - }; - }; - - uart1_console_sleep: uart1_console_sleep { - mux { - pins = "gpio20", "gpio21"; - function = "blsp_uart6"; - }; - - config { - pins = "gpio20", "gpio21"; - drive-strength = <2>; - bias-pull-down; - }; - }; }; cci { cci0_active: cci0_active { @@ -684,32 +658,6 @@ }; }; - blsp2_uart1_active: blsp2_uart1_active { - mux { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; - function = "blsp_uart6"; - }; - - config { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; - drive-strength = <16>; - bias-disable; - }; - }; - - blsp2_uart1_sleep: blsp2_uart1_sleep { - mux { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; - function = "gpio"; - }; - - config { - pins = "gpio20", "gpio21", "gpio22", "gpio23"; - drive-strength = <2>; - bias-disable; - }; - }; - /* SDC pin type */ sdc1_clk_on: sdc1_clk_on { config { @@ -964,6 +912,36 @@ }; }; + i2c_6 { + i2c_6_active: i2c_6_active { + /* active state */ + mux { + pins = "gpio22", "gpio23"; + function = "blsp_i2c6"; + }; + + config { + pins = "gpio22", "gpio23"; + drive-strength = <2>; + bias-disable; + }; + }; + + i2c_6_sleep: i2c_6_sleep { + /* suspended state */ + mux { + pins = "gpio22", "gpio23"; + function = "gpio"; + }; + + config { + pins = "gpio22", "gpio23"; + drive-strength = <2>; + bias-disable; + }; + }; + }; + nfc { nfc_int_active: nfc_int_active { /* active state */ @@ -1254,35 +1232,6 @@ }; }; - cross-conn-det { - cross_conn_det_act: lines_on { - mux { - pins = "gpio63"; - function = "gpio"; - }; - - config { - pins = "gpio63"; - drive-strength = <8>; - output-low; - bias-pull-down; - }; - }; - - cross_conn_det_sus: lines_off { - mux { - pins = "gpio63"; - function = "gpio"; - }; - - config { - pins = "gpio63"; - drive-strength = <2>; - bias-pull-down; - }; - }; - }; - /* WSA VI sense */ wsa-vi { wsa_vi_on: wsa_vi_on { @@ -1370,24 +1319,24 @@ pri-tlmm-lines { pri_tlmm_lines_act: pri_tlmm_lines_act { mux { - pins = "gpio91", "gpio93"; + pins = "gpio91", "gpio93", "gpio88"; function = "pri_mi2s"; }; config { - pins = "gpio91", "gpio93"; + pins = "gpio91", "gpio93", "gpio88"; drive-strength = <8>; }; }; pri_tlmm_lines_sus: pri_tlmm_lines_sus { mux { - pins = "gpio91", "gpio93"; + pins = "gpio91", "gpio93", "gpio88"; function = "pri_mi2s"; }; config { - pins = "gpio91", "gpio93"; + pins = "gpio91", "gpio93", "gpio88"; drive-strength = <2>; bias-pull-down; }; @@ -1421,66 +1370,6 @@ }; }; - spi6 { - spi6_default: spi6_default { - /* active state */ - mux { - /* MOSI, MISO, CLK */ - pins = "gpio20", "gpio21", "gpio23"; - function = "blsp_spi6"; - }; - - config { - pins = "gpio20", "gpio21", "gpio23"; - drive-strength = <12>; /* 12 MA */ - bias-disable = <0>; /* No PULL */ - }; - }; - - spi6_sleep: spi6_sleep { - /* suspended state */ - mux { - /* MOSI, MISO, CLK */ - pins = "gpio20", "gpio21", "gpio23"; - function = "gpio"; - }; - - config { - pins = "gpio20", "gpio21", "gpio23"; - drive-strength = <2>; /* 2 MA */ - bias-pull-down; /* PULL Down */ - }; - }; - - spi6_cs0_active: cs0_active { - /* CS */ - mux { - pins = "gpio22"; - function = "blsp_spi6"; - }; - - config { - pins = "gpio22"; - drive-strength = <2>; - bias-disable = <0>; - }; - }; - - spi6_cs0_sleep: cs0_sleep { - /* CS */ - mux { - pins = "gpio22"; - function = "gpio"; - }; - - config { - pins = "gpio22"; - drive-strength = <2>; - bias-disable = <0>; - }; - }; - }; - /* add pingrp for touchscreen */ ts_int_default: ts_int_default { mux { diff --git a/arch/arm64/boot/dts/qcom/msm8953.dtsi b/arch/arm64/boot/dts/qcom/msm8953.dtsi index 871b1d4b1270..5f111131b72b 100755 --- a/arch/arm64/boot/dts/qcom/msm8953.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953.dtsi @@ -188,8 +188,7 @@ i2c2 = &i2c_2; i2c3 = &i2c_3; i2c5 = &i2c_5; -// spi3 = &spi_3; - spi6 = &spi_6; + i2c6 = &i2c_6; }; soc: soc { @@ -625,42 +624,6 @@ status = "disabled"; }; - blsp2_uart1: uart@7af0000 { - compatible = "qcom,msm-hsuart-v14"; - reg = <0x7af0000 0x200>, - <0x7ac4000 0x1f000>; - reg-names = "core_mem", "bam_mem"; - - interrupt-names = "core_irq", "bam_irq", "wakeup_irq"; - #address-cells = <0>; - interrupt-parent = <&blsp2_uart1>; - interrupts = <0 1 2>; - #interrupt-cells = <1>; - interrupt-map-mask = <0xffffffff>; - interrupt-map = <0 &intc 0 307 0 - 1 &intc 0 239 0 - 2 &tlmm 21 0>; - - qcom,inject-rx-on-wakeup; - qcom,rx-char-to-inject = <0xFD>; - qcom,master-id = <84>; - clock-names = "core_clk", "iface_clk"; - clocks = <&clock_gcc clk_gcc_blsp2_uart2_apps_clk>, - <&clock_gcc clk_gcc_blsp2_ahb_clk>; - pinctrl-names = "sleep", "default"; - pinctrl-0 = <&blsp2_uart1_sleep>; - pinctrl-1 = <&blsp2_uart1_active>; - qcom,bam-tx-ep-pipe-index = <2>; - qcom,bam-rx-ep-pipe-index = <3>; - qcom,msm-bus,name = "blsp2_uart1"; - qcom,msm-bus,num-cases = <2>; - qcom,msm-bus,num-paths = <1>; - qcom,msm-bus,vectors-KBps = - <84 512 0 0>, - <84 512 500 800>; - status = "disabled"; - }; - blsp1_serial1: serial@78b0000 { compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; reg = <0x78b0000 0x200>; @@ -687,32 +650,6 @@ qcom,summing-threshold = <10>; }; - spi_6: spi@7af6000 { /* BLSP2 QUP2 */ - compatible = "qcom,spi-qup-v2"; - #address-cells = <1>; - #size-cells = <0>; - reg-names = "spi_physical", "spi_bam_physical"; - reg = <0x7af6000 0x600>, - <0x7ac4000 0x1f000>; - interrupt-names = "spi_irq", "spi_bam_irq"; - interrupts = <0 300 0>, <0 239 0>; - spi-max-frequency = <19200000>; - pinctrl-names = "spi_default", "spi_sleep"; - pinctrl-0 = <&spi6_default &spi6_cs0_active>; - pinctrl-1 = <&spi6_sleep &spi6_cs0_sleep>; - clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, - <&clock_gcc clk_gcc_blsp2_qup2_spi_apps_clk>; - clock-names = "iface_clk", "core_clk"; - qcom,infinite-mode = <0>; - qcom,use-bam; - qcom,use-pinctrl; - qcom,ver-reg-exists; - qcom,bam-consumer-pipe-index = <6>; - qcom,bam-producer-pipe-index = <7>; - qcom,master-id = <84>; - status = "disabled"; - }; - i2c_1: i2c@78b5000 { /* BLSP1 QUP1 */ compatible = "qcom,i2c-msm-v2"; #address-cells = <1>; @@ -816,6 +753,32 @@ status = "disabled"; }; + i2c_6: i2c@7af6000 { /* BLSP2 QUP2 */ + compatible = "qcom,i2c-msm-v2"; + #address-cells = <1>; + #size-cells = <0>; + reg-names = "qup_phys_addr"; + reg = <0x7af6000 0x600>; + interrupt-names = "qup_irq"; + interrupts = <0 300 0>; + qcom,clk-freq-out = <400000>; + qcom,clk-freq-in = <19200000>; + clock-names = "iface_clk", "core_clk"; + clocks = <&clock_gcc clk_gcc_blsp2_ahb_clk>, + <&clock_gcc clk_gcc_blsp2_qup2_i2c_apps_clk>; + + pinctrl-names = "i2c_active", "i2c_sleep"; + pinctrl-0 = <&i2c_6_active>; + pinctrl-1 = <&i2c_6_sleep>; + qcom,noise-rjct-scl = <0>; + qcom,noise-rjct-sda = <0>; + qcom,master-id = <84>; + dmas = <&dma_blsp2 6 64 0x20000020 0x20>, + <&dma_blsp2 7 32 0x20000020 0x20>; + dma-names = "tx", "rx"; + status = "ok"; + }; + slim_msm: slim@c140000{ cell-index = <1>; compatible = "qcom,slim-ngd"; diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index f5d85ba62bca..5764ea402863 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -684,3 +684,4 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y CONFIG_ELAN_FINGERPRINT=y +CONFIG_SND_SMARTPA_AW8898=y diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index cba4f0cd7c47..121ae13af52e 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -748,3 +748,4 @@ CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y CONFIG_ELAN_FINGERPRINT=y +CONFIG_SND_SMARTPA_AW8898=y diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c old mode 100644 new mode 100755 index 813a191febd8..d49131b01b33 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -294,6 +294,7 @@ static void fw_free_buf(struct firmware_buf *buf) static char fw_path_para[256]; static const char * const fw_path[] = { fw_path_para, + "/system/vendor/firmware", "/lib/firmware/updates/" UTS_RELEASE, "/lib/firmware/updates", "/lib/firmware/" UTS_RELEASE, diff --git a/drivers/video/fbdev/msm/mdss_dsi_panel.c b/drivers/video/fbdev/msm/mdss_dsi_panel.c index 91a76bd889a0..9bd501c0a198 100755 --- a/drivers/video/fbdev/msm/mdss_dsi_panel.c +++ b/drivers/video/fbdev/msm/mdss_dsi_panel.c @@ -533,10 +533,8 @@ int mdss_dsi_panel_reset(struct mdss_panel_data *pdata, int enable) //Move "pull low TP reset pin" from mdss_dsi.c, //it have to same with LCM reset pin pull low - /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off start*/ //TP reset pin pull low with LCD reset pin at same time. gpio_direction_output(64, 0); - /*[Fairphone_8901][Jialong]To reduce power,pull down Touch reset pin when panel off end*/ msleep(1); diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig old mode 100644 new mode 100755 index b4c914cf6635..75304d22f7af --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1097,6 +1097,12 @@ config SND_SOC_AW8896 help Enables support for aw8896 series Smart PA. +config SND_SMARTPA_AW8898 + tristate "SoC Audio for awinic aw8898 series" + depends on I2C + help + This option enables support for aw8898 series Smart PA. + config SND_SOC_TFA98XX tristate "NXP Semiconductors TFA98XX amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile old mode 100644 new mode 100755 index cf30a193cc0f..64ea9871bbd5 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -447,3 +447,5 @@ obj-$(CONFIG_SND_SOC_MAX98504) += snd-soc-max98504.o obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o obj-$(CONFIG_SND_SOC_AW8896) += snd-soc-aw8896.o obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o +#for AWINIC AW8898 Smart PA +obj-y += aw/aw8898.o diff --git a/sound/soc/codecs/aw/aw8898.c b/sound/soc/codecs/aw/aw8898.c new file mode 100755 index 000000000000..dc565ed012cc --- /dev/null +++ b/sound/soc/codecs/aw/aw8898.c @@ -0,0 +1,1612 @@ +/* + * aw8898.c aw8898 codec module + * + * Version: v1.1.3 + * + * Copyright (c) 2018 AWINIC Technology CO., LTD + * + * Author: Nick Li + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "aw8898.h" +#include "aw8898_reg.h" + +/****************************************************** + * + * Marco + * + ******************************************************/ +#define AW8898_I2C_NAME "aw8898_smartpa" + + +#define AW8898_VERSION "v1.1.3" + +#define AW8898_RATES SNDRV_PCM_RATE_8000_48000 +#define AW8898_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +//#define AWINIC_I2C_REGMAP + +#define AW_I2C_RETRIES 5 +#define AW_I2C_RETRY_DELAY 5 // 5ms +#define AW_READ_CHIPID_RETRIES 5 +#define AW_READ_CHIPID_RETRY_DELAY 5 + +static int aw8898_spk_control = 0; +static int aw8898_rcv_control = 0; + +#define AW8898_MAX_FIRMWARE_LOAD_CNT 20 +static char *aw8898_cfg_name = "aw8898_cfg.bin"; + +#ifdef AW8898_VBAT_MONITOR +static int aw8898_vbat_monitor_start(struct aw8898 *aw8898); +static int aw8898_vbat_monitor_stop(struct aw8898 *aw8898); +#endif + /****************************************************** + * + * aw8898 i2c write/read + * + ******************************************************/ +#ifndef AWINIC_I2C_REGMAP +static int i2c_write(struct aw8898 *aw8898, + unsigned char addr, unsigned int reg_data) +{ + int ret = -1; + u8 wbuf[512] = {0}; + + struct i2c_msg msgs[] = { + { + .addr = aw8898->i2c->addr, + .flags = 0, + .len = 3, + .buf = wbuf, + }, + }; + + wbuf[0] = addr; + wbuf[1] = (unsigned char)((reg_data & 0xff00)>>8); + wbuf[2] = (unsigned char)(reg_data & 0x00ff); + + ret = i2c_transfer(aw8898->i2c->adapter, msgs, 1); + if (ret < 0) { + pr_err("%s: i2c write error: %d\n", __func__, ret); + } + + return ret; +} + +static int i2c_read(struct aw8898 *aw8898, + unsigned char addr, unsigned int *reg_data) +{ + int ret = -1; + unsigned char rbuf[512] = {0}; + unsigned int get_data = 0; + + struct i2c_msg msgs[] = { + { + .addr = aw8898->i2c->addr, + .flags = 0, + .len = 1, + .buf = &addr, + }, + { + .addr = aw8898->i2c->addr, + .flags = I2C_M_RD, + .len = 2, + .buf = rbuf, + }, + }; + + ret = i2c_transfer(aw8898->i2c->adapter, msgs, 2); + if (ret < 0) { + pr_err("%s: i2c read error: %d\n", __func__, ret); + return ret; + } + + get_data = (unsigned int)(rbuf[0] & 0x00ff); + get_data <<= 8; + get_data |= (unsigned int)rbuf[1]; + + *reg_data = get_data; + + return ret; +} +#endif + +static int aw8898_i2c_write(struct aw8898 *aw8898, + unsigned char reg_addr, unsigned int reg_data) +{ + int ret = -1; + unsigned char cnt = 0; + + while(cnt < AW_I2C_RETRIES) { +#ifdef AWINIC_I2C_REGMAP + ret = regmap_write(aw8898->regmap, reg_addr, reg_data); + if(ret < 0) { + pr_err("%s: regmap_write cnt=%d error=%d\n", __func__, cnt, ret); + } else { + break; + } +#else + ret = i2c_write(aw8898, reg_addr, reg_data); + if(ret < 0) { + pr_err("%s: i2c_write cnt=%d error=%d\n", __func__, cnt, ret); + } else { + break; + } +#endif + cnt ++; + } + + return ret; +} + +static int aw8898_i2c_read(struct aw8898 *aw8898, + unsigned char reg_addr, unsigned int *reg_data) +{ + int ret = -1; + unsigned char cnt = 0; + + while(cnt < AW_I2C_RETRIES) { +#ifdef AWINIC_I2C_REGMAP + ret = regmap_read(aw8898->regmap, reg_addr, reg_data); + if(ret < 0) { + pr_err("%s: regmap_read cnt=%d error=%d\n", __func__, cnt, ret); + } else { + break; + } +#else + ret = i2c_read(aw8898, reg_addr, reg_data); + if(ret < 0) { + pr_err("%s: i2c_read cnt=%d error=%d\n", __func__, cnt, ret); + } else { + break; + } +#endif + cnt ++; + } + + return ret; +} + +static int aw8898_i2c_write_bits(struct aw8898 *aw8898, + unsigned char reg_addr, unsigned int mask, unsigned int reg_data) +{ + unsigned int reg_val; + + aw8898_i2c_read(aw8898, reg_addr, ®_val); + reg_val &= mask; + reg_val |= reg_data; + aw8898_i2c_write(aw8898, reg_addr, reg_val); + + return 0; +} + +/****************************************************** + * + * aw8898 control + * + ******************************************************/ +static void aw8898_run_mute(struct aw8898 *aw8898, bool mute) +{ + pr_debug("%s enter\n", __func__); + + if(mute) { + aw8898_i2c_write_bits(aw8898, AW8898_REG_PWMCTRL, + AW8898_BIT_PWMCTRL_HMUTE_MASK, AW8898_BIT_PWMCTRL_HMUTE_ENABLE); + } else { + aw8898_i2c_write_bits(aw8898, AW8898_REG_PWMCTRL, + AW8898_BIT_PWMCTRL_HMUTE_MASK, AW8898_BIT_PWMCTRL_HMUTE_DISABLE); + } +} + +static void aw8898_run_pwd(struct aw8898 *aw8898, bool pwd) +{ + pr_debug("%s enter\n", __func__); + + if(pwd) { + aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL, + AW8898_BIT_SYSCTRL_PW_MASK, AW8898_BIT_SYSCTRL_PW_PDN); + } else { + aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL, + AW8898_BIT_SYSCTRL_PW_MASK, AW8898_BIT_SYSCTRL_PW_ACTIVE); + } +} + +static void aw8898_spk_rcv_mode(struct aw8898 *aw8898) +{ + pr_debug("%s spk_rcv=%d\n", __func__, aw8898->spk_rcv_mode); + + if(aw8898->spk_rcv_mode == AW8898_SPEAKER_MODE) { + aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL, + AW8898_BIT_SYSCTRL_MODE_MASK, AW8898_BIT_SYSCTRL_SPK_MODE); + } else if(aw8898->spk_rcv_mode == AW8898_RECEIVER_MODE){ + aw8898_i2c_write_bits(aw8898, AW8898_REG_SYSCTRL, + AW8898_BIT_SYSCTRL_MODE_MASK, AW8898_BIT_SYSCTRL_RCV_MODE); + } else { + } +} + + +static void aw8898_start(struct aw8898 *aw8898) +{ + unsigned int reg_val = 0; + unsigned int iis_check_max = 5; + unsigned int i = 0; + + pr_debug("%s enter\n", __func__); + + aw8898_run_pwd(aw8898, false); + msleep(2); + for(i=0; ilen; i+=4) { + reg_addr = (aw8898_cont->data[i+1]<<8) + aw8898_cont->data[i+0]; + reg_val = (aw8898_cont->data[i+3]<<8) + aw8898_cont->data[i+2]; + pr_info("%s: reg=0x%04x, val = 0x%04x\n", __func__, reg_addr, reg_val); + aw8898_i2c_write(aw8898, (unsigned char)reg_addr, (unsigned int)reg_val); + } + + pr_debug("%s exit\n", __func__); +} + +static void aw8898_cfg_loaded(const struct firmware *cont, void *context) +{ + struct aw8898 *aw8898 = context; + struct aw8898_container *aw8898_cfg; + unsigned int i = 0; + + if (!cont) { + pr_err("%s: failed to read %s\n", __func__, aw8898_cfg_name); + release_firmware(cont); + return; + } + + pr_info("%s: loaded %s - size: %zu\n", __func__, aw8898_cfg_name, + cont ? cont->size : 0); + + for(i=0; isize; i++) { + pr_info("%s: addr:0x%04x, data:0x%02x\n", __func__, i, *(cont->data+i)); + } + + aw8898_cfg = kzalloc(cont->size+sizeof(int), GFP_KERNEL); + if (!aw8898_cfg) { + release_firmware(cont); + pr_err("%s: error allocating memory\n", __func__); + return; + } + aw8898_cfg->len = cont->size; + memcpy(aw8898_cfg->data, cont->data, cont->size); + release_firmware(cont); + + aw8898_container_update(aw8898, aw8898_cfg); + + kfree(aw8898_cfg); + + aw8898->init = 1; + pr_info("%s: cfg update complete\n", __func__); + + aw8898_spk_rcv_mode(aw8898); + aw8898_start(aw8898); +} + +static int aw8898_load_cfg(struct aw8898 *aw8898) +{ + pr_info("%s enter\n", __func__); + + return request_firmware_nowait(THIS_MODULE, FW_ACTION_HOTPLUG, + aw8898_cfg_name, aw8898->dev, GFP_KERNEL, + aw8898, aw8898_cfg_loaded); +} + +static void aw8898_cold_start(struct aw8898 *aw8898) +{ + int ret = -1; + + pr_info("%s enter\n", __func__); + + ret = aw8898_load_cfg(aw8898); + if(ret) { + pr_err("%s: cfg loading requested failed: %d\n", __func__, ret); + } +} + +static void aw8898_smartpa_cfg(struct aw8898 *aw8898, bool flag) +{ + pr_info("%s, flag = %d\n", __func__, flag); + + if(flag == true) { + if(aw8898->init == 0) { + pr_info("%s, init = %d\n", __func__, aw8898->init); + aw8898_cold_start(aw8898); + } else { + aw8898_spk_rcv_mode(aw8898); + aw8898_start(aw8898); + } + } else { + aw8898_stop(aw8898); + } +} + +/****************************************************** + * + * kcontrol + * + ******************************************************/ + static const char *const spk_function[] = { "Off", "On" }; + static const char *const rcv_function[] = { "Off", "On" }; + static const DECLARE_TLV_DB_SCALE(digital_gain,0,50,0); + + struct soc_mixer_control aw8898_mixer ={ + .reg = AW8898_REG_HAGCCFG7, + .shift = AW8898_VOL_REG_SHIFT, + .max = AW8898_VOLUME_MAX, + .min = AW8898_VOLUME_MIN, + }; + +static int aw8898_volume_info(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_info *uinfo) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control*) kcontrol->private_value; + + //set kcontrol info + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = mc->max - mc->min; + return 0; +} + +static int aw8898_volume_get(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + unsigned int reg_val = 0; + unsigned int value = 0; + struct soc_mixer_control *mc = (struct soc_mixer_control*) kcontrol->private_value; + + aw8898_i2c_read(aw8898, AW8898_REG_HAGCCFG7, ®_val); + ucontrol->value.integer.value[0] = (value >> mc->shift)\ + &(AW8898_BIT_HAGCCFG7_VOL_MASK); + return 0; +} + +static int aw8898_volume_put(struct snd_kcontrol *kcontrol,struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = (struct soc_mixer_control*) kcontrol->private_value; + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + unsigned int value = 0; + unsigned int reg_value = 0; + + //value is right + value = ucontrol->value.integer.value[0]; + if(value > (mc->max-mc->min)|| value <0){ + pr_err("%s:value over range \n",__func__); + return -1; + } + + //smartpa have clk + aw8898_i2c_read(aw8898, AW8898_REG_SYSST, ®_value); + if(!(reg_value&AW8898_BIT_SYSST_PLLS)){ + pr_err("%s: NO I2S CLK ,cat not write reg \n",__func__); + return 0; + } + //cal real value + value = value << mc->shift&AW8898_BIT_HAGCCFG7_VOL_MASK; + aw8898_i2c_read(aw8898, AW8898_REG_HAGCCFG7, ®_value); + value = value | (reg_value&0x00ff); + + //write value + aw8898_i2c_write(aw8898, AW8898_REG_HAGCCFG7, value); + + return 0; +} + +static struct snd_kcontrol_new aw8898_volume = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "aw8898_rx_volume", + .access= SNDRV_CTL_ELEM_ACCESS_TLV_READ|SNDRV_CTL_ELEM_ACCESS_READWRITE, + .tlv.p = (digital_gain), + .info = aw8898_volume_info, + .get = aw8898_volume_get, + .put = aw8898_volume_put, + .private_value = (unsigned long)&aw8898_mixer, +}; + +static int aw8898_spk_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: aw8898_spk_control=%d\n", __func__, aw8898_spk_control); + ucontrol->value.integer.value[0] = aw8898_spk_control; + return 0; +} + +static int aw8898_spk_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + + pr_debug("%s: ucontrol->value.integer.value[0]=%ld\n ", + __func__, ucontrol->value.integer.value[0]); + if(ucontrol->value.integer.value[0] == aw8898_spk_control) + return 1; + + aw8898_spk_control = ucontrol->value.integer.value[0]; + + aw8898->spk_rcv_mode = AW8898_SPEAKER_MODE; + + aw8898_spk_rcv_mode(aw8898); + + return 0; +} + +static int aw8898_rcv_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + pr_debug("%s: aw8898_rcv_control=%d\n", __func__, aw8898_rcv_control); + ucontrol->value.integer.value[0] = aw8898_rcv_control; + return 0; +} +static int aw8898_rcv_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + pr_debug("%s: ucontrol->value.integer.value[0]=%ld\n ", + __func__, ucontrol->value.integer.value[0]); + if(ucontrol->value.integer.value[0] == aw8898_rcv_control) + return 1; + + aw8898_rcv_control = ucontrol->value.integer.value[0]; + + aw8898->spk_rcv_mode = AW8898_RECEIVER_MODE; + + aw8898_spk_rcv_mode(aw8898); + + return 0; +} +static const struct soc_enum aw8898_snd_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(rcv_function), rcv_function), +}; + +static struct snd_kcontrol_new aw8898_controls[] = { + SOC_ENUM_EXT("aw8898_speaker_switch", aw8898_snd_enum[0], + aw8898_spk_get, aw8898_spk_set), + SOC_ENUM_EXT("aw8898_receiver_switch", aw8898_snd_enum[1], + aw8898_rcv_get, aw8898_rcv_set), +}; + +static void aw8898_add_codec_controls(struct aw8898 *aw8898) +{ + pr_info("%s enter\n", __func__); + + snd_soc_add_codec_controls(aw8898->codec, aw8898_controls, + ARRAY_SIZE(aw8898_controls)); + + snd_soc_add_codec_controls(aw8898->codec, &aw8898_volume,1); +} + +/****************************************************** + * + * DAPM Widget & Route + * + ******************************************************/ +#if 0 +static struct snd_soc_dapm_widget aw8898_dapm_widgets_common[] = { + /* Stream widgets */ + SND_SOC_DAPM_AIF_IN("AIF_IN", "AW89xx_AIF_Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF_OUT", "AW89xx_AIF_Capture", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUTPUT("OUTL"), + SND_SOC_DAPM_INPUT("AEC_Loopback"), +}; + +static const struct snd_soc_dapm_route aw8898_dapm_routes_common[] = { + { "OUTL", NULL, "AIF_IN" }, + { "AIF_OUT", NULL, "AEC_Loopback" }, +}; + +static void aw8898_add_widgets(struct aw8898 *aw8898) +{ + //struct snd_soc_dapm_context *dapm = &aw8898->codec->dapm; + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(aw8898->codec); + struct snd_soc_dapm_widget *widgets; + + pr_info("%s enter\n", __func__); + widgets = devm_kzalloc(&aw8898->i2c->dev, + sizeof(struct snd_soc_dapm_widget) * + ARRAY_SIZE(aw8898_dapm_widgets_common), + GFP_KERNEL); + if (!widgets) + return; + + memcpy(widgets, aw8898_dapm_widgets_common, + sizeof(struct snd_soc_dapm_widget) * + ARRAY_SIZE(aw8898_dapm_widgets_common)); + + snd_soc_dapm_new_controls(dapm, widgets, + ARRAY_SIZE(aw8898_dapm_widgets_common)); + snd_soc_dapm_add_routes(dapm, aw8898_dapm_routes_common, + ARRAY_SIZE(aw8898_dapm_routes_common)); +} +#endif +/****************************************************** + * + * Digital Audio Interface + * + ******************************************************/ +static int aw8898_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + + pr_info("%s: enter\n", __func__); + aw8898_run_pwd(aw8898, false); + + return 0; +} + +static int aw8898_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + //struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(dai->codec); + struct snd_soc_codec *codec = dai->codec; + + pr_info("%s: fmt=0x%x\n", __func__, fmt); + + /* Supported mode: regular I2S, slave, or PDM */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) { + dev_err(codec->dev, "%s: invalid codec master mode\n", __func__); + return -EINVAL; + } + break; + default: + dev_err(codec->dev, "%s: unsupported DAI format %d\n", __func__, + fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + return 0; +} + +static int aw8898_set_dai_sysclk(struct snd_soc_dai *codec_dai, + int clk_id, unsigned int freq, int dir) +{ + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec_dai->codec); + + pr_info("%s: freq=%d\n", __func__, freq); + + aw8898->sysclk = freq; + return 0; +} + +static int aw8898_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + unsigned int rate = 0; + int reg_value = 0; + int width = 0; + /* Supported */ + + //get rate param + aw8898->rate=rate = params_rate(params); + pr_debug("%s: requested rate: %d, sample size: %d\n", __func__, rate, + snd_pcm_format_width(params_format(params))); + //match rate + switch(rate) + { + case 8000: + reg_value = AW8898_BIT_I2SCTRL_SR_8K; + break; + case 16000: + reg_value = AW8898_BIT_I2SCTRL_SR_16K; + break; + case 32000: + reg_value = AW8898_BIT_I2SCTRL_SR_32K; + break; + case 44100: + reg_value = AW8898_BIT_I2SCTRL_SR_44P1K; + break; + case 48000: + reg_value = AW8898_BIT_I2SCTRL_SR_48K; + break; + default: + reg_value = AW8898_BIT_I2SCTRL_SR_48K; + pr_err("%s: rate can not support\n", __func__); + break; + } + //set chip rate + if(-1 != reg_value){ + aw8898_i2c_write_bits(aw8898, AW8898_REG_I2SCTRL, + AW8898_BIT_I2SCTRL_SR_MASK, reg_value); + } + + //get bit width + width = params_width(params); + pr_debug("%s: width = %d \n",__func__,width); + switch(width) + { + case 16: + reg_value = AW8898_BIT_I2SCTRL_FMS_16BIT; + break; + case 20: + reg_value = AW8898_BIT_I2SCTRL_FMS_20BIT; + break; + case 24: + reg_value = AW8898_BIT_I2SCTRL_FMS_24BIT; + break; + case 32: + reg_value = AW8898_BIT_I2SCTRL_FMS_32BIT; + break; + default: + reg_value = AW8898_BIT_I2SCTRL_FMS_16BIT; + pr_err("%s: width can not support\n", __func__); + break; + } + //set width + if(-1 != reg_value){ + aw8898_i2c_write_bits(aw8898, AW8898_REG_I2SCTRL, + AW8898_BIT_I2SCTRL_FMS_MASK, reg_value); + } + + return 0; +} + +static int aw8898_mute(struct snd_soc_dai *dai, int mute, int stream) +{ + struct snd_soc_codec *codec = dai->codec; + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + + pr_info("%s: mute state=%d\n", __func__, mute); + + if (!(aw8898->flags & AW8898_FLAG_START_ON_MUTE)) + return 0; + + if (mute) { + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + aw8898->pstream = 0; + else + aw8898->cstream = 0; + if (aw8898->pstream != 0 || aw8898->cstream != 0) + return 0; + + mutex_lock(&aw8898->cfg_lock); + aw8898_smartpa_cfg(aw8898, false); + mutex_unlock(&aw8898->cfg_lock); + } else { + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + aw8898->pstream = 1; + else + aw8898->cstream = 1; + + mutex_lock(&aw8898->cfg_lock); + aw8898_smartpa_cfg(aw8898, true); + mutex_unlock(&aw8898->cfg_lock); + } + + return 0; +} + +static void aw8898_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + + aw8898->rate = 0; + aw8898_run_pwd(aw8898, true); +} + +static const struct snd_soc_dai_ops aw8898_dai_ops = { + .startup = aw8898_startup, + .set_fmt = aw8898_set_fmt, + .set_sysclk = aw8898_set_dai_sysclk, + .hw_params = aw8898_hw_params, + .mute_stream = aw8898_mute, + .shutdown = aw8898_shutdown, +}; + +static struct snd_soc_dai_driver aw8898_dai[] = { + { + .name = "aw8898-aif", + .id = 1, + .playback = { + .stream_name = "Speaker_Playback", + .channels_min = 1, + .channels_max = 2, + .rates = AW8898_RATES, + .formats = AW8898_FORMATS, + }, + .capture = { + .stream_name = "Speaker_Capture", + .channels_min = 1, + .channels_max = 2, + .rates = AW8898_RATES, + .formats = AW8898_FORMATS, + }, + .ops = &aw8898_dai_ops, + .symmetric_rates = 1, + .symmetric_channels = 1, + .symmetric_samplebits = 1, + }, +}; + +/***************************************************** + * + * codec driver + * + *****************************************************/ +static int aw8898_probe(struct snd_soc_codec *codec) +{ + struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + int ret = 0; + + pr_info("%s enter\n", __func__); + + aw8898->codec = codec; + + //aw8898_add_widgets(aw8898); + + aw8898_add_codec_controls(aw8898); + + if (codec->dev->of_node) + dev_set_name(codec->dev, "%s", "aw8898_smartpa"); + + pr_info("%s exit\n", __func__); + + return ret; +} + +static int aw8898_remove(struct snd_soc_codec *codec) +{ + //struct aw8898 *aw8898 = snd_soc_codec_get_drvdata(codec); + pr_info("%s enter\n", __func__); + + //aw8898_inputdev_unregister(aw8898); + + return 0; +} + +/* +struct regmap *aw8898_get_regmap(struct device *dev) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + + return aw8898->regmap; +} +*/ + +static unsigned int aw8898_codec_read(struct snd_soc_codec *codec,unsigned int reg) +{ + struct aw8898 *aw8898=snd_soc_codec_get_drvdata(codec); + unsigned int value =0; + int ret; + pr_debug("%s:enter \n",__func__); + + if(aw8898_reg_access[reg]®_RD_ACCESS){ + ret=aw8898_i2c_read(aw8898,reg,&value); + if(ret<0){ + pr_debug("%s: read register failed \n",__func__); + return ret; + } + }else{ + pr_debug("%s:Register 0x%x NO read access\n",__func__,reg); + return -1; + } + return value; +} + +static int aw8898_codec_write(struct snd_soc_codec *codec,unsigned int reg,unsigned int value) +{ + int ret ; + struct aw8898 *aw8898=snd_soc_codec_get_drvdata(codec); + pr_debug("%s:enter ,reg is 0x%x value is 0x%x\n",__func__,reg,value); + + if(aw8898_reg_access[reg]®_WR_ACCESS){ + ret=aw8898_i2c_write(aw8898,reg,value); + return ret; + }else{ + pr_debug("%s: Register 0x%x NO write access \n",__func__,reg); + } + + return -1; +} +/* +static int aw8898_codec_readable(struct snd_soc_codec *codec,unsigned int reg) +{ + return aw8898_reg_access[reg]®_RD_ACCESS; +} +*/ +static struct snd_soc_codec_driver soc_codec_dev_aw8898 = { + .probe = aw8898_probe, + .remove = aw8898_remove, + //.get_regmap = aw8898_get_regmap, + .read = aw8898_codec_read, + .write= aw8898_codec_write, + .reg_cache_size= AW8898_REG_MAX, + .reg_word_size=2, +}; + +/***************************************************** + * + * regmap + * + *****************************************************/ +bool aw8898_writeable_register(struct device *dev, unsigned int reg) +{ + /* enable read access for all registers */ + return 1; +} + +bool aw8898_readable_register(struct device *dev, unsigned int reg) +{ + /* enable read access for all registers */ + return 1; +} + +bool aw8898_volatile_register(struct device *dev, unsigned int reg) +{ + /* enable read access for all registers */ + return 1; +} + +static const struct regmap_config aw8898_regmap = { + .reg_bits = 8, + .val_bits = 16, + + .max_register = AW8898_MAX_REGISTER, + .writeable_reg = aw8898_writeable_register, + .readable_reg = aw8898_readable_register, + .volatile_reg = aw8898_volatile_register, + .cache_type = REGCACHE_RBTREE, +}; + +/****************************************************** + * + * irq + * + ******************************************************/ +static void aw8898_interrupt_setup(struct aw8898 *aw8898) +{ + unsigned int reg_val; + + pr_info("%s enter\n", __func__); + + aw8898_i2c_read(aw8898, AW8898_REG_SYSINTM, ®_val); + reg_val &= (~AW8898_BIT_SYSINTM_PLLM); + reg_val &= (~AW8898_BIT_SYSINTM_OTHM); + reg_val &= (~AW8898_BIT_SYSINTM_OCDM); + aw8898_i2c_write(aw8898, AW8898_REG_SYSINTM, reg_val); +} + +static void aw8898_interrupt_clear(struct aw8898 *aw8898) +{ + unsigned int reg_val = 0; + + pr_info("%s enter\n", __func__); + + aw8898_i2c_read(aw8898, AW8898_REG_SYSST, ®_val); + pr_info("%s: reg SYSST=0x%x\n", __func__, reg_val); + + aw8898_i2c_read(aw8898, AW8898_REG_SYSINT, ®_val); + pr_info("%s: reg SYSINT=0x%x\n", __func__, reg_val); + + aw8898_i2c_read(aw8898, AW8898_REG_SYSINTM, ®_val); + pr_info("%s: reg SYSINTM=0x%x\n", __func__, reg_val); +} + +static irqreturn_t aw8898_irq(int irq, void *data) +{ + struct aw8898 *aw8898 = data; + + pr_info("%s enter\n", __func__); + + aw8898_interrupt_clear(aw8898); + + pr_info("%s exit\n", __func__); + + return IRQ_HANDLED; +} + +/***************************************************** + * + * device tree + * + *****************************************************/ +static int aw8898_parse_dt(struct device *dev, struct aw8898 *aw8898, + struct device_node *np) +{ + aw8898->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); + if (aw8898->reset_gpio < 0) { + dev_err(dev, "%s: no reset gpio provided, will not HW reset device\n", __func__); + return -1; + } else { + dev_info(dev, "%s: reset gpio provided ok\n", __func__); + } + aw8898->irq_gpio = of_get_named_gpio(np, "irq-gpio", 0); + if (aw8898->irq_gpio < 0) { + dev_info(dev, "%s: no irq gpio provided.\n", __func__); + } else { + dev_info(dev, "%s: irq gpio provided ok.\n", __func__); + } + + return 0; +} + +int aw8898_hw_reset(struct aw8898 *aw8898) +{ + pr_info("%s enter\n", __func__); + + if (aw8898 && gpio_is_valid(aw8898->reset_gpio)) { + gpio_set_value_cansleep(aw8898->reset_gpio, 0); + msleep(1); + gpio_set_value_cansleep(aw8898->reset_gpio, 1); + msleep(1); + } else { + dev_err(aw8898->dev, "%s: failed\n", __func__); + } + return 0; +} + +/***************************************************** + * + * check chip id + * + *****************************************************/ +int aw8898_read_chipid(struct aw8898 *aw8898) +{ + int ret = -1; + unsigned int cnt = 0; + unsigned int reg = 0; + + while(cnt < AW_READ_CHIPID_RETRIES) { + ret = aw8898_i2c_read(aw8898, AW8898_REG_ID, ®); + if (ret < 0) { + dev_err(aw8898->dev, "%s: failed to read register AW8898_REG_ID: %d\n", __func__, ret); + return -EIO; + } + switch (reg) { + case 0x1702: + pr_info("%s aw8898 detected\n", __func__); + aw8898->flags |= AW8898_FLAG_SKIP_INTERRUPTS; + aw8898->flags |= AW8898_FLAG_START_ON_MUTE; + aw8898->chipid = AW8898_ID; + pr_info("%s aw8898->flags=0x%x\n", __func__, aw8898->flags); + return 0; + default: + pr_info("%s unsupported device revision (0x%x)\n", __func__, reg ); + break; + } + cnt ++; + + msleep(AW_READ_CHIPID_RETRY_DELAY); + } + + return -EINVAL; +} + +/***************************************************** + * + * vbat monitor + * + *****************************************************/ +#ifdef AW8898_VBAT_MONITOR +static int aw8898_vbat_monitor_stop(struct aw8898 *aw8898) +{ + pr_info("%s enter\n", __func__); + + if(hrtimer_active(&aw8898->vbat_monitor_timer)) { + pr_info("%s: cancel vbat monitor\n", __func__); + hrtimer_cancel(&aw8898->vbat_monitor_timer); + } + return 0; +} + +static int aw8898_vbat_monitor_start(struct aw8898 *aw8898) +{ + int ram_timer_val = 30000; + + pr_info("%s enter\n", __func__); + + if(hrtimer_active(&aw8898->vbat_monitor_timer)) { + } else { + pr_info("%s: start vbat monitor\n", __func__); + hrtimer_start(&aw8898->vbat_monitor_timer, + ktime_set(ram_timer_val/1000, (ram_timer_val%1000)*1000000), + HRTIMER_MODE_REL); + } + return 0; +} + +static enum hrtimer_restart aw8898_vbat_monitor_timer_func(struct hrtimer *timer) +{ + struct aw8898 *aw8898 = container_of(timer, struct aw8898, vbat_monitor_timer); + + pr_info("%s enter\n", __func__); + + schedule_work(&aw8898->vbat_monitor_work); + + return HRTIMER_NORESTART; +} + +static int aw8898_get_sys_battery_info(char *dev) +{ + int fd; + int eCheck; + int nReadSize; + char buf[64],*pvalue; + mm_segment_t oldfs; + + oldfs = get_fs(); + set_fs(KERNEL_DS); + fd = sys_open(dev, O_RDONLY, 0); + if (fd < 0) { + pr_err("%s: open fail dev:%s fd:%d\n", __func__, dev, fd); + set_fs(oldfs); + return fd; + } + + nReadSize = sys_read(fd, buf, sizeof(buf) - 1); + pr_debug("%s: nReadSize:%d\n", __func__, nReadSize); + + eCheck = simple_strtoul(buf,&pvalue,10); + pr_debug("%s: eCheck = %d\n", __func__, eCheck); + + set_fs(oldfs); + sys_close(fd); + + if (eCheck > 0) + return eCheck; + else + return 0; +} + +static void aw8898_vbat_monitor_work_routine(struct work_struct *work) +{ + struct aw8898 *aw8898 = container_of(work, struct aw8898, vbat_monitor_work); + unsigned int reg_val = 0; + int sys_vbat_vol = 0; + + pr_info("%s enter\n", __func__); + + aw8898_i2c_read(aw8898, AW8898_REG_PWMCTRL, ®_val); + if((reg_val&AW8898_BIT_PWMCTRL_HMUTE_ENABLE) == AW8898_BIT_PWMCTRL_HMUTE_DISABLE) { + sys_vbat_vol = aw8898_get_sys_battery_info(SYS_BAT_DEV); + pr_info("%s: get sys battery = %d\n", __func__, sys_vbat_vol); + if((sys_vbat_vol < AW8898_SYS_VBAT_LIMIT) && (sys_vbat_vol > AW8898_SYS_VBAT_MIN)) { + aw8898_i2c_write_bits(aw8898, AW8898_REG_GENCTRL, + AW8898_BIT_GENCTRL_BST_ILIMIT_MASK, (aw8898->bst_ilimit<<4)); + } + aw8898_vbat_monitor_start(aw8898); + } +} + +static int aw8898_vbat_monitor_init(struct aw8898 *aw8898) +{ + pr_info("%s enter\n", __func__); + + aw8898->bst_ilimit = 0x00; + + hrtimer_init(&aw8898->vbat_monitor_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + aw8898->vbat_monitor_timer.function = aw8898_vbat_monitor_timer_func; + INIT_WORK(&aw8898->vbat_monitor_work, aw8898_vbat_monitor_work_routine); + return 0; +} +#endif +/****************************************************** + * + * sys bin attribute + * + *****************************************************/ +static ssize_t aw8898_reg_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct aw8898 *aw8898 = dev_get_drvdata(dev); + + if (count != 1) { + pr_info("invalid register address"); + return -EINVAL; + } + + aw8898->reg = buf[0]; + + return 1; +} + +static ssize_t aw8898_rw_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct aw8898 *aw8898 = dev_get_drvdata(dev); + u8 *data; + int ret; + int retries = AW_I2C_RETRIES; + + data = kmalloc(count+1, GFP_KERNEL); + if (data == NULL) { + pr_err("can not allocate memory\n"); + return -ENOMEM; + } + + data[0] = aw8898->reg; + memcpy(&data[1], buf, count); + + retry: + ret = i2c_master_send(aw8898->i2c, data, count+1); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(AW_I2C_RETRY_DELAY); + goto retry; + } + } + + kfree(data); + return ret; +} + +static ssize_t aw8898_rw_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct aw8898 *aw8898 = dev_get_drvdata(dev); + struct i2c_msg msgs[] = { + { + .addr = aw8898->i2c->addr, + .flags = 0, + .len = 1, + .buf = &aw8898->reg, + }, + { + .addr = aw8898->i2c->addr, + .flags = I2C_M_RD, + .len = count, + .buf = buf, + }, + }; + int ret; + int retries = AW_I2C_RETRIES; + retry: + ret = i2c_transfer(aw8898->i2c->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret < 0) { + pr_warn("i2c error, retries left: %d\n", retries); + if (retries) { + retries--; + msleep(AW_I2C_RETRY_DELAY); + goto retry; + } + return ret; + } + /* ret contains the number of i2c messages send */ + return 1 + ((ret > 1) ? count : 0); +} + +static struct bin_attribute dev_attr_rw = { + .attr = { + .name = "rw", + .mode = S_IRUSR | S_IWUSR, + }, + .size = 0, + .read = aw8898_rw_read, + .write = aw8898_rw_write, +}; + +static struct bin_attribute dev_attr_regaddr = { + .attr = { + .name = "regaddr", + .mode = S_IWUSR, + }, + .size = 0, + .read = NULL, + .write = aw8898_reg_write, +}; + +/****************************************************** + * + * sys group attribute: reg + * + ******************************************************/ +static ssize_t aw8898_reg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + + unsigned int databuf[2] = {0}; + + if(2 == sscanf(buf, "%x %x", &databuf[0], &databuf[1])) { + aw8898_i2c_write(aw8898, databuf[0], databuf[1]); + } + + return count; +} + +static ssize_t aw8898_reg_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + ssize_t len = 0; + unsigned char i = 0; + unsigned int reg_val = 0; + for(i = 0; i < AW8898_REG_MAX; i ++) { + if(!(aw8898_reg_access[i]®_RD_ACCESS)) + continue; + aw8898_i2c_read(aw8898, i, ®_val); + len += snprintf(buf+len, PAGE_SIZE-len, "reg:0x%02x=0x%04x \n", i, reg_val); + } + return len; +} + +static ssize_t aw8898_spk_rcv_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + + unsigned int databuf[2] = {0}; + + if(1 == sscanf(buf, "%d", &databuf[0])) { + aw8898->spk_rcv_mode = databuf[0]; + } + + return count; +} + +static ssize_t aw8898_spk_rcv_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + ssize_t len = 0; + if(aw8898->spk_rcv_mode == AW8898_SPEAKER_MODE) { + len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 spk_rcv: %d, speaker mode\n", aw8898->spk_rcv_mode); + } else if (aw8898->spk_rcv_mode == AW8898_RECEIVER_MODE) { + len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 spk_rcv: %d, receiver mode\n", aw8898->spk_rcv_mode); + } else { + len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 spk_rcv: %d, unknown mode\n", aw8898->spk_rcv_mode); + } + + return len; +} + +static ssize_t aw8898_bst_ilimit_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + + unsigned int databuf[2] = {0}; + + if(1 == sscanf(buf, "%x", &databuf[0])) { + aw8898->bst_ilimit = databuf[0]; + } + + return count; +} + +static ssize_t aw8898_bst_ilimit_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct aw8898 *aw8898 = dev_get_drvdata(dev); + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "aw8898 bst_ilimit=0x%02x\n", aw8898->bst_ilimit); + + return len; +} +static DEVICE_ATTR(reg, S_IWUSR | S_IRUGO, aw8898_reg_show, aw8898_reg_store); +static DEVICE_ATTR(spk_rcv, S_IWUSR | S_IRUGO, aw8898_spk_rcv_show, aw8898_spk_rcv_store); +static DEVICE_ATTR(bst_ilimit, S_IWUSR | S_IRUGO, aw8898_bst_ilimit_show, aw8898_bst_ilimit_store); + +static struct attribute *aw8898_attributes[] = { + &dev_attr_reg.attr, + &dev_attr_spk_rcv.attr, + &dev_attr_bst_ilimit.attr, + NULL +}; + +static struct attribute_group aw8898_attribute_group = { + .attrs = aw8898_attributes +}; + + +/****************************************************** + * + * i2c driver + * + ******************************************************/ +static int aw8898_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) +{ + struct snd_soc_dai_driver *dai; + struct aw8898 *aw8898; + struct device_node *np = i2c->dev.of_node; + int irq_flags = 0; + int ret = -1; + + pr_info("%s enter\n", __func__); + + if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_I2C)) { + dev_err(&i2c->dev, "check_functionality failed\n"); + return -EIO; + } + + aw8898 = devm_kzalloc(&i2c->dev, sizeof(struct aw8898), GFP_KERNEL); + if (aw8898 == NULL) + return -ENOMEM; + + aw8898->dev = &i2c->dev; + aw8898->i2c = i2c; + + /* aw8898 regmap */ + aw8898->regmap = devm_regmap_init_i2c(i2c, &aw8898_regmap); + if (IS_ERR(aw8898->regmap)) { + ret = PTR_ERR(aw8898->regmap); + dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n", __func__, ret); + goto err_regmap; + } + + i2c_set_clientdata(i2c, aw8898); + mutex_init(&aw8898->cfg_lock); + + /* aw8898 rst & int */ + if (np) { + ret = aw8898_parse_dt(&i2c->dev, aw8898, np); + if (ret) { + dev_err(&i2c->dev, "%s: failed to parse device tree node\n", __func__); + goto err_parse_dt; + } + } else { + aw8898->reset_gpio = -1; + aw8898->irq_gpio = -1; + } + + if (gpio_is_valid(aw8898->reset_gpio)) { + ret = devm_gpio_request_one(&i2c->dev, aw8898->reset_gpio, + GPIOF_OUT_INIT_LOW, "aw8898_rst"); + if (ret){ + dev_err(&i2c->dev, "%s: rst request failed\n", __func__); + goto err_gpio_request; + } + } + + if (gpio_is_valid(aw8898->irq_gpio)) { + ret = devm_gpio_request_one(&i2c->dev, aw8898->irq_gpio, + GPIOF_DIR_IN, "aw8898_int"); + if (ret){ + dev_err(&i2c->dev, "%s: int request failed\n", __func__); + goto err_gpio_request; + } + } + + /* hardware reset */ + aw8898_hw_reset(aw8898); + + /* aw8898 chip id */ + ret = aw8898_read_chipid(aw8898); + if (ret < 0) { + dev_err(&i2c->dev, "%s: aw8898_read_chipid failed ret=%d\n", __func__, ret); + goto err_id; + } + + /* aw8898 device name */ + if (i2c->dev.of_node) { + dev_set_name(&i2c->dev, "%s", "aw8898_smartpa"); + } else { + dev_err(&i2c->dev, "%s failed to set device name: %d\n", __func__, ret); + } + + /* register codec */ + dai = devm_kzalloc(&i2c->dev, sizeof(aw8898_dai), GFP_KERNEL); + if (!dai) { + goto err_dai_kzalloc; + } + memcpy(dai, aw8898_dai, sizeof(aw8898_dai)); + pr_info("%s dai->name(%s)\n", __func__, dai->name); + + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_aw8898, + dai, ARRAY_SIZE(aw8898_dai)); + if (ret < 0) { + dev_err(&i2c->dev, "%s failed to register aw8898: %d\n", __func__, ret); + goto err_register_codec; + } + + /* aw8898 irq */ + if (gpio_is_valid(aw8898->irq_gpio) && + !(aw8898->flags & AW8898_FLAG_SKIP_INTERRUPTS)) { + aw8898_interrupt_setup(aw8898); + /* register irq handler */ + irq_flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT; + ret = devm_request_threaded_irq(&i2c->dev, + gpio_to_irq(aw8898->irq_gpio), + NULL, aw8898_irq, irq_flags, + "aw8898", aw8898); + if (ret != 0) { + dev_err(&i2c->dev, "failed to request IRQ %d: %d\n", + gpio_to_irq(aw8898->irq_gpio), ret); + goto err_irq; + } + } else { + dev_info(&i2c->dev, "%s skipping IRQ registration\n", __func__); + /* disable feature support if gpio was invalid */ + aw8898->flags |= AW8898_FLAG_SKIP_INTERRUPTS; + } + + /* Register the sysfs files for climax backdoor access */ + ret = device_create_bin_file(&i2c->dev, &dev_attr_rw); + if (ret) + dev_info(&i2c->dev, "%s error creating sysfs files: rw\n", __func__); + ret = device_create_bin_file(&i2c->dev, &dev_attr_regaddr); + if (ret) + dev_info(&i2c->dev, "%s error creating sysfs files: regaddr\n", __func__); + + dev_set_drvdata(&i2c->dev, aw8898); + ret = sysfs_create_group(&i2c->dev.kobj, &aw8898_attribute_group); + if (ret < 0) { + dev_info(&i2c->dev, "%s error creating sysfs attr files\n", __func__); + goto err_sysfs; + } + +#ifdef AW8898_VBAT_MONITOR + aw8898_vbat_monitor_init(aw8898); +#endif + pr_info("%s probe completed successfully!\n", __func__); + + return 0; + +err_sysfs: + device_remove_bin_file(&i2c->dev, &dev_attr_regaddr); + device_remove_bin_file(&i2c->dev, &dev_attr_rw); + devm_free_irq(&i2c->dev, gpio_to_irq(aw8898->irq_gpio), aw8898); +err_irq: + snd_soc_unregister_codec(&i2c->dev); +err_register_codec: + devm_kfree(&i2c->dev, dai); + dai = NULL; +err_dai_kzalloc: +err_id: + if (gpio_is_valid(aw8898->reset_gpio)) + devm_gpio_free(&i2c->dev, aw8898->reset_gpio); + if (gpio_is_valid(aw8898->irq_gpio)) + devm_gpio_free(&i2c->dev, aw8898->irq_gpio); +err_gpio_request: +err_parse_dt: +err_regmap: + devm_kfree(&i2c->dev, aw8898); + aw8898 = NULL; + return ret; +} + +static int aw8898_i2c_remove(struct i2c_client *i2c) +{ + struct aw8898 *aw8898 = i2c_get_clientdata(i2c); + + pr_info("%s enter\n", __func__); + + device_remove_bin_file(&i2c->dev, &dev_attr_regaddr); + device_remove_bin_file(&i2c->dev, &dev_attr_rw); + devm_free_irq(&i2c->dev, gpio_to_irq(aw8898->irq_gpio), aw8898); + + snd_soc_unregister_codec(&i2c->dev); + + if (gpio_is_valid(aw8898->irq_gpio)) + devm_gpio_free(&i2c->dev, aw8898->irq_gpio); + if (gpio_is_valid(aw8898->reset_gpio)) + devm_gpio_free(&i2c->dev, aw8898->reset_gpio); + + return 0; +} + +static const struct i2c_device_id aw8898_i2c_id[] = { + { AW8898_I2C_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, aw8898_i2c_id); + +static struct of_device_id aw8898_dt_match[] = { + { .compatible = "awinic,aw8898_smartpa" }, + { }, +}; + +static struct i2c_driver aw8898_i2c_driver = { + .driver = { + .name = AW8898_I2C_NAME, + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(aw8898_dt_match), + }, + .probe = aw8898_i2c_probe, + .remove = aw8898_i2c_remove, + .id_table = aw8898_i2c_id, +}; + + +static int __init aw8898_i2c_init(void) +{ + int ret = 0; + + pr_info("aw8898 driver version %s\n", AW8898_VERSION); + + ret = i2c_add_driver(&aw8898_i2c_driver); + if(ret){ + pr_err("fail to add aw8898 device into i2c\n"); + return ret; + } + + return 0; +} +module_init(aw8898_i2c_init); + + +static void __exit aw8898_i2c_exit(void) +{ + i2c_del_driver(&aw8898_i2c_driver); +} +module_exit(aw8898_i2c_exit); + + +MODULE_DESCRIPTION("ASoC AW8898 Smart PA Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/aw/aw8898.h b/sound/soc/codecs/aw/aw8898.h new file mode 100755 index 000000000000..2042f5ecf57b --- /dev/null +++ b/sound/soc/codecs/aw/aw8898.h @@ -0,0 +1,72 @@ +#ifndef _AW8898_H_ +#define _AW8898_H_ + + +/* + * i2c transaction on Linux limited to 64k + * (See Linux kernel documentation: Documentation/i2c/writing-clients) +*/ +#define MAX_I2C_BUFFER_SIZE 65536 + +#define AW8898_FLAG_START_ON_MUTE (1 << 0) +#define AW8898_FLAG_SKIP_INTERRUPTS (1 << 1) +#define AW8898_FLAG_SAAM_AVAILABLE (1 << 2) +#define AW8898_FLAG_STEREO_DEVICE (1 << 3) +#define AW8898_FLAG_MULTI_MIC_INPUTS (1 << 4) + +#define AW8898_NUM_RATES 9 + +#define AW8898_MAX_REGISTER 0xff + +//#define AW8898_VBAT_MONITOR +#ifdef AW8898_VBAT_MONITOR +#define SYS_BAT_DEV "/sys/class/power_supply/battery/voltage_now" +#define AW8898_SYS_VBAT_LIMIT 3600000 +#define AW8898_SYS_VBAT_MIN 3000000 +#endif +enum aw8898_chipid{ + AW8898_ID, +}; + +enum aw8898_mode_spk_rcv{ + AW8898_SPEAKER_MODE = 0, + AW8898_RECEIVER_MODE = 1, +}; + +struct aw8898 { + struct regmap *regmap; + struct i2c_client *i2c; + struct snd_soc_codec *codec; + struct device *dev; + struct mutex cfg_lock; +#ifdef AW8898_VBAT_MONITOR + struct hrtimer vbat_monitor_timer; + struct work_struct vbat_monitor_work; +#endif + int sysclk; + int rate; + int pstream; + int cstream; + + int reset_gpio; + int irq_gpio; + +#ifdef CONFIG_DEBUG_FS + struct dentry *dbg_dir; +#endif + u8 reg; + + unsigned int flags; + unsigned int chipid; + unsigned int init; + unsigned int spk_rcv_mode; + unsigned int bst_ilimit; +}; + +struct aw8898_container{ + int len; + unsigned char data[]; +}; + + +#endif diff --git a/sound/soc/codecs/aw/aw8898_reg.h b/sound/soc/codecs/aw/aw8898_reg.h new file mode 100755 index 000000000000..c66927c8277e --- /dev/null +++ b/sound/soc/codecs/aw/aw8898_reg.h @@ -0,0 +1,448 @@ +#ifndef _AW8898_REG_H_ +#define _AW8898_REG_H_ + +/******************************************** + * Register List + *******************************************/ +#define AW8898_REG_ID 0x00 +#define AW8898_REG_SYSST 0x01 +#define AW8898_REG_SYSINT 0x02 +#define AW8898_REG_SYSINTM 0x03 +#define AW8898_REG_SYSCTRL 0x04 +#define AW8898_REG_I2SCTRL 0x05 +#define AW8898_REG_I2STXCFG 0x06 +#define AW8898_REG_PWMCTRL 0x08 +#define AW8898_REG_HAGCCFG1 0x09 +#define AW8898_REG_HAGCCFG2 0x0A +#define AW8898_REG_HAGCCFG3 0x0B +#define AW8898_REG_HAGCCFG4 0x0C +#define AW8898_REG_HAGCCFG5 0x0D +#define AW8898_REG_HAGCCFG6 0x0E +#define AW8898_REG_HAGCCFG7 0x0F +#define AW8898_REG_HAGCST 0x10 +#define AW8898_REG_DBGCTRL 0x20 +#define AW8898_REG_I2SCFG 0x21 +#define AW8898_REG_I2SSTAT 0x22 +#define AW8898_REG_I2SCAPCNT 0x23 +#define AW8898_REG_GENCTRL 0x60 +#define AW8898_REG_BSTCTRL1 0x61 +#define AW8898_REG_BSTCTRL2 0x62 +#define AW8898_REG_PLLCTRL1 0x63 +#define AW8898_REG_PLLCTRL2 0x64 +#define AW8898_REG_TESTCTRL 0x65 +#define AW8898_REG_AMPDBG1 0x66 +#define AW8898_REG_AMPDBG2 0x67 +#define AW8898_REG_BSTDBG1 0x68 +#define AW8898_REG_CDACTRL1 0x69 +#define AW8898_REG_CDACTRL2 0x6A +#define AW8898_REG_TESTCTRL2 0x6B + +#define AW8898_REG_MAX 0x6F + +/******************************************** + * Register Access + *******************************************/ +#define REG_NONE_ACCESS 0 +#define REG_RD_ACCESS 1 << 0 +#define REG_WR_ACCESS 1 << 1 + +const unsigned char aw8898_reg_access[AW8898_REG_MAX]={ + [AW8898_REG_ID ]= REG_RD_ACCESS, + [AW8898_REG_SYSST ]= REG_RD_ACCESS, + [AW8898_REG_SYSINT ]= REG_RD_ACCESS, + [AW8898_REG_SYSINTM ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_SYSCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_I2SCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_I2STXCFG ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_PWMCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG1 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG2 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG3 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG4 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG5 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG6 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCCFG7 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_HAGCST ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_DBGCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_I2SCFG ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_I2SSTAT ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_I2SCAPCNT ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_GENCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_BSTCTRL1 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_BSTCTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_PLLCTRL1 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_PLLCTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_TESTCTRL ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_AMPDBG1 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_AMPDBG2 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_BSTDBG1 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_CDACTRL1 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_CDACTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS, + [AW8898_REG_TESTCTRL2 ]= REG_RD_ACCESS|REG_WR_ACCESS, +}; + +/****************************************************** + * Register Detail + *****************************************************/ +// SYSST +#define AW8898_BIT_SYSST_UVLOS ( 1<<14) +#define AW8898_BIT_SYSST_ADPS ( 1<<13) +#define AW8898_BIT_SYSST_DSPS ( 1<<12) +#define AW8898_BIT_SYSST_BSTOCS ( 1<<11) +#define AW8898_BIT_SYSST_OVPS ( 1<<10) +#define AW8898_BIT_SYSST_BSTS ( 1<< 9) +#define AW8898_BIT_SYSST_SWS ( 1<< 8) +#define AW8898_BIT_SYSST_CLIPS ( 1<< 7) +#define AW8898_BIT_SYSST_WDS ( 1<< 6) +#define AW8898_BIT_SYSST_NOCLKS ( 1<< 5) +#define AW8898_BIT_SYSST_CLKS ( 1<< 4) +#define AW8898_BIT_SYSST_OCDS ( 1<< 3) +#define AW8898_BIT_SYSST_OTLS ( 1<< 2) +#define AW8898_BIT_SYSST_OTHS ( 1<< 1) +#define AW8898_BIT_SYSST_PLLS ( 1<< 0) + +// SYSINT +#define AW8898_BIT_SYSINT_UVLOI ( 1<<14) +#define AW8898_BIT_SYSINT_ADPI ( 1<<13) +#define AW8898_BIT_SYSINT_DSPI ( 1<<12) +#define AW8898_BIT_SYSINT_BSTOCI ( 1<<11) +#define AW8898_BIT_SYSINT_OVPI ( 1<<10) +#define AW8898_BIT_SYSINT_BSTI ( 1<< 9) +#define AW8898_BIT_SYSINT_SWI ( 1<< 8) +#define AW8898_BIT_SYSINT_CLIPI ( 1<< 7) +#define AW8898_BIT_SYSINT_WDI ( 1<< 6) +#define AW8898_BIT_SYSINT_NOCLKI ( 1<< 5) +#define AW8898_BIT_SYSINT_CLKI ( 1<< 4) +#define AW8898_BIT_SYSINT_OCDI ( 1<< 3) +#define AW8898_BIT_SYSINT_OTLI ( 1<< 2) +#define AW8898_BIT_SYSINT_OTHI ( 1<< 1) +#define AW8898_BIT_SYSINT_PLLI ( 1<< 0) + +// SYSINTM +#define AW8898_BIT_SYSINTM_UVLOM ( 1<<14) +#define AW8898_BIT_SYSINTM_ADPM ( 1<<13) +#define AW8898_BIT_SYSINTM_DSPM ( 1<<12) +#define AW8898_BIT_SYSINTM_BSTOCM ( 1<<11) +#define AW8898_BIT_SYSINTM_OVPM ( 1<<10) +#define AW8898_BIT_SYSINTM_BSTM ( 1<< 9) +#define AW8898_BIT_SYSINTM_SWM ( 1<< 8) +#define AW8898_BIT_SYSINTM_CLIPM ( 1<< 7) +#define AW8898_BIT_SYSINTM_WDM ( 1<< 6) +#define AW8898_BIT_SYSINTM_NOCLKM ( 1<< 5) +#define AW8898_BIT_SYSINTM_CLKM ( 1<< 4) +#define AW8898_BIT_SYSINTM_OCDM ( 1<< 3) +#define AW8898_BIT_SYSINTM_OTLM ( 1<< 2) +#define AW8898_BIT_SYSINTM_OTHM ( 1<< 1) +#define AW8898_BIT_SYSINTM_PLLM ( 1<< 0) + +// SYSCTRL +#define AW8898_BIT_SYSCTRL_INTMODE_MASK (~( 3<< 8)) +#define AW8898_BIT_SYSCTRL_INT_HIGH_PP ( 3<< 8) +#define AW8898_BIT_SYSCTRL_INT_LOW_PP ( 2<< 8) +#define AW8898_BIT_SYSCTRL_INT_HIGH_OD ( 1<< 8) +#define AW8898_BIT_SYSCTRL_INT_LOW_OD ( 0<< 8) +#define AW8898_BIT_SYSCTRL_MODE_MASK (~( 1<< 7)) +#define AW8898_BIT_SYSCTRL_RCV_MODE ( 1<< 7) +#define AW8898_BIT_SYSCTRL_SPK_MODE ( 0<< 7) +#define AW8898_BIT_SYSCTRL_I2SEN_MASK (~( 1<< 6)) +#define AW8898_BIT_SYSCTRL_I2S_ENABLE ( 1<< 6) +#define AW8898_BIT_SYSCTRL_I2S_DISABLE ( 0<< 6) +#define AW8898_BIT_SYSCTRL_WSINV_MASK (~( 1<< 5)) +#define AW8898_BIT_SYSCTRL_WS_INVERT ( 1<< 5) +#define AW8898_BIT_SYSCTRL_WS_NO_INVERT ( 0<< 5) +#define AW8898_BIT_SYSCTRL_BCKINV_MASK (~( 1<< 4)) +#define AW8898_BIT_SYSCTRL_BCK_INVERT ( 1<< 4) +#define AW8898_BIT_SYSCTRL_BCK_NO_INVERT ( 0<< 4) +#define AW8898_BIT_SYSCTRL_IPLL_MASK (~( 1<< 3)) +#define AW8898_BIT_SYSCTRL_PLL_WORD ( 1<< 3) +#define AW8898_BIT_SYSCTRL_PLL_BIT ( 0<< 3) +#define AW8898_BIT_SYSCTRL_DSPBY_MASK (~( 1<< 2)) +#define AW8898_BIT_SYSCTRL_DSP_BYPASS ( 1<< 2) +#define AW8898_BIT_SYSCTRL_DSP_WORK ( 0<< 2) +#define AW8898_BIT_SYSCTRL_CP_MASK (~( 1<< 1)) +#define AW8898_BIT_SYSCTRL_CP_PDN ( 1<< 1) +#define AW8898_BIT_SYSCTRL_CP_ACTIVE ( 0<< 1) +#define AW8898_BIT_SYSCTRL_PW_MASK (~( 1<< 0)) +#define AW8898_BIT_SYSCTRL_PW_PDN ( 1<< 0) +#define AW8898_BIT_SYSCTRL_PW_ACTIVE ( 0<< 0) + +// I2SCTRL +#define AW8898_BIT_I2SCTRL_INPLEV_MASK (~( 1<<13)) +#define AW8898_BIT_I2SCTRL_INPLEV_0DB ( 1<<13) +#define AW8898_BIT_I2SCTRL_INPLEV_NEG_6DB ( 0<<13) +#define AW8898_BIT_I2SCTRL_STEREO_MASK (~( 1<<12)) +#define AW8898_BIT_I2SCTRL_STEREO_ENABLE ( 1<<12) +#define AW8898_BIT_I2SCTRL_STEREO_DISABLE ( 0<<12) +#define AW8898_BIT_I2SCTRL_CHS_MASK (~( 3<<10)) +#define AW8898_BIT_I2SCTRL_CHS_MONO ( 3<<10) +#define AW8898_BIT_I2SCTRL_CHS_RIGHT ( 2<<10) +#define AW8898_BIT_I2SCTRL_CHS_LEFT ( 1<<10) +#define AW8898_BIT_I2SCTRL_MD_MASK (~( 3<< 8)) +#define AW8898_BIT_I2SCTRL_MD_LSB ( 2<< 8) +#define AW8898_BIT_I2SCTRL_MD_MSB ( 1<< 8) +#define AW8898_BIT_I2SCTRL_MD_STD ( 0<< 8) +#define AW8898_BIT_I2SCTRL_FMS_MASK (~( 3<< 6)) +#define AW8898_BIT_I2SCTRL_FMS_32BIT ( 3<< 6) +#define AW8898_BIT_I2SCTRL_FMS_24BIT ( 2<< 6) +#define AW8898_BIT_I2SCTRL_FMS_20BIT ( 1<< 6) +#define AW8898_BIT_I2SCTRL_FMS_16BIT ( 0<< 6) +#define AW8898_BIT_I2SCTRL_BCK_MASK (~( 3<< 4)) +#define AW8898_BIT_I2SCTRL_BCK_64FS ( 2<< 4) +#define AW8898_BIT_I2SCTRL_BCK_48FS ( 1<< 4) +#define AW8898_BIT_I2SCTRL_BCK_32FS ( 0<< 4) +#define AW8898_BIT_I2SCTRL_SR_MASK (~(15<< 0)) +#define AW8898_BIT_I2SCTRL_SR_192K (10<< 0) +#define AW8898_BIT_I2SCTRL_SR_96K ( 9<< 0) +#define AW8898_BIT_I2SCTRL_SR_48K ( 8<< 0) +#define AW8898_BIT_I2SCTRL_SR_44P1K ( 7<< 0) +#define AW8898_BIT_I2SCTRL_SR_32K ( 6<< 0) +#define AW8898_BIT_I2SCTRL_SR_24K ( 5<< 0) +#define AW8898_BIT_I2SCTRL_SR_22K ( 4<< 0) +#define AW8898_BIT_I2SCTRL_SR_16K ( 3<< 0) +#define AW8898_BIT_I2SCTRL_SR_12K ( 2<< 0) +#define AW8898_BIT_I2SCTRL_SR_11K ( 1<< 0) +#define AW8898_BIT_I2SCTRL_SR_8K ( 0<< 0) + + +// I2STXCFG +#define AW8898_BIT_I2STXCFG_FSYNC_MASK (~( 1<<15)) +#define AW8898_BIT_I2STXCFG_FSYNC_BCK_CYCLE ( 1<<15) +#define AW8898_BIT_I2STXCFG_FSYNC_ONE_SLOT ( 0<<15) +#define AW8898_BIT_I2STXCFG_SLOT_NUM_MASK (~( 1<<14)) +#define AW8898_BIT_I2STXCFG_SLOT_NUM_4_TIMES ( 1<<14) +#define AW8898_BIT_I2STXCFG_SLOT_NUM_2_TIMES ( 0<<14) +#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_MASK (~(15<<12)) +#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_3 ( 3<<12) +#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_2 ( 2<<12) +#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_1 ( 1<<12) +#define AW8898_BIT_I2STXCFG_TX_SLOT_VLD_0 ( 0<<12) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_MASK (~(15<< 8)) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3_2 (12<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3_1 (10<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3_0 ( 9<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_2_1 ( 6<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_2_0 ( 5<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_1_0 ( 3<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_3 ( 8<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_2 ( 4<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_1 ( 2<< 8) +#define AW8898_BIT_I2STXCFG_RX_SLOT_VLD_0 ( 1<< 8) +#define AW8898_BIT_I2STXCFG_DRVSTREN_MASK (~( 1<< 5)) +#define AW8898_BIT_I2STXCFG_DRVSTREN_8MA ( 1<< 5) +#define AW8898_BIT_I2STXCFG_DRVSTREN_2MA ( 0<< 5) +#define AW8898_BIT_I2STXCFG_DOHZ_MASK (~( 1<< 4)) +#define AW8898_BIT_I2STXCFG_DOHZ_HIZ ( 1<< 4) +#define AW8898_BIT_I2STXCFG_DOHZ_GND ( 0<< 4) +#define AW8898_BIT_I2STXCFG_DSEL_MASK (~( 3<< 2)) +#define AW8898_BIT_I2STXCFG_DSEL_DSP ( 2<< 2) +#define AW8898_BIT_I2STXCFG_DSEL_GAIN ( 1<< 2) +#define AW8898_BIT_I2STXCFG_DSEL_ZERO ( 0<< 2) +#define AW8898_BIT_I2STXCFG_CHS_MASK (~( 1<< 1)) +#define AW8898_BIT_I2STXCFG_CHS_RIGHT ( 1<< 1) +#define AW8898_BIT_I2STXCFG_CHS_LEFT ( 0<< 1) +#define AW8898_BIT_I2STXCFG_TX_MASK (~( 1<< 0)) +#define AW8898_BIT_I2STXCFG_TX_ENABLE ( 1<< 0) +#define AW8898_BIT_I2STXCFG_TX_DISABLE ( 0<< 0) + +// PWMCTRL +#define AW8898_BIT_PWMCTRL_DSMZTH_MASK (~(15<<12)) +#define AW8898_BIT_PWMCTRL_DSMZTH_UNIT ( 1<<12) +#define AW8898_BIT_PWMCTRL_PWMDELA_MASK (~(15<< 8)) +#define AW8898_BIT_PWMCTRL_PWMDELA_UNIT ( 1<< 8) +#define AW8898_BIT_PWMCTRL_PWMDELB_MASK (~(15<< 4)) +#define AW8898_BIT_PWMCTRL_PWMDELB_UNIT ( 1<< 4) +#define AW8898_BIT_PWMCTRL_PWMSH_MASK (~( 1<< 3)) +#define AW8898_BIT_PWMCTRL_PWMSH_TRIANGLE ( 1<< 3) +#define AW8898_BIT_PWMCTRL_PWMSH_SAWTOOTH ( 0<< 3) +#define AW8898_BIT_PWMCTRL_PWMRES_MASK (~( 1<< 2)) +#define AW8898_BIT_PWMCTRL_PWMRES_8BIT ( 1<< 2) +#define AW8898_BIT_PWMCTRL_PWMRES_7BIT ( 0<< 2) +#define AW8898_BIT_PWMCTRL_HDCCE_MASK (~( 1<< 1)) +#define AW8898_BIT_PWMCTRL_HDCCE_ENABLE ( 1<< 1) +#define AW8898_BIT_PWMCTRL_HDCCE_DISABLE ( 0<< 1) +#define AW8898_BIT_PWMCTRL_HMUTE_MASK (~( 1<< 0)) +#define AW8898_BIT_PWMCTRL_HMUTE_ENABLE ( 1<< 0) +#define AW8898_BIT_PWMCTRL_HMUTE_DISABLE ( 0<< 0) + +// HAGCCFG1 +#define AW8898_BIT_HAGCCFG1_RVTH_MASK (~(255<<8)) +#define AW8898_BIT_HAGCCFG1_RVTH_UNIT ( 1<< 8) +#define AW8898_BIT_HAGCCFG1_AVTH_MASK (~(255<<0)) +#define AW8898_BIT_HAGCCFG1_AVTH_UNIT ( 1<< 0) + +// HAGCCFG2 +#define AW8898_BIT_HAGCCFG2_ATTH_UNIT ( 1<< 0) + +// HAGCCFG3 +#define AW8898_BIT_HAGCCFG3_RTTH_UNIT ( 1<< 0) + +// HAGCCFG4 +#define AW8898_BIT_HAGCCFG4_MPD_MASK (~( 1<<14)) +#define AW8898_BIT_HAGCCFG4_MPD_ENABLE ( 1<<14) +#define AW8898_BIT_HAGCCFG4_MPD_DISABLE ( 0<<14) +#define AW8898_BIT_HAGCCFG4_MPD_TTH_MASK (~( 3<<12)) +#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P047 ( 3<<12) +#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P032 ( 2<<12) +#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P016 ( 1<<12) +#define AW8898_BIT_HAGCCFG4_MPD_TTH_0P008 ( 0<<12) +#define AW8898_BIT_HAGCCFG4_MPD_RTH_MASK (~( 3<<10)) +#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P047 ( 3<<10) +#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P032 ( 2<<10) +#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P016 ( 1<<10) +#define AW8898_BIT_HAGCCFG4_MPD_RTH_0P008 ( 0<<10) +#define AW8898_BIT_HAGCCFG4_MPD_ATH_MASK (~( 3<< 8)) +#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P047 ( 3<< 8) +#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P032 ( 2<< 8) +#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P016 ( 1<< 8) +#define AW8898_BIT_HAGCCFG4_MPD_ATH_0P008 ( 0<< 8) +#define AW8898_BIT_HAGCCFG4_HOLDTH_MASK (~(255<< 0)) + +// HAGCCFG5 + +// HAGCCFG6 + +// HAGCCFG7 +#define AW8898_BIT_HAGCCFG7_VOL_MASK (~(255< 8)) +#define AW8898_VOLUME_MAX (0) +#define AW8898_VOLUME_MIN (-255) +#define AW8898_VOL_REG_SHIFT (8) + +// HAGCST +#define AW8898_BIT_BSTVOUT_ST_10P25V (15<< 0) +#define AW8898_BIT_BSTVOUT_ST_10V (14<< 0) +#define AW8898_BIT_BSTVOUT_ST_9P75V (13<< 0) +#define AW8898_BIT_BSTVOUT_ST_9P5V (12<< 0) +#define AW8898_BIT_BSTVOUT_ST_9P25V (11<< 0) +#define AW8898_BIT_BSTVOUT_ST_9V (10<< 0) +#define AW8898_BIT_BSTVOUT_ST_8P75V ( 9<< 0) +#define AW8898_BIT_BSTVOUT_ST_8P5V ( 8<< 0) +#define AW8898_BIT_BSTVOUT_ST_8P25V ( 7<< 0) +#define AW8898_BIT_BSTVOUT_ST_8V ( 6<< 0) +#define AW8898_BIT_BSTVOUT_ST_7P75V ( 5<< 0) +#define AW8898_BIT_BSTVOUT_ST_7P5V ( 4<< 0) +#define AW8898_BIT_BSTVOUT_ST_7P25V ( 3<< 0) +#define AW8898_BIT_BSTVOUT_ST_7V ( 2<< 0) +#define AW8898_BIT_BSTVOUT_ST_6P75V ( 1<< 0) +#define AW8898_BIT_BSTVOUT_ST_6P5V ( 0<< 0) + +// DBGCTRL +#define AW8898_BIT_DBGCTRL_LPBK_FAR_MASK (~( 1<<15)) +#define AW8898_BIT_DBGCTRL_LPBK_FAR_ENABLE ( 1<<15) +#define AW8898_BIT_DBGCTRL_LPBK_FAR_DISABLE ( 0<<15) +#define AW8898_BIT_DBGCTRL_LPBK_NEAR_MASK (~( 1<<14)) +#define AW8898_BIT_DBGCTRL_LPBK_NEAR_ENABLE ( 1<<14) +#define AW8898_BIT_DBGCTRL_LPBK_NEAR_DISABLE ( 0<<14) +#define AW8898_BIT_DBGCTRL_PDUVL_MASK (~( 1<<13)) +#define AW8898_BIT_DBGCTRL_PDUVL_DISABLE ( 1<<13) +#define AW8898_BIT_DBGCTRL_PDUVL_ENABLE ( 0<<13) +#define AW8898_BIT_DBGCTRL_MUTE_MASK (~( 1<<12)) +#define AW8898_BIT_DBGCTRL_MUTE_NO_AUTO ( 1<<12) +#define AW8898_BIT_DBGCTRL_MUTE_AUTO ( 0<<12) +#define AW8898_BIT_DBGCTRL_NOCLK_RESET_MASK (~( 1<<11)) +#define AW8898_BIT_DBGCTRL_NOCLK_NO_RESET ( 1<<11) +#define AW8898_BIT_DBGCTRL_NOCLK_RESET ( 0<<11) +#define AW8898_BIT_DBGCTRL_PLL_UNLOCK_RESET_MASK (~( 1<<10)) +#define AW8898_BIT_DBGCTRL_PLL_UNLOCK_NO_RESET ( 1<<10) +#define AW8898_BIT_DBGCTRL_PLL_UNLOCK_RESET ( 0<<10) +#define AW8898_BIT_DBGCTRL_CLKMD_MASK (~( 1<< 9)) +#define AW8898_BIT_DBGCTRL_CLKMD_HALF ( 1<< 9) +#define AW8898_BIT_DBGCTRL_CLKMD_NORMAL ( 0<< 9) +#define AW8898_BIT_DBGCTRL_OSCPD_MASK (~( 1<< 8)) +#define AW8898_BIT_DBGCTRL_OSCPD_ENABLE ( 1<< 8) +#define AW8898_BIT_DBGCTRL_OSCPD_DISABLE ( 0<< 8) +#define AW8898_BIT_DBGCTRL_AMPPD_MASK (~( 1<< 7)) +#define AW8898_BIT_DBGCTRL_AMPPD_PDN ( 1<< 7) +#define AW8898_BIT_DBGCTRL_AMPPD_ACTIVE ( 0<< 7) +#define AW8898_BIT_DBGCTRL_PLLPD_MASK (~( 1<< 6)) +#define AW8898_BIT_DBGCTRL_PLLPD_PDN ( 1<< 6) +#define AW8898_BIT_DBGCTRL_PLLPD_ACTIVE ( 0<< 6) +#define AW8898_BIT_DBGCTRL_I2SRST_MASK (~( 1<< 5)) +#define AW8898_BIT_DBGCTRL_I2SRST_RESET ( 1<< 5) +#define AW8898_BIT_DBGCTRL_I2SRST_WORK ( 0<< 5) +#define AW8898_BIT_DBGCTRL_SYSRST_MASK (~( 1<< 4)) +#define AW8898_BIT_DBGCTRL_SYSRST_RESET ( 1<< 4) +#define AW8898_BIT_DBGCTRL_SYSRST_WORK ( 0<< 4) +#define AW8898_BIT_DBGCTRL_SYSCE_MASK (~( 1<< 0)) +#define AW8898_BIT_DBGCTRL_SYSCE_ENABLE ( 1<< 0) +#define AW8898_BIT_DBGCTRL_SYSCE_DISABLE ( 0<< 0) + + +// I2SCFG +#define AW8898_BIT_I2SCFG_I2SRX_MASK (~( 1<< 0)) +#define AW8898_BIT_I2SCFG_I2SRX_ENABLE ( 1<< 0) +#define AW8898_BIT_I2SCFG_I2SRX_DISABLE ( 0<< 0) + +// I2SSAT +#define AW8898_BIT_I2SSAT_DPSTAT ( 1<< 2) +#define AW8898_BIT_I2SSAT_I2SROVS ( 1<< 1) +#define AW8898_BIT_I2SSAT_I2STOVS ( 1<< 0) + +// GENCTRL +#define AW8898_BIT_GENCTRL_BURST_PEAK_MASK (~( 3<<14)) +#define AW8898_BIT_GENCTRL_BURST_PEAK_200MA ( 3<<14) +#define AW8898_BIT_GENCTRL_BURST_PEAK_160MA ( 2<<14) +#define AW8898_BIT_GENCTRL_BURST_PEAK_100MA ( 1<<14) +#define AW8898_BIT_GENCTRL_BURST_PEAK_130MA ( 0<<14) +#define AW8898_BIT_GENCTRL_BST_TDEG2_MASK (~( 7<< 9)) +#define AW8898_BIT_GENCTRL_BST_TDEG2_2P7S ( 7<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_1P3S ( 6<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_672MS ( 5<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_336MS ( 4<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_168MS ( 3<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_84MS ( 2<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_42MS ( 1<< 9) +#define AW8898_BIT_GENCTRL_BST_TDEG2_21MS ( 0<< 9) +#define AW8898_BIT_GENCTRL_BST_OCAP_MASK (~( 1<< 8)) +#define AW8898_BIT_GENCTRL_BST_OCAP_SLOW ( 1<< 8) +#define AW8898_BIT_GENCTRL_BST_OCAP_FAST ( 0<< 8) +#define AW8898_BIT_GENCTRL_BST_EN_MASK (~( 1<< 7)) +#define AW8898_BIT_GENCTRL_BST_ENABLE ( 1<< 7) +#define AW8898_BIT_GENCTRL_BST_DISABLE ( 0<< 7) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_MASK (~( 7<< 4)) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_4P5A ( 7<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_4P25A ( 6<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_4A ( 5<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_3P75A ( 4<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_3P5A ( 3<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_3P25A ( 2<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_3A ( 1<< 4) +#define AW8898_BIT_GENCTRL_BST_ILIMIT_2P75A ( 0<< 4) +#define AW8898_BIT_GENCTRL_BST_VOUT_MASK (~(15<< 0)) +#define AW8898_BIT_GENCTRL_BST_VOUT_10P25V (15<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_10V (14<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_9P75V (13<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_9P5V (12<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_9P25V (11<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_9V (10<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_8P75V ( 9<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_8P5V ( 8<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_8P25V ( 7<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_8V ( 6<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_7P75V ( 5<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_7P5V ( 4<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_7P25V ( 3<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_7V ( 2<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_6P75V ( 1<< 0) +#define AW8898_BIT_GENCTRL_BST_VOUT_6P5V ( 0<< 0) + +// BSTCTRL1 +#define AW8898_BIT_BSTCTRL1_RTH_MASK (~(64<< 8)) +#define AW8898_BIT_BSTCTRL1_ATH_MASK (~(64<< 0)) + +// BSTCTRL2 +#define AW8898_BIT_BST_MODE_MASK (~( 7<< 3)) +#define AW8898_BIT_BST_MODE_SMART_BOOST ( 6<< 3) +#define AW8898_BIT_BST_MODE_ADAPT_BOOST ( 5<< 3) +#define AW8898_BIT_BST_MODE_FORCE_BOOST ( 1<< 3) +#define AW8898_BIT_BST_MODE_TRANSP_BOOST ( 0<< 3) +#define AW8898_BIT_BST_TDEG_MASK (~( 7<< 0)) +#define AW8898_BIT_BST_TDEG_2P7S ( 7<< 0) +#define AW8898_BIT_BST_TDEG_1P3S ( 6<< 0) +#define AW8898_BIT_BST_TDEG_672MS ( 5<< 0) +#define AW8898_BIT_BST_TDEG_336MS ( 4<< 0) +#define AW8898_BIT_BST_TDEG_168MS ( 3<< 0) +#define AW8898_BIT_BST_TDEG_84MS ( 2<< 0) +#define AW8898_BIT_BST_TDEG_42MS ( 1<< 0) +#define AW8898_BIT_BST_TDEG_21MS ( 0<< 0) + +#endif -- GitLab From 3938bf3e81b93e3a08672cc750e9bb0e7a63bda9 Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Thu, 28 May 2020 14:58:48 +0800 Subject: [PATCH 25/96] Add Audio drivers for FP3 [2/4] Enable config and add drivers for 'tas2557' codec. Issue: FP3-A11#202 Change-Id: I9b9ea4f13ac2432fd3e2104438ff7362406a1428 (cherry picked from commit 55d13014376b9950ada458d4e16b26a6a28f67f9) (cherry picked from commit bde46d6932cf950e4e671647c57e5628fd9b890e) --- arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 11 + arch/arm64/configs/msm8953-perf_defconfig | 4 + arch/arm64/configs/msm8953_defconfig | 4 + sound/soc/codecs/Kconfig | 2 + sound/soc/codecs/Makefile | 1 + sound/soc/codecs/tas2557/Kconfig | 15 + sound/soc/codecs/tas2557/Makefile | 2 + sound/soc/codecs/tas2557/tas2557-codec.c | 634 ++++++ sound/soc/codecs/tas2557/tas2557-codec.h | 30 + sound/soc/codecs/tas2557/tas2557-core.c | 2117 +++++++++++++++++++++ sound/soc/codecs/tas2557/tas2557-core.h | 79 + sound/soc/codecs/tas2557/tas2557-misc.c | 595 ++++++ sound/soc/codecs/tas2557/tas2557-misc.h | 57 + sound/soc/codecs/tas2557/tas2557-regmap.c | 904 +++++++++ sound/soc/codecs/tas2557/tas2557.h | 489 +++++ sound/soc/codecs/tas2557/tiload.c | 409 ++++ sound/soc/codecs/tas2557/tiload.h | 65 + 17 files changed, 5418 insertions(+) create mode 100755 sound/soc/codecs/tas2557/Kconfig create mode 100755 sound/soc/codecs/tas2557/Makefile create mode 100755 sound/soc/codecs/tas2557/tas2557-codec.c create mode 100755 sound/soc/codecs/tas2557/tas2557-codec.h create mode 100755 sound/soc/codecs/tas2557/tas2557-core.c create mode 100755 sound/soc/codecs/tas2557/tas2557-core.h create mode 100755 sound/soc/codecs/tas2557/tas2557-misc.c create mode 100755 sound/soc/codecs/tas2557/tas2557-misc.h create mode 100755 sound/soc/codecs/tas2557/tas2557-regmap.c create mode 100755 sound/soc/codecs/tas2557/tas2557.h create mode 100755 sound/soc/codecs/tas2557/tiload.c create mode 100755 sound/soc/codecs/tas2557/tiload.h diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi index 70050ef01987..7ccd074446e0 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -69,6 +69,17 @@ status = "okay"; }; /* AWINIC AW8898 Smart PA End */ + + tas2557@4c { + sound-dai-cells = <1>; + compatible = "ti,tas2557"; + reg = <0x4c>; + ti,cdc-reset-gpio = <&tlmm 21 0>; + ti,irq-gpio = <&tlmm 20 0>; + ti,i2s-bits = <16>; + ti,bypass-tmax = <0>; + status = "ok"; + }; }; &sdhc_1 { diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index 5764ea402863..6011a1b57b4b 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -685,3 +685,7 @@ CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y CONFIG_ELAN_FINGERPRINT=y CONFIG_SND_SMARTPA_AW8898=y +CONFIG_SND_SOC_TAS2557=y +CONFIG_TAS2557_REGMAP=y +CONFIG_TAS2557_CODEC=y +CONFIG_TAS2557_MISC=y diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 121ae13af52e..0fb0e891f161 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -749,3 +749,7 @@ CONFIG_CRYPTO_CRC32_ARM64=y CONFIG_QMI_ENCDEC=y CONFIG_ELAN_FINGERPRINT=y CONFIG_SND_SMARTPA_AW8898=y +CONFIG_SND_SOC_TAS2557=y +CONFIG_TAS2557_REGMAP=y +CONFIG_TAS2557_CODEC=y +CONFIG_TAS2557_MISC=y diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 75304d22f7af..49bfc8197c83 100755 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -1103,6 +1103,8 @@ config SND_SMARTPA_AW8898 help This option enables support for aw8898 series Smart PA. +source "sound/soc/codecs/tas2557/Kconfig" + config SND_SOC_TFA98XX tristate "NXP Semiconductors TFA98XX amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 64ea9871bbd5..5c4088ff61ea 100755 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -449,3 +449,4 @@ obj-$(CONFIG_SND_SOC_AW8896) += snd-soc-aw8896.o obj-$(CONFIG_SND_SOC_TFA98XX) += snd-soc-tfa98xx.o #for AWINIC AW8898 Smart PA obj-y += aw/aw8898.o +obj-$(CONFIG_SND_SOC_TAS2557) += tas2557/ diff --git a/sound/soc/codecs/tas2557/Kconfig b/sound/soc/codecs/tas2557/Kconfig new file mode 100755 index 000000000000..acbdfcb794c4 --- /dev/null +++ b/sound/soc/codecs/tas2557/Kconfig @@ -0,0 +1,15 @@ + +menuconfig SND_SOC_TAS2557 + tristate "Texas Instruments TAS2557 SmartAmp(R)" + +if SND_SOC_TAS2557 +config TAS2557_REGMAP + bool "Use of RegMap API" + +config TAS2557_CODEC + bool "Codec Driver support" + +config TAS2557_MISC + bool "Misc Driver support" + +endif # SND_SOC_TAS2557 diff --git a/sound/soc/codecs/tas2557/Makefile b/sound/soc/codecs/tas2557/Makefile new file mode 100755 index 000000000000..128737242e7d --- /dev/null +++ b/sound/soc/codecs/tas2557/Makefile @@ -0,0 +1,2 @@ +snd-soc-tas2557-objs := tas2557-core.o tas2557-regmap.o tas2557-codec.o tas2557-misc.o tiload.o +obj-$(CONFIG_SND_SOC_TAS2557) += snd-soc-tas2557.o diff --git a/sound/soc/codecs/tas2557/tas2557-codec.c b/sound/soc/codecs/tas2557/tas2557-codec.c new file mode 100755 index 000000000000..cf9c4193ee8a --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-codec.c @@ -0,0 +1,634 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-codec.c +** +** Description: +** ALSA SoC driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier +** +** ============================================================================= +*/ + +#ifdef CONFIG_TAS2557_CODEC + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557-core.h" +#include "tas2557-codec.h" + +#define KCONTROL_CODEC + +static unsigned int tas2557_codec_read(struct snd_soc_codec *pCodec, + unsigned int nRegister) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + unsigned int Value = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = pTAS2557->read(pTAS2557, nRegister, &Value); + if (ret < 0) + dev_err(pTAS2557->dev, "%s, %d, ERROR happen=%d\n", __func__, + __LINE__, ret); + else + ret = Value; + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_codec_write(struct snd_soc_codec *pCodec, unsigned int nRegister, + unsigned int nValue) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = pTAS2557->write(pTAS2557, nRegister, nValue); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_codec_suspend(struct snd_soc_codec *pCodec) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + pTAS2557->runtime_suspend(pTAS2557); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_codec_resume(struct snd_soc_codec *pCodec) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + pTAS2557->runtime_resume(pTAS2557); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static const struct snd_soc_dapm_widget tas2557_dapm_widgets[] = { + SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("ASI2", "ASI2 Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_IN("ASIM", "ASIM Playback", 0, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUT_DRV("ClassD", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("NDivider", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("OUT") +}; + +static const struct snd_soc_dapm_route tas2557_audio_map[] = { + {"DAC", NULL, "ASI1"}, + {"DAC", NULL, "ASI2"}, + {"DAC", NULL, "ASIM"}, + {"ClassD", NULL, "DAC"}, + {"OUT", NULL, "ClassD"}, + {"DAC", NULL, "PLL"}, + {"DAC", NULL, "NDivider"}, +}; + +static int tas2557_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static void tas2557_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); +} + +static int tas2557_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + tas2557_enable(pTAS2557, !mute); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_set_dai_sysclk(struct snd_soc_dai *pDAI, + int nClkID, unsigned int nFreqency, int nDir) +{ + struct snd_soc_codec *pCodec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + dev_dbg(pTAS2557->dev, "tas2557_set_dai_sysclk: freq = %u\n", nFreqency); + + return 0; +} + +static int tas2557_hw_params(struct snd_pcm_substream *pSubstream, + struct snd_pcm_hw_params *pParams, struct snd_soc_dai *pDAI) +{ + struct snd_soc_codec *pCodec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); +/* do bit rate setting during platform data */ +/* tas2557_set_bit_rate(pTAS2557, channel_both, snd_pcm_format_width(params_format(pParams))); */ + tas2557_set_sampling_rate(pTAS2557, params_rate(pParams)); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_set_dai_fmt(struct snd_soc_dai *pDAI, unsigned int nFormat) +{ + struct snd_soc_codec *codec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_prepare(struct snd_pcm_substream *pSubstream, + struct snd_soc_dai *pDAI) +{ + struct snd_soc_codec *codec = pDAI->codec; + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_set_bias_level(struct snd_soc_codec *pCodec, + enum snd_soc_bias_level eLevel) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, eLevel); + return 0; +} + +static int tas2557_codec_probe(struct snd_soc_codec *pCodec) +{ + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(pCodec); + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_codec_remove(struct snd_soc_codec *pCodec) +{ + return 0; +} + +static int tas2557_power_ctrl_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mbPowerUp; + dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_get = %d\n", + pTAS2557->mbPowerUp); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_power_ctrl_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + int nPowerOn = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "tas2557_power_ctrl_put = %d\n", nPowerOn); + tas2557_enable(pTAS2557, (nPowerOn != 0)); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_fs_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + int nFS = 48000; + + mutex_lock(&pTAS2557->codec_lock); + + if (pTAS2557->mpFirmware->mnConfigurations) + nFS = pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration].mnSamplingRate; + pValue->value.integer.value[0] = nFS; + dev_dbg(pTAS2557->dev, "tas2557_fs_get = %d\n", nFS); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_fs_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + int ret = 0; + int nFS = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + dev_info(pTAS2557->dev, "tas2557_fs_put = %d\n", nFS); + ret = tas2557_set_sampling_rate(pTAS2557, nFS); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_Cali_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + bool ret = 0; + int prm_r0 = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = tas2557_get_Cali_prm_r0(pTAS2557, &prm_r0); + if (ret) + pValue->value.integer.value[0] = prm_r0; + + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_program_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnCurrentProgram; + dev_dbg(pTAS2557->dev, "tas2557_program_get = %d\n", + pTAS2557->mnCurrentProgram); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_program_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int nProgram = pValue->value.integer.value[0]; + int ret = 0, nConfiguration = -1; + + mutex_lock(&pTAS2557->codec_lock); + + if (nProgram == pTAS2557->mnCurrentProgram) + nConfiguration = pTAS2557->mnCurrentConfiguration; + ret = tas2557_set_program(pTAS2557, nProgram, nConfiguration); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_configuration_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnCurrentConfiguration; + dev_dbg(pTAS2557->dev, "tas2557_configuration_get = %d\n", + pTAS2557->mnCurrentConfiguration); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_configuration_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int nConfiguration = pValue->value.integer.value[0]; + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + dev_info(pTAS2557->dev, "%s = %d\n", __func__, nConfiguration); + ret = tas2557_set_config(pTAS2557, nConfiguration); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static int tas2557_calibration_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnCurrentCalibration; + dev_info(pTAS2557->dev, + "tas2557_calibration_get = %d\n", + pTAS2557->mnCurrentCalibration); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static int tas2557_calibration_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int nCalibration = pValue->value.integer.value[0]; + int ret = 0; + + mutex_lock(&pTAS2557->codec_lock); + + ret = tas2557_set_calibration(pTAS2557, nCalibration); + + mutex_unlock(&pTAS2557->codec_lock); + return ret; +} + +static const char * const classd_edge_text[] = { + "0 (50ns)", + "1 (40ns)", + "2 (29ns)", + "3 (25ns)", + "4 (14ns)", + "5 (13ns)", + "6 (12ns)", + "7 (11ns)", +}; + +static const struct soc_enum classd_edge_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(classd_edge_text), classd_edge_text), +}; + +static int tas2557_edge_get(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + mutex_lock(&pTAS2557->codec_lock); + + pValue->value.integer.value[0] = pTAS2557->mnEdge; + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} +static int tas2557_edge_put(struct snd_kcontrol *pKcontrol, + struct snd_ctl_elem_value *pValue) +{ +#ifdef KCONTROL_CODEC + struct snd_soc_codec *codec = snd_soc_kcontrol_codec(pKcontrol); +#else + struct snd_soc_codec *codec = snd_kcontrol_chip(pKcontrol); +#endif + struct tas2557_priv *pTAS2557 = snd_soc_codec_get_drvdata(codec); + unsigned int edge = pValue->value.integer.value[0]; + + mutex_lock(&pTAS2557->codec_lock); + + dev_dbg(pTAS2557->dev, "%s, edge %d\n", __func__, edge); + pTAS2557->mnEdge = pValue->value.integer.value[0]; + tas2557_update_edge(pTAS2557); + + mutex_unlock(&pTAS2557->codec_lock); + return 0; +} + +static const struct snd_kcontrol_new tas2557_snd_controls[] = { + SOC_SINGLE_EXT("PowerCtrl", SND_SOC_NOPM, 0, 0x0001, 0, + tas2557_power_ctrl_get, tas2557_power_ctrl_put), + SOC_SINGLE_EXT("Program", SND_SOC_NOPM, 0, 0x00FF, 0, tas2557_program_get, + tas2557_program_put), + SOC_SINGLE_EXT("Configuration", SND_SOC_NOPM, 0, 0x00FF, 0, + tas2557_configuration_get, tas2557_configuration_put), + SOC_SINGLE_EXT("FS", SND_SOC_NOPM, 8000, 48000, 0, + tas2557_fs_get, tas2557_fs_put), + SOC_SINGLE_EXT("Get Cali_Re", SND_SOC_NOPM, 0, 0x7f000000, 0, + tas2557_Cali_get, NULL), + SOC_SINGLE_EXT("Calibration", SND_SOC_NOPM, 0, 0x00FF, 0, + tas2557_calibration_get, tas2557_calibration_put), + SOC_ENUM_EXT("TAS2557 ClassD Edge", classd_edge_enum[0], + tas2557_edge_get, tas2557_edge_put), +}; + +static struct snd_soc_codec_driver soc_codec_driver_tas2557 = { + .probe = tas2557_codec_probe, + .remove = tas2557_codec_remove, + .read = tas2557_codec_read, + .write = tas2557_codec_write, + .suspend = tas2557_codec_suspend, + .resume = tas2557_codec_resume, + .set_bias_level = tas2557_set_bias_level, + .idle_bias_off = true, + .component_driver = { + .controls = tas2557_snd_controls, + .num_controls = ARRAY_SIZE(tas2557_snd_controls), + .dapm_widgets = tas2557_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tas2557_dapm_widgets), + .dapm_routes = tas2557_audio_map, + .num_dapm_routes = ARRAY_SIZE(tas2557_audio_map), + }, +}; + +static struct snd_soc_dai_ops tas2557_dai_ops = { + .startup = tas2557_startup, + .shutdown = tas2557_shutdown, + .digital_mute = tas2557_mute, + .hw_params = tas2557_hw_params, + .prepare = tas2557_prepare, + .set_sysclk = tas2557_set_dai_sysclk, + .set_fmt = tas2557_set_dai_fmt, +}; + +#define TAS2557_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) +static struct snd_soc_dai_driver tas2557_dai_driver[] = { + { + .name = "tas2557 ASI1", + .id = 0, + .playback = { + .stream_name = "ASI1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS2557_FORMATS, + }, + .ops = &tas2557_dai_ops, + .symmetric_rates = 1, + }, + { + .name = "tas2557 ASI2", + .id = 1, + .playback = { + .stream_name = "ASI2 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS2557_FORMATS, + }, + .ops = &tas2557_dai_ops, + .symmetric_rates = 1, + }, + { + .name = "tas2557 ASIM", + .id = 2, + .playback = { + .stream_name = "ASIM Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = TAS2557_FORMATS, + }, + .ops = &tas2557_dai_ops, + .symmetric_rates = 1, + }, +}; + +int tas2557_register_codec(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + + dev_info(pTAS2557->dev, "%s, enter\n", __func__); + nResult = snd_soc_register_codec(pTAS2557->dev, + &soc_codec_driver_tas2557, + tas2557_dai_driver, ARRAY_SIZE(tas2557_dai_driver)); + return nResult; +} + +int tas2557_deregister_codec(struct tas2557_priv *pTAS2557) +{ + snd_soc_unregister_codec(pTAS2557->dev); + return 0; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 ALSA SOC Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); +#endif diff --git a/sound/soc/codecs/tas2557/tas2557-codec.h b/sound/soc/codecs/tas2557/tas2557-codec.h new file mode 100755 index 000000000000..8e20270c6b92 --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-codec.h @@ -0,0 +1,30 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-codec.h +** +** Description: +** header file for tas2557-codec.c +** +** ============================================================================= +*/ + +#ifndef _TAS2557_CODEC_H +#define _TAS2557_CODEC_H + +#include "tas2557.h" + +int tas2557_register_codec(struct tas2557_priv *pTAS2557); +int tas2557_deregister_codec(struct tas2557_priv *pTAS2557); + +#endif /* _TAS2557_CODEC_H */ diff --git a/sound/soc/codecs/tas2557/tas2557-core.c b/sound/soc/codecs/tas2557/tas2557-core.c new file mode 100755 index 000000000000..783642cc05ca --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-core.c @@ -0,0 +1,2117 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-core.c +** +** Description: +** TAS2557 common functions for Android Linux +** +** ============================================================================= +*/ + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557.h" +#include "tas2557-core.h" + +#define PPC_DRIVER_CRCCHK 0x00000200 +#define PPC_DRIVER_CONFDEV 0x00000300 +#define PPC_DRIVER_MTPLLSRC 0x00000400 +#define PPC_DRIVER_CFGDEV_NONCRC 0x00000101 + +#define TAS2557_CAL_NAME "/data/tas2557_cal.bin" +#define RESTART_MAX 3 + +static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, + char *pFileName); +static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, + unsigned int nType); +static void tas2557_clear_firmware(struct TFirmware *pFirmware); +static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock); +static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, + unsigned int nConfiguration, bool bLoadSame); + +#define TAS2557_UDELAY 0xFFFFFFFE +#define TAS2557_MDELAY 0xFFFFFFFD + +#define TAS2557_BLOCK_PLL 0x00 +#define TAS2557_BLOCK_PGM_ALL 0x0d +#define TAS2557_BLOCK_PGM_DEV_A 0x01 +#define TAS2557_BLOCK_PGM_DEV_B 0x08 +#define TAS2557_BLOCK_CFG_COEFF_DEV_A 0x03 +#define TAS2557_BLOCK_CFG_COEFF_DEV_B 0x0a +#define TAS2557_BLOCK_CFG_PRE_DEV_A 0x04 +#define TAS2557_BLOCK_CFG_PRE_DEV_B 0x0b +#define TAS2557_BLOCK_CFG_POST 0x05 +#define TAS2557_BLOCK_CFG_POST_POWER 0x06 + +static unsigned int p_tas2557_default_data[] = { + TAS2557_SAR_ADC2_REG, 0x05, /* enable SAR ADC */ + TAS2557_CLK_ERR_CTRL2, 0x21, /*clk1:clock hysteresis, 0.34ms; clock halt, 22ms*/ + TAS2557_CLK_ERR_CTRL3, 0x21, /*clk2: rampDown 15dB/us, clock hysteresis, 10.66us; clock halt, 22ms */ + TAS2557_SAFE_GUARD_REG, TAS2557_SAFE_GUARD_PATTERN, /* safe guard */ + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static unsigned int p_tas2557_irq_config[] = { + TAS2557_CLK_HALT_REG, 0x71, /* enable clk halt detect2 interrupt */ + TAS2557_INT_GEN1_REG, 0x11, /* enable spk OC and OV */ + TAS2557_INT_GEN2_REG, 0x11, /* enable clk err1 and die OT */ + TAS2557_INT_GEN3_REG, 0x11, /* enable clk err2 and brownout */ + TAS2557_INT_GEN4_REG, 0x01, /* disable SAR, enable clk halt */ + TAS2557_GPIO4_PIN_REG, 0x07, /* set GPIO4 as int1, default */ + TAS2557_INT_MODE_REG, 0x80, /* active high until INT_STICKY_1 and INT_STICKY_2 are read to be cleared. */ + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static unsigned int p_tas2557_startup_data[] = { + TAS2557_GPI_PIN_REG, 0x15, /* enable DIN, MCLK, CCI */ + TAS2557_GPIO1_PIN_REG, 0x01, /* enable BCLK */ + TAS2557_GPIO2_PIN_REG, 0x01, /* enable WCLK */ + TAS2557_POWER_CTRL2_REG, 0xA0, /* Class-D, Boost power up */ + TAS2557_POWER_CTRL2_REG, 0xA3, /* Class-D, Boost, IV sense power up */ + TAS2557_POWER_CTRL1_REG, 0xF8, /* PLL, DSP, clock dividers power up */ + TAS2557_UDELAY, 2000, /* delay */ + TAS2557_CLK_ERR_CTRL, 0x2b, /* enable clock error detection */ + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static unsigned int p_tas2557_unmute_data[] = { + TAS2557_MUTE_REG, 0x00, /* unmute */ + TAS2557_SOFT_MUTE_REG, 0x00, /* soft unmute */ + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static unsigned int p_tas2557_shutdown_data[] = { + TAS2557_CLK_ERR_CTRL, 0x00, /* disable clock error detection */ + TAS2557_SOFT_MUTE_REG, 0x01, /* soft mute */ + TAS2557_UDELAY, 10000, /* delay 10ms */ + TAS2557_MUTE_REG, 0x03, /* mute */ + TAS2557_POWER_CTRL1_REG, 0x60, /* DSP power down */ + TAS2557_UDELAY, 2000, /* delay 2ms */ + TAS2557_POWER_CTRL2_REG, 0x00, /* Class-D, Boost power down */ + TAS2557_POWER_CTRL1_REG, 0x00, /* all power down */ + TAS2557_GPIO1_PIN_REG, 0x00, /* disable BCLK */ + TAS2557_GPIO2_PIN_REG, 0x00, /* disable WCLK */ + TAS2557_GPI_PIN_REG, 0x00, /* disable DIN, MCLK, CCI */ + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static int tas2557_dev_load_data(struct tas2557_priv *pTAS2557, + unsigned int *pData) +{ + int ret = 0; + unsigned int n = 0; + unsigned int nRegister; + unsigned int nData; + + do { + nRegister = pData[n * 2]; + nData = pData[n * 2 + 1]; + if (nRegister == TAS2557_UDELAY) + udelay(nData); + else if (nRegister != 0xFFFFFFFF) { + ret = pTAS2557->write(pTAS2557, nRegister, nData); + if (ret < 0) + break; + } + n++; + } while (nRegister != 0xFFFFFFFF); + return ret; +} + +int tas2557_configIRQ(struct tas2557_priv *pTAS2557) +{ + return tas2557_dev_load_data(pTAS2557, p_tas2557_irq_config); +} + +int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate) +{ + int ret = 0, n = -1; + + dev_dbg(pTAS2557->dev, "tas2557_set_bit_rate: nBitRate = %d\n", nBitRate); + + switch (nBitRate) { + case 16: + n = 0; + break; + case 20: + n = 1; + break; + case 24: + n = 2; + break; + case 32: + n = 3; + break; + } + + if (n >= 0) + ret = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x18, n<<3); + return ret; +} + +int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate) +{ + int ret = 0; + unsigned int nValue = 0; + unsigned char bitRate; + + ret = pTAS2557->read(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, &nValue); + if (ret >= 0) { + bitRate = (nValue&0x18)>>3; + if (bitRate == 0) + bitRate = 16; + else if (bitRate == 1) + bitRate = 20; + else if (bitRate == 2) + bitRate = 24; + else if (bitRate == 3) + bitRate = 32; + *pBitRate = bitRate; + } + + return ret; +} + +int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain) +{ + int ret = 0; + unsigned int nValue = 0; + + ret = pTAS2557->read(pTAS2557, TAS2557_SPK_CTRL_REG, &nValue); + if (ret >= 0) + *pnGain = ((nValue&TAS2557_DAC_GAIN_MASK)>>TAS2557_DAC_GAIN_SHIFT); + + return ret; +} + +int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain) +{ + int ret = 0; + + ret = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, TAS2557_DAC_GAIN_MASK, + (nGain<mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + if (!pTAS2557->mbPowerUp) { + dev_err(pTAS2557->dev, "%s, device not powered on\n", __func__); + goto end; + } + + nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_DIE_TEMP_REG, nBuf, 4); + if (nResult >= 0) { + temp = ((int)nBuf[0] << 24) | ((int)nBuf[1] << 16) | ((int)nBuf[2] << 8) | nBuf[3]; + *pTemperature = temp; + } + +end: + + return nResult; +} + +int tas2557_load_platdata(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + nResult = tas2557_configIRQ(pTAS2557); + if (nResult < 0) + goto end; + } + + nResult = tas2557_set_bit_rate(pTAS2557, pTAS2557->mnI2SBits); + +end: + + return nResult; +} + +int tas2557_load_default(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_default_data); + if (nResult < 0) + goto end; + + nResult = tas2557_load_platdata(pTAS2557); + if (nResult < 0) + goto end; + + /* enable DOUT tri-state for extra BCLKs */ + nResult = pTAS2557->update_bits(pTAS2557, TAS2557_ASI1_DAC_FORMAT_REG, 0x01, 0x01); +end: + + return nResult; +} + +static void failsafe(struct tas2557_priv *pTAS2557) +{ + int ret; + + dev_err(pTAS2557->dev, "%s\n", __func__); + pTAS2557->mnErrCode |= ERROR_FAILSAFE; + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + if(pTAS2557->mnRestart < RESTART_MAX) + { + pTAS2557->mnRestart ++; + msleep(100); + dev_err(pTAS2557->dev, "I2C COMM error, restart SmartAmp.\n"); + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100)); + return; + } + pTAS2557->enableIRQ(pTAS2557, false, false); + ret = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + if (ret < 0) + dev_dbg(pTAS2557->dev, "failed load shutdown\n"); + + pTAS2557->mbPowerUp = false; + pTAS2557->hw_reset(pTAS2557); + ret = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01); + if (ret < 0) + dev_dbg(pTAS2557->dev, "failed sw reset\n"); + + udelay(1000); + ret = pTAS2557->write(pTAS2557, TAS2557_SPK_CTRL_REG, 0x04); + if (ret < 0) + dev_dbg(pTAS2557->dev, "failed in spk ctrl\n"); + if (pTAS2557->mpFirmware != NULL) + tas2557_clear_firmware(pTAS2557->mpFirmware); + + pTAS2557->mpFirmware->mnPrograms = 0; +} + +int tas2557_checkPLL(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; +/* +* TO DO +*/ + + return nResult; +} + +/* +* tas2557_load_coefficient +*/ +static int tas2557_load_coefficient(struct tas2557_priv *pTAS2557, + int nPrevConfig, int nNewConfig, bool bPowerOn) +{ + int nResult = 0; + struct TPLL *pPLL; + struct TProgram *pProgram; + struct TConfiguration *pPrevConfiguration; + struct TConfiguration *pNewConfiguration; + bool bRestorePower = false; + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + if (nNewConfig >= pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "%s, invalid configuration New=%d, total=%d\n", + __func__, nNewConfig, pTAS2557->mpFirmware->mnConfigurations); + goto end; + } + + if (nPrevConfig < 0) + pPrevConfiguration = NULL; + else if (nPrevConfig == nNewConfig) { + dev_dbg(pTAS2557->dev, "%s, config [%d] already loaded\n", + __func__, nNewConfig); + goto end; + } else + pPrevConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nPrevConfig]); + + pNewConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nNewConfig]); + pTAS2557->mnCurrentConfiguration = nNewConfig; + if (pPrevConfiguration) { + if (pPrevConfiguration->mnPLL == pNewConfiguration->mnPLL) { + dev_dbg(pTAS2557->dev, "%s, PLL same\n", __func__); + goto prog_coefficient; + } + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (bPowerOn) { + dev_dbg(pTAS2557->dev, "%s, power down to load new PLL\n", __func__); + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) + pTAS2557->enableIRQ(pTAS2557, false, false); + + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + if (nResult < 0) + goto end; + bRestorePower = true; + } + + /* load PLL */ + pPLL = &(pTAS2557->mpFirmware->mpPLLs[pNewConfiguration->mnPLL]); + dev_dbg(pTAS2557->dev, "load PLL: %s block for Configuration %s\n", + pPLL->mpName, pNewConfiguration->mpName); + nResult = tas2557_load_block(pTAS2557, &(pPLL->mBlock)); + if (nResult < 0) + goto end; + pTAS2557->mnCurrentSampleRate = pNewConfiguration->mnSamplingRate; + + dev_dbg(pTAS2557->dev, "load configuration %s conefficient pre block\n", + pNewConfiguration->mpName); + nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), TAS2557_BLOCK_CFG_PRE_DEV_A); + if (nResult < 0) + goto end; + +prog_coefficient: + dev_dbg(pTAS2557->dev, "load new configuration: %s, coeff block data\n", + pNewConfiguration->mpName); + nResult = tas2557_load_data(pTAS2557, &(pNewConfiguration->mData), + TAS2557_BLOCK_CFG_COEFF_DEV_A); + if (nResult < 0) + goto end; + + if (pTAS2557->mpCalFirmware->mnCalibrations) { + nResult = tas2557_set_calibration(pTAS2557, pTAS2557->mnCurrentCalibration); + if (nResult < 0) + goto end; + } + + if (bRestorePower) { + pTAS2557->clearIRQ(pTAS2557); + dev_dbg(pTAS2557->dev, "device powered up, load startup\n"); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + } + dev_dbg(pTAS2557->dev, + "device powered up, load unmute\n"); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + pTAS2557->enableIRQ(pTAS2557, true, true); + if (!hrtimer_active(&pTAS2557->mtimer)) { + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start(&pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + } + } +end: + + pTAS2557->mnNewConfiguration = pTAS2557->mnCurrentConfiguration; + return nResult; +} + +int tas2557_update_edge(struct tas2557_priv *pTAS2557) +{ + int nResult = 0; + dev_dbg(pTAS2557->dev, + "%s, edge: %d\n", + __func__, pTAS2557->mnEdge); + + nResult = pTAS2557->update_bits(pTAS2557, TAS2557_SPK_CTRL_REG, 0x7, pTAS2557->mnEdge); + + return nResult; +} + +int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable) +{ + int nResult = 0; + unsigned int nValue; + const char *pFWName; + struct TProgram *pProgram; + + dev_dbg(pTAS2557->dev, "Enable: %d\n", bEnable); + + if ((pTAS2557->mpFirmware->mnPrograms == 0) + || (pTAS2557->mpFirmware->mnConfigurations == 0)) { + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + /*Load firmware*/ + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) { + dev_info(pTAS2557->dev, "PG2.1 Silicon found\n"); + pFWName = TAS2557_FW_NAME; + } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) { + dev_info(pTAS2557->dev, "PG1.0 Silicon found\n"); + pFWName = TAS2557_PG1P0_FW_NAME; + } else { + nResult = -ENOTSUPP; + dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", pTAS2557->mnPGID); + goto end; + } + nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName, + pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready); + if(nResult < 0) + goto end; + dev_err(pTAS2557->dev, "%s, firmware is loaded\n", __func__); + } + + /* check safe guard*/ + nResult = pTAS2557->read(pTAS2557, TAS2557_SAFE_GUARD_REG, &nValue); + if (nResult < 0) + goto end; + if ((nValue&0xff) != TAS2557_SAFE_GUARD_PATTERN) { + dev_err(pTAS2557->dev, "ERROR safe guard failure!\n"); + nResult = -EPIPE; + pTAS2557->mnErrCode = ERROR_SAFE_GUARD; + pTAS2557->mbPowerUp = true; + goto end; + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (bEnable) { + if (!pTAS2557->mbPowerUp) { + if (!pTAS2557->mbCalibrationLoaded) { + tas2557_set_calibration(pTAS2557, 0xFF); + pTAS2557->mbCalibrationLoaded = true; + } + + if (pTAS2557->mbLoadConfigurationPrePowerUp) { + dev_dbg(pTAS2557->dev, "load coefficient before power\n"); + pTAS2557->mbLoadConfigurationPrePowerUp = false; + nResult = tas2557_load_coefficient(pTAS2557, + pTAS2557->mnCurrentConfiguration, pTAS2557->mnNewConfiguration, false); + if (nResult < 0) + goto end; + } + + pTAS2557->clearIRQ(pTAS2557); + /* power on device */ + dev_dbg(pTAS2557->dev, "Enable: load startup sequence\n"); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + goto end; + } + } + dev_dbg(pTAS2557->dev, "Enable: load unmute sequence\n"); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); + if (nResult < 0) + goto end; + + pTAS2557->mbPowerUp = true; + + tas2557_get_die_temperature(pTAS2557, &nValue); + if(nValue == 0x80000000) + { + dev_err(pTAS2557->dev, "%s, thermal sensor is wrong, mute output\n", __func__); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + /* turn on IRQ */ + pTAS2557->enableIRQ(pTAS2557, true, true); + if (!hrtimer_active(&pTAS2557->mtimer)) { + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start(&pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + } + pTAS2557->mnRestart = 0; + } + } else { + if (pTAS2557->mbPowerUp) { + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + dev_dbg(pTAS2557->dev, "Enable: load shutdown sequence\n"); + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + /* turn off IRQ */ + pTAS2557->enableIRQ(pTAS2557, false, false); + } + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + if (nResult < 0) + goto end; + + pTAS2557->mbPowerUp = false; + pTAS2557->mnRestart = 0; + } + } + + nResult = 0; + +end: + if (nResult < 0) { + if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK | ERROR_SAFE_GUARD)) + failsafe(pTAS2557); + } + + return nResult; +} + +int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate) +{ + int nResult = 0; + struct TConfiguration *pConfiguration; + unsigned int nConfiguration; + + dev_dbg(pTAS2557->dev, "tas2557_setup_clocks: nSamplingRate = %d [Hz]\n", + nSamplingRate); + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = -EINVAL; + goto end; + } + + pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + if (pConfiguration->mnSamplingRate == nSamplingRate) { + dev_info(pTAS2557->dev, "Sampling rate for current configuration matches: %d\n", + nSamplingRate); + nResult = 0; + goto end; + } + + for (nConfiguration = 0; + nConfiguration < pTAS2557->mpFirmware->mnConfigurations; + nConfiguration++) { + pConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]); + if ((pConfiguration->mnSamplingRate == nSamplingRate) + && (pConfiguration->mnProgram == pTAS2557->mnCurrentProgram)) { + dev_info(pTAS2557->dev, + "Found configuration: %s, with compatible sampling rate %d\n", + pConfiguration->mpName, nSamplingRate); + nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false); + goto end; + } + } + + dev_err(pTAS2557->dev, "Cannot find a configuration that supports sampling rate: %d\n", + nSamplingRate); + +end: + + return nResult; +} + +static void fw_print_header(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware) +{ + dev_info(pTAS2557->dev, "FW Size = %d", pFirmware->mnFWSize); + dev_info(pTAS2557->dev, "Checksum = 0x%04X", pFirmware->mnChecksum); + dev_info(pTAS2557->dev, "PPC Version = 0x%04X", pFirmware->mnPPCVersion); + dev_info(pTAS2557->dev, "FW Version = 0x%04X", pFirmware->mnFWVersion); + dev_info(pTAS2557->dev, "Driver Version= 0x%04X", pFirmware->mnDriverVersion); + dev_info(pTAS2557->dev, "Timestamp = %d", pFirmware->mnTimeStamp); + dev_info(pTAS2557->dev, "DDC Name = %s", pFirmware->mpDDCName); + dev_info(pTAS2557->dev, "Description = %s", pFirmware->mpDescription); +} + +inline unsigned int fw_convert_number(unsigned char *pData) +{ + return pData[3] + (pData[2] << 8) + (pData[1] << 16) + (pData[0] << 24); +} + +static int fw_parse_header(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned char pMagicNumber[] = { 0x35, 0x35, 0x35, 0x32 }; + + if (nSize < 104) { + dev_err(pTAS2557->dev, "Firmware: Header too short"); + return -EINVAL; + } + + if (memcmp(pData, pMagicNumber, 4)) { + dev_err(pTAS2557->dev, "Firmware: Magic number doesn't match"); + return -EINVAL; + } + pData += 4; + + pFirmware->mnFWSize = fw_convert_number(pData); + pData += 4; + + pFirmware->mnChecksum = fw_convert_number(pData); + pData += 4; + + pFirmware->mnPPCVersion = fw_convert_number(pData); + pData += 4; + + pFirmware->mnFWVersion = fw_convert_number(pData); + pData += 4; + + pFirmware->mnDriverVersion = fw_convert_number(pData); + pData += 4; + + pFirmware->mnTimeStamp = fw_convert_number(pData); + pData += 4; + + memcpy(pFirmware->mpDDCName, pData, 64); + pData += 64; + + n = strlen(pData); + pFirmware->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + if ((pData - pDataStart) >= nSize) { + dev_err(pTAS2557->dev, "Firmware: Header too short after DDC description"); + return -EINVAL; + } + + pFirmware->mnDeviceFamily = fw_convert_number(pData); + pData += 4; + if (pFirmware->mnDeviceFamily != 0) { + dev_err(pTAS2557->dev, + "deviceFamily %d, not TAS device", pFirmware->mnDeviceFamily); + return -EINVAL; + } + + pFirmware->mnDevice = fw_convert_number(pData); + pData += 4; + + if (pFirmware->mnDevice != 2) { + dev_err(pTAS2557->dev, + "device %d, not TAS2557 Dual Mono", pFirmware->mnDevice); + return -EINVAL; + } + + fw_print_header(pTAS2557, pFirmware); + return pData - pDataStart; +} + +static int fw_parse_block_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware, + struct TBlock *pBlock, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + + pBlock->mnType = fw_convert_number(pData); + pData += 4; + + if (pFirmware->mnDriverVersion >= PPC_DRIVER_CRCCHK) { + pBlock->mbPChkSumPresent = pData[0]; + pData++; + + pBlock->mnPChkSum = pData[0]; + pData++; + + pBlock->mbYChkSumPresent = pData[0]; + pData++; + + pBlock->mnYChkSum = pData[0]; + pData++; + } else { + pBlock->mbPChkSumPresent = 0; + pBlock->mbYChkSumPresent = 0; + } + + pBlock->mnCommands = fw_convert_number(pData); + pData += 4; + + n = pBlock->mnCommands * 4; + pBlock->mpData = kmemdup(pData, n, GFP_KERNEL); + pData += n; + return pData - pDataStart; +} + +static int fw_parse_data(struct tas2557_priv *pTAS2557, struct TFirmware *pFirmware, + struct TData *pImageData, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int nBlock; + unsigned int n; + + memcpy(pImageData->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pImageData->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + pImageData->mnBlocks = (pData[0] << 8) + pData[1]; + pData += 2; + + pImageData->mpBlocks = + kmalloc(sizeof(struct TBlock) * pImageData->mnBlocks, GFP_KERNEL); + if(pImageData->mpBlocks == NULL) + { + dev_dbg(pTAS2557->dev, "failed malloc blocks mem\n"); + goto end; + } + + for (nBlock = 0; nBlock < pImageData->mnBlocks; nBlock++) { + n = fw_parse_block_data(pTAS2557, pFirmware, + &(pImageData->mpBlocks[nBlock]), pData); + pData += n; + } + +end: + return pData - pDataStart; +} + +static int fw_parse_pll_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nPLL; + struct TPLL *pPLL; + + pFirmware->mnPLLs = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnPLLs == 0) + goto end; + + pFirmware->mpPLLs = kmalloc_array(pFirmware->mnPLLs, sizeof(struct TPLL), GFP_KERNEL); + for (nPLL = 0; nPLL < pFirmware->mnPLLs; nPLL++) { + pPLL = &(pFirmware->mpPLLs[nPLL]); + + memcpy(pPLL->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pPLL->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + n = fw_parse_block_data(pTAS2557, pFirmware, &(pPLL->mBlock), pData); + pData += n; + } + +end: + return pData - pDataStart; +} + +static int fw_parse_program_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nProgram; + struct TProgram *pProgram; + + pFirmware->mnPrograms = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnPrograms == 0) + goto end; + + pFirmware->mpPrograms = + kmalloc(sizeof(struct TProgram) * pFirmware->mnPrograms, GFP_KERNEL); + if(pFirmware->mpPrograms == NULL) + { + dev_dbg(pTAS2557->dev, "failed malloc program mem\n"); + goto end; + } + + for (nProgram = 0; nProgram < pFirmware->mnPrograms; nProgram++) { + pProgram = &(pFirmware->mpPrograms[nProgram]); + memcpy(pProgram->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pProgram->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + pProgram->mnAppMode = pData[0]; + pData++; + + pProgram->mnBoost = (pData[0] << 8) + pData[1]; + pData += 2; + + n = fw_parse_data(pTAS2557, pFirmware, &(pProgram->mData), pData); + pData += n; + } + +end: + + return pData - pDataStart; +} + +static int fw_parse_configuration_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nConfiguration; + struct TConfiguration *pConfiguration; + + pFirmware->mnConfigurations = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnConfigurations == 0) + goto end; + + pFirmware->mpConfigurations = + kmalloc(sizeof(struct TConfiguration) * pFirmware->mnConfigurations, + GFP_KERNEL); + if(pFirmware->mpConfigurations == NULL) + { + dev_dbg(pTAS2557->dev, "failed malloc configuration mem\n"); + goto end; + } + + for (nConfiguration = 0; nConfiguration < pFirmware->mnConfigurations; + nConfiguration++) { + pConfiguration = &(pFirmware->mpConfigurations[nConfiguration]); + memcpy(pConfiguration->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pConfiguration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + if ((pFirmware->mnDriverVersion >= PPC_DRIVER_CONFDEV) + || ((pFirmware->mnDriverVersion >= PPC_DRIVER_CFGDEV_NONCRC) + && (pFirmware->mnDriverVersion < PPC_DRIVER_CRCCHK))) { + pConfiguration->mnDevices = (pData[0] << 8) + pData[1]; + pData += 2; + } else + pConfiguration->mnDevices = 1; + + pConfiguration->mnProgram = pData[0]; + pData++; + + pConfiguration->mnPLL = pData[0]; + pData++; + + pConfiguration->mnSamplingRate = fw_convert_number(pData); + pData += 4; + + if (pFirmware->mnDriverVersion >= PPC_DRIVER_MTPLLSRC) { + pConfiguration->mnPLLSrc = pData[0]; + pData++; + + pConfiguration->mnPLLSrcRate = fw_convert_number(pData); + pData += 4; + } + + n = fw_parse_data(pTAS2557, pFirmware, &(pConfiguration->mData), pData); + pData += n; + } + +end: + + return pData - pDataStart; +} + +int fw_parse_calibration_data(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData) +{ + unsigned char *pDataStart = pData; + unsigned int n; + unsigned int nCalibration; + struct TCalibration *pCalibration; + + pFirmware->mnCalibrations = (pData[0] << 8) + pData[1]; + pData += 2; + + if (pFirmware->mnCalibrations == 0) + goto end; + + pFirmware->mpCalibrations = + kmalloc(sizeof(struct TCalibration) * pFirmware->mnCalibrations, GFP_KERNEL); + if(pFirmware->mpCalibrations == NULL) + { + dev_err(pTAS2557->dev, "failed to malloc calibration mem\n"); + goto end; + } + + for (nCalibration = 0; + nCalibration < pFirmware->mnCalibrations; + nCalibration++) { + pCalibration = &(pFirmware->mpCalibrations[nCalibration]); + memcpy(pCalibration->mpName, pData, 64); + pData += 64; + + n = strlen(pData); + pCalibration->mpDescription = kmemdup(pData, n + 1, GFP_KERNEL); + pData += n + 1; + + pCalibration->mnProgram = pData[0]; + pData++; + + pCalibration->mnConfiguration = pData[0]; + pData++; + + n = fw_parse_data(pTAS2557, pFirmware, &(pCalibration->mData), pData); + pData += n; + } + +end: + + return pData - pDataStart; +} + +static int fw_parse(struct tas2557_priv *pTAS2557, + struct TFirmware *pFirmware, unsigned char *pData, unsigned int nSize) +{ + int nPosition = 0; + + nPosition = fw_parse_header(pTAS2557, pFirmware, pData, nSize); + if (nPosition < 0) { + dev_err(pTAS2557->dev, "Firmware: Wrong Header"); + return -EINVAL; + } + + if (nPosition >= nSize) { + dev_err(pTAS2557->dev, "Firmware: Too short"); + return -EINVAL; + } + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + nPosition = fw_parse_pll_data(pTAS2557, pFirmware, pData); + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + nPosition = fw_parse_program_data(pTAS2557, pFirmware, pData); + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + nPosition = fw_parse_configuration_data(pTAS2557, pFirmware, pData); + + pData += nPosition; + nSize -= nPosition; + nPosition = 0; + + if (nSize > 64) + nPosition = fw_parse_calibration_data(pTAS2557, pFirmware, pData); + return 0; +} + + +static const unsigned char crc8_lookup_table[CRC8_TABLE_SIZE] = { +0x00, 0x4D, 0x9A, 0xD7, 0x79, 0x34, 0xE3, 0xAE, 0xF2, 0xBF, 0x68, 0x25, 0x8B, 0xC6, 0x11, 0x5C, +0xA9, 0xE4, 0x33, 0x7E, 0xD0, 0x9D, 0x4A, 0x07, 0x5B, 0x16, 0xC1, 0x8C, 0x22, 0x6F, 0xB8, 0xF5, +0x1F, 0x52, 0x85, 0xC8, 0x66, 0x2B, 0xFC, 0xB1, 0xED, 0xA0, 0x77, 0x3A, 0x94, 0xD9, 0x0E, 0x43, +0xB6, 0xFB, 0x2C, 0x61, 0xCF, 0x82, 0x55, 0x18, 0x44, 0x09, 0xDE, 0x93, 0x3D, 0x70, 0xA7, 0xEA, +0x3E, 0x73, 0xA4, 0xE9, 0x47, 0x0A, 0xDD, 0x90, 0xCC, 0x81, 0x56, 0x1B, 0xB5, 0xF8, 0x2F, 0x62, +0x97, 0xDA, 0x0D, 0x40, 0xEE, 0xA3, 0x74, 0x39, 0x65, 0x28, 0xFF, 0xB2, 0x1C, 0x51, 0x86, 0xCB, +0x21, 0x6C, 0xBB, 0xF6, 0x58, 0x15, 0xC2, 0x8F, 0xD3, 0x9E, 0x49, 0x04, 0xAA, 0xE7, 0x30, 0x7D, +0x88, 0xC5, 0x12, 0x5F, 0xF1, 0xBC, 0x6B, 0x26, 0x7A, 0x37, 0xE0, 0xAD, 0x03, 0x4E, 0x99, 0xD4, +0x7C, 0x31, 0xE6, 0xAB, 0x05, 0x48, 0x9F, 0xD2, 0x8E, 0xC3, 0x14, 0x59, 0xF7, 0xBA, 0x6D, 0x20, +0xD5, 0x98, 0x4F, 0x02, 0xAC, 0xE1, 0x36, 0x7B, 0x27, 0x6A, 0xBD, 0xF0, 0x5E, 0x13, 0xC4, 0x89, +0x63, 0x2E, 0xF9, 0xB4, 0x1A, 0x57, 0x80, 0xCD, 0x91, 0xDC, 0x0B, 0x46, 0xE8, 0xA5, 0x72, 0x3F, +0xCA, 0x87, 0x50, 0x1D, 0xB3, 0xFE, 0x29, 0x64, 0x38, 0x75, 0xA2, 0xEF, 0x41, 0x0C, 0xDB, 0x96, +0x42, 0x0F, 0xD8, 0x95, 0x3B, 0x76, 0xA1, 0xEC, 0xB0, 0xFD, 0x2A, 0x67, 0xC9, 0x84, 0x53, 0x1E, +0xEB, 0xA6, 0x71, 0x3C, 0x92, 0xDF, 0x08, 0x45, 0x19, 0x54, 0x83, 0xCE, 0x60, 0x2D, 0xFA, 0xB7, +0x5D, 0x10, 0xC7, 0x8A, 0x24, 0x69, 0xBE, 0xF3, 0xAF, 0xE2, 0x35, 0x78, 0xD6, 0x9B, 0x4C, 0x01, +0xF4, 0xB9, 0x6E, 0x23, 0x8D, 0xC0, 0x17, 0x5A, 0x06, 0x4B, 0x9C, 0xD1, 0x7F, 0x32, 0xE5, 0xA8 +}; + +static int isInPageYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData, + unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len) +{ + int nResult = 0; + + if (nBook == TAS2557_YRAM_BOOK1) { + if (nPage == TAS2557_YRAM1_PAGE) { + if (nReg >= TAS2557_YRAM1_START_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } else if ((nReg + len) > TAS2557_YRAM1_START_REG) { + pCRCData->mnOffset = TAS2557_YRAM1_START_REG; + pCRCData->mnLen = len - (TAS2557_YRAM1_START_REG - nReg); + nResult = 1; + } else + nResult = 0; + } else if (nPage == TAS2557_YRAM3_PAGE) { + if (nReg > TAS2557_YRAM3_END_REG) { + nResult = 0; + } else if (nReg >= TAS2557_YRAM3_START_REG) { + if ((nReg + len) > TAS2557_YRAM3_END_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = TAS2557_YRAM3_END_REG - nReg + 1; + nResult = 1; + } else { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } + } else { + if ((nReg + (len - 1)) < TAS2557_YRAM3_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = TAS2557_YRAM3_START_REG; + pCRCData->mnLen = len - (TAS2557_YRAM3_START_REG - nReg); + nResult = 1; + } + } + } + } else if (nBook == TAS2557_YRAM_BOOK2) { + if (nPage == TAS2557_YRAM5_PAGE) { + if (nReg > TAS2557_YRAM5_END_REG) { + nResult = 0; + } else if (nReg >= TAS2557_YRAM5_START_REG) { + if ((nReg + len) > TAS2557_YRAM5_END_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = TAS2557_YRAM5_END_REG - nReg + 1; + nResult = 1; + } else { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } + } else { + if ((nReg + (len - 1)) < TAS2557_YRAM5_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = TAS2557_YRAM5_START_REG; + pCRCData->mnLen = len - (TAS2557_YRAM5_START_REG - nReg); + nResult = 1; + } + } + } + } else + nResult = 0; + + return nResult; +} + +static int isInBlockYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData, + unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len) +{ + int nResult; + + if (nBook == TAS2557_YRAM_BOOK1) { + if (nPage < TAS2557_YRAM2_START_PAGE) + nResult = 0; + else if (nPage <= TAS2557_YRAM2_END_PAGE) { + if (nReg > TAS2557_YRAM2_END_REG) + nResult = 0; + else if (nReg >= TAS2557_YRAM2_START_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } else { + if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = TAS2557_YRAM2_START_REG; + pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG; + nResult = 1; + } + } + } else + nResult = 0; + } else if (nBook == TAS2557_YRAM_BOOK2) { + if (nPage < TAS2557_YRAM4_START_PAGE) + nResult = 0; + else if (nPage <= TAS2557_YRAM4_END_PAGE) { + if (nReg > TAS2557_YRAM2_END_REG) + nResult = 0; + else if (nReg >= TAS2557_YRAM2_START_REG) { + pCRCData->mnOffset = nReg; + pCRCData->mnLen = len; + nResult = 1; + } else { + if ((nReg + (len - 1)) < TAS2557_YRAM2_START_REG) + nResult = 0; + else { + pCRCData->mnOffset = TAS2557_YRAM2_START_REG; + pCRCData->mnLen = nReg + len - TAS2557_YRAM2_START_REG; + nResult = 1; + } + } + } else + nResult = 0; + } else + nResult = 0; + + return nResult; +} + + +static int isYRAM(struct tas2557_priv *pTAS2557, struct TYCRC *pCRCData, + unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char len) +{ + int nResult; + + nResult = isInPageYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len); + + if (nResult == 0) + nResult = isInBlockYRAM(pTAS2557, pCRCData, nBook, nPage, nReg, len); + + return nResult; +} + +/* + * crc8 - calculate a crc8 over the given input data. + * + * table: crc table used for calculation. + * pdata: pointer to data buffer. + * nbytes: number of bytes in data buffer. + * crc: previous returned crc8 value. + */ +static u8 ti_crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc) +{ + /* loop over the buffer data */ + while (nbytes-- > 0) + crc = table[(crc ^ *pdata++) & 0xff]; + + return crc; +} + +static int doSingleRegCheckSum(struct tas2557_priv *pTAS2557, + unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned char nValue) +{ + int nResult = 0; + struct TYCRC sCRCData; + unsigned int nData1 = 0; + + if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG)) + && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG)) + && (nReg >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG)) + && (nReg <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) { + /* DSP swap command, pass */ + nResult = 0; + goto end; + } + + nResult = isYRAM(pTAS2557, &sCRCData, nBook, nPage, nReg, 1); + if (nResult == 1) { + nResult = pTAS2557->read(pTAS2557, TAS2557_REG(nBook, nPage, nReg), &nData1); + if (nResult < 0) + goto end; + + if (nData1 != nValue) { + dev_err(pTAS2557->dev, "error2 (line %d),B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n", + __LINE__, nBook, nPage, nReg, nValue, nData1); + nResult = -EAGAIN; + goto end; + } + + nResult = ti_crc8(crc8_lookup_table, &nValue, 1, 0); + } + +end: + + return nResult; +} + +static int doMultiRegCheckSum(struct tas2557_priv *pTAS2557, + unsigned char nBook, unsigned char nPage, unsigned char nReg, unsigned int len) +{ + int nResult = 0, i; + unsigned char nCRCChkSum = 0; + unsigned char nBuf1[128]; + struct TYCRC TCRCData; + + if ((nReg + len-1) > 127) { + nResult = -EINVAL; + dev_err(pTAS2557->dev, "firmware error\n"); + goto end; + } + + if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG)) + && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG)) + && (nReg == TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG)) + && (len == 4)) { + /* DSP swap command, pass */ + nResult = 0; + goto end; + } + + nResult = isYRAM(pTAS2557, &TCRCData, nBook, nPage, nReg, len); + if (nResult == 1) { + if (len == 1) { + dev_err(pTAS2557->dev, "firmware error\n"); + nResult = -EINVAL; + goto end; + } else { + nResult = pTAS2557->bulk_read(pTAS2557, TAS2557_REG(nBook, nPage, TCRCData.mnOffset), nBuf1, TCRCData.mnLen); + if (nResult < 0) + goto end; + + for (i = 0; i < TCRCData.mnLen; i++) { + if ((nBook == TAS2557_BOOK_ID(TAS2557_SA_COEFF_SWAP_REG)) + && (nPage == TAS2557_PAGE_ID(TAS2557_SA_COEFF_SWAP_REG)) + && ((i + TCRCData.mnOffset) + >= TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG)) + && ((i + TCRCData.mnOffset) + <= (TAS2557_PAGE_REG(TAS2557_SA_COEFF_SWAP_REG) + 4))) { + /* DSP swap command, bypass */ + continue; + } else + nCRCChkSum += ti_crc8(crc8_lookup_table, &nBuf1[i], 1, 0); + } + + nResult = nCRCChkSum; + } + } + +end: + + return nResult; +} + +static int tas2557_load_block(struct tas2557_priv *pTAS2557, struct TBlock *pBlock) +{ + int nResult = 0; + unsigned int nCommand = 0; + unsigned char nBook; + unsigned char nPage; + unsigned char nOffset; + unsigned char nData; + unsigned int nLength; + unsigned int nSleep; + unsigned char nCRCChkSum = 0; + unsigned int nValue1; + int nRetry = 6; + unsigned char *pData = pBlock->mpData; + + dev_dbg(pTAS2557->dev, "TAS2557 load block: Type = %d, commands = %d\n", + pBlock->mnType, pBlock->mnCommands); +start: + if (pBlock->mbPChkSumPresent) { + nResult = pTAS2557->write(pTAS2557, TAS2557_CRC_RESET_REG, 1); + if (nResult < 0) + goto end; + } + + if (pBlock->mbYChkSumPresent) + nCRCChkSum = 0; + + nCommand = 0; + + while (nCommand < pBlock->mnCommands) { + pData = pBlock->mpData + nCommand * 4; + + nBook = pData[0]; + nPage = pData[1]; + nOffset = pData[2]; + nData = pData[3]; + + nCommand++; + + if (nOffset <= 0x7F) { + nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), nData); + if (nResult < 0) + goto end; + if (pBlock->mbYChkSumPresent) { + nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, nData); + if (nResult < 0) + goto check; + nCRCChkSum += (unsigned char)nResult; + } + } else if (nOffset == 0x81) { + nSleep = (nBook << 8) + nPage; + msleep(nSleep); + } else if (nOffset == 0x85) { + pData += 4; + nLength = (nBook << 8) + nPage; + nBook = pData[0]; + nPage = pData[1]; + nOffset = pData[2]; + if (nLength > 1) { + nResult = pTAS2557->bulk_write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData + 3, nLength); + if (nResult < 0) + goto end; + if (pBlock->mbYChkSumPresent) { + nResult = doMultiRegCheckSum(pTAS2557, nBook, nPage, nOffset, nLength); + if (nResult < 0) + goto check; + nCRCChkSum += (unsigned char)nResult; + } + } else { + nResult = pTAS2557->write(pTAS2557, TAS2557_REG(nBook, nPage, nOffset), pData[3]); + if (nResult < 0) + goto end; + if (pBlock->mbYChkSumPresent) { + nResult = doSingleRegCheckSum(pTAS2557, nBook, nPage, nOffset, pData[3]); + if (nResult < 0) + goto check; + nCRCChkSum += (unsigned char)nResult; + } + } + + nCommand++; + + if (nLength >= 2) + nCommand += ((nLength - 2) / 4) + 1; + } + } + if (pBlock->mbPChkSumPresent) { + nResult = pTAS2557->read(pTAS2557, TAS2557_CRC_CHECKSUM_REG, &nValue1); + if (nResult < 0) + goto end; + if ((nValue1&0xff) != pBlock->mnPChkSum) { + dev_err(pTAS2557->dev, "Block PChkSum Error: FW = 0x%x, Reg = 0x%x\n", + pBlock->mnPChkSum, (nValue1&0xff)); + nResult = -EAGAIN; + pTAS2557->mnErrCode |= ERROR_PRAM_CRCCHK; + goto check; + } + + nResult = 0; + pTAS2557->mnErrCode &= ~ERROR_PRAM_CRCCHK; + dev_dbg(pTAS2557->dev, "Block[0x%x] PChkSum match\n", pBlock->mnType); + } + + if (pBlock->mbYChkSumPresent) { + if (nCRCChkSum != pBlock->mnYChkSum) { + dev_err(pTAS2557->dev, "Block YChkSum Error: FW = 0x%x, YCRC = 0x%x\n", + pBlock->mnYChkSum, nCRCChkSum); + nResult = -EAGAIN; + pTAS2557->mnErrCode |= ERROR_YRAM_CRCCHK; + goto check; + } + pTAS2557->mnErrCode &= ~ERROR_YRAM_CRCCHK; + nResult = 0; + dev_dbg(pTAS2557->dev, "Block[0x%x] YChkSum match\n", pBlock->mnType); + } + +check: + if (nResult == -EAGAIN) { + nRetry--; + if (nRetry > 0) + goto start; + } + +end: + if (nResult < 0) { + dev_err(pTAS2557->dev, "Block (%d) load error\n", + pBlock->mnType); + } + return nResult; +} + +static int tas2557_load_data(struct tas2557_priv *pTAS2557, struct TData *pData, unsigned int nType) +{ + int nResult = 0; + unsigned int nBlock; + struct TBlock *pBlock; + + dev_dbg(pTAS2557->dev, + "TAS2557 load data: %s, Blocks = %d, Block Type = %d\n", pData->mpName, pData->mnBlocks, nType); + + for (nBlock = 0; nBlock < pData->mnBlocks; nBlock++) { + pBlock = &(pData->mpBlocks[nBlock]); + if (pBlock->mnType == nType) { + nResult = tas2557_load_block(pTAS2557, pBlock); + if (nResult < 0) + break; + } + } + + return nResult; +} + +static int tas2557_load_configuration(struct tas2557_priv *pTAS2557, + unsigned int nConfiguration, bool bLoadSame) +{ + int nResult = 0; + struct TConfiguration *pCurrentConfiguration = NULL; + struct TConfiguration *pNewConfiguration = NULL; + + dev_dbg(pTAS2557->dev, "%s: %d\n", __func__, nConfiguration); + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = 0; + goto end; + } + + if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n", + nConfiguration); + nResult = 0; + goto end; + } + + if ((!pTAS2557->mbLoadConfigurationPrePowerUp) + && (nConfiguration == pTAS2557->mnCurrentConfiguration) + && (!bLoadSame)) { + dev_info(pTAS2557->dev, "Configuration %d is already loaded\n", + nConfiguration); + nResult = 0; + goto end; + } + + pCurrentConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + pNewConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]); + if (pNewConfiguration->mnProgram != pCurrentConfiguration->mnProgram) { + dev_err(pTAS2557->dev, "Configuration %d, %s doesn't share the same program as current %d\n", + nConfiguration, pNewConfiguration->mpName, pCurrentConfiguration->mnProgram); + nResult = 0; + goto end; + } + + if (pNewConfiguration->mnPLL >= pTAS2557->mpFirmware->mnPLLs) { + dev_err(pTAS2557->dev, "Configuration %d, %s doesn't have a valid PLL index %d\n", + nConfiguration, pNewConfiguration->mpName, pNewConfiguration->mnPLL); + nResult = 0; + goto end; + } + + if (pTAS2557->mbPowerUp) { + pTAS2557->mbLoadConfigurationPrePowerUp = false; + nResult = tas2557_load_coefficient(pTAS2557, pTAS2557->mnCurrentConfiguration, nConfiguration, true); + } else { + dev_dbg(pTAS2557->dev, + "TAS2557 was powered down, will load coefficient when power up\n"); + pTAS2557->mbLoadConfigurationPrePowerUp = true; + pTAS2557->mnNewConfiguration = nConfiguration; + } + +end: + + if (nResult < 0) { + if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); + } + + return nResult; +} + +int tas2557_set_config(struct tas2557_priv *pTAS2557, int config) +{ + struct TConfiguration *pConfiguration; + struct TProgram *pProgram; + unsigned int nProgram = pTAS2557->mnCurrentProgram; + unsigned int nConfiguration = config; + int nResult = 0; + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = -EINVAL; + goto end; + } + + if (nConfiguration >= pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "Configuration %d doesn't exist\n", + nConfiguration); + nResult = -EINVAL; + goto end; + } + + pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[nConfiguration]); + pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]); + + if (nProgram != pConfiguration->mnProgram) { + dev_err(pTAS2557->dev, + "Configuration %d, %s with Program %d isn't compatible with existing Program %d, %s\n", + nConfiguration, pConfiguration->mpName, pConfiguration->mnProgram, + nProgram, pProgram->mpName); + nResult = -EINVAL; + goto end; + } + + nResult = tas2557_load_configuration(pTAS2557, nConfiguration, false); + +end: + + return nResult; +} + +void tas2557_clear_firmware(struct TFirmware *pFirmware) +{ + unsigned int n, nn; + + if (!pFirmware) + return; + + kfree(pFirmware->mpDescription); + + if (pFirmware->mpPLLs != NULL) { + for (n = 0; n < pFirmware->mnPLLs; n++) { + kfree(pFirmware->mpPLLs[n].mpDescription); + kfree(pFirmware->mpPLLs[n].mBlock.mpData); + } + kfree(pFirmware->mpPLLs); + } + + if (pFirmware->mpPrograms != NULL) { + for (n = 0; n < pFirmware->mnPrograms; n++) { + kfree(pFirmware->mpPrograms[n].mpDescription); + kfree(pFirmware->mpPrograms[n].mData.mpDescription); + for (nn = 0; nn < pFirmware->mpPrograms[n].mData.mnBlocks; nn++) + kfree(pFirmware->mpPrograms[n].mData.mpBlocks[nn].mpData); + kfree(pFirmware->mpPrograms[n].mData.mpBlocks); + } + kfree(pFirmware->mpPrograms); + } + + if (pFirmware->mpConfigurations != NULL) { + for (n = 0; n < pFirmware->mnConfigurations; n++) { + kfree(pFirmware->mpConfigurations[n].mpDescription); + kfree(pFirmware->mpConfigurations[n].mData.mpDescription); + for (nn = 0; nn < pFirmware->mpConfigurations[n].mData.mnBlocks; nn++) + kfree(pFirmware->mpConfigurations[n].mData.mpBlocks[nn].mpData); + kfree(pFirmware->mpConfigurations[n].mData.mpBlocks); + } + kfree(pFirmware->mpConfigurations); + } + + if (pFirmware->mpCalibrations != NULL) { + for (n = 0; n < pFirmware->mnCalibrations; n++) { + kfree(pFirmware->mpCalibrations[n].mpDescription); + kfree(pFirmware->mpCalibrations[n].mData.mpDescription); + for (nn = 0; nn < pFirmware->mpCalibrations[n].mData.mnBlocks; nn++) + kfree(pFirmware->mpCalibrations[n].mData.mpBlocks[nn].mpData); + kfree(pFirmware->mpCalibrations[n].mData.mpBlocks); + } + kfree(pFirmware->mpCalibrations); + } + + memset(pFirmware, 0x00, sizeof(struct TFirmware)); +} + +static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, char *pFileName) +{ + int nResult = 0; + + int nFile; + mm_segment_t fs; + unsigned char pBuffer[1000]; + int nSize = 0; + + dev_dbg(pTAS2557->dev, "%s:\n", __func__); + + fs = get_fs(); + set_fs(KERNEL_DS); + nFile = sys_open(pFileName, O_RDONLY, 0); + + dev_info(pTAS2557->dev, "TAS2557 calibration file = %s, handle = %d\n", + pFileName, nFile); + + if (nFile >= 0) { + nSize = sys_read(nFile, pBuffer, 1000); + sys_close(nFile); + } else { + dev_err(pTAS2557->dev, "TAS2557 cannot open calibration file: %s\n", + pFileName); + } + + set_fs(fs); + + if (!nSize) + goto end; + + tas2557_clear_firmware(pTAS2557->mpCalFirmware); + dev_info(pTAS2557->dev, "TAS2557 calibration file size = %d\n", nSize); + nResult = fw_parse(pTAS2557, pTAS2557->mpCalFirmware, pBuffer, nSize); + + if (nResult) + dev_err(pTAS2557->dev, "TAS2557 calibration file is corrupt\n"); + else + dev_info(pTAS2557->dev, "TAS2557 calibration: %d calibrations\n", + pTAS2557->mpCalFirmware->mnCalibrations); +end: + + return nResult; +} + +static bool tas2557_get_coefficient_in_block(struct tas2557_priv *pTAS2557, + struct TBlock *pBlock, int nReg, int *pnValue) +{ + int nCoefficient = 0; + bool bFound = false; + unsigned char *pCommands; + int nBook, nPage, nOffset, len; + int i, n; + + pCommands = pBlock->mpData; + for (i = 0 ; i < pBlock->mnCommands;) { + nBook = pCommands[4 * i + 0]; + nPage = pCommands[4 * i + 1]; + nOffset = pCommands[4 * i + 2]; + if ((nOffset < 0x7f) || (nOffset == 0x81)) + i++; + else if (nOffset == 0x85) { + len = ((int)nBook << 8) | nPage; + nBook = pCommands[4 * i + 4]; + nPage = pCommands[4 * i + 5]; + nOffset = pCommands[4 * i + 6]; + n = 4 * i + 7; + i += 2; + i += ((len - 1) / 4); + if ((len - 1) % 4) + i++; + if ((nBook != TAS2557_BOOK_ID(nReg)) + || (nPage != TAS2557_PAGE_ID(nReg))) + continue; + if (nOffset > TAS2557_PAGE_REG(nReg)) + continue; + if ((len + nOffset) >= (TAS2557_PAGE_REG(nReg) + 4)) { + n += (TAS2557_PAGE_REG(nReg) - nOffset); + nCoefficient = ((int)pCommands[n] << 24) + | ((int)pCommands[n + 1] << 16) + | ((int)pCommands[n + 2] << 8) + | (int)pCommands[n + 3]; + bFound = true; + break; + } + } else { + dev_err(pTAS2557->dev, "%s, format error %d\n", __func__, nOffset); + break; + } + } + + if (bFound) { + *pnValue = nCoefficient; + dev_dbg(pTAS2557->dev, "%s, B[0x%x]P[0x%x]R[0x%x]=0x%x\n", __func__, + TAS2557_BOOK_ID(nReg), TAS2557_PAGE_ID(nReg), TAS2557_PAGE_REG(nReg), + nCoefficient); + } + + return bFound; +} + +static bool tas2557_get_coefficient_in_data(struct tas2557_priv *pTAS2557, + struct TData *pData, int blockType, int nReg, int *pnValue) +{ + bool bFound = false; + struct TBlock *pBlock; + int i; + + for (i = 0; i < pData->mnBlocks; i++) { + pBlock = &(pData->mpBlocks[i]); + if (pBlock->mnType == blockType) { + bFound = tas2557_get_coefficient_in_block(pTAS2557, + pBlock, nReg, pnValue); + if (bFound) + break; + } + } + + return bFound; +} + +static bool tas2557_find_Tmax_in_configuration(struct tas2557_priv *pTAS2557, + struct TConfiguration *pConfiguration, int *pnTMax) +{ + struct TData *pData; + bool bFound = false; + int nBlockType, nReg, nCoefficient; + + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + nReg = TAS2557_PG2P1_CALI_T_REG; + else + nReg = TAS2557_PG1P0_CALI_T_REG; + + nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A; + + pData = &(pConfiguration->mData); + bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCoefficient); + if (bFound) + *pnTMax = nCoefficient; + + return bFound; +} + +void tas2557_fw_ready(const struct firmware *pFW, void *pContext) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *) pContext; + int nResult; + unsigned int nProgram = 0; + unsigned int nSampleRate = 0; + +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + + dev_info(pTAS2557->dev, "%s:\n", __func__); + + if (unlikely(!pFW) || unlikely(!pFW->data)) { + dev_err(pTAS2557->dev, "%s firmware is not loaded.\n", + TAS2557_FW_NAME); + goto end; + } + + if (pTAS2557->mpFirmware->mpConfigurations) { + nProgram = pTAS2557->mnCurrentProgram; + nSampleRate = pTAS2557->mnCurrentSampleRate; + dev_dbg(pTAS2557->dev, "clear current firmware\n"); + tas2557_clear_firmware(pTAS2557->mpFirmware); + } + + nResult = fw_parse(pTAS2557, pTAS2557->mpFirmware, (unsigned char *)(pFW->data), pFW->size); + release_firmware(pFW); + if (nResult < 0) { + dev_err(pTAS2557->dev, "firmware is corrupt\n"); + goto end; + } + + if (!pTAS2557->mpFirmware->mnPrograms) { + dev_err(pTAS2557->dev, "firmware contains no programs\n"); + nResult = -EINVAL; + goto end; + } + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_err(pTAS2557->dev, "firmware contains no configurations\n"); + nResult = -EINVAL; + goto end; + } + + if (nProgram >= pTAS2557->mpFirmware->mnPrograms) { + dev_info(pTAS2557->dev, + "no previous program, set to default\n"); + nProgram = 0; + } + + pTAS2557->mnCurrentSampleRate = nSampleRate; + nResult = tas2557_set_program(pTAS2557, nProgram, -1); +end: + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif +} + +int tas2557_set_program(struct tas2557_priv *pTAS2557, + unsigned int nProgram, int nConfig) +{ + struct TProgram *pProgram; + unsigned int nConfiguration = 0; + unsigned int nSampleRate = 0; + unsigned char nGain; + bool bFound = false; + int nResult = 0; + + if ((!pTAS2557->mpFirmware->mpPrograms) || + (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n"); + nResult = 0; + goto end; + } + + if (nProgram >= pTAS2557->mpFirmware->mnPrograms) { + dev_err(pTAS2557->dev, "TAS2557: Program %d doesn't exist\n", + nProgram); + nResult = 0; + goto end; + } + + if (nConfig < 0) { + nConfiguration = 0; + nSampleRate = pTAS2557->mnCurrentSampleRate; + while (!bFound && (nConfiguration < pTAS2557->mpFirmware->mnConfigurations)) { + if (pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnProgram == nProgram) { + if (nSampleRate == 0) { + bFound = true; + dev_info(pTAS2557->dev, "find default configuration %d\n", nConfiguration); + } else if (nSampleRate == pTAS2557->mpFirmware->mpConfigurations[nConfiguration].mnSamplingRate) { + bFound = true; + dev_info(pTAS2557->dev, "find matching configuration %d\n", nConfiguration); + } else { + nConfiguration++; + } + } else { + nConfiguration++; + } + } + if (!bFound) { + dev_err(pTAS2557->dev, + "Program %d, no valid configuration found for sample rate %d, ignore\n", + nProgram, nSampleRate); + nResult = 0; + goto end; + } + } else { + if (pTAS2557->mpFirmware->mpConfigurations[nConfig].mnProgram != nProgram) { + dev_err(pTAS2557->dev, "%s, configuration program doesn't match\n", __func__); + nResult = 0; + goto end; + } + nConfiguration = nConfig; + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[nProgram]); + if (pTAS2557->mbPowerUp) { + dev_info(pTAS2557->dev, + "device powered up, power down to load program %d (%s)\n", + nProgram, pProgram->mpName); + if (hrtimer_active(&pTAS2557->mtimer)) + hrtimer_cancel(&pTAS2557->mtimer); + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) + pTAS2557->enableIRQ(pTAS2557, false, false); + + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + if (nResult < 0) + goto end; + } + + pTAS2557->hw_reset(pTAS2557); + nResult = pTAS2557->write(pTAS2557, TAS2557_SW_RESET_REG, 0x01); + if (nResult < 0) + goto end; + msleep(1); + nResult = tas2557_load_default(pTAS2557); + if (nResult < 0) + goto end; + + dev_info(pTAS2557->dev, "load program %d (%s)\n", nProgram, pProgram->mpName); + nResult = tas2557_load_data(pTAS2557, &(pProgram->mData), TAS2557_BLOCK_PGM_DEV_A); + if (nResult < 0) + goto end; + pTAS2557->mnCurrentProgram = nProgram; + + nResult = tas2557_get_DAC_gain(pTAS2557, &nGain); + if (nResult < 0) + goto end; + pTAS2557->mnDevGain = nGain; + pTAS2557->mnDevCurrentGain = nGain; + + nResult = tas2557_load_coefficient(pTAS2557, -1, nConfiguration, false); + if (nResult < 0) + goto end; + + tas2557_update_edge(pTAS2557); + + if (pTAS2557->mbPowerUp) { + pTAS2557->clearIRQ(pTAS2557); + dev_dbg(pTAS2557->dev, "device powered up, load startup\n"); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_startup_data); + if (nResult < 0) + goto end; + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + nResult = tas2557_checkPLL(pTAS2557); + if (nResult < 0) { + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_shutdown_data); + pTAS2557->mbPowerUp = false; + goto end; + } + } + dev_dbg(pTAS2557->dev, "device powered up, load unmute\n"); + nResult = tas2557_dev_load_data(pTAS2557, p_tas2557_unmute_data); + if (nResult < 0) + goto end; + + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + pTAS2557->enableIRQ(pTAS2557, true, true); + if (!hrtimer_active(&pTAS2557->mtimer)) { + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start(&pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + } + } + +end: + + if (nResult < 0) { + if (pTAS2557->mnErrCode & (ERROR_DEVA_I2C_COMM | ERROR_PRAM_CRCCHK | ERROR_YRAM_CRCCHK)) + failsafe(pTAS2557); + } + return nResult; +} + +int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration) +{ + struct TCalibration *pCalibration = NULL; + struct TConfiguration *pConfiguration; + struct TProgram *pProgram; + int nTmax = 0; + bool bFound = false; + int nResult = 0; + + if ((!pTAS2557->mpFirmware->mpPrograms) + || (!pTAS2557->mpFirmware->mpConfigurations)) { + dev_err(pTAS2557->dev, "Firmware not loaded\n\r"); + nResult = 0; + goto end; + } + + if (nCalibration == 0x00FF) { + nResult = tas2557_load_calibration(pTAS2557, TAS2557_CAL_NAME); + if (nResult < 0) { + dev_info(pTAS2557->dev, "load new calibration file %s fail %d\n", + TAS2557_CAL_NAME, nResult); + goto end; + } + nCalibration = 0; + } + + if (nCalibration >= pTAS2557->mpCalFirmware->mnCalibrations) { + dev_err(pTAS2557->dev, + "Calibration %d doesn't exist\n", nCalibration); + nResult = 0; + goto end; + } + + pTAS2557->mnCurrentCalibration = nCalibration; + if (pTAS2557->mbLoadConfigurationPrePowerUp) + goto end; + + pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[nCalibration]); + pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + if (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE) { + if (pTAS2557->mbBypassTMax) { + bFound = tas2557_find_Tmax_in_configuration(pTAS2557, pConfiguration, &nTmax); + if (bFound && (nTmax == TAS2557_COEFFICIENT_TMAX)) { + dev_dbg(pTAS2557->dev, "%s, config[%s] bypass load calibration\n", + __func__, pConfiguration->mpName); + goto end; + } + } + + dev_dbg(pTAS2557->dev, "%s, load calibration\n", __func__); + nResult = tas2557_load_data(pTAS2557, &(pCalibration->mData), TAS2557_BLOCK_CFG_COEFF_DEV_A); + if (nResult < 0) + goto end; + } + +end: + if (nResult < 0) { + tas2557_clear_firmware(pTAS2557->mpCalFirmware); + nResult = tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration); + } + + return nResult; +} + +bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0) +{ + struct TCalibration *pCalibration; + struct TData *pData; + int nReg; + int nCali_Re; + bool bFound = false; + int nBlockType; + + if (!pTAS2557->mpCalFirmware->mnCalibrations) { + dev_err(pTAS2557->dev, "%s, no calibration data\n", __func__); + goto end; + } + + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + nReg = TAS2557_PG2P1_CALI_R0_REG; + else + nReg = TAS2557_PG1P0_CALI_R0_REG; + + nBlockType = TAS2557_BLOCK_CFG_COEFF_DEV_A; + + pCalibration = &(pTAS2557->mpCalFirmware->mpCalibrations[pTAS2557->mnCurrentCalibration]); + pData = &(pCalibration->mData); + + bFound = tas2557_get_coefficient_in_data(pTAS2557, pData, nBlockType, nReg, &nCali_Re); + +end: + + if (bFound) + *prm_r0 = nCali_Re; + + return bFound; +} + +int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557) +{ + struct device_node *np = dev->of_node; + int rc = 0, ret = 0; + unsigned int value; + + pTAS2557->mnResetGPIO = of_get_named_gpio(np, "ti,cdc-reset-gpio", 0); + if (!gpio_is_valid(pTAS2557->mnResetGPIO)) { + dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n", + "ti,cdc-reset-gpio", np->full_name, + pTAS2557->mnResetGPIO); + ret = -EINVAL; + goto end; + } else + dev_dbg(pTAS2557->dev, "ti,cdc-reset-gpio=%d\n", pTAS2557->mnResetGPIO); + + pTAS2557->mnGpioINT = of_get_named_gpio(np, "ti,irq-gpio", 0); + if (!gpio_is_valid(pTAS2557->mnGpioINT)) + dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n", + "ti,irq-gpio", np->full_name, + pTAS2557->mnGpioINT); + + + rc = of_property_read_u32(np, "ti,i2s-bits", &value); + if (rc) + dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n", + "ti,i2s-bits", np->full_name, rc); + else + pTAS2557->mnI2SBits = value; + + rc = of_property_read_u32(np, "ti,bypass-tmax", &value); + if (rc) + dev_err(pTAS2557->dev, "Looking up %s property in node %s failed %d\n", + "ti,bypass-tmax", np->full_name, rc); + else + pTAS2557->mbBypassTMax = (value > 0); + +end: + + return ret; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 common functions for Android Linux"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/tas2557/tas2557-core.h b/sound/soc/codecs/tas2557/tas2557-core.h new file mode 100755 index 000000000000..cb46eee35320 --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-core.h @@ -0,0 +1,79 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-core.h +** +** Description: +** header file for tas2557-core.c +** +** ============================================================================= +*/ + +#ifndef _TAS2557_CORE_H +#define _TAS2557_CORE_H + +#include "tas2557.h" + +#define TAS2557_YRAM_BOOK1 140 + +#define TAS2557_YRAM1_PAGE 42 +#define TAS2557_YRAM1_START_REG 88 +#define TAS2557_YRAM1_END_REG 127 + +#define TAS2557_YRAM2_START_PAGE 43 +#define TAS2557_YRAM2_END_PAGE 49 +#define TAS2557_YRAM2_START_REG 8 +#define TAS2557_YRAM2_END_REG 127 + +#define TAS2557_YRAM3_PAGE 50 +#define TAS2557_YRAM3_START_REG 8 +#define TAS2557_YRAM3_END_REG 27 + +/* should not include B0_P53_R44-R47 */ +#define TAS2557_YRAM_BOOK2 0 +#define TAS2557_YRAM4_START_PAGE 50 +#define TAS2557_YRAM4_END_PAGE 60 +#define TAS2557_YRAM4_START_REG 8 +#define TAS2557_YRAM4_END_REG 127 + +#define TAS2557_YRAM5_PAGE 61 +#define TAS2557_YRAM5_START_REG 8 +#define TAS2557_YRAM5_END_REG 27 + +#define TAS2557_COEFFICIENT_TMAX 0x7fffffff +#define TAS2557_SAFE_GUARD_PATTERN 0x5a +#define LOW_TEMPERATURE_CHECK_PERIOD 5000 /* 5 second */ + +struct TYCRC { + unsigned char mnOffset; + unsigned char mnLen; +}; + +int tas2557_enable(struct tas2557_priv *pTAS2557, bool bEnable); +int tas2557_SA_DevChnSetup(struct tas2557_priv *pTAS2557, unsigned int mode); +int tas2557_get_die_temperature(struct tas2557_priv *pTAS2557, int *pTemperature); +int tas2557_set_sampling_rate(struct tas2557_priv *pTAS2557, unsigned int nSamplingRate); +int tas2557_set_bit_rate(struct tas2557_priv *pTAS2557, unsigned int nBitRate); +int tas2557_get_bit_rate(struct tas2557_priv *pTAS2557, unsigned char *pBitRate); +int tas2557_set_config(struct tas2557_priv *pTAS2557, int config); +void tas2557_fw_ready(const struct firmware *pFW, void *pContext); +bool tas2557_get_Cali_prm_r0(struct tas2557_priv *pTAS2557, int *prm_r0); +int tas2557_set_program(struct tas2557_priv *pTAS2557, unsigned int nProgram, int nConfig); +int tas2557_set_calibration(struct tas2557_priv *pTAS2557, int nCalibration); +int tas2557_load_default(struct tas2557_priv *pTAS2557); +int tas2557_parse_dt(struct device *dev, struct tas2557_priv *pTAS2557); +int tas2557_get_DAC_gain(struct tas2557_priv *pTAS2557, unsigned char *pnGain); +int tas2557_set_DAC_gain(struct tas2557_priv *pTAS2557, unsigned int nGain); +int tas2557_configIRQ(struct tas2557_priv *pTAS2557); +int tas2557_update_edge(struct tas2557_priv *pTAS2557); +#endif /* _TAS2557_CORE_H */ diff --git a/sound/soc/codecs/tas2557/tas2557-misc.c b/sound/soc/codecs/tas2557/tas2557-misc.c new file mode 100755 index 000000000000..da19d41d8e4d --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-misc.c @@ -0,0 +1,595 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-misc.c +** +** Description: +** misc driver for Texas Instruments TAS2557 High Performance 4W Smart Amplifier +** +** ============================================================================= +*/ + +#ifdef CONFIG_TAS2557_MISC + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tas2557.h" +#include "tas2557-core.h" +#include "tas2557-misc.h" +#include + +static int g_logEnable = 1; +static struct tas2557_priv *g_tas2557; + +static int tas2557_file_open(struct inode *inode, struct file *file) +{ + struct tas2557_priv *pTAS2557 = g_tas2557; + + if (!try_module_get(THIS_MODULE)) + return -ENODEV; + + file->private_data = (void *)pTAS2557; + if (g_logEnable) + dev_info(pTAS2557->dev, "%s\n", __func__); + return 0; +} + +static int tas2557_file_release(struct inode *inode, struct file *file) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)file->private_data; + + if (g_logEnable) + dev_info(pTAS2557->dev, "%s\n", __func__); + file->private_data = (void *)NULL; + module_put(THIS_MODULE); + + return 0; +} + +static ssize_t tas2557_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)file->private_data; + int ret = 0; + unsigned int nValue = 0; + unsigned char value = 0; + unsigned char *p_kBuf = NULL; + + mutex_lock(&pTAS2557->file_lock); + + switch (pTAS2557->mnDBGCmd) { + case TIAUDIO_CMD_REG_READ: { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_READ: current_reg = 0x%x, count=%d\n", + pTAS2557->mnCurrentReg, (int)count); + if (count == 1) { + ret = pTAS2557->read(pTAS2557, pTAS2557->mnCurrentReg, &nValue); + if (ret < 0) + break; + + value = (u8)nValue; + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_READ: nValue=0x%x, value=0x%x\n", nValue, value); + ret = copy_to_user(buf, &value, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + } else if (count > 1) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + ret = pTAS2557->bulk_read(pTAS2557, pTAS2557->mnCurrentReg, p_kBuf, count); + if (ret < 0) + break; + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } + } + break; + + case TIAUDIO_CMD_PROGRAM: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM: count = %d\n", (int)count); + + if (count == PROGRAM_BUF_SIZE) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TProgram *pProgram = + &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + p_kBuf[0] = pTAS2557->mpFirmware->mnPrograms; + p_kBuf[1] = pTAS2557->mnCurrentProgram; + p_kBuf[2] = pProgram->mnAppMode; + p_kBuf[3] = (pProgram->mnBoost&0xff00)>>8; + p_kBuf[4] = (pProgram->mnBoost&0x00ff); + memcpy(&p_kBuf[5], pProgram->mpName, FW_NAME_SIZE); + strlcpy(&p_kBuf[5+FW_NAME_SIZE], pProgram->mpDescription, strlen(pProgram->mpDescription) + 1); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } else + dev_err(pTAS2557->dev, "read buffer not sufficient\n"); + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + } + break; + + case TIAUDIO_CMD_CONFIGURATION: { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION: count = %d\n", (int)count); + if (count == CONFIGURATION_BUF_SIZE) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TConfiguration *pConfiguration = &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + + p_kBuf[0] = pTAS2557->mpFirmware->mnConfigurations; + p_kBuf[1] = pTAS2557->mnCurrentConfiguration; + memcpy(&p_kBuf[2], pConfiguration->mpName, FW_NAME_SIZE); + p_kBuf[2+FW_NAME_SIZE] = pConfiguration->mnProgram; + p_kBuf[3+FW_NAME_SIZE] = pConfiguration->mnPLL; + p_kBuf[4+FW_NAME_SIZE] = (pConfiguration->mnSamplingRate&0x000000ff); + p_kBuf[5+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x0000ff00)>>8); + p_kBuf[6+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0x00ff0000)>>16); + p_kBuf[7+FW_NAME_SIZE] = ((pConfiguration->mnSamplingRate&0xff000000)>>24); + strlcpy(&p_kBuf[8+FW_NAME_SIZE], pConfiguration->mpDescription, strlen(pConfiguration->mpDescription)+1); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } else + dev_err(pTAS2557->dev, "read buffer not sufficient\n"); + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + } + break; + + case TIAUDIO_CMD_FW_TIMESTAMP: { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_FW_TIMESTAMP: count = %d\n", (int)count); + + if (count == 4) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + p_kBuf[0] = (pTAS2557->mpFirmware->mnTimeStamp&0x000000ff); + p_kBuf[1] = ((pTAS2557->mpFirmware->mnTimeStamp&0x0000ff00)>>8); + p_kBuf[2] = ((pTAS2557->mpFirmware->mnTimeStamp&0x00ff0000)>>16); + p_kBuf[3] = ((pTAS2557->mpFirmware->mnTimeStamp&0xff000000)>>24); + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } + } + break; + + case TIAUDIO_CMD_CALIBRATION: { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CALIBRATION: count = %d\n", (int)count); + + if (count == 1) { + unsigned char curCal = pTAS2557->mnCurrentCalibration; + + ret = copy_to_user(buf, &curCal, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + } + } + break; + + case TIAUDIO_CMD_SAMPLERATE: { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_SAMPLERATE: count = %d\n", (int)count); + if (count == 4) { + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf != NULL) { + struct TConfiguration *pConfiguration = + &(pTAS2557->mpFirmware->mpConfigurations[pTAS2557->mnCurrentConfiguration]); + + p_kBuf[0] = (pConfiguration->mnSamplingRate&0x000000ff); + p_kBuf[1] = ((pConfiguration->mnSamplingRate&0x0000ff00)>>8); + p_kBuf[2] = ((pConfiguration->mnSamplingRate&0x00ff0000)>>16); + p_kBuf[3] = ((pConfiguration->mnSamplingRate&0xff000000)>>24); + + ret = copy_to_user(buf, p_kBuf, count); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + + kfree(p_kBuf); + } else + dev_err(pTAS2557->dev, "read no mem\n"); + } + } + break; + + case TIAUDIO_CMD_BITRATE: { + if (g_logEnable) + dev_info(pTAS2557->dev, + "TIAUDIO_CMD_BITRATE: count = %d\n", (int)count); + + if (count == 1) { + unsigned char bitRate = 0; + ret = tas2557_get_bit_rate(pTAS2557, &bitRate); + if (ret >= 0) { + ret = copy_to_user(buf, &bitRate, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + } + } + } + break; + + case TIAUDIO_CMD_DACVOLUME: { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_DACVOLUME: count = %d\n", (int)count); + + if (count == 1) { + unsigned char volume = 0; + + ret = tas2557_get_DAC_gain(pTAS2557, &volume); + if (ret >= 0) { + ret = copy_to_user(buf, &volume, 1); + if (ret != 0) { + /* Failed to copy all the data, exit */ + dev_err(pTAS2557->dev, "copy to user fail %d\n", ret); + } + } + } + } + break; + } + pTAS2557->mnDBGCmd = 0; + + mutex_unlock(&pTAS2557->file_lock); + return count; +} + +static ssize_t tas2557_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)file->private_data; + int ret = 0; + unsigned char *p_kBuf = NULL; + unsigned int reg = 0; + unsigned int len = 0; + + mutex_lock(&pTAS2557->file_lock); + + p_kBuf = kzalloc(count, GFP_KERNEL); + if (p_kBuf == NULL) { + dev_err(pTAS2557->dev, "write no mem\n"); + goto err; + } + + ret = copy_from_user(p_kBuf, buf, count); + if (ret != 0) { + dev_err(pTAS2557->dev, "copy_from_user failed.\n"); + goto err; + } + + pTAS2557->mnDBGCmd = p_kBuf[0]; + switch (pTAS2557->mnDBGCmd) { + case TIAUDIO_CMD_REG_WITE: + if (count > 5) { + reg = ((unsigned int)p_kBuf[1] << 24) + + ((unsigned int)p_kBuf[2] << 16) + + ((unsigned int)p_kBuf[3] << 8) + + (unsigned int)p_kBuf[4]; + len = count - 5; + if (len == 1) { + ret = pTAS2557->write(pTAS2557, reg, p_kBuf[5]); + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_WITE, Reg=0x%x, Val=0x%x\n", reg, p_kBuf[5]); + } else + ret = pTAS2557->bulk_write(pTAS2557, reg, &p_kBuf[5], len); + } else + dev_err(pTAS2557->dev, "%s, write len fail, count=%d.\n", __func__, (int)count); + pTAS2557->mnDBGCmd = 0; + break; + + case TIAUDIO_CMD_REG_READ: + if (count == 5) { + pTAS2557->mnCurrentReg = ((unsigned int)p_kBuf[1] << 24) + + ((unsigned int)p_kBuf[2] << 16) + + ((unsigned int)p_kBuf[3] << 8) + + (unsigned int)p_kBuf[4]; + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_REG_READ whole=0x%x\n", pTAS2557->mnCurrentReg); + } else + dev_err(pTAS2557->dev, "read len fail.\n"); + break; + + case TIAUDIO_CMD_DEBUG_ON: + if (count == 2) + g_logEnable = p_kBuf[1]; + + pTAS2557->mnDBGCmd = 0; + break; + + case TIAUDIO_CMD_PROGRAM: + { + if (count == 2) { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + int config = -1; + + if (p_kBuf[1] == pTAS2557->mnCurrentProgram) + config = pTAS2557->mnCurrentConfiguration; + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_PROGRAM, set to %d, cfg=%d\n", p_kBuf[1], config); + tas2557_set_program(pTAS2557, p_kBuf[1], config); + pTAS2557->mnDBGCmd = 0; + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + } + } + break; + + case TIAUDIO_CMD_CONFIGURATION: + { + if (count == 2) { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CONFIGURATION, set to %d\n", p_kBuf[1]); + tas2557_set_config(pTAS2557, p_kBuf[1]); + pTAS2557->mnDBGCmd = 0; + } else + dev_err(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + } + } + break; + + case TIAUDIO_CMD_FW_TIMESTAMP: + /*let go*/ + break; + + case TIAUDIO_CMD_CALIBRATION: + { + if (count == 2) { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_CALIBRATION, set to %d\n", p_kBuf[1]); + tas2557_set_calibration(pTAS2557, p_kBuf[1]); + pTAS2557->mnDBGCmd = 0; + } + } + } + break; + + case TIAUDIO_CMD_SAMPLERATE: + if (count == 5) { + unsigned int nSampleRate = ((unsigned int)p_kBuf[1] << 24) + + ((unsigned int)p_kBuf[2] << 16) + + ((unsigned int)p_kBuf[3] << 8) + + (unsigned int)p_kBuf[4]; + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_SAMPLERATE, set to %d\n", nSampleRate); + + tas2557_set_sampling_rate(pTAS2557, nSampleRate); + } + break; + + case TIAUDIO_CMD_BITRATE: + if (count == 2) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_BITRATE, set to %d\n", p_kBuf[1]); + + tas2557_set_bit_rate(pTAS2557, p_kBuf[1]); + } + break; + + case TIAUDIO_CMD_DACVOLUME: + if (count == 2) { + unsigned char volume; + + volume = (p_kBuf[1] & 0x0f); + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_DACVOLUME, set to %d\n", volume); + + ret = tas2557_set_DAC_gain(pTAS2557, volume); + if (ret < 0) + goto err; + } + break; + + case TIAUDIO_CMD_SPEAKER: + if (count == 2) { + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_SPEAKER, set to %d\n", p_kBuf[1]); + tas2557_enable(pTAS2557, (p_kBuf[1] > 0)); + } + break; + + case TIAUDIO_CMD_FW_RELOAD: + if (count == 1) { + const char *pFWName; + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) + pFWName = TAS2557_FW_NAME; + else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) + pFWName = TAS2557_PG1P0_FW_NAME; + else + break; + + ret = request_firmware_nowait(THIS_MODULE, 1, pFWName, + pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready); + + if (g_logEnable) + dev_info(pTAS2557->dev, "TIAUDIO_CMD_FW_RELOAD: ret = %d\n", ret); + } + break; + + default: + pTAS2557->mnDBGCmd = 0; + break; + } + +err: + if (p_kBuf != NULL) + kfree(p_kBuf); + + mutex_unlock(&pTAS2557->file_lock); + + return count; +} + +static long tas2557_file_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct tas2557_priv *pTAS2557 = file->private_data; + int ret = 0; + + mutex_lock(&pTAS2557->file_lock); + + switch (cmd) { + case SMARTPA_SPK_DAC_VOLUME: + { + } + break; + + case SMARTPA_SPK_POWER_ON: + { + tas2557_enable(pTAS2557, true); + } + break; + + case SMARTPA_SPK_POWER_OFF: + { + tas2557_enable(pTAS2557, false); + } + break; + + case SMARTPA_SPK_SWITCH_PROGRAM: + { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_program(pTAS2557, arg, -1); + } + break; + + case SMARTPA_SPK_SWITCH_CONFIGURATION: + { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_config(pTAS2557, arg); + } + break; + + case SMARTPA_SPK_SWITCH_CALIBRATION: + { + if ((pTAS2557->mpFirmware->mnConfigurations > 0) + && (pTAS2557->mpFirmware->mnPrograms > 0)) + tas2557_set_calibration(pTAS2557, arg); + } + break; + + case SMARTPA_SPK_SET_SAMPLERATE: + { + tas2557_set_sampling_rate(pTAS2557, arg); + } + break; + + case SMARTPA_SPK_SET_BITRATE: + { + tas2557_set_bit_rate(pTAS2557, arg); + } + break; + } + + mutex_unlock(&pTAS2557->file_lock); + return ret; +} + +static const struct file_operations fops = { + .owner = THIS_MODULE, + .read = tas2557_file_read, + .write = tas2557_file_write, + .unlocked_ioctl = tas2557_file_unlocked_ioctl, + .open = tas2557_file_open, + .release = tas2557_file_release, +}; + +#define MODULE_NAME "tas2557" +static struct miscdevice tas2557_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = MODULE_NAME, + .fops = &fops, +}; + +int tas2557_register_misc(struct tas2557_priv *pTAS2557) +{ + int ret = 0; + + g_tas2557 = pTAS2557; + + ret = misc_register(&tas2557_misc); + if (ret) + dev_err(pTAS2557->dev, "TAS2557 misc fail: %d\n", ret); + + dev_info(pTAS2557->dev, "%s, leave\n", __func__); + + return ret; +} + +int tas2557_deregister_misc(struct tas2557_priv *pTAS2557) +{ + misc_deregister(&tas2557_misc); + return 0; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 Misc Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); +#endif diff --git a/sound/soc/codecs/tas2557/tas2557-misc.h b/sound/soc/codecs/tas2557/tas2557-misc.h new file mode 100755 index 000000000000..38bfa64910cd --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-misc.h @@ -0,0 +1,57 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-misc.h +** +** Description: +** header file for tas2557-misc.c +** +** ============================================================================= +*/ + +#ifndef _TAS2557_MISC_H +#define _TAS2557_MISC_H + +#define FW_NAME_SIZE 64 +#define FW_DESCRIPTION_SIZE 256 +#define PROGRAM_BUF_SIZE (5 + FW_NAME_SIZE + FW_DESCRIPTION_SIZE) +#define CONFIGURATION_BUF_SIZE (8 + FW_NAME_SIZE + FW_DESCRIPTION_SIZE) + +#define TIAUDIO_CMD_REG_WITE 1 +#define TIAUDIO_CMD_REG_READ 2 +#define TIAUDIO_CMD_DEBUG_ON 3 +#define TIAUDIO_CMD_PROGRAM 4 +#define TIAUDIO_CMD_CONFIGURATION 5 +#define TIAUDIO_CMD_FW_TIMESTAMP 6 +#define TIAUDIO_CMD_CALIBRATION 7 +#define TIAUDIO_CMD_SAMPLERATE 8 +#define TIAUDIO_CMD_BITRATE 9 +#define TIAUDIO_CMD_DACVOLUME 10 +#define TIAUDIO_CMD_SPEAKER 11 +#define TIAUDIO_CMD_FW_RELOAD 12 + +#define TAS2557_MAGIC_NUMBER 0x3537 /* '2557' */ + +#define SMARTPA_SPK_DAC_VOLUME _IOWR(TAS2557_MAGIC_NUMBER, 1, unsigned long) +#define SMARTPA_SPK_POWER_ON _IOWR(TAS2557_MAGIC_NUMBER, 2, unsigned long) +#define SMARTPA_SPK_POWER_OFF _IOWR(TAS2557_MAGIC_NUMBER, 3, unsigned long) +#define SMARTPA_SPK_SWITCH_PROGRAM _IOWR(TAS2557_MAGIC_NUMBER, 4, unsigned long) +#define SMARTPA_SPK_SWITCH_CONFIGURATION _IOWR(TAS2557_MAGIC_NUMBER, 5, unsigned long) +#define SMARTPA_SPK_SWITCH_CALIBRATION _IOWR(TAS2557_MAGIC_NUMBER, 6, unsigned long) +#define SMARTPA_SPK_SET_SAMPLERATE _IOWR(TAS2557_MAGIC_NUMBER, 7, unsigned long) +#define SMARTPA_SPK_SET_BITRATE _IOWR(TAS2557_MAGIC_NUMBER, 8, unsigned long) + +int tas2557_register_misc(struct tas2557_priv *pTAS2557); +int tas2557_deregister_misc(struct tas2557_priv *pTAS2557); + +#endif /* _TAS2557_MISC_H */ diff --git a/sound/soc/codecs/tas2557/tas2557-regmap.c b/sound/soc/codecs/tas2557/tas2557-regmap.c new file mode 100755 index 000000000000..63ba6e59ac8a --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557-regmap.c @@ -0,0 +1,904 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557-regmap.c +** +** Description: +** I2C driver with regmap for Texas Instruments TAS2557 High Performance 4W Smart Amplifier +** +** ============================================================================= +*/ + +#ifdef CONFIG_TAS2557_REGMAP + +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tas2557.h" +#include "tas2557-core.h" + +#ifdef CONFIG_TAS2557_CODEC +#include "tas2557-codec.h" +#endif + +#ifdef CONFIG_TAS2557_MISC +#include "tas2557-misc.h" +#endif + +#define ENABLE_TILOAD +#ifdef ENABLE_TILOAD +#include "tiload.h" +#endif + +#define LOW_TEMPERATURE_GAIN 6 +#define LOW_TEMPERATURE_COUNTER 12 + +static int tas2557_change_book_page( + struct tas2557_priv *pTAS2557, + unsigned char nBook, + unsigned char nPage) +{ + int nResult = 0; + + if ((pTAS2557->mnCurrentBook == nBook) + && pTAS2557->mnCurrentPage == nPage) + goto end; + + if (pTAS2557->mnCurrentBook != nBook) { + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, 0); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentPage = 0; + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_REG, nBook); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentBook = nBook; + if (nPage != 0) { + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, nPage); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentPage = nPage; + } + } else if (pTAS2557->mnCurrentPage != nPage) { + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_BOOKCTL_PAGE, nPage); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + goto end; + } + pTAS2557->mnCurrentPage = nPage; + } + +end: + if (nResult < 0) + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + + return nResult; +} + +static int tas2557_dev_read( + struct tas2557_priv *pTAS2557, + unsigned int nRegister, + unsigned int *pValue) +{ + int nResult = 0; + unsigned int Value = 0; + + mutex_lock(&pTAS2557->dev_lock); + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only reads from TILoad pass. */ + nRegister &= ~0x80000000; + dev_dbg(pTAS2557->dev, "TiLoad R REG B[%d]P[%d]R[%d]\n", + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister)); + } + + nResult = tas2557_change_book_page(pTAS2557, + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), &Value); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + goto end; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + *pValue = Value; + } +end: + + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +static int tas2557_dev_write( + struct tas2557_priv *pTAS2557, + unsigned int nRegister, + unsigned int nValue) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + if ((nRegister == 0xAFFEAFFE) && (nValue == 0xBABEBABE)) { + pTAS2557->mbTILoadActive = true; + goto end; + } + + if ((nRegister == 0xBABEBABE) && (nValue == 0xAFFEAFFE)) { + pTAS2557->mbTILoadActive = false; + goto end; + } + + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end;/* let only writes from TILoad pass. */ + nRegister &= ~0x80000000; + + dev_dbg(pTAS2557->dev, "TiLoad W REG B[%d]P[%d]R[%d] =0x%x\n", + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), + nValue); + } + + nResult = tas2557_change_book_page(pTAS2557, + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nValue); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + + mutex_unlock(&pTAS2557->dev_lock); + + return nResult; +} + +static int tas2557_dev_bulk_read( + struct tas2557_priv *pTAS2557, + unsigned int nRegister, + u8 *pData, + unsigned int nLength) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + + nRegister &= ~0x80000000; + dev_dbg(pTAS2557->dev, "TiLoad BR REG B[%d]P[%d]R[%d], count=%d\n", + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), + nLength); + } + + nResult = tas2557_change_book_page(pTAS2557, + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_bulk_read(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +static int tas2557_dev_bulk_write( + struct tas2557_priv *pTAS2557, + unsigned int nRegister, + u8 *pData, + unsigned int nLength) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + + nRegister &= ~0x80000000; + + dev_dbg(pTAS2557->dev, "TiLoad BW REG B[%d]P[%d]R[%d], count=%d\n", + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), + nLength); + } + + nResult = tas2557_change_book_page( pTAS2557, + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_bulk_write(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), pData, nLength); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +static int tas2557_dev_update_bits( + struct tas2557_priv *pTAS2557, + unsigned int nRegister, + unsigned int nMask, + unsigned int nValue) +{ + int nResult = 0; + + mutex_lock(&pTAS2557->dev_lock); + + if (pTAS2557->mbTILoadActive) { + if (!(nRegister & 0x80000000)) + goto end; /* let only writes from TILoad pass. */ + + nRegister &= ~0x80000000; + dev_dbg(pTAS2557->dev, "TiLoad SB REG B[%d]P[%d]R[%d], mask=0x%x, value=0x%x\n", + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister), + TAS2557_PAGE_REG(nRegister), + nMask, nValue); + } + + nResult = tas2557_change_book_page( pTAS2557, + TAS2557_BOOK_ID(nRegister), + TAS2557_PAGE_ID(nRegister)); + if (nResult >= 0) { + nResult = regmap_update_bits(pTAS2557->mpRegmap, TAS2557_PAGE_REG(nRegister), nMask, nValue); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s, %d, I2C error %d\n", + __func__, __LINE__, nResult); + pTAS2557->mnErrCode |= ERROR_DEVA_I2C_COMM; + } else + pTAS2557->mnErrCode &= ~ERROR_DEVA_I2C_COMM; + } + +end: + mutex_unlock(&pTAS2557->dev_lock); + return nResult; +} + +void tas2557_clearIRQ(struct tas2557_priv *pTAS2557) +{ + unsigned int nValue; + int nResult = 0; + + nResult = pTAS2557->read(pTAS2557, TAS2557_FLAGS_1, &nValue); + if (nResult >= 0) + pTAS2557->read(pTAS2557, TAS2557_FLAGS_2, &nValue); + +} + + +void tas2557_enableIRQ(struct tas2557_priv *pTAS2557, bool enable, bool startup_chk) +{ + if (enable) { + if (!pTAS2557->mbIRQEnable) { + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + enable_irq(pTAS2557->mnIRQ); + if (startup_chk) { + /* check after 10 ms */ + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(10)); + } + pTAS2557->mbIRQEnable = true; + } + } + } else { + if (gpio_is_valid(pTAS2557->mnGpioINT)) + disable_irq_nosync(pTAS2557->mnIRQ); + pTAS2557->mbIRQEnable = false; + } +} + +static void tas2557_hw_reset(struct tas2557_priv *pTAS2557) +{ + if (gpio_is_valid(pTAS2557->mnResetGPIO)) { + gpio_direction_output(pTAS2557->mnResetGPIO, 0); + msleep(5); + gpio_direction_output(pTAS2557->mnResetGPIO, 1); + msleep(2); + } + + pTAS2557->mnCurrentBook = -1; + pTAS2557->mnCurrentPage = -1; + if (pTAS2557->mnErrCode) + dev_info(pTAS2557->dev, "before reset, ErrCode=0x%x\n", pTAS2557->mnErrCode); + pTAS2557->mnErrCode = 0; +} + +static void irq_work_routine(struct work_struct *work) +{ + int nResult = 0; + unsigned int nDevInt1Status = 0, nDevInt2Status = 0; + unsigned int nDevPowerUpFlag = 0; + int nCounter = 2; + struct tas2557_priv *pTAS2557 = + container_of(work, struct tas2557_priv, irq_work.work); + +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + + if(pTAS2557->mnErrCode & ERROR_FAILSAFE) + goto program; + + if (pTAS2557->mbRuntimeSuspend) { + dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__); + goto end; + } + + if (!pTAS2557->mbPowerUp) { + dev_info(pTAS2557->dev, "%s, device not powered\n", __func__); + goto end; + } + + if ((!pTAS2557->mpFirmware->mnConfigurations) + || (!pTAS2557->mpFirmware->mnPrograms)) { + dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + nResult = tas2557_dev_write(pTAS2557, TAS2557_GPIO4_PIN_REG, 0x00); + if (nResult < 0) + goto program; + nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_1, &nDevInt1Status); + if (nResult >= 0) + nResult = tas2557_dev_read(pTAS2557, TAS2557_FLAGS_2, &nDevInt2Status); + if (nResult < 0) + goto program; + + if (((nDevInt1Status & 0xfc) != 0) || ((nDevInt2Status & 0x0c) != 0)) { + /* in case of INT_OC, INT_UV, INT_OT, INT_BO, INT_CL, INT_CLK1, INT_CLK2 */ + dev_err(pTAS2557->dev, "critical error: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status); + if (nDevInt1Status & 0x80) { + pTAS2557->mnErrCode |= ERROR_OVER_CURRENT; + dev_err(pTAS2557->dev, "DEVA SPK over current!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_OVER_CURRENT; + + if (nDevInt1Status & 0x40) { + pTAS2557->mnErrCode |= ERROR_UNDER_VOLTAGE; + dev_err(pTAS2557->dev, "DEVA SPK under voltage!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_UNDER_VOLTAGE; + + if (nDevInt1Status & 0x20) { + pTAS2557->mnErrCode |= ERROR_CLK_HALT; + dev_err(pTAS2557->dev, "DEVA clk halted!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_HALT; + + if (nDevInt1Status & 0x10) { + pTAS2557->mnErrCode |= ERROR_DIE_OVERTEMP; + dev_err(pTAS2557->dev, "DEVA die over temperature!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_DIE_OVERTEMP; + + if (nDevInt1Status & 0x08) { + pTAS2557->mnErrCode |= ERROR_BROWNOUT; + dev_err(pTAS2557->dev, "DEVA brownout!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_BROWNOUT; + + if (nDevInt1Status & 0x04) { + pTAS2557->mnErrCode |= ERROR_CLK_LOST; + dev_err(pTAS2557->dev, "DEVA clock lost!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_LOST; + + if (nDevInt2Status & 0x08) { + pTAS2557->mnErrCode |= ERROR_CLK_DET1; + dev_err(pTAS2557->dev, "DEVA clk detection 1!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_DET1; + + if (nDevInt2Status & 0x04) { + pTAS2557->mnErrCode |= ERROR_CLK_DET2; + dev_err(pTAS2557->dev, "DEVA clk detection 2!\n"); + } else + pTAS2557->mnErrCode &= ~ERROR_CLK_DET2; + + goto program; + } else { + dev_dbg(pTAS2557->dev, "IRQ Status: 0x%x, 0x%x\n", nDevInt1Status, nDevInt2Status); + nCounter = 2; + while (nCounter > 0) { + nResult = tas2557_dev_read(pTAS2557, TAS2557_POWER_UP_FLAG_REG, &nDevPowerUpFlag); + if (nResult < 0) + goto program; + if ((nDevPowerUpFlag & 0xc0) == 0xc0) + break; + nCounter--; + if (nCounter > 0) { + /* in case check pow status just after power on TAS2557 */ + dev_dbg(pTAS2557->dev, "PowSts: 0x%x, check again after 10ms\n", + nDevPowerUpFlag); + msleep(10); + } + } + if ((nDevPowerUpFlag & 0xc0) != 0xc0) { + dev_err(pTAS2557->dev, "%s, Critical ERROR B[%d]_P[%d]_R[%d]= 0x%x\n", + __func__, + TAS2557_BOOK_ID(TAS2557_POWER_UP_FLAG_REG), + TAS2557_PAGE_ID(TAS2557_POWER_UP_FLAG_REG), + TAS2557_PAGE_REG(TAS2557_POWER_UP_FLAG_REG), + nDevPowerUpFlag); + pTAS2557->mnErrCode |= ERROR_CLASSD_PWR; + goto program; + } + pTAS2557->mnErrCode &= ~ERROR_CLASSD_PWR; + + dev_dbg(pTAS2557->dev, "%s: INT1=0x%x, INT2=0x%x; PowerUpFlag=0x%x\n", + __func__, nDevInt1Status, nDevInt2Status, nDevPowerUpFlag); + goto end; + } + +program: + /* hardware reset and reload */ + nResult = -1; + tas2557_set_program(pTAS2557, pTAS2557->mnCurrentProgram, pTAS2557->mnCurrentConfiguration); + +end: + if (nResult >= 0) { + tas2557_dev_write(pTAS2557, TAS2557_GPIO4_PIN_REG, 0x07); + tas2557_enableIRQ(pTAS2557, true, false); + } +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif +} + +static irqreturn_t tas2557_irq_handler(int irq, void *dev_id) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)dev_id; + + tas2557_enableIRQ(pTAS2557, false, false); + /* get IRQ status after 100 ms */ + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(100)); + return IRQ_HANDLED; +} + +static enum hrtimer_restart temperature_timer_func(struct hrtimer *timer) +{ + struct tas2557_priv *pTAS2557 = container_of(timer, struct tas2557_priv, mtimer); + + if (pTAS2557->mbPowerUp) { + schedule_work(&pTAS2557->mtimerwork); + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + tas2557_enableIRQ(pTAS2557, false, false); + schedule_delayed_work(&pTAS2557->irq_work, msecs_to_jiffies(1)); + } + } + return HRTIMER_NORESTART; +} + +static void timer_work_routine(struct work_struct *work) +{ + struct tas2557_priv *pTAS2557 = container_of(work, struct tas2557_priv, mtimerwork); + int nResult, nActTemp; + int nTemp = 0; + struct TProgram *pProgram; + static int nAvg; + +#ifdef CONFIG_TAS2557_CODEC + mutex_lock(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_lock(&pTAS2557->file_lock); +#endif + + if (pTAS2557->mbRuntimeSuspend) { + dev_info(pTAS2557->dev, "%s, Runtime Suspended\n", __func__); + goto end; + } + + if (!pTAS2557->mpFirmware->mnConfigurations) { + dev_info(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (!pTAS2557->mbPowerUp + || (pProgram->mnAppMode != TAS2557_APP_TUNINGMODE)) { + dev_info(pTAS2557->dev, "%s, pass, Pow=%d, program=%s\n", + __func__, pTAS2557->mbPowerUp, pProgram->mpName); + goto end; + } + + nResult = tas2557_get_die_temperature(pTAS2557, &nTemp); + if (nResult >= 0) { + nActTemp = (int)(nTemp >> 23); + dev_dbg(pTAS2557->dev, "Die=0x%x, degree=%d\n", nTemp, nActTemp); + if (!pTAS2557->mnDieTvReadCounter) + nAvg = 0; + pTAS2557->mnDieTvReadCounter++; + nAvg += nActTemp; + if (!(pTAS2557->mnDieTvReadCounter % LOW_TEMPERATURE_COUNTER)) { + nAvg /= LOW_TEMPERATURE_COUNTER; + dev_dbg(pTAS2557->dev, "check : avg=%d\n", nAvg); + if (nAvg < -6) { + /* if Die temperature is below -6 degree C */ + if (pTAS2557->mnDevCurrentGain != LOW_TEMPERATURE_GAIN) { + nResult = tas2557_set_DAC_gain(pTAS2557, LOW_TEMPERATURE_GAIN); + if (nResult < 0) + goto end; + pTAS2557->mnDevCurrentGain = LOW_TEMPERATURE_GAIN; + dev_dbg(pTAS2557->dev, "LOW Temp: set gain to %d\n", LOW_TEMPERATURE_GAIN); + } + } else if (nAvg > 5) { + /* if Die temperature is above 5 degree C */ + if (pTAS2557->mnDevCurrentGain != pTAS2557->mnDevGain) { + nResult = tas2557_set_DAC_gain(pTAS2557, pTAS2557->mnDevGain); + if (nResult < 0) + goto end; + pTAS2557->mnDevCurrentGain = pTAS2557->mnDevGain; + dev_dbg(pTAS2557->dev, "LOW Temp: set gain to original\n"); + } + } + nAvg = 0; + } + + if (pTAS2557->mbPowerUp) + hrtimer_start(&pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + +end: + +#ifdef CONFIG_TAS2557_MISC + mutex_unlock(&pTAS2557->file_lock); +#endif + +#ifdef CONFIG_TAS2557_CODEC + mutex_unlock(&pTAS2557->codec_lock); +#endif +} + +static int tas2557_runtime_suspend(struct tas2557_priv *pTAS2557) +{ + dev_dbg(pTAS2557->dev, "%s\n", __func__); + + pTAS2557->mbRuntimeSuspend = true; + + if (hrtimer_active(&pTAS2557->mtimer)) { + dev_dbg(pTAS2557->dev, "cancel die temp timer\n"); + hrtimer_cancel(&pTAS2557->mtimer); + } + if (work_pending(&pTAS2557->mtimerwork)) { + dev_dbg(pTAS2557->dev, "cancel timer work\n"); + cancel_work_sync(&pTAS2557->mtimerwork); + } + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + if (delayed_work_pending(&pTAS2557->irq_work)) { + dev_dbg(pTAS2557->dev, "cancel IRQ work\n"); + cancel_delayed_work_sync(&pTAS2557->irq_work); + } + } + + return 0; +} + +static int tas2557_runtime_resume(struct tas2557_priv *pTAS2557) +{ + struct TProgram *pProgram; + + dev_dbg(pTAS2557->dev, "%s\n", __func__); + if (!pTAS2557->mpFirmware->mpPrograms) { + dev_dbg(pTAS2557->dev, "%s, firmware not loaded\n", __func__); + goto end; + } + + if (pTAS2557->mnCurrentProgram >= pTAS2557->mpFirmware->mnPrograms) { + dev_err(pTAS2557->dev, "%s, firmware corrupted\n", __func__); + goto end; + } + + pProgram = &(pTAS2557->mpFirmware->mpPrograms[pTAS2557->mnCurrentProgram]); + if (pTAS2557->mbPowerUp && (pProgram->mnAppMode == TAS2557_APP_TUNINGMODE)) { + if (!hrtimer_active(&pTAS2557->mtimer)) { + dev_dbg(pTAS2557->dev, "%s, start Die Temp check timer\n", __func__); + pTAS2557->mnDieTvReadCounter = 0; + hrtimer_start(&pTAS2557->mtimer, + ns_to_ktime((u64)LOW_TEMPERATURE_CHECK_PERIOD * NSEC_PER_MSEC), HRTIMER_MODE_REL); + } + } + + pTAS2557->mbRuntimeSuspend = false; +end: + + return 0; +} + +static bool tas2557_volatile(struct device *pDev, unsigned int nRegister) +{ + return true; +} + +static bool tas2557_writeable(struct device *pDev, unsigned int nRegister) +{ + return true; +} + +static const struct regmap_config tas2557_i2c_regmap = { + .reg_bits = 8, + .val_bits = 8, + .writeable_reg = tas2557_writeable, + .volatile_reg = tas2557_volatile, + .cache_type = REGCACHE_NONE, + .max_register = 128, +}; + +/* tas2557_i2c_probe : +* platform dependent +* should implement hardware reset functionality +*/ +static int tas2557_i2c_probe(struct i2c_client *pClient, + const struct i2c_device_id *pID) +{ + struct tas2557_priv *pTAS2557; + int nResult = 0; + unsigned int nValue = 0; + const char *pFWName; + + dev_info(&pClient->dev, "%s enter\n", __func__); + + pTAS2557 = devm_kzalloc(&pClient->dev, sizeof(struct tas2557_priv), GFP_KERNEL); + if (!pTAS2557) { + nResult = -ENOMEM; + goto err; + } + + pTAS2557->dev = &pClient->dev; + i2c_set_clientdata(pClient, pTAS2557); + dev_set_drvdata(&pClient->dev, pTAS2557); + + pTAS2557->mpRegmap = devm_regmap_init_i2c(pClient, &tas2557_i2c_regmap); + if (IS_ERR(pTAS2557->mpRegmap)) { + nResult = PTR_ERR(pTAS2557->mpRegmap); + dev_err(&pClient->dev, "Failed to allocate register map: %d\n", + nResult); + goto err; + } + + if (pClient->dev.of_node) + tas2557_parse_dt(&pClient->dev, pTAS2557); + + if (gpio_is_valid(pTAS2557->mnResetGPIO)) { + nResult = gpio_request(pTAS2557->mnResetGPIO, "TAS2557-RESET"); + if (nResult < 0) { + dev_err(pTAS2557->dev, "%s: GPIO %d request error\n", + __func__, pTAS2557->mnResetGPIO); + goto err; + } + tas2557_hw_reset(pTAS2557); + } + + pTAS2557->read = tas2557_dev_read; + pTAS2557->write = tas2557_dev_write; + pTAS2557->bulk_read = tas2557_dev_bulk_read; + pTAS2557->bulk_write = tas2557_dev_bulk_write; + pTAS2557->update_bits = tas2557_dev_update_bits; + pTAS2557->enableIRQ = tas2557_enableIRQ; + pTAS2557->clearIRQ = tas2557_clearIRQ; + pTAS2557->set_config = tas2557_set_config; + pTAS2557->set_calibration = tas2557_set_calibration; + pTAS2557->hw_reset = tas2557_hw_reset; + pTAS2557->runtime_suspend = tas2557_runtime_suspend; + pTAS2557->runtime_resume = tas2557_runtime_resume; + pTAS2557->mnRestart = 0; + pTAS2557->mnEdge = 4; + + mutex_init(&pTAS2557->dev_lock); + + /* Reset the chip */ + nResult = tas2557_dev_write(pTAS2557, TAS2557_SW_RESET_REG, 0x01); + if (nResult < 0) { + dev_err(&pClient->dev, "I2c fail, %d\n", nResult); + goto err; + } + + msleep(1); + tas2557_dev_read(pTAS2557, TAS2557_REV_PGID_REG, &nValue); + pTAS2557->mnPGID = nValue; + if (pTAS2557->mnPGID == TAS2557_PG_VERSION_2P1) { + dev_info(pTAS2557->dev, "PG2.1 Silicon found\n"); + pFWName = TAS2557_FW_NAME; + } else if (pTAS2557->mnPGID == TAS2557_PG_VERSION_1P0) { + dev_info(pTAS2557->dev, "PG1.0 Silicon found\n"); + pFWName = TAS2557_PG1P0_FW_NAME; + } else { + nResult = -ENOTSUPP; + dev_info(pTAS2557->dev, "unsupport Silicon 0x%x\n", pTAS2557->mnPGID); + goto err; + } + + if (gpio_is_valid(pTAS2557->mnGpioINT)) { + nResult = gpio_request(pTAS2557->mnGpioINT, "TAS2557-IRQ"); + if (nResult < 0) { + dev_err(pTAS2557->dev, + "%s: GPIO %d request INT error\n", + __func__, pTAS2557->mnGpioINT); + goto err; + } + + gpio_direction_input(pTAS2557->mnGpioINT); + pTAS2557->mnIRQ = gpio_to_irq(pTAS2557->mnGpioINT); + dev_dbg(pTAS2557->dev, "irq = %d\n", pTAS2557->mnIRQ); + INIT_DELAYED_WORK(&pTAS2557->irq_work, irq_work_routine); + nResult = request_threaded_irq(pTAS2557->mnIRQ, tas2557_irq_handler, + NULL, IRQF_TRIGGER_HIGH | IRQF_ONESHOT, + pClient->name, pTAS2557); + if (nResult < 0) { + dev_err(pTAS2557->dev, + "request_irq failed, %d\n", nResult); + goto err; + } + disable_irq_nosync(pTAS2557->mnIRQ); + } + + pTAS2557->mpFirmware = devm_kzalloc(&pClient->dev, sizeof(struct TFirmware), GFP_KERNEL); + if (!pTAS2557->mpFirmware) { + nResult = -ENOMEM; + goto err; + } + + pTAS2557->mpCalFirmware = devm_kzalloc(&pClient->dev, sizeof(struct TFirmware), GFP_KERNEL); + if (!pTAS2557->mpCalFirmware) { + nResult = -ENOMEM; + goto err; + } + +#ifdef CONFIG_TAS2557_CODEC + mutex_init(&pTAS2557->codec_lock); + tas2557_register_codec(pTAS2557); +#endif + +#ifdef CONFIG_TAS2557_MISC + mutex_init(&pTAS2557->file_lock); + tas2557_register_misc(pTAS2557); +#endif + +#ifdef ENABLE_TILOAD + tiload_driver_init(pTAS2557); +#endif + + hrtimer_init(&pTAS2557->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + pTAS2557->mtimer.function = temperature_timer_func; + INIT_WORK(&pTAS2557->mtimerwork, timer_work_routine); + + nResult = request_firmware_nowait(THIS_MODULE, 1, pFWName, + pTAS2557->dev, GFP_KERNEL, pTAS2557, tas2557_fw_ready); + +err: + + return nResult; +} + +static int tas2557_i2c_remove(struct i2c_client *pClient) +{ + struct tas2557_priv *pTAS2557 = i2c_get_clientdata(pClient); + + dev_info(pTAS2557->dev, "%s\n", __func__); + +#ifdef CONFIG_TAS2557_CODEC + tas2557_deregister_codec(pTAS2557); + mutex_destroy(&pTAS2557->codec_lock); +#endif + +#ifdef CONFIG_TAS2557_MISC + tas2557_deregister_misc(pTAS2557); + mutex_destroy(&pTAS2557->file_lock); +#endif + + mutex_destroy(&pTAS2557->dev_lock); + return 0; +} + +static const struct i2c_device_id tas2557_i2c_id[] = { + {"tas2557", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, tas2557_i2c_id); + +#if defined(CONFIG_OF) +static const struct of_device_id tas2557_of_match[] = { + {.compatible = "ti,tas2557"}, + {}, +}; + +MODULE_DEVICE_TABLE(of, tas2557_of_match); +#endif + +static struct i2c_driver tas2557_i2c_driver = { + .driver = { + .name = "tas2557", + .owner = THIS_MODULE, +#if defined(CONFIG_OF) + .of_match_table = of_match_ptr(tas2557_of_match), +#endif + }, + .probe = tas2557_i2c_probe, + .remove = tas2557_i2c_remove, + .id_table = tas2557_i2c_id, +}; + +module_i2c_driver(tas2557_i2c_driver); + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("TAS2557 I2C Smart Amplifier driver"); +MODULE_LICENSE("GPL v2"); + +#endif diff --git a/sound/soc/codecs/tas2557/tas2557.h b/sound/soc/codecs/tas2557/tas2557.h new file mode 100755 index 000000000000..a45c4ec1420c --- /dev/null +++ b/sound/soc/codecs/tas2557/tas2557.h @@ -0,0 +1,489 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tas2557.h +** +** Description: +** definitions and data structures for TAS2557 Android Linux driver +** +** ============================================================================= +*/ + +#ifndef _TAS2557_H +#define _TAS2557_H + +#include +#include +#include + +/* Page Control Register */ +#define TAS2557_PAGECTL_REG 0 + +/* Book Control Register (available in page0 of each book) */ +#define TAS2557_BOOKCTL_PAGE 0 +#define TAS2557_BOOKCTL_REG 127 + +/* 0000 0000 0BBB BBBB BPPP PPPP PRRR RRRR */ + +#define TAS2557_REG(book, page, reg) ((((unsigned int)book * 256 * 128) + \ + ((unsigned int)page * 128)) + reg) + +#define TAS2557_BOOK_ID(reg) ((unsigned char)(reg / (256 * 128))) +#define TAS2557_PAGE_ID(reg) ((unsigned char)((reg % (256 * 128)) / 128)) +#define TAS2557_BOOK_REG(reg) ((unsigned char)(reg % (256 * 128))) +#define TAS2557_PAGE_REG(reg) ((unsigned char)((reg % (256 * 128)) % 128)) + +/* Book0, Page0 registers */ +#define TAS2557_SW_RESET_REG TAS2557_REG(0, 0, 1) + +#define TAS2557_REV_PGID_REG TAS2557_REG(0, 0, 3) +#define TAS2557_PG_VERSION_1P0 0x80 +#define TAS2557_PG_VERSION_2P0 0x90 +#define TAS2557_PG_VERSION_2P1 0xa0 + +#define TAS2557_POWER_CTRL1_REG TAS2557_REG(0, 0, 4) +#define TAS2557_POWER_CTRL2_REG TAS2557_REG(0, 0, 5) + +#define TAS2557_SPK_CTRL_REG TAS2557_REG(0, 0, 6) +/* B0P0R6 - TAS2557_SPK_CTRL_REG */ +#define TAS2557_DAC_GAIN_MASK (0xf << 3) +#define TAS2557_DAC_GAIN_SHIFT 0x03 + +#define TAS2557_MUTE_REG TAS2557_REG(0, 0, 7) +#define TAS2557_SNS_CTRL_REG TAS2557_REG(0, 0, 8) +#define TAS2557_ADC_INPUT_SEL_REG TAS2557_REG(0, 0, 9) +#define TAS2557_DBOOST_CTL_REG TAS2557_REG(0, 0, 10) +#define TAS2557_NONAME11_REG TAS2557_REG(0, 0, 11) +#define TAS2557_NONAME12_REG TAS2557_REG(0, 0, 12) +#define TAS2557_NONAME13_REG TAS2557_REG(0, 0, 13) +#define TAS2557_NONAME14_REG TAS2557_REG(0, 0, 14) +#define TAS2557_NONAME15_REG TAS2557_REG(0, 0, 15) +#define TAS2557_NONAME16_REG TAS2557_REG(0, 0, 16) +#define TAS2557_NONAME17_REG TAS2557_REG(0, 0, 17) +#define TAS2557_NONAME18_REG TAS2557_REG(0, 0, 18) +#define TAS2557_SAR_SAMPLING_TIME_REG TAS2557_REG(0, 0, 19) +#define TAS2557_SAR_ADC1_REG TAS2557_REG(0, 0, 20) +#define TAS2557_SAR_ADC2_REG TAS2557_REG(0, 0, 21) /* B0_P0_R0x15*/ +#define TAS2557_CRC_CHECKSUM_REG TAS2557_REG(0, 0, 32) +#define TAS2557_CRC_RESET_REG TAS2557_REG(0, 0, 33) +#define TAS2557_DSP_MODE_SELECT_REG TAS2557_REG(0, 0, 34) +#define TAS2557_SAFE_GUARD_REG TAS2557_REG(0, 0, 37) +#define TAS2557_ASI_CTL1_REG TAS2557_REG(0, 0, 42) +#define TAS2557_CLK_ERR_CTRL TAS2557_REG(0, 0, 44) /* B0_P0_R0x2c*/ +#define TAS2557_CLK_ERR_CTRL2 TAS2557_REG(0, 0, 45) /* B0_P0_R0x2d*/ +#define TAS2557_CLK_ERR_CTRL3 TAS2557_REG(0, 0, 46) /* B0_P0_R0x2e*/ +#define TAS2557_DBOOST_CFG_REG TAS2557_REG(0, 0, 52) +#define TAS2557_POWER_UP_FLAG_REG TAS2557_REG(0, 0, 100) +#define TAS2557_FLAGS_1 TAS2557_REG(0, 0, 104) /* B0_P0_R0x68*/ +#define TAS2557_FLAGS_2 TAS2557_REG(0, 0, 108) /* B0_P0_R0x6c*/ + +/* Book0, Page1 registers */ +#define TAS2557_ASI1_DAC_FORMAT_REG TAS2557_REG(0, 1, 1) +#define TAS2557_ASI1_ADC_FORMAT_REG TAS2557_REG(0, 1, 2) +#define TAS2557_ASI1_OFFSET1_REG TAS2557_REG(0, 1, 3) +#define TAS2557_ASI1_ADC_PATH_REG TAS2557_REG(0, 1, 7) +#define TAS2557_ASI1_DAC_BCLK_REG TAS2557_REG(0, 1, 8) +#define TAS2557_ASI1_DAC_WCLK_REG TAS2557_REG(0, 1, 9) +#define TAS2557_ASI1_ADC_BCLK_REG TAS2557_REG(0, 1, 10) +#define TAS2557_ASI1_ADC_WCLK_REG TAS2557_REG(0, 1, 11) +#define TAS2557_ASI1_DIN_DOUT_MUX_REG TAS2557_REG(0, 1, 12) +#define TAS2557_ASI1_BDIV_CLK_SEL_REG TAS2557_REG(0, 1, 13) +#define TAS2557_ASI1_BDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 14) +#define TAS2557_ASI1_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 15) +#define TAS2557_ASI1_DAC_CLKOUT_REG TAS2557_REG(0, 1, 16) +#define TAS2557_ASI1_ADC_CLKOUT_REG TAS2557_REG(0, 1, 17) +#define TAS2557_ASI2_DAC_FORMAT_REG TAS2557_REG(0, 1, 21) +#define TAS2557_ASI2_ADC_FORMAT_REG TAS2557_REG(0, 1, 22) +#define TAS2557_ASI2_OFFSET1_REG TAS2557_REG(0, 1, 23) +#define TAS2557_ASI2_ADC_PATH_REG TAS2557_REG(0, 1, 27) +#define TAS2557_ASI2_DAC_BCLK_REG TAS2557_REG(0, 1, 28) +#define TAS2557_ASI2_DAC_WCLK_REG TAS2557_REG(0, 1, 29) +#define TAS2557_ASI2_ADC_BCLK_REG TAS2557_REG(0, 1, 30) +#define TAS2557_ASI2_ADC_WCLK_REG TAS2557_REG(0, 1, 31) +#define TAS2557_ASI2_DIN_DOUT_MUX_REG TAS2557_REG(0, 1, 32) +#define TAS2557_ASI2_BDIV_CLK_SEL_REG TAS2557_REG(0, 1, 33) +#define TAS2557_ASI2_BDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 34) +#define TAS2557_ASI2_WDIV_CLK_RATIO_REG TAS2557_REG(0, 1, 35) +#define TAS2557_ASI2_DAC_CLKOUT_REG TAS2557_REG(0, 1, 36) +#define TAS2557_ASI2_ADC_CLKOUT_REG TAS2557_REG(0, 1, 37) +#define TAS2557_GPIO1_PIN_REG TAS2557_REG(0, 1, 61) /*B0_P1_R0x3d */ +#define TAS2557_GPIO2_PIN_REG TAS2557_REG(0, 1, 62) /*B0_P1_R0x3e */ +#define TAS2557_GPIO3_PIN_REG TAS2557_REG(0, 1, 63) /*B0_P1_R0x3f */ +#define TAS2557_GPIO4_PIN_REG TAS2557_REG(0, 1, 64) /*B0_P1_R0x40 */ +#define TAS2557_GPIO5_PIN_REG TAS2557_REG(0, 1, 65) +#define TAS2557_GPIO6_PIN_REG TAS2557_REG(0, 1, 66) +#define TAS2557_GPIO7_PIN_REG TAS2557_REG(0, 1, 67) +#define TAS2557_GPIO8_PIN_REG TAS2557_REG(0, 1, 68) +#define TAS2557_GPIO9_PIN_REG TAS2557_REG(0, 1, 69) +#define TAS2557_GPIO10_PIN_REG TAS2557_REG(0, 1, 70) +#define TAS2557_GPI_PIN_REG TAS2557_REG(0, 1, 77) /*B0_P1_R0x4d */ +#define TAS2557_GPIO_HIZ_CTRL1_REG TAS2557_REG(0, 1, 79) +#define TAS2557_GPIO_HIZ_CTRL2_REG TAS2557_REG(0, 1, 80) /*B0_P1_R0x50 */ +#define TAS2557_GPIO_HIZ_CTRL3_REG TAS2557_REG(0, 1, 81) +#define TAS2557_GPIO_HIZ_CTRL4_REG TAS2557_REG(0, 1, 82) +#define TAS2557_GPIO_HIZ_CTRL5_REG TAS2557_REG(0, 1, 83) +#define TAS2557_BIT_BANG_CTRL_REG TAS2557_REG(0, 1, 87) +#define TAS2557_BIT_BANG_OUT1_REG TAS2557_REG(0, 1, 88) +#define TAS2557_BIT_BANG_OUT2_REG TAS2557_REG(0, 1, 89) +#define TAS2557_BIT_BANG_IN1_REG TAS2557_REG(0, 1, 90) +#define TAS2557_BIT_BANG_IN2_REG TAS2557_REG(0, 1, 91) +#define TAS2557_BIT_BANG_IN3_REG TAS2557_REG(0, 1, 92) +#define TAS2557_PDM_IN_CLK_REG TAS2557_REG(0, 1, 94) +#define TAS2557_PDM_IN_PIN_REG TAS2557_REG(0, 1, 95) +#define TAS2557_ASIM_IFACE1_REG TAS2557_REG(0, 1, 98) +#define TAS2557_ASIM_FORMAT_REG TAS2557_REG(0, 1, 99) +#define TAS2557_ASIM_IFACE3_REG TAS2557_REG(0, 1, 100) +#define TAS2557_ASIM_IFACE4_REG TAS2557_REG(0, 1, 101) +#define TAS2557_ASIM_IFACE5_REG TAS2557_REG(0, 1, 102) +#define TAS2557_ASIM_IFACE6_REG TAS2557_REG(0, 1, 103) +#define TAS2557_ASIM_IFACE7_REG TAS2557_REG(0, 1, 104) +#define TAS2557_ASIM_IFACE8_REG TAS2557_REG(0, 1, 105) +#define TAS2557_CLK_HALT_REG TAS2557_REG(0, 1, 106) /* B0_P1_R0x6a */ +#define TAS2557_INT_GEN1_REG TAS2557_REG(0, 1, 108) /* B0_P1_R0x6c */ +#define TAS2557_INT_GEN2_REG TAS2557_REG(0, 1, 109) /* B0_P1_R0x6d */ +#define TAS2557_INT_GEN3_REG TAS2557_REG(0, 1, 110) /* B0_P1_R0x6e */ +#define TAS2557_INT_GEN4_REG TAS2557_REG(0, 1, 111) /* B0_P1_R0x6f */ +#define TAS2557_INT_MODE_REG TAS2557_REG(0, 1, 114) /* B0_P1_R0x72 */ +#define TAS2557_MAIN_CLKIN_REG TAS2557_REG(0, 1, 115) +#define TAS2557_PLL_CLKIN_REG TAS2557_REG(0, 1, 116) +#define TAS2557_CLKOUT_MUX_REG TAS2557_REG(0, 1, 117) +#define TAS2557_CLKOUT_CDIV_REG TAS2557_REG(0, 1, 118) +#define TAS2557_HACK_GP01_REG TAS2557_REG(0, 1, 122) + +#define TAS2557_HACK01_REG TAS2557_REG(0, 2, 10) + +#define TAS2557_ISENSE_THRESHOLD TAS2557_REG(0, 50, 104) +#define TAS2557_BOOSTON_EFFICIENCY TAS2557_REG(0, 51, 16) +#define TAS2557_BOOSTOFF_EFFICIENCY TAS2557_REG(0, 51, 20) +#define TAS2557_BOOST_HEADROOM TAS2557_REG(0, 51, 24) +#define TAS2557_THERMAL_FOLDBACK_REG TAS2557_REG(0, 51, 100) + +#define TAS2557_SA_PG2P1_CHL_CTRL_REG TAS2557_REG(0, 53, 20) /* B0_P0x35_R0x14 */ +#define TAS2557_SA_COEFF_SWAP_REG TAS2557_REG(0, 53, 44) /* B0_P0x35_R0x2c */ + +#define TAS2557_SA_PG1P0_CHL_CTRL_REG TAS2557_REG(0, 58, 120) /* B0_P0x3a_R0x78 */ + +#define TAS2557_TEST_MODE_REG TAS2557_REG(0, 253, 13) /* B0_P0xfd_R0x0d */ +#define TAS2557_BROADCAST_REG TAS2557_REG(0, 253, 54) /* B0_P0xfd_R0x36 */ +#define TAS2557_CRYPTIC_REG TAS2557_REG(0, 253, 71) +#define TAS2557_PG2P1_CALI_R0_REG TAS2557_REG(0x8c, 0x2f, 0x40) +#define TAS2557_PG1P0_CALI_R0_REG TAS2557_REG(0x8c, 0x2f, 0x28) +#define TAS2557_PG2P1_CALI_T_REG TAS2557_REG(0x8c, 0x30, 0x20) +#define TAS2557_PG1P0_CALI_T_REG TAS2557_REG(0x8c, 0x30, 0x08) + +#define TAS2557_DAC_INTERPOL_REG TAS2557_REG(100, 0, 1) +#define TAS2557_SOFT_MUTE_REG TAS2557_REG(100, 0, 7) +#define TAS2557_PLL_P_VAL_REG TAS2557_REG(100, 0, 27) +#define TAS2557_PLL_J_VAL_REG TAS2557_REG(100, 0, 28) +#define TAS2557_PLL_D_VAL_MSB_REG TAS2557_REG(100, 0, 29) +#define TAS2557_PLL_D_VAL_LSB_REG TAS2557_REG(100, 0, 30) +#define TAS2557_CLK_MISC_REG TAS2557_REG(100, 0, 31) +#define TAS2557_PLL_N_VAL_REG TAS2557_REG(100, 0, 32) +#define TAS2557_DAC_MADC_VAL_REG TAS2557_REG(100, 0, 33) +#define TAS2557_ISENSE_DIV_REG TAS2557_REG(100, 0, 42) +#define TAS2557_RAMP_CLK_DIV_MSB_REG TAS2557_REG(100, 0, 43) +#define TAS2557_RAMP_CLK_DIV_LSB_REG TAS2557_REG(100, 0, 44) + +#define TAS2557_DIE_TEMP_REG TAS2557_REG(130, 2, 124) /* B0x82_P0x02_R0x7C */ + +/* Bits */ +/* B0P0R4 - TAS2557_POWER_CTRL1_REG */ +#define TAS2557_SW_SHUTDOWN (0x1 << 0) +#define TAS2557_MADC_POWER_UP (0x1 << 3) +#define TAS2557_MDAC_POWER_UP (0x1 << 4) +#define TAS2557_NDIV_POWER_UP (0x1 << 5) +#define TAS2557_PLL_POWER_UP (0x1 << 6) +#define TAS2557_DSP_POWER_UP (0x1 << 7) + +/* B0P0R5 - TAS2557_POWER_CTRL2_REG */ +#define TAS2557_VSENSE_ENABLE (0x1 << 0) +#define TAS2557_ISENSE_ENABLE (0x1 << 1) +#define TAS2557_BOOST_ENABLE (0x1 << 5) +#define TAS2557_CLASSD_ENABLE (0x1 << 7) + +/* B0P0R7 - TAS2557_MUTE_REG */ +#define TAS2557_CLASSD_MUTE (0x1 << 0) +#define TAS2557_ISENSE_MUTE (0x1 << 1) + +/* B0P253R13 - TAS2557_TEST_MODE_REG */ +#define TAS2557_TEST_MODE_ENABLE (13) +#define TAS2557_TEST_MODE_MASK (0xf << 0) + +/* B0P253R71 - TAS2557_CRYPTIC_REG */ +#define TAS2557_OSC_TRIM_CAP(x) ((x & 0x3f) << 0) +#define TAS2557_DISABLE_ENCRYPTION (0x1 << 6) +#define TAS2557_SL_COMP (0x1 << 7) + +/* B0P1R115/6 - TAS2557_MAIN/PLL_CLKIN_REG */ +#define TAS2557_XXX_CLKIN_GPIO1 (0) +#define TAS2557_XXX_CLKIN_GPIO2 (1) +#define TAS2557_XXX_CLKIN_GPIO3 (2) +#define TAS2557_XXX_CLKIN_GPIO4 (3) +#define TAS2557_XXX_CLKIN_GPIO5 (4) +#define TAS2557_XXX_CLKIN_GPIO6 (5) +#define TAS2557_XXX_CLKIN_GPIO7 (6) +#define TAS2557_XXX_CLKIN_GPIO8 (7) +#define TAS2557_XXX_CLKIN_GPIO9 (8) +#define TAS2557_XXX_CLKIN_GPIO10 (9) +#define TAS2557_XXX_CLKIN_GPI1 (12) +#define TAS2557_XXX_CLKIN_GPI2 (13) +#define TAS2557_XXX_CLKIN_GPI3 (14) +#define TAS2557_NDIV_CLKIN_PLL (15) +#define TAS2557_PLL_CLKIN_INT_OSC (15) + +#define TAS2557_MCLK_CLKIN_SRC_GPIO1 (0) +#define TAS2557_MCLK_CLKIN_SRC_GPIO2 (1) +#define TAS2557_MCLK_CLKIN_SRC_GPIO3 (2) +#define TAS2557_MCLK_CLKIN_SRC_GPIO4 (3) +#define TAS2557_MCLK_CLKIN_SRC_GPIO5 (4) +#define TAS2557_MCLK_CLKIN_SRC_GPIO6 (5) +#define TAS2557_MCLK_CLKIN_SRC_GPIO7 (6) +#define TAS2557_MCLK_CLKIN_SRC_GPIO8 (7) +#define TAS2557_MCLK_CLKIN_SRC_GPIO9 (8) +#define TAS2557_MCLK_CLKIN_SRC_GPIO10 (9) +#define TAS2557_MCLK_CLKIN_SRC_GPI1 (12) +#define TAS2557_MCLK_CLKIN_SRC_GPI2 (13) +#define TAS2557_MCLK_CLKIN_SRC_GPI3 (14) + +#define TAS2557_FORMAT_I2S (0x0 << 5) +#define TAS2557_FORMAT_DSP (0x1 << 5) +#define TAS2557_FORMAT_RIGHT_J (0x2 << 5) +#define TAS2557_FORMAT_LEFT_J (0x3 << 5) +#define TAS2557_FORMAT_MONO_PCM (0x4 << 5) +#define TAS2557_FORMAT_MASK (0x7 << 5) + +#define TAS2557_WORDLENGTH_16BIT (0x0 << 3) +#define TAS2557_WORDLENGTH_20BIT (0x1 << 3) +#define TAS2557_WORDLENGTH_24BIT (0x2 << 3) +#define TAS2557_WORDLENGTH_32BIT (0x3 << 3) +#define TAS2557_WORDLENGTH_MASK TAS2557_WORDLENGTH_32BIT + +/* B100P0R7 - TAS2557_SOFT_MUTE_REG */ +#define TAS2557_PDM_SOFT_MUTE (0x1 << 0) +#define TAS2557_VSENSE_SOFT_MUTE (0x1 << 1) +#define TAS2557_ISENSE_SOFT_MUTE (0x1 << 2) +#define TAS2557_CLASSD_SOFT_MUTE (0x1 << 3) + +/* B100P0R27 - TAS2557_PLL_P_VAL_REG */ +#define TAS2557_PLL_P_VAL_MASK (0x3f << 0) + +/* B100P0R28 - TAS2557_PLL_J_VAL_REG */ +#define TAS2557_PLL_J_VAL_MASK ((unsigned int) (0x7f << 0)) +#define TAS2557_PLL_J_VAL_MASKX 0x00 + +/* B100P0R29-30 - TAS2557_PLL_D_VAL_MSB/LSB_REG */ +#define TAS2557_PLL_D_MSB_VAL(x) ((x >> 8) & 0x3f) +#define TAS2557_PLL_D_LSB_VAL(x) (x & 0xff) + +/* B100P0R31 - TAS2557_CLK_MISC_REG */ +#define TAS2557_DSP_CLK_FROM_PLL (0x1 << 5) + +#define TAS2557_FW_NAME "tas2557_uCDSP.bin" +#define TAS2557_PG1P0_FW_NAME "tas2557_pg1p0_uCDSP.bin" + +#define TAS2557_APP_ROM1MODE 0 +#define TAS2557_APP_ROM2MODE 1 +#define TAS2557_APP_TUNINGMODE 2 +#define TAS2557_APP_ROM1_96KHZ 3 +#define TAS2557_APP_ROM2_96KHZ 4 +#define TAS2557_APP_RAMMODE 5 + +#define TAS2557_BOOST_OFF 0 +#define TAS2557_BOOST_DEVA 1 +#define TAS2557_BOOST_DEVB 2 +#define TAS2557_BOOST_BOTH 3 + +#define ERROR_NONE 0x00000000 +#define ERROR_PLL_ABSENT 0x00000001 +#define ERROR_DEVA_I2C_COMM 0x00000002 +#define ERROR_PRAM_CRCCHK 0x00000008 +#define ERROR_YRAM_CRCCHK 0x00000010 +#define ERROR_CLK_DET2 0x00000020 +#define ERROR_CLK_DET1 0x00000040 +#define ERROR_CLK_LOST 0x00000080 +#define ERROR_BROWNOUT 0x00000100 +#define ERROR_DIE_OVERTEMP 0x00000200 +#define ERROR_CLK_HALT 0x00000400 +#define ERROR_UNDER_VOLTAGE 0x00000800 +#define ERROR_OVER_CURRENT 0x00001000 +#define ERROR_CLASSD_PWR 0x00002000 +#define ERROR_SAFE_GUARD 0x00004000 +#define ERROR_FAILSAFE 0x40000000 + +struct TBlock { + unsigned int mnType; + unsigned char mbPChkSumPresent; + unsigned char mnPChkSum; + unsigned char mbYChkSumPresent; + unsigned char mnYChkSum; + unsigned int mnCommands; + unsigned char *mpData; +}; + +struct TData { + char mpName[64]; + char *mpDescription; + unsigned int mnBlocks; + struct TBlock *mpBlocks; +}; + +struct TProgram { + char mpName[64]; + char *mpDescription; + unsigned char mnAppMode; + unsigned short mnBoost; + struct TData mData; +}; + +struct TPLL { + char mpName[64]; + char *mpDescription; + struct TBlock mBlock; +}; + +struct TConfiguration { + char mpName[64]; + char *mpDescription; + unsigned int mnDevices; + unsigned int mnProgram; + unsigned int mnPLL; + unsigned int mnSamplingRate; + unsigned char mnPLLSrc; + unsigned int mnPLLSrcRate; + struct TData mData; +}; + +struct TCalibration { + char mpName[64]; + char *mpDescription; + unsigned int mnProgram; + unsigned int mnConfiguration; + struct TData mData; +}; + +struct TFirmware { + unsigned int mnFWSize; + unsigned int mnChecksum; + unsigned int mnPPCVersion; + unsigned int mnFWVersion; + unsigned int mnDriverVersion; + unsigned int mnTimeStamp; + char mpDDCName[64]; + char *mpDescription; + unsigned int mnDeviceFamily; + unsigned int mnDevice; + unsigned int mnPLLs; + struct TPLL *mpPLLs; + unsigned int mnPrograms; + struct TProgram *mpPrograms; + unsigned int mnConfigurations; + struct TConfiguration *mpConfigurations; + unsigned int mnCalibrations; + struct TCalibration *mpCalibrations; +}; + +struct tas2557_register { + int book; + int page; + int reg; +}; + +struct tas2557_priv { + struct device *dev; + struct regmap *mpRegmap; + int mnPGID; + int mnResetGPIO; + struct mutex dev_lock; + struct TFirmware *mpFirmware; + struct TFirmware *mpCalFirmware; + unsigned int mnCurrentProgram; + unsigned int mnCurrentSampleRate; + unsigned int mnNewConfiguration; + unsigned int mnCurrentConfiguration; + unsigned int mnCurrentCalibration; + unsigned char mnCurrentBook; + unsigned char mnCurrentPage; + bool mbTILoadActive; + bool mbPowerUp; + bool mbLoadConfigurationPrePowerUp; + bool mbLoadCalibrationPostPowerUp; + bool mbCalibrationLoaded; + int (*read)(struct tas2557_priv *pTAS2557, + unsigned int reg, + unsigned int *pValue); + int (*write)(struct tas2557_priv *pTAS2557, + unsigned int reg, + unsigned int Value); + int (*bulk_read)(struct tas2557_priv *pTAS2557, + unsigned int reg, + unsigned char *pData, + unsigned int len); + int (*bulk_write)(struct tas2557_priv *pTAS2557, + unsigned int reg, + unsigned char *pData, + unsigned int len); + int (*update_bits)(struct tas2557_priv *pTAS2557, + unsigned int reg, + unsigned int mask, + unsigned int value); + int (*set_config)(struct tas2557_priv *pTAS2557, + int config); + int (*set_calibration)(struct tas2557_priv *pTAS2557, + int calibration); + void (*clearIRQ)(struct tas2557_priv *pTAS2557); + void (*enableIRQ)(struct tas2557_priv *pTAS2557, bool enable, bool startup_chk); + void (*hw_reset)(struct tas2557_priv *pTAS2557); + /* device is working, but system is suspended */ + int (*runtime_suspend)(struct tas2557_priv *pTAS2557); + int (*runtime_resume)(struct tas2557_priv *pTAS2557); + + int mnGpioINT; + struct delayed_work irq_work; + unsigned int mnIRQ; + bool mbIRQEnable; + unsigned char mnI2SBits; + + + /* for low temperature check */ + unsigned int mnDevGain; + unsigned int mnDevCurrentGain; + unsigned int mnDieTvReadCounter; + struct hrtimer mtimer; + struct work_struct mtimerwork; + + /* device is working, but system is suspended */ + bool mbRuntimeSuspend; + + unsigned int mnErrCode; + unsigned int mnRestart; + + /* for configurations with maximum TLimit 0x7fffffff, + * bypass calibration update, usually used in factory test + */ + bool mbBypassTMax; + + unsigned int mnEdge; + +#ifdef CONFIG_TAS2557_CODEC + struct mutex codec_lock; +#endif + +#ifdef CONFIG_TAS2557_MISC + int mnDBGCmd; + int mnCurrentReg; + struct mutex file_lock; +#endif + +}; + +#endif /* _TAS2557_H */ diff --git a/sound/soc/codecs/tas2557/tiload.c b/sound/soc/codecs/tas2557/tiload.c new file mode 100755 index 000000000000..1719bc4ce706 --- /dev/null +++ b/sound/soc/codecs/tas2557/tiload.c @@ -0,0 +1,409 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tiload.c +** +** Description: +** utility for TAS2557 Android in-system tuning +** +** ============================================================================= +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tiload.h" + +/* enable debug prints in the driver */ +#define DEBUG + +static struct cdev *tiload_cdev; +static int tiload_major; /* Dynamic allocation of Mjr No. */ +static int tiload_opened; /* Dynamic allocation of Mjr No. */ +static struct tas2557_priv *g_TAS2557; +struct class *tiload_class; +static unsigned int magic_num; + +static char gPage; +static char gBook; +/******************************** Debug section *****************************/ + + +/*---------------------------------------------------------------------------- + * Function : tiload_open + * + * Purpose : open method for tiload programming interface + *---------------------------------------------------------------------------- + */ +static int tiload_open(struct inode *in, struct file *filp) +{ + struct tas2557_priv *pTAS2557 = g_TAS2557; + + dev_info(pTAS2557->dev, "%s\n", __func__); + + if (tiload_opened) { + dev_info(pTAS2557->dev, "%s device is already opened\n", "tiload"); + return -EINVAL; + } + filp->private_data = (void *)pTAS2557; + tiload_opened++; + return 0; +} + +/*---------------------------------------------------------------------------- + * Function : tiload_release + * + * Purpose : close method for tiload programming interface + *---------------------------------------------------------------------------- + */ +static int tiload_release(struct inode *in, struct file *filp) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data; + + dev_info(pTAS2557->dev, "%s\n", __func__); + filp->private_data = NULL; + tiload_opened--; + return 0; +} + +#define MAX_LENGTH 128 +/*---------------------------------------------------------------------------- + * Function : tiload_read + * + * Purpose : read from codec + *---------------------------------------------------------------------------- + */ +static ssize_t tiload_read(struct file *filp, char __user *buf, + size_t count, loff_t *offset) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data; + static char rd_data[MAX_LENGTH + 1]; + unsigned int nCompositeRegister = 0, Value = 0; + char reg_addr; + size_t size; + int ret = 0; +#ifdef DEBUG + /* int i; */ +#endif + + dev_info(pTAS2557->dev, "%s\n", __func__); + if (count > MAX_LENGTH) { + dev_err(pTAS2557->dev, "Max %d bytes can be read\n", MAX_LENGTH); + return -EINVAL; + } + + /* copy register address from user space */ + size = copy_from_user(®_addr, buf, 1); + if (size != 0) { + dev_err(pTAS2557->dev, "read: copy_from_user failure\n"); + return -EINVAL; + } + + size = count; + + nCompositeRegister = BPR_REG(gBook, gPage, reg_addr); + if (count == 1) { + ret = + pTAS2557->read(pTAS2557, 0x80000000 | nCompositeRegister, &Value); + if (ret >= 0) + rd_data[0] = (char) Value; + } else if (count > 1) { + ret = + pTAS2557->bulk_read(pTAS2557, 0x80000000 | nCompositeRegister, + rd_data, size); + } + if (ret < 0) + dev_err(pTAS2557->dev, "%s, %d, ret=%d, count=%zu error happen!\n", + __func__, __LINE__, ret, count); + +#ifdef DEBUG + dev_info(pTAS2557->dev, "read size = %d, reg_addr= %x , count = %d\n", + (int) size, reg_addr, (int) count); +/* for (i = 0; i < (int) size; i++) { +* dev_dbg(pTAS2557->dev, "rd_data[%d]=%x\n", i, rd_data[i]); +* } +*/ +#endif + if (size != count) + dev_err(pTAS2557->dev, "read %d registers from the codec\n", (int) size); + + if (copy_to_user(buf, rd_data, size) != 0) { + dev_err(pTAS2557->dev, "copy_to_user failed\n"); + return -EINVAL; + } + + return size; +} + +/* + *---------------------------------------------------------------------------- + * Function : tiload_write + * + * Purpose : write to codec + *---------------------------------------------------------------------------- + */ +static ssize_t tiload_write(struct file *filp, const char __user *buf, + size_t count, loff_t *offset) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data; + static char wr_data[MAX_LENGTH + 1]; + char *pData = wr_data; + size_t size; + unsigned int nCompositeRegister = 0; + unsigned int nRegister; + int ret = 0; +#ifdef DEBUG + /* int i; */ +#endif + dev_info(pTAS2557->dev, "%s\n", __func__); + + if (count > MAX_LENGTH) { + dev_err(pTAS2557->dev, "Max %d bytes can be read\n", MAX_LENGTH); + return -EINVAL; + } + + /* copy buffer from user space */ + size = copy_from_user(wr_data, buf, count); + if (size != 0) { + dev_err(pTAS2557->dev, "copy_from_user failure %d\n", (int) size); + return -EINVAL; + } +#ifdef DEBUG + dev_info(pTAS2557->dev, "write size = %zu\n", count); +/* for (i = 0; i < (int) count; i++) { +* dev_info(pTAS2557->dev, "wr_data[%d]=%x\n", i, wr_data[i]); +* } +*/ +#endif + nRegister = wr_data[0]; + size = count; + if ((nRegister == 127) && (gPage == 0)) { + gBook = wr_data[1]; + return size; + } + + if (nRegister == 0) { + gPage = wr_data[1]; + pData++; + count--; + } + + nCompositeRegister = BPR_REG(gBook, gPage, nRegister); + if (count == 2) { + ret = + pTAS2557->write(pTAS2557, 0x80000000 | nCompositeRegister, + pData[1]); + } else if (count > 2) { + ret = + pTAS2557->bulk_write(pTAS2557, 0x80000000 | nCompositeRegister, + &pData[1], count - 1); + } + + if (ret < 0) + dev_err(pTAS2557->dev, "%s, %d, ret=%d, count=%zu, ERROR Happen\n", __func__, + __LINE__, ret, count); + + return size; +} + +static void tiload_route_IO(struct tas2557_priv *pTAS2557, unsigned int bLock) +{ + if (bLock) + pTAS2557->write(pTAS2557, 0xAFFEAFFE, 0xBABEBABE); + else + pTAS2557->write(pTAS2557, 0xBABEBABE, 0xAFFEAFFE); +} + +static long tiload_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data; + long num = 0; + void __user *argp = (void __user *) arg; + int val; + struct BPR bpr; + + dev_info(pTAS2557->dev, "%s, cmd=0x%x\n", __func__, cmd); +/* if (_IOC_TYPE(cmd) != TILOAD_IOC_MAGIC) + * return -ENOTTY; + */ + + switch (cmd) { + case TILOAD_IOMAGICNUM_GET: + num = copy_to_user(argp, &magic_num, sizeof(int)); + break; + case TILOAD_IOMAGICNUM_SET: + num = copy_from_user(&magic_num, argp, sizeof(int)); + dev_info(pTAS2557->dev, "TILOAD_IOMAGICNUM_SET\n"); + tiload_route_IO(pTAS2557, magic_num); + break; + case TILOAD_BPR_READ: + break; + case TILOAD_BPR_WRITE: + num = copy_from_user(&bpr, argp, sizeof(struct BPR)); + dev_info(pTAS2557->dev, "TILOAD_BPR_WRITE: 0x%02X, 0x%02X, 0x%02X\n\r", bpr.nBook, + bpr.nPage, bpr.nRegister); + break; + case TILOAD_IOCTL_SET_CHL: + break; + case TILOAD_IOCTL_SET_CONFIG: + num = copy_from_user(&val, argp, sizeof(val)); + pTAS2557->set_config(pTAS2557, val); + break; + case TILOAD_IOCTL_SET_CALIBRATION: + num = copy_from_user(&val, argp, sizeof(val)); + pTAS2557->set_calibration(pTAS2557, val); + break; + default: + break; + } + return num; +} + +#ifdef CONFIG_COMPAT +static long tiload_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct tas2557_priv *pTAS2557 = (struct tas2557_priv *)filp->private_data; + long nResult = 0; + + switch (cmd) { + case TILOAD_COMPAT_IOMAGICNUM_GET: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOMAGICNUM_GET=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_IOMAGICNUM_GET, + (unsigned long) compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOMAGICNUM_SET: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOMAGICNUM_SET=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_IOMAGICNUM_SET, + (unsigned long) compat_ptr(arg)); + break; + + case TILOAD_COMPAT_BPR_READ: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_BPR_READ=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_BPR_READ, + (unsigned long) compat_ptr(arg)); + break; + + case TILOAD_COMPAT_BPR_WRITE: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_BPR_WRITE=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_BPR_WRITE, + (unsigned long) compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOCTL_SET_CHL: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOCTL_SET_CHL=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CHL, + (unsigned long) compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOCTL_SET_CONFIG: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOCTL_SET_CONFIG=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CONFIG, + (unsigned long) compat_ptr(arg)); + break; + + case TILOAD_COMPAT_IOCTL_SET_CALIBRATION: + dev_info(pTAS2557->dev, "%s, TILOAD_COMPAT_IOCTL_SET_CALIBRATION=0x%x\n", + __func__, cmd); + nResult = tiload_ioctl(filp, TILOAD_IOCTL_SET_CALIBRATION, + (unsigned long) compat_ptr(arg)); + break; + + default: + dev_err(pTAS2557->dev, "%s, unsupport compat ioctl=0x%x\n", + __func__, cmd); + break; + } + + return nResult; +} +#endif + +/*********** File operations structure for tiload *************/ +static const struct file_operations tiload_fops = { + .owner = THIS_MODULE, + .open = tiload_open, + .release = tiload_release, + .read = tiload_read, + .write = tiload_write, + .unlocked_ioctl = tiload_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = tiload_compat_ioctl, +#endif +}; + +/*---------------------------------------------------------------------------- + * Function : tiload_driver_init + * + * Purpose : Register a char driver for dynamic tiload programming + *---------------------------------------------------------------------------- + */ +int tiload_driver_init(struct tas2557_priv *pTAS2557) +{ + int result; + dev_t dev = MKDEV(tiload_major, 0); + + g_TAS2557 = pTAS2557; + + dev_info(pTAS2557->dev, "%s\n", __func__); + + result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME); + if (result < 0) { + dev_err(pTAS2557->dev, "cannot allocate major number %d\n", tiload_major); + return result; + } + tiload_class = class_create(THIS_MODULE, DEVICE_NAME); + tiload_major = MAJOR(dev); + dev_info(pTAS2557->dev, "allocated Major Number: %d\n", tiload_major); + + tiload_cdev = cdev_alloc(); + cdev_init(tiload_cdev, &tiload_fops); + tiload_cdev->owner = THIS_MODULE; + tiload_cdev->ops = &tiload_fops; + + if (device_create(tiload_class, NULL, dev, NULL, "tiload_node") == NULL) + dev_err(pTAS2557->dev, "Device creation failed\n"); + + if (cdev_add(tiload_cdev, dev, 1) < 0) { + dev_err(pTAS2557->dev, "tiload_driver: cdev_add failed\n"); + unregister_chrdev_region(dev, 1); + tiload_cdev = NULL; + return 1; + } + dev_info(pTAS2557->dev, "Registered TiLoad driver, Major number: %d\n", tiload_major); + /* class_device_create(tiload_class, NULL, dev, NULL, DEVICE_NAME, 0); */ + return 0; +} + +MODULE_AUTHOR("Texas Instruments Inc."); +MODULE_DESCRIPTION("Utility for TAS2557 Android in-system tuning"); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/codecs/tas2557/tiload.h b/sound/soc/codecs/tas2557/tiload.h new file mode 100755 index 000000000000..7468acfa3964 --- /dev/null +++ b/sound/soc/codecs/tas2557/tiload.h @@ -0,0 +1,65 @@ +/* +** ============================================================================= +** Copyright (c) 2016 Texas Instruments Inc. +** +** This program is free software; you can redistribute it and/or modify it under +** the terms of the GNU General Public License as published by the Free Software +** Foundation; version 2. +** +** This program is distributed 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. +** +** File: +** tiload.h +** +** Description: +** header file for tiload.c +** +** ============================================================================= +*/ + +#ifndef _TILOAD_H +#define _TILOAD_H + +#ifdef CONFIG_COMPAT +#include +#endif + +#include "tas2557.h" + +#define BPR_REG(book, page, reg) (((book * 256 * 128) + \ + (page * 128)) + reg) + +/* typedefs required for the included header files */ +struct BPR { + unsigned char nBook; + unsigned char nPage; + unsigned char nRegister; +}; + +/* defines */ +#define DEVICE_NAME "tiload_node" + +#define TILOAD_IOC_MAGIC 0xE0 +#define TILOAD_IOMAGICNUM_GET _IOR(TILOAD_IOC_MAGIC, 1, int) +#define TILOAD_IOMAGICNUM_SET _IOW(TILOAD_IOC_MAGIC, 2, int) +#define TILOAD_BPR_READ _IOR(TILOAD_IOC_MAGIC, 3, struct BPR) +#define TILOAD_BPR_WRITE _IOW(TILOAD_IOC_MAGIC, 4, struct BPR) +#define TILOAD_IOCTL_SET_CHL _IOW(TILOAD_IOC_MAGIC, 5, int) +#define TILOAD_IOCTL_SET_CONFIG _IOW(TILOAD_IOC_MAGIC, 6, int) +#define TILOAD_IOCTL_SET_CALIBRATION _IOW(TILOAD_IOC_MAGIC, 7, int) + +#ifdef CONFIG_COMPAT +#define TILOAD_COMPAT_IOMAGICNUM_GET _IOR(TILOAD_IOC_MAGIC, 1, compat_int_t) +#define TILOAD_COMPAT_IOMAGICNUM_SET _IOW(TILOAD_IOC_MAGIC, 2, compat_int_t) +#define TILOAD_COMPAT_BPR_READ _IOR(TILOAD_IOC_MAGIC, 3, struct BPR) +#define TILOAD_COMPAT_BPR_WRITE _IOW(TILOAD_IOC_MAGIC, 4, struct BPR) +#define TILOAD_COMPAT_IOCTL_SET_CHL _IOW(TILOAD_IOC_MAGIC, 5, compat_int_t) +#define TILOAD_COMPAT_IOCTL_SET_CONFIG _IOW(TILOAD_IOC_MAGIC, 6, compat_int_t) +#define TILOAD_COMPAT_IOCTL_SET_CALIBRATION _IOW(TILOAD_IOC_MAGIC, 7, compat_int_t) +#endif + +int tiload_driver_init(struct tas2557_priv *pTAS2557); + +#endif -- GitLab From 77d6b6be91374dacf012df900f0e9ec7d4a6c943 Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Thu, 2 Jul 2020 12:07:33 +0800 Subject: [PATCH 26/96] Read calibration data for speakers from persist Use the calibration data from persist partition instead of data partition to adjust speaker performance. Issue: FP3-A11#202 Change-Id: Ib3e9aaa3bc8a55fe4bbf99061c7d71b8ace810ac (cherry picked from commit ee7f73755ef1c4e41736762910f241f96404dc04) --- sound/soc/codecs/tas2557/tas2557-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/tas2557/tas2557-core.c b/sound/soc/codecs/tas2557/tas2557-core.c index 783642cc05ca..c5349d38f01e 100755 --- a/sound/soc/codecs/tas2557/tas2557-core.c +++ b/sound/soc/codecs/tas2557/tas2557-core.c @@ -46,7 +46,7 @@ #define PPC_DRIVER_MTPLLSRC 0x00000400 #define PPC_DRIVER_CFGDEV_NONCRC 0x00000101 -#define TAS2557_CAL_NAME "/data/tas2557_cal.bin" +#define TAS2557_CAL_NAME "/mnt/vendor/persist/tas2557_cal.bin" #define RESTART_MAX 3 static int tas2557_load_calibration(struct tas2557_priv *pTAS2557, -- GitLab From 288d86dc809e6faf6ada6d8f5b665e5808906d70 Mon Sep 17 00:00:00 2001 From: Bharath Date: Sat, 14 Aug 2021 13:29:53 +0530 Subject: [PATCH 27/96] Cleanup debug warnings This simply spams the build logs. Issue: FP3-A11#202 Change-Id: I63fa15ec58e113125581baa58168039f8cce6130 --- AndroidKernel.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index 3d0669f4a746..35726c3849ed 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -26,7 +26,6 @@ TARGET_KERNEL_HEADER_ARCH := $(strip $(TARGET_KERNEL_HEADER_ARCH)) ifeq ($(TARGET_KERNEL_HEADER_ARCH),) KERNEL_HEADER_ARCH := $(KERNEL_ARCH) else -$(warning Forcing kernel header generation only for '$(TARGET_KERNEL_HEADER_ARCH)') KERNEL_HEADER_ARCH := $(TARGET_KERNEL_HEADER_ARCH) endif @@ -52,7 +51,6 @@ ifeq ($(KERNEL_LLVM_SUPPORT), true) $(warning "Using sdllvm" $(KERNEL_LLVM_BIN)) else KERNEL_LLVM_BIN := $(shell pwd)/$(CLANG) #Using aosp-llvm compiler - $(warning "Using aosp-llvm" $(KERNEL_LLVM_BIN)) endif endif -- GitLab From 211a78fdcea00d792ce5f73c45ed78f875b7bc20 Mon Sep 17 00:00:00 2001 From: frankcheng Date: Sat, 9 May 2020 20:59:58 +0800 Subject: [PATCH 28/96] Add Camera drivers for FP3 Issue: FP3-A11#229 Change-Id: Iecba04814a03123628c4a634d59834c395a5dd72 --- .../dts/qcom/msm8953-camera-sensor-mtp.dtsi | 251 +++++++----------- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 76 +++++- .../camera_v2/sensor/actuator/msm_actuator.c | 6 +- .../msm/camera_v2/sensor/msm_sensor_driver.c | 18 ++ 4 files changed, 180 insertions(+), 171 deletions(-) mode change 100644 => 100755 arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c diff --git a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi old mode 100644 new mode 100755 index f3e13c0a1949..41346118441a --- a/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-camera-sensor-mtp.dtsi @@ -20,7 +20,6 @@ reg = <0x0>; compatible = "qcom,actuator"; qcom,cci-master = <0>; - cam_vaf-supply = <&pm8953_l17>; qcom,cam-vreg-name = "cam_vaf"; qcom,cam-vreg-min-voltage = <2850000>; qcom,cam-vreg-max-voltage = <2850000>; @@ -44,111 +43,85 @@ compatible = "qcom,eeprom"; qcom,cci-master = <0>; reg = <0x0>; - cam_vio-supply = <&pm8953_l6>; - cam_vdig-supply = <&pm8953_l2>; - cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf"; - qcom,cam-vreg-min-voltage = <0 1200000 2850000>; - qcom,cam-vreg-max-voltage = <0 1200000 2850000>; - qcom,cam-vreg-op-mode = <0 105000 100000>; + cam_vana-supply = <&pm8953_l22>; + cam_v_custom1-supply = <&pm8953_l2>; + qcom,cam-vreg-name = "cam_vana", "cam_v_custom1"; + qcom,cam-vreg-min-voltage = <2800000 1175000>; + qcom,cam-vreg-max-voltage = <2800000 1175000>; + qcom,cam-vreg-op-mode = <80000 105000>; pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk0_default - &cam_sensor_rear_default - &cam_sensor_rear_vana>; - pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep - &cam_sensor_rear_vana_sleep>; + pinctrl-0 = <&cam_sensor_mclk0_default &cam_sensor_rear_default>; + pinctrl-1 = <&cam_sensor_mclk0_sleep &cam_sensor_rear_sleep>; gpios = <&tlmm 26 0>, <&tlmm 40 0>, - <&tlmm 39 0>, - <&tlmm 134 0>; + <&tlmm 130 0>; qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-vana = <3>; - qcom,gpio-req-tbl-num = <0 1 2 3>; - qcom,gpio-req-tbl-flags = <1 0 0 0>; + qcom,gpio-vio = <2>; + qcom,gpio-req-tbl-num = <0 1 2>; + qcom,gpio-req-tbl-flags = <1 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0", - "CAM_STANDBY0", - "CAM_VANA"; + "CAM_VIO"; + qcom,sensor-position = <0>; + qcom,sensor-mode = <0>; status = "ok"; clocks = <&clock_gcc clk_mclk0_clk_src>, <&clock_gcc clk_gcc_camss_mclk0_clk>; clock-names = "cam_src_clk", "cam_clk"; - qcom,clock-rates = <19200000 0>; + qcom,clock-rates = <24000000 0>; }; eeprom1: qcom,eeprom@1 { cell-index = <1>; - reg = <0x1>; compatible = "qcom,eeprom"; qcom,cci-master = <1>; - cam_vdig-supply = <&pm8953_l23>; - cam_vio-supply = <&pm8953_l6>; + reg = <0x1>; + cam_vana-supply = <&pm8953_l22>; - cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", - "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,cam-vreg-name = "cam_vana"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <80000>; qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_default - &cam_sensor_front1_default>; + &cam_sensor_front1_default + &cam_sensor_front1_vdig_default + &cam_sensor_front1_vio_default>; pinctrl-1 = <&cam_sensor_mclk1_sleep - &cam_sensor_front1_sleep>; + &cam_sensor_front1_sleep + &cam_sensor_front1_vdig_sleep + &cam_sensor_front1_vio_sleep>; + gpios = <&tlmm 27 0>, - <&tlmm 129 0>, - <&tlmm 130 0>; + <&tlmm 129 0>, + <&tlmm 46 0>, + <&tlmm 130 0>; qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-vdig = <2>; + qcom,gpio-vio = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2", - "CAM_STANDBY2"; - qcom,sensor-position = <1>; - qcom,sensor-mode = <0>; - status = "ok"; - clocks = <&clock_gcc clk_mclk1_clk_src>, - <&clock_gcc clk_gcc_camss_mclk1_clk>; - clock-names = "cam_src_clk", "cam_clk"; - qcom,clock-rates = <19200000 0>; - }; + "CAM_RESET2", + "CAM_VDIG2", + "CAM_VIO2"; - eeprom2: qcom,eeprom@2 { - cell-index = <2>; - compatible = "qcom,eeprom"; - qcom,cci-master = <1>; - reg = <0x2>; - cam_vdig-supply = <&pm8953_l23>; - cam_vana-supply = <&pm8953_l22>; - cam_vio-supply = <&pm8953_l6>; - cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", - "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-op-mode = <200000 0 80000 100000>; - pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk2_default - &cam_sensor_front_default>; - pinctrl-1 = <&cam_sensor_mclk2_sleep - &cam_sensor_front_sleep>; - gpios = <&tlmm 28 0>, - <&tlmm 131 0>, - <&tlmm 132 0>; - qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; - qcom,gpio-req-tbl-label = "CAMIF_MCLK1", - "CAM_RESET1", - "CAM_STANDBY1"; status = "ok"; - clocks = <&clock_gcc clk_mclk2_clk_src>, - <&clock_gcc clk_gcc_camss_mclk2_clk>; + qcom,cam-power-seq-val = "sensor_gpio_reset", + "cam_vana", "sensor_gpio_vdig", + "sensor_gpio_vio", "sensor_gpio_reset", + "sensor_cam_mclk"; + qcom,cam-power-seq-type = "sensor_gpio", + "sensor_vreg", "sensor_gpio", + "sensor_gpio", "sensor_gpio", + "sensor_clk"; + qcom,cam-power-seq-cfg-val = <0 1 1 1 1 24000000>; + qcom,cam-power-seq-delay = <5 1 1 3 3 10>; clock-names = "cam_src_clk", "cam_clk"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; qcom,clock-rates = <19200000 0>; }; @@ -162,16 +135,12 @@ qcom,led-flash-src = <&led_flash0>; qcom,eeprom-src = <&eeprom0>; qcom,actuator-src = <&actuator0>; - cam_vio-supply = <&pm8953_l6>; - cam_vdig-supply = <&pm8953_l2>; - cam_vaf-supply = <&pm8953_l17>; cam_vana-supply = <&pm8953_l22>; - cam_v_custom1-supply = <&pm8953_l23>; - qcom,cam-vreg-name = "cam_vio", "cam_vdig", "cam_vaf", - "cam_vana", "cam_v_custom1"; - qcom,cam-vreg-min-voltage = <0 1200000 2850000 2800000 1200000>; - qcom,cam-vreg-max-voltage = <0 1200000 2850000 2800000 1200000>; - qcom,cam-vreg-op-mode = <0 105000 100000 80000 105000>; + cam_v_custom1-supply = <&pm8953_l2>; + qcom,cam-vreg-name = "cam_vana", "cam_v_custom1"; + qcom,cam-vreg-min-voltage = <2800000 1175000>; + qcom,cam-vreg-max-voltage = <2800000 1175000>; + qcom,cam-vreg-op-mode = <80000 105000>; pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk0_default &cam_sensor_rear_default @@ -180,17 +149,17 @@ &cam_sensor_rear_vana_sleep>; gpios = <&tlmm 26 0>, <&tlmm 40 0>, - <&tlmm 39 0>, - <&tlmm 134 0>; + <&tlmm 130 0>, + <&tlmm 128 0>; qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-vana = <3>; + qcom,gpio-vio = <2>; + qcom,gpio-vaf = <3>; qcom,gpio-req-tbl-num = <0 1 2 3>; qcom,gpio-req-tbl-flags = <1 0 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET0", - "CAM_STANDBY0", - "CAM_VANA"; + "CAM_VIO", + "CAM_VAF"; qcom,sensor-position = <0>; qcom,sensor-mode = <0>; qcom,cci-master = <0>; @@ -201,90 +170,52 @@ qcom,clock-rates = <24000000 0>; }; - qcom,camera@1 { - cell-index = <1>; - compatible = "qcom,camera"; - reg = <0x1>; - qcom,csiphy-sd-index = <1>; - qcom,csid-sd-index = <1>; - qcom,mount-angle = <90>; - qcom,eeprom-src = <&eeprom2>; - qcom,actuator-src = <&actuator1>; - cam_vdig-supply = <&pm8953_l23>; - cam_vana-supply = <&pm8953_l22>; - cam_vio-supply = <&pm8953_l6>; - cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", - "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-op-mode = <200000 0 80000 100000>; - pinctrl-names = "cam_default", "cam_suspend"; - pinctrl-0 = <&cam_sensor_mclk2_default - &cam_sensor_front_default>; - pinctrl-1 = <&cam_sensor_mclk2_sleep - &cam_sensor_front_sleep>; - gpios = <&tlmm 28 0>, - <&tlmm 131 0>, - <&tlmm 132 0>; - qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; - qcom,gpio-req-tbl-label = "CAMIF_MCLK1", - "CAM_RESET1", - "CAM_STANDBY1"; - qcom,sensor-position = <0x100>; - qcom,sensor-mode = <1>; - qcom,cci-master = <1>; - status = "ok"; - clocks = <&clock_gcc clk_mclk2_clk_src>, - <&clock_gcc clk_gcc_camss_mclk2_clk>; - clock-names = "cam_src_clk", "cam_clk"; - qcom,clock-rates = <24000000 0>; - }; - - qcom,camera@2 { + camera2: qcom,camera@2 { cell-index = <2>; compatible = "qcom,camera"; reg = <0x02>; qcom,csiphy-sd-index = <2>; - qcom,csid-sd-index = <2>; - qcom,mount-angle = <90>; + qcom,csid-sd-index = <1>; + qcom,mount-angle = <270>; qcom,eeprom-src = <&eeprom1>; - qcom,actuator-src = <&actuator1>; - cam_vdig-supply = <&pm8953_l23>; - cam_vio-supply = <&pm8953_l6>; cam_vana-supply = <&pm8953_l22>; - cam_vaf-supply = <&pm8953_l17>; - qcom,cam-vreg-name = "cam_vdig", "cam_vio", "cam_vana", - "cam_vaf"; - qcom,cam-vreg-min-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-max-voltage = <1200000 0 2800000 2850000>; - qcom,cam-vreg-op-mode = <105000 0 80000 100000>; + qcom,cam-vreg-name = "cam_vana"; + qcom,cam-vreg-min-voltage = <2800000>; + qcom,cam-vreg-max-voltage = <2800000>; + qcom,cam-vreg-op-mode = <80000>; qcom,gpio-no-mux = <0>; + pinctrl-names = "cam_default", "cam_suspend"; pinctrl-0 = <&cam_sensor_mclk1_default - &cam_sensor_front1_default>; + &cam_sensor_front1_default + &cam_sensor_front1_vdig_default + &cam_sensor_front1_vio_default>; pinctrl-1 = <&cam_sensor_mclk1_sleep - &cam_sensor_front1_sleep>; + &cam_sensor_front1_sleep + &cam_sensor_front1_vdig_sleep + &cam_sensor_front1_vio_sleep>; + gpios = <&tlmm 27 0>, - <&tlmm 129 0>, - <&tlmm 130 0>; + <&tlmm 129 0>, + <&tlmm 46 0>, + <&tlmm 130 0>; qcom,gpio-reset = <1>; - qcom,gpio-standby = <2>; - qcom,gpio-req-tbl-num = <0 1 2>; - qcom,gpio-req-tbl-flags = <1 0 0>; + qcom,gpio-vdig = <2>; + qcom,gpio-vio = <3>; + qcom,gpio-req-tbl-num = <0 1 2 3>; + qcom,gpio-req-tbl-flags = <1 0 0 0>; qcom,gpio-req-tbl-label = "CAMIF_MCLK2", - "CAM_RESET2", - "CAM_STANDBY2"; + "CAM_RESET2", + "CAM_VDIG2", + "CAM_VIO2"; + qcom,sensor-position = <1>; qcom,sensor-mode = <0>; qcom,cci-master = <1>; status = "ok"; - clocks = <&clock_gcc clk_mclk1_clk_src>, - <&clock_gcc clk_gcc_camss_mclk1_clk>; clock-names = "cam_src_clk", "cam_clk"; + clocks = <&clock_gcc clk_mclk1_clk_src>, + <&clock_gcc clk_gcc_camss_mclk1_clk>; qcom,clock-rates = <24000000 0>; }; }; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 7c74b29e8fbd..8f55971ecabd 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -92,7 +92,7 @@ config { pins = "gpio31", "gpio32"; - drive-strength = <2>; /* 2 MA */ + drive-strength = <4>; /* 4 MA */ bias-disable; /* No PULL */ }; }; @@ -203,12 +203,12 @@ cam_sensor_rear_vana: cam_sensor_rear_vdig { /* VDIG */ mux { - pins = "gpio134"; + pins = "gpio128"; function = "gpio"; }; config { - pins = "gpio134"; + pins = "gpio128"; bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; @@ -217,12 +217,12 @@ cam_sensor_rear_vana_sleep: cam_sensor_rear_vdig_sleep { /* VDIG */ mux { - pins = "gpio134"; + pins = "gpio128"; function = "gpio"; }; config { - pins = "gpio134"; + pins = "gpio128"; bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; @@ -239,7 +239,7 @@ config { pins = "gpio27"; bias-disable; /* No PULL */ - drive-strength = <2>; /* 2 MA */ + drive-strength = <8>; /* 8 MA */ }; }; @@ -316,15 +316,71 @@ }; }; + cam_sensor_front1_vio_default: cam_sensor_front1_vio_default { + /* CAM IOVDD */ + mux { + pins = "gpio130"; + function = "gpio"; + }; + + config { + pins = "gpio130"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front1_vio_sleep: cam_sensor_front1_vio_sleep { + /* CAM IOVDD */ + mux { + pins = "gpio130"; + function = "gpio"; + }; + + config { + pins = "gpio130"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front1_vdig_default: cam_sensor_front1_vdig_default { + /* CAM DVDD */ + mux { + pins = "gpio46"; + function = "gpio"; + }; + + config { + pins = "gpio46"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + + cam_sensor_front1_vdig_sleep: cam_sensor_front1_vdig_sleep { + /* CAM DVDD */ + mux { + pins = "gpio46"; + function = "gpio"; + }; + + config { + pins = "gpio46"; + bias-disable; /* No PULL */ + drive-strength = <2>; /* 2 MA */ + }; + }; + cam_sensor_front1_default: cam_sensor_front1_default { /* RESET, STANDBY */ mux { - pins = "gpio129", "gpio130"; + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ function = "gpio"; }; config { - pins = "gpio129", "gpio130"; + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; @@ -333,12 +389,12 @@ cam_sensor_front1_sleep: cam_sensor_front1_sleep { /* RESET, STANDBY */ mux { - pins = "gpio129", "gpio130"; + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ function = "gpio"; }; config { - pins = "gpio129", "gpio130"; + pins = "gpio129"; /* Only Reset,Non-standby GPIO */ bias-disable; /* No PULL */ drive-strength = <2>; /* 2 MA */ }; diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c old mode 100644 new mode 100755 index 2806132c09b8..d3d72abc858a --- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c +++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c @@ -31,6 +31,9 @@ DEFINE_MSM_MUTEX(msm_actuator_mutex); #define PARK_LENS_SMALL_STEP 3 #define MAX_QVALUE 4096 +extern int nActuatorAK7374; +extern int nActuatorDW9800; + static struct v4l2_file_operations msm_actuator_v4l2_subdev_fops; static int32_t msm_actuator_power_up(struct msm_actuator_ctrl_t *a_ctrl); static int32_t msm_actuator_power_down(struct msm_actuator_ctrl_t *a_ctrl); @@ -118,7 +121,8 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl, write_arr[i].data_shift) | ((hw_dword & write_arr[i].hw_mask) >> write_arr[i].hw_shift); - + if(nActuatorAK7374 == 0 && nActuatorDW9800 == 0) + value = abs(1023-value); if (write_arr[i].reg_addr != 0xFFFF) { i2c_byte1 = write_arr[i].reg_addr; i2c_byte2 = value; diff --git a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c old mode 100644 new mode 100755 index 4bc13d03d36d..382084485e52 --- a/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c +++ b/drivers/media/platform/msm/camera_v2/sensor/msm_sensor_driver.c @@ -25,6 +25,9 @@ #define SENSOR_MAX_MOUNTANGLE (360) +int nActuatorAK7374 = 0; +int nActuatorDW9800 = 0; + static struct v4l2_file_operations msm_sensor_v4l2_subdev_fops; static int32_t msm_sensor_driver_platform_probe(struct platform_device *pdev); @@ -1136,6 +1139,21 @@ int32_t msm_sensor_driver_probe(void *setting, goto free_camera_info; } + pr_err("%s:%d s_ctrl->sensordata->actuator_name: %s\n", + __func__, __LINE__, + s_ctrl->sensordata->actuator_name); + if (strcmp(s_ctrl->sensordata->actuator_name, "ak7374") == 0) { + nActuatorAK7374 = 1; + pr_err("%s:%d nActuatorAK7374: %d\n", + __func__, __LINE__, + nActuatorAK7374); + } else if (strcmp(s_ctrl->sensordata->actuator_name, "dw9800") == 0) { + nActuatorDW9800 = 1; + pr_err("%s:%d nActuatorDW9800: %d\n", + __func__, __LINE__, + nActuatorDW9800); + } + pr_err("%s probe succeeded", slave_info->sensor_name); s_ctrl->bypass_video_node_creation = -- GitLab From 0e55b579c897fd478bbfb1d89065a0acae45f8ab Mon Sep 17 00:00:00 2001 From: frankcheng Date: Sat, 4 Jul 2020 15:23:33 +0800 Subject: [PATCH 29/96] Add a flag for VIO turn on and off if multi-camera operate Includes required parts of squashed commit "The define declare and common message modified". (Change-Id: I0d995ee5d197e071a138ba82ba68a4ee54383a55) Issue: FP3-A11#230 Change-Id: If9a0803a21e5ec7af40d6e23d7f47b2546120234 --- .../camera_v2/sensor/io/msm_camera_dt_util.c | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c index a33436e72ba9..26dc662c0cde 100644 --- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c +++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_dt_util.c @@ -26,6 +26,13 @@ #undef CDBG #define CDBG(fmt, args...) pr_debug(fmt, ##args) +/* enable multi-camera on/off code */ +#define MULTI_CAMERA_POWER_ON + +#if defined (MULTI_CAMERA_POWER_ON) +int iovdd_count = 0; +#endif + int msm_camera_fill_vreg_params(struct camera_vreg_t *cam_vreg, int num_vreg, struct msm_sensor_power_setting *power_setting, uint16_t power_setting_size) @@ -1512,10 +1519,26 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, CDBG("%s:%d gpio set val %d\n", __func__, __LINE__, ctrl->gpio_conf->gpio_num_info->gpio_num [power_setting->seq_val]); + #if defined (MULTI_CAMERA_POWER_ON) + if (power_setting->seq_val == SENSOR_GPIO_VIO) { + CDBG("[%s][Arima] 1.Set common gpio. Loop %d\n", __func__, iovdd_count); + if (iovdd_count == 0) { + gpio_set_value_cansleep( + ctrl->gpio_conf->gpio_num_info->gpio_num[power_setting->seq_val], + (int) power_setting->config_val ); + } + iovdd_count++; + } else { + gpio_set_value_cansleep( + ctrl->gpio_conf->gpio_num_info->gpio_num[power_setting->seq_val], + (int) power_setting->config_val); + } + #else gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [power_setting->seq_val], (int) power_setting->config_val); + #endif /* (MULTI_CAMERA_POWER_ON) */ break; case SENSOR_VREG: if (power_setting->seq_val == INVALID_VREG) @@ -1588,9 +1611,25 @@ int msm_camera_power_up(struct msm_camera_power_ctrl_t *ctrl, if (!ctrl->gpio_conf->gpio_num_info->valid [power_setting->seq_val]) continue; + #if defined (MULTI_CAMERA_POWER_ON) + if (power_setting->seq_val == SENSOR_GPIO_VIO) { + iovdd_count --; + if (iovdd_count == 0) { + gpio_set_value_cansleep( + ctrl->gpio_conf->gpio_num_info->gpio_num[power_setting->seq_val], + GPIOF_OUT_INIT_LOW ); + } + CDBG("[%s][Arima] 2.Set common gpio. Loop %d\n", __func__, iovdd_count); + } else { + gpio_set_value_cansleep( + ctrl->gpio_conf->gpio_num_info->gpio_num + [power_setting->seq_val], GPIOF_OUT_INIT_LOW); + } + #else gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [power_setting->seq_val], GPIOF_OUT_INIT_LOW); + #endif /* (MULTI_CAMERA_POWER_ON) */ break; case SENSOR_VREG: if (power_setting->seq_val < ctrl->num_vreg) @@ -1715,10 +1754,26 @@ int msm_camera_power_down(struct msm_camera_power_ctrl_t *ctrl, if (!ctrl->gpio_conf->gpio_num_info->valid [pd->seq_val]) continue; + #if defined (MULTI_CAMERA_POWER_ON) + if (pd->seq_val == SENSOR_GPIO_VIO) { + iovdd_count --; + if (iovdd_count == 0) { + gpio_set_value_cansleep( + ctrl->gpio_conf->gpio_num_info->gpio_num[pd->seq_val], + (int) pd->config_val ); + } + CDBG("[%s][Arima] 3.Set common gpio. Loop %d\n", __func__, iovdd_count); + } else { + gpio_set_value_cansleep( + ctrl->gpio_conf->gpio_num_info->gpio_num[pd->seq_val], + (int) pd->config_val ); + } + #else gpio_set_value_cansleep( ctrl->gpio_conf->gpio_num_info->gpio_num [pd->seq_val], (int) pd->config_val); + #endif /* (MULTI_CAMERA_POWER_ON) */ break; case SENSOR_VREG: if (pd->seq_val == INVALID_VREG) -- GitLab From 9025f7a8dea1a4261c3f176c77645bf5d635cdcb Mon Sep 17 00:00:00 2001 From: shermanwei Date: Thu, 5 Sep 2019 11:27:27 +0800 Subject: [PATCH 30/96] Fix sensitivity of Proximity sensor Add proper nodes for the sensors so that the sensor can perform corrssponding actions. This also fixes the issue of screen never turning on sometimes. Reference QC article: KBA-180725024109 Issue: FP3-A11#230 Change-Id: I445c5026369fad21c26a56833110c190d64822d3 (cherry picked from commit 32b311163e8954d8f7d738bfb45a02c4d01f91b9) (cherry picked from commit 001d6a879807d1d231fc1ed16c1a9a1d28e13b18) --- net/ipc_router/ipc_router_core.c | 4 ++++ 1 file changed, 4 insertions(+) mode change 100644 => 100755 net/ipc_router/ipc_router_core.c diff --git a/net/ipc_router/ipc_router_core.c b/net/ipc_router/ipc_router_core.c old mode 100644 new mode 100755 index beca506bdae0..f68817ec0a4b --- a/net/ipc_router/ipc_router_core.c +++ b/net/ipc_router/ipc_router_core.c @@ -239,6 +239,10 @@ static int is_sensor_port(struct msm_ipc_router_remote_port *rport) if (rport && rport->server) { svcid = rport->server->name.service; + /* hold wakelock for thresh(proximity) algo sensor and + * OEM1(e.g: pick up gesture sensor) */ + if (svcid == 277 || svcid == 287) + return false; if (svcid == 400 || (svcid >= 256 && svcid <= 320)) return true; } -- GitLab From 46125373802e32ea78e1c258719a29cc17d1b669 Mon Sep 17 00:00:00 2001 From: yutingshih Date: Tue, 21 Apr 2020 16:03:55 +0800 Subject: [PATCH 31/96] Modify the LED settings Slightly ramp up the lux values and other adjustments. Issue: FP3-A11#230 Change-Id: I36732b9b701400832a0a4975626cd933e608fc4e --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 22 ++++++++++++++-------- drivers/leds/leds-qti-tri-led.c | 13 +++++++++++++ 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index 6919e741e006..28f2d7f0ca93 100644 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -565,29 +565,35 @@ nvmem = <&pmi632_sdam7>; qcom,pbs-client = <&pmi632_pbs_client3>; qcom,lut-sdam-base = <0x80>; - qcom,lut-patterns = <0 0 0 14 28 42 56 70 84 100 - 100 84 70 56 42 28 14 0 0 0>; + qcom,lut-patterns = <0 0 0 0 0 0 0 0 2 16 30 44 58 72 86 96 100 100 + 100 100 96 86 72 58 44 30 16 2 0 0 0 0 0 0 0 0>; lpg@1 { qcom,lpg-chan-id = <1>; - qcom,ramp-step-ms = <200>; + qcom,ramp-step-ms = <60>; + qcom,ramp-pause-hi-count = <80>; + qcom,ramp-pause-lo-count = <80>; qcom,ramp-low-index = <0>; - qcom,ramp-high-index = <19>; + qcom,ramp-high-index = <35>; qcom,ramp-pattern-repeat; qcom,lpg-sdam-base = <0x48>; }; lpg@2 { qcom,lpg-chan-id = <2>; - qcom,ramp-step-ms = <200>; + qcom,ramp-step-ms = <60>; + qcom,ramp-pause-hi-count = <80>; + qcom,ramp-pause-lo-count = <80>; qcom,ramp-low-index = <0>; - qcom,ramp-high-index = <19>; + qcom,ramp-high-index = <35>; qcom,ramp-pattern-repeat; qcom,lpg-sdam-base = <0x56>; }; lpg@3 { qcom,lpg-chan-id = <3>; - qcom,ramp-step-ms = <200>; + qcom,ramp-step-ms = <60>; + qcom,ramp-pause-hi-count = <80>; + qcom,ramp-pause-lo-count = <80>; qcom,ramp-low-index = <0>; - qcom,ramp-high-index = <19>; + qcom,ramp-high-index = <35>; qcom,ramp-pattern-repeat; qcom,lpg-sdam-base = <0x64>; }; diff --git a/drivers/leds/leds-qti-tri-led.c b/drivers/leds/leds-qti-tri-led.c index c49465532f83..4f3de34d5c68 100644 --- a/drivers/leds/leds-qti-tri-led.c +++ b/drivers/leds/leds-qti-tri-led.c @@ -475,6 +475,19 @@ static int qpnp_tri_led_parse_dt(struct qpnp_tri_led_chip *chip) of_get_property(child_node, "label", NULL) ? : child_node->name; + led->pwm_setting.pre_period_ns = 0; + led->pwm_setting.period_ns = 0; + led->pwm_setting.duty_ns = 0; + + led->led_setting.on_ms = 0; + led->led_setting.off_ms = 0; + led->led_setting.brightness = LED_OFF; + led->led_setting.blink = false; + led->led_setting.breath = false; + + led->blinking = false; + led->breathing = false; + led->pwm_dev = devm_of_pwm_get(chip->dev, child_node, NULL); if (IS_ERR(led->pwm_dev)) { -- GitLab From e285e591b4bd0b5ccabcccf17995c822ef780cfe Mon Sep 17 00:00:00 2001 From: michaellin Date: Tue, 29 Jan 2019 15:08:29 +0800 Subject: [PATCH 32/96] Reassign ESE Enable gpio in case of collision ESE Enable reserved gpio141 is used for RF variant and hence reassign ESE Enable gpio to gpio134 in case of collision. Issue: FP3-A11#230 Change-Id: Ic8d29c92c4fc85ea3d340be7d7cde3d7129c5ae6 (cherry picked from commit 251ef03387a16a754835ce9a48f9e604865f9117) --- arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi | 2 +- arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi index 7ccd074446e0..71c68d5383c8 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-mtp.dtsi @@ -44,7 +44,7 @@ qcom,nq-ven = <&tlmm 16 0x00>; qcom,nq-firm = <&tlmm 62 0x00>; qcom,nq-clkreq = <&pm8953_gpios 2 0x00>; - qcom,nq-esepwr = <&tlmm 141 0x00>; + qcom,nq-esepwr = <&tlmm 134 0x00>; interrupt-parent = <&tlmm>; qcom,clk-src = "BBCLK2"; interrupts = <17 0>; diff --git a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi index 8f55971ecabd..fd31fc920259 100755 --- a/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8953-pinctrl.dtsi @@ -1033,13 +1033,13 @@ /* active state */ mux { /* 16: NFC ENABLE 62: FW DNLD */ - /* 141: ESE Enable */ - pins = "gpio16", "gpio62", "gpio141"; + /* 134: ESE Enable */ + pins = "gpio16", "gpio62", "gpio134"; function = "gpio"; }; config { - pins = "gpio16", "gpio62", "gpio141"; + pins = "gpio16", "gpio62", "gpio134"; drive-strength = <2>; /* 2 MA */ bias-pull-up; }; @@ -1049,13 +1049,13 @@ /* sleep state */ mux { /* 16: NFC ENABLE 62: FW DNLD */ - /* 141: ESE Enable */ - pins = "gpio16", "gpio62", "gpio141"; + /* 134: ESE Enable */ + pins = "gpio16", "gpio62", "gpio134"; function = "gpio"; }; config { - pins = "gpio16", "gpio62", "gpio141"; + pins = "gpio16", "gpio62", "gpio134"; drive-strength = <2>; /* 2 MA */ bias-disable; }; -- GitLab From e3722d8816987612456bef8e6e17e82fa713a3ab Mon Sep 17 00:00:00 2001 From: michaellin Date: Tue, 21 Apr 2020 18:39:32 +0800 Subject: [PATCH 33/96] Introduce firmware download fail recovery mechanism Let NFC IRQ stay enabled even in download mode to avoid NFC from not recovering. Issue: FP3-A11#230 Change-Id: Icbd45691e6b1aeebe2f694c04ae1573837913c3b --- drivers/nfc/nq-nci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) mode change 100644 => 100755 drivers/nfc/nq-nci.c diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c old mode 100644 new mode 100755 index bae7f5b8d5cc..15a6c5355b9f --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -29,6 +29,10 @@ #include #endif +#define PFX "[NFC][NQ]" +/* To avoid from recovery fail and then NFC always in download mode */ +#define NFC_FW_DOWNLOAD_MODE + struct nqx_platform_data { unsigned int irq_gpio; unsigned int en_gpio; @@ -476,7 +480,9 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) * interrupts to avoid spurious notifications to upper * layers. */ + #if !defined( NFC_FW_DOWNLOAD_MODE ) nqx_disable_irq(nqx_dev); + #endif /* ( NFC_FW_DOWNLOAD_MODE ) */ dev_dbg(&nqx_dev->client->dev, "gpio_set_value disable: %s: info: %p\n", __func__, nqx_dev); @@ -533,6 +539,11 @@ int nfc_ioctl_power_states(struct file *filp, unsigned long arg) return -EBUSY; /* Device or resource busy */ } } + #if defined( NFC_FW_DOWNLOAD_MODE ) + /* Enable IRQ while upgrade FW. To avoid from recovery fail and then NFC + * always in download mode */ + nqx_enable_irq( nqx_dev ); + #endif /* ( NFC_FW_DOWNLOAD_MODE ) */ gpio_set_value(nqx_dev->en_gpio, 1); usleep_range(10000, 10100); if (gpio_is_valid(nqx_dev->firm_gpio)) { @@ -1187,8 +1198,12 @@ static int nqx_probe(struct i2c_client *client, if (r) { /* make sure NFCC is not enabled */ gpio_set_value(platform_data->en_gpio, 0); + #if !defined( NFC_FW_DOWNLOAD_MODE ) /* Qualcomm default */ /* We don't think there is hardware switch NFC OFF */ goto err_request_hw_check_failed; + #else + dev_err(&client->dev, "[%s]nfcc_hw_check() error !!\n", __func__ ); + #endif /* ( NFC_FW_DOWNLOAD_MODE ) */ } /* Register reboot notifier here */ -- GitLab From 413721f2d513e729364bc5a32c93020f824dcaa7 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Wed, 22 Apr 2020 15:13:49 +0800 Subject: [PATCH 34/96] Add Fuji & Kayo battery profiles Issue: FP3-A11#230 Change-Id: I23fd580e7abbc4ff8dc7ac87575dcbb5dca5cf56 --- ...ydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi | 1049 +++++++++++++++++ ...rydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi | 1038 ++++++++++++++++ arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi | 4 +- 3 files changed, 2089 insertions(+), 2 deletions(-) create mode 100755 arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi create mode 100755 arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi diff --git a/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi b/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi new file mode 100755 index 000000000000..c3655c0ef105 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi @@ -0,0 +1,1049 @@ +/* Copyright (c) 2018, The Linux Foundation. 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 version 2 and + * only version 2 as published by the Free Software Foundation. + * + * 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. + */ +qcom,batterydata_fuji_3000mah { + /* 3804571_Arima_8901_Fuji_3000mAH_FG_averaged_MasterSlave_Jan22th2019 */ + qcom,max-voltage-uv = <4390000>; + qcom,v-cutoff-uv = <3400000>; + qcom,fg-cc-cv-threshold-mv = <4380>; + + qcom,fcc-max-ua = <2000000>; + qcom,fastchg-current-ma = <2000>; + qcom,chg-term-ua = <100000>; + + qcom,batt-id-kohm = <10>; + qcom,battery-beta = <4100>; + qcom,battery-therm-kohm = <100>; + qcom,battery-type = + "Fuji_3000mAH_FG_averaged_MasterSlave_Jan22th2019"; + qcom,qg-batt-profile-ver = <100>; + + qcom,jeita-fcc-ranges = <0 150 600000 + 151 400 2000000 + 401 450 1500000 + 451 550 1000000 + 551 600 0>; + qcom,jeita-fv-ranges = <0 150 4400000 + 151 400 4400000 + 401 450 4400000 + 451 550 4100000 + 551 600 3300000>; + + /* COOL = 15 DegC, WARM = 45 DegC */ + qcom,jeita-soft-thresholds = <0x44FF 0x2204>; + /* COLD = 0 DegC, HOT = 55 DegC */ + qcom,jeita-hard-thresholds = <0x5675 0x1987>; + + qcom,fcc1-temp-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-data = <2865 2966 3060 3122 3139>; + }; + + qcom,fcc2-temp-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-data = <2964 3062 3085 3043 3073 3084>; + }; + + qcom,pc-temp-v1-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <43284 43531 43756 43842 43863>, + <43035 43269 43533 43627 43647>, + <42788 43017 43288 43406 43431>, + <42545 42778 43048 43178 43209>, + <42307 42546 42811 42943 42981>, + <42074 42313 42575 42706 42747>, + <41845 42081 42342 42469 42511>, + <41622 41854 42110 42233 42274>, + <41406 41630 41881 42000 42041>, + <41204 41411 41654 41770 41809>, + <41011 41204 41429 41542 41580>, + <40801 41011 41212 41319 41355>, + <40550 40819 41007 41100 41134>, + <40289 40612 40807 40887 40921>, + <40063 40394 40602 40682 40712>, + <39865 40195 40395 40484 40510>, + <39698 40019 40206 40294 40315>, + <39558 39864 40038 40115 40132>, + <39432 39730 39880 39943 39960>, + <39303 39606 39725 39775 39791>, + <39169 39484 39573 39617 39628>, + <39039 39364 39419 39446 39459>, + <38920 39243 39268 39205 39244>, + <38809 39118 39104 38925 38987>, + <38706 38995 38900 38754 38801>, + <38609 38886 38687 38657 38686>, + <38521 38792 38545 38574 38589>, + <38447 38703 38445 38490 38487>, + <38383 38606 38368 38410 38392>, + <38327 38500 38306 38331 38306>, + <38279 38414 38255 38252 38230>, + <38236 38348 38214 38183 38160>, + <38195 38294 38182 38127 38101>, + <38155 38248 38148 38074 38045>, + <38115 38208 38113 38025 37991>, + <38070 38172 38076 37979 37937>, + <38019 38140 38037 37930 37877>, + <37980 38104 37995 37880 37810>, + <37979 38053 37936 37818 37735>, + <37989 37979 37842 37732 37651>, + <37954 37885 37727 37624 37556>, + <37853 37750 37609 37504 37443>, + <37727 37596 37477 37366 37307>, + <37570 37437 37322 37204 37147>, + <37405 37295 37175 37057 36996>, + <37275 37197 37079 36975 36913>, + <37228 37152 37054 36955 36894>, + <37187 37128 37032 36940 36880>, + <37145 37096 37015 36923 36865>, + <37083 37054 36984 36882 36824>, + <36912 36900 36821 36673 36613>, + <36504 36491 36441 36265 36205>, + <35936 35949 35916 35716 35662>, + <35181 35220 35209 34971 34929>, + <33991 34089 34155 33851 33829>, + <30000 30000 30000 30000 30000>; + }; + + qcom,pc-temp-v2-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <43865 43810 43785 43700 43675 43665>, + <43445 43386 43420 43374 43403 43411>, + <43061 43012 43087 43074 43142 43164>, + <42715 42699 42792 42806 42895 42924>, + <42400 42432 42528 42566 42661 42693>, + <42116 42193 42275 42331 42430 42462>, + <41856 41988 42029 42097 42198 42230>, + <41623 41789 41786 41867 41968 41999>, + <41426 41533 41519 41640 41739 41772>, + <41256 41231 41242 41417 41512 41547>, + <41083 41027 41055 41200 41291 41325>, + <40887 40937 40957 40990 41076 41108>, + <40674 40843 40851 40786 40867 40894>, + <40418 40575 40624 40587 40663 40690>, + <40052 40115 40304 40393 40464 40490>, + <39703 39807 40049 40214 40273 40298>, + <39484 39642 39853 40060 40089 40112>, + <39316 39494 39659 39905 39915 39934>, + <39146 39312 39445 39713 39757 39769>, + <38969 39122 39229 39495 39604 39604>, + <38801 38939 39031 39277 39409 39409>, + <38645 38757 38848 39052 39154 39173>, + <38500 38588 38674 38846 38924 38957>, + <38379 38430 38503 38682 38751 38779>, + <38282 38292 38345 38540 38606 38627>, + <38200 38194 38221 38416 38483 38503>, + <38126 38119 38122 38305 38376 38396>, + <38060 38053 38050 38204 38281 38299>, + <37997 37990 37995 38111 38195 38209>, + <37934 37932 37946 38024 38116 38126>, + <37873 37874 37900 37951 38038 38051>, + <37814 37818 37859 37886 37961 37982>, + <37757 37761 37815 37830 37889 37918>, + <37698 37702 37770 37782 37823 37860>, + <37639 37642 37721 37740 37760 37795>, + <37579 37580 37669 37699 37692 37701>, + <37519 37515 37611 37658 37622 37590>, + <37460 37451 37548 37613 37546 37491>, + <37397 37386 37478 37553 37467 37405>, + <37332 37321 37398 37482 37384 37323>, + <37263 37258 37299 37394 37300 37242>, + <37188 37195 37188 37281 37202 37148>, + <37104 37132 37077 37156 37078 37026>, + <37008 37062 36981 37012 36935 36888>, + <36897 36973 36906 36861 36810 36769>, + <36753 36865 36836 36801 36780 36742>, + <36665 36812 36803 36782 36767 36730>, + <36551 36742 36771 36769 36750 36716>, + <36416 36637 36719 36736 36721 36684>, + <36223 36466 36610 36679 36634 36594>, + <35963 36186 36375 36502 36349 36303>, + <35623 35770 35979 36106 35895 35839>, + <35148 35191 35403 35552 35295 35244>, + <34444 34358 34580 34813 34488 34441>, + <33312 33033 33293 33745 33316 33316>, + <31012 30090 30748 31936 31165 30645>; + }; + + qcom,pc-temp-z1-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <17054 15240 13662 12757 12408>, + <17124 15229 13698 12768 12438>, + <17016 15219 13668 12726 12417>, + <16914 15183 13617 12701 12397>, + <16838 15155 13583 12668 12382>, + <16744 15143 13558 12638 12370>, + <16640 15093 13528 12609 12359>, + <16529 15012 13482 12590 12352>, + <16427 14931 13442 12580 12348>, + <16342 14856 13422 12574 12346>, + <16264 14788 13406 12572 12345>, + <16170 14704 13400 12569 12346>, + <16019 14604 13414 12569 12347>, + <15850 14481 13431 12570 12349>, + <15738 14362 13422 12573 12352>, + <15657 14330 13401 12574 12355>, + <15581 14346 13398 12577 12358>, + <15496 14373 13416 12581 12363>, + <15420 14400 13430 12589 12368>, + <15369 14430 13439 12596 12373>, + <15329 14464 13455 12602 12378>, + <15295 14511 13473 12609 12383>, + <15264 14559 13503 12615 12389>, + <15235 14602 13523 12621 12394>, + <15225 14639 13527 12629 12400>, + <15259 14663 13531 12640 12409>, + <15299 14691 13544 12651 12418>, + <15307 14724 13572 12661 12427>, + <15298 14758 13586 12672 12435>, + <15297 14796 13584 12682 12444>, + <15325 14832 13582 12692 12454>, + <15372 14866 13587 12702 12463>, + <15403 14897 13616 12713 12472>, + <15419 14941 13638 12726 12481>, + <15435 15005 13645 12741 12490>, + <15466 15037 13651 12757 12499>, + <15533 15047 13666 12768 12508>, + <15611 15059 13689 12775 12517>, + <15713 15086 13712 12783 12525>, + <15815 15129 13745 12797 12534>, + <15877 15157 13778 12814 12544>, + <15962 15156 13793 12827 12553>, + <16018 15159 13807 12840 12562>, + <16054 15244 13834 12856 12571>, + <16139 15219 13861 12870 12581>, + <16155 15207 13872 12888 12593>, + <16128 15182 13833 12892 12600>, + <16123 15232 13881 12902 12605>, + <16064 15224 13854 12918 12610>, + <16159 15224 13885 12928 12621>, + <16206 15263 13908 12947 12632>, + <16240 15262 13928 12953 12645>, + <16304 15324 13949 12982 12663>, + <16264 15364 13995 13019 12688>, + <16264 15364 13995 13019 12688>, + <16264 15364 13995 13019 12688>; + }; + + qcom,pc-temp-z2-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <9350 9754 9949 10368 10349>, + <9479 9908 10066 10325 10322>, + <9559 9989 10154 10384 10464>, + <9616 10006 10169 10359 10507>, + <9660 10015 10160 10338 10448>, + <9687 10030 10125 10312 10406>, + <9695 10019 10096 10277 10379>, + <9698 9989 10087 10254 10355>, + <9700 9988 10091 10245 10335>, + <9700 9993 10097 10241 10323>, + <9699 9995 10102 10249 10325>, + <9700 9986 10105 10264 10316>, + <9712 9970 10090 10274 10298>, + <9728 9962 10066 10285 10271>, + <9739 9951 10067 10291 10260>, + <9746 9935 10080 10269 10272>, + <9748 9920 10092 10244 10286>, + <9730 9905 10101 10251 10287>, + <9701 9875 10113 10278 10301>, + <9681 9840 10131 10302 10317>, + <9655 9822 10159 10343 10330>, + <9630 9813 10191 10378 10342>, + <9617 9809 10233 10329 10330>, + <9607 9828 10258 10225 10299>, + <9604 9858 10240 10187 10291>, + <9606 9862 10214 10182 10339>, + <9607 9842 10211 10192 10409>, + <9605 9825 10202 10281 10482>, + <9593 9853 10196 10410 10548>, + <9580 9988 10211 10450 10534>, + <9575 10068 10236 10463 10429>, + <9569 10061 10257 10460 10363>, + <9553 10046 10276 10423 10353>, + <9505 10042 10293 10391 10352>, + <9460 10041 10308 10400 10381>, + <9448 10041 10319 10429 10460>, + <9448 10044 10324 10456 10531>, + <9447 10049 10328 10483 10597>, + <9421 10058 10333 10510 10636>, + <9375 10076 10351 10539 10644>, + <9330 10095 10369 10563 10643>, + <9274 10114 10376 10558 10608>, + <9238 10135 10380 10536 10508>, + <9214 10156 10366 10535 10521>, + <9259 10180 10386 10536 10557>, + <9240 10062 10415 10512 10526>, + <9254 10173 10397 10455 10497>, + <9279 9874 10392 10437 10496>, + <9290 9778 10398 10442 10527>, + <9293 9745 10432 10482 10608>, + <9286 9862 10424 10564 10552>, + <9238 10014 10422 10498 10451>, + <9256 9882 10280 10429 10345>, + <9197 9773 10194 10309 10327>, + <9197 9773 10194 10309 10327>, + <9197 9773 10194 10309 10327>; + }; + + qcom,pc-temp-z3-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <19799 19569 19396 19351 19342>, + <19912 19746 19493 19399 19368>, + <19966 19815 19586 19441 19391>, + <19983 19811 19632 19464 19415>, + <19985 19772 19643 19476 19423>, + <19980 19735 19646 19481 19427>, + <19971 19703 19645 19484 19429>, + <19953 19677 19638 19484 19428>, + <19929 19656 19629 19474 19421>, + <19904 19637 19622 19459 19409>, + <19879 19613 19614 19447 19401>, + <19855 19584 19603 19437 19392>, + <19832 19555 19583 19429 19384>, + <19811 19527 19565 19424 19376>, + <19797 19502 19554 19418 19371>, + <19788 19486 19545 19407 19369>, + <19778 19477 19534 19397 19367>, + <19759 19468 19520 19394 19363>, + <19734 19452 19507 19392 19356>, + <19712 19435 19500 19392 19352>, + <19692 19424 19494 19394 19354>, + <19675 19418 19494 19397 19356>, + <19660 19414 19497 19400 19356>, + <19647 19456 19499 19403 19354>, + <19637 19525 19503 19401 19351>, + <19629 19538 19508 19385 19344>, + <19622 19532 19509 19374 19339>, + <19614 19525 19505 19375 19359>, + <19605 19550 19502 19379 19396>, + <19596 19670 19499 19394 19406>, + <19586 19740 19497 19431 19405>, + <19574 19731 19496 19445 19403>, + <19563 19717 19495 19440 19396>, + <19552 19703 19494 19431 19385>, + <19539 19688 19496 19423 19378>, + <19523 19671 19498 19413 19371>, + <19505 19648 19497 19408 19369>, + <19488 19627 19493 19406 19371>, + <19457 19610 19490 19404 19373>, + <19409 19596 19488 19402 19373>, + <19364 19591 19485 19401 19371>, + <19319 19593 19484 19398 19367>, + <19308 19595 19482 19395 19360>, + <19312 19583 19473 19395 19361>, + <19289 19511 19455 19391 19362>, + <19288 19392 19434 19372 19348>, + <19287 19411 19424 19366 19342>, + <19283 19309 19418 19359 19339>, + <19281 19283 19366 19356 19334>, + <19281 19281 19345 19353 19329>, + <19281 19311 19408 19343 19338>, + <19288 19382 19391 19345 19344>, + <19284 19387 19369 19346 19352>, + <19293 19386 19360 19355 19342>, + <19293 19386 19360 19355 19342>, + <19293 19386 19360 19355 19342>; + }; + + qcom,pc-temp-z4-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <17587 16958 15547 15139 15017>, + <17976 16963 15776 15093 14962>, + <17856 16883 15807 15147 14959>, + <17670 16658 15582 15132 14987>, + <17371 16377 15400 15029 14926>, + <17004 16165 15259 14955 14873>, + <16727 15984 15149 14898 14833>, + <16521 15829 15064 14854 14802>, + <16352 15706 14994 14820 14782>, + <16206 15607 14932 14796 14767>, + <16076 15526 14876 14782 14755>, + <15991 15453 14840 14772 14747>, + <15948 15394 14819 14761 14740>, + <15916 15360 14805 14747 14732>, + <15878 15335 14797 14737 14722>, + <15812 15316 14791 14732 14711>, + <15741 15300 14784 14728 14699>, + <15679 15285 14769 14720 14691>, + <15628 15271 14754 14705 14684>, + <15613 15258 14746 14699 14680>, + <15616 15248 14740 14697 14679>, + <15621 15240 14739 14696 14680>, + <15628 15229 14743 14759 14721>, + <15635 15172 14751 14896 14839>, + <15641 15093 14811 14935 14887>, + <15651 15073 14906 14927 14882>, + <15665 15073 14932 14916 14872>, + <15674 15071 14939 14897 14836>, + <15678 15038 14941 14868 14777>, + <15680 14913 14928 14830 14746>, + <15677 14839 14904 14778 14728>, + <15671 14839 14881 14751 14717>, + <15668 14839 14855 14743 14709>, + <15665 14837 14830 14739 14705>, + <15662 14828 14808 14740 14706>, + <15662 14818 14790 14743 14712>, + <15662 14807 14776 14747 14721>, + <15653 14796 14764 14750 14737>, + <15602 14787 14762 14754 14748>, + <15521 14779 14776 14760 14747>, + <15466 14774 14789 14764 14743>, + <15431 14773 14783 14761 14737>, + <15379 14772 14770 14749 14728>, + <15284 14765 14766 14746 14727>, + <15126 14773 14749 14739 14724>, + <15091 14844 14714 14701 14695>, + <15083 14814 14704 14690 14684>, + <15073 14915 14690 14674 14662>, + <15060 14935 14729 14654 14644>, + <15049 14929 14743 14656 14648>, + <15047 14898 14697 14703 14670>, + <15089 14864 14750 14712 14672>, + <15142 14893 14793 14714 14664>, + <15193 14919 14820 14707 14678>, + <15193 14919 14820 14707 14678>, + <15193 14919 14820 14707 14678>; + }; + + qcom,pc-temp-z5-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <11358 11494 11908 12557 13389>, + <11833 12183 12842 14487 15070>, + <12405 12614 13565 15212 16202>, + <13059 12845 14214 15154 15974>, + <13839 13016 14733 15844 16391>, + <14725 13243 15142 16503 17010>, + <15596 13561 15530 17246 17748>, + <16428 13923 15943 17791 18190>, + <17232 14315 16465 18116 18220>, + <18038 14676 17422 18276 18181>, + <18865 14865 18877 18272 18221>, + <19674 14984 19625 18249 18128>, + <20431 15072 19727 18334 17870>, + <21130 15054 19828 18929 17679>, + <21810 14893 20358 19394 17847>, + <22506 14672 21207 19043 18615>, + <23103 14352 21538 18592 19519>, + <23615 13980 21561 18936 19805>, + <24007 13586 21664 20345 19853>, + <24079 13189 22550 21969 20033>, + <23879 12900 24359 24356 21912>, + <23551 12671 26666 26933 24174>, + <23128 12532 29984 28811 24236>, + <22573 16009 33223 30302 22786>, + <22055 21616 36917 29852 20806>, + <21614 22839 40896 23931 17498>, + <21164 22782 41274 18905 15329>, + <20626 22748 37726 17548 16139>, + <19994 24693 34208 16813 18506>, + <19350 32731 32197 17946 20729>, + <18718 37419 30660 22928 22860>, + <18080 37241 29522 27156 24796>, + <17492 36724 28389 30069 26670>, + <16942 35950 27991 31898 28277>, + <16419 34643 29482 32339 29267>, + <15905 32897 31269 32587 29981>, + <15355 29571 32211 32574 30108>, + <14748 26352 33439 31949 29477>, + <13625 25160 33934 30921 28421>, + <12198 24457 33717 28597 26596>, + <11393 24278 33374 25720 24194>, + <10921 27010 32613 24473 22458>, + <10794 29096 30844 23817 21101>, + <10850 27893 27612 23152 20368>, + <11132 22763 26589 22273 20057>, + <11208 13720 25644 21579 19840>, + <11175 14905 22757 20915 19343>, + <11126 11694 21938 20443 21124>, + <11126 11332 15067 22031 23038>, + <11136 11316 13648 21640 21325>, + <11203 11811 21336 16010 17501>, + <11383 13311 15695 14689 17028>, + <11284 12864 13476 14307 17977>, + <11138 12491 12651 14501 15692>, + <11138 12491 12651 14501 15692>, + <11138 12491 12651 14501 15692>; + }; + + qcom,pc-temp-z6-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <18743 17091 15593 15023 14880>, + <18832 17074 15694 15021 14873>, + <18667 17018 15717 15055 14880>, + <18442 16858 15615 15051 14899>, + <18182 16642 15523 15006 14876>, + <17900 16469 15442 14972 14854>, + <17667 16323 15372 14945 14837>, + <17477 16198 15314 14920 14821>, + <17311 16093 15265 14896 14807>, + <17163 16004 15224 14877 14794>, + <17028 15920 15186 14864 14785>, + <16900 15837 15158 14853 14777>, + <16781 15757 15140 14844 14769>, + <16675 15682 15125 14836 14761>, + <16585 15617 15114 14828 14754>, + <16505 15585 15104 14820 14748>, + <16434 15572 15094 14813 14743>, + <16368 15564 15082 14807 14737>, + <16311 15560 15073 14802 14731>, + <16274 15557 15071 14800 14728>, + <16252 15557 15069 14801 14729>, + <16234 15561 15069 14804 14732>, + <16218 15568 15075 14834 14752>, + <16204 15580 15086 14895 14802>, + <16195 15595 15118 14912 14821>, + <16195 15605 15163 14904 14818>, + <16200 15611 15177 14894 14813>, + <16204 15619 15181 14886 14809>, + <16206 15631 15183 14880 14805>, + <16209 15650 15178 14876 14800>, + <16213 15665 15171 14875 14794>, + <16218 15672 15165 14872 14788>, + <16222 15677 15156 14868 14781>, + <16226 15679 15150 14864 14776>, + <16231 15679 15146 14862 14775>, + <16239 15678 15144 14861 14776>, + <16249 15673 15143 14861 14778>, + <16254 15669 15144 14863 14787>, + <16253 15670 15145 14866 14794>, + <16249 15674 15157 14871 14794>, + <16257 15680 15169 14875 14794>, + <16286 15693 15172 14875 14791>, + <16316 15704 15173 14872 14786>, + <16342 15708 15173 14873 14787>, + <16325 15691 15169 14872 14788>, + <16317 15673 15152 14851 14771>, + <16313 15670 15145 14844 14764>, + <16314 15661 15139 14835 14754>, + <16312 15666 15131 14827 14744>, + <16314 15671 15133 14830 14745>, + <16332 15687 15154 14849 14762>, + <16363 15720 15177 14859 14770>, + <16400 15752 15199 14867 14775>, + <16456 15793 15224 14878 14780>, + <16456 15793 15224 14878 14780>, + <16456 15793 15224 14878 14780>; + }; + + qcom,pc-temp-y1-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <8808 7810 7119 6408 5842 5630>, + <8786 7775 7119 6399 5837 5635>, + <8736 7762 7115 6384 5832 5636>, + <8678 7760 7110 6366 5827 5636>, + <8629 7765 7105 6351 5820 5634>, + <8607 7767 7104 6346 5814 5631>, + <8601 7778 7101 6343 5808 5626>, + <8591 7794 7099 6340 5801 5619>, + <8582 7787 7102 6338 5795 5615>, + <8573 7757 7116 6335 5790 5611>, + <8570 7745 7124 6331 5785 5608>, + <8624 7765 7127 6328 5779 5606>, + <8727 7788 7126 6326 5774 5605>, + <8752 7789 7127 6327 5770 5604>, + <8709 7780 7131 6333 5768 5603>, + <8675 7786 7134 6341 5767 5603>, + <8674 7825 7137 6350 5771 5603>, + <8678 7854 7137 6359 5774 5605>, + <8683 7852 7147 6363 5774 5607>, + <8693 7848 7161 6366 5773 5609>, + <8706 7850 7165 6372 5774 5612>, + <8744 7872 7164 6387 5778 5614>, + <8799 7893 7165 6399 5784 5617>, + <8812 7904 7178 6400 5791 5621>, + <8806 7914 7197 6400 5800 5626>, + <8795 7914 7204 6407 5807 5630>, + <8773 7885 7208 6428 5812 5636>, + <8743 7863 7210 6443 5819 5641>, + <8735 7872 7220 6445 5827 5646>, + <8759 7886 7233 6445 5834 5652>, + <8772 7888 7234 6446 5843 5659>, + <8759 7882 7226 6449 5852 5665>, + <8766 7881 7224 6454 5862 5672>, + <8792 7916 7232 6468 5871 5679>, + <8813 7964 7241 6486 5880 5686>, + <8815 7988 7255 6492 5888 5692>, + <8814 8004 7277 6497 5894 5697>, + <8836 8004 7284 6502 5901 5702>, + <8866 7958 7264 6515 5912 5708>, + <8906 7919 7248 6530 5925 5714>, + <8961 7936 7272 6538 5941 5722>, + <8999 7955 7306 6561 5956 5731>, + <9030 7948 7304 6572 5971 5741>, + <9138 7971 7313 6570 5991 5752>, + <9293 8063 7376 6564 6002 5762>, + <9280 8096 7390 6587 6025 5773>, + <9284 8110 7390 6636 6033 5780>, + <9320 8108 7371 6593 6049 5787>, + <9330 8116 7400 6614 6059 5790>, + <9393 8172 7426 6617 6073 5796>, + <9703 8314 7410 6624 6079 5798>, + <9758 8346 7470 6622 6098 5814>, + <9705 8401 7565 6635 6133 5835>, + <10044 8597 7580 6686 6162 5853>, + <10044 8597 7580 6686 6162 5853>, + <10044 8597 7580 6686 6162 5853>; + }; + + qcom,pc-temp-y2-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <9675 9851 9914 10743 11138 11081>, + <9669 9878 9974 10737 11099 11049>, + <9666 9917 10046 10731 11053 11013>, + <9667 9967 10118 10726 11008 10976>, + <9670 10024 10176 10721 10968 10946>, + <9677 10089 10208 10716 10940 10925>, + <9780 10167 10219 10712 10918 10911>, + <9972 10248 10230 10708 10901 10901>, + <10034 10326 10320 10707 10889 10894>, + <10038 10403 10526 10711 10878 10888>, + <10042 10429 10594 10717 10875 10888>, + <10180 10418 10528 10741 10888 10901>, + <10405 10407 10470 10772 10910 10922>, + <10410 10441 10537 10793 10939 10952>, + <10025 10548 10688 10814 10981 10998>, + <9694 10633 10768 10844 11028 11051>, + <9679 10703 10805 10909 11082 11129>, + <9679 10742 10840 10969 11141 11206>, + <9679 10736 10890 10994 11214 11272>, + <9677 10717 10932 11012 11286 11322>, + <9675 10674 10922 11016 11287 11314>, + <9674 10440 10844 11003 11197 11231>, + <9672 10221 10781 10994 11134 11160>, + <9670 10009 10759 11001 11138 11131>, + <9669 9764 10742 11020 11147 11115>, + <9668 9717 10681 11032 11159 11129>, + <9667 9704 10412 11038 11174 11163>, + <9667 9696 10242 11039 11192 11197>, + <9666 9690 10281 11029 11245 11226>, + <9666 9685 10329 11015 11312 11253>, + <9665 9681 10171 11007 11347 11291>, + <9664 9676 9906 10994 11376 11370>, + <9664 9673 9790 10983 11380 11454>, + <9663 9671 9739 10978 11359 11538>, + <9663 9669 9708 10974 11332 11581>, + <9662 9668 9690 10971 11303 11512>, + <9662 9666 9679 10963 11266 11359>, + <9661 9665 9674 10949 11229 11276>, + <9661 9664 9670 10923 11193 11241>, + <9660 9663 9668 10883 11153 11227>, + <9659 9662 9666 10838 11111 11226>, + <9658 9661 9665 10778 11067 11210>, + <9656 9661 9664 10708 11026 11160>, + <9655 9660 9662 10622 10943 11138>, + <9654 9659 9662 10228 10911 11078>, + <9653 9658 9660 10125 10831 10967>, + <9653 9657 9659 10114 10830 10950>, + <9653 9657 9659 10273 10823 11000>, + <9652 9656 9658 10052 10816 10977>, + <9651 9655 9658 10003 10819 10980>, + <9650 9653 9657 9927 10781 10944>, + <9650 9652 9656 9774 10694 10866>, + <9649 9650 9654 9711 10638 10811>, + <9648 9648 9651 9680 10579 10795>, + <9648 9648 9651 9680 10579 10795>, + <9648 9648 9651 9680 10579 10795>; + }; + + qcom,pc-temp-y3-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <14144 13709 13581 13347 13296 13282>, + <14059 13689 13577 13349 13297 13282>, + <13977 13665 13573 13351 13298 13283>, + <13900 13641 13566 13353 13299 13284>, + <13833 13622 13559 13355 13301 13285>, + <13778 13611 13551 13357 13302 13286>, + <13735 13607 13542 13359 13304 13287>, + <13700 13604 13531 13360 13306 13289>, + <13663 13576 13516 13360 13306 13290>, + <13615 13504 13494 13359 13305 13292>, + <13577 13472 13473 13357 13305 13293>, + <13559 13471 13452 13353 13308 13293>, + <13546 13471 13439 13349 13311 13294>, + <13545 13467 13441 13347 13311 13297>, + <13547 13457 13444 13346 13310 13301>, + <13549 13448 13443 13345 13308 13302>, + <13548 13440 13428 13347 13305 13301>, + <13545 13432 13411 13349 13303 13300>, + <13545 13423 13398 13348 13304 13298>, + <13546 13414 13385 13342 13306 13294>, + <13548 13407 13375 13337 13305 13291>, + <13543 13401 13365 13331 13300 13288>, + <13530 13397 13359 13326 13296 13285>, + <13524 13394 13357 13323 13294 13283>, + <13527 13393 13355 13320 13293 13282>, + <13532 13396 13344 13318 13292 13282>, + <13542 13405 13313 13315 13291 13281>, + <13563 13412 13299 13313 13290 13281>, + <13584 13417 13311 13314 13292 13281>, + <13601 13422 13330 13315 13293 13281>, + <13619 13428 13342 13315 13294 13282>, + <13646 13438 13352 13315 13294 13282>, + <13681 13451 13363 13316 13293 13283>, + <13714 13471 13379 13316 13292 13285>, + <13744 13493 13393 13317 13291 13287>, + <13776 13513 13404 13318 13291 13286>, + <13808 13534 13413 13320 13291 13282>, + <13840 13557 13426 13322 13291 13280>, + <13880 13581 13444 13324 13290 13280>, + <13935 13607 13463 13327 13290 13279>, + <14003 13634 13478 13327 13291 13280>, + <14085 13664 13495 13326 13292 13280>, + <14183 13700 13511 13327 13294 13280>, + <14296 13732 13519 13329 13294 13281>, + <14422 13708 13517 13321 13291 13281>, + <14457 13757 13563 13325 13298 13285>, + <14503 13801 13590 13331 13304 13289>, + <14521 13839 13628 13342 13308 13295>, + <14713 13901 13658 13344 13315 13298>, + <14935 14010 13687 13353 13319 13301>, + <15231 14155 13722 13360 13315 13297>, + <15654 14400 13776 13376 13318 13298>, + <16286 14815 13917 13404 13325 13302>, + <17253 15517 14206 13445 13334 13308>, + <17253 15517 14206 13445 13334 13308>, + <17253 15517 14206 13445 13334 13308>; + }; + + qcom,pc-temp-y4-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <16880 16884 16843 16611 16506 16469>, + <17007 16924 16871 16627 16508 16469>, + <17093 16973 16919 16648 16510 16469>, + <17145 17019 16971 16670 16510 16470>, + <17172 17053 17011 16687 16510 16470>, + <17179 17065 17025 16693 16510 16470>, + <17149 17056 17023 16691 16508 16471>, + <17093 17046 17018 16687 16507 16471>, + <17094 17059 17011 16687 16508 16472>, + <17226 17114 17000 16690 16513 16475>, + <17333 17176 17007 16695 16518 16478>, + <17293 17260 17141 16712 16521 16484>, + <17204 17323 17260 16733 16525 16490>, + <17135 17210 17179 16744 16533 16494>, + <17035 16910 16999 16752 16549 16497>, + <16948 16809 16929 16761 16566 16503>, + <16928 16821 16912 16775 16589 16517>, + <16919 16831 16893 16785 16611 16536>, + <16904 16817 16852 16772 16634 16565>, + <16871 16780 16801 16731 16654 16596>, + <16843 16747 16757 16685 16645 16593>, + <16842 16716 16720 16629 16574 16546>, + <16845 16694 16678 16583 16515 16502>, + <16850 16683 16617 16562 16493 16476>, + <16865 16674 16566 16549 16480 16460>, + <16884 16670 16562 16543 16480 16460>, + <16890 16668 16600 16542 16487 16466>, + <16893 16668 16626 16539 16496 16474>, + <16898 16673 16612 16531 16505 16485>, + <16914 16680 16593 16518 16515 16497>, + <16931 16687 16601 16515 16520 16510>, + <16940 16695 16621 16515 16523 16524>, + <16946 16700 16638 16515 16526 16533>, + <16955 16703 16653 16523 16529 16540>, + <16968 16707 16669 16538 16531 16542>, + <16987 16715 16686 16553 16526 16525>, + <17010 16726 16701 16572 16512 16494>, + <17038 16740 16707 16587 16503 16478>, + <17075 16758 16709 16598 16496 16471>, + <17132 16779 16708 16605 16494 16470>, + <17202 16805 16693 16606 16500 16476>, + <17280 16832 16672 16605 16509 16481>, + <17371 16860 16659 16599 16511 16480>, + <17453 16867 16656 16576 16509 16478>, + <17499 16793 16648 16557 16478 16450>, + <17354 16787 16668 16568 16493 16466>, + <17325 16805 16690 16584 16507 16478>, + <17230 16828 16716 16599 16525 16487>, + <17314 16853 16750 16641 16543 16505>, + <17418 16879 16774 16676 16557 16515>, + <17579 16937 16765 16673 16529 16487>, + <17841 17050 16758 16641 16533 16488>, + <18286 17288 16811 16646 16553 16508>, + <19246 17929 17050 16675 16600 16553>, + <19246 17929 17050 16675 16600 16553>, + <19246 17929 17050 16675 16600 16553>; + }; + + qcom,pc-temp-y5-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <13349 13500 12008 16323 17921 18586>, + <13013 13211 12999 16372 18068 18170>, + <13045 13460 14163 16440 18117 17710>, + <13320 14144 15309 16514 18105 17265>, + <13715 15164 16245 16584 18071 16894>, + <14107 16431 16784 16639 18053 16652>, + <15410 18600 17088 16695 17996 16513>, + <17536 20511 17255 16740 17870 16387>, + <18076 19525 16766 16676 17290 16217>, + <17054 15658 15346 16346 15850 16011>, + <16481 14123 14892 15892 15277 15729>, + <19499 17492 16061 14980 15396 15204>, + <24621 21017 17812 14144 15517 14821>, + <25408 20858 19909 14373 15176 15053>, + <19266 19889 22106 15510 14330 15539>, + <14011 19657 22597 16782 13917 15522>, + <13930 20662 22429 18272 13747 14811>, + <14318 21567 22355 19738 13690 14376>, + <14451 21644 22492 20874 14676 14378>, + <14374 21674 22713 21825 16938 14452>, + <14244 21685 22878 22222 19000 15411>, + <13814 20618 23037 22357 21260 18677>, + <12837 19295 23301 22430 22271 20342>, + <12176 16786 23920 22466 21851 20137>, + <11864 13808 23986 22484 20993 19645>, + <11690 13424 20980 22476 20018 18847>, + <11718 13473 14954 22064 18767 17527>, + <11839 13487 12836 21697 18243 16702>, + <11898 13409 13272 22531 19014 16373>, + <11842 13290 13839 24064 20139 16235>, + <11799 13214 13911 24209 20558 16295>, + <11882 13197 13854 22855 20583 16587>, + <12081 13234 13947 21466 20365 17253>, + <12245 13308 14112 20300 20058 19153>, + <12343 13345 14250 19299 19990 20733>, + <12425 13241 14355 18875 20397 20809>, + <12521 13059 14473 18615 20909 20171>, + <12618 12937 14722 18543 20846 19319>, + <12669 12781 15271 18808 19408 18313>, + <12666 12638 15669 19097 17814 17411>, + <12672 12597 15667 18859 16901 16533>, + <12691 12631 15351 17917 16234 15888>, + <12643 12878 14521 18213 16069 15695>, + <12660 13276 13856 19221 16226 15964>, + <12919 13897 13862 16001 18127 19756>, + <13276 14032 13814 14924 17294 17122>, + <13415 14407 13713 14773 16651 16358>, + <13462 14550 14038 15725 15949 16993>, + <13362 14718 14211 14276 16288 16750>, + <12923 14999 14569 14561 17215 18436>, + <12369 14407 14848 14966 18423 20471>, + <11893 13109 14633 14660 19769 21365>, + <11228 12058 13726 14484 20580 22907>, + <10382 11039 12284 14642 21348 24120>, + <10382 11039 12284 14642 21348 24120>, + <10382 11039 12284 14642 21348 24120>; + }; + + qcom,pc-temp-y6-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <7174 6488 5990 5336 5123 5070>, + <7088 6443 5977 5337 5122 5071>, + <7004 6400 5963 5338 5122 5072>, + <6926 6360 5948 5338 5122 5072>, + <6857 6324 5931 5338 5121 5073>, + <6801 6295 5913 5338 5121 5074>, + <6753 6272 5893 5335 5121 5074>, + <6715 6251 5872 5331 5120 5075>, + <6695 6217 5847 5327 5120 5076>, + <6680 6173 5819 5324 5120 5077>, + <6668 6156 5812 5323 5120 5078>, + <6655 6172 5831 5323 5122 5080>, + <6635 6187 5849 5323 5125 5082>, + <6610 6157 5830 5323 5128 5085>, + <6553 6076 5788 5324 5130 5088>, + <6504 6045 5764 5326 5134 5091>, + <6492 6044 5753 5332 5138 5095>, + <6487 6042 5741 5337 5143 5100>, + <6483 6035 5724 5333 5150 5106>, + <6479 6023 5705 5318 5157 5112>, + <6476 6013 5690 5302 5154 5110>, + <6474 6004 5678 5283 5130 5094>, + <6471 5997 5668 5269 5111 5079>, + <6471 5991 5658 5264 5104 5071>, + <6481 5986 5652 5262 5100 5066>, + <6497 5988 5652 5262 5100 5066>, + <6513 6004 5658 5264 5102 5068>, + <6530 6022 5667 5266 5105 5070>, + <6549 6037 5688 5268 5110 5074>, + <6571 6054 5714 5271 5115 5078>, + <6596 6076 5739 5274 5118 5083>, + <6624 6104 5768 5281 5120 5088>, + <6656 6132 5800 5289 5122 5093>, + <6689 6159 5834 5300 5123 5097>, + <6723 6188 5870 5315 5124 5099>, + <6759 6220 5907 5331 5124 5093>, + <6795 6256 5946 5351 5121 5083>, + <6833 6291 5985 5373 5121 5078>, + <6885 6324 6023 5395 5121 5076>, + <6968 6358 6057 5419 5121 5076>, + <7077 6396 6083 5441 5126 5079>, + <7209 6437 6107 5463 5133 5082>, + <7380 6484 6136 5487 5140 5084>, + <7573 6535 6166 5510 5144 5084>, + <7769 6532 6182 5515 5136 5078>, + <7828 6592 6243 5539 5150 5087>, + <7890 6644 6283 5566 5161 5094>, + <7929 6694 6329 5597 5173 5102>, + <8177 6776 6372 5629 5187 5111>, + <8470 6929 6419 5671 5197 5116>, + <8868 7149 6460 5696 5190 5106>, + <9428 7492 6523 5720 5201 5109>, + <10244 8043 6746 5788 5225 5121>, + <11535 8996 7213 5886 5260 5142>, + <11535 8996 7213 5886 5260 5142>, + <11535 8996 7213 5886 5260 5142>; + }; + +}; diff --git a/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi b/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi new file mode 100755 index 000000000000..ce1d8873e8ef --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi @@ -0,0 +1,1038 @@ + +qcom,4184448_Arima_8902EU_3000mAh { + qcom,max-voltage-uv = <4390000>; + qcom,v-cutoff-uv = <3400000>; + qcom,fg-cc-cv-threshold-mv = <4380>; + qcom,fcc-max-ua = <2700000>; + qcom,fastchg-current-ma = <2700>; + qcom,chg-term-ua = <100000>; + qcom,batt-id-kohm = <50>; + qcom,battery-beta = <4100>; + qcom,battery-therm-kohm = <100>; + qcom,battery-type = "Kayo_3000mAh_FG_averaged_MasterSlave_Nov4th2019"; + qcom,qg-batt-profile-ver = <100>; + + qcom,jeita-fcc-ranges = <0 200 600000 + 201 400 2700000 + 401 450 1500000 + 451 550 1000000 + 551 600 0>; + qcom,jeita-fv-ranges = <0 200 4400000 + 201 400 4400000 + 401 450 4400000 + 451 550 4100000 + 551 600 3300000>; + + /* COOL = 20 DegC, WARM = 45 DegC */ + qcom,jeita-soft-thresholds = <0x3EBC 0x2204>; + /* COLD = 0 DegC, HOT = 55 DegC */ + qcom,jeita-hard-thresholds = <0x5675 0x1987>; + + qcom,step-chg-ranges = <3500000 4200000 2700000 + 4200001 4400000 1500000>; + + qcom,fcc1-temp-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-data = <2916 2987 3056 3077 3086>; + }; + + qcom,fcc2-temp-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-data = <3049 3044 3049 3058 3057 3057>; + }; + + qcom,pc-temp-v1-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <43505 43700 43831 43863 43874>, + <43223 43436 43575 43604 43615>, + <42972 43181 43325 43357 43374>, + <42740 42936 43082 43121 43135>, + <42513 42699 42840 42885 42899>, + <42290 42465 42600 42648 42664>, + <42072 42233 42363 42413 42432>, + <41858 42006 42129 42179 42200>, + <41647 41788 41899 41947 41970>, + <41449 41575 41673 41719 41742>, + <41275 41375 41449 41492 41515>, + <41102 41200 41240 41272 41292>, + <40890 41023 41056 41058 41076>, + <40629 40803 40869 40853 40867>, + <40376 40537 40638 40648 40663>, + <40152 40296 40381 40446 40464>, + <39950 40096 40175 40254 40274>, + <39795 39922 40019 40078 40095>, + <39678 39783 39875 39911 39925>, + <39570 39672 39732 39752 39761>, + <39450 39550 39589 39601 39607>, + <39330 39403 39402 39421 39432>, + <39209 39239 39142 39161 39196>, + <39089 39046 38910 38917 38962>, + <38970 38812 38757 38775 38807>, + <38852 38639 38636 38670 38688>, + <38735 38538 38540 38571 38578>, + <38629 38463 38464 38475 38471>, + <38529 38404 38394 38385 38374>, + <38442 38358 38325 38300 38288>, + <38382 38316 38262 38221 38211>, + <38336 38275 38203 38152 38140>, + <38298 38238 38150 38094 38075>, + <38263 38204 38102 38040 38015>, + <38232 38174 38062 37995 37962>, + <38200 38141 38025 37953 37911>, + <38170 38109 37989 37905 37853>, + <38133 38072 37953 37854 37789>, + <38079 38016 37902 37791 37717>, + <38002 37926 37815 37710 37637>, + <37909 37822 37708 37612 37545>, + <37785 37705 37596 37502 37437>, + <37643 37570 37468 37372 37309>, + <37484 37410 37312 37219 37153>, + <37344 37263 37166 37074 37009>, + <37241 37162 37070 36982 36924>, + <37211 37136 37044 36961 36902>, + <37186 37117 37031 36946 36887>, + <37160 37097 37013 36929 36872>, + <37119 37062 36976 36885 36821>, + <36940 36869 36767 36648 36564>, + <36508 36448 36348 36223 36135>, + <35949 35887 35785 35659 35574>, + <35193 35123 35019 34892 34806>, + <34002 33937 33832 33710 33623>, + <30000 30000 30000 30000 30000>; + }; + + qcom,pc-temp-v2-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <43915 43870 43850 43820 43770 43750>, + <43535 43503 43526 43515 43483 43471>, + <43192 43171 43226 43231 43212 43205>, + <42893 42880 42955 42969 42957 42954>, + <42631 42624 42711 42728 42719 42717>, + <42381 42377 42473 42491 42484 42483>, + <42137 42128 42235 42256 42250 42250>, + <41898 41886 42002 42023 42018 42018>, + <41638 41652 41774 41795 41789 41789>, + <41360 41423 41550 41569 41563 41564>, + <41149 41218 41333 41347 41340 41341>, + <41029 41055 41126 41127 41123 41123>, + <40908 40891 40923 40915 40910 40909>, + <40654 40662 40723 40720 40707 40705>, + <40246 40370 40525 40536 40508 40506>, + <39909 40095 40311 40337 40316 40315>, + <39663 39845 40066 40107 40125 40128>, + <39457 39615 39829 39895 39943 39949>, + <39287 39422 39645 39742 39778 39783>, + <39141 39249 39486 39614 39622 39623>, + <38988 39077 39308 39444 39440 39439>, + <38821 38900 39097 39205 39217 39219>, + <38660 38734 38898 38976 39002 39007>, + <38512 38588 38738 38797 38820 38826>, + <38375 38456 38599 38642 38658 38665>, + <38270 38332 38474 38513 38526 38532>, + <38188 38210 38363 38405 38418 38423>, + <38118 38110 38263 38308 38321 38325>, + <38055 38039 38174 38217 38232 38234>, + <37999 37982 38093 38134 38149 38150>, + <37947 37935 38016 38061 38075 38074>, + <37899 37897 37941 37993 38005 38002>, + <37853 37861 37879 37930 37940 37936>, + <37805 37827 37835 37869 37884 37880>, + <37757 37793 37798 37812 37826 37821>, + <37705 37751 37759 37755 37749 37733>, + <37651 37702 37720 37698 37652 37610>, + <37590 37647 37676 37636 37559 37500>, + <37518 37583 37622 37565 37474 37411>, + <37439 37509 37558 37488 37392 37328>, + <37359 37421 37477 37410 37316 37250>, + <37274 37316 37371 37325 37237 37170>, + <37195 37197 37249 37215 37129 37062>, + <37117 37071 37108 37079 36992 36926>, + <37035 36961 36966 36930 36852 36793>, + <36948 36867 36890 36881 36816 36763>, + <36898 36819 36867 36867 36808 36752>, + <36843 36772 36841 36853 36793 36736>, + <36764 36701 36805 36823 36765 36710>, + <36632 36595 36726 36763 36696 36625>, + <36401 36395 36513 36551 36435 36335>, + <36034 36017 36066 36101 35970 35860>, + <35477 35437 35421 35504 35356 35242>, + <34667 34604 34564 34707 34524 34396>, + <33357 33266 33270 33533 33299 33148>, + <29584 29579 29543 29540 29552 29553>; + }; + + qcom,pc-temp-z1-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <14599 13422 12448 12029 11916>, + <14539 13426 12442 12038 11932>, + <14504 13419 12430 12034 11931>, + <14480 13395 12421 12028 11929>, + <14463 13354 12410 12025 11928>, + <14447 13327 12396 12022 11929>, + <14438 13311 12386 12020 11931>, + <14441 13299 12379 12020 11932>, + <14453 13289 12375 12021 11933>, + <14459 13281 12375 12022 11934>, + <14440 13277 12379 12022 11935>, + <14406 13281 12381 12022 11936>, + <14374 13285 12383 12024 11938>, + <14335 13275 12384 12027 11941>, + <14301 13247 12376 12027 11943>, + <14274 13229 12357 12027 11944>, + <14252 13221 12352 12027 11946>, + <14250 13215 12360 12029 11948>, + <14266 13222 12371 12033 11951>, + <14280 13248 12379 12036 11953>, + <14289 13268 12386 12039 11956>, + <14303 13281 12392 12041 11958>, + <14310 13291 12397 12042 11960>, + <14326 13292 12401 12044 11961>, + <14348 13290 12406 12047 11964>, + <14369 13290 12412 12053 11968>, + <14403 13309 12418 12058 11972>, + <14418 13335 12424 12062 11976>, + <14390 13338 12430 12067 11981>, + <14356 13331 12437 12072 11985>, + <14352 13331 12443 12077 11989>, + <14358 13341 12450 12082 11992>, + <14367 13353 12456 12086 11996>, + <14380 13362 12463 12090 12000>, + <14397 13370 12471 12095 12003>, + <14416 13375 12480 12099 12006>, + <14441 13382 12488 12103 12009>, + <14462 13391 12496 12106 12011>, + <14468 13404 12504 12109 12013>, + <14469 13424 12511 12113 12016>, + <14474 13437 12519 12117 12019>, + <14490 13441 12525 12121 12022>, + <14495 13445 12530 12125 12025>, + <14477 13454 12538 12128 12028>, + <14505 13478 12547 12133 12032>, + <14495 13462 12558 12136 12033>, + <14465 13457 12554 12138 12034>, + <14488 13470 12557 12139 12036>, + <14524 13460 12560 12141 12037>, + <14513 13470 12566 12144 12040>, + <14515 13503 12576 12150 12046>, + <14537 13510 12589 12161 12053>, + <14588 13546 12611 12175 12068>, + <14625 13621 12652 12200 12088>, + <14625 13621 12652 12200 12088>, + <14625 13621 12652 12200 12088>; + }; + + qcom,pc-temp-z2-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <9712 9885 10112 10225 10274>, + <9792 9893 10141 10307 10271>, + <9825 9895 10133 10369 10364>, + <9845 9888 10112 10341 10395>, + <9860 9865 10090 10310 10403>, + <9873 9846 10063 10269 10370>, + <9881 9834 10046 10241 10329>, + <9879 9826 10039 10243 10320>, + <9870 9826 10036 10252 10316>, + <9860 9826 10044 10264 10310>, + <9853 9827 10063 10282 10288>, + <9843 9840 10079 10296 10267>, + <9825 9856 10092 10291 10258>, + <9789 9861 10105 10275 10255>, + <9767 9862 10122 10264 10264>, + <9768 9865 10140 10241 10282>, + <9770 9879 10151 10233 10304>, + <9776 9901 10158 10243 10333>, + <9796 9923 10164 10256 10364>, + <9810 9949 10177 10268 10383>, + <9805 9965 10195 10282 10398>, + <9793 9972 10203 10305 10403>, + <9785 9976 10206 10367 10381>, + <9781 9978 10206 10419 10355>, + <9779 9979 10189 10387 10375>, + <9781 9981 10163 10306 10447>, + <9788 9986 10160 10287 10494>, + <9795 9992 10174 10329 10528>, + <9802 9992 10187 10361 10545>, + <9807 9989 10205 10357 10449>, + <9812 9987 10223 10347 10264>, + <9815 9991 10222 10333 10218>, + <9819 9997 10208 10311 10224>, + <9824 10003 10201 10300 10234>, + <9830 10008 10205 10325 10274>, + <9838 10014 10212 10371 10343>, + <9852 10020 10217 10413 10412>, + <9867 10027 10226 10458 10494>, + <9881 10036 10238 10490 10530>, + <9895 10047 10268 10511 10526>, + <9909 10057 10292 10523 10518>, + <9922 10062 10289 10521 10514>, + <9942 10068 10281 10514 10512>, + <9986 10083 10287 10466 10501>, + <10168 10194 10324 10440 10492>, + <10204 10275 10381 10463 10512>, + <10117 10323 10371 10461 10519>, + <10078 10427 10370 10454 10521>, + <10040 10550 10407 10447 10559>, + <10045 10586 10407 10549 10754>, + <10031 10491 10568 10539 10410>, + <10023 10462 10575 10439 10280>, + <9876 10362 10543 10309 10300>, + <9730 10231 10462 10272 10258>, + <9730 10231 10462 10272 10258>, + <9730 10231 10462 10272 10258>; + }; + + qcom,pc-temp-z3-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <19803 19568 19401 19348 19348>, + <20075 19716 19528 19411 19369>, + <20081 19811 19562 19454 19411>, + <20062 19834 19578 19464 19433>, + <20034 19844 19582 19468 19440>, + <19966 19847 19584 19469 19440>, + <19907 19848 19584 19470 19440>, + <19901 19848 19574 19463 19434>, + <19900 19843 19559 19448 19417>, + <19900 19825 19547 19436 19406>, + <19899 19804 19534 19427 19401>, + <19898 19774 19526 19420 19396>, + <19910 19745 19516 19414 19385>, + <19966 19736 19507 19404 19372>, + <20004 19733 19504 19397 19367>, + <19994 19728 19503 19385 19365>, + <19971 19712 19499 19378 19363>, + <19943 19687 19487 19377 19355>, + <19899 19665 19475 19375 19344>, + <19869 19642 19470 19374 19342>, + <19877 19632 19466 19372 19342>, + <19901 19647 19469 19372 19343>, + <19923 19671 19495 19388 19349>, + <19942 19689 19514 19404 19356>, + <19958 19707 19506 19392 19349>, + <19971 19715 19491 19363 19328>, + <19982 19714 19480 19354 19324>, + <19987 19712 19471 19361 19367>, + <19987 19708 19467 19371 19406>, + <19986 19700 19472 19393 19402>, + <19981 19693 19482 19420 19389>, + <19964 19687 19491 19424 19380>, + <19944 19681 19501 19417 19375>, + <19927 19674 19505 19408 19370>, + <19909 19667 19502 19400 19364>, + <19887 19661 19496 19393 19359>, + <19857 19654 19490 19391 19359>, + <19833 19648 19482 19390 19361>, + <19823 19645 19476 19388 19361>, + <19817 19642 19472 19384 19360>, + <19809 19639 19469 19380 19357>, + <19799 19633 19467 19379 19354>, + <19782 19623 19464 19379 19350>, + <19746 19608 19456 19370 19351>, + <19539 19554 19438 19361 19350>, + <19448 19517 19424 19359 19336>, + <19360 19487 19421 19353 19336>, + <19338 19415 19383 19350 19334>, + <19334 19359 19380 19350 19322>, + <19331 19356 19379 19342 19311>, + <19336 19407 19355 19344 19349>, + <19363 19368 19347 19351 19359>, + <19378 19358 19345 19361 19341>, + <19370 19355 19344 19360 19341>, + <19370 19355 19344 19360 19341>, + <19370 19355 19344 19360 19341>; + }; + + qcom,pc-temp-z4-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <17301 16140 15222 15043 14943>, + <17308 15962 15418 15009 14905>, + <17122 15786 15328 15050 14950>, + <16727 15606 15162 14976 14903>, + <16433 15424 15062 14917 14859>, + <16251 15281 14992 14877 14826>, + <16097 15174 14938 14845 14801>, + <15952 15090 14895 14822 14787>, + <15818 15031 14862 14805 14779>, + <15698 14987 14843 14793 14770>, + <15592 14949 14829 14783 14761>, + <15496 14907 14817 14775 14753>, + <15401 14876 14803 14767 14749>, + <15307 14870 14793 14758 14746>, + <15235 14869 14788 14757 14740>, + <15190 14866 14784 14753 14727>, + <15156 14857 14776 14747 14716>, + <15122 14842 14753 14733 14710>, + <15093 14830 14734 14716 14706>, + <15061 14817 14728 14709 14701>, + <15019 14806 14725 14705 14695>, + <14971 14793 14734 14708 14694>, + <14933 14784 14809 14785 14760>, + <14900 14807 14876 14871 14845>, + <14879 14900 14900 14891 14870>, + <14875 14951 14915 14901 14882>, + <14873 14946 14914 14901 14881>, + <14874 14934 14897 14876 14817>, + <14882 14919 14874 14840 14752>, + <14892 14896 14848 14796 14738>, + <14893 14874 14819 14748 14730>, + <14887 14854 14793 14729 14721>, + <14880 14837 14768 14720 14708>, + <14873 14820 14753 14716 14702>, + <14865 14805 14745 14714 14702>, + <14862 14792 14740 14713 14703>, + <14861 14779 14737 14715 14707>, + <14860 14769 14734 14723 14723>, + <14851 14768 14734 14731 14732>, + <14832 14769 14745 14740 14734>, + <14825 14770 14755 14747 14735>, + <14824 14765 14748 14740 14731>, + <14823 14760 14735 14728 14721>, + <14824 14761 14737 14735 14723>, + <14909 14753 14731 14734 14720>, + <14962 14738 14704 14705 14702>, + <15055 14759 14693 14694 14688>, + <15069 14828 14716 14674 14667>, + <15067 14881 14704 14652 14654>, + <15059 14879 14702 14660 14665>, + <15048 14832 14755 14694 14659>, + <15060 14897 14775 14692 14655>, + <15071 14921 14782 14684 14675>, + <15107 14937 14788 14688 14676>, + <15107 14937 14788 14688 14676>, + <15107 14937 14788 14688 14676>; + }; + + qcom,pc-temp-z5-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <11454 11745 12182 12555 13430>, + <12243 12652 13896 14662 14641>, + <12436 13367 14441 15536 15665>, + <12532 13830 14827 15834 16844>, + <12552 14152 15222 16091 17560>, + <12527 14535 15609 16368 17875>, + <12502 15138 15928 16601 18050>, + <12551 15743 16212 16735 17898>, + <12726 16087 16403 16725 17371>, + <12887 16332 16498 16662 17155>, + <12979 16550 16698 16583 17268>, + <13082 16850 16825 16576 17355>, + <13409 17177 17092 16656 16992>, + <14282 17631 17333 16659 16294>, + <14830 18572 17534 16467 16225>, + <14822 19041 18085 15934 16905>, + <14790 18616 18533 15813 17373>, + <14713 18031 18902 16522 17104>, + <14449 17791 19349 17525 16697>, + <14245 17646 19899 18215 16853>, + <14598 17636 20709 18771 17988>, + <15691 20478 23295 19826 18918>, + <17030 25517 32932 23676 19820>, + <18860 30303 39368 27018 20550>, + <21143 35691 34703 24339 19129>, + <23928 38044 26187 17537 15121>, + <27393 36280 21987 15112 13807>, + <30042 33236 19473 14804 16059>, + <32020 30881 18529 14686 18244>, + <33389 28692 18785 16275 18450>, + <33081 27358 19394 19654 18492>, + <30672 26749 20802 21861 18808>, + <28094 26332 24167 23393 20141>, + <26285 26063 26973 24608 21754>, + <24607 25796 29058 25724 23548>, + <22853 25708 30393 26520 25129>, + <20734 25757 30186 26653 25308>, + <19445 25839 29114 26586 25032>, + <19728 26174 27935 26310 24544>, + <20483 27216 26468 23530 22587>, + <20945 27813 25238 20623 20253>, + <21181 26835 24812 20503 19350>, + <21204 25242 24404 20657 18824>, + <20042 23391 22263 18651 18178>, + <15624 21181 21039 17430 17655>, + <13453 19868 21195 18547 16954>, + <11648 17113 21109 18133 17459>, + <11421 13549 15913 18875 18995>, + <11379 12104 15838 21530 18855>, + <11375 12108 15893 19283 16193>, + <11506 13512 13714 15340 18602>, + <11658 12181 12915 15355 19788>, + <11612 11862 12663 15997 15501>, + <11332 11678 12471 15399 15001>, + <11332 11678 12471 15399 15001>, + <11332 11678 12471 15399 15001>; + }; + + qcom,pc-temp-z6-lut { + qcom,lut-col-legend = <0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200>, + <9000 8800 8600 8400 8200>, + <8000 7800 7600 7400 7200>, + <7000 6800 6600 6400 6200>, + <6000 5800 5600 5400 5200>, + <5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200>, + <3000 2800 2600 2400 2200>, + <2000 1800 1600 1400 1200>, + <1000 900 800 700 600>, + <500 400 300 200 100>, + <0>; + qcom,lut-data = <16973 15807 15018 14827 14765>, + <17065 15779 15164 14847 14763>, + <16980 15735 15135 14883 14799>, + <16753 15671 15074 14859 14791>, + <16567 15579 15033 14838 14782>, + <16430 15503 15001 14823 14772>, + <16316 15449 14974 14808 14760>, + <16229 15404 14948 14793 14748>, + <16160 15366 14926 14779 14736>, + <16098 15334 14911 14767 14727>, + <16041 15303 14899 14759 14720>, + <15989 15268 14889 14751 14714>, + <15949 15238 14879 14743 14707>, + <15916 15223 14869 14736 14699>, + <15884 15215 14863 14729 14692>, + <15850 15206 14857 14722 14686>, + <15816 15191 14849 14715 14680>, + <15783 15173 14834 14707 14673>, + <15748 15158 14822 14701 14666>, + <15725 15144 14818 14697 14663>, + <15719 15138 14816 14695 14660>, + <15716 15143 14822 14696 14660>, + <15716 15153 14871 14740 14695>, + <15717 15177 14908 14785 14735>, + <15720 15227 14913 14785 14738>, + <15724 15253 14914 14778 14736>, + <15733 15252 14911 14772 14734>, + <15741 15248 14900 14765 14730>, + <15748 15243 14889 14758 14724>, + <15754 15231 14882 14752 14717>, + <15753 15219 14876 14746 14708>, + <15745 15210 14870 14740 14699>, + <15735 15201 14866 14733 14692>, + <15727 15194 14862 14727 14686>, + <15719 15186 14858 14722 14683>, + <15710 15181 14855 14718 14680>, + <15700 15176 14851 14718 14682>, + <15693 15173 14847 14721 14689>, + <15690 15173 14846 14724 14694>, + <15687 15178 14850 14725 14694>, + <15687 15181 14854 14727 14693>, + <15688 15180 14851 14725 14690>, + <15688 15179 14846 14720 14685>, + <15677 15176 14844 14719 14686>, + <15623 15154 14835 14714 14685>, + <15600 15133 14818 14701 14671>, + <15596 15128 14812 14694 14664>, + <15593 15123 14803 14684 14654>, + <15591 15118 14797 14674 14642>, + <15592 15120 14796 14674 14642>, + <15601 15133 14809 14690 14660>, + <15634 15150 14818 14696 14667>, + <15666 15168 14825 14701 14669>, + <15707 15193 14837 14707 14674>, + <15707 15193 14837 14707 14674>, + <15707 15193 14837 14707 14674>; + }; + + qcom,pc-temp-y1-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <7552 6810 6241 5686 5442 5364>, + <7545 6802 6232 5681 5439 5365>, + <7543 6796 6224 5677 5437 5366>, + <7546 6794 6215 5672 5434 5367>, + <7553 6793 6208 5668 5432 5367>, + <7561 6793 6202 5664 5430 5367>, + <7572 6804 6199 5660 5429 5367>, + <7581 6819 6195 5656 5427 5366>, + <7576 6820 6192 5654 5427 5366>, + <7550 6812 6189 5652 5426 5366>, + <7540 6808 6187 5649 5425 5367>, + <7553 6811 6186 5648 5425 5367>, + <7568 6816 6186 5646 5424 5367>, + <7570 6816 6186 5644 5424 5368>, + <7562 6813 6184 5642 5424 5370>, + <7564 6815 6183 5642 5425 5371>, + <7576 6837 6188 5650 5426 5372>, + <7587 6859 6195 5657 5427 5373>, + <7588 6854 6198 5656 5427 5373>, + <7579 6834 6203 5655 5428 5373>, + <7572 6826 6206 5655 5429 5374>, + <7556 6818 6208 5656 5431 5375>, + <7544 6814 6209 5658 5432 5375>, + <7553 6824 6207 5662 5434 5377>, + <7570 6842 6203 5666 5435 5380>, + <7573 6846 6202 5670 5437 5381>, + <7567 6832 6209 5674 5440 5383>, + <7559 6821 6217 5679 5443 5384>, + <7555 6821 6225 5684 5445 5386>, + <7555 6822 6231 5690 5448 5388>, + <7553 6823 6235 5695 5451 5390>, + <7541 6824 6242 5700 5455 5393>, + <7532 6824 6249 5706 5458 5396>, + <7541 6826 6256 5712 5461 5399>, + <7554 6829 6262 5718 5464 5401>, + <7555 6829 6265 5725 5467 5403>, + <7551 6826 6262 5734 5471 5405>, + <7546 6825 6258 5738 5474 5408>, + <7535 6832 6263 5739 5475 5411>, + <7526 6841 6270 5740 5476 5414>, + <7539 6844 6274 5742 5479 5415>, + <7576 6860 6278 5746 5482 5415>, + <7552 6858 6295 5752 5483 5416>, + <7527 6841 6309 5758 5486 5418>, + <7601 6836 6293 5763 5490 5421>, + <7546 6867 6308 5765 5492 5421>, + <7555 6871 6310 5772 5494 5424>, + <7582 6861 6320 5779 5494 5424>, + <7584 6849 6325 5788 5497 5425>, + <7612 6861 6321 5791 5498 5425>, + <7599 6858 6326 5796 5500 5427>, + <7691 6876 6346 5806 5508 5435>, + <7678 6902 6371 5830 5519 5444>, + <7757 6955 6381 5870 5536 5456>, + <7757 6955 6381 5870 5536 5456>, + <7757 6955 6381 5870 5536 5456>; + }; + + qcom,pc-temp-y2-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <9914 10222 10683 10964 11183 11045>, + <9946 10230 10651 10941 11126 11069>, + <9983 10240 10621 10918 11071 11067>, + <10020 10249 10593 10895 11020 11052>, + <10050 10257 10567 10872 10975 11035>, + <10068 10262 10544 10849 10941 11028>, + <10074 10265 10523 10825 10911 11019>, + <10079 10267 10506 10802 10890 11002>, + <10101 10266 10496 10774 10887 10976>, + <10158 10263 10488 10742 10895 10930>, + <10213 10263 10483 10729 10900 10910>, + <10266 10342 10478 10738 10902 10910>, + <10305 10434 10476 10748 10902 10910>, + <10314 10433 10492 10751 10898 10920>, + <10318 10403 10543 10754 10887 10947>, + <10326 10392 10576 10759 10885 10954>, + <10351 10419 10589 10776 10908 10926>, + <10387 10455 10601 10800 10946 10901>, + <10432 10476 10615 10843 10994 10928>, + <10484 10492 10630 10897 11052 10992>, + <10484 10511 10647 10908 11086 11025>, + <10286 10534 10664 10894 11107 11052>, + <10094 10558 10683 10883 11119 11075>, + <9952 10585 10701 10892 11121 11108>, + <9736 10611 10721 10911 11120 11155>, + <9680 10616 10741 10926 11122 11189>, + <9673 10605 10765 10949 11123 11222>, + <9668 10592 10780 10972 11125 11238>, + <9666 10579 10784 10989 11140 11234>, + <9664 10561 10786 11002 11163 11228>, + <9663 10538 10790 11008 11178 11230>, + <9661 10508 10798 11010 11191 11244>, + <9660 10466 10803 11011 11200 11260>, + <9659 10335 10790 11004 11211 11279>, + <9658 10135 10767 10993 11219 11295>, + <9657 10006 10747 10986 11196 11289>, + <9655 9805 10727 10977 11126 11262>, + <9655 9695 10703 10967 11096 11241>, + <9654 9677 10673 10957 11113 11231>, + <9653 9667 10636 10946 11131 11227>, + <9653 9661 10595 10934 11116 11220>, + <9652 9658 10547 10920 11077 11193>, + <9652 9656 10487 10904 11077 11137>, + <9652 9653 10419 10885 11093 11129>, + <9651 9652 10290 10865 11083 11158>, + <9651 9652 10140 10837 11039 11066>, + <9651 9651 10260 10820 10979 10993>, + <9651 9651 10216 10799 10953 10940>, + <9651 9651 10188 10795 10964 10908>, + <9650 9650 10170 10774 10960 10865>, + <9650 9650 10144 10741 10924 10853>, + <9649 9650 9941 10682 10864 10805>, + <9648 9649 9709 10605 10800 10758>, + <9647 9648 9665 10555 10732 10653>, + <9647 9648 9665 10555 10732 10653>, + <9647 9648 9665 10555 10732 10653>; + }; + + qcom,pc-temp-y3-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <13564 13490 13355 13305 13277 13275>, + <13617 13499 13361 13303 13278 13276>, + <13666 13512 13367 13302 13280 13277>, + <13707 13527 13372 13301 13282 13278>, + <13735 13539 13377 13301 13283 13279>, + <13744 13545 13381 13302 13284 13280>, + <13734 13546 13384 13303 13284 13281>, + <13717 13547 13386 13304 13285 13282>, + <13707 13555 13388 13304 13285 13283>, + <13699 13577 13389 13302 13285 13283>, + <13686 13587 13391 13302 13286 13283>, + <13638 13554 13394 13308 13290 13283>, + <13591 13513 13397 13316 13295 13283>, + <13592 13504 13398 13319 13295 13285>, + <13607 13500 13401 13321 13294 13289>, + <13611 13496 13402 13322 13294 13291>, + <13582 13489 13399 13324 13296 13289>, + <13549 13479 13393 13326 13298 13288>, + <13536 13470 13388 13326 13300 13289>, + <13527 13460 13382 13327 13301 13291>, + <13514 13451 13375 13326 13301 13292>, + <13488 13442 13368 13321 13297 13288>, + <13467 13432 13361 13315 13293 13283>, + <13461 13421 13356 13309 13288 13280>, + <13459 13409 13352 13303 13284 13278>, + <13456 13398 13348 13301 13282 13277>, + <13449 13388 13344 13300 13281 13277>, + <13445 13380 13342 13300 13281 13276>, + <13452 13373 13342 13300 13282 13277>, + <13468 13368 13344 13301 13283 13278>, + <13489 13368 13343 13302 13284 13278>, + <13523 13374 13338 13306 13284 13278>, + <13561 13381 13335 13307 13284 13278>, + <13598 13391 13338 13307 13285 13279>, + <13641 13402 13343 13307 13286 13280>, + <13695 13412 13344 13306 13286 13279>, + <13766 13428 13344 13306 13285 13277>, + <13844 13447 13344 13305 13285 13276>, + <13929 13471 13348 13303 13283 13276>, + <14023 13502 13352 13301 13282 13276>, + <14128 13548 13355 13300 13282 13277>, + <14249 13625 13357 13300 13284 13278>, + <14381 13738 13361 13300 13284 13278>, + <14524 13900 13364 13301 13283 13278>, + <14576 14042 13355 13301 13282 13277>, + <14696 14187 13357 13304 13281 13279>, + <14828 14350 13379 13307 13288 13282>, + <14982 14536 13393 13314 13290 13285>, + <15128 14688 13413 13314 13293 13290>, + <15291 14820 13436 13324 13301 13291>, + <15495 14916 13453 13326 13297 13287>, + <16003 15021 13463 13324 13297 13287>, + <16900 15292 13520 13334 13299 13291>, + <18414 16030 13693 13348 13304 13295>, + <18414 16030 13693 13348 13304 13295>, + <18414 16030 13693 13348 13304 13295>; + }; + + qcom,pc-temp-y4-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <17336 16910 16654 16528 16493 16478>, + <17345 16950 16664 16529 16489 16472>, + <17360 17005 16676 16531 16486 16469>, + <17381 17063 16687 16534 16484 16467>, + <17406 17111 16697 16537 16484 16466>, + <17436 17135 16702 16541 16484 16466>, + <17481 17143 16704 16544 16486 16467>, + <17521 17148 16706 16548 16491 16469>, + <17513 17139 16712 16557 16497 16473>, + <17470 17104 16727 16572 16504 16478>, + <17459 17092 16742 16580 16508 16483>, + <17755 17309 16753 16581 16509 16491>, + <18088 17561 16766 16582 16510 16498>, + <17958 17551 16815 16591 16517 16502>, + <17483 17428 16913 16615 16533 16505>, + <17227 17302 16949 16639 16547 16510>, + <17152 17162 16927 16660 16558 16522>, + <17111 17048 16899 16684 16570 16539>, + <17097 17011 16885 16729 16597 16559>, + <17088 16991 16873 16782 16631 16581>, + <17080 16960 16846 16784 16637 16584>, + <17062 16899 16748 16691 16606 16566>, + <17049 16842 16657 16597 16566 16541>, + <17037 16811 16626 16552 16527 16511>, + <17009 16787 16606 16520 16491 16481>, + <17003 16757 16600 16515 16484 16475>, + <17010 16710 16599 16517 16487 16477>, + <17017 16681 16598 16519 16491 16481>, + <17024 16688 16598 16523 16497 16486>, + <17030 16703 16597 16529 16505 16495>, + <17032 16714 16595 16536 16516 16504>, + <17032 16722 16591 16544 16529 16517>, + <17032 16731 16588 16551 16542 16529>, + <17037 16752 16591 16558 16557 16544>, + <17043 16787 16596 16562 16569 16556>, + <17045 16818 16605 16560 16557 16543>, + <17047 16862 16620 16550 16515 16500>, + <17047 16896 16633 16539 16491 16478>, + <17044 16920 16644 16524 16483 16474>, + <17040 16937 16653 16513 16480 16472>, + <17042 16938 16659 16518 16485 16476>, + <17050 16933 16664 16530 16495 16484>, + <17067 16920 16673 16537 16496 16484>, + <17092 16909 16677 16539 16494 16481>, + <17104 16907 16671 16514 16472 16460>, + <17107 16918 16696 16522 16490 16475>, + <17141 16963 16691 16540 16499 16485>, + <17180 17018 16736 16559 16512 16499>, + <17223 17102 16796 16588 16529 16521>, + <17257 17205 16887 16618 16545 16531>, + <17284 17261 16939 16607 16502 16483>, + <17442 17263 16943 16591 16494 16478>, + <17801 17305 16996 16625 16510 16492>, + <18794 17772 17141 16709 16559 16537>, + <18794 17772 17141 16709 16559 16537>, + <18794 17772 17141 16709 16559 16537>; + }; + + qcom,pc-temp-y5-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <9561 11462 13393 14613 13122 14203>, + <9957 11826 13761 14231 13403 14561>, + <10618 12421 14121 13799 13565 14776>, + <11343 13062 14429 13377 13638 14881>, + <11936 13568 14640 13030 13650 14906>, + <12198 13754 14711 12818 13629 14882>, + <12254 13708 14658 12725 13485 14774>, + <12284 13647 14543 12646 13248 14586>, + <12201 13889 14333 12429 12994 14346>, + <11891 14806 13915 12024 12697 14004>, + <11748 15214 13562 11873 12606 13650>, + <11989 13951 13266 12314 13123 13214>, + <12478 12499 13067 12783 13673 12899>, + <13614 13075 13078 12724 13468 13090>, + <15670 15217 13175 12491 12829 13652>, + <16335 16082 13356 12416 12608 13810>, + <14952 15650 14131 12486 12710 13221>, + <13612 15209 15044 12618 12838 12684>, + <13802 15292 15557 12917 12912 12716>, + <14381 15573 15951 13533 12986 12878>, + <14504 15710 16197 14452 13314 13166>, + <13761 15755 16381 16253 14962 13950>, + <12935 15775 16472 17409 16182 14687>, + <12235 15674 16267 16729 15958 15068>, + <11340 15417 15775 15439 15458 15333>, + <11015 15120 15370 14948 15046 15286>, + <10875 14344 14909 14766 14607 14758>, + <10796 13500 14656 14670 14389 14416>, + <10768 12866 15021 14698 14575 14530>, + <10751 12339 15579 14865 14855 14693>, + <10767 12262 15511 15302 14928 14662>, + <10867 12492 14847 16313 14894 14420>, + <10973 12673 14461 16966 14961 14292>, + <11046 12827 14863 17184 15410 14669>, + <11116 12947 15446 17313 16009 15211>, + <11204 12748 15461 17316 16488 15448>, + <11313 12067 15082 17145 16940 15612>, + <11359 11737 14859 16910 17040 15654>, + <11304 11697 15027 16281 16164 15541>, + <11202 11634 15240 15482 15226 15343>, + <11077 11632 15141 14907 15093 15094>, + <10923 11665 14782 14443 15099 14773>, + <10879 11630 14532 14078 14642 14517>, + <10913 11485 14265 14000 14412 14404>, + <10872 11371 13177 14806 15169 15860>, + <11038 11318 12659 14742 13466 14171>, + <11078 11212 13426 14374 14372 13964>, + <11252 11405 13433 14745 13876 14003>, + <11425 11431 13705 13712 13947 14775>, + <11572 11839 14106 14341 15142 14609>, + <11569 12340 14307 15209 16090 15443>, + <11194 12346 13428 15199 17270 15675>, + <10507 11656 11893 15949 16875 17050>, + <9839 10544 11476 16641 17739 18076>, + <9839 10544 11476 16641 17739 18076>, + <9839 10544 11476 16641 17739 18076>; + }; + + qcom,pc-temp-y6-lut { + qcom,lut-col-legend = <(-10) 0 10 25 40 50>; + qcom,lut-row-legend = <10000 9800 9600 9400 9200 9000>, + <8800 8600 8400 8200 8000 7800>, + <7600 7400 7200 7000 6800 6600>, + <6400 6200 6000 5800 5600 5400>, + <5200 5000 4800 4600 4400 4200>, + <4000 3800 3600 3400 3200 3000>, + <2800 2600 2400 2200 2000 1800>, + <1600 1400 1200 1000 900 800>, + <700 600 500 400 300 200>, + <100 0>; + qcom,lut-data = <6387 5774 5317 5112 5054 5039>, + <6411 5795 5320 5111 5053 5039>, + <6428 5812 5324 5111 5053 5039>, + <6437 5825 5327 5111 5053 5039>, + <6442 5832 5330 5112 5054 5040>, + <6443 5834 5331 5112 5055 5040>, + <6439 5829 5330 5114 5056 5042>, + <6429 5822 5329 5115 5058 5043>, + <6412 5817 5329 5117 5060 5044>, + <6381 5813 5332 5119 5061 5046>, + <6369 5812 5334 5122 5064 5048>, + <6420 5844 5337 5126 5067 5050>, + <6476 5880 5341 5131 5070 5052>, + <6446 5873 5355 5137 5073 5055>, + <6336 5837 5382 5144 5077 5059>, + <6270 5799 5392 5152 5080 5062>, + <6242 5757 5384 5160 5085 5065>, + <6227 5722 5373 5168 5090 5068>, + <6231 5707 5366 5181 5099 5075>, + <6242 5698 5358 5196 5110 5083>, + <6244 5686 5345 5196 5111 5084>, + <6237 5667 5312 5166 5099 5076>, + <6231 5652 5283 5134 5084 5065>, + <6231 5645 5271 5117 5069 5054>, + <6236 5640 5264 5104 5056 5043>, + <6245 5639 5261 5102 5054 5041>, + <6273 5638 5261 5103 5054 5042>, + <6307 5638 5261 5104 5055 5042>, + <6341 5647 5264 5106 5057 5045>, + <6379 5671 5269 5109 5061 5048>, + <6419 5697 5271 5113 5064 5051>, + <6462 5727 5271 5118 5068 5055>, + <6509 5761 5272 5122 5073 5058>, + <6559 5800 5278 5125 5078 5064>, + <6613 5845 5288 5127 5083 5068>, + <6673 5893 5296 5127 5079 5064>, + <6740 5947 5305 5124 5067 5050>, + <6813 6009 5315 5122 5060 5044>, + <6893 6082 5328 5117 5057 5043>, + <6978 6167 5342 5113 5056 5043>, + <7070 6263 5358 5114 5058 5044>, + <7171 6377 5375 5119 5062 5047>, + <7283 6510 5400 5123 5063 5048>, + <7405 6670 5428 5125 5062 5047>, + <7460 6806 5437 5119 5055 5041>, + <7557 6935 5466 5125 5060 5047>, + <7667 7081 5510 5134 5068 5052>, + <7794 7244 5568 5145 5073 5058>, + <7924 7388 5641 5155 5081 5069>, + <8062 7523 5723 5173 5091 5072>, + <8242 7618 5792 5173 5076 5056>, + <8750 7710 5851 5170 5075 5055>, + <9655 7965 5997 5194 5082 5063>, + <11188 8777 6283 5238 5102 5081>, + <11188 8777 6283 5238 5102 5081>, + <11188 8777 6283 5238 5102 5081>; + }; + +}; diff --git a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi index 4eb5f2521f5e..e57f2df54d9a 100755 --- a/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm450-pmi632.dtsi @@ -36,8 +36,8 @@ /{ mtp_batterydata: qcom,battery-data { qcom,batt-id-range-pct = <15>; - #include "qg-batterydata-ascent-3450mah.dtsi" - #include "qg-batterydata-mlp356477-2800mah.dtsi" + #include "qg-batterydata-Fuji-3000mah-Jan22th2019-pmi632.dtsi" + #include "qg-batterydata-Kayo-3000mah-Nov4th2019-pmi632.dtsi" }; }; -- GitLab From c03a7681d39fa0cf6f75587a414a3c2a0d0895b1 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Fri, 24 Apr 2020 16:03:07 +0800 Subject: [PATCH 35/96] Set Battery re-charging voltage to 4.3V Issue: FP3-A11#230 Change-Id: Ie9c967e895ddca03a8a5a499b728fab0e62e8c57 --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) mode change 100644 => 100755 arch/arm64/boot/dts/qcom/pmi632.dtsi diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi old mode 100644 new mode 100755 index 28f2d7f0ca93..8d363a0cac1d --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -314,7 +314,7 @@ qcom,pmic-revid = <&pmi632_revid>; dpdm-supply = <&qusb_phy>; - qcom,auto-recharge-soc = <98>; + qcom,auto-recharge-vbat-mv = <4300>; qcom,chg-vadc = <&pmi632_vadc>; qcom,flash-disable-soc = <10>; qcom,sw-jeita-enable; @@ -484,8 +484,6 @@ #size-cells = <1>; qcom,qg-iterm-ma = <100>; - qcom,hold-soc-while-full; - qcom,linearize-soc; qcom,qg-vadc = <&pmi632_vadc>; qcom,pmic-revid = <&pmi632_revid>; -- GitLab From 0ed02fe62d21987792d3c71c206453537d298341 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 27 Apr 2020 16:06:56 +0800 Subject: [PATCH 36/96] Fill the correct NTC table for battery Issue: FP3-A11#230 Change-Id: I7155d49c94adff3743aaef45a234db62c761d218 --- drivers/hwmon/qpnp-adc-common.c | 142 ++++++++++++++++---------------- 1 file changed, 71 insertions(+), 71 deletions(-) mode change 100644 => 100755 drivers/hwmon/qpnp-adc-common.c diff --git a/drivers/hwmon/qpnp-adc-common.c b/drivers/hwmon/qpnp-adc-common.c old mode 100644 new mode 100755 index 5a54b73800cb..2d3a9013cd59 --- a/drivers/hwmon/qpnp-adc-common.c +++ b/drivers/hwmon/qpnp-adc-common.c @@ -659,76 +659,76 @@ static const struct qpnp_vadc_map_pt adcmap_ncp03wf683[] = { /* Voltage to temperature */ static const struct qpnp_vadc_map_pt adcmap_batt_therm[] = { - {1770, -400}, - {1757, -380}, - {1743, -360}, - {1727, -340}, - {1710, -320}, - {1691, -300}, - {1671, -280}, - {1650, -260}, - {1627, -240}, - {1602, -220}, - {1576, -200}, - {1548, -180}, - {1519, -160}, - {1488, -140}, - {1456, -120}, - {1423, -100}, - {1388, -80}, - {1353, -60}, - {1316, -40}, - {1278, -20}, - {1240, 0}, - {1201, 20}, - {1162, 40}, - {1122, 60}, - {1082, 80}, - {1042, 100}, - {1003, 120}, - {964, 140}, - {925, 160}, - {887, 180}, - {849, 200}, - {812, 220}, - {777, 240}, - {742, 260}, - {708, 280}, - {675, 300}, - {643, 320}, - {613, 340}, - {583, 360}, - {555, 380}, - {528, 400}, - {502, 420}, - {477, 440}, - {453, 460}, - {430, 480}, - {409, 500}, - {388, 520}, - {369, 540}, - {350, 560}, - {333, 580}, - {316, 600}, - {300, 620}, - {285, 640}, - {271, 660}, - {257, 680}, - {245, 700}, - {233, 720}, - {221, 740}, - {210, 760}, - {200, 780}, - {190, 800}, - {181, 820}, - {173, 840}, - {164, 860}, - {157, 880}, - {149, 900}, - {142, 920}, - {136, 940}, - {129, 960}, - {124, 980} + {1819, -400}, + {1812, -380}, + {1803, -360}, + {1794, -340}, + {1784, -320}, + {1773, -300}, + {1761, -280}, + {1747, -260}, + {1732, -240}, + {1716, -220}, + {1699, -200}, + {1680, -180}, + {1659, -160}, + {1637, -140}, + {1613, -120}, + {1588, -100}, + {1561, -80}, + {1532, -60}, + {1501, -40}, + {1470, -20}, + {1436, 0}, + {1401, 20}, + {1365, 40}, + {1327, 60}, + {1289, 80}, + {1249, 100}, + {1209, 120}, + {1167, 140}, + {1126, 160}, + {1084, 180}, + {1042, 200}, + {1000, 220}, + {958, 240}, + {916, 260}, + {875, 280}, + {835, 300}, + {796, 320}, + {757, 340}, + {720, 360}, + {683, 380}, + {648, 400}, + {614, 420}, + {581, 440}, + {550, 460}, + {520, 480}, + {491, 500}, + {463, 520}, + {437, 540}, + {412, 560}, + {389, 580}, + {367, 600}, + {345, 620}, + {325, 640}, + {306, 660}, + {289, 680}, + {272, 700}, + {256, 720}, + {241, 740}, + {227, 760}, + {214, 780}, + {201, 800}, + {190, 820}, + {179, 840}, + {169, 860}, + {159, 880}, + {150, 900}, + {141, 920}, + {133, 940}, + {126, 960}, + {119, 980} }; /* Voltage to temperature */ @@ -2471,7 +2471,7 @@ int32_t qpnp_adc_scale_die_temp_1390(struct qpnp_vadc_chip *chip, pr_debug("raw_code:%x, v_adc:%lld\n", adc_code, adc_chan_result->physical); - /* T = (1.49322 – V) / 0.00356 */ + /* T = (1.49322 ??V) / 0.00356 */ adc_chan_result->physical = 1493220 - adc_chan_result->physical; adc_chan_result->physical = div64_s64(adc_chan_result->physical, 356); -- GitLab From 84f6baf21cce6776883647dfa5fb9850b6c270be Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 27 Apr 2020 18:23:44 +0800 Subject: [PATCH 37/96] Add condition of charging current for thermal-mitigation Issue: FP3-A11#230 Change-Id: If9dab24562fb9fda76a50ad4f4f75b0891189c25 --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index 8d363a0cac1d..0c661036fd38 100755 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -324,8 +324,8 @@ qcom,connector-internal-pull-kohm = <100>; qcom,thermal-mitigation - = <3000000 2500000 2000000 1500000 - 1000000 500000>; + = <2000000 1500000 1000000 500000 + 500000 500000>; qcom,chgr@1000 { reg = <0x1000 0x100>; -- GitLab From cb6c248624b696b60481e0b19bd2ea3dab829c80 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 27 Apr 2020 19:09:56 +0800 Subject: [PATCH 38/96] Setting jeita fv re-charge voltage for warm temp Jeita fv stop charging when battery temp is warm, but without use HW re-charge. To fix this, add a dynamic re-charge function for warm temp's HW re-charge. Issue: FP3-A11#230 Change-Id: I9343ab687113f03d93cecb8baa5e8ac794cf7f7b --- drivers/power/supply/qcom/smb5-lib.c | 38 ++++++++++++++++++++++ drivers/power/supply/qcom/smb5-lib.h | 1 + drivers/power/supply/qcom/step-chg-jeita.c | 8 +++++ 3 files changed, 47 insertions(+) mode change 100644 => 100755 drivers/power/supply/qcom/smb5-lib.c mode change 100644 => 100755 drivers/power/supply/qcom/smb5-lib.h mode change 100644 => 100755 drivers/power/supply/qcom/step-chg-jeita.c diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c old mode 100644 new mode 100755 index 1fae67880e12..7670e5dcdc4a --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -1236,6 +1236,36 @@ static int smblib_usb_irq_enable_vote_callback(struct votable *votable, return 0; } +static int smblib_jeita_rechg_voltage_vote_callback(struct votable *votable, void *data, + int voltage, const char *client) +{ + struct smb_charger *chg = data; + int rc = 0; + u32 temp = VBAT_TO_VRAW_ADC((voltage/1000)); + + temp = ((temp & 0xFF00) >> 8) | ((temp & 0xFF) << 8); + rc = smblib_batch_write(chg, + CHGR_ADC_RECHARGE_THRESHOLD_MSB_REG, (u8 *)&temp, 2); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure ADC_RECHARGE_THRESHOLD REG rc=%d\n", + rc); + return rc; + } + /* Program the sample count for VBAT based recharge to 3 */ + rc = smblib_masked_write(chg, CHGR_NO_SAMPLE_TERM_RCHG_CFG_REG, + NO_OF_SAMPLE_FOR_RCHG, + 2 << NO_OF_SAMPLE_FOR_RCHG_SHIFT); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure CHGR_NO_SAMPLE_FOR_TERM_RCHG_CFG rc=%d\n", + rc); + return rc; + } + + dev_err(chg->dev, "jeita_rechg_voltage =%d\n", voltage); + + return rc; +} + /******************* * VCONN REGULATOR * * *****************/ @@ -4521,6 +4551,14 @@ static int smblib_create_votables(struct smb_charger *chg) return rc; } + chg->rechg_vol_votable = create_votable("RECHG_VOL", VOTE_MIN, + smblib_jeita_rechg_voltage_vote_callback, + chg); + if (IS_ERR(chg->rechg_vol_votable)) { + rc = PTR_ERR(chg->rechg_vol_votable); + return rc; + } + return rc; } diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h old mode 100644 new mode 100755 index 49110470e75e..e7dd8be8664d --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -347,6 +347,7 @@ struct smb_charger { struct votable *chg_disable_votable; struct votable *pl_enable_votable_indirect; struct votable *usb_irq_enable_votable; + struct votable *rechg_vol_votable; /* work */ struct work_struct bms_update_work; diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c old mode 100644 new mode 100755 index 3e8b46b9e12b..4262d7024a6e --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -80,6 +80,7 @@ struct step_chg_info { struct votable *fcc_votable; struct votable *fv_votable; struct votable *usb_icl_votable; + struct votable *rechg_vol_votable; struct wakeup_source *step_chg_ws; struct power_supply *batt_psy; struct power_supply *bms_psy; @@ -500,6 +501,8 @@ static int handle_step_chg_config(struct step_chg_info *chip) } #define JEITA_SUSPEND_HYST_UV 50000 +#define JEITA_RECHG_HYST_UV 200000//100000 + static int handle_jeita(struct step_chg_info *chip) { union power_supply_propval pval = {0, }; @@ -561,6 +564,9 @@ static int handle_jeita(struct step_chg_info *chip) if (rc < 0) fv_uv = 0; + if (!chip->rechg_vol_votable) + chip->rechg_vol_votable = find_votable("RECHG_VOL"); + chip->fv_votable = find_votable("FV"); if (!chip->fv_votable) goto update_time; @@ -597,6 +603,8 @@ static int handle_jeita(struct step_chg_info *chip) set_jeita_fv: vote(chip->fv_votable, JEITA_VOTER, fv_uv ? true : false, fv_uv); + vote(chip->rechg_vol_votable, + JEITA_VOTER, true, (fv_uv -JEITA_RECHG_HYST_UV)); update_time: chip->jeita_last_update_time = ktime_get(); -- GitLab From 751aa0852899e335f49c5172f6ac9ee842bdd29a Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Fri, 8 May 2020 17:36:49 +0800 Subject: [PATCH 39/96] Fix phone can not charge fully Issue: FP3-A11#230 Change-Id: I5cf21af81ca3ceb84e56cb5c9c2c6f39bfae10b1 --- drivers/power/supply/qcom/qpnp-smb5.c | 8 ++++++++ drivers/power/supply/qcom/step-chg-jeita.c | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) mode change 100644 => 100755 drivers/power/supply/qcom/qpnp-smb5.c diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c old mode 100644 new mode 100755 index 7505c49e922e..3183f694021e --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -2092,6 +2092,14 @@ static int smb5_init_hw(struct smb5 *chip) } } + /* AICL PERIODIC RERUN ENABLE*/ + rc = smblib_write(chg, USBIN_AICL_OPTIONS_CFG_REG, 0xD4); + if (rc < 0) { + dev_err(chg->dev, + "Couldn't config RERUN AICL ENABLE rc=%d\n", rc); + return rc; + } + /* enable the charging path */ rc = vote(chg->chg_disable_votable, DEFAULT_VOTER, false, 0); if (rc < 0) { diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index 4262d7024a6e..1d7616ea3103 100755 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -500,8 +500,8 @@ static int handle_step_chg_config(struct step_chg_info *chip) return (STEP_CHG_HYSTERISIS_DELAY_US - elapsed_us + 1000); } -#define JEITA_SUSPEND_HYST_UV 50000 -#define JEITA_RECHG_HYST_UV 200000//100000 +#define JEITA_SUSPEND_HYST_UV 200000 +#define JEITA_RECHG_HYST_UV 200000 static int handle_jeita(struct step_chg_info *chip) { -- GitLab From 3340b5a3dabd4ef40826cb21df03f807487f6a15 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Mon, 11 May 2020 09:31:08 +0800 Subject: [PATCH 40/96] Enable step-charging for Kayo battery 1.Add step-charging parameters in battery profile (case:156287) 2.Set hysteresis of voltage to "0" Issue: FP3-A11#230 Change-Id: I1e3eeab77cc5cb5c25ca037ad8d332bcee21f660 --- drivers/power/supply/qcom/step-chg-jeita.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/step-chg-jeita.c b/drivers/power/supply/qcom/step-chg-jeita.c index 1d7616ea3103..5f61803200cd 100755 --- a/drivers/power/supply/qcom/step-chg-jeita.c +++ b/drivers/power/supply/qcom/step-chg-jeita.c @@ -778,7 +778,7 @@ int qcom_step_chg_init(struct device *dev, chip->step_chg_config->psy_prop = POWER_SUPPLY_PROP_VOLTAGE_NOW; chip->step_chg_config->prop_name = "VBATT"; - chip->step_chg_config->hysteresis = 100000; + chip->step_chg_config->hysteresis = 0; /* 100000 */; chip->jeita_fcc_config = devm_kzalloc(dev, sizeof(struct jeita_fcc_cfg), GFP_KERNEL); -- GitLab From de3a69f93bb60bdccef8ca07415fe21f29343b91 Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Tue, 27 Nov 2018 16:14:44 +0800 Subject: [PATCH 41/96] power: smb5: Disable unused rid change interrupt sources Fixes issue where system can't enter VDD minimization. Issue: FP3-A11#230 Change-Id: Ia4e733a80cb29cb8f2d3507b91eb0a87e52c7313 (cherry picked from commit 5c010f118669e4b14e2baa532193b3cff486244e) --- drivers/power/supply/qcom/qpnp-smb5.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index 3183f694021e..27e06740e495 100755 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -1684,7 +1684,7 @@ static int smb5_init_vconn_regulator(struct smb5 *chip) static int smb5_configure_typec(struct smb_charger *chg) { int rc; - u8 val = 0; + u8 val = 0, rid_int_src = 0; rc = smblib_read(chg, LEGACY_CABLE_STATUS_REG, &val); if (rc < 0) { @@ -1750,6 +1750,16 @@ static int smb5_configure_typec(struct smb_charger *chg) rc); return rc; } + + /* Enable Water detection rid source interrupt */ + rid_int_src |= TYPEC_WATER_DETECTION_INT_EN_BIT; + } + + /* Disable rid source interrupts which are not required. */ + rc = smblib_write(chg, TYPE_C_INTERRUPT_EN_CFG_2_REG, rid_int_src); + if (rc < 0) { + dev_err(chg->dev, "Couldn't configure Type-C interrupts rc=%d\n", rc); + return rc; } /* Disable TypeC and RID change source interrupts */ -- GitLab From 126e973a2ca1bda79b40faa32706098afeda6d7b Mon Sep 17 00:00:00 2001 From: jessicatseng Date: Thu, 4 Jun 2020 09:42:07 +0800 Subject: [PATCH 42/96] Modify charging termination current Issue: FP3-A11#230 Change-Id: Id6c08ccb32aa03bf2e8eab18d34bc2ed6ba5e8ab --- arch/arm64/boot/dts/qcom/pmi632.dtsi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/pmi632.dtsi b/arch/arm64/boot/dts/qcom/pmi632.dtsi index 0c661036fd38..ab3b3698063d 100755 --- a/arch/arm64/boot/dts/qcom/pmi632.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi632.dtsi @@ -327,6 +327,8 @@ = <2000000 1500000 1000000 500000 500000 500000>; + qcom,chg-term-src = <1>; + qcom,chg-term-current-ma = <(-100)>; qcom,chgr@1000 { reg = <0x1000 0x100>; interrupts = @@ -483,7 +485,7 @@ #address-cells = <1>; #size-cells = <1>; - qcom,qg-iterm-ma = <100>; + qcom,qg-iterm-ma = <150>; qcom,qg-vadc = <&pmi632_vadc>; qcom,pmic-revid = <&pmi632_revid>; -- GitLab From 2f9f368033361e3998e69636466ebe1c32c79b3e Mon Sep 17 00:00:00 2001 From: tracychui Date: Fri, 12 Jun 2020 17:46:51 +0800 Subject: [PATCH 43/96] Expose power up/down reason and memory info Feature:ARFP3-91: Expose power up and power down reason ARFP3-77: Expose main memory hardware revision Issue: FP3-A11#230 Change-Id: I62242576e233d5c92025a97f46246b924b19bba8 --- arch/arm64/include/asm/processor.h | 3 ++ drivers/input/misc/qpnp-power-on.c | 9 ++++- drivers/soc/qcom/socinfo.c | 62 ++++++++++++++++++++++++++++++ kernel/sysctl.c | 40 +++++++++++++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) mode change 100644 => 100755 arch/arm64/include/asm/processor.h mode change 100644 => 100755 drivers/input/misc/qpnp-power-on.c mode change 100644 => 100755 drivers/soc/qcom/socinfo.c mode change 100644 => 100755 kernel/sysctl.c diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h old mode 100644 new mode 100755 index e9ba70ab4a38..cd0d55ad1b3b --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -81,7 +81,10 @@ extern phys_addr_t arm64_dma_phys_limit; #define ARCH_LOW_ADDRESS_LIMIT (arm64_dma_phys_limit - 1) extern unsigned int boot_reason; +extern unsigned int qpnp_pon_reason_extern; +extern unsigned int qpnp_poff_reason_extern; extern unsigned int cold_boot; +extern char ddr_vendor[32]; struct debug_info { /* Have we suspended stepping by a debugger? */ diff --git a/drivers/input/misc/qpnp-power-on.c b/drivers/input/misc/qpnp-power-on.c old mode 100644 new mode 100755 index 65379ed8ed35..edb21cfe51ff --- a/drivers/input/misc/qpnp-power-on.c +++ b/drivers/input/misc/qpnp-power-on.c @@ -313,6 +313,8 @@ static const char * const qpnp_poff_reason[] = { [39] = "Triggered from S3_RESET_KPDPWR_ANDOR_RESIN (power key and/or reset line)", }; +unsigned int qpnp_pon_reason_extern = 0; +unsigned int qpnp_poff_reason_extern = 0; static int qpnp_pon_masked_write(struct qpnp_pon *pon, u16 addr, u8 mask, u8 val) { @@ -2287,8 +2289,10 @@ static int qpnp_pon_probe(struct platform_device *pdev) goto err_out; } - if (sys_reset) + if (sys_reset) { boot_reason = ffs(pon_sts); + qpnp_pon_reason_extern = ffs(pon_sts); + } index = ffs(pon_sts) - 1; cold_boot = !qpnp_pon_is_warm_reset(); @@ -2322,6 +2326,9 @@ static int qpnp_pon_probe(struct platform_device *pdev) } poff_sts = buf[0] | (buf[1] << 8); } + if (sys_reset) { + qpnp_poff_reason_extern = ffs(poff_sts); + } index = ffs(poff_sts) - 1 + reason_index_offset; if (index >= ARRAY_SIZE(qpnp_poff_reason) || index < 0) { dev_info(&pon->pdev->dev, diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c old mode 100644 new mode 100755 index 7dee6074a493..c46234f16c1d --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -2007,6 +2007,64 @@ static void socinfo_select_format(void) } } +char ddr_vendor[32] = ""; +/* BOOT.BF.3.3.2\boot_images\core\api\boot\ddr_common.h */ +typedef enum +{ + RESERVED_0, /**< Reserved for future use. */ + SAMSUNG, /**< Samsung. */ + QIMONDA, /**< Qimonda. */ + ELPIDA, /**< Elpida Memory, Inc. */ + ETRON, /**< Etron Technology, Inc. */ + NANYA, /**< Nanya Technology Corporation. */ + HYNIX, /**< Hynix Semiconductor Inc. */ + MOSEL, /**< Mosel Vitelic Corporation. */ + WINBOND, /**< Winbond Electronics Corp. */ + ESMT, /**< Elite Semiconductor Memory Technology Inc. */ + RESERVED_1, /**< Reserved for future use. */ + SPANSION, /**< Spansion Inc. */ + SST, /**< Silicon Storage Technology, Inc. */ + ZMOS, /**< ZMOS Technology, Inc. */ + INTEL, /**< Intel Corporation. */ + NUMONYX = 254, /**< Numonyx, acquired by Micron Technology, Inc. */ + MICRON = 255, /**< Micron Technology, Inc. */ + DDR_MANUFACTURES_MAX = 0x7FFFFFFF /**< Forces the enumerator to 32 bits. */ +} DDR_MANUFACTURES; + +void smem_get_ddr_manufacturer_id(unsigned char *buf) +{ + unsigned int *manufacturer_id; + unsigned int manufacturer_id_len = sizeof(manufacturer_id); + + manufacturer_id = smem_get_entry(SMEM_ID_VENDOR2, &manufacturer_id_len, 0, + SMEM_ANY_HOST_FLAG); + if (manufacturer_id == NULL) + { + pr_err("[B]%s(%d): Failed to read SMEM_ID_VENDOR2\n", __func__, __LINE__); + } + + switch(*manufacturer_id) + { + case SAMSUNG: + snprintf((char *)buf, 64, "SAMSUNG"); + break; + case ELPIDA: + snprintf((char *)buf, 64, "ELPIDA"); + break; + case HYNIX: + snprintf((char *)buf, 64, "HYNIX"); + break; + case MICRON: + snprintf((char *)buf, 64, "MICRON"); + break; + default: + snprintf((char *)buf, 64, "OTHERS"); + break; + } + + pr_err("[B]%s(%d): manufacturer_id=%d, %s\n", __func__, __LINE__, *manufacturer_id, buf); +} + int __init socinfo_init(void) { static bool socinfo_init_done; @@ -2036,6 +2094,10 @@ int __init socinfo_init(void) arch_read_hardware_id = msm_read_hardware_id; socinfo_init_done = true; + memset(ddr_vendor, 0, sizeof(ddr_vendor)); + smem_get_ddr_manufacturer_id((unsigned char *) ddr_vendor); + pr_err("[B]%s(%d): ddr_vendor=%s\n", __func__, __LINE__, ddr_vendor); + return 0; } subsys_initcall(socinfo_init); diff --git a/kernel/sysctl.c b/kernel/sysctl.c old mode 100644 new mode 100755 index f3a22c903ddb..47f88bb5b3cf --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -230,6 +231,8 @@ static struct ctl_table vm_table[]; static struct ctl_table fs_table[]; static struct ctl_table debug_table[]; static struct ctl_table dev_table[]; +static struct ctl_table qpnp_power_on_table[]; +static struct ctl_table ddr_table[]; extern struct ctl_table random_table[]; #ifdef CONFIG_EPOLL extern struct ctl_table epoll_table[]; @@ -267,6 +270,11 @@ static struct ctl_table sysctl_base_table[] = { .mode = 0555, .child = dev_table, }, + { + .procname = "qpnp-power-on", + .mode = 0555, + .child = qpnp_power_on_table, + }, { } }; @@ -2089,6 +2097,38 @@ static struct ctl_table debug_table[] = { }; static struct ctl_table dev_table[] = { + { + .procname = "ddr", + .mode = 0555, + .child = ddr_table, + }, + { } +}; +static struct ctl_table qpnp_power_on_table[] = { + { + .procname = "pon_reason", + .data = &qpnp_pon_reason_extern, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = proc_dointvec, + }, + { + .procname = "poff_reason", + .data = &qpnp_poff_reason_extern, + .maxlen = sizeof(int), + .mode = 0444, + .proc_handler = proc_dointvec, + }, + { } +}; +static struct ctl_table ddr_table[] = { + { + .procname = "vendor", + .data = &ddr_vendor, + .maxlen = 32, + .mode = 0444, + .proc_handler = proc_dostring, + }, { } }; -- GitLab From 6ebe3f0758cf4e4fff95c146eaedd0c6b7e28ff8 Mon Sep 17 00:00:00 2001 From: tracychui Date: Mon, 29 Jun 2020 16:51:39 +0800 Subject: [PATCH 44/96] Add memory detect node for service menu Issue: FP3-A11#230 Change-Id: I0e3aa68cdeca14fe304fcdeef216c6349953a5dc --- drivers/mmc/core/mmc.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 0831456c3c52..80acd1c12c1b 100755 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -27,10 +28,13 @@ #include "bus.h" #include "mmc_ops.h" #include "sd_ops.h" +#include #define DEFAULT_CMD6_TIMEOUT_MS 500 #define MIN_CACHE_EN_TIMEOUT_MS 1600 +static u32 memory_cid = 0x0; + static const unsigned int tran_exp[] = { 10000, 100000, 1000000, 10000000, 0, 0, 0, 0 @@ -3156,6 +3160,29 @@ static const struct mmc_bus_ops mmc_ops = { .post_hibernate = mmc_post_hibernate }; +static int proc_memory_vendor_show(struct seq_file *m, void *v) +{ + if (memory_cid==0x15010052) { + seq_printf(m, "Samsung_2nd\n"); + } + else { + seq_printf(m, "Samsung_Main\n"); + } + return 0; +} + +static int proc_memory_vendor_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_memory_vendor_show, NULL); +} + +static const struct file_operations proc_memory_vendor_fops = { + .open = proc_memory_vendor_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + /* * Starting point for MMC card init. */ @@ -3219,6 +3246,11 @@ int mmc_attach_mmc(struct mmc_host *host) register_reboot_notifier(&host->card->reboot_notify); + proc_create("memory_vendor", 0, NULL, &proc_memory_vendor_fops); + if (host->card->type == MMC_TYPE_MMC) { + memory_cid=host->card->raw_cid[0]; + } + return 0; remove_card: -- GitLab From 69b36133b409eb3f920ae6f9dc2681385a615959 Mon Sep 17 00:00:00 2001 From: Umang Agrawal Date: Thu, 7 Feb 2019 14:43:53 +0530 Subject: [PATCH 45/96] power: smb5: Add support for typeC role reversal smb5 typeC supports role-reversal where device can be forced either to DFP or UFP mode. Add support of force mode via dual role class framework. Issue: FP3-A11#69 Change-Id: I9a25ef29f536ee53ca3143ed38b30a0f929a8995 Signed-off-by: Umang Agrawal (cherry picked from commit 6a7cf05e1edccf36434adf5c39797eabaa0841f2) --- drivers/power/supply/qcom/qpnp-smb5.c | 211 ++++++++++++++++++++++++++ drivers/power/supply/qcom/smb5-lib.c | 112 ++++++++++++++ drivers/power/supply/qcom/smb5-lib.h | 12 ++ 3 files changed, 335 insertions(+) diff --git a/drivers/power/supply/qcom/qpnp-smb5.c b/drivers/power/supply/qcom/qpnp-smb5.c index 27e06740e495..76704da24904 100755 --- a/drivers/power/supply/qcom/qpnp-smb5.c +++ b/drivers/power/supply/qcom/qpnp-smb5.c @@ -1591,6 +1591,209 @@ static int smb5_init_batt_psy(struct smb5 *chip) return rc; } +/******************************** + * DUAL-ROLE CLASS REGISTRATION * + ********************************/ +static enum dual_role_property smb5_dr_properties[] = { + DUAL_ROLE_PROP_SUPPORTED_MODES, + DUAL_ROLE_PROP_MODE, + DUAL_ROLE_PROP_PR, + DUAL_ROLE_PROP_DR, +}; + +static int smb5_dr_get_property(struct dual_role_phy_instance *dual_role, + enum dual_role_property prop, unsigned int *val) +{ + struct smb_charger *chg = dual_role_get_drvdata(dual_role); + union power_supply_propval pval = {0, }; + /* Initializing pr, dr and mode to value 2 corresponding to NONE case */ + int mode = 2, pr = 2, dr = 2, rc = 0; + + if (!chg) + return -ENODEV; + + rc = smblib_get_prop_usb_present(chg, &pval); + if (rc < 0) { + pr_err("Couldn't get usb present status, rc=%d\n", rc); + return rc; + } + + if (chg->connector_type == POWER_SUPPLY_CONNECTOR_TYPEC) { + if (chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) { + mode = DUAL_ROLE_PROP_MODE_NONE; + pr = DUAL_ROLE_PROP_PR_NONE; + dr = DUAL_ROLE_PROP_DR_NONE; + } else if (chg->typec_mode < + POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { + mode = DUAL_ROLE_PROP_MODE_DFP; + pr = DUAL_ROLE_PROP_PR_SRC; + dr = DUAL_ROLE_PROP_DR_HOST; + } else if (chg->typec_mode >= + POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { + mode = DUAL_ROLE_PROP_MODE_UFP; + pr = DUAL_ROLE_PROP_PR_SNK; + dr = DUAL_ROLE_PROP_DR_DEVICE; + } + } else if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) { + pr = DUAL_ROLE_PROP_PR_NONE; + + if (chg->otg_present) { + mode = DUAL_ROLE_PROP_MODE_DFP; + dr = DUAL_ROLE_PROP_DR_HOST; + } else if (pval.intval) { + mode = DUAL_ROLE_PROP_MODE_UFP; + dr = DUAL_ROLE_PROP_DR_DEVICE; + } else { + mode = DUAL_ROLE_PROP_MODE_NONE; + dr = DUAL_ROLE_PROP_DR_NONE; + } + } + + switch (prop) { + case DUAL_ROLE_PROP_MODE: + *val = mode; + break; + case DUAL_ROLE_PROP_PR: + *val = pr; + break; + case DUAL_ROLE_PROP_DR: + *val = dr; + break; + default: + pr_err("dual role class get property %d not supported\n", prop); + return -EINVAL; + } + + return 0; +} + +static int smb5_dr_set_property(struct dual_role_phy_instance *dual_role, + enum dual_role_property prop, const unsigned int *val) +{ + struct smb_charger *chg = dual_role_get_drvdata(dual_role); + int rc = 0; + + if (!chg) + return -ENODEV; + + mutex_lock(&chg->dr_lock); + switch (prop) { + case DUAL_ROLE_PROP_MODE: + if (chg->pr_swap_in_progress) { + pr_debug("Already in mode transition. Skipping request\n"); + mutex_unlock(&chg->dr_lock); + return 0; + } + + switch (*val) { + case DUAL_ROLE_PROP_MODE_UFP: + if (chg->typec_mode >= + POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { + chg->dr_mode = DUAL_ROLE_PROP_MODE_UFP; + } else { + chg->pr_swap_in_progress = true; + rc = smblib_force_dr_mode(chg, + DUAL_ROLE_PROP_MODE_UFP); + if (rc < 0) { + chg->pr_swap_in_progress = false; + pr_err("Failed to force UFP mode, rc=%d\n", + rc); + } + } + break; + case DUAL_ROLE_PROP_MODE_DFP: + if (chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEFAULT + && chg->typec_mode != POWER_SUPPLY_TYPEC_NONE) { + chg->dr_mode = DUAL_ROLE_PROP_MODE_DFP; + } else { + chg->pr_swap_in_progress = true; + rc = smblib_force_dr_mode(chg, + DUAL_ROLE_PROP_MODE_DFP); + if (rc < 0) { + chg->pr_swap_in_progress = false; + pr_err("Failed to force DFP mode, rc=%d\n", + rc); + } + } + break; + default: + pr_err("Invalid role (not DFP/UFP): %d\n", *val); + rc = -EINVAL; + } + + /* + * Schedule delayed work to check if the device latched to + * the requested mode. + */ + if (chg->pr_swap_in_progress && !rc) { + cancel_delayed_work_sync(&chg->role_reversal_check); + vote(chg->awake_votable, DR_SWAP_VOTER, true, 0); + schedule_delayed_work(&chg->role_reversal_check, + msecs_to_jiffies(ROLE_REVERSAL_DELAY_MS)); + } + break; + default: + pr_err("dual role class set property %d not supported\n", prop); + rc = -EINVAL; + } + + mutex_unlock(&chg->dr_lock); + return rc; +} + +static int smb5_dr_prop_writeable(struct dual_role_phy_instance *dual_role, + enum dual_role_property prop) +{ + struct smb_charger *chg = dual_role_get_drvdata(dual_role); + + if (!chg) + return -ENODEV; + + /* uUSB connector does not support role switch */ + if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB) + return 0; + + switch (prop) { + case DUAL_ROLE_PROP_MODE: + return 1; + default: + break; + } + + return 0; +} + +static const struct dual_role_phy_desc dr_desc = { + .name = "otg_default", + .supported_modes = DUAL_ROLE_SUPPORTED_MODES_DFP_AND_UFP, + .properties = smb5_dr_properties, + .num_properties = ARRAY_SIZE(smb5_dr_properties), + .get_property = smb5_dr_get_property, + .set_property = smb5_dr_set_property, + .property_is_writeable = smb5_dr_prop_writeable, +}; + +static int smb5_init_dual_role_class(struct smb5 *chip) +{ + struct smb_charger *chg = &chip->chg; + int rc = 0; + + /* Register dual role class for only non-PD TypeC and uUSB designs */ + if (!chg->pd_not_supported) + return rc; + + mutex_init(&chg->dr_lock); + chg->dual_role = devm_dual_role_instance_register(chg->dev, &dr_desc); + if (IS_ERR(chg->dual_role)) { + pr_err("Couldn't register dual role class\n"); + rc = PTR_ERR(chg->dual_role); + } else { + chg->dual_role->drv_data = chg; + } + + return rc; +} + /****************************** * VBUS REGULATOR REGISTRATION * ******************************/ @@ -2953,6 +3156,14 @@ static int smb5_probe(struct platform_device *pdev) goto cleanup; } + /* Register android dual-role class */ + rc = smb5_init_dual_role_class(chip); + if (rc < 0) { + pr_err("Couldn't initialize dual role class, rc=%d\n", + rc); + goto cleanup; + } + rc = smb5_determine_initial_status(chip); if (rc < 0) { pr_err("Couldn't determine initial status rc=%d\n", diff --git a/drivers/power/supply/qcom/smb5-lib.c b/drivers/power/supply/qcom/smb5-lib.c index 7670e5dcdc4a..f4feddb45b6e 100755 --- a/drivers/power/supply/qcom/smb5-lib.c +++ b/drivers/power/supply/qcom/smb5-lib.c @@ -3247,6 +3247,8 @@ void smblib_usb_plugin_locked(struct smb_charger *chg) smblib_micro_usb_plugin(chg, vbus_rising); power_supply_changed(chg->usb_psy); + if (chg->dual_role) + dual_role_instance_changed(chg->dual_role); smblib_dbg(chg, PR_INTERRUPT, "IRQ: usbin-plugin %s\n", vbus_rising ? "attached" : "detached"); } @@ -3538,6 +3540,8 @@ irqreturn_t usb_source_change_irq_handler(int irq, void *data) smblib_hvdcp_adaptive_voltage_change(chg); power_supply_changed(chg->usb_psy); + if (chg->dual_role) + dual_role_instance_changed(chg->dual_role); rc = smblib_read(chg, APSD_STATUS_REG, &stat); if (rc < 0) { @@ -3788,6 +3792,8 @@ irqreturn_t typec_state_change_irq_handler(int irq, void *data) smblib_typec_mode_name[chg->typec_mode]); power_supply_changed(chg->usb_psy); + if (chg->dual_role) + dual_role_instance_changed(chg->dual_role); return IRQ_HANDLED; } @@ -3840,10 +3846,21 @@ irqreturn_t typec_attach_detach_irq_handler(int irq, void *data) chg->ok_to_pd = false; chg->sink_src_mode = UNATTACHED_MODE; chg->early_usb_attach = false; + + /* + * Restore DRP mode on type-C cable disconnect if role + * swap is not in progress, to ensure forced sink or src + * mode configuration is reset properly. + */ + if (chg->dual_role) + smblib_force_dr_mode(chg, + DUAL_ROLE_PROP_MODE_NONE); } } power_supply_changed(chg->usb_psy); + if (chg->dual_role) + dual_role_instance_changed(chg->dual_role); return IRQ_HANDLED; } @@ -4471,6 +4488,97 @@ static void jeita_update_work(struct work_struct *work) chg->jeita_configured = true; } +static char *dr_mode_text[] = { + "ufp", "dfp", "none" +}; + +int smblib_force_dr_mode(struct smb_charger *chg, int mode) +{ + int rc = 0; + + switch (mode) { + case DUAL_ROLE_PROP_MODE_UFP: + rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, + TYPEC_POWER_ROLE_CMD_MASK | EN_TRY_SNK_BIT, + EN_SNK_ONLY_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't enable snk, rc=%d\n", rc); + return rc; + } + break; + case DUAL_ROLE_PROP_MODE_DFP: + rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, + TYPEC_POWER_ROLE_CMD_MASK | EN_TRY_SNK_BIT, + EN_SRC_ONLY_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't enable src, rc=%d\n", rc); + return rc; + } + break; + case DUAL_ROLE_PROP_MODE_NONE: + rc = smblib_masked_write(chg, TYPE_C_MODE_CFG_REG, + TYPEC_POWER_ROLE_CMD_MASK | EN_TRY_SNK_BIT, + EN_TRY_SNK_BIT); + if (rc < 0) { + smblib_err(chg, "Couldn't enable try.snk, rc=%d\n", rc); + return rc; + } + break; + default: + smblib_err(chg, "Power role %d not supported\n", mode); + return -EINVAL; + } + + if (chg->dr_mode != mode) { + chg->dr_mode = mode; + smblib_dbg(chg, PR_MISC, "Forced mode: %s\n", + dr_mode_text[chg->dr_mode]); + } + + return rc; +} + +static void smblib_dual_role_check_work(struct work_struct *work) +{ + struct smb_charger *chg = container_of(work, struct smb_charger, + role_reversal_check.work); + int rc = 0; + + mutex_lock(&chg->dr_lock); + + switch (chg->dr_mode) { + case DUAL_ROLE_PROP_MODE_UFP: + if (chg->typec_mode < POWER_SUPPLY_TYPEC_SOURCE_DEFAULT) { + smblib_dbg(chg, PR_MISC, "Role reversal not latched to UFP in %d msecs. Resetting to DRP mode\n", + ROLE_REVERSAL_DELAY_MS); + rc = smblib_force_dr_mode(chg, + DUAL_ROLE_PROP_MODE_NONE); + if (rc < 0) + pr_err("Failed to set DRP mode, rc=%d\n", rc); + } + chg->pr_swap_in_progress = false; + break; + case DUAL_ROLE_PROP_MODE_DFP: + if (chg->typec_mode >= POWER_SUPPLY_TYPEC_SOURCE_DEFAULT || + chg->typec_mode == POWER_SUPPLY_TYPEC_NONE) { + smblib_dbg(chg, PR_MISC, "Role reversal not latched to DFP in %d msecs. Resetting to DRP mode\n", + ROLE_REVERSAL_DELAY_MS); + rc = smblib_force_dr_mode(chg, + DUAL_ROLE_PROP_MODE_NONE); + if (rc < 0) + pr_err("Failed to set DRP mode, rc=%d\n", rc); + } + chg->pr_swap_in_progress = false; + break; + default: + pr_debug("Already in DRP mode\n"); + break; + } + + mutex_unlock(&chg->dr_lock); + vote(chg->awake_votable, DR_SWAP_VOTER, false, 0); +} + static int smblib_create_votables(struct smb_charger *chg) { int rc = 0; @@ -4588,6 +4696,8 @@ int smblib_init(struct smb_charger *chg) INIT_DELAYED_WORK(&chg->uusb_otg_work, smblib_uusb_otg_work); INIT_DELAYED_WORK(&chg->bb_removal_work, smblib_bb_removal_work); INIT_DELAYED_WORK(&chg->usbov_dbc_work, smblib_usbov_dbc_work); + INIT_DELAYED_WORK(&chg->role_reversal_check, + smblib_dual_role_check_work); if (chg->wa_flags & CHG_TERMINATION_WA) { INIT_WORK(&chg->chg_termination_work, @@ -4621,6 +4731,7 @@ int smblib_init(struct smb_charger *chg) chg->fake_batt_status = -EINVAL; chg->jeita_configured = false; chg->sink_src_mode = UNATTACHED_MODE; + chg->dr_mode = DUAL_ROLE_PROP_MODE_NONE; switch (chg->mode) { case PARALLEL_MASTER: @@ -4695,6 +4806,7 @@ int smblib_deinit(struct smb_charger *chg) cancel_delayed_work_sync(&chg->uusb_otg_work); cancel_delayed_work_sync(&chg->bb_removal_work); cancel_delayed_work_sync(&chg->usbov_dbc_work); + cancel_delayed_work_sync(&chg->role_reversal_check); power_supply_unreg_notifier(&chg->nb); smblib_destroy_votables(chg); qcom_step_chg_deinit(); diff --git a/drivers/power/supply/qcom/smb5-lib.h b/drivers/power/supply/qcom/smb5-lib.h index e7dd8be8664d..8abb3276f637 100755 --- a/drivers/power/supply/qcom/smb5-lib.h +++ b/drivers/power/supply/qcom/smb5-lib.h @@ -19,6 +19,7 @@ #include #include #include +#include #include "storm-watch.h" enum print_reason { @@ -73,6 +74,7 @@ enum print_reason { #define USBOV_DBC_VOTER "USBOV_DBC_VOTER" #define FCC_STEPPER_VOTER "FCC_STEPPER_VOTER" #define CHG_TERMINATION_VOTER "CHG_TERMINATION_VOTER" +#define DR_SWAP_VOTER "DR_SWAP_VOTER" #define BOOST_BACK_STORM_COUNT 3 #define WEAK_CHG_STORM_COUNT 8 @@ -88,6 +90,8 @@ enum print_reason { #define TYPEC_MEDIUM_CURRENT_UA 1500000 #define TYPEC_HIGH_CURRENT_UA 3000000 +#define ROLE_REVERSAL_DELAY_MS 2000 + enum smb_mode { PARALLEL_MASTER = 0, PARALLEL_SLAVE, @@ -315,6 +319,7 @@ struct smb_charger { /* locks */ struct mutex lock; struct mutex ps_change_lock; + struct mutex dr_lock; struct mutex vadc_lock; /* power supplies */ @@ -326,6 +331,10 @@ struct smb_charger { struct power_supply *usb_port_psy; enum power_supply_type real_charger_type; + + /* dual role class */ + struct dual_role_phy_instance *dual_role; + /* notifiers */ struct notifier_block nb; @@ -362,6 +371,7 @@ struct smb_charger { struct delayed_work uusb_otg_work; struct delayed_work bb_removal_work; struct delayed_work usbov_dbc_work; + struct delayed_work role_reversal_check; /* alarm */ struct alarm moisture_protection_alarm; @@ -420,6 +430,7 @@ struct smb_charger { bool fcc_stepper_enable; int charge_full_cc; int cc_soc_ref; + int dr_mode; int last_cc_soc; /* workaround flag */ @@ -595,6 +606,7 @@ int smblib_get_prop_pr_swap_in_progress(struct smb_charger *chg, union power_supply_propval *val); int smblib_set_prop_pr_swap_in_progress(struct smb_charger *chg, const union power_supply_propval *val); +int smblib_force_dr_mode(struct smb_charger *chg, int mode); int smblib_get_prop_from_bms(struct smb_charger *chg, enum power_supply_property psp, union power_supply_propval *val); -- GitLab From e0aa942bd19cf994722ce2ec8423fe7db2b9a070 Mon Sep 17 00:00:00 2001 From: Allen Lu Date: Mon, 6 Jul 2020 14:07:48 +0800 Subject: [PATCH 46/96] Disable ramdump in user build Issue: PRJ8901-1292 Issue: FP3-A11#183 Change-Id: I4feb021e2b1ea9420c032df740212b250492e9a5 (cherry picked from commit bb5d2b1b82ba9a3442021ec63d4060f4bcf4f296) --- arch/arm64/configs/msm8953-perf_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index 6011a1b57b4b..c4dacd7a1e84 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -355,7 +355,7 @@ CONFIG_GPIOLIB=y CONFIG_GPIO_SYSFS=y CONFIG_GPIO_QPNP_PIN=y CONFIG_POWER_RESET_QCOM=y -CONFIG_QCOM_DLOAD_MODE=y +CONFIG_QCOM_DLOAD_MODE=n CONFIG_QPNP_FG=y CONFIG_SMB135X_CHARGER=y CONFIG_SMB1355_SLAVE_CHARGER=y -- GitLab From 4a1019f35b6f32cb81c4d582e30389cbdc5e0075 Mon Sep 17 00:00:00 2001 From: Mark Tomlinson Date: Fri, 25 Jun 2021 15:14:56 +1200 Subject: [PATCH 47/96] usb: max-3421: Prevent corruption of freed memory commit b5fdf5c6e6bee35837e160c00ac89327bdad031b upstream. The MAX-3421 USB driver remembers the state of the USB toggles for a device/endpoint. To save SPI writes, this was only done when a new device/endpoint was being used. Unfortunately, if the old device was removed, this would cause writes to freed memory. To fix this, a simpler scheme is used. The toggles are read from hardware when a URB is completed, and the toggles are always written to hardware when any URB transaction is started. This will cause a few more SPI transactions, but no causes kernel panics. Fixes: 2d53139f3162 ("Add support for using a MAX3421E chip as a host driver.") Issue: FP3SEC-163 Change-Id: Ied2bfa09a4841869778c6d4c29ef9b3ba8116a2b Cc: stable Signed-off-by: Mark Tomlinson Link: https://lore.kernel.org/r/20210625031456.8632-1-mark.tomlinson@alliedtelesis.co.nz Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 48e448d614983cda699da863e6549d9b201fabb2) --- drivers/usb/host/max3421-hcd.c | 44 +++++++++++----------------------- 1 file changed, 14 insertions(+), 30 deletions(-) diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 369869a29ebd..1654a1bc6414 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -149,8 +149,6 @@ struct max3421_hcd { */ struct urb *curr_urb; enum scheduling_pass sched_pass; - struct usb_device *loaded_dev; /* dev that's loaded into the chip */ - int loaded_epnum; /* epnum whose toggles are loaded */ int urb_done; /* > 0 -> no errors, < 0: errno */ size_t curr_len; u8 hien; @@ -488,39 +486,17 @@ max3421_set_speed(struct usb_hcd *hcd, struct usb_device *dev) * Caller must NOT hold HCD spinlock. */ static void -max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, - int force_toggles) +max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum) { - struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); - int old_epnum, same_ep, rcvtog, sndtog; - struct usb_device *old_dev; + int rcvtog, sndtog; u8 hctl; - old_dev = max3421_hcd->loaded_dev; - old_epnum = max3421_hcd->loaded_epnum; - - same_ep = (dev == old_dev && epnum == old_epnum); - if (same_ep && !force_toggles) - return; - - if (old_dev && !same_ep) { - /* save the old end-points toggles: */ - u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); - - rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1; - sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; - - /* no locking: HCD (i.e., we) own toggles, don't we? */ - usb_settoggle(old_dev, old_epnum, 0, rcvtog); - usb_settoggle(old_dev, old_epnum, 1, sndtog); - } /* setup new endpoint's toggle bits: */ rcvtog = usb_gettoggle(dev, epnum, 0); sndtog = usb_gettoggle(dev, epnum, 1); hctl = (BIT(rcvtog + MAX3421_HCTL_RCVTOG0_BIT) | BIT(sndtog + MAX3421_HCTL_SNDTOG0_BIT)); - max3421_hcd->loaded_epnum = epnum; spi_wr8(hcd, MAX3421_REG_HCTL, hctl); /* @@ -528,7 +504,6 @@ max3421_set_address(struct usb_hcd *hcd, struct usb_device *dev, int epnum, * address-assignment so it's best to just always load the * address whenever the end-point changed/was forced. */ - max3421_hcd->loaded_dev = dev; spi_wr8(hcd, MAX3421_REG_PERADDR, dev->devnum); } @@ -663,7 +638,7 @@ max3421_select_and_start_urb(struct usb_hcd *hcd) struct max3421_hcd *max3421_hcd = hcd_to_max3421(hcd); struct urb *urb, *curr_urb = NULL; struct max3421_ep *max3421_ep; - int epnum, force_toggles = 0; + int epnum; struct usb_host_endpoint *ep; struct list_head *pos; unsigned long flags; @@ -773,7 +748,6 @@ max3421_select_and_start_urb(struct usb_hcd *hcd) usb_settoggle(urb->dev, epnum, 0, 1); usb_settoggle(urb->dev, epnum, 1, 1); max3421_ep->pkt_state = PKT_STATE_SETUP; - force_toggles = 1; } else max3421_ep->pkt_state = PKT_STATE_TRANSFER; } @@ -781,7 +755,7 @@ max3421_select_and_start_urb(struct usb_hcd *hcd) spin_unlock_irqrestore(&max3421_hcd->lock, flags); max3421_ep->last_active = max3421_hcd->frame_number; - max3421_set_address(hcd, urb->dev, epnum, force_toggles); + max3421_set_address(hcd, urb->dev, epnum); max3421_set_speed(hcd, urb->dev); max3421_next_transfer(hcd, 0); return 1; @@ -1376,6 +1350,16 @@ max3421_urb_done(struct usb_hcd *hcd) status = 0; urb = max3421_hcd->curr_urb; if (urb) { + /* save the old end-points toggles: */ + u8 hrsl = spi_rd8(hcd, MAX3421_REG_HRSL); + int rcvtog = (hrsl >> MAX3421_HRSL_RCVTOGRD_BIT) & 1; + int sndtog = (hrsl >> MAX3421_HRSL_SNDTOGRD_BIT) & 1; + int epnum = usb_endpoint_num(&urb->ep->desc); + + /* no locking: HCD (i.e., we) own toggles, don't we? */ + usb_settoggle(urb->dev, epnum, 0, rcvtog); + usb_settoggle(urb->dev, epnum, 1, sndtog); + max3421_hcd->curr_urb = NULL; spin_lock_irqsave(&max3421_hcd->lock, flags); usb_hcd_unlink_urb_from_ep(hcd, urb); -- GitLab From f11890b15dab49c30ef8232adb6cbe1cefd760ea Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Tue, 17 Aug 2021 14:23:28 -0700 Subject: [PATCH 48/96] ANDROID: xt_quota2: set usersize in xt_match registration object Explicitly set what is visible to userspace Bug: 196046570 Issue: FP3SEC-162 Test: passed netd test suites Change-Id: Iacec0ef8ae290e01f1b60508d8abcd40a3653c83 Signed-off-by: Todd Kjos (cherry picked from commit df6b2e37a1f0edb73f794ffc9b9ea9fa88865440) --- net/netfilter/xt_quota2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c index 8c56ff2aa2fa..3d2ae4e49a24 100644 --- a/net/netfilter/xt_quota2.c +++ b/net/netfilter/xt_quota2.c @@ -321,6 +321,7 @@ static struct xt_match quota_mt2_reg[] __read_mostly = { .match = quota_mt2, .destroy = quota_mt2_destroy, .matchsize = sizeof(struct xt_quota_mtinfo2), + .usersize = offsetof(struct xt_quota_mtinfo2, master), .me = THIS_MODULE, }, { @@ -331,6 +332,7 @@ static struct xt_match quota_mt2_reg[] __read_mostly = { .match = quota_mt2, .destroy = quota_mt2_destroy, .matchsize = sizeof(struct xt_quota_mtinfo2), + .usersize = offsetof(struct xt_quota_mtinfo2, master), .me = THIS_MODULE, }, }; -- GitLab From b23dae587dee3be9e7735e0c5df20df7d569b11d Mon Sep 17 00:00:00 2001 From: Sam Liddicott Date: Tue, 7 Jan 2014 09:21:53 -0800 Subject: [PATCH 49/96] ANDROID: xt_quota2: remove trailing junk which might have a digit in it Make sure string only contains the characters specified by userspace. Fix cherry-picked from xtables-extensions project Bug: 196046570 Issue: FP3SEC-162 Test: passed netd test suites Fixes: 10cda83af99d ("ANDROID: netfilter: xt_quota2: adding the original quota2 from xtables-addons") Change-Id: I965448564906e5fbf0fe6d6414f44d9e257ea195 Signed-off-by: Sam Liddicott Signed-off-by: Todd Kjos (cherry picked from https://git.code.sf.net/p/xtables-addons/xtables-addons bc2bcc383c70b293bd816c29523a952ca8736fb5) (cherry picked from commit 9e79ec119d6f5f46a0c40b70095d6ec1e4a02607) --- net/netfilter/xt_quota2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/netfilter/xt_quota2.c b/net/netfilter/xt_quota2.c index 3d2ae4e49a24..7f9d9981a9e2 100644 --- a/net/netfilter/xt_quota2.c +++ b/net/netfilter/xt_quota2.c @@ -135,6 +135,8 @@ static ssize_t quota_proc_write(struct file *file, const char __user *input, if (copy_from_user(buf, input, size) != 0) return -EFAULT; buf[sizeof(buf)-1] = '\0'; + if (size < sizeof(buf)) + buf[size] = '\0'; spin_lock_bh(&e->lock); e->quota = simple_strtoull(buf, NULL, 0); -- GitLab From 65ce15a566dd742af82059687f6f89747afd6182 Mon Sep 17 00:00:00 2001 From: Willem de Bruijn Date: Mon, 2 Jan 2017 17:19:40 -0500 Subject: [PATCH 50/96] UPSTREAM: xtables: add xt_match, xt_target and data copy_to_user functions xt_entry_target, xt_entry_match and their private data may contain kernel data. Introduce helper functions xt_match_to_user, xt_target_to_user and xt_data_to_user that copy only the expected fields. These replace existing logic that calls copy_to_user on entire structs, then overwrites select fields. Private data is defined in xt_match and xt_target. All matches and targets that maintain kernel data store this at the tail of their private structure. Extend xt_match and xt_target with .usersize to limit how many bytes of data are copied. The remainder is cleared. If compatsize is specified, usersize can only safely be used if all fields up to usersize use platform-independent types. Otherwise, the compat_to_user callback must be defined. This patch does not yet enable the support logic. Bug: 120612905 Issue: FP3SEC-162 Change-Id: I71ca0160d0ad7b8ee97b412c1e278b75b297bd54 Signed-off-by: Willem de Bruijn Signed-off-by: Pablo Neira Ayuso Signed-off-by: Hridya Valsaraju (cherry picked from commit f32815d21d4d8287336fb9cef4d2d9e0866214c2) (cherry picked from commit a1a9b3693f8a981651d61c5db73750bcb594007a) --- include/linux/netfilter/x_tables.h | 9 +++++ net/netfilter/x_tables.c | 54 ++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index 69111fa2e578..ee62bca5e0af 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h @@ -139,6 +139,7 @@ struct xt_match { const char *table; unsigned int matchsize; + unsigned int usersize; #ifdef CONFIG_COMPAT unsigned int compatsize; #endif @@ -179,6 +180,7 @@ struct xt_target { const char *table; unsigned int targetsize; + unsigned int usersize; #ifdef CONFIG_COMPAT unsigned int compatsize; #endif @@ -261,6 +263,13 @@ int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto, int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto, bool inv_proto); +int xt_match_to_user(const struct xt_entry_match *m, + struct xt_entry_match __user *u); +int xt_target_to_user(const struct xt_entry_target *t, + struct xt_entry_target __user *u); +int xt_data_to_user(void __user *dst, const void *src, + int usersize, int size); + void *xt_copy_counters_from_user(const void __user *user, unsigned int len, struct xt_counters_info *info, bool compat); diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index e065140d0c93..1db69888cc14 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c @@ -267,6 +267,60 @@ struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision) } EXPORT_SYMBOL_GPL(xt_request_find_target); + +static int xt_obj_to_user(u16 __user *psize, u16 size, + void __user *pname, const char *name, + u8 __user *prev, u8 rev) +{ + if (put_user(size, psize)) + return -EFAULT; + if (copy_to_user(pname, name, strlen(name) + 1)) + return -EFAULT; + if (put_user(rev, prev)) + return -EFAULT; + + return 0; +} + +#define XT_OBJ_TO_USER(U, K, TYPE, C_SIZE) \ + xt_obj_to_user(&U->u.TYPE##_size, C_SIZE ? : K->u.TYPE##_size, \ + U->u.user.name, K->u.kernel.TYPE->name, \ + &U->u.user.revision, K->u.kernel.TYPE->revision) + +int xt_data_to_user(void __user *dst, const void *src, + int usersize, int size) +{ + usersize = usersize ? : size; + if (copy_to_user(dst, src, usersize)) + return -EFAULT; + if (usersize != size && clear_user(dst + usersize, size - usersize)) + return -EFAULT; + + return 0; +} +EXPORT_SYMBOL_GPL(xt_data_to_user); + +#define XT_DATA_TO_USER(U, K, TYPE, C_SIZE) \ + xt_data_to_user(U->data, K->data, \ + K->u.kernel.TYPE->usersize, \ + C_SIZE ? : K->u.kernel.TYPE->TYPE##size) + +int xt_match_to_user(const struct xt_entry_match *m, + struct xt_entry_match __user *u) +{ + return XT_OBJ_TO_USER(u, m, match, 0) || + XT_DATA_TO_USER(u, m, match, 0); +} +EXPORT_SYMBOL_GPL(xt_match_to_user); + +int xt_target_to_user(const struct xt_entry_target *t, + struct xt_entry_target __user *u) +{ + return XT_OBJ_TO_USER(u, t, target, 0) || + XT_DATA_TO_USER(u, t, target, 0); +} +EXPORT_SYMBOL_GPL(xt_target_to_user); + static int match_revfn(u8 af, const char *name, u8 revision, int *bestp) { const struct xt_match *m; -- GitLab From 06bb7d1c5ff29ca40534d81510e1288058550a1b Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 13 Jul 2021 17:49:23 +0200 Subject: [PATCH 51/96] seq_file: disallow extremely large seq buffer allocations commit 8cae8cd89f05f6de223d63e6d15e31c8ba9cf53b upstream. There is no reasonable need for a buffer larger than this, and it avoids int overflow pitfalls. Fixes: 058504edd026 ("fs/seq_file: fallback to vmalloc allocation") Issue: FP3SEC-160 Change-Id: I9146bf107c54eec606b5ce468e22d47674ddf14e Suggested-by: Al Viro Reported-by: Qualys Security Advisory Signed-off-by: Eric Sandeen Cc: stable@kernel.org Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 82280f83d873caccddeeaf6de343762e79969f52) --- fs/seq_file.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/seq_file.c b/fs/seq_file.c index 368bfb92b115..3ade39e02bb7 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c @@ -28,6 +28,9 @@ static void *seq_buf_alloc(unsigned long size) void *buf; gfp_t gfp = GFP_KERNEL; + if (unlikely(size > MAX_RW_COUNT)) + return NULL; + /* * For high order allocations, use __GFP_NORETRY to avoid oom-killing - * it's better to fall back to vmalloc() than to kill things. For small -- GitLab From ced2e1a2c599b6c6a4e16d0dbf89984de94452b0 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Thu, 4 Feb 2021 18:32:31 -0800 Subject: [PATCH 52/96] mm: thp: fix MADV_REMOVE deadlock on shmem THP commit 1c2f67308af4c102b4e1e6cd6f69819ae59408e0 upstream. Sergey reported deadlock between kswapd correctly doing its usual lock_page(page) followed by down_read(page->mapping->i_mmap_rwsem), and madvise(MADV_REMOVE) on an madvise(MADV_HUGEPAGE) area doing down_write(page->mapping->i_mmap_rwsem) followed by lock_page(page). This happened when shmem_fallocate(punch hole)'s unmap_mapping_range() reaches zap_pmd_range()'s call to __split_huge_pmd(). The same deadlock could occur when partially truncating a mapped huge tmpfs file, or using fallocate(FALLOC_FL_PUNCH_HOLE) on it. __split_huge_pmd()'s page lock was added in 5.8, to make sure that any concurrent use of reuse_swap_page() (holding page lock) could not catch the anon THP's mapcounts and swapcounts while they were being split. Fortunately, reuse_swap_page() is never applied to a shmem or file THP (not even by khugepaged, which checks PageSwapCache before calling), and anonymous THPs are never created in shmem or file areas: so that __split_huge_pmd()'s page lock can only be necessary for anonymous THPs, on which there is no risk of deadlock with i_mmap_rwsem. Link: https://lkml.kernel.org/r/alpine.LSU.2.11.2101161409470.2022@eggly.anvils Fixes: c444eb564fb1 ("mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked()") Signed-off-by: Hugh Dickins Reported-by: Sergey Senozhatsky Reviewed-by: Andrea Arcangeli Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Greg Kroah-Hartman Issue: FP3SEC-44 (cherry picked from commit 332293a2301fde82bc41b359f870a96871764aaa) Change-Id: Ifaa50890b2ee496d64c797f748657e0fb86cebe9 (cherry picked from commit 2fbeba3d9c2fca5e354150b6da4a53afcae64585) --- mm/huge_memory.c | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index fad4a0ca903c..fac621f1b29c 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1755,6 +1755,8 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, spinlock_t *ptl; struct mm_struct *mm = vma->vm_mm; unsigned long haddr = address & HPAGE_PMD_MASK; + bool do_unlock_page = false; + pmd_t _pmd; mmu_notifier_invalidate_range_start(mm, haddr, haddr + HPAGE_PMD_SIZE); ptl = pmd_lock(mm, pmd); @@ -1764,11 +1766,41 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, * pmd against. Otherwise we can end up replacing wrong page. */ VM_BUG_ON(freeze && !page); - if (page && page != pmd_page(*pmd)) - goto out; + if (page) { + VM_WARN_ON_ONCE(!PageLocked(page)); + if (page != pmd_page(*pmd)) + goto out; + } +repeat: if (pmd_trans_huge(*pmd)) { - page = pmd_page(*pmd); + if (!page) { + page = pmd_page(*pmd); + /* + * An anonymous page must be locked, to ensure that a + * concurrent reuse_swap_page() sees stable mapcount; + * but reuse_swap_page() is not used on shmem or file, + * and page lock must not be taken when zap_pmd_range() + * calls __split_huge_pmd() while i_mmap_lock is held. + */ + if (PageAnon(page)) { + if (unlikely(!trylock_page(page))) { + get_page(page); + _pmd = *pmd; + spin_unlock(ptl); + lock_page(page); + spin_lock(ptl); + if (unlikely(!pmd_same(*pmd, _pmd))) { + unlock_page(page); + put_page(page); + page = NULL; + goto repeat; + } + put_page(page); + } + do_unlock_page = true; + } + } if (PageMlocked(page)) clear_page_mlock(page); } else if (!pmd_devmap(*pmd)) @@ -1776,6 +1808,8 @@ void __split_huge_pmd(struct vm_area_struct *vma, pmd_t *pmd, __split_huge_pmd_locked(vma, pmd, haddr, freeze); out: spin_unlock(ptl); + if (do_unlock_page) + unlock_page(page); mmu_notifier_invalidate_range_end(mm, haddr, haddr + HPAGE_PMD_SIZE); } -- GitLab From 4b2937ffcedcf356b6412f6b736d61b899a5db17 Mon Sep 17 00:00:00 2001 From: Shreyansh Chouhan Date: Sat, 21 Aug 2021 12:44:24 +0530 Subject: [PATCH 53/96] ip_gre: add validation for csum_start Validate csum_start in gre_handle_offloads before we call _gre_xmit so that we do not crash later when the csum_start value is used in the lco_csum function call. This patch deals with ipv4 code. Fixes: c54419321455 ("GRE: Refactor GRE tunneling code.") Issue: FP3SEC-183 Change-Id: If4c3793676c62aac8b9f3e3027e1452428e2cce0 Reported-by: syzbot+ff8e1b9f2f36481e2efc@syzkaller.appspotmail.com Signed-off-by: Shreyansh Chouhan Reviewed-by: Willem de Bruijn Signed-off-by: David S. Miller (cherry picked from commit 1d011c4803c72f3907eccfc1ec63caefb852fcbf) (cherry picked from commit ca6f4e1d306f978eeb64079d4421aedfbfda5b4a) --- net/ipv4/ip_gre.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index 9609ad71dd26..fe1801d9f059 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -353,6 +353,8 @@ static void __gre_xmit(struct sk_buff *skb, struct net_device *dev, static int gre_handle_offloads(struct sk_buff *skb, bool csum) { + if (csum && skb_checksum_start(skb) < skb->data) + return -EINVAL; return iptunnel_handle_offloads(skb, csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); } -- GitLab From 534a5100cabc767283a3217727f1f5739f273a50 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 9 Sep 2020 22:25:06 -0400 Subject: [PATCH 54/96] epoll: do not insert into poll queues until all sanity checks are done Issue: FP3SEC-211 Change-Id: Ic72328e7ef18af5f0b6414d1097a9096431a9ecc Signed-off-by: Al Viro (cherry picked from commit f8d4f44df056c5b504b0d49683fb7279218fd207) (cherry picked from commit c05f972c63902e2baa6bfdc98acf9ff9e62e5e33) --- fs/eventpoll.c | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 4bcbab679afb..0824914e80a7 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c @@ -1333,6 +1333,22 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, RCU_INIT_POINTER(epi->ws, NULL); } + /* Add the current item to the list of active epoll hook for this file */ + spin_lock(&tfile->f_lock); + list_add_tail_rcu(&epi->fllink, &tfile->f_ep_links); + spin_unlock(&tfile->f_lock); + + /* + * Add the current item to the RB tree. All RB tree operations are + * protected by "mtx", and ep_insert() is called with "mtx" held. + */ + ep_rbtree_insert(ep, epi); + + /* now check if we've created too many backpaths */ + error = -EINVAL; + if (full_check && reverse_path_check()) + goto error_remove_epi; + /* Initialize the poll table using the queue callback */ epq.epi = epi; init_poll_funcptr(&epq.pt, ep_ptable_queue_proc); @@ -1355,22 +1371,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, if (epi->nwait < 0) goto error_unregister; - /* Add the current item to the list of active epoll hook for this file */ - spin_lock(&tfile->f_lock); - list_add_tail_rcu(&epi->fllink, &tfile->f_ep_links); - spin_unlock(&tfile->f_lock); - - /* - * Add the current item to the RB tree. All RB tree operations are - * protected by "mtx", and ep_insert() is called with "mtx" held. - */ - ep_rbtree_insert(ep, epi); - - /* now check if we've created too many backpaths */ - error = -EINVAL; - if (full_check && reverse_path_check()) - goto error_remove_epi; - /* We have to drop the new item inside our item list to keep track of it */ spin_lock_irqsave(&ep->lock, flags); @@ -1396,6 +1396,8 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, return 0; +error_unregister: + ep_unregister_pollwait(ep, epi); error_remove_epi: spin_lock(&tfile->f_lock); list_del_rcu(&epi->fllink); @@ -1403,9 +1405,6 @@ static int ep_insert(struct eventpoll *ep, struct epoll_event *event, rb_erase(&epi->rbn, &ep->rbr); -error_unregister: - ep_unregister_pollwait(ep, epi); - /* * We need to do this because an event could have been arrived on some * allocated wait queue. Note that we don't care about the ep->ovflist -- GitLab From 8f9d818eefe03b58ba6e7b9f3f1472ffbc3bc4f9 Mon Sep 17 00:00:00 2001 From: Paras Nagda Date: Thu, 5 Aug 2021 18:01:38 +0530 Subject: [PATCH 55/96] Revert "uapi/media: Update yuv buffer size based on hardware requirement" This reverts commit e265d46203a6a01abb9824933dee5641f4aff428. Issue: FP3-A11#89 Test: run cts -m CtsMediaTestCases -t android.media.cts.VideoEncoderTest#testGoogVP9* Change-Id: If32289e81e4eb825cbcbadb785b2da8fb7b5874e Signed-off-by: Paras Nagda --- include/uapi/media/msm_media_info.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/include/uapi/media/msm_media_info.h b/include/uapi/media/msm_media_info.h index d784d71a6c91..19ea81259207 100644 --- a/include/uapi/media/msm_media_info.h +++ b/include/uapi/media/msm_media_info.h @@ -1276,6 +1276,7 @@ static inline unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height) static inline unsigned int VENUS_BUFFER_SIZE( int color_fmt, int width, int height) { + const unsigned int extra_size = VENUS_EXTRADATA_SIZE(width, height); unsigned int uv_alignment = 0, size = 0; unsigned int w_alignment = 512; unsigned int y_plane, uv_plane, y_stride, @@ -1304,7 +1305,8 @@ static inline unsigned int VENUS_BUFFER_SIZE( uv_alignment = 4096; y_plane = y_stride * y_sclines; uv_plane = uv_stride * uv_sclines + uv_alignment; - size = y_plane + uv_plane; + size = y_plane + uv_plane + + MSM_MEDIA_MAX(extra_size, 8 * y_stride); size = MSM_MEDIA_ALIGN(size, 4096); /* Additional size to cover last row of non-aligned frame */ @@ -1319,7 +1321,8 @@ static inline unsigned int VENUS_BUFFER_SIZE( uv_alignment = 4096; y_plane = y_stride * y_sclines; uv_plane = uv_stride * uv_sclines + uv_alignment; - size = y_plane + uv_plane; + size = y_plane + uv_plane + + MSM_MEDIA_MAX(extra_size, 8 * y_stride); size = MSM_MEDIA_ALIGN(size, 4096); break; case COLOR_FMT_NV12_MVTB: @@ -1327,7 +1330,7 @@ static inline unsigned int VENUS_BUFFER_SIZE( y_plane = y_stride * y_sclines; uv_plane = uv_stride * uv_sclines + uv_alignment; size = y_plane + uv_plane; - size = 2 * size; + size = 2 * size + extra_size; size = MSM_MEDIA_ALIGN(size, 4096); break; case COLOR_FMT_NV12_UBWC: @@ -1347,7 +1350,8 @@ static inline unsigned int VENUS_BUFFER_SIZE( uv_meta_scanlines, 4096); size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane + - uv_meta_plane)*2; + uv_meta_plane)*2 + + MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride); size = MSM_MEDIA_ALIGN(size, 4096); /* Additional size to cover last row of non-aligned frame */ @@ -1370,7 +1374,8 @@ static inline unsigned int VENUS_BUFFER_SIZE( uv_meta_scanlines, 4096); size = y_ubwc_plane + uv_ubwc_plane + y_meta_plane + - uv_meta_plane; + uv_meta_plane + + MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride); size = MSM_MEDIA_ALIGN(size, 4096); break; case COLOR_FMT_P010_UBWC: -- GitLab From ab8dce8a4fafb72ab0c1dec128c84e499b0d08ec Mon Sep 17 00:00:00 2001 From: Paras Nagda Date: Mon, 6 Sep 2021 11:48:18 +0530 Subject: [PATCH 56/96] Revert "uapi/media: Support for Interlaced UBWC format" This reverts commit 929a791f013498aeb7f1105dd8fabb1a2c39d431. Issue: FP3-A11#115 Test: run vts -m VtsHalMediaOmxV1_0TargetVideoDecTest -t PerInstance/VideoDecHidlTest#AdaptivePlaybackTest/default_OMX_qcom_video_decoder_mpeg2_video_decoder_mpeg2_15 Change-Id: I02ebb8706809de811e37be0e13fc3b654d45168e --- include/uapi/media/msm_media_info.h | 286 +--------------------------- 1 file changed, 4 insertions(+), 282 deletions(-) diff --git a/include/uapi/media/msm_media_info.h b/include/uapi/media/msm_media_info.h index 19ea81259207..1de968e8055d 100644 --- a/include/uapi/media/msm_media_info.h +++ b/include/uapi/media/msm_media_info.h @@ -149,12 +149,7 @@ enum color_fmts { * + 2*(UV_Stride * UV_Scanlines) + Extradata), 4096) */ COLOR_FMT_NV12_MVTB, - /* - * The buffer can be of 2 types: - * (1) Venus NV12 UBWC Progressive - * (2) Venus NV12 UBWC Interlaced - * - * (1) Venus NV12 UBWC Progressive Buffer Format: + /* Venus NV12 UBWC: * Compressed Macro-tile format for NV12. * Contains 4 planes in the following order - * (A) Y_Meta_Plane @@ -240,186 +235,6 @@ enum color_fmts { * Total size = align( Y_UBWC_Plane_size + UV_UBWC_Plane_size + * Y_Meta_Plane_size + UV_Meta_Plane_size * + max(Extradata, Y_Stride * 48), 4096) - * - * - * (2) Venus NV12 UBWC Interlaced Buffer Format: - * Compressed Macro-tile format for NV12 interlaced. - * Contains 8 planes in the following order - - * (A) Y_Meta_Top_Field_Plane - * (B) Y_UBWC_Top_Field_Plane - * (C) UV_Meta_Top_Field_Plane - * (D) UV_UBWC_Top_Field_Plane - * (E) Y_Meta_Bottom_Field_Plane - * (F) Y_UBWC_Bottom_Field_Plane - * (G) UV_Meta_Bottom_Field_Plane - * (H) UV_UBWC_Bottom_Field_Plane - * Y_Meta_Top_Field_Plane consists of meta information to decode - * compressed tile data for Y_UBWC_Top_Field_Plane. - * Y_UBWC_Top_Field_Plane consists of Y data in compressed macro-tile - * format for top field of an interlaced frame. - * UBWC decoder block will use the Y_Meta_Top_Field_Plane data together - * with Y_UBWC_Top_Field_Plane data to produce loss-less uncompressed - * 8 bit Y samples for top field of an interlaced frame. - * - * UV_Meta_Top_Field_Plane consists of meta information to decode - * compressed tile data in UV_UBWC_Top_Field_Plane. - * UV_UBWC_Top_Field_Plane consists of UV data in compressed macro-tile - * format for top field of an interlaced frame. - * UBWC decoder block will use UV_Meta_Top_Field_Plane data together - * with UV_UBWC_Top_Field_Plane data to produce loss-less uncompressed - * 8 bit subsampled color difference samples for top field of an - * interlaced frame. - * - * Each tile in Y_UBWC_Top_Field_Plane/UV_UBWC_Top_Field_Plane is - * independently decodable and randomly accessible. There is no - * dependency between tiles. - * - * Y_Meta_Bottom_Field_Plane consists of meta information to decode - * compressed tile data for Y_UBWC_Bottom_Field_Plane. - * Y_UBWC_Bottom_Field_Plane consists of Y data in compressed macro-tile - * format for bottom field of an interlaced frame. - * UBWC decoder block will use the Y_Meta_Bottom_Field_Plane data - * together with Y_UBWC_Bottom_Field_Plane data to produce loss-less - * uncompressed 8 bit Y samples for bottom field of an interlaced frame. - * - * UV_Meta_Bottom_Field_Plane consists of meta information to decode - * compressed tile data in UV_UBWC_Bottom_Field_Plane. - * UV_UBWC_Bottom_Field_Plane consists of UV data in compressed - * macro-tile format for bottom field of an interlaced frame. - * UBWC decoder block will use UV_Meta_Bottom_Field_Plane data together - * with UV_UBWC_Bottom_Field_Plane data to produce loss-less - * uncompressed 8 bit subsampled color difference samples for bottom - * field of an interlaced frame. - * - * Each tile in Y_UBWC_Bottom_Field_Plane/UV_UBWC_Bottom_Field_Plane is - * independently decodable and randomly accessible. There is no - * dependency between tiles. - * - * <-----Y_TF_Meta_Stride----> - * <-------- Width ------> - * M M M M M M M M M M M M . . ^ ^ - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . Half_height | - * M M M M M M M M M M M M . . | Meta_Y_TF_Scanlines - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . V | - * . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * . . . . . . . . . . . . . . V - * <-Compressed tile Y_TF Stride-> - * <------- Width -------> - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_TF_Scanlines - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | - * . . . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * . . . . . . . . . . . . . . . . V - * <----UV_TF_Meta_Stride----> - * M M M M M M M M M M M M . . ^ - * M M M M M M M M M M M M . . | - * M M M M M M M M M M M M . . | - * M M M M M M M M M M M M . . M_UV_TF_Scanlines - * . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . V - * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * <-Compressed tile UV_TF Stride-> - * U* V* U* V* U* V* U* V* . . . . ^ - * U* V* U* V* U* V* U* V* . . . . | - * U* V* U* V* U* V* U* V* . . . . | - * U* V* U* V* U* V* U* V* . . . . UV_TF_Scanlines - * . . . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . . . V - * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * <-----Y_BF_Meta_Stride----> - * <-------- Width ------> - * M M M M M M M M M M M M . . ^ ^ - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . Half_height | - * M M M M M M M M M M M M . . | Meta_Y_BF_Scanlines - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . | | - * M M M M M M M M M M M M . . V | - * . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * . . . . . . . . . . . . . . V - * <-Compressed tile Y_BF Stride-> - * <------- Width -------> - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . ^ ^ - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . Half_height | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | Macro_tile_Y_BF_Scanlines - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . | | - * Y* Y* Y* Y* Y* Y* Y* Y* . . . . V | - * . . . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * . . . . . . . . . . . . . . . . V - * <----UV_BF_Meta_Stride----> - * M M M M M M M M M M M M . . ^ - * M M M M M M M M M M M M . . | - * M M M M M M M M M M M M . . | - * M M M M M M M M M M M M . . M_UV_BF_Scanlines - * . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . V - * . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * <-Compressed tile UV_BF Stride-> - * U* V* U* V* U* V* U* V* . . . . ^ - * U* V* U* V* U* V* U* V* . . . . | - * U* V* U* V* U* V* U* V* . . . . | - * U* V* U* V* U* V* U* V* . . . . UV_BF_Scanlines - * . . . . . . . . . . . . . . . . | - * . . . . . . . . . . . . . . . . V - * . . . . . . . . . . . . . . . . -------> Buffer size aligned to 4k - * - * Half_height = (Height+1)>>1 - * Y_TF_Stride = align(Width, 128) - * UV_TF_Stride = align(Width, 128) - * Y_TF_Scanlines = align(Half_height, 32) - * UV_TF_Scanlines = align((Half_height+1)/2, 32) - * Y_UBWC_TF_Plane_size = align(Y_TF_Stride * Y_TF_Scanlines, 4096) - * UV_UBWC_TF_Plane_size = align(UV_TF_Stride * UV_TF_Scanlines, 4096) - * Y_TF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) - * Y_TF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16) - * Y_TF_Meta_Plane_size = - * align(Y_TF_Meta_Stride * Y_TF_Meta_Scanlines, 4096) - * UV_TF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) - * UV_TF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16) - * UV_TF_Meta_Plane_size = - * align(UV_TF_Meta_Stride * UV_TF_Meta_Scanlines, 4096) - * Y_BF_Stride = align(Width, 128) - * UV_BF_Stride = align(Width, 128) - * Y_BF_Scanlines = align(Half_height, 32) - * UV_BF_Scanlines = align((Half_height+1)/2, 32) - * Y_UBWC_BF_Plane_size = align(Y_BF_Stride * Y_BF_Scanlines, 4096) - * UV_UBWC_BF_Plane_size = align(UV_BF_Stride * UV_BF_Scanlines, 4096) - * Y_BF_Meta_Stride = align(roundup(Width, Y_TileWidth), 64) - * Y_BF_Meta_Scanlines = align(roundup(Half_height, Y_TileHeight), 16) - * Y_BF_Meta_Plane_size = - * align(Y_BF_Meta_Stride * Y_BF_Meta_Scanlines, 4096) - * UV_BF_Meta_Stride = align(roundup(Width, UV_TileWidth), 64) - * UV_BF_Meta_Scanlines = align(roundup(Half_height, UV_TileHeight), 16) - * UV_BF_Meta_Plane_size = - * align(UV_BF_Meta_Stride * UV_BF_Meta_Scanlines, 4096) - * Extradata = 8k - * - * Total size = align( Y_UBWC_TF_Plane_size + UV_UBWC_TF_Plane_size + - * Y_TF_Meta_Plane_size + UV_TF_Meta_Plane_size + - * Y_UBWC_BF_Plane_size + UV_UBWC_BF_Plane_size + - * Y_BF_Meta_Plane_size + UV_BF_Meta_Plane_size + - * + max(Extradata, Y_TF_Stride * 48), 4096) */ COLOR_FMT_NV12_UBWC, /* Venus NV12 10-bit UBWC: @@ -860,13 +675,6 @@ static inline unsigned int VENUS_EXTRADATA_SIZE(int width, int height) return 16 * 1024; } -/* - * Function arguments: - * @color_fmt - * @width - * Progressive: width - * Interlaced: width - */ static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width) { unsigned int alignment, stride = 0; @@ -906,13 +714,6 @@ static inline unsigned int VENUS_Y_STRIDE(int color_fmt, int width) return stride; } -/* - * Function arguments: - * @color_fmt - * @width - * Progressive: width - * Interlaced: width - */ static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width) { unsigned int alignment, stride = 0; @@ -952,13 +753,6 @@ static inline unsigned int VENUS_UV_STRIDE(int color_fmt, int width) return stride; } -/* - * Function arguments: - * @color_fmt - * @height - * Progressive: height - * Interlaced: (height+1)>>1 - */ static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) { unsigned int alignment, sclines = 0; @@ -989,13 +783,6 @@ static inline unsigned int VENUS_Y_SCANLINES(int color_fmt, int height) return sclines; } -/* - * Function arguments: - * @color_fmt - * @height - * Progressive: height - * Interlaced: (height+1)>>1 - */ static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) { unsigned int alignment, sclines = 0; @@ -1022,19 +809,12 @@ static inline unsigned int VENUS_UV_SCANLINES(int color_fmt, int height) goto invalid_input; } - sclines = MSM_MEDIA_ALIGN((height+1)>>1, alignment); + sclines = MSM_MEDIA_ALIGN(height / 2, alignment); invalid_input: return sclines; } -/* - * Function arguments: - * @color_fmt - * @width - * Progressive: width - * Interlaced: width - */ static inline unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) { int y_tile_width = 0, y_meta_stride = 0; @@ -1061,13 +841,6 @@ static inline unsigned int VENUS_Y_META_STRIDE(int color_fmt, int width) return y_meta_stride; } -/* - * Function arguments: - * @color_fmt - * @height - * Progressive: height - * Interlaced: (height+1)>>1 - */ static inline unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) { int y_tile_height = 0, y_meta_scanlines = 0; @@ -1094,13 +867,6 @@ static inline unsigned int VENUS_Y_META_SCANLINES(int color_fmt, int height) return y_meta_scanlines; } -/* - * Function arguments: - * @color_fmt - * @width - * Progressive: width - * Interlaced: width - */ static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) { int uv_tile_width = 0, uv_meta_stride = 0; @@ -1120,20 +886,13 @@ static inline unsigned int VENUS_UV_META_STRIDE(int color_fmt, int width) goto invalid_input; } - uv_meta_stride = MSM_MEDIA_ROUNDUP((width+1)>>1, uv_tile_width); + uv_meta_stride = MSM_MEDIA_ROUNDUP(width / 2, uv_tile_width); uv_meta_stride = MSM_MEDIA_ALIGN(uv_meta_stride, 64); invalid_input: return uv_meta_stride; } -/* - * Function arguments: - * @color_fmt - * @height - * Progressive: height - * Interlaced: (height+1)>>1 - */ static inline unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) { int uv_tile_height = 0, uv_meta_scanlines = 0; @@ -1153,7 +912,7 @@ static inline unsigned int VENUS_UV_META_SCANLINES(int color_fmt, int height) goto invalid_input; } - uv_meta_scanlines = MSM_MEDIA_ROUNDUP((height+1)>>1, uv_tile_height); + uv_meta_scanlines = MSM_MEDIA_ROUNDUP(height / 2, uv_tile_height); uv_meta_scanlines = MSM_MEDIA_ALIGN(uv_meta_scanlines, 16); invalid_input: @@ -1263,16 +1022,6 @@ static inline unsigned int VENUS_RGB_META_SCANLINES(int color_fmt, int height) return rgb_meta_scanlines; } -/* - * Function arguments: - * @color_fmt - * @width - * Progressive: width - * Interlaced: width - * @height - * Progressive: height - * Interlaced: height - */ static inline unsigned int VENUS_BUFFER_SIZE( int color_fmt, int width, int height) { @@ -1334,33 +1083,6 @@ static inline unsigned int VENUS_BUFFER_SIZE( size = MSM_MEDIA_ALIGN(size, 4096); break; case COLOR_FMT_NV12_UBWC: - y_sclines = VENUS_Y_SCANLINES(color_fmt, (height+1)>>1); - y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); - uv_sclines = VENUS_UV_SCANLINES(color_fmt, (height+1)>>1); - uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); - y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width); - y_meta_scanlines = - VENUS_Y_META_SCANLINES(color_fmt, (height+1)>>1); - y_meta_plane = MSM_MEDIA_ALIGN( - y_meta_stride * y_meta_scanlines, 4096); - uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width); - uv_meta_scanlines = - VENUS_UV_META_SCANLINES(color_fmt, (height+1)>>1); - uv_meta_plane = MSM_MEDIA_ALIGN(uv_meta_stride * - uv_meta_scanlines, 4096); - - size = (y_ubwc_plane + uv_ubwc_plane + y_meta_plane + - uv_meta_plane)*2 + - MSM_MEDIA_MAX(extra_size + 8192, 48 * y_stride); - size = MSM_MEDIA_ALIGN(size, 4096); - - /* Additional size to cover last row of non-aligned frame */ - if (width >= 2400 && height >= 2400) { - size += MSM_MEDIA_ALIGN(width, w_alignment) * - w_alignment; - size = MSM_MEDIA_ALIGN(size, 4096); - } - break; case COLOR_FMT_NV12_BPP10_UBWC: y_ubwc_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096); uv_ubwc_plane = MSM_MEDIA_ALIGN(uv_stride * uv_sclines, 4096); -- GitLab From ccbc889b98b98aac45ebd5d45a068bd52528cf0c Mon Sep 17 00:00:00 2001 From: weikao Date: Fri, 28 Aug 2020 13:49:39 +0800 Subject: [PATCH 57/96] Fix image capture during video recording Fixes issue: During video recording, still picture captured shows full green screen. Issue: PRJ8901-1488 Change-Id: I482ca772e5bad60e47b06dfb625db1417eba593f (cherry picked from commit 75bcf6833da5769814e7dfe9547f628cc33fca68) --- .../platform/msm/camera_v2/isp/msm_buf_mgr.c | 56 +++++++++++++++++++ .../platform/msm/camera_v2/isp/msm_buf_mgr.h | 3 + .../msm/camera_v2/isp/msm_isp_axi_util.c | 2 +- 3 files changed, 60 insertions(+), 1 deletion(-) mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h mode change 100644 => 100755 drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c index ed7120879862..5806ab15ddda 100644 --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.c @@ -757,6 +757,61 @@ static int msm_isp_buf_divert(struct msm_isp_buf_mgr *buf_mgr, return 0; } +static int msm_isp_buf_err(struct msm_isp_buf_mgr *buf_mgr, + uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id, uint32_t output_format) +{ + int rc = 0; + unsigned long flags; + struct msm_isp_bufq *bufq = NULL; + struct msm_isp_buffer *buf_info = NULL; + enum msm_isp_buffer_state state; + + bufq = msm_isp_get_bufq(buf_mgr, bufq_handle); + if (!bufq) { + pr_err("Invalid bufq\n"); + return -EINVAL; + } + + buf_info = msm_isp_get_buf_ptr(buf_mgr, bufq_handle, buf_index); + if (!buf_info) { + pr_err("%s: buf not found\n", __func__); + return -EINVAL; + } + + spin_lock_irqsave(&bufq->bufq_lock, flags); + state = buf_info->state; + + if (BUF_SRC(bufq->stream_id) == MSM_ISP_BUFFER_SRC_HAL) { + if (state == MSM_ISP_BUFFER_STATE_DEQUEUED) { + buf_info->state = MSM_ISP_BUFFER_STATE_DISPATCHED; + spin_unlock_irqrestore(&bufq->bufq_lock, flags); + buf_mgr->vb2_ops->buf_error(buf_info->vb2_v4l2_buf, + bufq->session_id, bufq->stream_id, + frame_id, tv, output_format); + } else { + spin_unlock_irqrestore(&bufq->bufq_lock, flags); + } + goto done; + } + + /* + * For native buffer put the diverted buffer back to queue since caller + * is not going to send it to CPP, this is error case like + * drop_frame/empty_buffer + */ + if (state == MSM_ISP_BUFFER_STATE_DIVERTED) { + buf_info->state = MSM_ISP_BUFFER_STATE_PREPARED; + rc = msm_isp_put_buf_unsafe(buf_mgr, buf_info->bufq_handle, + buf_info->buf_idx); + if (rc < 0) + pr_err("%s: Buf put failed\n", __func__); + } + spin_unlock_irqrestore(&bufq->bufq_lock, flags); +done: + return rc; +} + static int msm_isp_buf_done(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id, uint32_t output_format) @@ -1510,6 +1565,7 @@ static struct msm_isp_buf_ops isp_buf_ops = { .buf_mgr_debug = msm_isp_buf_mgr_debug, .get_bufq = msm_isp_get_bufq, .buf_divert = msm_isp_buf_divert, + .buf_err = msm_isp_buf_err, }; int msm_isp_create_isp_buf_mgr( diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h old mode 100644 new mode 100755 index 4ea6dd6c2210..6205b109f52b --- a/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h +++ b/drivers/media/platform/msm/camera_v2/isp/msm_buf_mgr.h @@ -180,6 +180,9 @@ struct msm_isp_buf_ops { int (*buf_divert)(struct msm_isp_buf_mgr *buf_mgr, uint32_t bufq_handle, uint32_t buf_index, struct timeval *tv, uint32_t frame_id); + int (*buf_err)(struct msm_isp_buf_mgr *buf_mgr, + uint32_t bufq_handle, uint32_t buf_index, + struct timeval *tv, uint32_t frame_id, uint32_t output_format); }; struct msm_isp_buf_mgr { diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c old mode 100644 new mode 100755 index 63ae9d1ea71a..54812dc8c41b --- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c +++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c @@ -3600,7 +3600,7 @@ static int msm_isp_return_empty_buffer(struct vfe_device *vfe_dev, buf->buf_debug.put_state[buf->buf_debug.put_state_last] = MSM_ISP_BUFFER_STATE_DROP_REG; buf->buf_debug.put_state_last ^= 1; - rc = vfe_dev->buf_mgr->ops->buf_done(vfe_dev->buf_mgr, + rc = vfe_dev->buf_mgr->ops->buf_err(vfe_dev->buf_mgr, buf->bufq_handle, buf->buf_idx, ×tamp.buf_time, frame_id, stream_info->runtime_output_format); -- GitLab From e29004c4797098988e91121a23ab1c31bf7734bc Mon Sep 17 00:00:00 2001 From: jinjiawu Date: Wed, 9 Dec 2020 18:30:05 +0800 Subject: [PATCH 58/96] Upgrade himax fw CID0804_D02_C15 for Ghost touch Upgrade Himax to improve ghost touch issue by new feature in auto calibration. Change-Id: Ife345a6b35b2c7f770bc7d0c360b6199ec56ef2d (cherry picked from commit 0206504f21256d73b1f10aa5162429262932e25d) --- .../FP_DJN_Arima_CID0804_D02_C15_20201209.i | 4096 +++++++++++++++++ .../hxchipset83112b/himax_common.c | 2 +- 2 files changed, 4097 insertions(+), 1 deletion(-) create mode 100755 drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i diff --git a/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i new file mode 100755 index 000000000000..e902408d3f6d --- /dev/null +++ b/drivers/input/touchscreen/hxchipset83112b/FP_DJN_Arima_CID0804_D02_C15_20201209.i @@ -0,0 +1,4096 @@ +0x48,0x00,0x01,0x94,0x48,0x00,0x00,0x30,0x48,0x00,0x00,0x2E,0x48,0x00,0x00,0x2C, +0x48,0x00,0x00,0x2A,0x48,0x00,0x00,0x49,0x48,0x00,0x00,0x69,0x48,0x00,0x00,0x89, +0x48,0x00,0x00,0xA9,0x48,0x00,0x00,0xDE,0x48,0x00,0x01,0x38,0x48,0x00,0x01,0x3A, +0x48,0x00,0x01,0x3C,0x48,0x00,0x01,0x3E,0x48,0x00,0x01,0x2C,0x48,0x00,0x01,0x3E, +0x50,0x03,0x00,0x40,0x50,0x03,0x00,0x40,0x50,0x03,0x00,0x40,0x8E,0x03,0x00,0x40, +0x96,0x03,0x00,0x40,0x9E,0x03,0x00,0x40,0xA4,0x03,0x00,0x40,0xAC,0x03,0x00,0x40, +0xB2,0x03,0x00,0x40,0xD5,0x00,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E, +0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,0x64,0x22, +0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08, +0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x46,0xF4,0x00,0x00,0x58,0xF7, +0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC, +0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02, +0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00, +0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x05,0x46,0xF4, +0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00,0x3A,0x0F,0x94,0x3C, +0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02, +0x64,0x12,0xA4,0x02,0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02, +0x00,0x03,0x64,0x00,0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F, +0x84,0x06,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00,0x3C,0x00,0xD5,0x00, +0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C, +0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02,0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C, +0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF, +0x88,0x09,0xB6,0x5F,0x84,0x07,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50,0x4A,0x00, +0x3C,0x00,0x3A,0x1F,0xA4,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x6E,0x80,0x20,0x3A,0x6F, +0x98,0x3C,0x64,0x62,0x00,0x02,0x64,0x72,0xA4,0x02,0x9D,0xFC,0x64,0x82,0x04,0x02, +0x3A,0x6F,0xA0,0x3C,0x9F,0xB2,0x64,0x62,0x00,0x03,0x64,0x00,0x00,0x08,0x80,0xDF, +0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0xDF,0x46,0xF4,0x00,0x00,0x58,0xF7,0x83,0x50, +0x4B,0xE0,0x3C,0x01,0x05,0xFF,0x80,0x00,0x3A,0x6F,0xA0,0x04,0x64,0x62,0x00,0x03, +0x64,0x00,0x00,0x08,0x64,0x72,0xA4,0x03,0x64,0x82,0x04,0x03,0x3A,0x6F,0x98,0x04, +0x42,0x6E,0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x1F,0xA4,0x04,0x64,0x00,0x00,0x04, +0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C, +0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x00,0x46,0x14,0x00,0x00, +0x58,0x10,0x83,0x8E,0xDD,0x21,0x05,0xFF,0x80,0x00,0x3A,0x2F,0x88,0x04,0x42,0x2E, +0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x0F,0x94,0x04,0x64,0x00,0x00,0x04,0x3A,0x1F, +0x94,0x3C,0x3A,0xFF,0xEF,0xBC,0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x12, +0x00,0x02,0x64,0x22,0xA4,0x02,0x64,0x32,0x04,0x02,0x3A,0x1F,0x8C,0x3C,0x9E,0x4A, +0x64,0x12,0x00,0x03,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x46,0x14, +0x00,0x00,0x58,0x10,0x80,0x4C,0x38,0x10,0x82,0x02,0xDD,0x21,0x05,0xFF,0x80,0x00, +0x3A,0x0F,0x88,0x04,0x64,0x02,0x00,0x43,0x64,0x00,0x00,0x08,0x64,0x02,0x00,0x03, +0x64,0x12,0xA4,0x03,0x64,0x22,0x04,0x03,0x3A,0x2F,0x88,0x04,0x42,0x2E,0x80,0x21, +0x3A,0xFF,0xEF,0x84,0x3A,0x1F,0x94,0x04,0x3A,0x0F,0x80,0x04,0x64,0x00,0x00,0x04, +0x3A,0x0F,0x80,0x3C,0x84,0x05,0xD5,0xC4,0x3A,0x0F,0x80,0x3C,0x84,0x01,0xD5,0xC0, +0x3A,0x0F,0x80,0x3C,0x84,0x02,0xD5,0xBC,0x3A,0x0F,0x80,0x3C,0x84,0x03,0xD5,0xB8, +0x3A,0x0F,0x80,0x3C,0x84,0x04,0xD5,0xB4,0x3A,0x0F,0x94,0x3C,0x3A,0xFF,0xEF,0xBC, +0x42,0x2E,0x80,0x20,0x3A,0x2F,0x88,0x3C,0x64,0x02,0x00,0x02,0x64,0x12,0xA4,0x02, +0x64,0x22,0x04,0x02,0x3A,0x0F,0x88,0x3C,0x9E,0x02,0x64,0x02,0x00,0x03,0x64,0x00, +0x00,0x08,0x80,0x5F,0xEF,0xFC,0x43,0xFF,0x88,0x09,0xB6,0x5F,0x84,0x0F,0x46,0x14, +0x00,0x00,0x58,0x10,0x83,0x50,0xDD,0x21,0x05,0xFF,0x80,0x00,0x3A,0x0F,0x88,0x04, +0x64,0x02,0x00,0x03,0x64,0x00,0x00,0x08,0x64,0x12,0xA4,0x03,0x64,0x22,0x04,0x03, +0x3A,0x2F,0x88,0x04,0x42,0x2E,0x80,0x21,0x3A,0xFF,0xEF,0x84,0x3A,0x0F,0x94,0x04, +0x64,0x00,0x00,0x04,0x40,0x00,0x00,0x09,0x47,0xD4,0x00,0x0B,0x59,0xDE,0x83,0x70, +0x3E,0x0F,0xF4,0xB4,0x42,0x0E,0x00,0x21,0x3F,0xC8,0x00,0x00,0x3F,0xF8,0x0C,0x90, +0x49,0x00,0x00,0x1E,0x49,0x00,0x00,0x18,0x49,0x00,0x11,0xAD,0xD5,0x00,0x92,0x00, +0xD5,0x00,0x84,0x00,0x64,0x05,0xE4,0x03,0x46,0x04,0x00,0x00,0x58,0x00,0x00,0x00, +0x64,0x02,0x24,0x03,0x64,0x02,0x00,0x02,0x66,0x00,0x00,0x06,0x64,0x02,0x00,0x03, +0xEA,0x5D,0xDD,0x9E,0xFC,0x00,0x49,0xFF,0xFF,0xEE,0xFC,0x80,0x46,0x04,0x00,0x00, +0x58,0x00,0x00,0x00,0xEA,0x37,0x64,0x04,0xC0,0x03,0xEA,0x5D,0xDD,0x9E,0xFC,0x00, +0x49,0x00,0x45,0x70,0xFC,0x80,0xFC,0x00,0x49,0x00,0x4A,0x9A,0xFC,0x80,0x40,0x00, +0x00,0x09,0xDD,0x9E,0xFC,0x00,0x49,0x00,0x45,0xC7,0xFC,0x80,0x40,0x00,0x00,0x09, +0xDD,0x9E,0xFC,0x00,0x49,0x00,0x48,0x68,0xFC,0x80,0x00,0x00,0x80,0xA0,0x94,0x91, +0x88,0x02,0x92,0x00,0x1A,0x12,0x80,0x01,0xD8,0xFE,0xDD,0x9E,0x80,0xA0,0x80,0x62, +0x96,0x8F,0x8A,0x62,0xC2,0x06,0x88,0x02,0x18,0x12,0x80,0x01,0xD8,0xFE,0x8A,0x02, +0xC3,0x06,0x88,0x02,0x88,0x03,0x3A,0x12,0x84,0x24,0xD8,0xFE,0xDD,0x9E,0x80,0xA2, +0x80,0x60,0x96,0x0F,0x8A,0x60,0xC0,0x08,0x88,0x02,0x28,0x42,0x80,0x01,0x18,0x40, +0x80,0x01,0xD8,0xFC,0x8A,0x02,0xC3,0x08,0x88,0x02,0x88,0x03,0x3A,0x42,0x90,0x04, +0x3A,0x40,0x90,0x24,0xD8,0xFC,0xDD,0x9E,0xFC,0x01,0xF0,0x81,0xF0,0x01,0x8E,0x01, +0xF0,0x81,0xC0,0x03,0xEA,0x6D,0xD5,0xFB,0xFC,0x81,0xFC,0x01,0xF0,0x81,0xF0,0x01, +0x8E,0x01,0xF0,0x81,0xC0,0x05,0xEA,0x36,0xC0,0x03,0xEA,0x6D,0xD5,0xF9,0xFC,0x81, +0xFC,0x01,0x84,0xCE,0xF0,0x81,0xF0,0x01,0x8E,0xC1,0xDD,0x4A,0x97,0xB0,0x84,0x05, +0xDD,0x50,0xCE,0xFA,0xFC,0x81,0x80,0x3F,0x3E,0x08,0x03,0x50,0x9A,0x08,0x5C,0xF0, +0x00,0x3D,0xE8,0x05,0x3C,0x1F,0xFF,0x6D,0x84,0x01,0xDD,0x9E,0x3E,0x08,0x0C,0x90, +0x8A,0x01,0x3C,0x1D,0xFF,0x6D,0xE2,0x20,0xE8,0x03,0x3C,0x0F,0xFF,0x6D,0x84,0x00, +0xDD,0x9E,0xFC,0x00,0xDD,0x4D,0x5A,0x00,0x08,0x18,0x5A,0x00,0x06,0x16,0xEA,0xB1, +0xEB,0x24,0xEB,0x32,0xEB,0x58,0xEA,0x68,0xDD,0x48,0x2E,0x07,0xFD,0x29,0x3E,0x07, +0xFD,0x2F,0x46,0x21,0x00,0x05,0x58,0x21,0x08,0x88,0xEA,0x5B,0x46,0x11,0x00,0x05, +0x58,0x10,0x86,0xD8,0xD5,0x06,0xEA,0x5B,0xEB,0x24,0xEB,0x32,0xEB,0x58,0xEA,0x68, +0xDD,0x48,0x84,0x00,0xDD,0x58,0xDD,0x4D,0x5A,0x00,0x08,0x17,0x5A,0x00,0x06,0x15, +0x84,0xA0,0x80,0x05,0xEB,0x70,0x58,0x31,0x81,0x44,0xDD,0x4F,0x50,0x12,0x8F,0x34, +0x88,0x23,0xA4,0x48,0x8C,0xA2,0xE6,0x21,0x88,0x0F,0x96,0x01,0xDA,0xF8,0x5C,0xF0, +0x00,0xD9,0xE9,0x02,0xD5,0x00,0xFC,0x80,0xFC,0x41,0x3F,0xCF,0xFD,0x90,0x84,0x00, +0x3E,0x07,0xFC,0xC2,0x49,0x00,0x4C,0x36,0x3E,0x07,0xFC,0xCF,0x84,0x20,0xF1,0x81, +0x4E,0x02,0x00,0xB6,0xEB,0x5B,0x02,0x50,0x80,0x00,0x44,0x10,0xA5,0x5A,0x46,0x71, +0x00,0x00,0x58,0x73,0x80,0x00,0x4C,0x50,0x80,0xAB,0xEB,0x5B,0x02,0x50,0x80,0x00, +0x44,0x10,0xA3,0x3A,0x4C,0x50,0x80,0xA4,0x9E,0x41,0xE6,0x27,0xE9,0x04,0x5A,0x08, +0x09,0x14,0xD5,0x06,0x84,0x21,0x3E,0x17,0xFC,0xC2,0x5A,0x08,0x01,0x0E,0xB8,0x00, +0x5A,0x00,0x08,0x07,0x5A,0x00,0x06,0x05,0xEB,0x55,0xEA,0xAD,0xD5,0x03,0xEB,0x52, +0xEA,0xFC,0xF0,0x81,0xD5,0x0E,0x54,0x10,0x00,0xF7,0x5A,0x18,0x02,0x05,0xEB,0x55, +0xEA,0x74,0xD5,0xF8,0x5A,0x18,0x03,0x04,0xB8,0x1A,0xD5,0xF4,0x5A,0x00,0x08,0xFE, +0xB0,0x41,0x3E,0x0F,0xFC,0xCF,0x49,0x00,0x07,0x11,0xF5,0x01,0x46,0x11,0x00,0x04, +0x58,0x10,0x84,0xB8,0x84,0xC1,0xD1,0x07,0x50,0x10,0x85,0xF0,0x40,0x62,0x84,0x03, +0x5C,0x63,0x00,0x01,0xEA,0x7A,0xEA,0xEB,0x84,0x20,0xFE,0x84,0xEB,0x82,0x58,0x00, +0x00,0x04,0x94,0x91,0xDD,0x42,0xB8,0x00,0x5A,0x08,0x08,0x08,0xEA,0x5B,0xEB,0x5B, +0xEB,0x33,0xF2,0x01,0xDD,0x48,0xD5,0x46,0x5A,0x00,0x06,0xFA,0x84,0x00,0xF1,0x01, +0x49,0x00,0x07,0x20,0xC8,0xF4,0xF1,0x01,0xB8,0x1A,0x4C,0x10,0x40,0x0E,0x46,0x91, +0x00,0x04,0x58,0x94,0x8A,0xA8,0xF0,0x01,0x80,0x29,0x84,0x40,0x49,0x00,0x41,0xC6, +0x14,0x9F,0x80,0x01,0xD5,0x09,0xEB,0x55,0xEA,0x74,0x4C,0x10,0x3F,0xF2,0x84,0x01, +0x49,0x00,0x07,0x08,0xC8,0xED,0x2F,0x37,0xFF,0xC9,0x2F,0x17,0xFF,0xC8,0x50,0x03, +0x00,0x12,0x94,0x41,0x42,0x60,0x98,0x73,0x94,0x82,0x84,0x00,0x05,0x2F,0x80,0x01, +0x40,0x98,0x84,0x08,0x95,0xB1,0x80,0xA0,0x80,0x80,0x9C,0x6C,0xE2,0x93,0x41,0x03, +0x84,0x00,0xE8,0x10,0x98,0xC6,0x88,0x72,0x84,0x20,0xE2,0x31,0xE8,0x07,0x38,0xA1, +0x85,0x01,0x38,0xA8,0x05,0x09,0x8C,0x21,0xD5,0xF9,0x8C,0x81,0x88,0xA9,0x88,0x02, +0xD5,0xED,0xEA,0x7A,0x2E,0x17,0xFF,0xC8,0x42,0x01,0x04,0x24,0x88,0x41,0x8C,0x02, +0x40,0x03,0x80,0x20,0x84,0x20,0x94,0x91,0xDD,0x42,0xEA,0x9E,0x54,0x00,0x00,0xF7, +0x5A,0x08,0x01,0x04,0x49,0x00,0x00,0xCC,0x49,0x00,0x4B,0xE4,0xFC,0xC1,0xFC,0x00, +0xDD,0x4C,0x96,0x04,0xC0,0x09,0xEA,0x36,0xC0,0x08,0x2E,0x07,0xFE,0x31,0xC8,0x05, +0x49,0x00,0x4A,0xEC,0xD5,0x02,0xEA,0x6B,0xFC,0x80,0x2E,0x17,0xFC,0xD4,0xFE,0x0C, +0x96,0x01,0xDD,0x9E,0xFC,0x60,0xDD,0x56,0x04,0x70,0x00,0x3F,0x92,0xF8,0x96,0x78, +0x5A,0x10,0xAA,0x06,0x5A,0x10,0xCC,0x04,0x5A,0x18,0xDD,0x46,0x04,0x60,0x00,0x3F, +0x40,0x03,0x40,0x09,0xEA,0xED,0x96,0x31,0x40,0x90,0x20,0x09,0x97,0xB0,0xEA,0x48, +0x5A,0x70,0xCC,0x19,0x5A,0x70,0xDD,0x28,0x5A,0x78,0xAA,0x2D,0x84,0xE0,0x46,0xC1, +0x00,0x07,0x58,0xC6,0x0F,0x80,0x96,0x38,0xE2,0x06,0xE8,0x24,0x50,0xB3,0x80,0x01, +0x80,0x0A,0x80,0x29,0x40,0x25,0x80,0x13,0xEA,0x3B,0x38,0x06,0x1C,0x08,0x80,0xEB, +0xD5,0xF3,0x84,0x40,0x46,0xB1,0x00,0x07,0x58,0xB5,0x8F,0x80,0x96,0x10,0xE2,0x06, +0xE8,0x11,0x9D,0xD1,0x38,0x35,0x88,0x00,0x80,0x0A,0x96,0xB9,0x80,0x29,0xDD,0x4E, +0x80,0x47,0xD5,0xF5,0xEB,0x62,0x00,0x30,0x0F,0x80,0x80,0x29,0x80,0x0A,0x80,0x46, +0xDD,0x4E,0xEA,0x3C,0x83,0x81,0xB8,0x3F,0x46,0x2B,0xB0,0x00,0xEA,0xB0,0x40,0x01, +0x01,0x15,0xB8,0xBF,0xFC,0xE0,0xFC,0x00,0xDD,0x53,0x4E,0x00,0x4C,0x83,0x84,0x62, +0xDD,0x4E,0xF8,0x24,0x84,0x42,0xDD,0x4E,0xF8,0x21,0x84,0x43,0xDD,0x4E,0xF8,0x15, +0xDD,0x4E,0x84,0x0A,0xDD,0x50,0xF8,0x1A,0x84,0x44,0xDD,0x4E,0xF8,0x1D,0xEA,0x3B, +0x3E,0x07,0xFC,0xD3,0xF8,0x13,0x84,0x41,0xDD,0x4E,0x4E,0x00,0x4C,0x74,0xFA,0x64, +0xDD,0x4E,0xF8,0x0C,0x84,0x43,0xDD,0x4E,0x84,0x20,0x84,0x44,0x44,0x30,0x00,0x80, +0xDD,0x52,0x83,0xFF,0xDD,0x4E,0x84,0x0A,0xDD,0x50,0x84,0x20,0x80,0x61,0xDD,0x52, +0x83,0xFF,0x84,0x44,0xDD,0x4E,0x84,0x20,0x84,0x45,0xDD,0x52,0x83,0xFF,0xEA,0x3B, +0x3E,0x07,0xFC,0xBC,0xFC,0x80,0xFC,0x00,0x84,0x0E,0xDD,0x40,0xC8,0x1B,0xFA,0x02, +0xDD,0x40,0xC8,0x18,0xFA,0x06,0xDD,0x40,0xC8,0x15,0x84,0x0A,0xDD,0x40,0xC8,0x12, +0xFA,0x0A,0xDD,0x40,0xC8,0x0F,0xFA,0x13,0xDD,0x40,0xC8,0x0C,0xFA,0x0E,0xDD,0x40, +0xC8,0x09,0xFA,0x18,0xDD,0x40,0xC8,0x06,0xFA,0x1C,0xDD,0x40,0xC8,0x03,0xDD,0x47, +0xDD,0x40,0xEA,0x27,0x02,0x00,0x80,0x9C,0x02,0x10,0x80,0x0A,0x8A,0x01,0x44,0x10, +0x06,0x5C,0xFE,0x0C,0x84,0x2A,0xEA,0xDF,0x92,0x04,0xFC,0x80,0xFC,0x40,0x3F,0xCF, +0xFD,0x90,0xEB,0x52,0x00,0x20,0x02,0xC0,0xC2,0x04,0xEB,0x52,0x10,0x20,0x02,0xC1, +0xBD,0x11,0x5A,0x58,0x05,0x06,0x84,0x00,0xEB,0x79,0x10,0x00,0x82,0xC1,0x2E,0x47, +0xFD,0x03,0xEB,0x26,0x44,0x30,0x03,0xE8,0x44,0x10,0x27,0x10,0xFE,0x1C,0x42,0x02, +0x04,0x73,0xB9,0x0C,0x84,0x8A,0x88,0x01,0x42,0x02,0x90,0x73,0xEB,0x85,0x96,0x01, +0x12,0x00,0x87,0xA2,0x2E,0x57,0xFD,0x1D,0xEB,0x62,0x00,0x00,0x00,0x80,0xEA,0x2A, +0xFE,0x24,0x42,0x02,0x84,0x73,0x2E,0x57,0xFD,0x08,0x96,0x91,0x88,0x05,0x96,0x01, +0xEB,0x60,0x12,0x02,0x87,0xA3,0xEB,0x4F,0xEA,0xA8,0xEB,0x60,0x12,0x02,0x87,0xA5, +0xEB,0x65,0x02,0x00,0x00,0x5E,0xEB,0x60,0x92,0x01,0x12,0x02,0x87,0xA6,0xEB,0x65, +0x02,0x00,0x00,0x64,0xEB,0x60,0x92,0x01,0x12,0x02,0x87,0xA7,0xEA,0x40,0xEB,0x60, +0x12,0x02,0x87,0xA8,0xB8,0x19,0xEB,0x60,0x96,0x01,0x12,0x02,0x87,0xA9,0x3C,0x03, +0xFE,0xF6,0xEB,0x60,0x12,0x02,0x87,0xAA,0xEB,0x1A,0xEB,0x60,0x12,0x02,0x87,0xAB, +0xEB,0x09,0xEB,0x60,0x12,0x02,0x87,0xAC,0x3C,0x03,0xFE,0xDA,0xEB,0x60,0x12,0x02, +0x87,0xB0,0x2E,0x07,0xFC,0xFB,0xEB,0x60,0x12,0x02,0x87,0xB1,0xEB,0x62,0x12,0x20, +0x07,0xB2,0xEB,0x52,0x00,0x00,0x02,0xC1,0xEB,0x73,0x12,0x01,0x07,0xB3,0x2E,0x27, +0xFC,0xE1,0xEA,0xE0,0xEB,0x00,0xEB,0x73,0x12,0x01,0x07,0xB4,0x2E,0x27,0xFD,0x24, +0xEB,0x62,0x02,0x00,0x07,0xB5,0xEB,0x00,0xEB,0x73,0x96,0x01,0x12,0x01,0x07,0xB5, +0x2E,0x27,0xFD,0x26,0xEA,0x29,0xFE,0x1C,0x42,0x01,0x10,0x73,0xEB,0x73,0x96,0x01, +0x12,0x01,0x07,0xB6,0x3C,0x03,0xFF,0x14,0xEB,0x73,0x12,0x01,0x07,0xB7,0x3C,0x03, +0xFF,0x12,0xEB,0x73,0x12,0x01,0x07,0xB8,0xBA,0x10,0x2E,0x07,0xFC,0xDA,0xEB,0x00, +0xEB,0x73,0x96,0x01,0x12,0x01,0x07,0xB9,0xEB,0x62,0x02,0x20,0x07,0xBA,0x2E,0x47, +0xFD,0x20,0x2E,0x07,0xFD,0x0D,0xFE,0x0C,0x42,0x02,0x0C,0x73,0x88,0x02,0x96,0x01, +0xEB,0x73,0x12,0x01,0x07,0xBA,0xEB,0x73,0x3C,0x03,0xFE,0xD8,0x12,0x01,0x07,0xBE, +0x3C,0x03,0xFE,0x9F,0x12,0x01,0x07,0xBE,0x2E,0x27,0xFF,0x5C,0x42,0x01,0x18,0x0B, +0xC0,0x0B,0x2E,0x38,0x02,0x8C,0x2E,0x08,0x02,0x8D,0x42,0x01,0x84,0x73,0xEB,0x85, +0x96,0x01,0x12,0x00,0x87,0xBF,0xEB,0x4F,0x02,0x00,0x02,0xD5,0xEB,0x85,0x12,0x00, +0x81,0xD8,0x3C,0x03,0xFE,0xBD,0xEB,0x85,0x8C,0x0F,0x96,0x01,0x96,0x92,0x12,0x00, +0x81,0xEB,0x4E,0x25,0x00,0x17,0x2E,0x00,0x00,0x1D,0x92,0x07,0x4E,0x02,0x00,0x76, +0xEB,0x3E,0xEA,0xEB,0xEB,0x58,0x58,0x21,0x00,0x00,0xFE,0x44,0xEB,0x4E,0x8C,0x22, +0x40,0x11,0x04,0x20,0xEB,0x73,0x58,0x21,0x0F,0x44,0xDD,0x48,0x48,0x00,0x00,0x66, +0x84,0x0E,0xDD,0x40,0xC8,0xE9,0xFA,0x02,0xDD,0x40,0xC8,0xE6,0xFA,0x06,0xDD,0x40, +0xC8,0xE3,0x84,0x0A,0xDD,0x40,0xC8,0xE0,0xFA,0x0A,0xDD,0x40,0xC8,0xDD,0xFA,0x13, +0xDD,0x40,0xC8,0xDA,0xFA,0x0E,0xDD,0x40,0xC8,0xD7,0xFA,0x18,0xDD,0x40,0xC8,0xD4, +0xFA,0x1C,0xDD,0x40,0xC8,0xD1,0xDD,0x47,0xDD,0x40,0xC8,0xCE,0xB8,0x12,0x5A,0x08, +0x01,0xCC,0x2E,0x67,0xFF,0xC8,0xB8,0x00,0x46,0x41,0x00,0x00,0x58,0x42,0x00,0x00, +0x5A,0x08,0x08,0x0C,0x2E,0x37,0xFF,0xC9,0x42,0x21,0x98,0x24,0x9C,0x52,0x8A,0x46, +0x40,0x12,0x04,0x20,0x8C,0x42,0xD5,0x09,0x2E,0x00,0x00,0x1D,0x96,0x37,0xFE,0x34, +0x8C,0x02,0x40,0x12,0x00,0x20,0x98,0x86,0x40,0x62,0x08,0x20,0xEB,0x4E,0xEB,0x73, +0x58,0x21,0x0F,0x44,0xDD,0x48,0x46,0x97,0xFF,0xFF,0x80,0x26,0xEB,0x4E,0xEB,0x73, +0x58,0x21,0x03,0xB0,0xDD,0x48,0x84,0xC0,0x50,0x94,0x8F,0xFF,0x46,0xA1,0x00,0x00, +0x58,0xA5,0x00,0x04,0xEA,0x77,0xE2,0xC0,0x4E,0xF2,0xFF,0x97,0xEA,0x31,0x40,0x70, +0x24,0x00,0x42,0x73,0x00,0x73,0x80,0x06,0x40,0x75,0x1C,0x20,0x49,0x00,0x24,0x5F, +0x8C,0xC1,0xAC,0x38,0x97,0xB0,0xD5,0xEF,0xFC,0xC0,0xFC,0x60,0x84,0x07,0x46,0x11, +0x00,0x07,0x10,0x00,0x8B,0x0E,0x46,0x11,0x00,0x07,0x10,0x00,0x8B,0x22,0x46,0x00, +0x00,0x0C,0x00,0x00,0x00,0x00,0x5A,0x00,0xA5,0x04,0x48,0x00,0x01,0x87,0xEB,0x62, +0x04,0x50,0x03,0xC0,0xEB,0x03,0x97,0x69,0x4C,0x50,0x00,0xDA,0xEB,0x7F,0x00,0x00, +0x08,0x3B,0xEB,0x5E,0x10,0x00,0x8B,0x8B,0xEB,0x7F,0x00,0x00,0x08,0x3C,0xEB,0x5E, +0x10,0x00,0x8B,0x8C,0xEB,0x7F,0x00,0x00,0x08,0x3D,0xEB,0x5E,0x10,0x00,0x8B,0x8D, +0xEB,0x7F,0x00,0x00,0x08,0x3E,0xEB,0x5E,0x10,0x00,0x8B,0x8E,0xEB,0x7F,0x00,0x00, +0x08,0x3F,0xEB,0x5E,0x10,0x00,0x8B,0x8F,0xEB,0x7F,0x02,0x00,0x04,0x0F,0xEB,0x5E, +0x12,0x00,0x85,0xB7,0xEB,0x7F,0x02,0x00,0x04,0x10,0xEB,0x5E,0x12,0x00,0x85,0xB8, +0xEB,0x7F,0x02,0x00,0x04,0x11,0xEB,0x5E,0x12,0x00,0x85,0xB9,0xEB,0x7F,0x04,0x00, +0x01,0xF8,0xEB,0x5E,0x14,0x00,0x82,0xCC,0xEB,0x7F,0x02,0x00,0x04,0x0D,0xEB,0x5E, +0x12,0x00,0x85,0xB5,0xEB,0x7F,0x02,0x00,0x04,0x0E,0xEB,0x5E,0x12,0x00,0x85,0xB6, +0xEB,0x7F,0x00,0x00,0x09,0xE7,0xEB,0x5E,0x10,0x00,0x8D,0x37,0xEB,0x7F,0x00,0x00, +0x09,0xE8,0xEB,0x5E,0x10,0x00,0x8D,0x38,0xEB,0x7F,0x00,0x00,0x09,0xE9,0xEB,0x5E, +0x10,0x00,0x8D,0x39,0xEB,0x7F,0x00,0x00,0x09,0xEA,0xEB,0x5E,0x10,0x00,0x8D,0x3A, +0xEB,0x7F,0x00,0x00,0x09,0xEB,0xEB,0x5E,0x10,0x00,0x8D,0x3B,0xEB,0x7F,0x02,0x00, +0x04,0xE5,0xEB,0x5E,0x12,0x00,0x86,0x8D,0xEB,0x7F,0x02,0x00,0x04,0xE6,0xEB,0x5E, +0x12,0x00,0x86,0x8E,0xEB,0x7F,0x02,0x00,0x04,0xE7,0xEB,0x5E,0x12,0x00,0x86,0x8F, +0xEB,0x7F,0x04,0x00,0x02,0x63,0xEB,0x5E,0x14,0x00,0x83,0x37,0xEB,0x7F,0x02,0x00, +0x04,0xE3,0xEB,0x5E,0x12,0x00,0x86,0x8B,0xEB,0x7F,0x02,0x00,0x04,0xE4,0xEB,0x5E, +0x12,0x00,0x86,0x8C,0x44,0x20,0xC0,0x00,0x44,0x00,0x00,0x80,0x46,0x11,0x00,0x07, +0x58,0x10,0x80,0x00,0xDD,0x48,0x44,0x00,0x01,0x80,0x46,0x11,0x00,0x07,0x58,0x10, +0x80,0x86,0x44,0x20,0xC1,0x00,0xDD,0x48,0xFA,0x1A,0x46,0x11,0x00,0x07,0x58,0x10, +0x82,0x66,0x44,0x20,0xC2,0xE0,0xDD,0x48,0x44,0x00,0x00,0x38,0x46,0x11,0x00,0x07, +0x58,0x10,0x83,0x48,0x44,0x20,0xCA,0x48,0xDD,0x48,0xDD,0x47,0x46,0x11,0x00,0x07, +0x58,0x10,0x83,0x80,0x44,0x20,0xCA,0x80,0xDD,0x48,0xFA,0x08,0x46,0x11,0x00,0x07, +0x58,0x10,0x82,0x06,0x44,0x20,0xC2,0x80,0xDD,0x48,0xFA,0x08,0x46,0x11,0x00,0x07, +0x58,0x10,0x82,0x36,0x44,0x20,0xC2,0xB0,0xDD,0x48,0xFA,0x08,0x46,0x11,0x00,0x07, +0x58,0x10,0x82,0x1E,0x44,0x20,0xC2,0x98,0xDD,0x48,0xFA,0x08,0x46,0x11,0x00,0x07, +0x58,0x10,0x82,0x4E,0x44,0x20,0xC2,0xC8,0xDD,0x48,0x46,0x00,0x00,0x0C,0x04,0x00, +0x00,0xCF,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xA5,0xD5,0x04,0xEB,0x62,0x04,0x00, +0x00,0xA5,0x3C,0x0F,0xFF,0x76,0x84,0x08,0x46,0x11,0x00,0x07,0x10,0x00,0x80,0x02, +0x84,0x04,0x46,0x11,0x00,0x07,0x10,0x00,0x80,0x03,0x46,0x21,0x00,0x07,0x58,0x21, +0x00,0x86,0x44,0x00,0x01,0x80,0xEA,0x4C,0xDD,0x48,0x2E,0x07,0xFF,0xC9,0x3E,0x00, +0x00,0xE1,0x2E,0x17,0xFF,0xC8,0x88,0x01,0x3E,0x10,0x00,0xE0,0x2E,0x27,0xFF,0xCA, +0x84,0xA0,0x3E,0x00,0x00,0xE9,0x45,0x00,0xE0,0x00,0xEB,0x62,0x3E,0x20,0x00,0xE3, +0x14,0x50,0x00,0xB1,0x80,0x45,0x44,0x90,0xFF,0xFF,0x81,0x50,0x44,0xB0,0x00,0x48, +0x46,0xC1,0x00,0x07,0x58,0xC6,0x05,0x00,0x44,0x40,0x00,0x6C,0x86,0x23,0x45,0x20, +0x00,0xD8,0x44,0xDF,0xFF,0x94,0x45,0x30,0x05,0x10,0x38,0x08,0x14,0x01,0x4C,0x04, +0x80,0x32,0x80,0xCC,0x42,0x61,0x2C,0x73,0x84,0x60,0x40,0xE5,0x14,0x00,0x38,0x17, +0x0D,0x01,0x95,0xD9,0x9E,0x09,0x41,0x40,0x12,0x96,0x40,0x8A,0x46,0x96,0x5C,0xF0, +0x81,0x45,0x40,0x8A,0x00,0x13,0xE8,0x05,0x42,0x04,0x34,0x73,0x96,0x01,0xD5,0x11, +0x52,0x00,0x82,0x88,0x40,0x10,0x10,0x16,0x50,0x00,0x00,0x6C,0x96,0x01,0x4E,0x83, +0x00,0x07,0x50,0x1A,0x00,0x02,0x42,0x00,0xC8,0x73,0xD5,0x05,0x5A,0x80,0x02,0x04, +0x42,0x04,0x48,0x73,0x8C,0x61,0x38,0x03,0x1C,0x09,0x5A,0x38,0x24,0xDA,0x8C,0x41, +0x96,0x91,0x50,0x52,0x80,0x48,0x4C,0x59,0xFF,0xCA,0x46,0x00,0x00,0x0C,0x04,0x00, +0x02,0xC3,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF7,0x46,0x00,0x00,0x0C,0x02,0x00, +0x05,0x85,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xED,0x46,0x00,0x00,0x0C,0x02,0x00, +0x05,0x84,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xEC,0x46,0x00,0x00,0x0C,0x04,0x00, +0x02,0xC1,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xF5,0x46,0x00,0x00,0x0C,0x46,0x11, +0x00,0x07,0x04,0x00,0x02,0xC0,0x14,0x00,0x83,0xF4,0xEA,0x8B,0x44,0x00,0x72,0xC0, +0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB0,0xFC,0xE0,0xFC,0x21,0x46,0x69,0x00,0x08, +0x44,0x70,0x35,0xCA,0x12,0x73,0x00,0x08,0xEA,0x48,0xC8,0x20,0x12,0x73,0x00,0x08, +0x46,0x10,0x00,0x0C,0x00,0x10,0x81,0x03,0xEA,0x5C,0xC1,0x13,0xF0,0x81,0x49,0xFF, +0xFC,0xA4,0x46,0x00,0x00,0x0C,0x00,0x10,0x01,0x06,0xF0,0x01,0xC9,0x04,0x44,0x00, +0xE8,0x00,0xD5,0x05,0x5A,0x18,0x02,0x06,0x44,0x00,0xEC,0x00,0x49,0x00,0x3B,0xCC, +0xEA,0xEA,0x12,0x13,0x00,0x08,0x96,0x00,0xD5,0x03,0x44,0x00,0x00,0xF0,0xFC,0xA1, +0xFC,0x00,0x46,0x09,0x00,0x08,0xEA,0xEA,0x12,0x10,0x00,0x08,0xEA,0xB7,0x02,0x01, +0x00,0x72,0x42,0x30,0x0C,0x0B,0xCB,0x34,0x02,0x11,0x00,0x72,0x42,0x00,0x90,0x0B, +0xC8,0x31,0x02,0x11,0x00,0x72,0xEA,0xDA,0xC9,0x2E,0x2E,0x17,0xFF,0x5B,0x42,0x00, +0x88,0x0B,0xC8,0x03,0xEB,0x2E,0xD5,0x06,0x49,0x00,0x3C,0x6E,0x44,0x00,0x00,0xF1, +0xD5,0x22,0xB4,0x02,0x96,0x16,0xC0,0xFE,0x46,0x09,0x00,0x08,0x44,0x20,0x35,0xCA, +0x12,0x20,0x00,0x08,0x42,0x20,0x8C,0x0B,0x80,0x20,0xCA,0x04,0xEA,0xB7,0xEB,0x2E, +0xD5,0x06,0x49,0x00,0x3C,0x62,0x44,0x00,0x00,0xF2,0xD5,0x0D,0xB4,0x02,0x92,0x0C, +0x96,0x0F,0x5A,0x08,0x03,0xFD,0x44,0x00,0x35,0xCA,0x12,0x00,0x80,0x08,0x84,0x00, +0xD5,0x02,0x80,0x03,0xFC,0x80,0x00,0x00,0xFC,0x00,0x5C,0xF0,0x00,0x31,0x4E,0xF2, +0x01,0x56,0x3E,0xFF,0x5B,0x60,0x38,0x07,0x81,0x01,0x40,0xF0,0x3C,0x00,0xDD,0x0F, +0x62,0x00,0x68,0x00,0x72,0x00,0x7C,0x00,0x86,0x00,0x90,0x00,0x9A,0x00,0xAC,0x00, +0xB6,0x00,0xC0,0x00,0xCA,0x00,0xDC,0x00,0xE6,0x00,0xF0,0x00,0xFA,0x00,0x06,0x01, +0x10,0x01,0x1A,0x01,0x26,0x01,0x32,0x01,0x3C,0x01,0x46,0x01,0x50,0x01,0x5E,0x01, +0x68,0x01,0x72,0x01,0x7C,0x01,0x92,0x01,0x9C,0x01,0xA6,0x01,0xB0,0x01,0xC8,0x01, +0x9A,0x02,0xD4,0x01,0xDE,0x01,0xE8,0x01,0xFE,0x01,0x9A,0x02,0x08,0x02,0x12,0x02, +0x1C,0x02,0x32,0x02,0x3C,0x02,0x46,0x02,0x50,0x02,0x5E,0x02,0x68,0x02,0x72,0x02, +0x80,0x02,0xEB,0x62,0xDD,0x5D,0xF8,0x5E,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x76,0xF7, +0xF8,0x59,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x66,0x67,0xF8,0xAB,0xEB,0x62,0xDD,0x5D, +0x50,0x00,0x7E,0xFF,0xF8,0x4F,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x7E,0x6F,0xF8,0x4A, +0xEB,0x62,0xDD,0x44,0x44,0x0F,0x6E,0x6F,0xF8,0x9C,0x84,0x04,0xDD,0x40,0x80,0xC0, +0xC0,0x04,0x85,0xE1,0x48,0x00,0x00,0xFC,0x84,0x05,0xF8,0x8D,0xEB,0x62,0xDD,0x5D, +0x50,0x00,0x5D,0xDE,0xF8,0x37,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x5B,0xDC,0xF8,0x32, +0xEB,0x62,0xDD,0x44,0x44,0x0F,0xBB,0xBC,0xF8,0x84,0x84,0x07,0xDD,0x40,0xC8,0xEA, +0x84,0x08,0xDD,0x40,0x80,0xC0,0x84,0x09,0xCE,0xE5,0xF8,0x75,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0x55,0x56,0xF8,0x76,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x53,0x54,0xF8,0x71, +0xEB,0x62,0xDD,0x44,0x44,0x0F,0x33,0x34,0xF8,0x6C,0x84,0x0C,0xDD,0x40,0x80,0xC0, +0x84,0x0D,0xCE,0xD0,0xF8,0x60,0xEB,0x62,0xDD,0x5D,0x50,0x00,0x6E,0xEF,0xF8,0x0A, +0xEB,0x62,0xDD,0x5D,0x50,0x00,0x6C,0xED,0xF8,0x05,0xEB,0x62,0xDD,0x5D,0x50,0x00, +0x4C,0xCD,0x48,0x00,0x00,0xAD,0xFA,0x00,0xDD,0x40,0x80,0xC0,0xC8,0xBB,0xFA,0x01, +0xF8,0x4A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x88,0x89,0xF8,0x4B,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0x87,0x88,0xF8,0x46,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x77,0x78,0xF8,0x41, +0xFA,0x04,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0xA6,0xFA,0x05,0xF8,0x34,0xEB,0x62, +0xDD,0x44,0x44,0x0F,0xAA,0xAB,0xF8,0x35,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xA9,0xAA, +0xF8,0x30,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x99,0x9A,0xF8,0x2B,0xFA,0x07,0xDD,0x40, +0x4E,0x03,0xFF,0x91,0xFA,0x08,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x8C,0xFA,0x09, +0xF8,0x1A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAE,0xAF,0xF8,0x1B,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0xAE,0x9F,0xF8,0x16,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x9E,0x9F,0xF8,0x11, +0xFA,0x0B,0xDD,0x40,0x4E,0x03,0xFF,0x77,0xFA,0x0C,0xDD,0x40,0x80,0xC0,0x4E,0x03, +0xFF,0x72,0xFA,0x0D,0x48,0x00,0x00,0x68,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAF,0xB0, +0x48,0x00,0x00,0x55,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAF,0xA0,0xD5,0x4F,0xEB,0x62, +0xDD,0x44,0x44,0x0F,0x9F,0xA0,0xD5,0x4A,0xFA,0x0F,0xDD,0x40,0x4E,0x03,0xFF,0x5B, +0xFA,0x11,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x56,0xFA,0x12,0xD5,0x4C,0xEB,0x62, +0xDD,0x44,0x44,0x0F,0xAD,0xAE,0xD5,0x3A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAD,0x9E, +0xD5,0x35,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x9D,0x9E,0xD5,0x30,0xFA,0x14,0xDD,0x40, +0x4E,0x03,0xFF,0x41,0xFA,0x16,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x3C,0xFA,0x17, +0xD5,0x32,0xEB,0x62,0xDD,0x44,0x44,0x0F,0xAC,0xAD,0xD5,0x20,0xEB,0x62,0xDD,0x44, +0x44,0x0F,0xAC,0x9D,0xD5,0x1B,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x9C,0x9D,0xD5,0x16, +0xFA,0x1A,0xDD,0x40,0x80,0xC0,0x4E,0x03,0xFF,0x26,0xFA,0x1B,0xD5,0x1C,0xEB,0x62, +0xDD,0x44,0x44,0x0F,0x44,0x45,0xD5,0x0A,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x40,0x41, +0xD5,0x05,0xEB,0x62,0xDD,0x44,0x44,0x0F,0x00,0x01,0x88,0x01,0xE6,0x01,0xD5,0x0F, +0xFA,0x1D,0xDD,0x40,0x4E,0x03,0xFF,0x0F,0xFA,0x1E,0xDD,0x40,0x80,0xC0,0x4E,0x03, +0xFF,0x0A,0xFA,0x1F,0xDD,0x40,0xE2,0xC0,0xD5,0x02,0x85,0xE0,0x80,0x0F,0xFC,0x80, +0x92,0x00,0xFC,0x00,0x84,0x00,0xDD,0x40,0xC8,0x43,0x84,0x0B,0xDD,0x40,0xC0,0x04, +0x44,0x00,0xAC,0xAC,0xD5,0x3F,0x84,0x0F,0xDD,0x40,0xC0,0x04,0x44,0x00,0x13,0x13, +0xD5,0x39,0xFA,0x03,0xDD,0x40,0xC0,0x04,0x44,0x00,0x78,0x78,0xD5,0x33,0x84,0x07, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x22,0x22,0xD5,0x2D,0xFA,0x07,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x55,0x55,0xD5,0x27,0xFA,0x0B,0xDD,0x40,0xC0,0x04,0x44,0x00,0x51,0x51, +0xD5,0x21,0xFA,0x0F,0xDD,0x40,0xC0,0x04,0x44,0x00,0x50,0x50,0xD5,0x1B,0xFA,0x14, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x52,0x52,0xD5,0x15,0xFA,0x19,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x53,0x63,0xD5,0x0F,0xFA,0x1D,0xDD,0x40,0xC0,0x04,0x44,0x00,0xBB,0xBB, +0xD5,0x09,0x84,0x03,0xDD,0x40,0xC0,0x04,0x44,0x00,0x01,0x91,0xD5,0x03,0x44,0x00, +0x09,0x09,0x46,0x11,0x00,0x07,0xEA,0x32,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xB0, +0xEB,0x82,0x58,0x00,0x06,0x04,0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3E,0x07, +0xFD,0x09,0x84,0x20,0xB9,0x80,0xEB,0x6B,0x46,0x27,0x2C,0x80,0x14,0x21,0x80,0xB2, +0x3E,0x17,0xFC,0xF7,0x3E,0x07,0xFD,0x1B,0xB8,0x0A,0x44,0x10,0x72,0xC8,0x40,0x50, +0x40,0x09,0xD9,0x07,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFC,0xF7,0xD5,0x09, +0x44,0x10,0x7F,0x0C,0xD9,0x06,0x96,0x01,0xB8,0x8A,0x84,0x01,0x3E,0x07,0xFD,0x1B, +0xB8,0x0A,0x44,0x10,0xFF,0xFE,0x8E,0x01,0xE2,0x20,0xE8,0x03,0x84,0x01,0xB8,0x8A, +0x84,0x0E,0xDD,0x40,0xC0,0x06,0xDD,0x4C,0x96,0x37,0x3E,0x07,0xFF,0x5B,0xD5,0x1F, +0xFA,0x02,0xDD,0x40,0xC8,0xF9,0xFA,0x06,0xDD,0x40,0xC8,0xF6,0x84,0x0A,0xDD,0x40, +0xC8,0xF3,0xFA,0x0A,0xDD,0x40,0xC8,0xF0,0xFA,0x13,0xDD,0x40,0xC8,0xED,0xFA,0x0E, +0xDD,0x40,0xC8,0xEA,0xFA,0x18,0xDD,0x40,0xC8,0xE7,0xFA,0x1C,0xDD,0x40,0xC8,0xE4, +0xDD,0x47,0xDD,0x40,0xC8,0xE1,0xB8,0x0A,0x5A,0x08,0x01,0xDF,0xDD,0x47,0xDD,0x40, +0xC0,0x0B,0xEB,0x65,0xDD,0x5C,0x84,0x20,0xDD,0x4F,0xEA,0xA9,0xEB,0x55,0xEA,0x74, +0x84,0x3F,0xDD,0x4F,0xEA,0xA9,0xFC,0x80,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC7, +0xEA,0x40,0x2E,0x17,0xFF,0xC6,0xE2,0x01,0x56,0x07,0x80,0x01,0xEA,0xBB,0xEA,0x40, +0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xA5,0xDD,0x9E,0xFC,0x00,0x84,0x0E,0xDD,0x40, +0xC0,0x07,0x84,0x0C,0xDD,0x40,0xC0,0x0B,0x44,0x00,0xCC,0xCC,0xD5,0x13,0xFA,0x02, +0xDD,0x40,0xC8,0xF8,0xFA,0x06,0xDD,0x40,0xC8,0xF5,0xD5,0x12,0xFA,0x00,0xDD,0x40, +0xC0,0x04,0x44,0x00,0x33,0x33,0xD5,0x06,0xFA,0x04,0xDD,0x40,0xC0,0x3D,0x44,0x00, +0x88,0x88,0x46,0x11,0x00,0x07,0xEA,0x32,0x84,0x01,0xDD,0x58,0xD5,0x35,0x84,0x0A, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x44,0x44,0xD5,0x2C,0xFA,0x0A,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x66,0x66,0xD5,0x26,0xFA,0x0E,0xDD,0x40,0xC0,0x04,0x44,0x00,0x61,0x61, +0xD5,0x20,0xFA,0x13,0xDD,0x40,0xC0,0x04,0x44,0x00,0x60,0x60,0xD5,0x1A,0xFA,0x18, +0xDD,0x40,0xC0,0x04,0x44,0x00,0x62,0x62,0xD5,0x14,0xFA,0x1C,0xDD,0x40,0xC0,0x04, +0x44,0x00,0x63,0x63,0xD5,0x0E,0xDD,0x47,0xDD,0x40,0xC0,0x03,0xEA,0x28,0xD5,0x09, +0x84,0x06,0xDD,0x40,0xC0,0x04,0x44,0x00,0x91,0x91,0xD5,0x03,0x44,0x00,0x99,0x99, +0x46,0x11,0x00,0x07,0xEA,0x32,0xFC,0x80,0xFC,0x00,0xA6,0x00,0x80,0xC1,0x5A,0x08, +0x0A,0x0E,0x84,0x0E,0xDD,0x40,0xC8,0x07,0xFA,0x02,0xDD,0x40,0xC8,0x04,0xFA,0x06, +0xDD,0x40,0xC0,0x26,0xEB,0x55,0xEA,0x74,0xD5,0x22,0x5A,0x08,0x0B,0x04,0xDD,0x47, +0xD5,0xF8,0x5A,0x08,0x0C,0x18,0xFA,0x0A,0xDD,0x40,0xC0,0x05,0xEB,0x65,0xDD,0x5C, +0xB6,0x06,0xD5,0x0A,0xFA,0x13,0xDD,0x40,0xC8,0xFA,0xFA,0x0E,0xDD,0x40,0xC8,0xF7, +0xFA,0x18,0xDD,0x40,0xC8,0xF4,0xDD,0x47,0xDD,0x40,0xC0,0x0A,0xEB,0x65,0xDD,0x5C, +0xD5,0x06,0x5A,0x08,0x0F,0x06,0xEB,0x82,0x58,0x00,0x06,0x04,0xB6,0x06,0xFC,0x80, +0xC0,0x04,0x5A,0x00,0x01,0x1A,0xD5,0x29,0xFC,0x00,0xFA,0x13,0x80,0xC1,0xDD,0x40, +0xC0,0x07,0xEB,0x65,0xDD,0x5C,0x4C,0x60,0x40,0x04,0x84,0x01,0xD5,0x20,0xFA,0x18, +0xDD,0x40,0xC0,0x1D,0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x40,0x03,0x0C,0x03, +0x5C,0x00,0x00,0x01,0xD5,0x14,0x46,0x21,0x00,0x03,0x58,0x21,0x00,0x78,0x4C,0x11, +0x00,0x10,0x50,0x01,0x75,0xE0,0x4C,0x10,0x00,0x0C,0x50,0x21,0x70,0xD0,0x40,0x00, +0x88,0x03,0x5C,0x00,0x00,0x01,0xDD,0x9E,0x84,0x00,0xDD,0x9E,0xFC,0x80,0x84,0x01, +0xDD,0x9E,0xEA,0x4C,0x00,0x00,0x80,0x70,0x00,0x10,0x80,0x71,0x8C,0x01,0x42,0x00, +0x80,0x73,0x96,0x01,0x2E,0x37,0xFC,0xF7,0x9E,0x86,0xEB,0x5B,0x58,0x10,0x80,0x00, +0xEA,0xBD,0xEB,0x6B,0x9E,0x85,0x02,0x31,0x81,0x64,0xEA,0xBD,0x46,0x21,0x00,0x07, +0x04,0x21,0x03,0xF2,0x9E,0xC4,0x96,0x91,0x38,0x20,0x8D,0x09,0x9E,0x83,0x3C,0x33, +0xFE,0xD8,0xEA,0xBD,0x9E,0x82,0x3C,0x33,0xFE,0xEC,0xEA,0xBD,0x46,0x21,0x00,0x07, +0x04,0x21,0x03,0xC1,0x9E,0xC1,0x96,0x91,0x92,0x48,0x38,0x20,0x8D,0x09,0x46,0x21, +0x00,0x07,0x04,0x21,0x03,0xC1,0x96,0x90,0x38,0x20,0x81,0x09,0xDD,0x9E,0x44,0x10, +0x22,0xB8,0x50,0x00,0x7C,0x18,0xFE,0x0C,0x44,0x11,0x86,0xA0,0xEA,0xDF,0x50,0x00, +0x00,0x56,0x96,0x01,0xDD,0x9E,0xFC,0x00,0xFA,0x02,0xDD,0x40,0xC0,0x05,0x2E,0x10, +0x00,0x91,0xDD,0x5A,0xD5,0x0E,0xFA,0x06,0xDD,0x40,0xC0,0x0F,0x49,0x00,0x44,0x32, +0xEA,0x2A,0x5A,0x08,0x0C,0x05,0x2E,0x00,0x00,0x93,0xD5,0x03,0x2E,0x00,0x00,0x92, +0xFE,0x0C,0x49,0xFF,0xFF,0xDE,0xD5,0x03,0x49,0xFF,0xF9,0x47,0x46,0x11,0x00,0x07, +0x14,0x00,0x83,0xF2,0xFC,0x80,0xFC,0x00,0x84,0xA0,0x97,0x29,0xE2,0x81,0xE8,0x10, +0xA5,0x18,0x38,0x61,0x15,0x01,0x5A,0x08,0x01,0x06,0xE2,0x86,0x40,0x43,0x3C,0x1B, +0xD5,0x03,0x42,0x42,0x18,0x01,0x1A,0x41,0x80,0x01,0x8C,0xA1,0xD5,0xEF,0xFC,0x80, +0xFC,0x20,0x2F,0x17,0xFD,0x1B,0x84,0x60,0xFB,0x94,0x2E,0x20,0x00,0xE1,0xE2,0x62, +0xE8,0x22,0x42,0x71,0xC0,0x24,0x84,0x40,0x2E,0x40,0x00,0xE0,0xE2,0x44,0xE8,0x18, +0x99,0x57,0x40,0x60,0x94,0x20,0x22,0x43,0x00,0x00,0x38,0x50,0x15,0x11,0x4F,0x12, +0x00,0x0A,0x43,0x32,0x00,0x03,0x42,0xF2,0x80,0x03,0xE1,0xEF,0x40,0x42,0xBC,0x1B, +0xD5,0x03,0x42,0x42,0x90,0x00,0x8C,0x41,0xAD,0x30,0x96,0x90,0xD5,0xE6,0x8C,0x61, +0x96,0xD8,0xD5,0xDC,0xFC,0xA0,0xFC,0x00,0x3F,0xCF,0xFD,0x90,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x10,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05,0xEB,0x52, +0xEA,0xFC,0xD5,0x05,0xEB,0x41,0xC8,0x06,0xEB,0x55,0xEA,0xAD,0xEB,0x5B,0xEA,0x91, +0xEB,0x3D,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x02, +0xEA,0x50,0xFC,0x80,0xFC,0x00,0x3C,0x0D,0xFF,0x76,0x3C,0x2D,0xFF,0x6C,0xE2,0x40, +0xE8,0x19,0xEB,0x62,0x04,0x00,0x00,0xB2,0x96,0x81,0xE2,0x41,0xE8,0x13,0x96,0x49, +0x92,0x10,0xEB,0x4B,0x46,0x11,0x00,0x07,0x14,0x00,0x80,0xB2,0xEB,0x41,0x5A,0x08, +0x01,0x0A,0xEA,0xB1,0xEB,0x5B,0xEA,0x91,0x46,0x21,0x00,0x03,0x58,0x21,0x0A,0x98, +0xDD,0x48,0xFC,0x80,0x46,0x38,0x00,0x30,0x4E,0x00,0x43,0x5F,0xCA,0xFE,0x4E,0x00, +0x43,0x62,0xDD,0x9E,0xFC,0x63,0x3F,0xCF,0xFD,0x8C,0x81,0x20,0xB1,0x81,0x3E,0x0F, +0xFA,0xD4,0x3B,0x00,0x4C,0x04,0x80,0xE1,0x80,0x26,0x3B,0x00,0xCC,0x24,0xA4,0x00, +0xAC,0x08,0x2E,0x80,0x00,0x8D,0x81,0x42,0x40,0x04,0x00,0x10,0x85,0x81,0x4E,0x04, +0x00,0x04,0x44,0xC0,0xFF,0xFF,0xEA,0x27,0x02,0x00,0x80,0x9C,0x02,0x30,0x80,0x0A, +0x40,0xB0,0x0C,0x01,0x84,0x0E,0xDD,0x40,0x40,0xB5,0xA4,0x08,0x84,0x60,0xC8,0x09, +0x54,0x44,0x00,0x7F,0x44,0x50,0x00,0x64,0xFF,0x2C,0x42,0x46,0x10,0x24,0x96,0xE3, +0x88,0x6B,0xBB,0x80,0x3C,0x0D,0xFF,0x63,0xFE,0x02,0xB8,0x84,0x84,0x04,0x49,0xFF, +0xFF,0xC3,0xB9,0x04,0xEB,0x58,0xEA,0x68,0x80,0x09,0x49,0x00,0x43,0x35,0x84,0x06, +0x42,0x64,0x80,0x73,0x40,0x25,0x00,0x13,0x84,0x00,0x46,0x41,0x00,0x00,0x58,0x42, +0x0B,0x14,0x44,0x30,0x01,0xB0,0x38,0x13,0x00,0x00,0x81,0x27,0x42,0x90,0x8C,0x73, +0x38,0x52,0x09,0x01,0x38,0x54,0x89,0x09,0x99,0x70,0xA7,0x69,0x81,0x27,0x50,0x11, +0x00,0x6C,0x42,0x92,0x8C,0x73,0x39,0x02,0x05,0x01,0x50,0x21,0x00,0x24,0x8C,0x02, +0x39,0x04,0x85,0x09,0x96,0x91,0x5A,0x08,0x06,0xE8,0xFC,0xE3,0x46,0x10,0x00,0xE0, +0xDD,0x43,0x8C,0x27,0xEA,0xCA,0x46,0x10,0x01,0xC0,0x8C,0x35,0x14,0x10,0x01,0x60, +0x46,0x10,0x02,0xA0,0x50,0x10,0x80,0x23,0x14,0x10,0x01,0x61,0x84,0x20,0x14,0x10, +0x01,0x62,0x14,0x10,0x01,0x63,0x14,0x10,0x01,0x64,0x14,0x10,0x01,0x65,0x14,0x10, +0x01,0x66,0x14,0x10,0x01,0x67,0x14,0x10,0x01,0x68,0xDD,0x9E,0xFC,0x60,0xEE,0xE0, +0x3E,0x1F,0xFA,0xE8,0x80,0xE0,0x50,0xAF,0x80,0x30,0x3E,0x0F,0xFB,0x0C,0xB1,0x83, +0x3B,0x00,0xE0,0x00,0x44,0x20,0x00,0xF0,0x3B,0x03,0x60,0x20,0x84,0x20,0x3B,0x00, +0x48,0x00,0x80,0x0A,0x3B,0x0F,0xC8,0x20,0xDD,0x42,0x84,0x20,0x80,0x0A,0xA8,0x41, +0xA8,0x42,0xA8,0x43,0xA8,0x44,0xA8,0x45,0xA8,0x46,0xF1,0x8C,0xFA,0x22,0x40,0x13, +0x84,0x57,0x96,0x90,0x81,0x3F,0x94,0x91,0x86,0x67,0x44,0x00,0x00,0x55,0x46,0xE3, +0x00,0x00,0x45,0x43,0x00,0x00,0xE6,0x42,0xE8,0x0A,0x38,0x53,0x08,0x00,0x84,0x20, +0x40,0x50,0x14,0x0C,0xF8,0x12,0x82,0x21,0x82,0x41,0xD5,0x3D,0xE6,0x48,0xE8,0x07, +0xEA,0xBE,0x41,0x20,0x04,0x0C,0xF8,0x08,0x82,0x21,0xD5,0x0C,0xE6,0x4E,0xE8,0x0C, +0xEA,0xBE,0x41,0x10,0x04,0x0C,0x84,0x20,0x80,0x61,0x80,0xE1,0x82,0x01,0x83,0xFF, +0x82,0x41,0x80,0xA1,0xD5,0x28,0xE6,0x54,0xE8,0x08,0xEA,0xBE,0x41,0x00,0x04,0x0C, +0x84,0x20,0x80,0x61,0x80,0xE1,0xD5,0x14,0xE6,0x5A,0xE8,0x08,0x38,0x73,0x08,0x00, +0x84,0x20,0x40,0x70,0x1C,0x0C,0x80,0x61,0xD5,0x0A,0x5C,0xF1,0x00,0x20,0xE8,0x0A, +0x38,0x33,0x08,0x00,0x84,0x20,0x40,0x30,0x0C,0x0C,0x80,0xE1,0x82,0x01,0x82,0x21, +0xD5,0xE0,0xEA,0xBE,0x84,0x60,0x40,0x10,0x04,0x0C,0x80,0xE3,0x82,0x03,0x82,0x23, +0x82,0x43,0x80,0xA3,0x80,0x93,0x85,0x60,0x88,0xAE,0x88,0x34,0x38,0x84,0xAE,0x02, +0x50,0xC2,0x00,0x01,0xEA,0x55,0x89,0x05,0x38,0x85,0x12,0x0A,0x39,0x25,0x32,0x0A, +0x50,0xC2,0x00,0x02,0xEA,0x55,0x39,0x15,0x32,0x0A,0x50,0xC2,0x00,0x03,0xEA,0x55, +0x39,0x05,0x32,0x0A,0x50,0xC2,0x00,0x04,0xEA,0x55,0x38,0x75,0x32,0x0A,0x50,0xD2, +0x00,0x05,0x50,0xC2,0x00,0x06,0xEA,0x55,0x54,0xD6,0x80,0xFF,0x8C,0x87,0x8D,0x61, +0x38,0x35,0x36,0x0A,0x97,0x20,0x38,0x15,0x32,0x0A,0x5A,0xB8,0x03,0xD9,0x50,0x19, +0x80,0x15,0x8C,0x41,0x55,0x30,0x80,0xFF,0x96,0x91,0x5B,0x30,0x31,0x04,0x48,0xFF, +0xFF,0x84,0x84,0x00,0x46,0x32,0x00,0x00,0x40,0x15,0x00,0x00,0x5A,0x00,0xC8,0x0A, +0x98,0x83,0xB4,0x81,0xB6,0x82,0xB4,0xA2,0xB4,0x81,0xDC,0xFC,0x8C,0x04,0xD5,0xF5, +0xED,0x20,0xFC,0xE0,0xFC,0x00,0x80,0xC0,0x5A,0x08,0x01,0x0C,0xDD,0x43,0x84,0x22, +0xEA,0x58,0x84,0x23,0xEA,0x46,0xEA,0x4F,0xC8,0x04,0xEA,0x42,0xE6,0x01,0xEA,0x66, +0x9E,0x31,0x96,0x40,0xE6,0x26,0xE8,0x18,0x84,0x43,0x40,0x10,0x08,0x16,0xE2,0x46, +0x2E,0x27,0xFD,0x09,0x96,0x00,0x40,0x27,0x88,0x20,0xEB,0x24,0xEB,0x32,0x96,0x90, +0x49,0xFF,0xFE,0xA2,0x5A,0x68,0x06,0x16,0xEA,0x4F,0x5A,0x08,0x11,0x13,0xEA,0x2B, +0x96,0x00,0xDD,0x58,0xD5,0x0E,0x5A,0x68,0x08,0x0D,0xEA,0x4F,0x8C,0x01,0x96,0x00, +0xE6,0x12,0xE9,0x02,0x84,0x00,0x3E,0x07,0xFD,0x09,0xEA,0x4F,0x49,0xFF,0xFF,0x10, +0xFC,0x80,0xFC,0x00,0x2E,0x17,0xFC,0xDC,0x2E,0x07,0xFF,0x93,0xFE,0x0C,0x3C,0x0F, +0xFF,0x7B,0x84,0x00,0x3C,0x0F,0xFF,0x75,0x49,0x00,0x2D,0x21,0xFC,0x80,0xFC,0x40, +0x2E,0x47,0xFF,0x61,0x84,0x20,0xFF,0x04,0x2F,0x20,0x00,0xE1,0x2F,0x30,0x00,0xE0, +0x80,0x41,0x84,0x01,0x80,0xA1,0x45,0x10,0x00,0x48,0x47,0x01,0x00,0x00,0x59,0x08, +0x06,0x04,0x44,0x90,0x00,0x64,0x4C,0x59,0x00,0x19,0x80,0xF0,0x42,0x72,0xC4,0x73, +0x84,0x60,0x97,0x98,0xE2,0xD3,0xE8,0x0E,0x38,0x63,0x8D,0x11,0x42,0xF3,0x24,0x24, +0xE0,0x8F,0xE8,0x04,0x8C,0x21,0x96,0x48,0x84,0x00,0x42,0x23,0x08,0x00,0x8C,0x61, +0xD5,0xF1,0x8C,0xA1,0x97,0x68,0xD5,0xE8,0x96,0x91,0x46,0x31,0x00,0x07,0x12,0x21, +0x87,0x99,0x96,0x49,0x46,0x21,0x00,0x07,0x12,0x11,0x07,0x9A,0xFC,0xC0,0x46,0x11, +0x00,0x07,0x04,0x20,0x80,0xB2,0xEA,0x2A,0x96,0xD1,0xFE,0xCC,0x2E,0x47,0xFF,0x6E, +0x2E,0x17,0xFF,0x67,0xFE,0x64,0xFE,0x0C,0xE2,0x03,0xE8,0x04,0x84,0x21,0x84,0x00, +0xD5,0x03,0x84,0x20,0x84,0x01,0x96,0x91,0x46,0x31,0x00,0x07,0x12,0x21,0x87,0x99, +0x96,0x49,0x46,0x21,0x00,0x07,0x12,0x11,0x07,0x9A,0xDD,0x9E,0xFC,0x42,0x44,0x00, +0x87,0x87,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xC6,0x3C,0x2D,0xFF,0x7E,0x84,0x00, +0x12,0x0F,0x80,0x07,0x12,0x0F,0x80,0x03,0x12,0x0F,0x80,0x02,0x12,0x0F,0x80,0x01, +0x84,0x1F,0x12,0x0F,0x80,0x06,0x12,0x0F,0x80,0x05,0x12,0x0F,0x80,0x04,0xEB,0x62, +0x00,0x70,0x0F,0x1C,0xEB,0x62,0x00,0x60,0x0F,0x1D,0xEB,0x62,0x00,0x00,0x0F,0x20, +0x97,0xF8,0x97,0xB0,0x54,0x90,0x00,0xFF,0x84,0xA0,0x44,0x10,0x05,0x10,0x98,0x15, +0xA4,0x00,0x96,0x01,0x12,0x0F,0x80,0x07,0xEA,0x25,0x02,0x3F,0x80,0x01,0xE2,0x60, +0xEA,0x25,0xE8,0x05,0x96,0x01,0x12,0x0F,0x80,0x01,0xD5,0x1F,0x02,0x3F,0x80,0x02, +0xE2,0x60,0xE8,0x0A,0xEA,0x22,0xEA,0xD6,0x4C,0x30,0x00,0x07,0xEA,0x25,0x96,0x01, +0x12,0x0F,0x80,0x02,0xD5,0x12,0xEA,0x25,0x02,0x3F,0x80,0x03,0xE2,0x60,0xE8,0x0D, +0xEA,0x22,0xEA,0xD6,0x4C,0x30,0x00,0x0A,0xEA,0x22,0xEA,0xD7,0x4C,0x30,0x00,0x06, +0xEA,0x25,0x96,0x01,0x12,0x0F,0x80,0x03,0xEA,0x22,0xEA,0x86,0xE2,0x60,0xE8,0x06, +0xEA,0x25,0x96,0x01,0x12,0x0F,0x80,0x04,0xD5,0x1F,0xEA,0x22,0xEA,0xE8,0xE2,0x60, +0xE8,0x0A,0xEA,0x22,0xEA,0x86,0x4C,0x30,0x00,0x07,0xEA,0x25,0x96,0x01,0x12,0x0F, +0x80,0x05,0xD5,0x12,0xEA,0x22,0x02,0x0F,0x80,0x06,0xE2,0x60,0xE8,0x0D,0xEA,0x22, +0xEA,0x86,0x4C,0x30,0x00,0x0A,0xEA,0x22,0xEA,0xE8,0x4C,0x30,0x00,0x06,0xEA,0x25, +0x96,0x01,0x12,0x0F,0x80,0x06,0x8C,0xA2,0xD9,0xAB,0x84,0x20,0xFA,0x44,0xEB,0x62, +0x58,0x00,0x0F,0x24,0xDD,0x42,0x49,0xFF,0xF6,0x58,0xFF,0xC4,0xEA,0x2A,0x40,0x73, +0x84,0xF7,0x02,0x2F,0x80,0x01,0x97,0xF9,0xE2,0xE2,0xE9,0x09,0xFF,0x84,0x02,0x2F, +0x80,0x04,0x40,0x63,0x04,0xD7,0x97,0xB1,0xE2,0x46,0xE8,0x07,0xEB,0x62,0xEA,0xE6, +0x46,0x11,0x00,0x07,0xEA,0x37,0xEA,0xE3,0xEB,0x41,0xC0,0x05,0x80,0x09,0x49,0xFF, +0xFF,0x40,0xD5,0x04,0x80,0x09,0x49,0xFF,0xFF,0x04,0xC8,0x07,0xEB,0x62,0xEA,0xE6, +0x46,0x11,0x00,0x07,0xEB,0x04,0xEA,0xE3,0xEB,0x62,0xEA,0xE6,0xC8,0x06,0x44,0x0F, +0xAA,0xAA,0x46,0x11,0x00,0x07,0xEA,0xE3,0xEA,0xD6,0x46,0x11,0x00,0x07,0x96,0x01, +0x12,0x00,0x87,0x93,0xEA,0xD7,0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x94, +0x02,0x0F,0x80,0x03,0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x95,0xEA,0x86, +0x46,0x11,0x00,0x07,0x96,0x01,0x12,0x00,0x87,0x96,0xEA,0xE8,0x46,0x11,0x00,0x07, +0x96,0x01,0x12,0x00,0x87,0x97,0x02,0x0F,0x80,0x06,0x46,0x11,0x00,0x07,0x96,0x01, +0x12,0x00,0x87,0x98,0x84,0x00,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0x9B,0x44,0x00, +0xA6,0x6A,0x46,0x11,0x00,0x07,0x14,0x00,0x83,0xC6,0xFC,0xC2,0x46,0x08,0x00,0x20, +0x04,0x10,0x00,0x0E,0x42,0x10,0xD4,0x08,0xEB,0x1D,0x4E,0x00,0x3D,0x9D,0x4E,0x00, +0x3D,0xA2,0x4E,0x00,0x3D,0x9E,0x44,0x10,0xFB,0xFF,0x4E,0x00,0x3D,0x9C,0x4E,0x00, +0x3D,0xA2,0x46,0x11,0x00,0x07,0x02,0x10,0x80,0x40,0x84,0x45,0xE6,0x22,0x46,0x19, +0x00,0x68,0xE9,0x02,0x84,0x4F,0x10,0x20,0x89,0x04,0x02,0x10,0x00,0x1E,0x84,0x44, +0x58,0x10,0x80,0x01,0xEA,0x34,0x02,0x10,0x00,0x1E,0xEA,0xB2,0xEA,0x34,0x84,0x20, +0xEA,0x79,0xEA,0x60,0xEB,0x31,0xEA,0xE1,0xEA,0x3C,0x10,0x20,0x80,0x28,0xF8,0x76, +0xDD,0x9E,0xFC,0x20,0x46,0x68,0x00,0x20,0x10,0x03,0x00,0x48,0x05,0x03,0x00,0x0E, +0x46,0x7F,0xFE,0x3F,0x84,0x07,0x50,0x73,0x8F,0xFF,0xFE,0x46,0x40,0x78,0x1C,0x02, +0x83,0x86,0x40,0x73,0x86,0x44,0xBF,0x8E,0xB9,0x0E,0xFE,0x86,0x66,0x10,0x80,0x38, +0x40,0x20,0x88,0x64,0xBA,0x8E,0x12,0x33,0x00,0x9C,0x12,0x43,0x00,0x8A,0x12,0x53, +0x00,0x0A,0xFC,0xA0,0xFC,0x00,0xEA,0x4C,0x00,0x50,0x81,0x2C,0x84,0x0A,0xFF,0x44, +0x00,0x10,0x81,0x39,0x80,0x65,0xDD,0x5A,0x42,0x30,0x80,0x73,0x84,0x46,0x96,0xD9, +0xFA,0x01,0x84,0x27,0x84,0x81,0xF8,0x17,0xFC,0x80,0xFC,0x00,0xEA,0x4C,0x00,0x40, +0x81,0x2D,0x84,0x0A,0xFF,0x04,0x00,0x30,0x81,0x3A,0x80,0xA4,0xDD,0x5A,0x00,0x20, +0x81,0x2F,0x42,0x51,0x80,0x73,0x00,0x00,0x81,0x2E,0x96,0xE9,0x40,0x11,0x10,0x09, +0x80,0xA4,0x96,0x9F,0x49,0xFF,0xFF,0xB7,0xFC,0x80,0xFC,0x01,0x84,0x20,0xF0,0x81, +0x46,0x09,0x00,0x68,0x10,0x10,0x09,0x04,0x84,0x0E,0xDD,0x40,0xC0,0x35,0x84,0x0E, +0xDD,0x40,0xC0,0x39,0xDD,0x43,0xEB,0x11,0x44,0x10,0xFF,0xDF,0x4E,0x00,0x3D,0x1B, +0x44,0x10,0xFE,0xFF,0x4E,0x00,0x3D,0x17,0x4E,0x00,0x3D,0x13,0x44,0x10,0xFB,0xFF, +0xFE,0x56,0xEA,0x34,0x51,0xC0,0x00,0x38,0xB9,0x7F,0x2E,0x20,0x00,0x77,0x66,0x10, +0x8F,0x00,0x96,0x9F,0x40,0x10,0x89,0x04,0xB9,0xFF,0x44,0x10,0x00,0x32,0x12,0x10, +0x00,0x9A,0x83,0xFF,0x84,0x21,0xEA,0x79,0xB4,0x5C,0x46,0x1F,0xFE,0x3F,0xEA,0x81, +0xFE,0x56,0x42,0x10,0xC8,0x08,0xB6,0x3C,0xB4,0x3C,0x66,0x10,0x80,0x38,0x58,0x10, +0x80,0x08,0xB6,0x3C,0xD5,0x18,0xFA,0x02,0xDD,0x40,0xC8,0xCA,0xFA,0x06,0xDD,0x40, +0xC8,0xC7,0xD5,0x17,0xFA,0x02,0xDD,0x40,0xC0,0x06,0xF8,0x08,0xF0,0x01,0x49,0xFF, +0xFF,0x8B,0xD5,0x09,0xFA,0x06,0xDD,0x40,0xC0,0x06,0x49,0xFF,0xFF,0x31,0xF0,0x01, +0x49,0xFF,0xFF,0x95,0xF0,0x01,0x49,0xFF,0xFC,0xCB,0xEA,0x4F,0x49,0xFF,0xFC,0xE8, +0xDD,0x47,0xDD,0x40,0xEA,0x27,0xC0,0x02,0x84,0x01,0x10,0x00,0x80,0x68,0x10,0x00, +0x80,0x6C,0xFC,0x81,0xFC,0x00,0x84,0x07,0xDD,0x40,0xC0,0x1F,0xDD,0x4D,0x5A,0x00, +0x07,0x05,0x66,0x10,0x00,0x02,0xC9,0x04,0x49,0xFF,0xFD,0xC5,0xD5,0x1C,0x2E,0x10, +0x00,0x97,0xEA,0x5C,0xC1,0x0C,0x5A,0x00,0x06,0x0B,0xDD,0x43,0x84,0x26,0xEB,0x34, +0x84,0x20,0xEB,0x36,0x44,0x1F,0xFC,0x78,0x4E,0x00,0x41,0x1F,0x44,0x00,0x24,0x24, +0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x07,0x84,0x08,0xDD,0x40,0xC0,0x03,0xF9,0x85, +0xD5,0x02,0xF9,0x49,0xFC,0x80,0xEA,0x30,0x96,0x04,0xC0,0x09,0xFC,0x00,0x49,0x00, +0x34,0xBD,0xC8,0xFE,0x49,0x00,0x34,0x9F,0xC8,0xFE,0xFC,0x80,0xDD,0x9E,0xFC,0x00, +0xFA,0x13,0xDD,0x40,0xC0,0x0F,0xEB,0x52,0x58,0x00,0x04,0x74,0x3C,0x0F,0xFF,0x7E, +0x84,0x21,0x84,0x08,0xEA,0x3D,0x84,0x01,0xEB,0x10,0xEA,0xCF,0x84,0x00,0xEB,0x2C, +0xD5,0x0B,0xFA,0x18,0xDD,0x40,0xC8,0xF0,0xEB,0x65,0xEB,0x48,0x3C,0x0F,0xFF,0x7E, +0x84,0x07,0x84,0x21,0xEA,0x3D,0xFC,0x80,0xEA,0x30,0x96,0x04,0xC0,0x09,0xFC,0x00, +0x49,0x00,0x34,0x82,0xC8,0xFE,0x49,0x00,0x34,0x88,0xC8,0xFE,0xFC,0x80,0xDD,0x9E, +0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x58,0x00,0x00,0x10,0xAE,0x0B,0x4E,0x00,0x04,0xBF, +0x46,0x11,0x00,0x07,0xEA,0x6F,0xF8,0xBF,0xFC,0x80,0xFC,0x00,0x80,0xC0,0xFA,0x08, +0xDD,0x40,0xC0,0x0D,0xEA,0x30,0xEA,0x8D,0xC0,0x0A,0x40,0x03,0x10,0x09,0xEA,0x27, +0x12,0x00,0x82,0xB8,0x50,0x00,0x00,0x64,0x12,0x00,0x80,0xB6,0xFA,0x11,0xDD,0x40, +0xC0,0x0C,0xEA,0x30,0xEA,0x8D,0xC0,0x09,0x92,0xC1,0xDD,0x43,0x12,0x60,0x02,0xB8, +0x50,0x63,0x00,0x64,0x12,0x60,0x00,0xB6,0xFC,0x80,0xFC,0x00,0xEB,0x7C,0x58,0x10, +0x86,0x58,0xEA,0xB1,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xFA,0x07,0xDD,0x40,0xC0,0x05,0xEA,0x59,0x44,0x00,0x56,0x56,0xD5,0x21, +0xFA,0x08,0xDD,0x40,0xC0,0x18,0xB8,0x00,0x5A,0x08,0x07,0x30,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x08,0x49,0xFF,0xFF,0xE3,0xEB,0x55,0xEA,0xAD,0xEB,0x5B,0xEA,0x91, +0xEB,0x3D,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x1D, +0xEB,0x49,0xD5,0x11,0xFA,0x0B,0xDD,0x40,0xC0,0x08,0xEA,0x59,0x44,0x00,0x51,0x61, +0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x11,0xFA,0x0C,0xDD,0x40,0xC0,0x06,0xB8,0x00, +0x5A,0x08,0x07,0x0C,0xEA,0x50,0xD5,0x09,0xFA,0x0D,0xDD,0x40,0xC0,0xFC,0xB8,0x00, +0x5A,0x08,0x07,0x04,0x49,0xFF,0xFF,0xBB,0xFC,0x80,0xFC,0x00,0xEB,0x7C,0x58,0x10, +0x86,0x58,0xEA,0x5B,0x50,0x20,0x8A,0x20,0xDD,0x48,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xFA,0x0F,0xDD,0x40,0xC0,0x05,0xEA,0x59,0x44,0x00,0x50,0x60,0xD5,0x24, +0xFA,0x11,0xDD,0x40,0xC0,0x1B,0xB8,0x00,0x5A,0x08,0x08,0x33,0xB8,0x12,0xB9,0x08, +0xE2,0x20,0xE8,0x0A,0x49,0xFF,0xFF,0xE3,0x49,0x00,0x2A,0xC8,0xEB,0x52,0xEA,0xFC, +0xEB,0x5B,0xEA,0x91,0xEB,0x3D,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x03,0x8C,0x01, +0xB8,0x88,0xBD,0x08,0xD9,0x1D,0xEB,0x49,0xD5,0x11,0xFA,0x14,0xDD,0x40,0xC0,0x08, +0xEA,0x59,0x44,0x00,0x52,0x62,0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x11,0xFA,0x16, +0xDD,0x40,0xC0,0x06,0xB8,0x00,0x5A,0x08,0x08,0x0C,0xEA,0x50,0xD5,0x09,0xFA,0x17, +0xDD,0x40,0xC0,0xFC,0xB8,0x00,0x5A,0x08,0x08,0x04,0x49,0xFF,0xFF,0xB8,0xFC,0x80, +0xFC,0x00,0xEA,0x4C,0xA6,0x0B,0x66,0x00,0x00,0x10,0xAE,0x0B,0x84,0x00,0x46,0x11, +0x00,0x07,0xEA,0x6F,0x49,0xFF,0xFF,0x01,0xF8,0x46,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xFA,0x1D,0xDD,0x40,0xC0,0x0B,0xEA,0x30,0x96,0x04,0xC0,0x02,0xEA,0x59, +0x44,0x00,0xBF,0xBF,0x46,0x11,0x00,0x07,0xEA,0x32,0xD5,0x30,0xFA,0x1E,0xDD,0x40, +0xC0,0x2C,0xEA,0x30,0x96,0x04,0xC0,0x04,0xB8,0x00,0x5A,0x08,0x07,0x28,0xB8,0x12, +0xB9,0x08,0xE2,0x20,0xE8,0x17,0x84,0x01,0x44,0x10,0x02,0x88,0xEB,0x58,0xEA,0x68, +0x46,0x31,0x00,0x02,0x58,0x31,0x86,0x58,0x49,0xFF,0xFA,0x7F,0x84,0x00,0x44,0x10, +0x02,0x88,0xEB,0x58,0xEA,0x68,0x46,0x31,0x00,0x03,0x58,0x31,0x80,0x78,0x49,0xFF, +0xFA,0x74,0xB8,0x08,0xB9,0x12,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x88,0xD5,0x06, +0xEA,0x30,0x96,0x04,0xC0,0x02,0xEB,0x49,0xEA,0x50,0xFC,0x80,0xFC,0x00,0x84,0x0E, +0xDD,0x40,0xC0,0x03,0xEA,0x50,0xF8,0x0C,0xFA,0x02,0xDD,0x40,0xC8,0xFC,0xFA,0x06, +0xDD,0x40,0xC8,0xF9,0x84,0x0A,0xDD,0x40,0xC0,0x05,0x49,0xFF,0xFE,0x85,0x48,0x00, +0x00,0x3A,0xFA,0x0A,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x12,0xD5,0x33,0xFA,0x0E, +0xDD,0x40,0xC8,0xFB,0xFA,0x13,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x51,0xD5,0x2A, +0xFA,0x18,0xDD,0x40,0xC8,0xFB,0xFA,0x1C,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x8A, +0xD5,0x21,0xDD,0x47,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xFF,0x92,0xD5,0x1B,0x84,0x06, +0xDD,0x40,0xC0,0x0B,0xEA,0x56,0x66,0x00,0x00,0x08,0x3E,0x07,0xFF,0x5A,0x84,0x00, +0xEB,0x10,0x84,0x00,0x3C,0x0F,0xFF,0x7B,0x49,0xFF,0xFA,0x67,0xEB,0x62,0x04,0x50, +0x03,0xC6,0x44,0x00,0x6A,0xA6,0xD8,0x06,0x84,0x02,0xDD,0x40,0xC0,0x03,0x49,0xFF, +0xFC,0x7F,0xFC,0x80,0xFC,0x00,0xDD,0x4C,0x96,0x04,0xC0,0x16,0xEA,0x36,0xC0,0x07, +0x2E,0x07,0xFE,0x31,0x2E,0x17,0xFF,0xA9,0xE2,0x01,0xE9,0x05,0x84,0x00,0x3E,0x07, +0xFE,0x31,0xD5,0x0C,0x8C,0x01,0x3E,0x07,0xFE,0x31,0x2E,0x07,0xFE,0x30,0x8C,0x01, +0x3E,0x07,0xFE,0x30,0xD5,0x03,0x84,0x02,0xEA,0x6B,0xFC,0x80,0xFC,0x40,0xEA,0x23, +0x84,0x24,0x9D,0x82,0x8E,0x01,0xEA,0xDF,0x46,0x90,0x0F,0xFF,0x88,0xC0,0x97,0xB0, +0x84,0xE0,0x50,0x94,0x8F,0xFF,0xC6,0x12,0x5A,0x68,0x01,0x09,0x52,0x73,0xFE,0x03, +0x97,0xF9,0x40,0x04,0x9F,0x04,0xDD,0x4A,0xD5,0x06,0x84,0x1F,0x50,0x73,0x83,0xFC, +0xDD,0x4A,0x97,0xF9,0x8E,0xC1,0x97,0xB0,0xD5,0xEF,0x3E,0x67,0xFC,0xD2,0xFC,0xC0, +0xFC,0x60,0x80,0xC0,0x3C,0xCD,0xFF,0x81,0x2E,0x87,0xFC,0xE0,0x3C,0x9D,0xFF,0x70, +0xEA,0x4E,0xEA,0xED,0x3C,0x0D,0xFF,0x78,0xC0,0x04,0x00,0x73,0x00,0x92,0xC7,0x03, +0x2E,0x77,0xFD,0x20,0x85,0x60,0x81,0xA6,0x81,0xCB,0xEA,0x23,0x40,0xF7,0x00,0x06, +0xE8,0x33,0xEA,0xF8,0xEA,0xA5,0xC0,0x0B,0x04,0x16,0x80,0x01,0x96,0x09,0xEA,0xB0, +0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0xB4,0x2D,0xD5,0x0A,0xB4,0x2D,0x96,0x09, +0xEA,0xB0,0x96,0x49,0x96,0x01,0x40,0x20,0x05,0x15,0x04,0x16,0x80,0x01,0x96,0x09, +0xEA,0xB0,0x96,0x01,0x96,0x49,0x40,0x10,0x05,0x15,0x40,0x01,0x06,0x00,0xDD,0x4A, +0xB4,0x2D,0x04,0x26,0x80,0x01,0x96,0x08,0x40,0x10,0x05,0x1C,0x89,0x61,0x40,0xB5, +0x89,0x1C,0x96,0x90,0x40,0x05,0x88,0x00,0x40,0xB0,0x00,0x13,0x50,0xE7,0x00,0x01, +0x50,0xD6,0x80,0x0C,0xD5,0xCB,0x00,0x03,0x00,0x20,0x00,0x23,0x00,0x14,0x00,0x13, +0x00,0x08,0xEA,0xE9,0x40,0x00,0x09,0x00,0x88,0x01,0x00,0x13,0x00,0x2C,0xEA,0x8A, +0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x23,0xE6,0x05,0xE9,0x11,0x00,0x03,0x00,0x50, +0x00,0x23,0x00,0x44,0x00,0x13,0x00,0x38,0xEA,0xE9,0x40,0x00,0x09,0x00,0x88,0x01, +0x00,0x13,0x00,0x5C,0xEA,0x8A,0xDD,0x4A,0x84,0x0A,0xDD,0x50,0xEA,0x23,0xE6,0x09, +0xE9,0x0A,0x00,0x13,0x00,0x74,0x00,0x03,0x00,0x68,0x40,0x00,0x05,0x00,0xDD,0x4A, +0x84,0x0A,0xDD,0x50,0xEB,0x39,0x84,0x20,0x84,0x6C,0xE2,0x22,0xE8,0x0B,0x80,0x06, +0x42,0x00,0x8C,0x73,0x8C,0x21,0x00,0x00,0x00,0x08,0x88,0x0B,0x40,0xB0,0x00,0x13, +0xD5,0xF5,0xEA,0x57,0xEA,0x8D,0xC0,0x15,0xEA,0xE5,0xEA,0x29,0xE3,0x0C,0x94,0x05, +0x40,0xA0,0x28,0x64,0x40,0xA5,0x04,0x24,0x8F,0x23,0x40,0x85,0x3C,0x04,0xE7,0x21, +0x40,0xF4,0x3C,0x44,0x40,0x77,0x9C,0x84,0x12,0x73,0x00,0x48,0x3E,0x17,0xFD,0x16, +0x02,0x23,0x00,0x48,0x00,0x13,0x00,0x92,0x40,0x31,0x20,0x09,0x96,0x10,0x96,0x90, +0x88,0x43,0x58,0x10,0x80,0xF0,0x40,0x00,0x81,0x00,0x88,0x22,0x40,0x00,0x0E,0x00, +0x89,0x61,0x40,0x00,0x2F,0x01,0xDD,0x4A,0xFC,0xE0,0xFC,0x00,0xEA,0x6C,0x5A,0x08, +0x01,0x04,0x49,0x00,0x2C,0x96,0x49,0x00,0x2C,0x8F,0x80,0xC0,0xEA,0x6C,0xC0,0x07, +0xEA,0x6C,0x5A,0x08,0x01,0x0A,0xEA,0x69,0x5A,0x08,0x01,0x07,0x3C,0x03,0xFE,0x9F, +0x8C,0x01,0x3C,0x0B,0xFE,0x9F,0xEA,0x9E,0xC8,0x1B,0xEA,0x6C,0xC0,0x07,0xEA,0x6C, +0x5A,0x08,0x01,0x17,0xEA,0x69,0x5A,0x08,0x01,0x14,0x84,0x01,0x3E,0x07,0xFC,0xBF, +0x49,0xFF,0xFE,0xEA,0xEA,0x36,0xC8,0x0C,0xEA,0xF0,0xC0,0x05,0x80,0x06,0x49,0xFF, +0xFF,0x21,0xD5,0x05,0x2E,0x07,0xFE,0x32,0xC0,0x03,0xEA,0x95,0xEA,0xC2,0xEA,0xF0, +0x3E,0x07,0xFE,0x32,0xFC,0x80,0xFC,0x40,0x3F,0xCF,0xFD,0x90,0x80,0xC0,0x49,0xFF, +0xFE,0xD3,0xEA,0x36,0x81,0x20,0x49,0x00,0x3D,0x51,0x4E,0x02,0x00,0xF3,0x5C,0x94, +0x80,0x01,0x4E,0x92,0x00,0x07,0x2E,0x07,0xFC,0xD2,0xC0,0x03,0xEA,0x95,0xEA,0xFB, +0xBA,0x00,0x9E,0x17,0xE6,0x02,0xEA,0x87,0xE8,0x08,0xC9,0x07,0x5A,0x20,0x07,0x03, +0xEA,0xFB,0x49,0x00,0x18,0xCD,0xEA,0xFB,0x4E,0x12,0x00,0x50,0x84,0x3F,0x3E,0x17, +0xFD,0xDC,0x2E,0x17,0xFC,0xC2,0xC9,0x49,0x4E,0x92,0x00,0x48,0xDD,0x4C,0x96,0x04, +0xC8,0x02,0xEA,0x6B,0x2E,0x07,0xFC,0xC0,0x44,0x10,0xA5,0x5A,0xEB,0x4B,0xEA,0x87, +0xEA,0x8A,0xDD,0x4A,0x2E,0x67,0xFC,0xC0,0x44,0x2F,0xA5,0x5A,0x44,0x10,0x00,0x3D, +0x88,0x46,0xEA,0x9E,0xFF,0x8C,0x40,0x21,0x01,0x00,0x8C,0xC2,0xEB,0x82,0x58,0x00, +0x00,0x00,0x40,0x60,0x18,0x20,0x96,0x91,0x80,0xA6,0x50,0x03,0x00,0x7A,0x0A,0x12, +0x80,0x01,0x88,0x41,0x96,0x91,0xD8,0xFC,0xFE,0x92,0x40,0x71,0x40,0x08,0x85,0x40, +0xA4,0x30,0x5A,0xA8,0x1E,0x05,0x8C,0xC2,0x88,0x07,0xD5,0x05,0xA4,0x71,0x8C,0xC4, +0x40,0x00,0x06,0x00,0xDD,0x4A,0x8D,0x41,0xFA,0x0E,0xDD,0x50,0x5A,0xA8,0x1F,0xF2, +0x2E,0x07,0xFC,0xC0,0x8C,0x01,0x96,0x00,0xEA,0xD9,0x2E,0x17,0xFC,0xC9,0xE2,0x01, +0xE9,0x21,0x84,0x00,0xEA,0xD9,0xD5,0x1E,0x00,0x23,0x00,0x92,0x4E,0x23,0x00,0x7A, +0xEA,0xCB,0xEA,0x5C,0xC1,0x09,0x2E,0x57,0xFD,0x1D,0x2E,0x17,0xFD,0x16,0xD1,0x04, +0xE6,0x02,0x4E,0xF2,0x00,0x6F,0xEA,0x69,0xC8,0x0D,0xB8,0x14,0xC8,0x04,0x2E,0x07, +0xFC,0xC2,0xC0,0x08,0x4E,0x92,0x00,0x04,0xEA,0x95,0xD5,0x04,0x84,0x01,0x3E,0x07, +0xFC,0xD2,0x2E,0x07,0xFC,0xC2,0x4E,0x02,0x00,0x6D,0x4E,0x92,0x00,0x6B,0xDD,0x4C, +0x96,0x04,0xC8,0x02,0xEA,0x6B,0x2E,0x07,0xFC,0xC1,0x8C,0x01,0x96,0x00,0x3E,0x07, +0xFC,0xC1,0x2E,0x17,0xFC,0xC4,0xE2,0x20,0xE8,0x04,0x84,0x01,0x3E,0x07,0xFC,0xC1, +0x2E,0x07,0xFC,0xC1,0x2E,0x77,0xFC,0xC8,0x9E,0x41,0x92,0xE1,0xFF,0xCC,0xEB,0x5B, +0xEB,0x33,0x40,0x70,0x9C,0x20,0x2E,0x17,0xFC,0xEC,0xC1,0x11,0x44,0x10,0xA3,0x3A, +0xEB,0x4B,0xEA,0x87,0xEA,0x8A,0xDD,0x4A,0x2E,0x17,0xFC,0xC1,0x44,0x0F,0xA3,0x3A, +0x88,0x01,0xEA,0x87,0x40,0x00,0x05,0x00,0x96,0x01,0xD5,0x07,0x46,0x00,0x40,0x30, +0x50,0x00,0x02,0x01,0xDD,0x4A,0x84,0x0A,0x2E,0x27,0xFC,0xC8,0x84,0x20,0x92,0x41, +0xE2,0x22,0xE8,0x07,0x38,0x33,0x85,0x01,0x8C,0x21,0x88,0x03,0x96,0x01,0xD5,0xF9, +0xFE,0x02,0x40,0x60,0x40,0x08,0x85,0x20,0x2E,0x17,0xFC,0xC8,0x8C,0x22,0x90,0x22, +0xE3,0x21,0xE8,0x1F,0x8E,0x21,0xA4,0x38,0x4C,0x90,0xC0,0x05,0x8C,0xE2,0x88,0x06, +0xD5,0x05,0xA4,0x79,0x8C,0xE4,0x40,0x00,0x06,0x00,0xDD,0x4A,0x8D,0x21,0xD5,0xED, +0x5A,0x90,0x01,0x04,0x48,0xFF,0xFF,0x9F,0xEA,0x69,0x4E,0x03,0xFF,0x9C,0xB8,0x14, +0xC0,0x03,0x4E,0x22,0xFF,0x93,0x80,0x06,0x49,0xFF,0xFE,0x1C,0x48,0xFF,0xFF,0x93, +0xFC,0xC0,0xFC,0x20,0x80,0xE0,0x80,0xC1,0x49,0x00,0x28,0x2E,0xDD,0x4D,0x84,0x20, +0x49,0x00,0x2A,0x20,0xEA,0x7A,0x3E,0x20,0x00,0xE1,0x84,0x00,0xEA,0xF1,0x3E,0x07, +0xFC,0xCC,0xEB,0x5B,0x10,0x00,0x86,0x01,0xFA,0x00,0x3E,0x07,0xFC,0xBB,0xFA,0x14, +0xFA,0x30,0x49,0x00,0x3B,0x85,0xEB,0x39,0x84,0x25,0xFE,0x8C,0x96,0x90,0x54,0x01, +0x00,0x03,0xC8,0x03,0x8C,0x44,0xD5,0x02,0x8C,0x48,0x96,0x90,0x66,0x21,0x00,0x03, +0x52,0x21,0x00,0x7A,0x96,0x90,0x3E,0x27,0xFC,0xC8,0x2E,0x40,0x00,0xE1,0x2E,0x30, +0x00,0xE0,0x2E,0x10,0x00,0xE9,0x42,0x12,0x0C,0x73,0x92,0x41,0x40,0x20,0x88,0x17, +0x96,0x90,0xC0,0x02,0x8C,0x41,0x3E,0x27,0xFC,0xC4,0x44,0x20,0x00,0x3D,0x40,0x20, +0x88,0x37,0x96,0x90,0xC1,0x02,0x8C,0x41,0x3E,0x27,0xFC,0xC9,0x84,0x00,0xEA,0xD9, +0x2E,0x17,0xFF,0x67,0x3E,0x17,0xFC,0xD4,0x3E,0x07,0xFC,0xD2,0x2E,0x07,0xFF,0xCE, +0x2E,0x27,0xFF,0xCF,0x40,0x21,0x01,0x04,0x3C,0x2E,0x00,0x36,0x2E,0x07,0xFF,0xD0, +0x2E,0x17,0xFF,0xD1,0x40,0x10,0x81,0x04,0x3C,0x1E,0x00,0x37,0x40,0x21,0x0C,0x57, +0x40,0x10,0x90,0x37,0x3E,0x20,0x00,0xEA,0x3E,0x10,0x00,0xEB,0x8C,0x82,0x3E,0x47, +0xFC,0xCE,0x8C,0x62,0x3E,0x37,0xFC,0xBD,0x84,0x00,0x3C,0x0B,0xFE,0x9D,0xCF,0x21, +0xEB,0x62,0x14,0x70,0x03,0xF1,0xDD,0x4C,0x96,0x04,0xC0,0x05,0x84,0x01,0xEA,0xD0, +0x84,0x02,0xEA,0x6B,0xEB,0x62,0x58,0x00,0x0F,0x44,0x84,0x20,0x44,0x20,0x00,0x3C, +0xDD,0x42,0xCE,0x08,0xEB,0x62,0x58,0x00,0x03,0xB0,0x80,0x26,0x44,0x20,0x00,0x3C, +0xDD,0x42,0xEB,0x62,0x58,0x00,0x0F,0x80,0x84,0x20,0x44,0x20,0x00,0x40,0xDD,0x42, +0x46,0x19,0x00,0x08,0xA4,0x08,0x96,0x01,0x3C,0x0B,0xFE,0x9A,0x92,0x01,0x3C,0x0B, +0xFE,0x9B,0xA4,0x0A,0x3C,0x0B,0xFE,0x99,0x49,0x00,0x05,0x0C,0x84,0x1F,0x3E,0x07, +0xFD,0xDC,0x84,0x00,0xEB,0x0A,0x3E,0x07,0xFC,0xC3,0x84,0x00,0x3C,0x0B,0xFE,0x9F, +0xFC,0xA0,0xFC,0x61,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01, +0xDD,0x57,0xEA,0x37,0xDD,0x45,0x46,0x01,0x00,0x07,0x04,0x50,0x03,0xF0,0x44,0x00, +0xA1,0x1A,0x92,0xB0,0xD8,0x03,0x49,0x00,0x30,0x5A,0x49,0x00,0x3C,0x05,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0xEB,0x02,0xDD,0x45, +0x49,0x00,0x35,0x84,0xC8,0xFE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07, +0x96,0x01,0xDD,0x57,0x58,0x00,0x00,0x03,0xDD,0x45,0x49,0x00,0x3C,0x2F,0x49,0xFF, +0xF3,0x6E,0xC0,0x02,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xA1,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0xEB,0x04,0xDD,0x45, +0xFA,0x4F,0x44,0x00,0x00,0xE7,0x84,0x22,0x44,0x30,0x00,0xF8,0xDD,0x4E,0x49,0xFF, +0xF1,0xBE,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57, +0x58,0x00,0x00,0x05,0xDD,0x45,0x84,0x01,0x44,0x10,0x01,0xE0,0x84,0x45,0x44,0x30, +0x02,0x58,0x49,0x00,0x34,0xFB,0x80,0xC0,0xC8,0xF7,0x84,0x45,0x84,0x01,0x44,0x10, +0x00,0x80,0x49,0x00,0x35,0x30,0x46,0x01,0x00,0x07,0xEA,0xB8,0x96,0x49,0xEA,0x6E, +0x58,0x10,0x80,0x06,0xEA,0x7E,0x49,0xFF,0xF4,0xFE,0x49,0xFF,0xF5,0x48,0x4E,0x00, +0x33,0xE5,0x80,0x06,0xEA,0x5C,0xEA,0xBA,0x84,0x21,0xEB,0x82,0x12,0x60,0x00,0x00, +0x80,0x41,0x44,0x00,0x00,0xE7,0xEA,0x3B,0x96,0x01,0x46,0x11,0x00,0x07,0x12,0x00, +0x87,0xAF,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57, +0x58,0x00,0x00,0x07,0xDD,0x45,0xFA,0x0A,0xDD,0x40,0xC8,0x19,0xFA,0x0E,0xDD,0x40, +0xC8,0x16,0xFA,0x13,0xDD,0x40,0xC8,0x13,0xFA,0x18,0xDD,0x40,0xC8,0x10,0x46,0x01, +0x00,0x07,0xEA,0x62,0x4E,0x00,0x33,0x7B,0xD8,0x08,0xEA,0x21,0xEA,0x20,0x83,0xFF, +0x46,0x11,0x00,0x07,0xEA,0x6F,0xD5,0x03,0x49,0xFF,0xF3,0x24,0x49,0x00,0x3C,0x1D, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00, +0x00,0x08,0xDD,0x45,0x84,0x00,0xDD,0x58,0x84,0xC0,0x3C,0x6F,0xFF,0x6A,0x46,0x01, +0x00,0x07,0xEA,0xB8,0x84,0x41,0x96,0x49,0xEA,0x6E,0x10,0x2F,0x80,0x00,0x10,0x2F, +0x80,0x01,0x10,0x2F,0x80,0x02,0x10,0x2F,0x80,0x03,0x10,0x2F,0x80,0x04,0x58,0x10, +0x80,0x09,0xEA,0x7E,0x3A,0x0F,0x84,0x00,0x49,0x00,0x2F,0xB2,0x80,0x06,0x84,0x26, +0x49,0x00,0x3A,0xD9,0x46,0x00,0x0E,0xD0,0x46,0x10,0x20,0x0C,0x50,0x00,0x00,0x40, +0x8C,0x26,0x49,0x00,0x3A,0xCB,0x46,0x09,0x00,0x20,0xB4,0x20,0x66,0x10,0x80,0x40, +0xB6,0x20,0xEA,0xCB,0xEA,0x8E,0xC1,0x05,0xA0,0x41,0x58,0x10,0x80,0x08,0xA8,0x41, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00, +0x00,0x0A,0xDD,0x45,0x84,0x41,0x44,0x00,0x00,0xBC,0x84,0x20,0x84,0x66,0x46,0x78, +0x00,0x20,0x46,0x9A,0x33,0xAA,0xDD,0x4E,0x84,0xC0,0x50,0xA3,0x84,0xF4,0x50,0x94, +0x83,0x3A,0x46,0xB9,0x00,0x90,0x84,0x07,0x49,0x00,0x2D,0xCA,0x8C,0x05,0x46,0x11, +0x00,0x07,0x14,0x00,0x83,0xF9,0xEA,0x42,0x4E,0x02,0x00,0xC7,0xEA,0xB5,0x46,0x01, +0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00,0x00,0x0B, +0xDD,0x45,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x84,0x00,0xDD,0x58,0xD5,0x0C,0xFA,0x02, +0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,0xC8,0xF5, +0x49,0xFF,0xED,0xC9,0x49,0x00,0x02,0xD2,0xC8,0x1E,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x01,0xDD,0x57,0x58,0x00,0x00,0x0C,0xDD,0x45,0x84,0x0E, +0xDD,0x40,0xC0,0x04,0x49,0xFF,0xF4,0xE2,0xF8,0x0C,0xFA,0x02,0xDD,0x40,0xC8,0xFB, +0xFA,0x06,0xDD,0x40,0xC8,0xF8,0xDD,0x47,0xDD,0x40,0xC8,0xF5,0x49,0x00,0x02,0x0A, +0x48,0x00,0x00,0x83,0x84,0x00,0x3E,0x07,0xFC,0xB8,0x3E,0x07,0xFC,0xBF,0x46,0x01, +0x00,0x07,0xEA,0xB8,0x96,0x49,0xEA,0x6E,0x58,0x10,0x80,0x0D,0xEA,0x7E,0x84,0x0E, +0xDD,0x40,0xC8,0x28,0xFA,0x02,0xDD,0x40,0xC8,0x25,0xFA,0x06,0xDD,0x40,0xC8,0x22, +0xDD,0x47,0xDD,0x40,0xC8,0x1F,0xDD,0x4D,0x5A,0x00,0x08,0x15,0x5A,0x00,0x06,0x13, +0xDD,0x54,0x5A,0x08,0x01,0x06,0xF8,0x4C,0xC8,0x03,0x49,0x00,0x29,0xC2,0xEB,0x40, +0xC8,0x0D,0x49,0x00,0x11,0xE6,0x49,0x00,0x2A,0xF3,0x49,0x00,0x28,0x25,0x80,0xC0, +0xD5,0x05,0x49,0x00,0x25,0xBB,0x49,0x00,0x25,0x97,0xEB,0x40,0xC8,0x03,0x49,0x00, +0x02,0x49,0x49,0xFF,0xFB,0x65,0x49,0xFF,0xED,0xA9,0x84,0x01,0x3E,0x07,0xFC,0xB8, +0x80,0x06,0x49,0xFF,0xFC,0xD2,0xEA,0xF0,0x49,0x00,0x29,0x49,0xEA,0x69,0xC8,0x02, +0xEA,0xC2,0x49,0x00,0x01,0xA0,0x84,0x0E,0xDD,0x40,0xC8,0x36,0xFA,0x02,0xDD,0x40, +0xC8,0x33,0xFA,0x06,0xDD,0x40,0xC8,0x30,0x84,0x0A,0xDD,0x40,0xC8,0x2D,0xFA,0x0A, +0xDD,0x40,0xC8,0x2A,0xFA,0x13,0xDD,0x40,0xC8,0x27,0xFA,0x0E,0xDD,0x40,0xC8,0x24, +0xFA,0x18,0xDD,0x40,0xC8,0x21,0xFA,0x1C,0xDD,0x40,0xC8,0x1E,0xDD,0x47,0xDD,0x40, +0xC8,0x1B,0x3C,0x0D,0xFF,0x76,0x5A,0x08,0x01,0x18,0xEB,0x40,0xC8,0x13,0xEB,0x13, +0x5A,0x08,0x01,0x09,0x00,0x05,0x00,0x00,0x96,0x04,0xC8,0x04,0x49,0x00,0x25,0x00, +0xD5,0x07,0x00,0x05,0x00,0x00,0x96,0x0E,0xC8,0x03,0x49,0x00,0x24,0xB0,0x49,0x00, +0x25,0xBD,0x49,0x00,0x2A,0x5B,0x46,0x01,0x00,0x07,0xEA,0xB8,0x96,0x49,0xEA,0x6E, +0x58,0x10,0x80,0x0E,0xEA,0x7E,0xDD,0x4D,0x5A,0x08,0x07,0x07,0x00,0x53,0x83,0x40, +0xEA,0x64,0xD8,0x19,0xD5,0x0C,0x5A,0x08,0x08,0x17,0x00,0x53,0x83,0x40,0xEA,0x9D, +0xD8,0x12,0x00,0x05,0x80,0x00,0xC8,0xFE,0x49,0x00,0x34,0x0A,0x49,0x00,0x34,0xC5, +0x46,0x01,0x00,0x07,0xEA,0x62,0x4C,0x54,0xC0,0x07,0x84,0x21,0xDD,0x4D,0xEA,0x3D, +0x84,0x00,0xEB,0x0A,0x84,0x0E,0xDD,0x40,0xC8,0x13,0xFA,0x02,0xDD,0x40,0xC8,0x10, +0xFA,0x06,0xDD,0x40,0xC8,0x0D,0x84,0x0A,0xDD,0x40,0xC8,0x0A,0xFA,0x0A,0xDD,0x40, +0xC8,0x07,0xFA,0x13,0xDD,0x40,0xC8,0x04,0xDD,0x47,0xDD,0x40,0xC0,0x05,0x84,0x01, +0xF8,0x05,0xC8,0xFE,0xF8,0x06,0x2E,0x07,0xFC,0xC5,0x49,0x00,0x2F,0x0F,0xC8,0xFC, +0x48,0xFF,0xFE,0xF3,0xFC,0x00,0x46,0x61,0x00,0x03,0x58,0x63,0x0A,0x98,0x80,0x06, +0x84,0x20,0xDD,0x4F,0xDD,0x42,0x50,0x03,0x05,0x10,0x84,0x20,0xDD,0x4F,0xDD,0x42, +0x50,0x03,0x10,0x10,0x84,0x20,0x44,0x20,0x05,0xF0,0xDD,0x42,0x50,0x03,0x16,0x00, +0x84,0x20,0xDD,0x4F,0xDD,0x42,0x84,0x00,0x3C,0x0F,0xFF,0x7D,0xFC,0x80,0xFC,0x20, +0x3F,0xCF,0xFD,0x90,0xB8,0x00,0x5A,0x00,0x08,0x05,0x84,0xC3,0x5A,0x08,0x06,0x03, +0x84,0xC1,0xB9,0x19,0x2E,0x27,0xFC,0xE7,0x2E,0x07,0xFC,0xF8,0x88,0x02,0xE2,0x20, +0x4E,0xF2,0x00,0x5B,0xB9,0x19,0xC9,0x05,0xEB,0x4F,0xEA,0x61,0xDD,0x4F,0xDD,0x42, +0xB9,0x19,0x2E,0x07,0xFC,0xE7,0x84,0x80,0xE2,0x20,0xE8,0x2D,0x2E,0x37,0xFF,0x61, +0x2E,0x07,0xFF,0x97,0x44,0x10,0x00,0xD8,0x88,0x60,0xFE,0x74,0xBD,0x1A,0x94,0xDA, +0x46,0x21,0x00,0x05,0x58,0x21,0x00,0x98,0x40,0x12,0x84,0x20,0x84,0x80,0x45,0x00, +0x6D,0x60,0x45,0x10,0xDA,0xC0,0xD1,0x17,0x02,0x01,0x6F,0xF0,0xA5,0xE8,0x8A,0x07, +0x96,0x01,0x97,0xC3,0x42,0x73,0x80,0x03,0xE0,0xE3,0xE8,0x04,0xA5,0xD0,0x88,0x07, +0xAC,0x10,0x2A,0x01,0x00,0x01,0x88,0x10,0x96,0x01,0xE3,0xA0,0xE8,0x02,0x84,0x81, +0x8C,0xA2,0xD5,0xEA,0xB8,0x19,0x8C,0x01,0xB8,0x99,0x5A,0x48,0x01,0x1E,0x44,0x20, +0x00,0xD8,0xFE,0xB4,0xBD,0x1A,0x46,0x31,0x00,0x05,0x58,0x31,0x80,0x98,0x40,0x22, +0x88,0x20,0x84,0x80,0xD2,0x0F,0xA5,0xE8,0xB8,0x19,0x22,0x11,0x80,0x00,0x96,0x03, +0x40,0x00,0x80,0x16,0x88,0x07,0x96,0x01,0x1A,0x02,0x80,0x01,0x1A,0x41,0x80,0x01, +0xD5,0xF2,0x84,0x00,0xB8,0x99,0xB9,0x19,0x2E,0x47,0xFC,0xE7,0x2E,0x07,0xFC,0xF8, +0x88,0x04,0xE2,0x20,0xE9,0x3A,0x84,0x40,0xBA,0x99,0xBD,0x1A,0x44,0x00,0x00,0xD8, +0x42,0x13,0x00,0x24,0x46,0x31,0x00,0x05,0x58,0x31,0x80,0x98,0x40,0x12,0x84,0x20, +0xD1,0x0D,0x22,0x01,0x80,0x00,0xA5,0xA8,0x40,0x00,0x10,0x16,0x88,0x06,0x96,0x01, +0x1A,0x02,0x80,0x01,0x1A,0x21,0x80,0x01,0xD5,0xF4,0xB8,0x00,0x5A,0x08,0x02,0x1E, +0x2E,0x07,0xFC,0xDA,0x2E,0x10,0x00,0x28,0xE2,0x20,0xE8,0x05,0x84,0x01,0xB8,0x90, +0x84,0x00,0xD5,0x11,0x2E,0x2F,0xFF,0x5B,0x4E,0x24,0x00,0x10,0x3C,0x33,0xFE,0xBF, +0xBA,0x26,0xE2,0x62,0xE9,0x0A,0x3C,0x33,0xFE,0xC4,0xBA,0x25,0xE2,0x62,0xE9,0x05, +0xC1,0x04,0x8C,0x01,0x3E,0x07,0xFC,0xDA,0xFC,0xA0,0x00,0x00,0xFC,0x20,0x3C,0x1D, +0xFF,0x7E,0xEA,0x40,0x2E,0x37,0xFD,0x1C,0xE2,0x03,0xE8,0x48,0xEA,0xD4,0x5A,0x08, +0x01,0x2C,0x2E,0x57,0xFD,0x00,0x9E,0x19,0xD8,0x27,0x2E,0x77,0xFF,0xC2,0x84,0xA0, +0x47,0x01,0x00,0x02,0x59,0x08,0x01,0x44,0x44,0x60,0x05,0x10,0x50,0x22,0x8F,0x34, +0x99,0x0D,0x88,0x50,0xA4,0x20,0x03,0x11,0x00,0x00,0xE3,0xA0,0xE8,0x04,0xA4,0x20, +0xA4,0x90,0xD5,0x03,0xA4,0x10,0xA4,0xA0,0x8A,0x02,0xE0,0xE0,0xE8,0x05,0x84,0x00, +0x3E,0x07,0xFC,0xE8,0xD5,0x03,0x8C,0xA2,0xDE,0xEA,0xEA,0xD4,0x5A,0x08,0x01,0x05, +0x3E,0x37,0xFC,0xFD,0xD5,0x1D,0xEA,0xD4,0xC8,0x1B,0xDD,0x4D,0x8E,0x02,0xE6,0x07, +0xE8,0x17,0x3E,0xFF,0x79,0x70,0x38,0x07,0x80,0x00,0xEA,0xAF,0x4A,0x00,0x3C,0x00, +0x08,0x1E,0x1E,0x1E,0x0C,0x08,0x0C,0x00,0xEA,0xB1,0xD5,0x02,0xEA,0x5B,0x46,0x21, +0x00,0x03,0x58,0x21,0x00,0x78,0xDD,0x48,0xD5,0x03,0x49,0xFF,0xFF,0x02,0xFC,0xA0, +0x92,0x00,0xFC,0x00,0xEB,0x25,0xC0,0x1C,0x2E,0x07,0xFD,0x05,0x2E,0x17,0xFF,0x96, +0xE2,0x01,0xE9,0x10,0x84,0x00,0x3E,0x07,0xFC,0xF3,0x84,0x20,0x3C,0x1F,0xFF,0x7D, +0x2E,0x07,0xFC,0xFF,0x3E,0x07,0xFC,0xE7,0xEB,0x4F,0xEA,0x61,0xDD,0x4F,0xDD,0x42, +0xD5,0x07,0x3C,0x1D,0xFF,0x75,0xC9,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x05,0xFC,0x80, +0xFC,0x00,0x3F,0xCF,0xFD,0x90,0x2E,0x17,0xFD,0x00,0x2E,0x07,0xFC,0xFD,0xE2,0x20, +0xE9,0x05,0x84,0x01,0xEA,0xBB,0x84,0x0A,0xD5,0x03,0x84,0x00,0xEA,0xBB,0x3E,0x07, +0xFC,0xF8,0x2E,0x07,0xFC,0xEC,0xC0,0x2A,0x84,0x01,0xEB,0x16,0x84,0x01,0x3E,0x07, +0xFC,0xE8,0x84,0x02,0xEA,0xF9,0xBE,0x00,0x5A,0x68,0x02,0x18,0x2E,0x07,0xFD,0x17, +0x5A,0x08,0x01,0x14,0xEA,0x29,0xE6,0x01,0x3E,0xF7,0xFD,0x31,0x80,0x06,0x80,0x26, +0xEA,0x3D,0x3E,0x67,0xFD,0x17,0xEA,0x29,0xC0,0x04,0xEB,0x65,0xDD,0x5C,0xD5,0x03, +0xEB,0x65,0xEA,0xB4,0xB8,0x9A,0xD5,0x2B,0x84,0x00,0x3E,0x07,0xFD,0x11,0x2E,0x07, +0xFC,0xFB,0x8C,0x01,0x3E,0x07,0xFC,0xFB,0xD5,0x08,0x49,0xFF,0xFF,0x51,0x2E,0x07, +0xFD,0x11,0x8C,0x01,0x3E,0x07,0xFD,0x11,0xEB,0x82,0x02,0x50,0x03,0x01,0xEB,0x03, +0xD0,0x09,0x2E,0x0F,0xFF,0x5A,0x4E,0x04,0x00,0x06,0xB8,0x00,0x8E,0x07,0xE6,0x02, +0xE8,0x06,0xEA,0x40,0x8C,0x01,0x96,0x00,0xEA,0xC7,0xD5,0x09,0xEB,0x82,0x00,0x00, +0x06,0x01,0xEB,0x5B,0x8C,0x01,0x96,0x00,0x10,0x00,0x86,0x01,0xFC,0x80,0xFC,0x20, +0x3C,0x7D,0xFF,0x7E,0x84,0xA0,0xEB,0x1C,0xEB,0x27,0x84,0x63,0xDD,0x4F,0x98,0x7D, +0x50,0x02,0x8F,0x34,0xA5,0x08,0x88,0x06,0xA4,0x00,0x42,0x02,0x0C,0x73,0x8C,0xA2, +0x90,0x02,0x96,0x01,0xAC,0x08,0xDA,0xF4,0x84,0x03,0x3C,0x0F,0xFF,0x74,0xFC,0xA0, +0xFC,0x00,0x3F,0xCF,0xFD,0x90,0xB8,0x00,0x5A,0x00,0x08,0x04,0x5A,0x08,0x06,0x05, +0xEB,0x4F,0xEA,0xA8,0xD5,0x04,0xB8,0x11,0xC8,0x04,0xEA,0x97,0xE6,0x01,0xD5,0x02, +0x85,0xE0,0x3E,0xF7,0xFD,0x08,0xEA,0x56,0xEA,0xA5,0xC0,0x0F,0x2E,0x07,0xFD,0x08, +0xC0,0x0C,0xB8,0x10,0x5A,0x00,0x02,0x0A,0x49,0xFF,0xFE,0x4B,0x84,0x00,0x3E,0x07, +0xFC,0xE5,0x84,0x00,0xEA,0x51,0xD5,0x10,0x84,0xC0,0xBE,0x99,0x80,0x26,0xEB,0x4F, +0xEA,0x61,0xDD,0x4F,0xDD,0x42,0xB8,0x10,0x5A,0x08,0x02,0x05,0x49,0xFF,0xFF,0xB9, +0xD5,0x03,0x3E,0x67,0xFC,0xDA,0xFC,0x80,0x2E,0x07,0xFC,0xEC,0xDD,0x9E,0xFC,0x60, +0x3D,0x3C,0x00,0x37,0x2E,0x90,0x00,0x42,0x2E,0x47,0xFF,0x5D,0x92,0x84,0x3C,0x2C, +0x00,0x36,0x4E,0x42,0x00,0xF1,0x3F,0x18,0x02,0x14,0x38,0x38,0x80,0x00,0x5A,0x38, +0x01,0x13,0xEA,0xC4,0xFF,0x04,0x44,0x30,0xFF,0xFF,0x99,0xCC,0xA1,0xBE,0x4C,0x61, +0xC0,0x0B,0xA1,0x7B,0xDE,0x08,0x38,0x30,0x90,0x02,0x4C,0x32,0xC0,0x05,0x84,0x60, +0x38,0x38,0x80,0x08,0xEA,0xC4,0x42,0x30,0x10,0x24,0xEA,0x8C,0x99,0xCB,0xB4,0xA7, +0x8E,0x41,0x8F,0xE1,0xDC,0x54,0x50,0x41,0x80,0x0C,0x88,0x81,0xB5,0x84,0x4D,0x02, +0x80,0x4F,0x51,0x21,0x80,0x18,0x89,0xC1,0xB4,0xD2,0x4C,0x62,0x80,0x49,0xA0,0xE1, +0x40,0x18,0x04,0x08,0xE0,0x26,0x04,0x09,0x00,0x01,0x95,0xD9,0xE9,0x0B,0xE0,0xE0, +0xE8,0x19,0x40,0x18,0x18,0x01,0xFE,0x5C,0x9A,0x83,0x40,0x10,0x88,0x36,0x88,0x30, +0xD5,0x02,0x84,0x20,0xE0,0xE0,0xB6,0x24,0xE8,0x04,0x84,0x00,0xA8,0x21,0xF8,0x2D, +0x9A,0x18,0x42,0x18,0x00,0x24,0x40,0x53,0x40,0x01,0x40,0x00,0x94,0x16,0x99,0x58, +0xD5,0x23,0x99,0x72,0xE0,0xA1,0x41,0x10,0x4C,0x00,0xE9,0x0F,0xE1,0xA7,0x4E,0xF2, +0x00,0x9B,0x40,0x58,0x18,0x01,0x40,0x11,0xCC,0x01,0xFE,0x6C,0x9B,0x43,0x40,0x10, +0x94,0x36,0x88,0x30,0xB6,0x24,0xD5,0x02,0xB6,0x44,0xE1,0xA7,0xE8,0x04,0x15,0x32, +0x00,0x01,0xF8,0x0B,0x40,0x58,0x08,0x01,0x9A,0x18,0xFE,0x2C,0x40,0x53,0x40,0x01, +0x40,0x50,0x14,0xB6,0x88,0xA3,0xA9,0x61,0x48,0x00,0x00,0x7E,0x46,0x41,0x00,0x01, +0x58,0x42,0x0D,0x80,0x40,0x42,0x00,0x20,0xA7,0x21,0x5A,0x40,0xFE,0x0D,0x2E,0x47, +0xFD,0x1F,0xCC,0x71,0xEA,0x8C,0xD4,0x6F,0xA1,0xBB,0x4C,0x62,0x00,0x6D,0xA1,0xBE, +0x4C,0x62,0x40,0x6A,0x8C,0x6C,0x38,0xB8,0x80,0x00,0x88,0x61,0xB5,0x83,0x05,0x21, +0x80,0x01,0xA0,0x79,0x4E,0xB3,0x00,0x60,0x40,0x68,0x04,0x08,0x40,0x33,0x24,0x01, +0xE0,0x65,0x40,0x39,0x04,0x08,0xE9,0x10,0x40,0x41,0xA4,0x01,0xE0,0x81,0xE8,0x1B, +0x40,0x28,0x14,0x01,0x42,0x29,0x08,0x24,0x40,0x40,0xC8,0x01,0x40,0x21,0x10,0x56, +0x88,0x50,0xA8,0xBE,0xD5,0x03,0x14,0xB3,0x80,0x06,0x8A,0x69,0xE0,0x61,0xE9,0x3C, +0x40,0x39,0x04,0x01,0x42,0x38,0x0C,0x24,0x8A,0xB0,0x40,0x21,0x94,0x56,0x40,0x59, +0x08,0x00,0xD5,0x30,0x99,0x2A,0x8A,0x89,0xE0,0x86,0x40,0xA0,0xCC,0x00,0xE9,0x06, +0x40,0x45,0x24,0x01,0xE0,0x83,0xE9,0x04,0xD5,0x2E,0xA8,0xBE,0xD5,0x11,0x40,0x68, +0x14,0x01,0x40,0x49,0x4C,0x01,0xFF,0x34,0x40,0x60,0xC8,0x01,0x40,0x42,0x18,0x96, +0x88,0x90,0x4E,0x45,0x00,0x04,0xA9,0x3E,0xD5,0x03,0x14,0xB3,0x80,0x06,0x40,0x95, +0x24,0x01,0xE1,0x23,0xE8,0x04,0x15,0x33,0x80,0x07,0xD5,0x12,0x40,0x38,0x08,0x01, +0x40,0x29,0x04,0x01,0xFE,0x9C,0x8A,0xB0,0x40,0x51,0x14,0xB6,0x88,0xB2,0x4E,0x55, +0x00,0x04,0xA9,0x7F,0xD5,0x05,0x50,0x13,0x80,0x18,0x84,0x40,0xA8,0x89,0x84,0x21, +0x38,0x18,0x80,0x08,0xFC,0xE0,0x3E,0x18,0x02,0x14,0x38,0x00,0x80,0x00,0xDD,0x9E, +0xFC,0x20,0x3F,0xCF,0xFD,0xB8,0x3E,0x68,0x00,0xF8,0x84,0x1F,0x84,0xE0,0x12,0x03, +0x00,0x44,0x12,0x03,0x00,0x45,0x84,0x20,0x50,0x03,0x00,0x60,0x84,0x4C,0x12,0x73, +0x00,0x42,0x12,0x73,0x00,0x43,0xDD,0x42,0x80,0x06,0x44,0x10,0xFF,0xFF,0x44,0x20, +0x00,0x60,0xDD,0x42,0x50,0x03,0x00,0x78,0x84,0x20,0x84,0x4C,0xDD,0x42,0x46,0x11, +0x41,0x41,0x50,0x03,0x00,0x6C,0x50,0x10,0x84,0x14,0x84,0x4C,0xDD,0x42,0x46,0x01, +0x00,0x07,0x58,0x00,0x02,0x66,0xA6,0x40,0xA6,0x81,0xEA,0x33,0xB9,0x81,0xA6,0x42, +0xA6,0x83,0xEA,0x33,0xB9,0x8E,0xA6,0x45,0xA6,0x86,0xEA,0x33,0xB9,0x80,0xA6,0x47, +0xEB,0x0F,0xEA,0x33,0xB9,0x94,0x00,0x10,0x00,0x0A,0x00,0x20,0x00,0x0B,0xEA,0x33, +0xB9,0x96,0x00,0x10,0x00,0x0C,0x00,0x20,0x00,0x0D,0xEA,0x33,0xB9,0x97,0x00,0x10, +0x00,0x0F,0x00,0x20,0x00,0x10,0xEA,0x33,0xB9,0x8C,0x00,0x10,0x00,0x11,0x00,0x00, +0x00,0x12,0x40,0x00,0x05,0x04,0xB8,0x85,0x3C,0x7B,0xFE,0xB6,0x84,0x20,0x3E,0x08, +0x02,0x5C,0xFA,0x48,0xDD,0x42,0xFC,0xA0,0xFC,0x20,0x46,0x71,0x00,0x07,0x58,0x73, +0x83,0x48,0x82,0x00,0x46,0x51,0x00,0x01,0x58,0x52,0x8F,0xF4,0x84,0x00,0x47,0x11, +0x00,0x01,0x59,0x18,0x8D,0x68,0x00,0x68,0x00,0x00,0x38,0x43,0x98,0x00,0x5A,0x40, +0xFF,0x18,0x41,0x23,0x98,0x00,0x41,0x32,0x10,0x09,0x01,0x29,0x00,0x01,0x4C,0x29, +0xC0,0x0C,0x97,0x1F,0xE2,0x64,0xE9,0x08,0x38,0x48,0x84,0x00,0x38,0x42,0x92,0x02, +0xE2,0x92,0xE9,0x02,0x84,0x01,0x8C,0xC2,0x10,0x68,0x00,0x00,0xD5,0xE5,0xFC,0xA0, +0x46,0x31,0x00,0x07,0x58,0x31,0x83,0x48,0xA6,0x80,0x38,0x41,0x88,0x00,0x8C,0x41, +0x5A,0x48,0xFF,0x04,0xAE,0x80,0xDD,0x9E,0xC9,0xFE,0xAE,0x80,0xD5,0xF6,0x3C,0x3D, +0xFF,0x75,0x84,0x28,0x3E,0x08,0x01,0xB4,0xEA,0x8C,0xEB,0x0F,0xC2,0x08,0xCB,0x04, +0x10,0x30,0x00,0x08,0xD5,0x04,0x8E,0x41,0x10,0x20,0x00,0x08,0xEB,0x0F,0xCA,0x03, +0xB6,0x80,0xA9,0x01,0x8E,0x21,0x96,0x48,0x8C,0x0C,0xC9,0xF0,0xDD,0x9E,0xFC,0x01, +0x84,0x6C,0xEA,0x38,0x80,0x5F,0x84,0x00,0x3E,0x48,0x01,0xB4,0x80,0x24,0x42,0x10, +0x0C,0x73,0x00,0x50,0x80,0x08,0xCD,0x0A,0x46,0x01,0x00,0x07,0x3B,0x01,0x44,0x00, +0x00,0x00,0x02,0x7A,0xEA,0xEC,0xEA,0xFD,0xD5,0x04,0x8C,0x01,0x5A,0x08,0x08,0xF0, +0xFC,0x81,0xFC,0x21,0xEA,0x38,0x80,0x80,0x46,0x01,0x00,0x07,0x00,0x60,0x02,0x7D, +0x46,0x01,0x00,0x07,0x00,0x70,0x02,0x7E,0x46,0x01,0x00,0x07,0x80,0xA1,0x01,0x00, +0x02,0x7A,0x3E,0x18,0x01,0xB4,0x84,0x68,0x84,0x00,0x00,0x20,0x80,0x08,0xC2,0x14, +0xB4,0x41,0xE2,0x82,0xE8,0x03,0x8A,0x44,0xD5,0x02,0x9A,0xA2,0xE2,0x46,0xE8,0x0C, +0xA0,0x89,0xE2,0xA2,0xE8,0x03,0x8A,0x45,0xD5,0x02,0x9A,0xAA,0xE2,0x47,0xE8,0x04, +0x11,0x00,0x80,0x08,0x84,0x01,0x8E,0x61,0x96,0xD8,0x8C,0x2C,0xCB,0xE7,0xFC,0xA1, +0xFC,0x01,0xEA,0x38,0x80,0xC0,0x80,0x01,0x2E,0x17,0xFD,0x25,0xC1,0x04,0x84,0x21, +0x84,0xA2,0xD5,0x03,0x84,0x22,0x84,0xA1,0x3E,0x48,0x00,0xF8,0x38,0x32,0x0B,0x02, +0xE2,0x66,0xE8,0x03,0x9A,0xF3,0xD5,0x02,0x8A,0x66,0x46,0x61,0x00,0x07,0x00,0x63, +0x02,0x7F,0xFF,0x74,0xE2,0xA3,0xE9,0x0D,0x40,0x32,0x08,0x60,0xA0,0x99,0xE2,0x40, +0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40,0xFE,0x74,0x40,0x00,0x88,0x06,0xD5,0x02, +0x84,0x01,0xFC,0x81,0xFC,0x20,0x84,0x00,0x3C,0x0B,0xFE,0xB0,0x3C,0x0B,0xFE,0xBC, +0x3C,0x0B,0xFE,0xBA,0x46,0x11,0x00,0x07,0x04,0x70,0x83,0xCF,0x46,0x11,0x00,0x07, +0x00,0x60,0x82,0x6A,0x46,0x11,0x00,0x07,0x00,0x50,0x82,0x6F,0x46,0x11,0x00,0x07, +0x00,0x40,0x82,0x74,0x46,0x11,0x00,0x07,0x00,0x30,0x82,0x79,0x46,0x11,0x00,0x07, +0x00,0x20,0x82,0x88,0x46,0x1A,0x11,0xAA,0x50,0x10,0x81,0x1A,0x4C,0x70,0x80,0x0C, +0x46,0x11,0x00,0x07,0x04,0x70,0x83,0xCF,0x46,0x1A,0x33,0xAA,0x50,0x10,0x83,0x3A, +0x4C,0x70,0xC0,0x26,0x84,0x00,0x3E,0x07,0xFD,0x25,0x44,0x00,0x00,0x96,0x3C,0x0B, +0xFE,0xB9,0x44,0x00,0x00,0x32,0x3C,0x0B,0xFE,0xBB,0x3C,0x6B,0xFE,0xB4,0x3C,0x5B, +0xFE,0xB8,0x3C,0x4B,0xFE,0xAF,0x3C,0x3B,0xFE,0xB7,0x46,0x01,0x00,0x07,0x00,0x00, +0x02,0x82,0x3C,0x0B,0xFE,0xB1,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x83,0x94,0x01, +0x3C,0x0B,0xFE,0xB3,0x3C,0x2B,0xFE,0xB5,0x84,0x00,0xD5,0x21,0x84,0x21,0x3E,0x17, +0xFD,0x25,0x44,0x10,0x00,0x32,0x3C,0x1B,0xFE,0xB9,0x3C,0x1B,0xFE,0xBB,0x3C,0x6B, +0xFE,0xB4,0x3C,0x5B,0xFE,0xB8,0x3C,0x4B,0xFE,0xAF,0x3C,0x3B,0xFE,0xB7,0x46,0x11, +0x00,0x07,0x00,0x10,0x82,0x84,0x3C,0x1B,0xFE,0xB1,0x46,0x11,0x00,0x07,0x00,0x10, +0x82,0x85,0x94,0x49,0x3C,0x1B,0xFE,0xB3,0x3C,0x2B,0xFE,0xB5,0x3C,0x0B,0xFE,0xB2, +0xFC,0xA0,0xFC,0x01,0x3F,0xC8,0x00,0xD8,0x46,0x21,0x00,0x07,0x04,0x51,0x03,0xCF, +0x46,0x3A,0x11,0xAA,0xEA,0x38,0x50,0x31,0x81,0x1A,0x80,0x20,0x3C,0x23,0xFE,0xB3, +0xF0,0x01,0xDB,0x03,0xE2,0x02,0xD5,0x0D,0x46,0x31,0x00,0x07,0x04,0x51,0x83,0xCF, +0x46,0x3A,0x33,0xAA,0x50,0x31,0x83,0x3A,0xDB,0x0A,0xBB,0x01,0x9A,0x9A,0xE2,0x40, +0xE8,0x15,0x3C,0x03,0xFE,0xB1,0xE2,0x20,0xE8,0x0A,0xD5,0x0E,0xE2,0x02,0xE9,0x05, +0xBB,0x01,0x9A,0x9A,0xE2,0x40,0xE8,0x0A,0x3C,0x03,0xFE,0xB1,0xBA,0x00,0x9A,0x10, +0x40,0x00,0x04,0x06,0xD5,0x04,0x84,0x01,0xD5,0x02,0x84,0x00,0xFC,0x81,0xFC,0x21, +0x80,0xE0,0x3A,0x1F,0x88,0x20,0x3A,0x0F,0x84,0x00,0x80,0x47,0x80,0xDF,0x49,0xFF, +0xFF,0xC2,0x5A,0x08,0x01,0x0A,0x3C,0x13,0xFE,0xB6,0x40,0x20,0x1C,0x0C,0xFE,0x57, +0x3C,0x1B,0xFE,0xB6,0xD5,0x02,0x84,0x00,0xB4,0x5F,0x3E,0x18,0x02,0x44,0x38,0x20, +0x9D,0x09,0xA0,0xB1,0x3E,0x18,0x02,0x74,0x38,0x20,0x9D,0x09,0xFC,0xA1,0xEB,0x79, +0xEA,0x72,0x38,0x00,0x80,0x00,0x3E,0x18,0x01,0x84,0x40,0x10,0x80,0x40,0xA6,0x0A, +0xA6,0x4B,0x8A,0x01,0x96,0x01,0xDD,0x9E,0xEB,0x79,0xEA,0x72,0x38,0x20,0x80,0x00, +0x3E,0x18,0x01,0x84,0x40,0x00,0x88,0x40,0xA6,0x01,0x38,0x10,0x8A,0x00,0x8A,0x01, +0x96,0x01,0xDD,0x9E,0xEB,0x79,0xEA,0x72,0x38,0x30,0x80,0x00,0x46,0x01,0x00,0x01, +0x58,0x00,0x0F,0xDC,0x40,0x10,0x0C,0x20,0xA6,0x49,0x80,0x80,0xE6,0x22,0xE8,0x18, +0x38,0x00,0x0D,0x00,0xE6,0x02,0xE8,0x14,0xEB,0x55,0x22,0xF0,0x05,0x4C,0xF8,0x08, +0xEB,0x55,0x22,0xF0,0x05,0x70,0xF8,0x04,0xEB,0x55,0x22,0xF0,0x05,0x4D,0xDD,0x5F, +0x4E,0xF3,0x00,0x78,0x83,0xFF,0xEB,0x55,0x22,0xF0,0x05,0x71,0xD5,0x3C,0xEA,0x31, +0x9E,0x82,0xE0,0x22,0x4E,0xF3,0x00,0x6C,0x38,0x52,0x0D,0x00,0xE6,0xA2,0xE8,0x15, +0x46,0x11,0x00,0x02,0xEB,0x19,0x40,0x20,0x80,0x20,0x22,0xF1,0x0C,0xA9,0xDD,0x5F, +0xE9,0x60,0x22,0xF1,0x0C,0xCD,0xDD,0x5F,0xE9,0x5C,0x22,0xF1,0x0C,0xA8,0xDD,0x5F, +0xE9,0x58,0x22,0xF1,0x0C,0xCC,0xD5,0x1F,0xE6,0x22,0xE8,0x1F,0xEA,0x77,0x38,0x12, +0x0D,0x00,0x9F,0x42,0xE0,0x25,0xE9,0x4D,0x9E,0x41,0xEB,0x65,0x58,0x00,0x01,0x44, +0xEB,0x30,0x80,0x60,0x42,0x30,0x88,0x73,0x22,0xF1,0x8C,0xAA,0xDD,0x5F,0xE9,0x41, +0x42,0x02,0x88,0x73,0xF8,0x23,0xE9,0x3D,0x22,0xF1,0x8C,0xAB,0xDD,0x5F,0xE9,0x39, +0x22,0xF0,0x0C,0xAB,0xF8,0x2C,0xDD,0x9E,0xFC,0x00,0x2E,0x10,0x00,0xE1,0x9F,0x8A, +0xE0,0xA6,0xE9,0x2B,0x8E,0x21,0xFA,0x74,0xFE,0x5C,0x8E,0x01,0x46,0x41,0x00,0x02, +0x58,0x42,0x01,0x44,0x99,0x48,0x40,0x52,0x14,0x20,0x22,0xF2,0x8C,0xAA,0xDD,0x5F, +0xE9,0x1C,0xFE,0xF4,0x88,0x03,0x40,0x02,0x00,0x20,0x22,0xF0,0x0C,0xAA,0xDD,0x5F, +0x83,0xFF,0xE9,0x13,0x88,0x22,0x40,0x12,0x04,0x20,0x22,0xF0,0x8C,0xAA,0xDD,0x5F, +0xE9,0x0C,0x88,0x43,0x40,0x22,0x08,0x20,0x22,0xF1,0x0C,0xAA,0x44,0x00,0x00,0x96, +0x40,0x00,0x3C,0x07,0x83,0xFF,0xD5,0x07,0x84,0x00,0xD5,0x05,0xE6,0x22,0xE9,0xAF, +0x84,0x00,0xDD,0x9E,0xFC,0x80,0xFC,0x62,0x3F,0xC8,0x00,0xD8,0xEA,0x38,0x81,0x20, +0x80,0x02,0x80,0xE2,0x81,0x41,0x49,0xFF,0xFF,0x44,0x54,0xB0,0x00,0xFF,0x80,0xC0, +0x80,0x07,0x49,0xFF,0xFF,0x4B,0x54,0xC0,0x00,0xFF,0x80,0x80,0x46,0xE1,0x00,0x01, +0x58,0xE7,0x0D,0x68,0x84,0x00,0x10,0x0F,0x80,0x0F,0xEA,0xC9,0x46,0xD1,0x00,0x01, +0x58,0xD6,0x8F,0xF4,0xEB,0x3C,0x42,0xF6,0x2C,0x24,0xE2,0x0F,0xE8,0x07,0x97,0xB0, +0x97,0x20,0xFF,0x34,0x9B,0xA0,0x97,0xB1,0xD5,0x03,0x44,0x60,0x00,0xFF,0x46,0x01, +0x00,0x07,0x00,0x10,0x02,0x7C,0xE3,0x41,0xE9,0x06,0xB8,0x01,0x85,0x00,0x8A,0x01, +0xE2,0x0A,0xE8,0x09,0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x9B,0x85,0x00, +0x40,0x84,0x00,0x06,0xEA,0x39,0x80,0x28,0xEA,0xC8,0x46,0x01,0x00,0x07,0x00,0x00, +0x02,0x7C,0xE3,0x40,0xE9,0x05,0xB9,0x01,0x8A,0x20,0xE2,0x2A,0xE8,0x19,0xE3,0x20, +0xE9,0x05,0xB9,0x00,0x9A,0x08,0xE2,0x09,0xE8,0x13,0xEA,0xC9,0xEB,0x3C,0xE2,0x06, +0xE8,0x0F,0x9A,0x30,0xE6,0x03,0xE9,0x0C,0x80,0x07,0x49,0xFF,0xFF,0x0D,0xC0,0x08, +0xEA,0x39,0x80,0x27,0x80,0x4B,0x80,0x6C,0xEA,0x9B,0xC0,0x02,0x85,0x01,0xEA,0x39, +0x80,0x28,0xEA,0xC8,0x2E,0x07,0xFD,0x25,0xC8,0x33,0x46,0x01,0x00,0x07,0x00,0x10, +0x02,0x7C,0xE3,0x21,0xE9,0x05,0xB8,0x00,0x8A,0x01,0xE2,0x09,0xE8,0x08,0xEA,0x39, +0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x9B,0xC0,0x02,0x85,0x01,0xEA,0x39,0x80,0x28, +0xEA,0xC8,0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x7C,0xE3,0x40,0xE9,0x05,0xB9,0x01, +0x8A,0x20,0xE2,0x2A,0xE8,0x15,0xE3,0x20,0xE9,0x05,0xB9,0x00,0x9A,0x08,0xE2,0x09, +0xE8,0x0F,0xEA,0xC9,0xEB,0x3C,0xE2,0x06,0xE8,0x0B,0x8A,0xC0,0xE6,0xC4,0xE9,0x08, +0xEA,0x39,0x80,0x27,0x80,0x4C,0x80,0x6B,0xEA,0x9B,0xC0,0x02,0x85,0x01,0x80,0x08, +0xFC,0xE2,0x40,0x00,0x04,0x0E,0x96,0x04,0xDD,0x9E,0x84,0x41,0x40,0x11,0x04,0x0C, +0xA4,0x80,0xFE,0x57,0xAC,0x40,0xDD,0x9E,0x44,0x2E,0xFF,0xFF,0x40,0x11,0x04,0x0C, +0xA4,0x80,0x40,0x11,0x06,0x1E,0xAC,0x40,0xDD,0x9E,0xFC,0x20,0x3E,0x78,0x00,0xF8, +0x80,0xC0,0x84,0x20,0x98,0x38,0x10,0x10,0x00,0x6C,0x50,0x03,0x80,0x84,0x80,0x26, +0xF8,0x7E,0x50,0x03,0x80,0x86,0x80,0x26,0xF8,0x7A,0x50,0x03,0x80,0x8A,0x80,0x26, +0xF8,0x76,0x50,0x03,0x80,0x88,0x80,0x26,0xF8,0x72,0xFC,0xA0,0xFC,0x41,0xEA,0x38, +0x84,0x01,0x3C,0x10,0x00,0xBF,0x40,0x00,0x08,0x0C,0x96,0x03,0x80,0xC2,0xFE,0x47, +0x3C,0x18,0x00,0xBF,0x3C,0x10,0x00,0xBE,0x3E,0x98,0x00,0xF8,0xFE,0x0F,0x3C,0x08, +0x00,0xBE,0x40,0x04,0x98,0x00,0x84,0x3F,0xEA,0x2F,0x50,0x04,0x80,0x8A,0x80,0x26, +0x80,0xE3,0xF8,0x55,0x50,0x04,0x80,0x88,0x80,0x26,0xF8,0x51,0xC7,0x07,0x40,0x64, +0x98,0x60,0x3B,0x0F,0xC4,0x00,0x3B,0x03,0x44,0x20,0xFC,0xC1,0xFC,0x62,0xB6,0x1F, +0x50,0x9F,0x80,0x08,0x3A,0x14,0x88,0x20,0xEB,0x39,0x3C,0x83,0xFE,0xB6,0x46,0x01, +0x00,0x07,0x00,0xA0,0x02,0x7C,0xEB,0x1E,0x84,0xC0,0x40,0xC0,0x28,0x01,0xEA,0xA4, +0x50,0xB1,0x80,0x0C,0x40,0xD0,0x28,0x01,0x80,0xE6,0x4C,0x71,0x00,0x1D,0x80,0x08, +0x80,0x27,0xF2,0x81,0xF8,0x21,0x04,0xE5,0x80,0x00,0x05,0xC5,0x80,0x01,0xF2,0x01, +0xC8,0x0D,0xE3,0x4E,0xE8,0x0B,0x40,0xF7,0x30,0x06,0xE8,0x08,0xE3,0x5C,0xE8,0x06, +0x40,0xFE,0x34,0x06,0xE8,0x03,0x8C,0xC1,0x97,0xB0,0x8C,0xE1,0x97,0xF8,0x50,0xB5, +0x80,0x30,0xD5,0xE4,0xC6,0x07,0x80,0x08,0xB4,0x3F,0xF8,0x06,0x84,0xC0,0x40,0x63, +0x00,0x06,0x80,0x08,0xB4,0x3F,0xDD,0x55,0xC0,0x0B,0x3A,0x04,0x84,0x00,0xB4,0x5F, +0x49,0xFF,0xFD,0x20,0xC0,0x05,0x3E,0x0F,0xFD,0x6C,0xB4,0x3F,0xEA,0x41,0x80,0x06, +0xFC,0xE2,0xFC,0x63,0x3F,0xCF,0xFD,0xB8,0xEA,0xC5,0x42,0x10,0x98,0x0B,0x4E,0x12, +0x02,0x43,0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x87,0x5A,0x18,0xFF,0x07,0x46,0x11, +0x00,0x07,0x00,0x10,0x82,0x81,0xD5,0x02,0x96,0x49,0xF1,0x82,0x81,0x80,0x84,0xC0, +0x49,0xFF,0xFC,0x9F,0x44,0xD0,0xFF,0xFF,0x49,0xFF,0xFD,0x26,0x3E,0x78,0x00,0xF8, +0x50,0xAF,0x80,0x10,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0D,0x08,0xEA,0x23,0xE2,0xC0, +0x4E,0xF2,0x01,0xD1,0x81,0x6C,0xDD,0x47,0x42,0xB3,0x00,0x73,0x8D,0x6C,0xB5,0x2B, +0x4C,0x96,0xC0,0x60,0x54,0x93,0x00,0xFF,0xEB,0x44,0x80,0x29,0xDD,0x55,0xC0,0x1F, +0xEA,0xB6,0x80,0x29,0xDD,0x55,0xC8,0x1B,0x98,0x3E,0x00,0x10,0x00,0x60,0xF2,0x02, +0xE2,0x22,0xE8,0x2A,0xE6,0x24,0xE9,0x28,0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x86, +0x10,0x10,0x00,0x78,0x94,0x33,0x98,0x78,0xEA,0x6A,0x3B,0x05,0xC4,0x20,0xEA,0x2A, +0x14,0x15,0x80,0x02,0x88,0x0E,0x3B,0x05,0xC4,0x00,0xD5,0x11,0x98,0x7E,0x00,0x00, +0x80,0x78,0xC0,0x12,0x8E,0x01,0x10,0x00,0x80,0x78,0x94,0x33,0x98,0x78,0xEA,0x6A, +0xEA,0x2A,0x3B,0x05,0xC4,0x20,0x14,0x15,0x80,0x02,0x88,0x0E,0x3B,0x00,0x44,0x20, +0xB8,0x11,0x8C,0x01,0xB8,0x91,0x98,0x3E,0x00,0x00,0x00,0x78,0xC8,0x06,0xEB,0x45, +0x38,0xD3,0x9B,0x0A,0x14,0xD0,0x00,0x01,0x98,0x3E,0x84,0x20,0xEA,0x2F,0xFA,0x24, +0x10,0x10,0x00,0x6C,0x80,0x29,0x3E,0x08,0x01,0x80,0xEB,0x43,0x80,0x29,0x3E,0x08, +0x01,0x82,0xEB,0x43,0x80,0x29,0x3E,0x08,0x01,0x7C,0xEA,0x41,0x80,0x29,0x3E,0x08, +0x01,0x7E,0xEA,0x41,0x3E,0x0F,0xFD,0x6C,0x80,0x29,0xEA,0x41,0x48,0x00,0x01,0x67, +0x96,0x30,0x3B,0x05,0xC4,0x00,0xF0,0x81,0x3C,0x00,0x00,0xC0,0xF1,0x01,0x3B,0x05, +0x44,0x20,0x81,0x11,0xDD,0x55,0xC0,0x1A,0x14,0x9F,0x80,0x04,0x14,0x8F,0x80,0x05, +0xEA,0x2D,0x49,0xFF,0xFC,0x48,0xC0,0x06,0xEA,0x2D,0xF2,0x01,0x84,0x61,0xEB,0x1F, +0xD5,0x0D,0xEA,0x2D,0xF2,0x01,0x49,0xFF,0xFE,0x18,0xC0,0x08,0xEA,0x2D,0xF2,0x01, +0x84,0x61,0xEB,0x1F,0xEA,0x2D,0x49,0xFF,0xFC,0x1C,0x2E,0x17,0xFD,0x25,0x46,0x01, +0x00,0x07,0x00,0x00,0x02,0x7C,0xC9,0x07,0xE2,0x09,0xE8,0x10,0xEA,0xC0,0x9A,0x08, +0xE3,0x20,0xD5,0x07,0xE2,0x08,0xE8,0x0A,0x3C,0x1C,0x00,0x37,0x9A,0x08,0xE3,0x00, +0xE8,0x05,0x3E,0x08,0x01,0x80,0xF1,0x01,0xEA,0x41,0x14,0x9F,0x80,0x04,0x14,0x8F, +0x80,0x05,0xEA,0x2D,0x49,0xFF,0xFC,0x17,0xEA,0xB6,0xF1,0x01,0xDD,0x55,0xC0,0x09, +0xEA,0x2D,0xF2,0x01,0x49,0xFF,0xFC,0x3E,0xC0,0x04,0xF0,0x01,0x49,0xFF,0xFE,0x97, +0x3C,0x00,0x00,0xC1,0xF1,0x01,0xDD,0x55,0xC0,0x44,0x3A,0x15,0x08,0x00,0xF0,0x01, +0x49,0xFF,0xFD,0x07,0xB9,0x01,0xE2,0x29,0xE8,0x08,0xB9,0x0E,0xE3,0x21,0xE8,0x05, +0x3C,0x13,0xFE,0xB4,0xE3,0x01,0xE9,0x26,0xB9,0x00,0xE2,0x29,0xE8,0x0B,0xB9,0x14, +0xE3,0x21,0xE8,0x08,0x3C,0x23,0xFE,0xB8,0x3C,0x1C,0x00,0x37,0x8A,0x22,0xE2,0x28, +0xE9,0x19,0xB9,0x16,0xE2,0x28,0xE8,0x08,0xB9,0x17,0xE3,0x01,0xE8,0x05,0x3C,0x13, +0xFE,0xAF,0xE3,0x21,0xE9,0x0F,0xB9,0x0C,0xE2,0x28,0xE8,0x0A,0xB9,0x05,0xE3,0x01, +0xE8,0x07,0x3C,0x23,0xFE,0xB7,0xEA,0xC0,0x8A,0x22,0xE2,0x29,0xE9,0x03,0x96,0x04, +0xC0,0x0C,0xEB,0x45,0xB7,0x20,0x14,0x80,0x00,0x01,0xF1,0x01,0x3E,0x08,0x01,0x7C, +0xEB,0x43,0x98,0x3E,0x84,0x20,0xEA,0x2F,0x3E,0x08,0x01,0x82,0xF1,0x01,0xEA,0x41, +0xEB,0x44,0xF1,0x01,0xDD,0x55,0xC0,0x33,0xEA,0xB6,0xF1,0x01,0xDD,0x55,0xC8,0x2F, +0x98,0x7E,0x00,0x00,0x80,0x60,0x5A,0x00,0xFF,0x05,0x8C,0x01,0x10,0x00,0x80,0x60, +0x38,0x03,0x9B,0x02,0xE2,0x09,0xE8,0x04,0x40,0x04,0x80,0x01,0xD5,0x02,0x8A,0x09, +0x46,0x11,0x00,0x07,0x00,0x10,0x82,0x80,0xE2,0x20,0xE9,0x16,0xEB,0x45,0xA0,0x01, +0xE2,0x08,0xE8,0x04,0x40,0x04,0x00,0x01,0xD5,0x02,0x8A,0x08,0xE2,0x20,0xE9,0x0C, +0x46,0x01,0x00,0x07,0x00,0x00,0x02,0x87,0x5A,0x00,0xFF,0x0A,0x98,0x7E,0x00,0x10, +0x80,0x60,0xE2,0x01,0xE8,0x04,0xF0,0x01,0x49,0xFF,0xFE,0x19,0xF0,0x01,0x3A,0x15, +0x08,0x00,0x80,0x6C,0x49,0xFF,0xFE,0x54,0x5A,0x08,0x01,0x06,0xEA,0x2D,0xF2,0x01, +0x84,0x60,0xEB,0x1F,0xEB,0x44,0xF1,0x01,0xDD,0x55,0x80,0x80,0xC0,0x1A,0xF0,0x83, +0xEA,0xB6,0xF1,0x01,0xDD,0x55,0xF4,0x03,0xC8,0x14,0x3C,0x13,0xFE,0xB5,0xE3,0x01, +0xE9,0x0D,0xEA,0xA4,0x8A,0x01,0xE2,0x08,0xE9,0x09,0x3C,0x13,0xFE,0xB2,0xE3,0x21, +0xE9,0x05,0xEB,0x1E,0x8A,0x01,0xE2,0x09,0xE8,0x04,0x98,0x3E,0x84,0x20,0xEA,0x2F, +0x98,0x3E,0x00,0x20,0x00,0x6C,0xE6,0x54,0xE8,0x61,0x8C,0x41,0x96,0x90,0x46,0x11, +0x00,0x07,0x10,0x20,0x00,0x6C,0x00,0x10,0x82,0x87,0x00,0x00,0x00,0x60,0x94,0xF3, +0xE2,0x01,0xE8,0x3D,0x5A,0x10,0xFF,0x3C,0x38,0x53,0x9B,0x01,0x3D,0x1C,0x00,0x36, +0x98,0x3B,0x40,0x28,0x94,0x01,0xA4,0x02,0x3D,0x0C,0x00,0x37,0x96,0x91,0x40,0x18, +0x00,0x01,0xE2,0xA2,0x96,0x49,0xE8,0x08,0xE2,0xA0,0xE8,0x06,0xE2,0xA1,0xE8,0x04, +0x86,0x40,0x39,0x23,0x9B,0x0A,0xE2,0x45,0xE8,0x08,0xE2,0x40,0xE8,0x06,0xE2,0x41, +0xE8,0x04,0x8F,0xA1,0x39,0x13,0x9B,0x0A,0xE2,0x05,0xE8,0x0A,0xE2,0x02,0xE8,0x08, +0xE2,0x01,0xE8,0x06,0x41,0x13,0x8C,0x00,0x86,0x40,0x15,0x28,0x80,0x01,0xE2,0x25, +0xE8,0x09,0xE2,0x22,0xE8,0x07,0xE2,0x20,0xE8,0x05,0x98,0x3B,0x8F,0x81,0x15,0x00, +0x00,0x01,0x88,0x67,0xB5,0x23,0x04,0x81,0x80,0x01,0xD5,0x12,0x38,0x03,0x9B,0x02, +0xFA,0xA4,0x40,0x14,0x80,0x01,0xFE,0x54,0x88,0x67,0x40,0x90,0x95,0x36,0x89,0x20, +0xA0,0x19,0x40,0x14,0x00,0x01,0xFE,0x54,0x40,0x80,0x95,0x16,0x89,0x00,0x98,0x3E, +0x84,0x3F,0xB7,0x2B,0x14,0x85,0x80,0x01,0xEA,0x2F,0xC4,0x08,0x84,0x00,0x14,0xD5, +0x80,0x00,0x14,0xD5,0x80,0x01,0x14,0x05,0x80,0x02,0x8C,0xC1,0x97,0xB1,0x48,0xFF, +0xFE,0x2F,0x84,0x00,0x49,0xFF,0xFC,0x15,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xDF, +0x84,0x00,0x49,0xFF,0xFC,0x1B,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xE0,0x46,0x01, +0x00,0x01,0x00,0x10,0x0D,0x68,0x46,0x01,0x00,0x01,0x58,0x00,0x0F,0xF4,0x38,0x00, +0x06,0x01,0x46,0x11,0x00,0x07,0x12,0x00,0x81,0xE1,0x3C,0x40,0x00,0xBE,0x46,0x11, +0x00,0x07,0x3C,0x30,0x00,0xBF,0x84,0x00,0x12,0x00,0x81,0xE2,0x46,0x11,0x00,0x07, +0x12,0x00,0x81,0xE3,0x84,0xAA,0x84,0x25,0x84,0x01,0x46,0x21,0x00,0x07,0x02,0x21, +0x01,0xE2,0x97,0xA4,0x42,0x20,0x18,0x73,0x46,0x61,0x00,0x07,0x96,0x91,0x12,0x23, +0x01,0xE2,0x46,0x21,0x00,0x07,0x97,0x9C,0x02,0x21,0x01,0xE3,0x42,0x20,0x18,0x73, +0x8E,0x21,0xFE,0x2C,0x96,0x91,0x46,0x61,0x00,0x07,0x96,0x49,0x12,0x23,0x01,0xE3, +0x92,0x81,0x92,0x61,0x96,0x01,0xC9,0xE2,0x2E,0x00,0x01,0x58,0x46,0x11,0x00,0x07, +0x12,0x00,0x81,0xE4,0xFC,0xE3,0x3E,0x18,0x00,0xF8,0x88,0x01,0x00,0x00,0x00,0x78, +0xDD,0x9E,0xFC,0x60,0x47,0x01,0x00,0x07,0x59,0x08,0x02,0x4E,0x47,0x21,0x00,0x07, +0x59,0x29,0x02,0x1E,0x2E,0x90,0x00,0xE3,0x8C,0x04,0x84,0x80,0xEA,0xB3,0x46,0x71, +0x00,0x01,0x58,0x73,0x8E,0x38,0x81,0x50,0x47,0x11,0x00,0x07,0x59,0x18,0x82,0x36, +0x81,0x72,0x47,0x31,0x00,0x07,0x59,0x39,0x82,0x06,0x96,0x60,0xE2,0x29,0xE8,0x4B, +0x04,0x50,0x7F,0xFF,0xD6,0x45,0xB4,0x20,0x4C,0x13,0x00,0x43,0x40,0x23,0x90,0x60, +0x38,0x53,0x93,0x0A,0xA8,0x51,0xEA,0xC5,0xEB,0x38,0xC1,0x1B,0x84,0x41,0x38,0x89, +0x09,0x01,0xE3,0x05,0xE8,0x04,0x8C,0x41,0x96,0x90,0xD5,0xFA,0x9E,0x51,0x96,0x48, +0x38,0x39,0x85,0x01,0x38,0xF5,0x85,0x01,0x38,0x19,0x89,0x01,0x8A,0xAF,0x8A,0x23, +0xFE,0x6C,0x40,0x54,0x3C,0x01,0x40,0x50,0x94,0xB7,0x88,0xA3,0x14,0x50,0x7F,0xFF, +0xEA,0xC5,0xEA,0x8E,0xC1,0x1D,0xB4,0x40,0x84,0x61,0x38,0x18,0x0D,0x01,0xE2,0x22, +0xE8,0x04,0x8C,0x61,0x96,0xD8,0xD5,0xFA,0x9F,0x59,0x54,0xC2,0x80,0xFF,0x38,0xF5, +0x31,0x01,0x38,0x58,0xB1,0x01,0x40,0x81,0x3C,0x01,0x38,0x28,0x8D,0x01,0x8A,0x2F, +0x8A,0x45,0x42,0x24,0x08,0x24,0x40,0x11,0x04,0x37,0x88,0x25,0xB6,0x20,0x8C,0x81, +0x8C,0x0C,0xD5,0xB4,0xFC,0xE0,0x3C,0x1D,0xFF,0x70,0x5A,0x18,0x02,0x07,0x2E,0x37, +0xFD,0x0C,0x2E,0x47,0xFD,0x22,0xD5,0x05,0x2E,0x37,0xFD,0x12,0x2E,0x47,0xFC,0xD5, +0x2E,0x27,0xFD,0x03,0xC8,0x12,0x5A,0x28,0x01,0x22,0x2E,0x17,0xFE,0x34,0x8C,0x21, +0x96,0x48,0xE2,0x24,0x3E,0x17,0xFE,0x34,0xE9,0x19,0x3E,0x07,0xFD,0x03,0x3E,0x07, +0xFE,0x34,0x3E,0x07,0xFE,0x33,0xD5,0x12,0x5A,0x08,0x01,0x11,0xCA,0x0F,0x2E,0x17, +0xFE,0x33,0x8C,0x21,0x96,0x48,0xE2,0x23,0x3E,0x17,0xFE,0x33,0xE9,0x07,0x3E,0x07, +0xFD,0x03,0x3E,0x27,0xFE,0x34,0x3E,0x27,0xFE,0x33,0x2E,0x57,0xFD,0x03,0xD8,0x06, +0x84,0x00,0x3E,0x07,0xFE,0x34,0x3E,0x07,0xFE,0x33,0xDD,0x9E,0xFC,0x69,0x3F,0xCF, +0xFD,0xD4,0x2E,0x77,0xFD,0x03,0xB8,0x00,0x8E,0xE1,0xE6,0x02,0x5C,0x73,0x80,0x01, +0x84,0xC0,0xE9,0x04,0x9F,0x81,0xFF,0x84,0x92,0xC1,0x50,0x8F,0x80,0x3C,0x80,0x08, +0x84,0x20,0x84,0x4C,0xDD,0x42,0x46,0xD1,0x00,0x02,0x58,0xD6,0x80,0xB4,0x85,0x60, +0x46,0x51,0x00,0x01,0x58,0x52,0x8F,0xDC,0x46,0xA1,0x00,0x02,0x58,0xA5,0x00,0x24, +0x81,0x2D,0x80,0x6B,0x81,0x85,0x85,0xDF,0x47,0x31,0x00,0x01,0x59,0x39,0x8F,0xF4, +0xB8,0x00,0xE2,0x60,0xE8,0x68,0x38,0x14,0x0C,0x00,0x51,0x01,0x80,0x01,0xC9,0x3C, +0x3D,0x13,0xFE,0xAD,0x41,0x21,0x84,0x08,0x80,0x90,0x41,0x48,0x84,0x08,0x41,0x59, +0x14,0x00,0x4C,0x40,0x00,0x32,0x41,0x72,0x04,0x08,0x40,0x26,0x5C,0x00,0x00,0x1A, +0x80,0x01,0xA6,0x91,0x8A,0x22,0xEB,0x17,0x96,0x48,0xE6,0x2C,0xE8,0x05,0xFE,0x4C, +0x55,0x60,0x80,0xFF,0xD5,0x03,0x45,0x60,0x00,0x79,0x38,0x26,0x48,0x00,0x38,0x16, +0x5C,0x00,0x9A,0x51,0xEB,0x17,0x96,0x48,0xE6,0x2C,0xE8,0x04,0xFE,0x4C,0x96,0x48, +0xD5,0x03,0x44,0x10,0x00,0x79,0x88,0x36,0x96,0x48,0xE3,0xA1,0xE9,0x07,0x38,0xE4, +0x0C,0x08,0x84,0xE1,0x38,0xE4,0x10,0x08,0xD5,0x05,0x40,0xFA,0x04,0x07,0xE8,0x02, +0x8D,0x61,0x8C,0x81,0xD5,0xCF,0x2E,0x07,0xFF,0x87,0x38,0x19,0x8E,0x02,0xE2,0x20, +0xE9,0x10,0x80,0x49,0x80,0x6A,0xA0,0x52,0xA0,0x1A,0x88,0x01,0xA8,0x12,0xB4,0x29, +0xB4,0x0A,0x88,0x01,0xB6,0x09,0xA0,0x51,0xA0,0x19,0x88,0x01,0xA8,0x11,0xD5,0x0F, +0x96,0x18,0x15,0x3F,0x80,0x03,0xF5,0x82,0x15,0x0F,0x80,0x01,0x49,0x00,0x00,0xDE, +0x05,0x0F,0x80,0x01,0xF5,0x02,0x05,0x3F,0x80,0x03,0xC8,0xE4,0x80,0x70,0x8D,0x2C, +0x8D,0x4C,0xD5,0x97,0x4C,0xB3,0x40,0x03,0x84,0xE0,0x80,0x07,0x49,0xFF,0xFF,0x2D, +0xBF,0x00,0xCF,0x05,0x3E,0x77,0xFC,0xED,0x3E,0x77,0xFD,0x02,0x3C,0x9C,0x00,0x36, +0xEA,0x31,0xF0,0x86,0x3C,0xAC,0x00,0x37,0xEA,0x77,0xF0,0x87,0x50,0x04,0xFF,0xFF, +0xF0,0x81,0x50,0x05,0x7F,0xFF,0xF0,0x82,0xEA,0xF8,0x46,0x81,0x00,0x01,0x58,0x84, +0x0D,0x98,0x96,0x44,0xEA,0x8D,0xF0,0x8A,0x2E,0x07,0xFD,0x14,0xF0,0x8B,0x2E,0x60, +0x00,0x43,0xF1,0x88,0x54,0x03,0x00,0xF0,0xF0,0x83,0x40,0x05,0x00,0x01,0xF0,0x8C, +0x95,0xB4,0x2E,0x07,0xFC,0xED,0x97,0xB0,0xF0,0x85,0x40,0x04,0x98,0x01,0xF0,0x8D, +0x2E,0x17,0xFD,0x23,0x2E,0x07,0xFD,0x02,0xF1,0x89,0xF0,0x84,0x85,0x60,0x81,0x88, +0x4C,0xB3,0x80,0x71,0xB4,0x0D,0x04,0xE6,0x80,0x02,0xF2,0x06,0x84,0x60,0x42,0x00, +0x24,0x69,0xEA,0x67,0x80,0x4E,0x84,0x60,0xEA,0x67,0xF2,0x06,0x40,0x24,0x88,0x57, +0x92,0x41,0xC9,0x04,0xC9,0x05,0xE2,0x40,0xE8,0x03,0x8A,0x02,0xD5,0x02,0x84,0x00, +0xB6,0x08,0x04,0x06,0x80,0x01,0xF2,0x07,0x84,0x60,0x42,0x00,0x28,0x69,0xEA,0x67, +0x80,0x4E,0x84,0x60,0xEA,0x67,0xF2,0x07,0x40,0x25,0x08,0x57,0x92,0x41,0xC9,0x04, +0xC9,0x05,0xE2,0x40,0xE8,0x03,0x8A,0x02,0xD5,0x02,0x84,0x00,0x14,0x04,0x00,0x01, +0xB4,0x08,0xE2,0x09,0xE9,0x03,0xF0,0x01,0xB6,0x08,0x04,0x04,0x00,0x01,0xE2,0x0A, +0xE9,0x04,0xF0,0x02,0x14,0x04,0x00,0x01,0xF0,0x08,0xC0,0x05,0xB4,0x08,0xF1,0x01, +0x9A,0x08,0xB6,0x08,0xB4,0x08,0xF1,0x09,0xEB,0x76,0x58,0x21,0x0E,0xA4,0x40,0x10, +0x04,0x37,0x38,0x11,0x2C,0x08,0xF1,0x0A,0xC1,0x06,0x80,0x68,0xA0,0x59,0xF2,0x02, +0x9A,0x51,0xA8,0x59,0x04,0x14,0x00,0x01,0xF2,0x0B,0xEB,0x68,0x58,0x31,0x8E,0x98, +0x40,0x20,0x88,0x57,0x38,0x21,0xAC,0x08,0xF2,0x03,0xE2,0x41,0xE8,0x06,0xF2,0x0C, +0xE2,0x22,0xE8,0x03,0x84,0x21,0xF1,0x85,0xE2,0xC0,0xE8,0x06,0xF1,0x0D,0xE2,0x01, +0xE8,0x03,0x84,0x01,0xF0,0x84,0x8D,0x61,0x8D,0x08,0x50,0xD6,0x80,0x0C,0x48,0xFF, +0xFF,0x91,0x00,0x1F,0x80,0x14,0x3E,0x17,0xFC,0xED,0x00,0x1F,0x80,0x10,0x3E,0x17, +0xFD,0x02,0x46,0x01,0x00,0x01,0x02,0x00,0x06,0xCC,0x46,0x11,0x00,0x07,0x12,0x00, +0x87,0xAD,0x46,0x01,0x00,0x01,0x02,0x00,0x06,0xCE,0x46,0x11,0x00,0x07,0x12,0x00, +0x87,0xAE,0xEA,0x28,0xE6,0xEC,0xE8,0x08,0x40,0x16,0x1C,0x60,0x38,0x06,0x1F,0x0A, +0xA8,0x09,0x8C,0xE1,0xD5,0xF8,0xFC,0xE9,0x46,0x31,0x00,0x01,0x58,0x31,0x8F,0xDC, +0x40,0x41,0x80,0x20,0x2E,0x20,0x00,0xE0,0xA7,0x21,0x8E,0x41,0xE6,0x82,0x96,0x90, +0x2E,0x10,0x00,0xE1,0xE9,0x0C,0xE2,0x44,0xE9,0x0A,0x38,0x01,0x81,0x00,0xE6,0x02, +0xE9,0x06,0x8E,0x21,0x96,0x48,0x40,0x00,0x80,0x06,0xDD,0x9E,0x84,0x01,0xDD,0x9E, +0xFC,0x00,0x3F,0xCF,0xFD,0xC0,0x2E,0x07,0xFD,0x15,0xC0,0x05,0x84,0x00,0xB8,0x85, +0x48,0x00,0x00,0x83,0xBE,0x0F,0xCE,0x34,0xB9,0x05,0x8E,0x21,0xE6,0x23,0xE8,0x30, +0xDD,0x54,0x5A,0x08,0x01,0x0C,0x80,0x06,0x49,0xFF,0xFF,0xD0,0xC0,0x04,0x2E,0x07, +0xFF,0x6F,0xD5,0x06,0x2E,0x07,0xFF,0x6E,0xD5,0x03,0x2E,0x07,0xFF,0x72,0xB9,0x00, +0x5A,0x10,0x03,0x05,0xEA,0x98,0x5A,0x18,0x01,0x06,0x2E,0x17,0xFF,0x70,0x88,0x01, +0x96,0x01,0xDD,0x49,0xEA,0x82,0xC1,0x0B,0x84,0x00,0x49,0xFF,0xFF,0xB7,0x2E,0x10, +0x00,0x0C,0xC0,0x04,0x40,0x00,0x84,0x09,0xD5,0x02,0x96,0x09,0x46,0x11,0x00,0x02, +0x04,0x10,0x80,0x2F,0x92,0x21,0xE2,0x20,0xE8,0x03,0x84,0x00,0xB8,0x85,0xEA,0x97, +0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x2F,0xC8,0x07,0x3C,0x03,0xFE,0xAB,0x40,0x00, +0x80,0x17,0x3E,0x07,0xFC,0xFE,0xB8,0x05,0x92,0x21,0x49,0xFF,0xEA,0x05,0xB8,0x05, +0xE6,0x02,0xE9,0x3A,0xB9,0x0F,0xE2,0x20,0xE8,0x37,0x3C,0x63,0xFE,0xAE,0xEB,0x01, +0xC8,0x04,0x40,0x13,0x04,0x09,0xD5,0x03,0x94,0x71,0x96,0x49,0xEA,0x44,0xC0,0x09, +0x2E,0x07,0xFF,0x6C,0xDD,0x49,0x80,0xC0,0x2E,0x07,0xFF,0x6D,0xDD,0x49,0x80,0x20, +0xEA,0x4E,0xC0,0x0A,0x2E,0x00,0x00,0x19,0xDD,0x49,0x80,0xC0,0x2E,0x00,0x00,0x19, +0xDD,0x49,0x94,0x01,0x96,0x41,0xBA,0x0F,0xBB,0x05,0x84,0x8C,0x46,0x51,0x00,0x02, +0x58,0x52,0x80,0xB4,0xE2,0x43,0xE8,0x10,0x80,0x05,0x42,0x01,0x10,0x73,0xE6,0x42, +0xA0,0x02,0x82,0x01,0x92,0x01,0x41,0x03,0x3C,0x1B,0xE2,0x10,0xE8,0x03,0xBA,0x85, +0xD5,0x03,0x8C,0x41,0xD5,0xF0,0xFC,0x80,0xFC,0x60,0x2E,0x07,0xFD,0x18,0x5A,0x08, +0x01,0x0D,0x2E,0x07,0xFC,0xEF,0xE6,0x15,0xE9,0x05,0x84,0x00,0x3E,0x07,0xFD,0x18, +0xD5,0x04,0x8C,0x01,0x3E,0x07,0xFC,0xEF,0x3C,0x03,0xFE,0xA0,0xE6,0x1F,0x2F,0x30, +0x00,0xE3,0xE8,0x14,0x2E,0x47,0xFD,0x18,0x2E,0x37,0xFC,0xEF,0x84,0x00,0xEB,0x79, +0x58,0x10,0x8C,0xCC,0x46,0x51,0x00,0x01,0x58,0x52,0x8D,0x98,0xEA,0xB3,0x80,0xE0, +0x47,0x01,0x00,0x01,0x59,0x08,0x0D,0x74,0xD5,0x1B,0xEA,0xC3,0xC8,0xEC,0xEB,0x79, +0x58,0x10,0x8C,0x6C,0xEA,0xC6,0xE2,0x13,0xE8,0xE6,0x40,0x30,0x80,0x60,0x38,0x20, +0x83,0x0A,0xA8,0x99,0x8C,0x01,0xD5,0xF8,0x38,0x22,0x83,0x02,0x4C,0x23,0x40,0x13, +0xA6,0x88,0x8E,0x41,0xE6,0x53,0xE9,0x07,0xAF,0xC8,0x8C,0x01,0x8C,0x21,0xE2,0x13, +0xE9,0xF4,0xD5,0x0E,0x38,0x28,0x00,0x00,0x5A,0x28,0x01,0xF8,0x80,0x82,0x84,0x60, +0xD5,0xF4,0xA6,0x88,0x5A,0x20,0xFF,0xF3,0x8C,0x41,0xAE,0x88,0xD5,0xEF,0x3E,0x47, +0xFD,0x18,0x46,0xA1,0x00,0x01,0x58,0xA5,0x0B,0xA0,0x3E,0x37,0xFC,0xEF,0xEB,0x79, +0x58,0x10,0x8B,0xAC,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x98,0x46,0x71,0x00,0x01, +0x58,0x73,0x8D,0x74,0x80,0xCA,0x45,0x20,0xFF,0xFF,0x85,0x20,0x85,0x61,0x40,0x03, +0x28,0x01,0xE2,0x13,0xE8,0x50,0xB4,0x43,0x4C,0x29,0x40,0x08,0xB7,0xC1,0x10,0xB3, +0x80,0x00,0x10,0xB3,0x00,0x00,0xD5,0x26,0xA6,0x38,0x5A,0x08,0x01,0x24,0xB4,0xA1, +0x4C,0x59,0x40,0x06,0x3B,0x01,0xC4,0x00,0xEA,0xEC,0xD5,0x1C,0xE2,0xA2,0xE8,0x03, +0x9A,0x15,0xD5,0x02,0x9A,0x2A,0xA1,0x59,0xA1,0x09,0xE2,0x85,0xE8,0x03,0x9B,0x2C, +0xD5,0x02,0x8A,0x85,0xFE,0x04,0x42,0x02,0x10,0x73,0x81,0xE0,0x2E,0x50,0x00,0xEA, +0x2E,0x40,0x00,0xEB,0xFF,0x2C,0xE2,0x8F,0xE8,0x05,0x10,0x93,0x80,0x00,0x3E,0x97, +0xFD,0x18,0xB4,0xA1,0x4C,0x59,0x00,0x1B,0x4C,0x29,0x00,0x19,0xA6,0x30,0x5A,0x08, +0x01,0x16,0xE2,0xA2,0xE8,0x03,0x9B,0x55,0xD5,0x02,0x8A,0xA2,0xA0,0x99,0xA0,0x09, +0xE2,0x02,0xE8,0x03,0x9A,0x10,0xD5,0x02,0x8A,0x02,0xFF,0x6C,0x42,0x50,0x00,0x73, +0x5C,0xF2,0xB8,0x41,0xE9,0x03,0x10,0x93,0x00,0x00,0x8C,0xC1,0x8C,0x28,0x8C,0x68, +0x8C,0xE1,0xD5,0xAE,0xFC,0xE0,0xFC,0x61,0x3F,0xCF,0xFD,0xFC,0x46,0x71,0x00,0x01, +0x58,0x73,0x8D,0x98,0x46,0xB1,0x00,0x01,0x58,0xB5,0x8B,0x88,0x46,0x91,0x00,0x01, +0x58,0x94,0x8B,0x94,0x84,0xC0,0x81,0x47,0x44,0x80,0xFF,0xFF,0x46,0xC1,0x00,0x01, +0x58,0xC6,0x0D,0x80,0x44,0xDF,0xFF,0x80,0x46,0xE1,0x00,0x01,0x58,0xE7,0x0D,0x08, +0x46,0x31,0x00,0x01,0x58,0x31,0x8C,0x6C,0x44,0x10,0xFF,0xFE,0xEA,0x23,0xE2,0xC0, +0xE8,0x52,0x96,0x30,0xF1,0x81,0xB6,0x7F,0x49,0xFF,0xF6,0x2F,0xB4,0x7F,0xF1,0x01, +0x5A,0x08,0x01,0x05,0x2E,0x07,0xFD,0x1F,0xEA,0x94,0xB4,0xA7,0x4C,0x54,0x40,0x1C, +0x00,0x04,0x80,0x00,0x2E,0x27,0xFD,0x1F,0xE2,0x02,0xE8,0x06,0x8C,0x01,0xEA,0x94, +0xB6,0x27,0xA8,0x79,0xD5,0x33,0x84,0x00,0x38,0x57,0x1B,0x02,0xEA,0xBF,0x84,0x1F, +0xEA,0x94,0x94,0x33,0x4C,0x54,0x00,0x2B,0x98,0x98,0x88,0x0E,0x3B,0x00,0x44,0x00, +0xEA,0xA2,0xD5,0x24,0xEA,0xE0,0xC0,0x0E,0xC6,0x0D,0x46,0x01,0x00,0x01,0x04,0x00, +0x03,0x36,0x5C,0xF0,0x00,0xC9,0xE9,0x06,0x2E,0x27,0xFF,0xB3,0x3E,0xD7,0xFD,0x10, +0xD5,0x03,0x2E,0x27,0xFC,0xDB,0x00,0x05,0x80,0x00,0xE2,0x02,0xE8,0x0B,0x8C,0x01, +0xEA,0xBF,0x84,0x5F,0x40,0x06,0x18,0x20,0xB7,0x07,0x14,0x83,0x80,0x01,0xAE,0x81, +0xD5,0x05,0x84,0x00,0xEA,0x94,0x84,0x1F,0xEA,0xBF,0x8C,0xC1,0x8D,0x61,0x8D,0x21, +0x8C,0xE8,0xD5,0xAD,0x84,0xC0,0xBE,0x80,0x84,0x3F,0x46,0x01,0x00,0x01,0x58,0x00, +0x0D,0x80,0xFA,0x48,0xDD,0x42,0x80,0x06,0x46,0x41,0x00,0x01,0x58,0x42,0x0D,0x98, +0xEA,0xB3,0x46,0x31,0x00,0x01,0x58,0x31,0x8D,0x08,0x46,0x71,0x00,0x01,0x58,0x73, +0x8C,0xD8,0x82,0x40,0x45,0x30,0xFF,0xFE,0x46,0x91,0x00,0x01,0x58,0x94,0x8D,0x80, +0x85,0x7E,0x38,0x55,0x02,0x02,0x94,0x42,0xD6,0x0F,0xBA,0x00,0x8C,0x41,0xBA,0x80, +0x4C,0x59,0xC0,0x0D,0x98,0xA1,0x88,0x23,0xEA,0x6A,0x40,0x10,0x24,0x00,0xEA,0xA2, +0x10,0xB0,0x80,0x01,0xD5,0x07,0x39,0x23,0x81,0x0A,0x98,0x99,0x88,0x2A,0xEA,0x6A, +0xEA,0xA2,0x8C,0x02,0x5A,0x08,0x18,0xE7,0x49,0xFF,0xFE,0x90,0xFC,0xE1,0xFC,0x60, +0x3F,0xCF,0xFD,0xD4,0xB8,0x0B,0xC0,0x03,0x84,0x00,0xD5,0x04,0x2E,0x07,0xFF,0x5D, +0x92,0x04,0x3E,0x07,0xFC,0xE3,0xEB,0x46,0xB9,0x04,0x8C,0x01,0xE2,0x20,0x46,0x21, +0x00,0x01,0x58,0x21,0x09,0x48,0x2E,0x90,0x00,0xE3,0xE9,0x21,0x84,0xEC,0x42,0x60, +0x1C,0x24,0x84,0x74,0x84,0xA0,0x46,0xB1,0x00,0x01,0x58,0xB5,0x8D,0x98,0xB8,0x84, +0x88,0x46,0xEB,0x79,0x58,0x10,0x89,0x54,0x43,0x30,0x0C,0x24,0x88,0xC3,0x81,0x05, +0x46,0xA1,0x00,0x01,0x58,0xA5,0x0D,0x68,0x46,0xC1,0x00,0x02,0x58,0xC6,0x00,0xB4, +0x3E,0xD8,0x02,0x8C,0xEA,0x8C,0x81,0xCB,0x86,0x87,0xD5,0x4E,0x84,0x60,0x44,0x60, +0x00,0x30,0xE0,0x69,0xE8,0xDC,0x80,0x22,0x42,0x11,0x98,0x73,0x84,0x81,0x8C,0x2C, +0xE0,0x80,0x8C,0x2C,0xE8,0x09,0x50,0x50,0xFF,0xF4,0x3B,0x02,0xC8,0x00,0x8C,0x81, +0x3B,0x00,0xC8,0x20,0xD5,0xF6,0x8C,0x61,0xD5,0xED,0x50,0xF1,0xFF,0xF4,0x3B,0x01, +0xC8,0x00,0x51,0x5A,0x80,0x01,0x3B,0x07,0xC8,0x20,0x40,0xFA,0x80,0x07,0x8C,0x6C, +0xE9,0xF5,0x2E,0x37,0xFF,0x5C,0x43,0x21,0x98,0x0B,0x38,0x35,0x14,0x00,0x4F,0x22, +0x00,0x29,0x38,0x36,0x8C,0x10,0x39,0x15,0x97,0x02,0x41,0x02,0x8C,0x08,0x4D,0x12, +0x00,0x2B,0x2F,0x17,0xFC,0xF2,0xE3,0xA3,0x40,0x38,0xBC,0x1B,0x89,0x8E,0x3B,0x08, +0x44,0x00,0xEA,0xA2,0x4F,0x23,0x00,0x07,0x05,0x01,0x00,0x02,0x42,0x3A,0x40,0x73, +0x92,0x63,0xA8,0xD2,0x04,0x30,0xFF,0xFD,0x4C,0x32,0x00,0x18,0x8C,0xA1,0x50,0x10, +0x80,0x30,0x50,0x21,0x00,0x30,0xE0,0xA9,0xE8,0x2F,0x80,0x61,0x86,0xA0,0xD5,0xC6, +0x81,0xEC,0x42,0xF1,0x9C,0x73,0x80,0x6F,0x2E,0xF7,0xFD,0x0A,0xA0,0xDA,0x40,0x31, +0xBC,0x0D,0xD5,0xD2,0x84,0x60,0xD5,0xDB,0xB4,0x61,0x4C,0x32,0x3F,0xE9,0x5A,0x00, +0x01,0xE7,0xBB,0x00,0xE6,0x63,0xE8,0x05,0xA0,0xCB,0x4C,0x32,0x40,0x5A,0xD5,0x20, +0xA0,0xCB,0x4C,0x32,0x00,0x07,0x5A,0x08,0x03,0xF9,0xA0,0xCE,0x4C,0x32,0x7F,0xF6, +0x80,0x61,0x86,0x01,0x8D,0x81,0xE0,0x10,0xB6,0x83,0xA9,0x19,0x14,0x81,0x80,0x02, +0x8C,0x6C,0xE8,0xF9,0xD5,0xEA,0x84,0xC0,0xEA,0x23,0xE0,0xC0,0xE8,0x45,0x96,0x30, +0xEB,0x79,0x58,0x10,0x89,0x48,0x49,0xFF,0xF3,0xEC,0x8C,0xC1,0xD5,0xF6,0x84,0x61, +0x5A,0x08,0x03,0xBE,0x05,0x00,0x80,0x06,0x4D,0x02,0x3F,0xBA,0xCB,0xB8,0xB4,0x61, +0xB5,0xA2,0x05,0x01,0x00,0x01,0x41,0x58,0x8C,0x01,0xA0,0xC9,0x40,0xF8,0x0C,0x01, +0x2E,0x30,0x00,0xEA,0x42,0xF7,0xBC,0x24,0x41,0x21,0x88,0x09,0x2E,0x30,0x00,0xEB, +0x42,0xFA,0xD4,0x73,0x92,0x62,0xFE,0xDC,0x42,0x39,0x48,0x73,0x40,0xF7,0x8C,0x07, +0xE8,0x9E,0x41,0x21,0x4C,0x00,0x38,0x39,0x18,0x02,0x89,0xC6,0x89,0xA3,0x04,0x39, +0x00,0x01,0x93,0xA1,0x88,0x70,0x92,0x61,0x82,0x01,0x86,0x41,0x8D,0xC1,0xE0,0x12, +0xB7,0xB0,0x14,0x38,0x00,0x01,0x8D,0x8C,0xE8,0xFA,0x48,0xFF,0xFF,0x89,0x84,0x60, +0x5A,0x00,0x03,0xCA,0xD5,0xCD,0xFC,0xE0,0xFC,0x64,0x81,0x80,0x84,0x00,0x12,0x06, +0x00,0x48,0x10,0x06,0x00,0x92,0x2E,0x17,0xFD,0x03,0x2E,0x47,0xFF,0x7A,0x2E,0x07, +0xFF,0x79,0xC9,0x05,0xEA,0x98,0xC9,0x03,0xEA,0x82,0xC1,0x06,0x58,0x12,0x00,0x0F, +0xB6,0x3F,0x92,0x04,0xD5,0x05,0x97,0x1F,0x94,0x63,0xB6,0x3F,0x96,0x1F,0x8C,0x01, +0x85,0x48,0x42,0xA0,0x28,0x01,0x2E,0x07,0xFC,0xD7,0xE2,0x0A,0xE8,0x03,0x8C,0x01, +0xD5,0x04,0xE3,0x40,0xE8,0x03,0x8E,0x01,0xEA,0xED,0x40,0x05,0x04,0x09,0x96,0x00, +0xF0,0x82,0x84,0xC0,0x46,0x81,0x00,0x01,0x58,0x84,0x06,0x30,0x3C,0xDD,0xFE,0xC6, +0x46,0xE1,0x00,0x01,0x58,0xE7,0x06,0x24,0xEA,0x23,0xE2,0xC0,0x4E,0xF2,0x01,0x5A, +0x94,0x73,0x46,0x01,0x00,0x01,0x58,0x00,0x0E,0x38,0x39,0x10,0x1B,0x02,0x88,0x01, +0xF1,0x81,0xA1,0x41,0xEB,0x79,0x58,0x10,0x89,0x48,0xDD,0x47,0xEB,0x0E,0x38,0x44, +0x18,0x00,0x80,0x01,0x8C,0x0C,0xA1,0xCB,0x04,0x90,0x00,0x01,0xEA,0x28,0x46,0x21, +0x00,0x01,0x58,0x21,0x06,0x3C,0x4C,0x70,0x40,0x0D,0x4C,0x93,0xC0,0x0B,0x44,0x0F, +0xFF,0xB4,0x38,0x07,0x18,0x08,0x84,0x00,0x38,0x01,0x18,0x08,0x48,0x00,0x01,0x1D, +0x00,0x06,0x00,0x92,0x84,0x21,0x8C,0x01,0x10,0x06,0x00,0x92,0x02,0x06,0x00,0x48, +0x40,0x30,0x98,0x0C,0xFE,0x1F,0x12,0x06,0x00,0x48,0x38,0x01,0x18,0x00,0x47,0xC1, +0x00,0x01,0x59,0xCE,0x06,0x48,0xC8,0x14,0x46,0x21,0x00,0x01,0x58,0x21,0x06,0x3C, +0x38,0x11,0x18,0x08,0x94,0xB6,0x40,0x1E,0x00,0x00,0x38,0x70,0x88,0x0A,0x8C,0x08, +0x88,0x22,0x14,0x90,0x80,0x01,0x5A,0x08,0x40,0xF8,0x48,0x00,0x00,0xF8,0xE3,0xA7, +0xE8,0x04,0x41,0x33,0xC4,0x01,0xD5,0x03,0x41,0x38,0x9C,0x01,0xE2,0xA9,0xE8,0x04, +0x41,0x24,0x94,0x01,0xD5,0x03,0x41,0x22,0xA4,0x01,0x42,0x19,0xCC,0x24,0x42,0x19, +0x48,0x73,0x38,0x07,0x18,0x00,0x92,0x21,0xC8,0x06,0x2E,0x27,0xFF,0x73,0x2E,0x37, +0xFF,0x74,0xD5,0x05,0x2E,0x27,0xFF,0x77,0x2E,0x37,0xFF,0x78,0x2E,0xF7,0xFD,0x26, +0x47,0x61,0x00,0x01,0x59,0x6B,0x0D,0x68,0xE9,0x10,0x38,0xFB,0x18,0x00,0x47,0x01, +0x00,0x01,0x59,0x08,0x0F,0xF4,0x2E,0xB7,0xFD,0x01,0x39,0x08,0x3E,0x02,0xE3,0x70, +0xE9,0x04,0x2E,0xF7,0xFD,0x20,0xE8,0x07,0x86,0x03,0x42,0x21,0x40,0x24,0xEA,0xF2, +0x96,0x90,0x96,0xD8,0xC8,0x15,0xE2,0xE2,0xE9,0x09,0x3D,0x0C,0x00,0x36,0x8F,0x81, +0x8B,0x82,0xE3,0x87,0x40,0x20,0x3C,0x1B,0xD5,0x02,0x80,0x40,0xE3,0x23,0xE9,0x07, +0x3D,0x0C,0x00,0x37,0x8F,0x81,0x8B,0x83,0xE3,0x89,0xE8,0x02,0x84,0x60,0x46,0xB1, +0x00,0x02,0x58,0xB5,0x80,0xB4,0x38,0xFB,0x18,0x00,0x86,0x0C,0x82,0x8B,0x43,0x47, +0xC0,0x73,0x04,0xFA,0x00,0x02,0xE9,0x02,0xC0,0x0F,0xE3,0xE2,0xE8,0x03,0xE3,0xC3, +0xE9,0x09,0x84,0x00,0x46,0x21,0x00,0x01,0x58,0x21,0x06,0x24,0x38,0x01,0x18,0x08, +0xD5,0x03,0x81,0x25,0x80,0xF1,0xB4,0x1F,0x92,0x22,0x40,0x10,0x80,0x37,0x8C,0x21, +0xE6,0x31,0xE9,0x02,0xFA,0x20,0xB4,0x1F,0xC0,0x41,0xEB,0x46,0xC0,0x09,0xDD,0x47, +0x80,0x4D,0x42,0x23,0x00,0x73,0xEA,0x28,0xA0,0x96,0x4C,0x20,0x00,0x38,0x80,0x06, +0x15,0x6F,0x80,0x07,0xF1,0x86,0xF5,0x85,0x15,0x1F,0x80,0x04,0xF4,0x83,0xF8,0x41, +0xF4,0x03,0x05,0x1F,0x80,0x04,0xF5,0x05,0xF1,0x06,0x05,0x6F,0x80,0x07,0xC8,0x26, +0x38,0x2B,0x18,0x00,0x84,0x0C,0x42,0xB1,0x00,0x73,0x04,0x05,0x80,0x02,0xC0,0x1E, +0x52,0x00,0x80,0x10,0x42,0x20,0x44,0x24,0x42,0x23,0x84,0x73,0x95,0xFC,0x82,0x22, +0x3C,0x2C,0x00,0x36,0xFF,0x44,0x40,0x73,0x88,0xF7,0x42,0x54,0x84,0x73,0x40,0x04, +0x90,0x08,0x3C,0x9C,0x00,0x37,0x97,0xF8,0x40,0x00,0x24,0x17,0x96,0x00,0x89,0xA7, +0x88,0xA0,0x40,0x78,0x90,0x09,0x40,0x92,0x90,0x09,0xF0,0x01,0xE6,0x2D,0x88,0x04, +0x40,0x0E,0x00,0x60,0xB6,0xE0,0x14,0x90,0x00,0x01,0xE9,0x09,0xDD,0x47,0x80,0x2D, +0xEB,0x0E,0xEA,0x28,0xA1,0x4E,0xD8,0x03,0xEB,0x46,0xC8,0x23,0x80,0x06,0xF4,0x83, +0x49,0xFF,0xF3,0x53,0xF4,0x03,0xC8,0x1D,0x80,0xE0,0x80,0xA0,0x4C,0x55,0x00,0x13, +0xF1,0x01,0x88,0x24,0x38,0x2E,0x07,0x02,0x40,0x1E,0x04,0x60,0xA0,0x49,0x88,0xE2, +0x88,0x01,0xC4,0x04,0x9E,0x61,0x97,0x08,0xD5,0x02,0x84,0x87,0x8C,0xA1,0x97,0x68, +0xD5,0xEE,0xF1,0x02,0x88,0xE1,0x88,0x01,0x40,0x73,0xA8,0xF7,0x40,0x90,0x29,0x37, +0x46,0x01,0x00,0x01,0x58,0x00,0x06,0x30,0x38,0x00,0x18,0x00,0x8C,0x01,0x96,0x00, +0x5A,0x08,0x08,0x03,0x84,0x00,0x38,0x04,0x18,0x08,0x84,0x0C,0x80,0x2C,0xEB,0x0E, +0x80,0x4D,0xB6,0xE1,0x14,0x90,0x80,0x01,0x80,0x01,0x44,0x10,0x00,0x30,0x42,0x23, +0x04,0x73,0x8C,0xC1,0xA0,0x55,0x10,0x10,0x00,0x08,0x97,0xB0,0x48,0xFF,0xFE,0xA6, +0x3E,0xA7,0xFC,0xD7,0xFC,0xE4,0xEA,0x57,0x42,0x00,0x18,0x0B,0x4E,0x02,0x01,0x68, +0x84,0x00,0x3E,0x18,0x02,0x8C,0x84,0x41,0x38,0x20,0x80,0x08,0x8C,0x01,0x5A,0x08, +0x0C,0xFD,0xFC,0x66,0xEA,0xC3,0xF0,0x83,0xEB,0x1E,0xF0,0x81,0xEA,0x31,0xF0,0x84, +0xEA,0xA4,0xF0,0x82,0xEA,0x77,0xF0,0x85,0x2E,0x00,0x00,0xBA,0xF0,0x86,0x2E,0x00, +0x00,0xBB,0x85,0x80,0xF0,0x87,0x3E,0x68,0x02,0x8C,0x3E,0xA8,0x01,0x84,0x84,0xE1, +0x81,0x6C,0xF0,0x03,0x4C,0xB0,0x01,0x43,0x00,0x15,0x00,0x00,0x01,0x05,0x00,0x01, +0x01,0x15,0x00,0x02,0x40,0x00,0xC0,0x00,0x40,0x80,0x04,0x0A,0x00,0x05,0x00,0x03, +0x40,0x28,0x80,0x00,0x41,0x41,0x04,0x0A,0xC1,0x08,0x4F,0x02,0x00,0x09,0x4F,0x12, +0x00,0x09,0x40,0x70,0x00,0x1A,0xD5,0x06,0x80,0xE1,0xD5,0x04,0x80,0xF0,0xD5,0x02, +0x80,0xF1,0xEB,0x30,0x42,0x40,0x08,0x24,0x84,0x60,0x40,0x42,0x04,0x20,0x44,0x20, +0x00,0x4A,0x42,0x43,0x88,0x75,0x80,0xA1,0x82,0x63,0x81,0x23,0x82,0x43,0x83,0x03, +0xE3,0x85,0xE9,0x24,0x41,0x51,0x90,0x00,0x46,0x21,0x00,0x02,0x58,0x21,0x01,0x44, +0x41,0x5A,0x88,0x00,0x81,0xA0,0x85,0xC0,0x40,0x22,0xA0,0x06,0xE3,0xAD,0xE9,0x13, +0x40,0xFA,0xB8,0x00,0x22,0xF7,0x8C,0xAA,0xC2,0x05,0x89,0xCF,0x43,0x37,0x94,0x73, +0xD5,0x05,0x41,0x8C,0x3C,0x00,0x42,0x97,0x94,0x73,0x50,0xD6,0x80,0x01,0x50,0xE7, +0x00,0x48,0xD5,0xED,0x8C,0xA1,0x8C,0x62,0xD5,0xDC,0x84,0x60,0x83,0x83,0x81,0xA3, +0x81,0xC3,0x81,0x03,0xE3,0x81,0xE9,0x23,0x99,0x5C,0x46,0x21,0x00,0x02,0x58,0x21, +0x01,0x44,0x41,0x62,0x88,0x00,0x86,0xA0,0x80,0xA0,0xE3,0xA5,0xE9,0x15,0xE2,0xB4, +0x41,0x7B,0x54,0x00,0xE8,0x07,0x22,0xFB,0x8C,0xAA,0x89,0x0F,0x42,0xD7,0x94,0x73, +0xD5,0x07,0x22,0xFB,0x8C,0xAA,0x40,0xE7,0x3C,0x00,0x43,0xC7,0x94,0x73,0x8C,0xA1, +0x51,0x5A,0x80,0x48,0xD5,0xEB,0x8C,0x21,0x8C,0x62,0xD5,0xDD,0xF0,0x01,0xF1,0x04, +0x80,0x58,0x40,0x40,0x04,0x97,0x84,0x60,0x42,0x04,0x90,0x69,0x15,0x3F,0x80,0x0B, +0x15,0x2F,0x80,0x0A,0xF4,0x88,0xF8,0x36,0xF4,0x08,0x81,0x20,0x40,0x52,0x04,0x09, +0x05,0x2F,0x80,0x0A,0x05,0x3F,0x80,0x0B,0xC9,0x05,0xC9,0x03,0xE2,0xA0,0xE9,0x02, +0x85,0x20,0x42,0x09,0x90,0x69,0x80,0x52,0x84,0x60,0xF5,0x88,0xF8,0x23,0x80,0x80, +0xF5,0x08,0xC9,0x05,0xC9,0x03,0xE2,0xA0,0xE9,0x02,0x84,0x80,0xF0,0x02,0xF1,0x05, +0x80,0x4E,0x40,0x50,0x04,0xB7,0x84,0x60,0x42,0x0E,0x14,0x69,0xF4,0x8A,0xF5,0x88, +0xF8,0x11,0xF5,0x08,0x81,0xC0,0x41,0xC2,0x84,0x09,0xF4,0x0A,0xC9,0x06,0xC9,0x04, +0x40,0xFE,0x00,0x06,0xE9,0x02,0x85,0xC0,0x80,0x48,0x42,0x06,0x94,0x69,0x84,0x60, +0xF4,0x88,0xEA,0x67,0x80,0x40,0xF4,0x08,0xC9,0x05,0xC9,0x06,0x40,0xFE,0x00,0x06, +0xE8,0x03,0x80,0x02,0xD5,0x02,0x84,0x00,0x4E,0x92,0x00,0x0C,0xC4,0x0A,0xE2,0x89, +0xE8,0x04,0x40,0x44,0x90,0x01,0xD5,0x02,0x8A,0x89,0x40,0x92,0x00,0x13,0xD5,0x02, +0x85,0x21,0x4E,0xE2,0x00,0x0B,0xC0,0x09,0xE2,0x0E,0xE8,0x04,0x40,0x07,0x00,0x01, +0xD5,0x02,0x8A,0x0E,0x96,0x01,0xD5,0x02,0x84,0x01,0xF8,0x11,0xF8,0x12,0xF8,0x1E, +0x84,0x40,0x46,0x34,0x05,0x0C,0xF8,0x1A,0xFD,0x20,0xF0,0x88,0xF0,0x02,0xF5,0x89, +0xF8,0x1B,0xF8,0x1C,0xF8,0x20,0xF8,0x21,0x81,0x00,0x80,0x09,0x49,0x00,0x2D,0x7A, +0x46,0x2F,0x5C,0x28,0x46,0x34,0x00,0x15,0x50,0x21,0x0F,0x5C,0x50,0x31,0x8C,0x28, +0x83,0xFF,0xF8,0x04,0x84,0x40,0x46,0x34,0x06,0x28,0x49,0x00,0x2A,0xEF,0xFD,0x20, +0xF0,0x88,0xF0,0x01,0xF5,0x89,0x49,0x00,0x2D,0x8B,0xF4,0x08,0xF5,0x09,0xFD,0x10, +0xFD,0x02,0x83,0xFF,0x49,0x00,0x2B,0xD2,0x49,0x00,0x2D,0x36,0xE3,0x00,0x40,0x04, +0x3C,0x1A,0x96,0x42,0xE4,0x34,0xE9,0x02,0x85,0x81,0xEB,0x79,0x58,0x10,0x8F,0xF4, +0x88,0x0C,0x38,0x10,0xAE,0x02,0x96,0x02,0xE2,0x20,0x80,0x46,0xAE,0x30,0xE8,0x02, +0xAE,0x70,0xF0,0x06,0xE2,0x20,0xE9,0x0A,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0xCC, +0x38,0x00,0x2C,0x00,0xF1,0x07,0xE2,0x01,0xE8,0x05,0x20,0x03,0x00,0x00,0x90,0x01, +0xAE,0x30,0x20,0x01,0x00,0x00,0x8C,0xC1,0x4E,0x06,0x00,0x05,0x84,0x01,0x10,0x03, +0x7F,0xFF,0x8D,0x61,0x8D,0x44,0x48,0xFF,0xFE,0xBE,0xFC,0xE6,0xDD,0x9E,0xFC,0x60, +0x3F,0xCF,0xFD,0xC0,0x3E,0x08,0x02,0x98,0x84,0x20,0xEB,0x30,0xDD,0x42,0x3E,0x08, +0x02,0xE0,0x44,0x10,0x7F,0xFF,0xFA,0x54,0xEA,0xA9,0x46,0x01,0x00,0x01,0x58,0x00, +0x00,0x28,0x84,0x20,0xFA,0x54,0xDD,0x42,0xEA,0x56,0xEA,0xF3,0xC0,0x1F,0xDD,0x54, +0x5A,0x08,0x01,0x12,0xEB,0x25,0xC8,0x0C,0xEB,0x08,0x2E,0x07,0xFF,0x97,0xC1,0x03, +0x2E,0x00,0x00,0x2A,0xEA,0x82,0xC1,0x09,0x2E,0x00,0x00,0x0D,0xD5,0x06,0x2E,0x07, +0xFF,0x9A,0xD5,0x03,0x2E,0x07,0xFF,0x98,0xB9,0x00,0x5A,0x18,0x03,0x04,0x2E,0x07, +0xFF,0x9B,0xEA,0x98,0xC1,0x03,0x2E,0x00,0x00,0x2B,0xEA,0xCC,0xEA,0x8E,0xC1,0x18, +0xB9,0x00,0x5A,0x18,0x02,0x06,0x2E,0x27,0xFD,0x26,0x5A,0x20,0x01,0x05,0x2E,0x27, +0xFD,0x07,0xC2,0x04,0x2E,0x17,0xFF,0xA0,0xD5,0x0B,0x5A,0x10,0x03,0x05,0xEA,0x98, +0x5A,0x18,0x01,0x05,0x2E,0x17,0xFF,0x9F,0xD5,0x03,0x2E,0x17,0xFF,0x9E,0x46,0x21, +0x00,0x07,0x12,0x01,0x07,0xA4,0x2E,0x27,0xFC,0xFE,0x2E,0x30,0x00,0x9F,0xE2,0x62, +0xE8,0x03,0x8A,0x43,0xD5,0x02,0x84,0x40,0x3E,0x27,0xFC,0xFE,0x2F,0x17,0xFC,0xFE, +0x46,0x21,0x00,0x07,0x02,0x21,0x07,0xA4,0x41,0x28,0x80,0x13,0x88,0x52,0x96,0x91, +0x46,0x31,0x00,0x07,0x12,0x21,0x87,0xA4,0x46,0x21,0x00,0x01,0x96,0x03,0x12,0x11, +0x00,0x13,0x46,0x21,0x00,0x01,0x12,0x01,0x00,0x12,0x84,0x00,0x46,0x21,0x00,0x05, +0x12,0x01,0x02,0xD6,0x2E,0x40,0x00,0xE1,0x2F,0x00,0x00,0xE0,0x3C,0x8D,0xFF,0x7E, +0x46,0x21,0x00,0x01,0x58,0x21,0x00,0x28,0x84,0x00,0x46,0xB1,0x00,0x03,0x58,0xB5, +0x80,0x78,0x3E,0x98,0x02,0xE0,0x82,0x62,0x44,0xD0,0x00,0x48,0x46,0xE1,0x00,0x07, +0x58,0xE7,0x05,0x00,0x45,0x40,0x00,0x4C,0x82,0xA0,0x51,0x65,0xF0,0xCC,0x82,0xE9, +0x3E,0xC8,0x02,0x98,0xE2,0x04,0xE8,0x4E,0x83,0x0E,0x43,0x80,0x34,0x73,0x43,0x90, +0x50,0x24,0x95,0xC2,0x84,0xC0,0xE2,0xD0,0xE8,0x3B,0x38,0x5C,0x19,0x01,0x40,0xAC, +0x98,0x20,0x38,0x35,0x95,0x01,0x38,0x54,0x15,0x01,0x89,0x56,0x9B,0x5D,0x97,0x69, +0x96,0xEB,0x12,0x35,0x14,0xB2,0x02,0xA1,0x00,0x00,0xE1,0x43,0xE8,0x02,0xAD,0x50, +0x38,0xA4,0x9C,0x02,0xE2,0x6A,0xE8,0x06,0x4E,0x37,0x00,0x07,0x38,0x34,0x9C,0x0A, +0xD5,0x06,0x4E,0x36,0x00,0x05,0x39,0x5B,0x9C,0x0A,0xD5,0x18,0x38,0xA6,0x1C,0x02, +0x89,0x43,0x38,0xA6,0x1C,0x0A,0x46,0xA1,0x00,0x05,0x02,0xA5,0x02,0xD6,0xE1,0x43, +0xE8,0x0D,0x46,0x31,0x00,0x05,0x12,0x51,0x82,0xD6,0x46,0x31,0x00,0x05,0x10,0x01, +0x85,0xAE,0x46,0x31,0x00,0x05,0x10,0x61,0x85,0xAF,0x8C,0xC1,0xD5,0xC5,0xC9,0x03, +0xAC,0x50,0xD5,0x05,0xA4,0xD0,0x40,0x31,0x84,0x77,0xAC,0xD0,0x8C,0x01,0x8C,0x42, +0xD5,0xB2,0x2E,0x30,0x00,0xBC,0x84,0x00,0x80,0x40,0x3E,0x58,0x02,0xE0,0xE2,0x44, +0xE8,0x0E,0xEB,0x79,0x02,0x10,0x80,0x12,0x38,0x62,0x8A,0x02,0x96,0x4B,0x88,0x23, +0xE2,0x26,0xE8,0x03,0x8C,0x01,0x96,0x01,0x8C,0x41,0xD5,0xF2,0xC0,0x08,0x2E,0x17, +0xFC,0xFF,0x84,0x03,0xFE,0x0C,0x8C,0x01,0x3C,0x0B,0xFE,0xBD,0x3C,0x23,0xFE,0xBD, +0xC2,0x16,0x2E,0x30,0x00,0xBE,0x3E,0x58,0x02,0xE0,0x84,0x00,0x3E,0x68,0x02,0x98, +0xE2,0x04,0xE8,0x0A,0x38,0x13,0x02,0x02,0x40,0x10,0xC0,0x37,0x88,0x23,0x38,0x12, +0x82,0x0A,0x8C,0x01,0xD5,0xF6,0x8E,0x41,0x3C,0x2B,0xFE,0xBD,0xEA,0xF8,0x96,0x1E, +0xC8,0x1F,0xEB,0x4F,0x46,0x21,0x00,0x05,0x02,0x10,0x02,0xD6,0x00,0x21,0x05,0xAE, +0x46,0x01,0x00,0x01,0x02,0x00,0x00,0x12,0x38,0x29,0x89,0x01,0x96,0x03,0x88,0x02, +0xE0,0x01,0xEB,0x1C,0xEB,0x27,0xE8,0x1F,0x46,0x01,0x00,0x01,0x02,0x00,0x00,0x12, +0x96,0x03,0x88,0x40,0x8A,0x22,0xEB,0x4F,0x12,0x10,0x02,0xD6,0xD5,0x19,0x84,0x00, +0x3E,0x28,0x02,0xE0,0x46,0x31,0x00,0x01,0x58,0x31,0x80,0x28,0xE2,0x04,0xE8,0xDA, +0x38,0x11,0x02,0x02,0x38,0x59,0x81,0x01,0xE2,0xA1,0xE8,0x03,0x38,0x11,0x81,0x09, +0x8C,0x01,0xD5,0xF5,0x84,0x00,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD6,0xEB,0x4F, +0xEB,0x21,0x84,0x40,0x40,0xB0,0x04,0x09,0x2E,0xE7,0xFF,0x64,0x2F,0x47,0xFF,0xCD, +0x46,0x01,0x00,0x01,0x00,0x90,0x02,0xC0,0x2E,0x87,0xFD,0x04,0x80,0xA2,0x80,0x62, +0x44,0xD0,0x00,0x4C,0x80,0xE2,0x53,0x58,0x80,0x00,0xE2,0x64,0xE8,0x52,0x80,0x06, +0x42,0x01,0xB4,0x73,0x40,0xC1,0x84,0x08,0x50,0x00,0x29,0x64,0x85,0x40,0xE3,0x50, +0xE8,0x46,0x22,0x10,0x00,0x00,0x4E,0x15,0x00,0x13,0xEA,0x89,0xEA,0x9C,0x39,0x69, +0xB0,0x01,0xEA,0x7F,0x40,0xFB,0x3C,0x00,0x40,0xF7,0x84,0x07,0xE8,0x14,0xEA,0x89, +0xEA,0x9C,0xEA,0x7F,0x40,0xFB,0x3C,0x00,0x8A,0x2F,0xD5,0x0B,0xEA,0x89,0xEA,0x9C, +0xEA,0x7F,0x52,0xF7,0x80,0x00,0xE0,0x2F,0xE8,0x06,0xEA,0x89,0xEA,0x9C,0x88,0x2F, +0xAC,0x40,0xD5,0x02,0xAD,0xC0,0x22,0x10,0x00,0x00,0x4E,0x17,0x00,0x08,0xE0,0x2B, +0xE8,0x0B,0xE1,0xA1,0xE8,0x08,0x8A,0x32,0xD5,0x04,0xE0,0x35,0xE8,0x04,0x88,0x32, +0xAC,0x40,0xD5,0x02,0xAD,0xC0,0x2A,0x10,0x00,0x01,0x40,0xF0,0xB8,0x00,0x4E,0xF4, +0x00,0x09,0x8C,0xA1,0x97,0x69,0xE2,0xB4,0xE9,0x04,0x58,0x94,0x80,0x01,0x85,0x01, +0x4E,0x14,0x00,0x04,0x8A,0x41,0x96,0x91,0x8D,0x41,0xD5,0xBA,0x8C,0x61,0xD5,0xAE, +0x46,0x01,0x00,0x01,0x10,0x90,0x02,0xC0,0x3E,0x87,0xFD,0x04,0x2E,0x07,0xFF,0xFE, +0x94,0x05,0xE0,0x02,0xE8,0x08,0x54,0x04,0x80,0xFF,0xEB,0x02,0xEB,0x79,0xEA,0xEE, +0x84,0x01,0xEA,0x75,0x46,0x01,0x00,0x07,0x04,0x10,0x03,0xF2,0xEB,0x4F,0xEB,0x21, +0xE2,0x20,0xE8,0x11,0x46,0x01,0x00,0x01,0x00,0x00,0x02,0xC0,0xEB,0x79,0xEB,0x04, +0xEA,0xEE,0x84,0x21,0x3E,0x17,0xFD,0x04,0x2E,0x07,0xFC,0xE0,0x8C,0x01,0xB8,0x91, +0x3E,0x17,0xFD,0x15,0xB8,0x00,0x5A,0x08,0x03,0x05,0x84,0xE1,0x86,0x24,0xD5,0x03, +0x84,0xE0,0x86,0x21,0xEB,0x01,0x5A,0x08,0x01,0x04,0x80,0xE0,0x86,0x22,0x40,0x08, +0x9C,0x20,0x54,0x90,0x00,0xFF,0x2F,0x67,0xFD,0x26,0x2F,0x37,0xFD,0x30,0x84,0xA0, +0x51,0x79,0xFF,0xFF,0x80,0x45,0x45,0x50,0x00,0x26,0x45,0x40,0x00,0x24,0x44,0xE0, +0x00,0x48,0x44,0xDF,0xFF,0xB8,0xE2,0x44,0xE8,0x41,0x42,0xA1,0x38,0x24,0x52,0x12, +0xA9,0x64,0x50,0x35,0x19,0x54,0x42,0xB1,0x54,0x24,0x42,0x81,0x50,0x24,0x88,0x26, +0x88,0x66,0x42,0xC1,0x34,0x24,0x86,0x40,0xE3,0xD0,0xE8,0x2C,0x40,0xF0,0x94,0x00, +0x4F,0x62,0x00,0x0D,0x4F,0x32,0x00,0x0B,0x38,0x07,0xAD,0x11,0x22,0xF0,0xFD,0x2F, +0x42,0x07,0xDC,0x73,0x40,0x00,0x4C,0x16,0xD5,0x12,0x40,0x01,0xB0,0x00,0x38,0x00, +0x21,0x11,0x39,0x87,0xAD,0x11,0x40,0xF7,0xA8,0x00,0xFE,0x3C,0x22,0xF7,0xFA,0x80, +0x42,0x0C,0x44,0x73,0x42,0x07,0x9C,0x73,0x40,0x00,0x24,0x16,0x12,0x00,0xFD,0x2F, +0xA4,0x18,0x12,0x01,0x82,0x88,0x2A,0x00,0x80,0x01,0x1A,0x01,0x80,0x01,0x8D,0xC1, +0xD5,0xD4,0x8C,0x41,0x50,0x52,0xFF,0xB4,0xD5,0xBF,0x46,0x01,0x00,0x04,0x58,0x00, +0x0A,0xA8,0x44,0x10,0x00,0xFD,0x44,0x20,0x02,0xF8,0xEA,0xA9,0x2E,0x0F,0xFF,0xCC, +0x4E,0x04,0x00,0xAC,0x2E,0x07,0xFC,0xED,0xC8,0x04,0x2F,0x00,0x00,0x44,0xD5,0x03, +0x45,0x00,0x00,0xFF,0x2E,0x07,0xFD,0x02,0xC8,0x04,0x2E,0x70,0x00,0x44,0xD5,0x02, +0xEA,0xE7,0x2E,0x50,0x00,0xE1,0xEA,0x31,0x9D,0x29,0x50,0x90,0x7F,0xFF,0x51,0x10, +0x00,0x01,0x46,0x11,0x00,0x04,0x58,0x10,0x85,0x04,0x84,0x61,0x86,0x40,0xE2,0x64, +0xE8,0x20,0x22,0x20,0x80,0x01,0x23,0x30,0x80,0x02,0xE1,0xE2,0xE8,0x06,0x8A,0x53, +0xFE,0xBC,0x90,0x48,0xAC,0x88,0xD5,0x03,0x13,0x20,0x80,0x00,0x38,0x20,0x81,0x11, +0x39,0x30,0xA5,0x11,0xE1,0xE2,0xE8,0x07,0x8A,0x53,0xFE,0xBC,0x90,0x48,0x38,0x20, +0xC5,0x09,0xD5,0x03,0x39,0x20,0xC5,0x09,0x8C,0x61,0x50,0x10,0x80,0x4C,0xD5,0xE0, +0x44,0x70,0x00,0x4C,0xFF,0xEC,0x9C,0x81,0x46,0x11,0x00,0x04,0x58,0x10,0x84,0xBA, +0x51,0x23,0x80,0x4C,0x86,0x21,0x86,0x60,0xE3,0xA2,0xE8,0x21,0x22,0x30,0x80,0x26, +0x22,0x90,0x80,0x4C,0xE1,0x23,0xE8,0x06,0x8A,0x69,0xEA,0xF2,0x90,0x68,0xAC,0xC8, +0xD5,0x03,0x13,0x30,0x80,0x00,0x40,0x90,0x9C,0x00,0x38,0x30,0x9C,0x11,0x22,0x94, +0xFF,0xDA,0xE1,0x23,0xE8,0x07,0x8A,0x69,0xEA,0xF2,0x90,0x68,0x38,0x30,0xC8,0x09, +0xD5,0x03,0x39,0x30,0xC8,0x09,0x8D,0xA1,0x8C,0x22,0xD5,0xDF,0x46,0x11,0x00,0x04, +0x22,0x30,0x82,0x5D,0x46,0x11,0x00,0x04,0x22,0x10,0x82,0x82,0x44,0x70,0x00,0x4C, +0x88,0x23,0x90,0x21,0x46,0x31,0x00,0x04,0x12,0x11,0x82,0x5C,0x80,0x66,0x80,0x26, +0x42,0x32,0x1C,0x73,0x42,0x12,0x9C,0x73,0x23,0x01,0x91,0xBB,0x22,0x10,0x91,0xBA, +0x88,0x30,0x90,0x21,0x12,0x11,0x91,0xBA,0x40,0x33,0x08,0x20,0x40,0x13,0x00,0x20, +0x22,0x70,0x91,0xBA,0x22,0x11,0x91,0xE0,0x88,0x27,0x90,0x21,0x12,0x11,0x91,0xBA, +0xFA,0x76,0xFF,0x1C,0x98,0x62,0x42,0x22,0x8C,0x73,0x88,0x04,0x40,0x03,0x00,0x20, +0x40,0x13,0x04,0x20,0x40,0x63,0x08,0x20,0x22,0x40,0x11,0xBA,0x22,0x03,0x11,0xBA, +0x88,0x04,0x90,0x01,0x12,0x00,0x91,0xBA,0xFC,0xE0,0xEB,0x79,0x58,0x10,0x80,0x28, +0x38,0x00,0x81,0x01,0xDD,0x9E,0xFC,0x40,0x82,0x40,0x2E,0x47,0xFE,0x59,0x3D,0x0C, +0x00,0x36,0x3D,0x1C,0x00,0x37,0x84,0x00,0x80,0xE0,0x80,0x40,0x86,0x6C,0x44,0x90, +0xFF,0xFF,0x85,0x41,0x2E,0x30,0x00,0xE3,0xE2,0x43,0xE8,0x2D,0x80,0x72,0x42,0x31, +0x4C,0x73,0xB4,0xA3,0xA0,0xD9,0x4C,0x54,0x80,0x24,0x40,0x62,0x08,0x0E,0x97,0xB4, +0xC6,0x15,0x46,0x61,0x00,0x07,0x00,0x63,0x03,0x99,0x40,0xF8,0x18,0x01,0xE2,0xAF, +0xE8,0x17,0xE2,0xC5,0xE8,0x15,0x46,0x61,0x00,0x07,0x00,0x63,0x03,0x9A,0x40,0xF8, +0x98,0x01,0xE2,0x6F,0xE8,0x0D,0xE2,0xC3,0xE8,0x0B,0xCF,0x03,0xA9,0x49,0xB6,0x61, +0x40,0x35,0x08,0x0C,0x40,0x42,0x0C,0x12,0x9C,0xC1,0x96,0x18,0x84,0xE1,0x8C,0x41, +0x96,0x90,0xD5,0xD1,0x3E,0x47,0xFE,0x59,0xFC,0xC0,0xFC,0x00,0x84,0x1F,0x3E,0x07, +0xFE,0x59,0x84,0x00,0x3C,0x0B,0xFF,0x9D,0x3C,0x0B,0xFF,0x9C,0x84,0x3F,0x3C,0x1B, +0xFF,0x9B,0x3C,0x1B,0xFF,0x9A,0x3E,0x2F,0xFF,0x30,0xAC,0x10,0xAC,0x11,0x3E,0x2F, +0xFF,0x2C,0xAC,0x10,0xAC,0x11,0x3E,0x2F,0xFF,0x28,0xAC,0x50,0xAC,0x51,0x3E,0x2F, +0xFF,0x24,0xAC,0x50,0xAC,0x51,0x3E,0x07,0xFE,0xCC,0xEB,0x47,0x46,0x01,0x00,0x07, +0x58,0x00,0x03,0x80,0xA6,0x46,0xA6,0x87,0xEA,0x7C,0x3C,0x1B,0xFF,0x3D,0x00,0x10, +0x00,0x08,0x00,0x20,0x00,0x09,0xEA,0x7C,0x3C,0x1B,0xFF,0x3C,0x00,0x10,0x00,0x0A, +0x00,0x20,0x00,0x0B,0xEA,0x7C,0x3C,0x1B,0xFF,0x3B,0x00,0x10,0x00,0x0C,0x3E,0x17, +0xFE,0x75,0x00,0x10,0x00,0x0D,0x3E,0x17,0xFE,0x74,0x00,0x10,0x00,0x0E,0x3E,0x17, +0xFE,0x73,0x00,0x10,0x00,0x0F,0x3E,0x17,0xFE,0x72,0x3E,0x18,0x00,0xD8,0xA4,0x8A, +0x00,0x30,0x00,0x10,0x9B,0x13,0x3C,0x4B,0xFF,0x38,0x3C,0x3B,0xFF,0x37,0xA4,0x48, +0x00,0x30,0x00,0x11,0x9B,0x0B,0x3C,0x4B,0xFF,0x36,0x3C,0x3B,0xFF,0x35,0x00,0x30, +0x00,0x12,0x8A,0x43,0x3C,0x2B,0xFF,0x34,0x3C,0x3B,0xFF,0x33,0x00,0x20,0x00,0x13, +0x8A,0x22,0x3C,0x1B,0xFF,0x32,0x3C,0x2B,0xFF,0x31,0x00,0x10,0x00,0x14,0x00,0x20, +0x00,0x15,0xEA,0x7C,0x3C,0x1B,0xFF,0x30,0x00,0x10,0x00,0x16,0x3C,0x1B,0xFF,0x2F, +0x00,0x10,0x00,0x17,0x3C,0x1B,0xFF,0x2E,0x00,0x00,0x00,0x18,0x3C,0x0B,0xFF,0x2D, +0xFA,0x44,0x3E,0x0F,0xFE,0xB8,0x84,0x20,0xDD,0x42,0x3E,0x6F,0xFE,0xD8,0x3E,0x0F, +0xFE,0xA4,0x84,0x20,0xFA,0x44,0xDD,0x42,0x80,0x06,0x84,0x3F,0x44,0x20,0x00,0x4C, +0xDD,0x42,0x80,0x06,0x84,0x3F,0x44,0x20,0x00,0x4C,0xDD,0x42,0xEB,0x29,0x84,0x20, +0xFA,0x56,0xDD,0x42,0x46,0x01,0x00,0x01,0xEA,0xDB,0x84,0x20,0xFA,0x43,0xDD,0x42, +0x3E,0x0F,0xFE,0xD0,0x84,0x20,0x84,0x48,0xDD,0x42,0xFC,0x80,0xFC,0x00,0xEA,0x36, +0x2E,0x67,0xFD,0xDC,0x9E,0x71,0x96,0x48,0x5C,0xF0,0x80,0xFE,0xE8,0x23,0xC8,0x22, +0x40,0x03,0x40,0x08,0x40,0x00,0x19,0x00,0x88,0x06,0x40,0x00,0x1B,0x00,0x95,0xB2, +0xDD,0x4A,0x52,0x63,0x7F,0xF0,0x44,0x00,0x44,0xCC,0x40,0x00,0x1B,0x00,0xDD,0x4A, +0x84,0xCC,0x8E,0xC1,0x84,0x1F,0x97,0xB0,0xDD,0x4A,0xCE,0xFC,0x84,0x0A,0x49,0xFF, +0xD7,0x55,0x3E,0x0F,0xFD,0xDC,0x84,0x3F,0x84,0x41,0xDD,0x42,0x84,0x01,0x3E,0x07, +0xFE,0x58,0xFC,0x80,0x5A,0x08,0x08,0x14,0x5A,0x10,0x0C,0x1D,0xE6,0x2D,0xE8,0x08, +0xE6,0x25,0xE9,0x17,0xE6,0x27,0xE9,0x0F,0x5A,0x10,0x09,0x15,0xD5,0x12,0x5A,0x10, +0x2F,0x12,0x5A,0x10,0x79,0x0D,0x5A,0x10,0x1F,0x0E,0xD5,0x0B,0x5A,0x10,0xFF,0x0B, +0x5A,0x10,0x79,0x06,0x5A,0x18,0x0D,0x07,0x84,0x27,0xD5,0x04,0x84,0x29,0xD5,0x02, +0x84,0x28,0x80,0x01,0xDD,0x9E,0x2E,0x07,0xFE,0x58,0xDD,0x9E,0x84,0x00,0x3E,0x07, +0xFE,0x58,0xDD,0x9E,0xE2,0x20,0xE8,0x03,0x8A,0x01,0xD5,0x02,0x9A,0x08,0x96,0x01, +0xDD,0x9E,0xFC,0x60,0x80,0xE0,0xEA,0x65,0x80,0xC1,0xE6,0x02,0xE8,0x0A,0x84,0x20, +0x3E,0x17,0xFE,0x57,0x3E,0x17,0xFE,0x56,0x3E,0x17,0xFE,0x55,0x3E,0x17,0xFE,0x54, +0x3C,0x13,0xFF,0x98,0xE2,0x27,0xE8,0x07,0x3C,0x7B,0xFF,0x98,0x3C,0x6B,0xFF,0x99, +0x3C,0x0B,0xFF,0x6B,0xEA,0xA7,0xE2,0xE1,0xE8,0x07,0x3C,0x7B,0xFF,0x94,0x3C,0x6B, +0xFF,0x95,0x3C,0x0B,0xFF,0x69,0x3C,0x13,0xFF,0x97,0xE2,0x26,0xE8,0x07,0x3C,0x7B, +0xFF,0x96,0x3C,0x6B,0xFF,0x97,0x3C,0x0B,0xFF,0x6A,0xEA,0xA6,0xE2,0xC1,0xE8,0x07, +0x3C,0x7B,0xFF,0x92,0x3C,0x6B,0xFF,0x93,0x3C,0x0B,0xFF,0x68,0x3C,0xA3,0xFF,0x9B, +0x80,0x07,0x80,0x2A,0xDD,0x41,0x81,0x60,0x3C,0x93,0xFF,0x9A,0x80,0x06,0x80,0x29, +0xDD,0x41,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x81,0xE2,0x2B,0xE9,0x04,0xE2,0x20, +0x4E,0xF2,0x00,0x58,0xE3,0x47,0x2E,0x0F,0xFE,0x55,0xE8,0x0B,0x2E,0x37,0xFE,0x57, +0xEA,0xDE,0xEA,0xA0,0xE4,0x02,0x8C,0x21,0xEA,0xA3,0xE8,0x11,0x8C,0x01,0xD5,0x0D, +0xE2,0xEA,0xE8,0x0D,0x2E,0x37,0xFE,0x57,0xEA,0xDE,0xEA,0xA0,0x5E,0xF0,0x7F,0xFF, +0x8E,0x21,0xEA,0xA3,0xE9,0x04,0x8E,0x01,0x3E,0x07,0xFE,0x55,0xE3,0x26,0x2E,0x0F, +0xFE,0x54,0xE8,0x0C,0x2E,0x37,0xFE,0x56,0x3E,0x2F,0xFE,0xA4,0xEA,0xA0,0xE4,0x02, +0x8C,0x21,0xEA,0xA3,0xE8,0x12,0x8C,0x01,0xD5,0x0E,0xE2,0xC9,0xE8,0x0E,0x2E,0x37, +0xFE,0x56,0x3E,0x2F,0xFE,0xA4,0xEA,0xA0,0x5E,0xF0,0x7F,0xFF,0x8E,0x21,0xEA,0xA3, +0xE9,0x04,0x8E,0x01,0x3E,0x07,0xFE,0x54,0x2E,0x0F,0xFE,0x55,0xC8,0x0C,0x4C,0x75, +0x00,0x0B,0x2E,0x07,0xFE,0x57,0x8C,0x01,0x96,0x00,0xE6,0x0A,0xE9,0x02,0x84,0x09, +0x3E,0x07,0xFE,0x57,0x2E,0x0F,0xFE,0x54,0xC8,0x0C,0x4C,0x64,0x80,0x0B,0x2E,0x07, +0xFE,0x56,0x8C,0x01,0x96,0x00,0xE6,0x0A,0xE9,0x02,0x84,0x09,0x3E,0x07,0xFE,0x56, +0xFC,0xE0,0xFC,0x61,0x83,0x80,0xEA,0x65,0x81,0x41,0xE6,0x02,0x46,0xD1,0x00,0x01, +0x58,0xD6,0x81,0x90,0x46,0xC1,0x00,0x01,0x58,0xC6,0x00,0x60,0xE8,0x13,0x84,0x40, +0x3E,0x1F,0xFE,0x40,0x80,0x02,0x82,0x42,0xD5,0x11,0x38,0x02,0x0D,0x09,0x38,0x03, +0x8D,0x09,0x80,0x66,0x5A,0x68,0x08,0x10,0x8C,0x50,0x19,0x20,0x80,0x01,0x5A,0x29, +0x30,0x06,0x3E,0x8F,0xFE,0x40,0x85,0x20,0xD5,0x0E,0x84,0x60,0x40,0x46,0x88,0x00, +0x40,0x76,0x08,0x00,0x9D,0x99,0xCB,0xEA,0x39,0xC6,0x88,0x09,0x38,0xA6,0x08,0x09, +0x80,0x66,0xD5,0xF9,0x46,0x01,0x00,0x01,0xEA,0xDB,0x38,0x60,0x24,0x00,0x40,0xB4, +0x8C,0x08,0x40,0x05,0x98,0x00,0x38,0x16,0x01,0x01,0x38,0x76,0x81,0x01,0xF1,0x81, +0x3E,0x1F,0xFB,0x1C,0x38,0xE0,0x80,0x00,0x80,0x1C,0x80,0x27,0xDD,0x41,0xE6,0x06, +0xE9,0x0B,0x5A,0xE8,0x01,0x05,0x40,0x7E,0x1C,0x06,0xD5,0x07,0x5A,0xE8,0x03,0x05, +0x40,0x73,0xF0,0x06,0xD5,0x02,0xEA,0xE7,0x80,0x0A,0xF1,0x01,0xDD,0x41,0xE6,0x06, +0xE9,0x0D,0x5A,0xE8,0x02,0x06,0xF0,0x01,0x40,0x75,0x00,0x06,0xD5,0x07,0x5A,0xE8, +0x04,0x06,0xF0,0x01,0xE2,0x0A,0xE9,0x04,0xD5,0x18,0x5A,0x78,0x01,0x16,0x00,0x04, +0x00,0x00,0x8C,0x01,0x96,0x00,0x5A,0x08,0x02,0x18,0x8C,0xC1,0x84,0x00,0x96,0xB0, +0x40,0x65,0x88,0x00,0x10,0x04,0x00,0x00,0x46,0x01,0x00,0x01,0xEA,0xDB,0x38,0x20, +0x24,0x08,0xF8,0x04,0xD5,0x0B,0xCF,0x0A,0x88,0xCB,0x39,0xC6,0x99,0x09,0x38,0xA6, +0x19,0x09,0x83,0xFF,0x84,0x00,0x10,0x04,0x00,0x00,0x8D,0x21,0x8D,0x01,0x5A,0x98, +0x13,0xAB,0xFC,0xE1,0xFC,0x65,0x80,0xC0,0x3C,0xD3,0xFF,0x9B,0x3C,0xA3,0xFF,0x9A, +0xEA,0x65,0x80,0xE1,0xE6,0x02,0xE8,0x04,0x84,0x1F,0x3E,0x07,0xFE,0x3F,0x40,0xF6, +0x98,0x06,0xE9,0x04,0x44,0x90,0x00,0x40,0xD5,0x03,0x44,0x90,0x00,0x60,0x80,0x06, +0x80,0x2D,0xDD,0x41,0xE3,0x47,0x81,0x60,0x85,0x00,0xE8,0x02,0xFB,0x10,0x80,0x07, +0x80,0x2A,0xDD,0x41,0x80,0x80,0x46,0x01,0x00,0x07,0x00,0x00,0x03,0x80,0xB6,0x1F, +0x02,0x5F,0x80,0x00,0xE2,0xAB,0xE9,0x03,0xE2,0xA4,0xE8,0x09,0x2E,0x07,0xFE,0x3F, +0x5A,0x08,0xFF,0x06,0xE2,0x8B,0xE8,0x1D,0x3E,0x97,0xFE,0x3F,0xE2,0xCD,0x14,0xFF, +0x80,0x02,0x40,0x16,0x98,0x06,0xF1,0x83,0xE3,0x47,0x2E,0x07,0xFE,0x3F,0x14,0xFF, +0x80,0x04,0xE2,0xEA,0xF0,0x81,0x3E,0xCF,0xFE,0x7C,0x3F,0xCF,0xFE,0xD8,0x80,0x04, +0x82,0xAB,0x85,0xC0,0x86,0x8C,0x14,0xFF,0x80,0x05,0x44,0xD0,0x00,0xFF,0xD5,0x06, +0xE3,0x64,0xE8,0xE5,0x3E,0x87,0xFE,0x3F,0xD5,0xE2,0x02,0xA6,0x00,0x00,0x5A,0xA0, +0xFF,0x2A,0x02,0x1E,0x00,0x00,0xE2,0x26,0xE9,0x04,0x44,0x90,0x00,0x40,0xD5,0x03, +0x44,0x90,0x00,0x60,0x80,0x06,0x15,0x4F,0x80,0x08,0xF5,0x87,0xF4,0x86,0xDD,0x41, +0x02,0x1E,0x00,0x01,0x82,0xA0,0xE2,0x27,0xF4,0x06,0xF5,0x07,0x05,0x4F,0x80,0x08, +0x85,0x00,0xE8,0x02,0xFB,0x10,0x80,0x07,0x15,0x4F,0x80,0x09,0xF5,0x88,0xF4,0x87, +0x15,0x5F,0x80,0x06,0xDD,0x41,0x05,0x4F,0x80,0x09,0xF5,0x08,0xF4,0x07,0x05,0x5F, +0x80,0x06,0x80,0x2A,0x42,0x17,0x50,0x73,0xEA,0x80,0x38,0x11,0x04,0x00,0x40,0xF0, +0x9C,0x09,0x5A,0xF8,0x01,0x19,0x5A,0xA0,0xFF,0x17,0x55,0x60,0x80,0x60,0x96,0x67, +0xC1,0x05,0xB4,0x5F,0xFE,0x54,0x96,0x48,0xD5,0x02,0x80,0x2F,0x4D,0x64,0xC0,0x04, +0xE2,0x35,0xD5,0x04,0x4D,0x64,0x40,0x08,0xE2,0x20,0xE8,0x05,0x50,0x25,0x00,0x01, +0x12,0x26,0x00,0x00,0x02,0x16,0x00,0x00,0xC1,0x1E,0x5A,0x10,0xFF,0x1D,0xEA,0x80, +0x42,0x27,0x50,0x73,0xF8,0x33,0xC9,0x03,0xF1,0x05,0xD5,0x04,0x5A,0x18,0x20,0x06, +0xF1,0x04,0xC1,0x11,0xCC,0x0C,0xD5,0x0F,0x5A,0x18,0x60,0x04,0xF1,0x03,0xD5,0x04, +0x5A,0x18,0x40,0x0A,0xF1,0x02,0xC1,0x07,0x4E,0xB2,0x00,0x06,0x12,0x6E,0x00,0x00, +0x12,0x7E,0x00,0x01,0x42,0x17,0x50,0x24,0xEA,0x80,0x38,0x11,0x04,0x00,0xF2,0x01, +0x54,0x10,0x80,0x60,0xFE,0x55,0x5A,0x18,0x20,0x04,0x12,0xD6,0x00,0x00,0x0A,0x16, +0x00,0x01,0x42,0xA7,0x50,0x24,0xEA,0x80,0x40,0x35,0x04,0x00,0x38,0x31,0x0C,0x00, +0x92,0x67,0xCB,0x18,0x5A,0x10,0xFF,0x17,0x88,0x4A,0x88,0x22,0x00,0x10,0xFF,0xFF, +0x54,0x10,0x80,0x60,0x83,0xFF,0x40,0x24,0x04,0x03,0x5A,0x28,0x20,0x04,0xE2,0xA0, +0xE9,0x07,0x40,0x14,0x84,0x03,0x5A,0x18,0x20,0x06,0xE2,0xB5,0xE8,0x03,0x12,0xD6, +0x7F,0xFF,0x50,0xE7,0x00,0x01,0x51,0xCE,0x00,0x04,0x5A,0xE0,0x13,0x04,0x48,0xFF, +0xFF,0x5E,0xFC,0xE5,0xFC,0x60,0x80,0xA0,0x46,0x01,0x00,0x07,0x02,0x60,0x01,0xDC, +0x46,0x01,0x00,0x07,0x02,0x70,0x01,0xDD,0xE6,0x42,0x81,0x41,0x81,0x22,0x97,0xB1, +0x97,0xF9,0xE9,0x17,0x84,0x05,0x44,0x20,0x27,0x10,0xDD,0x5B,0x40,0x03,0x08,0x57, +0x44,0x10,0x03,0xE8,0x96,0x91,0x40,0x21,0x04,0x57,0x44,0x0F,0xFC,0x18,0x42,0x61, +0x00,0x73,0x8C,0x41,0x84,0x0A,0x40,0x21,0x00,0x16,0x42,0x60,0x04,0x73,0x97,0xB1, +0x2E,0x07,0xFE,0x3E,0xC0,0x20,0x5A,0x00,0x05,0x1F,0x5A,0x00,0x04,0x07,0x3C,0x03, +0xFF,0x1E,0x8C,0x01,0x3C,0x0B,0xFF,0x1E,0xEB,0x23,0x3C,0x13,0xFF,0x37,0xE2,0x20, +0x4E,0xF2,0x00,0xE1,0x3C,0x13,0xFF,0x38,0xE2,0x01,0x4E,0xF2,0x00,0xDC,0xEB,0x22, +0x3C,0x13,0xFF,0x35,0xE2,0x20,0x4E,0xF2,0x00,0xD6,0x3C,0x13,0xFF,0x36,0xE2,0x01, +0x4E,0xF2,0x00,0xD1,0x2E,0x27,0xFE,0x3E,0xCA,0x15,0x5A,0x90,0x01,0x03,0xF8,0x4E, +0xEA,0x28,0x4C,0x50,0x00,0xAE,0x3E,0x97,0xFE,0x3E,0x3C,0x5B,0xFF,0x1D,0x3C,0xAB, +0xFF,0x1C,0x3C,0x2B,0xFF,0x1E,0x3C,0x2B,0xFF,0x1B,0x84,0x1F,0x3E,0x07,0xFC,0xB0, +0xF8,0x3D,0x54,0x01,0x00,0xFD,0x5A,0x00,0x01,0x04,0x48,0x00,0x00,0x55,0x5A,0x98, +0x01,0x38,0x80,0x25,0xEB,0x23,0xDD,0x41,0x2E,0xB7,0xFE,0x72,0xE3,0x60,0xE9,0x06, +0xEB,0x22,0x80,0x2A,0xDD,0x41,0xE3,0x60,0xE8,0x13,0x84,0x05,0xDD,0x5B,0xDD,0x5A, +0x40,0x13,0x00,0x17,0x84,0x2A,0x96,0x01,0x40,0x00,0x04,0x17,0x84,0x56,0x42,0x60, +0x08,0x73,0x8C,0x01,0x40,0x00,0x04,0x56,0x42,0x60,0x88,0x73,0xD5,0x16,0x3C,0x13, +0xFF,0x1E,0x3C,0x23,0xFF,0x1B,0x2E,0x07,0xFE,0x75,0x88,0x02,0xE0,0x01,0x4E,0xF2, +0x00,0x70,0x84,0x05,0xDD,0x5B,0x84,0x0A,0x40,0x23,0x00,0x37,0x96,0x49,0x8A,0xC1, +0x8C,0x21,0x40,0x00,0x80,0x36,0x88,0xC1,0x97,0xB1,0x48,0x00,0x00,0x62,0x4E,0x93, +0x00,0x60,0x3C,0x03,0xFF,0x1E,0x3C,0x33,0xFF,0x1B,0xE2,0x60,0xE8,0x11,0x2E,0x17, +0xFE,0x75,0x88,0x23,0xE0,0x20,0xE9,0x0C,0x84,0x22,0x5A,0x20,0x01,0x05,0x5A,0x28, +0x03,0x05,0x84,0x24,0x3E,0x17,0xFE,0x3E,0x3C,0x0B,0xFF,0x1B,0xD5,0x49,0x84,0x05, +0xDD,0x5B,0xD5,0x46,0x5A,0x28,0x02,0x45,0x3C,0xB3,0xFF,0x1E,0x3C,0x83,0xFF,0x1B, +0xE3,0x68,0xE9,0x32,0x2E,0x07,0xFE,0x74,0x88,0x08,0xE1,0x60,0xE8,0x2D,0x5A,0x98, +0x01,0x38,0xEA,0x28,0xD0,0x35,0x80,0x25,0xEB,0x23,0xDD,0x41,0x2E,0xC7,0xFE,0x72, +0xE2,0x0C,0xE8,0x10,0xEB,0x22,0x80,0x2A,0xDD,0x41,0xE2,0x0C,0xE8,0x0B,0x2E,0x07, +0xFE,0x73,0x88,0x08,0xE1,0x60,0xE9,0x06,0x84,0x03,0xDD,0x5B,0x3C,0xBB,0xFF,0x1B, +0xD5,0x1F,0x84,0x05,0xDD,0x5B,0xDD,0x5A,0x40,0x13,0x80,0x17,0x84,0x2A,0x96,0x01, +0x40,0x00,0x04,0x17,0x84,0x56,0x42,0x70,0x08,0x73,0x8C,0x01,0x40,0x00,0x04,0x56, +0x42,0x70,0x88,0x73,0xD5,0x0C,0x84,0x05,0xDD,0x5B,0x84,0x0A,0x40,0x23,0x80,0x37, +0x96,0x49,0x8A,0xE1,0x8C,0x21,0x40,0x00,0x80,0x36,0x88,0xE1,0x97,0xF9,0x2E,0x07, +0xFE,0x3E,0x5A,0x08,0x04,0x09,0x44,0x0F,0xFF,0x80,0x3E,0x07,0xFC,0xB0,0x84,0x00, +0xDD,0x5B,0xD5,0x07,0x5A,0x08,0x05,0x06,0x4E,0x93,0x00,0x04,0x3E,0x97,0xFE,0x3E, +0x46,0x01,0x00,0x07,0x12,0x60,0x01,0xDC,0x46,0x01,0x00,0x07,0x12,0x70,0x01,0xDD, +0xFC,0xE0,0x84,0x05,0x44,0x30,0x03,0xE8,0xDD,0x5B,0x40,0x03,0x0C,0x77,0xEA,0x2A, +0x96,0xD9,0x40,0x31,0x84,0x77,0x44,0x0F,0xFF,0x9C,0x42,0x61,0x80,0x73,0x8C,0x61, +0x84,0x0A,0x40,0x31,0x80,0x16,0x42,0x60,0x04,0x73,0x97,0xB1,0x48,0xFF,0xFF,0x1C, +0xFC,0x00,0x84,0x00,0x3E,0x6F,0xFE,0xB8,0x3E,0x5F,0xFE,0xA4,0x80,0x20,0x80,0x40, +0x2A,0x43,0x00,0x01,0xC4,0x0E,0x22,0x33,0x00,0x00,0xC3,0x0B,0x42,0x42,0x00,0x03, +0xE4,0x85,0xE9,0x07,0x42,0x31,0x80,0x03,0xE4,0x65,0xE9,0x03,0x8C,0x21,0x96,0x48, +0x2A,0x42,0x80,0x01,0xC4,0x0E,0x22,0x32,0x80,0x00,0xC3,0x0B,0x42,0x42,0x00,0x03, +0xE4,0x85,0xE9,0x07,0x42,0x31,0x80,0x03,0xE4,0x65,0xE9,0x03,0x8C,0x01,0x96,0x00, +0x8C,0x41,0x96,0x90,0x5A,0x28,0x09,0xDE,0x8E,0x21,0xE6,0x22,0xE8,0x5C,0x8E,0x01, +0xE6,0x02,0xE8,0x59,0xEA,0x3A,0x3C,0x63,0xFF,0x9B,0xE2,0xC0,0xE8,0x03,0x9A,0x86, +0xD5,0x02,0x9A,0xB0,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x82,0x46,0x31,0x00,0x07, +0x00,0x31,0x83,0x83,0x40,0xF1,0x85,0x00,0xE0,0x4F,0xE8,0x45,0x3C,0x23,0xFF,0x9C, +0xEA,0xAE,0xE2,0x22,0xE8,0x03,0x9A,0x51,0xD5,0x02,0x8A,0x22,0x46,0x21,0x00,0x07, +0x00,0x21,0x03,0x84,0x46,0x31,0x00,0x07,0x00,0x31,0x83,0x85,0x40,0xF1,0x89,0x00, +0xE0,0x2F,0xE8,0x31,0xEA,0xA7,0xDD,0x41,0x5C,0xF0,0x00,0x64,0xE8,0x08,0x80,0x06, +0x3C,0x13,0xFF,0x98,0xDD,0x41,0x5C,0xF0,0x00,0x64,0xE9,0x25,0x3C,0x43,0xFF,0x6B, +0x3C,0x33,0xFF,0x68,0x84,0x00,0x3E,0x2F,0xFE,0xD0,0x80,0x20,0x40,0x31,0x90,0x06, +0x5A,0x10,0x03,0x07,0xA5,0x10,0xA5,0x51,0xE2,0xA4,0xE8,0x05,0xD5,0x02,0xC3,0x03, +0x8C,0x01,0xD5,0x02,0x8E,0x01,0x8C,0x21,0x96,0x48,0x96,0x02,0x8C,0x42,0x5A,0x18, +0x04,0xF1,0x4E,0x07,0x00,0x04,0x84,0x01,0xD5,0x02,0x84,0x00,0x3E,0x07,0xFE,0xCC, +0x84,0x08,0xD5,0x02,0xEA,0x92,0xFC,0x80,0xFC,0x60,0x80,0xE0,0x81,0x21,0x3C,0xA3, +0xFF,0x3B,0x5A,0x10,0x0B,0x04,0x5A,0x18,0x07,0x1F,0x3C,0x07,0xFF,0x5C,0xE4,0x05, +0xE9,0x15,0x3C,0xF7,0xFF,0x5D,0x5E,0xF7,0xFF,0xFC,0xE8,0x10,0x3C,0x07,0xFF,0x5E, +0xE4,0x05,0xE9,0x0C,0x3C,0x67,0xFF,0x5F,0xCE,0x09,0x3C,0x07,0xFF,0x60,0xC8,0x07, +0x3C,0x67,0xFF,0x61,0x5C,0x63,0x00,0x01,0xD5,0x02,0x84,0xC0,0xEA,0x3A,0xEA,0xE4, +0xE2,0x20,0xF8,0x71,0xEB,0x79,0x58,0x10,0x81,0x90,0x94,0x3C,0x98,0x81,0x80,0x81, +0x5A,0x98,0x0D,0x12,0x3C,0x13,0xFF,0x9D,0x3C,0x03,0xFF,0x9B,0xE2,0x20,0x4E,0xF2, +0x02,0x3F,0xA4,0x50,0xA4,0x11,0xE2,0x20,0x4E,0xF2,0x02,0x3A,0xA4,0x52,0xA4,0x13, +0x48,0x00,0x00,0xE5,0xEB,0x79,0x58,0x10,0x80,0x60,0x98,0xC1,0x5A,0x90,0x06,0x06, +0x5A,0x90,0x09,0x04,0x48,0x00,0x00,0x52,0x38,0xA0,0x80,0x01,0xA4,0x19,0xE2,0x0A, +0xE9,0x1C,0x3C,0x83,0xFF,0x9A,0x3C,0x63,0xFF,0x97,0x80,0x08,0x80,0x26,0xDD,0x41, +0x81,0x80,0x3C,0xB3,0xFF,0x93,0x80,0x08,0x80,0x2B,0xDD,0x41,0xE2,0x0C,0xE9,0x0D, +0x3C,0x83,0xFF,0x9C,0x80,0x26,0x80,0x08,0xDD,0x41,0x80,0xC0,0x80,0x2B,0x80,0x08, +0xDD,0x41,0x40,0x63,0x00,0x06,0xD5,0x02,0x84,0xC1,0x5A,0x98,0x06,0x10,0xEB,0x2A, +0xE3,0x40,0xE8,0x04,0x40,0x05,0x00,0x11,0xD5,0x02,0x96,0x03,0x96,0x01,0xEA,0xA6, +0xDD,0x41,0xE6,0x1A,0x4E,0xF3,0x01,0xFA,0xF8,0x9A,0x5A,0x90,0x09,0x03,0xF9,0xAB, +0x3C,0xB3,0xFF,0x98,0x3C,0x93,0xFF,0x9D,0x80,0x0B,0x80,0x29,0xDD,0x41,0x81,0x80, +0x3C,0xA3,0xFF,0x94,0x80,0x29,0x80,0x0A,0xDD,0x41,0xE2,0x0C,0x4E,0xF3,0x01,0xE8, +0x3C,0x93,0xFF,0x9B,0x80,0x0B,0x80,0x29,0xDD,0x41,0x81,0x60,0x80,0x29,0x80,0x0A, +0xDD,0x41,0xE3,0x60,0x48,0x00,0x00,0xFD,0x5A,0x98,0x79,0x3A,0x3C,0xA3,0xFF,0x98, +0x3C,0x63,0xFF,0x9D,0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x60,0x3C,0x93,0xFF,0x94, +0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0B,0x4E,0xF3,0x01,0xCA,0x3C,0x63,0xFF,0x9B, +0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x40,0x80,0x26,0x80,0x09,0xDD,0x41,0xE3,0x40, +0x4E,0xF3,0x01,0xBE,0x3C,0x93,0xFF,0x93,0x3C,0x63,0xFF,0x9C,0x80,0x09,0x80,0x26, +0xDD,0x41,0x81,0x60,0x3C,0xA3,0xFF,0x97,0x80,0x26,0x80,0x0A,0xDD,0x41,0xE2,0x0B, +0x4E,0xF3,0x01,0xAE,0x3C,0x63,0xFF,0x9A,0x80,0x0A,0x80,0x26,0xDD,0x41,0x81,0x40, +0x80,0x26,0x80,0x09,0xDD,0x41,0xE2,0x0A,0x48,0x00,0x01,0x9E,0x5A,0x98,0x3D,0x1F, +0x84,0x40,0x80,0x22,0x80,0x02,0x3E,0x4F,0xFE,0xA4,0x38,0x32,0x09,0x11,0x4E,0x37, +0x00,0x05,0x88,0x03,0x96,0x03,0xD5,0x03,0x88,0x23,0x96,0x4B,0x8C,0x41,0x5A,0x28, +0x0A,0xF6,0x42,0xF0,0x00,0x03,0x42,0x20,0x80,0x03,0xE0,0x4F,0xE8,0x04,0x4E,0x13, +0x01,0x87,0xF8,0xE4,0x4E,0x03,0x01,0x84,0xF8,0xE1,0x5A,0x98,0x05,0x24,0xEA,0xDE, +0x84,0x29,0x84,0x00,0x2A,0x41,0x00,0x01,0xC4,0x15,0x22,0x31,0x00,0x00,0xC3,0x12, +0x42,0x52,0x00,0x03,0xE4,0xA5,0xE9,0x0E,0x42,0x51,0x80,0x03,0xE4,0xA5,0xE9,0x0A, +0xC8,0x06,0x4E,0x44,0x00,0x08,0x40,0x00,0x0C,0x07,0xD5,0x04,0x5A,0x08,0x01,0x03, +0x84,0x05,0x8E,0x21,0x96,0x48,0xC9,0xE7,0x5A,0x00,0x01,0x04,0x48,0x00,0x01,0x60, +0xF8,0xBD,0x5A,0x98,0x0E,0x0E,0xA4,0x50,0xEA,0x3A,0xE2,0x01,0x4E,0xF3,0x01,0x58, +0xA4,0x12,0xE2,0x20,0x4E,0xF2,0x01,0x54,0xA4,0x51,0xE2,0x20,0xF8,0x49,0x5A,0x98, +0x1F,0x21,0xA5,0x51,0xA5,0x12,0xE2,0x85,0x4E,0xF2,0x01,0x4A,0xA5,0x13,0x3C,0x63, +0xFF,0x9D,0xE2,0xC4,0x4E,0xF2,0x01,0x44,0xA5,0x1C,0xEA,0xE2,0xE2,0x04,0x4E,0xF2, +0x01,0x3F,0xA4,0x19,0xE2,0x04,0x4E,0xF2,0x01,0x3B,0xA4,0x1A,0xE2,0x04,0x4E,0xF2, +0x01,0x37,0xA4,0x1B,0xE2,0x04,0x4E,0xF2,0x01,0x33,0xA4,0x15,0xE2,0x05,0xF8,0x28, +0x5A,0x98,0x2F,0x29,0x3C,0x53,0xFF,0x9D,0x38,0x42,0x00,0x01,0xE2,0x85,0x4E,0xF2, +0x01,0x27,0x3C,0x43,0xFF,0x9C,0xEA,0xE2,0xE2,0x80,0x4E,0xF2,0x01,0x21,0xA5,0x59, +0xE2,0x05,0x4E,0xF2,0x01,0x1D,0xA4,0x12,0xA4,0x51,0xE2,0x01,0x4E,0xF2,0x01,0x18, +0xA4,0x5A,0xE2,0x25,0x4E,0xF2,0x01,0x14,0x3C,0x23,0xFF,0x9B,0xE2,0x02,0x4E,0xF2, +0x01,0x0F,0x3C,0x03,0xFF,0x9A,0xE2,0x01,0x4E,0xF2,0x01,0x0A,0xE2,0x80,0x48,0x00, +0x00,0x64,0x5A,0x98,0x0C,0x29,0xEA,0xE2,0xA5,0x19,0x02,0xC1,0x80,0x02,0xE2,0x80, +0x3C,0xA3,0xFF,0x9D,0x3C,0x83,0xFF,0x9B,0xE8,0x07,0xE2,0x8C,0xE8,0x05,0xE3,0x48, +0x56,0x67,0x80,0x01,0xD5,0x02,0x84,0xC1,0xA4,0x52,0x80,0x0A,0xDD,0x41,0x81,0x20, +0x3C,0xB3,0xFF,0x9C,0x80,0x2C,0x80,0x0B,0xDD,0x41,0x89,0x20,0x80,0x28,0x80,0x0A, +0xDD,0x41,0x81,0x40,0xEA,0xAE,0x80,0x0B,0xDD,0x41,0x88,0x0A,0xE0,0x09,0x4E,0xF3, +0x00,0xDF,0xF8,0x91,0x5A,0x90,0x0A,0x04,0x5A,0x98,0x1D,0x1C,0x84,0x40,0x80,0x22, +0x80,0x02,0x3E,0x4F,0xFE,0xB8,0x38,0x32,0x09,0x11,0x4E,0x37,0x00,0x05,0x88,0x03, +0x96,0x03,0xD5,0x03,0x88,0x23,0x96,0x4B,0x8C,0x41,0x5A,0x28,0x0A,0xF6,0x42,0x00, +0x00,0x03,0xEB,0x17,0xE0,0x20,0xE8,0x03,0xE4,0x24,0xD5,0x1E,0xE0,0x01,0xD5,0x19, +0x5A,0x98,0x2D,0x1F,0x84,0x40,0x80,0x02,0x80,0x22,0x3E,0x3F,0xFE,0xA4,0x38,0xF1, +0x89,0x11,0x4E,0xF7,0x00,0x05,0x88,0x2F,0x96,0x4B,0xD5,0x03,0x88,0x0F,0x96,0x03, +0x8C,0x41,0x5A,0x28,0x0A,0xF6,0x42,0x00,0x00,0x03,0x42,0xF0,0x80,0x03,0xE0,0x0F, +0x4E,0xF2,0x00,0xAB,0xE4,0x04,0x4E,0xF2,0x00,0xA3,0x48,0x00,0x00,0xA6,0x8F,0x21, +0xE7,0x24,0x4E,0xF2,0x00,0xA2,0x84,0x00,0x80,0xC0,0x81,0x20,0x81,0x60,0x81,0x00, +0x3E,0x4F,0xFE,0xB8,0x3E,0x5F,0xFE,0xA4,0x38,0x32,0x01,0x11,0x94,0x41,0xE4,0x65, +0xE9,0x05,0x88,0x6B,0x40,0xB1,0x80,0x11,0xD5,0x07,0x5E,0xF1,0xFF,0xFC,0xE8,0x04, +0x88,0x69,0x40,0x91,0x80,0x11,0x38,0x12,0x84,0x11,0xE4,0x25,0xE9,0x06,0x40,0x20, +0xA0,0x00,0x40,0x81,0x00,0x11,0xD5,0x06,0x5E,0xF0,0xFF,0xFC,0xE8,0x03,0x88,0xC1, +0x97,0xB3,0x8C,0x01,0x5A,0x08,0x0A,0xE2,0xEB,0x29,0x38,0x10,0x1D,0x01,0x84,0x4C, +0x3E,0x0F,0xFB,0xB4,0x42,0x03,0x88,0x73,0x88,0x01,0x00,0x00,0x7F,0xFF,0x54,0x00, +0x00,0x60,0xC8,0x1B,0xEA,0xAE,0xEB,0x2A,0xE2,0x20,0x4E,0xF2,0x00,0x61,0xDD,0x41, +0x3C,0x13,0xFF,0x3C,0xE2,0x20,0x4E,0xF2,0x00,0x5B,0x3C,0x03,0xFF,0x98,0xEA,0xA7, +0xDD,0x41,0xE2,0x0A,0x4E,0xF2,0x00,0x54,0x4E,0x83,0x00,0x52,0x8C,0xC3,0x97,0xB1, +0x5C,0x63,0x00,0x07,0x48,0x00,0x00,0x4A,0x5A,0x08,0x20,0x18,0xEB,0x2A,0xEA,0xAE, +0xE2,0x01,0x4E,0xF2,0x00,0x45,0xDD,0x41,0x3C,0x13,0xFF,0x3C,0xE2,0x20,0xE8,0x3F, +0x3C,0x03,0xFF,0x98,0xEA,0xA7,0xDD,0x41,0xE2,0x0A,0xE8,0x39,0xE5,0x04,0xE9,0x37, +0x84,0x20,0x40,0x60,0x98,0x06,0xD5,0x31,0x5A,0x08,0x60,0x17,0xEA,0xE4,0xEA,0x3A, +0xE2,0x01,0xE8,0x2D,0xDD,0x41,0x3C,0x13,0xFF,0x3D,0xE2,0x20,0xE8,0x28,0x3C,0x03, +0xFF,0x97,0xEA,0xA6,0xDD,0x41,0xE2,0x0A,0xE8,0x22,0xE5,0x64,0xE9,0x20,0x84,0x20, +0x40,0x60,0xA4,0x06,0xD5,0x1A,0x5A,0x08,0x40,0x20,0xEA,0x3A,0xEA,0xE4,0xE2,0x20, +0xE8,0x16,0xDD,0x41,0x3C,0x13,0xFF,0x3D,0xE2,0x20,0xE8,0x11,0x3C,0x03,0xFF,0x97, +0xEA,0xA6,0xDD,0x41,0xE2,0x0A,0xE8,0x0B,0x4E,0xB3,0x00,0x0A,0x50,0x64,0x80,0x03, +0x97,0xB1,0xE6,0xC7,0xE9,0x04,0xD5,0x08,0x5A,0x68,0x01,0x07,0x44,0x10,0x00,0xFF, +0xEB,0x29,0x38,0x10,0x1D,0x09,0xFC,0xE0,0xFC,0x64,0x84,0x20,0xB0,0x02,0xFA,0x48, +0xDD,0x42,0x84,0x00,0x3E,0x4F,0xFE,0x7C,0x3E,0x3F,0xFB,0xB4,0x84,0xAC,0x38,0x12, +0x01,0x01,0x3E,0xDF,0xFE,0x7C,0x5A,0x10,0xFF,0x13,0x42,0x20,0x14,0x24,0x99,0x91, +0x38,0x61,0x98,0x10,0x4E,0x65,0x00,0x0C,0x88,0x43,0x88,0x22,0xA6,0x89,0xB0,0x42, +0x38,0x10,0x88,0x00,0xB1,0x82,0x8C,0x21,0x38,0x13,0x08,0x08,0x8C,0x01,0x5A,0x08, +0x13,0xE8,0x84,0x00,0xB0,0x42,0x38,0x10,0x80,0x00,0x97,0x00,0xC1,0x0A,0x84,0xC0, +0x81,0x26,0xEA,0xE7,0x3F,0xCF,0xFE,0x7C,0x3E,0xBF,0xFB,0xB4,0x85,0xCC,0xD5,0x12, +0x8C,0x01,0x5A,0x08,0x18,0xF1,0xEA,0x92,0xD5,0x35,0x42,0xC3,0x38,0x24,0x40,0x06, +0x08,0x00,0x38,0x15,0x80,0x00,0x96,0x0A,0x4E,0x04,0x00,0x0D,0x8C,0xC1,0x5A,0x60, +0x13,0x23,0x38,0x26,0x99,0x01,0x54,0x83,0x00,0xFF,0x94,0xF1,0x5A,0x28,0xFF,0xEF, +0xD5,0xF6,0x40,0x05,0xB0,0x00,0x88,0x40,0xA7,0x51,0xDC,0xF1,0x80,0x08,0xF3,0x81, +0xB6,0x9F,0x49,0xFF,0xFD,0x33,0xF3,0x01,0xB4,0x9F,0x38,0x2E,0x0C,0x01,0x5A,0x20, +0xFF,0xE7,0x50,0x14,0x80,0x01,0x88,0x4C,0x54,0x90,0x80,0xFF,0x38,0x75,0x88,0x00, +0x81,0x48,0xD5,0xDD,0x5A,0x98,0x01,0xD1,0x38,0x06,0xA9,0x01,0x5A,0x00,0xFF,0xCD, +0x80,0x07,0xFC,0xE4,0xFC,0x42,0xB0,0xC2,0x97,0x81,0x97,0xC9,0x3A,0x01,0x84,0x20, +0x81,0x42,0xFD,0x03,0x49,0xFF,0xFB,0x58,0x5A,0xA8,0x01,0x3C,0x9E,0x31,0x96,0x01, +0x44,0x10,0xFF,0xFD,0xE2,0x20,0x4E,0xF3,0x00,0x50,0xEA,0x3A,0xC8,0x15,0x3C,0x93, +0xFF,0x9C,0x4E,0x93,0x00,0x12,0xF8,0x5F,0x80,0x09,0x3E,0x1F,0xFE,0xD8,0x38,0x60, +0x80,0x09,0x98,0x81,0x8C,0x04,0xAD,0xD1,0x5A,0x08,0x4C,0xFB,0x3C,0x6B,0xFF,0x9D, +0x3C,0x7B,0xFF,0x9C,0xD5,0x19,0x46,0x11,0x00,0x07,0x00,0x10,0x83,0x9B,0x46,0x21, +0x00,0x07,0xEA,0x65,0x00,0x21,0x03,0x9C,0x40,0xF1,0x05,0x00,0xE0,0x0F,0xE8,0x03, +0x8C,0x01,0xEB,0x47,0xFD,0x03,0x49,0xFF,0xF9,0x06,0xFD,0x03,0x49,0xFF,0xFA,0x2C, +0xFD,0x03,0x49,0xFF,0xF9,0xA0,0x3C,0x6B,0xFF,0x9B,0x3C,0x7B,0xFF,0x9A,0xD5,0x1C, +0x4E,0xA3,0x00,0x1F,0xEA,0x97,0xC0,0x09,0x2E,0x07,0xFC,0xB0,0x5A,0x00,0xFF,0x16, +0x84,0x3F,0x3E,0x17,0xFC,0xB0,0xD5,0x11,0xEA,0x3A,0xC0,0xF7,0x49,0xFF,0xFC,0x3A, +0xB6,0x1F,0x49,0xFF,0xFF,0x3B,0xF0,0x81,0xF1,0x01,0xB4,0x1F,0x49,0xFF,0xF8,0xB4, +0x5A,0x08,0xFF,0x04,0xD5,0xEA,0xEA,0x92,0xEA,0xE5,0x5A,0x18,0x01,0x12,0x46,0x11, +0x00,0x07,0x00,0x10,0x83,0x9B,0x46,0x21,0x00,0x07,0xEA,0x65,0x00,0x21,0x03,0x9C, +0x40,0xF1,0x05,0x00,0xE0,0x0F,0xE8,0x03,0x8C,0x01,0xEB,0x47,0xEA,0x92,0x4E,0xA3, +0x00,0x06,0xB6,0x1F,0x49,0xFF,0xF7,0xCB,0xB4,0x1F,0xFC,0xC2,0x3E,0x1F,0xFE,0x1C, +0xA6,0x08,0xFA,0x56,0xA6,0x49,0x8E,0x01,0x42,0x10,0x08,0x73,0xEB,0x65,0x58,0x00, +0x01,0x44,0x50,0x40,0x91,0xB8,0x40,0x40,0x10,0x20,0xA5,0x62,0x3E,0x28,0x03,0x3C, +0x97,0x6B,0xAD,0x50,0x9C,0xE4,0xA5,0x21,0x50,0x10,0x94,0xB0,0x97,0x23,0xAD,0x15, +0xA5,0x19,0x40,0x00,0x04,0x20,0x97,0x23,0xAD,0x16,0x02,0x41,0x80,0x26,0x3E,0x18, +0x03,0x28,0x97,0x23,0xAD,0x14,0x02,0x41,0x80,0x25,0x97,0x23,0xAD,0x12,0x02,0x41, +0x80,0x27,0x97,0x23,0xAD,0x13,0x02,0x41,0x80,0x4C,0x97,0x23,0xAD,0x11,0x02,0x41, +0x80,0x4B,0x97,0x23,0xAD,0x17,0x02,0x31,0x80,0x4D,0x96,0xDB,0x12,0x31,0x00,0x08, +0xA4,0xC2,0x9C,0x84,0x96,0xDB,0xAC,0xC8,0xA4,0x01,0x96,0x03,0xAC,0x0D,0xA4,0x11, +0x96,0x03,0xAC,0x0E,0x02,0x01,0x00,0x26,0x96,0x03,0xAC,0x0C,0x02,0x01,0x00,0x25, +0x96,0x03,0xAC,0x0A,0x02,0x01,0x00,0x27,0x96,0x03,0xAC,0x0B,0x02,0x01,0x00,0x4C, +0x96,0x03,0xAC,0x09,0x02,0x01,0x00,0x4B,0x96,0x03,0xAC,0x0F,0x02,0x01,0x00,0x4D, +0x96,0x03,0x12,0x00,0x80,0x08,0xDD,0x9E,0x46,0x21,0x00,0x01,0x58,0x21,0x0F,0xDC, +0x38,0x31,0x05,0x00,0x38,0x31,0x01,0x08,0x40,0x31,0x04,0x20,0xA6,0xD9,0x40,0x21, +0x00,0x20,0xAE,0xD1,0x46,0x21,0x00,0x01,0xEB,0x3B,0x38,0x31,0x06,0x02,0x38,0x31, +0x02,0x0A,0x84,0x4C,0x42,0x30,0x08,0x24,0xFE,0x8C,0x46,0x41,0x00,0x02,0x58,0x42, +0x00,0xB4,0x99,0x63,0x88,0x82,0x3B,0x02,0x48,0x00,0x46,0x41,0x00,0x02,0x58,0x42, +0x00,0x24,0x88,0x44,0x3B,0x02,0xC8,0x20,0x88,0x64,0x3B,0x01,0x48,0x00,0x3E,0x28, +0x01,0x84,0x3B,0x01,0xC8,0x20,0x40,0x11,0x04,0x40,0xEA,0xDD,0x3A,0x10,0x84,0x00, +0x3A,0x10,0x04,0x20,0xDD,0x9E,0x92,0x00,0x84,0x20,0x46,0x21,0x00,0x01,0xEB,0x3B, +0x38,0x11,0x02,0x0A,0x84,0x4C,0xFE,0x84,0x46,0x31,0x00,0x02,0x58,0x31,0x80,0xB4, +0x88,0x62,0xB6,0x23,0xA8,0x59,0xA8,0x5A,0x46,0x31,0x00,0x02,0x58,0x31,0x80,0x24, +0x88,0x43,0xB6,0x22,0xA8,0x51,0xA8,0x52,0x2E,0x37,0xFC,0xBD,0x3E,0x28,0x01,0x84, +0x38,0x31,0x02,0x08,0xEA,0xDD,0xAE,0x41,0xAE,0x42,0x2E,0x17,0xFC,0xCE,0xAE,0x43, +0xDD,0x9E,0x92,0x00,0x3B,0xFF,0xFC,0xBC,0x51,0xFF,0xFF,0xFC,0x49,0xFF,0xFF,0x40, +0x3C,0x00,0x01,0xA2,0x96,0x03,0x4E,0x05,0x00,0xAF,0x3C,0x20,0x01,0xA2,0x80,0xA2, +0x46,0x11,0x00,0x01,0x2E,0x07,0xFE,0x1D,0x00,0x10,0x8F,0xF3,0xE2,0x20,0xE8,0x49, +0x9A,0x41,0xE4,0x22,0x4E,0xF3,0x00,0x4A,0x2E,0x17,0xFE,0x1C,0x46,0x31,0x00,0x02, +0x04,0x31,0x80,0x2C,0x98,0x93,0x46,0x31,0x00,0x02,0x04,0x41,0x80,0x2A,0x46,0x31, +0x00,0x02,0x04,0x31,0x80,0x2B,0xF8,0x52,0x46,0x51,0x00,0x02,0x14,0x22,0x80,0x2C, +0x46,0x21,0x00,0x02,0x14,0x41,0x00,0x2A,0x46,0x21,0x00,0x02,0x14,0x31,0x00,0x2B, +0x2E,0x20,0x01,0xB1,0xE2,0x40,0xE8,0x5D,0x3E,0x00,0x01,0xB1,0x2E,0x20,0x01,0xB2, +0xE2,0x41,0xE8,0x4F,0x3E,0x10,0x01,0xB2,0xFA,0x56,0x42,0x00,0x88,0x73,0x46,0x11, +0x00,0x02,0xEB,0x19,0x50,0x00,0x14,0xB0,0x94,0x01,0x88,0x01,0x22,0x10,0x00,0x02, +0x5A,0x10,0xFE,0x50,0xEA,0x4A,0x2E,0x27,0xFE,0x1C,0xAC,0xC2,0x2E,0x17,0xFE,0x1D, +0x3E,0x27,0xFE,0x18,0xEC,0x04,0x3E,0x17,0xFE,0x19,0x3B,0xFF,0xFC,0x84,0xDD,0x9E, +0x8A,0x20,0xE4,0x22,0x4E,0xF2,0xFF,0xBA,0x46,0x31,0x00,0x01,0x2E,0x17,0xFE,0x1C, +0x00,0x31,0x8F,0xF2,0xE2,0x61,0xE8,0x53,0x9A,0xCB,0xE4,0x62,0x4E,0xF2,0xFF,0xB0, +0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x50,0x88,0x43,0x46,0x31,0x00,0x02,0x04,0x41, +0x80,0x4E,0x46,0x31,0x00,0x02,0x04,0x31,0x80,0x4F,0x42,0x42,0x80,0x73,0x42,0x32, +0x84,0x73,0x4A,0x00,0x00,0x60,0x46,0x51,0x00,0x02,0x14,0x22,0x80,0x50,0x46,0x21, +0x00,0x02,0x14,0x41,0x00,0x4E,0x46,0x21,0x00,0x02,0x14,0x31,0x00,0x4F,0xD5,0xA9, +0x2E,0x20,0x01,0xB3,0xE2,0x22,0xE8,0xB1,0x3E,0x10,0x01,0xB3,0x48,0xFF,0xFF,0xAE, +0x2E,0x20,0x01,0xB0,0xE2,0x02,0xE8,0xA3,0x3E,0x00,0x01,0xB0,0x48,0xFF,0xFF,0xA0, +0x2E,0x27,0xFC,0xEE,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x08,0x8C,0x21,0xEA,0x4A, +0xAC,0xC2,0xE2,0x41,0xEB,0x65,0x14,0x10,0x00,0x08,0xE8,0x17,0x2E,0x17,0xFE,0x1C, +0x2E,0x07,0xFE,0x1D,0x3E,0x17,0xFE,0x18,0xEC,0x04,0x3E,0x07,0xFE,0x19,0x3B,0xFF, +0xFC,0x84,0xDD,0x9E,0x84,0xA0,0x84,0x40,0x48,0xFF,0xFF,0x54,0x8A,0x61,0xE4,0x62, +0x4E,0xF2,0xFF,0x5E,0x48,0xFF,0xFF,0xAE,0x49,0xFF,0xCE,0x7F,0xC8,0xE8,0xDD,0x5E, +0xC1,0x1C,0x3C,0x00,0x01,0x94,0xEA,0x96,0x97,0x43,0xD2,0x17,0xDD,0x59,0xEA,0x84, +0xEA,0xD1,0x4E,0x00,0x00,0x56,0xE9,0x11,0x8E,0x21,0xDD,0x51,0x49,0xFF,0xFF,0x2C, +0x2E,0x07,0xFE,0x18,0x50,0x00,0x00,0x01,0x2E,0x17,0xFE,0x19,0x3E,0x07,0xFE,0x1C, +0xEA,0xAA,0xEA,0x2C,0x2E,0x17,0xFE,0x1C,0xEB,0x0C,0x8E,0x01,0xE0,0x20,0xE8,0x19, +0x3C,0x00,0x01,0x95,0xEA,0x96,0x97,0x43,0xD2,0x14,0xDD,0x59,0xEA,0x84,0xEA,0xD2, +0xF8,0x37,0xE9,0x0F,0x9C,0x49,0xDD,0x51,0x49,0xFF,0xFF,0x0E,0x2E,0x07,0xFE,0x18, +0x50,0x00,0x7F,0xFF,0x2E,0x17,0xFE,0x19,0x3E,0x07,0xFE,0x1C,0xEA,0xAA,0xEA,0x2C, +0xEB,0x15,0xC1,0x19,0x3C,0x00,0x01,0x96,0xEA,0x96,0x97,0x43,0xD2,0x14,0xDD,0x59, +0xEA,0x84,0x3C,0x30,0x01,0xA0,0xF8,0x1C,0xE9,0x0E,0x9E,0x49,0xEA,0xAA,0xEA,0x24, +0xEA,0x49,0xEA,0x45,0x50,0x00,0x00,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFE,0x30, +0x2E,0x17,0xFE,0x1D,0xEB,0x2F,0x8E,0x01,0xE0,0x20,0xE8,0x1B,0x3C,0x00,0x01,0x97, +0xEA,0x96,0x97,0x43,0xD2,0x16,0xDD,0x59,0xEA,0x84,0x3C,0x30,0x01,0xA1,0x96,0x03, +0x96,0xDB,0x88,0x02,0xE0,0x03,0x83,0xFF,0xE9,0x0C,0x9C,0x49,0xEA,0xAA,0xEA,0x24, +0xEA,0x49,0xEA,0x45,0x50,0x00,0x7F,0xFF,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFE,0x10, +0xDD,0x5E,0x4E,0x12,0x00,0x51,0xEA,0x85,0xC2,0x20,0x3C,0x00,0x01,0x99,0xEA,0x4A, +0x97,0x43,0xD3,0x1B,0xDD,0x59,0xEA,0x9F,0xEA,0xD1,0xF8,0x75,0xE9,0x16,0xEA,0x71, +0x3C,0x00,0x01,0xA0,0xF8,0x7A,0xE9,0x11,0x3C,0x00,0x01,0x9E,0x3C,0x40,0x01,0xA0, +0x3C,0x50,0x01,0xA3,0x97,0x23,0x96,0x03,0xEA,0x78,0x88,0x04,0x88,0x03,0x97,0x2B, +0x40,0xF0,0x10,0x07,0x4E,0xF2,0x00,0xA6,0xEB,0x2F,0x8E,0x01,0xE0,0x40,0xE8,0x2B, +0x3C,0x00,0x01,0x9A,0xEA,0x4A,0x97,0x43,0xD3,0x26,0xDD,0x59,0xEA,0x9F,0xEA,0xD1, +0xF8,0x52,0xE9,0x21,0xEA,0x71,0x3C,0x00,0x01,0xA1,0xF8,0x57,0xE9,0x1C,0x3C,0x00, +0x01,0x9E,0x3C,0x40,0x01,0xA1,0x3C,0x50,0x01,0xA4,0x97,0x23,0x96,0x03,0xEA,0x78, +0x4E,0x00,0x00,0x5C,0xE9,0x10,0x8E,0x21,0x8C,0x41,0xDD,0x51,0xEA,0x83,0xEA,0x24, +0xEA,0x45,0xEA,0x49,0x8C,0x21,0x8E,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFD,0xC0, +0x2E,0x17,0xFE,0x1C,0xEB,0x0C,0x8E,0x01,0xE0,0x20,0x4E,0xF2,0xFF,0x21,0xEA,0x85, +0xC2,0x1C,0x3C,0x00,0x01,0x9B,0xEA,0x4A,0x97,0x43,0xD3,0x17,0xDD,0x59,0xEA,0x9F, +0xEA,0xD2,0xF8,0x21,0xE9,0x12,0xEA,0x71,0x3C,0x00,0x01,0xA0,0xF8,0x26,0xE9,0x0D, +0x3C,0x00,0x01,0x9F,0x3C,0x40,0x01,0xA0,0x3C,0x50,0x01,0xA5,0x97,0x23,0x96,0x03, +0xEA,0x78,0x4E,0x00,0x00,0x2B,0xE8,0x3D,0xEB,0x2F,0x8E,0x01,0xE0,0x40,0x4E,0xF2, +0xFE,0xFF,0x3C,0x00,0x01,0x9C,0xEA,0x4A,0x97,0x43,0x4C,0x51,0xBE,0xF9,0xDD,0x59, +0xEA,0x9F,0xEA,0xD2,0x96,0x03,0x96,0xDB,0x88,0x04,0xE0,0x03,0x83,0xFF,0x4E,0xF3, +0xFE,0xEF,0xEA,0x71,0x3C,0x00,0x01,0xA1,0x96,0xDB,0x97,0x43,0x98,0x23,0xE0,0x05, +0x83,0xFF,0x4E,0xF3,0xFE,0xE5,0x3C,0x00,0x01,0x9F,0x3C,0x40,0x01,0xA1,0x3C,0x50, +0x01,0xA6,0x97,0x23,0x96,0x03,0xEA,0x78,0x88,0x04,0x88,0x03,0x97,0x2B,0xE0,0x04, +0x83,0xFF,0x4E,0xF3,0xFE,0xD5,0x8C,0x21,0x9C,0x91,0xDD,0x51,0xEA,0x83,0xEA,0x24, +0xEA,0x45,0xEA,0x49,0x8E,0x21,0x8E,0x01,0xDD,0x51,0xEA,0x3E,0x48,0xFF,0xFE,0xC8, +0x8C,0x21,0x8E,0x41,0xDD,0x51,0xEA,0x83,0x49,0xFF,0xFE,0x16,0xEA,0x45,0xEA,0x49, +0x8E,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFD,0x52,0xEB,0x0C,0xDD,0x5E, +0x8E,0x01,0x40,0x00,0x80,0x07,0x4E,0x02,0xFE,0xB3,0xEA,0x85,0x48,0xFF,0xFF,0xAE, +0x8E,0x21,0x50,0x21,0x7F,0xFF,0xDD,0x51,0xEA,0x83,0xEA,0x24,0xEA,0x45,0xEA,0x49, +0x8C,0x21,0x8C,0x01,0xDD,0x51,0xEA,0x3E,0x49,0xFF,0xFD,0x3A,0xDD,0x5E,0x4E,0x12, +0xFF,0x7B,0xEA,0x85,0x48,0xFF,0xFF,0x4A,0x84,0x00,0x46,0x11,0x00,0x05,0x12,0x00, +0x82,0xD4,0x46,0x11,0x00,0x05,0x12,0x00,0x82,0xD5,0x2E,0x30,0x00,0xE1,0x2E,0x10, +0x00,0xE0,0x2E,0x27,0xFC,0xE2,0x3A,0x6F,0xB4,0x3C,0x2E,0x60,0x00,0xBD,0x2E,0x97, +0xFC,0xDE,0x3C,0x03,0xFE,0xBD,0x88,0xC2,0x40,0x61,0x00,0x1A,0x97,0xB1,0x84,0x80, +0x44,0xA0,0x00,0x48,0x47,0x21,0x00,0x02,0x59,0x29,0x01,0x44,0x44,0xB0,0x00,0x4C, +0x44,0x80,0x00,0xFE,0x47,0x31,0x00,0x01,0x59,0x39,0x8E,0xB0,0x96,0x20,0xE2,0x03, +0xE8,0x36,0x80,0xF2,0x82,0x12,0x42,0x72,0x28,0x73,0x43,0x02,0x2C,0x73,0x50,0x73, +0x99,0x54,0x51,0x08,0x29,0xB2,0x84,0xA0,0x51,0x10,0x00,0x01,0xD1,0x1E,0xA4,0x38, +0x8C,0xA1,0x96,0x03,0xE0,0xC0,0xE8,0x15,0x12,0x88,0x00,0x00,0xEB,0x4F,0xEA,0xA8, +0x40,0xC9,0x80,0x20,0x5C,0xF0,0x00,0x95,0x39,0x19,0x81,0x08,0x10,0x56,0x00,0x01, +0xE8,0x04,0x8C,0x01,0x40,0x00,0x00,0x13,0x46,0xC1,0x00,0x05,0x12,0x06,0x02,0xD4, +0x8C,0xE2,0x97,0x68,0x8D,0x82,0xD5,0xE3,0xEB,0x4F,0xEA,0xA8,0x8C,0x81,0xE2,0x09, +0xE9,0xCE,0x84,0x01,0xEA,0xFA,0x44,0x00,0x00,0x00,0xEA,0x51,0x2E,0x60,0x00,0xB7, +0x4E,0x63,0x00,0x0E,0xEB,0x4F,0x02,0x50,0x02,0xD5,0xEA,0xEB,0x9F,0x01,0x2E,0x07, +0xFF,0xC9,0x8E,0x01,0xFE,0x24,0xE0,0xA0,0xE9,0x26,0xD5,0x23,0x44,0x00,0x00,0x64, +0xFF,0x84,0x41,0x00,0x84,0x08,0xEB,0x55,0xEA,0xAD,0x84,0xA0,0xD3,0xEC,0x80,0x80, +0x41,0x10,0x40,0x00,0x4C,0x48,0x80,0x11,0xA5,0xE0,0x97,0xFB,0xE0,0xC7,0xE8,0x0A, +0x46,0x71,0x00,0x05,0x02,0x73,0x82,0xD5,0x46,0x91,0x00,0x05,0x8C,0xE1,0x12,0x74, +0x82,0xD5,0x8C,0x82,0xD5,0xF0,0x8C,0xA1,0x97,0x68,0x50,0x00,0x00,0x48,0xD5,0xE7, +0x48,0x00,0x00,0x00,0x2E,0x0F,0xFF,0xCC,0x4E,0x04,0x00,0x4E,0x46,0x51,0x00,0x02, +0x58,0x52,0x81,0x44,0x9D,0xC9,0x84,0x00,0x8C,0x61,0x45,0x00,0x00,0x4C,0x82,0x25, +0x44,0x60,0x00,0xFC,0xFB,0xD6,0xE0,0x60,0xE9,0x1A,0x80,0x85,0x42,0x40,0x40,0x73, +0x22,0xF2,0x11,0xBA,0xE0,0x4F,0xE8,0x03,0x12,0x62,0x14,0xB2,0x80,0x87,0x42,0x40, +0x48,0x73,0x41,0x38,0x90,0x20,0x22,0xF9,0x91,0xBA,0xE0,0x4F,0xE8,0x05,0x40,0x42, +0x90,0x20,0x12,0x62,0x14,0xB2,0x8C,0x01,0x96,0x00,0xD5,0xE6,0x46,0x41,0x00,0x02, +0x58,0x42,0x01,0x44,0xFA,0xB6,0x8C,0x21,0x84,0x00,0x80,0xE4,0x44,0x60,0x00,0xFC, +0xFE,0xEC,0xE0,0x20,0xE9,0x18,0x40,0x52,0x00,0x20,0x22,0xF2,0x91,0xBA,0xE0,0x4F, +0xE8,0x03,0x12,0x62,0x94,0xB2,0x99,0x58,0x41,0x03,0x94,0x20,0x22,0xF8,0x11,0xBA, +0xE0,0x4F,0xE8,0x05,0x40,0x52,0x14,0x20,0x12,0x62,0x94,0xB2,0x8C,0x01,0x96,0x00, +0x48,0xFF,0xFF,0xE9,0x3A,0x6F,0xB4,0x04,0xDD,0x9E,0x92,0x00,0x3A,0x6F,0xBA,0xBC, +0xEF,0xFC,0x3F,0xCF,0xFD,0xD4,0x84,0xC0,0x80,0x06,0x8C,0xC1,0x54,0x63,0x00,0xFF, +0x49,0xFF,0xFC,0xD4,0x5A,0x68,0x0C,0xFA,0x84,0x20,0xB9,0x80,0xB9,0x8E,0xEB,0x4F, +0x02,0x20,0x02,0xD4,0x2E,0x07,0xFC,0xEE,0x92,0x01,0xE2,0x40,0xE8,0x24,0x3C,0x03, +0xFE,0xA3,0x8C,0x01,0x96,0x01,0xEA,0x51,0x2E,0x47,0xFF,0x7B,0x84,0x6A,0xFE,0xE4, +0xE0,0x60,0xE8,0x19,0x3C,0x1B,0xFE,0xA3,0x3E,0x17,0xFD,0x0F,0x3E,0x17,0xFD,0x1D, +0xC2,0x13,0x84,0xC0,0x46,0xB1,0x00,0x02,0x58,0xB5,0x80,0xB4,0x80,0xE6,0x46,0x91, +0x00,0x01,0x58,0x94,0x8E,0xB0,0x46,0xA1,0x00,0x02,0x58,0xA5,0x01,0x44,0x81,0x8B, +0x48,0x00,0x00,0x5F,0xCA,0x06,0x84,0x00,0xEA,0x51,0x3E,0x07,0xFD,0x0F,0xEA,0xFA, +0xEA,0x97,0xC0,0xE8,0xEA,0x56,0x96,0x04,0xC0,0xE5,0x84,0x00,0x3E,0x07,0xFD,0x20, +0x48,0x00,0x00,0x9E,0x40,0x24,0x84,0x20,0xA7,0x11,0x38,0x34,0x85,0x00,0x80,0x44, +0x42,0x21,0xC0,0x73,0x41,0x15,0x08,0x20,0x23,0x18,0x94,0xB2,0x5B,0x10,0xFE,0x4C, +0x8C,0x21,0x96,0x48,0xE2,0x25,0xE9,0xEF,0x4E,0x02,0x00,0x74,0x46,0x01,0x00,0x01, +0x10,0x70,0x0F,0xF2,0x46,0x01,0x00,0x01,0x10,0x60,0x0F,0xF3,0x3E,0x77,0xFE,0x1C, +0x3E,0x67,0xFE,0x1D,0x49,0xFF,0xFC,0x98,0x2E,0x17,0xFC,0xEE,0xEB,0x65,0x04,0x00, +0x00,0x08,0xE2,0x20,0xE8,0x06,0x84,0x01,0x3E,0x07,0xFD,0x0F,0x84,0x00,0xEA,0x51, +0x2E,0x07,0xFF,0x5A,0x96,0x04,0xC8,0x31,0xB8,0x00,0xC0,0x4E,0x9E,0x41,0x84,0x4C, +0x80,0x6B,0x42,0x30,0x88,0x73,0x46,0x11,0x00,0x02,0xA0,0xDA,0x04,0x10,0x80,0x50, +0xE2,0x61,0xE8,0x42,0x96,0x00,0x81,0xC2,0x4E,0x03,0x00,0x2A,0xB8,0x00,0xE6,0x0B, +0xE8,0x04,0x9C,0x01,0x3C,0x0F,0xFF,0x75,0xB8,0x0E,0x8C,0x01,0xB8,0x8E,0x84,0x0B, +0x49,0xFF,0xFC,0x44,0x46,0x01,0x00,0x05,0x02,0x50,0x02,0xD4,0x84,0x00,0x80,0x20, +0xFB,0x96,0xD5,0xB9,0x40,0x25,0x08,0x20,0x22,0x21,0x11,0xBA,0xE0,0x02,0xE8,0xB1, +0x96,0x11,0x80,0xC4,0x80,0xE3,0xD5,0xAD,0x2E,0x07,0xFD,0x0F,0xC0,0xCE,0xEA,0x4E, +0x96,0x00,0xC8,0xCB,0xB8,0x80,0x84,0x01,0xEA,0xFA,0xD5,0x31,0x50,0xD0,0x7F,0xFF, +0x80,0x2C,0x42,0x16,0xB8,0x73,0xA0,0x8A,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x50, +0xE2,0x41,0xE8,0xCD,0x80,0x2D,0xEA,0xF5,0x80,0x0D,0x44,0x10,0x00,0x0B,0xEA,0xF5, +0x54,0x06,0x80,0xFF,0xD5,0xC2,0x84,0x2B,0x49,0xFF,0xFB,0xD8,0x48,0xFF,0xFF,0xC0, +0x3C,0x2D,0xFF,0x75,0x2E,0x37,0xFD,0x01,0x46,0x41,0x00,0x01,0x58,0x42,0x0F,0xF4, +0x80,0x20,0xE2,0x22,0xE8,0x0A,0x38,0x52,0x06,0x02,0xE2,0x65,0xE8,0x03,0x8C,0x01, +0x96,0x00,0x8C,0x21,0x96,0x48,0xD5,0xF6,0x3E,0x07,0xFD,0x07,0xEC,0x04,0x3A,0x6F, +0xBA,0x84,0xDD,0x9E,0xFC,0x60,0x51,0xFF,0xFB,0xA0,0x3D,0x3D,0xFF,0x75,0x4F,0x32, +0x02,0xEB,0x46,0x37,0xFF,0xFF,0x84,0x20,0xB1,0x50,0xB1,0xDC,0xB1,0xA8,0x51,0x1F, +0x80,0xD0,0x51,0x2F,0x81,0x00,0x50,0x2F,0x81,0x30,0x50,0xBF,0x81,0x60,0x50,0x31, +0x8F,0xFF,0x84,0x00,0xB1,0x04,0x38,0x02,0x06,0x0A,0x50,0x4F,0x81,0x90,0x38,0x02, +0x06,0x0A,0x50,0x9F,0x82,0x20,0xEA,0xC4,0x42,0x90,0x90,0x73,0x38,0x02,0x86,0x0A, +0x38,0x03,0x86,0x0A,0x38,0x03,0x06,0x0A,0x38,0x08,0x86,0x0A,0x38,0x09,0x06,0x0A, +0x38,0x01,0x06,0x0A,0x38,0x05,0x86,0x0A,0x80,0x89,0x38,0x32,0x02,0x0A,0x8C,0x01, +0x5A,0x08,0x0C,0xFD,0x8C,0x21,0x5A,0x18,0x0C,0xDE,0x3C,0x9D,0xFF,0x7F,0x84,0x80, +0xE3,0x33,0x80,0x13,0x47,0x97,0xFF,0xFF,0x40,0x04,0xBC,0x1A,0x80,0x64,0x46,0xC1, +0x00,0x01,0x58,0xC6,0x0D,0x08,0x45,0xE0,0xFF,0xFF,0x51,0x9C,0x8F,0xFF,0x46,0xD1, +0x00,0x01,0x58,0xD6,0x8D,0x98,0x40,0x99,0xA4,0x06,0x47,0x51,0x00,0x01,0x59,0x5A, +0x8C,0x0C,0x47,0x61,0x00,0x01,0x59,0x6B,0x0C,0x3C,0x38,0xE6,0x13,0x02,0x94,0x63, +0x4C,0xEF,0x00,0x41,0x50,0xAF,0x82,0x20,0x40,0xA5,0x0C,0x40,0x40,0x80,0xB0,0x00, +0x41,0x42,0x08,0x08,0x86,0x00,0xE1,0x80,0xE8,0x31,0xE3,0x93,0xE8,0x29,0x38,0x16, +0xC3,0x02,0x04,0xF4,0x00,0x01,0x41,0x80,0xB8,0x01,0x40,0x16,0xC0,0x60,0xA0,0x49, +0x40,0xF0,0xBC,0x01,0x43,0x77,0xBC,0x24,0x2E,0x17,0xFC,0xDF,0x43,0x7C,0x60,0x73, +0x15,0x75,0x00,0x00,0xC9,0x17,0x4E,0x92,0x00,0x16,0x38,0x1A,0xD0,0x02,0x43,0x8C, +0x04,0x24,0x38,0x1B,0x50,0x02,0x42,0x17,0x84,0x24,0xE0,0x38,0xE8,0x04,0x40,0x1C, +0x04,0x01,0xD5,0x02,0x8A,0x38,0x94,0x4D,0x88,0x37,0xB6,0x2A,0xD5,0x03,0x15,0x95, +0x00,0x00,0x8D,0x81,0x50,0xA5,0x00,0x30,0xD5,0xCF,0xEB,0x12,0x38,0x40,0x8E,0x0A, +0x8C,0x61,0x8C,0x81,0x5A,0x48,0x0C,0xBB,0x46,0x47,0xFF,0xFF,0x45,0x30,0x00,0x30, +0x50,0x42,0x0F,0xFF,0xE0,0x60,0xE8,0x10,0x50,0x1F,0x82,0x20,0x41,0x00,0x8C,0x40, +0x84,0x20,0xE0,0x20,0xE8,0x07,0x42,0x90,0xCC,0x24,0x8C,0x21,0x38,0x48,0x24,0x0A, +0xD5,0xF9,0x8C,0x61,0xD5,0xF0,0x84,0x20,0x46,0x37,0xFF,0xFF,0x84,0x9F,0x82,0x01, +0x50,0x31,0x8F,0xFF,0xE0,0x20,0xE8,0x0B,0x38,0x42,0x86,0x0A,0x38,0x43,0x86,0x0A, +0x39,0x09,0x06,0x0A,0x38,0x31,0x06,0x0A,0x8C,0x21,0xD5,0xF5,0x51,0x0F,0x82,0x20, +0x80,0x30,0x86,0x60,0x44,0xA0,0x00,0x30,0xE1,0xE0,0xE8,0x1D,0xB4,0x81,0x84,0x61, +0xE0,0x60,0xE8,0x09,0x42,0x91,0xA8,0x24,0x8C,0x61,0x38,0x90,0xA4,0x02,0x42,0x42, +0x24,0x01,0xD5,0xF7,0xC4,0x0D,0x84,0x60,0xE0,0x60,0xE8,0x0A,0x42,0xC1,0xA8,0x24, +0x8C,0x61,0x38,0x90,0xB0,0x02,0x8B,0x24,0x38,0x90,0xB0,0x0A,0xD5,0xF6,0x8D,0xE1, +0x8C,0x24,0xD5,0xE3,0x85,0x80,0x80,0x2C,0x85,0x5F,0xE0,0x20,0xE8,0x2B,0xB5,0xF0, +0x84,0x61,0xE0,0x60,0xE8,0x07,0x38,0x98,0x0E,0x02,0x8C,0x61,0x43,0x39,0xA4,0x01, +0xD5,0xF9,0x39,0x38,0x86,0x0A,0x84,0x60,0xE0,0x60,0xE8,0x11,0x38,0x98,0x0E,0x02, +0x4D,0x34,0xC0,0x0C,0x38,0x92,0x8E,0x02,0x4E,0x94,0x00,0x08,0xB1,0x04,0x38,0x32, +0x06,0x0A,0x38,0x12,0x8E,0x0A,0xD5,0x0A,0x8C,0x61,0xD5,0xEF,0xB0,0xC4,0x38,0x13, +0x32,0x0A,0x38,0xA1,0x86,0x0A,0x50,0xC6,0x00,0x01,0x8C,0x21,0x51,0x08,0x00,0x30, +0xD5,0xD5,0x82,0xEC,0x4E,0xC3,0x00,0x0C,0x84,0x00,0x50,0xDF,0x81,0xC0,0x46,0x31, +0x00,0x01,0x58,0x31,0x8D,0x98,0xEA,0xC6,0x48,0x00,0x00,0xAC,0x47,0x37,0xFF,0xFF, +0x51,0x39,0x8F,0xFF,0x80,0x6C,0x85,0x40,0x44,0xC0,0x00,0x30,0x81,0xB3,0x85,0x1F, +0x86,0x80,0x40,0xFA,0x0C,0x07,0xE8,0x2D,0x39,0x03,0x52,0x02,0x51,0x5F,0x82,0x20, +0x39,0x68,0xC2,0x02,0x43,0x58,0x30,0x73,0x84,0x20,0xE0,0x20,0xE8,0x1F,0xEB,0x3A, +0xE8,0x1B,0x38,0x9A,0x86,0x02,0x40,0xE4,0xD8,0x01,0x38,0x49,0x06,0x02,0x88,0x8E, +0xE0,0x8F,0xE8,0x12,0xCC,0x0D,0x38,0xE2,0x86,0x02,0x4E,0xE5,0x00,0x59,0x38,0xE3, +0x0E,0x0A,0x38,0x41,0x06,0x0A,0x39,0x03,0x86,0x0A,0x8C,0x61,0xD5,0x05,0x38,0x41, +0x06,0x0A,0x39,0x05,0x86,0x0A,0x8C,0x21,0xD5,0xE1,0x51,0x4A,0x00,0x01,0xD5,0xD2, +0x81,0xCD,0x84,0x20,0xE0,0x20,0xE8,0x07,0xEB,0x3A,0xE8,0x03,0x42,0xE7,0x3C,0x01, +0x8C,0x21,0xD5,0xF9,0x86,0x00,0xE1,0x83,0xE8,0x0A,0x38,0x93,0x42,0x02,0x8D,0x81, +0x38,0x18,0xA6,0x02,0x88,0x2E,0x38,0x18,0xA6,0x0A,0xD5,0xF6,0x43,0x41,0xA8,0x00, +0x84,0x20,0xE0,0x20,0xE8,0xB7,0xEB,0x3A,0x50,0x90,0x80,0x01,0xE8,0x21,0x40,0xF7, +0xB8,0x01,0x38,0xF1,0x06,0x0A,0xE9,0x21,0x38,0xF2,0x86,0x02,0x39,0x05,0x86,0x02, +0x4E,0xF4,0x00,0x11,0x80,0x69,0xE0,0x60,0xE8,0x1A,0x38,0xF1,0x0E,0x02,0xE9,0x08, +0x50,0x4F,0x81,0x00,0x38,0x92,0x0E,0x02,0x89,0x2E,0x38,0x92,0x0E,0x0A,0x8C,0x61, +0xD5,0xF3,0x38,0xF3,0x0E,0x0A,0x39,0x03,0x86,0x0A,0x8C,0x61,0xD5,0x06,0x39,0x09, +0x06,0x02,0x89,0x8E,0x39,0x09,0x06,0x0A,0x80,0x29,0xD5,0xD4,0xB0,0xC4,0x38,0x31, +0xC2,0x02,0xB1,0x04,0x38,0x12,0x42,0x0A,0x39,0x02,0x86,0x0A,0x4E,0x35,0x00,0x06, +0x39,0x03,0x8E,0x02,0x80,0x23,0xD5,0xF3,0x51,0x7B,0xFF,0xFF,0x4F,0x72,0xFF,0x66, +0x84,0x20,0xE0,0x20,0xE8,0x07,0x38,0x83,0x86,0x0A,0x39,0x31,0x06,0x0A,0x8C,0x21, +0xD5,0xF9,0x84,0x60,0x80,0x23,0xE0,0x20,0x4E,0xF2,0xFF,0x6C,0xB1,0x04,0x39,0x02, +0x06,0x02,0x4F,0x04,0x00,0x05,0x38,0x13,0x0E,0x0A,0x8C,0x61,0x8C,0x21,0xD5,0xF4, +0x98,0x58,0xEA,0x6A,0x40,0x40,0x34,0x00,0x38,0x21,0x80,0x0A,0x8C,0x08,0x3B,0x02, +0x44,0x20,0xA8,0x89,0x47,0x41,0x00,0x01,0x59,0x4A,0x0D,0x98,0x5A,0x08,0x60,0xF2, +0x84,0xE0,0x47,0x61,0x00,0x01,0x59,0x6B,0x0D,0x08,0x46,0xE1,0x00,0x01,0x58,0xE7, +0x0C,0x3C,0x47,0x51,0x00,0x01,0x59,0x5A,0x8C,0x6C,0x3D,0x3D,0xFF,0x75,0xE2,0xF3, +0x4E,0xF2,0x00,0xFA,0x2E,0x57,0xFD,0x19,0xB0,0x44,0x38,0x20,0x9E,0x02,0x3C,0x1D, +0xFF,0x7F,0x2E,0x37,0xFD,0x0E,0xE2,0x41,0x2E,0x00,0x00,0xEA,0x4E,0xF2,0x00,0x77, +0xEB,0x12,0x38,0x60,0x8A,0x02,0x46,0xC1,0x00,0x01,0x58,0xC6,0x0C,0xD8,0x38,0x16, +0x1A,0x02,0xC9,0x03,0xFF,0x44,0xD5,0x03,0x44,0x50,0x00,0x64,0x46,0x21,0x00,0x01, +0xEB,0x20,0x38,0x21,0x1B,0x02,0x39,0x06,0x9F,0x02,0x40,0x83,0x8C,0x08,0x40,0x98, +0x08,0x01,0x40,0x26,0xA0,0x00,0x05,0x11,0x00,0x01,0x46,0x21,0x00,0x01,0xEB,0x20, +0x40,0x21,0x18,0x60,0xA0,0x91,0x40,0xA8,0x88,0x01,0x46,0x21,0x00,0x01,0x58,0x21, +0x0D,0x74,0x38,0x21,0x18,0x00,0x42,0xB5,0x28,0x24,0x42,0xB4,0xA4,0x73,0x5A,0x28, +0x01,0x2B,0x2F,0xE0,0x00,0xE3,0x3C,0x23,0xFE,0xA5,0x84,0x80,0x41,0x21,0x04,0x08, +0x3C,0x23,0xFE,0xA1,0x41,0x71,0x04,0x08,0xE0,0x9E,0xE8,0x1D,0x38,0x2A,0x93,0x02, +0x41,0x82,0x0C,0x08,0xE3,0x82,0xE8,0x03,0x8A,0x50,0xD5,0x03,0x40,0x28,0x08,0x01, +0xE2,0x52,0xE8,0x0F,0x46,0x21,0x00,0x01,0x58,0x21,0x0C,0x6C,0x88,0x58,0xA0,0x91, +0xE3,0xA2,0xE8,0x03,0x8A,0x51,0xD5,0x03,0x40,0x28,0x88,0x01,0xE2,0x57,0xE9,0x4B, +0x8C,0x81,0xD5,0xE3,0x84,0x41,0x96,0xDF,0x8C,0x67,0xFE,0x1C,0x88,0x25,0x85,0xE7, +0x40,0x15,0x84,0x37,0x40,0xF0,0x3D,0xF6,0xE2,0x2F,0xE9,0x42,0x2E,0x07,0xFD,0x06, +0x2E,0x47,0xFD,0x18,0xEB,0x79,0x58,0x10,0x8C,0xCC,0x9D,0x43,0x84,0x7D,0x38,0x10, +0x98,0x00,0x42,0x52,0x0C,0x73,0xE0,0x25,0xE9,0x30,0x84,0x00,0xEA,0xC6,0x46,0x31, +0x00,0x01,0x58,0x31,0x8D,0x08,0x38,0x51,0x83,0x02,0x94,0x43,0xDA,0x1E,0x44,0x20, +0xFF,0xFD,0x46,0x31,0x00,0x01,0x58,0x31,0x8C,0x0C,0x38,0x2B,0x03,0x0A,0x84,0x40, +0x38,0x21,0x82,0x0A,0x40,0x36,0x9C,0x60,0x88,0x34,0x3B,0x01,0xC4,0x00,0xEA,0xEC, +0xEB,0x79,0xEA,0x72,0x38,0x70,0x80,0x08,0xEB,0x79,0x58,0x10,0x8C,0xD8,0x38,0x27, +0x02,0x0A,0x38,0x20,0x82,0x0A,0xD5,0x04,0x8C,0x01,0x5A,0x08,0x0C,0xDA,0x8C,0xE1, +0x48,0xFF,0xFF,0x4D,0x84,0x42,0xD5,0xB8,0xE7,0xE3,0xE8,0xD0,0xC0,0xCF,0x96,0x30, +0x15,0x5F,0x80,0x03,0x15,0x6F,0x80,0x02,0x15,0x4F,0x80,0x01,0xB6,0x5F,0x49,0xFF, +0xE4,0xF4,0xB4,0x5F,0x05,0x4F,0x80,0x01,0x05,0x6F,0x80,0x02,0x05,0x5F,0x80,0x03, +0xC8,0xBD,0x3C,0x33,0xFE,0xA5,0x3C,0x13,0xFE,0xA1,0xFE,0x5C,0xFE,0x8C,0xE2,0x4B, +0xE8,0x09,0xEB,0x79,0x58,0x10,0x8C,0x0C,0x38,0x07,0x1A,0x0A,0x38,0x00,0x9A,0x0A, +0xD5,0xD7,0xB0,0x04,0x38,0x00,0x1E,0x02,0xEB,0x12,0x38,0x00,0x82,0x02,0x89,0x0D, +0x40,0x0A,0x00,0x60,0x3B,0x04,0x44,0x00,0x3B,0x00,0x44,0x20,0x46,0x01,0x00,0x01, +0x58,0x00,0x0D,0x68,0x38,0x70,0x18,0x08,0x2E,0x07,0xFC,0xDF,0xC8,0xC1,0x46,0x01, +0x00,0x01,0x58,0x00,0x0C,0x0C,0x38,0x97,0x1A,0x0A,0x38,0xA0,0x1A,0x0A,0x38,0xB6, +0x1A,0x0A,0xD5,0xB6,0x51,0xFF,0x84,0x60,0xFC,0xE0,0xFC,0x00,0x3F,0xCF,0xFD,0x90, +0xB9,0x00,0x2E,0x07,0xFF,0x90,0x5A,0x18,0x07,0x03,0x92,0x01,0x3E,0x07,0xFC,0xDC, +0xB8,0x11,0xC0,0x05,0x2E,0x07,0xFC,0xD8,0x5A,0x08,0x01,0x37,0x2E,0x37,0xFC,0xDC, +0x2E,0x27,0xFF,0x93,0xB8,0x17,0xFE,0x9C,0xE2,0x02,0xE8,0x07,0xEA,0xCC,0x42,0x10, +0x8C,0x0B,0xC1,0x2C,0x8C,0x01,0xD5,0x29,0x84,0x01,0xEB,0x10,0x84,0x00,0xEA,0xCF, +0x84,0x00,0xB8,0x8E,0x84,0x01,0xB8,0x9C,0x84,0x08,0x5A,0x10,0x07,0x09,0x5A,0x18, +0x02,0x0A,0x2E,0x07,0xFF,0x5F,0x5A,0x08,0x03,0x06,0x84,0x06,0x2E,0x17,0xFC,0xE9, +0xEA,0x3D,0x84,0x00,0xEB,0x16,0x2E,0x07,0xFC,0xE9,0xC0,0x03,0x84,0x00,0xEB,0x2C, +0xB8,0x00,0x5A,0x00,0x06,0x04,0x5A,0x08,0x08,0x0A,0x46,0x01,0x00,0x01,0x58,0x00, +0x04,0x74,0xB8,0x9A,0xD5,0x03,0x84,0x00,0xB8,0x97,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0xB9,0x11,0xB8,0x00,0xC9,0x0F,0x5A,0x08,0x08,0x08,0x46,0x11,0x00,0x05, +0x02,0x10,0x82,0xD4,0xC9,0x08,0xD5,0x03,0x5A,0x00,0x06,0xFA,0x2E,0x17,0xFC,0xD8, +0x5A,0x18,0x01,0x32,0x84,0x20,0x3E,0x17,0xFC,0xF5,0x84,0x20,0xB9,0x97,0x5A,0x00, +0x08,0x04,0x5A,0x08,0x06,0x20,0xB9,0x8E,0x5A,0x08,0x08,0x04,0x84,0x07,0xD5,0x04, +0x5A,0x08,0x06,0x06,0x84,0x02,0x2E,0x17,0xFC,0xD8,0xEA,0x3D,0x84,0x00,0xEB,0x16, +0xB8,0x00,0x5A,0x08,0x07,0x05,0xEB,0x65,0xEB,0x48,0xD5,0x05,0xEA,0x29,0xC8,0x05, +0xEB,0x65,0xEA,0xB4,0xB8,0x9A,0xD5,0x1E,0x5A,0x08,0x01,0x1D,0xEB,0x65,0xDD,0x5C, +0xD5,0xFA,0x8E,0x03,0xE6,0x03,0xE8,0x16,0xEA,0x43,0xB4,0x01,0x58,0x00,0x04,0x00, +0xB6,0x01,0xD5,0x10,0x2E,0x27,0xFF,0x92,0xFA,0x2E,0xFE,0x54,0x2E,0x27,0xFF,0x93, +0xB8,0x0E,0xFE,0x54,0xE2,0x01,0xE8,0x04,0x8C,0x01,0xB8,0x8E,0xD5,0x03,0x84,0x01, +0xEA,0xCF,0xFC,0x80,0xDD,0x4D,0x5A,0x08,0x08,0x05,0x2E,0x27,0xFF,0x66,0xD5,0x06, +0x84,0x40,0x5A,0x08,0x06,0x04,0x2E,0x27,0xFF,0x71,0x84,0x20,0x80,0x01,0x46,0x31, +0x00,0x01,0x58,0x31,0x82,0xC4,0x38,0xF1,0x85,0x11,0xE0,0x4F,0xE8,0x06,0x5C,0xF0, +0x00,0x95,0xE8,0x03,0x8C,0x01,0x96,0x01,0x8C,0x21,0x5A,0x18,0xD8,0xF6,0x46,0x11, +0x00,0x05,0x12,0x00,0x82,0xD4,0xDD,0x9E,0xFC,0x20,0xDD,0x4D,0x5A,0x08,0x08,0x09, +0x2E,0x17,0xFF,0x66,0x94,0x49,0x96,0x4B,0x2E,0x57,0xFF,0x9D,0xD5,0x0C,0x5A,0x08, +0x06,0x09,0x2E,0x17,0xFF,0x71,0x94,0x49,0x96,0x4B,0x2E,0x57,0xFF,0x99,0xD5,0x03, +0x84,0x20,0x80,0xA1,0x84,0x40,0x3C,0x6D,0xFF,0x7E,0x80,0x82,0x46,0x71,0x00,0x02, +0x58,0x73,0x81,0x44,0x82,0x02,0x47,0x11,0x00,0x01,0x59,0x18,0x82,0xC4,0x98,0x17, +0x02,0x00,0x07,0x9A,0x38,0x33,0x08,0x01,0x9A,0xC3,0x96,0xD9,0x96,0x1B,0x4E,0x05, +0x00,0x07,0xE0,0xA0,0x84,0x00,0xE8,0x07,0x9A,0x1D,0xD5,0x04,0x88,0x05,0x42,0x00, +0x40,0x01,0x96,0x03,0x38,0x08,0x88,0x09,0x88,0x01,0x4E,0x04,0x00,0x04,0x8C,0x81, +0x97,0x21,0x8C,0x42,0x5A,0x29,0xB0,0xE5,0x2E,0x07,0xFF,0xCD,0xE2,0x04,0xE8,0x0A, +0x46,0x01,0x00,0x01,0x00,0x00,0x02,0xC0,0xEB,0x79,0xEA,0x37,0xEA,0xEE,0x84,0x01, +0xEA,0x75,0xFC,0xA0,0xEB,0x26,0xDD,0x9E,0xEA,0xC3,0xC0,0x04,0x84,0x00,0x3C,0x0F, +0xFF,0x80,0xDD,0x9E,0xFC,0x40,0x3F,0xCF,0xFD,0xAC,0x80,0xE1,0x84,0x20,0x80,0xC0, +0x46,0x41,0x00,0x01,0x58,0x42,0x09,0x48,0x80,0xA1,0x44,0x30,0xFF,0xFF,0x50,0x00, +0x80,0x08,0x88,0x04,0x84,0x40,0x8C,0x41,0xB6,0xA0,0x14,0x30,0x7F,0xFE,0x14,0x30, +0x7F,0xFF,0x8C,0x0C,0x5A,0x28,0x04,0xF9,0x50,0x10,0x80,0x30,0x5A,0x1A,0x40,0xF1, +0x84,0x00,0x46,0x21,0x00,0x01,0xEB,0x20,0x44,0x10,0xFF,0xFF,0x38,0x11,0x00,0x0A, +0x98,0xC2,0x8C,0x08,0xA8,0x59,0x5A,0x08,0x60,0xFB,0x46,0x01,0x00,0x01,0x58,0x00, +0x0C,0x3C,0x84,0x20,0xEA,0xEF,0xDD,0x42,0x46,0x01,0x00,0x01,0x58,0x00,0x0C,0x0C, +0x84,0x20,0xEA,0xEF,0xDD,0x42,0xC6,0x04,0x2E,0x07,0xFF,0xC3,0xD5,0x07,0xC7,0x04, +0x2E,0x07,0xFF,0xC5,0xD5,0x03,0x2E,0x07,0xFF,0xC7,0x8C,0x01,0xEA,0xF9,0x2E,0x07, +0xFD,0x1C,0x5A,0x08,0x01,0x04,0x84,0x02,0xEA,0xF9,0xEA,0xD3,0x85,0x20,0xEA,0xCD, +0x3E,0x97,0xFD,0x0F,0x3E,0x97,0xFD,0x1D,0x3E,0x97,0xFD,0x16,0x84,0x40,0x3E,0x97, +0xFC,0xDF,0xBA,0x8A,0xBA,0x98,0xEB,0x4F,0x12,0x20,0x02,0xD4,0xBA,0x94,0xBA,0x8D, +0xBA,0x96,0x3E,0x27,0xFD,0x08,0xBA,0x92,0x3E,0x97,0xFD,0x13,0xBA,0x90,0xEA,0xC0, +0x92,0x27,0x8C,0x21,0x96,0x48,0x3E,0x17,0xFD,0x23,0xEA,0xA4,0x92,0x07,0x8C,0x01, +0x96,0x00,0x3E,0x07,0xFD,0x14,0x2E,0x27,0xFF,0x76,0x2E,0x40,0x00,0xEA,0x3E,0x27, +0xFD,0x0E,0x54,0x31,0x00,0x0F,0x42,0x51,0x90,0x24,0x92,0x44,0x40,0x12,0x84,0x36, +0x3C,0x1B,0xFE,0xA2,0x2E,0x10,0x00,0xEB,0xFF,0x14,0xFE,0xCC,0xFE,0x8C,0x40,0x01, +0x80,0x16,0x3C,0x0B,0xFE,0xAA,0x3C,0x4B,0xFE,0xA5,0x3C,0x2B,0xFE,0xA1,0x2E,0x07, +0xFF,0x75,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFD,0x06,0x92,0x04,0x3E,0x07,0xFD,0x19, +0x2E,0x07,0xFF,0x5D,0x92,0x04,0x3E,0x07,0xFC,0xE3,0x84,0x02,0xB8,0x85,0x2E,0x07, +0xFF,0x60,0xDD,0x49,0x3C,0x0B,0xFE,0xA4,0x2E,0x07,0xFF,0x6A,0xDD,0x49,0x3C,0x0B, +0xFE,0xA8,0x2E,0x07,0xFF,0x6B,0xDD,0x49,0x3C,0x0B,0xFE,0xA9,0x3E,0x97,0xFC,0xF9, +0x3E,0x97,0xFD,0x1E,0x3E,0x97,0xFC,0xFA,0x2E,0x07,0xFF,0x7E,0xEA,0x73,0x2E,0x07, +0xFF,0x7F,0xEA,0xBC,0x2E,0x07,0xFF,0x81,0x40,0x10,0x10,0x09,0x3E,0x17,0xFD,0x0A, +0x96,0x1F,0x84,0x2A,0xFE,0x0C,0x3E,0x07,0xFC,0xF2,0x2E,0x07,0xFF,0x8B,0x3C,0x0B, +0xFE,0xAD,0xC7,0x0B,0x2E,0x07,0xFF,0x86,0x54,0x10,0x00,0x0F,0x3E,0x17,0xFC,0xF0, +0x92,0x04,0x3E,0x07,0xFC,0xE4,0xD5,0x13,0x2E,0x07,0xFF,0x84,0x54,0x10,0x00,0x0F, +0x3E,0x17,0xFC,0xF0,0x92,0x04,0x3E,0x07,0xFC,0xE4,0x2E,0x07,0xFF,0x85,0x54,0x10, +0x00,0x0F,0x3E,0x17,0xFC,0xD9,0x92,0x04,0x3E,0x07,0xFC,0xF1,0x49,0xFF,0xEF,0x28, +0x46,0x01,0x00,0x01,0x58,0x00,0x0B,0x94,0x84,0x3F,0x84,0x4C,0xDD,0x42,0x84,0x00, +0x3E,0x07,0xFD,0x05,0x2E,0x17,0xFF,0x96,0x84,0x00,0x40,0x00,0x04,0x06,0x3E,0x07, +0xFC,0xF3,0x2E,0x27,0xFF,0x8E,0x3E,0x27,0xFC,0xE0,0x2E,0x37,0xFF,0x8F,0xFA,0x24, +0x42,0x21,0x84,0x73,0x96,0x90,0x3E,0x27,0xFC,0xFF,0xC0,0x02,0x84,0x44,0x3E,0x27, +0xFC,0xE7,0x2E,0x07,0xFF,0x90,0x84,0x40,0x3E,0x07,0xFC,0xDC,0x3E,0x27,0xFC,0xFE, +0x3E,0x27,0xFD,0x20,0x3E,0x27,0xFD,0x0D,0x3E,0x27,0xFC,0xD6,0x3E,0x27,0xFC,0xF6, +0x3E,0x27,0xFC,0xDD,0x84,0x00,0x3C,0x0B,0xFE,0xA7,0x3E,0x07,0xFD,0x07,0x2E,0x07, +0xFF,0x80,0x3E,0x07,0xFD,0x01,0x2E,0x00,0x00,0xB8,0x54,0x10,0x00,0x0F,0x3E,0x17, +0xFD,0x0C,0x92,0x04,0x3E,0x07,0xFD,0x22,0x2E,0x00,0x00,0xB9,0x54,0x10,0x00,0x0F, +0x3E,0x17,0xFD,0x12,0x92,0x04,0x3E,0x07,0xFC,0xD5,0x3E,0x27,0xFD,0x26,0xCE,0x03, +0x3E,0x27,0xFD,0x31,0x3E,0x27,0xFD,0x2A,0x3E,0x27,0xFD,0x2F,0x3E,0x27,0xFD,0x27, +0x3E,0x27,0xFD,0x29,0x3E,0x27,0xFD,0x2B,0x3E,0x27,0xFD,0x2E,0x84,0x00,0xB8,0x9F, +0xB8,0x9E,0x2E,0x4F,0xFF,0x5B,0x4E,0x45,0x00,0x03,0x84,0x02,0x84,0x40,0x3E,0x07, +0xFD,0x17,0x86,0x00,0x3E,0x27,0xFD,0x2C,0x84,0xA0,0x3D,0x0B,0xFE,0xC3,0xBD,0x9D, +0x2E,0x30,0x00,0x22,0xEA,0x2A,0xFE,0xCC,0x3C,0x3B,0xFE,0xC2,0x2E,0x30,0x00,0x23, +0xFE,0xCC,0x3C,0x3B,0xFE,0xC5,0x2E,0x30,0x00,0x24,0xFE,0xCC,0x3C,0x3B,0xFE,0xBF, +0x2E,0x30,0x00,0x25,0xFE,0x5C,0x3C,0x1B,0xFE,0xC4,0x2E,0x10,0x00,0x26,0x3C,0x1B, +0xFE,0xC0,0x2E,0x10,0x00,0x27,0x3E,0x17,0xFD,0x2D,0x2E,0x10,0x00,0x29,0x3E,0x17, +0xFD,0x30,0x3F,0x07,0xFD,0x28,0x3E,0x27,0xFC,0xDA,0xBD,0x89,0x3E,0x27,0xFD,0x21, +0x3E,0x27,0xFD,0x24,0x3E,0x27,0xFC,0xE1,0x2E,0x10,0x00,0x1A,0x40,0x30,0x90,0x09, +0x3E,0x37,0xFC,0xEA,0x96,0x5F,0x3E,0x17,0xFD,0x0B,0xCE,0x10,0x3E,0x27,0xFC,0xF5, +0xEB,0x79,0x10,0x20,0x82,0xC0,0xEB,0x79,0x10,0x20,0x82,0xC1,0x84,0x21,0x3E,0x17, +0xFC,0xE8,0x3E,0x27,0xFD,0x11,0xBE,0x80,0xBE,0x86,0xC7,0x04,0xEB,0x65,0xEB,0x48, +0xD5,0x12,0x4E,0x44,0x00,0x0C,0xC8,0x08,0xEA,0x29,0xE6,0x01,0x3E,0xF7,0xFD,0x31, +0x84,0x01,0x3E,0x07,0xFD,0x17,0xEA,0x29,0xC8,0x04,0xEB,0x65,0xEA,0xB4,0xD5,0x03, +0xEB,0x65,0xDD,0x5C,0xB8,0x93,0x84,0xE0,0x44,0x20,0x05,0x10,0x3E,0x77,0xFC,0xF8, +0x84,0x20,0xEB,0x4F,0xEA,0x61,0xDD,0x42,0x3E,0x77,0xFC,0xF5,0x84,0x01,0xEB,0x2C, +0x84,0xC0,0x3E,0x77,0xFC,0xD8,0xBE,0x87,0x49,0xFF,0xDB,0xB4,0xEB,0x4F,0x12,0x60, +0x02,0xD6,0x3C,0x6B,0xFE,0xA3,0x3E,0x67,0xFD,0x15,0x3C,0x6B,0xFE,0x9F,0x46,0x01, +0x00,0x05,0x10,0x60,0x06,0xD6,0x46,0x01,0x00,0x05,0x12,0x60,0x03,0x6A,0x46,0x01, +0x00,0x05,0x10,0x60,0x06,0x42,0x46,0x01,0x00,0x05,0x12,0x60,0x03,0x20,0x46,0x31, +0x00,0x05,0x58,0x31,0x86,0x44,0xEA,0x28,0x46,0x21,0x00,0x05,0x58,0x21,0x05,0xB0, +0x98,0x73,0x38,0x01,0x98,0x0A,0x38,0x01,0x18,0x0A,0xA8,0x09,0x10,0x70,0x80,0x08, +0x98,0x72,0x8C,0xCC,0xA8,0x09,0x10,0x70,0x80,0x08,0x5A,0x68,0x90,0xF3,0xFC,0xC0, +0x2E,0x27,0xFD,0x1C,0x5A,0x18,0x02,0x05,0x3E,0x27,0xFC,0xFD,0xD5,0x0E,0x8E,0x07, +0xE6,0x02,0xE8,0x05,0x2E,0x07,0xFF,0xC4,0xEA,0xDD,0xD5,0x05,0x2E,0x17,0xFF,0xC6, +0x40,0x01,0x04,0x40,0x3E,0x07,0xFC,0xFD,0x84,0x00,0x3E,0x07,0xFC,0xE6,0xEA,0xBB, +0xEA,0xC7,0xDD,0x9E,0xFC,0x0B,0x3F,0xCF,0xFD,0x90,0x2E,0x07,0xFD,0x03,0xC8,0x12, +0xB8,0x0C,0x5A,0x00,0x02,0x09,0x2E,0x07,0xFF,0x88,0xDD,0x49,0xEA,0x35,0x2E,0x07, +0xFF,0x89,0xD5,0x0E,0x2E,0x07,0xFF,0x8C,0xDD,0x49,0xEA,0x35,0x2E,0x07,0xFF,0x8D, +0xD5,0x07,0xEA,0xA1,0x96,0x1F,0xDD,0x49,0xEA,0x35,0xEA,0xA1,0x92,0x04,0xDD,0x49, +0xEA,0x53,0xEA,0x4E,0xC0,0x09,0x2E,0x00,0x00,0x1B,0xDD,0x49,0xEA,0x35,0x2E,0x00, +0x00,0x1B,0xDD,0x49,0xEA,0x53,0xEA,0x44,0xC0,0x07,0xEB,0x1A,0x94,0x01,0xEA,0x35, +0xEB,0x09,0x94,0x01,0xEA,0x53,0xDD,0x54,0x5A,0x08,0x01,0x04,0x49,0x00,0x03,0x31, +0xEB,0x07,0xEA,0xFF,0xDD,0x4C,0x42,0x00,0x18,0x0B,0xC0,0x06,0xDD,0x54,0x5A,0x08, +0x01,0x04,0x49,0x00,0x04,0x64,0xB8,0x1B,0xB9,0x11,0xE2,0x01,0xE8,0x0C,0xC0,0x0B, +0xEA,0x4E,0xC0,0x09,0xEB,0x1A,0x94,0x01,0xEA,0x35,0xEB,0x09,0x94,0x01,0xEA,0x53, +0xEB,0x07,0xEA,0xFF,0x84,0x00,0x3E,0x07,0xFD,0x10,0xDD,0x4C,0x42,0x00,0x18,0x0B, +0xBA,0x11,0xC0,0x33,0xB8,0x14,0x5A,0x08,0x01,0x31,0xE6,0x42,0xE9,0x2E,0x46,0x01, +0x00,0x01,0x00,0x10,0x0F,0xDC,0x46,0x01,0x00,0x01,0x00,0x00,0x0F,0xDE,0xE2,0x01, +0xE8,0x03,0x9A,0x08,0xD5,0x02,0x8A,0x01,0x2E,0x37,0xFF,0xB2,0xE0,0x03,0xE8,0x1D, +0x46,0x01,0x00,0x01,0x00,0x10,0x0F,0xDD,0x46,0x01,0x00,0x01,0x00,0x00,0x0F,0xDF, +0xE2,0x01,0xE8,0x03,0x9A,0x08,0xD5,0x02,0x8A,0x01,0xE0,0x03,0xE8,0x0E,0xEB,0x65, +0x04,0x00,0x00,0x2F,0x46,0x11,0x00,0x02,0x04,0x10,0x80,0x32,0x92,0x01,0xE2,0x20, +0xE8,0x04,0x84,0x01,0x3E,0x07,0xFD,0x10,0xB8,0x1B,0xE2,0x40,0xE8,0x12,0x2E,0x07, +0xFD,0x03,0xC0,0x0F,0xEA,0x4E,0xC8,0x0D,0xEA,0xE0,0xC8,0x0B,0xEA,0xA1,0x96,0x1F, +0xDD,0x49,0xEA,0x35,0xEA,0xA1,0x92,0x04,0xDD,0x49,0xEA,0x53,0xEB,0x07,0xEA,0xFF, +0xB8,0x11,0xC0,0x1E,0x46,0x11,0x00,0x01,0x00,0x10,0x8F,0xDC,0x46,0x01,0x00,0x01, +0x8E,0x21,0x00,0x00,0x0F,0xDD,0xFA,0x54,0x42,0x00,0x88,0x73,0x46,0x11,0x00,0x02, +0xEB,0x19,0x40,0x00,0x80,0x20,0x22,0xF0,0x0C,0xA9,0x2E,0x07,0xFF,0x62,0x94,0x01, +0xE0,0x0F,0xE8,0x06,0x84,0x00,0xEA,0xCD,0xEA,0xE5,0xC1,0x11,0xD5,0x0E,0x3C,0x03, +0xFE,0xA0,0x5C,0xF0,0x03,0xE8,0xE8,0x0B,0x8C,0x01,0xEA,0xCD,0x3C,0x03,0xFE,0x9C, +0x5C,0xF0,0x00,0xC8,0xE8,0x04,0x8C,0x01,0x3C,0x0B,0xFE,0x9C,0x46,0x01,0x00,0x07, +0xEA,0x62,0xEA,0x21,0xEA,0x20,0xD8,0x17,0x49,0xFF,0xE2,0xEC,0x49,0xFF,0xE1,0x68, +0x49,0xFF,0xF9,0x12,0x49,0xFF,0xE7,0x79,0x49,0xFF,0xE4,0x2F,0x49,0xFF,0xE4,0xE1, +0xDD,0x54,0x5A,0x08,0x01,0x10,0x46,0x01,0x00,0x01,0x58,0x00,0x09,0x48,0x49,0xFF, +0xDE,0x62,0xD5,0x08,0xDD,0x4C,0xEA,0xF3,0xC8,0xE8,0xDD,0x54,0x5A,0x08,0x01,0x30, +0xD5,0xE4,0x46,0x01,0x00,0x05,0xEA,0x52,0x49,0xFF,0xE5,0xC8,0x46,0x01,0x00,0x05, +0xEA,0x52,0x49,0xFF,0xE0,0xA0,0xB8,0x00,0x5A,0x08,0x07,0x1F,0xB1,0x82,0x80,0x26, +0x46,0x21,0x00,0x01,0xEB,0x3B,0x46,0x01,0x00,0x05,0xEA,0x52,0x46,0x31,0x00,0x01, +0x58,0x31,0x8D,0x68,0x49,0xFF,0xEB,0xC1,0xF0,0x81,0xF2,0x01,0x3A,0x03,0x04,0x00, +0x49,0xFF,0xF3,0xBA,0x5A,0x00,0xFF,0x09,0x3E,0x07,0xFD,0xDC,0x96,0x01,0x46,0x11, +0x00,0x07,0x12,0x00,0x81,0xDB,0x84,0x00,0x3E,0x07,0xFC,0xDF,0x46,0x01,0x00,0x05, +0xEA,0x52,0xFC,0x8B,0x46,0x01,0x00,0x05,0x58,0x00,0x05,0xB0,0xDD,0x9E,0x46,0x11, +0x00,0x05,0x58,0x10,0x85,0xB0,0x46,0x01,0x00,0x05,0xEA,0x52,0x3B,0x00,0x64,0x04, +0xF8,0x01,0x3B,0x00,0xE4,0x24,0x3B,0x00,0x64,0x04,0x83,0xFF,0x3B,0x00,0xE4,0x24, +0x3B,0x00,0x58,0x00,0x3B,0x00,0xD8,0x20,0xDD,0x9E,0x3C,0x0F,0xFF,0x78,0xDD,0x9E, +0x3C,0x13,0xFE,0xC1,0x3C,0x53,0xFE,0xC0,0xD9,0x07,0x84,0x00,0x3E,0x07,0xFD,0x26, +0x84,0x00,0xEB,0x18,0xDD,0x9E,0xC8,0x06,0xEA,0x44,0xC0,0x04,0x8C,0x21,0x3C,0x1B, +0xFE,0xC1,0xDD,0x9E,0xFC,0x00,0x84,0x01,0x3E,0x07,0xFD,0x2A,0x3E,0x07,0xFD,0x2C, +0x84,0x00,0x3C,0x0B,0xFE,0xC3,0x84,0x21,0x3C,0x1F,0xFF,0x88,0xEB,0x18,0xFC,0x80, +0xFC,0x00,0x3C,0x1D,0xFF,0x88,0x5A,0x18,0x01,0x1F,0x2E,0x17,0xFD,0x2A,0x5A,0x18, +0x01,0x14,0x84,0x40,0x3E,0x27,0xFD,0x2A,0x2E,0x37,0xFD,0x31,0xCB,0x04,0x3E,0x17, +0xFD,0x31,0xD5,0x06,0x5A,0x38,0x01,0x09,0x3E,0x27,0xFD,0x31,0x84,0x20,0x49,0x00, +0x06,0xAB,0x49,0x00,0x0A,0xF1,0x2E,0x07,0xFD,0x2B,0x8C,0x01,0x3E,0x07,0xFD,0x2B, +0x84,0x02,0xD5,0x07,0x84,0x03,0x5A,0x10,0x02,0x05,0x5A,0x18,0x03,0x05,0x84,0x00, +0x3C,0x0F,0xFF,0x88,0xFC,0x80,0xFC,0x00,0x3C,0x1F,0xFF,0x7E,0x84,0x20,0x3C,0x1F, +0xFF,0x7D,0xDD,0x4F,0x46,0x01,0x00,0x05,0xEA,0x61,0xDD,0x42,0xFC,0x80,0xFC,0x00, +0x3F,0xCF,0xFD,0xD0,0xEB,0x08,0xC9,0x04,0x3C,0x63,0xFE,0xC2,0xD5,0x07,0x5A,0x18, +0x01,0x05,0x3C,0x63,0xFE,0xC5,0xD5,0x02,0xEA,0xB3,0x84,0x40,0x80,0x02,0x46,0x41, +0x00,0x05,0x58,0x42,0x06,0xD8,0x38,0x32,0x09,0x01,0x8C,0x41,0x88,0x03,0x5A,0x28, +0xD8,0xFC,0x44,0x20,0x7F,0xFF,0x92,0x04,0xE2,0x40,0x40,0x01,0x3C,0x1B,0x2E,0x27, +0xFD,0x2F,0xCA,0x03,0xB8,0x96,0xD5,0x02,0xB8,0x95,0x2E,0x07,0xFD,0x2E,0xE6,0x0A, +0xE8,0x04,0x8C,0x01,0x3E,0x07,0xFD,0x2E,0x2E,0x07,0xFD,0x2E,0xE6,0x02,0x4E,0xF3, +0x00,0x7C,0xC9,0x43,0x3C,0x23,0xFE,0xBF,0xB8,0x16,0xE2,0x40,0xE8,0x07,0x84,0x01, +0x3E,0x07,0xFD,0x26,0x3C,0x1B,0xFE,0xC1,0xD5,0x04,0xB8,0x01,0x49,0xFF,0xFF,0x6A, +0xB8,0x15,0x88,0xC0,0xB8,0x16,0xE2,0xC0,0xE8,0x03,0xEA,0x44,0xC8,0x05,0xB8,0x00, +0xEB,0x14,0x5A,0x08,0x01,0x12,0x2E,0x0F,0xFF,0x5B,0x4E,0x04,0x00,0x0E,0x46,0x01, +0x00,0x07,0xEA,0x26,0xEA,0x47,0xEA,0x3F,0xD0,0x07,0x46,0x01,0x00,0x07,0xEA,0x26, +0xEA,0x21,0xEA,0x20,0xD8,0x08,0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x21,0xEA,0x20, +0x4C,0x50,0x40,0x4B,0xEB,0x35,0x46,0x01,0x00,0x02,0xEA,0xB4,0x50,0x10,0x05,0x10, +0x49,0xFF,0xFF,0x8B,0xB8,0x00,0x5A,0x08,0x01,0x04,0x84,0x02,0xD5,0x04,0x5A,0x08, +0x03,0x3C,0x84,0x00,0xB8,0x80,0xD5,0x38,0x5A,0x18,0x01,0x37,0x3C,0x23,0xFE,0xC4, +0xB8,0x15,0xE2,0x40,0xE8,0x06,0x3E,0x17,0xFD,0x26,0x84,0x00,0xEB,0x18,0xD5,0x04, +0xB8,0x01,0x49,0xFF,0xFF,0x27,0xB8,0x16,0x88,0xC0,0xB8,0x15,0xE2,0xC0,0xE8,0x03, +0xEA,0x44,0xC8,0x05,0xB8,0x00,0xEB,0x14,0x5A,0x08,0x01,0x12,0x2E,0x0F,0xFF,0x5B, +0x4E,0x04,0x00,0x0E,0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x47,0xEA,0x3F,0xD0,0x07, +0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x21,0xEA,0x20,0xD8,0x07,0x46,0x01,0x00,0x07, +0xEA,0x26,0xEA,0x47,0xEA,0x3F,0xD8,0x08,0xEB,0x35,0x46,0x01,0x00,0x02,0xDD,0x5C, +0x50,0x10,0x7A,0xF0,0xD5,0xBE,0xB8,0x04,0xC8,0x2F,0xEA,0x29,0x5A,0x08,0x01,0x2D, +0x2E,0x17,0xFC,0xF5,0xC9,0x29,0x3C,0x03,0xFE,0xBF,0xBA,0x16,0xE2,0x40,0xE8,0x24, +0x3C,0x03,0xFE,0xC4,0xBA,0x15,0xE2,0x40,0xE8,0x1F,0x46,0x01,0x00,0x07,0xEA,0x26, +0xEA,0x21,0xEA,0x20,0xD0,0x19,0x46,0x01,0x00,0x07,0xEA,0x26,0xEA,0x47,0xEA,0x3F, +0xD0,0x13,0x2E,0x07,0xFD,0x28,0x5C,0xF0,0x00,0xC8,0xE8,0x03,0x8C,0x01,0xD5,0x0D, +0x3E,0x17,0xFD,0x28,0xEB,0x35,0x46,0x01,0x00,0x02,0xDD,0x5C,0x50,0x10,0x7A,0xF0, +0x49,0xFF,0xFF,0x1B,0xD5,0x04,0x84,0x00,0x3E,0x07,0xFD,0x28,0xB9,0x01,0x2E,0x07, +0xFD,0x2C,0xC0,0x0F,0xC9,0x0E,0x3C,0x03,0xFE,0xC3,0x2E,0x27,0xFD,0x2D,0xE2,0x40, +0xE8,0x06,0x3E,0x17,0xFD,0x2C,0x3C,0x1B,0xFE,0xC3,0xD5,0x06,0x8C,0x01,0xD5,0x02, +0x84,0x00,0x3C,0x0B,0xFE,0xC3,0xFC,0x80,0xFC,0x00,0x3F,0xCF,0xFD,0xD4,0x3C,0x13, +0xFE,0xBF,0xB8,0x15,0xE2,0x20,0xE9,0x06,0x3C,0x13,0xFE,0xC4,0xB8,0x14,0xE2,0x20, +0xE8,0x05,0x2E,0x07,0xFD,0x15,0xC8,0x02,0xEA,0x75,0x2E,0x07,0xFD,0x04,0xC0,0x2D, +0x84,0x00,0xEA,0x75,0x2E,0x17,0xFC,0xE0,0xB8,0x0C,0xE2,0x20,0xEA,0xCC,0xE8,0x22, +0x42,0x20,0x84,0x0B,0xC2,0x1F,0xBA,0x00,0xC2,0x04,0x2E,0x27,0xFD,0x15,0xC2,0x1A, +0xDD,0x54,0x5C,0x10,0x00,0x01,0x84,0x01,0xEA,0xBA,0xDD,0x54,0x5A,0x00,0x01,0x04, +0x84,0x07,0xD5,0x02,0x84,0x02,0x84,0x22,0xEA,0x3D,0xDD,0x54,0x80,0xC0,0x5A,0x08, +0x01,0x0E,0xEA,0x36,0xC8,0x04,0xEA,0x95,0xEA,0xC2,0xD5,0x08,0x3E,0x67,0xFC,0xD2, +0xD5,0x05,0xEA,0x5C,0xC1,0x03,0x8C,0x01,0xB8,0x8C,0xFC,0x80,0xFC,0x00,0x3F,0xCF, +0xFD,0x90,0x46,0x01,0x00,0x07,0x04,0x50,0x03,0xCE,0xEA,0x21,0xEA,0x20,0xD8,0x03, +0x84,0x03,0xD5,0x1E,0x46,0x01,0x00,0x05,0xEB,0x21,0x3C,0x13,0xFE,0xA4,0xE2,0x20, +0x84,0x20,0xBA,0x0C,0xE8,0x0B,0xB9,0x8D,0xB8,0x07,0xE6,0x03,0xE8,0x04,0x8C,0x01, +0xB8,0x87,0xD5,0x0F,0xC2,0x0E,0xB9,0x8C,0xD5,0x0C,0xB9,0x87,0xB8,0x0D,0xE6,0x0F, +0xE8,0x04,0x8C,0x01,0xB8,0x8D,0xD5,0x05,0x5A,0x20,0x02,0x04,0x84,0x02,0xB8,0x8C, +0xB8,0x0C,0xC8,0x0A,0x2E,0x07,0xFF,0x61,0xEA,0x4B,0x3C,0x03,0xFE,0xA8,0xEA,0x88, +0x2E,0x07,0xFC,0xF0,0xD5,0x22,0x5A,0x08,0x02,0x17,0x2E,0x07,0xFF,0x62,0xEA,0x4B, +0x3C,0x03,0xFE,0xA9,0xEA,0x88,0x2E,0x07,0xFC,0xF0,0xEA,0x70,0x2E,0x07,0xFC,0xF1, +0xEA,0x93,0x2E,0x07,0xFF,0x7E,0xEA,0x73,0x2E,0x07,0xFF,0x7F,0xEA,0xBC,0x2E,0x00, +0x00,0x9E,0xD5,0x16,0x5A,0x08,0x03,0x18,0x2E,0x07,0xFF,0x63,0xEA,0x4B,0x3C,0x03, +0xFE,0xA8,0xEA,0x88,0x2E,0x07,0xFC,0xE4,0xEA,0x70,0xEA,0xF7,0xEA,0x93,0x2E,0x07, +0xFF,0x7C,0xEA,0x73,0x2E,0x07,0xFF,0x7D,0xEA,0xBC,0x2E,0x00,0x00,0x9D,0xDD,0x49, +0x3C,0x0B,0xFE,0xAB,0xEB,0x01,0xC0,0x1C,0xEB,0x25,0xC8,0x1A,0x2E,0x00,0x00,0x0A, +0xEA,0x4B,0x2E,0x00,0x00,0x0C,0xEA,0x88,0x2E,0x00,0x00,0x0F,0x40,0x10,0x10,0x09, +0x3E,0x17,0xFC,0xDB,0xB9,0x1B,0x5A,0x18,0x01,0x04,0x96,0x1F,0xD5,0x02,0xEA,0xF7, +0xEA,0x93,0x2E,0x07,0xFF,0x7C,0xEA,0x73,0x2E,0x00,0x00,0x0E,0xEA,0xBC,0xB8,0x00, +0x5A,0x08,0x07,0x05,0x2E,0x07,0xFF,0x65,0xEA,0x4B,0xEB,0x26,0xC0,0x04,0x2E,0x07, +0xFF,0x71,0xEA,0x4B,0xEA,0x44,0xC0,0x07,0x2E,0x07,0xFC,0xE4,0xEA,0x70,0xEA,0xF7, +0x8C,0x02,0xEA,0x93,0xB8,0x1C,0xC0,0x03,0x84,0x00,0xEA,0x70,0xFC,0x80,0xFC,0x40, +0x2E,0x50,0x00,0x10,0x40,0x62,0x90,0x09,0x4E,0x62,0x01,0x38,0x46,0x01,0x00,0x07, +0x04,0x10,0x03,0xC5,0xEA,0x21,0xEA,0x20,0x4C,0x10,0x00,0x06,0xDD,0x4C,0xEB,0x1B, +0x4E,0x02,0x01,0x2C,0xEA,0x82,0x3C,0x0D,0xFF,0x78,0x4E,0x13,0x01,0x0E,0xE6,0x02, +0x4E,0xF2,0x01,0x0B,0x2E,0x37,0xFD,0x1D,0x4E,0x33,0x01,0x07,0x2E,0x20,0x00,0x14, +0x2E,0x70,0x00,0xE1,0x54,0x01,0x00,0x0F,0x8C,0xE1,0x9C,0x41,0x8A,0xE0,0xEA,0x31, +0x92,0x44,0x51,0x00,0x00,0x01,0x51,0x21,0x00,0x01,0x8B,0x82,0x80,0x03,0x80,0x43, +0xFB,0xF6,0x46,0x91,0x00,0x04,0x58,0x94,0x84,0xB8,0xE0,0x27,0xE8,0x19,0x42,0xA0, +0xCC,0x24,0x80,0x92,0xE0,0x90,0xE8,0x11,0x41,0x12,0x28,0x00,0x41,0x14,0xC4,0x20, +0x02,0xF8,0x80,0x00,0xEA,0x7F,0xE0,0x0F,0xE8,0x05,0x02,0x08,0x80,0x00,0x80,0x61, +0x80,0x44,0x8C,0x81,0x97,0x20,0xD5,0xEF,0x8C,0x21,0x96,0x48,0xD5,0xE7,0x46,0x11, +0x00,0x07,0x12,0x00,0x87,0xBB,0x2E,0x40,0x00,0x3B,0x2E,0x10,0x00,0x3C,0xE2,0x04, +0x40,0x10,0x80,0x06,0x41,0x07,0x84,0x02,0x3F,0x07,0xFD,0x0D,0x2E,0x10,0x00,0x12, +0xE2,0x20,0xE8,0x0D,0x2E,0x10,0x00,0x11,0xE2,0x01,0xE8,0x09,0x3C,0x43,0xFE,0xA0, +0x2E,0x70,0x00,0x13,0x84,0x2A,0xFE,0x7C,0xE0,0x24,0xE9,0x03,0x4F,0x02,0x00,0xB0, +0xFA,0x96,0xFF,0x1C,0x47,0x11,0x00,0x04,0x59,0x18,0x84,0xB8,0x99,0xE2,0x95,0xF9, +0x8E,0xE2,0x40,0x13,0xC4,0x00,0xA4,0x48,0x8C,0xE4,0x88,0xF1,0x41,0x20,0x80,0x11, +0xA4,0x78,0x50,0x72,0x7F,0xDA,0x96,0x4B,0x88,0xE2,0x95,0xF9,0x88,0x32,0x88,0x01, +0x40,0x13,0xC4,0x00,0xA4,0x48,0x88,0x01,0x50,0x12,0x00,0x26,0x88,0x22,0x94,0x49, +0x40,0x40,0xC4,0x00,0xA5,0x20,0x88,0x04,0x9F,0x3A,0x88,0x91,0xA5,0x20,0x8C,0xE2, +0x88,0xF1,0x88,0x04,0xA5,0x38,0x88,0x04,0x9F,0x0A,0x88,0x91,0x8C,0x22,0xA5,0x20, +0x88,0x31,0xA4,0x48,0x88,0x04,0x88,0x01,0x96,0x01,0x92,0x01,0x46,0x11,0x00,0x07, +0x12,0x00,0x87,0xBC,0x2E,0x10,0x00,0x15,0xE2,0x20,0xE8,0x03,0x4F,0x02,0x00,0x0E, +0x2E,0x10,0x00,0x3E,0xE2,0x20,0x4E,0xF2,0x00,0x84,0x2E,0x10,0x00,0x3D,0xE2,0x01, +0x4E,0xF2,0x00,0x7F,0x4F,0x02,0x00,0x7D,0xEA,0x8F,0x5A,0x08,0xFF,0x04,0x48,0x00, +0x00,0x7D,0xC8,0x08,0x3E,0x27,0xFC,0xF6,0x3E,0x37,0xFC,0xDD,0x3E,0x07,0xFC,0xEB, +0xD5,0x4F,0x2E,0x07,0xFC,0xF6,0xE2,0x40,0xE8,0x03,0x9A,0x82,0xD5,0x02,0x8A,0x40, +0x2E,0x07,0xFC,0xDD,0x96,0x90,0xE2,0x60,0xE8,0x03,0x9A,0xC3,0xD5,0x02,0x8A,0x60, +0xDD,0x5A,0x96,0xD8,0x80,0x82,0x42,0x41,0x80,0x73,0x97,0x5F,0x80,0x04,0x46,0x41, +0x00,0x07,0x12,0x02,0x07,0xBD,0x9C,0x69,0x2E,0x00,0x00,0x16,0x5A,0x68,0x01,0x0F, +0x96,0x1F,0xE0,0x02,0xE9,0x03,0xE0,0x03,0xE8,0x03,0x84,0x1F,0xEA,0xB9,0x2E,0x57, +0xFC,0xD6,0xD9,0x26,0x84,0x01,0xEB,0x0D,0xD5,0x23,0x92,0x04,0xE2,0x02,0xE9,0x03, +0xE2,0x03,0xE8,0x04,0x84,0x1F,0xEA,0xB9,0xD5,0x1B,0x98,0x1A,0x2E,0x47,0xFC,0xEB, +0x96,0x00,0xE2,0x04,0xE8,0x07,0x8A,0x80,0xE4,0x83,0xE9,0x04,0x84,0x1F,0xEA,0xB9, +0xD5,0x03,0x3E,0x07,0xFC,0xEB,0xFE,0x94,0x42,0x21,0x8C,0x73,0xFE,0x4C,0x96,0x90, +0xE0,0x22,0xE8,0x06,0xEA,0x8F,0x90,0xA1,0xE0,0xA0,0xE9,0xDD,0xD5,0xE4,0xEA,0x8F, +0x5C,0xF0,0x00,0xF0,0xE8,0x1D,0x8C,0x01,0xEA,0xB9,0xD5,0x1A,0x5A,0x60,0x03,0x19, +0x3F,0x07,0xFC,0xD6,0xD5,0x15,0x84,0x20,0x3E,0x17,0xFC,0xD6,0xC8,0x0E,0x2E,0x20, +0x00,0x17,0x3C,0x13,0xFE,0xA7,0x94,0x91,0xE0,0x22,0xE8,0x05,0x8C,0x21,0x3C,0x1B, +0xFE,0xA7,0xD5,0x06,0xEB,0x0D,0xD5,0x02,0x84,0x00,0x3C,0x0B,0xFE,0xA7,0xEA,0x8F, +0x46,0x11,0x00,0x07,0x12,0x00,0x87,0xBA,0xFC,0xC0,0xFC,0x20,0x3F,0xCF,0xFD,0xD4, +0x2E,0x50,0x01,0x85,0x2E,0x40,0x01,0x84,0x84,0x22,0x9A,0xAC,0x8C,0x41,0x40,0x21, +0x04,0x56,0x2F,0x00,0x01,0x86,0x88,0x44,0x2E,0x70,0x01,0x87,0x96,0x10,0x46,0x21, +0x00,0x01,0x00,0x21,0x0F,0xDD,0x46,0x61,0x00,0x07,0x9A,0x82,0x42,0x31,0x00,0x03, +0x40,0x28,0x1C,0x01,0x8C,0x41,0x40,0x11,0x04,0x36,0x46,0x21,0x00,0x01,0x88,0x27, +0x00,0x21,0x0F,0xDC,0x96,0x48,0x9A,0x8A,0x42,0x21,0x00,0x03,0x88,0x43,0x96,0xD1, +0x12,0x33,0x07,0xB5,0x2E,0x37,0xFC,0xE1,0xCB,0x21,0xB8,0x00,0xC0,0x57,0x46,0x01, +0x00,0x01,0x00,0x10,0x0B,0xA0,0xC9,0x52,0x2E,0x00,0x00,0x18,0xE0,0x02,0xE8,0x13, +0x2E,0x07,0xFD,0x24,0x8C,0x01,0x96,0x00,0x3E,0x07,0xFD,0x24,0x2E,0x07,0xFD,0x24, +0x2E,0x27,0xFC,0xEA,0xE2,0x40,0xE8,0x42,0x84,0x01,0x3E,0x07,0xFC,0xE1,0x3E,0x17, +0xFD,0x20,0xD5,0x3C,0x3E,0x17,0xFD,0x24,0xD5,0x39,0xBA,0x03,0xCA,0x07,0xBA,0x00, +0xCA,0x05,0x3E,0x27,0xFD,0x24,0x3E,0x27,0xFC,0xE1,0x2E,0x30,0x00,0x1C,0x46,0x21, +0x00,0x01,0x04,0x21,0x03,0xFD,0xE2,0x62,0xE8,0x29,0xFA,0x76,0x80,0x40,0x42,0x23, +0x8C,0x73,0xEB,0x1C,0xEB,0x27,0x40,0x23,0x08,0x20,0x22,0x21,0x14,0xB2,0x5A,0x20, +0xFD,0x1E,0x42,0x08,0x0C,0x73,0x40,0x23,0x00,0x20,0x22,0x01,0x14,0xB2,0x5A,0x00, +0xFD,0x16,0xFE,0x5C,0x98,0x0C,0x40,0x03,0x00,0x20,0x22,0x00,0x14,0xB2,0x5A,0x00, +0xFD,0x0E,0x88,0xA1,0x40,0x53,0x14,0x20,0x22,0x02,0x94,0xB2,0x5A,0x00,0xFD,0x07, +0x84,0x00,0x3E,0x07,0xFD,0x24,0x3E,0x07,0xFC,0xE1,0xFC,0xA0,0x46,0x19,0x00,0x00, +0x04,0x00,0x80,0x30,0xEA,0x37,0x14,0x00,0x80,0x30,0xDD,0x9E,0x46,0x19,0x00,0x28, +0xA4,0xCA,0x84,0x41,0x40,0x21,0x00,0x0C,0x40,0x21,0x88,0x12,0xAC,0x8A,0x50,0x10, +0x80,0x74,0x40,0x10,0x80,0x40,0xA6,0x08,0xDD,0x9E,0x46,0x09,0x00,0x88,0x84,0x21, +0x10,0x10,0x00,0xA8,0x44,0x1F,0xFF,0xA5,0x10,0x10,0x00,0xE0,0x46,0x02,0xB1,0x18, +0x50,0x00,0x03,0x00,0x46,0x13,0x00,0xB9,0xB6,0x01,0x46,0x06,0x65,0x5F,0x50,0x00, +0x0F,0x00,0x46,0x13,0x00,0xEB,0xB6,0x01,0xDD,0x9E,0xFC,0x40,0x80,0xE1,0x81,0x20, +0x80,0xC2,0xDD,0x53,0x46,0x33,0x00,0x00,0x88,0x67,0x4E,0x92,0x00,0x04,0xB6,0xC3, +0xD5,0x03,0x97,0xB0,0xAF,0x98,0xDD,0x56,0x04,0x00,0x00,0x3A,0x92,0x0C,0x96,0x0F, +0x5A,0x08,0x03,0x06,0x84,0x20,0x46,0x03,0x00,0xB9,0xB6,0x20,0x84,0x20,0xEA,0x5E, +0x10,0x10,0x00,0xA8,0xFC,0xC0,0xFC,0x00,0xF8,0x32,0x80,0x43,0xDD,0x4B,0xFC,0x80, +0xFC,0x20,0x80,0xE0,0x80,0xC1,0xDD,0x53,0x46,0x23,0x00,0x00,0xC7,0x13,0x98,0x32, +0xA6,0x40,0x9C,0x11,0x88,0x06,0xA7,0x00,0x9C,0x12,0x88,0x06,0x9C,0xD3,0xA6,0x00, +0x98,0xB3,0xA6,0x90,0xEA,0xE9,0x40,0x00,0x0B,0x04,0xFE,0x0F,0x40,0x00,0x11,0x04, +0xD5,0x04,0x88,0x46,0xA6,0x10,0x96,0x00,0xEA,0x3C,0x04,0x10,0x80,0x3A,0x92,0x2C, +0x96,0x4F,0x5A,0x18,0x03,0x06,0x84,0x40,0x46,0x13,0x00,0xB9,0xB6,0x41,0x84,0x40, +0x46,0x19,0x00,0x88,0x10,0x20,0x80,0xA8,0xFC,0xA0,0xFC,0x00,0x40,0x10,0xA8,0x08, +0x40,0x10,0x81,0x80,0x88,0x22,0x84,0x00,0x83,0xFF,0xEA,0x5F,0x96,0x00,0xFC,0x80, +0x46,0x38,0x00,0x00,0x84,0x40,0x50,0x31,0x80,0x34,0xB4,0x03,0x46,0x18,0x00,0x00, +0x96,0x04,0xC0,0x06,0x5A,0x20,0x64,0x2E,0x8C,0x41,0x96,0x90,0xD5,0xF7,0x5A,0x20, +0x64,0x29,0xA8,0x0C,0xA0,0x8C,0x50,0x40,0x80,0x20,0x58,0x21,0x00,0x80,0xA8,0x8C, +0xA0,0x8C,0x66,0x21,0x1F,0x00,0x58,0x21,0x07,0x00,0xA8,0x8C,0xA0,0xCC,0x44,0x2C, +0xFF,0xFF,0xFE,0x9E,0x42,0x21,0x44,0x08,0xA8,0x8C,0xB6,0x04,0xB4,0x64,0x46,0x2F, +0x0F,0xFF,0x50,0x21,0x0F,0xFF,0xFE,0x9E,0x46,0x30,0x70,0x00,0xFE,0x9F,0xB6,0x44, +0xB4,0x44,0x42,0x21,0x78,0x08,0xB6,0x44,0x84,0x44,0x10,0x20,0x80,0x24,0xDD,0x9E, +0xFA,0x11,0xDD,0x9E,0xFC,0x63,0xF0,0x81,0xEB,0x5B,0xEB,0x33,0x44,0x00,0x04,0x00, +0xF2,0x01,0xDD,0x48,0xEA,0x8B,0x81,0x60,0x4E,0x03,0x00,0x9C,0x46,0xEF,0xF0,0x0F, +0x81,0x80,0x50,0x07,0x0F,0xFF,0x84,0xC1,0x85,0xA4,0xF0,0x84,0xEB,0x82,0x58,0x00, +0x00,0x04,0x38,0x70,0x34,0x00,0x8C,0x01,0x38,0xA6,0x80,0x00,0x4E,0x72,0x00,0x8A, +0x54,0x05,0x00,0xFB,0x85,0x00,0xF0,0x83,0xE3,0x07,0x4E,0xF2,0x00,0x7C,0x40,0x04, +0x34,0x00,0xEB,0x5B,0x58,0x10,0x80,0x00,0x88,0x01,0x00,0x90,0x00,0x06,0x5A,0xA0, +0xBD,0x6C,0x5A,0xA8,0xE9,0x0C,0x54,0x04,0x80,0xC0,0x5A,0x08,0xC0,0x05,0x54,0xE4, +0x80,0x3F,0xD5,0x0F,0x85,0xC1,0xC0,0x0D,0xD5,0x0B,0x5A,0xA8,0xC1,0x08,0x2E,0x07, +0xFC,0xD3,0x81,0xC6,0x5A,0x08,0x01,0x06,0xD5,0x59,0x5A,0xA0,0xB6,0x0A,0x81,0xC6, +0x88,0xC8,0x96,0x30,0xF0,0x81,0xEA,0xD7,0x84,0xC3,0xF0,0x82,0xD5,0x07,0x2E,0x07, +0xFC,0xBC,0x5A,0x00,0xFF,0xF6,0x81,0xC6,0xD5,0x49,0x80,0x0A,0x80,0x2C,0xF2,0x02, +0x80,0x69,0x49,0xFF,0xFF,0x32,0x5A,0xA0,0xB9,0x42,0xF0,0x03,0x5A,0x00,0xB2,0x3F, +0x5A,0xA0,0xE9,0x3D,0x80,0x0A,0x80,0x2C,0xF2,0x02,0xEA,0x3B,0xF0,0x85,0x4C,0x90, +0x00,0x36,0x44,0x00,0x00,0x32,0xDD,0x50,0x9E,0x31,0x97,0x80,0xF3,0x05,0xCE,0xE6, +0x46,0x01,0x00,0x07,0x04,0x20,0x03,0xF0,0xF1,0x04,0x66,0x21,0x00,0xFF,0x40,0x25, +0x08,0x04,0x14,0x20,0x03,0xF0,0x04,0x00,0x03,0xF0,0x44,0x2F,0x00,0xFF,0xFE,0x86, +0x40,0x21,0x31,0x04,0x46,0x01,0x00,0x07,0x14,0x20,0x03,0xF0,0x04,0x00,0x03,0xF0, +0x81,0x6A,0xFE,0x0E,0xF1,0x01,0x40,0x60,0x06,0x04,0x46,0x01,0x00,0x07,0x14,0x60, +0x03,0xF0,0x04,0x10,0x03,0xF0,0x40,0x10,0xA0,0x08,0x92,0x28,0x40,0x10,0x8F,0x04, +0x14,0x10,0x03,0xF0,0xD5,0x03,0x81,0xC6,0x81,0x89,0x8D,0x01,0x80,0xCE,0x48,0xFF, +0xFF,0x85,0x8C,0xE2,0x40,0xD6,0x9C,0x00,0x5C,0xF6,0x84,0x00,0x4E,0xF3,0xFF,0x70, +0x80,0x0B,0xFC,0xE3,0x46,0x09,0x00,0x08,0x02,0x50,0x00,0x08,0xEA,0xEA,0xD1,0x03, +0x12,0x10,0x00,0x08,0xDD,0x9E,0xFC,0x00,0xEA,0xB5,0x46,0x10,0x30,0x00,0xEA,0xB7, +0x8C,0x21,0xEB,0x2E,0xB4,0x02,0x96,0x04,0xC0,0x04,0x8E,0x21,0xC9,0xFC,0xFA,0x14, +0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x11,0x00,0x00,0x80,0x40,0xDD,0x4B, +0xEA,0x48,0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x11,0x10,0x00,0x80,0x40, +0xDD,0x4B,0xEA,0x48,0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x12,0x90,0x00, +0x80,0x40,0xDD,0x4B,0xEA,0x48,0xFC,0x80,0xFC,0x00,0xDD,0x53,0x84,0x00,0x44,0x12, +0x80,0x00,0x80,0x40,0xDD,0x4B,0xEA,0x48,0xFC,0x80,0x46,0x09,0x00,0x08,0xA5,0x46, +0x44,0x10,0xAC,0x53,0xD1,0x04,0x44,0x1F,0xAC,0x53,0xAC,0x46,0xDD,0x9E,0x46,0x09, +0x00,0x08,0xA4,0x46,0xC1,0x03,0x84,0x20,0xAC,0x46,0xDD,0x9E,0xFC,0x01,0xEA,0x38, +0x00,0x1F,0x80,0x00,0x84,0x01,0x40,0x30,0x80,0x02,0x00,0x1F,0x80,0x01,0x00,0x2F, +0x80,0x04,0xFE,0x46,0x40,0x11,0x84,0x20,0x00,0x3F,0x80,0x02,0xFE,0xC6,0x40,0x10, +0x8C,0x60,0x00,0x3F,0x80,0x03,0xFE,0xC6,0x40,0x10,0x8C,0x80,0xFE,0x16,0x40,0x00, +0x80,0xA0,0xEB,0x42,0xEB,0x3F,0xEA,0x5D,0xFC,0x81,0x9E,0x41,0xE6,0x23,0xE8,0x1B, +0xEA,0x27,0x84,0x40,0x10,0x20,0x80,0x94,0x84,0x41,0x10,0x20,0x80,0x94,0xEA,0x3C, +0x5A,0x00,0x02,0x08,0x5A,0x00,0x03,0x0A,0xEA,0xD5,0x12,0x00,0x80,0x0A,0xD5,0x09, +0x44,0x00,0x00,0xA5,0xAC,0x0E,0xD5,0x05,0x44,0x00,0x00,0x55,0x12,0x00,0x80,0x0C, +0x84,0x00,0xDD,0x9E,0xFA,0x02,0xDD,0x9E,0x46,0x20,0x4C,0x4B,0x50,0x21,0x04,0x00, +0xE2,0x41,0xE9,0x18,0xE6,0x04,0xE8,0x16,0xFC,0x01,0xF0,0x81,0x80,0xC1,0x84,0x00, +0xF1,0x01,0xEA,0x2E,0x3C,0x1D,0xFF,0xD1,0xFA,0x44,0xFF,0x8C,0x84,0x00,0xF1,0x01, +0x40,0x23,0x08,0x57,0xF8,0x2C,0x84,0x00,0xF1,0x01,0x84,0x48,0xF8,0x2D,0x84,0x00, +0xFC,0x81,0xFA,0x02,0xDD,0x9E,0xE6,0x04,0xE8,0x2B,0xFC,0x40,0x80,0xE0,0x81,0x21, +0x84,0x01,0x80,0x27,0xEA,0x2E,0x46,0x49,0x00,0x80,0x8C,0x84,0x40,0x42,0x1C,0xA0, +0x44,0x10,0x00,0x65,0x8E,0x21,0x96,0x48,0xB4,0x64,0xB4,0x04,0xC1,0x1B,0x40,0x60, +0x0C,0x04,0xCE,0xF9,0x40,0x24,0x88,0x09,0xDD,0x5A,0x42,0x11,0x00,0x24,0x2E,0x27, +0xFD,0xA2,0x84,0x01,0x40,0x20,0x88,0x57,0x80,0x27,0x88,0x40,0x49,0x00,0x0A,0x6F, +0x84,0x01,0x80,0x40,0x80,0x27,0x49,0x00,0x0A,0x75,0x80,0x06,0xD5,0x04,0xFA,0x02, +0xDD,0x9E,0xFA,0x14,0xFC,0xC0,0x46,0x18,0x00,0x60,0x00,0x00,0x80,0x14,0xEB,0x02, +0x10,0x00,0x80,0x14,0xDD,0x9E,0x46,0x08,0x00,0x60,0x00,0x10,0x00,0x10,0x84,0x01, +0x40,0x00,0x04,0x12,0xDD,0x9E,0x00,0x00,0xFC,0x01,0x10,0x0F,0x80,0x07,0x00,0x0F, +0x80,0x07,0x96,0x00,0xE6,0x06,0xE8,0x47,0x3E,0xFF,0xD5,0x88,0x38,0x07,0x80,0x00, +0x40,0xF0,0x3C,0x00,0x4A,0x00,0x3C,0x00,0x22,0x06,0x0A,0x10,0x16,0x1C,0xEB,0x0B, +0xD5,0x0E,0x44,0x60,0x00,0x66,0xD5,0x0B,0x44,0x60,0x00,0x77,0xD5,0x08,0x44,0x60, +0x00,0x99,0xD5,0x05,0x44,0x60,0x00,0xAA,0xD5,0x02,0x84,0xC0,0x46,0x19,0x00,0x78, +0x00,0x0F,0x80,0x07,0xF8,0x03,0x46,0x19,0x00,0x70,0x00,0x00,0x80,0x08,0xEA,0x37, +0xEA,0xFD,0x83,0xFF,0x2E,0x07,0xFC,0xBA,0xC0,0x02,0xEB,0x0B,0xEA,0x57,0xEA,0xA5, +0xC8,0x11,0xEA,0x7D,0xC8,0x0F,0x49,0xFF,0xE6,0x40,0xC8,0x0C,0xEA,0x3C,0x04,0x00, +0x80,0x10,0x42,0x00,0x44,0x0B,0xC8,0x06,0x04,0x00,0x80,0x10,0x42,0x00,0x48,0x0B, +0xC0,0x02,0xEB,0x0B,0x97,0xB1,0xDD,0x56,0x12,0x60,0x00,0x50,0x64,0x00,0x00,0x00, +0x84,0x00,0xD5,0x02,0xFA,0x02,0xFC,0x81,0xFC,0x20,0x84,0xA0,0x50,0x21,0x00,0x24, +0x80,0x85,0x45,0x20,0x00,0x48,0x47,0x11,0x00,0x07,0x59,0x18,0x85,0x00,0x2E,0x30, +0x00,0xE1,0xE0,0x83,0xE8,0x18,0x82,0x11,0x43,0x02,0x48,0x73,0x84,0x60,0x2E,0x60, +0x00,0xE0,0xE0,0x66,0xE8,0x0D,0x38,0x78,0x0D,0x01,0x99,0x9D,0x40,0x70,0x1C,0x20, +0xA5,0xF8,0x40,0x60,0x98,0x20,0x97,0xFB,0xAD,0xF0,0x8C,0x61,0xD5,0xF1,0x8C,0x81, +0x88,0xA2,0xD5,0xE6,0xFC,0xA0,0xFC,0x21,0x3F,0xCF,0xFD,0x8C,0xF0,0x81,0xDD,0x47, +0x80,0xE1,0x80,0xC2,0xDD,0x40,0xC0,0x02,0x84,0xC4,0xEA,0x2B,0xC0,0x1A,0xDD,0x43, +0x02,0x30,0x00,0x9C,0x02,0x00,0x00,0x0A,0x8A,0x60,0x40,0x31,0xA4,0x08,0xBB,0x80, +0x3C,0x3D,0xFF,0x63,0xFE,0xDA,0xBB,0x84,0x80,0x06,0x49,0x00,0x09,0x7C,0xB9,0x04, +0xF0,0x01,0x44,0x20,0x01,0xB0,0x42,0x70,0x08,0x73,0x80,0x47,0x49,0x00,0x09,0x8C, +0xFC,0xA1,0x00,0x00,0xFC,0x00,0xE6,0x28,0x4E,0xF2,0x01,0x89,0x9E,0x82,0xE6,0x47, +0x4E,0xF2,0x01,0x85,0x44,0x30,0x01,0xAC,0x3E,0xFF,0xD6,0xC8,0x38,0x27,0x88,0x00, +0x40,0xF1,0x3C,0x00,0x4A,0x00,0x3C,0x00,0x08,0x08,0x08,0x08,0x08,0x0E,0x0E,0x00, +0x44,0x20,0xD6,0xB0,0xD5,0x03,0x44,0x20,0xD3,0x58,0x42,0x20,0x8C,0x73,0x00,0x31, +0x01,0x88,0x80,0x22,0xEA,0xB7,0x10,0x31,0x00,0x28,0x3C,0x3D,0xFF,0x64,0x8E,0x67, +0xE6,0x62,0xE8,0x0F,0x46,0x31,0x00,0x07,0x04,0x51,0x83,0xC4,0x46,0x3A,0x55,0xAA, +0x50,0x31,0x85,0x5A,0xD3,0x06,0x2E,0x37,0xFF,0x5B,0x42,0x31,0x90,0x0B,0xC3,0x05, +0x04,0x30,0x80,0x59,0x14,0x31,0x00,0x30,0x46,0x28,0x00,0x20,0x00,0x30,0x81,0x89, +0x10,0x31,0x02,0xBC,0x00,0x30,0x81,0x8A,0x10,0x31,0x00,0x2C,0x00,0x30,0x81,0x8B, +0x10,0x31,0x02,0x38,0x04,0x30,0x80,0x4B,0x14,0x31,0x00,0x8D,0x04,0x30,0x80,0x4C, +0x14,0x31,0x00,0x0E,0x00,0x30,0x81,0x8C,0x10,0x31,0x00,0x40,0x00,0x30,0x81,0x8D, +0x10,0x31,0x00,0x44,0x00,0x30,0x81,0x8E,0x10,0x31,0x00,0x48,0x00,0x30,0x81,0x8F, +0x10,0x31,0x00,0x4C,0x00,0x30,0x81,0x90,0x10,0x31,0x00,0x50,0x00,0x30,0x81,0x91, +0x10,0x31,0x00,0x54,0x00,0x30,0x81,0x92,0x10,0x31,0x00,0x58,0x00,0x30,0x81,0x93, +0x10,0x31,0x00,0x64,0x02,0x30,0x80,0xB4,0x12,0x31,0x00,0x12,0x02,0x30,0x80,0xB5, +0x12,0x31,0x00,0x8A,0x02,0x30,0x80,0xB6,0x12,0x31,0x00,0x1E,0x00,0x30,0x81,0x94, +0x10,0x31,0x00,0x28,0x00,0x30,0x81,0x95,0x10,0x31,0x00,0x34,0x00,0x30,0x81,0x96, +0x10,0x31,0x02,0xAC,0x00,0x30,0x81,0x97,0x10,0x31,0x00,0x18,0x00,0x30,0x81,0x98, +0x10,0x31,0x05,0x68,0x00,0x30,0x81,0x99,0x10,0x31,0x05,0x78,0x00,0x30,0x81,0x9A, +0x10,0x31,0x01,0x30,0x00,0x30,0x81,0x9B,0x10,0x31,0x01,0x2C,0x00,0x30,0x81,0x9C, +0x10,0x31,0x01,0xDC,0x00,0x30,0x81,0x9D,0x10,0x31,0x02,0x9C,0x00,0x30,0x81,0x9E, +0x10,0x31,0x01,0xD8,0x02,0x30,0x80,0xB7,0x12,0x31,0x00,0x9A,0x02,0x30,0x80,0xB8, +0x12,0x31,0x00,0x9C,0x02,0x30,0x80,0xB9,0x12,0x31,0x00,0x0A,0x02,0x30,0x80,0xBA, +0x12,0x31,0x00,0xF8,0x02,0x30,0x80,0xBB,0x12,0x31,0x00,0xFC,0x02,0x30,0x80,0xBC, +0x12,0x31,0x00,0xFE,0x02,0x30,0x80,0xBD,0x12,0x31,0x01,0x00,0x00,0x30,0x81,0x9F, +0x10,0x31,0x02,0x04,0x04,0x30,0x80,0x4D,0x14,0x31,0x00,0x38,0x04,0x30,0x80,0x4E, +0x14,0x31,0x00,0x39,0x00,0x30,0x81,0xA0,0x10,0x31,0x00,0xCC,0x00,0x30,0x81,0xA1, +0x10,0x31,0x00,0xD0,0x02,0x30,0x80,0xBE,0x12,0x31,0x00,0xF6,0x04,0x30,0x80,0x4F, +0x14,0x31,0x00,0x78,0x04,0x30,0x80,0x50,0x14,0x31,0x00,0x79,0x02,0x30,0x80,0xBF, +0x12,0x31,0x00,0xF4,0x02,0x30,0x80,0xC0,0x12,0x31,0x02,0xB8,0x02,0x30,0x80,0xC1, +0x12,0x31,0x00,0xB6,0x04,0x30,0x80,0x51,0x14,0x31,0x00,0xB1,0x04,0x30,0x80,0x52, +0x14,0x31,0x00,0xB3,0x04,0x30,0x80,0x53,0x14,0x31,0x00,0xB4,0x04,0x30,0x80,0x3F, +0x14,0x31,0x01,0x5F,0x04,0x30,0x80,0x40,0x14,0x31,0x01,0x60,0x04,0x30,0x80,0x41, +0x14,0x31,0x01,0x61,0x04,0x30,0x80,0x42,0x14,0x31,0x01,0x62,0x04,0x30,0x80,0x43, +0x14,0x31,0x01,0x63,0x04,0x30,0x80,0x44,0x14,0x31,0x01,0x64,0x04,0x30,0x80,0x45, +0x14,0x31,0x01,0x65,0x04,0x30,0x80,0x46,0x14,0x31,0x01,0x66,0x04,0x30,0x80,0x47, +0x14,0x31,0x01,0x67,0x04,0x30,0x80,0x48,0x14,0x31,0x01,0x68,0x04,0x30,0x80,0x49, +0x14,0x31,0x01,0x69,0x04,0x30,0x80,0x4A,0x14,0x31,0x01,0x6A,0x00,0x30,0x81,0xA2, +0x10,0x31,0x00,0xD8,0x04,0x30,0x80,0x54,0x14,0x31,0x00,0x30,0x04,0x30,0x80,0x55, +0x14,0x31,0x00,0x31,0x04,0x30,0x80,0x56,0x14,0x31,0x00,0x32,0x00,0x30,0x81,0xA3, +0x10,0x31,0x00,0xB0,0x00,0x30,0x81,0xA4,0x10,0x31,0x00,0xB4,0x00,0x30,0x81,0xA5, +0x10,0x31,0x05,0xBC,0x04,0x30,0x80,0x57,0x14,0x31,0x00,0xB2,0x04,0x30,0x80,0x58, +0x14,0x31,0x00,0xB0,0x00,0x30,0x81,0xA6,0x10,0x31,0x01,0x58,0x00,0x30,0x81,0xA7, +0x10,0x31,0x01,0x5C,0x02,0x30,0x80,0xC2,0x46,0x52,0x00,0x00,0x12,0x31,0x00,0x94, +0x50,0x22,0x80,0xFC,0xB4,0x61,0xB6,0x65,0xB4,0x85,0xB4,0x61,0x4C,0x41,0xFF,0xFC, +0x8C,0xA4,0x8C,0x24,0xDA,0xF8,0x49,0xFF,0xC7,0xF2,0x49,0xFF,0xC4,0x06,0x46,0x00, +0x00,0x0D,0x00,0x00,0x04,0xF9,0x8E,0x01,0x96,0x00,0x3E,0x07,0xFC,0xC6,0x46,0x00, +0x00,0x0D,0x00,0x00,0x06,0xA5,0x8E,0x01,0x96,0x00,0x3E,0x07,0xFC,0xCD,0xEA,0x8B, +0x80,0xC0,0xC8,0x0E,0xDD,0x5A,0xDD,0x50,0xDD,0x4D,0x8E,0x07,0xE6,0x02,0xE8,0x08, +0x84,0x21,0xDD,0x43,0x10,0x10,0x02,0xA0,0xD5,0x03,0xFA,0x02,0xD5,0x02,0x80,0x06, +0xFC,0x80,0x92,0x00,0xFC,0x40,0x84,0xC0,0x80,0x26,0x84,0x01,0xEA,0x2E,0x80,0x26, +0x8C,0xC1,0x84,0x00,0x97,0xB0,0xEA,0x2E,0x5A,0x68,0x04,0xF8,0x84,0xE0,0x3E,0x77, +0xFC,0xD1,0x46,0x68,0x00,0x20,0x85,0x21,0x3E,0x97,0xFC,0xB9,0x10,0x73,0x01,0x68, +0x44,0x00,0x01,0xF4,0x10,0x73,0x02,0x14,0x10,0x73,0x02,0xA0,0x10,0x73,0x00,0xB0, +0x10,0x73,0x00,0x84,0x10,0x73,0x01,0x00,0x10,0x73,0x00,0x8C,0x10,0x73,0x00,0x1C, +0x10,0x73,0x00,0x20,0xDD,0x50,0x10,0x93,0x00,0x20,0xDD,0x5A,0x10,0x73,0x00,0x94, +0xEA,0x6D,0x8E,0x01,0xC8,0xFE,0x84,0x21,0x46,0x28,0x00,0x30,0x10,0x13,0x00,0x94, +0x12,0x01,0x00,0xE4,0x10,0x13,0x00,0x90,0x46,0x19,0x00,0x68,0xAE,0x08,0xDD,0x4D, +0x8E,0x07,0xE6,0x02,0xE8,0x0B,0x46,0x01,0x00,0x07,0xEA,0x62,0xEA,0x21,0xEA,0x20, +0xD0,0x04,0xDD,0x4C,0xEA,0xF3,0xC0,0x02,0xEA,0x5A,0x84,0x20,0xEA,0x76,0xAE,0x40, +0xDD,0x4F,0x46,0x01,0x00,0x00,0x58,0x00,0x0B,0x14,0x84,0x20,0xDD,0x42,0xFC,0xC0, +0xFC,0x00,0x3F,0xCF,0xFD,0x90,0x46,0x10,0x00,0xE7,0x84,0x00,0x50,0x10,0x8C,0x15, +0x44,0x20,0x00,0x68,0xDD,0x4B,0xDD,0x43,0x84,0x21,0x46,0x20,0xFF,0xFF,0xEA,0x46, +0x50,0x21,0x0F,0xFF,0x10,0x10,0x00,0x1C,0x10,0x10,0x00,0x84,0x10,0x10,0x00,0x80, +0xEB,0x4D,0xB4,0xA0,0xEA,0x27,0xDA,0xFE,0x84,0xC1,0x84,0x00,0x10,0x60,0x80,0xFC, +0x10,0x60,0x81,0x00,0x10,0x00,0x80,0x90,0xB8,0x00,0x8E,0x07,0xE6,0x02,0xE8,0x08, +0xEA,0x5A,0xEA,0x5E,0xEA,0xFE,0xEA,0x43,0xB4,0x01,0xEA,0xF6,0xB6,0x01,0x84,0x01, +0xEA,0x54,0xB8,0x00,0x8E,0x02,0xE6,0x04,0xE8,0x05,0xFA,0x38,0xDD,0x43,0x10,0x10, +0x00,0xD8,0xB8,0x00,0x5A,0x08,0x02,0x05,0x84,0x03,0x49,0x00,0x08,0xB8,0xB8,0x00, +0x5A,0x08,0x06,0x07,0x44,0x10,0xFF,0xEE,0xDD,0x43,0x14,0x10,0x00,0xAD,0xFC,0x80, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0xDD,0x45,0xDD,0x56, +0xF8,0x07,0xC1,0x31,0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFE,0xEA,0xE1,0x04,0x10, +0x00,0x15,0x92,0x30,0x96,0x48,0x83,0xFF,0x5A,0x18,0x33,0x26,0xEB,0x4A,0x8E,0x27, +0xE6,0x22,0xE8,0x21,0x04,0x10,0x00,0x15,0x92,0x38,0x5A,0x18,0x11,0x05,0x3E,0x17, +0xFC,0xBE,0xD5,0x08,0x04,0x00,0x00,0x15,0x92,0x18,0x5A,0x08,0x22,0x04,0x3E,0x07, +0xFC,0xBE,0x2E,0x07,0xFC,0xBE,0x5A,0x08,0x22,0x09,0xEA,0x47,0xEA,0x3F,0x83,0xFF, +0x46,0x11,0x00,0x07,0xEA,0x6F,0xD5,0x07,0x2E,0x07,0xFC,0xBE,0x5A,0x08,0x11,0x04, +0x84,0x01,0xEB,0x0A,0xDD,0x56,0x04,0x10,0x00,0x16,0x4E,0x00,0xFF,0xD4,0xC1,0x06, +0x00,0x10,0x00,0x50,0x54,0x10,0x80,0xFD,0xEA,0xE1,0x04,0x00,0x00,0x17,0x5A,0x08, +0xA5,0x11,0xFC,0x00,0x44,0x10,0x00,0x87,0xDD,0x56,0x14,0x10,0x00,0x17,0xF9,0x9A, +0x84,0x00,0xEB,0x42,0xEB,0x3F,0xEA,0x5D,0xEA,0xB5,0xEA,0xD3,0xDD,0x50,0xD5,0xFD, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x01,0x00, +0xDD,0x45,0xDD,0x9E,0xFC,0x00,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07, +0x96,0x00,0x58,0x00,0x30,0x00,0xDD,0x45,0xDD,0x56,0x04,0x10,0x00,0x3A,0x83,0xFF, +0x42,0x10,0xE0,0x0B,0xC1,0x08,0x44,0x10,0x00,0x49,0x12,0x10,0x00,0x0E,0x84,0x20, +0x12,0x10,0x00,0x0E,0x04,0x00,0x00,0x3A,0x42,0x00,0x68,0x0B,0xC0,0x04,0x84,0x02, +0x49,0xFF,0xFC,0x35,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00, +0x58,0x00,0x31,0x00,0xDD,0x45,0xFC,0x80,0xFC,0x01,0x80,0xC0,0x46,0x09,0x00,0x20, +0xA0,0x84,0xB6,0x46,0xA0,0x05,0xB6,0x01,0xB4,0x66,0x42,0x11,0xC4,0x0B,0xC9,0x04, +0x42,0x21,0xC0,0x0B,0xD5,0x03,0x84,0x41,0x80,0x22,0x42,0x01,0xC8,0x0B,0xC0,0x03, +0x84,0x41,0x84,0x22,0x42,0x01,0xCC,0x0B,0xC0,0x03,0x84,0x41,0x84,0x23,0x42,0x01, +0xD0,0x0B,0xC0,0x03,0x84,0x40,0x80,0x22,0x42,0x31,0xD4,0x0B,0xC3,0x08,0xEA,0x2B, +0x96,0x00,0xDD,0x58,0x49,0xFF,0xC9,0x8B,0x84,0x40,0x84,0x21,0xB4,0x06,0x42,0x00, +0x58,0x0B,0xC0,0x18,0x3C,0x0D,0xFF,0x65,0x5A,0x08,0x01,0x13,0xDD,0x4D,0x5A,0x08, +0x06,0x10,0x84,0x25,0x84,0x02,0xEA,0xAB,0x2E,0x17,0xFC,0xCB,0x8C,0x21,0x96,0x48, +0x3E,0x17,0xFC,0xCB,0x8C,0x21,0x94,0x09,0x54,0x00,0x00,0xFE,0xEA,0xDC,0x84,0x40, +0x84,0x22,0xB4,0x06,0x84,0xC1,0x42,0x00,0x5C,0x0B,0xC0,0x07,0xDD,0x4C,0xFE,0x36, +0xC0,0x19,0x80,0x06,0xEA,0xD0,0xD5,0x16,0xC2,0x10,0x5A,0x18,0x02,0x0B,0xF1,0x81, +0xEA,0xB5,0xF1,0x01,0x80,0x01,0x44,0x10,0x07,0xD0,0x49,0xFF,0xFC,0x0E,0xD5,0x0C, +0x80,0x06,0xEA,0x2E,0xEB,0x2D,0xD5,0x08,0x5A,0x10,0x02,0x07,0x84,0x00,0xEA,0x2E, +0xD5,0x03,0x84,0x23,0xD5,0xFC,0xFC,0x81,0xFC,0x20,0x46,0x60,0x00,0xCB,0x50,0x73, +0x08,0x02,0xDD,0x53,0x80,0x27,0x84,0x00,0xEA,0x5F,0x54,0x20,0x00,0x7F,0x80,0x27, +0x84,0x00,0xDD,0x4B,0x50,0x13,0x08,0x05,0x84,0x00,0xEA,0x5F,0x96,0x00,0x92,0x03, +0xFC,0xA0,0xFC,0x40,0x46,0x60,0x00,0xCB,0x50,0xA3,0x08,0x05,0x80,0x2A,0x80,0xE0, +0x84,0x00,0xEA,0x5F,0x50,0x63,0x08,0x02,0x81,0x20,0xDD,0x53,0x80,0x26,0x84,0x00, +0xEA,0x5F,0x54,0x20,0x00,0x7F,0x80,0x26,0x84,0x00,0xDD,0x4B,0x54,0x24,0x80,0x07, +0x40,0x21,0x1C,0x64,0x84,0x00,0x80,0x2A,0x96,0x90,0xDD,0x4B,0xFC,0xC0,0x2E,0x07, +0xFF,0x40,0xC0,0x34,0xFC,0x00,0xEA,0x76,0xA1,0x83,0x49,0xFF,0xFF,0xC7,0x46,0x21, +0x00,0x00,0x02,0x51,0x03,0x01,0x44,0x20,0xA5,0x5A,0x80,0x20,0xDA,0x09,0x46,0x21, +0x00,0x00,0x00,0x51,0x06,0x00,0xD0,0x04,0x00,0x01,0x06,0x00,0xD5,0x1C,0x3C,0x2D, +0xFF,0xD4,0xE2,0x46,0xE8,0x04,0xC0,0x12,0x8E,0x01,0xD5,0x08,0x3C,0x2D,0xFF,0xD5, +0xE2,0xC2,0xE8,0x06,0xE6,0x1F,0xE8,0x0A,0x8C,0x01,0x96,0x40,0xD5,0x07,0x44,0x0F, +0xA5,0x5A,0x46,0x21,0x00,0x00,0x12,0x01,0x03,0x01,0x46,0x01,0x00,0x00,0x10,0x10, +0x06,0x00,0x80,0x01,0x49,0xFF,0xFF,0xAF,0xFC,0x80,0xDD,0x9E,0x46,0x09,0x00,0x90, +0xEB,0x2B,0x58,0x10,0x80,0x04,0xEB,0x06,0x84,0x20,0x10,0x10,0x00,0x68,0xEB,0x4C, +0x54,0x10,0x80,0xFB,0xEA,0x60,0xDD,0x9E,0xC3,0x20,0xFC,0x00,0x3E,0x07,0xFF,0x40, +0x3C,0x1F,0xFF,0xD1,0x46,0x50,0x00,0xF4,0x3C,0x2F,0xFF,0xD2,0x99,0x8A,0x3C,0x3F, +0xFF,0xD3,0x8A,0x22,0x50,0x42,0x82,0x40,0x42,0x53,0x10,0x24,0xFF,0x0C,0x40,0x52, +0x8C,0xB7,0x40,0x32,0x0C,0x77,0x3C,0x5F,0xFF,0xD4,0x3C,0x3F,0xFF,0xD5,0xC0,0x07, +0x49,0xFF,0xFF,0xD6,0x84,0x00,0xD5,0x03,0xFA,0x00,0xDD,0x9E,0xFC,0x80,0x46,0x09, +0x00,0x90,0xEB,0x2B,0xEA,0xB2,0xEB,0x06,0x84,0x20,0x10,0x10,0x00,0x64,0xEB,0x4C, +0x54,0x10,0x80,0xFD,0xEA,0x60,0xDD,0x9E,0x46,0x09,0x00,0x90,0xEB,0x2B,0x58,0x10, +0x80,0x01,0xEB,0x06,0x84,0x2F,0xEA,0x2F,0xEB,0x4C,0x54,0x10,0x80,0xFE,0xEA,0x60, +0xDD,0x9E,0x3E,0x07,0xFD,0xA0,0x84,0x60,0x3E,0x37,0xFD,0xA1,0x3E,0x17,0xFD,0xA2, +0x3E,0x17,0xFD,0xA3,0x3E,0x27,0xFD,0xA4,0xC0,0x07,0xFC,0x00,0x49,0xFF,0xFF,0xD9, +0x49,0xFF,0xFF,0xE4,0xFC,0x80,0xDD,0x9E,0xFC,0x20,0x46,0x08,0x00,0x50,0x46,0x69, +0x00,0x00,0x84,0xE0,0xB4,0x00,0x12,0x73,0x00,0x4C,0x46,0x00,0x00,0x0F,0x04,0x00, +0x02,0xC0,0xEA,0x8B,0xC8,0x2F,0x3E,0x77,0xFF,0x40,0x44,0x10,0x01,0xF4,0x3C,0x1F, +0xFF,0xD1,0x84,0x2A,0x3C,0x1F,0xFF,0xD2,0x44,0x10,0x02,0x58,0x3C,0x1F,0xFF,0xD3, +0x46,0x10,0x00,0xCF,0x50,0x10,0x88,0x50,0x3C,0x1F,0xFF,0xD4,0x46,0x10,0x00,0xC7, +0x50,0x10,0x86,0x1A,0x3C,0x1F,0xFF,0xD5,0x44,0x10,0x00,0x80,0x84,0x45,0x49,0xFF, +0xFF,0xC2,0x49,0xFF,0xFD,0x79,0x49,0x00,0x05,0x44,0x84,0x09,0xEB,0x42,0xEB,0x3F, +0xEA,0x5D,0xEA,0x48,0xC8,0x07,0x44,0x10,0x00,0xDA,0x12,0x13,0x00,0x1A,0x12,0x13, +0x00,0x1E,0xFC,0xA0,0x2E,0x07,0xFD,0xA0,0xC0,0x09,0x46,0x19,0x00,0x90,0xA6,0x08, +0xEA,0x37,0xAE,0x08,0x84,0x01,0x3E,0x07,0xFD,0xA1,0xDD,0x9E,0x2E,0x07,0xFD,0xA0, +0xC0,0x10,0xEB,0x4A,0xEA,0x76,0x5A,0x18,0x08,0x09,0xA0,0x41,0x84,0x20,0x3E,0x17, +0xFD,0xA1,0x00,0x00,0x00,0x60,0xD5,0x05,0xA0,0x02,0x84,0x00,0x3E,0x07,0xFD,0xA1, +0x84,0x00,0xDD,0x9E,0x46,0x28,0x00,0x20,0x02,0x11,0x00,0x9C,0x02,0x31,0x00,0x0A, +0x02,0x01,0x00,0x0A,0x8A,0x23,0x96,0x4B,0x8E,0x09,0x96,0x01,0x9E,0xC9,0x12,0x01, +0x00,0x94,0x84,0x80,0x46,0x09,0x00,0x68,0x96,0xD9,0xAF,0x00,0xAC,0xC2,0x10,0x40, +0x00,0x08,0x84,0x83,0x10,0x40,0x00,0x0C,0x02,0x41,0x00,0x9A,0x46,0x22,0x00,0x00, +0x40,0x21,0x10,0x56,0x8C,0x41,0x90,0x41,0xA8,0x85,0xEA,0xEF,0x10,0x20,0x00,0x20, +0x46,0x20,0x40,0x00,0x40,0x11,0x04,0x36,0x8C,0x21,0x90,0x21,0x14,0x10,0x00,0x09, +0x84,0x21,0x12,0x30,0x00,0x14,0xAE,0x40,0xDD,0x9E,0x00,0x00,0xFC,0x01,0x3F,0xCF, +0xFD,0x90,0xF1,0x81,0xBA,0x00,0xBA,0x82,0xB8,0x80,0xB6,0x1F,0x2E,0x27,0xFF,0x5A, +0x92,0x47,0x3E,0x27,0xFF,0x40,0x84,0x41,0x3E,0x27,0xFC,0xC5,0x3E,0x27,0xFC,0xC3, +0x49,0xFF,0xFD,0x02,0xF1,0x01,0xB4,0x1F,0xC1,0x03,0x49,0xFF,0xF3,0x33,0xB8,0x00, +0x9E,0x42,0xE6,0x27,0xE8,0x20,0x3E,0xFF,0xDF,0xE4,0x38,0x17,0x84,0x00,0x40,0xF0, +0xBC,0x00,0xDD,0x0F,0x08,0x08,0x08,0x08,0x16,0x1E,0x26,0x00,0xEB,0x3E,0xEA,0x90, +0x2E,0x27,0xFD,0x31,0x84,0x20,0xE2,0x22,0xD5,0x0C,0x84,0x26,0xEA,0x90,0x85,0xE2, +0xD5,0x08,0xEB,0x3E,0xEA,0x90,0x85,0xE0,0xD5,0x04,0x84,0x26,0xEA,0x90,0x85,0xE1, +0x3C,0xFF,0xFF,0x6A,0xEA,0xCB,0xEA,0x8E,0xC1,0x03,0x84,0x22,0xB9,0x81,0xB9,0x06, +0x49,0xFF,0xFB,0x42,0xC8,0x2F,0xB9,0x00,0x8E,0x27,0xE6,0x22,0xE8,0x25,0x46,0x11, +0x00,0x07,0x04,0x50,0x83,0xC4,0x46,0x1A,0x55,0xAA,0x50,0x10,0x85,0x5A,0xD1,0x1C, +0x2E,0x17,0xFF,0x5B,0xEB,0x38,0xC9,0x18,0x46,0x01,0x00,0x07,0xEA,0x62,0xEA,0x47, +0xEA,0x3F,0xD8,0x06,0x44,0x11,0xFF,0x00,0xDD,0x56,0x14,0x10,0x00,0x30,0x84,0x05, +0xEA,0x54,0xEA,0xB5,0x84,0x20,0xDD,0x43,0xEA,0xF4,0x44,0x10,0x07,0xD0,0x84,0x02, +0x49,0xFF,0xFA,0x3B,0xD5,0x07,0xB6,0x1F,0x49,0xFF,0xFF,0x5E,0x49,0xFF,0xFC,0xFA, +0xB4,0x1F,0xFC,0x81,0x92,0x00,0x46,0x18,0x00,0x20,0x50,0x10,0x85,0xC8,0xA6,0x88, +0xDD,0x43,0xCA,0xFE,0xFC,0x00,0x84,0x21,0x10,0x10,0x02,0xA0,0xEB,0x4A,0x5A,0x18, +0x07,0x0C,0x46,0x10,0x00,0x0D,0x02,0x10,0x82,0x6C,0xEA,0xF4,0x46,0x10,0x00,0x0D, +0x02,0x10,0x82,0x6D,0xD5,0x0C,0x5A,0x18,0x08,0x0D,0x46,0x10,0x00,0x0D,0x02,0x10, +0x83,0x42,0xEA,0xF4,0x46,0x10,0x00,0x0D,0x02,0x10,0x83,0x43,0x12,0x10,0x00,0xB6, +0xEA,0x27,0x02,0x00,0x82,0xB8,0x02,0x10,0x80,0xB6,0x49,0xFF,0xC5,0x10,0xEA,0x8B, +0xFC,0x80,0x46,0x08,0x00,0x20,0x00,0x10,0x00,0xF8,0xEB,0x4D,0xEA,0xB2,0x10,0x10, +0x7D,0xBC,0xEA,0xC1,0xEA,0x81,0xB4,0xA0,0xD9,0xFF,0xDD,0x9E,0xC0,0x04,0xFC,0x00, +0xEA,0x5A,0xFC,0x80,0xEA,0x3C,0x04,0x00,0x80,0x30,0x66,0x00,0x00,0x01,0x14,0x00, +0x80,0x30,0xDD,0x9E,0xFC,0x21,0x3F,0xCF,0xFD,0x90,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x50,0x00,0xDD,0x45,0x46,0x69,0x00,0x20, +0x04,0x03,0x00,0x0A,0xB6,0x1F,0xB4,0x1F,0xEB,0x14,0xB6,0x1F,0xF0,0x81,0xF0,0x01, +0x66,0x00,0x00,0x04,0xF0,0x81,0xB6,0x1F,0xB4,0x3F,0x84,0x00,0x49,0x00,0x04,0x9B, +0x80,0x1F,0xB0,0x41,0x49,0xFF,0xFD,0x62,0xB4,0x1F,0x42,0x00,0x2C,0x0B,0xC0,0x19, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x51,0x00, +0xDD,0x45,0xB4,0x06,0x66,0x00,0x08,0x00,0xB6,0x06,0xB8,0x00,0x8E,0x07,0xE6,0x02, +0xE8,0x08,0x84,0x00,0x49,0xFF,0xFF,0xBC,0xEA,0x5E,0x84,0x21,0x10,0x10,0x00,0xA0, +0xB4,0x1F,0x42,0x00,0x28,0x0B,0xC0,0x33,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11, +0x00,0x07,0x96,0x00,0x58,0x00,0x52,0x00,0xDD,0x45,0xEA,0x43,0xB4,0x01,0x66,0x00, +0x04,0x00,0xB6,0x01,0xB8,0x00,0x5A,0x08,0x02,0x09,0xEB,0x13,0x5A,0x08,0x01,0x06, +0x84,0x06,0xB8,0x80,0x84,0x04,0xD5,0x0A,0xEB,0x13,0xC8,0x0A,0xB8,0x00,0x8E,0x03, +0xE6,0x03,0xE8,0x06,0x84,0x02,0xB8,0x80,0x84,0x03,0x49,0x00,0x05,0x40,0xB8,0x01, +0x5A,0x08,0x02,0x0E,0xB8,0x00,0x5A,0x08,0x06,0x05,0xB8,0x02,0x5A,0x00,0x02,0x04, +0x2E,0x07,0xFC,0xBB,0x49,0xFF,0xFD,0x8F,0x84,0x00,0xB8,0x81,0xB4,0x1F,0x42,0x00, +0x4C,0x0B,0xC0,0x0D,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00, +0x58,0x00,0x53,0x00,0xDD,0x45,0x84,0x00,0x49,0xFF,0xFF,0x72,0xF0,0x01,0x42,0x00, +0x38,0x0B,0xC0,0x04,0x49,0xFF,0xF8,0xF3,0xD5,0x07,0xF0,0x01,0x42,0x00,0x3C,0x0B, +0xC0,0x03,0x49,0xFF,0xF8,0xF6,0xF0,0x01,0x84,0xC1,0x42,0x00,0x0C,0x0B,0xC0,0x16, +0xDD,0x43,0x00,0x00,0x03,0x40,0xB9,0x00,0x96,0x00,0x5A,0x18,0x06,0x10,0x54,0x00, +0x00,0xFB,0xC8,0x0C,0xB8,0x01,0x5A,0x00,0x02,0x0A,0x84,0x25,0x84,0x02,0xEA,0xAB, +0x3E,0x67,0xFC,0xCB,0x84,0x04,0xEA,0xDC,0xBE,0x81,0xF6,0x01,0x84,0xE1,0x42,0x63, +0x04,0x0B,0x4E,0x62,0x00,0x39,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07, +0x96,0x00,0x58,0x00,0x54,0x00,0xDD,0x45,0x84,0x00,0x80,0x27,0xEA,0xBA,0x49,0xFF, +0xF9,0x5C,0x84,0x0E,0xDD,0x40,0xC0,0x04,0x49,0xFF,0xC3,0xFB,0xD5,0x20,0xFA,0x02, +0xDD,0x40,0xC8,0xFB,0xFA,0x06,0xDD,0x40,0xC8,0xF8,0x84,0x0A,0xDD,0x40,0xC8,0xF5, +0xFA,0x0A,0xDD,0x40,0xC8,0xF2,0xFA,0x13,0xDD,0x40,0xC8,0xEF,0xFA,0x0E,0xDD,0x40, +0xC8,0xEC,0xFA,0x18,0xDD,0x40,0xC8,0xE9,0xFA,0x1C,0xDD,0x40,0xC8,0xE6,0xDD,0x47, +0xDD,0x40,0xC8,0xE3,0x84,0x07,0x84,0x21,0x49,0xFF,0xFE,0x62,0x84,0x00,0x3E,0x07, +0xFF,0x3F,0xD5,0x24,0xF0,0x01,0xEA,0xA5,0xC0,0x21,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x55,0x00,0xDD,0x45,0x3E,0x67,0xFC,0xC7, +0x80,0x26,0x3E,0x67,0xFC,0xCC,0x80,0x06,0xEA,0xBA,0x49,0xFF,0xF9,0x1E,0x80,0x27, +0x2E,0x07,0xFF,0x5E,0x49,0xFF,0xFE,0x44,0xDD,0x53,0x46,0x10,0x00,0xBC,0x80,0x06, +0x8C,0x21,0x84,0x46,0xDD,0x4B,0x3E,0x77,0xFF,0x3F,0x46,0x01,0x00,0x07,0xDD,0x46, +0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x56,0x00,0xDD,0x45,0xFC,0xA1,0xFC,0x00, +0xE6,0x04,0xE8,0x03,0x8E,0x01,0xD5,0x1B,0x5A,0x00,0x04,0x04,0x5A,0x08,0x08,0x14, +0x84,0x00,0x46,0x11,0x00,0x05,0x58,0x10,0x88,0x88,0x84,0x44,0xF8,0x17,0xEA,0x2B, +0xC0,0x16,0x2E,0x07,0xFD,0x27,0x3E,0x07,0xFD,0x29,0x8C,0x01,0x96,0x04,0x3E,0x07, +0xFD,0x27,0xD5,0x0D,0x8E,0x05,0x96,0x40,0xE6,0x23,0xE8,0x09,0x84,0x23,0x40,0x10, +0x04,0x16,0x84,0x44,0x96,0x00,0xEB,0x5B,0xEA,0x7B,0xEA,0xAC,0xFC,0x80,0xFC,0x00, +0x54,0x10,0x00,0xFB,0x5A,0x10,0x03,0x04,0x48,0x00,0x00,0x71,0xF8,0x75,0xB4,0xA2, +0xDD,0x43,0xD9,0xFE,0xEB,0x11,0x44,0x10,0xFE,0xFF,0x83,0xFF,0xF8,0x03,0x44,0x10, +0xFD,0xFF,0xFE,0x56,0xEA,0x34,0xEB,0x11,0x83,0xFF,0x44,0x10,0xFB,0xFF,0x4E,0x00, +0xFF,0xFA,0x44,0x10,0xF7,0xFF,0xFE,0x56,0xEA,0x34,0x83,0xFF,0xFA,0x20,0xEA,0x60, +0x10,0x10,0x00,0x48,0xEB,0x31,0x2E,0x17,0xFD,0x27,0xC1,0x22,0x5A,0x10,0x01,0x03, +0xF8,0x51,0xEB,0x6E,0x02,0x51,0x06,0x8E,0xEB,0x6E,0x02,0x41,0x06,0x8F,0xEB,0x6E, +0x02,0x31,0x06,0x8D,0xEB,0x6E,0x02,0x21,0x06,0x8B,0xF8,0x1E,0xEB,0x6E,0x04,0x21, +0x03,0x37,0x83,0x80,0xBA,0x8E,0x84,0x40,0x10,0x20,0x02,0x38,0x46,0x20,0x08,0x09, +0x50,0x21,0x0A,0x12,0xBA,0x8E,0x50,0x00,0x01,0x9C,0xAE,0x40,0xD5,0x2A,0xEB,0x6E, +0x02,0x51,0x05,0xB8,0xEB,0x6E,0x02,0x41,0x05,0xB9,0xEB,0x6E,0x02,0x31,0x05,0xB7, +0xEB,0x6E,0x02,0x21,0x05,0xB5,0x12,0x50,0x00,0x9C,0x12,0x40,0x00,0x0A,0x12,0x30, +0x00,0x9A,0x12,0x20,0x00,0x8A,0x83,0xFF,0xEB,0x6E,0x04,0x21,0x02,0xCC,0x83,0x80, +0xBA,0x8E,0xEA,0x79,0x46,0x10,0x08,0x09,0x50,0x10,0x8A,0x12,0xB9,0x8E,0x84,0x21, +0x10,0x10,0x01,0x9C,0x50,0x00,0x01,0x9C,0xA6,0x40,0x5A,0x10,0x01,0xFF,0xF8,0x04, +0xA6,0x40,0x5A,0x10,0x01,0xFF,0x48,0x00,0x00,0x6F,0x5A,0x00,0x04,0x06,0x5A,0x00, +0x08,0x04,0x48,0x00,0x00,0x6B,0x46,0x28,0x00,0x20,0xEA,0xC1,0x50,0x21,0x03,0x3C, +0xEA,0x81,0x83,0xFF,0xB4,0xA2,0xDD,0x43,0xD9,0xFE,0x83,0x80,0xB9,0x0E,0x42,0x10, +0xD4,0x09,0xB9,0x8E,0xEB,0x08,0xC9,0x24,0xEB,0x5E,0x00,0x30,0x8B,0x8D,0xEB,0x5E, +0x00,0x20,0x8B,0x8E,0xEB,0x5E,0x00,0x10,0x8B,0x8F,0xF8,0x23,0xEB,0x5E,0x02,0x40, +0x85,0xB8,0xEB,0x5E,0x02,0x30,0x85,0xB9,0xEB,0x5E,0x02,0x20,0x85,0xB7,0xEB,0x5E, +0x02,0x10,0x85,0xB5,0xF8,0x28,0xEB,0x5E,0x04,0x10,0x82,0xCC,0xEB,0x1D,0xEB,0x5E, +0x02,0x10,0x85,0xB6,0xEA,0x34,0xEB,0x5E,0x00,0x10,0x8B,0x8B,0xD5,0x30,0xEB,0x5E, +0x00,0x30,0x8D,0x39,0xEB,0x5E,0x00,0x20,0x8D,0x3A,0xEB,0x5E,0x00,0x10,0x8D,0x3B, +0x10,0x30,0x00,0x44,0x10,0x20,0x00,0x48,0xEB,0x31,0x83,0xFF,0xEB,0x5E,0x02,0x40, +0x86,0x8E,0xEB,0x5E,0x02,0x30,0x86,0x8F,0xEB,0x5E,0x02,0x20,0x86,0x8D,0xEB,0x5E, +0x02,0x10,0x86,0x8B,0x12,0x40,0x00,0x9C,0x12,0x30,0x00,0x0A,0x12,0x20,0x00,0x9A, +0x12,0x10,0x00,0x8A,0x83,0xFF,0xEB,0x5E,0x04,0x10,0x83,0x37,0xEB,0x1D,0xEB,0x5E, +0x02,0x10,0x86,0x8C,0xEA,0x34,0xEB,0x5E,0x00,0x10,0x8D,0x37,0xEA,0x79,0x84,0x21, +0x10,0x10,0x01,0x9C,0x49,0xFF,0xFC,0xF0,0xFC,0x80,0x00,0x00,0xFC,0x20,0x3F,0xCF, +0xFD,0x90,0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00, +0x10,0x00,0xDD,0x45,0xDD,0x43,0x84,0x20,0x10,0x10,0x00,0x88,0x00,0x60,0x03,0x40, +0xEA,0x57,0x97,0xB0,0xEB,0x1B,0xC0,0x0B,0xB8,0x00,0x5A,0x08,0x06,0x09,0x84,0x22, +0x84,0x00,0xEA,0x2E,0x84,0x02,0xEA,0xDC,0x84,0x00,0xB8,0x81,0xDD,0x4D,0x8E,0x02, +0xE6,0x07,0x4E,0xF2,0x01,0xA2,0x3E,0xFF,0xE5,0xB4,0x38,0x07,0x81,0x01,0x40,0xF0, +0x3C,0x00,0xDD,0x0F,0x0E,0x00,0x32,0x03,0x32,0x03,0x32,0x03,0x7C,0x01,0xAA,0x01, +0x6E,0x02,0xDD,0x56,0x04,0x10,0x00,0x3A,0x9F,0xF1,0xEA,0xDA,0x84,0x01,0xC1,0x09, +0x46,0x11,0x00,0x07,0xEA,0xD8,0x40,0x00,0x1C,0x0C,0x40,0x00,0x80,0x12,0xD5,0x08, +0x46,0x11,0x00,0x07,0xEA,0xD8,0x40,0x00,0x1C,0x0C,0xFE,0x0F,0x96,0x01,0x46,0x11, +0x00,0x07,0xEA,0x99,0x46,0x01,0x00,0x07,0x02,0x10,0x07,0xF4,0x44,0x00,0xDF,0xFF, +0xFE,0x0E,0x46,0x11,0x00,0x07,0xEA,0x99,0xEA,0xD8,0x44,0x00,0xBF,0xFF,0xFE,0x0E, +0x46,0x11,0x00,0x07,0xEA,0x99,0x02,0x00,0x87,0xF4,0x54,0x00,0x7F,0xFF,0xEA,0x99, +0x84,0x00,0x3E,0x07,0xFF,0x3E,0x84,0x0E,0xDD,0x40,0xC0,0x05,0x80,0x06,0x49,0xFF, +0xBF,0x93,0xEA,0x63,0xFA,0x02,0xDD,0x40,0xC8,0xFA,0xFA,0x06,0xDD,0x40,0xC8,0xF7, +0x5A,0x60,0x01,0x04,0x48,0x00,0x01,0x53,0xDD,0x43,0x84,0x22,0xEA,0x58,0x84,0x23, +0xEA,0x46,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x97,0xF8,0xE6,0xE8,0xE8,0x04,0x80,0x06, +0x49,0xFF,0xFE,0x6F,0x9E,0x33,0xE6,0x02,0xE9,0x08,0x9E,0x37,0xE6,0x02,0xE9,0x05, +0x5A,0x60,0x08,0x03,0xEA,0x63,0xD5,0x0F,0x80,0x06,0x49,0xFF,0xFE,0x8A,0x5A,0x60, +0x04,0x05,0x5A,0x60,0x08,0x03,0xEA,0x63,0xB8,0x00,0x49,0xFF,0xF1,0x4B,0x5A,0x60, +0x04,0x13,0xD5,0xEF,0x84,0x01,0x44,0x10,0x04,0xA6,0xEA,0xAB,0x2E,0x07,0xFC,0xC7, +0xC8,0x1A,0xEA,0x76,0xA6,0x40,0xEA,0xB2,0xAE,0x40,0xA6,0x40,0x58,0x10,0x80,0x04, +0xAE,0x40,0xD5,0x11,0xEA,0x2B,0x96,0x00,0xDD,0x58,0x49,0xFF,0xC4,0x60,0xEB,0x13, +0x5A,0x00,0x01,0x04,0x48,0x00,0x00,0x4A,0xEA,0x43,0xB4,0x01,0x58,0x00,0x04,0x00, +0xB6,0x01,0xD5,0x43,0x2E,0x07,0xFC,0xC7,0x8C,0x01,0x96,0x00,0xE6,0x04,0xE8,0x03, +0xEA,0xF1,0xD5,0x3B,0x84,0x00,0xEA,0xF1,0xDD,0x43,0x00,0x10,0x03,0x20,0x5A,0x10, +0x10,0x06,0x00,0x10,0x03,0x20,0x5A,0x18,0x06,0x31,0xEA,0xC1,0xEB,0x4D,0xEA,0x81, +0xB4,0xA0,0xD9,0xFF,0x46,0x19,0x00,0x90,0xA6,0x08,0xC8,0xFF,0x49,0xFF,0xFB,0x21, +0xEA,0x57,0xEB,0x1B,0xC0,0x09,0x2E,0x0F,0xFF,0x5A,0x4E,0x04,0x00,0x06,0x49,0xFF, +0xFA,0xE5,0x3E,0x07,0xFC,0xBB,0x49,0xFF,0xFB,0xF3,0xC0,0x17,0x48,0x00,0x00,0xE5, +0x8E,0xC1,0xE6,0xC2,0x4E,0xF2,0x00,0xCE,0xDD,0x43,0x84,0x22,0xEA,0x58,0x84,0x23, +0xEA,0x46,0xEA,0x42,0xE6,0x01,0xEA,0x66,0x84,0x44,0x84,0x00,0xEB,0x5B,0xEA,0x7B, +0xEA,0xAC,0xEA,0x2B,0x96,0x00,0xDD,0x58,0x49,0xFF,0xB5,0xEE,0xEA,0x63,0x5A,0x68, +0x01,0x0A,0xDD,0x43,0x84,0x22,0xEA,0x58,0x84,0x23,0xEA,0x46,0xEA,0x42,0xE6,0x01, +0xEA,0x66,0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x00,0x00,0xBC,0xA6,0x40, +0xC9,0xFF,0xEA,0x64,0xE6,0x03,0xEA,0x64,0xE9,0x0C,0x8E,0x02,0xE0,0xC0,0xE9,0x11, +0xEA,0x64,0xE2,0x06,0xE9,0x0E,0x2E,0x17,0xFC,0xC6,0x9C,0x32,0x8A,0x01,0xD5,0x04, +0xE2,0x06,0xE9,0x07,0x9E,0x31,0x96,0x00,0xEB,0x5B,0xEA,0x7B,0x84,0x44,0xEA,0xAC, +0xEA,0x64,0x4C,0x60,0x40,0x35,0x84,0xC1,0xDD,0x43,0x12,0x60,0x02,0xE0,0xEA,0x2B, +0x96,0x00,0xDD,0x58,0xEA,0x5A,0xEA,0x5E,0xEA,0xFE,0xEA,0x43,0xB4,0x01,0xEA,0xF6, +0xB6,0x01,0x2E,0x07,0xFF,0x3E,0xE6,0x09,0xE9,0x04,0x84,0x04,0xEA,0x54,0xD5,0x02, +0xEB,0x2D,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D,0x80,0x26,0x44,0x20,0x00,0xAA, +0x84,0x00,0xDD,0x4B,0x44,0x00,0x02,0xBC,0xDD,0x50,0x84,0x00,0x80,0x26,0x44,0x20, +0x00,0xBA,0xDD,0x4B,0x2E,0x07,0xFF,0x3E,0xE6,0x14,0xE8,0x04,0x8C,0x01,0x3E,0x07, +0xFF,0x3E,0xEA,0x7D,0x4E,0x02,0x00,0x5E,0x84,0x01,0xD5,0x02,0x84,0x02,0xEA,0x54, +0xEA,0x63,0xEA,0x9D,0x4C,0x60,0x40,0x56,0x49,0xFF,0xFB,0x66,0x2E,0x17,0xFC,0xCD, +0xDD,0x43,0x5A,0x10,0x01,0x05,0x84,0x22,0x10,0x10,0x00,0xB4,0x84,0xC1,0x84,0x22, +0x10,0x60,0x01,0xCC,0xEA,0x58,0x84,0x23,0xEA,0x46,0xEA,0x5A,0xEA,0x5E,0xEA,0xFE, +0xEA,0x43,0xB4,0x01,0xEA,0xF6,0xB6,0x01,0xEA,0x9D,0x5A,0x08,0x01,0x18,0xB8,0x00, +0x5A,0x08,0x08,0x15,0x46,0x60,0x00,0xD8,0x50,0x63,0x0C,0x0D,0x49,0xFF,0xFC,0x3B, +0x80,0x26,0x44,0x20,0x00,0xAA,0x84,0x00,0xDD,0x4B,0x44,0x00,0x02,0xBC,0xDD,0x50, +0x84,0x00,0x80,0x26,0x44,0x20,0x00,0xBA,0xDD,0x4B,0xEA,0x42,0xE6,0x01,0xEA,0x66, +0x84,0x44,0x84,0x00,0xEB,0x5B,0xEA,0x7B,0xEA,0xAC,0xEA,0x9D,0x5A,0x00,0x01,0x0E, +0xDD,0x43,0x84,0x21,0x10,0x10,0x00,0xBC,0x50,0x10,0x00,0xBC,0xA6,0x08,0x96,0x00, +0xC8,0xFE,0xEA,0x27,0x10,0x00,0x80,0xB4,0xDD,0x43,0x84,0xC1,0x12,0x60,0x02,0xE0, +0xEA,0x2B,0x96,0x00,0xDD,0x58,0x84,0x04,0xEA,0x54,0xEA,0x7D,0xC0,0x02,0xEB,0x2D, +0x46,0x01,0x00,0x07,0xDD,0x46,0x46,0x11,0x00,0x07,0x96,0x00,0x58,0x00,0x11,0x00, +0xDD,0x45,0x84,0x00,0xD5,0x09,0xFA,0x02,0xD5,0x07,0x5A,0x60,0x05,0x04,0x48,0xFF, +0xFE,0xB5,0x48,0xFF,0xFE,0xB0,0xFC,0xA0,0xFC,0x00,0x84,0x00,0xEA,0xD0,0x2E,0x27, +0xFF,0xA8,0x84,0x2A,0xFE,0x54,0x84,0x03,0xEA,0xAB,0xFC,0x80,0x2E,0x07,0xFF,0x3F, +0xDD,0x9E,0x8E,0x01,0xC0,0x03,0xEA,0x6D,0xD5,0xFD,0xDD,0x9E,0xFC,0x01,0x10,0x0F, +0x80,0x07,0x10,0x1F,0x80,0x06,0x46,0x08,0x00,0x30,0x84,0x20,0x10,0x2F,0x80,0x05, +0x10,0x10,0x00,0x0C,0x10,0x10,0x00,0x10,0x84,0x21,0x10,0x10,0x00,0x14,0x00,0x1F, +0x80,0x07,0x96,0x48,0x10,0x10,0x00,0x34,0x00,0x1F,0x80,0x06,0x96,0x48,0x10,0x10, +0x00,0x38,0x00,0x1F,0x80,0x05,0x96,0x48,0x10,0x10,0x00,0x3C,0xFC,0x81,0x84,0x00, +0x46,0x21,0x00,0x05,0x58,0x21,0x0A,0x38,0x96,0x40,0x38,0x11,0x00,0x08,0x50,0x30, +0x00,0x6C,0x56,0x10,0x80,0x80,0x8C,0x01,0x38,0x11,0x0C,0x08,0x5A,0x08,0x6C,0xF6, +0xDD,0x9E,0x46,0x38,0x00,0x30,0xA6,0x98,0x46,0x18,0x00,0x30,0x96,0x90,0x83,0xFF, +0xCA,0xFB,0xFA,0x6C,0x10,0x20,0x81,0xB4,0xAE,0xCC,0x10,0x00,0x80,0xC4,0x84,0x05, +0x10,0x20,0x80,0x18,0x10,0x20,0x81,0x18,0x10,0x00,0x80,0x0C,0x84,0x01,0xEA,0xFD, +0x83,0xFF,0xDD,0x9E,0x46,0x08,0x00,0x30,0x14,0x10,0x00,0x32,0x44,0x1F,0xFF,0xD8, +0x10,0x10,0x00,0x34,0x10,0x10,0x00,0x38,0x84,0x20,0x10,0x10,0x00,0xC0,0x46,0x11, +0x00,0x05,0x58,0x10,0x8A,0x38,0x12,0x10,0x00,0x5C,0x96,0x91,0x84,0x21,0x12,0x20, +0x00,0x5E,0xAE,0x40,0xA6,0x40,0xC9,0xFF,0xDD,0x9E,0x46,0x19,0x00,0x28,0x10,0x00, +0x80,0x68,0xDD,0x9E,0x96,0x00,0x46,0x19,0x00,0x28,0x10,0x00,0x80,0x60,0xDD,0x9E, +0x46,0x08,0x00,0x20,0x00,0x00,0x04,0xB4,0xDD,0x9E,0xE6,0x24,0xE8,0x09,0x94,0x4D, +0xC0,0x03,0xEB,0x37,0xD5,0x03,0x46,0x09,0x00,0x10,0x88,0x20,0xB6,0x41,0xDD,0x9E, +0xE6,0x24,0xE8,0x0C,0x94,0x4D,0x96,0x90,0xC0,0x04,0xEB,0x37,0x8C,0x10,0xD5,0x04, +0x46,0x09,0x00,0x10,0x8C,0x08,0x88,0x20,0xAE,0x88,0xDD,0x9E,0xE6,0x24,0xE8,0x1C, +0x94,0x4D,0xC0,0x10,0xEB,0x37,0x50,0x30,0x00,0x10,0x88,0x61,0x84,0x42,0xAE,0x98, +0xA6,0x98,0x96,0x90,0xCA,0xFE,0x8C,0x0C,0x88,0x20,0xAE,0x88,0xA6,0x08,0xC8,0xFF, +0xDD,0x9E,0x46,0x29,0x00,0x10,0x8C,0x48,0x88,0x22,0xAE,0x08,0x44,0x00,0x00,0x40, +0xAE,0x08,0xA6,0x08,0xC8,0xFF,0xDD,0x9E,0x46,0x29,0x00,0x20,0xB6,0x02,0xA8,0x51, +0xDD,0x9E,0x46,0x29,0x00,0x20,0x14,0x01,0x00,0x09,0x14,0x11,0x00,0x0A,0xDD,0x9E, +0x46,0x18,0x00,0x60,0xB6,0x01,0xDD,0x9E,0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x03, +0xD0,0x16,0x46,0x01,0x00,0x00,0xEA,0x4D,0x44,0x00,0xA3,0x3A,0xD0,0x10,0x46,0x01, +0x00,0x00,0xEA,0x4D,0xEB,0x05,0xD0,0x0B,0x46,0x01,0x00,0x00,0x02,0x00,0x00,0x00, +0x84,0x20,0x50,0x00,0x45,0x5D,0x40,0x00,0x80,0x06,0xDD,0x9E,0x84,0x00,0xDD,0x9E, +0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x05,0xD0,0x07,0x46,0x01,0x00,0x00,0xEA,0x4D, +0x44,0x00,0x3A,0xA3,0xD8,0x3F,0xEA,0x9E,0xC0,0x3D,0xFC,0x20,0x49,0xFF,0xBB,0x0B, +0xEA,0x7A,0xEA,0x31,0x84,0xA0,0x98,0x50,0x42,0x11,0x00,0x73,0x2E,0x07,0xFF,0xBA, +0x46,0x31,0x00,0x00,0x58,0x31,0x80,0x04,0x88,0x20,0x3C,0x23,0xFE,0x9D,0x44,0x60, +0x5A,0xA5,0x80,0x05,0xD1,0x11,0x46,0x41,0x00,0x00,0x02,0x42,0x00,0x00,0x4C,0x43, +0x00,0x06,0x99,0x2A,0x40,0x42,0x04,0xF7,0xAD,0xD8,0x0A,0x41,0x80,0x01,0x8C,0xA1, +0x88,0x04,0x96,0x01,0xD5,0xF0,0xFE,0x02,0x96,0x01,0xEB,0x5B,0x12,0x00,0x80,0x01, +0x46,0x01,0x00,0x00,0xEA,0x4D,0xEB,0x05,0xD8,0x04,0x44,0x0F,0xA5,0x5A,0xD5,0x03, +0x44,0x0F,0xA3,0x3A,0xEB,0x5B,0x12,0x00,0x80,0x00,0x8C,0x41,0x3C,0x2B,0xFE,0x9D, +0xFC,0xA0,0xDD,0x9E,0xFC,0x00,0xF8,0x15,0x42,0x10,0x8C,0x0B,0xC9,0x08,0xF8,0x1C, +0xC9,0x06,0x02,0x00,0x00,0x72,0x42,0x00,0x28,0x0B,0xC0,0x36,0xDD,0x4C,0x96,0x04, +0xC0,0x08,0x46,0x09,0x00,0x28,0x84,0x21,0x10,0x10,0x00,0x68,0x84,0x22,0xEA,0x2F, +0xDD,0x56,0x02,0x10,0x00,0x72,0x83,0xFF,0xEA,0xDA,0xC1,0x06,0x46,0x0E,0xBE,0xBE, +0x50,0x00,0x0B,0xEB,0xD5,0x14,0x02,0x10,0x00,0x72,0xEB,0x38,0x83,0xFF,0xC1,0x06, +0x46,0x0E,0xCE,0xCE,0x50,0x00,0x0C,0xEC,0xD5,0x0A,0x02,0x00,0x00,0x72,0x42,0x00, +0x0C,0x0B,0xC0,0x07,0x46,0x0E,0xDE,0xDE,0x50,0x00,0x0D,0xED,0x49,0xFF,0xB2,0x82, +0xDD,0x4C,0x96,0x04,0xC0,0x05,0xEA,0x7D,0xC0,0x03,0x49,0xFF,0xFE,0x8F,0x44,0x00, +0x13,0x88,0x49,0xFF,0xB2,0x6C,0xFC,0x80,0xFC,0x00,0xEA,0x48,0xDD,0x53,0xEA,0xCE, +0x84,0x20,0x84,0x41,0xEA,0x3B,0x5A,0x08,0xEE,0x04,0x84,0x00,0xD5,0x20,0xEA,0xCE, +0x84,0x20,0x84,0x41,0xEA,0x3B,0x5A,0x08,0xDE,0x04,0x84,0x01,0xD5,0x18,0xEA,0xCE, +0x84,0x20,0x84,0x41,0xEA,0x3B,0x5A,0x08,0xCE,0x17,0x44,0x00,0x00,0xE8,0x84,0x20, +0x84,0x46,0xEA,0x3B,0x5A,0x08,0x03,0x04,0x84,0x02,0xD5,0x09,0x44,0x00,0x00,0xE8, +0x84,0x20,0x84,0x46,0xEA,0x3B,0x5A,0x08,0x04,0x07,0x84,0x03,0x46,0x11,0x00,0x07, +0x12,0x00,0x80,0x40,0xEA,0x3C,0x46,0x21,0x00,0x07,0x04,0x00,0x80,0x34,0x00,0x21, +0x00,0x80,0xFE,0x17,0x14,0x00,0x80,0x74,0xFC,0x80,0x5A,0x00,0x05,0x0B,0x5A,0x00, +0x06,0x14,0x5A,0x08,0x03,0x29,0xF8,0x10,0x44,0x10,0xFF,0x00,0xF8,0x15,0xD5,0x1F, +0xF8,0x0B,0x84,0x30,0xF8,0x11,0x46,0x13,0x11,0x50,0x50,0x10,0x8E,0x07,0xEA,0xCA, +0x14,0x10,0x01,0x60,0xD5,0x14,0xDD,0x43,0x84,0x20,0xEB,0x34,0xEB,0x36,0x83,0xFF, +0xEB,0x34,0xEB,0x36,0x84,0x3A,0x14,0x10,0x00,0xAD,0x84,0x27,0x10,0x10,0x02,0xAC, +0x83,0xFF,0x46,0x10,0x03,0x10,0x50,0x10,0x80,0x31,0xEA,0xCA,0x84,0x21,0xDD,0x43, +0x10,0x10,0x01,0xCC,0xDD,0x9E,0xFC,0x40,0xDD,0x53,0xF8,0x04,0xFA,0x72,0x49,0xFF, +0xF2,0x4C,0xDD,0x52,0x84,0x20,0x84,0x4D,0x83,0xFF,0xFA,0x73,0x49,0xFF,0xF2,0x45, +0xEA,0xD3,0x49,0xFF,0xFE,0x20,0x84,0xE0,0x46,0x91,0x00,0x07,0x58,0x94,0x82,0x98, +0xDD,0x52,0x84,0x20,0x84,0x41,0x83,0xFF,0x84,0x65,0x49,0xFF,0xF2,0x36,0x50,0x33, +0xFF,0xF3,0xDD,0x52,0x84,0x20,0x84,0x42,0x83,0xFF,0x96,0xD8,0x49,0xFF,0xF2,0x2D, +0xDD,0x52,0x84,0x20,0x84,0x44,0x44,0x30,0x00,0x80,0x49,0xFF,0xF2,0x26,0x44,0x60, +0x00,0x64,0xEA,0x6D,0x8E,0xC1,0x97,0xB1,0xCE,0xFD,0xDD,0x52,0x80,0x26,0x84,0x44, +0x80,0x66,0x49,0xFF,0xF2,0x1A,0xDD,0x52,0x80,0x26,0x84,0x45,0xEA,0x3B,0x38,0x04, +0x9C,0x08,0x8C,0xE1,0x5A,0x78,0x0D,0xD6,0x44,0x00,0x72,0xC4,0x46,0x11,0x00,0x07, +0x14,0x00,0x80,0xB1,0x84,0x41,0x80,0x26,0xDD,0x52,0x44,0x30,0x00,0x40,0x49,0xFF, +0xF2,0x04,0xDD,0x52,0x80,0x26,0x80,0x47,0xFA,0x70,0x49,0xFF,0xF1,0xFE,0xFC,0xC0, +0xFC,0x00,0x84,0x22,0x80,0xC0,0x80,0x41,0xEA,0xD5,0x84,0x61,0x49,0xFF,0xF1,0xF5, +0x84,0x67,0x40,0x31,0x98,0x64,0xEA,0xD5,0x84,0x22,0x84,0x45,0x96,0xD8,0x49,0xFF, +0xF1,0xEC,0xFC,0x80,0x84,0x80,0xD5,0x2D,0x41,0x41,0x40,0x09,0x97,0x41,0x92,0x10, +0x40,0x40,0xD0,0x37,0x96,0xD1,0x40,0x10,0xC0,0x08,0xFE,0x47,0x42,0x02,0x0C,0x24, +0xE2,0x20,0xE8,0x09,0x9F,0x21,0x98,0x4A,0xE2,0x22,0xE9,0x05,0xE2,0x20,0xE8,0x03, +0x9F,0x21,0x98,0x4A,0x9A,0x48,0x40,0x10,0xD0,0x17,0x40,0x00,0x40,0x08,0xFE,0x2F, +0xFE,0xCC,0xE2,0x03,0xE8,0x09,0x98,0x02,0x9E,0x49,0xE2,0x02,0xE9,0x05,0xE2,0x03, +0xE8,0x03,0x98,0x02,0x9E,0x49,0x9A,0x03,0x40,0x42,0x40,0x08,0xFE,0x67,0xDD,0x9E, +0x3B,0xFF,0xFE,0xBC,0xFD,0x80,0xFD,0x91,0x83,0x84,0xCB,0x4D,0xE3,0xB2,0xE8,0x19, +0x42,0x09,0x00,0x07,0x82,0xA0,0xC0,0x0D,0x41,0x29,0x00,0x0C,0x52,0x50,0x00,0x20, +0x40,0x58,0x14,0x0D,0x41,0x18,0x80,0x0C,0x41,0x18,0x94,0x04,0x41,0x08,0x00,0x0C, +0xFD,0x08,0x80,0x52,0x49,0xFF,0xFF,0xBA,0x82,0xC1,0x82,0x00,0x86,0xE0,0xD5,0x23, +0xC2,0x28,0x42,0x09,0x00,0x07,0x82,0xA0,0xC8,0x04,0x8B,0xB2,0x86,0xE1,0xD5,0x14, +0x52,0xF0,0x00,0x20,0x41,0x29,0x00,0x0C,0x80,0x52,0x40,0x48,0x3C,0x0D,0x40,0x58, +0x80,0x0C,0x41,0x08,0x00,0x0C,0x40,0x02,0x90,0x04,0x40,0x18,0xBC,0x0D,0x49,0xFF, +0xFF,0x9D,0x82,0xE1,0x82,0x20,0xFD,0x08,0x80,0x52,0x49,0xFF,0xFF,0x97,0x82,0xC1, +0x51,0x00,0x00,0x00,0x4F,0xC2,0x00,0x53,0x86,0x20,0x41,0x08,0x54,0x0D,0xD5,0x4B, +0x41,0x19,0x4A,0x17,0x84,0x20,0x84,0x00,0x4F,0xC2,0x00,0x4C,0xB7,0x9C,0x15,0x1E, +0x00,0x01,0xD5,0x47,0xE3,0xB3,0xE9,0xF7,0x42,0x09,0x80,0x07,0x82,0xA0,0xC0,0x44, +0x52,0x40,0x00,0x20,0x40,0x59,0x10,0x0D,0x40,0x29,0x80,0x0C,0xFE,0xAF,0x82,0x62, +0x41,0x29,0x00,0x0C,0x40,0x38,0x10,0x0D,0x41,0x08,0x00,0x0C,0x40,0x08,0x80,0x0C, +0x40,0x18,0x90,0x0D,0xFE,0x1F,0x49,0xFF,0xFF,0x69,0x82,0xC1,0x82,0x20,0x42,0x00, +0xC8,0x69,0xE3,0xA1,0xE9,0x05,0x4C,0x18,0xC0,0x0C,0xE3,0x80,0xE8,0x09,0x51,0x6B, +0x7F,0xFF,0x8A,0x33,0x40,0x30,0x48,0x01,0xE2,0x03,0x8A,0x2F,0x80,0x03,0x86,0xE0, +0x4F,0xC2,0x00,0x15,0x40,0x08,0x00,0x01,0x40,0x18,0x84,0x01,0xE3,0x80,0x8A,0x2F, +0x52,0x4A,0x80,0x20,0x41,0x10,0x90,0x0C,0x41,0x00,0x54,0x0D,0x41,0x08,0x44,0x04, +0x41,0x10,0xD4,0x0D,0xB7,0x9C,0x15,0x1E,0x00,0x01,0x80,0x16,0x50,0x1B,0x80,0x00, +0x3B,0xFF,0xFE,0x84,0xDD,0x9E,0xE3,0xF1,0xE9,0x03,0xE3,0x92,0xE9,0x09,0x86,0xC1, +0x40,0x48,0x48,0x01,0x8B,0xB3,0xE3,0x84,0x8B,0xAF,0x82,0x04,0xD5,0x02,0x86,0xC0, +0x86,0xE0,0x4F,0xC3,0xFF,0xE9,0xD5,0xEA,0xFC,0x42,0x95,0x09,0x92,0x95,0x40,0x70, +0xAC,0x08,0x40,0x60,0x54,0x09,0xFF,0xF7,0x40,0x60,0x2C,0x08,0x47,0xC8,0x00,0x00, +0x95,0x59,0x92,0xB5,0x40,0x91,0xAC,0x08,0x40,0x81,0x54,0x09,0x40,0x94,0xA0,0x04, +0x40,0x81,0x2C,0x08,0xFE,0xCD,0x40,0xA1,0xF0,0x02,0x44,0x30,0x07,0xFF,0xC4,0x58, +0x4C,0x32,0x00,0x75,0x40,0x73,0xF0,0x04,0x4E,0x52,0x00,0x87,0x4C,0x32,0x80,0x79, +0x40,0x94,0xF0,0x04,0x14,0xAF,0x80,0x03,0x50,0x02,0xFC,0x02,0x99,0x20,0x42,0x23, +0xA4,0x69,0x42,0x03,0x24,0x69,0x40,0x91,0x04,0x00,0xE3,0x21,0x40,0xA1,0xBC,0x00, +0x42,0x23,0xA0,0x69,0x99,0xD0,0xE2,0xE0,0x89,0x2F,0xE3,0x2F,0x89,0x4F,0x89,0x23, +0xE3,0x23,0x89,0x4F,0x42,0x03,0x20,0x69,0x99,0xF9,0xE2,0xE1,0x89,0x2F,0xE3,0x2F, +0x40,0x15,0x3C,0x00,0xFF,0xC7,0x58,0x04,0x80,0x01,0x40,0x04,0x9C,0x1A,0xE4,0x20, +0xE9,0x07,0x81,0xE0,0x98,0x00,0xE2,0x0F,0x98,0x49,0x88,0x2F,0x9F,0x21,0x04,0xAF, +0x80,0x03,0x4E,0x47,0x00,0x71,0x52,0x52,0x07,0xFF,0x4E,0x57,0x00,0x46,0x50,0x00, +0x04,0x00,0x5C,0xF0,0x04,0x00,0xE8,0x04,0x88,0x2F,0xE2,0x2F,0x88,0x8F,0x40,0x20, +0x2C,0x09,0x96,0x94,0x9A,0x02,0x92,0x0B,0x40,0x20,0xD4,0x08,0xFE,0x17,0x94,0x49, +0x92,0x2C,0x40,0x52,0x50,0x08,0xFE,0x6F,0x40,0x10,0xA8,0x04,0xFC,0xC2,0x40,0xF3, +0x98,0x04,0xE8,0x19,0x40,0xF3,0x7C,0x09,0x99,0xFF,0x88,0xEF,0x99,0xB6,0xCF,0x05, +0x80,0xE6,0x84,0xC0,0x50,0x42,0x7F,0xE0,0x42,0x03,0x80,0x07,0xC0,0x9E,0x9B,0x20, +0x52,0x20,0x00,0x20,0x40,0x23,0x08,0x0D,0x40,0x63,0x00,0x0C,0x40,0x73,0x80,0x0C, +0xFF,0xD7,0xD5,0x93,0xD3,0x15,0x80,0x2A,0xFC,0xC2,0xFF,0xF7,0x4C,0x7E,0x40,0x11, +0xCD,0x06,0x40,0x24,0x84,0x08,0x40,0x21,0x20,0x04,0xC2,0x0A,0xDB,0x05,0x40,0x94, +0xA0,0x04,0x4C,0x9E,0x40,0x06,0x84,0x00,0x46,0x17,0xFF,0x00,0xD5,0xCE,0x84,0x00, +0x44,0x18,0x00,0x00,0xFC,0xC2,0x40,0x04,0xA0,0x04,0xC0,0xE6,0x40,0xF4,0x7C,0x09, +0x89,0x29,0x89,0x2F,0x89,0x08,0x4E,0x93,0x00,0x06,0x81,0x28,0x85,0x00,0x50,0x52, +0xFF,0xE0,0x42,0x04,0x80,0x07,0x4E,0x02,0xFF,0x6F,0x9B,0x68,0x52,0x20,0x00,0x20, +0x40,0x24,0x08,0x0D,0x40,0x84,0x00,0x0C,0x40,0x94,0x80,0x0C,0x40,0x94,0x88,0x04, +0x48,0xFF,0xFF,0x62,0x84,0xC0,0x52,0x32,0x00,0x01,0x5C,0xF1,0x80,0x20,0xE9,0x0A, +0x80,0xC0,0x80,0x01,0x84,0x20,0x50,0x31,0xFF,0xE0,0xC0,0x04,0x5C,0xF1,0x80,0x20, +0xE8,0x1A,0xC3,0x10,0x52,0x21,0x80,0x20,0x40,0x70,0x88,0x0C,0x40,0x50,0x08,0x0C, +0x40,0x00,0x0C,0x0D,0x40,0x10,0x8C,0x0D,0xFE,0x3F,0xFF,0xAF,0xC6,0x03,0x58,0x00, +0x00,0x01,0x50,0x00,0x04,0x00,0x5C,0xF0,0x04,0x00,0x88,0x2F,0x40,0x40,0xFC,0x09, +0x48,0xFF,0xFF,0x77,0x84,0x00,0xD5,0xA0,0xFC,0x42,0x95,0x09,0x92,0x95,0x40,0x70, +0xAC,0x08,0x40,0x60,0x54,0x09,0xFF,0xF7,0x40,0x60,0x2C,0x08,0x47,0xC8,0x00,0x00, +0x95,0x59,0x92,0xB5,0x40,0x91,0xAC,0x08,0x40,0x81,0x54,0x09,0x40,0x94,0xA0,0x04, +0x40,0x81,0x2C,0x08,0xFE,0xCD,0x40,0xA1,0xF0,0x02,0x44,0x30,0x07,0xFF,0x4E,0x42, +0x00,0xC5,0x4C,0x32,0x00,0xEF,0x40,0x73,0xF0,0x04,0x4E,0x52,0x00,0xFB,0x4C,0x32, +0x80,0xF3,0x40,0x94,0xF0,0x04,0x9B,0x25,0x50,0x42,0x03,0xFF,0x92,0xC1,0x40,0x13, +0xFC,0x08,0xFF,0x8F,0x92,0xE1,0x40,0x24,0xC0,0x09,0x40,0x33,0x88,0xF7,0x40,0x14, +0x80,0x13,0x42,0x50,0x8C,0x24,0x40,0x73,0xC0,0x08,0x40,0x03,0x40,0x09,0xFF,0xC7, +0x80,0x07,0x9B,0xFD,0xE2,0x07,0xE8,0x05,0x9E,0xD9,0x88,0xE9,0xE2,0xE9,0xE8,0xFD, +0x40,0x23,0x88,0xF7,0x42,0x50,0x88,0x24,0x40,0x73,0xC0,0x08,0x96,0x31,0xFF,0xC7, +0x80,0x07,0x9B,0xFD,0xE2,0x07,0xE8,0x05,0x9E,0x91,0x88,0xE9,0xE2,0xE9,0xE8,0xFD, +0x40,0x31,0xC0,0x08,0x98,0xDA,0x42,0x01,0xA0,0x69,0xFF,0x82,0x80,0x07,0x9B,0xF9, +0xE2,0x07,0xC6,0x05,0x80,0x07,0x9F,0xF9,0xE9,0x03,0xE2,0x07,0xE8,0x0C,0x9E,0xD9, +0x88,0xC8,0x40,0x03,0x20,0x06,0x88,0xE9,0xE2,0xE9,0xC0,0x04,0x9D,0xF9,0xE9,0x03, +0xE6,0xE1,0xE8,0xF6,0x4C,0x74,0xC0,0x07,0x80,0x28,0x80,0xE6,0x84,0x40,0x84,0x00, +0xD5,0x2B,0x40,0x14,0xC0,0x09,0x40,0x23,0x84,0xF7,0x40,0x04,0x80,0x13,0x42,0xF0, +0x08,0x24,0x40,0x73,0xC0,0x08,0x40,0x53,0x40,0x09,0xFF,0xEF,0x80,0xA7,0x8A,0xEF, +0xE2,0xA7,0xE8,0x05,0x9E,0x91,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,0x40,0x13,0x84,0xF7, +0x42,0x50,0x04,0x24,0x40,0x73,0xC0,0x08,0x96,0x31,0xFF,0xC7,0x80,0x07,0x9B,0xFD, +0xE2,0x07,0xE8,0x05,0x9E,0x49,0x88,0xE9,0xE2,0xE9,0xE8,0xFD,0x40,0x21,0x40,0x08, +0x98,0x91,0x42,0x01,0x20,0x69,0xFF,0x82,0x80,0x07,0x9B,0xF9,0xE2,0x07,0xC6,0x05, +0x80,0x07,0x9F,0xF9,0xE9,0x03,0xE2,0x07,0xE8,0x0C,0x9E,0x91,0x88,0xC8,0x40,0x03, +0x20,0x06,0x88,0xE9,0xE2,0xE9,0xC0,0x04,0x9D,0xF9,0xE9,0x03,0xE6,0xE1,0xE8,0xF6, +0xE4,0x60,0xE9,0x07,0x81,0xE2,0x98,0x92,0xE2,0x4F,0x98,0xDB,0x88,0x6F,0x9F,0x21, +0xFF,0xF7,0x58,0x01,0x00,0x01,0x40,0x01,0x1C,0x1A,0x80,0x23,0x4E,0x47,0x00,0x79, +0x52,0x52,0x07,0xFF,0x4E,0x57,0x00,0x4A,0x50,0x00,0x04,0x00,0x5C,0xF0,0x04,0x00, +0xE8,0x04,0x88,0x2F,0xE2,0x2F,0x88,0x8F,0x40,0x20,0x2C,0x09,0x96,0x94,0x9A,0x02, +0x92,0x0B,0x40,0x20,0xD4,0x08,0xFE,0x17,0x94,0x49,0x92,0x2C,0x40,0x52,0x50,0x08, +0xFE,0x6F,0x40,0x10,0xA8,0x04,0xFC,0xC2,0x40,0xF3,0x98,0x04,0xE8,0x1B,0x40,0xF3, +0x7C,0x09,0x99,0xFF,0x88,0xEF,0x99,0xB6,0xCF,0x05,0x80,0xE6,0x84,0xC0,0x50,0x42, +0x7F,0xE0,0x42,0x03,0x80,0x07,0x4E,0x02,0xFF,0x32,0x9B,0x20,0x52,0x20,0x00,0x20, +0x40,0x23,0x08,0x0D,0x40,0x63,0x00,0x0C,0x40,0x73,0x80,0x0C,0xFF,0xD7,0x48,0xFF, +0xFF,0x26,0xD3,0x07,0xCD,0x04,0x40,0xF4,0xA0,0x04,0xE8,0x07,0x80,0x2A,0xFC,0xC2, +0x40,0x94,0xA0,0x04,0x4C,0x9E,0x3F,0xFC,0x84,0x00,0x44,0x18,0x00,0x00,0xFC,0xC2, +0xFF,0xF7,0x4C,0x7E,0x7F,0xFB,0xD3,0xF9,0x84,0x00,0x46,0x17,0xFF,0x00,0x40,0x10, +0xA8,0x04,0xFC,0xC2,0x40,0x94,0xA0,0x04,0x4C,0x9E,0x7F,0xF0,0x84,0x00,0xD5,0xE7, +0x40,0xF4,0xA0,0x04,0xE8,0xF2,0x40,0xF4,0x7C,0x09,0x89,0x29,0x89,0x2F,0x89,0x08, +0x4E,0x93,0x00,0x06,0x81,0x28,0x85,0x00,0x50,0x52,0xFF,0xE0,0x42,0x04,0x80,0x07, +0x4E,0x02,0xFE,0xFB,0x9B,0x68,0x52,0x20,0x00,0x20,0x40,0x24,0x08,0x0D,0x40,0x84, +0x00,0x0C,0x40,0x94,0x80,0x0C,0x40,0x94,0x88,0x04,0x48,0xFF,0xFE,0xEE,0x84,0xC0, +0x52,0x32,0x00,0x01,0x5C,0xF1,0x80,0x20,0xE9,0x0A,0x80,0xC0,0x80,0x01,0x84,0x20, +0x50,0x31,0xFF,0xE0,0xC0,0x04,0x5C,0xF1,0x80,0x20,0xE8,0x1A,0xC3,0x10,0x52,0x21, +0x80,0x20,0x40,0x70,0x88,0x0C,0x40,0x50,0x08,0x0C,0x40,0x00,0x0C,0x0D,0x40,0x10, +0x8C,0x0D,0xFE,0x3F,0xFF,0xAF,0xC6,0x03,0x58,0x00,0x00,0x01,0x50,0x00,0x04,0x00, +0x5C,0xF0,0x04,0x00,0x88,0x2F,0x40,0x40,0xFC,0x09,0x48,0xFF,0xFF,0x6F,0x84,0x00, +0xD5,0x9E,0x92,0x00,0x40,0x30,0xAC,0x08,0x40,0x40,0x54,0x09,0xFE,0xE7,0x46,0x48, +0x00,0x00,0xFE,0xE7,0x95,0x09,0x92,0x95,0x52,0x22,0x04,0x1E,0xE4,0x40,0xE9,0x0C, +0xFA,0x90,0xE2,0x44,0xE9,0x02,0x84,0x60,0x40,0x31,0x88,0x0D,0xE4,0x20,0xE8,0x02, +0xFE,0xDA,0x80,0x03,0xDD,0x9E,0xC0,0x03,0x58,0x10,0x80,0x01,0x46,0x47,0xFF,0x00, +0xE2,0x81,0xE8,0x04,0x46,0x08,0x00,0x00,0xDD,0x9E,0x84,0x1F,0xDD,0x9E,0x92,0x00, +0x3A,0x6F,0x98,0x3C,0x84,0x20,0x80,0xA1,0x80,0x61,0x80,0x40,0xC2,0x10,0xE4,0x40, +0xE8,0x07,0x46,0x58,0x00,0x00,0xFE,0x92,0xC1,0x03,0xFE,0x4A,0x8E,0x41,0x44,0x30, +0x04,0x1E,0x42,0x41,0x00,0x07,0x9A,0xDC,0x40,0x21,0x10,0x0C,0x40,0x40,0xAC,0x09, +0x40,0x61,0x54,0x08,0xFF,0x37,0x95,0x91,0x92,0xCC,0xFF,0x77,0x40,0x61,0xD0,0x08, +0xFF,0x77,0x80,0x04,0x80,0x25,0x3A,0x6F,0x98,0x04,0xDD,0x9E,0x3A,0x6F,0x98,0x3C, +0x84,0x20,0x80,0x61,0x80,0x40,0xC2,0x08,0x44,0x30,0x04,0x1E,0x42,0x51,0x00,0x07, +0x9A,0xDD,0x40,0x21,0x14,0x0C,0x40,0x40,0xAC,0x09,0x40,0x61,0x54,0x08,0xFF,0x37, +0x95,0x51,0x92,0xAC,0x40,0x61,0xD0,0x08,0xFF,0x77,0x80,0x04,0x80,0x25,0x3A,0x6F, +0x98,0x04,0xDD,0x9E,0x49,0x00,0x07,0x5C,0x49,0x00,0x2A,0xEA,0x49,0x00,0x01,0xE6, +0x46,0x08,0x00,0x20,0x04,0x10,0x03,0xC1,0x12,0x00,0x87,0xA0,0x02,0x00,0x07,0xA0, +0x44,0x00,0x00,0x30,0x49,0x00,0x01,0xF7,0x49,0x00,0x03,0x4D,0x49,0x00,0x4F,0x00, +0x49,0x00,0x42,0x45,0x2E,0x07,0xFF,0x5B,0x3C,0x0D,0xFF,0x64,0x49,0x00,0x42,0x63, +0x44,0x20,0x05,0x10,0x49,0x00,0x4E,0x41,0x3E,0x17,0xFE,0x1C,0x44,0x00,0x00,0xBB, +0x49,0x00,0x42,0x2D,0x49,0x00,0x4E,0x3E,0x49,0x00,0x1B,0x91,0x46,0x09,0x00,0x00, +0x66,0x00,0x00,0xFF,0x3E,0x07,0xFC,0xD1,0x3C,0x00,0x01,0xA2,0x44,0x00,0x00,0x64, +0x3E,0x07,0xFE,0x3E,0x58,0x00,0x06,0x58,0x04,0x00,0x03,0xC1,0x2E,0x17,0xFE,0x1C, +0x5E,0xF7,0x80,0x97,0x50,0x00,0x05,0x5A,0x46,0x0A,0x55,0xAA,0x02,0x3F,0x80,0x07, +0x2E,0x00,0x00,0xE3,0x49,0x00,0x32,0xEA,0x02,0x0F,0x80,0x07,0x04,0x50,0x03,0xF1, +0x46,0x18,0x00,0x20,0x44,0x00,0xFF,0xFF,0x2E,0x07,0xFD,0x31,0x44,0x10,0x00,0x64, +0x2E,0x07,0xFC,0xB9,0x49,0x00,0x32,0x2E,0x3A,0x05,0x04,0x00,0x49,0x00,0x4E,0xD6, +0x10,0x10,0x00,0x60,0x2E,0x00,0x00,0x97,0x2E,0x00,0x00,0xE0,0x14,0x00,0x83,0xC1, +0x40,0x11,0x05,0x04,0x12,0x10,0x00,0x1E,0x3C,0x0B,0xFE,0xAC,0x49,0x00,0x44,0x63, +0x58,0x00,0x00,0x01,0x3A,0x0F,0x84,0x20,0x50,0x0F,0x80,0x0F,0x3C,0x03,0xFF,0x9D, +0x49,0x00,0x42,0x95,0x46,0x19,0x00,0x00,0x49,0x00,0x49,0x86,0x3E,0x07,0xFE,0x1D, +0x50,0x00,0x03,0x3A,0x2E,0x07,0xFD,0x00,0x49,0x00,0x1B,0x9C,0x2E,0x07,0xFC,0xD1, +0x46,0x19,0x00,0x20,0x2E,0x07,0xFD,0x26,0x2E,0x17,0xFE,0x18,0x10,0x10,0x00,0x8C, +0x46,0x0A,0x33,0xAA,0x49,0x00,0x43,0x8B,0x2E,0x07,0xFE,0x19,0x3C,0x3D,0xFF,0x83, +0x3E,0x07,0xFC,0xE2,0x3E,0x1F,0xFF,0x58,0x02,0x50,0x00,0x00,0x2E,0x07,0xFC,0xE1, +0x2E,0x07,0xFD,0x09,0x49,0x00,0x09,0x7D,0x3C,0x0B,0xFE,0xA3,0x58,0x00,0x06,0x44, +0x3C,0x0B,0xFE,0xA6,0x3E,0x07,0xFC,0xC5,0x54,0xC6,0x00,0xFF,0x2E,0x07,0xFF,0x5A, +0x2E,0x07,0xFF,0x5C,0x10,0x10,0x01,0x68,0x49,0x00,0x0F,0x28,0x49,0x00,0x42,0x16, +0x44,0x00,0x01,0xB0,0x42,0x10,0x84,0x0B,0x64,0x00,0x00,0x08,0x46,0x09,0x00,0x88, +0x49,0x00,0x42,0x68,0x10,0x10,0x00,0x44,0x58,0x00,0x00,0x98,0x04,0x50,0x03,0xC4, +0x48,0x00,0x4E,0x20,0x2E,0x07,0xFC,0xC6,0x3C,0x03,0xFF,0x9E,0x3E,0xF7,0xFC,0xB9, +0x49,0x00,0x50,0x7A,0x58,0x21,0x0B,0x14,0x2E,0x07,0xFC,0xBF,0x3B,0x00,0xC4,0x00, +0x49,0x00,0x4E,0xB2,0x2E,0x07,0xFC,0xB8,0x40,0x00,0x00,0x09,0x66,0x10,0x80,0xFF, +0x14,0x00,0x83,0xC4,0x3E,0x07,0xFC,0xDB,0x3C,0x30,0x01,0xA2,0x58,0x10,0x8D,0x68, +0x3E,0x07,0xFC,0xDE,0x58,0x00,0x00,0x78,0x3E,0x07,0xFD,0x04,0x46,0x09,0x00,0x90, +0x2E,0x00,0x00,0xE1,0x3C,0x33,0xFE,0xA6,0x10,0x10,0x02,0x38,0x2E,0x27,0xFF,0xC9, +0x58,0x10,0x8B,0x14,0x40,0x11,0x05,0x00,0x49,0x00,0x44,0x63,0x12,0x10,0x07,0xA0, +0x40,0xF7,0x80,0x11,0x3E,0x2F,0xFB,0xB4,0x50,0x10,0x8F,0xFF,0x2E,0x17,0xFD,0x20, +0x3E,0x27,0xFE,0x1D,0x3C,0x23,0xFE,0xAC,0x2E,0x27,0xFE,0x1D,0x02,0x0F,0x80,0x04, +0x2E,0x17,0xFC,0xCF,0x3C,0x0B,0xFE,0xAE,0x46,0xF1,0x00,0x01,0x40,0x00,0x07,0x00, +0x49,0x00,0x42,0xA0,0x44,0x40,0xFF,0xFF,0x42,0x00,0x04,0x0B,0x42,0x10,0x94,0x0B, +0x2E,0x07,0xFC,0xD6,0x3E,0x10,0x00,0xE1,0x58,0x10,0x86,0x04,0x44,0x00,0x00,0xFF, +0x3E,0x07,0xFD,0x1F,0x10,0x04,0x80,0x00,0x49,0x00,0x10,0x9E,0x3C,0x2D,0xFF,0x83, +0x2E,0x07,0xFD,0x1D,0x2E,0x17,0xFD,0x26,0x12,0x00,0x87,0xF4,0x49,0x00,0x42,0x95, +0x49,0x00,0x18,0xAC,0x02,0xF7,0x80,0x12,0x2E,0x07,0xFC,0xCD,0x2E,0x07,0xFC,0xCF, +0x3C,0x43,0xFE,0xAC,0x38,0x11,0x0D,0x01,0x2E,0x07,0xFF,0x8A,0x3B,0x01,0x44,0x20, +0x38,0x11,0x0D,0x09,0x3C,0x0C,0x00,0x37,0x42,0x00,0x08,0x0B,0x3C,0x13,0xFF,0x93, +0x3C,0x13,0xFF,0x94,0x02,0x00,0x02,0xD4,0x49,0x00,0x01,0xDE,0x3E,0x17,0xFE,0x1D, +0x49,0x00,0x44,0x0C,0x49,0x00,0x44,0xE3,0x58,0x00,0x0A,0x98,0x3C,0x13,0xFF,0x9A, +0x40,0xF0,0x3C,0x00,0x40,0x00,0x20,0x08,0x44,0x00,0x05,0x10,0x58,0x10,0x80,0x02, +0x44,0x60,0xFF,0xFF,0x58,0x00,0x01,0x48,0x49,0x00,0x43,0x82,0x3C,0x00,0x00,0xBF, +0x46,0x29,0x00,0x00,0x02,0x10,0x07,0xA0,0x3E,0x07,0xFC,0xD6,0x49,0x00,0x12,0xA9, +0x3E,0x07,0xFC,0xEC,0x3E,0x07,0xFC,0xEE,0x38,0x30,0x89,0x09,0x38,0x13,0x08,0x00, +0x10,0x05,0x80,0x00,0x3C,0x1C,0x00,0x36,0x46,0x10,0xFF,0xFF,0x49,0x00,0x03,0x3F, +0x3C,0x0D,0xFF,0x75,0x44,0x40,0x00,0x30,0x2E,0x17,0xFF,0xCC,0x44,0x20,0xFF,0xFF, +0x3E,0x07,0xFD,0x00,0x49,0x00,0x18,0xD8,0x38,0x07,0x1C,0x00,0x14,0x10,0x01,0x5F, +0x2E,0x17,0xFF,0x5C,0x2E,0x17,0xFF,0x5A,0x3C,0x0B,0xFE,0xA0,0x44,0x00,0x00,0xC6, +0x3E,0x07,0xFC,0xD8,0x49,0x00,0x4E,0xAD,0x3C,0x30,0x01,0x9E,0x3C,0x30,0x01,0x9F, +0x44,0x00,0x03,0xE8,0x2E,0x07,0xFC,0xE8,0x44,0x00,0x00,0xCB,0x02,0x0F,0x80,0x01, +0x02,0x0F,0x80,0x02,0x02,0x10,0x87,0xF4,0x3E,0x07,0xFC,0xC0,0x42,0x10,0xA8,0x0B, +0x58,0x00,0x00,0x4C,0x49,0x00,0x50,0x68,0x40,0x01,0x00,0x40,0x3E,0x2F,0xFE,0xB8, +0x40,0x00,0x04,0x16,0x2E,0x07,0xFD,0x10,0x10,0x10,0x00,0x50,0x38,0x00,0x80,0x01, +0x12,0x00,0x87,0x92,0x3C,0x13,0xFF,0x9B,0x2E,0x17,0xFD,0x1D,0x02,0x00,0x07,0x92, +0x44,0x70,0x00,0xFF,0x02,0x0F,0x80,0x05,0x40,0x00,0x40,0x08,0x44,0x10,0x35,0xCA, +0x2E,0x07,0xFF,0xC8,0x3B,0x00,0xC4,0x20,0x54,0xA0,0x00,0xFF,0x10,0x00,0x82,0xC0, +0x44,0x20,0x00,0x30,0x00,0x03,0x00,0x92,0x3E,0x07,0xFC,0xC7,0x42,0x31,0xC0,0x24, +0x42,0x00,0x10,0x0B,0x12,0x10,0x02,0xB8,0x49,0x00,0x32,0x8C,0x58,0x00,0x08,0x00, +0x2E,0x07,0xFC,0xD9,0x2E,0x07,0xFF,0xCC,0x3E,0x07,0xFD,0x1C,0x3E,0x07,0xFD,0x1D, +0x48,0x00,0x12,0xA8,0x58,0x00,0x02,0xC4,0x10,0x00,0x80,0x08,0x10,0x60,0x00,0xA0, +0x49,0x00,0x35,0xE6,0x42,0x01,0x04,0x73,0x2E,0x07,0xFD,0x20,0x58,0x00,0x00,0x02, +0x44,0x00,0xA5,0x5A,0x58,0x00,0x00,0x04,0x44,0x00,0x5A,0xA5,0x10,0x10,0x00,0x40, +0x49,0x00,0x34,0xFC,0x2E,0x17,0xFD,0x31,0x3C,0x03,0xFE,0xA6,0x3E,0x07,0xFC,0xBA, +0x44,0x60,0x00,0x55,0x2E,0x07,0xFC,0xCE,0x3E,0x07,0xFD,0x20,0x42,0x13,0x00,0x73, +0x00,0x20,0x00,0x08,0x3E,0x07,0xFC,0xF5,0x02,0x20,0x00,0x1E,0x50,0x1F,0x81,0x90, +0x49,0x00,0x3A,0xD2,0x66,0x00,0x00,0x02,0x2E,0x17,0xFE,0x1D,0x49,0x00,0x15,0x62, +0x42,0x10,0x80,0x03,0x3C,0x0B,0xFE,0xC1,0x58,0x10,0x81,0x44,0x3C,0x03,0xFE,0xAC, +0x42,0x00,0x14,0x0B,0x46,0x61,0x00,0x02,0x14,0x10,0x00,0x0E,0x3C,0x0C,0x00,0x36, +0x49,0x00,0x1B,0xBE,0x58,0x21,0x0D,0x08,0x02,0x00,0x02,0xD6,0x3C,0x03,0xFF,0x1C, +0x3C,0x03,0xFF,0x1D,0x46,0x11,0x00,0x03,0x2E,0x07,0xFC,0xF3,0x2E,0x07,0xFC,0xF5, +0x58,0x63,0x01,0x44,0x00,0x00,0x02,0x7C,0x3E,0x0F,0xFE,0x7C,0x3C,0x03,0xFF,0x9C, +0x00,0x10,0x00,0x40,0x3E,0x07,0xFC,0xE9,0x3E,0x67,0xFC,0xC5,0x50,0x21,0x00,0xE8, +0x2E,0x07,0xFC,0xBD,0x44,0x20,0x00,0x48,0x10,0x10,0x00,0x4C,0x58,0x10,0x80,0x78, +0x58,0x10,0x80,0x04,0x14,0x10,0x01,0x6D,0x49,0x00,0x3E,0x3A,0x14,0x10,0x01,0x6E, +0x46,0x09,0x00,0x80,0x42,0x10,0x90,0x0B,0x2E,0x20,0x00,0xE3,0x38,0xF1,0x06,0x02, +0x58,0x21,0x0F,0xF4,0x38,0x06,0x82,0x02,0x49,0x00,0x0A,0xB0,0x2E,0x17,0xFF,0xC9, +0x64,0x12,0x00,0x43,0x3C,0x0D,0xFF,0x88,0x2E,0x07,0xFC,0xF7,0x64,0x03,0x00,0x03, +0x49,0x00,0x1B,0x95,0x3C,0x00,0x00,0xBE,0x40,0x03,0x98,0x60,0x2E,0x07,0xFC,0xE3, +0x3C,0x0B,0xFF,0x9E,0x58,0x00,0x0B,0x68,0x49,0x00,0x0F,0x1C,0x3C,0x1D,0xFF,0x64, +0x40,0x00,0x82,0x00,0x00,0x10,0x00,0x44,0x50,0x00,0x03,0x3C,0x44,0x00,0x00,0x3C, +0x46,0x01,0x00,0x05,0x46,0x01,0x00,0x06,0x46,0x01,0x00,0x07,0x46,0x01,0x00,0x01, +0x46,0x01,0x00,0x02,0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x03,0x46,0x01,0x00,0x04, +0x46,0x01,0x00,0x05,0x46,0x21,0x00,0x00,0x46,0x21,0x00,0x01,0x46,0x21,0x00,0x02, +0x46,0x11,0x00,0x00,0x46,0x11,0x00,0x01,0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x06, +0x46,0x11,0x00,0x07,0x46,0x51,0x00,0x07,0x46,0x51,0x00,0x08,0x46,0x01,0x00,0x07, +0x46,0x01,0x00,0x08,0x46,0x01,0x00,0x09,0x46,0x01,0x00,0x02,0x46,0x01,0x00,0x03, +0x46,0x01,0x00,0x04,0x46,0x31,0x00,0x01,0x46,0x31,0x00,0x02,0x46,0x31,0x00,0x03, +0x46,0x31,0x00,0x07,0x46,0x31,0x00,0x08,0x46,0x31,0x00,0x09,0x46,0x21,0x00,0x06, +0x46,0x21,0x00,0x07,0x46,0x31,0x00,0x02,0x46,0x31,0x00,0x03,0x46,0x31,0x00,0x04, +0x46,0x21,0x00,0x07,0x46,0x21,0x00,0x08,0x46,0x21,0x00,0x09,0x46,0x21,0x00,0x01, +0x46,0x21,0x00,0x02,0x46,0x21,0x00,0x03,0x46,0x11,0x00,0x01,0x46,0x11,0x00,0x02, +0x46,0x11,0x00,0x03,0x46,0x11,0x00,0x02,0x46,0x11,0x00,0x03,0x46,0x11,0x00,0x04, +0x46,0x00,0x00,0x0D,0x46,0x00,0x00,0x0E,0x46,0x00,0x00,0x0F,0x46,0x01,0x00,0x00, +0x46,0x01,0x00,0x01,0x46,0x01,0x00,0x02,0x46,0x11,0x00,0x07,0x46,0x11,0x00,0x08, +0x46,0x11,0x00,0x09,0x00,0x01,0x02,0x00,0x01,0x02,0x01,0x00,0x00,0x02,0x02,0x01, +0x02,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x08,0x09,0x10,0x11, +0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09, +0x10,0x11,0x00,0x01,0x08,0x09,0x10,0x11,0x00,0x01,0x08,0x09,0x00,0xA1,0x28,0x04, +0x00,0x0A,0x85,0x02,0x00,0x54,0x50,0x01,0x48,0x19,0x00,0x10,0x02,0x04,0x02,0x00, +0x00,0x00,0x00,0x00,0x04,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x02,0x04, +0x00,0x00,0x00,0x00,0x04,0x02,0x01,0x04,0x03,0x02,0x00,0x00,0x02,0x01,0x04,0x03, +0x01,0x02,0x00,0x00,0x03,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x04,0x03,0x02, +0x00,0x00,0x00,0x00,0x04,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x00,0x00, +0x00,0x00,0x00,0x00,0x04,0x03,0x01,0x02,0x00,0x00,0x00,0x00,0x03,0x01,0x00,0x00, +0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xA2,0x82,0xA2,0x82,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x81,0xA1,0x81,0xA1,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA2,0x82,0xA2,0x82, +0xA2,0x0D,0x00,0x00,0x00,0x00,0x00,0x00,0xC1,0xA1,0xE1,0x81,0xA1,0x85,0xC5,0xA5, +0xE5,0x0E,0x00,0x00,0xE5,0x85,0xC5,0xAA,0xC1,0x1F,0x00,0x00,0x00,0x00,0x00,0x00, +0xC1,0xA2,0xC1,0x82,0xE1,0x2F,0x00,0x00,0x00,0x00,0x00,0x00,0xE3,0x83,0xC3,0xA3, +0xE3,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0xC5,0xA5,0xE5,0x05,0x01,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xEA,0xCA,0xEA,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xC5,0xE5,0xC5,0x85,0x79,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0xCA,0x09, +0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAA,0x8A,0x0A,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x8A,0xAA,0x1D,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xEA,0xCA,0x2D,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCA,0xEA,0x3D,0x02, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x81,0x01,0x03,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xA1,0x02,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xC1,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE1,0x04,0x03,0x00, +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,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xA5,0x5A,0x08,0x04,0x06,0x02,0x09,0x52,0x63,0x75,0x73,0x74,0x6F,0x6D,0x65,0x72, +0x00,0x00,0x00,0x00,0x70,0x72,0x6F,0x6A,0x65,0x63,0x74,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x37,0x31,0x30,0x32,0x35,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x15,0x02,0x3F,0x82,0xC2,0x10,0x02,0x03,0x37,0x64,0x30,0x96,0xC8,0x3C,0xFF,0x0A, +0x14,0x14,0x28,0x14,0x32,0x32,0x25,0x20,0x05,0x40,0x25,0x14,0x14,0x82,0x82,0x16, +0x16,0x53,0x75,0x0A,0x78,0x46,0x64,0x3C,0x0F,0x0C,0x00,0x00,0x11,0x00,0x00,0x08, +0x0F,0x0A,0x96,0x10,0x09,0x06,0x0A,0x04,0x14,0x64,0xFF,0x14,0x00,0x00,0x1E,0x8C, +0x64,0x64,0x78,0x90,0x08,0x00,0x0F,0x06,0x04,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x02,0x80,0x00,0x00,0x00, +0x00,0x0C,0x00,0x00,0x00,0x1E,0x20,0x22,0x24,0x00,0x50,0x02,0x02,0x0A,0x02,0x05, +0x24,0x12,0x0A,0x06,0xED,0x03,0x08,0x70,0x04,0x38,0x00,0x7F,0x03,0x44,0x47,0x34, +0x00,0x04,0x56,0x0D,0xD4,0x53,0x0F,0x00,0x00,0x7F,0x03,0x44,0x47,0x34,0x00,0x04, +0x56,0x0D,0xD4,0x53,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x28,0x00,0x00, +0x00,0x00,0x00,0x16,0x0A,0x14,0x80,0x0A,0x14,0x64,0x14,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x0B,0x0C,0x1B,0x15,0x50,0x25,0x02,0x50,0x0F,0x03,0x00,0x28,0xB2,0x64, +0x04,0x3C,0x35,0x1E,0x32,0x80,0x0E,0x07,0x23,0x0A,0xB4,0x78,0x96,0x5A,0x64,0x32, +0x00,0x00,0x64,0x64,0x00,0x14,0x03,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09, +0x06,0x0A,0x0A,0x78,0x3C,0x96,0x32,0x00,0x00,0x00,0x00,0x88,0x30,0x00,0x00,0x00, +0x00,0x0A,0x0A,0x50,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x06,0x00,0x00,0x00, +0x1E,0x00,0x00,0x00,0x00,0x02,0xD0,0x05,0x00,0x0A,0x05,0xFF,0x0A,0x03,0xE8,0x03, +0xE8,0x03,0x02,0x01,0xF4,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0F, +0x14,0x14,0x0A,0x0A,0x1C,0x30,0x00,0x00,0x11,0x11,0x0A,0x05,0x3D,0x0A,0x1B,0x33, +0x00,0x00,0x11,0x0A,0x05,0x85,0x14,0x15,0x14,0x10,0x15,0x14,0x00,0x00,0x00,0x01, +0x00,0x00,0x00,0x00,0x00,0x10,0x0A,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x01,0x0A,0x06,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x28,0xA0, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x6F,0x08,0x6F,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x00,0x5C,0x08,0x6F,0x08, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0xED,0x00,0x36,0x01,0xE2,0x02,0x2D,0x03,0x37,0x04,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEB,0x00,0x40,0x01,0xDF,0x02, +0x34,0x03,0x37,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x08,0x70,0x14,0x00,0x00,0x08,0x70,0x14,0x00,0x00,0x04,0x38,0x0A,0x00, +0x00,0x04,0x38,0x0A,0x64,0x0C,0x64,0xFF,0x96,0x96,0x64,0x3C,0xC8,0xFF,0xB4,0x5A, +0x05,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,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40, +0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x65,0x67,0x65,0x67,0x65,0x67,0x65,0x67,0x64,0x65,0x64,0x65, +0x00,0x65,0x00,0x65,0x00,0x65,0x00,0x65,0x64,0x65,0x64,0x65,0x65,0x67,0x65,0x67, +0x65,0x67,0x65,0x67,0x00,0x00,0x00,0x00,0x26,0x00,0x39,0x00,0x24,0x0C,0x36,0x0C, +0xFF,0x34,0x00,0x45,0x00,0xFF,0x37,0x00,0x26,0x00,0xFF,0x36,0x00,0x24,0x00,0xFF, +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, +0x05,0x02,0x00,0xFA,0x00,0xFA,0x01,0xC2,0x03,0x20,0x01,0x2C,0x19,0x20,0x00,0x4B, +0x32,0x32,0x00,0x00,0x01,0xF4,0x00,0x96,0xC8,0x18,0x18,0x01,0xF4,0x20,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFE,0xF7,0x9B,0x3C,0xFF,0xFF,0x07,0x80,0x4B,0x00,0xEF,0x0F,0x0C,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xA5,0x5A, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x48,0x69, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00, +0x07,0x0E,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x0A,0xBA,0x90,0x00,0x20,0x00,0x00,0x00,0xDC,0x05,0x00,0x00,0xC9,0x00,0x00,0x00, +0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00, +0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00, +0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x81,0x02,0x20,0x47,0x81,0x02, +0x85,0x0C,0x81,0x02,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00, +0x00,0x00,0x00,0x00,0x78,0x02,0x00,0x00,0x03,0x5D,0x08,0x02,0x1F,0x06,0x11,0x1B, +0x0C,0x11,0x1F,0x09,0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15, +0x00,0x04,0x30,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,0x07,0x0E,0x15,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x0A,0xBA,0x90,0x00, +0x20,0x00,0x00,0x00,0xDC,0x05,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00, +0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA, +0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x04,0x81,0x02,0x20,0x47,0x81,0x02,0x85,0x0C,0x81,0x02, +0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00, +0x78,0x02,0x00,0x00,0x03,0x5D,0x08,0x02,0x1F,0x06,0x11,0x1B,0x0C,0x11,0x1F,0x09, +0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,0x00,0x04,0x30,0x03, +0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0x07,0x0E,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x22,0x9A,0x80,0x00,0x20,0x00,0x00,0x00, +0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00, +0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, +0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x03,0x00,0x00, +0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00, +0x5E,0x01,0x5E,0x01,0xC8,0x00,0x14,0x00,0x29,0x0E,0x5B,0x0E,0x97,0x00,0x00,0x00, +0x04,0x5D,0x08,0x04,0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x03,0x02,0x03, +0x00,0x02,0x03,0x03,0x01,0x00,0x15,0x15,0x00,0x04,0x30,0x03,0x02,0x00,0x03,0x03, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0x38,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x00,0x00,0x00,0x3A,0x9A,0x84,0x00,0x20,0x00,0x00,0x00,0xF4,0x01,0x00,0x00, +0xC9,0x00,0x00,0x00,0x00,0x41,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00, +0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, +0x02,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x04,0xA0,0x00, +0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01, +0xC8,0x00,0x14,0x00,0xA4,0x38,0xD6,0x38,0x97,0x00,0x00,0x00,0x04,0x5D,0x08,0x04, +0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x04,0x02,0x03,0x00,0x02,0x03,0x03, +0x01,0x00,0x15,0x15,0x00,0x03,0x30,0x03,0x00,0x01,0x03,0x03,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x0E,0x00, +0x15,0x00,0x31,0x00,0x1C,0x00,0x23,0x00,0x2A,0x00,0x31,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00, +0x22,0x9A,0x80,0x00,0x20,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00, +0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00, +0xAA,0xAA,0xAA,0xA2,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00, +0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00, +0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00, +0x00,0x00,0x00,0x00,0x97,0x00,0x00,0x00,0x04,0x05,0x08,0x04,0x1F,0x06,0x10,0x1A, +0x0B,0x10,0x15,0x09,0x00,0x03,0x00,0x03,0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15, +0x00,0x04,0x30,0x01,0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xFF,0xFD,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0x07,0x00,0x0E,0x00,0x15,0x00,0x31,0x00, +0x1C,0x00,0x23,0x00,0x2A,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x3A,0xBA,0x84,0x00, +0x20,0x00,0x00,0x00,0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00, +0x0A,0x00,0x00,0x00,0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xA2, +0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x04,0xA0,0x00,0x20,0x47,0x64,0x00,0x34,0x08,0x64,0x00, +0x14,0x00,0xC8,0x00,0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00, +0x97,0x00,0x00,0x00,0x04,0x05,0x08,0x07,0x1F,0x08,0x11,0x18,0x0C,0x11,0x16,0x09, +0x00,0x04,0x00,0x03,0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,0x00,0x04,0x30,0x01, +0x00,0x00,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xC0,0x01,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x07,0x1C,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0xFF,0x38,0xE0,0x30,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00, +0xFF,0xC0,0x01,0x37,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0xFF,0xFD,0x37, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0x03,0x00,0xFF,0x00,0x00,0x30,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,0xFF,0x00, +0xFF,0xFF,0x03,0x00,0x31,0x00,0x31,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x3A,0x9A,0x84,0x00,0x20,0x00,0x00,0x00, +0xF0,0x04,0x00,0x00,0xC9,0x00,0x00,0x00,0x80,0x61,0x00,0x00,0x0A,0x00,0x00,0x00, +0x32,0x00,0x00,0x00,0x14,0x00,0x00,0x00,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, +0xAA,0xAA,0xAA,0xAA,0x03,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0xA0,0x00,0x20,0x47,0xA0,0x00,0x20,0x08,0xA0,0x00,0x14,0x00,0xC8,0x00, +0x5E,0x01,0x5E,0x01,0x64,0x00,0x14,0x00,0x00,0x00,0x00,0x00,0x97,0x00,0x00,0x00, +0x04,0x05,0x08,0x04,0x1F,0x06,0x10,0x1A,0x0B,0x10,0x15,0x09,0x00,0x04,0x07,0x03, +0x00,0x02,0x03,0x03,0x00,0x01,0x15,0x15,0x00,0x04,0x30,0x01,0x00,0x00,0x03,0x03, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x65,0x02,0x66,0x02,0x67,0x02,0x68,0x02,0x69,0x02,0x6A,0x02,0x6B,0x02,0x6C,0x02, +0x6D,0x02,0x6E,0x02,0x6F,0x02,0x70,0x02,0x71,0x02,0x72,0x02,0x73,0x02,0x74,0x02, +0x75,0x02,0x76,0x02,0x77,0x02,0x78,0x02,0x79,0x02,0x7A,0x02,0x7B,0x02,0x7C,0x02, +0x7D,0x02,0x7E,0x02,0x7F,0x02,0x80,0x02,0x81,0x02,0x82,0x02,0x83,0x02,0x84,0x02, +0x85,0x02,0x86,0x02,0x87,0x02,0x88,0x02,0x41,0x02,0x42,0x02,0x43,0x02,0x44,0x02, +0x45,0x02,0x46,0x02,0x47,0x02,0x48,0x02,0x49,0x02,0x4A,0x02,0x4B,0x02,0x4C,0x02, +0x4D,0x02,0x4E,0x02,0x4F,0x02,0x50,0x02,0x51,0x02,0x52,0x02,0x53,0x02,0x54,0x02, +0x55,0x02,0x56,0x02,0x57,0x02,0x58,0x02,0x59,0x02,0x5A,0x02,0x5B,0x02,0x5C,0x02, +0x5D,0x02,0x5E,0x02,0x5F,0x02,0x60,0x02,0x61,0x02,0x62,0x02,0x63,0x02,0x64,0x02, +0x1D,0x02,0x1E,0x02,0x1F,0x02,0x20,0x02,0x21,0x02,0x22,0x02,0x23,0x02,0x24,0x02, +0x25,0x02,0x26,0x02,0x27,0x02,0x28,0x02,0x29,0x02,0x2A,0x02,0x2B,0x02,0x2C,0x02, +0x2D,0x02,0x2E,0x02,0x2F,0x02,0x30,0x02,0x31,0x02,0x32,0x02,0x33,0x02,0x34,0x02, +0x35,0x02,0x36,0x02,0x37,0x02,0x38,0x02,0x39,0x02,0x3A,0x02,0x3B,0x02,0x3C,0x02, +0x3D,0x02,0x3E,0x02,0x3F,0x02,0x40,0x02,0xF9,0x01,0xFA,0x01,0xFB,0x01,0xFC,0x01, +0xFD,0x01,0xFE,0x01,0xFF,0x01,0x00,0x02,0x01,0x02,0x02,0x02,0x03,0x02,0x04,0x02, +0x05,0x02,0x06,0x02,0x07,0x02,0x08,0x02,0x09,0x02,0x0A,0x02,0x0B,0x02,0x0C,0x02, +0x0D,0x02,0x0E,0x02,0x0F,0x02,0x10,0x02,0x11,0x02,0x12,0x02,0x13,0x02,0x14,0x02, +0x15,0x02,0x16,0x02,0x17,0x02,0x18,0x02,0x19,0x02,0x1A,0x02,0x1B,0x02,0x1C,0x02, +0xD5,0x01,0xD6,0x01,0xD7,0x01,0xD8,0x01,0xD9,0x01,0xDA,0x01,0xDB,0x01,0xDC,0x01, +0xDD,0x01,0xDE,0x01,0xDF,0x01,0xE0,0x01,0xE1,0x01,0xE2,0x01,0xE3,0x01,0xE4,0x01, +0xE5,0x01,0xE6,0x01,0xE7,0x01,0xE8,0x01,0xE9,0x01,0xEA,0x01,0xEB,0x01,0xEC,0x01, +0xED,0x01,0xEE,0x01,0xEF,0x01,0xF0,0x01,0xF1,0x01,0xF2,0x01,0xF3,0x01,0xF4,0x01, +0xF5,0x01,0xF6,0x01,0xF7,0x01,0xF8,0x01,0xB1,0x01,0xB2,0x01,0xB3,0x01,0xB4,0x01, +0xB5,0x01,0xB6,0x01,0xB7,0x01,0xB8,0x01,0xB9,0x01,0xBA,0x01,0xBB,0x01,0xBC,0x01, +0xBD,0x01,0xBE,0x01,0xBF,0x01,0xC0,0x01,0xC1,0x01,0xC2,0x01,0xC3,0x01,0xC4,0x01, +0xC5,0x01,0xC6,0x01,0xC7,0x01,0xC8,0x01,0xC9,0x01,0xCA,0x01,0xCB,0x01,0xCC,0x01, +0xCD,0x01,0xCE,0x01,0xCF,0x01,0xD0,0x01,0xD1,0x01,0xD2,0x01,0xD3,0x01,0xD4,0x01, +0x8D,0x01,0x8E,0x01,0x8F,0x01,0x90,0x01,0x91,0x01,0x92,0x01,0x93,0x01,0x94,0x01, +0x95,0x01,0x96,0x01,0x97,0x01,0x98,0x01,0x99,0x01,0x9A,0x01,0x9B,0x01,0x9C,0x01, +0x9D,0x01,0x9E,0x01,0x9F,0x01,0xA0,0x01,0xA1,0x01,0xA2,0x01,0xA3,0x01,0xA4,0x01, +0xA5,0x01,0xA6,0x01,0xA7,0x01,0xA8,0x01,0xA9,0x01,0xAA,0x01,0xAB,0x01,0xAC,0x01, +0xAD,0x01,0xAE,0x01,0xAF,0x01,0xB0,0x01,0x69,0x01,0x6A,0x01,0x6B,0x01,0x6C,0x01, +0x6D,0x01,0x6E,0x01,0x6F,0x01,0x70,0x01,0x71,0x01,0x72,0x01,0x73,0x01,0x74,0x01, +0x75,0x01,0x76,0x01,0x77,0x01,0x78,0x01,0x79,0x01,0x7A,0x01,0x7B,0x01,0x7C,0x01, +0x7D,0x01,0x7E,0x01,0x7F,0x01,0x80,0x01,0x81,0x01,0x82,0x01,0x83,0x01,0x84,0x01, +0x85,0x01,0x86,0x01,0x87,0x01,0x88,0x01,0x89,0x01,0x8A,0x01,0x8B,0x01,0x8C,0x01, +0x45,0x01,0x46,0x01,0x47,0x01,0x48,0x01,0x49,0x01,0x4A,0x01,0x4B,0x01,0x4C,0x01, +0x4D,0x01,0x4E,0x01,0x4F,0x01,0x50,0x01,0x51,0x01,0x52,0x01,0x53,0x01,0x54,0x01, +0x55,0x01,0x56,0x01,0x57,0x01,0x58,0x01,0x59,0x01,0x5A,0x01,0x5B,0x01,0x5C,0x01, +0x5D,0x01,0x5E,0x01,0x5F,0x01,0x60,0x01,0x61,0x01,0x62,0x01,0x63,0x01,0x64,0x01, +0x65,0x01,0x66,0x01,0x67,0x01,0x68,0x01,0x21,0x01,0x22,0x01,0x23,0x01,0x24,0x01, +0x25,0x01,0x26,0x01,0x27,0x01,0x28,0x01,0x29,0x01,0x2A,0x01,0x2B,0x01,0x2C,0x01, +0x2D,0x01,0x2E,0x01,0x2F,0x01,0x30,0x01,0x31,0x01,0x32,0x01,0x33,0x01,0x34,0x01, +0x35,0x01,0x36,0x01,0x37,0x01,0x38,0x01,0x39,0x01,0x3A,0x01,0x3B,0x01,0x3C,0x01, +0x3D,0x01,0x3E,0x01,0x3F,0x01,0x40,0x01,0x41,0x01,0x42,0x01,0x43,0x01,0x44,0x01, +0xFD,0x00,0xFE,0x00,0xFF,0x00,0x00,0x01,0x01,0x01,0x02,0x01,0x03,0x01,0x04,0x01, +0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0A,0x01,0x0B,0x01,0x0C,0x01, +0x0D,0x01,0x0E,0x01,0x0F,0x01,0x10,0x01,0x11,0x01,0x12,0x01,0x13,0x01,0x14,0x01, +0x15,0x01,0x16,0x01,0x17,0x01,0x18,0x01,0x19,0x01,0x1A,0x01,0x1B,0x01,0x1C,0x01, +0x1D,0x01,0x1E,0x01,0x1F,0x01,0x20,0x01,0xD9,0x00,0xDA,0x00,0xDB,0x00,0xDC,0x00, +0xDD,0x00,0xDE,0x00,0xDF,0x00,0xE0,0x00,0xE1,0x00,0xE2,0x00,0xE3,0x00,0xE4,0x00, +0xE5,0x00,0xE6,0x00,0xE7,0x00,0xE8,0x00,0xE9,0x00,0xEA,0x00,0xEB,0x00,0xEC,0x00, +0xED,0x00,0xEE,0x00,0xEF,0x00,0xF0,0x00,0xF1,0x00,0xF2,0x00,0xF3,0x00,0xF4,0x00, +0xF5,0x00,0xF6,0x00,0xF7,0x00,0xF8,0x00,0xF9,0x00,0xFA,0x00,0xFB,0x00,0xFC,0x00, +0xB5,0x00,0xB6,0x00,0xB7,0x00,0xB8,0x00,0xB9,0x00,0xBA,0x00,0xBB,0x00,0xBC,0x00, +0xBD,0x00,0xBE,0x00,0xBF,0x00,0xC0,0x00,0xC1,0x00,0xC2,0x00,0xC3,0x00,0xC4,0x00, +0xC5,0x00,0xC6,0x00,0xC7,0x00,0xC8,0x00,0xC9,0x00,0xCA,0x00,0xCB,0x00,0xCC,0x00, +0xCD,0x00,0xCE,0x00,0xCF,0x00,0xD0,0x00,0xD1,0x00,0xD2,0x00,0xD3,0x00,0xD4,0x00, +0xD5,0x00,0xD6,0x00,0xD7,0x00,0xD8,0x00,0x91,0x00,0x92,0x00,0x93,0x00,0x94,0x00, +0x95,0x00,0x96,0x00,0x97,0x00,0x98,0x00,0x99,0x00,0x9A,0x00,0x9B,0x00,0x9C,0x00, +0x9D,0x00,0x9E,0x00,0x9F,0x00,0xA0,0x00,0xA1,0x00,0xA2,0x00,0xA3,0x00,0xA4,0x00, +0xA5,0x00,0xA6,0x00,0xA7,0x00,0xA8,0x00,0xA9,0x00,0xAA,0x00,0xAB,0x00,0xAC,0x00, +0xAD,0x00,0xAE,0x00,0xAF,0x00,0xB0,0x00,0xB1,0x00,0xB2,0x00,0xB3,0x00,0xB4,0x00, +0x6D,0x00,0x6E,0x00,0x6F,0x00,0x70,0x00,0x71,0x00,0x72,0x00,0x73,0x00,0x74,0x00, +0x75,0x00,0x76,0x00,0x77,0x00,0x78,0x00,0x79,0x00,0x7A,0x00,0x7B,0x00,0x7C,0x00, +0x7D,0x00,0x7E,0x00,0x7F,0x00,0x80,0x00,0x81,0x00,0x82,0x00,0x83,0x00,0x84,0x00, +0x85,0x00,0x86,0x00,0x87,0x00,0x88,0x00,0x89,0x00,0x8A,0x00,0x8B,0x00,0x8C,0x00, +0x8D,0x00,0x8E,0x00,0x8F,0x00,0x90,0x00,0x49,0x00,0x4A,0x00,0x4B,0x00,0x4C,0x00, +0x4D,0x00,0x4E,0x00,0x4F,0x00,0x50,0x00,0x51,0x00,0x52,0x00,0x53,0x00,0x54,0x00, +0x55,0x00,0x56,0x00,0x57,0x00,0x58,0x00,0x59,0x00,0x5A,0x00,0x5B,0x00,0x5C,0x00, +0x5D,0x00,0x5E,0x00,0x5F,0x00,0x60,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x64,0x00, +0x65,0x00,0x66,0x00,0x67,0x00,0x68,0x00,0x69,0x00,0x6A,0x00,0x6B,0x00,0x6C,0x00, +0x25,0x00,0x26,0x00,0x27,0x00,0x28,0x00,0x29,0x00,0x2A,0x00,0x2B,0x00,0x2C,0x00, +0x2D,0x00,0x2E,0x00,0x2F,0x00,0x30,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x34,0x00, +0x35,0x00,0x36,0x00,0x37,0x00,0x38,0x00,0x39,0x00,0x3A,0x00,0x3B,0x00,0x3C,0x00, +0x3D,0x00,0x3E,0x00,0x3F,0x00,0x40,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,0x00, +0x45,0x00,0x46,0x00,0x47,0x00,0x48,0x00,0x01,0x00,0x02,0x00,0x03,0x00,0x04,0x00, +0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,0x09,0x00,0x0A,0x00,0x0B,0x00,0x0C,0x00, +0x0D,0x00,0x0E,0x00,0x0F,0x00,0x10,0x00,0x11,0x00,0x12,0x00,0x13,0x00,0x14,0x00, +0x15,0x00,0x16,0x00,0x17,0x00,0x18,0x00,0x19,0x00,0x1A,0x00,0x1B,0x00,0x1C,0x00, +0x1D,0x00,0x1E,0x00,0x1F,0x00,0x20,0x00,0x21,0x00,0x22,0x00,0x23,0x00,0x24,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0x00,0x00,0x03,0xB9,0x83,0x11,0x2B,0x01,0xBD,0x01,0x02,0xC2,0x08,0x70, +0x01,0xBD,0x03,0x04,0xB2,0x04,0x38,0x08,0x70,0x01,0xBD,0x00,0x0A,0xB1,0xF8,0x27, +0x27,0x00,0x00,0x0B,0x0E,0x0B,0x0E,0x33,0x02,0xD2,0x2D,0x2D,0x0B,0xB2,0x80,0x02, +0x18,0x80,0x70,0x00,0x08,0x1C,0x08,0x11,0x05,0x01,0xE9,0xD1,0x02,0xB2,0x00,0x08, +0x01,0xE9,0x00,0x01,0xBD,0x02,0x02,0xB2,0xB5,0x0A,0x01,0xBD,0x00,0x08,0xDD,0x00, +0x00,0x08,0x1C,0x08,0x34,0x34,0x88,0x18,0xB4,0x65,0x6B,0x00,0x00,0xD0,0xD4,0x36, +0xCF,0x06,0xCE,0x00,0xCE,0x00,0x00,0x00,0x07,0x00,0x2A,0x07,0x01,0x07,0x00,0x00, +0x2A,0x01,0xBD,0x03,0x01,0xE9,0xC3,0x03,0xB4,0x01,0x67,0x2A,0x01,0xE9,0x00,0x01, +0xBD,0x00,0x01,0xC1,0x01,0x01,0xBD,0x01,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1, +0xEF,0xEA,0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7, +0xB0,0xA8,0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22, +0x17,0x0D,0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8, +0xCC,0x9B,0x00,0x01,0xBD,0x02,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA, +0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8, +0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D, +0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B, +0x00,0x01,0xBD,0x03,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,0xE7,0xE5, +0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,0xA0,0x98, +0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,0x09,0x07, +0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,0x00,0x01, +0xBD,0x00,0x01,0xC2,0xC8,0x01,0xCC,0x08,0x25,0xD3,0x81,0x00,0x00,0x00,0x00,0x01, +0x00,0x04,0x00,0x01,0x13,0x40,0x04,0x09,0x09,0x0B,0x0B,0x32,0x10,0x08,0x00,0x08, +0x32,0x10,0x08,0x00,0x08,0x32,0x10,0x08,0x00,0x08,0x00,0x00,0x0A,0x08,0x7B,0x01, +0xE9,0xC5,0x01,0xC6,0xF7,0x01,0xE9,0x00,0x01,0xE9,0xD4,0x01,0xC6,0x6E,0x01,0xE9, +0x00,0x01,0xE9,0xEF,0x01,0xD3,0x0C,0x01,0xE9,0x00,0x01,0xBD,0x01,0x01,0xE9,0xC8, +0x01,0xD3,0xA1,0x01,0xE9,0x00,0x01,0xBD,0x00,0x38,0xD5,0x18,0x18,0x19,0x18,0x18, +0x20,0x18,0x18,0x18,0x10,0x10,0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18, +0x28,0x28,0x18,0x18,0x18,0x18,0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36, +0x36,0x37,0x37,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0xFC, +0xFC,0x00,0x00,0x30,0xD6,0x18,0x18,0x19,0x18,0x18,0x20,0x19,0x18,0x18,0x10,0x10, +0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,0x28,0x28,0x18,0x18,0x18,0x18, +0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,0x36,0x37,0x37,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA, +0xAF,0xEA,0xAA,0xAA,0xAA,0xAB,0xAF,0xEF,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01, +0xBD,0x01,0x0C,0xD8,0xAA,0xAA,0xAB,0xAF,0xEA,0xAA,0xAA,0xAA,0xAE,0xAF,0xEA,0xAA, +0x01,0xBD,0x02,0x0C,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA, +0xAA,0x01,0xBD,0x03,0x18,0xD8,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF, +0xEA,0xAA,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,0xBD, +0x00,0x01,0xE9,0xE4,0x02,0xE7,0x17,0x69,0x01,0xE9,0x00,0x19,0xE7,0x09,0x09,0x00, +0x07,0xE8,0x00,0x26,0x00,0x07,0x00,0x00,0xE8,0x32,0x00,0xE9,0x0A,0x0A,0x00,0x00, +0x00,0x01,0x01,0x00,0x12,0x04,0x01,0xBD,0x01,0x09,0xE7,0x02,0x00,0x01,0x20,0x01, +0x18,0x08,0xA8,0x09,0x01,0xBD,0x02,0x03,0xE7,0x20,0x20,0x00,0x01,0xBD,0x03,0x06, +0xE7,0x00,0xDC,0x11,0x70,0x00,0x20,0x01,0xE9,0xC9,0x06,0xE7,0x2A,0xCE,0x02,0x70, +0x01,0x04,0x01,0xE9,0x00,0x01,0xBD,0x00,0x01,0xD1,0x27,0x04,0xC9,0x04,0x0C,0x6D, +0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x04,0x00,0x00,0x03,0xB9,0x83,0x11,0x2B,0x01,0xBD,0x01,0x02,0xC2,0x08,0x70, +0x01,0xBD,0x03,0x04,0xB2,0x04,0x38,0x08,0x70,0x01,0xBD,0x00,0x0A,0xB1,0xF8,0x27, +0x27,0x00,0x00,0x0B,0x0E,0x0B,0x0E,0x33,0x02,0xD2,0x2D,0x2D,0x0B,0xB2,0x80,0x02, +0x18,0x80,0x70,0x00,0x08,0x1C,0x08,0x11,0x05,0x01,0xE9,0xD1,0x02,0xB2,0x00,0x08, +0x01,0xE9,0x00,0x01,0xBD,0x02,0x02,0xB2,0xB5,0x0A,0x01,0xBD,0x00,0x08,0xDD,0x00, +0x00,0x08,0x1C,0x08,0x34,0x34,0x88,0x18,0xB4,0x65,0x6B,0x00,0x00,0xD0,0xD4,0x36, +0xCF,0x06,0xCE,0x00,0xCE,0x00,0x00,0x00,0x07,0x00,0x2A,0x07,0x01,0x07,0x00,0x00, +0x2A,0x01,0xBD,0x03,0x01,0xE9,0xC3,0x03,0xB4,0x01,0x67,0x2A,0x01,0xE9,0x00,0x01, +0xBD,0x00,0x01,0xC1,0x01,0x01,0xBD,0x01,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1, +0xEF,0xEA,0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7, +0xB0,0xA8,0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22, +0x17,0x0D,0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8, +0xCC,0x9B,0x00,0x01,0xBD,0x02,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA, +0xE7,0xE5,0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8, +0xA0,0x98,0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D, +0x09,0x07,0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B, +0x00,0x01,0xBD,0x03,0x39,0xC1,0xFF,0xFB,0xF9,0xF6,0xF4,0xF1,0xEF,0xEA,0xE7,0xE5, +0xE2,0xDF,0xDD,0xDA,0xD8,0xD5,0xD2,0xCF,0xCC,0xC5,0xBE,0xB7,0xB0,0xA8,0xA0,0x98, +0x8E,0x85,0x7B,0x72,0x69,0x5E,0x53,0x48,0x3E,0x35,0x2B,0x22,0x17,0x0D,0x09,0x07, +0x05,0x01,0x00,0x26,0xF0,0x86,0x25,0x6E,0xB6,0xDD,0xF3,0xD8,0xCC,0x9B,0x00,0x01, +0xBD,0x00,0x01,0xC2,0xC8,0x01,0xCC,0x08,0x25,0xD3,0x81,0x00,0x00,0x00,0x00,0x01, +0x00,0x04,0x00,0x01,0x13,0x40,0x04,0x09,0x09,0x0B,0x0B,0x32,0x10,0x08,0x00,0x08, +0x32,0x10,0x08,0x00,0x08,0x32,0x10,0x08,0x00,0x08,0x00,0x00,0x0A,0x08,0x7B,0x01, +0xE9,0xC5,0x01,0xC6,0xF7,0x01,0xE9,0x00,0x01,0xE9,0xD4,0x01,0xC6,0x6E,0x01,0xE9, +0x00,0x01,0xE9,0xEF,0x01,0xD3,0x0C,0x01,0xE9,0x00,0x01,0xBD,0x01,0x01,0xE9,0xC8, +0x01,0xD3,0xA1,0x01,0xE9,0x00,0x01,0xBD,0x00,0x38,0xD5,0x18,0x18,0x19,0x18,0x18, +0x20,0x18,0x18,0x18,0x10,0x10,0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18, +0x28,0x28,0x18,0x18,0x18,0x18,0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36, +0x36,0x37,0x37,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFC,0xFC,0x00,0x00,0xFC, +0xFC,0x00,0x00,0x30,0xD6,0x18,0x18,0x19,0x18,0x18,0x20,0x19,0x18,0x18,0x10,0x10, +0x18,0x18,0x00,0x00,0x18,0x18,0x01,0x01,0x18,0x18,0x28,0x28,0x18,0x18,0x18,0x18, +0x18,0x2F,0x2F,0x30,0x30,0x31,0x31,0x35,0x35,0x36,0x36,0x37,0x37,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA, +0xAF,0xEA,0xAA,0xAA,0xAA,0xAB,0xAF,0xEF,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01, +0xBD,0x01,0x0C,0xD8,0xAA,0xAA,0xAB,0xAF,0xEA,0xAA,0xAA,0xAA,0xAE,0xAF,0xEA,0xAA, +0x01,0xBD,0x02,0x0C,0xD8,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA, +0xAA,0x01,0xBD,0x03,0x18,0xD8,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF, +0xEA,0xAA,0xBA,0xAA,0xAA,0xAF,0xEA,0xAA,0xAA,0xAA,0xAA,0xAF,0xEA,0xAA,0x01,0xBD, +0x00,0x01,0xE9,0xE4,0x02,0xE7,0x17,0x69,0x01,0xE9,0x00,0x19,0xE7,0x09,0x09,0x00, +0x07,0xE8,0x00,0x26,0x00,0x07,0x00,0x00,0xE8,0x32,0x00,0xE9,0x0A,0x0A,0x00,0x00, +0x00,0x01,0x01,0x00,0x12,0x04,0x01,0xBD,0x01,0x09,0xE7,0x02,0x00,0x01,0x20,0x01, +0x18,0x08,0xA8,0x09,0x01,0xBD,0x02,0x03,0xE7,0x20,0x20,0x00,0x01,0xBD,0x03,0x06, +0xE7,0x00,0xDC,0x11,0x70,0x00,0x20,0x01,0xE9,0xC9,0x06,0xE7,0x2A,0xCE,0x02,0x70, +0x01,0x04,0x01,0xE9,0x00,0x01,0xBD,0x00,0x01,0xD1,0x27,0x04,0xC9,0x04,0x0C,0x6D, +0x01,0x00,0x35,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x30,0xC3,0x1B,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x08,0x78,0x56,0xE7,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x53,0x00,0x00,0x00,0x67,0x11,0xF7,0x97 diff --git a/drivers/input/touchscreen/hxchipset83112b/himax_common.c b/drivers/input/touchscreen/hxchipset83112b/himax_common.c index 5f1a98fde846..3c9791e35d37 100755 --- a/drivers/input/touchscreen/hxchipset83112b/himax_common.c +++ b/drivers/input/touchscreen/hxchipset83112b/himax_common.c @@ -31,7 +31,7 @@ unsigned char i_CTPM_FW_HX83112A[]= }; unsigned char i_CTPM_FW_HX83112B[]= { -#include "FP_DJN_Arima_CID0804_D02_C14_20190903.i" +#include "FP_DJN_Arima_CID0804_D02_C15_20201209.i" }; #endif -- GitLab From 8eaeb9fb3e86a0e6988d0fb246f42989f28bf75f Mon Sep 17 00:00:00 2001 From: michaellin Date: Mon, 16 Nov 2020 16:11:02 +0800 Subject: [PATCH 59/96] Modify chip ID for PN553 A0 Change-Id: Ia9343e7f28d2672283a453ed38d77bf6f9530b22 (cherry picked from commit 65fed4b7968b556536bc3154d02d36e51a1bf318) --- drivers/nfc/nq-nci.c | 1 + drivers/nfc/nq-nci.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/nfc/nq-nci.c b/drivers/nfc/nq-nci.c index 15a6c5355b9f..3fd060ad3045 100755 --- a/drivers/nfc/nq-nci.c +++ b/drivers/nfc/nq-nci.c @@ -842,6 +842,7 @@ static int nfcc_hw_check(struct i2c_client *client, struct nqx_dev *nqx_dev) dev_dbg(&client->dev, "%s: ## NFCC == NQ220 ##\n", __func__); break; + case NFCC_PN553_A0: case NFCC_NQ_310: dev_dbg(&client->dev, "%s: ## NFCC == NQ310 ##\n", __func__); diff --git a/drivers/nfc/nq-nci.h b/drivers/nfc/nq-nci.h index d17897db7bab..4d1155955d79 100644 --- a/drivers/nfc/nq-nci.h +++ b/drivers/nfc/nq-nci.h @@ -46,7 +46,8 @@ enum nfcc_initial_core_reset_ntf { enum nfcc_chip_variant { NFCC_NQ_210 = 0x48, /**< NFCC NQ210 */ NFCC_NQ_220 = 0x58, /**< NFCC NQ220 */ - NFCC_NQ_310 = 0x40, /**< NFCC NQ310 */ + NFCC_PN553_A0 = 0x40, /**< NFCC PN553_A0 */ + NFCC_NQ_310 = 0x41, /**< NFCC NQ310 */ NFCC_NQ_330 = 0x51, /**< NFCC NQ330 */ NFCC_SN100_A = 0xa3, /**< NFCC SN100_A */ NFCC_SN100_B = 0xa4, /**< NFCC SN100_B */ -- GitLab From fd2347938091584f4a6c26dcce0a0950d802dbaf Mon Sep 17 00:00:00 2001 From: Vlastimil Babka Date: Fri, 26 Feb 2021 17:22:00 +0100 Subject: [PATCH 60/96] mm, thp: make do_huge_pmd_wp_page() lock page for testing mapcount Jann reported [1] a race between __split_huge_pmd_locked() and page_trans_huge_map_swapcount() which can result in a page to be reused instead of COWed. This was later assigned CVE-2020-29368. This was fixed by commit c444eb564fb1 ("mm: thp: make the THP mapcount atomic against __split_huge_pmd_locked()") by doing the split under the page lock, while all users of page_trans_huge_map_swapcount() were already also under page lock. The fix was backported also to 4.9 stable series. When testing the backport on a 4.12 based kernel, Nicolai noticed the POC from [1] still reproduces after backporting c444eb564fb1 and identified a missing page lock in do_huge_pmd_wp_page() around the call to page_trans_huge_mapcount(). The page lock was only added in ba3c4ce6def4 ("mm, THP, swap: make reuse_swap_page() works for THP swapped out") in 4.14. The commit also wrapped page_trans_huge_mapcount() into page_trans_huge_map_swapcount() for the purposes of COW decisions. I have verified that 4.9.y indeed also reproduces with the POC. Backporting ba3c4ce6def4 alone however is not possible as it's part of a larger effort of optimizing THP swapping, which would be risky to backport fully. Therefore this 4.9-stable-only patch just wraps page_trans_huge_mapcount() in page_trans_huge_mapcount() under page lock the same way as ba3c4ce6def4 does, but without the page_trans_huge_map_swapcount() part. Other callers of page_trans_huge_mapcount() are all under page lock already. I have verified the POC no longer reproduces afterwards. [1] https://bugs.chromium.org/p/project-zero/issues/detail?id=2045 Reported-by: Nicolai Stange Signed-off-by: Vlastimil Babka Signed-off-by: Sasha Levin Issue: FP3SEC-44 (cherry picked from commit cc916628eae7a8494b9a3de329d7baf12fd964c6) Change-Id: Ibfe3129de6b4ee6c73191853194d6d2de7463ad2 --- mm/huge_memory.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mm/huge_memory.c b/mm/huge_memory.c index fac621f1b29c..1c84c5cf75ff 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1024,6 +1024,19 @@ int do_huge_pmd_wp_page(struct fault_env *fe, pmd_t orig_pmd) * We can only reuse the page if nobody else maps the huge page or it's * part. */ + if (!trylock_page(page)) { + get_page(page); + spin_unlock(fe->ptl); + lock_page(page); + spin_lock(fe->ptl); + if (unlikely(!pmd_same(*fe->pmd, orig_pmd))) { + unlock_page(page); + put_page(page); + goto out_unlock; + } + put_page(page); + } + if (page_trans_huge_mapcount(page, NULL) == 1) { pmd_t entry; entry = pmd_mkyoung(orig_pmd); @@ -1031,8 +1044,10 @@ int do_huge_pmd_wp_page(struct fault_env *fe, pmd_t orig_pmd) if (pmdp_set_access_flags(vma, haddr, fe->pmd, entry, 1)) update_mmu_cache_pmd(vma, fe->address, fe->pmd); ret |= VM_FAULT_WRITE; + unlock_page(page); goto out_unlock; } + unlock_page(page); get_page(page); spin_unlock(fe->ptl); alloc: -- GitLab From a96644aaea8eec69d1158dd7fca7ac93cd5bee88 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 10 Dec 2021 16:28:30 -0800 Subject: [PATCH 61/96] wait: add wake_up_pollfree() commit 42288cb44c4b5fff7653bc392b583a2b8bd6a8c0 upstream. Several ->poll() implementations are special in that they use a waitqueue whose lifetime is the current task, rather than the struct file as is normally the case. This is okay for blocking polls, since a blocking poll occurs within one task; however, non-blocking polls require another solution. This solution is for the queue to be cleared before it is freed, using 'wake_up_poll(wq, EPOLLHUP | POLLFREE);'. However, that has a bug: wake_up_poll() calls __wake_up() with nr_exclusive=1. Therefore, if there are multiple "exclusive" waiters, and the wakeup function for the first one returns a positive value, only that one will be called. That's *not* what's needed for POLLFREE; POLLFREE is special in that it really needs to wake up everyone. Considering the three non-blocking poll systems: - io_uring poll doesn't handle POLLFREE at all, so it is broken anyway. - aio poll is unaffected, since it doesn't support exclusive waits. However, that's fragile, as someone could add this feature later. - epoll doesn't appear to be broken by this, since its wakeup function returns 0 when it sees POLLFREE. But this is fragile. Although there is a workaround (see epoll), it's better to define a function which always sends POLLFREE to all waiters. Add such a function. Also make it verify that the queue really becomes empty after all waiters have been woken up. Reported-by: Linus Torvalds Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211209010455.42744-2-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 0e92a7e47a0411d5208990c83a3d200515e314e8) Issue: FP3SEC-255 Change-Id: I1ec70169a39be42640172af512f4b47827ef5569 --- include/linux/wait.h | 26 ++++++++++++++++++++++++++ kernel/sched/wait.c | 8 ++++++++ 2 files changed, 34 insertions(+) diff --git a/include/linux/wait.h b/include/linux/wait.h index 2408e8d5c05c..e022ee95bd45 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -202,6 +202,7 @@ void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key); void __wake_up_sync_key(wait_queue_head_t *q, unsigned int mode, int nr, void *key); void __wake_up_locked(wait_queue_head_t *q, unsigned int mode, int nr); void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr); +void __wake_up_pollfree(wait_queue_head_t *wq_head); void __wake_up_bit(wait_queue_head_t *, void *, int); int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned); int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, wait_bit_action_f *, unsigned); @@ -236,6 +237,31 @@ wait_queue_head_t *bit_waitqueue(void *, int); #define wake_up_interruptible_sync_poll(x, m) \ __wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, (void *) (m)) +/** + * wake_up_pollfree - signal that a polled waitqueue is going away + * @wq_head: the wait queue head + * + * In the very rare cases where a ->poll() implementation uses a waitqueue whose + * lifetime is tied to a task rather than to the 'struct file' being polled, + * this function must be called before the waitqueue is freed so that + * non-blocking polls (e.g. epoll) are notified that the queue is going away. + * + * The caller must also RCU-delay the freeing of the wait_queue_head, e.g. via + * an explicit synchronize_rcu() or call_rcu(), or via SLAB_DESTROY_BY_RCU. + */ +static inline void wake_up_pollfree(wait_queue_head_t *wq_head) +{ + /* + * For performance reasons, we don't always take the queue lock here. + * Therefore, we might race with someone removing the last entry from + * the queue, and proceed while they still hold the queue lock. + * However, rcu_read_lock() is required to be held in such cases, so we + * can safely proceed with an RCU-delayed free. + */ + if (waitqueue_active(wq_head)) + __wake_up_pollfree(wq_head); +} + #define ___wait_cond_timeout(condition) \ ({ \ bool __cond = (condition); \ diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c index 9453efe9b25a..133afaf05c3f 100644 --- a/kernel/sched/wait.c +++ b/kernel/sched/wait.c @@ -10,6 +10,7 @@ #include #include #include +#include void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *key) { @@ -156,6 +157,13 @@ void __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive) } EXPORT_SYMBOL_GPL(__wake_up_sync); /* For internal use only */ +void __wake_up_pollfree(wait_queue_head_t *wq_head) +{ + __wake_up(wq_head, TASK_NORMAL, 0, (void *)(POLLHUP | POLLFREE)); + /* POLLFREE must have cleared the queue. */ + WARN_ON_ONCE(waitqueue_active(wq_head)); +} + /* * Note: we use "set_current_state()" _after_ the wait-queue add, * because we need a memory barrier there on SMP, so that any -- GitLab From f0906e2b7cb9996209ecccf3efe7d47f16c86348 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 10 Dec 2021 16:28:31 -0800 Subject: [PATCH 62/96] binder: use wake_up_pollfree() commit a880b28a71e39013e357fd3adccd1d8a31bc69a8 upstream. wake_up_poll() uses nr_exclusive=1, so it's not guaranteed to wake up all exclusive waiters. Yet, POLLFREE *must* wake up all waiters. epoll and aio poll are fortunately not affected by this, but it's very fragile. Thus, the new function wake_up_pollfree() has been introduced. Convert binder to use wake_up_pollfree(). Reported-by: Linus Torvalds Fixes: f5cb779ba163 ("ANDROID: binder: remove waitqueue when thread exits.") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211209010455.42744-3-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman Change-Id: I0f08d9f9a40348d7d2381607fabe3648416ab2a2 Issue: FP3SEC-255 (cherry picked from commit 0487ea896e62b5a90a81ac6e73c35e595d77f499) --- drivers/android/binder.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 51bef2482149..dc08be5132c0 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -4756,23 +4756,20 @@ static int binder_thread_release(struct binder_proc *proc, } /* - * If this thread used poll, make sure we remove the waitqueue - * from any epoll data structures holding it with POLLFREE. - * waitqueue_active() is safe to use here because we're holding - * the inner lock. + * If this thread used poll, make sure we remove the waitqueue from any + * poll data structures holding it. */ - if ((thread->looper & BINDER_LOOPER_STATE_POLL) && - waitqueue_active(&thread->wait)) { - wake_up_poll(&thread->wait, POLLHUP | POLLFREE); - } + if (thread->looper & BINDER_LOOPER_STATE_POLL) + wake_up_pollfree(&thread->wait); binder_inner_proc_unlock(thread->proc); /* - * This is needed to avoid races between wake_up_poll() above and - * and ep_remove_waitqueue() called for other reasons (eg the epoll file - * descriptor being closed); ep_remove_waitqueue() holds an RCU read - * lock, so we can be sure it's done after calling synchronize_rcu(). + * This is needed to avoid races between wake_up_pollfree() above and + * someone else removing the last entry from the queue for other reasons + * (e.g. ep_remove_wait_queue() being called due to an epoll file + * descriptor being closed). Such other users hold an RCU read lock, so + * we can be sure they're done after we call synchronize_rcu(). */ if (thread->looper & BINDER_LOOPER_STATE_POLL) synchronize_rcu(); -- GitLab From a624749496f0aea6a1da67baad2b4a0e219ae161 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Fri, 10 Dec 2021 16:28:32 -0800 Subject: [PATCH 63/96] signalfd: use wake_up_pollfree() commit 9537bae0da1f8d1e2361ab6d0479e8af7824e160 upstream. wake_up_poll() uses nr_exclusive=1, so it's not guaranteed to wake up all exclusive waiters. Yet, POLLFREE *must* wake up all waiters. epoll and aio poll are fortunately not affected by this, but it's very fragile. Thus, the new function wake_up_pollfree() has been introduced. Convert signalfd to use wake_up_pollfree(). Reported-by: Linus Torvalds Fixes: d80e731ecab4 ("epoll: introduce POLLFREE to flush ->signalfd_wqh before kfree()") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20211209010455.42744-4-ebiggers@kernel.org Signed-off-by: Eric Biggers Signed-off-by: Greg Kroah-Hartman Change-Id: I2534cce4e3d5be1b439b01eb8717903e08bb8e65 Issue: FP3SEC-255 (cherry picked from commit 5ecb4e93d70a21f3b7094029986ef0c3e321f56c) --- fs/signalfd.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/fs/signalfd.c b/fs/signalfd.c index 270221fcef42..9c5fa0ab5e0f 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c @@ -34,17 +34,7 @@ void signalfd_cleanup(struct sighand_struct *sighand) { - wait_queue_head_t *wqh = &sighand->signalfd_wqh; - /* - * The lockless check can race with remove_wait_queue() in progress, - * but in this case its caller should run under rcu_read_lock() and - * sighand_cachep is SLAB_DESTROY_BY_RCU, we can safely return. - */ - if (likely(!waitqueue_active(wqh))) - return; - - /* wait_queue_t->func(POLLFREE) should do remove_wait_queue() */ - wake_up_poll(wqh, POLLHUP | POLLFREE); + wake_up_pollfree(&sighand->signalfd_wqh); } struct signalfd_ctx { -- GitLab From 770a824be52e1ee7e46b064a9b6e07abfada2ebb Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Mon, 28 Jun 2021 16:13:42 -0300 Subject: [PATCH 64/96] sctp: add size validation when walking chunks [ Upstream commit 50619dbf8db77e98d821d615af4f634d08e22698 ] The first chunk in a packet is ensured to be present at the beginning of sctp_rcv(), as a packet needs to have at least 1 chunk. But the second one, may not be completely available and ch->length can be over uninitialized memory. Fix here is by only trying to walk on the next chunk if there is enough to hold at least the header, and then proceed with the ch->length validation that is already there. Reported-by: Ilja Van Sprundel Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Sasha Levin Change-Id: Ic2b962d31bc5bd2a0bf8d064deead466d607b605 Issue: FP3SEC-257 (cherry picked from commit c7da1d1ed43a6c2bece0d287e2415adf2868697e) --- net/sctp/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sctp/input.c b/net/sctp/input.c index 969fb1623e4e..3077b3bb6229 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -1165,7 +1165,7 @@ static struct sctp_association *__sctp_rcv_walk_lookup(struct net *net, ch = (sctp_chunkhdr_t *) ch_end; chunk_num++; - } while (ch_end < skb_tail_pointer(skb)); + } while (ch_end + sizeof(*ch) < skb_tail_pointer(skb)); return asoc; } -- GitLab From 18faf0586c549c665d56570db1091a0bc09e2b49 Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Mon, 28 Jun 2021 16:13:43 -0300 Subject: [PATCH 65/96] sctp: validate chunk size in __rcv_asconf_lookup commit b6ffe7671b24689c09faa5675dd58f93758a97ae upstream. In one of the fallbacks that SCTP has for identifying an association for an incoming packet, it looks for AddIp chunk (from ASCONF) and take a peek. Thing is, at this stage nothing was validating that the chunk actually had enough content for that, allowing the peek to happen over uninitialized memory. Similar check already exists in actual asconf handling in sctp_verify_asconf(). Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Change-Id: Ibfe53fc724143423353ed6b2984d2508ee4fc457 Issue: FP3SEC-257 (cherry picked from commit 6b5361868870e9a097745446798aa10ee92c159c) --- net/sctp/input.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/sctp/input.c b/net/sctp/input.c index 3077b3bb6229..945526e9e297 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -1087,6 +1087,9 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( union sctp_addr_param *param; union sctp_addr paddr; + if (ntohs(ch->length) < sizeof(*asconf) + sizeof(struct sctp_paramhdr)) + return NULL; + /* Skip over the ADDIP header and find the Address parameter */ param = (union sctp_addr_param *)(asconf + 1); -- GitLab From bd53fbdd7ef7edbb36e04ffb451b0aa3fa97ca8c Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Mon, 28 Jun 2021 16:13:44 -0300 Subject: [PATCH 66/96] sctp: add param size validation for SCTP_PARAM_SET_PRIMARY commit ef6c8d6ccf0c1dccdda092ebe8782777cd7803c9 upstream. When SCTP handles an INIT chunk, it calls for example: sctp_sf_do_5_1B_init sctp_verify_init sctp_verify_param sctp_process_init sctp_process_param handling of SCTP_PARAM_SET_PRIMARY sctp_verify_init() wasn't doing proper size validation and neither the later handling, allowing it to work over the chunk itself, possibly being uninitialized memory. Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Change-Id: I032230924ead7a03dfb3101e9cd4d48e36bfc616 Issue: FP3SEC-257 (cherry picked from commit 4d2de0d232ee386fceacf7cdb20a6398c3c0854b) --- net/sctp/sm_make_chunk.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index acb0c2631c79..93397bd2b085 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2155,9 +2155,16 @@ static sctp_ierror_t sctp_verify_param(struct net *net, break; case SCTP_PARAM_SET_PRIMARY: - if (net->sctp.addip_enable) - break; - goto fallthrough; + if (!net->sctp.addip_enable) + goto fallthrough; + + if (ntohs(param.p->length) < sizeof(struct sctp_addip_param) + + sizeof(struct sctp_paramhdr)) { + sctp_process_inv_paramlength(asoc, param.p, + chunk, err_chunk); + retval = SCTP_IERROR_ABORT; + } + break; case SCTP_PARAM_HOST_NAME_ADDRESS: /* Tell the peer, we won't support this param. */ -- GitLab From d1b235d89e7b76003f2711273b9793c125e88899 Mon Sep 17 00:00:00 2001 From: Marcelo Ricardo Leitner Date: Mon, 28 Jun 2021 16:13:41 -0300 Subject: [PATCH 67/96] sctp: validate from_addr_param return commit 0c5dc070ff3d6246d22ddd931f23a6266249e3db upstream. Ilja reported that, simply putting it, nothing was validating that from_addr_param functions were operating on initialized memory. That is, the parameter itself was being validated by sctp_walk_params, but it doesn't check for types and their specific sizes and it could be a 0-length one, causing from_addr_param to potentially work over the next parameter or even uninitialized memory. The fix here is to, in all calls to from_addr_param, check if enough space is there for the wanted IP address type. Reported-by: Ilja Van Sprundel Signed-off-by: Marcelo Ricardo Leitner Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman Change-Id: I7c84e42afa19aa569885a676af27e33999b76430 Issue: FP3SEC-257 (cherry picked from commit 92e7bca98452aa760713016a434aa7edfc09fb13) --- include/net/sctp/structs.h | 2 +- net/sctp/bind_addr.c | 20 +++++++++++--------- net/sctp/input.c | 6 ++++-- net/sctp/ipv6.c | 7 ++++++- net/sctp/protocol.c | 7 ++++++- net/sctp/sm_make_chunk.c | 29 ++++++++++++++++------------- 6 files changed, 44 insertions(+), 27 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index b46133a41f55..c0707e9bd918 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -470,7 +470,7 @@ struct sctp_af { int saddr); void (*from_sk) (union sctp_addr *, struct sock *sk); - void (*from_addr_param) (union sctp_addr *, + bool (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, __be16 port, int iif); int (*to_addr_param) (const union sctp_addr *, diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c index 401c60750b20..00925523336a 100644 --- a/net/sctp/bind_addr.c +++ b/net/sctp/bind_addr.c @@ -285,20 +285,16 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, rawaddr = (union sctp_addr_param *)raw_addr_list; af = sctp_get_af_specific(param_type2af(param->type)); - if (unlikely(!af)) { + if (unlikely(!af) || + !af->from_addr_param(&addr, rawaddr, htons(port), 0)) { retval = -EINVAL; - sctp_bind_addr_clean(bp); - break; + goto out_err; } - af->from_addr_param(&addr, rawaddr, htons(port), 0); retval = sctp_add_bind_addr(bp, &addr, sizeof(addr), SCTP_ADDR_SRC, gfp); - if (retval) { - /* Can't finish building the list, clean up. */ - sctp_bind_addr_clean(bp); - break; - } + if (retval) + goto out_err; len = ntohs(param->length); addrs_len -= len; @@ -306,6 +302,12 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list, } return retval; + +out_err: + if (retval) + sctp_bind_addr_clean(bp); + + return retval; } /******************************************************************** diff --git a/net/sctp/input.c b/net/sctp/input.c index 945526e9e297..82716bed195a 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -1051,7 +1051,8 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct net *net, if (!af) continue; - af->from_addr_param(paddr, params.addr, sh->source, 0); + if (!af->from_addr_param(paddr, params.addr, sh->source, 0)) + continue; asoc = __sctp_lookup_association(net, laddr, paddr, transportp); if (asoc) @@ -1097,7 +1098,8 @@ static struct sctp_association *__sctp_rcv_asconf_lookup( if (unlikely(!af)) return NULL; - af->from_addr_param(&paddr, param, peer_port, 0); + if (af->from_addr_param(&paddr, param, peer_port, 0)) + return NULL; return __sctp_lookup_association(net, laddr, &paddr, transportp); } diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 50bc8c4ca906..01337204d2b6 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c @@ -490,15 +490,20 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk) } /* Initialize a sctp_addr from an address parameter. */ -static void sctp_v6_from_addr_param(union sctp_addr *addr, +static bool sctp_v6_from_addr_param(union sctp_addr *addr, union sctp_addr_param *param, __be16 port, int iif) { + if (ntohs(param->v6.param_hdr.length) < sizeof(struct sctp_ipv6addr_param)) + return false; + addr->v6.sin6_family = AF_INET6; addr->v6.sin6_port = port; addr->v6.sin6_flowinfo = 0; /* BUG */ addr->v6.sin6_addr = param->v6.addr; addr->v6.sin6_scope_id = iif; + + return true; } /* Initialize an address parameter from a sctp_addr and return the length diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index c5a2a538279b..c9956d770578 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -273,14 +273,19 @@ static void sctp_v4_to_sk_daddr(union sctp_addr *addr, struct sock *sk) } /* Initialize a sctp_addr from an address parameter. */ -static void sctp_v4_from_addr_param(union sctp_addr *addr, +static bool sctp_v4_from_addr_param(union sctp_addr *addr, union sctp_addr_param *param, __be16 port, int iif) { + if (ntohs(param->v4.param_hdr.length) < sizeof(struct sctp_ipv4addr_param)) + return false; + addr->v4.sin_family = AF_INET; addr->v4.sin_port = port; addr->v4.sin_addr.s_addr = param->v4.addr.s_addr; memset(addr->v4.sin_zero, 0, sizeof(addr->v4.sin_zero)); + + return true; } /* Initialize an address parameter from a sctp_addr and return the length diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 93397bd2b085..6587421bada6 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -2342,11 +2342,13 @@ int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk, /* Process the initialization parameters. */ sctp_walk_params(param, peer_init, init_hdr.params) { - if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS || - param.p->type == SCTP_PARAM_IPV6_ADDRESS)) { + if (!src_match && + (param.p->type == SCTP_PARAM_IPV4_ADDRESS || + param.p->type == SCTP_PARAM_IPV6_ADDRESS)) { af = sctp_get_af_specific(param_type2af(param.p->type)); - af->from_addr_param(&addr, param.addr, - chunk->sctp_hdr->source, 0); + if (!af->from_addr_param(&addr, param.addr, + chunk->sctp_hdr->source, 0)) + continue; if (sctp_cmp_addr_exact(sctp_source(chunk), &addr)) src_match = 1; } @@ -2540,7 +2542,8 @@ static int sctp_process_param(struct sctp_association *asoc, break; do_addr_param: af = sctp_get_af_specific(param_type2af(param.p->type)); - af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0); + if (!af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0)) + break; scope = sctp_scope(peer_addr); if (sctp_in_scope(net, &addr, scope)) if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED)) @@ -2633,15 +2636,13 @@ static int sctp_process_param(struct sctp_association *asoc, addr_param = param.v + sizeof(sctp_addip_param_t); af = sctp_get_af_specific(param_type2af(addr_param->p.type)); - if (af == NULL) + if (!af) break; - af->from_addr_param(&addr, addr_param, - htons(asoc->peer.port), 0); + if (!af->from_addr_param(&addr, addr_param, + htons(asoc->peer.port), 0)) + break; - /* if the address is invalid, we can't process it. - * XXX: see spec for what to do. - */ if (!af->addr_valid(&addr, NULL, NULL)) break; @@ -3053,7 +3054,8 @@ static __be16 sctp_process_asconf_param(struct sctp_association *asoc, if (unlikely(!af)) return SCTP_ERROR_DNS_FAILED; - af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0); + if (!af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0)) + return SCTP_ERROR_DNS_FAILED; /* ADDIP 4.2.1 This parameter MUST NOT contain a broadcast * or multicast address. @@ -3318,7 +3320,8 @@ static void sctp_asconf_param_success(struct sctp_association *asoc, /* We have checked the packet before, so we do not check again. */ af = sctp_get_af_specific(param_type2af(addr_param->p.type)); - af->from_addr_param(&addr, addr_param, htons(bp->port), 0); + if (!af->from_addr_param(&addr, addr_param, htons(bp->port), 0)) + return; switch (asconf_param->param_hdr.type) { case SCTP_PARAM_ADD_IP: -- GitLab From b756e7ee8fa23e0c30f89ef1046d58aa6f82ea07 Mon Sep 17 00:00:00 2001 From: Jann Horn Date: Mon, 27 Jul 2020 14:04:24 +0200 Subject: [PATCH 68/96] UPSTREAM: binder: Prevent context manager from incrementing ref 0 Binder is designed such that a binder_proc never has references to itself. If this rule is violated, memory corruption can occur when a process sends a transaction to itself; see e.g. . There is a remaining edgecase through which such a transaction-to-self can still occur from the context of a task with BINDER_SET_CONTEXT_MGR access: - task A opens /dev/binder twice, creating binder_proc instances P1 and P2 - P1 becomes context manager - P2 calls ACQUIRE on the magic handle 0, allocating index 0 in its handle table - P1 dies (by closing the /dev/binder fd and waiting a bit) - P2 becomes context manager - P2 calls ACQUIRE on the magic handle 0, allocating index 1 in its handle table [this triggers a warning: "binder: 1974:1974 tried to acquire reference to desc 0, got 1 instead"] - task B opens /dev/binder once, creating binder_proc instance P3 - P3 calls P2 (via magic handle 0) with (void*)1 as argument (two-way transaction) - P2 receives the handle and uses it to call P3 (two-way transaction) - P3 calls P2 (via magic handle 0) (two-way transaction) - P2 calls P2 (via handle 1) (two-way transaction) And then, if P2 does *NOT* accept the incoming transaction work, but instead closes the binder fd, we get a crash. Solve it by preventing the context manager from using ACQUIRE on ref 0. There shouldn't be any legitimate reason for the context manager to do that. Additionally, print a warning if someone manages to find another way to trigger a transaction-to-self bug in the future. Cc: stable@vger.kernel.org Fixes: 457b9a6f09f0 ("Staging: android: add binder driver") Acked-by: Todd Kjos Signed-off-by: Jann Horn Reviewed-by: Martijn Coenen Link: https://lore.kernel.org/r/20200727120424.1627555-1-jannh@google.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 4b836a1426cb0f1ef2a6e211d7e553221594f8fc) Signed-off-by: Greg Kroah-Hartman Change-Id: Id582f18932f3013be62fdd662d0a559e05eb10f8 (cherry picked from commit 86ec9d414948cb0f4ad8b9f823261f991cdd7d0f) --- drivers/android/binder.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index dc08be5132c0..a103028b7025 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -3116,6 +3116,12 @@ static void binder_transaction(struct binder_proc *proc, goto err_dead_binder; } e->to_node = target_node->debug_id; + if (WARN_ON(proc == target_proc)) { + return_error = BR_FAILED_REPLY; + return_error_param = -EINVAL; + return_error_line = __LINE__; + goto err_invalid_target_handle; + } if (security_binder_transaction(proc->tsk, target_proc->tsk) < 0) { return_error = BR_FAILED_REPLY; @@ -3694,10 +3700,17 @@ static int binder_thread_write(struct binder_proc *proc, struct binder_node *ctx_mgr_node; mutex_lock(&context->context_mgr_node_lock); ctx_mgr_node = context->binder_context_mgr_node; - if (ctx_mgr_node) + if (ctx_mgr_node) { + if (ctx_mgr_node->proc == proc) { + binder_user_error("%d:%d context manager tried to acquire desc 0\n", + proc->pid, thread->pid); + mutex_unlock(&context->context_mgr_node_lock); + return -EINVAL; + } ret = binder_inc_ref_for_node( proc, ctx_mgr_node, strong, NULL, &rdata); + } mutex_unlock(&context->context_mgr_node_lock); } if (ret) -- GitLab From 8c8e04fbcb017d4e030b12f116385dcc5d11531f Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Tue, 12 Oct 2021 09:56:12 -0700 Subject: [PATCH 69/96] UPSTREAM: binder: use euid from cred instead of using task commit 29bc22ac5e5bc63275e850f0c8fc549e3d0e306b upstream. Save the 'struct cred' associated with a binder process at initial open to avoid potential race conditions when converting to an euid. Set a transaction's sender_euid from the 'struct cred' saved at binder_open() instead of looking up the euid from the binder proc's 'struct task'. This ensures the euid is associated with the security context that of the task that opened binder. Cc: stable@vger.kernel.org # 4.4+ Fixes: 457b9a6f09f0 ("Staging: android: add binder driver") Signed-off-by: Todd Kjos Suggested-by: Stephen Smalley Suggested-by: Jann Horn Acked-by: Casey Schaufler Signed-off-by: Paul Moore Change-Id: I91922e7f359df5901749f1b09094c3c68d45aed4 Bug: 200688826 Signed-off-by: Todd Kjos Issue: FP3SEC-266 (cherry picked from commit a0e450acb13f84048cdd9e863df0e2c45653635a) --- drivers/android/binder.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index a103028b7025..84a38b98c056 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -503,6 +503,9 @@ struct binder_priority { * @files files_struct for process * (protected by @files_lock) * @files_lock mutex to protect @files + * @cred struct cred associated with the `struct file` + * in binder_open() + * (invariant after initialized) * @deferred_work_node: element for binder_deferred_list * (protected by binder_deferred_lock) * @deferred_work: bitmap of deferred work to perform @@ -550,6 +553,7 @@ struct binder_proc { struct task_struct *tsk; struct files_struct *files; struct mutex files_lock; + const struct cred *cred; struct hlist_node deferred_work_node; int deferred_work; bool is_dead; @@ -3214,7 +3218,7 @@ static void binder_transaction(struct binder_proc *proc, t->from = thread; else t->from = NULL; - t->sender_euid = task_euid(proc->tsk); + t->sender_euid = proc->cred->euid; t->to_proc = target_proc; t->to_thread = target_thread; t->code = tr->code; @@ -4698,6 +4702,7 @@ static void binder_free_proc(struct binder_proc *proc) BUG_ON(!list_empty(&proc->delivered_death)); binder_alloc_deferred_release(&proc->alloc); put_task_struct(proc->tsk); + put_cred(proc->cred); binder_stats_deleted(BINDER_STAT_PROC); kfree(proc); } @@ -5222,6 +5227,7 @@ static int binder_open(struct inode *nodp, struct file *filp) get_task_struct(current->group_leader); proc->tsk = current->group_leader; mutex_init(&proc->files_lock); + proc->cred = get_cred(filp->f_cred); INIT_LIST_HEAD(&proc->todo); if (binder_supported_policy(current->policy)) { proc->default_priority.sched_policy = current->policy; -- GitLab From 25b5e5647b8ab5d4249ccd4a25fc4be649397f6e Mon Sep 17 00:00:00 2001 From: Todd Kjos Date: Tue, 12 Oct 2021 09:56:13 -0700 Subject: [PATCH 70/96] BACKPORT: binder: use cred instead of task for selinux checks commit 52f88693378a58094c538662ba652aff0253c4fe upstream. Since binder was integrated with selinux, it has passed 'struct task_struct' associated with the binder_proc to represent the source and target of transactions. The conversion of task to SID was then done in the hook implementations. It turns out that there are race conditions which can result in an incorrect security context being used. Fix by using the 'struct cred' saved during binder_open and pass it to the selinux subsystem. Cc: stable@vger.kernel.org # 5.14 (need backport for earlier stables) Fixes: 79af73079d75 ("Add security hooks to binder and implement the hooks for SELinux.") Suggested-by: Jann Horn Signed-off-by: Todd Kjos Acked-by: Casey Schaufler Signed-off-by: Paul Moore Change-Id: Id7157515d2b08f11683aeb8ad9b8f1da075d34e7 [ tkjos@ fixed minor conflicts ] Bug: 200688826 Signed-off-by: Todd Kjos Issue: FP3SEC-266 (cherry picked from commit a69d9cd3d44dd9e9964b19740567620233ed6f17) --- drivers/android/binder.c | 12 ++++++------ include/linux/lsm_hooks.h | 32 ++++++++++++++++---------------- include/linux/security.h | 28 ++++++++++++++-------------- security/security.c | 14 +++++++------- security/selinux/hooks.c | 31 +++++++++++++------------------ 5 files changed, 56 insertions(+), 61 deletions(-) diff --git a/drivers/android/binder.c b/drivers/android/binder.c index 84a38b98c056..ebff3c3feff7 100644 --- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -2585,7 +2585,7 @@ static int binder_translate_binder(struct flat_binder_object *fp, ret = -EINVAL; goto done; } - if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { + if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { ret = -EPERM; goto done; } @@ -2631,7 +2631,7 @@ static int binder_translate_handle(struct flat_binder_object *fp, proc->pid, thread->pid, fp->handle); return -EINVAL; } - if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) { + if (security_binder_transfer_binder(proc->cred, target_proc->cred)) { ret = -EPERM; goto done; } @@ -2715,7 +2715,7 @@ static int binder_translate_fd(int fd, ret = -EBADF; goto err_fget; } - ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file); + ret = security_binder_transfer_file(proc->cred, target_proc->cred, file); if (ret < 0) { ret = -EPERM; goto err_security; @@ -3126,8 +3126,8 @@ static void binder_transaction(struct binder_proc *proc, return_error_line = __LINE__; goto err_invalid_target_handle; } - if (security_binder_transaction(proc->tsk, - target_proc->tsk) < 0) { + if (security_binder_transaction(proc->cred, + target_proc->cred) < 0) { return_error = BR_FAILED_REPLY; return_error_param = -EPERM; return_error_line = __LINE__; @@ -4905,7 +4905,7 @@ static int binder_ioctl_set_ctx_mgr(struct file *filp, ret = -EBUSY; goto out; } - ret = security_binder_set_context_mgr(proc->tsk); + ret = security_binder_set_context_mgr(proc->cred); if (ret < 0) goto out; if (uid_valid(context->binder_context_mgr_uid)) { diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index f510c681378c..eff58ecc0182 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -1147,22 +1147,22 @@ * * @binder_set_context_mgr * Check whether @mgr is allowed to be the binder context manager. - * @mgr contains the task_struct for the task being registered. + * @mgr contains the struct cred for the current binder process. * Return 0 if permission is granted. * @binder_transaction * Check whether @from is allowed to invoke a binder transaction call * to @to. - * @from contains the task_struct for the sending task. - * @to contains the task_struct for the receiving task. - * @binder_transfer_binder + * @from contains the struct cred for the sending process. + * @to contains the struct cred for the receiving process. + * @binder_transfer_binder: * Check whether @from is allowed to transfer a binder reference to @to. - * @from contains the task_struct for the sending task. - * @to contains the task_struct for the receiving task. - * @binder_transfer_file + * @from contains the struct cred for the sending process. + * @to contains the struct cred for the receiving process. + * @binder_transfer_file: * Check whether @from is allowed to transfer @file to @to. - * @from contains the task_struct for the sending task. + * @from contains the struct cred for the sending process. * @file contains the struct file being transferred. - * @to contains the task_struct for the receiving task. + * @to contains the struct cred for the receiving process. * * @ptrace_access_check: * Check permission before allowing the current process to trace the @@ -1365,13 +1365,13 @@ */ union security_list_options { - int (*binder_set_context_mgr)(struct task_struct *mgr); - int (*binder_transaction)(struct task_struct *from, - struct task_struct *to); - int (*binder_transfer_binder)(struct task_struct *from, - struct task_struct *to); - int (*binder_transfer_file)(struct task_struct *from, - struct task_struct *to, + int (*binder_set_context_mgr)(const struct cred *mgr); + int (*binder_transaction)(const struct cred *from, + const struct cred *to); + int (*binder_transfer_binder)(const struct cred *from, + const struct cred *to); + int (*binder_transfer_file)(const struct cred *from, + const struct cred *to, struct file *file); int (*ptrace_access_check)(struct task_struct *child, diff --git a/include/linux/security.h b/include/linux/security.h index bfb1b749da64..c6ef76aec04c 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -185,13 +185,13 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) extern int security_init(void); /* Security operations */ -int security_binder_set_context_mgr(struct task_struct *mgr); -int security_binder_transaction(struct task_struct *from, - struct task_struct *to); -int security_binder_transfer_binder(struct task_struct *from, - struct task_struct *to); -int security_binder_transfer_file(struct task_struct *from, - struct task_struct *to, struct file *file); +int security_binder_set_context_mgr(const struct cred *mgr); +int security_binder_transaction(const struct cred *from, + const struct cred *to); +int security_binder_transfer_binder(const struct cred *from, + const struct cred *to); +int security_binder_transfer_file(const struct cred *from, + const struct cred *to, struct file *file); int security_ptrace_access_check(struct task_struct *child, unsigned int mode); int security_ptrace_traceme(struct task_struct *parent); int security_capget(struct task_struct *target, @@ -398,25 +398,25 @@ static inline int security_init(void) return 0; } -static inline int security_binder_set_context_mgr(struct task_struct *mgr) +static inline int security_binder_set_context_mgr(const struct cred *mgr) { return 0; } -static inline int security_binder_transaction(struct task_struct *from, - struct task_struct *to) +static inline int security_binder_transaction(const struct cred *from, + const struct cred *to) { return 0; } -static inline int security_binder_transfer_binder(struct task_struct *from, - struct task_struct *to) +static inline int security_binder_transfer_binder(const struct cred *from, + const struct cred *to) { return 0; } -static inline int security_binder_transfer_file(struct task_struct *from, - struct task_struct *to, +static inline int security_binder_transfer_file(const struct cred *from, + const struct cred *to, struct file *file) { return 0; diff --git a/security/security.c b/security/security.c index d757debd56b6..0706f12ab06d 100644 --- a/security/security.c +++ b/security/security.c @@ -132,25 +132,25 @@ int __init security_module_enable(const char *module) /* Security operations */ -int security_binder_set_context_mgr(struct task_struct *mgr) +int security_binder_set_context_mgr(const struct cred *mgr) { return call_int_hook(binder_set_context_mgr, 0, mgr); } -int security_binder_transaction(struct task_struct *from, - struct task_struct *to) +int security_binder_transaction(const struct cred *from, + const struct cred *to) { return call_int_hook(binder_transaction, 0, from, to); } -int security_binder_transfer_binder(struct task_struct *from, - struct task_struct *to) +int security_binder_transfer_binder(const struct cred *from, + const struct cred *to) { return call_int_hook(binder_transfer_binder, 0, from, to); } -int security_binder_transfer_file(struct task_struct *from, - struct task_struct *to, struct file *file) +int security_binder_transfer_file(const struct cred *from, + const struct cred *to, struct file *file) { return call_int_hook(binder_transfer_file, 0, from, to, file); } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 6581b288e2af..90423e00a357 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -2078,21 +2078,18 @@ static inline u32 open_file_to_av(struct file *file) /* Hook functions begin here. */ -static int selinux_binder_set_context_mgr(struct task_struct *mgr) +static int selinux_binder_set_context_mgr(const struct cred *mgr) { - u32 mysid = current_sid(); - u32 mgrsid = task_sid(mgr); - - return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER, + return avc_has_perm(current_sid(), cred_sid(mgr), SECCLASS_BINDER, BINDER__SET_CONTEXT_MGR, NULL); } -static int selinux_binder_transaction(struct task_struct *from, - struct task_struct *to) +static int selinux_binder_transaction(const struct cred *from, + const struct cred *to) { u32 mysid = current_sid(); - u32 fromsid = task_sid(from); - u32 tosid = task_sid(to); + u32 fromsid = cred_sid(from); + u32 tosid = cred_sid(to); int rc; if (mysid != fromsid) { @@ -2106,21 +2103,19 @@ static int selinux_binder_transaction(struct task_struct *from, NULL); } -static int selinux_binder_transfer_binder(struct task_struct *from, - struct task_struct *to) +static int selinux_binder_transfer_binder(const struct cred *from, + const struct cred *to) { - u32 fromsid = task_sid(from); - u32 tosid = task_sid(to); - - return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER, + return avc_has_perm(cred_sid(from), cred_sid(to), + SECCLASS_BINDER, BINDER__TRANSFER, NULL); } -static int selinux_binder_transfer_file(struct task_struct *from, - struct task_struct *to, +static int selinux_binder_transfer_file(const struct cred *from, + const struct cred *to, struct file *file) { - u32 sid = task_sid(to); + u32 sid = cred_sid(to); struct file_security_struct *fsec = file->f_security; struct dentry *dentry = file->f_path.dentry; struct inode_security_struct *isec; -- GitLab From 8f0b3a08e5783d72d46f3223afeb810d1a7259b0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Dec 2021 18:59:27 +0100 Subject: [PATCH 71/96] UPSTREAM: USB: gadget: detect too-big endpoint 0 requests Sometimes USB hosts can ask for buffers that are too large from endpoint 0, which should not be allowed. If this happens for OUT requests, stall the endpoint, but for IN requests, trim the request size to the endpoint buffer size. Co-developed-by: Szymon Heidrich Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 153a2d7e3350cc89d406ba2d35be8793a64c2038) Bug: 210292367 Signed-off-by: Greg Kroah-Hartman Change-Id: I9bbd6154177d7a1fb6c2e3a3dffa96634d85bb7f Signed-off-by: Greg Kroah-Hartman Issue: FP3SEC-288 (cherry picked from commit d6b6272a552b1c2ea42987637ee00f0b6af0712c) --- drivers/usb/gadget/composite.c | 12 ++++++++++++ drivers/usb/gadget/legacy/dbgp.c | 13 +++++++++++++ drivers/usb/gadget/legacy/inode.c | 16 +++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f7367ba4b2aa..3c1135292d0f 100755 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1736,6 +1736,18 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) struct usb_function *f = NULL; u8 endp; + if (w_length > USB_COMP_EP0_BUFSIZ) { + if (ctrl->bRequestType == USB_DIR_OUT) { + goto done; + } else { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); + w_length = USB_COMP_EP0_BUFSIZ; + } + } + /* partial re-init of the response message; the function or the * gadget might need to intercept e.g. a control-OUT completion * when we delegate to it. diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index 99ca3dabc4f3..ed19c12bea25 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -344,6 +344,19 @@ static int dbgp_setup(struct usb_gadget *gadget, void *data = NULL; u16 len = 0; + if (length > DBGP_REQ_LEN) { + if (ctrl->bRequestType == USB_DIR_OUT) { + return err; + } else { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(DBGP_REQ_LEN); + length = DBGP_REQ_LEN; + } + } + + if (request == USB_REQ_GET_DESCRIPTOR) { switch (value>>8) { case USB_DT_DEVICE: diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index cb02e9ecd8e7..4eff69d2cba1 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -113,6 +113,8 @@ enum ep0_state { /* enough for the whole queue: most events invalidate others */ #define N_EVENT 5 +#define RBUF_SIZE 256 + struct dev_data { spinlock_t lock; atomic_t count; @@ -147,7 +149,7 @@ struct dev_data { struct dentry *dentry; /* except this scratch i/o buffer for ep0 */ - u8 rbuf [256]; + u8 rbuf[RBUF_SIZE]; }; static inline void get_dev (struct dev_data *data) @@ -1336,6 +1338,18 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); + if (w_length > RBUF_SIZE) { + if (ctrl->bRequestType == USB_DIR_OUT) { + return value; + } else { + /* Cast away the const, we are going to overwrite on purpose. */ + __le16 *temp = (__le16 *)&ctrl->wLength; + + *temp = cpu_to_le16(RBUF_SIZE); + w_length = RBUF_SIZE; + } + } + spin_lock (&dev->lock); dev->setup_abort = 0; if (dev->state == STATE_DEV_UNCONNECTED) { -- GitLab From 8c88057fdc250148d2f5cd8e8c488dc5007da76c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 9 Dec 2021 19:02:15 +0100 Subject: [PATCH 72/96] UPSTREAM: USB: gadget: zero allocate endpoint 0 buffers Under some conditions, USB gadget devices can show allocated buffer contents to a host. Fix this up by zero-allocating them so that any extra data will all just be zeros. Reported-by: Szymon Heidrich Tested-by: Szymon Heidrich Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 86ebbc11bb3f60908a51f3e41a17e3f477c2eaa3) Bug: 210292367 Signed-off-by: Greg Kroah-Hartman Change-Id: I72b4376cd4296a8b8af0ade2d702cd420146f3aa Signed-off-by: Greg Kroah-Hartman Issue: FP3SEC-288 (cherry picked from commit 0a638b26e0e706f65b8cb3a88d3b7dc69b57d85e) --- drivers/usb/gadget/composite.c | 2 +- drivers/usb/gadget/legacy/dbgp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 3c1135292d0f..36ce31f59097 100755 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2334,7 +2334,7 @@ int composite_dev_prepare(struct usb_composite_driver *composite, if (!cdev->req) return -ENOMEM; - cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ + + cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ + (gadget->extra_buf_alloc), GFP_KERNEL); if (!cdev->req->buf) goto fail; diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index ed19c12bea25..f1c5a22704b2 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -136,7 +136,7 @@ static int dbgp_enable_ep_req(struct usb_ep *ep) goto fail_1; } - req->buf = kmalloc(DBGP_REQ_LEN, GFP_KERNEL); + req->buf = kzalloc(DBGP_REQ_LEN, GFP_KERNEL); if (!req->buf) { err = -ENOMEM; stp = 2; -- GitLab From 6f98acf8467580a40c5a6f5fc97e87b8b19c3b88 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 14 Dec 2021 19:46:21 +0100 Subject: [PATCH 73/96] FROMGIT: USB: gadget: bRequestType is a bitfield, not a enum Szymon rightly pointed out that the previous check for the endpoint direction in bRequestType was not looking at only the bit involved, but rather the whole value. Normally this is ok, but for some request types, bits other than bit 8 could be set and the check for the endpoint length could not stall correctly. Fix that up by only checking the single bit. Fixes: 153a2d7e3350 ("USB: gadget: detect too-big endpoint 0 requests") Cc: Felipe Balbi Reported-by: Szymon Heidrich Link: https://lore.kernel.org/r/20211214184621.385828-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit f08adf5add9a071160c68bb2a61d697f39ab0758 https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb.git usb-linus) Bug: 210292376 Signed-off-by: Greg Kroah-Hartman Change-Id: I7e708b2b94433009c87f697346e0515d93454f48 Issue: FP3SEC-288 (cherry picked from commit 52c0273c7435c83f114a5601a2d172ccd4c1e514) --- drivers/usb/gadget/composite.c | 6 +++--- drivers/usb/gadget/legacy/dbgp.c | 6 +++--- drivers/usb/gadget/legacy/inode.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 36ce31f59097..7f3cc5c0d290 100755 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1737,14 +1737,14 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) u8 endp; if (w_length > USB_COMP_EP0_BUFSIZ) { - if (ctrl->bRequestType == USB_DIR_OUT) { - goto done; - } else { + if (ctrl->bRequestType & USB_DIR_IN) { /* Cast away the const, we are going to overwrite on purpose. */ __le16 *temp = (__le16 *)&ctrl->wLength; *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ); w_length = USB_COMP_EP0_BUFSIZ; + } else { + goto done; } } diff --git a/drivers/usb/gadget/legacy/dbgp.c b/drivers/usb/gadget/legacy/dbgp.c index f1c5a22704b2..e8818ad973e4 100644 --- a/drivers/usb/gadget/legacy/dbgp.c +++ b/drivers/usb/gadget/legacy/dbgp.c @@ -345,14 +345,14 @@ static int dbgp_setup(struct usb_gadget *gadget, u16 len = 0; if (length > DBGP_REQ_LEN) { - if (ctrl->bRequestType == USB_DIR_OUT) { - return err; - } else { + if (ctrl->bRequestType & USB_DIR_IN) { /* Cast away the const, we are going to overwrite on purpose. */ __le16 *temp = (__le16 *)&ctrl->wLength; *temp = cpu_to_le16(DBGP_REQ_LEN); length = DBGP_REQ_LEN; + } else { + return err; } } diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 4eff69d2cba1..93f0cfb30317 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1339,14 +1339,14 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) u16 w_length = le16_to_cpu(ctrl->wLength); if (w_length > RBUF_SIZE) { - if (ctrl->bRequestType == USB_DIR_OUT) { - return value; - } else { + if (ctrl->bRequestType & USB_DIR_IN) { /* Cast away the const, we are going to overwrite on purpose. */ __le16 *temp = (__le16 *)&ctrl->wLength; *temp = cpu_to_le16(RBUF_SIZE); w_length = RBUF_SIZE; + } else { + return value; } } -- GitLab From 80d7f07f48af432f6126877a2fb689cb01a4629e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 21 Feb 2022 11:03:13 +0100 Subject: [PATCH 74/96] lib/iov_iter: initialize "flags" in new pipe_buffer commit 9d2231c5d74e13b2a0546fee6737ee4446017903 upstream. The functions copy_page_to_iter_pipe() and push_pipe() can both allocate a new pipe_buffer, but the "flags" member initializer is missing. Fixes: 241699cd72a8 ("new iov_iter flavour: pipe-backed") To: Alexander Viro To: linux-fsdevel@vger.kernel.org To: linux-kernel@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Max Kellermann Signed-off-by: Al Viro Signed-off-by: Greg Kroah-Hartman Bug: 220741611 Change-Id: I91076a0b6327ee8dd87e75fc875062b6adf2de4c Issue: FP3SEC-335 (cherry picked from commit c460ef6e0596eb5ca844c45338c20f6023f1e43c) --- lib/iov_iter.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/iov_iter.c b/lib/iov_iter.c index a75ea633b5c4..9bb4b3e36dd2 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -370,6 +370,7 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by return 0; pipe->nrbufs++; buf->ops = &page_cache_pipe_buf_ops; + buf->flags = 0; get_page(buf->page = page); buf->offset = offset; buf->len = bytes; @@ -494,6 +495,7 @@ static size_t push_pipe(struct iov_iter *i, size_t size, break; pipe->nrbufs++; pipe->bufs[idx].ops = &default_pipe_buf_ops; + pipe->bufs[idx].flags = 0; pipe->bufs[idx].page = page; pipe->bufs[idx].offset = 0; if (left <= PAGE_SIZE) { -- GitLab From 1143950334b6a1cf1da3542d1686ba2f9eda8078 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 25 Jan 2022 14:18:08 +0000 Subject: [PATCH 75/96] ion: Do not 'put' ION handle until after its final use pass_to_user() eventually calls kref_put() on an ION handle which is still live, potentially allowing for it to be legitimately freed by the client. Prevent this from happening before its final use in both ION_IOC_ALLOC and ION_IOC_IMPORT. Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman (cherry picked from commit c47385c73fced27375559d1a2eb10f165a0869b0) Issue: FP3SEC-320 Change-Id: I658d8b13cce60b6d384fa0e630980f0d459ca52c (cherry picked from commit a84b980fcde59e2c1629723bb2aa1eedb78b83ab) --- drivers/staging/android/ion/ion.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c index 46decb1669c9..55a051130165 100644 --- a/drivers/staging/android/ion/ion.c +++ b/drivers/staging/android/ion/ion.c @@ -1635,10 +1635,10 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) data.allocation.flags, true); if (IS_ERR(handle)) return PTR_ERR(handle); - pass_to_user(handle); data.allocation.handle = handle->id; cleanup_handle = handle; + pass_to_user(handle); break; } case ION_IOC_FREE: @@ -1683,11 +1683,12 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (IS_ERR(handle)) { ret = PTR_ERR(handle); } else { + data.handle.handle = handle->id; handle = pass_to_user(handle); - if (IS_ERR(handle)) + if (IS_ERR(handle)) { ret = PTR_ERR(handle); - else - data.handle.handle = handle->id; + data.handle.handle = 0; + } } break; } -- GitLab From 3a77289b614ed598f04d7b7ef72f39e510072868 Mon Sep 17 00:00:00 2001 From: Bharath Date: Thu, 14 Oct 2021 17:15:39 +0530 Subject: [PATCH 76/96] Conditionally build texfat.ko module Build the module only when TARGET_GENERATE_TEXFAT flag is set to true. Issue: FP3-A11#46 Change-Id: I4da79fc15db45ba7347464e21b4234e4895ddbd4 (cherry picked from commit 69f9a331584339a4f576ba33d8459c700d710b7b) --- AndroidKernel.mk | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index 35726c3849ed..b61f13e10824 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -213,7 +213,13 @@ $(KERNEL_CONFIG): $(KERNEL_OUT) echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi +ifeq ($(TARGET_GENERATE_TEXFAT), true) +# Pull in the texfat kernel module build macros +include vendor/tuxera/texfat.mk +endif + ifeq ($(TARGET_KERNEL_APPEND_DTB), true) +ifeq ($(TARGET_GENERATE_TEXFAT), true) TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) @@ -222,7 +228,21 @@ $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules_install $(mv-modules) + $(clean-up-texfat) + $(generate-texfat) + $(extract-texfat) $(clean-module-folder) +else +TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image +$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) +$(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) + $(hide) echo "Building kernel modules..." + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) Image + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules + $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules_install + $(mv-modules) + $(clean-module-folder) +endif $(TARGET_PREBUILT_INT_KERNEL): $(TARGET_PREBUILT_INT_KERNEL_IMAGE) $(hide) echo "Building kernel..." -- GitLab From 8b137b306e07a54312c9396df56319a2d565a111 Mon Sep 17 00:00:00 2001 From: Bharath Date: Fri, 6 Aug 2021 11:35:25 +0530 Subject: [PATCH 77/96] Enable CONFIG_NLS_UTF8 config This is needed to build and enable exFAT/texFAT kernel module. Issue: FP3-A11#46 Change-Id: Id798170207b88ccc22b0543e961067c16edc8040 --- arch/arm64/configs/msm8953-perf_defconfig | 3 +++ arch/arm64/configs/msm8953_defconfig | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm64/configs/msm8953-perf_defconfig b/arch/arm64/configs/msm8953-perf_defconfig index c4dacd7a1e84..4563cabbd370 100755 --- a/arch/arm64/configs/msm8953-perf_defconfig +++ b/arch/arm64/configs/msm8953-perf_defconfig @@ -689,3 +689,6 @@ CONFIG_SND_SOC_TAS2557=y CONFIG_TAS2557_REGMAP=y CONFIG_TAS2557_CODEC=y CONFIG_TAS2557_MISC=y + +# For exFAT module +CONFIG_NLS_UTF8=y diff --git a/arch/arm64/configs/msm8953_defconfig b/arch/arm64/configs/msm8953_defconfig index 0fb0e891f161..757e5519917a 100755 --- a/arch/arm64/configs/msm8953_defconfig +++ b/arch/arm64/configs/msm8953_defconfig @@ -753,3 +753,6 @@ CONFIG_SND_SOC_TAS2557=y CONFIG_TAS2557_REGMAP=y CONFIG_TAS2557_CODEC=y CONFIG_TAS2557_MISC=y + +# For exFAT module +CONFIG_NLS_UTF8=y -- GitLab From 39dd7fced74363a5a618d9cb438024462da80e43 Mon Sep 17 00:00:00 2001 From: Bharath Date: Wed, 4 May 2022 16:46:42 +0530 Subject: [PATCH 78/96] Revert "Adjust AndroidKernel.mk to match newer versions" This reverts commit 72e1a0a7a2aa07a506ea8530f5709651ca3be87c. Not required for clang based compilation. Issue: FP3-A11#330 Change-Id: I5980d0177ae1c25dc71cbd36051935aef3827038 --- AndroidKernel.mk | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/AndroidKernel.mk b/AndroidKernel.mk index b61f13e10824..52c8381c972b 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -41,6 +41,13 @@ KERNEL_CONFIG_OVERRIDE := CONFIG_ANDROID_BINDER_IPC_32BIT=y endif endif +TARGET_KERNEL_CROSS_COMPILE_PREFIX := $(strip $(TARGET_KERNEL_CROSS_COMPILE_PREFIX)) +ifeq ($(TARGET_KERNEL_CROSS_COMPILE_PREFIX),) +KERNEL_CROSS_COMPILE := arm-eabi- +else +KERNEL_CROSS_COMPILE := $(TARGET_KERNEL_CROSS_COMPILE_PREFIX) +endif + ifeq ($(KERNEL_LLVM_SUPPORT), true) ifeq ($(KERNEL_SD_LLVM_SUPPORT), true) #Using sd-llvm compiler ifeq ($(shell echo $(SDCLANG_PATH) | head -c 1),/) @@ -168,14 +175,6 @@ $(TARGET_PREBUILT_INT_KERNEL_VM): $(KERNEL_VM_USR) endif endif -TARGET_KERNEL_CLANG_PATH ?= $(BUILD_TOP)/prebuilts/clang/host/$(HOST_OS)-x86/$(KERNEL_CLANG_VERSION) -PATH_OVERRIDE := PATH=$(TARGET_KERNEL_CLANG_PATH)/bin:$$PATH LD_LIBRARY_PATH=$(TARGET_KERNEL_CLANG_PATH)/lib64:$$LD_LIBRARY_PATH - -PATH_OVERRIDE += PATH=$(KERNEL_TOOLCHAIN_PATH_gcc)/bin:$$PATH - -# System tools are no longer allowed on 10+ -PATH_OVERRIDE += $(TOOLS_PATH_OVERRIDE) - ifneq ($(KERNEL_VM_DEFCONFIG),) $(KERNEL_VM_OUT): mkdir -p $(KERNEL_VM_OUT); @@ -207,7 +206,7 @@ $(KERNEL_OUT): mkdir -p $(KERNEL_OUT) $(KERNEL_CONFIG): $(KERNEL_OUT) - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_DEFCONFIG) + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_DEFCONFIG) $(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \ echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \ echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ @@ -224,9 +223,9 @@ TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) $(hide) echo "Building kernel modules..." - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) Image - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules_install + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) Image + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install $(mv-modules) $(clean-up-texfat) $(generate-texfat) @@ -237,9 +236,9 @@ TARGET_PREBUILT_INT_KERNEL_IMAGE := $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/Image $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_USR) $(TARGET_PREBUILT_INT_KERNEL_IMAGE): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) $(hide) echo "Building kernel modules..." - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) Image - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) modules_install + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) Image + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) modules + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) INSTALL_MOD_PATH=$(BUILD_ROOT_LOC)../$(KERNEL_MODULES_INSTALL) INSTALL_MOD_STRIP=1 $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) modules_install $(mv-modules) $(clean-module-folder) endif @@ -247,7 +246,7 @@ endif $(TARGET_PREBUILT_INT_KERNEL): $(TARGET_PREBUILT_INT_KERNEL_IMAGE) $(hide) echo "Building kernel..." $(hide) rm -rf $(KERNEL_OUT)/arch/$(KERNEL_ARCH)/boot/dts - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_CFLAGS) + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_CFLAGS) else TARGET_PREBUILT_INT_KERNEL_IMAGE := $(TARGET_PREBUILT_INT_KERNEL) $(TARGET_PREBUILT_INT_KERNEL): $(KERNEL_OUT) $(KERNEL_HEADERS_INSTALL) @@ -262,8 +261,8 @@ endif $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) $(hide) if [ ! -z "$(KERNEL_HEADER_DEFCONFIG)" ]; then \ rm -f $(BUILD_ROOT_LOC)$(KERNEL_CONFIG); \ - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD)$(KERNEL_HEADER_DEFCONFIG); \ - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) headers_install;\ + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_HEADER_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_HEADER_DEFCONFIG); \ + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_HEADER_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) headers_install;\ if [ -d "$(KERNEL_HEADERS_INSTALL)/include/bringup_headers" ]; then \ cp -Rf $(KERNEL_HEADERS_INSTALL)/include/bringup_headers/* $(KERNEL_HEADERS_INSTALL)/include/ ;\ fi ;\ @@ -271,22 +270,22 @@ $(KERNEL_HEADERS_INSTALL): $(KERNEL_OUT) $(hide) if [ "$(KERNEL_HEADER_DEFCONFIG)" != "$(KERNEL_DEFCONFIG)" ]; then \ echo "Used a different defconfig for header generation"; \ rm -f $(BUILD_ROOT_LOC)$(KERNEL_CONFIG); \ - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) $(KERNEL_DEFCONFIG); fi + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) $(KERNEL_DEFCONFIG); fi $(hide) if [ ! -z "$(KERNEL_CONFIG_OVERRIDE)" ]; then \ echo "Overriding kernel config with '$(KERNEL_CONFIG_OVERRIDE)'"; \ echo $(KERNEL_CONFIG_OVERRIDE) >> $(KERNEL_OUT)/.config; \ - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) oldconfig; fi + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) oldconfig; fi .PHONY: kerneltags kerneltags: $(KERNEL_OUT) $(KERNEL_CONFIG) - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) tags + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) tags .PHONY: kernelconfig kernelconfig: $(KERNEL_OUT) $(KERNEL_CONFIG) env KCONFIG_NOTIMESTAMP=true \ - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) menuconfig + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) menuconfig env KCONFIG_NOTIMESTAMP=true \ - $(PATH_OVERRIDE) $(KERNEL_MAKE_CMD) $(KERNEL_MAKE_FLAGS) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE) $(KERNEL_CLANG_TRIPLE) $(KERNEL_CC) $(KERNEL_LD) savedefconfig + $(MAKE) -C $(TARGET_KERNEL_SOURCE) O=$(BUILD_ROOT_LOC)$(KERNEL_OUT) $(KERNEL_MAKE_ENV) ARCH=$(KERNEL_ARCH) CROSS_COMPILE=$(KERNEL_CROSS_COMPILE) $(real_cc) savedefconfig cp $(KERNEL_OUT)/defconfig $(TARGET_KERNEL_SOURCE)/arch/$(KERNEL_ARCH)/configs/$(KERNEL_DEFCONFIG) endif -- GitLab From 02360b258f840df3007e8e2f85296661dfc54476 Mon Sep 17 00:00:00 2001 From: Nathan Chancellor Date: Mon, 23 Jul 2018 13:32:53 -0700 Subject: [PATCH 79/96] scripts: Remove gcc-wrapper.py This adds an unnecessary dependency on Python when regular -Werror will do fine. Issue: FP3-A11#330 Signed-off-by: Nathan Chancellor Signed-off-by: khusika Change-Id: I81f0e52e7270923f7e3d30a79ec9e9205d47ae0b --- AndroidKernel.mk | 4 +- Makefile | 6 +-- scripts/gcc-wrapper.py | 95 ------------------------------------------ 3 files changed, 3 insertions(+), 102 deletions(-) delete mode 100755 scripts/gcc-wrapper.py diff --git a/AndroidKernel.mk b/AndroidKernel.mk index 52c8381c972b..f638c5dfedb5 100644 --- a/AndroidKernel.mk +++ b/AndroidKernel.mk @@ -68,9 +68,9 @@ KERNEL_GCC_NOANDROID_CHK := $(shell (echo "int main() {return 0;}" | $(KERNEL_CR real_cc := ifeq ($(KERNEL_LLVM_SUPPORT),true) ifeq ($(KERNEL_ARCH), arm64) - real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=aarch64-linux-gnu- + real_cc := CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=aarch64-linux-gnu- else - real_cc := REAL_CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=arm-linux-gnueabihf + real_cc := CC=$(KERNEL_LLVM_BIN) CLANG_TRIPLE=arm-linux-gnueabihf endif else ifeq ($(strip $(KERNEL_GCC_NOANDROID_CHK)),0) diff --git a/Makefile b/Makefile index 25f9ad4232c9..ed160a067b8a 100644 --- a/Makefile +++ b/Makefile @@ -348,7 +348,7 @@ include scripts/Kbuild.include # Make variables (CC, etc...) AS = $(CROSS_COMPILE)as LD = $(CROSS_COMPILE)ld -REAL_CC = $(CROSS_COMPILE)gcc +CC = $(CROSS_COMPILE)gcc LDGOLD = $(CROSS_COMPILE)ld.gold CPP = $(CC) -E AR = $(CROSS_COMPILE)ar @@ -364,10 +364,6 @@ PERL = perl PYTHON = python CHECK = sparse -# Use the wrapper for the compiler. This wrapper scans for new -# warnings and causes the build to stop upon encountering them -CC = $(PYTHON) $(srctree)/scripts/gcc-wrapper.py $(REAL_CC) - CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \ -Wbitwise -Wno-return-void $(CF) NOSTDINC_FLAGS = diff --git a/scripts/gcc-wrapper.py b/scripts/gcc-wrapper.py deleted file mode 100755 index 3d1d6fbcaa04..000000000000 --- a/scripts/gcc-wrapper.py +++ /dev/null @@ -1,95 +0,0 @@ -#! /usr/bin/env python2 -# -*- coding: utf-8 -*- - -# Copyright (c) 2011-2017, The Linux Foundation. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of The Linux Foundation nor -# the names of its contributors may be used to endorse or promote -# products derived from this software without specific prior written -# permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -# Invoke gcc, looking for warnings, and causing a failure if there are -# non-whitelisted warnings. - -import errno -import re -import os -import sys -import subprocess - -# Note that gcc uses unicode, which may depend on the locale. TODO: -# force LANG to be set to en_US.UTF-8 to get consistent warnings. - -allowed_warnings = set([ - ]) - -# Capture the name of the object file, can find it. -ofile = None - -warning_re = re.compile(r'''(.*/|)([^/]+\.[a-z]+:\d+):(\d+:)? warning:''') -def interpret_warning(line): - """Decode the message from gcc. The messages we care about have a filename, and a warning""" - line = line.rstrip('\n') - m = warning_re.match(line) - if m and m.group(2) not in allowed_warnings: - print >> sys.stderr, "error, forbidden warning:", m.group(2) - - # If there is a warning, remove any object if it exists. - if ofile: - try: - os.remove(ofile) - except OSError: - pass - sys.exit(1) - -def run_gcc(): - args = sys.argv[1:] - # Look for -o - try: - i = args.index('-o') - global ofile - ofile = args[i+1] - except (ValueError, IndexError): - pass - - compiler = sys.argv[0] - - try: - proc = subprocess.Popen(args, stderr=subprocess.PIPE) - for line in proc.stderr: - print >> sys.stderr, line, - interpret_warning(line) - - result = proc.wait() - except OSError as e: - result = e.errno - if result == errno.ENOENT: - print >> sys.stderr, args[0] + ':',e.strerror - print >> sys.stderr, 'Is your PATH set correctly?' - else: - print >> sys.stderr, ' '.join(args), str(e) - - return result - -if __name__ == '__main__': - status = run_gcc() - sys.exit(status) -- GitLab From e779d171915a51dbf6b75b141fb41e2cbd30f784 Mon Sep 17 00:00:00 2001 From: Bharath Date: Wed, 4 May 2022 16:51:25 +0530 Subject: [PATCH 80/96] Makefile: Remove unsupported cflag Clang throws an error stating that '-Wno-undefined-optimized' is unsupported. Hence, drop this flag. Issue: FP3-A11#330 Change-Id: I469abcf9b22a846e6051008926ac0dd7ea65fc18 --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index ed160a067b8a..3b752a9c0d11 100644 --- a/Makefile +++ b/Makefile @@ -531,7 +531,6 @@ KBUILD_CFLAGS += $(call cc-disable-warning, format-invalid-specifier) KBUILD_CFLAGS += $(call cc-disable-warning, gnu) KBUILD_CFLAGS += $(call cc-disable-warning, address-of-packed-member) KBUILD_CFLAGS += $(call cc-disable-warning, duplicate-decl-specifier) -KBUILD_CFLAGS += -Wno-undefined-optimized KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare KBUILD_CFLAGS += $(call cc-option, -Wno-sometimes-uninitialized) KBUILD_CFLAGS += -Wno-asm-operand-widths -- GitLab From 7a1445ad993bd56fa711cdc822e09c62a8754d16 Mon Sep 17 00:00:00 2001 From: Petri Gynther Date: Tue, 5 Nov 2019 15:56:00 -0800 Subject: [PATCH 81/96] msm: camera_v2: remove gcc invocations Remove gcc invocations, so that we can move to pure clang compilation. Resolves: make CC=clang HOSTCC=clang mrproper ... Android GCC has been deprecated in favor of Clang, and will be removed from Android in 2020-01 as per the deprecation plan in: https://android.googlesource.com/platform/prebuilts/clang/host/linux-x86/+/master/GCC_4_9_DEPRECATION.md Issue: FP3-A11#330 Bug: 141693040 Change-Id: I10557fb29b4a5d4139d690661c22ab5be3fedaaf Signed-off-by: Petri Gynther --- drivers/media/platform/msm/camera_v2/fd/Makefile | 1 - drivers/media/platform/msm/camera_v2/jpeg_10/Makefile | 2 -- drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile | 1 - 3 files changed, 4 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/fd/Makefile b/drivers/media/platform/msm/camera_v2/fd/Makefile index 8d01d3a8708d..a1d33dad11fc 100644 --- a/drivers/media/platform/msm/camera_v2/fd/Makefile +++ b/drivers/media/platform/msm/camera_v2/fd/Makefile @@ -1,4 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common ccflags-y += -Idrivers/media/platform/msm/camera_v2 diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile index 0b8dc1db225c..72808f94c54b 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile +++ b/drivers/media/platform/msm/camera_v2/jpeg_10/Makefile @@ -1,5 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) - ccflags-y += -Idrivers/media/platform/msm/camera_v2/jpeg_10 ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io ccflags-y += -Idrivers/media/platform/msm/camera_v2/common diff --git a/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile b/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile index 21cbadbd6425..239b664b78d5 100644 --- a/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile +++ b/drivers/media/platform/msm/camera_v2/jpeg_dma/Makefile @@ -1,4 +1,3 @@ -GCC_VERSION := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc) ccflags-y += -Idrivers/media/video/msm ccflags-y += -Idrivers/media/platform/msm/camera_v2/common obj-$(CONFIG_MSM_JPEGDMA) += msm_jpeg_dma_dev.o msm_jpeg_dma_hw.o -- GitLab From 5a08838922e72111a576d06c00110445f910b35f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 9 Feb 2022 16:37:53 +0100 Subject: [PATCH 82/96] UPSTREAM: usb: gadget: rndis: check size of RNDIS_MSG_SET command Check the size of the RNDIS_MSG_SET command given to us before attempting to respond to an invalid message size. Issue: FP3SEC-374 Bug: 162326603 Reported-by: Szymon Heidrich Cc: stable@kernel.org Tested-by: Szymon Heidrich Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 38ea1eac7d88072bbffb630e2b3db83ca649b826) Signed-off-by: Greg Kroah-Hartman Change-Id: I61168b48de4ca79a3a28dd4d3b81779bc25554c1 (cherry picked from commit 16d19b656133457225cf69a4825faf30a0ca59a4) (cherry picked from commit 528615555b59cbd659186d44b3c6db69c30414eb) --- drivers/usb/gadget/function/rndis.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c index 038993d20bcb..9305af25e805 100644 --- a/drivers/usb/gadget/function/rndis.c +++ b/drivers/usb/gadget/function/rndis.c @@ -650,14 +650,17 @@ static int rndis_set_response(struct rndis_params *params, rndis_set_cmplt_type *resp; rndis_resp_t *r; + BufLength = le32_to_cpu(buf->InformationBufferLength); + BufOffset = le32_to_cpu(buf->InformationBufferOffset); + if ((BufLength > RNDIS_MAX_TOTAL_SIZE) || + (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE)) + return -EINVAL; + r = rndis_add_response(params, sizeof(rndis_set_cmplt_type)); if (!r) return -ENOMEM; resp = (rndis_set_cmplt_type *)r->buf; - BufLength = le32_to_cpu(buf->InformationBufferLength); - BufOffset = le32_to_cpu(buf->InformationBufferOffset); - #ifdef VERBOSE_DEBUG pr_debug("%s: Length: %d\n", __func__, BufLength); pr_debug("%s: Offset: %d\n", __func__, BufOffset); -- GitLab From 5d2e2c296f1b6c9059af7f986f1326195b2c3301 Mon Sep 17 00:00:00 2001 From: Szymon Heidrich Date: Mon, 24 Jan 2022 12:14:00 +0100 Subject: [PATCH 83/96] UPSTREAM: USB: gadget: validate interface OS descriptor requests Stall the control endpoint in case provided index exceeds array size of MAX_CONFIG_INTERFACES or when the retrieved function pointer is null. Issue: FP3SEC-355 Issue: FP3SEC-404 Bug: 213172319 Signed-off-by: Szymon Heidrich Cc: stable@kernel.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 75e5b4849b81e19e9efe1654b30d7f3151c33c2c) Signed-off-by: Greg Kroah-Hartman Change-Id: I78f46b6f2140394a6bc6cff9f829c0742d7ad2fc (cherry picked from commit c7732dbce590ef33ac2345f21efa6703f78b9e95) (cherry picked from commit 823fc2b264f1ec12678564271c5fa34e3250cf83) --- drivers/usb/gadget/composite.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 7f3cc5c0d290..8e6d9732b5e6 100755 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -2053,6 +2053,9 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (w_index != 0x5 || (w_value >> 8)) break; interface = w_value & 0xFF; + if (interface >= MAX_CONFIG_INTERFACES || + !os_desc_cfg->interface[interface]) + break; buf[6] = w_index; if (w_length == 0x0A) { count = count_ext_prop(os_desc_cfg, -- GitLab From 7c430a32f252597e46750ea000228b91c5ba9967 Mon Sep 17 00:00:00 2001 From: Liu Jian Date: Fri, 16 Jul 2021 12:06:17 +0800 Subject: [PATCH 84/96] igmp: Add ip_mc_list lock in ip_check_mc_rcu commit 23d2b94043ca8835bd1e67749020e839f396a1c2 upstream. I got below panic when doing fuzz test: Kernel panic - not syncing: panic_on_warn set ... CPU: 0 PID: 4056 Comm: syz-executor.3 Tainted: G B 5.14.0-rc1-00195-gcff5c4254439-dirty #2 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014 Call Trace: dump_stack_lvl+0x7a/0x9b panic+0x2cd/0x5af end_report.cold+0x5a/0x5a kasan_report+0xec/0x110 ip_check_mc_rcu+0x556/0x5d0 __mkroute_output+0x895/0x1740 ip_route_output_key_hash_rcu+0x2d0/0x1050 ip_route_output_key_hash+0x182/0x2e0 ip_route_output_flow+0x28/0x130 udp_sendmsg+0x165d/0x2280 udpv6_sendmsg+0x121e/0x24f0 inet6_sendmsg+0xf7/0x140 sock_sendmsg+0xe9/0x180 ____sys_sendmsg+0x2b8/0x7a0 ___sys_sendmsg+0xf0/0x160 __sys_sendmmsg+0x17e/0x3c0 __x64_sys_sendmmsg+0x9e/0x100 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae RIP: 0033:0x462eb9 Code: f7 d8 64 89 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 bc ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f3df5af1c58 EFLAGS: 00000246 ORIG_RAX: 0000000000000133 RAX: ffffffffffffffda RBX: 000000000073bf00 RCX: 0000000000462eb9 RDX: 0000000000000312 RSI: 0000000020001700 RDI: 0000000000000007 RBP: 0000000000000004 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 00007f3df5af26bc R13: 00000000004c372d R14: 0000000000700b10 R15: 00000000ffffffff It is one use-after-free in ip_check_mc_rcu. In ip_mc_del_src, the ip_sf_list of pmc has been freed under pmc->lock protection. But access to ip_sf_list in ip_check_mc_rcu is not protected by the lock. Issue: FP3SEC-373 Signed-off-by: Liu Jian Signed-off-by: David S. Miller Signed-off-by: Lee Jones Signed-off-by: Greg Kroah-Hartman (cherry picked from commit ddd7e8b7b84836c584a284b98ca9bd7a348a0558) Change-Id: Iabf0da26b04eb378728fcdb5ca353a3b38e43678 --- net/ipv4/igmp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 02c1736c0b89..b7e5f2917340 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -2684,6 +2684,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u rv = 1; } else if (im) { if (src_addr) { + spin_lock_bh(&im->lock); for (psf = im->sources; psf; psf = psf->sf_next) { if (psf->sf_inaddr == src_addr) break; @@ -2694,6 +2695,7 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u im->sfcount[MCAST_EXCLUDE]; else rv = im->sfcount[MCAST_EXCLUDE] != 0; + spin_unlock_bh(&im->lock); } else rv = 1; /* unspecified source; tentatively allow */ } -- GitLab From bd1ffc5af96540ee5a439549984b8b2e59482a66 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Sat, 1 Jan 2022 01:21:38 +0800 Subject: [PATCH 85/96] usb: gadget: clear related members when goto fail commit 501e38a5531efbd77d5c73c0ba838a889bfc1d74 upstream. dev->config and dev->hs_config and dev->dev need to be cleaned if dev_config fails to avoid UAF. Issue: FP3SEC-397 Acked-by: Alan Stern Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20211231172138.7993-3-hbh25y@gmail.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit fdd64084e405544c5c11841ca9261785c988e2a1) Change-Id: If3ad511be65ab812407c11aa9829ebc56c3963f0 --- drivers/usb/gadget/legacy/inode.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 93f0cfb30317..bbc4b138abde 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1882,8 +1882,8 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) value = usb_gadget_probe_driver(&gadgetfs_driver); if (value != 0) { - kfree (dev->buf); - dev->buf = NULL; + spin_lock_irq(&dev->lock); + goto fail; } else { /* at this point "good" hardware has for the first time * let the USB the host see us. alternatively, if users @@ -1900,6 +1900,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) return value; fail: + dev->config = NULL; + dev->hs_config = NULL; + dev->dev = NULL; spin_unlock_irq (&dev->lock); pr_debug ("%s: %s fail %Zd, %p\n", shortname, __func__, value, dev); kfree (dev->buf); -- GitLab From 1116d7e712c8c247584126040a315cebd6699659 Mon Sep 17 00:00:00 2001 From: Hangyu Hua Date: Sat, 1 Jan 2022 01:21:37 +0800 Subject: [PATCH 86/96] usb: gadget: don't release an existing dev->buf commit 89f3594d0de58e8a57d92d497dea9fee3d4b9cda upstream. dev->buf does not need to be released if it already exists before executing dev_config. Issue: FP3SEC-397 Acked-by: Alan Stern Signed-off-by: Hangyu Hua Link: https://lore.kernel.org/r/20211231172138.7993-2-hbh25y@gmail.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit c13159a588818a1d2cd6519f4d3b6f7e17a9ffbd) Change-Id: I96c30f66a01a78ee27e6dd70b17f6ccb0ca38171 --- drivers/usb/gadget/legacy/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index bbc4b138abde..08e833b090f3 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1833,8 +1833,9 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) spin_lock_irq (&dev->lock); value = -EINVAL; if (dev->buf) { + spin_unlock_irq(&dev->lock); kfree(kbuf); - goto fail; + return value; } dev->buf = kbuf; -- GitLab From e6dfea8e78b288ad9f9d6a9a058a689b0368ec96 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 24 Jul 2017 09:46:18 -0700 Subject: [PATCH 87/96] HID: introduce hid_is_using_ll_driver commit fc2237a724a9e448599076d7d23497f51e2f7441 upstream. Although HID itself is transport-agnostic, occasionally a driver may want to interact with the low-level transport that a device is connected through. To do this, we need to know what kind of bus is in use. The first guess may be to look at the 'bus' field of the 'struct hid_device', but this field may be emulated in some cases (e.g. uhid). More ideally, we can check which ll_driver a device is using. This function introduces a 'hid_is_using_ll_driver' function and makes the 'struct hid_ll_driver' of the four most common transports accessible through hid.h. Signed-off-by: Jason Gerecke Acked-By: Benjamin Tissoires Signed-off-by: Jiri Kosina Signed-off-by: Greg Kroah-Hartman Issue: FP3SEC-378 (cherry picked from commit e1e84bd83f1d2eb4d37ad1b62aa67c29665e1184) Change-Id: I3631570a92f47bbf6d724ba1fbc28e5f4d9ebf41 --- drivers/hid/i2c-hid/i2c-hid-core.c | 3 ++- drivers/hid/uhid.c | 3 ++- drivers/hid/usbhid/hid-core.c | 3 ++- include/linux/hid.h | 11 +++++++++++ net/bluetooth/hidp/core.c | 3 ++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index 850527d5fab1..12918f15f651 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -871,7 +871,7 @@ static int i2c_hid_power(struct hid_device *hid, int lvl) return 0; } -static struct hid_ll_driver i2c_hid_ll_driver = { +struct hid_ll_driver i2c_hid_ll_driver = { .parse = i2c_hid_parse, .start = i2c_hid_start, .stop = i2c_hid_stop, @@ -881,6 +881,7 @@ static struct hid_ll_driver i2c_hid_ll_driver = { .output_report = i2c_hid_output_report, .raw_request = i2c_hid_raw_request, }; +EXPORT_SYMBOL_GPL(i2c_hid_ll_driver); static int i2c_hid_init_irq(struct i2c_client *client) { diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c index 7a136847c8b2..5e6d32251d09 100644 --- a/drivers/hid/uhid.c +++ b/drivers/hid/uhid.c @@ -374,7 +374,7 @@ static int uhid_hid_output_report(struct hid_device *hid, __u8 *buf, return uhid_hid_output_raw(hid, buf, count, HID_OUTPUT_REPORT); } -static struct hid_ll_driver uhid_hid_driver = { +struct hid_ll_driver uhid_hid_driver = { .start = uhid_hid_start, .stop = uhid_hid_stop, .open = uhid_hid_open, @@ -383,6 +383,7 @@ static struct hid_ll_driver uhid_hid_driver = { .raw_request = uhid_hid_raw_request, .output_report = uhid_hid_output_report, }; +EXPORT_SYMBOL_GPL(uhid_hid_driver); #ifdef CONFIG_COMPAT diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 7838343eb37c..3dd129561c14 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -1261,7 +1261,7 @@ static int usbhid_idle(struct hid_device *hid, int report, int idle, return hid_set_idle(dev, ifnum, report, idle); } -static struct hid_ll_driver usb_hid_driver = { +struct hid_ll_driver usb_hid_driver = { .parse = usbhid_parse, .start = usbhid_start, .stop = usbhid_stop, @@ -1274,6 +1274,7 @@ static struct hid_ll_driver usb_hid_driver = { .output_report = usbhid_output_report, .idle = usbhid_idle, }; +EXPORT_SYMBOL_GPL(usb_hid_driver); static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *id) { diff --git a/include/linux/hid.h b/include/linux/hid.h index 877bb9aaca18..5abeed48e1f1 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -763,6 +763,17 @@ struct hid_ll_driver { int (*idle)(struct hid_device *hdev, int report, int idle, int reqtype); }; +extern struct hid_ll_driver i2c_hid_ll_driver; +extern struct hid_ll_driver hidp_hid_driver; +extern struct hid_ll_driver uhid_hid_driver; +extern struct hid_ll_driver usb_hid_driver; + +static inline bool hid_is_using_ll_driver(struct hid_device *hdev, + struct hid_ll_driver *driver) +{ + return hdev->ll_driver == driver; +} + #define PM_HINT_FULLON 1<<5 #define PM_HINT_NORMAL 1<<1 diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 552e00b07196..0c1702b6a2b9 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c @@ -734,7 +734,7 @@ static void hidp_stop(struct hid_device *hid) hid->claimed = 0; } -static struct hid_ll_driver hidp_hid_driver = { +struct hid_ll_driver hidp_hid_driver = { .parse = hidp_parse, .start = hidp_start, .stop = hidp_stop, @@ -743,6 +743,7 @@ static struct hid_ll_driver hidp_hid_driver = { .raw_request = hidp_raw_request, .output_report = hidp_output_report, }; +EXPORT_SYMBOL_GPL(hidp_hid_driver); /* This function sets up the hid device. It does not add it to the HID system. That is done in hidp_add_connection(). */ -- GitLab From 58de77c36a34b3c80bf4d231997c0c5c4f0de07f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 1 Dec 2021 19:35:01 +0100 Subject: [PATCH 88/96] HID: add hid_is_usb() function to make it simpler for USB detection commit f83baa0cb6cfc92ebaf7f9d3a99d7e34f2e77a8a upstream. A number of HID drivers already call hid_is_using_ll_driver() but only for the detection of if this is a USB device or not. Make this more obvious by creating hid_is_usb() and calling the function that way. Also converts the existing hid_is_using_ll_driver() functions to use the new call. Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: stable@vger.kernel.org Tested-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20211201183503.2373082-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman Change-Id: Ibfa4252d4b6501a09a997bb9efbab46fae3fd1dc Issue: FP3SEC-378 (cherry picked from commit 28d8244f3ec961a11bfb4ad83cdc48ff9b8c47a7) --- include/linux/hid.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/linux/hid.h b/include/linux/hid.h index 5abeed48e1f1..bc3627b5ed65 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -774,6 +774,11 @@ static inline bool hid_is_using_ll_driver(struct hid_device *hdev, return hdev->ll_driver == driver; } +static inline bool hid_is_usb(struct hid_device *hdev) +{ + return hid_is_using_ll_driver(hdev, &usb_hid_driver); +} + #define PM_HINT_FULLON 1<<5 #define PM_HINT_NORMAL 1<<1 -- GitLab From ac9f34bfaae74378061f5c36c6f59fa7d835cbd9 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Dec 2021 09:12:31 +0100 Subject: [PATCH 89/96] HID: add USB_HID dependancy to hid-prodikeys commit 30cb3c2ad24b66fb7639a6d1f4390c74d6e68f94 upstream. The prodikeys HID driver only controls USB devices, yet did not have a dependancy on USB_HID. This causes build errors on some configurations like nios2 when building due to new changes to the prodikeys driver. Reported-by: kernel test robot Cc: stable@vger.kernel.org Cc: Jiri Kosina Cc: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20211203081231.2856936-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 5b8d74ff145de1b5adb133895fd63cd533d68422) Issue: FP3SEC-378 Change-Id: Ifbff6c7522a684fab6974565570a92e61651ae0a --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 7e4923942732..79e0facd2864 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -194,7 +194,7 @@ config HID_CORSAIR config HID_PRODIKEYS tristate "Prodikeys PC-MIDI Keyboard support" - depends on HID && SND + depends on USB_HID && SND select SND_RAWMIDI ---help--- Support for Prodikeys PC-MIDI Keyboard device support. -- GitLab From 852b99995f9dec5938733d75f808227a81a94b46 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 3 Dec 2021 08:59:27 +0100 Subject: [PATCH 90/96] HID: add USB_HID dependancy to hid-chicony commit d080811f27936f712f619f847389f403ac873b8f upstream. The chicony HID driver only controls USB devices, yet did not have a dependancy on USB_HID. This causes build errors on some configurations like sparc when building due to new changes to the chicony driver. Reported-by: Stephen Rothwell Cc: stable@vger.kernel.org Cc: Jiri Kosina Cc: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20211203075927.2829218-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 4435bc144fb6295db371e9753305a96f0c19b2ef) Issue: FP3SEC-378 Change-Id: Ic65d7879192eb876683d13eb18628dd0f4594e98 --- drivers/hid/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 79e0facd2864..0a23580f6dcc 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -176,7 +176,7 @@ config HID_CHERRY config HID_CHICONY tristate "Chicony devices" - depends on HID + depends on USB_HID default !EXPERT ---help--- Support for Chicony Tactical pad and special keys on Chicony keyboards. -- GitLab From 38355e1bb898558141b775e2c4cce8b2372f21b4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2021 12:48:19 +0100 Subject: [PATCH 91/96] HID: add USB_HID dependancy on some USB HID drivers commit f237d9028f844a86955fc9da59d7ac4a5c55d7d5 upstream. Some HID drivers are only for USB drivers, yet did not depend on CONFIG_USB_HID. This was hidden by the fact that the USB functions were stubbed out in the past, but now that drivers are checking for USB devices properly, build errors can occur with some random configurations. Reported-by: kernel test robot Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20211202114819.2511954-1-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit c57e3b8082a4860f31f71d113b3e66bb64b4eb0a) Issue: FP3SEC-378 Change-Id: Ia755dc2803f1111c33d1c4b06b02913eebdf34c0 --- drivers/hid/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 0a23580f6dcc..849f5a359e30 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -183,7 +183,7 @@ config HID_CHICONY config HID_CORSAIR tristate "Corsair devices" - depends on HID && USB && LEDS_CLASS + depends on USB_HID && LEDS_CLASS ---help--- Support for Corsair devices that are not fully compliant with the HID standard. @@ -421,7 +421,7 @@ config HID_LENOVO config HID_LOGITECH tristate "Logitech devices" - depends on HID + depends on USB_HID default !EXPERT ---help--- Support for Logitech devices that are not fully compliant with HID standard. @@ -741,7 +741,7 @@ config HID_SAITEK config HID_SAMSUNG tristate "Samsung InfraRed remote control or keyboards" - depends on HID + depends on USB_HID ---help--- Support for Samsung InfraRed remote control or keyboards. -- GitLab From bd2f549182f117137f6b8860505a27331086b77e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 1 Dec 2021 19:35:02 +0100 Subject: [PATCH 92/96] HID: wacom: fix problems when device is not a valid USB device commit 720ac467204a70308bd687927ed475afb904e11b upstream. The wacom driver accepts devices of more than just USB types, but some code paths can cause problems if the device being controlled is not a USB device due to a lack of checking. Add the needed checks to ensure that the USB device accesses are only happening on a "real" USB device, and not one on some other bus. Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: linux-input@vger.kernel.org Cc: stable@vger.kernel.org Tested-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20211201183503.2373082-2-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 1309eb2ef1001c4cc7e07b867ad9576d2cfeab47) Issue: FP3SEC-378 Change-Id: I605a7a3598b54693ce2104d4afdbdf879bb7fb2e --- drivers/hid/wacom_sys.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index e8b90b534f08..b74fcda49a22 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -506,7 +506,7 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, * Skip the query for this type and modify defaults based on * interface number. */ - if (features->type == WIRELESS) { + if (features->type == WIRELESS && intf) { if (intf->cur_altsetting->desc.bInterfaceNumber == 0) features->device_type = WACOM_DEVICETYPE_WL_MONITOR; else @@ -2115,6 +2115,9 @@ static void wacom_wireless_work(struct work_struct *work) wacom_destroy_battery(wacom); + if (!usbdev) + return; + /* Stylus interface */ hdev1 = usb_get_intfdata(usbdev->config->interface[1]); wacom1 = hid_get_drvdata(hdev1); @@ -2354,8 +2357,6 @@ static void wacom_remote_work(struct work_struct *work) static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - struct usb_device *dev = interface_to_usbdev(intf); struct wacom *wacom; struct wacom_wac *wacom_wac; struct wacom_features *features; @@ -2388,8 +2389,14 @@ static int wacom_probe(struct hid_device *hdev, wacom_wac->hid_data.inputmode = -1; wacom_wac->mode_report = -1; - wacom->usbdev = dev; - wacom->intf = intf; + if (hid_is_usb(hdev)) { + struct usb_interface *intf = to_usb_interface(hdev->dev.parent); + struct usb_device *dev = interface_to_usbdev(intf); + + wacom->usbdev = dev; + wacom->intf = intf; + } + mutex_init(&wacom->lock); INIT_WORK(&wacom->wireless_work, wacom_wireless_work); INIT_WORK(&wacom->battery_work, wacom_battery_work); -- GitLab From ef8b3e97a91802639bd30ee76d478a25087e5b3e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 1 Dec 2021 19:35:03 +0100 Subject: [PATCH 93/96] HID: check for valid USB device for many HID drivers commit 93020953d0fa7035fd036ad87a47ae2b7aa4ae33 upstream. Many HID drivers assume that the HID device assigned to them is a USB device as that was the only way HID devices used to be able to be created in Linux. However, with the additional ways that HID devices can be created for many different bus types, that is no longer true, so properly check that we have a USB device associated with the HID device before allowing a driver that makes this assumption to claim it. Cc: Jiri Kosina Cc: Benjamin Tissoires Cc: Michael Zaidman Cc: Stefan Achatz Cc: Maxime Coquelin Cc: Alexandre Torgue Cc: linux-input@vger.kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman Tested-by: Benjamin Tissoires [bentiss: amended for thrustmater.c hunk to apply] Signed-off-by: Benjamin Tissoires Link: https://lore.kernel.org/r/20211201183503.2373082-3-gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 10d0f0aaa5cde52bd5685ee8d0adc02f1efb1983) Issue: FP3SEC-378 Change-Id: I7908d6af9e70865a6db17fac75624064165449ad --- drivers/hid/hid-chicony.c | 8 ++++++-- drivers/hid/hid-corsair.c | 7 ++++++- drivers/hid/hid-elo.c | 3 +++ drivers/hid/hid-holtek-kbd.c | 9 +++++++-- drivers/hid/hid-holtek-mouse.c | 9 +++++++++ drivers/hid/hid-lg.c | 10 ++++++++-- drivers/hid/hid-prodikeys.c | 10 ++++++++-- drivers/hid/hid-roccat-arvo.c | 3 +++ drivers/hid/hid-roccat-isku.c | 3 +++ drivers/hid/hid-roccat-kone.c | 3 +++ drivers/hid/hid-roccat-koneplus.c | 3 +++ drivers/hid/hid-roccat-konepure.c | 3 +++ drivers/hid/hid-roccat-kovaplus.c | 3 +++ drivers/hid/hid-roccat-lua.c | 3 +++ drivers/hid/hid-roccat-pyra.c | 3 +++ drivers/hid/hid-roccat-ryos.c | 3 +++ drivers/hid/hid-roccat-savu.c | 3 +++ drivers/hid/hid-samsung.c | 3 +++ drivers/hid/hid-uclogic.c | 3 +++ 19 files changed, 83 insertions(+), 9 deletions(-) diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index f04ed9aabc3f..f11948ddf642 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -61,8 +61,12 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - + struct usb_interface *intf; + + if (!hid_is_usb(hdev)) + return rdesc; + + intf = to_usb_interface(hdev->dev.parent); if (intf->cur_altsetting->desc.bInterfaceNumber == 1) { /* Change usage maximum and logical maximum from 0x7fff to * 0x2fff, so they don't exceed HID_MAX_USAGES */ diff --git a/drivers/hid/hid-corsair.c b/drivers/hid/hid-corsair.c index 9ba5d98a1180..d8cf08b6b31c 100644 --- a/drivers/hid/hid-corsair.c +++ b/drivers/hid/hid-corsair.c @@ -553,7 +553,12 @@ static int corsair_probe(struct hid_device *dev, const struct hid_device_id *id) int ret; unsigned long quirks = id->driver_data; struct corsair_drvdata *drvdata; - struct usb_interface *usbif = to_usb_interface(dev->dev.parent); + struct usb_interface *usbif; + + if (!hid_is_usb(dev)) + return -EINVAL; + + usbif = to_usb_interface(dev->dev.parent); drvdata = devm_kzalloc(&dev->dev, sizeof(struct corsair_drvdata), GFP_KERNEL); diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c index 5eea6fe0d7bd..c3ecac13e620 100644 --- a/drivers/hid/hid-elo.c +++ b/drivers/hid/hid-elo.c @@ -230,6 +230,9 @@ static int elo_probe(struct hid_device *hdev, const struct hid_device_id *id) struct elo_priv *priv; int ret; + if (!hid_is_usb(hdev)) + return -EINVAL; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/hid/hid-holtek-kbd.c b/drivers/hid/hid-holtek-kbd.c index ab9da597106f..2f8eb6639744 100644 --- a/drivers/hid/hid-holtek-kbd.c +++ b/drivers/hid/hid-holtek-kbd.c @@ -143,12 +143,17 @@ static int holtek_kbd_input_event(struct input_dev *dev, unsigned int type, static int holtek_kbd_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - int ret = hid_parse(hdev); + struct usb_interface *intf; + int ret; + + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (!ret) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + intf = to_usb_interface(hdev->dev.parent); if (!ret && intf->cur_altsetting->desc.bInterfaceNumber == 1) { struct hid_input *hidinput; list_for_each_entry(hidinput, &hdev->inputs, list) { diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c index 78b3a0c76775..27c08ddab0e1 100644 --- a/drivers/hid/hid-holtek-mouse.c +++ b/drivers/hid/hid-holtek-mouse.c @@ -65,6 +65,14 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, return rdesc; } +static int holtek_mouse_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + if (!hid_is_usb(hdev)) + return -EINVAL; + return 0; +} + static const struct hid_device_id holtek_mouse_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A067) }, @@ -86,6 +94,7 @@ static struct hid_driver holtek_mouse_driver = { .name = "holtek_mouse", .id_table = holtek_mouse_devices, .report_fixup = holtek_mouse_report_fixup, + .probe = holtek_mouse_probe, }; module_hid_driver(holtek_mouse_driver); diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index 7e55d3f755dd..f8d1d481c838 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -714,12 +714,18 @@ static int lg_raw_event(struct hid_device *hdev, struct hid_report *report, static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) { - struct usb_interface *iface = to_usb_interface(hdev->dev.parent); - __u8 iface_num = iface->cur_altsetting->desc.bInterfaceNumber; + struct usb_interface *iface; + __u8 iface_num; unsigned int connect_mask = HID_CONNECT_DEFAULT; struct lg_drv_data *drv_data; int ret; + if (!hid_is_usb(hdev)) + return -EINVAL; + + iface = to_usb_interface(hdev->dev.parent); + iface_num = iface->cur_altsetting->desc.bInterfaceNumber; + /* G29 only work with the 1st interface */ if ((hdev->product == USB_DEVICE_ID_LOGITECH_G29_WHEEL) && (iface_num != 0)) { diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 762f33817dd0..7c3e42efbc56 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -803,12 +803,18 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; - struct usb_interface *intf = to_usb_interface(hdev->dev.parent); - unsigned short ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + struct usb_interface *intf; + unsigned short ifnum; unsigned long quirks = id->driver_data; struct pk_device *pk; struct pcmidi_snd *pm = NULL; + if (!hid_is_usb(hdev)) + return -EINVAL; + + intf = to_usb_interface(hdev->dev.parent); + ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + pk = kzalloc(sizeof(*pk), GFP_KERNEL); if (pk == NULL) { hid_err(hdev, "can't alloc descriptor\n"); diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index 329c5d1270f9..fb545a11214f 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -347,6 +347,9 @@ static int arvo_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 02db537f8f3e..c07a7ea8a687 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c @@ -327,6 +327,9 @@ static int isku_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index bf4675a27396..e102e06ad14c 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -743,6 +743,9 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 09e8fc72aa1d..b63de4c5b5dd 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c @@ -434,6 +434,9 @@ static int koneplus_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c index 07de2f9014c6..ef9508822e5f 100644 --- a/drivers/hid/hid-roccat-konepure.c +++ b/drivers/hid/hid-roccat-konepure.c @@ -136,6 +136,9 @@ static int konepure_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 317c9c2c0a7c..6256c211398a 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c @@ -504,6 +504,9 @@ static int kovaplus_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-lua.c b/drivers/hid/hid-roccat-lua.c index ac1a7313e259..13ae2a7d176d 100644 --- a/drivers/hid/hid-roccat-lua.c +++ b/drivers/hid/hid-roccat-lua.c @@ -163,6 +163,9 @@ static int lua_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index b30aa7b82bf8..027aa9d0ec1f 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -452,6 +452,9 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c index 47cc8f30ff6d..fda4a396a12e 100644 --- a/drivers/hid/hid-roccat-ryos.c +++ b/drivers/hid/hid-roccat-ryos.c @@ -144,6 +144,9 @@ static int ryos_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index 6dbf6e04dce7..0230fb54f08a 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c @@ -116,6 +116,9 @@ static int savu_probe(struct hid_device *hdev, { int retval; + if (!hid_is_usb(hdev)) + return -EINVAL; + retval = hid_parse(hdev); if (retval) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 7cbb067d4a9e..89bb2260367f 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -157,6 +157,9 @@ static int samsung_probe(struct hid_device *hdev, int ret; unsigned int cmask = HID_CONNECT_DEFAULT; + if (!hid_is_usb(hdev)) + return -EINVAL; + ret = hid_parse(hdev); if (ret) { hid_err(hdev, "parse failed\n"); diff --git a/drivers/hid/hid-uclogic.c b/drivers/hid/hid-uclogic.c index 1509d7287ff3..b3f2e40b1c5b 100644 --- a/drivers/hid/hid-uclogic.c +++ b/drivers/hid/hid-uclogic.c @@ -791,6 +791,9 @@ static int uclogic_tablet_enable(struct hid_device *hdev) __u8 *p; s32 v; + if (!hid_is_usb(hdev)) + return -EINVAL; + /* * Read string descriptor containing tablet parameters. The specific * string descriptor and data were discovered by sniffing the Windows -- GitLab From 7662f152fbed50561aaf4b766bfcd4342c4df2ea Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 20 Dec 2021 10:51:20 +0100 Subject: [PATCH 94/96] HID: holtek: fix mouse probing commit 93a2207c254ca102ebbdae47b00f19bbfbfa7ecd upstream. An overlook from the previous commit: we don't even parse or start the device, meaning that the device is not presented to user space. Fixes: 93020953d0fa ("HID: check for valid USB device for many HID drivers") Cc: stable@vger.kernel.org Link: https://bugs.archlinux.org/task/73048 Link: https://bugzilla.kernel.org/show_bug.cgi?id=215341 Link: https://lore.kernel.org/r/e4efbf13-bd8d-0370-629b-6c80c0044b15@leemhuis.info/ Signed-off-by: Benjamin Tissoires Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 9c84904dd7bee1533be80aaed1f1f2826e649b4f) Change-Id: Ibe4620b7fd9174c9a24b64d3fa25ee005eb596e7 Issue: FP3SEC-378 --- drivers/hid/hid-holtek-mouse.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/hid/hid-holtek-mouse.c b/drivers/hid/hid-holtek-mouse.c index 27c08ddab0e1..96db7e96fcea 100644 --- a/drivers/hid/hid-holtek-mouse.c +++ b/drivers/hid/hid-holtek-mouse.c @@ -68,8 +68,23 @@ static __u8 *holtek_mouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, static int holtek_mouse_probe(struct hid_device *hdev, const struct hid_device_id *id) { + int ret; + if (!hid_is_usb(hdev)) return -EINVAL; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "hid parse failed: %d\n", ret); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "hw start failed: %d\n", ret); + return ret; + } + return 0; } -- GitLab From 586ca749b2d7625136063bc562ebc4e4c38e14e2 Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 3 Feb 2022 12:28:52 +0100 Subject: [PATCH 95/96] power: fg-alg: return -1 instead of -EINVAL on error Align our code to the return value found in other versions of the patch "power: qpnp-qg: Add TTF_VALID param for valid TTF/TTE reporting". This stops the time_to_full_now attribute from returning -22 (-EINVAL) when the battery is fully charged which VTS is not happy about. Issue: FP3-A12#4 Issue: FP3-A11#355 Test: run vts -m VtsHalHealthV2_1TargetTest -t PerInstance/HealthHidlTest#getHealthInfo_2_1/0_default Change-Id: Ib36d74a4cbed0c125217bd15c07de5eff2c42659 (cherry picked from commit 4f6dc7409ee10da81aa3c91aa0fffb8f9522e3c8) --- drivers/power/supply/qcom/fg-alg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/power/supply/qcom/fg-alg.c b/drivers/power/supply/qcom/fg-alg.c index 09c3fc47f013..12652e6e8225 100644 --- a/drivers/power/supply/qcom/fg-alg.c +++ b/drivers/power/supply/qcom/fg-alg.c @@ -813,7 +813,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) } if (!valid) { - *val = -EINVAL; + *val = -1; return 0; } @@ -824,7 +824,7 @@ static int get_time_to_full_locked(struct ttf *ttf, int *val) } if (charge_status != POWER_SUPPLY_STATUS_CHARGING) { - *val = -EINVAL; + *val = -1; return 0; } @@ -1145,7 +1145,7 @@ int ttf_get_time_to_empty(struct ttf *ttf, int *val) } if (!valid) { - *val = -EINVAL; + *val = -1; return 0; } @@ -1156,7 +1156,7 @@ int ttf_get_time_to_empty(struct ttf *ttf, int *val) } if (charge_status == POWER_SUPPLY_STATUS_CHARGING) { - *val = -EINVAL; + *val = -1; return 0; } -- GitLab From 4573107259686856a550f34f13e717dca0c799c9 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 24 Jan 2022 14:41:50 +0100 Subject: [PATCH 96/96] gup: document and work around "COW can break either way" issue commit 9bbd42e79720122334226afad9ddcac1c3e6d373 upstream. Doing a "get_user_pages()" on a copy-on-write page for reading can be ambiguous: the page can be COW'ed at any time afterwards, and the direction of a COW event isn't defined. Yes, whoever writes to it will generally do the COW, but if the thread that did the get_user_pages() unmapped the page before the write (and that could happen due to memory pressure in addition to any outright action), the writer could also just take over the old page instead. End result: the get_user_pages() call might result in a page pointer that is no longer associated with the original VM, and is associated with - and controlled by - another VM having taken it over instead. So when doing a get_user_pages() on a COW mapping, the only really safe thing to do would be to break the COW when getting the page, even when only getting it for reading. At the same time, some users simply don't even care. For example, the perf code wants to look up the page not because it cares about the page, but because the code simply wants to look up the physical address of the access for informational purposes, and doesn't really care about races when a page might be unmapped and remapped elsewhere. This adds logic to force a COW event by setting FOLL_WRITE on any copy-on-write mapping when FOLL_GET (or FOLL_PIN) is used to get a page pointer as a result. The current semantics end up being: - __get_user_pages_fast(): no change. If you don't ask for a write, you won't break COW. You'd better know what you're doing. - get_user_pages_fast(): the fast-case "look it up in the page tables without anything getting mmap_sem" now refuses to follow a read-only page, since it might need COW breaking. Which happens in the slow path - the fast path doesn't know if the memory might be COW or not. - get_user_pages() (including the slow-path fallback for gup_fast()): for a COW mapping, turn on FOLL_WRITE for FOLL_GET/FOLL_PIN, with very similar semantics to FOLL_FORCE. If it turns out that we want finer granularity (ie "only break COW when it might actually matter" - things like the zero page are special and don't need to be broken) we might need to push these semantics deeper into the lookup fault path. So if people care enough, it's possible that we might end up adding a new internal FOLL_BREAK_COW flag to go with the internal FOLL_COW flag we already have for tracking "I had a COW". Alternatively, if it turns out that different callers might want to explicitly control the forced COW break behavior, we might even want to make such a flag visible to the users of get_user_pages() instead of using the above default semantics. But for now, this is mostly commentary on the issue (this commit message being a lot bigger than the patch, and that patch in turn is almost all comments), with that minimal "enable COW breaking early" logic using the existing FOLL_WRITE behavior. [ It might be worth noting that we've always had this ambiguity, and it could arguably be seen as a user-space issue. You only get private COW mappings that could break either way in situations where user space is doing cooperative things (ie fork() before an execve() etc), but it _is_ surprising and very subtle, and fork() is supposed to give you independent address spaces. So let's treat this as a kernel issue and make the semantics of get_user_pages() easier to understand. Note that obviously a true shared mapping will still get a page that can change under us, so this does _not_ mean that get_user_pages() somehow returns any "stable" page ] [surenb: backport notes Replaced (gup_flags | FOLL_WRITE) with write=1 in gup_pgd_range. Removed FOLL_PIN usage in should_force_cow_break since it's missing in the earlier kernels.] Reported-by: Jann Horn Tested-by: Christoph Hellwig Acked-by: Oleg Nesterov Acked-by: Kirill Shutemov Acked-by: Jan Kara Cc: Andrea Arcangeli Cc: Matthew Wilcox Signed-off-by: Linus Torvalds [surenb: backport to 4.19 kernel] Cc: stable@vger.kernel.org # 4.19.x Signed-off-by: Suren Baghdasaryan Signed-off-by: Greg Kroah-Hartman [bwh: Backported to 4.9: - Generic get_user_pages_fast() calls __get_user_pages_fast() here, so make it pass write=1 - Various architectures have their own implementations of get_user_pages_fast(), so apply the corresponding change there - Adjust context] Signed-off-by: Ben Hutchings Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 04176d2e4fbabed4e374b432aed5fd2abe756092) Issue: FP3SEC-417 Change-Id: I5cf2e56d566633c1ff97dbbdd47f2fb9140bcca1 --- arch/mips/mm/gup.c | 9 ++++++++- arch/s390/mm/gup.c | 9 ++++++++- arch/sh/mm/gup.c | 9 ++++++++- arch/sparc/mm/gup.c | 9 ++++++++- arch/x86/mm/gup.c | 9 ++++++++- mm/gup.c | 44 ++++++++++++++++++++++++++++++++++++++------ mm/huge_memory.c | 7 +++---- 7 files changed, 81 insertions(+), 15 deletions(-) diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c index d8c3c159289a..71a19d20bbb7 100644 --- a/arch/mips/mm/gup.c +++ b/arch/mips/mm/gup.c @@ -271,7 +271,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, next = pgd_addr_end(addr, end); if (pgd_none(pgd)) goto slow; - if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + if (!gup_pud_range(pgd, addr, next, 1, pages, &nr)) goto slow; } while (pgdp++, addr = next, addr != end); local_irq_enable(); diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index cf045f56581e..be1e2ed6405d 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c @@ -261,7 +261,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, might_sleep(); start &= PAGE_MASK; - nr = __get_user_pages_fast(start, nr_pages, write, pages); + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + nr = __get_user_pages_fast(start, nr_pages, 1, pages); if (nr == nr_pages) return nr; diff --git a/arch/sh/mm/gup.c b/arch/sh/mm/gup.c index 063c298ba56c..7fec66e34af0 100644 --- a/arch/sh/mm/gup.c +++ b/arch/sh/mm/gup.c @@ -239,7 +239,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, next = pgd_addr_end(addr, end); if (pgd_none(pgd)) goto slow; - if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + if (!gup_pud_range(pgd, addr, next, 1, pages, &nr)) goto slow; } while (pgdp++, addr = next, addr != end); local_irq_enable(); diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index cd0e32bbcb1d..685679f87988 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c @@ -218,7 +218,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, next = pgd_addr_end(addr, end); if (pgd_none(pgd)) goto slow; - if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + if (!gup_pud_range(pgd, addr, next, 1, pages, &nr)) goto slow; } while (pgdp++, addr = next, addr != end); diff --git a/arch/x86/mm/gup.c b/arch/x86/mm/gup.c index 82f727fbbbd2..549f89fb3abc 100644 --- a/arch/x86/mm/gup.c +++ b/arch/x86/mm/gup.c @@ -454,7 +454,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, next = pgd_addr_end(addr, end); if (pgd_none(pgd)) goto slow; - if (!gup_pud_range(pgd, addr, next, write, pages, &nr)) + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + if (!gup_pud_range(pgd, addr, next, 1, pages, &nr)) goto slow; } while (pgdp++, addr = next, addr != end); local_irq_enable(); diff --git a/mm/gup.c b/mm/gup.c index 6bb7a8eb7f82..0b80bf3878dc 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -61,13 +61,22 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address, } /* - * FOLL_FORCE can write to even unwritable pte's, but only - * after we've gone through a COW cycle and they are dirty. + * FOLL_FORCE or a forced COW break can write even to unwritable pte's, + * but only after we've gone through a COW cycle and they are dirty. */ static inline bool can_follow_write_pte(pte_t pte, unsigned int flags) { - return pte_write(pte) || - ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte)); + return pte_write(pte) || ((flags & FOLL_COW) && pte_dirty(pte)); +} + +/* + * A (separate) COW fault might break the page the other way and + * get_user_pages() would return the page from what is now the wrong + * VM. So we need to force a COW break at GUP time even for reads. + */ +static inline bool should_force_cow_break(struct vm_area_struct *vma, unsigned int flags) +{ + return is_cow_mapping(vma->vm_flags) && (flags & FOLL_GET); } static struct page *follow_page_pte(struct vm_area_struct *vma, @@ -577,12 +586,18 @@ static long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm, if (!vma || check_vma_flags(vma, gup_flags)) return i ? : -EFAULT; if (is_vm_hugetlb_page(vma)) { + if (should_force_cow_break(vma, foll_flags)) + foll_flags |= FOLL_WRITE; i = follow_hugetlb_page(mm, vma, pages, vmas, &start, &nr_pages, i, - gup_flags); + foll_flags); continue; } } + + if (should_force_cow_break(vma, foll_flags)) + foll_flags |= FOLL_WRITE; + retry: /* * If we have a pending SIGKILL, don't keep faulting pages and @@ -1503,6 +1518,10 @@ static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end, /* * Like get_user_pages_fast() except it's IRQ-safe in that it won't fall back to * the regular GUP. It will only return non-negative values. + * + * Careful, careful! COW breaking can go either way, so a non-write + * access can get ambiguous page results. If you call this function without + * 'write' set, you'd better be sure that you're ok with that ambiguity. */ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages) @@ -1532,6 +1551,12 @@ int __get_user_pages_fast(unsigned long start, int nr_pages, int write, * * We do not adopt an rcu_read_lock(.) here as we also want to * block IPIs that come from THPs splitting. + * + * NOTE! We allow read-only gup_fast() here, but you'd better be + * careful about possible COW pages. You'll get _a_ COW page, but + * not necessarily the one you intended to get depending on what + * COW event happens after this. COW may break the page copy in a + * random direction. */ local_irq_save(flags); @@ -1580,7 +1605,14 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, int nr, ret; start &= PAGE_MASK; - nr = __get_user_pages_fast(start, nr_pages, write, pages); + /* + * The FAST_GUP case requires FOLL_WRITE even for pure reads, + * because get_user_pages() may need to cause an early COW in + * order to avoid confusing the normal COW routines. So only + * targets that are already writable are safe to do by just + * looking at the page tables. + */ + nr = __get_user_pages_fast(start, nr_pages, 1, pages); ret = nr; if (nr < nr_pages) { diff --git a/mm/huge_memory.c b/mm/huge_memory.c index 1c84c5cf75ff..0fd4bc8aea67 100644 --- a/mm/huge_memory.c +++ b/mm/huge_memory.c @@ -1137,13 +1137,12 @@ int do_huge_pmd_wp_page(struct fault_env *fe, pmd_t orig_pmd) } /* - * FOLL_FORCE can write to even unwritable pmd's, but only - * after we've gone through a COW cycle and they are dirty. + * FOLL_FORCE or a forced COW break can write even to unwritable pmd's, + * but only after we've gone through a COW cycle and they are dirty. */ static inline bool can_follow_write_pmd(pmd_t pmd, unsigned int flags) { - return pmd_write(pmd) || - ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pmd_dirty(pmd)); + return pmd_write(pmd) || ((flags & FOLL_COW) && pmd_dirty(pmd)); } struct page *follow_trans_huge_pmd(struct vm_area_struct *vma, -- GitLab