aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-12-06 17:07:15 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-12-06 17:07:15 +0100
commit68ee93f3d058ff58f994d08be00d3aad9ec20970 (patch)
tree5fb2d14340332062e416246c5759adcaa64a2340 /drivers
parent17021fd920fb5bc97a8c81a20b208c5b38f1b0e8 (diff)
parentb99374450c03bf5081b88995d91d34fb9b2fd040 (diff)
downloadkernel_samsung_smdk4412-68ee93f3d058ff58f994d08be00d3aad9ec20970.zip
kernel_samsung_smdk4412-68ee93f3d058ff58f994d08be00d3aad9ec20970.tar.gz
kernel_samsung_smdk4412-68ee93f3d058ff58f994d08be00d3aad9ec20970.tar.bz2
Merge branch 'master' of fossencdi.org:kernel_samsung_smdk4412
Diffstat (limited to 'drivers')
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/base/sync.c321
-rw-r--r--drivers/battery/Kconfig9
-rw-r--r--drivers/battery/Makefile1
-rw-r--r--drivers/battery/battery-factory.c36
-rwxr-xr-xdrivers/battery/max17047_fuelgauge_c.c2217
-rw-r--r--drivers/battery/max77693_charger.c25
-rw-r--r--drivers/battery/samsung_battery.c41
-rw-r--r--drivers/cpufreq/cpufreq_ondemand.c34
-rw-r--r--drivers/cpufreq/cpufreq_pegasusq.c28
-rw-r--r--drivers/cpufreq/powernow-k8.c56
-rw-r--r--drivers/gpu/Makefile6
-rw-r--r--drivers/gpu/drm/Makefile1
-rw-r--r--drivers/gpu/ion/exynos/exynos_ion.c6
-rw-r--r--drivers/gpu/mali400/Kconfig26
-rw-r--r--drivers/gpu/mali400/r3p2/mali/Kbuild220
-rw-r--r--drivers/gpu/mali400/r3p2/mali/Kconfig67
-rw-r--r--drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION24
-rw-r--r--drivers/gpu/mali400/r3p2/mali/Makefile138
-rw-r--r--drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c1
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c392
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.h18
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c129
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h52
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c217
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h46
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp.c364
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp.h96
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c116
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h152
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c571
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h47
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_group.c2046
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_group.h283
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c47
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h104
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h186
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c1293
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h51
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c184
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h101
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c351
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.h37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c375
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h152
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c420
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h68
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c51
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c463
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h75
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c101
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h19
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_memory.c1295
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_memory.h86
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c452
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h130
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c485
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h100
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk.h1811
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.h166
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h183
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h269
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h141
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm.c144
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm.h28
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c240
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h73
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c405
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h113
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp.c521
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp.h127
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c169
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h308
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c1890
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h80
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h47
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_session.c47
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_session.h72
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h626
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c95
-rw-r--r--drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h40
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h390
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h264
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h90
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h172
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h202
-rw-r--r--drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h1165
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.h31
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c35
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c480
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h40
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c730
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c1709
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h30
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h126
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c55
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c139
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c303
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c723
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c140
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c22
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c61
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c64
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c191
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c110
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c287
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h37
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c51
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c77
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c73
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c124
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c75
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h17
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h17
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c300
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h36
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c273
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h102
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c183
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h17
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c174
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c88
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c303
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c95
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c183
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c41
-rw-r--r--drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h74
-rw-r--r--drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c405
-rw-r--r--drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c1375
-rw-r--r--drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h121
-rw-r--r--drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h128
-rw-r--r--drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h173
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c13
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.h48
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c13
-rw-r--r--drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.h26
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Kbuild78
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Kconfig7
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Makefile67
-rw-r--r--drivers/gpu/mali400/r3p2/ump/Makefile.common20
-rw-r--r--drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h22
l---------drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m4001
-rw-r--r--drivers/gpu/mali400/r3p2/ump/arch/config.h22
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c548
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c418
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h128
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c166
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.h91
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h53
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c259
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h53
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_osk.h52
-rw-r--r--drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h61
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h236
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h35
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h48
-rw-r--r--drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h204
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h31
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h59
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c500
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h18
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c288
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.h23
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c265
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.h23
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c78
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c27
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c507
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c37
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c331
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.h44
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c306
-rw-r--r--drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h47
-rw-r--r--drivers/input/keyboard/Kconfig5
-rw-r--r--drivers/input/keyboard/cypress/cypress-touchkey.c546
-rw-r--r--drivers/input/keyboard/cypress/cypress-touchkey.h23
-rw-r--r--drivers/input/keyboard/gpio_keys.c126
-rw-r--r--drivers/input/touchscreen/Kconfig26
-rw-r--r--drivers/input/touchscreen/mms152_ts.c34
-rw-r--r--drivers/input/touchscreen/mms_ts.c9
-rw-r--r--drivers/input/touchscreen/mxt224_u1.c6
-rw-r--r--drivers/input/touchscreen/synaptics_fw.h8851
-rw-r--r--drivers/input/touchscreen/synaptics_fw_updater.c91
-rw-r--r--drivers/input/touchscreen/synaptics_s7301.c482
-rw-r--r--drivers/input/touchscreen/synaptics_sysfs.c463
-rw-r--r--drivers/input/touchscreen/synaptics_sysfs.h1
-rw-r--r--drivers/input/touchscreen/wacom/w9002_flash.c1253
-rw-r--r--drivers/input/touchscreen/wacom/w9002_flash.h211
-rw-r--r--drivers/input/touchscreen/wacom/wacom_i2c.c54
-rw-r--r--drivers/input/touchscreen/wacom/wacom_i2c_firm.c7
-rw-r--r--drivers/input/touchscreen/wacom/wacom_i2c_flash.c28
-rw-r--r--drivers/input/touchscreen/wacom/wacom_i2c_func.c52
-rw-r--r--drivers/md/dm-crypt.c62
-rw-r--r--drivers/md/dm-log.c20
-rw-r--r--drivers/md/dm-mpath.c152
-rw-r--r--drivers/md/dm-snap-persistent.c71
-rw-r--r--drivers/md/dm-table.c60
-rw-r--r--drivers/md/dm.c61
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/media/video/Kconfig9
-rw-r--r--drivers/media/video/Makefile1
-rw-r--r--drivers/media/video/exynos/fimc-lite/fimc-lite-core.c2
-rw-r--r--drivers/media/video/exynos/fimc-lite/fimc-lite-core.h2
-rw-r--r--drivers/media/video/isx012.c352
-rw-r--r--drivers/media/video/isx012.h39
-rw-r--r--drivers/media/video/isx012_regs.h14
-rw-r--r--drivers/media/video/isx012_regs_kona.h11284
-rw-r--r--drivers/media/video/samsung/Kconfig4
-rw-r--r--drivers/media/video/samsung/fimc/fimc.h1
-rw-r--r--drivers/media/video/samsung/fimc/fimc_capture.c64
-rw-r--r--drivers/media/video/samsung/fimc/fimc_dev.c54
-rw-r--r--drivers/media/video/samsung/fimc/fimc_dev_u1.c54
-rw-r--r--drivers/media/video/samsung/mali/Kconfig2
-rw-r--r--drivers/media/video/samsung/mali/Kconfig_module10
-rw-r--r--drivers/media/video/samsung/mali/arch-orion-m400/config.h2
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c10
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c59
-rw-r--r--drivers/media/video/samsung/ump/Kconfig2
-rw-r--r--drivers/media/video/sr130pc20.c1994
-rwxr-xr-xdrivers/media/video/sr130pc20.h655
-rw-r--r--drivers/media/video/sr130pc20_regs.h4229
-rw-r--r--drivers/media/video/sr130pc20_regs_kona.h4229
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/max77693-muic.c8
-rw-r--r--drivers/misc/tzic.c8
-rw-r--r--drivers/mmc/card/block.c1
-rw-r--r--drivers/motor/isa1200_vibrator.c40
-rw-r--r--drivers/motor/max77693_haptic.c65
-rw-r--r--drivers/motor/max8997_vibrator.c40
-rw-r--r--drivers/net/wireless/bcmdhd/Makefile2
-rwxr-xr-xdrivers/net/wireless/bcmdhd/bcmsdspi_linux.c2
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c2
-rwxr-xr-xdrivers/net/wireless/bcmdhd/dhd_custom_sec.c140
-rwxr-xr-xdrivers/net/wireless/bcmdhd/dhd_sec_feature.h3
-rw-r--r--drivers/net/wireless/bcmdhd/include/bcmutils.h3
-rw-r--r--drivers/net/wireless/bcmdhd/wl_iw.c2
-rw-r--r--drivers/power/sec_battery_px.c2
-rw-r--r--drivers/sensor/Kconfig54
-rw-r--r--drivers/sensor/Makefile6
-rw-r--r--drivers/sensor/al3201.c51
-rw-r--r--drivers/sensor/gp2a_proximity.c763
-rw-r--r--drivers/sensor/k3dh_kona.c1080
-rw-r--r--drivers/sensor/k3dh_reg.h1
-rw-r--r--drivers/sensor/yas_mag_driver-yas532.c2909
-rw-r--r--drivers/sensor/yas_mag_driver.c27
-rw-r--r--drivers/sensor/yas_mag_kernel_driver.c2192
-rw-r--r--drivers/sensor/yas_ori_kernel_driver.c695
-rw-r--r--drivers/sensor/yas_pcb_test.c1282
-rw-r--r--drivers/sensor/yas_pcb_test.h106
-rw-r--r--drivers/sensor/yas_types.h48
-rw-r--r--drivers/sensorhub/ssp_sysfs.c41
-rw-r--r--drivers/staging/android/binder.c2
-rw-r--r--drivers/tty/n_tty.c2
-rw-r--r--drivers/tty/serial/samsung.c10
-rw-r--r--drivers/usb/host/shost/shost_readyq.c2
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/backlight/Kconfig7
-rw-r--r--drivers/video/backlight/Makefile1
-rw-r--r--drivers/video/backlight/lp855x_bl.c466
-rw-r--r--drivers/video/fbmem.c12
-rw-r--r--drivers/video/samsung/Kconfig6
-rw-r--r--drivers/video/samsung/Makefile5
-rw-r--r--drivers/video/samsung/mdnie_color_tone_4412.h239
-rw-r--r--drivers/video/samsung/mdnie_kona.c1171
-rw-r--r--drivers/video/samsung/mdnie_kona.h148
-rw-r--r--drivers/video/samsung/mdnie_table_4412_kona.h319
-rw-r--r--drivers/video/samsung/mdnie_table_ebook.h153
-rw-r--r--drivers/video/samsung/mdnie_table_kona.h1304
-rw-r--r--drivers/video/samsung/mdnie_table_t0.h16
-rw-r--r--drivers/video/samsung/mdnie_tuning_kona.c294
-rw-r--r--drivers/video/samsung/s3cfb_ielcd_kona.c136
-rw-r--r--drivers/video/samsung/s3cfb_ielcd_kona.h28
-rw-r--r--drivers/video/samsung/s3cfb_main.c21
-rw-r--r--drivers/video/samsung/s3cfb_mdnie_kona.c120
-rw-r--r--drivers/video/samsung/s3cfb_mdnie_kona.h88
-rw-r--r--drivers/video/samsung/s3cfb_nt71391.c415
-rw-r--r--drivers/video/samsung/s3cfb_ops.c13
-rw-r--r--drivers/video/samsung_extdisp/s3cfb_extdsp.h2
-rw-r--r--drivers/video/samsung_extdisp/s3cfb_extdsp_main.c2
281 files changed, 88252 insertions, 1510 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig
index eb24286..b16fa42 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -1,5 +1,7 @@
menu "Device Drivers"
+source "drivers/gpu/mali400/Kconfig"
+
source "drivers/base/Kconfig"
source "drivers/connector/Kconfig"
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
index d6913f8..06a5eac 100644
--- a/drivers/base/sync.c
+++ b/drivers/base/sync.c
@@ -15,6 +15,7 @@
*/
#include <linux/debugfs.h>
+#include <linux/export.h>
#include <linux/file.h>
#include <linux/fs.h>
#include <linux/kernel.h>
@@ -27,8 +28,13 @@
#include <linux/anon_inodes.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/sync.h>
+
static void sync_fence_signal_pt(struct sync_pt *pt);
static int _sync_pt_has_signaled(struct sync_pt *pt);
+static void sync_fence_free(struct kref *kref);
+static void sync_dump(void);
static LIST_HEAD(sync_timeline_list_head);
static DEFINE_SPINLOCK(sync_timeline_list_lock);
@@ -49,6 +55,7 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
if (obj == NULL)
return NULL;
+ kref_init(&obj->kref);
obj->ops = ops;
strlcpy(obj->name, name, sizeof(obj->name));
@@ -64,9 +71,12 @@ struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
return obj;
}
+EXPORT_SYMBOL(sync_timeline_create);
-static void sync_timeline_free(struct sync_timeline *obj)
+static void sync_timeline_free(struct kref *kref)
{
+ struct sync_timeline *obj =
+ container_of(kref, struct sync_timeline, kref);
unsigned long flags;
if (obj->ops->release_obj)
@@ -81,19 +91,17 @@ static void sync_timeline_free(struct sync_timeline *obj)
void sync_timeline_destroy(struct sync_timeline *obj)
{
- unsigned long flags;
- bool needs_freeing;
-
- spin_lock_irqsave(&obj->child_list_lock, flags);
obj->destroyed = true;
- needs_freeing = list_empty(&obj->child_list_head);
- spin_unlock_irqrestore(&obj->child_list_lock, flags);
- if (needs_freeing)
- sync_timeline_free(obj);
- else
+ /*
+ * If this is not the last reference, signal any children
+ * that their parent is going away.
+ */
+
+ if (!kref_put(&obj->kref, sync_timeline_free))
sync_timeline_signal(obj);
}
+EXPORT_SYMBOL(sync_timeline_destroy);
static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt)
{
@@ -110,7 +118,6 @@ static void sync_timeline_remove_pt(struct sync_pt *pt)
{
struct sync_timeline *obj = pt->parent;
unsigned long flags;
- bool needs_freeing;
spin_lock_irqsave(&obj->active_list_lock, flags);
if (!list_empty(&pt->active_list))
@@ -118,12 +125,10 @@ static void sync_timeline_remove_pt(struct sync_pt *pt)
spin_unlock_irqrestore(&obj->active_list_lock, flags);
spin_lock_irqsave(&obj->child_list_lock, flags);
- list_del(&pt->child_list);
- needs_freeing = obj->destroyed && list_empty(&obj->child_list_head);
+ if (!list_empty(&pt->child_list)) {
+ list_del_init(&pt->child_list);
+ }
spin_unlock_irqrestore(&obj->child_list_lock, flags);
-
- if (needs_freeing)
- sync_timeline_free(obj);
}
void sync_timeline_signal(struct sync_timeline *obj)
@@ -132,26 +137,33 @@ void sync_timeline_signal(struct sync_timeline *obj)
LIST_HEAD(signaled_pts);
struct list_head *pos, *n;
+ trace_sync_timeline(obj);
+
spin_lock_irqsave(&obj->active_list_lock, flags);
list_for_each_safe(pos, n, &obj->active_list_head) {
struct sync_pt *pt =
container_of(pos, struct sync_pt, active_list);
- if (_sync_pt_has_signaled(pt))
- list_move(pos, &signaled_pts);
+ if (_sync_pt_has_signaled(pt)) {
+ list_del_init(pos);
+ list_add(&pt->signaled_list, &signaled_pts);
+ kref_get(&pt->fence->kref);
+ }
}
spin_unlock_irqrestore(&obj->active_list_lock, flags);
list_for_each_safe(pos, n, &signaled_pts) {
struct sync_pt *pt =
- container_of(pos, struct sync_pt, active_list);
+ container_of(pos, struct sync_pt, signaled_list);
list_del_init(pos);
sync_fence_signal_pt(pt);
+ kref_put(&pt->fence->kref, sync_fence_free);
}
}
+EXPORT_SYMBOL(sync_timeline_signal);
struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
{
@@ -165,10 +177,12 @@ struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
return NULL;
INIT_LIST_HEAD(&pt->active_list);
+ kref_get(&parent->kref);
sync_timeline_add_pt(parent, pt);
return pt;
}
+EXPORT_SYMBOL(sync_pt_create);
void sync_pt_free(struct sync_pt *pt)
{
@@ -177,8 +191,11 @@ void sync_pt_free(struct sync_pt *pt)
sync_timeline_remove_pt(pt);
+ kref_put(&pt->parent->kref, sync_timeline_free);
+
kfree(pt);
}
+EXPORT_SYMBOL(sync_pt_free);
/* call with pt->parent->active_list_lock held */
static int _sync_pt_has_signaled(struct sync_pt *pt)
@@ -247,6 +264,7 @@ static struct sync_fence *sync_fence_alloc(const char *name)
if (fence->file == NULL)
goto err;
+ kref_init(&fence->kref);
strlcpy(fence->name, name, sizeof(fence->name));
INIT_LIST_HEAD(&fence->pt_list_head);
@@ -282,29 +300,67 @@ struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
list_add(&pt->pt_list, &fence->pt_list_head);
sync_pt_activate(pt);
+ /*
+ * signal the fence in case pt was activated before
+ * sync_pt_activate(pt) was called
+ */
+ sync_fence_signal_pt(pt);
+
return fence;
}
+EXPORT_SYMBOL(sync_fence_create);
static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src)
{
- struct list_head *pos;
+ struct list_head *pos, *test_pos;
list_for_each(pos, &src->pt_list_head) {
struct sync_pt *orig_pt =
container_of(pos, struct sync_pt, pt_list);
- struct sync_pt *new_pt = sync_pt_dup(orig_pt);
+ struct sync_pt *new_pt;
+
+ /* Skip already signaled points */
+ if (1 == orig_pt->status)
+ continue;
+
+ list_for_each(test_pos, &src->pt_list_head) {
+ struct sync_pt *test_pt =
+ container_of(pos, struct sync_pt, pt_list);
+ if (orig_pt->parent == test_pt->parent) {
+ int diff;
+ diff = orig_pt->parent->ops->compare(orig_pt,
+ test_pt);
+ if (diff == -1) {
+ /* Skip orig_pt; another point will
+ * signal after it */
+ continue;
+ }
+ break;
+ }
+ }
+
+ new_pt = sync_pt_dup(orig_pt);
if (new_pt == NULL)
return -ENOMEM;
new_pt->fence = dst;
list_add(&new_pt->pt_list, &dst->pt_list_head);
- sync_pt_activate(new_pt);
}
return 0;
}
+static void sync_fence_detach_pts(struct sync_fence *fence)
+{
+ struct list_head *pos, *n;
+
+ list_for_each_safe(pos, n, &fence->pt_list_head) {
+ struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
+ sync_timeline_remove_pt(pt);
+ }
+}
+
static void sync_fence_free_pts(struct sync_fence *fence)
{
struct list_head *pos, *n;
@@ -331,16 +387,19 @@ err:
fput(file);
return NULL;
}
+EXPORT_SYMBOL(sync_fence_fdget);
void sync_fence_put(struct sync_fence *fence)
{
fput(fence->file);
}
+EXPORT_SYMBOL(sync_fence_put);
void sync_fence_install(struct sync_fence *fence, int fd)
{
fd_install(fd, fence->file);
}
+EXPORT_SYMBOL(sync_fence_install);
static int sync_fence_get_status(struct sync_fence *fence)
{
@@ -349,7 +408,13 @@ static int sync_fence_get_status(struct sync_fence *fence)
list_for_each(pos, &fence->pt_list_head) {
struct sync_pt *pt = container_of(pos, struct sync_pt, pt_list);
- int pt_status = pt->status;
+ int pt_status;
+
+ if (pt == NULL) {
+ printk(KERN_ERR"[sync driver] sync_fence_get_status : sync_pt is NULL\n");
+ break;
+ }
+ pt_status = pt->status;
if (pt_status < 0) {
status = pt_status;
@@ -365,6 +430,7 @@ static int sync_fence_get_status(struct sync_fence *fence)
struct sync_fence *sync_fence_merge(const char *name,
struct sync_fence *a, struct sync_fence *b)
{
+ struct list_head *pos;
struct sync_fence *fence;
int err;
@@ -380,7 +446,29 @@ struct sync_fence *sync_fence_merge(const char *name,
if (err < 0)
goto err;
- fence->status = sync_fence_get_status(fence);
+ /* Make sure there is at least one point in the fence */
+ if (list_empty(&fence->pt_list_head)) {
+ struct sync_pt *orig_pt = list_first_entry(&a->pt_list_head,
+ struct sync_pt, pt_list);
+ struct sync_pt *new_pt = sync_pt_dup(orig_pt);
+
+ new_pt->fence = fence;
+ list_add(&new_pt->pt_list, &fence->pt_list_head);
+ }
+
+ list_for_each(pos, &fence->pt_list_head) {
+ struct sync_pt *pt =
+ container_of(pos, struct sync_pt, pt_list);
+ sync_pt_activate(pt);
+ }
+
+ /*
+ * signal the fence in case one of it's pts were activated before
+ * they were activated
+ */
+ sync_fence_signal_pt(list_first_entry(&fence->pt_list_head,
+ struct sync_pt,
+ pt_list));
return fence;
err:
@@ -388,6 +476,7 @@ err:
kfree(fence);
return NULL;
}
+EXPORT_SYMBOL(sync_fence_merge);
static void sync_fence_signal_pt(struct sync_pt *pt)
{
@@ -421,33 +510,22 @@ static void sync_fence_signal_pt(struct sync_pt *pt)
container_of(pos, struct sync_fence_waiter,
waiter_list);
- waiter->callback(fence, waiter->callback_data);
list_del(pos);
- kfree(waiter);
+ waiter->callback(fence, waiter);
}
wake_up(&fence->wq);
}
}
int sync_fence_wait_async(struct sync_fence *fence,
- void (*callback)(struct sync_fence *, void *data),
- void *callback_data)
+ struct sync_fence_waiter *waiter)
{
- struct sync_fence_waiter *waiter;
unsigned long flags;
int err = 0;
- waiter = kzalloc(sizeof(struct sync_fence_waiter), GFP_KERNEL);
- if (waiter == NULL)
- return -ENOMEM;
-
- waiter->callback = callback;
- waiter->callback_data = callback_data;
-
spin_lock_irqsave(&fence->waiter_list_lock, flags);
if (fence->status) {
- kfree(waiter);
err = fence->status;
goto out;
}
@@ -458,44 +536,120 @@ out:
return err;
}
+EXPORT_SYMBOL(sync_fence_wait_async);
+
+int sync_fence_cancel_async(struct sync_fence *fence,
+ struct sync_fence_waiter *waiter)
+{
+ struct list_head *pos;
+ struct list_head *n;
+ unsigned long flags;
+ int ret = -ENOENT;
+
+ spin_lock_irqsave(&fence->waiter_list_lock, flags);
+ /*
+ * Make sure waiter is still in waiter_list because it is possible for
+ * the waiter to be removed from the list while the callback is still
+ * pending.
+ */
+ list_for_each_safe(pos, n, &fence->waiter_list_head) {
+ struct sync_fence_waiter *list_waiter =
+ container_of(pos, struct sync_fence_waiter,
+ waiter_list);
+ if (list_waiter == waiter) {
+ list_del(pos);
+ ret = 0;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL(sync_fence_cancel_async);
+
+static bool sync_fence_check(struct sync_fence *fence)
+{
+ /*
+ * Make sure that reads to fence->status are ordered with the
+ * wait queue event triggering
+ */
+ smp_rmb();
+ return fence->status != 0;
+}
int sync_fence_wait(struct sync_fence *fence, long timeout)
{
- int err;
+ int err = 0;
+ struct sync_pt *pt;
- if (timeout) {
+ trace_sync_wait(fence, 1);
+ list_for_each_entry(pt, &fence->pt_list_head, pt_list)
+ trace_sync_pt(pt);
+
+ if (timeout > 0) {
timeout = msecs_to_jiffies(timeout);
err = wait_event_interruptible_timeout(fence->wq,
- fence->status != 0,
+ sync_fence_check(fence),
timeout);
- } else {
- err = wait_event_interruptible(fence->wq, fence->status != 0);
+ } else if (timeout < 0) {
+ err = wait_event_interruptible(fence->wq,
+ sync_fence_check(fence));
}
+ trace_sync_wait(fence, 0);
if (err < 0)
return err;
- if (fence->status < 0)
+ if (fence->status < 0) {
+ pr_info("fence error %d on [%p]\n", fence->status, fence);
+ sync_dump();
return fence->status;
+ }
- if (fence->status == 0)
+ if (fence->status == 0) {
+ if (timeout > 0) {
+ pr_info("fence timeout on [%p] after %dms\n", fence,
+ jiffies_to_msecs(timeout));
+ sync_dump();
+ }
return -ETIME;
+ }
return 0;
}
+EXPORT_SYMBOL(sync_fence_wait);
+
+static void sync_fence_free(struct kref *kref)
+{
+ struct sync_fence *fence = container_of(kref, struct sync_fence, kref);
+
+ sync_fence_free_pts(fence);
+
+ kfree(fence);
+}
static int sync_fence_release(struct inode *inode, struct file *file)
{
struct sync_fence *fence = file->private_data;
unsigned long flags;
- sync_fence_free_pts(fence);
-
+ /*
+ * We need to remove all ways to access this fence before droping
+ * our ref.
+ *
+ * start with its membership in the global fence list
+ */
spin_lock_irqsave(&sync_fence_list_lock, flags);
list_del(&fence->sync_fence_list);
spin_unlock_irqrestore(&sync_fence_list_lock, flags);
- kfree(fence);
+ /*
+ * remove its pts from their parents so that sync_timeline_signal()
+ * can't reference the fence.
+ */
+ sync_fence_detach_pts(fence);
+
+ kref_put(&fence->kref, sync_fence_free);
return 0;
}
@@ -506,6 +660,12 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
poll_wait(file, &fence->wq, wait);
+ /*
+ * Make sure that reads to fence->status are ordered with the
+ * wait queue event triggering
+ */
+ smp_rmb();
+
if (fence->status == 1)
return POLLIN;
else if (fence->status < 0)
@@ -516,7 +676,7 @@ static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg)
{
- __u32 value;
+ __s32 value;
if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
return -EFAULT;
@@ -531,8 +691,13 @@ static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg)
struct sync_fence *fence2, *fence3;
struct sync_merge_data data;
- if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
- return -EFAULT;
+ if (fd < 0)
+ return fd;
+
+ if (copy_from_user(&data, (void __user *)arg, sizeof(data))) {
+ err = -EFAULT;
+ goto err_put_fd;
+ }
fence2 = sync_fence_fdget(data.fd2);
if (fence2 == NULL) {
@@ -568,7 +733,7 @@ err_put_fd:
return err;
}
-int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
+static int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
{
struct sync_pt_info *info = data;
int ret;
@@ -596,7 +761,6 @@ int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
return info->len;
}
-
static long sync_fence_ioctl_fence_info(struct sync_fence *fence,
unsigned long arg)
{
@@ -690,7 +854,17 @@ static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
}
- if (pt->parent->ops->print_pt) {
+ if (pt->parent->ops->timeline_value_str &&
+ pt->parent->ops->pt_value_str) {
+ char value[64];
+ pt->parent->ops->pt_value_str(pt, value, sizeof(value));
+ seq_printf(s, ": %s", value);
+ if (fence) {
+ pt->parent->ops->timeline_value_str(pt->parent, value,
+ sizeof(value));
+ seq_printf(s, " / %s", value);
+ }
+ } else if (pt->parent->ops->print_pt) {
seq_printf(s, ": ");
pt->parent->ops->print_pt(s, pt);
}
@@ -705,7 +879,11 @@ static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
- if (obj->ops->print_obj) {
+ if (obj->ops->timeline_value_str) {
+ char value[64];
+ obj->ops->timeline_value_str(obj, value, sizeof(value));
+ seq_printf(s, ": %s", value);
+ } else if (obj->ops->print_obj) {
seq_printf(s, ": ");
obj->ops->print_obj(s, obj);
}
@@ -726,7 +904,8 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
struct list_head *pos;
unsigned long flags;
- seq_printf(s, "%s: %s\n", fence->name, sync_status_str(fence->status));
+ seq_printf(s, "[%p] %s: %s\n", fence, fence->name,
+ sync_status_str(fence->status));
list_for_each(pos, &fence->pt_list_head) {
struct sync_pt *pt =
@@ -740,8 +919,7 @@ static void sync_print_fence(struct seq_file *s, struct sync_fence *fence)
container_of(pos, struct sync_fence_waiter,
waiter_list);
- seq_printf(s, "waiter %pF %p\n", waiter->callback,
- waiter->callback_data);
+ seq_printf(s, "waiter %pF\n", waiter->callback);
}
spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
}
@@ -795,7 +973,34 @@ static __init int sync_debugfs_init(void)
debugfs_create_file("sync", S_IRUGO, NULL, NULL, &sync_debugfs_fops);
return 0;
}
-
late_initcall(sync_debugfs_init);
+#define DUMP_CHUNK 256
+static char sync_dump_buf[64 * 1024];
+void sync_dump(void)
+{
+ struct seq_file s = {
+ .buf = sync_dump_buf,
+ .size = sizeof(sync_dump_buf) - 1,
+ };
+ int i;
+
+ sync_debugfs_show(&s, NULL);
+
+ for (i = 0; i < s.count; i += DUMP_CHUNK) {
+ if ((s.count - i) > DUMP_CHUNK) {
+ char c = s.buf[i + DUMP_CHUNK];
+ s.buf[i + DUMP_CHUNK] = 0;
+ pr_cont("%s", s.buf + i);
+ s.buf[i + DUMP_CHUNK] = c;
+ } else {
+ s.buf[s.count] = 0;
+ pr_cont("%s", s.buf + i);
+ }
+ }
+}
+#else
+static void sync_dump(void)
+{
+}
#endif
diff --git a/drivers/battery/Kconfig b/drivers/battery/Kconfig
index acfbdb3..489bca1 100644
--- a/drivers/battery/Kconfig
+++ b/drivers/battery/Kconfig
@@ -45,6 +45,15 @@ config BATTERY_MAX17047_FUELGAUGE
in handheld and portable equipment. The MAX17047 is configured
to operate with a single lithium cell
+config BATTERY_MAX17047_C_FUELGAUGE
+ tristate "Maxim MAX17047 Fuel Gauge - COULOMB_COUNTING"
+ depends on I2C
+ help
+ MAX17047 is fuel-gauge systems for lithium-ion (Li+) batteries
+ in handheld and portable equipment. The MAX17047 is configured
+ to operate with a single lithium cell
+
+
config BATTERY_SMB136_CHARGER
tristate "SMB136 battery charger support"
depends on I2C
diff --git a/drivers/battery/Makefile b/drivers/battery/Makefile
index bb1af5e..af56fec 100644
--- a/drivers/battery/Makefile
+++ b/drivers/battery/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_MAX8997_CHARGER) += max8997-charger.o
obj-$(CONFIG_BATTERY_MAX17043_FUELGAUGE) += max17043_fuelgauge.o
obj-$(CONFIG_BATTERY_MAX17042_FUELGAUGE) += max17042_fuelgauge.o
obj-$(CONFIG_BATTERY_MAX17047_FUELGAUGE) += max17047_fuelgauge.o
+obj-$(CONFIG_BATTERY_MAX17047_C_FUELGAUGE) += max17047_fuelgauge_c.o
obj-$(CONFIG_BATTERY_SMB136_CHARGER) += smb136_charger.o
obj-$(CONFIG_BATTERY_MAX77693_CHARGER) += max77693_charger.o
diff --git a/drivers/battery/battery-factory.c b/drivers/battery/battery-factory.c
index c1cd9b1..0f20fed 100644
--- a/drivers/battery/battery-factory.c
+++ b/drivers/battery/battery-factory.c
@@ -121,6 +121,9 @@ static ssize_t factory_show_property(struct device *dev,
int i;
int cnt, dat, d_max, d_min, d_total;
int val;
+#if defined(CONFIG_MACH_KONA)
+ int comp1, comp3;
+#endif
const ptrdiff_t off = attr - factory_attrs;
pr_debug("%s: %s\n", __func__, factory_attrs[off].attr.name);
@@ -149,10 +152,16 @@ static ssize_t factory_show_property(struct device *dev,
val = 0;
for (cnt = 0; cnt < CNT_TEMPER_AVG; cnt++) {
msleep(100);
+#if defined(CONFIG_MACH_KONA)
+ info->battery_temper_adc = battery_get_info(info,
+ POWER_SUPPLY_PROP_TEMP);
+#else
battery_get_info(info, POWER_SUPPLY_PROP_TEMP);
+#endif
val += info->battery_temper_adc;
info->battery_temper_adc_avg = val / (cnt + 1);
}
+#if !defined(CONFIG_MACH_KONA)
#ifdef CONFIG_S3C_ADC
info->battery_temper_avg = info->pdata->covert_adc(
info->battery_temper_adc_avg,
@@ -160,6 +169,10 @@ static ssize_t factory_show_property(struct device *dev,
#else
info->battery_temper_avg = info->battery_temper;
#endif
+#else
+ info->battery_temper_avg = info->battery_temper_adc_avg;
+#endif
+
val = info->battery_temper_avg;
pr_info("%s: temper avg(%d)\n", __func__, val);
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
@@ -185,6 +198,9 @@ static ssize_t factory_show_property(struct device *dev,
d_total += dat;
}
val = (d_total - d_max - d_min) / (CNT_VOLTAGE_AVG - 2);
+#if defined(CONFIG_MACH_KONA)
+ val /= 1000;
+#endif
pr_info("%s: voltage avg(%d)\n", __func__, val);
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
break;
@@ -242,8 +258,28 @@ static ssize_t factory_show_property(struct device *dev,
i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", val);
break;
case BATT_VOL_ADC:
+ i += scnprintf(buf + i, PAGE_SIZE - i, "N/A\n");
+ break;
case BATT_VOL_ADC_CAL:
+#if defined(CONFIG_MACH_KONA)
+ /* For using compensation 1% value */
+ comp1 = info->is_comp_1;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", comp1);
+ break;
+#else
+ i += scnprintf(buf + i, PAGE_SIZE - i, "N/A\n");
+ break;
+#endif
case BATT_VOL_ADC_AVER:
+#if defined(CONFIG_MACH_KONA)
+ /* For using compensation 3% value */
+ comp3 = info->is_comp_3;
+ i += scnprintf(buf + i, PAGE_SIZE - i, "%d\n", comp3);
+ break;
+#else
+ i += scnprintf(buf + i, PAGE_SIZE - i, "N/A\n");
+ break;
+#endif
case BATT_TEMP_ADC_CAL:
case AUTH_BATTERY:
i += scnprintf(buf + i, PAGE_SIZE - i, "N/A\n");
diff --git a/drivers/battery/max17047_fuelgauge_c.c b/drivers/battery/max17047_fuelgauge_c.c
new file mode 100755
index 0000000..4b26cb0
--- /dev/null
+++ b/drivers/battery/max17047_fuelgauge_c.c
@@ -0,0 +1,2217 @@
+/*
+ * max17047_fuelgauge.c
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * SangYoung Son <hello.son@samsung.com>
+ *
+ * based on max17040_battery.c
+ *
+ * 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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mutex.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/power_supply.h>
+#include <linux/battery/samsung_battery.h>
+#include <linux/battery/max17047_fuelgauge_c.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <plat/gpio-cfg.h>
+#include <linux/rtc.h>
+#if defined(CONFIG_TARGET_LOCALE_KOR) || defined(CONFIG_MACH_M0_CTC)\
+ || defined(CONFIG_MACH_T0_CHN_CTC)
+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#endif
+#endif
+
+/* TRIM ERROR DETECTION */
+#define USE_TRIM_ERROR_DETECTION
+
+#define CONFIG_FUELGAUGE_MAX17047_COULOMB_COUNTING
+
+/* MAX17047 Registers. */
+#define MAX17047_REG_STATUS 0x00
+#define MAX17047_REG_VALRT_TH 0x01
+#define MAX17047_REG_TALRT_TH 0x02
+#define MAX17047_REG_SALRT_TH 0x03
+#define MAX17047_REG_REMCAP_REP 0x05
+#define MAX17047_SOCREP 0x06
+#define MAX17047_REG_VCELL 0x09
+#define MAX17047_REG_FULLCAP 0x10
+#define MAX17047_REG_TEMPERATURE 0x08
+#define MAX17047_REG_CYCLES 0x17
+#define MAX17047_REG_DESIGNCAP_REG 0x18
+#define MAX17047_REG_AVGVCELL 0x19
+#define MAX17047_REG_CONFIG 0x1D
+#define MAX17047_REG_VERSION 0x21
+#define MAX17047_REG_FULLCAP_NOM 0x23
+#define MAX17047_REG_LEARNCFG 0x28
+#define MAX17047_REG_FILTERCFG 0x29
+#define MAX17047_REG_MISCCFG 0x2B
+#define MAX17047_REG_CGAIN 0x2E
+#define MAX17047_REG_RCOMP 0x38
+#define MAX17047_REG_VFOCV 0xFB
+#define MAX17047_REG_SOC_VF 0xFF
+#define MAX17047_REG_FULLCAP 0x10
+#define MAX17047_REG_FULLCAPNOM 0x23
+#define MAX17047_REG_CURRENT 0x0A
+#define MAX17047_REG_AVG_CURRENT 0x0B
+#define MAX17047_REG_DQACC 0x45
+#define MAX17047_REG_DPACC 0x46
+#define MAX17047_REG_VFSOC 0xFF
+
+
+
+
+/* Polling work */
+#undef DEBUG_FUELGAUGE_POLLING
+#define MAX17047_POLLING_INTERVAL 10000
+
+/* rcomp update */
+#if defined(CONFIG_MACH_C1_KOR_SKT) || \
+ defined(CONFIG_MACH_C1_KOR_KT) || \
+ defined(CONFIG_MACH_C1_KOR_LGT)
+#define CHECK_RCOMP_UPDATE
+#define MAX17047_NEW_RCOMP 0x0070
+#endif
+
+/* adjust full soc */
+#if defined(CONFIG_MACH_T0)
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+#define FULL_SOC_DEFAULT 9700
+#define FULL_SOC_LOW 9600
+#define FULL_SOC_HIGH 10050
+#define KEEP_FULL_SOC 100 /* 1.0% */
+#else
+#define FULL_SOC_DEFAULT 9650
+#define FULL_SOC_LOW 9500
+#define FULL_SOC_HIGH 10050
+#define KEEP_FULL_SOC 100 /* 1.0% */
+#endif
+#elif defined(CONFIG_MACH_GC1)
+#define FULL_SOC_DEFAULT 9700
+#define FULL_SOC_LOW 9650
+#define FULL_SOC_HIGH 10000
+#define KEEP_FULL_SOC 110 /* 1.1% */
+#elif defined(CONFIG_MACH_KONA)
+#define FULL_SOC_DEFAULT 9900
+#define FULL_SOC_LOW 9700
+#define FULL_SOC_HIGH 10000
+#define KEEP_FULL_SOC 100 // /* 1.0% */
+#else /* M0, C1,,, */
+#define FULL_SOC_DEFAULT 9850
+#define FULL_SOC_LOW 9700
+#define FULL_SOC_HIGH 10000
+#define KEEP_FULL_SOC 100 /* 1.0% */
+#endif
+#define KEEP_SOC_DEFAULT 50 /* 0.5% */
+
+struct max17047_fuelgauge_data {
+ struct i2c_client *client;
+ struct max17047_platform_data *pdata;
+
+ struct power_supply fuelgauge;
+
+ /* workqueue */
+ struct delayed_work update_work;
+#ifdef DEBUG_FUELGAUGE_POLLING
+ struct delayed_work polling_work;
+#endif
+
+ /* mutex */
+ struct mutex irq_lock;
+
+ /* wakelock */
+ struct wake_lock update_wake_lock;
+
+ unsigned int irq;
+
+ unsigned int vcell;
+ unsigned int avgvcell;
+ unsigned int vfocv;
+ unsigned int soc;
+ unsigned int rawsoc;
+ unsigned int temperature;
+
+/*#if defined(CONFIG_FUELGAUGE_MAX17047_COULOMB_COUNTING)*/
+ u32 previous_fullcap;
+ u32 previous_vffullcap;
+
+ /* low battery comp */
+ int low_batt_comp_cnt[LOW_BATT_COMP_RANGE_NUM][LOW_BATT_COMP_LEVEL_NUM];
+
+ /* low battery boot */
+ int low_batt_boot_flag;
+ bool is_low_batt_alarm;
+
+ /* miscellaneous */
+ unsigned long fullcap_check_interval;
+ int full_check_flag;
+ bool is_first_check;
+/*#endif*/
+
+ /* adjust full soc */
+ int full_soc;
+
+#if defined(CONFIG_MACH_GC1)
+ int prev_status;
+#endif
+
+#ifdef USE_TRIM_ERROR_DETECTION
+ /* trim error state */
+ bool trim_err;
+#endif
+
+#ifdef CONFIG_DEBUG_FS
+ struct dentry *fg_debugfs_dir;
+#endif
+
+#ifdef CONFIG_HIBERNATION
+ u8 *reg_dump;
+#endif
+
+};
+
+static struct battery_data_t fg_battery_data[] = {
+ /* SDI battery data */
+ {
+ .Capacity = 0x2530,
+ .low_battery_comp_voltage = 3500,
+ .low_battery_table = {
+ /* range, slope, offset */
+ {-5000, 0, 0}, /* dummy for top limit */
+ {-1250, 0, 3320},
+ {-750, 97, 3451},
+ {-100, 96, 3461},
+ {0, 0, 3456},
+ },
+ .temp_adjust_table = {
+ /* range, slope, offset */
+ {47000, 122, 8950},
+ {60000, 200, 51000},
+ {100000, 0, 0}, /* dummy for top limit */
+ },
+ .type_str = "SDI",
+ }
+};
+
+
+#define MAX17047_CAPACITY 0x2530
+
+static int max17047_i2c_read(struct i2c_client *client, int reg, u8 *buf)
+{
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(client, reg, 2, buf);
+ if (ret < 0)
+ pr_err("%s: err %d, reg: 0x%02x\n", __func__, ret, reg);
+
+ return ret;
+}
+
+static int max17047_i2c_write(struct i2c_client *client, int reg, u8 *buf)
+{
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(client, reg, 2, buf);
+ if (ret < 0)
+ pr_err("%s: err %d, reg: 0x%02x, data: 0x%x%x\n", __func__,
+ ret, reg, buf[0], buf[1]);
+
+ return ret;
+}
+
+static int fg_read_register(struct i2c_client *client,
+ u8 addr)
+{
+ u8 data[2];
+
+ if (max17047_i2c_read(client, addr, data) < 0) {
+ dev_err(&client->dev, "%s: Failed to read addr(0x%x)\n",
+ __func__, addr);
+ return -1;
+ }
+
+ return (data[1] << 8) | data[0];
+}
+
+static int fg_write_register(struct i2c_client *client,
+ u8 addr, u16 w_data)
+{
+ u8 data[2];
+
+ data[0] = w_data & 0xFF;
+ data[1] = w_data >> 8;
+
+ if (max17047_i2c_write(client, addr, data) < 0) {
+ dev_err(&client->dev, "%s: Failed to write addr(0x%x)\n",
+ __func__, addr);
+ return -1;
+ }
+
+ return 0;
+}
+
+static void max17047_test_read(struct max17047_fuelgauge_data *fg_data)
+{
+ int reg;
+ u8 data[2];
+ int i;
+ u8 buf[673];
+
+ struct timespec ts;
+ struct rtc_time tm;
+ pr_info("%s\n", __func__);
+
+ getnstimeofday(&ts);
+ rtc_time_to_tm(ts.tv_sec, &tm);
+
+ pr_info("%s: %d/%d/%d %02d:%02d\n", __func__,
+ tm.tm_mday,
+ tm.tm_mon + 1,
+ tm.tm_year + 1900,
+ tm.tm_hour,
+ tm.tm_min);
+
+ i = 0;
+ for (reg = 0; reg < 0x50; reg++) {
+ if (!(reg & 0xf))
+ i += sprintf(buf + i, "\n%02x| ", reg);
+ max17047_i2c_read(fg_data->client, reg, data);
+ i += sprintf(buf + i, "%02x%02x ", data[1], data[0]);
+ }
+ for (reg = 0xe0; reg < 0x100; reg++) {
+ if (!(reg & 0xf))
+ i += sprintf(buf + i, "\n%02x| ", reg);
+ max17047_i2c_read(fg_data->client, reg, data);
+ i += sprintf(buf + i, "%02x%02x ", data[1], data[0]);
+ }
+
+ pr_info(" 0 1 2 3 4 5 6 7");
+ pr_cont(" 8 9 a b c d e f");
+ pr_cont("%s\n", buf);
+}
+
+static int fg_check_battery_present(struct i2c_client *client)
+{
+ u8 status_data[2];
+ int ret = 1;
+
+ /* 1. Check Bst bit */
+ if (max17047_i2c_read(client, MAX17047_REG_STATUS, status_data) < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to read STATUS_REG\n", __func__);
+ return 0;
+ }
+
+ if (status_data[0] & (0x1 << 3)) {
+ dev_info(&client->dev,
+ "%s: addr(0x01), data(0x%04x)\n", __func__,
+ (status_data[1]<<8) | status_data[0]);
+ dev_info(&client->dev, "%s: battery is absent!!\n", __func__);
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int max17047_get_temperature(struct i2c_client *client)
+{
+#if defined(CONFIG_MACH_KONA)
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2] = {0x00, 0x00};
+ int temper = 0;
+
+ if (fg_check_battery_present(client)) {
+ if (max17047_i2c_read(client, MAX17047_REG_TEMPERATURE, data) < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to read TEMPERATURE_REG\n",
+ __func__);
+ return -1;
+ }
+
+ if (data[1]&(0x1 << 7)) {
+ temper = ((~(data[1]))&0xFF)+1;
+ temper *= (-1000);
+ temper -= ((~((int)data[0]))+1) * 39 / 10;
+ } else {
+ temper = data[1] & 0x7f;
+ temper *= 1000;
+ temper += data[0] * 39 / 10;
+ }
+ } else
+ temper = 20000;
+
+ dev_info(&client->dev, "%s: TEMPERATURE(%d), data(0x%04x)\n",
+ __func__, temper/100, (data[1]<<8) | data[0]);
+
+ return temper/100;
+#else
+ return 300;
+#endif
+}
+
+/* max17047_get_XXX(); Return current value and update data value */
+static int max17047_get_vfocv(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2];
+ int ret;
+ u32 vfocv;
+ pr_debug("%s\n", __func__);
+
+ ret = max17047_i2c_read(client, MAX17047_REG_VFOCV, data);
+ if (ret < 0)
+ return ret;
+
+ vfocv = fg_data->vfocv = ((data[0] >> 3) + (data[1] << 5)) * 625 / 1000;
+
+ pr_debug("%s: VFOCV(0x%02x%02x, %d)\n", __func__,
+ data[1], data[0], vfocv);
+ return vfocv * 1000;
+}
+
+static int fg_read_vcell(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2];
+ u32 vcell;
+ u16 w_data;
+ u32 temp;
+ u32 temp2;
+
+ if (max17047_i2c_read(client, MAX17047_REG_VCELL, data) < 0) {
+ dev_err(&client->dev, "%s: Failed to read VCELL\n", __func__);
+ return -1;
+ }
+
+ w_data = (data[1]<<8) | data[0];
+
+ temp = (w_data & 0xFFF) * 78125;
+ vcell = temp / 1000000;
+
+ temp = ((w_data & 0xF000) >> 4) * 78125;
+ temp2 = temp / 1000000;
+ vcell += (temp2 << 4);
+
+ dev_info(&client->dev, "%s: VCELL(%d), data(0x%04x)\n",
+ __func__, vcell, (data[1]<<8) | data[0]);
+
+ return vcell;
+}
+
+
+static int max17047_get_vcell(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2];
+ int ret;
+ u32 vcell;
+ pr_debug("%s\n", __func__);
+
+ ret = max17047_i2c_read(client, MAX17047_REG_VCELL, data);
+ if (ret < 0)
+ return ret;
+
+ vcell = fg_data->vcell = ((data[0] >> 3) + (data[1] << 5)) * 625;
+
+ pr_debug("%s: VCELL(0x%02x%02x, %d)\n", __func__,
+ data[1], data[0], vcell);
+ return vcell;
+}
+
+static int max17047_get_avgvcell(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2];
+ int ret;
+ u32 avgvcell;
+ pr_debug("%s\n", __func__);
+
+ ret = max17047_i2c_read(client, MAX17047_REG_AVGVCELL, data);
+ if (ret < 0)
+ return ret;
+
+ avgvcell = fg_data->avgvcell = ((data[0] >> 3) + (data[1] << 5)) * 625;
+
+ pr_debug("%s: AVGVCELL(0x%02x%02x, %d)\n", __func__,
+ data[1], data[0], avgvcell);
+ return avgvcell;
+}
+
+static int max17047_get_rawsoc(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2];
+ int soc;
+
+ if (max17047_i2c_read(client, MAX17047_SOCREP, data) < 0) {
+ dev_err(&client->dev, "%s: Failed to read SOCREP\n", __func__);
+ return -1;
+ }
+
+ soc = (data[1] * 100) + (data[0] * 100 / 256);
+
+ dev_dbg(&client->dev, "%s: raw capacity (0.01%%) (%d)\n",
+ __func__, soc);
+
+ dev_dbg(&client->dev, "%s: raw capacity (%d), data(0x%04x)\n",
+ __func__, soc, (data[1]<<8) | data[0]);
+
+ return min(soc, 10000);
+}
+
+#if 0
+static int max17047_get_soc(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ int rawsoc, soc, fullsoc, empty;
+ pr_debug("%s\n", __func__);
+
+ rawsoc = max17047_get_rawsoc(fg_data->client);
+
+#if defined(CONFIG_MACH_C1)
+ empty = 0;
+#else /* M0, T0,,, */
+ empty = 29;
+#endif
+
+ if (fg_data->full_soc <= 0)
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+ fullsoc = fg_data->full_soc - empty;
+ rawsoc -= empty;
+
+ soc = fg_data->soc =
+ ((rawsoc < empty) ? 0 : (min((rawsoc * 100 / fullsoc), 100)));
+
+ pr_info("%s: SOC(%d, %d / %d)\n", __func__, soc, rawsoc, fullsoc);
+ return soc;
+}
+
+#else
+/* soc should be 0.1% unit */
+static int max17047_get_soc(struct i2c_client *client)
+{
+ u8 data[2];
+ int soc;
+
+ if (max17047_i2c_read(client, MAX17047_SOCREP, data) < 0) {
+ pr_err("%s: Failed to read SOCREP\n", __func__);
+ return -1;
+ }
+
+ soc = ((data[1] * 100) + (data[0] * 100 / 256)) / 10;
+
+ pr_info("%s: raw capacity (%d), data(0x%04x)\n", __func__, soc, (data[1]<<8) | data[0]);
+
+ return min(soc, 1000);
+}
+#endif
+
+static int fg_reset_capacity_by_jig_connection(struct i2c_client *client)
+{
+ pr_info("%s: DesignCap = Capacity - 1 (Jig Connection)\n", __func__);
+
+ return fg_write_register(client, MAX17047_REG_DESIGNCAP_REG,
+ fg_battery_data[SDI].Capacity - 1);
+}
+
+#if defined(CONFIG_MACH_KONA)
+/* For using JIG detach */
+struct i2c_client *fg_client;
+
+void fg_reset_capacity_by_jig_connection_ex(void)
+{
+
+ pr_info("%s: DesignCap = Capacity - 1 (Jig Connection)\n", __func__);
+ printk("[BAT] %s call!!\n", __func__);
+
+
+ fg_write_register(fg_client, MAX17047_REG_DESIGNCAP_REG,
+ fg_battery_data[SDI].Capacity - 1);
+}
+EXPORT_SYMBOL(fg_reset_capacity_by_jig_connection_ex);
+#endif
+
+static void fg_periodic_read(struct i2c_client *client)
+{
+ u8 reg;
+ int i;
+ int data[0x10];
+ char *str = NULL;
+
+ str = kzalloc(sizeof(char)*1024, GFP_KERNEL);
+ if (!str)
+ return;
+
+ for (i = 0; i < 16; i++) {
+ for (reg = 0; reg < 0x10; reg++)
+ data[reg] = fg_read_register(client, reg + i * 0x10);
+
+ sprintf(str+strlen(str),
+ "%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
+ data[0x00], data[0x01], data[0x02], data[0x03],
+ data[0x04], data[0x05], data[0x06], data[0x07]);
+ sprintf(str+strlen(str),
+ "%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,%04xh,",
+ data[0x08], data[0x09], data[0x0a], data[0x0b],
+ data[0x0c], data[0x0d], data[0x0e], data[0x0f]);
+ if (i == 4)
+ i = 13;
+ }
+
+ dev_info(&client->dev, "maxim check %s", str);
+
+ kfree(str);
+}
+
+static int fg_read_current(struct i2c_client *client)
+{
+ u8 data1[2], data2[2];
+ u32 temp, sign;
+ s32 i_current;
+ s32 avg_current;
+
+ if (max17047_i2c_read(client, MAX17047_REG_CURRENT, data1) < 0) {
+ pr_err("%s: Failed to read CURRENT\n",
+ __func__);
+ return -1;
+ }
+
+ if (max17047_i2c_read(client, MAX17047_REG_AVG_CURRENT, data2) < 0) {
+ pr_err("%s: Failed to read AVERAGE CURRENT\n",
+ __func__);
+ return -1;
+ }
+
+ temp = ((data1[1]<<8) | data1[0]) & 0xFFFF;
+ if (temp & (0x1 << 15)) {
+ sign = NEGATIVE;
+ temp = (~temp & 0xFFFF) + 1;
+ } else
+ sign = POSITIVE;
+
+ /* 1.5625uV/0.01Ohm(Rsense) = 156.25uA */
+ i_current = temp * 15625 / 100000;
+ if (sign)
+ i_current *= -1;
+
+ temp = ((data2[1]<<8) | data2[0]) & 0xFFFF;
+ if (temp & (0x1 << 15)) {
+ sign = NEGATIVE;
+ temp = (~temp & 0xFFFF) + 1;
+ } else
+ sign = POSITIVE;
+
+ /* 1.5625uV/0.01Ohm(Rsense) = 156.25uA */
+ avg_current = temp * 15625 / 100000;
+ if (sign)
+ avg_current *= -1;
+
+ pr_info("%s: CURRENT(%dmA), AVG_CURRENT(%dmA)\n",
+ __func__, i_current, avg_current);
+
+ fg_periodic_read(client);
+
+ return i_current;
+}
+
+static int fg_read_avg_current(struct i2c_client *client)
+{
+ u8 data2[2];
+ u32 temp, sign;
+ s32 avg_current;
+
+ if (max17047_i2c_read(client, MAX17047_REG_AVG_CURRENT, data2) < 0) {
+ pr_err("%s: Failed to read AVERAGE CURRENT\n",
+ __func__);
+ return -1;
+ }
+
+ temp = ((data2[1]<<8) | data2[0]) & 0xFFFF;
+ if (temp & (0x1 << 15)) {
+ sign = NEGATIVE;
+ temp = (~temp & 0xFFFF) + 1;
+ } else
+ sign = POSITIVE;
+
+ /* 1.5625uV/0.01Ohm(Rsense) = 156.25uA */
+ avg_current = temp * 15625 / 100000;
+
+ if (sign)
+ avg_current *= -1;
+
+ return avg_current;
+}
+
+/* soc should be 0.1% unit */
+static int fg_read_vfsoc(struct i2c_client *client)
+{
+ u8 data[2];
+ int soc;
+
+ if (max17047_i2c_read(client, MAX17047_REG_VFSOC, data) < 0) {
+ pr_err("%s: Failed to read VFSOC\n", __func__);
+ return -1;
+ }
+
+ soc = ((data[1] * 100) + (data[0] * 100 / 256)) / 10;
+
+ return min(soc, 1000);
+}
+
+
+int get_fuelgauge_value(struct i2c_client *client, int data)
+{
+ int ret = 0;
+
+ switch (data) {
+ case FG_LEVEL:
+ /*ret = fg_read_soc(client);*/
+ ret = max17047_get_soc(client);
+
+ break;
+
+ case FG_TEMPERATURE:
+ /*ret = fg_read_temp(client);*/
+ break;
+
+ case FG_VOLTAGE:
+ ret = fg_read_vcell(client);
+ break;
+
+ case FG_CURRENT:
+ ret = fg_read_current(client);
+ break;
+
+ case FG_CURRENT_AVG:
+ ret = fg_read_avg_current(client);
+ break;
+
+ case FG_CHECK_STATUS:
+ /*ret = fg_check_status_reg(client);*/
+ break;
+
+ case FG_RAW_SOC:
+ /*ret = fg_read_rawsoc(client);*/
+ break;
+
+ case FG_VF_SOC:
+ ret = fg_read_vfsoc(client);
+ break;
+
+ case FG_AV_SOC:
+ /*ret = fg_read_avsoc(client);*/
+ break;
+
+ case FG_FULLCAP:
+ /*ret = fg_read_fullcap(client);*/
+ break;
+
+ case FG_MIXCAP:
+ /*ret = fg_read_mixcap(client);*/
+ break;
+
+ case FG_AVCAP:
+ /*ret = fg_read_avcap(client);*/
+ break;
+
+ case FG_REPCAP:
+ /*ret = fg_read_repcap(client);*/
+ break;
+
+ default:
+ ret = -1;
+ break;
+ }
+
+ return ret;
+}
+
+
+void fg_check_vf_fullcap_range(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+
+ static int new_vffullcap;
+ bool is_vffullcap_changed = true;
+
+ if (is_jig_attached == JIG_ON)
+ fg_reset_capacity_by_jig_connection(client);
+
+ new_vffullcap = fg_read_register(client, MAX17047_REG_FULLCAP_NOM);
+ if (new_vffullcap < 0)
+ new_vffullcap = fg_battery_data[SDI].Capacity;
+
+ /* compare with initial capacity */
+ if (new_vffullcap >
+ (fg_battery_data[SDI].Capacity * 110 / 100)) {
+ pr_info("%s: [Case 1] capacity = 0x%04x, NewVfFullCap = 0x%04x\n",
+ __func__, fg_battery_data[SDI].Capacity,
+ new_vffullcap);
+
+ new_vffullcap =
+ (fg_battery_data[SDI].Capacity * 110) / 100;
+
+ fg_write_register(client, MAX17047_REG_DQACC,
+ (u16)(new_vffullcap / 4));
+ fg_write_register(client, MAX17047_REG_DPACC, (u16)0x3200);
+ } else if (new_vffullcap <
+ (fg_battery_data[SDI].Capacity * 50 / 100)) {
+ pr_info("%s: [Case 5] capacity = 0x%04x, NewVfFullCap = 0x%04x\n",
+ __func__, fg_battery_data[SDI].Capacity, new_vffullcap);
+
+ new_vffullcap =
+ (fg_battery_data[SDI].Capacity * 50) / 100;
+
+ fg_write_register(client, MAX17047_REG_DQACC,
+ (u16)(new_vffullcap / 4));
+ fg_write_register(client, MAX17047_REG_DPACC, (u16)0x3200);
+ } else {
+ /* compare with previous capacity */
+ if (new_vffullcap >
+ (fg_data->previous_vffullcap * 110 / 100)) {
+ pr_info("%s: [Case 2] previous_vffullcap = 0x%04x, NewVfFullCap = 0x%04x\n",
+ __func__, fg_data->previous_vffullcap,
+ new_vffullcap);
+
+ new_vffullcap =
+ (fg_data->previous_vffullcap * 110) /
+ 100;
+
+ fg_write_register(client, MAX17047_REG_DQACC,
+ (u16)(new_vffullcap / 4));
+ fg_write_register(client, MAX17047_REG_DPACC, (u16)0x3200);
+ } else if (new_vffullcap <
+ (fg_data->previous_vffullcap * 90 / 100)) {
+ pr_info("%s: [Case 3] previous_vffullcap = 0x%04x, NewVfFullCap = 0x%04x\n",
+ __func__, fg_data->previous_vffullcap, new_vffullcap);
+
+ new_vffullcap =
+ (fg_data->previous_vffullcap * 90) / 100;
+
+ fg_write_register(client, MAX17047_REG_DQACC,
+ (u16)(new_vffullcap / 4));
+ fg_write_register(client, MAX17047_REG_DPACC, (u16)0x3200);
+ } else {
+ pr_info("%s: [Case 4] previous_vffullcap = 0x%04x, NewVfFullCap = 0x%04x\n",
+ __func__, fg_data->previous_vffullcap,
+ new_vffullcap);
+ is_vffullcap_changed = false;
+ }
+ }
+
+ /* delay for register setting (dQacc, dPacc) */
+ if (is_vffullcap_changed)
+ msleep(300);
+
+ fg_data->previous_vffullcap =
+ fg_read_register(client, MAX17047_REG_FULLCAP_NOM);
+
+ if (is_vffullcap_changed)
+ pr_info("%s : VfFullCap(0x%04x), dQacc(0x%04x), dPacc(0x%04x)\n",
+ __func__,
+ fg_read_register(client, MAX17047_REG_FULLCAP_NOM),
+ fg_read_register(client, MAX17047_REG_DQACC),
+ fg_read_register(client, MAX17047_REG_DPACC));
+
+}
+
+void fg_set_full_charged(struct i2c_client *client)
+{
+ pr_info("[FG_Set_Full] (B) FullCAP(%d), RemCAP(%d)\n",
+ (fg_read_register(client, MAX17047_REG_FULLCAP)/2),
+ (fg_read_register(client, MAX17047_REG_REMCAP_REP)/2));
+
+ fg_write_register(client, MAX17047_REG_FULLCAP,
+ (u16)fg_read_register(client, MAX17047_REG_REMCAP_REP));
+
+ pr_info("[FG_Set_Full] (A) FullCAP(%d), RemCAP(%d)\n",
+ (fg_read_register(client, MAX17047_REG_FULLCAP)/2),
+ (fg_read_register(client, MAX17047_REG_REMCAP_REP)/2));
+}
+
+static void add_low_batt_comp_cnt(struct i2c_client *client,
+ int range, int level)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ int i;
+ int j;
+
+ /* Increase the requested count value, and reset others. */
+ fg_data->low_batt_comp_cnt[range-1][level/2]++;
+
+ for (i = 0; i < LOW_BATT_COMP_RANGE_NUM; i++) {
+ for (j = 0; j < LOW_BATT_COMP_LEVEL_NUM; j++) {
+ if (i == range-1 && j == level/2)
+ continue;
+ else
+ fg_data->low_batt_comp_cnt[i][j] = 0;
+ }
+ }
+}
+
+
+static int get_low_batt_threshold(struct i2c_client *client,
+ int range, int nCurrent, int level)
+{
+ int ret = 0;
+
+ ret = fg_battery_data[SDI].low_battery_table[range][OFFSET] +
+ ((nCurrent *
+ fg_battery_data[SDI].low_battery_table[range][SLOPE]) /
+ 1000);
+
+ return ret;
+}
+
+void reset_low_batt_comp_cnt(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+
+ memset(fg_data->low_batt_comp_cnt, 0,
+ sizeof(fg_data->low_batt_comp_cnt));
+}
+
+static void display_low_batt_comp_cnt(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+
+ pr_info("Check Array(%s): [%d, %d], [%d, %d], ",
+ fg_battery_data[SDI].type_str,
+ fg_data->low_batt_comp_cnt[0][0],
+ fg_data->low_batt_comp_cnt[0][1],
+ fg_data->low_batt_comp_cnt[1][0],
+ fg_data->low_batt_comp_cnt[1][1]);
+ pr_info("[%d, %d], [%d, %d], [%d, %d]\n",
+ fg_data->low_batt_comp_cnt[2][0],
+ fg_data->low_batt_comp_cnt[2][1],
+ fg_data->low_batt_comp_cnt[3][0],
+ fg_data->low_batt_comp_cnt[3][1],
+ fg_data->low_batt_comp_cnt[4][0],
+ fg_data->low_batt_comp_cnt[4][1]);
+}
+
+
+static int check_low_batt_comp_condition(
+ struct i2c_client *client, int *nLevel)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ int i;
+ int j;
+ int ret = 0;
+
+ for (i = 0; i < LOW_BATT_COMP_RANGE_NUM; i++) {
+ for (j = 0; j < LOW_BATT_COMP_LEVEL_NUM; j++) {
+ if (fg_data->low_batt_comp_cnt[i][j] >=
+ MAX_LOW_BATT_CHECK_CNT) {
+ display_low_batt_comp_cnt(client);
+ ret = 1;
+ *nLevel = j*2 + 1;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+void fg_low_batt_compensation(struct i2c_client *client, u32 level)
+{
+#if defined(CONFIG_MACH_KONA)
+ struct power_supply *battery_psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+#endif
+ int read_val;
+ u32 temp;
+
+ pr_info("%s: Adjust SOCrep to %d!!\n",
+ __func__, level);
+
+ read_val = fg_read_register(client, MAX17047_REG_FULLCAP);
+ if (read_val < 0)
+ return;
+
+#if defined(CONFIG_MACH_KONA)
+ if (read_val > 2) { /* 3% compensation */
+ /* RemCapREP (05h) = FullCap(10h) x 0.0301 */
+ temp = read_val * (level*100 + 1) / 10000;
+
+ /* Display conpensation 3% value for debug screen */
+ value.intval = 1;
+ battery_psy->set_property(battery_psy,
+ POWER_SUPPLY_PROP_COMPENSATION_3,
+ &value);
+ } else { /* 1% compensation */
+ /* RemCapREP (05h) = FullCap(10h) x 0.0090 */
+ temp = read_val * (level*90) / 10000;
+
+ /* Display conpensation 1% value for debug screen */
+ value.intval = 1;
+ battery_psy->set_property(battery_psy,
+ POWER_SUPPLY_PROP_COMPENSATION_1,
+ &value);
+ }
+#else
+ if (read_val > 2) /* 3% compensation */
+ /* RemCapREP (05h) = FullCap(10h) x 0.0301 */
+ temp = read_val * (level*100 + 1) / 10000;
+ else /* 1% compensation */
+ /* RemCapREP (05h) = FullCap(10h) x 0.0090 */
+ temp = read_val * (level*90) / 10000;
+#endif
+
+ fg_write_register(client, MAX17047_REG_REMCAP_REP, (u16)temp);
+}
+
+void prevent_early_poweroff(struct i2c_client *client,
+ int vcell, int *fg_soc)
+{
+ int soc = 0;
+ int read_val;
+
+ soc = get_fuelgauge_value(client, FG_LEVEL);
+
+ if (soc > POWER_OFF_SOC_HIGH_MARGIN)
+ return;
+
+ pr_info("%s: soc=%d%%, vcell=%d\n", __func__,
+ soc, vcell);
+
+ if (vcell > POWER_OFF_VOLTAGE_HIGH_MARGIN) {
+ read_val = fg_read_register(client, MAX17047_REG_FULLCAP);
+ /* FullCAP * 0.013 */
+ fg_write_register(client, MAX17047_REG_REMCAP_REP,
+ (u16)(read_val * 13 / 1000));
+ msleep(200);
+ *fg_soc = max17047_get_soc(client);
+ dev_info(&client->dev, "%s : new soc=%d, vcell=%d\n",
+ __func__, *fg_soc, vcell);
+ }
+}
+
+int low_batt_compensation(struct i2c_client *client,
+ int fg_soc, int fg_vcell, int fg_current)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ int fg_avg_current = 0;
+ int fg_min_current = 0;
+ int new_level = 0;
+ int i, table_size;
+
+ /* Not charging, Under low battery comp voltage */
+ if (fg_vcell <= fg_battery_data[SDI].low_battery_comp_voltage) {
+ fg_avg_current = fg_read_avg_current(client);
+ fg_min_current = min(fg_avg_current, fg_current);
+
+ table_size =
+ sizeof(fg_battery_data[SDI].low_battery_table) /
+ (sizeof(s16)*TABLE_MAX);
+
+ for (i = 1; i < CURRENT_RANGE_MAX_NUM; i++) {
+ if ((fg_min_current >= fg_battery_data[SDI].low_battery_table[i-1][RANGE]) &&
+ (fg_min_current < fg_battery_data[SDI].low_battery_table[i][RANGE])) {
+ if (fg_soc >= 2 && fg_vcell <
+ get_low_batt_threshold(client,
+ i, fg_min_current, 1)) {
+ add_low_batt_comp_cnt(
+ client, i, 1);
+ } else {
+ reset_low_batt_comp_cnt(client);
+ }
+ }
+ }
+
+ if (check_low_batt_comp_condition(client, &new_level)) {
+ fg_low_batt_compensation(client, new_level);
+ reset_low_batt_comp_cnt(client);
+
+ /* Do not update soc right after
+ * low battery compensation
+ * to prevent from powering-off suddenly
+ */
+ pr_info("%s: SOC is set to %d by low compensation!!\n",
+ __func__, max17047_get_soc(client));
+ }
+ }
+
+ /* Prevent power off over 3500mV */
+ prevent_early_poweroff(client, fg_vcell, &fg_soc);
+
+ return fg_soc;
+}
+
+int fg_adjust_capacity(struct i2c_client *client)
+{
+ u8 data[2];
+
+ data[0] = 0;
+ data[1] = 0;
+
+ /* 1. Write RemCapREP(05h)=0; */
+ if (max17047_i2c_write(client, MAX17047_REG_REMCAP_REP, data) < 0) {
+ pr_err("%s: Failed to write RemCap_REP\n", __func__);
+ return -1;
+ }
+ msleep(200);
+
+ pr_info("%s: After adjust - RepSOC(%d)\n", __func__, max17047_get_soc(client));
+
+ return 0;
+}
+
+static bool is_booted_in_low_battery(struct i2c_client *client)
+{
+ int fg_vcell = get_fuelgauge_value(client, FG_VOLTAGE);
+ int fg_current = get_fuelgauge_value(client, FG_CURRENT);
+ int threshold = 0;
+
+ threshold = 3300 + ((fg_current * 17) / 100);
+
+ if (fg_vcell <= threshold)
+ return true;
+ else
+ return false;
+}
+
+static bool fuelgauge_recovery_handler(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ int current_soc;
+ int avsoc;
+ int temperature;
+
+ if (fg_data->soc > LOW_BATTERY_SOC_REDUCE_UNIT) {
+ pr_err("%s: Reduce the Reported SOC by 1%%\n",
+ __func__);
+ current_soc =
+ get_fuelgauge_value(client, FG_LEVEL);
+
+ if (current_soc) {
+ pr_info("%s: Returning to Normal discharge path\n",
+ __func__);
+ pr_info("%s: Actual SOC(%d) non-zero\n",
+ __func__, current_soc);
+ fg_data->is_low_batt_alarm = false;
+ } else {
+ temperature =
+ get_fuelgauge_value(client, FG_TEMPERATURE);
+ avsoc =
+ get_fuelgauge_value(client, FG_AV_SOC);
+
+ if ((fg_data->soc > avsoc) ||
+ (temperature < 0)) {
+ fg_data->soc -=
+ LOW_BATTERY_SOC_REDUCE_UNIT;
+ pr_err("%s: New Reduced RepSOC (%d)\n",
+ __func__, fg_data->soc);
+ } else
+ pr_info("%s: Waiting for recovery (AvSOC:%d)\n",
+ __func__, avsoc);
+ }
+ }
+
+ return fg_data->is_low_batt_alarm;
+}
+
+
+static int get_fuelgauge_soc(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ struct power_supply *battery_psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+ int fg_soc;
+ int fg_vfsoc;
+ int fg_vcell;
+ int fg_current;
+ int avg_current;
+ ktime_t current_time;
+ struct timespec ts;
+ int fullcap_check_interval;
+ int cable_type;
+
+ if (fg_data->is_low_batt_alarm) {
+ if (fuelgauge_recovery_handler(client)) {
+ fg_soc = fg_data->soc;
+ goto return_soc;
+ }
+ }
+
+ current_time = alarm_get_elapsed_realtime();
+ ts = ktime_to_timespec(current_time);
+
+ /* check fullcap range */
+ fullcap_check_interval =
+ (ts.tv_sec - fg_data->fullcap_check_interval);
+ if (fullcap_check_interval >
+ VFFULLCAP_CHECK_INTERVAL) {
+ dev_info(&client->dev,
+ "%s: check fullcap range (interval:%d)\n",
+ __func__, fullcap_check_interval);
+ fg_check_vf_fullcap_range(client);
+ fg_data->fullcap_check_interval = ts.tv_sec;
+ }
+
+ fg_soc = get_fuelgauge_value(client, FG_LEVEL);
+ if (fg_soc < 0) {
+ pr_info("Can't read soc!!!");
+ fg_soc = fg_data->soc;
+ }
+
+ if (!battery_psy) {
+ pr_info("%s : battery driver didn't load yet.\n", __func__);
+ return fg_soc;
+ }
+
+ battery_psy->get_property(battery_psy,
+ POWER_SUPPLY_PROP_ONLINE,
+ &value);
+
+ cable_type = value.intval;
+
+ if (fg_data->low_batt_boot_flag) {
+ fg_soc = 0;
+
+ if (cable_type != POWER_SUPPLY_TYPE_BATTERY &&
+ !is_booted_in_low_battery(client)) {
+ fg_adjust_capacity(client);
+ fg_data->low_batt_boot_flag = 0;
+ }
+
+ if (cable_type == POWER_SUPPLY_TYPE_BATTERY)
+ fg_data->low_batt_boot_flag = 0;
+ }
+
+ fg_vcell = get_fuelgauge_value(client, FG_VOLTAGE);
+ fg_current = get_fuelgauge_value(client, FG_CURRENT);
+ avg_current = get_fuelgauge_value(client, FG_CURRENT_AVG);
+ fg_vfsoc = get_fuelgauge_value(client, FG_VF_SOC);
+
+
+ battery_psy->get_property(battery_psy,
+ POWER_SUPPLY_PROP_STATUS,
+ &value);
+
+ /* Algorithm for reducing time to fully charged (from MAXIM) */
+ if (value.intval != POWER_SUPPLY_STATUS_DISCHARGING &&
+ value.intval != POWER_SUPPLY_STATUS_FULL &&
+ cable_type != POWER_SUPPLY_TYPE_USB &&
+ /* Skip when first check after boot up */
+ !fg_data->is_first_check &&
+ (fg_vfsoc > VFSOC_FOR_FULLCAP_LEARNING &&
+ (fg_current > LOW_CURRENT_FOR_FULLCAP_LEARNING &&
+ fg_current < HIGH_CURRENT_FOR_FULLCAP_LEARNING) &&
+ (avg_current > LOW_AVGCURRENT_FOR_FULLCAP_LEARNING &&
+ avg_current < HIGH_AVGCURRENT_FOR_FULLCAP_LEARNING))) {
+
+ if (fg_data->full_check_flag == 2) {
+ pr_info("%s: force fully charged SOC !! (%d)",
+ __func__, fg_data->full_check_flag);
+ fg_set_full_charged(client);
+ fg_soc = get_fuelgauge_value(client, FG_LEVEL);
+ } else if (fg_data->full_check_flag < 2)
+ pr_info("%s: full_check_flag (%d)",
+ __func__, fg_data->full_check_flag);
+
+ /* prevent overflow */
+ if (fg_data->full_check_flag++ > 10000)
+ fg_data->full_check_flag = 3;
+ } else
+ fg_data->full_check_flag = 0;
+
+ /* Checks vcell level and tries to compensate SOC if needed.*/
+ /* If jig cable is connected, then skip low batt compensation check. */
+ if (is_jig_attached != JIG_ON &&
+ value.intval == POWER_SUPPLY_STATUS_DISCHARGING)
+ fg_soc = low_batt_compensation(
+ client, fg_soc, fg_vcell, fg_current);
+
+ if (fg_data->is_first_check)
+ fg_data->is_first_check = false;
+ fg_data->soc = fg_soc;
+
+return_soc:
+
+#if defined(CONFIG_MACH_KONA)
+ if (fg_data->full_soc <= 0)
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+
+ fg_soc =(min((fg_soc * 10000 / (fg_data->full_soc)), 1000));
+#endif
+
+ pr_info("%s: soc(%d), low_batt_alarm(%d)\n",
+ __func__, fg_data->soc,
+ fg_data->is_low_batt_alarm);
+
+ return fg_soc;
+}
+
+static void max17047_adjust_fullsoc(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data =
+ i2c_get_clientdata(client);
+ int prev_full_soc = fg_data->full_soc;
+ int raw_soc = max17047_get_rawsoc(fg_data->client);
+ int keep_soc = 0;
+
+ if (raw_soc < 0) {
+ pr_err("%s : fg data error!(%d)\n", __func__, raw_soc);
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+ return;
+ }
+
+ if (raw_soc < FULL_SOC_LOW)
+ fg_data->full_soc = FULL_SOC_LOW;
+ else if (raw_soc > FULL_SOC_HIGH) {
+ keep_soc = FULL_SOC_HIGH / 100;
+ fg_data->full_soc = (FULL_SOC_HIGH - keep_soc);
+ } else {
+ keep_soc = ((raw_soc * KEEP_FULL_SOC) / 10000);
+ if (raw_soc > (FULL_SOC_LOW + keep_soc))
+ fg_data->full_soc = raw_soc - keep_soc;
+ else
+ fg_data->full_soc = FULL_SOC_LOW;
+ }
+
+ if (prev_full_soc != fg_data->full_soc)
+ pr_info("%s : full_soc(%d->%d), rsoc(%d), keep(%d)\n", __func__,
+ prev_full_soc, fg_data->full_soc, raw_soc, keep_soc);
+}
+
+/* SOC% alert, disabled(0xFF00) */
+static void max17047_set_salrt(struct max17047_fuelgauge_data *fg_data,
+ u8 min, u8 max)
+{
+ struct i2c_client *client = fg_data->client;
+ u8 i2c_data[2];
+ pr_info("%s: min(%d%%), max(%d%%)\n", __func__, min, max);
+
+ i2c_data[1] = max;
+ i2c_data[0] = min;
+ max17047_i2c_write(client, MAX17047_REG_SALRT_TH, i2c_data);
+
+ max17047_i2c_read(client, MAX17047_REG_SALRT_TH, i2c_data);
+ if ((i2c_data[0] != min) || (i2c_data[1] != max))
+ pr_err("%s: SALRT_TH is not valid (0x%02d%02d ? 0x%02d%02d)\n",
+ __func__, i2c_data[1], i2c_data[0], max, min);
+}
+
+/* Temperature alert, disabled(0x7F80) */
+static void max17047_set_talrt(struct max17047_fuelgauge_data *fg_data,
+ u8 min, u8 max)
+{
+ struct i2c_client *client = fg_data->client;
+ u8 i2c_data[2];
+ pr_info("%s: min(0x%02x), max(0x%02x)\n", __func__, min, max);
+
+ i2c_data[1] = max;
+ i2c_data[0] = min;
+ max17047_i2c_write(client, MAX17047_REG_TALRT_TH, i2c_data);
+
+ max17047_i2c_read(client, MAX17047_REG_TALRT_TH, i2c_data);
+ if ((i2c_data[0] != min) || (i2c_data[1] != max))
+ pr_err("%s: TALRT_TH is not valid (0x%02d%02d ? 0x%02d%02d)\n",
+ __func__, i2c_data[1], i2c_data[0], max, min);
+}
+
+/* Voltage alert, disabled(0xFF00) */
+static void max17047_set_valrt(struct max17047_fuelgauge_data *fg_data,
+ u8 min, u8 max)
+{
+ struct i2c_client *client = fg_data->client;
+ u8 i2c_data[2];
+ pr_info("%s: min(%dmV), max(%dmV)\n", __func__, min * 20, max * 20);
+
+ i2c_data[1] = max;
+ i2c_data[0] = min;
+ max17047_i2c_write(client, MAX17047_REG_VALRT_TH, i2c_data);
+
+ max17047_i2c_read(client, MAX17047_REG_VALRT_TH, i2c_data);
+ if ((i2c_data[0] != min) || (i2c_data[1] != max))
+ pr_err("%s: VALRT_TH is not valid (0x%02d%02d ? 0x%02d%02d)\n",
+ __func__, i2c_data[1], i2c_data[0], max, min);
+}
+
+static void max17047_alert_init(struct max17047_fuelgauge_data *fg_data)
+{
+ struct i2c_client *client = fg_data->client;
+ u8 i2c_data[2];
+ pr_debug("%s\n", __func__);
+
+ /* SALRT Threshold setting */
+ /* min 1%, max disable */
+ max17047_set_salrt(fg_data, 0x01, 0xFF);
+
+ /* TALRT Threshold setting */
+ /* min disable, max disable */
+ max17047_set_talrt(fg_data, 0x80, 0x7F);
+
+ /* VALRT Threshold setting */
+ /* min disable, max disable */
+ max17047_set_valrt(fg_data, 0x00, 0xFF);
+
+ /* Enable SOC alerts */
+ max17047_i2c_read(client, MAX17047_REG_CONFIG, i2c_data);
+ i2c_data[0] |= (0x1 << 2);
+ max17047_i2c_write(client, MAX17047_REG_CONFIG, i2c_data);
+}
+
+static void max17047_reg_init(struct max17047_fuelgauge_data *fg_data)
+{
+ struct i2c_client *client = fg_data->client;
+ u8 i2c_data[2];
+ pr_debug("%s\n", __func__);
+
+ if (max17047_i2c_read(client, MAX17047_REG_FILTERCFG, i2c_data) < 0)
+ return;
+
+ /* Clear average vcell (12 sec) */
+ i2c_data[0] &= 0x8f;
+
+ max17047_i2c_write(client, MAX17047_REG_FILTERCFG, i2c_data);
+
+ i2c_data[0] = 0xd9;
+ i2c_data[1] = 0x35;
+ max17047_i2c_write(client, MAX17047_REG_CGAIN, i2c_data);
+}
+
+static void max17047_update_work(struct work_struct *work)
+{
+ struct max17047_fuelgauge_data *fg_data = container_of(work,
+ struct max17047_fuelgauge_data,
+ update_work.work);
+ struct power_supply *battery_psy;
+ struct i2c_client *client = fg_data->client;
+ union power_supply_propval value;
+ pr_debug("%s\n", __func__);
+
+#ifdef CONFIG_SLP
+ battery_psy = &fg_data->fuelgauge;
+#else
+ battery_psy = power_supply_get_by_name("battery");
+#endif
+
+ max17047_get_vcell(client);
+ max17047_get_vfocv(client);
+ max17047_get_avgvcell(client);
+ max17047_get_rawsoc(client);
+ max17047_get_soc(client);
+
+ pr_info("%s: VCELL(%d), VFOCV(%d), AVGVCELL(%d), RAWSOC(%d), SOC(%d)\n",
+ __func__, fg_data->vcell,
+ fg_data->vfocv, fg_data->avgvcell,
+ fg_data->rawsoc, fg_data->soc);
+
+ max17047_test_read(fg_data);
+
+ if (!battery_psy || !battery_psy->set_property) {
+ pr_err("%s: fail to get battery power supply\n", __func__);
+ return;
+ }
+
+ battery_psy->set_property(battery_psy,
+ POWER_SUPPLY_PROP_STATUS,
+ &value);
+
+ wake_lock_timeout(&fg_data->update_wake_lock, HZ);
+}
+
+#ifdef DEBUG_FUELGAUGE_POLLING
+static void max17047_polling_work(struct work_struct *work)
+{
+ struct max17047_fuelgauge_data *fg_data = container_of(work,
+ struct max17047_fuelgauge_data,
+ polling_work.work);
+ int reg;
+ int i;
+ u8 data[2];
+ u8 buf[512];
+
+ max17047_get_vcell(fg_data->client);
+ max17047_get_vfocv(fg_data->client);
+ max17047_get_avgvcell(fg_data->client);
+ max17047_get_rawsoc(fg_data->client);
+ max17047_get_soc(fg_data->client);
+
+ pr_info("%s: VCELL(%d), VFOCV(%d), AVGVCELL(%d), RAWSOC(%d), SOC(%d)\n",
+ __func__, fg_data->vcell,
+ fg_data->vfocv, fg_data->avgvcell,
+ fg_data->rawsoc, fg_data->soc);
+
+ max17047_test_read(fg_data);
+
+ schedule_delayed_work(&fg_data->polling_work,
+ msecs_to_jiffies(MAX17047_POLLING_INTERVAL));
+}
+#endif
+
+static enum power_supply_property max17047_fuelgauge_props[] = {
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_VOLTAGE_AVG,
+ POWER_SUPPLY_PROP_CAPACITY,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static int max17047_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max17047_fuelgauge_data *fg_data = container_of(psy,
+ struct max17047_fuelgauge_data,
+ fuelgauge);
+ switch (psp) {
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ switch (val->intval) {
+ case VOLTAGE_TYPE_VCELL:
+ val->intval = max17047_get_vcell(fg_data->client);
+ break;
+ case VOLTAGE_TYPE_VFOCV:
+ val->intval = max17047_get_vfocv(fg_data->client);
+ break;
+ default:
+ val->intval = max17047_get_vcell(fg_data->client);
+ break;
+ }
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_AVG:
+ val->intval = max17047_get_avgvcell(fg_data->client);
+ break;
+ /* Current (mA) */
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = get_fuelgauge_value(fg_data->client, FG_CURRENT);
+ break;
+ /* Average Current (mA) */
+ case POWER_SUPPLY_PROP_CURRENT_AVG:
+ val->intval = get_fuelgauge_value(fg_data->client, FG_CURRENT_AVG);
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ switch (val->intval) {
+ case SOC_TYPE_ADJUSTED:
+ /*val->intval = max17047_get_soc(fg_data->client);*/
+ val->intval = get_fuelgauge_soc(fg_data->client) / 10;
+ break;
+ case SOC_TYPE_RAW:
+ val->intval = max17047_get_rawsoc(fg_data->client);
+ break;
+ case SOC_TYPE_FULL:
+ val->intval = fg_data->full_soc;
+ break;
+ default:
+ val->intval = get_fuelgauge_soc(fg_data->client) / 10;
+ break;
+ }
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ val->intval = max17047_get_temperature(fg_data->client);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int max17047_reset_soc(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ u8 data[2];
+ int vfocv, fullcap;
+
+ /* delay for current stablization */
+ msleep(500);
+
+ dev_info(&client->dev,
+ "%s: Before quick-start - VCELL(%d), VFOCV(%d), VfSOC(%d), RepSOC(%d)\n",
+ __func__, max17047_get_vcell(client), max17047_get_vfocv(client),
+ fg_read_vfsoc(client), max17047_get_soc(client));
+ dev_info(&client->dev,
+ "%s: Before quick-start - current(%d), avg current(%d)\n",
+ __func__, fg_read_current(client),
+ fg_read_avg_current(client));
+
+ if (is_jig_attached == JIG_OFF) {
+ dev_info(&client->dev,
+ "%s : Return by No JIG_ON signal\n", __func__);
+ return 0;
+ }
+
+ fg_write_register(client, MAX17047_REG_CYCLES, 0);
+
+ if (max17047_i2c_read(client, MAX17047_REG_MISCCFG, data) < 0) {
+ dev_err(&client->dev, "%s: Failed to read MiscCFG\n", __func__);
+ return -1;
+ }
+
+ data[1] |= (0x1 << 2);
+ if (max17047_i2c_write(client, MAX17047_REG_MISCCFG, data) < 0) {
+ dev_err(&client->dev,
+ "%s: Failed to write MiscCFG\n", __func__);
+ return -1;
+ }
+
+ msleep(250);
+ fg_write_register(client, MAX17047_REG_FULLCAP,
+ fg_battery_data[SDI].Capacity);
+ msleep(500);
+
+ dev_info(&client->dev,
+ "%s: After quick-start - VCELL(%d), VFOCV(%d), VfSOC(%d), RepSOC(%d)\n",
+ __func__, max17047_get_vcell(client), max17047_get_vfocv(client),
+ fg_read_vfsoc(client), max17047_get_soc(client));
+ dev_info(&client->dev,
+ "%s: After quick-start - current(%d), avg current(%d)\n",
+ __func__, fg_read_current(client),
+ fg_read_avg_current(client));
+ fg_write_register(client, MAX17047_REG_CYCLES, 0x00a0);
+
+/* P8 is not turned off by Quickstart @3.4V
+ * (It's not a problem, depend on mode data)
+ * Power off for factory test(File system, etc..) */
+ vfocv = max17047_get_vfocv(client);
+ if (vfocv < POWER_OFF_VOLTAGE_LOW_MARGIN) {
+ dev_info(&client->dev, "%s: Power off condition(%d)\n",
+ __func__, vfocv);
+
+ fullcap = fg_read_register(client, MAX17047_REG_FULLCAP);
+ /* FullCAP * 0.009 */
+ fg_write_register(client, MAX17047_REG_REMCAP_REP,
+ (u16)(fullcap * 9 / 1000));
+ msleep(200);
+ dev_info(&client->dev, "%s: new soc=%d, vfocv=%d\n", __func__,
+ max17047_get_soc(client), vfocv);
+ }
+
+ dev_info(&client->dev,
+ "%s: Additional step - VfOCV(%d), VfSOC(%d), RepSOC(%d)\n",
+ __func__, max17047_get_vfocv(client),
+ fg_read_vfsoc(client), max17047_get_soc(client));
+
+ return 0;
+}
+
+
+static int max17047_set_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ const union power_supply_propval *val)
+{
+ struct max17047_fuelgauge_data *fg_data = container_of(psy,
+ struct max17047_fuelgauge_data,
+ fuelgauge);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_CAPACITY:
+ max17047_reset_soc(fg_data->client);
+ break;
+ case POWER_SUPPLY_PROP_STATUS:
+ if (val->intval != POWER_SUPPLY_STATUS_FULL)
+ return -EINVAL;
+ pr_info("%s: charger full state!\n", __func__);
+ /* adjust full soc */
+ max17047_adjust_fullsoc(fg_data->client);
+ break;
+#if defined(CONFIG_MACH_GC1)
+ case POWER_SUPPLY_PROP_RCOMP:
+ if (fg_data->prev_status == val->intval) {
+ pr_debug("%s: No rcomp change, prev(%d) = cur(%d)\n",
+ __func__, fg_data->prev_status, val->intval);
+ } else {
+ if (val->intval == POWER_SUPPLY_STATUS_CHARGING)
+ max17047_set_rcomp(fg_data->client, 1);
+ else
+ max17047_set_rcomp(fg_data->client, 0);
+ max17047_get_rcomp(fg_data->client, val->intval);
+ fg_data->prev_status = val->intval;
+ }
+ break;
+#endif
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static irqreturn_t max17047_fuelgauge_isr(int irq, void *data)
+{
+ struct max17047_fuelgauge_data *fg_data = data;
+ struct i2c_client *client = fg_data->client;
+ u8 i2c_data[2];
+ pr_info("%s: irq(%d)\n", __func__, irq);
+ mutex_lock(&fg_data->irq_lock);
+
+ max17047_i2c_read(client, MAX17047_REG_STATUS, i2c_data);
+ pr_info("%s: MAX17047_REG_STATUS(0x%02x%02x)\n", __func__,
+ i2c_data[1], i2c_data[0]);
+
+ cancel_delayed_work(&fg_data->update_work);
+ wake_lock(&fg_data->update_wake_lock);
+ schedule_delayed_work(&fg_data->update_work, msecs_to_jiffies(1000));
+
+ mutex_unlock(&fg_data->irq_lock);
+ return IRQ_HANDLED;
+}
+
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+#ifdef CONFIG_DEBUG_FS
+static int max17047_debugfs_open(struct inode *inode, struct file *filp)
+{
+ filp->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t max17047_debugfs_read_registers(struct file *filp,
+ char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct max17047_fuelgauge_data *fg_data = filp->private_data;
+ struct i2c_client *client = NULL;
+ u8 i2c_data[2];
+ int reg = 0;
+ char *buf;
+ size_t len = 0;
+ ssize_t ret;
+
+ if (!fg_data) {
+ pr_err("%s : fg_data is null\n", __func__);
+ return 0;
+ }
+
+ client = fg_data->client;
+
+ if (*ppos != 0)
+ return 0;
+
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ reg = MAX17047_REG_STATUS;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "status(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = MAX17047_REG_CONFIG;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "config(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = MAX17047_REG_RCOMP;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "rcomp(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = MAX17047_REG_CGAIN;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "cgain(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = MAX17047_REG_SALRT_TH;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "salrt(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = MAX17047_REG_MISCCFG;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "misc(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = 0x39;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "tempc0(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = 0x0F;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "remCap(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ reg = 0x10;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "fullCap(0x%x)=%02x%02x ", reg, i2c_data[1], i2c_data[0]);
+
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+
+ ret = simple_read_from_buffer(buffer, len, ppos, buf, PAGE_SIZE);
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations max17047_debugfs_fops = {
+ .owner = THIS_MODULE,
+ .open = max17047_debugfs_open,
+ .read = max17047_debugfs_read_registers,
+};
+
+static ssize_t max17047_debugfs_read_defaultdata(struct file *filp,
+ char __user *buffer, size_t count, loff_t *ppos)
+{
+ struct max17047_fuelgauge_data *fg_data = filp->private_data;
+ struct i2c_client *client = NULL;
+ u8 i2c_data[2];
+ int reg = 0;
+ char *buf;
+ size_t len = 0;
+ ssize_t ret;
+
+ if (!fg_data) {
+ pr_err("%s : fg_data is null\n", __func__);
+ return 0;
+ }
+
+ client = fg_data->client;
+
+ if (*ppos != 0)
+ return 0;
+
+ if (count < sizeof(buf))
+ return -ENOSPC;
+
+ buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ reg = MAX17047_REG_RCOMP;
+ max17047_i2c_read(client, reg, i2c_data);
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "rcomp=%02x%02x ", i2c_data[1], i2c_data[0]);
+
+ len += snprintf(buf + len, PAGE_SIZE - len,
+ "fsoc=%d", fg_data->full_soc);
+
+ len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+
+ ret = simple_read_from_buffer(buffer, len, ppos, buf, PAGE_SIZE);
+ kfree(buf);
+
+ return ret;
+}
+
+static const struct file_operations max17047_debugfs_fops2 = {
+ .owner = THIS_MODULE,
+ .open = max17047_debugfs_open,
+ .read = max17047_debugfs_read_defaultdata,
+};
+#endif
+#endif
+
+#ifdef CHECK_RCOMP_UPDATE
+static void max17047_check_rcomp_update(struct i2c_client *client)
+{
+ u8 data[2];
+ int ret, rcomp;
+
+ /* read rcomp */
+ ret = max17047_i2c_read(client, MAX17047_REG_RCOMP, data);
+ if (ret < 0)
+ return;
+
+ rcomp = (data[1] << 8) | data[0];
+ pr_info("%s: rcomp = 0x%04x\n", __func__, rcomp);
+
+ /* check rcomp update */
+ if (rcomp != MAX17047_NEW_RCOMP) {
+ data[0] = MAX17047_NEW_RCOMP & 0xff;
+ data[1] = MAX17047_NEW_RCOMP >> 8;
+ max17047_i2c_write(client, MAX17047_REG_RCOMP, data);
+ pr_info("%s: set new rcomp = 0x%04x\n",
+ __func__, MAX17047_NEW_RCOMP);
+ max17047_i2c_read(client, MAX17047_REG_RCOMP, data);
+ rcomp = (data[1] << 8) | data[0];
+ pr_info("%s: verify rcomp = 0x%04x\n", __func__, rcomp);
+ }
+}
+#endif
+
+static int __devinit max17047_fuelgauge_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct max17047_fuelgauge_data *fg_data;
+ struct max17047_platform_data *pdata = client->dev.platform_data;
+ int ret = -ENODEV;
+ int rawsoc, firstsoc;
+ ktime_t current_time;
+ struct timespec ts;
+
+ pr_info("%s: fuelgauge init\n", __func__);
+
+ if (!pdata) {
+ pr_err("%s: no platform data\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ return -EIO;
+
+ fg_data = kzalloc(sizeof(struct max17047_fuelgauge_data), GFP_KERNEL);
+ if (!fg_data)
+ return -ENOMEM;
+
+ fg_data->client = client;
+ fg_data->pdata = pdata;
+ fg_client = client;
+
+ i2c_set_clientdata(client, fg_data);
+
+ mutex_init(&fg_data->irq_lock);
+
+ wake_lock_init(&fg_data->update_wake_lock, WAKE_LOCK_SUSPEND,
+ "fuel-update");
+
+ /* Initialize full_soc, set this before fisrt SOC reading */
+ fg_data->full_soc = FULL_SOC_DEFAULT;
+ /* first full_soc update */
+ rawsoc = max17047_get_rawsoc(fg_data->client);
+ if (rawsoc > FULL_SOC_DEFAULT)
+ max17047_adjust_fullsoc(client);
+ firstsoc = max17047_get_soc(client);
+ pr_info("%s: rsoc=%d, fsoc=%d, soc=%d\n", __func__,
+ rawsoc, fg_data->full_soc, firstsoc);
+
+ if (fg_data->pdata->psy_name)
+ fg_data->fuelgauge.name =
+ fg_data->pdata->psy_name;
+ else
+ fg_data->fuelgauge.name = "max17047-fuelgauge";
+
+ fg_data->fuelgauge.type = POWER_SUPPLY_TYPE_BATTERY;
+ fg_data->fuelgauge.properties = max17047_fuelgauge_props;
+ fg_data->fuelgauge.num_properties =
+ ARRAY_SIZE(max17047_fuelgauge_props);
+ fg_data->fuelgauge.get_property = max17047_get_property;
+ fg_data->fuelgauge.set_property = max17047_set_property;
+
+ ret = power_supply_register(&client->dev, &fg_data->fuelgauge);
+ if (ret) {
+ pr_err("%s: failed power supply register\n", __func__);
+ goto err_psy_reg_fg;
+ }
+
+ current_time = alarm_get_elapsed_realtime();
+ ts = ktime_to_timespec(current_time);
+
+ fg_data->fullcap_check_interval = ts.tv_sec;
+
+ /* Init parameters to prevent wrong compensation */
+ fg_data->previous_fullcap =
+ fg_read_register(fg_data->client, MAX17047_REG_FULLCAP);
+
+ fg_data->previous_vffullcap =
+ fg_read_register(fg_data->client, MAX17047_REG_FULLCAPNOM);
+
+ max17047_test_read(fg_data);
+
+ if (is_jig_attached == JIG_ON)
+ fg_reset_capacity_by_jig_connection(fg_data->client);
+
+ /* Initialize fuelgauge alert */
+ max17047_alert_init(fg_data);
+
+ INIT_DELAYED_WORK_DEFERRABLE(&fg_data->update_work,
+ max17047_update_work);
+
+ /* Request IRQ */
+ fg_data->irq = gpio_to_irq(fg_data->pdata->irq_gpio);
+ ret = gpio_request(fg_data->pdata->irq_gpio, "fuelgauge-irq");
+ if (ret) {
+ pr_err("%s: failed requesting gpio %d\n", __func__,
+ fg_data->pdata->irq_gpio);
+ goto err_irq;
+ }
+ gpio_direction_input(fg_data->pdata->irq_gpio);
+ gpio_free(fg_data->pdata->irq_gpio);
+
+ ret = request_threaded_irq(fg_data->irq, NULL,
+ max17047_fuelgauge_isr, IRQF_TRIGGER_FALLING,
+ "max17047-alert", fg_data);
+ if (ret < 0) {
+ pr_err("%s: fail to request max17047 irq: %d: %d\n",
+ __func__, fg_data->irq, ret);
+ goto err_irq;
+ }
+
+ ret = enable_irq_wake(fg_data->irq);
+ if (ret < 0) {
+ pr_err("%s: failed enable irq wake %d\n", __func__,
+ fg_data->irq);
+ goto err_enable_irq;
+ }
+
+#ifdef DEBUG_FUELGAUGE_POLLING
+ INIT_DELAYED_WORK_DEFERRABLE(&fg_data->polling_work,
+ max17047_polling_work);
+ schedule_delayed_work(&fg_data->polling_work, 0);
+#else
+ max17047_test_read(fg_data);
+#endif
+
+ pr_info("%s: probe complete\n", __func__);
+
+#if defined(CONFIG_TARGET_LOCALE_KOR)
+#ifdef CONFIG_DEBUG_FS
+ fg_data->fg_debugfs_dir =
+ debugfs_create_dir("fg_debug", NULL);
+ if (fg_data->fg_debugfs_dir) {
+ if (!debugfs_create_file("max17047_regs", 0644,
+ fg_data->fg_debugfs_dir,
+ fg_data, &max17047_debugfs_fops))
+ pr_err("%s : debugfs_create_file, error\n", __func__);
+ if (!debugfs_create_file("default_data", 0644,
+ fg_data->fg_debugfs_dir,
+ fg_data, &max17047_debugfs_fops2))
+ pr_err("%s : debugfs_create_file2, error\n", __func__);
+ } else
+ pr_err("%s : debugfs_create_dir, error\n", __func__);
+#endif
+#endif
+
+ return 0;
+
+err_enable_irq:
+ free_irq(fg_data->irq, fg_data);
+err_irq:
+ power_supply_unregister(&fg_data->fuelgauge);
+err_psy_reg_fg:
+ wake_lock_destroy(&fg_data->update_wake_lock);
+ mutex_destroy(&fg_data->irq_lock);
+ kfree(fg_data);
+ return ret;
+}
+
+static int __devexit max17047_fuelgauge_remove(struct i2c_client *client)
+{
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+
+ wake_lock_destroy(&fg_data->update_wake_lock);
+ free_irq(fg_data->irq, fg_data);
+ power_supply_unregister(&fg_data->fuelgauge);
+#ifdef DEBUG_FUELGAUGE_POLLING
+ cancel_delayed_work(&fg_data->polling_work);
+#endif
+ cancel_delayed_work(&fg_data->update_work);
+ mutex_destroy(&fg_data->irq_lock);
+ kfree(fg_data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int max17047_fuelgauge_suspend(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ struct power_supply *psy = power_supply_get_by_name("battery");
+ union power_supply_propval value;
+ int charge_state, voltage_max, voltage_min;
+ int valrt_vol;
+ pr_info("%s\n", __func__);
+
+#ifdef DEBUG_FUELGAUGE_POLLING
+ cancel_delayed_work(&fg_data->polling_work);
+#endif
+
+#if !defined(CONFIG_SLP)
+ /* default disable */
+ valrt_vol = 0;
+
+ /* voltage alert recharge voltage */
+ if (!psy) {
+ pr_err("%s: fail to get battery psy\n", __func__);
+ return 0;
+ }
+ psy->get_property(psy, POWER_SUPPLY_PROP_STATUS, &value);
+ charge_state = value.intval;
+
+ if (charge_state == POWER_SUPPLY_STATUS_FULL) {
+ psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ &value);
+ voltage_max = value.intval;
+
+ /* valrt voltage set as recharge voltage */
+ valrt_vol = voltage_max - RECHG_DROP_VALUE;
+ } else {
+ psy->get_property(psy, POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ &value);
+ voltage_min = value.intval;
+
+ /* valrt voltage set as min voltage - 50mV */
+ valrt_vol = voltage_min - 50000;
+ }
+
+ pr_info("%s: charge state(%d), vcell(%d), valrt(%d)\n", __func__,
+ charge_state, fg_data->vcell, valrt_vol);
+
+ /* set voltage alert */
+ max17047_set_valrt(fg_data, (valrt_vol / 1000 / 20), 0xFF);
+#endif
+
+ return 0;
+}
+
+static int max17047_fuelgauge_resume(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct max17047_fuelgauge_data *fg_data = i2c_get_clientdata(client);
+ pr_info("%s\n", __func__);
+
+#if !defined(CONFIG_SLP)
+ /* min disable, max disable */
+ max17047_set_valrt(fg_data, 0x00, 0xFF);
+#endif
+
+#ifdef DEBUG_FUELGAUGE_POLLING
+ schedule_delayed_work(&fg_data->polling_work, 0);
+#endif
+
+ return 0;
+}
+#else
+#define max17047_fuelgauge_suspend NULL
+#define max17047_fuelgauge_resume NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id max17047_fuelgauge_id[] = {
+ {"max17047-fuelgauge", 0},
+ {}
+};
+
+#ifdef CONFIG_HIBERNATION
+static const u16 save_addr[] = {
+ MAX17047_REG_VALRT_TH,
+ MAX17047_REG_TALRT_TH,
+ MAX17047_REG_SALRT_TH,
+
+ MAX17047_REG_TEMPERATURE,
+ MAX17047_REG_CONFIG,
+
+ MAX17047_REG_LEARNCFG,
+ MAX17047_REG_FILTERCFG,
+ MAX17047_REG_MISCCFG,
+ MAX17047_REG_CGAIN,
+ MAX17047_REG_RCOMP,
+ MAX17047_REG_SOC_VF,
+};
+
+
+static int max17047_freeze(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct max17047_fuelgauge_data *fg_data
+ = i2c_get_clientdata(client);
+ int i, j;
+
+ if (fg_data->reg_dump) {
+ dev_err(dev, "Register dump is not clean.\n");
+ return -EINVAL;
+ }
+
+ fg_data->reg_dump = kzalloc(sizeof(u16) * ARRAY_SIZE(save_addr),
+ GFP_KERNEL);
+ if (!fg_data->reg_dump) {
+ dev_err(dev, "Cannot allocate memory for hibernation dump.\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(save_addr); i++, j += 2)
+ max17047_i2c_read(client, save_addr[i]
+ , &(fg_data->reg_dump[j]));
+
+ return 0;
+}
+
+static int max17047_restore(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct max17047_fuelgauge_data *fg_data
+ = i2c_get_clientdata(client);
+ int i, j;
+
+ if (!fg_data->reg_dump) {
+ dev_err(dev, "Cannot allocate memory for hibernation dump.\n");
+ return -ENOMEM;
+ }
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(save_addr); i++, j += 2)
+ max17047_i2c_write(client, save_addr[i]
+ , &(fg_data->reg_dump[j]));
+
+ kfree(fg_data->reg_dump);
+ fg_data->reg_dump = NULL;
+
+ return 0;
+}
+#endif
+
+
+
+#ifdef CONFIG_PM
+const struct dev_pm_ops max17047_pm = {
+ .suspend = max17047_fuelgauge_suspend,
+ .resume = max17047_fuelgauge_resume,
+#ifdef CONFIG_HIBERNATION
+ .freeze = max17047_freeze,
+ .thaw = max17047_restore,
+ .restore = max17047_restore,
+#endif
+};
+#endif
+
+
+MODULE_DEVICE_TABLE(i2c, max17047_fuelgauge_id);
+
+static struct i2c_driver max17047_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "max17047-fuelgauge",
+ .pm = &max17047_pm,
+
+ },
+ .probe = max17047_fuelgauge_i2c_probe,
+ .remove = __devexit_p(max17047_fuelgauge_remove),
+ .id_table = max17047_fuelgauge_id,
+};
+
+static int __init max17047_fuelgauge_init(void)
+{
+ return i2c_add_driver(&max17047_i2c_driver);
+}
+
+static void __exit max17047_fuelgauge_exit(void)
+{
+ i2c_del_driver(&max17047_i2c_driver);
+}
+
+module_init(max17047_fuelgauge_init);
+module_exit(max17047_fuelgauge_exit);
+
+MODULE_AUTHOR("SangYoung Son <hello.son@samsung.com>");
+MODULE_DESCRIPTION("max17047 Fuel gauge driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/battery/max77693_charger.c b/drivers/battery/max77693_charger.c
index 35289a6..5b4293c 100644
--- a/drivers/battery/max77693_charger.c
+++ b/drivers/battery/max77693_charger.c
@@ -109,10 +109,12 @@
/* MAX77693_CHG_REG_CHG_CNFG_04 */
#define MAX77693_CHG_MINVSYS_MASK 0xE0
#define MAX77693_CHG_MINVSYS_SHIFT 5
+#define MAX77693_CHG_MINVSYS_3_4V 0x04
#define MAX77693_CHG_MINVSYS_3_6V 0x06
#define MAX77693_CHG_CV_PRM_MASK 0x1F
#define MAX77693_CHG_CV_PRM_SHIFT 0
#define MAX77693_CHG_CV_PRM_4_20V 0x16
+#define MAX77693_CHG_CV_PRM_4_30V 0x1A
#define MAX77693_CHG_CV_PRM_4_35V 0x1D
#define MAX77693_CHG_CV_PRM_4_40V 0x1F
@@ -149,7 +151,11 @@
#define STABLE_POWER_DELAY 500
/* charger type detection */
+#if defined(CONFIG_MACH_KONA)
+#define DET_ERR_RETRY 7
+#else
#define DET_ERR_RETRY 5
+#endif
#define DET_ERR_DELAY 200
/* soft charging */
@@ -855,7 +861,12 @@ chg_det_err:
chg_data->reg_loop_deted = false;
state = POWER_SUPPLY_TYPE_BATTERY;
break;
- case 0x1: /* USB cabled */
+ case 0x1: /* USB cabled */
+#if defined(CONFIG_MACH_KONA)
+ if(mu_adc1k == 0x80) //MHL charging
+ state = POWER_SUPPLY_TYPE_MAINS;
+ else
+#endif
state = POWER_SUPPLY_TYPE_USB;
#ifdef CONFIG_BATTERY_WPC_CHARGER
wc_state = max77693_get_wc_state(chg_data);
@@ -1101,8 +1112,14 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
reg_data |= (0x00 << 3); /* 0min */
} else {
#if defined(USE_2STEP_TERM) /* now only T0 */
+#if defined(CONFIG_MACH_KONA)
+ reg_data = (0x05 << 0); /* 250mA */
+ reg_data |= (0x04 << 3); /* 40min */
+#else
+
reg_data = (0x04 << 0); /* 200mA */
reg_data |= (0x04 << 3); /* 40min */
+#endif
#else
#if defined(CONFIG_MACH_GC1)
reg_data = (0x02 << 0); /* 150mA */
@@ -1121,13 +1138,19 @@ static void max77693_charger_reg_init(struct max77693_charger_data *chg_data)
*/
max77693_read_reg(i2c, MAX77693_CHG_REG_CHG_CNFG_04, &reg_data);
reg_data &= (~MAX77693_CHG_MINVSYS_MASK);
+#if defined(CONFIG_MACH_KONA)
+ reg_data |= (MAX77693_CHG_MINVSYS_3_4V << MAX77693_CHG_MINVSYS_SHIFT);
+#else
reg_data |= (MAX77693_CHG_MINVSYS_3_6V << MAX77693_CHG_MINVSYS_SHIFT);
+#endif
reg_data &= (~MAX77693_CHG_CV_PRM_MASK);
#if defined(CONFIG_MACH_M0)
if ((system_rev != 3) && (system_rev >= 1))
reg_data |= (MAX77693_CHG_CV_PRM_4_35V << 0);
else
reg_data |= (MAX77693_CHG_CV_PRM_4_20V << 0);
+#elif defined(CONFIG_MACH_KONA)
+ reg_data |= (MAX77693_CHG_CV_PRM_4_30V << 0);
#else /* C1, C2, M3, T0, ... */
reg_data |= (MAX77693_CHG_CV_PRM_4_35V << 0);
#endif
diff --git a/drivers/battery/samsung_battery.c b/drivers/battery/samsung_battery.c
index ffe10e9..d3f45f2 100644
--- a/drivers/battery/samsung_battery.c
+++ b/drivers/battery/samsung_battery.c
@@ -58,15 +58,27 @@ static void battery_error_control(struct battery_info *info);
unsigned int lpcharge;
static int battery_get_lpm_state(char *str)
{
- get_option(&str, &lpcharge);
+ if (strncmp(str, "1", 1) == 0)
+ lpcharge = 1;
+
pr_info("%s: Low power charging mode: %d\n", __func__, lpcharge);
return lpcharge;
}
__setup("lpcharge=", battery_get_lpm_state);
-#if defined(CONFIG_RTC_ALARM_BOOT)
+
+/* For KitKat bootloader compatibility */
+static int bootloader_get_lpm_state(char *str)
+{
+ if (strncmp(str, "charger", 7) == 0)
+ lpcharge = 1;
+
+ pr_info("%s: Low power charging mode: %d\n", __func__, lpcharge);
+
+ return lpcharge;
+}
+__setup("androidboot.mode=", bootloader_get_lpm_state);
EXPORT_SYMBOL(lpcharge);
-#endif
/* Cable type from charger or adc */
static int battery_get_cable(struct battery_info *info)
@@ -2007,6 +2019,14 @@ static int samsung_battery_set_property(struct power_supply *ps,
case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
info->pdata->voltage_min = val->intval;
break;
+#if defined(CONFIG_MACH_KONA)
+ case POWER_SUPPLY_PROP_COMPENSATION_3:
+ info->is_comp_3 = val->intval;
+ break;
+ case POWER_SUPPLY_PROP_COMPENSATION_1:
+ info->is_comp_1 = val->intval;
+ break;
+#endif
default:
return -EINVAL;
}
@@ -2037,12 +2057,19 @@ static int samsung_usb_get_property(struct power_supply *ps,
return -EINVAL;
/* Set enable=1 only if the USB charger is connected */
- val->intval = ((info->charge_virt_state !=
- POWER_SUPPLY_STATUS_DISCHARGING) &&
- ((info->cable_type == POWER_SUPPLY_TYPE_USB) ||
+#if defined(CONFIG_MACH_KONA)
+ val->intval = (((info->cable_type == POWER_SUPPLY_TYPE_USB) ||
(info->cable_type == POWER_SUPPLY_TYPE_USB_CDP) ||
((info->cable_type == POWER_SUPPLY_TYPE_DOCK) &&
(info->online_prop == ONLINE_PROP_USB))));
+#else
+ val->intval = ((info->charge_virt_state !=
+ POWER_SUPPLY_STATUS_DISCHARGING) &&
+ ((info->cable_type == POWER_SUPPLY_TYPE_USB) ||
+ (info->cable_type == POWER_SUPPLY_TYPE_USB_CDP) ||
+ ((info->cable_type == POWER_SUPPLY_TYPE_DOCK) &&
+ (info->online_prop == ONLINE_PROP_USB))));
+#endif
return 0;
}
@@ -2161,9 +2188,11 @@ static __devinit int samsung_battery_probe(struct platform_device *pdev)
pr_info("%s: VF detect source: %s\n", __func__,
vf_src_name[info->pdata->vf_det_src]);
+#if !defined(CONFIG_MACH_KONA)
/* recalculate recharge voltage, it depends on max voltage value */
info->pdata->recharge_voltage = info->pdata->voltage_max -
RECHG_DROP_VALUE;
+#endif
pr_info("%s: Recharge voltage: %d\n", __func__,
info->pdata->recharge_voltage);
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
index e151adc..a87dc5d 100644
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -85,7 +85,6 @@ struct cpu_dbs_info_s {
cputime64_t prev_cpu_idle;
cputime64_t prev_cpu_iowait;
cputime64_t prev_cpu_wall;
- unsigned int prev_cpu_wall_delta;
cputime64_t prev_cpu_nice;
struct cpufreq_policy *cur_policy;
struct delayed_work work;
@@ -609,10 +608,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
unsigned int idle_time, wall_time, iowait_time;
unsigned int load, load_freq;
int freq_avg;
- bool deep_sleep_detected = false;
- /* the evil magic numbers, only 2 at least */
- const unsigned int deep_sleep_backoff = 10;
- const unsigned int deep_sleep_factor = 5;
j_dbs_info = &per_cpu(od_cpu_dbs_info, j);
@@ -623,32 +618,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
j_dbs_info->prev_cpu_wall);
j_dbs_info->prev_cpu_wall = cur_wall_time;
- /*
- * Ignore wall delta jitters in both directions. An
- * exceptionally long wall_time will likely result
- * idle but it was waken up to do work so the next
- * slice is less likely to want to run at low
- * frequency. Let's evaluate the next slice instead of
- * the idle long one that passed already and it's too
- * late to reduce in frequency. As opposed an
- * exceptionally short slice that just run at low
- * frequency is unlikely to be idle, but we may go
- * back to idle pretty soon and that not idle slice
- * already passed. If short slices will keep coming
- * after a series of long slices the exponential
- * backoff will converge faster and we'll react faster
- * to high load. As opposed we'll decay slower
- * towards low load and long idle times.
- */
- if (j_dbs_info->prev_cpu_wall_delta >
- wall_time * deep_sleep_factor ||
- j_dbs_info->prev_cpu_wall_delta * deep_sleep_factor <
- wall_time)
- deep_sleep_detected = true;
- j_dbs_info->prev_cpu_wall_delta =
- (j_dbs_info->prev_cpu_wall_delta * deep_sleep_backoff
- + wall_time) / (deep_sleep_backoff+1);
-
idle_time = (unsigned int) cputime64_sub(cur_idle_time,
j_dbs_info->prev_cpu_idle);
j_dbs_info->prev_cpu_idle = cur_idle_time;
@@ -674,9 +643,6 @@ static void dbs_check_cpu(struct cpu_dbs_info_s *this_dbs_info)
idle_time += jiffies_to_usecs(cur_nice_jiffies);
}
- if (deep_sleep_detected)
- continue;
-
/*
* For the purpose of ondemand, waiting for disk IO is an
* indication that you're performance critical, and not that
diff --git a/drivers/cpufreq/cpufreq_pegasusq.c b/drivers/cpufreq/cpufreq_pegasusq.c
index 208a991..c44af54 100644
--- a/drivers/cpufreq/cpufreq_pegasusq.c
+++ b/drivers/cpufreq/cpufreq_pegasusq.c
@@ -165,7 +165,7 @@ static unsigned int get_nr_run_avg(void)
#define DEF_START_DELAY (0)
#define UP_THRESHOLD_AT_MIN_FREQ (40)
-#define FREQ_FOR_RESPONSIVENESS (400000)
+#define FREQ_FOR_RESPONSIVENESS (500000)
#define HOTPLUG_DOWN_INDEX (0)
#define HOTPLUG_UP_INDEX (1)
@@ -306,7 +306,7 @@ static void apply_hotplug_lock(void)
lock = atomic_read(&g_hotplug_lock);
flag = lock - online;
- if (flag == 0)
+ if (lock == 0 || flag == 0)
return;
work = flag > 0 ? &dbs_info->up_work : &dbs_info->down_work;
@@ -380,6 +380,13 @@ void cpufreq_pegasusq_min_cpu_unlock(void)
lock = atomic_read(&g_hotplug_lock);
if (lock == 0)
return;
+#if defined(CONFIG_HAS_EARLYSUSPEND) && EARLYSUSPEND_HOTPLUGLOCK
+ if (dbs_tuners_ins.early_suspend >= 0) { /* if LCD is off-state */
+ atomic_set(&g_hotplug_lock, 1);
+ apply_hotplug_lock();
+ return;
+ }
+#endif
flag = lock - online;
if (flag >= 0)
return;
@@ -484,6 +491,21 @@ static ssize_t show_hotplug_lock(struct kobject *kobj,
return sprintf(buf, "%d\n", atomic_read(&g_hotplug_lock));
}
+static ssize_t show_cpucore_table(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ ssize_t count = 0;
+ int i;
+
+ for (i = CONFIG_NR_CPUS; i > 0; i--) {
+ count += sprintf(&buf[count], "%d ", i);
+ }
+ count += sprintf(&buf[count], "\n");
+
+ return count;
+}
+
+
#define show_hotplug_param(file_name, num_core, up_down) \
static ssize_t show_##file_name##_##num_core##_##up_down \
(struct kobject *kobj, struct attribute *attr, char *buf) \
@@ -813,6 +835,7 @@ define_one_global_rw(max_cpu_lock);
define_one_global_rw(min_cpu_lock);
define_one_global_rw(hotplug_lock);
define_one_global_rw(dvfs_debug);
+define_one_global_ro(cpucore_table);
static struct attribute *dbs_attributes[] = {
&sampling_rate_min.attr,
@@ -846,6 +869,7 @@ static struct attribute *dbs_attributes[] = {
&hotplug_rq_3_0.attr,
&hotplug_rq_3_1.attr,
&hotplug_rq_4_0.attr,
+ &cpucore_table.attr,
NULL
};
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index f6cd315..ad683ec 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -32,6 +32,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/cpumask.h>
+#include <linux/sched.h> /* for current / set_cpus_allowed() */
#include <linux/io.h>
#include <linux/delay.h>
@@ -1131,23 +1132,16 @@ static int transition_frequency_pstate(struct powernow_k8_data *data,
return res;
}
-struct powernowk8_target_arg {
- struct cpufreq_policy *pol;
- unsigned targfreq;
- unsigned relation;
-};
-
-static long powernowk8_target_fn(void *arg)
+/* Driver entry point to switch to the target frequency */
+static int powernowk8_target(struct cpufreq_policy *pol,
+ unsigned targfreq, unsigned relation)
{
- struct powernowk8_target_arg *pta = arg;
- struct cpufreq_policy *pol = pta->pol;
- unsigned targfreq = pta->targfreq;
- unsigned relation = pta->relation;
+ cpumask_var_t oldmask;
struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu);
u32 checkfid;
u32 checkvid;
unsigned int newstate;
- int ret;
+ int ret = -EIO;
if (!data)
return -EINVAL;
@@ -1155,16 +1149,29 @@ static long powernowk8_target_fn(void *arg)
checkfid = data->currfid;
checkvid = data->currvid;
+ /* only run on specific CPU from here on. */
+ /* This is poor form: use a workqueue or smp_call_function_single */
+ if (!alloc_cpumask_var(&oldmask, GFP_KERNEL))
+ return -ENOMEM;
+
+ cpumask_copy(oldmask, tsk_cpus_allowed(current));
+ set_cpus_allowed_ptr(current, cpumask_of(pol->cpu));
+
+ if (smp_processor_id() != pol->cpu) {
+ printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu);
+ goto err_out;
+ }
+
if (pending_bit_stuck()) {
printk(KERN_ERR PFX "failing targ, change pending bit set\n");
- return -EIO;
+ goto err_out;
}
pr_debug("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
pol->cpu, targfreq, pol->min, pol->max, relation);
if (query_current_values_with_pending_wait(data))
- return -EIO;
+ goto err_out;
if (cpu_family != CPU_HW_PSTATE) {
pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
@@ -1182,7 +1189,7 @@ static long powernowk8_target_fn(void *arg)
if (cpufreq_frequency_table_target(pol, data->powernow_table,
targfreq, relation, &newstate))
- return -EIO;
+ goto err_out;
mutex_lock(&fidvid_mutex);
@@ -1195,8 +1202,9 @@ static long powernowk8_target_fn(void *arg)
ret = transition_frequency_fidvid(data, newstate);
if (ret) {
printk(KERN_ERR PFX "transition frequency failed\n");
+ ret = 1;
mutex_unlock(&fidvid_mutex);
- return 1;
+ goto err_out;
}
mutex_unlock(&fidvid_mutex);
@@ -1205,18 +1213,12 @@ static long powernowk8_target_fn(void *arg)
data->powernow_table[newstate].index);
else
pol->cur = find_khz_freq_from_fid(data->currfid);
+ ret = 0;
- return 0;
-}
-
-/* Driver entry point to switch to the target frequency */
-static int powernowk8_target(struct cpufreq_policy *pol,
- unsigned targfreq, unsigned relation)
-{
- struct powernowk8_target_arg pta = { .pol = pol, .targfreq = targfreq,
- .relation = relation };
-
- return work_on_cpu(pol->cpu, powernowk8_target_fn, &pta);
+err_out:
+ set_cpus_allowed_ptr(current, oldmask);
+ free_cpumask_var(oldmask);
+ return ret;
}
/* Driver entry point to verify the policy and range of frequencies */
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 00efbf6..8a0ed22 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -4,3 +4,9 @@ else
obj-y += drm/ vga/ stub/ ion/
endif
+ifeq ($(CONFIG_MALI400),y)
+ifeq ($(CONFIG_MALI_VER_R3P2),y)
+obj-y += mali400/r3p2/mali/
+obj-y += mali400/r3p2/ump/
+endif
+endif
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 94f9ec1..d11f4f3 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -40,7 +40,6 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/
obj-$(CONFIG_DRM_VIA) +=via/
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
ifeq ($(CONFIG_NAPLES_COMMON),y)
-obj-$(CONFIG_DRM_EXYNOS) +=exynos_tmp/
else
obj-$(CONFIG_DRM_EXYNOS) +=exynos/
endif
diff --git a/drivers/gpu/ion/exynos/exynos_ion.c b/drivers/gpu/ion/exynos/exynos_ion.c
index 100f055..9779777 100644
--- a/drivers/gpu/ion/exynos/exynos_ion.c
+++ b/drivers/gpu/ion/exynos/exynos_ion.c
@@ -487,8 +487,10 @@ static int ion_exynos_contig_heap_allocate(struct ion_heap *heap,
}
buffer->flags = flags;
+#ifdef CONFIG_ION_EXYNOS_CONTIGHEAP_DEBUG
printk(KERN_INFO "[ION] alloc: 0x%x\n",
(unsigned int)buffer->priv_phys);
+#endif
return 0;
}
@@ -503,8 +505,10 @@ static void ion_exynos_contig_heap_free(struct ion_buffer *buffer)
#endif
ret = cma_free(buffer->priv_phys);
+#ifdef CONFIG_ION_EXYNOS_CONTIGHEAP_DEBUG
printk(KERN_INFO "[ION] free: 0x%x, [0x%x]\n",
(unsigned int)buffer->priv_phys, ret);
+#endif
}
static int ion_exynos_contig_heap_phys(struct ion_heap *heap,
@@ -544,6 +548,8 @@ static int ion_exynos_contig_heap_map_user(struct ion_heap *heap,
if (buffer->flags & ION_EXYNOS_NONCACHE_MASK)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ /* Set User Permission */
+ vma->vm_page_prot = pte_mkdirty(vma->vm_page_prot);
return remap_pfn_range(vma, vma->vm_start, pfn + vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
diff --git a/drivers/gpu/mali400/Kconfig b/drivers/gpu/mali400/Kconfig
new file mode 100644
index 0000000..8ec13b3
--- /dev/null
+++ b/drivers/gpu/mali400/Kconfig
@@ -0,0 +1,26 @@
+menuconfig MALI400
+ tristate "Mali-300/400/450 support"
+ depends on ARM
+ default y
+ ---help---
+ This enables support for the ARM Mali-300, Mali-400, and Mali-450
+ GPUs.
+
+ To compile this driver as a module, choose M here: the module will be
+ called mali.
+
+choice
+depends on MALI400
+prompt "Select MALI VER"
+default MALI_VER_R3P2
+config MALI_VER_R3P2
+ bool "Mali400 Version R3P2"
+ help
+ Choose this option to select DDK version.
+
+if MALI_VER_R3P2
+source "drivers/gpu/mali400/r3p2/mali/Kconfig"
+source "drivers/gpu/mali400/r3p2/ump/Kconfig"
+endif
+
+endchoice
diff --git a/drivers/gpu/mali400/r3p2/mali/Kbuild b/drivers/gpu/mali400/r3p2/mali/Kbuild
new file mode 100644
index 0000000..81acbb8
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/Kbuild
@@ -0,0 +1,220 @@
+#
+# Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# This file is called by the Linux build system.
+
+# set up defaults if not defined by the user
+TIMESTAMP ?= default
+OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 16
+USING_GPU_UTILIZATION ?= 1
+PROFILING_SKIP_PP_JOBS ?= 0
+PROFILING_SKIP_PP_AND_GP_JOBS ?= 0
+MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP ?= 0
+MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED ?= 0
+MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS ?= 0
+MALI_UPPER_HALF_SCHEDULING ?= 1
+# MALI_SEC
+# Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
+ifeq ($(CONFIG_CPU_EXYNOS4210),y)
+ TARGET_PLATFORM=pegasus-m400
+endif
+ifeq ($(CONFIG_CPU_EXYNOS4212),y)
+ TARGET_PLATFORM=pegasus-m400
+endif
+ifeq ($(CONFIG_CPU_EXYNOS4412),y)
+ TARGET_PLATFORM=pegasus-m400
+endif
+ifeq ($(CONFIG_SOC_EXYNOS3470),y)
+ TARGET_PLATFORM=exynos4270
+endif
+
+include $(srctree)/$(src)/MALI_CONFIGURATION
+MALI_PLATFORM = $(MALI_PLATFORM-$(TARGET_PLATFORM))
+EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+MALI_PLATFORM_FILES = $(subst $(srctree)/$(src)/,,$(wildcard $(srctree)/$(src)/platform/$(MALI_PLATFORM)/*.c))
+# End of MALI_SEC
+
+# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
+# The ARM proprietary product will only include the license/proprietary directory
+# The GPL product will only include the license/gpl directory
+$(warning Current directory is $(srctree)/$(src) from $(shell pwd))
+ifeq ($(wildcard $(srctree)/$(src)/linux/license/gpl/*),)
+ ccflags-y += -I$(srctree)/$(src)/linux/license/proprietary
+ ifeq ($(CONFIG_MALI400_PROFILING),y)
+ $(error Profiling is incompatible with non-GPL license)
+ endif
+ ifeq ($(CONFIG_PM_RUNTIME),y)
+ $(error Runtime PM is incompatible with non-GPL license)
+ endif
+ ifeq ($(CONFIG_DMA_SHARED_BUFFER),y)
+ $(error DMA-BUF is incompatible with non-GPL license)
+ endif
+ $(error Linux Device integration is incompatible with non-GPL license)
+else
+ ccflags-y += -I$(srctree)/$(src)/linux/license/gpl
+endif
+
+mali-y += \
+ linux/mali_osk_atomics.o \
+ linux/mali_osk_irq.o \
+ linux/mali_osk_wq.o \
+ linux/mali_osk_locks.o \
+ linux/mali_osk_wait_queue.o \
+ linux/mali_osk_low_level_mem.o \
+ linux/mali_osk_math.o \
+ linux/mali_osk_memory.o \
+ linux/mali_osk_misc.o \
+ linux/mali_osk_mali.o \
+ linux/mali_osk_notification.o \
+ linux/mali_osk_time.o \
+ linux/mali_osk_timers.o
+
+mali-y += \
+ linux/mali_ukk_mem.o \
+ linux/mali_ukk_gp.o \
+ linux/mali_ukk_pp.o \
+ linux/mali_ukk_core.o
+
+# Source files which always are included in a build
+mali-y += \
+ common/mali_kernel_core.o \
+ linux/mali_kernel_linux.o \
+ common/mali_kernel_descriptor_mapping.o \
+ common/mali_session.o \
+ linux/mali_device_pause_resume.o \
+ common/mali_kernel_vsync.o \
+ linux/mali_ukk_vsync.o \
+ linux/mali_kernel_sysfs.o \
+ common/mali_mmu.o \
+ common/mali_mmu_page_directory.o \
+ common/mali_memory.o \
+ common/mali_kernel_memory_engine.o \
+ common/mali_block_allocator.o \
+ common/mali_kernel_mem_os.o \
+ common/mali_mem_validation.o \
+ common/mali_hw_core.o \
+ common/mali_gp.o \
+ common/mali_pp.o \
+ common/mali_pp_job.o \
+ common/mali_gp_job.o \
+ common/mali_scheduler.o \
+ common/mali_gp_scheduler.o \
+ common/mali_pp_scheduler.o \
+ common/mali_group.o \
+ common/mali_dlbu.o \
+ common/mali_broadcast.o \
+ common/mali_pm.o \
+ common/mali_pmu.o \
+ common/mali_user_settings_db.o \
+ common/mali_kernel_utilization.o \
+ common/mali_l2_cache.o \
+ common/mali_pm_domain.o \
+ linux/mali_osk_pm.o \
+ linux/mali_pmu_power_up_down.o \
+ __malidrv_build_info.o
+
+ifneq ($(MALI_PLATFORM_FILES),)
+ mali-y += $(MALI_PLATFORM_FILES:.c=.o)
+endif
+
+mali-$(CONFIG_MALI400_PROFILING) += linux/mali_ukk_profiling.o
+mali-$(CONFIG_MALI400_PROFILING) += linux/mali_osk_profiling.o
+
+mali-$(CONFIG_MALI400_INTERNAL_PROFILING) += linux/mali_profiling_internal.o timestamp-$(TIMESTAMP)/mali_timestamp.o
+ccflags-$(CONFIG_MALI400_INTERNAL_PROFILING) += -I$(srctree)/$(src)/timestamp-$(TIMESTAMP)
+
+mali-$(CONFIG_DMA_SHARED_BUFFER) += linux/mali_dma_buf.o
+mali-$(CONFIG_SYNC) += linux/mali_sync.o linux/mali_sync_user.o
+
+# Tell the Linux build system from which .o file to create the kernel module
+obj-$(CONFIG_MALI400) := mali.o
+
+ccflags-y += $(EXTRA_DEFINES)
+
+# Set up our defines, which will be passed to gcc
+ccflags-y += -DPROFILING_SKIP_PP_JOBS=$(PROFILING_SKIP_PP_JOBS)
+ccflags-y += -DPROFILING_SKIP_PP_AND_GP_JOBS=$(PROFILING_SKIP_PP_AND_GP_JOBS)
+
+ccflags-y += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
+ccflags-y += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
+ccflags-y += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
+ccflags-y += -DMALI_STATE_TRACKING=1
+ccflags-y += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
+ccflags-y += -DUSING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
+
+ifeq ($(MALI_UPPER_HALF_SCHEDULING),1)
+ ccflags-y += -DMALI_UPPER_HALF_SCHEDULING
+endif
+
+ccflags-$(CONFIG_MALI400_UMP) += -I$(srctree)/$(src)/../../ump/include/ump
+ccflags-$(CONFIG_MALI400_DEBUG) += -DDEBUG
+
+# Use our defines when compiling
+ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/include -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/platform
+# MALI_SEC
+ccflags-y += -I$(srctree)/$(src)/../ump/include -I$(srctree)/$(src)/include/linux/mali
+
+# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
+MALI_RELEASE_NAME=$(shell cat $(srctree)/$(src)/.version 2> /dev/null)
+
+SVN_INFO = (cd $(srctree)/$(src); svn info 2>/dev/null)
+
+ifneq ($(shell $(SVN_INFO) 2>/dev/null),)
+# SVN detected
+SVN_REV := $(shell $(SVN_INFO) | grep '^Revision: '| sed -e 's/^Revision: //' 2>/dev/null)
+DRIVER_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
+CHANGE_DATE := $(shell $(SVN_INFO) | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
+CHANGED_REVISION := $(shell $(SVN_INFO) | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
+REPO_URL := $(shell $(SVN_INFO) | grep '^URL: ' | cut -d: -f2- | cut -b2-)
+
+else # SVN
+GIT_REV := $(shell cd $(srctree)/$(src); git describe --always 2>/dev/null)
+ifneq ($(GIT_REV),)
+# Git detected
+DRIVER_REV := $(MALI_RELEASE_NAME)-$(GIT_REV)
+CHANGE_DATE := $(shell cd $(srctree)/$(src); git log -1 --format="%ci")
+CHANGED_REVISION := $(GIT_REV)
+REPO_URL := $(shell cd $(srctree)/$(src); git describe --all --always 2>/dev/null)
+
+else # Git
+# No Git or SVN detected
+DRIVER_REV := $(MALI_RELEASE_NAME)
+CHANGE_DATE := $(MALI_RELEASE_NAME)
+CHANGED_REVISION := $(MALI_RELEASE_NAME)
+endif
+endif
+
+ccflags-y += -DSVN_REV_STRING=\"$(DRIVER_REV)\"
+
+VERSION_STRINGS :=
+VERSION_STRINGS += API_VERSION=$(shell cd $(srctree)/$(src); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)include/linux/mali/mali_utgard_uk_types.h | cut -d' ' -f 3 )
+VERSION_STRINGS += REPO_URL=$(REPO_URL)
+VERSION_STRINGS += REVISION=$(DRIVER_REV)
+VERSION_STRINGS += CHANGED_REVISION=$(CHANGED_REVISION)
+VERSION_STRINGS += CHANGE_DATE=$(CHANGE_DATE)
+VERSION_STRINGS += BUILD_DATE=$(shell date)
+ifdef CONFIG_MALI400_DEBUG
+VERSION_STRINGS += BUILD=debug
+else
+VERSION_STRINGS += BUILD=release
+endif
+VERSION_STRINGS += TARGET_PLATFORM=$(TARGET_PLATFORM)
+VERSION_STRINGS += MALI_PLATFORM=$(MALI_PLATFORM)
+VERSION_STRINGS += KDIR=$(KDIR)
+VERSION_STRINGS += OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
+VERSION_STRINGS += USING_UMP=$(CONFIG_MALI400_UMP)
+VERSION_STRINGS += USING_PROFILING=$(CONFIG_MALI400_PROFILING)
+VERSION_STRINGS += USING_INTERNAL_PROFILING=$(CONFIG_MALI400_INTERNAL_PROFILING)
+VERSION_STRINGS += USING_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
+VERSION_STRINGS += MALI_UPPER_HALF_SCHEDULING=$(MALI_UPPER_HALF_SCHEDULING)
+
+# Create file with Mali driver configuration
+$(srctree)/$(src)/__malidrv_build_info.c:
+ @echo 'const char *__malidrv_build_info(void) { return "malidrv: $(VERSION_STRINGS)";}' > $(srctree)/$(src)/__malidrv_build_info.c
diff --git a/drivers/gpu/mali400/r3p2/mali/Kconfig b/drivers/gpu/mali400/r3p2/mali/Kconfig
new file mode 100644
index 0000000..14af54a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/Kconfig
@@ -0,0 +1,67 @@
+config MALI400_DEBUG
+ bool "Enable debug in Mali driver"
+ depends on MALI400
+ ---help---
+ This enabled extra debug checks and messages in the Mali driver.
+
+config MALI400_PROFILING
+ bool "Enable Mali profiling"
+ depends on MALI400
+ select TRACEPOINTS
+ default n
+ ---help---
+ This enables gator profiling of Mali GPU events.
+
+config MALI400_INTERNAL_PROFILING
+ bool "Enable internal Mali profiling API"
+ depends on MALI400_PROFILING
+ default n
+ ---help---
+ This enables the internal legacy Mali profiling API.
+
+if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
+config MALI_DVFS
+ bool "Enable mali DVFS"
+ depends on MALI400 && PM
+ default y
+ ---help---
+ This enables Mali driver DVFS.
+endif
+
+if SOC_EXYNOS3470
+config MALI_DVFS
+ bool "Enable mali DVFS"
+ depends on MALI400 && PM_DEVFREQ
+ default y
+ ---help---
+ This enables Mali driver DVFS.
+endif
+
+if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
+config MALI400_UMP
+ bool "Enable UMP support"
+ depends on MALI400
+ default y
+ ---help---
+ This enables support for the UMP memory sharing API in the Mali driver.
+endif
+
+config MALI_DMA_BUF_MAP_ON_ATTACH
+ bool "Map dma-buf attachments on attach"
+ depends on MALI400 && DMA_SHARED_BUFFER
+ default y
+ ---help---
+ This makes the Mali driver map dma-buf attachments after doing
+ attach. If this is not set the dma-buf attachments will be mapped for
+ every time the GPU need to access the buffer.
+
+ Mapping for each access can cause lower performance.
+
+config MALI_SHARED_INTERRUPTS
+ bool "Support for shared interrupts"
+ depends on MALI400
+ default n
+ ---help---
+ Adds functionality required to properly support shared interrupts. Without this support,
+ the device driver will fail during insmod if it detects shared interrupts. Works even if
+ the GPU is not using shared interrupts, but can cause lower performance.
diff --git a/drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION b/drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION
new file mode 100644
index 0000000..4b099b7
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/MALI_CONFIGURATION
@@ -0,0 +1,24 @@
+# Location of default kernels
+KDIR-odroida:=/projects/pr297/linux/odroid-a/current/linux
+KDIR-odroidpc:=/projects/pr297/linux/odroid-pc/current/linux
+KDIR-odroidq:=/projects/pr297/linux/odroid-q/current/linux
+KDIR-orion:=/projects/pr297/linux/orion/current/linux
+KDIR-pegasus:=/projects/pr297/linux/pegasus-smdk/current/linux
+KDIR-tcc8900:=/projects/pr297/linux/tcc8900/current/linux
+KDIR-pb11mp:=/projects/pr297/linux/pb11mp/current/linux
+KDIR-vea9:=/projects/pr297/linux/vea9/current/linux
+KDIR-snowball:=/no/default/kernel/yet
+
+# Name of platform directory with platform specific code (should be built into kernel on a real system)
+MALI_PLATFORM-odroida=exynos4
+MALI_PLATFORM-odroidpc=exynos4
+MALI_PLATFORM-odroidq=exynos4
+MALI_PLATFORM-orion=exynos4
+MALI_PLATFORM-pegasus=exynos4
+# MALI_SEC
+MALI_PLATFORM-pegasus-m400=pegasus-m400
+MALI_PLATFORM-exynos4270=exynos4270
+MALI_PLATFORM-tcc8900=tcc8900
+MALI_PLATFORM-pb11mp=arm
+MALI_PLATFORM-vea9=arm
+MALI_PLATFORM-snowball=ux500
diff --git a/drivers/gpu/mali400/r3p2/mali/Makefile b/drivers/gpu/mali400/r3p2/mali/Makefile
new file mode 100644
index 0000000..b487011
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/Makefile
@@ -0,0 +1,138 @@
+#
+# Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+USE_UMPV2=0
+USING_PROFILING ?= 1
+USING_INTERNAL_PROFILING ?= 0
+MALI_DMA_BUF_MAP_ON_ATTACH ?= 1
+
+# The Makefile sets up "arch" based on the CONFIG, creates the version info
+# string and the __malidrv_build_info.c file, and then call the Linux build
+# system to actually build the driver. After that point the Kbuild file takes
+# over.
+
+# set up defaults if not defined by the user
+ARCH ?= arm
+
+OSKOS=linux
+FILES_PREFIX=
+
+check_cc2 = \
+ $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
+ then \
+ echo "$(2)"; \
+ else \
+ echo "$(3)"; \
+ fi ;)
+
+# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak
+-include ../../../arm_internal.mak
+
+# Give warning of old config parameters are used
+ifneq ($(CONFIG),)
+$(warning "You have specified the CONFIG variable which is no longer in used. Use TARGET_PLATFORM instead.")
+endif
+
+ifneq ($(CPU),)
+$(warning "You have specified the CPU variable which is no longer in used. Use TARGET_PLATFORM instead.")
+endif
+
+# Include the mapping between TARGET_PLATFORM and KDIR + MALI_PLATFORM
+-include MALI_CONFIGURATION
+export KDIR ?= $(KDIR-$(TARGET_PLATFORM))
+export MALI_PLATFORM ?= $(MALI_PLATFORM-$(TARGET_PLATFORM))
+
+ifneq ($(TARGET_PLATFORM),)
+ifeq ($(MALI_PLATFORM),)
+$(error "Invalid TARGET_PLATFORM: $(TARGET_PLATFORM)")
+endif
+endif
+
+# validate lookup result
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(TARGET_PLATFORM))
+endif
+
+
+ifeq ($(USING_UMP),1)
+export CONFIG_MALI400_UMP=y
+export EXTRA_DEFINES += -DCONFIG_MALI400_UMP=1
+ifeq ($(USE_UMPV2),1)
+UMP_SYMVERS_FILE ?= ../umpv2/Module.symvers
+else
+UMP_SYMVERS_FILE ?= ../ump/Module.symvers
+endif
+KBUILD_EXTRA_SYMBOLS = $(realpath $(UMP_SYMVERS_FILE))
+$(warning $(KBUILD_EXTRA_SYMBOLS))
+endif
+
+# Define host system directory
+KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
+
+include $(KDIR)/.config
+
+ifeq ($(ARCH), arm)
+# when compiling for ARM we're cross compiling
+export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
+endif
+
+# report detected/selected settings
+ifdef ARM_INTERNAL_BUILD
+$(warning TARGET_PLATFORM $(TARGET_PLATFORM))
+$(warning KDIR $(KDIR))
+$(warning MALI_PLATFORM $(MALI_PLATFORM))
+endif
+
+# Set up build config
+export CONFIG_MALI400=m
+
+ifneq ($(MALI_PLATFORM),)
+export EXTRA_DEFINES += -DMALI_FAKE_PLATFORM_DEVICE=1
+export MALI_PLATFORM_FILES = $(wildcard platform/$(MALI_PLATFORM)/*.c)
+endif
+
+ifeq ($(USING_PROFILING),1)
+ifeq ($(CONFIG_TRACEPOINTS),)
+$(warning CONFIG_TRACEPOINTS reqired for profiling)
+else
+export CONFIG_MALI400_PROFILING=y
+export EXTRA_DEFINES += -DCONFIG_MALI400_PROFILING=1
+ifeq ($(USING_INTERNAL_PROFILING),1)
+export CONFIG_MALI400_INTERNAL_PROFILING=y
+export EXTRA_DEFINES += -DCONFIG_MALI400_INTERNAL_PROFILING=1
+endif
+endif
+endif
+
+ifeq ($(MALI_DMA_BUF_MAP_ON_ATTACH),1)
+export CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH=y
+export EXTRA_DEFINES += -DCONFIG_MALI_DMA_BUF_MAP_ON_ATTACH
+endif
+
+ifeq ($(MALI_SHARED_INTERRUPTS),1)
+export CONFIG_MALI_SHARED_INTERRUPTS=y
+export EXTRA_DEFINES += -DCONFIG_MALI_SHARED_INTERRUPTS
+endif
+
+ifneq ($(BUILD),release)
+export CONFIG_MALI400_DEBUG=y
+endif
+
+all: $(UMP_SYMVERS_FILE)
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules
+ @rm $(FILES_PREFIX)__malidrv_build_info.c $(FILES_PREFIX)__malidrv_build_info.o
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+
+kernelrelease:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease
+
+export CONFIG KBUILD_EXTRA_SYMBOLS
diff --git a/drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c b/drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c
new file mode 100644
index 0000000..af5e808
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/__malidrv_build_info.c
@@ -0,0 +1 @@
+const char *__malidrv_build_info(void) { return "malidrv: API_VERSION=23 REPO_URL=heads/master REVISION=r3p2-01rel3-137c649 CHANGED_REVISION=137c649 CHANGE_DATE=2013-08-22 17:45:49 +0900 BUILD_DATE=Fri Aug 23 20:48:48 KST 2013 BUILD=release TARGET_PLATFORM=pegasus-m400 MALI_PLATFORM=pegasus-m400 KDIR= OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=16 USING_UMP=y USING_PROFILING= USING_INTERNAL_PROFILING= USING_GPU_UTILIZATION=1 MALI_UPPER_HALF_SCHEDULING=1";}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c
new file mode 100644
index 0000000..3651ce5
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.c
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "mali_kernel_common.h"
+#include "mali_kernel_memory_engine.h"
+#include "mali_block_allocator.h"
+#include "mali_osk.h"
+
+#define MALI_BLOCK_SIZE (256UL * 1024UL) /* 256 kB, remember to keep the ()s */
+
+typedef struct block_info
+{
+ struct block_info * next;
+} block_info;
+
+/* The structure used as the handle produced by block_allocator_allocate,
+ * and removed by block_allocator_release */
+typedef struct block_allocator_allocation
+{
+ /* The list will be released in reverse order */
+ block_info *last_allocated;
+ mali_allocation_engine * engine;
+ mali_memory_allocation * descriptor;
+ u32 start_offset;
+ u32 mapping_length;
+} block_allocator_allocation;
+
+
+typedef struct block_allocator
+{
+ _mali_osk_lock_t *mutex;
+ block_info * all_blocks;
+ block_info * first_free;
+ u32 base;
+ u32 cpu_usage_adjust;
+ u32 num_blocks;
+} block_allocator;
+
+MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block);
+static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
+static void block_allocator_release(void * ctx, void * handle);
+static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block);
+static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block );
+static void block_allocator_destroy(mali_physical_memory_allocator * allocator);
+static u32 block_allocator_stat(mali_physical_memory_allocator * allocator);
+
+mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name)
+{
+ mali_physical_memory_allocator * allocator;
+ block_allocator * info;
+ u32 usable_size;
+ u32 num_blocks;
+
+ usable_size = size & ~(MALI_BLOCK_SIZE - 1);
+ MALI_DEBUG_PRINT(3, ("Mali block allocator create for region starting at 0x%08X length 0x%08X\n", base_address, size));
+ MALI_DEBUG_PRINT(4, ("%d usable bytes\n", usable_size));
+ num_blocks = usable_size / MALI_BLOCK_SIZE;
+ MALI_DEBUG_PRINT(4, ("which becomes %d blocks\n", num_blocks));
+
+ if (usable_size == 0)
+ {
+ MALI_DEBUG_PRINT(1, ("Memory block of size %d is unusable\n", size));
+ return NULL;
+ }
+
+ allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator));
+ if (NULL != allocator)
+ {
+ info = _mali_osk_malloc(sizeof(block_allocator));
+ if (NULL != info)
+ {
+ info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
+ if (NULL != info->mutex)
+ {
+ info->all_blocks = _mali_osk_malloc(sizeof(block_info) * num_blocks);
+ if (NULL != info->all_blocks)
+ {
+ u32 i;
+ info->first_free = NULL;
+ info->num_blocks = num_blocks;
+
+ info->base = base_address;
+ info->cpu_usage_adjust = cpu_usage_adjust;
+
+ for ( i = 0; i < num_blocks; i++)
+ {
+ info->all_blocks[i].next = info->first_free;
+ info->first_free = &info->all_blocks[i];
+ }
+
+ allocator->allocate = block_allocator_allocate;
+ allocator->allocate_page_table_block = block_allocator_allocate_page_table_block;
+ allocator->destroy = block_allocator_destroy;
+ allocator->stat = block_allocator_stat;
+ allocator->ctx = info;
+ allocator->name = name;
+
+ return allocator;
+ }
+ _mali_osk_lock_term(info->mutex);
+ }
+ _mali_osk_free(info);
+ }
+ _mali_osk_free(allocator);
+ }
+
+ return NULL;
+}
+
+static void block_allocator_destroy(mali_physical_memory_allocator * allocator)
+{
+ block_allocator * info;
+ MALI_DEBUG_ASSERT_POINTER(allocator);
+ MALI_DEBUG_ASSERT_POINTER(allocator->ctx);
+ info = (block_allocator*)allocator->ctx;
+
+ _mali_osk_free(info->all_blocks);
+ _mali_osk_lock_term(info->mutex);
+ _mali_osk_free(info);
+ _mali_osk_free(allocator);
+}
+
+MALI_STATIC_INLINE u32 get_phys(block_allocator * info, block_info * block)
+{
+ return info->base + ((block - info->all_blocks) * MALI_BLOCK_SIZE);
+}
+
+static mali_physical_memory_allocation_result block_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
+{
+ block_allocator * info;
+ u32 left;
+ block_info * last_allocated = NULL;
+ mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE;
+ block_allocator_allocation *ret_allocation;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(offset);
+ MALI_DEBUG_ASSERT_POINTER(alloc_info);
+
+ info = (block_allocator*)ctx;
+ left = descriptor->size - *offset;
+ MALI_DEBUG_ASSERT(0 != left);
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+
+ ret_allocation = _mali_osk_malloc( sizeof(block_allocator_allocation) );
+
+ if ( NULL == ret_allocation )
+ {
+ /* Failure; try another allocator by returning MALI_MEM_ALLOC_NONE */
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+ return result;
+ }
+
+ ret_allocation->start_offset = *offset;
+ ret_allocation->mapping_length = 0;
+
+ while ((left > 0) && (info->first_free))
+ {
+ block_info * block;
+ u32 phys_addr;
+ u32 padding;
+ u32 current_mapping_size;
+
+ block = info->first_free;
+ info->first_free = info->first_free->next;
+ block->next = last_allocated;
+ last_allocated = block;
+
+ phys_addr = get_phys(info, block);
+
+ padding = *offset & (MALI_BLOCK_SIZE-1);
+
+ if (MALI_BLOCK_SIZE - padding < left)
+ {
+ current_mapping_size = MALI_BLOCK_SIZE - padding;
+ }
+ else
+ {
+ current_mapping_size = left;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, phys_addr + padding, info->cpu_usage_adjust, current_mapping_size))
+ {
+ MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n"));
+ result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->start_offset, ret_allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0);
+
+ /* release all memory back to the pool */
+ while (last_allocated)
+ {
+ /* This relinks every block we've just allocated back into the free-list */
+ block = last_allocated->next;
+ last_allocated->next = info->first_free;
+ info->first_free = last_allocated;
+ last_allocated = block;
+ }
+
+ break;
+ }
+
+ *offset += current_mapping_size;
+ left -= current_mapping_size;
+ ret_allocation->mapping_length += current_mapping_size;
+ }
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+
+ if (last_allocated)
+ {
+ if (left) result = MALI_MEM_ALLOC_PARTIAL;
+ else result = MALI_MEM_ALLOC_FINISHED;
+
+ /* Record all the information about this allocation */
+ ret_allocation->last_allocated = last_allocated;
+ ret_allocation->engine = engine;
+ ret_allocation->descriptor = descriptor;
+
+ alloc_info->ctx = info;
+ alloc_info->handle = ret_allocation;
+ alloc_info->release = block_allocator_release;
+ }
+ else
+ {
+ /* Free the allocation information - nothing to be passed back */
+ _mali_osk_free( ret_allocation );
+ }
+
+ return result;
+}
+
+static void block_allocator_release(void * ctx, void * handle)
+{
+ block_allocator * info;
+ block_info * block, * next;
+ block_allocator_allocation *allocation;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(handle);
+
+ info = (block_allocator*)ctx;
+ allocation = (block_allocator_allocation*)handle;
+ block = allocation->last_allocated;
+
+ MALI_DEBUG_ASSERT_POINTER(block);
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
+ {
+ MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
+ return;
+ }
+
+ /* unmap */
+ mali_allocation_engine_unmap_physical(allocation->engine, allocation->descriptor, allocation->start_offset, allocation->mapping_length, (_mali_osk_mem_mapregion_flags_t)0);
+
+ while (block)
+ {
+ MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
+
+ next = block->next;
+
+ /* relink into free-list */
+ block->next = info->first_free;
+ info->first_free = block;
+
+ /* advance the loop */
+ block = next;
+ }
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_free( allocation );
+}
+
+
+static mali_physical_memory_allocation_result block_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
+{
+ block_allocator * info;
+ mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(block);
+ info = (block_allocator*)ctx;
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+
+ if (NULL != info->first_free)
+ {
+ void * virt;
+ u32 phys;
+ u32 size;
+ block_info * alloc;
+ alloc = info->first_free;
+
+ phys = get_phys(info, alloc); /* Does not modify info or alloc */
+ size = MALI_BLOCK_SIZE; /* Must be multiple of MALI_MMU_PAGE_SIZE */
+ virt = _mali_osk_mem_mapioregion( phys, size, "Mali block allocator page tables" );
+
+ /* Failure of _mali_osk_mem_mapioregion will result in MALI_MEM_ALLOC_INTERNAL_FAILURE,
+ * because it's unlikely another allocator will be able to map in. */
+
+ if ( NULL != virt )
+ {
+ block->ctx = info; /* same as incoming ctx */
+ block->handle = alloc;
+ block->phys_base = phys;
+ block->size = size;
+ block->release = block_allocator_release_page_table_block;
+ block->mapping = virt;
+
+ info->first_free = alloc->next;
+
+ alloc->next = NULL; /* Could potentially link many blocks together instead */
+
+ _mali_osk_memset(block->mapping, 0, size);
+
+ result = MALI_MEM_ALLOC_FINISHED;
+ }
+ }
+ else result = MALI_MEM_ALLOC_NONE;
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+
+ return result;
+}
+
+
+static void block_allocator_release_page_table_block( mali_page_table_block *page_table_block )
+{
+ block_allocator * info;
+ block_info * block, * next;
+
+ MALI_DEBUG_ASSERT_POINTER( page_table_block );
+
+ info = (block_allocator*)page_table_block->ctx;
+ block = (block_info*)page_table_block->handle;
+
+ MALI_DEBUG_ASSERT_POINTER(info);
+ MALI_DEBUG_ASSERT_POINTER(block);
+
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
+ {
+ MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
+ return;
+ }
+
+ /* Unmap all the physical memory at once */
+ _mali_osk_mem_unmapioregion( page_table_block->phys_base, page_table_block->size, page_table_block->mapping );
+
+ /** @note This loop handles the case where more than one block_info was linked.
+ * Probably unnecessary for page table block releasing. */
+ while (block)
+ {
+ next = block->next;
+
+ MALI_DEBUG_ASSERT(!((block < info->all_blocks) || (block > (info->all_blocks + info->num_blocks))));
+
+ block->next = info->first_free;
+ info->first_free = block;
+
+ block = next;
+ }
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+}
+
+static u32 block_allocator_stat(mali_physical_memory_allocator * allocator)
+{
+ block_allocator * info;
+ block_info *block;
+ u32 free_blocks = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(allocator);
+
+ info = (block_allocator*)allocator->ctx;
+ block = info->first_free;
+
+ while(block)
+ {
+ free_blocks++;
+ block = block->next;
+ }
+ return (info->num_blocks - free_blocks) * MALI_BLOCK_SIZE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.h b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.h
new file mode 100644
index 0000000..d3f0f9b
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_block_allocator.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_BLOCK_ALLOCATOR_H__
+#define __MALI_BLOCK_ALLOCATOR_H__
+
+#include "mali_kernel_memory_engine.h"
+
+mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u32 cpu_usage_adjust, u32 size, const char *name);
+
+#endif /* __MALI_BLOCK_ALLOCATOR_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c
new file mode 100644
index 0000000..8b05496
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_broadcast.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+
+static const int bcast_unit_reg_size = 0x1000;
+static const int bcast_unit_addr_broadcast_mask = 0x0;
+static const int bcast_unit_addr_irq_override_mask = 0x4;
+
+struct mali_bcast_unit
+{
+ struct mali_hw_core hw_core;
+ u32 current_mask;
+};
+
+struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource)
+{
+ struct mali_bcast_unit *bcast_unit = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(resource);
+ MALI_DEBUG_PRINT(2, ("Mali Broadcast unit: Creating Mali Broadcast unit: %s\n", resource->description));
+
+ bcast_unit = _mali_osk_malloc(sizeof(struct mali_bcast_unit));
+ if (NULL == bcast_unit)
+ {
+ MALI_PRINT_ERROR(("Mali Broadcast unit: Failed to allocate memory for Broadcast unit\n"));
+ return NULL;
+ }
+
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&bcast_unit->hw_core, resource, bcast_unit_reg_size))
+ {
+ bcast_unit->current_mask = 0;
+ mali_bcast_reset(bcast_unit);
+
+ return bcast_unit;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali Broadcast unit: Failed map broadcast unit\n"));
+ }
+
+ _mali_osk_free(bcast_unit);
+
+ return NULL;
+}
+
+void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit)
+{
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+
+ mali_hw_core_delete(&bcast_unit->hw_core);
+ _mali_osk_free(bcast_unit);
+}
+
+void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group)
+{
+ u32 bcast_id;
+ u32 broadcast_mask;
+
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ bcast_id = mali_pp_core_get_bcast_id(mali_group_get_pp_core(group));
+
+ broadcast_mask = bcast_unit->current_mask;
+
+ broadcast_mask |= (bcast_id); /* add PP core to broadcast */
+ broadcast_mask |= (bcast_id << 16); /* add MMU to broadcast */
+
+ /* store mask so we can restore on reset */
+ bcast_unit->current_mask = broadcast_mask;
+}
+
+void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group)
+{
+ u32 bcast_id;
+ u32 broadcast_mask;
+
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ bcast_id = mali_pp_core_get_bcast_id(mali_group_get_pp_core(group));
+
+ broadcast_mask = bcast_unit->current_mask;
+
+ broadcast_mask &= ~((bcast_id << 16) | bcast_id);
+
+ /* store mask so we can restore on reset */
+ bcast_unit->current_mask = broadcast_mask;
+}
+
+void mali_bcast_reset(struct mali_bcast_unit *bcast_unit)
+{
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+
+ /* set broadcast mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_broadcast_mask,
+ bcast_unit->current_mask);
+
+ /* set IRQ override mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_irq_override_mask,
+ bcast_unit->current_mask & 0xFF);
+}
+
+void mali_bcast_disable(struct mali_bcast_unit *bcast_unit)
+{
+ MALI_DEBUG_ASSERT_POINTER(bcast_unit);
+
+ /* set broadcast mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_broadcast_mask,
+ 0x0);
+
+ /* set IRQ override mask */
+ mali_hw_core_register_write(&bcast_unit->hw_core,
+ bcast_unit_addr_irq_override_mask,
+ 0x0);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h
new file mode 100644
index 0000000..df5f2f9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_broadcast.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/*
+ * Interface for the broadcast unit on Mali-450.
+ *
+ * - Represents up to 8 × (MMU + PP) pairs.
+ * - Supports dynamically changing which (MMU + PP) pairs receive the broadcast by
+ * setting a mask.
+ */
+
+#include "mali_hw_core.h"
+#include "mali_group.h"
+
+struct mali_bcast_unit;
+
+struct mali_bcast_unit *mali_bcast_unit_create(const _mali_osk_resource_t *resource);
+void mali_bcast_unit_delete(struct mali_bcast_unit *bcast_unit);
+
+/* Add a group to the list of (MMU + PP) pairs broadcasts go out to. */
+void mali_bcast_add_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group);
+
+/* Remove a group to the list of (MMU + PP) pairs broadcasts go out to. */
+void mali_bcast_remove_group(struct mali_bcast_unit *bcast_unit, struct mali_group *group);
+
+/* Re-set cached mask. This needs to be called after having been suspended. */
+void mali_bcast_reset(struct mali_bcast_unit *bcast_unit);
+
+/**
+ * Disable broadcast unit
+ *
+ * mali_bcast_enable must be called to re-enable the unit. Cores may not be
+ * added or removed when the unit is disabled.
+ */
+void mali_bcast_disable(struct mali_bcast_unit *bcast_unit);
+
+/**
+ * Re-enable broadcast unit
+ *
+ * This resets the masks to include the cores present when mali_bcast_disable was called.
+ */
+MALI_STATIC_INLINE void mali_bcast_enable(struct mali_bcast_unit *bcast_unit)
+{
+ mali_bcast_reset(bcast_unit);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c
new file mode 100644
index 0000000..0181663
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_dlbu.h"
+#include "mali_memory.h"
+#include "mali_pp.h"
+#include "mali_group.h"
+#include "mali_osk.h"
+#include "mali_hw_core.h"
+
+/**
+ * Size of DLBU registers in bytes
+ */
+#define MALI_DLBU_SIZE 0x400
+
+u32 mali_dlbu_phys_addr = 0;
+static mali_io_address mali_dlbu_cpu_addr = 0;
+
+/**
+ * DLBU register numbers
+ * Used in the register read/write routines.
+ * See the hardware documentation for more information about each register
+ */
+typedef enum mali_dlbu_register {
+ MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR = 0x0000, /**< Master tile list physical base address;
+ 31:12 Physical address to the page used for the DLBU
+ 0 DLBU enable - set this bit to 1 enables the AXI bus
+ between PPs and L2s, setting to 0 disables the router and
+ no further transactions are sent to DLBU */
+ MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR = 0x0004, /**< Master tile list virtual base address;
+ 31:12 Virtual address to the page used for the DLBU */
+ MALI_DLBU_REGISTER_TLLIST_VBASEADDR = 0x0008, /**< Tile list virtual base address;
+ 31:12 Virtual address to the tile list. This address is used when
+ calculating the call address sent to PP.*/
+ MALI_DLBU_REGISTER_FB_DIM = 0x000C, /**< Framebuffer dimension;
+ 23:16 Number of tiles in Y direction-1
+ 7:0 Number of tiles in X direction-1 */
+ MALI_DLBU_REGISTER_TLLIST_CONF = 0x0010, /**< Tile list configuration;
+ 29:28 select the size of each allocated block: 0=128 bytes, 1=256, 2=512, 3=1024
+ 21:16 2^n number of tiles to be binned to one tile list in Y direction
+ 5:0 2^n number of tiles to be binned to one tile list in X direction */
+ MALI_DLBU_REGISTER_START_TILE_POS = 0x0014, /**< Start tile positions;
+ 31:24 start position in Y direction for group 1
+ 23:16 start position in X direction for group 1
+ 15:8 start position in Y direction for group 0
+ 7:0 start position in X direction for group 0 */
+ MALI_DLBU_REGISTER_PP_ENABLE_MASK = 0x0018, /**< PP enable mask;
+ 7 enable PP7 for load balancing
+ 6 enable PP6 for load balancing
+ 5 enable PP5 for load balancing
+ 4 enable PP4 for load balancing
+ 3 enable PP3 for load balancing
+ 2 enable PP2 for load balancing
+ 1 enable PP1 for load balancing
+ 0 enable PP0 for load balancing */
+} mali_dlbu_register;
+
+typedef enum
+{
+ PP0ENABLE = 0,
+ PP1ENABLE,
+ PP2ENABLE,
+ PP3ENABLE,
+ PP4ENABLE,
+ PP5ENABLE,
+ PP6ENABLE,
+ PP7ENABLE
+} mali_dlbu_pp_enable;
+
+struct mali_dlbu_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ u32 pp_cores_mask; /**< This is a mask for the PP cores whose operation will be controlled by LBU
+ see MALI_DLBU_REGISTER_PP_ENABLE_MASK register */
+};
+
+_mali_osk_errcode_t mali_dlbu_initialize(void)
+{
+
+ MALI_DEBUG_PRINT(2, ("Mali DLBU: Initializing\n"));
+
+ if (_MALI_OSK_ERR_OK == mali_mmu_get_table_page(&mali_dlbu_phys_addr, &mali_dlbu_cpu_addr))
+ {
+ MALI_SUCCESS;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_dlbu_terminate(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali DLBU: terminating\n"));
+
+ mali_mmu_release_table_page(mali_dlbu_phys_addr);
+}
+
+struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource)
+{
+ struct mali_dlbu_core *core = NULL;
+
+ MALI_DEBUG_PRINT(2, ("Mali DLBU: Creating Mali dynamic load balancing unit: %s\n", resource->description));
+
+ core = _mali_osk_malloc(sizeof(struct mali_dlbu_core));
+ if (NULL != core)
+ {
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI_DLBU_SIZE))
+ {
+ core->pp_cores_mask = 0;
+ if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core))
+ {
+ return core;
+ }
+ MALI_PRINT_ERROR(("Failed to reset DLBU %s\n", core->hw_core.description));
+ mali_hw_core_delete(&core->hw_core);
+ }
+
+ _mali_osk_free(core);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali DLBU: Failed to allocate memory for DLBU core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_dlbu_delete(struct mali_dlbu_core *dlbu)
+{
+ MALI_DEBUG_ASSERT_POINTER(dlbu);
+
+ mali_dlbu_reset(dlbu);
+ mali_hw_core_delete(&dlbu->hw_core);
+ _mali_osk_free(dlbu);
+}
+
+_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu)
+{
+ u32 dlbu_registers[7];
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ MALI_DEBUG_ASSERT_POINTER(dlbu);
+
+ MALI_DEBUG_PRINT(4, ("Mali DLBU: mali_dlbu_reset: %s\n", dlbu->hw_core.description));
+
+ dlbu_registers[0] = mali_dlbu_phys_addr | 1; /* bit 0 enables the whole core */
+ dlbu_registers[1] = MALI_DLBU_VIRT_ADDR;
+ dlbu_registers[2] = 0;
+ dlbu_registers[3] = 0;
+ dlbu_registers[4] = 0;
+ dlbu_registers[5] = 0;
+ dlbu_registers[6] = dlbu->pp_cores_mask;
+
+ /* write reset values to core registers */
+ mali_hw_core_register_write_array_relaxed(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, dlbu_registers, 7);
+
+ err = _MALI_OSK_ERR_OK;
+
+ return err;
+}
+
+void mali_dlbu_update_mask(struct mali_dlbu_core *dlbu)
+{
+ MALI_DEBUG_ASSERT_POINTER(dlbu);
+
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
+}
+
+void mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
+{
+ struct mali_pp_core *pp_core;
+ u32 bcast_id;
+
+ MALI_DEBUG_ASSERT_POINTER( dlbu );
+ MALI_DEBUG_ASSERT_POINTER( group );
+
+ pp_core = mali_group_get_pp_core(group);
+ bcast_id = mali_pp_core_get_bcast_id(pp_core);
+
+ dlbu->pp_cores_mask |= bcast_id;
+ MALI_DEBUG_PRINT(3, ("Mali DLBU: Adding core[%d] New mask= 0x%02x\n", bcast_id , dlbu->pp_cores_mask));
+}
+
+/* Remove a group from the DLBU */
+void mali_dlbu_remove_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
+{
+ struct mali_pp_core *pp_core;
+ u32 bcast_id;
+
+ MALI_DEBUG_ASSERT_POINTER( dlbu );
+ MALI_DEBUG_ASSERT_POINTER( group );
+
+ pp_core = mali_group_get_pp_core(group);
+ bcast_id = mali_pp_core_get_bcast_id(pp_core);
+
+ dlbu->pp_cores_mask &= ~bcast_id;
+ MALI_DEBUG_PRINT(3, ("Mali DLBU: Removing core[%d] New mask= 0x%02x\n", bcast_id, dlbu->pp_cores_mask));
+}
+
+/* Configure the DLBU for \a job. This needs to be done before the job is started on the groups in the DLBU. */
+void mali_dlbu_config_job(struct mali_dlbu_core *dlbu, struct mali_pp_job *job)
+{
+ u32 *registers;
+ MALI_DEBUG_ASSERT(job);
+ registers = mali_pp_job_get_dlbu_registers(job);
+ MALI_DEBUG_PRINT(4, ("Mali DLBU: Starting job\n"));
+
+ /* Writing 4 registers:
+ * DLBU registers except the first two (written once at DLBU initialisation / reset) and the PP_ENABLE_MASK register */
+ mali_hw_core_register_write_array_relaxed(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, registers, 4);
+
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h
new file mode 100644
index 0000000..b1a59d6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_dlbu.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_DLBU_H__
+#define __MALI_DLBU_H__
+
+#define MALI_DLBU_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */
+
+#include "mali_osk.h"
+
+struct mali_pp_job;
+struct mali_group;
+
+extern u32 mali_dlbu_phys_addr;
+
+struct mali_dlbu_core;
+
+_mali_osk_errcode_t mali_dlbu_initialize(void);
+void mali_dlbu_terminate(void);
+
+struct mali_dlbu_core *mali_dlbu_create(const _mali_osk_resource_t * resource);
+void mali_dlbu_delete(struct mali_dlbu_core *dlbu);
+
+_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu);
+
+void mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
+void mali_dlbu_remove_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
+
+/** @brief Called to update HW after DLBU state changed
+ *
+ * This function must be called after \a mali_dlbu_add_group or \a
+ * mali_dlbu_remove_group to write the updated mask to hardware, unless the
+ * same is accomplished by calling \a mali_dlbu_reset.
+ */
+void mali_dlbu_update_mask(struct mali_dlbu_core *dlbu);
+
+void mali_dlbu_config_job(struct mali_dlbu_core *dlbu, struct mali_pp_job *job);
+
+#endif /* __MALI_DLBU_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp.c b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.c
new file mode 100644
index 0000000..c2b01f9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_gp.h"
+#include "mali_hw_core.h"
+#include "mali_group.h"
+#include "mali_osk.h"
+#include "regs/mali_gp_regs.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+static struct mali_gp_core *mali_global_gp_core = NULL;
+
+/* Interrupt handlers */
+static void mali_gp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data);
+
+struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group)
+{
+ struct mali_gp_core* core = NULL;
+
+ MALI_DEBUG_ASSERT(NULL == mali_global_gp_core);
+ MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description));
+
+ core = _mali_osk_malloc(sizeof(struct mali_gp_core));
+ if (NULL != core)
+ {
+ core->counter_src0_used = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src1_used = MALI_HW_CORE_NO_COUNTER;
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE))
+ {
+ _mali_osk_errcode_t ret;
+
+ ret = mali_gp_reset(core);
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ ret = mali_group_add_gp_core(group, core);
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ core->irq = _mali_osk_irq_init(resource->irq,
+ mali_group_upper_half_gp,
+ group,
+ mali_gp_irq_probe_trigger,
+ mali_gp_irq_probe_ack,
+ core,
+ "mali_gp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core));
+ mali_global_gp_core = core;
+
+ return core;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
+ }
+ mali_group_remove_gp_core(group);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to add core %s to group\n", core->hw_core.description));
+ }
+ }
+ mali_hw_core_delete(&core->hw_core);
+ }
+
+ _mali_osk_free(core);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_gp_delete(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ _mali_osk_irq_term(core->irq);
+ mali_hw_core_delete(&core->hw_core);
+ mali_global_gp_core = NULL;
+ _mali_osk_free(core);
+}
+
+void mali_gp_stop_bus(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
+}
+
+_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core)
+{
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ /* Send the stop bus command. */
+ mali_gp_stop_bus(core);
+
+ /* Wait for bus to be stopped */
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to stop bus on %s\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_hard_reset(struct mali_gp_core *core)
+{
+ const u32 reset_wait_target_register = MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW;
+ const u32 reset_invalid_value = 0xC0FFE000;
+ const u32 reset_check_value = 0xC01A0000;
+ const u32 reset_default_value = 0;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(4, ("Mali GP: Hard reset of core %s\n", core->hw_core.description));
+
+ mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_invalid_value);
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_check_value);
+ if (reset_check_value == mali_hw_core_register_read(&core->hw_core, reset_wait_target_register))
+ {
+ break;
+ }
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: The hard reset loop didn't work, unable to recover\n"));
+ }
+
+ mali_hw_core_register_write(&core->hw_core, reset_wait_target_register, reset_default_value); /* set it back to the default */
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
+
+}
+
+void mali_gp_reset_async(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description));
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET);
+
+}
+
+_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core)
+{
+ int i;
+ u32 rawstat = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ rawstat = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
+ if (rawstat & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ }
+
+ if (i == MALI_REG_POLL_COUNT_FAST)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, rawstat: 0x%08x\n",
+ core->hw_core.description, rawstat));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core)
+{
+ mali_gp_reset_async(core);
+ return mali_gp_reset_wait(core);
+}
+
+void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job)
+{
+ u32 startcmd = 0;
+ u32 *frame_registers = mali_gp_job_get_frame_registers(job);
+
+ core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job);
+ core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ if (mali_gp_job_has_vs_job(job))
+ {
+ startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
+ }
+
+ if (mali_gp_job_has_plbu_job(job))
+ {
+ startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
+ }
+
+ MALI_DEBUG_ASSERT(0 != startcmd);
+
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR, frame_registers, MALIGP2_NUM_REGS_FRAME);
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
+ }
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALIGP2_REG_VAL_PERF_CNT_ENABLE);
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali GP: Starting job (0x%08x) on core %s with command 0x%08X\n", job, core->hw_core.description, startcmd));
+
+ /* Barrier to make sure the previous register write is finished */
+ _mali_osk_write_mem_barrier();
+
+ /* This is the command that starts the core. */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, startcmd);
+
+ /* Barrier to make sure the previous register write is finished */
+ _mali_osk_write_mem_barrier();
+}
+
+void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr)
+{
+ u32 irq_readout;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT);
+
+ if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED); /* re-enable interrupts */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, start_addr);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, end_addr);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP: Resuming job\n"));
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
+ _mali_osk_write_mem_barrier();
+ }
+ /*
+ * else: core has been reset between PLBU_OUT_OF_MEM interrupt and this new heap response.
+ * A timeout or a page fault on Mali-200 PP core can cause this behaviour.
+ */
+}
+
+u32 mali_gp_core_get_version(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_VERSION);
+}
+
+struct mali_gp_core *mali_gp_get_global_gp_core(void)
+{
+ return mali_global_gp_core;
+}
+
+/* ------------- interrupt handling below ------------------ */
+static void mali_gp_irq_probe_trigger(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG);
+ _mali_osk_mem_barrier();
+}
+
+static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+ u32 irq_readout;
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
+ if (MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG);
+ _mali_osk_mem_barrier();
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+/* ------ local helper functions below --------- */
+#if MALI_STATE_TRACKING
+u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "\tGP: %s\n", core->hw_core.description);
+
+ return n;
+}
+#endif
+
+void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job, mali_bool suspend)
+{
+ u32 val0 = 0;
+ u32 val1 = 0;
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ val0 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
+ mali_gp_job_set_perf_counter_value0(job, val0);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_0_C0, val0);
+#endif
+
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ val1 = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+ mali_gp_job_set_perf_counter_value1(job, val1);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_0_C1, val1);
+#endif
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp.h b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.h
new file mode 100644
index 0000000..2750c75
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_GP_H__
+#define __MALI_GP_H__
+
+#include "mali_osk.h"
+#include "mali_gp_job.h"
+#include "mali_hw_core.h"
+#include "regs/mali_gp_regs.h"
+
+struct mali_group;
+
+/**
+ * Definition of the GP core struct
+ * Used to track a GP core in the system.
+ */
+struct mali_gp_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */
+ u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */
+};
+
+_mali_osk_errcode_t mali_gp_initialize(void);
+void mali_gp_terminate(void);
+
+struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group);
+void mali_gp_delete(struct mali_gp_core *core);
+
+void mali_gp_stop_bus(struct mali_gp_core *core);
+_mali_osk_errcode_t mali_gp_stop_bus_wait(struct mali_gp_core *core);
+void mali_gp_reset_async(struct mali_gp_core *core);
+_mali_osk_errcode_t mali_gp_reset_wait(struct mali_gp_core *core);
+void mali_gp_hard_reset(struct mali_gp_core *core);
+_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core);
+
+void mali_gp_job_start(struct mali_gp_core *core, struct mali_gp_job *job);
+void mali_gp_resume_with_new_heap(struct mali_gp_core *core, u32 start_addr, u32 end_addr);
+
+u32 mali_gp_core_get_version(struct mali_gp_core *core);
+
+struct mali_gp_core *mali_gp_get_global_gp_core(void);
+
+u32 mali_gp_dump_state(struct mali_gp_core *core, char *buf, u32 size);
+
+void mali_gp_update_performance_counters(struct mali_gp_core *core, struct mali_gp_job *job, mali_bool suspend);
+
+/*** Accessor functions ***/
+MALI_STATIC_INLINE const char *mali_gp_get_hw_core_desc(struct mali_gp_core *core)
+{
+ return core->hw_core.description;
+}
+
+/*** Register reading/writing functions ***/
+MALI_STATIC_INLINE u32 mali_gp_get_int_stat(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
+}
+
+MALI_STATIC_INLINE void mali_gp_mask_all_interrupts(struct mali_gp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
+}
+
+MALI_STATIC_INLINE u32 mali_gp_read_rawstat(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_read_core_status(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS);
+}
+
+MALI_STATIC_INLINE void mali_gp_enable_interrupts(struct mali_gp_core *core, u32 irq_exceptions)
+{
+ /* Enable all interrupts, except those specified in irq_exceptions */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK,
+ MALIGP2_REG_VAL_IRQ_MASK_USED & ~irq_exceptions);
+}
+
+MALI_STATIC_INLINE u32 mali_gp_read_plbu_alloc_start_addr(struct mali_gp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR);
+}
+
+#endif /* __MALI_GP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c
new file mode 100644
index 0000000..dae68b1
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_gp_job.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_uk_types.h"
+
+static u32 gp_counter_src0 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
+static u32 gp_counter_src1 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
+
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id)
+{
+ struct mali_gp_job *job;
+ u32 perf_counter_flag;
+
+ job = _mali_osk_malloc(sizeof(struct mali_gp_job));
+ if (NULL != job)
+ {
+ job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
+ if (NULL == job->finished_notification)
+ {
+ _mali_osk_free(job);
+ return NULL;
+ }
+
+ job->oom_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
+ if (NULL == job->oom_notification)
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ _mali_osk_free(job);
+ return NULL;
+ }
+
+ if (0 != copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_gp_start_job_s)))
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ _mali_osk_notification_delete(job->oom_notification);
+ _mali_osk_free(job);
+ return NULL;
+ }
+
+ perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
+
+ /* case when no counters came from user space
+ * so pass the debugfs / DS-5 provided global ones to the job object */
+ if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
+ (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)))
+ {
+ mali_gp_job_set_perf_counter_src0(job, mali_gp_job_get_gp_counter_src0());
+ mali_gp_job_set_perf_counter_src1(job, mali_gp_job_get_gp_counter_src1());
+ }
+
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ job->id = id;
+ job->heap_current_addr = job->uargs.frame_registers[4];
+ job->perf_counter_value0 = 0;
+ job->perf_counter_value1 = 0;
+ job->pid = _mali_osk_get_pid();
+ job->tid = _mali_osk_get_tid();
+
+ return job;
+ }
+
+ return NULL;
+}
+
+void mali_gp_job_delete(struct mali_gp_job *job)
+{
+
+ /* de-allocate the pre-allocated oom notifications */
+ if (NULL != job->oom_notification)
+ {
+ _mali_osk_notification_delete(job->oom_notification);
+ job->oom_notification = NULL;
+ }
+ if (NULL != job->finished_notification)
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ job->finished_notification = NULL;
+ }
+
+ _mali_osk_free(job);
+}
+
+u32 mali_gp_job_get_gp_counter_src0(void)
+{
+ return gp_counter_src0;
+}
+
+mali_bool mali_gp_job_set_gp_counter_src0(u32 counter)
+{
+ gp_counter_src0 = counter;
+
+ return MALI_TRUE;
+}
+
+u32 mali_gp_job_get_gp_counter_src1(void)
+{
+ return gp_counter_src1;
+}
+
+mali_bool mali_gp_job_set_gp_counter_src1(u32 counter)
+{
+ gp_counter_src1 = counter;
+
+ return MALI_TRUE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h
new file mode 100644
index 0000000..e021b9b
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_job.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_GP_JOB_H__
+#define __MALI_GP_JOB_H__
+
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_uk_types.h"
+#include "mali_session.h"
+
+/**
+ * The structure represents a GP job, including all sub-jobs
+ * (This struct unfortunately needs to be public because of how the _mali_osk_list_*
+ * mechanism works)
+ */
+struct mali_gp_job
+{
+ _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */
+ struct mali_session_data *session; /**< Session which submitted this job */
+ _mali_uk_gp_start_job_s uargs; /**< Arguments from user space */
+ u32 id; /**< identifier for this job in kernel space (sequential numbering) */
+ u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */
+ u32 perf_counter_value0; /**< Value of performance counter 0 (to be returned to user space) */
+ u32 perf_counter_value1; /**< Value of performance counter 1 (to be returned to user space) */
+ u32 pid; /**< Process ID of submitting process */
+ u32 tid; /**< Thread ID of submitting thread */
+ _mali_osk_notification_t *finished_notification; /**< Notification sent back to userspace on job complete */
+ _mali_osk_notification_t *oom_notification; /**< Notification sent back to userspace on OOM */
+};
+
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *uargs, u32 id);
+void mali_gp_job_delete(struct mali_gp_job *job);
+
+u32 mali_gp_job_get_gp_counter_src0(void);
+mali_bool mali_gp_job_set_gp_counter_src0(u32 counter);
+u32 mali_gp_job_get_gp_counter_src1(void);
+mali_bool mali_gp_job_set_gp_counter_src1(u32 counter);
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_id(struct mali_gp_job *job)
+{
+ return (NULL == job) ? 0 : job->id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_user_id(struct mali_gp_job *job)
+{
+ return job->uargs.user_job_ptr;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
+{
+ return job->uargs.frame_builder_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
+{
+ return job->uargs.flush_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_pid(struct mali_gp_job *job)
+{
+ return job->pid;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_tid(struct mali_gp_job *job)
+{
+ return job->tid;
+}
+
+MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job)
+{
+ return job->uargs.frame_registers;
+}
+
+MALI_STATIC_INLINE struct mali_session_data *mali_gp_job_get_session(struct mali_gp_job *job)
+{
+ return job->session;
+}
+
+MALI_STATIC_INLINE mali_bool mali_gp_job_has_vs_job(struct mali_gp_job *job)
+{
+ return (job->uargs.frame_registers[0] != job->uargs.frame_registers[1]) ? MALI_TRUE : MALI_FALSE;
+}
+
+MALI_STATIC_INLINE mali_bool mali_gp_job_has_plbu_job(struct mali_gp_job *job)
+{
+ return (job->uargs.frame_registers[2] != job->uargs.frame_registers[3]) ? MALI_TRUE : MALI_FALSE;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_current_heap_addr(struct mali_gp_job *job)
+{
+ return job->heap_current_addr;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_current_heap_addr(struct mali_gp_job *job, u32 heap_addr)
+{
+ job->heap_current_addr = heap_addr;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_flag(struct mali_gp_job *job)
+{
+ return job->uargs.perf_counter_flag;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
+{
+ return job->uargs.perf_counter_src0;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
+{
+ return job->uargs.perf_counter_src1;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value0(struct mali_gp_job *job)
+{
+ return job->perf_counter_value0;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_value1(struct mali_gp_job *job)
+{
+ return job->perf_counter_value1;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src0(struct mali_gp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src0 = src;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_src1(struct mali_gp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src1 = src;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value0(struct mali_gp_job *job, u32 value)
+{
+ job->perf_counter_value0 = value;
+}
+
+MALI_STATIC_INLINE void mali_gp_job_set_perf_counter_value1(struct mali_gp_job *job, u32 value)
+{
+ job->perf_counter_value1 = value;
+}
+
+#endif /* __MALI_GP_JOB_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c
new file mode 100644
index 0000000..ebbc281
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_gp_scheduler.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_scheduler.h"
+#include "mali_gp.h"
+#include "mali_gp_job.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_kernel_utilization.h"
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+#include <linux/sched.h>
+#include <trace/events/gpu.h>
+#endif
+
+enum mali_gp_slot_state
+{
+ MALI_GP_SLOT_STATE_IDLE,
+ MALI_GP_SLOT_STATE_WORKING,
+ MALI_GP_SLOT_STATE_DISABLED,
+};
+
+/* A render slot is an entity which jobs can be scheduled onto */
+struct mali_gp_slot
+{
+ struct mali_group *group;
+ /*
+ * We keep track of the state here as well as in the group object
+ * so we don't need to take the group lock so often (and also avoid clutter with the working lock)
+ */
+ enum mali_gp_slot_state state;
+ u32 returned_cookie;
+};
+
+static u32 gp_version = 0;
+static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */
+static struct mali_gp_slot slot;
+
+/* Variables to allow safe pausing of the scheduler */
+static _mali_osk_wait_queue_t *gp_scheduler_working_wait_queue = NULL;
+static u32 pause_count = 0;
+
+static mali_bool mali_gp_scheduler_is_suspended(void);
+static void mali_gp_scheduler_job_queued(void);
+static void mali_gp_scheduler_job_completed(void);
+
+static _mali_osk_lock_t *gp_scheduler_lock = NULL;
+/* Contains tid of thread that locked the scheduler or 0, if not locked */
+
+_mali_osk_errcode_t mali_gp_scheduler_initialize(void)
+{
+ u32 num_groups;
+ u32 i;
+
+ _MALI_OSK_INIT_LIST_HEAD(&job_queue);
+
+ gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ if (NULL == gp_scheduler_lock)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
+ if (NULL == gp_scheduler_working_wait_queue)
+ {
+ _mali_osk_lock_term(gp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ /* Find all the available GP cores */
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
+ {
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
+ if (NULL != gp_core)
+ {
+ if (0 == gp_version)
+ {
+ /* Retrieve GP version */
+ gp_version = mali_gp_core_get_version(gp_core);
+ }
+ slot.group = group;
+ slot.state = MALI_GP_SLOT_STATE_IDLE;
+ break; /* There is only one GP, no point in looking for more */
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_scheduler_terminate(void)
+{
+ MALI_DEBUG_ASSERT( MALI_GP_SLOT_STATE_IDLE == slot.state
+ || MALI_GP_SLOT_STATE_DISABLED == slot.state);
+ MALI_DEBUG_ASSERT_POINTER(slot.group);
+ mali_group_delete(slot.group);
+
+ _mali_osk_wait_queue_term(gp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(gp_scheduler_lock);
+}
+
+MALI_STATIC_INLINE void mali_gp_scheduler_lock(void)
+{
+ if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
+ {
+ /* Non-interruptable lock failed: this should never happen. */
+ MALI_DEBUG_ASSERT(0);
+ }
+ MALI_DEBUG_PRINT(5, ("Mali GP scheduler: GP scheduler lock taken\n"));
+}
+
+MALI_STATIC_INLINE void mali_gp_scheduler_unlock(void)
+{
+ MALI_DEBUG_PRINT(5, ("Mali GP scheduler: Releasing GP scheduler lock\n"));
+ _mali_osk_lock_signal(gp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+#ifdef DEBUG
+MALI_STATIC_INLINE void mali_gp_scheduler_assert_locked(void)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);
+}
+#define MALI_ASSERT_GP_SCHEDULER_LOCKED() mali_gp_scheduler_assert_locked()
+#else
+#define MALI_ASSERT_GP_SCHEDULER_LOCKED()
+#endif
+
+static void mali_gp_scheduler_schedule(void)
+{
+ struct mali_gp_job *job;
+
+ mali_gp_scheduler_lock();
+
+ if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
+ pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0));
+ mali_gp_scheduler_unlock();
+ return; /* Nothing to do, so early out */
+ }
+
+ /* Get (and remove) next job in queue */
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
+ _mali_osk_list_del(&job->list);
+
+ /* Mark slot as busy */
+ slot.state = MALI_GP_SLOT_STATE_WORKING;
+
+ mali_gp_scheduler_unlock();
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
+
+ mali_group_lock(slot.group);
+ mali_group_start_gp_job(slot.group, job);
+ mali_group_unlock(slot.group);
+}
+
+static void mali_gp_scheduler_schedule_on_group(struct mali_group *group)
+{
+ struct mali_gp_job *job;
+
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);
+
+ if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state || _mali_osk_list_empty(&job_queue))
+ {
+ mali_gp_scheduler_unlock();
+ MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
+ pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0));
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_gp_get_hw_core_desc(group->gp_core), sched_clock(), 0, 0, 0);
+#endif
+ return; /* Nothing to do, so early out */
+ }
+
+ /* Get (and remove) next job in queue */
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
+ _mali_osk_list_del(&job->list);
+
+ /* Mark slot as busy */
+ slot.state = MALI_GP_SLOT_STATE_WORKING;
+
+ mali_gp_scheduler_unlock();
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
+
+ mali_group_start_gp_job(slot.group, job);
+}
+
+static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
+{
+ _mali_uk_gp_job_finished_s *jobres = job->finished_notification->result_buffer;
+ _mali_osk_memset(jobres, 0, sizeof(_mali_uk_gp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
+ jobres->user_job_ptr = mali_gp_job_get_user_id(job);
+ if (MALI_TRUE == success)
+ {
+ jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
+ }
+ else
+ {
+ jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
+ }
+
+ jobres->heap_current_addr = mali_gp_job_get_current_heap_addr(job);
+ jobres->perf_counter0 = mali_gp_job_get_perf_counter_value0(job);
+ jobres->perf_counter1 = mali_gp_job_get_perf_counter_value1(job);
+
+ mali_session_send_notification(mali_gp_job_get_session(job), job->finished_notification);
+ job->finished_notification = NULL;
+
+ mali_gp_job_delete(job);
+}
+
+void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success)
+{
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) completed (%s)\n", mali_gp_job_get_id(job), job, success ? "success" : "failure"));
+
+ mali_gp_scheduler_return_job_to_user(job, success);
+
+ mali_gp_scheduler_lock();
+
+ /* Mark slot as idle again */
+ slot.state = MALI_GP_SLOT_STATE_IDLE;
+
+ /* If paused, then this was the last job, so wake up sleeping workers */
+ if (pause_count > 0)
+ {
+ _mali_osk_wait_queue_wake_up(gp_scheduler_working_wait_queue);
+ }
+
+ mali_gp_scheduler_schedule_on_group(group);
+
+ /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+ mali_gp_scheduler_job_completed();
+}
+
+void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
+{
+ _mali_uk_gp_job_suspended_s * jobres;
+ _mali_osk_notification_t * notification;
+
+ mali_gp_scheduler_lock();
+
+ notification = job->oom_notification;
+ job->oom_notification = NULL;
+ slot.returned_cookie = mali_gp_job_get_id(job);
+
+ jobres = (_mali_uk_gp_job_suspended_s *)notification->result_buffer;
+ jobres->user_job_ptr = mali_gp_job_get_user_id(job);
+ jobres->cookie = mali_gp_job_get_id(job);
+
+ mali_gp_scheduler_unlock();
+
+ jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
+
+ mali_session_send_notification(mali_gp_job_get_session(job), notification);
+
+ /*
+ * If this function failed, then we could return the job to user space right away,
+ * but there is a job timer anyway that will do that eventually.
+ * This is not exactly a common case anyway.
+ */
+}
+
+void mali_gp_scheduler_suspend(void)
+{
+ mali_gp_scheduler_lock();
+ pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
+ mali_gp_scheduler_unlock();
+
+ _mali_osk_wait_queue_wait_event(gp_scheduler_working_wait_queue, mali_gp_scheduler_is_suspended);
+}
+
+void mali_gp_scheduler_resume(void)
+{
+ mali_gp_scheduler_lock();
+ pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
+ mali_gp_scheduler_unlock();
+ if (0 == pause_count)
+ {
+ mali_gp_scheduler_schedule();
+ }
+}
+
+_mali_osk_errcode_t _mali_ukk_gp_start_job(void *ctx, _mali_uk_gp_start_job_s *uargs)
+{
+ struct mali_session_data *session;
+ struct mali_gp_job *job;
+
+ MALI_DEBUG_ASSERT_POINTER(uargs);
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+
+ session = (struct mali_session_data*)ctx;
+
+ job = mali_gp_job_create(session, uargs, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+#if PROFILING_SKIP_PP_AND_GP_JOBS
+#warning GP jobs will not be executed
+ mali_gp_scheduler_return_job_to_user(job, MALI_TRUE);
+ return _MALI_OSK_ERR_OK;
+#endif
+
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_job_enqueue(mali_gp_job_get_tid(job), mali_gp_job_get_id(job), "GP");
+#endif
+
+ mali_gp_scheduler_job_queued();
+
+ mali_gp_scheduler_lock();
+ _mali_osk_list_addtail(&job->list, &job_queue);
+ mali_gp_scheduler_unlock();
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job));
+
+ mali_gp_scheduler_schedule();
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores(_mali_uk_get_gp_number_of_cores_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ args->number_of_cores = 1;
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_gp_core_version(_mali_uk_get_gp_core_version_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ args->version = gp_version;
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_gp_suspend_response(_mali_uk_gp_suspend_response_s *args)
+{
+ struct mali_session_data *session;
+ struct mali_gp_job *resumed_job;
+ _mali_osk_notification_t *new_notification = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ if (NULL == args->ctx)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ session = (struct mali_session_data*)args->ctx;
+ if (NULL == session)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ if (_MALIGP_JOB_RESUME_WITH_NEW_HEAP == args->code)
+ {
+ new_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
+
+ if (NULL == new_notification)
+ {
+ MALI_PRINT_ERROR(("Mali GP scheduler: Failed to allocate notification object. Will abort GP job.\n"));
+ mali_group_lock(slot.group);
+ mali_group_abort_gp_job(slot.group, args->cookie);
+ mali_group_unlock(slot.group);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ mali_group_lock(slot.group);
+
+ if (_MALIGP_JOB_RESUME_WITH_NEW_HEAP == args->code)
+ {
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Resuming job %u with new heap; 0x%08X - 0x%08X\n", args->cookie, args->arguments[0], args->arguments[1]));
+
+ resumed_job = mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]);
+ if (NULL != resumed_job)
+ {
+ resumed_job->oom_notification = new_notification;
+ mali_group_unlock(slot.group);
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ mali_group_unlock(slot.group);
+ _mali_osk_notification_delete(new_notification);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting job %u, no new heap provided\n", args->cookie));
+ mali_group_abort_gp_job(slot.group, args->cookie);
+ mali_group_unlock(slot.group);
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_scheduler_abort_session(struct mali_session_data *session)
+{
+ struct mali_gp_job *job, *tmp;
+
+ mali_gp_scheduler_lock();
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Aborting all jobs from session 0x%08x\n", session));
+
+ /* Check queue for jobs and remove */
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_gp_job, list)
+ {
+ if (mali_gp_job_get_session(job) == session)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Removing GP job 0x%08x from queue\n", job));
+ _mali_osk_list_del(&(job->list));
+ mali_gp_job_delete(job);
+
+ mali_gp_scheduler_job_completed();
+ }
+ }
+
+ mali_gp_scheduler_unlock();
+
+ mali_group_abort_session(slot.group, session);
+}
+
+static mali_bool mali_gp_scheduler_is_suspended(void)
+{
+ mali_bool ret;
+
+ mali_gp_scheduler_lock();
+ ret = pause_count > 0 && slot.state == MALI_GP_SLOT_STATE_IDLE;
+ mali_gp_scheduler_unlock();
+
+ return ret;
+}
+
+
+#if MALI_STATE_TRACKING
+u32 mali_gp_scheduler_dump_state(char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "GP\n");
+ n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
+
+ n += mali_group_dump_state(slot.group, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+
+ return n;
+}
+#endif
+
+void mali_gp_scheduler_reset_all_groups(void)
+{
+ if (NULL != slot.group)
+ {
+ mali_group_lock(slot.group);
+ mali_group_reset(slot.group);
+ mali_group_unlock(slot.group);
+ }
+}
+
+void mali_gp_scheduler_zap_all_active(struct mali_session_data *session)
+{
+ if (NULL != slot.group)
+ {
+ mali_group_zap_session(slot.group, session);
+ }
+}
+
+void mali_gp_scheduler_enable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(slot.group == group);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: enabling gp group %p\n", group));
+
+ mali_group_lock(group);
+
+ if (MALI_GROUP_STATE_DISABLED != group->state)
+ {
+ mali_group_unlock(group);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: gp group %p already enabled\n", group));
+ return;
+ }
+
+ mali_gp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+ MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_DISABLED == slot.state);
+ slot.state = MALI_GP_SLOT_STATE_IDLE;
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ mali_group_power_on_group(group);
+ mali_group_reset(group);
+
+ mali_gp_scheduler_unlock();
+ mali_group_unlock(group);
+
+ /* Pick up any jobs that might have been queued while the GP group was disabled. */
+ mali_gp_scheduler_schedule();
+}
+
+void mali_gp_scheduler_disable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(slot.group == group);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: disabling gp group %p\n", group));
+
+ mali_gp_scheduler_suspend();
+ mali_group_lock(group);
+ mali_gp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_DISABLED == slot.state);
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: gp group %p already disabled\n", group));
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(MALI_GP_SLOT_STATE_IDLE == slot.state);
+ slot.state = MALI_GP_SLOT_STATE_DISABLED;
+ group->state = MALI_GROUP_STATE_DISABLED;
+
+ mali_group_power_off_group(group);
+ }
+
+ mali_gp_scheduler_unlock();
+ mali_group_unlock(group);
+ mali_gp_scheduler_resume();
+}
+
+static void mali_gp_scheduler_job_queued(void)
+{
+ /* We hold a PM reference for every job we hold queued (and running) */
+ _mali_osk_pm_dev_ref_add();
+
+ if (mali_utilization_enabled())
+ {
+ /*
+ * We cheat a little bit by counting the PP as busy from the time a GP job is queued.
+ * This will be fine because we only loose the tiny idle gap between jobs, but
+ * we will instead get less utilization work to do (less locks taken)
+ */
+ mali_utilization_gp_start();
+ }
+}
+
+static void mali_gp_scheduler_job_completed(void)
+{
+ /* Release the PM reference we got in the mali_gp_scheduler_job_queued() function */
+ _mali_osk_pm_dev_ref_dec();
+
+ if (mali_utilization_enabled())
+ {
+ mali_utilization_gp_end();
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h
new file mode 100644
index 0000000..7f61a78
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_gp_scheduler.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_GP_SCHEDULER_H__
+#define __MALI_GP_SCHEDULER_H__
+
+#include "mali_osk.h"
+#include "mali_gp_job.h"
+#include "mali_group.h"
+
+_mali_osk_errcode_t mali_gp_scheduler_initialize(void);
+void mali_gp_scheduler_terminate(void);
+
+void mali_gp_scheduler_job_done(struct mali_group *group, struct mali_gp_job *job, mali_bool success);
+void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job);
+void mali_gp_scheduler_abort_session(struct mali_session_data *session);
+u32 mali_gp_scheduler_dump_state(char *buf, u32 size);
+
+void mali_gp_scheduler_suspend(void);
+void mali_gp_scheduler_resume(void);
+
+/**
+ * @brief Reset all groups
+ *
+ * This function resets all groups known by the GP scheuduler. This must be
+ * called after the Mali HW has been powered on in order to reset the HW.
+ */
+void mali_gp_scheduler_reset_all_groups(void);
+
+/**
+ * @brief Zap TLB on all groups with \a session active
+ *
+ * The scheculer will zap the session on all groups it owns.
+ */
+void mali_gp_scheduler_zap_all_active(struct mali_session_data *session);
+
+void mali_gp_scheduler_enable_group(struct mali_group *group);
+void mali_gp_scheduler_disable_group(struct mali_group *group);
+
+#endif /* __MALI_GP_SCHEDULER_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_group.c b/drivers/gpu/mali400/r3p2/mali/common/mali_group.c
new file mode 100644
index 0000000..070879e
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_group.c
@@ -0,0 +1,2046 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_group.h"
+#include "mali_osk.h"
+#include "mali_l2_cache.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_mmu.h"
+#include "mali_dlbu.h"
+#include "mali_broadcast.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_kernel_core.h"
+#include "mali_osk_profiling.h"
+#include "mali_pm_domain.h"
+#include "mali_pm.h"
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+#include <linux/sched.h>
+#include <trace/events/gpu.h>
+#endif
+
+
+static void mali_group_bottom_half_mmu(void *data);
+static void mali_group_bottom_half_gp(void *data);
+static void mali_group_bottom_half_pp(void *data);
+
+static void mali_group_timeout(void *data);
+static void mali_group_reset_pp(struct mali_group *group);
+static void mali_group_reset_mmu(struct mali_group *group);
+
+#if defined(CONFIG_MALI400_PROFILING)
+static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num);
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+
+/*
+ * The group object is the most important object in the device driver,
+ * and acts as the center of many HW operations.
+ * The reason for this is that operations on the MMU will affect all
+ * cores connected to this MMU (a group is defined by the MMU and the
+ * cores which are connected to this).
+ * The group lock is thus the most important lock, followed by the
+ * GP and PP scheduler locks. They must be taken in the following
+ * order:
+ * GP/PP lock first, then group lock(s).
+ */
+
+static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS] = { NULL, };
+static u32 mali_global_num_groups = 0;
+
+enum mali_group_activate_pd_status
+{
+ MALI_GROUP_ACTIVATE_PD_STATUS_FAILED,
+ MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD,
+ MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD,
+};
+
+/* local helper functions */
+static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session);
+static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session);
+static void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session);
+static void mali_group_recovery_reset(struct mali_group *group);
+static void mali_group_mmu_page_fault(struct mali_group *group);
+
+static void mali_group_post_process_job_pp(struct mali_group *group);
+static void mali_group_post_process_job_gp(struct mali_group *group, mali_bool suspend);
+
+void mali_group_lock(struct mali_group *group)
+{
+ if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(group->lock, _MALI_OSK_LOCKMODE_RW))
+ {
+ /* Non-interruptable lock failed: this should never happen. */
+ MALI_DEBUG_ASSERT(0);
+ }
+ MALI_DEBUG_PRINT(5, ("Mali group: Group lock taken 0x%08X\n", group));
+}
+
+void mali_group_unlock(struct mali_group *group)
+{
+ MALI_DEBUG_PRINT(5, ("Mali group: Releasing group lock 0x%08X\n", group));
+ _mali_osk_lock_signal(group->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+#ifdef DEBUG
+void mali_group_assert_locked(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+}
+#endif
+
+
+struct mali_group *mali_group_create(struct mali_l2_cache_core *core, struct mali_dlbu_core *dlbu, struct mali_bcast_unit *bcast)
+{
+ struct mali_group *group = NULL;
+ _mali_osk_lock_flags_t lock_flags;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#else
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#endif
+
+ if (mali_global_num_groups >= MALI_MAX_NUMBER_OF_GROUPS)
+ {
+ MALI_PRINT_ERROR(("Mali group: Too many group objects created\n"));
+ return NULL;
+ }
+
+ group = _mali_osk_calloc(1, sizeof(struct mali_group));
+ if (NULL != group)
+ {
+ group->timeout_timer = _mali_osk_timer_init();
+
+ if (NULL != group->timeout_timer)
+ {
+ _mali_osk_lock_order_t order;
+ _mali_osk_timer_setcallback(group->timeout_timer, mali_group_timeout, (void *)group);
+
+ if (NULL != dlbu)
+ {
+ order = _MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL;
+ }
+ else
+ {
+ order = _MALI_OSK_LOCK_ORDER_GROUP;
+ }
+
+ group->lock = _mali_osk_lock_init(lock_flags, 0, order);
+ if (NULL != group->lock)
+ {
+ group->l2_cache_core[0] = core;
+ group->session = NULL;
+ group->page_dir_ref_count = 0;
+ group->power_is_on = MALI_TRUE;
+ group->state = MALI_GROUP_STATE_IDLE;
+ _mali_osk_list_init(&group->group_list);
+ _mali_osk_list_init(&group->pp_scheduler_list);
+ group->parent_group = NULL;
+ group->l2_cache_core_ref_count[0] = 0;
+ group->l2_cache_core_ref_count[1] = 0;
+ group->bcast_core = bcast;
+ group->dlbu_core = dlbu;
+
+ mali_global_groups[mali_global_num_groups] = group;
+ mali_global_num_groups++;
+
+ return group;
+ }
+ _mali_osk_timer_term(group->timeout_timer);
+ }
+ _mali_osk_free(group);
+ }
+
+ return NULL;
+}
+
+_mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core)
+{
+ /* This group object now owns the MMU core object */
+ group->mmu= mmu_core;
+ group->bottom_half_work_mmu = _mali_osk_wq_create_work(mali_group_bottom_half_mmu, group);
+ if (NULL == group->bottom_half_work_mmu)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_group_remove_mmu_core(struct mali_group *group)
+{
+ /* This group object no longer owns the MMU core object */
+ group->mmu = NULL;
+ if (NULL != group->bottom_half_work_mmu)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
+ }
+}
+
+_mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core)
+{
+ /* This group object now owns the GP core object */
+ group->gp_core = gp_core;
+ group->bottom_half_work_gp = _mali_osk_wq_create_work(mali_group_bottom_half_gp, group);
+ if (NULL == group->bottom_half_work_gp)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_group_remove_gp_core(struct mali_group *group)
+{
+ /* This group object no longer owns the GP core object */
+ group->gp_core = NULL;
+ if (NULL != group->bottom_half_work_gp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_gp);
+ }
+}
+
+_mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core)
+{
+ /* This group object now owns the PP core object */
+ group->pp_core = pp_core;
+ group->bottom_half_work_pp = _mali_osk_wq_create_work(mali_group_bottom_half_pp, group);
+ if (NULL == group->bottom_half_work_pp)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_group_remove_pp_core(struct mali_group *group)
+{
+ /* This group object no longer owns the PP core object */
+ group->pp_core = NULL;
+ if (NULL != group->bottom_half_work_pp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_pp);
+ }
+}
+
+void mali_group_set_pm_domain(struct mali_group *group, struct mali_pm_domain *domain)
+{
+ group->pm_domain = domain;
+}
+
+void mali_group_delete(struct mali_group *group)
+{
+ u32 i;
+
+ MALI_DEBUG_PRINT(4, ("Deleting group %p\n", group));
+
+ MALI_DEBUG_ASSERT(NULL == group->parent_group);
+
+ /* Delete the resources that this group owns */
+ if (NULL != group->gp_core)
+ {
+ mali_gp_delete(group->gp_core);
+ }
+
+ if (NULL != group->pp_core)
+ {
+ mali_pp_delete(group->pp_core);
+ }
+
+ if (NULL != group->mmu)
+ {
+ mali_mmu_delete(group->mmu);
+ }
+
+ if (mali_group_is_virtual(group))
+ {
+ /* Remove all groups from virtual group */
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ child->parent_group = NULL;
+ mali_group_delete(child);
+ }
+
+ mali_dlbu_delete(group->dlbu_core);
+
+ if (NULL != group->bcast_core)
+ {
+ mali_bcast_unit_delete(group->bcast_core);
+ }
+ }
+
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ if (mali_global_groups[i] == group)
+ {
+ mali_global_groups[i] = NULL;
+ mali_global_num_groups--;
+
+ if (i != mali_global_num_groups)
+ {
+ /* We removed a group from the middle of the array -- move the last
+ * group to the current position to close the gap */
+ mali_global_groups[i] = mali_global_groups[mali_global_num_groups];
+ mali_global_groups[mali_global_num_groups] = NULL;
+ }
+
+ break;
+ }
+ }
+
+ if (NULL != group->timeout_timer)
+ {
+ _mali_osk_timer_del(group->timeout_timer);
+ _mali_osk_timer_term(group->timeout_timer);
+ }
+
+ if (NULL != group->bottom_half_work_mmu)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_mmu);
+ }
+
+ if (NULL != group->bottom_half_work_gp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_gp);
+ }
+
+ if (NULL != group->bottom_half_work_pp)
+ {
+ _mali_osk_wq_delete_work(group->bottom_half_work_pp);
+ }
+
+ _mali_osk_lock_term(group->lock);
+
+ _mali_osk_free(group);
+}
+
+MALI_DEBUG_CODE(static void mali_group_print_virtual(struct mali_group *vgroup)
+{
+ u32 i;
+ struct mali_group *group;
+ struct mali_group *temp;
+
+ MALI_DEBUG_PRINT(4, ("Virtual group %p\n", vgroup));
+ MALI_DEBUG_PRINT(4, ("l2_cache_core[0] = %p, ref = %d\n", vgroup->l2_cache_core[0], vgroup->l2_cache_core_ref_count[0]));
+ MALI_DEBUG_PRINT(4, ("l2_cache_core[1] = %p, ref = %d\n", vgroup->l2_cache_core[1], vgroup->l2_cache_core_ref_count[1]));
+
+ i = 0;
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &vgroup->group_list, struct mali_group, group_list)
+ {
+ MALI_DEBUG_PRINT(4, ("[%d] %p, l2_cache_core[0] = %p\n", i, group, group->l2_cache_core[0]));
+ i++;
+ }
+})
+
+/**
+ * @brief Add child group to virtual group parent
+ *
+ * Before calling this function, child must have it's state set to JOINING_VIRTUAL
+ * to ensure it's not touched during the transition period. When this function returns,
+ * child's state will be IN_VIRTUAL.
+ */
+void mali_group_add_group(struct mali_group *parent, struct mali_group *child, mali_bool update_hw)
+{
+ mali_bool found;
+ u32 i;
+ struct mali_session_data *child_session;
+
+ MALI_DEBUG_PRINT(3, ("Adding group %p to virtual group %p\n", child, parent));
+
+ MALI_ASSERT_GROUP_LOCKED(parent);
+
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
+ MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
+ MALI_DEBUG_ASSERT(NULL == child->parent_group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_JOINING_VIRTUAL == child->state);
+
+ _mali_osk_list_addtail(&child->group_list, &parent->group_list);
+
+ child->state = MALI_GROUP_STATE_IN_VIRTUAL;
+ child->parent_group = parent;
+
+ MALI_DEBUG_ASSERT_POINTER(child->l2_cache_core[0]);
+
+ MALI_DEBUG_PRINT(4, ("parent->l2_cache_core: [0] = %p, [1] = %p\n", parent->l2_cache_core[0], parent->l2_cache_core[1]));
+ MALI_DEBUG_PRINT(4, ("child->l2_cache_core: [0] = %p, [1] = %p\n", child->l2_cache_core[0], child->l2_cache_core[1]));
+
+ /* Keep track of the L2 cache cores of child groups */
+ found = MALI_FALSE;
+ for (i = 0; i < 2; i++)
+ {
+ if (parent->l2_cache_core[i] == child->l2_cache_core[0])
+ {
+ MALI_DEBUG_ASSERT(parent->l2_cache_core_ref_count[i] > 0);
+ parent->l2_cache_core_ref_count[i]++;
+ found = MALI_TRUE;
+ }
+ }
+
+ if (!found)
+ {
+ /* First time we see this L2 cache, add it to our list */
+ i = (NULL == parent->l2_cache_core[0]) ? 0 : 1;
+
+ MALI_DEBUG_PRINT(4, ("First time we see l2_cache %p. Adding to [%d] = %p\n", child->l2_cache_core[0], i, parent->l2_cache_core[i]));
+
+ MALI_DEBUG_ASSERT(NULL == parent->l2_cache_core[i]);
+
+ parent->l2_cache_core[i] = child->l2_cache_core[0];
+ parent->l2_cache_core_ref_count[i]++;
+ }
+
+ /* Update Broadcast Unit and DLBU */
+ mali_bcast_add_group(parent->bcast_core, child);
+ mali_dlbu_add_group(parent->dlbu_core, child);
+
+ child_session = child->session;
+ child->session = NULL;
+
+ /* Above this comment, only software state is updated and the HW is not
+ * touched. Now, check if Mali is powered and skip the rest if it isn't
+ * powered.
+ */
+
+ if (!update_hw)
+ {
+ MALI_DEBUG_CODE(mali_group_print_virtual(parent));
+ return;
+ }
+
+ /* Update MMU */
+ MALI_DEBUG_ASSERT(0 == child->page_dir_ref_count);
+ if (parent->session == child_session)
+ {
+ mali_mmu_zap_tlb(child->mmu);
+ }
+ else
+ {
+ if (NULL == parent->session)
+ {
+ mali_mmu_activate_empty_page_directory(child->mmu);
+ }
+ else
+ {
+
+ mali_bool activate_success = mali_mmu_activate_page_directory(child->mmu,
+ mali_session_get_page_directory(parent->session));
+ MALI_DEBUG_ASSERT(activate_success);
+ MALI_IGNORE(activate_success);
+ }
+ }
+
+ /* Update HW only if power is on */
+ mali_bcast_reset(parent->bcast_core);
+ mali_dlbu_update_mask(parent->dlbu_core);
+
+ /* Start job on child when parent is active */
+ if (NULL != parent->pp_running_job)
+ {
+ struct mali_pp_job *job = parent->pp_running_job;
+ MALI_DEBUG_PRINT(3, ("Group %x joining running job %d on virtual group %x\n",
+ child, mali_pp_job_get_id(job), parent));
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_WORKING == parent->state);
+ mali_pp_job_start(child->pp_core, job, mali_pp_core_get_id(child->pp_core), MALI_TRUE);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
+ mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+ }
+
+ MALI_DEBUG_CODE(mali_group_print_virtual(parent);)
+}
+
+/**
+ * @brief Remove child group from virtual group parent
+ *
+ * After the child is removed, it's state will be LEAVING_VIRTUAL and must be set
+ * to IDLE before it can be used.
+ */
+void mali_group_remove_group(struct mali_group *parent, struct mali_group *child)
+{
+ u32 i;
+
+ MALI_ASSERT_GROUP_LOCKED(parent);
+
+ MALI_DEBUG_PRINT(3, ("Removing group %p from virtual group %p\n", child, parent));
+
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
+ MALI_DEBUG_ASSERT(!mali_group_is_virtual(child));
+ MALI_DEBUG_ASSERT(parent == child->parent_group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IN_VIRTUAL == child->state);
+ /* Removing groups while running is not yet supported. */
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == parent->state);
+
+ mali_group_lock(child);
+
+ /* Update Broadcast Unit and DLBU */
+ mali_bcast_remove_group(parent->bcast_core, child);
+ mali_dlbu_remove_group(parent->dlbu_core, child);
+
+ /* Update HW only if power is on */
+ if (mali_pm_is_power_on())
+ {
+ mali_bcast_reset(parent->bcast_core);
+ mali_dlbu_update_mask(parent->dlbu_core);
+ }
+
+ _mali_osk_list_delinit(&child->group_list);
+
+ child->session = parent->session;
+ child->parent_group = NULL;
+ child->state = MALI_GROUP_STATE_LEAVING_VIRTUAL;
+
+ /* Keep track of the L2 cache cores of child groups */
+ i = (child->l2_cache_core[0] == parent->l2_cache_core[0]) ? 0 : 1;
+
+ MALI_DEBUG_ASSERT(child->l2_cache_core[0] == parent->l2_cache_core[i]);
+
+ parent->l2_cache_core_ref_count[i]--;
+
+ if (parent->l2_cache_core_ref_count[i] == 0)
+ {
+ parent->l2_cache_core[i] = NULL;
+ }
+
+ MALI_DEBUG_CODE(mali_group_print_virtual(parent));
+
+ mali_group_unlock(child);
+}
+
+struct mali_group *mali_group_acquire_group(struct mali_group *parent)
+{
+ struct mali_group *child;
+
+ MALI_ASSERT_GROUP_LOCKED(parent);
+
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(parent));
+ MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&parent->group_list));
+
+ child = _MALI_OSK_LIST_ENTRY(parent->group_list.prev, struct mali_group, group_list);
+
+ mali_group_remove_group(parent, child);
+
+ return child;
+}
+
+void mali_group_reset(struct mali_group *group)
+{
+ /*
+ * This function should not be used to abort jobs,
+ * currently only called during insmod and PM resume
+ */
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT(NULL == group->gp_running_job);
+ MALI_DEBUG_ASSERT(NULL == group->pp_running_job);
+
+ group->session = NULL;
+
+ if (NULL != group->dlbu_core)
+ {
+ mali_dlbu_reset(group->dlbu_core);
+ }
+
+ if (NULL != group->bcast_core)
+ {
+ mali_bcast_reset(group->bcast_core);
+ }
+
+ if (NULL != group->mmu)
+ {
+ mali_group_reset_mmu(group);
+ }
+
+ if (NULL != group->gp_core)
+ {
+ mali_gp_reset(group->gp_core);
+ }
+
+ if (NULL != group->pp_core)
+ {
+ mali_group_reset_pp(group);
+ }
+}
+
+struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group)
+{
+ return group->gp_core;
+}
+
+struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group)
+{
+ return group->pp_core;
+}
+
+void mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job)
+{
+ struct mali_session_data *session;
+ enum mali_group_activate_pd_status activate_status;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
+
+ session = mali_gp_job_get_session(job);
+
+ if (NULL != group->l2_cache_core[0])
+ {
+ mali_l2_cache_invalidate_conditional(group->l2_cache_core[0], mali_gp_job_get_id(job));
+ }
+
+ activate_status = mali_group_activate_page_directory(group, session);
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
+ {
+ /* if session is NOT kept Zapping is done as part of session switch */
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
+ {
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+ }
+ mali_gp_job_start(group->gp_core, job);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) |
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_gp_job_get_frame_builder_id(job), mali_gp_job_get_flush_id(job), 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
+ mali_gp_job_get_pid(job), mali_gp_job_get_tid(job), 0, 0, 0);
+#if defined(CONFIG_MALI400_PROFILING)
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ mali_group_report_l2_cache_counters_per_core(group, 0);
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_gp_get_hw_core_desc(group->gp_core), sched_clock(),
+ mali_gp_job_get_pid(job), 0, mali_gp_job_get_id(job));
+#endif
+ group->gp_running_job = job;
+ group->state = MALI_GROUP_STATE_WORKING;
+
+ }
+
+ /* Setup the timeout timer value and save the job id for the job running on the gp core */
+ _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+}
+
+void mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job)
+{
+ struct mali_session_data *session;
+ enum mali_group_activate_pd_status activate_status;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_IDLE == group->state);
+
+ session = mali_pp_job_get_session(job);
+
+ if (NULL != group->l2_cache_core[0])
+ {
+ mali_l2_cache_invalidate_conditional(group->l2_cache_core[0], mali_pp_job_get_id(job));
+ }
+
+ if (NULL != group->l2_cache_core[1])
+ {
+ mali_l2_cache_invalidate_conditional(group->l2_cache_core[1], mali_pp_job_get_id(job));
+ }
+
+ activate_status = mali_group_activate_page_directory(group, session);
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_FAILED != activate_status)
+ {
+ /* if session is NOT kept Zapping is done as part of session switch */
+ if (MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD == activate_status)
+ {
+ MALI_DEBUG_PRINT(3, ("PP starting job PD_Switch 0 Flush 1 Zap 1\n"));
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+ }
+
+ if (mali_group_is_virtual(group))
+ {
+ struct mali_group *child;
+ struct mali_group *temp;
+ u32 core_num = 0;
+
+ /* Configure DLBU for the job */
+ mali_dlbu_config_job(group->dlbu_core, job);
+
+ /* Write stack address for each child group */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_write_addr_stack(child->pp_core, job);
+ core_num++;
+ }
+ }
+
+ mali_pp_job_start(group->pp_core, job, sub_job, MALI_FALSE);
+
+ /* if the group is virtual, loop through physical groups which belong to this group
+ * and call profiling events for its cores as virtual */
+ if (MALI_TRUE == mali_group_is_virtual(group))
+ {
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
+ mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+ }
+#if defined(CONFIG_MALI400_PROFILING)
+ if (0 != group->l2_cache_core_ref_count[0])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+ }
+ if (0 != group->l2_cache_core_ref_count[1])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
+ }
+ }
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+ }
+ else /* group is physical - call profiling events for physical cores */
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ mali_pp_job_get_frame_builder_id(job), mali_pp_job_get_flush_id(job), 0, 0, 0);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
+ mali_pp_job_get_pid(job), mali_pp_job_get_tid(job), 0, 0, 0);
+#if defined(CONFIG_MALI400_PROFILING)
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+ }
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_pp_get_hw_core_desc(group->pp_core), sched_clock(), mali_pp_job_get_tid(job), 0, mali_pp_job_get_id(job));
+#endif
+ group->pp_running_job = job;
+ group->pp_running_sub_job = sub_job;
+ group->state = MALI_GROUP_STATE_WORKING;
+
+ }
+
+ /* Setup the timeout timer value and save the job id for the job running on the pp core */
+ _mali_osk_timer_mod(group->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+}
+
+struct mali_gp_job *mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (group->state != MALI_GROUP_STATE_OOM ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ return NULL; /* Illegal request or job has already been aborted */
+ }
+
+ if (NULL != group->l2_cache_core[0])
+ {
+ mali_l2_cache_invalidate(group->l2_cache_core[0]);
+ }
+
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+
+ mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0);
+
+ group->state = MALI_GROUP_STATE_WORKING;
+
+ return group->gp_running_job;
+}
+
+static void mali_group_reset_mmu(struct mali_group *group)
+{
+ struct mali_group *child;
+ struct mali_group *temp;
+ _mali_osk_errcode_t err;
+
+ if (!mali_group_is_virtual(group))
+ {
+ /* This is a physical group or an idle virtual group -- simply wait for
+ * the reset to complete. */
+ err = mali_mmu_reset(group->mmu);
+ MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
+ }
+ else /* virtual group */
+ {
+ err = mali_mmu_reset(group->mmu);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ return;
+ }
+
+ /* Loop through all members of this virtual group and wait
+ * until they are done resetting.
+ */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ err = mali_mmu_reset(child->mmu);
+ MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
+ }
+ }
+}
+
+static void mali_group_reset_pp(struct mali_group *group)
+{
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ mali_pp_reset_async(group->pp_core);
+
+ if (!mali_group_is_virtual(group) || NULL == group->pp_running_job)
+ {
+ /* This is a physical group or an idle virtual group -- simply wait for
+ * the reset to complete. */
+ mali_pp_reset_wait(group->pp_core);
+ }
+ else /* virtual group */
+ {
+ /* Loop through all members of this virtual group and wait until they
+ * are done resetting.
+ */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_reset_wait(child->pp_core);
+ }
+ }
+}
+
+static void mali_group_complete_pp(struct mali_group *group, mali_bool success)
+{
+ struct mali_pp_job *pp_job_to_return;
+ u32 pp_sub_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->pp_core);
+ MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ mali_group_post_process_job_pp(group);
+
+ if (success)
+ {
+ /* Only do soft reset for successful jobs, a full recovery
+ * reset will be done for failed jobs. */
+ mali_pp_reset_async(group->pp_core);
+ }
+
+ pp_job_to_return = group->pp_running_job;
+ pp_sub_job_to_return = group->pp_running_sub_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->pp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ /* Do hard reset if the job failed, or if soft reset fails */
+ if (!success || _MALI_OSK_ERR_OK != mali_pp_reset_wait(group->pp_core))
+ {
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
+
+ mali_group_recovery_reset(group);
+ }
+
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, success);
+}
+
+static void mali_group_complete_gp(struct mali_group *group, mali_bool success)
+{
+ struct mali_gp_job *gp_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->gp_core);
+ MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ mali_group_post_process_job_gp(group, MALI_FALSE);
+
+ mali_gp_reset_async(group->gp_core);
+
+ gp_job_to_return = group->gp_running_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->gp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ if (_MALI_OSK_ERR_OK != mali_gp_reset_wait(group->gp_core))
+ {
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
+
+ mali_group_recovery_reset(group);
+ }
+
+ mali_gp_scheduler_job_done(group, gp_job_to_return, success);
+}
+
+void mali_group_abort_gp_job(struct mali_group *group, u32 job_id)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (MALI_GROUP_STATE_IDLE == group->state ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_gp(group, MALI_FALSE);
+}
+
+static void mali_group_abort_pp_job(struct mali_group *group, u32 job_id)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (MALI_GROUP_STATE_IDLE == group->state ||
+ mali_pp_job_get_id(group->pp_running_job) != job_id)
+ {
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_pp(group, MALI_FALSE);
+}
+
+void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session)
+{
+ struct mali_gp_job *gp_job;
+ struct mali_pp_job *pp_job;
+ u32 gp_job_id = 0;
+ u32 pp_job_id = 0;
+ mali_bool abort_pp = MALI_FALSE;
+ mali_bool abort_gp = MALI_FALSE;
+
+ mali_group_lock(group);
+
+ if (mali_group_is_in_virtual(group))
+ {
+ /* Group is member of a virtual group, don't touch it! */
+ mali_group_unlock(group);
+ return;
+ }
+
+ gp_job = group->gp_running_job;
+ pp_job = group->pp_running_job;
+
+ if ((NULL != gp_job) && (mali_gp_job_get_session(gp_job) == session))
+ {
+ MALI_DEBUG_PRINT(4, ("Aborting GP job 0x%08x from session 0x%08x\n", gp_job, session));
+
+ gp_job_id = mali_gp_job_get_id(gp_job);
+ abort_gp = MALI_TRUE;
+ }
+
+ if ((NULL != pp_job) && (mali_pp_job_get_session(pp_job) == session))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Aborting PP job 0x%08x from session 0x%08x\n", pp_job, session));
+
+ pp_job_id = mali_pp_job_get_id(pp_job);
+ abort_pp = MALI_TRUE;
+ }
+
+ if (abort_gp)
+ {
+ mali_group_abort_gp_job(group, gp_job_id);
+ }
+ if (abort_pp)
+ {
+ mali_group_abort_pp_job(group, pp_job_id);
+ }
+
+ mali_group_remove_session_if_unused(group, session);
+
+ mali_group_unlock(group);
+}
+
+struct mali_group *mali_group_get_glob_group(u32 index)
+{
+ if(mali_global_num_groups > index)
+ {
+ return mali_global_groups[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_group_get_glob_num_groups(void)
+{
+ return mali_global_num_groups;
+}
+
+static enum mali_group_activate_pd_status mali_group_activate_page_directory(struct mali_group *group, struct mali_session_data *session)
+{
+ enum mali_group_activate_pd_status retval;
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ MALI_DEBUG_PRINT(5, ("Mali group: Activating page directory 0x%08X from session 0x%08X on group 0x%08X\n", mali_session_get_page_directory(session), session, group));
+ MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count);
+
+ if (0 != group->page_dir_ref_count)
+ {
+ if (group->session != session)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Activating session FAILED: 0x%08x on group 0x%08X. Existing session: 0x%08x\n", session, group, group->session));
+ return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Activating session already activated: 0x%08x on group 0x%08X. New Ref: %d\n", session, group, 1+group->page_dir_ref_count));
+ retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD;
+
+ }
+ }
+ else
+ {
+ /* There might be another session here, but it is ok to overwrite it since group->page_dir_ref_count==0 */
+ if (group->session != session)
+ {
+ mali_bool activate_success;
+ MALI_DEBUG_PRINT(5, ("Mali group: Activate session: %08x previous: %08x on group 0x%08X. Ref: %d\n", session, group->session, group, 1+group->page_dir_ref_count));
+
+ activate_success = mali_mmu_activate_page_directory(group->mmu, mali_session_get_page_directory(session));
+ MALI_DEBUG_ASSERT(activate_success);
+ if ( MALI_FALSE== activate_success ) return MALI_GROUP_ACTIVATE_PD_STATUS_FAILED;
+ group->session = session;
+ retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_SWITCHED_PD;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: Activate existing session 0x%08X on group 0x%08X. Ref: %d\n", session->page_directory, group, 1+group->page_dir_ref_count));
+ retval = MALI_GROUP_ACTIVATE_PD_STATUS_OK_KEPT_PD;
+ }
+ }
+
+ group->page_dir_ref_count++;
+ return retval;
+}
+
+static void mali_group_deactivate_page_directory(struct mali_group *group, struct mali_session_data *session)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ MALI_DEBUG_ASSERT(0 < group->page_dir_ref_count);
+ MALI_DEBUG_ASSERT(session == group->session);
+
+ group->page_dir_ref_count--;
+
+ /* As an optimization, the MMU still points to the group->session even if (0 == group->page_dir_ref_count),
+ and we do not call mali_mmu_activate_empty_page_directory(group->mmu); */
+ MALI_DEBUG_ASSERT(0 <= group->page_dir_ref_count);
+}
+
+static void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (0 == group->page_dir_ref_count)
+ {
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_WORKING != group->state);
+
+ if (group->session == session)
+ {
+ MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
+ MALI_DEBUG_PRINT(3, ("Mali group: Deactivating unused session 0x%08X on group %08X\n", session, group));
+ mali_mmu_activate_empty_page_directory(group->mmu);
+ group->session = NULL;
+ }
+ }
+}
+
+mali_bool mali_group_power_is_on(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ return group->power_is_on;
+}
+
+void mali_group_power_on_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_IN_VIRTUAL == group->state
+ || MALI_GROUP_STATE_JOINING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ MALI_DEBUG_PRINT(3, ("Group %p powered on\n", group));
+
+ group->power_is_on = MALI_TRUE;
+}
+
+void mali_group_power_off_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_LOCK_HELD(group->lock);
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_IN_VIRTUAL == group->state
+ || MALI_GROUP_STATE_JOINING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ MALI_DEBUG_PRINT(3, ("Group %p powered off\n", group));
+
+ /* It is necessary to set group->session = NULL so that the powered off MMU is not written
+ * to on map/unmap. It is also necessary to set group->power_is_on = MALI_FALSE so that
+ * pending bottom_halves does not access powered off cores. */
+
+ group->session = NULL;
+ group->power_is_on = MALI_FALSE;
+}
+
+void mali_group_power_on(void)
+{
+ int i;
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ struct mali_group *group = mali_global_groups[i];
+
+ mali_group_lock(group);
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_ASSERT(MALI_FALSE == group->power_is_on);
+ }
+ else
+ {
+ mali_group_power_on_group(group);
+ }
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(4, ("Mali Group: power on\n"));
+}
+
+void mali_group_power_off(void)
+{
+ int i;
+
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ struct mali_group *group = mali_global_groups[i];
+
+ mali_group_lock(group);
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_ASSERT(MALI_FALSE == group->power_is_on);
+ }
+ else
+ {
+ mali_group_power_off_group(group);
+ }
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(4, ("Mali Group: power off\n"));
+}
+
+static void mali_group_recovery_reset(struct mali_group *group)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ /* Stop cores, bus stop */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_stop_bus(group->pp_core);
+ }
+ else
+ {
+ mali_gp_stop_bus(group->gp_core);
+ }
+
+ /* Flush MMU and clear page fault (if any) */
+ mali_mmu_activate_fault_flush_page_directory(group->mmu);
+ mali_mmu_page_fault_done(group->mmu);
+
+ /* Wait for cores to stop bus, then do a hard reset on them */
+ if (NULL != group->pp_core)
+ {
+ if (mali_group_is_virtual(group))
+ {
+ struct mali_group *child, *temp;
+
+ /* Disable the broadcast unit while we do reset directly on the member cores. */
+ mali_bcast_disable(group->bcast_core);
+
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_stop_bus_wait(child->pp_core);
+ mali_pp_hard_reset(child->pp_core);
+ }
+
+ mali_bcast_enable(group->bcast_core);
+ }
+ else
+ {
+ mali_pp_stop_bus_wait(group->pp_core);
+ mali_pp_hard_reset(group->pp_core);
+ }
+ }
+ else
+ {
+ mali_gp_stop_bus_wait(group->gp_core);
+ mali_gp_hard_reset(group->gp_core);
+ }
+
+ /* Reset MMU */
+ err = mali_mmu_reset(group->mmu);
+ MALI_DEBUG_ASSERT(_MALI_OSK_ERR_OK == err);
+ MALI_IGNORE(err);
+
+ group->session = NULL;
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "Group: %p\n", group);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tstate: %d\n", group->state);
+ if (group->gp_core)
+ {
+ n += mali_gp_dump_state(group->gp_core, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tGP job: %p\n", group->gp_running_job);
+ }
+ if (group->pp_core)
+ {
+ n += mali_pp_dump_state(group->pp_core, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\tPP job: %p, subjob %d \n",
+ group->pp_running_job, group->pp_running_sub_job);
+ }
+
+ return n;
+}
+#endif
+
+static void mali_group_mmu_page_fault(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (NULL != group->pp_core)
+ {
+ struct mali_pp_job *pp_job_to_return;
+ u32 pp_sub_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->pp_running_job);
+
+ mali_group_post_process_job_pp(group);
+
+ pp_job_to_return = group->pp_running_job;
+ pp_sub_job_to_return = group->pp_running_sub_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->pp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ mali_group_recovery_reset(group); /* This will also clear the page fault itself */
+
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, MALI_FALSE);
+ }
+ else
+ {
+ struct mali_gp_job *gp_job_to_return;
+
+ MALI_DEBUG_ASSERT_POINTER(group->gp_running_job);
+
+ mali_group_post_process_job_gp(group, MALI_FALSE);
+
+ gp_job_to_return = group->gp_running_job;
+ group->state = MALI_GROUP_STATE_IDLE;
+ group->gp_running_job = NULL;
+
+ mali_group_deactivate_page_directory(group, group->session);
+
+ mali_group_recovery_reset(group); /* This will also clear the page fault itself */
+
+ mali_gp_scheduler_job_done(group, gp_job_to_return, MALI_FALSE);
+ }
+}
+
+_mali_osk_errcode_t mali_group_upper_half_mmu(void * data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_mmu_core *mmu = group->mmu;
+ u32 int_stat;
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain))
+ {
+ goto out;
+ }
+#endif
+
+ /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
+ int_stat = mali_mmu_get_int_status(mmu);
+ if (0 != int_stat)
+ {
+ struct mali_group *parent = group->parent_group;
+
+ /* page fault or bus error, we thread them both in the same way */
+ mali_mmu_mask_all_interrupts(mmu);
+ if (NULL == parent)
+ {
+ _mali_osk_wq_schedule_work(group->bottom_half_work_mmu);
+ }
+ else
+ {
+ _mali_osk_wq_schedule_work(parent->bottom_half_work_mmu);
+ }
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+out:
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_pm_domain_unlock_state(group->pm_domain);
+#endif
+
+ return err;
+}
+
+static void mali_group_bottom_half_mmu(void * data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_mmu_core *mmu = group->mmu;
+ u32 rawstat;
+ MALI_DEBUG_CODE(u32 status);
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ mali_group_lock(group);
+
+ MALI_DEBUG_ASSERT(NULL == group->parent_group);
+
+ if ( MALI_FALSE == mali_group_power_is_on(group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", mmu->hw_core.description));
+ mali_group_unlock(group);
+ return;
+ }
+
+ rawstat = mali_mmu_get_rawstat(mmu);
+ MALI_DEBUG_CODE(status = mali_mmu_get_status(mmu));
+
+ MALI_DEBUG_PRINT(4, ("Mali MMU: Bottom half, interrupt 0x%08X, status 0x%08X\n", rawstat, status));
+
+ if (rawstat & (MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR))
+ {
+ /* An actual page fault has occurred. */
+ u32 fault_address = mali_mmu_get_page_fault_addr(mmu);
+ MALI_DEBUG_PRINT(2,("Mali MMU: Page fault detected at 0x%x from bus id %d of type %s on %s\n",
+ (void*)fault_address,
+ (status >> 6) & 0x1F,
+ (status & 32) ? "write" : "read",
+ mmu->hw_core.description));
+ MALI_IGNORE(fault_address);
+
+ mali_group_mmu_page_fault(group);
+ }
+
+ mali_group_unlock(group);
+}
+
+_mali_osk_errcode_t mali_group_upper_half_gp(void *data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_gp_core *core = group->gp_core;
+ u32 irq_readout;
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain))
+ {
+ goto out;
+ }
+#endif
+
+ irq_readout = mali_gp_get_int_stat(core);
+
+ if (MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_gp_mask_all_interrupts(core);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
+
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+out:
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_pm_domain_unlock_state(group->pm_domain);
+#endif
+
+ return err;
+}
+
+static void mali_group_bottom_half_gp(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+ u32 irq_readout;
+ u32 irq_errors;
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(0), 0, 0);
+
+ mali_group_lock(group);
+
+ if ( MALI_FALSE == mali_group_power_is_on(group) )
+ {
+ MALI_PRINT_ERROR(("Mali group: Interrupt bottom half of %s when core is OFF.", mali_gp_get_hw_core_desc(group->gp_core)));
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ irq_readout = mali_gp_read_rawstat(group->gp_core);
+
+ MALI_DEBUG_PRINT(4, ("Mali group: GP bottom half IRQ 0x%08X from core %s\n", irq_readout, mali_gp_get_hw_core_desc(group->gp_core)));
+
+ if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST))
+ {
+ u32 core_status = mali_gp_read_core_status(group->gp_core);
+ if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali group: GP job completed, calling group handler\n"));
+ group->core_timed_out = MALI_FALSE;
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ mali_group_complete_gp(group, MALI_TRUE);
+ mali_group_unlock(group);
+ return;
+ }
+ }
+
+ /*
+ * Now lets look at the possible error cases (IRQ indicating error or timeout)
+ * END_CMD_LST, HANG and PLBU_OOM interrupts are not considered error.
+ */
+ irq_errors = irq_readout & ~(MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_HANG|MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM);
+ if (0 != irq_errors)
+ {
+ MALI_PRINT_ERROR(("Mali group: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, mali_gp_get_hw_core_desc(group->gp_core)));
+ group->core_timed_out = MALI_FALSE;
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ mali_group_complete_gp(group, MALI_FALSE);
+ mali_group_unlock(group);
+ return;
+ }
+ else if (group->core_timed_out) /* SW timeout */
+ {
+ group->core_timed_out = MALI_FALSE;
+ if (!_mali_osk_timer_pending(group->timeout_timer) && NULL != group->gp_running_job)
+ {
+ MALI_PRINT(("Mali group: Job %d timed out\n", mali_gp_job_get_id(group->gp_running_job)));
+ mali_group_complete_gp(group, MALI_FALSE);
+ mali_group_unlock(group);
+ return;
+ }
+ }
+ else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
+ {
+ /* GP wants more memory in order to continue. */
+ MALI_DEBUG_PRINT(3, ("Mali group: PLBU needs more heap memory\n"));
+
+ group->state = MALI_GROUP_STATE_OOM;
+ mali_group_unlock(group); /* Nothing to do on the HW side, so just release group lock right away */
+ mali_gp_scheduler_oom(group, group->gp_running_job);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ /*
+ * The only way to get here is if we only got one of two needed END_CMD_LST
+ * interrupts. Enable all but not the complete interrupt that has been
+ * received and continue to run.
+ */
+ mali_gp_enable_interrupts(group->gp_core, irq_readout & (MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST|MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST));
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
+}
+
+static void mali_group_post_process_job_gp(struct mali_group *group, mali_bool suspend)
+{
+ /* Stop the timeout timer. */
+ _mali_osk_timer_del_async(group->timeout_timer);
+
+ if (NULL == group->gp_running_job)
+ {
+ /* Nothing to do */
+ return;
+ }
+
+ mali_gp_update_performance_counters(group->gp_core, group->gp_running_job, suspend);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ if (suspend)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
+ mali_gp_job_get_perf_counter_value0(group->gp_running_job),
+ mali_gp_job_get_perf_counter_value1(group->gp_running_job),
+ mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
+ 0, 0);
+ }
+ else
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0),
+ mali_gp_job_get_perf_counter_value0(group->gp_running_job),
+ mali_gp_job_get_perf_counter_value1(group->gp_running_job),
+ mali_gp_job_get_perf_counter_src0(group->gp_running_job) | (mali_gp_job_get_perf_counter_src1(group->gp_running_job) << 8),
+ 0, 0);
+
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ mali_group_report_l2_cache_counters_per_core(group, 0);
+ }
+#endif
+
+ mali_gp_job_set_current_heap_addr(group->gp_running_job,
+ mali_gp_read_plbu_alloc_start_addr(group->gp_core));
+}
+
+_mali_osk_errcode_t mali_group_upper_half_pp(void *data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_pp_core *core = group->pp_core;
+ u32 irq_readout;
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_FALSE == mali_pm_domain_lock_state(group->pm_domain))
+ {
+ goto out;
+ }
+#endif
+
+ /*
+ * For Mali-450 there is one particular case we need to watch out for:
+ *
+ * Criteria 1) this function call can be due to a shared interrupt,
+ * and not necessary because this core signaled an interrupt.
+ * Criteria 2) this core is a part of a virtual group, and thus it should
+ * not do any post processing.
+ * Criteria 3) this core has actually indicated that is has completed by
+ * having set raw_stat/int_stat registers to != 0
+ *
+ * If all this criteria is meet, then we could incorrectly start post
+ * processing on the wrong group object (this should only happen on the
+ * parent group)
+ */
+#if !defined(MALI_UPPER_HALF_SCHEDULING)
+ if (mali_group_is_in_virtual(group))
+ {
+ /*
+ * This check is done without the group lock held, which could lead to
+ * a potential race. This is however ok, since we will safely re-check
+ * this with the group lock held at a later stage. This is just an
+ * early out which will strongly benefit shared IRQ systems.
+ */
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+#endif
+
+ irq_readout = mali_pp_get_int_stat(core);
+ if (MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_pp_mask_all_interrupts(core);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ /* Currently no support for this interrupt event for the virtual PP core */
+ if (!mali_group_is_virtual(group))
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id) |
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT,
+ irq_readout, 0, 0, 0, 0);
+ }
+#endif
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ /* Check if job is complete without errors */
+ if (MALI200_REG_VAL_IRQ_END_OF_FRAME == irq_readout)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler from upper half\n"));
+
+ mali_group_lock(group);
+
+ /* Check if job is complete without errors, again, after taking the group lock */
+ irq_readout = mali_pp_read_rawstat(core);
+ if (MALI200_REG_VAL_IRQ_END_OF_FRAME != irq_readout)
+ {
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+ if (mali_group_is_virtual(group))
+ {
+ u32 status_readout = mali_pp_read_status(group->pp_core);
+ if (status_readout & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)
+ {
+ MALI_DEBUG_PRINT(6, ("Mali PP: Not all cores in broadcast completed\n"));
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+ }
+
+ if (mali_group_is_in_virtual(group))
+ {
+ /* We're member of a virtual group, so interrupt should be handled by the virtual group */
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+ err = _MALI_OSK_ERR_FAULT;
+ goto out;
+ }
+
+ group->core_timed_out = MALI_FALSE;
+ mali_group_complete_pp(group, MALI_TRUE);
+ /* No need to enable interrupts again, since the core will be reset while completing the job */
+
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF,
+ 0, 0, MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+#endif
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
+ err = _MALI_OSK_ERR_OK;
+ goto out;
+ }
+
+out:
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ mali_pm_domain_unlock_state(group->pm_domain);
+#endif
+
+ return err;
+}
+
+static void mali_group_bottom_half_pp(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+ struct mali_pp_core *core = group->pp_core;
+ u32 irq_readout;
+ u32 irq_errors;
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(core->core_id), 0, 0);
+
+ mali_group_lock(group);
+
+ if (mali_group_is_in_virtual(group))
+ {
+ /* We're member of a virtual group, so interrupt should be handled by the virtual group */
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ if ( MALI_FALSE == mali_group_power_is_on(group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", mali_pp_get_hw_core_desc(core)));
+ mali_group_unlock(group);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ irq_readout = mali_pp_read_rawstat(group->pp_core);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, mali_pp_get_hw_core_desc(group->pp_core)));
+
+ /* Check if job is complete without errors */
+ if (MALI200_REG_VAL_IRQ_END_OF_FRAME == irq_readout)
+ {
+ if (mali_group_is_virtual(group))
+ {
+ u32 status_readout = mali_pp_read_status(group->pp_core);
+
+ if (status_readout & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)
+ {
+ MALI_DEBUG_PRINT(6, ("Mali PP: Not all cores in broadcast completed\n"));
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
+ group->core_timed_out = MALI_FALSE;
+ mali_group_complete_pp(group, MALI_TRUE);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ /*
+ * Now lets look at the possible error cases (IRQ indicating error or timeout)
+ * END_OF_FRAME and HANG interrupts are not considered error.
+ */
+ irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG);
+ if (0 != irq_errors)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Unexpected interrupt 0x%08X from core %s, aborting job\n",
+ irq_readout, mali_pp_get_hw_core_desc(group->pp_core)));
+ group->core_timed_out = MALI_FALSE;
+ mali_group_complete_pp(group, MALI_FALSE);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+ else if (group->core_timed_out) /* SW timeout */
+ {
+ group->core_timed_out = MALI_FALSE;
+ if (!_mali_osk_timer_pending(group->timeout_timer) && NULL != group->pp_running_job)
+ {
+ MALI_PRINT(("Mali PP: Job %d timed out on core %s\n",
+ mali_pp_job_get_id(group->pp_running_job), mali_pp_get_hw_core_desc(core)));
+ mali_group_complete_pp(group, MALI_FALSE);
+ mali_group_unlock(group);
+ }
+ else
+ {
+ mali_group_unlock(group);
+ }
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+ return;
+ }
+
+ /*
+ * We should never get here, re-enable interrupts and continue
+ */
+ if (0 == irq_readout)
+ {
+ MALI_DEBUG_PRINT(3, ("Mali group: No interrupt found on core %s\n",
+ mali_pp_get_hw_core_desc(group->pp_core)));
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali group: Unhandled PP interrupt 0x%08X on %s\n", irq_readout,
+ mali_pp_get_hw_core_desc(group->pp_core)));
+ }
+ mali_pp_enable_interrupts(core);
+ mali_group_unlock(group);
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF,
+ 0, _mali_osk_get_tid(), 0, 0, 0);
+}
+
+static void mali_group_post_process_job_pp(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ /* Stop the timeout timer. */
+ _mali_osk_timer_del_async(group->timeout_timer);
+
+ if (NULL != group->pp_running_job)
+ {
+ if (MALI_TRUE == mali_group_is_virtual(group))
+ {
+ struct mali_group *child;
+ struct mali_group *temp;
+
+ /* update performance counters from each physical pp core within this virtual group */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ mali_pp_update_performance_counters(group->pp_core, child->pp_core, group->pp_running_job, mali_pp_core_get_id(child->pp_core));
+ }
+
+#if defined(CONFIG_MALI400_PROFILING)
+ /* send profiling data per physical core */
+ _MALI_OSK_LIST_FOREACHENTRY(child, temp, &group->group_list, struct mali_group, group_list)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(child->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL,
+ mali_pp_job_get_perf_counter_value0(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
+ mali_pp_job_get_perf_counter_value1(group->pp_running_job, mali_pp_core_get_id(child->pp_core)),
+ mali_pp_job_get_perf_counter_src0(group->pp_running_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job) << 8),
+ 0, 0);
+ }
+ if (0 != group->l2_cache_core_ref_count[0])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+ }
+ if (0 != group->l2_cache_core_ref_count[1])
+ {
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[1])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[1])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[1]));
+ }
+ }
+
+#endif
+ }
+ else
+ {
+ /* update performance counters for a physical group's pp core */
+ mali_pp_update_performance_counters(group->pp_core, group->pp_core, group->pp_running_job, group->pp_running_sub_job);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|
+ MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(mali_pp_core_get_id(group->pp_core))|
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL,
+ mali_pp_job_get_perf_counter_value0(group->pp_running_job, group->pp_running_sub_job),
+ mali_pp_job_get_perf_counter_value1(group->pp_running_job, group->pp_running_sub_job),
+ mali_pp_job_get_perf_counter_src0(group->pp_running_job) | (mali_pp_job_get_perf_counter_src1(group->pp_running_job) << 8),
+ 0, 0);
+ if ((MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src0(group->l2_cache_core[0])) &&
+ (MALI_HW_CORE_NO_COUNTER != mali_l2_cache_core_get_counter_src1(group->l2_cache_core[0])))
+ {
+ mali_group_report_l2_cache_counters_per_core(group, mali_l2_cache_get_id(group->l2_cache_core[0]));
+ }
+#endif
+ }
+ }
+}
+
+static void mali_group_timeout(void *data)
+{
+ struct mali_group *group = (struct mali_group *)data;
+
+ group->core_timed_out = MALI_TRUE;
+
+ if (NULL != group->gp_core)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali group: TIMEOUT on %s\n", mali_gp_get_hw_core_desc(group->gp_core)));
+ _mali_osk_wq_schedule_work(group->bottom_half_work_gp);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Mali group: TIMEOUT on %s\n", mali_pp_get_hw_core_desc(group->pp_core)));
+ _mali_osk_wq_schedule_work(group->bottom_half_work_pp);
+ }
+}
+
+void mali_group_zap_session(struct mali_group *group, struct mali_session_data *session)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ /* Early out - safe even if mutex is not held */
+ if (group->session != session) return;
+
+ mali_group_lock(group);
+
+ mali_group_remove_session_if_unused(group, session);
+
+ if (group->session == session)
+ {
+ /* The Zap also does the stall and disable_stall */
+ mali_bool zap_success = mali_mmu_zap_tlb(group->mmu);
+ if (MALI_TRUE != zap_success)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n"));
+ mali_group_mmu_page_fault(group);
+ }
+ }
+
+ mali_group_unlock(group);
+}
+
+#if defined(CONFIG_MALI400_PROFILING)
+static void mali_group_report_l2_cache_counters_per_core(struct mali_group *group, u32 core_num)
+{
+ u32 source0 = 0;
+ u32 value0 = 0;
+ u32 source1 = 0;
+ u32 value1 = 0;
+ u32 profiling_channel = 0;
+
+ switch(core_num)
+ {
+ case 0: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
+ break;
+ case 1: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS;
+ break;
+ case 2: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS;
+ break;
+ default: profiling_channel = MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS;
+ break;
+ }
+
+ if (0 == core_num)
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
+ }
+ if (1 == core_num)
+ {
+ if (1 == mali_l2_cache_get_id(group->l2_cache_core[0]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
+ }
+ else if (1 == mali_l2_cache_get_id(group->l2_cache_core[1]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
+ }
+ }
+ if (2 == core_num)
+ {
+ if (2 == mali_l2_cache_get_id(group->l2_cache_core[0]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[0], &source0, &value0, &source1, &value1);
+ }
+ else if (2 == mali_l2_cache_get_id(group->l2_cache_core[1]))
+ {
+ mali_l2_cache_core_get_counter_values(group->l2_cache_core[1], &source0, &value0, &source1, &value1);
+ }
+ }
+
+ _mali_osk_profiling_add_event(profiling_channel, source1 << 8 | source0, value0, value1, 0, 0);
+}
+#endif /* #if defined(CONFIG_MALI400_PROFILING) */
+
+mali_bool mali_group_is_enabled(struct mali_group *group)
+{
+ mali_bool enabled = MALI_TRUE;
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ mali_group_lock(group);
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ enabled = MALI_FALSE;
+ }
+ mali_group_unlock(group);
+
+ return enabled;
+}
+
+void mali_group_enable(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT( NULL != mali_group_get_pp_core(group)
+ || NULL != mali_group_get_gp_core(group));
+
+ if (NULL != mali_group_get_pp_core(group))
+ {
+ mali_pp_scheduler_enable_group(group);
+ }
+ else
+ {
+ mali_gp_scheduler_enable_group(group);
+ }
+}
+
+void mali_group_disable(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT( NULL != mali_group_get_pp_core(group)
+ || NULL != mali_group_get_gp_core(group));
+
+ if (NULL != mali_group_get_pp_core(group))
+ {
+ mali_pp_scheduler_disable_group(group);
+ }
+ else
+ {
+ mali_gp_scheduler_disable_group(group);
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_group.h b/drivers/gpu/mali400/r3p2/mali/common/mali_group.h
new file mode 100644
index 0000000..6a6a777
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_group.h
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_GROUP_H__
+#define __MALI_GROUP_H__
+
+#include "linux/jiffies.h"
+#include "mali_osk.h"
+#include "mali_l2_cache.h"
+#include "mali_mmu.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_session.h"
+
+/* max runtime [ms] for a core job - used by timeout timers */
+#define MAX_RUNTIME 5000
+/** @brief A mali group object represents a MMU and a PP and/or a GP core.
+ *
+ */
+#define MALI_MAX_NUMBER_OF_GROUPS 10
+
+enum mali_group_core_state
+{
+ MALI_GROUP_STATE_IDLE,
+ MALI_GROUP_STATE_WORKING,
+ MALI_GROUP_STATE_OOM,
+ MALI_GROUP_STATE_IN_VIRTUAL,
+ MALI_GROUP_STATE_JOINING_VIRTUAL,
+ MALI_GROUP_STATE_LEAVING_VIRTUAL,
+ MALI_GROUP_STATE_DISABLED,
+};
+
+/* Forward declaration from mali_pm_domain.h */
+struct mali_pm_domain;
+
+/**
+ * The structure represents a render group
+ * A render group is defined by all the cores that share the same Mali MMU
+ */
+
+struct mali_group
+{
+ struct mali_mmu_core *mmu;
+ struct mali_session_data *session;
+ int page_dir_ref_count;
+
+ mali_bool power_is_on;
+ enum mali_group_core_state state;
+
+ struct mali_gp_core *gp_core;
+ struct mali_gp_job *gp_running_job;
+
+ struct mali_pp_core *pp_core;
+ struct mali_pp_job *pp_running_job;
+ u32 pp_running_sub_job;
+
+ struct mali_l2_cache_core *l2_cache_core[2];
+ u32 l2_cache_core_ref_count[2];
+
+ struct mali_dlbu_core *dlbu_core;
+ struct mali_bcast_unit *bcast_core;
+
+ _mali_osk_lock_t *lock;
+
+ _mali_osk_list_t pp_scheduler_list;
+
+ /* List used for virtual groups. For a virtual group, the list represents the
+ * head element. */
+ _mali_osk_list_t group_list;
+
+ struct mali_group *pm_domain_list;
+ struct mali_pm_domain *pm_domain;
+
+ /* Parent virtual group (if any) */
+ struct mali_group *parent_group;
+
+ _mali_osk_wq_work_t *bottom_half_work_mmu;
+ _mali_osk_wq_work_t *bottom_half_work_gp;
+ _mali_osk_wq_work_t *bottom_half_work_pp;
+
+ _mali_osk_timer_t *timeout_timer;
+ mali_bool core_timed_out;
+};
+
+/** @brief Create a new Mali group object
+ *
+ * @param cluster Pointer to the cluster to which the group is connected.
+ * @param mmu Pointer to the MMU that defines this group
+ * @return A pointer to a new group object
+ */
+struct mali_group *mali_group_create(struct mali_l2_cache_core *core,
+ struct mali_dlbu_core *dlbu,
+ struct mali_bcast_unit *bcast);
+
+_mali_osk_errcode_t mali_group_add_mmu_core(struct mali_group *group, struct mali_mmu_core* mmu_core);
+void mali_group_remove_mmu_core(struct mali_group *group);
+
+_mali_osk_errcode_t mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core);
+void mali_group_remove_gp_core(struct mali_group *group);
+
+_mali_osk_errcode_t mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core);
+void mali_group_remove_pp_core(struct mali_group *group);
+
+void mali_group_set_pm_domain(struct mali_group *group, struct mali_pm_domain *domain);
+
+void mali_group_delete(struct mali_group *group);
+
+/** @brief Virtual groups */
+void mali_group_add_group(struct mali_group *parent, struct mali_group *child, mali_bool update_hw);
+void mali_group_remove_group(struct mali_group *parent, struct mali_group *child);
+struct mali_group *mali_group_acquire_group(struct mali_group *parent);
+
+MALI_STATIC_INLINE mali_bool mali_group_is_virtual(struct mali_group *group)
+{
+ return (NULL != group->dlbu_core);
+}
+
+/** @brief Check if a group is considered as part of a virtual group
+ *
+ * @note A group is considered to be "part of" a virtual group also during the transition
+ * in to / out of the virtual group.
+ */
+MALI_STATIC_INLINE mali_bool mali_group_is_in_virtual(struct mali_group *group)
+{
+ return (MALI_GROUP_STATE_IN_VIRTUAL == group->state ||
+ MALI_GROUP_STATE_JOINING_VIRTUAL == group->state ||
+ MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state);
+}
+
+/** @brief Reset group
+ *
+ * This function will reset the entire group, including all the cores present in the group.
+ *
+ * @param group Pointer to the group to reset
+ */
+void mali_group_reset(struct mali_group *group);
+
+/** @brief Zap MMU TLB on all groups
+ *
+ * Zap TLB on group if \a session is active.
+ */
+void mali_group_zap_session(struct mali_group* group, struct mali_session_data *session);
+
+/** @brief Get pointer to GP core object
+ */
+struct mali_gp_core* mali_group_get_gp_core(struct mali_group *group);
+
+/** @brief Get pointer to PP core object
+ */
+struct mali_pp_core* mali_group_get_pp_core(struct mali_group *group);
+
+/** @brief Lock group object
+ *
+ * Most group functions will lock the group object themselves. The expection is
+ * the group_bottom_half which requires the group to be locked on entry.
+ *
+ * @param group Pointer to group to lock
+ */
+void mali_group_lock(struct mali_group *group);
+
+/** @brief Unlock group object
+ *
+ * @param group Pointer to group to unlock
+ */
+void mali_group_unlock(struct mali_group *group);
+#ifdef DEBUG
+void mali_group_assert_locked(struct mali_group *group);
+#define MALI_ASSERT_GROUP_LOCKED(group) mali_group_assert_locked(group)
+#else
+#define MALI_ASSERT_GROUP_LOCKED(group)
+#endif
+
+/** @brief Start GP job
+ */
+void mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
+/** @brief Start fragment of PP job
+ */
+void mali_group_start_pp_job(struct mali_group *group, struct mali_pp_job *job, u32 sub_job);
+
+/** @brief Resume GP job that suspended waiting for more heap memory
+ */
+struct mali_gp_job *mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr);
+/** @brief Abort GP job
+ *
+ * Used to abort suspended OOM jobs when user space failed to allocte more memory.
+ */
+void mali_group_abort_gp_job(struct mali_group *group, u32 job_id);
+/** @brief Abort all GP jobs from \a session
+ *
+ * Used on session close when terminating all running and queued jobs from \a session.
+ */
+void mali_group_abort_session(struct mali_group *group, struct mali_session_data *session);
+
+mali_bool mali_group_power_is_on(struct mali_group *group);
+void mali_group_power_on_group(struct mali_group *group);
+void mali_group_power_off_group(struct mali_group *group);
+void mali_group_power_on(void);
+void mali_group_power_off(void);
+
+struct mali_group *mali_group_get_glob_group(u32 index);
+u32 mali_group_get_glob_num_groups(void);
+
+u32 mali_group_dump_state(struct mali_group *group, char *buf, u32 size);
+
+/* MMU-related functions */
+_mali_osk_errcode_t mali_group_upper_half_mmu(void * data);
+
+/* GP-related functions */
+_mali_osk_errcode_t mali_group_upper_half_gp(void *data);
+
+/* PP-related functions */
+_mali_osk_errcode_t mali_group_upper_half_pp(void *data);
+
+/** @brief Check if group is enabled
+ *
+ * @param group group to check
+ * @return MALI_TRUE if enabled, MALI_FALSE if not
+ */
+mali_bool mali_group_is_enabled(struct mali_group *group);
+
+/** @brief Enable group
+ *
+ * An enabled job is put on the idle scheduler list and can be used to handle jobs. Does nothing if
+ * group is already enabled.
+ *
+ * @param group group to enable
+ */
+void mali_group_enable(struct mali_group *group);
+
+/** @brief Disable group
+ *
+ * A disabled group will no longer be used by the scheduler. If part of a virtual group, the group
+ * will be removed before being disabled. Cores part of a disabled group is safe to power down.
+ *
+ * @param group group to disable
+ */
+void mali_group_disable(struct mali_group *group);
+
+MALI_STATIC_INLINE mali_bool mali_group_virtual_disable_if_empty(struct mali_group *group)
+{
+ mali_bool empty = MALI_FALSE;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
+
+ if (_mali_osk_list_empty(&group->group_list))
+ {
+ group->state = MALI_GROUP_STATE_DISABLED;
+ group->session = NULL;
+
+ empty = MALI_TRUE;
+ }
+
+ return empty;
+}
+
+MALI_STATIC_INLINE mali_bool mali_group_virtual_enable_if_empty(struct mali_group *group)
+{
+ mali_bool empty = MALI_FALSE;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+ MALI_DEBUG_ASSERT(mali_group_is_virtual(group));
+
+ if (_mali_osk_list_empty(&group->group_list))
+ {
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ empty = MALI_TRUE;
+ }
+
+ return empty;
+}
+
+#endif /* __MALI_GROUP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c
new file mode 100644
index 0000000..c3a9c8b
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_hw_core.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size)
+{
+ core->phys_addr = resource->base;
+ core->description = resource->description;
+ core->size = reg_size;
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_mem_reqregion(core->phys_addr, core->size, core->description))
+ {
+ core->mapped_registers = _mali_osk_mem_mapioregion(core->phys_addr, core->size, core->description);
+ if (NULL != core->mapped_registers)
+ {
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to map memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr));
+ }
+ _mali_osk_mem_unreqregion(core->phys_addr, core->size);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to request memory region for core %s at phys_addr 0x%08X\n", core->description, core->phys_addr));
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_hw_core_delete(struct mali_hw_core *core)
+{
+ _mali_osk_mem_unmapioregion(core->phys_addr, core->size, core->mapped_registers);
+ core->mapped_registers = NULL;
+ _mali_osk_mem_unreqregion(core->phys_addr, core->size);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h
new file mode 100644
index 0000000..e687f60
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_hw_core.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_HW_CORE_H__
+#define __MALI_HW_CORE_H__
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+/**
+ * The common parts for all Mali HW cores (GP, PP, MMU, L2 and PMU)
+ * This struct is embedded inside all core specific structs.
+ */
+struct mali_hw_core
+{
+ u32 phys_addr; /**< Physical address of the registers */
+ u32 size; /**< Size of registers */
+ mali_io_address mapped_registers; /**< Virtual mapping of the registers */
+ const char* description; /**< Name of unit (as specified in device configuration) */
+};
+
+#define MALI_REG_POLL_COUNT_FAST 1000
+#define MALI_REG_POLL_COUNT_SLOW 1000000
+
+_mali_osk_errcode_t mali_hw_core_create(struct mali_hw_core *core, const _mali_osk_resource_t *resource, u32 reg_size);
+void mali_hw_core_delete(struct mali_hw_core *core);
+
+MALI_STATIC_INLINE u32 mali_hw_core_register_read(struct mali_hw_core *core, u32 relative_address)
+{
+ u32 read_val;
+ read_val = _mali_osk_mem_ioread32(core->mapped_registers, relative_address);
+ MALI_DEBUG_PRINT(6, ("register_read for core %s, relative addr=0x%04X, val=0x%08X\n",
+ core->description, relative_address, read_val));
+ return read_val;
+}
+
+MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed(struct mali_hw_core *core, u32 relative_address, u32 new_val)
+{
+ MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n",
+ core->description, relative_address, new_val));
+ _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
+}
+
+/* Conditionally write a register.
+ * The register will only be written if the new value is different from the old_value.
+ * If the new value is different, the old value will also be updated */
+MALI_STATIC_INLINE void mali_hw_core_register_write_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 new_val, const u32 old_val)
+{
+ MALI_DEBUG_PRINT(6, ("register_write_relaxed for core %s, relative addr=0x%04X, val=0x%08X\n",
+ core->description, relative_address, new_val));
+ if(old_val != new_val)
+ {
+ _mali_osk_mem_iowrite32_relaxed(core->mapped_registers, relative_address, new_val);
+ }
+}
+
+
+MALI_STATIC_INLINE void mali_hw_core_register_write(struct mali_hw_core *core, u32 relative_address, u32 new_val)
+{
+ MALI_DEBUG_PRINT(6, ("register_write for core %s, relative addr=0x%04X, val=0x%08X\n",
+ core->description, relative_address, new_val));
+ _mali_osk_mem_iowrite32(core->mapped_registers, relative_address, new_val);
+}
+
+MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs)
+{
+ u32 i;
+ MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n",
+ core->description,relative_address, nr_of_regs));
+
+ /* Do not use burst writes against the registers */
+ for (i = 0; i< nr_of_regs; i++)
+ {
+ mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
+ }
+}
+
+/* Conditionally write a set of registers.
+ * The register will only be written if the new value is different from the old_value.
+ * If the new value is different, the old value will also be updated */
+MALI_STATIC_INLINE void mali_hw_core_register_write_array_relaxed_conditional(struct mali_hw_core *core, u32 relative_address, u32 *write_array, u32 nr_of_regs, const u32* old_array)
+{
+ u32 i;
+ MALI_DEBUG_PRINT(6, ("register_write_array: for core %s, relative addr=0x%04X, nr of regs=%u\n",
+ core->description,relative_address, nr_of_regs));
+
+ /* Do not use burst writes against the registers */
+ for (i = 0; i< nr_of_regs; i++)
+ {
+ if(old_array[i] != write_array[i])
+ {
+ mali_hw_core_register_write_relaxed(core, relative_address + i*4, write_array[i]);
+ }
+ }
+}
+
+#endif /* __MALI_HW_CORE_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h
new file mode 100644
index 0000000..3376a07
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_common.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_COMMON_H__
+#define __MALI_KERNEL_COMMON_H__
+
+#include "mali_osk.h"
+
+/* Make sure debug is defined when it should be */
+#ifndef DEBUG
+ #if defined(_DEBUG)
+ #define DEBUG
+ #endif
+#endif
+
+/* MALI_SEC */
+/* Macro for generating a kernel panic.
+ * Turned on off by compile-time Makefile settings
+ */
+#if defined(USING_KERNEL_PANIC)
+#include <linux/kernel.h>
+ #define MALI_PANIC(fmt, args...) panic( fmt, ## args );
+#else
+ #define MALI_PANIC(fmt, args...)
+#endif
+
+/* The file include several useful macros for error checking, debugging and printing.
+ * - MALI_PRINTF(...) Do not use this function: Will be included in Release builds.
+ * - MALI_DEBUG_PRINT(nr, (X) ) Prints the second argument if nr<=MALI_DEBUG_LEVEL.
+ * - MALI_DEBUG_ERROR( (X) ) Prints an errortext, a source trace, and the given error message.
+ * - MALI_DEBUG_ASSERT(exp,(X)) If the asserted expr is false, the program will exit.
+ * - MALI_DEBUG_ASSERT_POINTER(pointer) Triggers if the pointer is a zero pointer.
+ * - MALI_DEBUG_CODE( X ) The code inside the macro is only compiled in Debug builds.
+ *
+ * The (X) means that you must add an extra parenthesis around the argumentlist.
+ *
+ * The printf function: MALI_PRINTF(...) is routed to _mali_osk_debugmsg
+ *
+ * Suggested range for the DEBUG-LEVEL is [1:6] where
+ * [1:2] Is messages with highest priority, indicate possible errors.
+ * [3:4] Is messages with medium priority, output important variables.
+ * [5:6] Is messages with low priority, used during extensive debugging.
+ */
+
+ /**
+ * Fundamental error macro. Reports an error code. This is abstracted to allow us to
+ * easily switch to a different error reporting method if we want, and also to allow
+ * us to search for error returns easily.
+ *
+ * Note no closing semicolon - this is supplied in typical usage:
+ *
+ * MALI_ERROR(MALI_ERROR_OUT_OF_MEMORY);
+ */
+#define MALI_ERROR(error_code) return (error_code)
+
+/**
+ * Basic error macro, to indicate success.
+ * Note no closing semicolon - this is supplied in typical usage:
+ *
+ * MALI_SUCCESS;
+ */
+#define MALI_SUCCESS MALI_ERROR(_MALI_OSK_ERR_OK)
+
+/**
+ * Basic error macro. This checks whether the given condition is true, and if not returns
+ * from this function with the supplied error code. This is a macro so that we can override it
+ * for stress testing.
+ *
+ * Note that this uses the do-while-0 wrapping to ensure that we don't get problems with dangling
+ * else clauses. Note also no closing semicolon - this is supplied in typical usage:
+ *
+ * MALI_CHECK((p!=NULL), ERROR_NO_OBJECT);
+ */
+#define MALI_CHECK(condition, error_code) do { if(!(condition)) MALI_ERROR(error_code); } while(0)
+
+/**
+ * Error propagation macro. If the expression given is anything other than _MALI_OSK_NO_ERROR,
+ * then the value is returned from the enclosing function as an error code. This effectively
+ * acts as a guard clause, and propagates error values up the call stack. This uses a
+ * temporary value to ensure that the error expression is not evaluated twice.
+ * If the counter for forcing a failure has been set using _mali_force_error, this error will be
+ * returned without evaluating the expression in MALI_CHECK_NO_ERROR
+ */
+#define MALI_CHECK_NO_ERROR(expression) \
+ do { _mali_osk_errcode_t _check_no_error_result=(expression); \
+ if(_check_no_error_result != _MALI_OSK_ERR_OK) \
+ MALI_ERROR(_check_no_error_result); \
+ } while(0)
+
+/**
+ * Pointer check macro. Checks non-null pointer.
+ */
+#define MALI_CHECK_NON_NULL(pointer, error_code) MALI_CHECK( ((pointer)!=NULL), (error_code) )
+
+/**
+ * Error macro with goto. This checks whether the given condition is true, and if not jumps
+ * to the specified label using a goto. The label must therefore be local to the function in
+ * which this macro appears. This is most usually used to execute some clean-up code before
+ * exiting with a call to ERROR.
+ *
+ * Like the other macros, this is a macro to allow us to override the condition if we wish,
+ * e.g. to force an error during stress testing.
+ */
+#define MALI_CHECK_GOTO(condition, label) do { if(!(condition)) goto label; } while(0)
+
+/**
+ * Explicitly ignore a parameter passed into a function, to suppress compiler warnings.
+ * Should only be used with parameter names.
+ */
+#define MALI_IGNORE(x) x=x
+
+#define MALI_PRINTF(args) _mali_osk_dbgmsg args;
+
+#define MALI_PRINT_ERROR(args) do{ \
+ MALI_PRINTF(("Mali: ERR: %s\n" ,__FILE__)); \
+ MALI_PRINTF((" %s()%4d\n ", __FUNCTION__, __LINE__)) ; \
+ MALI_PRINTF(args); \
+ MALI_PRINTF(("\n")); \
+ } while(0)
+
+#define MALI_PRINT(args) do{ \
+ MALI_PRINTF(("Mali: ")); \
+ MALI_PRINTF(args); \
+ } while (0)
+
+#ifdef DEBUG
+#ifndef mali_debug_level
+extern int mali_debug_level;
+#endif
+
+#define MALI_DEBUG_CODE(code) code
+#define MALI_DEBUG_PRINT(level, args) do { \
+ if((level) <= mali_debug_level)\
+ {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); } \
+ } while (0)
+
+#define MALI_DEBUG_PRINT_ERROR(args) MALI_PRINT_ERROR(args)
+
+#define MALI_DEBUG_PRINT_IF(level,condition,args) \
+ if((condition)&&((level) <= mali_debug_level))\
+ {MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); }
+
+#define MALI_DEBUG_PRINT_ELSE(level, args)\
+ else if((level) <= mali_debug_level)\
+ { MALI_PRINTF(("Mali<" #level ">: ")); MALI_PRINTF(args); }
+
+/**
+ * @note these variants of DEBUG ASSERTS will cause a debugger breakpoint
+ * to be entered (see _mali_osk_break() ). An alternative would be to call
+ * _mali_osk_abort(), on OSs that support it.
+ */
+#define MALI_DEBUG_PRINT_ASSERT(condition, args) do {if( !(condition)) { MALI_PRINT_ERROR(args); _mali_osk_break(); } } while(0)
+#define MALI_DEBUG_ASSERT_POINTER(pointer) do {if( (pointer)== NULL) {MALI_PRINT_ERROR(("NULL pointer " #pointer)); _mali_osk_break();} } while(0)
+#define MALI_DEBUG_ASSERT(condition) do {if( !(condition)) {MALI_PRINT_ERROR(("ASSERT failed: " #condition )); _mali_osk_break();} } while(0)
+
+#else /* DEBUG */
+
+#define MALI_DEBUG_CODE(code)
+#define MALI_DEBUG_PRINT(string,args) do {} while(0)
+#define MALI_DEBUG_PRINT_ERROR(args) do {} while(0)
+#define MALI_DEBUG_PRINT_IF(level,condition,args) do {} while(0)
+#define MALI_DEBUG_PRINT_ELSE(level,condition,args) do {} while(0)
+#define MALI_DEBUG_PRINT_ASSERT(condition,args) do {} while(0)
+#define MALI_DEBUG_ASSERT_POINTER(pointer) do {} while(0)
+#define MALI_DEBUG_ASSERT(condition) do {} while(0)
+
+#endif /* DEBUG */
+
+/**
+ * variables from user space cannot be dereferenced from kernel space; tagging them
+ * with __user allows the GCC compiler to generate a warning. Other compilers may
+ * not support this so we define it here as an empty macro if the compiler doesn't
+ * define it.
+ */
+#ifndef __user
+#define __user
+#endif
+
+#endif /* __MALI_KERNEL_COMMON_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c
new file mode 100644
index 0000000..5680374
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.c
@@ -0,0 +1,1293 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+#include "mali_kernel_core.h"
+#include "mali_memory.h"
+#include "mali_mem_validation.h"
+#include "mali_mmu.h"
+#include "mali_mmu_page_directory.h"
+#include "mali_dlbu.h"
+#include "mali_broadcast.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_pmu.h"
+#include "mali_scheduler.h"
+#include "mali_kernel_utilization.h"
+#include "mali_l2_cache.h"
+#include "mali_pm_domain.h"
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+#include "mali_profiling_internal.h"
+#endif
+
+
+/* Mali GPU memory. Real values come from module parameter or from device specific data */
+unsigned int mali_dedicated_mem_start = 0;
+unsigned int mali_dedicated_mem_size = 0;
+unsigned int mali_shared_mem_size = 0;
+
+/* Frame buffer memory to be accessible by Mali GPU */
+int mali_fb_start = 0;
+int mali_fb_size = 0;
+
+/** Start profiling from module load? */
+int mali_boot_profiling = 0;
+
+/** Limits for the number of PP cores behind each L2 cache. */
+int mali_max_pp_cores_group_1 = 0xFF;
+int mali_max_pp_cores_group_2 = 0xFF;
+
+int mali_inited_pp_cores_group_1 = 0;
+int mali_inited_pp_cores_group_2 = 0;
+
+static _mali_product_id_t global_product_id = _MALI_PRODUCT_ID_UNKNOWN;
+static u32 global_gpu_base_address = 0;
+static u32 global_gpu_major_version = 0;
+static u32 global_gpu_minor_version = 0;
+
+#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
+
+/* timer related */
+int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
+
+static _mali_osk_errcode_t mali_set_global_gpu_base_address(void)
+{
+ global_gpu_base_address = _mali_osk_resource_base_address();
+ if (0 == global_gpu_base_address)
+ {
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static u32 mali_get_bcast_id(_mali_osk_resource_t *resource_pp)
+{
+ switch (resource_pp->base - global_gpu_base_address)
+ {
+ case 0x08000:
+ case 0x20000: /* fall-through for aliased mapping */
+ return 0x01;
+ case 0x0A000:
+ case 0x22000: /* fall-through for aliased mapping */
+ return 0x02;
+ case 0x0C000:
+ case 0x24000: /* fall-through for aliased mapping */
+ return 0x04;
+ case 0x0E000:
+ case 0x26000: /* fall-through for aliased mapping */
+ return 0x08;
+ case 0x28000:
+ return 0x10;
+ case 0x2A000:
+ return 0x20;
+ case 0x2C000:
+ return 0x40;
+ case 0x2E000:
+ return 0x80;
+ default:
+ return 0;
+ }
+}
+
+static _mali_osk_errcode_t mali_parse_product_info(void)
+{
+ /*
+ * Mali-200 has the PP core first, while Mali-300, Mali-400 and Mali-450 have the GP core first.
+ * Look at the version register for the first PP core in order to determine the GPU HW revision.
+ */
+
+ u32 first_pp_offset;
+ _mali_osk_resource_t first_pp_resource;
+
+ /* Find out where the first PP core is located */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x8000, NULL))
+ {
+ /* Mali-300/400/450 */
+ first_pp_offset = 0x8000;
+ }
+ else
+ {
+ /* Mali-200 */
+ first_pp_offset = 0x0000;
+ }
+
+ /* Find the first PP core resource (again) */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + first_pp_offset, &first_pp_resource))
+ {
+ /* Create a dummy PP object for this core so that we can read the version register */
+ struct mali_group *group = mali_group_create(NULL, NULL, NULL);
+ if (NULL != group)
+ {
+ struct mali_pp_core *pp_core = mali_pp_create(&first_pp_resource, group, MALI_FALSE, mali_get_bcast_id(&first_pp_resource));
+ if (NULL != pp_core)
+ {
+ u32 pp_version = mali_pp_core_get_version(pp_core);
+ mali_group_delete(group);
+
+ global_gpu_major_version = (pp_version >> 8) & 0xFF;
+ global_gpu_minor_version = pp_version & 0xFF;
+
+ switch (pp_version >> 16)
+ {
+ case MALI200_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI200;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-200 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ MALI_PRINT_ERROR(("Mali-200 is not supported by this driver.\n"));
+ _mali_osk_abort();
+ break;
+ case MALI300_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI300;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-300 r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ case MALI400_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI400;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-400 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ case MALI450_PP_PRODUCT_ID:
+ global_product_id = _MALI_PRODUCT_ID_MALI450;
+ MALI_DEBUG_PRINT(2, ("Found Mali GPU Mali-450 MP r%up%u\n", global_gpu_major_version, global_gpu_minor_version));
+ break;
+ default:
+ MALI_DEBUG_PRINT(2, ("Found unknown Mali GPU (r%up%u)\n", global_gpu_major_version, global_gpu_minor_version));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to create initial PP object\n"));
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to create initial group object\n"));
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("First PP core not specified in config file\n"));
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+
+void mali_resource_count(u32 *pp_count, u32 *l2_count)
+{
+ *pp_count = 0;
+ *l2_count = 0;
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x08000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0A000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0C000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x0E000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x28000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2A000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2C000, NULL))
+ {
+ ++(*pp_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x2E000, NULL))
+ {
+ ++(*pp_count);
+ }
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x1000, NULL))
+ {
+ ++(*l2_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x10000, NULL))
+ {
+ ++(*l2_count);
+ }
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x11000, NULL))
+ {
+ ++(*l2_count);
+ }
+}
+
+static void mali_delete_groups(void)
+{
+ while (0 < mali_group_get_glob_num_groups())
+ {
+ mali_group_delete(mali_group_get_glob_group(0));
+ }
+}
+
+static void mali_delete_l2_cache_cores(void)
+{
+ while (0 < mali_l2_cache_core_get_glob_num_l2_cores())
+ {
+ mali_l2_cache_delete(mali_l2_cache_core_get_glob_l2_core(0));
+ }
+}
+
+static struct mali_l2_cache_core *mali_create_l2_cache_core(_mali_osk_resource_t *resource)
+{
+ struct mali_l2_cache_core *l2_cache = NULL;
+
+ if (NULL != resource)
+ {
+
+ MALI_DEBUG_PRINT(3, ("Found L2 cache %s\n", resource->description));
+
+ l2_cache = mali_l2_cache_create(resource);
+ if (NULL == l2_cache)
+ {
+ MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
+ return NULL;
+ }
+ }
+ MALI_DEBUG_PRINT(3, ("Created L2 cache core object\n"));
+
+ return l2_cache;
+}
+
+static _mali_osk_errcode_t mali_parse_config_l2_cache(void)
+{
+ struct mali_l2_cache_core *l2_cache = NULL;
+
+ if (mali_is_mali400())
+ {
+ _mali_osk_resource_t l2_resource;
+ if (_MALI_OSK_ERR_OK != _mali_osk_resource_find(global_gpu_base_address + 0x1000, &l2_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ l2_cache = mali_create_l2_cache_core(&l2_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+ else if (mali_is_mali450())
+ {
+ /*
+ * L2 for GP at 0x10000
+ * L2 for PP0-3 at 0x01000
+ * L2 for PP4-7 at 0x11000 (optional)
+ */
+
+ _mali_osk_resource_t l2_gp_resource;
+ _mali_osk_resource_t l2_pp_grp0_resource;
+ _mali_osk_resource_t l2_pp_grp1_resource;
+
+ /* Make cluster for GP's L2 */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x10000, &l2_gp_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for GP\n"));
+ l2_cache = mali_create_l2_cache_core(&l2_gp_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Make cluster for first PP core group */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x1000, &l2_pp_grp0_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 0\n"));
+ l2_cache = mali_create_l2_cache_core(&l2_pp_grp0_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_pm_domain_add_l2(MALI_PMU_M450_DOM1, l2_cache);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for PP group 0 in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Second PP core group is optional, don't fail if we don't find it */
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x11000, &l2_pp_grp1_resource))
+ {
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 L2 cache core for PP group 1\n"));
+ l2_cache = mali_create_l2_cache_core(&l2_pp_grp1_resource);
+ if (NULL == l2_cache)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_pm_domain_add_l2(MALI_PMU_M450_DOM3, l2_cache);
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static struct mali_group *mali_create_group(struct mali_l2_cache_core *cache,
+ _mali_osk_resource_t *resource_mmu,
+ _mali_osk_resource_t *resource_gp,
+ _mali_osk_resource_t *resource_pp)
+{
+ struct mali_mmu_core *mmu;
+ struct mali_group *group;
+
+ MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
+
+ /* Create the group object */
+ group = mali_group_create(cache, NULL, NULL);
+ if (NULL == group)
+ {
+ MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
+ return NULL;
+ }
+
+ /* Create the MMU object inside group */
+ mmu = mali_mmu_create(resource_mmu, group, MALI_FALSE);
+ if (NULL == mmu)
+ {
+ MALI_PRINT_ERROR(("Failed to create MMU object\n"));
+ mali_group_delete(group);
+ return NULL;
+ }
+
+ if (NULL != resource_gp)
+ {
+ /* Create the GP core object inside this group */
+ struct mali_gp_core *gp_core = mali_gp_create(resource_gp, group);
+ if (NULL == gp_core)
+ {
+ /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
+ MALI_PRINT_ERROR(("Failed to create GP object\n"));
+ mali_group_delete(group);
+ return NULL;
+ }
+ }
+
+ if (NULL != resource_pp)
+ {
+ struct mali_pp_core *pp_core;
+
+ /* Create the PP core object inside this group */
+ pp_core = mali_pp_create(resource_pp, group, MALI_FALSE, mali_get_bcast_id(resource_pp));
+ if (NULL == pp_core)
+ {
+ /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
+ MALI_PRINT_ERROR(("Failed to create PP object\n"));
+ mali_group_delete(group);
+ return NULL;
+ }
+ }
+
+ /* Reset group */
+ mali_group_lock(group);
+ mali_group_reset(group);
+ mali_group_unlock(group);
+
+ return group;
+}
+
+static _mali_osk_errcode_t mali_create_virtual_group(_mali_osk_resource_t *resource_mmu_pp_bcast,
+ _mali_osk_resource_t *resource_pp_bcast,
+ _mali_osk_resource_t *resource_dlbu,
+ _mali_osk_resource_t *resource_bcast)
+{
+ struct mali_mmu_core *mmu_pp_bcast_core;
+ struct mali_pp_core *pp_bcast_core;
+ struct mali_dlbu_core *dlbu_core;
+ struct mali_bcast_unit *bcast_core;
+ struct mali_group *group;
+
+ MALI_DEBUG_PRINT(2, ("Starting new virtual group for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
+
+ /* Create the DLBU core object */
+ dlbu_core = mali_dlbu_create(resource_dlbu);
+ if (NULL == dlbu_core)
+ {
+ MALI_PRINT_ERROR(("Failed to create DLBU object \n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the Broadcast unit core */
+ bcast_core = mali_bcast_unit_create(resource_bcast);
+ if (NULL == bcast_core)
+ {
+ MALI_PRINT_ERROR(("Failed to create Broadcast unit object!\n"));
+ mali_dlbu_delete(dlbu_core);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the group object */
+ group = mali_group_create(NULL, dlbu_core, bcast_core);
+ if (NULL == group)
+ {
+ MALI_PRINT_ERROR(("Failed to create group object for MMU PP broadcast core %s\n", resource_mmu_pp_bcast->description));
+ mali_bcast_unit_delete(bcast_core);
+ mali_dlbu_delete(dlbu_core);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the MMU object inside group */
+ mmu_pp_bcast_core = mali_mmu_create(resource_mmu_pp_bcast, group, MALI_TRUE);
+ if (NULL == mmu_pp_bcast_core)
+ {
+ MALI_PRINT_ERROR(("Failed to create MMU PP broadcast object\n"));
+ mali_group_delete(group);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the PP core object inside this group */
+ pp_bcast_core = mali_pp_create(resource_pp_bcast, group, MALI_TRUE, 0);
+ if (NULL == pp_bcast_core)
+ {
+ /* No need to clean up now, as we will clean up everything linked in from the cluster when we fail this function */
+ MALI_PRINT_ERROR(("Failed to create PP object\n"));
+ mali_group_delete(group);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_groups(void)
+{
+ struct mali_group *group;
+ int cluster_id_gp = 0;
+ int cluster_id_pp_grp0 = 0;
+ int cluster_id_pp_grp1 = 0;
+ int i;
+
+ _mali_osk_resource_t resource_gp;
+ _mali_osk_resource_t resource_gp_mmu;
+ _mali_osk_resource_t resource_pp[8];
+ _mali_osk_resource_t resource_pp_mmu[8];
+ _mali_osk_resource_t resource_pp_mmu_bcast;
+ _mali_osk_resource_t resource_pp_bcast;
+ _mali_osk_resource_t resource_dlbu;
+ _mali_osk_resource_t resource_bcast;
+ _mali_osk_errcode_t resource_gp_found;
+ _mali_osk_errcode_t resource_gp_mmu_found;
+ _mali_osk_errcode_t resource_pp_found[8];
+ _mali_osk_errcode_t resource_pp_mmu_found[8];
+ _mali_osk_errcode_t resource_pp_mmu_bcast_found;
+ _mali_osk_errcode_t resource_pp_bcast_found;
+ _mali_osk_errcode_t resource_dlbu_found;
+ _mali_osk_errcode_t resource_bcast_found;
+
+ if (!(mali_is_mali400() || mali_is_mali450()))
+ {
+ /* No known HW core */
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ if (mali_is_mali450())
+ {
+ /* Mali-450 have separate L2s for GP, and PP core group(s) */
+ cluster_id_pp_grp0 = 1;
+ cluster_id_pp_grp1 = 2;
+ }
+
+ resource_gp_found = _mali_osk_resource_find(global_gpu_base_address + 0x00000, &resource_gp);
+ resource_gp_mmu_found = _mali_osk_resource_find(global_gpu_base_address + 0x03000, &resource_gp_mmu);
+ resource_pp_found[0] = _mali_osk_resource_find(global_gpu_base_address + 0x08000, &(resource_pp[0]));
+ resource_pp_found[1] = _mali_osk_resource_find(global_gpu_base_address + 0x0A000, &(resource_pp[1]));
+ resource_pp_found[2] = _mali_osk_resource_find(global_gpu_base_address + 0x0C000, &(resource_pp[2]));
+ resource_pp_found[3] = _mali_osk_resource_find(global_gpu_base_address + 0x0E000, &(resource_pp[3]));
+ resource_pp_found[4] = _mali_osk_resource_find(global_gpu_base_address + 0x28000, &(resource_pp[4]));
+ resource_pp_found[5] = _mali_osk_resource_find(global_gpu_base_address + 0x2A000, &(resource_pp[5]));
+ resource_pp_found[6] = _mali_osk_resource_find(global_gpu_base_address + 0x2C000, &(resource_pp[6]));
+ resource_pp_found[7] = _mali_osk_resource_find(global_gpu_base_address + 0x2E000, &(resource_pp[7]));
+ resource_pp_mmu_found[0] = _mali_osk_resource_find(global_gpu_base_address + 0x04000, &(resource_pp_mmu[0]));
+ resource_pp_mmu_found[1] = _mali_osk_resource_find(global_gpu_base_address + 0x05000, &(resource_pp_mmu[1]));
+ resource_pp_mmu_found[2] = _mali_osk_resource_find(global_gpu_base_address + 0x06000, &(resource_pp_mmu[2]));
+ resource_pp_mmu_found[3] = _mali_osk_resource_find(global_gpu_base_address + 0x07000, &(resource_pp_mmu[3]));
+ resource_pp_mmu_found[4] = _mali_osk_resource_find(global_gpu_base_address + 0x1C000, &(resource_pp_mmu[4]));
+ resource_pp_mmu_found[5] = _mali_osk_resource_find(global_gpu_base_address + 0x1D000, &(resource_pp_mmu[5]));
+ resource_pp_mmu_found[6] = _mali_osk_resource_find(global_gpu_base_address + 0x1E000, &(resource_pp_mmu[6]));
+ resource_pp_mmu_found[7] = _mali_osk_resource_find(global_gpu_base_address + 0x1F000, &(resource_pp_mmu[7]));
+
+
+ if (mali_is_mali450())
+ {
+ resource_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x13000, &resource_bcast);
+ resource_dlbu_found = _mali_osk_resource_find(global_gpu_base_address + 0x14000, &resource_dlbu);
+ resource_pp_mmu_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x15000, &resource_pp_mmu_bcast);
+ resource_pp_bcast_found = _mali_osk_resource_find(global_gpu_base_address + 0x16000, &resource_pp_bcast);
+
+ if (_MALI_OSK_ERR_OK != resource_bcast_found ||
+ _MALI_OSK_ERR_OK != resource_dlbu_found ||
+ _MALI_OSK_ERR_OK != resource_pp_mmu_bcast_found ||
+ _MALI_OSK_ERR_OK != resource_pp_bcast_found)
+ {
+ /* Missing mandatory core(s) for Mali-450 */
+ MALI_DEBUG_PRINT(2, ("Missing mandatory resources, Mali-450 needs DLBU, Broadcast unit, virtual PP core and virtual MMU\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ if (_MALI_OSK_ERR_OK != resource_gp_found ||
+ _MALI_OSK_ERR_OK != resource_gp_mmu_found ||
+ _MALI_OSK_ERR_OK != resource_pp_found[0] ||
+ _MALI_OSK_ERR_OK != resource_pp_mmu_found[0])
+ {
+ /* Missing mandatory core(s) */
+ MALI_DEBUG_PRINT(2, ("Missing mandatory resource, need at least one GP and one PP, both with a separate MMU\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ MALI_DEBUG_ASSERT(1 <= mali_l2_cache_core_get_glob_num_l2_cores());
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_gp), &resource_gp_mmu, &resource_gp, NULL);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create group for first (and mandatory) PP core */
+ MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[0], NULL, &resource_pp[0]);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ if (mali_is_mali450())
+ {
+ mali_pm_domain_add_group(MALI_PMU_M450_DOM1, group);
+ }
+ else
+ {
+ mali_pm_domain_add_group(MALI_PMU_M400_PP0, group);
+ }
+ mali_inited_pp_cores_group_1++;
+
+ /* Create groups for rest of the cores in the first PP core group */
+ for (i = 1; i < 4; i++) /* First half of the PP cores belong to first core group */
+ {
+ if (mali_inited_pp_cores_group_1 < mali_max_pp_cores_group_1)
+ {
+ if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i])
+ {
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp0), &resource_pp_mmu[i], NULL, &resource_pp[i]);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ if (mali_is_mali450())
+ {
+ mali_pm_domain_add_group(MALI_PMU_M450_DOM2, group);
+ }
+ else
+ {
+ mali_pm_domain_add_group(MALI_PMU_M400_PP0 + i, group);
+ }
+ mali_inited_pp_cores_group_1++;
+ }
+ }
+ }
+
+ /* Create groups for cores in the second PP core group */
+ for (i = 4; i < 8; i++) /* Second half of the PP cores belong to second core group */
+ {
+ if (mali_inited_pp_cores_group_2 < mali_max_pp_cores_group_2)
+ {
+ if (_MALI_OSK_ERR_OK == resource_pp_found[i] && _MALI_OSK_ERR_OK == resource_pp_mmu_found[i])
+ {
+ MALI_DEBUG_ASSERT(mali_l2_cache_core_get_glob_num_l2_cores() >= 2); /* Only Mali-450 have a second core group */
+ group = mali_create_group(mali_l2_cache_core_get_glob_l2_core(cluster_id_pp_grp1), &resource_pp_mmu[i], NULL, &resource_pp[i]);
+ if (NULL == group)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ mali_pm_domain_add_group(MALI_PMU_M450_DOM3, group);
+ mali_inited_pp_cores_group_2++;
+ }
+ }
+ }
+
+ if(mali_is_mali450())
+ {
+ _mali_osk_errcode_t err = mali_create_virtual_group(&resource_pp_mmu_bcast, &resource_pp_bcast, &resource_dlbu, &resource_bcast);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return err;
+ }
+ }
+
+ mali_max_pp_cores_group_1 = mali_inited_pp_cores_group_1;
+ mali_max_pp_cores_group_2 = mali_inited_pp_cores_group_2;
+ MALI_DEBUG_PRINT(2, ("%d+%d PP cores initialized\n", mali_inited_pp_cores_group_1, mali_inited_pp_cores_group_2));
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_check_shared_interrupts(void)
+{
+#if !defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ if (MALI_TRUE == _mali_osk_shared_interrupts())
+ {
+ MALI_PRINT_ERROR(("Shared interrupts detected, but driver support is not enabled\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif /* !defined(CONFIG_MALI_SHARED_INTERRUPTS) */
+
+ /* It is OK to compile support for shared interrupts even if Mali is not using it. */
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_create_pm_domains(void)
+{
+ struct mali_pm_domain *domain;
+ u32 number_of_pp_cores = 0;
+ u32 number_of_l2_caches = 0;
+
+ mali_resource_count(&number_of_pp_cores, &number_of_l2_caches);
+
+ if (mali_is_mali450())
+ {
+ MALI_DEBUG_PRINT(2, ("Creating PM domains for Mali-450 MP%d\n", number_of_pp_cores));
+ switch (number_of_pp_cores)
+ {
+ case 8: /* Fall through */
+ case 6: /* Fall through */
+ domain = mali_pm_domain_create(MALI_PMU_M450_DOM3, MALI_PMU_M450_DOM3_MASK);
+ MALI_CHECK(NULL != domain, _MALI_OSK_ERR_NOMEM);
+ case 4: /* Fall through */
+ case 3: /* Fall through */
+ case 2: /* Fall through */
+ domain = mali_pm_domain_create(MALI_PMU_M450_DOM2, MALI_PMU_M450_DOM2_MASK);
+ MALI_CHECK(NULL != domain, _MALI_OSK_ERR_NOMEM);
+ domain = mali_pm_domain_create(MALI_PMU_M450_DOM1, MALI_PMU_M450_DOM1_MASK);
+ MALI_CHECK(NULL != domain, _MALI_OSK_ERR_NOMEM);
+
+ break;
+ default:
+ MALI_PRINT_ERROR(("Unsupported core configuration\n"));
+ MALI_DEBUG_ASSERT(0);
+ }
+ }
+ else
+ {
+ int i;
+ u32 mask = MALI_PMU_M400_PP0_MASK;
+
+ MALI_DEBUG_PRINT(2, ("Creating PM domains for Mali-400 MP%d\n", number_of_pp_cores));
+
+ MALI_DEBUG_ASSERT(mali_is_mali400());
+
+ for (i = 0; i < number_of_pp_cores; i++)
+ {
+ MALI_CHECK(NULL != mali_pm_domain_create(i, mask), _MALI_OSK_ERR_NOMEM);
+
+ /* Shift mask up, for next core */
+ mask = mask << 1;
+ }
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_pmu(void)
+{
+ _mali_osk_resource_t resource_pmu;
+
+ MALI_DEBUG_ASSERT(0 != global_gpu_base_address);
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_resource_find(global_gpu_base_address + 0x02000, &resource_pmu))
+ {
+ struct mali_pmu_core *pmu;
+ u32 number_of_pp_cores = 0;
+ u32 number_of_l2_caches = 0;
+
+ mali_resource_count(&number_of_pp_cores, &number_of_l2_caches);
+
+ pmu = mali_pmu_create(&resource_pmu, number_of_pp_cores, number_of_l2_caches);
+ if (NULL == pmu)
+ {
+ MALI_PRINT_ERROR(("Failed to create PMU\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ /* It's ok if the PMU doesn't exist */
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_memory(void)
+{
+ _mali_osk_errcode_t ret;
+
+ if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size && 0 == mali_shared_mem_size)
+ {
+ /* Memory settings are not overridden by module parameters, so use device settings */
+ struct _mali_osk_device_data data = { 0, };
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
+ {
+ /* Use device specific settings (if defined) */
+ mali_dedicated_mem_start = data.dedicated_mem_start;
+ mali_dedicated_mem_size = data.dedicated_mem_size;
+ mali_shared_mem_size = data.shared_mem_size;
+ }
+
+ if (0 == mali_dedicated_mem_start && 0 == mali_dedicated_mem_size && 0 == mali_shared_mem_size)
+ {
+ /* No GPU memory specified */
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ MALI_DEBUG_PRINT(2, ("Using device defined memory settings (dedicated: 0x%08X@0x%08X, shared: 0x%08X)\n",
+ mali_dedicated_mem_size, mali_dedicated_mem_start, mali_shared_mem_size));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Using module defined memory settings (dedicated: 0x%08X@0x%08X, shared: 0x%08X)\n",
+ mali_dedicated_mem_size, mali_dedicated_mem_start, mali_shared_mem_size));
+ }
+
+ if (0 < mali_dedicated_mem_size && 0 != mali_dedicated_mem_start)
+ {
+ /* Dedicated memory */
+ ret = mali_memory_core_resource_dedicated_memory(mali_dedicated_mem_start, mali_dedicated_mem_size);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register dedicated memory\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ }
+
+ if (0 < mali_shared_mem_size)
+ {
+ /* Shared OS memory */
+ ret = mali_memory_core_resource_os_memory(mali_shared_mem_size);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register shared OS memory\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ }
+
+ if (0 == mali_fb_start && 0 == mali_fb_size)
+ {
+ /* Frame buffer settings are not overridden by module parameters, so use device settings */
+ struct _mali_osk_device_data data = { 0, };
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
+ {
+ /* Use device specific settings (if defined) */
+ mali_fb_start = data.fb_start;
+ mali_fb_size = data.fb_size;
+ }
+
+ MALI_DEBUG_PRINT(2, ("Using device defined frame buffer settings (0x%08X@0x%08X)\n",
+ mali_fb_size, mali_fb_start));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Using module defined frame buffer settings (0x%08X@0x%08X)\n",
+ mali_fb_size, mali_fb_start));
+ }
+
+ if (0 != mali_fb_size)
+ {
+ /* Register frame buffer */
+ ret = mali_mem_validation_add_range(mali_fb_start, mali_fb_size);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register frame buffer memory region\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_initialize_subsystems(void)
+{
+ _mali_osk_errcode_t err;
+ struct mali_pmu_core *pmu;
+
+ err = mali_session_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto session_init_failed;
+
+#if defined(CONFIG_MALI400_PROFILING)
+ err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ /* No biggie if we weren't able to initialize the profiling */
+ MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
+ }
+#endif
+
+ err = mali_memory_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto memory_init_failed;
+
+ /* Configure memory early. Memory allocation needed for mali_mmu_initialize. */
+ err = mali_parse_config_memory();
+ if (_MALI_OSK_ERR_OK != err) goto parse_memory_config_failed;
+
+ err = mali_set_global_gpu_base_address();
+ if (_MALI_OSK_ERR_OK != err) goto set_global_gpu_base_address_failed;
+
+ err = mali_check_shared_interrupts();
+ if (_MALI_OSK_ERR_OK != err) goto check_shared_interrupts_failed;
+
+ err = mali_pp_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed;
+
+ /* Initialize the power management module */
+ err = mali_pm_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pm_init_failed;
+
+ /* Initialize the MALI PMU */
+ err = mali_parse_config_pmu();
+ if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed;
+
+ /* Make sure the power stays on for the rest of this function */
+ err = _mali_osk_pm_dev_ref_add();
+ if (_MALI_OSK_ERR_OK != err) goto pm_always_on_failed;
+
+ /*
+ * If run-time PM is used, then the mali_pm module has now already been
+ * notified that the power now is on (through the resume callback functions).
+ * However, if run-time PM is not used, then there will probably not be any
+ * calls to the resume callback functions, so we need to explicitly tell it
+ * that the power is on.
+ */
+ mali_pm_set_power_is_on();
+
+ /* Reset PMU HW and ensure all Mali power domains are on */
+ pmu = mali_pmu_get_global_pmu_core();
+ if (NULL != pmu)
+ {
+ err = mali_pmu_reset(pmu);
+ if (_MALI_OSK_ERR_OK != err) goto pmu_reset_failed;
+ }
+
+ /* Detect which Mali GPU we are dealing with */
+ err = mali_parse_product_info();
+ if (_MALI_OSK_ERR_OK != err) goto product_info_parsing_failed;
+
+ /* The global_product_id is now populated with the correct Mali GPU */
+
+ /* Create PM domains only if PMU exists */
+ if (NULL != pmu)
+ {
+ err = mali_create_pm_domains();
+ if (_MALI_OSK_ERR_OK != err) goto pm_domain_failed;
+ }
+
+ /* Initialize MMU module */
+ err = mali_mmu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed;
+
+ if (mali_is_mali450())
+ {
+ err = mali_dlbu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed;
+ }
+
+ /* Start configuring the actual Mali hardware. */
+ err = mali_parse_config_l2_cache();
+ if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed;
+ err = mali_parse_config_groups();
+ if (_MALI_OSK_ERR_OK != err) goto config_parsing_failed;
+
+ /* Initialize the schedulers */
+ err = mali_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto scheduler_init_failed;
+ err = mali_gp_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto gp_scheduler_init_failed;
+
+ /* PP scheduler population can't fail */
+ mali_pp_scheduler_populate();
+
+ /* Initialize the GPU utilization tracking */
+ err = mali_utilization_init();
+ if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed;
+
+ /* Allowing the system to be turned off */
+ _mali_osk_pm_dev_ref_dec();
+
+ MALI_SUCCESS; /* all ok */
+
+ /* Error handling */
+
+utilization_init_failed:
+ mali_pp_scheduler_depopulate();
+ mali_gp_scheduler_terminate();
+gp_scheduler_init_failed:
+ mali_scheduler_terminate();
+scheduler_init_failed:
+config_parsing_failed:
+ mali_delete_groups(); /* Delete any groups not (yet) owned by a scheduler */
+ mali_delete_l2_cache_cores(); /* Delete L2 cache cores even if config parsing failed. */
+dlbu_init_failed:
+ mali_dlbu_terminate();
+mmu_init_failed:
+ mali_pm_domain_terminate();
+pm_domain_failed:
+ /* Nothing to roll back */
+product_info_parsing_failed:
+ /* Nothing to roll back */
+pmu_reset_failed:
+ /* Allowing the system to be turned off */
+ _mali_osk_pm_dev_ref_dec();
+pm_always_on_failed:
+ pmu = mali_pmu_get_global_pmu_core();
+ if (NULL != pmu)
+ {
+ mali_pmu_delete(pmu);
+ }
+parse_pmu_config_failed:
+ mali_pm_terminate();
+pm_init_failed:
+ mali_pp_scheduler_terminate();
+pp_scheduler_init_failed:
+check_shared_interrupts_failed:
+ global_gpu_base_address = 0;
+set_global_gpu_base_address_failed:
+ global_gpu_base_address = 0;
+parse_memory_config_failed:
+ mali_memory_terminate();
+memory_init_failed:
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_term();
+#endif
+ mali_session_terminate();
+session_init_failed:
+ return err;
+}
+
+void mali_terminate_subsystems(void)
+{
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
+
+ /* shut down subsystems in reverse order from startup */
+
+ /* We need the GPU to be powered up for the terminate sequence */
+ _mali_osk_pm_dev_ref_add();
+
+ mali_utilization_term();
+ mali_pp_scheduler_depopulate();
+ mali_gp_scheduler_terminate();
+ mali_scheduler_terminate();
+ mali_delete_l2_cache_cores();
+ if (mali_is_mali450())
+ {
+ mali_dlbu_terminate();
+ }
+ mali_mmu_terminate();
+ if (NULL != pmu)
+ {
+ mali_pmu_delete(pmu);
+ }
+ mali_pm_terminate();
+ mali_memory_terminate();
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_term();
+#endif
+
+ /* Allowing the system to be turned off */
+ _mali_osk_pm_dev_ref_dec();
+
+ mali_pp_scheduler_terminate();
+ mali_session_terminate();
+}
+
+_mali_product_id_t mali_kernel_core_get_product_id(void)
+{
+ return global_product_id;
+}
+
+u32 mali_kernel_core_get_gpu_major_version(void)
+{
+ return global_gpu_major_version;
+}
+
+u32 mali_kernel_core_get_gpu_minor_version(void)
+{
+ return global_gpu_minor_version;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args )
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ /* check compatability */
+ if ( args->version == _MALI_UK_API_VERSION )
+ {
+ args->compatible = 1;
+ }
+ else
+ {
+ args->compatible = 0;
+ }
+
+ args->version = _MALI_UK_API_VERSION; /* report our version */
+
+ /* success regardless of being compatible or not */
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args )
+{
+ _mali_osk_errcode_t err;
+ _mali_osk_notification_t * notification;
+ _mali_osk_notification_queue_t *queue;
+
+ /* check input */
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
+
+ /* if the queue does not exist we're currently shutting down */
+ if (NULL == queue)
+ {
+ MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
+ args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
+ MALI_SUCCESS;
+ }
+
+ /* receive a notification, might sleep */
+ err = _mali_osk_notification_queue_receive(queue, &notification);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ MALI_ERROR(err); /* errcode returned, pass on to caller */
+ }
+
+ /* copy the buffer to the user */
+ args->type = (_mali_uk_notification_type)notification->notification_type;
+ _mali_osk_memcpy(&args->data, notification->result_buffer, notification->result_buffer_size);
+
+ /* finished with the notification */
+ _mali_osk_notification_delete( notification );
+
+ MALI_SUCCESS; /* all ok */
+}
+
+_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args )
+{
+ _mali_osk_notification_t * notification;
+ _mali_osk_notification_queue_t *queue;
+
+ /* check input */
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
+
+ /* if the queue does not exist we're currently shutting down */
+ if (NULL == queue)
+ {
+ MALI_DEBUG_PRINT(1, ("No notification queue registered with the session. Asking userspace to stop querying\n"));
+ MALI_SUCCESS;
+ }
+
+ notification = _mali_osk_notification_create(args->type, 0);
+ if (NULL == notification)
+ {
+ MALI_PRINT_ERROR( ("Failed to create notification object\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ _mali_osk_notification_queue_send(queue, notification);
+
+ MALI_SUCCESS; /* all ok */
+}
+
+_mali_osk_errcode_t _mali_ukk_open(void **context)
+{
+ struct mali_session_data *session;
+
+ /* allocated struct to track this session */
+ session = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
+ MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_NOMEM);
+
+ MALI_DEBUG_PRINT(3, ("Session starting\n"));
+
+ /* create a response queue for this session */
+ session->ioctl_queue = _mali_osk_notification_queue_init();
+ if (NULL == session->ioctl_queue)
+ {
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ session->page_directory = mali_mmu_pagedir_alloc();
+ if (NULL == session->page_directory)
+ {
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session->page_directory, MALI_DLBU_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE))
+ {
+ MALI_PRINT_ERROR(("Failed to map DLBU page into session\n"));
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ if (0 != mali_dlbu_phys_addr)
+ {
+ mali_mmu_pagedir_update(session->page_directory, MALI_DLBU_VIRT_ADDR, mali_dlbu_phys_addr,
+ _MALI_OSK_MALI_PAGE_SIZE, MALI_CACHE_STANDARD);
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session))
+ {
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+#ifdef CONFIG_SYNC
+ _mali_osk_list_init(&session->pending_jobs);
+ session->pending_jobs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK,
+ 0, _MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS);
+ if (NULL == session->pending_jobs_lock)
+ {
+ MALI_PRINT_ERROR(("Failed to create pending jobs lock\n"));
+ mali_memory_session_end(session);
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+#endif
+
+ *context = (void*)session;
+
+ /* Add session to the list of all sessions. */
+ mali_session_add(session);
+
+ /* Initialize list of jobs on this session */
+ _MALI_OSK_INIT_LIST_HEAD(&session->job_list);
+
+ MALI_DEBUG_PRINT(2, ("Session started\n"));
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_close(void **context)
+{
+ struct mali_session_data *session;
+ MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
+ session = (struct mali_session_data *)*context;
+
+ MALI_DEBUG_PRINT(3, ("Session ending\n"));
+
+ /* Remove session from list of all sessions. */
+ mali_session_remove(session);
+
+ /* Abort pending jobs */
+#ifdef CONFIG_SYNC
+ {
+ _mali_osk_list_t tmp_job_list;
+ struct mali_pp_job *job, *tmp;
+ _MALI_OSK_INIT_LIST_HEAD(&tmp_job_list);
+
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ /* Abort asynchronous wait on fence. */
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &session->pending_jobs, struct mali_pp_job, list)
+ {
+ MALI_DEBUG_PRINT(2, ("Sync: Aborting wait for session %x job %x\n", session, job));
+ if (sync_fence_cancel_async(job->pre_fence, &job->sync_waiter))
+ {
+ MALI_DEBUG_PRINT(2, ("Sync: Failed to abort job %x\n", job));
+ }
+ _mali_osk_list_add(&job->list, &tmp_job_list);
+ }
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_wq_flush();
+
+ _mali_osk_lock_term(session->pending_jobs_lock);
+
+ /* Delete jobs */
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &tmp_job_list, struct mali_pp_job, list)
+ {
+ mali_pp_job_delete(job);
+ }
+ }
+#endif
+
+ /* Abort queued and running jobs */
+ mali_gp_scheduler_abort_session(session);
+ mali_pp_scheduler_abort_session(session);
+
+ /* Flush pending work.
+ * Needed to make sure all bottom half processing related to this
+ * session has been completed, before we free internal data structures.
+ */
+ _mali_osk_wq_flush();
+
+ /* Free remaining memory allocated to this session */
+ mali_memory_session_end(session);
+
+ /* Free session data structures */
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
+
+ *context = NULL;
+
+ MALI_DEBUG_PRINT(2, ("Session has ended\n"));
+
+ MALI_SUCCESS;
+}
+
+#if MALI_STATE_TRACKING
+u32 _mali_kernel_core_dump_state(char* buf, u32 size)
+{
+ int n = 0; /* Number of bytes written to buf */
+
+ n += mali_gp_scheduler_dump_state(buf + n, size - n);
+ n += mali_pp_scheduler_dump_state(buf + n, size - n);
+
+ return n;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h
new file mode 100644
index 0000000..bf56b5c
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_core.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_CORE_H__
+#define __MALI_KERNEL_CORE_H__
+
+#include "mali_osk.h"
+
+extern int mali_max_job_runtime;
+
+typedef enum
+{
+ _MALI_PRODUCT_ID_UNKNOWN,
+ _MALI_PRODUCT_ID_MALI200,
+ _MALI_PRODUCT_ID_MALI300,
+ _MALI_PRODUCT_ID_MALI400,
+ _MALI_PRODUCT_ID_MALI450,
+} _mali_product_id_t;
+
+_mali_osk_errcode_t mali_initialize_subsystems(void);
+
+void mali_terminate_subsystems(void);
+
+_mali_product_id_t mali_kernel_core_get_product_id(void);
+
+u32 mali_kernel_core_get_gpu_major_version(void);
+
+u32 mali_kernel_core_get_gpu_minor_version(void);
+
+u32 _mali_kernel_core_dump_state(char* buf, u32 size);
+
+MALI_STATIC_INLINE mali_bool mali_is_mali450(void)
+{
+ return _MALI_PRODUCT_ID_MALI450 == mali_kernel_core_get_product_id();
+}
+
+MALI_STATIC_INLINE mali_bool mali_is_mali400(void)
+{
+ u32 id = mali_kernel_core_get_product_id();
+ return _MALI_PRODUCT_ID_MALI400 == id || _MALI_PRODUCT_ID_MALI300 == id;
+}
+
+#endif /* __MALI_KERNEL_CORE_H__ */
+
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c
new file mode 100644
index 0000000..b9f05ca
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_kernel_descriptor_mapping.h"
+#include "mali_osk.h"
+#include "mali_osk_bitops.h"
+
+#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
+
+/**
+ * Allocate a descriptor table capable of holding 'count' mappings
+ * @param count Number of mappings in the table
+ * @return Pointer to a new table, NULL on error
+ */
+static mali_descriptor_table * descriptor_table_alloc(int count);
+
+/**
+ * Free a descriptor table
+ * @param table The table to free
+ */
+static void descriptor_table_free(mali_descriptor_table * table);
+
+mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries)
+{
+ mali_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(mali_descriptor_mapping));
+
+ init_entries = MALI_PAD_INT(init_entries);
+ max_entries = MALI_PAD_INT(max_entries);
+
+ if (NULL != map)
+ {
+ map->table = descriptor_table_alloc(init_entries);
+ if (NULL != map->table)
+ {
+ map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP);
+ if (NULL != map->lock)
+ {
+ _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
+ map->max_nr_mappings_allowed = max_entries;
+ map->current_nr_mappings = init_entries;
+ return map;
+ }
+ descriptor_table_free(map->table);
+ }
+ _mali_osk_free(map);
+ }
+ return NULL;
+}
+
+void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map)
+{
+ descriptor_table_free(map->table);
+ _mali_osk_lock_term(map->lock);
+ _mali_osk_free(map);
+}
+
+_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *odescriptor)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ int new_descriptor;
+
+ MALI_DEBUG_ASSERT_POINTER(map);
+ MALI_DEBUG_ASSERT_POINTER(odescriptor);
+
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ new_descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
+ if (new_descriptor == map->current_nr_mappings)
+ {
+ /* no free descriptor, try to expand the table */
+ mali_descriptor_table * new_table, * old_table;
+ if (map->current_nr_mappings >= map->max_nr_mappings_allowed) goto unlock_and_exit;
+
+ map->current_nr_mappings += BITS_PER_LONG;
+ new_table = descriptor_table_alloc(map->current_nr_mappings);
+ if (NULL == new_table) goto unlock_and_exit;
+
+ old_table = map->table;
+ _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
+ _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
+ map->table = new_table;
+ descriptor_table_free(old_table);
+ }
+
+ /* we have found a valid descriptor, set the value and usage bit */
+ _mali_osk_set_nonatomic_bit(new_descriptor, map->table->usage);
+ map->table->mappings[new_descriptor] = target;
+ *odescriptor = new_descriptor;
+ err = _MALI_OSK_ERR_OK;
+
+unlock_and_exit:
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
+ MALI_ERROR(err);
+}
+
+void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*))
+{
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(map);
+ MALI_DEBUG_ASSERT_POINTER(callback);
+
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ /* id 0 is skipped as it's an reserved ID not mapping to anything */
+ for (i = 1; i < map->current_nr_mappings; ++i)
+ {
+ if (_mali_osk_test_bit(i, map->table->usage))
+ {
+ callback(i, map->table->mappings[i]);
+ }
+ }
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
+}
+
+_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target)
+{
+ _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT;
+ MALI_DEBUG_ASSERT_POINTER(map);
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ {
+ *target = map->table->mappings[descriptor];
+ result = _MALI_OSK_ERR_OK;
+ }
+ else *target = NULL;
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
+ MALI_ERROR(result);
+}
+
+_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target)
+{
+ _mali_osk_errcode_t result = _MALI_OSK_ERR_FAULT;
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ {
+ map->table->mappings[descriptor] = target;
+ result = _MALI_OSK_ERR_OK;
+ }
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
+ MALI_ERROR(result);
+}
+
+void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor)
+{
+ void *old_value = NULL;
+
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ {
+ old_value = map->table->mappings[descriptor];
+ map->table->mappings[descriptor] = NULL;
+ _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
+ }
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
+
+ return old_value;
+}
+
+static mali_descriptor_table * descriptor_table_alloc(int count)
+{
+ mali_descriptor_table * table;
+
+ table = _mali_osk_calloc(1, sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count));
+
+ if (NULL != table)
+ {
+ table->usage = (u32*)((u8*)table + sizeof(mali_descriptor_table));
+ table->mappings = (void**)((u8*)table + sizeof(mali_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
+ }
+
+ return table;
+}
+
+static void descriptor_table_free(mali_descriptor_table * table)
+{
+ _mali_osk_free(table);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h
new file mode 100644
index 0000000..82ed94d
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_descriptor_mapping.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_kernel_descriptor_mapping.h
+ */
+
+#ifndef __MALI_KERNEL_DESCRIPTOR_MAPPING_H__
+#define __MALI_KERNEL_DESCRIPTOR_MAPPING_H__
+
+#include "mali_osk.h"
+
+/**
+ * The actual descriptor mapping table, never directly accessed by clients
+ */
+typedef struct mali_descriptor_table
+{
+ u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */
+ void** mappings; /**< Array of the pointers the descriptors map to */
+} mali_descriptor_table;
+
+/**
+ * The descriptor mapping object
+ * Provides a separate namespace where we can map an integer to a pointer
+ */
+typedef struct mali_descriptor_mapping
+{
+ _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */
+ int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */
+ int current_nr_mappings; /**< Current number of possible mappings */
+ mali_descriptor_table * table; /**< Pointer to the current mapping table */
+} mali_descriptor_mapping;
+
+/**
+ * Create a descriptor mapping object
+ * Create a descriptor mapping capable of holding init_entries growable to max_entries
+ * @param init_entries Number of entries to preallocate memory for
+ * @param max_entries Number of entries to max support
+ * @return Pointer to a descriptor mapping object, NULL on failure
+ */
+mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int max_entries);
+
+/**
+ * Destroy a descriptor mapping object
+ * @param map The map to free
+ */
+void mali_descriptor_mapping_destroy(mali_descriptor_mapping * map);
+
+/**
+ * Allocate a new mapping entry (descriptor ID)
+ * Allocates a new entry in the map.
+ * @param map The map to allocate a new entry in
+ * @param target The value to map to
+ * @return The descriptor allocated, a negative value on error
+ */
+_mali_osk_errcode_t mali_descriptor_mapping_allocate_mapping(mali_descriptor_mapping * map, void * target, int *descriptor);
+
+/**
+ * Get the value mapped to by a descriptor ID
+ * @param map The map to lookup the descriptor id in
+ * @param descriptor The descriptor ID to lookup
+ * @param target Pointer to a pointer which will receive the stored value
+ * @return 0 on successful lookup, negative on error
+ */
+_mali_osk_errcode_t mali_descriptor_mapping_get(mali_descriptor_mapping * map, int descriptor, void** target);
+
+/**
+ * Set the value mapped to by a descriptor ID
+ * @param map The map to lookup the descriptor id in
+ * @param descriptor The descriptor ID to lookup
+ * @param target Pointer to replace the current value with
+ * @return 0 on successful lookup, negative on error
+ */
+_mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, int descriptor, void * target);
+
+/**
+ * Call the specified callback function for each descriptor in map.
+ * Entire function is mutex protected.
+ * @param map The map to do callbacks for
+ * @param callback A callback function which will be calle for each entry in map
+ */
+void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (*callback)(int, void*));
+
+/**
+ * Free the descriptor ID
+ * For the descriptor to be reused it has to be freed
+ * @param map The map to free the descriptor from
+ * @param descriptor The descriptor ID to free
+ *
+ * @return old value of descriptor mapping
+ */
+void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor);
+
+#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c
new file mode 100644
index 0000000..0ab3a80
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.c
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_kernel_memory_engine.h"
+#include "mali_osk.h"
+
+typedef struct os_allocation
+{
+ u32 num_pages;
+ u32 offset_start;
+ mali_allocation_engine * engine;
+ mali_memory_allocation * descriptor;
+} os_allocation;
+
+typedef struct os_allocator
+{
+ _mali_osk_lock_t *mutex;
+
+ /**
+ * Maximum number of pages to allocate from the OS
+ */
+ u32 num_pages_max;
+
+ /**
+ * Number of pages allocated from the OS
+ */
+ u32 num_pages_allocated;
+
+ /** CPU Usage adjustment (add to mali physical address to get cpu physical address) */
+ u32 cpu_usage_adjust;
+} os_allocator;
+
+static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
+static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block);
+static void os_allocator_release(void * ctx, void * handle);
+static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block );
+static void os_allocator_destroy(mali_physical_memory_allocator * allocator);
+static u32 os_allocator_stat(mali_physical_memory_allocator * allocator);
+
+mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name)
+{
+ mali_physical_memory_allocator * allocator;
+ os_allocator * info;
+
+ max_allocation = (max_allocation + _MALI_OSK_CPU_PAGE_SIZE-1) & ~(_MALI_OSK_CPU_PAGE_SIZE-1);
+
+ MALI_DEBUG_PRINT(2, ("Mali OS memory allocator created with max allocation size of 0x%X bytes, cpu_usage_adjust 0x%08X\n", max_allocation, cpu_usage_adjust));
+
+ allocator = _mali_osk_malloc(sizeof(mali_physical_memory_allocator));
+ if (NULL != allocator)
+ {
+ info = _mali_osk_malloc(sizeof(os_allocator));
+ if (NULL != info)
+ {
+ info->num_pages_max = max_allocation / _MALI_OSK_CPU_PAGE_SIZE;
+ info->num_pages_allocated = 0;
+ info->cpu_usage_adjust = cpu_usage_adjust;
+
+ info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_MEM_INFO);
+ if (NULL != info->mutex)
+ {
+ allocator->allocate = os_allocator_allocate;
+ allocator->allocate_page_table_block = os_allocator_allocate_page_table_block;
+ allocator->destroy = os_allocator_destroy;
+ allocator->stat = os_allocator_stat;
+ allocator->ctx = info;
+ allocator->name = name;
+
+ return allocator;
+ }
+ _mali_osk_free(info);
+ }
+ _mali_osk_free(allocator);
+ }
+
+ return NULL;
+}
+
+static u32 os_allocator_stat(mali_physical_memory_allocator * allocator)
+{
+ os_allocator * info;
+ info = (os_allocator*)allocator->ctx;
+ return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE;
+}
+
+static void os_allocator_destroy(mali_physical_memory_allocator * allocator)
+{
+ os_allocator * info;
+ MALI_DEBUG_ASSERT_POINTER(allocator);
+ MALI_DEBUG_ASSERT_POINTER(allocator->ctx);
+ info = (os_allocator*)allocator->ctx;
+ _mali_osk_lock_term(info->mutex);
+ _mali_osk_free(info);
+ _mali_osk_free(allocator);
+}
+
+static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
+{
+ mali_physical_memory_allocation_result result = MALI_MEM_ALLOC_NONE;
+ u32 left;
+ os_allocator * info;
+ os_allocation * allocation;
+ int pages_allocated = 0;
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(offset);
+ MALI_DEBUG_ASSERT_POINTER(alloc_info);
+
+ info = (os_allocator*)ctx;
+ left = descriptor->size - *offset;
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+
+ /** @note this code may not work on Linux, or may require a more complex Linux implementation */
+ allocation = _mali_osk_malloc(sizeof(os_allocation));
+ if (NULL != allocation)
+ {
+ /* MALI_SEC */
+ //u32 os_mem_max_usage = info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE;
+ allocation->offset_start = *offset;
+ allocation->num_pages = ((left + _MALI_OSK_CPU_PAGE_SIZE - 1) & ~(_MALI_OSK_CPU_PAGE_SIZE - 1)) >> _MALI_OSK_CPU_PAGE_ORDER;
+ MALI_DEBUG_PRINT(6, ("Allocating page array of size %d bytes\n", allocation->num_pages * sizeof(struct page*)));
+ /* MALI_SEC */
+ while (left > 0)
+ {
+ err = mali_allocation_engine_map_physical(engine, descriptor, *offset, MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, info->cpu_usage_adjust, _MALI_OSK_CPU_PAGE_SIZE);
+ if ( _MALI_OSK_ERR_OK != err)
+ {
+ if ( _MALI_OSK_ERR_NOMEM == err)
+ {
+ /* 'Partial' allocation (or, out-of-memory on first page) */
+ break;
+ }
+
+ MALI_DEBUG_PRINT(1, ("Mapping of physical memory failed\n"));
+
+ /* Fatal error, cleanup any previous pages allocated. */
+ if ( pages_allocated > 0 )
+ {
+ mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*pages_allocated, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR );
+ /* (*offset) doesn't need to be restored; it will not be used by the caller on failure */
+ }
+
+ pages_allocated = 0;
+
+ result = MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ break;
+ }
+
+ /* Loop iteration */
+ if (left < _MALI_OSK_CPU_PAGE_SIZE) left = 0;
+ else left -= _MALI_OSK_CPU_PAGE_SIZE;
+
+ pages_allocated++;
+
+ *offset += _MALI_OSK_CPU_PAGE_SIZE;
+ }
+
+ if (left) MALI_PRINT(("Out of memory. Mali memory allocated: %d kB Configured maximum OS memory usage: %d kB\n",
+ (info->num_pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
+
+ /* Loop termination; decide on result */
+ if (pages_allocated)
+ {
+ MALI_DEBUG_PRINT(6, ("Allocated %d pages\n", pages_allocated));
+ if (left) result = MALI_MEM_ALLOC_PARTIAL;
+ else result = MALI_MEM_ALLOC_FINISHED;
+
+ /* Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory.
+ * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches.
+ * This is required for MALI to have the correct view of the memory.
+ */
+ _mali_osk_cache_ensure_uncached_range_flushed( (void *)descriptor, allocation->offset_start, pages_allocated *_MALI_OSK_CPU_PAGE_SIZE );
+ allocation->num_pages = pages_allocated;
+ allocation->engine = engine; /* Necessary to make the engine's unmap call */
+ allocation->descriptor = descriptor; /* Necessary to make the engine's unmap call */
+ info->num_pages_allocated += pages_allocated;
+
+ MALI_DEBUG_PRINT(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max));
+
+ alloc_info->ctx = info;
+ alloc_info->handle = allocation;
+ alloc_info->release = os_allocator_release;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(6, ("Releasing pages array due to no pages allocated\n"));
+ _mali_osk_free( allocation );
+ }
+ }
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+
+ return result;
+}
+
+static void os_allocator_release(void * ctx, void * handle)
+{
+ os_allocator * info;
+ os_allocation * allocation;
+ mali_allocation_engine * engine;
+ mali_memory_allocation * descriptor;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(handle);
+
+ info = (os_allocator*)ctx;
+ allocation = (os_allocation*)handle;
+ engine = allocation->engine;
+ descriptor = allocation->descriptor;
+
+ MALI_DEBUG_ASSERT_POINTER( engine );
+ MALI_DEBUG_ASSERT_POINTER( descriptor );
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
+ {
+ MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
+ return;
+ }
+
+ MALI_DEBUG_PRINT(6, ("Releasing %d os pages\n", allocation->num_pages));
+
+ MALI_DEBUG_ASSERT( allocation->num_pages <= info->num_pages_allocated);
+ info->num_pages_allocated -= allocation->num_pages;
+
+ mali_allocation_engine_unmap_physical( engine, descriptor, allocation->offset_start, _MALI_OSK_CPU_PAGE_SIZE*allocation->num_pages, _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR );
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_free(allocation);
+}
+
+static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
+{
+/* MALI_SEC 6->10 */
+#ifndef CONFIG_FORCE_MAX_ZONEORDER
+ int allocation_order = 10;
+#else
+ int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1;
+#endif
+ void *virt = NULL;
+ u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
+ os_allocator * info;
+
+ u32 cpu_phys_base;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ info = (os_allocator*)ctx;
+
+ /* Ensure we don't allocate more than we're supposed to from the ctx */
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW)) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+
+ /* if the number of pages to be requested lead to exceeding the memory
+ * limit in info->num_pages_max, reduce the size that is to be requested. */
+ while ( (info->num_pages_allocated + (1 << allocation_order) > info->num_pages_max)
+ && _mali_osk_mem_check_allocated(info->num_pages_max * _MALI_OSK_CPU_PAGE_SIZE) )
+ {
+ if ( allocation_order > 0 ) {
+ --allocation_order;
+ } else {
+ /* return OOM */
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+ return MALI_MEM_ALLOC_NONE;
+ }
+ }
+
+ /* try to allocate 2^(allocation_order) pages, if that fails, try
+ * allocation_order-1 to allocation_order 0 (inclusive) */
+ while ( allocation_order >= 0 )
+ {
+ size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
+ virt = _mali_osk_mem_allocioregion( &cpu_phys_base, size );
+
+ if (NULL != virt) break;
+
+ --allocation_order;
+ }
+
+ if ( NULL == virt )
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to allocate consistent memory. Is CONSISTENT_DMA_SIZE set too low?\n"));
+ /* return OOM */
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+ return MALI_MEM_ALLOC_NONE;
+ }
+
+ MALI_DEBUG_PRINT(5, ("os_allocator_allocate_page_table_block: Allocation of order %i succeeded\n",
+ allocation_order));
+
+ /* we now know the size of the allocation since we know for what
+ * allocation_order the allocation succeeded */
+ size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
+
+
+ block->release = os_allocator_page_table_block_release;
+ block->ctx = ctx;
+ block->handle = (void*)allocation_order;
+ block->size = size;
+ block->phys_base = cpu_phys_base - info->cpu_usage_adjust;
+ block->mapping = virt;
+
+ info->num_pages_allocated += (1 << allocation_order);
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+
+ return MALI_MEM_ALLOC_FINISHED;
+}
+
+static void os_allocator_page_table_block_release( mali_page_table_block *page_table_block )
+{
+ os_allocator * info;
+ u32 allocation_order;
+ u32 pages_allocated;
+
+ MALI_DEBUG_ASSERT_POINTER( page_table_block );
+
+ info = (os_allocator*)page_table_block->ctx;
+
+ MALI_DEBUG_ASSERT_POINTER( info );
+
+ allocation_order = (u32)page_table_block->handle;
+
+ pages_allocated = 1 << allocation_order;
+
+ MALI_DEBUG_ASSERT( pages_allocated * _MALI_OSK_CPU_PAGE_SIZE == page_table_block->size );
+
+ if (_MALI_OSK_ERR_OK != _mali_osk_lock_wait(info->mutex, _MALI_OSK_LOCKMODE_RW))
+ {
+ MALI_DEBUG_PRINT(1, ("allocator release: Failed to get mutex\n"));
+ return;
+ }
+
+ MALI_DEBUG_ASSERT( pages_allocated <= info->num_pages_allocated);
+ info->num_pages_allocated -= pages_allocated;
+
+ /* Adjust phys_base from mali physical address to CPU physical address */
+ _mali_osk_mem_freeioregion( page_table_block->phys_base + info->cpu_usage_adjust, page_table_block->size, page_table_block->mapping );
+
+ _mali_osk_lock_signal(info->mutex, _MALI_OSK_LOCKMODE_RW);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.h
new file mode 100644
index 0000000..0946169
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_mem_os.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_MEM_OS_H__
+#define __MALI_KERNEL_MEM_OS_H__
+
+/**
+ * @brief Creates an object that manages allocating OS memory
+ *
+ * Creates an object that provides an interface to allocate OS memory and
+ * have it mapped into the Mali virtual memory space.
+ *
+ * The object exposes pointers to
+ * - allocate OS memory
+ * - allocate Mali page tables in OS memory
+ * - destroy the object
+ *
+ * Allocations from OS memory are of type mali_physical_memory_allocation
+ * which provides a function to release the allocation.
+ *
+ * @param max_allocation max. number of bytes that can be allocated from OS memory
+ * @param cpu_usage_adjust value to add to mali physical addresses to obtain CPU physical addresses
+ * @param name description of the allocator
+ * @return pointer to mali_physical_memory_allocator object. NULL on failure.
+ **/
+mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u32 cpu_usage_adjust, const char *name);
+
+#endif /* __MALI_KERNEL_MEM_OS_H__ */
+
+
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c
new file mode 100644
index 0000000..00257ec
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.c
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_kernel_memory_engine.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+
+typedef struct memory_engine
+{
+ mali_kernel_mem_address_manager * mali_address;
+ mali_kernel_mem_address_manager * process_address;
+} memory_engine;
+
+mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager)
+{
+ memory_engine * engine;
+
+ /* Mali Address Manager need not support unmap_physical */
+ MALI_DEBUG_ASSERT_POINTER(mali_address_manager);
+ MALI_DEBUG_ASSERT_POINTER(mali_address_manager->allocate);
+ MALI_DEBUG_ASSERT_POINTER(mali_address_manager->release);
+ MALI_DEBUG_ASSERT_POINTER(mali_address_manager->map_physical);
+
+ /* Process Address Manager must support unmap_physical for OS allocation
+ * error path handling */
+ MALI_DEBUG_ASSERT_POINTER(process_address_manager);
+ MALI_DEBUG_ASSERT_POINTER(process_address_manager->allocate);
+ MALI_DEBUG_ASSERT_POINTER(process_address_manager->release);
+ MALI_DEBUG_ASSERT_POINTER(process_address_manager->map_physical);
+ MALI_DEBUG_ASSERT_POINTER(process_address_manager->unmap_physical);
+
+
+ engine = (memory_engine*)_mali_osk_malloc(sizeof(memory_engine));
+ if (NULL == engine) return NULL;
+
+ engine->mali_address = mali_address_manager;
+ engine->process_address = process_address_manager;
+
+ return (mali_allocation_engine)engine;
+}
+
+void mali_allocation_engine_destroy(mali_allocation_engine engine)
+{
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ _mali_osk_free(engine);
+}
+
+_mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_allocators, _mali_osk_list_t *tracking_list )
+{
+ memory_engine * engine = (memory_engine*)mem_engine;
+
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(physical_allocators);
+ /* ASSERT that the list member has been initialized, even if it won't be
+ * used for tracking. We need it to be initialized to see if we need to
+ * delete it from a list in the release function. */
+ MALI_DEBUG_ASSERT( NULL != descriptor->list.next && NULL != descriptor->list.prev );
+
+ if (_MALI_OSK_ERR_OK == engine->mali_address->allocate(descriptor))
+ {
+ _mali_osk_errcode_t res = _MALI_OSK_ERR_OK;
+ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
+ {
+ res = engine->process_address->allocate(descriptor);
+ }
+ if ( _MALI_OSK_ERR_OK == res )
+ {
+ /* address space setup OK, commit physical memory to the allocation */
+ mali_physical_memory_allocator * active_allocator = physical_allocators;
+ struct mali_physical_memory_allocation * active_allocation_tracker = &descriptor->physical_allocation;
+ u32 offset = 0;
+
+ while ( NULL != active_allocator )
+ {
+ switch (active_allocator->allocate(active_allocator->ctx, mem_engine, descriptor, &offset, active_allocation_tracker))
+ {
+ case MALI_MEM_ALLOC_FINISHED:
+ if ( NULL != tracking_list )
+ {
+ /* Insert into the memory session list */
+ /* ASSERT that it is not already part of a list */
+ MALI_DEBUG_ASSERT( _mali_osk_list_empty( &descriptor->list ) );
+ _mali_osk_list_add( &descriptor->list, tracking_list );
+ }
+
+ MALI_SUCCESS; /* all done */
+ case MALI_MEM_ALLOC_NONE:
+ /* reuse current active_allocation_tracker */
+ MALI_DEBUG_PRINT( 4, ("Memory Engine Allocate: No allocation on %s, resorting to %s\n",
+ ( active_allocator->name ) ? active_allocator->name : "UNNAMED",
+ ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") );
+ active_allocator = active_allocator->next;
+ break;
+ case MALI_MEM_ALLOC_PARTIAL:
+ if (NULL != active_allocator->next)
+ {
+ /* need a new allocation tracker */
+ active_allocation_tracker->next = _mali_osk_calloc(1, sizeof(mali_physical_memory_allocation));
+ if (NULL != active_allocation_tracker->next)
+ {
+ active_allocation_tracker = active_allocation_tracker->next;
+ MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate: Partial allocation on %s, resorting to %s\n",
+ ( active_allocator->name ) ? active_allocator->name : "UNNAMED",
+ ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") );
+ active_allocator = active_allocator->next;
+ break;
+ }
+ }
+ /* FALL THROUGH */
+ case MALI_MEM_ALLOC_INTERNAL_FAILURE:
+ active_allocator = NULL; /* end the while loop */
+ break;
+ }
+ }
+
+ MALI_PRINT(("Memory allocate failed, could not allocate size %d kB.\n", descriptor->size/1024));
+
+ /* allocation failure, start cleanup */
+ /* loop over any potential partial allocations */
+ active_allocation_tracker = &descriptor->physical_allocation;
+ while (NULL != active_allocation_tracker)
+ {
+ /* handle blank trackers which will show up during failure */
+ if (NULL != active_allocation_tracker->release)
+ {
+ active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle);
+ }
+ active_allocation_tracker = active_allocation_tracker->next;
+ }
+
+ /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */
+ for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; )
+ {
+ void * buf = active_allocation_tracker;
+ active_allocation_tracker = active_allocation_tracker->next;
+ _mali_osk_free(buf);
+ }
+
+ /* release the address spaces */
+
+ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
+ {
+ engine->process_address->release(descriptor);
+ }
+ }
+ engine->mali_address->release(descriptor);
+ }
+
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+}
+
+void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
+{
+ mali_allocation_engine_release_pt1_mali_pagetables_unmap(mem_engine, descriptor);
+ mali_allocation_engine_release_pt2_physical_memory_free(mem_engine, descriptor);
+}
+
+void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
+{
+ memory_engine * engine = (memory_engine*)mem_engine;
+
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ /* Calling: mali_address_manager_release() */
+ /* This function is allowed to be called several times, and it only does the release on the first call. */
+ engine->mali_address->release(descriptor);
+}
+
+void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor)
+{
+ memory_engine * engine = (memory_engine*)mem_engine;
+ mali_physical_memory_allocation * active_allocation_tracker;
+
+ /* Remove this from a tracking list in session_data->memory_head */
+ if ( ! _mali_osk_list_empty( &descriptor->list ) )
+ {
+ _mali_osk_list_del( &descriptor->list );
+ /* Clear the list for debug mode, catch use-after-free */
+ MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; )
+ }
+
+ active_allocation_tracker = &descriptor->physical_allocation;
+ while (NULL != active_allocation_tracker)
+ {
+ MALI_DEBUG_ASSERT_POINTER(active_allocation_tracker->release);
+ active_allocation_tracker->release(active_allocation_tracker->ctx, active_allocation_tracker->handle);
+ active_allocation_tracker = active_allocation_tracker->next;
+ }
+
+ /* free the allocation tracker objects themselves, skipping the tracker stored inside the descriptor itself */
+ for ( active_allocation_tracker = descriptor->physical_allocation.next; active_allocation_tracker != NULL; )
+ {
+ void * buf = active_allocation_tracker;
+ active_allocation_tracker = active_allocation_tracker->next;
+ _mali_osk_free(buf);
+ }
+
+ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
+ {
+ engine->process_address->release(descriptor);
+ }
+}
+
+_mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size)
+{
+ _mali_osk_errcode_t err;
+ memory_engine * engine = (memory_engine*)mem_engine;
+ _mali_osk_mem_mapregion_flags_t unmap_flags = (_mali_osk_mem_mapregion_flags_t)0;
+
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X\n", phys, size, offset));
+
+ MALI_DEBUG_ASSERT_POINTER(engine->mali_address);
+ MALI_DEBUG_ASSERT_POINTER(engine->mali_address->map_physical);
+
+ /* Handle process address manager first, because we may need them to
+ * allocate the physical page */
+ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
+ {
+ /* Handle OS-allocated specially, since an adjustment may be required */
+ if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == phys )
+ {
+ MALI_DEBUG_ASSERT( _MALI_OSK_CPU_PAGE_SIZE == size );
+
+ /* Set flags to use on error path */
+ unmap_flags |= _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR;
+
+ err = engine->process_address->map_physical(descriptor, offset, &phys, size);
+ /* Adjust for cpu physical address to mali physical address */
+ phys -= cpu_usage_adjust;
+ }
+ else
+ {
+ u32 cpu_phys;
+ /* Adjust mali physical address to cpu physical address */
+ cpu_phys = phys + cpu_usage_adjust;
+ err = engine->process_address->map_physical(descriptor, offset, &cpu_phys, size);
+ }
+
+ if ( _MALI_OSK_ERR_OK != err )
+ {
+ MALI_DEBUG_PRINT(2, ("Map failed: %s %d\n", __FUNCTION__, __LINE__));
+ MALI_ERROR( err );
+ }
+ }
+
+ MALI_DEBUG_PRINT(7, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset));
+
+ /* Mali address manager must use the physical address - no point in asking
+ * it to allocate another one for us */
+ MALI_DEBUG_ASSERT( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC != phys );
+
+ err = engine->mali_address->map_physical(descriptor, offset, &phys, size);
+
+ if ( _MALI_OSK_ERR_OK != err )
+ {
+ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
+ {
+ MALI_DEBUG_PRINT( 2, ("Process address manager succeeded, but Mali Address manager failed for phys=0x%08X size=0x%08X, offset=0x%08X. Will unmap.\n", phys, size, offset));
+ engine->process_address->unmap_physical(descriptor, offset, size, unmap_flags);
+ }
+ MALI_DEBUG_PRINT(2, ("Map mali failed: %s %d\n", __FUNCTION__, __LINE__));
+ MALI_ERROR( err );
+ }
+
+ MALI_SUCCESS;
+}
+
+void mali_allocation_engine_unmap_physical(mali_allocation_engine mem_engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags )
+{
+ memory_engine * engine = (memory_engine*)mem_engine;
+
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ MALI_DEBUG_PRINT(7, ("UnMapping length 0x%08X at offset 0x%08X\n", size, offset));
+
+ MALI_DEBUG_ASSERT_POINTER(engine->mali_address);
+ MALI_DEBUG_ASSERT_POINTER(engine->process_address);
+
+ if ( descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE )
+ {
+ /* Mandetory for process_address manager to have an unmap function*/
+ engine->process_address->unmap_physical( descriptor, offset, size, unmap_flags );
+ }
+
+ /* Optional for mali_address manager to have an unmap function*/
+ if ( NULL != engine->mali_address->unmap_physical )
+ {
+ engine->mali_address->unmap_physical( descriptor, offset, size, unmap_flags );
+ }
+}
+
+
+_mali_osk_errcode_t mali_allocation_engine_allocate_page_tables(mali_allocation_engine engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider)
+{
+ mali_physical_memory_allocator * active_allocator = physical_provider;
+
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(physical_provider);
+
+ while ( NULL != active_allocator )
+ {
+ switch (active_allocator->allocate_page_table_block(active_allocator->ctx, descriptor))
+ {
+ case MALI_MEM_ALLOC_FINISHED:
+ MALI_SUCCESS; /* all done */
+ case MALI_MEM_ALLOC_NONE:
+ /* try next */
+ MALI_DEBUG_PRINT( 2, ("Memory Engine Allocate PageTables: No allocation on %s, resorting to %s\n",
+ ( active_allocator->name ) ? active_allocator->name : "UNNAMED",
+ ( active_allocator->next ) ? (( active_allocator->next->name )? active_allocator->next->name : "UNNAMED") : "NONE") );
+ active_allocator = active_allocator->next;
+ break;
+ case MALI_MEM_ALLOC_PARTIAL:
+ MALI_DEBUG_PRINT(1, ("Invalid return value from allocate_page_table_block call: MALI_MEM_ALLOC_PARTIAL\n"));
+ /* FALL THROUGH */
+ case MALI_MEM_ALLOC_INTERNAL_FAILURE:
+ MALI_DEBUG_PRINT(1, ("Aborting due to allocation failure\n"));
+ active_allocator = NULL; /* end the while loop */
+ break;
+ }
+ }
+
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+}
+
+
+void mali_allocation_engine_report_allocators( mali_physical_memory_allocator * physical_provider )
+{
+ mali_physical_memory_allocator * active_allocator = physical_provider;
+ MALI_DEBUG_ASSERT_POINTER(physical_provider);
+
+ MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest numbered first) :\n"));
+ while ( NULL != active_allocator )
+ {
+ if ( NULL != active_allocator->name )
+ {
+ MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", active_allocator->alloc_order, active_allocator->name) );
+ }
+ else
+ {
+ MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", active_allocator->alloc_order) );
+ }
+ active_allocator = active_allocator->next;
+ }
+
+}
+
+u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator)
+{
+ u32 sum = 0;
+ while(NULL != allocator)
+ {
+ /* Only count allocators that have set up a stat function. */
+ if(allocator->stat)
+ sum += allocator->stat(allocator);
+
+ allocator = allocator->next;
+ }
+
+ return sum;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h
new file mode 100644
index 0000000..3b41cee
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_memory_engine.h
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_MEMORY_ENGINE_H__
+#define __MALI_KERNEL_MEMORY_ENGINE_H__
+
+typedef void * mali_allocation_engine;
+
+typedef enum { MALI_MEM_ALLOC_FINISHED, MALI_MEM_ALLOC_PARTIAL, MALI_MEM_ALLOC_NONE, MALI_MEM_ALLOC_INTERNAL_FAILURE } mali_physical_memory_allocation_result;
+
+typedef struct mali_physical_memory_allocation
+{
+ void (*release)(void * ctx, void * handle); /**< Function to call on to release the physical memory */
+ void * ctx;
+ void * handle;
+ struct mali_physical_memory_allocation * next;
+} mali_physical_memory_allocation;
+
+struct mali_page_table_block;
+
+typedef struct mali_page_table_block
+{
+ void (*release)(struct mali_page_table_block *page_table_block);
+ void * ctx;
+ void * handle;
+ u32 size; /**< In bytes, should be a multiple of MALI_MMU_PAGE_SIZE to avoid internal fragementation */
+ u32 phys_base; /**< Mali physical address */
+ mali_io_address mapping;
+} mali_page_table_block;
+
+
+/** @addtogroup _mali_osk_low_level_memory
+ * @{ */
+
+typedef enum
+{
+ MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE = 0x1,
+ MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE = 0x2,
+} mali_memory_allocation_flag;
+
+/**
+ * Supplying this 'magic' physical address requests that the OS allocate the
+ * physical address at page commit time, rather than committing a specific page
+ */
+#define MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC ((u32)(-1))
+
+typedef struct mali_memory_allocation
+{
+ /* Information about the allocation */
+ void * mapping; /**< CPU virtual address where the memory is mapped at */
+ u32 mali_address; /**< The Mali seen address of the memory allocation */
+ u32 size; /**< Size of the allocation */
+ u32 permission; /**< Permission settings */
+ mali_memory_allocation_flag flags;
+ u32 cache_settings; /* type: mali_memory_cache_settings, found in <linux/mali/mali_utgard_uk_types.h> Ump DD breaks if we include it...*/
+
+ _mali_osk_lock_t * lock;
+
+ /* Manager specific information pointers */
+ void * mali_addr_mapping_info; /**< Mali address allocation specific info */
+ void * process_addr_mapping_info; /**< Mapping manager specific info */
+
+ mali_physical_memory_allocation physical_allocation;
+
+ _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */
+} mali_memory_allocation;
+/** @} */ /* end group _mali_osk_low_level_memory */
+
+
+typedef struct mali_physical_memory_allocator
+{
+ mali_physical_memory_allocation_result (*allocate)(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
+ mali_physical_memory_allocation_result (*allocate_page_table_block)(void * ctx, mali_page_table_block * block); /* MALI_MEM_ALLOC_PARTIAL not allowed */
+ void (*destroy)(struct mali_physical_memory_allocator * allocator);
+ u32 (*stat)(struct mali_physical_memory_allocator * allocator);
+ void * ctx;
+ const char * name; /**< Descriptive name for use in mali_allocation_engine_report_allocators, or NULL */
+ u32 alloc_order; /**< Order in which the allocations should happen */
+ struct mali_physical_memory_allocator * next;
+} mali_physical_memory_allocator;
+
+typedef struct mali_kernel_mem_address_manager
+{
+ _mali_osk_errcode_t (*allocate)(mali_memory_allocation *); /**< Function to call to reserve an address */
+ void (*release)(mali_memory_allocation *); /**< Function to call to free the address allocated */
+
+ /**
+ * Function called for each physical sub allocation.
+ * Called for each physical block allocated by the physical memory manager.
+ * @param[in] descriptor The memory descriptor in question
+ * @param[in] off Offset from the start of range
+ * @param[in,out] phys_addr A pointer to the physical address of the start of the
+ * physical block. When *phys_addr == MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC
+ * is used, this requests the function to allocate the physical page
+ * itself, and return it through the pointer provided.
+ * @param[in] size Length in bytes of the physical block
+ * @return _MALI_OSK_ERR_OK on success.
+ * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
+ * Specifically, _MALI_OSK_ERR_UNSUPPORTED indicates that the function
+ * does not support allocating physical pages itself.
+ */
+ _mali_osk_errcode_t (*map_physical)(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);
+
+ /**
+ * Function called to remove a physical sub allocation.
+ * Called on error paths where one of the address managers fails.
+ *
+ * @note this is optional. For address managers where this is not
+ * implemented, the value of this member is NULL. The memory engine
+ * currently does not require the mali address manager to be able to
+ * unmap individual pages, but the process address manager must have this
+ * capability.
+ *
+ * @param[in] descriptor The memory descriptor in question
+ * @param[in] off Offset from the start of range
+ * @param[in] size Length in bytes of the physical block
+ * @param[in] flags flags to use on a per-page basis. For OS-allocated
+ * physical pages, this must include _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR.
+ * @return _MALI_OSK_ERR_OK on success.
+ * A value of type _mali_osk_errcode_t other than _MALI_OSK_ERR_OK indicates failure.
+ */
+ void (*unmap_physical)(mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags);
+
+} mali_kernel_mem_address_manager;
+
+mali_allocation_engine mali_allocation_engine_create(mali_kernel_mem_address_manager * mali_address_manager, mali_kernel_mem_address_manager * process_address_manager);
+
+void mali_allocation_engine_destroy(mali_allocation_engine engine);
+
+int mali_allocation_engine_allocate_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor, mali_physical_memory_allocator * physical_provider, _mali_osk_list_t *tracking_list );
+void mali_allocation_engine_release_memory(mali_allocation_engine engine, mali_memory_allocation * descriptor);
+
+void mali_allocation_engine_release_pt1_mali_pagetables_unmap(mali_allocation_engine engine, mali_memory_allocation * descriptor);
+void mali_allocation_engine_release_pt2_physical_memory_free(mali_allocation_engine engine, mali_memory_allocation * descriptor);
+
+int mali_allocation_engine_map_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 phys, u32 cpu_usage_adjust, u32 size);
+void mali_allocation_engine_unmap_physical(mali_allocation_engine engine, mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t unmap_flags);
+
+int mali_allocation_engine_allocate_page_tables(mali_allocation_engine, mali_page_table_block * descriptor, mali_physical_memory_allocator * physical_provider);
+
+void mali_allocation_engine_report_allocators(mali_physical_memory_allocator * physical_provider);
+
+u32 mali_allocation_engine_memory_usage(mali_physical_memory_allocator *allocator);
+
+#endif /* __MALI_KERNEL_MEMORY_ENGINE_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c
new file mode 100644
index 0000000..9dae2e8
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_utilization.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_kernel_common.h"
+
+/* Define how often to calculate and report GPU utilization, in milliseconds */
+static _mali_osk_lock_t *time_data_lock;
+
+static u32 num_running_gp_cores;
+static u32 num_running_pp_cores;
+
+static u64 work_start_time_gpu = 0;
+static u64 work_start_time_gp = 0;
+static u64 work_start_time_pp = 0;
+static u64 accumulated_work_time_gpu = 0;
+static u64 accumulated_work_time_gp = 0;
+static u64 accumulated_work_time_pp = 0;
+
+static u64 period_start_time = 0;
+
+#ifndef CONFIG_PM_DEVFREQ /* MALI_SEC */
+static _mali_osk_timer_t *utilization_timer = NULL;
+#endif
+static mali_bool timer_running = MALI_FALSE;
+
+static u32 last_utilization_gpu = 0 ;
+static u32 last_utilization_gp = 0 ;
+static u32 last_utilization_pp = 0 ;
+
+#ifndef CONFIG_PM_DEVFREQ /* MALI_SEC */
+static u32 mali_utilization_timeout = 100;
+#endif
+void (*mali_utilization_callback)(struct mali_gpu_utilization_data *data) = NULL;
+
+#ifndef CONFIG_PM_DEVFREQ
+static void calculate_gpu_utilization(void* arg)
+{
+#else
+void calculate_gpu_utilization(void *arg)
+{
+#endif
+ u64 time_now;
+ u64 time_period;
+ u32 leading_zeroes;
+ u32 shift_val;
+ u32 work_normalized_gpu;
+ u32 work_normalized_gp;
+ u32 work_normalized_pp;
+ u32 period_normalized;
+ u32 utilization_gpu;
+ u32 utilization_gp;
+ u32 utilization_pp;
+
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (accumulated_work_time_gpu == 0 && work_start_time_gpu == 0)
+ {
+ /*
+ * No work done for this period
+ * - No need to reschedule timer
+ * - Report zero usage
+ */
+ timer_running = MALI_FALSE;
+
+ last_utilization_gpu = 0;
+ last_utilization_gp = 0;
+ last_utilization_pp = 0;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (NULL != mali_utilization_callback)
+ {
+ struct mali_gpu_utilization_data data = { 0, };
+ mali_utilization_callback(&data);
+ }
+
+ return;
+ }
+
+ time_now = _mali_osk_time_get_ns();
+
+ time_period = time_now - period_start_time;
+
+ /* If we are currently busy, update working period up to now */
+ if (work_start_time_gpu != 0)
+ {
+ accumulated_work_time_gpu += (time_now - work_start_time_gpu);
+ work_start_time_gpu = time_now;
+
+ /* GP and/or PP will also be busy if the GPU is busy at this point */
+
+ if (work_start_time_gp != 0)
+ {
+ accumulated_work_time_gp += (time_now - work_start_time_gp);
+ work_start_time_gp = time_now;
+ }
+
+ if (work_start_time_pp != 0)
+ {
+ accumulated_work_time_pp += (time_now - work_start_time_pp);
+ work_start_time_pp = time_now;
+ }
+ }
+
+ /*
+ * We have two 64-bit values, a dividend and a divisor.
+ * To avoid dependencies to a 64-bit divider, we shift down the two values
+ * equally first.
+ * We shift the dividend up and possibly the divisor down, making the result X in 256.
+ */
+
+ /* Shift the 64-bit values down so they fit inside a 32-bit integer */
+ leading_zeroes = _mali_osk_clz((u32)(time_period >> 32));
+ shift_val = 32 - leading_zeroes;
+ work_normalized_gpu = (u32)(accumulated_work_time_gpu >> shift_val);
+ work_normalized_gp = (u32)(accumulated_work_time_gp >> shift_val);
+ work_normalized_pp = (u32)(accumulated_work_time_pp >> shift_val);
+ period_normalized = (u32)(time_period >> shift_val);
+
+ /*
+ * Now, we should report the usage in parts of 256
+ * this means we must shift up the dividend or down the divisor by 8
+ * (we could do a combination, but we just use one for simplicity,
+ * but the end result should be good enough anyway)
+ */
+ if (period_normalized > 0x00FFFFFF)
+ {
+ /* The divisor is so big that it is safe to shift it down */
+ period_normalized >>= 8;
+ }
+ else
+ {
+ /*
+ * The divisor is so small that we can shift up the dividend, without loosing any data.
+ * (dividend is always smaller than the divisor)
+ */
+ work_normalized_gpu <<= 8;
+ work_normalized_gp <<= 8;
+ work_normalized_pp <<= 8;
+ }
+
+ utilization_gpu = work_normalized_gpu / period_normalized;
+ utilization_gp = work_normalized_gp / period_normalized;
+ utilization_pp = work_normalized_pp / period_normalized;
+
+ last_utilization_gpu = utilization_gpu;
+ last_utilization_gp = utilization_gp;
+ last_utilization_pp = utilization_pp;
+
+ /* starting a new period */
+ accumulated_work_time_gpu = 0;
+ accumulated_work_time_gp = 0;
+ accumulated_work_time_pp = 0;
+ period_start_time = time_now;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+#ifndef CONFIG_PM_DEVFREQ
+ _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
+#endif
+
+ if (NULL != mali_utilization_callback)
+ {
+ struct mali_gpu_utilization_data data = { utilization_gpu, utilization_gp, utilization_pp };
+ mali_utilization_callback(&data);
+ }
+}
+
+_mali_osk_errcode_t mali_utilization_init(void)
+{
+#if USING_GPU_UTILIZATION
+ struct _mali_osk_device_data data;
+ if (_MALI_OSK_ERR_OK == _mali_osk_device_data_get(&data))
+ {
+ /* Use device specific settings (if defined) */
+#ifndef CONFIG_PM_DEVFREQ
+ if (0 != data.utilization_interval)
+ {
+ mali_utilization_timeout = data.utilization_interval;
+ }
+#endif
+ if (NULL != data.utilization_callback)
+ {
+ mali_utilization_callback = data.utilization_callback;
+ }
+ }
+#endif
+
+ if (NULL != mali_utilization_callback)
+ {
+#ifndef CONFIG_PM_DEVFREQ
+ MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: Utilization handler installed with interval %u\n", mali_utilization_timeout));
+#endif
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Mali GPU Utilization: No utilization handler installed\n"));
+ }
+
+ time_data_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |
+ _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_UTILIZATION);
+
+ if (NULL == time_data_lock)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ num_running_gp_cores = 0;
+ num_running_pp_cores = 0;
+
+#ifndef CONFIG_PM_DEVFREQ
+ utilization_timer = _mali_osk_timer_init();
+ if (NULL == utilization_timer)
+ {
+ _mali_osk_lock_term(time_data_lock);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ _mali_osk_timer_setcallback(utilization_timer, calculate_gpu_utilization, NULL);
+#endif
+
+ return _MALI_OSK_ERR_OK;
+}
+
+#ifndef CONFIG_PM_DEVFREQ
+void mali_utilization_suspend(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (timer_running == MALI_TRUE)
+ {
+ timer_running = MALI_FALSE;
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_timer_del(utilization_timer);
+ return;
+ }
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+}
+#endif
+
+void mali_utilization_term(void)
+{
+#ifndef CONFIG_PM_DEVFREQ
+ if (NULL != utilization_timer)
+ {
+ _mali_osk_timer_del(utilization_timer);
+ timer_running = MALI_FALSE;
+ _mali_osk_timer_term(utilization_timer);
+ utilization_timer = NULL;
+ }
+#endif
+
+ _mali_osk_lock_term(time_data_lock);
+}
+
+void mali_utilization_gp_start(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ ++num_running_gp_cores;
+ if (1 == num_running_gp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* First GP core started, consider GP busy from now and onwards */
+ work_start_time_gp = time_now;
+
+ if (0 == num_running_pp_cores)
+ {
+ /*
+ * There are no PP cores running, so this is also the point
+ * at which we consider the GPU to be busy as well.
+ */
+ work_start_time_gpu = time_now;
+ }
+
+ /* Start a new period (and timer) if needed */
+ if (timer_running != MALI_TRUE)
+ {
+ timer_running = MALI_TRUE;
+ period_start_time = time_now;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
+ }
+ else
+ {
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+}
+
+void mali_utilization_pp_start(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ ++num_running_pp_cores;
+ if (1 == num_running_pp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* First PP core started, consider PP busy from now and onwards */
+ work_start_time_pp = time_now;
+
+ if (0 == num_running_gp_cores)
+ {
+ /*
+ * There are no GP cores running, so this is also the point
+ * at which we consider the GPU to be busy as well.
+ */
+ work_start_time_gpu = time_now;
+ }
+
+ /* Start a new period (and timer) if needed */
+ if (timer_running != MALI_TRUE)
+ {
+ timer_running = MALI_TRUE;
+ period_start_time = time_now;
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+#ifndef CONFIG_PM_DEVFREQ
+ _mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(mali_utilization_timeout));
+#endif
+ }
+ else
+ {
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+}
+
+void mali_utilization_gp_end(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ --num_running_gp_cores;
+ if (0 == num_running_gp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* Last GP core ended, consider GP idle from now and onwards */
+ accumulated_work_time_gp += (time_now - work_start_time_gp);
+ work_start_time_gp = 0;
+
+ if (0 == num_running_pp_cores)
+ {
+ /*
+ * There are no PP cores running, so this is also the point
+ * at which we consider the GPU to be idle as well.
+ */
+ accumulated_work_time_gpu += (time_now - work_start_time_gpu);
+ work_start_time_gpu = 0;
+ }
+ }
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+void mali_utilization_pp_end(void)
+{
+ _mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+
+ --num_running_pp_cores;
+ if (0 == num_running_pp_cores)
+ {
+ u64 time_now = _mali_osk_time_get_ns();
+
+ /* Last PP core ended, consider PP idle from now and onwards */
+ accumulated_work_time_pp += (time_now - work_start_time_pp);
+ work_start_time_pp = 0;
+
+ if (0 == num_running_gp_cores)
+ {
+ /*
+ * There are no GP cores running, so this is also the point
+ * at which we consider the GPU to be idle as well.
+ */
+ accumulated_work_time_gpu += (time_now - work_start_time_gpu);
+ work_start_time_gpu = 0;
+ }
+ }
+
+ _mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+u32 _mali_ukk_utilization_gp_pp(void)
+{
+ return last_utilization_gpu;
+}
+
+u32 _mali_ukk_utilization_gp(void)
+{
+ return last_utilization_gp;
+}
+
+u32 _mali_ukk_utilization_pp(void)
+{
+ return last_utilization_pp;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h
new file mode 100644
index 0000000..6ee5101
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_utilization.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_UTILIZATION_H__
+#define __MALI_KERNEL_UTILIZATION_H__
+
+#include <linux/mali/mali_utgard.h>
+#include "mali_osk.h"
+
+extern void (*mali_utilization_callback)(struct mali_gpu_utilization_data *data);
+
+#ifdef CONFIG_PM_DEVFREQ /* MALI_SEC */
+void calculate_gpu_utilization(void *arg);
+#endif
+/**
+ * Initialize/start the Mali GPU utilization metrics reporting.
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t mali_utilization_init(void);
+
+/**
+ * Terminate the Mali GPU utilization metrics reporting
+ */
+void mali_utilization_term(void);
+
+/**
+ * Check if Mali utilization is enabled
+ */
+MALI_STATIC_INLINE mali_bool mali_utilization_enabled(void)
+{
+ return (NULL != mali_utilization_callback);
+}
+
+/**
+ * Should be called when a job is about to execute a GP job
+ */
+void mali_utilization_gp_start(void);
+
+/**
+ * Should be called when a job has completed executing a GP job
+ */
+void mali_utilization_gp_end(void);
+
+/**
+ * Should be called when a job is about to execute a PP job
+ */
+void mali_utilization_pp_start(void);
+
+/**
+ * Should be called when a job has completed executing a PP job
+ */
+void mali_utilization_pp_end(void);
+
+/**
+ * Should be called to stop the utilization timer during system suspend
+ */
+void mali_utilization_suspend(void);
+
+
+#endif /* __MALI_KERNEL_UTILIZATION_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c
new file mode 100644
index 0000000..a1fdf00
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_kernel_vsync.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_ukk.h"
+
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args)
+{
+ _mali_uk_vsync_event event = (_mali_uk_vsync_event)args->event;
+ MALI_IGNORE(event); /* event is not used for release code, and that is OK */
+
+#if defined(CONFIG_MALI400_PROFILING)
+ /*
+ * Manually generate user space events in kernel space.
+ * This saves user space from calling kernel space twice in this case.
+ * We just need to remember to add pid and tid manually.
+ */
+ if ( event==_MALI_UK_VSYNC_EVENT_BEGIN_WAIT)
+ {
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC,
+ _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
+ }
+
+ if (event==_MALI_UK_VSYNC_EVENT_END_WAIT)
+ {
+
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME |
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC,
+ _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
+ }
+#endif
+
+ MALI_DEBUG_PRINT(4, ("Received VSYNC event: %d\n", event));
+ MALI_SUCCESS;
+}
+
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c
new file mode 100644
index 0000000..b5cfcb5
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.c
@@ -0,0 +1,463 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_l2_cache.h"
+#include "mali_hw_core.h"
+#include "mali_scheduler.h"
+#include "mali_pm_domain.h"
+
+/**
+ * Size of the Mali L2 cache registers in bytes
+ */
+#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30
+
+/**
+ * Mali L2 cache register numbers
+ * Used in the register read/write routines.
+ * See the hardware documentation for more information about each register
+ */
+typedef enum mali_l2_cache_register {
+ MALI400_L2_CACHE_REGISTER_STATUS = 0x0008,
+ /*unused = 0x000C */
+ MALI400_L2_CACHE_REGISTER_COMMAND = 0x0010, /**< Misc cache commands, e.g. clear */
+ MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0014,
+ MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0018, /**< Limit of outstanding read requests */
+ MALI400_L2_CACHE_REGISTER_ENABLE = 0x001C, /**< Enable misc cache features */
+ MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0020,
+ MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0024,
+ MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x0028,
+ MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x002C,
+} mali_l2_cache_register;
+
+/**
+ * Mali L2 cache commands
+ * These are the commands that can be sent to the Mali L2 cache unit
+ */
+typedef enum mali_l2_cache_command
+{
+ MALI400_L2_CACHE_COMMAND_CLEAR_ALL = 0x01, /**< Clear the entire cache */
+ /* Read HW TRM carefully before adding/using other commands than the clear above */
+} mali_l2_cache_command;
+
+/**
+ * Mali L2 cache commands
+ * These are the commands that can be sent to the Mali L2 cache unit
+ */
+typedef enum mali_l2_cache_enable
+{
+ MALI400_L2_CACHE_ENABLE_DEFAULT = 0x0, /**< Default state of enable register */
+ MALI400_L2_CACHE_ENABLE_ACCESS = 0x01, /**< Permit cacheable accesses */
+ MALI400_L2_CACHE_ENABLE_READ_ALLOCATE = 0x02, /**< Permit cache read allocate */
+} mali_l2_cache_enable;
+
+/**
+ * Mali L2 cache status bits
+ */
+typedef enum mali_l2_cache_status
+{
+ MALI400_L2_CACHE_STATUS_COMMAND_BUSY = 0x01, /**< Command handler of L2 cache is busy */
+ MALI400_L2_CACHE_STATUS_DATA_BUSY = 0x02, /**< L2 cache is busy handling data requests */
+} mali_l2_cache_status;
+
+#define MALI400_L2_MAX_READS_DEFAULT 0x1C
+
+static struct mali_l2_cache_core *mali_global_l2_cache_cores[MALI_MAX_NUMBER_OF_L2_CACHE_CORES] = { NULL, };
+static u32 mali_global_num_l2_cache_cores = 0;
+
+int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT;
+
+/* Local helper functions */
+static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val);
+
+
+struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t *resource)
+{
+ struct mali_l2_cache_core *cache = NULL;
+ _mali_osk_lock_flags_t lock_flags;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#else
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#endif
+
+ MALI_DEBUG_PRINT(2, ("Mali L2 cache: Creating Mali L2 cache: %s\n", resource->description));
+
+ if (mali_global_num_l2_cache_cores >= MALI_MAX_NUMBER_OF_L2_CACHE_CORES)
+ {
+ MALI_PRINT_ERROR(("Mali L2 cache: Too many L2 cache core objects created\n"));
+ return NULL;
+ }
+
+ cache = _mali_osk_malloc(sizeof(struct mali_l2_cache_core));
+ if (NULL != cache)
+ {
+ cache->core_id = mali_global_num_l2_cache_cores;
+ cache->counter_src0 = MALI_HW_CORE_NO_COUNTER;
+ cache->counter_src1 = MALI_HW_CORE_NO_COUNTER;
+ cache->pm_domain = NULL;
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&cache->hw_core, resource, MALI400_L2_CACHE_REGISTERS_SIZE))
+ {
+ cache->command_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND);
+ if (NULL != cache->command_lock)
+ {
+ cache->counter_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER);
+ if (NULL != cache->counter_lock)
+ {
+ mali_l2_cache_reset(cache);
+
+ cache->last_invalidated_id = 0;
+
+ mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = cache;
+ mali_global_num_l2_cache_cores++;
+
+ return cache;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali L2 cache: Failed to create counter lock for L2 cache core %s\n", cache->hw_core.description));
+ }
+
+ _mali_osk_lock_term(cache->command_lock);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali L2 cache: Failed to create command lock for L2 cache core %s\n", cache->hw_core.description));
+ }
+
+ mali_hw_core_delete(&cache->hw_core);
+ }
+
+ _mali_osk_free(cache);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali L2 cache: Failed to allocate memory for L2 cache core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_l2_cache_delete(struct mali_l2_cache_core *cache)
+{
+ u32 i;
+
+ /* reset to defaults */
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT);
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT);
+
+ _mali_osk_lock_term(cache->counter_lock);
+ _mali_osk_lock_term(cache->command_lock);
+ mali_hw_core_delete(&cache->hw_core);
+
+ for (i = 0; i < mali_global_num_l2_cache_cores; i++)
+ {
+ if (mali_global_l2_cache_cores[i] == cache)
+ {
+ mali_global_l2_cache_cores[i] = NULL;
+ mali_global_num_l2_cache_cores--;
+
+ if (i != mali_global_num_l2_cache_cores)
+ {
+ /* We removed a l2 cache from the middle of the array -- move the last
+ * l2 cache to the current position to close the gap */
+ mali_global_l2_cache_cores[i] = mali_global_l2_cache_cores[mali_global_num_l2_cache_cores];
+ mali_global_l2_cache_cores[mali_global_num_l2_cache_cores] = NULL;
+ }
+
+ break;
+ }
+ }
+
+ _mali_osk_free(cache);
+}
+
+u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache)
+{
+ return cache->core_id;
+}
+
+mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter)
+{
+ u32 value = 0; /* disabled src */
+ mali_bool core_is_on;
+
+ MALI_DEBUG_ASSERT_POINTER(cache);
+
+ core_is_on = mali_l2_cache_lock_power_state(cache);
+
+ _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ cache->counter_src0 = counter;
+
+ if (MALI_HW_CORE_NO_COUNTER != counter)
+ {
+ value = counter;
+ }
+
+ if (MALI_TRUE == core_is_on)
+ {
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, value);
+ }
+
+ _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ mali_l2_cache_unlock_power_state(cache);
+
+ return MALI_TRUE;
+}
+
+mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter)
+{
+ u32 value = 0; /* disabled src */
+ mali_bool core_is_on;
+
+ MALI_DEBUG_ASSERT_POINTER(cache);
+
+ core_is_on = mali_l2_cache_lock_power_state(cache);
+
+ _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ cache->counter_src1 = counter;
+
+ if (MALI_HW_CORE_NO_COUNTER != counter)
+ {
+ value = counter;
+ }
+
+ if (MALI_TRUE == core_is_on)
+ {
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, value);
+ }
+
+ _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ mali_l2_cache_unlock_power_state(cache);
+
+ return MALI_TRUE;
+}
+
+u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache)
+{
+ return cache->counter_src0;
+}
+
+u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache)
+{
+ return cache->counter_src1;
+}
+
+void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1)
+{
+ MALI_DEBUG_ASSERT(NULL != src0);
+ MALI_DEBUG_ASSERT(NULL != value0);
+ MALI_DEBUG_ASSERT(NULL != src1);
+ MALI_DEBUG_ASSERT(NULL != value1);
+
+ /* Caller must hold the PM lock and know that we are powered on */
+
+ _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ *src0 = cache->counter_src0;
+ *src1 = cache->counter_src1;
+
+ if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER)
+ {
+ *value0 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
+ }
+
+ if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER)
+ {
+ *value1 = mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
+ }
+
+ _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index)
+{
+ if (mali_global_num_l2_cache_cores > index)
+ {
+ return mali_global_l2_cache_cores[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_l2_cache_core_get_glob_num_l2_cores(void)
+{
+ return mali_global_num_l2_cache_cores;
+}
+
+void mali_l2_cache_reset(struct mali_l2_cache_core *cache)
+{
+ /* Invalidate cache (just to keep it in a known state at startup) */
+ mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+
+ /* Enable cache */
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads);
+
+ /* Restart any performance counters (if enabled) */
+ _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (cache->counter_src0 != MALI_HW_CORE_NO_COUNTER)
+ {
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, cache->counter_src0);
+ }
+
+ if (cache->counter_src1 != MALI_HW_CORE_NO_COUNTER)
+ {
+ mali_hw_core_register_write(&cache->hw_core, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, cache->counter_src1);
+ }
+
+ _mali_osk_lock_signal(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+void mali_l2_cache_reset_all(void)
+{
+ int i;
+ u32 num_cores = mali_l2_cache_core_get_glob_num_l2_cores();
+
+ for (i = 0; i < num_cores; i++)
+ {
+ mali_l2_cache_reset(mali_l2_cache_core_get_glob_l2_core(i));
+ }
+}
+
+void mali_l2_cache_invalidate(struct mali_l2_cache_core *cache)
+{
+ MALI_DEBUG_ASSERT_POINTER(cache);
+
+ if (NULL != cache)
+ {
+ cache->last_invalidated_id = mali_scheduler_get_new_id();
+ mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+ }
+}
+
+mali_bool mali_l2_cache_invalidate_conditional(struct mali_l2_cache_core *cache, u32 id)
+{
+ MALI_DEBUG_ASSERT_POINTER(cache);
+
+ if (NULL != cache)
+ {
+ /* If the last cache invalidation was done by a job with a higher id we
+ * don't have to flush. Since user space will store jobs w/ their
+ * corresponding memory in sequence (first job #0, then job #1, ...),
+ * we don't have to flush for job n-1 if job n has already invalidated
+ * the cache since we know for sure that job n-1's memory was already
+ * written when job n was started. */
+ if (((s32)id) <= ((s32)cache->last_invalidated_id))
+ {
+ return MALI_FALSE;
+ }
+ else
+ {
+ cache->last_invalidated_id = mali_scheduler_get_new_id();
+ }
+
+ mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+ }
+ return MALI_TRUE;
+}
+
+void mali_l2_cache_invalidate_all(void)
+{
+ u32 i;
+ for (i = 0; i < mali_global_num_l2_cache_cores; i++)
+ {
+ /*additional check*/
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_l2_cache_cores[i]))
+ {
+ _mali_osk_errcode_t ret;
+ mali_global_l2_cache_cores[i]->last_invalidated_id = mali_scheduler_get_new_id();
+ ret = mali_l2_cache_send_command(mali_global_l2_cache_cores[i], MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to invalidate cache\n"));
+ }
+ }
+ mali_l2_cache_unlock_power_state(mali_global_l2_cache_cores[i]);
+ }
+}
+
+void mali_l2_cache_invalidate_all_pages(u32 *pages, u32 num_pages)
+{
+ u32 i;
+ for (i = 0; i < mali_global_num_l2_cache_cores; i++)
+ {
+ /*additional check*/
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_l2_cache_cores[i]))
+ {
+ u32 j;
+ for (j = 0; j < num_pages; j++)
+ {
+ _mali_osk_errcode_t ret;
+ ret = mali_l2_cache_send_command(mali_global_l2_cache_cores[i], MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[j]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to invalidate page cache\n"));
+ }
+ }
+ }
+ mali_l2_cache_unlock_power_state(mali_global_l2_cache_cores[i]);
+ }
+}
+
+mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache)
+{
+ return mali_pm_domain_lock_state(cache->pm_domain);
+}
+
+void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache)
+{
+ return mali_pm_domain_unlock_state(cache->pm_domain);
+}
+
+/* -------- local helper functions below -------- */
+
+
+static _mali_osk_errcode_t mali_l2_cache_send_command(struct mali_l2_cache_core *cache, u32 reg, u32 val)
+{
+ int i = 0;
+ const int loop_count = 100000;
+
+ /*
+ * Grab lock in order to send commands to the L2 cache in a serialized fashion.
+ * The L2 cache will ignore commands if it is busy.
+ */
+ _mali_osk_lock_wait(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* First, wait for L2 cache command handler to go idle */
+
+ for (i = 0; i < loop_count; i++)
+ {
+ if (!(mali_hw_core_register_read(&cache->hw_core, MALI400_L2_CACHE_REGISTER_STATUS) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY))
+ {
+ break;
+ }
+ }
+
+ if (i == loop_count)
+ {
+ _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
+ MALI_DEBUG_PRINT(1, ( "Mali L2 cache: aborting wait for command interface to go idle\n"));
+ MALI_ERROR( _MALI_OSK_ERR_FAULT );
+ }
+
+ /* then issue the command */
+ mali_hw_core_register_write(&cache->hw_core, reg, val);
+
+ _mali_osk_lock_signal(cache->command_lock, _MALI_OSK_LOCKMODE_RW);
+
+ MALI_SUCCESS;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h
new file mode 100644
index 0000000..cabed39
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_l2_cache.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_L2_CACHE_H__
+#define __MALI_KERNEL_L2_CACHE_H__
+
+#include "mali_osk.h"
+#include "mali_hw_core.h"
+#include "mali_pm_domain.h"
+
+#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES 3
+/* Maximum 1 GP and 4 PP for an L2 cache core (Mali-400 Quad-core) */
+#define MALI_MAX_NUMBER_OF_GROUPS_PER_L2_CACHE 5
+
+struct mali_group;
+
+/**
+ * Definition of the L2 cache core struct
+ * Used to track a L2 cache unit in the system.
+ * Contains information about the mapping of the registers
+ */
+struct mali_l2_cache_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ u32 core_id; /**< Unique core ID */
+ _mali_osk_lock_t *command_lock; /**< Serialize all L2 cache commands */
+ _mali_osk_lock_t *counter_lock; /**< Synchronize L2 cache counter access */
+ u32 counter_src0; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
+ u32 counter_src1; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
+ u32 last_invalidated_id;
+ struct mali_pm_domain *pm_domain;
+};
+
+_mali_osk_errcode_t mali_l2_cache_initialize(void);
+void mali_l2_cache_terminate(void);
+
+struct mali_l2_cache_core *mali_l2_cache_create(_mali_osk_resource_t * resource);
+void mali_l2_cache_delete(struct mali_l2_cache_core *cache);
+
+MALI_STATIC_INLINE void mali_l2_cache_set_pm_domain(struct mali_l2_cache_core *cache, struct mali_pm_domain *domain)
+{
+ cache->pm_domain = domain;
+}
+
+u32 mali_l2_cache_get_id(struct mali_l2_cache_core *cache);
+
+mali_bool mali_l2_cache_core_set_counter_src0(struct mali_l2_cache_core *cache, u32 counter);
+mali_bool mali_l2_cache_core_set_counter_src1(struct mali_l2_cache_core *cache, u32 counter);
+u32 mali_l2_cache_core_get_counter_src0(struct mali_l2_cache_core *cache);
+u32 mali_l2_cache_core_get_counter_src1(struct mali_l2_cache_core *cache);
+void mali_l2_cache_core_get_counter_values(struct mali_l2_cache_core *cache, u32 *src0, u32 *value0, u32 *src1, u32 *value1);
+struct mali_l2_cache_core *mali_l2_cache_core_get_glob_l2_core(u32 index);
+u32 mali_l2_cache_core_get_glob_num_l2_cores(void);
+
+void mali_l2_cache_reset(struct mali_l2_cache_core *cache);
+void mali_l2_cache_reset_all(void);
+
+struct mali_group *mali_l2_cache_get_group(struct mali_l2_cache_core *cache, u32 index);
+
+void mali_l2_cache_invalidate(struct mali_l2_cache_core *cache);
+mali_bool mali_l2_cache_invalidate_conditional(struct mali_l2_cache_core *cache, u32 id);
+void mali_l2_cache_invalidate_all(void);
+void mali_l2_cache_invalidate_all_pages(u32 *pages, u32 num_pages);
+
+mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache);
+void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache);
+
+#endif /* __MALI_KERNEL_L2_CACHE_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c
new file mode 100644
index 0000000..fac6d93
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_mem_validation.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+/* MALI_SEC */
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#ifndef CONFIG_MACH_KONA
+#define MALI_SEC_MEM_VALIDATION
+#endif
+#include <linux/cma.h>
+#include <plat/pd.h>
+#include <linux/platform_device.h>
+#endif
+
+#define MALI_INVALID_MEM_ADDR 0xFFFFFFFF
+
+typedef struct
+{
+ u32 phys_base; /**< Mali physical base of the memory, page aligned */
+ u32 size; /**< size in bytes of the memory, multiple of page size */
+} _mali_mem_validation_t;
+
+/* MALI_SEC */
+#if defined(MALI_SEC_MEM_VALIDATION)
+extern struct platform_device exynos4_device_pd[];
+#endif
+
+static _mali_mem_validation_t mali_mem_validator = { MALI_INVALID_MEM_ADDR, MALI_INVALID_MEM_ADDR };
+
+_mali_osk_errcode_t mali_mem_validation_add_range(u32 start, u32 size)
+{
+ /* MALI_SEC */
+#if defined(MALI_SEC_MEM_VALIDATION)
+ struct cma_info mem_info;
+#endif
+
+ /* Check that no other MEM_VALIDATION resources exist */
+ if (MALI_INVALID_MEM_ADDR != mali_mem_validator.phys_base)
+ {
+ MALI_PRINT_ERROR(("Failed to add frame buffer memory; another range is already specified\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* MALI_SEC */
+#if defined(MALI_SEC_MEM_VALIDATION)
+ if (cma_info(&mem_info, &exynos4_device_pd[PD_G3D].dev, "fimd")) {
+ MALI_PRINT_ERROR(("Failed to get framebuffer information from CMA\n"));
+ return _MALI_OSK_ERR_FAULT;
+ } else {
+ start = mem_info.lower_bound;
+ size = mem_info.total_size - mem_info.free_size;
+ }
+#endif
+
+ /* Check restrictions on page alignment */
+ if ((0 != (start & (~_MALI_OSK_CPU_PAGE_MASK))) ||
+ (0 != (size & (~_MALI_OSK_CPU_PAGE_MASK))))
+ {
+ MALI_PRINT_ERROR(("Failed to add frame buffer memory; incorrect alignment\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mali_mem_validator.phys_base = start;
+ mali_mem_validator.size = size;
+ MALI_DEBUG_PRINT(2, ("Memory Validator installed for Mali physical address base=0x%08X, size=0x%08X\n",
+ mali_mem_validator.phys_base, mali_mem_validator.size));
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size)
+{
+ if (phys_addr < (phys_addr + size)) /* Don't allow overflow (or zero size) */
+ {
+ if ((0 == ( phys_addr & (~_MALI_OSK_CPU_PAGE_MASK))) &&
+ (0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK))))
+ {
+ if ((phys_addr >= mali_mem_validator.phys_base) &&
+ ((phys_addr + (size - 1)) >= mali_mem_validator.phys_base) &&
+ (phys_addr <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) &&
+ ((phys_addr + (size - 1)) <= (mali_mem_validator.phys_base + (mali_mem_validator.size - 1))) )
+ {
+ MALI_DEBUG_PRINT(3, ("Accepted range 0x%08X + size 0x%08X (= 0x%08X)\n", phys_addr, size, (phys_addr + size - 1)));
+ return _MALI_OSK_ERR_OK;
+ }
+ }
+ }
+
+ MALI_PRINT_ERROR(("MALI PHYSICAL RANGE VALIDATION ERROR: The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_addr, size));
+
+ return _MALI_OSK_ERR_FAULT;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h
new file mode 100644
index 0000000..1eeab38
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mem_validation.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MEM_VALIDATION_H__
+#define __MALI_MEM_VALIDATION_H__
+
+#include "mali_osk.h"
+
+_mali_osk_errcode_t mali_mem_validation_add_range(u32 start, u32 size);
+_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size);
+
+#endif /* __MALI_MEM_VALIDATION_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_memory.c b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.c
new file mode 100644
index 0000000..1654675
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.c
@@ -0,0 +1,1295 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_kernel_descriptor_mapping.h"
+#include "mali_mem_validation.h"
+#include "mali_memory.h"
+#include "mali_mmu_page_directory.h"
+#include "mali_kernel_memory_engine.h"
+#include "mali_block_allocator.h"
+#include "mali_kernel_mem_os.h"
+#include "mali_session.h"
+#include "mali_l2_cache.h"
+#include "mali_scheduler.h"
+#if defined(CONFIG_MALI400_UMP)
+#include "ump_kernel_interface.h"
+#endif
+
+/* kernel side OS functions and user-kernel interface */
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+#include "mali_osk_list.h"
+#include "mali_osk_bitops.h"
+
+/**
+ * Per-session memory descriptor mapping table sizes
+ */
+#define MALI_MEM_DESCRIPTORS_INIT 64
+#define MALI_MEM_DESCRIPTORS_MAX 65536
+
+typedef struct dedicated_memory_info
+{
+ u32 base;
+ u32 size;
+ struct dedicated_memory_info * next;
+} dedicated_memory_info;
+
+/* types used for external_memory and ump_memory physical memory allocators, which are using the mali_allocation_engine */
+#if defined(CONFIG_MALI400_UMP)
+typedef struct ump_mem_allocation
+{
+ mali_allocation_engine * engine;
+ mali_memory_allocation * descriptor;
+ u32 initial_offset;
+ u32 size_allocated;
+ ump_dd_handle ump_mem;
+} ump_mem_allocation ;
+#endif
+
+typedef struct external_mem_allocation
+{
+ mali_allocation_engine * engine;
+ mali_memory_allocation * descriptor;
+ u32 initial_offset;
+ u32 size;
+} external_mem_allocation;
+
+/**
+ * @brief Internal function for unmapping memory
+ *
+ * Worker function for unmapping memory from a user-process. We assume that the
+ * session/descriptor's lock was obtained before entry. For example, the
+ * wrapper _mali_ukk_mem_munmap() will lock the descriptor, then call this
+ * function to do the actual unmapping. mali_memory_core_session_end() could
+ * also call this directly (depending on compilation options), having locked
+ * the descriptor.
+ *
+ * This function will fail if it is unable to put the MMU in stall mode (which
+ * might be the case if a page fault is also being processed).
+ *
+ * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args );
+
+#if defined(CONFIG_MALI400_UMP)
+static void ump_memory_release(void * ctx, void * handle);
+static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
+#endif /* CONFIG_MALI400_UMP */
+
+
+static void external_memory_release(void * ctx, void * handle);
+static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info);
+
+
+/* nop functions */
+
+/* mali address manager needs to allocate page tables on allocate, write to page table(s) on map, write to page table(s) and release page tables on release */
+static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor); /* validates the range, allocates memory for the page tables if needed */
+static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size);
+static void mali_address_manager_release(mali_memory_allocation * descriptor);
+
+/* MMU variables */
+
+typedef struct mali_mmu_page_table_allocation
+{
+ _mali_osk_list_t list;
+ u32 * usage_map;
+ u32 usage_count;
+ u32 num_pages;
+ mali_page_table_block pages;
+} mali_mmu_page_table_allocation;
+
+typedef struct mali_mmu_page_table_allocations
+{
+ _mali_osk_lock_t *lock;
+ _mali_osk_list_t partial;
+ _mali_osk_list_t full;
+ /* we never hold on to a empty allocation */
+} mali_mmu_page_table_allocations;
+
+static mali_kernel_mem_address_manager mali_address_manager =
+{
+ mali_address_manager_allocate, /* allocate */
+ mali_address_manager_release, /* release */
+ mali_address_manager_map, /* map_physical */
+ NULL /* unmap_physical not present*/
+};
+
+/* the mmu page table cache */
+static struct mali_mmu_page_table_allocations page_table_cache;
+
+
+static mali_kernel_mem_address_manager process_address_manager =
+{
+ _mali_osk_mem_mapregion_init, /* allocate */
+ _mali_osk_mem_mapregion_term, /* release */
+ _mali_osk_mem_mapregion_map, /* map_physical */
+ _mali_osk_mem_mapregion_unmap /* unmap_physical */
+};
+
+static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void);
+static void mali_mmu_page_table_cache_destroy(void);
+
+static mali_allocation_engine memory_engine = NULL;
+static mali_physical_memory_allocator * physical_memory_allocators = NULL;
+
+static dedicated_memory_info * mem_region_registrations = NULL;
+
+mali_allocation_engine mali_mem_get_memory_engine(void)
+{
+ return memory_engine;
+}
+
+/* called during module init */
+_mali_osk_errcode_t mali_memory_initialize(void)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_PRINT(2, ("Memory system initializing\n"));
+
+ err = mali_mmu_page_table_cache_create();
+ if(_MALI_OSK_ERR_OK != err)
+ {
+ MALI_ERROR(err);
+ }
+
+ memory_engine = mali_allocation_engine_create(&mali_address_manager, &process_address_manager);
+ MALI_CHECK_NON_NULL( memory_engine, _MALI_OSK_ERR_FAULT);
+
+ MALI_SUCCESS;
+}
+
+/* called if/when our module is unloaded */
+void mali_memory_terminate(void)
+{
+ MALI_DEBUG_PRINT(2, ("Memory system terminating\n"));
+
+ mali_mmu_page_table_cache_destroy();
+
+ while ( NULL != mem_region_registrations)
+ {
+ dedicated_memory_info * m;
+ m = mem_region_registrations;
+ mem_region_registrations = m->next;
+ _mali_osk_mem_unreqregion(m->base, m->size);
+ _mali_osk_free(m);
+ }
+
+ while ( NULL != physical_memory_allocators)
+ {
+ mali_physical_memory_allocator * m;
+ m = physical_memory_allocators;
+ physical_memory_allocators = m->next;
+ m->destroy(m);
+ }
+
+ if (NULL != memory_engine)
+ {
+ mali_allocation_engine_destroy(memory_engine);
+ memory_engine = NULL;
+ }
+}
+
+_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data * session_data)
+{
+ MALI_DEBUG_PRINT(5, ("Memory session begin\n"));
+
+ /* create descriptor mapping table */
+ session_data->descriptor_mapping = mali_descriptor_mapping_create(MALI_MEM_DESCRIPTORS_INIT, MALI_MEM_DESCRIPTORS_MAX);
+
+ if (NULL == session_data->descriptor_mapping)
+ {
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ session_data->memory_lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK
+ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_SESSION);
+ if (NULL == session_data->memory_lock)
+ {
+ mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ /* Init the session's memory allocation list */
+ _MALI_OSK_INIT_LIST_HEAD( &session_data->memory_head );
+
+ MALI_DEBUG_PRINT(5, ("MMU session begin: success\n"));
+ MALI_SUCCESS;
+}
+
+static void descriptor_table_cleanup_callback(int descriptor_id, void* map_target)
+{
+ mali_memory_allocation * descriptor;
+
+ descriptor = (mali_memory_allocation*)map_target;
+
+ MALI_DEBUG_PRINT(3, ("Cleanup of descriptor %d mapping to 0x%x in descriptor table\n", descriptor_id, map_target));
+ MALI_DEBUG_ASSERT(descriptor);
+
+ mali_allocation_engine_release_memory(memory_engine, descriptor);
+ _mali_osk_free(descriptor);
+}
+
+void mali_memory_session_end(struct mali_session_data *session_data)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_BUSY;
+
+ MALI_DEBUG_PRINT(3, ("MMU session end\n"));
+
+ if (NULL == session_data)
+ {
+ MALI_DEBUG_PRINT(1, ("No session data found during session end\n"));
+ return;
+ }
+
+ while (err == _MALI_OSK_ERR_BUSY)
+ {
+ /* Lock the session so we can modify the memory list */
+ _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+ err = _MALI_OSK_ERR_OK;
+
+ /* Free all memory engine allocations */
+ if (!_mali_osk_list_empty(&session_data->memory_head))
+ {
+ mali_memory_allocation *descriptor;
+ mali_memory_allocation *temp;
+ _mali_uk_mem_munmap_s unmap_args;
+
+ MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n"));
+
+ unmap_args.ctx = session_data;
+
+ /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */
+ _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->memory_head, mali_memory_allocation, list)
+ {
+ MALI_DEBUG_PRINT(4, ("Freeing block with mali address 0x%x size %d mapped in user space at 0x%x\n",
+ descriptor->mali_address, descriptor->size, descriptor->size, descriptor->mapping)
+ );
+ /* ASSERT that the descriptor's lock references the correct thing */
+ MALI_DEBUG_ASSERT( descriptor->lock == session_data->memory_lock );
+ /* Therefore, we have already locked the descriptor */
+
+ unmap_args.size = descriptor->size;
+ unmap_args.mapping = descriptor->mapping;
+ unmap_args.cookie = (u32)descriptor;
+
+ /*
+ * This removes the descriptor from the list, and frees the descriptor
+ *
+ * Does not handle the _MALI_OSK_SPECIFIC_INDIRECT_MMAP case, since
+ * the only OS we are aware of that requires indirect MMAP also has
+ * implicit mmap cleanup.
+ */
+ err = _mali_ukk_mem_munmap_internal( &unmap_args );
+
+ if (err == _MALI_OSK_ERR_BUSY)
+ {
+ _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+ /*
+ * Reason for this;
+ * We where unable to stall the MMU, probably because we are in page fault handling.
+ * Sleep for a while with the session lock released, then try again.
+ * Abnormal termination of programs with running Mali jobs is a normal reason for this.
+ */
+ _mali_osk_time_ubusydelay(10);
+ break; /* Will jump back into: "while (err == _MALI_OSK_ERR_BUSY)" */
+ }
+ }
+ }
+ }
+ /* Assert that we really did free everything */
+ MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) );
+
+ if (NULL != session_data->descriptor_mapping)
+ {
+ mali_descriptor_mapping_call_for_each(session_data->descriptor_mapping, descriptor_table_cleanup_callback);
+ mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
+ session_data->descriptor_mapping = NULL;
+ }
+
+ _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ /**
+ * @note Could the VMA close handler mean that we use the session data after it was freed?
+ * In which case, would need to refcount the session data, and free on VMA close
+ */
+
+ /* Free the lock */
+ _mali_osk_lock_term( session_data->memory_lock );
+
+ return;
+}
+
+_mali_osk_errcode_t mali_memory_core_resource_os_memory(u32 size)
+{
+ mali_physical_memory_allocator * allocator;
+ mali_physical_memory_allocator ** next_allocator_list;
+
+ u32 alloc_order = 1; /* OS memory has second priority */
+
+ allocator = mali_os_allocator_create(size, 0 /* cpu_usage_adjust */, "Shared Mali GPU memory");
+ if (NULL == allocator)
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to create OS memory allocator\n"));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ allocator->alloc_order = alloc_order;
+
+ /* link in the allocator: insertion into ordered list
+ * resources of the same alloc_order will be Last-in-first */
+ next_allocator_list = &physical_memory_allocators;
+
+ while (NULL != *next_allocator_list &&
+ (*next_allocator_list)->alloc_order < alloc_order )
+ {
+ next_allocator_list = &((*next_allocator_list)->next);
+ }
+
+ allocator->next = (*next_allocator_list);
+ (*next_allocator_list) = allocator;
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size)
+{
+ mali_physical_memory_allocator * allocator;
+ mali_physical_memory_allocator ** next_allocator_list;
+ dedicated_memory_info * cleanup_data;
+
+ u32 alloc_order = 0; /* Dedicated range has first priority */
+
+ /* do the low level linux operation first */
+
+ /* Request ownership of the memory */
+ if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(start, size, "Dedicated Mali GPU memory"))
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to request memory region for frame buffer (0x%08X - 0x%08X)\n", start, start + size - 1));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ /* create generic block allocator object to handle it */
+ allocator = mali_block_allocator_create(start, 0 /* cpu_usage_adjust */, size, "Dedicated Mali GPU memory");
+
+ if (NULL == allocator)
+ {
+ MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
+ _mali_osk_mem_unreqregion(start, size);
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ /* save low level cleanup info */
+ allocator->alloc_order = alloc_order;
+
+ cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info));
+
+ if (NULL == cleanup_data)
+ {
+ _mali_osk_mem_unreqregion(start, size);
+ allocator->destroy(allocator);
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ cleanup_data->base = start;
+ cleanup_data->size = size;
+
+ cleanup_data->next = mem_region_registrations;
+ mem_region_registrations = cleanup_data;
+
+ /* link in the allocator: insertion into ordered list
+ * resources of the same alloc_order will be Last-in-first */
+ next_allocator_list = &physical_memory_allocators;
+
+ while ( NULL != *next_allocator_list &&
+ (*next_allocator_list)->alloc_order < alloc_order )
+ {
+ next_allocator_list = &((*next_allocator_list)->next);
+ }
+
+ allocator->next = (*next_allocator_list);
+ (*next_allocator_list) = allocator;
+
+ MALI_SUCCESS;
+}
+
+#if defined(CONFIG_MALI400_UMP)
+static mali_physical_memory_allocation_result ump_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
+{
+ ump_dd_handle ump_mem;
+ u32 nr_blocks;
+ u32 i;
+ ump_dd_physical_block * ump_blocks;
+ ump_mem_allocation *ret_allocation;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(alloc_info);
+
+ ret_allocation = _mali_osk_malloc( sizeof( ump_mem_allocation ) );
+ if ( NULL==ret_allocation ) return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+
+ ump_mem = (ump_dd_handle)ctx;
+
+ MALI_DEBUG_PRINT(4, ("In ump_memory_commit\n"));
+
+ nr_blocks = ump_dd_phys_block_count_get(ump_mem);
+
+ MALI_DEBUG_PRINT(4, ("Have %d blocks\n", nr_blocks));
+
+ if (nr_blocks == 0)
+ {
+ MALI_DEBUG_PRINT(1, ("No block count\n"));
+ _mali_osk_free( ret_allocation );
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+
+ ump_blocks = _mali_osk_malloc(sizeof(*ump_blocks)*nr_blocks );
+ if ( NULL==ump_blocks )
+ {
+ _mali_osk_free( ret_allocation );
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+
+ if (UMP_DD_INVALID == ump_dd_phys_blocks_get(ump_mem, ump_blocks, nr_blocks))
+ {
+ _mali_osk_free(ump_blocks);
+ _mali_osk_free( ret_allocation );
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+
+ /* Store away the initial offset for unmapping purposes */
+ ret_allocation->initial_offset = *offset;
+
+ for(i=0; i<nr_blocks; ++i)
+ {
+ MALI_DEBUG_PRINT(4, ("Mapping in 0x%08x size %d\n", ump_blocks[i].addr , ump_blocks[i].size));
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[i].addr , 0, ump_blocks[i].size ))
+ {
+ u32 size_allocated = *offset - ret_allocation->initial_offset;
+ MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n"));
+
+ /* unmap all previous blocks (if any) */
+ mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
+
+ _mali_osk_free(ump_blocks);
+ _mali_osk_free(ret_allocation);
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+ *offset += ump_blocks[i].size;
+ }
+
+ if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
+ {
+ /* Map in an extra virtual guard page at the end of the VMA */
+ MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n"));
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, ump_blocks[0].addr , 0, _MALI_OSK_MALI_PAGE_SIZE ))
+ {
+ u32 size_allocated = *offset - ret_allocation->initial_offset;
+ MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n"));
+
+ /* unmap all previous blocks (if any) */
+ mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
+
+ _mali_osk_free(ump_blocks);
+ _mali_osk_free(ret_allocation);
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+ *offset += _MALI_OSK_MALI_PAGE_SIZE;
+ }
+
+ _mali_osk_free( ump_blocks );
+
+ ret_allocation->engine = engine;
+ ret_allocation->descriptor = descriptor;
+ ret_allocation->ump_mem = ump_mem;
+ ret_allocation->size_allocated = *offset - ret_allocation->initial_offset;
+
+ alloc_info->ctx = NULL;
+ alloc_info->handle = ret_allocation;
+ alloc_info->next = NULL;
+ alloc_info->release = ump_memory_release;
+
+ return MALI_MEM_ALLOC_FINISHED;
+}
+
+static void ump_memory_release(void * ctx, void * handle)
+{
+ ump_dd_handle ump_mem;
+ ump_mem_allocation *allocation;
+
+ allocation = (ump_mem_allocation *)handle;
+
+ MALI_DEBUG_ASSERT_POINTER( allocation );
+
+ ump_mem = allocation->ump_mem;
+
+ MALI_DEBUG_ASSERT(UMP_DD_HANDLE_INVALID!=ump_mem);
+
+ /* At present, this is a no-op. But, it allows the mali_address_manager to
+ * do unmapping of a subrange in future. */
+ mali_allocation_engine_unmap_physical( allocation->engine,
+ allocation->descriptor,
+ allocation->initial_offset,
+ allocation->size_allocated,
+ (_mali_osk_mem_mapregion_flags_t)0
+ );
+ _mali_osk_free( allocation );
+
+
+ ump_dd_reference_release(ump_mem) ;
+ return;
+}
+
+_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args )
+{
+ ump_dd_handle ump_mem;
+ mali_physical_memory_allocator external_memory_allocator;
+ struct mali_session_data *session_data;
+ mali_memory_allocation * descriptor;
+ int md;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ session_data = (struct mali_session_data *)args->ctx;
+ MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
+
+ /* check arguments */
+ /* NULL might be a valid Mali address */
+ if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+
+ /* size must be a multiple of the system page size */
+ if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+
+ MALI_DEBUG_PRINT(3,
+ ("Requested to map ump memory with secure id %d into virtual memory 0x%08X, size 0x%08X\n",
+ args->secure_id, args->mali_address, args->size));
+
+ ump_mem = ump_dd_handle_create_from_secure_id( (int)args->secure_id ) ;
+
+ if ( UMP_DD_HANDLE_INVALID==ump_mem ) MALI_ERROR(_MALI_OSK_ERR_FAULT);
+
+ descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
+ if (NULL == descriptor)
+ {
+ ump_dd_reference_release(ump_mem);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ descriptor->size = args->size;
+ descriptor->mapping = NULL;
+ descriptor->mali_address = args->mali_address;
+ descriptor->mali_addr_mapping_info = (void*)session_data;
+ descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
+ descriptor->cache_settings = (u32) MALI_CACHE_STANDARD;
+ descriptor->lock = session_data->memory_lock;
+
+ if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
+ {
+ descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
+ }
+ _mali_osk_list_init( &descriptor->list );
+
+ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md))
+ {
+ ump_dd_reference_release(ump_mem);
+ _mali_osk_free(descriptor);
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ external_memory_allocator.allocate = ump_memory_commit;
+ external_memory_allocator.allocate_page_table_block = NULL;
+ external_memory_allocator.ctx = ump_mem;
+ external_memory_allocator.name = "UMP Memory";
+ external_memory_allocator.next = NULL;
+
+ _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
+ {
+ _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+ mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
+ ump_dd_reference_release(ump_mem);
+ _mali_osk_free(descriptor);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ args->cookie = md;
+
+ MALI_DEBUG_PRINT(5,("Returning from UMP attach\n"));
+
+ /* All OK */
+ MALI_SUCCESS;
+}
+
+
+_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args )
+{
+ mali_memory_allocation * descriptor;
+ struct mali_session_data *session_data;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ session_data = (struct mali_session_data *)args->ctx;
+ MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
+
+ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor))
+ {
+ MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release ump memory\n", args->cookie));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ descriptor = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
+
+ if (NULL != descriptor)
+ {
+ _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ mali_allocation_engine_release_memory(memory_engine, descriptor);
+
+ _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ _mali_osk_free(descriptor);
+ }
+
+ MALI_SUCCESS;
+
+}
+#endif /* CONFIG_MALI400_UMP */
+
+
+static mali_physical_memory_allocation_result external_memory_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
+{
+ u32 * data;
+ external_mem_allocation * ret_allocation;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(alloc_info);
+
+ ret_allocation = _mali_osk_malloc( sizeof(external_mem_allocation) );
+
+ if ( NULL == ret_allocation )
+ {
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+
+ data = (u32*)ctx;
+
+ ret_allocation->engine = engine;
+ ret_allocation->descriptor = descriptor;
+ ret_allocation->initial_offset = *offset;
+
+ alloc_info->ctx = NULL;
+ alloc_info->handle = ret_allocation;
+ alloc_info->next = NULL;
+ alloc_info->release = external_memory_release;
+
+ MALI_DEBUG_PRINT(5, ("External map: mapping phys 0x%08X at mali virtual address 0x%08X staring at offset 0x%08X length 0x%08X\n", data[0], descriptor->mali_address, *offset, data[1]));
+
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, data[1]))
+ {
+ MALI_DEBUG_PRINT(1, ("Mapping of external memory failed\n"));
+ _mali_osk_free(ret_allocation);
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+ *offset += data[1];
+
+ if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
+ {
+ /* Map in an extra virtual guard page at the end of the VMA */
+ MALI_DEBUG_PRINT(4, ("Mapping in extra guard page\n"));
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_map_physical(engine, descriptor, *offset, data[0], 0, _MALI_OSK_MALI_PAGE_SIZE))
+ {
+ u32 size_allocated = *offset - ret_allocation->initial_offset;
+ MALI_DEBUG_PRINT(1, ("Mapping of external memory (guard page) failed\n"));
+
+ /* unmap what we previously mapped */
+ mali_allocation_engine_unmap_physical(engine, descriptor, ret_allocation->initial_offset, size_allocated, (_mali_osk_mem_mapregion_flags_t)0 );
+ _mali_osk_free(ret_allocation);
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+ }
+ *offset += _MALI_OSK_MALI_PAGE_SIZE;
+ }
+
+ ret_allocation->size = *offset - ret_allocation->initial_offset;
+
+ return MALI_MEM_ALLOC_FINISHED;
+}
+
+static void external_memory_release(void * ctx, void * handle)
+{
+ external_mem_allocation * allocation;
+
+ allocation = (external_mem_allocation *) handle;
+ MALI_DEBUG_ASSERT_POINTER( allocation );
+
+ /* At present, this is a no-op. But, it allows the mali_address_manager to
+ * do unmapping of a subrange in future. */
+
+ mali_allocation_engine_unmap_physical( allocation->engine,
+ allocation->descriptor,
+ allocation->initial_offset,
+ allocation->size,
+ (_mali_osk_mem_mapregion_flags_t)0
+ );
+
+ _mali_osk_free( allocation );
+
+ return;
+}
+
+_mali_osk_errcode_t _mali_ukk_mem_write_safe(_mali_uk_mem_write_safe_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ if (NULL == args->ctx)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ /* Return number of bytes actually copied */
+ args->size = _mali_osk_mem_write_safe(args->dest, args->src, args->size);
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args )
+{
+ mali_physical_memory_allocator external_memory_allocator;
+ struct mali_session_data *session_data;
+ u32 info[2];
+ mali_memory_allocation * descriptor;
+ int md;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ session_data = (struct mali_session_data *)args->ctx;
+ MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
+
+ external_memory_allocator.allocate = external_memory_commit;
+ external_memory_allocator.allocate_page_table_block = NULL;
+ external_memory_allocator.ctx = &info[0];
+ external_memory_allocator.name = "External Memory";
+ external_memory_allocator.next = NULL;
+
+ /* check arguments */
+ /* NULL might be a valid Mali address */
+ if ( ! args->size) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+
+ /* size must be a multiple of the system page size */
+ if ( args->size % _MALI_OSK_MALI_PAGE_SIZE ) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+
+ MALI_DEBUG_PRINT(3,
+ ("Requested to map physical memory 0x%x-0x%x into virtual memory 0x%x\n",
+ (void*)args->phys_addr,
+ (void*)(args->phys_addr + args->size -1),
+ (void*)args->mali_address)
+ );
+
+ /* Validate the mali physical range */
+ if (_MALI_OSK_ERR_OK != mali_mem_validation_check(args->phys_addr, args->size))
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ info[0] = args->phys_addr;
+ info[1] = args->size;
+
+ descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
+ if (NULL == descriptor) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+
+ descriptor->size = args->size;
+ descriptor->mapping = NULL;
+ descriptor->mali_address = args->mali_address;
+ descriptor->mali_addr_mapping_info = (void*)session_data;
+ descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
+ descriptor->cache_settings = (u32)MALI_CACHE_STANDARD;
+ descriptor->lock = session_data->memory_lock;
+ if (args->flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
+ {
+ descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
+ }
+ _mali_osk_list_init( &descriptor->list );
+
+ _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(memory_engine, descriptor, &external_memory_allocator, NULL))
+ {
+ _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_free(descriptor);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, descriptor, &md))
+ {
+ mali_allocation_engine_release_memory(memory_engine, descriptor);
+ _mali_osk_free(descriptor);
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ args->cookie = md;
+
+ MALI_DEBUG_PRINT(5,("Returning from range_map_external_memory\n"));
+
+ /* All OK */
+ MALI_SUCCESS;
+}
+
+
+_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args )
+{
+ mali_memory_allocation * descriptor;
+ void* old_value;
+ struct mali_session_data *session_data;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ session_data = (struct mali_session_data *)args->ctx;
+ MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
+
+ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_get(session_data->descriptor_mapping, args->cookie, (void**)&descriptor))
+ {
+ MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to unmap external memory\n", args->cookie));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ old_value = mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
+
+ if (NULL != old_value)
+ {
+ _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ mali_allocation_engine_release_memory(memory_engine, descriptor);
+
+ _mali_osk_lock_signal( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ _mali_osk_free(descriptor);
+ }
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args )
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ args->memory_size = 2 * 1024 * 1024 * 1024UL; /* 2GB address space */
+ args->mali_address_base = 1 * 1024 * 1024 * 1024UL; /* staring at 1GB, causing this layout: (0-1GB unused)(1GB-3G usage by Mali)(3G-4G unused) */
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args )
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_SUCCESS;
+}
+
+static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor)
+{
+ struct mali_session_data *session_data;
+ u32 actual_size;
+
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
+
+ actual_size = descriptor->size;
+
+ if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
+ {
+ actual_size += _MALI_OSK_MALI_PAGE_SIZE;
+ }
+
+ return mali_mmu_pagedir_map(session_data->page_directory, descriptor->mali_address, actual_size);
+}
+
+static void mali_address_manager_release(mali_memory_allocation * descriptor)
+{
+ const u32 illegal_mali_address = 0xffffffff;
+ struct mali_session_data *session_data;
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ /* It is allowed to call this function several times on the same descriptor.
+ When memory is released we set the illegal_mali_address so we can early out here. */
+ if ( illegal_mali_address == descriptor->mali_address) return;
+
+ session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
+ mali_mmu_pagedir_unmap(session_data->page_directory, descriptor->mali_address, descriptor->size);
+
+ descriptor->mali_address = illegal_mali_address ;
+}
+
+static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size)
+{
+ struct mali_session_data *session_data;
+ u32 mali_address;
+
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(phys_addr);
+
+ session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
+ MALI_DEBUG_ASSERT_POINTER(session_data);
+
+ mali_address = descriptor->mali_address + offset;
+
+ MALI_DEBUG_PRINT(7, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", *phys_addr, mali_address, size));
+
+ mali_mmu_pagedir_update(session_data->page_directory, mali_address, *phys_addr, size, descriptor->cache_settings);
+
+ MALI_SUCCESS;
+}
+
+/* This handler registered to mali_mmap for MMU builds */
+_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
+{
+ struct mali_session_data *session_data;
+ mali_memory_allocation * descriptor;
+
+ /* validate input */
+ if (NULL == args) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: args was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
+
+ /* Unpack arguments */
+ session_data = (struct mali_session_data *)args->ctx;
+
+ /* validate input */
+ if (NULL == session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_FAULT); }
+
+ descriptor = (mali_memory_allocation*) _mali_osk_calloc( 1, sizeof(mali_memory_allocation) );
+ if (NULL == descriptor) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: descriptor was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_NOMEM); }
+
+ descriptor->size = args->size;
+ descriptor->mali_address = args->phys_addr;
+ descriptor->mali_addr_mapping_info = (void*)session_data;
+
+ descriptor->process_addr_mapping_info = args->ukk_private; /* save to be used during physical manager callback */
+ descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE;
+ descriptor->cache_settings = (u32) args->cache_settings ;
+ descriptor->lock = session_data->memory_lock;
+ _mali_osk_list_init( &descriptor->list );
+
+ _mali_osk_lock_wait(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head))
+ {
+ /* We do not FLUSH nor TLB_ZAP on MMAP, since we do both of those on job start*/
+ _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ args->mapping = descriptor->mapping;
+ args->cookie = (u32)descriptor;
+
+ MALI_DEBUG_PRINT(7, ("MMAP OK\n"));
+ MALI_SUCCESS;
+ }
+ else
+ {
+ _mali_osk_lock_signal(session_data->memory_lock, _MALI_OSK_LOCKMODE_RW);
+ /* OOM, but not a fatal error */
+ MALI_DEBUG_PRINT(4, ("Memory allocation failure, OOM\n"));
+ _mali_osk_free(descriptor);
+ /* Linux will free the CPU address allocation, userspace client the Mali address allocation */
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+}
+
+static _mali_osk_errcode_t _mali_ukk_mem_munmap_internal( _mali_uk_mem_munmap_s *args )
+{
+ struct mali_session_data *session_data;
+ mali_memory_allocation * descriptor;
+
+ descriptor = (mali_memory_allocation *)args->cookie;
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ /** @note args->context unused; we use the memory_session from the cookie */
+ /* args->mapping and args->size are also discarded. They are only necessary
+ for certain do_munmap implementations. However, they could be used to check the
+ descriptor at this point. */
+
+ session_data = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
+ MALI_DEBUG_ASSERT_POINTER(session_data);
+
+ /* Unmapping the memory from the mali virtual address space.
+ It is allowed to call this function severeal times, which might happen if zapping below fails. */
+ mali_allocation_engine_release_pt1_mali_pagetables_unmap(memory_engine, descriptor);
+
+ mali_scheduler_zap_all_active(session_data);
+
+ /* Removes the descriptor from the session's memory list, releases physical memory, releases descriptor */
+ mali_allocation_engine_release_pt2_physical_memory_free(memory_engine, descriptor);
+
+ _mali_osk_free(descriptor);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+/* Handler for unmapping memory for MMU builds */
+_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
+{
+ mali_memory_allocation * descriptor;
+ _mali_osk_lock_t *descriptor_lock;
+ _mali_osk_errcode_t err;
+
+ descriptor = (mali_memory_allocation *)args->cookie;
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+
+ /** @note args->context unused; we use the memory_session from the cookie */
+ /* args->mapping and args->size are also discarded. They are only necessary
+ for certain do_munmap implementations. However, they could be used to check the
+ descriptor at this point. */
+
+ MALI_DEBUG_ASSERT_POINTER((struct mali_session_data *)descriptor->mali_addr_mapping_info);
+
+ descriptor_lock = descriptor->lock; /* should point to the session data lock... */
+
+ err = _MALI_OSK_ERR_BUSY;
+ while (err == _MALI_OSK_ERR_BUSY)
+ {
+ if (descriptor_lock)
+ {
+ _mali_osk_lock_wait( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
+ }
+
+ err = _mali_ukk_mem_munmap_internal( args );
+
+ if (descriptor_lock)
+ {
+ _mali_osk_lock_signal( descriptor_lock, _MALI_OSK_LOCKMODE_RW );
+ }
+
+ if (err == _MALI_OSK_ERR_BUSY)
+ {
+ /*
+ * Reason for this;
+ * We where unable to stall the MMU, probably because we are in page fault handling.
+ * Sleep for a while with the session lock released, then try again.
+ * Abnormal termination of programs with running Mali jobs is a normal reason for this.
+ */
+ _mali_osk_time_ubusydelay(10);
+ }
+ }
+
+ return err;
+}
+
+u32 _mali_ukk_report_memory_usage(void)
+{
+ return mali_allocation_engine_memory_usage(physical_memory_allocators);
+}
+
+_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping)
+{
+ _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (!_mali_osk_list_empty(&page_table_cache.partial))
+ {
+ mali_mmu_page_table_allocation * alloc = _MALI_OSK_LIST_ENTRY(page_table_cache.partial.next, mali_mmu_page_table_allocation, list);
+ int page_number = _mali_osk_find_first_zero_bit(alloc->usage_map, alloc->num_pages);
+ MALI_DEBUG_PRINT(6, ("Partial page table allocation found, using page offset %d\n", page_number));
+ _mali_osk_set_nonatomic_bit(page_number, alloc->usage_map);
+ alloc->usage_count++;
+ if (alloc->num_pages == alloc->usage_count)
+ {
+ /* full, move alloc to full list*/
+ _mali_osk_list_move(&alloc->list, &page_table_cache.full);
+ }
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+
+ *table_page = (MALI_MMU_PAGE_SIZE * page_number) + alloc->pages.phys_base;
+ *mapping = (mali_io_address)((MALI_MMU_PAGE_SIZE * page_number) + (u32)alloc->pages.mapping);
+ MALI_DEBUG_PRINT(4, ("Page table allocated for VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page ));
+ MALI_SUCCESS;
+ }
+ else
+ {
+ mali_mmu_page_table_allocation * alloc;
+ /* no free pages, allocate a new one */
+
+ alloc = (mali_mmu_page_table_allocation *)_mali_osk_calloc(1, sizeof(mali_mmu_page_table_allocation));
+ if (NULL == alloc)
+ {
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+ *table_page = MALI_INVALID_PAGE;
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ _MALI_OSK_INIT_LIST_HEAD(&alloc->list);
+
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_page_tables(memory_engine, &alloc->pages, physical_memory_allocators))
+ {
+ MALI_DEBUG_PRINT(1, ("No more memory for page tables\n"));
+ _mali_osk_free(alloc);
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+ *table_page = MALI_INVALID_PAGE;
+ *mapping = NULL;
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ /* create the usage map */
+ alloc->num_pages = alloc->pages.size / MALI_MMU_PAGE_SIZE;
+ alloc->usage_count = 1;
+ MALI_DEBUG_PRINT(3, ("New page table cache expansion, %d pages in new cache allocation\n", alloc->num_pages));
+ alloc->usage_map = _mali_osk_calloc(1, ((alloc->num_pages + BITS_PER_LONG - 1) & ~(BITS_PER_LONG-1) / BITS_PER_LONG) * sizeof(unsigned long));
+ if (NULL == alloc->usage_map)
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to allocate memory to describe MMU page table cache usage\n"));
+ alloc->pages.release(&alloc->pages);
+ _mali_osk_free(alloc);
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+ *table_page = MALI_INVALID_PAGE;
+ *mapping = NULL;
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
+
+ _mali_osk_set_nonatomic_bit(0, alloc->usage_map);
+
+ if (alloc->num_pages > 1)
+ {
+ _mali_osk_list_add(&alloc->list, &page_table_cache.partial);
+ }
+ else
+ {
+ _mali_osk_list_add(&alloc->list, &page_table_cache.full);
+ }
+
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+ *table_page = alloc->pages.phys_base; /* return the first page */
+ *mapping = alloc->pages.mapping; /* Mapping for first page */
+ MALI_DEBUG_PRINT(4, ("Page table allocated: VA=0x%08X, MaliPA=0x%08X\n", *mapping, *table_page ));
+ MALI_SUCCESS;
+ }
+}
+
+void mali_mmu_release_table_page(u32 pa)
+{
+ mali_mmu_page_table_allocation * alloc, * temp_alloc;
+
+ MALI_DEBUG_PRINT_IF(1, pa & 4095, ("Bad page address 0x%x given to mali_mmu_release_table_page\n", (void*)pa));
+
+ MALI_DEBUG_PRINT(4, ("Releasing table page 0x%08X to the cache\n", pa));
+
+ _mali_osk_lock_wait(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* find the entry this address belongs to */
+ /* first check the partial list */
+ _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.partial, mali_mmu_page_table_allocation, list)
+ {
+ u32 start = alloc->pages.phys_base;
+ u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE;
+ if (pa >= start && pa <= last)
+ {
+ MALI_DEBUG_ASSERT(0 != _mali_osk_test_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map));
+ _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map);
+ alloc->usage_count--;
+
+ _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
+
+ if (0 == alloc->usage_count)
+ {
+ /* empty, release whole page alloc */
+ _mali_osk_list_del(&alloc->list);
+ alloc->pages.release(&alloc->pages);
+ _mali_osk_free(alloc->usage_map);
+ _mali_osk_free(alloc);
+ }
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+ MALI_DEBUG_PRINT(4, ("(partial list)Released table page 0x%08X to the cache\n", pa));
+ return;
+ }
+ }
+
+ /* the check the full list */
+ _MALI_OSK_LIST_FOREACHENTRY(alloc, temp_alloc, &page_table_cache.full, mali_mmu_page_table_allocation, list)
+ {
+ u32 start = alloc->pages.phys_base;
+ u32 last = start + (alloc->num_pages - 1) * MALI_MMU_PAGE_SIZE;
+ if (pa >= start && pa <= last)
+ {
+ _mali_osk_clear_nonatomic_bit((pa - start)/MALI_MMU_PAGE_SIZE, alloc->usage_map);
+ alloc->usage_count--;
+
+ _mali_osk_memset((void*)( ((u32)alloc->pages.mapping) + (pa - start) ), 0, MALI_MMU_PAGE_SIZE);
+
+
+ if (0 == alloc->usage_count)
+ {
+ /* empty, release whole page alloc */
+ _mali_osk_list_del(&alloc->list);
+ alloc->pages.release(&alloc->pages);
+ _mali_osk_free(alloc->usage_map);
+ _mali_osk_free(alloc);
+ }
+ else
+ {
+ /* transfer to partial list */
+ _mali_osk_list_move(&alloc->list, &page_table_cache.partial);
+ }
+
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+ MALI_DEBUG_PRINT(4, ("(full list)Released table page 0x%08X to the cache\n", pa));
+ return;
+ }
+ }
+
+ MALI_DEBUG_PRINT(1, ("pa 0x%x not found in the page table cache\n", (void*)pa));
+
+ _mali_osk_lock_signal(page_table_cache.lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+static _mali_osk_errcode_t mali_mmu_page_table_cache_create(void)
+{
+ page_table_cache.lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK
+ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE);
+ MALI_CHECK_NON_NULL( page_table_cache.lock, _MALI_OSK_ERR_FAULT );
+ _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.partial);
+ _MALI_OSK_INIT_LIST_HEAD(&page_table_cache.full);
+ MALI_SUCCESS;
+}
+
+static void mali_mmu_page_table_cache_destroy(void)
+{
+ mali_mmu_page_table_allocation * alloc, *temp;
+
+ _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.partial, mali_mmu_page_table_allocation, list)
+ {
+ MALI_DEBUG_PRINT_IF(1, 0 != alloc->usage_count, ("Destroying page table cache while pages are tagged as in use. %d allocations still marked as in use.\n", alloc->usage_count));
+ _mali_osk_list_del(&alloc->list);
+ alloc->pages.release(&alloc->pages);
+ _mali_osk_free(alloc->usage_map);
+ _mali_osk_free(alloc);
+ }
+
+ MALI_DEBUG_PRINT_IF(1, !_mali_osk_list_empty(&page_table_cache.full), ("Page table cache full list contains one or more elements \n"));
+
+ _MALI_OSK_LIST_FOREACHENTRY(alloc, temp, &page_table_cache.full, mali_mmu_page_table_allocation, list)
+ {
+ MALI_DEBUG_PRINT(1, ("Destroy alloc 0x%08X with usage count %d\n", (u32)alloc, alloc->usage_count));
+ _mali_osk_list_del(&alloc->list);
+ alloc->pages.release(&alloc->pages);
+ _mali_osk_free(alloc->usage_map);
+ _mali_osk_free(alloc);
+ }
+
+ _mali_osk_lock_term(page_table_cache.lock);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_memory.h b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.h
new file mode 100644
index 0000000..537c346
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_memory.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MEMORY_H__
+#define __MALI_MEMORY_H__
+
+#include "mali_osk.h"
+#include "mali_session.h"
+
+/** @brief Initialize Mali memory subsystem
+ *
+ * Allocate and initialize internal data structures. Must be called before
+ * allocating Mali memory.
+ *
+ * @return On success _MALI_OSK_ERR_OK, othervise some error code describing the error.
+ */
+_mali_osk_errcode_t mali_memory_initialize(void);
+
+/** @brief Terminate Mali memory system
+ *
+ * Clean up and release internal data structures.
+ */
+void mali_memory_terminate(void);
+
+/** @brief Start new Mali memory session
+ *
+ * Allocate and prepare session specific memory allocation data data. The
+ * session page directory, lock, and descriptor map is set up.
+ *
+ * @param mali_session_data pointer to the session data structure
+ */
+_mali_osk_errcode_t mali_memory_session_begin(struct mali_session_data *mali_session_data);
+
+/** @brief Close a Mali memory session
+ *
+ * Release session specific memory allocation related data.
+ *
+ * @param mali_session_data pointer to the session data structure
+ */
+void mali_memory_session_end(struct mali_session_data *mali_session_data);
+
+/** @brief Allocate a page table page
+ *
+ * Allocate a page for use as a page directory or page table. The page is
+ * mapped into kernel space.
+ *
+ * @return _MALI_OSK_ERR_OK on success, othervise an error code
+ * @param table_page GPU pointer to the allocated page
+ * @param mapping CPU pointer to the mapping of the allocated page
+ */
+_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping);
+
+/** @brief Release a page table page
+ *
+ * Release a page table page allocated through \a mali_mmu_get_table_page
+ *
+ * @param pa the GPU address of the page to release
+ */
+void mali_mmu_release_table_page(u32 pa);
+
+
+/** @brief Parse resource and prepare the OS memory allocator
+ *
+ * @param size Maximum size to allocate for Mali GPU.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t mali_memory_core_resource_os_memory(u32 size);
+
+/** @brief Parse resource and prepare the dedicated memory allocator
+ *
+ * @param start Physical start address of dedicated Mali GPU memory.
+ * @param size Size of dedicated Mali GPU memory.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(u32 start, u32 size);
+
+mali_allocation_engine mali_mem_get_memory_engine(void);
+
+#endif /* __MALI_MEMORY_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c
new file mode 100644
index 0000000..158cccf
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.c
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_bitops.h"
+#include "mali_osk_list.h"
+#include "mali_ukk.h"
+
+#include "mali_mmu.h"
+#include "mali_hw_core.h"
+#include "mali_group.h"
+#include "mali_mmu_page_directory.h"
+
+/**
+ * Size of the MMU registers in bytes
+ */
+#define MALI_MMU_REGISTERS_SIZE 0x24
+
+/**
+ * MMU commands
+ * These are the commands that can be sent
+ * to the MMU unit.
+ */
+typedef enum mali_mmu_command
+{
+ MALI_MMU_COMMAND_ENABLE_PAGING = 0x00, /**< Enable paging (memory translation) */
+ MALI_MMU_COMMAND_DISABLE_PAGING = 0x01, /**< Disable paging (memory translation) */
+ MALI_MMU_COMMAND_ENABLE_STALL = 0x02, /**< Enable stall on page fault */
+ MALI_MMU_COMMAND_DISABLE_STALL = 0x03, /**< Disable stall on page fault */
+ MALI_MMU_COMMAND_ZAP_CACHE = 0x04, /**< Zap the entire page table cache */
+ MALI_MMU_COMMAND_PAGE_FAULT_DONE = 0x05, /**< Page fault processed */
+ MALI_MMU_COMMAND_HARD_RESET = 0x06 /**< Reset the MMU back to power-on settings */
+} mali_mmu_command;
+
+static void mali_mmu_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_mmu_probe_ack(void *data);
+
+MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu);
+
+/* page fault queue flush helper pages
+ * note that the mapping pointers are currently unused outside of the initialization functions */
+static u32 mali_page_fault_flush_page_directory = MALI_INVALID_PAGE;
+static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
+static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
+
+/* an empty page directory (no address valid) which is active on any MMU not currently marked as in use */
+static u32 mali_empty_page_directory = MALI_INVALID_PAGE;
+
+_mali_osk_errcode_t mali_mmu_initialize(void)
+{
+ /* allocate the helper pages */
+ mali_empty_page_directory = mali_allocate_empty_page();
+ if(0 == mali_empty_page_directory)
+ {
+ mali_empty_page_directory = MALI_INVALID_PAGE;
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_create_fault_flush_pages(&mali_page_fault_flush_page_directory,
+ &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page))
+ {
+ mali_free_empty_page(mali_empty_page_directory);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_mmu_terminate(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali MMU: terminating\n"));
+
+ /* Free global helper pages */
+ mali_free_empty_page(mali_empty_page_directory);
+
+ /* Free the page fault flush pages */
+ mali_destroy_fault_flush_pages(&mali_page_fault_flush_page_directory,
+ &mali_page_fault_flush_page_table, &mali_page_fault_flush_data_page);
+}
+
+struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual)
+{
+ struct mali_mmu_core* mmu = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(resource);
+
+ MALI_DEBUG_PRINT(2, ("Mali MMU: Creating Mali MMU: %s\n", resource->description));
+
+ mmu = _mali_osk_calloc(1,sizeof(struct mali_mmu_core));
+ if (NULL != mmu)
+ {
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&mmu->hw_core, resource, MALI_MMU_REGISTERS_SIZE))
+ {
+ if (_MALI_OSK_ERR_OK == mali_group_add_mmu_core(group, mmu))
+ {
+ if (is_virtual)
+ {
+ /* Skip reset and IRQ setup for virtual MMU */
+ return mmu;
+ }
+
+ if (_MALI_OSK_ERR_OK == mali_mmu_reset(mmu))
+ {
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ mmu->irq = _mali_osk_irq_init(resource->irq,
+ mali_group_upper_half_mmu,
+ group,
+ mali_mmu_probe_trigger,
+ mali_mmu_probe_ack,
+ mmu,
+ "mali_mmu_irq_handlers");
+ if (NULL != mmu->irq)
+ {
+ return mmu;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali MMU: Failed to setup interrupt handlers for MMU %s\n", mmu->hw_core.description));
+ }
+ }
+ mali_group_remove_mmu_core(group);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali MMU: Failed to add core %s to group\n", mmu->hw_core.description));
+ }
+ mali_hw_core_delete(&mmu->hw_core);
+ }
+
+ _mali_osk_free(mmu);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to allocate memory for MMU\n"));
+ }
+
+ return NULL;
+}
+
+void mali_mmu_delete(struct mali_mmu_core *mmu)
+{
+ if (NULL != mmu->irq)
+ {
+ _mali_osk_irq_term(mmu->irq);
+ }
+
+ mali_hw_core_delete(&mmu->hw_core);
+ _mali_osk_free(mmu);
+}
+
+static void mali_mmu_enable_paging(struct mali_mmu_core *mmu)
+{
+ int i;
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
+ {
+ if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
+ {
+ break;
+ }
+ }
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Enable paging request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+ }
+}
+
+mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu)
+{
+ int i;
+ u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+
+ if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED) )
+ {
+ MALI_DEBUG_PRINT(4, ("MMU stall is implicit when Paging is not enabled.\n"));
+ return MALI_TRUE;
+ }
+
+ if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
+ {
+ MALI_DEBUG_PRINT(3, ("Aborting MMU stall request since it is in pagefault state.\n"));
+ return MALI_FALSE;
+ }
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
+ {
+ mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+ if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)
+ {
+ break;
+ }
+ if ((mmu_status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) && (0 == (mmu_status & MALI_MMU_STATUS_BIT_STALL_NOT_ACTIVE)))
+ {
+ break;
+ }
+ if (0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED )))
+ {
+ break;
+ }
+ }
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_DEBUG_PRINT(2, ("Enable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+ return MALI_FALSE;
+ }
+
+ if ( mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
+ {
+ MALI_DEBUG_PRINT(2, ("Aborting MMU stall request since it has a pagefault.\n"));
+ return MALI_FALSE;
+ }
+
+ return MALI_TRUE;
+}
+
+void mali_mmu_disable_stall(struct mali_mmu_core *mmu)
+{
+ int i;
+ u32 mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+
+ if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED ))
+ {
+ MALI_DEBUG_PRINT(3, ("MMU disable skipped since it was not enabled.\n"));
+ return;
+ }
+ if (mmu_status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)
+ {
+ MALI_DEBUG_PRINT(2, ("Aborting MMU disable stall request since it is in pagefault state.\n"));
+ return;
+ }
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
+ {
+ u32 status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+ if ( 0 == (status & MALI_MMU_STATUS_BIT_STALL_ACTIVE) )
+ {
+ break;
+ }
+ if ( status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE )
+ {
+ break;
+ }
+ if ( 0 == (mmu_status & MALI_MMU_STATUS_BIT_PAGING_ENABLED ))
+ {
+ break;
+ }
+ }
+ if (MALI_REG_POLL_COUNT_FAST == i) MALI_DEBUG_PRINT(1,("Disable stall request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+}
+
+void mali_mmu_page_fault_done(struct mali_mmu_core *mmu)
+{
+ MALI_DEBUG_PRINT(4, ("Mali MMU: %s: Leaving page fault mode\n", mmu->hw_core.description));
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE);
+}
+
+MALI_STATIC_INLINE _mali_osk_errcode_t mali_mmu_raw_reset(struct mali_mmu_core *mmu)
+{
+ int i;
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
+ MALI_DEBUG_ASSERT(0xCAFEB000 == mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR));
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET);
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; ++i)
+ {
+ if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0)
+ {
+ break;
+ }
+ }
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Reset request failed, MMU status is 0x%08X\n", mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ mali_bool stall_success;
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ stall_success = mali_mmu_enable_stall(mmu);
+ if (!stall_success)
+ {
+ err = _MALI_OSK_ERR_BUSY;
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->hw_core.description));
+
+ if (_MALI_OSK_ERR_OK == mali_mmu_raw_reset(mmu))
+ {
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
+ /* no session is active, so just activate the empty page directory */
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory);
+ mali_mmu_enable_paging(mmu);
+ err = _MALI_OSK_ERR_OK;
+ }
+ mali_mmu_disable_stall(mmu);
+
+ return err;
+}
+
+mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu)
+{
+ mali_bool stall_success = mali_mmu_enable_stall(mmu);
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
+
+ if (MALI_FALSE == stall_success)
+ {
+ /* False means that it is in Pagefault state. Not possible to disable_stall then */
+ return MALI_FALSE;
+ }
+
+ mali_mmu_disable_stall(mmu);
+ return MALI_TRUE;
+}
+
+void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu)
+{
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
+}
+
+
+void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address)
+{
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_ZAP_ONE_LINE, MALI_MMU_PDE_ENTRY(mali_address));
+}
+
+static void mali_mmu_activate_address_space(struct mali_mmu_core *mmu, u32 page_directory)
+{
+ /* The MMU must be in stalled or page fault mode, for this writing to work */
+ MALI_DEBUG_ASSERT( 0 != ( mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)
+ & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) );
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, page_directory);
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
+
+}
+
+mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core *mmu, struct mali_page_directory *pagedir)
+{
+ mali_bool stall_success;
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ MALI_DEBUG_PRINT(5, ("Asked to activate page directory 0x%x on MMU %s\n", pagedir, mmu->hw_core.description));
+ stall_success = mali_mmu_enable_stall(mmu);
+
+ if ( MALI_FALSE==stall_success ) return MALI_FALSE;
+ mali_mmu_activate_address_space(mmu, pagedir->page_directory);
+ mali_mmu_disable_stall(mmu);
+ return MALI_TRUE;
+}
+
+void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu)
+{
+ mali_bool stall_success;
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+ MALI_DEBUG_PRINT(3, ("Activating the empty page directory on MMU %s\n", mmu->hw_core.description));
+
+ stall_success = mali_mmu_enable_stall(mmu);
+
+ /* This function can only be called when the core is idle, so it could not fail. */
+ MALI_DEBUG_ASSERT(stall_success);
+ MALI_IGNORE(stall_success);
+
+ mali_mmu_activate_address_space(mmu, mali_empty_page_directory);
+ mali_mmu_disable_stall(mmu);
+}
+
+void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu)
+{
+ mali_bool stall_success;
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ MALI_DEBUG_PRINT(3, ("Activating the page fault flush page directory on MMU %s\n", mmu->hw_core.description));
+ stall_success = mali_mmu_enable_stall(mmu);
+ /* This function is expect to fail the stalling, since it might be in PageFault mode when it is called */
+ mali_mmu_activate_address_space(mmu, mali_page_fault_flush_page_directory);
+ if ( MALI_TRUE==stall_success ) mali_mmu_disable_stall(mmu);
+}
+
+/* Is called when we want the mmu to give an interrupt */
+static void mali_mmu_probe_trigger(void *data)
+{
+ struct mali_mmu_core *mmu = (struct mali_mmu_core *)data;
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT, MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR);
+}
+
+/* Is called when the irq probe wants the mmu to acknowledge an interrupt from the hw */
+static _mali_osk_errcode_t mali_mmu_probe_ack(void *data)
+{
+ struct mali_mmu_core *mmu = (struct mali_mmu_core *)data;
+ u32 int_stat;
+
+ int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
+
+ MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_acknowledge: intstat 0x%x\n", int_stat));
+ if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
+ {
+ MALI_DEBUG_PRINT(2, ("Probe: Page fault detect: PASSED\n"));
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(1, ("Probe: Page fault detect: FAILED\n"));
+ }
+
+ if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
+ {
+ MALI_DEBUG_PRINT(2, ("Probe: Bus read error detect: PASSED\n"));
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(1, ("Probe: Bus read error detect: FAILED\n"));
+ }
+
+ if ( (int_stat & (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR)) ==
+ (MALI_MMU_INTERRUPT_PAGE_FAULT|MALI_MMU_INTERRUPT_READ_BUS_ERROR))
+ {
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+#if 0
+void mali_mmu_print_state(struct mali_mmu_core *mmu)
+{
+ MALI_DEBUG_PRINT(2, ("MMU: State of %s is 0x%08x\n", mmu->hw_core.description, mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS)));
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h
new file mode 100644
index 0000000..59b5399
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MMU_H__
+#define __MALI_MMU_H__
+
+#include "mali_osk.h"
+#include "mali_mmu_page_directory.h"
+#include "mali_hw_core.h"
+
+/* Forward declaration from mali_group.h */
+struct mali_group;
+
+/**
+ * MMU register numbers
+ * Used in the register read/write routines.
+ * See the hardware documentation for more information about each register
+ */
+typedef enum mali_mmu_register {
+ MALI_MMU_REGISTER_DTE_ADDR = 0x0000, /**< Current Page Directory Pointer */
+ MALI_MMU_REGISTER_STATUS = 0x0004, /**< Status of the MMU */
+ MALI_MMU_REGISTER_COMMAND = 0x0008, /**< Command register, used to control the MMU */
+ MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x000C, /**< Logical address of the last page fault */
+ MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x010, /**< Used to invalidate the mapping of a single page from the MMU */
+ MALI_MMU_REGISTER_INT_RAWSTAT = 0x0014, /**< Raw interrupt status, all interrupts visible */
+ MALI_MMU_REGISTER_INT_CLEAR = 0x0018, /**< Indicate to the MMU that the interrupt has been received */
+ MALI_MMU_REGISTER_INT_MASK = 0x001C, /**< Enable/disable types of interrupts */
+ MALI_MMU_REGISTER_INT_STATUS = 0x0020 /**< Interrupt status based on the mask */
+} mali_mmu_register;
+
+/**
+ * MMU interrupt register bits
+ * Each cause of the interrupt is reported
+ * through the (raw) interrupt status registers.
+ * Multiple interrupts can be pending, so multiple bits
+ * can be set at once.
+ */
+typedef enum mali_mmu_interrupt
+{
+ MALI_MMU_INTERRUPT_PAGE_FAULT = 0x01, /**< A page fault occured */
+ MALI_MMU_INTERRUPT_READ_BUS_ERROR = 0x02 /**< A bus read error occured */
+} mali_mmu_interrupt;
+
+typedef enum mali_mmu_status_bits
+{
+ MALI_MMU_STATUS_BIT_PAGING_ENABLED = 1 << 0,
+ MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE = 1 << 1,
+ MALI_MMU_STATUS_BIT_STALL_ACTIVE = 1 << 2,
+ MALI_MMU_STATUS_BIT_IDLE = 1 << 3,
+ MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY = 1 << 4,
+ MALI_MMU_STATUS_BIT_PAGE_FAULT_IS_WRITE = 1 << 5,
+ MALI_MMU_STATUS_BIT_STALL_NOT_ACTIVE = 1 << 31,
+} mali_mmu_status_bits;
+
+/**
+ * Definition of the MMU struct
+ * Used to track a MMU unit in the system.
+ * Contains information about the mapping of the registers
+ */
+struct mali_mmu_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+};
+
+_mali_osk_errcode_t mali_mmu_initialize(void);
+
+void mali_mmu_terminate(void);
+
+struct mali_mmu_core *mali_mmu_create(_mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual);
+void mali_mmu_delete(struct mali_mmu_core *mmu);
+
+_mali_osk_errcode_t mali_mmu_reset(struct mali_mmu_core *mmu);
+mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu);
+void mali_mmu_zap_tlb_without_stall(struct mali_mmu_core *mmu);
+void mali_mmu_invalidate_page(struct mali_mmu_core *mmu, u32 mali_address);
+
+mali_bool mali_mmu_activate_page_directory(struct mali_mmu_core* mmu, struct mali_page_directory *pagedir);
+void mali_mmu_activate_empty_page_directory(struct mali_mmu_core* mmu);
+void mali_mmu_activate_fault_flush_page_directory(struct mali_mmu_core* mmu);
+
+/**
+ * Issues the enable stall command to the MMU and waits for HW to complete the request
+ * @param mmu The MMU to enable paging for
+ * @return MALI_TRUE if HW stall was successfully engaged, otherwise MALI_FALSE (req timed out)
+ */
+mali_bool mali_mmu_enable_stall(struct mali_mmu_core *mmu);
+
+/**
+ * Issues the disable stall command to the MMU and waits for HW to complete the request
+ * @param mmu The MMU to enable paging for
+ */
+void mali_mmu_disable_stall(struct mali_mmu_core *mmu);
+
+void mali_mmu_page_fault_done(struct mali_mmu_core *mmu);
+
+/*** Register reading/writing functions ***/
+MALI_STATIC_INLINE u32 mali_mmu_get_int_status(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
+}
+
+MALI_STATIC_INLINE u32 mali_mmu_get_rawstat(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT);
+}
+
+MALI_STATIC_INLINE void mali_mmu_mask_all_interrupts(struct mali_mmu_core *mmu)
+{
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0);
+}
+
+MALI_STATIC_INLINE u32 mali_mmu_get_status(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+}
+
+MALI_STATIC_INLINE u32 mali_mmu_get_page_fault_addr(struct mali_mmu_core *mmu)
+{
+ return mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
+}
+
+#endif /* __MALI_MMU_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c
new file mode 100644
index 0000000..258fc1b
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.c
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#include "mali_osk.h"
+#include "mali_uk_types.h"
+#include "mali_mmu_page_directory.h"
+#include "mali_memory.h"
+#include "mali_l2_cache.h"
+#include "mali_group.h"
+
+static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data);
+
+u32 mali_allocate_empty_page(void)
+{
+ _mali_osk_errcode_t err;
+ mali_io_address mapping;
+ u32 address;
+
+ if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&address, &mapping))
+ {
+ /* Allocation failed */
+ return 0;
+ }
+
+ MALI_DEBUG_ASSERT_POINTER( mapping );
+
+ err = fill_page(mapping, 0);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ mali_mmu_release_table_page(address);
+ }
+ return address;
+}
+
+void mali_free_empty_page(u32 address)
+{
+ if (MALI_INVALID_PAGE != address)
+ {
+ mali_mmu_release_table_page(address);
+ }
+}
+
+_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page)
+{
+ _mali_osk_errcode_t err;
+ mali_io_address page_directory_mapping;
+ mali_io_address page_table_mapping;
+ mali_io_address data_page_mapping;
+
+ err = mali_mmu_get_table_page(data_page, &data_page_mapping);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ err = mali_mmu_get_table_page(page_table, &page_table_mapping);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ err = mali_mmu_get_table_page(page_directory, &page_directory_mapping);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ fill_page(data_page_mapping, 0);
+ fill_page(page_table_mapping, *data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
+ fill_page(page_directory_mapping, *page_table | MALI_MMU_FLAGS_PRESENT);
+ MALI_SUCCESS;
+ }
+ mali_mmu_release_table_page(*page_table);
+ *page_table = MALI_INVALID_PAGE;
+ }
+ mali_mmu_release_table_page(*data_page);
+ *data_page = MALI_INVALID_PAGE;
+ }
+ return err;
+}
+
+void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page)
+{
+ if (MALI_INVALID_PAGE != *page_directory)
+ {
+ mali_mmu_release_table_page(*page_directory);
+ *page_directory = MALI_INVALID_PAGE;
+ }
+
+ if (MALI_INVALID_PAGE != *page_table)
+ {
+ mali_mmu_release_table_page(*page_table);
+ *page_table = MALI_INVALID_PAGE;
+ }
+
+ if (MALI_INVALID_PAGE != *data_page)
+ {
+ mali_mmu_release_table_page(*data_page);
+ *data_page = MALI_INVALID_PAGE;
+ }
+}
+
+static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data)
+{
+ int i;
+ MALI_DEBUG_ASSERT_POINTER( mapping );
+
+ for(i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
+ {
+ _mali_osk_mem_iowrite32_relaxed( mapping, i * sizeof(u32), data);
+ }
+ _mali_osk_mem_barrier();
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size)
+{
+ const int first_pde = MALI_MMU_PDE_ENTRY(mali_address);
+ const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1);
+ _mali_osk_errcode_t err;
+ mali_io_address pde_mapping;
+ u32 pde_phys;
+ int i;
+
+ for(i = first_pde; i <= last_pde; i++)
+ {
+ if(0 == (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & MALI_MMU_FLAGS_PRESENT))
+ {
+ /* Page table not present */
+ MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]);
+ MALI_DEBUG_ASSERT(NULL == pagedir->page_entries_mapped[i]);
+
+ err = mali_mmu_get_table_page(&pde_phys, &pde_mapping);
+ if(_MALI_OSK_ERR_OK != err)
+ {
+ MALI_PRINT_ERROR(("Failed to allocate page table page.\n"));
+ return err;
+ }
+ pagedir->page_entries_mapped[i] = pde_mapping;
+
+ /* Update PDE, mark as present */
+ _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32),
+ pde_phys | MALI_MMU_FLAGS_PRESENT);
+
+ MALI_DEBUG_ASSERT(0 == pagedir->page_entries_usage_count[i]);
+ pagedir->page_entries_usage_count[i] = 1;
+ }
+ else
+ {
+ pagedir->page_entries_usage_count[i]++;
+ }
+ }
+ _mali_osk_write_mem_barrier();
+
+ MALI_SUCCESS;
+}
+
+MALI_STATIC_INLINE void mali_mmu_zero_pte(mali_io_address page_table, u32 mali_address, u32 size)
+{
+ int i;
+ const int first_pte = MALI_MMU_PTE_ENTRY(mali_address);
+ const int last_pte = MALI_MMU_PTE_ENTRY(mali_address + size - 1);
+
+ for (i = first_pte; i <= last_pte; i++)
+ {
+ _mali_osk_mem_iowrite32_relaxed(page_table, i * sizeof(u32), 0);
+ }
+}
+
+_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size)
+{
+ const int first_pde = MALI_MMU_PDE_ENTRY(mali_address);
+ const int last_pde = MALI_MMU_PDE_ENTRY(mali_address + size - 1);
+ u32 left = size;
+ int i;
+ mali_bool pd_changed = MALI_FALSE;
+ u32 pages_to_invalidate[3]; /* hard-coded to 3: max two pages from the PT level plus max one page from PD level */
+ u32 num_pages_inv = 0;
+ mali_bool invalidate_all = MALI_FALSE; /* safety mechanism in case page_entries_usage_count is unreliable */
+
+ /* For all page directory entries in range. */
+ for (i = first_pde; i <= last_pde; i++)
+ {
+ u32 size_in_pde, offset;
+
+ MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[i]);
+ MALI_DEBUG_ASSERT(0 != pagedir->page_entries_usage_count[i]);
+
+ /* Offset into page table, 0 if mali_address is 4MiB aligned */
+ offset = (mali_address & (MALI_MMU_VIRTUAL_PAGE_SIZE - 1));
+ if (left < MALI_MMU_VIRTUAL_PAGE_SIZE - offset)
+ {
+ size_in_pde = left;
+ }
+ else
+ {
+ size_in_pde = MALI_MMU_VIRTUAL_PAGE_SIZE - offset;
+ }
+
+ pagedir->page_entries_usage_count[i]--;
+
+ /* If entire page table is unused, free it */
+ if (0 == pagedir->page_entries_usage_count[i])
+ {
+ u32 page_address;
+ MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n"));
+ /* last reference removed, no need to zero out each PTE */
+
+ page_address = MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)));
+ pagedir->page_entries_mapped[i] = NULL;
+ _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i*sizeof(u32), 0);
+
+ mali_mmu_release_table_page(page_address);
+ pd_changed = MALI_TRUE;
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(num_pages_inv < 2);
+ if (num_pages_inv < 2)
+ {
+ pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i);
+ num_pages_inv++;
+ }
+ else
+ {
+ invalidate_all = MALI_TRUE;
+ }
+
+ /* If part of the page table is still in use, zero the relevant PTEs */
+ mali_mmu_zero_pte(pagedir->page_entries_mapped[i], mali_address, size_in_pde);
+ }
+
+ left -= size_in_pde;
+ mali_address += size_in_pde;
+ }
+ _mali_osk_write_mem_barrier();
+
+ /* L2 pages invalidation */
+ if (MALI_TRUE == pd_changed)
+ {
+ MALI_DEBUG_ASSERT(num_pages_inv < 3);
+ if (num_pages_inv < 3)
+ {
+ pages_to_invalidate[num_pages_inv] = pagedir->page_directory;
+ num_pages_inv++;
+ }
+ else
+ {
+ invalidate_all = MALI_TRUE;
+ }
+ }
+
+ if (invalidate_all)
+ {
+ mali_l2_cache_invalidate_all();
+ }
+ else
+ {
+ mali_l2_cache_invalidate_all_pages(pages_to_invalidate, num_pages_inv);
+ }
+
+ MALI_SUCCESS;
+}
+
+struct mali_page_directory *mali_mmu_pagedir_alloc(void)
+{
+ struct mali_page_directory *pagedir;
+
+ pagedir = _mali_osk_calloc(1, sizeof(struct mali_page_directory));
+ if(NULL == pagedir)
+ {
+ return NULL;
+ }
+
+ if(_MALI_OSK_ERR_OK != mali_mmu_get_table_page(&pagedir->page_directory, &pagedir->page_directory_mapped))
+ {
+ _mali_osk_free(pagedir);
+ return NULL;
+ }
+
+ /* Zero page directory */
+ fill_page(pagedir->page_directory_mapped, 0);
+
+ return pagedir;
+}
+
+void mali_mmu_pagedir_free(struct mali_page_directory *pagedir)
+{
+ const int num_page_table_entries = sizeof(pagedir->page_entries_mapped) / sizeof(pagedir->page_entries_mapped[0]);
+ int i;
+
+ /* Free referenced page tables and zero PDEs. */
+ for (i = 0; i < num_page_table_entries; i++)
+ {
+ if (pagedir->page_directory_mapped && (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT))
+ {
+ mali_mmu_release_table_page( _mali_osk_mem_ioread32(pagedir->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
+ _mali_osk_mem_iowrite32_relaxed(pagedir->page_directory_mapped, i * sizeof(u32), 0);
+ }
+ }
+ _mali_osk_write_mem_barrier();
+
+ /* Free the page directory page. */
+ mali_mmu_release_table_page(pagedir->page_directory);
+
+ _mali_osk_free(pagedir);
+}
+
+
+void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, mali_memory_cache_settings cache_settings)
+{
+ u32 end_address = mali_address + size;
+ u32 permission_bits;
+
+ switch ( cache_settings )
+ {
+ case MALI_CACHE_GP_READ_ALLOCATE:
+ MALI_DEBUG_PRINT(5, ("Map L2 GP_Read_allocate\n"));
+ permission_bits = MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE;
+ break;
+
+ case MALI_CACHE_STANDARD:
+ MALI_DEBUG_PRINT(5, ("Map L2 Standard\n"));
+ /*falltrough */
+ default:
+ if ( MALI_CACHE_STANDARD != cache_settings) MALI_PRINT_ERROR(("Wrong cache settings\n"));
+ permission_bits = MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT;
+ }
+
+ /* Map physical pages into MMU page tables */
+ for ( ; mali_address < end_address; mali_address += MALI_MMU_PAGE_SIZE, phys_address += MALI_MMU_PAGE_SIZE)
+ {
+ MALI_DEBUG_ASSERT_POINTER(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]);
+ _mali_osk_mem_iowrite32_relaxed(pagedir->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)],
+ MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32),
+ phys_address | permission_bits);
+ }
+ _mali_osk_write_mem_barrier();
+}
+
+u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index)
+{
+ return (_mali_osk_mem_ioread32(pagedir->page_directory_mapped, index*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
+}
+
+/* For instrumented */
+struct dump_info
+{
+ u32 buffer_left;
+ u32 register_writes_size;
+ u32 page_table_dump_size;
+ u32 *buffer;
+};
+
+static _mali_osk_errcode_t writereg(u32 where, u32 what, const char *comment, struct dump_info *info)
+{
+ if (NULL != info)
+ {
+ info->register_writes_size += sizeof(u32)*2; /* two 32-bit words */
+
+ if (NULL != info->buffer)
+ {
+ /* check that we have enough space */
+ if (info->buffer_left < sizeof(u32)*2) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+
+ *info->buffer = where;
+ info->buffer++;
+
+ *info->buffer = what;
+ info->buffer++;
+
+ info->buffer_left -= sizeof(u32)*2;
+ }
+ }
+
+ MALI_SUCCESS;
+}
+
+static _mali_osk_errcode_t dump_page(mali_io_address page, u32 phys_addr, struct dump_info * info)
+{
+ if (NULL != info)
+ {
+ /* 4096 for the page and 4 bytes for the address */
+ const u32 page_size_in_elements = MALI_MMU_PAGE_SIZE / 4;
+ const u32 page_size_in_bytes = MALI_MMU_PAGE_SIZE;
+ const u32 dump_size_in_bytes = MALI_MMU_PAGE_SIZE + 4;
+
+ info->page_table_dump_size += dump_size_in_bytes;
+
+ if (NULL != info->buffer)
+ {
+ if (info->buffer_left < dump_size_in_bytes) MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+
+ *info->buffer = phys_addr;
+ info->buffer++;
+
+ _mali_osk_memcpy(info->buffer, page, page_size_in_bytes);
+ info->buffer += page_size_in_elements;
+
+ info->buffer_left -= dump_size_in_bytes;
+ }
+ }
+
+ MALI_SUCCESS;
+}
+
+static _mali_osk_errcode_t dump_mmu_page_table(struct mali_page_directory *pagedir, struct dump_info * info)
+{
+ MALI_DEBUG_ASSERT_POINTER(pagedir);
+ MALI_DEBUG_ASSERT_POINTER(info);
+
+ if (NULL != pagedir->page_directory_mapped)
+ {
+ int i;
+
+ MALI_CHECK_NO_ERROR(
+ dump_page(pagedir->page_directory_mapped, pagedir->page_directory, info)
+ );
+
+ for (i = 0; i < 1024; i++)
+ {
+ if (NULL != pagedir->page_entries_mapped[i])
+ {
+ MALI_CHECK_NO_ERROR(
+ dump_page(pagedir->page_entries_mapped[i],
+ _mali_osk_mem_ioread32(pagedir->page_directory_mapped,
+ i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info)
+ );
+ }
+ }
+ }
+
+ MALI_SUCCESS;
+}
+
+static _mali_osk_errcode_t dump_mmu_registers(struct mali_page_directory *pagedir, struct dump_info * info)
+{
+ MALI_CHECK_NO_ERROR(writereg(0x00000000, pagedir->page_directory,
+ "set the page directory address", info));
+ MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info));
+ MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info));
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args )
+{
+ struct dump_info info = { 0, 0, 0, NULL };
+ struct mali_session_data * session_data;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+
+ session_data = (struct mali_session_data *)(args->ctx);
+
+ MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info));
+ MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info));
+ args->size = info.register_writes_size + info.page_table_dump_size;
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args )
+{
+ struct dump_info info = { 0, 0, 0, NULL };
+ struct mali_session_data * session_data;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->buffer, _MALI_OSK_ERR_INVALID_ARGS);
+
+ session_data = (struct mali_session_data *)(args->ctx);
+
+ info.buffer_left = args->size;
+ info.buffer = args->buffer;
+
+ args->register_writes = info.buffer;
+ MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data->page_directory, &info));
+
+ args->page_table_dump = info.buffer;
+ MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data->page_directory, &info));
+
+ args->register_writes_size = info.register_writes_size;
+ args->page_table_dump_size = info.page_table_dump_size;
+
+ MALI_SUCCESS;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h
new file mode 100644
index 0000000..628833a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_mmu_page_directory.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_MMU_PAGE_DIRECTORY_H__
+#define __MALI_MMU_PAGE_DIRECTORY_H__
+
+#include "mali_osk.h"
+
+/**
+ * Size of an MMU page in bytes
+ */
+#define MALI_MMU_PAGE_SIZE 0x1000
+
+/*
+ * Size of the address space referenced by a page table page
+ */
+#define MALI_MMU_VIRTUAL_PAGE_SIZE 0x400000 /* 4 MiB */
+
+/**
+ * Page directory index from address
+ * Calculates the page directory index from the given address
+ */
+#define MALI_MMU_PDE_ENTRY(address) (((address)>>22) & 0x03FF)
+
+/**
+ * Page table index from address
+ * Calculates the page table index from the given address
+ */
+#define MALI_MMU_PTE_ENTRY(address) (((address)>>12) & 0x03FF)
+
+/**
+ * Extract the memory address from an PDE/PTE entry
+ */
+#define MALI_MMU_ENTRY_ADDRESS(value) ((value) & 0xFFFFFC00)
+
+#define MALI_INVALID_PAGE ((u32)(~0))
+
+/**
+ *
+ */
+typedef enum mali_mmu_entry_flags
+{
+ MALI_MMU_FLAGS_PRESENT = 0x01,
+ MALI_MMU_FLAGS_READ_PERMISSION = 0x02,
+ MALI_MMU_FLAGS_WRITE_PERMISSION = 0x04,
+ MALI_MMU_FLAGS_OVERRIDE_CACHE = 0x8,
+ MALI_MMU_FLAGS_WRITE_CACHEABLE = 0x10,
+ MALI_MMU_FLAGS_WRITE_ALLOCATE = 0x20,
+ MALI_MMU_FLAGS_WRITE_BUFFERABLE = 0x40,
+ MALI_MMU_FLAGS_READ_CACHEABLE = 0x80,
+ MALI_MMU_FLAGS_READ_ALLOCATE = 0x100,
+ MALI_MMU_FLAGS_MASK = 0x1FF,
+} mali_mmu_entry_flags;
+
+
+#define MALI_MMU_FLAGS_FORCE_GP_READ_ALLOCATE ( \
+MALI_MMU_FLAGS_PRESENT | \
+ MALI_MMU_FLAGS_READ_PERMISSION | \
+ MALI_MMU_FLAGS_WRITE_PERMISSION | \
+ MALI_MMU_FLAGS_OVERRIDE_CACHE | \
+ MALI_MMU_FLAGS_WRITE_CACHEABLE | \
+ MALI_MMU_FLAGS_WRITE_BUFFERABLE | \
+ MALI_MMU_FLAGS_READ_CACHEABLE | \
+ MALI_MMU_FLAGS_READ_ALLOCATE )
+
+
+struct mali_page_directory
+{
+ u32 page_directory; /**< Physical address of the memory session's page directory */
+ mali_io_address page_directory_mapped; /**< Pointer to the mapped version of the page directory into the kernel's address space */
+
+ mali_io_address page_entries_mapped[1024]; /**< Pointers to the page tables which exists in the page directory mapped into the kernel's address space */
+ u32 page_entries_usage_count[1024]; /**< Tracks usage count of the page table pages, so they can be releases on the last reference */
+};
+
+/* Map Mali virtual address space (i.e. ensure page tables exist for the virtual range) */
+_mali_osk_errcode_t mali_mmu_pagedir_map(struct mali_page_directory *pagedir, u32 mali_address, u32 size);
+_mali_osk_errcode_t mali_mmu_pagedir_unmap(struct mali_page_directory *pagedir, u32 mali_address, u32 size);
+
+/* Back virtual address space with actual pages. Assumes input is contiguous and 4k aligned. */
+void mali_mmu_pagedir_update(struct mali_page_directory *pagedir, u32 mali_address, u32 phys_address, u32 size, u32 cache_settings);
+
+u32 mali_page_directory_get_phys_address(struct mali_page_directory *pagedir, u32 index);
+
+u32 mali_allocate_empty_page(void);
+void mali_free_empty_page(u32 address);
+_mali_osk_errcode_t mali_create_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page);
+void mali_destroy_fault_flush_pages(u32 *page_directory, u32 *page_table, u32 *data_page);
+
+struct mali_page_directory *mali_mmu_pagedir_alloc(void);
+void mali_mmu_pagedir_free(struct mali_page_directory *pagedir);
+
+#endif /* __MALI_MMU_PAGE_DIRECTORY_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_osk.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk.h
new file mode 100644
index 0000000..6217203
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk.h
@@ -0,0 +1,1811 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk.h
+ * Defines the OS abstraction layer for the kernel device driver (OSK)
+ */
+
+#ifndef __MALI_OSK_H__
+#define __MALI_OSK_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @addtogroup uddapi Unified Device Driver (UDD) APIs
+ *
+ * @{
+ */
+
+/**
+ * @addtogroup oskapi UDD OS Abstraction for Kernel-side (OSK) APIs
+ *
+ * @{
+ */
+
+/** @defgroup _mali_osk_miscellaneous OSK Miscellaneous functions, constants and types
+ * @{ */
+
+/* Define integer types used by OSK. Note: these currently clash with Linux so we only define them if not defined already */
+#ifndef __KERNEL__
+ typedef unsigned char u8;
+ typedef signed char s8;
+ typedef unsigned short u16;
+ typedef signed short s16;
+ typedef unsigned int u32;
+ typedef signed int s32;
+ typedef unsigned long long u64;
+ #define BITS_PER_LONG (sizeof(long)*8)
+#else
+ /* Ensure Linux types u32, etc. are defined */
+ #include <linux/types.h>
+#endif
+
+/** @brief Mali Boolean type which uses MALI_TRUE and MALI_FALSE
+ */
+ typedef unsigned long mali_bool;
+
+#ifndef MALI_TRUE
+ #define MALI_TRUE ((mali_bool)1)
+#endif
+
+#ifndef MALI_FALSE
+ #define MALI_FALSE ((mali_bool)0)
+#endif
+
+#define MALI_HW_CORE_NO_COUNTER ((u32)-1)
+
+/**
+ * @brief OSK Error codes
+ *
+ * Each OS may use its own set of error codes, and may require that the
+ * User/Kernel interface take certain error code. This means that the common
+ * error codes need to be sufficiently rich to pass the correct error code
+ * thorugh from the OSK to U/K layer, across all OSs.
+ *
+ * The result is that some error codes will appear redundant on some OSs.
+ * Under all OSs, the OSK layer must translate native OS error codes to
+ * _mali_osk_errcode_t codes. Similarly, the U/K layer must translate from
+ * _mali_osk_errcode_t codes to native OS error codes.
+ */
+typedef enum
+{
+ _MALI_OSK_ERR_OK = 0, /**< Success. */
+ _MALI_OSK_ERR_FAULT = -1, /**< General non-success */
+ _MALI_OSK_ERR_INVALID_FUNC = -2, /**< Invalid function requested through User/Kernel interface (e.g. bad IOCTL number) */
+ _MALI_OSK_ERR_INVALID_ARGS = -3, /**< Invalid arguments passed through User/Kernel interface */
+ _MALI_OSK_ERR_NOMEM = -4, /**< Insufficient memory */
+ _MALI_OSK_ERR_TIMEOUT = -5, /**< Timeout occurred */
+ _MALI_OSK_ERR_RESTARTSYSCALL = -6, /**< Special: On certain OSs, must report when an interruptable mutex is interrupted. Ignore otherwise. */
+ _MALI_OSK_ERR_ITEM_NOT_FOUND = -7, /**< Table Lookup failed */
+ _MALI_OSK_ERR_BUSY = -8, /**< Device/operation is busy. Try again later */
+ _MALI_OSK_ERR_UNSUPPORTED = -9, /**< Optional part of the interface used, and is unsupported */
+} _mali_osk_errcode_t;
+
+/** @} */ /* end group _mali_osk_miscellaneous */
+
+/** @defgroup _mali_osk_wq OSK work queues
+ * @{ */
+
+/** @brief Private type for work objects */
+typedef struct _mali_osk_wq_work_t_struct _mali_osk_wq_work_t;
+
+/** @brief Work queue handler function
+ *
+ * This function type is called when the work is scheduled by the work queue,
+ * e.g. as an IRQ bottom-half handler.
+ *
+ * Refer to \ref _mali_osk_wq_schedule_work() for more information on the
+ * work-queue and work handlers.
+ *
+ * @param arg resource-specific data
+ */
+typedef void (*_mali_osk_wq_work_handler_t)( void * arg );
+
+/* @} */ /* end group _mali_osk_wq */
+
+/** @defgroup _mali_osk_irq OSK IRQ handling
+ * @{ */
+
+/** @brief Private type for IRQ handling objects */
+typedef struct _mali_osk_irq_t_struct _mali_osk_irq_t;
+
+/** @brief Optional function to trigger an irq from a resource
+ *
+ * This function is implemented by the common layer to allow probing of a resource's IRQ.
+ * @param arg resource-specific data */
+typedef void (*_mali_osk_irq_trigger_t)( void * arg );
+
+/** @brief Optional function to acknowledge an irq from a resource
+ *
+ * This function is implemented by the common layer to allow probing of a resource's IRQ.
+ * @param arg resource-specific data
+ * @return _MALI_OSK_ERR_OK if the IRQ was successful, or a suitable _mali_osk_errcode_t on failure. */
+typedef _mali_osk_errcode_t (*_mali_osk_irq_ack_t)( void * arg );
+
+/** @brief IRQ 'upper-half' handler callback.
+ *
+ * This function is implemented by the common layer to do the initial handling of a
+ * resource's IRQ. This maps on to the concept of an ISR that does the minimum
+ * work necessary before handing off to an IST.
+ *
+ * The communication of the resource-specific data from the ISR to the IST is
+ * handled by the OSK implementation.
+ *
+ * On most systems, the IRQ upper-half handler executes in IRQ context.
+ * Therefore, the system may have restrictions about what can be done in this
+ * context
+ *
+ * If an IRQ upper-half handler requires more work to be done than can be
+ * acheived in an IRQ context, then it may defer the work with
+ * _mali_osk_wq_schedule_work(). Refer to \ref _mali_osk_wq_create_work() for
+ * more information.
+ *
+ * @param arg resource-specific data
+ * @return _MALI_OSK_ERR_OK if the IRQ was correctly handled, or a suitable
+ * _mali_osk_errcode_t otherwise.
+ */
+typedef _mali_osk_errcode_t (*_mali_osk_irq_uhandler_t)( void * arg );
+
+/** @} */ /* end group _mali_osk_irq */
+
+
+/** @defgroup _mali_osk_atomic OSK Atomic counters
+ * @{ */
+
+/** @brief Public type of atomic counters
+ *
+ * This is public for allocation on stack. On systems that support it, this is just a single 32-bit value.
+ * On others, it could be encapsulating an object stored elsewhere.
+ *
+ * Regardless of implementation, the \ref _mali_osk_atomic functions \b must be used
+ * for all accesses to the variable's value, even if atomicity is not required.
+ * Do not access u.val or u.obj directly.
+ */
+typedef struct
+{
+ union
+ {
+ u32 val;
+ void *obj;
+ } u;
+} _mali_osk_atomic_t;
+/** @} */ /* end group _mali_osk_atomic */
+
+
+/** @defgroup _mali_osk_lock OSK Mutual Exclusion Locks
+ * @{ */
+
+
+/** @brief OSK Mutual Exclusion Lock ordered list
+ *
+ * This lists the various types of locks in the system and is used to check
+ * that locks are taken in the correct order.
+ *
+ * Holding more than one lock of the same order at the same time is not
+ * allowed.
+ *
+ */
+typedef enum
+{
+ _MALI_OSK_LOCK_ORDER_LAST = 0,
+
+ _MALI_OSK_LOCK_ORDER_SESSION_PENDING_JOBS,
+ _MALI_OSK_LOCK_ORDER_PM_EXECUTE,
+ _MALI_OSK_LOCK_ORDER_UTILIZATION,
+ _MALI_OSK_LOCK_ORDER_L2_COUNTER,
+ _MALI_OSK_LOCK_ORDER_PROFILING,
+ _MALI_OSK_LOCK_ORDER_L2_COMMAND,
+ _MALI_OSK_LOCK_ORDER_PM_CORE_STATE,
+ _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED,
+ _MALI_OSK_LOCK_ORDER_SCHEDULER,
+ _MALI_OSK_LOCK_ORDER_GROUP,
+ _MALI_OSK_LOCK_ORDER_GROUP_VIRTUAL,
+ _MALI_OSK_LOCK_ORDER_DESCRIPTOR_MAP,
+ _MALI_OSK_LOCK_ORDER_MEM_PT_CACHE,
+ _MALI_OSK_LOCK_ORDER_MEM_INFO,
+ _MALI_OSK_LOCK_ORDER_MEM_SESSION,
+ _MALI_OSK_LOCK_ORDER_SESSIONS,
+ _MALI_OSK_LOCK_ORDER_PM_DOMAIN,
+ _MALI_OSK_LOCK_ORDER_PMU,
+
+ _MALI_OSK_LOCK_ORDER_FIRST
+} _mali_osk_lock_order_t;
+
+
+/** @brief OSK Mutual Exclusion Lock flags type
+ *
+ * Flags are supplied at the point where the Lock is initialized. Each flag can
+ * be combined with others using bitwise OR, '|'.
+ *
+ * The flags must be sufficiently rich to cope with all our OSs. This means
+ * that on some OSs, certain flags can be completely ignored. We define a
+ * number of terms that are significant across all OSs:
+ *
+ * - Sleeping/non-sleeping mutexs. Sleeping mutexs can block on waiting, and so
+ * schedule out the current thread. This is significant on OSs where there are
+ * situations in which the current thread must not be put to sleep. On OSs
+ * without this restriction, sleeping and non-sleeping mutexes can be treated
+ * as the same (if that is required).
+ * - Interruptable/non-interruptable mutexes. For sleeping mutexes, it may be
+ * possible for the sleep to be interrupted for a reason other than the thread
+ * being able to obtain the lock. OSs behaving in this way may provide a
+ * mechanism to control whether sleeping mutexes can be interrupted. On OSs
+ * that do not support the concept of interruption, \b or they do not support
+ * control of mutex interruption, then interruptable mutexes may be treated
+ * as non-interruptable.
+ *
+ * Some constrains apply to the lock type flags:
+ *
+ * - Spinlocks are by nature, non-interruptable. Hence, they must always be
+ * combined with the NONINTERRUPTABLE flag, because it is meaningless to ask
+ * for a spinlock that is interruptable (and this highlights its
+ * non-interruptable-ness). For example, on certain OSs they should be used when
+ * you must not sleep.
+ * - Reader/writer is an optimization hint, and any type of lock can be
+ * reader/writer. Since this is an optimization hint, the implementation need
+ * not respect this for any/all types of lock. For example, on certain OSs,
+ * there's no interruptable reader/writer mutex. If such a thing were requested
+ * on that OS, the fact that interruptable was requested takes priority over the
+ * reader/writer-ness, because reader/writer-ness is not necessary for correct
+ * operation.
+ * - Any lock can use the order parameter.
+ * - A onelock is an optimization hint specific to certain OSs. It can be
+ * specified when it is known that only one lock will be held by the thread,
+ * and so can provide faster mutual exclusion. This can be safely ignored if
+ * such optimization is not required/present.
+ *
+ * The absence of any flags (the value 0) results in a sleeping-mutex, which is interruptable.
+ */
+typedef enum
+{
+ _MALI_OSK_LOCKFLAG_SPINLOCK = 0x1, /**< Specifically, don't sleep on those architectures that require it */
+ _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE = 0x2, /**< The mutex cannot be interrupted, e.g. delivery of signals on those architectures where this is required */
+ _MALI_OSK_LOCKFLAG_READERWRITER = 0x4, /**< Optimise for readers/writers */
+ _MALI_OSK_LOCKFLAG_ORDERED = 0x8, /**< Use the order parameter; otherwise use automatic ordering */
+ _MALI_OSK_LOCKFLAG_ONELOCK = 0x10, /**< Each thread can only hold one lock at a time */
+ _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ = 0x20, /**< IRQ version of spinlock */
+ /** @enum _mali_osk_lock_flags_t
+ *
+ * Flags from 0x10000--0x80000000 are RESERVED for User-mode */
+
+} _mali_osk_lock_flags_t;
+
+/** @brief Mutual Exclusion Lock Mode Optimization hint
+ *
+ * The lock mode is used to implement the read/write locking of locks specified
+ * as _MALI_OSK_LOCKFLAG_READERWRITER. In this case, the RO mode can be used
+ * to allow multiple concurrent readers, but no writers. The RW mode is used for
+ * writers, and so will wait for all readers to release the lock (if any present).
+ * Further readers and writers will wait until the writer releases the lock.
+ *
+ * The mode is purely an optimization hint: for example, it is permissible for
+ * all locks to behave in RW mode, regardless of that supplied.
+ *
+ * It is an error to attempt to use locks in anything other that RW mode when
+ * _MALI_OSK_LOCKFLAG_READERWRITER is not supplied.
+ *
+ */
+typedef enum
+{
+ _MALI_OSK_LOCKMODE_UNDEF = -1, /**< Undefined lock mode. For internal use only */
+ _MALI_OSK_LOCKMODE_RW = 0x0, /**< Read-write mode, default. All readers and writers are mutually-exclusive */
+ _MALI_OSK_LOCKMODE_RO, /**< Read-only mode, to support multiple concurrent readers, but mutual exclusion in the presence of writers. */
+ /** @enum _mali_osk_lock_mode_t
+ *
+ * Lock modes 0x40--0x7F are RESERVED for User-mode */
+} _mali_osk_lock_mode_t;
+
+/** @brief Private type for Mutual Exclusion lock objects */
+typedef struct _mali_osk_lock_t_struct _mali_osk_lock_t;
+
+#ifdef DEBUG
+/** @brief Macro for asserting that the current thread holds a given lock
+ */
+#define MALI_DEBUG_ASSERT_LOCK_HELD(l) MALI_DEBUG_ASSERT(_mali_osk_lock_get_owner(l) == _mali_osk_get_tid());
+
+/** @brief returns a lock's owner (thread id) if debugging is enabled
+ */
+u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock );
+#else
+#define MALI_DEBUG_ASSERT_LOCK_HELD(l) do {} while(0)
+#endif
+
+/** @} */ /* end group _mali_osk_lock */
+
+/** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations
+ * @{ */
+
+/**
+ * @brief Private data type for use in IO accesses to/from devices.
+ *
+ * This represents some range that is accessible from the device. Examples
+ * include:
+ * - Device Registers, which could be readable and/or writeable.
+ * - Memory that the device has access to, for storing configuration structures.
+ *
+ * Access to this range must be made through the _mali_osk_mem_ioread32() and
+ * _mali_osk_mem_iowrite32() functions.
+ */
+typedef struct _mali_io_address * mali_io_address;
+
+/** @defgroup _MALI_OSK_CPU_PAGE CPU Physical page size macros.
+ *
+ * The order of the page size is supplied for
+ * ease of use by algorithms that might require it, since it is easier to know
+ * it ahead of time rather than calculating it.
+ *
+ * The Mali Page Mask macro masks off the lower bits of a physical address to
+ * give the start address of the page for that physical address.
+ *
+ * @note The Mali device driver code is designed for systems with 4KB page size.
+ * Changing these macros will not make the entire Mali device driver work with
+ * page sizes other than 4KB.
+ *
+ * @note The CPU Physical Page Size has been assumed to be the same as the Mali
+ * Physical Page Size.
+ *
+ * @{
+ */
+
+/** CPU Page Order, as log to base 2 of the Page size. @see _MALI_OSK_CPU_PAGE_SIZE */
+#define _MALI_OSK_CPU_PAGE_ORDER ((u32)12)
+/** CPU Page Size, in bytes. */
+#define _MALI_OSK_CPU_PAGE_SIZE (((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER))
+/** CPU Page Mask, which masks off the offset within a page */
+#define _MALI_OSK_CPU_PAGE_MASK (~((((u32)1) << (_MALI_OSK_CPU_PAGE_ORDER)) - ((u32)1)))
+/** @} */ /* end of group _MALI_OSK_CPU_PAGE */
+
+/** @defgroup _MALI_OSK_MALI_PAGE Mali Physical Page size macros
+ *
+ * Mali Physical page size macros. The order of the page size is supplied for
+ * ease of use by algorithms that might require it, since it is easier to know
+ * it ahead of time rather than calculating it.
+ *
+ * The Mali Page Mask macro masks off the lower bits of a physical address to
+ * give the start address of the page for that physical address.
+ *
+ * @note The Mali device driver code is designed for systems with 4KB page size.
+ * Changing these macros will not make the entire Mali device driver work with
+ * page sizes other than 4KB.
+ *
+ * @note The Mali Physical Page Size has been assumed to be the same as the CPU
+ * Physical Page Size.
+ *
+ * @{
+ */
+
+/** Mali Page Order, as log to base 2 of the Page size. @see _MALI_OSK_MALI_PAGE_SIZE */
+#define _MALI_OSK_MALI_PAGE_ORDER ((u32)12)
+/** Mali Page Size, in bytes. */
+#define _MALI_OSK_MALI_PAGE_SIZE (((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER))
+/** Mali Page Mask, which masks off the offset within a page */
+#define _MALI_OSK_MALI_PAGE_MASK (~((((u32)1) << (_MALI_OSK_MALI_PAGE_ORDER)) - ((u32)1)))
+/** @} */ /* end of group _MALI_OSK_MALI_PAGE*/
+
+/** @brief flags for mapping a user-accessible memory range
+ *
+ * Where a function with prefix '_mali_osk_mem_mapregion' accepts flags as one
+ * of the function parameters, it will use one of these. These allow per-page
+ * control over mappings. Compare with the mali_memory_allocation_flag type,
+ * which acts over an entire range
+ *
+ * These may be OR'd together with bitwise OR (|), but must be cast back into
+ * the type after OR'ing.
+ */
+typedef enum
+{
+ _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR = 0x1, /**< Physical address is OS Allocated */
+} _mali_osk_mem_mapregion_flags_t;
+/** @} */ /* end group _mali_osk_low_level_memory */
+
+/** @defgroup _mali_osk_notification OSK Notification Queues
+ * @{ */
+
+/** @brief Private type for notification queue objects */
+typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queue_t;
+
+/** @brief Public notification data object type */
+typedef struct _mali_osk_notification_t_struct
+{
+ u32 notification_type; /**< The notification type */
+ u32 result_buffer_size; /**< Size of the result buffer to copy to user space */
+ void * result_buffer; /**< Buffer containing any type specific data */
+} _mali_osk_notification_t;
+
+/** @} */ /* end group _mali_osk_notification */
+
+
+/** @defgroup _mali_osk_timer OSK Timer Callbacks
+ * @{ */
+
+/** @brief Function to call when a timer expires
+ *
+ * When a timer expires, this function is called. Note that on many systems,
+ * a timer callback will be executed in IRQ context. Therefore, restrictions
+ * may apply on what can be done inside the timer callback.
+ *
+ * If a timer requires more work to be done than can be acheived in an IRQ
+ * context, then it may defer the work with a work-queue. For example, it may
+ * use \ref _mali_osk_wq_schedule_work() to make use of a bottom-half handler
+ * to carry out the remaining work.
+ *
+ * Stopping the timer with \ref _mali_osk_timer_del() blocks on compeletion of
+ * the callback. Therefore, the callback may not obtain any mutexes also held
+ * by any callers of _mali_osk_timer_del(). Otherwise, a deadlock may occur.
+ *
+ * @param arg Function-specific data */
+typedef void (*_mali_osk_timer_callback_t)(void * arg );
+
+/** @brief Private type for Timer Callback Objects */
+typedef struct _mali_osk_timer_t_struct _mali_osk_timer_t;
+/** @} */ /* end group _mali_osk_timer */
+
+
+/** @addtogroup _mali_osk_list OSK Doubly-Linked Circular Lists
+ * @{ */
+
+/** @brief Public List objects.
+ *
+ * To use, add a _mali_osk_list_t member to the structure that may become part
+ * of a list. When traversing the _mali_osk_list_t objects, use the
+ * _MALI_OSK_CONTAINER_OF() macro to recover the structure from its
+ *_mali_osk_list_t member
+ *
+ * Each structure may have multiple _mali_osk_list_t members, so that the
+ * structure is part of multiple lists. When traversing lists, ensure that the
+ * correct _mali_osk_list_t member is used, because type-checking will be
+ * lost by the compiler.
+ */
+typedef struct _mali_osk_list_s
+{
+ struct _mali_osk_list_s *next;
+ struct _mali_osk_list_s *prev;
+} _mali_osk_list_t;
+
+/** @brief Initialize a list to be a head of an empty list
+ * @param exp the list to initialize. */
+#define _MALI_OSK_INIT_LIST_HEAD(exp) _mali_osk_list_init(exp)
+
+/** @brief Define a list variable, which is uninitialized.
+ * @param exp the name of the variable that the list will be defined as. */
+#define _MALI_OSK_LIST_HEAD(exp) _mali_osk_list_t exp
+
+/** @brief Define a list variable, which is initialized.
+ * @param exp the name of the variable that the list will be defined as. */
+#define _MALI_OSK_LIST_HEAD_STATIC_INIT(exp) _mali_osk_list_t exp = { &exp, &exp }
+
+/** @brief Find the containing structure of another structure
+ *
+ * This is the reverse of the operation 'offsetof'. This means that the
+ * following condition is satisfied:
+ *
+ * ptr == _MALI_OSK_CONTAINER_OF( &ptr->member, type, member )
+ *
+ * When ptr is of type 'type'.
+ *
+ * Its purpose it to recover a larger structure that has wrapped a smaller one.
+ *
+ * @note no type or memory checking occurs to ensure that a wrapper structure
+ * does in fact exist, and that it is being recovered with respect to the
+ * correct member.
+ *
+ * @param ptr the pointer to the member that is contained within the larger
+ * structure
+ * @param type the type of the structure that contains the member
+ * @param member the name of the member in the structure that ptr points to.
+ * @return a pointer to a \a type object which contains \a member, as pointed
+ * to by \a ptr.
+ */
+#define _MALI_OSK_CONTAINER_OF(ptr, type, member) \
+ ((type *)( ((char *)ptr) - offsetof(type,member) ))
+
+/** @brief Find the containing structure of a list
+ *
+ * When traversing a list, this is used to recover the containing structure,
+ * given that is contains a _mali_osk_list_t member.
+ *
+ * Each list must be of structures of one type, and must link the same members
+ * together, otherwise it will not be possible to correctly recover the
+ * sturctures that the lists link.
+ *
+ * @note no type or memory checking occurs to ensure that a structure does in
+ * fact exist for the list entry, and that it is being recovered with respect
+ * to the correct list member.
+ *
+ * @param ptr the pointer to the _mali_osk_list_t member in this structure
+ * @param type the type of the structure that contains the member
+ * @param member the member of the structure that ptr points to.
+ * @return a pointer to a \a type object which contains the _mali_osk_list_t
+ * \a member, as pointed to by the _mali_osk_list_t \a *ptr.
+ */
+#define _MALI_OSK_LIST_ENTRY(ptr, type, member) \
+ _MALI_OSK_CONTAINER_OF(ptr, type, member)
+
+/** @brief Enumerate a list safely
+ *
+ * With this macro, lists can be enumerated in a 'safe' manner. That is,
+ * entries can be deleted from the list without causing an error during
+ * enumeration. To achieve this, a 'temporary' pointer is required, which must
+ * be provided to the macro.
+ *
+ * Use it like a 'for()', 'while()' or 'do()' construct, and so it must be
+ * followed by a statement or compound-statement which will be executed for
+ * each list entry.
+ *
+ * Upon loop completion, providing that an early out was not taken in the
+ * loop body, then it is guaranteed that ptr->member == list, even if the loop
+ * body never executed.
+ *
+ * @param ptr a pointer to an object of type 'type', which points to the
+ * structure that contains the currently enumerated list entry.
+ * @param tmp a pointer to an object of type 'type', which must not be used
+ * inside the list-execution statement.
+ * @param list a pointer to a _mali_osk_list_t, from which enumeration will
+ * begin
+ * @param type the type of the structure that contains the _mali_osk_list_t
+ * member that is part of the list to be enumerated.
+ * @param member the _mali_osk_list_t member of the structure that is part of
+ * the list to be enumerated.
+ */
+#define _MALI_OSK_LIST_FOREACHENTRY(ptr, tmp, list, type, member) \
+ for (ptr = _MALI_OSK_LIST_ENTRY((list)->next, type, member), \
+ tmp = _MALI_OSK_LIST_ENTRY(ptr->member.next, type, member); \
+ &ptr->member != (list); \
+ ptr = tmp, tmp = _MALI_OSK_LIST_ENTRY(tmp->member.next, type, member))
+/** @} */ /* end group _mali_osk_list */
+
+
+/** @addtogroup _mali_osk_miscellaneous
+ * @{ */
+
+/** @brief resource description struct
+ *
+ * Platform independent representation of a Mali HW resource
+ */
+typedef struct _mali_osk_resource
+{
+ const char * description; /**< short description of the resource */
+ u32 base; /**< Physical base address of the resource, as seen by Mali resources. */
+ u32 irq; /**< IRQ number delivered to the CPU, or -1 to tell the driver to probe for it (if possible) */
+} _mali_osk_resource_t;
+/** @} */ /* end group _mali_osk_miscellaneous */
+
+
+#include "mali_kernel_memory_engine.h" /* include for mali_memory_allocation and mali_physical_memory_allocation type */
+
+/** @addtogroup _mali_osk_wq
+ * @{ */
+
+/** @brief Initialize work queues (for deferred work)
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_wq_init(void);
+
+/** @brief Terminate work queues (for deferred work)
+ */
+void _mali_osk_wq_term(void);
+
+/** @brief Create work in the work queue
+ *
+ * Creates a work object which can be scheduled in the work queue. When
+ * scheduled, \a handler will be called with \a data as the argument.
+ *
+ * Refer to \ref _mali_osk_wq_schedule_work() for details on how work
+ * is scheduled in the queue.
+ *
+ * The returned pointer must be freed with \ref _mali_osk_wq_delete_work()
+ * when no longer needed.
+ */
+_mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data );
+
+/** @brief Delete a work object
+ *
+ * This will flush the work queue to ensure that the work handler will not
+ * be called after deletion.
+ */
+void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work );
+
+/** @brief Delete a work object
+ *
+ * This will NOT flush the work queue, so only call this if you are sure that the work handler will
+ * not be called after deletion.
+ */
+void _mali_osk_wq_delete_work_nonflush( _mali_osk_wq_work_t *work );
+
+/** @brief Cause a queued, deferred call of the work handler
+ *
+ * _mali_osk_wq_schedule_work provides a mechanism for enqueuing deferred calls
+ * to the work handler. After calling \ref _mali_osk_wq_schedule_work(), the
+ * work handler will be scheduled to run at some point in the future.
+ *
+ * Typically this is called by the IRQ upper-half to defer further processing of
+ * IRQ-related work to the IRQ bottom-half handler. This is necessary for work
+ * that cannot be done in an IRQ context by the IRQ upper-half handler. Timer
+ * callbacks also use this mechanism, because they are treated as though they
+ * operate in an IRQ context. Refer to \ref _mali_osk_timer_t for more
+ * information.
+ *
+ * Code that operates in a kernel-process context (with no IRQ context
+ * restrictions) may also enqueue deferred calls to the IRQ bottom-half. The
+ * advantage over direct calling is that deferred calling allows the caller and
+ * IRQ bottom half to hold the same mutex, with a guarantee that they will not
+ * deadlock just by using this mechanism.
+ *
+ * _mali_osk_wq_schedule_work() places deferred call requests on a queue, to
+ * allow for more than one thread to make a deferred call. Therfore, if it is
+ * called 'K' times, then the IRQ bottom-half will be scheduled 'K' times too.
+ * 'K' is a number that is implementation-specific.
+ *
+ * _mali_osk_wq_schedule_work() is guaranteed to not block on:
+ * - enqueuing a deferred call request.
+ * - the completion of the work handler.
+ *
+ * This is to prevent deadlock. For example, if _mali_osk_wq_schedule_work()
+ * blocked, then it would cause a deadlock when the following two conditions
+ * hold:
+ * - The work handler callback (of type _mali_osk_wq_work_handler_t) locks
+ * a mutex
+ * - And, at the same time, the caller of _mali_osk_wq_schedule_work() also
+ * holds the same mutex
+ *
+ * @note care must be taken to not overflow the queue that
+ * _mali_osk_wq_schedule_work() operates on. Code must be structured to
+ * ensure that the number of requests made to the queue is bounded. Otherwise,
+ * work will be lost.
+ *
+ * The queue that _mali_osk_wq_schedule_work implements is a FIFO of N-writer,
+ * 1-reader type. The writers are the callers of _mali_osk_wq_schedule_work
+ * (all OSK-registered IRQ upper-half handlers in the system, watchdog timers,
+ * callers from a Kernel-process context). The reader is a single thread that
+ * handles all OSK-registered work.
+ *
+ * @param work a pointer to the _mali_osk_wq_work_t object corresponding to the
+ * work to begin processing.
+ */
+void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work );
+
+/** @brief Flush the work queue
+ *
+ * This will flush the OSK work queue, ensuring all work in the queue has
+ * completed before returning.
+ *
+ * Since this blocks on the completion of work in the work-queue, the
+ * caller of this function \b must \b not hold any mutexes that are taken by
+ * any registered work handler. To do so may cause a deadlock.
+ *
+ */
+void _mali_osk_wq_flush(void);
+
+
+/** @} */ /* end group _mali_osk_wq */
+
+/** @addtogroup _mali_osk_irq
+ * @{ */
+
+/** @brief Initialize IRQ handling for a resource
+ *
+ * Registers an interrupt handler \a uhandler for the given IRQ number \a irqnum.
+ * \a data will be passed as argument to the handler when an interrupt occurs.
+ *
+ * If \a irqnum is -1, _mali_osk_irq_init will probe for the IRQ number using
+ * the supplied \a trigger_func and \a ack_func. These functions will also
+ * receive \a data as their argument.
+ *
+ * @param irqnum The IRQ number that the resource uses, as seen by the CPU.
+ * The value -1 has a special meaning which indicates the use of probing, and
+ * trigger_func and ack_func must be non-NULL.
+ * @param uhandler The interrupt handler, corresponding to a ISR handler for
+ * the resource
+ * @param int_data resource specific data, which will be passed to uhandler
+ * @param trigger_func Optional: a function to trigger the resource's irq, to
+ * probe for the interrupt. Use NULL if irqnum != -1.
+ * @param ack_func Optional: a function to acknowledge the resource's irq, to
+ * probe for the interrupt. Use NULL if irqnum != -1.
+ * @param probe_data resource-specific data, which will be passed to
+ * (if present) trigger_func and ack_func
+ * @param description textual description of the IRQ resource.
+ * @return on success, a pointer to a _mali_osk_irq_t object, which represents
+ * the IRQ handling on this resource. NULL on failure.
+ */
+_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description );
+
+/** @brief Terminate IRQ handling on a resource.
+ *
+ * This will disable the interrupt from the device, and then waits for any
+ * currently executing IRQ handlers to complete.
+ *
+ * @note If work is deferred to an IRQ bottom-half handler through
+ * \ref _mali_osk_wq_schedule_work(), be sure to flush any remaining work
+ * with \ref _mali_osk_wq_flush() or (implicitly) with \ref _mali_osk_wq_delete_work()
+ *
+ * @param irq a pointer to the _mali_osk_irq_t object corresponding to the
+ * resource whose IRQ handling is to be terminated.
+ */
+void _mali_osk_irq_term( _mali_osk_irq_t *irq );
+
+/** @} */ /* end group _mali_osk_irq */
+
+
+/** @addtogroup _mali_osk_atomic
+ * @{ */
+
+/** @brief Decrement an atomic counter
+ *
+ * @note It is an error to decrement the counter beyond -(1<<23)
+ *
+ * @param atom pointer to an atomic counter */
+void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom );
+
+/** @brief Decrement an atomic counter, return new value
+ *
+ * @param atom pointer to an atomic counter
+ * @return The new value, after decrement */
+u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom );
+
+/** @brief Increment an atomic counter
+ *
+ * @note It is an error to increment the counter beyond (1<<23)-1
+ *
+ * @param atom pointer to an atomic counter */
+void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom );
+
+/** @brief Increment an atomic counter, return new value
+ *
+ * @param atom pointer to an atomic counter */
+u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom );
+
+/** @brief Initialize an atomic counter
+ *
+ * @note the parameter required is a u32, and so signed integers should be
+ * cast to u32.
+ *
+ * @param atom pointer to an atomic counter
+ * @param val the value to initialize the atomic counter.
+ * @return _MALI_OSK_ERR_OK on success, otherwise, a suitable
+ * _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val );
+
+/** @brief Read a value from an atomic counter
+ *
+ * This can only be safely used to determine the value of the counter when it
+ * is guaranteed that other threads will not be modifying the counter. This
+ * makes its usefulness limited.
+ *
+ * @param atom pointer to an atomic counter
+ */
+u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom );
+
+/** @brief Terminate an atomic counter
+ *
+ * @param atom pointer to an atomic counter
+ */
+void _mali_osk_atomic_term( _mali_osk_atomic_t *atom );
+/** @} */ /* end group _mali_osk_atomic */
+
+
+/** @defgroup _mali_osk_memory OSK Memory Allocation
+ * @{ */
+
+/** @brief Allocate zero-initialized memory.
+ *
+ * Returns a buffer capable of containing at least \a n elements of \a size
+ * bytes each. The buffer is initialized to zero.
+ *
+ * If there is a need for a bigger block of memory (16KB or bigger), then
+ * consider to use _mali_osk_vmalloc() instead, as this function might
+ * map down to a OS function with size limitations.
+ *
+ * The buffer is suitably aligned for storage and subsequent access of every
+ * type that the compiler supports. Therefore, the pointer to the start of the
+ * buffer may be cast into any pointer type, and be subsequently accessed from
+ * such a pointer, without loss of information.
+ *
+ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
+ * Failure to do so will cause a memory leak.
+ *
+ * @note Most toolchains supply memory allocation functions that meet the
+ * compiler's alignment requirements.
+ *
+ * @param n Number of elements to allocate
+ * @param size Size of each element
+ * @return On success, the zero-initialized buffer allocated. NULL on failure
+ */
+void *_mali_osk_calloc( u32 n, u32 size );
+
+/** @brief Allocate memory.
+ *
+ * Returns a buffer capable of containing at least \a size bytes. The
+ * contents of the buffer are undefined.
+ *
+ * If there is a need for a bigger block of memory (16KB or bigger), then
+ * consider to use _mali_osk_vmalloc() instead, as this function might
+ * map down to a OS function with size limitations.
+ *
+ * The buffer is suitably aligned for storage and subsequent access of every
+ * type that the compiler supports. Therefore, the pointer to the start of the
+ * buffer may be cast into any pointer type, and be subsequently accessed from
+ * such a pointer, without loss of information.
+ *
+ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
+ * Failure to do so will cause a memory leak.
+ *
+ * @note Most toolchains supply memory allocation functions that meet the
+ * compiler's alignment requirements.
+ *
+ * Remember to free memory using _mali_osk_free().
+ * @param size Number of bytes to allocate
+ * @return On success, the buffer allocated. NULL on failure.
+ */
+void *_mali_osk_malloc( u32 size );
+
+/** @brief Free memory.
+ *
+ * Reclaims the buffer pointed to by the parameter \a ptr for the system.
+ * All memory returned from _mali_osk_malloc() and _mali_osk_calloc()
+ * must be freed before the application exits. Otherwise,
+ * a memory leak will occur.
+ *
+ * Memory must be freed once. It is an error to free the same non-NULL pointer
+ * more than once.
+ *
+ * It is legal to free the NULL pointer.
+ *
+ * @param ptr Pointer to buffer to free
+ */
+void _mali_osk_free( void *ptr );
+
+/** @brief Allocate memory.
+ *
+ * Returns a buffer capable of containing at least \a size bytes. The
+ * contents of the buffer are undefined.
+ *
+ * This function is potentially slower than _mali_osk_malloc() and _mali_osk_calloc(),
+ * but do support bigger sizes.
+ *
+ * The buffer is suitably aligned for storage and subsequent access of every
+ * type that the compiler supports. Therefore, the pointer to the start of the
+ * buffer may be cast into any pointer type, and be subsequently accessed from
+ * such a pointer, without loss of information.
+ *
+ * When the buffer is no longer in use, it must be freed with _mali_osk_free().
+ * Failure to do so will cause a memory leak.
+ *
+ * @note Most toolchains supply memory allocation functions that meet the
+ * compiler's alignment requirements.
+ *
+ * Remember to free memory using _mali_osk_free().
+ * @param size Number of bytes to allocate
+ * @return On success, the buffer allocated. NULL on failure.
+ */
+void *_mali_osk_valloc( u32 size );
+
+/** @brief Free memory.
+ *
+ * Reclaims the buffer pointed to by the parameter \a ptr for the system.
+ * All memory returned from _mali_osk_valloc() must be freed before the
+ * application exits. Otherwise a memory leak will occur.
+ *
+ * Memory must be freed once. It is an error to free the same non-NULL pointer
+ * more than once.
+ *
+ * It is legal to free the NULL pointer.
+ *
+ * @param ptr Pointer to buffer to free
+ */
+void _mali_osk_vfree( void *ptr );
+
+/** @brief Copies memory.
+ *
+ * Copies the \a len bytes from the buffer pointed by the parameter \a src
+ * directly to the buffer pointed by \a dst.
+ *
+ * It is an error for \a src to overlap \a dst anywhere in \a len bytes.
+ *
+ * @param dst Pointer to the destination array where the content is to be
+ * copied.
+ * @param src Pointer to the source of data to be copied.
+ * @param len Number of bytes to copy.
+ * @return \a dst is always passed through unmodified.
+ */
+void *_mali_osk_memcpy( void *dst, const void *src, u32 len );
+
+/** @brief Fills memory.
+ *
+ * Sets the first \a n bytes of the block of memory pointed to by \a s to
+ * the specified value
+ * @param s Pointer to the block of memory to fill.
+ * @param c Value to be set, passed as u32. Only the 8 Least Significant Bits (LSB)
+ * are used.
+ * @param n Number of bytes to be set to the value.
+ * @return \a s is always passed through unmodified
+ */
+void *_mali_osk_memset( void *s, u32 c, u32 n );
+/** @} */ /* end group _mali_osk_memory */
+
+
+/** @brief Checks the amount of memory allocated
+ *
+ * Checks that not more than \a max_allocated bytes are allocated.
+ *
+ * Some OS bring up an interactive out of memory dialogue when the
+ * system runs out of memory. This can stall non-interactive
+ * apps (e.g. automated test runs). This function can be used to
+ * not trigger the OOM dialogue by keeping allocations
+ * within a certain limit.
+ *
+ * @return MALI_TRUE when \a max_allocated bytes are not in use yet. MALI_FALSE
+ * when at least \a max_allocated bytes are in use.
+ */
+mali_bool _mali_osk_mem_check_allocated( u32 max_allocated );
+
+/** @addtogroup _mali_osk_lock
+ * @{ */
+
+/** @brief Initialize a Mutual Exclusion Lock
+ *
+ * Locks are created in the signalled (unlocked) state.
+ *
+ * initial must be zero, since there is currently no means of expressing
+ * whether a reader/writer lock should be initially locked as a reader or
+ * writer. This would require some encoding to be used.
+ *
+ * 'Automatic' ordering means that locks must be obtained in the order that
+ * they were created. For all locks that can be held at the same time, they must
+ * either all provide the order parameter, or they all must use 'automatic'
+ * ordering - because there is no way of mixing 'automatic' and 'manual'
+ * ordering.
+ *
+ * @param flags flags combined with bitwise OR ('|'), or zero. There are
+ * restrictions on which flags can be combined, @see _mali_osk_lock_flags_t.
+ * @param initial For future expansion into semaphores. SBZ.
+ * @param order The locking order of the mutex. That is, locks obtained by the
+ * same thread must have been created with an increasing order parameter, for
+ * deadlock prevention. Setting to zero causes 'automatic' ordering to be used.
+ * @return On success, a pointer to a _mali_osk_lock_t object. NULL on failure.
+ */
+_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order );
+
+/** @brief Wait for a lock to be signalled (obtained)
+
+ * After a thread has successfully waited on the lock, the lock is obtained by
+ * the thread, and is marked as unsignalled. The thread releases the lock by
+ * signalling it.
+ *
+ * In the case of Reader/Writer locks, multiple readers can obtain a lock in
+ * the absence of writers, which is a performance optimization (providing that
+ * the readers never write to the protected resource).
+ *
+ * To prevent deadlock, locks must always be obtained in the same order.
+ *
+ * For locks marked as _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, it is a
+ * programming error for the function to exit without obtaining the lock. This
+ * means that the error code must only be checked for interruptible locks.
+ *
+ * @param lock the lock to wait upon (obtain).
+ * @param mode the mode in which the lock should be obtained. Unless the lock
+ * was created with _MALI_OSK_LOCKFLAG_READERWRITER, this must be
+ * _MALI_OSK_LOCKMODE_RW.
+ * @return On success, _MALI_OSK_ERR_OK. For interruptible locks, a suitable
+ * _mali_osk_errcode_t will be returned on failure, and the lock will not be
+ * obtained. In this case, the error code must be propagated up to the U/K
+ * interface.
+ */
+_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode);
+
+
+/** @brief Signal (release) a lock
+ *
+ * Locks may only be signalled by the thread that originally waited upon the
+ * lock.
+ *
+ * @note In the OSU, a flag exists to allow any thread to signal a
+ * lock. Such functionality is not present in the OSK.
+ *
+ * @param lock the lock to signal (release).
+ * @param mode the mode in which the lock should be obtained. This must match
+ * the mode in which the lock was waited upon.
+ */
+void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode );
+
+/** @brief Terminate a lock
+ *
+ * This terminates a lock and frees all associated resources.
+ *
+ * It is a programming error to terminate the lock when it is held (unsignalled)
+ * by a thread.
+ *
+ * @param lock the lock to terminate.
+ */
+void _mali_osk_lock_term( _mali_osk_lock_t *lock );
+/** @} */ /* end group _mali_osk_lock */
+
+
+/** @addtogroup _mali_osk_low_level_memory
+ * @{ */
+
+/** @brief Issue a memory barrier
+ *
+ * This defines an arbitrary memory barrier operation, which forces an ordering constraint
+ * on memory read and write operations.
+ */
+void _mali_osk_mem_barrier( void );
+
+/** @brief Issue a write memory barrier
+ *
+ * This defines an write memory barrier operation which forces an ordering constraint
+ * on memory write operations.
+ */
+void _mali_osk_write_mem_barrier( void );
+
+/** @brief Map a physically contiguous region into kernel space
+ *
+ * This is primarily used for mapping in registers from resources, and Mali-MMU
+ * page tables. The mapping is only visable from kernel-space.
+ *
+ * Access has to go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32
+ *
+ * @param phys CPU-physical base address of the memory to map in. This must
+ * be aligned to the system's page size, which is assumed to be 4K.
+ * @param size the number of bytes of physically contiguous address space to
+ * map in
+ * @param description A textual description of the memory being mapped in.
+ * @return On success, a Mali IO address through which the mapped-in
+ * memory/registers can be accessed. NULL on failure.
+ */
+mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description );
+
+/** @brief Unmap a physically contiguous address range from kernel space.
+ *
+ * The address range should be one previously mapped in through
+ * _mali_osk_mem_mapioregion.
+ *
+ * It is a programming error to do (but not limited to) the following:
+ * - attempt an unmap twice
+ * - unmap only part of a range obtained through _mali_osk_mem_mapioregion
+ * - unmap more than the range obtained through _mali_osk_mem_mapioregion
+ * - unmap an address range that was not successfully mapped using
+ * _mali_osk_mem_mapioregion
+ * - provide a mapping that does not map to phys.
+ *
+ * @param phys CPU-physical base address of the memory that was originally
+ * mapped in. This must be aligned to the system's page size, which is assumed
+ * to be 4K
+ * @param size The number of bytes that were originally mapped in.
+ * @param mapping The Mali IO address through which the mapping is
+ * accessed.
+ */
+void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address mapping );
+
+/** @brief Allocate and Map a physically contiguous region into kernel space
+ *
+ * This is used for allocating physically contiguous regions (such as Mali-MMU
+ * page tables) and mapping them into kernel space. The mapping is only
+ * visible from kernel-space.
+ *
+ * The alignment of the returned memory is guaranteed to be at least
+ * _MALI_OSK_CPU_PAGE_SIZE.
+ *
+ * Access must go through _mali_osk_mem_ioread32 and _mali_osk_mem_iowrite32
+ *
+ * @note This function is primarily to provide support for OSs that are
+ * incapable of separating the tasks 'allocate physically contiguous memory'
+ * and 'map it into kernel space'
+ *
+ * @param[out] phys CPU-physical base address of memory that was allocated.
+ * (*phys) will be guaranteed to be aligned to at least
+ * _MALI_OSK_CPU_PAGE_SIZE on success.
+ *
+ * @param[in] size the number of bytes of physically contiguous memory to
+ * allocate. This must be a multiple of _MALI_OSK_CPU_PAGE_SIZE.
+ *
+ * @return On success, a Mali IO address through which the mapped-in
+ * memory/registers can be accessed. NULL on failure, and (*phys) is unmodified.
+ */
+mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size );
+
+/** @brief Free a physically contiguous address range from kernel space.
+ *
+ * The address range should be one previously mapped in through
+ * _mali_osk_mem_allocioregion.
+ *
+ * It is a programming error to do (but not limited to) the following:
+ * - attempt a free twice on the same ioregion
+ * - free only part of a range obtained through _mali_osk_mem_allocioregion
+ * - free more than the range obtained through _mali_osk_mem_allocioregion
+ * - free an address range that was not successfully mapped using
+ * _mali_osk_mem_allocioregion
+ * - provide a mapping that does not map to phys.
+ *
+ * @param phys CPU-physical base address of the memory that was originally
+ * mapped in, which was aligned to _MALI_OSK_CPU_PAGE_SIZE.
+ * @param size The number of bytes that were originally mapped in, which was
+ * a multiple of _MALI_OSK_CPU_PAGE_SIZE.
+ * @param mapping The Mali IO address through which the mapping is
+ * accessed.
+ */
+void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address mapping );
+
+/** @brief Request a region of physically contiguous memory
+ *
+ * This is used to ensure exclusive access to a region of physically contigous
+ * memory.
+ *
+ * It is acceptable to implement this as a stub. However, it is then the job
+ * of the System Integrator to ensure that no other device driver will be using
+ * the physical address ranges used by Mali, while the Mali device driver is
+ * loaded.
+ *
+ * @param phys CPU-physical base address of the memory to request. This must
+ * be aligned to the system's page size, which is assumed to be 4K.
+ * @param size the number of bytes of physically contiguous address space to
+ * request.
+ * @param description A textual description of the memory being requested.
+ * @return _MALI_OSK_ERR_OK on success. Otherwise, a suitable
+ * _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description );
+
+/** @brief Un-request a region of physically contiguous memory
+ *
+ * This is used to release a regious of physically contiguous memory previously
+ * requested through _mali_osk_mem_reqregion, so that other device drivers may
+ * use it. This will be called at time of Mali device driver termination.
+ *
+ * It is a programming error to attempt to:
+ * - unrequest a region twice
+ * - unrequest only part of a range obtained through _mali_osk_mem_reqregion
+ * - unrequest more than the range obtained through _mali_osk_mem_reqregion
+ * - unrequest an address range that was not successfully requested using
+ * _mali_osk_mem_reqregion
+ *
+ * @param phys CPU-physical base address of the memory to un-request. This must
+ * be aligned to the system's page size, which is assumed to be 4K
+ * @param size the number of bytes of physically contiguous address space to
+ * un-request.
+ */
+void _mali_osk_mem_unreqregion( u32 phys, u32 size );
+
+/** @brief Read from a location currently mapped in through
+ * _mali_osk_mem_mapioregion
+ *
+ * This reads a 32-bit word from a 32-bit aligned location. It is a programming
+ * error to provide unaligned locations, or to read from memory that is not
+ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
+ * _mali_osk_mem_allocioregion().
+ *
+ * @param mapping Mali IO address to read from
+ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
+ * @return the 32-bit word from the specified location.
+ */
+u32 _mali_osk_mem_ioread32( volatile mali_io_address mapping, u32 offset );
+
+/** @brief Write to a location currently mapped in through
+ * _mali_osk_mem_mapioregion without memory barriers
+ *
+ * This write a 32-bit word to a 32-bit aligned location without using memory barrier.
+ * It is a programming error to provide unaligned locations, or to write to memory that is not
+ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
+ * _mali_osk_mem_allocioregion().
+ *
+ * @param mapping Mali IO address to write to
+ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
+ * @param val the 32-bit word to write.
+ */
+void _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val );
+
+/** @brief Write to a location currently mapped in through
+ * _mali_osk_mem_mapioregion with write memory barrier
+ *
+ * This write a 32-bit word to a 32-bit aligned location. It is a programming
+ * error to provide unaligned locations, or to write to memory that is not
+ * mapped in, or not mapped through either _mali_osk_mem_mapioregion() or
+ * _mali_osk_mem_allocioregion().
+ *
+ * @param mapping Mali IO address to write to
+ * @param offset Byte offset from the given IO address to operate on, must be a multiple of 4
+ * @param val the 32-bit word to write.
+ */
+void _mali_osk_mem_iowrite32( volatile mali_io_address mapping, u32 offset, u32 val );
+
+/** @brief Flush all CPU caches
+ *
+ * This should only be implemented if flushing of the cache is required for
+ * memory mapped in through _mali_osk_mem_mapregion.
+ */
+void _mali_osk_cache_flushall( void );
+
+/** @brief Flush any caches necessary for the CPU and MALI to have the same view of a range of uncached mapped memory
+ *
+ * This should only be implemented if your OS doesn't do a full cache flush (inner & outer)
+ * after allocating uncached mapped memory.
+ *
+ * Some OS do not perform a full cache flush (including all outer caches) for uncached mapped memory.
+ * They zero the memory through a cached mapping, then flush the inner caches but not the outer caches.
+ * This is required for MALI to have the correct view of the memory.
+ */
+void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size );
+
+/** @} */ /* end group _mali_osk_low_level_memory */
+
+
+/** @addtogroup _mali_osk_notification
+ *
+ * User space notification framework
+ *
+ * Communication with user space of asynchronous events is performed through a
+ * synchronous call to the \ref u_k_api.
+ *
+ * Since the events are asynchronous, the events have to be queued until a
+ * synchronous U/K API call can be made by user-space. A U/K API call might also
+ * be received before any event has happened. Therefore the notifications the
+ * different subsystems wants to send to user space has to be queued for later
+ * reception, or a U/K API call has to be blocked until an event has occured.
+ *
+ * Typical uses of notifications are after running of jobs on the hardware or
+ * when changes to the system is detected that needs to be relayed to user
+ * space.
+ *
+ * After an event has occured user space has to be notified using some kind of
+ * message. The notification framework supports sending messages to waiting
+ * threads or queueing of messages until a U/K API call is made.
+ *
+ * The notification queue is a FIFO. There are no restrictions on the numbers
+ * of readers or writers in the queue.
+ *
+ * A message contains what user space needs to identifiy how to handle an
+ * event. This includes a type field and a possible type specific payload.
+ *
+ * A notification to user space is represented by a
+ * \ref _mali_osk_notification_t object. A sender gets hold of such an object
+ * using _mali_osk_notification_create(). The buffer given by the
+ * _mali_osk_notification_t::result_buffer field in the object is used to store
+ * any type specific data. The other fields are internal to the queue system
+ * and should not be touched.
+ *
+ * @{ */
+
+/** @brief Create a notification object
+ *
+ * Returns a notification object which can be added to the queue of
+ * notifications pending for user space transfer.
+ *
+ * The implementation will initialize all members of the
+ * \ref _mali_osk_notification_t object. In particular, the
+ * _mali_osk_notification_t::result_buffer member will be initialized to point
+ * to \a size bytes of storage, and that storage will be suitably aligned for
+ * storage of any structure. That is, the created buffer meets the same
+ * requirements as _mali_osk_malloc().
+ *
+ * The notification object must be deleted when not in use. Use
+ * _mali_osk_notification_delete() for deleting it.
+ *
+ * @note You \b must \b not call _mali_osk_free() on a \ref _mali_osk_notification_t,
+ * object, or on a _mali_osk_notification_t::result_buffer. You must only use
+ * _mali_osk_notification_delete() to free the resources assocaited with a
+ * \ref _mali_osk_notification_t object.
+ *
+ * @param type The notification type
+ * @param size The size of the type specific buffer to send
+ * @return Pointer to a notification object with a suitable buffer, or NULL on error.
+ */
+_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size );
+
+/** @brief Delete a notification object
+ *
+ * This must be called to reclaim the resources of a notification object. This
+ * includes:
+ * - The _mali_osk_notification_t::result_buffer
+ * - The \ref _mali_osk_notification_t itself.
+ *
+ * A notification object \b must \b not be used after it has been deleted by
+ * _mali_osk_notification_delete().
+ *
+ * In addition, the notification object may not be deleted while it is in a
+ * queue. That is, if it has been placed on a queue with
+ * _mali_osk_notification_queue_send(), then it must not be deleted until
+ * it has been received by a call to _mali_osk_notification_queue_receive().
+ * Otherwise, the queue may be corrupted.
+ *
+ * @param object the notification object to delete.
+ */
+void _mali_osk_notification_delete( _mali_osk_notification_t *object );
+
+/** @brief Create a notification queue
+ *
+ * Creates a notification queue which can be used to queue messages for user
+ * delivery and get queued messages from
+ *
+ * The queue is a FIFO, and has no restrictions on the numbers of readers or
+ * writers.
+ *
+ * When the queue is no longer in use, it must be terminated with
+ * \ref _mali_osk_notification_queue_term(). Failure to do so will result in a
+ * memory leak.
+ *
+ * @return Pointer to a new notification queue or NULL on error.
+ */
+_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void );
+
+/** @brief Destroy a notification queue
+ *
+ * Destroys a notification queue and frees associated resources from the queue.
+ *
+ * A notification queue \b must \b not be destroyed in the following cases:
+ * - while there are \ref _mali_osk_notification_t objects in the queue.
+ * - while there are writers currently acting upon the queue. That is, while
+ * a thread is currently calling \ref _mali_osk_notification_queue_send() on
+ * the queue, or while a thread may call
+ * \ref _mali_osk_notification_queue_send() on the queue in the future.
+ * - while there are readers currently waiting upon the queue. That is, while
+ * a thread is currently calling \ref _mali_osk_notification_queue_receive() on
+ * the queue, or while a thread may call
+ * \ref _mali_osk_notification_queue_receive() on the queue in the future.
+ *
+ * Therefore, all \ref _mali_osk_notification_t objects must be flushed and
+ * deleted by the code that makes use of the notification queues, since only
+ * they know the structure of the _mali_osk_notification_t::result_buffer
+ * (even if it may only be a flat sturcture).
+ *
+ * @note Since the queue is a FIFO, the code using notification queues may
+ * create its own 'flush' type of notification, to assist in flushing the
+ * queue.
+ *
+ * Once the queue has been destroyed, it must not be used again.
+ *
+ * @param queue The queue to destroy
+ */
+void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue );
+
+/** @brief Schedule notification for delivery
+ *
+ * When a \ref _mali_osk_notification_t object has been created successfully
+ * and set up, it may be added to the queue of objects waiting for user space
+ * transfer.
+ *
+ * The sending will not block if the queue is full.
+ *
+ * A \ref _mali_osk_notification_t object \b must \b not be put on two different
+ * queues at the same time, or enqueued twice onto a single queue before
+ * reception. However, it is acceptable for it to be requeued \em after reception
+ * from a call to _mali_osk_notification_queue_receive(), even onto the same queue.
+ *
+ * Again, requeuing must also not enqueue onto two different queues at the same
+ * time, or enqueue onto the same queue twice before reception.
+ *
+ * @param queue The notification queue to add this notification to
+ * @param object The entry to add
+ */
+void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object );
+
+/** @brief Receive a notification from a queue
+ *
+ * Receives a single notification from the given queue.
+ *
+ * If no notifciations are ready the thread will sleep until one becomes ready.
+ * Therefore, notifications may not be received into an
+ * IRQ or 'atomic' context (that is, a context where sleeping is disallowed).
+ *
+ * @param queue The queue to receive from
+ * @param result Pointer to storage of a pointer of type
+ * \ref _mali_osk_notification_t*. \a result will be written to such that the
+ * expression \a (*result) will evaluate to a pointer to a valid
+ * \ref _mali_osk_notification_t object, or NULL if none were received.
+ * @return _MALI_OSK_ERR_OK on success. _MALI_OSK_ERR_RESTARTSYSCALL if the sleep was interrupted.
+ */
+_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result );
+
+/** @brief Dequeues a notification from a queue
+ *
+ * Receives a single notification from the given queue.
+ *
+ * If no notifciations are ready the function call will return an error code.
+ *
+ * @param queue The queue to receive from
+ * @param result Pointer to storage of a pointer of type
+ * \ref _mali_osk_notification_t*. \a result will be written to such that the
+ * expression \a (*result) will evaluate to a pointer to a valid
+ * \ref _mali_osk_notification_t object, or NULL if none were received.
+ * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if queue was empty.
+ */
+_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result );
+
+/** @} */ /* end group _mali_osk_notification */
+
+
+/** @addtogroup _mali_osk_timer
+ *
+ * Timers use the OS's representation of time, which are 'ticks'. This is to
+ * prevent aliasing problems between the internal timer time, and the time
+ * asked for.
+ *
+ * @{ */
+
+/** @brief Initialize a timer
+ *
+ * Allocates resources for a new timer, and initializes them. This does not
+ * start the timer.
+ *
+ * @return a pointer to the allocated timer object, or NULL on failure.
+ */
+_mali_osk_timer_t *_mali_osk_timer_init(void);
+
+/** @brief Start a timer
+ *
+ * It is an error to start a timer without setting the callback via
+ * _mali_osk_timer_setcallback().
+ *
+ * It is an error to use this to start an already started timer.
+ *
+ * The timer will expire in \a ticks_to_expire ticks, at which point, the
+ * callback function will be invoked with the callback-specific data,
+ * as registered by _mali_osk_timer_setcallback().
+ *
+ * @param tim the timer to start
+ * @param ticks_to_expire the amount of time in ticks for the timer to run
+ * before triggering.
+ */
+void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire );
+
+/** @brief Modify a timer
+ *
+ * Set the relative time at which a timer will expire, and start it if it is
+ * stopped. If \a ticks_to_expire 0 the timer fires immediately.
+ *
+ * It is an error to modify a timer without setting the callback via
+ * _mali_osk_timer_setcallback().
+ *
+ * The timer will expire at \a ticks_to_expire from the time of the call, at
+ * which point, the callback function will be invoked with the
+ * callback-specific data, as set by _mali_osk_timer_setcallback().
+ *
+ * @param tim the timer to modify, and start if necessary
+ * @param ticks_to_expire the \em absolute time in ticks at which this timer
+ * should trigger.
+ *
+ */
+void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 ticks_to_expire);
+
+/** @brief Stop a timer, and block on its completion.
+ *
+ * Stop the timer. When the function returns, it is guaranteed that the timer's
+ * callback will not be running on any CPU core.
+ *
+ * Since stoping the timer blocks on compeletion of the callback, the callback
+ * may not obtain any mutexes that the caller holds. Otherwise, a deadlock will
+ * occur.
+ *
+ * @note While the callback itself is guaranteed to not be running, work
+ * enqueued on the work-queue by the timer (with
+ * \ref _mali_osk_wq_schedule_work()) may still run. The timer callback and
+ * work handler must take this into account.
+ *
+ * It is legal to stop an already stopped timer.
+ *
+ * @param tim the timer to stop.
+ *
+ */
+void _mali_osk_timer_del( _mali_osk_timer_t *tim );
+
+/** @brief Stop a timer.
+ *
+ * Stop the timer. When the function returns, the timer's callback may still be
+ * running on any CPU core.
+ *
+ * It is legal to stop an already stopped timer.
+ *
+ * @param tim the timer to stop.
+ */
+void _mali_osk_timer_del_async( _mali_osk_timer_t *tim );
+
+/** @brief Check if timer is pending.
+ *
+ * Check if timer is active.
+ *
+ * @param tim the timer to check
+ * @return MALI_TRUE if time is active, MALI_FALSE if it is not active
+ */
+mali_bool _mali_osk_timer_pending( _mali_osk_timer_t *tim);
+
+/** @brief Set a timer's callback parameters.
+ *
+ * This must be called at least once before a timer is started/modified.
+ *
+ * After a timer has been stopped or expires, the callback remains set. This
+ * means that restarting the timer will call the same function with the same
+ * parameters on expiry.
+ *
+ * @param tim the timer to set callback on.
+ * @param callback Function to call when timer expires
+ * @param data Function-specific data to supply to the function on expiry.
+ */
+void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data );
+
+/** @brief Terminate a timer, and deallocate resources.
+ *
+ * The timer must first be stopped by calling _mali_osk_timer_del().
+ *
+ * It is a programming error for _mali_osk_timer_term() to be called on:
+ * - timer that is currently running
+ * - a timer that is currently executing its callback.
+ *
+ * @param tim the timer to deallocate.
+ */
+void _mali_osk_timer_term( _mali_osk_timer_t *tim );
+/** @} */ /* end group _mali_osk_timer */
+
+
+/** @defgroup _mali_osk_time OSK Time functions
+ *
+ * \ref _mali_osk_time use the OS's representation of time, which are
+ * 'ticks'. This is to prevent aliasing problems between the internal timer
+ * time, and the time asked for.
+ *
+ * OS tick time is measured as a u32. The time stored in a u32 may either be
+ * an absolute time, or a time delta between two events. Whilst it is valid to
+ * use math opeartors to \em change the tick value represented as a u32, it
+ * is often only meaningful to do such operations on time deltas, rather than
+ * on absolute time. However, it is meaningful to add/subtract time deltas to
+ * absolute times.
+ *
+ * Conversion between tick time and milliseconds (ms) may not be loss-less,
+ * and are \em implementation \em depenedant.
+ *
+ * Code use OS time must take this into account, since:
+ * - a small OS time may (or may not) be rounded
+ * - a large time may (or may not) overflow
+ *
+ * @{ */
+
+/** @brief Return whether ticka occurs after tickb
+ *
+ * Some OSs handle tick 'rollover' specially, and so can be more robust against
+ * tick counters rolling-over. This function must therefore be called to
+ * determine if a time (in ticks) really occurs after another time (in ticks).
+ *
+ * @param ticka ticka
+ * @param tickb tickb
+ * @return non-zero if ticka represents a time that occurs after tickb.
+ * Zero otherwise.
+ */
+int _mali_osk_time_after( u32 ticka, u32 tickb );
+
+/** @brief Convert milliseconds to OS 'ticks'
+ *
+ * @param ms time interval in milliseconds
+ * @return the corresponding time interval in OS ticks.
+ */
+u32 _mali_osk_time_mstoticks( u32 ms );
+
+/** @brief Convert OS 'ticks' to milliseconds
+ *
+ * @param ticks time interval in OS ticks.
+ * @return the corresponding time interval in milliseconds
+ */
+u32 _mali_osk_time_tickstoms( u32 ticks );
+
+
+/** @brief Get the current time in OS 'ticks'.
+ * @return the current time in OS 'ticks'.
+ */
+u32 _mali_osk_time_tickcount( void );
+
+/** @brief Cause a microsecond delay
+ *
+ * The delay will have microsecond resolution, and is necessary for correct
+ * operation of the driver. At worst, the delay will be \b at least \a usecs
+ * microseconds, and so may be (significantly) more.
+ *
+ * This function may be implemented as a busy-wait, which is the most sensible
+ * implementation. On OSs where there are situations in which a thread must not
+ * sleep, this is definitely implemented as a busy-wait.
+ *
+ * @param usecs the number of microseconds to wait for.
+ */
+void _mali_osk_time_ubusydelay( u32 usecs );
+
+/** @brief Return time in nano seconds, since any given reference.
+ *
+ * @return Time in nano seconds
+ */
+u64 _mali_osk_time_get_ns( void );
+
+
+/** @} */ /* end group _mali_osk_time */
+
+/** @defgroup _mali_osk_math OSK Math
+ * @{ */
+
+/** @brief Count Leading Zeros (Little-endian)
+ *
+ * @note This function must be implemented to support the reference
+ * implementation of _mali_osk_find_first_zero_bit, as defined in
+ * mali_osk_bitops.h.
+ *
+ * @param val 32-bit words to count leading zeros on
+ * @return the number of leading zeros.
+ */
+u32 _mali_osk_clz( u32 val );
+/** @} */ /* end group _mali_osk_math */
+
+/** @defgroup _mali_osk_wait_queue OSK Wait Queue functionality
+ * @{ */
+/** @brief Private type for wait queue objects */
+typedef struct _mali_osk_wait_queue_t_struct _mali_osk_wait_queue_t;
+
+/** @brief Initialize an empty Wait Queue */
+_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void );
+
+/** @brief Sleep if condition is false
+ *
+ * @param queue the queue to use
+ * @param condition function pointer to a boolean function
+ *
+ * Put thread to sleep if the given \a codition function returns false. When
+ * being asked to wake up again, the condition will be re-checked and the
+ * thread only woken up if the condition is now true.
+ */
+void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) );
+
+/** @brief Wake up all threads in wait queue if their respective conditions are
+ * true
+ *
+ * @param queue the queue whose threads should be woken up
+ *
+ * Wake up all threads in wait queue \a queue whose condition is now true.
+ */
+void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue );
+
+/** @brief terminate a wait queue
+ *
+ * @param queue the queue to terminate.
+ */
+void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue );
+/** @} */ /* end group _mali_osk_wait_queue */
+
+
+/** @addtogroup _mali_osk_miscellaneous
+ * @{ */
+
+/** @brief Output a device driver debug message.
+ *
+ * The interpretation of \a fmt is the same as the \c format parameter in
+ * _mali_osu_vsnprintf().
+ *
+ * @param fmt a _mali_osu_vsnprintf() style format string
+ * @param ... a variable-number of parameters suitable for \a fmt
+ */
+void _mali_osk_dbgmsg( const char *fmt, ... );
+
+/** @brief Print fmt into buf.
+ *
+ * The interpretation of \a fmt is the same as the \c format parameter in
+ * _mali_osu_vsnprintf().
+ *
+ * @param buf a pointer to the result buffer
+ * @param size the total number of bytes allowed to write to \a buf
+ * @param fmt a _mali_osu_vsnprintf() style format string
+ * @param ... a variable-number of parameters suitable for \a fmt
+ * @return The number of bytes written to \a buf
+ */
+u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... );
+
+/** @brief Abnormal process abort.
+ *
+ * Terminates the caller-process if this function is called.
+ *
+ * This function will be called from Debug assert-macros in mali_kernel_common.h.
+ *
+ * This function will never return - because to continue from a Debug assert
+ * could cause even more problems, and hinder debugging of the initial problem.
+ *
+ * This function is only used in Debug builds, and is not used in Release builds.
+ */
+void _mali_osk_abort(void);
+
+/** @brief Sets breakpoint at point where function is called.
+ *
+ * This function will be called from Debug assert-macros in mali_kernel_common.h,
+ * to assist in debugging. If debugging at this level is not required, then this
+ * function may be implemented as a stub.
+ *
+ * This function is only used in Debug builds, and is not used in Release builds.
+ */
+void _mali_osk_break(void);
+
+/** @brief Return an identificator for calling process.
+ *
+ * @return Identificator for calling process.
+ */
+u32 _mali_osk_get_pid(void);
+
+/** @brief Return an identificator for calling thread.
+ *
+ * @return Identificator for calling thread.
+ */
+u32 _mali_osk_get_tid(void);
+
+/** @brief Enable OS controlled runtime power management
+ */
+void _mali_osk_pm_dev_enable(void);
+
+/** @brief Disable OS controlled runtime power management
+ */
+void _mali_osk_pm_dev_disable(void);
+
+
+/** @brief Take a reference to the power manager system for the Mali device.
+ *
+ * When function returns successfully, Mali is ON.
+ *
+ * @note Call \a _mali_osk_pm_dev_ref_dec() to release this reference.
+ */
+_mali_osk_errcode_t _mali_osk_pm_dev_ref_add(void);
+
+
+/** @brief Release the reference to the power manger system for the Mali device.
+ *
+ * When reference count reach zero, the cores can be off.
+ *
+ * @note This must be used to release references taken with \a _mali_osk_pm_dev_ref_add().
+ */
+void _mali_osk_pm_dev_ref_dec(void);
+
+
+/** @brief Take a reference to the power manager system for the Mali device.
+ *
+ * Will leave the cores powered off if they are already powered off.
+ *
+ * @note Call \a _mali_osk_pm_dev_ref_dec() to release this reference.
+ *
+ * @return MALI_TRUE if the Mali GPU is powered on, otherwise MALI_FALSE.
+ */
+mali_bool _mali_osk_pm_dev_ref_add_no_power_on(void);
+
+
+/** @brief Releasing the reference to the power manger system for the Mali device.
+ *
+ * When reference count reach zero, the cores can be off.
+ *
+ * @note This must be used to release references taken with \a _mali_osk_pm_dev_ref_add_no_power_on().
+ */
+void _mali_osk_pm_dev_ref_dec_no_power_on(void);
+
+/** @brief Block untill pending PM operations are done
+ */
+void _mali_osk_pm_dev_barrier(void);
+
+/** @} */ /* end group _mali_osk_miscellaneous */
+
+/** @} */ /* end group osuapi */
+
+/** @} */ /* end group uddapi */
+
+#ifdef __cplusplus
+}
+#endif
+
+#include "mali_osk_specific.h" /* include any per-os specifics */
+
+/* Check standard inlines */
+#ifndef MALI_STATIC_INLINE
+ #error MALI_STATIC_INLINE not defined on your OS
+#endif
+
+#ifndef MALI_NON_STATIC_INLINE
+ #error MALI_NON_STATIC_INLINE not defined on your OS
+#endif
+
+#endif /* __MALI_OSK_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.h
new file mode 100644
index 0000000..f262f7d
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_bitops.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_bitops.h
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#ifndef __MALI_OSK_BITOPS_H__
+#define __MALI_OSK_BITOPS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MALI_STATIC_INLINE void _mali_internal_clear_bit( u32 bit, u32 *addr )
+{
+ MALI_DEBUG_ASSERT( bit < 32 );
+ MALI_DEBUG_ASSERT( NULL != addr );
+
+ (*addr) &= ~(1 << bit);
+}
+
+MALI_STATIC_INLINE void _mali_internal_set_bit( u32 bit, u32 *addr )
+{
+ MALI_DEBUG_ASSERT( bit < 32 );
+ MALI_DEBUG_ASSERT( NULL != addr );
+
+ (*addr) |= (1 << bit);
+}
+
+MALI_STATIC_INLINE u32 _mali_internal_test_bit( u32 bit, u32 value )
+{
+ MALI_DEBUG_ASSERT( bit < 32 );
+ return value & (1 << bit);
+}
+
+MALI_STATIC_INLINE int _mali_internal_find_first_zero_bit( u32 value )
+{
+ u32 inverted;
+ u32 negated;
+ u32 isolated;
+ u32 leading_zeros;
+
+ /* Begin with xxx...x0yyy...y, where ys are 1, number of ys is in range 0..31 */
+ inverted = ~value; /* zzz...z1000...0 */
+ /* Using count_trailing_zeros on inverted value -
+ * See ARM System Developers Guide for details of count_trailing_zeros */
+
+ /* Isolate the zero: it is preceeded by a run of 1s, so add 1 to it */
+ negated = (u32)-inverted ; /* -a == ~a + 1 (mod 2^n) for n-bit numbers */
+ /* negated = xxx...x1000...0 */
+
+ isolated = negated & inverted ; /* xxx...x1000...0 & zzz...z1000...0, zs are ~xs */
+ /* And so the first zero bit is in the same position as the 1 == number of 1s that preceeded it
+ * Note that the output is zero if value was all 1s */
+
+ leading_zeros = _mali_osk_clz( isolated );
+
+ return 31 - leading_zeros;
+}
+
+
+/** @defgroup _mali_osk_bitops OSK Non-atomic Bit-operations
+ * @{ */
+
+/**
+ * These bit-operations do not work atomically, and so locks must be used if
+ * atomicity is required.
+ *
+ * Reference implementations for Little Endian are provided, and so it should
+ * not normally be necessary to re-implement these. Efficient bit-twiddling
+ * techniques are used where possible, implemented in portable C.
+ *
+ * Note that these reference implementations rely on _mali_osk_clz() being
+ * implemented.
+ */
+
+/** @brief Clear a bit in a sequence of 32-bit words
+ * @param nr bit number to clear, starting from the (Little-endian) least
+ * significant bit
+ * @param addr starting point for counting.
+ */
+MALI_STATIC_INLINE void _mali_osk_clear_nonatomic_bit( u32 nr, u32 *addr )
+{
+ addr += nr >> 5; /* find the correct word */
+ nr = nr & ((1 << 5)-1); /* The bit number within the word */
+
+ _mali_internal_clear_bit( nr, addr );
+}
+
+/** @brief Set a bit in a sequence of 32-bit words
+ * @param nr bit number to set, starting from the (Little-endian) least
+ * significant bit
+ * @param addr starting point for counting.
+ */
+MALI_STATIC_INLINE void _mali_osk_set_nonatomic_bit( u32 nr, u32 *addr )
+{
+ addr += nr >> 5; /* find the correct word */
+ nr = nr & ((1 << 5)-1); /* The bit number within the word */
+
+ _mali_internal_set_bit( nr, addr );
+}
+
+/** @brief Test a bit in a sequence of 32-bit words
+ * @param nr bit number to test, starting from the (Little-endian) least
+ * significant bit
+ * @param addr starting point for counting.
+ * @return zero if bit was clear, non-zero if set. Do not rely on the return
+ * value being related to the actual word under test.
+ */
+MALI_STATIC_INLINE u32 _mali_osk_test_bit( u32 nr, u32 *addr )
+{
+ addr += nr >> 5; /* find the correct word */
+ nr = nr & ((1 << 5)-1); /* The bit number within the word */
+
+ return _mali_internal_test_bit( nr, *addr );
+}
+
+/* Return maxbit if not found */
+/** @brief Find the first zero bit in a sequence of 32-bit words
+ * @param addr starting point for search.
+ * @param maxbit the maximum number of bits to search
+ * @return the number of the first zero bit found, or maxbit if none were found
+ * in the specified range.
+ */
+MALI_STATIC_INLINE u32 _mali_osk_find_first_zero_bit( const u32 *addr, u32 maxbit )
+{
+ u32 total;
+
+ for ( total = 0; total < maxbit; total += 32, ++addr )
+ {
+ int result;
+ result = _mali_internal_find_first_zero_bit( *addr );
+
+ /* non-negative signifies the bit was found */
+ if ( result >= 0 )
+ {
+ total += (u32)result;
+ break;
+ }
+ }
+
+ /* Now check if we reached maxbit or above */
+ if ( total >= maxbit )
+ {
+ total = maxbit;
+ }
+
+ return total; /* either the found bit nr, or maxbit if not found */
+}
+/** @} */ /* end group _mali_osk_bitops */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_OSK_BITOPS_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h
new file mode 100644
index 0000000..49f01b6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_list.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_list.h
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#ifndef __MALI_OSK_LIST_H__
+#define __MALI_OSK_LIST_H__
+
+#include "mali_kernel_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+MALI_STATIC_INLINE void __mali_osk_list_add(_mali_osk_list_t *new_entry, _mali_osk_list_t *prev, _mali_osk_list_t *next)
+{
+ next->prev = new_entry;
+ new_entry->next = next;
+ new_entry->prev = prev;
+ prev->next = new_entry;
+}
+
+MALI_STATIC_INLINE void __mali_osk_list_del(_mali_osk_list_t *prev, _mali_osk_list_t *next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/** @addtogroup _mali_osk_list
+ * @{ */
+
+/** Reference implementations of Doubly-linked Circular Lists are provided.
+ * There is often no need to re-implement these.
+ *
+ * @note The implementation may differ subtly from any lists the OS provides.
+ * For this reason, these lists should not be mixed with OS-specific lists
+ * inside the OSK/UKK implementation. */
+
+/** @brief Initialize a list element.
+ *
+ * All list elements must be initialized before use.
+ *
+ * Do not use on any list element that is present in a list without using
+ * _mali_osk_list_del first, otherwise this will break the list.
+ *
+ * @param list the list element to initialize
+ */
+MALI_STATIC_INLINE void _mali_osk_list_init( _mali_osk_list_t *list )
+{
+ list->next = list;
+ list->prev = list;
+}
+
+/** @brief Insert a single list element after an entry in a list
+ *
+ * As an example, if this is inserted to the head of a list, then this becomes
+ * the first element of the list.
+ *
+ * Do not use to move list elements from one list to another, as it will break
+ * the originating list.
+ *
+ *
+ * @param newlist the list element to insert
+ * @param list the list in which to insert. The new element will be the next
+ * entry in this list
+ */
+MALI_STATIC_INLINE void _mali_osk_list_add( _mali_osk_list_t *new_entry, _mali_osk_list_t *list )
+{
+ __mali_osk_list_add(new_entry, list, list->next);
+}
+
+/** @brief Insert a single list element before an entry in a list
+ *
+ * As an example, if this is inserted to the head of a list, then this becomes
+ * the last element of the list.
+ *
+ * Do not use to move list elements from one list to another, as it will break
+ * the originating list.
+ *
+ * @param newlist the list element to insert
+ * @param list the list in which to insert. The new element will be the previous
+ * entry in this list
+ */
+MALI_STATIC_INLINE void _mali_osk_list_addtail( _mali_osk_list_t *new_entry, _mali_osk_list_t *list )
+{
+ __mali_osk_list_add(new_entry, list->prev, list);
+}
+
+/** @brief Remove a single element from a list
+ *
+ * The element will no longer be present in the list. The removed list element
+ * will be uninitialized, and so should not be traversed. It must be
+ * initialized before further use.
+ *
+ * @param list the list element to remove.
+ */
+MALI_STATIC_INLINE void _mali_osk_list_del( _mali_osk_list_t *list )
+{
+ __mali_osk_list_del(list->prev, list->next);
+}
+
+/** @brief Remove a single element from a list, and re-initialize it
+ *
+ * The element will no longer be present in the list. The removed list element
+ * will initialized, and so can be used as normal.
+ *
+ * @param list the list element to remove and initialize.
+ */
+MALI_STATIC_INLINE void _mali_osk_list_delinit( _mali_osk_list_t *list )
+{
+ __mali_osk_list_del(list->prev, list->next);
+ _mali_osk_list_init(list);
+}
+
+/** @brief Determine whether a list is empty.
+ *
+ * An empty list is one that contains a single element that points to itself.
+ *
+ * @param list the list to check.
+ * @return non-zero if the list is empty, and zero otherwise.
+ */
+MALI_STATIC_INLINE mali_bool _mali_osk_list_empty( _mali_osk_list_t *list )
+{
+ return list->next == list;
+}
+
+/** @brief Move a list element from one list to another.
+ *
+ * The list element must be initialized.
+ *
+ * As an example, moving a list item to the head of a new list causes this item
+ * to be the first element in the new list.
+ *
+ * @param move the list element to move
+ * @param list the new list into which the element will be inserted, as the next
+ * element in the list.
+ */
+MALI_STATIC_INLINE void _mali_osk_list_move( _mali_osk_list_t *move_entry, _mali_osk_list_t *list )
+{
+ __mali_osk_list_del(move_entry->prev, move_entry->next);
+ _mali_osk_list_add(move_entry, list);
+}
+
+/** @brief Move an entire list
+ *
+ * The list element must be initialized.
+ *
+ * Allows you to move a list from one list head to another list head
+ *
+ * @param old_list The existing list head
+ * @param new_list The new list head (must be an empty list)
+ */
+MALI_STATIC_INLINE void _mali_osk_list_move_list( _mali_osk_list_t *old_list, _mali_osk_list_t *new_list )
+{
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(new_list));
+ if (!_mali_osk_list_empty(old_list))
+ {
+ new_list->next = old_list->next;
+ new_list->prev = old_list->prev;
+ new_list->next->prev = new_list;
+ new_list->prev->next = new_list;
+ old_list->next = old_list;
+ old_list->prev = old_list;
+ }
+}
+/** @} */ /* end group _mali_osk_list */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_OSK_LIST_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h
new file mode 100644
index 0000000..2916a0d
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_mali.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_mali.h
+ * Defines the OS abstraction layer which is specific for the Mali kernel device driver (OSK)
+ */
+
+#ifndef __MALI_OSK_MALI_H__
+#define __MALI_OSK_MALI_H__
+
+#include <linux/mali/mali_utgard.h>
+#include <mali_osk.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/** @addtogroup _mali_osk_miscellaneous
+ * @{ */
+
+/** @brief Struct with device specific configuration data
+ */
+struct _mali_osk_device_data
+{
+ /* Dedicated GPU memory range (physical). */
+ u32 dedicated_mem_start;
+ u32 dedicated_mem_size;
+
+ /* Shared GPU memory */
+ u32 shared_mem_size;
+
+ /* Frame buffer memory to be accessible by Mali GPU (physical) */
+ u32 fb_start;
+ u32 fb_size;
+
+ /* Report GPU utilization in this interval (specified in ms) */
+ u32 utilization_interval;
+
+ /* Function that will receive periodic GPU utilization numbers */
+ void (*utilization_callback)(struct mali_gpu_utilization_data *data);
+
+ /*
+ * Mali PMU switch delay.
+ * Only needed if the power gates are connected to the PMU in a high fanout
+ * network. This value is the number of Mali clock cycles it takes to
+ * enable the power gates and turn on the power mesh.
+ * This value will have no effect if a daisy chain implementation is used.
+ */
+ u32 pmu_switch_delay;
+};
+
+/** @brief Find Mali GPU HW resource
+ *
+ * @param addr Address of Mali GPU resource to find
+ * @param res Storage for resource information if resource is found.
+ * @return _MALI_OSK_ERR_OK on success, _MALI_OSK_ERR_ITEM_NOT_FOUND if resource is not found
+ */
+_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res);
+
+
+/** @brief Find Mali GPU HW base address
+ *
+ * @return 0 if resources are found, otherwise the Mali GPU component with lowest address.
+ */
+u32 _mali_osk_resource_base_address(void);
+
+/** @brief Retrieve the Mali GPU specific data
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_device_data_get(struct _mali_osk_device_data *data);
+
+/** @brief Determines if Mali GPU has been configured with shared interrupts.
+ *
+ * @return MALI_TRUE if shared interrupts, MALI_FALSE if not.
+ */
+mali_bool _mali_osk_shared_interrupts(void);
+
+/** @} */ /* end group _mali_osk_miscellaneous */
+
+
+
+
+/** @addtogroup _mali_osk_low_level_memory
+ * @{ */
+
+/** @brief Initialize a user-space accessible memory range
+ *
+ * This initializes a virtual address range such that it is reserved for the
+ * current process, but does not map any physical pages into this range.
+ *
+ * This function may initialize or adjust any members of the
+ * mali_memory_allocation \a descriptor supplied, before the physical pages are
+ * mapped in with _mali_osk_mem_mapregion_map().
+ *
+ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
+ * set in \a descriptor->flags. It is an error to call this function without
+ * setting this flag. Otherwise, \a descriptor->flags bits are reserved for
+ * future expansion
+ *
+ * The \a descriptor's process_addr_mapping_info member can be modified to
+ * allocate OS-specific information. Note that on input, this will be a
+ * ukk_private word from the U/K inteface, as inserted by _mali_ukk_mem_mmap().
+ * This is used to pass information from the U/K interface to the OSK interface,
+ * if necessary. The precise usage of the process_addr_mapping_info member
+ * depends on the U/K implementation of _mali_ukk_mem_mmap().
+ *
+ * Therefore, the U/K implementation of _mali_ukk_mem_mmap() and the OSK
+ * implementation of _mali_osk_mem_mapregion_init() must agree on the meaning and
+ * usage of the ukk_private word and process_addr_mapping_info member.
+ *
+ * Refer to \ref u_k_api for more information on the U/K interface.
+ *
+ * On successful return, \a descriptor's mapping member will be correct for
+ * use with _mali_osk_mem_mapregion_term() and _mali_osk_mem_mapregion_map().
+ *
+ * @param descriptor the mali_memory_allocation to initialize.
+ */
+_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor );
+
+/** @brief Terminate a user-space accessible memory range
+ *
+ * This terminates a virtual address range reserved in the current user process,
+ * where none, some or all of the virtual address ranges have mappings to
+ * physical pages.
+ *
+ * It will unmap any physical pages that had been mapped into a reserved
+ * virtual address range for the current process, and then releases the virtual
+ * address range. Any extra book-keeping information or resources allocated
+ * during _mali_osk_mem_mapregion_init() will also be released.
+ *
+ * The \a descriptor itself is not freed - this must be handled by the caller of
+ * _mali_osk_mem_mapregion_term().
+ *
+ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
+ * set in descriptor->flags. It is an error to call this function without
+ * setting this flag. Otherwise, descriptor->flags bits are reserved for
+ * future expansion
+ *
+ * @param descriptor the mali_memory_allocation to terminate.
+ */
+void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor );
+
+/** @brief Map physical pages into a user process's virtual address range
+ *
+ * This is used to map a number of physically contigous pages into a
+ * user-process's virtual address range, which was previously reserved by a
+ * call to _mali_osk_mem_mapregion_init().
+ *
+ * This need not provide a mapping for the entire virtual address range
+ * reserved for \a descriptor - it may be used to map single pages per call.
+ *
+ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
+ * set in \a descriptor->flags. It is an error to call this function without
+ * setting this flag. Otherwise, \a descriptor->flags bits are reserved for
+ * future expansion
+ *
+ * The function may supply \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC.
+ * In this case, \a size must be set to \ref _MALI_OSK_CPU_PAGE_SIZE, and the function
+ * will allocate the physical page itself. The physical address of the
+ * allocated page will be returned through \a phys_addr.
+ *
+ * It is an error to set \a size != \ref _MALI_OSK_CPU_PAGE_SIZE while
+ * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC,
+ * since it is not always possible for OSs to support such a setting through this
+ * interface.
+ *
+ * @note \b IMPORTANT: This code must validate the input parameters. If the
+ * range defined by \a offset and \a size is outside the range allocated in
+ * \a descriptor, then this function \b MUST not attempt any mapping, and must
+ * instead return a suitable \ref _mali_osk_errcode_t \b failure code.
+ *
+ * @param[in,out] descriptor the mali_memory_allocation representing the
+ * user-process's virtual address range to map into.
+ *
+ * @param[in] offset the offset into the virtual address range. This is only added
+ * to the mapping member of the \a descriptor, and not the \a phys_addr parameter.
+ * It must be a multiple of \ref _MALI_OSK_CPU_PAGE_SIZE.
+ *
+ * @param[in,out] phys_addr a pointer to the physical base address to begin the
+ * mapping from. If \a size == \ref _MALI_OSK_CPU_PAGE_SIZE and
+ * \a *phys_addr == \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, then this
+ * function will allocate the physical page itself, and return the
+ * physical address of the page through \a phys_addr, which will be aligned to
+ * \ref _MALI_OSK_CPU_PAGE_SIZE. Otherwise, \a *phys_addr must be aligned to
+ * \ref _MALI_OSK_CPU_PAGE_SIZE, and is unmodified after the call.
+ * \a phys_addr is unaffected by the \a offset parameter.
+ *
+ * @param[in] size the number of bytes to map in. This must be a multiple of
+ * \ref _MALI_OSK_CPU_PAGE_SIZE.
+ *
+ * @return _MALI_OSK_ERR_OK on sucess, otherwise a _mali_osk_errcode_t value
+ * on failure
+ *
+ * @note could expand to use _mali_osk_mem_mapregion_flags_t instead of
+ * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC, but note that we must
+ * also modify the mali process address manager in the mmu/memory engine code.
+ */
+_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size );
+
+
+/** @brief Unmap physical pages from a user process's virtual address range
+ *
+ * This is used to unmap a number of physically contigous pages from a
+ * user-process's virtual address range, which were previously mapped by a
+ * call to _mali_osk_mem_mapregion_map(). If the range specified was allocated
+ * from OS memory, then that memory will be returned to the OS. Whilst pages
+ * will be mapped out, the Virtual address range remains reserved, and at the
+ * same base address.
+ *
+ * When this function is used to unmap pages from OS memory
+ * (_mali_osk_mem_mapregion_map() was called with *phys_addr ==
+ * \ref MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC), then the \a flags must
+ * include \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR. This is because
+ * it is not always easy for an OS implementation to discover whether the
+ * memory was OS allocated or not (and so, how it should release the memory).
+ *
+ * For this reason, only a range of pages of the same allocation type (all OS
+ * allocated, or none OS allocacted) may be unmapped in one call. Multiple
+ * calls must be made if allocations of these different types exist across the
+ * entire region described by the \a descriptor.
+ *
+ * The function will always be called with MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE
+ * set in \a descriptor->flags. It is an error to call this function without
+ * setting this flag. Otherwise, \a descriptor->flags bits are reserved for
+ * future expansion
+ *
+ * @param[in,out] descriptor the mali_memory_allocation representing the
+ * user-process's virtual address range to map into.
+ *
+ * @param[in] offset the offset into the virtual address range. This is only added
+ * to the mapping member of the \a descriptor. \a offset must be a multiple of
+ * \ref _MALI_OSK_CPU_PAGE_SIZE.
+ *
+ * @param[in] size the number of bytes to unmap. This must be a multiple of
+ * \ref _MALI_OSK_CPU_PAGE_SIZE.
+ *
+ * @param[in] flags specifies how the memory should be unmapped. For a range
+ * of pages that were originally OS allocated, this must have
+ * \ref _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR set.
+ */
+void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags );
+
+/** @brief Copy as much data as possible from src to dest, do not crash if src or dest isn't available.
+ *
+ * @param dest Destination buffer (limited to user space mapped Mali memory)
+ * @param src Source buffer
+ * @param size Number of bytes to copy
+ * @return Number of bytes actually copied
+ */
+u32 _mali_osk_mem_write_safe(void *dest, const void *src, u32 size);
+
+/** @} */ /* end group _mali_osk_low_level_memory */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_OSK_MALI_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h
new file mode 100644
index 0000000..c4822e2
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_osk_profiling.h
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_OSK_PROFILING_H__
+#define __MALI_OSK_PROFILING_H__
+
+#if defined(CONFIG_MALI400_PROFILING) && defined (CONFIG_TRACEPOINTS)
+
+#include "mali_linux_trace.h"
+#include "mali_profiling_events.h"
+#include "mali_profiling_gator_api.h"
+
+#define MALI_PROFILING_MAX_BUFFER_ENTRIES 1048576
+
+#define MALI_PROFILING_NO_HW_COUNTER = ((u32)-1)
+
+/** @defgroup _mali_osk_profiling External profiling connectivity
+ * @{ */
+
+/**
+ * Initialize the profiling module.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start);
+
+/*
+ * Terminate the profiling module.
+ */
+void _mali_osk_profiling_term(void);
+
+/**
+ * Start recording profiling data
+ *
+ * The specified limit will determine how large the capture buffer is.
+ * MALI_PROFILING_MAX_BUFFER_ENTRIES determines the maximum size allowed by the device driver.
+ *
+ * @param limit The desired maximum number of events to record on input, the actual maximum on output.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
+
+/**
+ * Add an profiling event
+ *
+ * @param event_id The event identificator.
+ * @param data0 First data parameter, depending on event_id specified.
+ * @param data1 Second data parameter, depending on event_id specified.
+ * @param data2 Third data parameter, depending on event_id specified.
+ * @param data3 Fourth data parameter, depending on event_id specified.
+ * @param data4 Fifth data parameter, depending on event_id specified.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+/* Call Linux tracepoint directly */
+#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4) trace_mali_timeline_event((event_id), (data0), (data1), (data2), (data3), (data4))
+
+/**
+ * Report a hardware counter event.
+ *
+ * @param counter_id The ID of the counter.
+ * @param value The value of the counter.
+ */
+
+/* Call Linux tracepoint directly */
+#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value)
+
+/**
+ * Report SW counters
+ *
+ * @param counters array of counter values
+ */
+void _mali_osk_profiling_report_sw_counters(u32 *counters);
+
+/**
+ * Stop recording profiling data
+ *
+ * @param count Returns the number of recorded events.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count);
+
+/**
+ * Retrieves the number of events that can be retrieved
+ *
+ * @return The number of recorded events that can be retrieved.
+ */
+u32 _mali_osk_profiling_get_count(void);
+
+/**
+ * Retrieve an event
+ *
+ * @param index Event index (start with 0 and continue until this function fails to retrieve all events)
+ * @param timestamp The timestamp for the retrieved event will be stored here.
+ * @param event_id The event ID for the retrieved event will be stored here.
+ * @param data The 5 data values for the retrieved event will be stored here.
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
+
+/**
+ * Clear the recorded buffer.
+ *
+ * This is needed in order to start another recording.
+ *
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t _mali_osk_profiling_clear(void);
+
+/**
+ * Checks if a recording of profiling data is in progress
+ *
+ * @return MALI_TRUE if recording of profiling data is in progress, MALI_FALSE if not
+ */
+mali_bool _mali_osk_profiling_is_recording(void);
+
+/**
+ * Checks if profiling data is available for retrival
+ *
+ * @return MALI_TRUE if profiling data is avaiable, MALI_FALSE if not
+ */
+mali_bool _mali_osk_profiling_have_recording(void);
+
+/** @} */ /* end group _mali_osk_profiling */
+
+#else /* defined(CONFIG_MALI400_PROFILING) && defined(CONFIG_TRACEPOINTS) */
+
+ /* Dummy add_event, for when profiling is disabled. */
+
+#define _mali_osk_profiling_add_event(event_id, data0, data1, data2, data3, data4)
+
+#endif /* defined(CONFIG_MALI400_PROFILING) && defined(CONFIG_TRACEPOINTS) */
+
+#endif /* __MALI_OSK_PROFILING_H__ */
+
+
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.c
new file mode 100644
index 0000000..e1d6aa4
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_pm.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_scheduler.h"
+#include "mali_kernel_utilization.h"
+#include "mali_group.h"
+#include "mali_pm_domain.h"
+#include "mali_pmu.h"
+
+static mali_bool mali_power_on = MALI_FALSE;
+
+_mali_osk_errcode_t mali_pm_initialize(void)
+{
+ _mali_osk_pm_dev_enable();
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pm_terminate(void)
+{
+ mali_pm_domain_terminate();
+ _mali_osk_pm_dev_disable();
+}
+
+/* Reset GPU after power up */
+static void mali_pm_reset_gpu(void)
+{
+ /* Reset all L2 caches */
+ mali_l2_cache_reset_all();
+
+ /* Reset all groups */
+ mali_scheduler_reset_all_groups();
+}
+
+void mali_pm_os_suspend(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali PM: OS suspend\n"));
+ mali_gp_scheduler_suspend();
+ mali_pp_scheduler_suspend();
+ mali_utilization_suspend();
+/* MALI_SEC */
+#if !defined(CONFIG_PM_RUNTIME)
+ mali_group_power_off();
+ mali_power_on = MALI_FALSE;
+#endif
+}
+
+void mali_pm_os_resume(void)
+{
+#if !defined(CONFIG_PM_RUNTIME)
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+ mali_bool do_reset = MALI_FALSE;
+#endif
+
+ MALI_DEBUG_PRINT(3, ("Mali PM: OS resume\n"));
+/* MALI_SEC */
+/******************************************************************
+ *
+ * <2013. 08. 23>
+ * In Pegasus prime, PMU is not enabled(Power off) while
+ * system wake up(suspend -> resume).
+ *
+ * Because PMU power is off, GPU does not work.
+ * Therefore code is commented like below.
+ *
+ *****************************************************************/
+#if !defined(CONFIG_PM_RUNTIME)
+ if (MALI_TRUE != mali_power_on)
+ {
+ do_reset = MALI_TRUE;
+ }
+
+ if (NULL != pmu)
+ {
+ mali_pmu_reset(pmu);
+ }
+
+ mali_power_on = MALI_TRUE;
+ _mali_osk_write_mem_barrier();
+
+ if (do_reset)
+ {
+ mali_pm_reset_gpu();
+ mali_group_power_on();
+ }
+#endif
+ mali_gp_scheduler_resume();
+ mali_pp_scheduler_resume();
+}
+
+void mali_pm_runtime_suspend(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali PM: Runtime suspend\n"));
+ mali_group_power_off();
+ mali_power_on = MALI_FALSE;
+}
+
+void mali_pm_runtime_resume(void)
+{
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+ mali_bool do_reset = MALI_FALSE;
+
+ MALI_DEBUG_PRINT(3, ("Mali PM: Runtime resume\n"));
+
+ if (MALI_TRUE != mali_power_on)
+ {
+ do_reset = MALI_TRUE;
+ }
+
+ if (NULL != pmu)
+ {
+ mali_pmu_reset(pmu);
+ }
+
+ mali_power_on = MALI_TRUE;
+ _mali_osk_write_mem_barrier();
+
+ if (do_reset)
+ {
+ mali_pm_reset_gpu();
+ mali_group_power_on();
+ }
+}
+
+void mali_pm_set_power_is_on(void)
+{
+ mali_power_on = MALI_TRUE;
+}
+
+mali_bool mali_pm_is_power_on(void)
+{
+ return mali_power_on;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.h
new file mode 100644
index 0000000..36f0f50
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PM_H__
+#define __MALI_PM_H__
+
+#include "mali_osk.h"
+
+_mali_osk_errcode_t mali_pm_initialize(void);
+void mali_pm_terminate(void);
+
+/* Callback functions registered for the runtime PMM system */
+void mali_pm_os_suspend(void);
+void mali_pm_os_resume(void);
+void mali_pm_runtime_suspend(void);
+void mali_pm_runtime_resume(void);
+
+void mali_pm_set_power_is_on(void);
+mali_bool mali_pm_is_power_on(void);
+
+#endif /* __MALI_PM_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c
new file mode 100644
index 0000000..9193778
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_pm_domain.h"
+#include "mali_pmu.h"
+#include "mali_pm.h"
+#include "mali_group.h"
+
+#define MALI_PM_DOMAIN_MAX_DOMAINS 7
+
+static struct mali_pm_domain *mali_pm_domains[MALI_PM_DOMAIN_MAX_DOMAINS] = { NULL, };
+
+static void mali_pm_domain_lock(struct mali_pm_domain *domain)
+{
+ _mali_osk_lock_wait(domain->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+static void mali_pm_domain_unlock(struct mali_pm_domain *domain)
+{
+ _mali_osk_lock_signal(domain->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+MALI_STATIC_INLINE void mali_pm_domain_state_set(struct mali_pm_domain *domain, mali_pm_domain_state state)
+{
+ domain->state = state;
+}
+
+struct mali_pm_domain *mali_pm_domain_create(u32 id, u32 pmu_mask)
+{
+ struct mali_pm_domain* domain;
+
+ MALI_DEBUG_PRINT(2, ("Mali PM domain: Creating Mali PM domain (mask=0x%08X)\n", pmu_mask));
+
+ domain = (struct mali_pm_domain *)_mali_osk_malloc(sizeof(struct mali_pm_domain));
+ if (NULL != domain)
+ {
+ _mali_osk_lock_flags_t flags = _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+ domain->lock = _mali_osk_lock_init(flags, 0, _MALI_OSK_LOCK_ORDER_PM_DOMAIN);
+ if (NULL == domain->lock)
+ {
+ _mali_osk_free(domain);
+ return NULL;
+ }
+
+ domain->state = MALI_PM_DOMAIN_ON;
+ domain->pmu_mask = pmu_mask;
+ domain->use_count = 0;
+ domain->group_list = NULL;
+ domain->group_count = 0;
+ domain->l2 = NULL;
+
+ MALI_DEBUG_ASSERT(MALI_PM_DOMAIN_MAX_DOMAINS > id);
+ mali_pm_domains[id] = domain;
+
+ return domain;
+ }
+ else
+ {
+ MALI_DEBUG_PRINT_ERROR(("Unable to create PM domain\n"));
+ }
+
+ return NULL;
+}
+
+void mali_pm_domain_delete(struct mali_pm_domain *domain)
+{
+ if (NULL == domain)
+ {
+ return;
+ }
+ _mali_osk_lock_term(domain->lock);
+
+ _mali_osk_free(domain);
+}
+
+void mali_pm_domain_terminate(void)
+{
+ int i;
+
+ /* Delete all domains */
+ for (i = 0; i < MALI_PM_DOMAIN_MAX_DOMAINS; i++)
+ {
+ mali_pm_domain_delete(mali_pm_domains[i]);
+ }
+}
+
+void mali_pm_domain_add_group(u32 id, struct mali_group *group)
+{
+ struct mali_pm_domain *domain = mali_pm_domain_get(id);
+ struct mali_group *next;
+
+ if (NULL == domain) return;
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ /* Assume domain is on and group is enabled initially. */
+ mali_pm_domain_ref_get(domain);
+
+ ++domain->group_count;
+ next = domain->group_list;
+
+ domain->group_list = group;
+
+ group->pm_domain_list = next;
+
+ mali_group_set_pm_domain(group, domain);
+}
+
+void mali_pm_domain_add_l2(u32 id, struct mali_l2_cache_core *l2)
+{
+ struct mali_pm_domain *domain = mali_pm_domain_get(id);
+
+ if (NULL == domain) return;
+
+ MALI_DEBUG_ASSERT(NULL == domain->l2);
+ MALI_DEBUG_ASSERT(NULL != l2);
+
+ domain->l2 = l2;
+
+ mali_l2_cache_set_pm_domain(l2, domain);
+}
+
+struct mali_pm_domain *mali_pm_domain_get(u32 id)
+{
+ MALI_DEBUG_ASSERT(MALI_PM_DOMAIN_MAX_DOMAINS > id);
+
+ return mali_pm_domains[id];
+}
+
+void mali_pm_domain_ref_get(struct mali_pm_domain *domain)
+{
+ if (NULL == domain) return;
+
+ mali_pm_domain_lock(domain);
+ ++domain->use_count;
+
+ if (MALI_PM_DOMAIN_ON != domain->state)
+ {
+ /* Power on */
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(3, ("PM Domain: Powering on 0x%08x\n", domain->pmu_mask));
+
+ if (NULL != pmu)
+ {
+ _mali_osk_errcode_t err;
+
+ err = mali_pmu_power_up(pmu, domain->pmu_mask);
+
+ if (_MALI_OSK_ERR_OK != err && _MALI_OSK_ERR_BUSY != err)
+ {
+ MALI_PRINT_ERROR(("PM Domain: Failed to power up PM domain 0x%08x\n",
+ domain->pmu_mask));
+ }
+ }
+ mali_pm_domain_state_set(domain, MALI_PM_DOMAIN_ON);
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(MALI_PM_DOMAIN_ON == mali_pm_domain_state_get(domain));
+ }
+
+ mali_pm_domain_unlock(domain);
+}
+
+void mali_pm_domain_ref_put(struct mali_pm_domain *domain)
+{
+ if (NULL == domain) return;
+
+ mali_pm_domain_lock(domain);
+ --domain->use_count;
+
+ if (0 == domain->use_count && MALI_PM_DOMAIN_OFF != domain->state)
+ {
+ /* Power off */
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(3, ("PM Domain: Powering off 0x%08x\n", domain->pmu_mask));
+
+ mali_pm_domain_state_set(domain, MALI_PM_DOMAIN_OFF);
+
+ if (NULL != pmu)
+ {
+ _mali_osk_errcode_t err;
+
+ err = mali_pmu_power_down(pmu, domain->pmu_mask);
+
+ if (_MALI_OSK_ERR_OK != err && _MALI_OSK_ERR_BUSY != err)
+ {
+ MALI_PRINT_ERROR(("PM Domain: Failed to power down PM domain 0x%08x\n",
+ domain->pmu_mask));
+ }
+ }
+ }
+ mali_pm_domain_unlock(domain);
+}
+
+mali_bool mali_pm_domain_lock_state(struct mali_pm_domain *domain)
+{
+ mali_bool is_powered = MALI_TRUE;
+
+ /* Take a reference without powering on */
+ if (NULL != domain)
+ {
+ mali_pm_domain_lock(domain);
+ ++domain->use_count;
+
+ if (MALI_PM_DOMAIN_ON != domain->state)
+ {
+ is_powered = MALI_FALSE;
+ }
+ mali_pm_domain_unlock(domain);
+ }
+
+ if(!_mali_osk_pm_dev_ref_add_no_power_on())
+ {
+ is_powered = MALI_FALSE;
+ }
+
+ return is_powered;
+}
+
+void mali_pm_domain_unlock_state(struct mali_pm_domain *domain)
+{
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ if (NULL != domain)
+ {
+ mali_pm_domain_ref_put(domain);
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h
new file mode 100644
index 0000000..3f3fa24
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pm_domain.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PM_DOMAIN_H__
+#define __MALI_PM_DOMAIN_H__
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+
+#include "mali_l2_cache.h"
+#include "mali_group.h"
+#include "mali_pmu.h"
+
+typedef enum
+{
+ MALI_PM_DOMAIN_ON,
+ MALI_PM_DOMAIN_OFF,
+} mali_pm_domain_state;
+
+struct mali_pm_domain
+{
+ mali_pm_domain_state state;
+ _mali_osk_lock_t *lock;
+
+ s32 use_count;
+
+ u32 pmu_mask;
+
+ int group_count;
+ struct mali_group *group_list;
+
+ struct mali_l2_cache_core *l2;
+};
+
+struct mali_pm_domain *mali_pm_domain_create(u32 id, u32 pmu_mask);
+void mali_pm_domain_add_group(u32 id, struct mali_group *group);
+void mali_pm_domain_add_l2(u32 id, struct mali_l2_cache_core *l2);
+void mali_pm_domain_delete(struct mali_pm_domain *domain);
+
+void mali_pm_domain_terminate(void);
+
+/** Get PM domain from domain ID
+ */
+struct mali_pm_domain *mali_pm_domain_get(u32 id);
+
+/* Ref counting */
+void mali_pm_domain_ref_get(struct mali_pm_domain *domain);
+void mali_pm_domain_ref_put(struct mali_pm_domain *domain);
+
+MALI_STATIC_INLINE struct mali_l2_cache_core *mali_pm_domain_l2_get(struct mali_pm_domain *domain)
+{
+ return domain->l2;
+}
+
+MALI_STATIC_INLINE mali_pm_domain_state mali_pm_domain_state_get(struct mali_pm_domain *domain)
+{
+ return domain->state;
+}
+
+mali_bool mali_pm_domain_lock_state(struct mali_pm_domain *domain);
+void mali_pm_domain_unlock_state(struct mali_pm_domain *domain);
+
+#define MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain) for ((group) = (domain)->group_list;\
+ NULL != (group); (group) = (group)->pm_domain_list)
+
+#endif /* __MALI_PM_DOMAIN_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c
new file mode 100644
index 0000000..668c8e9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.c
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_pmu.c
+ * Mali driver functions for Mali 400 PMU hardware
+ */
+#include "mali_hw_core.h"
+#include "mali_pmu.h"
+#include "mali_pp.h"
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_pm.h"
+#include "mali_osk_mali.h"
+
+static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches);
+
+/** @brief MALI inbuilt PMU hardware info and PMU hardware has knowledge of cores power mask
+ */
+struct mali_pmu_core
+{
+ struct mali_hw_core hw_core;
+ _mali_osk_lock_t *lock;
+ u32 registered_cores_mask;
+ u32 active_cores_mask;
+ u32 switch_delay;
+};
+
+static struct mali_pmu_core *mali_global_pmu_core = NULL;
+
+/** @brief Register layout for hardware PMU
+ */
+typedef enum {
+ PMU_REG_ADDR_MGMT_POWER_UP = 0x00, /*< Power up register */
+ PMU_REG_ADDR_MGMT_POWER_DOWN = 0x04, /*< Power down register */
+ PMU_REG_ADDR_MGMT_STATUS = 0x08, /*< Core sleep status register */
+ PMU_REG_ADDR_MGMT_INT_MASK = 0x0C, /*< Interrupt mask register */
+ PMU_REG_ADDR_MGMT_INT_RAWSTAT = 0x10, /*< Interrupt raw status register */
+ PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */
+ PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Switch delay register */
+ PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */
+} pmu_reg_addr_mgmt_addr;
+
+#define PMU_REG_VAL_IRQ 1
+
+struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches)
+{
+ struct mali_pmu_core* pmu;
+
+ MALI_DEBUG_ASSERT(NULL == mali_global_pmu_core);
+ MALI_DEBUG_PRINT(2, ("Mali PMU: Creating Mali PMU core\n"));
+
+ pmu = (struct mali_pmu_core *)_mali_osk_malloc(sizeof(struct mali_pmu_core));
+ if (NULL != pmu)
+ {
+ pmu->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE,
+ 0, _MALI_OSK_LOCK_ORDER_PMU);
+ if (NULL != pmu->lock)
+ {
+ pmu->registered_cores_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches);
+ pmu->active_cores_mask = pmu->registered_cores_mask;
+
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE))
+ {
+ _mali_osk_errcode_t err;
+ struct _mali_osk_device_data data = { 0, };
+
+ err = _mali_osk_device_data_get(&data);
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ pmu->switch_delay = data.pmu_switch_delay;
+ mali_global_pmu_core = pmu;
+ return pmu;
+ }
+ mali_hw_core_delete(&pmu->hw_core);
+ }
+ _mali_osk_lock_term(pmu->lock);
+ }
+ _mali_osk_free(pmu);
+ }
+
+ return NULL;
+}
+
+void mali_pmu_delete(struct mali_pmu_core *pmu)
+{
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu == mali_global_pmu_core);
+ MALI_DEBUG_PRINT(2, ("Mali PMU: Deleting Mali PMU core\n"));
+
+ _mali_osk_lock_term(pmu->lock);
+ mali_hw_core_delete(&pmu->hw_core);
+ _mali_osk_free(pmu);
+ mali_global_pmu_core = NULL;
+}
+
+static void mali_pmu_lock(struct mali_pmu_core *pmu)
+{
+ _mali_osk_lock_wait(pmu->lock, _MALI_OSK_LOCKMODE_RW);
+}
+static void mali_pmu_unlock(struct mali_pmu_core *pmu)
+{
+ _mali_osk_lock_signal(pmu->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+static _mali_osk_errcode_t mali_pmu_send_command_internal(struct mali_pmu_core *pmu, const u32 command, const u32 mask)
+{
+ u32 rawstat;
+ u32 timeout = MALI_REG_POLL_COUNT_SLOW;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(0 == (mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT)
+ & PMU_REG_VAL_IRQ));
+
+ mali_hw_core_register_write(&pmu->hw_core, command, mask);
+
+ /* Wait for the command to complete */
+ do
+ {
+ rawstat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_RAWSTAT);
+ --timeout;
+ } while (0 == (rawstat & PMU_REG_VAL_IRQ) && 0 < timeout);
+
+ MALI_DEBUG_ASSERT(0 < timeout);
+ if (0 == timeout)
+ {
+ return _MALI_OSK_ERR_TIMEOUT;
+ }
+
+ mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_CLEAR, PMU_REG_VAL_IRQ);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_pmu_send_command(struct mali_pmu_core *pmu, const u32 command, const u32 mask)
+{
+ u32 stat;
+
+ if (0 == mask) return _MALI_OSK_ERR_OK;
+
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->registered_cores_mask;
+
+ switch (command)
+ {
+ case PMU_REG_ADDR_MGMT_POWER_DOWN:
+ if (mask == stat) return _MALI_OSK_ERR_OK;
+ break;
+ case PMU_REG_ADDR_MGMT_POWER_UP:
+ if (0 == (stat & mask)) return _MALI_OSK_ERR_OK;
+ break;
+ default:
+ MALI_DEBUG_ASSERT(0);
+ break;
+ }
+
+ mali_pmu_send_command_internal(pmu, command, mask);
+
+#if defined(DEBUG)
+ {
+ /* Get power status of cores */
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->registered_cores_mask;
+
+ switch (command)
+ {
+ case PMU_REG_ADDR_MGMT_POWER_DOWN:
+ MALI_DEBUG_ASSERT(mask == (stat & mask));
+ MALI_DEBUG_ASSERT(0 == (stat & pmu->active_cores_mask));
+ MALI_DEBUG_ASSERT((pmu->registered_cores_mask & ~pmu->active_cores_mask) == stat);
+ break;
+ case PMU_REG_ADDR_MGMT_POWER_UP:
+ MALI_DEBUG_ASSERT(0 == (stat & mask));
+ MALI_DEBUG_ASSERT(0 == (stat & pmu->active_cores_mask));
+ break;
+ default:
+ MALI_DEBUG_ASSERT(0);
+ break;
+ }
+ }
+#endif /* defined(DEBUG) */
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu)
+{
+ _mali_osk_errcode_t err;
+ u32 cores_off_mask, cores_on_mask, stat;
+
+ mali_pmu_lock(pmu);
+
+ /* Setup the desired defaults */
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay);
+
+ /* Get power status of cores */
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+
+ cores_off_mask = pmu->registered_cores_mask & ~(stat | pmu->active_cores_mask);
+ cores_on_mask = pmu->registered_cores_mask & (stat & pmu->active_cores_mask);
+
+ if (0 != cores_off_mask)
+ {
+ err = mali_pmu_send_command_internal(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, cores_off_mask);
+ if (_MALI_OSK_ERR_OK != err) return err;
+ }
+
+ if (0 != cores_on_mask)
+ {
+ err = mali_pmu_send_command_internal(pmu, PMU_REG_ADDR_MGMT_POWER_UP, cores_on_mask);
+ if (_MALI_OSK_ERR_OK != err) return err;
+ }
+
+#if defined(DEBUG)
+ {
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->registered_cores_mask;
+
+ MALI_DEBUG_ASSERT(stat == (pmu->registered_cores_mask & ~pmu->active_cores_mask));
+ }
+#endif /* defined(DEBUG) */
+
+ mali_pmu_unlock(pmu);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pmu_power_down(struct mali_pmu_core *pmu, u32 mask)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0 );
+
+ /* Make sure we have a valid power domain mask */
+ if (mask > pmu->registered_cores_mask)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ mali_pmu_lock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Power down (0x%08X)\n", mask));
+
+ pmu->active_cores_mask &= ~mask;
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ if (!mali_pm_is_power_on())
+ {
+ /* Don't touch hardware if all of Mali is powered off. */
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Skipping power down (0x%08X) since Mali is off\n", mask));
+
+ return _MALI_OSK_ERR_BUSY;
+ }
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, mask);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_pmu_power_up(struct mali_pmu_core *pmu, u32 mask)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0 );
+
+ /* Make sure we have a valid power domain mask */
+ if (mask & ~pmu->registered_cores_mask)
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ mali_pmu_lock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Power up (0x%08X)\n", mask));
+
+ pmu->active_cores_mask |= mask;
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ if (!mali_pm_is_power_on())
+ {
+ /* Don't touch hardware if all of Mali is powered off. */
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Skipping power up (0x%08X) since Mali is off\n", mask));
+
+ return _MALI_OSK_ERR_BUSY;
+ }
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_UP, mask);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pmu_unlock(pmu);
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_pmu_power_down_all(struct mali_pmu_core *pmu)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0);
+
+ mali_pmu_lock(pmu);
+
+ /* Setup the desired defaults in case we were called before mali_pmu_reset() */
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay);
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->registered_cores_mask);
+
+ mali_pmu_unlock(pmu);
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_pmu_power_up_all(struct mali_pmu_core *pmu)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT(pmu->registered_cores_mask != 0);
+
+ mali_pmu_lock(pmu);
+
+ /* Setup the desired defaults in case we were called before mali_pmu_reset() */
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ mali_hw_core_register_write_relaxed(&pmu->hw_core, PMU_REG_ADDR_MGMT_SW_DELAY, pmu->switch_delay);
+
+ err = mali_pmu_send_command(pmu, PMU_REG_ADDR_MGMT_POWER_UP, pmu->active_cores_mask);
+
+ mali_pmu_unlock(pmu);
+ return err;
+}
+
+struct mali_pmu_core *mali_pmu_get_global_pmu_core(void)
+{
+ return mali_global_pmu_core;
+}
+
+static u32 mali_pmu_detect_mask(u32 number_of_pp_cores, u32 number_of_l2_caches)
+{
+ u32 mask = 0;
+
+ if (number_of_l2_caches == 1)
+ {
+ /* Mali-300 or Mali-400 */
+ u32 i;
+
+ /* GP */
+ mask = 0x01;
+
+ /* L2 cache */
+ mask |= 0x01<<1;
+
+ /* Set bit for each PP core */
+ for (i = 0; i < number_of_pp_cores; i++)
+ {
+ mask |= 0x01<<(i+2);
+ }
+ }
+ else if (number_of_l2_caches > 1)
+ {
+ /* Mali-450 */
+
+ /* GP (including its L2 cache) */
+ mask = 0x01;
+
+ /* There is always at least one PP (including its L2 cache) */
+ mask |= 0x01<<1;
+
+ /* Additional PP cores in same L2 cache */
+ if (number_of_pp_cores >= 2)
+ {
+ mask |= 0x01<<2;
+ }
+
+ /* Additional PP cores in a third L2 cache */
+ if (number_of_pp_cores >= 5)
+ {
+ mask |= 0x01<<3;
+ }
+ }
+
+ MALI_DEBUG_PRINT(4, ("Mali PMU: Power mask is 0x%08X (%u + %u)\n", mask, number_of_pp_cores, number_of_l2_caches));
+
+ return mask;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h
new file mode 100644
index 0000000..7e2f67c
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pmu.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_platform.h
+ * Platform specific Mali driver functions
+ */
+
+#ifndef __MALI_PMU_H__
+#define __MALI_PMU_H__
+
+#include "mali_osk.h"
+
+#define MALI_PMU_M450_DOM1 0
+#define MALI_PMU_M450_DOM1_MASK (1 << 1)
+#define MALI_PMU_M450_DOM2 1
+#define MALI_PMU_M450_DOM2_MASK (1 << 2)
+#define MALI_PMU_M450_DOM3 2
+#define MALI_PMU_M450_DOM3_MASK (1 << 3)
+
+#define MALI_PMU_M400_PP0 0
+#define MALI_PMU_M400_PP0_MASK (1 << 2)
+#define MALI_PMU_M400_PP1 1
+#define MALI_PMU_M400_PP1_MASK (1 << 3)
+#define MALI_PMU_M400_PP2 2
+#define MALI_PMU_M400_PP2_MASK (1 << 4)
+#define MALI_PMU_M400_PP3 3
+#define MALI_PMU_M400_PP3_MASK (1 << 5)
+
+struct mali_pmu_core;
+
+/** @brief Initialisation of MALI PMU
+ *
+ * This is called from entry point of the driver in order to create and intialize the PMU resource
+ *
+ * @param resource it will be a pointer to a PMU resource
+ * @param number_of_pp_cores Number of found PP resources in configuration
+ * @param number_of_l2_caches Number of found L2 cache resources in configuration
+ * @return The created PMU object, or NULL in case of failure.
+ */
+struct mali_pmu_core *mali_pmu_create(_mali_osk_resource_t *resource, u32 number_of_pp_cores, u32 number_of_l2_caches);
+
+/** @brief It deallocates the PMU resource
+ *
+ * This is called on the exit of the driver to terminate the PMU resource
+ *
+ * @param pmu Pointer to PMU core object to delete
+ */
+void mali_pmu_delete(struct mali_pmu_core *pmu);
+
+/** @brief Reset PMU core
+ *
+ * @param pmu Pointer to PMU core object to reset
+ * @return _MALI_OSK_ERR_OK on success, otherwise failure.
+ */
+_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu);
+
+/** @brief MALI GPU power down using MALI in-built PMU
+ *
+ * Called to power down the specified cores. The mask will be saved so that \a
+ * mali_pmu_power_up_all will bring the PMU back to the previous state set with
+ * this function or \a mali_pmu_power_up.
+ *
+ * @param pmu Pointer to PMU core object to power down
+ * @param mask Mask specifying which power domains to power down
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmu_power_down(struct mali_pmu_core *pmu, u32 mask);
+
+/** @brief MALI GPU power up using MALI in-built PMU
+ *
+ * Called to power up the specified cores. The mask will be saved so that \a
+ * mali_pmu_power_up_all will bring the PMU back to the previous state set with
+ * this function or \a mali_pmu_power_down.
+ *
+ * @param pmu Pointer to PMU core object to power up
+ * @param mask Mask specifying which power domains to power up
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmu_power_up(struct mali_pmu_core *pmu, u32 mask);
+
+/** @brief MALI GPU power down using MALI in-built PMU
+ *
+ * called to power down all cores
+ *
+ * @param pmu Pointer to PMU core object to power down
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmu_power_down_all(struct mali_pmu_core *pmu);
+
+/** @brief MALI GPU power up using MALI in-built PMU
+ *
+ * called to power up all cores
+ *
+ * @param pmu Pointer to PMU core object to power up
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_pmu_power_up_all(struct mali_pmu_core *pmu);
+
+/** @brief Retrieves the Mali PMU core object (if any)
+ *
+ * @return The Mali PMU object, or NULL if no PMU exists.
+ */
+struct mali_pmu_core *mali_pmu_get_global_pmu_core(void);
+
+#endif /* __MALI_PMU_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.c
new file mode 100644
index 0000000..8273239
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.c
@@ -0,0 +1,521 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_pp_job.h"
+#include "mali_pp.h"
+#include "mali_hw_core.h"
+#include "mali_group.h"
+#include "regs/mali_200_regs.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+/* Number of frame registers on Mali-200 */
+#define MALI_PP_MALI200_NUM_FRAME_REGISTERS ((0x04C/4)+1)
+/* Number of frame registers on Mali-300 and later */
+#define MALI_PP_MALI400_NUM_FRAME_REGISTERS ((0x058/4)+1)
+
+static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES] = { NULL };
+static u32 mali_global_num_pp_cores = 0;
+
+/* Interrupt handlers */
+static void mali_pp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
+
+struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id)
+{
+ struct mali_pp_core* core = NULL;
+
+ MALI_DEBUG_PRINT(2, ("Mali PP: Creating Mali PP core: %s\n", resource->description));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Base address of PP core: 0x%x\n", resource->base));
+
+ if (mali_global_num_pp_cores >= MALI_MAX_NUMBER_OF_PP_CORES)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Too many PP core objects created\n"));
+ return NULL;
+ }
+
+ core = _mali_osk_malloc(sizeof(struct mali_pp_core));
+ if (NULL != core)
+ {
+ core->core_id = mali_global_num_pp_cores;
+ core->bcast_id = bcast_id;
+ core->counter_src0_used = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src1_used = MALI_HW_CORE_NO_COUNTER;
+
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALI200_REG_SIZEOF_REGISTER_BANK))
+ {
+ _mali_osk_errcode_t ret;
+
+ if (!is_virtual)
+ {
+ ret = mali_pp_reset(core);
+ }
+ else
+ {
+ ret = _MALI_OSK_ERR_OK;
+ }
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ ret = mali_group_add_pp_core(group, core);
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ MALI_DEBUG_ASSERT(!is_virtual || -1 != resource->irq);
+
+ core->irq = _mali_osk_irq_init(resource->irq,
+ mali_group_upper_half_pp,
+ group,
+ mali_pp_irq_probe_trigger,
+ mali_pp_irq_probe_ack,
+ core,
+ "mali_pp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ mali_global_pp_cores[mali_global_num_pp_cores] = core;
+ mali_global_num_pp_cores++;
+
+ return core;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\n", core->hw_core.description));
+ }
+ mali_group_remove_pp_core(group);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to add core %s to group\n", core->hw_core.description));
+ }
+ }
+ mali_hw_core_delete(&core->hw_core);
+ }
+
+ _mali_osk_free(core);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to allocate memory for PP core\n"));
+ }
+
+ return NULL;
+}
+
+void mali_pp_delete(struct mali_pp_core *core)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ _mali_osk_irq_term(core->irq);
+ mali_hw_core_delete(&core->hw_core);
+
+ /* Remove core from global list */
+ for (i = 0; i < mali_global_num_pp_cores; i++)
+ {
+ if (mali_global_pp_cores[i] == core)
+ {
+ mali_global_pp_cores[i] = NULL;
+ mali_global_num_pp_cores--;
+
+ if (i != mali_global_num_pp_cores)
+ {
+ /* We removed a PP core from the middle of the array -- move the last
+ * PP core to the current position to close the gap */
+ mali_global_pp_cores[i] = mali_global_pp_cores[mali_global_num_pp_cores];
+ mali_global_pp_cores[mali_global_num_pp_cores] = NULL;
+ }
+
+ break;
+ }
+ }
+
+ _mali_osk_free(core);
+}
+
+void mali_pp_stop_bus(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ /* Will only send the stop bus command, and not wait for it to complete */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
+}
+
+_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core)
+{
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ /* Send the stop bus command. */
+ mali_pp_stop_bus(core);
+
+ /* Wait for bus to be stopped */
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
+ break;
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to stop bus on %s. Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+/* Frame register reset values.
+ * Taken from the Mali400 TRM, 3.6. Pixel processor control register summary */
+static const u32 mali_frame_registers_reset_values[_MALI_PP_MAX_FRAME_REGISTERS] =
+{
+ 0x0, /* Renderer List Address Register */
+ 0x0, /* Renderer State Word Base Address Register */
+ 0x0, /* Renderer Vertex Base Register */
+ 0x2, /* Feature Enable Register */
+ 0x0, /* Z Clear Value Register */
+ 0x0, /* Stencil Clear Value Register */
+ 0x0, /* ABGR Clear Value 0 Register */
+ 0x0, /* ABGR Clear Value 1 Register */
+ 0x0, /* ABGR Clear Value 2 Register */
+ 0x0, /* ABGR Clear Value 3 Register */
+ 0x0, /* Bounding Box Left Right Register */
+ 0x0, /* Bounding Box Bottom Register */
+ 0x0, /* FS Stack Address Register */
+ 0x0, /* FS Stack Size and Initial Value Register */
+ 0x0, /* Reserved */
+ 0x0, /* Reserved */
+ 0x0, /* Origin Offset X Register */
+ 0x0, /* Origin Offset Y Register */
+ 0x75, /* Subpixel Specifier Register */
+ 0x0, /* Tiebreak mode Register */
+ 0x0, /* Polygon List Format Register */
+ 0x0, /* Scaling Register */
+ 0x0 /* Tilebuffer configuration Register */
+};
+
+/* WBx register reset values */
+static const u32 mali_wb_registers_reset_values[_MALI_PP_MAX_WB_REGISTERS] =
+{
+ 0x0, /* WBx Source Select Register */
+ 0x0, /* WBx Target Address Register */
+ 0x0, /* WBx Target Pixel Format Register */
+ 0x0, /* WBx Target AA Format Register */
+ 0x0, /* WBx Target Layout */
+ 0x0, /* WBx Target Scanline Length */
+ 0x0, /* WBx Target Flags Register */
+ 0x0, /* WBx MRT Enable Register */
+ 0x0, /* WBx MRT Offset Register */
+ 0x0, /* WBx Global Test Enable Register */
+ 0x0, /* WBx Global Test Reference Value Register */
+ 0x0 /* WBx Global Test Compare Function Register */
+};
+
+/* Performance Counter 0 Enable Register reset value */
+static const u32 mali_perf_cnt_enable_reset_value = 0;
+
+_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
+{
+ /* Bus must be stopped before calling this function */
+ const u32 reset_invalid_value = 0xC0FFE000;
+ const u32 reset_check_value = 0xC01A0000;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
+
+ /* Set register to a bogus value. The register will be used to detect when reset is complete */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
+
+ /* Force core to reset */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
+
+ /* Wait for reset to be complete */
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
+ if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW))
+ {
+ break;
+ }
+ }
+
+ if (MALI_REG_POLL_COUNT_FAST == i)
+ {
+ MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
+ }
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pp_reset_async(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
+}
+
+_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core)
+{
+ int i;
+ u32 rawstat = 0;
+
+ for (i = 0; i < MALI_REG_POLL_COUNT_FAST; i++)
+ {
+ if (!(mali_pp_read_status(core) & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE))
+ {
+ rawstat = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT);
+ if (rawstat == MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ }
+ }
+
+ if (i == MALI_REG_POLL_COUNT_FAST)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to reset core %s, rawstat: 0x%08x\n",
+ core->hw_core.description, rawstat));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Re-enable interrupts */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
+{
+ mali_pp_reset_async(core);
+ return mali_pp_reset_wait(core);
+}
+
+void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual)
+{
+ u32 relative_address;
+ u32 start_index;
+ u32 nr_of_regs;
+ u32 *frame_registers = mali_pp_job_get_frame_registers(job);
+ u32 *wb0_registers = mali_pp_job_get_wb0_registers(job);
+ u32 *wb1_registers = mali_pp_job_get_wb1_registers(job);
+ u32 *wb2_registers = mali_pp_job_get_wb2_registers(job);
+ core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job);
+ core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ /* Write frame registers */
+
+ /*
+ * There are two frame registers which are different for each sub job:
+ * 1. The Renderer List Address Register (MALI200_REG_ADDR_FRAME)
+ * 2. The FS Stack Address Register (MALI200_REG_ADDR_STACK)
+ */
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_FRAME / sizeof(u32)]);
+
+ /* For virtual jobs, the stack address shouldn't be broadcast but written individually */
+ if (!mali_pp_job_is_virtual(job) || restart_virtual)
+ {
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job), mali_frame_registers_reset_values[MALI200_REG_ADDR_STACK / sizeof(u32)]);
+ }
+
+ /* Write registers between MALI200_REG_ADDR_FRAME and MALI200_REG_ADDR_STACK */
+ relative_address = MALI200_REG_ADDR_RSW;
+ start_index = MALI200_REG_ADDR_RSW / sizeof(u32);
+ nr_of_regs = (MALI200_REG_ADDR_STACK - MALI200_REG_ADDR_RSW) / sizeof(u32);
+
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
+ relative_address, &frame_registers[start_index],
+ nr_of_regs, &mali_frame_registers_reset_values[start_index]);
+
+ /* MALI200_REG_ADDR_STACK_SIZE */
+ relative_address = MALI200_REG_ADDR_STACK_SIZE;
+ start_index = MALI200_REG_ADDR_STACK_SIZE / sizeof(u32);
+
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core,
+ relative_address, frame_registers[start_index],
+ mali_frame_registers_reset_values[start_index]);
+
+ /* Skip 2 reserved registers */
+
+ /* Write remaining registers */
+ relative_address = MALI200_REG_ADDR_ORIGIN_OFFSET_X;
+ start_index = MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
+ nr_of_regs = MALI_PP_MALI400_NUM_FRAME_REGISTERS - MALI200_REG_ADDR_ORIGIN_OFFSET_X / sizeof(u32);
+
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core,
+ relative_address, &frame_registers[start_index],
+ nr_of_regs, &mali_frame_registers_reset_values[start_index]);
+
+ /* Write WBx registers */
+ if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
+ }
+
+ if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
+ }
+
+ if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, _MALI_PP_MAX_WB_REGISTERS, mali_wb_registers_reset_values);
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ }
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write_relaxed_conditional(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE, mali_perf_cnt_enable_reset_value);
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: Starting job 0x%08X part %u/%u on PP core %s\n", job, sub_job + 1, mali_pp_job_get_sub_job_count(job), core->hw_core.description));
+
+ /* Adding barrier to make sure all rester writes are finished */
+ _mali_osk_write_mem_barrier();
+
+ /* This is the command that starts the core. */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
+
+ /* Adding barrier to make sure previous rester writes is finished */
+ _mali_osk_write_mem_barrier();
+}
+
+u32 mali_pp_core_get_version(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION);
+}
+
+struct mali_pp_core* mali_pp_get_global_pp_core(u32 index)
+{
+ if (mali_global_num_pp_cores > index)
+ {
+ return mali_global_pp_cores[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_pp_get_glob_num_pp_cores(void)
+{
+ return mali_global_num_pp_cores;
+}
+
+/* ------------- interrupt handling below ------------------ */
+static void mali_pp_irq_probe_trigger(void *data)
+{
+ struct mali_pp_core *core = (struct mali_pp_core *)data;
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
+ _mali_osk_mem_barrier();
+}
+
+static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data)
+{
+ struct mali_pp_core *core = (struct mali_pp_core *)data;
+ u32 irq_readout;
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
+ if (MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG);
+ _mali_osk_mem_barrier();
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+
+#if 0
+static void mali_pp_print_registers(struct mali_pp_core *core)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_VERSION = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_VERSION)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_MASK = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_INT_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC)));
+ MALI_DEBUG_PRINT(2, ("Mali PP: Register MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x%08X\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
+}
+#endif
+
+#if 0
+void mali_pp_print_state(struct mali_pp_core *core)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) ));
+}
+#endif
+
+void mali_pp_update_performance_counters(struct mali_pp_core *parent, struct mali_pp_core *child, struct mali_pp_job *job, u32 subjob)
+{
+ u32 val0 = 0;
+ u32 val1 = 0;
+#if defined(CONFIG_MALI400_PROFILING)
+ int counter_index = COUNTER_FP_0_C0 + (2 * child->core_id);
+#endif
+
+ if (MALI_HW_CORE_NO_COUNTER != parent->counter_src0_used)
+ {
+ val0 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
+ mali_pp_job_set_perf_counter_value0(job, subjob, val0);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(counter_index, val0);
+#endif
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != parent->counter_src1_used)
+ {
+ val1 = mali_hw_core_register_read(&child->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+ mali_pp_job_set_perf_counter_value1(job, subjob, val1);
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
+#endif
+ }
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size)
+{
+ int n = 0;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "\tPP #%d: %s\n", core->core_id, core->hw_core.description);
+
+ return n;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.h
new file mode 100644
index 0000000..dd8f350
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PP_H__
+#define __MALI_PP_H__
+
+#include "mali_osk.h"
+#include "mali_pp_job.h"
+#include "mali_hw_core.h"
+
+struct mali_group;
+
+#define MALI_MAX_NUMBER_OF_PP_CORES 9
+
+/**
+ * Definition of the PP core struct
+ * Used to track a PP core in the system.
+ */
+struct mali_pp_core
+{
+ struct mali_hw_core hw_core; /**< Common for all HW cores */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ u32 core_id; /**< Unique core ID */
+ u32 bcast_id; /**< The "flag" value used by the Mali-450 broadcast and DLBU unit */
+ u32 counter_src0_used; /**< The selected performance counter 0 when a job is running */
+ u32 counter_src1_used; /**< The selected performance counter 1 when a job is running */
+};
+
+_mali_osk_errcode_t mali_pp_initialize(void);
+void mali_pp_terminate(void);
+
+struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t * resource, struct mali_group *group, mali_bool is_virtual, u32 bcast_id);
+void mali_pp_delete(struct mali_pp_core *core);
+
+void mali_pp_stop_bus(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_stop_bus_wait(struct mali_pp_core *core);
+void mali_pp_reset_async(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_reset_wait(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core);
+_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core);
+
+void mali_pp_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job, mali_bool restart_virtual);
+
+u32 mali_pp_core_get_version(struct mali_pp_core *core);
+
+MALI_STATIC_INLINE u32 mali_pp_core_get_id(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->core_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_core_get_bcast_id(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->bcast_id;
+}
+
+struct mali_pp_core* mali_pp_get_global_pp_core(u32 index);
+u32 mali_pp_get_glob_num_pp_cores(void);
+
+/* Debug */
+u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size);
+
+/**
+ * Put instrumented HW counters from the core(s) to the job object (if enabled)
+ *
+ * parent and child is always the same, except for virtual jobs on Mali-450.
+ * In this case, the counters will be enabled on the virtual core (parent),
+ * but values need to be read from the child cores.
+ *
+ * @param parent The core used to see if the counters was enabled
+ * @param child The core to actually read the values from
+ * @job Job object to update with counter values (if enabled)
+ * @subjob Which subjob the counters are applicable for (core ID for virtual jobs)
+ */
+void mali_pp_update_performance_counters(struct mali_pp_core *parent, struct mali_pp_core *child, struct mali_pp_job *job, u32 subjob);
+
+MALI_STATIC_INLINE const char *mali_pp_get_hw_core_desc(struct mali_pp_core *core)
+{
+ return core->hw_core.description;
+}
+
+/*** Register reading/writing functions ***/
+MALI_STATIC_INLINE u32 mali_pp_get_int_stat(struct mali_pp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_STATUS);
+}
+
+MALI_STATIC_INLINE u32 mali_pp_read_rawstat(struct mali_pp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_read_status(struct mali_pp_core *core)
+{
+ return mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS);
+}
+
+MALI_STATIC_INLINE void mali_pp_mask_all_interrupts(struct mali_pp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
+}
+
+MALI_STATIC_INLINE void mali_pp_clear_hang_interrupt(struct mali_pp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
+}
+
+MALI_STATIC_INLINE void mali_pp_enable_interrupts(struct mali_pp_core *core)
+{
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+}
+
+MALI_STATIC_INLINE void mali_pp_write_addr_stack(struct mali_pp_core *core, struct mali_pp_job *job)
+{
+ u32 addr = mali_pp_job_get_addr_stack(job, core->core_id);
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, addr);
+}
+
+#endif /* __MALI_PP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c
new file mode 100644
index 0000000..ca0ea05
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_pp_job.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_kernel_common.h"
+#include "mali_uk_types.h"
+#include "mali_pp_scheduler.h"
+
+static u32 pp_counter_src0 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 0, MALI_HW_CORE_NO_COUNTER for disabled */
+static u32 pp_counter_src1 = MALI_HW_CORE_NO_COUNTER; /**< Performance counter 1, MALI_HW_CORE_NO_COUNTER for disabled */
+
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id)
+{
+ struct mali_pp_job *job;
+ u32 perf_counter_flag;
+
+ job = _mali_osk_calloc(1, sizeof(struct mali_pp_job));
+ if (NULL != job)
+ {
+ if (0 != _mali_osk_copy_from_user(&job->uargs, uargs, sizeof(_mali_uk_pp_start_job_s)))
+ {
+ goto fail;
+ }
+
+ if (job->uargs.num_cores > _MALI_PP_MAX_SUB_JOBS)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
+ goto fail;
+ }
+
+ if (!mali_pp_job_use_no_notification(job))
+ {
+ job->finished_notification = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s));
+ if (NULL == job->finished_notification) goto fail;
+ }
+
+ perf_counter_flag = mali_pp_job_get_perf_counter_flag(job);
+
+ /* case when no counters came from user space
+ * so pass the debugfs / DS-5 provided global ones to the job object */
+ if (!((perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE) ||
+ (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)))
+ {
+ mali_pp_job_set_perf_counter_src0(job, mali_pp_job_get_pp_counter_src0());
+ mali_pp_job_set_perf_counter_src1(job, mali_pp_job_get_pp_counter_src1());
+ }
+
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ _mali_osk_list_init(&job->session_list);
+ job->id = id;
+
+ job->sub_jobs_num = job->uargs.num_cores ? job->uargs.num_cores : 1;
+ job->pid = _mali_osk_get_pid();
+ job->tid = _mali_osk_get_tid();
+
+ job->num_memory_cookies = job->uargs.num_memory_cookies;
+ if (job->num_memory_cookies > 0)
+ {
+ u32 size;
+
+ if (job->uargs.num_memory_cookies > session->descriptor_mapping->current_nr_mappings)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Too many memory cookies specified in job object\n"));
+ goto fail;
+ }
+
+ size = sizeof(*job->uargs.memory_cookies) * job->num_memory_cookies;
+
+ job->memory_cookies = _mali_osk_malloc(size);
+ if (NULL == job->memory_cookies)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Failed to allocate %d bytes of memory cookies!\n", size));
+ goto fail;
+ }
+
+ if (0 != _mali_osk_copy_from_user(job->memory_cookies, job->uargs.memory_cookies, size))
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Failed to copy %d bytes of memory cookies from user!\n", size));
+ goto fail;
+ }
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ job->num_dma_bufs = job->num_memory_cookies;
+ job->dma_bufs = _mali_osk_calloc(job->num_dma_bufs, sizeof(struct mali_dma_buf_attachment *));
+ if (NULL == job->dma_bufs)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Failed to allocate dma_bufs array!\n"));
+ goto fail;
+ }
+#endif
+ }
+ else
+ {
+ job->memory_cookies = NULL;
+ }
+
+ return job;
+ }
+
+fail:
+ if (NULL != job)
+ {
+ mali_pp_job_delete(job);
+ }
+
+ return NULL;
+}
+
+void mali_pp_job_delete(struct mali_pp_job *job)
+{
+#ifdef CONFIG_SYNC
+ /* It is safe to delete the work without flushing. */
+ if (NULL != job->sync_work) _mali_osk_wq_delete_work_nonflush(job->sync_work);
+ if (NULL != job->pre_fence) sync_fence_put(job->pre_fence);
+ if (NULL != job->sync_point) sync_fence_put(job->sync_point->fence);
+#endif
+ if (NULL != job->finished_notification)
+ {
+ _mali_osk_notification_delete(job->finished_notification);
+ }
+
+ _mali_osk_free(job->memory_cookies);
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* Unmap buffers attached to job */
+ if (0 < job->num_dma_bufs)
+ {
+ mali_dma_buf_unmap_job(job);
+ }
+
+ _mali_osk_free(job->dma_bufs);
+#endif /* CONFIG_DMA_SHARED_BUFFER */
+
+ _mali_osk_free(job);
+}
+
+u32 mali_pp_job_get_pp_counter_src0(void)
+{
+ return pp_counter_src0;
+}
+
+mali_bool mali_pp_job_set_pp_counter_src0(u32 counter)
+{
+ pp_counter_src0 = counter;
+
+ return MALI_TRUE;
+}
+
+u32 mali_pp_job_get_pp_counter_src1(void)
+{
+ return pp_counter_src1;
+}
+
+mali_bool mali_pp_job_set_pp_counter_src1(u32 counter)
+{
+ pp_counter_src1 = counter;
+
+ return MALI_TRUE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h
new file mode 100644
index 0000000..2aed8cc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_job.h
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PP_JOB_H__
+#define __MALI_PP_JOB_H__
+
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_uk_types.h"
+#include "mali_session.h"
+#include "mali_kernel_common.h"
+#include "regs/mali_200_regs.h"
+#include "mali_kernel_core.h"
+#ifdef CONFIG_SYNC
+#include <linux/sync.h>
+#endif
+#include "mali_dlbu.h"
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+#include "linux/mali_dma_buf.h"
+#endif
+
+/**
+ * The structure represents a PP job, including all sub-jobs
+ * (This struct unfortunately needs to be public because of how the _mali_osk_list_*
+ * mechanism works)
+ */
+struct mali_pp_job
+{
+ _mali_osk_list_t list; /**< Used to link jobs together in the scheduler queue */
+ struct mali_session_data *session; /**< Session which submitted this job */
+ _mali_osk_list_t session_list; /**< Used to link jobs together in the session job list */
+ _mali_uk_pp_start_job_s uargs; /**< Arguments from user space */
+ u32 id; /**< Identifier for this job in kernel space (sequential numbering) */
+ u32 perf_counter_value0[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 0 (to be returned to user space), one for each sub job */
+ u32 perf_counter_value1[_MALI_PP_MAX_SUB_JOBS]; /**< Value of performance counter 1 (to be returned to user space), one for each sub job */
+ u32 sub_jobs_num; /**< Number of subjobs; set to 1 for Mali-450 if DLBU is used, otherwise equals number of PP cores */
+ u32 sub_jobs_started; /**< Total number of sub-jobs started (always started in ascending order) */
+ u32 sub_jobs_completed; /**< Number of completed sub-jobs in this superjob */
+ u32 sub_job_errors; /**< Bitfield with errors (errors for each single sub-job is or'ed together) */
+ u32 pid; /**< Process ID of submitting process */
+ u32 tid; /**< Thread ID of submitting thread */
+ _mali_osk_notification_t *finished_notification; /**< Notification sent back to userspace on job complete */
+ u32 num_memory_cookies; /**< Number of memory cookies attached to job */
+ u32 *memory_cookies; /**< Memory cookies attached to job */
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ struct mali_dma_buf_attachment **dma_bufs; /**< Array of DMA-bufs used by job */
+ u32 num_dma_bufs; /**< Number of DMA-bufs used by job */
+#endif
+#ifdef CONFIG_SYNC
+ mali_sync_pt *sync_point; /**< Sync point to signal on completion */
+ struct sync_fence_waiter sync_waiter; /**< Sync waiter for async wait */
+ _mali_osk_wq_work_t *sync_work; /**< Work to schedule in callback */
+ struct sync_fence *pre_fence; /**< Sync fence this job must wait for */
+#endif
+};
+
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *uargs, u32 id);
+void mali_pp_job_delete(struct mali_pp_job *job);
+
+u32 mali_pp_job_get_pp_counter_src0(void);
+mali_bool mali_pp_job_set_pp_counter_src0(u32 counter);
+u32 mali_pp_job_get_pp_counter_src1(void);
+mali_bool mali_pp_job_set_pp_counter_src1(u32 counter);
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_id(struct mali_pp_job *job)
+{
+ return (NULL == job) ? 0 : job->id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_user_id(struct mali_pp_job *job)
+{
+ return job->uargs.user_job_ptr;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job)
+{
+ return job->uargs.frame_builder_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job)
+{
+ return job->uargs.flush_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_pid(struct mali_pp_job *job)
+{
+ return job->pid;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_tid(struct mali_pp_job *job)
+{
+ return job->tid;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job)
+{
+ return job->uargs.frame_registers;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_dlbu_registers(struct mali_pp_job *job)
+{
+ return job->uargs.dlbu_registers;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_is_virtual(struct mali_pp_job *job)
+{
+ return 0 == job->uargs.num_cores;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job)
+{
+ if (mali_pp_job_is_virtual(job))
+ {
+ return MALI_DLBU_VIRT_ADDR;
+ }
+ else if (0 == sub_job)
+ {
+ return job->uargs.frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
+ }
+ else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
+ {
+ return job->uargs.frame_registers_addr_frame[sub_job - 1];
+ }
+
+ return 0;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_addr_stack(struct mali_pp_job *job, u32 sub_job)
+{
+ if (0 == sub_job)
+ {
+ return job->uargs.frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
+ }
+ else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
+ {
+ return job->uargs.frame_registers_addr_stack[sub_job - 1];
+ }
+
+ return 0;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_wb0_registers(struct mali_pp_job *job)
+{
+ return job->uargs.wb0_registers;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job)
+{
+ return job->uargs.wb1_registers;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job)
+{
+ return job->uargs.wb2_registers;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job)
+{
+ job->uargs.wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job)
+{
+ job->uargs.wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job)
+{
+ job->uargs.wb2_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+}
+
+MALI_STATIC_INLINE struct mali_session_data *mali_pp_job_get_session(struct mali_pp_job *job)
+{
+ return job->session;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_has_unstarted_sub_jobs(struct mali_pp_job *job)
+{
+ return (job->sub_jobs_started < job->sub_jobs_num) ? MALI_TRUE : MALI_FALSE;
+}
+
+/* Function used when we are terminating a session with jobs. Return TRUE if it has a rendering job.
+ Makes sure that no new subjobs are started. */
+MALI_STATIC_INLINE void mali_pp_job_mark_unstarted_failed(struct mali_pp_job *job)
+{
+ u32 jobs_remaining = job->sub_jobs_num - job->sub_jobs_started;
+ job->sub_jobs_started += jobs_remaining;
+ job->sub_jobs_completed += jobs_remaining;
+ job->sub_job_errors += jobs_remaining;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job)
+{
+ return (job->sub_jobs_num == job->sub_jobs_completed) ? MALI_TRUE : MALI_FALSE;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_first_unstarted_sub_job(struct mali_pp_job *job)
+{
+ return job->sub_jobs_started;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_sub_job_count(struct mali_pp_job *job)
+{
+ return job->sub_jobs_num;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_started(struct mali_pp_job *job, u32 sub_job)
+{
+ /* Assert that we are marking the "first unstarted sub job" as started */
+ MALI_DEBUG_ASSERT(job->sub_jobs_started == sub_job);
+ job->sub_jobs_started++;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_mark_sub_job_completed(struct mali_pp_job *job, mali_bool success)
+{
+ job->sub_jobs_completed++;
+ if ( MALI_FALSE == success )
+ {
+ job->sub_job_errors++;
+ }
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_was_success(struct mali_pp_job *job)
+{
+ if ( 0 == job->sub_job_errors )
+ {
+ return MALI_TRUE;
+ }
+ return MALI_FALSE;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_has_active_barrier(struct mali_pp_job *job)
+{
+ return job->uargs.flags & _MALI_PP_JOB_FLAG_BARRIER ? MALI_TRUE : MALI_FALSE;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_barrier_enforced(struct mali_pp_job *job)
+{
+ job->uargs.flags &= ~_MALI_PP_JOB_FLAG_BARRIER;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_use_no_notification(struct mali_pp_job *job)
+{
+ return job->uargs.flags & _MALI_PP_JOB_FLAG_NO_NOTIFICATION ? MALI_TRUE : MALI_FALSE;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
+{
+ return job->uargs.perf_counter_flag;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job)
+{
+ return job->uargs.perf_counter_src0;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job)
+{
+ return job->uargs.perf_counter_src1;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value0(struct mali_pp_job *job, u32 sub_job)
+{
+ return job->perf_counter_value0[sub_job];
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_value1(struct mali_pp_job *job, u32 sub_job)
+{
+ return job->perf_counter_value1[sub_job];
+}
+
+MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_src0(struct mali_pp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src0 = src;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_src1(struct mali_pp_job *job, u32 src)
+{
+ job->uargs.perf_counter_src1 = src;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value0(struct mali_pp_job *job, u32 sub_job, u32 value)
+{
+ job->perf_counter_value0[sub_job] = value;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_set_perf_counter_value1(struct mali_pp_job *job, u32 sub_job, u32 value)
+{
+ job->perf_counter_value1[sub_job] = value;
+}
+
+MALI_STATIC_INLINE _mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
+{
+ if (mali_pp_job_is_virtual(job) && job->sub_jobs_num != 1)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
+
+#endif /* __MALI_PP_JOB_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c
new file mode 100644
index 0000000..3f10bdc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.c
@@ -0,0 +1,1890 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_pp_scheduler.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_scheduler.h"
+#include "mali_pp.h"
+#include "mali_pp_job.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_kernel_utilization.h"
+#include "mali_session.h"
+#include "mali_pm_domain.h"
+#include "linux/mali/mali_utgard.h"
+
+#if defined(CONFIG_DMA_SHARED_BUFFER)
+#include "mali_dma_buf.h"
+#endif
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+#include <linux/sched.h>
+#include <trace/events/gpu.h>
+#endif
+
+
+/* With certain configurations, job deletion involves functions which cannot be called from atomic context.
+ * This #if checks for those cases and enables job deletion to be deferred and run in a different context. */
+#if defined(CONFIG_SYNC) || !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+#define MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE 1
+#endif
+
+/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
+#define MALI_MAX_NUMBER_OF_PP_GROUPS 9
+
+static mali_bool mali_pp_scheduler_is_suspended(void);
+static void mali_pp_scheduler_do_schedule(void *arg);
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+static void mali_pp_scheduler_do_job_delete(void *arg);
+#endif
+static void mali_pp_scheduler_job_queued(void);
+static void mali_pp_scheduler_job_completed(void);
+
+static u32 pp_version = 0;
+
+/* Physical job queue */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(job_queue); /* List of physical jobs with some unscheduled work */
+static u32 job_queue_depth = 0;
+
+/* Physical groups */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_working); /* List of physical groups with working jobs on the pp core */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_idle); /* List of physical groups with idle jobs on the pp core */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(group_list_disabled); /* List of disabled physical groups */
+
+/* Virtual job queue (Mali-450 only) */
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(virtual_job_queue); /* List of unstarted jobs for the virtual group */
+static u32 virtual_job_queue_depth = 0;
+
+/* Virtual group (Mali-450 only) */
+static struct mali_group *virtual_group = NULL; /* Virtual group (if any) */
+static enum
+{
+ VIRTUAL_GROUP_IDLE,
+ VIRTUAL_GROUP_WORKING,
+ VIRTUAL_GROUP_DISABLED,
+}
+virtual_group_state = VIRTUAL_GROUP_IDLE; /* Flag which indicates whether the virtual group is working or idle */
+
+/* Number of physical cores */
+static u32 num_cores = 0;
+static u32 enabled_cores = 0;
+
+/* Variables to allow safe pausing of the scheduler */
+static _mali_osk_wait_queue_t *pp_scheduler_working_wait_queue = NULL;
+static u32 pause_count = 0;
+
+static _mali_osk_lock_t *pp_scheduler_lock = NULL;
+/* Contains tid of thread that locked the scheduler or 0, if not locked */
+MALI_DEBUG_CODE(static u32 pp_scheduler_lock_owner = 0);
+
+static _mali_osk_wq_work_t *pp_scheduler_wq_schedule = NULL;
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+static _mali_osk_wq_work_t *pp_scheduler_wq_job_delete = NULL;
+static _mali_osk_lock_t *pp_scheduler_job_delete_lock = NULL;
+static _MALI_OSK_LIST_HEAD_STATIC_INIT(pp_scheduler_job_deletion_queue);
+#endif
+
+MALI_STATIC_INLINE mali_bool mali_pp_scheduler_has_virtual_group(void)
+{
+ return NULL != virtual_group;
+}
+
+_mali_osk_errcode_t mali_pp_scheduler_initialize(void)
+{
+ _mali_osk_lock_flags_t lock_flags;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#else
+ lock_flags = _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE;
+#endif
+
+ pp_scheduler_lock = _mali_osk_lock_init(lock_flags, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ if (NULL == pp_scheduler_lock)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ pp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
+ if (NULL == pp_scheduler_working_wait_queue)
+ {
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ pp_scheduler_wq_schedule = _mali_osk_wq_create_work(mali_pp_scheduler_do_schedule, NULL);
+ if (NULL == pp_scheduler_wq_schedule)
+ {
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ pp_scheduler_wq_job_delete = _mali_osk_wq_create_work(mali_pp_scheduler_do_job_delete, NULL);
+ if (NULL == pp_scheduler_wq_job_delete)
+ {
+ _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ pp_scheduler_job_delete_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER_DEFERRED);
+ if (NULL == pp_scheduler_job_delete_lock)
+ {
+ _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete);
+ _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+#endif
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pp_scheduler_terminate(void)
+{
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ _mali_osk_lock_term(pp_scheduler_job_delete_lock);
+ _mali_osk_wq_delete_work(pp_scheduler_wq_job_delete);
+#endif
+
+ _mali_osk_wq_delete_work(pp_scheduler_wq_schedule);
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+}
+
+void mali_pp_scheduler_populate(void)
+{
+ struct mali_group *group;
+ struct mali_pp_core *pp_core;
+ u32 num_groups;
+ u32 i;
+
+ num_groups = mali_group_get_glob_num_groups();
+
+ /* Do we have a virtual group? */
+ for (i = 0; i < num_groups; i++)
+ {
+ group = mali_group_get_glob_group(i);
+
+ if (mali_group_is_virtual(group))
+ {
+ MALI_DEBUG_PRINT(3, ("Found virtual group %p\n", group));
+
+ virtual_group = group;
+ break;
+ }
+ }
+
+ /* Find all the available PP cores */
+ for (i = 0; i < num_groups; i++)
+ {
+ group = mali_group_get_glob_group(i);
+ pp_core = mali_group_get_pp_core(group);
+
+ if (NULL != pp_core && !mali_group_is_virtual(group))
+ {
+ if (0 == pp_version)
+ {
+ /* Retrieve PP version from the first available PP core */
+ pp_version = mali_pp_core_get_version(pp_core);
+ }
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ /* Add all physical PP cores to the virtual group */
+ mali_group_lock(virtual_group);
+ group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
+ mali_group_add_group(virtual_group, group, MALI_TRUE);
+ mali_group_unlock(virtual_group);
+ }
+ else
+ {
+ _mali_osk_list_add(&group->pp_scheduler_list, &group_list_idle);
+ }
+
+ num_cores++;
+ }
+ }
+ enabled_cores = num_cores;
+}
+
+void mali_pp_scheduler_depopulate(void)
+{
+ struct mali_group *group, *temp;
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_WORKING != virtual_group_state);
+
+ /* Delete all groups owned by scheduler */
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_delete(virtual_group);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ mali_group_delete(group);
+ }
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_disabled, struct mali_group, pp_scheduler_list)
+ {
+ mali_group_delete(group);
+ }
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_lock(void)
+{
+ if(_MALI_OSK_ERR_OK != _mali_osk_lock_wait(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW))
+ {
+ /* Non-interruptable lock failed: this should never happen. */
+ MALI_DEBUG_ASSERT(0);
+ }
+ MALI_DEBUG_PRINT(5, ("Mali PP scheduler: PP scheduler lock taken\n"));
+ MALI_DEBUG_ASSERT(0 == pp_scheduler_lock_owner);
+ MALI_DEBUG_CODE(pp_scheduler_lock_owner = _mali_osk_get_tid());
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_unlock(void)
+{
+ MALI_DEBUG_PRINT(5, ("Mali PP scheduler: Releasing PP scheduler lock\n"));
+ MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
+ MALI_DEBUG_CODE(pp_scheduler_lock_owner = 0);
+ _mali_osk_lock_signal(pp_scheduler_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_disable_empty_virtual(void)
+{
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+
+ if (mali_group_virtual_disable_if_empty(virtual_group))
+ {
+ MALI_DEBUG_PRINT(4, ("Disabling empty virtual group\n"));
+
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_IDLE == virtual_group_state);
+
+ virtual_group_state = VIRTUAL_GROUP_DISABLED;
+ }
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_enable_empty_virtual(void)
+{
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+
+ if (mali_group_virtual_enable_if_empty(virtual_group))
+ {
+ MALI_DEBUG_PRINT(4, ("Re-enabling empty virtual group\n"));
+
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_DISABLED == virtual_group_state);
+
+ virtual_group_state = VIRTUAL_GROUP_IDLE;
+ }
+}
+
+#ifdef DEBUG
+MALI_STATIC_INLINE void mali_pp_scheduler_assert_locked(void)
+{
+ MALI_DEBUG_ASSERT(_mali_osk_get_tid() == pp_scheduler_lock_owner);
+}
+#define MALI_ASSERT_PP_SCHEDULER_LOCKED() mali_pp_scheduler_assert_locked()
+#else
+#define MALI_ASSERT_PP_SCHEDULER_LOCKED()
+#endif
+
+/**
+ * Returns a physical job if a physical job is ready to run (no barrier present)
+ */
+MALI_STATIC_INLINE struct mali_pp_job *mali_pp_scheduler_get_physical_job(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+
+ if (!_mali_osk_list_empty(&job_queue))
+ {
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT(job_queue_depth > 0);
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
+
+ if (!mali_pp_job_has_active_barrier(job))
+ {
+ return job;
+ }
+ }
+
+ return NULL;
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_dequeue_physical_job(struct mali_pp_job *job)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT(job_queue_depth > 0);
+
+ /* Remove job from queue */
+ if (!mali_pp_job_has_unstarted_sub_jobs(job))
+ {
+ /* All sub jobs have been started: remove job from queue */
+ _mali_osk_list_delinit(&job->list);
+ }
+
+ --job_queue_depth;
+}
+
+/**
+ * Returns a virtual job if a virtual job is ready to run (no barrier present)
+ */
+MALI_STATIC_INLINE struct mali_pp_job *mali_pp_scheduler_get_virtual_job(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT_POINTER(virtual_group);
+
+ if (!_mali_osk_list_empty(&virtual_job_queue))
+ {
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT(virtual_job_queue_depth > 0);
+ job = _MALI_OSK_LIST_ENTRY(virtual_job_queue.next, struct mali_pp_job, list);
+
+ if (!mali_pp_job_has_active_barrier(job))
+ {
+ return job;
+ }
+ }
+
+ return NULL;
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_dequeue_virtual_job(struct mali_pp_job *job)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT(virtual_job_queue_depth > 0);
+
+ /* Remove job from queue */
+ _mali_osk_list_delinit(&job->list);
+ --virtual_job_queue_depth;
+}
+
+/**
+ * Checks if the criteria is met for removing a physical core from virtual group
+ */
+MALI_STATIC_INLINE mali_bool mali_pp_scheduler_can_move_virtual_to_physical(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+ MALI_DEBUG_ASSERT(mali_pp_scheduler_has_virtual_group());
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+ /*
+ * The criteria for taking out a physical group from a virtual group are the following:
+ * - There virtual group is idle
+ * - There are currently no physical groups (idle and working)
+ * - There are physical jobs to be scheduled (without a barrier)
+ */
+ return (VIRTUAL_GROUP_IDLE == virtual_group_state) &&
+ _mali_osk_list_empty(&group_list_idle) &&
+ _mali_osk_list_empty(&group_list_working) &&
+ (NULL != mali_pp_scheduler_get_physical_job());
+}
+
+MALI_STATIC_INLINE struct mali_group *mali_pp_scheduler_acquire_physical_group(void)
+{
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+
+ if (!_mali_osk_list_empty(&group_list_idle))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquiring physical group from idle list\n"));
+ return _MALI_OSK_LIST_ENTRY(group_list_idle.next, struct mali_group, pp_scheduler_list);
+ }
+ else if (mali_pp_scheduler_has_virtual_group())
+ {
+ MALI_ASSERT_GROUP_LOCKED(virtual_group);
+ if (mali_pp_scheduler_can_move_virtual_to_physical())
+ {
+ struct mali_group *group;
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquiring physical group from virtual group\n"));
+ group = mali_group_acquire_group(virtual_group);
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_pp_scheduler_disable_empty_virtual();
+ }
+
+ return group;
+ }
+ }
+
+ return NULL;
+}
+
+static void mali_pp_scheduler_schedule(void)
+{
+ struct mali_group* physical_groups_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
+ struct mali_pp_job* physical_jobs_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
+ u32 physical_subjobs_to_start[MALI_MAX_NUMBER_OF_PP_GROUPS-1];
+ int num_physical_jobs_to_start = 0;
+ int i;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ /* Need to lock the virtual group because we might need to grab a physical group from it */
+ mali_group_lock(virtual_group);
+ }
+
+ mali_pp_scheduler_lock();
+ if (pause_count > 0)
+ {
+ /* Scheduler is suspended, don't schedule any jobs */
+ mali_pp_scheduler_unlock();
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_unlock(virtual_group);
+ }
+ return;
+ }
+
+ /* Find physical job(s) to schedule first */
+ while (1)
+ {
+ struct mali_group *group;
+ struct mali_pp_job *job;
+ u32 subjob;
+
+ job = mali_pp_scheduler_get_physical_job();
+ if (NULL == job)
+ {
+ break; /* No job, early out */
+ }
+
+ MALI_DEBUG_ASSERT(!mali_pp_job_is_virtual(job));
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+ MALI_DEBUG_ASSERT(1 <= mali_pp_job_get_sub_job_count(job));
+
+ /* Acquire a physical group, either from the idle list or from the virtual group.
+ * In case the group was acquired from the virtual group, it's state will be
+ * LEAVING_VIRTUAL and must be set to IDLE before it can be used. */
+ group = mali_pp_scheduler_acquire_physical_group();
+ if (NULL == group)
+ {
+ /* Could not get a group to run the job on, early out */
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: No more physical groups available.\n"));
+ break;
+ }
+
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Acquired physical group %p\n", group));
+
+ /* Mark subjob as started */
+ subjob = mali_pp_job_get_first_unstarted_sub_job(job);
+ mali_pp_job_mark_sub_job_started(job, subjob);
+
+ /* Remove job from queue (if we now got the last subjob) */
+ mali_pp_scheduler_dequeue_physical_job(job);
+
+ /* Move group to working list */
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_working);
+
+ /* Keep track of this group, so that we actually can start the job once we are done with the scheduler lock we are now holding */
+ physical_groups_to_start[num_physical_jobs_to_start] = group;
+ physical_jobs_to_start[num_physical_jobs_to_start] = job;
+ physical_subjobs_to_start[num_physical_jobs_to_start] = subjob;
+ ++num_physical_jobs_to_start;
+
+ MALI_DEBUG_ASSERT(num_physical_jobs_to_start < MALI_MAX_NUMBER_OF_PP_GROUPS);
+ }
+
+ /* See if we have a virtual job to schedule */
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ if (VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ struct mali_pp_job *job = mali_pp_scheduler_get_virtual_job();
+ if (NULL != job)
+ {
+ MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+ MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
+
+ /* Mark the one and only subjob as started */
+ mali_pp_job_mark_sub_job_started(job, 0);
+
+ /* Remove job from queue */
+ mali_pp_scheduler_dequeue_virtual_job(job);
+
+ /* Virtual group is now working */
+ virtual_group_state = VIRTUAL_GROUP_WORKING;
+
+ /*
+ * We no longer need the scheduler lock,
+ * but we still need the virtual lock in order to start the virtual job
+ */
+ mali_pp_scheduler_unlock();
+
+ /* Start job */
+ mali_group_start_pp_job(virtual_group, job, 0);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Virtual job %u (0x%08X) part %u/%u started (from schedule)\n",
+ mali_pp_job_get_id(job), job, 1,
+ mali_pp_job_get_sub_job_count(job)));
+
+ /* And now we are all done with the virtual_group lock as well */
+ mali_group_unlock(virtual_group);
+ }
+ else
+ {
+ /* No virtual job, release the two locks we are holding */
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(virtual_group);
+ }
+ }
+ else
+ {
+ /* Virtual core busy, release the two locks we are holding */
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(virtual_group);
+ }
+
+ }
+ else
+ {
+ /* There is no virtual group, release the only lock we are holding */
+ mali_pp_scheduler_unlock();
+ }
+
+ /*
+ * Now we have released the scheduler lock, and we are ready to kick of the actual starting of the
+ * physical jobs.
+ * The reason we want to wait until we have released the scheduler lock is that job start actually
+ * may take quite a bit of time (quite many registers needs to be written). This will allow new jobs
+ * from user space to come in, and post processing of other PP jobs to happen at the same time as we
+ * start jobs.
+ */
+ for (i = 0; i < num_physical_jobs_to_start; i++)
+ {
+ struct mali_group *group = physical_groups_to_start[i];
+ struct mali_pp_job *job = physical_jobs_to_start[i];
+ u32 sub_job = physical_subjobs_to_start[i];
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+ mali_group_lock(group);
+
+ /* In case this group was acquired from a virtual core, update it's state to IDLE */
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ mali_group_start_pp_job(group, job, sub_job);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from schedule)\n",
+ mali_pp_job_get_id(job), job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(job)));
+
+ mali_group_unlock(group);
+
+ /* remove the return value from mali_group_start_xx_job, since we can't fail on Mali-300++ */
+ }
+}
+
+static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job, mali_bool deferred)
+{
+ if (MALI_FALSE == mali_pp_job_use_no_notification(job))
+ {
+ u32 i;
+ u32 num_counters_to_copy;
+ mali_bool success = mali_pp_job_was_success(job);
+
+ _mali_uk_pp_job_finished_s *jobres = job->finished_notification->result_buffer;
+ _mali_osk_memset(jobres, 0, sizeof(_mali_uk_pp_job_finished_s)); /* @@@@ can be removed once we initialize all members in this struct */
+ jobres->user_job_ptr = mali_pp_job_get_user_id(job);
+ if (MALI_TRUE == success)
+ {
+ jobres->status = _MALI_UK_JOB_STATUS_END_SUCCESS;
+ }
+ else
+ {
+ jobres->status = _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR;
+ }
+
+ if (mali_pp_job_is_virtual(job))
+ {
+ num_counters_to_copy = num_cores; /* Number of physical cores available */
+ }
+ else
+ {
+ num_counters_to_copy = mali_pp_job_get_sub_job_count(job);
+ }
+
+ for (i = 0; i < num_counters_to_copy; i++)
+ {
+ jobres->perf_counter0[i] = mali_pp_job_get_perf_counter_value0(job, i);
+ jobres->perf_counter1[i] = mali_pp_job_get_perf_counter_value1(job, i);
+ }
+
+ mali_session_send_notification(mali_pp_job_get_session(job), job->finished_notification);
+ job->finished_notification = NULL;
+ }
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ if (MALI_TRUE == deferred)
+ {
+ /* The deletion of the job object (releasing sync refs etc) must be done in a different context */
+ _mali_osk_lock_wait(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&job->list)); /* This job object should not be on any list */
+ _mali_osk_list_addtail(&job->list, &pp_scheduler_job_deletion_queue);
+
+ _mali_osk_lock_signal(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_wq_schedule_work(pp_scheduler_wq_job_delete);
+ }
+ else
+ {
+ mali_pp_job_delete(job);
+ }
+#else
+ MALI_DEBUG_ASSERT(MALI_FALSE == deferred); /* no use cases need this in this configuration */
+ mali_pp_job_delete(job);
+#endif
+}
+
+static void mali_pp_scheduler_do_schedule(void *arg)
+{
+ MALI_IGNORE(arg);
+
+ mali_pp_scheduler_schedule();
+}
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+static void mali_pp_scheduler_do_job_delete(void *arg)
+{
+ _MALI_OSK_LIST_HEAD_STATIC_INIT(list);
+ struct mali_pp_job *job;
+ struct mali_pp_job *tmp;
+
+ MALI_IGNORE(arg);
+
+ _mali_osk_lock_wait(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /*
+ * Quickly "unhook" the jobs pending to be deleted, so we can release the lock before
+ * we start deleting the job objects (without any locks held
+ */
+ _mali_osk_list_move_list(&pp_scheduler_job_deletion_queue, &list);
+
+ _mali_osk_lock_signal(pp_scheduler_job_delete_lock, _MALI_OSK_LOCKMODE_RW);
+
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &list, struct mali_pp_job, list)
+ {
+ mali_pp_job_delete(job); /* delete the job object itself */
+ }
+}
+#endif
+
+void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
+{
+ mali_bool job_is_done;
+ mali_bool barrier_enforced = MALI_FALSE;
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: %s job %u (0x%08X) part %u/%u completed (%s)\n",
+ mali_pp_job_is_virtual(job) ? "Virtual" : "Physical",
+ mali_pp_job_get_id(job),
+ job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(job),
+ success ? "success" : "failure"));
+ MALI_ASSERT_GROUP_LOCKED(group);
+ mali_pp_scheduler_lock();
+
+ mali_pp_job_mark_sub_job_completed(job, success);
+
+ MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job) == mali_group_is_virtual(group));
+
+ job_is_done = mali_pp_job_is_complete(job);
+
+ if (job_is_done)
+ {
+ struct mali_session_data *session = mali_pp_job_get_session(job);
+ struct mali_pp_job *job_head;
+
+ /* Remove job from session list */
+ _mali_osk_list_del(&job->session_list);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for %s job %u (0x%08X)\n",
+ mali_pp_job_is_virtual(job) ? "virtual" : "physical",
+ mali_pp_job_get_id(job), job));
+#if defined(CONFIG_SYNC)
+ if (job->sync_point)
+ {
+ int error;
+ if (success) error = 0;
+ else error = -EFAULT;
+ MALI_DEBUG_PRINT(4, ("Sync: Signal %spoint for job %d\n",
+ success ? "" : "failed ",
+ mali_pp_job_get_id(job)));
+ mali_sync_signal_pt(job->sync_point, error);
+ }
+#endif
+
+ /* Send notification back to user space */
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ mali_pp_scheduler_return_job_to_user(job, MALI_TRUE);
+#else
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE);
+#endif
+
+ mali_pp_scheduler_job_completed();
+
+ /* Resolve any barriers */
+ if (!_mali_osk_list_empty(&session->job_list))
+ {
+ job_head = _MALI_OSK_LIST_ENTRY(session->job_list.next, struct mali_pp_job, session_list);
+ if (mali_pp_job_has_active_barrier(job_head))
+ {
+ barrier_enforced = MALI_TRUE;
+ mali_pp_job_barrier_enforced(job_head);
+ }
+ }
+ }
+
+ /* If paused, then this was the last job, so wake up sleeping workers */
+ if (pause_count > 0)
+ {
+ /* Wake up sleeping workers. Their wake-up condition is that
+ * num_slots == num_slots_idle, so unless we are done working, no
+ * threads will actually be woken up.
+ */
+ if (mali_group_is_virtual(group))
+ {
+ virtual_group_state = VIRTUAL_GROUP_IDLE;
+ }
+ else
+ {
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
+ }
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_pp_get_hw_core_desc(group->pp_core), sched_clock(), 0, 0, 0);
+#endif
+ _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
+ mali_pp_scheduler_unlock();
+ return;
+ }
+
+ if (barrier_enforced)
+ {
+ /* A barrier was resolved, so schedule previously blocked jobs */
+ _mali_osk_wq_schedule_work(pp_scheduler_wq_schedule);
+ }
+
+ /* Recycle variables */
+ job = NULL;
+ sub_job = 0;
+
+ if (mali_group_is_virtual(group))
+ {
+ /* Virtual group */
+
+ /* Now that the virtual group is idle, check if we should reconfigure */
+ struct mali_pp_job *physical_job = NULL;
+ struct mali_group *physical_group = NULL;
+
+ /* Obey the policy */
+ virtual_group_state = VIRTUAL_GROUP_IDLE;
+
+ if (mali_pp_scheduler_can_move_virtual_to_physical())
+ {
+ /* There is a runnable physical job and we can acquire a physical group */
+ physical_job = mali_pp_scheduler_get_physical_job();
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(physical_job));
+
+ /* Mark subjob as started */
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(physical_job);
+ mali_pp_job_mark_sub_job_started(physical_job, sub_job);
+
+ /* Remove job from queue (if we now got the last subjob) */
+ mali_pp_scheduler_dequeue_physical_job(physical_job);
+
+ /* Acquire a physical group from the virtual group
+ * It's state will be LEAVING_VIRTUAL and must be set to IDLE before it can be used */
+ physical_group = mali_group_acquire_group(virtual_group);
+
+ /* Move physical group to the working list, as we will soon start a job on it */
+ _mali_osk_list_move(&(physical_group->pp_scheduler_list), &group_list_working);
+
+ mali_pp_scheduler_disable_empty_virtual();
+ }
+
+ /* Start the next virtual job */
+ job = mali_pp_scheduler_get_virtual_job();
+ if (NULL != job && VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ /* There is a runnable virtual job */
+ MALI_DEBUG_ASSERT(mali_pp_job_is_virtual(job));
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+ MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
+
+ mali_pp_job_mark_sub_job_started(job, 0);
+
+ /* Remove job from queue */
+ mali_pp_scheduler_dequeue_virtual_job(job);
+
+ /* Virtual group is now working */
+ virtual_group_state = VIRTUAL_GROUP_WORKING;
+
+ mali_pp_scheduler_unlock();
+
+ /* Start job */
+ mali_group_start_pp_job(group, job, 0);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Virtual job %u (0x%08X) part %u/%u started (from job_done)\n",
+ mali_pp_job_get_id(job), job, 1,
+ mali_pp_job_get_sub_job_count(job)));
+ }
+ else
+ {
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch("Mali_Virtual_PP", sched_clock(), 0, 0, 0);
+#endif
+ mali_pp_scheduler_unlock();
+ }
+
+ /* Start a physical job (if we acquired a physical group earlier) */
+ if (NULL != physical_job && NULL != physical_group)
+ {
+ mali_group_lock(physical_group);
+
+ /* Set the group state from LEAVING_VIRTUAL to IDLE to complete the transition */
+ physical_group->state = MALI_GROUP_STATE_IDLE;
+
+ /* Start job on core */
+ mali_group_start_pp_job(physical_group, physical_job, sub_job);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from job_done)\n",
+ mali_pp_job_get_id(physical_job), physical_job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(physical_job)));
+
+ mali_group_unlock(physical_group);
+ }
+ }
+ else
+ {
+ /* Physical group */
+ job = mali_pp_scheduler_get_physical_job();
+ if (NULL != job)
+ {
+ /* There is a runnable physical job */
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job));
+
+ /* Mark subjob as started */
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
+ mali_pp_job_mark_sub_job_started(job, sub_job);
+
+ /* Remove job from queue (if we now got the last subjob) */
+ mali_pp_scheduler_dequeue_physical_job(job);
+
+ mali_pp_scheduler_unlock();
+
+ /* Group is already on the working list, so start the job */
+ mali_group_start_pp_job(group, job, sub_job);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Physical job %u (0x%08X) part %u/%u started (from job_done)\n",
+ mali_pp_job_get_id(job), job, sub_job + 1,
+ mali_pp_job_get_sub_job_count(job)));
+ }
+ else if (mali_pp_scheduler_has_virtual_group())
+ {
+ /* Rejoin virtual group */
+ /* In the future, a policy check might be useful here */
+
+ /* We're no longer needed on the scheduler list */
+ _mali_osk_list_delinit(&(group->pp_scheduler_list));
+
+ /* Make sure no interrupts are handled for this group during
+ * the transition from physical to virtual */
+ group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
+
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+
+ mali_group_lock(virtual_group);
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_pp_scheduler_enable_empty_virtual();
+ }
+
+ /* We need to recheck the group state since it is possible that someone has
+ * modified the group before we locked the virtual group. */
+ if (MALI_GROUP_STATE_JOINING_VIRTUAL == group->state)
+ {
+ mali_group_add_group(virtual_group, group, MALI_TRUE);
+ }
+
+ mali_group_unlock(virtual_group);
+
+ if (mali_pp_scheduler_has_virtual_group() && VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ _mali_osk_wq_schedule_work(pp_scheduler_wq_schedule);
+ }
+
+ /* We need to return from this function with the group lock held */
+ mali_group_lock(group);
+ }
+ else
+ {
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_sched_switch(mali_pp_get_hw_core_desc(group->pp_core), sched_clock(), 0, 0, 0);
+#endif
+ mali_pp_scheduler_unlock();
+ }
+ }
+}
+
+void mali_pp_scheduler_suspend(void)
+{
+ mali_pp_scheduler_lock();
+ pause_count++; /* Increment the pause_count so that no more jobs will be scheduled */
+ mali_pp_scheduler_unlock();
+
+ /* Go to sleep. When woken up again (in mali_pp_scheduler_job_done), the
+ * mali_pp_scheduler_suspended() function will be called. This will return true
+ * iff state is idle and pause_count > 0, so if the core is active this
+ * will not do anything.
+ */
+ _mali_osk_wait_queue_wait_event(pp_scheduler_working_wait_queue, mali_pp_scheduler_is_suspended);
+}
+
+void mali_pp_scheduler_resume(void)
+{
+ mali_pp_scheduler_lock();
+ pause_count--; /* Decrement pause_count to allow scheduling again (if it reaches 0) */
+ mali_pp_scheduler_unlock();
+ if (0 == pause_count)
+ {
+ mali_pp_scheduler_schedule();
+ }
+}
+
+MALI_STATIC_INLINE void mali_pp_scheduler_queue_job(struct mali_pp_job *job, struct mali_session_data *session)
+{
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
+ trace_gpu_job_enqueue(mali_pp_job_get_tid(job), mali_pp_job_get_id(job), "PP");
+#endif
+
+#if defined(CONFIG_DMA_SHARED_BUFFER) && !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* Map buffers attached to job */
+ if (0 != job->num_memory_cookies)
+ {
+ mali_dma_buf_map_job(job);
+ }
+#endif /* CONFIG_DMA_SHARED_BUFFER */
+
+ mali_pp_scheduler_job_queued();
+
+ mali_pp_scheduler_lock();
+
+ if (mali_pp_job_is_virtual(job))
+ {
+ /* Virtual job */
+ virtual_job_queue_depth += 1;
+ _mali_osk_list_addtail(&job->list, &virtual_job_queue);
+ }
+ else
+ {
+ job_queue_depth += mali_pp_job_get_sub_job_count(job);
+ _mali_osk_list_addtail(&job->list, &job_queue);
+ }
+
+ if (mali_pp_job_has_active_barrier(job) && _mali_osk_list_empty(&session->job_list))
+ {
+ /* No running jobs on this session, so barrier condition already met */
+ mali_pp_job_barrier_enforced(job);
+ }
+
+ /* Add job to session list */
+ _mali_osk_list_addtail(&job->session_list, &session->job_list);
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: %s job %u (0x%08X) with %u parts queued\n",
+ mali_pp_job_is_virtual(job) ? "Virtual" : "Physical",
+ mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
+
+ mali_pp_scheduler_unlock();
+}
+
+#if defined(CONFIG_SYNC)
+static void sync_callback(struct sync_fence *fence, struct sync_fence_waiter *waiter)
+{
+ struct mali_pp_job *job = _MALI_OSK_CONTAINER_OF(waiter, struct mali_pp_job, sync_waiter);
+
+ /* Schedule sync_callback_work */
+ _mali_osk_wq_schedule_work(job->sync_work);
+}
+
+static void sync_callback_work(void *arg)
+{
+ struct mali_pp_job *job = (struct mali_pp_job *)arg;
+ struct mali_session_data *session;
+ int err;
+
+ MALI_DEBUG_ASSERT_POINTER(job);
+
+ session = job->session;
+
+ /* Remove job from session pending job list */
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_delinit(&job->list);
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+
+ err = sync_fence_wait(job->pre_fence, 0);
+ if (likely(0 == err))
+ {
+ MALI_DEBUG_PRINT(3, ("Mali sync: Job %d ready to run\n", mali_pp_job_get_id(job)));
+
+ mali_pp_scheduler_queue_job(job, session);
+
+ mali_pp_scheduler_schedule();
+ }
+ else
+ {
+ /* Fence signaled error */
+ MALI_DEBUG_PRINT(3, ("Mali sync: Job %d abort due to sync error\n", mali_pp_job_get_id(job)));
+
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, err);
+
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ }
+}
+#endif
+
+_mali_osk_errcode_t _mali_ukk_pp_start_job(void *ctx, _mali_uk_pp_start_job_s *uargs, int *fence)
+{
+ struct mali_session_data *session;
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT_POINTER(uargs);
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+
+ session = (struct mali_session_data*)ctx;
+
+ job = mali_pp_job_create(session, uargs, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ MALI_PRINT_ERROR(("Failed to create job!\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_pp_job_check(job))
+ {
+ /* Not a valid job, return to user immediately */
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+#if PROFILING_SKIP_PP_JOBS || PROFILING_SKIP_PP_AND_GP_JOBS
+#warning PP jobs will not be executed
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE);
+ return _MALI_OSK_ERR_OK;
+#endif
+
+#if defined(CONFIG_SYNC)
+ if (_MALI_PP_JOB_FLAG_FENCE & job->uargs.flags)
+ {
+ int post_fence = -1;
+
+ job->sync_point = mali_stream_create_point(job->uargs.stream);
+
+ if (unlikely(NULL == job->sync_point))
+ {
+ /* Fence creation failed. */
+ MALI_DEBUG_PRINT(2, ("Failed to create sync point for job %d\n", mali_pp_job_get_id(job)));
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ post_fence = mali_stream_create_fence(job->sync_point);
+
+ if (unlikely(0 > post_fence))
+ {
+ /* Fence creation failed. */
+ /* mali_stream_create_fence already freed the sync_point */
+ MALI_DEBUG_PRINT(2, ("Failed to create fence for job %d\n", mali_pp_job_get_id(job)));
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ /* Grab a reference to the fence. It must be around when the
+ * job is completed, so the point can be signalled. */
+ sync_fence_fdget(post_fence);
+
+ *fence = post_fence;
+
+ MALI_DEBUG_PRINT(3, ("Sync: Created fence %d for job %d\n", post_fence, mali_pp_job_get_id(job)));
+ }
+ else if (_MALI_PP_JOB_FLAG_EMPTY_FENCE & job->uargs.flags)
+ {
+ int empty_fence_fd = job->uargs.stream;
+ struct sync_fence *empty_fence;
+ struct sync_pt *pt;
+ int ret;
+
+ /* Grab and keep a reference to the fence. It must be around
+ * when the job is completed, so the point can be signalled. */
+ empty_fence = sync_fence_fdget(empty_fence_fd);
+
+ if (unlikely(NULL == empty_fence))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to accept empty fence: %d\n", empty_fence_fd));
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK;
+ }
+
+ if (unlikely(list_empty(&empty_fence->pt_list_head)))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to accept empty fence: %d\n", empty_fence_fd));
+ sync_fence_put(empty_fence);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK;
+ }
+
+ pt = list_first_entry(&empty_fence->pt_list_head, struct sync_pt, pt_list);
+
+ ret = mali_sync_timed_commit(pt);
+
+ if (unlikely(0 != ret))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Empty fence not valid: %d\n", empty_fence_fd));
+ sync_fence_put(empty_fence);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK;
+ }
+
+ job->sync_point = pt;
+
+ *fence = empty_fence_fd;
+
+ MALI_DEBUG_PRINT(3, ("Sync: Job %d now backs fence %d\n", mali_pp_job_get_id(job), empty_fence_fd));
+ }
+
+ if (0 < job->uargs.fence)
+ {
+ int pre_fence_fd = job->uargs.fence;
+ int err;
+
+ MALI_DEBUG_PRINT(3, ("Sync: Job %d waiting for fence %d\n", mali_pp_job_get_id(job), pre_fence_fd));
+
+ job->pre_fence = sync_fence_fdget(pre_fence_fd); /* Reference will be released when job is deleted. */
+ if (NULL == job->pre_fence)
+ {
+ MALI_DEBUG_PRINT(2, ("Failed to import fence %d\n", pre_fence_fd));
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, -EINVAL);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ job->sync_work = _mali_osk_wq_create_work(sync_callback_work, (void*)job);
+ if (NULL == job->sync_work)
+ {
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, -ENOMEM);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ /* Add pending job to session pending job list */
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_addtail(&job->list, &session->pending_jobs);
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+
+ sync_fence_waiter_init(&job->sync_waiter, sync_callback);
+ err = sync_fence_wait_async(job->pre_fence, &job->sync_waiter);
+
+ if (0 != err)
+ {
+ /* No async wait started, remove job from session pending job list */
+ _mali_osk_lock_wait(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_delinit(&job->list);
+ _mali_osk_lock_signal(session->pending_jobs_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+
+ if (1 == err)
+ {
+ /* Fence has already signalled */
+ mali_pp_scheduler_queue_job(job, session);
+ if (!_mali_osk_list_empty(&group_list_idle) || VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ mali_pp_scheduler_schedule();
+ }
+ return _MALI_OSK_ERR_OK;
+ }
+ else if (0 > err)
+ {
+ /* Sync fail */
+ if (job->sync_point) mali_sync_signal_pt(job->sync_point, err);
+ mali_pp_job_mark_sub_job_completed(job, MALI_FALSE); /* Flagging the job as failed. */
+ mali_pp_scheduler_return_job_to_user(job, MALI_FALSE); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ }
+ else
+#endif /* CONFIG_SYNC */
+ {
+ mali_pp_scheduler_queue_job(job, session);
+
+ if (!_mali_osk_list_empty(&group_list_idle) || VIRTUAL_GROUP_IDLE == virtual_group_state)
+ {
+ mali_pp_scheduler_schedule();
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores(_mali_uk_get_pp_number_of_cores_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+ args->number_of_total_cores = num_cores;
+ args->number_of_enabled_cores = enabled_cores;
+ return _MALI_OSK_ERR_OK;
+}
+
+u32 mali_pp_scheduler_get_num_cores_total(void)
+{
+ return num_cores;
+}
+
+u32 mali_pp_scheduler_get_num_cores_enabled(void)
+{
+ return enabled_cores;
+}
+
+_mali_osk_errcode_t _mali_ukk_get_pp_core_version(_mali_uk_get_pp_core_version_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+ args->version = pp_version;
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args)
+{
+ struct mali_session_data *session;
+ struct mali_pp_job *job;
+ struct mali_pp_job *tmp;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+
+ session = (struct mali_session_data*)args->ctx;
+
+ /* Check queue for jobs that match */
+ mali_pp_scheduler_lock();
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp, &job_queue, struct mali_pp_job, list)
+ {
+ if (mali_pp_job_get_session(job) == session &&
+ mali_pp_job_get_frame_builder_id(job) == (u32)args->fb_id &&
+ mali_pp_job_get_flush_id(job) == (u32)args->flush_id)
+ {
+ if (args->wbx & _MALI_UK_PP_JOB_WB0)
+ {
+ mali_pp_job_disable_wb0(job);
+ }
+ if (args->wbx & _MALI_UK_PP_JOB_WB1)
+ {
+ mali_pp_job_disable_wb1(job);
+ }
+ if (args->wbx & _MALI_UK_PP_JOB_WB2)
+ {
+ mali_pp_job_disable_wb2(job);
+ }
+ break;
+ }
+ }
+ mali_pp_scheduler_unlock();
+}
+
+void mali_pp_scheduler_abort_session(struct mali_session_data *session)
+{
+ struct mali_pp_job *job, *tmp_job;
+ struct mali_group *group, *tmp_group;
+ struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
+ s32 i = 0;
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ _MALI_OSK_LIST_HEAD_STATIC_INIT(deferred_deletion_list);
+#endif
+
+ mali_pp_scheduler_lock();
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Aborting all jobs from session 0x%08x\n", session));
+
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp_job, &session->job_list, struct mali_pp_job, session_list)
+ {
+ /* Remove job from queue (if it's not queued, list_del has no effect) */
+ _mali_osk_list_delinit(&job->list);
+
+ if (mali_pp_job_is_virtual(job))
+ {
+ MALI_DEBUG_ASSERT(1 == mali_pp_job_get_sub_job_count(job));
+ if (0 == mali_pp_job_get_first_unstarted_sub_job(job))
+ {
+ --virtual_job_queue_depth;
+ }
+ }
+ else
+ {
+ job_queue_depth -= mali_pp_job_get_sub_job_count(job) - mali_pp_job_get_first_unstarted_sub_job(job);
+ }
+
+ /* Mark all unstarted jobs as failed */
+ mali_pp_job_mark_unstarted_failed(job);
+
+ if (mali_pp_job_is_complete(job))
+ {
+ _mali_osk_list_del(&job->session_list);
+
+ /* It is safe to delete the job, since it won't land in job_done() */
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborted PP job 0x%08x\n", job));
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&job->list));
+ _mali_osk_list_addtail(&job->list, &deferred_deletion_list);
+#else
+ mali_pp_job_delete(job);
+#endif
+
+ mali_pp_scheduler_job_completed();
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in session\n", job));
+ }
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_working, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, tmp_group, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+
+ mali_pp_scheduler_unlock();
+
+#if defined(MALI_PP_SCHEDULER_USE_DEFERRED_JOB_DELETE)
+ _MALI_OSK_LIST_FOREACHENTRY(job, tmp_job, &deferred_deletion_list, struct mali_pp_job, list)
+ {
+ mali_pp_job_delete(job);
+ }
+#endif
+
+ /* Abort running jobs from this session */
+ while (i > 0)
+ {
+ mali_group_abort_session(groups[--i], session);
+ }
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_abort_session(virtual_group, session);
+ }
+}
+
+static mali_bool mali_pp_scheduler_is_suspended(void)
+{
+ mali_bool ret;
+
+ mali_pp_scheduler_lock();
+
+ ret = pause_count > 0
+ && _mali_osk_list_empty(&group_list_working)
+ && VIRTUAL_GROUP_WORKING != virtual_group_state;
+
+ mali_pp_scheduler_unlock();
+
+ return ret;
+}
+
+int mali_pp_scheduler_get_queue_depth(void)
+{
+ return job_queue_depth;
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
+{
+ int n = 0;
+ struct mali_group *group;
+ struct mali_group *temp;
+
+ n += _mali_osk_snprintf(buf + n, size - n, "PP:\n");
+ n += _mali_osk_snprintf(buf + n, size - n, "\tQueue is %s\n", _mali_osk_list_empty(&job_queue) ? "empty" : "not empty");
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_working, struct mali_group, pp_scheduler_list)
+ {
+ n += mali_group_dump_state(group, buf + n, size - n);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ n += mali_group_dump_state(group, buf + n, size - n);
+ }
+
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_disabled, struct mali_group, pp_scheduler_list)
+ {
+ n += mali_group_dump_state(group, buf + n, size - n);
+ }
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ n += mali_group_dump_state(virtual_group, buf + n, size -n);
+ }
+
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+ return n;
+}
+#endif
+
+/* This function is intended for power on reset of all cores.
+ * No locking is done for the list iteration, which can only be safe if the
+ * scheduler is paused and all cores idle. That is always the case on init and
+ * power on. */
+void mali_pp_scheduler_reset_all_groups(void)
+{
+ struct mali_group *group, *temp;
+ struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
+ s32 i = 0;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_lock(virtual_group);
+ mali_group_reset(virtual_group);
+ mali_group_unlock(virtual_group);
+ }
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_WORKING != virtual_group_state);
+ mali_pp_scheduler_lock();
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_idle, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+ mali_pp_scheduler_unlock();
+
+ while (i > 0)
+ {
+ group = groups[--i];
+
+ mali_group_lock(group);
+ mali_group_reset(group);
+ mali_group_unlock(group);
+ }
+}
+
+void mali_pp_scheduler_zap_all_active(struct mali_session_data *session)
+{
+ struct mali_group *group, *temp;
+ struct mali_group *groups[MALI_MAX_NUMBER_OF_GROUPS];
+ s32 i = 0;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_zap_session(virtual_group, session);
+ }
+
+ mali_pp_scheduler_lock();
+ _MALI_OSK_LIST_FOREACHENTRY(group, temp, &group_list_working, struct mali_group, pp_scheduler_list)
+ {
+ groups[i++] = group;
+ }
+ mali_pp_scheduler_unlock();
+
+ while (i > 0)
+ {
+ mali_group_zap_session(groups[--i], session);
+ }
+}
+
+/* A pm reference must be taken with _mali_osk_pm_dev_ref_add_no_power_on
+ * before calling this function to avoid Mali powering down as HW is accessed.
+ */
+static void mali_pp_scheduler_enable_group_internal(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ mali_group_lock(group);
+
+ if (MALI_GROUP_STATE_DISABLED != group->state)
+ {
+ mali_group_unlock(group);
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: PP group %p already enabled\n", group));
+ return;
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Enabling PP group %p\n", group));
+
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+ ++enabled_cores;
+
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_bool update_hw;
+
+ /* Add group to virtual group */
+ _mali_osk_list_delinit(&(group->pp_scheduler_list));
+ group->state = MALI_GROUP_STATE_JOINING_VIRTUAL;
+
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+
+ mali_group_lock(virtual_group);
+
+ update_hw = mali_pm_is_power_on();
+
+ mali_pm_domain_ref_get(group->pm_domain);
+ MALI_DEBUG_ASSERT(NULL == group->pm_domain ||
+ MALI_PM_DOMAIN_ON == mali_pm_domain_state_get(group->pm_domain));
+
+ if (update_hw)
+ {
+ mali_group_lock(group);
+ mali_group_power_on_group(group);
+ mali_group_reset(group);
+ mali_group_unlock(group);
+ }
+
+ mali_pp_scheduler_enable_empty_virtual();
+ mali_group_add_group(virtual_group, group, update_hw);
+ MALI_DEBUG_PRINT(4, ("Done enabling group %p. Added to virtual group.\n", group));
+
+ mali_group_unlock(virtual_group);
+ }
+ else
+ {
+ mali_pm_domain_ref_get(group->pm_domain);
+ MALI_DEBUG_ASSERT(NULL == group->pm_domain ||
+ MALI_PM_DOMAIN_ON == mali_pm_domain_state_get(group->pm_domain));
+
+ /* Put group on idle list */
+ if (mali_pm_is_power_on())
+ {
+ mali_group_power_on_group(group);
+ mali_group_reset(group);
+ }
+
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_idle);
+ group->state = MALI_GROUP_STATE_IDLE;
+
+ MALI_DEBUG_PRINT(4, ("Done enabling group %p. Now on idle list.\n", group));
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+ }
+}
+
+void mali_pp_scheduler_enable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+
+ mali_pp_scheduler_enable_group_internal(group);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ /* Pick up any jobs that might have been queued if all PP groups were disabled. */
+ mali_pp_scheduler_schedule();
+}
+
+static void mali_pp_scheduler_disable_group_internal(struct mali_group *group)
+{
+ if (mali_pp_scheduler_has_virtual_group())
+ {
+ mali_group_lock(virtual_group);
+
+ MALI_DEBUG_ASSERT(VIRTUAL_GROUP_WORKING != virtual_group_state);
+ if (MALI_GROUP_STATE_JOINING_VIRTUAL == group->state)
+ {
+ /* The group was in the process of being added to the virtual group. We
+ * only need to change the state to reverse this. */
+ group->state = MALI_GROUP_STATE_LEAVING_VIRTUAL;
+ }
+ else if (MALI_GROUP_STATE_IN_VIRTUAL == group->state)
+ {
+ /* Remove group from virtual group. The state of the group will be
+ * LEAVING_VIRTUAL and the group will not be on any scheduler list. */
+ mali_group_remove_group(virtual_group, group);
+
+ mali_pp_scheduler_disable_empty_virtual();
+ }
+
+ mali_group_unlock(virtual_group);
+ }
+
+ mali_group_lock(group);
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ if (MALI_GROUP_STATE_DISABLED == group->state)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: PP group %p already disabled\n", group));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Disabling PP group %p\n", group));
+
+ --enabled_cores;
+ _mali_osk_list_move(&(group->pp_scheduler_list), &group_list_disabled);
+ group->state = MALI_GROUP_STATE_DISABLED;
+
+ mali_group_power_off_group(group);
+ mali_pm_domain_ref_put(group->pm_domain);
+ }
+
+ mali_pp_scheduler_unlock();
+ mali_group_unlock(group);
+}
+
+void mali_pp_scheduler_disable_group(struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ mali_pp_scheduler_suspend();
+ _mali_osk_pm_dev_ref_add_no_power_on();
+
+ mali_pp_scheduler_disable_group_internal(group);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+ mali_pp_scheduler_resume();
+}
+
+
+static void mali_pp_scheduler_notify_core_change(u32 num_cores)
+{
+ if (!mali_is_mali450())
+ {
+ /* Notify all user space sessions about the change, so number of master tile lists can be adapter */
+ struct mali_session_data *session, *tmp;
+
+ mali_session_lock();
+ MALI_SESSION_FOREACH(session, tmp, link)
+ {
+ _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_NUM_CORE_CHANGE, sizeof(_mali_uk_pp_num_cores_changed_s));
+ if (NULL != notobj)
+ {
+ _mali_uk_pp_num_cores_changed_s *data = notobj->result_buffer;
+ data->number_of_enabled_cores = num_cores;
+ mali_session_send_notification(session, notobj);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to notify user space session about num PP core change\n"));
+ }
+ }
+ mali_session_unlock();
+ }
+}
+
+static void mali_pp_scheduler_set_perf_level_mali400(u32 target_core_nr)
+{
+ struct mali_group *group;
+ MALI_DEBUG_ASSERT(mali_is_mali400());
+
+ if (target_core_nr > enabled_cores)
+ {
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: enabling %d cores\n", target_core_nr, target_core_nr - enabled_cores));
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ _mali_osk_pm_dev_barrier();
+
+ while (target_core_nr > enabled_cores)
+ {
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&group_list_disabled));
+
+ group = _MALI_OSK_LIST_ENTRY(group_list_disabled.next, struct mali_group, pp_scheduler_list);
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_STATE_DISABLED == group->state);
+
+ mali_pp_scheduler_unlock();
+
+ mali_pp_scheduler_enable_group_internal(group);
+ }
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ mali_pp_scheduler_schedule();
+ }
+ else if (target_core_nr < enabled_cores)
+ {
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: disabling %d cores\n", target_core_nr, enabled_cores - target_core_nr));
+
+ mali_pp_scheduler_suspend();
+
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+
+ while (target_core_nr < enabled_cores)
+ {
+ mali_pp_scheduler_lock();
+
+ MALI_DEBUG_ASSERT(!_mali_osk_list_empty(&group_list_idle));
+ MALI_DEBUG_ASSERT(_mali_osk_list_empty(&group_list_working));
+
+ group = _MALI_OSK_LIST_ENTRY(group_list_idle.next, struct mali_group, pp_scheduler_list);
+
+ MALI_DEBUG_ASSERT_POINTER(group);
+ MALI_DEBUG_ASSERT( MALI_GROUP_STATE_IDLE == group->state
+ || MALI_GROUP_STATE_LEAVING_VIRTUAL == group->state
+ || MALI_GROUP_STATE_DISABLED == group->state);
+
+ mali_pp_scheduler_unlock();
+
+ mali_pp_scheduler_disable_group_internal(group);
+ }
+
+ mali_pp_scheduler_resume();
+ }
+
+ mali_pp_scheduler_notify_core_change(target_core_nr);
+}
+
+static void mali_pp_scheduler_set_perf_level_mali450(u32 target_core_nr)
+{
+ struct mali_group *group;
+ MALI_DEBUG_ASSERT(mali_is_mali450());
+
+ if (target_core_nr > enabled_cores)
+ {
+ /* Enable some cores */
+ struct mali_pm_domain *domain;
+
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: enabling %d cores\n", target_core_nr, target_core_nr - enabled_cores));
+
+ _mali_osk_pm_dev_ref_add_no_power_on();
+ _mali_osk_pm_dev_barrier();
+
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM2);
+
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_enable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+
+ if (target_core_nr > enabled_cores)
+ {
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM3);
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_enable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+ }
+
+ MALI_DEBUG_ASSERT(target_core_nr == enabled_cores);
+
+ _mali_osk_pm_dev_ref_dec_no_power_on();
+
+ mali_pp_scheduler_schedule();
+ }
+ else if (target_core_nr < enabled_cores)
+ {
+ /* Disable some cores */
+ struct mali_pm_domain *domain;
+
+ MALI_DEBUG_PRINT(2, ("Requesting %d cores: disabling %d cores\n", target_core_nr, enabled_cores - target_core_nr));
+
+ mali_pp_scheduler_suspend();
+
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM3);
+ if (NULL != domain)
+ {
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_disable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+ }
+
+ if (target_core_nr < enabled_cores)
+ {
+ domain = mali_pm_domain_get(MALI_PMU_M450_DOM2);
+ MALI_DEBUG_ASSERT_POINTER(domain);
+ MALI_PM_DOMAIN_FOR_EACH_GROUP(group, domain)
+ {
+ mali_pp_scheduler_disable_group_internal(group);
+ if (target_core_nr == enabled_cores) break;
+ }
+ }
+
+ MALI_DEBUG_ASSERT(target_core_nr == enabled_cores);
+
+ mali_pp_scheduler_resume();
+ }
+}
+
+int mali_pp_scheduler_set_perf_level(unsigned int cores)
+{
+ if (cores == enabled_cores) return 0;
+ if (cores > num_cores) return -EINVAL;
+ if (0 == cores) return -EINVAL;
+
+ if (!mali_pp_scheduler_has_virtual_group())
+ {
+ /* Mali-400 */
+ mali_pp_scheduler_set_perf_level_mali400(cores);
+ }
+ else
+ {
+ /* Mali-450 */
+ mali_pp_scheduler_set_perf_level_mali450(cores);
+ }
+
+ return 0;
+}
+
+static void mali_pp_scheduler_job_queued(void)
+{
+ /* We hold a PM reference for every job we hold queued (and running) */
+ _mali_osk_pm_dev_ref_add();
+
+ if (mali_utilization_enabled())
+ {
+ /*
+ * We cheat a little bit by counting the PP as busy from the time a PP job is queued.
+ * This will be fine because we only loose the tiny idle gap between jobs, but
+ * we will instead get less utilization work to do (less locks taken)
+ */
+ mali_utilization_pp_start();
+ }
+}
+
+static void mali_pp_scheduler_job_completed(void)
+{
+ /* Release the PM reference we got in the mali_pp_scheduler_job_queued() function */
+ _mali_osk_pm_dev_ref_dec();
+
+ if (mali_utilization_enabled())
+ {
+ mali_utilization_pp_end();
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h
new file mode 100644
index 0000000..71ec042
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_pp_scheduler.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PP_SCHEDULER_H__
+#define __MALI_PP_SCHEDULER_H__
+
+#include "mali_osk.h"
+#include "mali_pp_job.h"
+#include "mali_group.h"
+#include "linux/mali/mali_utgard.h"
+
+/** Initalize the HW independent parts of the PP scheduler
+ */
+_mali_osk_errcode_t mali_pp_scheduler_initialize(void);
+void mali_pp_scheduler_terminate(void);
+
+/** Poplulate the PP scheduler with groups
+ */
+void mali_pp_scheduler_populate(void);
+void mali_pp_scheduler_depopulate(void);
+
+void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success);
+
+void mali_pp_scheduler_suspend(void);
+void mali_pp_scheduler_resume(void);
+
+/** @brief Abort all PP jobs from session running or queued
+ *
+ * This functions aborts all PP jobs from the specified session. Queued jobs are removed from the queue and jobs
+ * currently running on a core will be aborted.
+ *
+ * @param session Pointer to session whose jobs should be aborted
+ */
+void mali_pp_scheduler_abort_session(struct mali_session_data *session);
+
+/**
+ * @brief Reset all groups
+ *
+ * This function resets all groups known by the PP scheuduler. This must be
+ * called after the Mali HW has been powered on in order to reset the HW.
+ *
+ * This function is intended for power on reset of all cores.
+ * No locking is done, which can only be safe if the scheduler is paused and
+ * all cores idle. That is always the case on init and power on.
+ */
+void mali_pp_scheduler_reset_all_groups(void);
+
+/**
+ * @brief Zap TLB on all groups with \a session active
+ *
+ * The scheculer will zap the session on all groups it owns.
+ */
+void mali_pp_scheduler_zap_all_active(struct mali_session_data *session);
+
+int mali_pp_scheduler_get_queue_depth(void);
+u32 mali_pp_scheduler_dump_state(char *buf, u32 size);
+
+void mali_pp_scheduler_enable_group(struct mali_group *group);
+void mali_pp_scheduler_disable_group(struct mali_group *group);
+
+int mali_pp_scheduler_set_perf_level(u32 cores);
+
+u32 mali_pp_scheduler_get_num_cores_total(void);
+u32 mali_pp_scheduler_get_num_cores_enabled(void);
+
+/**
+ * @brief Returns the number of Pixel Processors in the system irrespective of the context
+ *
+ * @return number of physical Pixel Processor cores in the system
+ */
+u32 mali_pp_scheduler_get_num_cores_total(void);
+
+#endif /* __MALI_PP_SCHEDULER_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c
new file mode 100644
index 0000000..f360209
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+
+static _mali_osk_atomic_t mali_job_autonumber;
+
+_mali_osk_errcode_t mali_scheduler_initialize(void)
+{
+ if ( _MALI_OSK_ERR_OK != _mali_osk_atomic_init(&mali_job_autonumber, 0))
+ {
+ MALI_DEBUG_PRINT(1, ("Initialization of atomic job id counter failed.\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_scheduler_terminate(void)
+{
+ _mali_osk_atomic_term(&mali_job_autonumber);
+}
+
+u32 mali_scheduler_get_new_id(void)
+{
+ u32 job_id = _mali_osk_atomic_inc_return(&mali_job_autonumber);
+ return job_id;
+}
+
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h
new file mode 100644
index 0000000..63e5be8
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_scheduler.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_SCHEDULER_H__
+#define __MALI_SCHEDULER_H__
+
+#include "mali_osk.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+
+_mali_osk_errcode_t mali_scheduler_initialize(void);
+void mali_scheduler_terminate(void);
+
+u32 mali_scheduler_get_new_id(void);
+
+/**
+ * @brief Reset all groups
+ *
+ * This function resets all groups known by the both the PP and GP scheuduler.
+ * This must be called after the Mali HW has been powered on in order to reset
+ * the HW.
+ */
+MALI_STATIC_INLINE void mali_scheduler_reset_all_groups(void)
+{
+ mali_gp_scheduler_reset_all_groups();
+ mali_pp_scheduler_reset_all_groups();
+}
+
+/**
+ * @brief Zap TLB on all active groups running \a session
+ *
+ * @param session Pointer to the session to zap
+ */
+MALI_STATIC_INLINE void mali_scheduler_zap_all_active(struct mali_session_data *session)
+{
+ mali_gp_scheduler_zap_all_active(session);
+ mali_pp_scheduler_zap_all_active(session);
+}
+
+#endif /* __MALI_SCHEDULER_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_session.c b/drivers/gpu/mali400/r3p2/mali/common/mali_session.c
new file mode 100644
index 0000000..2394bb9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_session.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "mali_session.h"
+
+_MALI_OSK_LIST_HEAD(mali_sessions);
+
+_mali_osk_lock_t *mali_sessions_lock;
+
+_mali_osk_errcode_t mali_session_initialize(void)
+{
+ _MALI_OSK_INIT_LIST_HEAD(&mali_sessions);
+
+ mali_sessions_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED, 0, _MALI_OSK_LOCK_ORDER_SESSIONS);
+
+ if (NULL == mali_sessions_lock) return _MALI_OSK_ERR_NOMEM;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_session_terminate(void)
+{
+ _mali_osk_lock_term(mali_sessions_lock);
+}
+
+void mali_session_add(struct mali_session_data *session)
+{
+ mali_session_lock();
+ _mali_osk_list_add(&session->link, &mali_sessions);
+ mali_session_unlock();
+}
+
+void mali_session_remove(struct mali_session_data *session)
+{
+ mali_session_lock();
+ _mali_osk_list_delinit(&session->link);
+ mali_session_unlock();
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_session.h b/drivers/gpu/mali400/r3p2/mali/common/mali_session.h
new file mode 100644
index 0000000..5c34dde
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_session.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_SESSION_H__
+#define __MALI_SESSION_H__
+
+#include "mali_mmu_page_directory.h"
+#include "mali_kernel_descriptor_mapping.h"
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+
+struct mali_session_data
+{
+ _mali_osk_notification_queue_t * ioctl_queue;
+
+#ifdef CONFIG_SYNC
+ _mali_osk_list_t pending_jobs;
+ _mali_osk_lock_t *pending_jobs_lock;
+#endif
+
+ _mali_osk_lock_t *memory_lock; /**< Lock protecting the vm manipulation */
+ mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
+ _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */
+
+ struct mali_page_directory *page_directory; /**< MMU page directory for this session */
+
+ _MALI_OSK_LIST_HEAD(link); /**< Link for list of all sessions */
+
+ _MALI_OSK_LIST_HEAD(job_list); /**< List of all jobs on this session */
+};
+
+_mali_osk_errcode_t mali_session_initialize(void);
+void mali_session_terminate(void);
+
+/* List of all sessions. Actual list head in mali_kernel_core.c */
+extern _mali_osk_list_t mali_sessions;
+/* Lock to protect modification and access to the mali_sessions list */
+extern _mali_osk_lock_t *mali_sessions_lock;
+
+MALI_STATIC_INLINE void mali_session_lock(void)
+{
+ _mali_osk_lock_wait(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+MALI_STATIC_INLINE void mali_session_unlock(void)
+{
+ _mali_osk_lock_signal(mali_sessions_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+void mali_session_add(struct mali_session_data *session);
+void mali_session_remove(struct mali_session_data *session);
+#define MALI_SESSION_FOREACH(session, tmp, link) \
+ _MALI_OSK_LIST_FOREACHENTRY(session, tmp, &mali_sessions, struct mali_session_data, link)
+
+MALI_STATIC_INLINE struct mali_page_directory *mali_session_get_page_directory(struct mali_session_data *session)
+{
+ return session->page_directory;
+}
+
+MALI_STATIC_INLINE void mali_session_send_notification(struct mali_session_data *session, _mali_osk_notification_t *object)
+{
+ _mali_osk_notification_queue_send(session->ioctl_queue, object);
+}
+
+#endif /* __MALI_SESSION_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h b/drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h
new file mode 100644
index 0000000..1f8a320
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_ukk.h
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_ukk.h
+ * Defines the kernel-side interface of the user-kernel interface
+ */
+
+#ifndef __MALI_UKK_H__
+#define __MALI_UKK_H__
+
+#include "mali_osk.h"
+#include "mali_uk_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @addtogroup uddapi Unified Device Driver (UDD) APIs
+ *
+ * @{
+ */
+
+/**
+ * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs
+ *
+ * - The _mali_uk functions are an abstraction of the interface to the device
+ * driver. On certain OSs, this would be implemented via the IOCTL interface.
+ * On other OSs, it could be via extension of some Device Driver Class, or
+ * direct function call for Bare metal/RTOSs.
+ * - It is important to note that:
+ * - The Device Driver has implemented the _mali_ukk set of functions
+ * - The Base Driver calls the corresponding set of _mali_uku functions.
+ * - What requires porting is solely the calling mechanism from User-side to
+ * Kernel-side, and propagating back the results.
+ * - Each U/K function is associated with a (group, number) pair from
+ * \ref _mali_uk_functions to make it possible for a common function in the
+ * Base Driver and Device Driver to route User/Kernel calls from/to the
+ * correct _mali_uk function. For example, in an IOCTL system, the IOCTL number
+ * would be formed based on the group and number assigned to the _mali_uk
+ * function, as listed in \ref _mali_uk_functions. On the user-side, each
+ * _mali_uku function would just make an IOCTL with the IOCTL-code being an
+ * encoded form of the (group, number) pair. On the kernel-side, the Device
+ * Driver's IOCTL handler decodes the IOCTL-code back into a (group, number)
+ * pair, and uses this to determine which corresponding _mali_ukk should be
+ * called.
+ * - Refer to \ref _mali_uk_functions for more information about this
+ * (group, number) pairing.
+ * - In a system where there is no distinction between user and kernel-side,
+ * the U/K interface may be implemented as:@code
+ * MALI_STATIC_INLINE _mali_osk_errcode_t _mali_uku_examplefunction( _mali_uk_examplefunction_s *args )
+ * {
+ * return mali_ukk_examplefunction( args );
+ * }
+ * @endcode
+ * - Therefore, all U/K calls behave \em as \em though they were direct
+ * function calls (but the \b implementation \em need \em not be a direct
+ * function calls)
+ *
+ * @note Naming the _mali_uk functions the same on both User and Kernel sides
+ * on non-RTOS systems causes debugging issues when setting breakpoints. In
+ * this case, it is not clear which function the breakpoint is put on.
+ * Therefore the _mali_uk functions in user space are prefixed with \c _mali_uku
+ * and in kernel space with \c _mali_ukk. The naming for the argument
+ * structures is unaffected.
+ *
+ * - The _mali_uk functions are synchronous.
+ * - Arguments to the _mali_uk functions are passed in a structure. The only
+ * parameter passed to the _mali_uk functions is a pointer to this structure.
+ * This first member of this structure, ctx, is a pointer to a context returned
+ * by _mali_uku_open(). For example:@code
+ * typedef struct
+ * {
+ * void *ctx;
+ * u32 number_of_cores;
+ * } _mali_uk_get_gp_number_of_cores_s;
+ * @endcode
+ *
+ * - Each _mali_uk function has its own argument structure named after the
+ * function. The argument is distinguished by the _s suffix.
+ * - The argument types are defined by the base driver and user-kernel
+ * interface.
+ * - All _mali_uk functions return a standard \ref _mali_osk_errcode_t.
+ * - Only arguments of type input or input/output need be initialized before
+ * calling a _mali_uk function.
+ * - Arguments of type output and input/output are only valid when the
+ * _mali_uk function returns \ref _MALI_OSK_ERR_OK.
+ * - The \c ctx member is always invalid after it has been used by a
+ * _mali_uk function, except for the context management functions
+ *
+ *
+ * \b Interface \b restrictions
+ *
+ * The requirements of the interface mean that an implementation of the
+ * User-kernel interface may do no 'real' work. For example, the following are
+ * illegal in the User-kernel implementation:
+ * - Calling functions necessary for operation on all systems, which would
+ * not otherwise get called on RTOS systems.
+ * - For example, a U/K interface that calls multiple _mali_ukk functions
+ * during one particular U/K call. This could not be achieved by the same code
+ * which uses direct function calls for the U/K interface.
+ * - Writing in values to the args members, when otherwise these members would
+ * not hold a useful value for a direct function call U/K interface.
+ * - For example, U/K interface implementation that take NULL members in
+ * their arguments structure from the user side, but those members are
+ * replaced with non-NULL values in the kernel-side of the U/K interface
+ * implementation. A scratch area for writing data is one such example. In this
+ * case, a direct function call U/K interface would segfault, because no code
+ * would be present to replace the NULL pointer with a meaningful pointer.
+ * - Note that we discourage the case where the U/K implementation changes
+ * a NULL argument member to non-NULL, and then the Device Driver code (outside
+ * of the U/K layer) re-checks this member for NULL, and corrects it when
+ * necessary. Whilst such code works even on direct function call U/K
+ * intefaces, it reduces the testing coverage of the Device Driver code. This
+ * is because we have no way of testing the NULL == value path on an OS
+ * implementation.
+ *
+ * A number of allowable examples exist where U/K interfaces do 'real' work:
+ * - The 'pointer switching' technique for \ref _mali_ukk_get_system_info
+ * - In this case, without the pointer switching on direct function call
+ * U/K interface, the Device Driver code still sees the same thing: a pointer
+ * to which it can write memory. This is because such a system has no
+ * distinction between a user and kernel pointer.
+ * - Writing an OS-specific value into the ukk_private member for
+ * _mali_ukk_mem_mmap().
+ * - In this case, this value is passed around by Device Driver code, but
+ * its actual value is never checked. Device Driver code simply passes it from
+ * the U/K layer to the OSK layer, where it can be acted upon. In this case,
+ * \em some OS implementations of the U/K (_mali_ukk_mem_mmap()) and OSK
+ * (_mali_osk_mem_mapregion_init()) functions will collaborate on the
+ * meaning of ukk_private member. On other OSs, it may be unused by both
+ * U/K and OSK layers
+ * - Therefore, on error inside the U/K interface implementation itself,
+ * it will be as though the _mali_ukk function itself had failed, and cleaned
+ * up after itself.
+ * - Compare this to a direct function call U/K implementation, where all
+ * error cleanup is handled by the _mali_ukk function itself. The direct
+ * function call U/K interface implementation is automatically atomic.
+ *
+ * The last example highlights a consequence of all U/K interface
+ * implementations: they must be atomic with respect to the Device Driver code.
+ * And therefore, should Device Driver code succeed but the U/K implementation
+ * fail afterwards (but before return to user-space), then the U/K
+ * implementation must cause appropriate cleanup actions to preserve the
+ * atomicity of the interface.
+ *
+ * @{
+ */
+
+
+/** @defgroup _mali_uk_context U/K Context management
+ *
+ * These functions allow for initialisation of the user-kernel interface once per process.
+ *
+ * Generally the context will store the OS specific object to communicate with the kernel device driver and further
+ * state information required by the specific implementation. The context is shareable among all threads in the caller process.
+ *
+ * On IOCTL systems, this is likely to be a file descriptor as a result of opening the kernel device driver.
+ *
+ * On a bare-metal/RTOS system with no distinction between kernel and
+ * user-space, the U/K interface simply calls the _mali_ukk variant of the
+ * function by direct function call. In this case, the context returned is the
+ * mali_session_data from _mali_ukk_open().
+ *
+ * The kernel side implementations of the U/K interface expect the first member of the argument structure to
+ * be the context created by _mali_uku_open(). On some OS implementations, the meaning of this context
+ * will be different between user-side and kernel-side. In which case, the kernel-side will need to replace this context
+ * with the kernel-side equivalent, because user-side will not have access to kernel-side data. The context parameter
+ * in the argument structure therefore has to be of type input/output.
+ *
+ * It should be noted that the caller cannot reuse the \c ctx member of U/K
+ * argument structure after a U/K call, because it may be overwritten. Instead,
+ * the context handle must always be stored elsewhere, and copied into
+ * the appropriate U/K argument structure for each user-side call to
+ * the U/K interface. This is not usually a problem, since U/K argument
+ * structures are usually placed on the stack.
+ *
+ * @{ */
+
+/** @brief Begin a new Mali Device Driver session
+ *
+ * This is used to obtain a per-process context handle for all future U/K calls.
+ *
+ * @param context pointer to storage to return a (void*)context handle.
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_open( void **context );
+
+/** @brief End a Mali Device Driver session
+ *
+ * This should be called when the process no longer requires use of the Mali Device Driver.
+ *
+ * The context handle must not be used after it has been closed.
+ *
+ * @param context pointer to a stored (void*)context handle.
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_close( void **context );
+
+/** @} */ /* end group _mali_uk_context */
+
+
+/** @addtogroup _mali_uk_core U/K Core
+ *
+ * The core functions provide the following functionality:
+ * - verify that the user and kernel API are compatible
+ * - retrieve information about the cores and memory banks in the system
+ * - wait for the result of jobs started on a core
+ *
+ * @{ */
+
+/** @brief Waits for a job notification.
+ *
+ * Sleeps until notified or a timeout occurs. Returns information about the notification.
+ *
+ * @param args see _mali_uk_wait_for_notification_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_wait_for_notification( _mali_uk_wait_for_notification_s *args );
+
+/** @brief Post a notification to the notification queue of this application.
+ *
+ * @param args see _mali_uk_post_notification_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *args );
+
+/** @brief Verifies if the user and kernel side of this API are compatible.
+ *
+ * @param args see _mali_uk_get_api_version_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args );
+
+/** @brief Get the user space settings applicable for calling process.
+ *
+ * @param args see _mali_uk_get_user_settings_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args);
+
+/** @brief Get a user space setting applicable for calling process.
+ *
+ * @param args see _mali_uk_get_user_setting_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args);
+
+/** @} */ /* end group _mali_uk_core */
+
+
+/** @addtogroup _mali_uk_memory U/K Memory
+ *
+ * The memory functions provide functionality with and without a Mali-MMU present.
+ *
+ * For Mali-MMU based systems, the following functionality is provided:
+ * - Initialize and terminate MALI virtual address space
+ * - Allocate/deallocate physical memory to a MALI virtual address range and map into/unmap from the
+ * current process address space
+ * - Map/unmap external physical memory into the MALI virtual address range
+ *
+ * For Mali-nonMMU based systems:
+ * - Allocate/deallocate MALI memory
+ *
+ * @{ */
+
+/**
+ * @brief Initialize the Mali-MMU Memory system
+ *
+ * For Mali-MMU builds of the drivers, this function must be called before any
+ * other functions in the \ref _mali_uk_memory group are called.
+ *
+ * @note This function is for Mali-MMU builds \b only. It should not be called
+ * when the drivers are built without Mali-MMU support.
+ *
+ * @param args see \ref _mali_uk_init_mem_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable
+ * _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args );
+
+/**
+ * @brief Terminate the MMU Memory system
+ *
+ * For Mali-MMU builds of the drivers, this function must be called when
+ * functions in the \ref _mali_uk_memory group will no longer be called. This
+ * function must be called before the application terminates.
+ *
+ * @note This function is for Mali-MMU builds \b only. It should not be called
+ * when the drivers are built without Mali-MMU support.
+ *
+ * @param args see \ref _mali_uk_term_mem_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable
+ * _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args );
+
+/** @brief Map Mali Memory into the current user process
+ *
+ * Maps Mali memory into the current user process in a generic way.
+ *
+ * This function is to be used for Mali-MMU mode. The function is available in both Mali-MMU and Mali-nonMMU modes,
+ * but should not be called by a user process in Mali-nonMMU mode.
+ *
+ * The implementation and operation of _mali_ukk_mem_mmap() is dependant on whether the driver is built for Mali-MMU
+ * or Mali-nonMMU:
+ * - In the nonMMU case, _mali_ukk_mem_mmap() requires a physical address to be specified. For this reason, an OS U/K
+ * implementation should not allow this to be called from user-space. In any case, nonMMU implementations are
+ * inherently insecure, and so the overall impact is minimal. Mali-MMU mode should be used if security is desired.
+ * - In the MMU case, _mali_ukk_mem_mmap() the _mali_uk_mem_mmap_s::phys_addr
+ * member is used for the \em Mali-virtual address desired for the mapping. The
+ * implementation of _mali_ukk_mem_mmap() will allocate both the CPU-virtual
+ * and CPU-physical addresses, and can cope with mapping a contiguous virtual
+ * address range to a sequence of non-contiguous physical pages. In this case,
+ * the CPU-physical addresses are not communicated back to the user-side, as
+ * they are unnecsessary; the \em Mali-virtual address range must be used for
+ * programming Mali structures.
+ *
+ * In the second (MMU) case, _mali_ukk_mem_mmap() handles management of
+ * CPU-virtual and CPU-physical ranges, but the \em caller must manage the
+ * \em Mali-virtual address range from the user-side.
+ *
+ * @note Mali-virtual address ranges are entirely separate between processes.
+ * It is not possible for a process to accidentally corrupt another process'
+ * \em Mali-virtual address space.
+ *
+ * @param args see _mali_uk_mem_mmap_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args );
+
+/** @brief Unmap Mali Memory from the current user process
+ *
+ * Unmaps Mali memory from the current user process in a generic way. This only operates on Mali memory supplied
+ * from _mali_ukk_mem_mmap().
+ *
+ * @param args see _mali_uk_mem_munmap_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args );
+
+/** @brief Determine the buffer size necessary for an MMU page table dump.
+ * @param args see _mali_uk_query_mmu_page_table_dump_size_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args );
+/** @brief Dump MMU Page tables.
+ * @param args see _mali_uk_dump_mmu_page_table_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args );
+
+/** @brief Write user data to specified Mali memory without causing segfaults.
+ * @param args see _mali_uk_mem_write_safe_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_mem_write_safe( _mali_uk_mem_write_safe_s *args );
+
+/** @brief Map a physically contiguous range of memory into Mali
+ * @param args see _mali_uk_map_external_mem_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args );
+
+/** @brief Unmap a physically contiguous range of memory from Mali
+ * @param args see _mali_uk_unmap_external_mem_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args );
+
+#if defined(CONFIG_MALI400_UMP)
+/** @brief Map UMP memory into Mali
+ * @param args see _mali_uk_attach_ump_mem_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_attach_ump_mem( _mali_uk_attach_ump_mem_s *args );
+/** @brief Unmap UMP memory from Mali
+ * @param args see _mali_uk_release_ump_mem_s in mali_utgard_uk_types.h
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args );
+#endif /* CONFIG_MALI400_UMP */
+
+/** @brief Determine virtual-to-physical mapping of a contiguous memory range
+ * (optional)
+ *
+ * This allows the user-side to do a virtual-to-physical address translation.
+ * In conjunction with _mali_uku_map_external_mem, this can be used to do
+ * direct rendering.
+ *
+ * This function will only succeed on a virtual range that is mapped into the
+ * current process, and that is contigious.
+ *
+ * If va is not page-aligned, then it is rounded down to the next page
+ * boundary. The remainer is added to size, such that ((u32)va)+size before
+ * rounding is equal to ((u32)va)+size after rounding. The rounded modified
+ * va and size will be written out into args on success.
+ *
+ * If the supplied size is zero, or not a multiple of the system's PAGE_SIZE,
+ * then size will be rounded up to the next multiple of PAGE_SIZE before
+ * translation occurs. The rounded up size will be written out into args on
+ * success.
+ *
+ * On most OSs, virtual-to-physical address translation is a priveledged
+ * function. Therefore, the implementer must validate the range supplied, to
+ * ensure they are not providing arbitrary virtual-to-physical address
+ * translations. While it is unlikely such a mechanism could be used to
+ * compromise the security of a system on its own, it is possible it could be
+ * combined with another small security risk to cause a much larger security
+ * risk.
+ *
+ * @note This is an optional part of the interface, and is only used by certain
+ * implementations of libEGL. If the platform layer in your libEGL
+ * implementation does not require Virtual-to-Physical address translation,
+ * then this function need not be implemented. A stub implementation should not
+ * be required either, as it would only be removed by the compiler's dead code
+ * elimination.
+ *
+ * @note if implemented, this function is entirely platform-dependant, and does
+ * not exist in common code.
+ *
+ * @param args see _mali_uk_va_to_mali_pa_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args );
+
+/** @} */ /* end group _mali_uk_memory */
+
+
+/** @addtogroup _mali_uk_pp U/K Fragment Processor
+ *
+ * The Fragment Processor (aka PP (Pixel Processor)) functions provide the following functionality:
+ * - retrieving version of the fragment processors
+ * - determine number of fragment processors
+ * - starting a job on a fragment processor
+ *
+ * @{ */
+
+/** @brief Issue a request to start a new job on a Fragment Processor.
+ *
+ * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can
+ * try to start the job again.
+ *
+ * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job
+ * which the hardware hasn't actually started processing yet. In this case the new job will be started instead and the
+ * existing one returned, otherwise the new job is started and the status field args->status is set to
+ * _MALI_UK_START_JOB_STARTED.
+ *
+ * Job completion can be awaited with _mali_ukk_wait_for_notification().
+ *
+ * @oaram ctx user-kernel context (mali_session)
+ * @param uargs see _mali_uk_pp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_pp_start_job( void *ctx, _mali_uk_pp_start_job_s *uargs, int *fence );
+
+/** @brief Returns the number of Fragment Processors in the system
+ *
+ * @param args see _mali_uk_get_pp_number_of_cores_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args );
+
+/** @brief Returns the version that all Fragment Processor cores are compatible with.
+ *
+ * This function may only be called when _mali_ukk_get_pp_number_of_cores() indicated at least one Fragment
+ * Processor core is available.
+ *
+ * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args );
+
+/** @brief Disable Write-back unit(s) on specified job
+ *
+ * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h"
+ */
+void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args);
+
+
+/** @} */ /* end group _mali_uk_pp */
+
+
+/** @addtogroup _mali_uk_gp U/K Vertex Processor
+ *
+ * The Vertex Processor (aka GP (Geometry Processor)) functions provide the following functionality:
+ * - retrieving version of the Vertex Processors
+ * - determine number of Vertex Processors available
+ * - starting a job on a Vertex Processor
+ *
+ * @{ */
+
+/** @brief Issue a request to start a new job on a Vertex Processor.
+ *
+ * If the request fails args->status is set to _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE and you can
+ * try to start the job again.
+ *
+ * An existing job could be returned for requeueing if the new job has a higher priority than a previously started job
+ * which the hardware hasn't actually started processing yet. In this case the new job will be started and the
+ * existing one returned, otherwise the new job is started and the status field args->status is set to
+ * _MALI_UK_START_JOB_STARTED.
+ *
+ * Job completion can be awaited with _mali_ukk_wait_for_notification().
+ *
+ * @oaram ctx user-kernel context (mali_session)
+ * @param uargs see _mali_uk_gp_start_job_s in "mali_utgard_uk_types.h". Use _mali_osk_copy_from_user to retrieve data!
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_gp_start_job( void *ctx, _mali_uk_gp_start_job_s *uargs );
+
+/** @brief Returns the number of Vertex Processors in the system.
+ *
+ * @param args see _mali_uk_get_gp_number_of_cores_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args );
+
+/** @brief Returns the version that all Vertex Processor cores are compatible with.
+ *
+ * This function may only be called when _mali_uk_get_gp_number_of_cores() indicated at least one Vertex
+ * Processor core is available.
+ *
+ * @param args see _mali_uk_get_gp_core_version_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args );
+
+/** @brief Resume or abort suspended Vertex Processor jobs.
+ *
+ * After receiving notification that a Vertex Processor job was suspended from
+ * _mali_ukk_wait_for_notification() you can use this function to resume or abort the job.
+ *
+ * @param args see _mali_uk_gp_suspend_response_s in "mali_utgard_uk_types.h"
+ * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
+ */
+_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args );
+
+/** @} */ /* end group _mali_uk_gp */
+
+#if defined(CONFIG_MALI400_PROFILING)
+/** @addtogroup _mali_uk_profiling U/K Timeline profiling module
+ * @{ */
+
+/** @brief Start recording profiling events.
+ *
+ * @param args see _mali_uk_profiling_start_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args);
+
+/** @brief Add event to profiling buffer.
+ *
+ * @param args see _mali_uk_profiling_add_event_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args);
+
+/** @brief Stop recording profiling events.
+ *
+ * @param args see _mali_uk_profiling_stop_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args);
+
+/** @brief Retrieve a recorded profiling event.
+ *
+ * @param args see _mali_uk_profiling_get_event_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args);
+
+/** @brief Clear recorded profiling events.
+ *
+ * @param args see _mali_uk_profiling_clear_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args);
+
+/** @} */ /* end group _mali_uk_profiling */
+#endif
+
+/** @addtogroup _mali_uk_vsync U/K VSYNC reporting module
+ * @{ */
+
+/** @brief Report events related to vsync.
+ *
+ * @note Events should be reported when starting to wait for vsync and when the
+ * waiting is finished. This information can then be used in kernel space to
+ * complement the GPU utilization metric.
+ *
+ * @param args see _mali_uk_vsync_event_report_s in "mali_utgard_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_vsync_event_report(_mali_uk_vsync_event_report_s *args);
+
+/** @} */ /* end group _mali_uk_vsync */
+
+/** @addtogroup _mali_sw_counters_report U/K Software counter reporting
+ * @{ */
+
+/** @brief Report software counters.
+ *
+ * @param args see _mali_uk_sw_counters_report_s in "mali_uk_types.h"
+ */
+_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args);
+
+/** @} */ /* end group _mali_sw_counters_report */
+
+/** @} */ /* end group u_k_api */
+
+/** @} */ /* end group uddapi */
+
+u32 _mali_ukk_report_memory_usage(void);
+
+u32 _mali_ukk_utilization_gp_pp(void);
+
+u32 _mali_ukk_utilization_gp(void);
+
+u32 _mali_ukk_utilization_pp(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_UKK_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c
new file mode 100644
index 0000000..8720b9a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.c
@@ -0,0 +1,95 @@
+/**
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_uk_types.h"
+#include "mali_user_settings_db.h"
+#include "mali_session.h"
+
+static u32 mali_user_settings[_MALI_UK_USER_SETTING_MAX];
+const char *_mali_uk_user_setting_descriptions[] = _MALI_UK_USER_SETTING_DESCRIPTIONS;
+
+static void mali_user_settings_notify(_mali_uk_user_setting_t setting, u32 value)
+{
+ struct mali_session_data *session, *tmp;
+
+ mali_session_lock();
+ MALI_SESSION_FOREACH(session, tmp, link)
+ {
+ _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_SETTINGS_CHANGED, sizeof(_mali_uk_settings_changed_s));
+ _mali_uk_settings_changed_s *data = notobj->result_buffer;
+ data->setting = setting;
+ data->value = value;
+
+ mali_session_send_notification(session, notobj);
+ }
+ mali_session_unlock();
+}
+
+void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value)
+{
+ mali_bool notify = MALI_FALSE;
+
+ if (setting >= _MALI_UK_USER_SETTING_MAX || setting < 0)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Invalid user setting %ud\n"));
+ return;
+ }
+
+ if (mali_user_settings[setting] != value)
+ {
+ notify = MALI_TRUE;
+ }
+
+ mali_user_settings[setting] = value;
+
+ if (notify)
+ {
+ mali_user_settings_notify(setting, value);
+ }
+}
+
+u32 mali_get_user_setting(_mali_uk_user_setting_t setting)
+{
+ if (setting >= _MALI_UK_USER_SETTING_MAX || setting < 0)
+ {
+ return 0;
+ }
+
+ return mali_user_settings[setting];
+}
+
+_mali_osk_errcode_t _mali_ukk_get_user_setting(_mali_uk_get_user_setting_s *args)
+{
+ _mali_uk_user_setting_t setting;
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ setting = args->setting;
+
+ if (0 <= setting && _MALI_UK_USER_SETTING_MAX > setting)
+ {
+ args->value = mali_user_settings[setting];
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+}
+
+_mali_osk_errcode_t _mali_ukk_get_user_settings(_mali_uk_get_user_settings_s *args)
+{
+ MALI_DEBUG_ASSERT_POINTER(args);
+
+ _mali_osk_memcpy(args->settings, mali_user_settings, sizeof(mali_user_settings));
+
+ return _MALI_OSK_ERR_OK;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h
new file mode 100644
index 0000000..fbb9415
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/common/mali_user_settings_db.h
@@ -0,0 +1,40 @@
+/**
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_USER_SETTINGS_DB_H__
+#define __MALI_USER_SETTINGS_DB_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mali_uk_types.h"
+
+/** @brief Set Mali user setting in DB
+ *
+ * Update the DB with a new value for \a setting. If the value is different from theprevious set value running sessions will be notified of the change.
+ *
+ * @param setting the setting to be changed
+ * @param value the new value to set
+ */
+void mali_set_user_setting(_mali_uk_user_setting_t setting, u32 value);
+
+/** @brief Get current Mali user setting value from DB
+ *
+ * @param setting the setting to extract
+ * @return the value of the selected setting
+ */
+u32 mali_get_user_setting(_mali_uk_user_setting_t setting);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __MALI_KERNEL_USER_SETTING__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h
new file mode 100644
index 0000000..cf3374a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard.h
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_utgard.h
+ * Defines types and interface exposed by the Mali Utgard device driver
+ */
+
+#ifndef __MALI_UTGARD_H__
+#define __MALI_UTGARD_H__
+
+#define MALI_GPU_NAME_UTGARD "mali-utgard"
+
+/* Mali-200 */
+
+#define MALI_GPU_RESOURCES_MALI200(base_addr, gp_irq, pp_irq, mmu_irq) \
+ MALI_GPU_RESOURCE_PP(base_addr + 0x0000, pp_irq) \
+ MALI_GPU_RESOURCE_GP(base_addr + 0x2000, gp_irq) \
+ MALI_GPU_RESOURCE_MMU(base_addr + 0x3000, mmu_irq)
+
+/* Mali-300 */
+
+#define MALI_GPU_RESOURCES_MALI300(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI300_PMU(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP1_PMU(base_addr, gp_irq, gp_mmu_irq, pp_irq, pp_mmu_irq)
+
+/* Mali-400 */
+
+#define MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP1_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP1(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+#define MALI_GPU_RESOURCES_MALI400_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP2_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+#define MALI_GPU_RESOURCES_MALI400_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0xC000, pp2_irq, base_addr + 0x6000, pp2_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP3_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+#define MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x1000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x0000, gp_irq, base_addr + 0x3000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x8000, pp0_irq, base_addr + 0x4000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0xA000, pp1_irq, base_addr + 0x5000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0xC000, pp2_irq, base_addr + 0x6000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0xE000, pp3_irq, base_addr + 0x7000, pp3_mmu_irq)
+
+#define MALI_GPU_RESOURCES_MALI400_MP4_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
+ MALI_GPU_RESOURCES_MALI400_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000)
+
+/* Mali-450 */
+#define MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP2_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP2(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP3_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP3(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x0E000, pp3_irq, base_addr + 0x07000, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP4_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP4(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP6(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x11000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x28000, pp3_irq, base_addr + 0x1C000, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(4, base_addr + 0x2A000, pp4_irq, base_addr + 0x1D000, pp4_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(5, base_addr + 0x2C000, pp5_irq, base_addr + 0x1E000, pp5_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP6_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP6(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCES_MALI450_MP8(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x10000) \
+ MALI_GPU_RESOURCE_GP_WITH_MMU(base_addr + 0x00000, gp_irq, base_addr + 0x03000, gp_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x01000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(0, base_addr + 0x08000, pp0_irq, base_addr + 0x04000, pp0_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(1, base_addr + 0x0A000, pp1_irq, base_addr + 0x05000, pp1_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(2, base_addr + 0x0C000, pp2_irq, base_addr + 0x06000, pp2_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(3, base_addr + 0x0E000, pp3_irq, base_addr + 0x07000, pp3_mmu_irq) \
+ MALI_GPU_RESOURCE_L2(base_addr + 0x11000) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(4, base_addr + 0x28000, pp4_irq, base_addr + 0x1C000, pp4_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(5, base_addr + 0x2A000, pp5_irq, base_addr + 0x1D000, pp5_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(6, base_addr + 0x2C000, pp6_irq, base_addr + 0x1E000, pp6_mmu_irq) \
+ MALI_GPU_RESOURCE_PP_WITH_MMU(7, base_addr + 0x2E000, pp7_irq, base_addr + 0x1F000, pp7_mmu_irq) \
+ MALI_GPU_RESOURCE_BCAST(base_addr + 0x13000) \
+ MALI_GPU_RESOURCE_DLBU(base_addr + 0x14000) \
+ MALI_GPU_RESOURCE_PP_BCAST(base_addr + 0x16000, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PP_MMU_BCAST(base_addr + 0x15000)
+
+#define MALI_GPU_RESOURCES_MALI450_MP8_PMU(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCES_MALI450_MP8(base_addr, gp_irq, gp_mmu_irq, pp0_irq, pp0_mmu_irq, pp1_irq, pp1_mmu_irq, pp2_irq, pp2_mmu_irq, pp3_irq, pp3_mmu_irq, pp4_irq, pp4_mmu_irq, pp5_irq, pp5_mmu_irq, pp6_irq, pp6_mmu_irq, pp7_irq, pp7_mmu_irq, pp_bcast_irq) \
+ MALI_GPU_RESOURCE_PMU(base_addr + 0x2000) \
+
+#define MALI_GPU_RESOURCE_L2(addr) \
+ { \
+ .name = "Mali_L2", \
+ .flags = IORESOURCE_MEM, \
+ .start = addr, \
+ .end = addr + 0x200, \
+ },
+
+#define MALI_GPU_RESOURCE_GP(gp_addr, gp_irq) \
+ { \
+ .name = "Mali_GP", \
+ .flags = IORESOURCE_MEM, \
+ .start = gp_addr, \
+ .end = gp_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_GP_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = gp_irq, \
+ .end = gp_irq, \
+ }, \
+
+#define MALI_GPU_RESOURCE_GP_WITH_MMU(gp_addr, gp_irq, gp_mmu_addr, gp_mmu_irq) \
+ { \
+ .name = "Mali_GP", \
+ .flags = IORESOURCE_MEM, \
+ .start = gp_addr, \
+ .end = gp_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_GP_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = gp_irq, \
+ .end = gp_irq, \
+ }, \
+ { \
+ .name = "Mali_GP_MMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = gp_mmu_addr, \
+ .end = gp_mmu_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_GP_MMU_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = gp_mmu_irq, \
+ .end = gp_mmu_irq, \
+ },
+
+#define MALI_GPU_RESOURCE_PP(pp_addr, pp_irq) \
+ { \
+ .name = "Mali_PP", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_addr, \
+ .end = pp_addr + 0x1100, \
+ }, \
+ { \
+ .name = "Mali_PP_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_irq, \
+ .end = pp_irq, \
+ }, \
+
+#define MALI_GPU_RESOURCE_PP_WITH_MMU(id, pp_addr, pp_irq, pp_mmu_addr, pp_mmu_irq) \
+ { \
+ .name = "Mali_PP" #id, \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_addr, \
+ .end = pp_addr + 0x1100, \
+ }, \
+ { \
+ .name = "Mali_PP" #id "_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_irq, \
+ .end = pp_irq, \
+ }, \
+ { \
+ .name = "Mali_PP" #id "_MMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_mmu_addr, \
+ .end = pp_mmu_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_PP" #id "_MMU_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_mmu_irq, \
+ .end = pp_mmu_irq, \
+ },
+
+#define MALI_GPU_RESOURCE_MMU(mmu_addr, mmu_irq) \
+ { \
+ .name = "Mali_MMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = mmu_addr, \
+ .end = mmu_addr + 0x100, \
+ }, \
+ { \
+ .name = "Mali_MMU_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = mmu_irq, \
+ .end = mmu_irq, \
+ },
+
+#define MALI_GPU_RESOURCE_PMU(pmu_addr) \
+ { \
+ .name = "Mali_PMU", \
+ .flags = IORESOURCE_MEM, \
+ .start = pmu_addr, \
+ .end = pmu_addr + 0x100, \
+ },
+
+#define MALI_GPU_RESOURCE_DLBU(dlbu_addr) \
+ { \
+ .name = "Mali_DLBU", \
+ .flags = IORESOURCE_MEM, \
+ .start = dlbu_addr, \
+ .end = dlbu_addr + 0x100, \
+ },
+
+#define MALI_GPU_RESOURCE_BCAST(bcast_addr) \
+ { \
+ .name = "Mali_Broadcast", \
+ .flags = IORESOURCE_MEM, \
+ .start = bcast_addr, \
+ .end = bcast_addr + 0x100, \
+ },
+
+#define MALI_GPU_RESOURCE_PP_BCAST(pp_addr, pp_irq) \
+ { \
+ .name = "Mali_PP_Broadcast", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_addr, \
+ .end = pp_addr + 0x1100, \
+ }, \
+ { \
+ .name = "Mali_PP_Broadcast_IRQ", \
+ .flags = IORESOURCE_IRQ, \
+ .start = pp_irq, \
+ .end = pp_irq, \
+ }, \
+
+#define MALI_GPU_RESOURCE_PP_MMU_BCAST(pp_mmu_bcast_addr) \
+ { \
+ .name = "Mali_PP_MMU_Broadcast", \
+ .flags = IORESOURCE_MEM, \
+ .start = pp_mmu_bcast_addr, \
+ .end = pp_mmu_bcast_addr + 0x100, \
+ },
+
+struct mali_gpu_utilization_data
+{
+ unsigned int utilization_gpu; /* Utilization for GP and all PP cores combined, 0 = no utilization, 256 = full utilization */
+ unsigned int utilization_gp; /* Utilization for GP core only, 0 = no utilization, 256 = full utilization */
+ unsigned int utilization_pp; /* Utilization for all PP cores combined, 0 = no utilization, 256 = full utilization */
+};
+
+struct mali_gpu_device_data
+{
+ /* Dedicated GPU memory range (physical). */
+ unsigned long dedicated_mem_start;
+ unsigned long dedicated_mem_size;
+
+ /* Shared GPU memory */
+ unsigned long shared_mem_size;
+
+ /* Frame buffer memory to be accessible by Mali GPU (physical) */
+ unsigned long fb_start;
+ unsigned long fb_size;
+
+ /* Report GPU utilization in this interval (specified in ms) */
+ unsigned long utilization_interval;
+
+ /* Function that will receive periodic GPU utilization numbers */
+ void (*utilization_callback)(struct mali_gpu_utilization_data *data);
+
+ /*
+ * Mali PMU switch delay.
+ * Only needed if the power gates are connected to the PMU in a high fanout
+ * network. This value is the number of Mali clock cycles it takes to
+ * enable the power gates and turn on the power mesh.
+ * This value will have no effect if a daisy chain implementation is used.
+ */
+ unsigned long pmu_switch_delay;
+};
+
+/** @brief MALI GPU power down using MALI in-built PMU
+ *
+ * called to power down all cores
+ */
+int mali_pmu_powerdown(void);
+
+
+/** @brief MALI GPU power up using MALI in-built PMU
+ *
+ * called to power up all cores
+ */
+int mali_pmu_powerup(void);
+
+/**
+ * Pause the scheduling and power state changes of Mali device driver.
+ * mali_dev_resume() must always be called as soon as possible after this function
+ * in order to resume normal operation of the Mali driver.
+ */
+void mali_dev_pause(void);
+
+/**
+ * Resume scheduling and allow power changes in Mali device driver.
+ * This must always be called after mali_dev_pause().
+ */
+void mali_dev_resume(void);
+
+/** @brief Set the desired number of PP cores to use.
+ *
+ * The internal Mali PMU will be used, if present, to physically power off the PP cores.
+ *
+ * @param num_cores The number of desired cores
+ * @return 0 on success, otherwise error. -EINVAL means an invalid number of cores was specified.
+ */
+int mali_perf_set_num_pp_cores(unsigned int num_cores);
+
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h
new file mode 100644
index 0000000..3ef9a28
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_counters.h
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MALI_UTGARD_COUNTERS_H_
+#define _MALI_UTGARD_COUNTERS_H_
+
+typedef struct
+{
+ void *unused;
+} mali_cinstr_counter_info;
+
+typedef enum
+{
+ MALI_CINSTR_COUNTER_SOURCE_EGL = 0,
+ MALI_CINSTR_COUNTER_SOURCE_OPENGLES = 1000,
+ MALI_CINSTR_COUNTER_SOURCE_OPENVG = 2000,
+ MALI_CINSTR_COUNTER_SOURCE_GP = 3000,
+ MALI_CINSTR_COUNTER_SOURCE_PP = 4000,
+} cinstr_counter_source;
+
+#define MALI_CINSTR_EGL_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_EGL
+#define MALI_CINSTR_EGL_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_EGL + 999)
+
+#define MALI_CINSTR_GLES_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENGLES
+#define MALI_CINSTR_GLES_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 999)
+
+#define MALI_CINSTR_VG_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_OPENVG
+#define MALI_CINSTR_VG_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_OPENVG + 999)
+
+#define MALI_CINSTR_GP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_GP
+#define MALI_CINSTR_GP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_GP + 999)
+
+#define MALI_CINSTR_PP_FIRST_COUNTER MALI_CINSTR_COUNTER_SOURCE_PP
+#define MALI_CINSTR_PP_LAST_COUNTER (MALI_CINSTR_COUNTER_SOURCE_PP + 999)
+
+
+typedef enum
+{
+ /* EGL counters */
+
+ MALI_CINSTR_EGL_BLIT_TIME = MALI_CINSTR_COUNTER_SOURCE_EGL + 0,
+
+ /* Last counter in the EGL set */
+ MALI_CINSTR_EGL_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_EGL + 1,
+
+ /* GLES counters */
+
+ MALI_CINSTR_GLES_DRAW_ELEMENTS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 0,
+ MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_INDICES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 1,
+ MALI_CINSTR_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 2,
+ MALI_CINSTR_GLES_DRAW_ARRAYS_CALLS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 3,
+ MALI_CINSTR_GLES_DRAW_ARRAYS_NUM_TRANSFORMED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 4,
+ MALI_CINSTR_GLES_DRAW_POINTS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 5,
+ MALI_CINSTR_GLES_DRAW_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 6,
+ MALI_CINSTR_GLES_DRAW_LINE_LOOP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 7,
+ MALI_CINSTR_GLES_DRAW_LINE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 8,
+ MALI_CINSTR_GLES_DRAW_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 9,
+ MALI_CINSTR_GLES_DRAW_TRIANGLE_STRIP = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 10,
+ MALI_CINSTR_GLES_DRAW_TRIANGLE_FAN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 11,
+ MALI_CINSTR_GLES_NON_VBO_DATA_COPY_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 12,
+ MALI_CINSTR_GLES_UNIFORM_BYTES_COPIED_TO_MALI = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 13,
+ MALI_CINSTR_GLES_UPLOAD_TEXTURE_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 14,
+ MALI_CINSTR_GLES_UPLOAD_VBO_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 15,
+ MALI_CINSTR_GLES_NUM_FLUSHES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 16,
+ MALI_CINSTR_GLES_NUM_VSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 17,
+ MALI_CINSTR_GLES_NUM_FSHADERS_GENERATED = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 18,
+ MALI_CINSTR_GLES_VSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 19,
+ MALI_CINSTR_GLES_FSHADER_GEN_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 20,
+ MALI_CINSTR_GLES_INPUT_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 21,
+ MALI_CINSTR_GLES_VXCACHE_HIT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 22,
+ MALI_CINSTR_GLES_VXCACHE_MISS = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 23,
+ MALI_CINSTR_GLES_VXCACHE_COLLISION = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 24,
+ MALI_CINSTR_GLES_CULLED_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 25,
+ MALI_CINSTR_GLES_CULLED_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 26,
+ MALI_CINSTR_GLES_BACKFACE_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 27,
+ MALI_CINSTR_GLES_GBCLIP_TRIANGLES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 28,
+ MALI_CINSTR_GLES_GBCLIP_LINES = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 29,
+ MALI_CINSTR_GLES_TRIANGLES_DRAWN = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 30,
+ MALI_CINSTR_GLES_DRAWCALL_TIME = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 31,
+ MALI_CINSTR_GLES_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 32,
+ MALI_CINSTR_GLES_INDEPENDENT_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 33,
+ MALI_CINSTR_GLES_STRIP_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 34,
+ MALI_CINSTR_GLES_FAN_TRIANGLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 35,
+ MALI_CINSTR_GLES_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 36,
+ MALI_CINSTR_GLES_INDEPENDENT_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 37,
+ MALI_CINSTR_GLES_STRIP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 38,
+ MALI_CINSTR_GLES_LOOP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 39,
+ MALI_CINSTR_GLES_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 40,
+
+ /* Last counter in the GLES set */
+ MALI_CINSTR_GLES_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENGLES + 41,
+
+ /* OpenVG counters */
+
+ MALI_CINSTR_VG_MASK_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 0,
+ MALI_CINSTR_VG_CLEAR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 1,
+ MALI_CINSTR_VG_APPEND_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 2,
+ MALI_CINSTR_VG_APPEND_PATH_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 3,
+ MALI_CINSTR_VG_MODIFY_PATH_COORDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 4,
+ MALI_CINSTR_VG_TRANSFORM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 5,
+ MALI_CINSTR_VG_INTERPOLATE_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 6,
+ MALI_CINSTR_VG_PATH_LENGTH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 7,
+ MALI_CINSTR_VG_POINT_ALONG_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 8,
+ MALI_CINSTR_VG_PATH_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 9,
+ MALI_CINSTR_VG_PATH_TRANSFORMED_BOUNDS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 10,
+ MALI_CINSTR_VG_DRAW_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 11,
+ MALI_CINSTR_VG_CLEAR_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 12,
+ MALI_CINSTR_VG_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 13,
+ MALI_CINSTR_VG_GET_IMAGE_SUB_DATA_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 14,
+ MALI_CINSTR_VG_COPY_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 15,
+ MALI_CINSTR_VG_DRAW_IMAGE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 16,
+ MALI_CINSTR_VG_SET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 17,
+ MALI_CINSTR_VG_WRITE_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 18,
+ MALI_CINSTR_VG_GET_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 19,
+ MALI_CINSTR_VG_READ_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 20,
+ MALI_CINSTR_VG_COPY_PIXELS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 21,
+ MALI_CINSTR_VG_COLOR_MATRIX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 22,
+ MALI_CINSTR_VG_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 23,
+ MALI_CINSTR_VG_SEPARABLE_CONVOLVE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 24,
+ MALI_CINSTR_VG_GAUSSIAN_BLUR_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 25,
+ MALI_CINSTR_VG_LOOKUP_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 26,
+ MALI_CINSTR_VG_LOOKUP_SINGLE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 27,
+ MALI_CINSTR_VG_CONTEXT_CREATE_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 28,
+ MALI_CINSTR_VG_STROKED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 29,
+ MALI_CINSTR_VG_STROKED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 30,
+ MALI_CINSTR_VG_STROKED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 31,
+ MALI_CINSTR_VG_STROKED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 32,
+ MALI_CINSTR_VG_FILLED_CUBICS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 33,
+ MALI_CINSTR_VG_FILLED_QUADS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 34,
+ MALI_CINSTR_VG_FILLED_ARCS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 35,
+ MALI_CINSTR_VG_FILLED_LINES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 36,
+ MALI_CINSTR_VG_DRAW_PATH_CALLS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 37,
+ MALI_CINSTR_VG_TRIANGLES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 38,
+ MALI_CINSTR_VG_VERTICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 39,
+ MALI_CINSTR_VG_INDICES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 40,
+ MALI_CINSTR_VG_FILLED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 41,
+ MALI_CINSTR_VG_STROKED_PATHS_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 42,
+ MALI_CINSTR_VG_FILL_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 43,
+ MALI_CINSTR_VG_DRAW_FILLED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 44,
+ MALI_CINSTR_VG_STROKE_EXTRACT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 45,
+ MALI_CINSTR_VG_DRAW_STROKED_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 46,
+ MALI_CINSTR_VG_DRAW_PAINT_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 47,
+ MALI_CINSTR_VG_DATA_STRUCTURES_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 48,
+ MALI_CINSTR_VG_MEM_PATH_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 49,
+ MALI_CINSTR_VG_RSW_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 50,
+
+ /* Last counter in the VG set */
+ MALI_CINSTR_VG_MAX_COUNTER = MALI_CINSTR_COUNTER_SOURCE_OPENVG + 51,
+
+ /* Mali GP counters */
+
+ MALI_CINSTR_GP_DEPRECATED_0 = MALI_CINSTR_COUNTER_SOURCE_GP + 0,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_GP = MALI_CINSTR_COUNTER_SOURCE_GP + 1,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 2,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_STORER = MALI_CINSTR_COUNTER_SOURCE_GP + 3,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_LOADER = MALI_CINSTR_COUNTER_SOURCE_GP + 4,
+ MALI_CINSTR_GP_CYCLES_VERTEX_LOADER_WAITING_FOR_VERTEX_SHADER = MALI_CINSTR_COUNTER_SOURCE_GP + 5,
+ MALI_CINSTR_GP_NUMBER_OF_WORDS_READ = MALI_CINSTR_COUNTER_SOURCE_GP + 6,
+ MALI_CINSTR_GP_NUMBER_OF_WORDS_WRITTEN = MALI_CINSTR_COUNTER_SOURCE_GP + 7,
+ MALI_CINSTR_GP_NUMBER_OF_READ_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 8,
+ MALI_CINSTR_GP_NUMBER_OF_WRITE_BURSTS = MALI_CINSTR_COUNTER_SOURCE_GP + 9,
+ MALI_CINSTR_GP_NUMBER_OF_VERTICES_PROCESSED = MALI_CINSTR_COUNTER_SOURCE_GP + 10,
+ MALI_CINSTR_GP_NUMBER_OF_VERTICES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 11,
+ MALI_CINSTR_GP_NUMBER_OF_PRIMITIVES_FETCHED = MALI_CINSTR_COUNTER_SOURCE_GP + 12,
+ MALI_CINSTR_GP_RESERVED_13 = MALI_CINSTR_COUNTER_SOURCE_GP + 13,
+ MALI_CINSTR_GP_NUMBER_OF_BACKFACE_CULLINGS_DONE = MALI_CINSTR_COUNTER_SOURCE_GP + 14,
+ MALI_CINSTR_GP_NUMBER_OF_COMMANDS_WRITTEN_TO_TILES = MALI_CINSTR_COUNTER_SOURCE_GP + 15,
+ MALI_CINSTR_GP_NUMBER_OF_MEMORY_BLOCKS_ALLOCATED = MALI_CINSTR_COUNTER_SOURCE_GP + 16,
+ MALI_CINSTR_GP_RESERVED_17 = MALI_CINSTR_COUNTER_SOURCE_GP + 17,
+ MALI_CINSTR_GP_RESERVED_18 = MALI_CINSTR_COUNTER_SOURCE_GP + 18,
+ MALI_CINSTR_GP_NUMBER_OF_VERTEX_LOADER_CACHE_MISSES = MALI_CINSTR_COUNTER_SOURCE_GP + 19,
+ MALI_CINSTR_GP_RESERVED_20 = MALI_CINSTR_COUNTER_SOURCE_GP + 20,
+ MALI_CINSTR_GP_RESERVED_21 = MALI_CINSTR_COUNTER_SOURCE_GP + 21,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_VERTEX_SHADER_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 22,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_COMMAND_PROCESSOR = MALI_CINSTR_COUNTER_SOURCE_GP + 23,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_LIST_WRITER = MALI_CINSTR_COUNTER_SOURCE_GP + 24,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_THROUGH_THE_PREPARE_LIST_COMMANDS = MALI_CINSTR_COUNTER_SOURCE_GP + 25,
+ MALI_CINSTR_GP_RESERVED_26 = MALI_CINSTR_COUNTER_SOURCE_GP + 26,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_PRIMITIVE_ASSEMBLY = MALI_CINSTR_COUNTER_SOURCE_GP + 27,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_VERTEX_FETCHER = MALI_CINSTR_COUNTER_SOURCE_GP + 28,
+ MALI_CINSTR_GP_RESERVED_29 = MALI_CINSTR_COUNTER_SOURCE_GP + 29,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_BOUNDINGBOX_AND_COMMAND_GENERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 30,
+ MALI_CINSTR_GP_RESERVED_31 = MALI_CINSTR_COUNTER_SOURCE_GP + 31,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_SCISSOR_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 32,
+ MALI_CINSTR_GP_ACTIVE_CYCLES_PLBU_TILE_ITERATOR = MALI_CINSTR_COUNTER_SOURCE_GP + 33,
+ MALI_CINSTR_GP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_GP + 900,
+
+ /* Mali PP counters */
+
+ MALI_CINSTR_PP_ACTIVE_CLOCK_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 0,
+ MALI_CINSTR_PP_TOTAL_CLOCK_CYCLES_COUNT_REMOVED = MALI_CINSTR_COUNTER_SOURCE_PP + 1,
+ MALI_CINSTR_PP_TOTAL_BUS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 2,
+ MALI_CINSTR_PP_TOTAL_BUS_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 3,
+ MALI_CINSTR_PP_BUS_READ_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 4,
+ MALI_CINSTR_PP_BUS_WRITE_REQUEST_CYCLES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 5,
+ MALI_CINSTR_PP_BUS_READ_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 6,
+ MALI_CINSTR_PP_BUS_WRITE_TRANSACTIONS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 7,
+ MALI_CINSTR_PP_RESERVED_08 = MALI_CINSTR_COUNTER_SOURCE_PP + 8,
+ MALI_CINSTR_PP_TILE_WRITEBACK_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 9,
+ MALI_CINSTR_PP_STORE_UNIT_WRITES = MALI_CINSTR_COUNTER_SOURCE_PP + 10,
+ MALI_CINSTR_PP_RESERVED_11 = MALI_CINSTR_COUNTER_SOURCE_PP + 11,
+ MALI_CINSTR_PP_PALETTE_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 12,
+ MALI_CINSTR_PP_TEXTURE_CACHE_UNCOMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 13,
+ MALI_CINSTR_PP_POLYGON_LIST_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 14,
+ MALI_CINSTR_PP_RSW_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 15,
+ MALI_CINSTR_PP_VERTEX_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 16,
+ MALI_CINSTR_PP_UNIFORM_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 17,
+ MALI_CINSTR_PP_PROGRAM_CACHE_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 18,
+ MALI_CINSTR_PP_VARYING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 19,
+ MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 20,
+ MALI_CINSTR_PP_TEXTURE_DESCRIPTORS_REMAPPING_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 21,
+ MALI_CINSTR_PP_TEXTURE_CACHE_COMPRESSED_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 22,
+ MALI_CINSTR_PP_LOAD_UNIT_READS = MALI_CINSTR_COUNTER_SOURCE_PP + 23,
+ MALI_CINSTR_PP_POLYGON_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 24,
+ MALI_CINSTR_PP_PIXEL_RECTANGLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 25,
+ MALI_CINSTR_PP_LINES_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 26,
+ MALI_CINSTR_PP_POINTS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 27,
+ MALI_CINSTR_PP_STALL_CYCLES_POLYGON_LIST_READER = MALI_CINSTR_COUNTER_SOURCE_PP + 28,
+ MALI_CINSTR_PP_STALL_CYCLES_TRIANGLE_SETUP = MALI_CINSTR_COUNTER_SOURCE_PP + 29,
+ MALI_CINSTR_PP_QUAD_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 30,
+ MALI_CINSTR_PP_FRAGMENT_RASTERIZED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 31,
+ MALI_CINSTR_PP_FRAGMENT_REJECTED_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 32,
+ MALI_CINSTR_PP_FRAGMENT_REJECTED_FWD_FRAGMENT_KILL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 33,
+ MALI_CINSTR_PP_FRAGMENT_PASSED_ZSTENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 34,
+ MALI_CINSTR_PP_PATCHES_REJECTED_EARLY_Z_STENCIL_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 35,
+ MALI_CINSTR_PP_PATCHES_EVALUATED = MALI_CINSTR_COUNTER_SOURCE_PP + 36,
+ MALI_CINSTR_PP_INSTRUCTION_COMPLETED_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 37,
+ MALI_CINSTR_PP_INSTRUCTION_FAILED_RENDEZVOUS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 38,
+ MALI_CINSTR_PP_INSTRUCTION_FAILED_VARYING_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 39,
+ MALI_CINSTR_PP_INSTRUCTION_FAILED_TEXTURE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 40,
+ MALI_CINSTR_PP_INSTRUCTION_FAILED_LOAD_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 41,
+ MALI_CINSTR_PP_INSTRUCTION_FAILED_TILE_READ_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 42,
+ MALI_CINSTR_PP_INSTRUCTION_FAILED_STORE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 43,
+ MALI_CINSTR_PP_RENDEZVOUS_BREAKAGE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 44,
+ MALI_CINSTR_PP_PIPELINE_BUBBLES_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 45,
+ MALI_CINSTR_PP_TEXTURE_MAPPER_MULTIPASS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 46,
+ MALI_CINSTR_PP_TEXTURE_MAPPER_CYCLE_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 47,
+ MALI_CINSTR_PP_VERTEX_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 48,
+ MALI_CINSTR_PP_VERTEX_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 49,
+ MALI_CINSTR_PP_VARYING_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 50,
+ MALI_CINSTR_PP_VARYING_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 51,
+ MALI_CINSTR_PP_VARYING_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 52,
+ MALI_CINSTR_PP_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 53,
+ MALI_CINSTR_PP_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 54,
+ MALI_CINSTR_PP_TEXTURE_CACHE_CONFLICT_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 55,
+ MALI_CINSTR_PP_PALETTE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 200 only */
+ MALI_CINSTR_PP_PALETTE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 200 only */
+ MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 56, /* Mali 400 class only */
+ MALI_CINSTR_PP_COMPRESSED_TEXTURE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 57, /* Mali 400 class only */
+ MALI_CINSTR_PP_LOAD_STORE_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 58,
+ MALI_CINSTR_PP_LOAD_STORE_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 59,
+ MALI_CINSTR_PP_PROGRAM_CACHE_HIT_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 60,
+ MALI_CINSTR_PP_PROGRAM_CACHE_MISS_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 61,
+ MALI_CINSTR_PP_JOB_COUNT = MALI_CINSTR_COUNTER_SOURCE_PP + 900,
+} cinstr_counters_m200_t;
+
+#endif /*_MALI_UTGARD_COUNTERS_H_*/
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h
new file mode 100644
index 0000000..6043a7d
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_ioctl.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_UTGARD_IOCTL_H__
+#define __MALI_UTGARD_IOCTL_H__
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <linux/fs.h> /* file system operations */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @file mali_kernel_ioctl.h
+ * Interface to the Linux device driver.
+ * This file describes the interface needed to use the Linux device driver.
+ * Its interface is designed to used by the HAL implementation through a thin arch layer.
+ */
+
+/**
+ * ioctl commands
+ */
+
+#define MALI_IOC_BASE 0x82
+#define MALI_IOC_CORE_BASE (_MALI_UK_CORE_SUBSYSTEM + MALI_IOC_BASE)
+#define MALI_IOC_MEMORY_BASE (_MALI_UK_MEMORY_SUBSYSTEM + MALI_IOC_BASE)
+#define MALI_IOC_PP_BASE (_MALI_UK_PP_SUBSYSTEM + MALI_IOC_BASE)
+#define MALI_IOC_GP_BASE (_MALI_UK_GP_SUBSYSTEM + MALI_IOC_BASE)
+#define MALI_IOC_PROFILING_BASE (_MALI_UK_PROFILING_SUBSYSTEM + MALI_IOC_BASE)
+#define MALI_IOC_VSYNC_BASE (_MALI_UK_VSYNC_SUBSYSTEM + MALI_IOC_BASE)
+
+#define MALI_IOC_WAIT_FOR_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_WAIT_FOR_NOTIFICATION, _mali_uk_wait_for_notification_s *)
+#define MALI_IOC_GET_API_VERSION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_API_VERSION, _mali_uk_get_api_version_s *)
+#define MALI_IOC_POST_NOTIFICATION _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_POST_NOTIFICATION, _mali_uk_post_notification_s *)
+#define MALI_IOC_GET_USER_SETTING _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTING, _mali_uk_get_user_setting_s *)
+#define MALI_IOC_GET_USER_SETTINGS _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_GET_USER_SETTINGS, _mali_uk_get_user_settings_s *)
+#define MALI_IOC_STREAM_CREATE _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_STREAM_CREATE, _mali_uk_stream_create_s *)
+#define MALI_IOC_FENCE_CREATE_EMPTY _IOWR(MALI_IOC_CORE_BASE, _MALI_UK_FENCE_CREATE_EMPTY, _mali_uk_fence_create_empty_s *)
+#define MALI_IOC_FENCE_VALIDATE _IOR(MALI_IOC_CORE_BASE, _MALI_UK_FENCE_VALIDATE, _mali_uk_fence_validate_s *)
+
+#define MALI_IOC_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, void *)
+#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, void *)
+#define MALI_IOC_MEM_INIT _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_INIT_MEM, _mali_uk_init_mem_s *)
+#define MALI_IOC_MEM_TERM _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_TERM_MEM, _mali_uk_term_mem_s *)
+#define MALI_IOC_MEM_MAP_EXT _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MAP_EXT_MEM, _mali_uk_map_external_mem_s *)
+#define MALI_IOC_MEM_UNMAP_EXT _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_UNMAP_EXT_MEM, _mali_uk_unmap_external_mem_s *)
+#define MALI_IOC_MEM_ATTACH_DMA_BUF _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_DMA_BUF, _mali_uk_attach_dma_buf_s *)
+#define MALI_IOC_MEM_RELEASE_DMA_BUF _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_DMA_BUF, _mali_uk_release_dma_buf_s *)
+#define MALI_IOC_MEM_DMA_BUF_GET_SIZE _IOR(MALI_IOC_MEMORY_BASE, _MALI_UK_DMA_BUF_GET_SIZE, _mali_uk_dma_buf_get_size_s *)
+#define MALI_IOC_MEM_ATTACH_UMP _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_ATTACH_UMP_MEM, _mali_uk_attach_ump_mem_s *)
+#define MALI_IOC_MEM_RELEASE_UMP _IOW(MALI_IOC_MEMORY_BASE, _MALI_UK_RELEASE_UMP_MEM, _mali_uk_release_ump_mem_s *)
+#define MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE _IOR (MALI_IOC_MEMORY_BASE, _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, _mali_uk_query_mmu_page_table_dump_size_s *)
+#define MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_DUMP_MMU_PAGE_TABLE, _mali_uk_dump_mmu_page_table_s *)
+#define MALI_IOC_MEM_WRITE_SAFE _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_MEM_WRITE_SAFE, _mali_uk_mem_write_safe_s *)
+
+#define MALI_IOC_PP_START_JOB _IOWR(MALI_IOC_PP_BASE, _MALI_UK_PP_START_JOB, _mali_uk_pp_start_job_s *)
+#define MALI_IOC_PP_NUMBER_OF_CORES_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_NUMBER_OF_CORES, _mali_uk_get_pp_number_of_cores_s *)
+#define MALI_IOC_PP_CORE_VERSION_GET _IOR (MALI_IOC_PP_BASE, _MALI_UK_GET_PP_CORE_VERSION, _mali_uk_get_pp_core_version_s * )
+#define MALI_IOC_PP_DISABLE_WB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_DISABLE_WB, _mali_uk_pp_disable_wb_s * )
+
+#define MALI_IOC_GP2_START_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_START_JOB, _mali_uk_gp_start_job_s *)
+#define MALI_IOC_GP2_NUMBER_OF_CORES_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_NUMBER_OF_CORES, _mali_uk_get_gp_number_of_cores_s *)
+#define MALI_IOC_GP2_CORE_VERSION_GET _IOR (MALI_IOC_GP_BASE, _MALI_UK_GET_GP_CORE_VERSION, _mali_uk_get_gp_core_version_s *)
+#define MALI_IOC_GP2_SUSPEND_RESPONSE _IOW (MALI_IOC_GP_BASE, _MALI_UK_GP_SUSPEND_RESPONSE,_mali_uk_gp_suspend_response_s *)
+
+#define MALI_IOC_PROFILING_START _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_START, _mali_uk_profiling_start_s *)
+#define MALI_IOC_PROFILING_ADD_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_ADD_EVENT, _mali_uk_profiling_add_event_s*)
+#define MALI_IOC_PROFILING_STOP _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_STOP, _mali_uk_profiling_stop_s *)
+#define MALI_IOC_PROFILING_GET_EVENT _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_EVENT, _mali_uk_profiling_get_event_s *)
+#define MALI_IOC_PROFILING_CLEAR _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_CLEAR, _mali_uk_profiling_clear_s *)
+#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_get_user_settings_s *)
+#define MALI_IOC_PROFILING_REPORT_SW_COUNTERS _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_REPORT_SW_COUNTERS, _mali_uk_sw_counters_report_s *)
+
+#define MALI_IOC_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_UTGARD_IOCTL_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h
new file mode 100644
index 0000000..99864b8
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_events.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MALI_UTGARD_PROFILING_EVENTS_H_
+#define _MALI_UTGARD_PROFILING_EVENTS_H_
+
+/*
+ * The event ID is a 32 bit value consisting of different fields
+ * reserved, 4 bits, for future use
+ * event type, 4 bits, cinstr_profiling_event_type_t
+ * event channel, 8 bits, the source of the event.
+ * event data, 16 bit field, data depending on event type
+ */
+
+/**
+ * Specifies what kind of event this is
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_TYPE_SINGLE = 0 << 24,
+ MALI_PROFILING_EVENT_TYPE_START = 1 << 24,
+ MALI_PROFILING_EVENT_TYPE_STOP = 2 << 24,
+ MALI_PROFILING_EVENT_TYPE_SUSPEND = 3 << 24,
+ MALI_PROFILING_EVENT_TYPE_RESUME = 4 << 24,
+} cinstr_profiling_event_type_t;
+
+
+/**
+ * Secifies the channel/source of the event
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_CHANNEL_SOFTWARE = 0 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_GP0 = 1 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP0 = 5 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP1 = 6 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP2 = 7 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP3 = 8 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP4 = 9 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP5 = 10 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP6 = 11 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_PP7 = 12 << 16,
+ MALI_PROFILING_EVENT_CHANNEL_GPU = 21 << 16,
+} cinstr_profiling_event_channel_t;
+
+
+#define MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(num) (((MALI_PROFILING_EVENT_CHANNEL_GP0 >> 16) + (num)) << 16)
+#define MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(num) (((MALI_PROFILING_EVENT_CHANNEL_PP0 >> 16) + (num)) << 16)
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from software channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_NEW_FRAME = 1,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_FLUSH = 2,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_EGL_SWAP_BUFFERS = 3,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_FB_EVENT = 4,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_GP_ENQUEUE = 5,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_PP_ENQUEUE = 6,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_READBACK = 7,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_WRITEBACK = 8,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_ENTER_API_FUNC = 10,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC = 11,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_DISCARD_ATTACHMENTS = 13,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_TRY_LOCK = 53,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_LOCK = 54,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_UMP_UNLOCK = 55,
+ MALI_PROFILING_EVENT_REASON_SINGLE_LOCK_CONTENDED = 56,
+} cinstr_profiling_event_reason_single_sw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
+ * to inform whether the core is physical or virtual
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL = 0,
+ MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL = 1,
+} cinstr_profiling_event_reason_start_stop_hw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_START/STOP is used from software channel
+ */
+typedef enum
+{
+ /*MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0,*/
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_MALI = 1,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_CALLBACK_THREAD = 2,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_WORKER_THREAD = 3,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_BOTTOM_HALF = 4,
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_UPPER_HALF = 5,
+} cinstr_profiling_event_reason_start_stop_sw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SUSPEND/RESUME is used from software channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_NONE = 0, /* used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1, /* NOT used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26, /* used in some build configurations */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT = 27, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC = 28, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29, /* used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30, /* used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31, /* used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32, /* used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33, /* NOT used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_QUEUE_BUFFER = 34, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_DEQUEUE_BUFFER = 35, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_UMP_LOCK = 36, /* Not currently used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_GLOBAL_LOCK = 37, /* Not currently used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_X11_SWAP = 38, /* Not currently used */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_MALI_EGL_IMAGE_SYNC_WAIT = 39, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GP_JOB_HANDLING =40, /* USED */
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PP_JOB_HANDLING =41, /* USED */
+} cinstr_profiling_event_reason_suspend_resume_sw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from a HW channel (GPx+PPx)
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT = 1,
+ MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH = 2,
+} cinstr_profiling_event_reason_single_hw_t;
+
+/**
+ * These events are applicable when the type MALI_PROFILING_EVENT_TYPE_SINGLE is used from the GPU channel
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE = 1,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L20_COUNTERS = 2,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L21_COUNTERS = 3,
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_L22_COUNTERS = 4,
+} cinstr_profiling_event_reason_single_gpu_t;
+
+/**
+ * These values are applicable for the 3rd data parameter when
+ * the type MALI_PROFILING_EVENT_TYPE_START is used from the software channel
+ * with the MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF reason.
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_DATA_CORE_GP0 = 1,
+ MALI_PROFILING_EVENT_DATA_CORE_PP0 = 5,
+ MALI_PROFILING_EVENT_DATA_CORE_PP1 = 6,
+ MALI_PROFILING_EVENT_DATA_CORE_PP2 = 7,
+ MALI_PROFILING_EVENT_DATA_CORE_PP3 = 8,
+ MALI_PROFILING_EVENT_DATA_CORE_PP4 = 9,
+ MALI_PROFILING_EVENT_DATA_CORE_PP5 = 10,
+ MALI_PROFILING_EVENT_DATA_CORE_PP6 = 11,
+ MALI_PROFILING_EVENT_DATA_CORE_PP7 = 12,
+} cinstr_profiling_event_data_core_t;
+
+#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_GP(num) (MALI_PROFILING_EVENT_DATA_CORE_GP0 + (num))
+#define MALI_PROFILING_MAKE_EVENT_DATA_CORE_PP(num) (MALI_PROFILING_EVENT_DATA_CORE_PP0 + (num))
+
+
+#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h
new file mode 100644
index 0000000..c449215
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_profiling_gator_api.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_UTGARD_PROFILING_GATOR_API_H__
+#define __MALI_UTGARD_PROFILING_GATOR_API_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MALI_PROFILING_API_VERSION 4
+
+#define MAX_NUM_L2_CACHE_CORES 3
+#define MAX_NUM_FP_CORES 8
+#define MAX_NUM_VP_CORES 1
+
+/** The list of events supported by the Mali DDK. */
+typedef enum
+{
+ /* Vertex processor activity */
+ ACTIVITY_VP_0 = 0,
+
+ /* Fragment processor activity */
+ ACTIVITY_FP_0,
+ ACTIVITY_FP_1,
+ ACTIVITY_FP_2,
+ ACTIVITY_FP_3,
+ ACTIVITY_FP_4,
+ ACTIVITY_FP_5,
+ ACTIVITY_FP_6,
+ ACTIVITY_FP_7,
+
+ /* L2 cache counters */
+ COUNTER_L2_0_C0,
+ COUNTER_L2_0_C1,
+ COUNTER_L2_1_C0,
+ COUNTER_L2_1_C1,
+ COUNTER_L2_2_C0,
+ COUNTER_L2_2_C1,
+
+ /* Vertex processor counters */
+ COUNTER_VP_0_C0,
+ COUNTER_VP_0_C1,
+
+ /* Fragment processor counters */
+ COUNTER_FP_0_C0,
+ COUNTER_FP_0_C1,
+ COUNTER_FP_1_C0,
+ COUNTER_FP_1_C1,
+ COUNTER_FP_2_C0,
+ COUNTER_FP_2_C1,
+ COUNTER_FP_3_C0,
+ COUNTER_FP_3_C1,
+ COUNTER_FP_4_C0,
+ COUNTER_FP_4_C1,
+ COUNTER_FP_5_C0,
+ COUNTER_FP_5_C1,
+ COUNTER_FP_6_C0,
+ COUNTER_FP_6_C1,
+ COUNTER_FP_7_C0,
+ COUNTER_FP_7_C1,
+
+ /*
+ * If more hardware counters are added, the _mali_osk_hw_counter_table
+ * below should also be updated.
+ */
+
+ /* EGL software counters */
+ COUNTER_EGL_BLIT_TIME,
+
+ /* GLES software counters */
+ COUNTER_GLES_DRAW_ELEMENTS_CALLS,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_INDICES,
+ COUNTER_GLES_DRAW_ELEMENTS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_ARRAYS_CALLS,
+ COUNTER_GLES_DRAW_ARRAYS_NUM_TRANSFORMED,
+ COUNTER_GLES_DRAW_POINTS,
+ COUNTER_GLES_DRAW_LINES,
+ COUNTER_GLES_DRAW_LINE_LOOP,
+ COUNTER_GLES_DRAW_LINE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLES,
+ COUNTER_GLES_DRAW_TRIANGLE_STRIP,
+ COUNTER_GLES_DRAW_TRIANGLE_FAN,
+ COUNTER_GLES_NON_VBO_DATA_COPY_TIME,
+ COUNTER_GLES_UNIFORM_BYTES_COPIED_TO_MALI,
+ COUNTER_GLES_UPLOAD_TEXTURE_TIME,
+ COUNTER_GLES_UPLOAD_VBO_TIME,
+ COUNTER_GLES_NUM_FLUSHES,
+ COUNTER_GLES_NUM_VSHADERS_GENERATED,
+ COUNTER_GLES_NUM_FSHADERS_GENERATED,
+ COUNTER_GLES_VSHADER_GEN_TIME,
+ COUNTER_GLES_FSHADER_GEN_TIME,
+ COUNTER_GLES_INPUT_TRIANGLES,
+ COUNTER_GLES_VXCACHE_HIT,
+ COUNTER_GLES_VXCACHE_MISS,
+ COUNTER_GLES_VXCACHE_COLLISION,
+ COUNTER_GLES_CULLED_TRIANGLES,
+ COUNTER_GLES_CULLED_LINES,
+ COUNTER_GLES_BACKFACE_TRIANGLES,
+ COUNTER_GLES_GBCLIP_TRIANGLES,
+ COUNTER_GLES_GBCLIP_LINES,
+ COUNTER_GLES_TRIANGLES_DRAWN,
+ COUNTER_GLES_DRAWCALL_TIME,
+ COUNTER_GLES_TRIANGLES_COUNT,
+ COUNTER_GLES_INDEPENDENT_TRIANGLES_COUNT,
+ COUNTER_GLES_STRIP_TRIANGLES_COUNT,
+ COUNTER_GLES_FAN_TRIANGLES_COUNT,
+ COUNTER_GLES_LINES_COUNT,
+ COUNTER_GLES_INDEPENDENT_LINES_COUNT,
+ COUNTER_GLES_STRIP_LINES_COUNT,
+ COUNTER_GLES_LOOP_LINES_COUNT,
+
+ /* Framebuffer capture pseudo-counter */
+ COUNTER_FILMSTRIP,
+
+ NUMBER_OF_EVENTS
+} _mali_osk_counter_id;
+
+#define FIRST_ACTIVITY_EVENT ACTIVITY_VP_0
+#define LAST_ACTIVITY_EVENT ACTIVITY_FP_7
+
+#define FIRST_HW_COUNTER COUNTER_L2_0_C0
+#define LAST_HW_COUNTER COUNTER_FP_7_C1
+
+#define FIRST_SW_COUNTER COUNTER_EGL_BLIT_TIME
+#define LAST_SW_COUNTER COUNTER_GLES_LOOP_LINES_COUNT
+
+#define FIRST_SPECIAL_COUNTER COUNTER_FILMSTRIP
+#define LAST_SPECIAL_COUNTER COUNTER_FILMSTRIP
+
+/**
+ * Structure to pass performance counter data of a Mali core
+ */
+typedef struct _mali_profiling_core_counters
+{
+ u32 source0;
+ u32 value0;
+ u32 source1;
+ u32 value1;
+} _mali_profiling_core_counters;
+
+/**
+ * Structure to pass performance counter data of Mali L2 cache cores
+ */
+typedef struct _mali_profiling_l2_counter_values
+{
+ struct _mali_profiling_core_counters cores[MAX_NUM_L2_CACHE_CORES];
+} _mali_profiling_l2_counter_values;
+
+/**
+ * Structure to pass data defining Mali instance in use:
+ *
+ * mali_product_id - Mali product id
+ * mali_version_major - Mali version major number
+ * mali_version_minor - Mali version minor number
+ * num_of_l2_cores - number of L2 cache cores
+ * num_of_fp_cores - number of fragment processor cores
+ * num_of_vp_cores - number of vertex processor cores
+ */
+typedef struct _mali_profiling_mali_version
+{
+ u32 mali_product_id;
+ u32 mali_version_major;
+ u32 mali_version_minor;
+ u32 num_of_l2_cores;
+ u32 num_of_fp_cores;
+ u32 num_of_vp_cores;
+} _mali_profiling_mali_version;
+
+/*
+ * List of possible actions to be controlled by Streamline.
+ * The following numbers are used by gator to control the frame buffer dumping and s/w counter reporting.
+ * We cannot use the enums in mali_uk_types.h because they are unknown inside gator.
+ */
+#define FBDUMP_CONTROL_ENABLE (1)
+#define FBDUMP_CONTROL_RATE (2)
+#define SW_COUNTER_ENABLE (3)
+#define FBDUMP_CONTROL_RESIZE_FACTOR (4)
+
+void _mali_profiling_control(u32 action, u32 value);
+
+u32 _mali_profiling_get_l2_counters(_mali_profiling_l2_counter_values *values);
+
+int _mali_profiling_set_event(u32 counter_id, s32 event_id);
+
+u32 _mali_profiling_get_api_version(void);
+
+void _mali_profiling_get_mali_version(struct _mali_profiling_mali_version *values);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_UTGARD_PROFILING_GATOR_API_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h
new file mode 100644
index 0000000..4957095
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/include/linux/mali/mali_utgard_uk_types.h
@@ -0,0 +1,1165 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_uk_types.h
+ * Defines the types and constants used in the user-kernel interface
+ */
+
+#ifndef __MALI_UTGARD_UK_TYPES_H__
+#define __MALI_UTGARD_UK_TYPES_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @addtogroup uddapi Unified Device Driver (UDD) APIs
+ *
+ * @{
+ */
+
+/**
+ * @addtogroup u_k_api UDD User/Kernel Interface (U/K) APIs
+ *
+ * @{
+ */
+
+/** @defgroup _mali_uk_core U/K Core
+ * @{ */
+
+/** Definition of subsystem numbers, to assist in creating a unique identifier
+ * for each U/K call.
+ *
+ * @see _mali_uk_functions */
+typedef enum
+{
+ _MALI_UK_CORE_SUBSYSTEM, /**< Core Group of U/K calls */
+ _MALI_UK_MEMORY_SUBSYSTEM, /**< Memory Group of U/K calls */
+ _MALI_UK_PP_SUBSYSTEM, /**< Fragment Processor Group of U/K calls */
+ _MALI_UK_GP_SUBSYSTEM, /**< Vertex Processor Group of U/K calls */
+ _MALI_UK_PROFILING_SUBSYSTEM, /**< Profiling Group of U/K calls */
+ _MALI_UK_PMM_SUBSYSTEM, /**< Power Management Module Group of U/K calls */
+ _MALI_UK_VSYNC_SUBSYSTEM, /**< VSYNC Group of U/K calls */
+} _mali_uk_subsystem_t;
+
+/** Within a function group each function has its unique sequence number
+ * to assist in creating a unique identifier for each U/K call.
+ *
+ * An ordered pair of numbers selected from
+ * ( \ref _mali_uk_subsystem_t,\ref _mali_uk_functions) will uniquely identify the
+ * U/K call across all groups of functions, and all functions. */
+typedef enum
+{
+ /** Core functions */
+
+ _MALI_UK_OPEN = 0, /**< _mali_ukk_open() */
+ _MALI_UK_CLOSE, /**< _mali_ukk_close() */
+ _MALI_UK_WAIT_FOR_NOTIFICATION, /**< _mali_ukk_wait_for_notification() */
+ _MALI_UK_GET_API_VERSION, /**< _mali_ukk_get_api_version() */
+ _MALI_UK_POST_NOTIFICATION, /**< _mali_ukk_post_notification() */
+ _MALI_UK_GET_USER_SETTING, /**< _mali_ukk_get_user_setting() *//**< [out] */
+ _MALI_UK_GET_USER_SETTINGS, /**< _mali_ukk_get_user_settings() *//**< [out] */
+ _MALI_UK_STREAM_CREATE, /**< _mali_ukk_stream_create() */
+ _MALI_UK_FENCE_CREATE_EMPTY, /**< _mali_ukk_fence_create_empty() */
+ _MALI_UK_FENCE_VALIDATE, /**< _mali_ukk_fence_validate() */
+
+ /** Memory functions */
+
+ _MALI_UK_INIT_MEM = 0, /**< _mali_ukk_init_mem() */
+ _MALI_UK_TERM_MEM, /**< _mali_ukk_term_mem() */
+ _MALI_UK_GET_BIG_BLOCK, /**< _mali_ukk_get_big_block() */
+ _MALI_UK_FREE_BIG_BLOCK, /**< _mali_ukk_free_big_block() */
+ _MALI_UK_MAP_MEM, /**< _mali_ukk_mem_mmap() */
+ _MALI_UK_UNMAP_MEM, /**< _mali_ukk_mem_munmap() */
+ _MALI_UK_QUERY_MMU_PAGE_TABLE_DUMP_SIZE, /**< _mali_ukk_mem_get_mmu_page_table_dump_size() */
+ _MALI_UK_DUMP_MMU_PAGE_TABLE, /**< _mali_ukk_mem_dump_mmu_page_table() */
+ _MALI_UK_ATTACH_DMA_BUF, /**< _mali_ukk_attach_dma_buf() */
+ _MALI_UK_RELEASE_DMA_BUF, /**< _mali_ukk_release_dma_buf() */
+ _MALI_UK_DMA_BUF_GET_SIZE, /**< _mali_ukk_dma_buf_get_size() */
+ _MALI_UK_ATTACH_UMP_MEM, /**< _mali_ukk_attach_ump_mem() */
+ _MALI_UK_RELEASE_UMP_MEM, /**< _mali_ukk_release_ump_mem() */
+ _MALI_UK_MAP_EXT_MEM, /**< _mali_uku_map_external_mem() */
+ _MALI_UK_UNMAP_EXT_MEM, /**< _mali_uku_unmap_external_mem() */
+ _MALI_UK_VA_TO_MALI_PA, /**< _mali_uku_va_to_mali_pa() */
+ _MALI_UK_MEM_WRITE_SAFE, /**< _mali_uku_mem_write_safe() */
+
+ /** Common functions for each core */
+
+ _MALI_UK_START_JOB = 0, /**< Start a Fragment/Vertex Processor Job on a core */
+ _MALI_UK_GET_NUMBER_OF_CORES, /**< Get the number of Fragment/Vertex Processor cores */
+ _MALI_UK_GET_CORE_VERSION, /**< Get the Fragment/Vertex Processor version compatible with all cores */
+
+ /** Fragment Processor Functions */
+
+ _MALI_UK_PP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_pp_start_job() */
+ _MALI_UK_GET_PP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_pp_number_of_cores() */
+ _MALI_UK_GET_PP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_pp_core_version() */
+ _MALI_UK_PP_DISABLE_WB, /**< _mali_ukk_pp_job_disable_wb() */
+
+ /** Vertex Processor Functions */
+
+ _MALI_UK_GP_START_JOB = _MALI_UK_START_JOB, /**< _mali_ukk_gp_start_job() */
+ _MALI_UK_GET_GP_NUMBER_OF_CORES = _MALI_UK_GET_NUMBER_OF_CORES, /**< _mali_ukk_get_gp_number_of_cores() */
+ _MALI_UK_GET_GP_CORE_VERSION = _MALI_UK_GET_CORE_VERSION, /**< _mali_ukk_get_gp_core_version() */
+ _MALI_UK_GP_SUSPEND_RESPONSE, /**< _mali_ukk_gp_suspend_response() */
+
+ /** Profiling functions */
+
+ _MALI_UK_PROFILING_START = 0, /**< __mali_uku_profiling_start() */
+ _MALI_UK_PROFILING_ADD_EVENT, /**< __mali_uku_profiling_add_event() */
+ _MALI_UK_PROFILING_STOP, /**< __mali_uku_profiling_stop() */
+ _MALI_UK_PROFILING_GET_EVENT, /**< __mali_uku_profiling_get_event() */
+ _MALI_UK_PROFILING_CLEAR, /**< __mali_uku_profiling_clear() */
+ _MALI_UK_PROFILING_GET_CONFIG, /**< __mali_uku_profiling_get_config() */
+ _MALI_UK_PROFILING_REPORT_SW_COUNTERS,/**< __mali_uku_profiling_report_sw_counters() */
+
+ /** VSYNC reporting fuctions */
+ _MALI_UK_VSYNC_EVENT_REPORT = 0, /**< _mali_ukk_vsync_event_report() */
+
+} _mali_uk_functions;
+
+/** @brief Get the size necessary for system info
+ *
+ * @see _mali_ukk_get_system_info_size()
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 size; /**< [out] size of buffer necessary to hold system information data, in bytes */
+} _mali_uk_get_system_info_size_s;
+
+
+/** @defgroup _mali_uk_getsysteminfo U/K Get System Info
+ * @{ */
+
+/**
+ * Type definition for the core version number.
+ * Used when returning the version number read from a core
+ *
+ * Its format is that of the 32-bit Version register for a particular core.
+ * Refer to the "Mali200 and MaliGP2 3D Graphics Processor Technical Reference
+ * Manual", ARM DDI 0415C, for more information.
+ */
+typedef u32 _mali_core_version;
+
+/**
+ * Enum values for the different modes the driver can be put in.
+ * Normal is the default mode. The driver then uses a job queue and takes job objects from the clients.
+ * Job completion is reported using the _mali_ukk_wait_for_notification call.
+ * The driver blocks this io command until a job has completed or failed or a timeout occurs.
+ *
+ * The 'raw' mode is reserved for future expansion.
+ */
+typedef enum _mali_driver_mode
+{
+ _MALI_DRIVER_MODE_RAW = 1, /**< Reserved for future expansion */
+ _MALI_DRIVER_MODE_NORMAL = 2 /**< Normal mode of operation */
+} _mali_driver_mode;
+
+/** @brief List of possible cores
+ *
+ * add new entries to the end of this enum */
+typedef enum _mali_core_type
+{
+ _MALI_GP2 = 2, /**< MaliGP2 Programmable Vertex Processor */
+ _MALI_200 = 5, /**< Mali200 Programmable Fragment Processor */
+ _MALI_400_GP = 6, /**< Mali400 Programmable Vertex Processor */
+ _MALI_400_PP = 7, /**< Mali400 Programmable Fragment Processor */
+ /* insert new core here, do NOT alter the existing values */
+} _mali_core_type;
+
+
+/** @brief Capabilities of Memory Banks
+ *
+ * These may be used to restrict memory banks for certain uses. They may be
+ * used when access is not possible (e.g. Bus does not support access to it)
+ * or when access is possible but not desired (e.g. Access is slow).
+ *
+ * In the case of 'possible but not desired', there is no way of specifying
+ * the flags as an optimization hint, so that the memory could be used as a
+ * last resort.
+ *
+ * @see _mali_mem_info
+ */
+typedef enum _mali_bus_usage
+{
+
+ _MALI_PP_READABLE = (1<<0), /** Readable by the Fragment Processor */
+ _MALI_PP_WRITEABLE = (1<<1), /** Writeable by the Fragment Processor */
+ _MALI_GP_READABLE = (1<<2), /** Readable by the Vertex Processor */
+ _MALI_GP_WRITEABLE = (1<<3), /** Writeable by the Vertex Processor */
+ _MALI_CPU_READABLE = (1<<4), /** Readable by the CPU */
+ _MALI_CPU_WRITEABLE = (1<<5), /** Writeable by the CPU */
+ _MALI_GP_L2_ALLOC = (1<<6), /** GP allocate mali L2 cache lines*/
+ _MALI_MMU_READABLE = _MALI_PP_READABLE | _MALI_GP_READABLE, /** Readable by the MMU (including all cores behind it) */
+ _MALI_MMU_WRITEABLE = _MALI_PP_WRITEABLE | _MALI_GP_WRITEABLE, /** Writeable by the MMU (including all cores behind it) */
+} _mali_bus_usage;
+
+typedef enum mali_memory_cache_settings
+{
+ MALI_CACHE_STANDARD = 0,
+ MALI_CACHE_GP_READ_ALLOCATE = 1,
+} mali_memory_cache_settings ;
+
+
+/** @brief Information about the Mali Memory system
+ *
+ * Information is stored in a linked list, which is stored entirely in the
+ * buffer pointed to by the system_info member of the
+ * _mali_uk_get_system_info_s arguments provided to _mali_ukk_get_system_info()
+ *
+ * Each element of the linked list describes a single Mali Memory bank.
+ * Each allocation can only come from one bank, and will not cross multiple
+ * banks.
+ *
+ * On Mali-MMU systems, there is only one bank, which describes the maximum
+ * possible address range that could be allocated (which may be much less than
+ * the available physical memory)
+ *
+ * The flags member describes the capabilities of the memory. It is an error
+ * to attempt to build a job for a particular core (PP or GP) when the memory
+ * regions used do not have the capabilities for supporting that core. This
+ * would result in a job abort from the Device Driver.
+ *
+ * For example, it is correct to build a PP job where read-only data structures
+ * are taken from a memory with _MALI_PP_READABLE set and
+ * _MALI_PP_WRITEABLE clear, and a framebuffer with _MALI_PP_WRITEABLE set and
+ * _MALI_PP_READABLE clear. However, it would be incorrect to use a framebuffer
+ * where _MALI_PP_WRITEABLE is clear.
+ */
+typedef struct _mali_mem_info
+{
+ u32 size; /**< Size of the memory bank in bytes */
+ _mali_bus_usage flags; /**< Capabilitiy flags of the memory */
+ u32 maximum_order_supported; /**< log2 supported size */
+ u32 identifier; /* mali_memory_cache_settings cache_settings; */
+ struct _mali_mem_info * next; /**< Next List Link */
+} _mali_mem_info;
+
+
+
+/** @} */ /* end group _mali_uk_core */
+
+
+/** @defgroup _mali_uk_gp U/K Vertex Processor
+ * @{ */
+
+/** @defgroup _mali_uk_gp_suspend_response_s Vertex Processor Suspend Response
+ * @{ */
+
+/** @brief Arguments for _mali_ukk_gp_suspend_response()
+ *
+ * When _mali_wait_for_notification() receives notification that a
+ * Vertex Processor job was suspended, you need to send a response to indicate
+ * what needs to happen with this job. You can either abort or resume the job.
+ *
+ * - set @c code to indicate response code. This is either @c _MALIGP_JOB_ABORT or
+ * @c _MALIGP_JOB_RESUME_WITH_NEW_HEAP to indicate you will provide a new heap
+ * for the job that will resolve the out of memory condition for the job.
+ * - copy the @c cookie value from the @c _mali_uk_gp_job_suspended_s notification;
+ * this is an identifier for the suspended job
+ * - set @c arguments[0] and @c arguments[1] to zero if you abort the job. If
+ * you resume it, @c argument[0] should specify the Mali start address for the new
+ * heap and @c argument[1] the Mali end address of the heap.
+ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
+ *
+ */
+typedef enum _maligp_job_suspended_response_code
+{
+ _MALIGP_JOB_ABORT, /**< Abort the Vertex Processor job */
+ _MALIGP_JOB_RESUME_WITH_NEW_HEAP /**< Resume the Vertex Processor job with a new heap */
+} _maligp_job_suspended_response_code;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 cookie; /**< [in] cookie from the _mali_uk_gp_job_suspended_s notification */
+ _maligp_job_suspended_response_code code; /**< [in] abort or resume response code, see \ref _maligp_job_suspended_response_code */
+ u32 arguments[2]; /**< [in] 0 when aborting a job. When resuming a job, the Mali start and end address for a new heap to resume the job with */
+} _mali_uk_gp_suspend_response_s;
+
+/** @} */ /* end group _mali_uk_gp_suspend_response_s */
+
+/** @defgroup _mali_uk_gpstartjob_s Vertex Processor Start Job
+ * @{ */
+
+/** @brief Status indicating the result of starting a Vertex or Fragment processor job */
+typedef enum
+{
+ _MALI_UK_START_JOB_STARTED, /**< Job started */
+ _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE /**< Job could not be started at this time. Try starting the job again */
+} _mali_uk_start_job_status;
+
+/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job */
+
+typedef enum
+{
+ _MALI_UK_JOB_STATUS_END_SUCCESS = 1<<(16+0),
+ _MALI_UK_JOB_STATUS_END_OOM = 1<<(16+1),
+ _MALI_UK_JOB_STATUS_END_ABORT = 1<<(16+2),
+ _MALI_UK_JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3),
+ _MALI_UK_JOB_STATUS_END_HANG = 1<<(16+4),
+ _MALI_UK_JOB_STATUS_END_SEG_FAULT = 1<<(16+5),
+ _MALI_UK_JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6),
+ _MALI_UK_JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7),
+ _MALI_UK_JOB_STATUS_END_SHUTDOWN = 1<<(16+8),
+ _MALI_UK_JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9)
+} _mali_uk_job_status;
+
+#define MALIGP2_NUM_REGS_FRAME (6)
+
+/** @brief Arguments for _mali_ukk_gp_start_job()
+ *
+ * To start a Vertex Processor job
+ * - associate the request with a reference to a @c mali_gp_job_info by setting
+ * user_job_ptr to the address of the @c mali_gp_job_info of the job.
+ * - set @c priority to the priority of the @c mali_gp_job_info
+ * - specify a timeout for the job by setting @c watchdog_msecs to the number of
+ * milliseconds the job is allowed to run. Specifying a value of 0 selects the
+ * default timeout in use by the device driver.
+ * - copy the frame registers from the @c mali_gp_job_info into @c frame_registers.
+ * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero
+ * for a non-instrumented build. For an instrumented build you can use up
+ * to two performance counters. Set the corresponding bit in @c perf_counter_flag
+ * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify
+ * the source of what needs to get counted (e.g. number of vertex loader
+ * cache hits). For source id values, see ARM DDI0415A, Table 3-60.
+ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
+ *
+ * When @c _mali_ukk_gp_start_job() returns @c _MALI_OSK_ERR_OK, status contains the
+ * result of the request (see \ref _mali_uk_start_job_status). If the job could
+ * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be
+ * tried again.
+ *
+ * After the job has started, @c _mali_wait_for_notification() will be notified
+ * that the job finished or got suspended. It may get suspended due to
+ * resource shortage. If it finished (see _mali_ukk_wait_for_notification())
+ * the notification will contain a @c _mali_uk_gp_job_finished_s result. If
+ * it got suspended the notification will contain a @c _mali_uk_gp_job_suspended_s
+ * result.
+ *
+ * The @c _mali_uk_gp_job_finished_s contains the job status (see \ref _mali_uk_job_status),
+ * the number of milliseconds the job took to render, and values of core registers
+ * when the job finished (irq status, performance counters, renderer list
+ * address). A job has finished succesfully when its status is
+ * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering
+ * the job, or software detected the job is taking more than watchdog_msecs to
+ * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG.
+ * If the hardware detected a bus error while accessing memory associated with the
+ * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT.
+ * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to
+ * stop the job but the job didn't start on the hardware yet, e.g. when the
+ * driver shutdown.
+ *
+ * In case the job got suspended, @c _mali_uk_gp_job_suspended_s contains
+ * the @c user_job_ptr identifier used to start the job with, the @c reason
+ * why the job stalled (see \ref _maligp_job_suspended_reason) and a @c cookie
+ * to identify the core on which the job stalled. This @c cookie will be needed
+ * when responding to this nofication by means of _mali_ukk_gp_suspend_response().
+ * (see _mali_ukk_gp_suspend_response()). The response is either to abort or
+ * resume the job. If the job got suspended due to an out of memory condition
+ * you may be able to resolve this by providing more memory and resuming the job.
+ *
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 user_job_ptr; /**< [in] identifier for the job in user space, a @c mali_gp_job_info* */
+ u32 priority; /**< [in] job priority. A lower number means higher priority */
+ u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job */
+ u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
+ u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
+ u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
+ u32 frame_builder_id; /**< [in] id of the originating frame builder */
+ u32 flush_id; /**< [in] flush id within the originating frame builder */
+} _mali_uk_gp_start_job_s;
+
+#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE (1<<0) /**< Enable performance counter SRC0 for a job */
+#define _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE (1<<1) /**< Enable performance counter SRC1 for a job */
+
+/** @} */ /* end group _mali_uk_gpstartjob_s */
+
+typedef struct
+{
+ u32 user_job_ptr; /**< [out] identifier for the job in user space */
+ _mali_uk_job_status status; /**< [out] status of finished job */
+ u32 heap_current_addr; /**< [out] value of the GP PLB PL heap start address register */
+ u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */
+ u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */
+} _mali_uk_gp_job_finished_s;
+
+typedef enum _maligp_job_suspended_reason
+{
+ _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY /**< Polygon list builder unit (PLBU) has run out of memory */
+} _maligp_job_suspended_reason;
+
+typedef struct
+{
+ u32 user_job_ptr; /**< [out] identifier for the job in user space */
+ _maligp_job_suspended_reason reason; /**< [out] reason why the job stalled */
+ u32 cookie; /**< [out] identifier for the core in kernel space on which the job stalled */
+} _mali_uk_gp_job_suspended_s;
+
+/** @} */ /* end group _mali_uk_gp */
+
+
+/** @defgroup _mali_uk_pp U/K Fragment Processor
+ * @{ */
+
+#define _MALI_PP_MAX_SUB_JOBS 8
+
+#define _MALI_PP_MAX_FRAME_REGISTERS ((0x058/4)+1)
+
+#define _MALI_PP_MAX_WB_REGISTERS ((0x02C/4)+1)
+
+#define _MALI_DLBU_MAX_REGISTERS 4
+
+/** Flag for _mali_uk_pp_start_job_s */
+#define _MALI_PP_JOB_FLAG_NO_NOTIFICATION (1<<0)
+#define _MALI_PP_JOB_FLAG_BARRIER (1<<1)
+#define _MALI_PP_JOB_FLAG_FENCE (1<<2)
+#define _MALI_PP_JOB_FLAG_EMPTY_FENCE (1<<3)
+
+/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job
+ * @{ */
+
+/** @brief Arguments for _mali_ukk_pp_start_job()
+ *
+ * To start a Fragment Processor job
+ * - associate the request with a reference to a mali_pp_job by setting
+ * @c user_job_ptr to the address of the @c mali_pp_job of the job.
+ * - set @c priority to the priority of the mali_pp_job
+ * - specify a timeout for the job by setting @c watchdog_msecs to the number of
+ * milliseconds the job is allowed to run. Specifying a value of 0 selects the
+ * default timeout in use by the device driver.
+ * - copy the frame registers from the @c mali_pp_job into @c frame_registers.
+ * For MALI200 you also need to copy the write back 0,1 and 2 registers.
+ * - set the @c perf_counter_flag, @c perf_counter_src0 and @c perf_counter_src1 to zero
+ * for a non-instrumented build. For an instrumented build you can use up
+ * to two performance counters. Set the corresponding bit in @c perf_counter_flag
+ * to enable them. @c perf_counter_src0 and @c perf_counter_src1 specify
+ * the source of what needs to get counted (e.g. number of vertex loader
+ * cache hits). For source id values, see ARM DDI0415A, Table 3-60.
+ * - pass in the user-kernel context in @c ctx that was returned from _mali_ukk_open()
+ *
+ * When _mali_ukk_pp_start_job() returns @c _MALI_OSK_ERR_OK, @c status contains the
+ * result of the request (see \ref _mali_uk_start_job_status). If the job could
+ * not get started (@c _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE) it should be
+ * tried again.
+ *
+ * After the job has started, _mali_wait_for_notification() will be notified
+ * when the job finished. The notification will contain a
+ * @c _mali_uk_pp_job_finished_s result. It contains the @c user_job_ptr
+ * identifier used to start the job with, the job @c status (see \ref _mali_uk_job_status),
+ * the number of milliseconds the job took to render, and values of core registers
+ * when the job finished (irq status, performance counters, renderer list
+ * address). A job has finished succesfully when its status is
+ * @c _MALI_UK_JOB_STATUS_FINISHED. If the hardware detected a timeout while rendering
+ * the job, or software detected the job is taking more than @c watchdog_msecs to
+ * complete, the status will indicate @c _MALI_UK_JOB_STATUS_HANG.
+ * If the hardware detected a bus error while accessing memory associated with the
+ * job, status will indicate @c _MALI_UK_JOB_STATUS_SEG_FAULT.
+ * status will indicate @c _MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to
+ * stop the job but the job didn't start on the hardware yet, e.g. when the
+ * driver shutdown.
+ *
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 user_job_ptr; /**< [in] identifier for the job in user space */
+ u32 priority; /**< [in] job priority. A lower number means higher priority */
+ u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< [in] core specific registers associated with first sub job, see ARM DDI0415A */
+ u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_FRAME registers for sub job 1-7 */
+ u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< [in] ADDR_STACK registers for sub job 1-7 */
+ u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS];
+ u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS];
+ u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS];
+ u32 dlbu_registers[_MALI_DLBU_MAX_REGISTERS]; /**< [in] Dynamic load balancing unit registers */
+ u32 num_cores; /**< [in] Number of cores to set up (valid range: 1-4) */
+ u32 perf_counter_flag; /**< [in] bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
+ u32 perf_counter_src0; /**< [in] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
+ u32 perf_counter_src1; /**< [in] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
+ u32 frame_builder_id; /**< [in] id of the originating frame builder */
+ u32 flush_id; /**< [in] flush id within the originating frame builder */
+ u32 flags; /**< [in] See _MALI_PP_JOB_FLAG_* for a list of avaiable flags */
+ s32 fence; /**< [in,out] Fence to wait on / fence that will be signalled on job completion, if _MALI_PP_JOB_FLAG_FENCE is set */
+ s32 stream; /**< [in] Steam identifier if _MALI_PP_JOB_FLAG_FENCE, an empty fence to use for this job if _MALI_PP_JOB_FLAG_EMPTY_FENCE is set */
+ u32 num_memory_cookies; /**< [in] number of memory cookies attached to job */
+ u32 *memory_cookies; /**< [in] memory cookies attached to job */
+} _mali_uk_pp_start_job_s;
+/** @} */ /* end group _mali_uk_ppstartjob_s */
+
+typedef struct
+{
+ u32 user_job_ptr; /**< [out] identifier for the job in user space */
+ _mali_uk_job_status status; /**< [out] status of finished job */
+ u32 perf_counter0[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 0 (see ARM DDI0415A), one for each sub job */
+ u32 perf_counter1[_MALI_PP_MAX_SUB_JOBS]; /**< [out] value of perfomance counter 1 (see ARM DDI0415A), one for each sub job */
+} _mali_uk_pp_job_finished_s;
+
+typedef struct
+{
+ u32 number_of_enabled_cores; /**< [out] the new number of enabled cores */
+} _mali_uk_pp_num_cores_changed_s;
+
+
+
+/**
+ * Flags to indicate write-back units
+ */
+typedef enum
+{
+ _MALI_UK_PP_JOB_WB0 = 1,
+ _MALI_UK_PP_JOB_WB1 = 2,
+ _MALI_UK_PP_JOB_WB2 = 4,
+} _mali_uk_pp_job_wbx_flag;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 fb_id; /**< [in] Frame builder ID of job to disable WB units for */
+ u32 flush_id; /**< [in] Flush ID of job to disable WB units for */
+ _mali_uk_pp_job_wbx_flag wbx; /**< [in] write-back units to disable */
+} _mali_uk_pp_disable_wb_s;
+
+
+/** @} */ /* end group _mali_uk_pp */
+
+
+/** @addtogroup _mali_uk_core U/K Core
+ * @{ */
+
+/** @defgroup _mali_uk_waitfornotification_s Wait For Notification
+ * @{ */
+
+/** @brief Notification type encodings
+ *
+ * Each Notification type is an ordered pair of (subsystem,id), and is unique.
+ *
+ * The encoding of subsystem,id into a 32-bit word is:
+ * encoding = (( subsystem << _MALI_NOTIFICATION_SUBSYSTEM_SHIFT ) & _MALI_NOTIFICATION_SUBSYSTEM_MASK)
+ * | (( id << _MALI_NOTIFICATION_ID_SHIFT ) & _MALI_NOTIFICATION_ID_MASK)
+ *
+ * @see _mali_uk_wait_for_notification_s
+ */
+typedef enum
+{
+ /** core notifications */
+
+ _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x20,
+ _MALI_NOTIFICATION_APPLICATION_QUIT = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x40,
+ _MALI_NOTIFICATION_SETTINGS_CHANGED = (_MALI_UK_CORE_SUBSYSTEM << 16) | 0x80,
+
+ /** Fragment Processor notifications */
+
+ _MALI_NOTIFICATION_PP_FINISHED = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x10,
+ _MALI_NOTIFICATION_PP_NUM_CORE_CHANGE = (_MALI_UK_PP_SUBSYSTEM << 16) | 0x20,
+
+ /** Vertex Processor notifications */
+
+ _MALI_NOTIFICATION_GP_FINISHED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x10,
+ _MALI_NOTIFICATION_GP_STALLED = (_MALI_UK_GP_SUBSYSTEM << 16) | 0x20,
+
+} _mali_uk_notification_type;
+
+/** to assist in splitting up 32-bit notification value in subsystem and id value */
+#define _MALI_NOTIFICATION_SUBSYSTEM_MASK 0xFFFF0000
+#define _MALI_NOTIFICATION_SUBSYSTEM_SHIFT 16
+#define _MALI_NOTIFICATION_ID_MASK 0x0000FFFF
+#define _MALI_NOTIFICATION_ID_SHIFT 0
+
+
+/** @brief Enumeration of possible settings which match mali_setting_t in user space
+ *
+ *
+ */
+typedef enum
+{
+ _MALI_UK_USER_SETTING_SW_EVENTS_ENABLE = 0,
+ _MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED,
+ _MALI_UK_USER_SETTING_DEPTHBUFFER_CAPTURE_ENABLED,
+ _MALI_UK_USER_SETTING_STENCILBUFFER_CAPTURE_ENABLED,
+ _MALI_UK_USER_SETTING_PER_TILE_COUNTERS_CAPTURE_ENABLED,
+ _MALI_UK_USER_SETTING_BUFFER_CAPTURE_COMPOSITOR,
+ _MALI_UK_USER_SETTING_BUFFER_CAPTURE_WINDOW,
+ _MALI_UK_USER_SETTING_BUFFER_CAPTURE_OTHER,
+ _MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES,
+ _MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR,
+ _MALI_UK_USER_SETTING_SW_COUNTER_ENABLED,
+ _MALI_UK_USER_SETTING_MAX,
+} _mali_uk_user_setting_t;
+
+/* See mali_user_settings_db.c */
+extern const char *_mali_uk_user_setting_descriptions[];
+#define _MALI_UK_USER_SETTING_DESCRIPTIONS \
+{ \
+ "sw_events_enable", \
+ "colorbuffer_capture_enable", \
+ "depthbuffer_capture_enable", \
+ "stencilbuffer_capture_enable", \
+ "per_tile_counters_enable", \
+ "buffer_capture_compositor", \
+ "buffer_capture_window", \
+ "buffer_capture_other", \
+ "buffer_capture_n_frames", \
+ "buffer_capture_resize_factor", \
+ "sw_counters_enable", \
+};
+
+/** @brief struct to hold the value to a particular setting as seen in the kernel space
+ */
+typedef struct
+{
+ _mali_uk_user_setting_t setting;
+ u32 value;
+} _mali_uk_settings_changed_s;
+
+/** @brief Arguments for _mali_ukk_wait_for_notification()
+ *
+ * On successful return from _mali_ukk_wait_for_notification(), the members of
+ * this structure will indicate the reason for notification.
+ *
+ * Specifically, the source of the notification can be identified by the
+ * subsystem and id fields of the mali_uk_notification_type in the code.type
+ * member. The type member is encoded in a way to divide up the types into a
+ * subsystem field, and a per-subsystem ID field. See
+ * _mali_uk_notification_type for more information.
+ *
+ * Interpreting the data union member depends on the notification type:
+ *
+ * - type == _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS
+ * - The kernel side is shutting down. No further
+ * _mali_uk_wait_for_notification() calls should be made.
+ * - In this case, the value of the data union member is undefined.
+ * - This is used to indicate to the user space client that it should close
+ * the connection to the Mali Device Driver.
+ * - type == _MALI_NOTIFICATION_PP_FINISHED
+ * - The notification data is of type _mali_uk_pp_job_finished_s. It contains the user_job_ptr
+ * identifier used to start the job with, the job status, the number of milliseconds the job took to render,
+ * and values of core registers when the job finished (irq status, performance counters, renderer list
+ * address).
+ * - A job has finished succesfully when its status member is _MALI_UK_JOB_STATUS_FINISHED.
+ * - If the hardware detected a timeout while rendering the job, or software detected the job is
+ * taking more than watchdog_msecs (see _mali_ukk_pp_start_job()) to complete, the status member will
+ * indicate _MALI_UK_JOB_STATUS_HANG.
+ * - If the hardware detected a bus error while accessing memory associated with the job, status will
+ * indicate _MALI_UK_JOB_STATUS_SEG_FAULT.
+ * - Status will indicate MALI_UK_JOB_STATUS_NOT_STARTED if the driver had to stop the job but the job
+ * didn't start the hardware yet, e.g. when the driver closes.
+ * - type == _MALI_NOTIFICATION_GP_FINISHED
+ * - The notification data is of type _mali_uk_gp_job_finished_s. The notification is similar to that of
+ * type == _MALI_NOTIFICATION_PP_FINISHED, except that several other GP core register values are returned.
+ * The status values have the same meaning for type == _MALI_NOTIFICATION_PP_FINISHED.
+ * - type == _MALI_NOTIFICATION_GP_STALLED
+ * - The nofication data is of type _mali_uk_gp_job_suspended_s. It contains the user_job_ptr
+ * identifier used to start the job with, the reason why the job stalled and a cookie to identify the core on
+ * which the job stalled.
+ * - The reason member of gp_job_suspended is set to _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY
+ * when the polygon list builder unit has run out of memory.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_uk_notification_type type; /**< [out] Type of notification available */
+ union
+ {
+ _mali_uk_gp_job_suspended_s gp_job_suspended;/**< [out] Notification data for _MALI_NOTIFICATION_GP_STALLED notification type */
+ _mali_uk_gp_job_finished_s gp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_GP_FINISHED notification type */
+ _mali_uk_pp_job_finished_s pp_job_finished; /**< [out] Notification data for _MALI_NOTIFICATION_PP_FINISHED notification type */
+ _mali_uk_settings_changed_s setting_changed;/**< [out] Notification data for _MALI_NOTIFICAATION_SETTINGS_CHANGED notification type */
+ } data;
+} _mali_uk_wait_for_notification_s;
+
+/** @brief Arguments for _mali_ukk_post_notification()
+ *
+ * Posts the specified notification to the notification queue for this application.
+ * This is used to send a quit message to the callback thread.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_uk_notification_type type; /**< [in] Type of notification to post */
+} _mali_uk_post_notification_s;
+
+/** @} */ /* end group _mali_uk_waitfornotification_s */
+
+/** @defgroup _mali_uk_getapiversion_s Get API Version
+ * @{ */
+
+/** helpers for Device Driver API version handling */
+
+/** @brief Encode a version ID from a 16-bit input
+ *
+ * @note the input is assumed to be 16 bits. It must not exceed 16 bits. */
+#define _MAKE_VERSION_ID(x) (((x) << 16UL) | (x))
+
+/** @brief Check whether a 32-bit value is likely to be Device Driver API
+ * version ID. */
+#define _IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF))
+
+/** @brief Decode a 16-bit version number from a 32-bit Device Driver API version
+ * ID */
+#define _GET_VERSION(x) (((x) >> 16UL) & 0xFFFF)
+
+/** @brief Determine whether two 32-bit encoded version IDs match */
+#define _IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y))))
+
+/**
+ * API version define.
+ * Indicates the version of the kernel API
+ * The version is a 16bit integer incremented on each API change.
+ * The 16bit integer is stored twice in a 32bit integer
+ * For example, for version 1 the value would be 0x00010001
+ */
+#define _MALI_API_VERSION 23
+#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
+
+/**
+ * The API version is a 16-bit integer stored in both the lower and upper 16-bits
+ * of a 32-bit value. The 16-bit API version value is incremented on each API
+ * change. Version 1 would be 0x00010001. Used in _mali_uk_get_api_version_s.
+ */
+typedef u32 _mali_uk_api_version;
+
+/** @brief Arguments for _mali_uk_get_api_version()
+ *
+ * The user-side interface version must be written into the version member,
+ * encoded using _MAKE_VERSION_ID(). It will be compared to the API version of
+ * the kernel-side interface.
+ *
+ * On successful return, the version member will be the API version of the
+ * kernel-side interface. _MALI_UK_API_VERSION macro defines the current version
+ * of the API.
+ *
+ * The compatible member must be checked to see if the version of the user-side
+ * interface is compatible with the kernel-side interface, since future versions
+ * of the interface may be backwards compatible.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_uk_api_version version; /**< [in,out] API version of user-side interface. */
+ int compatible; /**< [out] @c 1 when @version is compatible, @c 0 otherwise */
+} _mali_uk_get_api_version_s;
+/** @} */ /* end group _mali_uk_getapiversion_s */
+
+/** @defgroup _mali_uk_get_user_settings_s Get user space settings */
+
+/** @brief struct to keep the matching values of the user space settings within certain context
+ *
+ * Each member of the settings array corresponds to a matching setting in the user space and its value is the value
+ * of that particular setting.
+ *
+ * All settings are given reference to the context pointed to by the ctx pointer.
+ *
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 settings[_MALI_UK_USER_SETTING_MAX]; /**< [out] The values for all settings */
+} _mali_uk_get_user_settings_s;
+
+/** @brief struct to hold the value of a particular setting from the user space within a given context
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_uk_user_setting_t setting; /**< [in] setting to get */
+ u32 value; /**< [out] value of setting */
+} _mali_uk_get_user_setting_s;
+
+/** @} */ /* end group _mali_uk_core */
+
+
+/** @defgroup _mali_uk_memory U/K Memory
+ * @{ */
+
+/** @brief Arguments for _mali_ukk_init_mem(). */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 mali_address_base; /**< [out] start of MALI address space */
+ u32 memory_size; /**< [out] total MALI address space available */
+} _mali_uk_init_mem_s;
+
+/** @brief Arguments for _mali_ukk_term_mem(). */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+} _mali_uk_term_mem_s;
+
+/** Flag for _mali_uk_map_external_mem_s, _mali_uk_attach_ump_mem_s and _mali_uk_attach_dma_buf_s */
+#define _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE (1<<0)
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 phys_addr; /**< [in] physical address */
+ u32 size; /**< [in] size */
+ u32 mali_address; /**< [in] mali address to map the physical memory to */
+ u32 rights; /**< [in] rights necessary for accessing memory */
+ u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
+ u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
+} _mali_uk_map_external_mem_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
+} _mali_uk_unmap_external_mem_s;
+
+/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by memory descriptor */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 mem_fd; /**< [in] Memory descriptor */
+ u32 size; /**< [in] size */
+ u32 mali_address; /**< [in] mali address to map the physical memory to */
+ u32 rights; /**< [in] rights necessary for accessing memory */
+ u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
+ u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
+} _mali_uk_attach_dma_buf_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 mem_fd; /**< [in] Memory descriptor */
+ u32 size; /**< [out] size */
+} _mali_uk_dma_buf_get_size_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 cookie; /**< [in] identifier for mapped memory object in kernel space */
+} _mali_uk_release_dma_buf_s;
+
+/** @note This is identical to _mali_uk_map_external_mem_s above, however phys_addr is replaced by secure_id */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< [in] secure id */
+ u32 size; /**< [in] size */
+ u32 mali_address; /**< [in] mali address to map the physical memory to */
+ u32 rights; /**< [in] rights necessary for accessing memory */
+ u32 flags; /**< [in] flags, see \ref _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE */
+ u32 cookie; /**< [out] identifier for mapped memory object in kernel space */
+} _mali_uk_attach_ump_mem_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 cookie; /**< [in] identifier for mapped memory object in kernel space */
+} _mali_uk_release_ump_mem_s;
+
+/** @brief Arguments for _mali_ukk_va_to_mali_pa()
+ *
+ * if size is zero or not a multiple of the system's page size, it will be
+ * rounded up to the next multiple of the page size. This will occur before
+ * any other use of the size parameter.
+ *
+ * if va is not PAGE_SIZE aligned, it will be rounded down to the next page
+ * boundary.
+ *
+ * The range (va) to ((u32)va)+(size-1) inclusive will be checked for physical
+ * contiguity.
+ *
+ * The implementor will check that the entire physical range is allowed to be mapped
+ * into user-space.
+ *
+ * Failure will occur if either of the above are not satisfied.
+ *
+ * Otherwise, the physical base address of the range is returned through pa,
+ * va is updated to be page aligned, and size is updated to be a non-zero
+ * multiple of the system's pagesize.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ void *va; /**< [in,out] Virtual address of the start of the range */
+ u32 pa; /**< [out] Physical base address of the range */
+ u32 size; /**< [in,out] Size of the range, in bytes. */
+} _mali_uk_va_to_mali_pa_s;
+
+/**
+ * @brief Arguments for _mali_uk[uk]_mem_write_safe()
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ const void *src; /**< [in] Pointer to source data */
+ void *dest; /**< [in] Destination Mali buffer */
+ u32 size; /**< [in,out] Number of bytes to write/copy on input, number of bytes actually written/copied on output */
+} _mali_uk_mem_write_safe_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 size; /**< [out] size of MMU page table information (registers + page tables) */
+} _mali_uk_query_mmu_page_table_dump_size_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 size; /**< [in] size of buffer to receive mmu page table information */
+ void *buffer; /**< [in,out] buffer to receive mmu page table information */
+ u32 register_writes_size; /**< [out] size of MMU register dump */
+ u32 *register_writes; /**< [out] pointer within buffer where MMU register dump is stored */
+ u32 page_table_dump_size; /**< [out] size of MMU page table dump */
+ u32 *page_table_dump; /**< [out] pointer within buffer where MMU page table dump is stored */
+} _mali_uk_dump_mmu_page_table_s;
+
+/** @} */ /* end group _mali_uk_memory */
+
+
+/** @addtogroup _mali_uk_pp U/K Fragment Processor
+ * @{ */
+
+/** @brief Arguments for _mali_ukk_get_pp_number_of_cores()
+ *
+ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
+ * - Upon successful return from _mali_ukk_get_pp_number_of_cores(), @c number_of_cores
+ * will contain the number of Fragment Processor cores in the system.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 number_of_total_cores; /**< [out] Total number of Fragment Processor cores in the system */
+ u32 number_of_enabled_cores; /**< [out] Number of enabled Fragment Processor cores */
+} _mali_uk_get_pp_number_of_cores_s;
+
+/** @brief Arguments for _mali_ukk_get_pp_core_version()
+ *
+ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
+ * - Upon successful return from _mali_ukk_get_pp_core_version(), @c version contains
+ * the version that all Fragment Processor cores are compatible with.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */
+} _mali_uk_get_pp_core_version_s;
+
+/** @} */ /* end group _mali_uk_pp */
+
+
+/** @addtogroup _mali_uk_gp U/K Vertex Processor
+ * @{ */
+
+/** @brief Arguments for _mali_ukk_get_gp_number_of_cores()
+ *
+ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
+ * - Upon successful return from _mali_ukk_get_gp_number_of_cores(), @c number_of_cores
+ * will contain the number of Vertex Processor cores in the system.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 number_of_cores; /**< [out] number of Vertex Processor cores in the system */
+} _mali_uk_get_gp_number_of_cores_s;
+
+/** @brief Arguments for _mali_ukk_get_gp_core_version()
+ *
+ * - pass in the user-kernel context @c ctx that was returned from _mali_ukk_open()
+ * - Upon successful return from _mali_ukk_get_gp_core_version(), @c version contains
+ * the version that all Vertex Processor cores are compatible with.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */
+} _mali_uk_get_gp_core_version_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 limit; /**< [in,out] The desired limit for number of events to record on input, actual limit on output */
+} _mali_uk_profiling_start_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 event_id; /**< [in] event id to register (see enum mali_profiling_events for values) */
+ u32 data[5]; /**< [in] event specific data */
+} _mali_uk_profiling_add_event_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 count; /**< [out] The number of events sampled */
+} _mali_uk_profiling_stop_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 index; /**< [in] which index to get (starting at zero) */
+ u64 timestamp; /**< [out] timestamp of event */
+ u32 event_id; /**< [out] event id of event (see enum mali_profiling_events for values) */
+ u32 data[5]; /**< [out] event specific data */
+} _mali_uk_profiling_get_event_s;
+
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+} _mali_uk_profiling_clear_s;
+
+/** @} */ /* end group _mali_uk_gp */
+
+
+/** @addtogroup _mali_uk_memory U/K Memory
+ * @{ */
+
+/** @brief Arguments to _mali_ukk_mem_mmap()
+ *
+ * Use of the phys_addr member depends on whether the driver is compiled for
+ * Mali-MMU or nonMMU:
+ * - in the nonMMU case, this is the physical address of the memory as seen by
+ * the CPU (which may be a constant offset from that used by Mali)
+ * - in the MMU case, this is the Mali Virtual base address of the memory to
+ * allocate, and the particular physical pages used to back the memory are
+ * entirely determined by _mali_ukk_mem_mmap(). The details of the physical pages
+ * are not reported to user-space for security reasons.
+ *
+ * The cookie member must be stored for use later when freeing the memory by
+ * calling _mali_ukk_mem_munmap(). In the Mali-MMU case, the cookie is secure.
+ *
+ * The ukk_private word must be set to zero when calling from user-space. On
+ * Kernel-side, the OS implementation of the U/K interface can use it to
+ * communicate data to the OS implementation of the OSK layer. In particular,
+ * _mali_ukk_get_big_block() directly calls _mali_ukk_mem_mmap directly, and
+ * will communicate its own ukk_private word through the ukk_private member
+ * here. The common code itself will not inspect or modify the ukk_private
+ * word, and so it may be safely used for whatever purposes necessary to
+ * integrate Mali Memory handling into the OS.
+ *
+ * The uku_private member is currently reserved for use by the user-side
+ * implementation of the U/K interface. Its value must be zero.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ void *mapping; /**< [out] Returns user-space virtual address for the mapping */
+ u32 size; /**< [in] Size of the requested mapping */
+ u32 phys_addr; /**< [in] Physical address - could be offset, depending on caller+callee convention */
+ u32 cookie; /**< [out] Returns a cookie for use in munmap calls */
+ void *uku_private; /**< [in] User-side Private word used by U/K interface */
+ void *ukk_private; /**< [in] Kernel-side Private word used by U/K interface */
+ mali_memory_cache_settings cache_settings; /**< [in] Option to set special cache flags, tuning L2 efficency */
+} _mali_uk_mem_mmap_s;
+
+/** @brief Arguments to _mali_ukk_mem_munmap()
+ *
+ * The cookie and mapping members must be that returned from the same previous
+ * call to _mali_ukk_mem_mmap(). The size member must correspond to cookie
+ * and mapping - that is, it must be the value originally supplied to a call to
+ * _mali_ukk_mem_mmap that returned the values of mapping and cookie.
+ *
+ * An error will be returned if an attempt is made to unmap only part of the
+ * originally obtained range, or to unmap more than was originally obtained.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ void *mapping; /**< [in] The mapping returned from mmap call */
+ u32 size; /**< [in] The size passed to mmap call */
+ u32 cookie; /**< [in] Cookie from mmap call */
+} _mali_uk_mem_munmap_s;
+/** @} */ /* end group _mali_uk_memory */
+
+/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module
+ * @{ */
+
+/** @brief VSYNC events
+ *
+ * These events are reported when DDK starts to wait for vsync and when the
+ * vsync has occured and the DDK can continue on the next frame.
+ */
+typedef enum _mali_uk_vsync_event
+{
+ _MALI_UK_VSYNC_EVENT_BEGIN_WAIT = 0,
+ _MALI_UK_VSYNC_EVENT_END_WAIT
+} _mali_uk_vsync_event;
+
+/** @brief Arguments to _mali_ukk_vsync_event()
+ *
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ _mali_uk_vsync_event event; /**< [in] VSYNCH event type */
+} _mali_uk_vsync_event_report_s;
+
+/** @} */ /* end group _mali_uk_vsync */
+
+/** @defgroup _mali_uk_sw_counters_report U/K Software Counter Reporting
+ * @{ */
+
+/** @brief Software counter values
+ *
+ * Values recorded for each of the software counters during a single renderpass.
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32* counters; /**< [in] The array of counter values */
+ u32 num_counters; /**< [in] The number of elements in counters array */
+} _mali_uk_sw_counters_report_s;
+
+/** @} */ /* end group _mali_uk_sw_counters_report */
+
+/** @defgroup _mali_uk_stream U/K Mali stream module
+ * @{ */
+
+/** @brief Create stream
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [out] file descriptor describing stream */
+} _mali_uk_stream_create_s;
+
+/** @brief Destroy stream
+*/
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [in] file descriptor describing stream */
+} _mali_uk_stream_destroy_s;
+
+/** @brief Create empty fence
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ s32 stream; /**< [in] stream to create fence on */
+ s32 fence; /**< [out] file descriptor describing fence */
+} _mali_uk_fence_create_empty_s;
+
+/** @brief Check fence validity
+ */
+typedef struct
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int fd; /**< [in] file descriptor describing fence */
+} _mali_uk_fence_validate_s;
+
+/** @} */ /* end group _mali_uk_stream */
+
+/** @} */ /* end group u_k_api */
+
+/** @} */ /* end group uddapi */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_UTGARD_UK_TYPES_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.h b/drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.h
new file mode 100644
index 0000000..e9e5e55
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/license/gpl/mali_kernel_license.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_kernel_license.h
+ * Defines for the macro MODULE_LICENSE.
+ */
+
+#ifndef __MALI_KERNEL_LICENSE_H__
+#define __MALI_KERNEL_LICENSE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MALI_KERNEL_LINUX_LICENSE "GPL"
+#define MALI_LICENSE_IS_GPL 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_KERNEL_LICENSE_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c
new file mode 100644
index 0000000..0b82cba
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_device_pause_resume.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_device_pause_resume.c
+ * Implementation of the Mali pause/resume functionality
+ */
+
+#include <linux/module.h>
+#include <linux/mali/mali_utgard.h>
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+
+void mali_dev_pause(void)
+{
+ mali_gp_scheduler_suspend();
+ mali_pp_scheduler_suspend();
+}
+
+EXPORT_SYMBOL(mali_dev_pause);
+
+void mali_dev_resume(void)
+{
+ mali_gp_scheduler_resume();
+ mali_pp_scheduler_resume();
+}
+
+EXPORT_SYMBOL(mali_dev_resume);
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c
new file mode 100644
index 0000000..c34b2c6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.c
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+#include <linux/dma-buf.h>
+#include <linux/scatterlist.h>
+#include <linux/rbtree.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_kernel_linux.h"
+
+#include "mali_kernel_memory_engine.h"
+#include "mali_memory.h"
+#include "mali_dma_buf.h"
+
+
+struct mali_dma_buf_attachment {
+ struct dma_buf *buf;
+ struct dma_buf_attachment *attachment;
+ struct sg_table *sgt;
+ struct mali_session_data *session;
+ int map_ref;
+ struct mutex map_lock;
+ mali_bool is_mapped;
+ wait_queue_head_t wait_queue;
+};
+
+void mali_dma_buf_release(void *ctx, void *handle)
+{
+ struct mali_dma_buf_attachment *mem;
+
+ mem = (struct mali_dma_buf_attachment *)handle;
+
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release attachment %p\n", mem));
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT_POINTER(mem->attachment);
+ MALI_DEBUG_ASSERT_POINTER(mem->buf);
+
+#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ /* We mapped implicitly on attach, so we need to unmap on release */
+ mali_dma_buf_unmap(mem);
+#endif
+
+ /* Wait for buffer to become unmapped */
+ wait_event(mem->wait_queue, !mem->is_mapped);
+ MALI_DEBUG_ASSERT(!mem->is_mapped);
+
+ dma_buf_detach(mem->buf, mem->attachment);
+ dma_buf_put(mem->buf);
+
+ _mali_osk_free(mem);
+}
+
+/*
+ * Map DMA buf attachment \a mem into \a session at virtual address \a virt.
+ */
+int mali_dma_buf_map(struct mali_dma_buf_attachment *mem, struct mali_session_data *session, u32 virt, u32 *offset, u32 flags)
+{
+ struct mali_page_directory *pagedir;
+ struct scatterlist *sg;
+ int i;
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT_POINTER(session);
+ MALI_DEBUG_ASSERT(mem->session == session);
+
+ mutex_lock(&mem->map_lock);
+
+ mem->map_ref++;
+
+ MALI_DEBUG_PRINT(5, ("Mali DMA-buf: map attachment %p, new map_ref = %d\n", mem, mem->map_ref));
+
+ if (1 == mem->map_ref)
+ {
+ /* First reference taken, so we need to map the dma buf */
+ MALI_DEBUG_ASSERT(!mem->is_mapped);
+
+ pagedir = mali_session_get_page_directory(session);
+ MALI_DEBUG_ASSERT_POINTER(pagedir);
+
+ mem->sgt = dma_buf_map_attachment(mem->attachment, DMA_BIDIRECTIONAL);
+ if (IS_ERR_OR_NULL(mem->sgt))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf attachment\n"));
+ return -EFAULT;
+ }
+
+ for_each_sg(mem->sgt->sgl, sg, mem->sgt->nents, i)
+ {
+ u32 size = sg_dma_len(sg);
+ dma_addr_t phys = sg_dma_address(sg);
+
+ /* sg must be page aligned. */
+ MALI_DEBUG_ASSERT(0 == size % MALI_MMU_PAGE_SIZE);
+
+ mali_mmu_pagedir_update(pagedir, virt, phys, size, MALI_CACHE_STANDARD);
+
+ virt += size;
+ *offset += size;
+ }
+
+ if (flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
+ {
+ u32 guard_phys;
+ MALI_DEBUG_PRINT(7, ("Mapping in extra guard page\n"));
+
+ guard_phys = sg_dma_address(mem->sgt->sgl);
+ mali_mmu_pagedir_update(pagedir, virt, guard_phys, MALI_MMU_PAGE_SIZE, MALI_CACHE_STANDARD);
+ }
+
+ mem->is_mapped = MALI_TRUE;
+ mutex_unlock(&mem->map_lock);
+
+ /* Wake up any thread waiting for buffer to become mapped */
+ wake_up_all(&mem->wait_queue);
+ }
+ else
+ {
+ MALI_DEBUG_ASSERT(mem->is_mapped);
+ mutex_unlock(&mem->map_lock);
+ }
+
+ return 0;
+}
+
+void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem)
+{
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT_POINTER(mem->attachment);
+ MALI_DEBUG_ASSERT_POINTER(mem->buf);
+
+ mutex_lock(&mem->map_lock);
+
+ mem->map_ref--;
+
+ MALI_DEBUG_PRINT(5, ("Mali DMA-buf: unmap attachment %p, new map_ref = %d\n", mem, mem->map_ref));
+
+ if (0 == mem->map_ref)
+ {
+ dma_buf_unmap_attachment(mem->attachment, mem->sgt, DMA_BIDIRECTIONAL);
+
+ mem->is_mapped = MALI_FALSE;
+ }
+
+ mutex_unlock(&mem->map_lock);
+
+ /* Wake up any thread waiting for buffer to become unmapped */
+ wake_up_all(&mem->wait_queue);
+}
+
+#if !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+int mali_dma_buf_map_job(struct mali_pp_job *job)
+{
+ mali_memory_allocation *descriptor;
+ struct mali_dma_buf_attachment *mem;
+ _mali_osk_errcode_t err;
+ int i;
+ u32 offset = 0;
+ int ret = 0;
+
+ _mali_osk_lock_wait( job->session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ for (i = 0; i < job->num_memory_cookies; i++)
+ {
+ int cookie = job->memory_cookies[i];
+
+ if (0 == cookie)
+ {
+ /* 0 is not a valid cookie */
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ MALI_DEBUG_ASSERT(0 < cookie);
+
+ err = mali_descriptor_mapping_get(job->session->descriptor_mapping,
+ cookie, (void**)&descriptor);
+
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to get descriptor for cookie %d\n", cookie));
+ ret = -EFAULT;
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ if (mali_dma_buf_release != descriptor->physical_allocation.release)
+ {
+ /* Not a DMA-buf */
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ mem = (struct mali_dma_buf_attachment *)descriptor->physical_allocation.handle;
+
+ MALI_DEBUG_ASSERT_POINTER(mem);
+ MALI_DEBUG_ASSERT(mem->session == job->session);
+
+ err = mali_dma_buf_map(mem, mem->session, descriptor->mali_address, &offset, descriptor->flags);
+ if (0 != err)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Mali DMA-buf: Failed to map dma-buf for cookie %d at mali address %x\b",
+ cookie, descriptor->mali_address));
+ ret = -EFAULT;
+ MALI_DEBUG_ASSERT(NULL == job->dma_bufs[i]);
+ continue;
+ }
+
+ /* Add mem to list of DMA-bufs mapped for this job */
+ job->dma_bufs[i] = mem;
+ }
+
+ _mali_osk_lock_signal( job->session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ return ret;
+}
+
+void mali_dma_buf_unmap_job(struct mali_pp_job *job)
+{
+ int i;
+ for (i = 0; i < job->num_dma_bufs; i++)
+ {
+ if (NULL == job->dma_bufs[i]) continue;
+
+ mali_dma_buf_unmap(job->dma_bufs[i]);
+ job->dma_bufs[i] = NULL;
+ }
+}
+#endif /* !CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH */
+
+/* Callback from memory engine which will map into Mali virtual address space */
+static mali_physical_memory_allocation_result mali_dma_buf_commit(void* ctx, mali_allocation_engine * engine, mali_memory_allocation * descriptor, u32* offset, mali_physical_memory_allocation * alloc_info)
+{
+ struct mali_session_data *session;
+ struct mali_dma_buf_attachment *mem;
+
+ MALI_DEBUG_ASSERT_POINTER(ctx);
+ MALI_DEBUG_ASSERT_POINTER(engine);
+ MALI_DEBUG_ASSERT_POINTER(descriptor);
+ MALI_DEBUG_ASSERT_POINTER(offset);
+ MALI_DEBUG_ASSERT_POINTER(alloc_info);
+
+ /* Mapping dma-buf with an offset is not supported. */
+ MALI_DEBUG_ASSERT(0 == *offset);
+
+ session = (struct mali_session_data *)descriptor->mali_addr_mapping_info;
+ MALI_DEBUG_ASSERT_POINTER(session);
+
+ mem = (struct mali_dma_buf_attachment *)ctx;
+
+ MALI_DEBUG_ASSERT(mem->session == session);
+
+#if defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+ if (0 == mali_dma_buf_map(mem, session, descriptor->mali_address, offset, descriptor->flags))
+ {
+ MALI_DEBUG_ASSERT(*offset == descriptor->size);
+#else
+ {
+#endif
+ alloc_info->ctx = NULL;
+ alloc_info->handle = mem;
+ alloc_info->next = NULL;
+ alloc_info->release = mali_dma_buf_release;
+
+ return MALI_MEM_ALLOC_FINISHED;
+ }
+
+ return MALI_MEM_ALLOC_INTERNAL_FAILURE;
+}
+
+int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *user_arg)
+{
+ mali_physical_memory_allocator external_memory_allocator;
+ struct dma_buf *buf;
+ struct mali_dma_buf_attachment *mem;
+ _mali_uk_attach_dma_buf_s args;
+ mali_memory_allocation *descriptor;
+ int md;
+ int fd;
+
+ /* Get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if (0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_attach_dma_buf_s)))
+ {
+ return -EFAULT;
+ }
+
+ fd = args.mem_fd;
+
+ buf = dma_buf_get(fd);
+ if (IS_ERR_OR_NULL(buf))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to get dma-buf from fd: %d\n", fd));
+ return PTR_RET(buf);
+ }
+
+ /* Currently, mapping of the full buffer are supported. */
+ if (args.size != buf->size)
+ {
+ MALI_DEBUG_PRINT_ERROR(("dma-buf size doesn't match mapping size.\n"));
+ dma_buf_put(buf);
+ return -EINVAL;
+ }
+
+ mem = _mali_osk_calloc(1, sizeof(struct mali_dma_buf_attachment));
+ if (NULL == mem)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to allocate dma-buf tracing struct\n"));
+ dma_buf_put(buf);
+ return -ENOMEM;
+ }
+
+ mem->buf = buf;
+ mem->session = session;
+ mem->map_ref = 0;
+ mutex_init(&mem->map_lock);
+ init_waitqueue_head(&mem->wait_queue);
+
+ mem->attachment = dma_buf_attach(mem->buf, &mali_platform_device->dev);
+ if (NULL == mem->attachment)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to attach to dma-buf %d\n", fd));
+ dma_buf_put(mem->buf);
+ _mali_osk_free(mem);
+ return -EFAULT;
+ }
+
+ /* Map dma-buf into this session's page tables */
+
+ /* Set up Mali memory descriptor */
+ descriptor = _mali_osk_calloc(1, sizeof(mali_memory_allocation));
+ if (NULL == descriptor)
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to allocate descriptor dma-buf %d\n", fd));
+ mali_dma_buf_release(NULL, mem);
+ return -ENOMEM;
+ }
+
+ descriptor->size = args.size;
+ descriptor->mapping = NULL;
+ descriptor->mali_address = args.mali_address;
+ descriptor->mali_addr_mapping_info = (void*)session;
+ descriptor->process_addr_mapping_info = NULL; /* do not map to process address space */
+ descriptor->lock = session->memory_lock;
+
+ if (args.flags & _MALI_MAP_EXTERNAL_MAP_GUARD_PAGE)
+ {
+ descriptor->flags = MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE;
+ }
+ _mali_osk_list_init( &descriptor->list );
+
+ /* Get descriptor mapping for memory. */
+ if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session->descriptor_mapping, descriptor, &md))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to create descriptor mapping for dma-buf %d\n", fd));
+ _mali_osk_free(descriptor);
+ mali_dma_buf_release(NULL, mem);
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_ASSERT(0 < md);
+
+ external_memory_allocator.allocate = mali_dma_buf_commit;
+ external_memory_allocator.allocate_page_table_block = NULL;
+ external_memory_allocator.ctx = mem;
+ external_memory_allocator.name = "DMA-BUF Memory";
+ external_memory_allocator.next = NULL;
+
+ /* Map memory into session's Mali virtual address space. */
+ _mali_osk_lock_wait(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
+ if (_MALI_OSK_ERR_OK != mali_allocation_engine_allocate_memory(mali_mem_get_memory_engine(), descriptor, &external_memory_allocator, NULL))
+ {
+ _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ MALI_DEBUG_PRINT_ERROR(("Failed to map dma-buf %d into Mali address space\n", fd));
+ mali_descriptor_mapping_free(session->descriptor_mapping, md);
+ mali_dma_buf_release(NULL, mem);
+ return -ENOMEM;
+ }
+ _mali_osk_lock_signal(session->memory_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* Return stuff to user space */
+ if (0 != put_user(md, &user_arg->cookie))
+ {
+ /* Roll back */
+ MALI_DEBUG_PRINT_ERROR(("Failed to return descriptor to user space for dma-buf %d\n", fd));
+ mali_descriptor_mapping_free(session->descriptor_mapping, md);
+ mali_dma_buf_release(NULL, mem);
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *user_arg)
+{
+ int ret = 0;
+ _mali_uk_release_dma_buf_s args;
+ mali_memory_allocation *descriptor;
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_release_dma_buf_s)) )
+ {
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: release descriptor cookie %d\n", args.cookie));
+
+ _mali_osk_lock_wait( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ descriptor = mali_descriptor_mapping_free(session->descriptor_mapping, args.cookie);
+
+ if (NULL != descriptor)
+ {
+ MALI_DEBUG_PRINT(3, ("Mali DMA-buf: Releasing dma-buf at mali address %x\n", descriptor->mali_address));
+
+ /* Will call back to mali_dma_buf_release() which will release the dma-buf attachment. */
+ mali_allocation_engine_release_memory(mali_mem_get_memory_engine(), descriptor);
+
+ _mali_osk_free(descriptor);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT_ERROR(("Invalid memory descriptor %d used to release dma-buf\n", args.cookie));
+ ret = -EINVAL;
+ }
+
+ _mali_osk_lock_signal( session->memory_lock, _MALI_OSK_LOCKMODE_RW );
+
+ /* Return the error that _mali_ukk_map_external_ump_mem produced */
+ return ret;
+}
+
+int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *user_arg)
+{
+ _mali_uk_dma_buf_get_size_s args;
+ int fd;
+ struct dma_buf *buf;
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&args, (void __user *)user_arg, sizeof(_mali_uk_dma_buf_get_size_s)) )
+ {
+ return -EFAULT;
+ }
+
+ /* Do DMA-BUF stuff */
+ fd = args.mem_fd;
+
+ buf = dma_buf_get(fd);
+ if (IS_ERR_OR_NULL(buf))
+ {
+ MALI_DEBUG_PRINT_ERROR(("Failed to get dma-buf from fd: %d\n", fd));
+ return PTR_RET(buf);
+ }
+
+ if (0 != put_user(buf->size, &user_arg->size))
+ {
+ dma_buf_put(buf);
+ return -EFAULT;
+ }
+
+ dma_buf_put(buf);
+
+ return 0;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h
new file mode 100644
index 0000000..1af3efc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_dma_buf.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_DMA_BUF_H__
+#define __MALI_DMA_BUF_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mali_osk.h"
+#include "common/mali_pp_job.h"
+
+struct mali_dma_buf_attachment;
+
+int mali_attach_dma_buf(struct mali_session_data *session, _mali_uk_attach_dma_buf_s __user *arg);
+int mali_release_dma_buf(struct mali_session_data *session, _mali_uk_release_dma_buf_s __user *arg);
+int mali_dma_buf_get_size(struct mali_session_data *session, _mali_uk_dma_buf_get_size_s __user *arg);
+int mali_dma_buf_map(struct mali_dma_buf_attachment *mem, struct mali_session_data *session, u32 virt, u32 *offset, u32 flags);
+void mali_dma_buf_unmap(struct mali_dma_buf_attachment *mem);
+void mali_dma_buf_release(void *ctx, void *handle);
+
+#if !defined(CONFIG_MALI_DMA_BUF_MAP_ON_ATTACH)
+int mali_dma_buf_map_job(struct mali_pp_job *job);
+void mali_dma_buf_unmap_job(struct mali_pp_job *job);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_KERNEL_LINUX_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c
new file mode 100644
index 0000000..f337d09
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.c
@@ -0,0 +1,730 @@
+/**
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_kernel_linux.c
+ * Implementation of the Linux device driver entrypoints
+ */
+#include <linux/module.h> /* kernel module definitions */
+#include <linux/fs.h> /* file system operations */
+#include <linux/cdev.h> /* character device definitions */
+#include <linux/mm.h> /* memory manager definitions */
+#include <linux/mali/mali_utgard_ioctl.h>
+#include <linux/version.h>
+#include <linux/device.h>
+#include "mali_kernel_license.h"
+#include <linux/platform_device.h>
+#include <linux/miscdevice.h>
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_kernel_core.h"
+#include "mali_osk.h"
+#include "mali_kernel_linux.h"
+#include "mali_ukk.h"
+#include "mali_ukk_wrappers.h"
+#include "mali_kernel_sysfs.h"
+#include "mali_pm.h"
+#include "mali_kernel_license.h"
+#include "mali_dma_buf.h"
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+#include "mali_profiling_internal.h"
+#endif
+/* MALI_SEC */
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4210)
+#include "../platform/pegasus-m400/exynos4_pmm.h"
+#elif defined(CONFIG_SOC_EXYNOS3470)
+#include "../platform/exynos4270/exynos4_pmm.h"
+#endif
+
+/* Streamline support for the Mali driver */
+#if defined(CONFIG_TRACEPOINTS) && defined(CONFIG_MALI400_PROFILING)
+/* Ask Linux to create the tracepoints */
+#define CREATE_TRACE_POINTS
+#include "mali_linux_trace.h"
+#endif /* CONFIG_TRACEPOINTS */
+
+/* from the __malidrv_build_info.c file that is generated during build */
+extern const char *__malidrv_build_info(void);
+
+/* Module parameter to control log level */
+int mali_debug_level = 2;
+module_param(mali_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(mali_debug_level, "Higher number, more dmesg output");
+
+module_param(mali_max_job_runtime, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_max_job_runtime, "Maximum allowed job runtime in msecs.\nJobs will be killed after this no matter what");
+
+extern int mali_l2_max_reads;
+module_param(mali_l2_max_reads, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_l2_max_reads, "Maximum reads for Mali L2 cache");
+
+extern unsigned int mali_dedicated_mem_start;
+module_param(mali_dedicated_mem_start, uint, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_dedicated_mem_start, "Physical start address of dedicated Mali GPU memory.");
+
+extern unsigned int mali_dedicated_mem_size;
+module_param(mali_dedicated_mem_size, uint, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_dedicated_mem_size, "Size of dedicated Mali GPU memory.");
+
+extern unsigned int mali_shared_mem_size;
+module_param(mali_shared_mem_size, uint, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_shared_mem_size, "Size of shared Mali GPU memory.");
+
+#if defined(CONFIG_MALI400_PROFILING)
+extern int mali_boot_profiling;
+module_param(mali_boot_profiling, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_boot_profiling, "Start profiling as a part of Mali driver initialization");
+#endif
+
+extern int mali_max_pp_cores_group_1;
+module_param(mali_max_pp_cores_group_1, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_max_pp_cores_group_1, "Limit the number of PP cores to use from first PP group.");
+
+extern int mali_max_pp_cores_group_2;
+module_param(mali_max_pp_cores_group_2, int, S_IRUSR | S_IRGRP | S_IROTH);
+MODULE_PARM_DESC(mali_max_pp_cores_group_2, "Limit the number of PP cores to use from second PP group (Mali-450 only).");
+
+/* Export symbols from common code: mali_user_settings.c */
+#include "mali_user_settings_db.h"
+EXPORT_SYMBOL(mali_set_user_setting);
+EXPORT_SYMBOL(mali_get_user_setting);
+
+static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
+
+/* This driver only supports one Mali device, and this variable stores this single platform device */
+struct platform_device *mali_platform_device = NULL;
+
+/* This driver only supports one Mali device, and this variable stores the exposed misc device (/dev/mali) */
+static struct miscdevice mali_miscdevice = { 0, };
+
+static int mali_miscdevice_register(struct platform_device *pdev);
+static void mali_miscdevice_unregister(void);
+
+static int mali_open(struct inode *inode, struct file *filp);
+static int mali_release(struct inode *inode, struct file *filp);
+#ifdef HAVE_UNLOCKED_IOCTL
+static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#else
+static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+#endif
+static int mali_mmap(struct file * filp, struct vm_area_struct * vma);
+
+static int mali_probe(struct platform_device *pdev);
+static int mali_remove(struct platform_device *pdev);
+
+static int mali_driver_suspend_scheduler(struct device *dev);
+static int mali_driver_resume_scheduler(struct device *dev);
+
+#ifdef CONFIG_PM_RUNTIME
+static int mali_driver_runtime_suspend(struct device *dev);
+static int mali_driver_runtime_resume(struct device *dev);
+static int mali_driver_runtime_idle(struct device *dev);
+#endif
+
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+extern int mali_platform_device_register(void);
+extern int mali_platform_device_unregister(void);
+#endif
+
+/* Linux power management operations provided by the Mali device driver */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+struct pm_ext_ops mali_dev_ext_pm_ops =
+{
+ .base =
+ {
+ .suspend = mali_driver_suspend_scheduler,
+ .resume = mali_driver_resume_scheduler,
+ .freeze = mali_driver_suspend_scheduler,
+ .thaw = mali_driver_resume_scheduler,
+ },
+};
+#else
+static const struct dev_pm_ops mali_dev_pm_ops =
+{
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = mali_driver_runtime_suspend,
+ .runtime_resume = mali_driver_runtime_resume,
+ .runtime_idle = mali_driver_runtime_idle,
+#endif
+ .suspend = mali_driver_suspend_scheduler,
+ .resume = mali_driver_resume_scheduler,
+ .freeze = mali_driver_suspend_scheduler,
+ .thaw = mali_driver_resume_scheduler,
+};
+#endif
+
+/* The Mali device driver struct */
+static struct platform_driver mali_platform_driver =
+{
+ .probe = mali_probe,
+ .remove = mali_remove,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+ .pm = &mali_dev_ext_pm_ops,
+#endif
+ .driver =
+ {
+ .name = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */
+ .owner = THIS_MODULE,
+ .bus = &platform_bus_type,
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+ .pm = &mali_dev_pm_ops,
+#endif
+ },
+};
+
+/* Linux misc device operations (/dev/mali) */
+struct file_operations mali_fops =
+{
+ .owner = THIS_MODULE,
+ .open = mali_open,
+ .release = mali_release,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = mali_ioctl,
+#else
+ .ioctl = mali_ioctl,
+#endif
+ .mmap = mali_mmap
+};
+
+int mali_module_init(void)
+{
+ int err = 0;
+
+ MALI_DEBUG_PRINT(2, ("Inserting Mali v%d device driver. \n",_MALI_API_VERSION));
+ MALI_DEBUG_PRINT(2, ("Compiled: %s, time: %s.\n", __DATE__, __TIME__));
+ MALI_DEBUG_PRINT(2, ("Driver revision: %s\n", SVN_REV_STRING));
+
+ /* Initialize module wide settings */
+ mali_osk_low_level_mem_init();
+
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+ MALI_DEBUG_PRINT(2, ("mali_module_init() registering device\n"));
+ err = mali_platform_device_register();
+ if (0 != err)
+ {
+ return err;
+ }
+#endif
+
+ MALI_DEBUG_PRINT(2, ("mali_module_init() registering driver\n"));
+
+ err = platform_driver_register(&mali_platform_driver);
+
+ if (0 != err)
+ {
+ MALI_DEBUG_PRINT(2, ("mali_module_init() Failed to register driver (%d)\n", err));
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+ mali_platform_device_unregister();
+#endif
+ mali_platform_device = NULL;
+ return err;
+ }
+
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+ err = _mali_internal_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
+ if (0 != err)
+ {
+ /* No biggie if we wheren't able to initialize the profiling */
+ MALI_PRINT_ERROR(("Failed to initialize profiling, feature will be unavailable\n"));
+ }
+#endif
+
+ MALI_PRINT(("Mali device driver loaded\n"));
+
+ return 0; /* Success */
+}
+
+void mali_module_exit(void)
+{
+ MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
+
+ MALI_DEBUG_PRINT(2, ("mali_module_exit() unregistering driver\n"));
+
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+ _mali_internal_profiling_term();
+#endif
+
+ platform_driver_unregister(&mali_platform_driver);
+
+#if defined(MALI_FAKE_PLATFORM_DEVICE)
+ MALI_DEBUG_PRINT(2, ("mali_module_exit() unregistering device\n"));
+ mali_platform_device_unregister();
+#endif
+
+ mali_osk_low_level_mem_term();
+
+ MALI_PRINT(("Mali device driver unloaded\n"));
+}
+
+static int mali_probe(struct platform_device *pdev)
+{
+ int err;
+
+ MALI_DEBUG_PRINT(2, ("mali_probe(): Called for platform device %s\n", pdev->name));
+
+ if (NULL != mali_platform_device)
+ {
+ /* Already connected to a device, return error */
+ MALI_PRINT_ERROR(("mali_probe(): The Mali driver is already connected with a Mali device."));
+ return -EEXIST;
+ }
+
+ mali_platform_device = pdev;
+
+ if (_MALI_OSK_ERR_OK == _mali_osk_wq_init())
+ {
+ /* Initialize the Mali GPU HW specified by pdev */
+ if (_MALI_OSK_ERR_OK == mali_initialize_subsystems())
+ {
+ /* Register a misc device (so we are accessible from user space) */
+ err = mali_miscdevice_register(pdev);
+ if (0 == err)
+ {
+ /* Setup sysfs entries */
+ err = mali_sysfs_register(mali_dev_name);
+ if (0 == err)
+ {
+ MALI_DEBUG_PRINT(2, ("mali_probe(): Successfully initialized driver for platform device %s\n", pdev->name));
+ return 0;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("mali_probe(): failed to register sysfs entries"));
+ }
+ mali_miscdevice_unregister();
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("mali_probe(): failed to register Mali misc device."));
+ }
+ mali_terminate_subsystems();
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("mali_probe(): Failed to initialize Mali device driver."));
+ }
+ _mali_osk_wq_term();
+ }
+
+ mali_platform_device = NULL;
+ return -EFAULT;
+}
+
+static int mali_remove(struct platform_device *pdev)
+{
+ MALI_DEBUG_PRINT(2, ("mali_remove() called for platform device %s\n", pdev->name));
+ mali_sysfs_unregister();
+ mali_miscdevice_unregister();
+ mali_terminate_subsystems();
+ _mali_osk_wq_term();
+ mali_platform_device = NULL;
+ return 0;
+}
+
+static int mali_miscdevice_register(struct platform_device *pdev)
+{
+ int err;
+
+ mali_miscdevice.minor = MISC_DYNAMIC_MINOR;
+ mali_miscdevice.name = mali_dev_name;
+ mali_miscdevice.fops = &mali_fops;
+ mali_miscdevice.parent = get_device(&pdev->dev);
+
+ err = misc_register(&mali_miscdevice);
+ if (0 != err)
+ {
+ MALI_PRINT_ERROR(("Failed to register misc device, misc_register() returned %d\n", err));
+ }
+
+ return err;
+}
+
+static void mali_miscdevice_unregister(void)
+{
+ misc_deregister(&mali_miscdevice);
+}
+
+static int mali_driver_suspend_scheduler(struct device *dev)
+{
+ mali_pm_os_suspend();
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP);
+ return 0;
+}
+
+static int mali_driver_resume_scheduler(struct device *dev)
+{
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
+ mali_pm_os_resume();
+ return 0;
+}
+
+#ifdef CONFIG_PM_RUNTIME
+static int mali_driver_runtime_suspend(struct device *dev)
+{
+ mali_pm_runtime_suspend();
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_LIGHT_SLEEP);
+ return 0;
+}
+
+static int mali_driver_runtime_resume(struct device *dev)
+{
+ /* MALI_SEC */
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
+ mali_pm_runtime_resume();
+ return 0;
+}
+
+static int mali_driver_runtime_idle(struct device *dev)
+{
+ /* Nothing to do */
+ return 0;
+}
+#endif
+
+/** @note munmap handler is done by vma close handler */
+static int mali_mmap(struct file * filp, struct vm_area_struct * vma)
+{
+ struct mali_session_data * session_data;
+ _mali_uk_mem_mmap_s args = {0, };
+
+ session_data = (struct mali_session_data *)filp->private_data;
+ if (NULL == session_data)
+ {
+ MALI_PRINT_ERROR(("mmap called without any session data available\n"));
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_PRINT(4, ("MMap() handler: start=0x%08X, phys=0x%08X, size=0x%08X vma->flags 0x%08x\n", (unsigned int)vma->vm_start, (unsigned int)(vma->vm_pgoff << PAGE_SHIFT), (unsigned int)(vma->vm_end - vma->vm_start), vma->vm_flags));
+
+ /* Re-pack the arguments that mmap() packed for us */
+ args.ctx = session_data;
+ args.phys_addr = vma->vm_pgoff << PAGE_SHIFT;
+ args.size = vma->vm_end - vma->vm_start;
+ args.ukk_private = vma;
+
+ if ( VM_SHARED== (VM_SHARED & vma->vm_flags))
+ {
+ args.cache_settings = MALI_CACHE_STANDARD ;
+ MALI_DEBUG_PRINT(3,("Allocate - Standard - Size: %d kb\n", args.size/1024));
+ }
+ else
+ {
+ args.cache_settings = MALI_CACHE_GP_READ_ALLOCATE;
+ MALI_DEBUG_PRINT(3,("Allocate - GP Cached - Size: %d kb\n", args.size/1024));
+ }
+ /* Setting it equal to VM_SHARED and not Private, which would have made the later io_remap fail for MALI_CACHE_GP_READ_ALLOCATE */
+ vma->vm_flags = 0x000000fb;
+
+ /* Call the common mmap handler */
+ MALI_CHECK(_MALI_OSK_ERR_OK ==_mali_ukk_mem_mmap( &args ), -EFAULT);
+
+ return 0;
+}
+
+static int mali_open(struct inode *inode, struct file *filp)
+{
+ struct mali_session_data * session_data;
+ _mali_osk_errcode_t err;
+
+ /* input validation */
+ if (mali_miscdevice.minor != iminor(inode))
+ {
+ MALI_PRINT_ERROR(("mali_open() Minor does not match\n"));
+ return -ENODEV;
+ }
+
+ /* allocated struct to track this session */
+ err = _mali_ukk_open((void **)&session_data);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ /* initialize file pointer */
+ filp->f_pos = 0;
+
+ /* link in our session data */
+ filp->private_data = (void*)session_data;
+
+ return 0;
+}
+
+static int mali_release(struct inode *inode, struct file *filp)
+{
+ _mali_osk_errcode_t err;
+
+ /* input validation */
+ if (mali_miscdevice.minor != iminor(inode))
+ {
+ MALI_PRINT_ERROR(("mali_release() Minor does not match\n"));
+ return -ENODEV;
+ }
+
+ err = _mali_ukk_close((void **)&filp->private_data);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ return 0;
+}
+
+int map_errcode( _mali_osk_errcode_t err )
+{
+ switch(err)
+ {
+ case _MALI_OSK_ERR_OK : return 0;
+ case _MALI_OSK_ERR_FAULT: return -EFAULT;
+ case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY;
+ case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL;
+ case _MALI_OSK_ERR_NOMEM: return -ENOMEM;
+ case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT;
+ case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS;
+ case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT;
+ default: return -EFAULT;
+ }
+}
+
+#ifdef HAVE_UNLOCKED_IOCTL
+static long mali_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+#else
+static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+#endif
+{
+ int err;
+ struct mali_session_data *session_data;
+
+#ifndef HAVE_UNLOCKED_IOCTL
+ /* inode not used */
+ (void)inode;
+#endif
+
+ MALI_DEBUG_PRINT(7, ("Ioctl received 0x%08X 0x%08lX\n", cmd, arg));
+
+ session_data = (struct mali_session_data *)filp->private_data;
+ if (NULL == session_data)
+ {
+ MALI_DEBUG_PRINT(7, ("filp->private_data was NULL\n"));
+ return -ENOTTY;
+ }
+
+ if (NULL == (void *)arg)
+ {
+ MALI_DEBUG_PRINT(7, ("arg was NULL\n"));
+ return -ENOTTY;
+ }
+
+ switch(cmd)
+ {
+ case MALI_IOC_WAIT_FOR_NOTIFICATION:
+ err = wait_for_notification_wrapper(session_data, (_mali_uk_wait_for_notification_s __user *)arg);
+ break;
+
+ case MALI_IOC_GET_API_VERSION:
+ err = get_api_version_wrapper(session_data, (_mali_uk_get_api_version_s __user *)arg);
+ break;
+
+ case MALI_IOC_POST_NOTIFICATION:
+ err = post_notification_wrapper(session_data, (_mali_uk_post_notification_s __user *)arg);
+ break;
+
+ case MALI_IOC_GET_USER_SETTINGS:
+ err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg);
+ break;
+
+#if defined(CONFIG_MALI400_PROFILING)
+ case MALI_IOC_PROFILING_START:
+ err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg);
+ break;
+
+ case MALI_IOC_PROFILING_ADD_EVENT:
+ err = profiling_add_event_wrapper(session_data, (_mali_uk_profiling_add_event_s __user *)arg);
+ break;
+
+ case MALI_IOC_PROFILING_STOP:
+ err = profiling_stop_wrapper(session_data, (_mali_uk_profiling_stop_s __user *)arg);
+ break;
+
+ case MALI_IOC_PROFILING_GET_EVENT:
+ err = profiling_get_event_wrapper(session_data, (_mali_uk_profiling_get_event_s __user *)arg);
+ break;
+
+ case MALI_IOC_PROFILING_CLEAR:
+ err = profiling_clear_wrapper(session_data, (_mali_uk_profiling_clear_s __user *)arg);
+ break;
+
+ case MALI_IOC_PROFILING_GET_CONFIG:
+ /* Deprecated: still compatible with get_user_settings */
+ err = get_user_settings_wrapper(session_data, (_mali_uk_get_user_settings_s __user *)arg);
+ break;
+
+ case MALI_IOC_PROFILING_REPORT_SW_COUNTERS:
+ err = profiling_report_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_report_s __user *)arg);
+ break;
+
+#else
+
+ case MALI_IOC_PROFILING_START: /* FALL-THROUGH */
+ case MALI_IOC_PROFILING_ADD_EVENT: /* FALL-THROUGH */
+ case MALI_IOC_PROFILING_STOP: /* FALL-THROUGH */
+ case MALI_IOC_PROFILING_GET_EVENT: /* FALL-THROUGH */
+ case MALI_IOC_PROFILING_CLEAR: /* FALL-THROUGH */
+ case MALI_IOC_PROFILING_GET_CONFIG: /* FALL-THROUGH */
+ case MALI_IOC_PROFILING_REPORT_SW_COUNTERS: /* FALL-THROUGH */
+ MALI_DEBUG_PRINT(2, ("Profiling not supported\n"));
+ err = -ENOTTY;
+ break;
+
+#endif
+
+ case MALI_IOC_MEM_INIT:
+ err = mem_init_wrapper(session_data, (_mali_uk_init_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_TERM:
+ err = mem_term_wrapper(session_data, (_mali_uk_term_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_WRITE_SAFE:
+ err = mem_write_safe_wrapper(session_data, (_mali_uk_mem_write_safe_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_MAP_EXT:
+ err = mem_map_ext_wrapper(session_data, (_mali_uk_map_external_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_UNMAP_EXT:
+ err = mem_unmap_ext_wrapper(session_data, (_mali_uk_unmap_external_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_QUERY_MMU_PAGE_TABLE_DUMP_SIZE:
+ err = mem_query_mmu_page_table_dump_size_wrapper(session_data, (_mali_uk_query_mmu_page_table_dump_size_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_DUMP_MMU_PAGE_TABLE:
+ err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg);
+ break;
+
+#if defined(CONFIG_MALI400_UMP)
+
+ case MALI_IOC_MEM_ATTACH_UMP:
+ err = mem_attach_ump_wrapper(session_data, (_mali_uk_attach_ump_mem_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_RELEASE_UMP:
+ err = mem_release_ump_wrapper(session_data, (_mali_uk_release_ump_mem_s __user *)arg);
+ break;
+
+#else
+
+ case MALI_IOC_MEM_ATTACH_UMP:
+ case MALI_IOC_MEM_RELEASE_UMP: /* FALL-THROUGH */
+ MALI_DEBUG_PRINT(2, ("UMP not supported\n"));
+ err = -ENOTTY;
+ break;
+#endif
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+ case MALI_IOC_MEM_ATTACH_DMA_BUF:
+ err = mali_attach_dma_buf(session_data, (_mali_uk_attach_dma_buf_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_RELEASE_DMA_BUF:
+ err = mali_release_dma_buf(session_data, (_mali_uk_release_dma_buf_s __user *)arg);
+ break;
+
+ case MALI_IOC_MEM_DMA_BUF_GET_SIZE:
+ err = mali_dma_buf_get_size(session_data, (_mali_uk_dma_buf_get_size_s __user *)arg);
+ break;
+#else
+
+ case MALI_IOC_MEM_ATTACH_DMA_BUF: /* FALL-THROUGH */
+ case MALI_IOC_MEM_RELEASE_DMA_BUF: /* FALL-THROUGH */
+ case MALI_IOC_MEM_DMA_BUF_GET_SIZE: /* FALL-THROUGH */
+ MALI_DEBUG_PRINT(2, ("DMA-BUF not supported\n"));
+ err = -ENOTTY;
+ break;
+#endif
+
+ case MALI_IOC_PP_START_JOB:
+ err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg);
+ break;
+
+ case MALI_IOC_PP_NUMBER_OF_CORES_GET:
+ err = pp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_pp_number_of_cores_s __user *)arg);
+ break;
+
+ case MALI_IOC_PP_CORE_VERSION_GET:
+ err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_s __user *)arg);
+ break;
+
+ case MALI_IOC_PP_DISABLE_WB:
+ err = pp_disable_wb_wrapper(session_data, (_mali_uk_pp_disable_wb_s __user *)arg);
+ break;
+
+ case MALI_IOC_GP2_START_JOB:
+ err = gp_start_job_wrapper(session_data, (_mali_uk_gp_start_job_s __user *)arg);
+ break;
+
+ case MALI_IOC_GP2_NUMBER_OF_CORES_GET:
+ err = gp_get_number_of_cores_wrapper(session_data, (_mali_uk_get_gp_number_of_cores_s __user *)arg);
+ break;
+
+ case MALI_IOC_GP2_CORE_VERSION_GET:
+ err = gp_get_core_version_wrapper(session_data, (_mali_uk_get_gp_core_version_s __user *)arg);
+ break;
+
+ case MALI_IOC_GP2_SUSPEND_RESPONSE:
+ err = gp_suspend_response_wrapper(session_data, (_mali_uk_gp_suspend_response_s __user *)arg);
+ break;
+
+ case MALI_IOC_VSYNC_EVENT_REPORT:
+ err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg);
+ break;
+
+ case MALI_IOC_STREAM_CREATE:
+#if defined(CONFIG_SYNC)
+ err = stream_create_wrapper(session_data, (_mali_uk_stream_create_s __user *)arg);
+ break;
+#endif
+ case MALI_IOC_FENCE_CREATE_EMPTY:
+#if defined(CONFIG_SYNC)
+ err = sync_fence_create_empty_wrapper(session_data, (_mali_uk_fence_create_empty_s __user *)arg);
+ break;
+#endif
+ case MALI_IOC_FENCE_VALIDATE:
+#if defined(CONFIG_SYNC)
+ err = sync_fence_validate_wrapper(session_data, (_mali_uk_fence_validate_s __user *)arg);
+ break;
+#else
+ MALI_DEBUG_PRINT(2, ("Sync objects not supported\n"));
+ err = -ENOTTY;
+ break;
+#endif
+
+ case MALI_IOC_MEM_GET_BIG_BLOCK: /* Fallthrough */
+ case MALI_IOC_MEM_FREE_BIG_BLOCK:
+ MALI_PRINT_ERROR(("Non-MMU mode is no longer supported.\n"));
+ err = -ENOTTY;
+ break;
+
+ default:
+ MALI_DEBUG_PRINT(2, ("No handler for ioctl 0x%08X 0x%08lX\n", cmd, arg));
+ err = -ENOTTY;
+ };
+
+ return err;
+}
+
+
+module_init(mali_module_init);
+module_exit(mali_module_exit);
+
+MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE);
+MODULE_AUTHOR("ARM Ltd.");
+MODULE_VERSION(SVN_REV_STRING);
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h
new file mode 100644
index 0000000..8bc4c39
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_linux.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_LINUX_H__
+#define __MALI_KERNEL_LINUX_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <linux/cdev.h> /* character device definitions */
+#include "mali_kernel_license.h"
+#include "mali_osk.h"
+
+extern struct platform_device *mali_platform_device;
+
+#if MALI_LICENSE_IS_GPL
+/* Defined in mali_osk_irq.h */
+extern struct workqueue_struct * mali_wq;
+#endif
+
+void mali_osk_low_level_mem_init(void);
+void mali_osk_low_level_mem_term(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_KERNEL_LINUX_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c
new file mode 100644
index 0000000..fa1fa9c
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.c
@@ -0,0 +1,1709 @@
+/**
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+/**
+ * @file mali_kernel_sysfs.c
+ * Implementation of some sysfs data exports
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include "mali_kernel_license.h"
+#include "mali_kernel_common.h"
+#include "mali_ukk.h"
+
+#if MALI_LICENSE_IS_GPL
+
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <asm/uaccess.h>
+#include <linux/module.h>
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_sysfs.h"
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+#include <linux/slab.h>
+#include "mali_osk_profiling.h"
+#endif
+
+#include <linux/mali/mali_utgard.h>
+#include "mali_pm.h"
+#include "mali_pmu.h"
+#include "mali_group.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_l2_cache.h"
+#include "mali_hw_core.h"
+#include "mali_kernel_core.h"
+#include "mali_user_settings_db.h"
+#include "mali_profiling_internal.h"
+#include "mali_gp_job.h"
+#include "mali_pp_job.h"
+#include "mali_pp_scheduler.h"
+
+#define POWER_BUFFER_SIZE 3
+
+static struct dentry *mali_debugfs_dir = NULL;
+
+typedef enum
+{
+ _MALI_DEVICE_SUSPEND,
+ _MALI_DEVICE_RESUME,
+ _MALI_DEVICE_DVFS_PAUSE,
+ _MALI_DEVICE_DVFS_RESUME,
+ _MALI_MAX_EVENTS
+} _mali_device_debug_power_events;
+
+static const char* const mali_power_events[_MALI_MAX_EVENTS] = {
+ [_MALI_DEVICE_SUSPEND] = "suspend",
+ [_MALI_DEVICE_RESUME] = "resume",
+ [_MALI_DEVICE_DVFS_PAUSE] = "dvfs_pause",
+ [_MALI_DEVICE_DVFS_RESUME] = "dvfs_resume",
+};
+
+static mali_bool power_always_on_enabled = MALI_FALSE;
+
+static int open_copy_private_data(struct inode *inode, struct file *filp)
+{
+ filp->private_data = inode->i_private;
+ return 0;
+}
+
+static ssize_t group_enabled_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+ struct mali_group *group;
+
+ group = (struct mali_group *)filp->private_data;
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ r = sprintf(buffer, "%u\n", mali_group_is_enabled(group) ? 1 : 0);
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static ssize_t group_enabled_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+ unsigned long val;
+ struct mali_group *group;
+
+ group = (struct mali_group *)filp->private_data;
+ MALI_DEBUG_ASSERT_POINTER(group);
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ r = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != r)
+ {
+ return -EINVAL;
+ }
+
+ switch (val)
+ {
+ case 1:
+ mali_group_enable(group);
+ break;
+ case 0:
+ mali_group_disable(group);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static const struct file_operations group_enabled_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = group_enabled_read,
+ .write = group_enabled_write,
+};
+
+static ssize_t hw_core_base_addr_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+ struct mali_hw_core *hw_core;
+
+ hw_core = (struct mali_hw_core *)filp->private_data;
+ MALI_DEBUG_ASSERT_POINTER(hw_core);
+
+ r = sprintf(buffer, "0x%08X\n", hw_core->phys_addr);
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations hw_core_base_addr_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = hw_core_base_addr_read,
+};
+
+static ssize_t gp_gpx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
+{
+ char buf[64];
+ int r;
+ u32 val;
+
+ if (0 == src_id)
+ {
+ val = mali_gp_job_get_gp_counter_src0();
+ }
+ else
+ {
+ val = mali_gp_job_get_gp_counter_src1();
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER == val)
+ {
+ r = sprintf(buf, "-1\n");
+ }
+ else
+ {
+ r = sprintf(buf, "%u\n", val);
+ }
+ return simple_read_from_buffer(ubuf, cnt, gpos, buf, r);
+}
+
+static ssize_t gp_gpx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
+{
+ char buf[64];
+ long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val < 0)
+ {
+ /* any negative input will disable counter */
+ val = MALI_HW_CORE_NO_COUNTER;
+ }
+
+ if (0 == src_id)
+ {
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
+ {
+ return 0;
+ }
+ }
+
+ *gpos += cnt;
+ return cnt;
+}
+
+static ssize_t gp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos, u32 src_id)
+{
+ char buf[64];
+ long val;
+ int ret;
+ u32 num_groups;
+ int i;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val < 0)
+ {
+ /* any negative input will disable counter */
+ val = MALI_HW_CORE_NO_COUNTER;
+ }
+
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
+ {
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
+ if (NULL != gp_core)
+ {
+ if (0 == src_id)
+ {
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src0((u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_gp_job_set_gp_counter_src1((u32)val))
+ {
+ return 0;
+ }
+ }
+ }
+ }
+
+ *gpos += cnt;
+ return cnt;
+}
+
+static ssize_t gp_gpx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos)
+{
+ return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 0);
+}
+
+static ssize_t gp_gpx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *gpos)
+{
+ return gp_gpx_counter_srcx_read(filp, ubuf, cnt, gpos, 1);
+}
+
+static ssize_t gp_gpx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
+{
+ return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 0);
+}
+
+static ssize_t gp_gpx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
+{
+ return gp_gpx_counter_srcx_write(filp, ubuf, cnt, gpos, 1);
+}
+
+static ssize_t gp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
+{
+ return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 0);
+}
+
+static ssize_t gp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *gpos)
+{
+ return gp_all_counter_srcx_write(filp, ubuf, cnt, gpos, 1);
+}
+
+static const struct file_operations gp_gpx_counter_src0_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = gp_gpx_counter_src0_read,
+ .write = gp_gpx_counter_src0_write,
+};
+
+static const struct file_operations gp_gpx_counter_src1_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = gp_gpx_counter_src1_read,
+ .write = gp_gpx_counter_src1_write,
+};
+
+static const struct file_operations gp_all_counter_src0_fops = {
+ .owner = THIS_MODULE,
+ .write = gp_all_counter_src0_write,
+};
+
+static const struct file_operations gp_all_counter_src1_fops = {
+ .owner = THIS_MODULE,
+ .write = gp_all_counter_src1_write,
+};
+
+static ssize_t pp_ppx_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ char buf[64];
+ int r;
+ u32 val;
+
+ if (0 == src_id)
+ {
+ val = mali_pp_job_get_pp_counter_src0();
+ }
+ else
+ {
+ val = mali_pp_job_get_pp_counter_src1();
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER == val)
+ {
+ r = sprintf(buf, "-1\n");
+ }
+ else
+ {
+ r = sprintf(buf, "%u\n", val);
+ }
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ char buf[64];
+ long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val < 0)
+ {
+ /* any negative input will disable counter */
+ val = MALI_HW_CORE_NO_COUNTER;
+ }
+
+ if (0 == src_id)
+ {
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
+ {
+ return 0;
+ }
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t pp_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ char buf[64];
+ long val;
+ int ret;
+ u32 num_groups;
+ int i;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val < 0)
+ {
+ /* any negative input will disable counter */
+ val = MALI_HW_CORE_NO_COUNTER;
+ }
+
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
+ {
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+ if (NULL != pp_core)
+ {
+ if (0 == src_id)
+ {
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src0((u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_pp_job_set_pp_counter_src1((u32)val))
+ {
+ return 0;
+ }
+ }
+ }
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t pp_ppx_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 0);
+}
+
+static ssize_t pp_ppx_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return pp_ppx_counter_srcx_read(filp, ubuf, cnt, ppos, 1);
+}
+
+static ssize_t pp_ppx_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
+}
+
+static ssize_t pp_ppx_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return pp_ppx_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
+}
+
+static ssize_t pp_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
+}
+
+static ssize_t pp_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return pp_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
+}
+
+static const struct file_operations pp_ppx_counter_src0_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = pp_ppx_counter_src0_read,
+ .write = pp_ppx_counter_src0_write,
+};
+
+static const struct file_operations pp_ppx_counter_src1_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = pp_ppx_counter_src1_read,
+ .write = pp_ppx_counter_src1_write,
+};
+
+static const struct file_operations pp_all_counter_src0_fops = {
+ .owner = THIS_MODULE,
+ .write = pp_all_counter_src0_write,
+};
+
+static const struct file_operations pp_all_counter_src1_fops = {
+ .owner = THIS_MODULE,
+ .write = pp_all_counter_src1_write,
+};
+
+static ssize_t l2_l2x_counter_srcx_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ char buf[64];
+ int r;
+ u32 val;
+ struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data;
+
+ if (0 == src_id)
+ {
+ val = mali_l2_cache_core_get_counter_src0(l2_core);
+ }
+ else
+ {
+ val = mali_l2_cache_core_get_counter_src1(l2_core);
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER == val)
+ {
+ r = sprintf(buf, "-1\n");
+ }
+ else
+ {
+ r = sprintf(buf, "%u\n", val);
+ }
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t l2_l2x_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ struct mali_l2_cache_core *l2_core = (struct mali_l2_cache_core *)filp->private_data;
+ char buf[64];
+ long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val < 0)
+ {
+ /* any negative input will disable counter */
+ val = MALI_HW_CORE_NO_COUNTER;
+ }
+
+ if (0 == src_id)
+ {
+ if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t l2_all_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ char buf[64];
+ long val;
+ int ret;
+ u32 l2_id;
+ struct mali_l2_cache_core *l2_cache;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtol(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val < 0)
+ {
+ /* any negative input will disable counter */
+ val = MALI_HW_CORE_NO_COUNTER;
+ }
+
+ l2_id = 0;
+ l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
+ while (NULL != l2_cache)
+ {
+ if (0 == src_id)
+ {
+ if (MALI_TRUE != mali_l2_cache_core_set_counter_src0(l2_cache, (u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_l2_cache_core_set_counter_src1(l2_cache, (u32)val))
+ {
+ return 0;
+ }
+ }
+
+ /* try next L2 */
+ l2_id++;
+ l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t l2_l2x_counter_src0_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 0);
+}
+
+static ssize_t l2_l2x_counter_src1_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return l2_l2x_counter_srcx_read(filp, ubuf, cnt, ppos, 1);
+}
+
+static ssize_t l2_l2x_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
+}
+
+static ssize_t l2_l2x_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return l2_l2x_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
+}
+
+static ssize_t l2_all_counter_src0_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 0);
+}
+
+static ssize_t l2_all_counter_src1_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return l2_all_counter_srcx_write(filp, ubuf, cnt, ppos, 1);
+}
+
+static const struct file_operations l2_l2x_counter_src0_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = l2_l2x_counter_src0_read,
+ .write = l2_l2x_counter_src0_write,
+};
+
+static const struct file_operations l2_l2x_counter_src1_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = l2_l2x_counter_src1_read,
+ .write = l2_l2x_counter_src1_write,
+};
+
+static const struct file_operations l2_all_counter_src0_fops = {
+ .owner = THIS_MODULE,
+ .write = l2_all_counter_src0_write,
+};
+
+static const struct file_operations l2_all_counter_src1_fops = {
+ .owner = THIS_MODULE,
+ .write = l2_all_counter_src1_write,
+};
+
+static ssize_t power_always_on_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ unsigned long val;
+ int ret;
+ char buf[32];
+
+ cnt = min(cnt, sizeof(buf) - 1);
+ if (copy_from_user(buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+ buf[cnt] = '\0';
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (0 != ret)
+ {
+ return ret;
+ }
+
+ /* Update setting (not exactly thread safe) */
+ if (1 == val && MALI_FALSE == power_always_on_enabled)
+ {
+ power_always_on_enabled = MALI_TRUE;
+ _mali_osk_pm_dev_ref_add();
+ }
+ else if (0 == val && MALI_TRUE == power_always_on_enabled)
+ {
+ power_always_on_enabled = MALI_FALSE;
+ _mali_osk_pm_dev_ref_dec();
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t power_always_on_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ if (MALI_TRUE == power_always_on_enabled)
+ {
+ return simple_read_from_buffer(ubuf, cnt, ppos, "1\n", 2);
+ }
+ else
+ {
+ return simple_read_from_buffer(ubuf, cnt, ppos, "0\n", 2);
+ }
+}
+
+static const struct file_operations power_always_on_fops = {
+ .owner = THIS_MODULE,
+ .read = power_always_on_read,
+ .write = power_always_on_write,
+};
+
+static ssize_t power_power_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+
+ if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND])))
+ {
+ mali_pm_os_suspend();
+
+ }
+ else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME])))
+ {
+ mali_pm_os_resume();
+ }
+ else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE])))
+ {
+ mali_dev_pause();
+ }
+ else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME])))
+ {
+ mali_dev_resume();
+ }
+ *ppos += cnt;
+ return cnt;
+}
+
+static loff_t power_power_events_seek(struct file *file, loff_t offset, int orig)
+{
+ file->f_pos = offset;
+ return 0;
+}
+
+static const struct file_operations power_power_events_fops = {
+ .owner = THIS_MODULE,
+ .write = power_power_events_write,
+ .llseek = power_power_events_seek,
+};
+
+#if MALI_STATE_TRACKING
+static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
+{
+ u32 len = 0;
+ u32 size;
+ char *buf;
+
+ size = seq_get_buf(seq_file, &buf);
+
+ if(!size)
+ {
+ return -ENOMEM;
+ }
+
+ /* Create the internal state dump. */
+ len = snprintf(buf+len, size-len, "Mali device driver %s\n", SVN_REV_STRING);
+ len += snprintf(buf+len, size-len, "License: %s\n\n", MALI_KERNEL_LINUX_LICENSE);
+
+ len += _mali_kernel_core_dump_state(buf + len, size - len);
+
+ seq_commit(seq_file, len);
+
+ return 0;
+}
+
+static int mali_seq_internal_state_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mali_seq_internal_state_show, NULL);
+}
+
+static const struct file_operations mali_seq_internal_state_fops = {
+ .owner = THIS_MODULE,
+ .open = mali_seq_internal_state_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+#endif /* MALI_STATE_TRACKING */
+
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+static ssize_t profiling_record_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ int r;
+
+ r = sprintf(buf, "%u\n", _mali_internal_profiling_is_recording() ? 1 : 0);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ unsigned long val;
+ int ret;
+
+ if (cnt >= sizeof(buf))
+ {
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+
+ buf[cnt] = 0;
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (val != 0)
+ {
+ u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* This can be made configurable at a later stage if we need to */
+
+ /* check if we are already recording */
+ if (MALI_TRUE == _mali_internal_profiling_is_recording())
+ {
+ MALI_DEBUG_PRINT(3, ("Recording of profiling events already in progress\n"));
+ return -EFAULT;
+ }
+
+ /* check if we need to clear out an old recording first */
+ if (MALI_TRUE == _mali_internal_profiling_have_recording())
+ {
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_clear())
+ {
+ MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
+ return -EFAULT;
+ }
+ }
+
+ /* start recording profiling data */
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
+ {
+ MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_PRINT(3, ("Profiling recording started (max %u events)\n", limit));
+ }
+ else
+ {
+ /* stop recording profiling data */
+ u32 count = 0;
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_stop(&count))
+ {
+ MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
+ return -EFAULT;
+ }
+
+ MALI_DEBUG_PRINT(2, ("Profiling recording stopped (recorded %u events)\n", count));
+ }
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static const struct file_operations profiling_record_fops = {
+ .owner = THIS_MODULE,
+ .read = profiling_record_read,
+ .write = profiling_record_write,
+};
+
+static void *profiling_events_start(struct seq_file *s, loff_t *pos)
+{
+ loff_t *spos;
+
+ /* check if we have data avaiable */
+ if (MALI_TRUE != _mali_internal_profiling_have_recording())
+ {
+ return NULL;
+ }
+
+ spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
+ if (NULL == spos)
+ {
+ return NULL;
+ }
+
+ *spos = *pos;
+ return spos;
+}
+
+static void *profiling_events_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ loff_t *spos = v;
+
+ /* check if we have data avaiable */
+ if (MALI_TRUE != _mali_internal_profiling_have_recording())
+ {
+ return NULL;
+ }
+
+ /* check if the next entry actually is avaiable */
+ if (_mali_internal_profiling_get_count() <= (u32)(*spos + 1))
+ {
+ return NULL;
+ }
+
+ *pos = ++*spos;
+ return spos;
+}
+
+static void profiling_events_stop(struct seq_file *s, void *v)
+{
+ kfree(v);
+}
+
+static int profiling_events_show(struct seq_file *seq_file, void *v)
+{
+ loff_t *spos = v;
+ u32 index;
+ u64 timestamp;
+ u32 event_id;
+ u32 data[5];
+
+ index = (u32)*spos;
+
+ /* Retrieve all events */
+ if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
+ {
+ seq_printf(seq_file, "%llu %u %u %u %u %u %u\n", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
+ return 0;
+ }
+
+ return 0;
+}
+
+static int profiling_events_show_human_readable(struct seq_file *seq_file, void *v)
+{
+ #define MALI_EVENT_ID_IS_HW(event_id) (((event_id & 0x00FF0000) >= MALI_PROFILING_EVENT_CHANNEL_GP0) && ((event_id & 0x00FF0000) <= MALI_PROFILING_EVENT_CHANNEL_PP7))
+
+ static u64 start_time = 0;
+ loff_t *spos = v;
+ u32 index;
+ u64 timestamp;
+ u32 event_id;
+ u32 data[5];
+
+ index = (u32)*spos;
+
+ /* Retrieve all events */
+ if (_MALI_OSK_ERR_OK == _mali_internal_profiling_get_event(index, &timestamp, &event_id, data))
+ {
+ seq_printf(seq_file, "%llu %u %u %u %u %u %u # ", timestamp, event_id, data[0], data[1], data[2], data[3], data[4]);
+
+ if (0 == index)
+ {
+ start_time = timestamp;
+ }
+
+ seq_printf(seq_file, "[%06u] ", index);
+
+ switch(event_id & 0x0F000000)
+ {
+ case MALI_PROFILING_EVENT_TYPE_SINGLE:
+ seq_printf(seq_file, "SINGLE | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_START:
+ seq_printf(seq_file, "START | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_STOP:
+ seq_printf(seq_file, "STOP | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_SUSPEND:
+ seq_printf(seq_file, "SUSPEND | ");
+ break;
+ case MALI_PROFILING_EVENT_TYPE_RESUME:
+ seq_printf(seq_file, "RESUME | ");
+ break;
+ default:
+ seq_printf(seq_file, "0x%01X | ", (event_id & 0x0F000000) >> 24);
+ break;
+ }
+
+ switch(event_id & 0x00FF0000)
+ {
+ case MALI_PROFILING_EVENT_CHANNEL_SOFTWARE:
+ seq_printf(seq_file, "SW | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_GP0:
+ seq_printf(seq_file, "GP0 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP0:
+ seq_printf(seq_file, "PP0 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP1:
+ seq_printf(seq_file, "PP1 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP2:
+ seq_printf(seq_file, "PP2 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP3:
+ seq_printf(seq_file, "PP3 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP4:
+ seq_printf(seq_file, "PP4 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP5:
+ seq_printf(seq_file, "PP5 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP6:
+ seq_printf(seq_file, "PP6 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_PP7:
+ seq_printf(seq_file, "PP7 | ");
+ break;
+ case MALI_PROFILING_EVENT_CHANNEL_GPU:
+ seq_printf(seq_file, "GPU | ");
+ break;
+ default:
+ seq_printf(seq_file, "0x%02X | ", (event_id & 0x00FF0000) >> 16);
+ break;
+ }
+
+ if (MALI_EVENT_ID_IS_HW(event_id))
+ {
+ if (((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_START) || ((event_id & 0x0F000000) == MALI_PROFILING_EVENT_TYPE_STOP))
+ {
+ switch(event_id & 0x0000FFFF)
+ {
+ case MALI_PROFILING_EVENT_REASON_START_STOP_HW_PHYSICAL:
+ seq_printf(seq_file, "PHYSICAL | ");
+ break;
+ case MALI_PROFILING_EVENT_REASON_START_STOP_HW_VIRTUAL:
+ seq_printf(seq_file, "VIRTUAL | ");
+ break;
+ default:
+ seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
+ break;
+ }
+ }
+ else
+ {
+ seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
+ }
+ }
+ else
+ {
+ seq_printf(seq_file, "0x%04X | ", event_id & 0x0000FFFF);
+ }
+
+ seq_printf(seq_file, "T0 + 0x%016llX\n", timestamp - start_time);
+
+ return 0;
+ }
+
+ return 0;
+}
+
+static const struct seq_operations profiling_events_seq_ops = {
+ .start = profiling_events_start,
+ .next = profiling_events_next,
+ .stop = profiling_events_stop,
+ .show = profiling_events_show
+};
+
+static int profiling_events_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &profiling_events_seq_ops);
+}
+
+static const struct file_operations profiling_events_fops = {
+ .owner = THIS_MODULE,
+ .open = profiling_events_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static const struct seq_operations profiling_events_human_readable_seq_ops = {
+ .start = profiling_events_start,
+ .next = profiling_events_next,
+ .stop = profiling_events_stop,
+ .show = profiling_events_show_human_readable
+};
+
+static int profiling_events_human_readable_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &profiling_events_human_readable_seq_ops);
+}
+
+static const struct file_operations profiling_events_human_readable_fops = {
+ .owner = THIS_MODULE,
+ .open = profiling_events_human_readable_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+#endif
+
+static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 mem = _mali_ukk_report_memory_usage();
+
+ r = snprintf(buf, 64, "%u\n", mem);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static const struct file_operations memory_usage_fops = {
+ .owner = THIS_MODULE,
+ .read = memory_used_read,
+};
+
+static ssize_t utilization_gp_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 uval= _mali_ukk_utilization_gp_pp();
+
+ r = snprintf(buf, 64, "%u\n", uval);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t utilization_gp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 uval= _mali_ukk_utilization_gp();
+
+ r = snprintf(buf, 64, "%u\n", uval);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static ssize_t utilization_pp_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 uval= _mali_ukk_utilization_pp();
+
+ r = snprintf(buf, 64, "%u\n", uval);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+
+static const struct file_operations utilization_gp_pp_fops = {
+ .owner = THIS_MODULE,
+ .read = utilization_gp_pp_read,
+};
+
+static const struct file_operations utilization_gp_fops = {
+ .owner = THIS_MODULE,
+ .read = utilization_gp_read,
+};
+
+static const struct file_operations utilization_pp_fops = {
+ .owner = THIS_MODULE,
+ .read = utilization_pp_read,
+};
+
+static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ unsigned long val;
+ int ret;
+ _mali_uk_user_setting_t setting;
+ char buf[32];
+
+ cnt = min(cnt, sizeof(buf) - 1);
+ if (copy_from_user(buf, ubuf, cnt))
+ {
+ return -EFAULT;
+ }
+ buf[cnt] = '\0';
+
+ ret = strict_strtoul(buf, 10, &val);
+ if (0 != ret)
+ {
+ return ret;
+ }
+
+ /* Update setting */
+ setting = (_mali_uk_user_setting_t)(filp->private_data);
+ mali_set_user_setting(setting, val);
+
+ *ppos += cnt;
+ return cnt;
+}
+
+static ssize_t user_settings_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 value;
+ _mali_uk_user_setting_t setting;
+
+ setting = (_mali_uk_user_setting_t)(filp->private_data);
+ value = mali_get_user_setting(setting);
+
+ r = snprintf(buf, 64, "%u\n", value);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static const struct file_operations user_settings_fops = {
+ .owner = THIS_MODULE,
+ .open = open_copy_private_data,
+ .read = user_settings_read,
+ .write = user_settings_write,
+};
+
+static int mali_sysfs_user_settings_register(void)
+{
+ struct dentry *mali_user_settings_dir = debugfs_create_dir("userspace_settings", mali_debugfs_dir);
+
+ if (mali_user_settings_dir != NULL)
+ {
+ int i;
+ for (i = 0; i < _MALI_UK_USER_SETTING_MAX; i++)
+ {
+ debugfs_create_file(_mali_uk_user_setting_descriptions[i], 0600, mali_user_settings_dir, (void*)i, &user_settings_fops);
+ }
+ }
+
+ return 0;
+}
+
+static ssize_t pmu_power_down_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int ret;
+ char buffer[32];
+ unsigned long val;
+ struct mali_pmu_core *pmu;
+ _mali_osk_errcode_t err;
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ ret = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != ret)
+ {
+ return -EINVAL;
+ }
+
+ pmu = mali_pmu_get_global_pmu_core();
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+
+ err = mali_pmu_power_down(pmu, val);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return -EINVAL;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static ssize_t pmu_power_up_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int ret;
+ char buffer[32];
+ unsigned long val;
+ struct mali_pmu_core *pmu;
+ _mali_osk_errcode_t err;
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ ret = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != ret)
+ {
+ return -EINVAL;
+ }
+
+ pmu = mali_pmu_get_global_pmu_core();
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+
+ err = mali_pmu_power_up(pmu, val);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return -EINVAL;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static const struct file_operations pmu_power_down_fops = {
+ .owner = THIS_MODULE,
+ .write = pmu_power_down_write,
+};
+
+static const struct file_operations pmu_power_up_fops = {
+ .owner = THIS_MODULE,
+ .write = pmu_power_up_write,
+};
+
+static ssize_t pp_num_cores_enabled_write(struct file *filp, const char __user *buf, size_t count, loff_t *offp)
+{
+ int ret;
+ char buffer[32];
+ unsigned long val;
+
+ if (count >= sizeof(buffer))
+ {
+ return -ENOMEM;
+ }
+
+ if (copy_from_user(&buffer[0], buf, count))
+ {
+ return -EFAULT;
+ }
+ buffer[count] = '\0';
+
+ ret = strict_strtoul(&buffer[0], 10, &val);
+ if (0 != ret)
+ {
+ return -EINVAL;
+ }
+
+ ret = mali_perf_set_num_pp_cores(val);
+ if (ret)
+ {
+ return ret;
+ }
+
+ *offp += count;
+ return count;
+}
+
+static ssize_t pp_num_cores_enabled_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+
+ r = sprintf(buffer, "%u\n", mali_pp_scheduler_get_num_cores_enabled());
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations pp_num_cores_enabled_fops = {
+ .owner = THIS_MODULE,
+ .write = pp_num_cores_enabled_write,
+ .read = pp_num_cores_enabled_read,
+};
+
+static ssize_t pp_num_cores_total_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r;
+ char buffer[64];
+
+ r = sprintf(buffer, "%u\n", mali_pp_scheduler_get_num_cores_total());
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations pp_num_cores_total_fops = {
+ .owner = THIS_MODULE,
+ .read = pp_num_cores_total_read,
+};
+
+
+static ssize_t version_read(struct file *filp, char __user *buf, size_t count, loff_t *offp)
+{
+ int r = 0;
+ char buffer[64];
+
+ switch (mali_kernel_core_get_product_id())
+ {
+ case _MALI_PRODUCT_ID_MALI200:
+ r = sprintf(buffer, "Mali-200\n");
+ break;
+ case _MALI_PRODUCT_ID_MALI300:
+ r = sprintf(buffer, "Mali-300\n");
+ break;
+ case _MALI_PRODUCT_ID_MALI400:
+ r = sprintf(buffer, "Mali-400 MP\n");
+ break;
+ case _MALI_PRODUCT_ID_MALI450:
+ r = sprintf(buffer, "Mali-450 MP\n");
+ break;
+ case _MALI_PRODUCT_ID_UNKNOWN:
+ return -EINVAL;
+ break;
+ };
+
+ return simple_read_from_buffer(buf, count, offp, buffer, r);
+}
+
+static const struct file_operations version_fops = {
+ .owner = THIS_MODULE,
+ .read = version_read,
+};
+
+int mali_sysfs_register(const char *mali_dev_name)
+{
+ mali_debugfs_dir = debugfs_create_dir(mali_dev_name, NULL);
+ if(ERR_PTR(-ENODEV) == mali_debugfs_dir)
+ {
+ /* Debugfs not supported. */
+ mali_debugfs_dir = NULL;
+ }
+ else
+ {
+ if(NULL != mali_debugfs_dir)
+ {
+ /* Debugfs directory created successfully; create files now */
+ struct dentry *mali_pmu_dir;
+ struct dentry *mali_power_dir;
+ struct dentry *mali_gp_dir;
+ struct dentry *mali_pp_dir;
+ struct dentry *mali_l2_dir;
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+ struct dentry *mali_profiling_dir;
+#endif
+
+ debugfs_create_file("version", 0400, mali_debugfs_dir, NULL, &version_fops);
+
+ mali_pmu_dir = debugfs_create_dir("pmu", mali_debugfs_dir);
+ if (NULL != mali_pmu_dir)
+ {
+ debugfs_create_file("power_down", 0200, mali_pmu_dir, NULL, &pmu_power_down_fops);
+ debugfs_create_file("power_up", 0200, mali_pmu_dir, NULL, &pmu_power_up_fops);
+ }
+
+ mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir);
+ if (mali_power_dir != NULL)
+ {
+ /* MALI_SEC : 0600 -> 0400 */
+ debugfs_create_file("always_on", 0400, mali_power_dir, NULL, &power_always_on_fops);
+ /* MALI_SEC : 0200 -> 0400 */
+ debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &power_power_events_fops);
+ }
+
+ mali_gp_dir = debugfs_create_dir("gp", mali_debugfs_dir);
+ if (mali_gp_dir != NULL)
+ {
+ struct dentry *mali_gp_all_dir;
+ u32 num_groups;
+ int i;
+
+ mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir);
+ if (mali_gp_all_dir != NULL)
+ {
+ debugfs_create_file("counter_src0", 0200, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0200, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
+ }
+
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
+ {
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_gp_core *gp_core = mali_group_get_gp_core(group);
+ if (NULL != gp_core)
+ {
+ struct dentry *mali_gp_gpx_dir;
+ mali_gp_gpx_dir = debugfs_create_dir("gp0", mali_gp_dir);
+ if (NULL != mali_gp_gpx_dir)
+ {
+ debugfs_create_file("counter_src0", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0600, mali_gp_gpx_dir, gp_core, &gp_gpx_counter_src1_fops);
+ debugfs_create_file("base_addr", 0400, mali_gp_gpx_dir, &gp_core->hw_core, &hw_core_base_addr_fops);
+ debugfs_create_file("enabled", 0600, mali_gp_gpx_dir, group, &group_enabled_fops);
+ }
+ break; /* no need to look for any other GP cores */
+ }
+
+ }
+ }
+
+ mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir);
+ if (mali_pp_dir != NULL)
+ {
+ struct dentry *mali_pp_all_dir;
+ u32 num_groups;
+ int i;
+
+ debugfs_create_file("num_cores_total", 0400, mali_pp_dir, NULL, &pp_num_cores_total_fops);
+ debugfs_create_file("num_cores_enabled", 0600, mali_pp_dir, NULL, &pp_num_cores_enabled_fops);
+
+ mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir);
+ if (mali_pp_all_dir != NULL)
+ {
+ debugfs_create_file("counter_src0", 0200, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0200, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
+ }
+
+ num_groups = mali_group_get_glob_num_groups();
+ for (i = 0; i < num_groups; i++)
+ {
+ struct mali_group *group = mali_group_get_glob_group(i);
+
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+ if (NULL != pp_core)
+ {
+ char buf[16];
+ struct dentry *mali_pp_ppx_dir;
+ _mali_osk_snprintf(buf, sizeof(buf), "pp%u", mali_pp_core_get_id(pp_core));
+ mali_pp_ppx_dir = debugfs_create_dir(buf, mali_pp_dir);
+ if (NULL != mali_pp_ppx_dir)
+ {
+ debugfs_create_file("counter_src0", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0600, mali_pp_ppx_dir, pp_core, &pp_ppx_counter_src1_fops);
+ debugfs_create_file("base_addr", 0400, mali_pp_ppx_dir, &pp_core->hw_core, &hw_core_base_addr_fops);
+ if (!mali_group_is_virtual(group))
+ {
+ debugfs_create_file("enabled", 0600, mali_pp_ppx_dir, group, &group_enabled_fops);
+ }
+ }
+ }
+ }
+ }
+
+ mali_l2_dir = debugfs_create_dir("l2", mali_debugfs_dir);
+ if (mali_l2_dir != NULL)
+ {
+ struct dentry *mali_l2_all_dir;
+ u32 l2_id;
+ struct mali_l2_cache_core *l2_cache;
+
+ mali_l2_all_dir = debugfs_create_dir("all", mali_l2_dir);
+ if (mali_l2_all_dir != NULL)
+ {
+ debugfs_create_file("counter_src0", 0200, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0200, mali_l2_all_dir, NULL, &l2_all_counter_src1_fops);
+ }
+
+ l2_id = 0;
+ l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
+ while (NULL != l2_cache)
+ {
+ char buf[16];
+ struct dentry *mali_l2_l2x_dir;
+ _mali_osk_snprintf(buf, sizeof(buf), "l2%u", l2_id);
+ mali_l2_l2x_dir = debugfs_create_dir(buf, mali_l2_dir);
+ if (NULL != mali_l2_l2x_dir)
+ {
+ debugfs_create_file("counter_src0", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0600, mali_l2_l2x_dir, l2_cache, &l2_l2x_counter_src1_fops);
+ debugfs_create_file("base_addr", 0400, mali_l2_l2x_dir, &l2_cache->hw_core, &hw_core_base_addr_fops);
+ }
+
+ /* try next L2 */
+ l2_id++;
+ l2_cache = mali_l2_cache_core_get_glob_l2_core(l2_id);
+ }
+ }
+
+ debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops);
+
+ debugfs_create_file("utilization_gp_pp", 0400, mali_debugfs_dir, NULL, &utilization_gp_pp_fops);
+ debugfs_create_file("utilization_gp", 0400, mali_debugfs_dir, NULL, &utilization_gp_fops);
+ debugfs_create_file("utilization_pp", 0400, mali_debugfs_dir, NULL, &utilization_pp_fops);
+
+#if defined(CONFIG_MALI400_INTERNAL_PROFILING)
+ mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir);
+ if (mali_profiling_dir != NULL)
+ {
+ struct dentry *mali_profiling_proc_dir = debugfs_create_dir("proc", mali_profiling_dir);
+ if (mali_profiling_proc_dir != NULL)
+ {
+ struct dentry *mali_profiling_proc_default_dir = debugfs_create_dir("default", mali_profiling_proc_dir);
+ if (mali_profiling_proc_default_dir != NULL)
+ {
+ debugfs_create_file("enable", 0600, mali_profiling_proc_default_dir, (void*)_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, &user_settings_fops);
+ }
+ }
+ debugfs_create_file("record", 0600, mali_profiling_dir, NULL, &profiling_record_fops);
+ debugfs_create_file("events", 0400, mali_profiling_dir, NULL, &profiling_events_fops);
+ debugfs_create_file("events_human_readable", 0400, mali_profiling_dir, NULL, &profiling_events_human_readable_fops);
+ }
+#endif
+
+#if MALI_STATE_TRACKING
+ debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops);
+#endif
+
+ if (mali_sysfs_user_settings_register())
+ {
+ /* Failed to create the debugfs entries for the user settings DB. */
+ MALI_DEBUG_PRINT(2, ("Failed to create user setting debugfs files. Ignoring...\n"));
+ }
+ }
+ }
+
+ /* Success! */
+ return 0;
+}
+
+int mali_sysfs_unregister(void)
+{
+ if(NULL != mali_debugfs_dir)
+ {
+ debugfs_remove_recursive(mali_debugfs_dir);
+ }
+ return 0;
+}
+
+#else /* MALI_LICENSE_IS_GPL */
+
+/* Dummy implementations for non-GPL */
+
+int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
+{
+ return 0;
+}
+
+int mali_sysfs_unregister(void)
+{
+ return 0;
+}
+
+#endif /* MALI_LICENSE_IS_GPL */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h
new file mode 100644
index 0000000..f970f0f
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_kernel_sysfs.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_KERNEL_SYSFS_H__
+#define __MALI_KERNEL_SYSFS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <linux/device.h>
+
+#define MALI_PROC_DIR "driver/mali"
+
+int mali_sysfs_register(const char *mali_dev_name);
+int mali_sysfs_unregister(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_KERNEL_LINUX_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h
new file mode 100644
index 0000000..5329ba3
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_linux_trace.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if !defined (MALI_LINUX_TRACE_H) || defined (TRACE_HEADER_MULTI_READ)
+#define MALI_LINUX_TRACE_H
+
+#include <linux/types.h>
+
+#include <linux/stringify.h>
+#include <linux/tracepoint.h>
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM mali
+#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM)
+
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE mali_linux_trace
+
+/**
+ * Define the tracepoint used to communicate the status of a GPU. Called
+ * when a GPU turns on or turns off.
+ *
+ * @param event_id The type of the event. This parameter is a bitfield
+ * encoding the type of the event.
+ *
+ * @param d0 First data parameter.
+ * @param d1 Second data parameter.
+ * @param d2 Third data parameter.
+ * @param d3 Fourth data parameter.
+ * @param d4 Fifth data parameter.
+ */
+TRACE_EVENT(mali_timeline_event,
+
+ TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1,
+ unsigned int d2, unsigned int d3, unsigned int d4),
+
+ TP_ARGS(event_id, d0, d1, d2, d3, d4),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, event_id)
+ __field(unsigned int, d0)
+ __field(unsigned int, d1)
+ __field(unsigned int, d2)
+ __field(unsigned int, d3)
+ __field(unsigned int, d4)
+ ),
+
+ TP_fast_assign(
+ __entry->event_id = event_id;
+ __entry->d0 = d0;
+ __entry->d1 = d1;
+ __entry->d2 = d2;
+ __entry->d3 = d3;
+ __entry->d4 = d4;
+ ),
+
+ TP_printk("event=%d", __entry->event_id)
+);
+
+/**
+ * Define a tracepoint used to regsiter the value of a hardware counter.
+ * Hardware counters belonging to the vertex or fragment processor are
+ * reported via this tracepoint each frame, whilst L2 cache hardware
+ * counters are reported continuously.
+ *
+ * @param counter_id The counter ID.
+ * @param value The value of the counter.
+ */
+TRACE_EVENT(mali_hw_counter,
+
+ TP_PROTO(unsigned int counter_id, unsigned int value),
+
+ TP_ARGS(counter_id, value),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, counter_id)
+ __field(unsigned int, value)
+ ),
+
+ TP_fast_assign(
+ __entry->counter_id = counter_id;
+ ),
+
+ TP_printk("event %d = %d", __entry->counter_id, __entry->value)
+);
+
+/**
+ * Define a tracepoint used to send a bundle of software counters.
+ *
+ * @param counters The bundle of counters.
+ */
+TRACE_EVENT(mali_sw_counters,
+
+ TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters),
+
+ TP_ARGS(pid, tid, surface_id, counters),
+
+ TP_STRUCT__entry(
+ __field(pid_t, pid)
+ __field(pid_t, tid)
+ __field(void *, surface_id)
+ __field(unsigned int *, counters)
+ ),
+
+ TP_fast_assign(
+ __entry->pid = pid;
+ __entry->tid = tid;
+ __entry->surface_id = surface_id;
+ __entry->counters = counters;
+ ),
+
+ TP_printk("counters were %s", __entry->counters == NULL? "NULL" : "not NULL")
+);
+
+#endif /* MALI_LINUX_TRACE_H */
+
+/* This part must exist outside the header guard. */
+#include <trace/define_trace.h>
+
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c
new file mode 100644
index 0000000..05831c5
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_atomics.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_atomics.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include "mali_osk.h"
+#include <asm/atomic.h>
+#include "mali_kernel_common.h"
+
+void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom )
+{
+ atomic_dec((atomic_t *)&atom->u.val);
+}
+
+u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom )
+{
+ return atomic_dec_return((atomic_t *)&atom->u.val);
+}
+
+void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom )
+{
+ atomic_inc((atomic_t *)&atom->u.val);
+}
+
+u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom )
+{
+ return atomic_inc_return((atomic_t *)&atom->u.val);
+}
+
+_mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val )
+{
+ MALI_CHECK_NON_NULL(atom, _MALI_OSK_ERR_INVALID_ARGS);
+ atomic_set((atomic_t *)&atom->u.val, val);
+ return _MALI_OSK_ERR_OK;
+}
+
+u32 _mali_osk_atomic_read( _mali_osk_atomic_t *atom )
+{
+ return atomic_read((atomic_t *)&atom->u.val);
+}
+
+void _mali_osk_atomic_term( _mali_osk_atomic_t *atom )
+{
+ MALI_IGNORE(atom);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c
new file mode 100644
index 0000000..787a145
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_irq.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_irq.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/slab.h> /* For memory allocation */
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "linux/interrupt.h"
+
+typedef struct _mali_osk_irq_t_struct
+{
+ u32 irqnum;
+ void *data;
+ _mali_osk_irq_uhandler_t uhandler;
+} mali_osk_irq_object_t;
+
+typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
+static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ); /* , struct pt_regs *regs*/
+
+_mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandler, void *int_data, _mali_osk_irq_trigger_t trigger_func, _mali_osk_irq_ack_t ack_func, void *probe_data, const char *description )
+{
+ mali_osk_irq_object_t *irq_object;
+ unsigned long irq_flags = 0;
+
+#if defined(CONFIG_MALI_SHARED_INTERRUPTS)
+ irq_flags |= IRQF_SHARED;
+#endif /* defined(CONFIG_MALI_SHARED_INTERRUPTS) */
+
+ irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL);
+ if (NULL == irq_object)
+ {
+ return NULL;
+ }
+
+ if (-1 == irqnum)
+ {
+ /* Probe for IRQ */
+ if ( (NULL != trigger_func) && (NULL != ack_func) )
+ {
+ unsigned long probe_count = 3;
+ _mali_osk_errcode_t err;
+ int irq;
+
+ MALI_DEBUG_PRINT(2, ("Probing for irq\n"));
+
+ do
+ {
+ unsigned long mask;
+
+ mask = probe_irq_on();
+ trigger_func(probe_data);
+
+ _mali_osk_time_ubusydelay(5);
+
+ irq = probe_irq_off(mask);
+ err = ack_func(probe_data);
+ }
+ while (irq < 0 && (err == _MALI_OSK_ERR_OK) && probe_count--);
+
+ if (irq < 0 || (_MALI_OSK_ERR_OK != err)) irqnum = -1;
+ else irqnum = irq;
+ }
+ else irqnum = -1; /* no probe functions, fault */
+
+ if (-1 != irqnum)
+ {
+ /* found an irq */
+ MALI_DEBUG_PRINT(2, ("Found irq %d\n", irqnum));
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(2, ("Probe for irq failed\n"));
+ }
+ }
+
+ irq_object->irqnum = irqnum;
+ irq_object->uhandler = uhandler;
+ irq_object->data = int_data;
+
+ if (-1 == irqnum)
+ {
+ MALI_DEBUG_PRINT(2, ("No IRQ for core '%s' found during probe\n", description));
+ kfree(irq_object);
+ return NULL;
+ }
+
+ if (0 != request_irq(irqnum, irq_handler_upper_half, irq_flags, description, irq_object))
+ {
+ MALI_DEBUG_PRINT(2, ("Unable to install IRQ handler for core '%s'\n", description));
+ kfree(irq_object);
+ return NULL;
+ }
+
+ return irq_object;
+}
+
+void _mali_osk_irq_term( _mali_osk_irq_t *irq )
+{
+ mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
+ free_irq(irq_object->irqnum, irq_object);
+ kfree(irq_object);
+}
+
+
+/** This function is called directly in interrupt context from the OS just after
+ * the CPU get the hw-irq from mali, or other devices on the same IRQ-channel.
+ * It is registered one of these function for each mali core. When an interrupt
+ * arrives this function will be called equal times as registered mali cores.
+ * That means that we only check one mali core in one function call, and the
+ * core we check for each turn is given by the \a dev_id variable.
+ * If we detect an pending interrupt on the given core, we mask the interrupt
+ * out by settging the core's IRQ_MASK register to zero.
+ * Then we schedule the mali_core_irq_handler_bottom_half to run as high priority
+ * work queue job.
+ */
+static irqreturn_t irq_handler_upper_half (int port_name, void* dev_id ) /* , struct pt_regs *regs*/
+{
+ irqreturn_t ret = IRQ_NONE;
+ mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)dev_id;
+
+ if (_MALI_OSK_ERR_OK == irq_object->uhandler(irq_object->data))
+ {
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c
new file mode 100644
index 0000000..cce946a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_locks.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_locks.c
+ * Implemenation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/spinlock.h>
+#include <linux/rwsem.h>
+#include <linux/mutex.h>
+
+#include <linux/slab.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+/* These are all the locks we implement: */
+typedef enum
+{
+ _MALI_OSK_INTERNAL_LOCKTYPE_SPIN, /* Mutex, implicitly non-interruptable, use spin_lock/spin_unlock */
+ _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ, /* Mutex, IRQ version of spinlock, use spin_lock_irqsave/spin_unlock_irqrestore */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX, /* Interruptable, use mutex_unlock()/down_interruptable() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT, /* Non-Interruptable, use mutex_unlock()/down() */
+ _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW, /* Non-interruptable, Reader/Writer, use {mutex_unlock,down}{read,write}() */
+
+ /* Linux supports, but we do not support:
+ * Non-Interruptable Reader/Writer spinlock mutexes - RW optimization will be switched off
+ */
+
+ /* Linux does not support:
+ * One-locks, of any sort - no optimization for this fact will be made.
+ */
+
+} _mali_osk_internal_locktype;
+
+struct _mali_osk_lock_t_struct
+{
+ _mali_osk_internal_locktype type;
+ unsigned long flags;
+ union
+ {
+ spinlock_t spinlock;
+ struct mutex mutex;
+ struct rw_semaphore rw_sema;
+ } obj;
+ MALI_DEBUG_CODE(
+ /** original flags for debug checking */
+ _mali_osk_lock_flags_t orig_flags;
+
+ /* id of the thread currently holding this lock, 0 if no
+ * threads hold it. */
+ u32 owner;
+ /* what mode the lock was taken in */
+ _mali_osk_lock_mode_t mode;
+ ); /* MALI_DEBUG_CODE */
+};
+
+_mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial, u32 order )
+{
+ _mali_osk_lock_t *lock = NULL;
+
+ /* Validate parameters: */
+ /* Flags acceptable */
+ MALI_DEBUG_ASSERT( 0 == ( flags & ~(_MALI_OSK_LOCKFLAG_SPINLOCK
+ | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ
+ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
+ | _MALI_OSK_LOCKFLAG_READERWRITER
+ | _MALI_OSK_LOCKFLAG_ORDERED
+ | _MALI_OSK_LOCKFLAG_ONELOCK )) );
+ /* Spinlocks are always non-interruptable */
+ MALI_DEBUG_ASSERT( (((flags & _MALI_OSK_LOCKFLAG_SPINLOCK) || (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ)) && (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE))
+ || !(flags & _MALI_OSK_LOCKFLAG_SPINLOCK));
+ /* Parameter initial SBZ - for future expansion */
+ MALI_DEBUG_ASSERT( 0 == initial );
+
+ lock = kmalloc(sizeof(_mali_osk_lock_t), GFP_KERNEL);
+
+ if ( NULL == lock )
+ {
+ return lock;
+ }
+
+ /* Determine type of mutex: */
+ /* defaults to interruptable mutex if no flags are specified */
+
+ if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK) )
+ {
+ /* Non-interruptable Spinlocks override all others */
+ lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN;
+ spin_lock_init( &lock->obj.spinlock );
+ }
+ else if ( (flags & _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ ) )
+ {
+ lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ;
+ lock->flags = 0;
+ spin_lock_init( &lock->obj.spinlock );
+ }
+ else if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE)
+ && (flags & _MALI_OSK_LOCKFLAG_READERWRITER) )
+ {
+ lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW;
+ init_rwsem( &lock->obj.rw_sema );
+ }
+ else
+ {
+ /* Usual mutex types */
+ if ( (flags & _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE) )
+ {
+ lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT;
+ }
+ else
+ {
+ lock->type = _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX;
+ }
+
+ /* Initially unlocked */
+ mutex_init(&lock->obj.mutex);
+ }
+
+#ifdef DEBUG
+ /* Debug tracking of flags */
+ lock->orig_flags = flags;
+
+ /* Debug tracking of lock owner */
+ lock->owner = 0;
+#endif /* DEBUG */
+
+ return lock;
+}
+
+#ifdef DEBUG
+u32 _mali_osk_lock_get_owner( _mali_osk_lock_t *lock )
+{
+ return lock->owner;
+}
+
+u32 _mali_osk_lock_get_mode( _mali_osk_lock_t *lock )
+{
+ return lock->mode;
+}
+#endif /* DEBUG */
+
+_mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+
+ /* Parameter validation */
+ MALI_DEBUG_ASSERT_POINTER( lock );
+
+ MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
+ || _MALI_OSK_LOCKMODE_RO == mode );
+
+ /* Only allow RO locks when the initial object was a Reader/Writer lock
+ * Since information is lost on the internal locktype, we use the original
+ * information, which is only stored when built for DEBUG */
+ MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
+ || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) );
+
+ switch ( lock->type )
+ {
+ case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN:
+ spin_lock(&lock->obj.spinlock);
+ break;
+ case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ:
+ {
+ unsigned long tmp_flags;
+ spin_lock_irqsave(&lock->obj.spinlock, tmp_flags);
+ lock->flags = tmp_flags;
+ }
+ break;
+
+ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
+ if (mutex_lock_interruptible(&lock->obj.mutex))
+ {
+ MALI_PRINT_ERROR(("Can not lock mutex\n"));
+ err = _MALI_OSK_ERR_RESTARTSYSCALL;
+ }
+ break;
+
+ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
+ mutex_lock(&lock->obj.mutex);
+ break;
+
+ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
+ if (mode == _MALI_OSK_LOCKMODE_RO)
+ {
+ down_read(&lock->obj.rw_sema);
+ }
+ else
+ {
+ down_write(&lock->obj.rw_sema);
+ }
+ break;
+
+ default:
+ /* Reaching here indicates a programming error, so you will not get here
+ * on non-DEBUG builds */
+ MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) );
+ break;
+ }
+
+#ifdef DEBUG
+ /* This thread is now the owner of this lock */
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ if (mode == _MALI_OSK_LOCKMODE_RW)
+ {
+ if (0 != lock->owner)
+ {
+ printk(KERN_ERR "%d: ERROR: Lock %p already has owner %d\n", _mali_osk_get_tid(), lock, lock->owner);
+ dump_stack();
+ }
+ lock->owner = _mali_osk_get_tid();
+ lock->mode = mode;
+ }
+ else /* mode == _MALI_OSK_LOCKMODE_RO */
+ {
+ lock->mode = mode;
+ }
+ }
+#endif
+
+ return err;
+}
+
+void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
+{
+ /* Parameter validation */
+ MALI_DEBUG_ASSERT_POINTER( lock );
+
+ MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
+ || _MALI_OSK_LOCKMODE_RO == mode );
+
+ /* Only allow RO locks when the initial object was a Reader/Writer lock
+ * Since information is lost on the internal locktype, we use the original
+ * information, which is only stored when built for DEBUG */
+ MALI_DEBUG_ASSERT( _MALI_OSK_LOCKMODE_RW == mode
+ || (_MALI_OSK_LOCKMODE_RO == mode && (_MALI_OSK_LOCKFLAG_READERWRITER & lock->orig_flags)) );
+
+#ifdef DEBUG
+ /* make sure the thread releasing the lock actually was the owner */
+ if (mode == _MALI_OSK_LOCKMODE_RW)
+ {
+ if (_mali_osk_get_tid() != lock->owner)
+ {
+ printk(KERN_ERR "%d: ERROR: Lock %p owner was %d\n", _mali_osk_get_tid(), lock, lock->owner);
+ dump_stack();
+ }
+ /* This lock now has no owner */
+ lock->owner = 0;
+ } /* else if (mode == _MALI_OSK_LOCKMODE_RO) Nothing to check */
+#endif /* DEBUG */
+
+ switch ( lock->type )
+ {
+ case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN:
+ spin_unlock(&lock->obj.spinlock);
+ break;
+ case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN_IRQ:
+ spin_unlock_irqrestore(&lock->obj.spinlock, lock->flags);
+ break;
+
+ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
+ /* FALLTHROUGH */
+ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT:
+ mutex_unlock(&lock->obj.mutex);
+ break;
+
+ case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX_NONINT_RW:
+ if (mode == _MALI_OSK_LOCKMODE_RO)
+ {
+ up_read(&lock->obj.rw_sema);
+ }
+ else
+ {
+ up_write(&lock->obj.rw_sema);
+ }
+ break;
+
+ default:
+ /* Reaching here indicates a programming error, so you will not get here
+ * on non-DEBUG builds */
+ MALI_DEBUG_PRINT_ERROR( ("Invalid internal lock type: %.8X", lock->type ) );
+ break;
+ }
+}
+
+void _mali_osk_lock_term( _mali_osk_lock_t *lock )
+{
+ /* Parameter validation */
+ MALI_DEBUG_ASSERT_POINTER( lock );
+
+ /* Linux requires no explicit termination of spinlocks, semaphores, or rw_semaphores */
+ kfree(lock);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c
new file mode 100644
index 0000000..8c0ef17
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_low_level_mem.c
@@ -0,0 +1,723 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_low_level_mem.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
+#include <asm/io.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
+#include <linux/shrinker.h>
+#endif
+#include <linux/sched.h>
+#include <linux/mm_types.h>
+#include <linux/rwsem.h>
+
+#include "mali_osk.h"
+#include "mali_ukk.h" /* required to hook in _mali_ukk_mem_mmap handling */
+#include "mali_kernel_common.h"
+#include "mali_kernel_linux.h"
+
+static void mali_kernel_memory_vma_open(struct vm_area_struct * vma);
+static void mali_kernel_memory_vma_close(struct vm_area_struct * vma);
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf);
+#else
+static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address);
+#endif
+
+
+typedef struct mali_vma_usage_tracker
+{
+ int references;
+ u32 cookie;
+} mali_vma_usage_tracker;
+
+#define INVALID_PAGE 0xffffffff
+
+/* Linked list structure to hold details of all OS allocations in a particular
+ * mapping
+ */
+struct AllocationList
+{
+ struct AllocationList *next;
+ u32 offset;
+ u32 physaddr;
+};
+
+typedef struct AllocationList AllocationList;
+
+/* Private structure to store details of a mapping region returned
+ * from _mali_osk_mem_mapregion_init
+ */
+struct MappingInfo
+{
+ struct vm_area_struct *vma;
+ struct AllocationList *list;
+ struct AllocationList *tail;
+};
+
+typedef struct MappingInfo MappingInfo;
+
+
+static u32 _kernel_page_allocate(void);
+static void _kernel_page_release(u32 physical_address);
+static AllocationList * _allocation_list_item_get(void);
+static void _allocation_list_item_release(AllocationList * item);
+
+
+/* Variable declarations */
+static DEFINE_SPINLOCK(allocation_list_spinlock);
+static AllocationList * pre_allocated_memory = (AllocationList*) NULL ;
+static int pre_allocated_memory_size_current = 0;
+#ifdef MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB
+ static int pre_allocated_memory_size_max = MALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB * 1024 * 1024;
+#else
+ static int pre_allocated_memory_size_max = 16 * 1024 * 1024; /* 6 MiB */
+#endif
+
+static struct vm_operations_struct mali_kernel_vm_ops =
+{
+ .open = mali_kernel_memory_vma_open,
+ .close = mali_kernel_memory_vma_close,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ .fault = mali_kernel_memory_cpu_page_fault_handler
+#else
+ .nopfn = mali_kernel_memory_cpu_page_fault_handler
+#endif
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
+ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35)
+static int mali_mem_shrink(int nr_to_scan, gfp_t gfp_mask)
+ #else
+static int mali_mem_shrink(struct shrinker *shrinker, int nr_to_scan, gfp_t gfp_mask)
+ #endif
+#else
+static int mali_mem_shrink(struct shrinker *shrinker, struct shrink_control *sc)
+#endif
+{
+ unsigned long flags;
+ AllocationList *item;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
+ int nr = nr_to_scan;
+#else
+ int nr = sc->nr_to_scan;
+#endif
+
+ if (0 == nr)
+ {
+ return pre_allocated_memory_size_current / PAGE_SIZE;
+ }
+
+ if (0 == pre_allocated_memory_size_current)
+ {
+ /* No pages availble */
+ return 0;
+ }
+
+ if (0 == spin_trylock_irqsave(&allocation_list_spinlock, flags))
+ {
+ /* Not able to lock. */
+ return -1;
+ }
+
+ while (pre_allocated_memory && nr > 0)
+ {
+ item = pre_allocated_memory;
+ pre_allocated_memory = item->next;
+
+ _kernel_page_release(item->physaddr);
+ _mali_osk_free(item);
+
+ pre_allocated_memory_size_current -= PAGE_SIZE;
+ --nr;
+ }
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+
+ return pre_allocated_memory_size_current / PAGE_SIZE;
+}
+
+struct shrinker mali_mem_shrinker = {
+ .shrink = mali_mem_shrink,
+ .seeks = DEFAULT_SEEKS,
+};
+
+void mali_osk_low_level_mem_init(void)
+{
+ pre_allocated_memory = (AllocationList*) NULL ;
+
+ register_shrinker(&mali_mem_shrinker);
+}
+
+void mali_osk_low_level_mem_term(void)
+{
+ unregister_shrinker(&mali_mem_shrinker);
+
+ while ( NULL != pre_allocated_memory )
+ {
+ AllocationList *item;
+ item = pre_allocated_memory;
+ pre_allocated_memory = item->next;
+ _kernel_page_release(item->physaddr);
+ _mali_osk_free( item );
+ }
+ pre_allocated_memory_size_current = 0;
+}
+
+static u32 _kernel_page_allocate(void)
+{
+ struct page *new_page;
+ u32 linux_phys_addr;
+
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
+
+ if ( NULL == new_page )
+ {
+ return INVALID_PAGE;
+ }
+
+ /* Ensure page is flushed from CPU caches. */
+ linux_phys_addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL);
+
+ return linux_phys_addr;
+}
+
+static void _kernel_page_release(u32 physical_address)
+{
+ struct page *unmap_page;
+
+ #if 1
+ dma_unmap_page(NULL, physical_address, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ #endif
+
+ unmap_page = pfn_to_page( physical_address >> PAGE_SHIFT );
+ MALI_DEBUG_ASSERT_POINTER( unmap_page );
+ __free_page( unmap_page );
+}
+
+static AllocationList * _allocation_list_item_get(void)
+{
+ AllocationList *item = NULL;
+ unsigned long flags;
+
+ spin_lock_irqsave(&allocation_list_spinlock,flags);
+ if ( pre_allocated_memory )
+ {
+ item = pre_allocated_memory;
+ pre_allocated_memory = pre_allocated_memory->next;
+ pre_allocated_memory_size_current -= PAGE_SIZE;
+
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+ return item;
+ }
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+
+ item = _mali_osk_malloc( sizeof(AllocationList) );
+ if ( NULL == item)
+ {
+ return NULL;
+ }
+
+ item->physaddr = _kernel_page_allocate();
+ if ( INVALID_PAGE == item->physaddr )
+ {
+ /* Non-fatal error condition, out of memory. Upper levels will handle this. */
+ _mali_osk_free( item );
+ return NULL;
+ }
+ return item;
+}
+
+static void _allocation_list_item_release(AllocationList * item)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&allocation_list_spinlock,flags);
+ if ( pre_allocated_memory_size_current < pre_allocated_memory_size_max)
+ {
+ item->next = pre_allocated_memory;
+ pre_allocated_memory = item;
+ pre_allocated_memory_size_current += PAGE_SIZE;
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+ return;
+ }
+ spin_unlock_irqrestore(&allocation_list_spinlock,flags);
+
+ _kernel_page_release(item->physaddr);
+ _mali_osk_free( item );
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
+#else
+static unsigned long mali_kernel_memory_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ void __user * address;
+ address = vmf->virtual_address;
+#endif
+ /*
+ * We always fail the call since all memory is pre-faulted when assigned to the process.
+ * Only the Mali cores can use page faults to extend buffers.
+ */
+
+ MALI_DEBUG_PRINT(1, ("Page-fault in Mali memory region caused by the CPU.\n"));
+ MALI_DEBUG_PRINT(1, ("Tried to access %p (process local virtual address) which is not currently mapped to any Mali memory.\n", (void*)address));
+
+ MALI_IGNORE(address);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ return VM_FAULT_SIGBUS;
+#else
+ return NOPFN_SIGBUS;
+#endif
+}
+
+static void mali_kernel_memory_vma_open(struct vm_area_struct * vma)
+{
+ mali_vma_usage_tracker * vma_usage_tracker;
+ MALI_DEBUG_PRINT(4, ("Open called on vma %p\n", vma));
+
+ vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data;
+ vma_usage_tracker->references++;
+
+ return;
+}
+
+static void mali_kernel_memory_vma_close(struct vm_area_struct * vma)
+{
+ _mali_uk_mem_munmap_s args = {0, };
+ mali_memory_allocation * descriptor;
+ mali_vma_usage_tracker * vma_usage_tracker;
+ MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma));
+
+ vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data;
+
+ BUG_ON(!vma_usage_tracker);
+ BUG_ON(0 == vma_usage_tracker->references);
+
+ vma_usage_tracker->references--;
+
+ if (0 != vma_usage_tracker->references)
+ {
+ MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references));
+ return;
+ }
+
+ /** @note args->context unused, initialized to 0.
+ * Instead, we use the memory_session from the cookie */
+
+ descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie;
+
+ args.cookie = (u32)descriptor;
+ args.mapping = descriptor->mapping;
+ args.size = descriptor->size;
+
+ _mali_ukk_mem_munmap( &args );
+
+ /* vma_usage_tracker is free()d by _mali_osk_mem_mapregion_term().
+ * In the case of the memory engine, it is called as the release function that has been registered with the engine*/
+}
+
+void _mali_osk_mem_barrier( void )
+{
+ mb();
+}
+
+void _mali_osk_write_mem_barrier( void )
+{
+ wmb();
+}
+
+mali_io_address _mali_osk_mem_mapioregion( u32 phys, u32 size, const char *description )
+{
+ return (mali_io_address)ioremap_nocache(phys, size);
+}
+
+void _mali_osk_mem_unmapioregion( u32 phys, u32 size, mali_io_address virt )
+{
+ iounmap((void*)virt);
+}
+
+mali_io_address _mali_osk_mem_allocioregion( u32 *phys, u32 size )
+{
+ void * virt;
+ MALI_DEBUG_ASSERT_POINTER( phys );
+ MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) );
+ MALI_DEBUG_ASSERT( 0 != size );
+
+ /* dma_alloc_* uses a limited region of address space. On most arch/marchs
+ * 2 to 14 MiB is available. This should be enough for the page tables, which
+ * currently is the only user of this function. */
+ virt = dma_alloc_writecombine(NULL, size, phys, GFP_KERNEL | GFP_DMA | __GFP_ZERO);
+
+ MALI_DEBUG_PRINT(3, ("Page table virt: 0x%x = dma_alloc_coherent(size:%d, phys:0x%x, )\n", virt, size, phys));
+
+ if ( NULL == virt )
+ {
+ MALI_DEBUG_PRINT(5, ("allocioregion: Failed to allocate Pagetable memory, size=0x%.8X\n", size ));
+ return 0;
+ }
+
+ MALI_DEBUG_ASSERT( 0 == (*phys & ~_MALI_OSK_CPU_PAGE_MASK) );
+
+ return (mali_io_address)virt;
+}
+
+void _mali_osk_mem_freeioregion( u32 phys, u32 size, mali_io_address virt )
+{
+ MALI_DEBUG_ASSERT_POINTER( (void*)virt );
+ MALI_DEBUG_ASSERT( 0 != size );
+ MALI_DEBUG_ASSERT( 0 == (phys & ( (1 << PAGE_SHIFT) - 1 )) );
+
+ dma_free_writecombine(NULL, size, virt, phys);
+}
+
+_mali_osk_errcode_t inline _mali_osk_mem_reqregion( u32 phys, u32 size, const char *description )
+{
+#if MALI_LICENSE_IS_GPL
+ return _MALI_OSK_ERR_OK; /* GPL driver gets the mem region for the resources registered automatically */
+#else
+ return ((NULL == request_mem_region(phys, size, description)) ? _MALI_OSK_ERR_NOMEM : _MALI_OSK_ERR_OK);
+#endif
+}
+
+void inline _mali_osk_mem_unreqregion( u32 phys, u32 size )
+{
+#if !MALI_LICENSE_IS_GPL
+ release_mem_region(phys, size);
+#endif
+}
+
+void inline _mali_osk_mem_iowrite32_relaxed( volatile mali_io_address addr, u32 offset, u32 val )
+{
+ __raw_writel(cpu_to_le32(val),((u8*)addr) + offset);
+}
+
+u32 inline _mali_osk_mem_ioread32( volatile mali_io_address addr, u32 offset )
+{
+ return ioread32(((u8*)addr) + offset);
+}
+
+void inline _mali_osk_mem_iowrite32( volatile mali_io_address addr, u32 offset, u32 val )
+{
+ iowrite32(val, ((u8*)addr) + offset);
+}
+
+void _mali_osk_cache_flushall( void )
+{
+ /** @note Cached memory is not currently supported in this implementation */
+}
+
+void _mali_osk_cache_ensure_uncached_range_flushed( void *uncached_mapping, u32 offset, u32 size )
+{
+ _mali_osk_write_mem_barrier();
+}
+
+_mali_osk_errcode_t _mali_osk_mem_mapregion_init( mali_memory_allocation * descriptor )
+{
+ struct vm_area_struct *vma;
+ mali_vma_usage_tracker * vma_usage_tracker;
+ MappingInfo *mappingInfo;
+
+ if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
+
+ MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
+
+ vma = (struct vm_area_struct*)descriptor->process_addr_mapping_info;
+
+ if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
+
+ /* Re-write the process_addr_mapping_info */
+ mappingInfo = _mali_osk_calloc( 1, sizeof(MappingInfo) );
+
+ if ( NULL == mappingInfo ) return _MALI_OSK_ERR_FAULT;
+
+ vma_usage_tracker = _mali_osk_calloc( 1, sizeof(mali_vma_usage_tracker) );
+
+ if (NULL == vma_usage_tracker)
+ {
+ MALI_DEBUG_PRINT(2, ("Failed to allocate memory to track memory usage\n"));
+ _mali_osk_free( mappingInfo );
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mappingInfo->vma = vma;
+ descriptor->process_addr_mapping_info = mappingInfo;
+
+ /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */
+ descriptor->mapping = (void __user*)vma->vm_start;
+ /* list member is already NULL */
+
+ /*
+ set some bits which indicate that:
+ The memory is IO memory, meaning that no paging is to be performed and the memory should not be included in crash dumps
+ The memory is reserved, meaning that it's present and can never be paged out (see also previous entry)
+ */
+ vma->vm_flags |= VM_IO;
+ vma->vm_flags |= VM_DONTCOPY;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+ vma->vm_flags |= VM_RESERVED;
+#else
+ vma->vm_flags |= VM_DONTDUMP;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags |= VM_PFNMAP;
+#endif
+
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ vma->vm_ops = &mali_kernel_vm_ops; /* Operations used on any memory system */
+
+ vma_usage_tracker->references = 1; /* set initial reference count to be 1 as vma_open won't be called for the first mmap call */
+ vma_usage_tracker->cookie = (u32)descriptor; /* cookie for munmap */
+
+ vma->vm_private_data = vma_usage_tracker;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_osk_mem_mapregion_term( mali_memory_allocation * descriptor )
+{
+ struct vm_area_struct* vma;
+ mali_vma_usage_tracker * vma_usage_tracker;
+ MappingInfo *mappingInfo;
+
+ if (NULL == descriptor) return;
+
+ MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
+
+ mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
+
+ MALI_DEBUG_ASSERT_POINTER( mappingInfo );
+
+ /* Linux does the right thing as part of munmap to remove the mapping
+ * All that remains is that we remove the vma_usage_tracker setup in init() */
+ vma = mappingInfo->vma;
+
+ MALI_DEBUG_ASSERT_POINTER( vma );
+
+ /* ASSERT that there are no allocations on the list. Unmap should've been
+ * called on all OS allocations. */
+ MALI_DEBUG_ASSERT( NULL == mappingInfo->list );
+
+ vma_usage_tracker = vma->vm_private_data;
+
+ /* We only get called if mem_mapregion_init succeeded */
+ _mali_osk_free(vma_usage_tracker);
+
+ _mali_osk_free( mappingInfo );
+ return;
+}
+
+_mali_osk_errcode_t _mali_osk_mem_mapregion_map( mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size )
+{
+ struct vm_area_struct *vma;
+ MappingInfo *mappingInfo;
+
+ if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
+
+ MALI_DEBUG_ASSERT_POINTER( phys_addr );
+
+ MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
+
+ MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) );
+
+ MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK));
+
+ if (NULL == descriptor->mapping) return _MALI_OSK_ERR_INVALID_ARGS;
+
+ if (size > (descriptor->size - offset))
+ {
+ MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_map: virtual memory area not large enough to map physical 0x%x size %x into area 0x%x at offset 0x%xr\n",
+ *phys_addr, size, descriptor->mapping, offset));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
+
+ MALI_DEBUG_ASSERT_POINTER( mappingInfo );
+
+ vma = mappingInfo->vma;
+
+ if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
+
+ MALI_DEBUG_PRINT(7, ("Process map: mapping 0x%08X to process address 0x%08lX length 0x%08X\n", *phys_addr, (long unsigned int)(descriptor->mapping + offset), size));
+
+ if ( MALI_MEMORY_ALLOCATION_OS_ALLOCATED_PHYSADDR_MAGIC == *phys_addr )
+ {
+ _mali_osk_errcode_t ret;
+ AllocationList *alloc_item;
+ u32 linux_phys_frame_num;
+
+ alloc_item = _allocation_list_item_get();
+ if (NULL == alloc_item)
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to allocate list item\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ linux_phys_frame_num = alloc_item->physaddr >> PAGE_SHIFT;
+
+ ret = ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, linux_phys_frame_num, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;
+
+ if ( ret != _MALI_OSK_ERR_OK)
+ {
+ MALI_PRINT_ERROR(("%s %d could not remap_pfn_range()\n", __FUNCTION__, __LINE__));
+ _allocation_list_item_release(alloc_item);
+ return ret;
+ }
+
+ /* Put our alloc_item into the list of allocations on success */
+ if (NULL == mappingInfo->list)
+ {
+ mappingInfo->list = alloc_item;
+ }
+ else
+ {
+ mappingInfo->tail->next = alloc_item;
+ }
+
+ mappingInfo->tail = alloc_item;
+ alloc_item->next = NULL;
+ alloc_item->offset = offset;
+
+ /* Write out new physical address on success */
+ *phys_addr = alloc_item->physaddr;
+
+ return ret;
+ }
+
+ /* Otherwise, Use the supplied physical address */
+
+ /* ASSERT that supplied phys_addr is page aligned */
+ MALI_DEBUG_ASSERT( 0 == ((*phys_addr) & ~_MALI_OSK_CPU_PAGE_MASK) );
+
+ return ( remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, *phys_addr >> PAGE_SHIFT, size, vma->vm_page_prot) ) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;
+
+}
+
+void _mali_osk_mem_mapregion_unmap( mali_memory_allocation * descriptor, u32 offset, u32 size, _mali_osk_mem_mapregion_flags_t flags )
+{
+ MappingInfo *mappingInfo;
+
+ if (NULL == descriptor) return;
+
+ MALI_DEBUG_ASSERT( 0 != (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_INTO_USERSPACE) );
+
+ MALI_DEBUG_ASSERT( 0 == (size & ~_MALI_OSK_CPU_PAGE_MASK) );
+
+ MALI_DEBUG_ASSERT( 0 == (offset & ~_MALI_OSK_CPU_PAGE_MASK) );
+
+ if (NULL == descriptor->mapping) return;
+
+ if (size > (descriptor->size - offset))
+ {
+ MALI_DEBUG_PRINT(1,("_mali_osk_mem_mapregion_unmap: virtual memory area not large enough to unmap size %x from area 0x%x at offset 0x%x\n",
+ size, descriptor->mapping, offset));
+ return;
+ }
+ mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
+
+ MALI_DEBUG_ASSERT_POINTER( mappingInfo );
+
+ if ( 0 != (flags & _MALI_OSK_MEM_MAPREGION_FLAG_OS_ALLOCATED_PHYSADDR) )
+ {
+ /* This physical RAM was allocated in _mali_osk_mem_mapregion_map and
+ * so needs to be unmapped
+ */
+ while (size)
+ {
+ /* First find the allocation in the list of allocations */
+ AllocationList *alloc = mappingInfo->list;
+ AllocationList **prev = &(mappingInfo->list);
+
+ while (NULL != alloc && alloc->offset != offset)
+ {
+ prev = &(alloc->next);
+ alloc = alloc->next;
+ }
+ if (alloc == NULL) {
+ MALI_DEBUG_PRINT(1, ("Unmapping memory that isn't mapped\n"));
+ size -= _MALI_OSK_CPU_PAGE_SIZE;
+ offset += _MALI_OSK_CPU_PAGE_SIZE;
+ continue;
+ }
+
+ *prev = alloc->next;
+ _allocation_list_item_release(alloc);
+
+ /* Move onto the next allocation */
+ size -= _MALI_OSK_CPU_PAGE_SIZE;
+ offset += _MALI_OSK_CPU_PAGE_SIZE;
+ }
+ }
+
+ /* Linux does the right thing as part of munmap to remove the mapping */
+
+ return;
+}
+
+u32 _mali_osk_mem_write_safe(void *dest, const void *src, u32 size)
+{
+#define MALI_MEM_SAFE_COPY_BLOCK_SIZE 4096
+ u32 retval = 0;
+ void *temp_buf;
+
+ temp_buf = kmalloc(MALI_MEM_SAFE_COPY_BLOCK_SIZE, GFP_KERNEL);
+ if (NULL != temp_buf)
+ {
+ u32 bytes_left_to_copy = size;
+ u32 i;
+ for (i = 0; i < size; i += MALI_MEM_SAFE_COPY_BLOCK_SIZE)
+ {
+ u32 size_to_copy;
+ u32 size_copied;
+ u32 bytes_left;
+
+ if (bytes_left_to_copy > MALI_MEM_SAFE_COPY_BLOCK_SIZE)
+ {
+ size_to_copy = MALI_MEM_SAFE_COPY_BLOCK_SIZE;
+ }
+ else
+ {
+ size_to_copy = bytes_left_to_copy;
+ }
+
+ bytes_left = copy_from_user(temp_buf, ((char*)src) + i, size_to_copy);
+ size_copied = size_to_copy - bytes_left;
+
+ bytes_left = copy_to_user(((char*)dest) + i, temp_buf, size_copied);
+ size_copied -= bytes_left;
+
+ bytes_left_to_copy -= size_copied;
+ retval += size_copied;
+
+ if (size_copied != size_to_copy)
+ {
+ break; /* Early out, we was not able to copy this entire block */
+ }
+ }
+
+ kfree(temp_buf);
+ }
+
+ return retval;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c
new file mode 100644
index 0000000..50d6ddf
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_mali.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_mali.c
+ * Implementation of the OS abstraction layer which is specific for the Mali kernel device driver
+ */
+#include <linux/kernel.h>
+#include <asm/uaccess.h>
+#include <linux/platform_device.h>
+#include <linux/mali/mali_utgard.h>
+
+#include "mali_osk_mali.h"
+#include "mali_kernel_common.h" /* MALI_xxx macros */
+#include "mali_osk.h" /* kernel side OS functions */
+#include "mali_uk_types.h"
+#include "mali_kernel_linux.h"
+
+_mali_osk_errcode_t _mali_osk_resource_find(u32 addr, _mali_osk_resource_t *res)
+{
+ int i;
+
+ if (NULL == mali_platform_device)
+ {
+ /* Not connected to a device */
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+ }
+
+ for (i = 0; i < mali_platform_device->num_resources; i++)
+ {
+ if (IORESOURCE_MEM == resource_type(&(mali_platform_device->resource[i])) &&
+ mali_platform_device->resource[i].start == addr)
+ {
+ if (NULL != res)
+ {
+ res->base = addr;
+ res->description = mali_platform_device->resource[i].name;
+
+ /* Any (optional) IRQ resource belonging to this resource will follow */
+ if ((i + 1) < mali_platform_device->num_resources &&
+ IORESOURCE_IRQ == resource_type(&(mali_platform_device->resource[i+1])))
+ {
+ res->irq = mali_platform_device->resource[i+1].start;
+ }
+ else
+ {
+ res->irq = -1;
+ }
+ }
+ return _MALI_OSK_ERR_OK;
+ }
+ }
+
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+}
+
+u32 _mali_osk_resource_base_address(void)
+{
+ u32 lowest_addr = 0xFFFFFFFF;
+ u32 ret = 0;
+
+ if (NULL != mali_platform_device)
+ {
+ int i;
+ for (i = 0; i < mali_platform_device->num_resources; i++)
+ {
+ if (mali_platform_device->resource[i].flags & IORESOURCE_MEM &&
+ mali_platform_device->resource[i].start < lowest_addr)
+ {
+ lowest_addr = mali_platform_device->resource[i].start;
+ ret = lowest_addr;
+ }
+ }
+ }
+
+ return ret;
+}
+
+_mali_osk_errcode_t _mali_osk_device_data_get(struct _mali_osk_device_data *data)
+{
+ MALI_DEBUG_ASSERT_POINTER(data);
+
+ if (NULL != mali_platform_device)
+ {
+ struct mali_gpu_device_data* os_data = NULL;
+
+ os_data = (struct mali_gpu_device_data*)mali_platform_device->dev.platform_data;
+ if (NULL != os_data)
+ {
+ /* Copy data from OS dependant struct to Mali neutral struct (identical!) */
+ data->dedicated_mem_start = os_data->dedicated_mem_start;
+ data->dedicated_mem_size = os_data->dedicated_mem_size;
+ data->shared_mem_size = os_data->shared_mem_size;
+ data->fb_start = os_data->fb_start;
+ data->fb_size = os_data->fb_size;
+ data->utilization_interval = os_data->utilization_interval;
+ data->utilization_callback = os_data->utilization_callback;
+ data->pmu_switch_delay = os_data->pmu_switch_delay;
+ return _MALI_OSK_ERR_OK;
+ }
+ }
+
+ return _MALI_OSK_ERR_ITEM_NOT_FOUND;
+}
+
+mali_bool _mali_osk_shared_interrupts(void)
+{
+ u32 irqs[128];
+ u32 i, j, irq, num_irqs_found = 0;
+
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ MALI_DEBUG_ASSERT(128 >= mali_platform_device->num_resources);
+
+ for (i = 0; i < mali_platform_device->num_resources; i++)
+ {
+ if (IORESOURCE_IRQ & mali_platform_device->resource[i].flags)
+ {
+ irq = mali_platform_device->resource[i].start;
+
+ for (j = 0; j < num_irqs_found; ++j)
+ {
+ if (irq == irqs[j])
+ {
+ return MALI_TRUE;
+ }
+ }
+
+ irqs[num_irqs_found++] = irq;
+ }
+ }
+
+ return MALI_FALSE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c
new file mode 100644
index 0000000..3e62e51
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_math.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_math.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include "mali_osk.h"
+#include <linux/bitops.h>
+
+u32 inline _mali_osk_clz( u32 input )
+{
+ return 32-fls(input);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c
new file mode 100644
index 0000000..7bb470f
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_memory.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_memory.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include "mali_osk.h"
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+
+void inline *_mali_osk_calloc( u32 n, u32 size )
+{
+ return kcalloc(n, size, GFP_KERNEL);
+}
+
+void inline *_mali_osk_malloc( u32 size )
+{
+ return kmalloc(size, GFP_KERNEL);
+}
+
+void inline _mali_osk_free( void *ptr )
+{
+ kfree(ptr);
+}
+
+void inline *_mali_osk_valloc( u32 size )
+{
+ return vmalloc(size);
+}
+
+void inline _mali_osk_vfree( void *ptr )
+{
+ vfree(ptr);
+}
+
+void inline *_mali_osk_memcpy( void *dst, const void *src, u32 len )
+{
+ return memcpy(dst, src, len);
+}
+
+void inline *_mali_osk_memset( void *s, u32 c, u32 n )
+{
+ return memset(s, c, n);
+}
+
+mali_bool _mali_osk_mem_check_allocated( u32 max_allocated )
+{
+ /* No need to prevent an out-of-memory dialogue appearing on Linux,
+ * so we always return MALI_TRUE.
+ */
+ return MALI_TRUE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c
new file mode 100644
index 0000000..ad486db
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_misc.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_misc.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+#include <linux/kernel.h>
+#include <asm/uaccess.h>
+#include <asm/cacheflush.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include "mali_osk.h"
+
+void _mali_osk_dbgmsg( const char *fmt, ... )
+{
+ va_list args;
+ va_start(args, fmt);
+ vprintk(fmt, args);
+ va_end(args);
+}
+
+u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... )
+{
+ int res;
+ va_list args;
+ va_start(args, fmt);
+
+ res = vscnprintf(buf, (size_t)size, fmt, args);
+
+ va_end(args);
+ return res;
+}
+
+void _mali_osk_abort(void)
+{
+ /* make a simple fault by dereferencing a NULL pointer */
+ dump_stack();
+ *(int *)0 = 0;
+}
+
+void _mali_osk_break(void)
+{
+ _mali_osk_abort();
+}
+
+u32 _mali_osk_get_pid(void)
+{
+ /* Thread group ID is the process ID on Linux */
+ return (u32)current->tgid;
+}
+
+u32 _mali_osk_get_tid(void)
+{
+ /* pid is actually identifying the thread on Linux */
+ return (u32)current->pid;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c
new file mode 100644
index 0000000..c265f88
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_notification.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_notification.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/**
+ * Declaration of the notification queue object type
+ * Contains a linked list of notification pending delivery to user space.
+ * It also contains a wait queue of exclusive waiters blocked in the ioctl
+ * When a new notification is posted a single thread is resumed.
+ */
+struct _mali_osk_notification_queue_t_struct
+{
+ spinlock_t mutex; /**< Mutex protecting the list */
+ wait_queue_head_t receive_queue; /**< Threads waiting for new entries to the queue */
+ struct list_head head; /**< List of notifications waiting to be picked up */
+};
+
+typedef struct _mali_osk_notification_wrapper_t_struct
+{
+ struct list_head list; /**< Internal linked list variable */
+ _mali_osk_notification_t data; /**< Notification data */
+} _mali_osk_notification_wrapper_t;
+
+_mali_osk_notification_queue_t *_mali_osk_notification_queue_init( void )
+{
+ _mali_osk_notification_queue_t * result;
+
+ result = (_mali_osk_notification_queue_t *)kmalloc(sizeof(_mali_osk_notification_queue_t), GFP_KERNEL);
+ if (NULL == result) return NULL;
+
+ spin_lock_init(&result->mutex);
+ init_waitqueue_head(&result->receive_queue);
+ INIT_LIST_HEAD(&result->head);
+
+ return result;
+}
+
+_mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
+{
+ /* OPT Recycling of notification objects */
+ _mali_osk_notification_wrapper_t *notification;
+
+ notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size,
+ GFP_KERNEL | __GFP_HIGH | __GFP_REPEAT);
+ if (NULL == notification)
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to create a notification object\n"));
+ return NULL;
+ }
+
+ /* Init the list */
+ INIT_LIST_HEAD(&notification->list);
+
+ if (0 != size)
+ {
+ notification->data.result_buffer = ((u8*)notification) + sizeof(_mali_osk_notification_wrapper_t);
+ }
+ else
+ {
+ notification->data.result_buffer = NULL;
+ }
+
+ /* set up the non-allocating fields */
+ notification->data.notification_type = type;
+ notification->data.result_buffer_size = size;
+
+ /* all ok */
+ return &(notification->data);
+}
+
+void _mali_osk_notification_delete( _mali_osk_notification_t *object )
+{
+ _mali_osk_notification_wrapper_t *notification;
+ MALI_DEBUG_ASSERT_POINTER( object );
+
+ notification = container_of( object, _mali_osk_notification_wrapper_t, data );
+
+ /* Free the container */
+ kfree(notification);
+}
+
+void _mali_osk_notification_queue_term( _mali_osk_notification_queue_t *queue )
+{
+ _mali_osk_notification_t *result;
+ MALI_DEBUG_ASSERT_POINTER( queue );
+
+ while (_MALI_OSK_ERR_OK == _mali_osk_notification_queue_dequeue(queue, &result))
+ {
+ _mali_osk_notification_delete( result );
+ }
+
+ /* not much to do, just free the memory */
+ kfree(queue);
+}
+void _mali_osk_notification_queue_send( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t *object )
+{
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ unsigned long irq_flags;
+#endif
+
+ _mali_osk_notification_wrapper_t *notification;
+ MALI_DEBUG_ASSERT_POINTER( queue );
+ MALI_DEBUG_ASSERT_POINTER( object );
+
+ notification = container_of( object, _mali_osk_notification_wrapper_t, data );
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_lock_irqsave(&queue->mutex, irq_flags);
+#else
+ spin_lock(&queue->mutex);
+#endif
+
+ list_add_tail(&notification->list, &queue->head);
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_unlock_irqrestore(&queue->mutex, irq_flags);
+#else
+ spin_unlock(&queue->mutex);
+#endif
+
+ /* and wake up one possible exclusive waiter */
+ wake_up(&queue->receive_queue);
+}
+
+_mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
+{
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ unsigned long irq_flags;
+#endif
+
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_ITEM_NOT_FOUND;
+ _mali_osk_notification_wrapper_t *wrapper_object;
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_lock_irqsave(&queue->mutex, irq_flags);
+#else
+ spin_lock(&queue->mutex);
+#endif
+
+ if (!list_empty(&queue->head))
+ {
+ wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list);
+ *result = &(wrapper_object->data);
+ list_del_init(&wrapper_object->list);
+ ret = _MALI_OSK_ERR_OK;
+ }
+
+#if defined(MALI_UPPER_HALF_SCHEDULING)
+ spin_unlock_irqrestore(&queue->mutex, irq_flags);
+#else
+ spin_unlock(&queue->mutex);
+#endif
+
+ return ret;
+}
+
+_mali_osk_errcode_t _mali_osk_notification_queue_receive( _mali_osk_notification_queue_t *queue, _mali_osk_notification_t **result )
+{
+ /* check input */
+ MALI_DEBUG_ASSERT_POINTER( queue );
+ MALI_DEBUG_ASSERT_POINTER( result );
+
+ /* default result */
+ *result = NULL;
+
+ if (wait_event_interruptible(queue->receive_queue,
+ _MALI_OSK_ERR_OK == _mali_osk_notification_queue_dequeue(queue, result)))
+ {
+ return _MALI_OSK_ERR_RESTARTSYSCALL;
+ }
+
+ return _MALI_OSK_ERR_OK; /* all ok */
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c
new file mode 100644
index 0000000..bc19af9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_pm.c
@@ -0,0 +1,110 @@
+/**
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_pm.c
+ * Implementation of the callback functions from common power management
+ */
+
+#include <linux/sched.h>
+
+#ifdef CONFIG_PM_RUNTIME
+#include <linux/pm_runtime.h>
+#endif /* CONFIG_PM_RUNTIME */
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_linux.h"
+
+static _mali_osk_atomic_t mali_pm_ref_count;
+
+void _mali_osk_pm_dev_enable(void)
+{
+ _mali_osk_atomic_init(&mali_pm_ref_count, 0);
+}
+
+void _mali_osk_pm_dev_disable(void)
+{
+ _mali_osk_atomic_term(&mali_pm_ref_count);
+}
+
+/* Can NOT run in atomic context */
+_mali_osk_errcode_t _mali_osk_pm_dev_ref_add(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ int err;
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ err = pm_runtime_get_sync(&(mali_platform_device->dev));
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_mark_last_busy(&(mali_platform_device->dev));
+#endif
+ if (0 > err)
+ {
+ MALI_PRINT_ERROR(("Mali OSK PM: pm_runtime_get_sync() returned error code %d\n", err));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ _mali_osk_atomic_inc(&mali_pm_ref_count);
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: Power ref taken (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+#endif
+ return _MALI_OSK_ERR_OK;
+}
+
+/* Can run in atomic context */
+void _mali_osk_pm_dev_ref_dec(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ _mali_osk_atomic_dec(&mali_pm_ref_count);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_mark_last_busy(&(mali_platform_device->dev));
+ pm_runtime_put_autosuspend(&(mali_platform_device->dev));
+#else
+ pm_runtime_put(&(mali_platform_device->dev));
+#endif
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: Power ref released (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+#endif
+}
+
+/* Can run in atomic context */
+mali_bool _mali_osk_pm_dev_ref_add_no_power_on(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ u32 ref;
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+ pm_runtime_get_noresume(&(mali_platform_device->dev));
+ ref = _mali_osk_atomic_read(&mali_pm_ref_count);
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: No-power ref taken (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+ return ref > 0 ? MALI_TRUE : MALI_FALSE;
+#else
+ return MALI_TRUE;
+#endif
+}
+
+/* Can run in atomic context */
+void _mali_osk_pm_dev_ref_dec_no_power_on(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ MALI_DEBUG_ASSERT_POINTER(mali_platform_device);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_put_autosuspend(&(mali_platform_device->dev));
+#else
+ pm_runtime_put(&(mali_platform_device->dev));
+#endif
+ MALI_DEBUG_PRINT(4, ("Mali OSK PM: No-power ref released (%u)\n", _mali_osk_atomic_read(&mali_pm_ref_count)));
+#endif
+}
+
+void _mali_osk_pm_dev_barrier(void)
+{
+#ifdef CONFIG_PM_RUNTIME
+ pm_runtime_barrier(&(mali_platform_device->dev));
+#endif
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c
new file mode 100644
index 0000000..5429329
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_profiling.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h>
+
+#include <mali_profiling_gator_api.h>
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_ukk.h"
+#include "mali_uk_types.h"
+#include "mali_osk_profiling.h"
+#include "mali_linux_trace.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_pp_scheduler.h"
+#include "mali_l2_cache.h"
+#include "mali_user_settings_db.h"
+
+_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
+{
+ if (MALI_TRUE == auto_start)
+ {
+ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_osk_profiling_term(void)
+{
+ /* Nothing to do */
+}
+
+_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit)
+{
+ /* Nothing to do */
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_osk_profiling_stop(u32 *count)
+{
+ /* Nothing to do */
+ return _MALI_OSK_ERR_OK;
+}
+
+u32 _mali_osk_profiling_get_count(void)
+{
+ return 0;
+}
+
+_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
+{
+ /* Nothing to do */
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_osk_profiling_clear(void)
+{
+ /* Nothing to do */
+ return _MALI_OSK_ERR_OK;
+}
+
+mali_bool _mali_osk_profiling_is_recording(void)
+{
+ return MALI_FALSE;
+}
+
+mali_bool _mali_osk_profiling_have_recording(void)
+{
+ return MALI_FALSE;
+}
+
+void _mali_osk_profiling_report_sw_counters(u32 *counters)
+{
+ trace_mali_sw_counters(_mali_osk_get_pid(), _mali_osk_get_tid(), NULL, counters);
+}
+
+
+_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
+{
+ return _mali_osk_profiling_start(&args->limit);
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_add_event(_mali_uk_profiling_add_event_s *args)
+{
+ /* Always add process and thread identificator in the first two data elements for events from user space */
+ _mali_osk_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_stop(_mali_uk_profiling_stop_s *args)
+{
+ return _mali_osk_profiling_stop(&args->count);
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_get_event(_mali_uk_profiling_get_event_s *args)
+{
+ return _mali_osk_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data);
+}
+
+_mali_osk_errcode_t _mali_ukk_profiling_clear(_mali_uk_profiling_clear_s *args)
+{
+ return _mali_osk_profiling_clear();
+}
+
+_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args)
+{
+ _mali_osk_profiling_report_sw_counters(args->counters);
+ return _MALI_OSK_ERR_OK;
+}
+
+/**
+ * Called by gator.ko to set HW counters
+ *
+ * @param counter_id The counter ID.
+ * @param event_id Event ID that the counter should count (HW counter value from TRM).
+ *
+ * @return 1 on success, 0 on failure.
+ */
+int _mali_profiling_set_event(u32 counter_id, s32 event_id)
+{
+ if (COUNTER_VP_0_C0 == counter_id)
+ {
+ if (MALI_TRUE == mali_gp_job_set_gp_counter_src0(event_id))
+ {
+ return 1;
+ }
+ }
+
+ if (COUNTER_VP_0_C1 == counter_id)
+ {
+ if (MALI_TRUE == mali_gp_job_set_gp_counter_src1(event_id))
+ {
+ return 1;
+ }
+ }
+
+ if (COUNTER_FP_0_C0 == counter_id)
+ {
+ if (MALI_TRUE == mali_pp_job_set_pp_counter_src0(event_id))
+ {
+ return 1;
+ }
+ }
+
+ if (COUNTER_FP_0_C1 == counter_id)
+ {
+ if (MALI_TRUE == mali_pp_job_set_pp_counter_src1(event_id))
+ {
+ return 1;
+ }
+ }
+
+ if (COUNTER_L2_0_C0 <= counter_id && COUNTER_L2_2_C1 >= counter_id)
+ {
+ u32 core_id = (counter_id - COUNTER_L2_0_C0) >> 1;
+ struct mali_l2_cache_core* l2_cache_core = mali_l2_cache_core_get_glob_l2_core(core_id);
+
+ if (NULL != l2_cache_core)
+ {
+ u32 counter_src = (counter_id - COUNTER_L2_0_C0) & 1;
+ if (0 == counter_src)
+ {
+ if (MALI_TRUE == mali_l2_cache_core_set_counter_src0(l2_cache_core, event_id))
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE == mali_l2_cache_core_set_counter_src1(l2_cache_core, event_id))
+ {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Called by gator.ko to retrieve the L2 cache counter values for all L2 cache cores.
+ * The L2 cache counters are unique in that they are polled by gator, rather than being
+ * transmitted via the tracepoint mechanism.
+ *
+ * @param values Pointer to a _mali_profiling_l2_counter_values structure where
+ * the counter sources and values will be output
+ * @return 0 if all went well; otherwise, return the mask with the bits set for the powered off cores
+ */
+u32 _mali_profiling_get_l2_counters(_mali_profiling_l2_counter_values *values)
+{
+ struct mali_l2_cache_core *l2_cache;
+ u32 l2_cores_num = mali_l2_cache_core_get_glob_num_l2_cores();
+ u32 i;
+ u32 ret = 0;
+
+ MALI_DEBUG_ASSERT(l2_cores_num <= 3);
+
+ for (i = 0; i < l2_cores_num; i++)
+ {
+ l2_cache = mali_l2_cache_core_get_glob_l2_core(i);
+
+ if (NULL == l2_cache)
+ {
+ continue;
+ }
+
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(l2_cache))
+ {
+ /* It is now safe to access the L2 cache core in order to retrieve the counters */
+ mali_l2_cache_core_get_counter_values(l2_cache,
+ &values->cores[i].source0,
+ &values->cores[i].value0,
+ &values->cores[i].source1,
+ &values->cores[i].value1);
+ }
+ else
+ {
+ /* The core was not available, set the right bit in the mask. */
+ ret |= (1 << i);
+ }
+ mali_l2_cache_unlock_power_state(l2_cache);
+ }
+
+ return ret;
+}
+
+/**
+ * Called by gator to control the production of profiling information at runtime.
+ */
+void _mali_profiling_control(u32 action, u32 value)
+{
+ switch(action)
+ {
+ case FBDUMP_CONTROL_ENABLE:
+ mali_set_user_setting(_MALI_UK_USER_SETTING_COLORBUFFER_CAPTURE_ENABLED, (value == 0 ? MALI_FALSE : MALI_TRUE));
+ break;
+ case FBDUMP_CONTROL_RATE:
+ mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_N_FRAMES, value);
+ break;
+ case SW_COUNTER_ENABLE:
+ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_COUNTER_ENABLED, value);
+ break;
+ case FBDUMP_CONTROL_RESIZE_FACTOR:
+ mali_set_user_setting(_MALI_UK_USER_SETTING_BUFFER_CAPTURE_RESIZE_FACTOR, value);
+ break;
+ default:
+ break; /* Ignore unimplemented actions */
+ }
+}
+
+/**
+ * Called by gator to get mali api version.
+ */
+u32 _mali_profiling_get_api_version(void)
+{
+ return MALI_PROFILING_API_VERSION;
+}
+
+/**
+* Called by gator to get the data about Mali instance in use:
+* product id, version, number of cores
+*/
+void _mali_profiling_get_mali_version(struct _mali_profiling_mali_version *values)
+{
+ values->mali_product_id = (u32)mali_kernel_core_get_product_id();
+ values->mali_version_major = mali_kernel_core_get_gpu_major_version();
+ values->mali_version_minor = mali_kernel_core_get_gpu_minor_version();
+ values->num_of_l2_cores = mali_l2_cache_core_get_glob_num_l2_cores();
+ values->num_of_fp_cores = mali_pp_scheduler_get_num_cores_total();
+ values->num_of_vp_cores = 1;
+}
+
+EXPORT_SYMBOL(_mali_profiling_set_event);
+EXPORT_SYMBOL(_mali_profiling_get_l2_counters);
+EXPORT_SYMBOL(_mali_profiling_control);
+EXPORT_SYMBOL(_mali_profiling_get_api_version);
+EXPORT_SYMBOL(_mali_profiling_get_mali_version);
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h
new file mode 100644
index 0000000..15d98e0
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_specific.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_specific.h
+ * Defines per-OS Kernel level specifics, such as unusual workarounds for
+ * certain OSs.
+ */
+
+#ifndef __MALI_OSK_SPECIFIC_H__
+#define __MALI_OSK_SPECIFIC_H__
+
+#include <asm/uaccess.h>
+
+#include "mali_sync.h"
+
+#define MALI_STATIC_INLINE static inline
+#define MALI_NON_STATIC_INLINE inline
+
+#ifdef CONFIG_SYNC
+typedef struct sync_timeline mali_sync_tl;
+typedef struct sync_pt mali_sync_pt;
+#endif /* CONFIG_SYNC */
+
+MALI_STATIC_INLINE u32 _mali_osk_copy_from_user(void *to, void *from, u32 n)
+{
+ return (u32)copy_from_user(to, from, (unsigned long)n);
+}
+
+#endif /* __MALI_OSK_SPECIFIC_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c
new file mode 100644
index 0000000..2aa6588
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_time.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_time.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include "mali_osk.h"
+#include <linux/jiffies.h>
+#include <linux/time.h>
+#include <asm/delay.h>
+
+int _mali_osk_time_after( u32 ticka, u32 tickb )
+{
+ return time_after((unsigned long)ticka, (unsigned long)tickb);
+}
+
+u32 _mali_osk_time_mstoticks( u32 ms )
+{
+ return msecs_to_jiffies(ms);
+}
+
+u32 _mali_osk_time_tickstoms( u32 ticks )
+{
+ return jiffies_to_msecs(ticks);
+}
+
+u32 _mali_osk_time_tickcount( void )
+{
+ return jiffies;
+}
+
+void _mali_osk_time_ubusydelay( u32 usecs )
+{
+ udelay(usecs);
+}
+
+u64 _mali_osk_time_get_ns( void )
+{
+ struct timespec tsval;
+ getnstimeofday(&tsval);
+ return (u64)timespec_to_ns(&tsval);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c
new file mode 100644
index 0000000..0e28b32
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_timers.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_timers.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/timer.h>
+#include <linux/slab.h>
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+struct _mali_osk_timer_t_struct
+{
+ struct timer_list timer;
+};
+
+typedef void (*timer_timeout_function_t)(unsigned long);
+
+_mali_osk_timer_t *_mali_osk_timer_init(void)
+{
+ _mali_osk_timer_t *t = (_mali_osk_timer_t*)kmalloc(sizeof(_mali_osk_timer_t), GFP_KERNEL);
+ if (NULL != t) init_timer(&t->timer);
+ return t;
+}
+
+void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ tim->timer.expires = jiffies + ticks_to_expire;
+ add_timer(&(tim->timer));
+}
+
+void _mali_osk_timer_mod( _mali_osk_timer_t *tim, u32 ticks_to_expire)
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ mod_timer(&(tim->timer), jiffies + ticks_to_expire);
+}
+
+void _mali_osk_timer_del( _mali_osk_timer_t *tim )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ del_timer_sync(&(tim->timer));
+}
+
+void _mali_osk_timer_del_async( _mali_osk_timer_t *tim )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ del_timer(&(tim->timer));
+}
+
+mali_bool _mali_osk_timer_pending( _mali_osk_timer_t *tim )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ return 1 == timer_pending(&(tim->timer));
+}
+
+void _mali_osk_timer_setcallback( _mali_osk_timer_t *tim, _mali_osk_timer_callback_t callback, void *data )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ tim->timer.data = (unsigned long)data;
+ tim->timer.function = (timer_timeout_function_t)callback;
+}
+
+void _mali_osk_timer_term( _mali_osk_timer_t *tim )
+{
+ MALI_DEBUG_ASSERT_POINTER(tim);
+ kfree(tim);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c
new file mode 100644
index 0000000..ce0561d
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wait_queue.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_wait_queue.c
+ * Implemenation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/wait.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+struct _mali_osk_wait_queue_t_struct
+{
+ wait_queue_head_t wait_queue;
+};
+
+_mali_osk_wait_queue_t* _mali_osk_wait_queue_init( void )
+{
+ _mali_osk_wait_queue_t* ret = NULL;
+
+ ret = kmalloc(sizeof(_mali_osk_wait_queue_t), GFP_KERNEL);
+
+ if (NULL == ret)
+ {
+ return ret;
+ }
+
+ init_waitqueue_head(&ret->wait_queue);
+ MALI_DEBUG_ASSERT(!waitqueue_active(&ret->wait_queue));
+
+ return ret;
+}
+
+void _mali_osk_wait_queue_wait_event( _mali_osk_wait_queue_t *queue, mali_bool (*condition)(void) )
+{
+ MALI_DEBUG_ASSERT_POINTER( queue );
+ MALI_DEBUG_PRINT(6, ("Adding to wait queue %p\n", queue));
+ wait_event(queue->wait_queue, condition());
+}
+
+void _mali_osk_wait_queue_wake_up( _mali_osk_wait_queue_t *queue )
+{
+ MALI_DEBUG_ASSERT_POINTER( queue );
+
+ /* if queue is empty, don't attempt to wake up its elements */
+ if (!waitqueue_active(&queue->wait_queue)) return;
+
+ MALI_DEBUG_PRINT(6, ("Waking up elements in wait queue %p ....\n", queue));
+
+ wake_up_all(&queue->wait_queue);
+
+ MALI_DEBUG_PRINT(6, ("... elements in wait queue %p woken up\n", queue));
+}
+
+void _mali_osk_wait_queue_term( _mali_osk_wait_queue_t *queue )
+{
+ /* Parameter validation */
+ MALI_DEBUG_ASSERT_POINTER( queue );
+
+ /* Linux requires no explicit termination of wait queues */
+ kfree(queue);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c
new file mode 100644
index 0000000..23f5720
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_osk_wq.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_osk_wq.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+#include <linux/slab.h> /* For memory allocation */
+#include <linux/workqueue.h>
+#include <linux/version.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_license.h"
+#include "mali_kernel_linux.h"
+
+typedef struct _mali_osk_wq_work_t_struct
+{
+ _mali_osk_wq_work_handler_t handler;
+ void *data;
+ struct work_struct work_handle;
+} mali_osk_wq_work_object_t;
+
+#if MALI_LICENSE_IS_GPL
+struct workqueue_struct *mali_wq = NULL;
+#endif
+
+static void _mali_osk_wq_work_func ( struct work_struct *work );
+
+_mali_osk_errcode_t _mali_osk_wq_init(void)
+{
+#if MALI_LICENSE_IS_GPL
+ MALI_DEBUG_ASSERT(NULL == mali_wq);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
+ mali_wq = alloc_workqueue("mali", WQ_UNBOUND, 0);
+#else
+ mali_wq = create_workqueue("mali");
+#endif
+ if(NULL == mali_wq)
+ {
+ MALI_PRINT_ERROR(("Unable to create Mali workqueue\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+#endif
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_osk_wq_flush(void)
+{
+#if MALI_LICENSE_IS_GPL
+ flush_workqueue(mali_wq);
+#else
+ flush_scheduled_work();
+#endif
+}
+
+void _mali_osk_wq_term(void)
+{
+#if MALI_LICENSE_IS_GPL
+ MALI_DEBUG_ASSERT(NULL != mali_wq);
+
+ flush_workqueue(mali_wq);
+ destroy_workqueue(mali_wq);
+ mali_wq = NULL;
+#else
+ flush_scheduled_work();
+#endif
+}
+
+_mali_osk_wq_work_t *_mali_osk_wq_create_work( _mali_osk_wq_work_handler_t handler, void *data )
+{
+ mali_osk_wq_work_object_t *work = kmalloc(sizeof(mali_osk_wq_work_object_t), GFP_KERNEL);
+
+ if (NULL == work) return NULL;
+
+ work->handler = handler;
+ work->data = data;
+
+ INIT_WORK( &work->work_handle, _mali_osk_wq_work_func );
+
+ return work;
+}
+
+void _mali_osk_wq_delete_work( _mali_osk_wq_work_t *work )
+{
+ mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
+ _mali_osk_wq_flush();
+ kfree(work_object);
+}
+
+void _mali_osk_wq_delete_work_nonflush( _mali_osk_wq_work_t *work )
+{
+ mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
+ kfree(work_object);
+}
+
+void _mali_osk_wq_schedule_work( _mali_osk_wq_work_t *work )
+{
+ mali_osk_wq_work_object_t *work_object = (mali_osk_wq_work_object_t *)work;
+#if MALI_LICENSE_IS_GPL
+ queue_work(mali_wq, &work_object->work_handle);
+#else
+ schedule_work(&work_object->work_handle);
+#endif
+}
+
+static void _mali_osk_wq_work_func ( struct work_struct *work )
+{
+ mali_osk_wq_work_object_t *work_object;
+
+ work_object = _MALI_OSK_CONTAINER_OF(work, mali_osk_wq_work_object_t, work_handle);
+ work_object->handler(work_object->data);
+}
+
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c
new file mode 100644
index 0000000..05dc291
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_pmu_power_up_down.c
@@ -0,0 +1,75 @@
+/**
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_pmu_power_up_down.c
+ */
+
+#include <linux/version.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_pmu.h"
+#include "mali_pp_scheduler.h"
+#include "linux/mali/mali_utgard.h"
+
+/* Mali PMU power up/down APIs */
+
+int mali_pmu_powerup(void)
+{
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(5, ("Mali PMU: Power up\n"));
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ if (NULL == pmu)
+ {
+ return -ENXIO;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_pmu_power_up_all(pmu))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(mali_pmu_powerup);
+
+int mali_pmu_powerdown(void)
+{
+ struct mali_pmu_core *pmu = mali_pmu_get_global_pmu_core();
+
+ MALI_DEBUG_PRINT(5, ("Mali PMU: Power down\n"));
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ if (NULL == pmu)
+ {
+ return -ENXIO;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_pmu_power_down_all(pmu))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(mali_pmu_powerdown);
+
+int mali_perf_set_num_pp_cores(unsigned int num_cores)
+{
+ return mali_pp_scheduler_set_perf_level(num_cores);
+}
+
+EXPORT_SYMBOL(mali_perf_set_num_pp_cores);
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h
new file mode 100644
index 0000000..2639a40
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_events.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PROFILING_EVENTS_H__
+#define __MALI_PROFILING_EVENTS_H__
+
+/* Simple wrapper in order to find the OS specific location of this file */
+#include <linux/mali/mali_utgard_profiling_events.h>
+
+#endif /* __MALI_PROFILING_EVENTS_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h
new file mode 100644
index 0000000..c111cfd
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_gator_api.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PROFILING_GATOR_API_H__
+#define __MALI_PROFILING_GATOR_API_H__
+
+/* Simple wrapper in order to find the OS specific location of this file */
+#include <linux/mali/mali_utgard_profiling_gator_api.h>
+
+#endif /* __MALI_PROFILING_GATOR_API_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c
new file mode 100644
index 0000000..e40a800
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.c
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_mali.h"
+#include "mali_ukk.h"
+#include "mali_timestamp.h"
+#include "mali_osk_profiling.h"
+#include "mali_user_settings_db.h"
+#include "mali_profiling_internal.h"
+
+typedef struct mali_profiling_entry
+{
+ u64 timestamp;
+ u32 event_id;
+ u32 data[5];
+} mali_profiling_entry;
+
+
+typedef enum mali_profiling_state
+{
+ MALI_PROFILING_STATE_UNINITIALIZED,
+ MALI_PROFILING_STATE_IDLE,
+ MALI_PROFILING_STATE_RUNNING,
+ MALI_PROFILING_STATE_RETURN,
+} mali_profiling_state;
+
+static _mali_osk_lock_t *lock = NULL;
+static mali_profiling_state prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
+static mali_profiling_entry* profile_entries = NULL;
+static _mali_osk_atomic_t profile_insert_index;
+static u32 profile_mask = 0;
+static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
+
+void probe_mali_timeline_event(void *data, TP_PROTO(unsigned int event_id, unsigned int d0, unsigned int d1, unsigned
+ int d2, unsigned int d3, unsigned int d4))
+{
+ add_event(event_id, d0, d1, d2, d3, d4);
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_init(mali_bool auto_start)
+{
+ profile_entries = NULL;
+ profile_mask = 0;
+ _mali_osk_atomic_init(&profile_insert_index, 0);
+
+ lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
+ if (NULL == lock)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ prof_state = MALI_PROFILING_STATE_IDLE;
+
+ if (MALI_TRUE == auto_start)
+ {
+ u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
+
+ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
+ if (_MALI_OSK_ERR_OK != _mali_internal_profiling_start(&limit))
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _mali_internal_profiling_term(void)
+{
+ u32 count;
+
+ /* Ensure profiling is stopped */
+ _mali_internal_profiling_stop(&count);
+
+ prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
+
+ if (NULL != profile_entries)
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ if (NULL != lock)
+ {
+ _mali_osk_lock_term(lock);
+ lock = NULL;
+ }
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_start(u32 * limit)
+{
+ _mali_osk_errcode_t ret;
+ mali_profiling_entry *new_profile_entries;
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (MALI_PROFILING_STATE_RUNNING == prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_BUSY;
+ }
+
+ new_profile_entries = _mali_osk_valloc(*limit * sizeof(mali_profiling_entry));
+
+ if (NULL == new_profile_entries)
+ {
+ _mali_osk_vfree(new_profile_entries);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ if (MALI_PROFILING_MAX_BUFFER_ENTRIES < *limit)
+ {
+ *limit = MALI_PROFILING_MAX_BUFFER_ENTRIES;
+ }
+
+ profile_mask = 1;
+ while (profile_mask <= *limit)
+ {
+ profile_mask <<= 1;
+ }
+ profile_mask >>= 1;
+
+ *limit = profile_mask;
+
+ profile_mask--; /* turns the power of two into a mask of one less */
+
+ if (MALI_PROFILING_STATE_IDLE != prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_vfree(new_profile_entries);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ profile_entries = new_profile_entries;
+
+ ret = _mali_timestamp_reset();
+
+ if (_MALI_OSK_ERR_OK == ret)
+ {
+ prof_state = MALI_PROFILING_STATE_RUNNING;
+ }
+ else
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ register_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return ret;
+}
+
+static inline void add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
+{
+ u32 cur_index = (_mali_osk_atomic_inc_return(&profile_insert_index) - 1) & profile_mask;
+
+ profile_entries[cur_index].timestamp = _mali_timestamp_get();
+ profile_entries[cur_index].event_id = event_id;
+ profile_entries[cur_index].data[0] = data0;
+ profile_entries[cur_index].data[1] = data1;
+ profile_entries[cur_index].data[2] = data2;
+ profile_entries[cur_index].data[3] = data3;
+ profile_entries[cur_index].data[4] = data4;
+
+ /* If event is "leave API function", add current memory usage to the event
+ * as data point 4. This is used in timeline profiling to indicate how
+ * much memory was used when leaving a function. */
+ if (event_id == (MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC))
+ {
+ profile_entries[cur_index].data[4] = _mali_ukk_report_memory_usage();
+ }
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_stop(u32 * count)
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (MALI_PROFILING_STATE_RUNNING != prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ /* go into return state (user to retreive events), no more events will be added after this */
+ prof_state = MALI_PROFILING_STATE_RETURN;
+
+ unregister_trace_mali_timeline_event(probe_mali_timeline_event, NULL);
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+
+ tracepoint_synchronize_unregister();
+
+ *count = _mali_osk_atomic_read(&profile_insert_index);
+ if (*count > profile_mask) *count = profile_mask;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+u32 _mali_internal_profiling_get_count(void)
+{
+ u32 retval = 0;
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+ if (MALI_PROFILING_STATE_RETURN == prof_state)
+ {
+ retval = _mali_osk_atomic_read(&profile_insert_index);
+ if (retval > profile_mask) retval = profile_mask;
+ }
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+
+ return retval;
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
+{
+ u32 raw_index = _mali_osk_atomic_read(&profile_insert_index);
+
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (index < profile_mask)
+ {
+ if ((raw_index & ~profile_mask) != 0)
+ {
+ index += raw_index;
+ index &= profile_mask;
+ }
+
+ if (prof_state != MALI_PROFILING_STATE_RETURN)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ if(index >= raw_index)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ *timestamp = profile_entries[index].timestamp;
+ *event_id = profile_entries[index].event_id;
+ data[0] = profile_entries[index].data[0];
+ data[1] = profile_entries[index].data[1];
+ data[2] = profile_entries[index].data[2];
+ data[3] = profile_entries[index].data[3];
+ data[4] = profile_entries[index].data[4];
+ }
+ else
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _mali_internal_profiling_clear(void)
+{
+ _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
+
+ if (MALI_PROFILING_STATE_RETURN != prof_state)
+ {
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_INVALID_ARGS; /* invalid to call this function in this state */
+ }
+
+ prof_state = MALI_PROFILING_STATE_IDLE;
+ profile_mask = 0;
+ _mali_osk_atomic_init(&profile_insert_index, 0);
+
+ if (NULL != profile_entries)
+ {
+ _mali_osk_vfree(profile_entries);
+ profile_entries = NULL;
+ }
+
+ _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ return _MALI_OSK_ERR_OK;
+}
+
+mali_bool _mali_internal_profiling_is_recording(void)
+{
+ return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
+}
+
+mali_bool _mali_internal_profiling_have_recording(void)
+{
+ return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h
new file mode 100644
index 0000000..092b9b0
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_profiling_internal.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_PROFILING_INTERNAL_H__
+#define __MALI_PROFILING_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "mali_osk.h"
+
+int _mali_internal_profiling_init(mali_bool auto_start);
+void _mali_internal_profiling_term(void);
+
+mali_bool _mali_internal_profiling_is_recording(void);
+mali_bool _mali_internal_profiling_have_recording(void);
+_mali_osk_errcode_t _mali_internal_profiling_clear(void);
+_mali_osk_errcode_t _mali_internal_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
+u32 _mali_internal_profiling_get_count(void);
+int _mali_internal_profiling_stop(u32 * count);
+int _mali_internal_profiling_start(u32 * limit);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_PROFILING_INTERNAL_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c
new file mode 100644
index 0000000..6293610
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_sync.c
+ *
+ */
+
+#include <linux/seq_file.h>
+#include <linux/sync.h>
+#include <linux/timer.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+
+struct mali_sync_timeline
+{
+ struct sync_timeline timeline;
+ atomic_t counter;
+ atomic_t signalled;
+};
+
+struct mali_sync_pt
+{
+ struct sync_pt pt;
+ u32 order;
+ s32 error;
+ struct timer_list timer;
+};
+
+static void mali_sync_timed_pt_timeout(unsigned long data);
+
+static inline struct mali_sync_timeline *to_mali_sync_timeline(struct sync_timeline *timeline)
+{
+ return container_of(timeline, struct mali_sync_timeline, timeline);
+}
+
+static inline struct mali_sync_pt *to_mali_sync_pt(struct sync_pt *pt)
+{
+ return container_of(pt, struct mali_sync_pt, pt);
+}
+
+static struct sync_pt *timeline_dup(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ struct mali_sync_pt *new_mpt;
+ struct sync_pt *new_pt = sync_pt_create(pt->parent, sizeof(struct mali_sync_pt));
+
+ if (!new_pt)
+ {
+ return NULL;
+ }
+
+ new_mpt = to_mali_sync_pt(new_pt);
+ new_mpt->order = mpt->order;
+
+ return new_pt;
+
+}
+
+static int timeline_has_signaled(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(pt->parent);
+ long diff;
+
+ if (0 != mpt->error)
+ {
+ return mpt->error;
+ }
+
+ diff = atomic_read(&mtl->signalled) - mpt->order;
+
+ return diff >= 0;
+}
+
+static int timeline_compare(struct sync_pt *a, struct sync_pt *b)
+{
+ struct mali_sync_pt *ma = container_of(a, struct mali_sync_pt, pt);
+ struct mali_sync_pt *mb = container_of(b, struct mali_sync_pt, pt);
+
+ long diff = ma->order - mb->order;
+
+ if (diff < 0)
+ {
+ return -1;
+ }
+ else if (diff == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+static void timeline_free_pt(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+
+ if (mpt->timer.function == mali_sync_timed_pt_timeout)
+ {
+ del_timer_sync(&mpt->timer);
+ }
+}
+
+static void timeline_print_tl(struct seq_file *s, struct sync_timeline *sync_timeline)
+{
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(sync_timeline);
+
+ seq_printf(s, "%u, %u", atomic_read(&mtl->signalled), atomic_read(&mtl->counter));
+}
+
+static void timeline_print_pt(struct seq_file *s, struct sync_pt *sync_pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(sync_pt);
+
+ seq_printf(s, "%u", mpt->order);
+
+}
+
+static struct sync_timeline_ops mali_timeline_ops = {
+ .driver_name = "Mali",
+ .dup = timeline_dup,
+ .has_signaled = timeline_has_signaled,
+ .compare = timeline_compare,
+ .free_pt = timeline_free_pt,
+ .print_obj = timeline_print_tl,
+ .print_pt = timeline_print_pt
+};
+
+int mali_sync_timeline_is_ours(struct sync_timeline *timeline)
+{
+ return (timeline->ops == &mali_timeline_ops);
+}
+
+struct sync_timeline *mali_sync_timeline_alloc(const char * name)
+{
+ struct sync_timeline *tl;
+ struct mali_sync_timeline *mtl;
+
+ tl = sync_timeline_create(&mali_timeline_ops,
+ sizeof(struct mali_sync_timeline), name);
+ if (!tl)
+ {
+ return NULL;
+ }
+
+ /* Set the counter in our private struct */
+ mtl = to_mali_sync_timeline(tl);
+ atomic_set(&mtl->counter, 0);
+ atomic_set(&mtl->signalled, 0);
+
+ return tl;
+}
+
+struct sync_pt *mali_sync_pt_alloc(struct sync_timeline *parent)
+{
+ struct sync_pt *pt = sync_pt_create(parent, sizeof(struct mali_sync_pt));
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(parent);
+ struct mali_sync_pt *mpt;
+
+ if (!pt)
+ {
+ return NULL;
+ }
+
+ mpt = to_mali_sync_pt(pt);
+ mpt->order = atomic_inc_return(&mtl->counter);
+ mpt->error = 0;
+
+ return pt;
+}
+
+static void mali_sync_timed_pt_timeout(unsigned long data)
+{
+ struct sync_pt *pt = (struct sync_pt *)data;
+
+ MALI_DEBUG_ASSERT_POINTER(pt);
+
+ mali_sync_signal_pt(pt, -ETIME);
+}
+
+struct sync_pt *mali_sync_timed_pt_alloc(struct sync_timeline *parent)
+{
+ struct sync_pt *pt;
+ struct mali_sync_pt *mpt;
+ const u32 timeout = msecs_to_jiffies(MALI_SYNC_TIMED_FENCE_TIMEOUT);
+
+ pt = mali_sync_pt_alloc(parent);
+ if (NULL == pt) return NULL;
+ mpt = to_mali_sync_pt(pt);
+
+ init_timer(&mpt->timer);
+
+ mpt->timer.function = mali_sync_timed_pt_timeout;
+ mpt->timer.data = (unsigned long)pt;
+ mpt->timer.expires = jiffies + timeout;
+
+ add_timer(&mpt->timer);
+
+ return pt;
+}
+
+/*
+ * Returns 0 if sync_pt has been committed and are ready for use, -ETIME if
+ * timeout already happened and the fence has been signalled.
+ *
+ * If an error occurs the sync point can not be used.
+ */
+int mali_sync_timed_commit(struct sync_pt *pt)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ int ret;
+
+ if (!mali_sync_timeline_is_ours(pt->parent))
+ {
+ return -EINVAL;
+ }
+
+ /* Stop timer */
+ ret = del_timer_sync(&mpt->timer);
+
+ if (0 == ret)
+ {
+ return -ETIME;
+ }
+
+ MALI_DEBUG_ASSERT(0 == timeline_has_signaled(pt));
+
+ return 0;
+}
+
+void mali_sync_signal_pt(struct sync_pt *pt, int error)
+{
+ struct mali_sync_pt *mpt = to_mali_sync_pt(pt);
+ struct mali_sync_timeline *mtl = to_mali_sync_timeline(pt->parent);
+ int signalled;
+ long diff;
+
+ if (0 != error)
+ {
+ MALI_DEBUG_ASSERT(0 > error);
+ mpt->error = error;
+ }
+
+ do {
+
+ signalled = atomic_read(&mtl->signalled);
+
+ diff = signalled - mpt->order;
+
+ if (diff > 0)
+ {
+ /* The timeline is already at or ahead of this point. This should not happen unless userspace
+ * has been signalling fences out of order, so warn but don't violate the sync_pt API.
+ * The warning is only in debug builds to prevent a malicious user being able to spam dmesg.
+ */
+ MALI_DEBUG_PRINT_ERROR(("Sync points were triggerd in a different order to allocation!\n"));
+ return;
+ }
+ } while (atomic_cmpxchg(&mtl->signalled, signalled, mpt->order) != signalled);
+
+ sync_timeline_signal(pt->parent);
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h
new file mode 100644
index 0000000..4415ec6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_sync.h
+ *
+ */
+
+#ifndef _MALI_SYNC_H_
+#define _MALI_SYNC_H_
+
+#ifdef CONFIG_SYNC
+
+#include <linux/seq_file.h>
+#include <linux/sync.h>
+
+#define MALI_SYNC_TIMED_FENCE_TIMEOUT 4000 /* 4s */
+
+/*
+ * Create a stream object.
+ * Built on top of timeline object.
+ * Exposed as a file descriptor.
+ * Life-time controlled via the file descriptor:
+ * - dup to add a ref
+ * - close to remove a ref
+ */
+_mali_osk_errcode_t mali_stream_create(const char * name, int * out_fd);
+
+/*
+ * Create a fence in a stream object
+ */
+struct sync_pt *mali_stream_create_point(int tl_fd);
+int mali_stream_create_fence(struct sync_pt *pt);
+int mali_stream_create_empty_fence(int tl_fd);
+
+/**
+ * Commit an empty timed fence
+ *
+ * This stops the timer of the empty fence and returns wether or not the fence
+ * is still suitable for use.
+ *
+ * Returns -ETIME if fence is already signalled, in which case it can not be
+ * used, or 0 when the timer was stopped and the fence is OK to use.
+ */
+int mali_sync_timed_commit(struct sync_pt *pt);
+
+/*
+ * Validate a fd to be a valid fence
+ * No reference is taken.
+ *
+ * This function is only usable to catch unintentional user errors early,
+ * it does not stop malicious code changing the fd after this function returns.
+ */
+_mali_osk_errcode_t mali_fence_validate(int fd);
+
+
+/* Returns true if the specified timeline is allocated by Mali */
+int mali_sync_timeline_is_ours(struct sync_timeline *timeline);
+
+/* Allocates a timeline for Mali
+ *
+ * One timeline should be allocated per API context.
+ */
+struct sync_timeline *mali_sync_timeline_alloc(const char *name);
+
+/* Allocates a sync point within the timeline.
+ *
+ * The timeline must be the one allocated by mali_sync_timeline_alloc
+ *
+ * Sync points must be triggered in *exactly* the same order as they are allocated.
+ */
+struct sync_pt *mali_sync_pt_alloc(struct sync_timeline *parent);
+
+/* Allocates a timed sync point within the timeline.
+ *
+ * The timeline must be the one allocated by mali_sync_timeline_alloc
+ *
+ * Sync points must be triggered in *exactly* the same order as they are allocated.
+ *
+ * Timed sync points should be backed by a proper event before reaching the
+ * timeout. If timeout is reached the fence will be signalled with an error (-ETIME).
+ */
+struct sync_pt *mali_sync_timed_pt_alloc(struct sync_timeline *parent);
+
+/* Signals a particular sync point
+ *
+ * Sync points must be triggered in *exactly* the same order as they are allocated.
+ *
+ * If they are signalled in the wrong order then a message will be printed in debug
+ * builds and otherwise attempts to signal order sync_pts will be ignored.
+ */
+void mali_sync_signal_pt(struct sync_pt *pt, int error);
+
+#endif /* CONFIG_SYNC */
+#endif /* _MALI_SYNC_H_ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c
new file mode 100644
index 0000000..7f0fddfc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_sync_user.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_sync_user.c
+ *
+ */
+
+#ifdef CONFIG_SYNC
+
+#include <linux/sched.h>
+#include <linux/fdtable.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/module.h>
+#include <linux/anon_inodes.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_sync.h"
+
+static int mali_stream_close(struct inode * inode, struct file * file)
+{
+ struct sync_timeline * tl;
+ tl = (struct sync_timeline*)file->private_data;
+ BUG_ON(!tl);
+ sync_timeline_destroy(tl);
+ return 0;
+}
+
+static struct file_operations stream_fops =
+{
+ .owner = THIS_MODULE,
+ .release = mali_stream_close,
+};
+
+_mali_osk_errcode_t mali_stream_create(const char * name, int *out_fd)
+{
+ struct sync_timeline * tl;
+ BUG_ON(!out_fd);
+
+ tl = mali_sync_timeline_alloc(name);
+ if (!tl)
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ *out_fd = anon_inode_getfd(name, &stream_fops, tl, O_RDONLY | O_CLOEXEC);
+
+ if (*out_fd < 0)
+ {
+ sync_timeline_destroy(tl);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ else
+ {
+ return _MALI_OSK_ERR_OK;
+ }
+}
+
+static mali_sync_pt *mali_stream_create_point_internal(int tl_fd, mali_bool timed)
+{
+ struct sync_timeline *tl;
+ struct sync_pt * pt;
+ struct file *tl_file;
+
+ tl_file = fget(tl_fd);
+ if (tl_file == NULL)
+ return NULL;
+
+ if (tl_file->f_op != &stream_fops)
+ {
+ pt = NULL;
+ goto out;
+ }
+
+ tl = tl_file->private_data;
+
+ if (unlikely(timed))
+ {
+ pt = mali_sync_timed_pt_alloc(tl);
+ }
+ else
+ {
+ pt = mali_sync_pt_alloc(tl);
+ }
+
+ if (!pt)
+ {
+ pt = NULL;
+ goto out;
+ }
+
+out:
+ fput(tl_file);
+
+ return pt;
+}
+
+mali_sync_pt *mali_stream_create_point(int tl_fd)
+{
+ return mali_stream_create_point_internal(tl_fd, MALI_FALSE);
+}
+
+int mali_stream_create_fence(mali_sync_pt *pt)
+{
+ struct sync_fence *fence;
+ struct fdtable * fdt;
+ struct files_struct * files;
+ int fd = -1;
+
+ fence = sync_fence_create("mali_fence", pt);
+ if (!fence)
+ {
+ sync_pt_free(pt);
+ fd = -EFAULT;
+ goto out;
+ }
+
+ /* create a fd representing the fence */
+ fd = get_unused_fd();
+ if (fd < 0)
+ {
+ sync_fence_put(fence);
+ goto out;
+ }
+
+ files = current->files;
+ spin_lock(&files->file_lock);
+ fdt = files_fdtable(files);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ __set_close_on_exec(fd, fdt);
+#else
+ FD_SET(fd, fdt->close_on_exec);
+#endif
+ spin_unlock(&files->file_lock);
+
+ /* bind fence to the new fd */
+ sync_fence_install(fence, fd);
+
+out:
+ return fd;
+}
+
+int mali_stream_create_empty_fence(int tl_fd)
+{
+ int fd;
+ mali_sync_pt *pt;
+
+ pt = mali_stream_create_point_internal(tl_fd, MALI_TRUE);
+
+ if (NULL == pt) return -ENOMEM;
+
+ fd = mali_stream_create_fence(pt);
+
+ return fd;
+}
+
+_mali_osk_errcode_t mali_fence_validate(int fd)
+{
+ struct sync_fence * fence;
+ fence = sync_fence_fdget(fd);
+ if (NULL != fence)
+ {
+ sync_fence_put(fence);
+ return _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+}
+
+#endif /* CONFIG_SYNC */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h
new file mode 100644
index 0000000..fbe902a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_uk_types.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_UK_TYPES_H__
+#define __MALI_UK_TYPES_H__
+
+/* Simple wrapper in order to find the OS specific location of this file */
+#include <linux/mali/mali_utgard_uk_types.h>
+
+#endif /* __MALI_UK_TYPES_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c
new file mode 100644
index 0000000..1768ff2
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_core.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <linux/slab.h> /* memort allocation functions */
+#include <asm/uaccess.h> /* user space access */
+#include <linux/pid.h>
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_ukk_wrappers.h"
+#include "mali_sync.h"
+
+int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs)
+{
+ _mali_uk_get_api_version_s kargs;
+ _mali_osk_errcode_t err;
+
+ u32 mem = _mali_ukk_report_memory_usage();
+ printk("Mali: mem_usage before %d : %u\n", _mali_osk_get_pid(), mem);
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != get_user(kargs.version, &uargs->version)) return -EFAULT;
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_get_api_version(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT;
+ if (0 != put_user(kargs.compatible, &uargs->compatible)) return -EFAULT;
+
+ return 0;
+}
+
+int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs)
+{
+ _mali_uk_wait_for_notification_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_wait_for_notification(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ if(_MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS != kargs.type)
+ {
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_wait_for_notification_s))) return -EFAULT;
+ }
+ else
+ {
+ if (0 != put_user(kargs.type, &uargs->type)) return -EFAULT;
+ }
+
+ return 0;
+}
+
+int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs)
+{
+ _mali_uk_post_notification_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+
+ if (0 != get_user(kargs.type, &uargs->type))
+ {
+ return -EFAULT;
+ }
+
+ err = _mali_ukk_post_notification(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
+int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs)
+{
+ _mali_uk_get_user_settings_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_get_user_settings(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_get_user_settings_s))) return -EFAULT;
+
+ return 0;
+}
+
+#ifdef CONFIG_SYNC
+int stream_create_wrapper(struct mali_session_data *session_data, _mali_uk_stream_create_s __user *uargs)
+{
+ _mali_uk_stream_create_s kargs;
+ _mali_osk_errcode_t err;
+ char name[32];
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ snprintf(name, 32, "mali-%u", _mali_osk_get_pid());
+
+ kargs.ctx = session_data;
+ err = mali_stream_create(name, &kargs.fd);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_stream_create_s))) return -EFAULT;
+
+ return 0;
+}
+
+int sync_fence_create_empty_wrapper(struct mali_session_data *session_data, _mali_uk_fence_create_empty_s __user *uargs)
+{
+ _mali_uk_fence_create_empty_s kargs;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != get_user(kargs.stream, &uargs->stream)) return -EFAULT;
+
+ kargs.fence = mali_stream_create_empty_fence(kargs.stream);
+ if (0 > kargs.fence)
+ {
+ return kargs.fence;
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_fence_create_empty_s))) return -EFAULT;
+
+ return 0;
+}
+
+int sync_fence_validate_wrapper(struct mali_session_data *session, _mali_uk_fence_validate_s __user *uargs)
+{
+ int fd;
+ _mali_osk_errcode_t err;
+
+ if (0 != get_user(fd, &uargs->fd))
+ {
+ return -EFAULT;
+ }
+
+ err = mali_fence_validate(fd);
+
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ return 0;
+ }
+
+ return -EINVAL;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c
new file mode 100644
index 0000000..4ee4a81
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_gp.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_ukk_wrappers.h"
+
+int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs)
+{
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ err = _mali_ukk_gp_start_job(session_data, uargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ return 0;
+}
+
+int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs)
+{
+ _mali_uk_get_gp_core_version_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_get_gp_core_version(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ /* no known transactions to roll-back */
+
+ if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT;
+
+ return 0;
+}
+
+int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs)
+{
+ _mali_uk_gp_suspend_response_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_gp_suspend_response_s))) return -EFAULT;
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_gp_suspend_response(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ if (0 != put_user(kargs.cookie, &uargs->cookie)) return -EFAULT;
+
+ /* no known transactions to roll-back */
+ return 0;
+}
+
+int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs)
+{
+ _mali_uk_get_gp_number_of_cores_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_get_gp_number_of_cores(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ /* no known transactions to roll-back */
+
+ if (0 != put_user(kargs.number_of_cores, &uargs->number_of_cores)) return -EFAULT;
+
+ return 0;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c
new file mode 100644
index 0000000..7d1d23d
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_mem.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_ukk_wrappers.h"
+
+int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs)
+{
+ _mali_uk_init_mem_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_init_mem(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ if (0 != put_user(kargs.mali_address_base, &uargs->mali_address_base)) goto mem_init_rollback;
+ if (0 != put_user(kargs.memory_size, &uargs->memory_size)) goto mem_init_rollback;
+
+ return 0;
+
+mem_init_rollback:
+ {
+ _mali_uk_term_mem_s kargs;
+ kargs.ctx = session_data;
+ err = _mali_ukk_term_mem(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_init_mem, as a result of failing put_user(), failed\n"));
+ }
+ }
+ return -EFAULT;
+}
+
+int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs)
+{
+ _mali_uk_term_mem_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_term_mem(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
+int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user * uargs)
+{
+ _mali_uk_mem_write_safe_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_mem_write_safe_s)))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+
+ /* Check if we can access the buffers */
+ if (!access_ok(VERIFY_WRITE, kargs.dest, kargs.size)
+ || !access_ok(VERIFY_READ, kargs.src, kargs.size))
+ {
+ return -EINVAL;
+ }
+
+ /* Check if size wraps */
+ if ((kargs.size + kargs.dest) <= kargs.dest
+ || (kargs.size + kargs.src) <= kargs.src)
+ {
+ return -EINVAL;
+ }
+
+ err = _mali_ukk_mem_write_safe(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ if (0 != put_user(kargs.size, &uargs->size))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument)
+{
+ _mali_uk_map_external_mem_s uk_args;
+ _mali_osk_errcode_t err_code;
+
+ /* validate input */
+ /* the session_data pointer was validated by caller */
+ MALI_CHECK_NON_NULL( argument, -EINVAL);
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_map_external_mem_s)) )
+ {
+ return -EFAULT;
+ }
+
+ uk_args.ctx = session_data;
+ err_code = _mali_ukk_map_external_mem( &uk_args );
+
+ if (0 != put_user(uk_args.cookie, &argument->cookie))
+ {
+ if (_MALI_OSK_ERR_OK == err_code)
+ {
+ /* Rollback */
+ _mali_uk_unmap_external_mem_s uk_args_unmap;
+
+ uk_args_unmap.ctx = session_data;
+ uk_args_unmap.cookie = uk_args.cookie;
+ err_code = _mali_ukk_unmap_external_mem( &uk_args_unmap );
+ if (_MALI_OSK_ERR_OK != err_code)
+ {
+ MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_unmap_external_mem, as a result of failing put_user(), failed\n"));
+ }
+ }
+ return -EFAULT;
+ }
+
+ /* Return the error that _mali_ukk_free_big_block produced */
+ return map_errcode(err_code);
+}
+
+int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument)
+{
+ _mali_uk_unmap_external_mem_s uk_args;
+ _mali_osk_errcode_t err_code;
+
+ /* validate input */
+ /* the session_data pointer was validated by caller */
+ MALI_CHECK_NON_NULL( argument, -EINVAL);
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_unmap_external_mem_s)) )
+ {
+ return -EFAULT;
+ }
+
+ uk_args.ctx = session_data;
+ err_code = _mali_ukk_unmap_external_mem( &uk_args );
+
+ /* Return the error that _mali_ukk_free_big_block produced */
+ return map_errcode(err_code);
+}
+
+#if defined(CONFIG_MALI400_UMP)
+int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument)
+{
+ _mali_uk_release_ump_mem_s uk_args;
+ _mali_osk_errcode_t err_code;
+
+ /* validate input */
+ /* the session_data pointer was validated by caller */
+ MALI_CHECK_NON_NULL( argument, -EINVAL);
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_release_ump_mem_s)) )
+ {
+ return -EFAULT;
+ }
+
+ uk_args.ctx = session_data;
+ err_code = _mali_ukk_release_ump_mem( &uk_args );
+
+ /* Return the error that _mali_ukk_free_big_block produced */
+ return map_errcode(err_code);
+}
+
+int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument)
+{
+ _mali_uk_attach_ump_mem_s uk_args;
+ _mali_osk_errcode_t err_code;
+
+ /* validate input */
+ /* the session_data pointer was validated by caller */
+ MALI_CHECK_NON_NULL( argument, -EINVAL);
+
+ /* get call arguments from user space. copy_from_user returns how many bytes which where NOT copied */
+ if ( 0 != copy_from_user(&uk_args, (void __user *)argument, sizeof(_mali_uk_attach_ump_mem_s)) )
+ {
+ return -EFAULT;
+ }
+
+ uk_args.ctx = session_data;
+ err_code = _mali_ukk_attach_ump_mem( &uk_args );
+
+ if (0 != put_user(uk_args.cookie, &argument->cookie))
+ {
+ if (_MALI_OSK_ERR_OK == err_code)
+ {
+ /* Rollback */
+ _mali_uk_release_ump_mem_s uk_args_unmap;
+
+ uk_args_unmap.ctx = session_data;
+ uk_args_unmap.cookie = uk_args.cookie;
+ err_code = _mali_ukk_release_ump_mem( &uk_args_unmap );
+ if (_MALI_OSK_ERR_OK != err_code)
+ {
+ MALI_DEBUG_PRINT(4, ("reverting _mali_ukk_attach_mem, as a result of failing put_user(), failed\n"));
+ }
+ }
+ return -EFAULT;
+ }
+
+ /* Return the error that _mali_ukk_map_external_ump_mem produced */
+ return map_errcode(err_code);
+}
+#endif /* CONFIG_MALI400_UMP */
+
+int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs)
+{
+ _mali_uk_query_mmu_page_table_dump_size_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ kargs.ctx = session_data;
+
+ err = _mali_ukk_query_mmu_page_table_dump_size(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ if (0 != put_user(kargs.size, &uargs->size)) return -EFAULT;
+
+ return 0;
+}
+
+int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs)
+{
+ _mali_uk_dump_mmu_page_table_s kargs;
+ _mali_osk_errcode_t err;
+ void *buffer;
+ int rc = -EFAULT;
+
+ /* validate input */
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ /* the session_data pointer was validated by caller */
+
+ kargs.buffer = NULL;
+
+ /* get location of user buffer */
+ if (0 != get_user(buffer, &uargs->buffer)) goto err_exit;
+ /* get size of mmu page table info buffer from user space */
+ if ( 0 != get_user(kargs.size, &uargs->size) ) goto err_exit;
+ /* verify we can access the whole of the user buffer */
+ if (!access_ok(VERIFY_WRITE, buffer, kargs.size)) goto err_exit;
+
+ /* allocate temporary buffer (kernel side) to store mmu page table info */
+ MALI_CHECK(kargs.size > 0, -ENOMEM);
+ kargs.buffer = _mali_osk_valloc(kargs.size);
+ if (NULL == kargs.buffer)
+ {
+ rc = -ENOMEM;
+ goto err_exit;
+ }
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_dump_mmu_page_table(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ rc = map_errcode(err);
+ goto err_exit;
+ }
+
+ /* copy mmu page table info back to user space and update pointers */
+ if (0 != copy_to_user(uargs->buffer, kargs.buffer, kargs.size) ) goto err_exit;
+ if (0 != put_user((kargs.register_writes - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->register_writes)) goto err_exit;
+ if (0 != put_user((kargs.page_table_dump - (u32 *)kargs.buffer) + (u32 *)uargs->buffer, &uargs->page_table_dump)) goto err_exit;
+ if (0 != put_user(kargs.register_writes_size, &uargs->register_writes_size)) goto err_exit;
+ if (0 != put_user(kargs.page_table_dump_size, &uargs->page_table_dump_size)) goto err_exit;
+ rc = 0;
+
+err_exit:
+ if (kargs.buffer) _mali_osk_vfree(kargs.buffer);
+ return rc;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c
new file mode 100644
index 0000000..6663e7f
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_pp.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_ukk_wrappers.h"
+
+int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs)
+{
+ _mali_osk_errcode_t err;
+ int fence = -1;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ err = _mali_ukk_pp_start_job(session_data, uargs, &fence);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+#if defined(CONFIG_SYNC)
+ if (0 != put_user(fence, &uargs->fence))
+ {
+ /* Since the job has started we can't return an error. */
+ }
+#endif /* CONFIG_SYNC */
+
+ return 0;
+}
+
+int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs)
+{
+ _mali_uk_get_pp_number_of_cores_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ kargs.ctx = session_data;
+
+ err = _mali_ukk_get_pp_number_of_cores(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_get_pp_number_of_cores_s)))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs)
+{
+ _mali_uk_get_pp_core_version_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_get_pp_core_version(&kargs);
+ if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
+
+ if (0 != put_user(kargs.version, &uargs->version)) return -EFAULT;
+
+ return 0;
+}
+
+int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs)
+{
+ _mali_uk_pp_disable_wb_s kargs;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+ MALI_CHECK_NON_NULL(session_data, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_pp_disable_wb_s))) return -EFAULT;
+
+ kargs.ctx = session_data;
+ _mali_ukk_pp_job_disable_wb(&kargs);
+
+ return 0;
+}
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c
new file mode 100644
index 0000000..f4e31c9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_profiling.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+#include <linux/slab.h>
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_ukk_wrappers.h"
+
+int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs)
+{
+ _mali_uk_profiling_start_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_start_s)))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_profiling_start(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ if (0 != put_user(kargs.limit, &uargs->limit))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs)
+{
+ _mali_uk_profiling_add_event_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_profiling_add_event_s)))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_profiling_add_event(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
+int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs)
+{
+ _mali_uk_profiling_stop_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_profiling_stop(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ if (0 != put_user(kargs.count, &uargs->count))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs)
+{
+ _mali_uk_profiling_get_event_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != get_user(kargs.index, &uargs->index))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+
+ err = _mali_ukk_profiling_get_event(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ kargs.ctx = NULL; /* prevent kernel address to be returned to user space */
+ if (0 != copy_to_user(uargs, &kargs, sizeof(_mali_uk_profiling_get_event_s)))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs)
+{
+ _mali_uk_profiling_clear_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_profiling_clear(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
+int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
+{
+ _mali_uk_sw_counters_report_s kargs;
+ _mali_osk_errcode_t err;
+ u32 *counter_buffer;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s)))
+ {
+ return -EFAULT;
+ }
+
+ /* make sure that kargs.num_counters is [at least somewhat] sane */
+ if (kargs.num_counters > 10000) {
+ MALI_DEBUG_PRINT(1, ("User space attempted to allocate too many counters.\n"));
+ return -EINVAL;
+ }
+
+ counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
+ if (NULL == counter_buffer)
+ {
+ return -ENOMEM;
+ }
+
+ if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters))
+ {
+ kfree(counter_buffer);
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+ kargs.counters = counter_buffer;
+
+ err = _mali_ukk_sw_counters_report(&kargs);
+
+ kfree(counter_buffer);
+
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
+
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c
new file mode 100644
index 0000000..f9b5a3e
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_vsync.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#include <linux/fs.h> /* file system operations */
+#include <asm/uaccess.h> /* user space access */
+
+#include "mali_ukk.h"
+#include "mali_osk.h"
+#include "mali_kernel_common.h"
+#include "mali_session.h"
+#include "mali_ukk_wrappers.h"
+
+
+int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs)
+{
+ _mali_uk_vsync_event_report_s kargs;
+ _mali_osk_errcode_t err;
+
+ MALI_CHECK_NON_NULL(uargs, -EINVAL);
+
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_vsync_event_report_s)))
+ {
+ return -EFAULT;
+ }
+
+ kargs.ctx = session_data;
+ err = _mali_ukk_vsync_event_report(&kargs);
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
+
+ return 0;
+}
+
diff --git a/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h
new file mode 100644
index 0000000..08bdae4
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/linux/mali_ukk_wrappers.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file mali_ukk_wrappers.h
+ * Defines the wrapper functions for each user-kernel function
+ */
+
+#ifndef __MALI_UKK_WRAPPERS_H__
+#define __MALI_UKK_WRAPPERS_H__
+
+#include "mali_uk_types.h"
+#include "mali_osk.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+int wait_for_notification_wrapper(struct mali_session_data *session_data, _mali_uk_wait_for_notification_s __user *uargs);
+int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs);
+int get_user_settings_wrapper(struct mali_session_data *session_data, _mali_uk_get_user_settings_s __user *uargs);
+#if defined(CONFIG_SYNC)
+int stream_create_wrapper(struct mali_session_data *session_data, _mali_uk_stream_create_s __user *uargs);
+int sync_fence_create_empty_wrapper(struct mali_session_data *session_data, _mali_uk_fence_create_empty_s __user *uargs);
+int sync_fence_validate_wrapper(struct mali_session_data *session, _mali_uk_fence_validate_s __user *uargs);
+#endif
+int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_post_notification_s __user *uargs);
+int mem_init_wrapper(struct mali_session_data *session_data, _mali_uk_init_mem_s __user *uargs);
+int mem_term_wrapper(struct mali_session_data *session_data, _mali_uk_term_mem_s __user *uargs);
+int mem_write_safe_wrapper(struct mali_session_data *session_data, _mali_uk_mem_write_safe_s __user * uargs);
+int mem_map_ext_wrapper(struct mali_session_data *session_data, _mali_uk_map_external_mem_s __user * argument);
+int mem_unmap_ext_wrapper(struct mali_session_data *session_data, _mali_uk_unmap_external_mem_s __user * argument);
+int mem_query_mmu_page_table_dump_size_wrapper(struct mali_session_data *session_data, _mali_uk_query_mmu_page_table_dump_size_s __user * uargs);
+int mem_dump_mmu_page_table_wrapper(struct mali_session_data *session_data, _mali_uk_dump_mmu_page_table_s __user * uargs);
+
+#if defined(CONFIG_MALI400_UMP)
+int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_attach_ump_mem_s __user * argument);
+int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument);
+#endif
+
+int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs);
+int pp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_number_of_cores_s __user *uargs);
+int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_pp_core_version_s __user *uargs);
+int pp_disable_wb_wrapper(struct mali_session_data *session_data, _mali_uk_pp_disable_wb_s __user *uargs);
+int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_start_job_s __user *uargs);
+int gp_get_number_of_cores_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_number_of_cores_s __user *uargs);
+int gp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_gp_core_version_s __user *uargs);
+int gp_suspend_response_wrapper(struct mali_session_data *session_data, _mali_uk_gp_suspend_response_s __user *uargs);
+
+int profiling_start_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_start_s __user *uargs);
+int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_add_event_s __user *uargs);
+int profiling_stop_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_stop_s __user *uargs);
+int profiling_get_event_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_event_s __user *uargs);
+int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_clear_s __user *uargs);
+int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs);
+
+int vsync_event_report_wrapper(struct mali_session_data *session_data, _mali_uk_vsync_event_report_s __user *uargs);
+
+
+int map_errcode( _mali_osk_errcode_t err );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MALI_UKK_WRAPPERS_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c
new file mode 100644
index 0000000..bf83249
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4.c
@@ -0,0 +1,405 @@
+/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4.c
+ *
+ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
+ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
+ *
+ * Samsung SoC Mali400 DVFS driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software FoundatIon.
+ */
+
+/**
+ * @file exynos4.c
+ * Platform specific Mali driver functions for the exynos 4XXX based platforms
+ */
+#include <linux/platform_device.h>
+#include <linux/version.h>
+#include <linux/pm.h>
+#include <linux/suspend.h>
+
+#ifdef CONFIG_PM_RUNTIME
+#include <linux/pm_runtime.h>
+#endif
+
+#ifdef CONFIG_MALI_DVFS
+#include "mali_kernel_utilization.h"
+#endif /* CONFIG_MALI_DVFS */
+
+#include <linux/mali/mali_utgard.h>
+#include "mali_kernel_common.h"
+#include "mali_kernel_linux.h"
+#include "mali_pm.h"
+
+#include <plat/pd.h>
+
+#include "exynos4_pmm.h"
+
+#if defined(CONFIG_PM_RUNTIME)
+/* We does not need PM NOTIFIER in r3p2 DDK */
+//#define USE_PM_NOTIFIER
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+struct exynos_pm_domain;
+extern struct exynos_pm_domain exynos4_pd_g3d;
+void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, struct exynos_pm_domain *pd);
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+extern struct platform_device exynos4_device_pd[];
+#else
+extern struct platform_device s5pv310_device_pd[];
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+
+static void mali_platform_device_release(struct device *device);
+
+#if defined(CONFIG_PM_RUNTIME)
+#if defined(USE_PM_NOTIFIER)
+static int mali_os_suspend(struct device *device);
+static int mali_os_resume(struct device *device);
+static int mali_os_freeze(struct device *device);
+static int mali_os_thaw(struct device *device);
+
+static int mali_runtime_suspend(struct device *device);
+static int mali_runtime_resume(struct device *device);
+static int mali_runtime_idle(struct device *device);
+#endif
+#endif
+
+#if defined(CONFIG_ARCH_S5PV310) && !defined(CONFIG_BOARD_HKDKC210)
+
+/* This is for other SMDK boards */
+#define MALI_BASE_IRQ 232
+
+#else
+
+/* This is for the Odroid boards */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
+#define MALI_BASE_IRQ 182
+#else
+#define MALI_BASE_IRQ 150
+#endif
+
+#endif
+
+#define MALI_GP_IRQ MALI_BASE_IRQ + 9
+#define MALI_PP0_IRQ MALI_BASE_IRQ + 5
+#define MALI_PP1_IRQ MALI_BASE_IRQ + 6
+#define MALI_PP2_IRQ MALI_BASE_IRQ + 7
+#define MALI_PP3_IRQ MALI_BASE_IRQ + 8
+#define MALI_GP_MMU_IRQ MALI_BASE_IRQ + 4
+#define MALI_PP0_MMU_IRQ MALI_BASE_IRQ + 0
+#define MALI_PP1_MMU_IRQ MALI_BASE_IRQ + 1
+#define MALI_PP2_MMU_IRQ MALI_BASE_IRQ + 2
+#define MALI_PP3_MMU_IRQ MALI_BASE_IRQ + 3
+
+static struct resource mali_gpu_resources[] =
+{
+ MALI_GPU_RESOURCES_MALI400_MP4(0x13000000,
+ MALI_GP_IRQ, MALI_GP_MMU_IRQ,
+ MALI_PP0_IRQ, MALI_PP0_MMU_IRQ,
+ MALI_PP1_IRQ, MALI_PP1_MMU_IRQ,
+ MALI_PP2_IRQ, MALI_PP2_MMU_IRQ,
+ MALI_PP3_IRQ, MALI_PP3_MMU_IRQ)
+};
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy);
+
+static struct notifier_block mali_pwr_notif_block = {
+ .notifier_call = mali_pwr_suspend_notifier
+};
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+
+#if 0
+static struct dev_pm_ops mali_gpu_device_type_pm_ops =
+{
+#ifndef CONFIG_PM_RUNTIME
+ .suspend = mali_os_suspend,
+ .resume = mali_os_resume,
+#endif
+ .freeze = mali_os_freeze,
+ .thaw = mali_os_thaw,
+#ifdef CONFIG_PM_RUNTIME
+ .runtime_suspend = mali_runtime_suspend,
+ .runtime_resume = mali_runtime_resume,
+ .runtime_idle = mali_runtime_idle,
+#endif
+};
+#endif
+
+#if defined(USE_PM_NOTIFIER)
+static struct device_type mali_gpu_device_device_type =
+{
+ .pm = &mali_gpu_device_type_pm_ops,
+};
+#endif
+
+static struct platform_device mali_gpu_device =
+{
+ .name = "mali_dev", /* MALI_SEC MALI_GPU_NAME_UTGARD, */
+ .id = 0,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ /* Set in mali_platform_device_register() for these kernels */
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+ .dev.parent = &exynos4_device_pd[PD_G3D].dev,
+#else
+ .dev.parent = &s5pv310_device_pd[PD_G3D].dev,
+#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) */
+ .dev.release = mali_platform_device_release,
+#if 0
+ /*
+ * We temporarily make use of a device type so that we can control the Mali power
+ * from within the mali.ko (since the default platform bus implementation will not do that).
+ * Ideally .dev.pm_domain should be used instead, as this is the new framework designed
+ * to control the power of devices.
+ */
+ .dev.type = &mali_gpu_device_device_type, /* We should probably use the pm_domain instead of type on newer kernels */
+#endif
+};
+
+static struct mali_gpu_device_data mali_gpu_data =
+{
+ .shared_mem_size = 256 * 1024 * 1024, /* 256MB */
+ .fb_start = 0x40000000,
+ .fb_size = 0xb1000000,
+ .utilization_interval = 100, /* 100ms */
+ .utilization_callback = mali_gpu_utilization_handler,
+};
+
+int mali_platform_device_register(void)
+{
+ int err;
+
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_register() called\n"));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,0)
+ exynos_pm_add_dev_to_genpd(&mali_gpu_device, &exynos4_pd_g3d);
+#endif
+
+ /* Connect resources to the device */
+ err = platform_device_add_resources(&mali_gpu_device, mali_gpu_resources, sizeof(mali_gpu_resources) / sizeof(mali_gpu_resources[0]));
+ if (0 == err)
+ {
+ err = platform_device_add_data(&mali_gpu_device, &mali_gpu_data, sizeof(mali_gpu_data));
+ if (0 == err)
+ {
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+ err = register_pm_notifier(&mali_pwr_notif_block);
+ if (err)
+ {
+ goto plat_init_err;
+ }
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+
+ /* Register the platform device */
+ err = platform_device_register(&mali_gpu_device);
+ if (0 == err)
+ {
+ mali_platform_init(&(mali_gpu_device.dev));
+
+#ifdef CONFIG_PM_RUNTIME
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ pm_runtime_set_autosuspend_delay(&(mali_gpu_device.dev), 1000);
+ pm_runtime_use_autosuspend(&(mali_gpu_device.dev));
+#endif
+ pm_runtime_enable(&(mali_gpu_device.dev));
+#endif
+
+ return 0;
+ }
+ }
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+plat_init_err:
+ unregister_pm_notifier(&mali_pwr_notif_block);
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+ platform_device_unregister(&mali_gpu_device);
+ }
+
+ return err;
+}
+
+void mali_platform_device_unregister(void)
+{
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_unregister() called\n"));
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+ unregister_pm_notifier(&mali_pwr_notif_block);
+#endif
+#endif /* CONFIG_PM_RUNTIME */
+
+ mali_platform_deinit(&(mali_gpu_device.dev));
+
+ platform_device_unregister(&mali_gpu_device);
+}
+
+static void mali_platform_device_release(struct device *device)
+{
+ MALI_DEBUG_PRINT(4, ("mali_platform_device_release() called\n"));
+}
+
+#ifdef CONFIG_PM_RUNTIME
+#if defined(USE_PM_NOTIFIER)
+static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy)
+{
+ int err = 0;
+ switch (event)
+ {
+ case PM_SUSPEND_PREPARE:
+ mali_pm_os_suspend();
+ err = mali_os_suspend(&(mali_platform_device->dev));
+ break;
+
+ case PM_POST_SUSPEND:
+ err = mali_os_resume(&(mali_platform_device->dev));
+ mali_pm_os_resume();
+ break;
+ default:
+ break;
+ }
+ return err;
+}
+
+static int mali_os_suspend(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_os_suspend() called\n"));
+
+#ifdef CONFIG_MALI_DVFS
+ mali_utilization_suspend();
+#endif
+
+ if (NULL != device &&
+ NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->suspend)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->suspend(device);
+ }
+
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_DEEP_SLEEP);
+
+ return ret;
+}
+
+static int mali_os_resume(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_os_resume() called\n"));
+#ifdef CONFIG_REGULATOR
+ mali_regulator_enable();
+ g3d_power_domain_control(1);
+#endif
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_ON);
+
+ if (NULL != device &&
+ NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->resume)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->resume(device);
+ }
+
+ return ret;
+}
+
+static int mali_os_freeze(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_os_freeze() called\n"));
+
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->freeze)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->freeze(device);
+ }
+
+ return ret;
+}
+
+static int mali_os_thaw(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_os_thaw() called\n"));
+
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->thaw)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->thaw(device);
+ }
+
+ return ret;
+}
+
+static int mali_runtime_suspend(struct device *device)
+{
+ int ret = 0;
+
+ MALI_DEBUG_PRINT(4, ("mali_runtime_suspend() called\n"));
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->runtime_suspend)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_suspend(device);
+ }
+
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_LIGHT_SLEEP);
+
+ return ret;
+}
+
+static int mali_runtime_resume(struct device *device)
+{
+ int ret = 0;
+ MALI_DEBUG_PRINT(4, ("mali_runtime_resume() called\n"));
+
+ mali_platform_power_mode_change(device, MALI_POWER_MODE_ON);
+
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->runtime_resume)
+ {
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_resume(device);
+ }
+
+ return ret;
+}
+
+static int mali_runtime_idle(struct device *device)
+{
+ MALI_DEBUG_PRINT(4, ("mali_runtime_idle() called\n"));
+ if (NULL != device->driver &&
+ NULL != device->driver->pm &&
+ NULL != device->driver->pm->runtime_idle)
+ {
+ int ret = 0;
+ /* Need to notify Mali driver about this event */
+ ret = device->driver->pm->runtime_idle(device);
+ if (0 != ret)
+ {
+ return ret;
+ }
+ }
+
+ return 1;
+}
+
+#endif /* USE_PM_NOTIFIER */
+#endif /* CONFIG_PM_RUNTIME */
diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c
new file mode 100644
index 0000000..65acaa6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.c
@@ -0,0 +1,1375 @@
+/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.c
+ *
+ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
+ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
+ *
+ * Samsung SoC Mali400 DVFS driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software FoundatIon.
+ */
+
+/**
+ * @file exynos4_pmm.c
+ * Platform specific Mali driver functions for the exynos 4XXX based platforms
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "exynos4_pmm.h"
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+
+#if defined(CONFIG_MALI400_PROFILING)
+#include "mali_osk_profiling.h"
+#endif
+
+#if defined(CONFIG_PM_RUNTIME)
+#include <plat/pd.h>
+#endif
+
+#include <asm/io.h>
+#include <mach/regs-pmu.h>
+
+#include <linux/workqueue.h>
+
+#ifdef CONFIG_CPU_EXYNOS4210
+#define MALI_DVFS_STEPS 2
+#define MALI_DVFS_WATING 10 /* msec */
+#define MALI_DVFS_DEFAULT_STEP 0
+#else
+#define MALI_DVFS_STEPS 5
+#define MALI_DVFS_WATING 10 /* msec */
+#define MALI_DVFS_DEFAULT_STEP 1
+#define PD_G3D_LOCK_FLAG 2
+#endif
+
+#ifdef CONFIG_CPU_FREQ
+#include <mach/asv.h>
+#define EXYNOS4_ASV_ENABLED
+#endif
+
+#define MALI_DVFS_CLK_DEBUG 0
+#define SEC_THRESHOLD 1
+
+#define CPUFREQ_LOCK_DURING_440 0
+#define CHIPID_REG (S5P_VA_CHIPID + 0x4)
+
+static int bMaliDvfsRun = 0;
+
+typedef struct mali_dvfs_tableTag{
+ unsigned int clock;
+ unsigned int freq;
+ unsigned int vol;
+#if SEC_THRESHOLD
+ unsigned int downthreshold;
+ unsigned int upthreshold;
+#endif
+}mali_dvfs_table;
+
+typedef struct mali_dvfs_statusTag{
+ unsigned int currentStep;
+ mali_dvfs_table * pCurrentDvfs;
+
+} mali_dvfs_status_t;
+
+/* dvfs status */
+mali_dvfs_status_t maliDvfsStatus;
+int mali_dvfs_control;
+
+typedef struct mali_runtime_resumeTag{
+ int clk;
+ int vol;
+ unsigned int step;
+}mali_runtime_resume_table;
+
+mali_runtime_resume_table mali_runtime_resume = {266, 900000, 1};
+
+/* dvfs table */
+mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ /* step 0 */{160 ,1000000 ,875000 , 0 , 70},
+ /* step 1 */{266 ,1000000 ,900000 ,62 , 90},
+ /* step 2 */{350 ,1000000 ,950000 ,85 , 90},
+ /* step 3 */{440 ,1000000 ,1025000 ,85 , 90},
+ /* step 4 */{533 ,1000000 ,1075000 ,95 ,100} };
+#else
+ /* step 0 */{134 ,1000000 , 950000 ,85 , 90},
+ /* step 1 */{267 ,1000000 ,1050000 ,85 ,100} };
+#endif
+
+#ifdef EXYNOS4_ASV_ENABLED
+#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */
+#define ASV_LEVEL_PRIME 13 /* ASV0, 1, 12 is reserved */
+#define ASV_LEVEL_PD 13
+#define ASV_LEVEL_4210_12 8
+#define ASV_LEVEL_4210_14 5
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+static unsigned int asv_3d_volt_9_table_1ghz_type[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
+ { 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000, 900000, 900000, 900000, 875000}, /* L3(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 1000000, 975000, 975000, 975000, 950000, 950000, 950000, 900000, 900000, 900000, 900000, 875000}, /* L2(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1075000, 1050000, 1050000, 1050000, 1000000, 1000000, 1000000, 975000, 975000, 975000, 975000, 925000}, /* L1(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1125000, 1100000, 1100000, 1100000, 1075000, 1075000, 1075000, 1025000, 1025000, 1025000, 1025000, 975000}, /* L0(440Mhz) */
+#endif
+#endif
+#endif
+};
+static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS-1][ASV_LEVEL] = {
+ { 950000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 950000, 925000, 925000, 925000, 900000, 900000, 875000, 875000, 875000, 875000, 850000}, /* L2(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1050000, 1025000, 1000000, 1000000, 975000, 950000, 950000, 950000, 925000, 925000, 925000, 900000}, /* L1(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1100000, 1075000, 1050000, 1050000, 1050000, 1025000, 1025000, 1000000, 1000000, 1000000, 975000, 950000}, /* L0(440Mhz) */
+#endif
+#endif
+#endif
+};
+
+static unsigned int asv_3d_volt_9_table_for_prime[MALI_DVFS_STEPS][ASV_LEVEL_PRIME] = {
+ { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000, 850000}, /* L4(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 875000, 875000}, /* L3(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 912500, 900000, 887500}, /* L2(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 975000, 962500, 950000}, /* L1(440Mhz) */
+#if (MALI_DVFS_STEPS > 4)
+ { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1075000, 1062500, 1037500, 1025000, 1012500}, /* L0(533Mhz) */
+#endif
+#endif
+#endif
+#endif
+};
+
+static unsigned int asv_3d_volt_4212_9_table[MALI_DVFS_STEPS][ASV_LEVEL_PD] = {
+ { 950000, 925000, 900000, 900000, 900000, 900000, 900000, 900000, 875000, 850000, 850000, 850000, 850000}, /* L3(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 950000, 925000, 925000, 925000, 925000, 925000, 900000, 900000, 900000, 875000, 875000, 875000}, /* L2(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1025000, 1000000, 975000, 975000, 975000, 950000, 950000, 925000, 925000, 925000, 925000, 900000, 875000}, /* L1(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1100000, 1075000, 1050000, 1050000, 1050000, 1050000, 1025000, 1000000, 1000000, 975000, 975000, 950000, 925000}, /* L0(440Mhz) */
+#endif
+#endif
+#endif
+};
+#else
+
+static unsigned int asv_3d_volt_4210_12_table[MALI_DVFS_STEPS][ASV_LEVEL_4210_12] = {
+ { 1000000, 1000000, 1000000, 950000, 950000, 950000, 950000, 950000}, /* L1(134Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 1100000, 1100000, 1100000, 1000000, 1000000, 1000000, 1000000, 950000}, /* L0(266Mhz) */
+#endif
+};
+
+static unsigned int asv_3d_volt_4210_14_table[MALI_DVFS_STEPS][ASV_LEVEL_4210_14] = {
+ { 1000000, 1000000, 950000, 950000, 950000}, /* L1(134Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 1100000, 1100000, 1000000, 1000000, 950000}, /* L0(266Mhz) */
+#endif
+};
+#endif
+#endif /* ASV_LEVEL */
+
+#define EXTXTALCLK_NAME "ext_xtal"
+#define VPLLSRCCLK_NAME "vpll_src"
+#define FOUTVPLLCLK_NAME "fout_vpll"
+#define SCLVPLLCLK_NAME "sclk_vpll"
+#define GPUMOUT1CLK_NAME "mout_g3d1"
+
+#define MPLLCLK_NAME "mout_mpll"
+#define GPUMOUT0CLK_NAME "mout_g3d0"
+#define GPUCLK_NAME "sclk_g3d"
+#define CLK_DIV_STAT_G3D 0x1003C62C
+#define CLK_DESC "clk-divider-status"
+
+static struct clk *ext_xtal_clock = NULL;
+static struct clk *vpll_src_clock = NULL;
+static struct clk *fout_vpll_clock = NULL;
+static struct clk *sclk_vpll_clock = NULL;
+
+static struct clk *mpll_clock = NULL;
+static struct clk *mali_parent_clock = NULL;
+static struct clk *mali_mout0_clock = NULL;
+static struct clk *mali_clock = NULL;
+
+#if defined(CONFIG_CPU_EXYNOS4412) || defined(CONFIG_CPU_EXYNOS4212)
+/* Pegasus */
+static const mali_bool bis_vpll = MALI_TRUE;
+int mali_gpu_clk = 440;
+int mali_gpu_vol = 1025000;
+#else
+/* Orion */
+static const mali_bool bis_vpll = MALI_FALSE;
+int mali_gpu_clk = 267;
+int mali_gpu_vol = 1050000;
+#endif
+
+static unsigned int GPU_MHZ = 1000000;
+
+int gpu_power_state;
+static int bPoweroff;
+atomic_t clk_active;
+
+#define MAX_MALI_DVFS_STEPS 5
+static _mali_osk_atomic_t bottomlock_status;
+int bottom_lock_step = 0;
+
+#if MALI_VOLTAGE_LOCK
+int mali_lock_vol = 0;
+static _mali_osk_atomic_t voltage_lock_status;
+static mali_bool mali_vol_lock_flag = 0;
+#endif
+
+/* Declare for sysfs */
+#ifdef CONFIG_MALI_DVFS
+module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(mali_dvfs_control, "Mali Current DVFS");
+
+DEVICE_ATTR(time_in_state, S_IRUGO|S_IWUSR, show_time_in_state, set_time_in_state);
+MODULE_PARM_DESC(time_in_state, "Time-in-state of Mali DVFS");
+#endif
+
+module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(mali_gpu_clk, "Mali Current Clock");
+
+module_param(mali_gpu_vol, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
+
+module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
+MODULE_PARM_DESC(gpu_power_state, "Mali Power State");
+
+#ifdef CONFIG_REGULATOR
+struct regulator *g3d_regulator = NULL;
+#endif
+
+mali_io_address clk_register_map = 0;
+
+/* DVFS */
+static unsigned int mali_dvfs_utilization = 255;
+u64 mali_dvfs_time[MALI_DVFS_STEPS];
+#ifdef CONFIG_MALI_DVFS
+static void update_time_in_state(int level);
+#endif
+static void mali_dvfs_work_handler(struct work_struct *w);
+static struct workqueue_struct *mali_dvfs_wq = 0;
+extern mali_io_address clk_register_map;
+_mali_osk_lock_t *mali_dvfs_lock;
+int mali_runtime_resumed = -1;
+static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
+
+#ifdef CONFIG_REGULATOR
+void mali_regulator_disable(void)
+{
+ if(IS_ERR_OR_NULL(g3d_regulator))
+ {
+ MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
+ return;
+ }
+ regulator_disable(g3d_regulator);
+}
+
+void mali_regulator_enable(void)
+{
+ if(IS_ERR_OR_NULL(g3d_regulator))
+ {
+ MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
+ return;
+ }
+ regulator_enable(g3d_regulator);
+}
+
+void mali_regulator_set_voltage(int min_uV, int max_uV)
+{
+ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ if(IS_ERR_OR_NULL(g3d_regulator))
+ {
+ MALI_DEBUG_PRINT(1, ("error on mali_regulator_set_voltage : g3d_regulator is null\n"));
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return;
+ }
+ MALI_PRINT(("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
+ regulator_set_voltage(g3d_regulator, min_uV, max_uV);
+ mali_gpu_vol = regulator_get_voltage(g3d_regulator);
+ MALI_DEBUG_PRINT(1, ("Mali voltage: %d\n", mali_gpu_vol));
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+}
+#endif
+
+unsigned long mali_clk_get_rate(void)
+{
+ return clk_get_rate(mali_clock);
+}
+
+
+static unsigned int get_mali_dvfs_status(void)
+{
+ return maliDvfsStatus.currentStep;
+}
+
+mali_bool mali_clk_get(void)
+{
+ if (bis_vpll)
+ {
+ if (ext_xtal_clock == NULL)
+ {
+ ext_xtal_clock = clk_get(NULL, EXTXTALCLK_NAME);
+ if (IS_ERR(ext_xtal_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source ext_xtal_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (vpll_src_clock == NULL)
+ {
+ vpll_src_clock = clk_get(NULL, VPLLSRCCLK_NAME);
+ if (IS_ERR(vpll_src_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source vpll_src_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (fout_vpll_clock == NULL)
+ {
+ fout_vpll_clock = clk_get(NULL, FOUTVPLLCLK_NAME);
+ if (IS_ERR(fout_vpll_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source fout_vpll_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (sclk_vpll_clock == NULL)
+ {
+ sclk_vpll_clock = clk_get(NULL, SCLVPLLCLK_NAME);
+ if (IS_ERR(sclk_vpll_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source sclk_vpll_clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (mali_parent_clock == NULL)
+ {
+ mali_parent_clock = clk_get(NULL, GPUMOUT1CLK_NAME);
+
+ if (IS_ERR(mali_parent_clock)) {
+ MALI_PRINT(( "MALI Error : failed to get source mali parent clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (mali_mout0_clock == NULL)
+ {
+ mali_mout0_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
+
+ if (IS_ERR(mali_mout0_clock)) {
+ MALI_PRINT( ( "MALI Error : failed to get source mali mout0 clock\n"));
+ return MALI_FALSE;
+ }
+ }
+ }
+ else /* mpll */
+ {
+ if (mpll_clock == NULL)
+ {
+ mpll_clock = clk_get(NULL, MPLLCLK_NAME);
+
+ if (IS_ERR(mpll_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source mpll clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ if (mali_parent_clock == NULL)
+ {
+ mali_parent_clock = clk_get(NULL, GPUMOUT0CLK_NAME);
+
+ if (IS_ERR(mali_parent_clock)) {
+ MALI_PRINT(( "MALI Error : failed to get source mali parent clock\n"));
+ return MALI_FALSE;
+ }
+ }
+ }
+
+ /* mali clock get always. */
+ if (mali_clock == NULL)
+ {
+ mali_clock = clk_get(NULL, GPUCLK_NAME);
+
+ if (IS_ERR(mali_clock)) {
+ MALI_PRINT(("MALI Error : failed to get source mali clock\n"));
+ return MALI_FALSE;
+ }
+ }
+
+ return MALI_TRUE;
+}
+
+void mali_clk_put(mali_bool binc_mali_clock)
+{
+ if (mali_parent_clock)
+ {
+ clk_put(mali_parent_clock);
+ mali_parent_clock = NULL;
+ }
+
+ if (mali_mout0_clock)
+ {
+ clk_put(mali_mout0_clock);
+ mali_mout0_clock = NULL;
+ }
+
+ if (mpll_clock)
+ {
+ clk_put(mpll_clock);
+ mpll_clock = NULL;
+ }
+
+ if (sclk_vpll_clock)
+ {
+ clk_put(sclk_vpll_clock);
+ sclk_vpll_clock = NULL;
+ }
+
+ if (binc_mali_clock && fout_vpll_clock)
+ {
+ clk_put(fout_vpll_clock);
+ fout_vpll_clock = NULL;
+ }
+
+ if (vpll_src_clock)
+ {
+ clk_put(vpll_src_clock);
+ vpll_src_clock = NULL;
+ }
+
+ if (ext_xtal_clock)
+ {
+ clk_put(ext_xtal_clock);
+ ext_xtal_clock = NULL;
+ }
+
+ if (binc_mali_clock && mali_clock)
+ {
+ clk_put(mali_clock);
+ mali_clock = NULL;
+ }
+}
+
+void mali_clk_set_rate(unsigned int clk, unsigned int mhz)
+{
+ int err;
+ unsigned long rate = (unsigned long)clk * (unsigned long)mhz;
+
+ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ MALI_DEBUG_PRINT(3, ("Mali platform: Setting frequency to %d mhz\n", clk));
+
+ if (mali_clk_get() == MALI_FALSE) {
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return;
+ }
+
+ if (bis_vpll)
+ {
+ /* in Pega-prime, vpll_src_clock means ext_xtal_clock!! */
+ clk_set_parent(sclk_vpll_clock, vpll_src_clock);
+
+ clk_set_rate(fout_vpll_clock, (unsigned int)clk * GPU_MHZ);
+ clk_set_parent(vpll_src_clock, ext_xtal_clock);
+ clk_set_parent(sclk_vpll_clock, fout_vpll_clock);
+
+ clk_set_parent(mali_parent_clock, sclk_vpll_clock);
+ clk_set_parent(mali_clock, mali_parent_clock);
+ }
+ else
+ {
+ clk_set_parent(mali_parent_clock, mpll_clock);
+ clk_set_parent(mali_clock, mali_parent_clock);
+ }
+
+ if (atomic_read(&clk_active) == 0) {
+ if (clk_enable(mali_clock) < 0) {
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return;
+ }
+ atomic_set(&clk_active, 1);
+ }
+
+ err = clk_set_rate(mali_clock, rate);
+ if (err > 0)
+ MALI_PRINT_ERROR(("Failed to set Mali clock: %d\n", err));
+
+ rate = mali_clk_get_rate();
+
+ MALI_PRINT(("Mali frequency %d\n", rate / mhz));
+ GPU_MHZ = mhz;
+ mali_gpu_clk = (int)(rate / mhz);
+
+ mali_clk_put(MALI_FALSE);
+
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+int get_mali_dvfs_control_status(void)
+{
+ return mali_dvfs_control;
+}
+
+mali_bool set_mali_dvfs_current_step(unsigned int step)
+{
+ _mali_osk_lock_wait(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ maliDvfsStatus.currentStep = step % MALI_DVFS_STEPS;
+ if (step >= MALI_DVFS_STEPS)
+ mali_runtime_resumed = maliDvfsStatus.currentStep;
+
+ _mali_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
+ return MALI_TRUE;
+}
+
+
+static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
+{
+ u32 validatedStep=step;
+#if MALI_DVFS_CLK_DEBUG
+ unsigned int *pRegMaliClkDiv;
+ unsigned int *pRegMaliMpll;
+#endif
+
+ if(boostup) {
+#ifdef CONFIG_REGULATOR
+ /* change the voltage */
+ mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+#endif
+ /* change the clock */
+ mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+ } else {
+ /* change the clock */
+ mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
+#ifdef CONFIG_REGULATOR
+ /* change the voltage */
+ mali_regulator_set_voltage(mali_dvfs[step].vol, mali_dvfs[step].vol);
+#endif
+ }
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_EVENT_CHANNEL_GPU|
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+#endif
+ mali_clk_put(MALI_FALSE);
+
+#if MALI_DVFS_CLK_DEBUG
+ pRegMaliClkDiv = ioremap(0x1003c52c,32);
+ pRegMaliMpll = ioremap(0x1003c22c,32);
+ MALI_PRINT(("Mali MPLL reg:%d, CLK DIV: %d \n",*pRegMaliMpll, *pRegMaliClkDiv));
+#endif
+
+#ifdef EXYNOS4_ASV_ENABLED
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_dvfs[step].clock == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
+#endif
+
+ set_mali_dvfs_current_step(validatedStep);
+ /* for future use */
+ maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
+
+#if CPUFREQ_LOCK_DURING_440
+ /* lock/unlock CPU freq by Mali */
+ if (mali_dvfs[step].clock >= 440)
+ err = cpufreq_lock_by_mali(400);
+ else
+ cpufreq_unlock_by_mali();
+#endif
+
+
+ return MALI_TRUE;
+}
+
+static void mali_platform_wating(u32 msec)
+{
+ /*
+ * sample wating
+ * change this in the future with proper check routine.
+ */
+ unsigned int read_val;
+ while(1) {
+ read_val = _mali_osk_mem_ioread32(clk_register_map, 0x00);
+ if ((read_val & 0x8000)==0x0000) break;
+
+ _mali_osk_time_ubusydelay(100); /* 1000 -> 100 : 20101218 */
+ }
+}
+
+static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
+{
+ MALI_DEBUG_PRINT(4, ("> change_mali_dvfs_status: %d, %d \n",step, boostup));
+
+ if (!set_mali_dvfs_status(step, boostup)) {
+ MALI_DEBUG_PRINT(1, ("error on set_mali_dvfs_status: %d, %d \n",step, boostup));
+ return MALI_FALSE;
+ }
+
+ /* wait until clock and voltage is stablized */
+ mali_platform_wating(MALI_DVFS_WATING); /* msec */
+
+ return MALI_TRUE;
+}
+
+#ifdef EXYNOS4_ASV_ENABLED
+extern unsigned int exynos_result_of_asv;
+
+static mali_bool mali_dvfs_table_update(void)
+{
+ unsigned int step_num = MALI_DVFS_STEPS;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ unsigned int i, tmp, g3d_lock_volt = 0;
+ bool lock_flag_g3d = false;
+
+ if(samsung_rev() < EXYNOS4412_REV_2_0)
+ step_num = MALI_DVFS_STEPS - 1;
+
+ if(soc_is_exynos4412()) {
+ if (exynos_armclk_max == 1000000) {
+ MALI_PRINT(("::C::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_1ghz_type[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ } else if(((is_special_flag() >> G3D_LOCK_FLAG) & 0x1) && (samsung_rev() >= EXYNOS4412_REV_2_0)) {
+ MALI_PRINT(("::L::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv] + 25000;
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n ", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ } else if (samsung_rev() >= EXYNOS4412_REV_2_0) {
+ MALI_PRINT(("::P::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table_for_prime[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ } else {
+ MALI_PRINT(("::Q::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ for (i = 0; i < step_num; i++) {
+ mali_dvfs[i].vol = asv_3d_volt_9_table[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ }
+ }
+ else if(soc_is_exynos4212()) {
+ tmp = __raw_readl(CHIPID_REG);
+ lock_flag_g3d = (tmp >> PD_G3D_LOCK_FLAG) & 0x1;
+ if (lock_flag_g3d)
+ g3d_lock_volt = 25000;
+
+ for (i = 0; i < step_num; i++) {
+ MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv));
+ mali_dvfs[i].vol = asv_3d_volt_4212_9_table[i][exynos_result_of_asv] + g3d_lock_volt;
+ MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+ }
+#else
+ unsigned int i, exynos_result_of_asv_group, target_asv;
+
+ exynos_result_of_asv_group = exynos_result_of_asv & 0xf;
+ target_asv = exynos_result_of_asv >> 28;
+ MALI_PRINT(("exynos_result_of_asv_group = 0x%x, target_asv = 0x%x\n", exynos_result_of_asv_group, target_asv));
+
+ for (i = 0; i < step_num; i++) {
+ if (target_asv == 0x8) { //SUPPORT_1400MHZ
+ mali_dvfs[i].vol = asv_3d_volt_4210_14_table[i][exynos_result_of_asv_group];
+ } else if (target_asv == 0x4){ //SUPPORT_1200MHZ
+ mali_dvfs[i].vol = asv_3d_volt_4210_12_table[i][exynos_result_of_asv_group];
+ }
+ MALI_PRINT(("mali_dvfs[%d].vol = %d \n", i, mali_dvfs[i].vol));
+
+ // Update voltage using for resume
+ if (mali_runtime_resume.clk == mali_dvfs[i].clock) {
+ mali_runtime_resume.vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("mali_runtime_resume.vol = %d \n", mali_runtime_resume.vol));
+ }
+
+ // update voltage using for init timing
+ if (mali_gpu_clk == mali_dvfs[i].clock) {
+ mali_gpu_vol = mali_dvfs[i].vol;
+
+ MALI_PRINT(("init_gpu_vol = %d \n", mali_gpu_vol));
+ }
+ }
+#endif
+
+ return MALI_TRUE;
+}
+#endif
+
+static unsigned int decideNextStatus(unsigned int utilization)
+{
+ static unsigned int level = 0;
+ int iStepCount = 0;
+ if (mali_runtime_resumed >= 0) {
+ level = mali_runtime_resumed;
+ mali_runtime_resumed = -1;
+ }
+
+ if (mali_dvfs_control == 0 && level == get_mali_dvfs_status()) {
+ if (utilization > (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].upthreshold / 100) &&
+ level < MALI_DVFS_STEPS - 1) {
+ level++;
+ if ((samsung_rev() < EXYNOS4412_REV_2_0) && 3 == get_mali_dvfs_status()) {
+ level=get_mali_dvfs_status();
+ }
+ }
+ else if (utilization < (int)(255 * mali_dvfs[maliDvfsStatus.currentStep].downthreshold / 100) &&
+ level > 0) {
+ level--;
+ }
+
+ if (_mali_osk_atomic_read(&bottomlock_status) > 0) {
+ if (level < bottom_lock_step)
+ level = bottom_lock_step;
+ }
+ } else {
+ for (iStepCount = MALI_DVFS_STEPS-1; iStepCount >= 0; iStepCount--) {
+ if ( mali_dvfs_control >= mali_dvfs[iStepCount].clock ) {
+ level = iStepCount;
+ break;
+ }
+ }
+ }
+
+ return level;
+}
+
+
+static mali_bool mali_dvfs_status(unsigned int utilization)
+{
+ unsigned int nextStatus = 0;
+ unsigned int curStatus = 0;
+ mali_bool boostup = MALI_FALSE;
+ static int stay_count = 5;
+
+ MALI_DEBUG_PRINT(4, ("> mali_dvfs_status: %d \n",utilization));
+
+ /* decide next step */
+ curStatus = get_mali_dvfs_status();
+ nextStatus = decideNextStatus(utilization);
+
+ MALI_DEBUG_PRINT(4, ("= curStatus %d, nextStatus %d, maliDvfsStatus.currentStep %d \n", curStatus, nextStatus, maliDvfsStatus.currentStep));
+ /* if next status is same with current status, don't change anything */
+ if(curStatus != nextStatus) {
+ /*check if boost up or not*/
+ if(maliDvfsStatus.currentStep < nextStatus) {
+ boostup = 1;
+ stay_count = 5;
+ } else if (maliDvfsStatus.currentStep > nextStatus){
+ stay_count--;
+ }
+ if( boostup == 1 || stay_count <= 0){
+ /*change mali dvfs status*/
+#ifdef CONFIG_MALI_DVFS
+ update_time_in_state(curStatus);
+#endif
+ if (!change_mali_dvfs_status(nextStatus,boostup)) {
+ MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
+ return MALI_FALSE;
+ }
+ boostup = 0;
+ stay_count = 5;
+ }
+ }
+ else
+ stay_count = 5;
+ return MALI_TRUE;
+}
+
+
+int mali_dvfs_is_running(void)
+{
+ return bMaliDvfsRun;
+}
+
+
+static void mali_dvfs_work_handler(struct work_struct *w)
+{
+ bMaliDvfsRun=1;
+
+ MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
+
+ if(!mali_dvfs_status(mali_dvfs_utilization))
+ MALI_DEBUG_PRINT(1, ( "error on mali dvfs status in mali_dvfs_work_handler"));
+
+ bMaliDvfsRun=0;
+}
+
+mali_bool init_mali_dvfs_status(void)
+{
+ /*
+ * default status
+ * add here with the right function to get initilization value.
+ */
+
+ if (!mali_dvfs_wq)
+ mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
+
+ _mali_osk_atomic_init(&bottomlock_status, 0);
+
+ /* add a error handling here */
+ maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+
+ return MALI_TRUE;
+}
+
+void deinit_mali_dvfs_status(void)
+{
+ if (mali_dvfs_wq)
+ destroy_workqueue(mali_dvfs_wq);
+
+ _mali_osk_atomic_term(&bottomlock_status);
+
+ mali_dvfs_wq = NULL;
+}
+
+mali_bool mali_dvfs_handler(unsigned int utilization)
+{
+ mali_dvfs_utilization = utilization;
+ queue_work_on(0, mali_dvfs_wq, &mali_dvfs_work);
+
+ return MALI_TRUE;
+}
+
+static mali_bool init_mali_clock(void)
+{
+ mali_bool ret = MALI_TRUE;
+ gpu_power_state = 1;
+ bPoweroff = 1;
+
+ if (mali_clock != 0)
+ return ret; /* already initialized */
+
+ mali_dvfs_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE
+ | _MALI_OSK_LOCKFLAG_ONELOCK, 0, 0);
+ if (mali_dvfs_lock == NULL)
+ return _MALI_OSK_ERR_FAULT;
+
+ if (!mali_clk_get())
+ {
+ MALI_PRINT(("Error: Failed to get Mali clock\n"));
+ goto err_clk;
+ }
+
+ mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+
+ MALI_PRINT(("init_mali_clock mali_clock %x\n", mali_clock));
+
+#ifdef CONFIG_REGULATOR
+ g3d_regulator = regulator_get(NULL, "vdd_g3d");
+
+ if (IS_ERR(g3d_regulator))
+ {
+ MALI_PRINT(("MALI Error : failed to get vdd_g3d\n"));
+ ret = MALI_FALSE;
+ goto err_regulator;
+ }
+
+ regulator_enable(g3d_regulator);
+ mali_regulator_set_voltage(mali_gpu_vol, mali_gpu_vol);
+
+#ifdef EXYNOS4_ASV_ENABLED
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_gpu_clk == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
+#endif
+#endif
+
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|
+ MALI_PROFILING_EVENT_CHANNEL_GPU|
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+#endif
+
+ mali_clk_put(MALI_FALSE);
+
+ return MALI_TRUE;
+
+#ifdef CONFIG_REGULATOR
+err_regulator:
+ regulator_put(g3d_regulator);
+#endif
+err_clk:
+ mali_clk_put(MALI_TRUE);
+
+ return ret;
+}
+
+static mali_bool deinit_mali_clock(void)
+{
+ if (mali_clock == 0)
+ return MALI_TRUE;
+
+#ifdef CONFIG_REGULATOR
+ if (g3d_regulator)
+ {
+ regulator_put(g3d_regulator);
+ g3d_regulator = NULL;
+ }
+#endif
+
+ mali_clk_put(MALI_TRUE);
+
+ return MALI_TRUE;
+}
+
+
+static _mali_osk_errcode_t enable_mali_clocks(void)
+{
+ int err;
+
+ if (atomic_read(&clk_active) == 0) {
+ err = clk_enable(mali_clock);
+ MALI_DEBUG_PRINT(3,("enable_mali_clocks mali_clock %p error %d \n", mali_clock, err));
+ atomic_set(&clk_active, 1);
+ gpu_power_state = 1;
+ }
+
+ /* set clock rate */
+#ifdef CONFIG_MALI_DVFS
+ if (get_mali_dvfs_control_status() != 0 || mali_gpu_clk >= mali_runtime_resume.clk) {
+ mali_clk_set_rate(mali_gpu_clk, GPU_MHZ);
+ } else {
+#ifdef CONFIG_REGULATOR
+ mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
+
+#ifdef EXYNOS4_ASV_ENABLED
+ if (samsung_rev() < EXYNOS4412_REV_2_0) {
+ if (mali_runtime_resume.clk == 160)
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_100V);
+ else
+ exynos4x12_set_abb_member(ABB_G3D, ABB_MODE_130V);
+ }
+#endif
+#endif
+ mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
+ set_mali_dvfs_current_step(mali_runtime_resume.step);
+ }
+#else
+ mali_clk_set_rate((unsigned int)mali_gpu_clk, GPU_MHZ);
+ maliDvfsStatus.currentStep = MALI_DVFS_DEFAULT_STEP;
+#endif
+
+
+ MALI_SUCCESS;
+}
+
+static _mali_osk_errcode_t disable_mali_clocks(void)
+{
+ if (atomic_read(&clk_active) == 1) {
+ clk_disable(mali_clock);
+ atomic_set(&clk_active, 0);
+ gpu_power_state = 0;
+ }
+ MALI_DEBUG_PRINT(3, ("disable_mali_clocks mali_clock %p \n", mali_clock));
+
+ MALI_SUCCESS;
+}
+
+/* Some defines changed names in later Odroid-A kernels. Make sure it works for both. */
+#ifndef S5P_G3D_CONFIGURATION
+#define S5P_G3D_CONFIGURATION S5P_PMU_G3D_CONF
+#endif
+#ifndef S5P_G3D_STATUS
+#define S5P_G3D_STATUS S5P_PMU_G3D_CONF + 0x4
+#endif
+
+_mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
+{
+ if (bpower_on)
+ {
+ void __iomem *status;
+ u32 timeout;
+ __raw_writel(S5P_INT_LOCAL_PWR_EN, S5P_G3D_CONFIGURATION);
+ status = S5P_G3D_STATUS;
+
+ timeout = 10;
+ while ((__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
+ != S5P_INT_LOCAL_PWR_EN) {
+ if (timeout == 0) {
+ MALI_PRINTF(("Power domain enable failed.\n"));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ _mali_osk_time_ubusydelay(100);
+ }
+ }
+ else
+ {
+ void __iomem *status;
+ u32 timeout;
+ __raw_writel(0, S5P_G3D_CONFIGURATION);
+
+ status = S5P_G3D_STATUS;
+ /* Wait max 1ms */
+ timeout = 10;
+ while (__raw_readl(status) & S5P_INT_LOCAL_PWR_EN)
+ {
+ if (timeout == 0) {
+ MALI_PRINTF(("Power domain disable failed.\n" ));
+ return -ETIMEDOUT;
+ }
+ timeout--;
+ _mali_osk_time_ubusydelay(100);
+ }
+ }
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_init(struct device *dev)
+{
+#ifdef EXYNOS4_ASV_ENABLED
+ mali_dvfs_table_update();
+#endif
+
+ MALI_CHECK(init_mali_clock(), _MALI_OSK_ERR_FAULT);
+
+ atomic_set(&clk_active, 0);
+
+#ifdef CONFIG_MALI_DVFS
+ /* Create sysfs for time-in-state */
+ if (device_create_file(dev, &dev_attr_time_in_state)) {
+ dev_err(dev, "Couldn't create sysfs file [time_in_state]\n");
+ }
+
+ if (!clk_register_map) clk_register_map = _mali_osk_mem_mapioregion( CLK_DIV_STAT_G3D, 0x20, CLK_DESC );
+ if (!init_mali_dvfs_status())
+ MALI_DEBUG_PRINT(1, ("mali_platform_init failed\n"));
+#endif
+
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_ON);
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_deinit(struct device *dev)
+{
+
+ mali_platform_power_mode_change(dev, MALI_POWER_MODE_DEEP_SLEEP);
+ deinit_mali_clock();
+
+#ifdef CONFIG_MALI_DVFS
+ deinit_mali_dvfs_status();
+ if (clk_register_map )
+ {
+ _mali_osk_mem_unmapioregion(CLK_DIV_STAT_G3D, 0x20, clk_register_map);
+ clk_register_map = NULL;
+ }
+#endif
+
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode)
+{
+ switch (power_mode)
+ {
+ case MALI_POWER_MODE_ON:
+ MALI_DEBUG_PRINT(3, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n",
+ bPoweroff ? "powering on" : "already on"));
+ if (bPoweroff == 1)
+ {
+#if !defined(CONFIG_PM_RUNTIME)
+ g3d_power_domain_control(1);
+#endif
+ MALI_DEBUG_PRINT(4, ("enable clock \n"));
+ enable_mali_clocks();
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ mali_gpu_clk, mali_gpu_vol/1000, 0, 0, 0);
+
+#endif
+ bPoweroff=0;
+ }
+ break;
+ case MALI_POWER_MODE_LIGHT_SLEEP:
+ case MALI_POWER_MODE_DEEP_SLEEP:
+ MALI_DEBUG_PRINT(3, ("Mali platform: Got %s event, %s\n", power_mode ==
+ MALI_POWER_MODE_LIGHT_SLEEP ? "MALI_POWER_MODE_LIGHT_SLEEP" :
+ "MALI_POWER_MODE_DEEP_SLEEP", bPoweroff ? "already off" : "powering off"));
+ if (bPoweroff == 0)
+ {
+ disable_mali_clocks();
+#if defined(CONFIG_MALI400_PROFILING)
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE |
+ MALI_PROFILING_EVENT_CHANNEL_GPU |
+ MALI_PROFILING_EVENT_REASON_SINGLE_GPU_FREQ_VOLT_CHANGE,
+ 0, 0, 0, 0, 0);
+#endif
+
+#if !defined(CONFIG_PM_RUNTIME)
+ g3d_power_domain_control(0);
+#endif
+ bPoweroff=1;
+ }
+
+ break;
+ }
+ MALI_SUCCESS;
+}
+
+void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data)
+{
+ if (bPoweroff==0)
+ {
+#ifdef CONFIG_MALI_DVFS
+ if(!mali_dvfs_handler(data->utilization_gpu))
+ MALI_DEBUG_PRINT(1, ("error on mali dvfs status in utilization\n"));
+#endif
+ }
+}
+
+#ifdef CONFIG_CPU_EXYNOS4210
+int mali_dvfs_bottom_lock_push()
+{
+ int prev_status = _mali_osk_atomic_read(&bottomlock_status);
+
+ if (prev_status < 0) {
+ MALI_PRINT(("gpu bottom lock status is not valid for push\n"));
+ return -1;
+ }
+ if (prev_status == 0) {
+ mali_regulator_set_voltage(mali_dvfs[1].vol, mali_dvfs[1].vol);
+ mali_clk_set_rate(mali_dvfs[1].clock, mali_dvfs[1].freq);
+ set_mali_dvfs_current_step(1);
+ }
+ return _mali_osk_atomic_inc_return(&bottomlock_status);
+}
+#else
+int mali_dvfs_bottom_lock_push(int lock_step)
+{
+ int prev_status = _mali_osk_atomic_read(&bottomlock_status);
+
+ if (prev_status < 0) {
+ MALI_PRINT(("gpu bottom lock status is not valid for push\n"));
+ return -1;
+ }
+ if (bottom_lock_step < lock_step) {
+ bottom_lock_step = lock_step;
+ if (get_mali_dvfs_status() < lock_step) {
+ mali_regulator_set_voltage(mali_dvfs[lock_step].vol, mali_dvfs[lock_step].vol);
+ mali_clk_set_rate(mali_dvfs[lock_step].clock, mali_dvfs[lock_step].freq);
+ set_mali_dvfs_current_step(lock_step);
+ }
+ }
+ return _mali_osk_atomic_inc_return(&bottomlock_status);
+}
+#endif
+
+int mali_dvfs_bottom_lock_pop(void)
+{
+ int prev_status = _mali_osk_atomic_read(&bottomlock_status);
+ if (prev_status <= 0) {
+ MALI_PRINT(("gpu bottom lock status is not valid for pop\n"));
+ return -1;
+ } else if (prev_status >= 1) {
+ bottom_lock_step = 0;
+ MALI_PRINT(("gpu bottom lock release\n"));
+ }
+
+ return _mali_osk_atomic_dec_return(&bottomlock_status);
+}
+
+int mali_dvfs_get_vol(int step)
+{
+ step = step % MAX_MALI_DVFS_STEPS;
+ MALI_DEBUG_ASSERT(step<MAX_MALI_DVFS_STEPS);
+ return mali_dvfs[step].vol;
+}
+
+#if MALI_VOLTAGE_LOCK
+int mali_voltage_lock_push(int lock_vol)
+{
+ int prev_status = _mali_osk_atomic_read(&voltage_lock_status);
+
+ if (prev_status < 0) {
+ MALI_PRINT(("gpu voltage lock status is not valid for push\n"));
+ return -1;
+ }
+ if (prev_status == 0) {
+ mali_lock_vol = lock_vol;
+ if (mali_gpu_vol < mali_lock_vol)
+ mali_regulator_set_voltage(mali_lock_vol, mali_lock_vol);
+ } else {
+ MALI_PRINT(("gpu voltage lock status is already pushed, current lock voltage : %d\n", mali_lock_vol));
+ return -1;
+ }
+
+ return _mali_osk_atomic_inc_return(&voltage_lock_status);
+}
+
+int mali_voltage_lock_pop(void)
+{
+ if (_mali_osk_atomic_read(&voltage_lock_status) <= 0) {
+ MALI_PRINT(("gpu voltage lock status is not valid for pop\n"));
+ return -1;
+ }
+ return _mali_osk_atomic_dec_return(&voltage_lock_status);
+}
+
+int mali_voltage_lock_init(void)
+{
+ mali_vol_lock_flag = MALI_TRUE;
+
+ MALI_SUCCESS;
+}
+
+int mali_vol_get_from_table(int vol)
+{
+ int i;
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ if (mali_dvfs[i].vol >= vol)
+ return mali_dvfs[i].vol;
+ }
+ MALI_PRINT(("Failed to get voltage from mali_dvfs table, maximum voltage is %d uV\n", mali_dvfs[MALI_DVFS_STEPS-1].vol));
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_MALI_DVFS
+static void update_time_in_state(int level)
+{
+ u64 current_time;
+ static u64 prev_time=0;
+
+ if (prev_time ==0)
+ prev_time=get_jiffies_64();
+
+ current_time = get_jiffies_64();
+ mali_dvfs_time[level] += current_time-prev_time;
+ prev_time = current_time;
+}
+
+ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ ssize_t ret = 0;
+ int i;
+
+ update_time_in_state(maliDvfsStatus.currentStep);
+
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "%d %llu\n",
+ mali_dvfs[i].clock,
+ mali_dvfs_time[i]);
+ }
+
+ if (ret < PAGE_SIZE - 1) {
+ ret += snprintf(buf+ret, PAGE_SIZE-ret, "\n");
+ } else {
+ buf[PAGE_SIZE-2] = '\n';
+ buf[PAGE_SIZE-1] = '\0';
+ ret = PAGE_SIZE-1;
+ }
+
+ return ret;
+}
+
+ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int i;
+
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ mali_dvfs_time[i] = 0;
+ }
+
+ return count;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h
new file mode 100644
index 0000000..1b9cf57
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/platform/pegasus-m400/exynos4_pmm.h
@@ -0,0 +1,121 @@
+/* drivers/gpu/mali400/mali/platform/pegasus-m400/exynos4_pmm.h
+ *
+ * Copyright 2011 by S.LSI. Samsung Electronics Inc.
+ * San#24, Nongseo-Dong, Giheung-Gu, Yongin, Korea
+ *
+ * Samsung SoC Mali400 DVFS driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software FoundatIon.
+ */
+
+/**
+ * @file exynos4_pmm.h
+ * Platform specific Mali driver functions for the exynos 4XXX based platforms
+ */
+
+#ifndef __EXYNOS4_PMM_H__
+#define __EXYNOS4_PMM_H__
+
+#include "mali_utgard.h"
+#include "mali_osk.h"
+#include <linux/platform_device.h>
+/* @Enable or Disable Mali GPU Bottom Lock feature */
+#define MALI_GPU_BOTTOM_LOCK 1
+#define MALI_VOLTAGE_LOCK 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief description of power change reasons
+ */
+typedef enum mali_power_mode_tag
+{
+ MALI_POWER_MODE_ON,
+ MALI_POWER_MODE_LIGHT_SLEEP,
+ MALI_POWER_MODE_DEEP_SLEEP,
+} mali_power_mode;
+
+/** @brief Platform specific setup and initialisation of MALI
+ *
+ * This is called from the entrypoint of the driver to initialize the platform
+ *
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_platform_init(struct device *dev);
+
+/** @brief Platform specific deinitialisation of MALI
+ *
+ * This is called on the exit of the driver to terminate the platform
+ *
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_platform_deinit(struct device *dev);
+
+/** @brief Platform specific powerdown sequence of MALI
+ *
+ * Call as part of platform init if there is no PMM support, else the
+ * PMM will call it.
+ * There are three power modes defined:
+ * 1) MALI_POWER_MODE_ON
+ * 2) MALI_POWER_MODE_LIGHT_SLEEP
+ * 3) MALI_POWER_MODE_DEEP_SLEEP
+ * MALI power management module transitions to MALI_POWER_MODE_LIGHT_SLEEP mode when MALI is idle
+ * for idle timer (software timer defined in mali_pmm_policy_jobcontrol.h) duration, MALI transitions
+ * to MALI_POWER_MODE_LIGHT_SLEEP mode during timeout if there are no more jobs queued.
+ * MALI power management module transitions to MALI_POWER_MODE_DEEP_SLEEP mode when OS does system power
+ * off.
+ * Customer has to add power down code when MALI transitions to MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP
+ * mode.
+ * MALI_POWER_MODE_ON mode is entered when the MALI is to powered up. Some customers want to control voltage regulators during
+ * the whole system powers on/off. Customer can track in this function whether the MALI is powered up from
+ * MALI_POWER_MODE_LIGHT_SLEEP or MALI_POWER_MODE_DEEP_SLEEP mode and manage the voltage regulators as well.
+ * @param power_mode defines the power modes
+ * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
+ */
+_mali_osk_errcode_t mali_platform_power_mode_change(struct device *dev, mali_power_mode power_mode);
+
+
+/** @brief Platform specific handling of GPU utilization data
+ *
+ * When GPU utilization data is enabled, this function will be
+ * periodically called.
+ *
+ * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
+ */
+void mali_gpu_utilization_handler(struct mali_gpu_utilization_data *data);
+
+_mali_osk_errcode_t g3d_power_domain_control(int bpower_on);
+
+#ifdef CONFIG_REGULATOR
+void mali_regulator_disable(void);
+void mali_regulator_enable(void);
+void mali_regulator_set_voltage(int min_uV, int max_uV);
+#endif
+
+#ifdef CONFIG_MALI_DVFS
+ssize_t show_time_in_state(struct device *dev, struct device_attribute *attr, char *buf);
+ssize_t set_time_in_state(struct device *dev, struct device_attribute *attr, const char *buf, size_t count);
+#ifdef CONFIG_CPU_EXYNOS4210
+#if MALI_GPU_BOTTOM_LOCK
+int mali_dvfs_bottom_lock_push(void);
+int mali_dvfs_bottom_lock_pop(void);
+#endif
+#else
+int mali_dvfs_bottom_lock_push(int lock_step);
+int mali_dvfs_bottom_lock_pop(void);
+#endif
+#endif
+
+#if MALI_VOLTAGE_LOCK
+int mali_voltage_lock_push(int lock_vol);
+int mali_voltage_lock_pop(void);
+int mali_voltage_lock_init(void);
+int mali_vol_get_from_table(int vol);
+#endif
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h b/drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h
new file mode 100644
index 0000000..dd75149
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/regs/mali_200_regs.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MALI200_REGS_H_
+#define _MALI200_REGS_H_
+
+/**
+ * Enum for management register addresses.
+ */
+enum mali200_mgmt_reg
+{
+ MALI200_REG_ADDR_MGMT_VERSION = 0x1000,
+ MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR = 0x1004,
+ MALI200_REG_ADDR_MGMT_STATUS = 0x1008,
+ MALI200_REG_ADDR_MGMT_CTRL_MGMT = 0x100c,
+
+ MALI200_REG_ADDR_MGMT_INT_RAWSTAT = 0x1020,
+ MALI200_REG_ADDR_MGMT_INT_CLEAR = 0x1024,
+ MALI200_REG_ADDR_MGMT_INT_MASK = 0x1028,
+ MALI200_REG_ADDR_MGMT_INT_STATUS = 0x102c,
+
+ MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW = 0x1044,
+
+ MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS = 0x1050,
+
+ MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x1080,
+ MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x1084,
+ MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x108c,
+
+ MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x10a0,
+ MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x10a4,
+ MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x10ac,
+
+ MALI200_REG_SIZEOF_REGISTER_BANK = 0x10f0
+
+};
+
+#define MALI200_REG_VAL_PERF_CNT_ENABLE 1
+
+enum mali200_mgmt_ctrl_mgmt {
+ MALI200_REG_VAL_CTRL_MGMT_STOP_BUS = (1<<0),
+ MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES = (1<<3),
+ MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET = (1<<5),
+ MALI200_REG_VAL_CTRL_MGMT_START_RENDERING = (1<<6),
+ MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7), /* Only valid for Mali-300 and later */
+};
+
+enum mali200_mgmt_irq {
+ MALI200_REG_VAL_IRQ_END_OF_FRAME = (1<<0),
+ MALI200_REG_VAL_IRQ_END_OF_TILE = (1<<1),
+ MALI200_REG_VAL_IRQ_HANG = (1<<2),
+ MALI200_REG_VAL_IRQ_FORCE_HANG = (1<<3),
+ MALI200_REG_VAL_IRQ_BUS_ERROR = (1<<4),
+ MALI200_REG_VAL_IRQ_BUS_STOP = (1<<5),
+ MALI200_REG_VAL_IRQ_CNT_0_LIMIT = (1<<6),
+ MALI200_REG_VAL_IRQ_CNT_1_LIMIT = (1<<7),
+ MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR = (1<<8),
+ MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND = (1<<9),
+ MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW = (1<<10),
+ MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW = (1<<11),
+ MALI400PP_REG_VAL_IRQ_RESET_COMPLETED = (1<<12),
+};
+
+#define MALI200_REG_VAL_IRQ_MASK_ALL ((enum mali200_mgmt_irq) (\
+ MALI200_REG_VAL_IRQ_END_OF_FRAME |\
+ MALI200_REG_VAL_IRQ_END_OF_TILE |\
+ MALI200_REG_VAL_IRQ_HANG |\
+ MALI200_REG_VAL_IRQ_FORCE_HANG |\
+ MALI200_REG_VAL_IRQ_BUS_ERROR |\
+ MALI200_REG_VAL_IRQ_BUS_STOP |\
+ MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\
+ MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\
+ MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\
+ MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\
+ MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\
+ MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW |\
+ MALI400PP_REG_VAL_IRQ_RESET_COMPLETED))
+
+#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\
+ MALI200_REG_VAL_IRQ_END_OF_FRAME |\
+ MALI200_REG_VAL_IRQ_FORCE_HANG |\
+ MALI200_REG_VAL_IRQ_BUS_ERROR |\
+ MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR |\
+ MALI400PP_REG_VAL_IRQ_INVALID_PLIST_COMMAND |\
+ MALI400PP_REG_VAL_IRQ_CALL_STACK_UNDERFLOW |\
+ MALI400PP_REG_VAL_IRQ_CALL_STACK_OVERFLOW))
+
+#define MALI200_REG_VAL_IRQ_MASK_NONE ((enum mali200_mgmt_irq)(0))
+
+enum mali200_mgmt_status {
+ MALI200_REG_VAL_STATUS_RENDERING_ACTIVE = (1<<0),
+ MALI200_REG_VAL_STATUS_BUS_STOPPED = (1<<4),
+};
+
+enum mali200_render_unit
+{
+ MALI200_REG_ADDR_FRAME = 0x0000,
+ MALI200_REG_ADDR_RSW = 0x0004,
+ MALI200_REG_ADDR_STACK = 0x0030,
+ MALI200_REG_ADDR_STACK_SIZE = 0x0034,
+ MALI200_REG_ADDR_ORIGIN_OFFSET_X = 0x0040
+};
+
+enum mali200_wb_unit {
+ MALI200_REG_ADDR_WB0 = 0x0100,
+ MALI200_REG_ADDR_WB1 = 0x0200,
+ MALI200_REG_ADDR_WB2 = 0x0300
+};
+
+enum mali200_wb_unit_regs {
+ MALI200_REG_ADDR_WB_SOURCE_SELECT = 0x0000,
+};
+
+/* This should be in the top 16 bit of the version register of Mali PP */
+#define MALI200_PP_PRODUCT_ID 0xC807
+#define MALI300_PP_PRODUCT_ID 0xCE07
+#define MALI400_PP_PRODUCT_ID 0xCD07
+#define MALI450_PP_PRODUCT_ID 0xCF07
+
+
+#endif /* _MALI200_REGS_H_ */
diff --git a/drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h b/drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h
new file mode 100644
index 0000000..c204901
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/regs/mali_gp_regs.h
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef _MALIGP2_CONROL_REGS_H_
+#define _MALIGP2_CONROL_REGS_H_
+
+/**
+ * These are the different geometry processor control registers.
+ * Their usage is to control and monitor the operation of the
+ * Vertex Shader and the Polygon List Builder in the geometry processor.
+ * Addresses are in 32-bit word relative sizes.
+ * @see [P0081] "Geometry Processor Data Structures" for details
+ */
+
+typedef enum {
+ MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR = 0x00,
+ MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR = 0x04,
+ MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR = 0x08,
+ MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR = 0x0c,
+ MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR = 0x10,
+ MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR = 0x14,
+ MALIGP2_REG_ADDR_MGMT_CMD = 0x20,
+ MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT = 0x24,
+ MALIGP2_REG_ADDR_MGMT_INT_CLEAR = 0x28,
+ MALIGP2_REG_ADDR_MGMT_INT_MASK = 0x2C,
+ MALIGP2_REG_ADDR_MGMT_INT_STAT = 0x30,
+ MALIGP2_REG_ADDR_MGMT_WRITE_BOUND_LOW = 0x34,
+ MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE = 0x3C,
+ MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE = 0x40,
+ MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC = 0x44,
+ MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC = 0x48,
+ MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE = 0x4C,
+ MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE = 0x50,
+ MALIGP2_REG_ADDR_MGMT_STATUS = 0x68,
+ MALIGP2_REG_ADDR_MGMT_VERSION = 0x6C,
+ MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ = 0x80,
+ MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ = 0x84,
+ MALIGP2_CONTR_AXI_BUS_ERROR_STAT = 0x94,
+ MALIGP2_REGISTER_ADDRESS_SPACE_SIZE = 0x98,
+} maligp_reg_addr_mgmt_addr;
+
+#define MALIGP2_REG_VAL_PERF_CNT_ENABLE 1
+
+/**
+ * Commands to geometry processor.
+ * @see MALIGP2_CTRL_REG_CMD
+ */
+typedef enum
+{
+ MALIGP2_REG_VAL_CMD_START_VS = (1<< 0),
+ MALIGP2_REG_VAL_CMD_START_PLBU = (1<< 1),
+ MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC = (1<< 4),
+ MALIGP2_REG_VAL_CMD_RESET = (1<< 5),
+ MALIGP2_REG_VAL_CMD_FORCE_HANG = (1<< 6),
+ MALIGP2_REG_VAL_CMD_STOP_BUS = (1<< 9),
+ MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10), /* only valid for Mali-300 and later */
+} mgp_contr_reg_val_cmd;
+
+
+/** @defgroup MALIGP2_IRQ
+ * Interrupt status of geometry processor.
+ * @see MALIGP2_CTRL_REG_INT_RAWSTAT, MALIGP2_REG_ADDR_MGMT_INT_CLEAR,
+ * MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_ADDR_MGMT_INT_STAT
+ * @{
+ */
+#define MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST (1 << 0)
+#define MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST (1 << 1)
+#define MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM (1 << 2)
+#define MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ (1 << 3)
+#define MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ (1 << 4)
+#define MALIGP2_REG_VAL_IRQ_HANG (1 << 5)
+#define MALIGP2_REG_VAL_IRQ_FORCE_HANG (1 << 6)
+#define MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT (1 << 7)
+#define MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT (1 << 8)
+#define MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR (1 << 9)
+#define MALIGP2_REG_VAL_IRQ_SYNC_ERROR (1 << 10)
+#define MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR (1 << 11)
+#define MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED (1 << 12)
+#define MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD (1 << 13)
+#define MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD (1 << 14)
+#define MALI400GP_REG_VAL_IRQ_RESET_COMPLETED (1 << 19)
+#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW (1 << 20)
+#define MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW (1 << 21)
+#define MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS (1 << 22)
+
+/* Mask defining all IRQs in Mali GP */
+#define MALIGP2_REG_VAL_IRQ_MASK_ALL \
+ (\
+ MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
+ MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
+ MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
+ MALIGP2_REG_VAL_IRQ_VS_SEM_IRQ | \
+ MALIGP2_REG_VAL_IRQ_PLBU_SEM_IRQ | \
+ MALIGP2_REG_VAL_IRQ_HANG | \
+ MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
+ MALIGP2_REG_VAL_IRQ_PERF_CNT_0_LIMIT | \
+ MALIGP2_REG_VAL_IRQ_PERF_CNT_1_LIMIT | \
+ MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
+ MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
+ MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \
+ MALI400GP_REG_VAL_IRQ_AXI_BUS_STOPPED | \
+ MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \
+ MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \
+ MALI400GP_REG_VAL_IRQ_RESET_COMPLETED | \
+ MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \
+ MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \
+ MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
+
+/* Mask defining the IRQs in Mali GP which we use */
+#define MALIGP2_REG_VAL_IRQ_MASK_USED \
+ (\
+ MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
+ MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST | \
+ MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | \
+ MALIGP2_REG_VAL_IRQ_FORCE_HANG | \
+ MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
+ MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
+ MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR | \
+ MALI400GP_REG_VAL_IRQ_VS_INVALID_CMD | \
+ MALI400GP_REG_VAL_IRQ_PLB_INVALID_CMD | \
+ MALI400GP_REG_VAL_IRQ_SEMAPHORE_UNDERFLOW | \
+ MALI400GP_REG_VAL_IRQ_SEMAPHORE_OVERFLOW | \
+ MALI400GP_REG_VAL_IRQ_PTR_ARRAY_OUT_OF_BOUNDS)
+
+/* Mask defining non IRQs on MaliGP2*/
+#define MALIGP2_REG_VAL_IRQ_MASK_NONE 0
+
+/** }@ defgroup MALIGP2_IRQ*/
+
+/** @defgroup MALIGP2_STATUS
+ * The different Status values to the geometry processor.
+ * @see MALIGP2_CTRL_REG_STATUS
+ * @{
+ */
+#define MALIGP2_REG_VAL_STATUS_VS_ACTIVE 0x0002
+#define MALIGP2_REG_VAL_STATUS_BUS_STOPPED 0x0004
+#define MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE 0x0008
+#define MALIGP2_REG_VAL_STATUS_BUS_ERROR 0x0040
+#define MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR 0x0100
+/** }@ defgroup MALIGP2_STATUS*/
+
+#define MALIGP2_REG_VAL_STATUS_MASK_ACTIVE (\
+ MALIGP2_REG_VAL_STATUS_VS_ACTIVE|\
+ MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE)
+
+
+#define MALIGP2_REG_VAL_STATUS_MASK_ERROR (\
+ MALIGP2_REG_VAL_STATUS_BUS_ERROR |\
+ MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR )
+
+/* This should be in the top 16 bit of the version register of gp.*/
+#define MALI200_GP_PRODUCT_ID 0xA07
+#define MALI300_GP_PRODUCT_ID 0xC07
+#define MALI400_GP_PRODUCT_ID 0xB07
+#define MALI450_GP_PRODUCT_ID 0xD07
+
+/**
+ * The different sources for instrumented on the geometry processor.
+ * @see MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC
+ */
+
+enum MALIGP2_cont_reg_perf_cnt_src {
+ MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED = 0x0a,
+};
+
+#endif
diff --git a/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c
new file mode 100644
index 0000000..a6b1d76
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_timestamp.h"
+
+/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */
diff --git a/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.h
new file mode 100644
index 0000000..3279dae
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-arm11-cc/mali_timestamp.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_TIMESTAMP_H__
+#define __MALI_TIMESTAMP_H__
+
+#include "mali_osk.h"
+
+MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void)
+{
+ /*
+ * reset counters and overflow flags
+ */
+
+ u32 mask = (1 << 0) | /* enable all three counters */
+ (0 << 1) | /* reset both Count Registers to 0x0 */
+ (1 << 2) | /* reset the Cycle Counter Register to 0x0 */
+ (0 << 3) | /* 1 = Cycle Counter Register counts every 64th processor clock cycle */
+ (0 << 4) | /* Count Register 0 interrupt enable */
+ (0 << 5) | /* Count Register 1 interrupt enable */
+ (0 << 6) | /* Cycle Counter interrupt enable */
+ (0 << 8) | /* Count Register 0 overflow flag (clear or write, flag on read) */
+ (0 << 9) | /* Count Register 1 overflow flag (clear or write, flag on read) */
+ (1 << 10); /* Cycle Counter Register overflow flag (clear or write, flag on read) */
+
+ __asm__ __volatile__ ("MCR p15, 0, %0, c15, c12, 0" : : "r" (mask) );
+
+ return _MALI_OSK_ERR_OK;
+}
+
+MALI_STATIC_INLINE u64 _mali_timestamp_get(void)
+{
+ u32 result;
+
+ /* this is for the clock cycles */
+ __asm__ __volatile__ ("MRC p15, 0, %0, c15, c12, 1" : "=r" (result));
+
+ return (u64)result;
+}
+
+#endif /* __MALI_TIMESTAMP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c
new file mode 100644
index 0000000..a6b1d76
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_timestamp.h"
+
+/* This file is intentionally left empty, as all functions are inlined in mali_profiling_sampler.h */
diff --git a/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.h b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.h
new file mode 100644
index 0000000..94b842a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/mali/timestamp-default/mali_timestamp.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MALI_TIMESTAMP_H__
+#define __MALI_TIMESTAMP_H__
+
+#include "mali_osk.h"
+
+MALI_STATIC_INLINE _mali_osk_errcode_t _mali_timestamp_reset(void)
+{
+ return _MALI_OSK_ERR_OK;
+}
+
+MALI_STATIC_INLINE u64 _mali_timestamp_get(void)
+{
+ return _mali_osk_time_get_ns();
+}
+
+#endif /* __MALI_TIMESTAMP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/Kbuild b/drivers/gpu/mali400/r3p2/ump/Kbuild
new file mode 100644
index 0000000..4ca1aae
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Kbuild
@@ -0,0 +1,78 @@
+#
+# Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# Set default configuration to use, if Makefile didn't provide one.
+# Change this to use a different config.h
+# MALI_SEC
+# CONFIG ?= os_memory_64m
+CONFIG ?= pegasus-m400
+
+# Validate selected config
+ifneq ($(shell [ -d $(srctree)/$(src)/arch-$(CONFIG) ] && [ -f $(srctree)/$(src)/arch-$(CONFIG)/config.h ] && echo "OK"), OK)
+$(warning Current directory is $(srctree)/$(src))
+$(error No configuration found for config $(CONFIG). Check that arch-$(CONFIG)/config.h exists)
+else
+# Link arch to the selected arch-config directory
+$(shell [ -L $(srctree)/$(src)/arch ] && rm $(srctree)/$(src)/arch)
+$(shell ln -sf arch-$(CONFIG) $(srctree)/$(src)/arch)
+$(shell touch $(srctree)/$(src)/arch/config.h)
+endif
+
+UDD_FILE_PREFIX = ../mali/
+
+# Get subversion revision number, fall back to 0000 if no svn info is available
+SVN_REV := 0000
+
+ccflags-y += -DSVN_REV=$(SVN_REV)
+ccflags-y += -DSVN_REV_STRING=\"$(SVN_REV)\"
+
+ccflags-y += -I$(srctree)/$(src) -I$(srctree)/$(src)/common -I$(srctree)/$(src)/linux -I$(srctree)/$(src)/../mali/common -I$(srctree)/$(src)/../mali/linux -I$(srctree)/$(src)/../../ump/include/ump
+
+# MALI_SEC
+ccflags-y += -I$(srctree)/$(src)/include
+ccflags-y += -DUSING_MEMORY=1 -DUMP_MEM_SIZE=512
+
+ccflags-y += -DMALI_STATE_TRACKING=0
+ccflags-$(CONFIG_UMP_DEBUG) += -DDEBUG
+
+# For customer releases the Linux Device Drivers will be provided as ARM proprietary and GPL releases:
+# The ARM proprietary product will only include the license/proprietary directory
+# The GPL product will only include the license/gpl directory
+
+ifeq ($(wildcard $(srctree)/$(src)/linux/license/gpl/*),)
+ccflags-y += -I$(srctree)/$(src)/linux/license/proprietary
+else
+ccflags-y += -I$(srctree)/$(src)/linux/license/gpl
+endif
+
+ump-y = common/ump_kernel_common.o \
+ common/ump_kernel_descriptor_mapping.o \
+ common/ump_kernel_api.o \
+ common/ump_kernel_ref_drv.o \
+ linux/ump_kernel_linux.o \
+ linux/ump_kernel_memory_backend_os.o \
+ linux/ump_kernel_memory_backend_dedicated.o \
+ linux/ump_memory_backend.o \
+ linux/ump_ukk_wrappers.o \
+ linux/ump_ukk_ref_wrappers.o \
+ linux/ump_osk_atomics.o \
+ linux/ump_osk_low_level_mem.o \
+ linux/ump_osk_misc.o
+
+# MALI_SEC
+# $(UDD_FILE_PREFIX)linux/mali_osk_atomics.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_locks.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_memory.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_math.o \
+# $(UDD_FILE_PREFIX)linux/mali_osk_misc.o
+
+# MALI_SEC
+obj-$(CONFIG_MALI400_UMP) := ump.o
+
diff --git a/drivers/gpu/mali400/r3p2/ump/Kconfig b/drivers/gpu/mali400/r3p2/ump/Kconfig
new file mode 100644
index 0000000..13785e2
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Kconfig
@@ -0,0 +1,7 @@
+config UMP_DEBUG
+ bool "Enable extra debug in UMP"
+ depends on MALI400_UMP
+ default n
+ ---help---
+ This enabled extra debug checks and messages in UMP.
+
diff --git a/drivers/gpu/mali400/r3p2/ump/Makefile b/drivers/gpu/mali400/r3p2/ump/Makefile
new file mode 100644
index 0000000..e2aa8e5
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Makefile
@@ -0,0 +1,67 @@
+#
+# Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH
+
+export ARCH ?= arm
+BUILD ?= debug
+
+check_cc2 = \
+ $(shell if $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; \
+ then \
+ echo "$(2)"; \
+ else \
+ echo "$(3)"; \
+ fi ;)
+
+# Check that required parameters are supplied.
+ifeq ($(CONFIG),)
+$(error "CONFIG must be specified.")
+endif
+ifeq ($(CPU)$(KDIR),)
+$(error "KDIR or CPU must be specified.")
+endif
+
+# Get any user defined KDIR-<names> or maybe even a hardcoded KDIR
+-include KDIR_CONFIGURATION
+
+# Define host system directory
+KDIR-$(shell uname -m):=/lib/modules/$(shell uname -r)/build
+
+ifeq ($(ARCH), arm)
+# when compiling for ARM we're cross compiling
+export CROSS_COMPILE ?= $(call check_cc2, arm-linux-gnueabi-gcc, arm-linux-gnueabi-, arm-none-linux-gnueabi-)
+endif
+
+# look up KDIR based om CPU selection
+KDIR ?= $(KDIR-$(CPU))
+
+export CONFIG
+
+export CONFIG_UMP := m
+ifeq ($(BUILD),debug)
+export CONFIG_UMP_DEBUG := y
+else
+export CONFIG_UMP_DEBUG := n
+endif
+
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(CPU))
+endif
+
+all:
+ $(MAKE) -C $(KDIR) M=$(CURDIR) modules
+
+kernelrelease:
+ $(MAKE) -C $(KDIR) kernelrelease
+
+clean:
+ $(MAKE) -C $(KDIR) M=$(CURDIR) clean
+ $(MAKE) -C $(KDIR) M=$(CURDIR)/../mali clean
diff --git a/drivers/gpu/mali400/r3p2/ump/Makefile.common b/drivers/gpu/mali400/r3p2/ump/Makefile.common
new file mode 100644
index 0000000..c6aa633
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/Makefile.common
@@ -0,0 +1,20 @@
+#
+# Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+#
+# This program is free software and is provided to you under the terms of the GNU General Public License version 2
+# as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+#
+# A copy of the licence is included with the program, and can also be obtained from Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+SRC = $(UMP_FILE_PREFIX)common/ump_kernel_common.c \
+ $(UMP_FILE_PREFIX)common/ump_kernel_descriptor_mapping.c \
+ $(UMP_FILE_PREFIX)common/ump_kernel_api.c \
+ $(UMP_FILE_PREFIX)common/ump_kernel_ref_drv.c
+
+# Get subversion revision number, fall back to 0000 if no svn info is available
+SVN_REV:=$(shell ((svnversion | grep -qv exported && echo -n 'Revision: ' && svnversion) || git svn info | sed -e 's/$$$$/M/' | grep '^Revision: ' || echo ${MALI_RELEASE_NAME}) 2>/dev/null | sed -e 's/^Revision: //')
+
+EXTRA_CFLAGS += -DSVN_REV=$(SVN_REV)
+EXTRA_CFLAGS += -DSVN_REV_STRING=\"$(SVN_REV)\"
diff --git a/drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h b/drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h
new file mode 100644
index 0000000..7afbca6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/arch-pegasus-m400/config.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARCH_CONFIG_UMP_H__
+#define __ARCH_CONFIG_UMP_H__
+
+#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY
+#if (USING_MEMORY == 0) /* Dedicated Memory */
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000
+#else
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0
+#endif
+
+#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024
+#endif /* __ARCH_CONFIG_UMP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m400 b/drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m400
new file mode 120000
index 0000000..4006f31
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/arch/arch-pegasus-m400
@@ -0,0 +1 @@
+arch-pegasus-m400 \ No newline at end of file
diff --git a/drivers/gpu/mali400/r3p2/ump/arch/config.h b/drivers/gpu/mali400/r3p2/ump/arch/config.h
new file mode 100644
index 0000000..7afbca6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/arch/config.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __ARCH_CONFIG_UMP_H__
+#define __ARCH_CONFIG_UMP_H__
+
+#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY
+#if (USING_MEMORY == 0) /* Dedicated Memory */
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000
+#else
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0
+#endif
+
+#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024
+#endif /* __ARCH_CONFIG_UMP_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c
new file mode 100644
index 0000000..013f4c6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_api.c
@@ -0,0 +1,548 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "ump_osk.h"
+#include "ump_uk_types.h"
+#include "ump_kernel_interface.h"
+#include "ump_kernel_common.h"
+
+
+
+/* ---------------- UMP kernel space API functions follows ---------------- */
+
+
+
+UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle memh)
+{
+ ump_dd_mem * mem = (ump_dd_mem *)memh;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ DBG_MSG(5, ("Returning secure ID. ID: %u\n", mem->secure_id));
+
+ return mem->secure_id;
+}
+
+
+
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id)
+{
+ ump_dd_mem * mem;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id));
+ if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ ump_dd_reference_add(mem);
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return (ump_dd_handle)mem;
+}
+
+/* MALI_SEC */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id)
+{
+ ump_dd_mem * mem;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ DBG_MSG(5, ("Getting handle from secure ID. ID: %u\n", secure_id));
+ if (0 != ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Secure ID not found. ID: %u\n", secure_id));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return (ump_dd_handle)mem;
+}
+
+UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle memh)
+{
+ ump_dd_mem * mem = (ump_dd_mem*) memh;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ return mem->nr_blocks;
+}
+
+
+
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle memh, ump_dd_physical_block * blocks, unsigned long num_blocks)
+{
+ ump_dd_mem * mem = (ump_dd_mem *)memh;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ if (blocks == NULL)
+ {
+ DBG_MSG(1, ("NULL parameter in ump_dd_phys_blocks_get()\n"));
+ return UMP_DD_INVALID;
+ }
+
+ if (mem->nr_blocks != num_blocks)
+ {
+ DBG_MSG(1, ("Specified number of blocks do not match actual number of blocks\n"));
+ return UMP_DD_INVALID;
+ }
+
+ DBG_MSG(5, ("Returning physical block information. ID: %u\n", mem->secure_id));
+
+ _mali_osk_memcpy(blocks, mem->block_array, sizeof(ump_dd_physical_block) * mem->nr_blocks);
+
+ return UMP_DD_SUCCESS;
+}
+
+
+
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle memh, unsigned long index, ump_dd_physical_block * block)
+{
+ ump_dd_mem * mem = (ump_dd_mem *)memh;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ if (block == NULL)
+ {
+ DBG_MSG(1, ("NULL parameter in ump_dd_phys_block_get()\n"));
+ return UMP_DD_INVALID;
+ }
+
+ if (index >= mem->nr_blocks)
+ {
+ DBG_MSG(5, ("Invalid index specified in ump_dd_phys_block_get()\n"));
+ return UMP_DD_INVALID;
+ }
+
+ DBG_MSG(5, ("Returning physical block information. ID: %u, index: %lu\n", mem->secure_id, index));
+
+ *block = mem->block_array[index];
+
+ return UMP_DD_SUCCESS;
+}
+
+
+
+UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle memh)
+{
+ ump_dd_mem * mem = (ump_dd_mem*)memh;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ DBG_MSG(5, ("Returning size. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes));
+
+ return mem->size_bytes;
+}
+
+
+
+UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle memh)
+{
+ ump_dd_mem * mem = (ump_dd_mem*)memh;
+ int new_ref;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ new_ref = _ump_osk_atomic_inc_and_read(&mem->ref_count);
+
+ DBG_MSG(5, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
+}
+
+
+
+UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle memh)
+{
+ int new_ref;
+ ump_dd_mem * mem = (ump_dd_mem*)memh;
+
+ DEBUG_ASSERT_POINTER(mem);
+
+ /* We must hold this mutex while doing the atomic_dec_and_read, to protect
+ that elements in the ump_descriptor_mapping table is always valid. If they
+ are not, userspace may accidently map in this secure_ids right before its freed
+ giving a mapped backdoor into unallocated memory.*/
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ new_ref = _ump_osk_atomic_dec_and_read(&mem->ref_count);
+
+ DBG_MSG(5, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
+
+ if (0 == new_ref)
+ {
+ DBG_MSG(3, ("Final release of memory. ID: %u\n", mem->secure_id));
+
+ ump_descriptor_mapping_free(device.secure_id_map, (int)mem->secure_id);
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ mem->release_func(mem->ctx, mem);
+ _mali_osk_free(mem);
+ }
+ else
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ }
+}
+
+
+
+/* --------------- Handling of user space requests follows --------------- */
+
+
+_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args )
+{
+ ump_session_data * session_data;
+
+ DEBUG_ASSERT_POINTER( args );
+ DEBUG_ASSERT_POINTER( args->ctx );
+
+ session_data = (ump_session_data *)args->ctx;
+
+ /* check compatability */
+ if (args->version == UMP_IOCTL_API_VERSION)
+ {
+ DBG_MSG(3, ("API version set to newest %d (compatible)\n", GET_VERSION(args->version)));
+ args->compatible = 1;
+ session_data->api_version = args->version;
+ }
+ else if (args->version == MAKE_VERSION_ID(1))
+ {
+ DBG_MSG(2, ("API version set to depricated: %d (compatible)\n", GET_VERSION(args->version)));
+ args->compatible = 1;
+ session_data->api_version = args->version;
+ }
+ else
+ {
+ DBG_MSG(2, ("API version set to %d (incompatible with client version %d)\n", GET_VERSION(UMP_IOCTL_API_VERSION), GET_VERSION(args->version)));
+ args->compatible = 0;
+ args->version = UMP_IOCTL_API_VERSION; /* report our version */
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+
+_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info )
+{
+ ump_session_memory_list_element * session_memory_element;
+ ump_session_memory_list_element * tmp;
+ ump_session_data * session_data;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_INVALID_FUNC;
+ int secure_id;
+
+ DEBUG_ASSERT_POINTER( release_info );
+ DEBUG_ASSERT_POINTER( release_info->ctx );
+
+ /* Retreive the session data */
+ session_data = (ump_session_data*)release_info->ctx;
+
+ /* If there are many items in the memory session list we
+ * could be de-referencing this pointer a lot so keep a local copy
+ */
+ secure_id = release_info->secure_id;
+
+ DBG_MSG(4, ("Releasing memory with IOCTL, ID: %u\n", secure_id));
+
+ /* Iterate through the memory list looking for the requested secure ID */
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _MALI_OSK_LIST_FOREACHENTRY(session_memory_element, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list)
+ {
+ if ( session_memory_element->mem->secure_id == secure_id)
+ {
+ ump_dd_mem *release_mem;
+
+ release_mem = session_memory_element->mem;
+ _mali_osk_list_del(&session_memory_element->list);
+ ump_dd_reference_release(release_mem);
+ _mali_osk_free(session_memory_element);
+
+ ret = _MALI_OSK_ERR_OK;
+ break;
+ }
+ }
+
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG_IF(1, _MALI_OSK_ERR_OK != ret, ("UMP memory with ID %u does not belong to this session.\n", secure_id));
+
+ DBG_MSG(4, ("_ump_ukk_release() returning 0x%x\n", ret));
+ return ret;
+}
+
+_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction )
+{
+ ump_dd_mem * mem;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+
+ DEBUG_ASSERT_POINTER( user_interaction );
+
+ /* We lock the mappings so things don't get removed while we are looking for the memory */
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)user_interaction->secure_id, (void**)&mem))
+ {
+ user_interaction->size = mem->size_bytes;
+ DBG_MSG(4, ("Returning size. ID: %u, size: %lu ", (ump_secure_id)user_interaction->secure_id, (unsigned long)user_interaction->size));
+ ret = _MALI_OSK_ERR_OK;
+ }
+ else
+ {
+ user_interaction->size = 0;
+ DBG_MSG(1, ("Failed to look up mapping in ump_ioctl_size_get(). ID: %u\n", (ump_secure_id)user_interaction->secure_id));
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ return ret;
+}
+
+
+
+void _ump_ukk_msync( _ump_uk_msync_s *args )
+{
+ ump_dd_mem * mem = NULL;
+ void *virtual = NULL;
+ u32 size = 0;
+ u32 offset = 0;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
+
+ if (NULL == mem)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_msync(). ID: %u\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+ /* Ensure the memory doesn't dissapear when we are flushing it. */
+ ump_dd_reference_add(mem);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* Returns the cache settings back to Userspace */
+ args->is_cached=mem->is_cached;
+
+ /* If this flag is the only one set, we should not do the actual flush, only the readout */
+ if ( _UMP_UK_MSYNC_READOUT_CACHE_ENABLED==args->op )
+ {
+ DBG_MSG(3, ("_ump_ukk_msync READOUT ID: %u Enabled: %d\n", (ump_secure_id)args->secure_id, mem->is_cached));
+ goto msync_release_and_return;
+ }
+
+ /* Nothing to do if the memory is not caches */
+ if ( 0==mem->is_cached )
+ {
+ DBG_MSG(3, ("_ump_ukk_msync IGNORING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op));
+ goto msync_release_and_return;
+ }
+ DBG_MSG(3, ("UMP[%02u] _ump_ukk_msync Flush OP: %d Address: 0x%08x Mapping: 0x%08x\n",
+ (ump_secure_id)args->secure_id, args->op, args->address, args->mapping));
+
+ if ( args->address )
+ {
+ virtual = (void *)((u32)args->address);
+ offset = (u32)((args->address) - (args->mapping));
+ } else {
+ /* Flush entire mapping when no address is specified. */
+ virtual = args->mapping;
+ }
+ if ( args->size )
+ {
+ size = args->size;
+ } else {
+ /* Flush entire mapping when no size is specified. */
+ size = mem->size_bytes - offset;
+ }
+
+ if ( (offset + size) > mem->size_bytes )
+ {
+ DBG_MSG(1, ("Trying to flush more than the entire UMP allocation: offset: %u + size: %u > %u\n", offset, size, mem->size_bytes));
+ goto msync_release_and_return;
+ }
+
+ /* The actual cache flush - Implemented for each OS*/
+ _ump_osk_msync( mem, virtual, offset, size, args->op, NULL);
+
+msync_release_and_return:
+ ump_dd_reference_release(mem);
+ return;
+}
+
+void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args)
+{
+ ump_session_data * session_data;
+ ump_uk_cache_op_control op;
+
+ DEBUG_ASSERT_POINTER( args );
+ DEBUG_ASSERT_POINTER( args->ctx );
+
+ op = args->op;
+ session_data = (ump_session_data *)args->ctx;
+
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ if ( op== _UMP_UK_CACHE_OP_START )
+ {
+ session_data->cache_operations_ongoing++;
+ DBG_MSG(4, ("Cache ops start\n" ));
+ if ( session_data->cache_operations_ongoing != 1 )
+ {
+ DBG_MSG(2, ("UMP: Number of simultanious cache control ops: %d\n", session_data->cache_operations_ongoing) );
+ }
+ }
+ else if ( op== _UMP_UK_CACHE_OP_FINISH )
+ {
+ DBG_MSG(4, ("Cache ops finish\n"));
+ session_data->cache_operations_ongoing--;
+ #if 0
+ if ( session_data->has_pending_level1_cache_flush)
+ {
+ /* This function will set has_pending_level1_cache_flush=0 */
+ _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data);
+ }
+ #endif
+
+ /* to be on the safe side: always flush l1 cache when cache operations are done */
+ _ump_osk_msync( NULL, NULL, 0, 0, _UMP_UK_MSYNC_FLUSH_L1, session_data);
+ DBG_MSG(4, ("Cache ops finish end\n" ));
+ }
+ else
+ {
+ DBG_MSG(1, ("Illegal call to %s at line %d\n", __FUNCTION__, __LINE__));
+ }
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
+}
+
+void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args )
+{
+ ump_dd_mem * mem = NULL;
+ ump_uk_user old_user;
+ ump_uk_msync_op cache_op = _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE;
+ ump_session_data *session_data;
+
+ DEBUG_ASSERT_POINTER( args );
+ DEBUG_ASSERT_POINTER( args->ctx );
+
+ session_data = (ump_session_data *)args->ctx;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
+
+ if (NULL == mem)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_switch_hw_usage(). ID: %u\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+
+ old_user = mem->hw_device;
+ mem->hw_device = args->new_user;
+
+ DBG_MSG(3, ("UMP[%02u] Switch usage Start New: %s Prev: %s.\n", (ump_secure_id)args->secure_id, args->new_user?"MALI":"CPU",old_user?"MALI":"CPU"));
+
+ if ( ! mem->is_cached )
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(3, ("UMP[%02u] Changing owner of uncached memory. Cache flushing not needed.\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+
+ if ( old_user == args->new_user)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(4, ("UMP[%02u] Setting the new_user equal to previous for. Cache flushing not needed.\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+ if (
+ /* Previous AND new is both different from CPU */
+ (old_user != _UMP_UK_USED_BY_CPU) && (args->new_user != _UMP_UK_USED_BY_CPU )
+ )
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(4, ("UMP[%02u] Previous and new user is not CPU. Cache flushing not needed.\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+
+ if ( (old_user != _UMP_UK_USED_BY_CPU ) && (args->new_user==_UMP_UK_USED_BY_CPU) )
+ {
+ cache_op =_UMP_UK_MSYNC_INVALIDATE;
+ DBG_MSG(4, ("UMP[%02u] Cache invalidation needed\n", (ump_secure_id)args->secure_id));
+#ifdef UMP_SKIP_INVALIDATION
+#error
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(4, ("UMP[%02u] Performing Cache invalidation SKIPPED\n", (ump_secure_id)args->secure_id));
+ return;
+#endif
+ }
+ /* Ensure the memory doesn't dissapear when we are flushing it. */
+ ump_dd_reference_add(mem);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* Take lock to protect: session->cache_operations_ongoing and session->has_pending_level1_cache_flush */
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ /* Actual cache flush */
+ _ump_osk_msync( mem, NULL, 0, mem->size_bytes, cache_op, session_data);
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
+ ump_dd_reference_release(mem);
+ DBG_MSG(4, ("UMP[%02u] Switch usage Finish\n", (ump_secure_id)args->secure_id));
+ return;
+}
+
+void _ump_ukk_lock(_ump_uk_lock_s *args )
+{
+ ump_dd_mem * mem = NULL;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
+
+ if (NULL == mem)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("UMP[%02u] Failed to look up mapping in _ump_ukk_lock(). ID: %u\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+ ump_dd_reference_add(mem);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ DBG_MSG(1, ("UMP[%02u] Lock. New lock flag: %d. Old Lock flag:\n", (u32)args->secure_id, (u32)args->lock_usage, (u32) mem->lock_usage ));
+
+ mem->lock_usage = (ump_lock_usage) args->lock_usage;
+
+ ump_dd_reference_release(mem);
+}
+
+void _ump_ukk_unlock(_ump_uk_unlock_s *args )
+{
+ ump_dd_mem * mem = NULL;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ ump_descriptor_mapping_get(device.secure_id_map, (int)args->secure_id, (void**)&mem);
+
+ if (NULL == mem)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in _ump_ukk_unlock(). ID: %u\n", (ump_secure_id)args->secure_id));
+ return;
+ }
+ ump_dd_reference_add(mem);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ DBG_MSG(1, ("UMP[%02u] Unlocking. Old Lock flag:\n", (u32)args->secure_id, (u32) mem->lock_usage ));
+
+ mem->lock_usage = (ump_lock_usage) UMP_NOT_LOCKED;
+
+ ump_dd_reference_release(mem);
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c
new file mode 100644
index 0000000..cf072fb
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.c
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_bitops.h"
+#include "mali_osk_list.h"
+#include "ump_osk.h"
+#include "ump_uk_types.h"
+#include "ump_ukk.h"
+#include "ump_kernel_common.h"
+#include "ump_kernel_descriptor_mapping.h"
+#include "ump_kernel_memory_backend.h"
+
+
+
+/**
+ * Define the initial and maximum size of number of secure_ids on the system
+ */
+#define UMP_SECURE_ID_TABLE_ENTRIES_INITIAL (128 )
+#define UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM (4096 )
+
+
+/**
+ * Define the initial and maximum size of the ump_session_data::cookies_map,
+ * which is a \ref ump_descriptor_mapping. This limits how many secure_ids
+ * may be mapped into a particular process using _ump_ukk_map_mem().
+ */
+
+#define UMP_COOKIES_PER_SESSION_INITIAL (UMP_SECURE_ID_TABLE_ENTRIES_INITIAL )
+#define UMP_COOKIES_PER_SESSION_MAXIMUM (UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM)
+
+struct ump_dev device;
+
+_mali_osk_errcode_t ump_kernel_constructor(void)
+{
+ _mali_osk_errcode_t err;
+
+ /* Perform OS Specific initialization */
+ err = _ump_osk_init();
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ MSG_ERR(("Failed to initiaze the UMP Device Driver"));
+ return err;
+ }
+
+ /* Init the global device */
+ _mali_osk_memset(&device, 0, sizeof(device) );
+
+ /* Create the descriptor map, which will be used for mapping secure ID to ump_dd_mem structs */
+ device.secure_id_map_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0 , 0);
+ if (NULL == device.secure_id_map_lock)
+ {
+ MSG_ERR(("Failed to create OSK lock for secure id lookup table\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ device.secure_id_map = ump_descriptor_mapping_create(UMP_SECURE_ID_TABLE_ENTRIES_INITIAL, UMP_SECURE_ID_TABLE_ENTRIES_MAXIMUM);
+ if (NULL == device.secure_id_map)
+ {
+ _mali_osk_lock_term(device.secure_id_map_lock);
+ MSG_ERR(("Failed to create secure id lookup table\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ /* Init memory backend */
+ device.backend = ump_memory_backend_create();
+ if (NULL == device.backend)
+ {
+ MSG_ERR(("Failed to create memory backend\n"));
+ _mali_osk_lock_term(device.secure_id_map_lock);
+ ump_descriptor_mapping_destroy(device.secure_id_map);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void ump_kernel_destructor(void)
+{
+ DEBUG_ASSERT_POINTER(device.secure_id_map);
+ DEBUG_ASSERT_POINTER(device.secure_id_map_lock);
+
+ _mali_osk_lock_term(device.secure_id_map_lock);
+ device.secure_id_map_lock = NULL;
+
+ ump_descriptor_mapping_destroy(device.secure_id_map);
+ device.secure_id_map = NULL;
+
+ device.backend->shutdown(device.backend);
+ device.backend = NULL;
+
+ ump_memory_backend_destroy();
+
+ _ump_osk_term();
+}
+
+/** Creates a new UMP session
+ */
+_mali_osk_errcode_t _ump_ukk_open( void** context )
+{
+ struct ump_session_data * session_data;
+
+ /* allocated struct to track this session */
+ session_data = (struct ump_session_data *)_mali_osk_malloc(sizeof(struct ump_session_data));
+ if (NULL == session_data)
+ {
+ MSG_ERR(("Failed to allocate ump_session_data in ump_file_open()\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ session_data->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0);
+ if( NULL == session_data->lock )
+ {
+ MSG_ERR(("Failed to initialize lock for ump_session_data in ump_file_open()\n"));
+ _mali_osk_free(session_data);
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ session_data->cookies_map = ump_descriptor_mapping_create( UMP_COOKIES_PER_SESSION_INITIAL, UMP_COOKIES_PER_SESSION_MAXIMUM );
+
+ if ( NULL == session_data->cookies_map )
+ {
+ MSG_ERR(("Failed to create descriptor mapping for _ump_ukk_map_mem cookies\n"));
+
+ _mali_osk_lock_term( session_data->lock );
+ _mali_osk_free( session_data );
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_list);
+
+ _MALI_OSK_INIT_LIST_HEAD(&session_data->list_head_session_memory_mappings_list);
+
+ /* Since initial version of the UMP interface did not use the API_VERSION ioctl we have to assume
+ that it is this version, and not the "latest" one: UMP_IOCTL_API_VERSION
+ Current and later API versions would do an additional call to this IOCTL and update this variable
+ to the correct one.*/
+ session_data->api_version = MAKE_VERSION_ID(1);
+
+ *context = (void*)session_data;
+
+ session_data->cache_operations_ongoing = 0 ;
+ session_data->has_pending_level1_cache_flush = 0;
+
+ DBG_MSG(2, ("New session opened\n"));
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _ump_ukk_close( void** context )
+{
+ struct ump_session_data * session_data;
+ ump_session_memory_list_element * item;
+ ump_session_memory_list_element * tmp;
+
+ session_data = (struct ump_session_data *)*context;
+ if (NULL == session_data)
+ {
+ MSG_ERR(("Session data is NULL in _ump_ukk_close()\n"));
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+
+ /* Unmap any descriptors mapped in. */
+ if (0 == _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list))
+ {
+ ump_memory_allocation *descriptor;
+ ump_memory_allocation *temp;
+
+ DBG_MSG(1, ("Memory mappings found on session usage list during session termination\n"));
+
+ /* use the 'safe' list iterator, since freeing removes the active block from the list we're iterating */
+ _MALI_OSK_LIST_FOREACHENTRY(descriptor, temp, &session_data->list_head_session_memory_mappings_list, ump_memory_allocation, list)
+ {
+ _ump_uk_unmap_mem_s unmap_args;
+ DBG_MSG(4, ("Freeing block with phys address 0x%x size 0x%x mapped in user space at 0x%x\n",
+ descriptor->phys_addr, descriptor->size, descriptor->mapping));
+ unmap_args.ctx = (void*)session_data;
+ unmap_args.mapping = descriptor->mapping;
+ unmap_args.size = descriptor->size;
+ unmap_args._ukk_private = NULL; /* NOTE: unused */
+ unmap_args.cookie = descriptor->cookie;
+
+ /* NOTE: This modifies the list_head_session_memory_mappings_list */
+ _ump_ukk_unmap_mem( &unmap_args );
+ }
+ }
+
+ /* ASSERT that we really did free everything, because _ump_ukk_unmap_mem()
+ * can fail silently. */
+ DEBUG_ASSERT( _mali_osk_list_empty(&session_data->list_head_session_memory_mappings_list) );
+
+ _MALI_OSK_LIST_FOREACHENTRY(item, tmp, &session_data->list_head_session_memory_list, ump_session_memory_list_element, list)
+ {
+ _mali_osk_list_del(&item->list);
+ DBG_MSG(2, ("Releasing UMP memory %u as part of file close\n", item->mem->secure_id));
+ ump_dd_reference_release(item->mem);
+ _mali_osk_free(item);
+ }
+
+ ump_descriptor_mapping_destroy( session_data->cookies_map );
+
+ _mali_osk_lock_term(session_data->lock);
+ _mali_osk_free(session_data);
+
+ DBG_MSG(2, ("Session closed\n"));
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
+{
+ struct ump_session_data * session_data;
+ ump_memory_allocation * descriptor; /* Describes current mapping of memory */
+ _mali_osk_errcode_t err;
+ unsigned long offset = 0;
+ unsigned long left;
+ ump_dd_handle handle; /* The real UMP handle for this memory. Its real datatype is ump_dd_mem* */
+ ump_dd_mem * mem; /* The real UMP memory. It is equal to the handle, but with exposed struct */
+ u32 block;
+ int map_id;
+
+ session_data = (ump_session_data *)args->ctx;
+ if( NULL == session_data )
+ {
+ MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+ /* MALI_SEC */
+ /* SEC kernel stability 2012-02-17 */
+ if (NULL == session_data->cookies_map)
+ {
+ MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n"));
+ return _MALI_OSK_ERR_INVALID_ARGS;
+ }
+ descriptor = (ump_memory_allocation*) _mali_osk_calloc( 1, sizeof(ump_memory_allocation));
+ if (NULL == descriptor)
+ {
+ MSG_ERR(("ump_ukk_map_mem: descriptor allocation failed\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ handle = ump_dd_handle_create_from_secure_id(args->secure_id);
+ if ( UMP_DD_HANDLE_INVALID == handle)
+ {
+ _mali_osk_free(descriptor);
+ DBG_MSG(1, ("Trying to map unknown secure ID %u\n", args->secure_id));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mem = (ump_dd_mem*)handle;
+ DEBUG_ASSERT(mem);
+ if (mem->size_bytes != args->size)
+ {
+ _mali_osk_free(descriptor);
+ ump_dd_reference_release(handle);
+ DBG_MSG(1, ("Trying to map too much or little. ID: %u, virtual size=%lu, UMP size: %lu\n", args->secure_id, args->size, mem->size_bytes));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ map_id = ump_descriptor_mapping_allocate_mapping( session_data->cookies_map, (void*) descriptor );
+
+ if (map_id < 0)
+ {
+ _mali_osk_free(descriptor);
+ ump_dd_reference_release(handle);
+ DBG_MSG(1, ("ump_ukk_map_mem: unable to allocate a descriptor_mapping for return cookie\n"));
+
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ descriptor->size = args->size;
+ descriptor->handle = handle;
+ descriptor->phys_addr = args->phys_addr;
+ descriptor->process_mapping_info = args->_ukk_private;
+ descriptor->ump_session = session_data;
+ descriptor->cookie = (u32)map_id;
+
+ if ( mem->is_cached )
+ {
+ descriptor->is_cached = 1;
+ args->is_cached = 1;
+ DBG_MSG(3, ("Mapping UMP secure_id: %d as cached.\n", args->secure_id));
+ }
+ /* MALI_SEC */
+ else if ( args->is_cached)
+ {
+ mem->is_cached = 1;
+ descriptor->is_cached = 1;
+ DBG_MSG(3, ("Warning mapping UMP secure_id: %d. As cached, while it was allocated uncached.\n", args->secure_id));
+ }
+ else
+ {
+ descriptor->is_cached = 0;
+ args->is_cached = 0;
+ DBG_MSG(3, ("Mapping UMP secure_id: %d as Uncached.\n", args->secure_id));
+ }
+
+ _mali_osk_list_init( &descriptor->list );
+
+ err = _ump_osk_mem_mapregion_init( descriptor );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ DBG_MSG(1, ("Failed to initialize memory mapping in _ump_ukk_map_mem(). ID: %u\n", args->secure_id));
+ ump_descriptor_mapping_free( session_data->cookies_map, map_id );
+ _mali_osk_free(descriptor);
+ ump_dd_reference_release(mem);
+ return err;
+ }
+
+ DBG_MSG(4, ("Mapping virtual to physical memory: ID: %u, size:%lu, first physical addr: 0x%08lx, number of regions: %lu\n",
+ mem->secure_id,
+ mem->size_bytes,
+ ((NULL != mem->block_array) ? mem->block_array->addr : 0),
+ mem->nr_blocks));
+
+ left = descriptor->size;
+ /* loop over all blocks and map them in */
+ for (block = 0; block < mem->nr_blocks; block++)
+ {
+ unsigned long size_to_map;
+
+ if (left > mem->block_array[block].size)
+ {
+ size_to_map = mem->block_array[block].size;
+ }
+ else
+ {
+ size_to_map = left;
+ }
+
+ if (_MALI_OSK_ERR_OK != _ump_osk_mem_mapregion_map(descriptor, offset, (u32 *)&(mem->block_array[block].addr), size_to_map ) )
+ {
+ DBG_MSG(1, ("WARNING: _ump_ukk_map_mem failed to map memory into userspace\n"));
+ printk(KERN_ALERT"UMP:_ump_ukk_map_mem failed to map memory into userspace\n");
+ ump_descriptor_mapping_free( session_data->cookies_map, map_id );
+ ump_dd_reference_release(mem);
+ _ump_osk_mem_mapregion_term( descriptor );
+ _mali_osk_free(descriptor);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ left -= size_to_map;
+ offset += size_to_map;
+ }
+
+ /* Add to the ump_memory_allocation tracking list */
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_add( &descriptor->list, &session_data->list_head_session_memory_mappings_list );
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
+ args->mapping = descriptor->mapping;
+ args->cookie = descriptor->cookie;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args )
+{
+ struct ump_session_data * session_data;
+ ump_memory_allocation * descriptor;
+ ump_dd_handle handle;
+
+ session_data = (ump_session_data *)args->ctx;
+
+ if( NULL == session_data )
+ {
+ MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
+ return;
+ }
+ /* MALI_SEC */
+ /* SEC kernel stability 2012-02-17 */
+ if (NULL == session_data->cookies_map)
+ {
+ MSG_ERR(("session_data->cookies_map is NULL in _ump_ukk_map_mem()\n"));
+ return;
+ }
+ if (0 != ump_descriptor_mapping_get( session_data->cookies_map, (int)args->cookie, (void**)&descriptor) )
+ {
+ MSG_ERR(("_ump_ukk_map_mem: cookie 0x%X not found for this session\n", args->cookie ));
+ return;
+ }
+
+ DEBUG_ASSERT_POINTER(descriptor);
+
+ handle = descriptor->handle;
+ if ( UMP_DD_HANDLE_INVALID == handle)
+ {
+ DBG_MSG(1, ("WARNING: Trying to unmap unknown handle: UNKNOWN\n"));
+ return;
+ }
+
+ /* Remove the ump_memory_allocation from the list of tracked mappings */
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_del( &descriptor->list );
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
+ ump_descriptor_mapping_free( session_data->cookies_map, (int)args->cookie );
+
+ ump_dd_reference_release(handle);
+
+ _ump_osk_mem_mapregion_term( descriptor );
+ _mali_osk_free(descriptor);
+}
+
+u32 _ump_ukk_report_memory_usage( void )
+{
+ if(device.backend->stat)
+ return device.backend->stat(device.backend);
+ else
+ return 0;
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h
new file mode 100644
index 0000000..6e3a2e9
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_common.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __UMP_KERNEL_COMMON_H__
+#define __UMP_KERNEL_COMMON_H__
+
+#include "ump_kernel_types.h"
+#include "ump_kernel_interface.h"
+#include "ump_kernel_descriptor_mapping.h"
+#include "ump_kernel_memory_backend.h"
+
+
+#ifdef DEBUG
+ extern int ump_debug_level;
+ #define UMP_DEBUG_PRINT(args) _mali_osk_dbgmsg args
+ #define UMP_DEBUG_CODE(args) args
+ #define DBG_MSG(level,args) do { /* args should be in brackets */ \
+ ((level) <= ump_debug_level)?\
+ UMP_DEBUG_PRINT(("UMP<" #level ">: ")), \
+ UMP_DEBUG_PRINT(args):0; \
+ } while (0)
+
+ #define DBG_MSG_IF(level,condition,args) /* args should be in brackets */ \
+ if((condition)&&((level) <= ump_debug_level)) {\
+ UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \
+ UMP_DEBUG_PRINT(args); \
+ }
+
+ #define DBG_MSG_ELSE(level,args) /* args should be in brackets */ \
+ else if((level) <= ump_debug_level) { \
+ UMP_DEBUG_PRINT(("UMP<" #level ">: ")); \
+ UMP_DEBUG_PRINT(args); \
+ }
+
+ #define DEBUG_ASSERT_POINTER(pointer) do {if( (pointer)== NULL) MSG_ERR(("NULL pointer " #pointer)); } while(0)
+ #define DEBUG_ASSERT(condition) do {if(!(condition)) MSG_ERR(("ASSERT failed: " #condition)); } while(0)
+#else /* DEBUG */
+ #define UMP_DEBUG_PRINT(args) do {} while(0)
+ #define UMP_DEBUG_CODE(args)
+ #define DBG_MSG(level,args) do {} while(0)
+ #define DBG_MSG_IF(level,condition,args) do {} while(0)
+ #define DBG_MSG_ELSE(level,args) do {} while(0)
+ #define DEBUG_ASSERT(condition) do {} while(0)
+ #define DEBUG_ASSERT_POINTER(pointer) do {} while(0)
+#endif /* DEBUG */
+
+#define MSG_ERR(args) do{ /* args should be in brackets */ \
+ _mali_osk_dbgmsg("UMP: ERR: %s\n" ,__FILE__); \
+ _mali_osk_dbgmsg( " %s()%4d\n", __FUNCTION__, __LINE__) ; \
+ _mali_osk_dbgmsg args ; \
+ _mali_osk_dbgmsg("\n"); \
+ } while(0)
+
+#define MSG(args) do{ /* args should be in brackets */ \
+ _mali_osk_dbgmsg("UMP: "); \
+ _mali_osk_dbgmsg args; \
+ } while (0)
+
+
+
+/*
+ * This struct is used to store per session data.
+ * A session is created when someone open() the device, and
+ * closed when someone close() it or the user space application terminates.
+ */
+typedef struct ump_session_data
+{
+ _mali_osk_list_t list_head_session_memory_list; /**< List of ump allocations made by the process (elements are ump_session_memory_list_element) */
+ _mali_osk_list_t list_head_session_memory_mappings_list; /**< List of ump_memory_allocations mapped in */
+ int api_version;
+ _mali_osk_lock_t * lock;
+ ump_descriptor_mapping * cookies_map; /**< Secure mapping of cookies from _ump_ukk_map_mem() */
+ int cache_operations_ongoing;
+ int has_pending_level1_cache_flush;
+} ump_session_data;
+
+
+
+/*
+ * This struct is used to track the UMP memory references a session has.
+ * We need to track this in order to be able to clean up after user space processes
+ * which don't do it themself (e.g. due to a crash or premature termination).
+ */
+typedef struct ump_session_memory_list_element
+{
+ struct ump_dd_mem * mem;
+ _mali_osk_list_t list;
+} ump_session_memory_list_element;
+
+
+
+/*
+ * Device specific data, created when device driver is loaded, and then kept as the global variable device.
+ */
+typedef struct ump_dev
+{
+ _mali_osk_lock_t * secure_id_map_lock;
+ ump_descriptor_mapping * secure_id_map;
+ ump_memory_backend * backend;
+} ump_dev;
+
+
+
+extern int ump_debug_level;
+extern struct ump_dev device;
+
+_mali_osk_errcode_t ump_kernel_constructor(void);
+void ump_kernel_destructor(void);
+int map_errcode( _mali_osk_errcode_t err );
+
+/**
+ * variables from user space cannot be dereferenced from kernel space; tagging them
+ * with __user allows the GCC compiler to generate a warning. Other compilers may
+ * not support this so we define it here as an empty macro if the compiler doesn't
+ * define it.
+ */
+#ifndef __user
+#define __user
+#endif
+
+#endif /* __UMP_KERNEL_COMMON_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c
new file mode 100644
index 0000000..2531f80
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.c
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_osk_bitops.h"
+#include "ump_kernel_common.h"
+#include "ump_kernel_descriptor_mapping.h"
+
+#define MALI_PAD_INT(x) (((x) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1))
+
+/**
+ * Allocate a descriptor table capable of holding 'count' mappings
+ * @param count Number of mappings in the table
+ * @return Pointer to a new table, NULL on error
+ */
+static ump_descriptor_table * descriptor_table_alloc(int count);
+
+/**
+ * Free a descriptor table
+ * @param table The table to free
+ */
+static void descriptor_table_free(ump_descriptor_table * table);
+
+ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries)
+{
+ ump_descriptor_mapping * map = _mali_osk_calloc(1, sizeof(ump_descriptor_mapping) );
+
+ init_entries = MALI_PAD_INT(init_entries);
+ max_entries = MALI_PAD_INT(max_entries);
+
+ if (NULL != map)
+ {
+ map->table = descriptor_table_alloc(init_entries);
+ if (NULL != map->table)
+ {
+ map->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_READERWRITER, 0 , 0);
+ if ( NULL != map->lock )
+ {
+ _mali_osk_set_nonatomic_bit(0, map->table->usage); /* reserve bit 0 to prevent NULL/zero logic to kick in */
+ map->max_nr_mappings_allowed = max_entries;
+ map->current_nr_mappings = init_entries;
+ return map;
+ }
+ descriptor_table_free(map->table);
+ }
+ _mali_osk_free(map);
+ }
+ return NULL;
+}
+
+void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map)
+{
+ descriptor_table_free(map->table);
+ _mali_osk_lock_term( map->lock );
+ _mali_osk_free(map);
+}
+
+int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target)
+{
+ int descriptor = -1;/*-EFAULT;*/
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ descriptor = _mali_osk_find_first_zero_bit(map->table->usage, map->current_nr_mappings);
+ if (descriptor == map->current_nr_mappings)
+ {
+ int nr_mappings_new;
+ /* no free descriptor, try to expand the table */
+ ump_descriptor_table * new_table;
+ ump_descriptor_table * old_table = map->table;
+ nr_mappings_new= map->current_nr_mappings *2;
+
+ if (map->current_nr_mappings >= map->max_nr_mappings_allowed)
+ {
+ descriptor = -1;
+ goto unlock_and_exit;
+ }
+
+ new_table = descriptor_table_alloc(nr_mappings_new);
+ if (NULL == new_table)
+ {
+ descriptor = -1;
+ goto unlock_and_exit;
+ }
+
+ _mali_osk_memcpy(new_table->usage, old_table->usage, (sizeof(unsigned long)*map->current_nr_mappings) / BITS_PER_LONG);
+ _mali_osk_memcpy(new_table->mappings, old_table->mappings, map->current_nr_mappings * sizeof(void*));
+ map->table = new_table;
+ map->current_nr_mappings = nr_mappings_new;
+ descriptor_table_free(old_table);
+ }
+
+ /* we have found a valid descriptor, set the value and usage bit */
+ _mali_osk_set_nonatomic_bit(descriptor, map->table->usage);
+ map->table->mappings[descriptor] = target;
+
+unlock_and_exit:
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
+ return descriptor;
+}
+
+int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target)
+{
+ int result = -1;/*-EFAULT;*/
+ DEBUG_ASSERT(map);
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ {
+ *target = map->table->mappings[descriptor];
+ result = 0;
+ }
+ else *target = NULL;
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
+ return result;
+}
+
+int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target)
+{
+ int result = -1;/*-EFAULT;*/
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RO);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ {
+ map->table->mappings[descriptor] = target;
+ result = 0;
+ }
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RO);
+ return result;
+}
+
+void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor)
+{
+ _mali_osk_lock_wait(map->lock, _MALI_OSK_LOCKMODE_RW);
+ if ( (descriptor >= 0) && (descriptor < map->current_nr_mappings) && _mali_osk_test_bit(descriptor, map->table->usage) )
+ {
+ map->table->mappings[descriptor] = NULL;
+ _mali_osk_clear_nonatomic_bit(descriptor, map->table->usage);
+ }
+ _mali_osk_lock_signal(map->lock, _MALI_OSK_LOCKMODE_RW);
+}
+
+static ump_descriptor_table * descriptor_table_alloc(int count)
+{
+ ump_descriptor_table * table;
+
+ table = _mali_osk_calloc(1, sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG) + (sizeof(void*) * count) );
+
+ if (NULL != table)
+ {
+ table->usage = (u32*)((u8*)table + sizeof(ump_descriptor_table));
+ table->mappings = (void**)((u8*)table + sizeof(ump_descriptor_table) + ((sizeof(unsigned long) * count)/BITS_PER_LONG));
+ }
+
+ return table;
+}
+
+static void descriptor_table_free(ump_descriptor_table * table)
+{
+ _mali_osk_free(table);
+}
+
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.h
new file mode 100644
index 0000000..92bbe54
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_descriptor_mapping.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_descriptor_mapping.h
+ */
+
+#ifndef __UMP_KERNEL_DESCRIPTOR_MAPPING_H__
+#define __UMP_KERNEL_DESCRIPTOR_MAPPING_H__
+
+#include "mali_osk.h"
+
+/**
+ * The actual descriptor mapping table, never directly accessed by clients
+ */
+typedef struct ump_descriptor_table
+{
+ u32 * usage; /**< Pointer to bitpattern indicating if a descriptor is valid/used or not */
+ void** mappings; /**< Array of the pointers the descriptors map to */
+} ump_descriptor_table;
+
+/**
+ * The descriptor mapping object
+ * Provides a separate namespace where we can map an integer to a pointer
+ */
+typedef struct ump_descriptor_mapping
+{
+ _mali_osk_lock_t *lock; /**< Lock protecting access to the mapping object */
+ int max_nr_mappings_allowed; /**< Max number of mappings to support in this namespace */
+ int current_nr_mappings; /**< Current number of possible mappings */
+ ump_descriptor_table * table; /**< Pointer to the current mapping table */
+} ump_descriptor_mapping;
+
+/**
+ * Create a descriptor mapping object
+ * Create a descriptor mapping capable of holding init_entries growable to max_entries
+ * @param init_entries Number of entries to preallocate memory for
+ * @param max_entries Number of entries to max support
+ * @return Pointer to a descriptor mapping object, NULL on failure
+ */
+ump_descriptor_mapping * ump_descriptor_mapping_create(int init_entries, int max_entries);
+
+/**
+ * Destroy a descriptor mapping object
+ * @param map The map to free
+ */
+void ump_descriptor_mapping_destroy(ump_descriptor_mapping * map);
+
+/**
+ * Allocate a new mapping entry (descriptor ID)
+ * Allocates a new entry in the map.
+ * @param map The map to allocate a new entry in
+ * @param target The value to map to
+ * @return The descriptor allocated, a negative value on error
+ */
+int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void * target);
+
+/**
+ * Get the value mapped to by a descriptor ID
+ * @param map The map to lookup the descriptor id in
+ * @param descriptor The descriptor ID to lookup
+ * @param target Pointer to a pointer which will receive the stored value
+ * @return 0 on successful lookup, negative on error
+ */
+int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, void** target);
+
+/**
+ * Set the value mapped to by a descriptor ID
+ * @param map The map to lookup the descriptor id in
+ * @param descriptor The descriptor ID to lookup
+ * @param target Pointer to replace the current value with
+ * @return 0 on successful lookup, negative on error
+ */
+int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, void * target);
+
+/**
+ * Free the descriptor ID
+ * For the descriptor to be reused it has to be freed
+ * @param map The map to free the descriptor from
+ * @param descriptor The descriptor ID to free
+ */
+void ump_descriptor_mapping_free(ump_descriptor_mapping * map, int descriptor);
+
+#endif /* __UMP_KERNEL_DESCRIPTOR_MAPPING_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h
new file mode 100644
index 0000000..8b11452
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_memory_backend.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_memory_mapping.h
+ */
+
+#ifndef __UMP_KERNEL_MEMORY_BACKEND_H__
+#define __UMP_KERNEL_MEMORY_BACKEND_H__
+
+#include "ump_kernel_interface.h"
+#include "ump_kernel_types.h"
+
+
+typedef struct ump_memory_allocation
+{
+ void * phys_addr;
+ void * mapping;
+ unsigned long size;
+ ump_dd_handle handle;
+ void * process_mapping_info;
+ u32 cookie; /**< necessary on some U/K interface implementations */
+ struct ump_session_data * ump_session; /**< Session that this allocation belongs to */
+ _mali_osk_list_t list; /**< List for linking together memory allocations into the session's memory head */
+ u32 is_cached;
+} ump_memory_allocation;
+
+typedef struct ump_memory_backend
+{
+ int (*allocate)(void* ctx, ump_dd_mem * descriptor);
+ void (*release)(void* ctx, ump_dd_mem * descriptor);
+ void (*shutdown)(struct ump_memory_backend * backend);
+ u32 (*stat)(struct ump_memory_backend *backend);
+ int (*pre_allocate_physical_check)(void *ctx, u32 size);
+ u32 (*adjust_to_mali_phys)(void *ctx, u32 cpu_phys);
+ /* MALI_SEC */
+ void *(*get)(ump_dd_mem *mem, void *args);
+ void (*set)(ump_dd_mem *mem, void *args);
+ void * ctx;
+} ump_memory_backend;
+
+ump_memory_backend * ump_memory_backend_create ( void );
+void ump_memory_backend_destroy( void );
+
+#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */
+
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c
new file mode 100644
index 0000000..6335bf6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_ref_drv.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "mali_osk.h"
+#include "mali_osk_list.h"
+#include "ump_osk.h"
+#include "ump_uk_types.h"
+
+#include "ump_kernel_interface_ref_drv.h"
+#include "ump_kernel_common.h"
+#include "ump_kernel_descriptor_mapping.h"
+
+#define UMP_MINIMUM_SIZE 4096
+#define UMP_MINIMUM_SIZE_MASK (~(UMP_MINIMUM_SIZE-1))
+#define UMP_SIZE_ALIGN(x) (((x)+UMP_MINIMUM_SIZE-1)&UMP_MINIMUM_SIZE_MASK)
+#define UMP_ADDR_ALIGN_OFFSET(x) ((x)&(UMP_MINIMUM_SIZE-1))
+static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor);
+
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks)
+{
+ ump_dd_mem * mem;
+ unsigned long size_total = 0;
+ int map_id;
+ u32 i;
+
+ /* Go through the input blocks and verify that they are sane */
+ for (i=0; i < num_blocks; i++)
+ {
+ unsigned long addr = blocks[i].addr;
+ unsigned long size = blocks[i].size;
+
+ DBG_MSG(5, ("Adding physical memory to new handle. Address: 0x%08lx, size: %lu\n", addr, size));
+ size_total += blocks[i].size;
+
+ if (0 != UMP_ADDR_ALIGN_OFFSET(addr))
+ {
+ MSG_ERR(("Trying to create UMP memory from unaligned physical address. Address: 0x%08lx\n", addr));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ if (0 != UMP_ADDR_ALIGN_OFFSET(size))
+ {
+ MSG_ERR(("Trying to create UMP memory with unaligned size. Size: %lu\n", size));
+ return UMP_DD_HANDLE_INVALID;
+ }
+ }
+
+ /* Allocate the ump_dd_mem struct for this allocation */
+ mem = _mali_osk_malloc(sizeof(*mem));
+ if (NULL == mem)
+ {
+ DBG_MSG(1, ("Could not allocate ump_dd_mem in ump_dd_handle_create_from_phys_blocks()\n"));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ /* Find a secure ID for this allocation */
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*) mem);
+
+ if (map_id < 0)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_free(mem);
+ DBG_MSG(1, ("Failed to allocate secure ID in ump_dd_handle_create_from_phys_blocks()\n"));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ /* Now, make a copy of the block information supplied by the user */
+ mem->block_array = _mali_osk_malloc(sizeof(ump_dd_physical_block)* num_blocks);
+ if (NULL == mem->block_array)
+ {
+ ump_descriptor_mapping_free(device.secure_id_map, map_id);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_free(mem);
+ DBG_MSG(1, ("Could not allocate a mem handle for function ump_dd_handle_create_from_phys_blocks().\n"));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ _mali_osk_memcpy(mem->block_array, blocks, sizeof(ump_dd_physical_block) * num_blocks);
+
+ /* And setup the rest of the ump_dd_mem struct */
+ _mali_osk_atomic_init(&mem->ref_count, 1);
+ mem->secure_id = (ump_secure_id)map_id;
+ mem->size_bytes = size_total;
+ mem->nr_blocks = num_blocks;
+ mem->backend_info = NULL;
+ mem->ctx = NULL;
+ mem->release_func = phys_blocks_release;
+ /* For now UMP handles created by ump_dd_handle_create_from_phys_blocks() is forced to be Uncached */
+ mem->is_cached = 0;
+ mem->hw_device = _UMP_UK_USED_BY_CPU;
+ mem->lock_usage = UMP_NOT_LOCKED;
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(3, ("UMP memory created. ID: %u, size: %lu\n", mem->secure_id, mem->size_bytes));
+
+ return (ump_dd_handle)mem;
+}
+
+static void phys_blocks_release(void * ctx, struct ump_dd_mem * descriptor)
+{
+ _mali_osk_free(descriptor->block_array);
+ descriptor->block_array = NULL;
+}
+
+_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
+{
+ ump_session_data * session_data = NULL;
+ ump_dd_mem *new_allocation = NULL;
+ ump_session_memory_list_element * session_memory_element = NULL;
+ int map_id;
+
+ DEBUG_ASSERT_POINTER( user_interaction );
+ DEBUG_ASSERT_POINTER( user_interaction->ctx );
+
+ session_data = (ump_session_data *) user_interaction->ctx;
+
+ session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element));
+ if (NULL == session_memory_element)
+ {
+ DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+
+ new_allocation = _mali_osk_calloc( 1, sizeof(ump_dd_mem));
+ if (NULL==new_allocation)
+ {
+ _mali_osk_free(session_memory_element);
+ DBG_MSG(1, ("Failed to allocate ump_dd_mem in _ump_ukk_allocate()\n"));
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ /* Create a secure ID for this allocation */
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ map_id = ump_descriptor_mapping_allocate_mapping(device.secure_id_map, (void*)new_allocation);
+
+ if (map_id < 0)
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_free(session_memory_element);
+ _mali_osk_free(new_allocation);
+ DBG_MSG(1, ("Failed to allocate secure ID in ump_ioctl_allocate()\n"));
+ return - _MALI_OSK_ERR_INVALID_FUNC;
+ }
+
+ /* Initialize the part of the new_allocation that we know so for */
+ new_allocation->secure_id = (ump_secure_id)map_id;
+ _mali_osk_atomic_init(&new_allocation->ref_count,1);
+ if ( 0==(UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE & user_interaction->constraints) )
+ new_allocation->is_cached = 0;
+ else new_allocation->is_cached = 1;
+
+ /* special case a size of 0, we should try to emulate what malloc does in this case, which is to return a valid pointer that must be freed, but can't be dereferences */
+ if (0 == user_interaction->size)
+ {
+ user_interaction->size = 1; /* emulate by actually allocating the minimum block size */
+ }
+
+ new_allocation->size_bytes = UMP_SIZE_ALIGN(user_interaction->size); /* Page align the size */
+ new_allocation->lock_usage = UMP_NOT_LOCKED;
+
+ /* Now, ask the active memory backend to do the actual memory allocation */
+ if (!device.backend->allocate( device.backend->ctx, new_allocation ) )
+ {
+ DBG_MSG(3, ("OOM: No more UMP memory left. Failed to allocate memory in ump_ioctl_allocate(). Size: %lu, requested size: %lu\n", new_allocation->size_bytes, (unsigned long)user_interaction->size));
+ ump_descriptor_mapping_free(device.secure_id_map, map_id);
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_free(new_allocation);
+ _mali_osk_free(session_memory_element);
+ return _MALI_OSK_ERR_INVALID_FUNC;
+ }
+ new_allocation->hw_device = _UMP_UK_USED_BY_CPU;
+ new_allocation->ctx = device.backend->ctx;
+ new_allocation->release_func = device.backend->release;
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ /* Initialize the session_memory_element, and add it to the session object */
+ session_memory_element->mem = new_allocation;
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list));
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
+ user_interaction->secure_id = new_allocation->secure_id;
+ user_interaction->size = new_allocation->size_bytes;
+ DBG_MSG(3, ("UMP memory allocated. ID: %u, size: %lu\n", new_allocation->secure_id, new_allocation->size_bytes));
+
+ return _MALI_OSK_ERR_OK;
+}
+
+/* MALI_SEC */
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args)
+{
+ ump_dd_mem * mem;
+ ump_secure_id secure_id;
+
+ DEBUG_ASSERT_POINTER(memh);
+
+ secure_id = ump_dd_secure_id_get(memh);
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ device.backend->set(mem, args);
+ }
+ else
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_set(). ID: %u\n", (ump_secure_id)secure_id));
+ return UMP_DD_INVALID;
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return UMP_DD_SUCCESS;
+}
+
+UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args)
+{
+ ump_dd_mem * mem;
+ void *result;
+
+ _mali_osk_lock_wait(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ if (0 == ump_descriptor_mapping_get(device.secure_id_map, (int)secure_id, (void**)&mem))
+ {
+ result = device.backend->get(mem, args);
+ }
+ else
+ {
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+ DBG_MSG(1, ("Failed to look up mapping in ump_meminfo_get(). ID: %u\n", (ump_secure_id)secure_id));
+ return UMP_DD_HANDLE_INVALID;
+ }
+
+ _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
+
+ return result;
+}
+
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr)
+{
+ ump_dd_mem * mem;
+
+ DBG_MSG(5, ("Getting handle from Virtual address. vaddr: %u\n", vaddr));
+
+ _ump_osk_mem_mapregion_get(&mem, vaddr);
+
+ DBG_MSG(1, ("Getting handle's Handle : 0x%8lx\n", mem));
+
+ return (ump_dd_handle)mem;
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h
new file mode 100644
index 0000000..19a9755
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_kernel_types.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __UMP_KERNEL_TYPES_H__
+#define __UMP_KERNEL_TYPES_H__
+
+#include "ump_kernel_interface.h"
+#include "mali_osk.h"
+
+
+typedef enum
+{
+ UMP_USED_BY_CPU = 0,
+ UMP_USED_BY_MALI = 1,
+ UMP_USED_BY_UNKNOWN_DEVICE= 100,
+} ump_hw_usage;
+
+typedef enum
+{
+ UMP_NOT_LOCKED = 0,
+ UMP_READ = 1,
+ UMP_READ_WRITE = 3,
+} ump_lock_usage;
+
+
+/*
+ * This struct is what is "behind" a ump_dd_handle
+ */
+typedef struct ump_dd_mem
+{
+ ump_secure_id secure_id;
+ _mali_osk_atomic_t ref_count;
+ unsigned long size_bytes;
+ unsigned long nr_blocks;
+ ump_dd_physical_block * block_array;
+ void (*release_func)(void * ctx, struct ump_dd_mem * descriptor);
+ void * ctx;
+ void * backend_info;
+ int is_cached;
+ ump_hw_usage hw_device;
+ ump_lock_usage lock_usage;
+} ump_dd_mem;
+
+
+
+#endif /* __UMP_KERNEL_TYPES_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_osk.h b/drivers/gpu/mali400/r3p2/ump/common/ump_osk.h
new file mode 100644
index 0000000..d9d182a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_osk.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_osk.h
+ * Defines the OS abstraction layer for the UMP kernel device driver (OSK)
+ */
+
+#ifndef __UMP_OSK_H__
+#define __UMP_OSK_H__
+
+#include <mali_osk.h>
+#include <ump_kernel_memory_backend.h>
+#include "ump_uk_types.h"
+#include "ump_kernel_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+_mali_osk_errcode_t _ump_osk_init( void );
+
+_mali_osk_errcode_t _ump_osk_term( void );
+
+int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom );
+
+int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom );
+
+_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation *descriptor );
+
+_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size );
+
+void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor );
+
+void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data );
+
+/* MALI_SEC */
+void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h b/drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h
new file mode 100644
index 0000000..56e4be3
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/common/ump_ukk.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_ukk.h
+ * Defines the kernel-side interface of the user-kernel interface
+ */
+
+#ifndef __UMP_UKK_H__
+#define __UMP_UKK_H__
+
+#include "mali_osk.h"
+#include "ump_uk_types.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+_mali_osk_errcode_t _ump_ukk_open( void** context );
+
+_mali_osk_errcode_t _ump_ukk_close( void** context );
+
+_mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction );
+
+_mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info );
+
+_mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction );
+
+_mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args );
+
+_mali_osk_errcode_t _ump_uku_get_api_version( _ump_uk_api_version_s *args );
+
+void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args );
+
+void _ump_ukk_msync( _ump_uk_msync_s *args );
+
+void _ump_ukk_cache_operations_control(_ump_uk_cache_operations_control_s* args);
+
+void _ump_ukk_switch_hw_usage(_ump_uk_switch_hw_usage_s *args );
+
+void _ump_ukk_lock(_ump_uk_lock_s *args );
+
+void _ump_ukk_unlock(_ump_uk_unlock_s *args );
+
+u32 _ump_ukk_report_memory_usage( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UMP_UKK_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h
new file mode 100644
index 0000000..042c8b1
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_interface.h
+ *
+ * This file contains the kernel space part of the UMP API.
+ */
+
+#ifndef __UMP_KERNEL_INTERFACE_H__
+#define __UMP_KERNEL_INTERFACE_H__
+
+
+/** @defgroup ump_kernel_space_api UMP Kernel Space API
+ * @{ */
+
+
+#include "ump_kernel_platform.h"
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/**
+ * External representation of a UMP handle in kernel space.
+ */
+typedef void * ump_dd_handle;
+
+/**
+ * Typedef for a secure ID, a system wide identificator for UMP memory buffers.
+ */
+typedef unsigned int ump_secure_id;
+
+
+/**
+ * Value to indicate an invalid UMP memory handle.
+ */
+#define UMP_DD_HANDLE_INVALID ((ump_dd_handle)0)
+
+
+/**
+ * Value to indicate an invalid secure Id.
+ */
+#define UMP_INVALID_SECURE_ID ((ump_secure_id)-1)
+
+
+/**
+ * UMP error codes for kernel space.
+ */
+typedef enum
+{
+ UMP_DD_SUCCESS, /**< indicates success */
+ UMP_DD_INVALID, /**< indicates failure */
+} ump_dd_status_code;
+
+
+/**
+ * Struct used to describe a physical block used by UMP memory
+ */
+typedef struct ump_dd_physical_block
+{
+ unsigned long addr; /**< The physical address of the block */
+ unsigned long size; /**< The length of the block, typically page aligned */
+} ump_dd_physical_block;
+
+
+/**
+ * Retrieves the secure ID for the specified UMP memory.
+ *
+ * This identificator is unique across the entire system, and uniquely identifies
+ * the specified UMP memory. This identificator can later be used through the
+ * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id" or
+ * @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id"
+ * functions in order to access this UMP memory, for instance from another process.
+ *
+ * @note There is a user space equivalent function called @ref ump_secure_id_get "ump_secure_id_get"
+ *
+ * @see ump_dd_handle_create_from_secure_id
+ * @see ump_handle_create_from_secure_id
+ * @see ump_secure_id_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return Returns the secure ID for the specified UMP memory.
+ */
+UMP_KERNEL_API_EXPORT ump_secure_id ump_dd_secure_id_get(ump_dd_handle mem);
+
+
+/**
+ * Retrieves a handle to allocated UMP memory.
+ *
+ * The usage of UMP memory is reference counted, so this will increment the reference
+ * count by one for the specified UMP memory.
+ * Use @ref ump_dd_reference_release "ump_dd_reference_release" when there is no longer any
+ * use for the retrieved handle.
+ *
+ * @note There is a user space equivalent function called @ref ump_handle_create_from_secure_id "ump_handle_create_from_secure_id"
+ *
+ * @see ump_dd_reference_release
+ * @see ump_handle_create_from_secure_id
+ *
+ * @param secure_id The secure ID of the UMP memory to open, that can be retrieved using the @ref ump_secure_id_get "ump_secure_id_get " function.
+ *
+ * @return UMP_INVALID_MEMORY_HANDLE indicates failure, otherwise a valid handle is returned.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_secure_id(ump_secure_id secure_id);
+
+
+/**
+ * Retrieves the number of physical blocks used by the specified UMP memory.
+ *
+ * This function retrieves the number of @ref ump_dd_physical_block "ump_dd_physical_block" structs needed
+ * to describe the physical memory layout of the given UMP memory. This can later be used when calling
+ * the functions @ref ump_dd_phys_blocks_get "ump_dd_phys_blocks_get" and
+ * @ref ump_dd_phys_block_get "ump_dd_phys_block_get".
+ *
+ * @see ump_dd_phys_blocks_get
+ * @see ump_dd_phys_block_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return The number of ump_dd_physical_block structs required to describe the physical memory layout of the specified UMP memory.
+ */
+UMP_KERNEL_API_EXPORT unsigned long ump_dd_phys_block_count_get(ump_dd_handle mem);
+
+
+/**
+ * Retrieves all physical memory block information for specified UMP memory.
+ *
+ * This function can be used by other device drivers in order to create MMU tables.
+ *
+ * @note This function will fail if the num_blocks parameter is either to large or to small.
+ *
+ * @see ump_dd_phys_block_get
+ *
+ * @param mem Handle to UMP memory.
+ * @param blocks An array of @ref ump_dd_physical_block "ump_dd_physical_block" structs that will receive the physical description.
+ * @param num_blocks The number of blocks to return in the blocks array. Use the function
+ * @ref ump_dd_phys_block_count_get "ump_dd_phys_block_count_get" first to determine the number of blocks required.
+ *
+ * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_blocks_get(ump_dd_handle mem, ump_dd_physical_block * blocks, unsigned long num_blocks);
+
+
+/**
+ * Retrieves the physical memory block information for specified block for the specified UMP memory.
+ *
+ * This function can be used by other device drivers in order to create MMU tables.
+ *
+ * @note This function will return UMP_DD_INVALID if the specified index is out of range.
+ *
+ * @see ump_dd_phys_blocks_get
+ *
+ * @param mem Handle to UMP memory.
+ * @param index Which physical info block to retrieve.
+ * @param block Pointer to a @ref ump_dd_physical_block "ump_dd_physical_block" struct which will receive the requested information.
+ *
+ * @return UMP_DD_SUCCESS indicates success, UMP_DD_INVALID indicates failure.
+ */
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_phys_block_get(ump_dd_handle mem, unsigned long index, ump_dd_physical_block * block);
+
+
+/**
+ * Retrieves the actual size of the specified UMP memory.
+ *
+ * The size is reported in bytes, and is typically page aligned.
+ *
+ * @note There is a user space equivalent function called @ref ump_size_get "ump_size_get"
+ *
+ * @see ump_size_get
+ *
+ * @param mem Handle to UMP memory.
+ *
+ * @return Returns the allocated size of the specified UMP memory, in bytes.
+ */
+UMP_KERNEL_API_EXPORT unsigned long ump_dd_size_get(ump_dd_handle mem);
+
+
+/**
+ * Adds an extra reference to the specified UMP memory.
+ *
+ * This function adds an extra reference to the specified UMP memory. This function should
+ * be used every time a UMP memory handle is duplicated, that is, assigned to another ump_dd_handle
+ * variable. The function @ref ump_dd_reference_release "ump_dd_reference_release" must then be used
+ * to release each copy of the UMP memory handle.
+ *
+ * @note You are not required to call @ref ump_dd_reference_add "ump_dd_reference_add"
+ * for UMP handles returned from
+ * @ref ump_dd_handle_create_from_secure_id "ump_dd_handle_create_from_secure_id",
+ * because these handles are already reference counted by this function.
+ *
+ * @note There is a user space equivalent function called @ref ump_reference_add "ump_reference_add"
+ *
+ * @see ump_reference_add
+ *
+ * @param mem Handle to UMP memory.
+ */
+UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle mem);
+
+
+/**
+ * Releases a reference from the specified UMP memory.
+ *
+ * This function should be called once for every reference to the UMP memory handle.
+ * When the last reference is released, all resources associated with this UMP memory
+ * handle are freed.
+ *
+ * @note There is a user space equivalent function called @ref ump_reference_release "ump_reference_release"
+ *
+ * @see ump_reference_release
+ *
+ * @param mem Handle to UMP memory.
+ */
+UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle mem);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/** @} */ /* end group ump_kernel_space_api */
+
+
+#endif /* __UMP_KERNEL_INTERFACE_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h
new file mode 100644
index 0000000..b253de5
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_interface_ref_drv.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_interface.h
+ */
+
+#ifndef __UMP_KERNEL_INTERFACE_REF_DRV_H__
+#define __UMP_KERNEL_INTERFACE_REF_DRV_H__
+
+#include "ump_kernel_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Turn specified physical memory into UMP memory. */
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd_physical_block * blocks, unsigned long num_blocks);
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get(ump_secure_id secure_id);
+UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args);
+UMP_KERNEL_API_EXPORT void *ump_dd_meminfo_get(ump_secure_id secure_id, void* args);
+UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long vaddr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UMP_KERNEL_INTERFACE_REF_DRV_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h
new file mode 100644
index 0000000..4349605
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_kernel_platform.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_platform.h
+ *
+ * This file should define UMP_KERNEL_API_EXPORT,
+ * which dictates how the UMP kernel API should be exported/imported.
+ * Modify this file, if needed, to match your platform setup.
+ */
+
+#ifndef __UMP_KERNEL_PLATFORM_H__
+#define __UMP_KERNEL_PLATFORM_H__
+
+/** @addtogroup ump_kernel_space_api
+ * @{ */
+
+/**
+ * A define which controls how UMP kernel space API functions are imported and exported.
+ * This define should be set by the implementor of the UMP API.
+ */
+
+#if defined(_WIN32)
+
+#if defined(UMP_BUILDING_UMP_LIBRARY)
+#define UMP_KERNEL_API_EXPORT __declspec(dllexport)
+#else
+#define UMP_KERNEL_API_EXPORT __declspec(dllimport)
+#endif
+
+#else
+
+#define UMP_KERNEL_API_EXPORT
+
+#endif
+
+
+/** @} */ /* end group ump_kernel_space_api */
+
+
+#endif /* __UMP_KERNEL_PLATFORM_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h b/drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h
new file mode 100644
index 0000000..2f87272
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/include/ump_uk_types.h
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_uk_types.h
+ * Defines the types and constants used in the user-kernel interface
+ */
+
+#ifndef __UMP_UK_TYPES_H__
+#define __UMP_UK_TYPES_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* Helpers for API version handling */
+#define MAKE_VERSION_ID(x) (((x) << 16UL) | (x))
+#define IS_VERSION_ID(x) (((x) & 0xFFFF) == (((x) >> 16UL) & 0xFFFF))
+#define GET_VERSION(x) (((x) >> 16UL) & 0xFFFF)
+#define IS_API_MATCH(x, y) (IS_VERSION_ID((x)) && IS_VERSION_ID((y)) && (GET_VERSION((x)) == GET_VERSION((y))))
+
+/**
+ * API version define.
+ * Indicates the version of the kernel API
+ * The version is a 16bit integer incremented on each API change.
+ * The 16bit integer is stored twice in a 32bit integer
+ * So for version 1 the value would be 0x00010001
+ */
+#define UMP_IOCTL_API_VERSION MAKE_VERSION_ID(2)
+
+typedef enum
+{
+ _UMP_IOC_QUERY_API_VERSION = 1,
+ _UMP_IOC_ALLOCATE,
+ _UMP_IOC_RELEASE,
+ _UMP_IOC_SIZE_GET,
+ _UMP_IOC_MAP_MEM, /* not used in Linux */
+ _UMP_IOC_UNMAP_MEM, /* not used in Linux */
+ _UMP_IOC_MSYNC,
+ _UMP_IOC_CACHE_OPERATIONS_CONTROL,
+ _UMP_IOC_SWITCH_HW_USAGE,
+ _UMP_IOC_LOCK,
+ _UMP_IOC_UNLOCK,
+ _UMP_IOC_ION_IMPORT,
+}_ump_uk_functions;
+
+typedef enum
+{
+ UMP_REF_DRV_UK_CONSTRAINT_NONE = 0,
+ UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR = 1,
+ UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE = 128,
+} ump_uk_alloc_constraints;
+
+typedef enum
+{
+ _UMP_UK_MSYNC_CLEAN = 0,
+ _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE = 1,
+ _UMP_UK_MSYNC_INVALIDATE = 2,
+ _UMP_UK_MSYNC_FLUSH_L1 = 3,
+ _UMP_UK_MSYNC_READOUT_CACHE_ENABLED = 128,
+} ump_uk_msync_op;
+
+typedef enum
+{
+ _UMP_UK_CACHE_OP_START = 0,
+ _UMP_UK_CACHE_OP_FINISH = 1,
+} ump_uk_cache_op_control;
+
+typedef enum
+{
+ _UMP_UK_READ = 1,
+ _UMP_UK_READ_WRITE = 3,
+} ump_uk_lock_usage;
+
+typedef enum
+{
+ _UMP_UK_USED_BY_CPU = 0,
+ _UMP_UK_USED_BY_MALI = 1,
+ _UMP_UK_USED_BY_UNKNOWN_DEVICE= 100,
+} ump_uk_user;
+
+/**
+ * Get API version ([in,out] u32 api_version, [out] u32 compatible)
+ */
+typedef struct _ump_uk_api_version_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 version; /**< Set to the user space version on entry, stores the device driver version on exit */
+ u32 compatible; /**< Non-null if the device is compatible with the client */
+} _ump_uk_api_version_s;
+
+/**
+ * ALLOCATE ([out] u32 secure_id, [in,out] u32 size, [in] contraints)
+ */
+typedef struct _ump_uk_allocate_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< Return value from DD to Userdriver */
+ u32 size; /**< Input and output. Requested size; input. Returned size; output */
+ ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
+} _ump_uk_allocate_s;
+
+typedef struct _ump_uk_ion_import_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ int ion_fd; /**< ion_fd */
+ u32 secure_id; /**< Return value from DD to Userdriver */
+ u32 size; /**< Input and output. Requested size; input. Returned size; output */
+ ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
+} _ump_uk_ion_import_s;
+
+/**
+ * SIZE_GET ([in] u32 secure_id, [out]size )
+ */
+typedef struct _ump_uk_size_get_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< Input to DD */
+ u32 size; /**< Returned size; output */
+} _ump_uk_size_get_s;
+
+/**
+ * Release ([in] u32 secure_id)
+ */
+typedef struct _ump_uk_release_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< Input to DD */
+} _ump_uk_release_s;
+
+typedef struct _ump_uk_map_mem_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ void *mapping; /**< [out] Returns user-space virtual address for the mapping */
+ void *phys_addr; /**< [in] physical address */
+ unsigned long size; /**< [in] size */
+ u32 secure_id; /**< [in] secure_id to assign to mapping */
+ void * _ukk_private; /**< Only used inside linux port between kernel frontend and common part to store vma */
+ u32 cookie;
+ u32 is_cached; /**< [in,out] caching of CPU mappings */
+} _ump_uk_map_mem_s;
+
+typedef struct _ump_uk_unmap_mem_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ void *mapping;
+ u32 size;
+ void * _ukk_private;
+ u32 cookie;
+} _ump_uk_unmap_mem_s;
+
+typedef struct _ump_uk_msync_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ void *mapping; /**< [in] mapping addr */
+ void *address; /**< [in] flush start addr */
+ u32 size; /**< [in] size to flush */
+ ump_uk_msync_op op; /**< [in] flush operation */
+ u32 cookie; /**< [in] cookie stored with reference to the kernel mapping internals */
+ u32 secure_id; /**< [in] secure_id that identifies the ump buffer */
+ u32 is_cached; /**< [out] caching of CPU mappings */
+} _ump_uk_msync_s;
+
+typedef struct _ump_uk_cache_operations_control_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ ump_uk_cache_op_control op; /**< [in] cache operations start/stop */
+} _ump_uk_cache_operations_control_s;
+
+
+typedef struct _ump_uk_switch_hw_usage_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< [in] secure_id that identifies the ump buffer */
+ ump_uk_user new_user; /**< [in] cookie stored with reference to the kernel mapping internals */
+
+} _ump_uk_switch_hw_usage_s;
+
+typedef struct _ump_uk_lock_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< [in] secure_id that identifies the ump buffer */
+ ump_uk_lock_usage lock_usage;
+} _ump_uk_lock_s;
+
+typedef struct _ump_uk_unlock_s
+{
+ void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ u32 secure_id; /**< [in] secure_id that identifies the ump buffer */
+} _ump_uk_unlock_s;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UMP_UK_TYPES_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h b/drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h
new file mode 100644
index 0000000..187e33b
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/license/gpl/ump_kernel_license.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_license.h
+ * Defines for the macro MODULE_LICENSE.
+ */
+
+#ifndef __UMP_KERNEL_LICENSE_H__
+#define __UMP_KERNEL_LICENSE_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define UMP_KERNEL_LINUX_LICENSE "GPL"
+#define UMP_LICENSE_IS_GPL 1
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UMP_KERNEL_LICENSE_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h
new file mode 100644
index 0000000..dcc343a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ioctl.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __UMP_IOCTL_H__
+#define __UMP_IOCTL_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <linux/types.h>
+#include <linux/ioctl.h>
+
+#include <ump_uk_types.h>
+
+#ifndef __user
+#define __user
+#endif
+
+
+/**
+ * @file UMP_ioctl.h
+ * This file describes the interface needed to use the Linux device driver.
+ * The interface is used by the userpace UMP driver.
+ */
+
+#define UMP_IOCTL_NR 0x90
+
+
+#define UMP_IOC_QUERY_API_VERSION _IOR(UMP_IOCTL_NR, _UMP_IOC_QUERY_API_VERSION, _ump_uk_api_version_s)
+#define UMP_IOC_ALLOCATE _IOWR(UMP_IOCTL_NR, _UMP_IOC_ALLOCATE, _ump_uk_allocate_s)
+#define UMP_IOC_RELEASE _IOR(UMP_IOCTL_NR, _UMP_IOC_RELEASE, _ump_uk_release_s)
+#define UMP_IOC_SIZE_GET _IOWR(UMP_IOCTL_NR, _UMP_IOC_SIZE_GET, _ump_uk_size_get_s)
+#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_msync_s)
+/* MALI_SEC */
+#define UMP_IOC_ION_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s)
+/* MALI_SEC */
+#define UMP_IOC_DMABUF_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_DMABUF_IMPORT,\
+ struct ump_uk_dmabuf)
+
+#define UMP_IOC_CACHE_OPERATIONS_CONTROL _IOW(UMP_IOCTL_NR, _UMP_IOC_CACHE_OPERATIONS_CONTROL, _ump_uk_cache_operations_control_s)
+#define UMP_IOC_SWITCH_HW_USAGE _IOW(UMP_IOCTL_NR, _UMP_IOC_SWITCH_HW_USAGE, _ump_uk_switch_hw_usage_s)
+#define UMP_IOC_LOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_LOCK, _ump_uk_lock_s)
+#define UMP_IOC_UNLOCK _IOW(UMP_IOCTL_NR, _UMP_IOC_UNLOCK, _ump_uk_unlock_s)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UMP_IOCTL_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c
new file mode 100644
index 0000000..b509f43
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.c
@@ -0,0 +1,500 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h> /* kernel module definitions */
+#include <linux/fs.h> /* file system operations */
+#include <linux/cdev.h> /* character device definitions */
+#include <linux/ioport.h> /* request_mem_region */
+#include <linux/mm.h> /* memory management functions and types */
+#include <asm/uaccess.h> /* user space access */
+#include <asm/atomic.h>
+#include <linux/device.h>
+#include <linux/debugfs.h>
+
+#include "arch/config.h" /* Configuration for current platform. The symlinc for arch is set by Makefile */
+#include "ump_ioctl.h"
+#include "ump_kernel_common.h"
+#include "ump_kernel_interface.h"
+#include "ump_kernel_interface_ref_drv.h"
+#include "ump_kernel_descriptor_mapping.h"
+#include "ump_kernel_memory_backend.h"
+#include "ump_kernel_memory_backend_os.h"
+#include "ump_kernel_memory_backend_dedicated.h"
+#include "ump_kernel_license.h"
+
+#include "ump_osk.h"
+#include "ump_ukk.h"
+#include "ump_uk_types.h"
+#include "ump_ukk_wrappers.h"
+#include "ump_ukk_ref_wrappers.h"
+
+/* MALI_SEC */
+#ifdef CONFIG_ION_EXYNOS
+#include <linux/ion.h>
+extern struct ion_device *ion_exynos;
+struct ion_client *ion_client_ump = NULL;
+#endif
+
+/* MALI_SEC */
+#if defined(CONFIG_MALI400)
+extern int map_errcode( _mali_osk_errcode_t err );
+#endif
+
+/* Module parameter to control log level */
+int ump_debug_level = 2;
+module_param(ump_debug_level, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
+MODULE_PARM_DESC(ump_debug_level, "Higher number, more dmesg output");
+
+/* By default the module uses any available major, but it's possible to set it at load time to a specific number */
+int ump_major = 0;
+module_param(ump_major, int, S_IRUGO); /* r--r--r-- */
+MODULE_PARM_DESC(ump_major, "Device major number");
+
+/* Name of the UMP device driver */
+static char ump_dev_name[] = "ump"; /* should be const, but the functions we call requires non-cost */
+
+
+#if UMP_LICENSE_IS_GPL
+static struct dentry *ump_debugfs_dir = NULL;
+#endif
+
+/*
+ * The data which we attached to each virtual memory mapping request we get.
+ * Each memory mapping has a reference to the UMP memory it maps.
+ * We release this reference when the last memory mapping is unmapped.
+ */
+typedef struct ump_vma_usage_tracker
+{
+ int references;
+ ump_dd_handle handle;
+} ump_vma_usage_tracker;
+
+struct ump_device
+{
+ struct cdev cdev;
+#if UMP_LICENSE_IS_GPL
+ struct class * ump_class;
+#endif
+};
+
+/* The global variable containing the global device data */
+static struct ump_device ump_device;
+
+
+/* Forward declare static functions */
+static int ump_file_open(struct inode *inode, struct file *filp);
+static int ump_file_release(struct inode *inode, struct file *filp);
+#ifdef HAVE_UNLOCKED_IOCTL
+static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+#else
+static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
+#endif
+static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma);
+
+
+/* This variable defines the file operations this UMP device driver offer */
+static struct file_operations ump_fops =
+{
+ .owner = THIS_MODULE,
+ .open = ump_file_open,
+ .release = ump_file_release,
+#ifdef HAVE_UNLOCKED_IOCTL
+ .unlocked_ioctl = ump_file_ioctl,
+#else
+ .ioctl = ump_file_ioctl,
+#endif
+ .mmap = ump_file_mmap
+};
+
+
+/* This function is called by Linux to initialize this module.
+ * All we do is initialize the UMP device driver.
+ */
+static int ump_initialize_module(void)
+{
+ _mali_osk_errcode_t err;
+
+ DBG_MSG(2, ("Inserting UMP device driver. Compiled: %s, time: %s\n", __DATE__, __TIME__));
+
+ err = ump_kernel_constructor();
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ MSG_ERR(("UMP device driver init failed\n"));
+ return map_errcode(err);
+ }
+
+ MSG(("UMP device driver %s loaded\n", SVN_REV_STRING));
+ return 0;
+}
+
+
+
+/*
+ * This function is called by Linux to unload/terminate/exit/cleanup this module.
+ * All we do is terminate the UMP device driver.
+ */
+static void ump_cleanup_module(void)
+{
+/* MALI_SEC */
+#ifdef CONFIG_ION_EXYNOS
+ if (ion_client_ump)
+ ion_client_destroy(ion_client_ump);
+#endif
+
+ DBG_MSG(2, ("Unloading UMP device driver\n"));
+ ump_kernel_destructor();
+ DBG_MSG(2, ("Module unloaded\n"));
+}
+
+
+
+static ssize_t ump_memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ char buf[64];
+ size_t r;
+ u32 mem = _ump_ukk_report_memory_usage();
+
+ r = snprintf(buf, 64, "%u\n", mem);
+ return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
+}
+
+static const struct file_operations ump_memory_usage_fops = {
+ .owner = THIS_MODULE,
+ .read = ump_memory_used_read,
+};
+
+/*
+ * Initialize the UMP device driver.
+ */
+int ump_kernel_device_initialize(void)
+{
+ int err;
+ dev_t dev = 0;
+#if UMP_LICENSE_IS_GPL
+ ump_debugfs_dir = debugfs_create_dir(ump_dev_name, NULL);
+ if (ERR_PTR(-ENODEV) == ump_debugfs_dir)
+ {
+ ump_debugfs_dir = NULL;
+ }
+ else
+ {
+ debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops);
+ }
+#endif
+
+ if (0 == ump_major)
+ {
+ /* auto select a major */
+ err = alloc_chrdev_region(&dev, 0, 1, ump_dev_name);
+ ump_major = MAJOR(dev);
+ }
+ else
+ {
+ /* use load time defined major number */
+ dev = MKDEV(ump_major, 0);
+ err = register_chrdev_region(dev, 1, ump_dev_name);
+ }
+
+ if (0 == err)
+ {
+ memset(&ump_device, 0, sizeof(ump_device));
+
+ /* initialize our char dev data */
+ cdev_init(&ump_device.cdev, &ump_fops);
+ ump_device.cdev.owner = THIS_MODULE;
+ ump_device.cdev.ops = &ump_fops;
+
+ /* register char dev with the kernel */
+ err = cdev_add(&ump_device.cdev, dev, 1/*count*/);
+ if (0 == err)
+ {
+
+#if UMP_LICENSE_IS_GPL
+ ump_device.ump_class = class_create(THIS_MODULE, ump_dev_name);
+ if (IS_ERR(ump_device.ump_class))
+ {
+ err = PTR_ERR(ump_device.ump_class);
+ }
+ else
+ {
+ struct device * mdev;
+ mdev = device_create(ump_device.ump_class, NULL, dev, NULL, ump_dev_name);
+ if (!IS_ERR(mdev))
+ {
+ return 0;
+ }
+
+ err = PTR_ERR(mdev);
+ }
+ cdev_del(&ump_device.cdev);
+#else
+ return 0;
+#endif
+ }
+
+ unregister_chrdev_region(dev, 1);
+ }
+
+ return err;
+}
+
+
+
+/*
+ * Terminate the UMP device driver
+ */
+void ump_kernel_device_terminate(void)
+{
+ dev_t dev = MKDEV(ump_major, 0);
+
+#if UMP_LICENSE_IS_GPL
+ device_destroy(ump_device.ump_class, dev);
+ class_destroy(ump_device.ump_class);
+#endif
+
+ /* unregister char device */
+ cdev_del(&ump_device.cdev);
+
+ /* free major */
+ unregister_chrdev_region(dev, 1);
+
+#if UMP_LICENSE_IS_GPL
+ if(ump_debugfs_dir)
+ debugfs_remove_recursive(ump_debugfs_dir);
+#endif
+}
+
+/*
+ * Open a new session. User space has called open() on us.
+ */
+static int ump_file_open(struct inode *inode, struct file *filp)
+{
+ struct ump_session_data * session_data;
+ _mali_osk_errcode_t err;
+
+ /* input validation */
+ if (0 != MINOR(inode->i_rdev))
+ {
+ MSG_ERR(("Minor not zero in ump_file_open()\n"));
+ return -ENODEV;
+ }
+
+ /* Call the OS-Independent UMP Open function */
+ err = _ump_ukk_open((void**) &session_data );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ MSG_ERR(("Ump failed to open a new session\n"));
+ return map_errcode( err );
+ }
+
+ filp->private_data = (void*)session_data;
+ filp->f_pos = 0;
+
+ return 0; /* success */
+}
+
+
+
+/*
+ * Close a session. User space has called close() or crashed/terminated.
+ */
+static int ump_file_release(struct inode *inode, struct file *filp)
+{
+ _mali_osk_errcode_t err;
+
+ err = _ump_ukk_close((void**) &filp->private_data );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ return map_errcode( err );
+ }
+
+ return 0; /* success */
+}
+
+
+
+/*
+ * Handle IOCTL requests.
+ */
+#ifdef HAVE_UNLOCKED_IOCTL
+static long ump_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+#else
+static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+#endif
+{
+ int err = -ENOTTY;
+ void __user * argument;
+ struct ump_session_data * session_data;
+
+#ifndef HAVE_UNLOCKED_IOCTL
+ (void)inode; /* inode not used */
+#endif
+
+ session_data = (struct ump_session_data *)filp->private_data;
+ if (NULL == session_data)
+ {
+ MSG_ERR(("No session data attached to file object\n"));
+ return -ENOTTY;
+ }
+
+ /* interpret the argument as a user pointer to something */
+ argument = (void __user *)arg;
+
+ switch (cmd)
+ {
+ case UMP_IOC_QUERY_API_VERSION:
+ err = ump_get_api_version_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_ALLOCATE :
+ err = ump_allocate_wrapper((u32 __user *)argument, session_data);
+ break;
+/* MALI_SEC */
+#ifdef CONFIG_ION_EXYNOS
+ case UMP_IOC_ION_IMPORT:
+ err = ump_ion_import_wrapper((u32 __user *)argument, session_data);
+ break;
+#endif
+#ifdef CONFIG_DMA_SHARED_BUFFER
+ case UMP_IOC_DMABUF_IMPORT:
+ err = ump_dmabuf_import_wrapper((u32 __user *)argument,
+ session_data);
+ break;
+#endif
+ case UMP_IOC_RELEASE:
+ err = ump_release_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_SIZE_GET:
+ err = ump_size_get_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_MSYNC:
+ err = ump_msync_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_CACHE_OPERATIONS_CONTROL:
+ err = ump_cache_operations_control_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_SWITCH_HW_USAGE:
+ err = ump_switch_hw_usage_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_LOCK:
+ err = ump_lock_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ case UMP_IOC_UNLOCK:
+ err = ump_unlock_wrapper((u32 __user *)argument, session_data);
+ break;
+
+ default:
+ DBG_MSG(1, ("No handler for IOCTL. cmd: 0x%08x, arg: 0x%08lx\n", cmd, arg));
+ err = -EFAULT;
+ break;
+ }
+
+ return err;
+}
+
+/* MALI_SEC */
+#if !defined(CONFIG_MALI400)
+int map_errcode( _mali_osk_errcode_t err )
+{
+ switch(err)
+ {
+ case _MALI_OSK_ERR_OK : return 0;
+ case _MALI_OSK_ERR_FAULT: return -EFAULT;
+ case _MALI_OSK_ERR_INVALID_FUNC: return -ENOTTY;
+ case _MALI_OSK_ERR_INVALID_ARGS: return -EINVAL;
+ case _MALI_OSK_ERR_NOMEM: return -ENOMEM;
+ case _MALI_OSK_ERR_TIMEOUT: return -ETIMEDOUT;
+ case _MALI_OSK_ERR_RESTARTSYSCALL: return -ERESTARTSYS;
+ case _MALI_OSK_ERR_ITEM_NOT_FOUND: return -ENOENT;
+ default: return -EFAULT;
+ }
+}
+#endif
+
+/*
+ * Handle from OS to map specified virtual memory to specified UMP memory.
+ */
+static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma)
+{
+ _ump_uk_map_mem_s args;
+ _mali_osk_errcode_t err;
+ struct ump_session_data * session_data;
+
+ /* Validate the session data */
+ session_data = (struct ump_session_data *)filp->private_data;
+ /* MALI_SEC */
+ // original : if (NULL == session_data)
+ if (NULL == session_data || NULL == session_data->cookies_map->table->mappings)
+ {
+ MSG_ERR(("mmap() called without any session data available\n"));
+ return -EFAULT;
+ }
+
+ /* Re-pack the arguments that mmap() packed for us */
+ args.ctx = session_data;
+ args.phys_addr = 0;
+ args.size = vma->vm_end - vma->vm_start;
+ args._ukk_private = vma;
+ args.secure_id = vma->vm_pgoff;
+ args.is_cached = 0;
+
+ if (!(vma->vm_flags & VM_SHARED))
+ {
+ args.is_cached = 1;
+ vma->vm_flags = vma->vm_flags | VM_SHARED | VM_MAYSHARE ;
+ DBG_MSG(3, ("UMP Map function: Forcing the CPU to use cache\n"));
+ }
+ /* By setting this flag, during a process fork; the child process will not have the parent UMP mappings */
+ vma->vm_flags |= VM_DONTCOPY;
+
+ DBG_MSG(4, ("UMP vma->flags: %x\n", vma->vm_flags ));
+
+ /* Call the common mmap handler */
+ err = _ump_ukk_map_mem( &args );
+ if ( _MALI_OSK_ERR_OK != err)
+ {
+ MSG_ERR(("_ump_ukk_map_mem() failed in function ump_file_mmap()"));
+ return map_errcode( err );
+ }
+
+ return 0; /* success */
+}
+
+/* Export UMP kernel space API functions */
+EXPORT_SYMBOL(ump_dd_secure_id_get);
+EXPORT_SYMBOL(ump_dd_handle_create_from_secure_id);
+EXPORT_SYMBOL(ump_dd_phys_block_count_get);
+EXPORT_SYMBOL(ump_dd_phys_block_get);
+EXPORT_SYMBOL(ump_dd_phys_blocks_get);
+EXPORT_SYMBOL(ump_dd_size_get);
+EXPORT_SYMBOL(ump_dd_reference_add);
+EXPORT_SYMBOL(ump_dd_reference_release);
+/* MALI_SEC */
+EXPORT_SYMBOL(ump_dd_meminfo_get);
+EXPORT_SYMBOL(ump_dd_meminfo_set);
+EXPORT_SYMBOL(ump_dd_handle_get_from_vaddr);
+
+/* Export our own extended kernel space allocator */
+EXPORT_SYMBOL(ump_dd_handle_create_from_phys_blocks);
+
+/* Setup init and exit functions for this module */
+module_init(ump_initialize_module);
+module_exit(ump_cleanup_module);
+
+/* And some module informatio */
+MODULE_LICENSE(UMP_KERNEL_LINUX_LICENSE);
+MODULE_AUTHOR("ARM Ltd.");
+MODULE_VERSION(SVN_REV_STRING);
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h
new file mode 100644
index 0000000..4985bb7
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_linux.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __UMP_KERNEL_LINUX_H__
+#define __UMP_KERNEL_LINUX_H__
+
+int ump_kernel_device_initialize(void);
+void ump_kernel_device_terminate(void);
+
+
+#endif /* __UMP_KERNEL_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c
new file mode 100644
index 0000000..f42a320
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else /* pre 2.6.26 the file was in the arch specific location */
+#include <asm/semaphore.h>
+#endif
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/atomic.h>
+#include <linux/vmalloc.h>
+#include "ump_kernel_common.h"
+#include "ump_kernel_memory_backend.h"
+
+
+
+#define UMP_BLOCK_SIZE (256UL * 1024UL) /* 256kB, remember to keep the ()s */
+
+
+
+typedef struct block_info
+{
+ struct block_info * next;
+} block_info;
+
+
+
+typedef struct block_allocator
+{
+ struct semaphore mutex;
+ block_info * all_blocks;
+ block_info * first_free;
+ u32 base;
+ u32 num_blocks;
+ u32 num_free;
+} block_allocator;
+
+
+static void block_allocator_shutdown(ump_memory_backend * backend);
+static int block_allocator_allocate(void* ctx, ump_dd_mem * mem);
+static void block_allocator_release(void * ctx, ump_dd_mem * handle);
+static inline u32 get_phys(block_allocator * allocator, block_info * block);
+static u32 block_allocator_stat(struct ump_memory_backend *backend);
+
+
+
+/*
+ * Create dedicated memory backend
+ */
+ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size)
+{
+ ump_memory_backend * backend;
+ block_allocator * allocator;
+ u32 usable_size;
+ u32 num_blocks;
+
+ usable_size = (size + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1);
+ num_blocks = usable_size / UMP_BLOCK_SIZE;
+
+ if (0 == usable_size)
+ {
+ DBG_MSG(1, ("Memory block of size %u is unusable\n", size));
+ return NULL;
+ }
+
+ DBG_MSG(5, ("Creating dedicated UMP memory backend. Base address: 0x%08x, size: 0x%08x\n", base_address, size));
+ DBG_MSG(6, ("%u usable bytes which becomes %u blocks\n", usable_size, num_blocks));
+
+ backend = kzalloc(sizeof(ump_memory_backend), GFP_KERNEL);
+ if (NULL != backend)
+ {
+ allocator = kmalloc(sizeof(block_allocator), GFP_KERNEL);
+ if (NULL != allocator)
+ {
+ allocator->all_blocks = kmalloc(sizeof(block_allocator) * num_blocks, GFP_KERNEL);
+ if (NULL != allocator->all_blocks)
+ {
+ int i;
+
+ allocator->first_free = NULL;
+ allocator->num_blocks = num_blocks;
+ allocator->num_free = num_blocks;
+ allocator->base = base_address;
+ sema_init(&allocator->mutex, 1);
+
+ for (i = 0; i < num_blocks; i++)
+ {
+ allocator->all_blocks[i].next = allocator->first_free;
+ allocator->first_free = &allocator->all_blocks[i];
+ }
+
+ backend->ctx = allocator;
+ backend->allocate = block_allocator_allocate;
+ backend->release = block_allocator_release;
+ backend->shutdown = block_allocator_shutdown;
+ backend->stat = block_allocator_stat;
+ backend->pre_allocate_physical_check = NULL;
+ backend->adjust_to_mali_phys = NULL;
+ /* MALI_SEC */
+ backend->get = NULL;
+ backend->set = NULL;
+
+ return backend;
+ }
+ kfree(allocator);
+ }
+ kfree(backend);
+ }
+
+ return NULL;
+}
+
+
+
+/*
+ * Destroy specified dedicated memory backend
+ */
+static void block_allocator_shutdown(ump_memory_backend * backend)
+{
+ block_allocator * allocator;
+
+ BUG_ON(!backend);
+ BUG_ON(!backend->ctx);
+
+ allocator = (block_allocator*)backend->ctx;
+
+ DBG_MSG_IF(1, allocator->num_free != allocator->num_blocks, ("%u blocks still in use during shutdown\n", allocator->num_blocks - allocator->num_free));
+
+ kfree(allocator->all_blocks);
+ kfree(allocator);
+ kfree(backend);
+}
+
+
+
+static int block_allocator_allocate(void* ctx, ump_dd_mem * mem)
+{
+ block_allocator * allocator;
+ u32 left;
+ block_info * last_allocated = NULL;
+ int i = 0;
+
+ BUG_ON(!ctx);
+ BUG_ON(!mem);
+
+ allocator = (block_allocator*)ctx;
+ left = mem->size_bytes;
+
+ BUG_ON(!left);
+ BUG_ON(!&allocator->mutex);
+
+ mem->nr_blocks = ((left + UMP_BLOCK_SIZE - 1) & ~(UMP_BLOCK_SIZE - 1)) / UMP_BLOCK_SIZE;
+ mem->block_array = (ump_dd_physical_block*)vmalloc(sizeof(ump_dd_physical_block) * mem->nr_blocks);
+ if (NULL == mem->block_array)
+ {
+ MSG_ERR(("Failed to allocate block array\n"));
+ return 0;
+ }
+
+ if (down_interruptible(&allocator->mutex))
+ {
+ MSG_ERR(("Could not get mutex to do block_allocate\n"));
+ return 0;
+ }
+
+ mem->size_bytes = 0;
+
+ while ((left > 0) && (allocator->first_free))
+ {
+ block_info * block;
+
+ block = allocator->first_free;
+ allocator->first_free = allocator->first_free->next;
+ block->next = last_allocated;
+ last_allocated = block;
+ allocator->num_free--;
+
+ mem->block_array[i].addr = get_phys(allocator, block);
+ mem->block_array[i].size = UMP_BLOCK_SIZE;
+ mem->size_bytes += UMP_BLOCK_SIZE;
+
+ i++;
+
+ if (left < UMP_BLOCK_SIZE) left = 0;
+ else left -= UMP_BLOCK_SIZE;
+ }
+
+ if (left)
+ {
+ block_info * block;
+ /* release all memory back to the pool */
+ while (last_allocated)
+ {
+ block = last_allocated->next;
+ last_allocated->next = allocator->first_free;
+ allocator->first_free = last_allocated;
+ last_allocated = block;
+ allocator->num_free++;
+ }
+
+ vfree(mem->block_array);
+ mem->backend_info = NULL;
+ mem->block_array = NULL;
+
+ DBG_MSG(4, ("Could not find a mem-block for the allocation.\n"));
+ up(&allocator->mutex);
+
+ return 0;
+ }
+
+ mem->backend_info = last_allocated;
+
+ up(&allocator->mutex);
+ mem->is_cached=0;
+
+ return 1;
+}
+
+
+
+static void block_allocator_release(void * ctx, ump_dd_mem * handle)
+{
+ block_allocator * allocator;
+ block_info * block, * next;
+
+ BUG_ON(!ctx);
+ BUG_ON(!handle);
+
+ allocator = (block_allocator*)ctx;
+ block = (block_info*)handle->backend_info;
+ BUG_ON(!block);
+
+ if (down_interruptible(&allocator->mutex))
+ {
+ MSG_ERR(("Allocator release: Failed to get mutex - memory leak\n"));
+ return;
+ }
+
+ while (block)
+ {
+ next = block->next;
+
+ BUG_ON( (block < allocator->all_blocks) || (block > (allocator->all_blocks + allocator->num_blocks)));
+
+ block->next = allocator->first_free;
+ allocator->first_free = block;
+ allocator->num_free++;
+
+ block = next;
+ }
+ DBG_MSG(3, ("%d blocks free after release call\n", allocator->num_free));
+ up(&allocator->mutex);
+
+ vfree(handle->block_array);
+ handle->block_array = NULL;
+}
+
+
+
+/*
+ * Helper function for calculating the physical base adderss of a memory block
+ */
+static inline u32 get_phys(block_allocator * allocator, block_info * block)
+{
+ return allocator->base + ((block - allocator->all_blocks) * UMP_BLOCK_SIZE);
+}
+
+static u32 block_allocator_stat(struct ump_memory_backend *backend)
+{
+ block_allocator *allocator;
+ BUG_ON(!backend);
+ allocator = (block_allocator*)backend->ctx;
+ BUG_ON(!allocator);
+
+ return (allocator->num_blocks - allocator->num_free)* UMP_BLOCK_SIZE;
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.h
new file mode 100644
index 0000000..fa4bdcc
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_dedicated.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_memory_backend_dedicated.h
+ */
+
+#ifndef __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__
+#define __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__
+
+#include "ump_kernel_memory_backend.h"
+
+ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size);
+
+#endif /* __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ */
+
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c
new file mode 100644
index 0000000..57c2a7f
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.c
@@ -0,0 +1,265 @@
+/*
+ * Copyright (C) 2010-2011 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#include <linux/semaphore.h>
+#else /* pre 2.6.26 the file was in the arch specific location */
+#include <asm/semaphore.h>
+#endif
+
+#include <linux/dma-mapping.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <asm/atomic.h>
+#include <linux/vmalloc.h>
+#include <asm/cacheflush.h>
+#include "ump_kernel_common.h"
+#include "ump_kernel_memory_backend.h"
+
+
+
+typedef struct os_allocator
+{
+ struct semaphore mutex;
+ u32 num_pages_max; /**< Maximum number of pages to allocate from the OS */
+ u32 num_pages_allocated; /**< Number of pages allocated from the OS */
+} os_allocator;
+
+
+
+static void os_free(void* ctx, ump_dd_mem * descriptor);
+static int os_allocate(void* ctx, ump_dd_mem * descriptor);
+static void os_memory_backend_destroy(ump_memory_backend * backend);
+static u32 os_stat(struct ump_memory_backend *backend);
+
+
+
+/*
+ * Create OS memory backend
+ */
+ump_memory_backend * ump_os_memory_backend_create(const int max_allocation)
+{
+ ump_memory_backend * backend;
+ os_allocator * info;
+
+ info = kmalloc(sizeof(os_allocator), GFP_KERNEL);
+ if (NULL == info)
+ {
+ return NULL;
+ }
+
+ info->num_pages_max = max_allocation >> PAGE_SHIFT;
+ info->num_pages_allocated = 0;
+
+ sema_init(&info->mutex, 1);
+
+ backend = kmalloc(sizeof(ump_memory_backend), GFP_KERNEL);
+ if (NULL == backend)
+ {
+ kfree(info);
+ return NULL;
+ }
+
+ backend->ctx = info;
+ backend->allocate = os_allocate;
+ backend->release = os_free;
+ backend->shutdown = os_memory_backend_destroy;
+ backend->stat = os_stat;
+ backend->pre_allocate_physical_check = NULL;
+ backend->adjust_to_mali_phys = NULL;
+ /* MALI_SEC */
+ backend->get = NULL;
+ backend->set = NULL;
+
+ return backend;
+}
+
+
+
+/*
+ * Destroy specified OS memory backend
+ */
+static void os_memory_backend_destroy(ump_memory_backend * backend)
+{
+ os_allocator * info = (os_allocator*)backend->ctx;
+
+ DBG_MSG_IF(1, 0 != info->num_pages_allocated, ("%d pages still in use during shutdown\n", info->num_pages_allocated));
+
+ kfree(info);
+ kfree(backend);
+}
+
+
+
+/*
+ * Allocate UMP memory
+ */
+static int os_allocate(void* ctx, ump_dd_mem * descriptor)
+{
+ u32 left;
+ os_allocator * info;
+ int pages_allocated = 0;
+ int is_cached;
+
+ BUG_ON(!descriptor);
+ BUG_ON(!ctx);
+
+ info = (os_allocator*)ctx;
+ left = descriptor->size_bytes;
+ is_cached = descriptor->is_cached;
+
+ if (down_interruptible(&info->mutex))
+ {
+ DBG_MSG(1, ("Failed to get mutex in os_free\n"));
+ return 0; /* failure */
+ }
+
+ descriptor->backend_info = NULL;
+ descriptor->nr_blocks = ((left + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) >> PAGE_SHIFT;
+
+ DBG_MSG(5, ("Allocating page array. Size: %lu\n", descriptor->nr_blocks * sizeof(ump_dd_physical_block)));
+
+ descriptor->block_array = (ump_dd_physical_block *)vmalloc(sizeof(ump_dd_physical_block) * descriptor->nr_blocks);
+ if (NULL == descriptor->block_array)
+ {
+ up(&info->mutex);
+ DBG_MSG(1, ("Block array could not be allocated\n"));
+ return 0; /* failure */
+ }
+
+ while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max))
+ {
+ struct page * new_page;
+
+ if (is_cached)
+ {
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN);
+ } else
+ {
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
+ }
+ if (NULL == new_page)
+ {
+ /* MALI_SEC */
+ DBG_MSG(1, ("UMP memory allocated: Out of Memory !!\n"));
+ break;
+ }
+
+ /* Ensure page caches are flushed. */
+ if ( is_cached )
+ {
+ descriptor->block_array[pages_allocated].addr = page_to_phys(new_page);
+ descriptor->block_array[pages_allocated].size = PAGE_SIZE;
+ } else
+ {
+ descriptor->block_array[pages_allocated].addr = dma_map_page(NULL, new_page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL );
+ descriptor->block_array[pages_allocated].size = PAGE_SIZE;
+ }
+
+ DBG_MSG(5, ("Allocated page 0x%08lx cached: %d\n", descriptor->block_array[pages_allocated].addr, is_cached));
+
+ if (left < PAGE_SIZE)
+ {
+ left = 0;
+ }
+ else
+ {
+ left -= PAGE_SIZE;
+ }
+
+ pages_allocated++;
+ }
+
+ DBG_MSG(5, ("Alloce for ID:%2d got %d pages, cached: %d\n", descriptor->secure_id, pages_allocated));
+
+ if (left)
+ {
+ DBG_MSG(1, ("Failed to allocate needed pages\n"));
+ printk(KERN_ALERT"UMP::Failed to allocated pages, totally pages = %d, allocated pages = %d, currently requested pages = %d \n",
+ (int)info->num_pages_max, (int)info->num_pages_allocated, left + pages_allocated);
+ /* MALI_SEC */
+ DBG_MSG(1, ("UMP memory allocated: %d kB Configured maximum OS memory usage: %d kB\n",
+ (pages_allocated * _MALI_OSK_CPU_PAGE_SIZE)/1024, (info->num_pages_max* _MALI_OSK_CPU_PAGE_SIZE)/1024));
+
+ while(pages_allocated)
+ {
+ pages_allocated--;
+ if ( !is_cached )
+ {
+ dma_unmap_page(NULL, descriptor->block_array[pages_allocated].addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ }
+ __free_page(pfn_to_page(descriptor->block_array[pages_allocated].addr >> PAGE_SHIFT) );
+ }
+
+ up(&info->mutex);
+
+ return 0; /* failure */
+ }
+
+ info->num_pages_allocated += pages_allocated;
+
+ DBG_MSG(6, ("%d out of %d pages now allocated\n", info->num_pages_allocated, info->num_pages_max));
+
+ up(&info->mutex);
+
+ return 1; /* success*/
+}
+
+
+/*
+ * Free specified UMP memory
+ */
+static void os_free(void* ctx, ump_dd_mem * descriptor)
+{
+ os_allocator * info;
+ int i;
+
+ BUG_ON(!ctx);
+ BUG_ON(!descriptor);
+
+ info = (os_allocator*)ctx;
+
+ BUG_ON(descriptor->nr_blocks > info->num_pages_allocated);
+
+ if (down_interruptible(&info->mutex))
+ {
+ DBG_MSG(1, ("Failed to get mutex in os_free\n"));
+ return;
+ }
+
+ DBG_MSG(5, ("Releasing %lu OS pages\n", descriptor->nr_blocks));
+
+ info->num_pages_allocated -= descriptor->nr_blocks;
+
+ up(&info->mutex);
+
+ for ( i = 0; i < descriptor->nr_blocks; i++)
+ {
+ DBG_MSG(6, ("Freeing physical page. Address: 0x%08lx\n", descriptor->block_array[i].addr));
+ if ( ! descriptor->is_cached)
+ {
+ dma_unmap_page(NULL, descriptor->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL);
+ }
+ __free_page(pfn_to_page(descriptor->block_array[i].addr>>PAGE_SHIFT) );
+ }
+
+ vfree(descriptor->block_array);
+}
+
+
+static u32 os_stat(struct ump_memory_backend *backend)
+{
+ os_allocator *info;
+ info = (os_allocator*)backend->ctx;
+ return info->num_pages_allocated * _MALI_OSK_MALI_PAGE_SIZE;
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.h
new file mode 100644
index 0000000..f924705
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_kernel_memory_backend_os.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_kernel_memory_backend_os.h
+ */
+
+#ifndef __UMP_KERNEL_MEMORY_BACKEND_OS_H__
+#define __UMP_KERNEL_MEMORY_BACKEND_OS_H__
+
+#include "ump_kernel_memory_backend.h"
+
+ump_memory_backend * ump_os_memory_backend_create(const int max_allocation);
+
+#endif /* __UMP_KERNEL_MEMORY_BACKEND_OS_H__ */
+
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c
new file mode 100644
index 0000000..fd1f555
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_memory_backend.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <linux/module.h> /* kernel module definitions */
+#include <linux/ioport.h> /* request_mem_region */
+
+#include "arch/config.h" /* Configuration for current platform. The symlink for arch is set by Makefile */
+
+#include "ump_osk.h"
+#include "ump_kernel_common.h"
+#include "ump_kernel_memory_backend_os.h"
+#include "ump_kernel_memory_backend_dedicated.h"
+
+/* Configure which dynamic memory allocator to use */
+int ump_backend = ARCH_UMP_BACKEND_DEFAULT;
+module_param(ump_backend, int, S_IRUGO); /* r--r--r-- */
+MODULE_PARM_DESC(ump_backend, "0 = dedicated memory backend (default), 1 = OS memory backend");
+
+/* The base address of the memory block for the dedicated memory backend */
+unsigned int ump_memory_address = ARCH_UMP_MEMORY_ADDRESS_DEFAULT;
+module_param(ump_memory_address, uint, S_IRUGO); /* r--r--r-- */
+MODULE_PARM_DESC(ump_memory_address, "The physical address to map for the dedicated memory backend");
+
+/* The size of the memory block for the dedicated memory backend */
+unsigned int ump_memory_size = ARCH_UMP_MEMORY_SIZE_DEFAULT;
+module_param(ump_memory_size, uint, S_IRUGO); /* r--r--r-- */
+MODULE_PARM_DESC(ump_memory_size, "The size of fixed memory to map in the dedicated memory backend");
+
+ump_memory_backend* ump_memory_backend_create ( void )
+{
+ ump_memory_backend * backend = NULL;
+
+ /* Create the dynamic memory allocator backend */
+ if (0 == ump_backend)
+ {
+ DBG_MSG(2, ("Using dedicated memory backend\n"));
+
+ DBG_MSG(2, ("Requesting dedicated memory: 0x%08x, size: %u\n", ump_memory_address, ump_memory_size));
+ /* Ask the OS if we can use the specified physical memory */
+ if (NULL == request_mem_region(ump_memory_address, ump_memory_size, "UMP Memory"))
+ {
+ MSG_ERR(("Failed to request memory region (0x%08X - 0x%08X). Is Mali DD already loaded?\n", ump_memory_address, ump_memory_address + ump_memory_size - 1));
+ return NULL;
+ }
+ backend = ump_block_allocator_create(ump_memory_address, ump_memory_size);
+ }
+ else if (1 == ump_backend)
+ {
+ DBG_MSG(2, ("Using OS memory backend, allocation limit: %d\n", ump_memory_size));
+ backend = ump_os_memory_backend_create(ump_memory_size);
+ }
+/* MALI_SEC */
+#ifdef CONFIG_UMP_VCM_ALLOC
+ else if (2 == ump_backend)
+ {
+ DBG_MSG(2, ("Using VCM memory backend, allocation limit: %d\n", ump_memory_size));
+ backend = ump_vcm_memory_backend_create(ump_memory_size);
+ }
+#endif
+
+ return backend;
+}
+
+void ump_memory_backend_destroy( void )
+{
+ if (0 == ump_backend)
+ {
+ DBG_MSG(2, ("Releasing dedicated memory: 0x%08x\n", ump_memory_address));
+ release_mem_region(ump_memory_address, ump_memory_size);
+ }
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c
new file mode 100644
index 0000000..ef1902e
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_atomics.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_osk_atomics.c
+ * Implementation of the OS abstraction layer for the UMP kernel device driver
+ */
+
+#include "ump_osk.h"
+#include <asm/atomic.h>
+
+int _ump_osk_atomic_dec_and_read( _mali_osk_atomic_t *atom )
+{
+ return atomic_dec_return((atomic_t *)&atom->u.val);
+}
+
+int _ump_osk_atomic_inc_and_read( _mali_osk_atomic_t *atom )
+{
+ return atomic_inc_return((atomic_t *)&atom->u.val);
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c
new file mode 100644
index 0000000..5fd85a6
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_low_level_mem.c
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_osk_memory.c
+ * Implementation of the OS abstraction layer for the kernel device driver
+ */
+
+/* needed to detect kernel version specific code */
+#include <linux/version.h>
+
+#include "ump_osk.h"
+#include "ump_uk_types.h"
+#include "ump_ukk.h"
+#include "ump_kernel_common.h"
+#include <linux/module.h> /* kernel module definitions */
+#include <linux/kernel.h>
+#include <linux/mm.h>
+/* MALI_SEC */
+#include <linux/sched.h>
+#include <linux/slab.h>
+
+#include <asm/memory.h>
+#include <asm/uaccess.h> /* to verify pointers from user space */
+#include <asm/cacheflush.h>
+#include <linux/dma-mapping.h>
+
+typedef struct ump_vma_usage_tracker
+{
+ atomic_t references;
+ ump_memory_allocation *descriptor;
+} ump_vma_usage_tracker;
+
+static void ump_vma_open(struct vm_area_struct * vma);
+static void ump_vma_close(struct vm_area_struct * vma);
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf);
+#else
+static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address);
+#endif
+
+static struct vm_operations_struct ump_vm_ops =
+{
+ .open = ump_vma_open,
+ .close = ump_vma_close,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ .fault = ump_cpu_page_fault_handler
+#else
+ .nopfn = ump_cpu_page_fault_handler
+#endif
+};
+
+/*
+ * Page fault for VMA region
+ * This should never happen since we always map in the entire virtual memory range.
+ */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+static int ump_cpu_page_fault_handler(struct vm_area_struct *vma, struct vm_fault *vmf)
+#else
+static unsigned long ump_cpu_page_fault_handler(struct vm_area_struct * vma, unsigned long address)
+#endif
+{
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ void __user * address;
+ address = vmf->virtual_address;
+#endif
+ MSG_ERR(("Page-fault in UMP memory region caused by the CPU\n"));
+ MSG_ERR(("VMA: 0x%08lx, virtual address: 0x%08lx\n", (unsigned long)vma, address));
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ return VM_FAULT_SIGBUS;
+#else
+ return NOPFN_SIGBUS;
+#endif
+}
+
+static void ump_vma_open(struct vm_area_struct * vma)
+{
+ ump_vma_usage_tracker * vma_usage_tracker;
+ int new_val;
+
+ vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data;
+ BUG_ON(NULL == vma_usage_tracker);
+
+ new_val = atomic_inc_return(&vma_usage_tracker->references);
+
+ DBG_MSG(4, ("VMA open, VMA reference count incremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val));
+}
+
+static void ump_vma_close(struct vm_area_struct * vma)
+{
+ ump_vma_usage_tracker * vma_usage_tracker;
+ _ump_uk_unmap_mem_s args;
+ int new_val;
+
+ vma_usage_tracker = (ump_vma_usage_tracker*)vma->vm_private_data;
+ BUG_ON(NULL == vma_usage_tracker);
+
+ new_val = atomic_dec_return(&vma_usage_tracker->references);
+
+ DBG_MSG(4, ("VMA close, VMA reference count decremented. VMA: 0x%08lx, reference count: %d\n", (unsigned long)vma, new_val));
+
+ if (0 == new_val)
+ {
+ ump_memory_allocation * descriptor;
+
+ descriptor = vma_usage_tracker->descriptor;
+
+ args.ctx = descriptor->ump_session;
+ args.cookie = descriptor->cookie;
+ args.mapping = descriptor->mapping;
+ args.size = descriptor->size;
+
+ args._ukk_private = NULL; /** @note unused */
+
+ DBG_MSG(4, ("No more VMA references left, releasing UMP memory\n"));
+ _ump_ukk_unmap_mem( & args );
+
+ /* vma_usage_tracker is free()d by _ump_osk_mem_mapregion_term() */
+ }
+}
+
+_mali_osk_errcode_t _ump_osk_mem_mapregion_init( ump_memory_allocation * descriptor )
+{
+ ump_vma_usage_tracker * vma_usage_tracker;
+ struct vm_area_struct *vma;
+
+ if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
+
+ vma_usage_tracker = kmalloc(sizeof(ump_vma_usage_tracker), GFP_KERNEL);
+ if (NULL == vma_usage_tracker)
+ {
+ DBG_MSG(1, ("Failed to allocate memory for ump_vma_usage_tracker in _mali_osk_mem_mapregion_init\n"));
+ return -_MALI_OSK_ERR_FAULT;
+ }
+
+ vma = (struct vm_area_struct*)descriptor->process_mapping_info;
+ if (NULL == vma )
+ {
+ kfree(vma_usage_tracker);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ vma->vm_private_data = vma_usage_tracker;
+ vma->vm_flags |= VM_IO;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
+ vma->vm_flags |= VM_RESERVED;
+#else
+ vma->vm_flags |= VM_DONTDUMP;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_flags |= VM_PFNMAP;
+#endif
+
+
+ if (0==descriptor->is_cached)
+ {
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+ }
+ DBG_MSG(3, ("Mapping with page_prot: 0x%x\n", vma->vm_page_prot ));
+
+ /* Setup the functions which handle further VMA handling */
+ vma->vm_ops = &ump_vm_ops;
+
+ /* Do the va range allocation - in this case, it was done earlier, so we copy in that information */
+ descriptor->mapping = (void __user*)vma->vm_start;
+
+ atomic_set(&vma_usage_tracker->references, 1); /*this can later be increased if process is forked, see ump_vma_open() */
+ vma_usage_tracker->descriptor = descriptor;
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor )
+{
+ struct vm_area_struct* vma;
+ ump_vma_usage_tracker * vma_usage_tracker;
+
+ if (NULL == descriptor) return;
+
+ /* Linux does the right thing as part of munmap to remove the mapping
+ * All that remains is that we remove the vma_usage_tracker setup in init() */
+ vma = (struct vm_area_struct*)descriptor->process_mapping_info;
+
+ vma_usage_tracker = vma->vm_private_data;
+
+ /* We only get called if mem_mapregion_init succeeded */
+ kfree(vma_usage_tracker);
+ return;
+}
+
+_mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descriptor, u32 offset, u32 * phys_addr, unsigned long size )
+{
+ struct vm_area_struct *vma;
+ _mali_osk_errcode_t retval;
+
+ if (NULL == descriptor) return _MALI_OSK_ERR_FAULT;
+
+ vma = (struct vm_area_struct*)descriptor->process_mapping_info;
+
+ if (NULL == vma ) return _MALI_OSK_ERR_FAULT;
+
+ retval = remap_pfn_range( vma, ((u32)descriptor->mapping) + offset, (*phys_addr) >> PAGE_SHIFT, size, vma->vm_page_prot) ? _MALI_OSK_ERR_FAULT : _MALI_OSK_ERR_OK;;
+
+ DBG_MSG(4, ("Mapping virtual to physical memory. ID: %u, vma: 0x%08lx, virtual addr:0x%08lx, physical addr: 0x%08lx, size:%lu, prot:0x%x, vm_flags:0x%x RETVAL: 0x%x\n",
+ ump_dd_secure_id_get(descriptor->handle),
+ (unsigned long)vma,
+ (unsigned long)(vma->vm_start + offset),
+ (unsigned long)*phys_addr,
+ size,
+ (unsigned int)vma->vm_page_prot, vma->vm_flags, retval));
+
+ return retval;
+}
+
+/* MALI_SEC */
+static u32 _ump_osk_virt_to_phys_start(ump_dd_mem * mem, u32 start, u32 address, int *index)
+{
+ int i;
+ u32 offset = address - start;
+ ump_dd_physical_block *block;
+ u32 sum = 0;
+
+ for (i=0; i<mem->nr_blocks; i++) {
+ block = &mem->block_array[i];
+ sum += block->size;
+ if (sum > offset) {
+ *index = i;
+ DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size)));
+ return (u32)block->addr + offset - (sum -block->size);
+ }
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+/* MALI_SEC */
+static u32 _ump_osk_virt_to_phys_end(ump_dd_mem * mem, u32 start, u32 address, int *index)
+{
+ int i;
+ u32 offset = address - start;
+ ump_dd_physical_block *block;
+ u32 sum = 0;
+
+ for (i=0; i<mem->nr_blocks; i++) {
+ block = &mem->block_array[i];
+ sum += block->size;
+ if (sum >= offset) {
+ *index = i;
+ DBG_MSG(3, ("_ump_osk_virt_to_phys : index : %d, virtual 0x%x, phys 0x%x\n", i, address, (u32)block->addr + offset - (sum -block->size)));
+ return (u32)block->addr + offset - (sum -block->size);
+ }
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+/* MALI_SEC */
+static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size)
+{
+ int start_index, end_index;
+ u32 start_p, end_p;
+
+ DBG_MSG(3, ("Cache flush with user virtual address. start : 0x%x, end : 0x%x, address 0x%x, size 0x%x\n", start, start+mem->size_bytes, address, size));
+
+ start_p = _ump_osk_virt_to_phys_start(mem, start, address, &start_index);
+ end_p = _ump_osk_virt_to_phys_end(mem, start, address+size, &end_index);
+
+ if (start_index==end_index) {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)
+ outer_flush_range(start_p, end_p);
+ else
+ outer_clean_range(start_p, end_p);
+ } else {
+ ump_dd_physical_block *block;
+ int i;
+
+ for (i=start_index; i<=end_index; i++) {
+ block = &mem->block_array[i];
+
+ if (i == start_index) {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
+ outer_flush_range(start_p, block->addr+block->size);
+ } else {
+ outer_clean_range(start_p, block->addr+block->size);
+ }
+ }
+ else if (i == end_index) {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
+ outer_flush_range(block->addr, end_p);
+ } else {
+ outer_clean_range(block->addr, end_p);
+ }
+ break;
+ }
+ else {
+ if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
+ outer_flush_range(block->addr, block->addr+block->size);
+ } else {
+ outer_clean_range(block->addr, block->addr+block->size);
+ }
+ }
+ }
+ }
+ return;
+}
+/* The end of MALI_SEC */
+
+static void level1_cache_flush_all(void)
+{
+ DBG_MSG(4, ("UMP[xx] Flushing complete L1 cache\n"));
+ __cpuc_flush_kern_all();
+}
+
+void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data )
+{
+ int i;
+ /* MALI_SEC */
+ const void *start_v, *end_v;
+
+ /* Flush L1 using virtual address, the entire range in one go.
+ * Only flush if user space process has a valid write mapping on given address. */
+ if( (mem) && (virt!=NULL) && (access_ok(VERIFY_WRITE, virt, size)) )
+ {
+ /* MALI_SEC */
+ start_v = (void *)virt;
+ end_v = (void *)(start_v + size - 1);
+ /* There is no dmac_clean_range, so the L1 is always flushed,
+ * also for UMP_MSYNC_CLEAN. */
+ if (size >= SZ_64K)
+ flush_all_cpu_caches();
+ else
+ dmac_flush_range(start_v, end_v);
+
+ /* MALI ORIGINAL CODE */
+ //__cpuc_flush_dcache_area(virt, size);
+
+ DBG_MSG(3, ("UMP[%02u] Flushing CPU L1 Cache. Cpu address: %x-%x\n", mem->secure_id, start_v,end_v));
+ }
+ else
+ {
+ if (session_data)
+ {
+ if (op == _UMP_UK_MSYNC_FLUSH_L1 )
+ {
+ DBG_MSG(4, ("UMP Pending L1 cache flushes: %d\n", session_data->has_pending_level1_cache_flush));
+ session_data->has_pending_level1_cache_flush = 0;
+ level1_cache_flush_all();
+ return;
+ }
+ else
+ {
+ if (session_data->cache_operations_ongoing)
+ {
+ session_data->has_pending_level1_cache_flush++;
+ DBG_MSG(4, ("UMP[%02u] Defering the L1 flush. Nr pending:%d\n", mem->secure_id, session_data->has_pending_level1_cache_flush) );
+ }
+ else
+ {
+ /* Flushing the L1 cache for each switch_user() if ump_cache_operations_control(START) is not called */
+ level1_cache_flush_all();
+ }
+ }
+ }
+ else
+ {
+ DBG_MSG(4, ("Unkown state %s %d\n", __FUNCTION__, __LINE__));
+ level1_cache_flush_all();
+ }
+ }
+
+ if ( NULL == mem ) return;
+
+ if ( mem->size_bytes==size)
+ {
+ DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache\n",mem->secure_id));
+ }
+ else
+ {
+ DBG_MSG(3, ("UMP[%02u] Flushing CPU L2 Cache. Blocks:%u, TotalSize:%u. FlushSize:%u Offset:0x%x FirstPaddr:0x%08x\n",
+ mem->secure_id, mem->nr_blocks, mem->size_bytes, size, offset, mem->block_array[0].addr));
+ }
+
+
+ /* Flush L2 using physical addresses, block for block. */
+ /* MALI_SEC */
+ if ((virt!=NULL) && (mem->size_bytes >= SZ_1M)) {
+ if (op == _UMP_UK_MSYNC_CLEAN)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)
+ outer_clean_all();
+#else
+ outer_sync();
+#endif
+ else if ((op == _UMP_UK_MSYNC_INVALIDATE) || (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE))
+ outer_flush_all();
+ return;
+ }
+
+ for (i=0 ; i < mem->nr_blocks; i++)
+ {
+ u32 start_p, end_p;
+ ump_dd_physical_block *block;
+ block = &mem->block_array[i];
+
+ if(offset >= block->size)
+ {
+ offset -= block->size;
+ continue;
+ }
+
+ if(offset)
+ {
+ start_p = (u32)block->addr + offset;
+ /* We'll zero the offset later, after using it to calculate end_p. */
+ }
+ else
+ {
+ start_p = (u32)block->addr;
+ }
+
+ if(size < block->size - offset)
+ {
+ end_p = start_p + size - 1;
+ size = 0;
+ }
+ else
+ {
+ if(offset)
+ {
+ end_p = start_p + (block->size - offset - 1);
+ size -= block->size - offset;
+ offset = 0;
+ }
+ else
+ {
+ end_p = start_p + block->size - 1;
+ size -= block->size;
+ }
+ }
+
+ switch(op)
+ {
+ case _UMP_UK_MSYNC_CLEAN:
+ outer_clean_range(start_p, end_p);
+ break;
+ case _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE:
+ outer_flush_range(start_p, end_p);
+ break;
+ case _UMP_UK_MSYNC_INVALIDATE:
+ outer_inv_range(start_p, end_p);
+ break;
+ default:
+ break;
+ }
+
+ if(0 == size)
+ {
+ /* Nothing left to flush. */
+ break;
+ }
+ }
+
+ return;
+}
+
+/* MALI_SEC */
+void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ ump_vma_usage_tracker * vma_usage_tracker;
+ ump_memory_allocation *descriptor;
+ ump_dd_handle handle;
+
+ DBG_MSG(3, ("_ump_osk_mem_mapregion_get: vaddr 0x%08lx\n", vaddr));
+
+ down_read(&mm->mmap_sem);
+ vma = find_vma(mm, vaddr);
+ up_read(&mm->mmap_sem);
+ if(!vma)
+ {
+ DBG_MSG(3, ("Not found VMA\n"));
+ *mem = NULL;
+ return;
+ }
+ DBG_MSG(4, ("Get vma: 0x%08lx vma->vm_start: 0x%08lx\n", (unsigned long)vma, vma->vm_start));
+
+ vma_usage_tracker = (struct ump_vma_usage_tracker*)vma->vm_private_data;
+ if(vma_usage_tracker == NULL)
+ {
+ DBG_MSG(3, ("Not found vma_usage_tracker\n"));
+ *mem = NULL;
+ return;
+ }
+
+ descriptor = (struct ump_memory_allocation*)vma_usage_tracker->descriptor;
+ handle = (ump_dd_handle)descriptor->handle;
+
+ DBG_MSG(3, ("Get handle: 0x%08lx\n", handle));
+ *mem = (ump_dd_mem*)handle;
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c
new file mode 100644
index 0000000..12066eb
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_osk_misc.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_osk_misc.c
+ * Implementation of the OS abstraction layer for the UMP kernel device driver
+ */
+
+
+#include "ump_osk.h"
+
+#include <linux/kernel.h>
+#include "ump_kernel_linux.h"
+
+/* is called from ump_kernel_constructor in common code */
+_mali_osk_errcode_t _ump_osk_init( void )
+{
+ if (0 != ump_kernel_device_initialize())
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t _ump_osk_term( void )
+{
+ ump_kernel_device_terminate();
+ return _MALI_OSK_ERR_OK;
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c
new file mode 100644
index 0000000..977db9a
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_ukk_wrappers.c
+ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation
+ */
+
+
+#include <asm/uaccess.h> /* user space access */
+
+#include "ump_osk.h"
+#include "ump_uk_types.h"
+#include "ump_ukk.h"
+#include "ump_kernel_common.h"
+
+/* MALI_SEC */
+#if defined(CONFIG_ION_EXYNOS) || defined(CONFIG_DMA_SHARED_BUFFER)
+#include <linux/scatterlist.h>
+#include "ump_kernel_interface_ref_drv.h"
+#include "mali_osk_list.h"
+#ifdef CONFIG_ION_EXYNOS
+#include <linux/ion.h>
+#include "../../../../gpu/ion/ion_priv.h"
+extern struct ion_device *ion_exynos;
+extern struct ion_client *ion_client_ump;
+#endif
+#ifdef CONFIG_DMA_SHARED_BUFFER
+#include <linux/dma-buf.h>
+#endif
+#endif
+
+/*
+ * IOCTL operation; Allocate UMP memory
+ */
+int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_allocate_s user_interaction;
+ _mali_osk_errcode_t err;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n"));
+ return -ENOTTY;
+ }
+
+ /* Copy the user space memory to kernel space (so we safely can read it) */
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ err = _ump_ukk_allocate( &user_interaction );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ DBG_MSG(1, ("_ump_ukk_allocate() failed in ump_ioctl_allocate()\n"));
+ return map_errcode(err);
+ }
+ user_interaction.ctx = NULL;
+
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */
+ _ump_uk_release_s release_args;
+
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n"));
+
+ release_args.ctx = (void *) session_data;
+ release_args.secure_id = user_interaction.secure_id;
+
+ err = _ump_ukk_release( &release_args );
+ if(_MALI_OSK_ERR_OK != err)
+ {
+ MSG_ERR(("_ump_ukk_release() also failed when trying to release newly allocated memory in ump_ioctl_allocate()\n"));
+ }
+
+ return -EFAULT;
+ }
+
+ return 0; /* success */
+}
+
+/* MALI_SEC */
+#ifdef CONFIG_ION_EXYNOS
+/*
+ * IOCTL operation; Import fd to UMP memory
+ */
+int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_ion_import_s user_interaction;
+ ump_dd_handle *ump_handle;
+ ump_dd_physical_block * blocks;
+ unsigned long num_blocks;
+ struct ion_handle *ion_hnd;
+ struct scatterlist *sg;
+ struct scatterlist *sg_ion;
+ unsigned long i = 0;
+
+ ump_session_memory_list_element * session_memory_element = NULL;
+ if (ion_client_ump==NULL)
+ ion_client_ump = ion_client_create(ion_exynos, -1, "ump");
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_allocate()\n"));
+ return -ENOTTY;
+ }
+
+ /* Copy the user space memory to kernel space (so we safely can read it) */
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_allocate()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ /* translate fd to secure ID*/
+ ion_hnd = ion_import_fd(ion_client_ump, user_interaction.ion_fd);
+ sg_ion = ion_map_dma(ion_client_ump,ion_hnd);
+
+ blocks = (ump_dd_physical_block*)_mali_osk_malloc(sizeof(ump_dd_physical_block)*1024);
+
+ if (NULL == blocks) {
+ MSG_ERR(("Failed to allocate blocks in ump_ioctl_allocate()\n"));
+ return -ENOMEM;
+ }
+
+ sg = sg_ion;
+ do {
+ blocks[i].addr = sg_phys(sg);
+ blocks[i].size = sg_dma_len(sg);
+ i++;
+ if (i>=1024) {
+ _mali_osk_free(blocks);
+ MSG_ERR(("ion_import fail() in ump_ioctl_allocate()\n"));
+ return -EFAULT;
+ }
+ sg = sg_next(sg);
+ } while(sg);
+
+ num_blocks = i;
+
+ /* Initialize the session_memory_element, and add it to the session object */
+ session_memory_element = _mali_osk_calloc( 1, sizeof(ump_session_memory_list_element));
+
+ if (NULL == session_memory_element)
+ {
+ _mali_osk_free(blocks);
+ DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n"));
+ return -EFAULT;
+ }
+
+ ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, num_blocks);
+ if (UMP_DD_HANDLE_INVALID == ump_handle)
+ {
+ _mali_osk_free(session_memory_element);
+ _mali_osk_free(blocks);
+ DBG_MSG(1, ("Failed to allocate ump_session_memory_list_element in ump_ioctl_allocate()\n"));
+ return -EFAULT;
+ }
+
+ session_memory_element->mem = (ump_dd_mem*)ump_handle;
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_add(&(session_memory_element->list), &(session_data->list_head_session_memory_list));
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ ion_unmap_dma(ion_client_ump,ion_hnd);
+ ion_free(ion_client_ump, ion_hnd);
+
+ _mali_osk_free(blocks);
+
+ user_interaction.secure_id = ump_dd_secure_id_get(ump_handle);
+ user_interaction.size = ump_dd_size_get(ump_handle);
+ user_interaction.ctx = NULL;
+
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ /* If the copy fails then we should release the memory. We can use the IOCTL release to accomplish this */
+
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_allocate()\n"));
+
+ return -EFAULT;
+ }
+ return 0; /* success */
+}
+#endif
+
+#ifdef CONFIG_DMA_SHARED_BUFFER
+int ump_dmabuf_import_wrapper(u32 __user *argument,
+ struct ump_session_data *session_data)
+{
+ ump_session_memory_list_element *session = NULL;
+ struct ump_uk_dmabuf ump_dmabuf;
+ ump_dd_handle *ump_handle;
+ ump_dd_physical_block *blocks;
+ struct dma_buf_attachment *attach;
+ struct dma_buf *dma_buf;
+ struct sg_table *sgt;
+ struct scatterlist *sgl;
+ unsigned long block_size;
+ /* FIXME */
+ struct device dev;
+ unsigned int i = 0, npages;
+ int ret;
+
+ /* Sanity check input parameters */
+ if (!argument || !session_data) {
+ MSG_ERR(("NULL parameter.\n"));
+ return -EINVAL;
+ }
+
+ if (copy_from_user(&ump_dmabuf, argument,
+ sizeof(struct ump_uk_dmabuf))) {
+ MSG_ERR(("copy_from_user() failed.\n"));
+ return -EFAULT;
+ }
+
+ dma_buf = dma_buf_get(ump_dmabuf.fd);
+ if (IS_ERR(dma_buf))
+ return PTR_ERR(dma_buf);
+
+ /*
+ * check whether dma_buf imported already exists or not.
+ *
+ * TODO
+ * if already imported then dma_buf_put() should be called
+ * and then just return dma_buf imported.
+ */
+
+ attach = dma_buf_attach(dma_buf, &dev);
+ if (IS_ERR(attach)) {
+ ret = PTR_ERR(attach);
+ goto err_dma_buf_put;
+ }
+
+ sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sgt)) {
+ ret = PTR_ERR(sgt);
+ goto err_dma_buf_detach;
+ }
+
+ npages = sgt->nents;
+
+ /* really need? */
+ ump_dmabuf.ctx = (void *)session_data;
+
+ block_size = sizeof(ump_dd_physical_block) * npages;
+
+ blocks = (ump_dd_physical_block *)_mali_osk_malloc(block_size);
+
+ if (NULL == blocks) {
+ MSG_ERR(("Failed to allocate blocks\n"));
+ ret = -ENOMEM;
+ goto err_dmu_buf_unmap;
+ }
+
+ sgl = sgt->sgl;
+
+ while (i < npages) {
+ blocks[i].addr = sg_phys(sgl);
+ blocks[i].size = sg_dma_len(sgl);
+ sgl = sg_next(sgl);
+ i++;
+ }
+
+ /*
+ * Initialize the session memory list element, and add it
+ * to the session object
+ */
+ session = _mali_osk_calloc(1, sizeof(*session));
+ if (!session) {
+ DBG_MSG(1, ("Failed to allocate session.\n"));
+ ret = -EFAULT;
+ goto err_free_block;
+ }
+
+ ump_handle = ump_dd_handle_create_from_phys_blocks(blocks, i);
+ if (UMP_DD_HANDLE_INVALID == ump_handle) {
+ DBG_MSG(1, ("Failed to create ump handle.\n"));
+ ret = -EFAULT;
+ goto err_free_session;
+ }
+
+ session->mem = (ump_dd_mem *)ump_handle;
+
+ _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+ _mali_osk_list_add(&(session->list),
+ &(session_data->list_head_session_memory_list));
+ _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
+
+ _mali_osk_free(blocks);
+
+ ump_dmabuf.ump_handle = (uint32_t)ump_handle;
+ ump_dmabuf.size = ump_dd_size_get(ump_handle);
+
+ if (copy_to_user(argument, &ump_dmabuf,
+ sizeof(struct ump_uk_dmabuf))) {
+ MSG_ERR(("copy_to_user() failed.\n"));
+ ret = -EFAULT;
+ goto err_release_ump_handle;
+ }
+
+ return 0;
+
+err_release_ump_handle:
+ ump_dd_reference_release(ump_handle);
+err_free_session:
+ _mali_osk_free(session);
+err_free_block:
+ _mali_osk_free(blocks);
+err_dmu_buf_unmap:
+ dma_buf_unmap_attachment(attach, sgt, DMA_BIDIRECTIONAL);
+err_dma_buf_detach:
+ dma_buf_detach(dma_buf, attach);
+err_dma_buf_put:
+ dma_buf_put(dma_buf);
+ return ret;
+}
+#endif
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.h
new file mode 100644
index 0000000..63ee98c
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_ref_wrappers.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2010 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_ukk_wrappers.h
+ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls for the reference implementation
+ */
+
+#ifndef __UMP_UKK_REF_WRAPPERS_H__
+#define __UMP_UKK_REF_WRAPPERS_H__
+
+#include <linux/kernel.h>
+#include "ump_kernel_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+int ump_allocate_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+
+/* MALI_SEC */
+#ifdef CONFIG_ION_EXYNOS
+int ump_ion_import_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+#endif
+/* MALI_SEC */
+#ifdef CONFIG_DMA_SHARED_BUFFER
+int ump_dmabuf_import_wrapper(u32 __user *argument,
+ struct ump_session_data *session_data);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __UMP_UKK_REF_WRAPPERS_H__ */
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c
new file mode 100644
index 0000000..780f311
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2010-2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_ukk_wrappers.c
+ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls
+ */
+
+#include <asm/uaccess.h> /* user space access */
+
+#include "ump_osk.h"
+#include "ump_uk_types.h"
+#include "ump_ukk.h"
+#include "ump_kernel_common.h"
+
+/*
+ * IOCTL operation; Negotiate version of IOCTL API
+ */
+int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_api_version_s version_info;
+ _mali_osk_errcode_t err;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_get_api_version()\n"));
+ return -ENOTTY;
+ }
+
+ /* Copy the user space memory to kernel space (so we safely can read it) */
+ if (0 != copy_from_user(&version_info, argument, sizeof(version_info)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n"));
+ return -EFAULT;
+ }
+
+ version_info.ctx = (void*) session_data;
+ err = _ump_uku_get_api_version( &version_info );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ MSG_ERR(("_ump_uku_get_api_version() failed in ump_ioctl_get_api_version()\n"));
+ return map_errcode(err);
+ }
+
+ version_info.ctx = NULL;
+
+ /* Copy ouput data back to user space */
+ if (0 != copy_to_user(argument, &version_info, sizeof(version_info)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_get_api_version()\n"));
+ return -EFAULT;
+ }
+
+ return 0; /* success */
+}
+
+
+/*
+ * IOCTL operation; Release reference to specified UMP memory.
+ */
+int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_release_s release_args;
+ _mali_osk_errcode_t err;
+
+ /* Sanity check input parameters */
+ if (NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_release()\n"));
+ return -ENOTTY;
+ }
+
+ /* Copy the user space memory to kernel space (so we safely can read it) */
+ if (0 != copy_from_user(&release_args, argument, sizeof(release_args)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_get_api_version()\n"));
+ return -EFAULT;
+ }
+
+ release_args.ctx = (void*) session_data;
+ err = _ump_ukk_release( &release_args );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ MSG_ERR(("_ump_ukk_release() failed in ump_ioctl_release()\n"));
+ return map_errcode(err);
+ }
+
+
+ return 0; /* success */
+}
+
+/*
+ * IOCTL operation; Return size for specified UMP memory.
+ */
+int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_size_get_s user_interaction;
+ _mali_osk_errcode_t err;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_size_get()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+ err = _ump_ukk_size_get( &user_interaction );
+ if( _MALI_OSK_ERR_OK != err )
+ {
+ MSG_ERR(("_ump_ukk_size_get() failed in ump_ioctl_size_get()\n"));
+ return map_errcode(err);
+ }
+
+ user_interaction.ctx = NULL;
+
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_size_get()\n"));
+ return -EFAULT;
+ }
+
+ return 0; /* success */
+}
+
+/*
+ * IOCTL operation; Do cache maintenance on specified UMP memory.
+ */
+int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_msync_s user_interaction;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_msync()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ _ump_ukk_msync( &user_interaction );
+
+ user_interaction.ctx = NULL;
+
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_msync()\n"));
+ return -EFAULT;
+ }
+
+ return 0; /* success */
+}
+int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_cache_operations_control_s user_interaction;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_cache_operations_control()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ _ump_ukk_cache_operations_control((_ump_uk_cache_operations_control_s*) &user_interaction );
+
+ user_interaction.ctx = NULL;
+
+#if 0 /* No data to copy back */
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_cache_operations_control()\n"));
+ return -EFAULT;
+ }
+#endif
+ return 0; /* success */
+}
+
+int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_switch_hw_usage_s user_interaction;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ _ump_ukk_switch_hw_usage( &user_interaction );
+
+ user_interaction.ctx = NULL;
+
+#if 0 /* No data to copy back */
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n"));
+ return -EFAULT;
+ }
+#endif
+ return 0; /* success */
+}
+
+int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_lock_s user_interaction;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ _ump_ukk_lock( &user_interaction );
+
+ user_interaction.ctx = NULL;
+
+#if 0 /* No data to copy back */
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n"));
+ return -EFAULT;
+ }
+#endif
+
+ return 0; /* success */
+}
+
+int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+{
+ _ump_uk_unlock_s user_interaction;
+
+ /* Sanity check input parameters */
+ if (NULL == argument || NULL == session_data)
+ {
+ MSG_ERR(("NULL parameter in ump_ioctl_size_get()\n"));
+ return -ENOTTY;
+ }
+
+ if (0 != copy_from_user(&user_interaction, argument, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_from_user() in ump_ioctl_switch_hw_usage()\n"));
+ return -EFAULT;
+ }
+
+ user_interaction.ctx = (void *) session_data;
+
+ _ump_ukk_unlock( &user_interaction );
+
+ user_interaction.ctx = NULL;
+
+#if 0 /* No data to copy back */
+ if (0 != copy_to_user(argument, &user_interaction, sizeof(user_interaction)))
+ {
+ MSG_ERR(("copy_to_user() failed in ump_ioctl_switch_hw_usage()\n"));
+ return -EFAULT;
+ }
+#endif
+
+ return 0; /* success */
+}
diff --git a/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h
new file mode 100644
index 0000000..e87a903
--- /dev/null
+++ b/drivers/gpu/mali400/r3p2/ump/linux/ump_ukk_wrappers.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2010, 2012 ARM Limited. All rights reserved.
+ *
+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence.
+ *
+ * A copy of the licence is included with the program, and can also be obtained from Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * @file ump_ukk_wrappers.h
+ * Defines the wrapper functions which turn Linux IOCTL calls into _ukk_ calls
+ */
+
+#ifndef __UMP_UKK_WRAPPERS_H__
+#define __UMP_UKK_WRAPPERS_H__
+
+#include <linux/kernel.h>
+#include "ump_kernel_common.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+
+int ump_get_api_version_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_release_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_cache_operations_control_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_switch_hw_usage_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_lock_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+int ump_unlock_wrapper(u32 __user * argument, struct ump_session_data * session_data);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif /* __UMP_UKK_WRAPPERS_H__ */
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 6c03331..61e680e 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -563,6 +563,11 @@ config KEYBOARD_W90P910
To compile this driver as a module, choose M here: the
module will be called w90p910_keypad.
+config SENSORS_HALL
+ tristate "HALL"
+ help
+ Say Y here to enable the HALL.
+
source "drivers/input/keyboard/cypress/Kconfig"
endif
diff --git a/drivers/input/keyboard/cypress/cypress-touchkey.c b/drivers/input/keyboard/cypress/cypress-touchkey.c
index 6ccd693..8aafaad 100644
--- a/drivers/input/keyboard/cypress/cypress-touchkey.c
+++ b/drivers/input/keyboard/cypress/cypress-touchkey.c
@@ -37,8 +37,6 @@
#include <linux/regulator/machine.h>
#include "issp_extern.h"
-#include "cypress-touchkey.h"
-
#ifdef CONFIG_TOUCHSCREEN_ATMEL_MXT540E
#include <linux/i2c/mxt540e.h>
#else
@@ -78,11 +76,6 @@ static int touchkey_keycode[] = { 0,
};
static const int touchkey_count = sizeof(touchkey_keycode) / sizeof(int);
-struct touchkey_i2c *tkey_i2c_local;
-struct timer_list touch_led_timer;
-int touch_led_timeout = 3; // timeout for the touchkey backlight in secs
-int touch_led_disabled = 0; // 1= force disable the touchkey backlight
-
#if defined(TK_HAS_AUTOCAL)
static u16 raw_data0;
static u16 raw_data1;
@@ -115,8 +108,8 @@ static bool g_debug_tkey = FALSE;
static int touchkey_i2c_check(struct touchkey_i2c *tkey_i2c);
-static u8 menu_sensitivity;
-static u8 back_sensitivity;
+static u16 menu_sensitivity;
+static u16 back_sensitivity;
#if defined(TK_USE_4KEY)
static u8 home_sensitivity;
static u8 search_sensitivity;
@@ -161,10 +154,10 @@ static ssize_t brightness_control(struct device *dev,
int data;
if (sscanf(buf, "%d\n", &data) == 1) {
- pr_err("[TouchKey] touch_led_brightness: %d\n", data);
+ printk(KERN_ERR "[TouchKey] touch_led_brightness: %d\n", data);
change_touch_key_led_voltage(data);
} else {
- pr_err("[TouchKey] touch_led_brightness Error\n");
+ printk(KERN_ERR "[TouchKey] touch_led_brightness Error\n");
}
return size;
@@ -191,7 +184,7 @@ static int i2c_touchkey_read(struct i2c_client *client,
if ((client == NULL) || !(touchkey_enable == 1)
|| !touchkey_probe) {
- pr_err("[TouchKey] touchkey is not enabled. %d\n",
+ printk(KERN_ERR "[TouchKey] touchkey is not enabled. %d\n",
__LINE__);
return -ENODEV;
}
@@ -210,7 +203,7 @@ static int i2c_touchkey_read(struct i2c_client *client,
if (err >= 0)
return 0;
- pr_err("[TouchKey] %s %d i2c transfer error\n",
+ printk(KERN_ERR "[TouchKey] %s %d i2c transfer error\n",
__func__, __LINE__);
mdelay(10);
}
@@ -229,7 +222,7 @@ static int i2c_touchkey_write(struct i2c_client *client,
if ((client == NULL) || !(touchkey_enable == 1)
|| !touchkey_probe) {
- pr_err("[TouchKey] touchkey is not enabled. %d\n",
+ printk(KERN_ERR "[TouchKey] touchkey is not enabled. %d\n",
__LINE__);
return -ENODEV;
}
@@ -249,7 +242,7 @@ static int i2c_touchkey_write(struct i2c_client *client,
if (err >= 0)
return 0;
- pr_debug("[TouchKey] %s %d i2c transfer error\n",
+ printk(KERN_DEBUG "[TouchKey] %s %d i2c transfer error\n",
__func__, __LINE__);
mdelay(10);
}
@@ -272,10 +265,11 @@ static int touchkey_autocalibration(struct touchkey_i2c *tkey_i2c)
while (retry < 3) {
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 4);
if (ret < 0) {
- pr_err("[TouchKey]i2c read fail.\n");
+ printk(KERN_ERR "[TouchKey]i2c read fail.\n");
return ret;
}
- pr_debug("[TouchKey] data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
+ printk(KERN_DEBUG
+ "[TouchKey] data[0]=%x data[1]=%x data[2]=%x data[3]=%x\n",
data[0], data[1], data[2], data[3]);
/* Send autocal Command */
@@ -290,23 +284,24 @@ static int touchkey_autocalibration(struct touchkey_i2c *tkey_i2c)
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 6);
if ((data[5] & TK_BIT_AUTOCAL)) {
- pr_debug("[Touchkey] autocal Enabled\n");
+ printk(KERN_DEBUG "[Touchkey] autocal Enabled\n");
break;
} else
- pr_debug("[Touchkey] autocal disabled, retry %d\n",
+ printk(KERN_DEBUG
+ "[Touchkey] autocal disabled, retry %d\n",
retry);
retry = retry + 1;
}
if (retry == 3)
- pr_debug("[Touchkey] autocal failed\n");
+ printk(KERN_DEBUG "[Touchkey] autocal failed\n");
return count;
}
#endif
-#if 0 /* CONFIG_TARGET_LOCALE_NAATT */
+#ifdef CONFIG_TARGET_LOCALE_NAATT
static ssize_t set_touchkey_autocal_testmode(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
@@ -317,7 +312,7 @@ static ssize_t set_touchkey_autocal_testmode(struct device *dev,
int on_off;
if (sscanf(buf, "%d\n", &on_off) == 1) {
- pr_err("[TouchKey] Test Mode : %d\n", on_off);
+ printk(KERN_ERR "[TouchKey] Test Mode : %d\n", on_off);
if (on_off == 1) {
set_data = 0x40;
@@ -329,11 +324,11 @@ static ssize_t set_touchkey_autocal_testmode(struct device *dev,
tkey_i2c->pdata->power_on(1);
msleep(50);
#if defined(TK_HAS_AUTOCAL)
- touchkey_autocalibration();
+ touchkey_autocalibration(tkey_i2c);
#endif
}
} else {
- pr_err("[TouchKey] touch_led_brightness Error\n");
+ printk(KERN_ERR "[TouchKey] touch_led_brightness Error\n");
}
return count;
@@ -348,24 +343,24 @@ static ssize_t touchkey_raw_data0_show(struct device *dev,
u8 data[26] = { 0, };
int ret;
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 26);
#if defined(CONFIG_TARGET_LOCALE_NA)
- pr_debug("called %s data[18] =%d,data[19] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[18] =%d,data[19] = %d\n", __func__,
data[18], data[19]);
raw_data0 = ((0x00FF & data[18]) << 8) | data[19];
#elif defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1)\
|| defined(CONFIG_MACH_M3)\
|| defined(CONFIG_MACH_T0)
- pr_debug("called %s data[16] =%d,data[17] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[16] =%d,data[17] = %d\n", __func__,
data[16], data[17]);
raw_data0 = ((0x00FF & data[16]) << 8) | data[17]; /* menu*/
#elif defined(CONFIG_MACH_Q1_BD)
- pr_debug("called %s data[16] =%d,data[17] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[16] =%d,data[17] = %d\n", __func__,
data[16], data[17]);
raw_data0 = ((0x00FF & data[14]) << 8) | data[15];
#else
- pr_debug("called %s data[18] =%d,data[19] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[18] =%d,data[19] = %d\n", __func__,
data[10], data[11]);
raw_data0 = ((0x00FF & data[10]) << 8) | data[11];
#endif
@@ -379,24 +374,24 @@ static ssize_t touchkey_raw_data1_show(struct device *dev,
u8 data[26] = { 0, };
int ret;
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 26);
#if defined(CONFIG_TARGET_LOCALE_NA)
- pr_debug("called %s data[20] =%d,data[21] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[20] =%d,data[21] = %d\n", __func__,
data[20], data[21]);
raw_data1 = ((0x00FF & data[20]) << 8) | data[21];
#elif defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1)\
|| defined(CONFIG_MACH_M3)\
|| defined(CONFIG_MACH_T0)
- pr_debug("called %s data[14] =%d,data[15] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[14] =%d,data[15] = %d\n", __func__,
data[14], data[15]);
raw_data1 = ((0x00FF & data[14]) << 8) | data[15]; /*back*/
#elif defined(CONFIG_MACH_Q1_BD)
- pr_debug("called %s data[14] =%d,data[15] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[14] =%d,data[15] = %d\n", __func__,
data[14], data[15]);
raw_data1 = ((0x00FF & data[16]) << 8) | data[17];
#else
- pr_debug("called %s data[20] =%d,data[21] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[20] =%d,data[21] = %d\n", __func__,
data[12], data[13]);
raw_data1 = ((0x00FF & data[12]) << 8) | data[13];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -410,14 +405,14 @@ static ssize_t touchkey_raw_data2_show(struct device *dev,
u8 data[26] = { 0, };
int ret;
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 26);
#if defined(CONFIG_TARGET_LOCALE_NA)
- pr_debug("called %s data[22] =%d,data[23] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[22] =%d,data[23] = %d\n", __func__,
data[22], data[23]);
raw_data2 = ((0x00FF & data[22]) << 8) | data[23];
#else
- pr_debug("called %s data[22] =%d,data[23] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[22] =%d,data[23] = %d\n", __func__,
data[14], data[15]);
raw_data2 = ((0x00FF & data[14]) << 8) | data[15];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -431,14 +426,14 @@ static ssize_t touchkey_raw_data3_show(struct device *dev,
u8 data[26] = { 0, };
int ret;
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 26);
#if defined(CONFIG_TARGET_LOCALE_NA)
- pr_debug("called %s data[24] =%d,data[25] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[24] =%d,data[25] = %d\n", __func__,
data[24], data[25]);
raw_data3 = ((0x00FF & data[24]) << 8) | data[25];
#else
- pr_debug("called %s data[24] =%d,data[25] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[24] =%d,data[25] = %d\n", __func__,
data[16], data[17]);
raw_data3 = ((0x00FF & data[16]) << 8) | data[17];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -456,9 +451,9 @@ static ssize_t touchkey_idac0_show(struct device *dev,
return 0;
#endif
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
- pr_debug("called %s data[6] =%d\n", __func__, data[6]);
+ printk(KERN_DEBUG "called %s data[6] =%d\n", __func__, data[6]);
idac0 = data[6];
return sprintf(buf, "%d\n", idac0);
}
@@ -474,9 +469,9 @@ static ssize_t touchkey_idac1_show(struct device *dev,
return 0;
#endif
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
- pr_debug("called %s data[7] = %d\n", __func__, data[7]);
+ printk(KERN_DEBUG "called %s data[7] = %d\n", __func__, data[7]);
idac1 = data[7];
return sprintf(buf, "%d\n", idac1);
}
@@ -492,9 +487,9 @@ static ssize_t touchkey_idac2_show(struct device *dev,
return 0;
#endif
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
- pr_debug("called %s data[8] =%d\n", __func__, data[8]);
+ printk(KERN_DEBUG "called %s data[8] =%d\n", __func__, data[8]);
idac2 = data[8];
return sprintf(buf, "%d\n", idac2);
}
@@ -510,9 +505,9 @@ static ssize_t touchkey_idac3_show(struct device *dev,
return 0;
#endif
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
- pr_debug("called %s data[9] = %d\n", __func__, data[9]);
+ printk(KERN_DEBUG "called %s data[9] = %d\n", __func__, data[9]);
idac3 = data[9];
return sprintf(buf, "%d\n", idac3);
}
@@ -524,9 +519,9 @@ static ssize_t touchkey_threshold_show(struct device *dev,
u8 data[10];
int ret;
- pr_debug("called %s\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
- pr_debug("called %s data[4] = %d\n", __func__, data[4]);
+ printk(KERN_DEBUG "called %s data[4] = %d\n", __func__, data[4]);
touchkey_threshold = data[4];
return sprintf(buf, "%d\n", touchkey_threshold);
}
@@ -544,12 +539,13 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
if (ret < 0) {
- pr_debug("[TouchKey] i2c read fail. do not excute firm update.\n");
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read fail. do not excute firm update.\n");
data[1] = 0;
data[2] = 0;
}
- pr_err("%s F/W version: 0x%x, Module version:0x%x\n", __func__,
+ printk(KERN_ERR "%s F/W version: 0x%x, Module version:0x%x\n", __func__,
data[1], data[2]);
tkey_i2c->firmware_ver = data[1];
@@ -563,34 +559,39 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
if ((tkey_i2c->firmware_ver < TK_FIRMWARE_VER) &&
(tkey_i2c->module_ver == TK_MODULE_VER)) {
#endif
- pr_debug("[TouchKey] firmware auto update excute\n");
+ printk(KERN_DEBUG "[TouchKey] firmware auto update excute\n");
tkey_i2c->update_status = TK_UPDATE_DOWN;
while (retry--) {
if (ISSP_main(tkey_i2c) == 0) {
- pr_debug("[TouchKey]firmware update succeeded\n");
+ printk(KERN_DEBUG
+ "[TouchKey]firmware update succeeded\n");
tkey_i2c->update_status = TK_UPDATE_PASS;
msleep(50);
break;
}
msleep(50);
- pr_debug("[TouchKey] firmware update failed. retry\n");
+ printk(KERN_DEBUG
+ "[TouchKey] firmware update failed. retry\n");
}
if (retry <= 0) {
tkey_i2c->pdata->power_on(0);
tkey_i2c->update_status = TK_UPDATE_FAIL;
- pr_debug("[TouchKey] firmware update failed.\n");
+ printk(KERN_DEBUG
+ "[TouchKey] firmware update failed.\n");
}
ret = touchkey_i2c_check(tkey_i2c);
if (ret < 0) {
- pr_debug("[TouchKey] i2c read fail.\n");
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read fail.\n");
return TK_UPDATE_FAIL;
}
#if defined(CONFIG_TARGET_LOCALE_KOR)
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
if (ret < 0) {
- pr_debug("[TouchKey] i2c read fail. do not excute firm update.\n");
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read fail. do not excute firm update.\n");
}
tkey_i2c->firmware_ver = data[1];
tkey_i2c->module_ver = data[2];
@@ -598,10 +599,13 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
printk(KERN_DEBUG "[TouchKey] firm ver = %d, module ver = %d\n",
tkey_i2c->firmware_ver, tkey_i2c->module_ver);
} else {
- pr_debug("[TouchKey] firmware auto update do not excute\n");
- pr_debug("[TouchKey] firmware_ver(banary=%d, current=%d)\n",
+ printk(KERN_DEBUG
+ "[TouchKey] firmware auto update do not excute\n");
+ printk(KERN_DEBUG
+ "[TouchKey] firmware_ver(banary=%d, current=%d)\n",
TK_FIRMWARE_VER, tkey_i2c->firmware_ver);
- pr_debug("[TouchKey] module_ver(banary=%d, current=%d)\n",
+ printk(KERN_DEBUG
+ "[TouchKey] module_ver(banary=%d, current=%d)\n",
TK_MODULE_VER, tkey_i2c->module_ver);
}
enable_irq(tkey_i2c->irq);
@@ -616,11 +620,12 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
if (ret < 0) {
- pr_debug("[TouchKey] i2c read fail. do not excute firm update.\n");
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read fail. do not excute firm update.\n");
return ret;
}
- pr_err("%s F/W version: 0x%x, Module version:0x%x\n", __func__,
+ printk(KERN_ERR "%s F/W version: 0x%x, Module version:0x%x\n", __func__,
data[1], data[2]);
retry = 3;
@@ -631,11 +636,12 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
tkey_i2c->update_status = TK_UPDATE_DOWN;
while (retry--) {
if (ISSP_main(tkey_i2c) == 0) {
- pr_err("[TOUCHKEY]Touchkey_update succeeded\n");
+ printk(KERN_ERR
+ "[TOUCHKEY]Touchkey_update succeeded\n");
tkey_i2c->update_status = TK_UPDATE_PASS;
break;
}
- pr_err("touchkey_update failed...retry...\n");
+ printk(KERN_ERR "touchkey_update failed...retry...\n");
}
if (retry <= 0) {
tkey_i2c->pdata->power_on(0);
@@ -644,9 +650,11 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
}
} else {
if (tkey_i2c->firmware_ver >= 0x0A) {
- pr_err("[TouchKey] Not F/W update. Cypess touch-key F/W version is latest\n");
+ printk(KERN_ERR
+ "[TouchKey] Not F/W update. Cypess touch-key F/W version is latest\n");
} else {
- pr_err("[TouchKey] Not F/W update. Cypess touch-key version(module or F/W) is not valid\n");
+ printk(KERN_ERR
+ "[TouchKey] Not F/W update. Cypess touch-key version(module or F/W) is not valid\n");
}
}
return ret;
@@ -657,7 +665,6 @@ static int touchkey_firmware_update(struct touchkey_i2c *tkey_i2c)
static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
{
struct touchkey_i2c *tkey_i2c = dev_id;
- static const int ledCmd[] = {TK_CMD_LED_ON, TK_CMD_LED_OFF};
u8 data[3];
int ret;
int retry = 10;
@@ -666,13 +673,18 @@ static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
set_touchkey_debug('a');
+ if (!atomic_read(&tkey_i2c->keypad_enable)) {
+ return;
+ }
+
retry = 3;
while (retry--) {
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
if (!ret)
break;
else {
- pr_debug("[TouchKey] i2c read failed, ret:%d, retry: %d\n",
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read failed, ret:%d, retry: %d\n",
ret, retry);
continue;
}
@@ -686,58 +698,33 @@ static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
pressed = !(data[0] & TK_BIT_PRESS_EV);
if (keycode_type <= 0 || keycode_type >= touchkey_count) {
- pr_debug("[Touchkey] keycode_type err\n");
+ printk(KERN_DEBUG "[Touchkey] keycode_type err\n");
return IRQ_HANDLED;
}
- if (pressed) {
+ if (pressed)
set_touchkey_debug('P');
- // enable lights on keydown
- if (touch_led_disabled == 0) {
- if (touchkey_led_status == TK_CMD_LED_OFF) {
- pr_debug("[Touchkey] %s: keydown - LED ON\n", __func__);
- i2c_touchkey_write(tkey_i2c->client, (u8 *) &ledCmd[0], 1);
- touchkey_led_status = TK_CMD_LED_ON;
- }
- if (timer_pending(&touch_led_timer) == 1) {
- mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout));
- }
- }
-
- } else {
- // touch led timeout on keyup
- if (touch_led_disabled == 0) {
- if (timer_pending(&touch_led_timer) == 0) {
- pr_debug("[Touchkey] %s: keyup - add_timer\n", __func__);
- touch_led_timer.expires = jiffies + (HZ * touch_led_timeout);
- add_timer(&touch_led_timer);
- } else {
- mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout));
- }
- }
- }
-
if (get_tsp_status() && pressed)
- pr_debug("[TouchKey] touchkey pressed but don't send event because touch is pressed.\n");
+ printk(KERN_DEBUG "[TouchKey] touchkey pressed but don't send event because touch is pressed.\n");
else {
input_report_key(tkey_i2c->input_dev,
touchkey_keycode[keycode_type], pressed);
input_sync(tkey_i2c->input_dev);
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
- pr_debug("[TouchKey] keycode:%d pressed:%d\n",
+ printk(KERN_DEBUG "[TouchKey] keycode:%d pressed:%d\n",
touchkey_keycode[keycode_type], pressed);
#else
- pr_debug("[TouchKey] pressed:%d\n",
+ printk(KERN_DEBUG "[TouchKey] pressed:%d\n",
pressed);
#endif
#if defined(CONFIG_TARGET_LOCALE_KOR)
if (g_debug_tkey == true) {
- pr_debug("[TouchKey] keycode[%d]=%d pressed:%d\n",
+ printk(KERN_DEBUG "[TouchKey] keycode[%d]=%d pressed:%d\n",
keycode_type, touchkey_keycode[keycode_type], pressed);
} else {
- pr_debug("[TouchKey] pressed:%d\n", pressed);
+ printk(KERN_DEBUG "[TouchKey] pressed:%d\n", pressed);
}
#endif
}
@@ -756,7 +743,7 @@ static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
#if 0
if (gpio_get_value(_3_GPIO_TOUCH_INT)) {
- pr_debug("[TouchKey] Unknown state.\n", __func__);
+ printk(KERN_DEBUG "[TouchKey] Unknown state.\n", __func__);
return IRQ_HANDLED;
}
#endif
@@ -780,7 +767,8 @@ static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
if (!ret)
break;
else {
- pr_debug("[TouchKey] i2c read failed, ret:%d, retry: %d\n",
+ printk(KERN_DEBUG
+ "[TouchKey] i2c read failed, ret:%d, retry: %d\n",
ret, retry);
continue;
}
@@ -821,16 +809,15 @@ static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
pressed = !(data[0] & TK_BIT_PRESS_EV);
if (keycode_type <= 0 || keycode_type >= touchkey_count) {
- pr_debug("[Touchkey] keycode_type err\n");
+ printk(KERN_DEBUG "[Touchkey] keycode_type err\n");
return IRQ_HANDLED;
}
- if (pressed) {
+ if (pressed)
set_touchkey_debug('P');
- }
if (get_tsp_status() && pressed)
- pr_debug("[TouchKey] touchkey pressed"
+ printk(KERN_DEBUG "[TouchKey] touchkey pressed"
" but don't send event because touch is pressed.\n");
else {
input_report_key(touchkey_driver->input_dev,
@@ -844,14 +831,14 @@ static irqreturn_t touchkey_interrupt(int irq, void *dev_id)
printk(KERN_DEBUG "search key sensitivity = %d\n",
search_sensitivity);
if (keycode_type == 2)
- pr_debug("back key sensitivity = %d\n",
+ printk(KERN_DEBUG "back key sensitivity = %d\n",
back_sensitivity);
#ifdef CONFIG_TARGET_LOCALE_NA
if (keycode_type == 3)
- pr_debug("home key sensitivity = %d\n",
+ printk(KERN_DEBUG "home key sensitivity = %d\n",
home_sensitivity);
if (keycode_type == 4)
- pr_debug("menu key sensitivity = %d\n",
+ printk(KERN_DEBUG "menu key sensitivity = %d\n",
menu_sensitivity);
#endif
@@ -871,7 +858,7 @@ static int sec_touchkey_early_suspend(struct early_suspend *h)
disable_irq(tkey_i2c->irq);
ret = cancel_work_sync(&tkey_i2c->update_work);
if (ret) {
- pr_debug("[Touchkey] enable_irq ret=%d\n", ret);
+ printk(KERN_DEBUG "[Touchkey] enable_irq ret=%d\n", ret);
enable_irq(tkey_i2c->irq);
}
@@ -884,9 +871,9 @@ static int sec_touchkey_early_suspend(struct early_suspend *h)
touchkey_enable = 0;
set_touchkey_debug('S');
- pr_debug("[TouchKey] sec_touchkey_early_suspend\n");
+ printk(KERN_DEBUG "[TouchKey] sec_touchkey_early_suspend\n");
if (touchkey_enable < 0) {
- pr_debug("[TouchKey] ---%s---touchkey_enable: %d\n",
+ printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n",
__func__, touchkey_enable);
return 0;
}
@@ -909,13 +896,13 @@ static int sec_touchkey_late_resume(struct early_suspend *h)
#endif
set_touchkey_debug('R');
- pr_debug("[TouchKey] sec_touchkey_late_resume\n");
+ printk(KERN_DEBUG "[TouchKey] sec_touchkey_late_resume\n");
/* enable ldo11 */
tkey_i2c->pdata->power_on(1);
if (touchkey_enable < 0) {
- pr_debug("[TouchKey] ---%s---touchkey_enable: %d\n",
+ printk(KERN_DEBUG "[TouchKey] ---%s---touchkey_enable: %d\n",
__func__, touchkey_enable);
return 0;
}
@@ -932,7 +919,7 @@ static int sec_touchkey_late_resume(struct early_suspend *h)
touchled_cmd_reversed = 0;
i2c_touchkey_write(tkey_i2c->client,
(u8 *) &touchkey_led_status, 1);
- pr_debug("[Touchkey] LED returned on\n");
+ printk(KERN_DEBUG "[Touchkey] LED returned on\n");
}
#ifdef TEST_JIG_MODE
i2c_touchkey_write(tkey_i2c->client, &get_touch, 1);
@@ -951,7 +938,7 @@ static int touchkey_i2c_check(struct touchkey_i2c *tkey_i2c)
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
if (ret < 0) {
- pr_err("[TouchKey] module version read fail\n");
+ printk(KERN_ERR "[TouchKey] module version read fail\n");
return ret;
}
@@ -983,8 +970,8 @@ static ssize_t touch_version_read(struct device *dev,
count = sprintf(buf, "0x%x\n", data[1]);
- pr_debug("[TouchKey] touch_version_read 0x%x\n", data[1]);
- pr_debug("[TouchKey] module_version_read 0x%x\n", data[2]);
+ printk(KERN_DEBUG "[TouchKey] touch_version_read 0x%x\n", data[1]);
+ printk(KERN_DEBUG "[TouchKey] module_version_read 0x%x\n", data[2]);
return count;
}
@@ -1006,15 +993,16 @@ void touchkey_update_func(struct work_struct *work)
#if defined(CONFIG_TARGET_LOCALE_NAATT)
char data[3];
i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
- pr_debug("[Touchkey] %s: F/W version: 0x%x, Module version:0x%x\n",
+ printk(KERN_DEBUG "[%s] F/W version: 0x%x, Module version:0x%x\n",
__func__, data[1], data[2]);
#endif
tkey_i2c->update_status = TK_UPDATE_DOWN;
- pr_debug("[Touchkey] %s: start\n", __func__);
+ printk(KERN_DEBUG "[TouchKey] %s start\n", __func__);
touchkey_enable = 0;
while (retry--) {
if (ISSP_main(tkey_i2c) == 0) {
- pr_debug("[TouchKey] touchkey_update succeeded\n");
+ printk(KERN_DEBUG
+ "[TouchKey] touchkey_update succeeded\n");
msleep(50);
touchkey_enable = 1;
#if defined(TK_HAS_AUTOCAL)
@@ -1093,13 +1081,13 @@ static ssize_t touchkey_led_control(struct device *dev,
#endif
ret = sscanf(buf, "%d", &data);
if (ret != 1) {
- printk(KERN_DEBUG "[Touchkey] %s: %d err\n",
+ printk(KERN_DEBUG "[TouchKey] %s, %d err\n",
__func__, __LINE__);
return size;
}
if (data != 1 && data != 2) {
- printk(KERN_DEBUG "[Touchkey] %s: wrong cmd %x\n",
+ printk(KERN_DEBUG "[TouchKey] %s wrong cmd %x\n",
__func__, data);
return size;
}
@@ -1111,154 +1099,17 @@ static ssize_t touchkey_led_control(struct device *dev,
data = ledCmd[data-1];
#endif
- if (touch_led_disabled == 0) {
- ret = i2c_touchkey_write(tkey_i2c->client, (u8 *) &data, 1);
- }
-
- if(data == ledCmd[0]) {
- if (touch_led_disabled == 0) {
- if (timer_pending(&touch_led_timer) == 0) {
- pr_debug("[Touchkey] %s: add_timer\n", __func__);
- touch_led_timer.expires = jiffies + (HZ * touch_led_timeout);
- add_timer(&touch_led_timer);
- } else {
- mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout));
- }
- }
- } else {
- if (timer_pending(&touch_led_timer) == 1) {
- pr_debug("[Touchkey] %s: del_timer\n", __func__);
- del_timer(&touch_led_timer);
- }
- }
-
- if (ret == -ENODEV) {
- pr_err("[Touchkey] error to write i2c\n");
+ ret = i2c_touchkey_write(tkey_i2c->client, (u8 *) &data, 1);
+
+ if (ret == -ENODEV)
touchled_cmd_reversed = 1;
- }
- pr_debug("[Touchkey] %s: touchkey_led_status=%d\n", __func__, data);
touchkey_led_status = data;
return size;
}
-static ssize_t touch_led_force_disable_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int ret;
-
- ret = sprintf(buf, "%d\n", touch_led_disabled);
- pr_info("[Touchkey] %s: touch_led_disabled=%d\n", __func__, touch_led_disabled);
-
- return ret;
-}
-
-static ssize_t touch_led_force_disable_store(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t size)
-{
- struct touchkey_i2c *tkey_i2c = dev_get_drvdata(dev);
- static const int ledCmd[] = {TK_CMD_LED_ON, TK_CMD_LED_OFF};
- int data, ret;
-
- ret = sscanf(buf, "%d\n", &data);
- if (unlikely(ret != 1)) {
- pr_err("[Touchkey] %s: err\n", __func__);
- return -EINVAL;
- }
- pr_info("[Touchkey] %s: value=%d\n", __func__, data);
-
- if (data == 1) {
- i2c_touchkey_write(tkey_i2c->client, (u8 *) &ledCmd[1], 1);
- touchkey_led_status = TK_CMD_LED_OFF;
- }
- touch_led_disabled = data;
-
- return size;
-}
-static DEVICE_ATTR(force_disable, S_IRUGO | S_IWUSR | S_IWGRP,
- touch_led_force_disable_show, touch_led_force_disable_store);
-
-static ssize_t touch_led_timeout_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- int ret;
-
- ret = sprintf(buf, "%d\n", touch_led_timeout);
- pr_info("[Touchkey] %s: touch_led_timeout=%d\n", __func__, touch_led_timeout);
-
- return ret;
-}
-
-static ssize_t touch_led_timeout_store(struct device *dev,
- struct device_attribute *attr, const char *buf,
- size_t size)
-{
- int data;
- int ret;
-
- ret = sscanf(buf, "%d\n", &data);
- if (unlikely(ret != 1)) {
- pr_err("[Touchkey] %s: err\n", __func__);
- return -EINVAL;
- }
- pr_info("[Touchkey] %s: new timeout=%d\n", __func__, data);
- touch_led_timeout = data;
-
- return size;
-}
-static DEVICE_ATTR(timeout, S_IRUGO | S_IWUSR | S_IWGRP,
- touch_led_timeout_show, touch_led_timeout_store);
-
-void touch_led_timedout(unsigned long ptr)
-{
- queue_work(tkey_i2c_local->wq, &tkey_i2c_local->work);
-}
-
-void touch_led_timedout_work(struct work_struct *work)
-{
- struct touchkey_i2c *tkey_i2c = container_of(work, struct touchkey_i2c, work);
- static const int ledCmd[] = {TK_CMD_LED_ON, TK_CMD_LED_OFF};
-
- if (touch_led_timeout != 0)
- {
- pr_debug("[Touchkey] %s: disabling touchled\n", __func__);
- i2c_touchkey_write(tkey_i2c->client, (u8 *) &ledCmd[1], 1);
- touchkey_led_status = TK_CMD_LED_OFF;
- }
-}
-
-void touchscreen_state_report(int state)
-{
- static const int ledCmd[] = {TK_CMD_LED_ON, TK_CMD_LED_OFF};
-
- if (touch_led_disabled == 0) {
- if (state == 1) {
- if(touchkey_led_status == TK_CMD_LED_OFF) {
- pr_debug("[Touchkey] %s: enable touchleds\n", __func__);
- i2c_touchkey_write(tkey_i2c_local->client, (u8 *) &ledCmd[0], 1);
- touchkey_led_status = TK_CMD_LED_ON;
- } else {
- if (timer_pending(&touch_led_timer) == 1) {
- pr_debug("[Touchkey] %s: mod_timer\n", __func__);
- mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout));
- }
- }
- } else if (state == 0) {
- if (timer_pending(&touch_led_timer) == 1) {
- pr_debug("[Touchkey] %s: mod_timer\n", __func__);
- mod_timer(&touch_led_timer, jiffies + (HZ * touch_led_timeout));
- } else if (touchkey_led_status == TK_CMD_LED_ON){
- pr_debug("[Touchkey] %s: add_timer\n", __func__);
- touch_led_timer.expires = jiffies + (HZ * touch_led_timeout);
- add_timer(&touch_led_timer);
- }
- }
- }
-}
-
-#if defined(TK_USE_4KEY) || defined(CONFIG_TARGET_LOCALE_NAATT) || defined(CONFIG_TARGET_LOCALE_NA)
+#if defined(TK_USE_4KEY)
static ssize_t touchkey_menu_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -1266,20 +1117,20 @@ static ssize_t touchkey_menu_show(struct device *dev,
u8 data[18] = { 0, };
int ret;
- pr_debug("[Touchkey] %s called\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 18);
#ifdef CONFIG_TARGET_LOCALE_NA
if (tkey_i2c->module_ver < 8) {
- pr_debug("[Touchkey] %s: data[12] =%d,data[13] = %d\n",
+ printk(KERN_DEBUG "called %s data[12] =%d,data[13] = %d\n",
__func__, data[12], data[13]);
menu_sensitivity = ((0x00FF & data[12]) << 8) | data[13];
} else {
- pr_debug("[Touchkey] %s: data[17] =%d\n", __func__,
+ printk(KERN_DEBUG "called %s data[17] =%d\n", __func__,
data[17]);
menu_sensitivity = data[17];
}
#else
- pr_debug("[Touchkey] %s: data[10] =%d,data[11] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[10] =%d,data[11] = %d\n", __func__,
data[10], data[11]);
menu_sensitivity = ((0x00FF & data[10]) << 8) | data[11];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -1293,20 +1144,20 @@ static ssize_t touchkey_home_show(struct device *dev,
u8 data[18] = { 0, };
int ret;
- pr_debug("[TouchKey] %s called\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 18);
#ifdef CONFIG_TARGET_LOCALE_NA
if (tkey_i2c->module_ver < 8) {
- pr_debug("[Touchkey] %s: data[10] =%d,data[11] = %d\n",
+ printk(KERN_DEBUG "called %s data[10] =%d,data[11] = %d\n",
__func__, data[10], data[11]);
home_sensitivity = ((0x00FF & data[10]) << 8) | data[11];
} else {
- pr_debug("[Touchkey] %s: data[15] =%d\n", __func__,
+ printk(KERN_DEBUG "called %s data[15] =%d\n", __func__,
data[15]);
home_sensitivity = data[15];
}
#else
- pr_debug("[Touchkey] %s: data[12] =%d,data[13] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[12] =%d,data[13] = %d\n", __func__,
data[12], data[13]);
home_sensitivity = ((0x00FF & data[12]) << 8) | data[13];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -1320,20 +1171,20 @@ static ssize_t touchkey_back_show(struct device *dev,
u8 data[18] = { 0, };
int ret;
- pr_debug("[TouchKey] %s called\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 18);
#ifdef CONFIG_TARGET_LOCALE_NA
if (tkey_i2c->module_ver < 8) {
- pr_debug("[Touchkey] %s: data[8] =%d,data[9] = %d\n",
+ printk(KERN_DEBUG "called %s data[8] =%d,data[9] = %d\n",
__func__, data[8], data[9]);
back_sensitivity = ((0x00FF & data[8]) << 8) | data[9];
} else {
- pr_debug("[Touchkey] %s: data[13] =%d\n", __func__,
+ printk(KERN_DEBUG "called %s data[13] =%d\n", __func__,
data[13]);
back_sensitivity = data[13];
}
#else
- pr_debug("[Touchkey] %s: data[14] =%d,data[15] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[14] =%d,data[15] = %d\n", __func__,
data[14], data[15]);
back_sensitivity = ((0x00FF & data[14]) << 8) | data[15];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -1347,20 +1198,20 @@ static ssize_t touchkey_search_show(struct device *dev,
u8 data[18] = { 0, };
int ret;
- pr_debug("[TouchKey] %s called\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 18);
#ifdef CONFIG_TARGET_LOCALE_NA
if (tkey_i2c->module_ver < 8) {
- pr_debug("[Touchkey] %s: data[6] =%d,data[7] = %d\n",
+ printk(KERN_DEBUG "called %s data[6] =%d,data[7] = %d\n",
__func__, data[6], data[7]);
search_sensitivity = ((0x00FF & data[6]) << 8) | data[7];
} else {
- pr_debug("[Touchkey] %s: data[11] =%d\n", __func__,
+ printk(KERN_DEBUG "called %s data[11] =%d\n", __func__,
data[11]);
search_sensitivity = data[11];
}
#else
- pr_debug("[Touchkey] %s: data[16] =%d,data[17] = %d\n", __func__,
+ printk(KERN_DEBUG "called %s data[16] =%d,data[17] = %d\n", __func__,
data[16], data[17]);
search_sensitivity = ((0x00FF & data[16]) << 8) | data[17];
#endif /* CONFIG_TARGET_LOCALE_NA */
@@ -1379,13 +1230,17 @@ static ssize_t touchkey_menu_show(struct device *dev,
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 14);
- pr_debug("[Touchkey] %s: data[13] =%d\n", __func__, data[13]);
- menu_sensitivity = data[13];
+ printk(KERN_DEBUG "called %s data[12] = %d, data[13] =%d\n", __func__,
+ data[12], data[13]);
+ menu_sensitivity = ((0x00FF & data[12]) << 8) | data[13];
+ printk(KERN_DEBUG "called %s menu_sensitivity =%d\n", __func__,
+ menu_sensitivity);
+
#else
u8 data[10];
int ret;
- pr_debug("[TouchKey] %s called\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
menu_sensitivity = data[7];
#endif
@@ -1404,13 +1259,16 @@ static ssize_t touchkey_back_show(struct device *dev,
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 14);
- pr_debug("[Touchkey] %s: data[11] =%d\n", __func__, data[11]);
- back_sensitivity = data[11];
+ printk(KERN_DEBUG "called %s data[10] = %d, data[11] =%d\n", __func__,
+ data[10], data[11]);
+ back_sensitivity =((0x00FF & data[10]) << 8) | data[11];
+ printk(KERN_DEBUG "called %s back_sensitivity =%d\n", __func__,
+ back_sensitivity);
#else
u8 data[10];
int ret;
- pr_debug("[TouchKey] %s called\n", __func__);
+ printk(KERN_DEBUG "called %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 10);
back_sensitivity = data[9];
#endif
@@ -1441,7 +1299,7 @@ static ssize_t autocalibration_status(struct device *dev,
int ret;
struct touchkey_i2c *tkey_i2c = dev_get_drvdata(dev);
- pr_debug("[Touchkey] %s\n", __func__);
+ printk(KERN_DEBUG "[Touchkey] %s\n", __func__);
ret = i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 6);
if ((data[5] & TK_BIT_AUTOCAL))
@@ -1487,19 +1345,20 @@ static ssize_t set_touchkey_update_show(struct device *dev,
while (retry--) {
if (ISSP_main(tkey_i2c) == 0) {
- pr_err("[TouchKey] Touchkey_update succeeded\n");
+ printk(KERN_ERR
+ "[TouchKey]Touchkey_update succeeded\n");
tkey_i2c->update_status = TK_UPDATE_PASS;
count = 1;
msleep(50);
break;
}
- pr_err("[TouchKey] touchkey_update failed... retry...\n");
+ printk(KERN_ERR "touchkey_update failed... retry...\n");
}
if (retry <= 0) {
/* disable ldo11 */
tkey_i2c->pdata->power_on(0);
count = 0;
- pr_err("[TouchKey] Touchkey_update fail\n");
+ printk(KERN_ERR "[TouchKey]Touchkey_update fail\n");
tkey_i2c->update_status = TK_UPDATE_FAIL;
enable_irq(tkey_i2c->irq);
return count;
@@ -1530,8 +1389,8 @@ static ssize_t set_touchkey_firm_version_read_show(struct device *dev,
i2c_touchkey_read(tkey_i2c->client, KEYCODE_REG, data, 3);
count = sprintf(buf, "0x%x\n", data[1]);
- pr_debug("[TouchKey] touch_version_read 0x%x\n", data[1]);
- pr_debug("[TouchKey] module_version_read 0x%x\n", data[2]);
+ printk(KERN_DEBUG "[TouchKey] touch_version_read 0x%x\n", data[1]);
+ printk(KERN_DEBUG "[TouchKey] module_version_read 0x%x\n", data[2]);
return count;
}
@@ -1542,7 +1401,8 @@ static ssize_t set_touchkey_firm_status_show(struct device *dev,
struct touchkey_i2c *tkey_i2c = dev_get_drvdata(dev);
int count = 0;
- pr_debug("[TouchKey] touch_update_read: update_status %d\n",
+ printk(KERN_DEBUG
+ "[TouchKey] touch_update_read: update_status %d\n",
tkey_i2c->update_status);
if (tkey_i2c->update_status == TK_UPDATE_PASS)
@@ -1555,6 +1415,40 @@ static ssize_t set_touchkey_firm_status_show(struct device *dev,
return count;
}
+static ssize_t sec_keypad_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct touchkey_i2c *tkey_i2c = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", atomic_read(&tkey_i2c->keypad_enable));
+}
+
+static ssize_t sec_keypad_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct touchkey_i2c *tkey_i2c = dev_get_drvdata(dev);
+
+ unsigned int val = 0;
+ sscanf(buf, "%d", &val);
+ val = (val == 0 ? 0 : 1);
+ atomic_set(&tkey_i2c->keypad_enable, val);
+ if (val) {
+ set_bit(KEY_BACK, tkey_i2c->input_dev->keybit);
+ set_bit(KEY_MENU, tkey_i2c->input_dev->keybit);
+ set_bit(KEY_HOME, tkey_i2c->input_dev->keybit);
+ } else {
+ clear_bit(KEY_BACK, tkey_i2c->input_dev->keybit);
+ clear_bit(KEY_MENU, tkey_i2c->input_dev->keybit);
+ clear_bit(KEY_HOME, tkey_i2c->input_dev->keybit);
+ }
+ input_sync(tkey_i2c->input_dev);
+
+ return count;
+}
+
+static DEVICE_ATTR(keypad_enable, S_IRUGO|S_IWUSR, sec_keypad_enable_show,
+ sec_keypad_enable_store);
+
static DEVICE_ATTR(recommended_version, S_IRUGO | S_IWUSR | S_IWGRP,
touch_version_read, touch_version_write);
static DEVICE_ATTR(updated_version, S_IRUGO | S_IWUSR | S_IWGRP,
@@ -1586,7 +1480,7 @@ static DEVICE_ATTR(touchkey_brightness, S_IRUGO | S_IWUSR | S_IWGRP, NULL,
brightness_control);
#endif
-#if 0 /* #if defined(CONFIG_TARGET_LOCALE_NAATT) */
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
static DEVICE_ATTR(touchkey_autocal_start, S_IRUGO | S_IWUSR | S_IWGRP, NULL,
set_touchkey_autocal_testmode);
#endif
@@ -1625,7 +1519,7 @@ static struct attribute *touchkey_attributes[] = {
#ifdef LED_LDO_WITH_REGULATOR
&dev_attr_touchkey_brightness.attr,
#endif
-#if 0/* defined(CONFIG_TARGET_LOCALE_NAATT) */
+#if defined(CONFIG_TARGET_LOCALE_NAATT)
&dev_attr_touchkey_autocal_start.attr,
#endif
#if defined(TK_HAS_AUTOCAL)
@@ -1640,9 +1534,8 @@ static struct attribute *touchkey_attributes[] = {
&dev_attr_touchkey_threshold.attr,
&dev_attr_autocal_enable.attr,
&dev_attr_autocal_stat.attr,
+ &dev_attr_keypad_enable.attr,
#endif
- &dev_attr_timeout.attr,
- &dev_attr_force_disable.attr,
NULL,
};
@@ -1662,7 +1555,7 @@ static int i2c_touchkey_probe(struct i2c_client *client,
int i;
int ret;
- pr_debug("[TouchKey] i2c_touchkey_probe\n");
+ printk(KERN_DEBUG "[TouchKey] i2c_touchkey_probe\n");
if (pdata == NULL) {
printk(KERN_ERR "%s: no pdata\n", __func__);
@@ -1672,7 +1565,7 @@ static int i2c_touchkey_probe(struct i2c_client *client,
/*Check I2C functionality */
ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
if (ret == 0) {
- pr_err("[Touchkey] No I2C functionality found\n");
+ printk(KERN_ERR "[Touchkey] No I2C functionality found\n");
ret = -ENODEV;
return ret;
}
@@ -1680,15 +1573,14 @@ static int i2c_touchkey_probe(struct i2c_client *client,
/*Obtain kernel memory space for touchkey i2c */
tkey_i2c = kzalloc(sizeof(struct touchkey_i2c), GFP_KERNEL);
if (NULL == tkey_i2c) {
- pr_err("[Touchkey] failed to allocate tkey_i2c.\n");
+ printk(KERN_ERR "[Touchkey] failed to allocate tkey_i2c.\n");
return -ENOMEM;
}
- tkey_i2c_local = tkey_i2c;
input_dev = input_allocate_device();
if (!input_dev) {
- pr_err("[Touchkey] failed to allocate input device\n");
+ printk(KERN_ERR"[Touchkey] failed to allocate input device\n");
kfree(tkey_i2c);
return -ENOMEM;
}
@@ -1710,6 +1602,8 @@ static int i2c_touchkey_probe(struct i2c_client *client,
set_bit(LED_MISC, input_dev->ledbit);
set_bit(EV_KEY, input_dev->evbit);
+ atomic_set(&tkey_i2c->keypad_enable, 1);
+
for (i = 1; i < touchkey_count; i++)
set_bit(touchkey_keycode[i], input_dev->keybit);
@@ -1717,7 +1611,7 @@ static int i2c_touchkey_probe(struct i2c_client *client,
ret = input_register_device(input_dev);
if (ret) {
- pr_err("[Touchkey] failed to register input device\n");
+ printk(KERN_ERR"[Touchkey] failed to register input device\n");
input_free_device(input_dev);
kfree(tkey_i2c);
return err;
@@ -1735,24 +1629,27 @@ static int i2c_touchkey_probe(struct i2c_client *client,
tkey_i2c->dev = device_create(sec_class, NULL, 0, NULL, "sec_touchkey");
if (IS_ERR(tkey_i2c->dev)) {
- pr_err("[TouchKey] Failed to create device(tkey_i2c->dev)!\n");
+ printk(KERN_ERR "Failed to create device(tkey_i2c->dev)!\n");
input_unregister_device(input_dev);
} else {
dev_set_drvdata(tkey_i2c->dev, tkey_i2c);
ret = sysfs_create_group(&tkey_i2c->dev->kobj,
&touchkey_attr_group);
if (ret) {
- pr_err("[TouchKey]: failed to create sysfs group\n");
+ printk(KERN_ERR
+ "[TouchKey]: failed to create sysfs group\n");
}
}
#if defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_C1)
gpio_request(GPIO_OLED_DET, "OLED_DET");
ret = gpio_get_value(GPIO_OLED_DET);
- pr_debug("[TouchKey] OLED_DET = %d\n", ret);
+ printk(KERN_DEBUG
+ "[TouchKey] OLED_DET = %d\n", ret);
if (ret == 0) {
- pr_debug("[TouchKey] device wasn't connected to board\n");
+ printk(KERN_DEBUG
+ "[TouchKey] device wasn't connected to board\n");
input_unregister_device(input_dev);
touchkey_probe = false;
@@ -1761,7 +1658,7 @@ static int i2c_touchkey_probe(struct i2c_client *client,
#else
ret = touchkey_i2c_check(tkey_i2c);
if (ret < 0) {
- pr_debug("[TouchKey] probe failed\n");
+ printk(KERN_DEBUG"[TouchKey] probe failed\n");
input_unregister_device(input_dev);
touchkey_probe = false;
return -EBUSY;
@@ -1773,7 +1670,8 @@ static int i2c_touchkey_probe(struct i2c_client *client,
IRQF_DISABLED | IRQF_TRIGGER_FALLING |
IRQF_ONESHOT, tkey_i2c->name, tkey_i2c);
if (ret < 0) {
- pr_err("[Touchkey]: failed to request irq(%d) - %d\n",
+ printk(KERN_ERR
+ "[Touchkey]: failed to request irq(%d) - %d\n",
tkey_i2c->irq, ret);
input_unregister_device(input_dev);
touchkey_probe = false;
@@ -1785,7 +1683,8 @@ static int i2c_touchkey_probe(struct i2c_client *client,
#if defined(TK_HAS_FIRMWARE_UPDATE)
ret = touchkey_firmware_update(tkey_i2c);
if (ret < 0) {
- pr_err("[Touchkey]: failed firmware updating process (%d)\n",
+ printk(KERN_ERR
+ "[Touchkey]: failed firmware updating process (%d)\n",
ret);
input_unregister_device(input_dev);
touchkey_probe = false;
@@ -1805,17 +1704,6 @@ static int i2c_touchkey_probe(struct i2c_client *client,
touchkey_autocalibration(tkey_i2c);
#endif
set_touchkey_debug('K');
-
- // init workqueue
- tkey_i2c->wq = create_singlethread_workqueue("tkey_i2c_wq");
- if (!tkey_i2c->wq) {
- ret = -ENOMEM;
- pr_err("[Touchkey] %s: could not create workqueue\n", __func__);
- }
-
- /* this is the thread function we run on the work queue */
- INIT_WORK(&tkey_i2c->work, touch_led_timedout_work);
-
return 0;
}
@@ -1833,13 +1721,13 @@ static int __init touchkey_init(void)
#if defined(CONFIG_MACH_M0)
if (system_rev < TOUCHKEY_FW_UPDATEABLE_HW_REV) {
- pr_debug("[Touchkey] Doesn't support this board rev %d\n",
+ printk(KERN_DEBUG "[Touchkey] Doesn't support this board rev %d\n",
system_rev);
return 0;
}
#elif defined(CONFIG_MACH_C1)
if (system_rev < TOUCHKEY_FW_UPDATEABLE_HW_REV) {
- pr_debug("[Touchkey] Doesn't support this board rev %d\n",
+ printk(KERN_DEBUG "[Touchkey] Doesn't support this board rev %d\n",
system_rev);
return 0;
}
@@ -1852,23 +1740,19 @@ static int __init touchkey_init(void)
ret = i2c_add_driver(&touchkey_i2c_driver);
if (ret) {
- pr_err("[TouchKey] registration failed, module not inserted.ret= %d\n",
+ printk(KERN_ERR
+ "[TouchKey] registration failed, module not inserted.ret= %d\n",
ret);
}
#ifdef TEST_JIG_MODE
i2c_touchkey_write(tkey_i2c->client, &get_touch, 1);
#endif
-
- // init the touchled timer
- init_timer(&touch_led_timer);
- touch_led_timer.function = touch_led_timedout;
-
return ret;
}
static void __exit touchkey_exit(void)
{
- pr_debug("[TouchKey] %s\n", __func__);
+ printk(KERN_DEBUG "[TouchKey] %s\n", __func__);
i2c_del_driver(&touchkey_i2c_driver);
}
diff --git a/drivers/input/keyboard/cypress/cypress-touchkey.h b/drivers/input/keyboard/cypress/cypress-touchkey.h
deleted file mode 100644
index 61abce2..0000000
--- a/drivers/input/keyboard/cypress/cypress-touchkey.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2012 The CyanogenMod Project
- *
- * Authors: Daniel Hillenbrand <codeworkx@cyanogenmod.com>
- * Marco Hillenbrand <marco.hillenbrand@googlemail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-void touchscreen_state_report(int state);
diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index bf75ef5..6feb939 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -47,10 +47,20 @@ struct gpio_keys_drvdata {
unsigned int n_buttons;
int (*enable)(struct device *dev);
void (*disable)(struct device *dev);
+#ifdef CONFIG_SENSORS_HALL
+ int gpio_flip_cover;
+ bool flip_cover;
+ struct delayed_work flip_cover_dwork;
+#endif
struct gpio_button_data data[0];
/* WARNING: this area can be expanded. Do NOT add any member! */
};
+#ifdef CONFIG_SENSORS_HALL
+int flip_cover_open;
+extern ts_powered_on;
+#endif
+
/*
* SYSFS interface for enabling/disabling keys and switches:
*
@@ -376,12 +386,36 @@ out:
return count;
}
+#ifdef CONFIG_SENSORS_HALL
+static ssize_t hall_detect_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gpio_keys_drvdata *ddata = dev_get_drvdata(dev);
+
+ if (ddata->flip_cover){
+ printk("%s: OPEN",__func__);
+ sprintf(buf, "OPEN");
+ }else{
+ printk("%s: CLOSE",__func__);
+ sprintf(buf, "CLOSE");
+ }
+
+ return strlen(buf);
+}
+#endif
+
static DEVICE_ATTR(sec_key_pressed, 0664, key_pressed_show, NULL);
static DEVICE_ATTR(wakeup_keys, 0664, NULL, wakeup_enable);
+#ifdef CONFIG_SENSORS_HALL
+static DEVICE_ATTR(hall_detect, 0664, hall_detect_show, NULL);
+#endif
static struct attribute *sec_key_attrs[] = {
&dev_attr_sec_key_pressed.attr,
&dev_attr_wakeup_keys.attr,
+#ifdef CONFIG_SENSORS_HALL
+ &dev_attr_hall_detect.attr,
+#endif
NULL,
};
@@ -531,9 +565,16 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
}
}
#endif
+#ifdef CONFIG_SENSORS_HALL
+ if(!flip_cover_open && button->code == KEY_POWER){
+ printk(KERN_DEBUG" cover closed...ignoring PWR button");
+ }else{
+#endif
input_event(input, type, button->code, !!state);
input_sync(input);
-
+#ifdef CONFIG_SENSORS_HALL
+ }
+#endif
if (button->code == KEY_POWER)
printk(KERN_DEBUG"[keys]PWR %d\n", !!state);
}
@@ -652,11 +693,85 @@ fail2:
return error;
}
+#ifdef CONFIG_SENSORS_HALL
+static void flip_cover_work(struct work_struct *work)
+{
+ struct gpio_keys_drvdata *ddata =
+ container_of(work, struct gpio_keys_drvdata,
+ flip_cover_dwork.work);
+
+ ddata->flip_cover = gpio_get_value(ddata->gpio_flip_cover);
+
+ printk(KERN_DEBUG "[keys] %s : %d\n",
+ __func__, ddata->flip_cover);
+
+ /* input_report_switch(ddata->input, SW_FLIP, ddata->flip_cover);
+ input_sync(ddata->input);*/
+
+ flip_cover_open = ddata->flip_cover;
+
+ if(!ts_powered_on && !ddata->flip_cover){
+ printk("[keys] screen already off\n");
+ }else if(ts_powered_on && ddata->flip_cover){
+ printk("[keys] screen already on\n");
+ }else{
+ input_report_key(ddata->input, KEY_POWER, 1);
+ input_sync(ddata->input);
+ input_report_key(ddata->input, KEY_POWER, 0);
+ input_sync(ddata->input);
+ }
+}
+
+static irqreturn_t flip_cover_detect(int irq, void *dev_id)
+{
+ struct gpio_keys_drvdata *ddata = dev_id;
+
+ cancel_delayed_work_sync(&ddata->flip_cover_dwork);
+ schedule_delayed_work(&ddata->flip_cover_dwork, HZ / 20);
+ return IRQ_HANDLED;
+}
+#endif
+
static int gpio_keys_open(struct input_dev *input)
{
struct gpio_keys_drvdata *ddata = input_get_drvdata(input);
+
+#ifdef CONFIG_SENSORS_HALL
+ int ret = 0;
+ int irq = gpio_to_irq(ddata->gpio_flip_cover);
+
+ INIT_DELAYED_WORK(&ddata->flip_cover_dwork, flip_cover_work);
+
+ ret = request_threaded_irq(
+ irq, NULL,
+ flip_cover_detect,
+ IRQF_DISABLED | IRQF_TRIGGER_RISING |
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "flip_cover", ddata);
+
+ if (ret) {
+ printk(KERN_ERR
+ "keys: failed to request flip cover irq %d gpio %d\n",
+ irq, ddata->gpio_flip_cover);
+ goto hall_sensor_error;
+ }
+
+ ret = enable_irq_wake(irq);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "keys: Failed to Enable Wakeup Source(%d) \n",
+ ret);
+ goto hall_sensor_error;
+ }
+
+ /* update the current status */
+ schedule_delayed_work(&ddata->flip_cover_dwork, HZ / 2);
- return ddata->enable ? ddata->enable(input->dev.parent) : 0;
+hall_sensor_error:
+
+#endif
+
+ return ddata->enable ? ddata->enable(input->dev.parent) : 0;
}
static void gpio_keys_close(struct input_dev *input)
@@ -690,6 +805,9 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
ddata->n_buttons = pdata->nbuttons;
ddata->enable = pdata->enable;
ddata->disable = pdata->disable;
+#ifdef CONFIG_SENSORS_HALL
+ ddata->gpio_flip_cover = pdata->gpio_flip_cover;
+#endif
mutex_init(&ddata->disable_lock);
platform_set_drvdata(pdev, ddata);
@@ -698,6 +816,10 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
input->name = pdata->name ? : pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
+/*#ifdef CONFIG_SENSORS_HALL
+ input->evbit[0] |= BIT_MASK(EV_SW);
+ input_set_capability(input, EV_SW, SW_FLIP);
+#endif*/
input->open = gpio_keys_open;
input->close = gpio_keys_close;
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
index 8c4ba2a..ec4d775 100644
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -958,6 +958,27 @@ config TOUCHSCREEN_SYNAPTICS_S7301
To compile this driver as a module, choose M here: the
module will be called melfas_ts.
+config TOUCHSCREEN_SYNAPTICS_S7301_KEYS
+ bool "S7301 touch key support"
+ default n
+ help
+ Say Y here if you want support for SYNAPTICS S7301
+ touchscreen controller Keys.
+
+config TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND
+ bool "S7301 touch key workaround"
+ default n
+ help
+ Say Y here if you want support for SYNAPTICS S7301
+ touchscreen controller reset control
+
+config TOUCHSCREEN_SYNAPTICS_S7301_KEYLED
+ bool "S7301 touch keyled support"
+ default n
+ help
+ Say Y here if you want support for SYNAPTICS S7301
+ with GPIO led control
+
config TOUCHSCREEN_CYTTSP4
tristate "Cypress GEN4 Touchscreen Interface"
depends on I2C
@@ -974,6 +995,11 @@ config SEC_TOUCHSCREEN_DVFS_LOCK
help
Say Y here if you want support for lock the cpu frequency.
+config SEC_TOUCHSCREEN_SURFACE_TOUCH
+ tristate "SEC surface touch"
+ help
+ Say Y here if you want support for surface touch.
+
config KEYPAD_MELFAS_TOUCH
tristate "Melfas touch keypad support"
default n
diff --git a/drivers/input/touchscreen/mms152_ts.c b/drivers/input/touchscreen/mms152_ts.c
index ad1dc98..fa1d295 100644
--- a/drivers/input/touchscreen/mms152_ts.c
+++ b/drivers/input/touchscreen/mms152_ts.c
@@ -49,8 +49,6 @@
#include <asm/unaligned.h>
-#include "../keyboard/cypress/cypress-touchkey.h"
-
#ifdef CONFIG_INPUT_FBSUSPEND
#ifdef CONFIG_DRM
#include <drm/drm_backlight.h>
@@ -977,10 +975,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
if (info->panel == 'M') {
if (info->finger_state[id] != 0) {
info->finger_state[id] = 0;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(0);
-
#ifdef CONFIG_LCD_FREQ_SWITCH
dev_notice(&client->dev,
"R(%c)(%d) [%2d]", info->ldi,
@@ -994,10 +988,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
} else {
if (info->finger_state[id] != 0) {
info->finger_state[id] = 0;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(0);
-
dev_notice(&client->dev,
"R [%2d]", id);
}
@@ -1006,10 +996,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
if (info->panel == 'M') {
if (info->finger_state[id] != 0) {
info->finger_state[id] = 0;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(0);
-
#ifdef CONFIG_LCD_FREQ_SWITCH
dev_notice(&client->dev,
"R(%c)(%d) [%2d],([%4d],[%3d])",
@@ -1025,10 +1011,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
} else {
if (info->finger_state[id] != 0) {
info->finger_state[id] = 0;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(0);
-
dev_notice(&client->dev,
"R [%2d],([%4d],[%3d]),S:%d W:%d",
id, x, y, tmp[4], tmp[5]);
@@ -1058,10 +1040,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
if (info->finger_state[id] == 0) {
info->finger_state[id] = 1;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(1);
-
#ifdef CONFIG_LCD_FREQ_SWITCH
dev_notice(&client->dev,
"P(%c)(%d) [%2d]", info->ldi,
@@ -1074,10 +1052,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
#else
if (info->finger_state[id] == 0) {
info->finger_state[id] = 1;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(1);
-
#ifdef CONFIG_LCD_FREQ_SWITCH
dev_notice(&client->dev,
"P(%c)(%d) [%2d],([%4d],[%3d]) w=%d, major=%d, minor=%d, angle=%d, palm=%d",
@@ -1108,20 +1082,12 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
#ifdef CONFIG_SAMSUNG_PRODUCT_SHIP
if (info->finger_state[id] == 0) {
info->finger_state[id] = 1;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(1);
-
dev_notice(&client->dev,
"P [%2d]", id);
}
#else
if (info->finger_state[id] == 0) {
info->finger_state[id] = 1;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(1);
-
dev_notice(&client->dev,
"P [%2d],([%4d],[%3d]),S:%d W:%d",
id, x, y, tmp[4], tmp[5]);
diff --git a/drivers/input/touchscreen/mms_ts.c b/drivers/input/touchscreen/mms_ts.c
index ebca68c..cdb47f7 100644
--- a/drivers/input/touchscreen/mms_ts.c
+++ b/drivers/input/touchscreen/mms_ts.c
@@ -50,8 +50,6 @@
#include <asm/unaligned.h>
-#include "../keyboard/cypress/cypress-touchkey.h"
-
#define MAX_FINGERS 10
#define MAX_WIDTH 30
#define MAX_PRESSURE 255
@@ -682,9 +680,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
, angle, palm);
#else
if (info->finger_state[id] != 0) {
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(0);
-
dev_notice(&client->dev,
"finger [%d] up, palm %d\n", id, palm);
}
@@ -723,10 +718,6 @@ static irqreturn_t mms_ts_interrupt(int irq, void *dev_id)
#else
if (info->finger_state[id] == 0) {
info->finger_state[id] = 1;
-
- // report state to cypress-touchkey for backlight timeout
- touchscreen_state_report(1);
-
dev_notice(&client->dev,
"finger [%d] down, palm %d\n", id, palm);
}
diff --git a/drivers/input/touchscreen/mxt224_u1.c b/drivers/input/touchscreen/mxt224_u1.c
index cd0674f..5a243fb 100644
--- a/drivers/input/touchscreen/mxt224_u1.c
+++ b/drivers/input/touchscreen/mxt224_u1.c
@@ -28,8 +28,6 @@
#include <mach/cpufreq.h>
#include <linux/input/mt.h>
-#include "../keyboard/cypress/cypress-touchkey.h"
-
#define OBJECT_TABLE_START_ADDRESS 7
#define OBJECT_TABLE_ELEMENT_SIZE 6
@@ -1339,10 +1337,6 @@ static void report_input_data(struct mxt224_data *data)
copy_data->lock_status = 1;
}
}
-
- /* tell cypress keypad we had finger activity */
- touchscreen_state_report(touch_is_pressed);
-
}
void palm_recovery(void)
diff --git a/drivers/input/touchscreen/synaptics_fw.h b/drivers/input/touchscreen/synaptics_fw.h
index 2cc5314..a5da7325 100644
--- a/drivers/input/touchscreen/synaptics_fw.h
+++ b/drivers/input/touchscreen/synaptics_fw.h
@@ -1,6 +1,8854 @@
#ifndef __RMI_FW_H
#define __RMI_FW_H
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+const char *rmi_config_ver_button = "00";
+
+#if defined(CONFIG_KONA_01_BD)
+const u8 rmi_fw_button[] = {
+ /*0000:*/ 0x82, 0x78, 0x14, 0xfe, 0x00, 0x00, 0x00, 0x05, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ /*0010:*/ 0x53, 0x37, 0x33, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0030:*/ 0x44, 0x53, 0x34, 0x20, 0x52, 0x33, 0x2e, 0x35, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0040:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0050:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0060:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0070:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0080:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0090:*/ 0x49, 0x32, 0x43, 0x00, 0x04, 0x00, 0xff, 0x00, 0x0c, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*00a0:*/ 0x49, 0x32, 0x43, 0x00, 0x04, 0x00, 0xff, 0x00, 0x0c, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*00b0:*/ 0x69, 0x96, 0x7e, 0xd0, 0x20, 0x5a, 0x00, 0x20, 0xc5, 0xc0, 0x2a, 0x79, 0xac, 0x74, 0x2e, 0x45,
+ /*00c0:*/ 0x57, 0x05, 0x48, 0x7c, 0xd7, 0x03, 0xb0, 0x50, 0xe0, 0x77, 0x3c, 0x8b, 0x79, 0xf6, 0x71, 0x75,
+ /*00d0:*/ 0xca, 0xec, 0xb0, 0x31, 0x53, 0xaa, 0x37, 0xe9, 0x19, 0x47, 0x46, 0x84, 0xba, 0x28, 0x18, 0xe9,
+ /*00e0:*/ 0x51, 0x89, 0xe7, 0xce, 0x3e, 0x64, 0x26, 0xa6, 0x25, 0x31, 0xc5, 0x0d, 0x9a, 0xa9, 0x93, 0xfa,
+ /*00f0:*/ 0x7c, 0x9a, 0x20, 0x17, 0x1a, 0x92, 0x35, 0xa6, 0x9a, 0x75, 0xa0, 0x23, 0x4f, 0xb1, 0xec, 0x1e,
+ /*0100:*/ 0x64, 0xce, 0x5c, 0x97, 0x6f, 0xf6, 0x36, 0x81, 0xf8, 0x90, 0x17, 0xb0, 0x0d, 0x0c, 0xd3, 0x50,
+ /*0110:*/ 0x2b, 0xb3, 0x37, 0x31, 0xe9, 0x03, 0x0c, 0x63, 0xf1, 0x9e, 0x52, 0x2d, 0xf5, 0xd3, 0x44, 0x87,
+ /*0120:*/ 0xa3, 0xef, 0xc0, 0x55, 0xf3, 0xca, 0x62, 0x4f, 0xc8, 0x13, 0xbd, 0x20, 0xe6, 0x3a, 0xac, 0xcd,
+ /*0130:*/ 0x2b, 0x4b, 0x2c, 0x18, 0x21, 0x16, 0xf3, 0xb6, 0xaa, 0x41, 0xe2, 0x66, 0xfc, 0x6f, 0x1f, 0xce,
+ /*0140:*/ 0x7f, 0x17, 0xdd, 0xfd, 0x49, 0xde, 0x8b, 0x2b, 0xec, 0xf9, 0xe4, 0xed, 0xaf, 0x8c, 0x26, 0xe0,
+ /*0150:*/ 0xb5, 0x30, 0xde, 0x4b, 0xb9, 0x9e, 0x4d, 0xfe, 0x43, 0x86, 0xce, 0x9e, 0x0b, 0x6f, 0xb9, 0xc8,
+ /*0160:*/ 0x1e, 0xcb, 0x83, 0xee, 0xdb, 0xf3, 0xcb, 0x5f, 0xa2, 0x9b, 0xba, 0x53, 0x3d, 0xde, 0x85, 0xce,
+ /*0170:*/ 0xda, 0xdc, 0xfd, 0x86, 0xe6, 0xdc, 0xb0, 0x14, 0xc0, 0x87, 0x68, 0x6d, 0x15, 0x39, 0x99, 0x81,
+ /*0180:*/ 0xf4, 0x8f, 0xfa, 0x4b, 0x47, 0x53, 0x99, 0x05, 0xe8, 0x9f, 0xd7, 0x8c, 0x0a, 0xdd, 0x12, 0x95,
+ /*0190:*/ 0xc6, 0xd0, 0xe3, 0xf9, 0x2c, 0xb0, 0xee, 0x4f, 0x50, 0x51, 0x9e, 0x2c, 0x7f, 0x07, 0xd7, 0xd7,
+ /*01a0:*/ 0xa6, 0xfc, 0x58, 0x56, 0x65, 0x04, 0x49, 0x73, 0x05, 0x3e, 0xd2, 0xe9, 0x37, 0xb8, 0xd7, 0xbc,
+ /*01b0:*/ 0x79, 0x5f, 0x8c, 0xc7, 0x28, 0xe6, 0x39, 0xef, 0x29, 0x7f, 0x26, 0x52, 0xd8, 0xda, 0x99, 0x4c,
+ /*01c0:*/ 0x6b, 0x6e, 0x7a, 0xd3, 0x9e, 0x75, 0xca, 0x55, 0xb2, 0x29, 0x88, 0xb8, 0x0b, 0x1d, 0x1c, 0x81,
+ /*01d0:*/ 0x98, 0x15, 0xf7, 0x59, 0x1d, 0x73, 0xc3, 0x8d, 0x42, 0x5e, 0xce, 0x78, 0x9b, 0x36, 0x49, 0xbe,
+ /*01e0:*/ 0xad, 0xc9, 0x81, 0xa4, 0x7e, 0x4c, 0xcb, 0x35, 0x52, 0x17, 0xd7, 0x73, 0x29, 0x4e, 0x81, 0xdf,
+ /*01f0:*/ 0x66, 0x04, 0x1d, 0x49, 0x3f, 0xa0, 0xf2, 0x2f, 0x42, 0xd0, 0xf4, 0xe9, 0x49, 0xae, 0x52, 0xf7,
+ /*0200:*/ 0xce, 0x67, 0x45, 0x5c, 0x59, 0x91, 0xb0, 0x83, 0xc0, 0x2e, 0xf4, 0x77, 0xcb, 0x65, 0xb5, 0xd3,
+ /*0210:*/ 0x18, 0x15, 0x9e, 0x05, 0x30, 0x8f, 0xb7, 0xb8, 0x40, 0x1f, 0x71, 0xb1, 0x0f, 0x81, 0x03, 0x89,
+ /*0220:*/ 0xb7, 0x6d, 0xef, 0x46, 0x6e, 0x45, 0x46, 0xc5, 0xd3, 0x94, 0x92, 0x41, 0xca, 0xc5, 0x32, 0xac,
+ /*0230:*/ 0x34, 0x10, 0x2b, 0x1a, 0x4f, 0xec, 0x94, 0xcf, 0x91, 0xd9, 0x80, 0xf1, 0x60, 0x9d, 0xe7, 0x63,
+ /*0240:*/ 0x51, 0xa7, 0xec, 0xe6, 0x1d, 0xf8, 0x38, 0xc7, 0xec, 0xe7, 0x69, 0x08, 0x02, 0x7b, 0x09, 0x89,
+ /*0250:*/ 0x84, 0x9a, 0xbd, 0x1f, 0x04, 0x9f, 0xf3, 0x20, 0xc8, 0x23, 0x4c, 0xd7, 0x0a, 0x64, 0x47, 0x43,
+ /*0260:*/ 0xb6, 0xc8, 0xad, 0xb7, 0xd5, 0xa4, 0xb0, 0xea, 0x57, 0x8d, 0xe9, 0x4e, 0x18, 0x81, 0x08, 0x26,
+ /*0270:*/ 0x68, 0x66, 0xe6, 0x0b, 0xb2, 0x5d, 0xf5, 0xc3, 0xc1, 0xc1, 0x25, 0x84, 0xdd, 0x00, 0x34, 0x10,
+ /*0280:*/ 0x94, 0xb6, 0xaf, 0x9f, 0x6a, 0xd5, 0x34, 0x1e, 0x9a, 0x42, 0xd0, 0xa7, 0xc9, 0xd7, 0x3f, 0xc3,
+ /*0290:*/ 0x43, 0xf2, 0x80, 0x94, 0x2e, 0xb9, 0xdb, 0x60, 0x76, 0xc5, 0xf5, 0x6f, 0xe8, 0x83, 0x96, 0x1b,
+ /*02a0:*/ 0x96, 0x80, 0xed, 0xb4, 0x0b, 0xc3, 0x34, 0x92, 0xa3, 0xe7, 0xb8, 0x07, 0x23, 0x1b, 0x1b, 0x44,
+ /*02b0:*/ 0x4a, 0x09, 0xf5, 0xb9, 0x50, 0x75, 0xf2, 0xd6, 0x75, 0xae, 0xef, 0xfa, 0x29, 0x4f, 0x7a, 0xf0,
+ /*02c0:*/ 0xfa, 0x01, 0xf4, 0x0c, 0x67, 0x2c, 0x2d, 0x36, 0x75, 0xfb, 0xe9, 0xaa, 0xf5, 0x4b, 0x87, 0xbb,
+ /*02d0:*/ 0xb8, 0xe7, 0x62, 0x4f, 0xbb, 0xc1, 0xc7, 0xd6, 0xa4, 0x10, 0xa3, 0xca, 0xb9, 0x80, 0x7a, 0x1e,
+ /*02e0:*/ 0xb0, 0xc5, 0xaa, 0x84, 0x0e, 0xe8, 0x10, 0x25, 0xa4, 0xd5, 0x1d, 0xc3, 0x2f, 0x11, 0x8e, 0xdc,
+ /*02f0:*/ 0xae, 0x9d, 0x51, 0x75, 0x40, 0x9e, 0x92, 0xec, 0x94, 0xff, 0x24, 0xbd, 0x00, 0x51, 0x43, 0x15,
+ /*0300:*/ 0x22, 0x7f, 0x7e, 0x22, 0xfa, 0x57, 0x2b, 0x1c, 0xf3, 0xb1, 0x11, 0x62, 0x0d, 0xb3, 0x68, 0x1a,
+ /*0310:*/ 0x6f, 0x2c, 0xb1, 0x6a, 0x0a, 0xb6, 0xc0, 0x8e, 0x14, 0x2f, 0x49, 0xd6, 0x65, 0x77, 0xb9, 0xfb,
+ /*0320:*/ 0x62, 0x78, 0xbf, 0x05, 0x1d, 0x37, 0xc7, 0x59, 0xa0, 0x1a, 0x8e, 0xb3, 0x08, 0x07, 0x69, 0x12,
+ /*0330:*/ 0x8b, 0xa1, 0x36, 0xd2, 0x42, 0xfe, 0x5a, 0xf7, 0xa6, 0xfd, 0x8b, 0x27, 0x6d, 0x1d, 0x3b, 0x8b,
+ /*0340:*/ 0xcb, 0xe9, 0x2b, 0x3f, 0xdd, 0xe0, 0xa4, 0x4e, 0x97, 0x41, 0x72, 0x15, 0xfc, 0x7a, 0x40, 0x84,
+ /*0350:*/ 0x24, 0x56, 0x76, 0xdd, 0x7b, 0xb8, 0xf6, 0xdc, 0x15, 0x01, 0x4a, 0x5f, 0x21, 0xae, 0xc0, 0xbd,
+ /*0360:*/ 0x14, 0x83, 0x35, 0x64, 0x54, 0x7d, 0xb5, 0x8b, 0xc6, 0x8d, 0xe0, 0x6a, 0xe4, 0x2b, 0x69, 0x49,
+ /*0370:*/ 0xd1, 0x0b, 0x17, 0x27, 0x09, 0x9a, 0x52, 0x82, 0x57, 0x90, 0x2f, 0x24, 0x43, 0xc3, 0x9d, 0x7d,
+ /*0380:*/ 0x31, 0x26, 0x6f, 0x54, 0x7d, 0xb6, 0x51, 0x15, 0x47, 0x4e, 0x9e, 0x96, 0x81, 0x29, 0xcb, 0xaa,
+ /*0390:*/ 0x01, 0xee, 0x77, 0x57, 0xc0, 0xf6, 0xb4, 0xe0, 0xd7, 0x90, 0xa9, 0x44, 0x2c, 0xe3, 0xa9, 0x32,
+ /*03a0:*/ 0x17, 0x3d, 0x5c, 0xe3, 0xc9, 0x82, 0xb2, 0x56, 0xb3, 0x9b, 0xda, 0xd6, 0x7c, 0x7d, 0x64, 0xd4,
+ /*03b0:*/ 0xe4, 0x39, 0x0d, 0xcc, 0xf3, 0x02, 0x59, 0xbe, 0x4b, 0x58, 0x4e, 0x1f, 0x47, 0x46, 0x55, 0x97,
+ /*03c0:*/ 0x67, 0xe7, 0xdc, 0x2f, 0xb1, 0x91, 0x81, 0x0b, 0x46, 0x97, 0x78, 0x25, 0x29, 0xb0, 0x7f, 0xa2,
+ /*03d0:*/ 0xb9, 0xfa, 0xf4, 0x20, 0x19, 0xab, 0xae, 0xf4, 0x7e, 0x74, 0x92, 0xf3, 0x63, 0x97, 0x05, 0xf4,
+ /*03e0:*/ 0x8c, 0xc8, 0xfb, 0xa7, 0x6f, 0xdf, 0x2d, 0xa8, 0x80, 0x17, 0x0c, 0x37, 0x6d, 0xe4, 0x97, 0x5b,
+ /*03f0:*/ 0xa4, 0x1d, 0xda, 0xb7, 0x45, 0xf0, 0xce, 0x7d, 0x31, 0xcc, 0xc2, 0x29, 0x37, 0xd1, 0x8c, 0x3d,
+ /*0400:*/ 0xcc, 0xa2, 0xf0, 0x70, 0x16, 0x9b, 0x87, 0xc6, 0x97, 0x20, 0x99, 0x8b, 0xb4, 0xb5, 0x39, 0xf7,
+ /*0410:*/ 0x7c, 0x7f, 0x86, 0x37, 0x79, 0x6e, 0x8b, 0x1b, 0xbf, 0xfb, 0x68, 0xd3, 0xf4, 0x61, 0x58, 0xe5,
+ /*0420:*/ 0x8a, 0xb0, 0xee, 0x70, 0x06, 0x18, 0x0c, 0x6b, 0x64, 0xf3, 0xb0, 0x64, 0x30, 0xee, 0xd3, 0xd1,
+ /*0430:*/ 0xa8, 0xe1, 0x30, 0xfc, 0x82, 0x36, 0x67, 0x93, 0x05, 0x6b, 0x4a, 0x33, 0x93, 0x5b, 0x8d, 0xdf,
+ /*0440:*/ 0xf4, 0x19, 0x3b, 0x85, 0xf0, 0x36, 0xf7, 0x50, 0xaa, 0x5e, 0xf7, 0x83, 0x93, 0x67, 0x78, 0x33,
+ /*0450:*/ 0x77, 0x3f, 0x9e, 0x34, 0x06, 0x6c, 0xcb, 0xc3, 0x00, 0x7f, 0xea, 0x39, 0x6d, 0xc5, 0x5e, 0x91,
+ /*0460:*/ 0xb1, 0x00, 0xbe, 0x6f, 0x08, 0x96, 0x01, 0xe4, 0xcb, 0x9f, 0x92, 0x79, 0x50, 0xaa, 0xda, 0x1e,
+ /*0470:*/ 0xec, 0x12, 0x2b, 0x4b, 0x0a, 0xa3, 0xcf, 0x8c, 0x1f, 0x4b, 0x15, 0xee, 0xec, 0x18, 0xa6, 0xfe,
+ /*0480:*/ 0xd5, 0x73, 0x82, 0x1d, 0x6e, 0x21, 0x8c, 0xe5, 0xf4, 0x36, 0x83, 0x9e, 0x00, 0x7b, 0x60, 0x9f,
+ /*0490:*/ 0x0d, 0xb4, 0x60, 0x70, 0xe0, 0x99, 0xc6, 0x55, 0xb9, 0xee, 0x3e, 0x24, 0x06, 0x15, 0x79, 0x0d,
+ /*04a0:*/ 0xa6, 0xc7, 0x79, 0x97, 0x01, 0x5c, 0x52, 0x38, 0xfa, 0x5b, 0x71, 0x38, 0xfa, 0xbf, 0xa0, 0x2c,
+ /*04b0:*/ 0x2c, 0x9d, 0x25, 0xfa, 0x70, 0xd7, 0x32, 0xb1, 0x33, 0xb6, 0xcd, 0xcd, 0xcd, 0xf6, 0x97, 0x3b,
+ /*04c0:*/ 0x3b, 0x0a, 0x33, 0xbb, 0x7a, 0xa5, 0x89, 0x14, 0xa6, 0x15, 0x44, 0xdb, 0x91, 0x07, 0x75, 0x48,
+ /*04d0:*/ 0xd5, 0x45, 0x46, 0x71, 0x1c, 0xf2, 0x12, 0xbc, 0x61, 0x70, 0x50, 0x56, 0xd3, 0x21, 0x5d, 0xc4,
+ /*04e0:*/ 0x29, 0x9f, 0x04, 0xfe, 0xe8, 0xdb, 0x77, 0x42, 0xde, 0xf3, 0xef, 0x2b, 0xfb, 0x34, 0xe7, 0x00,
+ /*04f0:*/ 0x8a, 0x50, 0x40, 0x3f, 0x62, 0x3d, 0x94, 0x49, 0xd2, 0x95, 0x27, 0xec, 0x86, 0xcd, 0xa2, 0x05,
+ /*0500:*/ 0xac, 0xfe, 0xb0, 0x83, 0xee, 0x52, 0x05, 0x7c, 0x40, 0x27, 0x4b, 0xc7, 0x93, 0xaa, 0x92, 0xce,
+ /*0510:*/ 0x72, 0x70, 0x8d, 0x9a, 0x5b, 0x88, 0x6b, 0x59, 0xa7, 0x61, 0xf7, 0x12, 0xe8, 0x61, 0xb6, 0x23,
+ /*0520:*/ 0xe8, 0xd3, 0xfc, 0x6a, 0xec, 0x4a, 0x05, 0xcd, 0x49, 0x74, 0xf4, 0xcb, 0x0e, 0xe3, 0x95, 0x95,
+ /*0530:*/ 0x0e, 0xc3, 0xd7, 0x9e, 0xb6, 0x6e, 0xcb, 0x4f, 0xdc, 0xe3, 0x3d, 0x87, 0x23, 0x3a, 0xc8, 0x8d,
+ /*0540:*/ 0x4f, 0x7b, 0xd8, 0xe9, 0x12, 0x46, 0x92, 0x0c, 0x75, 0xe0, 0x6b, 0x35, 0xf1, 0x82, 0xbc, 0xbb,
+ /*0550:*/ 0x09, 0x3f, 0xf9, 0xa7, 0xb6, 0x29, 0x62, 0x64, 0x09, 0x02, 0x5b, 0xf7, 0x47, 0xac, 0x69, 0xe5,
+ /*0560:*/ 0xb9, 0x7a, 0x6a, 0x7b, 0xb1, 0xad, 0xf4, 0x5f, 0xa4, 0x2c, 0x31, 0x06, 0x69, 0x63, 0x25, 0x32,
+ /*0570:*/ 0x75, 0x35, 0x95, 0x06, 0x41, 0xf8, 0x40, 0xce, 0x35, 0x2c, 0xad, 0x9b, 0xfb, 0xc0, 0x87, 0xed,
+ /*0580:*/ 0xe9, 0xd9, 0xe1, 0x65, 0x45, 0xc1, 0x98, 0x87, 0x0f, 0x2d, 0xc9, 0x38, 0xbc, 0x24, 0xdb, 0xa7,
+ /*0590:*/ 0x51, 0xae, 0x04, 0xa8, 0x3e, 0x1f, 0xab, 0xd4, 0xbb, 0x00, 0x08, 0x93, 0xc3, 0xcf, 0x15, 0x94,
+ /*05a0:*/ 0x2c, 0xd9, 0xa4, 0x0f, 0xb1, 0xc4, 0xda, 0xc6, 0xac, 0x24, 0x17, 0x8a, 0xda, 0xab, 0x4e, 0xa7,
+ /*05b0:*/ 0xeb, 0xeb, 0xc2, 0xdd, 0x01, 0x51, 0xfd, 0xc2, 0xf9, 0x3a, 0x2b, 0x97, 0x19, 0x3f, 0x1a, 0x84,
+ /*05c0:*/ 0x65, 0x14, 0xd6, 0xac, 0xf8, 0xbd, 0xe5, 0xa3, 0xb4, 0x19, 0x4b, 0xbe, 0x02, 0xe7, 0x71, 0xff,
+ /*05d0:*/ 0x14, 0xbe, 0xfa, 0x49, 0x20, 0x50, 0x74, 0x43, 0x68, 0x23, 0x86, 0x4b, 0xe3, 0xbe, 0x4d, 0x16,
+ /*05e0:*/ 0x93, 0xd0, 0xcf, 0xa5, 0x5a, 0x56, 0x0a, 0x4e, 0x05, 0xf0, 0x24, 0xf0, 0xe9, 0xbb, 0xf3, 0xd2,
+ /*05f0:*/ 0xcf, 0xaa, 0x1d, 0x6b, 0x99, 0x31, 0x79, 0xd8, 0x26, 0xc8, 0x0a, 0xa4, 0x32, 0xb1, 0xe2, 0x0c,
+ /*0600:*/ 0xaa, 0xb4, 0xe0, 0x05, 0xc4, 0x60, 0xb9, 0xdf, 0xad, 0x95, 0x51, 0x29, 0xbc, 0xa8, 0xcb, 0xae,
+ /*0610:*/ 0xc3, 0x75, 0xbf, 0x42, 0x8f, 0x02, 0xe8, 0xf1, 0x74, 0x2a, 0x93, 0x98, 0xce, 0x7e, 0x13, 0xd5,
+ /*0620:*/ 0xd6, 0x2c, 0xd5, 0x08, 0x45, 0xe2, 0x6d, 0xe1, 0x2a, 0x63, 0x8d, 0xa4, 0x3e, 0xab, 0x73, 0x6d,
+ /*0630:*/ 0x4c, 0x06, 0xf8, 0x44, 0x5a, 0xb1, 0x65, 0x0f, 0x1d, 0xf3, 0xcd, 0xf2, 0x3e, 0xde, 0xa2, 0x12,
+ /*0640:*/ 0xe6, 0x1c, 0xbd, 0x84, 0x65, 0x13, 0xb5, 0x3c, 0x9a, 0xa8, 0x17, 0xc3, 0x9e, 0xb4, 0xab, 0x52,
+ /*0650:*/ 0x30, 0x4c, 0x0a, 0xc2, 0xff, 0x20, 0x4b, 0xb4, 0x8e, 0xf9, 0x4a, 0xb6, 0x21, 0xaa, 0x47, 0x68,
+ /*0660:*/ 0x61, 0x6f, 0x81, 0x0e, 0x36, 0xe7, 0x19, 0x2f, 0x68, 0xbb, 0x18, 0x29, 0xdd, 0xf1, 0xc3, 0x57,
+ /*0670:*/ 0x9a, 0xe0, 0x66, 0x47, 0xda, 0xe2, 0x24, 0x27, 0xb7, 0x75, 0x6d, 0x99, 0x5f, 0x94, 0x5b, 0xae,
+ /*0680:*/ 0x60, 0xde, 0xc2, 0x2a, 0xd5, 0x36, 0x24, 0x61, 0x6a, 0x39, 0x08, 0x32, 0x18, 0x04, 0x41, 0x0f,
+ /*0690:*/ 0x24, 0xc2, 0x4a, 0x5f, 0xa2, 0x32, 0xf6, 0x8a, 0xe4, 0x03, 0x9e, 0x85, 0xb0, 0xe6, 0x5b, 0xeb,
+ /*06a0:*/ 0x15, 0x21, 0xce, 0xc7, 0xdc, 0x90, 0xfb, 0x22, 0x94, 0xf1, 0x77, 0x1b, 0x60, 0x17, 0x97, 0x6e,
+ /*06b0:*/ 0x19, 0x51, 0xde, 0xf6, 0x73, 0xa5, 0xf1, 0xf5, 0x71, 0xc5, 0xa2, 0x44, 0x61, 0x20, 0xe3, 0x08,
+ /*06c0:*/ 0x82, 0xd6, 0x9f, 0xfe, 0xdb, 0x11, 0x10, 0xfb, 0x38, 0x72, 0x9e, 0x3a, 0x1b, 0xa2, 0x28, 0xdb,
+ /*06d0:*/ 0x37, 0xef, 0xaf, 0x13, 0x6b, 0xde, 0x35, 0xa3, 0xc0, 0x42, 0x2c, 0xd3, 0xe0, 0x11, 0xe9, 0xe4,
+ /*06e0:*/ 0x94, 0x9c, 0x1e, 0xe4, 0x01, 0x02, 0x22, 0x8c, 0x13, 0x27, 0xda, 0xe6, 0x30, 0x61, 0x67, 0xca,
+ /*06f0:*/ 0x40, 0x87, 0x06, 0xce, 0x72, 0xa7, 0x14, 0x15, 0xa7, 0xe6, 0xa3, 0x7c, 0x51, 0xb7, 0xdd, 0x3e,
+ /*0700:*/ 0x2b, 0x8c, 0x7d, 0x56, 0x86, 0xb8, 0x3e, 0x17, 0xe8, 0x73, 0xce, 0xe8, 0x4a, 0xd9, 0xac, 0x9b,
+ /*0710:*/ 0x2b, 0x09, 0x3a, 0xb0, 0xb3, 0x96, 0xad, 0x98, 0xfd, 0x55, 0xdc, 0x0f, 0xf0, 0x1c, 0xaa, 0x8a,
+ /*0720:*/ 0xba, 0x6a, 0xfb, 0xf1, 0xac, 0x36, 0x35, 0x02, 0x42, 0x85, 0x6a, 0x81, 0x41, 0x78, 0xe1, 0x75,
+ /*0730:*/ 0xc2, 0x55, 0x5e, 0x15, 0x4c, 0x99, 0x22, 0xcc, 0x19, 0xc4, 0x91, 0x32, 0x80, 0x70, 0xa6, 0x7a,
+ /*0740:*/ 0x76, 0xa4, 0xfb, 0xfb, 0xa3, 0x94, 0x5d, 0xc7, 0x01, 0x92, 0x9a, 0xc7, 0xc1, 0x6f, 0x0e, 0x20,
+ /*0750:*/ 0xbc, 0x3d, 0x84, 0xf7, 0xa9, 0xe5, 0x6d, 0x72, 0x8c, 0x8a, 0x82, 0xfc, 0x53, 0x80, 0xdf, 0x34,
+ /*0760:*/ 0x82, 0xff, 0x69, 0xcb, 0x33, 0xbc, 0xeb, 0x6c, 0xe4, 0xbd, 0x9d, 0xc4, 0x67, 0xdc, 0x25, 0x55,
+ /*0770:*/ 0x51, 0xb5, 0x5f, 0xf5, 0x5c, 0xe4, 0x35, 0xfc, 0x55, 0xe5, 0x2d, 0xdf, 0x51, 0x2c, 0xcc, 0x28,
+ /*0780:*/ 0xaa, 0xe4, 0x7b, 0x5f, 0x87, 0x2a, 0x79, 0x48, 0xf3, 0xf6, 0xaf, 0x22, 0xf1, 0xe3, 0x62, 0x29,
+ /*0790:*/ 0x31, 0x65, 0x87, 0xef, 0x97, 0xa7, 0x18, 0xf6, 0xf4, 0xc7, 0x71, 0x5d, 0x53, 0xd5, 0x1b, 0x20,
+ /*07a0:*/ 0x4f, 0x15, 0x4b, 0x20, 0x3a, 0x5d, 0x37, 0xbb, 0x90, 0x80, 0xf3, 0xc2, 0xd0, 0x37, 0xb0, 0xe9,
+ /*07b0:*/ 0xad, 0xab, 0x28, 0xf4, 0x20, 0x23, 0x3d, 0x53, 0x68, 0xff, 0x00, 0x39, 0x99, 0x17, 0xde, 0xd1,
+ /*07c0:*/ 0x0d, 0x8d, 0xd9, 0x84, 0x03, 0xb9, 0x2b, 0x20, 0x8c, 0x98, 0x00, 0xbf, 0x59, 0x9c, 0xe8, 0xba,
+ /*07d0:*/ 0x29, 0x3f, 0xf8, 0x5c, 0x5b, 0xd2, 0xf3, 0x76, 0xf6, 0xac, 0x0b, 0x9e, 0x8d, 0xf4, 0x2a, 0xb2,
+ /*07e0:*/ 0x4e, 0xaf, 0xb9, 0xe9, 0xd1, 0xb3, 0x40, 0xa6, 0x08, 0xc5, 0x1a, 0x31, 0xb4, 0xd8, 0x05, 0x24,
+ /*07f0:*/ 0xdf, 0x29, 0xf0, 0xc0, 0xf6, 0x90, 0x0f, 0x0c, 0x72, 0xdb, 0x4d, 0x32, 0xbe, 0xd6, 0x72, 0x57,
+ /*0800:*/ 0xe3, 0xc3, 0xaa, 0x3c, 0x4b, 0x12, 0xea, 0xc8, 0xf6, 0xb8, 0x0f, 0xdf, 0xa9, 0x21, 0x8a, 0x20,
+ /*0810:*/ 0xfc, 0x2a, 0x14, 0xa0, 0x9d, 0xb4, 0xea, 0xbf, 0x09, 0xbe, 0xca, 0x32, 0xff, 0xd8, 0xfc, 0x91,
+ /*0820:*/ 0x2c, 0xf4, 0x58, 0x67, 0x79, 0x4a, 0xb7, 0x0f, 0x9d, 0x30, 0xf9, 0x8d, 0xbd, 0xaf, 0x28, 0x3b,
+ /*0830:*/ 0xdf, 0x8b, 0xa2, 0x83, 0xb1, 0xef, 0x3a, 0x1a, 0x8e, 0xff, 0x59, 0x1b, 0x25, 0xf7, 0x0f, 0x30,
+ /*0840:*/ 0x34, 0xc4, 0xbe, 0x4a, 0x41, 0xc4, 0x37, 0xf9, 0x59, 0x07, 0x42, 0x20, 0x28, 0xac, 0xca, 0x32,
+ /*0850:*/ 0xed, 0xd2, 0x03, 0x06, 0xa7, 0x96, 0x69, 0xb7, 0xe9, 0xde, 0xc8, 0x28, 0x06, 0xd8, 0x4d, 0xe7,
+ /*0860:*/ 0xab, 0xd5, 0xef, 0x00, 0x0f, 0x45, 0x50, 0xfb, 0x50, 0xbf, 0x79, 0x7d, 0xdc, 0x50, 0xa9, 0xec,
+ /*0870:*/ 0xbb, 0x92, 0x31, 0xce, 0x44, 0x9c, 0x06, 0x33, 0x8f, 0x39, 0x74, 0x74, 0xf4, 0x6c, 0xd6, 0xa6,
+ /*0880:*/ 0x8f, 0x50, 0x2b, 0x09, 0x1e, 0xeb, 0x31, 0x98, 0xc6, 0xfc, 0xfc, 0x40, 0x45, 0x45, 0x85, 0x82,
+ /*0890:*/ 0xa9, 0x4d, 0xd0, 0xfa, 0xd1, 0xe6, 0x0c, 0xda, 0x0a, 0x59, 0x2b, 0x7d, 0x9e, 0x93, 0x4e, 0x41,
+ /*08a0:*/ 0xce, 0x96, 0xc9, 0x9a, 0x7b, 0xd4, 0x83, 0xe8, 0x43, 0xdb, 0xb5, 0x6d, 0xe8, 0x1a, 0xa6, 0xe8,
+ /*08b0:*/ 0xf0, 0x5f, 0x7f, 0xf3, 0x40, 0x2c, 0x86, 0xbb, 0x7e, 0xfc, 0xa2, 0x64, 0xef, 0x99, 0xc8, 0xb7,
+ /*08c0:*/ 0x71, 0x9a, 0x4e, 0xd8, 0xe8, 0x16, 0x5d, 0x29, 0x7d, 0x76, 0x08, 0xdf, 0x0d, 0xde, 0x6b, 0x16,
+ /*08d0:*/ 0x29, 0xbd, 0xce, 0x46, 0x65, 0x85, 0xc8, 0xcd, 0xf4, 0x39, 0xa5, 0xa6, 0x87, 0xa8, 0x18, 0x85,
+ /*08e0:*/ 0x6b, 0x60, 0xd7, 0x94, 0xcd, 0x21, 0x04, 0x18, 0x73, 0x58, 0xb3, 0xd4, 0x88, 0x0a, 0xd0, 0x33,
+ /*08f0:*/ 0x70, 0xe7, 0x80, 0x18, 0x22, 0x48, 0xc4, 0xce, 0x53, 0xac, 0x96, 0x2d, 0xb3, 0x65, 0xd3, 0x6b,
+ /*0900:*/ 0x1f, 0xb9, 0xb4, 0xd9, 0x24, 0xf0, 0x13, 0x4d, 0xcc, 0x5e, 0x6d, 0xe8, 0x80, 0xce, 0xc8, 0xe4,
+ /*0910:*/ 0xb3, 0x56, 0x91, 0x7a, 0x27, 0xb0, 0x1a, 0x32, 0x55, 0x49, 0xa0, 0xc4, 0xa5, 0x44, 0xf0, 0xb4,
+ /*0920:*/ 0x8a, 0x35, 0x0b, 0x45, 0x37, 0xf5, 0x3c, 0xe4, 0x89, 0x46, 0x1a, 0x56, 0xea, 0xc0, 0xd3, 0x8e,
+ /*0930:*/ 0x65, 0x90, 0x7b, 0x8d, 0x32, 0x65, 0x51, 0x89, 0x8d, 0x96, 0xab, 0x98, 0xb1, 0xd6, 0x71, 0x6e,
+ /*0940:*/ 0x46, 0xf2, 0x33, 0xe9, 0x37, 0x14, 0xf7, 0x11, 0xd4, 0xa8, 0xbf, 0x2a, 0x22, 0xe9, 0xc7, 0xbd,
+ /*0950:*/ 0xad, 0x08, 0x95, 0x73, 0xb4, 0x5e, 0x1f, 0x92, 0xfa, 0x9a, 0x1a, 0xe9, 0x77, 0x22, 0xce, 0xa6,
+ /*0960:*/ 0xd2, 0xc5, 0xa3, 0xf9, 0x41, 0xd8, 0x88, 0x0b, 0xe2, 0x28, 0xf1, 0x7c, 0xda, 0x84, 0x71, 0xd1,
+ /*0970:*/ 0x00, 0x30, 0x6d, 0x6e, 0x6c, 0xba, 0x38, 0xcd, 0x51, 0x20, 0xe2, 0x85, 0x30, 0xc1, 0x4f, 0xba,
+ /*0980:*/ 0x8a, 0x89, 0xf2, 0x50, 0x43, 0xf6, 0x1b, 0x4a, 0xa7, 0x2e, 0x8b, 0x67, 0xc4, 0x6d, 0x32, 0x9a,
+ /*0990:*/ 0xba, 0xfb, 0xa7, 0xb2, 0x3f, 0xa3, 0x2d, 0xc6, 0x7c, 0x64, 0x94, 0xde, 0xcf, 0x27, 0x86, 0x90,
+ /*09a0:*/ 0xc7, 0xd5, 0xa3, 0x36, 0xa6, 0x10, 0xcb, 0xcd, 0x58, 0x53, 0x0b, 0xa6, 0xb4, 0x46, 0x2a, 0xf7,
+ /*09b0:*/ 0x28, 0x63, 0x6a, 0x4f, 0x0e, 0xd6, 0x48, 0x3f, 0x93, 0x09, 0x12, 0xb6, 0xd7, 0x4f, 0x59, 0x96,
+ /*09c0:*/ 0xf9, 0xa7, 0x31, 0x0f, 0x59, 0xe1, 0x27, 0xf1, 0x66, 0x99, 0xe7, 0xb4, 0x04, 0xdb, 0xb0, 0xa0,
+ /*09d0:*/ 0x41, 0x1c, 0x98, 0x4c, 0xed, 0x04, 0x19, 0x06, 0xd0, 0x4a, 0x94, 0xef, 0x17, 0xf0, 0x65, 0x5b,
+ /*09e0:*/ 0x47, 0x2e, 0x64, 0x59, 0xb4, 0x45, 0x26, 0x37, 0x21, 0x5a, 0x8a, 0x11, 0xda, 0x41, 0x71, 0x87,
+ /*09f0:*/ 0x43, 0x3d, 0xe7, 0xb9, 0xaf, 0x7e, 0x81, 0x81, 0xc9, 0xd1, 0xf1, 0x0f, 0x62, 0xcc, 0x35, 0xef,
+ /*0a00:*/ 0x8d, 0xee, 0x9d, 0x7a, 0x57, 0xa0, 0xad, 0x9b, 0x40, 0xc8, 0x28, 0xbf, 0xa8, 0xf4, 0xf5, 0x37,
+ /*0a10:*/ 0x60, 0xdb, 0xdb, 0xc8, 0xe5, 0xd1, 0x7b, 0xbc, 0x53, 0x43, 0x8b, 0xf8, 0x10, 0xbe, 0x9d, 0x56,
+ /*0a20:*/ 0x14, 0x75, 0xcc, 0x66, 0x5b, 0x8c, 0x2b, 0x33, 0xaf, 0xa6, 0xe4, 0x08, 0x29, 0xf6, 0x50, 0x7a,
+ /*0a30:*/ 0x0d, 0x11, 0xa1, 0xea, 0x30, 0x49, 0x98, 0x8b, 0xa6, 0x4d, 0x29, 0x73, 0x7d, 0xfa, 0x87, 0xc9,
+ /*0a40:*/ 0x6a, 0x13, 0xfa, 0x75, 0xa0, 0x5a, 0x89, 0xc0, 0xb4, 0x64, 0x96, 0x79, 0x42, 0x6f, 0x30, 0xef,
+ /*0a50:*/ 0x13, 0x1b, 0xe7, 0x44, 0xec, 0x55, 0xb1, 0x77, 0xa6, 0xd9, 0x63, 0x09, 0xc3, 0x29, 0x95, 0x5f,
+ /*0a60:*/ 0xee, 0x92, 0xb6, 0x6e, 0xb4, 0xfd, 0xf2, 0x48, 0x35, 0x13, 0x2c, 0xb7, 0x34, 0xd8, 0x2d, 0x6e,
+ /*0a70:*/ 0xce, 0x21, 0xda, 0xe8, 0x71, 0x86, 0x3a, 0x34, 0x80, 0x5d, 0x59, 0xd5, 0x32, 0x99, 0x95, 0x52,
+ /*0a80:*/ 0x83, 0xd5, 0x7b, 0xd5, 0xa7, 0xa3, 0x52, 0x48, 0x92, 0xdc, 0x1f, 0x34, 0x84, 0x72, 0x08, 0x5a,
+ /*0a90:*/ 0xce, 0xb7, 0x02, 0xea, 0xd1, 0x75, 0x39, 0xe2, 0xa5, 0xae, 0x72, 0x56, 0x2b, 0xcc, 0xd1, 0xc8,
+ /*0aa0:*/ 0x95, 0x54, 0x34, 0x35, 0x94, 0x80, 0xdb, 0x62, 0xbf, 0x1f, 0xe0, 0xbc, 0x0f, 0x43, 0xce, 0xce,
+ /*0ab0:*/ 0x64, 0xfe, 0xbe, 0x7d, 0xe1, 0xc6, 0x81, 0xfe, 0xa6, 0x2b, 0xd7, 0x02, 0x10, 0x83, 0x03, 0xb6,
+ /*0ac0:*/ 0x4d, 0x59, 0x5f, 0x12, 0x39, 0x90, 0x2d, 0x0c, 0xd8, 0x29, 0xbc, 0xae, 0xed, 0x41, 0x66, 0x37,
+ /*0ad0:*/ 0x2c, 0x90, 0xf7, 0xba, 0xf8, 0x09, 0x20, 0x3f, 0x38, 0xd4, 0x7a, 0x24, 0x7b, 0x1a, 0x8b, 0xc6,
+ /*0ae0:*/ 0x69, 0x2b, 0x4d, 0x15, 0xb3, 0xd7, 0x79, 0x5f, 0x87, 0xe5, 0x48, 0x5d, 0x2a, 0x89, 0x85, 0xd7,
+ /*0af0:*/ 0x96, 0xf9, 0x39, 0x91, 0xdb, 0x3d, 0x9e, 0x5b, 0x39, 0xe8, 0x3a, 0x29, 0x4c, 0xd1, 0x22, 0xce,
+ /*0b00:*/ 0x3f, 0xa4, 0xf3, 0xad, 0x28, 0xc2, 0xee, 0xa3, 0x27, 0x19, 0x0a, 0x86, 0x13, 0xeb, 0xcc, 0xc8,
+ /*0b10:*/ 0x69, 0xbf, 0x46, 0xf7, 0xe4, 0x6d, 0xf8, 0x31, 0xbb, 0xd7, 0x45, 0xfd, 0x0a, 0x68, 0xee, 0x2b,
+ /*0b20:*/ 0xb5, 0x71, 0xb2, 0xad, 0x5b, 0x80, 0x5e, 0x69, 0x58, 0x11, 0x6a, 0xea, 0x30, 0x88, 0x33, 0xec,
+ /*0b30:*/ 0xa9, 0xed, 0x2f, 0x8c, 0x95, 0x30, 0xec, 0x4a, 0xc1, 0x47, 0xbd, 0xd0, 0x60, 0x8c, 0x23, 0x0f,
+ /*0b40:*/ 0x9e, 0x11, 0x62, 0xc6, 0xc2, 0xb4, 0xc6, 0x43, 0x4c, 0xa6, 0x66, 0xe8, 0xbc, 0xed, 0x57, 0xfb,
+ /*0b50:*/ 0x6d, 0x73, 0x80, 0xd3, 0x5f, 0xe1, 0x90, 0x27, 0xd5, 0x32, 0x20, 0x9d, 0x1f, 0x72, 0x5d, 0xad,
+ /*0b60:*/ 0xdc, 0xb3, 0x3d, 0x86, 0x75, 0x95, 0x1b, 0x34, 0x52, 0x46, 0x66, 0x58, 0xf6, 0x9a, 0xd7, 0x06,
+ /*0b70:*/ 0xf0, 0x40, 0x64, 0x55, 0x74, 0xa5, 0x70, 0x56, 0x17, 0x71, 0xe7, 0xee, 0xf8, 0x18, 0x77, 0xdd,
+ /*0b80:*/ 0x23, 0x78, 0x01, 0xde, 0x3d, 0x5b, 0x97, 0xd1, 0x35, 0x00, 0x94, 0xd9, 0x12, 0xe3, 0x7b, 0x66,
+ /*0b90:*/ 0xac, 0x58, 0xdb, 0xe8, 0xb0, 0x41, 0x83, 0x3e, 0x7c, 0xdc, 0x04, 0x41, 0x2f, 0xf5, 0x89, 0xce,
+ /*0ba0:*/ 0xbd, 0xf6, 0xa9, 0x95, 0x20, 0x62, 0x66, 0x5d, 0x6a, 0x1d, 0x08, 0xca, 0x44, 0x80, 0x7e, 0xb0,
+ /*0bb0:*/ 0xfd, 0x45, 0x82, 0x92, 0x80, 0x52, 0x99, 0x90, 0x16, 0x59, 0xd1, 0x29, 0xa1, 0xf2, 0x56, 0x84,
+ /*0bc0:*/ 0xa4, 0x5d, 0xdd, 0x82, 0x27, 0x80, 0x17, 0x84, 0x1f, 0x6e, 0x71, 0xb0, 0x7c, 0xb8, 0x39, 0xf6,
+ /*0bd0:*/ 0x9e, 0x55, 0xe6, 0x85, 0xa6, 0x20, 0x56, 0x6b, 0x8e, 0x4e, 0xd5, 0xd1, 0x93, 0xa3, 0xf8, 0x01,
+ /*0be0:*/ 0xc5, 0x04, 0x73, 0x76, 0xdd, 0x79, 0x03, 0x50, 0xc3, 0x6f, 0x89, 0x53, 0x97, 0x3e, 0xf9, 0xa4,
+ /*0bf0:*/ 0xfa, 0xf8, 0xd6, 0x43, 0xcd, 0x98, 0x0d, 0x69, 0xf0, 0xff, 0xa3, 0xd6, 0xb9, 0xa6, 0x0a, 0x59,
+ /*0c00:*/ 0x87, 0x45, 0x5e, 0x1c, 0x0d, 0x5c, 0xc3, 0x30, 0x1c, 0x69, 0xd0, 0x26, 0xc4, 0x64, 0x9f, 0xd9,
+ /*0c10:*/ 0xd3, 0xad, 0xbe, 0x19, 0xfd, 0x77, 0x71, 0xdb, 0xa4, 0x60, 0x93, 0x6c, 0x7e, 0xc5, 0x11, 0x41,
+ /*0c20:*/ 0xab, 0x40, 0xa7, 0x57, 0x70, 0x4b, 0xac, 0x56, 0x21, 0x3e, 0xb7, 0xc3, 0x1e, 0x25, 0xf9, 0xab,
+ /*0c30:*/ 0x86, 0x8b, 0x56, 0xf1, 0x62, 0x37, 0x24, 0xe3, 0x38, 0xb3, 0x51, 0xa8, 0xcb, 0xaa, 0x09, 0xe8,
+ /*0c40:*/ 0x81, 0xa2, 0x9e, 0xc6, 0x4e, 0xbe, 0x7b, 0xfd, 0x96, 0x13, 0xb5, 0x2d, 0x7c, 0xf1, 0xa8, 0xf6,
+ /*0c50:*/ 0x3d, 0x01, 0x2d, 0x8a, 0x8d, 0xf7, 0x8c, 0x0e, 0x6a, 0xf0, 0x00, 0x32, 0xe0, 0x8a, 0xe8, 0xa6,
+ /*0c60:*/ 0x7a, 0x78, 0xad, 0xcb, 0xef, 0xc8, 0xfe, 0x06, 0x74, 0x04, 0x00, 0xf5, 0xc7, 0xf5, 0x00, 0xca,
+ /*0c70:*/ 0x9d, 0x50, 0x57, 0x95, 0x29, 0x13, 0x34, 0xe0, 0xa6, 0xad, 0x81, 0x09, 0x9f, 0x76, 0xc1, 0xde,
+ /*0c80:*/ 0x1b, 0x17, 0xd4, 0x9d, 0xa0, 0x68, 0x1e, 0x6d, 0xd8, 0x3a, 0xe3, 0xa8, 0x9b, 0xfd, 0x55, 0x37,
+ /*0c90:*/ 0xb9, 0xfb, 0x04, 0x17, 0x8c, 0x91, 0xcc, 0x51, 0xdf, 0x96, 0x51, 0x8d, 0x26, 0x1c, 0x38, 0x0c,
+ /*0ca0:*/ 0x74, 0x42, 0x6a, 0x48, 0xdb, 0xb0, 0xed, 0xca, 0x95, 0xa5, 0x07, 0x76, 0x39, 0xaa, 0x9d, 0xc1,
+ /*0cb0:*/ 0xf0, 0xe3, 0x71, 0xce, 0x8c, 0x09, 0x88, 0x63, 0x15, 0x6d, 0x15, 0x3a, 0xdb, 0xaf, 0xad, 0x8f,
+ /*0cc0:*/ 0x63, 0x64, 0x37, 0x65, 0x63, 0x19, 0x7f, 0x63, 0x8a, 0xb6, 0x21, 0xc9, 0x0b, 0xd3, 0x78, 0x0d,
+ /*0cd0:*/ 0x21, 0x08, 0x6e, 0x66, 0xf7, 0xd8, 0xfa, 0xdf, 0x1e, 0x67, 0xae, 0xa3, 0x0b, 0xa8, 0xfb, 0xab,
+ /*0ce0:*/ 0xa6, 0xcb, 0x28, 0x74, 0x47, 0x8e, 0x76, 0xb7, 0xf5, 0xe5, 0x8b, 0xe9, 0x90, 0x26, 0x78, 0xe8,
+ /*0cf0:*/ 0x88, 0x1a, 0x9b, 0xd6, 0x07, 0xe1, 0x4d, 0xe9, 0xc6, 0xc2, 0x3c, 0x42, 0xa5, 0x7c, 0x03, 0xb1,
+ /*0d00:*/ 0x40, 0xd8, 0xec, 0xdf, 0x63, 0x90, 0x38, 0x13, 0x17, 0x9a, 0x34, 0x93, 0x93, 0x7d, 0x17, 0x82,
+ /*0d10:*/ 0xac, 0x78, 0x36, 0x21, 0x8b, 0x13, 0x33, 0xe0, 0xb7, 0xc7, 0xf3, 0x35, 0xff, 0xd7, 0xf5, 0x18,
+ /*0d20:*/ 0xdc, 0x8f, 0xe9, 0xd3, 0x63, 0xf4, 0x69, 0x5a, 0xc2, 0xf7, 0x70, 0x1d, 0xd6, 0x2e, 0x24, 0x31,
+ /*0d30:*/ 0x03, 0x3f, 0x71, 0xc5, 0x1b, 0xa1, 0x0a, 0xa0, 0xaa, 0xfb, 0xd3, 0xc4, 0x2d, 0x0c, 0x5d, 0xb4,
+ /*0d40:*/ 0xf4, 0x69, 0xa2, 0x82, 0xe5, 0xd7, 0x2b, 0x2c, 0xf6, 0x08, 0x1d, 0xb2, 0x14, 0x98, 0x66, 0xc1,
+ /*0d50:*/ 0x15, 0x0d, 0xc9, 0xcc, 0x1d, 0xc2, 0x54, 0x9b, 0x80, 0x27, 0xec, 0x27, 0x70, 0x4b, 0x5c, 0xee,
+ /*0d60:*/ 0xc0, 0xd3, 0x3c, 0x68, 0x50, 0x00, 0xf5, 0x80, 0x56, 0x46, 0xc3, 0x30, 0x97, 0xca, 0x5e, 0x72,
+ /*0d70:*/ 0x50, 0x1d, 0xb2, 0x82, 0x22, 0x73, 0x6f, 0x01, 0xf9, 0xcc, 0x98, 0xf6, 0xc5, 0xdc, 0x75, 0x2e,
+ /*0d80:*/ 0xa6, 0x96, 0x75, 0x75, 0xf1, 0x61, 0x58, 0x2c, 0x9f, 0x7e, 0x5f, 0xba, 0x7b, 0xe3, 0xfa, 0x47,
+ /*0d90:*/ 0xf7, 0x8e, 0xc1, 0x0f, 0xeb, 0xf2, 0x7a, 0x4e, 0x35, 0x09, 0x60, 0xf0, 0x38, 0xeb, 0x57, 0x5e,
+ /*0da0:*/ 0xa3, 0x3f, 0x77, 0x3f, 0xc4, 0xcc, 0xf4, 0xf8, 0xc5, 0x33, 0x19, 0x8e, 0xc8, 0x4a, 0xd1, 0xe5,
+ /*0db0:*/ 0x17, 0x70, 0xdb, 0xf7, 0x7d, 0xbc, 0x7d, 0xe0, 0x2b, 0x7e, 0x10, 0x66, 0x51, 0x47, 0x64, 0xf9,
+ /*0dc0:*/ 0x62, 0xcf, 0x37, 0xbb, 0x92, 0xf5, 0xb3, 0xdf, 0x11, 0x37, 0x93, 0x81, 0x6f, 0xd8, 0xb4, 0x74,
+ /*0dd0:*/ 0x09, 0xcb, 0x36, 0x9e, 0x44, 0xe5, 0xce, 0x3e, 0xfb, 0x3b, 0xaa, 0x1b, 0xfc, 0x46, 0x7b, 0xe6,
+ /*0de0:*/ 0xb0, 0x86, 0x46, 0xbf, 0xf5, 0xc2, 0xa2, 0xdc, 0x5c, 0x91, 0xa7, 0x9f, 0x1b, 0xdd, 0x9f, 0x58,
+ /*0df0:*/ 0x12, 0x44, 0xfe, 0x55, 0x85, 0xc3, 0xfc, 0x12, 0x13, 0x3e, 0xf3, 0x7b, 0xd7, 0x47, 0x4d, 0x26,
+ /*0e00:*/ 0x93, 0x32, 0x45, 0x16, 0xd0, 0x03, 0x66, 0x23, 0xe2, 0x4f, 0x92, 0x21, 0x3c, 0x18, 0x9f, 0x2e,
+ /*0e10:*/ 0xdd, 0xec, 0x8f, 0xeb, 0x3b, 0xef, 0x26, 0xef, 0x35, 0x98, 0xf3, 0x26, 0x90, 0x3d, 0x01, 0x46,
+ /*0e20:*/ 0xc4, 0x3d, 0x49, 0x19, 0xc2, 0xc7, 0xc5, 0x57, 0xf1, 0xd4, 0x1d, 0x63, 0xb3, 0xe3, 0xec, 0x29,
+ /*0e30:*/ 0xb7, 0x8c, 0xa6, 0xb7, 0xae, 0x63, 0x79, 0x5e, 0xc8, 0x02, 0xde, 0x38, 0x4d, 0xee, 0x6e, 0x7e,
+ /*0e40:*/ 0x0f, 0x70, 0xe2, 0xc0, 0x23, 0x83, 0xf6, 0xd7, 0x9e, 0x53, 0xd5, 0x44, 0x96, 0xb1, 0xfe, 0x0c,
+ /*0e50:*/ 0xbb, 0x00, 0x6a, 0xb3, 0xab, 0xeb, 0x31, 0xae, 0x6e, 0x63, 0xed, 0x91, 0x16, 0x44, 0x43, 0xd4,
+ /*0e60:*/ 0x2d, 0xf3, 0x7a, 0x95, 0x5c, 0x93, 0xa9, 0x44, 0x91, 0x7c, 0xb0, 0xc7, 0xdd, 0x92, 0x1c, 0xde,
+ /*0e70:*/ 0xa6, 0xc3, 0xf1, 0x58, 0x4d, 0x25, 0xcd, 0x88, 0x1a, 0x54, 0xbe, 0x50, 0x2b, 0x9a, 0xfb, 0xbc,
+ /*0e80:*/ 0xd6, 0x4d, 0x59, 0x2d, 0xcd, 0x76, 0x16, 0x3c, 0x1c, 0xfd, 0x7a, 0xae, 0x41, 0xae, 0xfa, 0x95,
+ /*0e90:*/ 0xd6, 0xb8, 0x8b, 0xac, 0xa9, 0xee, 0x93, 0x2a, 0x55, 0x21, 0x4b, 0x6c, 0x1a, 0x28, 0x2f, 0x8d,
+ /*0ea0:*/ 0x9c, 0x42, 0xd0, 0xb0, 0x21, 0x90, 0x0a, 0xce, 0xa5, 0x55, 0x6d, 0x52, 0x8e, 0xb7, 0x98, 0xad,
+ /*0eb0:*/ 0xd4, 0xdf, 0x48, 0x48, 0x71, 0x7a, 0x66, 0x4a, 0xb2, 0x45, 0x17, 0xab, 0x5b, 0x91, 0x05, 0x7f,
+ /*0ec0:*/ 0x72, 0xf3, 0xd3, 0x89, 0x1f, 0x81, 0x1f, 0xd4, 0xe8, 0x38, 0x5d, 0x68, 0x24, 0xca, 0x5e, 0xe1,
+ /*0ed0:*/ 0xd4, 0x9e, 0xac, 0x17, 0x09, 0x0e, 0x88, 0x70, 0x7a, 0xae, 0xc1, 0xc8, 0x94, 0xf5, 0x6b, 0x21,
+ /*0ee0:*/ 0x69, 0xc5, 0xd2, 0xb6, 0x0b, 0xc7, 0x2e, 0x27, 0x0b, 0xf2, 0xfd, 0x74, 0x8b, 0xd6, 0xd9, 0x7d,
+ /*0ef0:*/ 0xcd, 0x58, 0x38, 0x20, 0xc8, 0x68, 0x48, 0x08, 0xbd, 0x18, 0x69, 0x0a, 0x4f, 0x04, 0x4e, 0xcf,
+ /*0f00:*/ 0x43, 0x7c, 0x6f, 0x11, 0x86, 0x5b, 0xbb, 0x5b, 0x25, 0x76, 0x77, 0xf0, 0x7b, 0xbd, 0xc7, 0xd2,
+ /*0f10:*/ 0x2c, 0x47, 0xf3, 0x13, 0x3c, 0xfd, 0xbc, 0xa3, 0x80, 0x22, 0xcf, 0x18, 0x92, 0x36, 0x09, 0x9a,
+ /*0f20:*/ 0x96, 0x72, 0x05, 0xb3, 0x67, 0xa2, 0x2a, 0xee, 0x1c, 0x7c, 0x84, 0x37, 0x1c, 0x0d, 0xaa, 0x02,
+ /*0f30:*/ 0xcd, 0xf6, 0xc6, 0x65, 0x14, 0x2d, 0xcd, 0x18, 0x42, 0xc2, 0x3f, 0xee, 0x09, 0xcd, 0x57, 0xf9,
+ /*0f40:*/ 0xdd, 0xa9, 0xd4, 0xf1, 0xb3, 0x97, 0x9f, 0xf7, 0xb7, 0x4a, 0x39, 0x9c, 0xb5, 0x64, 0xd2, 0x66,
+ /*0f50:*/ 0x58, 0x78, 0x69, 0x65, 0xfa, 0x21, 0xfd, 0x1e, 0x0f, 0xe2, 0x37, 0x57, 0xf9, 0x8d, 0x56, 0x34,
+ /*0f60:*/ 0x76, 0xb4, 0x07, 0xa4, 0x9b, 0xf4, 0x27, 0xf0, 0x26, 0x95, 0x23, 0xf5, 0x6a, 0x35, 0x99, 0x52,
+ /*0f70:*/ 0xac, 0x40, 0x51, 0xd2, 0xf2, 0x2b, 0x22, 0x54, 0xff, 0x45, 0xda, 0x84, 0x1e, 0x72, 0x53, 0xa3,
+ /*0f80:*/ 0xb2, 0x9e, 0xc0, 0x6e, 0x68, 0x62, 0xa1, 0x8a, 0x74, 0xa9, 0x90, 0xfa, 0x19, 0xd0, 0x25, 0x13,
+ /*0f90:*/ 0xd0, 0x3b, 0x59, 0xcd, 0x85, 0x5e, 0xc4, 0x4b, 0x7b, 0x3c, 0xd4, 0xc1, 0x91, 0xa9, 0xc0, 0xce,
+ /*0fa0:*/ 0x5a, 0xa6, 0xc0, 0x84, 0x0c, 0xea, 0xd5, 0xeb, 0xad, 0x6c, 0x81, 0x12, 0xb4, 0x3d, 0xac, 0x20,
+ /*0fb0:*/ 0xcc, 0x4c, 0x82, 0xa0, 0xc3, 0x77, 0x01, 0x20, 0xeb, 0xc0, 0xd5, 0x86, 0xa0, 0x79, 0x1f, 0x75,
+ /*0fc0:*/ 0x27, 0xf6, 0xd4, 0xae, 0x45, 0x0f, 0x42, 0x36, 0x7f, 0x96, 0x8a, 0x9a, 0x6d, 0x65, 0xa7, 0xa3,
+ /*0fd0:*/ 0x8b, 0x6a, 0xea, 0xb6, 0x72, 0xb8, 0x37, 0x3f, 0x3f, 0x64, 0x64, 0x84, 0xa3, 0x68, 0x44, 0x7a,
+ /*0fe0:*/ 0x10, 0xe6, 0x9c, 0x54, 0x54, 0x6b, 0xc9, 0x83, 0x88, 0x49, 0x71, 0x25, 0x7a, 0x01, 0x36, 0x15,
+ /*0ff0:*/ 0x8e, 0x84, 0x8c, 0x41, 0x8a, 0x07, 0xc3, 0x9a, 0x87, 0x16, 0x52, 0xe8, 0xe7, 0x49, 0xd3, 0xc8,
+ /*1000:*/ 0x8c, 0x4a, 0xfe, 0xd9, 0xd2, 0x8c, 0xac, 0x45, 0xf2, 0xc5, 0x57, 0x73, 0xf7, 0x47, 0x1c, 0x1d,
+ /*1010:*/ 0x33, 0x2a, 0x16, 0x87, 0xf2, 0xfc, 0xec, 0xcd, 0x41, 0x8f, 0x5e, 0xa4, 0x40, 0x75, 0x75, 0x33,
+ /*1020:*/ 0xcd, 0x40, 0x13, 0x77, 0xa6, 0xb7, 0x3a, 0xf4, 0xd5, 0x5c, 0x3d, 0x9e, 0xdc, 0xd2, 0x31, 0x4f,
+ /*1030:*/ 0x6a, 0x4f, 0xae, 0x9b, 0xa4, 0xe7, 0xb6, 0xb9, 0x3c, 0x87, 0x02, 0x5f, 0x48, 0xbe, 0x87, 0xa7,
+ /*1040:*/ 0x92, 0x52, 0x8f, 0x72, 0x15, 0xbe, 0xce, 0x65, 0xfe, 0x1d, 0x9e, 0xf8, 0x9f, 0xc3, 0x8e, 0x57,
+ /*1050:*/ 0xbf, 0xa7, 0xe6, 0x8f, 0xb1, 0x50, 0x8c, 0x19, 0x42, 0x8a, 0x4b, 0x6f, 0x4f, 0xcf, 0xe6, 0xd5,
+ /*1060:*/ 0x0d, 0xa3, 0xe7, 0x02, 0x2a, 0x35, 0x17, 0xc5, 0x74, 0xab, 0xa0, 0x6d, 0xee, 0x58, 0x35, 0x10,
+ /*1070:*/ 0xc6, 0xb6, 0xf1, 0x9b, 0xe2, 0x1e, 0xfc, 0xb8, 0x95, 0xcb, 0xbb, 0xb2, 0x0a, 0xc2, 0x1c, 0x67,
+ /*1080:*/ 0xa3, 0x1d, 0x62, 0x44, 0x96, 0xdb, 0x36, 0xf0, 0xfd, 0xd2, 0x48, 0x98, 0x92, 0xdc, 0xec, 0xf4,
+ /*1090:*/ 0x44, 0x81, 0xf8, 0x3a, 0x6f, 0x1e, 0x24, 0x14, 0x26, 0x0c, 0x15, 0x74, 0xf1, 0x45, 0x8d, 0xfb,
+ /*10a0:*/ 0xee, 0x32, 0x61, 0x72, 0x28, 0x41, 0xc4, 0x12, 0xc0, 0x37, 0xca, 0x7f, 0x70, 0x86, 0xce, 0xf5,
+ /*10b0:*/ 0x34, 0xcf, 0xc6, 0x99, 0x5a, 0x74, 0xc9, 0xad, 0xce, 0x7d, 0x35, 0x80, 0x00, 0x47, 0xbf, 0xdd,
+ /*10c0:*/ 0x49, 0x42, 0xde, 0x17, 0xf1, 0xf2, 0x77, 0x1f, 0x3e, 0x47, 0x7e, 0x18, 0x2a, 0xb5, 0xae, 0x43,
+ /*10d0:*/ 0x46, 0x7d, 0xa9, 0x10, 0xfa, 0x0a, 0xca, 0x54, 0xf6, 0x03, 0xe0, 0xa2, 0xd3, 0xe5, 0x2b, 0xca,
+ /*10e0:*/ 0xe5, 0x3b, 0x46, 0xb6, 0xe2, 0x0e, 0x36, 0x71, 0x68, 0xaf, 0x51, 0xc3, 0xd9, 0xeb, 0x64, 0x60,
+ /*10f0:*/ 0x78, 0x2c, 0xfc, 0x5f, 0x73, 0x1f, 0xa0, 0x8a, 0xa5, 0xe5, 0xc3, 0x90, 0x3e, 0xc8, 0x83, 0x56,
+ /*1100:*/ 0xda, 0x17, 0xee, 0x23, 0x3b, 0x7a, 0x6d, 0xfe, 0xef, 0xa9, 0xe8, 0x92, 0xc5, 0xa5, 0xd7, 0x5e,
+ /*1110:*/ 0x11, 0x18, 0xd8, 0xf5, 0x1c, 0xd8, 0x1d, 0x9b, 0x0b, 0x79, 0x91, 0xa3, 0x02, 0x7d, 0xa3, 0x0f,
+ /*1120:*/ 0xc2, 0xcc, 0xb0, 0x0d, 0xfc, 0x7e, 0xbd, 0x1b, 0xee, 0x42, 0x90, 0x65, 0x20, 0xd8, 0xad, 0x41,
+ /*1130:*/ 0x6b, 0xba, 0xb0, 0xeb, 0xaa, 0xa4, 0x1b, 0x80, 0x97, 0xa7, 0x88, 0x2e, 0xdc, 0xfd, 0x55, 0x65,
+ /*1140:*/ 0xe9, 0xf1, 0xb6, 0x9a, 0x27, 0xca, 0x23, 0x30, 0x46, 0x3e, 0x6f, 0x0c, 0x57, 0xc3, 0xd7, 0xca,
+ /*1150:*/ 0xe3, 0x99, 0xe6, 0x09, 0xa1, 0x5c, 0x72, 0xd8, 0x65, 0x08, 0x21, 0xfe, 0xb0, 0x48, 0xc9, 0xf9,
+ /*1160:*/ 0x42, 0xad, 0xda, 0x11, 0x70, 0x56, 0x0a, 0xa5, 0x3b, 0xd9, 0xee, 0xc7, 0x30, 0x9b, 0x23, 0xd9,
+ /*1170:*/ 0xa0, 0x82, 0x8d, 0xe0, 0x77, 0x67, 0x4a, 0x85, 0x8b, 0x52, 0x9a, 0x16, 0xf1, 0x6a, 0x74, 0x96,
+ /*1180:*/ 0xf7, 0xfe, 0xa6, 0x83, 0x72, 0xb6, 0x82, 0x78, 0x44, 0xd7, 0x51, 0x70, 0x92, 0x8e, 0x64, 0xc3,
+ /*1190:*/ 0x8c, 0x92, 0x18, 0xc9, 0x7a, 0x4d, 0x7e, 0xd1, 0x11, 0x53, 0xa6, 0x14, 0xed, 0x9c, 0x04, 0x01,
+ /*11a0:*/ 0xdb, 0x9f, 0xfd, 0x38, 0xc7, 0xf0, 0xb0, 0x70, 0x96, 0x7a, 0x67, 0xdc, 0x19, 0xeb, 0xaf, 0xf9,
+ /*11b0:*/ 0x25, 0x1f, 0xbc, 0xc0, 0xa4, 0xa8, 0x05, 0x7b, 0x9e, 0xd5, 0xe8, 0x1c, 0xe3, 0x71, 0xab, 0x92,
+ /*11c0:*/ 0xc9, 0xb4, 0xac, 0xb0, 0xe0, 0xf1, 0x59, 0x0b, 0x58, 0x3e, 0xca, 0x9d, 0x3e, 0xd0, 0xae, 0xeb,
+ /*11d0:*/ 0x51, 0xf0, 0x3c, 0xc0, 0xb9, 0x0b, 0xda, 0xba, 0x6b, 0xd8, 0x1f, 0x97, 0x68, 0x75, 0xbc, 0x88,
+ /*11e0:*/ 0x44, 0x5c, 0x37, 0xc7, 0x0c, 0xd7, 0xf1, 0x1d, 0x03, 0xe8, 0x0e, 0xa6, 0xae, 0xd0, 0x66, 0xa4,
+ /*11f0:*/ 0xd1, 0xf5, 0x52, 0xc8, 0x7b, 0x1e, 0xfe, 0x4b, 0x5d, 0xdd, 0xca, 0xad, 0x21, 0xde, 0x28, 0xf4,
+ /*1200:*/ 0x98, 0x98, 0x9c, 0xd2, 0x62, 0xd7, 0x00, 0xde, 0x6a, 0xf1, 0xa1, 0xe4, 0x1c, 0xaf, 0x1f, 0x9b,
+ /*1210:*/ 0x90, 0x8a, 0x40, 0x9d, 0x78, 0x64, 0x75, 0x60, 0xaa, 0xc7, 0xce, 0x63, 0x65, 0x1e, 0x65, 0x74,
+ /*1220:*/ 0x9b, 0x37, 0xb2, 0xb7, 0x54, 0xc5, 0x6d, 0xce, 0x1d, 0x08, 0x3a, 0x01, 0x07, 0xc1, 0x80, 0x21,
+ /*1230:*/ 0x1e, 0x25, 0xbe, 0x97, 0xbb, 0x53, 0x3f, 0x8a, 0xcf, 0x1c, 0xfe, 0x7f, 0x93, 0xfb, 0x0c, 0x5a,
+ /*1240:*/ 0x52, 0xf2, 0x63, 0xba, 0xd0, 0xa5, 0x5b, 0xd8, 0x98, 0xb8, 0x95, 0xd4, 0xc8, 0xb1, 0x04, 0x99,
+ /*1250:*/ 0x83, 0xb4, 0xcb, 0xe4, 0x3a, 0xea, 0x02, 0x5e, 0x88, 0x6e, 0xfd, 0xf8, 0x79, 0x5f, 0x03, 0x99,
+ /*1260:*/ 0x56, 0xea, 0x25, 0xc8, 0x08, 0x1b, 0x6a, 0x8d, 0x28, 0xe6, 0x08, 0x47, 0x67, 0xf5, 0xc7, 0x52,
+ /*1270:*/ 0x60, 0x08, 0x42, 0x5f, 0x58, 0x01, 0x0a, 0xf2, 0xa3, 0xa3, 0x1e, 0x91, 0x17, 0x5d, 0xe8, 0xe4,
+ /*1280:*/ 0x14, 0x10, 0x67, 0xc3, 0x1c, 0x3e, 0x71, 0x23, 0x45, 0xf3, 0xc9, 0x73, 0xc9, 0xc5, 0x94, 0x67,
+ /*1290:*/ 0x51, 0x22, 0xa5, 0xf9, 0x45, 0xce, 0x35, 0x20, 0xf7, 0xf7, 0x1a, 0xea, 0x52, 0x25, 0x17, 0xb1,
+ /*12a0:*/ 0xec, 0xc5, 0x4e, 0xe9, 0x03, 0x8f, 0xc2, 0x0c, 0xa3, 0x00, 0xd9, 0xe8, 0xe8, 0xb2, 0xbe, 0xaf,
+ /*12b0:*/ 0xcb, 0xda, 0xf8, 0xbe, 0x2d, 0x2e, 0x92, 0x23, 0x3b, 0x9b, 0x27, 0x65, 0x7f, 0x03, 0xc7, 0x8e,
+ /*12c0:*/ 0x9c, 0x86, 0x66, 0xf4, 0x67, 0xb4, 0x7b, 0x7d, 0x44, 0x73, 0x8e, 0x7e, 0x32, 0x87, 0x58, 0xa9,
+ /*12d0:*/ 0xcf, 0x92, 0xc8, 0x07, 0x41, 0xc5, 0x41, 0x17, 0x34, 0xed, 0x3b, 0xd6, 0x30, 0xca, 0x66, 0x50,
+ /*12e0:*/ 0x4a, 0x1e, 0x68, 0xcc, 0x91, 0xe2, 0x78, 0x38, 0xfc, 0x04, 0x72, 0xfb, 0xbb, 0x63, 0x4f, 0x30,
+ /*12f0:*/ 0xc2, 0xbb, 0x4a, 0xd5, 0xc9, 0x0e, 0x53, 0xc7, 0x5c, 0x83, 0x1d, 0xc0, 0x42, 0x22, 0xfa, 0xba,
+ /*1300:*/ 0x31, 0xfa, 0x85, 0x75, 0x8e, 0x7b, 0x1b, 0x63, 0x2a, 0x13, 0x2a, 0x33, 0x01, 0x86, 0xc0, 0xdd,
+ /*1310:*/ 0xfd, 0x14, 0xc5, 0x84, 0x9b, 0xcc, 0xa5, 0x89, 0x31, 0x27, 0x6e, 0x3b, 0xc6, 0xb0, 0xf2, 0x23,
+ /*1320:*/ 0x61, 0x52, 0x5b, 0x3a, 0xf2, 0x63, 0x3a, 0xc2, 0x6e, 0xaf, 0x98, 0x97, 0x5c, 0xbc, 0xd4, 0xf3,
+ /*1330:*/ 0xd4, 0x98, 0x25, 0x73, 0xc6, 0xbb, 0x64, 0x85, 0x88, 0x95, 0x0d, 0xcb, 0xaa, 0xfd, 0x57, 0x9c,
+ /*1340:*/ 0xa8, 0x4f, 0x32, 0xa4, 0xce, 0xf0, 0x0d, 0x1c, 0xac, 0x9a, 0x53, 0x84, 0xb8, 0x4e, 0x48, 0xc0,
+ /*1350:*/ 0xfb, 0xc2, 0x48, 0x1e, 0x76, 0xb4, 0xf2, 0x7c, 0xde, 0xe1, 0xc4, 0xf4, 0xb7, 0x09, 0x19, 0x7e,
+ /*1360:*/ 0x0d, 0x40, 0x92, 0xa3, 0x4e, 0x14, 0xcf, 0x15, 0x17, 0x6c, 0x81, 0x55, 0xaa, 0xce, 0xa6, 0x8b,
+ /*1370:*/ 0xbf, 0xd6, 0x30, 0x06, 0xa0, 0x1b, 0x18, 0x40, 0xca, 0x69, 0xab, 0xe2, 0x3e, 0xa5, 0xf2, 0x85,
+ /*1380:*/ 0x43, 0x54, 0x76, 0x5d, 0xe3, 0x96, 0xd4, 0x39, 0x47, 0x70, 0x1a, 0x71, 0x94, 0xcd, 0x9d, 0xfa,
+ /*1390:*/ 0xb0, 0x89, 0xab, 0x7a, 0x2e, 0x49, 0xb5, 0x34, 0x66, 0xbb, 0xdc, 0x6e, 0x5a, 0x1d, 0x65, 0x20,
+ /*13a0:*/ 0xce, 0x49, 0x1d, 0xeb, 0x73, 0x83, 0x00, 0x05, 0xb0, 0x5a, 0x56, 0xc3, 0xa5, 0x0f, 0x03, 0xb0,
+ /*13b0:*/ 0xdb, 0xb5, 0xf0, 0x61, 0x2c, 0xfd, 0x37, 0x38, 0x7d, 0xf8, 0xc4, 0x09, 0xd0, 0xf3, 0xdc, 0x62,
+ /*13c0:*/ 0xca, 0x29, 0x71, 0xb9, 0x44, 0xc4, 0x24, 0x21, 0xc5, 0xfe, 0x9c, 0xd9, 0xd4, 0x89, 0x44, 0x00,
+ /*13d0:*/ 0x20, 0xae, 0xd9, 0xae, 0xd6, 0xea, 0x5d, 0x04, 0x35, 0x4c, 0x09, 0x47, 0xfa, 0x85, 0x7f, 0x1e,
+ /*13e0:*/ 0x52, 0x62, 0xb7, 0x8a, 0x05, 0xc5, 0x47, 0x39, 0x2d, 0xe8, 0xf0, 0xf7, 0x57, 0x67, 0xf5, 0xda,
+ /*13f0:*/ 0x47, 0xe9, 0x10, 0x84, 0xb4, 0xf9, 0x3f, 0x8d, 0xae, 0xdd, 0xce, 0x76, 0xc9, 0xfe, 0x0b, 0x52,
+ /*1400:*/ 0x63, 0x1d, 0xde, 0x2a, 0x25, 0x54, 0x9c, 0xab, 0x2b, 0x52, 0x30, 0x8c, 0x80, 0xe8, 0x50, 0xe0,
+ /*1410:*/ 0x2b, 0x6b, 0xf5, 0x42, 0xbc, 0x26, 0x85, 0x9f, 0xd3, 0x9a, 0xbe, 0x41, 0xd2, 0xf1, 0xa6, 0xd7,
+ /*1420:*/ 0xf2, 0xcd, 0x72, 0xab, 0x8d, 0x4c, 0x46, 0x7b, 0xaf, 0x82, 0x58, 0xd7, 0x2f, 0x16, 0x07, 0x28,
+ /*1430:*/ 0xf0, 0x3a, 0x7e, 0x85, 0xc3, 0xf3, 0xe8, 0xe5, 0x00, 0x06, 0x00, 0xb5, 0x97, 0x19, 0x9f, 0xde,
+ /*1440:*/ 0x99, 0x1f, 0xf5, 0x08, 0x97, 0x02, 0x6e, 0x60, 0xc5, 0xa7, 0x77, 0x99, 0xcf, 0x04, 0xa6, 0x2f,
+ /*1450:*/ 0xb5, 0xca, 0xff, 0x4b, 0xd7, 0xee, 0xcc, 0x90, 0x6c, 0x77, 0xac, 0x95, 0x3f, 0x24, 0xa5, 0x50,
+ /*1460:*/ 0x00, 0x9d, 0xf5, 0x7e, 0xed, 0x37, 0xa8, 0xd6, 0xd7, 0xf2, 0xf7, 0x14, 0xb8, 0x2e, 0x7e, 0x1f,
+ /*1470:*/ 0xa3, 0x02, 0xec, 0x4c, 0xf5, 0xc6, 0x7b, 0x03, 0x99, 0x3b, 0x9d, 0xaf, 0xad, 0xe2, 0x44, 0x7c,
+ /*1480:*/ 0x89, 0xd6, 0xd3, 0x09, 0x0c, 0xed, 0x48, 0x17, 0x3e, 0xcc, 0xce, 0x08, 0x1d, 0x2d, 0x47, 0x36,
+ /*1490:*/ 0xf8, 0x6c, 0x37, 0xcd, 0x7c, 0xc7, 0xf3, 0x06, 0x17, 0x8c, 0xca, 0xfe, 0x36, 0x4c, 0xb8, 0x10,
+ /*14a0:*/ 0x08, 0xe6, 0xd5, 0xa8, 0x99, 0x56, 0x48, 0xe0, 0x18, 0x44, 0x72, 0x63, 0x3d, 0x09, 0xd5, 0xd9,
+ /*14b0:*/ 0x5a, 0xe1, 0x4c, 0x38, 0xd1, 0xdc, 0x0b, 0x47, 0xd3, 0x8a, 0x1a, 0xf8, 0xe8, 0x75, 0x3b, 0x1a,
+ /*14c0:*/ 0x9c, 0xcb, 0x89, 0x37, 0xc4, 0xa6, 0xa3, 0xbe, 0xf6, 0xe5, 0x40, 0xd3, 0x44, 0x1d, 0xea, 0x92,
+ /*14d0:*/ 0xfa, 0xf2, 0xd6, 0x0d, 0x52, 0xf0, 0x8c, 0x0b, 0x3a, 0x55, 0x75, 0x7a, 0xfc, 0xef, 0x81, 0xdb,
+ /*14e0:*/ 0xc5, 0x97, 0x81, 0xe3, 0x32, 0xd8, 0x8a, 0x49, 0xf0, 0x14, 0x28, 0x14, 0xac, 0x7a, 0xc6, 0x21,
+ /*14f0:*/ 0xe2, 0xa9, 0x61, 0xc4, 0xa5, 0xd2, 0x8d, 0xd6, 0x36, 0xba, 0x4f, 0x20, 0x43, 0xeb, 0xac, 0xef,
+ /*1500:*/ 0x6a, 0x81, 0x0a, 0x54, 0x37, 0x35, 0x34, 0x09, 0xce, 0xdc, 0x78, 0x43, 0x00, 0xc5, 0x46, 0x0e,
+ /*1510:*/ 0x17, 0xb1, 0x7a, 0x51, 0x96, 0x54, 0xee, 0x24, 0x32, 0xf9, 0x09, 0x66, 0xff, 0xf6, 0xb9, 0x9f,
+ /*1520:*/ 0x06, 0xa4, 0x55, 0x8c, 0x3b, 0x9d, 0xcd, 0x31, 0x01, 0x33, 0x61, 0xeb, 0xd3, 0x45, 0x49, 0x34,
+ /*1530:*/ 0x2e, 0xff, 0xa3, 0x7f, 0xf5, 0xb0, 0x37, 0x00, 0x31, 0x84, 0xb1, 0xa1, 0x9f, 0xa4, 0xdb, 0xc7,
+ /*1540:*/ 0xa2, 0xd9, 0x23, 0x4c, 0xf0, 0x09, 0x57, 0x9b, 0x4b, 0xbc, 0x6b, 0xe4, 0x15, 0x55, 0x9f, 0x3d,
+ /*1550:*/ 0x97, 0xa6, 0xab, 0x0a, 0x86, 0xde, 0xd3, 0x83, 0xd2, 0x81, 0x21, 0x75, 0x60, 0x66, 0xd8, 0xa1,
+ /*1560:*/ 0xd0, 0xdb, 0x08, 0x42, 0xe6, 0xf1, 0xeb, 0x6f, 0x59, 0xe2, 0x0f, 0xd1, 0x00, 0x3a, 0x09, 0x86,
+ /*1570:*/ 0x61, 0x8f, 0x3c, 0x6d, 0x02, 0x48, 0x41, 0x1a, 0x9b, 0xcd, 0x33, 0xd6, 0xbe, 0x15, 0x88, 0x2a,
+ /*1580:*/ 0x94, 0xf9, 0xc9, 0xda, 0x03, 0xb3, 0x1c, 0xaa, 0x22, 0x19, 0xa9, 0x9e, 0xdd, 0xe7, 0x7e, 0x92,
+ /*1590:*/ 0xdf, 0x06, 0xd7, 0x0c, 0xe0, 0x19, 0xa8, 0xec, 0x9a, 0x33, 0xfa, 0x30, 0xa7, 0xe9, 0xc9, 0x3d,
+ /*15a0:*/ 0x6a, 0x14, 0x89, 0x5b, 0xe9, 0x19, 0xfd, 0xf5, 0xdb, 0xfe, 0x70, 0x4a, 0x09, 0x18, 0x9a, 0x90,
+ /*15b0:*/ 0x16, 0x88, 0xb2, 0x60, 0x6e, 0x34, 0xa5, 0x22, 0x7e, 0x2d, 0x5a, 0x37, 0x0e, 0xbe, 0x71, 0x7e,
+ /*15c0:*/ 0x5a, 0xd4, 0x38, 0x0b, 0x25, 0x49, 0x4d, 0x07, 0x47, 0xee, 0x3d, 0xfe, 0x8f, 0x81, 0xdb, 0xb2,
+ /*15d0:*/ 0xda, 0x0d, 0x71, 0xbc, 0x10, 0x36, 0x69, 0xd5, 0xec, 0xdd, 0x57, 0xc4, 0xeb, 0x52, 0xd6, 0x2c,
+ /*15e0:*/ 0xce, 0xaf, 0xe7, 0xae, 0xfa, 0xf6, 0x22, 0x8e, 0x72, 0x39, 0xcb, 0x48, 0x0f, 0x76, 0x9c, 0x51,
+ /*15f0:*/ 0x54, 0x7b, 0x7c, 0x2d, 0x5d, 0x4e, 0x54, 0x82, 0xf4, 0xfd, 0x6b, 0xdf, 0x97, 0xed, 0xec, 0x68,
+ /*1600:*/ 0xb7, 0x03, 0x26, 0x74, 0x46, 0xcc, 0x3f, 0x6d, 0x49, 0x52, 0xce, 0xe2, 0x82, 0x12, 0x79, 0x85,
+ /*1610:*/ 0x95, 0xb6, 0x4c, 0x9e, 0x61, 0xd9, 0xc4, 0xaa, 0xd6, 0xcd, 0x0b, 0xad, 0x78, 0xd8, 0xed, 0x07,
+ /*1620:*/ 0x5c, 0x8b, 0xe4, 0x1c, 0x86, 0x85, 0xf2, 0xee, 0x98, 0x81, 0x4f, 0xa9, 0x74, 0x22, 0xd5, 0x7f,
+ /*1630:*/ 0xf3, 0x48, 0xec, 0x30, 0xde, 0x23, 0x10, 0xa8, 0x6e, 0x1e, 0xbb, 0x6b, 0x31, 0xd1, 0x26, 0x48,
+ /*1640:*/ 0xac, 0x4a, 0x19, 0x66, 0xef, 0x2e, 0x5f, 0xd9, 0x7a, 0xc6, 0xfa, 0xc3, 0x06, 0xf0, 0xfe, 0x6c,
+ /*1650:*/ 0xd3, 0xf5, 0xdd, 0x6b, 0x09, 0x39, 0x17, 0x99, 0x29, 0xff, 0x24, 0x51, 0x3b, 0x06, 0x35, 0x92,
+ /*1660:*/ 0xda, 0x9f, 0x9f, 0x32, 0x40, 0x5c, 0x05, 0x60, 0x18, 0xd5, 0xb4, 0xd7, 0x9d, 0x7f, 0xd8, 0x5b,
+ /*1670:*/ 0x3e, 0x67, 0xee, 0xaa, 0x12, 0xd0, 0xd1, 0x61, 0x78, 0x60, 0x28, 0x63, 0xd8, 0x91, 0xe1, 0x86,
+ /*1680:*/ 0x78, 0x01, 0x62, 0x55, 0xa8, 0x5c, 0x7d, 0xf5, 0x80, 0x97, 0x16, 0xaa, 0xcc, 0x62, 0xec, 0x35,
+ /*1690:*/ 0x18, 0x53, 0xda, 0xfc, 0x3b, 0x5b, 0x2f, 0xe5, 0xd0, 0xb9, 0xba, 0x31, 0xed, 0xbe, 0xe0, 0xf1,
+ /*16a0:*/ 0xfa, 0x54, 0x8f, 0x1d, 0x1a, 0xfc, 0xfb, 0xe0, 0xbb, 0x30, 0x0c, 0x6a, 0xf7, 0x80, 0x27, 0xbb,
+ /*16b0:*/ 0xb2, 0xc3, 0x38, 0xb9, 0x01, 0x2c, 0x93, 0x00, 0xac, 0xb0, 0xef, 0x9a, 0x44, 0x7d, 0xfb, 0x0b,
+ /*16c0:*/ 0x91, 0x36, 0xac, 0xb7, 0x0a, 0xe9, 0x29, 0xdc, 0x82, 0x8a, 0x76, 0x75, 0x12, 0xec, 0x81, 0x20,
+ /*16d0:*/ 0x55, 0x2b, 0x67, 0x28, 0xa6, 0x1a, 0x73, 0xde, 0x82, 0xac, 0x0f, 0xa6, 0xd8, 0xa6, 0x96, 0xf7,
+ /*16e0:*/ 0xe6, 0x27, 0x33, 0xa3, 0x4d, 0x37, 0x66, 0xbd, 0xcf, 0xa3, 0x70, 0x4f, 0xae, 0xb3, 0x55, 0x92,
+ /*16f0:*/ 0x8b, 0x7c, 0x5f, 0xd3, 0x5e, 0x8a, 0x84, 0xf8, 0x30, 0x95, 0x16, 0xb5, 0xfc, 0xc2, 0x23, 0x25,
+ /*1700:*/ 0x65, 0xdb, 0x48, 0xcd, 0xfc, 0xc4, 0xbf, 0xca, 0xa3, 0xd3, 0x8b, 0xe4, 0x5c, 0x7a, 0x97, 0x5d,
+ /*1710:*/ 0xa8, 0xc5, 0xf9, 0x1a, 0x91, 0x60, 0x3b, 0x20, 0x77, 0xe7, 0x35, 0x99, 0x43, 0x47, 0x1c, 0x96,
+ /*1720:*/ 0x54, 0xeb, 0x9f, 0xc0, 0x7e, 0xb0, 0xcd, 0x9f, 0x62, 0xec, 0x5c, 0xd9, 0x37, 0xc8, 0x4d, 0x92,
+ /*1730:*/ 0xc0, 0x76, 0xfa, 0x3b, 0xbd, 0x4b, 0xd1, 0x1f, 0x43, 0xd9, 0x55, 0x7a, 0xb8, 0x7c, 0x7b, 0xa3,
+ /*1740:*/ 0x0c, 0x26, 0x5f, 0x6b, 0x7c, 0x38, 0xc2, 0x72, 0x36, 0xd7, 0xc0, 0x5c, 0x57, 0x69, 0xd1, 0x1a,
+ /*1750:*/ 0xc6, 0xda, 0x20, 0x3a, 0x2a, 0x43, 0x2b, 0x32, 0x86, 0x37, 0x8d, 0x44, 0x20, 0x0c, 0xcf, 0xb4,
+ /*1760:*/ 0xe8, 0x7b, 0x38, 0xc2, 0xea, 0x4f, 0xd2, 0xf3, 0xe0, 0x44, 0x11, 0xa4, 0x60, 0x11, 0xea, 0x09,
+ /*1770:*/ 0x3a, 0x04, 0x0b, 0xe8, 0xcc, 0x55, 0xbf, 0xa2, 0xe7, 0xee, 0x4e, 0xbf, 0xc6, 0x10, 0xbf, 0x0c,
+ /*1780:*/ 0xb9, 0x24, 0xa9, 0x8c, 0x46, 0x81, 0xc7, 0x44, 0x3e, 0x63, 0x50, 0xce, 0x4c, 0x91, 0xfc, 0xe8,
+ /*1790:*/ 0x2e, 0x97, 0x76, 0xc5, 0xf4, 0xd0, 0x36, 0x5a, 0x6c, 0x30, 0xfe, 0xc1, 0x02, 0x86, 0x07, 0xd3,
+ /*17a0:*/ 0xeb, 0x57, 0x6d, 0x43, 0xf9, 0xfa, 0xc7, 0x39, 0xd5, 0xfa, 0x70, 0xa4, 0x55, 0x7c, 0x4e, 0x93,
+ /*17b0:*/ 0xca, 0xd9, 0x78, 0xcb, 0xa2, 0x1d, 0x79, 0x96, 0x55, 0x16, 0x94, 0x8d, 0x74, 0xda, 0xa5, 0x1c,
+ /*17c0:*/ 0xf6, 0xa3, 0xcc, 0x33, 0x0e, 0x3a, 0x29, 0xa0, 0xf9, 0x7d, 0x8b, 0x13, 0x6e, 0x7f, 0x02, 0x4a,
+ /*17d0:*/ 0x50, 0xd3, 0x7c, 0x1e, 0x09, 0x3c, 0xd0, 0x03, 0xad, 0x0d, 0xb2, 0xfa, 0xa1, 0x8b, 0xd3, 0x69,
+ /*17e0:*/ 0x91, 0x7a, 0x6a, 0xe2, 0x66, 0x1a, 0xe4, 0x3d, 0xdf, 0xab, 0x3f, 0xfa, 0x39, 0xb3, 0x66, 0x0a,
+ /*17f0:*/ 0x80, 0x1a, 0x07, 0x75, 0xe6, 0xfd, 0x9b, 0x9b, 0xfe, 0xf0, 0x9c, 0x3f, 0x9e, 0x43, 0xc8, 0xe3,
+ /*1800:*/ 0xbd, 0xb4, 0x32, 0x25, 0x4f, 0x96, 0x8f, 0xba, 0x46, 0x34, 0xdc, 0x9e, 0x18, 0xe8, 0x16, 0x9a,
+ /*1810:*/ 0xc1, 0x8c, 0x41, 0x16, 0x2d, 0x88, 0x0b, 0x1d, 0x6f, 0x2a, 0xbf, 0x99, 0x85, 0x14, 0xa3, 0x89,
+ /*1820:*/ 0x86, 0xac, 0xf6, 0xe3, 0x7b, 0xcf, 0x48, 0xec, 0xe0, 0x74, 0xbc, 0x96, 0x95, 0x4d, 0x76, 0x1d,
+ /*1830:*/ 0x5e, 0x76, 0x49, 0x63, 0x62, 0x75, 0x21, 0x87, 0x4d, 0x62, 0xb3, 0xfe, 0x0b, 0xf5, 0xed, 0x8c,
+ /*1840:*/ 0x95, 0x9c, 0xd3, 0xc5, 0x5f, 0x14, 0xd8, 0x4e, 0x41, 0xaa, 0xd9, 0x1f, 0xb3, 0x67, 0x35, 0xaf,
+ /*1850:*/ 0x0d, 0x3a, 0xcb, 0xe5, 0xcc, 0x84, 0xc4, 0xab, 0x45, 0x38, 0xa9, 0x45, 0x66, 0x12, 0x75, 0x93,
+ /*1860:*/ 0xc0, 0x36, 0x42, 0x88, 0xb6, 0x5e, 0x3f, 0xae, 0x67, 0xe5, 0x5f, 0xe2, 0xc1, 0x93, 0xca, 0x84,
+ /*1870:*/ 0x55, 0xa1, 0xda, 0xec, 0x53, 0xe8, 0x74, 0xc2, 0xdb, 0x25, 0xdf, 0x8a, 0xfb, 0xfa, 0xf0, 0x14,
+ /*1880:*/ 0xf7, 0x92, 0x67, 0xbb, 0x0a, 0x5e, 0xfa, 0x53, 0x4f, 0x5f, 0xf9, 0x05, 0x7b, 0xbd, 0x02, 0x3e,
+ /*1890:*/ 0x30, 0xdf, 0x90, 0xef, 0x3d, 0x84, 0x0b, 0x71, 0x8b, 0x08, 0xc3, 0xae, 0xb7, 0xdb, 0xe1, 0x19,
+ /*18a0:*/ 0x56, 0x85, 0x65, 0x98, 0x53, 0x32, 0x4b, 0xe7, 0xd5, 0x01, 0x4f, 0x02, 0xf2, 0xa1, 0xb6, 0x61,
+ /*18b0:*/ 0xf9, 0xa2, 0xd1, 0xb0, 0xb7, 0x87, 0x21, 0x62, 0x60, 0x7a, 0x91, 0x14, 0x7a, 0x11, 0x6d, 0xb4,
+ /*18c0:*/ 0x79, 0x40, 0xa4, 0x9a, 0x6d, 0xcf, 0xe2, 0x6d, 0x8a, 0xd2, 0x7d, 0xfb, 0x2b, 0x11, 0xfa, 0x92,
+ /*18d0:*/ 0xe3, 0x6f, 0x47, 0x7f, 0xa2, 0x41, 0x3b, 0x90, 0x36, 0x68, 0x90, 0x96, 0xf3, 0xf5, 0x27, 0xeb,
+ /*18e0:*/ 0x99, 0x6b, 0x31, 0x5b, 0x94, 0x7d, 0xa6, 0x2d, 0xdf, 0xfd, 0xee, 0x2c, 0x54, 0x59, 0x1c, 0xb7,
+ /*18f0:*/ 0xa9, 0xd0, 0x9a, 0x43, 0x82, 0x05, 0x47, 0xba, 0x26, 0xe3, 0x7d, 0x98, 0xd9, 0x4e, 0xe9, 0xed,
+ /*1900:*/ 0xbb, 0x30, 0x27, 0xb0, 0xed, 0xc4, 0x95, 0xb5, 0x64, 0x98, 0x66, 0xe6, 0x44, 0x9d, 0x63, 0x3f,
+ /*1910:*/ 0xb8, 0xdd, 0x35, 0xed, 0x79, 0x9c, 0x30, 0xd0, 0x5a, 0xfc, 0x14, 0xcf, 0x6b, 0x05, 0x48, 0x5d,
+ /*1920:*/ 0x35, 0xd7, 0xd6, 0x8c, 0xce, 0xee, 0x21, 0x73, 0x01, 0xeb, 0x8a, 0x14, 0x01, 0x1c, 0xee, 0x8a,
+ /*1930:*/ 0xbc, 0x7a, 0xbb, 0xbb, 0x7b, 0x89, 0x8a, 0xfa, 0x6a, 0xf8, 0x90, 0x6f, 0x07, 0xba, 0x77, 0x7b,
+ /*1940:*/ 0x27, 0x01, 0xfd, 0x67, 0x52, 0xcf, 0xf5, 0xc2, 0xa7, 0x2d, 0x79, 0xbf, 0x50, 0x7a, 0xc9, 0x1c,
+ /*1950:*/ 0x6a, 0x6f, 0x38, 0xa1, 0x76, 0x80, 0x22, 0x01, 0xa8, 0x4e, 0x6c, 0x8d, 0x64, 0x55, 0x63, 0x89,
+ /*1960:*/ 0xf8, 0xe4, 0x59, 0x37, 0xf7, 0xae, 0x6b, 0x61, 0x98, 0x7e, 0x43, 0xdd, 0xba, 0xf0, 0x07, 0x28,
+ /*1970:*/ 0x91, 0xe7, 0x8a, 0xf7, 0xe4, 0xaa, 0x86, 0x0b, 0x26, 0x1e, 0x3c, 0x45, 0x9b, 0x84, 0xd0, 0xe0,
+ /*1980:*/ 0xcf, 0x81, 0x1b, 0x61, 0x9b, 0xef, 0xde, 0x8c, 0xc0, 0xa4, 0x83, 0xe7, 0x31, 0x18, 0xf1, 0x66,
+ /*1990:*/ 0x2d, 0x65, 0x6f, 0x2e, 0xfb, 0x60, 0x99, 0xa4, 0xbd, 0x20, 0x6b, 0x83, 0xe6, 0x2d, 0x93, 0xbc,
+ /*19a0:*/ 0x9b, 0xce, 0xa5, 0x1e, 0x9b, 0xda, 0xb4, 0x69, 0x89, 0xb9, 0x42, 0x3a, 0x1a, 0xcc, 0x13, 0x7f,
+ /*19b0:*/ 0x5e, 0xc6, 0xa2, 0x4c, 0x8a, 0x82, 0xc0, 0x19, 0x2f, 0xe0, 0xac, 0x58, 0xb4, 0xbc, 0x69, 0x2f,
+ /*19c0:*/ 0x11, 0xa2, 0x85, 0x0b, 0x72, 0x32, 0x74, 0x83, 0x11, 0x58, 0xe0, 0x7a, 0xce, 0x55, 0xda, 0x6e,
+ /*19d0:*/ 0x2f, 0xe9, 0x6c, 0x62, 0xdc, 0xbd, 0x89, 0x0d, 0xfd, 0x7a, 0x32, 0xb9, 0x28, 0x7a, 0xc2, 0xb6,
+ /*19e0:*/ 0x10, 0x67, 0xf1, 0x6a, 0xe2, 0x04, 0x17, 0x9d, 0x2d, 0xe0, 0xde, 0xc3, 0xad, 0xff, 0xb6, 0x4b,
+ /*19f0:*/ 0x11, 0x3d, 0x53, 0x21, 0x6a, 0xe6, 0x30, 0xad, 0x15, 0x7d, 0x13, 0x28, 0x3c, 0xea, 0x29, 0x32,
+ /*1a00:*/ 0xa7, 0xb6, 0x67, 0x07, 0x1f, 0x0e, 0x72, 0xe8, 0xd7, 0xcf, 0x59, 0xb5, 0x68, 0xf4, 0xb6, 0x81,
+ /*1a10:*/ 0xed, 0xf5, 0xb8, 0xab, 0xfb, 0xee, 0x6c, 0x94, 0xff, 0x03, 0xa9, 0xc8, 0x1a, 0x30, 0x9b, 0x16,
+ /*1a20:*/ 0xff, 0x9b, 0x40, 0x57, 0x70, 0x9f, 0xb9, 0xcb, 0xf6, 0x79, 0x88, 0xee, 0x3f, 0xf1, 0xa0, 0x8d,
+ /*1a30:*/ 0x67, 0x26, 0x90, 0x71, 0x84, 0x34, 0xce, 0x7b, 0xaa, 0x83, 0xd1, 0x00, 0x33, 0xfd, 0x4d, 0x86,
+ /*1a40:*/ 0x55, 0x53, 0xc0, 0x6b, 0x3a, 0x44, 0xd8, 0xdb, 0x40, 0x24, 0xb8, 0xef, 0x7d, 0x2b, 0x7d, 0x03,
+ /*1a50:*/ 0x79, 0xaf, 0x0f, 0x86, 0x21, 0x4e, 0x41, 0xc6, 0x60, 0x21, 0x8e, 0x58, 0x26, 0x1b, 0x72, 0xfe,
+ /*1a60:*/ 0x71, 0x21, 0x0e, 0xa1, 0xd6, 0xf7, 0x41, 0x50, 0x68, 0xca, 0x3f, 0x62, 0xdf, 0xd1, 0x41, 0xe1,
+ /*1a70:*/ 0xdc, 0xc2, 0x7f, 0x82, 0xd8, 0x6e, 0x3e, 0xf9, 0x30, 0xee, 0x71, 0xcd, 0x1f, 0x0f, 0x4f, 0xb3,
+ /*1a80:*/ 0x03, 0xfb, 0x20, 0x75, 0x91, 0x1a, 0xbf, 0xb0, 0xc1, 0xc4, 0x65, 0x4b, 0x65, 0x52, 0x2a, 0x13,
+ /*1a90:*/ 0xb1, 0xb1, 0xc8, 0xe1, 0x9e, 0xc5, 0x78, 0x40, 0xae, 0xf6, 0x57, 0x12, 0xc9, 0x49, 0x24, 0xee,
+ /*1aa0:*/ 0x87, 0x6b, 0xa0, 0x0c, 0x0f, 0xb1, 0xbe, 0xac, 0xcb, 0x8b, 0xe9, 0x3f, 0x1b, 0xaa, 0x79, 0x9f,
+ /*1ab0:*/ 0xc4, 0xff, 0xac, 0xf9, 0xf7, 0x53, 0xab, 0xa8, 0xf2, 0x00, 0xc0, 0xa4, 0x24, 0x22, 0x97, 0x58,
+ /*1ac0:*/ 0x0c, 0x39, 0x96, 0xe2, 0xe9, 0xcf, 0x62, 0xcb, 0x8f, 0xdb, 0xa8, 0xdd, 0x5a, 0x5c, 0xb2, 0xce,
+ /*1ad0:*/ 0xae, 0x84, 0x2a, 0x68, 0x7c, 0x38, 0x56, 0x78, 0xe1, 0xa6, 0x7c, 0x6b, 0x8b, 0x47, 0x07, 0xe4,
+ /*1ae0:*/ 0xc7, 0x54, 0x9a, 0x76, 0x34, 0xe5, 0xf5, 0x23, 0x49, 0x15, 0x90, 0x73, 0xa3, 0x0a, 0x5c, 0x4b,
+ /*1af0:*/ 0x99, 0x6f, 0x7b, 0x0f, 0x61, 0x9e, 0xf9, 0xa5, 0x95, 0x42, 0xbd, 0x19, 0xa5, 0x31, 0x08, 0xdd,
+ /*1b00:*/ 0x9a, 0x23, 0xdb, 0x2c, 0x19, 0x50, 0xbb, 0xc3, 0x3b, 0x51, 0xec, 0xd9, 0x38, 0x5b, 0x1b, 0x58,
+ /*1b10:*/ 0x79, 0xfb, 0xa2, 0x94, 0x6a, 0xe1, 0xd9, 0x03, 0x58, 0xd2, 0xb7, 0xfe, 0xc2, 0x99, 0xf4, 0x45,
+ /*1b20:*/ 0x28, 0x00, 0x11, 0x41, 0x67, 0x09, 0x1a, 0x82, 0x48, 0x11, 0x25, 0x82, 0x66, 0xd9, 0x08, 0xe4,
+ /*1b30:*/ 0xf3, 0x4f, 0xf1, 0x4c, 0x40, 0x78, 0xb7, 0x40, 0x5f, 0x16, 0xd6, 0x4d, 0x9d, 0x25, 0xcb, 0xff,
+ /*1b40:*/ 0xe1, 0xe7, 0xaf, 0x0c, 0x5b, 0x9a, 0x57, 0xf6, 0xc1, 0xd0, 0x1c, 0x20, 0x68, 0x9a, 0x51, 0x7a,
+ /*1b50:*/ 0xbd, 0xcb, 0x96, 0x21, 0x57, 0xe4, 0x70, 0x9d, 0x9c, 0xda, 0xaa, 0x89, 0x0d, 0xc2, 0x53, 0xa9,
+ /*1b60:*/ 0x6b, 0x78, 0x12, 0xeb, 0x77, 0x4d, 0x5c, 0xe4, 0x5e, 0x2b, 0x30, 0x0f, 0xb3, 0x08, 0x9f, 0x68,
+ /*1b70:*/ 0xf1, 0xb4, 0x37, 0xac, 0xed, 0x39, 0x0e, 0x59, 0xfa, 0xc4, 0xa8, 0xfa, 0xcc, 0x76, 0x77, 0xba,
+ /*1b80:*/ 0x15, 0xae, 0xbe, 0x0f, 0x89, 0xb7, 0x3c, 0xf5, 0x27, 0x2c, 0xfc, 0x05, 0xb2, 0x32, 0x40, 0x61,
+ /*1b90:*/ 0x0d, 0xdd, 0x0a, 0x8a, 0x0c, 0xa5, 0x7e, 0x2c, 0x5e, 0x50, 0x6b, 0xa1, 0x3b, 0x87, 0x23, 0xa0,
+ /*1ba0:*/ 0xa9, 0x4c, 0x46, 0x4c, 0xfb, 0xe2, 0x39, 0x3a, 0x3b, 0x43, 0x9b, 0x24, 0x8b, 0x4c, 0xae, 0x25,
+ /*1bb0:*/ 0x81, 0x72, 0x5e, 0xaf, 0xe3, 0x3f, 0x8c, 0x5b, 0x2f, 0xfd, 0x48, 0x61, 0x29, 0x9e, 0xba, 0x76,
+ /*1bc0:*/ 0x73, 0x3c, 0xeb, 0xeb, 0x30, 0x18, 0xa9, 0x89, 0x4c, 0xbc, 0x09, 0xb6, 0xd7, 0x46, 0x27, 0x76,
+ /*1bd0:*/ 0x51, 0x41, 0x52, 0x29, 0x2a, 0x73, 0x2d, 0xf0, 0x13, 0x9c, 0x00, 0x38, 0xe1, 0xe6, 0xc7, 0x9c,
+ /*1be0:*/ 0x7b, 0x07, 0xab, 0xf0, 0xf9, 0x0f, 0xc0, 0xce, 0x6a, 0xba, 0x10, 0x03, 0xfa, 0x55, 0x8b, 0x1a,
+ /*1bf0:*/ 0xfc, 0xd4, 0xdf, 0x8d, 0xf5, 0x98, 0x7e, 0xf1, 0x70, 0xff, 0x41, 0x9d, 0x66, 0xa3, 0x3a, 0x99,
+ /*1c00:*/ 0x5e, 0xe2, 0x9f, 0x29, 0x3b, 0xc8, 0xe9, 0x32, 0xb7, 0x1a, 0xb3, 0x47, 0xde, 0x42, 0x2d, 0x37,
+ /*1c10:*/ 0x2f, 0x13, 0xe6, 0x4a, 0xd8, 0x4d, 0xfc, 0x65, 0x6b, 0xaa, 0xd7, 0x58, 0xab, 0x86, 0x95, 0x88,
+ /*1c20:*/ 0x36, 0xf8, 0xf9, 0xa6, 0xd6, 0x66, 0xf3, 0xa7, 0x18, 0x62, 0x7d, 0xa3, 0x5f, 0xbe, 0xac, 0xba,
+ /*1c30:*/ 0x9f, 0x02, 0x3b, 0xa7, 0x43, 0x2a, 0xb5, 0x48, 0x70, 0x76, 0xda, 0xa2, 0x06, 0xb4, 0x67, 0x48,
+ /*1c40:*/ 0x33, 0xd9, 0x2d, 0xce, 0xd2, 0xe0, 0xd5, 0x3b, 0x81, 0xbb, 0x7a, 0x6a, 0xa9, 0xe5, 0xac, 0x82,
+ /*1c50:*/ 0x7c, 0x05, 0x7d, 0x93, 0x03, 0x15, 0xc2, 0x8f, 0x14, 0x44, 0xf9, 0xe2, 0xb2, 0x85, 0xfd, 0xe4,
+ /*1c60:*/ 0x7f, 0xaf, 0x3f, 0x36, 0x1e, 0xdc, 0x0f, 0x81, 0x29, 0x22, 0xfd, 0xb6, 0xf4, 0xa1, 0xef, 0xe2,
+ /*1c70:*/ 0x28, 0x82, 0xcb, 0x1c, 0x50, 0x4b, 0x68, 0x92, 0xc5, 0x40, 0xba, 0x8f, 0xb0, 0x13, 0x1e, 0xb7,
+ /*1c80:*/ 0xc4, 0x89, 0x78, 0x90, 0x52, 0x4a, 0x0d, 0xa9, 0x21, 0x25, 0x46, 0x65, 0x6c, 0x3f, 0x44, 0xb6,
+ /*1c90:*/ 0x6c, 0x6b, 0x91, 0xe2, 0x84, 0x75, 0x33, 0x58, 0x67, 0xf1, 0x19, 0x91, 0xd2, 0x18, 0xdb, 0x6c,
+ /*1ca0:*/ 0x80, 0x06, 0x8f, 0xb4, 0x13, 0xde, 0x16, 0x1b, 0x70, 0x8e, 0x11, 0x92, 0xfd, 0xa5, 0x38, 0xbf,
+ /*1cb0:*/ 0x3b, 0x88, 0x8a, 0xec, 0x26, 0xe7, 0x04, 0x47, 0x34, 0x63, 0xcc, 0xcb, 0x57, 0x35, 0x2d, 0xe7,
+ /*1cc0:*/ 0x77, 0x7c, 0xe3, 0x84, 0xfc, 0xdd, 0x45, 0x3b, 0x45, 0x9e, 0x7c, 0xf8, 0x78, 0x5d, 0x42, 0x09,
+ /*1cd0:*/ 0x23, 0x9c, 0xf5, 0x8e, 0x95, 0x0a, 0xac, 0x64, 0x35, 0x20, 0x78, 0xca, 0x3e, 0x2b, 0x5f, 0xd5,
+ /*1ce0:*/ 0xb0, 0x22, 0xc6, 0x3a, 0x9a, 0x6f, 0xa7, 0x57, 0xf6, 0x83, 0xb4, 0xad, 0xe9, 0xd7, 0x0f, 0xaa,
+ /*1cf0:*/ 0x93, 0x49, 0x6b, 0x04, 0xf9, 0x35, 0x16, 0x37, 0x7f, 0x82, 0xac, 0x7e, 0x87, 0x32, 0x84, 0xef,
+ /*1d00:*/ 0x1c, 0x06, 0x6a, 0xdc, 0x26, 0x23, 0xcd, 0x39, 0x3c, 0x71, 0xae, 0x7d, 0x08, 0x6d, 0x76, 0xa4,
+ /*1d10:*/ 0xf0, 0x68, 0xd6, 0x6c, 0xec, 0xc4, 0x10, 0x6c, 0xaf, 0x8e, 0x50, 0x2c, 0xd8, 0x06, 0xcd, 0x19,
+ /*1d20:*/ 0x05, 0xf8, 0x16, 0x3a, 0x28, 0xb9, 0x2e, 0x00, 0x0b, 0xf9, 0xa9, 0x1b, 0x5a, 0xa5, 0x34, 0x9c,
+ /*1d30:*/ 0xbe, 0x65, 0xb5, 0xe6, 0xb4, 0xc1, 0x8a, 0xfe, 0x1c, 0x24, 0x0f, 0x7e, 0x91, 0x8c, 0x65, 0x3d,
+ /*1d40:*/ 0xaa, 0x26, 0x13, 0x91, 0x8b, 0xee, 0xd9, 0x0c, 0xdc, 0xc7, 0x08, 0x21, 0x8c, 0xc4, 0xb7, 0x86,
+ /*1d50:*/ 0x45, 0xf7, 0x11, 0x35, 0x9d, 0x76, 0x38, 0x81, 0x6c, 0xc5, 0x49, 0x87, 0xe2, 0xe9, 0x48, 0x5c,
+ /*1d60:*/ 0xf9, 0x15, 0x30, 0x10, 0x2e, 0xee, 0x6e, 0x4d, 0x9b, 0xd3, 0xb8, 0x10, 0xff, 0xdd, 0x5d, 0xe1,
+ /*1d70:*/ 0x2c, 0x38, 0xfe, 0x0f, 0xae, 0x14, 0xb9, 0x21, 0x74, 0x6a, 0xc0, 0xf8, 0x29, 0x2e, 0xa1, 0xb0,
+ /*1d80:*/ 0xf9, 0x3c, 0x72, 0x46, 0x1b, 0xe7, 0xa2, 0xef, 0x18, 0x0b, 0xe3, 0xc7, 0x6b, 0x60, 0x6a, 0x7f,
+ /*1d90:*/ 0x60, 0x36, 0xa5, 0xa9, 0x3b, 0x13, 0x97, 0xd4, 0xee, 0x5a, 0x23, 0xd0, 0xc9, 0x2d, 0x3a, 0x1f,
+ /*1da0:*/ 0x84, 0x86, 0x42, 0xc5, 0x94, 0xf0, 0x6f, 0x9e, 0xd7, 0xa9, 0xa0, 0x63, 0xd0, 0xc2, 0xa2, 0x57,
+ /*1db0:*/ 0x3a, 0xe5, 0x14, 0xc9, 0xce, 0x7a, 0x77, 0xfc, 0x72, 0x99, 0xf7, 0x02, 0x92, 0xdb, 0x95, 0xf3,
+ /*1dc0:*/ 0x66, 0x17, 0xb0, 0xe1, 0x83, 0xe3, 0x13, 0x55, 0xe4, 0xf2, 0xb7, 0x45, 0x35, 0x34, 0x5e, 0x3b,
+ /*1dd0:*/ 0x1d, 0x68, 0x0a, 0x38, 0x94, 0x43, 0x7b, 0xc0, 0x21, 0x77, 0x3e, 0x11, 0x51, 0xba, 0x1b, 0x0c,
+ /*1de0:*/ 0x1f, 0x0b, 0x28, 0x23, 0xca, 0x79, 0x5b, 0x3c, 0xc8, 0x4b, 0x84, 0xd8, 0xa0, 0xfc, 0x9d, 0x7f,
+ /*1df0:*/ 0xad, 0xce, 0x6a, 0xe4, 0x7b, 0xbd, 0xbc, 0xbe, 0x9c, 0xef, 0x2c, 0x5e, 0x5c, 0x64, 0x1e, 0x5d,
+ /*1e00:*/ 0x97, 0x83, 0x20, 0x63, 0x5b, 0x4d, 0x18, 0xdd, 0xe3, 0x08, 0x7a, 0xfd, 0x7a, 0xb0, 0xb4, 0x89,
+ /*1e10:*/ 0xfe, 0x5d, 0x59, 0x5a, 0x50, 0x91, 0x6a, 0xe3, 0xd8, 0xe4, 0x4c, 0x74, 0x06, 0x1e, 0xb8, 0xcb,
+ /*1e20:*/ 0x27, 0x0e, 0x57, 0x76, 0x4c, 0x31, 0x76, 0x86, 0xd4, 0x37, 0x93, 0x6c, 0x13, 0x45, 0x6d, 0x79,
+ /*1e30:*/ 0xef, 0xab, 0xb6, 0x07, 0x7b, 0x07, 0xc0, 0x26, 0xa1, 0x61, 0x40, 0xa0, 0x67, 0x36, 0xfc, 0xb5,
+ /*1e40:*/ 0x8b, 0x75, 0x02, 0xd8, 0x4d, 0x60, 0x40, 0xeb, 0xf4, 0x02, 0xb2, 0xe3, 0x5e, 0x22, 0x13, 0xf5,
+ /*1e50:*/ 0xb4, 0x71, 0xb9, 0x64, 0x3a, 0x71, 0xba, 0xdb, 0x4e, 0xbe, 0x8e, 0x35, 0x18, 0xe1, 0xf3, 0xf1,
+ /*1e60:*/ 0xde, 0xd9, 0xba, 0x88, 0x1e, 0x08, 0xd7, 0x79, 0x54, 0xdd, 0x1c, 0xda, 0xa3, 0xcd, 0x18, 0x7b,
+ /*1e70:*/ 0x84, 0x17, 0xc7, 0x0a, 0x17, 0x9f, 0x14, 0x58, 0x6c, 0xce, 0x7f, 0x1b, 0x7c, 0x0b, 0xcd, 0x82,
+ /*1e80:*/ 0xee, 0x1a, 0x9f, 0x24, 0x94, 0x01, 0x76, 0xbe, 0x68, 0xb5, 0xc5, 0x9e, 0x6f, 0x3c, 0x90, 0x02,
+ /*1e90:*/ 0x2b, 0x58, 0xc3, 0x2e, 0x9d, 0xc0, 0x4e, 0xa2, 0x78, 0xf2, 0x2d, 0x8a, 0x07, 0x82, 0xbe, 0xd4,
+ /*1ea0:*/ 0xbf, 0x4a, 0x08, 0xa3, 0xa5, 0x89, 0xe0, 0x3f, 0x28, 0x0b, 0xec, 0xac, 0x77, 0xdd, 0xac, 0x52,
+ /*1eb0:*/ 0x7a, 0x58, 0x65, 0x59, 0x48, 0x03, 0xf9, 0x27, 0xd1, 0xa9, 0x7b, 0x37, 0xbe, 0x4c, 0x6c, 0x6b,
+ /*1ec0:*/ 0x73, 0x15, 0x74, 0xfc, 0x83, 0x1e, 0xbd, 0x67, 0x20, 0x14, 0xe9, 0xad, 0x93, 0x13, 0xd5, 0x45,
+ /*1ed0:*/ 0x2a, 0xdc, 0x6c, 0xa3, 0x04, 0xe7, 0x5f, 0x58, 0xea, 0x95, 0x25, 0x25, 0xe8, 0xb5, 0x32, 0x26,
+ /*1ee0:*/ 0xd8, 0xa1, 0x16, 0x0c, 0xbe, 0x63, 0xee, 0xc3, 0x52, 0xba, 0x01, 0xbe, 0xfd, 0xc1, 0x9b, 0x5c,
+ /*1ef0:*/ 0xf4, 0x6d, 0x1c, 0x08, 0x0a, 0xd9, 0xd9, 0xa6, 0xd2, 0x24, 0x05, 0x7c, 0x05, 0x8c, 0x4a, 0x7a,
+ /*1f00:*/ 0xfe, 0x35, 0x11, 0x82, 0xb6, 0x94, 0xe1, 0x3e, 0xc3, 0xd1, 0xad, 0x88, 0x3c, 0x2f, 0xb2, 0x2c,
+ /*1f10:*/ 0x75, 0xef, 0x37, 0xd8, 0x33, 0x9a, 0xf6, 0x65, 0x8f, 0x58, 0xa7, 0x64, 0x52, 0xb8, 0x95, 0x19,
+ /*1f20:*/ 0xe6, 0xee, 0x39, 0x03, 0xdd, 0x8d, 0x33, 0x47, 0xb5, 0xb7, 0x4b, 0x6f, 0x55, 0xb6, 0x8e, 0xca,
+ /*1f30:*/ 0x3d, 0x6f, 0xc7, 0x39, 0x1f, 0x56, 0xa1, 0xa8, 0xef, 0x0b, 0xcb, 0x52, 0xea, 0x2d, 0x1f, 0x11,
+ /*1f40:*/ 0xee, 0x6b, 0x6a, 0x26, 0x84, 0xce, 0x02, 0x5a, 0x10, 0x2d, 0x6f, 0xd6, 0x8f, 0xf9, 0x68, 0xd8,
+ /*1f50:*/ 0x0a, 0x67, 0xeb, 0x09, 0x7c, 0xd0, 0xa8, 0xfd, 0x47, 0x40, 0x49, 0x6f, 0xb1, 0xcd, 0x01, 0xaa,
+ /*1f60:*/ 0x2d, 0x85, 0xb8, 0xc7, 0x81, 0x3e, 0xc7, 0xa9, 0xbe, 0xc5, 0xc6, 0x20, 0xf2, 0x4d, 0x61, 0xff,
+ /*1f70:*/ 0x64, 0x45, 0xed, 0xa0, 0xa0, 0xa8, 0xbb, 0xb4, 0x78, 0x44, 0x1c, 0x7f, 0xe8, 0x87, 0x7b, 0xc1,
+ /*1f80:*/ 0x29, 0xc2, 0x71, 0x0d, 0x9a, 0xa7, 0x9c, 0xc4, 0x03, 0x1b, 0x6c, 0x25, 0x2f, 0x9f, 0xc4, 0xd1,
+ /*1f90:*/ 0x67, 0x19, 0x81, 0x3f, 0x71, 0x94, 0xcd, 0xed, 0x84, 0x9d, 0x0f, 0x42, 0xae, 0x38, 0xdf, 0xbd,
+ /*1fa0:*/ 0xc3, 0x92, 0x6b, 0xa8, 0x8b, 0x18, 0x45, 0xe2, 0xf3, 0x1c, 0x7c, 0xe6, 0x06, 0xeb, 0x41, 0x48,
+ /*1fb0:*/ 0xe1, 0x44, 0x79, 0x28, 0xa2, 0xfe, 0x46, 0x85, 0x9d, 0x1a, 0x83, 0x1d, 0x9c, 0xe3, 0xe2, 0xc9,
+ /*1fc0:*/ 0x33, 0x68, 0xa8, 0xa9, 0x07, 0x9c, 0x7f, 0x71, 0xe7, 0xf0, 0x4e, 0x21, 0x90, 0x80, 0xc1, 0x3e,
+ /*1fd0:*/ 0x1f, 0xae, 0xdd, 0xb8, 0x5a, 0x17, 0x86, 0x9a, 0xdf, 0xec, 0xde, 0xaa, 0x48, 0x99, 0x4b, 0xd9,
+ /*1fe0:*/ 0xa8, 0x9b, 0xbc, 0x34, 0x65, 0x30, 0x1a, 0x72, 0xf4, 0x69, 0xee, 0x81, 0x06, 0x86, 0xbe, 0x65,
+ /*1ff0:*/ 0x74, 0x22, 0xdc, 0x45, 0x61, 0x4d, 0x11, 0x16, 0x94, 0xc3, 0xaf, 0x31, 0xf2, 0x2e, 0x7e, 0x0a,
+ /*2000:*/ 0xe9, 0xcc, 0x15, 0x55, 0xdd, 0x5c, 0x4b, 0xc8, 0xe6, 0x54, 0x65, 0x71, 0x96, 0xb6, 0x05, 0xa1,
+ /*2010:*/ 0xf6, 0x12, 0xf5, 0x2e, 0xbd, 0x04, 0x7d, 0xc9, 0xb6, 0xe1, 0x40, 0x64, 0x35, 0x33, 0x2e, 0x1e,
+ /*2020:*/ 0xfd, 0xcb, 0x48, 0x03, 0xc1, 0x90, 0x27, 0x65, 0x2c, 0xa5, 0x3b, 0xba, 0x99, 0x89, 0x1d, 0x63,
+ /*2030:*/ 0x27, 0x31, 0xa4, 0x45, 0x7a, 0x5d, 0xbb, 0x67, 0xea, 0x3e, 0x3d, 0x03, 0x71, 0x8b, 0xda, 0x94,
+ /*2040:*/ 0xc6, 0x09, 0xb6, 0xfb, 0x87, 0x2e, 0x50, 0x67, 0x04, 0x3d, 0xf0, 0x54, 0xd8, 0xcb, 0xee, 0x74,
+ /*2050:*/ 0x59, 0x15, 0x9a, 0x40, 0xb2, 0xf1, 0xae, 0xa2, 0x9c, 0x76, 0x6b, 0x2b, 0x70, 0xc8, 0xe9, 0x20,
+ /*2060:*/ 0x95, 0x16, 0xb8, 0xb2, 0x7e, 0x43, 0xd7, 0x5b, 0x3d, 0xce, 0x82, 0x22, 0x61, 0xff, 0x64, 0x14,
+ /*2070:*/ 0xcc, 0x7e, 0xf8, 0x73, 0x5e, 0x72, 0xf3, 0xfc, 0xea, 0xbf, 0x44, 0xc4, 0x1b, 0x25, 0xd1, 0xbd,
+ /*2080:*/ 0x95, 0x3a, 0xb0, 0x1b, 0x1f, 0xfa, 0x7b, 0xbe, 0x52, 0x80, 0x21, 0xb6, 0x22, 0x0b, 0x9c, 0x38,
+ /*2090:*/ 0x3d, 0xbb, 0xae, 0x2f, 0xd8, 0xaf, 0x45, 0x00, 0x47, 0x44, 0xcd, 0x6a, 0x66, 0x8c, 0xc5, 0x35,
+ /*20a0:*/ 0xfd, 0x6d, 0xe4, 0xf5, 0xfa, 0xfa, 0x00, 0xff, 0x96, 0xdb, 0x91, 0xad, 0x00, 0x05, 0xbe, 0x99,
+ /*20b0:*/ 0xa0, 0x15, 0x4d, 0xb6, 0xb5, 0x26, 0xc4, 0x82, 0xa9, 0xd4, 0xbc, 0x2f, 0xe1, 0x85, 0x18, 0xd0,
+ /*20c0:*/ 0xa7, 0xdc, 0xbe, 0x53, 0x84, 0xac, 0x2a, 0xc3, 0xf9, 0x8c, 0x01, 0x6e, 0xdb, 0x3e, 0x7a, 0xf4,
+ /*20d0:*/ 0x0b, 0xf3, 0x82, 0x34, 0x4d, 0x8a, 0x67, 0x0a, 0x68, 0x5c, 0x87, 0xd5, 0x12, 0x11, 0xf7, 0xd0,
+ /*20e0:*/ 0xf2, 0xd7, 0x3c, 0x2c, 0x7a, 0xf6, 0xee, 0x3a, 0x7f, 0xa3, 0x66, 0xb4, 0x76, 0x5e, 0x2b, 0x14,
+ /*20f0:*/ 0x17, 0xdc, 0x28, 0x89, 0xa4, 0xba, 0x8e, 0x66, 0x82, 0x18, 0xfe, 0x04, 0xcc, 0x44, 0xf8, 0xd9,
+ /*2100:*/ 0x76, 0x30, 0x30, 0xad, 0x4c, 0xa0, 0x5f, 0x8a, 0x7b, 0x59, 0x07, 0xb9, 0x1f, 0xdc, 0x88, 0xac,
+ /*2110:*/ 0xbf, 0xcb, 0x8d, 0x64, 0x34, 0x01, 0xd6, 0xb1, 0x03, 0xd7, 0xa8, 0x0b, 0x2f, 0xee, 0x98, 0x8d,
+ /*2120:*/ 0x18, 0x9f, 0x19, 0xf4, 0xc3, 0x9c, 0x44, 0x9a, 0x2b, 0xdf, 0x88, 0x79, 0xad, 0x0f, 0x13, 0x3e,
+ /*2130:*/ 0xd7, 0xb9, 0x5c, 0x50, 0xed, 0x0c, 0xda, 0xb0, 0xb6, 0x6e, 0xdb, 0x6d, 0x03, 0x31, 0xc6, 0x97,
+ /*2140:*/ 0xac, 0x8f, 0x9c, 0x2d, 0x16, 0x88, 0x72, 0x49, 0x82, 0x99, 0xc0, 0x71, 0x59, 0x27, 0xb6, 0x39,
+ /*2150:*/ 0xc8, 0x30, 0x56, 0x8e, 0x8f, 0xa2, 0xa5, 0xbe, 0xc4, 0x01, 0x1e, 0x12, 0x42, 0xab, 0xd1, 0x9c,
+ /*2160:*/ 0x4c, 0x34, 0xef, 0x87, 0x36, 0xf2, 0xce, 0xde, 0xf5, 0x23, 0x71, 0x12, 0x7e, 0xb6, 0x8e, 0x25,
+ /*2170:*/ 0x82, 0x7d, 0xd6, 0xac, 0x07, 0xbb, 0x01, 0xfc, 0x9d, 0x14, 0xdf, 0x24, 0x38, 0x7c, 0xd8, 0x42,
+ /*2180:*/ 0x3a, 0xf9, 0xb1, 0xfd, 0x66, 0x9f, 0x7c, 0x47, 0x9d, 0x57, 0x3b, 0x75, 0x44, 0x63, 0xe8, 0x4c,
+ /*2190:*/ 0x7c, 0xf2, 0xfc, 0xec, 0x43, 0x83, 0x87, 0xd3, 0x13, 0x73, 0x33, 0x98, 0x7d, 0x33, 0x0b, 0x4b,
+ /*21a0:*/ 0x44, 0xb2, 0xc1, 0x9c, 0xb3, 0x03, 0x67, 0x80, 0xef, 0x95, 0x06, 0xe0, 0xbb, 0xe1, 0xe5, 0x33,
+ /*21b0:*/ 0x21, 0x73, 0x1f, 0x91, 0xf1, 0x14, 0xdc, 0x9e, 0x53, 0xe3, 0x14, 0x85, 0x43, 0x1e, 0xaa, 0x5d,
+ /*21c0:*/ 0x08, 0x7b, 0x28, 0x8d, 0x43, 0x27, 0xec, 0x2d, 0xab, 0xe7, 0xe2, 0x09, 0xc9, 0x15, 0x1a, 0x87,
+ /*21d0:*/ 0x58, 0xa6, 0xfe, 0x35, 0xd0, 0xd9, 0x87, 0x39, 0x7e, 0xae, 0xc2, 0x91, 0x0a, 0x0f, 0xf3, 0x48,
+ /*21e0:*/ 0xe2, 0x5d, 0x4c, 0x1a, 0x56, 0xbb, 0x74, 0x8e, 0x9f, 0x25, 0xf0, 0x90, 0x46, 0xcf, 0x50, 0x35,
+ /*21f0:*/ 0x7a, 0x59, 0xe1, 0x6a, 0xd4, 0x24, 0x97, 0x4a, 0xca, 0xdb, 0xbd, 0x83, 0xd9, 0xa9, 0x6a, 0xae,
+ /*2200:*/ 0xea, 0x46, 0x97, 0x14, 0xdd, 0xaf, 0x46, 0x79, 0x98, 0xb7, 0x20, 0xf2, 0x3e, 0x98, 0xd8, 0x6c,
+ /*2210:*/ 0xc5, 0x57, 0x5d, 0xed, 0x08, 0xda, 0x0f, 0x98, 0x06, 0xd8, 0xdc, 0x2c, 0x28, 0x8d, 0xc5, 0x21,
+ /*2220:*/ 0x33, 0xc1, 0xc4, 0x2d, 0x1e, 0x85, 0x7b, 0x82, 0x12, 0x74, 0x78, 0x2b, 0xf5, 0x0b, 0x77, 0xeb,
+ /*2230:*/ 0xc8, 0x6f, 0x42, 0x83, 0xe2, 0x19, 0x25, 0x6b, 0xff, 0x92, 0xb7, 0x63, 0x82, 0xae, 0xc9, 0x0d,
+ /*2240:*/ 0xa0, 0xc3, 0x64, 0x6f, 0x13, 0x8c, 0xf2, 0x8a, 0xa2, 0xb6, 0x57, 0x99, 0x2e, 0x92, 0xa6, 0x3c,
+ /*2250:*/ 0xa1, 0x86, 0x05, 0x76, 0x4f, 0x55, 0x5d, 0x2b, 0x3c, 0x28, 0x30, 0x00, 0x51, 0x5e, 0xa1, 0x90,
+ /*2260:*/ 0x35, 0x0b, 0x78, 0xb6, 0x04, 0x82, 0xca, 0xe0, 0x3e, 0xb9, 0xe0, 0x12, 0x19, 0x62, 0xfd, 0x05,
+ /*2270:*/ 0x81, 0xd7, 0x78, 0xb9, 0x23, 0x14, 0xe3, 0xb3, 0x4d, 0xac, 0x97, 0x80, 0xac, 0x4c, 0x98, 0xea,
+ /*2280:*/ 0x60, 0x89, 0x62, 0x8b, 0xc0, 0xd2, 0x37, 0x5c, 0x5a, 0x63, 0xcf, 0x7a, 0x55, 0x3a, 0x67, 0xeb,
+ /*2290:*/ 0xec, 0xcb, 0xd6, 0xf7, 0x39, 0x33, 0xf0, 0x6e, 0x4c, 0x8c, 0x0f, 0x75, 0x60, 0x5a, 0x5f, 0x08,
+ /*22a0:*/ 0x52, 0x93, 0x86, 0x50, 0xf3, 0xf1, 0x99, 0x9f, 0x3a, 0x02, 0x9e, 0xe8, 0xca, 0xe7, 0x95, 0x47,
+ /*22b0:*/ 0xb0, 0x37, 0x4e, 0xa1, 0x53, 0xc8, 0xaf, 0xb6, 0x6e, 0x55, 0xdf, 0xf8, 0x7d, 0xf2, 0xe7, 0x36,
+ /*22c0:*/ 0xc2, 0xf8, 0xbc, 0x54, 0xe7, 0x01, 0x13, 0x6b, 0x3f, 0xcc, 0xd0, 0x84, 0xe4, 0xac, 0xd8, 0x0a,
+ /*22d0:*/ 0x26, 0x2f, 0x82, 0xe1, 0xce, 0x3d, 0x60, 0xe4, 0xb9, 0xb2, 0xad, 0xd9, 0x9c, 0x4c, 0x2f, 0xa3,
+ /*22e0:*/ 0x2b, 0x37, 0x8f, 0x0d, 0x65, 0x38, 0xc5, 0x76, 0xca, 0x97, 0xa1, 0x64, 0xca, 0x3c, 0x14, 0xb6,
+ /*22f0:*/ 0xb3, 0x68, 0xaf, 0xb2, 0x47, 0x66, 0x4b, 0x85, 0x21, 0x1e, 0xa2, 0x60, 0xd7, 0x85, 0x8a, 0x9b,
+ /*2300:*/ 0x35, 0x0e, 0xd8, 0x20, 0x12, 0x8b, 0xca, 0x25, 0x17, 0xc4, 0x57, 0xb8, 0x6a, 0x6f, 0xac, 0xa9,
+ /*2310:*/ 0xf4, 0xe9, 0x3c, 0xc1, 0x05, 0x4a, 0x8c, 0x5c, 0xba, 0xbb, 0x82, 0xe7, 0xa7, 0xd0, 0x58, 0x44,
+ /*2320:*/ 0x13, 0x86, 0xac, 0x3c, 0x63, 0x9b, 0xa8, 0xb5, 0x56, 0x13, 0x55, 0xce, 0xc3, 0xd3, 0x29, 0xec,
+ /*2330:*/ 0x96, 0x27, 0x17, 0xde, 0x8a, 0xec, 0x31, 0x56, 0x6e, 0x3b, 0xfa, 0x4e, 0xa9, 0x51, 0x9c, 0x1c,
+ /*2340:*/ 0x67, 0x70, 0xbb, 0xc7, 0x50, 0x2d, 0xfb, 0xc9, 0x21, 0x64, 0x4c, 0xdd, 0xe7, 0xd2, 0x57, 0xfe,
+ /*2350:*/ 0x09, 0x12, 0x0d, 0xe7, 0x5b, 0x0f, 0x81, 0x21, 0x13, 0x44, 0x2f, 0x57, 0xab, 0xe8, 0xac, 0xf6,
+ /*2360:*/ 0x02, 0x23, 0x3d, 0xa1, 0x4f, 0xf5, 0x54, 0x20, 0xe2, 0x82, 0x4d, 0xf4, 0x22, 0x15, 0xc5, 0x70,
+ /*2370:*/ 0xf7, 0x9d, 0xd7, 0x3b, 0xb5, 0x30, 0x82, 0x94, 0x47, 0x26, 0xba, 0xb1, 0x15, 0xe6, 0x7c, 0xba,
+ /*2380:*/ 0xb0, 0xcd, 0xd2, 0xe6, 0x69, 0x52, 0x35, 0x0b, 0x77, 0x78, 0xd2, 0x65, 0x7c, 0xa3, 0xba, 0x56,
+ /*2390:*/ 0x61, 0xa0, 0xb1, 0x93, 0x83, 0xa1, 0x28, 0x23, 0x37, 0xb5, 0x1f, 0x56, 0x64, 0xdc, 0x66, 0x02,
+ /*23a0:*/ 0x22, 0x2d, 0xa7, 0x14, 0x77, 0x3e, 0xc0, 0xdb, 0x5c, 0x84, 0x63, 0x0f, 0xea, 0x37, 0x36, 0x34,
+ /*23b0:*/ 0xab, 0xab, 0x99, 0x5b, 0x81, 0x37, 0x22, 0xa5, 0x94, 0xe5, 0xf2, 0x79, 0x2f, 0x45, 0xc7, 0xc9,
+ /*23c0:*/ 0xa7, 0xfa, 0x6d, 0xbe, 0x02, 0x99, 0x2e, 0xeb, 0x6c, 0xc8, 0xc3, 0x24, 0x48, 0xbc, 0x9b, 0x4e,
+ /*23d0:*/ 0x13, 0x05, 0xfe, 0x9f, 0x67, 0xe7, 0x62, 0xc3, 0x74, 0x6d, 0x24, 0xf9, 0x42, 0x71, 0x77, 0x85,
+ /*23e0:*/ 0x4f, 0xb4, 0xba, 0x77, 0xbc, 0xdc, 0x49, 0x94, 0x73, 0x24, 0xe1, 0x62, 0xe1, 0xee, 0x8f, 0xd1,
+ /*23f0:*/ 0xa1, 0x7a, 0x72, 0x40, 0xba, 0x5e, 0x8c, 0x60, 0x31, 0x6e, 0x5d, 0x71, 0x15, 0x42, 0xf9, 0x70,
+ /*2400:*/ 0x61, 0x88, 0x08, 0x72, 0xa7, 0x03, 0x92, 0x3d, 0xc0, 0x0f, 0xed, 0x11, 0xf9, 0x32, 0xbe, 0x42,
+ /*2410:*/ 0x03, 0xb3, 0xb9, 0x15, 0xe1, 0x50, 0x00, 0xcf, 0xcd, 0x19, 0x19, 0x82, 0x32, 0x39, 0x43, 0x1a,
+ /*2420:*/ 0x54, 0xbd, 0xf4, 0xd8, 0x47, 0xe1, 0x01, 0x7a, 0xf5, 0xdb, 0x6f, 0xae, 0xad, 0xd4, 0x52, 0x6a,
+ /*2430:*/ 0xe0, 0x98, 0xa8, 0x8e, 0x1b, 0x1c, 0x54, 0x75, 0x6f, 0x71, 0x53, 0xbd, 0xea, 0x26, 0x78, 0x50,
+ /*2440:*/ 0x7b, 0x10, 0xe5, 0x5b, 0x56, 0xe4, 0xd8, 0x47, 0x20, 0xf8, 0x39, 0xb5, 0x29, 0xab, 0x99, 0x66,
+ /*2450:*/ 0xe9, 0xc9, 0xa2, 0x30, 0x8e, 0x14, 0xfc, 0x2c, 0x14, 0xdc, 0xba, 0xc9, 0x8a, 0xa1, 0x06, 0xab,
+ /*2460:*/ 0xfd, 0xc8, 0x93, 0x52, 0x26, 0x44, 0xf6, 0x0d, 0xc9, 0x46, 0x8a, 0x4e, 0x0b, 0x96, 0x98, 0x4d,
+ /*2470:*/ 0xf3, 0x71, 0x8f, 0xdf, 0x02, 0x2a, 0xa6, 0x8b, 0xe7, 0x6d, 0x6c, 0x80, 0x18, 0x21, 0x3c, 0x7c,
+ /*2480:*/ 0x6f, 0xc0, 0xb6, 0xea, 0x5d, 0x78, 0xb5, 0x46, 0xf9, 0x27, 0xfa, 0x4f, 0xd3, 0xbe, 0x83, 0xe2,
+ /*2490:*/ 0xaa, 0x26, 0xee, 0x71, 0x86, 0x5d, 0xf1, 0x05, 0x15, 0x97, 0x98, 0x0a, 0xdd, 0xa3, 0x67, 0x93,
+ /*24a0:*/ 0x50, 0xc1, 0x1a, 0xa7, 0xd1, 0xa0, 0xcd, 0xa4, 0xfe, 0xfa, 0x5a, 0x0e, 0x34, 0x64, 0x4c, 0x00,
+ /*24b0:*/ 0x41, 0xfc, 0x6e, 0x8c, 0x65, 0x60, 0xa5, 0xe9, 0xea, 0xc1, 0xd2, 0xed, 0x27, 0xd1, 0x3c, 0x87,
+ /*24c0:*/ 0xbb, 0xdd, 0xc8, 0xfa, 0x10, 0xa4, 0x90, 0x68, 0x4d, 0x8c, 0x9f, 0x3d, 0x47, 0x41, 0x1e, 0x38,
+ /*24d0:*/ 0x55, 0x7a, 0x02, 0xb5, 0xfc, 0xea, 0xcc, 0x33, 0x15, 0x62, 0xa3, 0x0c, 0x16, 0x39, 0x3a, 0x1d,
+ /*24e0:*/ 0xfd, 0x6d, 0x89, 0xb2, 0x93, 0x18, 0xb1, 0xfb, 0x74, 0x2b, 0x58, 0x6e, 0x2e, 0xa3, 0x0a, 0xfc,
+ /*24f0:*/ 0xed, 0x5e, 0xc9, 0xfc, 0xda, 0xdc, 0x61, 0xf1, 0x1b, 0xdc, 0x8b, 0xd6, 0x19, 0x3d, 0x3f, 0x68,
+ /*2500:*/ 0x90, 0x83, 0x19, 0x79, 0xe7, 0xfe, 0x11, 0x14, 0xf7, 0xe7, 0x3d, 0x94, 0x08, 0x60, 0xbd, 0xaa,
+ /*2510:*/ 0xdd, 0x87, 0xd0, 0xf4, 0xd2, 0xf5, 0xe4, 0x90, 0xa8, 0x73, 0xae, 0xb6, 0xb3, 0x8a, 0xc1, 0x36,
+ /*2520:*/ 0xa1, 0x1a, 0x03, 0x7c, 0xbe, 0x9d, 0xcb, 0xbc, 0x3a, 0x0f, 0x16, 0x54, 0xdb, 0xd6, 0xb4, 0x84,
+ /*2530:*/ 0x79, 0xe3, 0x95, 0xee, 0x5a, 0x65, 0x88, 0x1a, 0x68, 0x82, 0xc1, 0x32, 0x47, 0x94, 0x4a, 0x8b,
+ /*2540:*/ 0xb8, 0x1b, 0xa4, 0x77, 0x49, 0x65, 0x51, 0xbb, 0xbd, 0x0c, 0xd2, 0x7b, 0xbd, 0xff, 0xd9, 0x72,
+ /*2550:*/ 0x2e, 0x37, 0xc2, 0xc0, 0xf0, 0x03, 0xc7, 0x13, 0x46, 0xef, 0x7b, 0xa1, 0xf1, 0xa5, 0xbd, 0x1f,
+ /*2560:*/ 0x0e, 0x2f, 0x4e, 0x20, 0x51, 0xc7, 0x54, 0x57, 0x84, 0x78, 0xac, 0x7b, 0xc9, 0xe1, 0x8d, 0x66,
+ /*2570:*/ 0x51, 0x12, 0x79, 0x7c, 0x9c, 0x3d, 0xe2, 0xf3, 0x8e, 0x6b, 0x77, 0x84, 0x47, 0x14, 0x4d, 0x87,
+ /*2580:*/ 0xac, 0xa0, 0x9a, 0x5f, 0xd7, 0x4f, 0x18, 0x44, 0x8e, 0x96, 0x6f, 0xf4, 0xf0, 0x45, 0x73, 0x36,
+ /*2590:*/ 0x34, 0xa5, 0xaa, 0x24, 0xec, 0xde, 0x68, 0xa3, 0xda, 0x9e, 0xfc, 0x19, 0xba, 0x0e, 0x31, 0x80,
+ /*25a0:*/ 0x20, 0xad, 0x73, 0x0c, 0x35, 0x2d, 0x5f, 0x50, 0x41, 0x58, 0x02, 0xb6, 0x4c, 0xeb, 0xcf, 0xa1,
+ /*25b0:*/ 0x6e, 0x54, 0x66, 0xf9, 0xfb, 0xfa, 0x73, 0x48, 0x53, 0x9d, 0xbc, 0x7b, 0xe4, 0x6e, 0xad, 0xa7,
+ /*25c0:*/ 0x68, 0x6c, 0x3a, 0xed, 0xd9, 0x01, 0x49, 0xbe, 0xe8, 0x03, 0x36, 0xb6, 0x06, 0x2f, 0xfc, 0xfa,
+ /*25d0:*/ 0x5c, 0xd1, 0xe2, 0x4d, 0x62, 0xdc, 0x1c, 0xb8, 0x9b, 0xfc, 0x6e, 0x26, 0x3c, 0x38, 0xc3, 0x3d,
+ /*25e0:*/ 0xe0, 0x52, 0x61, 0x10, 0x34, 0x97, 0x15, 0x3f, 0xa9, 0xdc, 0xc2, 0xad, 0x32, 0xf7, 0x3d, 0x70,
+ /*25f0:*/ 0xe7, 0xf1, 0x2e, 0xe8, 0x1e, 0xbd, 0x8e, 0x90, 0xfb, 0x22, 0x73, 0xde, 0xe7, 0xb8, 0x9c, 0xce,
+ /*2600:*/ 0x9b, 0x89, 0xd3, 0x51, 0xfd, 0xe9, 0x07, 0xbe, 0x32, 0x14, 0x04, 0x22, 0xf8, 0x73, 0x75, 0x39,
+ /*2610:*/ 0x6d, 0x77, 0x21, 0x58, 0x5e, 0x64, 0x98, 0x36, 0x67, 0xc4, 0xed, 0x70, 0x25, 0xf7, 0x79, 0x12,
+ /*2620:*/ 0x53, 0xa8, 0xff, 0x59, 0x0b, 0xb7, 0xe0, 0x78, 0x35, 0xe5, 0x47, 0x70, 0xd9, 0xc5, 0x13, 0xe7,
+ /*2630:*/ 0xda, 0xa9, 0x09, 0xc9, 0x17, 0x68, 0x58, 0xb8, 0xbc, 0xa3, 0xf3, 0xf6, 0x02, 0xda, 0x35, 0x93,
+ /*2640:*/ 0x7f, 0xf2, 0x4e, 0x5f, 0x2f, 0xf2, 0x30, 0xca, 0xce, 0x23, 0xb3, 0x13, 0xff, 0xa3, 0xd6, 0x76,
+ /*2650:*/ 0xf8, 0xd5, 0xb8, 0xad, 0x52, 0xe3, 0x55, 0x15, 0x6e, 0x3b, 0x61, 0x5e, 0x25, 0x97, 0xda, 0x62,
+ /*2660:*/ 0xe6, 0x5a, 0x1a, 0xc3, 0x2e, 0x5d, 0xcd, 0xb9, 0x41, 0xe3, 0x72, 0x0b, 0x12, 0x94, 0x95, 0x08,
+ /*2670:*/ 0x06, 0x86, 0x45, 0xf9, 0x38, 0x8d, 0x41, 0xf6, 0x3e, 0x84, 0x6d, 0x06, 0xfb, 0x41, 0x55, 0x0d,
+ /*2680:*/ 0x8e, 0x31, 0x8d, 0x8d, 0x7c, 0x9b, 0x1e, 0x54, 0x5a, 0xac, 0xe1, 0x3e, 0xc0, 0x03, 0x36, 0x23,
+ /*2690:*/ 0x81, 0x13, 0xe7, 0xcc, 0x1b, 0xc3, 0x9c, 0x6a, 0xc1, 0xfc, 0xe9, 0x9c, 0x20, 0xa0, 0x4a, 0x84,
+ /*26a0:*/ 0x0f, 0x17, 0xcc, 0xf1, 0xb6, 0xcc, 0xf9, 0x5e, 0x52, 0x0a, 0x70, 0x03, 0x24, 0x73, 0x65, 0x5b,
+ /*26b0:*/ 0x28, 0x8d, 0xe5, 0x99, 0x8e, 0x47, 0xfd, 0x75, 0x63, 0xd6, 0x6a, 0x16, 0xe7, 0xa8, 0x27, 0x44,
+ /*26c0:*/ 0x76, 0xf6, 0x81, 0xf9, 0xec, 0x37, 0x49, 0x5b, 0x50, 0x19, 0x11, 0x8e, 0xe4, 0x21, 0x6f, 0xca,
+ /*26d0:*/ 0xd3, 0x91, 0xb7, 0x2d, 0x91, 0x1b, 0x99, 0x19, 0xb6, 0xfb, 0xcd, 0xb6, 0xe4, 0x11, 0xd3, 0x26,
+ /*26e0:*/ 0x70, 0xa9, 0x3f, 0x3e, 0x81, 0x66, 0x8c, 0x97, 0xce, 0xe8, 0x98, 0x0a, 0x55, 0x57, 0x7f, 0x14,
+ /*26f0:*/ 0x8b, 0x9d, 0xb5, 0x81, 0x3b, 0x61, 0x25, 0x5e, 0xa0, 0xda, 0xcc, 0x64, 0xf1, 0xe2, 0xe4, 0xa0,
+ /*2700:*/ 0x86, 0xdb, 0xec, 0x17, 0x94, 0x06, 0xe8, 0xa3, 0x6d, 0x65, 0xd7, 0x0e, 0xda, 0x42, 0xfa, 0x65,
+ /*2710:*/ 0x2f, 0x86, 0xde, 0xb3, 0x0c, 0x85, 0x46, 0xb2, 0x5f, 0x43, 0x40, 0xc7, 0x06, 0xfc, 0xd7, 0xbc,
+ /*2720:*/ 0x13, 0x3d, 0x1e, 0x7c, 0xfe, 0x21, 0x92, 0x51, 0xcd, 0xb6, 0xf2, 0xdd, 0xf2, 0xf1, 0x63, 0x3d,
+ /*2730:*/ 0x23, 0x81, 0xd4, 0x82, 0x2e, 0x7b, 0x7d, 0x9b, 0xa4, 0x45, 0x30, 0xf5, 0xbf, 0x32, 0x01, 0xbd,
+ /*2740:*/ 0xda, 0x6e, 0xb6, 0x43, 0xbc, 0xb3, 0xf2, 0xbb, 0x7c, 0x99, 0xcc, 0x84, 0xc2, 0x32, 0x89, 0xe9,
+ /*2750:*/ 0xfa, 0xeb, 0x75, 0x52, 0x77, 0xc2, 0xf4, 0x18, 0x1f, 0x16, 0xef, 0x3a, 0xcd, 0xef, 0xce, 0x7f,
+ /*2760:*/ 0x69, 0xcf, 0x0d, 0x50, 0xa4, 0xc6, 0x17, 0xf8, 0x00, 0x28, 0xed, 0xa6, 0x98, 0x97, 0xb8, 0x42,
+ /*2770:*/ 0xae, 0xc1, 0x43, 0x4d, 0x00, 0x0c, 0x41, 0x67, 0xf1, 0xe5, 0xed, 0x28, 0x75, 0x64, 0x27, 0x57,
+ /*2780:*/ 0x0a, 0x42, 0xa0, 0x9f, 0x81, 0x6b, 0xf4, 0xa8, 0x4a, 0x92, 0xe4, 0xf4, 0xe2, 0x02, 0x5d, 0xf1,
+ /*2790:*/ 0x2c, 0xe6, 0x61, 0x2d, 0xc8, 0x73, 0x24, 0x58, 0xb9, 0x52, 0x8c, 0x3d, 0x69, 0x5f, 0xc4, 0xc5,
+ /*27a0:*/ 0x7c, 0x76, 0x40, 0x0f, 0x27, 0x98, 0x30, 0x34, 0xc7, 0xb3, 0x9f, 0x8c, 0xa2, 0x59, 0x90, 0x60,
+ /*27b0:*/ 0xe5, 0xbe, 0x1c, 0x06, 0xc5, 0x7e, 0x3b, 0xce, 0x8c, 0x18, 0x19, 0x52, 0xe5, 0x20, 0xc9, 0x58,
+ /*27c0:*/ 0xea, 0x6b, 0x24, 0x44, 0x8f, 0x8d, 0x41, 0xbc, 0xb7, 0xd9, 0x7d, 0x38, 0xc5, 0xf9, 0xe4, 0x8d,
+ /*27d0:*/ 0xf6, 0x7a, 0x01, 0x3d, 0x0f, 0x9c, 0xf3, 0x55, 0x54, 0x78, 0xa8, 0xb8, 0x2e, 0x4f, 0xfd, 0x4e,
+ /*27e0:*/ 0xc7, 0xea, 0x78, 0xbc, 0xa3, 0x35, 0xa6, 0x8a, 0x70, 0xfb, 0xef, 0xb0, 0x5e, 0x72, 0x91, 0x3e,
+ /*27f0:*/ 0x43, 0xc0, 0xb0, 0x1e, 0x7a, 0x3a, 0xcd, 0xa1, 0xfd, 0x02, 0x6b, 0x55, 0xc1, 0xd2, 0x3a, 0xd1,
+ /*2800:*/ 0x65, 0x71, 0x5d, 0x2c, 0x57, 0xce, 0x15, 0xec, 0x08, 0xb0, 0x83, 0xf0, 0xac, 0x4f, 0x10, 0xa0,
+ /*2810:*/ 0x80, 0xc3, 0x64, 0x82, 0x87, 0xb4, 0x99, 0x83, 0xd3, 0x3b, 0x21, 0x03, 0xbc, 0xa3, 0x8a, 0x4f,
+ /*2820:*/ 0xcb, 0x72, 0x0f, 0x13, 0x55, 0xb8, 0x50, 0x30, 0x8a, 0xc7, 0x3e, 0xc8, 0x1b, 0xd2, 0x80, 0xec,
+ /*2830:*/ 0x87, 0x25, 0x4f, 0x9f, 0x19, 0xd6, 0x3f, 0xfc, 0x7b, 0xed, 0x1b, 0x8b, 0xa8, 0x27, 0x82, 0xa2,
+ /*2840:*/ 0x67, 0xae, 0xed, 0xd9, 0x1d, 0xba, 0x29, 0x2c, 0xd2, 0x11, 0x6a, 0xbd, 0x98, 0x0a, 0xca, 0x16,
+ /*2850:*/ 0xaf, 0xe6, 0x80, 0x10, 0xe4, 0x3c, 0x0e, 0xd2, 0xd2, 0xfe, 0x4a, 0x71, 0x1f, 0x6e, 0x6e, 0xf4,
+ /*2860:*/ 0xf5, 0x4a, 0x27, 0xf8, 0xb8, 0x6a, 0xf1, 0x47, 0xbe, 0xfe, 0x48, 0x31, 0x87, 0xd1, 0x31, 0x1d,
+ /*2870:*/ 0x6e, 0x64, 0xde, 0x2a, 0x50, 0xb6, 0x47, 0xf2, 0x35, 0xd7, 0x97, 0x70, 0x2a, 0xf7, 0xf1, 0xa7,
+ /*2880:*/ 0x14, 0x57, 0x09, 0x45, 0xa9, 0x64, 0x6b, 0x3f, 0x98, 0xc7, 0xe9, 0xf4, 0x5f, 0x74, 0xe4, 0x44,
+ /*2890:*/ 0x34, 0xce, 0x4a, 0x60, 0x80, 0x6c, 0xe7, 0x88, 0xc9, 0xab, 0x26, 0x5a, 0xc4, 0x5f, 0xe3, 0x09,
+ /*28a0:*/ 0x2d, 0xc8, 0x95, 0xae, 0xfc, 0x8e, 0xdf, 0xc9, 0x3c, 0x65, 0x5c, 0xf5, 0x7c, 0x04, 0x20, 0xcb,
+ /*28b0:*/ 0x22, 0xb7, 0x6b, 0x91, 0xc3, 0x2d, 0xa0, 0x25, 0xc2, 0x69, 0x7b, 0x3d, 0x86, 0x1a, 0x20, 0x49,
+ /*28c0:*/ 0x8d, 0x42, 0xc1, 0xc4, 0x9a, 0x1f, 0xf3, 0x3f, 0x52, 0xf0, 0xf1, 0xe2, 0x5c, 0xf0, 0x37, 0x12,
+ /*28d0:*/ 0x99, 0x13, 0x21, 0x70, 0x39, 0x7c, 0x74, 0x22, 0xff, 0xc6, 0xc6, 0x0c, 0xbc, 0xf6, 0x8d, 0x72,
+ /*28e0:*/ 0xeb, 0xa4, 0x13, 0x79, 0xd7, 0x23, 0xa8, 0xdb, 0x59, 0x7b, 0x70, 0xfd, 0x06, 0xf5, 0x6c, 0x53,
+ /*28f0:*/ 0xe5, 0x04, 0x74, 0xa7, 0xc8, 0xb6, 0xe6, 0x95, 0x99, 0x95, 0x89, 0x55, 0xc7, 0xdd, 0xc9, 0x45,
+ /*2900:*/ 0xb5, 0x88, 0xc7, 0xbd, 0x0d, 0x52, 0xf0, 0x08, 0x03, 0x87, 0x9e, 0x8b, 0xe6, 0x68, 0x57, 0xde,
+ /*2910:*/ 0x81, 0x77, 0x92, 0x91, 0x45, 0x41, 0x3a, 0xfe, 0x2f, 0xf0, 0x2c, 0x3b, 0xed, 0x9d, 0x3e, 0xbf,
+ /*2920:*/ 0x4a, 0x8e, 0x7f, 0x54, 0xaa, 0x5c, 0x08, 0x84, 0x86, 0xf3, 0xc3, 0x04, 0x86, 0x2a, 0xab, 0xaf,
+ /*2930:*/ 0xcc, 0xac, 0xd8, 0x59, 0x7d, 0xa1, 0xd3, 0x70, 0x4f, 0xb1, 0x1b, 0x05, 0xbb, 0x61, 0x85, 0xd7,
+ /*2940:*/ 0x3b, 0xaf, 0x3c, 0x80, 0x2a, 0xae, 0x1b, 0xfe, 0x24, 0xb6, 0x1d, 0x23, 0x3d, 0xae, 0x39, 0x5a,
+ /*2950:*/ 0xe5, 0xc4, 0x23, 0x39, 0x4f, 0x4c, 0x7e, 0x83, 0x4e, 0x8a, 0x8a, 0x89, 0x5f, 0x9e, 0x28, 0x1b,
+ /*2960:*/ 0xd8, 0xdf, 0xb8, 0xf7, 0x0e, 0x9d, 0x83, 0x23, 0x33, 0x77, 0x09, 0x96, 0x4b, 0x3c, 0xd3, 0x34,
+ /*2970:*/ 0x32, 0x75, 0x8b, 0x57, 0xd0, 0x75, 0xa1, 0xbe, 0xbf, 0xaa, 0x47, 0xfd, 0x34, 0xe1, 0x8d, 0xb2,
+ /*2980:*/ 0x15, 0x23, 0xdb, 0x9e, 0x68, 0x87, 0x98, 0xf4, 0x50, 0xc2, 0x43, 0xaf, 0x3a, 0x76, 0xcb, 0xb8,
+ /*2990:*/ 0x3f, 0x8f, 0x5c, 0x0d, 0x82, 0x4d, 0x86, 0xfe, 0x53, 0x51, 0xea, 0xba, 0xf7, 0x47, 0x9f, 0xbd,
+ /*29a0:*/ 0xb9, 0xf3, 0xe7, 0x5c, 0x21, 0x05, 0x9f, 0xa0, 0x51, 0x53, 0xec, 0xda, 0xce, 0x5d, 0xd7, 0x54,
+ /*29b0:*/ 0xbb, 0x95, 0xb8, 0xf0, 0x81, 0xf5, 0x80, 0x72, 0x6c, 0x11, 0xf6, 0x50, 0x7e, 0xb6, 0x7b, 0x17,
+ /*29c0:*/ 0xd4, 0xd9, 0xca, 0x9f, 0x2a, 0x42, 0xef, 0x81, 0x72, 0x68, 0x21, 0x4a, 0x32, 0x41, 0xa8, 0x2b,
+ /*29d0:*/ 0x6b, 0xf7, 0xc2, 0x9d, 0xdc, 0x14, 0x0e, 0xfa, 0x35, 0x95, 0x7d, 0x9c, 0xb5, 0x2c, 0x52, 0xac,
+ /*29e0:*/ 0xf3, 0x4a, 0x82, 0x9a, 0x6b, 0xa6, 0x5a, 0x53, 0xbe, 0x75, 0x7e, 0xd7, 0x62, 0x28, 0xe1, 0x42,
+ /*29f0:*/ 0x1b, 0x44, 0x8c, 0xb3, 0xf7, 0x59, 0x60, 0xb4, 0x6d, 0x87, 0x89, 0xf3, 0x5b, 0xe9, 0x02, 0xee,
+ /*2a00:*/ 0x38, 0xdb, 0xcb, 0x3f, 0x5a, 0x99, 0x68, 0x43, 0x13, 0x62, 0x6b, 0x05, 0xd7, 0xc0, 0x81, 0x10,
+ /*2a10:*/ 0xbf, 0x56, 0x4e, 0x2a, 0x21, 0xe2, 0x17, 0x64, 0xfa, 0x2c, 0xc1, 0xee, 0xa0, 0xee, 0x91, 0xcb,
+ /*2a20:*/ 0x12, 0xaa, 0x14, 0x08, 0xc1, 0x29, 0x23, 0xb4, 0xc6, 0xaf, 0xff, 0xf8, 0x4d, 0x05, 0x6c, 0xe8,
+ /*2a30:*/ 0x20, 0x11, 0xdf, 0xc4, 0x0f, 0x2c, 0x49, 0xc9, 0xd3, 0xf2, 0x7d, 0x37, 0x9c, 0xc0, 0xc1, 0x99,
+ /*2a40:*/ 0xf5, 0xa1, 0x91, 0x10, 0x45, 0x6a, 0xf4, 0x61, 0x3e, 0x0f, 0x08, 0x4f, 0x84, 0xe9, 0x22, 0x0d,
+ /*2a50:*/ 0x1e, 0x78, 0x44, 0xd8, 0x31, 0x49, 0x6a, 0x31, 0x2a, 0x43, 0x5c, 0x64, 0x66, 0x43, 0x10, 0x9d,
+ /*2a60:*/ 0xa2, 0x74, 0x84, 0x28, 0xbf, 0x78, 0x5a, 0xfd, 0xbe, 0x2d, 0x01, 0xeb, 0x55, 0xa9, 0x41, 0x94,
+ /*2a70:*/ 0xd1, 0x7b, 0x72, 0x62, 0x82, 0x92, 0x64, 0xef, 0x05, 0xe9, 0xd0, 0x35, 0x3d, 0x46, 0x4d, 0xb4,
+ /*2a80:*/ 0x9f, 0x1e, 0x09, 0x38, 0x8c, 0x37, 0x70, 0x9e, 0xfb, 0x04, 0xa0, 0xd1, 0x49, 0x92, 0x85, 0x74,
+ /*2a90:*/ 0x23, 0x19, 0x41, 0xc3, 0x56, 0xf0, 0x89, 0xdf, 0x00, 0x83, 0x4b, 0xcb, 0xf1, 0x66, 0x9b, 0x8d,
+ /*2aa0:*/ 0x61, 0xf0, 0x6d, 0xee, 0x6b, 0x34, 0xc3, 0x88, 0x7e, 0xbf, 0x62, 0x3f, 0xe7, 0x4d, 0x85, 0x70,
+ /*2ab0:*/ 0xba, 0x7c, 0xe4, 0x78, 0x8f, 0xa1, 0x01, 0x58, 0x68, 0x67, 0x05, 0x36, 0x17, 0x0c, 0x4f, 0xe3,
+ /*2ac0:*/ 0xd4, 0x85, 0x39, 0x93, 0x8f, 0xf6, 0xd6, 0x93, 0x16, 0xd9, 0x19, 0x7c, 0xa6, 0x94, 0x76, 0xad,
+ /*2ad0:*/ 0xf4, 0xec, 0x5b, 0x63, 0x3d, 0x3e, 0x65, 0x29, 0x39, 0x6c, 0xa7, 0xe0, 0xbf, 0xe5, 0x64, 0x17,
+ /*2ae0:*/ 0xa9, 0xcb, 0xb9, 0x96, 0x58, 0x85, 0xdb, 0x55, 0x33, 0x31, 0x70, 0xac, 0x89, 0x01, 0x54, 0x83,
+ /*2af0:*/ 0x8d, 0x52, 0xa6, 0x6d, 0x71, 0x5f, 0x7b, 0xb6, 0x43, 0x8b, 0x44, 0x4e, 0xe4, 0x38, 0x67, 0x32,
+ /*2b00:*/ 0x4b, 0x5b, 0xea, 0xfd, 0xe5, 0x4c, 0x44, 0x15, 0x80, 0xde, 0x1c, 0x5d, 0x8c, 0xa5, 0xa1, 0x03,
+ /*2b10:*/ 0x56, 0x81, 0x78, 0x9b, 0xcc, 0x2f, 0xbb, 0x98, 0x55, 0xc8, 0x2b, 0x2c, 0x3d, 0x5a, 0x9c, 0x01,
+ /*2b20:*/ 0x73, 0x9f, 0x25, 0x24, 0x2a, 0xf9, 0xf0, 0x69, 0x59, 0x11, 0x7f, 0x0e, 0xa9, 0xfc, 0x14, 0x2d,
+ /*2b30:*/ 0x75, 0xa1, 0x24, 0xa0, 0x02, 0x29, 0x81, 0x04, 0x79, 0xfe, 0x7e, 0x99, 0x45, 0x01, 0xc0, 0xd4,
+ /*2b40:*/ 0x38, 0x9c, 0x9c, 0x24, 0xe8, 0x02, 0x26, 0xae, 0x10, 0x3d, 0x37, 0x33, 0xe3, 0x74, 0xd4, 0xfc,
+ /*2b50:*/ 0xe3, 0x82, 0x8e, 0xa2, 0x1c, 0x22, 0x8d, 0xd7, 0x94, 0xb3, 0xb3, 0x3c, 0xfc, 0xeb, 0xa9, 0x9c,
+ /*2b60:*/ 0xc6, 0x1c, 0x9e, 0x39, 0xaf, 0xb9, 0xfb, 0x65, 0x9a, 0xc7, 0xa3, 0xaa, 0x65, 0x23, 0x14, 0xb3,
+ /*2b70:*/ 0x30, 0x9f, 0x26, 0x3d, 0x44, 0x94, 0xe8, 0x44, 0xe1, 0xa8, 0x48, 0xb2, 0x6a, 0x1d, 0x2c, 0x49,
+ /*2b80:*/ 0xff, 0x90, 0x82, 0x9b, 0x21, 0xa9, 0xee, 0x51, 0x32, 0xfc, 0xa3, 0x77, 0x87, 0xf5, 0x1d, 0xc5,
+ /*2b90:*/ 0xd3, 0xb3, 0x1c, 0x25, 0x36, 0xa7, 0x23, 0xaf, 0xbf, 0x16, 0x25, 0x73, 0x91, 0x02, 0x04, 0xf7,
+ /*2ba0:*/ 0x4d, 0xe0, 0xa1, 0x12, 0x68, 0xa8, 0x89, 0xbe, 0x16, 0xed, 0x84, 0x18, 0x68, 0x17, 0x7b, 0x27,
+ /*2bb0:*/ 0x73, 0xc2, 0x07, 0xcf, 0x89, 0xdd, 0x18, 0x3c, 0x0f, 0x0c, 0x94, 0x2e, 0x9c, 0x44, 0xba, 0xf5,
+ /*2bc0:*/ 0x4f, 0x3b, 0xd4, 0xb7, 0x3a, 0x61, 0xd3, 0x4c, 0x1a, 0x09, 0x3c, 0x37, 0x29, 0x49, 0x8a, 0x38,
+ /*2bd0:*/ 0x91, 0xda, 0xb9, 0x64, 0x3c, 0xdd, 0xfe, 0x2a, 0x84, 0xb3, 0x56, 0x8c, 0xdb, 0x27, 0x73, 0x96,
+ /*2be0:*/ 0x5b, 0xfa, 0x89, 0x4d, 0xda, 0xd8, 0x0e, 0x72, 0x44, 0x6c, 0x66, 0x4f, 0x1a, 0x18, 0xa3, 0xf3,
+ /*2bf0:*/ 0xdc, 0xc0, 0x55, 0xa5, 0x25, 0x61, 0xd6, 0xf7, 0x09, 0xe1, 0xb6, 0x43, 0x4e, 0x1c, 0x6c, 0xd4,
+ /*2c00:*/ 0x49, 0xfe, 0x6c, 0xd1, 0xda, 0x1d, 0x53, 0xf7, 0x4e, 0x4d, 0xb2, 0x43, 0x0d, 0x98, 0x2e, 0x29,
+ /*2c10:*/ 0x9f, 0xd5, 0xfc, 0x21, 0x31, 0xd8, 0x74, 0x1a, 0x3b, 0xf7, 0x50, 0x06, 0x57, 0x6c, 0xbe, 0x5e,
+ /*2c20:*/ 0x5a, 0x29, 0xef, 0xac, 0xde, 0xf2, 0xe3, 0xad, 0x69, 0x6f, 0x67, 0x78, 0xce, 0x9f, 0xc4, 0x42,
+ /*2c30:*/ 0xb0, 0xac, 0xeb, 0x30, 0x7f, 0x23, 0x93, 0x86, 0xe7, 0x7d, 0x35, 0x32, 0xe3, 0x6b, 0x0e, 0x8b,
+ /*2c40:*/ 0x58, 0x83, 0x50, 0xe3, 0x5f, 0x12, 0xd4, 0xa7, 0xf2, 0x1b, 0xfb, 0xb1, 0xf9, 0x7e, 0x1e, 0x05,
+ /*2c50:*/ 0x7f, 0xec, 0x88, 0x2e, 0xd3, 0xda, 0x49, 0x3f, 0x3a, 0xc9, 0xb7, 0x3f, 0x44, 0xc5, 0xb6, 0x01,
+ /*2c60:*/ 0xb0, 0x6f, 0xa1, 0x3c, 0x9e, 0x44, 0x02, 0xf1, 0x11, 0x92, 0xf1, 0xd1, 0x7d, 0x2a, 0xa7, 0xc2,
+ /*2c70:*/ 0x7f, 0x5b, 0xc3, 0x0e, 0x03, 0xe1, 0x86, 0xf4, 0x63, 0x19, 0x15, 0xad, 0x1b, 0x0d, 0x9b, 0x04,
+ /*2c80:*/ 0x55, 0x49, 0xcb, 0x89, 0x85, 0x98, 0x6a, 0xd0, 0x18, 0x4d, 0xa2, 0x3e, 0x8c, 0x8b, 0x6c, 0x5b,
+ /*2c90:*/ 0xcf, 0xd1, 0xcb, 0xf3, 0x1a, 0x7b, 0x7b, 0x97, 0xe1, 0xa9, 0xd3, 0xcd, 0xc1, 0xbd, 0x25, 0x99,
+ /*2ca0:*/ 0x51, 0xde, 0x67, 0x08, 0x13, 0xa2, 0x91, 0x52, 0x4e, 0xf3, 0xca, 0xe7, 0xf3, 0xdc, 0x94, 0x1e,
+ /*2cb0:*/ 0x00, 0x60, 0x69, 0xfe, 0x98, 0xe9, 0x06, 0xc4, 0xf9, 0x9f, 0xdd, 0x2b, 0x25, 0x11, 0x41, 0x4f,
+ /*2cc0:*/ 0x7a, 0x75, 0x62, 0x4e, 0xbe, 0x00, 0x7b, 0xee, 0x38, 0x57, 0xd3, 0x5a, 0xf7, 0xc2, 0x33, 0x37,
+ /*2cd0:*/ 0x59, 0xe3, 0xd5, 0x20, 0x4e, 0xb1, 0x8d, 0xcf, 0x43, 0x03, 0xf3, 0x65, 0xca, 0xb6, 0xd1, 0x52,
+ /*2ce0:*/ 0x36, 0x8e, 0xdd, 0xb0, 0x30, 0x6c, 0xcf, 0xec, 0xe1, 0x04, 0xc1, 0x5b, 0x40, 0x7b, 0x4d, 0x02,
+ /*2cf0:*/ 0x91, 0x46, 0x3c, 0x90, 0x87, 0x60, 0xe4, 0x1b, 0xe0, 0xe1, 0x2c, 0xeb, 0x16, 0x6f, 0x6c, 0x72,
+ /*2d00:*/ 0xda, 0x71, 0x1f, 0x55, 0x3a, 0xe7, 0x52, 0x15, 0xff, 0x09, 0x4a, 0x84, 0x0c, 0xc5, 0x92, 0x69,
+ /*2d10:*/ 0x94, 0x5c, 0xb2, 0x15, 0x7f, 0x00, 0xe3, 0xf1, 0x43, 0x8b, 0x06, 0xa3, 0x51, 0xdf, 0xd1, 0x3c,
+ /*2d20:*/ 0x14, 0xe0, 0xe4, 0x18, 0xae, 0xe2, 0x56, 0x00, 0x6d, 0x04, 0xa0, 0xef, 0x21, 0xfe, 0x0e, 0xd6,
+ /*2d30:*/ 0x19, 0x78, 0x19, 0x98, 0xa4, 0x86, 0x6c, 0xc2, 0x39, 0x3b, 0x61, 0x33, 0xf9, 0xd9, 0xed, 0xcb,
+ /*2d40:*/ 0x8b, 0x14, 0x4e, 0xc2, 0x0f, 0x5d, 0xf0, 0x19, 0x0b, 0x21, 0x25, 0x61, 0x79, 0x93, 0x3d, 0x0d,
+ /*2d50:*/ 0xed, 0x6f, 0x1a, 0xa0, 0x19, 0xab, 0xb6, 0x56, 0xce, 0xa5, 0x51, 0xa4, 0x09, 0xf6, 0xc5, 0x95,
+ /*2d60:*/ 0x63, 0x85, 0x5f, 0x24, 0xd7, 0xd4, 0xba, 0x07, 0xa3, 0x62, 0x55, 0xe7, 0x3f, 0x7c, 0x3a, 0x8b,
+ /*2d70:*/ 0xc3, 0xc8, 0xe9, 0x94, 0x59, 0x59, 0xc9, 0x87, 0xc9, 0xc1, 0xdb, 0xb9, 0xc0, 0x13, 0xa1, 0x1e,
+ /*2d80:*/ 0xd4, 0x49, 0x32, 0xa3, 0x31, 0x42, 0xb4, 0x32, 0xed, 0x0a, 0xfd, 0xf4, 0xf8, 0x76, 0x01, 0x28,
+ /*2d90:*/ 0xaf, 0x1e, 0x7b, 0xd6, 0x7e, 0xf7, 0x05, 0x4c, 0x15, 0xee, 0x50, 0x74, 0x15, 0xbf, 0x19, 0xc7,
+ /*2da0:*/ 0x5e, 0xa6, 0x8d, 0xb9, 0x0d, 0xfc, 0x4a, 0xf1, 0x55, 0x4f, 0x2a, 0xea, 0x1c, 0x91, 0xdf, 0x47,
+ /*2db0:*/ 0xf2, 0x3a, 0xab, 0x09, 0x3a, 0x96, 0x92, 0x4b, 0xdd, 0xf7, 0x13, 0x82, 0xa1, 0x77, 0x44, 0x96,
+ /*2dc0:*/ 0xe2, 0x7b, 0x9d, 0xcb, 0xdd, 0x3b, 0x10, 0xf6, 0x45, 0x5b, 0xd0, 0x9e, 0xfb, 0x50, 0x10, 0x86,
+ /*2dd0:*/ 0x31, 0x05, 0x5c, 0x8e, 0x77, 0xb2, 0x49, 0x86, 0xe1, 0x35, 0x45, 0x65, 0x28, 0x5b, 0x05, 0xce,
+ /*2de0:*/ 0x4b, 0xef, 0xf2, 0x62, 0xde, 0xa3, 0x89, 0xf9, 0x8f, 0x68, 0x2a, 0x2c, 0xcd, 0x06, 0xd0, 0xb5,
+ /*2df0:*/ 0xb4, 0x4d, 0xa2, 0x38, 0xd1, 0x3c, 0x01, 0x13, 0x3c, 0x98, 0x8b, 0x72, 0x80, 0x4a, 0x22, 0x73,
+ /*2e00:*/ 0x45, 0x15, 0x5a, 0xaf, 0x27, 0x76, 0x7e, 0xd0, 0x5e, 0xad, 0x37, 0xdb, 0x59, 0xac, 0xd1, 0x11,
+ /*2e10:*/ 0x9e, 0xca, 0x10, 0x59, 0x29, 0x7d, 0x2f, 0xc4, 0xcb, 0x83, 0xdb, 0x96, 0x54, 0x7d, 0xa7, 0x4c,
+ /*2e20:*/ 0x61, 0x0b, 0x0e, 0xa1, 0xcd, 0xa5, 0x5d, 0x9c, 0x5d, 0xc7, 0x5a, 0x5d, 0x10, 0xfc, 0x43, 0x7b,
+ /*2e30:*/ 0x91, 0xd0, 0x2a, 0xdc, 0x9f, 0x4b, 0xeb, 0xaa, 0x53, 0xf3, 0x5a, 0x54, 0x16, 0x78, 0xd2, 0x67,
+ /*2e40:*/ 0x28, 0x1a, 0x39, 0x2e, 0x9a, 0x5b, 0xae, 0x7e, 0x2f, 0xc2, 0xf6, 0xa7, 0xaf, 0x8a, 0x84, 0xdf,
+ /*2e50:*/ 0x6b, 0xdb, 0xbc, 0xdf, 0xd7, 0x2e, 0xd5, 0x27, 0xbb, 0x31, 0x40, 0xb9, 0x54, 0xb1, 0xf9, 0x08,
+ /*2e60:*/ 0xdb, 0x69, 0xff, 0x2e, 0x40, 0xa9, 0x98, 0x36, 0x02, 0x24, 0x52, 0x27, 0x48, 0x5b, 0x16, 0x56,
+ /*2e70:*/ 0x8a, 0x2c, 0x7d, 0x15, 0xd1, 0xd8, 0xb2, 0x74, 0xbf, 0x2e, 0x65, 0x61, 0xe8, 0x1c, 0x53, 0x99,
+ /*2e80:*/ 0x54, 0x0a, 0xc0, 0x53, 0xc4, 0xdd, 0x62, 0x38, 0x49, 0x1a, 0xb7, 0xf1, 0xc0, 0xee, 0xf7, 0x58,
+ /*2e90:*/ 0xa9, 0xcd, 0xd2, 0x49, 0xcc, 0x6d, 0xee, 0x43, 0xd0, 0x0c, 0xd4, 0x4b, 0x15, 0x3d, 0x00, 0x7f,
+ /*2ea0:*/ 0x08, 0x29, 0x25, 0x1e, 0x13, 0xc4, 0xfa, 0x84, 0x9a, 0xbd, 0x22, 0xd9, 0xf8, 0x0f, 0xa9, 0xb6,
+ /*2eb0:*/ 0x13, 0x6f, 0x03, 0xd1, 0x91, 0xf7, 0x88, 0x36, 0xbd, 0xb3, 0xb1, 0x67, 0xca, 0x39, 0x4e, 0x1d,
+ /*2ec0:*/ 0xc7, 0xbc, 0xdf, 0xbb, 0x25, 0x1c, 0xcc, 0x59, 0xd1, 0x69, 0x9e, 0x56, 0xe3, 0x93, 0x63, 0xd5,
+ /*2ed0:*/ 0x44, 0xdd, 0x6b, 0x69, 0x1e, 0x51, 0xd0, 0x22, 0x69, 0x3f, 0x04, 0x43, 0xa5, 0xd6, 0x8f, 0x2f,
+ /*2ee0:*/ 0x6d, 0xe8, 0xd6, 0x0e, 0x3d, 0x58, 0x2a, 0x83, 0xd2, 0xee, 0x0e, 0x9d, 0x2c, 0xa8, 0xb5, 0xfa,
+ /*2ef0:*/ 0x65, 0x19, 0x04, 0x2d, 0x19, 0x8c, 0x07, 0xf5, 0x2f, 0x01, 0xf8, 0xc5, 0x38, 0x24, 0xd4, 0x6e,
+ /*2f00:*/ 0xfd, 0xd6, 0xad, 0xf6, 0xac, 0xcd, 0x92, 0x27, 0x93, 0x0b, 0xf9, 0x60, 0x22, 0x2b, 0xa2, 0xae,
+ /*2f10:*/ 0x86, 0x79, 0xd7, 0xd6, 0xb6, 0xad, 0x64, 0x59, 0x69, 0xe0, 0x83, 0xf3, 0xf9, 0x49, 0x19, 0x08,
+ /*2f20:*/ 0x9a, 0xa3, 0xfd, 0xf5, 0x92, 0x2d, 0x35, 0x06, 0x44, 0x32, 0xe7, 0xdf, 0x5e, 0x83, 0x93, 0x42,
+ /*2f30:*/ 0xe4, 0xf8, 0x24, 0xad, 0x65, 0x6d, 0x37, 0x58, 0x87, 0x80, 0x2b, 0xac, 0xc7, 0x27, 0xce, 0x2d,
+ /*2f40:*/ 0x07, 0x10, 0x7e, 0x1d, 0xa4, 0x80, 0x2c, 0x16, 0xf0, 0x3b, 0x66, 0x3d, 0x74, 0x15, 0x25, 0xe0,
+ /*2f50:*/ 0x46, 0xf3, 0x08, 0xbd, 0x0b, 0x6e, 0x44, 0x5a, 0xc5, 0x0e, 0x53, 0x01, 0x4b, 0x80, 0x16, 0x91,
+ /*2f60:*/ 0x07, 0x94, 0x8f, 0x66, 0xb9, 0x38, 0xa1, 0x44, 0xed, 0xd4, 0x44, 0x58, 0x36, 0xd2, 0x12, 0xf3,
+ /*2f70:*/ 0xb0, 0x41, 0x7a, 0xfa, 0xaa, 0xca, 0x35, 0xf2, 0xd6, 0x4e, 0xf7, 0x8b, 0xce, 0x9b, 0x7d, 0x67,
+ /*2f80:*/ 0xdc, 0xbb, 0x46, 0xc8, 0x19, 0xbf, 0x0d, 0xd0, 0x7a, 0xee, 0x10, 0xb7, 0x9c, 0x85, 0x94, 0xb4,
+ /*2f90:*/ 0xfd, 0x49, 0x0d, 0x77, 0x9e, 0x95, 0x0b, 0xe2, 0xd5, 0xef, 0x28, 0x08, 0xee, 0xbf, 0xf9, 0x4b,
+ /*2fa0:*/ 0x39, 0x74, 0x02, 0x96, 0x1a, 0x8f, 0x34, 0x8b, 0x3a, 0xd9, 0x3f, 0x63, 0xa4, 0xfd, 0x63, 0xbd,
+ /*2fb0:*/ 0xc6, 0xfd, 0x8f, 0x02, 0x97, 0x44, 0xbc, 0xb1, 0xe5, 0x95, 0xd0, 0x5b, 0xa8, 0x3c, 0x11, 0xd9,
+ /*2fc0:*/ 0x93, 0xbf, 0x66, 0x82, 0xdc, 0xdd, 0xd5, 0x99, 0xee, 0x92, 0x09, 0x8e, 0x06, 0x0e, 0x7e, 0x67,
+ /*2fd0:*/ 0x00, 0xb5, 0x93, 0xb3, 0x39, 0x00, 0xe2, 0xe2, 0xb7, 0xe3, 0xe0, 0x1f, 0x3e, 0xd7, 0x8a, 0xc7,
+ /*2fe0:*/ 0x7e, 0xa6, 0xce, 0x8b, 0x08, 0xaa, 0x9a, 0xde, 0x27, 0xd2, 0xaf, 0xca, 0x72, 0x41, 0xb0, 0x4f,
+ /*2ff0:*/ 0xea, 0xf5, 0x7b, 0x85, 0x46, 0x03, 0xa6, 0x1f, 0x50, 0x7f, 0x74, 0xba, 0x01, 0xae, 0x88, 0x1e,
+ /*3000:*/ 0x0a, 0x50, 0x71, 0xb9, 0xcc, 0x78, 0x5a, 0xdd, 0x4c, 0xad, 0x30, 0xbd, 0xe8, 0x34, 0x8a, 0xe1,
+ /*3010:*/ 0xaf, 0xa9, 0xeb, 0xb9, 0x22, 0x69, 0xd7, 0x30, 0x45, 0xa6, 0x06, 0xf3, 0xd6, 0x4e, 0xac, 0x19,
+ /*3020:*/ 0xcf, 0x12, 0x66, 0x1d, 0xd2, 0x11, 0xe1, 0xcf, 0x3c, 0x12, 0x21, 0xcd, 0x74, 0xd2, 0xba, 0x62,
+ /*3030:*/ 0xcc, 0x6c, 0xb9, 0x67, 0xfd, 0xc4, 0x5a, 0x94, 0xc5, 0x6f, 0x1e, 0xb7, 0x49, 0x8c, 0x24, 0x96,
+ /*3040:*/ 0xf1, 0x8c, 0x30, 0xb9, 0xfc, 0x2f, 0xdf, 0x9d, 0xb7, 0x6c, 0x81, 0x63, 0xf5, 0x0f, 0x1c, 0xfd,
+ /*3050:*/ 0x15, 0xbe, 0x0b, 0x36, 0xff, 0xa2, 0xc9, 0x07, 0x40, 0x85, 0x70, 0xe4, 0x4f, 0xb0, 0xa9, 0x11,
+ /*3060:*/ 0x8b, 0x8d, 0x6f, 0x74, 0x17, 0x7d, 0x4c, 0xf9, 0xc6, 0x23, 0x81, 0x56, 0x21, 0xcb, 0x99, 0x1c,
+ /*3070:*/ 0x31, 0x03, 0xa1, 0x05, 0x5a, 0x29, 0x9a, 0xf1, 0x2e, 0xf5, 0x07, 0xb1, 0x8b, 0x6b, 0xea, 0xb6,
+ /*3080:*/ 0xd0, 0xe8, 0x78, 0x93, 0xb3, 0x2d, 0xcf, 0xa6, 0xb8, 0x7e, 0xfe, 0x7c, 0x91, 0x25, 0xa6, 0xf1,
+ /*3090:*/ 0xc8, 0xaa, 0xff, 0xcd, 0x4a, 0xf3, 0x22, 0x62, 0x98, 0xbb, 0x95, 0xa7, 0x9e, 0xff, 0x23, 0x37,
+ /*30a0:*/ 0x88, 0x79, 0xbe, 0x02, 0x8e, 0x85, 0xd3, 0x8e, 0x38, 0x50, 0xab, 0x9a, 0x47, 0xa8, 0xa7, 0x1a,
+ /*30b0:*/ 0x22, 0x06, 0xd2, 0xcb, 0xa9, 0x49, 0xd0, 0xfc, 0xa2, 0x3f, 0xb5, 0x8c, 0x80, 0xa4, 0x65, 0xf0,
+ /*30c0:*/ 0x7a, 0xe0, 0xf5, 0x05, 0xf8, 0x1f, 0x75, 0x8b, 0x03, 0xa8, 0xd7, 0x45, 0xd1, 0x17, 0xf4, 0x85,
+ /*30d0:*/ 0x94, 0x85, 0x5a, 0xb3, 0x26, 0x52, 0x4d, 0x24, 0x45, 0x93, 0xd2, 0x19, 0x04, 0x3d, 0xb9, 0x4e,
+ /*30e0:*/ 0xe7, 0xac, 0x7c, 0xd3, 0x38, 0x2e, 0x13, 0xce, 0x72, 0xf7, 0x26, 0x49, 0x04, 0xd0, 0xe4, 0x9b,
+ /*30f0:*/ 0x0f, 0x4c, 0x91, 0x27, 0x37, 0x89, 0x20, 0x54, 0x8b, 0xf9, 0xbc, 0x46, 0xab, 0x97, 0x5d, 0xf3,
+ /*3100:*/ 0x8c, 0xf4, 0xdf, 0x79, 0x3d, 0x13, 0x84, 0xb1, 0x12, 0x33, 0x2d, 0x83, 0xc0, 0xb0, 0xc8, 0x77,
+ /*3110:*/ 0xb7, 0x2e, 0x24, 0x9d, 0xdd, 0x10, 0x31, 0x6f, 0x1b, 0xef, 0x9c, 0x20, 0xcd, 0x8d, 0x90, 0x07,
+ /*3120:*/ 0xbf, 0x1c, 0x6f, 0x46, 0xb6, 0x6e, 0xdd, 0x90, 0x8a, 0xf8, 0xf7, 0x14, 0xc0, 0xbe, 0xd4, 0x9b,
+ /*3130:*/ 0x6f, 0x2a, 0xf5, 0x37, 0xf5, 0xc9, 0x5a, 0x80, 0x5d, 0xef, 0x76, 0x99, 0x7c, 0xfd, 0xd7, 0x04,
+ /*3140:*/ 0xa5, 0x7b, 0xe5, 0x1e, 0x45, 0x20, 0x82, 0xaa, 0xf6, 0x4f, 0x6a, 0x34, 0xfd, 0xbe, 0x61, 0xc2,
+ /*3150:*/ 0x2d, 0xbc, 0x5f, 0xcc, 0x56, 0xc4, 0x4d, 0x62, 0x08, 0xcb, 0xf2, 0x2b, 0x1b, 0x79, 0xd6, 0xe3,
+ /*3160:*/ 0xb6, 0xc2, 0xb0, 0x98, 0xaa, 0xde, 0xb9, 0xf8, 0xf8, 0x26, 0x5e, 0xf1, 0x74, 0x61, 0x5e, 0x10,
+ /*3170:*/ 0xa6, 0xa7, 0x45, 0x50, 0x2b, 0x94, 0x6d, 0x0d, 0x03, 0x66, 0x81, 0xed, 0x6c, 0x30, 0x48, 0x96,
+ /*3180:*/ 0x56, 0xda, 0x29, 0x3d, 0x9a, 0xb1, 0xa3, 0x64, 0x1f, 0xcd, 0xc9, 0x63, 0x42, 0x01, 0x08, 0x34,
+ /*3190:*/ 0x1d, 0x0e, 0x92, 0xca, 0xec, 0x3f, 0x9f, 0x87, 0xda, 0x68, 0xbb, 0xf1, 0x7c, 0x47, 0xc5, 0x26,
+ /*31a0:*/ 0x72, 0xee, 0x46, 0x90, 0x5c, 0xa7, 0x49, 0xd8, 0xd8, 0xba, 0xd6, 0xc9, 0x52, 0x9f, 0x48, 0x38,
+ /*31b0:*/ 0x16, 0xd9, 0xe2, 0x99, 0x88, 0xab, 0x1f, 0xca, 0xd9, 0x63, 0xd4, 0xf2, 0x48, 0x07, 0x92, 0x45,
+ /*31c0:*/ 0xc9, 0xe7, 0x97, 0xdf, 0x7b, 0xf7, 0x4b, 0x69, 0x5b, 0x19, 0x3b, 0x3f, 0x79, 0xc2, 0x23, 0x90,
+ /*31d0:*/ 0xff, 0x84, 0x5a, 0x8a, 0xe8, 0xdf, 0xcb, 0xaf, 0x3d, 0xa0, 0x15, 0x81, 0x43, 0xc6, 0xb5, 0xd9,
+ /*31e0:*/ 0x68, 0xc7, 0x83, 0x0b, 0x8a, 0x77, 0x16, 0xb6, 0x75, 0x23, 0x98, 0x9d, 0x0a, 0x08, 0x47, 0x4f,
+ /*31f0:*/ 0x0b, 0x84, 0x21, 0xdf, 0x61, 0xd5, 0x75, 0x6a, 0x2e, 0x3d, 0x82, 0x58, 0xc6, 0xa8, 0x21, 0xa1,
+ /*3200:*/ 0xa6, 0x39, 0x33, 0x68, 0x31, 0x70, 0x73, 0x84, 0x15, 0x0e, 0xb5, 0x4f, 0xc4, 0x80, 0x9f, 0x10,
+ /*3210:*/ 0x34, 0xf5, 0x6d, 0xa6, 0x49, 0x8f, 0x85, 0x36, 0xb4, 0x4c, 0x2f, 0x1e, 0x60, 0xa6, 0xfc, 0xd6,
+ /*3220:*/ 0xb2, 0x48, 0x2c, 0x7b, 0xdc, 0x02, 0xc7, 0x21, 0x24, 0x47, 0x20, 0x45, 0xd6, 0xbb, 0x29, 0xf6,
+ /*3230:*/ 0x0d, 0x25, 0x12, 0x58, 0xfe, 0xec, 0x88, 0x29, 0x9d, 0x83, 0xe5, 0x24, 0xac, 0xa3, 0x9b, 0x1f,
+ /*3240:*/ 0x35, 0x58, 0xe2, 0x3a, 0xf0, 0x85, 0xe1, 0x37, 0xd4, 0x91, 0xe2, 0xbf, 0xd7, 0xf4, 0x03, 0xf2,
+ /*3250:*/ 0xe4, 0x9d, 0x09, 0x27, 0x95, 0x3f, 0x0e, 0x3d, 0xfd, 0xf7, 0x41, 0xee, 0xb1, 0x76, 0xe1, 0xaf,
+ /*3260:*/ 0xed, 0x68, 0x37, 0xd5, 0xea, 0xe8, 0x6e, 0xc6, 0x11, 0xe6, 0xd7, 0xb0, 0x59, 0x19, 0x4a, 0x83,
+ /*3270:*/ 0x3d, 0xec, 0x38, 0xc9, 0x5b, 0xed, 0xe8, 0xe3, 0x76, 0x03, 0xcd, 0x4a, 0x90, 0xa9, 0x21, 0xd5,
+ /*3280:*/ 0xf4, 0x89, 0xc2, 0x7a, 0xb7, 0xa6, 0x02, 0x40, 0x5c, 0xb7, 0xe7, 0xea, 0x3e, 0xb4, 0x3e, 0x42,
+ /*3290:*/ 0x81, 0x6e, 0x88, 0x87, 0x7c, 0xa1, 0x71, 0xd5, 0x08, 0x7f, 0x87, 0xa0, 0x34, 0x74, 0x4a, 0x73,
+ /*32a0:*/ 0x8b, 0xf6, 0xfe, 0x41, 0xc8, 0xd4, 0x1d, 0x3a, 0x1e, 0xae, 0xff, 0xf4, 0x7e, 0xfe, 0xdd, 0x44,
+ /*32b0:*/ 0x9a, 0x3e, 0x8f, 0x5e, 0xf1, 0xdd, 0xd2, 0x38, 0x61, 0x58, 0x1e, 0xf7, 0xcd, 0x30, 0x3d, 0x88,
+ /*32c0:*/ 0xc4, 0x14, 0x56, 0xb3, 0x1b, 0x68, 0x0a, 0x02, 0x58, 0x47, 0x42, 0xc6, 0xf0, 0x0c, 0x6a, 0xe9,
+ /*32d0:*/ 0xa4, 0x20, 0x32, 0x74, 0x5a, 0xf5, 0x54, 0xa4, 0x48, 0x61, 0x6a, 0xa8, 0x12, 0x6b, 0xd9, 0xa7,
+ /*32e0:*/ 0x0c, 0x6c, 0xcf, 0x74, 0x1c, 0x22, 0xe4, 0x7e, 0x94, 0xe6, 0xf6, 0x9f, 0x0f, 0x17, 0x2b, 0xb1,
+ /*32f0:*/ 0xf0, 0xb4, 0x3b, 0x6a, 0x98, 0xfd, 0x33, 0x56, 0x6b, 0x10, 0x3e, 0x75, 0xa8, 0x0e, 0x4a, 0x99,
+ /*3300:*/ 0x1c, 0xfb, 0xe4, 0x70, 0x94, 0x6f, 0xbd, 0xd9, 0x40, 0x68, 0x46, 0x1f, 0x42, 0xac, 0x6c, 0x2d,
+ /*3310:*/ 0x0d, 0x45, 0xb0, 0x63, 0x81, 0x15, 0xdc, 0x59, 0x54, 0x73, 0xd7, 0xcd, 0xf5, 0x39, 0x93, 0x0a,
+ /*3320:*/ 0x09, 0xc1, 0x6f, 0x26, 0xc2, 0x33, 0xdd, 0x31, 0x87, 0xab, 0xff, 0x93, 0x96, 0xa4, 0x27, 0xda,
+ /*3330:*/ 0xd3, 0x5e, 0x30, 0xb4, 0x04, 0x93, 0xd5, 0xdd, 0x83, 0x4b, 0x19, 0x36, 0xb4, 0xdd, 0xeb, 0x45,
+ /*3340:*/ 0x70, 0x7c, 0xe7, 0x0b, 0x53, 0xda, 0x85, 0x6f, 0x66, 0xcc, 0x88, 0x3d, 0xfe, 0x7f, 0x54, 0xe2,
+ /*3350:*/ 0x12, 0x18, 0xc8, 0xed, 0x0b, 0x49, 0xc3, 0x4e, 0x88, 0x24, 0xae, 0x50, 0x38, 0xed, 0x78, 0x69,
+ /*3360:*/ 0x0d, 0x2d, 0x31, 0x46, 0xce, 0x89, 0xcc, 0x3b, 0x34, 0x8e, 0x12, 0xf4, 0xa4, 0x84, 0x6b, 0xc1,
+ /*3370:*/ 0x2f, 0x69, 0x3a, 0x35, 0x67, 0xb7, 0x13, 0x9d, 0x14, 0x59, 0x2c, 0x73, 0xac, 0x97, 0x1c, 0xc9,
+ /*3380:*/ 0x23, 0xe0, 0xec, 0xf5, 0x84, 0xb6, 0x30, 0x8a, 0x7f, 0xe6, 0x9b, 0x0d, 0xad, 0xdc, 0xa4, 0x9e,
+ /*3390:*/ 0xe4, 0x9f, 0x92, 0xae, 0x05, 0xd7, 0xf3, 0x74, 0x54, 0x24, 0xf8, 0x9f, 0x09, 0xa4, 0xc9, 0x3c,
+ /*33a0:*/ 0x6d, 0xda, 0x01, 0xeb, 0x25, 0x06, 0x66, 0xdd, 0xc0, 0x2d, 0x73, 0xfd, 0x45, 0xd1, 0xe4, 0x34,
+ /*33b0:*/ 0x73, 0xb4, 0x62, 0x11, 0xaf, 0x82, 0x2d, 0xcb, 0xaa, 0xb7, 0x9c, 0x83, 0xc5, 0x57, 0x86, 0xc3,
+ /*33c0:*/ 0xdd, 0xa0, 0xf1, 0x6d, 0xf3, 0x5a, 0xbe, 0xa8, 0xb6, 0x9f, 0x66, 0x9c, 0x7b, 0x48, 0xf1, 0x71,
+ /*33d0:*/ 0x83, 0x94, 0x54, 0x8d, 0x85, 0xb5, 0x03, 0xd1, 0x88, 0xb9, 0xe6, 0xcb, 0x78, 0xab, 0xea, 0x24,
+ /*33e0:*/ 0x54, 0x7e, 0x3f, 0x66, 0xa0, 0x3e, 0x63, 0x9b, 0x8c, 0x57, 0x2c, 0xa9, 0x97, 0xba, 0xfd, 0x6e,
+ /*33f0:*/ 0x05, 0xbb, 0xda, 0x9f, 0x1c, 0x9d, 0x6d, 0xea, 0x04, 0x84, 0x8c, 0x07, 0x78, 0xa2, 0x80, 0x1e,
+ /*3400:*/ 0x1e, 0xe0, 0x0b, 0x8f, 0x89, 0xf3, 0x84, 0x23, 0x17, 0x71, 0xff, 0x15, 0x64, 0x49, 0x2e, 0x90,
+ /*3410:*/ 0x0e, 0x50, 0x20, 0x2f, 0xf1, 0x9b, 0xb9, 0xb3, 0xe6, 0xf0, 0xee, 0xbb, 0x5f, 0x6d, 0xa6, 0xa2,
+ /*3420:*/ 0x10, 0x8f, 0xaf, 0x2f, 0x4e, 0xe9, 0x27, 0xa0, 0x04, 0x48, 0xda, 0x9a, 0x03, 0x64, 0x33, 0x42,
+ /*3430:*/ 0x0e, 0x02, 0x2e, 0x1f, 0x0e, 0x87, 0x0c, 0xd7, 0xe7, 0x09, 0xac, 0x79, 0x42, 0x93, 0xd7, 0x4a,
+ /*3440:*/ 0xaa, 0x5f, 0x07, 0xed, 0xb1, 0xaf, 0x0c, 0x22, 0x63, 0x2a, 0x9c, 0x9d, 0x4b, 0x6c, 0xf6, 0x80,
+ /*3450:*/ 0x0a, 0x1e, 0x4a, 0x50, 0x07, 0x64, 0xc6, 0xcc, 0x3a, 0x2a, 0x64, 0x9e, 0xde, 0x5b, 0x2d, 0x6c,
+ /*3460:*/ 0xe3, 0x48, 0xb5, 0x11, 0x9d, 0x3c, 0xf0, 0x8f, 0x5c, 0x0d, 0xd7, 0x02, 0xf5, 0xce, 0xff, 0x71,
+ /*3470:*/ 0x06, 0xc4, 0x4b, 0x7d, 0x67, 0x7e, 0xef, 0xc4, 0x78, 0x60, 0xba, 0x58, 0x0f, 0xbc, 0x84, 0x7b,
+ /*3480:*/ 0xc5, 0xba, 0xde, 0x8b, 0xdc, 0x60, 0x78, 0xab, 0xf2, 0xde, 0xd4, 0xed, 0x00, 0x22, 0x6b, 0xa4,
+ /*3490:*/ 0x4a, 0x79, 0x43, 0x79, 0xba, 0x03, 0x84, 0x25, 0x0c, 0x41, 0x1d, 0x1f, 0x19, 0x23, 0x7c, 0xf7,
+ /*34a0:*/ 0x20, 0xa3, 0xfd, 0xa1, 0x4f, 0xff, 0xfe, 0x8c, 0x7e, 0xb9, 0x07, 0x7d, 0xbe, 0x79, 0x18, 0xa8,
+ /*34b0:*/ 0x24, 0x2a, 0x95, 0x01, 0xf3, 0x3f, 0xb1, 0xa6, 0xe4, 0xda, 0xcf, 0x68, 0x42, 0x08, 0x2c, 0x4d,
+ /*34c0:*/ 0x2a, 0xd7, 0xb3, 0x6f, 0x4a, 0xb4, 0x6b, 0xe9, 0x0b, 0xfb, 0x73, 0xb1, 0x21, 0x0a, 0x44, 0xab,
+ /*34d0:*/ 0x47, 0x02, 0xdb, 0xb5, 0x0b, 0x13, 0x6f, 0x0c, 0x78, 0x40, 0xbd, 0x73, 0x04, 0xf2, 0x7e, 0x54,
+ /*34e0:*/ 0x85, 0x35, 0x78, 0x52, 0x6d, 0xf4, 0x05, 0x70, 0x51, 0xa2, 0xb9, 0x6f, 0x34, 0x8c, 0x4b, 0x7b,
+ /*34f0:*/ 0xb8, 0x6c, 0x3b, 0xa5, 0xe7, 0x22, 0xc6, 0x46, 0xa8, 0x09, 0xc3, 0x6b, 0x19, 0x01, 0x50, 0xa5,
+ /*3500:*/ 0x58, 0xef, 0x4d, 0xfa, 0xee, 0x20, 0xbd, 0xcb, 0xd1, 0x56, 0xae, 0x7e, 0xc3, 0x6f, 0x61, 0x52,
+ /*3510:*/ 0xde, 0x9e, 0x59, 0xc4, 0x41, 0x52, 0x78, 0x39, 0x97, 0x30, 0x24, 0x9e, 0x92, 0xea, 0xbc, 0x69,
+ /*3520:*/ 0xf9, 0x8d, 0x1d, 0x1a, 0xce, 0x74, 0x52, 0x4f, 0x04, 0x5f, 0x0e, 0xd8, 0xb7, 0xb4, 0xf5, 0x5b,
+ /*3530:*/ 0xa9, 0x1c, 0xc0, 0x0d, 0xf3, 0xbc, 0x27, 0xde, 0x37, 0xe6, 0x26, 0x11, 0xd4, 0x9b, 0x25, 0x42,
+ /*3540:*/ 0xd7, 0xc1, 0xf6, 0xde, 0xb5, 0xae, 0x24, 0x59, 0x2a, 0x83, 0xb5, 0xa6, 0x8f, 0x03, 0xd3, 0xbf,
+ /*3550:*/ 0xcb, 0x58, 0x76, 0xe0, 0xf7, 0xdb, 0x63, 0xa4, 0x18, 0xbc, 0xfb, 0x0c, 0x76, 0x3e, 0x73, 0x71,
+ /*3560:*/ 0x4a, 0xdc, 0x5a, 0x0e, 0xf8, 0x59, 0x88, 0xc1, 0xc9, 0x55, 0x13, 0xc7, 0xab, 0x57, 0x85, 0x5b,
+ /*3570:*/ 0x46, 0x4d, 0x19, 0x14, 0x0c, 0xb0, 0x43, 0xd2, 0x92, 0xef, 0x6f, 0x8b, 0xd9, 0x06, 0xd3, 0x2f,
+ /*3580:*/ 0xaf, 0xf3, 0xa5, 0x09, 0x71, 0x96, 0x97, 0x5a, 0xfd, 0x03, 0x65, 0xad, 0x8e, 0x62, 0xce, 0x91,
+ /*3590:*/ 0x96, 0xd3, 0x91, 0x11, 0xb2, 0x85, 0xc7, 0xcb, 0x29, 0x79, 0x8d, 0x37, 0xd7, 0xec, 0x13, 0x43,
+ /*35a0:*/ 0x20, 0x08, 0x40, 0x8f, 0xa2, 0xee, 0xa5, 0x1f, 0xed, 0xa5, 0x78, 0x4b, 0x59, 0x50, 0x60, 0x09,
+ /*35b0:*/ 0x66, 0x0b, 0x0a, 0x5a, 0xc1, 0xd6, 0xe3, 0x96, 0xcd, 0xa2, 0x61, 0x26, 0x57, 0xa0, 0x51, 0x7e,
+ /*35c0:*/ 0x11, 0x21, 0xad, 0xce, 0xf5, 0x26, 0xdc, 0x8c, 0x3e, 0xd0, 0x61, 0xd8, 0x11, 0x2c, 0x7a, 0x68,
+ /*35d0:*/ 0xca, 0x95, 0x26, 0xde, 0x3c, 0xb4, 0xf1, 0x4b, 0x1e, 0xb8, 0x21, 0x83, 0x1e, 0xdb, 0xd9, 0x9d,
+ /*35e0:*/ 0x73, 0x60, 0xfa, 0x26, 0x2b, 0x41, 0xd1, 0x55, 0x16, 0x7b, 0x9f, 0xa8, 0xa4, 0x1f, 0x18, 0x5b,
+ /*35f0:*/ 0x6d, 0x22, 0xab, 0x73, 0x71, 0x7c, 0x04, 0xa8, 0xef, 0x3f, 0x1d, 0x2c, 0x9a, 0x98, 0x4e, 0xff,
+ /*3600:*/ 0xc7, 0xef, 0x7b, 0x63, 0x4d, 0x79, 0xe2, 0x33, 0x0a, 0xd8, 0x26, 0x30, 0xfc, 0xa3, 0x24, 0x5e,
+ /*3610:*/ 0x2f, 0xd7, 0xb3, 0x90, 0x1e, 0x45, 0x30, 0x41, 0x00, 0x59, 0x92, 0x62, 0x20, 0xb3, 0xff, 0x5d,
+ /*3620:*/ 0x47, 0x31, 0x6e, 0x87, 0xe5, 0x7e, 0x9d, 0x73, 0x8d, 0x3d, 0x74, 0x9c, 0x4b, 0xf7, 0xc8, 0x86,
+ /*3630:*/ 0xe4, 0xa7, 0xac, 0x4c, 0xf9, 0x51, 0x2f, 0x4d, 0xd2, 0x02, 0x9b, 0xcf, 0xb7, 0x68, 0x7f, 0x25,
+ /*3640:*/ 0xc7, 0x22, 0xfa, 0x75, 0xe5, 0xdd, 0x7e, 0xd3, 0x28, 0x07, 0x87, 0x78, 0x62, 0x20, 0x0e, 0xa1,
+ /*3650:*/ 0xab, 0x3e, 0xfd, 0xd0, 0x04, 0xe6, 0xd8, 0xf0, 0xa3, 0x1e, 0x05, 0xf5, 0x7e, 0x5e, 0xd8, 0xee,
+ /*3660:*/ 0x62, 0xc2, 0x71, 0xf7, 0x4a, 0x05, 0x84, 0x90, 0x15, 0x0a, 0x4a, 0x25, 0x32, 0x3c, 0x1c, 0xfe,
+ /*3670:*/ 0x14, 0xe2, 0x19, 0x3b, 0x97, 0xe4, 0x38, 0x8b, 0x7d, 0x30, 0x4b, 0x00, 0x62, 0x01, 0x68, 0x0f,
+ /*3680:*/ 0x01, 0xe3, 0xbb, 0x7d, 0x1a, 0x74, 0x0d, 0x09, 0x8e, 0x7a, 0xfe, 0x00, 0xc3, 0xb8, 0x23, 0xe7,
+ /*3690:*/ 0x98, 0xf5, 0xd7, 0x2b, 0x32, 0x2a, 0x4a, 0xbf, 0xe2, 0x21, 0x5f, 0xd8, 0x7a, 0x7c, 0x65, 0x0a,
+ /*36a0:*/ 0xba, 0x46, 0xfb, 0x66, 0x27, 0xdb, 0xd2, 0xa6, 0x52, 0x49, 0x7a, 0xb2, 0xee, 0x58, 0xe0, 0xc2,
+ /*36b0:*/ 0x90, 0x76, 0x90, 0x4a, 0x6f, 0xa1, 0x04, 0x44, 0xba, 0x9e, 0x40, 0x33, 0x16, 0x27, 0xa3, 0x0e,
+ /*36c0:*/ 0x6b, 0xed, 0x26, 0x0a, 0xaa, 0xc2, 0x09, 0x6a, 0xd6, 0x7c, 0x86, 0x9d, 0x3c, 0x57, 0x66, 0x01,
+ /*36d0:*/ 0xf0, 0x59, 0xd1, 0x2a, 0xf4, 0x5e, 0xa8, 0x4f, 0xff, 0x1a, 0xb2, 0xc6, 0xc6, 0xaa, 0x1e, 0x0d,
+ /*36e0:*/ 0x8d, 0x32, 0x05, 0x6d, 0x97, 0x25, 0xea, 0x32, 0x14, 0x4b, 0x6b, 0x20, 0x2a, 0x8c, 0x2b, 0xc1,
+ /*36f0:*/ 0x58, 0xcb, 0xa6, 0x87, 0x50, 0x96, 0xdb, 0x48, 0x3b, 0xcf, 0x6a, 0x41, 0x30, 0x72, 0x2d, 0x00,
+ /*3700:*/ 0x54, 0x6c, 0x03, 0x86, 0x88, 0x1a, 0x67, 0x8f, 0xa1, 0x4c, 0xdc, 0xf5, 0x7c, 0x16, 0xcf, 0x6f,
+ /*3710:*/ 0xa1, 0x5c, 0x59, 0x83, 0xb2, 0xca, 0xc3, 0xa4, 0x86, 0xa3, 0x0b, 0xab, 0x45, 0xeb, 0xf0, 0x21,
+ /*3720:*/ 0x8d, 0x06, 0x7f, 0x44, 0xa2, 0x4f, 0xeb, 0x63, 0x6f, 0x41, 0x11, 0x45, 0x7d, 0x00, 0xe9, 0x80,
+ /*3730:*/ 0x98, 0x25, 0xe3, 0x9c, 0x5f, 0x21, 0x9e, 0x3c, 0xfa, 0x8f, 0x0c, 0x35, 0x29, 0xce, 0x6e, 0xd6,
+ /*3740:*/ 0x48, 0x2c, 0x30, 0x90, 0xce, 0x35, 0x9d, 0x23, 0x10, 0x7d, 0x21, 0x0e, 0xc2, 0x93, 0x93, 0x8c,
+ /*3750:*/ 0xc5, 0xfc, 0xc6, 0x33, 0x05, 0x56, 0xa3, 0x53, 0x28, 0xd5, 0x3f, 0xc2, 0x80, 0x22, 0x9d, 0x5f,
+ /*3760:*/ 0xaa, 0x97, 0x06, 0x0b, 0xa1, 0xa7, 0x7b, 0x12, 0x7f, 0xcc, 0xca, 0xbc, 0x3e, 0x72, 0xd2, 0x17,
+ /*3770:*/ 0xb0, 0xd0, 0xe2, 0x0e, 0x36, 0xe4, 0xeb, 0xd5, 0x25, 0xc7, 0x94, 0xc4, 0x36, 0xa5, 0x2f, 0xee,
+ /*3780:*/ 0x03, 0xe3, 0x99, 0x3b, 0x9a, 0x57, 0x81, 0x71, 0xc6, 0xdc, 0x18, 0xea, 0x88, 0x10, 0x59, 0xfd,
+ /*3790:*/ 0x9d, 0x31, 0x71, 0x79, 0x55, 0x5d, 0x65, 0xf1, 0x20, 0x81, 0x9e, 0x0e, 0x42, 0x91, 0x2a, 0xa7,
+ /*37a0:*/ 0x0a, 0x79, 0xa8, 0x33, 0xd5, 0x00, 0x1d, 0x55, 0xb2, 0x47, 0xc6, 0xda, 0x47, 0x1e, 0x55, 0x7a,
+ /*37b0:*/ 0xb5, 0x16, 0xe9, 0x16, 0x75, 0x1c, 0x1a, 0x6e, 0x57, 0x30, 0xf4, 0xe1, 0xf0, 0x92, 0x2d, 0x28,
+ /*37c0:*/ 0xfa, 0x30, 0xc5, 0xc2, 0x6e, 0x6b, 0x0b, 0x98, 0x64, 0xd7, 0x3f, 0x6e, 0x73, 0x20, 0xb1, 0xda,
+ /*37d0:*/ 0x9a, 0xc4, 0x04, 0xe9, 0xc8, 0x8c, 0x09, 0xb3, 0x0f, 0x06, 0xa8, 0x07, 0x11, 0xc2, 0x15, 0x27,
+ /*37e0:*/ 0x08, 0xeb, 0x42, 0x29, 0xfb, 0x7c, 0xb2, 0xd5, 0x2c, 0x25, 0x85, 0x6b, 0x07, 0x51, 0xdc, 0x0a,
+ /*37f0:*/ 0x6b, 0xd4, 0xdb, 0x1d, 0xf7, 0x21, 0x59, 0xa0, 0xb5, 0xd9, 0xdf, 0x62, 0x34, 0xd0, 0xce, 0xad,
+ /*3800:*/ 0xfc, 0xad, 0x16, 0xcc, 0x01, 0x9d, 0x55, 0x5e, 0x84, 0xdd, 0x5f, 0xad, 0x3a, 0x36, 0x81, 0x5c,
+ /*3810:*/ 0xaf, 0x48, 0xce, 0x4d, 0xb7, 0x39, 0x02, 0x47, 0x20, 0x55, 0xd6, 0xbd, 0x4e, 0xf8, 0xe8, 0x78,
+ /*3820:*/ 0x74, 0xb3, 0x8e, 0x76, 0xbf, 0x71, 0x1e, 0x46, 0x5b, 0x33, 0x74, 0x23, 0xe1, 0x8b, 0xee, 0x89,
+ /*3830:*/ 0x38, 0xdb, 0xde, 0xb7, 0xae, 0x06, 0x3c, 0x51, 0x1b, 0xaf, 0xf6, 0x32, 0x61, 0x5b, 0xe2, 0xf6,
+ /*3840:*/ 0x7e, 0x0e, 0x78, 0xe8, 0xcf, 0x1a, 0x4a, 0x39, 0xf8, 0xda, 0x4f, 0x1b, 0xb5, 0xe4, 0x25, 0x3e,
+ /*3850:*/ 0x41, 0xef, 0x28, 0xcb, 0x17, 0x2f, 0xa4, 0x55, 0xd6, 0xf9, 0x88, 0x48, 0x26, 0x66, 0x56, 0xfe,
+ /*3860:*/ 0x30, 0x4d, 0x7d, 0x6b, 0xf8, 0x61, 0x80, 0x0f, 0x3d, 0x36, 0xb3, 0x7d, 0x73, 0x40, 0x17, 0x92,
+ /*3870:*/ 0x51, 0x58, 0x05, 0x49, 0x4b, 0x83, 0x13, 0x2a, 0x24, 0xd5, 0x92, 0xac, 0x40, 0x67, 0xe3, 0xa8,
+ /*3880:*/ 0xe9, 0xa6, 0x85, 0x58, 0xd7, 0xf4, 0xfc, 0x1d, 0xb5, 0x68, 0x19, 0xa7, 0xf8, 0xd8, 0xa5, 0x75,
+ /*3890:*/ 0xe0, 0x6d, 0xc6, 0x5a, 0xa6, 0xa3, 0x1c, 0x16, 0xd3, 0xf3, 0x61, 0xbb, 0x3c, 0x61, 0xb1, 0x3d,
+ /*38a0:*/ 0x58, 0xb9, 0x3f, 0x8a, 0xb2, 0x61, 0x6d, 0x78, 0x92, 0x20, 0x6e, 0xff, 0x69, 0x5e, 0x3e, 0xe2,
+ /*38b0:*/ 0x16, 0xb2, 0xc4, 0x44, 0x8d, 0xb9, 0x86, 0xa5, 0xcf, 0xc7, 0x97, 0xc1, 0x10, 0xed, 0xe7, 0x76,
+ /*38c0:*/ 0xe3, 0xa6, 0x51, 0x8f, 0x01, 0xb5, 0xd0, 0x34, 0xe2, 0xab, 0x7d, 0x45, 0xb6, 0x1f, 0x7c, 0xde,
+ /*38d0:*/ 0x5a, 0xa7, 0x59, 0x9e, 0xd2, 0x4b, 0x6d, 0xc8, 0xf4, 0x29, 0xb4, 0x73, 0x20, 0x0a, 0xc5, 0x60,
+ /*38e0:*/ 0xd1, 0x6e, 0xad, 0x8f, 0xb7, 0x56, 0xd3, 0xaa, 0xf9, 0xff, 0x16, 0xcc, 0x7b, 0x87, 0x2c, 0x3a,
+ /*38f0:*/ 0xa1, 0x1c, 0x57, 0x24, 0x5f, 0xb5, 0xb0, 0x99, 0x9c, 0xdb, 0xef, 0xdc, 0x4f, 0x6c, 0xea, 0x39,
+ /*3900:*/ 0x6d, 0x3d, 0x75, 0x65, 0x90, 0x79, 0xb5, 0x4b, 0xa9, 0x86, 0x74, 0xc5, 0xe6, 0x60, 0x7c, 0x2e,
+ /*3910:*/ 0xa4, 0x64, 0x93, 0xc8, 0x24, 0x54, 0x9b, 0xbf, 0x08, 0x07, 0xd1, 0x94, 0x87, 0xea, 0x9d, 0x88,
+ /*3920:*/ 0x19, 0x52, 0x32, 0xa4, 0xb5, 0x09, 0xf1, 0xb8, 0xee, 0x33, 0xc9, 0xff, 0x17, 0x9e, 0xbc, 0xb9,
+ /*3930:*/ 0xb4, 0x53, 0x93, 0xf4, 0x76, 0xa2, 0xd0, 0x87, 0xce, 0x22, 0xea, 0xee, 0xe3, 0xeb, 0x88, 0x58,
+ /*3940:*/ 0xb5, 0xb2, 0xd8, 0xed, 0x4c, 0x01, 0x2a, 0x8c, 0x25, 0x6f, 0xbf, 0xb1, 0xe5, 0x23, 0xf1, 0x7a,
+ /*3950:*/ 0x78, 0x2b, 0x32, 0x37, 0x99, 0xc3, 0xb0, 0x23, 0xa2, 0x9f, 0x72, 0xb6, 0x71, 0x88, 0x92, 0x32,
+ /*3960:*/ 0x52, 0x77, 0xd1, 0xb6, 0x0d, 0xbe, 0x6e, 0xd4, 0xdc, 0xf9, 0xb2, 0x0f, 0xcc, 0x8d, 0x8a, 0x96,
+ /*3970:*/ 0xce, 0x7f, 0x8f, 0xa4, 0x0e, 0x8f, 0x5f, 0x4c, 0x35, 0x54, 0xcb, 0xe2, 0xfa, 0xad, 0x5d, 0xd5,
+ /*3980:*/ 0x5d, 0x70, 0xf2, 0x82, 0x78, 0x27, 0xb9, 0xf9, 0x02, 0x15, 0x53, 0x00, 0xae, 0x29, 0x85, 0xf4,
+ /*3990:*/ 0xba, 0xc6, 0x0e, 0x6c, 0xb6, 0xe9, 0xef, 0xe1, 0x88, 0x42, 0xc5, 0x1a, 0x23, 0x5f, 0x19, 0xaf,
+ /*39a0:*/ 0x15, 0x9e, 0x26, 0x48, 0x42, 0x91, 0xc5, 0xc0, 0xfe, 0xfb, 0x72, 0x0c, 0x98, 0x98, 0xfa, 0xed,
+ /*39b0:*/ 0x94, 0x12, 0x1f, 0xc5, 0x14, 0x00, 0x55, 0xa5, 0x10, 0xc6, 0xf6, 0x3e, 0x64, 0x8c, 0xa7, 0x4e,
+ /*39c0:*/ 0x11, 0x84, 0x16, 0xeb, 0x48, 0x90, 0x49, 0xc2, 0xbf, 0x3c, 0xab, 0x54, 0xe4, 0x28, 0x59, 0x43,
+ /*39d0:*/ 0x77, 0xad, 0x1a, 0x14, 0xd8, 0xc3, 0x3e, 0x88, 0x3f, 0x7f, 0x38, 0xbf, 0xe2, 0x65, 0x89, 0x6d,
+ /*39e0:*/ 0x9e, 0x4e, 0x91, 0x5f, 0x6a, 0x70, 0x48, 0x17, 0xa0, 0x87, 0x68, 0x0d, 0x4b, 0x7c, 0x56, 0x1f,
+ /*39f0:*/ 0x57, 0xb0, 0x4d, 0x54, 0x78, 0x3e, 0x2b, 0xdb, 0x12, 0xed, 0x1d, 0x69, 0x7a, 0x48, 0x03, 0x46,
+ /*3a00:*/ 0x3c, 0xa8, 0x45, 0xff, 0xc7, 0x23, 0x17, 0x2d, 0xdd, 0x6b, 0xad, 0x4a, 0xff, 0x9d, 0x8d, 0xa2,
+ /*3a10:*/ 0x9e, 0x3d, 0x5b, 0xe6, 0x7a, 0x0f, 0x31, 0x6e, 0x0a, 0xca, 0xc4, 0x48, 0x91, 0xe5, 0xd2, 0x38,
+ /*3a20:*/ 0xfe, 0x87, 0x1b, 0x4a, 0xa1, 0xca, 0xd6, 0xad, 0x4d, 0x90, 0xff, 0x65, 0x93, 0xc1, 0x22, 0xdd,
+ /*3a30:*/ 0x46, 0x16, 0x89, 0x08, 0x6e, 0x6d, 0x35, 0x5e, 0x13, 0x95, 0x6d, 0x0e, 0xce, 0xd1, 0x3c, 0x98,
+ /*3a40:*/ 0x15, 0x0a, 0xee, 0xaa, 0xbb, 0x7e, 0xba, 0x21, 0x1c, 0x1d, 0x52, 0x6d, 0xaa, 0x86, 0xcd, 0x42,
+ /*3a50:*/ 0x52, 0xf4, 0xdf, 0xca, 0x57, 0xf8, 0x26, 0x7b, 0xc7, 0x31, 0x37, 0xec, 0xbb, 0x5b, 0x61, 0xe5,
+ /*3a60:*/ 0xda, 0xa9, 0x93, 0xd6, 0xe1, 0xd7, 0xcf, 0xdc, 0xeb, 0x3a, 0xcb, 0x19, 0x73, 0x40, 0xf3, 0xde,
+ /*3a70:*/ 0x5d, 0x4a, 0xaf, 0x46, 0x62, 0xbb, 0xf7, 0x4b, 0x4c, 0xe1, 0x50, 0xa7, 0xc5, 0x14, 0x71, 0xbf,
+ /*3a80:*/ 0x3a, 0x03, 0x8a, 0xd2, 0xaa, 0x9a, 0x44, 0x91, 0xaf, 0xd1, 0x44, 0x24, 0xa4, 0x0e, 0x47, 0x32,
+ /*3a90:*/ 0x51, 0x62, 0x14, 0x10, 0x8d, 0x21, 0x2d, 0x7e, 0x62, 0x12, 0x5d, 0xc1, 0x46, 0xcc, 0x9d, 0xd0,
+ /*3aa0:*/ 0xa0, 0xa2, 0x35, 0x33, 0xcb, 0x4c, 0xc0, 0x5a, 0x20, 0x2e, 0xc8, 0x49, 0x03, 0x12, 0x00, 0xc9,
+ /*3ab0:*/ 0x5c, 0xc8, 0xc3, 0xff, 0xfa, 0x1f, 0x85, 0x18, 0x78, 0xe4, 0x7f, 0x95, 0x07, 0xce, 0xb3, 0xf3,
+ /*3ac0:*/ 0xb1, 0x75, 0x76, 0xf3, 0xd8, 0x82, 0xc8, 0xc9, 0x5e, 0xb5, 0x30, 0xa6, 0xbf, 0xcb, 0x0a, 0x21,
+ /*3ad0:*/ 0x1e, 0x98, 0x06, 0x8e, 0x4c, 0x7a, 0xb4, 0x72, 0x36, 0xf5, 0xca, 0x07, 0xce, 0x90, 0xf2, 0x1f,
+ /*3ae0:*/ 0xcd, 0x68, 0xac, 0x7f, 0x12, 0x8a, 0x19, 0x2c, 0x60, 0x3a, 0x9a, 0x65, 0x79, 0x48, 0x01, 0x89,
+ /*3af0:*/ 0x9e, 0x61, 0xff, 0xe4, 0x36, 0x4f, 0x0d, 0x9b, 0x69, 0xaa, 0x9f, 0x01, 0x87, 0x53, 0x13, 0x0c,
+ /*3b00:*/ 0x93, 0x20, 0x21, 0x87, 0x41, 0x48, 0xfc, 0x82, 0xe9, 0x12, 0x4c, 0x17, 0xd0, 0xee, 0xdc, 0x68,
+ /*3b10:*/ 0xf9, 0xdd, 0x28, 0x13, 0xa4, 0x28, 0x12, 0x97, 0x38, 0xe9, 0xb9, 0x7c, 0x0e, 0xfe, 0xc3, 0xd3,
+ /*3b20:*/ 0x86, 0x7d, 0xb3, 0x82, 0x66, 0xb8, 0x98, 0xeb, 0xdd, 0x24, 0x82, 0xa6, 0x26, 0x82, 0xd0, 0xf0,
+ /*3b30:*/ 0x44, 0xd1, 0x1e, 0x49, 0xee, 0xf5, 0x48, 0x75, 0x87, 0xca, 0xe2, 0xdf, 0x81, 0x9a, 0x5b, 0x83,
+ /*3b40:*/ 0xfd, 0xa1, 0xef, 0x87, 0x83, 0x95, 0xe5, 0x8c, 0x74, 0x35, 0x38, 0xd9, 0x7c, 0x56, 0x5f, 0xf0,
+ /*3b50:*/ 0xd4, 0x60, 0xb8, 0x97, 0xe2, 0x96, 0x06, 0xd3, 0xc9, 0xc9, 0x88, 0x31, 0x02, 0x2a, 0xb2, 0x28,
+ /*3b60:*/ 0xb2, 0xcc, 0x91, 0xcb, 0x01, 0xec, 0xb5, 0x9d, 0x09, 0x6e, 0xd0, 0xde, 0xf0, 0xce, 0x72, 0x93,
+ /*3b70:*/ 0x6c, 0xcb, 0xaa, 0x2b, 0x29, 0x84, 0xbe, 0xab, 0xff, 0x42, 0x2e, 0x4f, 0xc1, 0x65, 0x22, 0x91,
+ /*3b80:*/ 0xac, 0xb3, 0xfb, 0x53, 0x98, 0x56, 0x8f, 0x16, 0xbe, 0x1d, 0x7f, 0x29, 0x17, 0xdc, 0x9d, 0xf8,
+ /*3b90:*/ 0x59, 0x8b, 0xa9, 0x76, 0x01, 0xa8, 0x24, 0xa7, 0x00, 0xdd, 0xa3, 0xe5, 0x6e, 0x27, 0x66, 0x2f,
+ /*3ba0:*/ 0xe7, 0x1d, 0x0d, 0x2a, 0x75, 0x80, 0x10, 0x38, 0xf6, 0x3d, 0x45, 0x18, 0xb0, 0x31, 0xcb, 0xe0,
+ /*3bb0:*/ 0x8e, 0x73, 0x14, 0xbc, 0x36, 0x16, 0xf3, 0xa8, 0xd5, 0x3e, 0xf6, 0xdc, 0xa7, 0x33, 0xcb, 0x49,
+ /*3bc0:*/ 0xb6, 0x45, 0x00, 0xb6, 0xcc, 0x9d, 0x40, 0xbc, 0x1d, 0x12, 0xbb, 0xe4, 0xd0, 0x3f, 0xa6, 0x28,
+ /*3bd0:*/ 0x5d, 0x0f, 0xa2, 0x90, 0xbe, 0x1f, 0x90, 0x6a, 0xb8, 0x22, 0x89, 0xf9, 0x3a, 0xdd, 0x7a, 0xe8,
+ /*3be0:*/ 0x63, 0x1f, 0x1f, 0x15, 0xa1, 0xbd, 0x72, 0x6d, 0x83, 0x02, 0x5e, 0x95, 0x5c, 0x33, 0x20, 0xb4,
+ /*3bf0:*/ 0xe5, 0x39, 0x87, 0xd9, 0x57, 0xd7, 0xb6, 0x86, 0x21, 0xff, 0xfa, 0x67, 0x7e, 0x94, 0xac, 0xda,
+ /*3c00:*/ 0xf0, 0xe0, 0x4e, 0xc4, 0x88, 0x84, 0x01, 0xcc, 0xfa, 0x37, 0x27, 0xbe, 0x63, 0x8f, 0x41, 0x94,
+ /*3c10:*/ 0x75, 0x06, 0x8c, 0x10, 0xd5, 0xf7, 0xe1, 0x2c, 0x92, 0xe1, 0x4f, 0xda, 0xdf, 0xac, 0x64, 0xe8,
+ /*3c20:*/ 0x8e, 0xbb, 0x8b, 0x9a, 0x70, 0x57, 0x50, 0xb3, 0x63, 0x77, 0xcf, 0xa6, 0xb0, 0x91, 0x13, 0xa4,
+ /*3c30:*/ 0x29, 0xf1, 0x27, 0x1d, 0x4e, 0x37, 0x6b, 0x81, 0xd3, 0x0d, 0x3c, 0xb6, 0x91, 0x42, 0xf4, 0x70,
+ /*3c40:*/ 0x64, 0x86, 0x2f, 0xee, 0xec, 0xc2, 0x97, 0xb7, 0xb6, 0xf2, 0x86, 0x8a, 0x7a, 0x2d, 0x6c, 0x06,
+ /*3c50:*/ 0x5d, 0x24, 0xd9, 0xf9, 0xc8, 0xd2, 0xd6, 0xb5, 0xb8, 0xd7, 0x0a, 0x1e, 0x31, 0x4f, 0x04, 0x9c,
+ /*3c60:*/ 0x4b, 0xe0, 0x21, 0xdf, 0xb3, 0x8d, 0xdf, 0xc7, 0x9d, 0x57, 0x62, 0xa4, 0xff, 0x88, 0x07, 0x0e,
+ /*3c70:*/ 0xad, 0x7f, 0x39, 0xe8, 0x8a, 0x04, 0x64, 0xde, 0x94, 0xc3, 0xa3, 0xd0, 0xc8, 0x40, 0x27, 0x63,
+ /*3c80:*/ 0x76, 0x4b, 0xa0, 0xe1, 0xdc, 0xf1, 0xec, 0x93, 0xd3, 0xa2, 0x69, 0x8a, 0xa7, 0xe2, 0x33, 0x97,
+ /*3c90:*/ 0x58, 0xff, 0x7e, 0x66, 0x24, 0x2c, 0x61, 0x7f, 0x3a, 0xdf, 0x92, 0x31, 0x4b, 0x66, 0x52, 0x7e,
+ /*3ca0:*/ 0xa3, 0x88, 0x7e, 0x57, 0xe6, 0x51, 0xf6, 0x7f, 0x98, 0x93, 0x6b, 0xd7, 0x7d, 0x7d, 0xee, 0x72,
+ /*3cb0:*/ 0xc6, 0x15, 0xe1, 0x30, 0x2a, 0xeb, 0x48, 0x8f, 0x8d, 0xed, 0x62, 0x0c, 0x53, 0x93, 0x62, 0x1e,
+ /*3cc0:*/ 0x61, 0x1a, 0x2e, 0x34, 0xad, 0xd2, 0x47, 0x0d, 0x08, 0x8e, 0xae, 0x35, 0x77, 0x25, 0x67, 0x00,
+ /*3cd0:*/ 0x9a, 0xf0, 0x51, 0x5e, 0x16, 0x94, 0x31, 0xd7, 0x24, 0x17, 0xa5, 0xe5, 0x2e, 0x92, 0x36, 0xcb,
+ /*3ce0:*/ 0x36, 0xf8, 0x16, 0xb7, 0x7b, 0xff, 0x2d, 0x25, 0x02, 0x00, 0xb3, 0x75, 0x78, 0xd5, 0xb2, 0x69,
+ /*3cf0:*/ 0xae, 0x95, 0xd8, 0xc4, 0x4e, 0xa1, 0x6f, 0x93, 0x20, 0xae, 0x74, 0x56, 0x7a, 0xed, 0x24, 0xbb,
+ /*3d00:*/ 0xc7, 0x8d, 0x0a, 0xbe, 0x9f, 0x5c, 0xd4, 0xa2, 0x20, 0xe9, 0x5e, 0x01, 0x6d, 0x16, 0xe1, 0x59,
+ /*3d10:*/ 0x05, 0x65, 0xa7, 0x5b, 0xdc, 0x3f, 0x15, 0xf0, 0x43, 0x97, 0x0f, 0x72, 0x60, 0x47, 0xf8, 0x1c,
+ /*3d20:*/ 0xff, 0xdc, 0xcf, 0xb1, 0xc3, 0x2a, 0x44, 0x9d, 0x37, 0xec, 0x8b, 0x0d, 0x7d, 0x37, 0xa5, 0x2f,
+ /*3d30:*/ 0x3c, 0x74, 0xca, 0x90, 0x2c, 0x0c, 0x8f, 0x88, 0x01, 0x48, 0x81, 0x0b, 0x8b, 0xf8, 0xc7, 0xb8,
+ /*3d40:*/ 0x96, 0x45, 0x06, 0x4e, 0x60, 0x04, 0xd8, 0xae, 0x30, 0xcb, 0x6b, 0xf9, 0xdd, 0x0a, 0x31, 0x8d,
+ /*3d50:*/ 0xde, 0x60, 0x42, 0xf3, 0xf1, 0x87, 0x31, 0x85, 0x25, 0x62, 0xcc, 0x92, 0x54, 0x49, 0x96, 0xd5,
+ /*3d60:*/ 0x72, 0xc7, 0xb7, 0xf1, 0x01, 0x0b, 0x30, 0xe5, 0x8b, 0xba, 0x49, 0x05, 0xe0, 0xa2, 0x54, 0xee,
+ /*3d70:*/ 0x45, 0xae, 0xd3, 0x75, 0x35, 0x61, 0x9a, 0x10, 0xee, 0x1f, 0x2a, 0x83, 0xfe, 0x81, 0x0d, 0xc4,
+ /*3d80:*/ 0xc2, 0x35, 0xc9, 0xf0, 0xed, 0x01, 0xf3, 0x5f, 0x9b, 0x66, 0x41, 0xc1, 0x10, 0x04, 0xc3, 0x57,
+ /*3d90:*/ 0x04, 0x74, 0x31, 0x72, 0xd9, 0x15, 0x9d, 0xe6, 0xc9, 0x2e, 0xb9, 0xd0, 0x2c, 0xe5, 0x27, 0x85,
+ /*3da0:*/ 0xa8, 0xe8, 0x8b, 0x44, 0x20, 0x99, 0x1e, 0x12, 0x33, 0xff, 0x4c, 0xa1, 0x59, 0x2c, 0x44, 0xd2,
+ /*3db0:*/ 0x51, 0x94, 0xa1, 0xc1, 0x65, 0xe8, 0x77, 0xad, 0xf7, 0x2c, 0x3c, 0x1b, 0xeb, 0x85, 0x31, 0x7e,
+ /*3dc0:*/ 0x7a, 0x3d, 0xe3, 0x49, 0xc3, 0xe7, 0x8f, 0xe1, 0x39, 0x88, 0x33, 0xd1, 0x8d, 0xf5, 0xec, 0x2c,
+ /*3dd0:*/ 0x43, 0x6a, 0x63, 0x8a, 0xad, 0x7b, 0x61, 0x8c, 0x55, 0x10, 0x89, 0x2e, 0x50, 0x0c, 0x72, 0x49,
+ /*3de0:*/ 0xad, 0xaf, 0xc4, 0x3f, 0x34, 0xdb, 0xc9, 0x23, 0x90, 0x18, 0xd6, 0x8c, 0xe9, 0xab, 0x5b, 0x01,
+ /*3df0:*/ 0x9c, 0x5d, 0x05, 0x65, 0x5c, 0x14, 0x27, 0x28, 0xa7, 0x42, 0x93, 0xbe, 0xde, 0xd2, 0x3a, 0x1f,
+ /*3e00:*/ 0x3f, 0x32, 0xaf, 0x89, 0x34, 0xfa, 0x7a, 0x0d, 0xdd, 0x66, 0xdc, 0x16, 0x60, 0x69, 0x24, 0x04,
+ /*3e10:*/ 0x1e, 0x9e, 0x55, 0x09, 0x3c, 0x98, 0xb3, 0x95, 0xcc, 0xa4, 0x51, 0xb4, 0x17, 0x80, 0x3a, 0x74,
+ /*3e20:*/ 0x2c, 0x2f, 0x54, 0x28, 0x83, 0xf9, 0xc4, 0x8a, 0x6b, 0x42, 0x57, 0x6c, 0x14, 0xba, 0xca, 0x51,
+ /*3e30:*/ 0x27, 0xeb, 0x90, 0x98, 0x59, 0x84, 0x0c, 0xea, 0x90, 0x6e, 0xf3, 0xb2, 0xc3, 0x50, 0xd2, 0x4e,
+ /*3e40:*/ 0xa0, 0xb3, 0xc0, 0x09, 0x41, 0x59, 0xb5, 0x18, 0x0e, 0x14, 0x27, 0xb1, 0x95, 0x21, 0x0c, 0xe7,
+ /*3e50:*/ 0x24, 0x79, 0x62, 0x9c, 0x90, 0xe5, 0x44, 0x98, 0x7b, 0x5f, 0xba, 0x46, 0x5f, 0x61, 0xbb, 0x25,
+ /*3e60:*/ 0xd3, 0x3b, 0x63, 0xdf, 0xc4, 0x76, 0xce, 0x55, 0x4d, 0xaf, 0x69, 0xfd, 0xab, 0xaa, 0x2c, 0x52,
+ /*3e70:*/ 0xaa, 0x20, 0x38, 0x7e, 0x29, 0x4a, 0x7d, 0x09, 0xee, 0xa8, 0x77, 0xe0, 0xed, 0x54, 0x64, 0x50,
+ /*3e80:*/ 0x19, 0x1f, 0xc7, 0x34, 0x79, 0xbf, 0x06, 0xf9, 0xac, 0x61, 0x6a, 0xd7, 0x8e, 0xb0, 0x65, 0x4d,
+ /*3e90:*/ 0xa0, 0xc1, 0x9a, 0xbb, 0x44, 0xbd, 0x30, 0xa0, 0xfb, 0xf5, 0x35, 0x91, 0xa7, 0x09, 0xbb, 0x48,
+ /*3ea0:*/ 0x4f, 0x94, 0x33, 0xe2, 0x3d, 0x79, 0xc0, 0x0b, 0x27, 0x42, 0x9f, 0x7c, 0x4c, 0x1a, 0xe5, 0x17,
+ /*3eb0:*/ 0xb2, 0xdf, 0xa3, 0x87, 0x4b, 0x76, 0xd3, 0x78, 0x24, 0x6b, 0xd4, 0x54, 0x7e, 0x73, 0x37, 0x2b,
+ /*3ec0:*/ 0xe1, 0xbe, 0xba, 0xbd, 0x6b, 0xb4, 0x5c, 0x7b, 0xba, 0xbc, 0x98, 0x65, 0xcb, 0xdf, 0xb9, 0x99,
+ /*3ed0:*/ 0x25, 0xeb, 0xe5, 0x93, 0xff, 0x8f, 0x82, 0x6c, 0x5f, 0x6b, 0xde, 0x47, 0xb7, 0x16, 0x92, 0x81,
+ /*3ee0:*/ 0x7c, 0x77, 0xe3, 0x0b, 0x6f, 0xf2, 0x9a, 0xa0, 0x98, 0xf4, 0xf5, 0xcd, 0x6e, 0xf4, 0x64, 0x65,
+ /*3ef0:*/ 0xc2, 0x87, 0x85, 0x54, 0x32, 0x11, 0x37, 0xde, 0xfb, 0x7e, 0x51, 0x64, 0x4b, 0x7f, 0x57, 0x34,
+ /*3f00:*/ 0x1c, 0xa3, 0x37, 0x11, 0x1e, 0x66, 0x43, 0xf5, 0x6d, 0x4d, 0x08, 0x94, 0x7c, 0x79, 0xb7, 0xfe,
+ /*3f10:*/ 0x20, 0x78, 0x2e, 0x19, 0x49, 0xf6, 0x3b, 0x86, 0xe4, 0xa1, 0xc5, 0x65, 0xef, 0xa9, 0x97, 0x55,
+ /*3f20:*/ 0x37, 0xed, 0x23, 0xd2, 0x5a, 0x14, 0x5a, 0xde, 0x6c, 0xda, 0x50, 0xfb, 0xcb, 0x56, 0x56, 0x8e,
+ /*3f30:*/ 0xf1, 0xd1, 0x18, 0x0d, 0x17, 0x7f, 0x3a, 0xb3, 0x07, 0x25, 0x1a, 0x76, 0x1f, 0xd8, 0x67, 0x97,
+ /*3f40:*/ 0x43, 0xfa, 0x02, 0xa8, 0x7c, 0x6d, 0x56, 0xb1, 0xd4, 0xba, 0x1d, 0x06, 0x60, 0x86, 0x66, 0xd6,
+ /*3f50:*/ 0xd5, 0x1b, 0x5e, 0x64, 0xf5, 0x02, 0x44, 0xa4, 0x8d, 0x21, 0x27, 0xd2, 0x16, 0xe4, 0xd9, 0xad,
+ /*3f60:*/ 0xac, 0x08, 0x12, 0x81, 0xd6, 0xe4, 0x4e, 0x68, 0xe4, 0xaf, 0x62, 0x8c, 0x7e, 0xef, 0x42, 0xa9,
+ /*3f70:*/ 0xff, 0x3f, 0x3b, 0x6c, 0x9f, 0xec, 0xa5, 0x9c, 0xf5, 0xf8, 0x4f, 0xa9, 0x37, 0x79, 0x86, 0x92,
+ /*3f80:*/ 0x2b, 0x6d, 0x75, 0xbc, 0x50, 0x5e, 0x78, 0x1c, 0xbe, 0x03, 0xcf, 0x7d, 0x37, 0x21, 0xcf, 0x43,
+ /*3f90:*/ 0x4e, 0x2b, 0x68, 0x7b, 0x77, 0x44, 0x39, 0x85, 0x1b, 0x1c, 0x4a, 0x1f, 0x75, 0x68, 0xa6, 0x9c,
+ /*3fa0:*/ 0x8c, 0x0f, 0x35, 0x78, 0x20, 0x1a, 0xe5, 0xa6, 0x2b, 0xbf, 0x4a, 0x08, 0x04, 0xe5, 0x9d, 0x08,
+ /*3fb0:*/ 0x4f, 0x03, 0x11, 0xc9, 0x08, 0x1a, 0xde, 0xd1, 0x9d, 0x7c, 0x74, 0x49, 0x5d, 0x09, 0xff, 0x38,
+ /*3fc0:*/ 0x29, 0x76, 0xa6, 0xf8, 0x9a, 0xda, 0xda, 0x9a, 0xb6, 0xc9, 0x39, 0x59, 0x62, 0xe1, 0x4b, 0x7f,
+ /*3fd0:*/ 0x11, 0xac, 0xa6, 0x21, 0x85, 0x0b, 0x2a, 0x0e, 0xa6, 0x89, 0x61, 0x00, 0xdc, 0xb0, 0x5a, 0x9b,
+ /*3fe0:*/ 0x1b, 0xbd, 0x44, 0x74, 0x01, 0xbc, 0x31, 0x7f, 0xbb, 0x2f, 0x4c, 0x83, 0x8d, 0xe2, 0x99, 0xea,
+ /*3ff0:*/ 0xad, 0xbb, 0xb4, 0xe5, 0xb6, 0x4d, 0xa8, 0xf6, 0x99, 0xe2, 0x85, 0x27, 0x08, 0x70, 0x84, 0x05,
+ /*4000:*/ 0xed, 0x8d, 0x0e, 0x89, 0x9a, 0x03, 0xc3, 0xe6, 0xa6, 0xe1, 0x8d, 0xc3, 0x2e, 0xdd, 0xc8, 0x53,
+ /*4010:*/ 0xb8, 0xd7, 0x88, 0xf6, 0x88, 0xb2, 0xb4, 0x38, 0xa6, 0xc4, 0xc1, 0x2c, 0x71, 0x41, 0x8f, 0xc3,
+ /*4020:*/ 0x51, 0x77, 0x20, 0x0c, 0xa6, 0x4c, 0xac, 0xcd, 0xf5, 0xae, 0x4c, 0x37, 0x57, 0xf5, 0x1c, 0x09,
+ /*4030:*/ 0xe3, 0xcf, 0x5c, 0x69, 0xed, 0x92, 0x5e, 0xce, 0xf1, 0x83, 0x41, 0xf7, 0xa1, 0x05, 0x3f, 0x56,
+ /*4040:*/ 0x5e, 0x76, 0x06, 0x63, 0xb7, 0x73, 0x2a, 0xe4, 0x83, 0x10, 0xe6, 0x30, 0x7e, 0x9a, 0xd6, 0xc5,
+ /*4050:*/ 0x8d, 0x7f, 0xf8, 0xeb, 0xf6, 0x05, 0x32, 0x24, 0xf1, 0x70, 0xa9, 0x85, 0x69, 0x5c, 0x37, 0x02,
+ /*4060:*/ 0x4a, 0x7e, 0x23, 0xee, 0x91, 0xa2, 0xdd, 0xaa, 0x51, 0x6b, 0x1b, 0x39, 0x76, 0x28, 0x9e, 0xbf,
+ /*4070:*/ 0xe5, 0xd9, 0xfe, 0x0b, 0x89, 0x63, 0xff, 0x47, 0x50, 0x8f, 0x66, 0x0e, 0x96, 0x0f, 0x3d, 0x8c,
+ /*4080:*/ 0xdd, 0x55, 0xfd, 0xae, 0x37, 0x18, 0x71, 0x0e, 0x08, 0x48, 0x65, 0x53, 0xb8, 0x1b, 0x9d, 0xc5,
+ /*4090:*/ 0x1f, 0x0f, 0x9e, 0x9a, 0xcf, 0xfb, 0x37, 0xf0, 0x6e, 0x5c, 0x8b, 0xec, 0x3b, 0x3a, 0xd3, 0xce,
+ /*40a0:*/ 0xc5, 0x94, 0x24, 0x88, 0x0b, 0x6a, 0x03, 0x4c, 0x52, 0xf7, 0xb2, 0x1d, 0x07, 0xae, 0x81, 0x3d,
+ /*40b0:*/ 0xf1, 0xfd, 0x8e, 0xcc, 0x3a, 0x47, 0x6e, 0xa9, 0x19, 0xf7, 0x16, 0x8e, 0x15, 0x93, 0x56, 0x20,
+ /*40c0:*/ 0x7e, 0x67, 0xd3, 0x17, 0xcb, 0xfa, 0x4b, 0xf1, 0x63, 0x02, 0x81, 0x14, 0x1e, 0xbd, 0x73, 0x95,
+ /*40d0:*/ 0xcc, 0xfd, 0x70, 0xa6, 0x30, 0x3e, 0x41, 0x64, 0x5a, 0x12, 0xc6, 0x50, 0x28, 0xf0, 0x83, 0x60,
+ /*40e0:*/ 0xd7, 0xb9, 0x72, 0x1d, 0x87, 0xab, 0x74, 0xf5, 0xb7, 0x30, 0xa1, 0xae, 0x89, 0x76, 0xfe, 0x92,
+ /*40f0:*/ 0x07, 0x34, 0x78, 0x8e, 0x8b, 0xb1, 0x44, 0x85, 0x37, 0xcf, 0xe8, 0x56, 0xe7, 0xaa, 0xa9, 0x70,
+ /*4100:*/ 0xe9, 0x79, 0x59, 0xa6, 0x3c, 0x9d, 0xad, 0xc5, 0x0f, 0x7d, 0x3c, 0x8e, 0xb9, 0xdc, 0xd4, 0xf7,
+ /*4110:*/ 0xe4, 0xcd, 0xa7, 0x27, 0xfd, 0x20, 0x33, 0x9d, 0x64, 0xcd, 0xcc, 0xaf, 0xb9, 0x43, 0xc6, 0x6b,
+ /*4120:*/ 0xcd, 0xaa, 0xf8, 0x8a, 0x97, 0x30, 0x95, 0xcc, 0xf2, 0x9f, 0x70, 0x25, 0x3f, 0x7b, 0x27, 0x0f,
+ /*4130:*/ 0xc2, 0x0f, 0xd7, 0x33, 0xde, 0x08, 0x90, 0xc2, 0x5d, 0xb5, 0xc0, 0x1a, 0x39, 0x86, 0xb3, 0x62,
+ /*4140:*/ 0xeb, 0x19, 0xee, 0x4c, 0x10, 0xe6, 0x75, 0x40, 0x7a, 0x9d, 0x8f, 0x80, 0x39, 0x75, 0x77, 0x37,
+ /*4150:*/ 0x27, 0x4e, 0x36, 0xa6, 0xc6, 0x7a, 0xb9, 0x0d, 0x7c, 0x5c, 0x7f, 0xbc, 0xe5, 0x9c, 0xe2, 0x13,
+ /*4160:*/ 0xfe, 0x3f, 0xc6, 0x30, 0xf8, 0xbb, 0xe6, 0x19, 0xcf, 0x2e, 0xfb, 0x6c, 0x10, 0x38, 0x61, 0x72,
+ /*4170:*/ 0xe3, 0x32, 0xfc, 0xcb, 0x72, 0x88, 0x6b, 0x62, 0x20, 0x32, 0x0b, 0xbc, 0xc3, 0xfd, 0x23, 0x9c,
+ /*4180:*/ 0xad, 0x96, 0xa7, 0xa4, 0x4e, 0x40, 0xfc, 0xac, 0x04, 0xbc, 0x8e, 0x17, 0x43, 0xba, 0x2b, 0xbf,
+ /*4190:*/ 0x0a, 0x5f, 0x2b, 0xaa, 0x74, 0x06, 0x1f, 0x75, 0x8e, 0xa4, 0x57, 0xdf, 0x1e, 0x4c, 0xfa, 0xb9,
+ /*41a0:*/ 0xb4, 0x33, 0x72, 0xd7, 0x88, 0x6b, 0x19, 0xb0, 0x36, 0x76, 0x07, 0xb2, 0x79, 0x77, 0x50, 0xc1,
+ /*41b0:*/ 0xb9, 0xa5, 0x28, 0x8d, 0xc8, 0x70, 0x3d, 0xdf, 0xe9, 0x96, 0x49, 0xf4, 0xbd, 0xed, 0x62, 0x3c,
+ /*41c0:*/ 0xe0, 0x63, 0x41, 0x84, 0x55, 0xef, 0x54, 0x2f, 0xb4, 0x94, 0x7d, 0x32, 0x56, 0x01, 0x04, 0x40,
+ /*41d0:*/ 0x73, 0x43, 0xdd, 0x84, 0xbe, 0xe6, 0x2f, 0xa1, 0xa7, 0xec, 0xed, 0x6f, 0x45, 0xd3, 0x74, 0x58,
+ /*41e0:*/ 0x5f, 0xae, 0x10, 0x4a, 0xe3, 0x7e, 0xc9, 0xca, 0xee, 0xe0, 0x05, 0xc5, 0x95, 0x34, 0xff, 0x5e,
+ /*41f0:*/ 0xda, 0x21, 0xf3, 0x49, 0x80, 0xf8, 0xd8, 0x33, 0x3a, 0x93, 0xab, 0xdd, 0x76, 0xdc, 0x77, 0x06,
+ /*4200:*/ 0x83, 0x9b, 0x67, 0x8a, 0xa0, 0x72, 0x2a, 0x32, 0x24, 0x00, 0x85, 0x1e, 0x27, 0x22, 0x91, 0x85,
+ /*4210:*/ 0xde, 0xb0, 0x9b, 0xc0, 0xa8, 0x03, 0x90, 0x9e, 0xe3, 0x18, 0x64, 0x91, 0x2c, 0xaa, 0x21, 0xbb,
+ /*4220:*/ 0xca, 0x34, 0x42, 0x9c, 0xcd, 0x73, 0x5e, 0xff, 0x7a, 0x9a, 0xc0, 0x1c, 0x6e, 0xb2, 0x45, 0xec,
+ /*4230:*/ 0x09, 0xe4, 0xed, 0x3f, 0xa2, 0xf2, 0x82, 0xa8, 0xa3, 0xc0, 0xd3, 0x4e, 0xbc, 0xe5, 0x11, 0x9b,
+ /*4240:*/ 0x5e, 0x3d, 0x0e, 0x1e, 0xcc, 0x85, 0x4c, 0x5d, 0x97, 0xa6, 0xa2, 0xe7, 0x90, 0xad, 0x0a, 0xf5,
+ /*4250:*/ 0x83, 0x65, 0xc6, 0xcc, 0x4f, 0x52, 0xe0, 0x38, 0xe9, 0x25, 0xa7, 0x83, 0x03, 0x4a, 0x0f, 0x72,
+ /*4260:*/ 0xe5, 0xc9, 0x36, 0x32, 0xb9, 0x7d, 0x58, 0xa2, 0x05, 0x0e, 0x30, 0x13, 0xd3, 0xfc, 0x30, 0x86,
+ /*4270:*/ 0xbd, 0xab, 0x67, 0xcf, 0x86, 0x4d, 0xa5, 0xfe, 0x6d, 0xb5, 0x91, 0x1e, 0xcf, 0x44, 0xc8, 0x40,
+ /*4280:*/ 0x2b, 0xaa, 0x96, 0x33, 0xb5, 0x8e, 0x32, 0x59, 0x0d, 0x0c, 0x6d, 0x91, 0x24, 0x7a, 0x49, 0x1a,
+ /*4290:*/ 0x8d, 0x8f, 0x14, 0xa6, 0x25, 0x35, 0xef, 0x8f, 0xb6, 0x53, 0xaf, 0xe2, 0xa5, 0xa4, 0x3d, 0x19,
+ /*42a0:*/ 0x9e, 0x61, 0x5c, 0x38, 0x60, 0xdc, 0x7a, 0x90, 0xda, 0xb0, 0xc7, 0x78, 0x2d, 0xc9, 0x8e, 0xc4,
+ /*42b0:*/ 0x2a, 0xe5, 0x9d, 0x10, 0x26, 0xef, 0x4f, 0x79, 0xf2, 0xf7, 0x89, 0x79, 0xdb, 0xc1, 0xf3, 0xc3,
+ /*42c0:*/ 0x38, 0x6a, 0xd3, 0x59, 0x31, 0x69, 0xfd, 0xd6, 0x9d, 0x26, 0x54, 0x44, 0x0e, 0x2b, 0xc5, 0x9a,
+ /*42d0:*/ 0x9f, 0x77, 0xb7, 0x73, 0x40, 0xc5, 0xa2, 0x46, 0x3b, 0xb9, 0xb6, 0xab, 0x58, 0x93, 0x88, 0x9c,
+ /*42e0:*/ 0xe5, 0xae, 0x1b, 0x90, 0xf8, 0xdf, 0xdf, 0xd6, 0x4d, 0x2e, 0x3b, 0xeb, 0x3a, 0x6f, 0xe3, 0x28,
+ /*42f0:*/ 0x73, 0x32, 0x71, 0xb3, 0x7c, 0xd8, 0x7a, 0xa2, 0xfc, 0x61, 0x56, 0x2c, 0x89, 0x63, 0x16, 0xbd,
+ /*4300:*/ 0xea, 0xd2, 0x49, 0x1b, 0x43, 0xcf, 0x2a, 0xce, 0xd2, 0x00, 0xe8, 0xef, 0x60, 0xf9, 0x9e, 0x41,
+ /*4310:*/ 0x23, 0xde, 0x64, 0xa1, 0x05, 0x64, 0x55, 0xdb, 0xb0, 0xac, 0x37, 0xd1, 0x41, 0xd4, 0xfa, 0xde,
+ /*4320:*/ 0x9c, 0x18, 0x46, 0x59, 0xac, 0x51, 0xc4, 0xd4, 0xb9, 0x4c, 0x35, 0xfa, 0xcd, 0xfd, 0x23, 0xde,
+ /*4330:*/ 0xa8, 0x5d, 0x7c, 0xdb, 0xa1, 0x1a, 0x99, 0x9d, 0x21, 0x12, 0x81, 0xa8, 0xd1, 0x20, 0xc2, 0xd4,
+ /*4340:*/ 0x6c, 0xe9, 0x8b, 0x16, 0x22, 0x55, 0x5b, 0x0e, 0x1d, 0xde, 0x36, 0x54, 0x96, 0x76, 0x51, 0x36,
+ /*4350:*/ 0x13, 0x4a, 0x9f, 0x0f, 0x42, 0x11, 0xb2, 0x8a, 0x69, 0xec, 0x5b, 0xbd, 0xbd, 0xe6, 0x90, 0x1d,
+ /*4360:*/ 0x6f, 0x36, 0x18, 0x6d, 0x71, 0x18, 0x6b, 0xa0, 0x08, 0x0c, 0x6a, 0xbd, 0xc9, 0xc9, 0x03, 0xbb,
+ /*4370:*/ 0x2b, 0x13, 0xc4, 0x81, 0xd4, 0x98, 0xaa, 0x33, 0xa7, 0x7c, 0x9d, 0x2a, 0xcf, 0xf4, 0xc8, 0x33,
+ /*4380:*/ 0xc8, 0x54, 0x80, 0x2e, 0x85, 0x05, 0xf3, 0x67, 0x34, 0x07, 0xe1, 0x5c, 0x49, 0x4a, 0x72, 0x7e,
+ /*4390:*/ 0x1b, 0x64, 0xc1, 0x66, 0xe8, 0x3d, 0x30, 0x38, 0x8c, 0x58, 0x3c, 0x0f, 0x64, 0x54, 0x9b, 0x1b,
+ /*43a0:*/ 0x5e, 0xb7, 0x87, 0x95, 0xf7, 0x92, 0xbe, 0x4c, 0x42, 0x03, 0x77, 0x74, 0xea, 0x9e, 0xf3, 0x92,
+ /*43b0:*/ 0x94, 0x0d, 0x47, 0x33, 0x23, 0x88, 0x74, 0x71, 0x47, 0xab, 0x1d, 0xd5, 0x92, 0x81, 0x73, 0x66,
+ /*43c0:*/ 0x62, 0xc3, 0x27, 0xe5, 0xe0, 0x84, 0xfa, 0xe4, 0x6a, 0x2e, 0x07, 0xea, 0xdb, 0x44, 0x24, 0xef,
+ /*43d0:*/ 0x8a, 0xb0, 0x5e, 0xb0, 0x61, 0x03, 0x9c, 0xf8, 0xc7, 0xc8, 0x34, 0x1b, 0x87, 0xc7, 0xf1, 0x3b,
+ /*43e0:*/ 0xb5, 0x7e, 0xb7, 0x37, 0x4d, 0x3a, 0xb7, 0x4b, 0x2e, 0x21, 0xe2, 0x3e, 0x0d, 0xe7, 0x07, 0x3c,
+ /*43f0:*/ 0x43, 0xb2, 0x6d, 0x87, 0xa9, 0x79, 0x96, 0x86, 0x0c, 0x0e, 0xbc, 0x0d, 0x5e, 0x5b, 0x9f, 0xbf,
+ /*4400:*/ 0xc0, 0xfe, 0x4b, 0x81, 0xa2, 0x91, 0x39, 0xf9, 0x59, 0xfa, 0x96, 0x80, 0x2a, 0x90, 0x13, 0x4c,
+ /*4410:*/ 0x4e, 0x08, 0x1e, 0xcc, 0xfe, 0x1f, 0x94, 0x2b, 0x1b, 0x3f, 0x80, 0xa2, 0x03, 0xc2, 0xee, 0x37,
+ /*4420:*/ 0x52, 0xa2, 0xb7, 0xfb, 0x2c, 0x42, 0xe6, 0xd9, 0x57, 0xa4, 0xdd, 0x41, 0x02, 0xfc, 0x9f, 0x40,
+ /*4430:*/ 0x62, 0xb8, 0xc6, 0x4b, 0x42, 0xe4, 0xd8, 0x50, 0x47, 0xad, 0xea, 0x55, 0x21, 0xe7, 0xbb, 0xa4,
+ /*4440:*/ 0xf5, 0x07, 0x70, 0x6f, 0xba, 0x7e, 0x30, 0x31, 0x03, 0x15, 0x9d, 0x44, 0x29, 0x16, 0xe0, 0x95,
+ /*4450:*/ 0x67, 0xf0, 0x4b, 0x27, 0x94, 0xaf, 0x48, 0x2f, 0x3d, 0xe8, 0x8c, 0x64, 0x47, 0x32, 0xa0, 0xb7,
+ /*4460:*/ 0x23, 0x27, 0xbf, 0xca, 0xdf, 0x6a, 0xc1, 0x41, 0x19, 0x82, 0xd4, 0x97, 0xee, 0x24, 0xbc, 0x65,
+ /*4470:*/ 0xd3, 0x8b, 0x10, 0xf8, 0x1b, 0x70, 0xe1, 0x5c, 0xeb, 0xa2, 0xa9, 0x89, 0x62, 0xec, 0xaa, 0xf6,
+ /*4480:*/ 0xb1, 0xda, 0xf9, 0xe5, 0x0c, 0x47, 0xa0, 0x06, 0x93, 0x6c, 0x54, 0xea, 0x48, 0x9d, 0x57, 0x90,
+ /*4490:*/ 0x8f, 0x5f, 0xd0, 0x6f, 0x97, 0x2a, 0x64, 0x46, 0x05, 0x22, 0x5a, 0xda, 0xbd, 0xb0, 0x47, 0x73,
+ /*44a0:*/ 0x62, 0x2c, 0x75, 0xcb, 0xed, 0x7d, 0x0b, 0x14, 0x30, 0xb3, 0x78, 0x4c, 0xe7, 0x9c, 0xaf, 0x9b,
+ /*44b0:*/ 0x7a, 0x97, 0xde, 0x12, 0xac, 0x5e, 0x6a, 0x96, 0xd7, 0xfd, 0x8c, 0x3f, 0xe8, 0xed, 0x61, 0x1d,
+ /*44c0:*/ 0x5e, 0xcf, 0xfb, 0xb9, 0x49, 0x80, 0xde, 0x1b, 0xb8, 0x12, 0x81, 0x5a, 0xdb, 0xd6, 0xb7, 0x0f,
+ /*44d0:*/ 0x50, 0xf5, 0x7e, 0xf8, 0xa6, 0xcc, 0xfa, 0x86, 0x25, 0xdb, 0xd1, 0xd1, 0xfb, 0x99, 0xbe, 0x28,
+ /*44e0:*/ 0x60, 0xc9, 0x83, 0xe6, 0x64, 0x56, 0xf6, 0x15, 0x8d, 0xf0, 0xad, 0xd2, 0x3f, 0x6f, 0x18, 0xe8,
+ /*44f0:*/ 0xee, 0x3c, 0x25, 0x52, 0x3f, 0x32, 0x29, 0x99, 0x36, 0xc2, 0x18, 0xb0, 0xea, 0xc5, 0x87, 0x60,
+ /*4500:*/ 0xda, 0xe4, 0x78, 0x89, 0xee, 0xaa, 0x9d, 0x4e, 0xfa, 0xca, 0xe1, 0xbe, 0xda, 0x46, 0x22, 0x28,
+ /*4510:*/ 0x13, 0x0e, 0xf1, 0x8e, 0x15, 0x6d, 0x68, 0x07, 0xc5, 0x0a, 0x41, 0x4f, 0x2d, 0xd6, 0x0c, 0x89,
+ /*4520:*/ 0x13, 0x5b, 0x79, 0x46, 0x0e, 0x14, 0x4d, 0x8a, 0xb1, 0xe0, 0x6e, 0xcc, 0x46, 0xa2, 0x35, 0xa6,
+ /*4530:*/ 0xf0, 0x61, 0x80, 0xe8, 0xd0, 0x24, 0xab, 0x1d, 0xa4, 0x28, 0x93, 0xb8, 0x87, 0xa5, 0xd0, 0xe4,
+ /*4540:*/ 0x9c, 0xfd, 0x29, 0x75, 0x8e, 0x85, 0x20, 0x25, 0xcb, 0xbb, 0x21, 0x20, 0xf9, 0x31, 0x07, 0xaf,
+ /*4550:*/ 0x5d, 0xf7, 0xc1, 0x7f, 0x89, 0xad, 0xab, 0xbf, 0x65, 0xf8, 0x71, 0xb0, 0x7f, 0xd2, 0xad, 0xd1,
+ /*4560:*/ 0x51, 0x48, 0x9f, 0xf0, 0xaa, 0xc0, 0xde, 0x60, 0x40, 0xe4, 0x2b, 0xb5, 0x0e, 0x24, 0xdd, 0xfa,
+ /*4570:*/ 0x0f, 0x52, 0xc3, 0x6e, 0xcc, 0xa2, 0xb9, 0x32, 0x30, 0x92, 0x24, 0x51, 0xb9, 0xff, 0x7d, 0xef,
+ /*4580:*/ 0x5b, 0x6c, 0xf2, 0xde, 0x08, 0x11, 0x94, 0x52, 0xac, 0x53, 0xd3, 0xc5, 0x97, 0xd6, 0xd2, 0x78,
+ /*4590:*/ 0x1c, 0x70, 0xea, 0xd8, 0x81, 0x7f, 0xd6, 0x3b, 0x27, 0x6f, 0x94, 0x59, 0x98, 0xcf, 0x5d, 0x06,
+ /*45a0:*/ 0x9b, 0x97, 0x47, 0xf9, 0x4f, 0x50, 0xb9, 0x56, 0x36, 0xb5, 0xb6, 0xb9, 0xe3, 0xe2, 0xce, 0x63,
+ /*45b0:*/ 0x0c, 0x3f, 0xc5, 0xe1, 0xde, 0x8f, 0xcb, 0x8b, 0x36, 0x8d, 0x8d, 0xb9, 0xa6, 0xfb, 0x1b, 0xe4,
+ /*45c0:*/ 0xe9, 0xea, 0xd0, 0xf0, 0x75, 0x2e, 0x75, 0x58, 0xfc, 0x48, 0x49, 0xad, 0x97, 0x3e, 0xc8, 0xdd,
+ /*45d0:*/ 0x12, 0x78, 0x79, 0xd1, 0xdc, 0xd7, 0x49, 0x05, 0x65, 0x64, 0x26, 0x9e, 0x00, 0xf5, 0x2b, 0xc2,
+ /*45e0:*/ 0x03, 0x74, 0xb3, 0x23, 0x74, 0xd5, 0xb4, 0x4b, 0xb4, 0x6e, 0x0e, 0x1e, 0xb3, 0xae, 0x14, 0xe2,
+ /*45f0:*/ 0xe8, 0xfb, 0xc2, 0xf6, 0xd5, 0x99, 0xd2, 0x90, 0x27, 0x13, 0xf9, 0x20, 0x7b, 0xd0, 0x76, 0x95,
+ /*4600:*/ 0x67, 0x45, 0x7a, 0x9b, 0x3c, 0x41, 0xc0, 0x6e, 0x6c, 0x2f, 0x0a, 0xe9, 0xcc, 0xa5, 0x8b, 0x41,
+ /*4610:*/ 0x8c, 0x27, 0xd6, 0xce, 0xde, 0x8f, 0x02, 0xd3, 0xad, 0xd5, 0x88, 0x19, 0xbb, 0xeb, 0xb8, 0x3c,
+ /*4620:*/ 0x45, 0xea, 0xff, 0xe8, 0x10, 0x93, 0xaf, 0xab, 0x24, 0xff, 0x10, 0x8e, 0x60, 0x92, 0x88, 0x0c,
+ /*4630:*/ 0x42, 0x17, 0xf4, 0x42, 0xbc, 0x7e, 0xfe, 0xbf, 0x14, 0x09, 0x6f, 0xff, 0xa2, 0x42, 0x43, 0x97,
+ /*4640:*/ 0x5f, 0x24, 0xae, 0xa1, 0xcf, 0x48, 0xe6, 0x35, 0x3f, 0x12, 0x55, 0x38, 0x0a, 0x91, 0x05, 0x46,
+ /*4650:*/ 0x9d, 0x80, 0xb3, 0x75, 0x24, 0x64, 0x19, 0x8e, 0xea, 0x65, 0x94, 0x22, 0xfe, 0x6c, 0xa4, 0x82,
+ /*4660:*/ 0x16, 0x96, 0x7f, 0x57, 0x4b, 0x72, 0x54, 0x9e, 0x84, 0x22, 0x06, 0x64, 0x24, 0xe1, 0x50, 0xc7,
+ /*4670:*/ 0x78, 0xb8, 0xa4, 0xb4, 0xfe, 0x60, 0xa1, 0x0c, 0xf6, 0xba, 0xdd, 0x93, 0x0f, 0xf5, 0x36, 0xe2,
+ /*4680:*/ 0xb6, 0x9c, 0xd3, 0xc8, 0x96, 0xb4, 0xd2, 0x02, 0x38, 0x42, 0x9a, 0x2f, 0x1b, 0x46, 0xd2, 0x20,
+ /*4690:*/ 0xc6, 0x90, 0xd5, 0xd4, 0x42, 0xf0, 0xd5, 0x14, 0xd1, 0xb1, 0xec, 0x02, 0x41, 0x25, 0xbb, 0x35,
+ /*46a0:*/ 0x0b, 0x9a, 0x66, 0x1d, 0xc8, 0xf9, 0xc1, 0x6a, 0x59, 0xfc, 0xc5, 0x57, 0xda, 0xdf, 0xe2, 0x8a,
+ /*46b0:*/ 0x8b, 0x1b, 0x21, 0x1d, 0x45, 0x76, 0x57, 0x8a, 0x0c, 0xd8, 0x21, 0xa0, 0x34, 0x42, 0xeb, 0xa7,
+ /*46c0:*/ 0x01, 0x62, 0x5f, 0x5d, 0xf5, 0x12, 0x44, 0x42, 0x4a, 0xb1, 0x2c, 0x9a, 0x44, 0x79, 0x9e, 0x6b,
+ /*46d0:*/ 0xde, 0xbf, 0x13, 0x8c, 0x22, 0x4f, 0xe7, 0x50, 0xd4, 0x0a, 0x18, 0x4f, 0x50, 0xf0, 0xbb, 0x16,
+ /*46e0:*/ 0xf5, 0x57, 0x2c, 0xd8, 0x66, 0x3f, 0x83, 0x62, 0xe8, 0x5a, 0xd4, 0x05, 0x67, 0xe0, 0xa7, 0x40,
+ /*46f0:*/ 0x08, 0xc3, 0x9e, 0x5b, 0xbb, 0x3a, 0xd3, 0x44, 0x15, 0xa6, 0xb3, 0x12, 0xea, 0x89, 0xd9, 0xbc,
+ /*4700:*/ 0xc1, 0xc8, 0x01, 0x39, 0x1c, 0xc7, 0xc0, 0xfa, 0xea, 0x85, 0xf9, 0x27, 0xe9, 0x10, 0x93, 0x49,
+ /*4710:*/ 0x5e, 0xa2, 0xb2, 0x40, 0xf3, 0x6f, 0xd1, 0xfb, 0x67, 0xfa, 0x1e, 0x44, 0xc5, 0x7d, 0x49, 0xbe,
+ /*4720:*/ 0xeb, 0xff, 0x2b, 0x0d, 0xcd, 0x82, 0xd5, 0x42, 0xd1, 0xf2, 0x26, 0x78, 0x8e, 0xec, 0x67, 0x01,
+ /*4730:*/ 0xb0, 0x5f, 0x0b, 0x28, 0x59, 0x49, 0x8d, 0x2d, 0x77, 0x30, 0x77, 0xfb, 0xf0, 0x1b, 0x1a, 0x83,
+ /*4740:*/ 0x93, 0x22, 0x0c, 0x92, 0xa5, 0x74, 0xbb, 0xe2, 0xa6, 0xe5, 0x9e, 0x86, 0x6c, 0x34, 0xee, 0x28,
+ /*4750:*/ 0xec, 0x81, 0xdc, 0x1f, 0x78, 0x54, 0x2c, 0x5a, 0xe6, 0xdf, 0x37, 0x61, 0xd1, 0x9b, 0x75, 0x87,
+ /*4760:*/ 0xc8, 0xe7, 0x9e, 0x1a, 0x26, 0x82, 0x16, 0xaa, 0x4e, 0x0a, 0xfc, 0xc1, 0xa6, 0xf3, 0xb6, 0xaf,
+ /*4770:*/ 0x1f, 0xff, 0xc2, 0xb4, 0xb7, 0x33, 0x13, 0xb3, 0xc4, 0xc7, 0x7d, 0xb1, 0xd3, 0x69, 0x5c, 0x8e,
+ /*4780:*/ 0xe7, 0x49, 0x52, 0x47, 0x16, 0x28, 0x14, 0x4a, 0x54, 0xb5, 0xe3, 0xa8, 0x62, 0x2d, 0x22, 0xb1,
+ /*4790:*/ 0x78, 0xe2, 0x15, 0x63, 0x6f, 0x0f, 0x7e, 0x5c, 0x3b, 0xc3, 0x12, 0xfd, 0x67, 0x62, 0x24, 0x12,
+ /*47a0:*/ 0x96, 0x75, 0x30, 0x87, 0x77, 0x81, 0x49, 0xa8, 0x95, 0x3b, 0x94, 0xb8, 0x32, 0x24, 0x65, 0xe5,
+ /*47b0:*/ 0xd7, 0x05, 0x07, 0xf4, 0xa2, 0xc7, 0x67, 0x1d, 0x0a, 0xc4, 0xee, 0x25, 0xf9, 0x6a, 0xc2, 0xf3,
+ /*47c0:*/ 0x06, 0xd9, 0xcc, 0x48, 0x0f, 0x85, 0xb0, 0x93, 0xdb, 0x27, 0x46, 0xfe, 0xc7, 0x8d, 0xcb, 0x02,
+ /*47d0:*/ 0xd5, 0xad, 0x0c, 0x18, 0xc1, 0x19, 0xab, 0xd5, 0xd9, 0xbf, 0x7a, 0xfe, 0xc1, 0x27, 0x80, 0xca,
+ /*47e0:*/ 0xca, 0x14, 0x1f, 0x4f, 0x64, 0xfb, 0xe5, 0x03, 0x28, 0x16, 0xa2, 0xc9, 0x09, 0x93, 0xdd, 0x40,
+ /*47f0:*/ 0xc3, 0x2f, 0x46, 0xd5, 0xcf, 0x29, 0xe0, 0x9c, 0xab, 0x0a, 0x5b, 0xab, 0xbd, 0x0e, 0x28, 0x16,
+ /*4800:*/ 0xc6, 0x5d, 0x3f, 0x5e, 0x41, 0x5a, 0x35, 0xd0, 0x3b, 0x9f, 0x49, 0x25, 0x00, 0x4b, 0x81, 0xda,
+ /*4810:*/ 0x04, 0xd4, 0x03, 0xe3, 0xd8, 0xb3, 0x51, 0xba, 0x4c, 0xe2, 0x1c, 0xb8, 0x9a, 0xaa, 0x0d, 0x00,
+ /*4820:*/ 0x21, 0x93, 0x0a, 0xcb, 0xa4, 0x1e, 0xf9, 0x50, 0x9f, 0xf0, 0xa3, 0x01, 0x84, 0xf1, 0xcf, 0x7f,
+ /*4830:*/ 0x93, 0x19, 0xbd, 0x53, 0x0c, 0xd1, 0x89, 0xe6, 0x2f, 0x10, 0x80, 0x91, 0x33, 0xb7, 0x99, 0xaa,
+ /*4840:*/ 0xe1, 0x26, 0xf7, 0xde, 0x76, 0x09, 0xf6, 0x45, 0x89, 0x33, 0xd0, 0xf0, 0xf8, 0xf6, 0xd4, 0x59,
+ /*4850:*/ 0x94, 0xf9, 0x06, 0xe5, 0x7c, 0xb4, 0x61, 0xac, 0x2f, 0x9a, 0x8e, 0x2d, 0x28, 0x37, 0x11, 0x3a,
+ /*4860:*/ 0x1d, 0xf7, 0x06, 0x79, 0x52, 0x8b, 0xa9, 0xd9, 0xa8, 0x89, 0xfc, 0xb4, 0xbf, 0xbe, 0x56, 0xfd,
+ /*4870:*/ 0x8a, 0x62, 0x89, 0x21, 0x6a, 0x58, 0x03, 0x22, 0x43, 0x56, 0x33, 0xca, 0x3e, 0x2a, 0x87, 0x66,
+ /*4880:*/ 0x16, 0xda, 0xb5, 0x96, 0x51, 0x86, 0xb9, 0x7e, 0x6d, 0xb5, 0xb5, 0xb2, 0x57, 0x5b, 0x75, 0xd5,
+ /*4890:*/ 0xd5, 0xc2, 0x72, 0x7b, 0x9e, 0xa5, 0xab, 0x45, 0x71, 0x77, 0x87, 0xc8, 0xb7, 0x0d, 0xbd, 0xea,
+ /*48a0:*/ 0x29, 0xd1, 0xc3, 0x15, 0x55, 0xa5, 0x16, 0x4c, 0x38, 0xa8, 0x86, 0x66, 0xd5, 0x7a, 0xf4, 0x47,
+ /*48b0:*/ 0x63, 0xb5, 0x01, 0x99, 0xec, 0xbb, 0x7e, 0x72, 0x4d, 0x6c, 0x49, 0x55, 0xde, 0xc1, 0xfa, 0xd9,
+ /*48c0:*/ 0x34, 0x60, 0x48, 0x48, 0x14, 0x9d, 0xb9, 0x9e, 0x5f, 0x2b, 0x7b, 0xbd, 0x68, 0x6a, 0xb2, 0x6d,
+ /*48d0:*/ 0xc6, 0x0b, 0x89, 0xbb, 0x84, 0xdd, 0x33, 0x5c, 0xc1, 0x36, 0x5e, 0xeb, 0x71, 0x39, 0x32, 0xd3,
+ /*48e0:*/ 0xdf, 0xdd, 0xd4, 0x46, 0x8d, 0x63, 0xaa, 0xea, 0x47, 0xc4, 0x15, 0x01, 0xe3, 0x37, 0xfc, 0x91,
+ /*48f0:*/ 0x92, 0xca, 0x90, 0xb5, 0xa0, 0x8d, 0xd7, 0xdb, 0x7a, 0xe2, 0x9d, 0x82, 0x7f, 0xb7, 0x40, 0x72,
+ /*4900:*/ 0xfb, 0x5e, 0xc9, 0x5a, 0xf9, 0xcf, 0xa8, 0x9f, 0x42, 0xa6, 0x66, 0xa6, 0x91, 0x41, 0x6c, 0xf8,
+ /*4910:*/ 0x59, 0xbf, 0x9e, 0xbb, 0x62, 0xab, 0x05, 0x1f, 0x19, 0x6e, 0x5f, 0x23, 0x48, 0x85, 0xa7, 0xaf,
+ /*4920:*/ 0xeb, 0x26, 0x7f, 0xb3, 0x42, 0xfe, 0x37, 0xd6, 0xa0, 0x9f, 0x47, 0xb3, 0x3a, 0x05, 0x6c, 0x78,
+ /*4930:*/ 0x08, 0x5d, 0xaa, 0x19, 0x37, 0xff, 0x69, 0x0d, 0x96, 0x2a, 0xd2, 0x8a, 0x0d, 0x7f, 0xbf, 0x5b,
+ /*4940:*/ 0x26, 0x40, 0x3e, 0x47, 0x30, 0xb5, 0xc1, 0x48, 0xa5, 0x4e, 0x76, 0xae, 0x8d, 0xba, 0x5b, 0x0b,
+ /*4950:*/ 0x22, 0xef, 0xdf, 0xa5, 0x33, 0xc6, 0xe9, 0x79, 0x5d, 0x1e, 0x6a, 0xec, 0xa2, 0xa6, 0xfa, 0x5f,
+ /*4960:*/ 0xac, 0x42, 0x67, 0x60, 0x06, 0x65, 0x6b, 0xf2, 0x3d, 0xbf, 0x92, 0x54, 0xfb, 0xe8, 0x7e, 0x1a,
+ /*4970:*/ 0xb5, 0x9b, 0x57, 0x86, 0x21, 0xc4, 0x80, 0x50, 0x54, 0xe7, 0xfc, 0x10, 0x9c, 0xb5, 0xde, 0x50,
+ /*4980:*/ 0x13, 0x92, 0x3a, 0x85, 0x09, 0xd3, 0x02, 0xa2, 0xf0, 0x38, 0xf0, 0x6d, 0x98, 0x9a, 0x59, 0x92,
+ /*4990:*/ 0xad, 0x89, 0x0d, 0xfd, 0xdf, 0x84, 0xbb, 0x77, 0x2d, 0x4c, 0xbb, 0x8c, 0xa5, 0xe2, 0xea, 0x45,
+ /*49a0:*/ 0xfd, 0x40, 0x07, 0xbc, 0xa0, 0xf0, 0x84, 0x48, 0x17, 0xd2, 0x58, 0x94, 0xbf, 0x89, 0x04, 0x7e,
+ /*49b0:*/ 0x6e, 0xc9, 0x7a, 0xcc, 0x4a, 0x65, 0xf7, 0xb4, 0xf4, 0x2f, 0xae, 0x6e, 0xae, 0x7f, 0x1c, 0xa7,
+ /*49c0:*/ 0xda, 0xce, 0x73, 0xda, 0x7c, 0x9c, 0xed, 0x7c, 0x5c, 0xc6, 0x56, 0x8b, 0xc7, 0xc1, 0x53, 0xb4,
+ /*49d0:*/ 0x5a, 0x30, 0x70, 0x09, 0xd7, 0xdd, 0x20, 0xd0, 0x2a, 0x47, 0x82, 0xb2, 0xa1, 0xd5, 0x69, 0x0a,
+ /*49e0:*/ 0xc1, 0xf8, 0xe9, 0x69, 0x60, 0x17, 0x3f, 0x4c, 0x79, 0x92, 0x33, 0x16, 0x92, 0xbf, 0x4a, 0x73,
+ /*49f0:*/ 0x7f, 0x0a, 0xd1, 0x96, 0x83, 0x53, 0x1c, 0x01, 0x01, 0x5d, 0xe4, 0xf1, 0xe3, 0xa1, 0xc4, 0x91,
+ /*4a00:*/ 0x71, 0x14, 0xbf, 0x60, 0x5a, 0xf5, 0x95, 0x0a, 0x45, 0x35, 0x39, 0x81, 0xea, 0xd4, 0x66, 0x69,
+ /*4a10:*/ 0xa6, 0x12, 0x6d, 0xa8, 0xb8, 0x32, 0x92, 0x1b, 0xa4, 0x59, 0x46, 0x6c, 0x8c, 0xed, 0xc0, 0x4c,
+ /*4a20:*/ 0x55, 0x99, 0xb3, 0xc1, 0x51, 0xfa, 0x30, 0xf0, 0x54, 0x2f, 0x6e, 0x7d, 0xbc, 0xb3, 0x9a, 0x9d,
+ /*4a30:*/ 0x27, 0x42, 0x30, 0xbf, 0x0e, 0x41, 0x87, 0x65, 0x70, 0x10, 0xbc, 0xf1, 0x4b, 0x3e, 0x64, 0x48,
+ /*4a40:*/ 0x88, 0xfb, 0xfa, 0x1b, 0x9a, 0xcb, 0xf5, 0xf7, 0x5c, 0xf8, 0xcc, 0xb2, 0xad, 0xc7, 0x96, 0x16,
+ /*4a50:*/ 0x36, 0xe4, 0x8c, 0x23, 0x21, 0x38, 0x60, 0x6c, 0x6d, 0xaa, 0xef, 0xc9, 0x26, 0xde, 0x1f, 0x17,
+ /*4a60:*/ 0xad, 0x4a, 0xa6, 0xbb, 0xcb, 0xce, 0x76, 0x40, 0x5e, 0x86, 0xdb, 0x97, 0x1f, 0x70, 0x86, 0xf7,
+ /*4a70:*/ 0x8f, 0xf8, 0x11, 0x39, 0x03, 0xc7, 0x0c, 0xcc, 0x71, 0x29, 0x00, 0x2a, 0x4e, 0x62, 0x49, 0xad,
+ /*4a80:*/ 0xb0, 0xfa, 0xfb, 0x80, 0x2e, 0xe8, 0x70, 0x73, 0x57, 0x42, 0xd3, 0xc0, 0x68, 0x7e, 0xaa, 0x0a,
+ /*4a90:*/ 0xdb, 0x99, 0x89, 0x07, 0x8a, 0x6d, 0x4c, 0x9c, 0xbc, 0x33, 0x4f, 0xee, 0x7f, 0x27, 0x45, 0x0f,
+ /*4aa0:*/ 0x7f, 0x16, 0xcb, 0x5b, 0xd7, 0x88, 0x9a, 0xbf, 0x4b, 0x98, 0x01, 0x1c, 0xaf, 0x06, 0x7f, 0x1e,
+ /*4ab0:*/ 0x4d, 0x07, 0x70, 0xb8, 0x7f, 0xac, 0xbb, 0x79, 0xc3, 0x10, 0x01, 0xbc, 0x43, 0x97, 0x46, 0x38,
+ /*4ac0:*/ 0x6e, 0x96, 0x82, 0x31, 0xe6, 0x2e, 0xa0, 0x56, 0xd6, 0xfa, 0xce, 0x3c, 0x43, 0xcd, 0xfe, 0x63,
+ /*4ad0:*/ 0x3d, 0xd8, 0x48, 0x28, 0x8d, 0x80, 0xb8, 0xe3, 0xfd, 0x3b, 0x74, 0x90, 0xbd, 0x64, 0x2d, 0x3f,
+ /*4ae0:*/ 0x18, 0x94, 0x39, 0x9c, 0x52, 0x8a, 0x6b, 0x88, 0x7b, 0xd2, 0xa7, 0x89, 0x16, 0x7b, 0x89, 0x45,
+ /*4af0:*/ 0xdd, 0x0e, 0xf1, 0xc7, 0xc4, 0x9b, 0xb8, 0x90, 0xb8, 0x97, 0x93, 0x4f, 0x98, 0x49, 0xef, 0xef,
+ /*4b00:*/ 0x0a, 0x78, 0xc9, 0xaf, 0xc3, 0xe2, 0xb6, 0x9c, 0x22, 0x69, 0x8b, 0x86, 0xff, 0x76, 0x04, 0x60,
+ /*4b10:*/ 0xab, 0x35, 0x92, 0x1c, 0xa8, 0xac, 0xdd, 0x99, 0x09, 0xdf, 0x97, 0xfe, 0x25, 0x86, 0x0a, 0x43,
+ /*4b20:*/ 0xdd, 0x5c, 0xee, 0x40, 0xdf, 0x68, 0x7b, 0x87, 0x70, 0xd0, 0x45, 0xa9, 0x9c, 0xd8, 0x19, 0xca,
+ /*4b30:*/ 0xfd, 0x08, 0x4a, 0xfc, 0x26, 0xfb, 0xb0, 0x3d, 0xab, 0xf9, 0x04, 0x77, 0x26, 0xc9, 0x18, 0x45,
+ /*4b40:*/ 0xdf, 0xf5, 0xed, 0x8a, 0xb6, 0x9a, 0x08, 0x2d, 0xa9, 0xb3, 0xd1, 0xea, 0x82, 0xfd, 0x5c, 0xbf,
+ /*4b50:*/ 0x32, 0x90, 0xc7, 0x2d, 0x01, 0xf9, 0x56, 0xb0, 0x6b, 0xfe, 0x7a, 0xe2, 0x03, 0x90, 0x48, 0x60,
+ /*4b60:*/ 0xdc, 0x0b, 0xc9, 0x2f, 0x95, 0xe6, 0x0b, 0x73, 0xb5, 0xeb, 0x3d, 0xfe, 0xbe, 0x7e, 0x89, 0x24,
+ /*4b70:*/ 0x15, 0x68, 0x08, 0x86, 0x38, 0xad, 0x27, 0x55, 0x9a, 0x56, 0x58, 0x06, 0x0a, 0x4b, 0x78, 0xde,
+ /*4b80:*/ 0x94, 0xb0, 0xa5, 0x95, 0x10, 0x85, 0x63, 0x8e, 0xcb, 0xd2, 0x26, 0x35, 0x14, 0xa3, 0x1d, 0xd8,
+ /*4b90:*/ 0x62, 0xc0, 0x42, 0x4c, 0xa4, 0xad, 0x9e, 0x59, 0x50, 0xf8, 0xcf, 0x55, 0xb8, 0x01, 0xfe, 0x68,
+ /*4ba0:*/ 0x92, 0x08, 0x8b, 0x8d, 0xd8, 0xab, 0x1d, 0xed, 0xec, 0x01, 0xbc, 0xf5, 0xe3, 0x7c, 0x5c, 0x13,
+ /*4bb0:*/ 0xef, 0x7d, 0x14, 0x21, 0xd1, 0x8e, 0x9b, 0xe4, 0x34, 0x78, 0x59, 0x45, 0x9c, 0x86, 0x37, 0xc2,
+ /*4bc0:*/ 0x24, 0xd1, 0xeb, 0x14, 0x83, 0x0a, 0x80, 0xde, 0x45, 0xa1, 0x17, 0x41, 0xd1, 0x36, 0x1e, 0x95,
+ /*4bd0:*/ 0x4d, 0x00, 0x13, 0x2d, 0x15, 0x7d, 0x4b, 0x52, 0x90, 0x32, 0x12, 0xc2, 0x7d, 0x72, 0xaa, 0x2a,
+ /*4be0:*/ 0x16, 0x54, 0x08, 0xb7, 0x2b, 0x86, 0xa5, 0xa6, 0x62, 0x2c, 0x8a, 0x0d, 0xd8, 0x50, 0x89, 0xf9,
+ /*4bf0:*/ 0xb2, 0x52, 0xd2, 0xd9, 0xa2, 0xa3, 0x21, 0x14, 0x87, 0x89, 0xe1, 0xe7, 0xce, 0xf0, 0x5f, 0xd8,
+ /*4c00:*/ 0x75, 0x61, 0xd6, 0x66, 0xcf, 0xda, 0x00, 0x21, 0xa6, 0xf0, 0xb4, 0x41, 0xcf, 0xf4, 0x71, 0x51,
+ /*4c10:*/ 0xba, 0x27, 0x32, 0x7c, 0x3c, 0xb6, 0xc8, 0x29, 0x53, 0x1f, 0xc5, 0xc1, 0xfd, 0x9f, 0xa8, 0x08,
+ /*4c20:*/ 0x30, 0x51, 0x7f, 0xf6, 0x8b, 0x6a, 0xa2, 0xbe, 0xd4, 0xf5, 0x15, 0xaf, 0x49, 0x19, 0xb9, 0x8e,
+ /*4c30:*/ 0x19, 0xfc, 0x70, 0x0c, 0x28, 0xdc, 0xee, 0x85, 0xb7, 0x5b, 0xde, 0x02, 0xdd, 0x85, 0x8c, 0x9b,
+ /*4c40:*/ 0x78, 0x13, 0x35, 0x1b, 0xd2, 0xe8, 0xcf, 0x9a, 0xc1, 0x3d, 0x21, 0xa2, 0xc5, 0x34, 0xdd, 0x9e,
+ /*4c50:*/ 0x6f, 0xeb, 0xc4, 0x82, 0x18, 0xd8, 0x5a, 0x31, 0x4a, 0x75, 0x45, 0xc9, 0x6f, 0x56, 0x63, 0x1f,
+ /*4c60:*/ 0xc9, 0x4d, 0x35, 0x74, 0x58, 0x31, 0xf1, 0x3e, 0xd7, 0xc5, 0x95, 0xf7, 0x29, 0x4f, 0x24, 0xf7,
+ /*4c70:*/ 0xd9, 0xba, 0xb6, 0x43, 0x34, 0x69, 0x34, 0x04, 0xf0, 0xac, 0x4c, 0x08, 0xed, 0xf9, 0xf4, 0xe3,
+ /*4c80:*/ 0xdc, 0xc5, 0x3e, 0x4f, 0x65, 0xde, 0xba, 0xb3, 0xaf, 0x6f, 0x1a, 0x1f, 0x21, 0x00, 0x80, 0xc2,
+ /*4c90:*/ 0x7c, 0x54, 0x55, 0x35, 0x05, 0x23, 0x65, 0x8c, 0x1a, 0x19, 0x2e, 0xd8, 0x4f, 0xfb, 0xb9, 0xfa,
+ /*4ca0:*/ 0x73, 0x5f, 0x33, 0x0e, 0xfb, 0x32, 0xf5, 0x84, 0x5e, 0xd1, 0x5d, 0x0c, 0x6d, 0x6b, 0x06, 0xc6,
+ /*4cb0:*/ 0x09, 0x5b, 0x14, 0x40, 0x84, 0x68, 0xca, 0x4e, 0xf3, 0xd0, 0xe0, 0x98, 0x86, 0xbe, 0xb8, 0x60,
+ /*4cc0:*/ 0x8c, 0xf6, 0xf3, 0x0e, 0xec, 0x70, 0xea, 0x53, 0x19, 0x2c, 0xfb, 0x69, 0x00, 0x37, 0x06, 0x36,
+ /*4cd0:*/ 0x3b, 0xee, 0xf1, 0x9e, 0xcb, 0xdb, 0x03, 0x00, 0x25, 0x35, 0xa1, 0x7b, 0xb2, 0x79, 0xce, 0x53,
+ /*4ce0:*/ 0xfe, 0xcb, 0x3c, 0x99, 0xde, 0x50, 0x5a, 0x26, 0xa0, 0xe4, 0x28, 0x96, 0xf6, 0x8d, 0x30, 0x97,
+ /*4cf0:*/ 0xcd, 0x6e, 0xbb, 0xb0, 0x70, 0x29, 0x60, 0xe8, 0x48, 0x1b, 0xe9, 0xfb, 0xa4, 0x29, 0xea, 0x52,
+ /*4d00:*/ 0x8f, 0x76, 0x77, 0x1a, 0xdb, 0xcd, 0x39, 0x7a, 0xcf, 0x9d, 0x66, 0xf3, 0x06, 0x9a, 0xb9, 0x80,
+ /*4d10:*/ 0xb7, 0xe7, 0xab, 0xbd, 0xe3, 0xbe, 0x33, 0xb2, 0x3a, 0x4b, 0x43, 0xc5, 0xa8, 0x91, 0x1c, 0xba,
+ /*4d20:*/ 0x89, 0xd4, 0x2b, 0xba, 0xfb, 0x91, 0xe0, 0x27, 0xf5, 0x57, 0xd8, 0x2d, 0x7b, 0xad, 0x3d, 0x0d,
+ /*4d30:*/ 0x2c, 0x21, 0xf8, 0x3a, 0x6a, 0x86, 0xbf, 0x66, 0x35, 0xb2, 0x3a, 0x55, 0xb7, 0x41, 0xf2, 0x8c,
+ /*4d40:*/ 0x82, 0x2f, 0xf9, 0x36, 0x5e, 0x63, 0xfe, 0x15, 0x23, 0x61, 0xa4, 0xee, 0x53, 0x45, 0xd3, 0xdc,
+ /*4d50:*/ 0xc5, 0x1b, 0xce, 0xb7, 0x3c, 0x23, 0x6d, 0x40, 0xa1, 0x28, 0x05, 0x0f, 0xd0, 0xb8, 0x9b, 0x48,
+ /*4d60:*/ 0xb3, 0xe1, 0x91, 0xe1, 0x0e, 0xe5, 0xd3, 0x7e, 0xaa, 0x7a, 0xad, 0xa1, 0xcb, 0xa9, 0x06, 0x4a,
+ /*4d70:*/ 0x22, 0x57, 0xa1, 0x7b, 0xd9, 0xf5, 0x09, 0x48, 0x09, 0x34, 0x88, 0xcf, 0xfd, 0xf8, 0xdd, 0x3d,
+ /*4d80:*/ 0xc2, 0x7c, 0x5b, 0x36, 0xb0, 0x53, 0x2f, 0x5f, 0x41, 0x3e, 0x15, 0x71, 0xb0, 0x06, 0x18, 0x68,
+ /*4d90:*/ 0x64, 0xc8, 0xdb, 0xab, 0x4a, 0x1f, 0xc0, 0x24, 0xd1, 0x4c, 0x59, 0xe8, 0x9e, 0xce, 0x10, 0x16,
+ /*4da0:*/ 0x68, 0x1f, 0x70, 0x1f, 0x31, 0xde, 0xa3, 0xe2, 0x20, 0xbb, 0xfc, 0x93, 0xa6, 0x43, 0x23, 0xea,
+ /*4db0:*/ 0x3a, 0x45, 0xe5, 0x93, 0x80, 0x92, 0x43, 0x5b, 0x05, 0x3d, 0x65, 0xe2, 0xbf, 0x56, 0x3f, 0x26,
+ /*4dc0:*/ 0x82, 0x0b, 0x1e, 0xd4, 0x46, 0x3a, 0x7a, 0x5a, 0x44, 0x91, 0x7e, 0x38, 0x3b, 0x6a, 0x17, 0xaf,
+ /*4dd0:*/ 0xc5, 0x5a, 0xb2, 0x68, 0xce, 0x68, 0x9c, 0x3c, 0x71, 0xc9, 0xde, 0xaa, 0x9b, 0xee, 0xd3, 0x50,
+ /*4de0:*/ 0x3c, 0xfd, 0xd8, 0x82, 0xc2, 0x6b, 0x92, 0x1a, 0xf9, 0x0c, 0x65, 0x20, 0x96, 0xc2, 0xd4, 0x2c,
+ /*4df0:*/ 0x0e, 0x89, 0x9d, 0xc7, 0xe0, 0xb9, 0x9b, 0x12, 0xad, 0xea, 0x0d, 0x97, 0x24, 0x99, 0xbe, 0x81,
+ /*4e00:*/ 0x08, 0x1f, 0x19, 0x70, 0x7f, 0x12, 0x9b, 0x46, 0x6b, 0xe3, 0xaf, 0x0b, 0xbb, 0xdd, 0xf9, 0xee,
+ /*4e10:*/ 0xfc, 0x40, 0x5b, 0x60, 0xb7, 0x9e, 0x00, 0xfe, 0x83, 0xca, 0x02, 0x31, 0xdb, 0x0a, 0x1a, 0xbe,
+ /*4e20:*/ 0xf1, 0x5f, 0xf9, 0x4f, 0xce, 0x03, 0x8c, 0xed, 0x31, 0x22, 0xaa, 0xcd, 0xa5, 0x34, 0xf5, 0xb2,
+ /*4e30:*/ 0x68, 0xad, 0x3e, 0xb4, 0x80, 0xa9, 0x11, 0x32, 0x56, 0x4d, 0xd6, 0x34, 0xe0, 0x3c, 0xf3, 0x49,
+ /*4e40:*/ 0x67, 0x5c, 0x8a, 0xf2, 0x08, 0xbf, 0x48, 0xac, 0xc1, 0x85, 0xa7, 0xfe, 0xcd, 0x8f, 0x46, 0x3c,
+ /*4e50:*/ 0xd5, 0x49, 0xfe, 0xf3, 0x9c, 0x61, 0x20, 0xd6, 0x16, 0x53, 0xfe, 0x67, 0x1d, 0x74, 0x44, 0x43,
+ /*4e60:*/ 0xab, 0x01, 0x7a, 0x1f, 0xdf, 0x83, 0x51, 0xbb, 0x25, 0xfc, 0xd7, 0x22, 0x94, 0x22, 0x03, 0x6c,
+ /*4e70:*/ 0x66, 0xa3, 0xa4, 0x0e, 0x19, 0x39, 0xd4, 0x9b, 0xfb, 0x4e, 0x37, 0x9d, 0x0d, 0xef, 0x7f, 0x7c,
+ /*4e80:*/ 0x08, 0x6b, 0xff, 0xbc, 0xab, 0xd9, 0xfe, 0xd9, 0x37, 0xd5, 0x8e, 0x5f, 0x33, 0xa3, 0xf1, 0xa4,
+ /*4e90:*/ 0x14, 0x77, 0xdb, 0x2b, 0xda, 0x8e, 0x5f, 0xb0, 0x33, 0x70, 0x6d, 0xd7, 0x84, 0xbf, 0xe5, 0x76,
+ /*4ea0:*/ 0xc3, 0xed, 0x1b, 0x34, 0xaa, 0xc1, 0x8d, 0x91, 0xf9, 0x44, 0x9b, 0xb7, 0x40, 0x92, 0x5d, 0xf3,
+ /*4eb0:*/ 0x3f, 0xe0, 0xb2, 0x34, 0x6b, 0x43, 0xc2, 0x04, 0xf5, 0x22, 0x95, 0xf5, 0xf6, 0x0a, 0x0d, 0x3c,
+ /*4ec0:*/ 0x51, 0xde, 0xa5, 0x32, 0x85, 0x29, 0x49, 0xd2, 0x37, 0x97, 0x44, 0x8f, 0x09, 0x49, 0xb7, 0xcb,
+ /*4ed0:*/ 0x76, 0xb5, 0x5d, 0x27, 0x24, 0x08, 0xb0, 0x73, 0x6d, 0xd5, 0xce, 0x44, 0xe2, 0xbf, 0x5a, 0xa1,
+ /*4ee0:*/ 0x52, 0x19, 0xdd, 0x09, 0xc1, 0x8c, 0x04, 0x0c, 0x5c, 0x4d, 0x80, 0xeb, 0x28, 0xb2, 0xf6, 0x74,
+ /*4ef0:*/ 0x98, 0xef, 0xe9, 0xfc, 0x67, 0xb1, 0x6a, 0x4d, 0x99, 0x50, 0xcc, 0x5e, 0x4e, 0x48, 0xaf, 0x3a,
+ /*4f00:*/ 0x2b, 0xf9, 0xd5, 0x8a, 0xf5, 0x2c, 0xb1, 0x48, 0x24, 0x3c, 0x93, 0xd8, 0xd0, 0x0a, 0x7a, 0x72,
+ /*4f10:*/ 0x20, 0xe6, 0xe1, 0x38, 0x6b, 0xa5, 0x30, 0x03, 0xaf, 0x3c, 0x52, 0x34, 0xdf, 0x42, 0x0c, 0x62,
+ /*4f20:*/ 0xfd, 0x7e, 0x11, 0x3a, 0x8b, 0x89, 0x36, 0x34, 0xf4, 0xdb, 0x88, 0xe4, 0xb9, 0x0a, 0xb8, 0x72,
+ /*4f30:*/ 0x3f, 0x42, 0x13, 0x7e, 0x4b, 0x4e, 0x6d, 0xae, 0x3c, 0x49, 0x26, 0x12, 0x75, 0x70, 0x8f, 0x43,
+ /*4f40:*/ 0xaa, 0xb3, 0x1a, 0x87, 0x12, 0x99, 0x43, 0x7c, 0x37, 0x52, 0xc6, 0xb1, 0x72, 0x5a, 0xab, 0xc8,
+ /*4f50:*/ 0x49, 0xd5, 0x30, 0x49, 0x8f, 0xf0, 0x06, 0xae, 0x97, 0x7d, 0x97, 0x57, 0x5e, 0x2b, 0x6a, 0x43,
+ /*4f60:*/ 0xa2, 0x8d, 0xa8, 0x4e, 0xcf, 0xa3, 0xbb, 0x1a, 0x28, 0x23, 0x06, 0x3d, 0x61, 0x2a, 0x4c, 0x97,
+ /*4f70:*/ 0x9a, 0xd2, 0x3e, 0xc1, 0x68, 0xc5, 0x3c, 0x81, 0x61, 0x7f, 0x8b, 0xea, 0x0f, 0x42, 0x9c, 0x89,
+ /*4f80:*/ 0xb8, 0xb1, 0x8a, 0xd1, 0x74, 0x09, 0x6c, 0x13, 0xee, 0x22, 0x8a, 0x3c, 0x59, 0xf6, 0x6c, 0xdb,
+ /*4f90:*/ 0xfd, 0xe9, 0x12, 0x29, 0xd9, 0x56, 0xdf, 0xe9, 0x9b, 0x4f, 0x30, 0x0e, 0x1c, 0x4c, 0x3f, 0x57,
+ /*4fa0:*/ 0xea, 0xd2, 0x9a, 0x00, 0x2d, 0x05, 0xfa, 0x0d, 0xcd, 0x2a, 0x6b, 0x7b, 0x12, 0xae, 0xe5, 0xe2,
+ /*4fb0:*/ 0xb0, 0xa1, 0x3c, 0xfc, 0xcb, 0x41, 0x00, 0x4c, 0x79, 0xbd, 0x02, 0x47, 0x36, 0x1b, 0x2a, 0xbc,
+ /*4fc0:*/ 0x46, 0x3a, 0x29, 0x68, 0x4b, 0x41, 0x5f, 0x47, 0x2b, 0xdb, 0x4c, 0x0d, 0xba, 0x7d, 0x3e, 0xd8,
+ /*4fd0:*/ 0x9a, 0x74, 0x62, 0x3d, 0x5d, 0x29, 0xec, 0x52, 0x65, 0x65, 0xdb, 0x95, 0xa5, 0x52, 0xff, 0xbb,
+ /*4fe0:*/ 0xef, 0xdb, 0xe9, 0xe4, 0xef, 0xb8, 0x0f, 0x94, 0x84, 0xab, 0xcb, 0x2e, 0x3c, 0x07, 0xee, 0xc1,
+ /*4ff0:*/ 0x26, 0xa5, 0xcd, 0xc4, 0x8f, 0xd7, 0x4c, 0xb5, 0x8c, 0xa8, 0x82, 0xbb, 0xda, 0xfe, 0x18, 0x25,
+ /*5000:*/ 0x0a, 0x5a, 0x1c, 0x02, 0x5a, 0x84, 0xa7, 0x1e, 0xdb, 0x8a, 0xc3, 0x97, 0xf0, 0x3a, 0x82, 0x06,
+ /*5010:*/ 0x08, 0x55, 0x93, 0x72, 0x66, 0xec, 0xac, 0x86, 0x3a, 0xb4, 0x27, 0xf4, 0x9d, 0x91, 0x96, 0xe8,
+ /*5020:*/ 0x6c, 0x06, 0x6c, 0xc0, 0xe4, 0x18, 0x1c, 0x54, 0x72, 0x2e, 0x4c, 0x56, 0xb6, 0x15, 0xe0, 0x72,
+ /*5030:*/ 0x66, 0xf0, 0xb0, 0xde, 0x53, 0x32, 0x30, 0x6c, 0xe4, 0x3f, 0x6e, 0x6e, 0x6a, 0xa3, 0xc5, 0x30,
+ /*5040:*/ 0xc8, 0xba, 0x71, 0x11, 0x9c, 0x57, 0x34, 0xb4, 0x92, 0x7d, 0x19, 0x3c, 0xcd, 0x9d, 0x22, 0xa2,
+ /*5050:*/ 0xf9, 0xdb, 0x99, 0x73, 0xfe, 0xcc, 0x10, 0x2d, 0xdf, 0x96, 0xf6, 0x8b, 0xce, 0x74, 0x91, 0xcb,
+ /*5060:*/ 0xd8, 0x50, 0x6b, 0x9d, 0x56, 0xec, 0x53, 0x7e, 0x5b, 0xaa, 0x7b, 0xa3, 0x9b, 0xaf, 0xa5, 0x7e,
+ /*5070:*/ 0xa4, 0xfa, 0x10, 0xdb, 0x73, 0x6e, 0xba, 0x66, 0x66, 0x17, 0xd5, 0x60, 0xa7, 0x9c, 0x4b, 0xdf,
+ /*5080:*/ 0xa7, 0x5e, 0x45, 0xfe, 0x5f, 0xbe, 0xf1, 0xd2, 0x63, 0x1a, 0x4d, 0x26, 0x22, 0x6e, 0x03, 0xe0,
+ /*5090:*/ 0x45, 0x89, 0x30, 0x41, 0x43, 0xad, 0x2b, 0xad, 0xf4, 0x0e, 0x0f, 0xa5, 0x33, 0xfc, 0x49, 0x30,
+ /*50a0:*/ 0x44, 0xf5, 0xc5, 0x8e, 0xe2, 0xa6, 0x32, 0x4b, 0x0c, 0xd5, 0x4d, 0x91, 0xe3, 0x48, 0xe2, 0xb7,
+ /*50b0:*/ 0xad, 0x24, 0xfb, 0xf9, 0x13, 0xe0, 0x3c, 0x8a, 0x03, 0xc6, 0x35, 0xbc, 0xd6, 0x6e, 0x03, 0x20,
+ /*50c0:*/ 0xda, 0x2b, 0x95, 0x22, 0x23, 0x55, 0xab, 0x79, 0x58, 0xd0, 0x55, 0x1a, 0x4d, 0xa4, 0xfd, 0x6e,
+ /*50d0:*/ 0x6b, 0x99, 0xc1, 0xf0, 0xba, 0x5d, 0x51, 0xfe, 0x59, 0xc3, 0x52, 0x19, 0x1b, 0x33, 0x89, 0x60,
+ /*50e0:*/ 0x07, 0xaf, 0x23, 0xd1, 0x01, 0xcd, 0xc9, 0xfa, 0x58, 0xa6, 0x7d, 0xec, 0x3e, 0x19, 0xc6, 0xc0,
+ /*50f0:*/ 0xa9, 0x5e, 0x9a, 0xb1, 0xe8, 0x58, 0xcb, 0x05, 0x36, 0x11, 0x98, 0xa3, 0x35, 0x32, 0x87, 0x44,
+ /*5100:*/ 0x5f, 0x6b, 0xdf, 0x09, 0x15, 0x42, 0xd7, 0xe9, 0x72, 0x56, 0x3f, 0x6b, 0x19, 0x08, 0x46, 0xf0,
+ /*5110:*/ 0x25, 0x77, 0x96, 0x04, 0x0f, 0x99, 0x4e, 0xa9, 0xbb, 0x7d, 0xad, 0x19, 0x6b, 0x2e, 0x42, 0x41,
+ /*5120:*/ 0xbc, 0xd2, 0xf0, 0x4b, 0xc6, 0xc5, 0x72, 0xa1, 0x39, 0x22, 0x56, 0x9b, 0x72, 0x34, 0x01, 0x3b,
+ /*5130:*/ 0x70, 0x33, 0x0f, 0xa3, 0x80, 0xf3, 0x9b, 0xcf, 0x4c, 0x22, 0xb5, 0xce, 0xd7, 0xe1, 0xdd, 0xa9,
+ /*5140:*/ 0xa0, 0x04, 0x87, 0xd0, 0xe2, 0x76, 0xed, 0xb6, 0x17, 0xb5, 0xf8, 0x20, 0x4c, 0xb2, 0x1c, 0x25,
+ /*5150:*/ 0x8b, 0x7e, 0x10, 0x65, 0xe3, 0xaa, 0x9b, 0x58, 0xfe, 0x41, 0x68, 0x9b, 0x2e, 0x02, 0x93, 0x86,
+ /*5160:*/ 0xab, 0xba, 0xb2, 0x70, 0xed, 0x13, 0x21, 0x94, 0xc7, 0x4f, 0xac, 0xb3, 0x77, 0xbb, 0xf1, 0x62,
+ /*5170:*/ 0x08, 0xfd, 0xe6, 0x53, 0xa0, 0x03, 0xc7, 0xbb, 0xcc, 0xf8, 0x90, 0x93, 0x2d, 0xc7, 0xee, 0xf8,
+ /*5180:*/ 0xf5, 0x08, 0xf8, 0x70, 0x2b, 0xc7, 0x29, 0x49, 0xc6, 0xc1, 0xbe, 0xc9, 0x48, 0x4b, 0xb4, 0x87,
+ /*5190:*/ 0xa3, 0xcb, 0x24, 0x88, 0x5f, 0xd7, 0xc0, 0x28, 0x2e, 0x13, 0x12, 0x6c, 0xf5, 0x00, 0x09, 0x12,
+ /*51a0:*/ 0x59, 0x8d, 0x38, 0x6c, 0xb7, 0x33, 0xda, 0x11, 0x66, 0x06, 0xd5, 0x11, 0x99, 0x1f, 0x3f, 0x44,
+ /*51b0:*/ 0xf1, 0x5e, 0x58, 0x7f, 0x30, 0xaf, 0x73, 0x8d, 0x24, 0x01, 0x5c, 0x1d, 0x02, 0x4a, 0x15, 0xd9,
+ /*51c0:*/ 0x8c, 0x6e, 0x12, 0xe6, 0x54, 0x73, 0xe9, 0x62, 0x31, 0xf9, 0x8e, 0x3c, 0x00, 0xff, 0x80, 0x48,
+ /*51d0:*/ 0xb9, 0x24, 0x18, 0x2f, 0xa7, 0xd8, 0x07, 0xd0, 0x84, 0x64, 0xe6, 0xad, 0x9d, 0xe9, 0xa7, 0xd8,
+ /*51e0:*/ 0x3c, 0xaa, 0x59, 0x19, 0x5a, 0x29, 0x61, 0xf8, 0x39, 0xcb, 0x16, 0x63, 0x9e, 0x6a, 0xc8, 0xcd,
+ /*51f0:*/ 0x5d, 0x4f, 0x97, 0x8c, 0xe3, 0xf1, 0x9a, 0xa0, 0x33, 0x24, 0x7c, 0x15, 0x65, 0x95, 0xb3, 0x09,
+ /*5200:*/ 0xaf, 0x2f, 0x11, 0x6c, 0xac, 0xea, 0x75, 0x33, 0x4b, 0x5a, 0xf3, 0x9f, 0x38, 0xa4, 0x60, 0xd8,
+ /*5210:*/ 0x0c, 0xff, 0x92, 0x97, 0x35, 0x63, 0xbe, 0x2f, 0x44, 0xa5, 0xc6, 0x4d, 0x61, 0x3e, 0xc5, 0xad,
+ /*5220:*/ 0xc6, 0x9b, 0x41, 0x02, 0x0c, 0x9d, 0x1e, 0xc5, 0xb1, 0x21, 0x0e, 0xd3, 0x44, 0xd8, 0x36, 0x49,
+ /*5230:*/ 0x73, 0x20, 0x23, 0xbc, 0x97, 0x99, 0xf0, 0xc2, 0x6f, 0x2c, 0x10, 0x69, 0x9d, 0xfe, 0x4d, 0x85,
+ /*5240:*/ 0xf7, 0xd6, 0x86, 0x87, 0x05, 0x42, 0x8d, 0xcb, 0xc7, 0x9f, 0xbd, 0x28, 0x0b, 0xdd, 0x8c, 0xe0,
+ /*5250:*/ 0x60, 0x61, 0x77, 0xb5, 0xca, 0x50, 0x33, 0x3d, 0xd4, 0x82, 0x51, 0x8d, 0x5b, 0x14, 0x28, 0x98,
+ /*5260:*/ 0x88, 0x90, 0x34, 0x1e, 0x77, 0xf6, 0x7f, 0xc2, 0x00, 0xf8, 0x55, 0x6d, 0xf9, 0xce, 0xb0, 0x3a,
+ /*5270:*/ 0xec, 0xe5, 0x5f, 0x8b, 0x2b, 0x12, 0x5c, 0x9b, 0x01, 0x33, 0xa6, 0x9b, 0x8b, 0xb1, 0x6a, 0x8d,
+ /*5280:*/ 0x70, 0xb2, 0x9e, 0x07, 0x27, 0x5a, 0x40, 0x5d, 0xba, 0x7f, 0x8b, 0x4c, 0x99, 0x49, 0x6e, 0x31,
+ /*5290:*/ 0x1e, 0xe4, 0x7e, 0x4a, 0x5d, 0xc3, 0xd1, 0x04, 0x0a, 0x7a, 0xab, 0x6a, 0x3c, 0x38, 0xa7, 0x7f,
+ /*52a0:*/ 0xd0, 0xcd, 0x06, 0x6a, 0x81, 0x37, 0x28, 0x25, 0xe9, 0xd2, 0xe6, 0x79, 0x1c, 0x43, 0x36, 0x80,
+ /*52b0:*/ 0x2b, 0x1d, 0xee, 0xd4, 0x4b, 0x7a, 0x5f, 0x9a, 0x7c, 0x38, 0xc1, 0x08, 0xa9, 0x17, 0x18, 0xd2,
+ /*52c0:*/ 0x6c, 0x78, 0xf0, 0xaa, 0xb4, 0x62, 0x38, 0x96, 0x6e, 0x96, 0x7b, 0x21, 0xc3, 0x21, 0x9b, 0xb2,
+ /*52d0:*/ 0x70, 0x5d, 0x7b, 0x2f, 0xb1, 0xc6, 0x96, 0x1a, 0xe0, 0xd7, 0x76, 0x6a, 0x6f, 0x4b, 0x23, 0x38,
+ /*52e0:*/ 0x9b, 0xc7, 0xac, 0xbf, 0x44, 0x01, 0x0f, 0xb6, 0x66, 0x97, 0xa5, 0xc6, 0xf8, 0xc2, 0xfa, 0x3b,
+ /*52f0:*/ 0x78, 0x48, 0xd1, 0xac, 0xe8, 0x47, 0xd0, 0x0e, 0x80, 0x0c, 0x52, 0xf0, 0xd4, 0x04, 0x4a, 0xd7,
+ /*5300:*/ 0x60, 0x49, 0xe5, 0x78, 0xe6, 0xc6, 0x91, 0xbc, 0x67, 0x12, 0x9a, 0x14, 0x39, 0x3a, 0xd5, 0x3a,
+ /*5310:*/ 0xa4, 0x2c, 0xfc, 0x1c, 0x30, 0x99, 0xdd, 0xf2, 0xba, 0xe6, 0xfa, 0xe3, 0x1d, 0xd9, 0xae, 0x64,
+ /*5320:*/ 0x11, 0x87, 0x92, 0x51, 0xc9, 0x61, 0x50, 0xb0, 0x82, 0x6d, 0x0b, 0x43, 0x8b, 0xf6, 0xae, 0x8e,
+ /*5330:*/ 0x83, 0x7d, 0x00, 0xfc, 0xd9, 0xf5, 0x4b, 0x14, 0x36, 0xf1, 0x4a, 0xea, 0x33, 0x92, 0x8c, 0x16,
+ /*5340:*/ 0x91, 0xb9, 0xf0, 0x44, 0xa2, 0x31, 0xed, 0x0e, 0x6b, 0x45, 0xb3, 0xe2, 0x47, 0xab, 0xc6, 0x70,
+ /*5350:*/ 0xf8, 0x84, 0xe8, 0xa4, 0x41, 0x9f, 0x32, 0xd5, 0x61, 0x6b, 0x81, 0x38, 0x34, 0x5b, 0x88, 0xf2,
+ /*5360:*/ 0x82, 0xae, 0x6c, 0x5e, 0xa0, 0x6f, 0xb1, 0x93, 0xaf, 0x6b, 0x04, 0xbe, 0xd5, 0xcb, 0xae, 0xac,
+ /*5370:*/ 0xd0, 0x09, 0x2a, 0x7d, 0x9f, 0xa6, 0xa9, 0xa2, 0x46, 0x61, 0x82, 0xaa, 0x95, 0x9c, 0xf1, 0x36,
+ /*5380:*/ 0x57, 0xb5, 0xcf, 0x5a, 0x00, 0x43, 0xac, 0x5c, 0xb4, 0xd9, 0xe2, 0x08, 0x03, 0x5c, 0x88, 0xc4,
+ /*5390:*/ 0xab, 0x50, 0xa6, 0x72, 0xae, 0xe0, 0x56, 0xba, 0x93, 0x9a, 0x87, 0x20, 0xe1, 0x08, 0x55, 0x2c,
+ /*53a0:*/ 0xeb, 0xff, 0xfd, 0xc6, 0x31, 0xc0, 0xb2, 0xce, 0x62, 0xe4, 0x8b, 0x31, 0xc3, 0xa9, 0x70, 0xed,
+ /*53b0:*/ 0x0f, 0x98, 0x04, 0x70, 0x07, 0xa3, 0x17, 0xc5, 0xb6, 0x15, 0x02, 0x2b, 0x62, 0x68, 0xb9, 0x18,
+ /*53c0:*/ 0xa4, 0x88, 0xf8, 0xad, 0x61, 0x63, 0x9d, 0x4f, 0x71, 0xd5, 0xbc, 0x32, 0x86, 0xa9, 0x2b, 0x6b,
+ /*53d0:*/ 0xdf, 0x2d, 0x0d, 0x4b, 0x6f, 0x65, 0xe4, 0x57, 0xae, 0x76, 0xac, 0x48, 0xeb, 0xa8, 0x12, 0xc5,
+ /*53e0:*/ 0x30, 0x93, 0x12, 0xfb, 0x85, 0xa9, 0x76, 0xe4, 0xca, 0x36, 0xbc, 0xb4, 0xd4, 0xa5, 0x6f, 0x3c,
+ /*53f0:*/ 0x77, 0x16, 0x05, 0x00, 0x3f, 0xd3, 0x0b, 0x93, 0x3e, 0xf0, 0xdd, 0xa3, 0xd9, 0xba, 0xfd, 0x6d,
+ /*5400:*/ 0x6e, 0x91, 0x64, 0x41, 0xa0, 0x40, 0xd7, 0x1a, 0x25, 0x33, 0xb8, 0x35, 0x50, 0x56, 0xa6, 0xf1,
+ /*5410:*/ 0x18, 0x19, 0x98, 0x5e, 0x74, 0x4b, 0xb0, 0xc0, 0xf2, 0xbb, 0x5b, 0x06, 0x1c, 0xc7, 0x35, 0x3b,
+ /*5420:*/ 0x3f, 0x00, 0x58, 0x20, 0x4a, 0x52, 0x25, 0xd2, 0x10, 0x79, 0x3b, 0x78, 0xd3, 0x6b, 0x39, 0x5c,
+ /*5430:*/ 0xf3, 0x22, 0xde, 0xb8, 0xd6, 0x8b, 0xe9, 0x2c, 0x03, 0x55, 0xd4, 0x82, 0x66, 0x33, 0x6e, 0xa1,
+ /*5440:*/ 0x68, 0xd8, 0x63, 0x1f, 0xda, 0xf8, 0x14, 0x4c, 0xfd, 0x78, 0x70, 0x3e, 0xdf, 0xdb, 0x83, 0x99,
+ /*5450:*/ 0x94, 0x61, 0xa5, 0x86, 0x64, 0xae, 0x9c, 0xfe, 0x33, 0xc7, 0x20, 0x04, 0x5a, 0xbe, 0xd4, 0x74,
+ /*5460:*/ 0xef, 0x19, 0x39, 0xf8, 0xf9, 0xff, 0xcc, 0x96, 0x3a, 0xb6, 0x1c, 0x54, 0xd8, 0xd7, 0xcb, 0xf6,
+ /*5470:*/ 0xd7, 0x97, 0x51, 0xd2, 0xd8, 0x86, 0x8e, 0x04, 0x5f, 0xc6, 0x5c, 0x3e, 0x71, 0x87, 0xa6, 0x50,
+ /*5480:*/ 0xeb, 0x41, 0x45, 0x45, 0xba, 0x0f, 0x67, 0x32, 0x44, 0x64, 0xbf, 0xde, 0xbc, 0x4c, 0x11, 0xfe,
+ /*5490:*/ 0xc2, 0x24, 0xe2, 0xf3, 0x30, 0xb2, 0x87, 0xa1, 0x62, 0xf6, 0xa0, 0x7d, 0xf7, 0xd9, 0x68, 0x83,
+ /*54a0:*/ 0x7a, 0x1b, 0x00, 0x0d, 0x01, 0xd8, 0xc0, 0xa6, 0x99, 0x2a, 0x95, 0x44, 0x5f, 0xda, 0xf6, 0xc3,
+ /*54b0:*/ 0xa0, 0x30, 0x0b, 0x1d, 0x88, 0xb4, 0xae, 0xc7, 0x2b, 0xae, 0x06, 0x2a, 0xb1, 0x72, 0x64, 0xec,
+ /*54c0:*/ 0x0b, 0xdc, 0xc6, 0xba, 0x92, 0xa6, 0xb9, 0x6e, 0x4f, 0x69, 0x12, 0x99, 0xb5, 0x00, 0xcf, 0x8d,
+ /*54d0:*/ 0x8e, 0x0b, 0x94, 0x75, 0xf2, 0x89, 0xb4, 0x35, 0x48, 0x9d, 0x7f, 0x76, 0x15, 0xb9, 0x92, 0x0b,
+ /*54e0:*/ 0x82, 0xba, 0x88, 0x8a, 0xff, 0x21, 0x3b, 0xd8, 0x53, 0x02, 0x78, 0x6a, 0x2a, 0x7c, 0x34, 0xb5,
+ /*54f0:*/ 0xfc, 0xc7, 0xb8, 0x99, 0xe0, 0xed, 0xb8, 0x52, 0xce, 0xc8, 0x68, 0x5e, 0x67, 0x2a, 0x7a, 0x4b,
+ /*5500:*/ 0x75, 0x78, 0x0f, 0x9d, 0xbe, 0x0e, 0x4c, 0xde, 0x5a, 0x1b, 0xc2, 0x36, 0xf3, 0xe4, 0x8a, 0xfd,
+ /*5510:*/ 0xf3, 0x72, 0x42, 0x38, 0xac, 0xd3, 0xc4, 0xaa, 0x16, 0xfa, 0x60, 0x8b, 0x4e, 0xd5, 0x87, 0x34,
+ /*5520:*/ 0x78, 0x01, 0x8b, 0x3b, 0x48, 0x1e, 0x57, 0x46, 0x59, 0x2d, 0x6c, 0xda, 0x80, 0xb2, 0x4b, 0x9c,
+ /*5530:*/ 0x77, 0xa2, 0x1c, 0xc0, 0x70, 0x63, 0xc1, 0x0e, 0x30, 0xf1, 0x26, 0xd1, 0xdd, 0x75, 0xf8, 0x3f,
+ /*5540:*/ 0x2c, 0xeb, 0x9d, 0xdf, 0xbc, 0x74, 0xff, 0x46, 0x6e, 0xbc, 0x7f, 0x9b, 0x41, 0xce, 0x20, 0xb0,
+ /*5550:*/ 0xb7, 0xff, 0x99, 0xc3, 0x13, 0x7c, 0xf6, 0x4b, 0xb3, 0x35, 0x37, 0xaa, 0xf2, 0x9a, 0xad, 0x67,
+ /*5560:*/ 0x81, 0xe0, 0x9d, 0xa6, 0x4f, 0x48, 0x68, 0xc2, 0x22, 0xaf, 0xf8, 0xdf, 0xf9, 0x2f, 0x08, 0x84,
+ /*5570:*/ 0x2c, 0xcb, 0xc4, 0x86, 0xe2, 0x5a, 0x38, 0x94, 0x45, 0x4d, 0xd7, 0x30, 0x97, 0x5a, 0xd4, 0x60,
+ /*5580:*/ 0x3b, 0x20, 0xb5, 0xf8, 0x39, 0x8c, 0x1a, 0x60, 0x05, 0xbb, 0x9e, 0x61, 0x8c, 0x56, 0x96, 0x39,
+ /*5590:*/ 0xe4, 0x78, 0x10, 0x07, 0x14, 0xb3, 0xbe, 0x0d, 0x24, 0x58, 0x78, 0xa8, 0x79, 0x29, 0xf0, 0xcc,
+ /*55a0:*/ 0x12, 0x4b, 0x5a, 0x9a, 0xa4, 0x4b, 0xa8, 0x37, 0x5e, 0xc3, 0x1b, 0x13, 0x77, 0x24, 0x09, 0x29,
+ /*55b0:*/ 0xcc, 0xf9, 0x05, 0xd7, 0x20, 0xe9, 0x16, 0xd5, 0xb0, 0x4d, 0x61, 0x44, 0xd7, 0x29, 0x9b, 0xd7,
+ /*55c0:*/ 0x6c, 0xaa, 0x82, 0xc9, 0x6e, 0x3a, 0x07, 0x8b, 0x9c, 0xef, 0x6a, 0xc0, 0x91, 0x11, 0x4b, 0x2d,
+ /*55d0:*/ 0x26, 0xd7, 0x3b, 0x11, 0x88, 0x4d, 0x6f, 0xf4, 0xad, 0xf3, 0xde, 0xdb, 0xa5, 0xb9, 0x7b, 0x64,
+ /*55e0:*/ 0x60, 0x7b, 0xd8, 0xf2, 0xd3, 0xa3, 0x64, 0x1a, 0x56, 0xc9, 0x5e, 0x6a, 0x86, 0xbd, 0x28, 0xea,
+ /*55f0:*/ 0x31, 0x28, 0x15, 0x84, 0x5c, 0xe5, 0x0a, 0x89, 0x54, 0x69, 0x14, 0x5b, 0xca, 0x24, 0x56, 0xc2,
+ /*5600:*/ 0x71, 0x96, 0xdf, 0x31, 0x9b, 0x72, 0x9f, 0xb3, 0xce, 0xd4, 0x87, 0xf6, 0x6f, 0x32, 0x89, 0x72,
+ /*5610:*/ 0x82, 0x7c, 0x59, 0x5c, 0x57, 0xfa, 0x01, 0x89, 0xd2, 0x2d, 0x45, 0xe3, 0x53, 0x62, 0xc9, 0x40,
+ /*5620:*/ 0x73, 0xa0, 0xcd, 0x96, 0xe1, 0xe5, 0x42, 0xed, 0x1a, 0x51, 0xb2, 0xb6, 0xc3, 0x18, 0xed, 0xd1,
+ /*5630:*/ 0x1f, 0x07, 0x69, 0x66, 0xbd, 0x27, 0x78, 0x6e, 0xd9, 0xf0, 0xe5, 0x37, 0x75, 0xbd, 0x67, 0xcf,
+ /*5640:*/ 0x62, 0x4e, 0xd2, 0xb1, 0xfa, 0xa9, 0x0c, 0x4a, 0xd3, 0x96, 0x96, 0x0f, 0xcd, 0x9b, 0x80, 0x1a,
+ /*5650:*/ 0x3b, 0x4a, 0x99, 0xdb, 0xd4, 0x16, 0x02, 0x62, 0x15, 0x97, 0xfa, 0xac, 0xd2, 0x04, 0x0b, 0xd5,
+ /*5660:*/ 0x7b, 0x20, 0x1d, 0xf3, 0x9c, 0xed, 0x32, 0x9b, 0x90, 0x2d, 0x95, 0xb1, 0x7e, 0x2c, 0xf8, 0x27,
+ /*5670:*/ 0x2c, 0x06, 0x8b, 0x23, 0x93, 0xc5, 0xa2, 0x0d, 0x94, 0xfc, 0xfd, 0x56, 0xe1, 0xe6, 0xa9, 0x81,
+ /*5680:*/ 0xe2, 0x48, 0x53, 0xee, 0x6d, 0xe9, 0x44, 0x92, 0x1b, 0x73, 0x16, 0xd6, 0x99, 0x12, 0xa4, 0x6a,
+ /*5690:*/ 0xa1, 0xfc, 0x8b, 0x1a, 0xf0, 0xb4, 0x1c, 0x67, 0xd4, 0x83, 0x65, 0x69, 0x9c, 0x64, 0xb1, 0x9e,
+ /*56a0:*/ 0x0b, 0x74, 0xbb, 0x0f, 0xa8, 0x7d, 0xb9, 0x39, 0x3b, 0x2c, 0x89, 0xcf, 0x70, 0x74, 0x27, 0xcf,
+ /*56b0:*/ 0x4a, 0xdd, 0x8a, 0xe5, 0x05, 0x46, 0x6d, 0x84, 0xba, 0x1d, 0x70, 0x78, 0x5a, 0x6f, 0x9a, 0xf1,
+ /*56c0:*/ 0xb4, 0xf8, 0x11, 0x7b, 0x39, 0xe7, 0x03, 0x67, 0x58, 0x6b, 0x64, 0x8c, 0x8d, 0xa3, 0xd2, 0x7d,
+ /*56d0:*/ 0xf4, 0x35, 0x4e, 0x48, 0x61, 0xc8, 0xaa, 0x57, 0xb9, 0xf5, 0xcd, 0x9c, 0xaa, 0x38, 0x78, 0x17,
+ /*56e0:*/ 0xaf, 0x59, 0x11, 0x2b, 0xfa, 0x49, 0x6c, 0xf3, 0xdf, 0x53, 0xb0, 0xb5, 0x3d, 0x1e, 0x37, 0x7e,
+ /*56f0:*/ 0x11, 0x2c, 0x56, 0xfa, 0xc7, 0x77, 0x6d, 0x6c, 0xd8, 0xd6, 0x12, 0x41, 0x12, 0xa2, 0x02, 0x06,
+ /*5700:*/ 0xcd, 0x5d, 0x75, 0xba, 0x86, 0xe5, 0xe5, 0x27, 0xdf, 0x8c, 0xd0, 0x06, 0xeb, 0x41, 0xbe, 0x8d,
+ /*5710:*/ 0xe1, 0xa2, 0x90, 0x8f, 0x4b, 0xbf, 0x76, 0x03, 0x75, 0x33, 0x29, 0x1a, 0x80, 0x57, 0xd6, 0x67,
+ /*5720:*/ 0x01, 0x72, 0xc1, 0x5a, 0xea, 0xd3, 0xbe, 0xb1, 0xac, 0x6c, 0x13, 0xc5, 0xc2, 0x72, 0x7d, 0x22,
+ /*5730:*/ 0xb0, 0xa2, 0xab, 0xf6, 0x52, 0x78, 0x37, 0xcf, 0x38, 0x1e, 0x13, 0xb9, 0xee, 0x71, 0x5a, 0xc4,
+ /*5740:*/ 0xfc, 0x6a, 0x11, 0xe1, 0xd6, 0x6e, 0x01, 0x32, 0x5a, 0x51, 0x35, 0x39, 0x59, 0x30, 0xc5, 0x15,
+ /*5750:*/ 0x87, 0x52, 0x63, 0xe8, 0x07, 0x39, 0xd8, 0xf0, 0x85, 0xf5, 0x7c, 0x31, 0x6d, 0xbf, 0x24, 0x27,
+ /*5760:*/ 0xf7, 0x66, 0xca, 0x6a, 0x81, 0xc8, 0x38, 0x02, 0x07, 0x20, 0x49, 0x2e, 0x9e, 0xe6, 0xe9, 0x5e,
+ /*5770:*/ 0x64, 0x81, 0xed, 0xea, 0xf9, 0x87, 0x53, 0xed, 0x06, 0xe0, 0x27, 0xba, 0x29, 0x0b, 0x00, 0xa0,
+ /*5780:*/ 0x2c, 0xbf, 0xee, 0x37, 0x44, 0x63, 0xa0, 0xf4, 0xe3, 0x9a, 0xc5, 0xba, 0x6f, 0x50, 0x1c, 0x72,
+ /*5790:*/ 0x14, 0x89, 0x3c, 0x14, 0xc4, 0xf7, 0x8c, 0x4d, 0x7d, 0x2a, 0xa2, 0xb4, 0x94, 0xfe, 0xfd, 0xce,
+ /*57a0:*/ 0xcf, 0x07, 0x71, 0x33, 0xe0, 0x46, 0xe0, 0x03, 0x94, 0x42, 0x9d, 0x55, 0x69, 0x2c, 0x3d, 0x74,
+ /*57b0:*/ 0x6b, 0x74, 0x52, 0x49, 0x34, 0x9c, 0x51, 0xc0, 0x19, 0x0c, 0x5e, 0x74, 0x76, 0xc2, 0x4a, 0x0a,
+ /*57c0:*/ 0x14, 0x88, 0x4e, 0x2a, 0xa5, 0x9a, 0x9e, 0xc3, 0x99, 0x72, 0x5e, 0xef, 0x9c, 0x94, 0xac, 0xa7,
+ /*57d0:*/ 0x61, 0x78, 0xc2, 0x36, 0x17, 0x82, 0x2d, 0xce, 0x7d, 0x92, 0xd0, 0x8a, 0x3b, 0x3e, 0x1f, 0x1d,
+ /*57e0:*/ 0x83, 0xf9, 0xa8, 0x44, 0xdf, 0xce, 0x84, 0x31, 0xdc, 0xf2, 0xd6, 0x0d, 0xb9, 0x0b, 0x89, 0xc5,
+ /*57f0:*/ 0x77, 0xae, 0xa1, 0x9a, 0x75, 0xc6, 0x93, 0x6e, 0xdb, 0x61, 0xdd, 0x3d, 0x8e, 0x7c, 0x4b, 0x53,
+ /*5800:*/ 0x14, 0x1d, 0x3c, 0x51, 0x5f, 0x60, 0xfe, 0x6a, 0x1d, 0xef, 0x49, 0x30, 0x03, 0xf3, 0xb2, 0x7c,
+ /*5810:*/ 0xf5, 0x1c, 0x88, 0x68, 0xf4, 0xb8, 0xf5, 0x36, 0x4f, 0x17, 0x11, 0x39, 0x44, 0xfc, 0xaa, 0xe2,
+ /*5820:*/ 0x51, 0x20, 0x77, 0xc7, 0xe0, 0xf4, 0x6e, 0x8c, 0xa5, 0x77, 0xc7, 0x66, 0x2c, 0x24, 0xb1, 0xae,
+ /*5830:*/ 0xc1, 0xbd, 0x1a, 0x64, 0x1c, 0x1e, 0xa3, 0xbb, 0x52, 0xb3, 0x53, 0x1a, 0x5e, 0x94, 0xd6, 0x10,
+ /*5840:*/ 0xd4, 0x17, 0x6e, 0x36, 0xe8, 0x09, 0x6a, 0x0f, 0x67, 0x73, 0x40, 0xb8, 0xcf, 0xdd, 0xc0, 0xac,
+ /*5850:*/ 0x3a, 0xfd, 0x08, 0xcd, 0xd2, 0x42, 0xc0, 0xb0, 0x4e, 0xc3, 0xca, 0x66, 0x2b, 0x84, 0x19, 0x6f,
+ /*5860:*/ 0x2e, 0xf2, 0x22, 0x21, 0x56, 0xb7, 0x17, 0xbe, 0x47, 0xc2, 0x96, 0x6e, 0x60, 0xf2, 0xc7, 0x1f,
+ /*5870:*/ 0x9b, 0xb5, 0x82, 0xea, 0x02, 0x46, 0x4e, 0x04, 0xca, 0x64, 0xa1, 0x70, 0xd6, 0xd0, 0xd7, 0x3d,
+ /*5880:*/ 0x15, 0x42, 0x68, 0x17, 0xfd, 0x7f, 0x7f, 0x9a, 0x12, 0x1b, 0xcc, 0x7a, 0x59, 0x85, 0x5e, 0xfd,
+ /*5890:*/ 0x74, 0x55, 0x8b, 0xc9, 0x55, 0xf7, 0x44, 0x64, 0xa8, 0xff, 0xd3, 0xb5, 0x32, 0x2e, 0xb1, 0x3a,
+ /*58a0:*/ 0x36, 0xe2, 0x4d, 0x18, 0x35, 0x37, 0x5c, 0x5b, 0x8d, 0x9b, 0x51, 0x51, 0x39, 0xb2, 0xbe, 0x5a,
+ /*58b0:*/ 0xaf, 0xf6, 0xa4, 0x35, 0xc5, 0x62, 0x26, 0x9e, 0x60, 0xa8, 0xad, 0x12, 0x89, 0xef, 0x23, 0x9a,
+ /*58c0:*/ 0x54, 0x74, 0xa6, 0x07, 0x40, 0xab, 0x97, 0xf4, 0xcc, 0xa9, 0x37, 0xd2, 0x43, 0xda, 0x9b, 0xdb,
+ /*58d0:*/ 0x07, 0x3c, 0x6f, 0x33, 0x64, 0x6b, 0xfd, 0xa7, 0x72, 0x5c, 0x61, 0xce, 0xe7, 0x2a, 0x21, 0x96,
+ /*58e0:*/ 0xac, 0xb4, 0x04, 0x2d, 0x0b, 0x8b, 0x6d, 0xa8, 0xbd, 0x48, 0xab, 0xcd, 0xc9, 0x1f, 0x12, 0xf3,
+ /*58f0:*/ 0xb6, 0x83, 0xec, 0xa2, 0x89, 0x8b, 0x89, 0x35, 0x62, 0x10, 0x5e, 0xc8, 0x28, 0xcc, 0x2f, 0xfb,
+ /*5900:*/ 0x85, 0xb4, 0x9a, 0xab, 0x51, 0x1a, 0x78, 0x84, 0x42, 0xec, 0x99, 0xad, 0x5b, 0x53, 0x24, 0x39,
+ /*5910:*/ 0x68, 0x4c, 0xdb, 0xef, 0xab, 0x5c, 0x89, 0xfa, 0x6f, 0xf7, 0x23, 0x6c, 0x42, 0x7d, 0xbf, 0xe9,
+ /*5920:*/ 0x29, 0x96, 0x1f, 0x47, 0x39, 0x86, 0x02, 0x36, 0x5a, 0x1a, 0x98, 0xe4, 0x1a, 0x7b, 0x03, 0x3b,
+ /*5930:*/ 0x6c, 0x5f, 0x41, 0x61, 0x20, 0x26, 0xe2, 0xf2, 0x26, 0x8a, 0xf7, 0x50, 0xe4, 0x50, 0xd2, 0x64,
+ /*5940:*/ 0xea, 0xec, 0xf5, 0x37, 0xea, 0xf7, 0x68, 0x8b, 0x31, 0x24, 0xc8, 0x78, 0x96, 0x2d, 0xc6, 0x9b,
+ /*5950:*/ 0x46, 0xa1, 0x9a, 0xe2, 0xdc, 0xbb, 0x26, 0x14, 0xd8, 0x7e, 0x78, 0xb9, 0x60, 0x1d, 0xc4, 0x4b,
+ /*5960:*/ 0x66, 0xad, 0x2d, 0x11, 0x40, 0x70, 0xcd, 0x41, 0xb5, 0xb5, 0x8d, 0xe1, 0xc2, 0x44, 0x6a, 0xcf,
+ /*5970:*/ 0x87, 0x28, 0xa8, 0x8a, 0xc6, 0x9b, 0xb4, 0xd8, 0x14, 0xae, 0x0e, 0xae, 0x4e, 0xde, 0x7f, 0xf1,
+ /*5980:*/ 0x79, 0xec, 0x9c, 0xed, 0x96, 0x33, 0xfd, 0x40, 0xae, 0xbf, 0x34, 0xa2, 0x9c, 0x5a, 0xf7, 0xcd,
+ /*5990:*/ 0x4b, 0xab, 0xaa, 0xd2, 0xd5, 0xb2, 0x39, 0xcd, 0x4a, 0x23, 0xc7, 0xb9, 0x82, 0x55, 0xa9, 0x00,
+ /*59a0:*/ 0xf1, 0x6d, 0x29, 0x99, 0x0d, 0xc6, 0x83, 0x5a, 0x21, 0xaa, 0x09, 0xb6, 0x24, 0x17, 0xd9, 0xbe,
+ /*59b0:*/ 0x56, 0xd8, 0x23, 0x56, 0x94, 0xe5, 0x72, 0xdd, 0xb3, 0xc7, 0x30, 0x76, 0x66, 0xc8, 0x79, 0xd6,
+ /*59c0:*/ 0xda, 0xa0, 0x85, 0x20, 0x75, 0xd4, 0x17, 0x65, 0x68, 0xb2, 0x47, 0xe7, 0xae, 0xfc, 0xe8, 0x40,
+ /*59d0:*/ 0xf0, 0x10, 0x64, 0xa8, 0x56, 0x29, 0x92, 0x4c, 0xe1, 0x8d, 0x80, 0x60, 0x3e, 0x05, 0x3d, 0xaa,
+ /*59e0:*/ 0x46, 0x9b, 0x4b, 0xa8, 0x80, 0xd7, 0xb0, 0x81, 0xa4, 0x5c, 0xc6, 0x12, 0xef, 0x4b, 0xda, 0x3f,
+ /*59f0:*/ 0x4b, 0x78, 0xf4, 0x64, 0x17, 0x52, 0xc2, 0xec, 0x4a, 0xc6, 0x44, 0x3b, 0x80, 0xcf, 0xd6, 0xa5,
+ /*5a00:*/ 0x44, 0xa5, 0x02, 0x3b, 0x05, 0x10, 0xd0, 0x69, 0xdf, 0x7e, 0x27, 0xf0, 0x25, 0x26, 0x09, 0xa8,
+ /*5a10:*/ 0xa7, 0x38, 0x72, 0xe5, 0x96, 0x62, 0x8a, 0xc7, 0x5e, 0xb1, 0x6a, 0xf6, 0x5a, 0x1a, 0x08, 0x88,
+ /*5a20:*/ 0xe4, 0x18, 0x42, 0xff, 0x53, 0xbb, 0x93, 0x7c, 0xc5, 0x34, 0x65, 0x29, 0xcc, 0xbe, 0xfa, 0xb2,
+ /*5a30:*/ 0xec, 0x59, 0x23, 0xd8, 0xb2, 0x31, 0xe4, 0xe1, 0xe1, 0xb7, 0xd9, 0x40, 0xbd, 0xb6, 0x1b, 0x29,
+ /*5a40:*/ 0xba, 0x10, 0x60, 0x3d, 0x93, 0x68, 0x2f, 0x08, 0x17, 0xf3, 0x43, 0xa8, 0x0c, 0x1e, 0xda, 0x76,
+ /*5a50:*/ 0x60, 0x8a, 0xb0, 0x2d, 0x44, 0x09, 0x24, 0xf2, 0xca, 0xa8, 0xf5, 0xd4, 0x4e, 0x2a, 0xbd, 0xd7,
+ /*5a60:*/ 0xed, 0x37, 0x24, 0x20, 0xfa, 0x00, 0x0a, 0x01, 0x4d, 0xc1, 0xfe, 0x71, 0x26, 0x76, 0xf0, 0x2f,
+ /*5a70:*/ 0x2b, 0xe9, 0xb5, 0xfe, 0xd9, 0x18, 0x96, 0x84, 0x51, 0xc1, 0x39, 0xf3, 0x1a, 0x87, 0x1c, 0xf6,
+ /*5a80:*/ 0x62, 0xed, 0xcd, 0xa7, 0x7e, 0x57, 0x6d, 0x08, 0xc6, 0x90, 0x6d, 0xe5, 0x6e, 0xee, 0x8f, 0x88,
+ /*5a90:*/ 0x07, 0x71, 0xab, 0x55, 0x66, 0xfc, 0xf7, 0x0b, 0x90, 0x97, 0xc9, 0xe9, 0xf0, 0xe5, 0x30, 0x9a,
+ /*5aa0:*/ 0xd0, 0x5a, 0x00, 0x9c, 0x1c, 0x3c, 0x49, 0x2a, 0x3e, 0x72, 0xb8, 0xfe, 0xab, 0x20, 0xc8, 0xf5,
+ /*5ab0:*/ 0xd7, 0xf9, 0x76, 0xbe, 0x33, 0x45, 0xac, 0x6b, 0x81, 0x50, 0x66, 0x9c, 0x24, 0xa0, 0x47, 0xe0,
+ /*5ac0:*/ 0xbe, 0x7f, 0xa2, 0x85, 0xb0, 0x8a, 0xfb, 0x42, 0x04, 0xe0, 0xed, 0xd6, 0xfd, 0xcc, 0x59, 0x6f,
+ /*5ad0:*/ 0xe7, 0x57, 0x63, 0x52, 0x03, 0x75, 0x28, 0x2d, 0x07, 0x7b, 0xe3, 0xf9, 0xfb, 0xa1, 0xef, 0x85,
+ /*5ae0:*/ 0x51, 0xf0, 0xf8, 0x76, 0x11, 0xa6, 0x80, 0xe4, 0x4b, 0x24, 0xfd, 0x1f, 0xc7, 0x68, 0x05, 0x8f,
+ /*5af0:*/ 0xd8, 0xdb, 0x52, 0xbd, 0x09, 0x85, 0x75, 0x5e, 0xe1, 0x61, 0x14, 0x60, 0xaf, 0xfd, 0xd2, 0xdf,
+ /*5b00:*/ 0xa3, 0x80, 0xc9, 0xa2, 0x80, 0x69, 0x47, 0xe9, 0xb7, 0xcd, 0xbb, 0xae, 0x53, 0xbd, 0xa8, 0xf6,
+ /*5b10:*/ 0x86, 0x88, 0x4c, 0xdb, 0xfc, 0xa7, 0xd1, 0x42, 0xfc, 0xb8, 0x9f, 0xe9, 0xf3, 0x7e, 0xeb, 0x13,
+ /*5b20:*/ 0x4f, 0xb0, 0xfa, 0xe0, 0x40, 0x42, 0xa6, 0x3b, 0x35, 0xf9, 0x72, 0x2f, 0x21, 0x17, 0x2d, 0xdd,
+ /*5b30:*/ 0xa2, 0x39, 0xa5, 0x88, 0xb2, 0x9b, 0xdb, 0x65, 0x3b, 0x70, 0x97, 0xb1, 0xe4, 0x4c, 0xda, 0x69,
+ /*5b40:*/ 0x88, 0x5c, 0xde, 0x5b, 0x89, 0x42, 0xe5, 0x13, 0x29, 0x73, 0x71, 0xe6, 0x37, 0x8a, 0x3e, 0x69,
+ /*5b50:*/ 0x66, 0xfd, 0xb2, 0x4b, 0x85, 0xa9, 0x29, 0x11, 0xce, 0x9b, 0x5a, 0x77, 0x48, 0xc8, 0x45, 0x19,
+ /*5b60:*/ 0x22, 0x07, 0x84, 0x91, 0xa0, 0x91, 0x5d, 0x7b, 0xde, 0x37, 0xd5, 0xcf, 0x62, 0x4e, 0x01, 0xd1,
+ /*5b70:*/ 0x87, 0x1f, 0xf9, 0x2d, 0xe6, 0x35, 0x67, 0x45, 0x69, 0x5a, 0x50, 0xaf, 0xae, 0xa8, 0x5b, 0x62,
+ /*5b80:*/ 0xbb, 0x03, 0x86, 0x97, 0x7f, 0x84, 0xe2, 0xbf, 0xc3, 0x04, 0x06, 0x1d, 0x08, 0xbc, 0x6d, 0x8e,
+ /*5b90:*/ 0xb9, 0x7a, 0x0d, 0xf1, 0x6c, 0xc6, 0x25, 0xd2, 0x17, 0x26, 0x05, 0x4c, 0xe3, 0xd6, 0x52, 0x19,
+ /*5ba0:*/ 0xf3, 0xd0, 0xb1, 0x0b, 0x62, 0x4d, 0x6c, 0x8e, 0xb8, 0x34, 0x1e, 0xd8, 0x0e, 0x88, 0xe2, 0x91,
+ /*5bb0:*/ 0xa8, 0xf0, 0xdf, 0x13, 0xb7, 0x5e, 0x12, 0xae, 0x21, 0x6b, 0x0c, 0x60, 0xa4, 0x40, 0xee, 0x1d,
+ /*5bc0:*/ 0x75, 0xfa, 0xd2, 0x0e, 0x21, 0x57, 0x15, 0x87, 0x0c, 0x30, 0x9f, 0x8a, 0x1c, 0xc6, 0xde, 0x93,
+ /*5bd0:*/ 0xb9, 0xc5, 0x3f, 0x48, 0x81, 0x07, 0xc0, 0xcb, 0x2f, 0xd3, 0x79, 0x60, 0x99, 0xab, 0x22, 0xa2,
+ /*5be0:*/ 0xcd, 0xc1, 0x6a, 0x6e, 0x87, 0xdf, 0xf9, 0x32, 0xba, 0x53, 0x25, 0xab, 0x0d, 0x3a, 0xcc, 0x31,
+ /*5bf0:*/ 0x61, 0x0e, 0xa7, 0x16, 0x4b, 0x2e, 0x1d, 0x94, 0xc5, 0x45, 0x80, 0x0c, 0x16, 0x93, 0x7c, 0xfd,
+ /*5c00:*/ 0x1f, 0xa1, 0x01, 0x20, 0xfb, 0xe3, 0x93, 0x92, 0x81, 0x38, 0x78, 0xd2, 0xda, 0xbd, 0xcd, 0xf0,
+ /*5c10:*/ 0xe6, 0x55, 0x6e, 0x33, 0x24, 0x06, 0xcb, 0xf1, 0xb3, 0x14, 0x90, 0x28, 0xe4, 0x33, 0xd7, 0xc8,
+ /*5c20:*/ 0x0d, 0xbb, 0x79, 0xcc, 0xe5, 0x9f, 0xcd, 0x78, 0x99, 0xb4, 0xab, 0xe1, 0x97, 0x30, 0x26, 0x62,
+ /*5c30:*/ 0xbe, 0x36, 0xfe, 0x00, 0x4d, 0xdf, 0x68, 0x50, 0x67, 0x63, 0xb6, 0xe2, 0x3b, 0xef, 0xbe, 0x2f,
+ /*5c40:*/ 0xca, 0xa2, 0xec, 0xc8, 0x79, 0x51, 0x56, 0x8c, 0xae, 0x14, 0xf8, 0xfc, 0x3f, 0x5f, 0x94, 0xdd,
+ /*5c50:*/ 0xb7, 0x0a, 0x1c, 0x79, 0xea, 0x22, 0x73, 0x33, 0x66, 0x7f, 0x4b, 0x0a, 0xb4, 0x51, 0xbd, 0xa7,
+ /*5c60:*/ 0xed, 0x46, 0x8f, 0xf9, 0x86, 0x65, 0x31, 0xfd, 0xf0, 0xdc, 0x2e, 0xee, 0xcf, 0xa7, 0x13, 0x9f,
+ /*5c70:*/ 0x07, 0x78, 0xc6, 0xc6, 0x07, 0x7b, 0x51, 0xda, 0x8f, 0x0b, 0xdb, 0xba, 0xd2, 0xde, 0xc6, 0x63,
+ /*5c80:*/ 0xbe, 0xd5, 0x92, 0xc6, 0xcb, 0xd3, 0xb3, 0xbb, 0x26, 0xe6, 0x10, 0x1f, 0x83, 0x69, 0x0e, 0x0a,
+ /*5c90:*/ 0xeb, 0xd5, 0x35, 0x71, 0xed, 0xa8, 0x77, 0x7a, 0x5a, 0x07, 0xaf, 0xd1, 0x3a, 0x00, 0xf6, 0x83,
+ /*5ca0:*/ 0x7e, 0x0d, 0x6c, 0xed, 0xd8, 0xc6, 0x3c, 0x15, 0x9d, 0xad, 0x5b, 0x1c, 0xb6, 0xfb, 0x4d, 0x89,
+ /*5cb0:*/ 0x0f, 0xa2, 0x8f, 0xf9, 0x3e, 0x48, 0x77, 0xeb, 0xd0, 0x8a, 0x0e, 0xfe, 0xd2, 0x15, 0x38, 0x1e,
+ /*5cc0:*/ 0x9c, 0x08, 0x60, 0xd8, 0xbf, 0x95, 0xb9, 0xe9, 0x5d, 0x6d, 0x7b, 0x8c, 0x86, 0x33, 0xe4, 0xb1,
+ /*5cd0:*/ 0x10, 0xf6, 0x0b, 0x1c, 0x2a, 0xcc, 0xe7, 0x3b, 0xc1, 0x18, 0x14, 0xf5, 0x8b, 0xf4, 0x50, 0x5b,
+ /*5ce0:*/ 0x64, 0x46, 0x8f, 0xc3, 0x70, 0xfb, 0x68, 0xe6, 0x9a, 0x73, 0x4e, 0x23, 0xc6, 0x21, 0x96, 0xf1,
+ /*5cf0:*/ 0x9f, 0xca, 0x75, 0xc4, 0xaf, 0xb2, 0xde, 0xd6, 0xa9, 0x5c, 0xa5, 0x18, 0x5d, 0x84, 0x79, 0xe3,
+ /*5d00:*/ 0xc5, 0xf5, 0x44, 0x5e, 0x63, 0xf0, 0xc8, 0x35, 0x15, 0xe3, 0xff, 0x04, 0x8a, 0x31, 0xd0, 0xee,
+ /*5d10:*/ 0xc6, 0xe4, 0x77, 0x30, 0xb8, 0x77, 0x49, 0x68, 0x1c, 0x33, 0x99, 0x2d, 0x7e, 0xf5, 0x45, 0xa9,
+ /*5d20:*/ 0x13, 0x69, 0xc2, 0xab, 0x3f, 0xea, 0x49, 0x07, 0x4b, 0xc9, 0x9d, 0x8a, 0x1f, 0x41, 0x7f, 0xf7,
+ /*5d30:*/ 0x98, 0x2d, 0x75, 0x11, 0x10, 0x23, 0xb7, 0xab, 0x26, 0x79, 0x04, 0x9c, 0x10, 0x2a, 0x75, 0xef,
+ /*5d40:*/ 0x54, 0xe6, 0xc7, 0xab, 0x2d, 0xe7, 0xb3, 0xf4, 0xdd, 0x9e, 0xb5, 0xda, 0xbd, 0x7b, 0xe9, 0xbd,
+ /*5d50:*/ 0x6b, 0xd8, 0xf3, 0x4b, 0x05, 0x76, 0xdb, 0x03, 0xa4, 0x2b, 0x37, 0x20, 0x8b, 0x3e, 0x2b, 0xa2,
+ /*5d60:*/ 0x18, 0x01, 0x8e, 0xcf, 0xf9, 0x3e, 0x8b, 0xf1, 0x80, 0x24, 0xde, 0x31, 0xd1, 0x81, 0x70, 0xaf,
+ /*5d70:*/ 0x82, 0xd7, 0x58, 0xa8, 0xdc, 0xce, 0x2b, 0x55, 0x44, 0x21, 0x2b, 0xe1, 0xac, 0x0e, 0x23, 0xe7,
+ /*5d80:*/ 0xb2, 0x0b, 0x5e, 0x12, 0x3c, 0x4e, 0x6e, 0x3b, 0xf7, 0xbb, 0xce, 0x72, 0x5a, 0x5d, 0x54, 0xa0,
+ /*5d90:*/ 0xf5, 0x2e, 0xce, 0x9f, 0x76, 0xbf, 0x25, 0xb1, 0xeb, 0x5a, 0xa6, 0x61, 0x7d, 0x98, 0x33, 0x2f,
+ /*5da0:*/ 0x49, 0x3d, 0xec, 0xdf, 0xef, 0xed, 0xa1, 0x90, 0xeb, 0xde, 0xc3, 0x89, 0xd0, 0x04, 0xa7, 0xa0,
+ /*5db0:*/ 0xaa, 0xb3, 0xed, 0x54, 0x13, 0xc4, 0x70, 0x90, 0xfa, 0x2a, 0xfd, 0x24, 0x87, 0xf5, 0x12, 0x82,
+ /*5dc0:*/ 0xf0, 0x39, 0xfd, 0x1a, 0xd5, 0x0f, 0x26, 0x4a, 0xaf, 0x40, 0xb4, 0x2e, 0x3f, 0x9c, 0xa7, 0x35,
+ /*5dd0:*/ 0xcb, 0x5d, 0xf3, 0x21, 0xea, 0xbf, 0xb9, 0x14, 0x01, 0x06, 0x36, 0xcc, 0x06, 0xba, 0xa9, 0x8a,
+ /*5de0:*/ 0x32, 0x22, 0x12, 0x22, 0x19, 0xff, 0x64, 0xd2, 0x33, 0x98, 0x90, 0xb0, 0x57, 0xcb, 0xe7, 0x6a,
+ /*5df0:*/ 0x58, 0xc9, 0x1d, 0x85, 0x08, 0x4e, 0x18, 0x57, 0x4b, 0x20, 0xd6, 0xbe, 0xaa, 0x8c, 0x44, 0xad,
+ /*5e00:*/ 0x83, 0x78, 0xe5, 0x79, 0x72, 0xc6, 0xa8, 0xf1, 0xe5, 0x09, 0x9d, 0x4f, 0x54, 0xd5, 0xb9, 0x7d,
+ /*5e10:*/ 0x5b, 0xe8, 0x9f, 0xb1, 0x45, 0xc2, 0xe3, 0xe3, 0xe2, 0xbf, 0x4d, 0xb4, 0x5b, 0x88, 0x15, 0x70,
+ /*5e20:*/ 0x94, 0xf0, 0xe6, 0x2c, 0x3c, 0x66, 0x15, 0xf2, 0xab, 0xdf, 0x57, 0x74, 0x59, 0x8e, 0x30, 0x0a,
+ /*5e30:*/ 0x52, 0xe0, 0x96, 0x54, 0x84, 0xbd, 0x28, 0x94, 0x80, 0x4d, 0xac, 0x0a, 0xc1, 0xf6, 0x36, 0x8b,
+ /*5e40:*/ 0x7b, 0x11, 0xce, 0x6e, 0x43, 0x50, 0xbc, 0x94, 0x93, 0x96, 0x29, 0xe3, 0xf3, 0x28, 0x1b, 0x88,
+ /*5e50:*/ 0x23, 0xb8, 0x7d, 0x0e, 0xd0, 0xb9, 0x46, 0x81, 0xa1, 0xb3, 0xba, 0xb9, 0x67, 0x48, 0xe6, 0xc5,
+ /*5e60:*/ 0x11, 0x12, 0xa3, 0xaa, 0xf3, 0x1d, 0xe0, 0x64, 0x20, 0x09, 0x31, 0xe4, 0x21, 0xd1, 0xbb, 0x6c,
+ /*5e70:*/ 0x67, 0x83, 0x43, 0xd1, 0x9b, 0x91, 0x3d, 0xdf, 0xea, 0xf3, 0xaf, 0x77, 0x4d, 0x58, 0x16, 0xe8,
+ /*5e80:*/ 0xce, 0xd6, 0x60, 0xaa, 0xa9, 0x40, 0x6d, 0x44, 0xbc, 0xb2, 0x46, 0x27, 0xc3, 0xa3, 0x5c, 0x18,
+ /*5e90:*/ 0xcd, 0xd9, 0xe5, 0xef, 0x91, 0x14, 0x3b, 0xff, 0xb2, 0xbd, 0x65, 0x9a, 0xf8, 0x75, 0x76, 0x7b,
+ /*5ea0:*/ 0x0f, 0xf8, 0xad, 0x0b, 0xbf, 0x4b, 0xdf, 0x2e, 0xa8, 0x45, 0xac, 0x4c, 0x3b, 0xb0, 0x18, 0x8e,
+ /*5eb0:*/ 0xb5, 0x85, 0x23, 0x1b, 0x63, 0xed, 0xaa, 0x09, 0x52, 0xb6, 0x36, 0xe0, 0xb8, 0x15, 0xa8, 0x8b,
+ /*5ec0:*/ 0x51, 0x4c, 0xa3, 0xca, 0x09, 0x3c, 0xec, 0x83, 0x91, 0xfb, 0x4f, 0x3b, 0xc5, 0x35, 0x4c, 0x13,
+ /*5ed0:*/ 0x0a, 0x8f, 0x58, 0xb5, 0x19, 0x29, 0xdd, 0x46, 0x53, 0xbd, 0xf4, 0x15, 0xdf, 0x29, 0xf5, 0xa4,
+ /*5ee0:*/ 0x25, 0x45, 0x85, 0xa3, 0x00, 0x75, 0x4d, 0x38, 0xfb, 0xfe, 0x53, 0xed, 0x1f, 0x14, 0xf2, 0x0e,
+ /*5ef0:*/ 0xb7, 0x40, 0x62, 0x88, 0x92, 0x54, 0x6e, 0xd2, 0xa5, 0x8d, 0x7a, 0x9b, 0x2b, 0xee, 0x74, 0xb0,
+ /*5f00:*/ 0xb0, 0x17, 0x2b, 0xd3, 0x46, 0x6a, 0x3d, 0xcb, 0xdc, 0x93, 0x00, 0xfc, 0xf1, 0x3d, 0x4d, 0x25,
+ /*5f10:*/ 0xe9, 0x8d, 0xdf, 0x8d, 0x0d, 0x4a, 0x3e, 0xcb, 0x58, 0xc2, 0x33, 0x72, 0x0b, 0xd2, 0x8d, 0x55,
+ /*5f20:*/ 0x74, 0x63, 0x66, 0x3f, 0x9b, 0xeb, 0x77, 0x17, 0xb9, 0x18, 0x9c, 0xc8, 0xb7, 0x9b, 0x52, 0x1c,
+ /*5f30:*/ 0xbd, 0xa9, 0xa1, 0x3d, 0x51, 0x7e, 0x9a, 0xf8, 0x94, 0x14, 0xb8, 0x59, 0xec, 0xe2, 0x2f, 0xf6,
+ /*5f40:*/ 0xdd, 0x8a, 0x44, 0x55, 0x72, 0xc8, 0x7b, 0xaf, 0xce, 0xd2, 0x85, 0xb8, 0x71, 0x2d, 0x2e, 0x9e,
+ /*5f50:*/ 0xcb, 0x22, 0xbf, 0xdb, 0xd3, 0x85, 0x08, 0x7c, 0x48, 0x06, 0xd7, 0xbe, 0x5a, 0xa6, 0x5a, 0xe5,
+ /*5f60:*/ 0x83, 0x6f, 0xbc, 0xc2, 0xf0, 0xce, 0xc1, 0x8c, 0x54, 0x5e, 0x01, 0x93, 0xc4, 0x48, 0x62, 0x29,
+ /*5f70:*/ 0xef, 0x74, 0x0a, 0x80, 0xb8, 0x03, 0x61, 0x67, 0x13, 0x38, 0xd5, 0x55, 0x89, 0xc1, 0x51, 0x06,
+ /*5f80:*/ 0x2f, 0xb6, 0x24, 0x34, 0xbe, 0x92, 0xc9, 0x9b, 0xa4, 0xc8, 0x50, 0x50, 0xb4, 0xf3, 0xba, 0xd3,
+ /*5f90:*/ 0x77, 0x18, 0xd1, 0x8d, 0x95, 0x11, 0x48, 0x0d, 0xbc, 0x2b, 0x0f, 0xee, 0x04, 0x6a, 0xd8, 0xa0,
+ /*5fa0:*/ 0x6a, 0xfb, 0x6e, 0xae, 0xac, 0x6c, 0xad, 0x4b, 0x66, 0x61, 0x35, 0x00, 0x29, 0x19, 0x31, 0x7d,
+ /*5fb0:*/ 0x67, 0x58, 0xd0, 0x95, 0x81, 0xfe, 0x31, 0x46, 0x91, 0xd8, 0xac, 0xb4, 0x5e, 0xbf, 0xf3, 0xfc,
+ /*5fc0:*/ 0x4a, 0xcc, 0x67, 0xc6, 0xbf, 0x89, 0xb9, 0x9a, 0x83, 0x3a, 0x6a, 0x00, 0xe3, 0x8e, 0x7f, 0x03,
+ /*5fd0:*/ 0xa2, 0xc6, 0x6e, 0x81, 0x9a, 0xd3, 0xf9, 0x9e, 0xb9, 0xe1, 0x15, 0x01, 0xb3, 0x6d, 0xc4, 0xea,
+ /*5fe0:*/ 0xa1, 0x3a, 0x29, 0x38, 0x64, 0x07, 0xeb, 0x7c, 0x96, 0x3c, 0x05, 0xc9, 0xee, 0x2c, 0x13, 0x91,
+ /*5ff0:*/ 0x30, 0x33, 0x84, 0x01, 0x31, 0xe0, 0xef, 0xe9, 0x31, 0x07, 0x59, 0x9b, 0xca, 0xc2, 0x73, 0xc1,
+ /*6000:*/ 0xbc, 0x1c, 0xd8, 0xc0, 0xce, 0x1d, 0xf4, 0x25, 0x2e, 0x88, 0xa1, 0xc1, 0x48, 0x98, 0x0c, 0xae,
+ /*6010:*/ 0x01, 0x9f, 0xe0, 0x94, 0x38, 0x4f, 0xd0, 0x8c, 0x36, 0x6b, 0x4d, 0xd5, 0x0b, 0x03, 0x8a, 0x5d,
+ /*6020:*/ 0x15, 0x3c, 0x3a, 0x09, 0x32, 0x95, 0xd8, 0xdb, 0x9f, 0xcf, 0x71, 0x67, 0x9b, 0xc6, 0xab, 0x87,
+ /*6030:*/ 0xd4, 0xfe, 0xad, 0xc2, 0xde, 0x17, 0x9c, 0xba, 0x4b, 0x1c, 0x73, 0x69, 0xe4, 0xa5, 0xc1, 0x90,
+ /*6040:*/ 0x2c, 0x25, 0xec, 0x91, 0x2e, 0xd9, 0x18, 0xe5, 0xa4, 0xfb, 0x4d, 0x6b, 0x31, 0x5d, 0xbb, 0xb5,
+ /*6050:*/ 0xb9, 0xe1, 0xdc, 0xf6, 0xcd, 0x88, 0x15, 0xbe, 0x82, 0xf7, 0x7e, 0x74, 0x9f, 0x67, 0x84, 0x38,
+ /*6060:*/ 0x60, 0x25, 0xa6, 0x22, 0x8a, 0xfa, 0xd1, 0x54, 0x9d, 0x4a, 0xab, 0x80, 0x8e, 0xf3, 0x46, 0x92,
+ /*6070:*/ 0x93, 0xd3, 0x56, 0xdf, 0x3c, 0xed, 0xfe, 0x16, 0x90, 0x7f, 0x22, 0xe8, 0xda, 0x79, 0xe3, 0x4d,
+ /*6080:*/ 0x32, 0x34, 0x05, 0xa4, 0x1e, 0xf8, 0xa1, 0xa4, 0x73, 0xe8, 0x3b, 0x94, 0xcc, 0xc5, 0x56, 0x86,
+ /*6090:*/ 0xd5, 0xc5, 0x52, 0x23, 0xf1, 0x3e, 0xbb, 0x73, 0x5f, 0x2e, 0xa4, 0x53, 0x18, 0x1d, 0xeb, 0xbc,
+ /*60a0:*/ 0xab, 0x38, 0x61, 0x83, 0x15, 0xcf, 0xbc, 0xff, 0xb7, 0x3e, 0x43, 0xa7, 0x48, 0x10, 0x64, 0x52,
+ /*60b0:*/ 0x3c, 0xae, 0x7c, 0x8f, 0xf0, 0x21, 0x96, 0x99, 0xc4, 0xc5, 0xaa, 0xfe, 0x96, 0xc0, 0x13, 0xa9,
+ /*60c0:*/ 0x91, 0xe2, 0xb3, 0x6b, 0x52, 0xea, 0x5f, 0xfa, 0xcd, 0xe3, 0x48, 0xd8, 0x8e, 0x8a, 0x8d, 0x8f,
+ /*60d0:*/ 0x89, 0x45, 0xf0, 0xcb, 0xc8, 0xc7, 0x21, 0x44, 0x22, 0xb3, 0xad, 0x68, 0x55, 0xd1, 0x59, 0xa6,
+ /*60e0:*/ 0xd0, 0x7e, 0xb2, 0xd3, 0xf1, 0xd1, 0x0a, 0x25, 0xc2, 0x3f, 0x3b, 0x40, 0x34, 0x03, 0x1e, 0xc3,
+ /*60f0:*/ 0x3c, 0x71, 0x70, 0xf8, 0x3a, 0x6a, 0x9d, 0x7c, 0x46, 0xbb, 0xd7, 0x79, 0x66, 0x6a, 0x3d, 0xb6,
+ /*6100:*/ 0x6f, 0x57, 0xa8, 0x22, 0xf3, 0x1e, 0x8c, 0x91, 0x44, 0x86, 0xa5, 0x91, 0xce, 0x11, 0x14, 0xc0,
+ /*6110:*/ 0x13, 0xaa, 0xaa, 0xbe, 0xb0, 0x7f, 0x2b, 0x6b, 0x12, 0x53, 0x75, 0x82, 0xcb, 0x1b, 0x56, 0xf8,
+ /*6120:*/ 0xc6, 0x1b, 0x83, 0x8c, 0x94, 0xd4, 0xfa, 0x0b, 0x2f, 0x90, 0x0d, 0xf0, 0x05, 0x80, 0xac, 0x2d,
+ /*6130:*/ 0xf2, 0x1c, 0x7a, 0x53, 0xce, 0x2a, 0xd2, 0xc8, 0xd7, 0x0c, 0x84, 0x60, 0xe1, 0x4d, 0xb1, 0x75,
+ /*6140:*/ 0x56, 0xc8, 0xf8, 0xab, 0x4d, 0x49, 0x16, 0x87, 0x41, 0x71, 0x1b, 0x0f, 0xed, 0x3a, 0xa6, 0xe4,
+ /*6150:*/ 0x92, 0x9e, 0xe7, 0xad, 0xb5, 0xb3, 0x0c, 0xa1, 0x7d, 0x00, 0x3d, 0x54, 0x11, 0xc6, 0x34, 0xb8,
+ /*6160:*/ 0x87, 0x2a, 0xb7, 0xf7, 0x56, 0xd1, 0x3e, 0x18, 0xa1, 0xcc, 0xc0, 0x71, 0x5d, 0xe3, 0x66, 0xf0,
+ /*6170:*/ 0xea, 0x05, 0xa4, 0xe2, 0x55, 0x77, 0x8c, 0x5c, 0xa5, 0xca, 0xb1, 0xae, 0xf4, 0x0f, 0xb3, 0x9d,
+ /*6180:*/ 0xb8, 0x0f, 0x1e, 0x0f, 0x8e, 0x5e, 0xbb, 0x0e, 0x26, 0x5e, 0x3a, 0xdc, 0xca, 0xb5, 0xa2, 0xad,
+ /*6190:*/ 0x1d, 0xfe, 0x65, 0x89, 0x4e, 0x67, 0x8c, 0xe3, 0xc6, 0x61, 0x0f, 0x28, 0x8c, 0x7a, 0xf0, 0x18,
+ /*61a0:*/ 0x26, 0xbd, 0x05, 0x5f, 0x08, 0xba, 0x7b, 0x76, 0xb3, 0xc0, 0x76, 0x52, 0xfe, 0xda, 0x9b, 0x79,
+ /*61b0:*/ 0xb9, 0x2b, 0x12, 0x05, 0xdf, 0x3f, 0xa3, 0x92, 0xff, 0x2f, 0x82, 0x65, 0x0c, 0xe6, 0x10, 0x26,
+ /*61c0:*/ 0x20, 0x3a, 0xbf, 0x49, 0x70, 0x40, 0x94, 0xd3, 0xc2, 0xd9, 0xf1, 0x66, 0xc4, 0x79, 0x57, 0xe6,
+ /*61d0:*/ 0xcd, 0x93, 0xd8, 0xc7, 0x21, 0xd0, 0x4d, 0x71, 0x39, 0x4c, 0xaf, 0xdf, 0xb8, 0x34, 0xa7, 0xdc,
+ /*61e0:*/ 0x94, 0x78, 0x2e, 0x1a, 0x6c, 0x1b, 0xb6, 0xe7, 0x18, 0x45, 0xb7, 0x05, 0xe9, 0x12, 0x20, 0x95,
+ /*61f0:*/ 0xa2, 0x6c, 0x35, 0x27, 0xaf, 0xdf, 0xed, 0x1f, 0x70, 0xd5, 0x74, 0x44, 0x65, 0x54, 0x38, 0x12,
+ /*6200:*/ 0x9c, 0xe8, 0x59, 0x3f, 0x9a, 0x07, 0x44, 0x32, 0xa7, 0x4b, 0x0a, 0xe5, 0x1d, 0x08, 0x82, 0x86,
+ /*6210:*/ 0xcf, 0x99, 0x47, 0x8d, 0xb4, 0x29, 0xa4, 0x96, 0x3f, 0x65, 0x8e, 0xaf, 0xb4, 0x44, 0xe9, 0x69,
+ /*6220:*/ 0x1e, 0xe8, 0xc8, 0xcb, 0x67, 0xd9, 0x78, 0x2e, 0xbb, 0x11, 0x72, 0xed, 0x4f, 0xe5, 0x95, 0xad,
+ /*6230:*/ 0x13, 0xc9, 0x68, 0x0c, 0x0e, 0xe4, 0xde, 0xcf, 0xb1, 0x65, 0xc5, 0x36, 0xe9, 0xeb, 0x25, 0xe7,
+ /*6240:*/ 0xdf, 0xe5, 0x02, 0x09, 0x31, 0x37, 0x99, 0x7a, 0xe3, 0xe5, 0x34, 0xf6, 0xea, 0x6e, 0xcc, 0x39,
+ /*6250:*/ 0x64, 0xbe, 0xb3, 0xd3, 0x0f, 0xf2, 0x7e, 0x18, 0xba, 0x53, 0x35, 0x19, 0x3f, 0x9f, 0x5a, 0x80,
+ /*6260:*/ 0x2a, 0xbb, 0x7e, 0x92, 0x31, 0xfd, 0x2a, 0x66, 0xee, 0x54, 0xd0, 0x32, 0xa3, 0x53, 0x2d, 0xfc,
+ /*6270:*/ 0xf5, 0x59, 0x13, 0xe1, 0xb0, 0xe9, 0x31, 0x07, 0x19, 0xe5, 0x08, 0x8e, 0x24, 0x87, 0x39, 0x8b,
+ /*6280:*/ 0xb2, 0xa8, 0xde, 0x81, 0xaa, 0x47, 0x5b, 0x9a, 0x41, 0xd5, 0xda, 0xb9, 0x61, 0x59, 0x4f, 0x30,
+ /*6290:*/ 0x25, 0xa3, 0x56, 0x4f, 0x9b, 0x9e, 0x63, 0x96, 0x75, 0xba, 0xfd, 0xf0, 0x4b, 0x64, 0x73, 0xbb,
+ /*62a0:*/ 0xa2, 0x96, 0x5b, 0xbf, 0xce, 0xc3, 0xa1, 0xa8, 0x90, 0xc9, 0x19, 0xf7, 0xb1, 0x82, 0xb7, 0xcc,
+ /*62b0:*/ 0xb1, 0x57, 0xa0, 0x13, 0x7c, 0x60, 0x34, 0x32, 0x65, 0xba, 0xf2, 0x5f, 0x41, 0xdc, 0x00, 0xd1,
+ /*62c0:*/ 0x5a, 0x38, 0xb6, 0x4f, 0x4d, 0xec, 0x18, 0x31, 0xc3, 0x8b, 0xaa, 0x06, 0xda, 0x2f, 0x2e, 0x7c,
+ /*62d0:*/ 0x2b, 0x57, 0x29, 0x81, 0x43, 0xb2, 0xca, 0xb9, 0x61, 0x2c, 0x94, 0x5e, 0x8e, 0xa2, 0x33, 0x80,
+ /*62e0:*/ 0x0a, 0x4b, 0x58, 0xa7, 0x1c, 0xf7, 0x0d, 0xc0, 0x1a, 0x61, 0x14, 0xf8, 0x82, 0x57, 0x5b, 0x0d,
+ /*62f0:*/ 0x17, 0x71, 0x8d, 0xf9, 0x42, 0x9a, 0x41, 0x1f, 0x84, 0x98, 0xcb, 0x38, 0x25, 0x4a, 0xb9, 0x0a,
+ /*6300:*/ 0xf1, 0xfc, 0x94, 0x14, 0x21, 0x51, 0xe3, 0xe5, 0x1a, 0xd9, 0x70, 0x31, 0x1a, 0x84, 0xaf, 0x08,
+ /*6310:*/ 0x20, 0x9f, 0x96, 0x61, 0x84, 0xf5, 0xfb, 0xfc, 0x4f, 0xf0, 0xb7, 0xcc, 0xef, 0x99, 0xb9, 0x6d,
+ /*6320:*/ 0x95, 0x11, 0x57, 0x20, 0x62, 0x62, 0xa8, 0xfb, 0xec, 0xf1, 0x0f, 0xcc, 0xc9, 0xf0, 0x63, 0xb8,
+ /*6330:*/ 0x59, 0xa4, 0xf8, 0xb0, 0xfd, 0xf6, 0xe2, 0x61, 0x45, 0x9b, 0xb4, 0x18, 0xf5, 0xe5, 0x9f, 0x3e,
+ /*6340:*/ 0x97, 0xe7, 0x3f, 0x08, 0xf7, 0x63, 0x9b, 0x71, 0x4f, 0x06, 0x95, 0x66, 0xa7, 0x2e, 0xa1, 0xa3,
+ /*6350:*/ 0xef, 0x22, 0xf7, 0x82, 0x00, 0xf8, 0xc6, 0x04, 0x03, 0xf6, 0x90, 0x4d, 0xd2, 0xe7, 0xb2, 0xda,
+ /*6360:*/ 0xeb, 0x4b, 0xff, 0x40, 0x33, 0x28, 0xed, 0x33, 0x81, 0x9e, 0xfa, 0x18, 0x43, 0xac, 0x82, 0x99,
+ /*6370:*/ 0x09, 0xa5, 0x7c, 0xd7, 0xc0, 0xf2, 0x9a, 0xeb, 0xb4, 0xb6, 0x18, 0x9a, 0x9c, 0x8e, 0x5e, 0xed,
+ /*6380:*/ 0x49, 0x18, 0xb6, 0x14, 0x74, 0x3b, 0x19, 0x2d, 0xa0, 0xdf, 0xc0, 0xa3, 0x56, 0x6b, 0x17, 0x80,
+ /*6390:*/ 0x40, 0x36, 0x2f, 0x5b, 0xf8, 0xc0, 0x39, 0x0b, 0x64, 0x73, 0x31, 0x15, 0x0f, 0x54, 0x3d, 0x52,
+ /*63a0:*/ 0x39, 0x99, 0xe3, 0x37, 0xaf, 0xae, 0xaa, 0xf2, 0x1e, 0xc4, 0x53, 0x41, 0xa8, 0x41, 0x82, 0x5c,
+ /*63b0:*/ 0xde, 0x4a, 0xef, 0xa9, 0x4b, 0x31, 0xfe, 0xdb, 0x5a, 0x2d, 0x55, 0xa2, 0x5a, 0x84, 0xda, 0xfc,
+ /*63c0:*/ 0x47, 0xbc, 0x8c, 0x5f, 0x6c, 0x30, 0x6f, 0xb7, 0xb0, 0x57, 0xe2, 0xe3, 0x30, 0x75, 0xae, 0x9d,
+ /*63d0:*/ 0x78, 0xd5, 0x98, 0x44, 0xee, 0x86, 0x44, 0x3c, 0xfd, 0x18, 0x0d, 0x5c, 0x16, 0x86, 0x04, 0xdb,
+ /*63e0:*/ 0x8a, 0xda, 0x0c, 0x37, 0xef, 0xb1, 0xea, 0xe5, 0x7c, 0x10, 0x6a, 0x17, 0x01, 0xd4, 0x44, 0x4e,
+ /*63f0:*/ 0xf3, 0xb3, 0x47, 0xce, 0x10, 0x78, 0x6e, 0x69, 0x98, 0x3e, 0x61, 0x21, 0xde, 0x65, 0x50, 0xb4,
+ /*6400:*/ 0x2e, 0x08, 0x08, 0x6b, 0xef, 0x25, 0x1b, 0x9d, 0x68, 0xee, 0xd0, 0xce, 0xd5, 0x36, 0xb0, 0xcd,
+ /*6410:*/ 0x4e, 0x0c, 0x19, 0x59, 0x57, 0xd8, 0xa1, 0x69, 0xe5, 0x1f, 0xba, 0x8d, 0x28, 0xa4, 0xe0, 0x56,
+ /*6420:*/ 0xdf, 0xab, 0xd0, 0x2a, 0x27, 0x60, 0xd3, 0xa1, 0x69, 0xbb, 0x77, 0xe5, 0xef, 0xa8, 0x99, 0xb4,
+ /*6430:*/ 0x3f, 0xc1, 0x09, 0x72, 0x69, 0xe9, 0x73, 0x5b, 0x59, 0x48, 0x4c, 0x1d, 0x9d, 0x73, 0xb6, 0x8e,
+ /*6440:*/ 0x2a, 0x66, 0x7e, 0xf5, 0xaf, 0x12, 0x69, 0xcf, 0x61, 0xbd, 0xd3, 0x84, 0xd3, 0x3a, 0xe4, 0xbf,
+ /*6450:*/ 0x7f, 0xeb, 0x21, 0x59, 0x72, 0x7c, 0xa6, 0x89, 0x6b, 0x2e, 0xc9, 0x46, 0xa8, 0x05, 0xc9, 0xf9,
+ /*6460:*/ 0x7a, 0x25, 0x27, 0xb8, 0xda, 0x80, 0xf6, 0xa7, 0x69, 0x28, 0x06, 0x5d, 0x8e, 0xa6, 0x0d, 0x3c,
+ /*6470:*/ 0x7b, 0x2a, 0xce, 0x1a, 0x13, 0x53, 0x98, 0x85, 0x1f, 0xc9, 0xce, 0xd0, 0xd4, 0x76, 0x6d, 0x6e,
+ /*6480:*/ 0xa9, 0x4e, 0x5a, 0x44, 0xc2, 0xb4, 0x6f, 0x5e, 0xe8, 0x8c, 0x88, 0xfb, 0xe2, 0x1e, 0x4b, 0x1a,
+ /*6490:*/ 0xa9, 0x55, 0x09, 0x70, 0x73, 0xf9, 0x4f, 0xd4, 0x4a, 0x53, 0xaa, 0x7e, 0x67, 0xe5, 0x61, 0x13,
+ /*64a0:*/ 0x53, 0xfc, 0xef, 0xe6, 0x82, 0x6a, 0xdf, 0x82, 0x87, 0x93, 0x8f, 0x85, 0x7a, 0x8e, 0x7a, 0xb9,
+ /*64b0:*/ 0xd8, 0xf9, 0xac, 0x79, 0x2c, 0x87, 0x9f, 0x40, 0x9a, 0xe3, 0x8b, 0xbd, 0x15, 0xaf, 0x70, 0xfb,
+ /*64c0:*/ 0x7f, 0x80, 0x74, 0x6c, 0x94, 0x02, 0x0d, 0xd2, 0x41, 0x7f, 0xe2, 0x38, 0xcb, 0xfe, 0x99, 0xef,
+ /*64d0:*/ 0xd7, 0x0e, 0x74, 0x93, 0x66, 0xae, 0xa7, 0x10, 0x42, 0x10, 0xf6, 0x77, 0x5e, 0x16, 0xe7, 0x4c,
+ /*64e0:*/ 0x41, 0x51, 0xc8, 0x80, 0x6c, 0xaf, 0xb9, 0xb6, 0x91, 0x17, 0xb3, 0xba, 0x00, 0x07, 0xe4, 0xd1,
+ /*64f0:*/ 0x89, 0x05, 0x31, 0xc9, 0x6c, 0x5a, 0x8f, 0x4c, 0xd2, 0x03, 0xe7, 0x79, 0x65, 0xfb, 0x6a, 0x60,
+ /*6500:*/ 0x6c, 0x1d, 0x88, 0x94, 0xf3, 0xc0, 0x15, 0xd0, 0xc3, 0xad, 0x93, 0x81, 0xee, 0x3e, 0x48, 0x9b,
+ /*6510:*/ 0xa7, 0xe8, 0x9b, 0x26, 0x55, 0x97, 0xcd, 0x15, 0xc1, 0xf0, 0x97, 0xb0, 0x47, 0x42, 0xba, 0xea,
+ /*6520:*/ 0x04, 0x2e, 0x31, 0xf8, 0xb3, 0xf5, 0xcb, 0xa4, 0xec, 0xf5, 0x59, 0xe4, 0x8f, 0x03, 0x69, 0x85,
+ /*6530:*/ 0x94, 0x55, 0x00, 0xeb, 0xa5, 0x15, 0xca, 0xe2, 0xac, 0xc7, 0xfb, 0x79, 0x23, 0xbc, 0x60, 0x2b,
+ /*6540:*/ 0x87, 0xcc, 0x55, 0xc5, 0xe8, 0x79, 0xd0, 0x1e, 0x4b, 0xde, 0xf6, 0xf0, 0x26, 0x87, 0x88, 0x29,
+ /*6550:*/ 0xf4, 0x78, 0x77, 0x42, 0xaf, 0x38, 0x53, 0xc4, 0x91, 0x7b, 0xf0, 0x2d, 0x12, 0x2d, 0xa3, 0x15,
+ /*6560:*/ 0xaf, 0x2d, 0x0d, 0xd1, 0xc5, 0x07, 0x55, 0x03, 0x8c, 0x1a, 0x51, 0x5d, 0x1c, 0xcb, 0xd2, 0xd5,
+ /*6570:*/ 0x6a, 0x9b, 0x6e, 0x48, 0x35, 0x7d, 0xd0, 0xc0, 0x45, 0x8f, 0x14, 0xca, 0x74, 0x9f, 0x84, 0xf8,
+ /*6580:*/ 0xd3, 0xd3, 0xe6, 0x14, 0x66, 0xc6, 0x8c, 0xde, 0x3b, 0x54, 0x33, 0x69, 0x20, 0x23, 0x60, 0x3d,
+ /*6590:*/ 0xc4, 0xd5, 0x7c, 0xc6, 0xa9, 0xd9, 0xf0, 0xbd, 0x4b, 0xbd, 0x0d, 0x5c, 0xea, 0x74, 0x0a, 0x6a,
+ /*65a0:*/ 0x17, 0x0d, 0x71, 0xfd, 0x9b, 0xa9, 0x0a, 0x1c, 0x80, 0xf6, 0x2a, 0xd9, 0xf7, 0x2f, 0x1b, 0x41,
+ /*65b0:*/ 0x06, 0x09, 0x10, 0x95, 0xfc, 0xbd, 0xe4, 0x81, 0x54, 0x47, 0x0e, 0xfd, 0xca, 0xe5, 0x6f, 0x49,
+ /*65c0:*/ 0x39, 0xe7, 0xb4, 0xea, 0x75, 0x3c, 0x02, 0x76, 0xb5, 0xa8, 0x0e, 0x4b, 0x81, 0x2d, 0xbc, 0x9d,
+ /*65d0:*/ 0xc9, 0x88, 0xea, 0x8f, 0xde, 0x8d, 0xdb, 0x69, 0x91, 0x6b, 0x30, 0xbf, 0xdb, 0x43, 0x57, 0xa3,
+ /*65e0:*/ 0xd2, 0xde, 0x8b, 0x8e, 0xaa, 0xc0, 0x46, 0xb5, 0x09, 0x61, 0xfd, 0x92, 0x11, 0x78, 0x73, 0xed,
+ /*65f0:*/ 0x89, 0xa3, 0xf9, 0x33, 0xd8, 0x5f, 0xbe, 0x1c, 0x82, 0x6c, 0xd1, 0xd0, 0x58, 0xb5, 0x72, 0x43,
+ /*6600:*/ 0x37, 0xd6, 0xca, 0x98, 0x30, 0x9c, 0x29, 0xae, 0x11, 0x14, 0x73, 0x17, 0x6d, 0x10, 0xea, 0xa6,
+ /*6610:*/ 0x2d, 0xf3, 0x1b, 0xe4, 0xd2, 0xba, 0x01, 0x52, 0x4b, 0xe9, 0x54, 0xb5, 0x3f, 0x9c, 0xb4, 0x9e,
+ /*6620:*/ 0xac, 0xe0, 0x93, 0x6d, 0xdc, 0x1d, 0xfa, 0xf7, 0x04, 0x8f, 0x4a, 0x7e, 0x97, 0xf3, 0x01, 0x38,
+ /*6630:*/ 0x2f, 0xa2, 0x3d, 0xcf, 0xd1, 0x4c, 0x6c, 0x57, 0xb5, 0x8e, 0xb3, 0x59, 0xdd, 0x84, 0x8c, 0x1a,
+ /*6640:*/ 0xaa, 0xc4, 0x9a, 0x6d, 0x7d, 0xd2, 0xf3, 0x5f, 0x60, 0x2d, 0xd3, 0xc3, 0xdb, 0x3c, 0xef, 0xea,
+ /*6650:*/ 0x0c, 0x99, 0x3a, 0xd0, 0xb5, 0xbb, 0xda, 0xcc, 0x35, 0xce, 0x81, 0xc1, 0x15, 0x61, 0x2d, 0x7c,
+ /*6660:*/ 0x20, 0xb1, 0x2a, 0x4c, 0x19, 0x79, 0xff, 0xe7, 0xfd, 0xa2, 0x7c, 0xd4, 0x81, 0xef, 0xd6, 0xc7,
+ /*6670:*/ 0x89, 0xfd, 0x67, 0x8f, 0xa0, 0x64, 0xb9, 0x84, 0x68, 0x87, 0xa2, 0x7d, 0x21, 0xa9, 0xd4, 0x28,
+ /*6680:*/ 0x89, 0x0d, 0x62, 0x08, 0x25, 0xb6, 0x41, 0x9f, 0x0c, 0x3b, 0xdf, 0x0d, 0x86, 0x9c, 0xbd, 0x16,
+ /*6690:*/ 0x6f, 0x03, 0x1b, 0xd8, 0x1c, 0x00, 0x91, 0x14, 0xc1, 0x3a, 0x45, 0x96, 0xa4, 0x4c, 0xa3, 0x27,
+ /*66a0:*/ 0x31, 0x4d, 0xf7, 0x8b, 0x69, 0xdc, 0xab, 0x4e, 0x91, 0xb7, 0x68, 0x46, 0x52, 0x04, 0xb4, 0xf0,
+ /*66b0:*/ 0xa3, 0x7d, 0xf2, 0xa3, 0x14, 0xb4, 0x12, 0xda, 0xa1, 0xb4, 0xa9, 0x6b, 0x22, 0x49, 0x0c, 0xaa,
+ /*66c0:*/ 0x1a, 0x95, 0x57, 0x4c, 0x6c, 0x0b, 0x72, 0x36, 0xf9, 0x02, 0x41, 0x17, 0xc9, 0x70, 0x7e, 0x10,
+ /*66d0:*/ 0xce, 0x4c, 0xd2, 0xa0, 0x46, 0xac, 0x64, 0x5a, 0x53, 0x12, 0x5a, 0xd1, 0x4b, 0x5c, 0x87, 0xa0,
+ /*66e0:*/ 0xb6, 0xc9, 0xf5, 0x6e, 0xa2, 0xbb, 0x3b, 0x6c, 0x55, 0x67, 0x73, 0xe2, 0x01, 0x5d, 0xac, 0x26,
+ /*66f0:*/ 0xad, 0x79, 0xc4, 0x56, 0x2c, 0x33, 0x66, 0x7b, 0xb9, 0xdf, 0x4f, 0x9e, 0xe5, 0x13, 0xb8, 0xf0,
+ /*6700:*/ 0x70, 0x53, 0x59, 0xa0, 0xc2, 0x74, 0xc5, 0xeb, 0x76, 0x4e, 0x1c, 0x0d, 0xfe, 0x98, 0x05, 0x57,
+ /*6710:*/ 0xd5, 0xbe, 0x81, 0xb2, 0x67, 0x0a, 0xcc, 0xde, 0xc1, 0x4e, 0x07, 0x80, 0x34, 0xee, 0x20, 0x93,
+ /*6720:*/ 0xbd, 0xc1, 0xd6, 0x72, 0x47, 0x17, 0xe0, 0x27, 0x90, 0xca, 0x97, 0x0e, 0x0f, 0x6c, 0xcc, 0xe2,
+ /*6730:*/ 0x97, 0x47, 0x49, 0x0c, 0x73, 0xaf, 0x47, 0x8d, 0x8a, 0x2a, 0x6e, 0xfb, 0x79, 0x81, 0xe2, 0xc8,
+ /*6740:*/ 0x97, 0x9f, 0x7e, 0x9b, 0xf4, 0x9a, 0x8f, 0x10, 0x75, 0x23, 0x4a, 0xb9, 0xbd, 0x0d, 0x25, 0xa1,
+ /*6750:*/ 0x50, 0xdf, 0x40, 0x23, 0xbf, 0x1c, 0x83, 0xcd, 0x4c, 0xb7, 0xa3, 0x51, 0x7f, 0xca, 0x44, 0x23,
+ /*6760:*/ 0xbe, 0xd8, 0x74, 0x8a, 0x4c, 0xb3, 0x72, 0x93, 0xaa, 0x9a, 0x32, 0x11, 0xc1, 0x4b, 0x9b, 0x96,
+ /*6770:*/ 0x88, 0x61, 0xc7, 0x22, 0xa3, 0x6c, 0x28, 0xf1, 0x17, 0xa5, 0x02, 0x5e, 0x6d, 0x71, 0x44, 0xe7,
+ /*6780:*/ 0xa6, 0x63, 0x9e, 0xee, 0xc6, 0xef, 0xc0, 0x18, 0xf8, 0xea, 0xf8, 0x78, 0x73, 0x8f, 0xae, 0xed,
+ /*6790:*/ 0xb3, 0x5b, 0x80, 0x12, 0x5b, 0x47, 0x48, 0x54, 0x3a, 0xf3, 0xaf, 0x37, 0x14, 0xc3, 0x8c, 0x09,
+ /*67a0:*/ 0x1e, 0x11, 0xb5, 0xc2, 0x82, 0xef, 0x31, 0x36, 0xe6, 0x73, 0xbe, 0xea, 0x98, 0x4f, 0x14, 0x17,
+ /*67b0:*/ 0x1d, 0xbb, 0x89, 0xba, 0x95, 0xf6, 0x79, 0xa9, 0x71, 0xc0, 0x47, 0xf1, 0x86, 0x18, 0x7c, 0x74,
+ /*67c0:*/ 0x18, 0x27, 0xb7, 0x28, 0x27, 0xf6, 0x2a, 0x4a, 0xcc, 0x8e, 0x7a, 0x0f, 0x90, 0x65, 0x9a, 0xc0,
+ /*67d0:*/ 0xd1, 0xba, 0xf3, 0xd8, 0x49, 0x6a, 0x88, 0x68, 0x41, 0xaa, 0xb9, 0x28, 0xfe, 0x4f, 0xe4, 0x3e,
+ /*67e0:*/ 0x1b, 0xc8, 0xa2, 0x0f, 0x38, 0x8d, 0x7b, 0x63, 0xee, 0x46, 0xbd, 0xa2, 0x75, 0xb3, 0x27, 0x35,
+ /*67f0:*/ 0x72, 0xa7, 0xd4, 0xdd, 0xea, 0xdb, 0xb6, 0x1a, 0x65, 0x39, 0xce, 0xc3, 0x83, 0x65, 0x2d, 0x83,
+ /*6800:*/ 0xb0, 0xf1, 0xd9, 0xa1, 0xb0, 0x48, 0x0f, 0x55, 0x48, 0x3b, 0x78, 0x98, 0xc9, 0x3a, 0x93, 0xbc,
+ /*6810:*/ 0xdb, 0x43, 0x32, 0x27, 0xf6, 0xba, 0xb7, 0xb7, 0x99, 0x11, 0x04, 0xa9, 0x4f, 0x8f, 0x89, 0x30,
+ /*6820:*/ 0x19, 0xad, 0x0d, 0x30, 0xfd, 0x02, 0xfa, 0x87, 0x73, 0xc1, 0x18, 0x07, 0x51, 0x54, 0x1b, 0xdf,
+ /*6830:*/ 0xae, 0xfd, 0x6f, 0x62, 0x23, 0x0b, 0x7b, 0xfb, 0x8a, 0xf8, 0x2b, 0xcc, 0x69, 0x0e, 0x56, 0x6d,
+ /*6840:*/ 0x35, 0x9d, 0xbd, 0x71, 0x51, 0xa7, 0xd9, 0xeb, 0x34, 0x9a, 0x95, 0x9d, 0x52, 0x71, 0x3e, 0x04,
+ /*6850:*/ 0x9f, 0x20, 0xfb, 0xf8, 0x6a, 0xf7, 0x7d, 0x3e, 0x1f, 0xeb, 0x71, 0xe4, 0xf1, 0xbf, 0xb8, 0xb9,
+ /*6860:*/ 0x62, 0x70, 0x84, 0x87, 0xdc, 0x9e, 0xaf, 0x21, 0xd7, 0xa3, 0x58, 0x03, 0x90, 0x9e, 0xcb, 0x9f,
+ /*6870:*/ 0x5d, 0x48, 0xfb, 0xb7, 0xa6, 0x0e, 0x94, 0xb2, 0xaa, 0x4a, 0xb5, 0x7e, 0xfc, 0x6b, 0xd1, 0x59,
+ /*6880:*/ 0x80, 0xec, 0xb0, 0x91, 0x68, 0x62, 0xd1, 0x93, 0x25, 0x70, 0xf7, 0x47, 0x31, 0x69, 0xc9, 0x05,
+ /*6890:*/ 0x31, 0x5b, 0x97, 0x48, 0x28, 0xee, 0xb0, 0x77, 0xac, 0x56, 0xde, 0xb0, 0x5f, 0x14, 0x19, 0x58,
+ /*68a0:*/ 0x1f, 0xd1, 0x31, 0xf6, 0x02, 0xcb, 0x81, 0x6a, 0xac, 0x57, 0x62, 0xea, 0xb9, 0xf0, 0x8f, 0xfd,
+ /*68b0:*/ 0x78, 0xbf, 0xbc, 0x3b, 0xf2, 0x41, 0x2c, 0xff, 0x6e, 0x83, 0x5d, 0xde, 0x22, 0x7b, 0x48, 0x65,
+ /*68c0:*/ 0xac, 0x72, 0xce, 0x12, 0xcf, 0x0c, 0x27, 0x9b, 0xd5, 0x8d, 0xf3, 0x32, 0x1a, 0x4f, 0x67, 0xa6,
+ /*68d0:*/ 0xeb, 0x6a, 0x4c, 0xc8, 0x81, 0x35, 0xd0, 0x22, 0x75, 0xc9, 0xd1, 0x29, 0x8e, 0x42, 0x73, 0x99,
+ /*68e0:*/ 0xdd, 0x50, 0x7e, 0x3c, 0xcb, 0x5f, 0xca, 0xbf, 0x8d, 0x66, 0x13, 0x0e, 0x19, 0x01, 0x58, 0x2d,
+ /*68f0:*/ 0x16, 0x91, 0xb4, 0x40, 0xba, 0xed, 0x9a, 0x02, 0x04, 0xa3, 0x82, 0x14, 0x9d, 0x8b, 0xcc, 0xd5,
+ /*6900:*/ 0xf5, 0x6f, 0x78, 0x60, 0xe5, 0x8b, 0x06, 0xc7, 0xf0, 0xb0, 0x5d, 0xd7, 0x2e, 0x0f, 0xa0, 0x6b,
+ /*6910:*/ 0x39, 0xcd, 0xb4, 0x2a, 0x2d, 0x81, 0x97, 0xa1, 0xab, 0x07, 0x8c, 0x7e, 0xbc, 0x68, 0x13, 0x38,
+ /*6920:*/ 0x85, 0x0a, 0x88, 0x17, 0xf3, 0xba, 0xbf, 0x58, 0x9c, 0xbe, 0x43, 0x3d, 0x36, 0xc3, 0x92, 0x8c,
+ /*6930:*/ 0x31, 0x90, 0xe3, 0x05, 0x3f, 0x6a, 0x25, 0x6e, 0x65, 0xd7, 0x62, 0x60, 0x6e, 0x79, 0x02, 0x62,
+ /*6940:*/ 0xec, 0xd5, 0x9b, 0x99, 0xe4, 0x30, 0xd8, 0xf1, 0x99, 0x45, 0x9d, 0xfb, 0x62, 0x5a, 0x3f, 0x3e,
+ /*6950:*/ 0x2d, 0x75, 0x94, 0x5c, 0x04, 0x31, 0xc0, 0x56, 0xeb, 0x37, 0x29, 0x60, 0x3c, 0x29, 0x63, 0x54,
+ /*6960:*/ 0x24, 0x1f, 0x34, 0xd3, 0x81, 0x5c, 0x2b, 0x07, 0x78, 0x6a, 0xab, 0x85, 0x02, 0x50, 0xd3, 0x0f,
+ /*6970:*/ 0x0f, 0x94, 0x3b, 0x33, 0x9a, 0xcc, 0x99, 0xad, 0xcc, 0xfc, 0xa3, 0xdf, 0xc9, 0xe7, 0x90, 0xb7,
+ /*6980:*/ 0xc1, 0x76, 0xb5, 0x01, 0x66, 0xa1, 0x33, 0x38, 0x26, 0xa6, 0xbb, 0xff, 0xaf, 0x10, 0x27, 0x0a,
+ /*6990:*/ 0x96, 0x6b, 0x1d, 0x74, 0xb1, 0x7d, 0xa9, 0x17, 0x5c, 0x4f, 0x2d, 0x2e, 0x69, 0xaa, 0xb6, 0x4f,
+ /*69a0:*/ 0x95, 0xa7, 0x90, 0xcd, 0x1b, 0x60, 0xb0, 0x68, 0x93, 0x91, 0xba, 0x34, 0xa8, 0x2d, 0xe4, 0xfe,
+ /*69b0:*/ 0xa0, 0x8b, 0x9e, 0x82, 0x77, 0x7a, 0xe3, 0x32, 0xc1, 0x8c, 0x50, 0xdf, 0x49, 0x5f, 0x57, 0xd4,
+ /*69c0:*/ 0x55, 0xe4, 0x25, 0xf0, 0x07, 0x91, 0xaa, 0x77, 0x9b, 0xf9, 0x99, 0xfb, 0x98, 0xd0, 0x01, 0xf8,
+ /*69d0:*/ 0x6b, 0x14, 0xd3, 0xc1, 0x2d, 0xcb, 0x3e, 0xb7, 0xd5, 0xe8, 0x61, 0x20, 0xbd, 0xa5, 0xe3, 0xe0,
+ /*69e0:*/ 0x11, 0x6e, 0x3b, 0xe5, 0x6e, 0xe0, 0xdc, 0x2f, 0x4c, 0x8b, 0x14, 0xa7, 0x08, 0x93, 0xcd, 0xf3,
+ /*69f0:*/ 0x5c, 0x8e, 0x30, 0xab, 0x09, 0x36, 0x70, 0xe9, 0x0c, 0x09, 0x93, 0x45, 0xad, 0x2a, 0x6c, 0xdf,
+ /*6a00:*/ 0x30, 0xe9, 0x50, 0xae, 0x8b, 0x94, 0x5f, 0x20, 0x52, 0xf1, 0x91, 0x22, 0x07, 0xb6, 0x3a, 0x14,
+ /*6a10:*/ 0xa1, 0x33, 0x78, 0x80, 0xa6, 0x49, 0x08, 0xbf, 0xfc, 0xc2, 0x4c, 0x49, 0xee, 0x93, 0x33, 0x77,
+ /*6a20:*/ 0xfd, 0x7d, 0xb6, 0x3d, 0x23, 0x8f, 0x5a, 0x90, 0xa0, 0xe0, 0x3c, 0xc9, 0x93, 0x97, 0x00, 0x16,
+ /*6a30:*/ 0xc2, 0xeb, 0x9b, 0xfa, 0x24, 0x04, 0xc7, 0x9e, 0x46, 0xbf, 0x14, 0xa7, 0x97, 0x03, 0x5d, 0x25,
+ /*6a40:*/ 0x08, 0xb2, 0xf4, 0xa0, 0x1e, 0xe5, 0x47, 0x36, 0x64, 0x7e, 0xab, 0x5d, 0xa8, 0x04, 0x18, 0x84,
+ /*6a50:*/ 0x8e, 0x3d, 0x96, 0xa8, 0xc9, 0xfb, 0xe0, 0x1f, 0x8d, 0xa8, 0x77, 0x73, 0xe5, 0x6c, 0xcf, 0xbf,
+ /*6a60:*/ 0x65, 0x9c, 0x73, 0x73, 0xed, 0x36, 0x18, 0xbd, 0xcb, 0xd0, 0xb2, 0x87, 0xea, 0x0a, 0x18, 0xf5,
+ /*6a70:*/ 0x7c, 0x0f, 0xf7, 0x6b, 0x35, 0x4f, 0xd9, 0x07, 0x8a, 0xa1, 0xa4, 0x21, 0x40, 0x81, 0x75, 0xff,
+ /*6a80:*/ 0x73, 0xeb, 0xcb, 0xda, 0x30, 0x09, 0xd5, 0x2a, 0x30, 0x5c, 0xd7, 0x86, 0x72, 0xe5, 0xc9, 0x31,
+ /*6a90:*/ 0xca, 0x91, 0xc9, 0x90, 0x48, 0xae, 0x14, 0x59, 0xc3, 0x7e, 0x82, 0xb6, 0x9d, 0x56, 0x10, 0x59,
+ /*6aa0:*/ 0xd7, 0x14, 0xbb, 0x47, 0x61, 0xd8, 0x53, 0x2b, 0x56, 0x62, 0xf2, 0x8f, 0x84, 0x58, 0x1b, 0xfb,
+ /*6ab0:*/ 0x95, 0x8d, 0x29, 0x78, 0xf5, 0x35, 0xeb, 0xe0, 0xe1, 0x1e, 0x9b, 0x66, 0x5f, 0xbd, 0xf9, 0x8f,
+ /*6ac0:*/ 0x3d, 0x12, 0x95, 0xb2, 0xbb, 0x75, 0x84, 0x36, 0x51, 0x33, 0xfa, 0x5a, 0x32, 0x16, 0x93, 0x12,
+ /*6ad0:*/ 0x12, 0x31, 0xb5, 0x48, 0x14, 0xb4, 0xdc, 0xcb, 0xb3, 0x38, 0xa7, 0x0b, 0x60, 0x56, 0xfa, 0x73,
+ /*6ae0:*/ 0x28, 0x5d, 0xcf, 0x1b, 0x56, 0x4d, 0x6f, 0xea, 0xea, 0xbd, 0xfc, 0xe6, 0x3c, 0x5c, 0x41, 0x8a,
+ /*6af0:*/ 0x3f, 0x6c, 0xfc, 0x7d, 0x8b, 0x66, 0x4d, 0x51, 0x8d, 0x71, 0x0e, 0xbf, 0xdd, 0xa1, 0x1e, 0x92,
+ /*6b00:*/ 0x7c, 0x4e, 0xd4, 0x6e, 0x0c, 0xaa, 0x50, 0x96, 0xce, 0x90, 0x55, 0xcb, 0x86, 0x24, 0xf2, 0x33,
+ /*6b10:*/ 0xab, 0x9b, 0xc6, 0x60, 0x0d, 0x7f, 0x5b, 0x94, 0x16, 0xd3, 0x55, 0xb7, 0xb4, 0x9e, 0xfe, 0xf0,
+ /*6b20:*/ 0xdc, 0xae, 0x2c, 0xc5, 0x24, 0x0f, 0x7e, 0x99, 0xe4, 0x77, 0x0e, 0x96, 0x90, 0xe8, 0x39, 0xac,
+ /*6b30:*/ 0x8a, 0x53, 0xfb, 0xe8, 0x75, 0x24, 0x69, 0x6f, 0xb2, 0x11, 0x2a, 0x45, 0x2d, 0x2f, 0x87, 0xac,
+ /*6b40:*/ 0xfa, 0xea, 0xd5, 0x70, 0x98, 0x39, 0xdb, 0x81, 0xcd, 0x56, 0xdd, 0x4f, 0xdf, 0x78, 0xe1, 0x2c,
+ /*6b50:*/ 0xab, 0x35, 0x54, 0x37, 0x11, 0xf7, 0x23, 0x31, 0xda, 0xb1, 0xd8, 0x76, 0x2e, 0x86, 0xaa, 0xc7,
+ /*6b60:*/ 0x8e, 0x73, 0x6a, 0xba, 0x2a, 0x98, 0xd3, 0x6b, 0x8a, 0x1f, 0x1d, 0xd3, 0xe9, 0x04, 0x3f, 0xf0,
+ /*6b70:*/ 0xdb, 0xb8, 0x06, 0xd9, 0xae, 0x7e, 0xcb, 0xbf, 0x3d, 0x85, 0xa6, 0x10, 0x30, 0xbc, 0x04, 0x96,
+ /*6b80:*/ 0x2a, 0xc8, 0x89, 0xa9, 0xa6, 0x14, 0xdc, 0x75, 0x4d, 0x5a, 0xe5, 0x4a, 0x89, 0x49, 0x58, 0x1a,
+ /*6b90:*/ 0x4a, 0x07, 0x55, 0x28, 0xd8, 0x5a, 0x12, 0xa0, 0x97, 0x0e, 0xcb, 0x3b, 0x70, 0xb1, 0xa9, 0xaf,
+ /*6ba0:*/ 0x3a, 0xd3, 0x5b, 0xbb, 0x07, 0x4a, 0x3e, 0x04, 0xa7, 0x2f, 0x1e, 0xb7, 0xa3, 0x80, 0xa5, 0x5d,
+ /*6bb0:*/ 0x52, 0x1c, 0x45, 0xd4, 0x11, 0xdf, 0x1a, 0xc0, 0x8d, 0xf6, 0xe4, 0x87, 0x07, 0xa3, 0xb3, 0xa1,
+ /*6bc0:*/ 0xe0, 0x5d, 0x68, 0x0a, 0x2f, 0x94, 0xc3, 0xab, 0x98, 0x76, 0x5e, 0x71, 0xf3, 0x75, 0xb2, 0xcd,
+ /*6bd0:*/ 0x38, 0x38, 0x8e, 0xa3, 0x10, 0xb8, 0xc3, 0x83, 0x71, 0xde, 0x20, 0xa2, 0x62, 0xa9, 0x5f, 0x28,
+ /*6be0:*/ 0xbb, 0xfd, 0x14, 0x11, 0x6c, 0x9f, 0x90, 0x0e, 0x47, 0x0d, 0xf0, 0x28, 0x52, 0x55, 0x1c, 0x5e,
+ /*6bf0:*/ 0xf2, 0x8d, 0x70, 0x81, 0x73, 0x6b, 0x7a, 0x7d, 0x21, 0x3e, 0x8e, 0x4c, 0x80, 0x38, 0x8e, 0x4c,
+ /*6c00:*/ 0x7e, 0x29, 0x99, 0x07, 0x05, 0x25, 0x81, 0x66, 0x64, 0x34, 0x95, 0x45, 0x8c, 0xf3, 0x00, 0x81,
+ /*6c10:*/ 0x81, 0xb8, 0x91, 0xb4, 0xfc, 0x83, 0xc4, 0xac, 0x60, 0xfd, 0x01, 0x04, 0x7a, 0xff, 0x87, 0x04,
+ /*6c20:*/ 0x79, 0x40, 0xc0, 0x93, 0x72, 0x66, 0x32, 0xc6, 0xc1, 0x42, 0xe5, 0x5e, 0x74, 0xd5, 0x3b, 0xb8,
+ /*6c30:*/ 0xde, 0xca, 0xbd, 0x17, 0xc0, 0x5f, 0x93, 0xe5, 0xdc, 0xe7, 0xdb, 0xf8, 0x53, 0x70, 0x01, 0x4d,
+ /*6c40:*/ 0x7a, 0x78, 0x1f, 0xc9, 0xa8, 0x96, 0xbb, 0xde, 0x29, 0xf8, 0x0b, 0x32, 0xd2, 0x9b, 0x00, 0x33,
+ /*6c50:*/ 0x96, 0xa5, 0xd6, 0x7f, 0x88, 0x78, 0x3d, 0x03, 0x39, 0x8b, 0x82, 0x48, 0x88, 0xd6, 0x2d, 0x3d,
+ /*6c60:*/ 0xc5, 0x13, 0xee, 0x2b, 0x61, 0x54, 0xf2, 0x10, 0xec, 0xd2, 0x8d, 0x4a, 0xc4, 0xbe, 0xef, 0x36,
+ /*6c70:*/ 0x39, 0x4f, 0xdc, 0x63, 0xb7, 0x0c, 0x40, 0x38, 0x47, 0x85, 0x40, 0xc7, 0x8b, 0xfa, 0x1f, 0x69,
+ /*6c80:*/ 0x9f, 0xd9, 0xf7, 0x4f, 0x68, 0x7f, 0x34, 0x23, 0xfc, 0x95, 0xee, 0xb2, 0x1c, 0x18, 0xda, 0x2a,
+ /*6c90:*/ 0x2b, 0x78, 0x53, 0x53, 0xa4, 0x32, 0x01, 0x83, 0xf6, 0x3e, 0xf5, 0x40, 0xb2, 0xae, 0x0f, 0x1f,
+ /*6ca0:*/ 0xf7, 0x1f, 0x7f, 0x69, 0x4e, 0x44, 0x54, 0x24, 0x2d, 0x82, 0x32, 0xd3, 0x71, 0x8f, 0xf4, 0x68,
+ /*6cb0:*/ 0x79, 0xc0, 0xdc, 0x98, 0xa6, 0xfb, 0x9b, 0xde, 0xa5, 0xb3, 0xea, 0xbd, 0x02, 0x64, 0xcc, 0xd9,
+ /*6cc0:*/ 0xa2, 0x25, 0x1c, 0x42, 0x15, 0xa8, 0xf0, 0xe5, 0x43, 0x94, 0x39, 0xaf, 0x10, 0xc3, 0x20, 0xa9,
+ /*6cd0:*/ 0x49, 0x2d, 0x12, 0x9f, 0x8e, 0xe5, 0x10, 0x5f, 0x67, 0xb4, 0x55, 0x7a, 0x58, 0x7c, 0xfd, 0xf0,
+ /*6ce0:*/ 0x13, 0x8a, 0xfe, 0xff, 0x5e, 0xfc, 0xc1, 0x93, 0x57, 0xa8, 0x7f, 0xe0, 0x5e, 0xad, 0x63, 0xa8,
+ /*6cf0:*/ 0x38, 0x0c, 0xa3, 0xfa, 0xb3, 0xab, 0x67, 0x4a, 0x09, 0xb8, 0xe5, 0xb2, 0xbd, 0x52, 0xa6, 0xb2,
+ /*6d00:*/ 0x9f, 0x07, 0xe7, 0xce, 0x31, 0xe3, 0x14, 0x82, 0x99, 0xca, 0xad, 0x55, 0x9b, 0xb6, 0x9e, 0x2f,
+ /*6d10:*/ 0xa4, 0x4f, 0xc7, 0xaa, 0x84, 0xfb, 0x22, 0x0a, 0x45, 0x7d, 0xab, 0x24, 0xd5, 0xe3, 0xd2, 0xb1,
+ /*6d20:*/ 0x12, 0xc7, 0xda, 0x73, 0xe8, 0xd4, 0x43, 0x56, 0xaa, 0x9d, 0xc9, 0x0a, 0x9a, 0x19, 0x12, 0x08,
+ /*6d30:*/ 0x89, 0x6f, 0x37, 0x59, 0xfe, 0x67, 0x0f, 0x3c, 0x7b, 0xae, 0x30, 0xa7, 0x1b, 0x6e, 0x8d, 0xb9,
+ /*6d40:*/ 0xd1, 0x6f, 0x94, 0x03, 0x95, 0x22, 0x90, 0xdd, 0x2a, 0xb2, 0xc2, 0x7a, 0x12, 0xe6, 0xad, 0x41,
+ /*6d50:*/ 0xe6, 0xeb, 0x85, 0x8e, 0x98, 0xc0, 0xe1, 0xeb, 0x87, 0xaa, 0xf0, 0xd4, 0xde, 0x5e, 0x32, 0xdb,
+ /*6d60:*/ 0x73, 0xca, 0xc8, 0x5f, 0x87, 0xca, 0x00, 0x3b, 0xfe, 0x3d, 0x0f, 0x90, 0x75, 0xe1, 0x8b, 0xf6,
+ /*6d70:*/ 0x73, 0x46, 0x86, 0x87, 0x98, 0xbf, 0x7d, 0x6d, 0x21, 0xec, 0xa3, 0x8c, 0x5a, 0x53, 0x48, 0x06,
+ /*6d80:*/ 0x56, 0x9a, 0x3d, 0x2b, 0x0a, 0xd7, 0x85, 0x14, 0x0f, 0x12, 0x19, 0x91, 0xcb, 0xb1, 0x9e, 0x6d,
+ /*6d90:*/ 0x9c, 0x27, 0xb2, 0x4e, 0x36, 0xeb, 0xa6, 0x25, 0x22, 0x4a, 0x15, 0x21, 0xd6, 0x23, 0xcf, 0xf1,
+ /*6da0:*/ 0xdf, 0xba, 0x0a, 0xb0, 0x6b, 0xd9, 0xd1, 0x43, 0xfd, 0x0a, 0xa8, 0xf3, 0xf0, 0x34, 0x78, 0x41,
+ /*6db0:*/ 0x7e, 0x70, 0xf4, 0x40, 0xbf, 0x82, 0x37, 0x79, 0xef, 0xe5, 0x80, 0x48, 0x1f, 0x91, 0x47, 0xd6,
+ /*6dc0:*/ 0x7e, 0x41, 0x92, 0x1e, 0x59, 0x28, 0x05, 0xcc, 0xa6, 0xd2, 0xb8, 0xe0, 0x2c, 0xc0, 0x23, 0x58,
+ /*6dd0:*/ 0x50, 0x3a, 0x96, 0x83, 0xd5, 0xa8, 0xa1, 0x82, 0x88, 0x43, 0xab, 0x0b, 0x88, 0xbe, 0xb7, 0x2d,
+ /*6de0:*/ 0x6f, 0x19, 0x74, 0x41, 0x6f, 0xb9, 0xd4, 0xea, 0x25, 0xe1, 0xc5, 0x62, 0x87, 0xb6, 0x0c, 0x2a,
+ /*6df0:*/ 0x5b, 0x9b, 0xa4, 0xa2, 0xcf, 0x9c, 0xb7, 0x60, 0x3a, 0x99, 0x1a, 0x37, 0xf9, 0xf9, 0xce, 0x49,
+ /*6e00:*/ 0x64, 0x2f, 0x3a, 0xc2, 0x35, 0x1b, 0x48, 0x99, 0x64, 0xdb, 0x26, 0xb4, 0x96, 0x74, 0x48, 0x2a,
+ /*6e10:*/ 0x98, 0x39, 0x51, 0x6b, 0x95, 0xb8, 0xaa, 0x47, 0xaf, 0xba, 0xc9, 0x75, 0x3a, 0x83, 0xf4, 0x6b,
+ /*6e20:*/ 0xc2, 0xe2, 0x9d, 0x35, 0x04, 0x4a, 0x7c, 0x2c, 0xa4, 0xac, 0xaf, 0xd4, 0xb6, 0x9c, 0x8c, 0xb1,
+ /*6e30:*/ 0xf7, 0xff, 0xca, 0xab, 0xda, 0x74, 0x70, 0xaf, 0xfc, 0x79, 0x64, 0x0f, 0x24, 0xb6, 0xab, 0x66,
+ /*6e40:*/ 0x0c, 0x31, 0x15, 0xaa, 0x1e, 0xa8, 0x52, 0xc2, 0x19, 0x93, 0x8c, 0x46, 0xbb, 0x66, 0x66, 0xa0,
+ /*6e50:*/ 0xfb, 0xc8, 0x1d, 0x39, 0x89, 0xed, 0xcc, 0x6c, 0x16, 0x88, 0x4d, 0xc4, 0x28, 0x98, 0x1b, 0x6d,
+ /*6e60:*/ 0xa4, 0x42, 0x67, 0x00, 0x06, 0xf8, 0xd5, 0x2b, 0xc2, 0xe3, 0xc7, 0xa7, 0x19, 0x32, 0xcf, 0x79,
+ /*6e70:*/ 0xce, 0x4b, 0x5f, 0x7f, 0xfe, 0xd6, 0xb1, 0xc8, 0xec, 0xe6, 0x96, 0x8b, 0x6a, 0xf6, 0xa4, 0x2b,
+ /*6e80:*/ 0xa7, 0x8f, 0xd8, 0xb1, 0x1f, 0xc5, 0xce, 0x24, 0xfe, 0xd0, 0xd7, 0xd7, 0xd9, 0xfb, 0x8e, 0x19,
+ /*6e90:*/ 0xfd, 0x6f, 0x54, 0x3a, 0x73, 0xbe, 0x0a, 0x5c, 0xd0, 0x1e, 0xf2, 0x85, 0x7c, 0x1e, 0x18, 0xc9,
+ /*6ea0:*/ 0x4f, 0x86, 0x9b, 0x71, 0x1f, 0x0a, 0x75, 0xc4, 0x5d, 0x68, 0xac, 0x1a, 0xef, 0xce, 0xdf, 0xb0,
+ /*6eb0:*/ 0x23, 0x4b, 0x79, 0xa1, 0x64, 0x86, 0x07, 0xa2, 0x91, 0x0d, 0x00, 0x36, 0xf1, 0xbe, 0xe7, 0x4a,
+ /*6ec0:*/ 0x03, 0x13, 0xf2, 0xc0, 0x40, 0x8a, 0x82, 0x49, 0xa8, 0x80, 0x9c, 0xda, 0x0c, 0xe8, 0xf9, 0xb3,
+ /*6ed0:*/ 0x5c, 0xbb, 0x5c, 0x2b, 0x8b, 0xf7, 0xdd, 0x8f, 0x7a, 0x7a, 0xac, 0x29, 0x65, 0x36, 0xb5, 0xc9,
+ /*6ee0:*/ 0xac, 0x60, 0x77, 0x12, 0xe3, 0x2e, 0xbf, 0x7c, 0xdd, 0x3a, 0x99, 0xe9, 0x79, 0xed, 0x36, 0x85,
+ /*6ef0:*/ 0x0b, 0xc5, 0xe7, 0x0d, 0xdb, 0x4d, 0x5e, 0x8c, 0x3a, 0xb5, 0xc2, 0x09, 0x52, 0xf9, 0xf8, 0x90,
+ /*6f00:*/ 0xbd, 0x35, 0x94, 0x27, 0x21, 0xe1, 0xbf, 0xa7, 0xb6, 0x1d, 0x31, 0x23, 0x55, 0x5c, 0xec, 0x78,
+ /*6f10:*/ 0xe6, 0x86, 0xd0, 0x3a, 0x32, 0x14, 0x2a, 0x20, 0x20, 0x59, 0x78, 0x24, 0xab, 0x27, 0xb5, 0xa0,
+ /*6f20:*/ 0x13, 0xfc, 0xf5, 0x5b, 0x1e, 0xad, 0x3a, 0x36, 0x40, 0x18, 0x4a, 0x73, 0x5b, 0xdd, 0x8d, 0xb2,
+ /*6f30:*/ 0xc3, 0xb9, 0xe4, 0x15, 0xf0, 0xd6, 0xf6, 0xf3, 0x5c, 0x26, 0x00, 0x22, 0xde, 0x9a, 0xa4, 0xe1,
+ /*6f40:*/ 0x36, 0xa6, 0xd9, 0xe7, 0xc9, 0x9e, 0xd7, 0xb2, 0x64, 0xfb, 0x24, 0xe9, 0xb0, 0xba, 0xa1, 0xa6,
+ /*6f50:*/ 0xc5, 0xc6, 0x7f, 0xbe, 0x22, 0x28, 0x02, 0x62, 0xb5, 0xf4, 0x38, 0xaa, 0x2d, 0x85, 0x45, 0xac,
+ /*6f60:*/ 0xe8, 0xcc, 0xfc, 0x2f, 0x75, 0xec, 0x09, 0xd2, 0xf5, 0x63, 0x64, 0xd0, 0x1a, 0xec, 0xfc, 0xfb,
+ /*6f70:*/ 0x59, 0xea, 0x70, 0x42, 0x09, 0xae, 0xe9, 0xd0, 0x4f, 0xbb, 0x34, 0xa8, 0x9e, 0x76, 0x2b, 0x13,
+ /*6f80:*/ 0x00, 0xe0, 0xde, 0x26, 0x12, 0x49, 0x6c, 0x1c, 0x52, 0xc1, 0x8d, 0xb9, 0x47, 0xaa, 0xff, 0xb3,
+ /*6f90:*/ 0x06, 0x54, 0x5e, 0x5f, 0x77, 0x82, 0x93, 0x8f, 0xd0, 0x62, 0xd6, 0xde, 0xd2, 0x00, 0xb2, 0xc2,
+ /*6fa0:*/ 0x7e, 0x08, 0x34, 0x9b, 0xc5, 0x2e, 0x6d, 0x3d, 0xbf, 0x06, 0xc8, 0xce, 0x3c, 0x96, 0x9b, 0x9c,
+ /*6fb0:*/ 0xe5, 0x94, 0x0c, 0x56, 0x4e, 0x54, 0xcf, 0xee, 0xff, 0xb3, 0x61, 0x66, 0xf3, 0x4a, 0xe0, 0x6b,
+ /*6fc0:*/ 0x20, 0xda, 0xe3, 0x5f, 0x04, 0xf7, 0xef, 0xc6, 0x27, 0x85, 0xb0, 0xf8, 0xf0, 0xf5, 0x37, 0x50,
+ /*6fd0:*/ 0x34, 0x5d, 0xde, 0x5e, 0x20, 0x57, 0x95, 0xe4, 0x30, 0x0d, 0xa9, 0xe8, 0x05, 0xb8, 0x5e, 0xbe,
+ /*6fe0:*/ 0x2d, 0x74, 0x7b, 0x4b, 0xff, 0x5a, 0x88, 0x31, 0xe5, 0x11, 0xe3, 0x90, 0xef, 0xb3, 0xd1, 0x28,
+ /*6ff0:*/ 0x92, 0x24, 0x4d, 0x93, 0xd3, 0x9c, 0xbf, 0xfc, 0x9d, 0x1f, 0x80, 0x4c, 0xdb, 0xbc, 0x82, 0x3f,
+ /*7000:*/ 0x0d, 0xc9, 0xa6, 0xf5, 0x90, 0x95, 0x0c, 0x18, 0x9b, 0x5a, 0x08, 0xe4, 0x6d, 0xed, 0x36, 0x63,
+ /*7010:*/ 0x78, 0x36, 0x56, 0xfc, 0x40, 0xa9, 0xbb, 0x23, 0xbe, 0x39, 0x16, 0xae, 0xe9, 0x3d, 0x2c, 0xc8,
+ /*7020:*/ 0x3f, 0x70, 0xfc, 0x9d, 0x6d, 0x3b, 0xc8, 0x75, 0xb5, 0x62, 0x8a, 0x80, 0xea, 0x90, 0x25, 0x1b,
+ /*7030:*/ 0xc2, 0x6c, 0x24, 0xc8, 0xab, 0x99, 0x6e, 0x32, 0x59, 0x3e, 0x03, 0xd1, 0xab, 0x20, 0xab, 0x64,
+ /*7040:*/ 0x55, 0xf5, 0x98, 0x31, 0x92, 0xc5, 0xcd, 0x26, 0x97, 0xe0, 0x80, 0xc5, 0xfe, 0x65, 0xd4, 0x21,
+ /*7050:*/ 0x45, 0x9e, 0xee, 0xad, 0x59, 0xd5, 0x32, 0x61, 0x62, 0x6b, 0x86, 0x53, 0xeb, 0xed, 0x36, 0x4c,
+ /*7060:*/ 0x59, 0x1e, 0x0f, 0xc7, 0xcf, 0xf4, 0x9b, 0x8c, 0x43, 0x08, 0x2f, 0x9a, 0x5e, 0x2c, 0x1f, 0xdb,
+ /*7070:*/ 0x5e, 0xd7, 0x0b, 0xe8, 0x4e, 0xe5, 0x76, 0x67, 0x18, 0xdc, 0xd9, 0x6e, 0x64, 0xf4, 0x8f, 0x98,
+ /*7080:*/ 0x47, 0x2f, 0x8d, 0x85, 0xbe, 0x9c, 0xd7, 0xaf, 0x2e, 0x56, 0x82, 0x9d, 0x71, 0x91, 0xbd, 0x7d,
+ /*7090:*/ 0xdd, 0x40, 0x85, 0xd9, 0x40, 0x7b, 0x2d, 0x51, 0xd6, 0xf4, 0xc9, 0x49, 0x1d, 0x5f, 0x1a, 0x23,
+ /*70a0:*/ 0xdc, 0xa7, 0x67, 0x16, 0xe4, 0xde, 0x7b, 0xd9, 0xf0, 0xd6, 0x0d, 0x0f, 0x20, 0x06, 0x22, 0x70,
+ /*70b0:*/ 0xcb, 0x63, 0x94, 0xab, 0xdb, 0xc8, 0x3c, 0xa6, 0x20, 0x70, 0xf4, 0xf4, 0x01, 0xac, 0x8e, 0xc7,
+ /*70c0:*/ 0x5a, 0x3c, 0x38, 0x5f, 0x39, 0x06, 0x47, 0x35, 0x5c, 0x98, 0xbf, 0x9c, 0x59, 0xd0, 0x8d, 0x2f,
+ /*70d0:*/ 0x73, 0x13, 0x06, 0x14, 0x5c, 0x10, 0xc6, 0x17, 0x87, 0xc6, 0x4d, 0x1e, 0x54, 0x67, 0x94, 0x2c,
+ /*70e0:*/ 0xf2, 0xfc, 0x9f, 0x8a, 0x55, 0x8e, 0xd4, 0x16, 0x76, 0xe2, 0x4f, 0x94, 0x29, 0xc9, 0x27, 0xd4,
+ /*70f0:*/ 0x84, 0xd1, 0xc3, 0x33, 0xc7, 0xf3, 0x5c, 0x82, 0x11, 0x95, 0x4f, 0xfb, 0x7b, 0xa1, 0x4d, 0xb4,
+ /*7100:*/ 0x8c, 0x83, 0xec, 0xb6, 0xb2, 0x27, 0xaf, 0xeb, 0x31, 0x07, 0x52, 0x40, 0xd0, 0xc4, 0x75, 0x78,
+ /*7110:*/ 0xf5, 0xcf, 0x28, 0xce, 0x4d, 0xcb, 0x72, 0x87, 0x97, 0x48, 0x7c, 0xc2, 0x76, 0xc7, 0x43, 0x36,
+ /*7120:*/ 0xa5, 0x95, 0x0f, 0x90, 0x8b, 0x0a, 0x90, 0xf0, 0xb3, 0x37, 0x59, 0x9d, 0x0a, 0xde, 0x1a, 0x3a,
+ /*7130:*/ 0x6e, 0xcd, 0xff, 0x66, 0x15, 0xef, 0xcc, 0x5b, 0x83, 0x84, 0x76, 0x9d, 0x07, 0xb3, 0xe4, 0x1c,
+ /*7140:*/ 0x36, 0xb3, 0x99, 0xf6, 0x62, 0x6c, 0x96, 0x5d, 0x56, 0xa7, 0xd7, 0xf2, 0xe2, 0x39, 0x9e, 0x63,
+ /*7150:*/ 0x54, 0x2b, 0x45, 0xc4, 0x4e, 0x55, 0x92, 0x80, 0xd7, 0x24, 0x4d, 0x05, 0x3a, 0x86, 0x34, 0x17,
+ /*7160:*/ 0xb1, 0x09, 0xb4, 0xaf, 0x34, 0x35, 0x69, 0x4f, 0x74, 0x1e, 0x9e, 0x8f, 0x9f, 0x7d, 0x89, 0x7d,
+ /*7170:*/ 0x7e, 0x5a, 0x0a, 0x38, 0xe1, 0x53, 0x73, 0x9a, 0x80, 0xdc, 0xea, 0x3f, 0x79, 0xf0, 0xd8, 0x48,
+ /*7180:*/ 0x7f, 0xf7, 0xc8, 0x73, 0x20, 0x3f, 0xbe, 0x71, 0xec, 0xc5, 0x8a, 0x65, 0x17, 0x16, 0xd0, 0xf4,
+ /*7190:*/ 0x7f, 0x21, 0x33, 0x94, 0xe1, 0xa5, 0x93, 0x32, 0x02, 0x0f, 0x3b, 0x74, 0x97, 0x88, 0x59, 0xcb,
+ /*71a0:*/ 0x12, 0xc5, 0x80, 0xd8, 0x7a, 0xe5, 0x89, 0x0c, 0x09, 0x62, 0x2b, 0x58, 0x9b, 0xef, 0xb5, 0x21,
+ /*71b0:*/ 0xed, 0xb2, 0x70, 0x45, 0x9e, 0x17, 0x87, 0x3b, 0x1b, 0xef, 0xb1, 0xee, 0xea, 0x0f, 0x6f, 0x70,
+ /*71c0:*/ 0x7d, 0x4d, 0xf9, 0x40, 0x11, 0x81, 0x97, 0xe7, 0x08, 0x94, 0x64, 0xd3, 0xe1, 0xbe, 0x76, 0xec,
+ /*71d0:*/ 0x95, 0x29, 0x5a, 0x83, 0xb3, 0x75, 0xd7, 0x10, 0xb1, 0x55, 0x7f, 0xc5, 0xd2, 0x57, 0xe3, 0xf8,
+ /*71e0:*/ 0xf0, 0x78, 0xef, 0xd9, 0x9a, 0xa5, 0xa8, 0xf6, 0x3d, 0xc8, 0xf2, 0xce, 0x58, 0xf0, 0x4b, 0x5a,
+ /*71f0:*/ 0xf3, 0xb7, 0xb3, 0xc8, 0x94, 0xe8, 0x1f, 0xef, 0x4b, 0x1d, 0x03, 0x0b, 0xc2, 0x51, 0xbf, 0x48,
+ /*7200:*/ 0xa7, 0xcf, 0xbe, 0x93, 0x5d, 0x93, 0x21, 0xfc, 0x33, 0x45, 0x6d, 0x79, 0xee, 0xb1, 0x8a, 0x60,
+ /*7210:*/ 0x70, 0xce, 0x7c, 0xbc, 0x58, 0x0b, 0x34, 0xb3, 0x8c, 0xd6, 0x8f, 0x94, 0x50, 0xbf, 0x0b, 0x50,
+ /*7220:*/ 0xc4, 0xf9, 0x9a, 0xd7, 0x95, 0x1e, 0xb0, 0x53, 0xe8, 0xd8, 0x14, 0x9e, 0x13, 0x5b, 0x9c, 0x9f,
+ /*7230:*/ 0xb4, 0xf5, 0x0d, 0x65, 0xfa, 0xe2, 0xaf, 0x04, 0x94, 0xda, 0x9f, 0x8e, 0x31, 0x0e, 0x66, 0xb6,
+ /*7240:*/ 0x45, 0x8b, 0xa5, 0xb5, 0xbc, 0x10, 0x30, 0xcf, 0xf7, 0x77, 0x79, 0x87, 0xd4, 0xe4, 0x32, 0xe3,
+ /*7250:*/ 0xce, 0x97, 0x4d, 0x63, 0xe8, 0xe5, 0x06, 0xf1, 0x3b, 0x30, 0x29, 0x35, 0xab, 0xe4, 0x46, 0x68,
+ /*7260:*/ 0x77, 0x94, 0xf7, 0x0d, 0x82, 0xf7, 0x61, 0xcb, 0x84, 0x2f, 0x2f, 0xfe, 0x5d, 0xe1, 0x25, 0x93,
+ /*7270:*/ 0xe2, 0xb3, 0xd2, 0x35, 0xf0, 0x3d, 0x43, 0x20, 0x1d, 0x4e, 0x9f, 0x35, 0x8c, 0x44, 0x95, 0xc5,
+ /*7280:*/ 0x71, 0x12, 0xd2, 0xc7, 0x8b, 0xf1, 0x30, 0x4a, 0x49, 0x51, 0xe4, 0xe9, 0x03, 0x9b, 0x14, 0x51,
+ /*7290:*/ 0x90, 0xbd, 0xbb, 0x9c, 0x21, 0xb8, 0xe0, 0x51, 0xe3, 0xca, 0xf4, 0xb4, 0x10, 0xd5, 0xa4, 0x8d,
+ /*72a0:*/ 0x9d, 0x3f, 0x28, 0x73, 0x7e, 0x5b, 0x6c, 0xe7, 0xca, 0x57, 0x66, 0x8d, 0x5b, 0x34, 0xe9, 0xaa,
+ /*72b0:*/ 0xb4, 0x2f, 0x56, 0x49, 0x1e, 0xa9, 0x14, 0xed, 0x2b, 0xee, 0x43, 0xa1, 0x3e, 0x10, 0xa4, 0xed,
+ /*72c0:*/ 0x1a, 0x13, 0xad, 0x78, 0x7a, 0xf2, 0x6e, 0xad, 0xca, 0x30, 0x2a, 0xa1, 0xd8, 0xf8, 0xe1, 0xd1,
+ /*72d0:*/ 0x91, 0x68, 0x5f, 0x6e, 0xd9, 0x06, 0x91, 0xd2, 0x8b, 0x2a, 0x9e, 0x29, 0x8c, 0xca, 0x5f, 0x46,
+ /*72e0:*/ 0x77, 0x6c, 0x19, 0xdc, 0x92, 0xf9, 0x8f, 0xc9, 0x68, 0x21, 0xe7, 0x6b, 0x89, 0xf5, 0x83, 0xa8,
+ /*72f0:*/ 0x6b, 0x9d, 0xe0, 0x1d, 0x77, 0x20, 0x16, 0x66, 0xe6, 0x53, 0xda, 0x32, 0x02, 0x39, 0x09, 0xcf,
+ /*7300:*/ 0xed, 0x34, 0xec, 0x87, 0xf7, 0xc0, 0x8d, 0xc7, 0xfc, 0x05, 0x7f, 0xc0, 0x6c, 0x78, 0x7c, 0xd9,
+ /*7310:*/ 0xa3, 0x30, 0xe3, 0xa2, 0x14, 0x0f, 0x42, 0xd6, 0x16, 0x62, 0xcb, 0xb6, 0x4a, 0xf4, 0xab, 0xee,
+ /*7320:*/ 0x29, 0x7e, 0xf3, 0xc1, 0x8e, 0xb9, 0xdd, 0x61, 0x44, 0x82, 0x2f, 0x1f, 0xc0, 0x28, 0x36, 0xb8,
+ /*7330:*/ 0x2c, 0xec, 0x2a, 0x4c, 0xe7, 0x50, 0x37, 0x9b, 0x6f, 0xb3, 0xb3, 0xc2, 0x1b, 0xf4, 0x91, 0x88,
+ /*7340:*/ 0x46, 0xb8, 0x2a, 0xbe, 0xc9, 0x56, 0x4e, 0x74, 0x16, 0xd7, 0x1f, 0x49, 0x3b, 0x50, 0xf2, 0x60,
+ /*7350:*/ 0xbe, 0x0f, 0x3d, 0x79, 0x4b, 0xae, 0x5d, 0xe5, 0x8b, 0xea, 0xd9, 0xe6, 0xca, 0x84, 0x85, 0x93,
+ /*7360:*/ 0x84, 0x98, 0x10, 0x0b, 0xa6, 0xfb, 0xb2, 0xa5, 0x3c, 0xc2, 0x79, 0x75, 0x56, 0x69, 0x26, 0x55,
+ /*7370:*/ 0x61, 0x6e, 0xf3, 0x3d, 0xb3, 0xfa, 0xdc, 0xd1, 0xe4, 0x57, 0x8f, 0x8f, 0x04, 0x61, 0xec, 0x42,
+ /*7380:*/ 0x6b, 0xe2, 0x89, 0xe2, 0x22, 0xc4, 0xde, 0x2e, 0xae, 0x0f, 0x78, 0x73, 0x0a, 0x7f, 0x33, 0x4a,
+ /*7390:*/ 0x26, 0x13, 0x11, 0x73, 0x32, 0x7f, 0x30, 0x28, 0x02, 0x40, 0x19, 0xfc, 0xaf, 0xf0, 0x12, 0x0c,
+ /*73a0:*/ 0x64, 0xcd, 0x83, 0x47, 0x66, 0x7e, 0xa5, 0x45, 0x0c, 0x91, 0xd4, 0x13, 0x45, 0x83, 0xd2, 0xbe,
+ /*73b0:*/ 0x1e, 0x7b, 0x00, 0x43, 0xd8, 0x12, 0x6c, 0xfe, 0xc4, 0x15, 0x34, 0x6e, 0x17, 0xb0, 0x18, 0x72,
+ /*73c0:*/ 0xc1, 0x08, 0x8d, 0x8c, 0x25, 0x24, 0x1a, 0xce, 0x06, 0xdb, 0x34, 0x8d, 0xec, 0xcb, 0x95, 0xf0,
+ /*73d0:*/ 0x09, 0x72, 0xa5, 0x5a, 0x22, 0x99, 0x0a, 0x93, 0x88, 0xea, 0x6e, 0x50, 0x80, 0x35, 0x0a, 0x12,
+ /*73e0:*/ 0x3f, 0x88, 0x4e, 0xe9, 0x64, 0x70, 0xc9, 0xea, 0x5a, 0xe1, 0x43, 0xe7, 0xb3, 0xd0, 0x32, 0x16,
+ /*73f0:*/ 0x58, 0xbf, 0x4b, 0xa0, 0x40, 0x26, 0xad, 0x4f, 0x83, 0xbe, 0x44, 0xbd, 0x29, 0xb2, 0x11, 0xd7,
+ /*7400:*/ 0x7a, 0x23, 0xe5, 0xc5, 0xda, 0xfc, 0xa6, 0xf8, 0xa1, 0x26, 0x99, 0xb3, 0xbb, 0x3d, 0xe6, 0x37,
+ /*7410:*/ 0x24, 0x36, 0x89, 0xa3, 0x67, 0x9b, 0x16, 0x46, 0xdf, 0x9c, 0x09, 0x07, 0x00, 0xf7, 0x14, 0xac,
+ /*7420:*/ 0x6c, 0x88, 0x2f, 0xfe, 0x3a, 0x88, 0xf2, 0xbf, 0x88, 0x87, 0x4e, 0xe5, 0x1a, 0xad, 0x70, 0x79,
+ /*7430:*/ 0x85, 0x2c, 0xa4, 0x2c, 0xf7, 0x8c, 0x2c, 0x9c, 0x16, 0x07, 0x3b, 0x64, 0x62, 0x94, 0x6b, 0xca,
+ /*7440:*/ 0x30, 0x6f, 0xe6, 0x86, 0x71, 0x82, 0x32, 0xd5, 0x22, 0xb7, 0x69, 0x44, 0x82, 0xab, 0xaa, 0xe1,
+ /*7450:*/ 0x5e, 0xf3, 0xd6, 0xb3, 0xf9, 0xe0, 0x1a, 0xfa, 0xf5, 0x54, 0x11, 0x7d, 0xf7, 0x38, 0xdb, 0x31,
+ /*7460:*/ 0x38, 0xfb, 0xf4, 0x3b, 0x47, 0x90, 0x1c, 0x57, 0xbf, 0x66, 0x4e, 0x68, 0xd9, 0x67, 0x03, 0x5a,
+ /*7470:*/ 0xa8, 0xd9, 0xe9, 0x91, 0xee, 0x66, 0x9c, 0x5f, 0xeb, 0x18, 0x12, 0xaf, 0x90, 0xf7, 0x58, 0x13,
+ /*7480:*/ 0x41, 0x5e, 0xa9, 0x66, 0xd7, 0x8a, 0xe7, 0x0c, 0xe9, 0x47, 0xa8, 0x96, 0x25, 0x7c, 0x5c, 0x38,
+ /*7490:*/ 0x46, 0xbc, 0x5a, 0x3d, 0x7f, 0xed, 0x9e, 0xc2, 0xc0, 0xde, 0x93, 0xcb, 0xfc, 0x19, 0x47, 0x5c,
+ /*74a0:*/ 0x5a, 0xca, 0x38, 0xd1, 0x88, 0xac, 0x7f, 0xf9, 0xad, 0x6f, 0x90, 0x62, 0x80, 0x6a, 0xac, 0x5e,
+ /*74b0:*/ 0x5c, 0x58, 0xfd, 0xa2, 0x62, 0xf8, 0x05, 0xbb, 0x5d, 0x63, 0x32, 0x74, 0x74, 0xc9, 0x1e, 0x28,
+ /*74c0:*/ 0xb6, 0x0e, 0x16, 0xa7, 0x4e, 0xc1, 0x51, 0x8e, 0x0d, 0xad, 0x1c, 0x8d, 0x3e, 0x86, 0x2b, 0x99,
+ /*74d0:*/ 0x77, 0x7c, 0x97, 0x70, 0xe9, 0xdf, 0x15, 0x83, 0xa9, 0x9c, 0x92, 0x7a, 0xf5, 0x54, 0x98, 0x7b,
+ /*74e0:*/ 0x33, 0xdf, 0xfb, 0xac, 0xde, 0xe8, 0x89, 0xda, 0x49, 0x77, 0x99, 0x22, 0xac, 0x52, 0x21, 0xf6,
+ /*74f0:*/ 0x7c, 0xf5, 0xa1, 0x67, 0x21, 0xc1, 0x7f, 0x65, 0x96, 0xcb, 0x84, 0x67, 0x1e, 0x87, 0x0f, 0x19,
+ /*7500:*/ 0x92, 0x53, 0x19, 0xce, 0x4f, 0xc5, 0x26, 0xef, 0x5b, 0xe6, 0xee, 0x9e, 0xe0, 0x4e, 0x26, 0xbc,
+ /*7510:*/ 0xa7, 0xe7, 0x06, 0x2d, 0x20, 0xd6, 0x5b, 0xe9, 0x57, 0x05, 0x50, 0xc1, 0x53, 0x3d, 0x0c, 0x29,
+ /*7520:*/ 0xc3, 0xb3, 0xd1, 0xe4, 0x20, 0x0f, 0xe1, 0xad, 0x1d, 0x0d, 0xe8, 0xd9, 0x8f, 0x32, 0xf8, 0x85,
+ /*7530:*/ 0xf4, 0xac, 0x21, 0x01, 0x5a, 0x64, 0xc8, 0x8c, 0x40, 0x2f, 0xf8, 0x52, 0xc8, 0x4d, 0x41, 0x2e,
+ /*7540:*/ 0x6d, 0x97, 0x57, 0x37, 0xca, 0xef, 0xba, 0x0a, 0xb2, 0x15, 0x38, 0x4c, 0xa1, 0xe1, 0x94, 0x1e,
+ /*7550:*/ 0xc2, 0x8e, 0x58, 0xe4, 0x8b, 0x6d, 0x52, 0x1d, 0x15, 0x7b, 0x10, 0x4b, 0x50, 0x32, 0x7b, 0xff,
+ /*7560:*/ 0x7b, 0xd4, 0xd9, 0xc6, 0x26, 0x21, 0x76, 0xf7, 0x4f, 0x9d, 0x35, 0x56, 0x50, 0x5a, 0x0b, 0x94,
+ /*7570:*/ 0x8d, 0x60, 0x84, 0x4d, 0xb2, 0xb3, 0x75, 0x9d, 0x34, 0xf6, 0x8f, 0x2d, 0xc9, 0x48, 0xd9, 0x16,
+ /*7580:*/ 0x20, 0xb4, 0xfa, 0xd4, 0x03, 0x1c, 0x0b, 0x6f, 0x56, 0x4a, 0x7b, 0x5b, 0x00, 0x4d, 0x09, 0x98,
+ /*7590:*/ 0x73, 0xd2, 0x14, 0xe7, 0xef, 0xc6, 0xba, 0x03, 0xab, 0xf9, 0xc4, 0x49, 0xa1, 0xc2, 0x56, 0xa5,
+ /*75a0:*/ 0x6b, 0xbc, 0x91, 0x76, 0x80, 0xc8, 0x85, 0x39, 0xd1, 0x05, 0x81, 0x7a, 0x78, 0x91, 0x7c, 0x4e,
+ /*75b0:*/ 0x15, 0x5a, 0x67, 0x76, 0x08, 0xa5, 0x76, 0xf1, 0x6f, 0xc4, 0x6d, 0x36, 0x40, 0xc1, 0x0a, 0x2b,
+ /*75c0:*/ 0xa3, 0x03, 0x6a, 0xf3, 0x20, 0xcc, 0x39, 0x24, 0x15, 0x21, 0x0d, 0xff, 0x0d, 0x75, 0x38, 0x93,
+ /*75d0:*/ 0x5a, 0x5b, 0xb0, 0x95, 0x27, 0x16, 0x4a, 0xd2, 0xf2, 0x44, 0x76, 0x1d, 0x01, 0xef, 0xf2, 0x9e,
+ /*75e0:*/ 0x92, 0xad, 0xe9, 0x00, 0x96, 0x51, 0x59, 0x9e, 0x03, 0xf8, 0xc4, 0xe8, 0xbb, 0xec, 0xa8, 0xce,
+ /*75f0:*/ 0x38, 0xb2, 0xc6, 0x7d, 0x8f, 0x08, 0xc8, 0xb1, 0x94, 0x41, 0xa8, 0xa0, 0x33, 0xcd, 0x6e, 0x85,
+ /*7600:*/ 0x56, 0x54, 0xf8, 0x93, 0xec, 0x92, 0x43, 0xee, 0xed, 0xac, 0xa6, 0x1a, 0xa6, 0xcd, 0x2a, 0xe5,
+ /*7610:*/ 0x78, 0xf5, 0x2e, 0x44, 0xaf, 0x5b, 0x21, 0x55, 0x12, 0x75, 0xf3, 0xb6, 0x09, 0x9c, 0x1a, 0x79,
+ /*7620:*/ 0xc3, 0xf4, 0x5c, 0x5f, 0xb9, 0xb9, 0xf1, 0x0b, 0x90, 0xf1, 0xc9, 0x81, 0x2c, 0x1f, 0xea, 0x57,
+ /*7630:*/ 0xfb, 0xce, 0x80, 0x90, 0xbc, 0x2b, 0x6b, 0x19, 0xaa, 0x6e, 0xef, 0xc3, 0xff, 0x04, 0x5a, 0x46,
+ /*7640:*/ 0x1a, 0x31, 0x58, 0x59, 0x90, 0x51, 0x5b, 0x6e, 0x8d, 0x0e, 0x03, 0xd9, 0x1f, 0x97, 0xdd, 0xdf,
+ /*7650:*/ 0x8c, 0xc7, 0xf7, 0x9c, 0x35, 0xfb, 0x11, 0xb1, 0x46, 0x93, 0x50, 0x93, 0xa4, 0xab, 0x2a, 0x9c,
+ /*7660:*/ 0xc9, 0x05, 0x67, 0x82, 0x4c, 0xa9, 0x5f, 0x12, 0xf0, 0xb4, 0x09, 0xe5, 0x95, 0x16, 0xa4, 0xd2,
+ /*7670:*/ 0x49, 0x01, 0x37, 0xb8, 0x69, 0xdf, 0x89, 0xbc, 0xe5, 0x9a, 0x0c, 0x6a, 0xfd, 0xae, 0xd9, 0xa0,
+ /*7680:*/ 0x3c, 0xeb, 0xb6, 0x4c, 0xe9, 0xcb, 0xc2, 0x88, 0xc6, 0x67, 0x8e, 0xa7, 0x69, 0xf5, 0xfc, 0xb6,
+ /*7690:*/ 0xb7, 0x26, 0xf1, 0x13, 0x9f, 0x30, 0xd2, 0x0f, 0xb0, 0x45, 0x39, 0x32, 0xc7, 0x37, 0xb2, 0xc4,
+ /*76a0:*/ 0x0c, 0xbd, 0x8b, 0xff, 0x2f, 0x79, 0x0c, 0x2a, 0xbe, 0x7b, 0xf5, 0x8e, 0x23, 0xb9, 0x83, 0xe2,
+ /*76b0:*/ 0xbe, 0x90, 0xcd, 0xa3, 0x81, 0x81, 0x64, 0x24, 0xf4, 0x09, 0x27, 0x58, 0xf5, 0x9e, 0x96, 0x1a,
+ /*76c0:*/ 0xd6, 0x75, 0x92, 0x63, 0x18, 0xd8, 0xe6, 0x5e, 0x83, 0x9e, 0x1a, 0xaf, 0xcf, 0x68, 0x72, 0xdc,
+ /*76d0:*/ 0xc3, 0x7b, 0xcb, 0x32, 0x28, 0x84, 0xfd, 0x6c, 0x39, 0x1d, 0xc9, 0x9c, 0x17, 0x2d, 0x28, 0x75,
+ /*76e0:*/ 0xba, 0xa4, 0x00, 0xea, 0xe6, 0x04, 0x1e, 0x70, 0x27, 0x67, 0xff, 0x5b, 0xdd, 0xd1, 0x8f, 0xfc,
+ /*76f0:*/ 0x71, 0x27, 0xd1, 0x53, 0xf3, 0xc6, 0xb3, 0x52, 0x47, 0x43, 0x6a, 0x01, 0x07, 0xf6, 0x0a, 0x21,
+ /*7700:*/ 0x2a, 0xda, 0x4e, 0x03, 0x41, 0x2f, 0xee, 0x85, 0xae, 0x7f, 0x3b, 0xe6, 0x38, 0xf7, 0x97, 0xde,
+ /*7710:*/ 0xf5, 0x67, 0x10, 0x52, 0xd5, 0x20, 0x73, 0x1b, 0xd9, 0x6b, 0x5c, 0x9a, 0x00, 0x90, 0xbc, 0xd3,
+ /*7720:*/ 0x9c, 0x8d, 0x26, 0x87, 0x97, 0x94, 0x8f, 0x6f, 0x05, 0x64, 0x8d, 0x7b, 0x6f, 0x51, 0xf1, 0xf1,
+ /*7730:*/ 0x43, 0xd2, 0xa3, 0x5e, 0xd5, 0x93, 0x4a, 0xe1, 0x83, 0x84, 0x7c, 0xde, 0xcf, 0x65, 0x1f, 0x6a,
+ /*7740:*/ 0x45, 0xba, 0x07, 0xa6, 0x8e, 0xe4, 0x01, 0x4d, 0x22, 0xdf, 0x00, 0x22, 0x39, 0x75, 0x3e, 0x0d,
+ /*7750:*/ 0x8d, 0x3c, 0x68, 0x5b, 0x7c, 0x81, 0xd1, 0xc6, 0x79, 0x2b, 0x54, 0xb7, 0xc1, 0x86, 0x2e, 0x03,
+ /*7760:*/ 0x44, 0xa6, 0xc0, 0xe0, 0x17, 0x59, 0x3a, 0xed, 0x0b, 0x6b, 0x0c, 0x08, 0x0a, 0xce, 0x9a, 0x31,
+ /*7770:*/ 0xa5, 0x94, 0x3c, 0x96, 0x29, 0x8f, 0xc7, 0xb0, 0xa3, 0x54, 0x91, 0x0d, 0xd5, 0x5e, 0xb3, 0x73,
+ /*7780:*/ 0x1a, 0xf6, 0x69, 0xb4, 0xb0, 0x16, 0xc1, 0x28, 0xdc, 0xbd, 0x4e, 0x2f, 0x89, 0x9d, 0xd2, 0xfe,
+ /*7790:*/ 0x4f, 0xb9, 0x7b, 0x81, 0xcb, 0xf3, 0x67, 0x99, 0x85, 0x44, 0x62, 0xb0, 0x77, 0xd8, 0x3b, 0x2b,
+ /*77a0:*/ 0xda, 0x8d, 0xcd, 0xa2, 0xf5, 0x00, 0x35, 0x98, 0xc2, 0xb0, 0x1f, 0x8d, 0x24, 0xac, 0x42, 0x1b,
+ /*77b0:*/ 0x8b, 0xe7, 0xc0, 0x66, 0xa8, 0x91, 0xf0, 0x68, 0x0b, 0x21, 0xe2, 0x0d, 0x71, 0x7f, 0x10, 0x7f,
+ /*77c0:*/ 0x54, 0x0d, 0x77, 0x01, 0x21, 0x48, 0xde, 0x35, 0x7d, 0x3d, 0x7d, 0xde, 0xc1, 0x3a, 0x18, 0x27,
+ /*77d0:*/ 0x63, 0xb2, 0x81, 0x34, 0x6f, 0x6f, 0x61, 0x8f, 0xd4, 0xcb, 0x95, 0x14, 0x13, 0xc5, 0x62, 0xf2,
+ /*77e0:*/ 0x53, 0xed, 0xad, 0x38, 0x92, 0x7d, 0xd5, 0x1b, 0x10, 0x45, 0x42, 0x78, 0xd1, 0x85, 0x2c, 0x42,
+ /*77f0:*/ 0xcb, 0x72, 0x74, 0x0b, 0x8a, 0x08, 0x39, 0x7b, 0x7b, 0xdb, 0x97, 0x69, 0xcc, 0x22, 0xc7, 0x6e,
+ /*7800:*/ 0x13, 0x5a, 0x2b, 0x90, 0x4b, 0xd7, 0xb3, 0x54, 0x7b, 0x64, 0xf4, 0x4e, 0x3e, 0xd2, 0xd1, 0xf0,
+ /*7810:*/ 0xbb, 0xa5, 0xab, 0xd4, 0xd7, 0x5d, 0xb4, 0x4b, 0x43, 0x8b, 0xe4, 0x0b, 0x27, 0xcb, 0x4c, 0xf9,
+ /*7820:*/ 0xe8, 0x9c, 0x24, 0x68, 0x42, 0x57, 0x9f, 0xa6, 0xc9, 0xc7, 0x53, 0xfc, 0x94, 0x1b, 0x18, 0x97,
+ /*7830:*/ 0xd5, 0xeb, 0x24, 0xbc, 0xb9, 0xaa, 0xc8, 0xe0, 0x01, 0x30, 0xc5, 0x01, 0x49, 0xc3, 0x61, 0x8a,
+ /*7840:*/ 0x47, 0x7a, 0x8d, 0x5b, 0x74, 0x0d, 0x48, 0xbf, 0x0c, 0xb3, 0xec, 0xe9, 0xe0, 0x1f, 0x6c, 0x36,
+ /*7850:*/ 0x67, 0xb7, 0xa1, 0xec, 0x9d, 0x51, 0x00, 0x4e, 0x2f, 0x58, 0xae, 0x7f, 0x61, 0x2e, 0x79, 0x24,
+ /*7860:*/ 0x50, 0x38, 0xe2, 0x3e, 0xc4, 0x00, 0xbb, 0xf2, 0x25, 0x5b, 0xa8, 0xf6, 0x75, 0x58, 0x30, 0xd9,
+ /*7870:*/ 0x63, 0x46, 0x4a, 0x62, 0xfc, 0x47, 0x83, 0xb5, 0xb7, 0xb0, 0x21, 0xf1, 0xfb, 0xaa, 0x6b, 0x17,
+ /*7880:*/ 0xb9, 0xa9, 0xea, 0xd0, 0x98, 0xfc, 0xd5, 0x76, 0x4f, 0x7f, 0x04, 0x69, 0x70, 0x49, 0xcc, 0x34,
+ /*7890:*/ 0x1f, 0x88, 0x0f, 0x63, 0x29, 0x47, 0x15, 0x56, 0x30, 0xfc, 0x99, 0xa9, 0xb9, 0x1a, 0x42, 0xe3,
+ /*78a0:*/ 0x0f, 0x28, 0x7a, 0xed, 0xca, 0xad, 0x55, 0x0f, 0xd7, 0xca, 0x5a, 0xae, 0x61, 0x4b, 0x24, 0xd2,
+ /*78b0:*/ 0x77, 0x68, 0xcc, 0xd2, 0x4f, 0x97, 0xc2, 0xeb, 0x79, 0x5c, 0x0a, 0xfe, 0x90, 0x5a, 0x31, 0xcb,
+ /*78c0:*/ 0x26, 0xa4, 0x73, 0x1e, 0xea, 0x43, 0xd4, 0x64, 0x6e, 0x0c, 0x07, 0x9d, 0xea, 0x6c, 0x91, 0x3c,
+ /*78d0:*/ 0x86, 0x72, 0xa6, 0xf2, 0xcd, 0x87, 0xc8, 0xbb, 0xfd, 0xef, 0x05, 0xa1, 0xf7, 0xff, 0x5f, 0x08,
+ /*78e0:*/ 0xc3, 0xc6, 0x55, 0x92, 0xb6, 0xf3, 0x3a, 0x87, 0x2b, 0x40, 0x3e, 0xe0, 0x37, 0x1f, 0xe2, 0xd4,
+ /*78f0:*/ 0x1e, 0x67, 0xc3, 0x87, 0xb6, 0x93, 0x76, 0x99, 0x22, 0x79, 0xfd, 0x1d, 0xbc, 0xf8, 0x2c, 0x54,
+ /*7900:*/ 0x10, 0x03, 0x2f, 0x36, 0xdb, 0x8c, 0x63, 0xba, 0x91, 0xbc, 0xca, 0xe1, 0xd7, 0xc7, 0x8e, 0x32,
+ /*7910:*/ 0x02, 0xb1, 0x77, 0x4d, 0x1d, 0x70, 0x2b, 0x3a, 0x84, 0xea, 0x1f, 0x78, 0xcc, 0xe8, 0x85, 0x30,
+ /*7920:*/ 0xbc, 0xe5, 0xb6, 0x15, 0x31, 0x4f, 0x61, 0xb2, 0x18, 0x5e, 0x36, 0xad, 0x70, 0x75, 0xd8, 0xe4,
+ /*7930:*/ 0x65, 0xdf, 0xac, 0xa1, 0xcc, 0x51, 0x1a, 0x0e, 0x8d, 0x45, 0xc4, 0x46, 0x73, 0x69, 0x2c, 0xc9,
+ /*7940:*/ 0xb3, 0x96, 0x4e, 0x58, 0x5d, 0x57, 0x68, 0x4e, 0x60, 0x48, 0x16, 0x74, 0x5e, 0xc3, 0xd8, 0x61,
+ /*7950:*/ 0x22, 0x30, 0x3b, 0x63, 0x96, 0x02, 0x35, 0x2a, 0x15, 0x21, 0x62, 0x92, 0x66, 0x7b, 0xfa, 0x90,
+ /*7960:*/ 0xfd, 0x63, 0x3c, 0xa7, 0x5a, 0x72, 0xd4, 0x95, 0x63, 0xb8, 0x57, 0x2e, 0x3a, 0x71, 0xa7, 0xd4,
+ /*7970:*/ 0xff, 0xf9, 0x02, 0xd4, 0xc1, 0xfe, 0xeb, 0x3e, 0x8c, 0xbf, 0xab, 0x16, 0x42, 0x2c, 0x0c, 0x57,
+ /*7980:*/ 0x12, 0xf0, 0x5a, 0x64, 0xf5, 0x09, 0x1c, 0x46, 0x7c, 0xfb, 0xe0, 0x68, 0x94, 0x97, 0x2c, 0x70,
+ /*7990:*/ 0x57, 0x13, 0xed, 0xec, 0xdc, 0xd8, 0xab, 0xba, 0x8e, 0x49, 0x87, 0x7c, 0x03, 0x6a, 0x5e, 0xf5,
+ /*79a0:*/ 0xca, 0x09, 0x96, 0x2c, 0x4b, 0xfb, 0x55, 0xb6, 0x1a, 0x04, 0xf0, 0xb0, 0xbc, 0x71, 0x4f, 0x68,
+ /*79b0:*/ 0x7c, 0xd4, 0x04, 0xd8, 0x16, 0x6d, 0xae, 0xa9, 0x62, 0xa7, 0xc0, 0xdd, 0x6c, 0xf5, 0x6a, 0x81,
+ /*79c0:*/ 0x56, 0xb9, 0x09, 0xed, 0x6a, 0xe1, 0x86, 0x44, 0xf7, 0x94, 0xbf, 0xda, 0xcc, 0xf6, 0x9c, 0x7a,
+ /*79d0:*/ 0xe8, 0x11, 0x1f, 0xdc, 0x7d, 0x22, 0xf2, 0xf1, 0xd2, 0x29, 0x28, 0x02, 0x90, 0x08, 0xb3, 0xdc,
+ /*79e0:*/ 0x13, 0xe5, 0x57, 0x6b, 0xd1, 0xd5, 0x4c, 0xc6, 0xed, 0xf2, 0x7f, 0x45, 0x38, 0x74, 0xd2, 0xe5,
+ /*79f0:*/ 0xb3, 0x38, 0x15, 0xc8, 0x55, 0xbe, 0x3c, 0x3d, 0x4e, 0x0c, 0xdd, 0x52, 0x4f, 0xea, 0x31, 0x26,
+ /*7a00:*/ 0x66, 0x93, 0x37, 0x93, 0x2b, 0x0e, 0x3b, 0x36, 0xd7, 0xd5, 0xc4, 0x9b, 0x3d, 0x0a, 0x25, 0x34,
+ /*7a10:*/ 0xcd, 0x7f, 0xea, 0x96, 0x9c, 0x34, 0x8f, 0xb8, 0x4a, 0x22, 0x4d, 0x64, 0x33, 0xc8, 0x79, 0x2d,
+ /*7a20:*/ 0xed, 0xe0, 0x63, 0x19, 0xac, 0xed, 0xf4, 0x95, 0x9e, 0x82, 0x87, 0x6d, 0xdd, 0x13, 0x7f, 0x00,
+ /*7a30:*/ 0xfe, 0x0a, 0xf8, 0x23, 0x1c, 0x6f, 0x53, 0xa4, 0xcd, 0x64, 0xe2, 0xae, 0xb8, 0x27, 0xff, 0x9f,
+ /*7a40:*/ 0xe9, 0x1e, 0xd7, 0x3e, 0x62, 0xc2, 0x3b, 0xfb, 0x2c, 0x93, 0x06, 0xcf, 0x21, 0xdb, 0x65, 0x8c,
+ /*7a50:*/ 0xc5, 0xe0, 0xfa, 0x99, 0x71, 0xf6, 0x55, 0x17, 0x64, 0xc9, 0xd6, 0x79, 0x0f, 0x0d, 0x4b, 0xdc,
+ /*7a60:*/ 0xcf, 0x24, 0x5d, 0x52, 0xed, 0x41, 0xe8, 0x06, 0x31, 0x87, 0x76, 0xdc, 0x4f, 0x79, 0x8e, 0x10,
+ /*7a70:*/ 0xa5, 0x5c, 0x37, 0x8c, 0xd4, 0xf7, 0x72, 0x77, 0xd9, 0x69, 0x24, 0x54, 0xdc, 0xf6, 0x35, 0x97,
+ /*7a80:*/ 0x0d, 0xe4, 0x14, 0xdd, 0xc7, 0x1c, 0x75, 0x5f, 0x2c, 0x33, 0xbe, 0xaa, 0x62, 0xbc, 0x53, 0x04,
+ /*7a90:*/ 0x18, 0xe0, 0x56, 0x8b, 0xdb, 0xcd, 0xcf, 0x98, 0xb5, 0x1b, 0xb4, 0xa9, 0x84, 0xb3, 0x89, 0xcf,
+ /*7aa0:*/ 0x5c, 0x57, 0x2d, 0x3d, 0xea, 0x89, 0xd7, 0x14, 0x1e, 0x3b, 0x1e, 0xfb, 0x2e, 0xf6, 0xa7, 0x62,
+ /*7ab0:*/ 0xd5, 0x21, 0x6f, 0xd2, 0x73, 0xd8, 0x3e, 0xde, 0x1a, 0x65, 0x9f, 0xd0, 0xeb, 0x90, 0x0b, 0x9d,
+ /*7ac0:*/ 0x21, 0xe5, 0x62, 0x5f, 0x31, 0x8c, 0x8e, 0x55, 0x8b, 0x85, 0x38, 0xa3, 0x16, 0xe8, 0x85, 0x48,
+ /*7ad0:*/ 0xce, 0xc9, 0xf3, 0x6e, 0x1c, 0x36, 0xd4, 0x38, 0x44, 0x92, 0x9b, 0xf0, 0xc4, 0x6a, 0x44, 0x13,
+ /*7ae0:*/ 0xfa, 0xde, 0x91, 0x4e, 0x04, 0xeb, 0x70, 0x2d, 0xb4, 0x5f, 0xc5, 0xe0, 0x49, 0x1c, 0x42, 0x4c,
+ /*7af0:*/ 0xca, 0xa2, 0x70, 0xc3, 0x5f, 0x38, 0x9c, 0x3b, 0xed, 0x96, 0xdf, 0x8d, 0x7f, 0x8c, 0xf9, 0x29,
+ /*7b00:*/ 0xe6, 0x5d, 0x4e, 0x0e, 0x9d, 0x47, 0x12, 0x37, 0x0c, 0x59, 0xf7, 0x01, 0xa9, 0xab, 0x4a, 0x08,
+ /*7b10:*/ 0x31, 0x9e, 0x5d, 0x7a, 0xbb, 0xe3, 0x69, 0x03, 0x53, 0xaf, 0xca, 0x96, 0x2e, 0x98, 0x12, 0xfd,
+ /*7b20:*/ 0x30, 0xab, 0xed, 0x90, 0xa2, 0x08, 0xd5, 0x2d, 0xcc, 0xda, 0xc3, 0x1b, 0xf9, 0x4c, 0x83, 0x71,
+ /*7b30:*/ 0xb0, 0x40, 0xc9, 0xe6, 0x1f, 0x03, 0x38, 0xc7, 0x6a, 0x85, 0xe1, 0xae, 0x1f, 0xca, 0x12, 0xe4,
+ /*7b40:*/ 0x6e, 0x9c, 0x1d, 0x6f, 0x6d, 0xa8, 0x2b, 0x9b, 0x46, 0x47, 0x8c, 0xba, 0x32, 0x3d, 0x98, 0x5d,
+ /*7b50:*/ 0x1e, 0xea, 0x08, 0xa6, 0x6d, 0xd8, 0x8a, 0x1c, 0x1c, 0xeb, 0x61, 0x0d, 0xc2, 0x9a, 0x3f, 0x79,
+ /*7b60:*/ 0xf4, 0x73, 0x8f, 0x30, 0xb7, 0x73, 0x06, 0x0c, 0xfc, 0x74, 0xf9, 0x60, 0x05, 0x46, 0xe9, 0x10,
+ /*7b70:*/ 0x1f, 0x8d, 0x01, 0x46, 0xd7, 0xc3, 0x72, 0x19, 0x7f, 0x45, 0x09, 0xe7, 0xe2, 0x9f, 0x7e, 0x57,
+ /*7b80:*/ 0x65, 0x0a, 0x4b, 0x02, 0x51, 0x20, 0xda, 0x6d, 0x09, 0xbf, 0x10, 0x02, 0xbc, 0xb9, 0x57, 0x5a,
+ /*7b90:*/ 0x4d, 0x49, 0x51, 0x9d, 0xb5, 0x1d, 0xb1, 0xf0, 0x1d, 0x31, 0xe1, 0xac, 0x27, 0x28, 0x6f, 0xc2,
+ /*7ba0:*/ 0x2f, 0xd2, 0x2e, 0xb6, 0xe8, 0xa9, 0xaa, 0xfd, 0x48, 0x61, 0x1a, 0xcc, 0x06, 0x33, 0x43, 0x42,
+ /*7bb0:*/ 0x5b, 0x37, 0x63, 0x31, 0xbc, 0x08, 0x0b, 0xea, 0x64, 0x64, 0xbf, 0x64, 0x48, 0xd6, 0x67, 0x02,
+ /*7bc0:*/ 0xda, 0xb3, 0xd4, 0x7b, 0xac, 0x59, 0x47, 0xde, 0x5a, 0x69, 0xac, 0xf4, 0xbc, 0x92, 0x5f, 0x23,
+ /*7bd0:*/ 0x0c, 0xd8, 0x07, 0x48, 0xd4, 0x7a, 0x7e, 0x5b, 0x09, 0xff, 0xc6, 0xc8, 0x6d, 0x64, 0xcb, 0x36,
+ /*7be0:*/ 0x0f, 0x71, 0xe9, 0x8a, 0xa2, 0xbe, 0xee, 0xaa, 0x21, 0xf5, 0xfe, 0xe6, 0xdc, 0x05, 0x19, 0x26,
+ /*7bf0:*/ 0x58, 0x85, 0x09, 0x62, 0x18, 0x96, 0x37, 0x0d, 0xde, 0xf5, 0xbf, 0xe6, 0x96, 0x15, 0xea, 0x51,
+ /*7c00:*/ 0x88, 0x63, 0x2e, 0x1d, 0x08, 0xad, 0xa2, 0x48, 0x0b, 0x93, 0x89, 0xb0, 0xfc, 0x89, 0xa7, 0x64,
+ /*7c10:*/ 0x85, 0x42, 0x55, 0x64, 0x67, 0x76, 0xb9, 0x88, 0x94, 0xa0, 0x4a, 0x6a, 0xf2, 0x5e, 0x02, 0xa8,
+ /*7c20:*/ 0x06, 0xd1, 0x43, 0x8b, 0xfa, 0xe7, 0x99, 0x3b, 0xdc, 0x61, 0xbe, 0x3e, 0x9a, 0xd7, 0xea, 0x8f,
+ /*7c30:*/ 0x67, 0xd4, 0xdd, 0x46, 0x5a, 0x87, 0xed, 0x92, 0x25, 0xe7, 0x0e, 0x27, 0x08, 0x49, 0xfc, 0x5c,
+ /*7c40:*/ 0x22, 0x35, 0xa8, 0x2f, 0xcd, 0x9a, 0xa2, 0x2a, 0x54, 0xf5, 0xdb, 0x0e, 0x2c, 0x77, 0xf6, 0x5d,
+ /*7c50:*/ 0xa3, 0x1f, 0xf5, 0xa3, 0x9a, 0xa7, 0x74, 0xce, 0x58, 0xb0, 0xbd, 0x88, 0x8e, 0x4f, 0x97, 0xff,
+ /*7c60:*/ 0x78, 0x0c, 0x9c, 0x7d, 0x5c, 0x65, 0x6c, 0x24, 0x7c, 0xe3, 0x7f, 0xee, 0x2f, 0x50, 0xf3, 0x1f,
+ /*7c70:*/ 0x7d, 0x6b, 0xd4, 0xc3, 0xe3, 0x3a, 0x88, 0x81, 0x8d, 0x61, 0x7f, 0xdc, 0xa9, 0x4b, 0xac, 0x0e,
+ /*7c80:*/ 0x76, 0x1e, 0x4e, 0xd8, 0xf7, 0x5b, 0x2c, 0x03, 0x37, 0xa6, 0x93, 0x78, 0xb0, 0xad, 0x96, 0xff,
+ /*7c90:*/ 0xf1, 0xaf, 0x9a, 0x1c, 0xa4, 0x9d, 0x04, 0x5a, 0xbd, 0x85, 0x1b, 0xd9, 0xad, 0x92, 0x1a, 0x28,
+ /*7ca0:*/ 0xe7, 0x7e, 0x08, 0x25, 0x67, 0xb8, 0x0c, 0x83, 0x2f, 0x3d, 0x92, 0xd7, 0xfe, 0xcf, 0x18, 0xee,
+ /*7cb0:*/ 0xd8, 0xd3, 0x2d, 0xec, 0x6f, 0x56, 0x3c, 0x6a, 0x69, 0x4b, 0x31, 0x8b, 0x7e, 0x9d, 0x18, 0x26,
+ /*7cc0:*/ 0xdc, 0xdd, 0x89, 0xc2, 0x1d, 0x32, 0x49, 0x27, 0xf7, 0x78, 0x46, 0x8e, 0xbf, 0x47, 0x37, 0x9d,
+ /*7cd0:*/ 0x45, 0xad, 0x46, 0x63, 0x9e, 0x70, 0xd7, 0xd9, 0xdd, 0x0f, 0x2f, 0xe1, 0x11, 0xe9, 0x93, 0xa2,
+ /*7ce0:*/ 0x99, 0x6e, 0xc4, 0x98, 0x6a, 0xf3, 0x31, 0x33, 0xe9, 0x54, 0x84, 0x6e, 0xc7, 0xe5, 0x7b, 0x79,
+ /*7cf0:*/ 0x4f, 0x06, 0x69, 0x36, 0x64, 0x23, 0x7e, 0xc5, 0xdc, 0x95, 0x1c, 0x34, 0x86, 0x93, 0x9e, 0xa9,
+ /*7d00:*/ 0x5f, 0xab, 0x6c, 0xff, 0xee, 0x8e, 0x80, 0x0b, 0x66, 0x76, 0xc0, 0x12, 0x75, 0x6d, 0x96, 0xb1,
+ /*7d10:*/ 0xaf, 0xb2, 0xe9, 0x96, 0x34, 0xcc, 0x99, 0x89, 0x59, 0xbc, 0xe0, 0xd5, 0xde, 0x1e, 0x7b, 0x3b,
+ /*7d20:*/ 0x88, 0xd3, 0xe4, 0x27, 0x06, 0x93, 0x4c, 0xf4, 0x8b, 0xdb, 0xef, 0xd3, 0x23, 0x85, 0x30, 0x37,
+ /*7d30:*/ 0x47, 0x54, 0x7e, 0x7d, 0xe7, 0x21, 0xeb, 0xc5, 0x55, 0x93, 0x1f, 0xd4, 0xf1, 0x8c, 0x7d, 0xd4,
+ /*7d40:*/ 0x3b, 0xfe, 0x83, 0x4a, 0xc8, 0x9a, 0xd4, 0x2a, 0x69, 0x52, 0x73, 0x81, 0x77, 0x8f, 0x7c, 0x98,
+ /*7d50:*/ 0xa0, 0x01, 0x7e, 0x7e, 0x34, 0x91, 0xb1, 0xea, 0x5b, 0x05, 0xa4, 0x0d, 0x41, 0x8c, 0x38, 0x0c,
+ /*7d60:*/ 0xfe, 0x32, 0x81, 0xee, 0x1a, 0x54, 0xcf, 0x01, 0x8e, 0xb3, 0x6e, 0xa0, 0x41, 0xa1, 0xa5, 0xa3,
+ /*7d70:*/ 0xc0, 0x18, 0x5e, 0x06, 0x32, 0x04, 0x85, 0x72, 0x60, 0x07, 0xb5, 0x30, 0xce, 0xfc, 0x21, 0xb4,
+ /*7d80:*/ 0xaa, 0xaa, 0xd9, 0xaf, 0xb1, 0x7e, 0xbd, 0x03, 0x32, 0x56, 0x55, 0x5c, 0xdb, 0xe3, 0x05, 0x06,
+ /*7d90:*/ 0x6b, 0x39, 0x67, 0x81, 0xcd, 0xd0, 0xc8, 0x5d, 0xb8, 0xae, 0xb6, 0x13, 0x3b, 0x6e, 0x4c, 0x4b,
+ /*7da0:*/ 0x8f, 0x12, 0x5f, 0x21, 0x61, 0x6c, 0xfc, 0x3f, 0x96, 0x1b, 0x82, 0x57, 0xf9, 0xbe, 0x5a, 0x91,
+ /*7db0:*/ 0x19, 0xac, 0xdd, 0x54, 0x2a, 0xd6, 0x8b, 0xa6, 0x0b, 0xb8, 0x7e, 0xeb, 0xaa, 0x86, 0x3a, 0x44,
+ /*7dc0:*/ 0x96, 0x7a, 0xec, 0x6a, 0x3e, 0xa0, 0x94, 0x3e, 0xb3, 0xe0, 0xc1, 0xf9, 0xd4, 0xff, 0xa4, 0x10,
+ /*7dd0:*/ 0x79, 0x8e, 0x83, 0x65, 0x2e, 0xd9, 0x90, 0xec, 0x00, 0xca, 0x2a, 0x86, 0xb8, 0x85, 0xf1, 0xa1,
+ /*7de0:*/ 0xdc, 0xfe, 0x54, 0x11, 0x67, 0xcf, 0x6d, 0x42, 0x6c, 0x2d, 0xf7, 0x8e, 0x9c, 0x5e, 0x0f, 0x62,
+ /*7df0:*/ 0x49, 0xf8, 0xb2, 0x4c, 0xc8, 0x7a, 0x47, 0x40, 0x59, 0xba, 0xa3, 0x8b, 0xad, 0x61, 0x8e, 0xd6,
+ /*7e00:*/ 0xbf, 0xd1, 0xf4, 0x3e, 0xb9, 0x80, 0x47, 0xd5, 0x94, 0xa9, 0xb9, 0xc1, 0x4d, 0xf4, 0x35, 0xa6,
+ /*7e10:*/ 0xa4, 0x13, 0x90, 0xcb, 0x7f, 0x9d, 0x08, 0xb7, 0x5a, 0x5e, 0x1f, 0x5a, 0x5c, 0x19, 0xc2, 0xce,
+ /*7e20:*/ 0xa2, 0xe4, 0xc1, 0x2c, 0xdb, 0xb9, 0x84, 0xb4, 0x7a, 0xa4, 0x0c, 0xaf, 0xf0, 0xdc, 0x7e, 0xe4,
+ /*7e30:*/ 0x27, 0x94, 0x69, 0x07, 0x6d, 0xc2, 0xaa, 0xc4, 0x95, 0x80, 0xb5, 0x94, 0xf8, 0x57, 0x0e, 0x97,
+ /*7e40:*/ 0x4d, 0x9a, 0x3e, 0x5c, 0x63, 0x44, 0x1b, 0x61, 0x22, 0xd8, 0x47, 0x4c, 0x35, 0x39, 0xa0, 0xfd,
+ /*7e50:*/ 0x52, 0x3c, 0x3f, 0x2f, 0x2d, 0x15, 0x19, 0x7b, 0xd9, 0x17, 0xa7, 0x90, 0x0f, 0xbe, 0x21, 0xf6,
+ /*7e60:*/ 0x7b, 0x58, 0x8f, 0x48, 0x77, 0x0e, 0xac, 0x66, 0xa3, 0x2f, 0x80, 0xee, 0xe6, 0x23, 0x72, 0x03,
+ /*7e70:*/ 0x8e, 0x56, 0x54, 0x13, 0x1e, 0x06, 0xbc, 0x5d, 0xdf, 0x78, 0xf5, 0x1f, 0x1e, 0x2f, 0xd6, 0x68,
+ /*7e80:*/ 0x50, 0x1d, 0xaf, 0x61, 0x5d, 0x4b, 0x38, 0x31, 0x2c, 0xef, 0x54, 0x3c, 0x5f, 0xfc, 0xb5, 0x5e,
+ /*7e90:*/ 0xd9, 0x96, 0x08, 0x31, 0x25, 0x20, 0x42, 0xfb, 0x19, 0xba, 0xc8, 0xf2, 0x0f, 0xe3, 0xfd, 0x5b,
+ /*7ea0:*/ 0xae, 0x65, 0xba, 0x26, 0xfa, 0x7a, 0xfd, 0x79, 0xfd, 0xda, 0x2b, 0xab, 0xb2, 0x0b, 0x40, 0x55,
+ /*7eb0:*/ 0x87, 0x81, 0x6d, 0xc1, 0x02, 0xa4, 0xbc, 0x94, 0x89, 0x81, 0x42, 0xe7, 0x40, 0xf0, 0xd0, 0xfe,
+ /*7ec0:*/ 0x54, 0x56, 0xf8, 0xfa, 0x0c, 0x53, 0xce, 0xac, 0x04, 0xe3, 0xfb, 0xc6, 0x2f, 0x87, 0x6b, 0xde,
+ /*7ed0:*/ 0x74, 0x0f, 0x7a, 0x5b, 0xb8, 0xf2, 0x0a, 0x66, 0xf0, 0xb2, 0x1e, 0xd8, 0x2f, 0x37, 0xe0, 0xc1,
+ /*7ee0:*/ 0x45, 0x62, 0x6b, 0x0b, 0xab, 0xe8, 0x1f, 0x31, 0x7a, 0x28, 0xca, 0x54, 0x6f, 0x36, 0x10, 0xd6,
+ /*7ef0:*/ 0x43, 0xc1, 0xe1, 0x0a, 0x2e, 0xb6, 0xce, 0xaf, 0x45, 0xdc, 0x18, 0x9e, 0xcf, 0x5a, 0xdd, 0xea,
+ /*7f00:*/ 0x2e, 0xd7, 0xe5, 0x55, 0x49, 0x3e, 0x08, 0x15, 0xf7, 0xe3, 0xf7, 0x78, 0x8e, 0x41, 0xd1, 0xf8,
+ /*7f10:*/ 0xf4, 0x7a, 0x59, 0x93, 0xc8, 0xdf, 0xdb, 0xe1, 0x88, 0x66, 0x21, 0x84, 0xb7, 0x4d, 0xd6, 0x4a,
+ /*7f20:*/ 0x61, 0x2c, 0x5b, 0x8b, 0xf4, 0xc3, 0x64, 0xcc, 0x73, 0x69, 0xca, 0x0b, 0x55, 0x38, 0xbd, 0x2a,
+ /*7f30:*/ 0x6d, 0x1f, 0xad, 0xe4, 0xfe, 0x3a, 0xbf, 0x4a, 0xff, 0x18, 0x5f, 0x9c, 0x5d, 0xa7, 0x2f, 0xbc,
+ /*7f40:*/ 0x71, 0x8a, 0xe0, 0x82, 0x4a, 0xd8, 0x92, 0xdb, 0xb6, 0x80, 0x29, 0xa4, 0xed, 0x65, 0x3f, 0x72,
+ /*7f50:*/ 0xc4, 0xbc, 0x05, 0x4f, 0x3a, 0x97, 0x5d, 0x3c, 0x24, 0x50, 0xa4, 0x5b, 0x4e, 0x75, 0xab, 0x20,
+ /*7f60:*/ 0x96, 0x42, 0xa3, 0x5b, 0x36, 0x74, 0x79, 0xb0, 0xd2, 0xce, 0x49, 0x23, 0xa2, 0x22, 0xd7, 0x21,
+ /*7f70:*/ 0x66, 0xbe, 0xc4, 0xa9, 0x0c, 0x9d, 0xb3, 0xfc, 0x18, 0x81, 0x48, 0x7e, 0x1b, 0xfa, 0xdf, 0xb8,
+ /*7f80:*/ 0xba, 0xae, 0x15, 0x16, 0xdf, 0xee, 0x6c, 0x53, 0xf9, 0x6a, 0x80, 0xbb, 0xe0, 0x5e, 0x98, 0x2d,
+ /*7f90:*/ 0x18, 0xf1, 0x45, 0x99, 0x2d, 0xb8, 0xc6, 0xff, 0x74, 0xf4, 0xaa, 0x0b, 0x94, 0x42, 0x09, 0xb8,
+ /*7fa0:*/ 0x26, 0x5f, 0x7c, 0x15, 0x17, 0xe0, 0x90, 0x04, 0x96, 0x1e, 0x8d, 0xa9, 0xc3, 0x59, 0xcb, 0x5a,
+ /*7fb0:*/ 0xc2, 0x22, 0x78, 0x9c, 0xbe, 0xb1, 0xc8, 0x5b, 0x84, 0xda, 0x24, 0x3f, 0x3b, 0xc9, 0x9b, 0x7a,
+ /*7fc0:*/ 0xbb, 0xfd, 0xe7, 0x4b, 0x23, 0x43, 0xd1, 0x04, 0x98, 0x14, 0x5e, 0x23, 0xdb, 0xb9, 0x18, 0x3c,
+ /*7fd0:*/ 0x4f, 0xdb, 0xe1, 0x14, 0x1e, 0x30, 0x19, 0xd6, 0xb6, 0x70, 0xd4, 0xe1, 0xe1, 0x40, 0xad, 0xff,
+ /*7fe0:*/ 0xe9, 0xcc, 0xd5, 0xfa, 0xc1, 0x2b, 0x66, 0x07, 0xde, 0x05, 0x6d, 0xe7, 0x97, 0x75, 0xb9, 0x3f,
+ /*7ff0:*/ 0x5f, 0xd2, 0xdf, 0xd2, 0xd1, 0x27, 0xfe, 0x29, 0xb7, 0xc5, 0xfa, 0x41, 0xfd, 0x39, 0x39, 0x45,
+ /*8000:*/ 0xc6, 0x96, 0xa2, 0xd5, 0x25, 0xab, 0x00, 0xe4, 0x4c, 0xc8, 0x48, 0xe5, 0x89, 0xa5, 0x0b, 0x13,
+ /*8010:*/ 0x82, 0xb5, 0x53, 0xd6, 0x4c, 0x47, 0x7d, 0x28, 0x39, 0xe5, 0xad, 0x94, 0xc4, 0x6d, 0x21, 0x1e,
+ /*8020:*/ 0xb0, 0x73, 0xd9, 0xcc, 0xa6, 0x2f, 0x0b, 0xf0, 0x9c, 0xd7, 0x5c, 0x5f, 0x99, 0xf6, 0x09, 0x6e,
+ /*8030:*/ 0x64, 0xb1, 0xce, 0xcc, 0xee, 0x55, 0xd9, 0xeb, 0x51, 0x5f, 0x03, 0x03, 0x6f, 0xc2, 0xea, 0x70,
+ /*8040:*/ 0xc3, 0x4c, 0xd1, 0x9e, 0x26, 0x06, 0x0f, 0x80, 0x2d, 0xf0, 0x43, 0x75, 0x09, 0x8c, 0x52, 0x6a,
+ /*8050:*/ 0xbb, 0x76, 0xda, 0x09, 0x2f, 0x00, 0x45, 0xad, 0x9a, 0x24, 0x12, 0x4c, 0x29, 0x58, 0x67, 0x4f,
+ /*8060:*/ 0xd8, 0xdd, 0xe9, 0x62, 0xd4, 0x95, 0x0d, 0x83, 0x62, 0xfe, 0x66, 0xad, 0x12, 0x06, 0xe1, 0x16,
+ /*8070:*/ 0xb8, 0x89, 0xb4, 0x9f, 0xa6, 0xb6, 0x4f, 0xa7, 0xfe, 0x72, 0xd5, 0xbc, 0x7c, 0x84, 0x62, 0xe2,
+ /*8080:*/ 0xb1, 0xfb, 0x0c, 0x54, 0xed, 0x69, 0x96, 0x68, 0x5c, 0x1b, 0xcf, 0xa3, 0x56, 0xdd, 0x0b, 0x78,
+ /*8090:*/ 0x9c, 0x5d, 0x7d, 0x9d, 0x05, 0x79, 0x72, 0xb9, 0xa9, 0x6e, 0xd1, 0xfb, 0x0c, 0x28, 0x2b, 0xa9,
+ /*80a0:*/ 0xf4, 0xb3, 0x41, 0xb1, 0x12, 0xe0, 0xe3, 0xf4, 0xf0, 0x6c, 0x86, 0x50, 0xf0, 0xaf, 0x23, 0x87,
+ /*80b0:*/ 0x67, 0x91, 0xe2, 0x07, 0x6c, 0x77, 0x16, 0xf9, 0x5f, 0x83, 0x8a, 0x46, 0xb6, 0xe3, 0x02, 0x59,
+ /*80c0:*/ 0x77, 0xaf, 0x3e, 0x98, 0x33, 0x3f, 0xb6, 0xf4, 0x02, 0x23, 0x50, 0xd8, 0x4b, 0xc9, 0x4e, 0xd9,
+ /*80d0:*/ 0x00, 0xe9, 0x68, 0x13, 0x44, 0xed, 0x2c, 0x4d, 0xd7, 0x60, 0xb4, 0x69, 0xc6, 0xd4, 0xe7, 0xc6,
+ /*80e0:*/ 0x57, 0xe4, 0xb0, 0x5d, 0x74, 0x51, 0xb5, 0x09, 0x54, 0x11, 0x58, 0x1b, 0xab, 0xf6, 0x54, 0xfb,
+ /*80f0:*/ 0xe4, 0xaa, 0x99, 0xb0, 0xc2, 0xa8, 0xc3, 0x2d, 0x52, 0x95, 0x39, 0x51, 0x4b, 0x18, 0x83, 0xe6,
+ /*8100:*/ 0xfc, 0x55, 0xd5, 0x0a, 0xae, 0x93, 0x70, 0x97, 0x60, 0x65, 0x63, 0x61, 0x72, 0x65, 0x9a, 0xe8,
+ /*8110:*/ 0x13, 0x86, 0x99, 0x14, 0x75, 0xca, 0xe2, 0x9b, 0x40, 0xaf, 0x63, 0x49, 0x50, 0xfc, 0x1d, 0x9b,
+ /*8120:*/ 0x2a, 0x26, 0xee, 0xbc, 0x88, 0x78, 0x1d, 0xd8, 0xd6, 0x51, 0x8b, 0x8f, 0x45, 0xf9, 0xe0, 0x4b,
+ /*8130:*/ 0x70, 0xb4, 0x6b, 0x84, 0x42, 0xe5, 0x7b, 0x26, 0xf0, 0xb4, 0xff, 0x15, 0x70, 0x23, 0xc7, 0xd6,
+ /*8140:*/ 0xd7, 0xa0, 0x22, 0x84, 0x8f, 0x3d, 0xd6, 0x25, 0x26, 0x22, 0x3e, 0xcf, 0x81, 0x67, 0x1e, 0xdc,
+ /*8150:*/ 0x23, 0xc7, 0x2a, 0xe7, 0x2e, 0x68, 0x65, 0x06, 0x2f, 0xe0, 0x57, 0xe0, 0x89, 0x27, 0x5f, 0xc6,
+ /*8160:*/ 0x81, 0x85, 0x04, 0xb0, 0xa3, 0xc9, 0xde, 0xe3, 0x4f, 0x68, 0x4d, 0xc7, 0xa2, 0xc9, 0xc2, 0x6c,
+ /*8170:*/ 0x42, 0x37, 0x7d, 0x94, 0xe4, 0x61, 0x26, 0x39, 0x26, 0xc7, 0x30, 0xd9, 0xfc, 0x5a, 0x82, 0x44,
+ /*8180:*/ 0xee, 0x2c, 0x82, 0x2f, 0xa3, 0x66, 0xfc, 0x7a, 0x6b, 0xde, 0x3a, 0xf8, 0xad, 0xc4, 0xcc, 0xdf,
+ /*8190:*/ 0x4f, 0x38, 0xf0, 0x1e, 0xd8, 0x0d, 0x7d, 0x98, 0x6b, 0x74, 0xa5, 0xd7, 0x10, 0xce, 0xa0, 0x53,
+ /*81a0:*/ 0x72, 0x51, 0xf1, 0x5a, 0xa0, 0x01, 0x2c, 0x33, 0xe5, 0xfe, 0x25, 0xeb, 0x6c, 0xe3, 0x79, 0x02,
+ /*81b0:*/ 0x87, 0x5a, 0x56, 0xe9, 0xb6, 0xd0, 0xd1, 0x41, 0xe4, 0x2f, 0x53, 0xed, 0xbd, 0x22, 0x14, 0xe0,
+ /*81c0:*/ 0x2d, 0x48, 0x8c, 0xb9, 0x67, 0xd8, 0x7b, 0x27, 0x58, 0x7a, 0x7c, 0xc8, 0xd6, 0x48, 0xec, 0xd9,
+ /*81d0:*/ 0xba, 0xcf, 0xd1, 0xc4, 0xbd, 0x7f, 0x38, 0xb7, 0xdf, 0x4a, 0xff, 0x99, 0xd8, 0xf4, 0xaa, 0xbf,
+ /*81e0:*/ 0x68, 0x9a, 0xcb, 0x63, 0xcd, 0x01, 0x05, 0x53, 0xfd, 0xae, 0xcd, 0xd7, 0xfe, 0xa7, 0x79, 0x42,
+ /*81f0:*/ 0x85, 0x63, 0x40, 0x44, 0x65, 0x1b, 0x83, 0x70, 0x16, 0x1f, 0xc0, 0xf1, 0xb2, 0x49, 0x0f, 0x99,
+ /*8200:*/ 0x40, 0xbe, 0x21, 0xfa, 0x8e, 0x85, 0xb7, 0x9d, 0xee, 0x28, 0xbc, 0xac, 0x2b, 0x85, 0x3b, 0xdf,
+ /*8210:*/ 0x4a, 0x72, 0x81, 0x6d, 0x0e, 0x75, 0x58, 0x34, 0x41, 0x5b, 0xa3, 0x0f, 0x00, 0x1b, 0x28, 0xcf,
+ /*8220:*/ 0xa7, 0x57, 0x4e, 0x78, 0x41, 0x7c, 0xf9, 0x4e, 0x44, 0xcb, 0x6f, 0x4b, 0x88, 0x84, 0x73, 0x4f,
+ /*8230:*/ 0xfa, 0x4a, 0xc4, 0xa9, 0xad, 0xd7, 0xeb, 0x1d, 0x52, 0xe4, 0xd7, 0xa3, 0xdc, 0x37, 0xae, 0x23,
+ /*8240:*/ 0xe3, 0xa6, 0x91, 0x02, 0x75, 0xf0, 0x16, 0xbb, 0x24, 0x09, 0x15, 0xa3, 0x79, 0xe2, 0xd9, 0x66,
+ /*8250:*/ 0x25, 0x27, 0xe8, 0x5e, 0x72, 0x7d, 0xc6, 0x38, 0xac, 0xfb, 0x62, 0x3b, 0x7d, 0x23, 0xe6, 0xbf,
+ /*8260:*/ 0x94, 0x12, 0x15, 0xcb, 0xd7, 0x73, 0xd7, 0xc9, 0x02, 0xff, 0xa5, 0xae, 0x15, 0x45, 0xc7, 0xfd,
+ /*8270:*/ 0x82, 0x77, 0x54, 0xd3, 0xc0, 0xcb, 0xc6, 0x1c, 0x8d, 0x58, 0x51, 0xd2, 0x82, 0x66, 0x03, 0x84,
+ /*8280:*/ 0x5a, 0x16, 0xad, 0x90, 0x0b, 0x29, 0x98, 0x6c, 0xa1, 0x53, 0xc3, 0x8e, 0x9e, 0x30, 0x61, 0x6f,
+ /*8290:*/ 0xc0, 0xc1, 0x8e, 0x61, 0x67, 0x82, 0x32, 0xb8, 0xa7, 0x4c, 0xa6, 0x78, 0x28, 0x72, 0xed, 0xc9,
+ /*82a0:*/ 0x17, 0x6d, 0xf4, 0xe1, 0x83, 0x9c, 0xa3, 0xc8, 0x57, 0x47, 0xf6, 0x0f, 0xa5, 0x43, 0x36, 0x78,
+ /*82b0:*/ 0x53, 0xd2, 0xf7, 0x75, 0xc2, 0x93, 0xb5, 0x4b, 0x5a, 0xbf, 0xa0, 0xfe, 0x09, 0xb3, 0xa4, 0x69,
+ /*82c0:*/ 0x3e, 0xee, 0x5e, 0xb1, 0xe6, 0x2b, 0xca, 0x21, 0x62, 0xed, 0xf5, 0x3a, 0xa6, 0x3c, 0x41, 0x44,
+ /*82d0:*/ 0x75, 0x03, 0xc8, 0x1e, 0x7f, 0x82, 0x5c, 0x9f, 0x77, 0x72, 0x73, 0xcf, 0xf4, 0x9e, 0x20, 0x63,
+ /*82e0:*/ 0x60, 0xe1, 0x4b, 0x42, 0xb4, 0xa1, 0xdf, 0xda, 0xdc, 0x2e, 0xda, 0x4f, 0xba, 0xf2, 0x2a, 0x44,
+ /*82f0:*/ 0x7a, 0x82, 0x40, 0xb9, 0x5d, 0xa2, 0x61, 0x1e, 0xea, 0xff, 0x9a, 0xd7, 0x85, 0x8b, 0x2a, 0x88,
+ /*8300:*/ 0x6a, 0xbc, 0xdb, 0x16, 0x1b, 0x43, 0x02, 0xbd, 0x36, 0xa1, 0x9e, 0x86, 0x45, 0x15, 0x4b, 0x07,
+ /*8310:*/ 0x05, 0xe0, 0x64, 0x85, 0xda, 0xc3, 0x61, 0xdd, 0xc6, 0xf7, 0xf1, 0x6b, 0xe0, 0xf0, 0x0b, 0xcd,
+ /*8320:*/ 0x6d, 0x6e, 0x33, 0x05, 0xdf, 0x4e, 0x18, 0x79, 0xfc, 0x85, 0x30, 0xf1, 0x04, 0xa8, 0x7a, 0x9a,
+ /*8330:*/ 0xbe, 0x72, 0x8f, 0x92, 0x30, 0xd8, 0x04, 0x19, 0xbc, 0x26, 0xc5, 0xe6, 0x71, 0xd3, 0x4d, 0xfc,
+ /*8340:*/ 0xe8, 0x44, 0xca, 0x60, 0xb6, 0x0a, 0x2f, 0x8a, 0x36, 0x83, 0x54, 0x6f, 0x68, 0xcd, 0xa6, 0x60,
+ /*8350:*/ 0x64, 0xdc, 0xcd, 0xde, 0xeb, 0x92, 0x47, 0x61, 0xce, 0xc7, 0xa9, 0x99, 0xd9, 0xad, 0x4e, 0x4d,
+ /*8360:*/ 0x11, 0xb5, 0x10, 0x46, 0x31, 0x91, 0x66, 0x42, 0xad, 0xe1, 0xb9, 0x79, 0x93, 0x62, 0xde, 0x40,
+ /*8370:*/ 0xd5, 0x1b, 0x74, 0x70, 0x73, 0xb1, 0xa7, 0xa3, 0x85, 0xcd, 0x55, 0x62, 0x8b, 0x2c, 0xf9, 0xcf,
+ /*8380:*/ 0xa5, 0x7f, 0x02, 0x3f, 0x58, 0x04, 0x7c, 0x02, 0x6f, 0x4d, 0xd4, 0x67, 0x95, 0x94, 0xf5, 0x42,
+ /*8390:*/ 0x57, 0xf9, 0xa1, 0x65, 0xc6, 0x2e, 0xb6, 0x7d, 0x1b, 0x93, 0x5b, 0xa3, 0x2d, 0x32, 0x77, 0x6b,
+ /*83a0:*/ 0xb0, 0xcd, 0xd6, 0x9b, 0xd6, 0x11, 0x7b, 0x5b, 0xc5, 0x10, 0x86, 0xc9, 0x74, 0x35, 0xfa, 0x67,
+ /*83b0:*/ 0xbc, 0xea, 0x5d, 0x46, 0x5c, 0xf6, 0x4f, 0xb7, 0x86, 0x58, 0xda, 0x5c, 0x38, 0xf5, 0x68, 0xb8,
+ /*83c0:*/ 0xcf, 0xbb, 0x7e, 0x76, 0x0d, 0xdd, 0x1b, 0x28, 0xcd, 0x4f, 0xb3, 0x99, 0x8c, 0x11, 0xef, 0x6e,
+ /*83d0:*/ 0x1b, 0xf0, 0x81, 0xb4, 0x6b, 0xb9, 0x34, 0xa4, 0x93, 0x5d, 0xf1, 0xca, 0xef, 0x45, 0x60, 0xc2,
+ /*83e0:*/ 0x35, 0xdf, 0x01, 0xcf, 0x2b, 0x3a, 0xb6, 0x1f, 0xd1, 0x8d, 0x3d, 0xe7, 0x12, 0x60, 0xed, 0xc4,
+ /*83f0:*/ 0x0b, 0x36, 0x84, 0xe3, 0x6b, 0x75, 0x09, 0x2a, 0x95, 0xad, 0xa5, 0x37, 0x4f, 0x75, 0xc5, 0x13,
+ /*8400:*/ 0x61, 0x74, 0x17, 0x83, 0x86, 0x94, 0x94, 0xfe, 0x0e, 0x7d, 0xc1, 0x54, 0x6b, 0x13, 0x3b, 0xd9,
+ /*8410:*/ 0x7c, 0xf7, 0x90, 0x56, 0x7d, 0x30, 0x42, 0xd0, 0x82, 0x42, 0xc3, 0x3a, 0x52, 0xdf, 0x70, 0x24,
+ /*8420:*/ 0xb3, 0xcb, 0x25, 0x15, 0x2d, 0x4e, 0xa9, 0xd4, 0x56, 0x33, 0xb9, 0x79, 0xca, 0xbd, 0xcc, 0x56,
+ /*8430:*/ 0x9f, 0x13, 0xc0, 0x44, 0xe4, 0x71, 0xdf, 0x2d, 0xf2, 0x55, 0x49, 0xae, 0x0f, 0x10, 0x4d, 0x03,
+ /*8440:*/ 0x08, 0x59, 0x6d, 0xf9, 0xb1, 0xd8, 0x14, 0x88, 0xdd, 0x0e, 0x0f, 0xa9, 0xbc, 0x5d, 0x74, 0xff,
+ /*8450:*/ 0x9b, 0xf8, 0x8c, 0xbb, 0xdf, 0xb4, 0x60, 0x64, 0x2f, 0x7b, 0x5e, 0x83, 0x52, 0xf5, 0x7a, 0xf7,
+ /*8460:*/ 0x33, 0x50, 0x08, 0x07, 0xb0, 0x2e, 0x7e, 0x88, 0xa8, 0x4b, 0xd2, 0xe5, 0xbc, 0x9c, 0xf2, 0x1b,
+ /*8470:*/ 0x64, 0xe9, 0x1c, 0x65, 0xb4, 0xec, 0x97, 0x0d, 0xd3, 0xa0, 0x8e, 0x02, 0xe9, 0x2b, 0xb1, 0x05,
+ /*8480:*/ 0x74, 0xe9, 0x8c, 0x18, 0x27, 0xcd, 0x6c, 0x59, 0x5d, 0xfd, 0xf3, 0x56, 0x5e, 0x56, 0xd7, 0xf0,
+ /*8490:*/ 0xa4, 0x0a, 0xc0, 0x16, 0x81, 0x07, 0x41, 0xc7, 0xf0, 0xe1, 0x08, 0x1a, 0xf8, 0xa8, 0x0f, 0xa7,
+ /*84a0:*/ 0x23, 0x95, 0xaa, 0x49, 0x3c, 0x5e, 0xb2, 0x7f, 0x69, 0xf3, 0x3d, 0xdd, 0xb4, 0x56, 0x96, 0xdb,
+ /*84b0:*/ 0xea, 0xf2, 0x34, 0xa8, 0xd0, 0xb7, 0x72, 0x98, 0x47, 0x15, 0x93, 0xf6, 0x57, 0x9c, 0xb1, 0x26,
+ /*84c0:*/ 0xf1, 0x00, 0xdf, 0xe8, 0xfb, 0x81, 0x15, 0x0f, 0x8d, 0x33, 0x9e, 0x79, 0x0e, 0x41, 0xf4, 0x16,
+ /*84d0:*/ 0x31, 0xdd, 0xfd, 0xec, 0x7d, 0x4b, 0x7e, 0x3b, 0xd7, 0x71, 0xf1, 0x1c, 0xb2, 0x53, 0x2b, 0x6f,
+ /*84e0:*/ 0xc5, 0x58, 0xf1, 0x50, 0xfe, 0xc3, 0x29, 0x82, 0xd2, 0xf4, 0x7c, 0xd7, 0x42, 0x8a, 0x7a, 0x83,
+ /*84f0:*/ 0x79, 0x42, 0x62, 0xde, 0x92, 0x64, 0x58, 0x6e, 0x9b, 0x24, 0x8d, 0x16, 0xb8, 0xf9, 0x83, 0xf9,
+ /*8500:*/ 0x8a, 0x35, 0x67, 0xf7, 0x07, 0xd5, 0x43, 0xd0, 0xc6, 0x71, 0x35, 0xfb, 0xb5, 0x9f, 0x0d, 0x84,
+ /*8510:*/ 0x9e, 0xa9, 0x69, 0x3b, 0x4e, 0x3c, 0xa3, 0x72, 0xd7, 0x48, 0xaf, 0xae, 0xba, 0xae, 0x4a, 0xf7,
+ /*8520:*/ 0x06, 0xce, 0xf6, 0xc8, 0x41, 0x0a, 0x7e, 0xfb, 0x76, 0xc6, 0xb0, 0xcc, 0xa9, 0xd9, 0xd3, 0xb6,
+ /*8530:*/ 0xfe, 0xc5, 0x62, 0x99, 0x28, 0x03, 0xdb, 0xa8, 0x10, 0xe9, 0xd2, 0x3b, 0x1b, 0xe2, 0xf5, 0x1b,
+ /*8540:*/ 0x81, 0xea, 0xfd, 0xd2, 0x9f, 0x34, 0xc8, 0xca, 0x58, 0x6d, 0x74, 0xbf, 0x2b, 0x53, 0x17, 0xf2,
+ /*8550:*/ 0x64, 0x15, 0xc0, 0x31, 0x77, 0x7a, 0x00, 0xcd, 0x28, 0x72, 0x56, 0x82, 0x81, 0xb8, 0xd8, 0x56,
+ /*8560:*/ 0x0f, 0xe1, 0xa3, 0xc2, 0xf8, 0x78, 0x01, 0x9f, 0x76, 0xd8, 0x77, 0xf6, 0x06, 0x78, 0x4c, 0xf4,
+ /*8570:*/ 0xf8, 0xab, 0x09, 0x9f, 0x81, 0x7c, 0xdf, 0x6c, 0x79, 0x0f, 0xb8, 0xed, 0xec, 0x92, 0x68, 0xb1,
+ /*8580:*/ 0x0d, 0xed, 0x5c, 0x62, 0xe1, 0x94, 0x91, 0xfd, 0x39, 0xbe, 0x65, 0x59, 0x45, 0xfb, 0x59, 0xe1,
+ /*8590:*/ 0xbd, 0xad, 0xbc, 0x41, 0xa0, 0x94, 0x49, 0xec, 0x29, 0x06, 0xe9, 0xd8, 0x64, 0x04, 0xe1, 0x70,
+ /*85a0:*/ 0x31, 0xb9, 0xe4, 0xdf, 0x23, 0xf9, 0x7d, 0x0f, 0x5d, 0x9a, 0xa6, 0x67, 0x4c, 0xde, 0xdd, 0xb6,
+ /*85b0:*/ 0xb2, 0xc5, 0x33, 0x87, 0xee, 0xb8, 0x36, 0xaa, 0x32, 0xdb, 0xc4, 0x90, 0x9b, 0xe0, 0xc2, 0x6c,
+ /*85c0:*/ 0xcd, 0xae, 0xff, 0x7e, 0x9a, 0x35, 0xa7, 0x4e, 0x48, 0xe2, 0x62, 0x1b, 0x0e, 0x7d, 0x9b, 0x44,
+ /*85d0:*/ 0x43, 0xbd, 0x55, 0x82, 0x88, 0x1a, 0x9c, 0x83, 0xfc, 0x1e, 0x3d, 0x8b, 0x6b, 0x29, 0x23, 0xf8,
+ /*85e0:*/ 0x1e, 0xba, 0xb4, 0x5b, 0xc5, 0x80, 0x12, 0x70, 0x48, 0x9b, 0x41, 0xfb, 0xe6, 0xc8, 0xf3, 0x19,
+ /*85f0:*/ 0x15, 0x7b, 0xc0, 0x8d, 0xb0, 0x49, 0x67, 0xcc, 0xf4, 0xe0, 0x12, 0x41, 0xf9, 0xfb, 0xd4, 0x1a,
+ /*8600:*/ 0xe8, 0x72, 0x1b, 0xfc, 0x02, 0xbe, 0x6d, 0x34, 0x96, 0xaf, 0xba, 0x96, 0x44, 0x7d, 0xce, 0x3f,
+ /*8610:*/ 0x0e, 0x58, 0x7b, 0xb1, 0x0d, 0xb7, 0x00, 0x43, 0x6d, 0x81, 0xaa, 0xa6, 0xe4, 0x5c, 0xf1, 0xa4,
+ /*8620:*/ 0x1f, 0xe4, 0xa8, 0x30, 0x2b, 0x0c, 0xbf, 0xdd, 0x69, 0xfa, 0xe7, 0xf7, 0x44, 0xff, 0x50, 0x2b,
+ /*8630:*/ 0x39, 0x73, 0xbd, 0x03, 0x22, 0x84, 0xef, 0x14, 0x08, 0x74, 0xa8, 0x85, 0x05, 0x64, 0xd4, 0xc7,
+ /*8640:*/ 0x30, 0xa4, 0x84, 0x2e, 0xbd, 0x8d, 0x0c, 0xee, 0xfc, 0x11, 0x0f, 0x0c, 0x3f, 0xb1, 0x48, 0x6e,
+ /*8650:*/ 0xb6, 0x09, 0x01, 0xc8, 0x54, 0x6a, 0xe7, 0x1b, 0x46, 0x90, 0x5b, 0x79, 0x64, 0x08, 0xa8, 0xda,
+ /*8660:*/ 0xb0, 0x7e, 0x1f, 0xc3, 0x8c, 0xee, 0x9e, 0x9f, 0x8b, 0x9b, 0xc2, 0x80, 0x2f, 0x4f, 0x0d, 0x3a,
+ /*8670:*/ 0x97, 0x3b, 0xcd, 0xfa, 0xde, 0xa0, 0xaf, 0x6d, 0x1e, 0xd2, 0x47, 0x31, 0xe0, 0xf3, 0xcf, 0x15,
+ /*8680:*/ 0x12, 0xae, 0x45, 0xbb, 0x28, 0x04, 0x5e, 0xf6, 0x2e, 0xab, 0xa5, 0x8f, 0xea, 0xd0, 0xa4, 0xbf,
+ /*8690:*/ 0xbe, 0xa7, 0x77, 0x5d, 0x7b, 0xab, 0x48, 0x5f, 0x1a, 0xe4, 0xc6, 0xb3, 0x62, 0x70, 0xdf, 0x82,
+ /*86a0:*/ 0x24, 0x59, 0xd6, 0x88, 0x5c, 0x36, 0xd6, 0x0c, 0xbe, 0xbc, 0xbd, 0xc6, 0x1a, 0xcb, 0x93, 0xfa,
+ /*86b0:*/ 0xff, 0x16, 0x26, 0xea, 0xd2, 0xd3, 0x41, 0x5a, 0x49, 0x00, 0x99, 0x12, 0x48, 0xbe, 0xa8, 0xc7,
+ /*86c0:*/ 0xe3, 0x5d, 0x3b, 0xb1, 0x40, 0x35, 0xee, 0xfe, 0xc3, 0x78, 0x2b, 0xfe, 0x10, 0x20, 0xc9, 0x96,
+ /*86d0:*/ 0x28, 0xc2, 0xb2, 0x17, 0x03, 0x69, 0x85, 0x74, 0xf5, 0xac, 0x28, 0x02, 0xd0, 0x97, 0x74, 0xf2,
+ /*86e0:*/ 0x22, 0x12, 0x80, 0xf1, 0x1b, 0xd8, 0x49, 0x1d, 0x70, 0x79, 0x56, 0x7a, 0xbb, 0x2e, 0x5b, 0x35,
+ /*86f0:*/ 0x17, 0x34, 0x9b, 0xef, 0xf8, 0x58, 0x8d, 0x4b, 0xf3, 0x9a, 0x7a, 0xb3, 0xf7, 0x8c, 0x08, 0x4c,
+ /*8700:*/ 0x1f, 0xe4, 0x47, 0x30, 0xa2, 0x16, 0x9e, 0xe3, 0x5f, 0xb6, 0x57, 0xb3, 0x93, 0x8f, 0xd0, 0x5e,
+ /*8710:*/ 0x3b, 0x8d, 0x64, 0x70, 0x7c, 0xbc, 0x6e, 0xc0, 0x12, 0x4b, 0x1e, 0xcd, 0x0b, 0x58, 0x5c, 0xed,
+ /*8720:*/ 0x19, 0x2f, 0x72, 0x39, 0xaf, 0x03, 0xaf, 0x8f, 0xe0, 0xc1, 0x3f, 0xcc, 0x8a, 0x9a, 0x95, 0x12,
+ /*8730:*/ 0x7c, 0x88, 0x38, 0x7d, 0x82, 0xdb, 0xbe, 0x58, 0xbb, 0xa8, 0x9b, 0x05, 0x5f, 0x81, 0xe4, 0xaa,
+ /*8740:*/ 0x58, 0x81, 0xdc, 0x5f, 0x8a, 0x7c, 0xc0, 0xbc, 0x57, 0xa8, 0x48, 0xa4, 0x7e, 0xd5, 0x6d, 0xc4,
+ /*8750:*/ 0x04, 0x62, 0xbd, 0x28, 0x0e, 0x5c, 0x97, 0x3b, 0xf2, 0x6f, 0xee, 0xe9, 0x0d, 0x5a, 0x9c, 0x79,
+ /*8760:*/ 0x17, 0xfe, 0xac, 0x66, 0xb0, 0xa6, 0x6e, 0x11, 0x9b, 0xbe, 0x0b, 0xb4, 0x32, 0x67, 0x47, 0x14,
+ /*8770:*/ 0x70, 0xd6, 0x1c, 0x8c, 0x8f, 0x95, 0x96, 0xa8, 0x46, 0x10, 0x82, 0x49, 0xb7, 0x69, 0xb7, 0x40,
+ /*8780:*/ 0x83, 0xad, 0xfa, 0x1f, 0x89, 0x05, 0x8a, 0x16, 0x58, 0xee, 0x9c, 0xfd, 0x9f, 0x0c, 0xc6, 0xca,
+ /*8790:*/ 0xaf, 0x47, 0x5a, 0x00, 0xcd, 0xd6, 0x83, 0x8d, 0x04, 0xf6, 0x18, 0xc7, 0xf3, 0xd2, 0x4c, 0x7c,
+ /*87a0:*/ 0xdf, 0xc8, 0x61, 0xa9, 0x82, 0x96, 0xf3, 0x18, 0x77, 0xe2, 0x0a, 0x2c, 0x77, 0x67, 0x3c, 0x65,
+ /*87b0:*/ 0xd4, 0x56, 0xb0, 0xa6, 0x57, 0x0e, 0x74, 0xc9, 0xb5, 0x5e, 0xde, 0xe3, 0x09, 0x69, 0x53, 0x77,
+ /*87c0:*/ 0xdf, 0xd6, 0x20, 0xba, 0x19, 0xd6, 0x16, 0xbd, 0x4c, 0x95, 0x94, 0x00, 0x4a, 0xf8, 0x72, 0x83,
+ /*87d0:*/ 0x4c, 0xf2, 0x96, 0xa7, 0x1e, 0xf9, 0x62, 0x98, 0x64, 0x1a, 0xa5, 0x40, 0xb1, 0xbe, 0xd5, 0xb6,
+ /*87e0:*/ 0x53, 0x5f, 0xb9, 0xce, 0xa3, 0xcf, 0x03, 0x46, 0x94, 0x85, 0xd8, 0xc4, 0x86, 0x23, 0x85, 0x08,
+ /*87f0:*/ 0x1a, 0x13, 0xa2, 0x41, 0xf6, 0x9d, 0x52, 0xc6, 0xb2, 0x67, 0xe3, 0x30, 0x23, 0xcb, 0x3a, 0x4b,
+ /*8800:*/ 0x41, 0x57, 0x5f, 0xd2, 0x75, 0x8b, 0x5f, 0x44, 0x39, 0x40, 0x34, 0x25, 0xf1, 0xda, 0x0a, 0xb0,
+ /*8810:*/ 0xf0, 0xac, 0x15, 0x8d, 0xee, 0x68, 0x5c, 0x39, 0xbf, 0x48, 0x9a, 0x82, 0xfd, 0x81, 0x45, 0x7e,
+ /*8820:*/ 0xce, 0x81, 0xe6, 0x97, 0x3d, 0xf4, 0x21, 0x8c, 0x9b, 0x36, 0xe6, 0xd0, 0xbf, 0xcc, 0xf2, 0x33,
+ /*8830:*/ 0x4e, 0x98, 0x70, 0x3f, 0x08, 0x52, 0x9f, 0xd4, 0x48, 0xf3, 0x0a, 0xd8, 0x51, 0xfb, 0x39, 0x9b,
+ /*8840:*/ 0x8a, 0xf1, 0x32, 0x55, 0xf0, 0x59, 0x68, 0x17, 0xc8, 0x35, 0xe3, 0x38, 0x8c, 0x40, 0xd4, 0xf7,
+ /*8850:*/ 0xd3, 0xe7, 0x20, 0x07, 0x84, 0xf8, 0xc0, 0x9a, 0x2c, 0x56, 0x6d, 0xaa, 0xae, 0xca, 0x16, 0x82,
+ /*8860:*/ 0x9a, 0xd1, 0x72, 0x2e, 0xd4, 0x12, 0xda, 0x65, 0xe6, 0x78, 0x01, 0x79, 0x16, 0xa2, 0x05, 0x45,
+ /*8870:*/ 0x0b, 0xbc, 0x65, 0xd4, 0xf5, 0x19, 0x9d, 0x1f, 0xa4, 0x49, 0x02, 0xe3, 0x0f, 0x1a, 0x82, 0x49,
+ /*8880:*/ 0x2c, 0xd2, 0x22, 0xdf, 0x97, 0x7d, 0xe6, 0xaf, 0x14, 0x03, 0xdf, 0x69, 0xe6, 0xf3, 0x07, 0x50,
+ /*8890:*/ 0x48, 0xe5, 0x42, 0xfe, 0xe3, 0x59, 0x91, 0x6d, 0xbc, 0xf6, 0xd1, 0xf0, 0x2a, 0xbd, 0x0a, 0x4d,
+ /*88a0:*/ 0x4f, 0x51, 0x6e, 0x0f, 0x76, 0xef, 0xa8, 0xb5, 0xa7, 0x8b, 0x49, 0xf3, 0xd5, 0x8e, 0xf4, 0x41,
+ /*88b0:*/ 0xf9, 0x57, 0x26, 0x2f, 0xcf, 0xa8, 0xd7, 0x76, 0x36, 0xd1, 0xf1, 0xb9, 0x26, 0x79, 0x92, 0xaf,
+ /*88c0:*/ 0xcc, 0xf6, 0xe9, 0xab, 0xf2, 0x96, 0xec, 0x5e, 0xbb, 0xcc, 0xf0, 0x89, 0x39, 0xc1, 0x83, 0x8f,
+ /*88d0:*/ 0xf5, 0x07, 0xb6, 0x17, 0x61, 0x17, 0x1c, 0xcd, 0xb6, 0x3b, 0xcc, 0x68, 0x8d, 0x52, 0x96, 0x18,
+ /*88e0:*/ 0xbf, 0x18, 0x00, 0xcf, 0xf5, 0x9c, 0x81, 0x20, 0xb0, 0xed, 0x63, 0xef, 0x1e, 0xa2, 0xac, 0x84,
+ /*88f0:*/ 0x19, 0xd8, 0x9a, 0x28, 0x68, 0x27, 0xb1, 0x99, 0x54, 0x4b, 0xe4, 0x0b, 0xcc, 0x55, 0x9e, 0x49,
+ /*8900:*/ 0xdb, 0xbc, 0x4d, 0x85, 0x1d, 0x83, 0x83, 0x46, 0x64, 0x27, 0xe1, 0x6d, 0x25, 0x24, 0x72, 0xfe,
+ /*8910:*/ 0xfb, 0x37, 0x67, 0x48, 0xf0, 0x7f, 0x7a, 0xbc, 0x9c, 0x9b, 0xa6, 0xe0, 0x55, 0xa4, 0x98, 0x3b,
+ /*8920:*/ 0x8e, 0xbe, 0x5b, 0x92, 0x29, 0x5e, 0xcd, 0x46, 0xcd, 0x83, 0x43, 0xfb, 0x8a, 0xaf, 0x68, 0x89,
+ /*8930:*/ 0xc6, 0x68, 0x32, 0x83, 0x7c, 0x33, 0x6e, 0xf9, 0x8f, 0x53, 0x40, 0xda, 0x2c, 0x6f, 0xcc, 0x7a,
+ /*8940:*/ 0xd7, 0x90, 0xd7, 0xc0, 0x29, 0x9d, 0xb7, 0x08, 0xe0, 0xa4, 0x41, 0x25, 0x7e, 0x39, 0x04, 0xf3,
+ /*8950:*/ 0x02, 0xb8, 0x4e, 0x3e, 0xee, 0x80, 0x07, 0x20, 0xdc, 0x49, 0x16, 0x9e, 0xab, 0xb0, 0x81, 0xd3,
+ /*8960:*/ 0x33, 0x00, 0xfe, 0xf6, 0x85, 0xcd, 0xf8, 0xe6, 0x79, 0x87, 0x1a, 0x5b, 0x1e, 0x11, 0x1b, 0xca,
+ /*8970:*/ 0x89, 0x35, 0xa5, 0x3a, 0x98, 0x0f, 0x4d, 0x20, 0x25, 0xe4, 0xbf, 0x48, 0x6d, 0x2c, 0x03, 0x97,
+ /*8980:*/ 0xff, 0xbb, 0x85, 0x3b, 0x1f, 0x17, 0x4f, 0xd6, 0xf4, 0xd4, 0xb8, 0x80, 0x49, 0x1a, 0x52, 0x26,
+ /*8990:*/ 0xbd, 0x81, 0x41, 0xe8, 0xc3, 0x63, 0x67, 0xf3, 0xe5, 0xeb, 0x57, 0xbe, 0x28, 0x83, 0xef, 0x3f,
+ /*89a0:*/ 0xcc, 0xff, 0x4f, 0xed, 0x19, 0xce, 0xe9, 0xe5, 0x0d, 0x1e, 0x0c, 0xd3, 0x8d, 0xed, 0xa3, 0x47,
+ /*89b0:*/ 0xb7, 0x1d, 0x63, 0x61, 0xc7, 0xfe, 0x36, 0xfa, 0x05, 0x30, 0xd9, 0x36, 0x04, 0xb8, 0x05, 0x1b,
+ /*89c0:*/ 0x89, 0xf3, 0xc0, 0x81, 0x07, 0xd5, 0xdf, 0x7f, 0x17, 0x5c, 0xaf, 0x75, 0x35, 0xeb, 0x2b, 0xac,
+ /*89d0:*/ 0x48, 0xd6, 0x07, 0xe7, 0x72, 0x3e, 0xa6, 0x30, 0x75, 0x77, 0x03, 0x74, 0x31, 0xe5, 0x8b, 0x10,
+ /*89e0:*/ 0xd0, 0x2a, 0x3c, 0xc7, 0x7d, 0xd4, 0x4e, 0xa5, 0xc9, 0xc7, 0xd1, 0xb8, 0xdb, 0x9d, 0x34, 0xbb,
+ /*89f0:*/ 0xce, 0x26, 0x16, 0x60, 0x38, 0x95, 0x28, 0x78, 0x60, 0xcb, 0x3f, 0xbd, 0xaa, 0x93, 0xed, 0xb3,
+ /*8a00:*/ 0x0d, 0xd0, 0x8c, 0xf4, 0x69, 0x24, 0x35, 0x84, 0x60, 0x2b, 0x48, 0x5b, 0x9a, 0x7e, 0xb8, 0xe1,
+ /*8a10:*/ 0xec, 0x6a, 0x17, 0x17, 0xb9, 0xdc, 0x5d, 0xa9, 0xf2, 0x95, 0x7f, 0xf5, 0xe7, 0x6c, 0x79, 0x93,
+ /*8a20:*/ 0xab, 0xb2, 0x52, 0x1a, 0x39, 0x5b, 0x3e, 0x49, 0x18, 0x19, 0x3c, 0xe7, 0x7e, 0xf4, 0x95, 0x96,
+ /*8a30:*/ 0x79, 0x30, 0xc0, 0x3f, 0x7a, 0xde, 0x28, 0xd9, 0x95, 0xe3, 0x69, 0x5b, 0xa5, 0x10, 0xb3, 0xe6,
+ /*8a40:*/ 0x1c, 0x01, 0xcc, 0xd4, 0xf2, 0x58, 0x76, 0x52, 0x9b, 0x1e, 0xa1, 0x90, 0xb0, 0xa4, 0x8e, 0x3e,
+ /*8a50:*/ 0x9f, 0x46, 0x9e, 0xa8, 0x75, 0x15, 0xe7, 0xfb, 0xf8, 0x5b, 0xb4, 0x55, 0x92, 0x12, 0x1b, 0x07,
+ /*8a60:*/ 0xb0, 0xe9, 0x0e, 0xf7, 0xf6, 0x1c, 0x7b, 0x31, 0x35, 0x2c, 0x3f, 0x12, 0x08, 0x1f, 0xe5, 0xf7,
+ /*8a70:*/ 0x7c, 0x9a, 0x32, 0xa2, 0xa5, 0x5c, 0x49, 0x54, 0x52, 0x0d, 0xca, 0xeb, 0x2c, 0x5e, 0x0d, 0xf2,
+ /*8a80:*/ 0x54, 0x10, 0x6b, 0x8f, 0x81, 0x1d, 0x56, 0x6e, 0x62, 0x7b, 0xfa, 0xe5, 0x65, 0x85, 0x71, 0xde,
+ /*8a90:*/ 0x53, 0x5e, 0x8a, 0x39, 0xed, 0x01, 0x3d, 0xe0, 0x37, 0x22, 0x1d, 0xd5, 0x6d, 0x94, 0xee, 0x8b,
+ /*8aa0:*/ 0x26, 0x8b, 0xe4, 0xf9, 0x2e, 0x14, 0xe8, 0x33, 0x59, 0xd1, 0x91, 0x32, 0x4a, 0x57, 0x4b, 0x8a,
+ /*8ab0:*/ 0x81, 0xbc, 0x57, 0x87, 0xe4, 0xa2, 0x73, 0x27, 0xd5, 0x25, 0x7b, 0x25, 0x09, 0x58, 0x29, 0xd5,
+ /*8ac0:*/ 0xb2, 0x7a, 0x3b, 0x59, 0x00, 0xf3, 0xba, 0x38, 0x72, 0xa2, 0xd3, 0x0e, 0x92, 0x0f, 0xbd, 0x9d,
+ /*8ad0:*/ 0x08, 0xbb, 0xe1, 0xdd, 0x55, 0x7c, 0xd7, 0xaa, 0xf6, 0x23, 0x2f, 0x21, 0xba, 0x7a, 0x4c, 0xe6,
+ /*8ae0:*/ 0xf6, 0x21, 0x8a, 0x3f, 0x28, 0xfa, 0x5d, 0x78, 0x4a, 0xba, 0x36, 0x1f, 0xdc, 0xeb, 0xa4, 0x25,
+ /*8af0:*/ 0x4a, 0x5c, 0x19, 0xab, 0xaf, 0x78, 0x25, 0x85, 0x5d, 0x2c, 0x56, 0x91, 0xb2, 0xc2, 0x4c, 0xd1,
+ /*8b00:*/ 0x12, 0x1b, 0x0f, 0xcf, 0x71, 0x79, 0x3f, 0x39, 0xd4, 0x0c, 0x02, 0xef, 0x4c, 0x77, 0x61, 0xb2,
+ /*8b10:*/ 0x3e, 0x7e, 0x2e, 0x89, 0x23, 0x88, 0x61, 0xd2, 0xb7, 0x7b, 0xe0, 0xfa, 0x91, 0xa6, 0x7b, 0x20,
+ /*8b20:*/ 0x26, 0x37, 0xbd, 0xd0, 0xaa, 0x0c, 0x6b, 0x9a, 0x12, 0x3a, 0xf6, 0xff, 0x39, 0x7f, 0x41, 0xee,
+ /*8b30:*/ 0x8b, 0xd3, 0xc6, 0x0e, 0x0e, 0xc1, 0x73, 0x60, 0x7e, 0xd0, 0x65, 0x4b, 0x47, 0x16, 0x17, 0xcd,
+ /*8b40:*/ 0x6d, 0x4d, 0x6e, 0x24, 0xdd, 0x1f, 0x24, 0x4c, 0x2a, 0xb1, 0x09, 0xf7, 0x77, 0xb6, 0x18, 0xe2,
+ /*8b50:*/ 0xa6, 0xd7, 0x2f, 0x41, 0xf8, 0x87, 0xb2, 0x89, 0x86, 0x60, 0xdc, 0x55, 0x0f, 0xbe, 0x68, 0xa9,
+ /*8b60:*/ 0x3c, 0x3e, 0xc1, 0xd9, 0x2b, 0x92, 0x1e, 0xb1, 0xe9, 0x97, 0xfc, 0xc8, 0xe9, 0x0a, 0xdc, 0xa6,
+ /*8b70:*/ 0x43, 0xe8, 0xc1, 0xeb, 0x02, 0x54, 0x9f, 0x94, 0xaa, 0xf2, 0xef, 0x72, 0xa3, 0x5b, 0x96, 0xfe,
+ /*8b80:*/ 0x33, 0xc5, 0x04, 0x0f, 0x37, 0x1c, 0x77, 0x5d, 0x53, 0x7c, 0xa3, 0x42, 0x0c, 0x40, 0x4a, 0x50,
+ /*8b90:*/ 0xc6, 0x44, 0x1e, 0xdd, 0x1c, 0x27, 0x87, 0x8f, 0x79, 0x8f, 0x2b, 0x7e, 0x2c, 0x2c, 0x08, 0xaf,
+ /*8ba0:*/ 0xc6, 0xcb, 0x68, 0xbe, 0xc7, 0x41, 0x9e, 0x01, 0xf5, 0x51, 0x04, 0xa2, 0x52, 0xb0, 0x58, 0xa6,
+ /*8bb0:*/ 0xc3, 0xd9, 0xf8, 0xe5, 0xe5, 0x60, 0x5a, 0x42, 0x1c, 0x92, 0x71, 0x27, 0x2b, 0x1b, 0x7b, 0xad,
+ /*8bc0:*/ 0x32, 0x24, 0x3e, 0x75, 0xa2, 0x64, 0xaa, 0x8e, 0xe1, 0x96, 0x6e, 0x80, 0xf7, 0x6f, 0xdb, 0xce,
+ /*8bd0:*/ 0xa8, 0xd5, 0x4a, 0x8b, 0xd4, 0x29, 0x10, 0x03, 0x17, 0x38, 0x5f, 0xdc, 0xca, 0xd7, 0xeb, 0xac,
+ /*8be0:*/ 0x45, 0x3d, 0xb8, 0x1b, 0x20, 0xae, 0x91, 0x6b, 0x63, 0xc7, 0xe4, 0x69, 0x94, 0xb9, 0x41, 0xe8,
+ /*8bf0:*/ 0xdc, 0x67, 0xb8, 0x0a, 0xfa, 0x72, 0x4e, 0x23, 0x12, 0xd9, 0xb1, 0x13, 0xf7, 0x53, 0xf6, 0x2b,
+ /*8c00:*/ 0x89, 0x06, 0x80, 0x67, 0x02, 0xc5, 0x4b, 0xbd, 0xaf, 0x60, 0x73, 0x90, 0x00, 0xd3, 0xfc, 0x9e,
+ /*8c10:*/ 0x59, 0x76, 0xaf, 0x70, 0x44, 0xd9, 0xae, 0x1a, 0x6b, 0xa7, 0x56, 0xad, 0x1b, 0xc2, 0xe6, 0xd5,
+ /*8c20:*/ 0xbc, 0x6f, 0x4a, 0xd9, 0x59, 0x11, 0xc1, 0xc5, 0xaf, 0x36, 0x26, 0x93, 0xd6, 0x20, 0x72, 0x61,
+ /*8c30:*/ 0x8e, 0xb6, 0x84, 0xab, 0x54, 0xcb, 0x7c, 0xf6, 0x84, 0x3b, 0x09, 0x3a, 0x46, 0x2f, 0xc6, 0x95,
+ /*8c40:*/ 0x07, 0x5f, 0xda, 0xf6, 0x8b, 0x30, 0x6d, 0xd9, 0xbb, 0x6f, 0x13, 0xea, 0x81, 0xa3, 0xd5, 0x72,
+ /*8c50:*/ 0x46, 0x43, 0x53, 0xe5, 0xbd, 0x02, 0x9c, 0x1d, 0x29, 0x94, 0x97, 0x01, 0xce, 0x6a, 0x76, 0x7b,
+ /*8c60:*/ 0xc3, 0xa5, 0x2f, 0xcf, 0xe4, 0x81, 0x32, 0xb5, 0x9f, 0xa1, 0x98, 0xea, 0xab, 0xe9, 0x6c, 0x8a,
+ /*8c70:*/ 0x37, 0x4e, 0x9e, 0x10, 0x1b, 0x87, 0xbd, 0x06, 0x77, 0xd5, 0x79, 0x79, 0xe3, 0x6d, 0x4e, 0x96,
+ /*8c80:*/ 0x51, 0x56, 0xd6, 0x18, 0x93, 0xe8, 0x69, 0xb4, 0x50, 0xf6, 0x61, 0xfc, 0x67, 0xdf, 0x82, 0xd4,
+ /*8c90:*/ 0x99, 0x06, 0x16, 0x97, 0x95, 0xd6, 0x43, 0xd6, 0x31, 0x4f, 0xb7, 0xeb, 0x2f, 0x3a, 0x3b, 0x1a,
+ /*8ca0:*/ 0xd9, 0xe2, 0xa1, 0xca, 0xbb, 0x76, 0x48, 0xe3, 0x47, 0xcc, 0xbe, 0x67, 0x24, 0xa2, 0xd0, 0x9a,
+ /*8cb0:*/ 0x7c, 0x30, 0x4f, 0x1b, 0x85, 0x08, 0xc9, 0xec, 0x98, 0x65, 0xb0, 0x93, 0x10, 0x1c, 0xca, 0x83,
+ /*8cc0:*/ 0x2d, 0x00, 0x68, 0x96, 0x39, 0x3f, 0x3f, 0x7c, 0x42, 0x6b, 0x6f, 0x41, 0x3f, 0xf3, 0x29, 0x66,
+ /*8cd0:*/ 0x98, 0xfb, 0x14, 0x3c, 0x8b, 0xd9, 0x5f, 0xdd, 0xe7, 0x8d, 0xbd, 0x40, 0x5a, 0x12, 0x41, 0x0c,
+ /*8ce0:*/ 0xd8, 0x02, 0x89, 0xc1, 0x65, 0x1b, 0xb2, 0x79, 0x6b, 0x98, 0x50, 0xff, 0xc8, 0xf0, 0x67, 0x66,
+ /*8cf0:*/ 0x51, 0xb8, 0x05, 0xc9, 0x1a, 0xcc, 0x7e, 0x28, 0x22, 0xc7, 0x11, 0xf6, 0xfc, 0x71, 0xeb, 0x97,
+ /*8d00:*/ 0x4b, 0x51, 0x53, 0x25, 0x88, 0xc9, 0x5e, 0x11, 0x84, 0x79, 0x4e, 0xf2, 0x02, 0x2f, 0xa6, 0x7e,
+ /*8d10:*/ 0x82, 0x65, 0x34, 0xfa, 0xd6, 0x33, 0xfe, 0xaa, 0x95, 0xe5, 0xb3, 0xd1, 0x5e, 0xf6, 0xdf, 0x96,
+ /*8d20:*/ 0x20, 0x29, 0xd6, 0xd4, 0xc1, 0x5c, 0x53, 0x2b, 0x4c, 0x32, 0xf4, 0xae, 0xfc, 0x69, 0x53, 0xfc,
+ /*8d30:*/ 0x2a, 0x7e, 0x83, 0xfb, 0x8f, 0x35, 0xe2, 0xd9, 0x5c, 0x12, 0x22, 0x5c, 0xc0, 0x75, 0x8a, 0x23,
+ /*8d40:*/ 0x8d, 0x63, 0xc8, 0xa9, 0x69, 0x40, 0x9c, 0x29, 0x22, 0xe9, 0x6a, 0x2b, 0x0c, 0xb7, 0xc8, 0x79,
+ /*8d50:*/ 0xb6, 0xcd, 0xaf, 0xac, 0x91, 0x96, 0x78, 0xb6, 0x29, 0x0b, 0xbd, 0x76, 0xd5, 0x2e, 0xcc, 0x39,
+ /*8d60:*/ 0x3b, 0xcc, 0xb1, 0xff, 0x91, 0xb9, 0xab, 0xcb, 0x34, 0xfb, 0xcf, 0xaf, 0xe3, 0xde, 0xb2, 0x37,
+ /*8d70:*/ 0xb5, 0x79, 0x47, 0xb3, 0xac, 0x9b, 0x20, 0xc4, 0xda, 0x7d, 0x6f, 0x49, 0x6f, 0x8b, 0xe3, 0x4b,
+ /*8d80:*/ 0x31, 0x23, 0x28, 0x63, 0x08, 0x59, 0x23, 0xf1, 0xa5, 0xea, 0x64, 0x08, 0x88, 0x34, 0xf3, 0x39,
+ /*8d90:*/ 0x62, 0xe8, 0x7a, 0x18, 0xed, 0x25, 0xa4, 0x68, 0x3d, 0xa6, 0x64, 0x0d, 0xdc, 0x99, 0x05, 0xc9,
+ /*8da0:*/ 0xb0, 0x9e, 0xc3, 0xe3, 0xa2, 0x9e, 0xc7, 0x92, 0x7a, 0xe1, 0xdd, 0x0e, 0x9d, 0x71, 0x6c, 0xf5,
+ /*8db0:*/ 0x73, 0xa5, 0xf9, 0xdf, 0x94, 0x49, 0xa3, 0x23, 0x73, 0xe0, 0x51, 0x6d, 0x0f, 0x9e, 0x1a, 0x87,
+ /*8dc0:*/ 0x3a, 0xef, 0xa4, 0x63, 0x13, 0x79, 0x7a, 0x2d, 0x0f, 0x7c, 0x88, 0x8b, 0xb1, 0x65, 0xbf, 0x0a,
+ /*8dd0:*/ 0xb5, 0x21, 0xc4, 0x7c, 0x65, 0xe3, 0x52, 0x1d, 0xa2, 0xf6, 0x1d, 0x93, 0x84, 0x86, 0x7a, 0xe8,
+ /*8de0:*/ 0x5f, 0x72, 0x4b, 0x85, 0x48, 0x8f, 0x23, 0x93, 0x7f, 0xdd, 0xef, 0x17, 0x46, 0x5d, 0xbe, 0xc0,
+ /*8df0:*/ 0x67, 0xbd, 0xe4, 0xd7, 0xc9, 0xca, 0x2e, 0xc6, 0x8b, 0xc3, 0x82, 0x28, 0x0f, 0xa6, 0x22, 0x9c,
+ /*8e00:*/ 0xaf, 0x0c, 0xa2, 0x5f, 0xe6, 0x91, 0x72, 0x6b, 0x43, 0x44, 0xd5, 0x8c, 0xd5, 0x55, 0xc2, 0x6a,
+ /*8e10:*/ 0x95, 0xe0, 0x42, 0x22, 0x41, 0xe7, 0xd5, 0x2a, 0xfa, 0xf7, 0xaa, 0x74, 0x29, 0x4f, 0x87, 0x2c,
+ /*8e20:*/ 0x38, 0x6a, 0x4a, 0x07, 0x38, 0xfd, 0x8c, 0xe2, 0x8d, 0xd8, 0x2b, 0x2e, 0xe7, 0x2b, 0xbc, 0x02,
+ /*8e30:*/ 0x22, 0xa1, 0x26, 0xce, 0x57, 0xab, 0x9b, 0x20, 0x02, 0x43, 0xaf, 0xb5, 0x73, 0x95, 0xc1, 0x5a,
+ /*8e40:*/ 0xe2, 0xe3, 0x7f, 0x60, 0x04, 0xab, 0xa3, 0x21, 0xf8, 0x18, 0xdb, 0x6b, 0x01, 0xdf, 0x6a, 0xac,
+ /*8e50:*/ 0xdb, 0x37, 0xa4, 0xdd, 0x4b, 0x0e, 0xfa, 0x39, 0xed, 0x64, 0xfb, 0xfc, 0x98, 0xe7, 0x71, 0x02,
+ /*8e60:*/ 0xdd, 0xbb, 0xa5, 0x62, 0x7e, 0x18, 0x16, 0xe1, 0x6e, 0xbd, 0x1d, 0xb3, 0xc5, 0x11, 0xd2, 0xdb,
+ /*8e70:*/ 0x20, 0x1f, 0x3a, 0x84, 0xda, 0x08, 0x7d, 0x58, 0x50, 0xc3, 0x3c, 0x5c, 0x7c, 0xc9, 0xb8, 0x78,
+ /*8e80:*/ 0x03, 0x57, 0x93, 0x71, 0x71, 0x28, 0xaf, 0x84, 0xd6, 0x89, 0xa2, 0xd4, 0x01, 0xcb, 0x26, 0x1b,
+ /*8e90:*/ 0x0a, 0x35, 0x38, 0xf8, 0x77, 0xb1, 0x09, 0x03, 0xb7, 0x1a, 0x0d, 0xb2, 0x82, 0x90, 0x22, 0x05,
+ /*8ea0:*/ 0x19, 0x63, 0x66, 0x58, 0x4a, 0xf9, 0x2f, 0x2f, 0xe2, 0xbb, 0x2b, 0x31, 0xca, 0xdc, 0x96, 0x47,
+ /*8eb0:*/ 0x88, 0x7d, 0x62, 0x75, 0xe6, 0x96, 0xf3, 0xa2, 0x1e, 0x62, 0x59, 0xff, 0x24, 0xbe, 0x2f, 0x8f,
+ /*8ec0:*/ 0xdf, 0xd5, 0x72, 0xfc, 0x0f, 0xc8, 0x10, 0x48, 0xa2, 0x90, 0xe0, 0x1a, 0xa2, 0x0c, 0x80, 0x80,
+ /*8ed0:*/ 0xda, 0xb8, 0x2f, 0x8c, 0xc4, 0x07, 0x49, 0x7a, 0x29, 0xf5, 0xbb, 0x02, 0x49, 0xc0, 0xa5, 0x5c,
+ /*8ee0:*/ 0x54, 0x6f, 0x05, 0xb6, 0x48, 0x1c, 0x41, 0xc9, 0xa2, 0x19, 0xab, 0xc4, 0x39, 0x6d, 0xf7, 0x7b,
+ /*8ef0:*/ 0x22, 0xc0, 0xbd, 0xbf, 0xd7, 0x88, 0x46, 0xe4, 0x18, 0x42, 0x06, 0xea, 0x45, 0xcb, 0x6a, 0xe1,
+ /*8f00:*/ 0x23, 0xe6, 0x93, 0x32, 0x7a, 0x56, 0x90, 0x80, 0xa9, 0xb1, 0xe3, 0x47, 0x6f, 0x71, 0x17, 0xb2,
+ /*8f10:*/ 0x6f, 0x5b, 0x23, 0x7a, 0x22, 0xea, 0xeb, 0xd1, 0x52, 0xed, 0x41, 0x71, 0xf5, 0x16, 0x98, 0x3a,
+ /*8f20:*/ 0x57, 0x79, 0x86, 0x99, 0xbf, 0xbe, 0xd2, 0x6b, 0x9d, 0x2a, 0x14, 0x61, 0x03, 0x5e, 0x4b, 0x5f,
+ /*8f30:*/ 0x02, 0x59, 0x22, 0x37, 0x13, 0x79, 0x7d, 0x47, 0xca, 0xc4, 0xe9, 0xa9, 0x0f, 0x33, 0x89, 0x72,
+ /*8f40:*/ 0x86, 0x3a, 0x79, 0x68, 0x17, 0x63, 0x6a, 0x0d, 0x50, 0x59, 0xd3, 0xb8, 0x3f, 0x32, 0x84, 0x6a,
+ /*8f50:*/ 0x7c, 0x11, 0x65, 0xb1, 0x34, 0xb6, 0x6a, 0x9f, 0x59, 0x28, 0xdd, 0xe8, 0xef, 0x10, 0x2a, 0x65,
+ /*8f60:*/ 0xde, 0x73, 0x8e, 0x15, 0x64, 0xcf, 0x99, 0xa9, 0x01, 0xdb, 0x79, 0x12, 0x99, 0x9b, 0x66, 0x0c,
+ /*8f70:*/ 0x5b, 0x2f, 0x31, 0xd4, 0xdd, 0x74, 0x8b, 0x64, 0x3e, 0x7e, 0xee, 0x85, 0xac, 0xcb, 0x94, 0x8a,
+ /*8f80:*/ 0xfb, 0xc8, 0x87, 0xce, 0xeb, 0x18, 0x23, 0xd4, 0x13, 0x4c, 0x22, 0xeb, 0x2d, 0x71, 0x7e, 0xd6,
+ /*8f90:*/ 0x4f, 0x06, 0x85, 0xf2, 0xf7, 0x4d, 0x39, 0xc3, 0x11, 0x33, 0x2a, 0x9e, 0xf8, 0x3c, 0xde, 0xef,
+ /*8fa0:*/ 0x06, 0xbe, 0xcd, 0x77, 0x21, 0xeb, 0xb0, 0xd6, 0xcf, 0x41, 0xd2, 0xd9, 0xb5, 0x8c, 0xa9, 0x51,
+ /*8fb0:*/ 0xae, 0x17, 0xe0, 0xb0, 0x60, 0x3f, 0x62, 0x82, 0x71, 0x28, 0x7e, 0xb9, 0x6d, 0x17, 0x26, 0xde,
+ /*8fc0:*/ 0xb0, 0x98, 0xeb, 0x35, 0x28, 0xb9, 0x1e, 0xd5, 0x82, 0xf7, 0xaf, 0xa2, 0x3b, 0xb7, 0xbe, 0xfd,
+ /*8fd0:*/ 0x4d, 0x68, 0x6a, 0x20, 0x61, 0x50, 0x47, 0xb2, 0x4a, 0x42, 0x7a, 0xfa, 0x29, 0xcc, 0x9e, 0x2f,
+ /*8fe0:*/ 0xd9, 0x50, 0x5b, 0xac, 0x1d, 0x02, 0x90, 0xd9, 0xe5, 0xe8, 0x51, 0x12, 0xe8, 0x3b, 0xb9, 0x06,
+ /*8ff0:*/ 0x93, 0xb5, 0x3c, 0xa3, 0xdf, 0x96, 0xd1, 0x07, 0xb5, 0xf7, 0x6d, 0xcd, 0x6e, 0x2c, 0xd3, 0x89,
+ /*9000:*/ 0xcd, 0x97, 0xfb, 0x6a, 0x85, 0xcf, 0x10, 0x46, 0xdc, 0xc6, 0xde, 0x2d, 0x28, 0x1a, 0xe7, 0x1a,
+ /*9010:*/ 0x6a, 0x19, 0x84, 0x67, 0x2d, 0x47, 0xb2, 0x05, 0xca, 0xe2, 0x74, 0xf6, 0xbc, 0x62, 0x15, 0x74,
+ /*9020:*/ 0x19, 0x15, 0x04, 0x73, 0xd1, 0x52, 0xe6, 0x57, 0xbf, 0x05, 0x0b, 0xe4, 0x38, 0x0c, 0x7c, 0x7b,
+ /*9030:*/ 0x87, 0x7c, 0xa0, 0xd3, 0x14, 0x94, 0xcc, 0x4d, 0x73, 0x12, 0xac, 0x5e, 0x7d, 0x74, 0xb3, 0x43,
+ /*9040:*/ 0xe1, 0x88, 0xca, 0x1d, 0x3d, 0x1c, 0xa1, 0x11, 0x83, 0xea, 0xf0, 0x72, 0x29, 0xda, 0xbe, 0xd3,
+ /*9050:*/ 0x98, 0xd2, 0xd8, 0xd6, 0x71, 0x9c, 0x7b, 0x44, 0xb8, 0x3c, 0xf6, 0x04, 0xc5, 0x32, 0xb8, 0x4e,
+ /*9060:*/ 0xb9, 0xcd, 0x59, 0x36, 0xe8, 0xd1, 0x63, 0x70, 0xd6, 0x5d, 0x0d, 0x49, 0xc8, 0x0e, 0xb6, 0x28,
+ /*9070:*/ 0x68, 0x67, 0xe8, 0x0c, 0x8c, 0x2f, 0x74, 0xfd, 0x56, 0x1d, 0x65, 0xaf, 0x33, 0xba, 0xf4, 0xe0,
+ /*9080:*/ 0x8c, 0xff, 0x5e, 0x96, 0x4c, 0xa9, 0x25, 0xde, 0x03, 0x8d, 0x38, 0xc6, 0xba, 0x40, 0xf8, 0xdf,
+ /*9090:*/ 0x93, 0xb4, 0x50, 0x58, 0x42, 0x73, 0x91, 0xad, 0xb4, 0x6f, 0x25, 0x0b, 0x7f, 0x5a, 0xd0, 0x69,
+ /*90a0:*/ 0x0e, 0x44, 0xbc, 0x27, 0xcc, 0x14, 0x07, 0xeb, 0x11, 0x20, 0x05, 0x3b, 0xf0, 0x73, 0x51, 0xc2,
+ /*90b0:*/ 0x3e, 0xbb, 0x85, 0xc9, 0xd7, 0xea, 0xd0, 0x0e, 0x25, 0xa1, 0x41, 0xe1, 0x70, 0xbd, 0xae, 0x81,
+ /*90c0:*/ 0xcc, 0x2b, 0x19, 0x39, 0x3b, 0xb3, 0x65, 0x2b, 0xd7, 0x9d, 0x94, 0xb3, 0xe1, 0xe7, 0xa5, 0xde,
+ /*90d0:*/ 0xd5, 0xe8, 0xb7, 0xc3, 0x4d, 0xbb, 0x32, 0x71, 0xa3, 0xfc, 0xb0, 0x6c, 0x8e, 0x20, 0xe7, 0xeb,
+ /*90e0:*/ 0x88, 0xc8, 0xa4, 0x76, 0xe8, 0xd5, 0xb1, 0x24, 0xbb, 0xa4, 0x35, 0xc8, 0x74, 0xb5, 0x3b, 0xba,
+ /*90f0:*/ 0x08, 0xbc, 0xbd, 0xcd, 0xe6, 0x0e, 0x71, 0x32, 0x0e, 0x88, 0x52, 0xfa, 0x45, 0xe7, 0x02, 0x3b,
+ /*9100:*/ 0x11, 0x5d, 0x8c, 0x07, 0x14, 0xc1, 0x68, 0x05, 0xc2, 0x4f, 0x03, 0x1c, 0x17, 0xa6, 0x38, 0xa1,
+ /*9110:*/ 0x9d, 0x07, 0xb0, 0xb3, 0x00, 0xab, 0x98, 0x89, 0x79, 0xd3, 0x8b, 0xb2, 0x93, 0x6b, 0x30, 0xf4,
+ /*9120:*/ 0x0c, 0xbd, 0xe3, 0x79, 0x3d, 0x1e, 0x3a, 0x75, 0xf8, 0x67, 0x3f, 0xd9, 0x20, 0x07, 0x22, 0xe6,
+ /*9130:*/ 0xc1, 0x4f, 0x85, 0x56, 0x68, 0xaa, 0xd1, 0x70, 0xd9, 0x3c, 0x24, 0xee, 0xdf, 0xcc, 0x1c, 0xda,
+ /*9140:*/ 0x76, 0xf5, 0x18, 0xd1, 0x53, 0x43, 0x3c, 0x1a, 0x51, 0xa4, 0x34, 0xce, 0xde, 0x4d, 0xfb, 0xee,
+ /*9150:*/ 0x8e, 0xca, 0xb7, 0x36, 0xae, 0x68, 0xcc, 0x22, 0x8b, 0xec, 0x66, 0xba, 0xcd, 0x93, 0x41, 0x75,
+ /*9160:*/ 0xc5, 0xba, 0x92, 0x23, 0xde, 0x1b, 0xc4, 0xc8, 0x75, 0xcb, 0xcc, 0x14, 0x2b, 0x99, 0x06, 0x43,
+ /*9170:*/ 0xd1, 0x9d, 0xae, 0xd5, 0x54, 0xda, 0x5f, 0x6f, 0x9c, 0x96, 0x52, 0x1c, 0xca, 0xf6, 0xab, 0x58,
+ /*9180:*/ 0xe4, 0xbd, 0x83, 0x35, 0xc6, 0x32, 0xae, 0xd7, 0x54, 0x59, 0x53, 0xb3, 0x33, 0xe6, 0xd9, 0x7c,
+ /*9190:*/ 0x72, 0xb5, 0xcb, 0x02, 0x92, 0xd8, 0xf2, 0x68, 0xd1, 0xdb, 0x93, 0xd8, 0x2e, 0xc9, 0xda, 0x87,
+ /*91a0:*/ 0x50, 0xf2, 0x6c, 0xf9, 0x58, 0x2e, 0x6a, 0x6a, 0xfc, 0x08, 0x56, 0x9c, 0x6e, 0xe1, 0xdf, 0xe2,
+ /*91b0:*/ 0x90, 0x38, 0xbe, 0xb9, 0xbc, 0x2e, 0xb9, 0x2c, 0xcc, 0xd9, 0x0d, 0x25, 0xe2, 0x37, 0xf4, 0x28,
+ /*91c0:*/ 0xe1, 0xc1, 0xf2, 0xc9, 0x68, 0xd3, 0xff, 0xa3, 0xf0, 0x28, 0x67, 0x48, 0xfb, 0x91, 0xfe, 0x46,
+ /*91d0:*/ 0xc4, 0xbf, 0x60, 0xe7, 0x97, 0x37, 0x3f, 0xd2, 0x7e, 0xdf, 0x3d, 0x27, 0x6d, 0x3e, 0x69, 0xa5,
+ /*91e0:*/ 0x7f, 0x2f, 0x57, 0xeb, 0x82, 0x7e, 0x94, 0x85, 0x69, 0xb2, 0x9d, 0xa6, 0x66, 0x16, 0xa7, 0xc2,
+ /*91f0:*/ 0x87, 0xe8, 0x72, 0x7c, 0x99, 0xd4, 0xb1, 0x43, 0xa8, 0x06, 0x32, 0x32, 0x1e, 0xb2, 0x6e, 0x2f,
+ /*9200:*/ 0xd0, 0xca, 0xe7, 0x10, 0xd5, 0xc2, 0xe5, 0x6b, 0x91, 0xac, 0xb4, 0x79, 0x6f, 0x23, 0xcc, 0xfc,
+ /*9210:*/ 0x09, 0xe4, 0x62, 0x5e, 0xb6, 0x58, 0xd1, 0x53, 0xd4, 0x10, 0x0b, 0x01, 0xf5, 0x26, 0x5f, 0x5a,
+ /*9220:*/ 0xcf, 0xf6, 0x44, 0x93, 0xad, 0xed, 0x64, 0xd2, 0xfd, 0x2c, 0x6a, 0xfe, 0x3c, 0x37, 0x44, 0xf0,
+ /*9230:*/ 0x0d, 0x21, 0xd3, 0x7b, 0x8d, 0x8a, 0xfe, 0x0c, 0xf9, 0x5a, 0x0a, 0x86, 0xed, 0xfb, 0x5b, 0x6b,
+ /*9240:*/ 0xbe, 0x39, 0xb9, 0x85, 0xf8, 0x76, 0xde, 0x5f, 0xd8, 0x6e, 0x95, 0xb6, 0xd5, 0x4b, 0x40, 0x32,
+ /*9250:*/ 0x4a, 0xf1, 0x1c, 0xa8, 0x48, 0xe2, 0xf3, 0x10, 0xa6, 0x51, 0xee, 0x2a, 0xbb, 0x65, 0xaa, 0xe6,
+ /*9260:*/ 0x4b, 0x9c, 0x5f, 0x30, 0xcc, 0xbe, 0xae, 0xe3, 0x0f, 0xbe, 0x34, 0x44, 0xf5, 0x3c, 0xb2, 0x6d,
+ /*9270:*/ 0xd5, 0x2f, 0x3b, 0x59, 0xc8, 0x7f, 0x48, 0xfa, 0x53, 0x6f, 0x85, 0x7b, 0xaa, 0x6d, 0xf5, 0x2c,
+ /*9280:*/ 0x0f, 0x23, 0x8a, 0x25, 0xee, 0x4f, 0x08, 0x00, 0xc9, 0x1d, 0x53, 0xdb, 0xad, 0x37, 0x35, 0x41,
+ /*9290:*/ 0x6c, 0x9f, 0xe2, 0x79, 0x6a, 0x21, 0x04, 0x05, 0xe6, 0x6f, 0x74, 0x9e, 0x9a, 0x1c, 0x33, 0xd6,
+ /*92a0:*/ 0x44, 0x5c, 0x09, 0x40, 0xcb, 0x0e, 0xe4, 0x27, 0xa3, 0xf8, 0xf7, 0xd4, 0xed, 0x09, 0x33, 0x71,
+ /*92b0:*/ 0x5d, 0x5c, 0x95, 0x25, 0x67, 0x0a, 0x5c, 0x2e, 0xb6, 0xe7, 0xb0, 0x10, 0x9c, 0x19, 0xb4, 0x39,
+ /*92c0:*/ 0x99, 0x11, 0xbd, 0x82, 0x87, 0x28, 0x6d, 0x75, 0x9d, 0x4e, 0x66, 0xbb, 0x1f, 0x01, 0x6b, 0x33,
+ /*92d0:*/ 0xf5, 0x01, 0x20, 0x9f, 0x69, 0x09, 0x99, 0x29, 0xda, 0x12, 0x5a, 0xa5, 0x47, 0xe2, 0x4d, 0x3c,
+ /*92e0:*/ 0x39, 0x54, 0x5e, 0x69, 0xa4, 0x54, 0x14, 0x1f, 0x3f, 0x75, 0xfc, 0x25, 0xa3, 0x3d, 0xc1, 0x65,
+ /*92f0:*/ 0xc6, 0xd0, 0xdb, 0x44, 0xbe, 0xe9, 0x6d, 0x3d, 0x00, 0x81, 0x3b, 0xed, 0xb5, 0xfd, 0xa6, 0x19,
+ /*9300:*/ 0x63, 0xa2, 0xf0, 0xd8, 0x86, 0xeb, 0x86, 0x20, 0xe2, 0xaa, 0x98, 0xf9, 0x21, 0x51, 0x40, 0x63,
+ /*9310:*/ 0x84, 0x80, 0x6d, 0x18, 0x84, 0x3c, 0x91, 0x6a, 0x93, 0x85, 0x25, 0x5b, 0x5a, 0x12, 0x61, 0xf3,
+ /*9320:*/ 0x20, 0x02, 0x6e, 0x52, 0x08, 0xcf, 0x9a, 0xda, 0xd0, 0xbc, 0xd5, 0x70, 0xca, 0x73, 0x28, 0xcb,
+ /*9330:*/ 0x6c, 0x97, 0xc1, 0xb0, 0x0e, 0xb7, 0xa2, 0xd7, 0xb8, 0xb2, 0xe3, 0x98, 0xf7, 0x9e, 0x60, 0xc6,
+ /*9340:*/ 0x54, 0x2d, 0x04, 0x98, 0x6f, 0x29, 0xbe, 0xdc, 0x67, 0xad, 0xfd, 0x2d, 0xf5, 0x0e, 0x11, 0xfb,
+ /*9350:*/ 0x00, 0xac, 0xef, 0x9d, 0x6c, 0x12, 0x26, 0xf4, 0xf0, 0xaf, 0x05, 0xe4, 0xbf, 0x07, 0x50, 0x17,
+ /*9360:*/ 0x9e, 0xf9, 0xfe, 0x37, 0x35, 0xa2, 0xb5, 0xff, 0x98, 0xd7, 0x05, 0xa2, 0xb2, 0xa7, 0x5c, 0x2a,
+ /*9370:*/ 0x3f, 0x67, 0x01, 0x06, 0xa9, 0x3e, 0xdc, 0x76, 0x97, 0xfb, 0x36, 0x72, 0x30, 0xb7, 0xe4, 0x30,
+ /*9380:*/ 0x51, 0xe3, 0xe7, 0xeb, 0xcc, 0xd3, 0x3d, 0x6f, 0x9e, 0x7e, 0x00, 0xc6, 0x7c, 0x14, 0xb0, 0xae,
+ /*9390:*/ 0x79, 0x1c, 0x0b, 0x55, 0xcc, 0x61, 0xaf, 0xfc, 0x96, 0xcf, 0xcc, 0xe1, 0x99, 0x4b, 0x85, 0xe7,
+ /*93a0:*/ 0xa8, 0x9b, 0x40, 0xa9, 0xf8, 0xe8, 0x68, 0xe7, 0x9d, 0xde, 0xf4, 0xdc, 0x93, 0x57, 0x0a, 0x54,
+ /*93b0:*/ 0x5e, 0x4a, 0x1c, 0xd7, 0x2f, 0xc4, 0x5d, 0x37, 0x98, 0xbc, 0x63, 0xf6, 0x5c, 0x9a, 0xc0, 0xf4,
+ /*93c0:*/ 0x5e, 0x07, 0xc5, 0xab, 0xe5, 0x51, 0xf1, 0xe9, 0x8d, 0xcd, 0x48, 0x54, 0xce, 0x87, 0x69, 0x51,
+ /*93d0:*/ 0x10, 0xb9, 0xe6, 0x47, 0x8c, 0x2f, 0x2f, 0xe1, 0x9b, 0xcd, 0x05, 0x55, 0x9c, 0xa7, 0x0f, 0x18,
+ /*93e0:*/ 0x76, 0xee, 0xc3, 0x7e, 0xfa, 0x69, 0xa3, 0x7f, 0xc2, 0xa9, 0xff, 0xaa, 0x7a, 0x2d, 0x13, 0xd1,
+ /*93f0:*/ 0xde, 0x8b, 0x1c, 0xd8, 0xe6, 0x6f, 0x12, 0xfc, 0x4c, 0xec, 0x79, 0x02, 0x17, 0x6f, 0xc3, 0xd1,
+ /*9400:*/ 0xb5, 0x6e, 0xff, 0x06, 0xf1, 0x06, 0xd6, 0xbe, 0xbf, 0x02, 0x04, 0x72, 0x48, 0xed, 0x80, 0x58,
+ /*9410:*/ 0xf0, 0x5f, 0x31, 0xcf, 0x4d, 0xec, 0xe0, 0x1b, 0x6d, 0x33, 0x69, 0xfd, 0x2f, 0x62, 0xb8, 0x93,
+ /*9420:*/ 0xac, 0x31, 0x56, 0x8e, 0x61, 0xde, 0x88, 0xea, 0x3f, 0xc4, 0x6b, 0xff, 0xcc, 0x6f, 0x10, 0x26,
+ /*9430:*/ 0x85, 0x04, 0x98, 0xe4, 0x3a, 0xda, 0x18, 0xa2, 0x99, 0x59, 0x73, 0x58, 0x91, 0x7c, 0x22, 0x7e,
+ /*9440:*/ 0x16, 0xd4, 0xd3, 0x20, 0x4c, 0x82, 0x21, 0x81, 0x43, 0x83, 0x36, 0x73, 0x04, 0x0e, 0x07, 0x79,
+ /*9450:*/ 0x81, 0xd7, 0x8e, 0x44, 0x50, 0x9f, 0x33, 0x68, 0x0c, 0x67, 0x18, 0xd3, 0xba, 0xbe, 0xc9, 0xb7,
+ /*9460:*/ 0xed, 0x8f, 0xb0, 0xdc, 0xc6, 0xab, 0x17, 0x84, 0xa0, 0x79, 0x78, 0xf9, 0x87, 0x8a, 0x21, 0xdf,
+ /*9470:*/ 0xe7, 0x4d, 0xfa, 0x3b, 0xd8, 0xf4, 0x00, 0x85, 0x00, 0x0d, 0x8e, 0x68, 0x7a, 0x5a, 0x1a, 0x6a,
+ /*9480:*/ 0x3a, 0x6d, 0x36, 0x12, 0xf4, 0xd4, 0x09, 0xf9, 0xc5, 0x50, 0x1c, 0xe6, 0xe0, 0x58, 0x25, 0xfa,
+ /*9490:*/ 0xbc, 0xea, 0xfe, 0x6e, 0x1f, 0x1a, 0x16, 0x8f, 0x2f, 0x0f, 0xb2, 0xf3, 0x85, 0xe0, 0x11, 0x9e,
+ /*94a0:*/ 0x90, 0xf1, 0xab, 0x01, 0xea, 0x9e, 0x03, 0xbe, 0xaa, 0x73, 0x8c, 0x96, 0xf2, 0x1c, 0x74, 0x46,
+ /*94b0:*/ 0xdd, 0x4c, 0xff, 0x63, 0x18, 0x4b, 0xee, 0x7d, 0xed, 0xff, 0x16, 0xc8, 0x8d, 0xac, 0x0e, 0xe1,
+ /*94c0:*/ 0x3b, 0x21, 0x1a, 0x5b, 0x69, 0x16, 0xb9, 0xb7, 0xbd, 0x97, 0x02, 0xb6, 0x29, 0xba, 0xd7, 0x0c,
+ /*94d0:*/ 0xb0, 0x33, 0xba, 0x5a, 0x0d, 0xd2, 0xe6, 0x32, 0x70, 0xd9, 0x71, 0xa3, 0x59, 0xce, 0xe0, 0xac,
+ /*94e0:*/ 0x9f, 0x3d, 0xd3, 0xba, 0x2e, 0x3d, 0x70, 0x1c, 0x19, 0x9e, 0xa5, 0x34, 0xef, 0xf7, 0x93, 0xcd,
+ /*94f0:*/ 0x6f, 0xd1, 0xfd, 0x72, 0x76, 0x3a, 0x33, 0x5c, 0x54, 0xd9, 0x85, 0xbf, 0x72, 0xfd, 0x13, 0xf0,
+ /*9500:*/ 0x5d, 0x37, 0x35, 0x42, 0x1c, 0xd2, 0x41, 0x66, 0x1d, 0xcb, 0xf9, 0x76, 0xd9, 0x26, 0x3b, 0xb7,
+ /*9510:*/ 0xe7, 0xf6, 0x32, 0xa9, 0x26, 0xba, 0x25, 0x9c, 0x35, 0xa5, 0x80, 0x11, 0x3d, 0x0d, 0x43, 0x80,
+ /*9520:*/ 0xd1, 0x90, 0xba, 0xe1, 0xc8, 0x1c, 0xe4, 0x83, 0x08, 0xaa, 0xaf, 0x66, 0x8e, 0x33, 0x9a, 0x4a,
+ /*9530:*/ 0xdd, 0x79, 0xf6, 0xa7, 0xfa, 0x15, 0x59, 0x61, 0xf6, 0x35, 0xd8, 0x0b, 0xe4, 0x86, 0xbb, 0x74,
+ /*9540:*/ 0xfa, 0x6b, 0xa5, 0x4e, 0xf8, 0x41, 0xa7, 0xb4, 0x37, 0x82, 0x8e, 0x5b, 0x1c, 0x71, 0xe2, 0xe1,
+ /*9550:*/ 0x57, 0xa8, 0xa1, 0xc3, 0x18, 0x6f, 0xcb, 0x31, 0x2e, 0x28, 0x9d, 0x09, 0x33, 0x67, 0x9b, 0xaf,
+ /*9560:*/ 0x6f, 0x07, 0x18, 0x49, 0xd1, 0x78, 0x5d, 0x87, 0xdf, 0xb7, 0x62, 0x14, 0x00, 0x7e, 0xc7, 0xe8,
+ /*9570:*/ 0x7f, 0xbc, 0x6a, 0xd4, 0x4c, 0x91, 0xc6, 0xde, 0xd3, 0x89, 0xc8, 0xbf, 0x90, 0xda, 0x84, 0x0f,
+ /*9580:*/ 0x56, 0xdd, 0x95, 0xae, 0x92, 0x78, 0xf3, 0x93, 0xf0, 0x6c, 0x9e, 0xab, 0xf5, 0xb7, 0xb5, 0x99,
+ /*9590:*/ 0xf6, 0xb3, 0x94, 0x57, 0xd1, 0x96, 0x91, 0x60, 0x31, 0x0d, 0xa9, 0xf4, 0x67, 0x62, 0xa4, 0xd5,
+ /*95a0:*/ 0xf1, 0x5e, 0x15, 0xd8, 0xba, 0x27, 0x4c, 0x2d, 0x1f, 0x92, 0x0e, 0x8a, 0x51, 0x74, 0xdd, 0x8f,
+ /*95b0:*/ 0x27, 0x89, 0x9b, 0xba, 0x1b, 0x1a, 0x01, 0x1e, 0x9a, 0xb5, 0x77, 0x72, 0x8e, 0xde, 0x73, 0xbb,
+ /*95c0:*/ 0xe9, 0x6a, 0xa1, 0xeb, 0xa2, 0xab, 0x70, 0x7a, 0x34, 0x34, 0x4f, 0x86, 0x2f, 0x26, 0x4f, 0x39,
+ /*95d0:*/ 0xab, 0x57, 0x4f, 0x76, 0xed, 0xf8, 0x30, 0xc0, 0x21, 0xb5, 0x17, 0x03, 0x8e, 0xf1, 0x4c, 0xe2,
+ /*95e0:*/ 0x50, 0x6e, 0xf8, 0x95, 0xee, 0x19, 0xc9, 0xf0, 0x7c, 0x06, 0x9e, 0x3d, 0x69, 0xdf, 0x90, 0x03,
+ /*95f0:*/ 0xae, 0xfb, 0xc4, 0x34, 0x9e, 0x0a, 0x7d, 0x2e, 0x4d, 0xc5, 0x97, 0x18, 0x01, 0xb7, 0xfb, 0xd7,
+ /*9600:*/ 0x89, 0x81, 0xd8, 0xd7, 0x2c, 0x12, 0x29, 0xd4, 0x3f, 0xa7, 0xcc, 0x67, 0x9a, 0xed, 0x17, 0xb9,
+ /*9610:*/ 0xd8, 0x74, 0x27, 0x54, 0xa0, 0x11, 0x44, 0xe0, 0x64, 0xfe, 0xa2, 0x57, 0xf5, 0x63, 0x55, 0xdd,
+ /*9620:*/ 0x7b, 0x45, 0xea, 0xc2, 0x19, 0xad, 0x3d, 0x68, 0xb7, 0x94, 0x89, 0xa6, 0x6e, 0x28, 0xd2, 0xbc,
+ /*9630:*/ 0x09, 0xe4, 0x75, 0x37, 0xd4, 0x26, 0x4e, 0xf1, 0x6c, 0x8b, 0x5d, 0x16, 0x12, 0xfc, 0x10, 0xff,
+ /*9640:*/ 0x12, 0x33, 0xdb, 0xd9, 0x7b, 0x22, 0x55, 0x7b, 0xe7, 0xc4, 0x9c, 0xd7, 0x50, 0x87, 0xc5, 0xde,
+ /*9650:*/ 0x8d, 0xe0, 0x74, 0xc7, 0x03, 0x9f, 0x64, 0x7f, 0xf4, 0xfd, 0xbd, 0xed, 0x0c, 0x14, 0x8c, 0x2a,
+ /*9660:*/ 0xf9, 0x2e, 0x06, 0x6e, 0xb7, 0x2a, 0x3e, 0x61, 0x02, 0xce, 0x84, 0xd4, 0xb6, 0x02, 0xee, 0x47,
+ /*9670:*/ 0x13, 0x01, 0x8c, 0x78, 0x6d, 0x2b, 0xea, 0xa2, 0x74, 0x3f, 0x87, 0x2d, 0x42, 0xa1, 0x7a, 0x63,
+ /*9680:*/ 0x25, 0x81, 0x88, 0x65, 0x0a, 0x42, 0x52, 0xa1, 0x8f, 0xba, 0xf5, 0x32, 0x27, 0xdd, 0x87, 0x68,
+ /*9690:*/ 0x95, 0x0e, 0x6e, 0xb3, 0x04, 0xbb, 0x40, 0x5e, 0x65, 0x0e, 0x51, 0x4c, 0x2a, 0x9c, 0x5a, 0x2e,
+ /*96a0:*/ 0xc9, 0xed, 0xc0, 0xe1, 0xb5, 0x7e, 0x69, 0xcf, 0x4e, 0x16, 0xe3, 0x11, 0x8e, 0xef, 0xb9, 0x44,
+ /*96b0:*/ 0x6b, 0x79, 0x1a, 0xf2, 0x7a, 0x58, 0xe7, 0xd3, 0xbb, 0x95, 0x9e, 0x9a, 0x63, 0xa2, 0x3c, 0x8c,
+ /*96c0:*/ 0xd3, 0x4f, 0x7e, 0x08, 0xd5, 0x48, 0x8f, 0x6f, 0x6d, 0x14, 0x44, 0x9d, 0x82, 0x1e, 0x27, 0x1c,
+ /*96d0:*/ 0xb7, 0x0d, 0xb5, 0xc8, 0x4a, 0x9e, 0x1d, 0x45, 0x6c, 0x69, 0x8d, 0x8b, 0x46, 0x21, 0x36, 0x51,
+ /*96e0:*/ 0xb8, 0x41, 0x18, 0x2f, 0x3c, 0x1f, 0xe1, 0xeb, 0x34, 0xc3, 0x09, 0xb5, 0xe8, 0xd7, 0x78, 0x60,
+ /*96f0:*/ 0xd5, 0x6f, 0xe4, 0xb1, 0x01, 0x3e, 0xac, 0xbf, 0xaa, 0xfd, 0x1a, 0x33, 0x75, 0xc7, 0x11, 0x66,
+ /*9700:*/ 0xed, 0x08, 0x5e, 0xbc, 0xa4, 0xc2, 0x12, 0x3e, 0x9f, 0xac, 0xc4, 0xee, 0xfe, 0xb2, 0xdb, 0x0f,
+ /*9710:*/ 0x0d, 0x6a, 0x03, 0x63, 0xe8, 0x9a, 0xfe, 0xde, 0xe1, 0x30, 0xba, 0x98, 0x1d, 0x33, 0x5c, 0x94,
+ /*9720:*/ 0x07, 0x88, 0x25, 0x84, 0xbe, 0x9c, 0x01, 0x21, 0xc3, 0x27, 0x98, 0xdb, 0x69, 0xb4, 0xec, 0x17,
+ /*9730:*/ 0x21, 0x15, 0x40, 0xbc, 0x54, 0xb3, 0xda, 0x62, 0x73, 0x09, 0x64, 0x6a, 0x41, 0x23, 0x8d, 0x47,
+ /*9740:*/ 0x19, 0xf7, 0x30, 0xe7, 0xb4, 0x2c, 0x60, 0xcb, 0x8c, 0xf3, 0xc4, 0xd8, 0xc5, 0x38, 0xba, 0xf7,
+ /*9750:*/ 0xf7, 0xe8, 0x1a, 0x07, 0x9c, 0xde, 0x82, 0x1c, 0x0f, 0xf9, 0x38, 0x4f, 0x32, 0xc0, 0x6c, 0x3d,
+ /*9760:*/ 0x4d, 0x90, 0x04, 0x0a, 0xe6, 0x34, 0xa9, 0x1d, 0xf6, 0x00, 0x97, 0xd8, 0x07, 0x8b, 0xfa, 0x3d,
+ /*9770:*/ 0x65, 0x0f, 0x31, 0x24, 0xd9, 0xf9, 0xdb, 0xc4, 0xbd, 0x6d, 0x14, 0xc5, 0x97, 0xdf, 0x6d, 0x22,
+ /*9780:*/ 0x82, 0x7b, 0x9d, 0x2e, 0x40, 0x53, 0x71, 0x0c, 0xde, 0x63, 0xe3, 0xf0, 0x50, 0xb9, 0x00, 0x99,
+ /*9790:*/ 0x76, 0x75, 0x3c, 0x90, 0x2d, 0x17, 0xb9, 0xed, 0x04, 0xcf, 0x14, 0x78, 0x8b, 0xe2, 0xcc, 0x7f,
+ /*97a0:*/ 0xa9, 0x49, 0xb0, 0x5d, 0x04, 0x64, 0xe4, 0x72, 0x55, 0x39, 0x1a, 0x9e, 0x88, 0xd4, 0x23, 0x9c,
+ /*97b0:*/ 0x04, 0xbf, 0xe0, 0x9b, 0xdf, 0xeb, 0x68, 0x6c, 0xc7, 0x04, 0xef, 0x6c, 0xb7, 0x6f, 0xd6, 0xff,
+ /*97c0:*/ 0xfe, 0x63, 0xeb, 0x9c, 0xc9, 0x7b, 0xfe, 0x30, 0x15, 0xce, 0x6c, 0xd2, 0x6f, 0xcc, 0x64, 0x5c,
+ /*97d0:*/ 0x76, 0x65, 0x45, 0xa6, 0x17, 0x85, 0x6c, 0xc5, 0x27, 0x2f, 0xd7, 0x16, 0x9e, 0xb7, 0x56, 0xb2,
+ /*97e0:*/ 0xb0, 0x72, 0x83, 0x5e, 0xde, 0xba, 0x80, 0xf1, 0x06, 0xe3, 0xaf, 0xcb, 0xad, 0xd8, 0x6b, 0xdd,
+ /*97f0:*/ 0x4a, 0xa9, 0xb6, 0x19, 0x48, 0x10, 0x50, 0xb7, 0xeb, 0x0a, 0x85, 0xa8, 0x9e, 0xbd, 0x10, 0x63,
+ /*9800:*/ 0x6c, 0x14, 0x33, 0x0a, 0x90, 0x63, 0x1f, 0xda, 0x0b, 0x1d, 0x19, 0xee, 0xf6, 0x20, 0xc5, 0x0c,
+ /*9810:*/ 0x79, 0x2d, 0x38, 0xbb, 0xdc, 0x38, 0x86, 0x4e, 0xce, 0x64, 0x1e, 0xfb, 0xfd, 0xbf, 0x8e, 0xa6,
+ /*9820:*/ 0x16, 0xec, 0xd9, 0x7b, 0x69, 0xb9, 0xc3, 0x96, 0x4a, 0x86, 0x43, 0x02, 0xf6, 0x74, 0xb5, 0x5f,
+ /*9830:*/ 0xb8, 0x39, 0xb1, 0x83, 0x40, 0x45, 0x72, 0xd8, 0xe9, 0x64, 0x81, 0x6a, 0xeb, 0x19, 0xbb, 0x42,
+ /*9840:*/ 0x61, 0xba, 0x45, 0x42, 0x47, 0x81, 0xe9, 0x19, 0x34, 0xdd, 0x80, 0x3e, 0xb9, 0x2c, 0x00, 0xad,
+ /*9850:*/ 0x0e, 0x3c, 0x71, 0x0b, 0xea, 0x1f, 0xf8, 0xa5, 0x38, 0x68, 0x66, 0x01, 0xa0, 0x70, 0xf4, 0x41,
+ /*9860:*/ 0x96, 0xa7, 0xb1, 0xae, 0x3c, 0xd9, 0xfd, 0x10, 0xb8, 0x4a, 0x70, 0x7b, 0x94, 0x00, 0xe8, 0xb6,
+ /*9870:*/ 0xa5, 0x24, 0xac, 0xa3, 0x5a, 0xd8, 0x6f, 0xa5, 0x48, 0x26, 0xd8, 0x7b, 0x4c, 0x5c, 0x30, 0x8b,
+ /*9880:*/ 0x6b, 0x55, 0x8a, 0x7b, 0x1b, 0xc8, 0xce, 0x9b, 0x7a, 0xc1, 0x36, 0xe7, 0x9a, 0x58, 0xe8, 0xc7,
+ /*9890:*/ 0x14, 0x8b, 0x01, 0x5f, 0x13, 0x04, 0x4c, 0x10, 0x43, 0x44, 0x33, 0x44, 0xe2, 0x60, 0xb6, 0x47,
+ /*98a0:*/ 0xca, 0x0a, 0x2e, 0x90, 0xa7, 0x49, 0xfc, 0x06, 0x3d, 0xf2, 0x4f, 0xd2, 0x69, 0x69, 0x6c, 0x0b,
+ /*98b0:*/ 0xe4, 0x37, 0x2a, 0x60, 0x8a, 0x8c, 0x0f, 0x33, 0xa9, 0xb1, 0xb3, 0xc8, 0xe6, 0x82, 0xa8, 0xaf,
+ /*98c0:*/ 0x56, 0x17, 0xc7, 0x77, 0xf6, 0xc9, 0xb2, 0x27, 0x79, 0x7e, 0xec, 0x3c, 0xba, 0xc4, 0x3b, 0x0f,
+ /*98d0:*/ 0x4f, 0xf4, 0x22, 0x13, 0x4c, 0x20, 0xda, 0xfb, 0xaf, 0x56, 0xae, 0x51, 0x27, 0x54, 0x15, 0x80,
+ /*98e0:*/ 0x85, 0x94, 0xb7, 0x97, 0x82, 0x8b, 0xef, 0xcf, 0x4a, 0xbf, 0xb8, 0x18, 0x2c, 0x37, 0x59, 0x8d,
+ /*98f0:*/ 0x32, 0xed, 0x94, 0x78, 0x56, 0x01, 0x05, 0xc0, 0xfe, 0x6f, 0x8c, 0x60, 0x7e, 0x77, 0xee, 0xc0,
+ /*9900:*/ 0xa8, 0x3f, 0x8d, 0xb9, 0x7d, 0x19, 0x8e, 0x95, 0xf8, 0xbe, 0xc5, 0xe8, 0x57, 0xbd, 0x3c, 0xfc,
+ /*9910:*/ 0x9b, 0xfd, 0x72, 0x44, 0xf4, 0x42, 0x2d, 0xcb, 0x8c, 0x81, 0x8c, 0x3b, 0x0c, 0xfe, 0x05, 0x42,
+ /*9920:*/ 0x55, 0xeb, 0xb9, 0x30, 0x27, 0xc5, 0x4c, 0x1b, 0x79, 0xd5, 0x9e, 0x2e, 0x50, 0x25, 0x08, 0x62,
+ /*9930:*/ 0xcc, 0x75, 0x72, 0x33, 0x26, 0xc3, 0xcd, 0x86, 0xb0, 0xe4, 0xee, 0xea, 0xd6, 0x2d, 0x57, 0xd3,
+ /*9940:*/ 0x80, 0x9c, 0xef, 0x9d, 0x78, 0x6d, 0x96, 0x28, 0xac, 0xed, 0x27, 0xea, 0x62, 0xbd, 0x8d, 0x9e,
+ /*9950:*/ 0x20, 0x2b, 0xc4, 0xe4, 0x3d, 0x61, 0x68, 0xff, 0x5c, 0x5d, 0x47, 0x44, 0x40, 0x4c, 0x9a, 0x47,
+ /*9960:*/ 0xa0, 0x24, 0x16, 0x1e, 0x88, 0xd5, 0x86, 0x29, 0x96, 0x0c, 0x4f, 0x13, 0x1f, 0x2c, 0x03, 0x98,
+ /*9970:*/ 0x56, 0xd9, 0x46, 0xe5, 0x18, 0x83, 0xed, 0x85, 0xd9, 0x8a, 0x8a, 0x88, 0xe6, 0x19, 0xf2, 0x7b,
+ /*9980:*/ 0xe4, 0x68, 0x3d, 0xfc, 0xbd, 0x71, 0x27, 0x22, 0xf4, 0x60, 0x51, 0x30, 0x52, 0x99, 0x43, 0x88,
+ /*9990:*/ 0x42, 0xa4, 0xe8, 0x16, 0xf2, 0x17, 0x3a, 0xd7, 0x2b, 0x85, 0x49, 0x53, 0x50, 0x14, 0x51, 0xd3,
+ /*99a0:*/ 0x4c, 0x85, 0xcc, 0x80, 0x1e, 0x49, 0x18, 0xb8, 0x3c, 0x3e, 0x1c, 0xbe, 0x56, 0x07, 0xf7, 0xc7,
+ /*99b0:*/ 0x9f, 0xda, 0xce, 0x00, 0x93, 0xe6, 0xa1, 0xda, 0xf1, 0x45, 0x7b, 0x3f, 0x26, 0x9c, 0xb6, 0xe8,
+ /*99c0:*/ 0xfb, 0xce, 0x3b, 0x85, 0x64, 0xf5, 0x85, 0x9c, 0x34, 0x4f, 0x89, 0x44, 0x52, 0x69, 0x99, 0xc9,
+ /*99d0:*/ 0x5d, 0x87, 0x52, 0x2c, 0xd3, 0x3a, 0x6e, 0x5c, 0x02, 0x41, 0x5c, 0x03, 0xa8, 0xfb, 0xcd, 0x82,
+ /*99e0:*/ 0xe6, 0xd7, 0xe2, 0x90, 0x06, 0x9e, 0x4f, 0xbc, 0x53, 0x79, 0x24, 0xd9, 0x20, 0xb6, 0x5f, 0xa6,
+ /*99f0:*/ 0x0d, 0x88, 0x85, 0xbe, 0x19, 0xe4, 0x1f, 0x95, 0xf8, 0x94, 0x6e, 0x01, 0x9d, 0xc0, 0xef, 0x18,
+ /*9a00:*/ 0xaf, 0xda, 0xac, 0x64, 0x8c, 0x7a, 0x84, 0x6d, 0x45, 0xa4, 0x34, 0x66, 0x9b, 0x81, 0xab, 0x69,
+ /*9a10:*/ 0x19, 0x49, 0x6c, 0xa8, 0xc6, 0x8b, 0x3b, 0xbd, 0xff, 0x27, 0x23, 0x48, 0xa6, 0x6b, 0xa9, 0x30,
+ /*9a20:*/ 0xf0, 0xbb, 0xe4, 0x08, 0x3d, 0x52, 0x21, 0x70, 0xbc, 0x42, 0x45, 0x92, 0xf7, 0x0c, 0x83, 0x33,
+ /*9a30:*/ 0x9f, 0x38, 0x28, 0x1b, 0xb3, 0xf2, 0xc4, 0x38, 0x24, 0x03, 0xfd, 0xa9, 0x18, 0x60, 0x54, 0xcc,
+ /*9a40:*/ 0xc1, 0xb0, 0x78, 0x8e, 0x99, 0x64, 0x9c, 0xeb, 0x02, 0xbc, 0x63, 0x7b, 0xd6, 0x03, 0x6d, 0xcb,
+ /*9a50:*/ 0x1f, 0x6f, 0x34, 0x59, 0xe6, 0x7e, 0xb0, 0x10, 0xbb, 0x5d, 0xe6, 0xfa, 0x66, 0xbe, 0x14, 0x10,
+ /*9a60:*/ 0xca, 0xd1, 0x3f, 0x99, 0x4c, 0x04, 0xfb, 0x56, 0x64, 0xec, 0x2e, 0x07, 0x61, 0x05, 0x9c, 0x8c,
+ /*9a70:*/ 0x1a, 0xc4, 0x34, 0x1d, 0xbf, 0x33, 0x69, 0x38, 0x9f, 0xa4, 0x9e, 0xbd, 0xc6, 0x4d, 0x49, 0xe4,
+ /*9a80:*/ 0xf3, 0xc5, 0x38, 0xb4, 0xb7, 0xa3, 0x0a, 0x49, 0x67, 0x9e, 0x79, 0xf0, 0xa7, 0x4c, 0x91, 0xf7,
+ /*9a90:*/ 0x42, 0x88, 0xc1, 0x4f, 0x01, 0xa0, 0x43, 0x6e, 0x39, 0xbd, 0x96, 0x07, 0x3e, 0xab, 0x70, 0x56,
+ /*9aa0:*/ 0x54, 0xe1, 0xc9, 0xa2, 0x9a, 0x98, 0xb9, 0xd6, 0x3c, 0x17, 0xa9, 0xbe, 0xc5, 0xe2, 0x36, 0x18,
+ /*9ab0:*/ 0xf4, 0x15, 0x9d, 0x0b, 0xa2, 0x66, 0x87, 0x79, 0x45, 0x6d, 0x24, 0x09, 0xa0, 0xcd, 0x87, 0xdc,
+ /*9ac0:*/ 0x3d, 0x69, 0x16, 0x6b, 0xef, 0xf4, 0x3b, 0x04, 0x34, 0x84, 0xf1, 0x19, 0x8c, 0x73, 0x90, 0xf0,
+ /*9ad0:*/ 0xde, 0xfb, 0xcf, 0x48, 0x44, 0x41, 0xf9, 0x81, 0xb3, 0xa7, 0x0a, 0xc2, 0xd4, 0x8c, 0x84, 0x9a,
+ /*9ae0:*/ 0x6a, 0x1c, 0x34, 0x63, 0x96, 0x0a, 0xe0, 0xc6, 0x10, 0x88, 0x8f, 0x8e, 0xac, 0x96, 0xee, 0xc0,
+ /*9af0:*/ 0x86, 0x16, 0x61, 0x8f, 0x35, 0xec, 0x47, 0x4e, 0x75, 0x17, 0x49, 0x0e, 0x3f, 0x34, 0x68, 0x7e,
+ /*9b00:*/ 0xae, 0x61, 0x0e, 0x7e, 0xd2, 0x81, 0x53, 0xd1, 0x53, 0x7a, 0x20, 0x7a, 0x40, 0x7a, 0x2e, 0xbc,
+ /*9b10:*/ 0x43, 0x3a, 0x66, 0x39, 0x0f, 0xc1, 0x85, 0xc0, 0x71, 0xe0, 0x15, 0x28, 0x47, 0xb5, 0xd1, 0x99,
+ /*9b20:*/ 0x6e, 0xd3, 0x48, 0xe0, 0x41, 0xa7, 0xf3, 0x27, 0x8f, 0xda, 0x55, 0x5f, 0x89, 0x0f, 0x9b, 0x91,
+ /*9b30:*/ 0xe9, 0x1f, 0x9b, 0x5e, 0x32, 0x53, 0x3e, 0x8c, 0x65, 0xd5, 0x92, 0x0b, 0x8c, 0x5f, 0x73, 0xcc,
+ /*9b40:*/ 0x0d, 0xc5, 0xa7, 0x1c, 0x80, 0x85, 0xca, 0xbc, 0x00, 0xf6, 0x73, 0x07, 0x9b, 0xb4, 0x93, 0x48,
+ /*9b50:*/ 0x22, 0xe3, 0xf9, 0x63, 0x9d, 0xe5, 0x82, 0x17, 0x3e, 0x65, 0x2b, 0x4f, 0x68, 0xc3, 0xc3, 0x6d,
+ /*9b60:*/ 0x8d, 0x9a, 0x5e, 0x47, 0xe6, 0x1f, 0x99, 0x94, 0xab, 0xd6, 0xc2, 0xeb, 0x05, 0x70, 0x23, 0x7a,
+ /*9b70:*/ 0x6b, 0xbd, 0xc0, 0x1d, 0xe2, 0x22, 0xa9, 0xb5, 0x56, 0xcb, 0x93, 0x2c, 0x88, 0xed, 0xd9, 0xbf,
+ /*9b80:*/ 0x14, 0x44, 0xb3, 0x99, 0xe2, 0x58, 0x2d, 0x78, 0x53, 0xc3, 0xbf, 0x94, 0xd0, 0x57, 0x95, 0xec,
+ /*9b90:*/ 0x25, 0xe2, 0x51, 0xb4, 0x6f, 0x2d, 0xf9, 0xb4, 0x15, 0x32, 0xa4, 0x20, 0xf8, 0x7e, 0x47, 0x65,
+ /*9ba0:*/ 0xc8, 0xb2, 0x95, 0xad, 0x41, 0xd5, 0x91, 0xbb, 0xd7, 0x66, 0x2c, 0x96, 0x7d, 0x78, 0x85, 0x3c,
+ /*9bb0:*/ 0x72, 0x21, 0x9d, 0xe4, 0x4a, 0x4a, 0x4f, 0x29, 0x76, 0x24, 0x82, 0x83, 0xb8, 0x19, 0x1b, 0x5a,
+ /*9bc0:*/ 0x1f, 0x13, 0x76, 0xc2, 0xe3, 0x69, 0x75, 0xea, 0x4a, 0xb0, 0xbd, 0x34, 0x87, 0x0c, 0xe3, 0xda,
+ /*9bd0:*/ 0x14, 0xce, 0x42, 0x65, 0x42, 0xed, 0x9a, 0x7f, 0x69, 0x83, 0x55, 0xa4, 0xbf, 0xd5, 0x91, 0xa9,
+ /*9be0:*/ 0x00, 0x57, 0xa1, 0x24, 0x8d, 0xd8, 0x01, 0xf7, 0x5a, 0x76, 0xf8, 0x15, 0x14, 0x80, 0xd0, 0x8e,
+ /*9bf0:*/ 0x26, 0xbb, 0x5c, 0x5b, 0x6b, 0x62, 0x5c, 0xa4, 0x75, 0xe2, 0x01, 0xd1, 0x46, 0x9b, 0x7f, 0x7f,
+ /*9c00:*/ 0x16, 0xd1, 0xa0, 0xfa, 0x4f, 0x8e, 0x3d, 0xe4, 0xe0, 0xab, 0xc4, 0x25, 0x7f, 0x3a, 0x1b, 0x17,
+ /*9c10:*/ 0x3a, 0x99, 0xff, 0xa6, 0x54, 0xce, 0x8d, 0x7c, 0xa6, 0x4a, 0xce, 0x6f, 0x98, 0xe3, 0x1d, 0x84,
+ /*9c20:*/ 0x8b, 0x74, 0xf7, 0x01, 0x99, 0x05, 0x21, 0xce, 0x4d, 0x0f, 0x4c, 0x91, 0x40, 0x24, 0xf4, 0x78,
+ /*9c30:*/ 0xec, 0x90, 0xc9, 0xca, 0xc2, 0x63, 0x97, 0x84, 0x56, 0x21, 0x88, 0x57, 0xc2, 0xc0, 0x9d, 0xbd,
+ /*9c40:*/ 0x78, 0xc8, 0x69, 0x9a, 0x00, 0xd0, 0xaa, 0x65, 0x9a, 0x74, 0x06, 0xf1, 0x66, 0x15, 0xcc, 0xf2,
+ /*9c50:*/ 0x2a, 0x6a, 0xc1, 0xf3, 0x02, 0x6e, 0x08, 0xc4, 0xea, 0x54, 0x55, 0x05, 0x86, 0xeb, 0x19, 0x4a,
+ /*9c60:*/ 0xa3, 0xee, 0xa7, 0x1a, 0x3c, 0x93, 0x34, 0x07, 0x91, 0x72, 0x36, 0xbd, 0xb7, 0x54, 0xc5, 0x05,
+ /*9c70:*/ 0xdb, 0xe3, 0xe6, 0x5d, 0x48, 0x58, 0x16, 0x23, 0xed, 0x21, 0x9e, 0xe6, 0xed, 0xb4, 0x8f, 0x75,
+ /*9c80:*/ 0x8d, 0x5b, 0x9a, 0x16, 0x65, 0x9e, 0x5f, 0xb9, 0xff, 0xc9, 0xcd, 0xd0, 0xa8, 0xd3, 0x36, 0x3e,
+ /*9c90:*/ 0x36, 0x67, 0x30, 0xf5, 0xd8, 0xbe, 0x1c, 0xe3, 0x30, 0x9e, 0x0c, 0x1b, 0x06, 0x6d, 0x34, 0x07,
+ /*9ca0:*/ 0x73, 0x56, 0x08, 0xff, 0xaa, 0x12, 0x5b, 0x46, 0x54, 0x57, 0xb5, 0x3d, 0x56, 0x95, 0x09, 0x9f,
+ /*9cb0:*/ 0x40, 0x99, 0x96, 0x83, 0x58, 0xbb, 0xcc, 0x88, 0x1a, 0x62, 0xbd, 0xb7, 0xaa, 0x27, 0x9a, 0xf7,
+ /*9cc0:*/ 0xd1, 0x23, 0x3c, 0xa7, 0x5f, 0x82, 0x20, 0x91, 0x0c, 0xa5, 0x4c, 0xda, 0x74, 0xf8, 0x0e, 0x59,
+ /*9cd0:*/ 0x68, 0x13, 0xd6, 0x07, 0xe2, 0x4e, 0x57, 0x5c, 0xd3, 0xb5, 0xb9, 0x11, 0xaa, 0x45, 0x74, 0xf2,
+ /*9ce0:*/ 0xf4, 0x37, 0x37, 0xff, 0x45, 0x6c, 0x51, 0x1d, 0xfe, 0xf0, 0x12, 0x40, 0x57, 0x6f, 0x41, 0x93,
+ /*9cf0:*/ 0xb0, 0x7c, 0xd3, 0x5d, 0xe4, 0x10, 0x0c, 0xe2, 0xfa, 0x90, 0xa9, 0x68, 0xf9, 0x41, 0xd4, 0x71,
+ /*9d00:*/ 0x2e, 0x46, 0xfb, 0x78, 0xca, 0xa6, 0x44, 0xec, 0xbf, 0xfb, 0x33, 0xea, 0xcd, 0x46, 0x64, 0xf0,
+ /*9d10:*/ 0x1e, 0x5a, 0x3a, 0x3a, 0xbe, 0x7f, 0x83, 0x94, 0xb2, 0x11, 0xb1, 0x32, 0x14, 0x05, 0xc0, 0xa0,
+ /*9d20:*/ 0x87, 0x7f, 0xb7, 0xf2, 0xe9, 0x08, 0xcb, 0x1f, 0x5d, 0x87, 0x30, 0xec, 0x05, 0xcf, 0xaa, 0x01,
+ /*9d30:*/ 0x2f, 0x23, 0x0d, 0x81, 0xde, 0x30, 0x8e, 0x03, 0x0e, 0x44, 0x6e, 0x62, 0xb9, 0x6e, 0x7c, 0x0e,
+ /*9d40:*/ 0x0a, 0x00, 0x63, 0xea, 0xb9, 0xbd, 0x9b, 0x8e, 0x1a, 0x3c, 0xb4, 0xff, 0xae, 0xd4, 0x15, 0x18,
+ /*9d50:*/ 0xe6, 0x0f, 0xfe, 0x28, 0x6e, 0xdc, 0x76, 0x2a, 0xf5, 0xd4, 0x14, 0xd8, 0x8c, 0x76, 0x35, 0xa8,
+ /*9d60:*/ 0x85, 0x38, 0x55, 0xfe, 0xc3, 0x83, 0xd5, 0xaa, 0x58, 0x92, 0xb8, 0x82, 0x45, 0x9c, 0xe5, 0x92,
+ /*9d70:*/ 0xd4, 0x11, 0xc9, 0xf9, 0xab, 0x5b, 0x9c, 0x77, 0xb3, 0xbe, 0x3f, 0x65, 0x89, 0xbd, 0x1d, 0xdf,
+ /*9d80:*/ 0x89, 0x64, 0xe3, 0x0b, 0xf4, 0xc8, 0xf2, 0xe1, 0x23, 0xbf, 0x13, 0x81, 0x33, 0x92, 0x94, 0x75,
+ /*9d90:*/ 0x1b, 0xd1, 0xfc, 0x34, 0xee, 0x54, 0xdc, 0x3c, 0x40, 0xf4, 0x5d, 0xdd, 0x64, 0xd5, 0xb0, 0xdf,
+ /*9da0:*/ 0x6a, 0xb6, 0x3b, 0x92, 0x71, 0x06, 0x33, 0xf7, 0xba, 0x9b, 0x4a, 0x79, 0x91, 0x31, 0x17, 0x86,
+ /*9db0:*/ 0x35, 0x37, 0x8f, 0x62, 0x57, 0x43, 0xe7, 0x72, 0x32, 0x56, 0x91, 0x41, 0xd5, 0xc9, 0x27, 0x54,
+ /*9dc0:*/ 0x7e, 0x61, 0x7b, 0x36, 0x15, 0x2d, 0xbd, 0x4d, 0x9f, 0x51, 0xfd, 0x85, 0x8d, 0x00, 0x91, 0xe3,
+ /*9dd0:*/ 0x64, 0xb1, 0x8b, 0x51, 0xbe, 0x0e, 0x5d, 0xdb, 0x41, 0x79, 0xec, 0x11, 0x95, 0xa7, 0xfa, 0x4b,
+ /*9de0:*/ 0xd3, 0x55, 0x98, 0xb2, 0xd2, 0x51, 0xfe, 0x51, 0x35, 0x9c, 0x22, 0x3e, 0x25, 0x91, 0x42, 0xc3,
+ /*9df0:*/ 0xb0, 0x75, 0x05, 0xeb, 0xf2, 0xcb, 0x7d, 0xaa, 0xb6, 0x4b, 0x82, 0x12, 0xc2, 0x88, 0xf9, 0x78,
+ /*9e00:*/ 0xf6, 0x01, 0x30, 0x50, 0x38, 0x6a, 0xcb, 0xb1, 0xf1, 0x27, 0xcb, 0xf7, 0xd3, 0xe1, 0x43, 0xf3,
+ /*9e10:*/ 0x9e, 0x8c, 0x92, 0xab, 0xcd, 0xa7, 0x03, 0xc3, 0xd0, 0x9c, 0x91, 0x8b, 0x2d, 0xde, 0xbc, 0x50,
+ /*9e20:*/ 0x63, 0x95, 0x4b, 0x7e, 0xda, 0xf4, 0x72, 0xe3, 0xcc, 0x2c, 0x35, 0x5d, 0x2c, 0xd0, 0x4b, 0x54,
+ /*9e30:*/ 0xaf, 0xf4, 0x42, 0x0e, 0xd4, 0x8a, 0x66, 0x56, 0x83, 0xd9, 0x5e, 0x1d, 0x81, 0xd3, 0xce, 0xad,
+ /*9e40:*/ 0x61, 0xca, 0x20, 0xe6, 0xc3, 0x17, 0xef, 0x4b, 0xbe, 0xf0, 0xbc, 0xda, 0xb3, 0x79, 0xb5, 0xcb,
+ /*9e50:*/ 0x38, 0x67, 0x2a, 0x17, 0x4f, 0xda, 0xfc, 0x1a, 0x87, 0x8d, 0xc3, 0x73, 0x87, 0x65, 0xf6, 0x03,
+ /*9e60:*/ 0xc9, 0xf0, 0xab, 0x2c, 0x6f, 0xae, 0x90, 0x15, 0x10, 0xf1, 0x8d, 0x90, 0x05, 0x1a, 0x27, 0x72,
+ /*9e70:*/ 0x2d, 0x2d, 0xfb, 0x1b, 0xec, 0x9a, 0x90, 0x21, 0x08, 0xb6, 0x58, 0x57, 0xb3, 0x3d, 0xb1, 0x29,
+ /*9e80:*/ 0x00, 0x62, 0x95, 0x68, 0x6b, 0x5b, 0xfb, 0x98, 0x6e, 0xbb, 0x9c, 0x53, 0x03, 0xd3, 0xda, 0x91,
+ /*9e90:*/ 0xac, 0xec, 0x1c, 0x4e, 0x56, 0xbb, 0x50, 0xe3, 0x23, 0xc0, 0x01, 0x63, 0x45, 0x01, 0xff, 0x30,
+ /*9ea0:*/ 0x6e, 0x6f, 0xe9, 0x60, 0xed, 0xab, 0x89, 0x5c, 0xcf, 0x0a, 0x89, 0x13, 0x39, 0x2a, 0xa6, 0x93,
+ /*9eb0:*/ 0x18, 0xc8, 0x26, 0xd3, 0x23, 0x8c, 0x22, 0xa4, 0x3c, 0xde, 0xe7, 0x7d, 0x9c, 0x5c, 0x35, 0x4c,
+ /*9ec0:*/ 0xb1, 0x6e, 0xfc, 0x19, 0xaa, 0x5a, 0x17, 0xad, 0x22, 0x75, 0x3e, 0x83, 0xa7, 0x7e, 0x72, 0xe0,
+ /*9ed0:*/ 0xaa, 0x75, 0x37, 0x2a, 0xd0, 0xd3, 0x8f, 0xbf, 0x20, 0x0b, 0x3e, 0xff, 0xea, 0x0b, 0x3c, 0x20,
+ /*9ee0:*/ 0x33, 0x6b, 0x28, 0xc8, 0x67, 0x85, 0x97, 0x61, 0x5f, 0x48, 0xaf, 0x38, 0x38, 0x07, 0x41, 0x6a,
+ /*9ef0:*/ 0x5e, 0x5a, 0x39, 0x4e, 0x45, 0xc6, 0xb5, 0x8f, 0xea, 0x78, 0x47, 0x51, 0x83, 0xb2, 0x98, 0xd1,
+ /*9f00:*/ 0x43, 0x0f, 0xc4, 0xaf, 0xad, 0xf4, 0x95, 0xe5, 0xc8, 0x6f, 0x48, 0x50, 0x83, 0x7c, 0xd4, 0xb9,
+ /*9f10:*/ 0x13, 0x7b, 0x60, 0x41, 0xf9, 0x2f, 0xe0, 0x31, 0x5f, 0x3f, 0x20, 0xce, 0x6f, 0xcd, 0x94, 0x0a,
+ /*9f20:*/ 0xd5, 0x0b, 0x01, 0x09, 0x5f, 0x1d, 0x43, 0x0a, 0x35, 0x05, 0x6b, 0xe6, 0x0a, 0x48, 0xb1, 0xa7,
+ /*9f30:*/ 0xe5, 0x03, 0x7f, 0x6b, 0xfe, 0xcc, 0xdf, 0x88, 0xbc, 0xde, 0x8f, 0x1f, 0xad, 0x77, 0xb0, 0xe9,
+ /*9f40:*/ 0x53, 0x1f, 0xad, 0xb0, 0x81, 0x9f, 0xa6, 0x9f, 0x7e, 0x36, 0x8e, 0xed, 0xba, 0xa9, 0x07, 0x78,
+ /*9f50:*/ 0x2f, 0xea, 0xdb, 0x66, 0x63, 0x32, 0x47, 0xbf, 0x38, 0xfe, 0x6b, 0xa8, 0x29, 0x27, 0x0a, 0x41,
+ /*9f60:*/ 0x0b, 0x84, 0x11, 0xcf, 0x5c, 0x57, 0x0f, 0x2a, 0xbc, 0x6f, 0xc8, 0xa8, 0x55, 0x19, 0xd8, 0xd0,
+ /*9f70:*/ 0x7c, 0xec, 0x19, 0x72, 0x50, 0xfa, 0x86, 0xf8, 0xa9, 0x1e, 0xb7, 0xa3, 0x96, 0xe2, 0x58, 0x17,
+ /*9f80:*/ 0x1c, 0xc9, 0x95, 0x38, 0x9e, 0x94, 0x9e, 0x16, 0xe1, 0x69, 0xe7, 0xea, 0xf2, 0x49, 0x5f, 0x9a,
+ /*9f90:*/ 0x64, 0x42, 0x5e, 0x7b, 0xb5, 0x4b, 0x5c, 0x29, 0x23, 0x84, 0xaf, 0xa3, 0x41, 0x54, 0xd2, 0x9e,
+ /*9fa0:*/ 0x25, 0x1d, 0x19, 0x1a, 0x86, 0x1d, 0xa5, 0xb4, 0xc6, 0x8f, 0x81, 0x1f, 0x06, 0xed, 0xb8, 0xee,
+ /*9fb0:*/ 0x1b, 0xf0, 0xb6, 0x78, 0xd1, 0x00, 0x85, 0x81, 0xff, 0xde, 0xdb, 0xc1, 0x6c, 0xb9, 0xdc, 0xb3,
+ /*9fc0:*/ 0x45, 0x16, 0x5f, 0xaf, 0x54, 0x17, 0xef, 0x0b, 0x98, 0x33, 0x29, 0xb5, 0x4a, 0xfb, 0x3d, 0x19,
+ /*9fd0:*/ 0x0d, 0x74, 0x8b, 0xee, 0x20, 0x94, 0x80, 0x59, 0xac, 0x93, 0xba, 0x50, 0x8a, 0x7b, 0xff, 0xd1,
+ /*9fe0:*/ 0xad, 0x7e, 0x91, 0x79, 0xcb, 0xb1, 0x64, 0x58, 0x55, 0x2a, 0xf8, 0xc4, 0xcd, 0x9b, 0xdc, 0x4c,
+ /*9ff0:*/ 0x17, 0x61, 0x19, 0x99, 0x54, 0x30, 0x20, 0x6b, 0xe9, 0xc8, 0xad, 0x1f, 0xcf, 0x61, 0x18, 0x5f,
+ /*a000:*/ 0x1d, 0x2d, 0xb1, 0xb6, 0xbf, 0xd9, 0xee, 0x38, 0x22, 0xd1, 0xd4, 0xad, 0xe7, 0xe4, 0xb3, 0xcd,
+ /*a010:*/ 0x65, 0x9c, 0x45, 0xcf, 0x2b, 0xe0, 0xde, 0x2c, 0x3a, 0x53, 0x1f, 0x98, 0x10, 0xf5, 0x15, 0xd8,
+ /*a020:*/ 0x53, 0xa4, 0x3c, 0x46, 0x00, 0x53, 0xab, 0x9b, 0x4f, 0x92, 0xb8, 0x70, 0x84, 0x24, 0xa7, 0xaf,
+ /*a030:*/ 0xe3, 0x0a, 0x5f, 0x89, 0x10, 0xa1, 0x72, 0x3d, 0x68, 0x14, 0x1d, 0xb9, 0x16, 0x4e, 0x6c, 0x19,
+ /*a040:*/ 0x43, 0x95, 0x83, 0xb8, 0x18, 0x61, 0x4d, 0x20, 0x6d, 0xb9, 0x97, 0x6b, 0x44, 0xe4, 0x9b, 0x2c,
+ /*a050:*/ 0xb5, 0x5a, 0xdd, 0xd5, 0xd1, 0x6a, 0xdf, 0x19, 0xf7, 0xb0, 0x5a, 0x09, 0xc1, 0x55, 0x3e, 0x88,
+ /*a060:*/ 0xbe, 0xa5, 0x49, 0x20, 0x95, 0x7f, 0xcb, 0x97, 0x5b, 0x51, 0x4d, 0xb0, 0x77, 0x89, 0xab, 0x4d,
+ /*a070:*/ 0xfc, 0x88, 0x20, 0x25, 0x68, 0x38, 0x6a, 0xb9, 0x5d, 0x0b, 0x9a, 0xe6, 0x96, 0xeb, 0x64, 0x66,
+ /*a080:*/ 0x1f, 0x7b, 0xb0, 0x2f, 0x35, 0xb6, 0x45, 0x25, 0x46, 0x09, 0x70, 0x98, 0xf8, 0xdc, 0x47, 0x14,
+ /*a090:*/ 0x7d, 0x61, 0xfa, 0x6e, 0x4e, 0x7c, 0x4f, 0x42, 0xe3, 0xaa, 0x1a, 0xf7, 0x44, 0xa8, 0x4a, 0x85,
+ /*a0a0:*/ 0xa5, 0xcc, 0x07, 0x7c, 0x2a, 0x23, 0xab, 0x1d, 0xf7, 0xa0, 0xd5, 0xd9, 0x9b, 0xfc, 0xf9, 0x9b,
+ /*a0b0:*/ 0xec, 0x93, 0xd4, 0x03, 0x86, 0x1d, 0x0b, 0x02, 0x82, 0xde, 0x06, 0xb3, 0xd1, 0x58, 0x03, 0xf1,
+ /*a0c0:*/ 0xbd, 0x8f, 0xf8, 0xc9, 0x39, 0x9d, 0xce, 0x16, 0x54, 0xb0, 0x42, 0x8b, 0xac, 0x08, 0x5c, 0xfb,
+ /*a0d0:*/ 0x0c, 0xcb, 0x79, 0xfc, 0x65, 0xe0, 0xe6, 0x54, 0xcd, 0x39, 0x6d, 0x3d, 0x67, 0x69, 0xf4, 0xb6,
+ /*a0e0:*/ 0x0d, 0x51, 0xb2, 0x3b, 0xc0, 0x61, 0x97, 0xde, 0xbd, 0x7f, 0x0a, 0xe0, 0xb0, 0xd7, 0x46, 0x21,
+ /*a0f0:*/ 0xb4, 0xa5, 0x9b, 0x96, 0x3c, 0xf5, 0x75, 0x39, 0x44, 0xb9, 0x06, 0xf2, 0xf7, 0x51, 0xc8, 0xfa,
+ /*a100:*/ 0x6f, 0x1c, 0x06, 0x3c, 0x90, 0xf0, 0xf6, 0x67, 0x17, 0xe8, 0xb2, 0x0c, 0x75, 0x40, 0x92, 0x4d,
+ /*a110:*/ 0x41, 0x08, 0x39, 0xf9, 0x71, 0xb8, 0xe5, 0xbf, 0x8f, 0xad, 0x90, 0x84, 0x29, 0x48, 0x8e, 0x75,
+ /*a120:*/ 0x4f, 0xb3, 0xf3, 0xe3, 0xc3, 0xf5, 0x3d, 0xe6, 0x95, 0xfb, 0x14, 0x5b, 0x89, 0xe4, 0xd8, 0xf3,
+ /*a130:*/ 0x16, 0x26, 0x76, 0xf5, 0x76, 0x43, 0x1f, 0xe3, 0x0b, 0xe4, 0xb7, 0x5a, 0x1a, 0x2c, 0x71, 0xb0,
+ /*a140:*/ 0xd4, 0xd0, 0x09, 0x8c, 0x64, 0x70, 0x57, 0x98, 0xe6, 0xa6, 0x10, 0x6f, 0xde, 0xe1, 0xa5, 0x45,
+ /*a150:*/ 0x9e, 0x41, 0x35, 0x3f, 0x78, 0x8e, 0xf1, 0x3c, 0x30, 0x32, 0xe2, 0xe1, 0xa6, 0xd8, 0x58, 0xc0,
+ /*a160:*/ 0xa4, 0x69, 0x1a, 0x5a, 0xb2, 0x56, 0x7f, 0x33, 0x3f, 0x10, 0x77, 0x92, 0xa7, 0xc0, 0xb2, 0xc0,
+ /*a170:*/ 0xf8, 0x27, 0xa5, 0xcd, 0xfa, 0x27, 0x9f, 0xe3, 0x28, 0x59, 0x54, 0xb3, 0x43, 0xf8, 0xd7, 0x20,
+ /*a180:*/ 0x25, 0xee, 0x34, 0x3d, 0x66, 0xa1, 0x48, 0x83, 0x61, 0x03, 0x29, 0xcb, 0xbb, 0x72, 0x56, 0x1d,
+ /*a190:*/ 0x66, 0xfc, 0xcf, 0x6e, 0x28, 0x22, 0xed, 0x3a, 0x2f, 0xdb, 0x4a, 0x0b, 0xa6, 0xbe, 0xb2, 0xe4,
+ /*a1a0:*/ 0x26, 0x40, 0x82, 0xd0, 0xab, 0xfa, 0x95, 0x03, 0x4d, 0xdb, 0x5b, 0x97, 0x65, 0x36, 0x4a, 0x5e,
+ /*a1b0:*/ 0xd9, 0x63, 0xc8, 0x9c, 0xbe, 0x70, 0x76, 0xee, 0xa0, 0xcf, 0x34, 0xad, 0xcd, 0xa1, 0x81, 0x19,
+ /*a1c0:*/ 0x71, 0x49, 0xb7, 0xc9, 0x47, 0xec, 0x92, 0x32, 0xc8, 0xf0, 0xe0, 0x30, 0xee, 0x9a, 0xbb, 0x11,
+ /*a1d0:*/ 0x8e, 0xe4, 0xa8, 0xdb, 0x1f, 0x29, 0xf5, 0xcf, 0x16, 0x82, 0x7b, 0xcf, 0x10, 0x48, 0xaa, 0x55,
+ /*a1e0:*/ 0x75, 0x9e, 0x8b, 0xc1, 0x34, 0xd2, 0x91, 0xd1, 0x56, 0x51, 0xee, 0xcb, 0xc5, 0x8b, 0xeb, 0x30,
+ /*a1f0:*/ 0xa9, 0x0c, 0xcd, 0x05, 0x7c, 0xd0, 0x64, 0x8b, 0x66, 0xba, 0x59, 0xd2, 0x0d, 0x87, 0x8f, 0xf6,
+ /*a200:*/ 0x67, 0x8b, 0x85, 0x44, 0x7f, 0xd9, 0x02, 0xfd, 0x75, 0x0b, 0x11, 0x45, 0xa5, 0x1d, 0x2a, 0x37,
+ /*a210:*/ 0xd8, 0xe7, 0xde, 0x33, 0xcf, 0xdb, 0xdb, 0x31, 0xe4, 0xf5, 0x41, 0xae, 0x33, 0x6e, 0x0e, 0x02,
+ /*a220:*/ 0x02, 0x38, 0xd7, 0x67, 0xb5, 0x24, 0xe9, 0x31, 0x91, 0x0f, 0x5f, 0x24, 0xd3, 0x2f, 0x41, 0xe7,
+ /*a230:*/ 0x8a, 0xb0, 0x5c, 0x88, 0x32, 0x4e, 0xff, 0xf1, 0xa4, 0xaf, 0xa8, 0x6b, 0x04, 0x5d, 0x0e, 0xb2,
+ /*a240:*/ 0xd8, 0x69, 0x74, 0x5b, 0xbc, 0x91, 0xf3, 0x59, 0x98, 0xf5, 0x13, 0xdd, 0x10, 0x45, 0x02, 0x6d,
+ /*a250:*/ 0xcb, 0x3e, 0x01, 0x31, 0xa0, 0x29, 0x07, 0x67, 0x3b, 0x04, 0x4a, 0xc3, 0x9c, 0x9e, 0x90, 0xa0,
+ /*a260:*/ 0x1d, 0xc1, 0x6a, 0x9e, 0xef, 0xd5, 0xf2, 0x1f, 0x91, 0xd0, 0xe7, 0xe2, 0x76, 0x83, 0xaa, 0x85,
+ /*a270:*/ 0xd6, 0x29, 0x8a, 0x74, 0x09, 0x94, 0xed, 0x4e, 0x2b, 0xd9, 0x6a, 0x55, 0x70, 0x3d, 0x16, 0x57,
+ /*a280:*/ 0xd4, 0x9e, 0x31, 0x66, 0x8b, 0xf4, 0x6a, 0x70, 0xce, 0xe5, 0x33, 0xc0, 0xb4, 0xcf, 0x41, 0xf7,
+ /*a290:*/ 0xb2, 0xbf, 0x95, 0xa1, 0xe3, 0x8b, 0x2e, 0x46, 0x1f, 0x44, 0xe5, 0xd0, 0x5e, 0x99, 0x4a, 0xb6,
+ /*a2a0:*/ 0x65, 0x90, 0x74, 0x2a, 0x8e, 0xbc, 0x1f, 0x17, 0x6a, 0x01, 0x05, 0xb7, 0xb5, 0xd2, 0xab, 0xf6,
+ /*a2b0:*/ 0xe6, 0x90, 0x5a, 0x07, 0xa1, 0x7c, 0x68, 0x9d, 0x7a, 0x88, 0x1c, 0x10, 0xa4, 0xe3, 0x7b, 0xbb,
+ /*a2c0:*/ 0xf4, 0xb0, 0x1f, 0x59, 0x96, 0x31, 0xea, 0xc5, 0xf2, 0x7e, 0x1e, 0x31, 0xa2, 0x94, 0x84, 0x3a,
+ /*a2d0:*/ 0xbd, 0x08, 0x8a, 0x3a, 0xa5, 0x6d, 0x0e, 0x45, 0x63, 0xd8, 0xe5, 0xf4, 0x53, 0xd5, 0x04, 0x64,
+ /*a2e0:*/ 0x43, 0x14, 0xed, 0x45, 0x96, 0x31, 0xdd, 0x73, 0xf8, 0xe5, 0x1f, 0x4f, 0xd7, 0x41, 0x9e, 0xed,
+ /*a2f0:*/ 0x87, 0xb0, 0x20, 0x8a, 0x51, 0xcf, 0x9e, 0x42, 0xe4, 0xb8, 0xce, 0x61, 0xbe, 0x3f, 0x03, 0xf6,
+ /*a300:*/ 0xdd, 0x55, 0x57, 0x17, 0x89, 0xe3, 0x11, 0x2f, 0x75, 0x54, 0x8f, 0xcc, 0x69, 0xc8, 0xd9, 0xd0,
+ /*a310:*/ 0x17, 0xfc, 0x6a, 0x4f, 0x11, 0x08, 0xc5, 0x67, 0xd4, 0xdd, 0x6e, 0x9c, 0xae, 0x18, 0x05, 0x50,
+ /*a320:*/ 0xd9, 0xb0, 0x75, 0x8c, 0x4a, 0x0a, 0xb9, 0x37, 0x91, 0x38, 0xab, 0x5e, 0xbc, 0xe0, 0x15, 0x07,
+ /*a330:*/ 0x10, 0xdd, 0x4c, 0xb2, 0xc7, 0x62, 0x57, 0x51, 0x72, 0xe9, 0x23, 0x50, 0x47, 0xf9, 0xc2, 0x31,
+ /*a340:*/ 0x40, 0x47, 0xfd, 0xe3, 0xf6, 0x45, 0xc4, 0xd8, 0x3b, 0x42, 0x47, 0xed, 0xd6, 0x36, 0x0a, 0x66,
+ /*a350:*/ 0x96, 0x1d, 0x3a, 0x27, 0x59, 0xa3, 0x51, 0xa6, 0xc0, 0x6c, 0xdb, 0x43, 0x0f, 0x86, 0xcb, 0xe6,
+ /*a360:*/ 0x01, 0x2d, 0x42, 0xcd, 0xa7, 0x63, 0x27, 0x0e, 0xd0, 0xdb, 0xa9, 0x39, 0xbe, 0x43, 0x78, 0x16,
+ /*a370:*/ 0x54, 0xcc, 0xff, 0x0d, 0x4c, 0x44, 0x22, 0x9e, 0xbf, 0x33, 0xbb, 0xb6, 0xd5, 0x9b, 0xe1, 0x80,
+ /*a380:*/ 0x26, 0x54, 0x76, 0xe7, 0xcb, 0x8b, 0x36, 0x9c, 0x85, 0xb7, 0xee, 0x62, 0x26, 0xa0, 0xd9, 0x99,
+ /*a390:*/ 0x1d, 0x8e, 0xfc, 0x66, 0xb8, 0x80, 0x64, 0x74, 0xc7, 0x5a, 0x51, 0x4e, 0x27, 0xac, 0x53, 0xb5,
+ /*a3a0:*/ 0x94, 0xf8, 0xab, 0xd9, 0xf9, 0x7b, 0xdd, 0xda, 0xac, 0xd6, 0xf8, 0x81, 0x8b, 0x1e, 0xd2, 0x11,
+ /*a3b0:*/ 0xc3, 0x2a, 0xc2, 0x32, 0xb5, 0x96, 0x11, 0xae, 0xa5, 0x44, 0xe8, 0xe3, 0x37, 0x2e, 0xe5, 0x46,
+ /*a3c0:*/ 0x89, 0xc1, 0x4a, 0x18, 0xdd, 0x0d, 0x08, 0x7c, 0x54, 0x4e, 0xe6, 0x48, 0x76, 0x74, 0x19, 0x7e,
+ /*a3d0:*/ 0x40, 0xf4, 0xf4, 0xe6, 0x04, 0x1c, 0xe2, 0x19, 0x2a, 0x87, 0x1d, 0x07, 0x3b, 0xf9, 0xf5, 0x72,
+ /*a3e0:*/ 0x67, 0xc5, 0xd5, 0x53, 0x5d, 0xa2, 0x6f, 0x87, 0x38, 0xe6, 0x3d, 0x7c, 0xf5, 0xcd, 0x02, 0xfc,
+ /*a3f0:*/ 0xf2, 0x74, 0x27, 0x62, 0x62, 0x71, 0x45, 0xaa, 0x1f, 0xbd, 0x49, 0x8c, 0xa3, 0xb8, 0xf7, 0x14,
+ /*a400:*/ 0xac, 0x49, 0xeb, 0xb3, 0x8f, 0x5f, 0x12, 0x46, 0x07, 0x28, 0x32, 0x4a, 0x50, 0x0e, 0x98, 0xb3,
+ /*a410:*/ 0x8f, 0x63, 0x38, 0x45, 0x76, 0xf1, 0xcf, 0x04, 0x86, 0x16, 0x2f, 0x10, 0xbd, 0xa0, 0xb1, 0xd1,
+ /*a420:*/ 0xe4, 0x32, 0x09, 0xa3, 0x0c, 0x4c, 0xf3, 0xb0, 0x3b, 0x7d, 0xa8, 0x9b, 0xf7, 0x6c, 0x11, 0xce,
+ /*a430:*/ 0xe4, 0x19, 0x8c, 0xbb, 0x27, 0x12, 0x73, 0x9f, 0xe9, 0x46, 0x4a, 0x82, 0xf9, 0x26, 0x30, 0x4e,
+ /*a440:*/ 0xef, 0x11, 0x55, 0x98, 0x2c, 0xa4, 0xf4, 0xa9, 0x42, 0x56, 0x67, 0x36, 0xbf, 0x8c, 0xe4, 0x8c,
+ /*a450:*/ 0xf8, 0x47, 0x8f, 0x73, 0x3a, 0x0c, 0xdd, 0xe6, 0x49, 0x29, 0x12, 0xf4, 0xc2, 0x7d, 0x72, 0x0f,
+ /*a460:*/ 0xa5, 0x5b, 0xb9, 0x19, 0xfe, 0x24, 0x65, 0xfd, 0x5a, 0xe6, 0x3f, 0xb0, 0x2c, 0x78, 0xec, 0x3f,
+ /*a470:*/ 0x1f, 0xc2, 0xa8, 0xd0, 0xdf, 0x1b, 0xa1, 0x9b, 0x47, 0x0b, 0x16, 0xb2, 0x1d, 0x75, 0xba, 0x23,
+ /*a480:*/ 0x20, 0x5a, 0x88, 0xca, 0x99, 0x54, 0x00, 0x8e, 0xd4, 0x9e, 0x31, 0x71, 0xdf, 0xb8, 0xf9, 0x23,
+ /*a490:*/ 0xc7, 0x88, 0x2a, 0x40, 0xc5, 0x5f, 0x17, 0x07, 0xe5, 0xab, 0x70, 0xff, 0xac, 0x79, 0xe8, 0x51,
+ /*a4a0:*/ 0x9c, 0x9f, 0x06, 0x43, 0x31, 0x7a, 0x0f, 0xa1, 0x12, 0x5a, 0x50, 0x86, 0x7a, 0x0f, 0xf9, 0xf2,
+ /*a4b0:*/ 0x13, 0x7d, 0x11, 0x72, 0x56, 0xa5, 0x54, 0x52, 0xb4, 0xcf, 0xb0, 0xdb, 0xce, 0xe1, 0x02, 0x8e,
+ /*a4c0:*/ 0xeb, 0xf8, 0xc6, 0xdd, 0xcf, 0x7f, 0x48, 0xa6, 0x18, 0xc1, 0x8e, 0xeb, 0xf7, 0xf0, 0x59, 0x2e,
+ /*a4d0:*/ 0xb5, 0xb0, 0x29, 0x7c, 0x46, 0x88, 0xfb, 0xf8, 0x5e, 0xb8, 0xd1, 0x96, 0x23, 0x8e, 0xaf, 0x06,
+ /*a4e0:*/ 0x44, 0x1b, 0xe0, 0xac, 0xf9, 0x5c, 0xa0, 0x2a, 0x05, 0xfc, 0x8f, 0x74, 0x4d, 0x42, 0x4c, 0xca,
+ /*a4f0:*/ 0xe8, 0x98, 0x96, 0x8c, 0x9b, 0x59, 0x92, 0xb1, 0x9a, 0x19, 0xed, 0x41, 0xc7, 0xe7, 0x61, 0x9b,
+ /*a500:*/ 0x30, 0x3c, 0x5b, 0x45, 0xcf, 0x90, 0xfb, 0xf4, 0x9f, 0xce, 0xc3, 0x83, 0x82, 0x70, 0xc2, 0xfd,
+ /*a510:*/ 0xb6, 0xcd, 0x94, 0x6a, 0x15, 0xa5, 0x30, 0x39, 0xa3, 0xbb, 0x0a, 0x70, 0x18, 0x69, 0x93, 0x7b,
+ /*a520:*/ 0x21, 0x1f, 0x7f, 0x71, 0x61, 0xb7, 0xa3, 0x21, 0xb1, 0xba, 0x65, 0x1d, 0x84, 0x39, 0xc7, 0x4e,
+ /*a530:*/ 0x21, 0x2f, 0xfe, 0x8a, 0x0f, 0xdf, 0x81, 0xbb, 0xb2, 0x72, 0x71, 0x25, 0xfa, 0xc2, 0xc5, 0xff,
+ /*a540:*/ 0x99, 0x6d, 0x1f, 0xa3, 0xfc, 0xf3, 0xec, 0x32, 0x92, 0xd3, 0x28, 0xf2, 0xc6, 0x26, 0x1f, 0xa0,
+ /*a550:*/ 0xe6, 0xdf, 0xc5, 0xb2, 0x6b, 0x17, 0x69, 0x64, 0xe1, 0xda, 0x68, 0x38, 0x14, 0xf5, 0x2e, 0xf5,
+ /*a560:*/ 0xaf, 0x57, 0x74, 0x44, 0xe1, 0x28, 0x6e, 0x2e, 0x28, 0x7f, 0x99, 0x1c, 0x23, 0x26, 0x96, 0x38,
+ /*a570:*/ 0xcb, 0x70, 0x62, 0x53, 0x1b, 0x70, 0xb3, 0x1b, 0xbb, 0x9a, 0x9e, 0x31, 0xfd, 0x6f, 0x74, 0x84,
+ /*a580:*/ 0x5c, 0xd5, 0xf7, 0x10, 0xf7, 0x76, 0xd4, 0x22, 0xe6, 0x5e, 0x4b, 0xad, 0x41, 0xe6, 0x23, 0xe5,
+ /*a590:*/ 0x36, 0xf1, 0x2b, 0x57, 0x87, 0x97, 0x60, 0x46, 0x9d, 0xea, 0x18, 0x25, 0xcf, 0x33, 0x4f, 0x68,
+ /*a5a0:*/ 0x4d, 0x9f, 0x61, 0x59, 0x09, 0xf4, 0x45, 0xa3, 0x03, 0x76, 0x68, 0x24, 0x18, 0x36, 0xbe, 0xb7,
+ /*a5b0:*/ 0x78, 0xf7, 0xdc, 0x21, 0xce, 0x36, 0x28, 0xd2, 0x79, 0xb9, 0xda, 0xf3, 0x7f, 0xc0, 0x74, 0x55,
+ /*a5c0:*/ 0x00, 0x38, 0x57, 0x73, 0x9b, 0x1e, 0x80, 0x84, 0x55, 0xfc, 0x35, 0x1c, 0xbd, 0x8c, 0x27, 0xf0,
+ /*a5d0:*/ 0x6d, 0xef, 0x8a, 0x6a, 0x3a, 0x76, 0x77, 0xd1, 0xf3, 0xf7, 0xbc, 0xdd, 0x97, 0x0b, 0x68, 0xcc,
+ /*a5e0:*/ 0x2b, 0xdc, 0x1f, 0xde, 0x52, 0x66, 0x67, 0x7d, 0x72, 0x4c, 0x2c, 0xa8, 0xf1, 0x8d, 0x6d, 0xa3,
+ /*a5f0:*/ 0x4c, 0x33, 0xcf, 0xa9, 0x25, 0x6b, 0x6e, 0xe0, 0x48, 0x81, 0x51, 0x85, 0xf4, 0x33, 0xda, 0x32,
+ /*a600:*/ 0x7b, 0xdd, 0xa8, 0x0e, 0x94, 0x08, 0xc2, 0x16, 0xd0, 0xdd, 0x93, 0x22, 0xdc, 0x90, 0x04, 0xc9,
+ /*a610:*/ 0xee, 0x2a, 0xcd, 0x58, 0xac, 0xf7, 0x9a, 0xe2, 0xd9, 0x0a, 0x7b, 0x18, 0x9f, 0x85, 0xfc, 0x8e,
+ /*a620:*/ 0xb6, 0x5c, 0x05, 0x46, 0x94, 0x55, 0xd5, 0x28, 0x84, 0x0a, 0xb1, 0x35, 0x8d, 0x38, 0x34, 0xd5,
+ /*a630:*/ 0xd6, 0x2b, 0x66, 0xd6, 0xc1, 0x19, 0x5d, 0x99, 0x2f, 0xbe, 0x7f, 0xd9, 0x53, 0xa5, 0x6f, 0xa0,
+ /*a640:*/ 0x18, 0xb5, 0x77, 0x12, 0x56, 0xdd, 0x64, 0x4c, 0x84, 0x43, 0xa6, 0x05, 0x29, 0xf2, 0x70, 0x88,
+ /*a650:*/ 0x64, 0x1e, 0x28, 0x35, 0x31, 0x2d, 0x9a, 0xa0, 0x1e, 0x05, 0x53, 0xa2, 0xf1, 0xa9, 0xa8, 0xae,
+ /*a660:*/ 0x6d, 0x93, 0x13, 0x2d, 0xeb, 0x94, 0xe9, 0x7f, 0x9e, 0x05, 0x52, 0x18, 0xa0, 0xaa, 0x4d, 0x25,
+ /*a670:*/ 0xf2, 0x1c, 0xa6, 0xf4, 0x38, 0x14, 0x36, 0xb6, 0x0c, 0x5f, 0xb3, 0x26, 0x1f, 0x35, 0x3d, 0x6d,
+ /*a680:*/ 0xa2, 0xa1, 0x06, 0x41, 0x44, 0xf2, 0xc2, 0xee, 0x8a, 0xf0, 0x5b, 0x4c, 0x15, 0xa2, 0x1d, 0xd1,
+ /*a690:*/ 0xd3, 0x44, 0x89, 0x49, 0x92, 0xe3, 0x1c, 0x15, 0x69, 0x43, 0xab, 0x10, 0xce, 0x16, 0xcf, 0x82,
+ /*a6a0:*/ 0x5b, 0x81, 0x1b, 0x86, 0x8b, 0x71, 0x79, 0x47, 0x49, 0x87, 0x8f, 0x73, 0x7a, 0xc2, 0xda, 0xb6,
+ /*a6b0:*/ 0x68, 0x45, 0x4d, 0x41, 0xbc, 0xec, 0x5c, 0x4a, 0xb1, 0x8b, 0x2d, 0xc2, 0x1f, 0x62, 0xd8, 0x8c,
+ /*a6c0:*/ 0x9e, 0x0d, 0x00, 0x5b, 0x20, 0x23, 0x39, 0xfe, 0x8c, 0x1c, 0x1d, 0xf6, 0xb8, 0x86, 0xb4, 0x2b,
+ /*a6d0:*/ 0xe2, 0xe9, 0x79, 0xc4, 0x30, 0xcf, 0xd8, 0xc4, 0x9d, 0xcf, 0x9d, 0xb2, 0xd3, 0x50, 0x2b, 0xdc,
+ /*a6e0:*/ 0xae, 0xfb, 0x67, 0x50, 0x73, 0x86, 0x0c, 0x01, 0x31, 0x8e, 0xb0, 0x98, 0x96, 0xe9, 0x3c, 0x58,
+ /*a6f0:*/ 0x08, 0x68, 0x0a, 0x63, 0xd2, 0xdf, 0xc7, 0x2e, 0xd5, 0xed, 0x14, 0xeb, 0x61, 0x56, 0x63, 0xa1,
+ /*a700:*/ 0xc1, 0xa9, 0x26, 0x25, 0xe8, 0x6c, 0xea, 0xa0, 0x5a, 0x8e, 0xaf, 0x5d, 0xca, 0x06, 0xa4, 0x64,
+ /*a710:*/ 0xad, 0xf8, 0xbd, 0x90, 0xbb, 0xbf, 0xb7, 0xb6, 0x25, 0x5d, 0x09, 0x39, 0x82, 0x01, 0x7d, 0xfb,
+ /*a720:*/ 0x31, 0x3c, 0x82, 0x2b, 0x40, 0x63, 0x01, 0x80, 0x4e, 0x7c, 0xe8, 0x6c, 0x9b, 0xef, 0x12, 0x2c,
+ /*a730:*/ 0x8d, 0x63, 0xff, 0xf5, 0xad, 0x77, 0x59, 0x39, 0x20, 0x99, 0x85, 0x51, 0xe7, 0x75, 0x07, 0xac,
+ /*a740:*/ 0xe8, 0x30, 0xa4, 0xc9, 0xbf, 0x9f, 0xa4, 0x1f, 0x11, 0x98, 0x01, 0x9b, 0xfb, 0x96, 0x7d, 0xa3,
+ /*a750:*/ 0xaf, 0x73, 0x15, 0x7b, 0xce, 0x7a, 0xce, 0x2c, 0x00, 0xa1, 0x0f, 0x3c, 0x49, 0x6c, 0x62, 0x4c,
+ /*a760:*/ 0x7c, 0xec, 0xbb, 0x44, 0xb5, 0xed, 0x16, 0x9d, 0x57, 0x2b, 0x76, 0x56, 0x57, 0x54, 0x8d, 0xd7,
+ /*a770:*/ 0xa1, 0x6c, 0xd8, 0x0f, 0xb5, 0x13, 0xe0, 0x56, 0xb6, 0xea, 0xaf, 0x60, 0x13, 0xd1, 0xf8, 0xbc,
+ /*a780:*/ 0x58, 0xa8, 0x52, 0x5e, 0x42, 0x1b, 0x70, 0x7d, 0x63, 0x7d, 0x8b, 0x69, 0x82, 0xc3, 0xab, 0x38,
+ /*a790:*/ 0x64, 0x82, 0xef, 0x3f, 0xa9, 0xd9, 0x51, 0x5c, 0x4b, 0x88, 0x35, 0x17, 0xc4, 0xd2, 0x2d, 0xa5,
+ /*a7a0:*/ 0x46, 0xb0, 0x11, 0xcf, 0x6d, 0x94, 0xa3, 0x93, 0x93, 0xb7, 0xa7, 0xf8, 0x09, 0x39, 0x03, 0x1c,
+ /*a7b0:*/ 0x15, 0xba, 0x34, 0x3e, 0xe0, 0x08, 0xda, 0x0a, 0x93, 0xa2, 0x35, 0x23, 0x9b, 0xa0, 0x49, 0x7e,
+ /*a7c0:*/ 0x58, 0xe4, 0x6d, 0xef, 0x21, 0xbd, 0xfb, 0x15, 0xe5, 0xb2, 0x26, 0xb9, 0xd9, 0xab, 0xef, 0x0e,
+ /*a7d0:*/ 0x12, 0xfc, 0x24, 0xd6, 0x5c, 0xfd, 0x0e, 0xf2, 0x00, 0x12, 0x0f, 0x22, 0x0c, 0x53, 0x54, 0xdd,
+ /*a7e0:*/ 0xe6, 0x04, 0x61, 0xcb, 0xf5, 0x4b, 0xd0, 0x91, 0x24, 0x7e, 0x91, 0x95, 0x07, 0x41, 0x4c, 0x32,
+ /*a7f0:*/ 0x64, 0x44, 0x4e, 0xdc, 0x0b, 0xf4, 0x8a, 0xb5, 0x75, 0xc8, 0x73, 0xee, 0xc3, 0x7d, 0xb0, 0xbf,
+ /*a800:*/ 0x63, 0x7d, 0x69, 0x96, 0x58, 0x9c, 0x10, 0xed, 0xe6, 0x5a, 0x55, 0xf7, 0x20, 0xda, 0xbd, 0x1b,
+ /*a810:*/ 0xba, 0x0a, 0xab, 0x36, 0x1f, 0xe3, 0xe0, 0x3c, 0x20, 0xae, 0x90, 0x60, 0xcd, 0xe0, 0x29, 0xe7,
+ /*a820:*/ 0x41, 0x27, 0x68, 0x1c, 0xf3, 0xcc, 0xb7, 0x79, 0xfb, 0x06, 0x48, 0x89, 0x61, 0xb2, 0x02, 0xb2,
+ /*a830:*/ 0xcf, 0x61, 0xe9, 0x77, 0x9f, 0x8d, 0x7e, 0x19, 0x2b, 0xd0, 0x2d, 0xf9, 0x61, 0x29, 0xc9, 0x46,
+ /*a840:*/ 0x84, 0xd1, 0x54, 0x4d, 0x83, 0xb0, 0x8c, 0x33, 0x4f, 0xa5, 0xeb, 0x98, 0xa0, 0x41, 0x5b, 0xa0,
+ /*a850:*/ 0x04, 0x09, 0x37, 0xc2, 0xa7, 0x5f, 0xdf, 0x63, 0xa8, 0x82, 0x78, 0xf9, 0xea, 0xfc, 0xde, 0xa5,
+ /*a860:*/ 0x5c, 0xe4, 0xd9, 0x80, 0x54, 0x78, 0x34, 0x77, 0x59, 0x2b, 0xbb, 0x38, 0x6e, 0xdd, 0x57, 0x9e,
+ /*a870:*/ 0xd7, 0xe3, 0x9c, 0x67, 0x2e, 0xc1, 0xa1, 0x9d, 0xf2, 0xa1, 0xb8, 0x99, 0xc0, 0x89, 0x83, 0x2c,
+ /*a880:*/ 0x03, 0xfc, 0xc0, 0x03, 0x77, 0x06, 0xc9, 0xbe, 0x8a, 0xe6, 0xaa, 0x42, 0x95, 0x43, 0x57, 0x30,
+ /*a890:*/ 0xdf, 0xc0, 0x71, 0x9b, 0x42, 0x39, 0x67, 0x35, 0xc1, 0xa8, 0xb0, 0x16, 0xe3, 0xc3, 0xa8, 0x20,
+ /*a8a0:*/ 0xd6, 0x11, 0xed, 0x12, 0x42, 0x62, 0x2e, 0x2b, 0x17, 0x43, 0x3a, 0x27, 0x0d, 0x83, 0xd6, 0x87,
+ /*a8b0:*/ 0x70, 0x0e, 0x84, 0x01, 0xfd, 0xa1, 0xd9, 0x2b, 0x5c, 0xdb, 0xf9, 0xbe, 0x27, 0xd3, 0x05, 0x7a,
+ /*a8c0:*/ 0x89, 0x77, 0x23, 0x7a, 0x0c, 0x4c, 0x3f, 0xb3, 0xbc, 0xc1, 0x80, 0xde, 0x88, 0x68, 0x6c, 0xbe,
+ /*a8d0:*/ 0x6b, 0xa0, 0xf4, 0xfe, 0x9d, 0xde, 0xa4, 0x8d, 0xc8, 0xfe, 0x8f, 0x0d, 0xf8, 0xfb, 0xe3, 0x33,
+ /*a8e0:*/ 0xd9, 0x9f, 0x38, 0x44, 0xf0, 0x1e, 0x13, 0x87, 0x4a, 0x35, 0x79, 0xbd, 0x56, 0x77, 0x4d, 0x2e,
+ /*a8f0:*/ 0xed, 0x44, 0x05, 0x70, 0xcb, 0xee, 0x56, 0xb8, 0x40, 0xc4, 0x29, 0x1a, 0xaf, 0x14, 0xd3, 0xd3,
+ /*a900:*/ 0x18, 0x34, 0x77, 0x79, 0x7c, 0x69, 0x36, 0xbc, 0x18, 0xea, 0xc8, 0x5e, 0xdf, 0x17, 0xfe, 0xf0,
+ /*a910:*/ 0x22, 0xd7, 0x5c, 0xa7, 0x24, 0xd8, 0xe9, 0x85, 0x2f, 0x08, 0xef, 0x68, 0x9a, 0xe9, 0x81, 0x80,
+ /*a920:*/ 0xe2, 0xb2, 0x5d, 0x11, 0x30, 0xf0, 0xa9, 0xab, 0x6b, 0xee, 0x2c, 0x62, 0x0a, 0xde, 0xec, 0x4e,
+ /*a930:*/ 0xd0, 0x25, 0xbb, 0xd5, 0xc5, 0x2d, 0xa8, 0xea, 0x1e, 0x7b, 0xfc, 0x84, 0x4b, 0x38, 0xb8, 0x90,
+ /*a940:*/ 0x8d, 0x4b, 0x3d, 0x7c, 0xa6, 0x8d, 0x1a, 0x73, 0x0f, 0x72, 0xb9, 0x2a, 0xc2, 0x31, 0x3c, 0xa5,
+ /*a950:*/ 0x18, 0xfe, 0x02, 0xb6, 0x2f, 0xfa, 0x3c, 0x23, 0x99, 0x73, 0x93, 0xcf, 0x14, 0x06, 0xb8, 0x76,
+ /*a960:*/ 0xf5, 0x66, 0xb2, 0xb8, 0x04, 0xd0, 0x10, 0x13, 0x38, 0x41, 0x17, 0x59, 0x20, 0x63, 0x09, 0xee,
+ /*a970:*/ 0x1b, 0xae, 0xc0, 0xea, 0xf3, 0xbf, 0xca, 0x9f, 0x25, 0x94, 0x0c, 0x96, 0x3f, 0x2d, 0x99, 0xc3,
+ /*a980:*/ 0x42, 0xe4, 0xe0, 0x92, 0x9c, 0x13, 0x0d, 0xb6, 0x87, 0xd6, 0x42, 0xbd, 0x35, 0xb2, 0x72, 0x57,
+ /*a990:*/ 0xb4, 0x52, 0x16, 0xa3, 0x86, 0x82, 0x21, 0x67, 0x5f, 0xff, 0x3d, 0x58, 0xcd, 0xb1, 0x9e, 0xbd,
+ /*a9a0:*/ 0x15, 0x87, 0x1e, 0x2f, 0x8d, 0x98, 0xcf, 0x4b, 0x93, 0x7b, 0x3f, 0xdd, 0x7c, 0x2b, 0xc5, 0x57,
+ /*a9b0:*/ 0x9b, 0x98, 0xfb, 0xc7, 0x53, 0xc3, 0x1f, 0xae, 0x9d, 0xd6, 0xed, 0xc8, 0xd0, 0xb6, 0x34, 0x21,
+ /*a9c0:*/ 0x94, 0xf3, 0x95, 0xfb, 0xf0, 0x80, 0x24, 0x98, 0x0f, 0xd1, 0xd3, 0xe0, 0xfd, 0xc5, 0xcd, 0xa6,
+ /*a9d0:*/ 0xda, 0xfb, 0x58, 0xb0, 0x1b, 0x9a, 0x24, 0x59, 0xaf, 0x55, 0xa6, 0x82, 0xab, 0x21, 0x40, 0x4a,
+ /*a9e0:*/ 0xaa, 0x4e, 0xcd, 0x23, 0x7d, 0x2b, 0xa3, 0x01, 0x18, 0x63, 0xfd, 0x2f, 0x12, 0xd3, 0x2b, 0x25,
+ /*a9f0:*/ 0xbd, 0xb0, 0x10, 0x59, 0x7c, 0x85, 0x5d, 0xdb, 0x28, 0x34, 0xd1, 0x1d, 0x9d, 0x50, 0x78, 0xef,
+ /*aa00:*/ 0x84, 0x97, 0x1a, 0x49, 0x1a, 0x8b, 0xd3, 0x88, 0xbe, 0x67, 0xac, 0x4a, 0x1f, 0x1b, 0x15, 0x21,
+ /*aa10:*/ 0x61, 0x85, 0xf3, 0x74, 0x48, 0x20, 0xe1, 0x55, 0x16, 0x2a, 0xf3, 0xdd, 0x5c, 0x9e, 0xc9, 0x13,
+ /*aa20:*/ 0x55, 0x70, 0xf7, 0xc1, 0x07, 0xcb, 0xa2, 0xa5, 0x7d, 0x7d, 0xcb, 0xbb, 0x56, 0x07, 0x7a, 0x5a,
+ /*aa30:*/ 0xa4, 0xf7, 0x1b, 0x28, 0x0a, 0x89, 0xef, 0x5a, 0x28, 0x01, 0xe0, 0xbb, 0x67, 0x9d, 0xab, 0x2f,
+ /*aa40:*/ 0xb8, 0x71, 0x48, 0x6c, 0x6e, 0x98, 0xc5, 0x7d, 0x81, 0xcd, 0xba, 0xc2, 0x70, 0x63, 0x9e, 0x87,
+ /*aa50:*/ 0x14, 0x54, 0xbb, 0xbb, 0xd6, 0x7b, 0xb1, 0xaa, 0xae, 0x22, 0xba, 0x87, 0x80, 0x59, 0x6f, 0x23,
+ /*aa60:*/ 0x06, 0x5c, 0x6c, 0x1d, 0x34, 0x70, 0xce, 0xfd, 0x37, 0x73, 0xff, 0x85, 0x92, 0xae, 0x13, 0xb7,
+ /*aa70:*/ 0x67, 0x5d, 0x32, 0xff, 0x39, 0x8e, 0x52, 0xaa, 0x3c, 0x99, 0xa7, 0xe9, 0x27, 0x4e, 0xbb, 0x58,
+ /*aa80:*/ 0x78, 0xa2, 0x85, 0x36, 0xad, 0xa5, 0xbe, 0xa9, 0x78, 0xc4, 0xae, 0x78, 0xef, 0xea, 0x18, 0x24,
+ /*aa90:*/ 0x50, 0x4a, 0x56, 0x85, 0x6c, 0xdc, 0x69, 0x14, 0xe2, 0xe0, 0xb3, 0x8d, 0x2e, 0xdf, 0x62, 0x47,
+ /*aaa0:*/ 0xcf, 0xf2, 0xee, 0xe2, 0x0b, 0xab, 0x08, 0xf0, 0x89, 0x29, 0x91, 0x12, 0xfc, 0x9f, 0x4c, 0xb9,
+ /*aab0:*/ 0x0c, 0x92, 0xd3, 0x0d, 0x41, 0x72, 0xce, 0x67, 0xbf, 0x72, 0x4a, 0xd5, 0x10, 0x3b, 0x7b, 0xa0,
+ /*aac0:*/ 0x6e, 0xf4, 0x51, 0x63, 0x47, 0x74, 0xd9, 0x5e, 0x0b, 0xb3, 0x3e, 0x56, 0xb9, 0x90, 0x30, 0xd8,
+ /*aad0:*/ 0xa6, 0x54, 0xf3, 0x87, 0x87, 0xf2, 0xca, 0xa8, 0x81, 0x72, 0xea, 0x07, 0x34, 0x2f, 0xb2, 0x11,
+ /*aae0:*/ 0x23, 0x49, 0xf5, 0x9d, 0x6c, 0x52, 0xd6, 0x41, 0x71, 0xe4, 0x2c, 0xc1, 0x4c, 0x30, 0x9e, 0xf3,
+ /*aaf0:*/ 0xb2, 0x21, 0x21, 0x3e, 0x1f, 0x12, 0x7b, 0x6b, 0xd1, 0xc7, 0xe8, 0xd0, 0x74, 0x1c, 0xf2, 0x46,
+ /*ab00:*/ 0xcc, 0x12, 0x89, 0x97, 0x9e, 0x92, 0x7f, 0x89, 0xdb, 0x82, 0x1c, 0xd4, 0xe8, 0xcd, 0x36, 0x76,
+ /*ab10:*/ 0x6c, 0x09, 0xe3, 0x15, 0x2e, 0x6a, 0xbf, 0x46, 0x28, 0x95, 0x2f, 0x01, 0x92, 0x00, 0x68, 0x6e,
+ /*ab20:*/ 0x5d, 0xbf, 0x3d, 0xc1, 0x29, 0xbf, 0x09, 0x4a, 0x08, 0x74, 0x79, 0x48, 0xb4, 0x5e, 0x5f, 0x52,
+ /*ab30:*/ 0x55, 0x0c, 0x41, 0x69, 0x3d, 0x48, 0xf6, 0xf0, 0x9b, 0x63, 0x1f, 0xaa, 0x6e, 0xfd, 0x7f, 0x0f,
+ /*ab40:*/ 0x83, 0x29, 0x68, 0xd7, 0xb5, 0xa6, 0x12, 0x05, 0x8f, 0x43, 0x07, 0xbc, 0x25, 0xd2, 0xec, 0xb3,
+ /*ab50:*/ 0xab, 0xc9, 0xf3, 0x1f, 0xbb, 0xc2, 0xe3, 0x78, 0x4e, 0xb6, 0x35, 0xfb, 0x94, 0xde, 0xf0, 0xd9,
+ /*ab60:*/ 0xe6, 0xec, 0xf8, 0xae, 0xf8, 0x46, 0x1a, 0x83, 0xd3, 0xdb, 0xfe, 0xbc, 0x80, 0x65, 0x4d, 0xc7,
+ /*ab70:*/ 0x83, 0x75, 0xb2, 0xdd, 0x77, 0xc3, 0x46, 0xd4, 0x32, 0xa4, 0x54, 0xef, 0x9b, 0xa3, 0x76, 0xb7,
+ /*ab80:*/ 0x9e, 0x60, 0x14, 0x6d, 0xd7, 0xb1, 0x47, 0x82, 0xef, 0x2c, 0xcf, 0x88, 0x17, 0x5c, 0xa1, 0xe6,
+ /*ab90:*/ 0x60, 0x22, 0xdb, 0x85, 0x18, 0x11, 0x08, 0xd0, 0x59, 0xc6, 0xe9, 0x19, 0x55, 0x3c, 0x81, 0xf4,
+ /*aba0:*/ 0x6d, 0xec, 0x1b, 0x88, 0xd6, 0xb6, 0x7a, 0x62, 0x5d, 0x7a, 0xc4, 0xf1, 0xf0, 0xa0, 0x09, 0x1a,
+ /*abb0:*/ 0xbc, 0xdf, 0x3c, 0xb0, 0x4f, 0x2b, 0xe1, 0x2e, 0x44, 0x3d, 0x9d, 0x0a, 0xb1, 0x1d, 0x66, 0x62,
+ /*abc0:*/ 0xbe, 0xbf, 0xe2, 0x2b, 0x66, 0xae, 0xa1, 0x35, 0x04, 0x63, 0x77, 0x97, 0xc9, 0x0b, 0xab, 0xeb,
+ /*abd0:*/ 0xf0, 0x61, 0xf2, 0x1f, 0xdb, 0x60, 0x51, 0x6f, 0xda, 0xd6, 0x19, 0xdf, 0x5b, 0xad, 0x6e, 0x02,
+ /*abe0:*/ 0x9c, 0xc8, 0xce, 0x0c, 0xa7, 0xcb, 0x93, 0x3d, 0x3c, 0xff, 0x9e, 0x88, 0xfa, 0xf9, 0x9c, 0x73,
+ /*abf0:*/ 0x9f, 0x3e, 0xbb, 0xa9, 0x40, 0x2c, 0x88, 0x4f, 0x19, 0x59, 0x1a, 0x42, 0x13, 0xca, 0x47, 0xb8,
+ /*ac00:*/ 0x46, 0x77, 0x49, 0xa0, 0xb7, 0xec, 0x73, 0x72, 0xb1, 0x9b, 0x61, 0x07, 0x8a, 0x61, 0x08, 0x1a,
+ /*ac10:*/ 0x4a, 0x59, 0x63, 0x60, 0x2a, 0x0f, 0x5a, 0xdf, 0x3c, 0x23, 0x83, 0x47, 0x32, 0x37, 0xde, 0x8a,
+ /*ac20:*/ 0x30, 0x10, 0x24, 0x3f, 0x31, 0x93, 0xcb, 0xca, 0xfa, 0x5c, 0xf0, 0xf9, 0x28, 0x50, 0x40, 0x2a,
+ /*ac30:*/ 0x62, 0xfd, 0x0b, 0x22, 0x52, 0x0b, 0xa4, 0x4d, 0xc4, 0xbc, 0x88, 0x32, 0x0f, 0x85, 0xab, 0xc9,
+ /*ac40:*/ 0x5c, 0x55, 0xc5, 0x63, 0xbb, 0x2f, 0xfb, 0x41, 0xf6, 0x52, 0xd7, 0x67, 0x35, 0x96, 0x0e, 0xf6,
+ /*ac50:*/ 0x46, 0x10, 0xaa, 0x92, 0x0a, 0xdf, 0xdf, 0xcb, 0x9b, 0xa7, 0xaa, 0x71, 0xe1, 0xd8, 0xfe, 0x03,
+ /*ac60:*/ 0xef, 0x25, 0x22, 0x72, 0x86, 0x42, 0x72, 0x00, 0xfc, 0xd2, 0x13, 0xbe, 0x03, 0x1c, 0x4c, 0x4d,
+ /*ac70:*/ 0x48, 0xb3, 0xaf, 0x7b, 0xb4, 0xa0, 0xe7, 0x0f, 0xc0, 0x40, 0x2b, 0x99, 0xfe, 0x6a, 0x8d, 0x82,
+ /*ac80:*/ 0x72, 0xef, 0x2b, 0x76, 0xdf, 0x82, 0x74, 0xd2, 0x17, 0xd0, 0xbc, 0xcf, 0x54, 0xb3, 0x6f, 0x34,
+ /*ac90:*/ 0xd7, 0x86, 0x90, 0x63, 0x1f, 0xdc, 0x54, 0xa6, 0xa7, 0x77, 0x4d, 0x84, 0x0d, 0x5a, 0x02, 0xc1,
+ /*aca0:*/ 0x3c, 0xd2, 0xc0, 0xc6, 0x1d, 0xa5, 0x60, 0x9b, 0x22, 0x08, 0x44, 0x01, 0xb8, 0x1a, 0xe4, 0x59,
+ /*acb0:*/ 0x63, 0x2b, 0x48, 0xed, 0xf1, 0x1f, 0x86, 0x18, 0x9c, 0x27, 0xe3, 0x11, 0xb8, 0x03, 0x1a, 0x28,
+ /*acc0:*/ 0xbb, 0x16, 0x90, 0x80, 0x8e, 0xc9, 0xd7, 0x57, 0x33, 0x82, 0x06, 0x44, 0x2b, 0x3f, 0xee, 0xbc,
+ /*acd0:*/ 0x4a, 0x19, 0x73, 0x96, 0x09, 0xb9, 0x26, 0x08, 0x57, 0xe9, 0x66, 0x86, 0x33, 0xfe, 0xf0, 0xad,
+ /*ace0:*/ 0xeb, 0x5f, 0x46, 0xd3, 0x8c, 0x6e, 0xa9, 0xeb, 0x0f, 0x58, 0x27, 0x1d, 0x37, 0x42, 0xd9, 0xbb,
+ /*acf0:*/ 0x65, 0x6d, 0xf0, 0x75, 0x89, 0xfb, 0x5e, 0x4d, 0xd7, 0x6d, 0x09, 0xb4, 0x42, 0x7e, 0x7c, 0x94,
+ /*ad00:*/ 0xa5, 0x34, 0x36, 0x13, 0x88, 0x1a, 0x12, 0x2b, 0x02, 0xd4, 0x38, 0x00, 0x25, 0xc4, 0x95, 0xe6,
+ /*ad10:*/ 0x3c, 0x9b, 0xbe, 0x55, 0x5d, 0x58, 0x6c, 0xef, 0x36, 0xbf, 0xeb, 0x90, 0x74, 0x93, 0x14, 0x07,
+ /*ad20:*/ 0xad, 0xfa, 0x42, 0x13, 0x7b, 0x13, 0x17, 0x1a, 0x9b, 0x0f, 0x36, 0xee, 0x61, 0x76, 0xe2, 0x85,
+ /*ad30:*/ 0x99, 0x42, 0x29, 0x50, 0x20, 0x7e, 0x3f, 0x09, 0xaf, 0x3a, 0xe5, 0x3f, 0x53, 0xf6, 0x76, 0x79,
+ /*ad40:*/ 0xfb, 0x8c, 0x73, 0xc9, 0x83, 0xf6, 0x1c, 0x21, 0xec, 0x05, 0x07, 0x10, 0xbc, 0x16, 0x8e, 0x65,
+ /*ad50:*/ 0x7f, 0xfe, 0x4a, 0x3e, 0xbe, 0xf7, 0x74, 0x47, 0x51, 0x89, 0x5f, 0xad, 0xc1, 0x9e, 0xa1, 0x6a,
+ /*ad60:*/ 0x69, 0x33, 0x5c, 0x10, 0x48, 0x10, 0xbb, 0x49, 0x98, 0x63, 0x04, 0xe4, 0x19, 0xfa, 0x45, 0x93,
+ /*ad70:*/ 0x09, 0x0d, 0xda, 0x37, 0x2e, 0xff, 0x4f, 0xaf, 0xdc, 0x3d, 0x71, 0x3e, 0x0c, 0x97, 0x3b, 0x8f,
+ /*ad80:*/ 0x80, 0xfc, 0x34, 0x24, 0x4e, 0x37, 0xaa, 0x11, 0xd0, 0x4a, 0x57, 0x9b, 0xa6, 0x6c, 0x4d, 0xc1,
+ /*ad90:*/ 0x65, 0x07, 0x6d, 0x1c, 0x9e, 0x06, 0xd9, 0xe3, 0x1a, 0x3f, 0xe0, 0xf1, 0x36, 0x9e, 0x74, 0x65,
+ /*ada0:*/ 0x5c, 0x75, 0xd2, 0xf5, 0xd9, 0xbc, 0x3c, 0x4f, 0x24, 0x4e, 0x04, 0x62, 0x04, 0x97, 0x3e, 0x6e,
+ /*adb0:*/ 0xc4, 0x01, 0x4c, 0x88, 0xfb, 0xb0, 0xdf, 0x7d, 0x45, 0xcd, 0xa0, 0xca, 0x91, 0x96, 0x11, 0x6e,
+ /*adc0:*/ 0x56, 0x5d, 0xe5, 0xd1, 0xf3, 0x2c, 0x4a, 0xf6, 0x07, 0xb3, 0x6d, 0xb6, 0x6b, 0x98, 0x7b, 0x9b,
+ /*add0:*/ 0x80, 0x7a, 0x02, 0x83, 0xc7, 0xef, 0x0e, 0x00, 0x81, 0xfc, 0x95, 0x64, 0xe4, 0xc0, 0xb3, 0xc1,
+ /*ade0:*/ 0x2f, 0xfe, 0x4a, 0x97, 0xa1, 0x1c, 0x68, 0xde, 0xee, 0xc6, 0xcc, 0x23, 0x33, 0x5c, 0x2b, 0xcd,
+ /*adf0:*/ 0xa1, 0x4b, 0xff, 0x97, 0x08, 0x01, 0x51, 0x5a, 0xc1, 0x69, 0x6a, 0xbc, 0xac, 0x3f, 0xc4, 0xf3,
+ /*ae00:*/ 0x5d, 0x75, 0x53, 0x23, 0x8d, 0xb5, 0x43, 0x8d, 0x2f, 0x41, 0x05, 0xd2, 0x7f, 0x88, 0xdd, 0x9e,
+ /*ae10:*/ 0xb8, 0x5b, 0x13, 0x34, 0x1a, 0x74, 0x5c, 0x6e, 0x81, 0xd3, 0x65, 0x6e, 0x02, 0xcf, 0xf1, 0xf2,
+ /*ae20:*/ 0xf2, 0x87, 0xca, 0xab, 0x11, 0x6e, 0xea, 0xf6, 0xa4, 0xa8, 0x82, 0xa8, 0x00, 0xbd, 0xc7, 0x80,
+ /*ae30:*/ 0x4f, 0xeb, 0x73, 0xbc, 0x9f, 0xbb, 0xc4, 0x17, 0x58, 0x68, 0x1f, 0x36, 0xfb, 0x3c, 0xda, 0xf4,
+ /*ae40:*/ 0xf4, 0xea, 0x6a, 0xce, 0x79, 0xe9, 0xb1, 0x83, 0x6d, 0x27, 0x22, 0xdc, 0x01, 0xf8, 0xec, 0x58,
+ /*ae50:*/ 0x6b, 0x58, 0x03, 0x24, 0x50, 0xeb, 0xed, 0xa9, 0x1c, 0x01, 0x1a, 0x7c, 0x50, 0xe3, 0x5e, 0x78,
+ /*ae60:*/ 0x90, 0xe8, 0x50, 0xfd, 0xe8, 0x34, 0xfc, 0x7c, 0x3e, 0x7b, 0x61, 0xd5, 0x93, 0x65, 0x47, 0xed,
+ /*ae70:*/ 0xfe, 0x63, 0xc1, 0xd1, 0x31, 0x86, 0x78, 0xa1, 0x68, 0xee, 0xfa, 0x4f, 0x5c, 0xf2, 0x45, 0x90,
+ /*ae80:*/ 0x7c, 0xb9, 0x6d, 0x98, 0x89, 0x3f, 0x3e, 0xc8, 0x0d, 0x02, 0xa2, 0x2e, 0xfd, 0x96, 0x3e, 0x16,
+ /*ae90:*/ 0xd6, 0xc8, 0x46, 0x89, 0xf5, 0x82, 0x71, 0xe7, 0x93, 0xcb, 0x57, 0x14, 0xce, 0xef, 0x51, 0x53,
+ /*aea0:*/ 0xaa, 0x3d, 0xe7, 0xdc, 0xbf, 0x14, 0xc1, 0x14, 0xdc, 0x24, 0xd1, 0xc9, 0x61, 0xb3, 0x0a, 0x9d,
+ /*aeb0:*/ 0xca, 0xcb, 0x00, 0x49, 0xc0, 0x9a, 0xbe, 0x59, 0x10, 0x9a, 0x0a, 0x75, 0x0a, 0x7a, 0x2d, 0xe2,
+ /*aec0:*/ 0x87, 0xe5, 0xb1, 0x32, 0x55, 0x8d, 0xd2, 0x3a, 0x0b, 0x3b, 0xd9, 0x16, 0xb1, 0x78, 0xa8, 0x83,
+ /*aed0:*/ 0x13, 0x30, 0x2f, 0xf8, 0xa0, 0x91, 0x55, 0xc5, 0x0b, 0x5e, 0x4a, 0x90, 0x1c, 0x10, 0x7c, 0x5a,
+ /*aee0:*/ 0x8e, 0x4b, 0x4b, 0xea, 0x12, 0xe2, 0x51, 0xfa, 0xc4, 0x5a, 0x52, 0x33, 0xff, 0xf9, 0x18, 0xc1,
+ /*aef0:*/ 0x5b, 0xa1, 0x29, 0xeb, 0x3f, 0xab, 0xf8, 0x1c, 0xa2, 0x7e, 0x97, 0xfd, 0x59, 0x04, 0x1a, 0x0c,
+ /*af00:*/ 0x60, 0x5e, 0x3d, 0x23, 0x5e, 0x0b, 0x8e, 0x2b, 0xf5, 0x57, 0xe7, 0x06, 0x71, 0x11, 0x68, 0xb6,
+ /*af10:*/ 0x5a, 0xc4, 0x49, 0xfa, 0x24, 0x17, 0xe7, 0xf7, 0xd2, 0xca, 0xc8, 0xbf, 0x5c, 0x5a, 0x98, 0xe5,
+ /*af20:*/ 0xb8, 0x72, 0x85, 0xb0, 0x8c, 0x4c, 0x49, 0xbc, 0x5f, 0xd5, 0xb3, 0x36, 0xa0, 0xc9, 0x59, 0xbc,
+ /*af30:*/ 0xc8, 0x5e, 0x00, 0xa4, 0x09, 0x95, 0x48, 0x31, 0x96, 0x76, 0x80, 0xee, 0x49, 0x9a, 0xac, 0xe4,
+ /*af40:*/ 0xbe, 0x94, 0xa5, 0xc6, 0x6c, 0xd0, 0xce, 0xcf, 0xa8, 0xdf, 0x61, 0xbb, 0xe5, 0x7a, 0x59, 0xe3,
+ /*af50:*/ 0x7d, 0xad, 0x3b, 0xa9, 0xcc, 0x26, 0xe7, 0x4e, 0x29, 0x5b, 0xed, 0x59, 0x43, 0x70, 0xdd, 0xb6,
+ /*af60:*/ 0xbf, 0x6c, 0xa6, 0x12, 0x87, 0xd0, 0xa2, 0x33, 0xf2, 0x9a, 0x8a, 0x39, 0xca, 0x63, 0x1e, 0x6a,
+ /*af70:*/ 0xf4, 0xf7, 0x4a, 0x97, 0xc6, 0x62, 0x85, 0xb1, 0x98, 0xf4, 0xbd, 0x2d, 0x2c, 0xf7, 0xe8, 0x47,
+ /*af80:*/ 0x73, 0x61, 0xda, 0x0b, 0xca, 0xc7, 0xa8, 0x37, 0x72, 0xdd, 0x08, 0xed, 0xfe, 0xb2, 0xc2, 0xa7,
+ /*af90:*/ 0x1f, 0x30, 0xce, 0x3a, 0x2e, 0xd8, 0x73, 0x77, 0xbf, 0xe1, 0x53, 0xab, 0xcf, 0xbf, 0x1d, 0xa2,
+ /*afa0:*/ 0x7b, 0xe6, 0x93, 0xa8, 0x0b, 0x1d, 0x7b, 0xdb, 0xaa, 0x83, 0x91, 0x76, 0x0b, 0xda, 0x09, 0x17,
+ /*afb0:*/ 0xe6, 0x8a, 0x25, 0x89, 0x1e, 0x9e, 0xe3, 0xec, 0xed, 0x9e, 0xfd, 0x5e, 0xb1, 0x47, 0x78, 0xd9,
+ /*afc0:*/ 0x1e, 0x2a, 0xfe, 0x92, 0x9b, 0x73, 0x70, 0x16, 0x2d, 0xdf, 0x76, 0x18, 0x35, 0x84, 0x40, 0xed,
+ /*afd0:*/ 0x42, 0xb5, 0xa6, 0x89, 0x52, 0x75, 0xf0, 0xbb, 0x20, 0xea, 0xea, 0xec, 0xa2, 0x40, 0xc8, 0x32,
+ /*afe0:*/ 0x82, 0xfb, 0x84, 0x0b, 0x99, 0x22, 0x39, 0x22, 0x0a, 0xde, 0x4f, 0x92, 0x96, 0xd1, 0xa5, 0xf1,
+ /*aff0:*/ 0x6b, 0xf4, 0x01, 0x04, 0x3d, 0x65, 0x70, 0x82, 0xe2, 0x2e, 0x76, 0xfc, 0x25, 0x81, 0x24, 0x59,
+ /*b000:*/ 0x7c, 0x77, 0x24, 0xab, 0x00, 0x06, 0x74, 0x9e, 0xa7, 0x6c, 0xaa, 0x04, 0x30, 0xed, 0x9d, 0xb3,
+ /*b010:*/ 0x56, 0xfc, 0x85, 0x8d, 0xa2, 0x90, 0xc3, 0xcd, 0x08, 0xd2, 0x71, 0xd7, 0xf2, 0x2e, 0x28, 0xfb,
+ /*b020:*/ 0x13, 0x28, 0xfc, 0x43, 0x40, 0x56, 0x80, 0xc4, 0x56, 0xd1, 0x39, 0x96, 0x1f, 0xdc, 0xa8, 0x70,
+ /*b030:*/ 0x32, 0x84, 0x40, 0xa1, 0x98, 0xb6, 0x1e, 0x7f, 0xbc, 0x05, 0xb8, 0x2c, 0x95, 0x26, 0xfd, 0x41,
+ /*b040:*/ 0x20, 0xbb, 0x88, 0x9f, 0x26, 0xf6, 0x4e, 0x99, 0x0e, 0x9c, 0xd9, 0xac, 0xc9, 0xcf, 0x71, 0x31,
+ /*b050:*/ 0xab, 0x6e, 0x05, 0xfd, 0x20, 0x69, 0x50, 0x93, 0x54, 0xe5, 0xc4, 0x0b, 0xc6, 0xa4, 0xd4, 0x00,
+ /*b060:*/ 0xcb, 0x58, 0x27, 0x33, 0x07, 0x01, 0xd6, 0xce, 0x25, 0xdf, 0xf9, 0x36, 0x54, 0x94, 0xf1, 0x40,
+ /*b070:*/ 0x61, 0x69, 0x12, 0x79, 0x5c, 0xb0, 0xf1, 0xba, 0xd2, 0x01, 0x9a, 0xd7, 0x96, 0xbe, 0x34, 0x95,
+ /*b080:*/ 0x06, 0xe7, 0x05, 0xc3, 0x13, 0x58, 0x4e, 0x85, 0xb6, 0xdb, 0x72, 0xba, 0x5e, 0x15, 0xc9, 0x0a,
+ /*b090:*/ 0x62, 0x60, 0x53, 0x3f, 0xad, 0x29, 0x3f, 0xe3, 0xe1, 0xbb, 0x23, 0xcc, 0x13, 0xb9, 0xbd, 0x85,
+ /*b0a0:*/ 0x5d, 0x84, 0x0b, 0x5f, 0x7c, 0x4d, 0x2e, 0x64, 0x41, 0x06, 0x39, 0x71, 0x2b, 0x30, 0x14, 0x59,
+ /*b0b0:*/ 0xfe, 0x18, 0x80, 0x37, 0x17, 0x9e, 0x40, 0xa8, 0x55, 0xf2, 0xf6, 0xcc, 0x4c, 0xad, 0x10, 0x88,
+ /*b0c0:*/ 0x70, 0x6d, 0xcc, 0x69, 0xc9, 0xfd, 0x11, 0xa3, 0xba, 0xd0, 0x6a, 0xe0, 0x65, 0xd1, 0xb8, 0x38,
+ /*b0d0:*/ 0x55, 0xec, 0x1a, 0x81, 0xd0, 0x51, 0x33, 0x31, 0x3b, 0x5a, 0xc9, 0x26, 0xc6, 0xf2, 0x78, 0x2d,
+ /*b0e0:*/ 0x8e, 0x4e, 0x22, 0x8b, 0x0d, 0x74, 0x4d, 0x36, 0x18, 0x45, 0xdc, 0x41, 0x44, 0x35, 0x6a, 0x3b,
+ /*b0f0:*/ 0x66, 0x2c, 0xd4, 0x61, 0x92, 0xb8, 0x48, 0xab, 0xa2, 0xb6, 0x09, 0x7f, 0xa7, 0x91, 0xe9, 0x97,
+ /*b100:*/ 0x53, 0x59, 0x04, 0x03, 0x00, 0x3f, 0x03, 0x1e, 0x05, 0x0e, 0x88, 0x00, 0x01, 0x01, 0xff, 0x0a,
+ /*b110:*/ 0x1f, 0x03, 0xff, 0x04, 0x1e, 0x06, 0x2d, 0x5c, 0x0f, 0x8d, 0x03, 0x01, 0x34, 0xfe, 0x33, 0xff,
+ /*b120:*/ 0x78, 0x43, 0xfd, 0x43, 0x50, 0xc3, 0x38, 0xc7, 0x00, 0x18, 0x20, 0x20, 0x20, 0x20, 0x14, 0x02,
+ /*b130:*/ 0x0c, 0x32, 0xe3, 0xbc, 0x00, 0x00, 0x05, 0x28, 0x0a, 0x2d, 0x00, 0x28, 0x0a, 0x32, 0x00, 0xc4,
+ /*b140:*/ 0x09, 0x3c, 0x00, 0xf0, 0x0a, 0x50, 0x00, 0x1e, 0x1e, 0x8c, 0x00, 0x96, 0x00, 0x14, 0x0a, 0x04,
+ /*b150:*/ 0x29, 0x1a, 0x64, 0x07, 0x66, 0x64, 0xc0, 0x20, 0x02, 0xaf, 0x00, 0x03, 0x0e, 0x1f, 0x08, 0x2a,
+ /*b160:*/ 0x00, 0x20, 0x04, 0x1b, 0x00, 0x80, 0x14, 0xc0, 0xc8, 0xc8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x38,
+ /*b170:*/ 0x37, 0x35, 0x34, 0x32, 0x31, 0x2f, 0x2d, 0x01, 0x04, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x13, 0x00,
+ /*b180:*/ 0x00, 0x00, 0x40, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x20, 0x20, 0x20, 0x20,
+ /*b190:*/ 0x20, 0x20, 0x20, 0x10, 0x5a, 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6d, 0x39, 0x00, 0x0a, 0x00, 0x10,
+ /*b1a0:*/ 0x27, 0x66, 0x12, 0xd4, 0x10, 0xff, 0x1a, 0x00, 0x28, 0x28, 0x1c, 0x26, 0x66, 0x66, 0x66, 0x66,
+ /*b1b0:*/ 0x66, 0x66, 0x66, 0xff, 0xc8, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11,
+ /*b1c0:*/ 0x04, 0x20, 0x40, 0x03, 0x00, 0x1f, 0x00, 0x1d, 0x2d, 0x1d, 0x2b, 0x1d, 0x28, 0x1d, 0x2c, 0x1d,
+ /*b1d0:*/ 0x20, 0xd9, 0x73, 0xca, 0x73, 0xd9, 0xcd, 0x0d, 0x04, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ /*b1e0:*/ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
+ /*b1f0:*/ 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
+ /*b200:*/ 0x27, 0x29, 0x2a, 0x2d, 0x2b, 0x28, 0x2c, 0x20, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x14,
+ /*b210:*/ 0x12, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+ /*b220:*/ 0x01, 0x00, 0x1d, 0x66, 0x66, 0x6d, 0x6d, 0x73, 0x73, 0x7a, 0x7a, 0x80, 0x80, 0x86, 0x86, 0x8d,
+ /*b230:*/ 0x8d, 0x93, 0x93, 0x9a, 0x9a, 0xa0, 0xa0, 0xa6, 0xa6, 0xad, 0xad, 0xb3, 0xb3, 0x80, 0x80, 0x80,
+ /*b240:*/ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /*b250:*/ 0x80, 0x0a, 0x1c, 0x2b, 0x1e, 0x0a, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b260:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b270:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b280:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b290:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xb8, 0x19, 0xcc,
+ /*b300:*/ 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b310:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b320:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b330:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b340:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b350:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b360:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b370:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b380:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b390:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b400:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b410:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b420:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b430:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b440:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ /*b450:*/ 0x3f, 0x03, 0x1e, 0x05, 0x0e, 0x08, 0x00, 0x19, 0x19, 0x00, 0x10, 0xe2, 0x04, 0xb6, 0x08, 0x1e,
+ /*b460:*/ 0x05, 0x28, 0xf5, 0x28, 0x1e, 0x05, 0x01, 0x30, 0x00, 0x30, 0x00, 0x00, 0x50, 0x00, 0x50, 0xf0,
+ /*b470:*/ 0xd2, 0xf0, 0xd2, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0xc0, 0x32, 0x70, 0x00, 0x00,
+ /*b480:*/ 0x00, 0x80, 0x04, 0x2e, 0x1b, 0x64, 0x07, 0x00, 0x00, 0x56, 0x35, 0x05, 0x10, 0x00, 0x00, 0x0b,
+ /*b490:*/ 0x20, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x33,
+ /*b4a0:*/ 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x03, 0x0f, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf0,
+ /*b4b0:*/ 0x15, 0x1b, 0x2e, 0x49, 0x40, 0xff, 0x0b, 0x20, 0x0c, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ /*b4c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b4d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x88, 0x55,
+ /*b4e0:*/ 0x15, 0x21, 0x11, 0x92, 0x87, 0x4f, 0x13, 0x01, 0x01, 0x89, 0x00, 0x4b, 0x00, 0x01, 0x34, 0x00,
+ /*b4f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b500:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b510:*/ 0x00, 0x02, 0x5e, 0x01, 0x03, 0x0e, 0x1f, 0x00, 0xde, 0x01, 0x19, 0x04, 0x1b, 0x00, 0x10, 0x0a,
+ /*b520:*/ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b530:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x05, 0x00, 0x00,
+ /*b540:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00,
+ /*b550:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x28, 0x00, 0x77, 0x18, 0x80, 0x18, 0x80, 0x1a,
+ /*b560:*/ 0x01, 0x19, 0x3f, 0x4d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x10, 0x0a, 0x00, 0x00,
+ /*b570:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x04, 0x40, 0x40, 0x03, 0x00, 0x2e, 0x1b,
+ /*b580:*/ 0x44, 0x00, 0x19, 0x01, 0x00, 0xbe, 0x00, 0xde, 0x3f, 0xd0, 0x80, 0x08, 0x03, 0x00, 0x00, 0x00,
+ /*b590:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7d, 0x10, 0x00, 0x01, 0x54, 0x00,
+ /*b5f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b600:*/ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x51, 0x51,
+ /*b610:*/ 0x51, 0x51, 0x51, 0xcd, 0x0d, 0x04, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x04, 0xff, 0x2e, 0x1b, 0x05,
+ /*b620:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b630:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b640:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b650:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b660:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b670:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b680:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b690:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6e0:*/ 0x00, 0x00, 0x00, 0x1d, 0x1a, 0x16, 0x00, 0x01, 0x55, 0x1b, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x00,
+ /*b6f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b700:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b710:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b720:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x32, 0x00, 0x1e, 0x04, 0x80, 0xc0, 0x04,
+ /*b730:*/ 0x28, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b740:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b750:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b760:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b770:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b780:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b790:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x28, 0x00, 0x00, 0x51, 0x00,
+ /*b7f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b800:*/ 0xff};
+#else
+const u8 rmi_fw_button[] = {
+ /*0000:*/ 0xaf, 0xee, 0x17, 0x5c, 0x00, 0x00, 0x00, 0x05, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ /*0010:*/ 0x53, 0x37, 0x33, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0030:*/ 0x44, 0x53, 0x34, 0x20, 0x52, 0x33, 0x2e, 0x35, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0040:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0050:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0060:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0070:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0080:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0090:*/ 0x49, 0x32, 0x43, 0x00, 0x04, 0x00, 0xff, 0x00, 0x0c, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*00a0:*/ 0x49, 0x32, 0x43, 0x00, 0x04, 0x00, 0xff, 0x00, 0x0c, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*00b0:*/ 0x69, 0x96, 0x7e, 0xd0, 0x20, 0x5a, 0x00, 0x20, 0xc5, 0xc0, 0x2a, 0x79, 0xac, 0x74, 0x2e, 0x45,
+ /*00c0:*/ 0x57, 0x05, 0x48, 0x7c, 0xd7, 0x03, 0xb0, 0x50, 0xe0, 0x77, 0x3c, 0x8b, 0x79, 0xf6, 0x71, 0x75,
+ /*00d0:*/ 0xca, 0xec, 0xb0, 0x31, 0x53, 0xaa, 0x37, 0xe9, 0x19, 0x47, 0x46, 0x84, 0xba, 0x28, 0x18, 0xe9,
+ /*00e0:*/ 0x51, 0x89, 0xe7, 0xce, 0x3e, 0x64, 0x26, 0xa6, 0x25, 0x31, 0xc5, 0x0d, 0x9a, 0xa9, 0x93, 0xfa,
+ /*00f0:*/ 0x7c, 0x9a, 0x20, 0x17, 0x1a, 0x92, 0x35, 0xa6, 0x9a, 0x75, 0xa0, 0x23, 0x4f, 0xb1, 0xec, 0x1e,
+ /*0100:*/ 0x64, 0xce, 0x5c, 0x97, 0x6f, 0xf6, 0x36, 0x81, 0xf8, 0x90, 0x17, 0xb0, 0x0d, 0x0c, 0xd3, 0x50,
+ /*0110:*/ 0x2b, 0xb3, 0x37, 0x31, 0xe9, 0x03, 0x0c, 0x63, 0xf1, 0x9e, 0x52, 0x2d, 0xf5, 0xd3, 0x44, 0x87,
+ /*0120:*/ 0xa3, 0xef, 0xc0, 0x55, 0xf3, 0xca, 0x62, 0x4f, 0xc8, 0x13, 0xbd, 0x20, 0xe6, 0x3a, 0xac, 0xcd,
+ /*0130:*/ 0x2b, 0x4b, 0x2c, 0x18, 0x21, 0x16, 0xf3, 0xb6, 0xaa, 0x41, 0xe2, 0x66, 0xfc, 0x6f, 0x1f, 0xce,
+ /*0140:*/ 0x7f, 0x17, 0xdd, 0xfd, 0x49, 0xde, 0x8b, 0x2b, 0xec, 0xf9, 0xe4, 0xed, 0xaf, 0x8c, 0x26, 0xe0,
+ /*0150:*/ 0xb5, 0x30, 0xde, 0x4b, 0xb9, 0x9e, 0x4d, 0xfe, 0x43, 0x86, 0xce, 0x9e, 0x0b, 0x6f, 0xb9, 0xc8,
+ /*0160:*/ 0x1e, 0xcb, 0x83, 0xee, 0xdb, 0xf3, 0xcb, 0x5f, 0xa2, 0x9b, 0xba, 0x53, 0x3d, 0xde, 0x85, 0xce,
+ /*0170:*/ 0xda, 0xdc, 0xfd, 0x86, 0xe6, 0xdc, 0xb0, 0x14, 0xc0, 0x87, 0x68, 0x6d, 0x15, 0x39, 0x99, 0x81,
+ /*0180:*/ 0xf4, 0x8f, 0xfa, 0x4b, 0x47, 0x53, 0x99, 0x05, 0xe8, 0x9f, 0xd7, 0x8c, 0x0a, 0xdd, 0x12, 0x95,
+ /*0190:*/ 0xc6, 0xd0, 0xe3, 0xf9, 0x2c, 0xb0, 0xee, 0x4f, 0x50, 0x51, 0x9e, 0x2c, 0x7f, 0x07, 0xd7, 0xd7,
+ /*01a0:*/ 0xa6, 0xfc, 0x58, 0x56, 0x65, 0x04, 0x49, 0x73, 0x05, 0x3e, 0xd2, 0xe9, 0x37, 0xb8, 0xd7, 0xbc,
+ /*01b0:*/ 0x79, 0x5f, 0x8c, 0xc7, 0x28, 0xe6, 0x39, 0xef, 0x29, 0x7f, 0x26, 0x52, 0xd8, 0xda, 0x99, 0x4c,
+ /*01c0:*/ 0x6b, 0x6e, 0x7a, 0xd3, 0x9e, 0x75, 0xca, 0x55, 0xb2, 0x29, 0x88, 0xb8, 0x0b, 0x1d, 0x1c, 0x81,
+ /*01d0:*/ 0x98, 0x15, 0xf7, 0x59, 0x1d, 0x73, 0xc3, 0x8d, 0x42, 0x5e, 0xce, 0x78, 0x9b, 0x36, 0x49, 0xbe,
+ /*01e0:*/ 0xad, 0xc9, 0x81, 0xa4, 0x7e, 0x4c, 0xcb, 0x35, 0x52, 0x17, 0xd7, 0x73, 0x29, 0x4e, 0x81, 0xdf,
+ /*01f0:*/ 0x66, 0x04, 0x1d, 0x49, 0x3f, 0xa0, 0xf2, 0x2f, 0x42, 0xd0, 0xf4, 0xe9, 0x49, 0xae, 0x52, 0xf7,
+ /*0200:*/ 0xce, 0x67, 0x45, 0x5c, 0x59, 0x91, 0xb0, 0x83, 0xc0, 0x2e, 0xf4, 0x77, 0xcb, 0x65, 0xb5, 0xd3,
+ /*0210:*/ 0x18, 0x15, 0x9e, 0x05, 0x30, 0x8f, 0xb7, 0xb8, 0x40, 0x1f, 0x71, 0xb1, 0x0f, 0x81, 0x03, 0x89,
+ /*0220:*/ 0xb7, 0x6d, 0xef, 0x46, 0x6e, 0x45, 0x46, 0xc5, 0xd3, 0x94, 0x92, 0x41, 0xca, 0xc5, 0x32, 0xac,
+ /*0230:*/ 0x34, 0x10, 0x2b, 0x1a, 0x4f, 0xec, 0x94, 0xcf, 0x91, 0xd9, 0x80, 0xf1, 0x60, 0x9d, 0xe7, 0x63,
+ /*0240:*/ 0x51, 0xa7, 0xec, 0xe6, 0x1d, 0xf8, 0x38, 0xc7, 0xec, 0xe7, 0x69, 0x08, 0x02, 0x7b, 0x09, 0x89,
+ /*0250:*/ 0x84, 0x9a, 0xbd, 0x1f, 0x04, 0x9f, 0xf3, 0x20, 0xc8, 0x23, 0x4c, 0xd7, 0x0a, 0x64, 0x47, 0x43,
+ /*0260:*/ 0xb6, 0xc8, 0xad, 0xb7, 0xd5, 0xa4, 0xb0, 0xea, 0x57, 0x8d, 0xe9, 0x4e, 0x18, 0x81, 0x08, 0x26,
+ /*0270:*/ 0x68, 0x66, 0xe6, 0x0b, 0xb2, 0x5d, 0xf5, 0xc3, 0xc1, 0xc1, 0x25, 0x84, 0xdd, 0x00, 0x34, 0x10,
+ /*0280:*/ 0x94, 0xb6, 0xaf, 0x9f, 0x6a, 0xd5, 0x34, 0x1e, 0x9a, 0x42, 0xd0, 0xa7, 0xc9, 0xd7, 0x3f, 0xc3,
+ /*0290:*/ 0x43, 0xf2, 0x80, 0x94, 0x2e, 0xb9, 0xdb, 0x60, 0x76, 0xc5, 0xf5, 0x6f, 0xe8, 0x83, 0x96, 0x1b,
+ /*02a0:*/ 0x96, 0x80, 0xed, 0xb4, 0x0b, 0xc3, 0x34, 0x92, 0xa3, 0xe7, 0xb8, 0x07, 0x23, 0x1b, 0x1b, 0x44,
+ /*02b0:*/ 0x4a, 0x09, 0xf5, 0xb9, 0x50, 0x75, 0xf2, 0xd6, 0x75, 0xae, 0xef, 0xfa, 0x29, 0x4f, 0x7a, 0xf0,
+ /*02c0:*/ 0xfa, 0x01, 0xf4, 0x0c, 0x67, 0x2c, 0x2d, 0x36, 0x75, 0xfb, 0xe9, 0xaa, 0xf5, 0x4b, 0x87, 0xbb,
+ /*02d0:*/ 0xb8, 0xe7, 0x62, 0x4f, 0xbb, 0xc1, 0xc7, 0xd6, 0xa4, 0x10, 0xa3, 0xca, 0xb9, 0x80, 0x7a, 0x1e,
+ /*02e0:*/ 0xb0, 0xc5, 0xaa, 0x84, 0x0e, 0xe8, 0x10, 0x25, 0xa4, 0xd5, 0x1d, 0xc3, 0x2f, 0x11, 0x8e, 0xdc,
+ /*02f0:*/ 0xae, 0x9d, 0x51, 0x75, 0x40, 0x9e, 0x92, 0xec, 0x94, 0xff, 0x24, 0xbd, 0x00, 0x51, 0x43, 0x15,
+ /*0300:*/ 0x22, 0x7f, 0x7e, 0x22, 0xfa, 0x57, 0x2b, 0x1c, 0xf3, 0xb1, 0x11, 0x62, 0x0d, 0xb3, 0x68, 0x1a,
+ /*0310:*/ 0x6f, 0x2c, 0xb1, 0x6a, 0x0a, 0xb6, 0xc0, 0x8e, 0x14, 0x2f, 0x49, 0xd6, 0x65, 0x77, 0xb9, 0xfb,
+ /*0320:*/ 0x62, 0x78, 0xbf, 0x05, 0x1d, 0x37, 0xc7, 0x59, 0xa0, 0x1a, 0x8e, 0xb3, 0x08, 0x07, 0x69, 0x12,
+ /*0330:*/ 0x8b, 0xa1, 0x36, 0xd2, 0x42, 0xfe, 0x5a, 0xf7, 0xa6, 0xfd, 0x8b, 0x27, 0x6d, 0x1d, 0x3b, 0x8b,
+ /*0340:*/ 0xcb, 0xe9, 0x2b, 0x3f, 0xdd, 0xe0, 0xa4, 0x4e, 0x97, 0x41, 0x72, 0x15, 0xfc, 0x7a, 0x40, 0x84,
+ /*0350:*/ 0x24, 0x56, 0x76, 0xdd, 0x7b, 0xb8, 0xf6, 0xdc, 0x15, 0x01, 0x4a, 0x5f, 0x21, 0xae, 0xc0, 0xbd,
+ /*0360:*/ 0x14, 0x83, 0x35, 0x64, 0x54, 0x7d, 0xb5, 0x8b, 0xc6, 0x8d, 0xe0, 0x6a, 0xe4, 0x2b, 0x69, 0x49,
+ /*0370:*/ 0xd1, 0x0b, 0x17, 0x27, 0x09, 0x9a, 0x52, 0x82, 0x57, 0x90, 0x2f, 0x24, 0x43, 0xc3, 0x9d, 0x7d,
+ /*0380:*/ 0x31, 0x26, 0x6f, 0x54, 0x7d, 0xb6, 0x51, 0x15, 0x47, 0x4e, 0x9e, 0x96, 0x81, 0x29, 0xcb, 0xaa,
+ /*0390:*/ 0x01, 0xee, 0x77, 0x57, 0xc0, 0xf6, 0xb4, 0xe0, 0xd7, 0x90, 0xa9, 0x44, 0x2c, 0xe3, 0xa9, 0x32,
+ /*03a0:*/ 0x17, 0x3d, 0x5c, 0xe3, 0xc9, 0x82, 0xb2, 0x56, 0xb3, 0x9b, 0xda, 0xd6, 0x7c, 0x7d, 0x64, 0xd4,
+ /*03b0:*/ 0xe4, 0x39, 0x0d, 0xcc, 0xf3, 0x02, 0x59, 0xbe, 0x4b, 0x58, 0x4e, 0x1f, 0x47, 0x46, 0x55, 0x97,
+ /*03c0:*/ 0x67, 0xe7, 0xdc, 0x2f, 0xb1, 0x91, 0x81, 0x0b, 0x46, 0x97, 0x78, 0x25, 0x29, 0xb0, 0x7f, 0xa2,
+ /*03d0:*/ 0xb9, 0xfa, 0xf4, 0x20, 0x19, 0xab, 0xae, 0xf4, 0x7e, 0x74, 0x92, 0xf3, 0x63, 0x97, 0x05, 0xf4,
+ /*03e0:*/ 0x8c, 0xc8, 0xfb, 0xa7, 0x6f, 0xdf, 0x2d, 0xa8, 0x80, 0x17, 0x0c, 0x37, 0x6d, 0xe4, 0x97, 0x5b,
+ /*03f0:*/ 0xa4, 0x1d, 0xda, 0xb7, 0x45, 0xf0, 0xce, 0x7d, 0x31, 0xcc, 0xc2, 0x29, 0x37, 0xd1, 0x8c, 0x3d,
+ /*0400:*/ 0xcc, 0xa2, 0xf0, 0x70, 0x16, 0x9b, 0x87, 0xc6, 0x97, 0x20, 0x99, 0x8b, 0xb4, 0xb5, 0x39, 0xf7,
+ /*0410:*/ 0x7c, 0x7f, 0x86, 0x37, 0x79, 0x6e, 0x8b, 0x1b, 0xbf, 0xfb, 0x68, 0xd3, 0xf4, 0x61, 0x58, 0xe5,
+ /*0420:*/ 0x8a, 0xb0, 0xee, 0x70, 0x06, 0x18, 0x0c, 0x6b, 0x64, 0xf3, 0xb0, 0x64, 0x30, 0xee, 0xd3, 0xd1,
+ /*0430:*/ 0xa8, 0xe1, 0x30, 0xfc, 0x82, 0x36, 0x67, 0x93, 0x05, 0x6b, 0x4a, 0x33, 0x93, 0x5b, 0x8d, 0xdf,
+ /*0440:*/ 0xf4, 0x19, 0x3b, 0x85, 0xf0, 0x36, 0xf7, 0x50, 0xaa, 0x5e, 0xf7, 0x83, 0x93, 0x67, 0x78, 0x33,
+ /*0450:*/ 0x77, 0x3f, 0x9e, 0x34, 0x06, 0x6c, 0xcb, 0xc3, 0x00, 0x7f, 0xea, 0x39, 0x6d, 0xc5, 0x5e, 0x91,
+ /*0460:*/ 0xb1, 0x00, 0xbe, 0x6f, 0x08, 0x96, 0x01, 0xe4, 0xcb, 0x9f, 0x92, 0x79, 0x50, 0xaa, 0xda, 0x1e,
+ /*0470:*/ 0xec, 0x12, 0x2b, 0x4b, 0x0a, 0xa3, 0xcf, 0x8c, 0x1f, 0x4b, 0x15, 0xee, 0xec, 0x18, 0xa6, 0xfe,
+ /*0480:*/ 0xd5, 0x73, 0x82, 0x1d, 0x6e, 0x21, 0x8c, 0xe5, 0xf4, 0x36, 0x83, 0x9e, 0x00, 0x7b, 0x60, 0x9f,
+ /*0490:*/ 0x0d, 0xb4, 0x60, 0x70, 0xe0, 0x99, 0xc6, 0x55, 0xb9, 0xee, 0x3e, 0x24, 0x06, 0x15, 0x79, 0x0d,
+ /*04a0:*/ 0xa6, 0xc7, 0x79, 0x97, 0x01, 0x5c, 0x52, 0x38, 0xfa, 0x5b, 0x71, 0x38, 0xfa, 0xbf, 0xa0, 0x2c,
+ /*04b0:*/ 0x2c, 0x9d, 0x25, 0xfa, 0x70, 0xd7, 0x32, 0xb1, 0x33, 0xb6, 0xcd, 0xcd, 0xcd, 0xf6, 0x97, 0x3b,
+ /*04c0:*/ 0x3b, 0x0a, 0x33, 0xbb, 0x7a, 0xa5, 0x89, 0x14, 0xa6, 0x15, 0x44, 0xdb, 0x91, 0x07, 0x75, 0x48,
+ /*04d0:*/ 0xd5, 0x45, 0x46, 0x71, 0x1c, 0xf2, 0x12, 0xbc, 0x61, 0x70, 0x50, 0x56, 0xd3, 0x21, 0x5d, 0xc4,
+ /*04e0:*/ 0x29, 0x9f, 0x04, 0xfe, 0xe8, 0xdb, 0x77, 0x42, 0xde, 0xf3, 0xef, 0x2b, 0xfb, 0x34, 0xe7, 0x00,
+ /*04f0:*/ 0x8a, 0x50, 0x40, 0x3f, 0x62, 0x3d, 0x94, 0x49, 0xd2, 0x95, 0x27, 0xec, 0x86, 0xcd, 0xa2, 0x05,
+ /*0500:*/ 0xac, 0xfe, 0xb0, 0x83, 0xee, 0x52, 0x05, 0x7c, 0x40, 0x27, 0x4b, 0xc7, 0x93, 0xaa, 0x92, 0xce,
+ /*0510:*/ 0x72, 0x70, 0x8d, 0x9a, 0x5b, 0x88, 0x6b, 0x59, 0xa7, 0x61, 0xf7, 0x12, 0xe8, 0x61, 0xb6, 0x23,
+ /*0520:*/ 0xe8, 0xd3, 0xfc, 0x6a, 0xec, 0x4a, 0x05, 0xcd, 0x49, 0x74, 0xf4, 0xcb, 0x0e, 0xe3, 0x95, 0x95,
+ /*0530:*/ 0x0e, 0xc3, 0xd7, 0x9e, 0xb6, 0x6e, 0xcb, 0x4f, 0xdc, 0xe3, 0x3d, 0x87, 0x23, 0x3a, 0xc8, 0x8d,
+ /*0540:*/ 0x4f, 0x7b, 0xd8, 0xe9, 0x12, 0x46, 0x92, 0x0c, 0x75, 0xe0, 0x6b, 0x35, 0xf1, 0x82, 0xbc, 0xbb,
+ /*0550:*/ 0x09, 0x3f, 0xf9, 0xa7, 0xb6, 0x29, 0x62, 0x64, 0x09, 0x02, 0x5b, 0xf7, 0x47, 0xac, 0x69, 0xe5,
+ /*0560:*/ 0xb9, 0x7a, 0x6a, 0x7b, 0xb1, 0xad, 0xf4, 0x5f, 0xa4, 0x2c, 0x31, 0x06, 0x69, 0x63, 0x25, 0x32,
+ /*0570:*/ 0x75, 0x35, 0x95, 0x06, 0x41, 0xf8, 0x40, 0xce, 0x35, 0x2c, 0xad, 0x9b, 0xfb, 0xc0, 0x87, 0xed,
+ /*0580:*/ 0xe9, 0xd9, 0xe1, 0x65, 0x45, 0xc1, 0x98, 0x87, 0x0f, 0x2d, 0xc9, 0x38, 0xbc, 0x24, 0xdb, 0xa7,
+ /*0590:*/ 0x51, 0xae, 0x04, 0xa8, 0x3e, 0x1f, 0xab, 0xd4, 0xbb, 0x00, 0x08, 0x93, 0xc3, 0xcf, 0x15, 0x94,
+ /*05a0:*/ 0x2c, 0xd9, 0xa4, 0x0f, 0xb1, 0xc4, 0xda, 0xc6, 0xac, 0x24, 0x17, 0x8a, 0xda, 0xab, 0x4e, 0xa7,
+ /*05b0:*/ 0xeb, 0xeb, 0xc2, 0xdd, 0x01, 0x51, 0xfd, 0xc2, 0xf9, 0x3a, 0x2b, 0x97, 0x19, 0x3f, 0x1a, 0x84,
+ /*05c0:*/ 0x65, 0x14, 0xd6, 0xac, 0xf8, 0xbd, 0xe5, 0xa3, 0xb4, 0x19, 0x4b, 0xbe, 0x02, 0xe7, 0x71, 0xff,
+ /*05d0:*/ 0x14, 0xbe, 0xfa, 0x49, 0x20, 0x50, 0x74, 0x43, 0x68, 0x23, 0x86, 0x4b, 0xe3, 0xbe, 0x4d, 0x16,
+ /*05e0:*/ 0x93, 0xd0, 0xcf, 0xa5, 0x5a, 0x56, 0x0a, 0x4e, 0x05, 0xf0, 0x24, 0xf0, 0xe9, 0xbb, 0xf3, 0xd2,
+ /*05f0:*/ 0xcf, 0xaa, 0x1d, 0x6b, 0x99, 0x31, 0x79, 0xd8, 0x26, 0xc8, 0x0a, 0xa4, 0x32, 0xb1, 0xe2, 0x0c,
+ /*0600:*/ 0xaa, 0xb4, 0xe0, 0x05, 0xc4, 0x60, 0xb9, 0xdf, 0xad, 0x95, 0x51, 0x29, 0xbc, 0xa8, 0xcb, 0xae,
+ /*0610:*/ 0xc3, 0x75, 0xbf, 0x42, 0x8f, 0x02, 0xe8, 0xf1, 0x74, 0x2a, 0x93, 0x98, 0xce, 0x7e, 0x13, 0xd5,
+ /*0620:*/ 0xd6, 0x2c, 0xd5, 0x08, 0x45, 0xe2, 0x6d, 0xe1, 0x2a, 0x63, 0x8d, 0xa4, 0x3e, 0xab, 0x73, 0x6d,
+ /*0630:*/ 0x4c, 0x06, 0xf8, 0x44, 0x5a, 0xb1, 0x65, 0x0f, 0x1d, 0xf3, 0xcd, 0xf2, 0x3e, 0xde, 0xa2, 0x12,
+ /*0640:*/ 0xe6, 0x1c, 0xbd, 0x84, 0x65, 0x13, 0xb5, 0x3c, 0x9a, 0xa8, 0x17, 0xc3, 0x9e, 0xb4, 0xab, 0x52,
+ /*0650:*/ 0x30, 0x4c, 0x0a, 0xc2, 0xff, 0x20, 0x4b, 0xb4, 0x8e, 0xf9, 0x4a, 0xb6, 0x21, 0xaa, 0x47, 0x68,
+ /*0660:*/ 0x61, 0x6f, 0x81, 0x0e, 0x36, 0xe7, 0x19, 0x2f, 0x68, 0xbb, 0x18, 0x29, 0xdd, 0xf1, 0xc3, 0x57,
+ /*0670:*/ 0x9a, 0xe0, 0x66, 0x47, 0xda, 0xe2, 0x24, 0x27, 0xb7, 0x75, 0x6d, 0x99, 0x5f, 0x94, 0x5b, 0xae,
+ /*0680:*/ 0x60, 0xde, 0xc2, 0x2a, 0xd5, 0x36, 0x24, 0x61, 0x6a, 0x39, 0x08, 0x32, 0x18, 0x04, 0x41, 0x0f,
+ /*0690:*/ 0x24, 0xc2, 0x4a, 0x5f, 0xa2, 0x32, 0xf6, 0x8a, 0xe4, 0x03, 0x9e, 0x85, 0xb0, 0xe6, 0x5b, 0xeb,
+ /*06a0:*/ 0x15, 0x21, 0xce, 0xc7, 0xdc, 0x90, 0xfb, 0x22, 0x94, 0xf1, 0x77, 0x1b, 0x60, 0x17, 0x97, 0x6e,
+ /*06b0:*/ 0x19, 0x51, 0xde, 0xf6, 0x73, 0xa5, 0xf1, 0xf5, 0x71, 0xc5, 0xa2, 0x44, 0x61, 0x20, 0xe3, 0x08,
+ /*06c0:*/ 0x82, 0xd6, 0x9f, 0xfe, 0xdb, 0x11, 0x10, 0xfb, 0x38, 0x72, 0x9e, 0x3a, 0x1b, 0xa2, 0x28, 0xdb,
+ /*06d0:*/ 0x37, 0xef, 0xaf, 0x13, 0x6b, 0xde, 0x35, 0xa3, 0xc0, 0x42, 0x2c, 0xd3, 0xe0, 0x11, 0xe9, 0xe4,
+ /*06e0:*/ 0x94, 0x9c, 0x1e, 0xe4, 0x01, 0x02, 0x22, 0x8c, 0x13, 0x27, 0xda, 0xe6, 0x30, 0x61, 0x67, 0xca,
+ /*06f0:*/ 0x40, 0x87, 0x06, 0xce, 0x72, 0xa7, 0x14, 0x15, 0xa7, 0xe6, 0xa3, 0x7c, 0x51, 0xb7, 0xdd, 0x3e,
+ /*0700:*/ 0x2b, 0x8c, 0x7d, 0x56, 0x86, 0xb8, 0x3e, 0x17, 0xe8, 0x73, 0xce, 0xe8, 0x4a, 0xd9, 0xac, 0x9b,
+ /*0710:*/ 0x2b, 0x09, 0x3a, 0xb0, 0xb3, 0x96, 0xad, 0x98, 0xfd, 0x55, 0xdc, 0x0f, 0xf0, 0x1c, 0xaa, 0x8a,
+ /*0720:*/ 0xba, 0x6a, 0xfb, 0xf1, 0xac, 0x36, 0x35, 0x02, 0x42, 0x85, 0x6a, 0x81, 0x41, 0x78, 0xe1, 0x75,
+ /*0730:*/ 0xc2, 0x55, 0x5e, 0x15, 0x4c, 0x99, 0x22, 0xcc, 0x19, 0xc4, 0x91, 0x32, 0x80, 0x70, 0xa6, 0x7a,
+ /*0740:*/ 0x76, 0xa4, 0xfb, 0xfb, 0xa3, 0x94, 0x5d, 0xc7, 0x01, 0x92, 0x9a, 0xc7, 0xc1, 0x6f, 0x0e, 0x20,
+ /*0750:*/ 0xbc, 0x3d, 0x84, 0xf7, 0xa9, 0xe5, 0x6d, 0x72, 0x8c, 0x8a, 0x82, 0xfc, 0x53, 0x80, 0xdf, 0x34,
+ /*0760:*/ 0x82, 0xff, 0x69, 0xcb, 0x33, 0xbc, 0xeb, 0x6c, 0xe4, 0xbd, 0x9d, 0xc4, 0x67, 0xdc, 0x25, 0x55,
+ /*0770:*/ 0x51, 0xb5, 0x5f, 0xf5, 0x5c, 0xe4, 0x35, 0xfc, 0x55, 0xe5, 0x2d, 0xdf, 0x51, 0x2c, 0xcc, 0x28,
+ /*0780:*/ 0xaa, 0xe4, 0x7b, 0x5f, 0x87, 0x2a, 0x79, 0x48, 0xf3, 0xf6, 0xaf, 0x22, 0xf1, 0xe3, 0x62, 0x29,
+ /*0790:*/ 0x31, 0x65, 0x87, 0xef, 0x97, 0xa7, 0x18, 0xf6, 0xf4, 0xc7, 0x71, 0x5d, 0x53, 0xd5, 0x1b, 0x20,
+ /*07a0:*/ 0x4f, 0x15, 0x4b, 0x20, 0x3a, 0x5d, 0x37, 0xbb, 0x90, 0x80, 0xf3, 0xc2, 0xd0, 0x37, 0xb0, 0xe9,
+ /*07b0:*/ 0xad, 0xab, 0x28, 0xf4, 0x20, 0x23, 0x3d, 0x53, 0x68, 0xff, 0x00, 0x39, 0x99, 0x17, 0xde, 0xd1,
+ /*07c0:*/ 0x0d, 0x8d, 0xd9, 0x84, 0x03, 0xb9, 0x2b, 0x20, 0x8c, 0x98, 0x00, 0xbf, 0x59, 0x9c, 0xe8, 0xba,
+ /*07d0:*/ 0x29, 0x3f, 0xf8, 0x5c, 0x5b, 0xd2, 0xf3, 0x76, 0xf6, 0xac, 0x0b, 0x9e, 0x8d, 0xf4, 0x2a, 0xb2,
+ /*07e0:*/ 0x4e, 0xaf, 0xb9, 0xe9, 0xd1, 0xb3, 0x40, 0xa6, 0x08, 0xc5, 0x1a, 0x31, 0xb4, 0xd8, 0x05, 0x24,
+ /*07f0:*/ 0xdf, 0x29, 0xf0, 0xc0, 0xf6, 0x90, 0x0f, 0x0c, 0x72, 0xdb, 0x4d, 0x32, 0xbe, 0xd6, 0x72, 0x57,
+ /*0800:*/ 0xe3, 0xc3, 0xaa, 0x3c, 0x4b, 0x12, 0xea, 0xc8, 0xf6, 0xb8, 0x0f, 0xdf, 0xa9, 0x21, 0x8a, 0x20,
+ /*0810:*/ 0xfc, 0x2a, 0x14, 0xa0, 0x9d, 0xb4, 0xea, 0xbf, 0x09, 0xbe, 0xca, 0x32, 0xff, 0xd8, 0xfc, 0x91,
+ /*0820:*/ 0x2c, 0xf4, 0x58, 0x67, 0x79, 0x4a, 0xb7, 0x0f, 0x9d, 0x30, 0xf9, 0x8d, 0xbd, 0xaf, 0x28, 0x3b,
+ /*0830:*/ 0xdf, 0x8b, 0xa2, 0x83, 0xb1, 0xef, 0x3a, 0x1a, 0x8e, 0xff, 0x59, 0x1b, 0x25, 0xf7, 0x0f, 0x30,
+ /*0840:*/ 0x34, 0xc4, 0xbe, 0x4a, 0x41, 0xc4, 0x37, 0xf9, 0x59, 0x07, 0x42, 0x20, 0x28, 0xac, 0xca, 0x32,
+ /*0850:*/ 0xed, 0xd2, 0x03, 0x06, 0xa7, 0x96, 0x69, 0xb7, 0xe9, 0xde, 0xc8, 0x28, 0x06, 0xd8, 0x4d, 0xe7,
+ /*0860:*/ 0xab, 0xd5, 0xef, 0x00, 0x0f, 0x45, 0x50, 0xfb, 0x50, 0xbf, 0x79, 0x7d, 0xdc, 0x50, 0xa9, 0xec,
+ /*0870:*/ 0xbb, 0x92, 0x31, 0xce, 0x44, 0x9c, 0x06, 0x33, 0x8f, 0x39, 0x74, 0x74, 0xf4, 0x6c, 0xd6, 0xa6,
+ /*0880:*/ 0x8f, 0x50, 0x2b, 0x09, 0x1e, 0xeb, 0x31, 0x98, 0xc6, 0xfc, 0xfc, 0x40, 0x45, 0x45, 0x85, 0x82,
+ /*0890:*/ 0xa9, 0x4d, 0xd0, 0xfa, 0xd1, 0xe6, 0x0c, 0xda, 0x0a, 0x59, 0x2b, 0x7d, 0x9e, 0x93, 0x4e, 0x41,
+ /*08a0:*/ 0xce, 0x96, 0xc9, 0x9a, 0x7b, 0xd4, 0x83, 0xe8, 0x43, 0xdb, 0xb5, 0x6d, 0xe8, 0x1a, 0xa6, 0xe8,
+ /*08b0:*/ 0xf0, 0x5f, 0x7f, 0xf3, 0x40, 0x2c, 0x86, 0xbb, 0x7e, 0xfc, 0xa2, 0x64, 0xef, 0x99, 0xc8, 0xb7,
+ /*08c0:*/ 0x71, 0x9a, 0x4e, 0xd8, 0xe8, 0x16, 0x5d, 0x29, 0x7d, 0x76, 0x08, 0xdf, 0x0d, 0xde, 0x6b, 0x16,
+ /*08d0:*/ 0x29, 0xbd, 0xce, 0x46, 0x65, 0x85, 0xc8, 0xcd, 0xf4, 0x39, 0xa5, 0xa6, 0x87, 0xa8, 0x18, 0x85,
+ /*08e0:*/ 0x6b, 0x60, 0xd7, 0x94, 0xcd, 0x21, 0x04, 0x18, 0x73, 0x58, 0xb3, 0xd4, 0x88, 0x0a, 0xd0, 0x33,
+ /*08f0:*/ 0x70, 0xe7, 0x80, 0x18, 0x22, 0x48, 0xc4, 0xce, 0x53, 0xac, 0x96, 0x2d, 0xb3, 0x65, 0xd3, 0x6b,
+ /*0900:*/ 0x1f, 0xb9, 0xb4, 0xd9, 0x24, 0xf0, 0x13, 0x4d, 0xcc, 0x5e, 0x6d, 0xe8, 0x80, 0xce, 0xc8, 0xe4,
+ /*0910:*/ 0xb3, 0x56, 0x91, 0x7a, 0x27, 0xb0, 0x1a, 0x32, 0x55, 0x49, 0xa0, 0xc4, 0xa5, 0x44, 0xf0, 0xb4,
+ /*0920:*/ 0x8a, 0x35, 0x0b, 0x45, 0x37, 0xf5, 0x3c, 0xe4, 0x89, 0x46, 0x1a, 0x56, 0xea, 0xc0, 0xd3, 0x8e,
+ /*0930:*/ 0x65, 0x90, 0x7b, 0x8d, 0x32, 0x65, 0x51, 0x89, 0x8d, 0x96, 0xab, 0x98, 0xb1, 0xd6, 0x71, 0x6e,
+ /*0940:*/ 0x46, 0xf2, 0x33, 0xe9, 0x37, 0x14, 0xf7, 0x11, 0xd4, 0xa8, 0xbf, 0x2a, 0x22, 0xe9, 0xc7, 0xbd,
+ /*0950:*/ 0xad, 0x08, 0x95, 0x73, 0xb4, 0x5e, 0x1f, 0x92, 0xfa, 0x9a, 0x1a, 0xe9, 0x77, 0x22, 0xce, 0xa6,
+ /*0960:*/ 0xd2, 0xc5, 0xa3, 0xf9, 0x41, 0xd8, 0x88, 0x0b, 0xe2, 0x28, 0xf1, 0x7c, 0xda, 0x84, 0x71, 0xd1,
+ /*0970:*/ 0x00, 0x30, 0x6d, 0x6e, 0x6c, 0xba, 0x38, 0xcd, 0x51, 0x20, 0xe2, 0x85, 0x30, 0xc1, 0x4f, 0xba,
+ /*0980:*/ 0x8a, 0x89, 0xf2, 0x50, 0x43, 0xf6, 0x1b, 0x4a, 0xa7, 0x2e, 0x8b, 0x67, 0xc4, 0x6d, 0x32, 0x9a,
+ /*0990:*/ 0xba, 0xfb, 0xa7, 0xb2, 0x3f, 0xa3, 0x2d, 0xc6, 0x7c, 0x64, 0x94, 0xde, 0xcf, 0x27, 0x86, 0x90,
+ /*09a0:*/ 0xc7, 0xd5, 0xa3, 0x36, 0xa6, 0x10, 0xcb, 0xcd, 0x58, 0x53, 0x0b, 0xa6, 0xb4, 0x46, 0x2a, 0xf7,
+ /*09b0:*/ 0x28, 0x63, 0x6a, 0x4f, 0x0e, 0xd6, 0x48, 0x3f, 0x93, 0x09, 0x12, 0xb6, 0xd7, 0x4f, 0x59, 0x96,
+ /*09c0:*/ 0xf9, 0xa7, 0x31, 0x0f, 0x59, 0xe1, 0x27, 0xf1, 0x66, 0x99, 0xe7, 0xb4, 0x04, 0xdb, 0xb0, 0xa0,
+ /*09d0:*/ 0x41, 0x1c, 0x98, 0x4c, 0xed, 0x04, 0x19, 0x06, 0xd0, 0x4a, 0x94, 0xef, 0x17, 0xf0, 0x65, 0x5b,
+ /*09e0:*/ 0x47, 0x2e, 0x64, 0x59, 0xb4, 0x45, 0x26, 0x37, 0x21, 0x5a, 0x8a, 0x11, 0xda, 0x41, 0x71, 0x87,
+ /*09f0:*/ 0x43, 0x3d, 0xe7, 0xb9, 0xaf, 0x7e, 0x81, 0x81, 0xc9, 0xd1, 0xf1, 0x0f, 0x62, 0xcc, 0x35, 0xef,
+ /*0a00:*/ 0x8d, 0xee, 0x9d, 0x7a, 0x57, 0xa0, 0xad, 0x9b, 0x40, 0xc8, 0x28, 0xbf, 0xa8, 0xf4, 0xf5, 0x37,
+ /*0a10:*/ 0x60, 0xdb, 0xdb, 0xc8, 0xe5, 0xd1, 0x7b, 0xbc, 0x53, 0x43, 0x8b, 0xf8, 0x10, 0xbe, 0x9d, 0x56,
+ /*0a20:*/ 0x14, 0x75, 0xcc, 0x66, 0x5b, 0x8c, 0x2b, 0x33, 0xaf, 0xa6, 0xe4, 0x08, 0x29, 0xf6, 0x50, 0x7a,
+ /*0a30:*/ 0x0d, 0x11, 0xa1, 0xea, 0x30, 0x49, 0x98, 0x8b, 0xa6, 0x4d, 0x29, 0x73, 0x7d, 0xfa, 0x87, 0xc9,
+ /*0a40:*/ 0x6a, 0x13, 0xfa, 0x75, 0xa0, 0x5a, 0x89, 0xc0, 0xb4, 0x64, 0x96, 0x79, 0x42, 0x6f, 0x30, 0xef,
+ /*0a50:*/ 0x13, 0x1b, 0xe7, 0x44, 0xec, 0x55, 0xb1, 0x77, 0xa6, 0xd9, 0x63, 0x09, 0xc3, 0x29, 0x95, 0x5f,
+ /*0a60:*/ 0xee, 0x92, 0xb6, 0x6e, 0xb4, 0xfd, 0xf2, 0x48, 0x35, 0x13, 0x2c, 0xb7, 0x34, 0xd8, 0x2d, 0x6e,
+ /*0a70:*/ 0xce, 0x21, 0xda, 0xe8, 0x71, 0x86, 0x3a, 0x34, 0x80, 0x5d, 0x59, 0xd5, 0x32, 0x99, 0x95, 0x52,
+ /*0a80:*/ 0x83, 0xd5, 0x7b, 0xd5, 0xa7, 0xa3, 0x52, 0x48, 0x92, 0xdc, 0x1f, 0x34, 0x84, 0x72, 0x08, 0x5a,
+ /*0a90:*/ 0xce, 0xb7, 0x02, 0xea, 0xd1, 0x75, 0x39, 0xe2, 0xa5, 0xae, 0x72, 0x56, 0x2b, 0xcc, 0xd1, 0xc8,
+ /*0aa0:*/ 0x95, 0x54, 0x34, 0x35, 0x94, 0x80, 0xdb, 0x62, 0xbf, 0x1f, 0xe0, 0xbc, 0x0f, 0x43, 0xce, 0xce,
+ /*0ab0:*/ 0x64, 0xfe, 0xbe, 0x7d, 0xe1, 0xc6, 0x81, 0xfe, 0xa6, 0x2b, 0xd7, 0x02, 0x10, 0x83, 0x03, 0xb6,
+ /*0ac0:*/ 0x4d, 0x59, 0x5f, 0x12, 0x39, 0x90, 0x2d, 0x0c, 0xd8, 0x29, 0xbc, 0xae, 0xed, 0x41, 0x66, 0x37,
+ /*0ad0:*/ 0x2c, 0x90, 0xf7, 0xba, 0xf8, 0x09, 0x20, 0x3f, 0x38, 0xd4, 0x7a, 0x24, 0x7b, 0x1a, 0x8b, 0xc6,
+ /*0ae0:*/ 0x69, 0x2b, 0x4d, 0x15, 0xb3, 0xd7, 0x79, 0x5f, 0x87, 0xe5, 0x48, 0x5d, 0x2a, 0x89, 0x85, 0xd7,
+ /*0af0:*/ 0x96, 0xf9, 0x39, 0x91, 0xdb, 0x3d, 0x9e, 0x5b, 0x39, 0xe8, 0x3a, 0x29, 0x4c, 0xd1, 0x22, 0xce,
+ /*0b00:*/ 0x3f, 0xa4, 0xf3, 0xad, 0x28, 0xc2, 0xee, 0xa3, 0x27, 0x19, 0x0a, 0x86, 0x13, 0xeb, 0xcc, 0xc8,
+ /*0b10:*/ 0x69, 0xbf, 0x46, 0xf7, 0xe4, 0x6d, 0xf8, 0x31, 0xbb, 0xd7, 0x45, 0xfd, 0x0a, 0x68, 0xee, 0x2b,
+ /*0b20:*/ 0xb5, 0x71, 0xb2, 0xad, 0x5b, 0x80, 0x5e, 0x69, 0x58, 0x11, 0x6a, 0xea, 0x30, 0x88, 0x33, 0xec,
+ /*0b30:*/ 0xa9, 0xed, 0x2f, 0x8c, 0x95, 0x30, 0xec, 0x4a, 0xc1, 0x47, 0xbd, 0xd0, 0x60, 0x8c, 0x23, 0x0f,
+ /*0b40:*/ 0x9e, 0x11, 0x62, 0xc6, 0xc2, 0xb4, 0xc6, 0x43, 0x4c, 0xa6, 0x66, 0xe8, 0xbc, 0xed, 0x57, 0xfb,
+ /*0b50:*/ 0x6d, 0x73, 0x80, 0xd3, 0x5f, 0xe1, 0x90, 0x27, 0xd5, 0x32, 0x20, 0x9d, 0x1f, 0x72, 0x5d, 0xad,
+ /*0b60:*/ 0xdc, 0xb3, 0x3d, 0x86, 0x75, 0x95, 0x1b, 0x34, 0x52, 0x46, 0x66, 0x58, 0xf6, 0x9a, 0xd7, 0x06,
+ /*0b70:*/ 0xf0, 0x40, 0x64, 0x55, 0x74, 0xa5, 0x70, 0x56, 0x17, 0x71, 0xe7, 0xee, 0xf8, 0x18, 0x77, 0xdd,
+ /*0b80:*/ 0x23, 0x78, 0x01, 0xde, 0x3d, 0x5b, 0x97, 0xd1, 0x35, 0x00, 0x94, 0xd9, 0x12, 0xe3, 0x7b, 0x66,
+ /*0b90:*/ 0xac, 0x58, 0xdb, 0xe8, 0xb0, 0x41, 0x83, 0x3e, 0x7c, 0xdc, 0x04, 0x41, 0x2f, 0xf5, 0x89, 0xce,
+ /*0ba0:*/ 0xbd, 0xf6, 0xa9, 0x95, 0x20, 0x62, 0x66, 0x5d, 0x6a, 0x1d, 0x08, 0xca, 0x44, 0x80, 0x7e, 0xb0,
+ /*0bb0:*/ 0xfd, 0x45, 0x82, 0x92, 0x80, 0x52, 0x99, 0x90, 0x16, 0x59, 0xd1, 0x29, 0xa1, 0xf2, 0x56, 0x84,
+ /*0bc0:*/ 0xa4, 0x5d, 0xdd, 0x82, 0x27, 0x80, 0x17, 0x84, 0x1f, 0x6e, 0x71, 0xb0, 0x7c, 0xb8, 0x39, 0xf6,
+ /*0bd0:*/ 0x9e, 0x55, 0xe6, 0x85, 0xa6, 0x20, 0x56, 0x6b, 0x8e, 0x4e, 0xd5, 0xd1, 0x93, 0xa3, 0xf8, 0x01,
+ /*0be0:*/ 0xc5, 0x04, 0x73, 0x76, 0xdd, 0x79, 0x03, 0x50, 0xc3, 0x6f, 0x89, 0x53, 0x97, 0x3e, 0xf9, 0xa4,
+ /*0bf0:*/ 0xfa, 0xf8, 0xd6, 0x43, 0xcd, 0x98, 0x0d, 0x69, 0xf0, 0xff, 0xa3, 0xd6, 0xb9, 0xa6, 0x0a, 0x59,
+ /*0c00:*/ 0x87, 0x45, 0x5e, 0x1c, 0x0d, 0x5c, 0xc3, 0x30, 0x1c, 0x69, 0xd0, 0x26, 0xc4, 0x64, 0x9f, 0xd9,
+ /*0c10:*/ 0xd3, 0xad, 0xbe, 0x19, 0xfd, 0x77, 0x71, 0xdb, 0xa4, 0x60, 0x93, 0x6c, 0x7e, 0xc5, 0x11, 0x41,
+ /*0c20:*/ 0xab, 0x40, 0xa7, 0x57, 0x70, 0x4b, 0xac, 0x56, 0x21, 0x3e, 0xb7, 0xc3, 0x1e, 0x25, 0xf9, 0xab,
+ /*0c30:*/ 0x86, 0x8b, 0x56, 0xf1, 0x62, 0x37, 0x24, 0xe3, 0x38, 0xb3, 0x51, 0xa8, 0xcb, 0xaa, 0x09, 0xe8,
+ /*0c40:*/ 0x81, 0xa2, 0x9e, 0xc6, 0x4e, 0xbe, 0x7b, 0xfd, 0x96, 0x13, 0xb5, 0x2d, 0x7c, 0xf1, 0xa8, 0xf6,
+ /*0c50:*/ 0x3d, 0x01, 0x2d, 0x8a, 0x8d, 0xf7, 0x8c, 0x0e, 0x6a, 0xf0, 0x00, 0x32, 0xe0, 0x8a, 0xe8, 0xa6,
+ /*0c60:*/ 0x7a, 0x78, 0xad, 0xcb, 0xef, 0xc8, 0xfe, 0x06, 0x74, 0x04, 0x00, 0xf5, 0xc7, 0xf5, 0x00, 0xca,
+ /*0c70:*/ 0x9d, 0x50, 0x57, 0x95, 0x29, 0x13, 0x34, 0xe0, 0xa6, 0xad, 0x81, 0x09, 0x9f, 0x76, 0xc1, 0xde,
+ /*0c80:*/ 0x1b, 0x17, 0xd4, 0x9d, 0xa0, 0x68, 0x1e, 0x6d, 0xd8, 0x3a, 0xe3, 0xa8, 0x9b, 0xfd, 0x55, 0x37,
+ /*0c90:*/ 0xb9, 0xfb, 0x04, 0x17, 0x8c, 0x91, 0xcc, 0x51, 0xdf, 0x96, 0x51, 0x8d, 0x26, 0x1c, 0x38, 0x0c,
+ /*0ca0:*/ 0x74, 0x42, 0x6a, 0x48, 0xdb, 0xb0, 0xed, 0xca, 0x95, 0xa5, 0x07, 0x76, 0x39, 0xaa, 0x9d, 0xc1,
+ /*0cb0:*/ 0xf0, 0xe3, 0x71, 0xce, 0x8c, 0x09, 0x88, 0x63, 0x15, 0x6d, 0x15, 0x3a, 0xdb, 0xaf, 0xad, 0x8f,
+ /*0cc0:*/ 0x63, 0x64, 0x37, 0x65, 0x63, 0x19, 0x7f, 0x63, 0x8a, 0xb6, 0x21, 0xc9, 0x0b, 0xd3, 0x78, 0x0d,
+ /*0cd0:*/ 0x21, 0x08, 0x6e, 0x66, 0xf7, 0xd8, 0xfa, 0xdf, 0x1e, 0x67, 0xae, 0xa3, 0x0b, 0xa8, 0xfb, 0xab,
+ /*0ce0:*/ 0xa6, 0xcb, 0x28, 0x74, 0x47, 0x8e, 0x76, 0xb7, 0xf5, 0xe5, 0x8b, 0xe9, 0x90, 0x26, 0x78, 0xe8,
+ /*0cf0:*/ 0x88, 0x1a, 0x9b, 0xd6, 0x07, 0xe1, 0x4d, 0xe9, 0xc6, 0xc2, 0x3c, 0x42, 0xa5, 0x7c, 0x03, 0xb1,
+ /*0d00:*/ 0x40, 0xd8, 0xec, 0xdf, 0x63, 0x90, 0x38, 0x13, 0x17, 0x9a, 0x34, 0x93, 0x93, 0x7d, 0x17, 0x82,
+ /*0d10:*/ 0xac, 0x78, 0x36, 0x21, 0x8b, 0x13, 0x33, 0xe0, 0xb7, 0xc7, 0xf3, 0x35, 0xff, 0xd7, 0xf5, 0x18,
+ /*0d20:*/ 0xdc, 0x8f, 0xe9, 0xd3, 0x63, 0xf4, 0x69, 0x5a, 0xc2, 0xf7, 0x70, 0x1d, 0xd6, 0x2e, 0x24, 0x31,
+ /*0d30:*/ 0x03, 0x3f, 0x71, 0xc5, 0x1b, 0xa1, 0x0a, 0xa0, 0xaa, 0xfb, 0xd3, 0xc4, 0x2d, 0x0c, 0x5d, 0xb4,
+ /*0d40:*/ 0xf4, 0x69, 0xa2, 0x82, 0xe5, 0xd7, 0x2b, 0x2c, 0xf6, 0x08, 0x1d, 0xb2, 0x14, 0x98, 0x66, 0xc1,
+ /*0d50:*/ 0x15, 0x0d, 0xc9, 0xcc, 0x1d, 0xc2, 0x54, 0x9b, 0x80, 0x27, 0xec, 0x27, 0x70, 0x4b, 0x5c, 0xee,
+ /*0d60:*/ 0xc0, 0xd3, 0x3c, 0x68, 0x50, 0x00, 0xf5, 0x80, 0x56, 0x46, 0xc3, 0x30, 0x97, 0xca, 0x5e, 0x72,
+ /*0d70:*/ 0x50, 0x1d, 0xb2, 0x82, 0x22, 0x73, 0x6f, 0x01, 0xf9, 0xcc, 0x98, 0xf6, 0xc5, 0xdc, 0x75, 0x2e,
+ /*0d80:*/ 0xa6, 0x96, 0x75, 0x75, 0xf1, 0x61, 0x58, 0x2c, 0x9f, 0x7e, 0x5f, 0xba, 0x7b, 0xe3, 0xfa, 0x47,
+ /*0d90:*/ 0xf7, 0x8e, 0xc1, 0x0f, 0xeb, 0xf2, 0x7a, 0x4e, 0x35, 0x09, 0x60, 0xf0, 0x38, 0xeb, 0x57, 0x5e,
+ /*0da0:*/ 0xa3, 0x3f, 0x77, 0x3f, 0xc4, 0xcc, 0xf4, 0xf8, 0xc5, 0x33, 0x19, 0x8e, 0xc8, 0x4a, 0xd1, 0xe5,
+ /*0db0:*/ 0x17, 0x70, 0xdb, 0xf7, 0x7d, 0xbc, 0x7d, 0xe0, 0x2b, 0x7e, 0x10, 0x66, 0x51, 0x47, 0x64, 0xf9,
+ /*0dc0:*/ 0x62, 0xcf, 0x37, 0xbb, 0x92, 0xf5, 0xb3, 0xdf, 0x11, 0x37, 0x93, 0x81, 0x6f, 0xd8, 0xb4, 0x74,
+ /*0dd0:*/ 0x09, 0xcb, 0x36, 0x9e, 0x44, 0xe5, 0xce, 0x3e, 0xfb, 0x3b, 0xaa, 0x1b, 0xfc, 0x46, 0x7b, 0xe6,
+ /*0de0:*/ 0xb0, 0x86, 0x46, 0xbf, 0xf5, 0xc2, 0xa2, 0xdc, 0x5c, 0x91, 0xa7, 0x9f, 0x1b, 0xdd, 0x9f, 0x58,
+ /*0df0:*/ 0x12, 0x44, 0xfe, 0x55, 0x85, 0xc3, 0xfc, 0x12, 0x13, 0x3e, 0xf3, 0x7b, 0xd7, 0x47, 0x4d, 0x26,
+ /*0e00:*/ 0x93, 0x32, 0x45, 0x16, 0xd0, 0x03, 0x66, 0x23, 0xe2, 0x4f, 0x92, 0x21, 0x3c, 0x18, 0x9f, 0x2e,
+ /*0e10:*/ 0xdd, 0xec, 0x8f, 0xeb, 0x3b, 0xef, 0x26, 0xef, 0x35, 0x98, 0xf3, 0x26, 0x90, 0x3d, 0x01, 0x46,
+ /*0e20:*/ 0xc4, 0x3d, 0x49, 0x19, 0xc2, 0xc7, 0xc5, 0x57, 0xf1, 0xd4, 0x1d, 0x63, 0xb3, 0xe3, 0xec, 0x29,
+ /*0e30:*/ 0xb7, 0x8c, 0xa6, 0xb7, 0xae, 0x63, 0x79, 0x5e, 0xc8, 0x02, 0xde, 0x38, 0x4d, 0xee, 0x6e, 0x7e,
+ /*0e40:*/ 0x0f, 0x70, 0xe2, 0xc0, 0x23, 0x83, 0xf6, 0xd7, 0x9e, 0x53, 0xd5, 0x44, 0x96, 0xb1, 0xfe, 0x0c,
+ /*0e50:*/ 0xbb, 0x00, 0x6a, 0xb3, 0xab, 0xeb, 0x31, 0xae, 0x6e, 0x63, 0xed, 0x91, 0x16, 0x44, 0x43, 0xd4,
+ /*0e60:*/ 0x2d, 0xf3, 0x7a, 0x95, 0x5c, 0x93, 0xa9, 0x44, 0x91, 0x7c, 0xb0, 0xc7, 0xdd, 0x92, 0x1c, 0xde,
+ /*0e70:*/ 0xa6, 0xc3, 0xf1, 0x58, 0x4d, 0x25, 0xcd, 0x88, 0x1a, 0x54, 0xbe, 0x50, 0x2b, 0x9a, 0xfb, 0xbc,
+ /*0e80:*/ 0xd6, 0x4d, 0x59, 0x2d, 0xcd, 0x76, 0x16, 0x3c, 0x1c, 0xfd, 0x7a, 0xae, 0x41, 0xae, 0xfa, 0x95,
+ /*0e90:*/ 0xd6, 0xb8, 0x8b, 0xac, 0xa9, 0xee, 0x93, 0x2a, 0x55, 0x21, 0x4b, 0x6c, 0x1a, 0x28, 0x2f, 0x8d,
+ /*0ea0:*/ 0x9c, 0x42, 0xd0, 0xb0, 0x21, 0x90, 0x0a, 0xce, 0xa5, 0x55, 0x6d, 0x52, 0x8e, 0xb7, 0x98, 0xad,
+ /*0eb0:*/ 0xd4, 0xdf, 0x48, 0x48, 0x71, 0x7a, 0x66, 0x4a, 0xb2, 0x45, 0x17, 0xab, 0x5b, 0x91, 0x05, 0x7f,
+ /*0ec0:*/ 0x72, 0xf3, 0xd3, 0x89, 0x1f, 0x81, 0x1f, 0xd4, 0xe8, 0x38, 0x5d, 0x68, 0x24, 0xca, 0x5e, 0xe1,
+ /*0ed0:*/ 0xd4, 0x9e, 0xac, 0x17, 0x09, 0x0e, 0x88, 0x70, 0x7a, 0xae, 0xc1, 0xc8, 0x94, 0xf5, 0x6b, 0x21,
+ /*0ee0:*/ 0x69, 0xc5, 0xd2, 0xb6, 0x0b, 0xc7, 0x2e, 0x27, 0x0b, 0xf2, 0xfd, 0x74, 0x8b, 0xd6, 0xd9, 0x7d,
+ /*0ef0:*/ 0xcd, 0x58, 0x38, 0x20, 0xc8, 0x68, 0x48, 0x08, 0xbd, 0x18, 0x69, 0x0a, 0x4f, 0x04, 0x4e, 0xcf,
+ /*0f00:*/ 0x43, 0x7c, 0x6f, 0x11, 0x86, 0x5b, 0xbb, 0x5b, 0x25, 0x76, 0x77, 0xf0, 0x7b, 0xbd, 0xc7, 0xd2,
+ /*0f10:*/ 0x2c, 0x47, 0xf3, 0x13, 0x3c, 0xfd, 0xbc, 0xa3, 0x80, 0x22, 0xcf, 0x18, 0x92, 0x36, 0x09, 0x9a,
+ /*0f20:*/ 0x96, 0x72, 0x05, 0xb3, 0x67, 0xa2, 0x2a, 0xee, 0x1c, 0x7c, 0x84, 0x37, 0x1c, 0x0d, 0xaa, 0x02,
+ /*0f30:*/ 0xcd, 0xf6, 0xc6, 0x65, 0x14, 0x2d, 0xcd, 0x18, 0x42, 0xc2, 0x3f, 0xee, 0x09, 0xcd, 0x57, 0xf9,
+ /*0f40:*/ 0xdd, 0xa9, 0xd4, 0xf1, 0xb3, 0x97, 0x9f, 0xf7, 0xb7, 0x4a, 0x39, 0x9c, 0xb5, 0x64, 0xd2, 0x66,
+ /*0f50:*/ 0x58, 0x78, 0x69, 0x65, 0xfa, 0x21, 0xfd, 0x1e, 0x0f, 0xe2, 0x37, 0x57, 0xf9, 0x8d, 0x56, 0x34,
+ /*0f60:*/ 0x76, 0xb4, 0x07, 0xa4, 0x9b, 0xf4, 0x27, 0xf0, 0x26, 0x95, 0x23, 0xf5, 0x6a, 0x35, 0x99, 0x52,
+ /*0f70:*/ 0xac, 0x40, 0x51, 0xd2, 0xf2, 0x2b, 0x22, 0x54, 0xff, 0x45, 0xda, 0x84, 0x1e, 0x72, 0x53, 0xa3,
+ /*0f80:*/ 0xb2, 0x9e, 0xc0, 0x6e, 0x68, 0x62, 0xa1, 0x8a, 0x74, 0xa9, 0x90, 0xfa, 0x19, 0xd0, 0x25, 0x13,
+ /*0f90:*/ 0xd0, 0x3b, 0x59, 0xcd, 0x85, 0x5e, 0xc4, 0x4b, 0x7b, 0x3c, 0xd4, 0xc1, 0x91, 0xa9, 0xc0, 0xce,
+ /*0fa0:*/ 0x5a, 0xa6, 0xc0, 0x84, 0x0c, 0xea, 0xd5, 0xeb, 0xad, 0x6c, 0x81, 0x12, 0xb4, 0x3d, 0xac, 0x20,
+ /*0fb0:*/ 0xcc, 0x4c, 0x82, 0xa0, 0xc3, 0x77, 0x01, 0x20, 0xeb, 0xc0, 0xd5, 0x86, 0xa0, 0x79, 0x1f, 0x75,
+ /*0fc0:*/ 0x27, 0xf6, 0xd4, 0xae, 0x45, 0x0f, 0x42, 0x36, 0x7f, 0x96, 0x8a, 0x9a, 0x6d, 0x65, 0xa7, 0xa3,
+ /*0fd0:*/ 0x8b, 0x6a, 0xea, 0xb6, 0x72, 0xb8, 0x37, 0x3f, 0x3f, 0x64, 0x64, 0x84, 0xa3, 0x68, 0x44, 0x7a,
+ /*0fe0:*/ 0x10, 0xe6, 0x9c, 0x54, 0x54, 0x6b, 0xc9, 0x83, 0x88, 0x49, 0x71, 0x25, 0x7a, 0x01, 0x36, 0x15,
+ /*0ff0:*/ 0x8e, 0x84, 0x8c, 0x41, 0x8a, 0x07, 0xc3, 0x9a, 0x87, 0x16, 0x52, 0xe8, 0xe7, 0x49, 0xd3, 0xc8,
+ /*1000:*/ 0x8c, 0x4a, 0xfe, 0xd9, 0xd2, 0x8c, 0xac, 0x45, 0xf2, 0xc5, 0x57, 0x73, 0xf7, 0x47, 0x1c, 0x1d,
+ /*1010:*/ 0x33, 0x2a, 0x16, 0x87, 0xf2, 0xfc, 0xec, 0xcd, 0x41, 0x8f, 0x5e, 0xa4, 0x40, 0x75, 0x75, 0x33,
+ /*1020:*/ 0xcd, 0x40, 0x13, 0x77, 0xa6, 0xb7, 0x3a, 0xf4, 0xd5, 0x5c, 0x3d, 0x9e, 0xdc, 0xd2, 0x31, 0x4f,
+ /*1030:*/ 0x6a, 0x4f, 0xae, 0x9b, 0xa4, 0xe7, 0xb6, 0xb9, 0x3c, 0x87, 0x02, 0x5f, 0x48, 0xbe, 0x87, 0xa7,
+ /*1040:*/ 0x92, 0x52, 0x8f, 0x72, 0x15, 0xbe, 0xce, 0x65, 0xfe, 0x1d, 0x9e, 0xf8, 0x9f, 0xc3, 0x8e, 0x57,
+ /*1050:*/ 0xbf, 0xa7, 0xe6, 0x8f, 0xb1, 0x50, 0x8c, 0x19, 0x42, 0x8a, 0x4b, 0x6f, 0x4f, 0xcf, 0xe6, 0xd5,
+ /*1060:*/ 0x0d, 0xa3, 0xe7, 0x02, 0x2a, 0x35, 0x17, 0xc5, 0x74, 0xab, 0xa0, 0x6d, 0xee, 0x58, 0x35, 0x10,
+ /*1070:*/ 0xc6, 0xb6, 0xf1, 0x9b, 0xe2, 0x1e, 0xfc, 0xb8, 0x95, 0xcb, 0xbb, 0xb2, 0x0a, 0xc2, 0x1c, 0x67,
+ /*1080:*/ 0xa3, 0x1d, 0x62, 0x44, 0x96, 0xdb, 0x36, 0xf0, 0xfd, 0xd2, 0x48, 0x98, 0x92, 0xdc, 0xec, 0xf4,
+ /*1090:*/ 0x44, 0x81, 0xf8, 0x3a, 0x6f, 0x1e, 0x24, 0x14, 0x26, 0x0c, 0x15, 0x74, 0xf1, 0x45, 0x8d, 0xfb,
+ /*10a0:*/ 0xee, 0x32, 0x61, 0x72, 0x28, 0x41, 0xc4, 0x12, 0xc0, 0x37, 0xca, 0x7f, 0x70, 0x86, 0xce, 0xf5,
+ /*10b0:*/ 0x34, 0xcf, 0xc6, 0x99, 0x5a, 0x74, 0xc9, 0xad, 0xce, 0x7d, 0x35, 0x80, 0x00, 0x47, 0xbf, 0xdd,
+ /*10c0:*/ 0x49, 0x42, 0xde, 0x17, 0xf1, 0xf2, 0x77, 0x1f, 0x3e, 0x47, 0x7e, 0x18, 0x2a, 0xb5, 0xae, 0x43,
+ /*10d0:*/ 0x46, 0x7d, 0xa9, 0x10, 0xfa, 0x0a, 0xca, 0x54, 0xf6, 0x03, 0xe0, 0xa2, 0xd3, 0xe5, 0x2b, 0xca,
+ /*10e0:*/ 0xe5, 0x3b, 0x46, 0xb6, 0xe2, 0x0e, 0x36, 0x71, 0x68, 0xaf, 0x51, 0xc3, 0xd9, 0xeb, 0x64, 0x60,
+ /*10f0:*/ 0x78, 0x2c, 0xfc, 0x5f, 0x73, 0x1f, 0xa0, 0x8a, 0xa5, 0xe5, 0xc3, 0x90, 0x3e, 0xc8, 0x83, 0x56,
+ /*1100:*/ 0xda, 0x17, 0xee, 0x23, 0x3b, 0x7a, 0x6d, 0xfe, 0xef, 0xa9, 0xe8, 0x92, 0xc5, 0xa5, 0xd7, 0x5e,
+ /*1110:*/ 0x11, 0x18, 0xd8, 0xf5, 0x1c, 0xd8, 0x1d, 0x9b, 0x0b, 0x79, 0x91, 0xa3, 0x02, 0x7d, 0xa3, 0x0f,
+ /*1120:*/ 0xc2, 0xcc, 0xb0, 0x0d, 0xfc, 0x7e, 0xbd, 0x1b, 0xee, 0x42, 0x90, 0x65, 0x20, 0xd8, 0xad, 0x41,
+ /*1130:*/ 0x6b, 0xba, 0xb0, 0xeb, 0xaa, 0xa4, 0x1b, 0x80, 0x97, 0xa7, 0x88, 0x2e, 0xdc, 0xfd, 0x55, 0x65,
+ /*1140:*/ 0xe9, 0xf1, 0xb6, 0x9a, 0x27, 0xca, 0x23, 0x30, 0x46, 0x3e, 0x6f, 0x0c, 0x57, 0xc3, 0xd7, 0xca,
+ /*1150:*/ 0xe3, 0x99, 0xe6, 0x09, 0xa1, 0x5c, 0x72, 0xd8, 0x65, 0x08, 0x21, 0xfe, 0xb0, 0x48, 0xc9, 0xf9,
+ /*1160:*/ 0x42, 0xad, 0xda, 0x11, 0x70, 0x56, 0x0a, 0xa5, 0x3b, 0xd9, 0xee, 0xc7, 0x30, 0x9b, 0x23, 0xd9,
+ /*1170:*/ 0xa0, 0x82, 0x8d, 0xe0, 0x77, 0x67, 0x4a, 0x85, 0x8b, 0x52, 0x9a, 0x16, 0xf1, 0x6a, 0x74, 0x96,
+ /*1180:*/ 0xf7, 0xfe, 0xa6, 0x83, 0x72, 0xb6, 0x82, 0x78, 0x44, 0xd7, 0x51, 0x70, 0x92, 0x8e, 0x64, 0xc3,
+ /*1190:*/ 0x8c, 0x92, 0x18, 0xc9, 0x7a, 0x4d, 0x7e, 0xd1, 0x11, 0x53, 0xa6, 0x14, 0xed, 0x9c, 0x04, 0x01,
+ /*11a0:*/ 0xdb, 0x9f, 0xfd, 0x38, 0xc7, 0xf0, 0xb0, 0x70, 0x96, 0x7a, 0x67, 0xdc, 0x19, 0xeb, 0xaf, 0xf9,
+ /*11b0:*/ 0x25, 0x1f, 0xbc, 0xc0, 0xa4, 0xa8, 0x05, 0x7b, 0x9e, 0xd5, 0xe8, 0x1c, 0xe3, 0x71, 0xab, 0x92,
+ /*11c0:*/ 0xc9, 0xb4, 0xac, 0xb0, 0xe0, 0xf1, 0x59, 0x0b, 0x58, 0x3e, 0xca, 0x9d, 0x3e, 0xd0, 0xae, 0xeb,
+ /*11d0:*/ 0x51, 0xf0, 0x3c, 0xc0, 0xb9, 0x0b, 0xda, 0xba, 0x6b, 0xd8, 0x1f, 0x97, 0x68, 0x75, 0xbc, 0x88,
+ /*11e0:*/ 0x44, 0x5c, 0x37, 0xc7, 0x0c, 0xd7, 0xf1, 0x1d, 0x03, 0xe8, 0x0e, 0xa6, 0xae, 0xd0, 0x66, 0xa4,
+ /*11f0:*/ 0xd1, 0xf5, 0x52, 0xc8, 0x7b, 0x1e, 0xfe, 0x4b, 0x5d, 0xdd, 0xca, 0xad, 0x21, 0xde, 0x28, 0xf4,
+ /*1200:*/ 0x98, 0x98, 0x9c, 0xd2, 0x62, 0xd7, 0x00, 0xde, 0x6a, 0xf1, 0xa1, 0xe4, 0x1c, 0xaf, 0x1f, 0x9b,
+ /*1210:*/ 0x90, 0x8a, 0x40, 0x9d, 0x78, 0x64, 0x75, 0x60, 0xaa, 0xc7, 0xce, 0x63, 0x65, 0x1e, 0x65, 0x74,
+ /*1220:*/ 0x9b, 0x37, 0xb2, 0xb7, 0x54, 0xc5, 0x6d, 0xce, 0x1d, 0x08, 0x3a, 0x01, 0x07, 0xc1, 0x80, 0x21,
+ /*1230:*/ 0x1e, 0x25, 0xbe, 0x97, 0xbb, 0x53, 0x3f, 0x8a, 0xcf, 0x1c, 0xfe, 0x7f, 0x93, 0xfb, 0x0c, 0x5a,
+ /*1240:*/ 0x52, 0xf2, 0x63, 0xba, 0xd0, 0xa5, 0x5b, 0xd8, 0x98, 0xb8, 0x95, 0xd4, 0xc8, 0xb1, 0x04, 0x99,
+ /*1250:*/ 0x83, 0xb4, 0xcb, 0xe4, 0x3a, 0xea, 0x02, 0x5e, 0x88, 0x6e, 0xfd, 0xf8, 0x79, 0x5f, 0x03, 0x99,
+ /*1260:*/ 0x56, 0xea, 0x25, 0xc8, 0x08, 0x1b, 0x6a, 0x8d, 0x28, 0xe6, 0x08, 0x47, 0x67, 0xf5, 0xc7, 0x52,
+ /*1270:*/ 0x60, 0x08, 0x42, 0x5f, 0x58, 0x01, 0x0a, 0xf2, 0xa3, 0xa3, 0x1e, 0x91, 0x17, 0x5d, 0xe8, 0xe4,
+ /*1280:*/ 0x14, 0x10, 0x67, 0xc3, 0x1c, 0x3e, 0x71, 0x23, 0x45, 0xf3, 0xc9, 0x73, 0xc9, 0xc5, 0x94, 0x67,
+ /*1290:*/ 0x51, 0x22, 0xa5, 0xf9, 0x45, 0xce, 0x35, 0x20, 0xf7, 0xf7, 0x1a, 0xea, 0x52, 0x25, 0x17, 0xb1,
+ /*12a0:*/ 0xec, 0xc5, 0x4e, 0xe9, 0x03, 0x8f, 0xc2, 0x0c, 0xa3, 0x00, 0xd9, 0xe8, 0xe8, 0xb2, 0xbe, 0xaf,
+ /*12b0:*/ 0xcb, 0xda, 0xf8, 0xbe, 0x2d, 0x2e, 0x92, 0x23, 0x3b, 0x9b, 0x27, 0x65, 0x7f, 0x03, 0xc7, 0x8e,
+ /*12c0:*/ 0x9c, 0x86, 0x66, 0xf4, 0x67, 0xb4, 0x7b, 0x7d, 0x44, 0x73, 0x8e, 0x7e, 0x32, 0x87, 0x58, 0xa9,
+ /*12d0:*/ 0xcf, 0x92, 0xc8, 0x07, 0x41, 0xc5, 0x41, 0x17, 0x34, 0xed, 0x3b, 0xd6, 0x30, 0xca, 0x66, 0x50,
+ /*12e0:*/ 0x4a, 0x1e, 0x68, 0xcc, 0x91, 0xe2, 0x78, 0x38, 0xfc, 0x04, 0x72, 0xfb, 0xbb, 0x63, 0x4f, 0x30,
+ /*12f0:*/ 0xc2, 0xbb, 0x4a, 0xd5, 0xc9, 0x0e, 0x53, 0xc7, 0x5c, 0x83, 0x1d, 0xc0, 0x42, 0x22, 0xfa, 0xba,
+ /*1300:*/ 0x31, 0xfa, 0x85, 0x75, 0x8e, 0x7b, 0x1b, 0x63, 0x2a, 0x13, 0x2a, 0x33, 0x01, 0x86, 0xc0, 0xdd,
+ /*1310:*/ 0xfd, 0x14, 0xc5, 0x84, 0x9b, 0xcc, 0xa5, 0x89, 0x31, 0x27, 0x6e, 0x3b, 0xc6, 0xb0, 0xf2, 0x23,
+ /*1320:*/ 0x61, 0x52, 0x5b, 0x3a, 0xf2, 0x63, 0x3a, 0xc2, 0x6e, 0xaf, 0x98, 0x97, 0x5c, 0xbc, 0xd4, 0xf3,
+ /*1330:*/ 0xd4, 0x98, 0x25, 0x73, 0xc6, 0xbb, 0x64, 0x85, 0x88, 0x95, 0x0d, 0xcb, 0xaa, 0xfd, 0x57, 0x9c,
+ /*1340:*/ 0xa8, 0x4f, 0x32, 0xa4, 0xce, 0xf0, 0x0d, 0x1c, 0xac, 0x9a, 0x53, 0x84, 0xb8, 0x4e, 0x48, 0xc0,
+ /*1350:*/ 0xfb, 0xc2, 0x48, 0x1e, 0x76, 0xb4, 0xf2, 0x7c, 0xde, 0xe1, 0xc4, 0xf4, 0xb7, 0x09, 0x19, 0x7e,
+ /*1360:*/ 0x0d, 0x40, 0x92, 0xa3, 0x4e, 0x14, 0xcf, 0x15, 0x17, 0x6c, 0x81, 0x55, 0xaa, 0xce, 0xa6, 0x8b,
+ /*1370:*/ 0xbf, 0xd6, 0x30, 0x06, 0xa0, 0x1b, 0x18, 0x40, 0xca, 0x69, 0xab, 0xe2, 0x3e, 0xa5, 0xf2, 0x85,
+ /*1380:*/ 0x43, 0x54, 0x76, 0x5d, 0xe3, 0x96, 0xd4, 0x39, 0x47, 0x70, 0x1a, 0x71, 0x94, 0xcd, 0x9d, 0xfa,
+ /*1390:*/ 0xb0, 0x89, 0xab, 0x7a, 0x2e, 0x49, 0xb5, 0x34, 0x66, 0xbb, 0xdc, 0x6e, 0x5a, 0x1d, 0x65, 0x20,
+ /*13a0:*/ 0xce, 0x49, 0x1d, 0xeb, 0x73, 0x83, 0x00, 0x05, 0xb0, 0x5a, 0x56, 0xc3, 0xa5, 0x0f, 0x03, 0xb0,
+ /*13b0:*/ 0xdb, 0xb5, 0xf0, 0x61, 0x2c, 0xfd, 0x37, 0x38, 0x7d, 0xf8, 0xc4, 0x09, 0xd0, 0xf3, 0xdc, 0x62,
+ /*13c0:*/ 0xca, 0x29, 0x71, 0xb9, 0x44, 0xc4, 0x24, 0x21, 0xc5, 0xfe, 0x9c, 0xd9, 0xd4, 0x89, 0x44, 0x00,
+ /*13d0:*/ 0x20, 0xae, 0xd9, 0xae, 0xd6, 0xea, 0x5d, 0x04, 0x35, 0x4c, 0x09, 0x47, 0xfa, 0x85, 0x7f, 0x1e,
+ /*13e0:*/ 0x52, 0x62, 0xb7, 0x8a, 0x05, 0xc5, 0x47, 0x39, 0x2d, 0xe8, 0xf0, 0xf7, 0x57, 0x67, 0xf5, 0xda,
+ /*13f0:*/ 0x47, 0xe9, 0x10, 0x84, 0xb4, 0xf9, 0x3f, 0x8d, 0xae, 0xdd, 0xce, 0x76, 0xc9, 0xfe, 0x0b, 0x52,
+ /*1400:*/ 0x63, 0x1d, 0xde, 0x2a, 0x25, 0x54, 0x9c, 0xab, 0x2b, 0x52, 0x30, 0x8c, 0x80, 0xe8, 0x50, 0xe0,
+ /*1410:*/ 0x2b, 0x6b, 0xf5, 0x42, 0xbc, 0x26, 0x85, 0x9f, 0xd3, 0x9a, 0xbe, 0x41, 0xd2, 0xf1, 0xa6, 0xd7,
+ /*1420:*/ 0xf2, 0xcd, 0x72, 0xab, 0x8d, 0x4c, 0x46, 0x7b, 0xaf, 0x82, 0x58, 0xd7, 0x2f, 0x16, 0x07, 0x28,
+ /*1430:*/ 0xf0, 0x3a, 0x7e, 0x85, 0xc3, 0xf3, 0xe8, 0xe5, 0x00, 0x06, 0x00, 0xb5, 0x97, 0x19, 0x9f, 0xde,
+ /*1440:*/ 0x99, 0x1f, 0xf5, 0x08, 0x97, 0x02, 0x6e, 0x60, 0xc5, 0xa7, 0x77, 0x99, 0xcf, 0x04, 0xa6, 0x2f,
+ /*1450:*/ 0xb5, 0xca, 0xff, 0x4b, 0xd7, 0xee, 0xcc, 0x90, 0x6c, 0x77, 0xac, 0x95, 0x3f, 0x24, 0xa5, 0x50,
+ /*1460:*/ 0x00, 0x9d, 0xf5, 0x7e, 0xed, 0x37, 0xa8, 0xd6, 0xd7, 0xf2, 0xf7, 0x14, 0xb8, 0x2e, 0x7e, 0x1f,
+ /*1470:*/ 0xa3, 0x02, 0xec, 0x4c, 0xf5, 0xc6, 0x7b, 0x03, 0x99, 0x3b, 0x9d, 0xaf, 0xad, 0xe2, 0x44, 0x7c,
+ /*1480:*/ 0x89, 0xd6, 0xd3, 0x09, 0x0c, 0xed, 0x48, 0x17, 0x3e, 0xcc, 0xce, 0x08, 0x1d, 0x2d, 0x47, 0x36,
+ /*1490:*/ 0xf8, 0x6c, 0x37, 0xcd, 0x7c, 0xc7, 0xf3, 0x06, 0x17, 0x8c, 0xca, 0xfe, 0x36, 0x4c, 0xb8, 0x10,
+ /*14a0:*/ 0x08, 0xe6, 0xd5, 0xa8, 0x99, 0x56, 0x48, 0xe0, 0x18, 0x44, 0x72, 0x63, 0x3d, 0x09, 0xd5, 0xd9,
+ /*14b0:*/ 0x5a, 0xe1, 0x4c, 0x38, 0xd1, 0xdc, 0x0b, 0x47, 0xd3, 0x8a, 0x1a, 0xf8, 0xe8, 0x75, 0x3b, 0x1a,
+ /*14c0:*/ 0x9c, 0xcb, 0x89, 0x37, 0xc4, 0xa6, 0xa3, 0xbe, 0xf6, 0xe5, 0x40, 0xd3, 0x44, 0x1d, 0xea, 0x92,
+ /*14d0:*/ 0xfa, 0xf2, 0xd6, 0x0d, 0x52, 0xf0, 0x8c, 0x0b, 0x3a, 0x55, 0x75, 0x7a, 0xfc, 0xef, 0x81, 0xdb,
+ /*14e0:*/ 0xc5, 0x97, 0x81, 0xe3, 0x32, 0xd8, 0x8a, 0x49, 0xf0, 0x14, 0x28, 0x14, 0xac, 0x7a, 0xc6, 0x21,
+ /*14f0:*/ 0xe2, 0xa9, 0x61, 0xc4, 0xa5, 0xd2, 0x8d, 0xd6, 0x36, 0xba, 0x4f, 0x20, 0x43, 0xeb, 0xac, 0xef,
+ /*1500:*/ 0x6a, 0x81, 0x0a, 0x54, 0x37, 0x35, 0x34, 0x09, 0xce, 0xdc, 0x78, 0x43, 0x00, 0xc5, 0x46, 0x0e,
+ /*1510:*/ 0x17, 0xb1, 0x7a, 0x51, 0x96, 0x54, 0xee, 0x24, 0x32, 0xf9, 0x09, 0x66, 0xff, 0xf6, 0xb9, 0x9f,
+ /*1520:*/ 0x06, 0xa4, 0x55, 0x8c, 0x3b, 0x9d, 0xcd, 0x31, 0x01, 0x33, 0x61, 0xeb, 0xd3, 0x45, 0x49, 0x34,
+ /*1530:*/ 0x2e, 0xff, 0xa3, 0x7f, 0xf5, 0xb0, 0x37, 0x00, 0x31, 0x84, 0xb1, 0xa1, 0x9f, 0xa4, 0xdb, 0xc7,
+ /*1540:*/ 0xa2, 0xd9, 0x23, 0x4c, 0xf0, 0x09, 0x57, 0x9b, 0x4b, 0xbc, 0x6b, 0xe4, 0x15, 0x55, 0x9f, 0x3d,
+ /*1550:*/ 0x97, 0xa6, 0xab, 0x0a, 0x86, 0xde, 0xd3, 0x83, 0xd2, 0x81, 0x21, 0x75, 0x60, 0x66, 0xd8, 0xa1,
+ /*1560:*/ 0xd0, 0xdb, 0x08, 0x42, 0xe6, 0xf1, 0xeb, 0x6f, 0x59, 0xe2, 0x0f, 0xd1, 0x00, 0x3a, 0x09, 0x86,
+ /*1570:*/ 0x61, 0x8f, 0x3c, 0x6d, 0x02, 0x48, 0x41, 0x1a, 0x9b, 0xcd, 0x33, 0xd6, 0xbe, 0x15, 0x88, 0x2a,
+ /*1580:*/ 0x94, 0xf9, 0xc9, 0xda, 0x03, 0xb3, 0x1c, 0xaa, 0x22, 0x19, 0xa9, 0x9e, 0xdd, 0xe7, 0x7e, 0x92,
+ /*1590:*/ 0xdf, 0x06, 0xd7, 0x0c, 0xe0, 0x19, 0xa8, 0xec, 0x9a, 0x33, 0xfa, 0x30, 0xa7, 0xe9, 0xc9, 0x3d,
+ /*15a0:*/ 0x6a, 0x14, 0x89, 0x5b, 0xe9, 0x19, 0xfd, 0xf5, 0xdb, 0xfe, 0x70, 0x4a, 0x09, 0x18, 0x9a, 0x90,
+ /*15b0:*/ 0x16, 0x88, 0xb2, 0x60, 0x6e, 0x34, 0xa5, 0x22, 0x7e, 0x2d, 0x5a, 0x37, 0x0e, 0xbe, 0x71, 0x7e,
+ /*15c0:*/ 0x5a, 0xd4, 0x38, 0x0b, 0x25, 0x49, 0x4d, 0x07, 0x47, 0xee, 0x3d, 0xfe, 0x8f, 0x81, 0xdb, 0xb2,
+ /*15d0:*/ 0xda, 0x0d, 0x71, 0xbc, 0x10, 0x36, 0x69, 0xd5, 0xec, 0xdd, 0x57, 0xc4, 0xeb, 0x52, 0xd6, 0x2c,
+ /*15e0:*/ 0xce, 0xaf, 0xe7, 0xae, 0xfa, 0xf6, 0x22, 0x8e, 0x72, 0x39, 0xcb, 0x48, 0x0f, 0x76, 0x9c, 0x51,
+ /*15f0:*/ 0x54, 0x7b, 0x7c, 0x2d, 0x5d, 0x4e, 0x54, 0x82, 0xf4, 0xfd, 0x6b, 0xdf, 0x97, 0xed, 0xec, 0x68,
+ /*1600:*/ 0xb7, 0x03, 0x26, 0x74, 0x46, 0xcc, 0x3f, 0x6d, 0x49, 0x52, 0xce, 0xe2, 0x82, 0x12, 0x79, 0x85,
+ /*1610:*/ 0x95, 0xb6, 0x4c, 0x9e, 0x61, 0xd9, 0xc4, 0xaa, 0xd6, 0xcd, 0x0b, 0xad, 0x78, 0xd8, 0xed, 0x07,
+ /*1620:*/ 0x5c, 0x8b, 0xe4, 0x1c, 0x86, 0x85, 0xf2, 0xee, 0x98, 0x81, 0x4f, 0xa9, 0x74, 0x22, 0xd5, 0x7f,
+ /*1630:*/ 0xf3, 0x48, 0xec, 0x30, 0xde, 0x23, 0x10, 0xa8, 0x6e, 0x1e, 0xbb, 0x6b, 0x31, 0xd1, 0x26, 0x48,
+ /*1640:*/ 0xac, 0x4a, 0x19, 0x66, 0xef, 0x2e, 0x5f, 0xd9, 0x7a, 0xc6, 0xfa, 0xc3, 0x06, 0xf0, 0xfe, 0x6c,
+ /*1650:*/ 0xd3, 0xf5, 0xdd, 0x6b, 0x09, 0x39, 0x17, 0x99, 0x29, 0xff, 0x24, 0x51, 0x3b, 0x06, 0x35, 0x92,
+ /*1660:*/ 0xda, 0x9f, 0x9f, 0x32, 0x40, 0x5c, 0x05, 0x60, 0x18, 0xd5, 0xb4, 0xd7, 0x9d, 0x7f, 0xd8, 0x5b,
+ /*1670:*/ 0x3e, 0x67, 0xee, 0xaa, 0x12, 0xd0, 0xd1, 0x61, 0x78, 0x60, 0x28, 0x63, 0xd8, 0x91, 0xe1, 0x86,
+ /*1680:*/ 0x78, 0x01, 0x62, 0x55, 0xa8, 0x5c, 0x7d, 0xf5, 0x80, 0x97, 0x16, 0xaa, 0xcc, 0x62, 0xec, 0x35,
+ /*1690:*/ 0x18, 0x53, 0xda, 0xfc, 0x3b, 0x5b, 0x2f, 0xe5, 0xd0, 0xb9, 0xba, 0x31, 0xed, 0xbe, 0xe0, 0xf1,
+ /*16a0:*/ 0xfa, 0x54, 0x8f, 0x1d, 0x1a, 0xfc, 0xfb, 0xe0, 0xbb, 0x30, 0x0c, 0x6a, 0xf7, 0x80, 0x27, 0xbb,
+ /*16b0:*/ 0xb2, 0xc3, 0x38, 0xb9, 0x01, 0x2c, 0x93, 0x00, 0xac, 0xb0, 0xef, 0x9a, 0x44, 0x7d, 0xfb, 0x0b,
+ /*16c0:*/ 0x91, 0x36, 0xac, 0xb7, 0x0a, 0xe9, 0x29, 0xdc, 0x82, 0x8a, 0x76, 0x75, 0x12, 0xec, 0x81, 0x20,
+ /*16d0:*/ 0x55, 0x2b, 0x67, 0x28, 0xa6, 0x1a, 0x73, 0xde, 0x82, 0xac, 0x0f, 0xa6, 0xd8, 0xa6, 0x96, 0xf7,
+ /*16e0:*/ 0xe6, 0x27, 0x33, 0xa3, 0x4d, 0x37, 0x66, 0xbd, 0xcf, 0xa3, 0x70, 0x4f, 0xae, 0xb3, 0x55, 0x92,
+ /*16f0:*/ 0x8b, 0x7c, 0x5f, 0xd3, 0x5e, 0x8a, 0x84, 0xf8, 0x30, 0x95, 0x16, 0xb5, 0xfc, 0xc2, 0x23, 0x25,
+ /*1700:*/ 0x65, 0xdb, 0x48, 0xcd, 0xfc, 0xc4, 0xbf, 0xca, 0xa3, 0xd3, 0x8b, 0xe4, 0x5c, 0x7a, 0x97, 0x5d,
+ /*1710:*/ 0xa8, 0xc5, 0xf9, 0x1a, 0x91, 0x60, 0x3b, 0x20, 0x77, 0xe7, 0x35, 0x99, 0x43, 0x47, 0x1c, 0x96,
+ /*1720:*/ 0x54, 0xeb, 0x9f, 0xc0, 0x7e, 0xb0, 0xcd, 0x9f, 0x62, 0xec, 0x5c, 0xd9, 0x37, 0xc8, 0x4d, 0x92,
+ /*1730:*/ 0xc0, 0x76, 0xfa, 0x3b, 0xbd, 0x4b, 0xd1, 0x1f, 0x43, 0xd9, 0x55, 0x7a, 0xb8, 0x7c, 0x7b, 0xa3,
+ /*1740:*/ 0x0c, 0x26, 0x5f, 0x6b, 0x7c, 0x38, 0xc2, 0x72, 0x36, 0xd7, 0xc0, 0x5c, 0x57, 0x69, 0xd1, 0x1a,
+ /*1750:*/ 0xc6, 0xda, 0x20, 0x3a, 0x2a, 0x43, 0x2b, 0x32, 0x86, 0x37, 0x8d, 0x44, 0x20, 0x0c, 0xcf, 0xb4,
+ /*1760:*/ 0xe8, 0x7b, 0x38, 0xc2, 0xea, 0x4f, 0xd2, 0xf3, 0xe0, 0x44, 0x11, 0xa4, 0x60, 0x11, 0xea, 0x09,
+ /*1770:*/ 0x3a, 0x04, 0x0b, 0xe8, 0xcc, 0x55, 0xbf, 0xa2, 0xe7, 0xee, 0x4e, 0xbf, 0xc6, 0x10, 0xbf, 0x0c,
+ /*1780:*/ 0xb9, 0x24, 0xa9, 0x8c, 0x46, 0x81, 0xc7, 0x44, 0x3e, 0x63, 0x50, 0xce, 0x4c, 0x91, 0xfc, 0xe8,
+ /*1790:*/ 0x2e, 0x97, 0x76, 0xc5, 0xf4, 0xd0, 0x36, 0x5a, 0x6c, 0x30, 0xfe, 0xc1, 0x02, 0x86, 0x07, 0xd3,
+ /*17a0:*/ 0xeb, 0x57, 0x6d, 0x43, 0xf9, 0xfa, 0xc7, 0x39, 0xd5, 0xfa, 0x70, 0xa4, 0x55, 0x7c, 0x4e, 0x93,
+ /*17b0:*/ 0xca, 0xd9, 0x78, 0xcb, 0xa2, 0x1d, 0x79, 0x96, 0x55, 0x16, 0x94, 0x8d, 0x74, 0xda, 0xa5, 0x1c,
+ /*17c0:*/ 0xf6, 0xa3, 0xcc, 0x33, 0x0e, 0x3a, 0x29, 0xa0, 0xf9, 0x7d, 0x8b, 0x13, 0x6e, 0x7f, 0x02, 0x4a,
+ /*17d0:*/ 0x50, 0xd3, 0x7c, 0x1e, 0x09, 0x3c, 0xd0, 0x03, 0xad, 0x0d, 0xb2, 0xfa, 0xa1, 0x8b, 0xd3, 0x69,
+ /*17e0:*/ 0x91, 0x7a, 0x6a, 0xe2, 0x66, 0x1a, 0xe4, 0x3d, 0xdf, 0xab, 0x3f, 0xfa, 0x39, 0xb3, 0x66, 0x0a,
+ /*17f0:*/ 0x80, 0x1a, 0x07, 0x75, 0xe6, 0xfd, 0x9b, 0x9b, 0xfe, 0xf0, 0x9c, 0x3f, 0x9e, 0x43, 0xc8, 0xe3,
+ /*1800:*/ 0xbd, 0xb4, 0x32, 0x25, 0x4f, 0x96, 0x8f, 0xba, 0x46, 0x34, 0xdc, 0x9e, 0x18, 0xe8, 0x16, 0x9a,
+ /*1810:*/ 0xc1, 0x8c, 0x41, 0x16, 0x2d, 0x88, 0x0b, 0x1d, 0x6f, 0x2a, 0xbf, 0x99, 0x85, 0x14, 0xa3, 0x89,
+ /*1820:*/ 0x86, 0xac, 0xf6, 0xe3, 0x7b, 0xcf, 0x48, 0xec, 0xe0, 0x74, 0xbc, 0x96, 0x95, 0x4d, 0x76, 0x1d,
+ /*1830:*/ 0x5e, 0x76, 0x49, 0x63, 0x62, 0x75, 0x21, 0x87, 0x4d, 0x62, 0xb3, 0xfe, 0x0b, 0xf5, 0xed, 0x8c,
+ /*1840:*/ 0x95, 0x9c, 0xd3, 0xc5, 0x5f, 0x14, 0xd8, 0x4e, 0x41, 0xaa, 0xd9, 0x1f, 0xb3, 0x67, 0x35, 0xaf,
+ /*1850:*/ 0x0d, 0x3a, 0xcb, 0xe5, 0xcc, 0x84, 0xc4, 0xab, 0x45, 0x38, 0xa9, 0x45, 0x66, 0x12, 0x75, 0x93,
+ /*1860:*/ 0xc0, 0x36, 0x42, 0x88, 0xb6, 0x5e, 0x3f, 0xae, 0x67, 0xe5, 0x5f, 0xe2, 0xc1, 0x93, 0xca, 0x84,
+ /*1870:*/ 0x55, 0xa1, 0xda, 0xec, 0x53, 0xe8, 0x74, 0xc2, 0xdb, 0x25, 0xdf, 0x8a, 0xfb, 0xfa, 0xf0, 0x14,
+ /*1880:*/ 0xf7, 0x92, 0x67, 0xbb, 0x0a, 0x5e, 0xfa, 0x53, 0x4f, 0x5f, 0xf9, 0x05, 0x7b, 0xbd, 0x02, 0x3e,
+ /*1890:*/ 0x30, 0xdf, 0x90, 0xef, 0x3d, 0x84, 0x0b, 0x71, 0x8b, 0x08, 0xc3, 0xae, 0xb7, 0xdb, 0xe1, 0x19,
+ /*18a0:*/ 0x56, 0x85, 0x65, 0x98, 0x53, 0x32, 0x4b, 0xe7, 0xd5, 0x01, 0x4f, 0x02, 0xf2, 0xa1, 0xb6, 0x61,
+ /*18b0:*/ 0xf9, 0xa2, 0xd1, 0xb0, 0xb7, 0x87, 0x21, 0x62, 0x60, 0x7a, 0x91, 0x14, 0x7a, 0x11, 0x6d, 0xb4,
+ /*18c0:*/ 0x79, 0x40, 0xa4, 0x9a, 0x6d, 0xcf, 0xe2, 0x6d, 0x8a, 0xd2, 0x7d, 0xfb, 0x2b, 0x11, 0xfa, 0x92,
+ /*18d0:*/ 0xe3, 0x6f, 0x47, 0x7f, 0xa2, 0x41, 0x3b, 0x90, 0x36, 0x68, 0x90, 0x96, 0xf3, 0xf5, 0x27, 0xeb,
+ /*18e0:*/ 0x99, 0x6b, 0x31, 0x5b, 0x94, 0x7d, 0xa6, 0x2d, 0xdf, 0xfd, 0xee, 0x2c, 0x54, 0x59, 0x1c, 0xb7,
+ /*18f0:*/ 0xa9, 0xd0, 0x9a, 0x43, 0x82, 0x05, 0x47, 0xba, 0x26, 0xe3, 0x7d, 0x98, 0xd9, 0x4e, 0xe9, 0xed,
+ /*1900:*/ 0xbb, 0x30, 0x27, 0xb0, 0xed, 0xc4, 0x95, 0xb5, 0x64, 0x98, 0x66, 0xe6, 0x44, 0x9d, 0x63, 0x3f,
+ /*1910:*/ 0xb8, 0xdd, 0x35, 0xed, 0x79, 0x9c, 0x30, 0xd0, 0x5a, 0xfc, 0x14, 0xcf, 0x6b, 0x05, 0x48, 0x5d,
+ /*1920:*/ 0x35, 0xd7, 0xd6, 0x8c, 0xce, 0xee, 0x21, 0x73, 0x01, 0xeb, 0x8a, 0x14, 0x01, 0x1c, 0xee, 0x8a,
+ /*1930:*/ 0xbc, 0x7a, 0xbb, 0xbb, 0x7b, 0x89, 0x8a, 0xfa, 0x6a, 0xf8, 0x90, 0x6f, 0x07, 0xba, 0x77, 0x7b,
+ /*1940:*/ 0x27, 0x01, 0xfd, 0x67, 0x52, 0xcf, 0xf5, 0xc2, 0xa7, 0x2d, 0x79, 0xbf, 0x50, 0x7a, 0xc9, 0x1c,
+ /*1950:*/ 0x6a, 0x6f, 0x38, 0xa1, 0x76, 0x80, 0x22, 0x01, 0xa8, 0x4e, 0x6c, 0x8d, 0x64, 0x55, 0x63, 0x89,
+ /*1960:*/ 0xf8, 0xe4, 0x59, 0x37, 0xf7, 0xae, 0x6b, 0x61, 0x98, 0x7e, 0x43, 0xdd, 0xba, 0xf0, 0x07, 0x28,
+ /*1970:*/ 0x91, 0xe7, 0x8a, 0xf7, 0xe4, 0xaa, 0x86, 0x0b, 0x26, 0x1e, 0x3c, 0x45, 0x9b, 0x84, 0xd0, 0xe0,
+ /*1980:*/ 0xcf, 0x81, 0x1b, 0x61, 0x9b, 0xef, 0xde, 0x8c, 0xc0, 0xa4, 0x83, 0xe7, 0x31, 0x18, 0xf1, 0x66,
+ /*1990:*/ 0x2d, 0x65, 0x6f, 0x2e, 0xfb, 0x60, 0x99, 0xa4, 0xbd, 0x20, 0x6b, 0x83, 0xe6, 0x2d, 0x93, 0xbc,
+ /*19a0:*/ 0x9b, 0xce, 0xa5, 0x1e, 0x9b, 0xda, 0xb4, 0x69, 0x89, 0xb9, 0x42, 0x3a, 0x1a, 0xcc, 0x13, 0x7f,
+ /*19b0:*/ 0x5e, 0xc6, 0xa2, 0x4c, 0x8a, 0x82, 0xc0, 0x19, 0x2f, 0xe0, 0xac, 0x58, 0xb4, 0xbc, 0x69, 0x2f,
+ /*19c0:*/ 0x11, 0xa2, 0x85, 0x0b, 0x72, 0x32, 0x74, 0x83, 0x11, 0x58, 0xe0, 0x7a, 0xce, 0x55, 0xda, 0x6e,
+ /*19d0:*/ 0x2f, 0xe9, 0x6c, 0x62, 0xdc, 0xbd, 0x89, 0x0d, 0xfd, 0x7a, 0x32, 0xb9, 0x28, 0x7a, 0xc2, 0xb6,
+ /*19e0:*/ 0x10, 0x67, 0xf1, 0x6a, 0xe2, 0x04, 0x17, 0x9d, 0x2d, 0xe0, 0xde, 0xc3, 0xad, 0xff, 0xb6, 0x4b,
+ /*19f0:*/ 0x11, 0x3d, 0x53, 0x21, 0x6a, 0xe6, 0x30, 0xad, 0x15, 0x7d, 0x13, 0x28, 0x3c, 0xea, 0x29, 0x32,
+ /*1a00:*/ 0xa7, 0xb6, 0x67, 0x07, 0x1f, 0x0e, 0x72, 0xe8, 0xd7, 0xcf, 0x59, 0xb5, 0x68, 0xf4, 0xb6, 0x81,
+ /*1a10:*/ 0xed, 0xf5, 0xb8, 0xab, 0xfb, 0xee, 0x6c, 0x94, 0xff, 0x03, 0xa9, 0xc8, 0x1a, 0x30, 0x9b, 0x16,
+ /*1a20:*/ 0xff, 0x9b, 0x40, 0x57, 0x70, 0x9f, 0xb9, 0xcb, 0xf6, 0x79, 0x88, 0xee, 0x3f, 0xf1, 0xa0, 0x8d,
+ /*1a30:*/ 0x67, 0x26, 0x90, 0x71, 0x84, 0x34, 0xce, 0x7b, 0xaa, 0x83, 0xd1, 0x00, 0x33, 0xfd, 0x4d, 0x86,
+ /*1a40:*/ 0x55, 0x53, 0xc0, 0x6b, 0x3a, 0x44, 0xd8, 0xdb, 0x40, 0x24, 0xb8, 0xef, 0x7d, 0x2b, 0x7d, 0x03,
+ /*1a50:*/ 0x79, 0xaf, 0x0f, 0x86, 0x21, 0x4e, 0x41, 0xc6, 0x60, 0x21, 0x8e, 0x58, 0x26, 0x1b, 0x72, 0xfe,
+ /*1a60:*/ 0x71, 0x21, 0x0e, 0xa1, 0xd6, 0xf7, 0x41, 0x50, 0x68, 0xca, 0x3f, 0x62, 0xdf, 0xd1, 0x41, 0xe1,
+ /*1a70:*/ 0xdc, 0xc2, 0x7f, 0x82, 0xd8, 0x6e, 0x3e, 0xf9, 0x30, 0xee, 0x71, 0xcd, 0x1f, 0x0f, 0x4f, 0xb3,
+ /*1a80:*/ 0x03, 0xfb, 0x20, 0x75, 0x91, 0x1a, 0xbf, 0xb0, 0xc1, 0xc4, 0x65, 0x4b, 0x65, 0x52, 0x2a, 0x13,
+ /*1a90:*/ 0xb1, 0xb1, 0xc8, 0xe1, 0x9e, 0xc5, 0x78, 0x40, 0xae, 0xf6, 0x57, 0x12, 0xc9, 0x49, 0x24, 0xee,
+ /*1aa0:*/ 0x87, 0x6b, 0xa0, 0x0c, 0x0f, 0xb1, 0xbe, 0xac, 0xcb, 0x8b, 0xe9, 0x3f, 0x1b, 0xaa, 0x79, 0x9f,
+ /*1ab0:*/ 0xc4, 0xff, 0xac, 0xf9, 0xf7, 0x53, 0xab, 0xa8, 0xf2, 0x00, 0xc0, 0xa4, 0x24, 0x22, 0x97, 0x58,
+ /*1ac0:*/ 0x0c, 0x39, 0x96, 0xe2, 0xe9, 0xcf, 0x62, 0xcb, 0x8f, 0xdb, 0xa8, 0xdd, 0x5a, 0x5c, 0xb2, 0xce,
+ /*1ad0:*/ 0xae, 0x84, 0x2a, 0x68, 0x7c, 0x38, 0x56, 0x78, 0xe1, 0xa6, 0x7c, 0x6b, 0x8b, 0x47, 0x07, 0xe4,
+ /*1ae0:*/ 0xc7, 0x54, 0x9a, 0x76, 0x34, 0xe5, 0xf5, 0x23, 0x49, 0x15, 0x90, 0x73, 0xa3, 0x0a, 0x5c, 0x4b,
+ /*1af0:*/ 0x99, 0x6f, 0x7b, 0x0f, 0x61, 0x9e, 0xf9, 0xa5, 0x95, 0x42, 0xbd, 0x19, 0xa5, 0x31, 0x08, 0xdd,
+ /*1b00:*/ 0x9a, 0x23, 0xdb, 0x2c, 0x19, 0x50, 0xbb, 0xc3, 0x3b, 0x51, 0xec, 0xd9, 0x38, 0x5b, 0x1b, 0x58,
+ /*1b10:*/ 0x79, 0xfb, 0xa2, 0x94, 0x6a, 0xe1, 0xd9, 0x03, 0x58, 0xd2, 0xb7, 0xfe, 0xc2, 0x99, 0xf4, 0x45,
+ /*1b20:*/ 0x28, 0x00, 0x11, 0x41, 0x67, 0x09, 0x1a, 0x82, 0x48, 0x11, 0x25, 0x82, 0x66, 0xd9, 0x08, 0xe4,
+ /*1b30:*/ 0xf3, 0x4f, 0xf1, 0x4c, 0x40, 0x78, 0xb7, 0x40, 0x5f, 0x16, 0xd6, 0x4d, 0x9d, 0x25, 0xcb, 0xff,
+ /*1b40:*/ 0xe1, 0xe7, 0xaf, 0x0c, 0x5b, 0x9a, 0x57, 0xf6, 0xc1, 0xd0, 0x1c, 0x20, 0x68, 0x9a, 0x51, 0x7a,
+ /*1b50:*/ 0xbd, 0xcb, 0x96, 0x21, 0x57, 0xe4, 0x70, 0x9d, 0x9c, 0xda, 0xaa, 0x89, 0x0d, 0xc2, 0x53, 0xa9,
+ /*1b60:*/ 0x6b, 0x78, 0x12, 0xeb, 0x77, 0x4d, 0x5c, 0xe4, 0x5e, 0x2b, 0x30, 0x0f, 0xb3, 0x08, 0x9f, 0x68,
+ /*1b70:*/ 0xf1, 0xb4, 0x37, 0xac, 0xed, 0x39, 0x0e, 0x59, 0xfa, 0xc4, 0xa8, 0xfa, 0xcc, 0x76, 0x77, 0xba,
+ /*1b80:*/ 0x15, 0xae, 0xbe, 0x0f, 0x89, 0xb7, 0x3c, 0xf5, 0x27, 0x2c, 0xfc, 0x05, 0xb2, 0x32, 0x40, 0x61,
+ /*1b90:*/ 0x0d, 0xdd, 0x0a, 0x8a, 0x0c, 0xa5, 0x7e, 0x2c, 0x5e, 0x50, 0x6b, 0xa1, 0x3b, 0x87, 0x23, 0xa0,
+ /*1ba0:*/ 0xa9, 0x4c, 0x46, 0x4c, 0xfb, 0xe2, 0x39, 0x3a, 0x3b, 0x43, 0x9b, 0x24, 0x8b, 0x4c, 0xae, 0x25,
+ /*1bb0:*/ 0x81, 0x72, 0x5e, 0xaf, 0xe3, 0x3f, 0x8c, 0x5b, 0x2f, 0xfd, 0x48, 0x61, 0x29, 0x9e, 0xba, 0x76,
+ /*1bc0:*/ 0x73, 0x3c, 0xeb, 0xeb, 0x30, 0x18, 0xa9, 0x89, 0x4c, 0xbc, 0x09, 0xb6, 0xd7, 0x46, 0x27, 0x76,
+ /*1bd0:*/ 0x51, 0x41, 0x52, 0x29, 0x2a, 0x73, 0x2d, 0xf0, 0x13, 0x9c, 0x00, 0x38, 0xe1, 0xe6, 0xc7, 0x9c,
+ /*1be0:*/ 0x7b, 0x07, 0xab, 0xf0, 0xf9, 0x0f, 0xc0, 0xce, 0x6a, 0xba, 0x10, 0x03, 0xfa, 0x55, 0x8b, 0x1a,
+ /*1bf0:*/ 0xfc, 0xd4, 0xdf, 0x8d, 0xf5, 0x98, 0x7e, 0xf1, 0x70, 0xff, 0x41, 0x9d, 0x66, 0xa3, 0x3a, 0x99,
+ /*1c00:*/ 0x5e, 0xe2, 0x9f, 0x29, 0x3b, 0xc8, 0xe9, 0x32, 0xb7, 0x1a, 0xb3, 0x47, 0xde, 0x42, 0x2d, 0x37,
+ /*1c10:*/ 0x2f, 0x13, 0xe6, 0x4a, 0xd8, 0x4d, 0xfc, 0x65, 0x6b, 0xaa, 0xd7, 0x58, 0xab, 0x86, 0x95, 0x88,
+ /*1c20:*/ 0x36, 0xf8, 0xf9, 0xa6, 0xd6, 0x66, 0xf3, 0xa7, 0x18, 0x62, 0x7d, 0xa3, 0x5f, 0xbe, 0xac, 0xba,
+ /*1c30:*/ 0x9f, 0x02, 0x3b, 0xa7, 0x43, 0x2a, 0xb5, 0x48, 0x70, 0x76, 0xda, 0xa2, 0x06, 0xb4, 0x67, 0x48,
+ /*1c40:*/ 0x33, 0xd9, 0x2d, 0xce, 0xd2, 0xe0, 0xd5, 0x3b, 0x81, 0xbb, 0x7a, 0x6a, 0xa9, 0xe5, 0xac, 0x82,
+ /*1c50:*/ 0x7c, 0x05, 0x7d, 0x93, 0x03, 0x15, 0xc2, 0x8f, 0x14, 0x44, 0xf9, 0xe2, 0xb2, 0x85, 0xfd, 0xe4,
+ /*1c60:*/ 0x7f, 0xaf, 0x3f, 0x36, 0x1e, 0xdc, 0x0f, 0x81, 0x29, 0x22, 0xfd, 0xb6, 0xf4, 0xa1, 0xef, 0xe2,
+ /*1c70:*/ 0x28, 0x82, 0xcb, 0x1c, 0x50, 0x4b, 0x68, 0x92, 0xc5, 0x40, 0xba, 0x8f, 0xb0, 0x13, 0x1e, 0xb7,
+ /*1c80:*/ 0xc4, 0x89, 0x78, 0x90, 0x52, 0x4a, 0x0d, 0xa9, 0x21, 0x25, 0x46, 0x65, 0x6c, 0x3f, 0x44, 0xb6,
+ /*1c90:*/ 0x6c, 0x6b, 0x91, 0xe2, 0x84, 0x75, 0x33, 0x58, 0x67, 0xf1, 0x19, 0x91, 0xd2, 0x18, 0xdb, 0x6c,
+ /*1ca0:*/ 0x80, 0x06, 0x8f, 0xb4, 0x13, 0xde, 0x16, 0x1b, 0x70, 0x8e, 0x11, 0x92, 0xfd, 0xa5, 0x38, 0xbf,
+ /*1cb0:*/ 0x3b, 0x88, 0x8a, 0xec, 0x26, 0xe7, 0x04, 0x47, 0x34, 0x63, 0xcc, 0xcb, 0x57, 0x35, 0x2d, 0xe7,
+ /*1cc0:*/ 0x77, 0x7c, 0xe3, 0x84, 0xfc, 0xdd, 0x45, 0x3b, 0x45, 0x9e, 0x7c, 0xf8, 0x78, 0x5d, 0x42, 0x09,
+ /*1cd0:*/ 0x23, 0x9c, 0xf5, 0x8e, 0x95, 0x0a, 0xac, 0x64, 0x35, 0x20, 0x78, 0xca, 0x3e, 0x2b, 0x5f, 0xd5,
+ /*1ce0:*/ 0xb0, 0x22, 0xc6, 0x3a, 0x9a, 0x6f, 0xa7, 0x57, 0xf6, 0x83, 0xb4, 0xad, 0xe9, 0xd7, 0x0f, 0xaa,
+ /*1cf0:*/ 0x93, 0x49, 0x6b, 0x04, 0xf9, 0x35, 0x16, 0x37, 0x7f, 0x82, 0xac, 0x7e, 0x87, 0x32, 0x84, 0xef,
+ /*1d00:*/ 0x1c, 0x06, 0x6a, 0xdc, 0x26, 0x23, 0xcd, 0x39, 0x3c, 0x71, 0xae, 0x7d, 0x08, 0x6d, 0x76, 0xa4,
+ /*1d10:*/ 0xf0, 0x68, 0xd6, 0x6c, 0xec, 0xc4, 0x10, 0x6c, 0xaf, 0x8e, 0x50, 0x2c, 0xd8, 0x06, 0xcd, 0x19,
+ /*1d20:*/ 0x05, 0xf8, 0x16, 0x3a, 0x28, 0xb9, 0x2e, 0x00, 0x0b, 0xf9, 0xa9, 0x1b, 0x5a, 0xa5, 0x34, 0x9c,
+ /*1d30:*/ 0xbe, 0x65, 0xb5, 0xe6, 0xb4, 0xc1, 0x8a, 0xfe, 0x1c, 0x24, 0x0f, 0x7e, 0x91, 0x8c, 0x65, 0x3d,
+ /*1d40:*/ 0xaa, 0x26, 0x13, 0x91, 0x8b, 0xee, 0xd9, 0x0c, 0xdc, 0xc7, 0x08, 0x21, 0x8c, 0xc4, 0xb7, 0x86,
+ /*1d50:*/ 0x45, 0xf7, 0x11, 0x35, 0x9d, 0x76, 0x38, 0x81, 0x6c, 0xc5, 0x49, 0x87, 0xe2, 0xe9, 0x48, 0x5c,
+ /*1d60:*/ 0xf9, 0x15, 0x30, 0x10, 0x2e, 0xee, 0x6e, 0x4d, 0x9b, 0xd3, 0xb8, 0x10, 0xff, 0xdd, 0x5d, 0xe1,
+ /*1d70:*/ 0x2c, 0x38, 0xfe, 0x0f, 0xae, 0x14, 0xb9, 0x21, 0x74, 0x6a, 0xc0, 0xf8, 0x29, 0x2e, 0xa1, 0xb0,
+ /*1d80:*/ 0xf9, 0x3c, 0x72, 0x46, 0x1b, 0xe7, 0xa2, 0xef, 0x18, 0x0b, 0xe3, 0xc7, 0x6b, 0x60, 0x6a, 0x7f,
+ /*1d90:*/ 0x60, 0x36, 0xa5, 0xa9, 0x3b, 0x13, 0x97, 0xd4, 0xee, 0x5a, 0x23, 0xd0, 0xc9, 0x2d, 0x3a, 0x1f,
+ /*1da0:*/ 0x84, 0x86, 0x42, 0xc5, 0x94, 0xf0, 0x6f, 0x9e, 0xd7, 0xa9, 0xa0, 0x63, 0xd0, 0xc2, 0xa2, 0x57,
+ /*1db0:*/ 0x3a, 0xe5, 0x14, 0xc9, 0xce, 0x7a, 0x77, 0xfc, 0x72, 0x99, 0xf7, 0x02, 0x92, 0xdb, 0x95, 0xf3,
+ /*1dc0:*/ 0x66, 0x17, 0xb0, 0xe1, 0x83, 0xe3, 0x13, 0x55, 0xe4, 0xf2, 0xb7, 0x45, 0x35, 0x34, 0x5e, 0x3b,
+ /*1dd0:*/ 0x1d, 0x68, 0x0a, 0x38, 0x94, 0x43, 0x7b, 0xc0, 0x21, 0x77, 0x3e, 0x11, 0x51, 0xba, 0x1b, 0x0c,
+ /*1de0:*/ 0x1f, 0x0b, 0x28, 0x23, 0xca, 0x79, 0x5b, 0x3c, 0xc8, 0x4b, 0x84, 0xd8, 0xa0, 0xfc, 0x9d, 0x7f,
+ /*1df0:*/ 0xad, 0xce, 0x6a, 0xe4, 0x7b, 0xbd, 0xbc, 0xbe, 0x9c, 0xef, 0x2c, 0x5e, 0x5c, 0x64, 0x1e, 0x5d,
+ /*1e00:*/ 0x97, 0x83, 0x20, 0x63, 0x5b, 0x4d, 0x18, 0xdd, 0xe3, 0x08, 0x7a, 0xfd, 0x7a, 0xb0, 0xb4, 0x89,
+ /*1e10:*/ 0xfe, 0x5d, 0x59, 0x5a, 0x50, 0x91, 0x6a, 0xe3, 0xd8, 0xe4, 0x4c, 0x74, 0x06, 0x1e, 0xb8, 0xcb,
+ /*1e20:*/ 0x27, 0x0e, 0x57, 0x76, 0x4c, 0x31, 0x76, 0x86, 0xd4, 0x37, 0x93, 0x6c, 0x13, 0x45, 0x6d, 0x79,
+ /*1e30:*/ 0xef, 0xab, 0xb6, 0x07, 0x7b, 0x07, 0xc0, 0x26, 0xa1, 0x61, 0x40, 0xa0, 0x67, 0x36, 0xfc, 0xb5,
+ /*1e40:*/ 0x8b, 0x75, 0x02, 0xd8, 0x4d, 0x60, 0x40, 0xeb, 0xf4, 0x02, 0xb2, 0xe3, 0x5e, 0x22, 0x13, 0xf5,
+ /*1e50:*/ 0xb4, 0x71, 0xb9, 0x64, 0x3a, 0x71, 0xba, 0xdb, 0x4e, 0xbe, 0x8e, 0x35, 0x18, 0xe1, 0xf3, 0xf1,
+ /*1e60:*/ 0xde, 0xd9, 0xba, 0x88, 0x1e, 0x08, 0xd7, 0x79, 0x54, 0xdd, 0x1c, 0xda, 0xa3, 0xcd, 0x18, 0x7b,
+ /*1e70:*/ 0x84, 0x17, 0xc7, 0x0a, 0x17, 0x9f, 0x14, 0x58, 0x6c, 0xce, 0x7f, 0x1b, 0x7c, 0x0b, 0xcd, 0x82,
+ /*1e80:*/ 0xee, 0x1a, 0x9f, 0x24, 0x94, 0x01, 0x76, 0xbe, 0x68, 0xb5, 0xc5, 0x9e, 0x6f, 0x3c, 0x90, 0x02,
+ /*1e90:*/ 0x2b, 0x58, 0xc3, 0x2e, 0x9d, 0xc0, 0x4e, 0xa2, 0x78, 0xf2, 0x2d, 0x8a, 0x07, 0x82, 0xbe, 0xd4,
+ /*1ea0:*/ 0xbf, 0x4a, 0x08, 0xa3, 0xa5, 0x89, 0xe0, 0x3f, 0x28, 0x0b, 0xec, 0xac, 0x77, 0xdd, 0xac, 0x52,
+ /*1eb0:*/ 0x7a, 0x58, 0x65, 0x59, 0x48, 0x03, 0xf9, 0x27, 0xd1, 0xa9, 0x7b, 0x37, 0xbe, 0x4c, 0x6c, 0x6b,
+ /*1ec0:*/ 0x73, 0x15, 0x74, 0xfc, 0x83, 0x1e, 0xbd, 0x67, 0x20, 0x14, 0xe9, 0xad, 0x93, 0x13, 0xd5, 0x45,
+ /*1ed0:*/ 0x2a, 0xdc, 0x6c, 0xa3, 0x04, 0xe7, 0x5f, 0x58, 0xea, 0x95, 0x25, 0x25, 0xe8, 0xb5, 0x32, 0x26,
+ /*1ee0:*/ 0xd8, 0xa1, 0x16, 0x0c, 0xbe, 0x63, 0xee, 0xc3, 0x52, 0xba, 0x01, 0xbe, 0xfd, 0xc1, 0x9b, 0x5c,
+ /*1ef0:*/ 0xf4, 0x6d, 0x1c, 0x08, 0x0a, 0xd9, 0xd9, 0xa6, 0xd2, 0x24, 0x05, 0x7c, 0x05, 0x8c, 0x4a, 0x7a,
+ /*1f00:*/ 0xfe, 0x35, 0x11, 0x82, 0xb6, 0x94, 0xe1, 0x3e, 0xc3, 0xd1, 0xad, 0x88, 0x3c, 0x2f, 0xb2, 0x2c,
+ /*1f10:*/ 0x75, 0xef, 0x37, 0xd8, 0x33, 0x9a, 0xf6, 0x65, 0x8f, 0x58, 0xa7, 0x64, 0x52, 0xb8, 0x95, 0x19,
+ /*1f20:*/ 0xe6, 0xee, 0x39, 0x03, 0xdd, 0x8d, 0x33, 0x47, 0xb5, 0xb7, 0x4b, 0x6f, 0x55, 0xb6, 0x8e, 0xca,
+ /*1f30:*/ 0x3d, 0x6f, 0xc7, 0x39, 0x1f, 0x56, 0xa1, 0xa8, 0xef, 0x0b, 0xcb, 0x52, 0xea, 0x2d, 0x1f, 0x11,
+ /*1f40:*/ 0xee, 0x6b, 0x6a, 0x26, 0x84, 0xce, 0x02, 0x5a, 0x10, 0x2d, 0x6f, 0xd6, 0x8f, 0xf9, 0x68, 0xd8,
+ /*1f50:*/ 0x0a, 0x67, 0xeb, 0x09, 0x7c, 0xd0, 0xa8, 0xfd, 0x47, 0x40, 0x49, 0x6f, 0xb1, 0xcd, 0x01, 0xaa,
+ /*1f60:*/ 0x2d, 0x85, 0xb8, 0xc7, 0x81, 0x3e, 0xc7, 0xa9, 0xbe, 0xc5, 0xc6, 0x20, 0xf2, 0x4d, 0x61, 0xff,
+ /*1f70:*/ 0x64, 0x45, 0xed, 0xa0, 0xa0, 0xa8, 0xbb, 0xb4, 0x78, 0x44, 0x1c, 0x7f, 0xe8, 0x87, 0x7b, 0xc1,
+ /*1f80:*/ 0x29, 0xc2, 0x71, 0x0d, 0x9a, 0xa7, 0x9c, 0xc4, 0x03, 0x1b, 0x6c, 0x25, 0x2f, 0x9f, 0xc4, 0xd1,
+ /*1f90:*/ 0x67, 0x19, 0x81, 0x3f, 0x71, 0x94, 0xcd, 0xed, 0x84, 0x9d, 0x0f, 0x42, 0xae, 0x38, 0xdf, 0xbd,
+ /*1fa0:*/ 0xc3, 0x92, 0x6b, 0xa8, 0x8b, 0x18, 0x45, 0xe2, 0xf3, 0x1c, 0x7c, 0xe6, 0x06, 0xeb, 0x41, 0x48,
+ /*1fb0:*/ 0xe1, 0x44, 0x79, 0x28, 0xa2, 0xfe, 0x46, 0x85, 0x9d, 0x1a, 0x83, 0x1d, 0x9c, 0xe3, 0xe2, 0xc9,
+ /*1fc0:*/ 0x33, 0x68, 0xa8, 0xa9, 0x07, 0x9c, 0x7f, 0x71, 0xe7, 0xf0, 0x4e, 0x21, 0x90, 0x80, 0xc1, 0x3e,
+ /*1fd0:*/ 0x1f, 0xae, 0xdd, 0xb8, 0x5a, 0x17, 0x86, 0x9a, 0xdf, 0xec, 0xde, 0xaa, 0x48, 0x99, 0x4b, 0xd9,
+ /*1fe0:*/ 0xa8, 0x9b, 0xbc, 0x34, 0x65, 0x30, 0x1a, 0x72, 0xf4, 0x69, 0xee, 0x81, 0x06, 0x86, 0xbe, 0x65,
+ /*1ff0:*/ 0x74, 0x22, 0xdc, 0x45, 0x61, 0x4d, 0x11, 0x16, 0x94, 0xc3, 0xaf, 0x31, 0xf2, 0x2e, 0x7e, 0x0a,
+ /*2000:*/ 0xe9, 0xcc, 0x15, 0x55, 0xdd, 0x5c, 0x4b, 0xc8, 0xe6, 0x54, 0x65, 0x71, 0x96, 0xb6, 0x05, 0xa1,
+ /*2010:*/ 0xf6, 0x12, 0xf5, 0x2e, 0xbd, 0x04, 0x7d, 0xc9, 0xb6, 0xe1, 0x40, 0x64, 0x35, 0x33, 0x2e, 0x1e,
+ /*2020:*/ 0xfd, 0xcb, 0x48, 0x03, 0xc1, 0x90, 0x27, 0x65, 0x2c, 0xa5, 0x3b, 0xba, 0x99, 0x89, 0x1d, 0x63,
+ /*2030:*/ 0x27, 0x31, 0xa4, 0x45, 0x7a, 0x5d, 0xbb, 0x67, 0xea, 0x3e, 0x3d, 0x03, 0x71, 0x8b, 0xda, 0x94,
+ /*2040:*/ 0xc6, 0x09, 0xb6, 0xfb, 0x87, 0x2e, 0x50, 0x67, 0x04, 0x3d, 0xf0, 0x54, 0xd8, 0xcb, 0xee, 0x74,
+ /*2050:*/ 0x59, 0x15, 0x9a, 0x40, 0xb2, 0xf1, 0xae, 0xa2, 0x9c, 0x76, 0x6b, 0x2b, 0x70, 0xc8, 0xe9, 0x20,
+ /*2060:*/ 0x95, 0x16, 0xb8, 0xb2, 0x7e, 0x43, 0xd7, 0x5b, 0x3d, 0xce, 0x82, 0x22, 0x61, 0xff, 0x64, 0x14,
+ /*2070:*/ 0xcc, 0x7e, 0xf8, 0x73, 0x5e, 0x72, 0xf3, 0xfc, 0xea, 0xbf, 0x44, 0xc4, 0x1b, 0x25, 0xd1, 0xbd,
+ /*2080:*/ 0x95, 0x3a, 0xb0, 0x1b, 0x1f, 0xfa, 0x7b, 0xbe, 0x52, 0x80, 0x21, 0xb6, 0x22, 0x0b, 0x9c, 0x38,
+ /*2090:*/ 0x3d, 0xbb, 0xae, 0x2f, 0xd8, 0xaf, 0x45, 0x00, 0x47, 0x44, 0xcd, 0x6a, 0x66, 0x8c, 0xc5, 0x35,
+ /*20a0:*/ 0xfd, 0x6d, 0xe4, 0xf5, 0xfa, 0xfa, 0x00, 0xff, 0x96, 0xdb, 0x91, 0xad, 0x00, 0x05, 0xbe, 0x99,
+ /*20b0:*/ 0xa0, 0x15, 0x4d, 0xb6, 0xb5, 0x26, 0xc4, 0x82, 0xa9, 0xd4, 0xbc, 0x2f, 0xe1, 0x85, 0x18, 0xd0,
+ /*20c0:*/ 0xa7, 0xdc, 0xbe, 0x53, 0x84, 0xac, 0x2a, 0xc3, 0xf9, 0x8c, 0x01, 0x6e, 0xdb, 0x3e, 0x7a, 0xf4,
+ /*20d0:*/ 0x0b, 0xf3, 0x82, 0x34, 0x4d, 0x8a, 0x67, 0x0a, 0x68, 0x5c, 0x87, 0xd5, 0x12, 0x11, 0xf7, 0xd0,
+ /*20e0:*/ 0xf2, 0xd7, 0x3c, 0x2c, 0x7a, 0xf6, 0xee, 0x3a, 0x7f, 0xa3, 0x66, 0xb4, 0x76, 0x5e, 0x2b, 0x14,
+ /*20f0:*/ 0x17, 0xdc, 0x28, 0x89, 0xa4, 0xba, 0x8e, 0x66, 0x82, 0x18, 0xfe, 0x04, 0xcc, 0x44, 0xf8, 0xd9,
+ /*2100:*/ 0x76, 0x30, 0x30, 0xad, 0x4c, 0xa0, 0x5f, 0x8a, 0x7b, 0x59, 0x07, 0xb9, 0x1f, 0xdc, 0x88, 0xac,
+ /*2110:*/ 0xbf, 0xcb, 0x8d, 0x64, 0x34, 0x01, 0xd6, 0xb1, 0x03, 0xd7, 0xa8, 0x0b, 0x2f, 0xee, 0x98, 0x8d,
+ /*2120:*/ 0x18, 0x9f, 0x19, 0xf4, 0xc3, 0x9c, 0x44, 0x9a, 0x2b, 0xdf, 0x88, 0x79, 0xad, 0x0f, 0x13, 0x3e,
+ /*2130:*/ 0xd7, 0xb9, 0x5c, 0x50, 0xed, 0x0c, 0xda, 0xb0, 0xb6, 0x6e, 0xdb, 0x6d, 0x03, 0x31, 0xc6, 0x97,
+ /*2140:*/ 0xac, 0x8f, 0x9c, 0x2d, 0x16, 0x88, 0x72, 0x49, 0x82, 0x99, 0xc0, 0x71, 0x59, 0x27, 0xb6, 0x39,
+ /*2150:*/ 0xc8, 0x30, 0x56, 0x8e, 0x8f, 0xa2, 0xa5, 0xbe, 0xc4, 0x01, 0x1e, 0x12, 0x42, 0xab, 0xd1, 0x9c,
+ /*2160:*/ 0x4c, 0x34, 0xef, 0x87, 0x36, 0xf2, 0xce, 0xde, 0xf5, 0x23, 0x71, 0x12, 0x7e, 0xb6, 0x8e, 0x25,
+ /*2170:*/ 0x82, 0x7d, 0xd6, 0xac, 0x07, 0xbb, 0x01, 0xfc, 0x9d, 0x14, 0xdf, 0x24, 0x38, 0x7c, 0xd8, 0x42,
+ /*2180:*/ 0x3a, 0xf9, 0xb1, 0xfd, 0x66, 0x9f, 0x7c, 0x47, 0x9d, 0x57, 0x3b, 0x75, 0x44, 0x63, 0xe8, 0x4c,
+ /*2190:*/ 0x7c, 0xf2, 0xfc, 0xec, 0x43, 0x83, 0x87, 0xd3, 0x13, 0x73, 0x33, 0x98, 0x7d, 0x33, 0x0b, 0x4b,
+ /*21a0:*/ 0x44, 0xb2, 0xc1, 0x9c, 0xb3, 0x03, 0x67, 0x80, 0xef, 0x95, 0x06, 0xe0, 0xbb, 0xe1, 0xe5, 0x33,
+ /*21b0:*/ 0x21, 0x73, 0x1f, 0x91, 0xf1, 0x14, 0xdc, 0x9e, 0x53, 0xe3, 0x14, 0x85, 0x43, 0x1e, 0xaa, 0x5d,
+ /*21c0:*/ 0x08, 0x7b, 0x28, 0x8d, 0x43, 0x27, 0xec, 0x2d, 0xab, 0xe7, 0xe2, 0x09, 0xc9, 0x15, 0x1a, 0x87,
+ /*21d0:*/ 0x58, 0xa6, 0xfe, 0x35, 0xd0, 0xd9, 0x87, 0x39, 0x7e, 0xae, 0xc2, 0x91, 0x0a, 0x0f, 0xf3, 0x48,
+ /*21e0:*/ 0xe2, 0x5d, 0x4c, 0x1a, 0x56, 0xbb, 0x74, 0x8e, 0x9f, 0x25, 0xf0, 0x90, 0x46, 0xcf, 0x50, 0x35,
+ /*21f0:*/ 0x7a, 0x59, 0xe1, 0x6a, 0xd4, 0x24, 0x97, 0x4a, 0xca, 0xdb, 0xbd, 0x83, 0xd9, 0xa9, 0x6a, 0xae,
+ /*2200:*/ 0xea, 0x46, 0x97, 0x14, 0xdd, 0xaf, 0x46, 0x79, 0x98, 0xb7, 0x20, 0xf2, 0x3e, 0x98, 0xd8, 0x6c,
+ /*2210:*/ 0xc5, 0x57, 0x5d, 0xed, 0x08, 0xda, 0x0f, 0x98, 0x06, 0xd8, 0xdc, 0x2c, 0x28, 0x8d, 0xc5, 0x21,
+ /*2220:*/ 0x33, 0xc1, 0xc4, 0x2d, 0x1e, 0x85, 0x7b, 0x82, 0x12, 0x74, 0x78, 0x2b, 0xf5, 0x0b, 0x77, 0xeb,
+ /*2230:*/ 0xc8, 0x6f, 0x42, 0x83, 0xe2, 0x19, 0x25, 0x6b, 0xff, 0x92, 0xb7, 0x63, 0x82, 0xae, 0xc9, 0x0d,
+ /*2240:*/ 0xa0, 0xc3, 0x64, 0x6f, 0x13, 0x8c, 0xf2, 0x8a, 0xa2, 0xb6, 0x57, 0x99, 0x2e, 0x92, 0xa6, 0x3c,
+ /*2250:*/ 0xa1, 0x86, 0x05, 0x76, 0x4f, 0x55, 0x5d, 0x2b, 0x3c, 0x28, 0x30, 0x00, 0x51, 0x5e, 0xa1, 0x90,
+ /*2260:*/ 0x35, 0x0b, 0x78, 0xb6, 0x04, 0x82, 0xca, 0xe0, 0x3e, 0xb9, 0xe0, 0x12, 0x19, 0x62, 0xfd, 0x05,
+ /*2270:*/ 0x81, 0xd7, 0x78, 0xb9, 0x23, 0x14, 0xe3, 0xb3, 0x4d, 0xac, 0x97, 0x80, 0xac, 0x4c, 0x98, 0xea,
+ /*2280:*/ 0x60, 0x89, 0x62, 0x8b, 0xc0, 0xd2, 0x37, 0x5c, 0x5a, 0x63, 0xcf, 0x7a, 0x55, 0x3a, 0x67, 0xeb,
+ /*2290:*/ 0xec, 0xcb, 0xd6, 0xf7, 0x39, 0x33, 0xf0, 0x6e, 0x4c, 0x8c, 0x0f, 0x75, 0x60, 0x5a, 0x5f, 0x08,
+ /*22a0:*/ 0x52, 0x93, 0x86, 0x50, 0xf3, 0xf1, 0x99, 0x9f, 0x3a, 0x02, 0x9e, 0xe8, 0xca, 0xe7, 0x95, 0x47,
+ /*22b0:*/ 0xb0, 0x37, 0x4e, 0xa1, 0x53, 0xc8, 0xaf, 0xb6, 0x6e, 0x55, 0xdf, 0xf8, 0x7d, 0xf2, 0xe7, 0x36,
+ /*22c0:*/ 0xc2, 0xf8, 0xbc, 0x54, 0xe7, 0x01, 0x13, 0x6b, 0x3f, 0xcc, 0xd0, 0x84, 0xe4, 0xac, 0xd8, 0x0a,
+ /*22d0:*/ 0x26, 0x2f, 0x82, 0xe1, 0xce, 0x3d, 0x60, 0xe4, 0xb9, 0xb2, 0xad, 0xd9, 0x9c, 0x4c, 0x2f, 0xa3,
+ /*22e0:*/ 0x2b, 0x37, 0x8f, 0x0d, 0x65, 0x38, 0xc5, 0x76, 0xca, 0x97, 0xa1, 0x64, 0xca, 0x3c, 0x14, 0xb6,
+ /*22f0:*/ 0xb3, 0x68, 0xaf, 0xb2, 0x47, 0x66, 0x4b, 0x85, 0x21, 0x1e, 0xa2, 0x60, 0xd7, 0x85, 0x8a, 0x9b,
+ /*2300:*/ 0x35, 0x0e, 0xd8, 0x20, 0x12, 0x8b, 0xca, 0x25, 0x17, 0xc4, 0x57, 0xb8, 0x6a, 0x6f, 0xac, 0xa9,
+ /*2310:*/ 0xf4, 0xe9, 0x3c, 0xc1, 0x05, 0x4a, 0x8c, 0x5c, 0xba, 0xbb, 0x82, 0xe7, 0xa7, 0xd0, 0x58, 0x44,
+ /*2320:*/ 0x13, 0x86, 0xac, 0x3c, 0x63, 0x9b, 0xa8, 0xb5, 0x56, 0x13, 0x55, 0xce, 0xc3, 0xd3, 0x29, 0xec,
+ /*2330:*/ 0x96, 0x27, 0x17, 0xde, 0x8a, 0xec, 0x31, 0x56, 0x6e, 0x3b, 0xfa, 0x4e, 0xa9, 0x51, 0x9c, 0x1c,
+ /*2340:*/ 0x67, 0x70, 0xbb, 0xc7, 0x50, 0x2d, 0xfb, 0xc9, 0x21, 0x64, 0x4c, 0xdd, 0xe7, 0xd2, 0x57, 0xfe,
+ /*2350:*/ 0x09, 0x12, 0x0d, 0xe7, 0x5b, 0x0f, 0x81, 0x21, 0x13, 0x44, 0x2f, 0x57, 0xab, 0xe8, 0xac, 0xf6,
+ /*2360:*/ 0x02, 0x23, 0x3d, 0xa1, 0x4f, 0xf5, 0x54, 0x20, 0xe2, 0x82, 0x4d, 0xf4, 0x22, 0x15, 0xc5, 0x70,
+ /*2370:*/ 0xf7, 0x9d, 0xd7, 0x3b, 0xb5, 0x30, 0x82, 0x94, 0x47, 0x26, 0xba, 0xb1, 0x15, 0xe6, 0x7c, 0xba,
+ /*2380:*/ 0xb0, 0xcd, 0xd2, 0xe6, 0x69, 0x52, 0x35, 0x0b, 0x77, 0x78, 0xd2, 0x65, 0x7c, 0xa3, 0xba, 0x56,
+ /*2390:*/ 0x61, 0xa0, 0xb1, 0x93, 0x83, 0xa1, 0x28, 0x23, 0x37, 0xb5, 0x1f, 0x56, 0x64, 0xdc, 0x66, 0x02,
+ /*23a0:*/ 0x22, 0x2d, 0xa7, 0x14, 0x77, 0x3e, 0xc0, 0xdb, 0x5c, 0x84, 0x63, 0x0f, 0xea, 0x37, 0x36, 0x34,
+ /*23b0:*/ 0xab, 0xab, 0x99, 0x5b, 0x81, 0x37, 0x22, 0xa5, 0x94, 0xe5, 0xf2, 0x79, 0x2f, 0x45, 0xc7, 0xc9,
+ /*23c0:*/ 0xa7, 0xfa, 0x6d, 0xbe, 0x02, 0x99, 0x2e, 0xeb, 0x6c, 0xc8, 0xc3, 0x24, 0x48, 0xbc, 0x9b, 0x4e,
+ /*23d0:*/ 0x13, 0x05, 0xfe, 0x9f, 0x67, 0xe7, 0x62, 0xc3, 0x74, 0x6d, 0x24, 0xf9, 0x42, 0x71, 0x77, 0x85,
+ /*23e0:*/ 0x4f, 0xb4, 0xba, 0x77, 0xbc, 0xdc, 0x49, 0x94, 0x73, 0x24, 0xe1, 0x62, 0xe1, 0xee, 0x8f, 0xd1,
+ /*23f0:*/ 0xa1, 0x7a, 0x72, 0x40, 0xba, 0x5e, 0x8c, 0x60, 0x31, 0x6e, 0x5d, 0x71, 0x15, 0x42, 0xf9, 0x70,
+ /*2400:*/ 0x61, 0x88, 0x08, 0x72, 0xa7, 0x03, 0x92, 0x3d, 0xc0, 0x0f, 0xed, 0x11, 0xf9, 0x32, 0xbe, 0x42,
+ /*2410:*/ 0x03, 0xb3, 0xb9, 0x15, 0xe1, 0x50, 0x00, 0xcf, 0xcd, 0x19, 0x19, 0x82, 0x32, 0x39, 0x43, 0x1a,
+ /*2420:*/ 0x54, 0xbd, 0xf4, 0xd8, 0x47, 0xe1, 0x01, 0x7a, 0xf5, 0xdb, 0x6f, 0xae, 0xad, 0xd4, 0x52, 0x6a,
+ /*2430:*/ 0xe0, 0x98, 0xa8, 0x8e, 0x1b, 0x1c, 0x54, 0x75, 0x6f, 0x71, 0x53, 0xbd, 0xea, 0x26, 0x78, 0x50,
+ /*2440:*/ 0x7b, 0x10, 0xe5, 0x5b, 0x56, 0xe4, 0xd8, 0x47, 0x20, 0xf8, 0x39, 0xb5, 0x29, 0xab, 0x99, 0x66,
+ /*2450:*/ 0xe9, 0xc9, 0xa2, 0x30, 0x8e, 0x14, 0xfc, 0x2c, 0x14, 0xdc, 0xba, 0xc9, 0x8a, 0xa1, 0x06, 0xab,
+ /*2460:*/ 0xfd, 0xc8, 0x93, 0x52, 0x26, 0x44, 0xf6, 0x0d, 0xc9, 0x46, 0x8a, 0x4e, 0x0b, 0x96, 0x98, 0x4d,
+ /*2470:*/ 0xf3, 0x71, 0x8f, 0xdf, 0x02, 0x2a, 0xa6, 0x8b, 0xe7, 0x6d, 0x6c, 0x80, 0x18, 0x21, 0x3c, 0x7c,
+ /*2480:*/ 0x6f, 0xc0, 0xb6, 0xea, 0x5d, 0x78, 0xb5, 0x46, 0xf9, 0x27, 0xfa, 0x4f, 0xd3, 0xbe, 0x83, 0xe2,
+ /*2490:*/ 0xaa, 0x26, 0xee, 0x71, 0x86, 0x5d, 0xf1, 0x05, 0x15, 0x97, 0x98, 0x0a, 0xdd, 0xa3, 0x67, 0x93,
+ /*24a0:*/ 0x50, 0xc1, 0x1a, 0xa7, 0xd1, 0xa0, 0xcd, 0xa4, 0xfe, 0xfa, 0x5a, 0x0e, 0x34, 0x64, 0x4c, 0x00,
+ /*24b0:*/ 0x41, 0xfc, 0x6e, 0x8c, 0x65, 0x60, 0xa5, 0xe9, 0xea, 0xc1, 0xd2, 0xed, 0x27, 0xd1, 0x3c, 0x87,
+ /*24c0:*/ 0xbb, 0xdd, 0xc8, 0xfa, 0x10, 0xa4, 0x90, 0x68, 0x4d, 0x8c, 0x9f, 0x3d, 0x47, 0x41, 0x1e, 0x38,
+ /*24d0:*/ 0x55, 0x7a, 0x02, 0xb5, 0xfc, 0xea, 0xcc, 0x33, 0x15, 0x62, 0xa3, 0x0c, 0x16, 0x39, 0x3a, 0x1d,
+ /*24e0:*/ 0xfd, 0x6d, 0x89, 0xb2, 0x93, 0x18, 0xb1, 0xfb, 0x74, 0x2b, 0x58, 0x6e, 0x2e, 0xa3, 0x0a, 0xfc,
+ /*24f0:*/ 0xed, 0x5e, 0xc9, 0xfc, 0xda, 0xdc, 0x61, 0xf1, 0x1b, 0xdc, 0x8b, 0xd6, 0x19, 0x3d, 0x3f, 0x68,
+ /*2500:*/ 0x90, 0x83, 0x19, 0x79, 0xe7, 0xfe, 0x11, 0x14, 0xf7, 0xe7, 0x3d, 0x94, 0x08, 0x60, 0xbd, 0xaa,
+ /*2510:*/ 0xdd, 0x87, 0xd0, 0xf4, 0xd2, 0xf5, 0xe4, 0x90, 0xa8, 0x73, 0xae, 0xb6, 0xb3, 0x8a, 0xc1, 0x36,
+ /*2520:*/ 0xa1, 0x1a, 0x03, 0x7c, 0xbe, 0x9d, 0xcb, 0xbc, 0x3a, 0x0f, 0x16, 0x54, 0xdb, 0xd6, 0xb4, 0x84,
+ /*2530:*/ 0x79, 0xe3, 0x95, 0xee, 0x5a, 0x65, 0x88, 0x1a, 0x68, 0x82, 0xc1, 0x32, 0x47, 0x94, 0x4a, 0x8b,
+ /*2540:*/ 0xb8, 0x1b, 0xa4, 0x77, 0x49, 0x65, 0x51, 0xbb, 0xbd, 0x0c, 0xd2, 0x7b, 0xbd, 0xff, 0xd9, 0x72,
+ /*2550:*/ 0x2e, 0x37, 0xc2, 0xc0, 0xf0, 0x03, 0xc7, 0x13, 0x46, 0xef, 0x7b, 0xa1, 0xf1, 0xa5, 0xbd, 0x1f,
+ /*2560:*/ 0x0e, 0x2f, 0x4e, 0x20, 0x51, 0xc7, 0x54, 0x57, 0x84, 0x78, 0xac, 0x7b, 0xc9, 0xe1, 0x8d, 0x66,
+ /*2570:*/ 0x51, 0x12, 0x79, 0x7c, 0x9c, 0x3d, 0xe2, 0xf3, 0x8e, 0x6b, 0x77, 0x84, 0x47, 0x14, 0x4d, 0x87,
+ /*2580:*/ 0xac, 0xa0, 0x9a, 0x5f, 0xd7, 0x4f, 0x18, 0x44, 0x8e, 0x96, 0x6f, 0xf4, 0xf0, 0x45, 0x73, 0x36,
+ /*2590:*/ 0x34, 0xa5, 0xaa, 0x24, 0xec, 0xde, 0x68, 0xa3, 0xda, 0x9e, 0xfc, 0x19, 0xba, 0x0e, 0x31, 0x80,
+ /*25a0:*/ 0x20, 0xad, 0x73, 0x0c, 0x35, 0x2d, 0x5f, 0x50, 0x41, 0x58, 0x02, 0xb6, 0x4c, 0xeb, 0xcf, 0xa1,
+ /*25b0:*/ 0x6e, 0x54, 0x66, 0xf9, 0xfb, 0xfa, 0x73, 0x48, 0x53, 0x9d, 0xbc, 0x7b, 0xe4, 0x6e, 0xad, 0xa7,
+ /*25c0:*/ 0x68, 0x6c, 0x3a, 0xed, 0xd9, 0x01, 0x49, 0xbe, 0xe8, 0x03, 0x36, 0xb6, 0x06, 0x2f, 0xfc, 0xfa,
+ /*25d0:*/ 0x5c, 0xd1, 0xe2, 0x4d, 0x62, 0xdc, 0x1c, 0xb8, 0x9b, 0xfc, 0x6e, 0x26, 0x3c, 0x38, 0xc3, 0x3d,
+ /*25e0:*/ 0xe0, 0x52, 0x61, 0x10, 0x34, 0x97, 0x15, 0x3f, 0xa9, 0xdc, 0xc2, 0xad, 0x32, 0xf7, 0x3d, 0x70,
+ /*25f0:*/ 0xe7, 0xf1, 0x2e, 0xe8, 0x1e, 0xbd, 0x8e, 0x90, 0xfb, 0x22, 0x73, 0xde, 0xe7, 0xb8, 0x9c, 0xce,
+ /*2600:*/ 0x9b, 0x89, 0xd3, 0x51, 0xfd, 0xe9, 0x07, 0xbe, 0x32, 0x14, 0x04, 0x22, 0xf8, 0x73, 0x75, 0x39,
+ /*2610:*/ 0x6d, 0x77, 0x21, 0x58, 0x5e, 0x64, 0x98, 0x36, 0x67, 0xc4, 0xed, 0x70, 0x25, 0xf7, 0x79, 0x12,
+ /*2620:*/ 0x53, 0xa8, 0xff, 0x59, 0x0b, 0xb7, 0xe0, 0x78, 0x35, 0xe5, 0x47, 0x70, 0xd9, 0xc5, 0x13, 0xe7,
+ /*2630:*/ 0xda, 0xa9, 0x09, 0xc9, 0x17, 0x68, 0x58, 0xb8, 0xbc, 0xa3, 0xf3, 0xf6, 0x02, 0xda, 0x35, 0x93,
+ /*2640:*/ 0x7f, 0xf2, 0x4e, 0x5f, 0x2f, 0xf2, 0x30, 0xca, 0xce, 0x23, 0xb3, 0x13, 0xff, 0xa3, 0xd6, 0x76,
+ /*2650:*/ 0xf8, 0xd5, 0xb8, 0xad, 0x52, 0xe3, 0x55, 0x15, 0x6e, 0x3b, 0x61, 0x5e, 0x25, 0x97, 0xda, 0x62,
+ /*2660:*/ 0xe6, 0x5a, 0x1a, 0xc3, 0x2e, 0x5d, 0xcd, 0xb9, 0x41, 0xe3, 0x72, 0x0b, 0x12, 0x94, 0x95, 0x08,
+ /*2670:*/ 0x06, 0x86, 0x45, 0xf9, 0x38, 0x8d, 0x41, 0xf6, 0x3e, 0x84, 0x6d, 0x06, 0xfb, 0x41, 0x55, 0x0d,
+ /*2680:*/ 0x8e, 0x31, 0x8d, 0x8d, 0x7c, 0x9b, 0x1e, 0x54, 0x5a, 0xac, 0xe1, 0x3e, 0xc0, 0x03, 0x36, 0x23,
+ /*2690:*/ 0x81, 0x13, 0xe7, 0xcc, 0x1b, 0xc3, 0x9c, 0x6a, 0xc1, 0xfc, 0xe9, 0x9c, 0x20, 0xa0, 0x4a, 0x84,
+ /*26a0:*/ 0x0f, 0x17, 0xcc, 0xf1, 0xb6, 0xcc, 0xf9, 0x5e, 0x52, 0x0a, 0x70, 0x03, 0x24, 0x73, 0x65, 0x5b,
+ /*26b0:*/ 0x28, 0x8d, 0xe5, 0x99, 0x8e, 0x47, 0xfd, 0x75, 0x63, 0xd6, 0x6a, 0x16, 0xe7, 0xa8, 0x27, 0x44,
+ /*26c0:*/ 0x76, 0xf6, 0x81, 0xf9, 0xec, 0x37, 0x49, 0x5b, 0x50, 0x19, 0x11, 0x8e, 0xe4, 0x21, 0x6f, 0xca,
+ /*26d0:*/ 0xd3, 0x91, 0xb7, 0x2d, 0x91, 0x1b, 0x99, 0x19, 0xb6, 0xfb, 0xcd, 0xb6, 0xe4, 0x11, 0xd3, 0x26,
+ /*26e0:*/ 0x70, 0xa9, 0x3f, 0x3e, 0x81, 0x66, 0x8c, 0x97, 0xce, 0xe8, 0x98, 0x0a, 0x55, 0x57, 0x7f, 0x14,
+ /*26f0:*/ 0x8b, 0x9d, 0xb5, 0x81, 0x3b, 0x61, 0x25, 0x5e, 0xa0, 0xda, 0xcc, 0x64, 0xf1, 0xe2, 0xe4, 0xa0,
+ /*2700:*/ 0x86, 0xdb, 0xec, 0x17, 0x94, 0x06, 0xe8, 0xa3, 0x6d, 0x65, 0xd7, 0x0e, 0xda, 0x42, 0xfa, 0x65,
+ /*2710:*/ 0x2f, 0x86, 0xde, 0xb3, 0x0c, 0x85, 0x46, 0xb2, 0x5f, 0x43, 0x40, 0xc7, 0x06, 0xfc, 0xd7, 0xbc,
+ /*2720:*/ 0x13, 0x3d, 0x1e, 0x7c, 0xfe, 0x21, 0x92, 0x51, 0xcd, 0xb6, 0xf2, 0xdd, 0xf2, 0xf1, 0x63, 0x3d,
+ /*2730:*/ 0x23, 0x81, 0xd4, 0x82, 0x2e, 0x7b, 0x7d, 0x9b, 0xa4, 0x45, 0x30, 0xf5, 0xbf, 0x32, 0x01, 0xbd,
+ /*2740:*/ 0xda, 0x6e, 0xb6, 0x43, 0xbc, 0xb3, 0xf2, 0xbb, 0x7c, 0x99, 0xcc, 0x84, 0xc2, 0x32, 0x89, 0xe9,
+ /*2750:*/ 0xfa, 0xeb, 0x75, 0x52, 0x77, 0xc2, 0xf4, 0x18, 0x1f, 0x16, 0xef, 0x3a, 0xcd, 0xef, 0xce, 0x7f,
+ /*2760:*/ 0x69, 0xcf, 0x0d, 0x50, 0xa4, 0xc6, 0x17, 0xf8, 0x00, 0x28, 0xed, 0xa6, 0x98, 0x97, 0xb8, 0x42,
+ /*2770:*/ 0xae, 0xc1, 0x43, 0x4d, 0x00, 0x0c, 0x41, 0x67, 0xf1, 0xe5, 0xed, 0x28, 0x75, 0x64, 0x27, 0x57,
+ /*2780:*/ 0x0a, 0x42, 0xa0, 0x9f, 0x81, 0x6b, 0xf4, 0xa8, 0x4a, 0x92, 0xe4, 0xf4, 0xe2, 0x02, 0x5d, 0xf1,
+ /*2790:*/ 0x2c, 0xe6, 0x61, 0x2d, 0xc8, 0x73, 0x24, 0x58, 0xb9, 0x52, 0x8c, 0x3d, 0x69, 0x5f, 0xc4, 0xc5,
+ /*27a0:*/ 0x7c, 0x76, 0x40, 0x0f, 0x27, 0x98, 0x30, 0x34, 0xc7, 0xb3, 0x9f, 0x8c, 0xa2, 0x59, 0x90, 0x60,
+ /*27b0:*/ 0xe5, 0xbe, 0x1c, 0x06, 0xc5, 0x7e, 0x3b, 0xce, 0x8c, 0x18, 0x19, 0x52, 0xe5, 0x20, 0xc9, 0x58,
+ /*27c0:*/ 0xea, 0x6b, 0x24, 0x44, 0x8f, 0x8d, 0x41, 0xbc, 0xb7, 0xd9, 0x7d, 0x38, 0xc5, 0xf9, 0xe4, 0x8d,
+ /*27d0:*/ 0xf6, 0x7a, 0x01, 0x3d, 0x0f, 0x9c, 0xf3, 0x55, 0x54, 0x78, 0xa8, 0xb8, 0x2e, 0x4f, 0xfd, 0x4e,
+ /*27e0:*/ 0xc7, 0xea, 0x78, 0xbc, 0xa3, 0x35, 0xa6, 0x8a, 0x70, 0xfb, 0xef, 0xb0, 0x5e, 0x72, 0x91, 0x3e,
+ /*27f0:*/ 0x43, 0xc0, 0xb0, 0x1e, 0x7a, 0x3a, 0xcd, 0xa1, 0xfd, 0x02, 0x6b, 0x55, 0xc1, 0xd2, 0x3a, 0xd1,
+ /*2800:*/ 0x65, 0x71, 0x5d, 0x2c, 0x57, 0xce, 0x15, 0xec, 0x08, 0xb0, 0x83, 0xf0, 0xac, 0x4f, 0x10, 0xa0,
+ /*2810:*/ 0x80, 0xc3, 0x64, 0x82, 0x87, 0xb4, 0x99, 0x83, 0xd3, 0x3b, 0x21, 0x03, 0xbc, 0xa3, 0x8a, 0x4f,
+ /*2820:*/ 0xcb, 0x72, 0x0f, 0x13, 0x55, 0xb8, 0x50, 0x30, 0x8a, 0xc7, 0x3e, 0xc8, 0x1b, 0xd2, 0x80, 0xec,
+ /*2830:*/ 0x87, 0x25, 0x4f, 0x9f, 0x19, 0xd6, 0x3f, 0xfc, 0x7b, 0xed, 0x1b, 0x8b, 0xa8, 0x27, 0x82, 0xa2,
+ /*2840:*/ 0x67, 0xae, 0xed, 0xd9, 0x1d, 0xba, 0x29, 0x2c, 0xd2, 0x11, 0x6a, 0xbd, 0x98, 0x0a, 0xca, 0x16,
+ /*2850:*/ 0xaf, 0xe6, 0x80, 0x10, 0xe4, 0x3c, 0x0e, 0xd2, 0xd2, 0xfe, 0x4a, 0x71, 0x1f, 0x6e, 0x6e, 0xf4,
+ /*2860:*/ 0xf5, 0x4a, 0x27, 0xf8, 0xb8, 0x6a, 0xf1, 0x47, 0xbe, 0xfe, 0x48, 0x31, 0x87, 0xd1, 0x31, 0x1d,
+ /*2870:*/ 0x6e, 0x64, 0xde, 0x2a, 0x50, 0xb6, 0x47, 0xf2, 0x35, 0xd7, 0x97, 0x70, 0x2a, 0xf7, 0xf1, 0xa7,
+ /*2880:*/ 0x14, 0x57, 0x09, 0x45, 0xa9, 0x64, 0x6b, 0x3f, 0x98, 0xc7, 0xe9, 0xf4, 0x5f, 0x74, 0xe4, 0x44,
+ /*2890:*/ 0x34, 0xce, 0x4a, 0x60, 0x80, 0x6c, 0xe7, 0x88, 0xc9, 0xab, 0x26, 0x5a, 0xc4, 0x5f, 0xe3, 0x09,
+ /*28a0:*/ 0x2d, 0xc8, 0x95, 0xae, 0xfc, 0x8e, 0xdf, 0xc9, 0x3c, 0x65, 0x5c, 0xf5, 0x7c, 0x04, 0x20, 0xcb,
+ /*28b0:*/ 0x22, 0xb7, 0x6b, 0x91, 0xc3, 0x2d, 0xa0, 0x25, 0xc2, 0x69, 0x7b, 0x3d, 0x86, 0x1a, 0x20, 0x49,
+ /*28c0:*/ 0x8d, 0x42, 0xc1, 0xc4, 0x9a, 0x1f, 0xf3, 0x3f, 0x52, 0xf0, 0xf1, 0xe2, 0x5c, 0xf0, 0x37, 0x12,
+ /*28d0:*/ 0x99, 0x13, 0x21, 0x70, 0x39, 0x7c, 0x74, 0x22, 0xff, 0xc6, 0xc6, 0x0c, 0xbc, 0xf6, 0x8d, 0x72,
+ /*28e0:*/ 0xeb, 0xa4, 0x13, 0x79, 0xd7, 0x23, 0xa8, 0xdb, 0x59, 0x7b, 0x70, 0xfd, 0x06, 0xf5, 0x6c, 0x53,
+ /*28f0:*/ 0xe5, 0x04, 0x74, 0xa7, 0xc8, 0xb6, 0xe6, 0x95, 0x99, 0x95, 0x89, 0x55, 0xc7, 0xdd, 0xc9, 0x45,
+ /*2900:*/ 0xb5, 0x88, 0xc7, 0xbd, 0x0d, 0x52, 0xf0, 0x08, 0x03, 0x87, 0x9e, 0x8b, 0xe6, 0x68, 0x57, 0xde,
+ /*2910:*/ 0x81, 0x77, 0x92, 0x91, 0x45, 0x41, 0x3a, 0xfe, 0x2f, 0xf0, 0x2c, 0x3b, 0xed, 0x9d, 0x3e, 0xbf,
+ /*2920:*/ 0x4a, 0x8e, 0x7f, 0x54, 0xaa, 0x5c, 0x08, 0x84, 0x86, 0xf3, 0xc3, 0x04, 0x86, 0x2a, 0xab, 0xaf,
+ /*2930:*/ 0xcc, 0xac, 0xd8, 0x59, 0x7d, 0xa1, 0xd3, 0x70, 0x4f, 0xb1, 0x1b, 0x05, 0xbb, 0x61, 0x85, 0xd7,
+ /*2940:*/ 0x3b, 0xaf, 0x3c, 0x80, 0x2a, 0xae, 0x1b, 0xfe, 0x24, 0xb6, 0x1d, 0x23, 0x3d, 0xae, 0x39, 0x5a,
+ /*2950:*/ 0xe5, 0xc4, 0x23, 0x39, 0x4f, 0x4c, 0x7e, 0x83, 0x4e, 0x8a, 0x8a, 0x89, 0x5f, 0x9e, 0x28, 0x1b,
+ /*2960:*/ 0xd8, 0xdf, 0xb8, 0xf7, 0x0e, 0x9d, 0x83, 0x23, 0x33, 0x77, 0x09, 0x96, 0x4b, 0x3c, 0xd3, 0x34,
+ /*2970:*/ 0x32, 0x75, 0x8b, 0x57, 0xd0, 0x75, 0xa1, 0xbe, 0xbf, 0xaa, 0x47, 0xfd, 0x34, 0xe1, 0x8d, 0xb2,
+ /*2980:*/ 0x15, 0x23, 0xdb, 0x9e, 0x68, 0x87, 0x98, 0xf4, 0x50, 0xc2, 0x43, 0xaf, 0x3a, 0x76, 0xcb, 0xb8,
+ /*2990:*/ 0x3f, 0x8f, 0x5c, 0x0d, 0x82, 0x4d, 0x86, 0xfe, 0x53, 0x51, 0xea, 0xba, 0xf7, 0x47, 0x9f, 0xbd,
+ /*29a0:*/ 0xb9, 0xf3, 0xe7, 0x5c, 0x21, 0x05, 0x9f, 0xa0, 0x51, 0x53, 0xec, 0xda, 0xce, 0x5d, 0xd7, 0x54,
+ /*29b0:*/ 0xbb, 0x95, 0xb8, 0xf0, 0x81, 0xf5, 0x80, 0x72, 0x6c, 0x11, 0xf6, 0x50, 0x7e, 0xb6, 0x7b, 0x17,
+ /*29c0:*/ 0xd4, 0xd9, 0xca, 0x9f, 0x2a, 0x42, 0xef, 0x81, 0x72, 0x68, 0x21, 0x4a, 0x32, 0x41, 0xa8, 0x2b,
+ /*29d0:*/ 0x6b, 0xf7, 0xc2, 0x9d, 0xdc, 0x14, 0x0e, 0xfa, 0x35, 0x95, 0x7d, 0x9c, 0xb5, 0x2c, 0x52, 0xac,
+ /*29e0:*/ 0xf3, 0x4a, 0x82, 0x9a, 0x6b, 0xa6, 0x5a, 0x53, 0xbe, 0x75, 0x7e, 0xd7, 0x62, 0x28, 0xe1, 0x42,
+ /*29f0:*/ 0x1b, 0x44, 0x8c, 0xb3, 0xf7, 0x59, 0x60, 0xb4, 0x6d, 0x87, 0x89, 0xf3, 0x5b, 0xe9, 0x02, 0xee,
+ /*2a00:*/ 0x38, 0xdb, 0xcb, 0x3f, 0x5a, 0x99, 0x68, 0x43, 0x13, 0x62, 0x6b, 0x05, 0xd7, 0xc0, 0x81, 0x10,
+ /*2a10:*/ 0xbf, 0x56, 0x4e, 0x2a, 0x21, 0xe2, 0x17, 0x64, 0xfa, 0x2c, 0xc1, 0xee, 0xa0, 0xee, 0x91, 0xcb,
+ /*2a20:*/ 0x12, 0xaa, 0x14, 0x08, 0xc1, 0x29, 0x23, 0xb4, 0xc6, 0xaf, 0xff, 0xf8, 0x4d, 0x05, 0x6c, 0xe8,
+ /*2a30:*/ 0x20, 0x11, 0xdf, 0xc4, 0x0f, 0x2c, 0x49, 0xc9, 0xd3, 0xf2, 0x7d, 0x37, 0x9c, 0xc0, 0xc1, 0x99,
+ /*2a40:*/ 0xf5, 0xa1, 0x91, 0x10, 0x45, 0x6a, 0xf4, 0x61, 0x3e, 0x0f, 0x08, 0x4f, 0x84, 0xe9, 0x22, 0x0d,
+ /*2a50:*/ 0x1e, 0x78, 0x44, 0xd8, 0x31, 0x49, 0x6a, 0x31, 0x2a, 0x43, 0x5c, 0x64, 0x66, 0x43, 0x10, 0x9d,
+ /*2a60:*/ 0xa2, 0x74, 0x84, 0x28, 0xbf, 0x78, 0x5a, 0xfd, 0xbe, 0x2d, 0x01, 0xeb, 0x55, 0xa9, 0x41, 0x94,
+ /*2a70:*/ 0xd1, 0x7b, 0x72, 0x62, 0x82, 0x92, 0x64, 0xef, 0x05, 0xe9, 0xd0, 0x35, 0x3d, 0x46, 0x4d, 0xb4,
+ /*2a80:*/ 0x9f, 0x1e, 0x09, 0x38, 0x8c, 0x37, 0x70, 0x9e, 0xfb, 0x04, 0xa0, 0xd1, 0x49, 0x92, 0x85, 0x74,
+ /*2a90:*/ 0x23, 0x19, 0x41, 0xc3, 0x56, 0xf0, 0x89, 0xdf, 0x00, 0x83, 0x4b, 0xcb, 0xf1, 0x66, 0x9b, 0x8d,
+ /*2aa0:*/ 0x61, 0xf0, 0x6d, 0xee, 0x6b, 0x34, 0xc3, 0x88, 0x7e, 0xbf, 0x62, 0x3f, 0xe7, 0x4d, 0x85, 0x70,
+ /*2ab0:*/ 0xba, 0x7c, 0xe4, 0x78, 0x8f, 0xa1, 0x01, 0x58, 0x68, 0x67, 0x05, 0x36, 0x17, 0x0c, 0x4f, 0xe3,
+ /*2ac0:*/ 0xd4, 0x85, 0x39, 0x93, 0x8f, 0xf6, 0xd6, 0x93, 0x16, 0xd9, 0x19, 0x7c, 0xa6, 0x94, 0x76, 0xad,
+ /*2ad0:*/ 0xf4, 0xec, 0x5b, 0x63, 0x3d, 0x3e, 0x65, 0x29, 0x39, 0x6c, 0xa7, 0xe0, 0xbf, 0xe5, 0x64, 0x17,
+ /*2ae0:*/ 0xa9, 0xcb, 0xb9, 0x96, 0x58, 0x85, 0xdb, 0x55, 0x33, 0x31, 0x70, 0xac, 0x89, 0x01, 0x54, 0x83,
+ /*2af0:*/ 0x8d, 0x52, 0xa6, 0x6d, 0x71, 0x5f, 0x7b, 0xb6, 0x43, 0x8b, 0x44, 0x4e, 0xe4, 0x38, 0x67, 0x32,
+ /*2b00:*/ 0x4b, 0x5b, 0xea, 0xfd, 0xe5, 0x4c, 0x44, 0x15, 0x80, 0xde, 0x1c, 0x5d, 0x8c, 0xa5, 0xa1, 0x03,
+ /*2b10:*/ 0x56, 0x81, 0x78, 0x9b, 0xcc, 0x2f, 0xbb, 0x98, 0x55, 0xc8, 0x2b, 0x2c, 0x3d, 0x5a, 0x9c, 0x01,
+ /*2b20:*/ 0x73, 0x9f, 0x25, 0x24, 0x2a, 0xf9, 0xf0, 0x69, 0x59, 0x11, 0x7f, 0x0e, 0xa9, 0xfc, 0x14, 0x2d,
+ /*2b30:*/ 0x75, 0xa1, 0x24, 0xa0, 0x02, 0x29, 0x81, 0x04, 0x79, 0xfe, 0x7e, 0x99, 0x45, 0x01, 0xc0, 0xd4,
+ /*2b40:*/ 0x38, 0x9c, 0x9c, 0x24, 0xe8, 0x02, 0x26, 0xae, 0x10, 0x3d, 0x37, 0x33, 0xe3, 0x74, 0xd4, 0xfc,
+ /*2b50:*/ 0xe3, 0x82, 0x8e, 0xa2, 0x1c, 0x22, 0x8d, 0xd7, 0x94, 0xb3, 0xb3, 0x3c, 0xfc, 0xeb, 0xa9, 0x9c,
+ /*2b60:*/ 0xc6, 0x1c, 0x9e, 0x39, 0xaf, 0xb9, 0xfb, 0x65, 0x9a, 0xc7, 0xa3, 0xaa, 0x65, 0x23, 0x14, 0xb3,
+ /*2b70:*/ 0x30, 0x9f, 0x26, 0x3d, 0x44, 0x94, 0xe8, 0x44, 0xe1, 0xa8, 0x48, 0xb2, 0x6a, 0x1d, 0x2c, 0x49,
+ /*2b80:*/ 0xff, 0x90, 0x82, 0x9b, 0x21, 0xa9, 0xee, 0x51, 0x32, 0xfc, 0xa3, 0x77, 0x87, 0xf5, 0x1d, 0xc5,
+ /*2b90:*/ 0xd3, 0xb3, 0x1c, 0x25, 0x36, 0xa7, 0x23, 0xaf, 0xbf, 0x16, 0x25, 0x73, 0x91, 0x02, 0x04, 0xf7,
+ /*2ba0:*/ 0x4d, 0xe0, 0xa1, 0x12, 0x68, 0xa8, 0x89, 0xbe, 0x16, 0xed, 0x84, 0x18, 0x68, 0x17, 0x7b, 0x27,
+ /*2bb0:*/ 0x73, 0xc2, 0x07, 0xcf, 0x89, 0xdd, 0x18, 0x3c, 0x0f, 0x0c, 0x94, 0x2e, 0x9c, 0x44, 0xba, 0xf5,
+ /*2bc0:*/ 0x4f, 0x3b, 0xd4, 0xb7, 0x3a, 0x61, 0xd3, 0x4c, 0x1a, 0x09, 0x3c, 0x37, 0x29, 0x49, 0x8a, 0x38,
+ /*2bd0:*/ 0x91, 0xda, 0xb9, 0x64, 0x3c, 0xdd, 0xfe, 0x2a, 0x84, 0xb3, 0x56, 0x8c, 0xdb, 0x27, 0x73, 0x96,
+ /*2be0:*/ 0x5b, 0xfa, 0x89, 0x4d, 0xda, 0xd8, 0x0e, 0x72, 0x44, 0x6c, 0x66, 0x4f, 0x1a, 0x18, 0xa3, 0xf3,
+ /*2bf0:*/ 0xdc, 0xc0, 0x55, 0xa5, 0x25, 0x61, 0xd6, 0xf7, 0x09, 0xe1, 0xb6, 0x43, 0x4e, 0x1c, 0x6c, 0xd4,
+ /*2c00:*/ 0x49, 0xfe, 0x6c, 0xd1, 0xda, 0x1d, 0x53, 0xf7, 0x4e, 0x4d, 0xb2, 0x43, 0x0d, 0x98, 0x2e, 0x29,
+ /*2c10:*/ 0x9f, 0xd5, 0xfc, 0x21, 0x31, 0xd8, 0x74, 0x1a, 0x3b, 0xf7, 0x50, 0x06, 0x57, 0x6c, 0xbe, 0x5e,
+ /*2c20:*/ 0x5a, 0x29, 0xef, 0xac, 0xde, 0xf2, 0xe3, 0xad, 0x69, 0x6f, 0x67, 0x78, 0xce, 0x9f, 0xc4, 0x42,
+ /*2c30:*/ 0xb0, 0xac, 0xeb, 0x30, 0x7f, 0x23, 0x93, 0x86, 0xe7, 0x7d, 0x35, 0x32, 0xe3, 0x6b, 0x0e, 0x8b,
+ /*2c40:*/ 0x58, 0x83, 0x50, 0xe3, 0x5f, 0x12, 0xd4, 0xa7, 0xf2, 0x1b, 0xfb, 0xb1, 0xf9, 0x7e, 0x1e, 0x05,
+ /*2c50:*/ 0x7f, 0xec, 0x88, 0x2e, 0xd3, 0xda, 0x49, 0x3f, 0x3a, 0xc9, 0xb7, 0x3f, 0x44, 0xc5, 0xb6, 0x01,
+ /*2c60:*/ 0xb0, 0x6f, 0xa1, 0x3c, 0x9e, 0x44, 0x02, 0xf1, 0x11, 0x92, 0xf1, 0xd1, 0x7d, 0x2a, 0xa7, 0xc2,
+ /*2c70:*/ 0x7f, 0x5b, 0xc3, 0x0e, 0x03, 0xe1, 0x86, 0xf4, 0x63, 0x19, 0x15, 0xad, 0x1b, 0x0d, 0x9b, 0x04,
+ /*2c80:*/ 0x55, 0x49, 0xcb, 0x89, 0x85, 0x98, 0x6a, 0xd0, 0x18, 0x4d, 0xa2, 0x3e, 0x8c, 0x8b, 0x6c, 0x5b,
+ /*2c90:*/ 0xcf, 0xd1, 0xcb, 0xf3, 0x1a, 0x7b, 0x7b, 0x97, 0xe1, 0xa9, 0xd3, 0xcd, 0xc1, 0xbd, 0x25, 0x99,
+ /*2ca0:*/ 0x51, 0xde, 0x67, 0x08, 0x13, 0xa2, 0x91, 0x52, 0x4e, 0xf3, 0xca, 0xe7, 0xf3, 0xdc, 0x94, 0x1e,
+ /*2cb0:*/ 0x00, 0x60, 0x69, 0xfe, 0x98, 0xe9, 0x06, 0xc4, 0xf9, 0x9f, 0xdd, 0x2b, 0x25, 0x11, 0x41, 0x4f,
+ /*2cc0:*/ 0x7a, 0x75, 0x62, 0x4e, 0xbe, 0x00, 0x7b, 0xee, 0x38, 0x57, 0xd3, 0x5a, 0xf7, 0xc2, 0x33, 0x37,
+ /*2cd0:*/ 0x59, 0xe3, 0xd5, 0x20, 0x4e, 0xb1, 0x8d, 0xcf, 0x43, 0x03, 0xf3, 0x65, 0xca, 0xb6, 0xd1, 0x52,
+ /*2ce0:*/ 0x36, 0x8e, 0xdd, 0xb0, 0x30, 0x6c, 0xcf, 0xec, 0xe1, 0x04, 0xc1, 0x5b, 0x40, 0x7b, 0x4d, 0x02,
+ /*2cf0:*/ 0x91, 0x46, 0x3c, 0x90, 0x87, 0x60, 0xe4, 0x1b, 0xe0, 0xe1, 0x2c, 0xeb, 0x16, 0x6f, 0x6c, 0x72,
+ /*2d00:*/ 0xda, 0x71, 0x1f, 0x55, 0x3a, 0xe7, 0x52, 0x15, 0xff, 0x09, 0x4a, 0x84, 0x0c, 0xc5, 0x92, 0x69,
+ /*2d10:*/ 0x94, 0x5c, 0xb2, 0x15, 0x7f, 0x00, 0xe3, 0xf1, 0x43, 0x8b, 0x06, 0xa3, 0x51, 0xdf, 0xd1, 0x3c,
+ /*2d20:*/ 0x14, 0xe0, 0xe4, 0x18, 0xae, 0xe2, 0x56, 0x00, 0x6d, 0x04, 0xa0, 0xef, 0x21, 0xfe, 0x0e, 0xd6,
+ /*2d30:*/ 0x19, 0x78, 0x19, 0x98, 0xa4, 0x86, 0x6c, 0xc2, 0x39, 0x3b, 0x61, 0x33, 0xf9, 0xd9, 0xed, 0xcb,
+ /*2d40:*/ 0x8b, 0x14, 0x4e, 0xc2, 0x0f, 0x5d, 0xf0, 0x19, 0x0b, 0x21, 0x25, 0x61, 0x79, 0x93, 0x3d, 0x0d,
+ /*2d50:*/ 0xed, 0x6f, 0x1a, 0xa0, 0x19, 0xab, 0xb6, 0x56, 0xce, 0xa5, 0x51, 0xa4, 0x09, 0xf6, 0xc5, 0x95,
+ /*2d60:*/ 0x63, 0x85, 0x5f, 0x24, 0xd7, 0xd4, 0xba, 0x07, 0xa3, 0x62, 0x55, 0xe7, 0x3f, 0x7c, 0x3a, 0x8b,
+ /*2d70:*/ 0xc3, 0xc8, 0xe9, 0x94, 0x59, 0x59, 0xc9, 0x87, 0xc9, 0xc1, 0xdb, 0xb9, 0xc0, 0x13, 0xa1, 0x1e,
+ /*2d80:*/ 0xd4, 0x49, 0x32, 0xa3, 0x31, 0x42, 0xb4, 0x32, 0xed, 0x0a, 0xfd, 0xf4, 0xf8, 0x76, 0x01, 0x28,
+ /*2d90:*/ 0xaf, 0x1e, 0x7b, 0xd6, 0x7e, 0xf7, 0x05, 0x4c, 0x15, 0xee, 0x50, 0x74, 0x15, 0xbf, 0x19, 0xc7,
+ /*2da0:*/ 0x5e, 0xa6, 0x8d, 0xb9, 0x0d, 0xfc, 0x4a, 0xf1, 0x55, 0x4f, 0x2a, 0xea, 0x1c, 0x91, 0xdf, 0x47,
+ /*2db0:*/ 0xf2, 0x3a, 0xab, 0x09, 0x3a, 0x96, 0x92, 0x4b, 0xdd, 0xf7, 0x13, 0x82, 0xa1, 0x77, 0x44, 0x96,
+ /*2dc0:*/ 0xe2, 0x7b, 0x9d, 0xcb, 0xdd, 0x3b, 0x10, 0xf6, 0x45, 0x5b, 0xd0, 0x9e, 0xfb, 0x50, 0x10, 0x86,
+ /*2dd0:*/ 0x31, 0x05, 0x5c, 0x8e, 0x77, 0xb2, 0x49, 0x86, 0xe1, 0x35, 0x45, 0x65, 0x28, 0x5b, 0x05, 0xce,
+ /*2de0:*/ 0x4b, 0xef, 0xf2, 0x62, 0xde, 0xa3, 0x89, 0xf9, 0x8f, 0x68, 0x2a, 0x2c, 0xcd, 0x06, 0xd0, 0xb5,
+ /*2df0:*/ 0xb4, 0x4d, 0xa2, 0x38, 0xd1, 0x3c, 0x01, 0x13, 0x3c, 0x98, 0x8b, 0x72, 0x80, 0x4a, 0x22, 0x73,
+ /*2e00:*/ 0x45, 0x15, 0x5a, 0xaf, 0x27, 0x76, 0x7e, 0xd0, 0x5e, 0xad, 0x37, 0xdb, 0x59, 0xac, 0xd1, 0x11,
+ /*2e10:*/ 0x9e, 0xca, 0x10, 0x59, 0x29, 0x7d, 0x2f, 0xc4, 0xcb, 0x83, 0xdb, 0x96, 0x54, 0x7d, 0xa7, 0x4c,
+ /*2e20:*/ 0x61, 0x0b, 0x0e, 0xa1, 0xcd, 0xa5, 0x5d, 0x9c, 0x5d, 0xc7, 0x5a, 0x5d, 0x10, 0xfc, 0x43, 0x7b,
+ /*2e30:*/ 0x91, 0xd0, 0x2a, 0xdc, 0x9f, 0x4b, 0xeb, 0xaa, 0x53, 0xf3, 0x5a, 0x54, 0x16, 0x78, 0xd2, 0x67,
+ /*2e40:*/ 0x28, 0x1a, 0x39, 0x2e, 0x9a, 0x5b, 0xae, 0x7e, 0x2f, 0xc2, 0xf6, 0xa7, 0xaf, 0x8a, 0x84, 0xdf,
+ /*2e50:*/ 0x6b, 0xdb, 0xbc, 0xdf, 0xd7, 0x2e, 0xd5, 0x27, 0xbb, 0x31, 0x40, 0xb9, 0x54, 0xb1, 0xf9, 0x08,
+ /*2e60:*/ 0xdb, 0x69, 0xff, 0x2e, 0x40, 0xa9, 0x98, 0x36, 0x02, 0x24, 0x52, 0x27, 0x48, 0x5b, 0x16, 0x56,
+ /*2e70:*/ 0x8a, 0x2c, 0x7d, 0x15, 0xd1, 0xd8, 0xb2, 0x74, 0xbf, 0x2e, 0x65, 0x61, 0xe8, 0x1c, 0x53, 0x99,
+ /*2e80:*/ 0x54, 0x0a, 0xc0, 0x53, 0xc4, 0xdd, 0x62, 0x38, 0x49, 0x1a, 0xb7, 0xf1, 0xc0, 0xee, 0xf7, 0x58,
+ /*2e90:*/ 0xa9, 0xcd, 0xd2, 0x49, 0xcc, 0x6d, 0xee, 0x43, 0xd0, 0x0c, 0xd4, 0x4b, 0x15, 0x3d, 0x00, 0x7f,
+ /*2ea0:*/ 0x08, 0x29, 0x25, 0x1e, 0x13, 0xc4, 0xfa, 0x84, 0x9a, 0xbd, 0x22, 0xd9, 0xf8, 0x0f, 0xa9, 0xb6,
+ /*2eb0:*/ 0x13, 0x6f, 0x03, 0xd1, 0x91, 0xf7, 0x88, 0x36, 0xbd, 0xb3, 0xb1, 0x67, 0xca, 0x39, 0x4e, 0x1d,
+ /*2ec0:*/ 0xc7, 0xbc, 0xdf, 0xbb, 0x25, 0x1c, 0xcc, 0x59, 0xd1, 0x69, 0x9e, 0x56, 0xe3, 0x93, 0x63, 0xd5,
+ /*2ed0:*/ 0x44, 0xdd, 0x6b, 0x69, 0x1e, 0x51, 0xd0, 0x22, 0x69, 0x3f, 0x04, 0x43, 0xa5, 0xd6, 0x8f, 0x2f,
+ /*2ee0:*/ 0x6d, 0xe8, 0xd6, 0x0e, 0x3d, 0x58, 0x2a, 0x83, 0xd2, 0xee, 0x0e, 0x9d, 0x2c, 0xa8, 0xb5, 0xfa,
+ /*2ef0:*/ 0x65, 0x19, 0x04, 0x2d, 0x19, 0x8c, 0x07, 0xf5, 0x2f, 0x01, 0xf8, 0xc5, 0x38, 0x24, 0xd4, 0x6e,
+ /*2f00:*/ 0xfd, 0xd6, 0xad, 0xf6, 0xac, 0xcd, 0x92, 0x27, 0x93, 0x0b, 0xf9, 0x60, 0x22, 0x2b, 0xa2, 0xae,
+ /*2f10:*/ 0x86, 0x79, 0xd7, 0xd6, 0xb6, 0xad, 0x64, 0x59, 0x69, 0xe0, 0x83, 0xf3, 0xf9, 0x49, 0x19, 0x08,
+ /*2f20:*/ 0x9a, 0xa3, 0xfd, 0xf5, 0x92, 0x2d, 0x35, 0x06, 0x44, 0x32, 0xe7, 0xdf, 0x5e, 0x83, 0x93, 0x42,
+ /*2f30:*/ 0xe4, 0xf8, 0x24, 0xad, 0x65, 0x6d, 0x37, 0x58, 0x87, 0x80, 0x2b, 0xac, 0xc7, 0x27, 0xce, 0x2d,
+ /*2f40:*/ 0x07, 0x10, 0x7e, 0x1d, 0xa4, 0x80, 0x2c, 0x16, 0xf0, 0x3b, 0x66, 0x3d, 0x74, 0x15, 0x25, 0xe0,
+ /*2f50:*/ 0x46, 0xf3, 0x08, 0xbd, 0x0b, 0x6e, 0x44, 0x5a, 0xc5, 0x0e, 0x53, 0x01, 0x4b, 0x80, 0x16, 0x91,
+ /*2f60:*/ 0x07, 0x94, 0x8f, 0x66, 0xb9, 0x38, 0xa1, 0x44, 0xed, 0xd4, 0x44, 0x58, 0x36, 0xd2, 0x12, 0xf3,
+ /*2f70:*/ 0xb0, 0x41, 0x7a, 0xfa, 0xaa, 0xca, 0x35, 0xf2, 0xd6, 0x4e, 0xf7, 0x8b, 0xce, 0x9b, 0x7d, 0x67,
+ /*2f80:*/ 0xdc, 0xbb, 0x46, 0xc8, 0x19, 0xbf, 0x0d, 0xd0, 0x7a, 0xee, 0x10, 0xb7, 0x9c, 0x85, 0x94, 0xb4,
+ /*2f90:*/ 0xfd, 0x49, 0x0d, 0x77, 0x9e, 0x95, 0x0b, 0xe2, 0xd5, 0xef, 0x28, 0x08, 0xee, 0xbf, 0xf9, 0x4b,
+ /*2fa0:*/ 0x39, 0x74, 0x02, 0x96, 0x1a, 0x8f, 0x34, 0x8b, 0x3a, 0xd9, 0x3f, 0x63, 0xa4, 0xfd, 0x63, 0xbd,
+ /*2fb0:*/ 0xc6, 0xfd, 0x8f, 0x02, 0x97, 0x44, 0xbc, 0xb1, 0xe5, 0x95, 0xd0, 0x5b, 0xa8, 0x3c, 0x11, 0xd9,
+ /*2fc0:*/ 0x93, 0xbf, 0x66, 0x82, 0xdc, 0xdd, 0xd5, 0x99, 0xee, 0x92, 0x09, 0x8e, 0x06, 0x0e, 0x7e, 0x67,
+ /*2fd0:*/ 0x00, 0xb5, 0x93, 0xb3, 0x39, 0x00, 0xe2, 0xe2, 0xb7, 0xe3, 0xe0, 0x1f, 0x3e, 0xd7, 0x8a, 0xc7,
+ /*2fe0:*/ 0x7e, 0xa6, 0xce, 0x8b, 0x08, 0xaa, 0x9a, 0xde, 0x27, 0xd2, 0xaf, 0xca, 0x72, 0x41, 0xb0, 0x4f,
+ /*2ff0:*/ 0xea, 0xf5, 0x7b, 0x85, 0x46, 0x03, 0xa6, 0x1f, 0x50, 0x7f, 0x74, 0xba, 0x01, 0xae, 0x88, 0x1e,
+ /*3000:*/ 0x0a, 0x50, 0x71, 0xb9, 0xcc, 0x78, 0x5a, 0xdd, 0x4c, 0xad, 0x30, 0xbd, 0xe8, 0x34, 0x8a, 0xe1,
+ /*3010:*/ 0xaf, 0xa9, 0xeb, 0xb9, 0x22, 0x69, 0xd7, 0x30, 0x45, 0xa6, 0x06, 0xf3, 0xd6, 0x4e, 0xac, 0x19,
+ /*3020:*/ 0xcf, 0x12, 0x66, 0x1d, 0xd2, 0x11, 0xe1, 0xcf, 0x3c, 0x12, 0x21, 0xcd, 0x74, 0xd2, 0xba, 0x62,
+ /*3030:*/ 0xcc, 0x6c, 0xb9, 0x67, 0xfd, 0xc4, 0x5a, 0x94, 0xc5, 0x6f, 0x1e, 0xb7, 0x49, 0x8c, 0x24, 0x96,
+ /*3040:*/ 0xf1, 0x8c, 0x30, 0xb9, 0xfc, 0x2f, 0xdf, 0x9d, 0xb7, 0x6c, 0x81, 0x63, 0xf5, 0x0f, 0x1c, 0xfd,
+ /*3050:*/ 0x15, 0xbe, 0x0b, 0x36, 0xff, 0xa2, 0xc9, 0x07, 0x40, 0x85, 0x70, 0xe4, 0x4f, 0xb0, 0xa9, 0x11,
+ /*3060:*/ 0x8b, 0x8d, 0x6f, 0x74, 0x17, 0x7d, 0x4c, 0xf9, 0xc6, 0x23, 0x81, 0x56, 0x21, 0xcb, 0x99, 0x1c,
+ /*3070:*/ 0x31, 0x03, 0xa1, 0x05, 0x5a, 0x29, 0x9a, 0xf1, 0x2e, 0xf5, 0x07, 0xb1, 0x8b, 0x6b, 0xea, 0xb6,
+ /*3080:*/ 0xd0, 0xe8, 0x78, 0x93, 0xb3, 0x2d, 0xcf, 0xa6, 0xb8, 0x7e, 0xfe, 0x7c, 0x91, 0x25, 0xa6, 0xf1,
+ /*3090:*/ 0xc8, 0xaa, 0xff, 0xcd, 0x4a, 0xf3, 0x22, 0x62, 0x98, 0xbb, 0x95, 0xa7, 0x9e, 0xff, 0x23, 0x37,
+ /*30a0:*/ 0x88, 0x79, 0xbe, 0x02, 0x8e, 0x85, 0xd3, 0x8e, 0x38, 0x50, 0xab, 0x9a, 0x47, 0xa8, 0xa7, 0x1a,
+ /*30b0:*/ 0x22, 0x06, 0xd2, 0xcb, 0xa9, 0x49, 0xd0, 0xfc, 0xa2, 0x3f, 0xb5, 0x8c, 0x80, 0xa4, 0x65, 0xf0,
+ /*30c0:*/ 0x7a, 0xe0, 0xf5, 0x05, 0xf8, 0x1f, 0x75, 0x8b, 0x03, 0xa8, 0xd7, 0x45, 0xd1, 0x17, 0xf4, 0x85,
+ /*30d0:*/ 0x94, 0x85, 0x5a, 0xb3, 0x26, 0x52, 0x4d, 0x24, 0x45, 0x93, 0xd2, 0x19, 0x04, 0x3d, 0xb9, 0x4e,
+ /*30e0:*/ 0xe7, 0xac, 0x7c, 0xd3, 0x38, 0x2e, 0x13, 0xce, 0x72, 0xf7, 0x26, 0x49, 0x04, 0xd0, 0xe4, 0x9b,
+ /*30f0:*/ 0x0f, 0x4c, 0x91, 0x27, 0x37, 0x89, 0x20, 0x54, 0x8b, 0xf9, 0xbc, 0x46, 0xab, 0x97, 0x5d, 0xf3,
+ /*3100:*/ 0x8c, 0xf4, 0xdf, 0x79, 0x3d, 0x13, 0x84, 0xb1, 0x12, 0x33, 0x2d, 0x83, 0xc0, 0xb0, 0xc8, 0x77,
+ /*3110:*/ 0xb7, 0x2e, 0x24, 0x9d, 0xdd, 0x10, 0x31, 0x6f, 0x1b, 0xef, 0x9c, 0x20, 0xcd, 0x8d, 0x90, 0x07,
+ /*3120:*/ 0xbf, 0x1c, 0x6f, 0x46, 0xb6, 0x6e, 0xdd, 0x90, 0x8a, 0xf8, 0xf7, 0x14, 0xc0, 0xbe, 0xd4, 0x9b,
+ /*3130:*/ 0x6f, 0x2a, 0xf5, 0x37, 0xf5, 0xc9, 0x5a, 0x80, 0x5d, 0xef, 0x76, 0x99, 0x7c, 0xfd, 0xd7, 0x04,
+ /*3140:*/ 0xa5, 0x7b, 0xe5, 0x1e, 0x45, 0x20, 0x82, 0xaa, 0xf6, 0x4f, 0x6a, 0x34, 0xfd, 0xbe, 0x61, 0xc2,
+ /*3150:*/ 0x2d, 0xbc, 0x5f, 0xcc, 0x56, 0xc4, 0x4d, 0x62, 0x08, 0xcb, 0xf2, 0x2b, 0x1b, 0x79, 0xd6, 0xe3,
+ /*3160:*/ 0xb6, 0xc2, 0xb0, 0x98, 0xaa, 0xde, 0xb9, 0xf8, 0xf8, 0x26, 0x5e, 0xf1, 0x74, 0x61, 0x5e, 0x10,
+ /*3170:*/ 0xa6, 0xa7, 0x45, 0x50, 0x2b, 0x94, 0x6d, 0x0d, 0x03, 0x66, 0x81, 0xed, 0x6c, 0x30, 0x48, 0x96,
+ /*3180:*/ 0x56, 0xda, 0x29, 0x3d, 0x9a, 0xb1, 0xa3, 0x64, 0x1f, 0xcd, 0xc9, 0x63, 0x42, 0x01, 0x08, 0x34,
+ /*3190:*/ 0x1d, 0x0e, 0x92, 0xca, 0xec, 0x3f, 0x9f, 0x87, 0xda, 0x68, 0xbb, 0xf1, 0x7c, 0x47, 0xc5, 0x26,
+ /*31a0:*/ 0x72, 0xee, 0x46, 0x90, 0x5c, 0xa7, 0x49, 0xd8, 0xd8, 0xba, 0xd6, 0xc9, 0x52, 0x9f, 0x48, 0x38,
+ /*31b0:*/ 0x16, 0xd9, 0xe2, 0x99, 0x88, 0xab, 0x1f, 0xca, 0xd9, 0x63, 0xd4, 0xf2, 0x48, 0x07, 0x92, 0x45,
+ /*31c0:*/ 0xc9, 0xe7, 0x97, 0xdf, 0x7b, 0xf7, 0x4b, 0x69, 0x5b, 0x19, 0x3b, 0x3f, 0x79, 0xc2, 0x23, 0x90,
+ /*31d0:*/ 0xff, 0x84, 0x5a, 0x8a, 0xe8, 0xdf, 0xcb, 0xaf, 0x3d, 0xa0, 0x15, 0x81, 0x43, 0xc6, 0xb5, 0xd9,
+ /*31e0:*/ 0x68, 0xc7, 0x83, 0x0b, 0x8a, 0x77, 0x16, 0xb6, 0x75, 0x23, 0x98, 0x9d, 0x0a, 0x08, 0x47, 0x4f,
+ /*31f0:*/ 0x0b, 0x84, 0x21, 0xdf, 0x61, 0xd5, 0x75, 0x6a, 0x2e, 0x3d, 0x82, 0x58, 0xc6, 0xa8, 0x21, 0xa1,
+ /*3200:*/ 0xa6, 0x39, 0x33, 0x68, 0x31, 0x70, 0x73, 0x84, 0x15, 0x0e, 0xb5, 0x4f, 0xc4, 0x80, 0x9f, 0x10,
+ /*3210:*/ 0x34, 0xf5, 0x6d, 0xa6, 0x49, 0x8f, 0x85, 0x36, 0xb4, 0x4c, 0x2f, 0x1e, 0x60, 0xa6, 0xfc, 0xd6,
+ /*3220:*/ 0xb2, 0x48, 0x2c, 0x7b, 0xdc, 0x02, 0xc7, 0x21, 0x24, 0x47, 0x20, 0x45, 0xd6, 0xbb, 0x29, 0xf6,
+ /*3230:*/ 0x0d, 0x25, 0x12, 0x58, 0xfe, 0xec, 0x88, 0x29, 0x9d, 0x83, 0xe5, 0x24, 0xac, 0xa3, 0x9b, 0x1f,
+ /*3240:*/ 0x35, 0x58, 0xe2, 0x3a, 0xf0, 0x85, 0xe1, 0x37, 0xd4, 0x91, 0xe2, 0xbf, 0xd7, 0xf4, 0x03, 0xf2,
+ /*3250:*/ 0xe4, 0x9d, 0x09, 0x27, 0x95, 0x3f, 0x0e, 0x3d, 0xfd, 0xf7, 0x41, 0xee, 0xb1, 0x76, 0xe1, 0xaf,
+ /*3260:*/ 0xed, 0x68, 0x37, 0xd5, 0xea, 0xe8, 0x6e, 0xc6, 0x11, 0xe6, 0xd7, 0xb0, 0x59, 0x19, 0x4a, 0x83,
+ /*3270:*/ 0x3d, 0xec, 0x38, 0xc9, 0x5b, 0xed, 0xe8, 0xe3, 0x76, 0x03, 0xcd, 0x4a, 0x90, 0xa9, 0x21, 0xd5,
+ /*3280:*/ 0xf4, 0x89, 0xc2, 0x7a, 0xb7, 0xa6, 0x02, 0x40, 0x5c, 0xb7, 0xe7, 0xea, 0x3e, 0xb4, 0x3e, 0x42,
+ /*3290:*/ 0x81, 0x6e, 0x88, 0x87, 0x7c, 0xa1, 0x71, 0xd5, 0x08, 0x7f, 0x87, 0xa0, 0x34, 0x74, 0x4a, 0x73,
+ /*32a0:*/ 0x8b, 0xf6, 0xfe, 0x41, 0xc8, 0xd4, 0x1d, 0x3a, 0x1e, 0xae, 0xff, 0xf4, 0x7e, 0xfe, 0xdd, 0x44,
+ /*32b0:*/ 0x9a, 0x3e, 0x8f, 0x5e, 0xf1, 0xdd, 0xd2, 0x38, 0x61, 0x58, 0x1e, 0xf7, 0xcd, 0x30, 0x3d, 0x88,
+ /*32c0:*/ 0xc4, 0x14, 0x56, 0xb3, 0x1b, 0x68, 0x0a, 0x02, 0x58, 0x47, 0x42, 0xc6, 0xf0, 0x0c, 0x6a, 0xe9,
+ /*32d0:*/ 0xa4, 0x20, 0x32, 0x74, 0x5a, 0xf5, 0x54, 0xa4, 0x48, 0x61, 0x6a, 0xa8, 0x12, 0x6b, 0xd9, 0xa7,
+ /*32e0:*/ 0x0c, 0x6c, 0xcf, 0x74, 0x1c, 0x22, 0xe4, 0x7e, 0x94, 0xe6, 0xf6, 0x9f, 0x0f, 0x17, 0x2b, 0xb1,
+ /*32f0:*/ 0xf0, 0xb4, 0x3b, 0x6a, 0x98, 0xfd, 0x33, 0x56, 0x6b, 0x10, 0x3e, 0x75, 0xa8, 0x0e, 0x4a, 0x99,
+ /*3300:*/ 0x1c, 0xfb, 0xe4, 0x70, 0x94, 0x6f, 0xbd, 0xd9, 0x40, 0x68, 0x46, 0x1f, 0x42, 0xac, 0x6c, 0x2d,
+ /*3310:*/ 0x0d, 0x45, 0xb0, 0x63, 0x81, 0x15, 0xdc, 0x59, 0x54, 0x73, 0xd7, 0xcd, 0xf5, 0x39, 0x93, 0x0a,
+ /*3320:*/ 0x09, 0xc1, 0x6f, 0x26, 0xc2, 0x33, 0xdd, 0x31, 0x87, 0xab, 0xff, 0x93, 0x96, 0xa4, 0x27, 0xda,
+ /*3330:*/ 0xd3, 0x5e, 0x30, 0xb4, 0x04, 0x93, 0xd5, 0xdd, 0x83, 0x4b, 0x19, 0x36, 0xb4, 0xdd, 0xeb, 0x45,
+ /*3340:*/ 0x70, 0x7c, 0xe7, 0x0b, 0x53, 0xda, 0x85, 0x6f, 0x66, 0xcc, 0x88, 0x3d, 0xfe, 0x7f, 0x54, 0xe2,
+ /*3350:*/ 0x12, 0x18, 0xc8, 0xed, 0x0b, 0x49, 0xc3, 0x4e, 0x88, 0x24, 0xae, 0x50, 0x38, 0xed, 0x78, 0x69,
+ /*3360:*/ 0x0d, 0x2d, 0x31, 0x46, 0xce, 0x89, 0xcc, 0x3b, 0x34, 0x8e, 0x12, 0xf4, 0xa4, 0x84, 0x6b, 0xc1,
+ /*3370:*/ 0x2f, 0x69, 0x3a, 0x35, 0x67, 0xb7, 0x13, 0x9d, 0x14, 0x59, 0x2c, 0x73, 0xac, 0x97, 0x1c, 0xc9,
+ /*3380:*/ 0x23, 0xe0, 0xec, 0xf5, 0x84, 0xb6, 0x30, 0x8a, 0x7f, 0xe6, 0x9b, 0x0d, 0xad, 0xdc, 0xa4, 0x9e,
+ /*3390:*/ 0xe4, 0x9f, 0x92, 0xae, 0x05, 0xd7, 0xf3, 0x74, 0x54, 0x24, 0xf8, 0x9f, 0x09, 0xa4, 0xc9, 0x3c,
+ /*33a0:*/ 0x6d, 0xda, 0x01, 0xeb, 0x25, 0x06, 0x66, 0xdd, 0xc0, 0x2d, 0x73, 0xfd, 0x45, 0xd1, 0xe4, 0x34,
+ /*33b0:*/ 0x73, 0xb4, 0x62, 0x11, 0xaf, 0x82, 0x2d, 0xcb, 0xaa, 0xb7, 0x9c, 0x83, 0xc5, 0x57, 0x86, 0xc3,
+ /*33c0:*/ 0xdd, 0xa0, 0xf1, 0x6d, 0xf3, 0x5a, 0xbe, 0xa8, 0xb6, 0x9f, 0x66, 0x9c, 0x7b, 0x48, 0xf1, 0x71,
+ /*33d0:*/ 0x83, 0x94, 0x54, 0x8d, 0x85, 0xb5, 0x03, 0xd1, 0x88, 0xb9, 0xe6, 0xcb, 0x78, 0xab, 0xea, 0x24,
+ /*33e0:*/ 0x54, 0x7e, 0x3f, 0x66, 0xa0, 0x3e, 0x63, 0x9b, 0x8c, 0x57, 0x2c, 0xa9, 0x97, 0xba, 0xfd, 0x6e,
+ /*33f0:*/ 0x05, 0xbb, 0xda, 0x9f, 0x1c, 0x9d, 0x6d, 0xea, 0x04, 0x84, 0x8c, 0x07, 0x78, 0xa2, 0x80, 0x1e,
+ /*3400:*/ 0x1e, 0xe0, 0x0b, 0x8f, 0x89, 0xf3, 0x84, 0x23, 0x17, 0x71, 0xff, 0x15, 0x64, 0x49, 0x2e, 0x90,
+ /*3410:*/ 0x0e, 0x50, 0x20, 0x2f, 0xf1, 0x9b, 0xb9, 0xb3, 0xe6, 0xf0, 0xee, 0xbb, 0x5f, 0x6d, 0xa6, 0xa2,
+ /*3420:*/ 0x10, 0x8f, 0xaf, 0x2f, 0x4e, 0xe9, 0x27, 0xa0, 0x04, 0x48, 0xda, 0x9a, 0x03, 0x64, 0x33, 0x42,
+ /*3430:*/ 0x0e, 0x02, 0x2e, 0x1f, 0x0e, 0x87, 0x0c, 0xd7, 0xe7, 0x09, 0xac, 0x79, 0x42, 0x93, 0xd7, 0x4a,
+ /*3440:*/ 0xaa, 0x5f, 0x07, 0xed, 0xb1, 0xaf, 0x0c, 0x22, 0x63, 0x2a, 0x9c, 0x9d, 0x4b, 0x6c, 0xf6, 0x80,
+ /*3450:*/ 0x0a, 0x1e, 0x4a, 0x50, 0x07, 0x64, 0xc6, 0xcc, 0x3a, 0x2a, 0x64, 0x9e, 0xde, 0x5b, 0x2d, 0x6c,
+ /*3460:*/ 0xe3, 0x48, 0xb5, 0x11, 0x9d, 0x3c, 0xf0, 0x8f, 0x5c, 0x0d, 0xd7, 0x02, 0xf5, 0xce, 0xff, 0x71,
+ /*3470:*/ 0x06, 0xc4, 0x4b, 0x7d, 0x67, 0x7e, 0xef, 0xc4, 0x78, 0x60, 0xba, 0x58, 0x0f, 0xbc, 0x84, 0x7b,
+ /*3480:*/ 0xc5, 0xba, 0xde, 0x8b, 0xdc, 0x60, 0x78, 0xab, 0xf2, 0xde, 0xd4, 0xed, 0x00, 0x22, 0x6b, 0xa4,
+ /*3490:*/ 0x4a, 0x79, 0x43, 0x79, 0xba, 0x03, 0x84, 0x25, 0x0c, 0x41, 0x1d, 0x1f, 0x19, 0x23, 0x7c, 0xf7,
+ /*34a0:*/ 0x20, 0xa3, 0xfd, 0xa1, 0x4f, 0xff, 0xfe, 0x8c, 0x7e, 0xb9, 0x07, 0x7d, 0xbe, 0x79, 0x18, 0xa8,
+ /*34b0:*/ 0x24, 0x2a, 0x95, 0x01, 0xf3, 0x3f, 0xb1, 0xa6, 0xe4, 0xda, 0xcf, 0x68, 0x42, 0x08, 0x2c, 0x4d,
+ /*34c0:*/ 0x2a, 0xd7, 0xb3, 0x6f, 0x4a, 0xb4, 0x6b, 0xe9, 0x0b, 0xfb, 0x73, 0xb1, 0x21, 0x0a, 0x44, 0xab,
+ /*34d0:*/ 0x47, 0x02, 0xdb, 0xb5, 0x0b, 0x13, 0x6f, 0x0c, 0x78, 0x40, 0xbd, 0x73, 0x04, 0xf2, 0x7e, 0x54,
+ /*34e0:*/ 0x85, 0x35, 0x78, 0x52, 0x6d, 0xf4, 0x05, 0x70, 0x51, 0xa2, 0xb9, 0x6f, 0x34, 0x8c, 0x4b, 0x7b,
+ /*34f0:*/ 0xb8, 0x6c, 0x3b, 0xa5, 0xe7, 0x22, 0xc6, 0x46, 0xa8, 0x09, 0xc3, 0x6b, 0x19, 0x01, 0x50, 0xa5,
+ /*3500:*/ 0x58, 0xef, 0x4d, 0xfa, 0xee, 0x20, 0xbd, 0xcb, 0xd1, 0x56, 0xae, 0x7e, 0xc3, 0x6f, 0x61, 0x52,
+ /*3510:*/ 0xde, 0x9e, 0x59, 0xc4, 0x41, 0x52, 0x78, 0x39, 0x97, 0x30, 0x24, 0x9e, 0x92, 0xea, 0xbc, 0x69,
+ /*3520:*/ 0xf9, 0x8d, 0x1d, 0x1a, 0xce, 0x74, 0x52, 0x4f, 0x04, 0x5f, 0x0e, 0xd8, 0xb7, 0xb4, 0xf5, 0x5b,
+ /*3530:*/ 0xa9, 0x1c, 0xc0, 0x0d, 0xf3, 0xbc, 0x27, 0xde, 0x37, 0xe6, 0x26, 0x11, 0xd4, 0x9b, 0x25, 0x42,
+ /*3540:*/ 0xd7, 0xc1, 0xf6, 0xde, 0xb5, 0xae, 0x24, 0x59, 0x2a, 0x83, 0xb5, 0xa6, 0x8f, 0x03, 0xd3, 0xbf,
+ /*3550:*/ 0xcb, 0x58, 0x76, 0xe0, 0xf7, 0xdb, 0x63, 0xa4, 0x18, 0xbc, 0xfb, 0x0c, 0x76, 0x3e, 0x73, 0x71,
+ /*3560:*/ 0x4a, 0xdc, 0x5a, 0x0e, 0xf8, 0x59, 0x88, 0xc1, 0xc9, 0x55, 0x13, 0xc7, 0xab, 0x57, 0x85, 0x5b,
+ /*3570:*/ 0x46, 0x4d, 0x19, 0x14, 0x0c, 0xb0, 0x43, 0xd2, 0x92, 0xef, 0x6f, 0x8b, 0xd9, 0x06, 0xd3, 0x2f,
+ /*3580:*/ 0xaf, 0xf3, 0xa5, 0x09, 0x71, 0x96, 0x97, 0x5a, 0xfd, 0x03, 0x65, 0xad, 0x8e, 0x62, 0xce, 0x91,
+ /*3590:*/ 0x96, 0xd3, 0x91, 0x11, 0xb2, 0x85, 0xc7, 0xcb, 0x29, 0x79, 0x8d, 0x37, 0xd7, 0xec, 0x13, 0x43,
+ /*35a0:*/ 0x20, 0x08, 0x40, 0x8f, 0xa2, 0xee, 0xa5, 0x1f, 0xed, 0xa5, 0x78, 0x4b, 0x59, 0x50, 0x60, 0x09,
+ /*35b0:*/ 0x66, 0x0b, 0x0a, 0x5a, 0xc1, 0xd6, 0xe3, 0x96, 0xcd, 0xa2, 0x61, 0x26, 0x57, 0xa0, 0x51, 0x7e,
+ /*35c0:*/ 0x11, 0x21, 0xad, 0xce, 0xf5, 0x26, 0xdc, 0x8c, 0x3e, 0xd0, 0x61, 0xd8, 0x11, 0x2c, 0x7a, 0x68,
+ /*35d0:*/ 0xca, 0x95, 0x26, 0xde, 0x3c, 0xb4, 0xf1, 0x4b, 0x1e, 0xb8, 0x21, 0x83, 0x1e, 0xdb, 0xd9, 0x9d,
+ /*35e0:*/ 0x73, 0x60, 0xfa, 0x26, 0x2b, 0x41, 0xd1, 0x55, 0x16, 0x7b, 0x9f, 0xa8, 0xa4, 0x1f, 0x18, 0x5b,
+ /*35f0:*/ 0x6d, 0x22, 0xab, 0x73, 0x71, 0x7c, 0x04, 0xa8, 0xef, 0x3f, 0x1d, 0x2c, 0x9a, 0x98, 0x4e, 0xff,
+ /*3600:*/ 0xc7, 0xef, 0x7b, 0x63, 0x4d, 0x79, 0xe2, 0x33, 0x0a, 0xd8, 0x26, 0x30, 0xfc, 0xa3, 0x24, 0x5e,
+ /*3610:*/ 0x2f, 0xd7, 0xb3, 0x90, 0x1e, 0x45, 0x30, 0x41, 0x00, 0x59, 0x92, 0x62, 0x20, 0xb3, 0xff, 0x5d,
+ /*3620:*/ 0x47, 0x31, 0x6e, 0x87, 0xe5, 0x7e, 0x9d, 0x73, 0x8d, 0x3d, 0x74, 0x9c, 0x4b, 0xf7, 0xc8, 0x86,
+ /*3630:*/ 0xe4, 0xa7, 0xac, 0x4c, 0xf9, 0x51, 0x2f, 0x4d, 0xd2, 0x02, 0x9b, 0xcf, 0xb7, 0x68, 0x7f, 0x25,
+ /*3640:*/ 0xc7, 0x22, 0xfa, 0x75, 0xe5, 0xdd, 0x7e, 0xd3, 0x28, 0x07, 0x87, 0x78, 0x62, 0x20, 0x0e, 0xa1,
+ /*3650:*/ 0xab, 0x3e, 0xfd, 0xd0, 0x04, 0xe6, 0xd8, 0xf0, 0xa3, 0x1e, 0x05, 0xf5, 0x7e, 0x5e, 0xd8, 0xee,
+ /*3660:*/ 0x62, 0xc2, 0x71, 0xf7, 0x4a, 0x05, 0x84, 0x90, 0x15, 0x0a, 0x4a, 0x25, 0x32, 0x3c, 0x1c, 0xfe,
+ /*3670:*/ 0x14, 0xe2, 0x19, 0x3b, 0x97, 0xe4, 0x38, 0x8b, 0x7d, 0x30, 0x4b, 0x00, 0x62, 0x01, 0x68, 0x0f,
+ /*3680:*/ 0x01, 0xe3, 0xbb, 0x7d, 0x1a, 0x74, 0x0d, 0x09, 0x8e, 0x7a, 0xfe, 0x00, 0xc3, 0xb8, 0x23, 0xe7,
+ /*3690:*/ 0x98, 0xf5, 0xd7, 0x2b, 0x32, 0x2a, 0x4a, 0xbf, 0xe2, 0x21, 0x5f, 0xd8, 0x7a, 0x7c, 0x65, 0x0a,
+ /*36a0:*/ 0xba, 0x46, 0xfb, 0x66, 0x27, 0xdb, 0xd2, 0xa6, 0x52, 0x49, 0x7a, 0xb2, 0xee, 0x58, 0xe0, 0xc2,
+ /*36b0:*/ 0x90, 0x76, 0x90, 0x4a, 0x6f, 0xa1, 0x04, 0x44, 0xba, 0x9e, 0x40, 0x33, 0x16, 0x27, 0xa3, 0x0e,
+ /*36c0:*/ 0x6b, 0xed, 0x26, 0x0a, 0xaa, 0xc2, 0x09, 0x6a, 0xd6, 0x7c, 0x86, 0x9d, 0x3c, 0x57, 0x66, 0x01,
+ /*36d0:*/ 0xf0, 0x59, 0xd1, 0x2a, 0xf4, 0x5e, 0xa8, 0x4f, 0xff, 0x1a, 0xb2, 0xc6, 0xc6, 0xaa, 0x1e, 0x0d,
+ /*36e0:*/ 0x8d, 0x32, 0x05, 0x6d, 0x97, 0x25, 0xea, 0x32, 0x14, 0x4b, 0x6b, 0x20, 0x2a, 0x8c, 0x2b, 0xc1,
+ /*36f0:*/ 0x58, 0xcb, 0xa6, 0x87, 0x50, 0x96, 0xdb, 0x48, 0x3b, 0xcf, 0x6a, 0x41, 0x30, 0x72, 0x2d, 0x00,
+ /*3700:*/ 0x54, 0x6c, 0x03, 0x86, 0x88, 0x1a, 0x67, 0x8f, 0xa1, 0x4c, 0xdc, 0xf5, 0x7c, 0x16, 0xcf, 0x6f,
+ /*3710:*/ 0xa1, 0x5c, 0x59, 0x83, 0xb2, 0xca, 0xc3, 0xa4, 0x86, 0xa3, 0x0b, 0xab, 0x45, 0xeb, 0xf0, 0x21,
+ /*3720:*/ 0x8d, 0x06, 0x7f, 0x44, 0xa2, 0x4f, 0xeb, 0x63, 0x6f, 0x41, 0x11, 0x45, 0x7d, 0x00, 0xe9, 0x80,
+ /*3730:*/ 0x98, 0x25, 0xe3, 0x9c, 0x5f, 0x21, 0x9e, 0x3c, 0xfa, 0x8f, 0x0c, 0x35, 0x29, 0xce, 0x6e, 0xd6,
+ /*3740:*/ 0x48, 0x2c, 0x30, 0x90, 0xce, 0x35, 0x9d, 0x23, 0x10, 0x7d, 0x21, 0x0e, 0xc2, 0x93, 0x93, 0x8c,
+ /*3750:*/ 0xc5, 0xfc, 0xc6, 0x33, 0x05, 0x56, 0xa3, 0x53, 0x28, 0xd5, 0x3f, 0xc2, 0x80, 0x22, 0x9d, 0x5f,
+ /*3760:*/ 0xaa, 0x97, 0x06, 0x0b, 0xa1, 0xa7, 0x7b, 0x12, 0x7f, 0xcc, 0xca, 0xbc, 0x3e, 0x72, 0xd2, 0x17,
+ /*3770:*/ 0xb0, 0xd0, 0xe2, 0x0e, 0x36, 0xe4, 0xeb, 0xd5, 0x25, 0xc7, 0x94, 0xc4, 0x36, 0xa5, 0x2f, 0xee,
+ /*3780:*/ 0x03, 0xe3, 0x99, 0x3b, 0x9a, 0x57, 0x81, 0x71, 0xc6, 0xdc, 0x18, 0xea, 0x88, 0x10, 0x59, 0xfd,
+ /*3790:*/ 0x9d, 0x31, 0x71, 0x79, 0x55, 0x5d, 0x65, 0xf1, 0x20, 0x81, 0x9e, 0x0e, 0x42, 0x91, 0x2a, 0xa7,
+ /*37a0:*/ 0x0a, 0x79, 0xa8, 0x33, 0xd5, 0x00, 0x1d, 0x55, 0xb2, 0x47, 0xc6, 0xda, 0x47, 0x1e, 0x55, 0x7a,
+ /*37b0:*/ 0xb5, 0x16, 0xe9, 0x16, 0x75, 0x1c, 0x1a, 0x6e, 0x57, 0x30, 0xf4, 0xe1, 0xf0, 0x92, 0x2d, 0x28,
+ /*37c0:*/ 0xfa, 0x30, 0xc5, 0xc2, 0x6e, 0x6b, 0x0b, 0x98, 0x64, 0xd7, 0x3f, 0x6e, 0x73, 0x20, 0xb1, 0xda,
+ /*37d0:*/ 0x9a, 0xc4, 0x04, 0xe9, 0xc8, 0x8c, 0x09, 0xb3, 0x0f, 0x06, 0xa8, 0x07, 0x11, 0xc2, 0x15, 0x27,
+ /*37e0:*/ 0x08, 0xeb, 0x42, 0x29, 0xfb, 0x7c, 0xb2, 0xd5, 0x2c, 0x25, 0x85, 0x6b, 0x07, 0x51, 0xdc, 0x0a,
+ /*37f0:*/ 0x6b, 0xd4, 0xdb, 0x1d, 0xf7, 0x21, 0x59, 0xa0, 0xb5, 0xd9, 0xdf, 0x62, 0x34, 0xd0, 0xce, 0xad,
+ /*3800:*/ 0xfc, 0xad, 0x16, 0xcc, 0x01, 0x9d, 0x55, 0x5e, 0x84, 0xdd, 0x5f, 0xad, 0x3a, 0x36, 0x81, 0x5c,
+ /*3810:*/ 0xaf, 0x48, 0xce, 0x4d, 0xb7, 0x39, 0x02, 0x47, 0x20, 0x55, 0xd6, 0xbd, 0x4e, 0xf8, 0xe8, 0x78,
+ /*3820:*/ 0x74, 0xb3, 0x8e, 0x76, 0xbf, 0x71, 0x1e, 0x46, 0x5b, 0x33, 0x74, 0x23, 0xe1, 0x8b, 0xee, 0x89,
+ /*3830:*/ 0x38, 0xdb, 0xde, 0xb7, 0xae, 0x06, 0x3c, 0x51, 0x1b, 0xaf, 0xf6, 0x32, 0x61, 0x5b, 0xe2, 0xf6,
+ /*3840:*/ 0x7e, 0x0e, 0x78, 0xe8, 0xcf, 0x1a, 0x4a, 0x39, 0xf8, 0xda, 0x4f, 0x1b, 0xb5, 0xe4, 0x25, 0x3e,
+ /*3850:*/ 0x41, 0xef, 0x28, 0xcb, 0x17, 0x2f, 0xa4, 0x55, 0xd6, 0xf9, 0x88, 0x48, 0x26, 0x66, 0x56, 0xfe,
+ /*3860:*/ 0x30, 0x4d, 0x7d, 0x6b, 0xf8, 0x61, 0x80, 0x0f, 0x3d, 0x36, 0xb3, 0x7d, 0x73, 0x40, 0x17, 0x92,
+ /*3870:*/ 0x51, 0x58, 0x05, 0x49, 0x4b, 0x83, 0x13, 0x2a, 0x24, 0xd5, 0x92, 0xac, 0x40, 0x67, 0xe3, 0xa8,
+ /*3880:*/ 0xe9, 0xa6, 0x85, 0x58, 0xd7, 0xf4, 0xfc, 0x1d, 0xb5, 0x68, 0x19, 0xa7, 0xf8, 0xd8, 0xa5, 0x75,
+ /*3890:*/ 0xe0, 0x6d, 0xc6, 0x5a, 0xa6, 0xa3, 0x1c, 0x16, 0xd3, 0xf3, 0x61, 0xbb, 0x3c, 0x61, 0xb1, 0x3d,
+ /*38a0:*/ 0x58, 0xb9, 0x3f, 0x8a, 0xb2, 0x61, 0x6d, 0x78, 0x92, 0x20, 0x6e, 0xff, 0x69, 0x5e, 0x3e, 0xe2,
+ /*38b0:*/ 0x16, 0xb2, 0xc4, 0x44, 0x8d, 0xb9, 0x86, 0xa5, 0xcf, 0xc7, 0x97, 0xc1, 0x10, 0xed, 0xe7, 0x76,
+ /*38c0:*/ 0xe3, 0xa6, 0x51, 0x8f, 0x01, 0xb5, 0xd0, 0x34, 0xe2, 0xab, 0x7d, 0x45, 0xb6, 0x1f, 0x7c, 0xde,
+ /*38d0:*/ 0x5a, 0xa7, 0x59, 0x9e, 0xd2, 0x4b, 0x6d, 0xc8, 0xf4, 0x29, 0xb4, 0x73, 0x20, 0x0a, 0xc5, 0x60,
+ /*38e0:*/ 0xd1, 0x6e, 0xad, 0x8f, 0xb7, 0x56, 0xd3, 0xaa, 0xf9, 0xff, 0x16, 0xcc, 0x7b, 0x87, 0x2c, 0x3a,
+ /*38f0:*/ 0xa1, 0x1c, 0x57, 0x24, 0x5f, 0xb5, 0xb0, 0x99, 0x9c, 0xdb, 0xef, 0xdc, 0x4f, 0x6c, 0xea, 0x39,
+ /*3900:*/ 0x6d, 0x3d, 0x75, 0x65, 0x90, 0x79, 0xb5, 0x4b, 0xa9, 0x86, 0x74, 0xc5, 0xe6, 0x60, 0x7c, 0x2e,
+ /*3910:*/ 0xa4, 0x64, 0x93, 0xc8, 0x24, 0x54, 0x9b, 0xbf, 0x08, 0x07, 0xd1, 0x94, 0x87, 0xea, 0x9d, 0x88,
+ /*3920:*/ 0x19, 0x52, 0x32, 0xa4, 0xb5, 0x09, 0xf1, 0xb8, 0xee, 0x33, 0xc9, 0xff, 0x17, 0x9e, 0xbc, 0xb9,
+ /*3930:*/ 0xb4, 0x53, 0x93, 0xf4, 0x76, 0xa2, 0xd0, 0x87, 0xce, 0x22, 0xea, 0xee, 0xe3, 0xeb, 0x88, 0x58,
+ /*3940:*/ 0xb5, 0xb2, 0xd8, 0xed, 0x4c, 0x01, 0x2a, 0x8c, 0x25, 0x6f, 0xbf, 0xb1, 0xe5, 0x23, 0xf1, 0x7a,
+ /*3950:*/ 0x78, 0x2b, 0x32, 0x37, 0x99, 0xc3, 0xb0, 0x23, 0xa2, 0x9f, 0x72, 0xb6, 0x71, 0x88, 0x92, 0x32,
+ /*3960:*/ 0x52, 0x77, 0xd1, 0xb6, 0x0d, 0xbe, 0x6e, 0xd4, 0xdc, 0xf9, 0xb2, 0x0f, 0xcc, 0x8d, 0x8a, 0x96,
+ /*3970:*/ 0xce, 0x7f, 0x8f, 0xa4, 0x0e, 0x8f, 0x5f, 0x4c, 0x35, 0x54, 0xcb, 0xe2, 0xfa, 0xad, 0x5d, 0xd5,
+ /*3980:*/ 0x5d, 0x70, 0xf2, 0x82, 0x78, 0x27, 0xb9, 0xf9, 0x02, 0x15, 0x53, 0x00, 0xae, 0x29, 0x85, 0xf4,
+ /*3990:*/ 0xba, 0xc6, 0x0e, 0x6c, 0xb6, 0xe9, 0xef, 0xe1, 0x88, 0x42, 0xc5, 0x1a, 0x23, 0x5f, 0x19, 0xaf,
+ /*39a0:*/ 0x15, 0x9e, 0x26, 0x48, 0x42, 0x91, 0xc5, 0xc0, 0xfe, 0xfb, 0x72, 0x0c, 0x98, 0x98, 0xfa, 0xed,
+ /*39b0:*/ 0x94, 0x12, 0x1f, 0xc5, 0x14, 0x00, 0x55, 0xa5, 0x10, 0xc6, 0xf6, 0x3e, 0x64, 0x8c, 0xa7, 0x4e,
+ /*39c0:*/ 0x11, 0x84, 0x16, 0xeb, 0x48, 0x90, 0x49, 0xc2, 0xbf, 0x3c, 0xab, 0x54, 0xe4, 0x28, 0x59, 0x43,
+ /*39d0:*/ 0x77, 0xad, 0x1a, 0x14, 0xd8, 0xc3, 0x3e, 0x88, 0x3f, 0x7f, 0x38, 0xbf, 0xe2, 0x65, 0x89, 0x6d,
+ /*39e0:*/ 0x9e, 0x4e, 0x91, 0x5f, 0x6a, 0x70, 0x48, 0x17, 0xa0, 0x87, 0x68, 0x0d, 0x4b, 0x7c, 0x56, 0x1f,
+ /*39f0:*/ 0x57, 0xb0, 0x4d, 0x54, 0x78, 0x3e, 0x2b, 0xdb, 0x12, 0xed, 0x1d, 0x69, 0x7a, 0x48, 0x03, 0x46,
+ /*3a00:*/ 0x3c, 0xa8, 0x45, 0xff, 0xc7, 0x23, 0x17, 0x2d, 0xdd, 0x6b, 0xad, 0x4a, 0xff, 0x9d, 0x8d, 0xa2,
+ /*3a10:*/ 0x9e, 0x3d, 0x5b, 0xe6, 0x7a, 0x0f, 0x31, 0x6e, 0x0a, 0xca, 0xc4, 0x48, 0x91, 0xe5, 0xd2, 0x38,
+ /*3a20:*/ 0xfe, 0x87, 0x1b, 0x4a, 0xa1, 0xca, 0xd6, 0xad, 0x4d, 0x90, 0xff, 0x65, 0x93, 0xc1, 0x22, 0xdd,
+ /*3a30:*/ 0x46, 0x16, 0x89, 0x08, 0x6e, 0x6d, 0x35, 0x5e, 0x13, 0x95, 0x6d, 0x0e, 0xce, 0xd1, 0x3c, 0x98,
+ /*3a40:*/ 0x15, 0x0a, 0xee, 0xaa, 0xbb, 0x7e, 0xba, 0x21, 0x1c, 0x1d, 0x52, 0x6d, 0xaa, 0x86, 0xcd, 0x42,
+ /*3a50:*/ 0x52, 0xf4, 0xdf, 0xca, 0x57, 0xf8, 0x26, 0x7b, 0xc7, 0x31, 0x37, 0xec, 0xbb, 0x5b, 0x61, 0xe5,
+ /*3a60:*/ 0xda, 0xa9, 0x93, 0xd6, 0xe1, 0xd7, 0xcf, 0xdc, 0xeb, 0x3a, 0xcb, 0x19, 0x73, 0x40, 0xf3, 0xde,
+ /*3a70:*/ 0x5d, 0x4a, 0xaf, 0x46, 0x62, 0xbb, 0xf7, 0x4b, 0x4c, 0xe1, 0x50, 0xa7, 0xc5, 0x14, 0x71, 0xbf,
+ /*3a80:*/ 0x3a, 0x03, 0x8a, 0xd2, 0xaa, 0x9a, 0x44, 0x91, 0xaf, 0xd1, 0x44, 0x24, 0xa4, 0x0e, 0x47, 0x32,
+ /*3a90:*/ 0x51, 0x62, 0x14, 0x10, 0x8d, 0x21, 0x2d, 0x7e, 0x62, 0x12, 0x5d, 0xc1, 0x46, 0xcc, 0x9d, 0xd0,
+ /*3aa0:*/ 0xa0, 0xa2, 0x35, 0x33, 0xcb, 0x4c, 0xc0, 0x5a, 0x20, 0x2e, 0xc8, 0x49, 0x03, 0x12, 0x00, 0xc9,
+ /*3ab0:*/ 0x5c, 0xc8, 0xc3, 0xff, 0xfa, 0x1f, 0x85, 0x18, 0x78, 0xe4, 0x7f, 0x95, 0x07, 0xce, 0xb3, 0xf3,
+ /*3ac0:*/ 0xb1, 0x75, 0x76, 0xf3, 0xd8, 0x82, 0xc8, 0xc9, 0x5e, 0xb5, 0x30, 0xa6, 0xbf, 0xcb, 0x0a, 0x21,
+ /*3ad0:*/ 0x1e, 0x98, 0x06, 0x8e, 0x4c, 0x7a, 0xb4, 0x72, 0x36, 0xf5, 0xca, 0x07, 0xce, 0x90, 0xf2, 0x1f,
+ /*3ae0:*/ 0xcd, 0x68, 0xac, 0x7f, 0x12, 0x8a, 0x19, 0x2c, 0x60, 0x3a, 0x9a, 0x65, 0x79, 0x48, 0x01, 0x89,
+ /*3af0:*/ 0x9e, 0x61, 0xff, 0xe4, 0x36, 0x4f, 0x0d, 0x9b, 0x69, 0xaa, 0x9f, 0x01, 0x87, 0x53, 0x13, 0x0c,
+ /*3b00:*/ 0x93, 0x20, 0x21, 0x87, 0x41, 0x48, 0xfc, 0x82, 0xe9, 0x12, 0x4c, 0x17, 0xd0, 0xee, 0xdc, 0x68,
+ /*3b10:*/ 0xf9, 0xdd, 0x28, 0x13, 0xa4, 0x28, 0x12, 0x97, 0x38, 0xe9, 0xb9, 0x7c, 0x0e, 0xfe, 0xc3, 0xd3,
+ /*3b20:*/ 0x86, 0x7d, 0xb3, 0x82, 0x66, 0xb8, 0x98, 0xeb, 0xdd, 0x24, 0x82, 0xa6, 0x26, 0x82, 0xd0, 0xf0,
+ /*3b30:*/ 0x44, 0xd1, 0x1e, 0x49, 0xee, 0xf5, 0x48, 0x75, 0x87, 0xca, 0xe2, 0xdf, 0x81, 0x9a, 0x5b, 0x83,
+ /*3b40:*/ 0xfd, 0xa1, 0xef, 0x87, 0x83, 0x95, 0xe5, 0x8c, 0x74, 0x35, 0x38, 0xd9, 0x7c, 0x56, 0x5f, 0xf0,
+ /*3b50:*/ 0xd4, 0x60, 0xb8, 0x97, 0xe2, 0x96, 0x06, 0xd3, 0xc9, 0xc9, 0x88, 0x31, 0x02, 0x2a, 0xb2, 0x28,
+ /*3b60:*/ 0xb2, 0xcc, 0x91, 0xcb, 0x01, 0xec, 0xb5, 0x9d, 0x09, 0x6e, 0xd0, 0xde, 0xf0, 0xce, 0x72, 0x93,
+ /*3b70:*/ 0x6c, 0xcb, 0xaa, 0x2b, 0x29, 0x84, 0xbe, 0xab, 0xff, 0x42, 0x2e, 0x4f, 0xc1, 0x65, 0x22, 0x91,
+ /*3b80:*/ 0xac, 0xb3, 0xfb, 0x53, 0x98, 0x56, 0x8f, 0x16, 0xbe, 0x1d, 0x7f, 0x29, 0x17, 0xdc, 0x9d, 0xf8,
+ /*3b90:*/ 0x59, 0x8b, 0xa9, 0x76, 0x01, 0xa8, 0x24, 0xa7, 0x00, 0xdd, 0xa3, 0xe5, 0x6e, 0x27, 0x66, 0x2f,
+ /*3ba0:*/ 0xe7, 0x1d, 0x0d, 0x2a, 0x75, 0x80, 0x10, 0x38, 0xf6, 0x3d, 0x45, 0x18, 0xb0, 0x31, 0xcb, 0xe0,
+ /*3bb0:*/ 0x8e, 0x73, 0x14, 0xbc, 0x36, 0x16, 0xf3, 0xa8, 0xd5, 0x3e, 0xf6, 0xdc, 0xa7, 0x33, 0xcb, 0x49,
+ /*3bc0:*/ 0xb6, 0x45, 0x00, 0xb6, 0xcc, 0x9d, 0x40, 0xbc, 0x1d, 0x12, 0xbb, 0xe4, 0xd0, 0x3f, 0xa6, 0x28,
+ /*3bd0:*/ 0x5d, 0x0f, 0xa2, 0x90, 0xbe, 0x1f, 0x90, 0x6a, 0xb8, 0x22, 0x89, 0xf9, 0x3a, 0xdd, 0x7a, 0xe8,
+ /*3be0:*/ 0x63, 0x1f, 0x1f, 0x15, 0xa1, 0xbd, 0x72, 0x6d, 0x83, 0x02, 0x5e, 0x95, 0x5c, 0x33, 0x20, 0xb4,
+ /*3bf0:*/ 0xe5, 0x39, 0x87, 0xd9, 0x57, 0xd7, 0xb6, 0x86, 0x21, 0xff, 0xfa, 0x67, 0x7e, 0x94, 0xac, 0xda,
+ /*3c00:*/ 0xf0, 0xe0, 0x4e, 0xc4, 0x88, 0x84, 0x01, 0xcc, 0xfa, 0x37, 0x27, 0xbe, 0x63, 0x8f, 0x41, 0x94,
+ /*3c10:*/ 0x75, 0x06, 0x8c, 0x10, 0xd5, 0xf7, 0xe1, 0x2c, 0x92, 0xe1, 0x4f, 0xda, 0xdf, 0xac, 0x64, 0xe8,
+ /*3c20:*/ 0x8e, 0xbb, 0x8b, 0x9a, 0x70, 0x57, 0x50, 0xb3, 0x63, 0x77, 0xcf, 0xa6, 0xb0, 0x91, 0x13, 0xa4,
+ /*3c30:*/ 0x29, 0xf1, 0x27, 0x1d, 0x4e, 0x37, 0x6b, 0x81, 0xd3, 0x0d, 0x3c, 0xb6, 0x91, 0x42, 0xf4, 0x70,
+ /*3c40:*/ 0x64, 0x86, 0x2f, 0xee, 0xec, 0xc2, 0x97, 0xb7, 0xb6, 0xf2, 0x86, 0x8a, 0x7a, 0x2d, 0x6c, 0x06,
+ /*3c50:*/ 0x5d, 0x24, 0xd9, 0xf9, 0xc8, 0xd2, 0xd6, 0xb5, 0xb8, 0xd7, 0x0a, 0x1e, 0x31, 0x4f, 0x04, 0x9c,
+ /*3c60:*/ 0x4b, 0xe0, 0x21, 0xdf, 0xb3, 0x8d, 0xdf, 0xc7, 0x9d, 0x57, 0x62, 0xa4, 0xff, 0x88, 0x07, 0x0e,
+ /*3c70:*/ 0xad, 0x7f, 0x39, 0xe8, 0x8a, 0x04, 0x64, 0xde, 0x94, 0xc3, 0xa3, 0xd0, 0xc8, 0x40, 0x27, 0x63,
+ /*3c80:*/ 0x76, 0x4b, 0xa0, 0xe1, 0xdc, 0xf1, 0xec, 0x93, 0xd3, 0xa2, 0x69, 0x8a, 0xa7, 0xe2, 0x33, 0x97,
+ /*3c90:*/ 0x58, 0xff, 0x7e, 0x66, 0x24, 0x2c, 0x61, 0x7f, 0x3a, 0xdf, 0x92, 0x31, 0x4b, 0x66, 0x52, 0x7e,
+ /*3ca0:*/ 0xa3, 0x88, 0x7e, 0x57, 0xe6, 0x51, 0xf6, 0x7f, 0x98, 0x93, 0x6b, 0xd7, 0x7d, 0x7d, 0xee, 0x72,
+ /*3cb0:*/ 0xc6, 0x15, 0xe1, 0x30, 0x2a, 0xeb, 0x48, 0x8f, 0x8d, 0xed, 0x62, 0x0c, 0x53, 0x93, 0x62, 0x1e,
+ /*3cc0:*/ 0x61, 0x1a, 0x2e, 0x34, 0xad, 0xd2, 0x47, 0x0d, 0x08, 0x8e, 0xae, 0x35, 0x77, 0x25, 0x67, 0x00,
+ /*3cd0:*/ 0x9a, 0xf0, 0x51, 0x5e, 0x16, 0x94, 0x31, 0xd7, 0x24, 0x17, 0xa5, 0xe5, 0x2e, 0x92, 0x36, 0xcb,
+ /*3ce0:*/ 0x36, 0xf8, 0x16, 0xb7, 0x7b, 0xff, 0x2d, 0x25, 0x02, 0x00, 0xb3, 0x75, 0x78, 0xd5, 0xb2, 0x69,
+ /*3cf0:*/ 0xae, 0x95, 0xd8, 0xc4, 0x4e, 0xa1, 0x6f, 0x93, 0x20, 0xae, 0x74, 0x56, 0x7a, 0xed, 0x24, 0xbb,
+ /*3d00:*/ 0xc7, 0x8d, 0x0a, 0xbe, 0x9f, 0x5c, 0xd4, 0xa2, 0x20, 0xe9, 0x5e, 0x01, 0x6d, 0x16, 0xe1, 0x59,
+ /*3d10:*/ 0x05, 0x65, 0xa7, 0x5b, 0xdc, 0x3f, 0x15, 0xf0, 0x43, 0x97, 0x0f, 0x72, 0x60, 0x47, 0xf8, 0x1c,
+ /*3d20:*/ 0xff, 0xdc, 0xcf, 0xb1, 0xc3, 0x2a, 0x44, 0x9d, 0x37, 0xec, 0x8b, 0x0d, 0x7d, 0x37, 0xa5, 0x2f,
+ /*3d30:*/ 0x3c, 0x74, 0xca, 0x90, 0x2c, 0x0c, 0x8f, 0x88, 0x01, 0x48, 0x81, 0x0b, 0x8b, 0xf8, 0xc7, 0xb8,
+ /*3d40:*/ 0x96, 0x45, 0x06, 0x4e, 0x60, 0x04, 0xd8, 0xae, 0x30, 0xcb, 0x6b, 0xf9, 0xdd, 0x0a, 0x31, 0x8d,
+ /*3d50:*/ 0xde, 0x60, 0x42, 0xf3, 0xf1, 0x87, 0x31, 0x85, 0x25, 0x62, 0xcc, 0x92, 0x54, 0x49, 0x96, 0xd5,
+ /*3d60:*/ 0x72, 0xc7, 0xb7, 0xf1, 0x01, 0x0b, 0x30, 0xe5, 0x8b, 0xba, 0x49, 0x05, 0xe0, 0xa2, 0x54, 0xee,
+ /*3d70:*/ 0x45, 0xae, 0xd3, 0x75, 0x35, 0x61, 0x9a, 0x10, 0xee, 0x1f, 0x2a, 0x83, 0xfe, 0x81, 0x0d, 0xc4,
+ /*3d80:*/ 0xc2, 0x35, 0xc9, 0xf0, 0xed, 0x01, 0xf3, 0x5f, 0x9b, 0x66, 0x41, 0xc1, 0x10, 0x04, 0xc3, 0x57,
+ /*3d90:*/ 0x04, 0x74, 0x31, 0x72, 0xd9, 0x15, 0x9d, 0xe6, 0xc9, 0x2e, 0xb9, 0xd0, 0x2c, 0xe5, 0x27, 0x85,
+ /*3da0:*/ 0xa8, 0xe8, 0x8b, 0x44, 0x20, 0x99, 0x1e, 0x12, 0x33, 0xff, 0x4c, 0xa1, 0x59, 0x2c, 0x44, 0xd2,
+ /*3db0:*/ 0x51, 0x94, 0xa1, 0xc1, 0x65, 0xe8, 0x77, 0xad, 0xf7, 0x2c, 0x3c, 0x1b, 0xeb, 0x85, 0x31, 0x7e,
+ /*3dc0:*/ 0x7a, 0x3d, 0xe3, 0x49, 0xc3, 0xe7, 0x8f, 0xe1, 0x39, 0x88, 0x33, 0xd1, 0x8d, 0xf5, 0xec, 0x2c,
+ /*3dd0:*/ 0x43, 0x6a, 0x63, 0x8a, 0xad, 0x7b, 0x61, 0x8c, 0x55, 0x10, 0x89, 0x2e, 0x50, 0x0c, 0x72, 0x49,
+ /*3de0:*/ 0xad, 0xaf, 0xc4, 0x3f, 0x34, 0xdb, 0xc9, 0x23, 0x90, 0x18, 0xd6, 0x8c, 0xe9, 0xab, 0x5b, 0x01,
+ /*3df0:*/ 0x9c, 0x5d, 0x05, 0x65, 0x5c, 0x14, 0x27, 0x28, 0xa7, 0x42, 0x93, 0xbe, 0xde, 0xd2, 0x3a, 0x1f,
+ /*3e00:*/ 0x3f, 0x32, 0xaf, 0x89, 0x34, 0xfa, 0x7a, 0x0d, 0xdd, 0x66, 0xdc, 0x16, 0x60, 0x69, 0x24, 0x04,
+ /*3e10:*/ 0x1e, 0x9e, 0x55, 0x09, 0x3c, 0x98, 0xb3, 0x95, 0xcc, 0xa4, 0x51, 0xb4, 0x17, 0x80, 0x3a, 0x74,
+ /*3e20:*/ 0x2c, 0x2f, 0x54, 0x28, 0x83, 0xf9, 0xc4, 0x8a, 0x6b, 0x42, 0x57, 0x6c, 0x14, 0xba, 0xca, 0x51,
+ /*3e30:*/ 0x27, 0xeb, 0x90, 0x98, 0x59, 0x84, 0x0c, 0xea, 0x90, 0x6e, 0xf3, 0xb2, 0xc3, 0x50, 0xd2, 0x4e,
+ /*3e40:*/ 0xa0, 0xb3, 0xc0, 0x09, 0x41, 0x59, 0xb5, 0x18, 0x0e, 0x14, 0x27, 0xb1, 0x95, 0x21, 0x0c, 0xe7,
+ /*3e50:*/ 0x24, 0x79, 0x62, 0x9c, 0x90, 0xe5, 0x44, 0x98, 0x7b, 0x5f, 0xba, 0x46, 0x5f, 0x61, 0xbb, 0x25,
+ /*3e60:*/ 0xd3, 0x3b, 0x63, 0xdf, 0xc4, 0x76, 0xce, 0x55, 0x4d, 0xaf, 0x69, 0xfd, 0xab, 0xaa, 0x2c, 0x52,
+ /*3e70:*/ 0xaa, 0x20, 0x38, 0x7e, 0x29, 0x4a, 0x7d, 0x09, 0xee, 0xa8, 0x77, 0xe0, 0xed, 0x54, 0x64, 0x50,
+ /*3e80:*/ 0x19, 0x1f, 0xc7, 0x34, 0x79, 0xbf, 0x06, 0xf9, 0xac, 0x61, 0x6a, 0xd7, 0x8e, 0xb0, 0x65, 0x4d,
+ /*3e90:*/ 0xa0, 0xc1, 0x9a, 0xbb, 0x44, 0xbd, 0x30, 0xa0, 0xfb, 0xf5, 0x35, 0x91, 0xa7, 0x09, 0xbb, 0x48,
+ /*3ea0:*/ 0x4f, 0x94, 0x33, 0xe2, 0x3d, 0x79, 0xc0, 0x0b, 0x27, 0x42, 0x9f, 0x7c, 0x4c, 0x1a, 0xe5, 0x17,
+ /*3eb0:*/ 0xb2, 0xdf, 0xa3, 0x87, 0x4b, 0x76, 0xd3, 0x78, 0x24, 0x6b, 0xd4, 0x54, 0x7e, 0x73, 0x37, 0x2b,
+ /*3ec0:*/ 0xe1, 0xbe, 0xba, 0xbd, 0x6b, 0xb4, 0x5c, 0x7b, 0xba, 0xbc, 0x98, 0x65, 0xcb, 0xdf, 0xb9, 0x99,
+ /*3ed0:*/ 0x25, 0xeb, 0xe5, 0x93, 0xff, 0x8f, 0x82, 0x6c, 0x5f, 0x6b, 0xde, 0x47, 0xb7, 0x16, 0x92, 0x81,
+ /*3ee0:*/ 0x7c, 0x77, 0xe3, 0x0b, 0x6f, 0xf2, 0x9a, 0xa0, 0x98, 0xf4, 0xf5, 0xcd, 0x6e, 0xf4, 0x64, 0x65,
+ /*3ef0:*/ 0xc2, 0x87, 0x85, 0x54, 0x32, 0x11, 0x37, 0xde, 0xfb, 0x7e, 0x51, 0x64, 0x4b, 0x7f, 0x57, 0x34,
+ /*3f00:*/ 0x1c, 0xa3, 0x37, 0x11, 0x1e, 0x66, 0x43, 0xf5, 0x6d, 0x4d, 0x08, 0x94, 0x7c, 0x79, 0xb7, 0xfe,
+ /*3f10:*/ 0x20, 0x78, 0x2e, 0x19, 0x49, 0xf6, 0x3b, 0x86, 0xe4, 0xa1, 0xc5, 0x65, 0xef, 0xa9, 0x97, 0x55,
+ /*3f20:*/ 0x37, 0xed, 0x23, 0xd2, 0x5a, 0x14, 0x5a, 0xde, 0x6c, 0xda, 0x50, 0xfb, 0xcb, 0x56, 0x56, 0x8e,
+ /*3f30:*/ 0xf1, 0xd1, 0x18, 0x0d, 0x17, 0x7f, 0x3a, 0xb3, 0x07, 0x25, 0x1a, 0x76, 0x1f, 0xd8, 0x67, 0x97,
+ /*3f40:*/ 0x43, 0xfa, 0x02, 0xa8, 0x7c, 0x6d, 0x56, 0xb1, 0xd4, 0xba, 0x1d, 0x06, 0x60, 0x86, 0x66, 0xd6,
+ /*3f50:*/ 0xd5, 0x1b, 0x5e, 0x64, 0xf5, 0x02, 0x44, 0xa4, 0x8d, 0x21, 0x27, 0xd2, 0x16, 0xe4, 0xd9, 0xad,
+ /*3f60:*/ 0xac, 0x08, 0x12, 0x81, 0xd6, 0xe4, 0x4e, 0x68, 0xe4, 0xaf, 0x62, 0x8c, 0x7e, 0xef, 0x42, 0xa9,
+ /*3f70:*/ 0xff, 0x3f, 0x3b, 0x6c, 0x9f, 0xec, 0xa5, 0x9c, 0xf5, 0xf8, 0x4f, 0xa9, 0x37, 0x79, 0x86, 0x92,
+ /*3f80:*/ 0x2b, 0x6d, 0x75, 0xbc, 0x50, 0x5e, 0x78, 0x1c, 0xbe, 0x03, 0xcf, 0x7d, 0x37, 0x21, 0xcf, 0x43,
+ /*3f90:*/ 0x4e, 0x2b, 0x68, 0x7b, 0x77, 0x44, 0x39, 0x85, 0x1b, 0x1c, 0x4a, 0x1f, 0x75, 0x68, 0xa6, 0x9c,
+ /*3fa0:*/ 0x8c, 0x0f, 0x35, 0x78, 0x20, 0x1a, 0xe5, 0xa6, 0x2b, 0xbf, 0x4a, 0x08, 0x04, 0xe5, 0x9d, 0x08,
+ /*3fb0:*/ 0x4f, 0x03, 0x11, 0xc9, 0x08, 0x1a, 0xde, 0xd1, 0x9d, 0x7c, 0x74, 0x49, 0x5d, 0x09, 0xff, 0x38,
+ /*3fc0:*/ 0x29, 0x76, 0xa6, 0xf8, 0x9a, 0xda, 0xda, 0x9a, 0xb6, 0xc9, 0x39, 0x59, 0x62, 0xe1, 0x4b, 0x7f,
+ /*3fd0:*/ 0x11, 0xac, 0xa6, 0x21, 0x85, 0x0b, 0x2a, 0x0e, 0xa6, 0x89, 0x61, 0x00, 0xdc, 0xb0, 0x5a, 0x9b,
+ /*3fe0:*/ 0x1b, 0xbd, 0x44, 0x74, 0x01, 0xbc, 0x31, 0x7f, 0xbb, 0x2f, 0x4c, 0x83, 0x8d, 0xe2, 0x99, 0xea,
+ /*3ff0:*/ 0xad, 0xbb, 0xb4, 0xe5, 0xb6, 0x4d, 0xa8, 0xf6, 0x99, 0xe2, 0x85, 0x27, 0x08, 0x70, 0x84, 0x05,
+ /*4000:*/ 0xed, 0x8d, 0x0e, 0x89, 0x9a, 0x03, 0xc3, 0xe6, 0xa6, 0xe1, 0x8d, 0xc3, 0x2e, 0xdd, 0xc8, 0x53,
+ /*4010:*/ 0xb8, 0xd7, 0x88, 0xf6, 0x88, 0xb2, 0xb4, 0x38, 0xa6, 0xc4, 0xc1, 0x2c, 0x71, 0x41, 0x8f, 0xc3,
+ /*4020:*/ 0x51, 0x77, 0x20, 0x0c, 0xa6, 0x4c, 0xac, 0xcd, 0xf5, 0xae, 0x4c, 0x37, 0x57, 0xf5, 0x1c, 0x09,
+ /*4030:*/ 0xe3, 0xcf, 0x5c, 0x69, 0xed, 0x92, 0x5e, 0xce, 0xf1, 0x83, 0x41, 0xf7, 0xa1, 0x05, 0x3f, 0x56,
+ /*4040:*/ 0x5e, 0x76, 0x06, 0x63, 0xb7, 0x73, 0x2a, 0xe4, 0x83, 0x10, 0xe6, 0x30, 0x7e, 0x9a, 0xd6, 0xc5,
+ /*4050:*/ 0x8d, 0x7f, 0xf8, 0xeb, 0xf6, 0x05, 0x32, 0x24, 0xf1, 0x70, 0xa9, 0x85, 0x69, 0x5c, 0x37, 0x02,
+ /*4060:*/ 0x4a, 0x7e, 0x23, 0xee, 0x91, 0xa2, 0xdd, 0xaa, 0x51, 0x6b, 0x1b, 0x39, 0x76, 0x28, 0x9e, 0xbf,
+ /*4070:*/ 0xe5, 0xd9, 0xfe, 0x0b, 0x89, 0x63, 0xff, 0x47, 0x50, 0x8f, 0x66, 0x0e, 0x96, 0x0f, 0x3d, 0x8c,
+ /*4080:*/ 0xdd, 0x55, 0xfd, 0xae, 0x37, 0x18, 0x71, 0x0e, 0x08, 0x48, 0x65, 0x53, 0xb8, 0x1b, 0x9d, 0xc5,
+ /*4090:*/ 0x1f, 0x0f, 0x9e, 0x9a, 0xcf, 0xfb, 0x37, 0xf0, 0x6e, 0x5c, 0x8b, 0xec, 0x3b, 0x3a, 0xd3, 0xce,
+ /*40a0:*/ 0xc5, 0x94, 0x24, 0x88, 0x0b, 0x6a, 0x03, 0x4c, 0x52, 0xf7, 0xb2, 0x1d, 0x07, 0xae, 0x81, 0x3d,
+ /*40b0:*/ 0xf1, 0xfd, 0x8e, 0xcc, 0x3a, 0x47, 0x6e, 0xa9, 0x19, 0xf7, 0x16, 0x8e, 0x15, 0x93, 0x56, 0x20,
+ /*40c0:*/ 0x7e, 0x67, 0xd3, 0x17, 0xcb, 0xfa, 0x4b, 0xf1, 0x63, 0x02, 0x81, 0x14, 0x1e, 0xbd, 0x73, 0x95,
+ /*40d0:*/ 0xcc, 0xfd, 0x70, 0xa6, 0x30, 0x3e, 0x41, 0x64, 0x5a, 0x12, 0xc6, 0x50, 0x28, 0xf0, 0x83, 0x60,
+ /*40e0:*/ 0xd7, 0xb9, 0x72, 0x1d, 0x87, 0xab, 0x74, 0xf5, 0xb7, 0x30, 0xa1, 0xae, 0x89, 0x76, 0xfe, 0x92,
+ /*40f0:*/ 0x07, 0x34, 0x78, 0x8e, 0x8b, 0xb1, 0x44, 0x85, 0x37, 0xcf, 0xe8, 0x56, 0xe7, 0xaa, 0xa9, 0x70,
+ /*4100:*/ 0xe9, 0x79, 0x59, 0xa6, 0x3c, 0x9d, 0xad, 0xc5, 0x0f, 0x7d, 0x3c, 0x8e, 0xb9, 0xdc, 0xd4, 0xf7,
+ /*4110:*/ 0xe4, 0xcd, 0xa7, 0x27, 0xfd, 0x20, 0x33, 0x9d, 0x64, 0xcd, 0xcc, 0xaf, 0xb9, 0x43, 0xc6, 0x6b,
+ /*4120:*/ 0xcd, 0xaa, 0xf8, 0x8a, 0x97, 0x30, 0x95, 0xcc, 0xf2, 0x9f, 0x70, 0x25, 0x3f, 0x7b, 0x27, 0x0f,
+ /*4130:*/ 0xc2, 0x0f, 0xd7, 0x33, 0xde, 0x08, 0x90, 0xc2, 0x5d, 0xb5, 0xc0, 0x1a, 0x39, 0x86, 0xb3, 0x62,
+ /*4140:*/ 0xeb, 0x19, 0xee, 0x4c, 0x10, 0xe6, 0x75, 0x40, 0x7a, 0x9d, 0x8f, 0x80, 0x39, 0x75, 0x77, 0x37,
+ /*4150:*/ 0x27, 0x4e, 0x36, 0xa6, 0xc6, 0x7a, 0xb9, 0x0d, 0x7c, 0x5c, 0x7f, 0xbc, 0xe5, 0x9c, 0xe2, 0x13,
+ /*4160:*/ 0xfe, 0x3f, 0xc6, 0x30, 0xf8, 0xbb, 0xe6, 0x19, 0xcf, 0x2e, 0xfb, 0x6c, 0x10, 0x38, 0x61, 0x72,
+ /*4170:*/ 0xe3, 0x32, 0xfc, 0xcb, 0x72, 0x88, 0x6b, 0x62, 0x20, 0x32, 0x0b, 0xbc, 0xc3, 0xfd, 0x23, 0x9c,
+ /*4180:*/ 0xad, 0x96, 0xa7, 0xa4, 0x4e, 0x40, 0xfc, 0xac, 0x04, 0xbc, 0x8e, 0x17, 0x43, 0xba, 0x2b, 0xbf,
+ /*4190:*/ 0x0a, 0x5f, 0x2b, 0xaa, 0x74, 0x06, 0x1f, 0x75, 0x8e, 0xa4, 0x57, 0xdf, 0x1e, 0x4c, 0xfa, 0xb9,
+ /*41a0:*/ 0xb4, 0x33, 0x72, 0xd7, 0x88, 0x6b, 0x19, 0xb0, 0x36, 0x76, 0x07, 0xb2, 0x79, 0x77, 0x50, 0xc1,
+ /*41b0:*/ 0xb9, 0xa5, 0x28, 0x8d, 0xc8, 0x70, 0x3d, 0xdf, 0xe9, 0x96, 0x49, 0xf4, 0xbd, 0xed, 0x62, 0x3c,
+ /*41c0:*/ 0xe0, 0x63, 0x41, 0x84, 0x55, 0xef, 0x54, 0x2f, 0xb4, 0x94, 0x7d, 0x32, 0x56, 0x01, 0x04, 0x40,
+ /*41d0:*/ 0x73, 0x43, 0xdd, 0x84, 0xbe, 0xe6, 0x2f, 0xa1, 0xa7, 0xec, 0xed, 0x6f, 0x45, 0xd3, 0x74, 0x58,
+ /*41e0:*/ 0x5f, 0xae, 0x10, 0x4a, 0xe3, 0x7e, 0xc9, 0xca, 0xee, 0xe0, 0x05, 0xc5, 0x95, 0x34, 0xff, 0x5e,
+ /*41f0:*/ 0xda, 0x21, 0xf3, 0x49, 0x80, 0xf8, 0xd8, 0x33, 0x3a, 0x93, 0xab, 0xdd, 0x76, 0xdc, 0x77, 0x06,
+ /*4200:*/ 0x83, 0x9b, 0x67, 0x8a, 0xa0, 0x72, 0x2a, 0x32, 0x24, 0x00, 0x85, 0x1e, 0x27, 0x22, 0x91, 0x85,
+ /*4210:*/ 0xde, 0xb0, 0x9b, 0xc0, 0xa8, 0x03, 0x90, 0x9e, 0xe3, 0x18, 0x64, 0x91, 0x2c, 0xaa, 0x21, 0xbb,
+ /*4220:*/ 0xca, 0x34, 0x42, 0x9c, 0xcd, 0x73, 0x5e, 0xff, 0x7a, 0x9a, 0xc0, 0x1c, 0x6e, 0xb2, 0x45, 0xec,
+ /*4230:*/ 0x09, 0xe4, 0xed, 0x3f, 0xa2, 0xf2, 0x82, 0xa8, 0xa3, 0xc0, 0xd3, 0x4e, 0xbc, 0xe5, 0x11, 0x9b,
+ /*4240:*/ 0x5e, 0x3d, 0x0e, 0x1e, 0xcc, 0x85, 0x4c, 0x5d, 0x97, 0xa6, 0xa2, 0xe7, 0x90, 0xad, 0x0a, 0xf5,
+ /*4250:*/ 0x83, 0x65, 0xc6, 0xcc, 0x4f, 0x52, 0xe0, 0x38, 0xe9, 0x25, 0xa7, 0x83, 0x03, 0x4a, 0x0f, 0x72,
+ /*4260:*/ 0xe5, 0xc9, 0x36, 0x32, 0xb9, 0x7d, 0x58, 0xa2, 0x05, 0x0e, 0x30, 0x13, 0xd3, 0xfc, 0x30, 0x86,
+ /*4270:*/ 0xbd, 0xab, 0x67, 0xcf, 0x86, 0x4d, 0xa5, 0xfe, 0x6d, 0xb5, 0x91, 0x1e, 0xcf, 0x44, 0xc8, 0x40,
+ /*4280:*/ 0x2b, 0xaa, 0x96, 0x33, 0xb5, 0x8e, 0x32, 0x59, 0x0d, 0x0c, 0x6d, 0x91, 0x24, 0x7a, 0x49, 0x1a,
+ /*4290:*/ 0x8d, 0x8f, 0x14, 0xa6, 0x25, 0x35, 0xef, 0x8f, 0xb6, 0x53, 0xaf, 0xe2, 0xa5, 0xa4, 0x3d, 0x19,
+ /*42a0:*/ 0x9e, 0x61, 0x5c, 0x38, 0x60, 0xdc, 0x7a, 0x90, 0xda, 0xb0, 0xc7, 0x78, 0x2d, 0xc9, 0x8e, 0xc4,
+ /*42b0:*/ 0x2a, 0xe5, 0x9d, 0x10, 0x26, 0xef, 0x4f, 0x79, 0xf2, 0xf7, 0x89, 0x79, 0xdb, 0xc1, 0xf3, 0xc3,
+ /*42c0:*/ 0x38, 0x6a, 0xd3, 0x59, 0x31, 0x69, 0xfd, 0xd6, 0x9d, 0x26, 0x54, 0x44, 0x0e, 0x2b, 0xc5, 0x9a,
+ /*42d0:*/ 0x9f, 0x77, 0xb7, 0x73, 0x40, 0xc5, 0xa2, 0x46, 0x3b, 0xb9, 0xb6, 0xab, 0x58, 0x93, 0x88, 0x9c,
+ /*42e0:*/ 0xe5, 0xae, 0x1b, 0x90, 0xf8, 0xdf, 0xdf, 0xd6, 0x4d, 0x2e, 0x3b, 0xeb, 0x3a, 0x6f, 0xe3, 0x28,
+ /*42f0:*/ 0x73, 0x32, 0x71, 0xb3, 0x7c, 0xd8, 0x7a, 0xa2, 0xfc, 0x61, 0x56, 0x2c, 0x89, 0x63, 0x16, 0xbd,
+ /*4300:*/ 0xea, 0xd2, 0x49, 0x1b, 0x43, 0xcf, 0x2a, 0xce, 0xd2, 0x00, 0xe8, 0xef, 0x60, 0xf9, 0x9e, 0x41,
+ /*4310:*/ 0x23, 0xde, 0x64, 0xa1, 0x05, 0x64, 0x55, 0xdb, 0xb0, 0xac, 0x37, 0xd1, 0x41, 0xd4, 0xfa, 0xde,
+ /*4320:*/ 0x9c, 0x18, 0x46, 0x59, 0xac, 0x51, 0xc4, 0xd4, 0xb9, 0x4c, 0x35, 0xfa, 0xcd, 0xfd, 0x23, 0xde,
+ /*4330:*/ 0xa8, 0x5d, 0x7c, 0xdb, 0xa1, 0x1a, 0x99, 0x9d, 0x21, 0x12, 0x81, 0xa8, 0xd1, 0x20, 0xc2, 0xd4,
+ /*4340:*/ 0x6c, 0xe9, 0x8b, 0x16, 0x22, 0x55, 0x5b, 0x0e, 0x1d, 0xde, 0x36, 0x54, 0x96, 0x76, 0x51, 0x36,
+ /*4350:*/ 0x13, 0x4a, 0x9f, 0x0f, 0x42, 0x11, 0xb2, 0x8a, 0x69, 0xec, 0x5b, 0xbd, 0xbd, 0xe6, 0x90, 0x1d,
+ /*4360:*/ 0x6f, 0x36, 0x18, 0x6d, 0x71, 0x18, 0x6b, 0xa0, 0x08, 0x0c, 0x6a, 0xbd, 0xc9, 0xc9, 0x03, 0xbb,
+ /*4370:*/ 0x2b, 0x13, 0xc4, 0x81, 0xd4, 0x98, 0xaa, 0x33, 0xa7, 0x7c, 0x9d, 0x2a, 0xcf, 0xf4, 0xc8, 0x33,
+ /*4380:*/ 0xc8, 0x54, 0x80, 0x2e, 0x85, 0x05, 0xf3, 0x67, 0x34, 0x07, 0xe1, 0x5c, 0x49, 0x4a, 0x72, 0x7e,
+ /*4390:*/ 0x1b, 0x64, 0xc1, 0x66, 0xe8, 0x3d, 0x30, 0x38, 0x8c, 0x58, 0x3c, 0x0f, 0x64, 0x54, 0x9b, 0x1b,
+ /*43a0:*/ 0x5e, 0xb7, 0x87, 0x95, 0xf7, 0x92, 0xbe, 0x4c, 0x42, 0x03, 0x77, 0x74, 0xea, 0x9e, 0xf3, 0x92,
+ /*43b0:*/ 0x94, 0x0d, 0x47, 0x33, 0x23, 0x88, 0x74, 0x71, 0x47, 0xab, 0x1d, 0xd5, 0x92, 0x81, 0x73, 0x66,
+ /*43c0:*/ 0x62, 0xc3, 0x27, 0xe5, 0xe0, 0x84, 0xfa, 0xe4, 0x6a, 0x2e, 0x07, 0xea, 0xdb, 0x44, 0x24, 0xef,
+ /*43d0:*/ 0x8a, 0xb0, 0x5e, 0xb0, 0x61, 0x03, 0x9c, 0xf8, 0xc7, 0xc8, 0x34, 0x1b, 0x87, 0xc7, 0xf1, 0x3b,
+ /*43e0:*/ 0xb5, 0x7e, 0xb7, 0x37, 0x4d, 0x3a, 0xb7, 0x4b, 0x2e, 0x21, 0xe2, 0x3e, 0x0d, 0xe7, 0x07, 0x3c,
+ /*43f0:*/ 0x43, 0xb2, 0x6d, 0x87, 0xa9, 0x79, 0x96, 0x86, 0x0c, 0x0e, 0xbc, 0x0d, 0x5e, 0x5b, 0x9f, 0xbf,
+ /*4400:*/ 0xc0, 0xfe, 0x4b, 0x81, 0xa2, 0x91, 0x39, 0xf9, 0x59, 0xfa, 0x96, 0x80, 0x2a, 0x90, 0x13, 0x4c,
+ /*4410:*/ 0x4e, 0x08, 0x1e, 0xcc, 0xfe, 0x1f, 0x94, 0x2b, 0x1b, 0x3f, 0x80, 0xa2, 0x03, 0xc2, 0xee, 0x37,
+ /*4420:*/ 0x52, 0xa2, 0xb7, 0xfb, 0x2c, 0x42, 0xe6, 0xd9, 0x57, 0xa4, 0xdd, 0x41, 0x02, 0xfc, 0x9f, 0x40,
+ /*4430:*/ 0x62, 0xb8, 0xc6, 0x4b, 0x42, 0xe4, 0xd8, 0x50, 0x47, 0xad, 0xea, 0x55, 0x21, 0xe7, 0xbb, 0xa4,
+ /*4440:*/ 0xf5, 0x07, 0x70, 0x6f, 0xba, 0x7e, 0x30, 0x31, 0x03, 0x15, 0x9d, 0x44, 0x29, 0x16, 0xe0, 0x95,
+ /*4450:*/ 0x67, 0xf0, 0x4b, 0x27, 0x94, 0xaf, 0x48, 0x2f, 0x3d, 0xe8, 0x8c, 0x64, 0x47, 0x32, 0xa0, 0xb7,
+ /*4460:*/ 0x23, 0x27, 0xbf, 0xca, 0xdf, 0x6a, 0xc1, 0x41, 0x19, 0x82, 0xd4, 0x97, 0xee, 0x24, 0xbc, 0x65,
+ /*4470:*/ 0xd3, 0x8b, 0x10, 0xf8, 0x1b, 0x70, 0xe1, 0x5c, 0xeb, 0xa2, 0xa9, 0x89, 0x62, 0xec, 0xaa, 0xf6,
+ /*4480:*/ 0xb1, 0xda, 0xf9, 0xe5, 0x0c, 0x47, 0xa0, 0x06, 0x93, 0x6c, 0x54, 0xea, 0x48, 0x9d, 0x57, 0x90,
+ /*4490:*/ 0x8f, 0x5f, 0xd0, 0x6f, 0x97, 0x2a, 0x64, 0x46, 0x05, 0x22, 0x5a, 0xda, 0xbd, 0xb0, 0x47, 0x73,
+ /*44a0:*/ 0x62, 0x2c, 0x75, 0xcb, 0xed, 0x7d, 0x0b, 0x14, 0x30, 0xb3, 0x78, 0x4c, 0xe7, 0x9c, 0xaf, 0x9b,
+ /*44b0:*/ 0x7a, 0x97, 0xde, 0x12, 0xac, 0x5e, 0x6a, 0x96, 0xd7, 0xfd, 0x8c, 0x3f, 0xe8, 0xed, 0x61, 0x1d,
+ /*44c0:*/ 0x5e, 0xcf, 0xfb, 0xb9, 0x49, 0x80, 0xde, 0x1b, 0xb8, 0x12, 0x81, 0x5a, 0xdb, 0xd6, 0xb7, 0x0f,
+ /*44d0:*/ 0x50, 0xf5, 0x7e, 0xf8, 0xa6, 0xcc, 0xfa, 0x86, 0x25, 0xdb, 0xd1, 0xd1, 0xfb, 0x99, 0xbe, 0x28,
+ /*44e0:*/ 0x60, 0xc9, 0x83, 0xe6, 0x64, 0x56, 0xf6, 0x15, 0x8d, 0xf0, 0xad, 0xd2, 0x3f, 0x6f, 0x18, 0xe8,
+ /*44f0:*/ 0xee, 0x3c, 0x25, 0x52, 0x3f, 0x32, 0x29, 0x99, 0x36, 0xc2, 0x18, 0xb0, 0xea, 0xc5, 0x87, 0x60,
+ /*4500:*/ 0xda, 0xe4, 0x78, 0x89, 0xee, 0xaa, 0x9d, 0x4e, 0xfa, 0xca, 0xe1, 0xbe, 0xda, 0x46, 0x22, 0x28,
+ /*4510:*/ 0x13, 0x0e, 0xf1, 0x8e, 0x15, 0x6d, 0x68, 0x07, 0xc5, 0x0a, 0x41, 0x4f, 0x2d, 0xd6, 0x0c, 0x89,
+ /*4520:*/ 0x13, 0x5b, 0x79, 0x46, 0x0e, 0x14, 0x4d, 0x8a, 0xb1, 0xe0, 0x6e, 0xcc, 0x46, 0xa2, 0x35, 0xa6,
+ /*4530:*/ 0xf0, 0x61, 0x80, 0xe8, 0xd0, 0x24, 0xab, 0x1d, 0xa4, 0x28, 0x93, 0xb8, 0x87, 0xa5, 0xd0, 0xe4,
+ /*4540:*/ 0x9c, 0xfd, 0x29, 0x75, 0x8e, 0x85, 0x20, 0x25, 0xcb, 0xbb, 0x21, 0x20, 0xf9, 0x31, 0x07, 0xaf,
+ /*4550:*/ 0x5d, 0xf7, 0xc1, 0x7f, 0x89, 0xad, 0xab, 0xbf, 0x65, 0xf8, 0x71, 0xb0, 0x7f, 0xd2, 0xad, 0xd1,
+ /*4560:*/ 0x51, 0x48, 0x9f, 0xf0, 0xaa, 0xc0, 0xde, 0x60, 0x40, 0xe4, 0x2b, 0xb5, 0x0e, 0x24, 0xdd, 0xfa,
+ /*4570:*/ 0x0f, 0x52, 0xc3, 0x6e, 0xcc, 0xa2, 0xb9, 0x32, 0x30, 0x92, 0x24, 0x51, 0xb9, 0xff, 0x7d, 0xef,
+ /*4580:*/ 0x5b, 0x6c, 0xf2, 0xde, 0x08, 0x11, 0x94, 0x52, 0xac, 0x53, 0xd3, 0xc5, 0x97, 0xd6, 0xd2, 0x78,
+ /*4590:*/ 0x1c, 0x70, 0xea, 0xd8, 0x81, 0x7f, 0xd6, 0x3b, 0x27, 0x6f, 0x94, 0x59, 0x98, 0xcf, 0x5d, 0x06,
+ /*45a0:*/ 0x9b, 0x97, 0x47, 0xf9, 0x4f, 0x50, 0xb9, 0x56, 0x36, 0xb5, 0xb6, 0xb9, 0xe3, 0xe2, 0xce, 0x63,
+ /*45b0:*/ 0x0c, 0x3f, 0xc5, 0xe1, 0xde, 0x8f, 0xcb, 0x8b, 0x36, 0x8d, 0x8d, 0xb9, 0xa6, 0xfb, 0x1b, 0xe4,
+ /*45c0:*/ 0xe9, 0xea, 0xd0, 0xf0, 0x75, 0x2e, 0x75, 0x58, 0xfc, 0x48, 0x49, 0xad, 0x97, 0x3e, 0xc8, 0xdd,
+ /*45d0:*/ 0x12, 0x78, 0x79, 0xd1, 0xdc, 0xd7, 0x49, 0x05, 0x65, 0x64, 0x26, 0x9e, 0x00, 0xf5, 0x2b, 0xc2,
+ /*45e0:*/ 0x03, 0x74, 0xb3, 0x23, 0x74, 0xd5, 0xb4, 0x4b, 0xb4, 0x6e, 0x0e, 0x1e, 0xb3, 0xae, 0x14, 0xe2,
+ /*45f0:*/ 0xe8, 0xfb, 0xc2, 0xf6, 0xd5, 0x99, 0xd2, 0x90, 0x27, 0x13, 0xf9, 0x20, 0x7b, 0xd0, 0x76, 0x95,
+ /*4600:*/ 0x67, 0x45, 0x7a, 0x9b, 0x3c, 0x41, 0xc0, 0x6e, 0x6c, 0x2f, 0x0a, 0xe9, 0xcc, 0xa5, 0x8b, 0x41,
+ /*4610:*/ 0x8c, 0x27, 0xd6, 0xce, 0xde, 0x8f, 0x02, 0xd3, 0xad, 0xd5, 0x88, 0x19, 0xbb, 0xeb, 0xb8, 0x3c,
+ /*4620:*/ 0x45, 0xea, 0xff, 0xe8, 0x10, 0x93, 0xaf, 0xab, 0x24, 0xff, 0x10, 0x8e, 0x60, 0x92, 0x88, 0x0c,
+ /*4630:*/ 0x42, 0x17, 0xf4, 0x42, 0xbc, 0x7e, 0xfe, 0xbf, 0x14, 0x09, 0x6f, 0xff, 0xa2, 0x42, 0x43, 0x97,
+ /*4640:*/ 0x5f, 0x24, 0xae, 0xa1, 0xcf, 0x48, 0xe6, 0x35, 0x3f, 0x12, 0x55, 0x38, 0x0a, 0x91, 0x05, 0x46,
+ /*4650:*/ 0x9d, 0x80, 0xb3, 0x75, 0x24, 0x64, 0x19, 0x8e, 0xea, 0x65, 0x94, 0x22, 0xfe, 0x6c, 0xa4, 0x82,
+ /*4660:*/ 0x16, 0x96, 0x7f, 0x57, 0x4b, 0x72, 0x54, 0x9e, 0x84, 0x22, 0x06, 0x64, 0x24, 0xe1, 0x50, 0xc7,
+ /*4670:*/ 0x78, 0xb8, 0xa4, 0xb4, 0xfe, 0x60, 0xa1, 0x0c, 0xf6, 0xba, 0xdd, 0x93, 0x0f, 0xf5, 0x36, 0xe2,
+ /*4680:*/ 0xb6, 0x9c, 0xd3, 0xc8, 0x96, 0xb4, 0xd2, 0x02, 0x38, 0x42, 0x9a, 0x2f, 0x1b, 0x46, 0xd2, 0x20,
+ /*4690:*/ 0xc6, 0x90, 0xd5, 0xd4, 0x42, 0xf0, 0xd5, 0x14, 0xd1, 0xb1, 0xec, 0x02, 0x41, 0x25, 0xbb, 0x35,
+ /*46a0:*/ 0x0b, 0x9a, 0x66, 0x1d, 0xc8, 0xf9, 0xc1, 0x6a, 0x59, 0xfc, 0xc5, 0x57, 0xda, 0xdf, 0xe2, 0x8a,
+ /*46b0:*/ 0x8b, 0x1b, 0x21, 0x1d, 0x45, 0x76, 0x57, 0x8a, 0x0c, 0xd8, 0x21, 0xa0, 0x34, 0x42, 0xeb, 0xa7,
+ /*46c0:*/ 0x01, 0x62, 0x5f, 0x5d, 0xf5, 0x12, 0x44, 0x42, 0x4a, 0xb1, 0x2c, 0x9a, 0x44, 0x79, 0x9e, 0x6b,
+ /*46d0:*/ 0xde, 0xbf, 0x13, 0x8c, 0x22, 0x4f, 0xe7, 0x50, 0xd4, 0x0a, 0x18, 0x4f, 0x50, 0xf0, 0xbb, 0x16,
+ /*46e0:*/ 0xf5, 0x57, 0x2c, 0xd8, 0x66, 0x3f, 0x83, 0x62, 0xe8, 0x5a, 0xd4, 0x05, 0x67, 0xe0, 0xa7, 0x40,
+ /*46f0:*/ 0x08, 0xc3, 0x9e, 0x5b, 0xbb, 0x3a, 0xd3, 0x44, 0x15, 0xa6, 0xb3, 0x12, 0xea, 0x89, 0xd9, 0xbc,
+ /*4700:*/ 0xc1, 0xc8, 0x01, 0x39, 0x1c, 0xc7, 0xc0, 0xfa, 0xea, 0x85, 0xf9, 0x27, 0xe9, 0x10, 0x93, 0x49,
+ /*4710:*/ 0x5e, 0xa2, 0xb2, 0x40, 0xf3, 0x6f, 0xd1, 0xfb, 0x67, 0xfa, 0x1e, 0x44, 0xc5, 0x7d, 0x49, 0xbe,
+ /*4720:*/ 0xeb, 0xff, 0x2b, 0x0d, 0xcd, 0x82, 0xd5, 0x42, 0xd1, 0xf2, 0x26, 0x78, 0x8e, 0xec, 0x67, 0x01,
+ /*4730:*/ 0xb0, 0x5f, 0x0b, 0x28, 0x59, 0x49, 0x8d, 0x2d, 0x77, 0x30, 0x77, 0xfb, 0xf0, 0x1b, 0x1a, 0x83,
+ /*4740:*/ 0x93, 0x22, 0x0c, 0x92, 0xa5, 0x74, 0xbb, 0xe2, 0xa6, 0xe5, 0x9e, 0x86, 0x6c, 0x34, 0xee, 0x28,
+ /*4750:*/ 0xec, 0x81, 0xdc, 0x1f, 0x78, 0x54, 0x2c, 0x5a, 0xe6, 0xdf, 0x37, 0x61, 0xd1, 0x9b, 0x75, 0x87,
+ /*4760:*/ 0xc8, 0xe7, 0x9e, 0x1a, 0x26, 0x82, 0x16, 0xaa, 0x4e, 0x0a, 0xfc, 0xc1, 0xa6, 0xf3, 0xb6, 0xaf,
+ /*4770:*/ 0x1f, 0xff, 0xc2, 0xb4, 0xb7, 0x33, 0x13, 0xb3, 0xc4, 0xc7, 0x7d, 0xb1, 0xd3, 0x69, 0x5c, 0x8e,
+ /*4780:*/ 0xe7, 0x49, 0x52, 0x47, 0x16, 0x28, 0x14, 0x4a, 0x54, 0xb5, 0xe3, 0xa8, 0x62, 0x2d, 0x22, 0xb1,
+ /*4790:*/ 0x78, 0xe2, 0x15, 0x63, 0x6f, 0x0f, 0x7e, 0x5c, 0x3b, 0xc3, 0x12, 0xfd, 0x67, 0x62, 0x24, 0x12,
+ /*47a0:*/ 0x96, 0x75, 0x30, 0x87, 0x77, 0x81, 0x49, 0xa8, 0x95, 0x3b, 0x94, 0xb8, 0x32, 0x24, 0x65, 0xe5,
+ /*47b0:*/ 0xd7, 0x05, 0x07, 0xf4, 0xa2, 0xc7, 0x67, 0x1d, 0x0a, 0xc4, 0xee, 0x25, 0xf9, 0x6a, 0xc2, 0xf3,
+ /*47c0:*/ 0x06, 0xd9, 0xcc, 0x48, 0x0f, 0x85, 0xb0, 0x93, 0xdb, 0x27, 0x46, 0xfe, 0xc7, 0x8d, 0xcb, 0x02,
+ /*47d0:*/ 0xd5, 0xad, 0x0c, 0x18, 0xc1, 0x19, 0xab, 0xd5, 0xd9, 0xbf, 0x7a, 0xfe, 0xc1, 0x27, 0x80, 0xca,
+ /*47e0:*/ 0xca, 0x14, 0x1f, 0x4f, 0x64, 0xfb, 0xe5, 0x03, 0x28, 0x16, 0xa2, 0xc9, 0x09, 0x93, 0xdd, 0x40,
+ /*47f0:*/ 0xc3, 0x2f, 0x46, 0xd5, 0xcf, 0x29, 0xe0, 0x9c, 0xab, 0x0a, 0x5b, 0xab, 0xbd, 0x0e, 0x28, 0x16,
+ /*4800:*/ 0xc6, 0x5d, 0x3f, 0x5e, 0x41, 0x5a, 0x35, 0xd0, 0x3b, 0x9f, 0x49, 0x25, 0x00, 0x4b, 0x81, 0xda,
+ /*4810:*/ 0x04, 0xd4, 0x03, 0xe3, 0xd8, 0xb3, 0x51, 0xba, 0x4c, 0xe2, 0x1c, 0xb8, 0x9a, 0xaa, 0x0d, 0x00,
+ /*4820:*/ 0x21, 0x93, 0x0a, 0xcb, 0xa4, 0x1e, 0xf9, 0x50, 0x9f, 0xf0, 0xa3, 0x01, 0x84, 0xf1, 0xcf, 0x7f,
+ /*4830:*/ 0x93, 0x19, 0xbd, 0x53, 0x0c, 0xd1, 0x89, 0xe6, 0x2f, 0x10, 0x80, 0x91, 0x33, 0xb7, 0x99, 0xaa,
+ /*4840:*/ 0xe1, 0x26, 0xf7, 0xde, 0x76, 0x09, 0xf6, 0x45, 0x89, 0x33, 0xd0, 0xf0, 0xf8, 0xf6, 0xd4, 0x59,
+ /*4850:*/ 0x94, 0xf9, 0x06, 0xe5, 0x7c, 0xb4, 0x61, 0xac, 0x2f, 0x9a, 0x8e, 0x2d, 0x28, 0x37, 0x11, 0x3a,
+ /*4860:*/ 0x1d, 0xf7, 0x06, 0x79, 0x52, 0x8b, 0xa9, 0xd9, 0xa8, 0x89, 0xfc, 0xb4, 0xbf, 0xbe, 0x56, 0xfd,
+ /*4870:*/ 0x8a, 0x62, 0x89, 0x21, 0x6a, 0x58, 0x03, 0x22, 0x43, 0x56, 0x33, 0xca, 0x3e, 0x2a, 0x87, 0x66,
+ /*4880:*/ 0x16, 0xda, 0xb5, 0x96, 0x51, 0x86, 0xb9, 0x7e, 0x6d, 0xb5, 0xb5, 0xb2, 0x57, 0x5b, 0x75, 0xd5,
+ /*4890:*/ 0xd5, 0xc2, 0x72, 0x7b, 0x9e, 0xa5, 0xab, 0x45, 0x71, 0x77, 0x87, 0xc8, 0xb7, 0x0d, 0xbd, 0xea,
+ /*48a0:*/ 0x29, 0xd1, 0xc3, 0x15, 0x55, 0xa5, 0x16, 0x4c, 0x38, 0xa8, 0x86, 0x66, 0xd5, 0x7a, 0xf4, 0x47,
+ /*48b0:*/ 0x63, 0xb5, 0x01, 0x99, 0xec, 0xbb, 0x7e, 0x72, 0x4d, 0x6c, 0x49, 0x55, 0xde, 0xc1, 0xfa, 0xd9,
+ /*48c0:*/ 0x34, 0x60, 0x48, 0x48, 0x14, 0x9d, 0xb9, 0x9e, 0x5f, 0x2b, 0x7b, 0xbd, 0x68, 0x6a, 0xb2, 0x6d,
+ /*48d0:*/ 0xc6, 0x0b, 0x89, 0xbb, 0x84, 0xdd, 0x33, 0x5c, 0xc1, 0x36, 0x5e, 0xeb, 0x71, 0x39, 0x32, 0xd3,
+ /*48e0:*/ 0xdf, 0xdd, 0xd4, 0x46, 0x8d, 0x63, 0xaa, 0xea, 0x47, 0xc4, 0x15, 0x01, 0xe3, 0x37, 0xfc, 0x91,
+ /*48f0:*/ 0x92, 0xca, 0x90, 0xb5, 0xa0, 0x8d, 0xd7, 0xdb, 0x7a, 0xe2, 0x9d, 0x82, 0x7f, 0xb7, 0x40, 0x72,
+ /*4900:*/ 0xfb, 0x5e, 0xc9, 0x5a, 0xf9, 0xcf, 0xa8, 0x9f, 0x42, 0xa6, 0x66, 0xa6, 0x91, 0x41, 0x6c, 0xf8,
+ /*4910:*/ 0x59, 0xbf, 0x9e, 0xbb, 0x62, 0xab, 0x05, 0x1f, 0x19, 0x6e, 0x5f, 0x23, 0x48, 0x85, 0xa7, 0xaf,
+ /*4920:*/ 0xeb, 0x26, 0x7f, 0xb3, 0x42, 0xfe, 0x37, 0xd6, 0xa0, 0x9f, 0x47, 0xb3, 0x3a, 0x05, 0x6c, 0x78,
+ /*4930:*/ 0x08, 0x5d, 0xaa, 0x19, 0x37, 0xff, 0x69, 0x0d, 0x96, 0x2a, 0xd2, 0x8a, 0x0d, 0x7f, 0xbf, 0x5b,
+ /*4940:*/ 0x26, 0x40, 0x3e, 0x47, 0x30, 0xb5, 0xc1, 0x48, 0xa5, 0x4e, 0x76, 0xae, 0x8d, 0xba, 0x5b, 0x0b,
+ /*4950:*/ 0x22, 0xef, 0xdf, 0xa5, 0x33, 0xc6, 0xe9, 0x79, 0x5d, 0x1e, 0x6a, 0xec, 0xa2, 0xa6, 0xfa, 0x5f,
+ /*4960:*/ 0xac, 0x42, 0x67, 0x60, 0x06, 0x65, 0x6b, 0xf2, 0x3d, 0xbf, 0x92, 0x54, 0xfb, 0xe8, 0x7e, 0x1a,
+ /*4970:*/ 0xb5, 0x9b, 0x57, 0x86, 0x21, 0xc4, 0x80, 0x50, 0x54, 0xe7, 0xfc, 0x10, 0x9c, 0xb5, 0xde, 0x50,
+ /*4980:*/ 0x13, 0x92, 0x3a, 0x85, 0x09, 0xd3, 0x02, 0xa2, 0xf0, 0x38, 0xf0, 0x6d, 0x98, 0x9a, 0x59, 0x92,
+ /*4990:*/ 0xad, 0x89, 0x0d, 0xfd, 0xdf, 0x84, 0xbb, 0x77, 0x2d, 0x4c, 0xbb, 0x8c, 0xa5, 0xe2, 0xea, 0x45,
+ /*49a0:*/ 0xfd, 0x40, 0x07, 0xbc, 0xa0, 0xf0, 0x84, 0x48, 0x17, 0xd2, 0x58, 0x94, 0xbf, 0x89, 0x04, 0x7e,
+ /*49b0:*/ 0x6e, 0xc9, 0x7a, 0xcc, 0x4a, 0x65, 0xf7, 0xb4, 0xf4, 0x2f, 0xae, 0x6e, 0xae, 0x7f, 0x1c, 0xa7,
+ /*49c0:*/ 0xda, 0xce, 0x73, 0xda, 0x7c, 0x9c, 0xed, 0x7c, 0x5c, 0xc6, 0x56, 0x8b, 0xc7, 0xc1, 0x53, 0xb4,
+ /*49d0:*/ 0x5a, 0x30, 0x70, 0x09, 0xd7, 0xdd, 0x20, 0xd0, 0x2a, 0x47, 0x82, 0xb2, 0xa1, 0xd5, 0x69, 0x0a,
+ /*49e0:*/ 0xc1, 0xf8, 0xe9, 0x69, 0x60, 0x17, 0x3f, 0x4c, 0x79, 0x92, 0x33, 0x16, 0x92, 0xbf, 0x4a, 0x73,
+ /*49f0:*/ 0x7f, 0x0a, 0xd1, 0x96, 0x83, 0x53, 0x1c, 0x01, 0x01, 0x5d, 0xe4, 0xf1, 0xe3, 0xa1, 0xc4, 0x91,
+ /*4a00:*/ 0x71, 0x14, 0xbf, 0x60, 0x5a, 0xf5, 0x95, 0x0a, 0x45, 0x35, 0x39, 0x81, 0xea, 0xd4, 0x66, 0x69,
+ /*4a10:*/ 0xa6, 0x12, 0x6d, 0xa8, 0xb8, 0x32, 0x92, 0x1b, 0xa4, 0x59, 0x46, 0x6c, 0x8c, 0xed, 0xc0, 0x4c,
+ /*4a20:*/ 0x55, 0x99, 0xb3, 0xc1, 0x51, 0xfa, 0x30, 0xf0, 0x54, 0x2f, 0x6e, 0x7d, 0xbc, 0xb3, 0x9a, 0x9d,
+ /*4a30:*/ 0x27, 0x42, 0x30, 0xbf, 0x0e, 0x41, 0x87, 0x65, 0x70, 0x10, 0xbc, 0xf1, 0x4b, 0x3e, 0x64, 0x48,
+ /*4a40:*/ 0x88, 0xfb, 0xfa, 0x1b, 0x9a, 0xcb, 0xf5, 0xf7, 0x5c, 0xf8, 0xcc, 0xb2, 0xad, 0xc7, 0x96, 0x16,
+ /*4a50:*/ 0x36, 0xe4, 0x8c, 0x23, 0x21, 0x38, 0x60, 0x6c, 0x6d, 0xaa, 0xef, 0xc9, 0x26, 0xde, 0x1f, 0x17,
+ /*4a60:*/ 0xad, 0x4a, 0xa6, 0xbb, 0xcb, 0xce, 0x76, 0x40, 0x5e, 0x86, 0xdb, 0x97, 0x1f, 0x70, 0x86, 0xf7,
+ /*4a70:*/ 0x8f, 0xf8, 0x11, 0x39, 0x03, 0xc7, 0x0c, 0xcc, 0x71, 0x29, 0x00, 0x2a, 0x4e, 0x62, 0x49, 0xad,
+ /*4a80:*/ 0xb0, 0xfa, 0xfb, 0x80, 0x2e, 0xe8, 0x70, 0x73, 0x57, 0x42, 0xd3, 0xc0, 0x68, 0x7e, 0xaa, 0x0a,
+ /*4a90:*/ 0xdb, 0x99, 0x89, 0x07, 0x8a, 0x6d, 0x4c, 0x9c, 0xbc, 0x33, 0x4f, 0xee, 0x7f, 0x27, 0x45, 0x0f,
+ /*4aa0:*/ 0x7f, 0x16, 0xcb, 0x5b, 0xd7, 0x88, 0x9a, 0xbf, 0x4b, 0x98, 0x01, 0x1c, 0xaf, 0x06, 0x7f, 0x1e,
+ /*4ab0:*/ 0x4d, 0x07, 0x70, 0xb8, 0x7f, 0xac, 0xbb, 0x79, 0xc3, 0x10, 0x01, 0xbc, 0x43, 0x97, 0x46, 0x38,
+ /*4ac0:*/ 0x6e, 0x96, 0x82, 0x31, 0xe6, 0x2e, 0xa0, 0x56, 0xd6, 0xfa, 0xce, 0x3c, 0x43, 0xcd, 0xfe, 0x63,
+ /*4ad0:*/ 0x3d, 0xd8, 0x48, 0x28, 0x8d, 0x80, 0xb8, 0xe3, 0xfd, 0x3b, 0x74, 0x90, 0xbd, 0x64, 0x2d, 0x3f,
+ /*4ae0:*/ 0x18, 0x94, 0x39, 0x9c, 0x52, 0x8a, 0x6b, 0x88, 0x7b, 0xd2, 0xa7, 0x89, 0x16, 0x7b, 0x89, 0x45,
+ /*4af0:*/ 0xdd, 0x0e, 0xf1, 0xc7, 0xc4, 0x9b, 0xb8, 0x90, 0xb8, 0x97, 0x93, 0x4f, 0x98, 0x49, 0xef, 0xef,
+ /*4b00:*/ 0x0a, 0x78, 0xc9, 0xaf, 0xc3, 0xe2, 0xb6, 0x9c, 0x22, 0x69, 0x8b, 0x86, 0xff, 0x76, 0x04, 0x60,
+ /*4b10:*/ 0xab, 0x35, 0x92, 0x1c, 0xa8, 0xac, 0xdd, 0x99, 0x09, 0xdf, 0x97, 0xfe, 0x25, 0x86, 0x0a, 0x43,
+ /*4b20:*/ 0xdd, 0x5c, 0xee, 0x40, 0xdf, 0x68, 0x7b, 0x87, 0x70, 0xd0, 0x45, 0xa9, 0x9c, 0xd8, 0x19, 0xca,
+ /*4b30:*/ 0xfd, 0x08, 0x4a, 0xfc, 0x26, 0xfb, 0xb0, 0x3d, 0xab, 0xf9, 0x04, 0x77, 0x26, 0xc9, 0x18, 0x45,
+ /*4b40:*/ 0xdf, 0xf5, 0xed, 0x8a, 0xb6, 0x9a, 0x08, 0x2d, 0xa9, 0xb3, 0xd1, 0xea, 0x82, 0xfd, 0x5c, 0xbf,
+ /*4b50:*/ 0x32, 0x90, 0xc7, 0x2d, 0x01, 0xf9, 0x56, 0xb0, 0x6b, 0xfe, 0x7a, 0xe2, 0x03, 0x90, 0x48, 0x60,
+ /*4b60:*/ 0xdc, 0x0b, 0xc9, 0x2f, 0x95, 0xe6, 0x0b, 0x73, 0xb5, 0xeb, 0x3d, 0xfe, 0xbe, 0x7e, 0x89, 0x24,
+ /*4b70:*/ 0x15, 0x68, 0x08, 0x86, 0x38, 0xad, 0x27, 0x55, 0x9a, 0x56, 0x58, 0x06, 0x0a, 0x4b, 0x78, 0xde,
+ /*4b80:*/ 0x94, 0xb0, 0xa5, 0x95, 0x10, 0x85, 0x63, 0x8e, 0xcb, 0xd2, 0x26, 0x35, 0x14, 0xa3, 0x1d, 0xd8,
+ /*4b90:*/ 0x62, 0xc0, 0x42, 0x4c, 0xa4, 0xad, 0x9e, 0x59, 0x50, 0xf8, 0xcf, 0x55, 0xb8, 0x01, 0xfe, 0x68,
+ /*4ba0:*/ 0x92, 0x08, 0x8b, 0x8d, 0xd8, 0xab, 0x1d, 0xed, 0xec, 0x01, 0xbc, 0xf5, 0xe3, 0x7c, 0x5c, 0x13,
+ /*4bb0:*/ 0xef, 0x7d, 0x14, 0x21, 0xd1, 0x8e, 0x9b, 0xe4, 0x34, 0x78, 0x59, 0x45, 0x9c, 0x86, 0x37, 0xc2,
+ /*4bc0:*/ 0x24, 0xd1, 0xeb, 0x14, 0x83, 0x0a, 0x80, 0xde, 0x45, 0xa1, 0x17, 0x41, 0xd1, 0x36, 0x1e, 0x95,
+ /*4bd0:*/ 0x4d, 0x00, 0x13, 0x2d, 0x15, 0x7d, 0x4b, 0x52, 0x90, 0x32, 0x12, 0xc2, 0x7d, 0x72, 0xaa, 0x2a,
+ /*4be0:*/ 0x16, 0x54, 0x08, 0xb7, 0x2b, 0x86, 0xa5, 0xa6, 0x62, 0x2c, 0x8a, 0x0d, 0xd8, 0x50, 0x89, 0xf9,
+ /*4bf0:*/ 0xb2, 0x52, 0xd2, 0xd9, 0xa2, 0xa3, 0x21, 0x14, 0x87, 0x89, 0xe1, 0xe7, 0xce, 0xf0, 0x5f, 0xd8,
+ /*4c00:*/ 0x75, 0x61, 0xd6, 0x66, 0xcf, 0xda, 0x00, 0x21, 0xa6, 0xf0, 0xb4, 0x41, 0xcf, 0xf4, 0x71, 0x51,
+ /*4c10:*/ 0xba, 0x27, 0x32, 0x7c, 0x3c, 0xb6, 0xc8, 0x29, 0x53, 0x1f, 0xc5, 0xc1, 0xfd, 0x9f, 0xa8, 0x08,
+ /*4c20:*/ 0x30, 0x51, 0x7f, 0xf6, 0x8b, 0x6a, 0xa2, 0xbe, 0xd4, 0xf5, 0x15, 0xaf, 0x49, 0x19, 0xb9, 0x8e,
+ /*4c30:*/ 0x19, 0xfc, 0x70, 0x0c, 0x28, 0xdc, 0xee, 0x85, 0xb7, 0x5b, 0xde, 0x02, 0xdd, 0x85, 0x8c, 0x9b,
+ /*4c40:*/ 0x78, 0x13, 0x35, 0x1b, 0xd2, 0xe8, 0xcf, 0x9a, 0xc1, 0x3d, 0x21, 0xa2, 0xc5, 0x34, 0xdd, 0x9e,
+ /*4c50:*/ 0x6f, 0xeb, 0xc4, 0x82, 0x18, 0xd8, 0x5a, 0x31, 0x4a, 0x75, 0x45, 0xc9, 0x6f, 0x56, 0x63, 0x1f,
+ /*4c60:*/ 0xc9, 0x4d, 0x35, 0x74, 0x58, 0x31, 0xf1, 0x3e, 0xd7, 0xc5, 0x95, 0xf7, 0x29, 0x4f, 0x24, 0xf7,
+ /*4c70:*/ 0xd9, 0xba, 0xb6, 0x43, 0x34, 0x69, 0x34, 0x04, 0xf0, 0xac, 0x4c, 0x08, 0xed, 0xf9, 0xf4, 0xe3,
+ /*4c80:*/ 0xdc, 0xc5, 0x3e, 0x4f, 0x65, 0xde, 0xba, 0xb3, 0xaf, 0x6f, 0x1a, 0x1f, 0x21, 0x00, 0x80, 0xc2,
+ /*4c90:*/ 0x7c, 0x54, 0x55, 0x35, 0x05, 0x23, 0x65, 0x8c, 0x1a, 0x19, 0x2e, 0xd8, 0x4f, 0xfb, 0xb9, 0xfa,
+ /*4ca0:*/ 0x73, 0x5f, 0x33, 0x0e, 0xfb, 0x32, 0xf5, 0x84, 0x5e, 0xd1, 0x5d, 0x0c, 0x6d, 0x6b, 0x06, 0xc6,
+ /*4cb0:*/ 0x09, 0x5b, 0x14, 0x40, 0x84, 0x68, 0xca, 0x4e, 0xf3, 0xd0, 0xe0, 0x98, 0x86, 0xbe, 0xb8, 0x60,
+ /*4cc0:*/ 0x8c, 0xf6, 0xf3, 0x0e, 0xec, 0x70, 0xea, 0x53, 0x19, 0x2c, 0xfb, 0x69, 0x00, 0x37, 0x06, 0x36,
+ /*4cd0:*/ 0x3b, 0xee, 0xf1, 0x9e, 0xcb, 0xdb, 0x03, 0x00, 0x25, 0x35, 0xa1, 0x7b, 0xb2, 0x79, 0xce, 0x53,
+ /*4ce0:*/ 0xfe, 0xcb, 0x3c, 0x99, 0xde, 0x50, 0x5a, 0x26, 0xa0, 0xe4, 0x28, 0x96, 0xf6, 0x8d, 0x30, 0x97,
+ /*4cf0:*/ 0xcd, 0x6e, 0xbb, 0xb0, 0x70, 0x29, 0x60, 0xe8, 0x48, 0x1b, 0xe9, 0xfb, 0xa4, 0x29, 0xea, 0x52,
+ /*4d00:*/ 0x8f, 0x76, 0x77, 0x1a, 0xdb, 0xcd, 0x39, 0x7a, 0xcf, 0x9d, 0x66, 0xf3, 0x06, 0x9a, 0xb9, 0x80,
+ /*4d10:*/ 0xb7, 0xe7, 0xab, 0xbd, 0xe3, 0xbe, 0x33, 0xb2, 0x3a, 0x4b, 0x43, 0xc5, 0xa8, 0x91, 0x1c, 0xba,
+ /*4d20:*/ 0x89, 0xd4, 0x2b, 0xba, 0xfb, 0x91, 0xe0, 0x27, 0xf5, 0x57, 0xd8, 0x2d, 0x7b, 0xad, 0x3d, 0x0d,
+ /*4d30:*/ 0x2c, 0x21, 0xf8, 0x3a, 0x6a, 0x86, 0xbf, 0x66, 0x35, 0xb2, 0x3a, 0x55, 0xb7, 0x41, 0xf2, 0x8c,
+ /*4d40:*/ 0x82, 0x2f, 0xf9, 0x36, 0x5e, 0x63, 0xfe, 0x15, 0x23, 0x61, 0xa4, 0xee, 0x53, 0x45, 0xd3, 0xdc,
+ /*4d50:*/ 0xc5, 0x1b, 0xce, 0xb7, 0x3c, 0x23, 0x6d, 0x40, 0xa1, 0x28, 0x05, 0x0f, 0xd0, 0xb8, 0x9b, 0x48,
+ /*4d60:*/ 0xb3, 0xe1, 0x91, 0xe1, 0x0e, 0xe5, 0xd3, 0x7e, 0xaa, 0x7a, 0xad, 0xa1, 0xcb, 0xa9, 0x06, 0x4a,
+ /*4d70:*/ 0x22, 0x57, 0xa1, 0x7b, 0xd9, 0xf5, 0x09, 0x48, 0x09, 0x34, 0x88, 0xcf, 0xfd, 0xf8, 0xdd, 0x3d,
+ /*4d80:*/ 0xc2, 0x7c, 0x5b, 0x36, 0xb0, 0x53, 0x2f, 0x5f, 0x41, 0x3e, 0x15, 0x71, 0xb0, 0x06, 0x18, 0x68,
+ /*4d90:*/ 0x64, 0xc8, 0xdb, 0xab, 0x4a, 0x1f, 0xc0, 0x24, 0xd1, 0x4c, 0x59, 0xe8, 0x9e, 0xce, 0x10, 0x16,
+ /*4da0:*/ 0x68, 0x1f, 0x70, 0x1f, 0x31, 0xde, 0xa3, 0xe2, 0x20, 0xbb, 0xfc, 0x93, 0xa6, 0x43, 0x23, 0xea,
+ /*4db0:*/ 0x3a, 0x45, 0xe5, 0x93, 0x80, 0x92, 0x43, 0x5b, 0x05, 0x3d, 0x65, 0xe2, 0xbf, 0x56, 0x3f, 0x26,
+ /*4dc0:*/ 0x82, 0x0b, 0x1e, 0xd4, 0x46, 0x3a, 0x7a, 0x5a, 0x44, 0x91, 0x7e, 0x38, 0x3b, 0x6a, 0x17, 0xaf,
+ /*4dd0:*/ 0xc5, 0x5a, 0xb2, 0x68, 0xce, 0x68, 0x9c, 0x3c, 0x71, 0xc9, 0xde, 0xaa, 0x9b, 0xee, 0xd3, 0x50,
+ /*4de0:*/ 0x3c, 0xfd, 0xd8, 0x82, 0xc2, 0x6b, 0x92, 0x1a, 0xf9, 0x0c, 0x65, 0x20, 0x96, 0xc2, 0xd4, 0x2c,
+ /*4df0:*/ 0x0e, 0x89, 0x9d, 0xc7, 0xe0, 0xb9, 0x9b, 0x12, 0xad, 0xea, 0x0d, 0x97, 0x24, 0x99, 0xbe, 0x81,
+ /*4e00:*/ 0x08, 0x1f, 0x19, 0x70, 0x7f, 0x12, 0x9b, 0x46, 0x6b, 0xe3, 0xaf, 0x0b, 0xbb, 0xdd, 0xf9, 0xee,
+ /*4e10:*/ 0xfc, 0x40, 0x5b, 0x60, 0xb7, 0x9e, 0x00, 0xfe, 0x83, 0xca, 0x02, 0x31, 0xdb, 0x0a, 0x1a, 0xbe,
+ /*4e20:*/ 0xf1, 0x5f, 0xf9, 0x4f, 0xce, 0x03, 0x8c, 0xed, 0x31, 0x22, 0xaa, 0xcd, 0xa5, 0x34, 0xf5, 0xb2,
+ /*4e30:*/ 0x68, 0xad, 0x3e, 0xb4, 0x80, 0xa9, 0x11, 0x32, 0x56, 0x4d, 0xd6, 0x34, 0xe0, 0x3c, 0xf3, 0x49,
+ /*4e40:*/ 0x67, 0x5c, 0x8a, 0xf2, 0x08, 0xbf, 0x48, 0xac, 0xc1, 0x85, 0xa7, 0xfe, 0xcd, 0x8f, 0x46, 0x3c,
+ /*4e50:*/ 0xd5, 0x49, 0xfe, 0xf3, 0x9c, 0x61, 0x20, 0xd6, 0x16, 0x53, 0xfe, 0x67, 0x1d, 0x74, 0x44, 0x43,
+ /*4e60:*/ 0xab, 0x01, 0x7a, 0x1f, 0xdf, 0x83, 0x51, 0xbb, 0x25, 0xfc, 0xd7, 0x22, 0x94, 0x22, 0x03, 0x6c,
+ /*4e70:*/ 0x66, 0xa3, 0xa4, 0x0e, 0x19, 0x39, 0xd4, 0x9b, 0xfb, 0x4e, 0x37, 0x9d, 0x0d, 0xef, 0x7f, 0x7c,
+ /*4e80:*/ 0x08, 0x6b, 0xff, 0xbc, 0xab, 0xd9, 0xfe, 0xd9, 0x37, 0xd5, 0x8e, 0x5f, 0x33, 0xa3, 0xf1, 0xa4,
+ /*4e90:*/ 0x14, 0x77, 0xdb, 0x2b, 0xda, 0x8e, 0x5f, 0xb0, 0x33, 0x70, 0x6d, 0xd7, 0x84, 0xbf, 0xe5, 0x76,
+ /*4ea0:*/ 0xc3, 0xed, 0x1b, 0x34, 0xaa, 0xc1, 0x8d, 0x91, 0xf9, 0x44, 0x9b, 0xb7, 0x40, 0x92, 0x5d, 0xf3,
+ /*4eb0:*/ 0x3f, 0xe0, 0xb2, 0x34, 0x6b, 0x43, 0xc2, 0x04, 0xf5, 0x22, 0x95, 0xf5, 0xf6, 0x0a, 0x0d, 0x3c,
+ /*4ec0:*/ 0x51, 0xde, 0xa5, 0x32, 0x85, 0x29, 0x49, 0xd2, 0x37, 0x97, 0x44, 0x8f, 0x09, 0x49, 0xb7, 0xcb,
+ /*4ed0:*/ 0x76, 0xb5, 0x5d, 0x27, 0x24, 0x08, 0xb0, 0x73, 0x6d, 0xd5, 0xce, 0x44, 0xe2, 0xbf, 0x5a, 0xa1,
+ /*4ee0:*/ 0x52, 0x19, 0xdd, 0x09, 0xc1, 0x8c, 0x04, 0x0c, 0x5c, 0x4d, 0x80, 0xeb, 0x28, 0xb2, 0xf6, 0x74,
+ /*4ef0:*/ 0x98, 0xef, 0xe9, 0xfc, 0x67, 0xb1, 0x6a, 0x4d, 0x99, 0x50, 0xcc, 0x5e, 0x4e, 0x48, 0xaf, 0x3a,
+ /*4f00:*/ 0x2b, 0xf9, 0xd5, 0x8a, 0xf5, 0x2c, 0xb1, 0x48, 0x24, 0x3c, 0x93, 0xd8, 0xd0, 0x0a, 0x7a, 0x72,
+ /*4f10:*/ 0x20, 0xe6, 0xe1, 0x38, 0x6b, 0xa5, 0x30, 0x03, 0xaf, 0x3c, 0x52, 0x34, 0xdf, 0x42, 0x0c, 0x62,
+ /*4f20:*/ 0xfd, 0x7e, 0x11, 0x3a, 0x8b, 0x89, 0x36, 0x34, 0xf4, 0xdb, 0x88, 0xe4, 0xb9, 0x0a, 0xb8, 0x72,
+ /*4f30:*/ 0x3f, 0x42, 0x13, 0x7e, 0x4b, 0x4e, 0x6d, 0xae, 0x3c, 0x49, 0x26, 0x12, 0x75, 0x70, 0x8f, 0x43,
+ /*4f40:*/ 0xaa, 0xb3, 0x1a, 0x87, 0x12, 0x99, 0x43, 0x7c, 0x37, 0x52, 0xc6, 0xb1, 0x72, 0x5a, 0xab, 0xc8,
+ /*4f50:*/ 0x49, 0xd5, 0x30, 0x49, 0x8f, 0xf0, 0x06, 0xae, 0x97, 0x7d, 0x97, 0x57, 0x5e, 0x2b, 0x6a, 0x43,
+ /*4f60:*/ 0xa2, 0x8d, 0xa8, 0x4e, 0xcf, 0xa3, 0xbb, 0x1a, 0x28, 0x23, 0x06, 0x3d, 0x61, 0x2a, 0x4c, 0x97,
+ /*4f70:*/ 0x9a, 0xd2, 0x3e, 0xc1, 0x68, 0xc5, 0x3c, 0x81, 0x61, 0x7f, 0x8b, 0xea, 0x0f, 0x42, 0x9c, 0x89,
+ /*4f80:*/ 0xb8, 0xb1, 0x8a, 0xd1, 0x74, 0x09, 0x6c, 0x13, 0xee, 0x22, 0x8a, 0x3c, 0x59, 0xf6, 0x6c, 0xdb,
+ /*4f90:*/ 0xfd, 0xe9, 0x12, 0x29, 0xd9, 0x56, 0xdf, 0xe9, 0x9b, 0x4f, 0x30, 0x0e, 0x1c, 0x4c, 0x3f, 0x57,
+ /*4fa0:*/ 0xea, 0xd2, 0x9a, 0x00, 0x2d, 0x05, 0xfa, 0x0d, 0xcd, 0x2a, 0x6b, 0x7b, 0x12, 0xae, 0xe5, 0xe2,
+ /*4fb0:*/ 0xb0, 0xa1, 0x3c, 0xfc, 0xcb, 0x41, 0x00, 0x4c, 0x79, 0xbd, 0x02, 0x47, 0x36, 0x1b, 0x2a, 0xbc,
+ /*4fc0:*/ 0x46, 0x3a, 0x29, 0x68, 0x4b, 0x41, 0x5f, 0x47, 0x2b, 0xdb, 0x4c, 0x0d, 0xba, 0x7d, 0x3e, 0xd8,
+ /*4fd0:*/ 0x9a, 0x74, 0x62, 0x3d, 0x5d, 0x29, 0xec, 0x52, 0x65, 0x65, 0xdb, 0x95, 0xa5, 0x52, 0xff, 0xbb,
+ /*4fe0:*/ 0xef, 0xdb, 0xe9, 0xe4, 0xef, 0xb8, 0x0f, 0x94, 0x84, 0xab, 0xcb, 0x2e, 0x3c, 0x07, 0xee, 0xc1,
+ /*4ff0:*/ 0x26, 0xa5, 0xcd, 0xc4, 0x8f, 0xd7, 0x4c, 0xb5, 0x8c, 0xa8, 0x82, 0xbb, 0xda, 0xfe, 0x18, 0x25,
+ /*5000:*/ 0x0a, 0x5a, 0x1c, 0x02, 0x5a, 0x84, 0xa7, 0x1e, 0xdb, 0x8a, 0xc3, 0x97, 0xf0, 0x3a, 0x82, 0x06,
+ /*5010:*/ 0x08, 0x55, 0x93, 0x72, 0x66, 0xec, 0xac, 0x86, 0x3a, 0xb4, 0x27, 0xf4, 0x9d, 0x91, 0x96, 0xe8,
+ /*5020:*/ 0x6c, 0x06, 0x6c, 0xc0, 0xe4, 0x18, 0x1c, 0x54, 0x72, 0x2e, 0x4c, 0x56, 0xb6, 0x15, 0xe0, 0x72,
+ /*5030:*/ 0x66, 0xf0, 0xb0, 0xde, 0x53, 0x32, 0x30, 0x6c, 0xe4, 0x3f, 0x6e, 0x6e, 0x6a, 0xa3, 0xc5, 0x30,
+ /*5040:*/ 0xc8, 0xba, 0x71, 0x11, 0x9c, 0x57, 0x34, 0xb4, 0x92, 0x7d, 0x19, 0x3c, 0xcd, 0x9d, 0x22, 0xa2,
+ /*5050:*/ 0xf9, 0xdb, 0x99, 0x73, 0xfe, 0xcc, 0x10, 0x2d, 0xdf, 0x96, 0xf6, 0x8b, 0xce, 0x74, 0x91, 0xcb,
+ /*5060:*/ 0xd8, 0x50, 0x6b, 0x9d, 0x56, 0xec, 0x53, 0x7e, 0x5b, 0xaa, 0x7b, 0xa3, 0x9b, 0xaf, 0xa5, 0x7e,
+ /*5070:*/ 0xa4, 0xfa, 0x10, 0xdb, 0x73, 0x6e, 0xba, 0x66, 0x66, 0x17, 0xd5, 0x60, 0xa7, 0x9c, 0x4b, 0xdf,
+ /*5080:*/ 0xa7, 0x5e, 0x45, 0xfe, 0x5f, 0xbe, 0xf1, 0xd2, 0x63, 0x1a, 0x4d, 0x26, 0x22, 0x6e, 0x03, 0xe0,
+ /*5090:*/ 0x45, 0x89, 0x30, 0x41, 0x43, 0xad, 0x2b, 0xad, 0xf4, 0x0e, 0x0f, 0xa5, 0x33, 0xfc, 0x49, 0x30,
+ /*50a0:*/ 0x44, 0xf5, 0xc5, 0x8e, 0xe2, 0xa6, 0x32, 0x4b, 0x0c, 0xd5, 0x4d, 0x91, 0xe3, 0x48, 0xe2, 0xb7,
+ /*50b0:*/ 0xad, 0x24, 0xfb, 0xf9, 0x13, 0xe0, 0x3c, 0x8a, 0x03, 0xc6, 0x35, 0xbc, 0xd6, 0x6e, 0x03, 0x20,
+ /*50c0:*/ 0xda, 0x2b, 0x95, 0x22, 0x23, 0x55, 0xab, 0x79, 0x58, 0xd0, 0x55, 0x1a, 0x4d, 0xa4, 0xfd, 0x6e,
+ /*50d0:*/ 0x6b, 0x99, 0xc1, 0xf0, 0xba, 0x5d, 0x51, 0xfe, 0x59, 0xc3, 0x52, 0x19, 0x1b, 0x33, 0x89, 0x60,
+ /*50e0:*/ 0x07, 0xaf, 0x23, 0xd1, 0x01, 0xcd, 0xc9, 0xfa, 0x58, 0xa6, 0x7d, 0xec, 0x3e, 0x19, 0xc6, 0xc0,
+ /*50f0:*/ 0xa9, 0x5e, 0x9a, 0xb1, 0xe8, 0x58, 0xcb, 0x05, 0x36, 0x11, 0x98, 0xa3, 0x35, 0x32, 0x87, 0x44,
+ /*5100:*/ 0x5f, 0x6b, 0xdf, 0x09, 0x15, 0x42, 0xd7, 0xe9, 0x72, 0x56, 0x3f, 0x6b, 0x19, 0x08, 0x46, 0xf0,
+ /*5110:*/ 0x25, 0x77, 0x96, 0x04, 0x0f, 0x99, 0x4e, 0xa9, 0xbb, 0x7d, 0xad, 0x19, 0x6b, 0x2e, 0x42, 0x41,
+ /*5120:*/ 0xbc, 0xd2, 0xf0, 0x4b, 0xc6, 0xc5, 0x72, 0xa1, 0x39, 0x22, 0x56, 0x9b, 0x72, 0x34, 0x01, 0x3b,
+ /*5130:*/ 0x70, 0x33, 0x0f, 0xa3, 0x80, 0xf3, 0x9b, 0xcf, 0x4c, 0x22, 0xb5, 0xce, 0xd7, 0xe1, 0xdd, 0xa9,
+ /*5140:*/ 0xa0, 0x04, 0x87, 0xd0, 0xe2, 0x76, 0xed, 0xb6, 0x17, 0xb5, 0xf8, 0x20, 0x4c, 0xb2, 0x1c, 0x25,
+ /*5150:*/ 0x8b, 0x7e, 0x10, 0x65, 0xe3, 0xaa, 0x9b, 0x58, 0xfe, 0x41, 0x68, 0x9b, 0x2e, 0x02, 0x93, 0x86,
+ /*5160:*/ 0xab, 0xba, 0xb2, 0x70, 0xed, 0x13, 0x21, 0x94, 0xc7, 0x4f, 0xac, 0xb3, 0x77, 0xbb, 0xf1, 0x62,
+ /*5170:*/ 0x08, 0xfd, 0xe6, 0x53, 0xa0, 0x03, 0xc7, 0xbb, 0xcc, 0xf8, 0x90, 0x93, 0x2d, 0xc7, 0xee, 0xf8,
+ /*5180:*/ 0xf5, 0x08, 0xf8, 0x70, 0x2b, 0xc7, 0x29, 0x49, 0xc6, 0xc1, 0xbe, 0xc9, 0x48, 0x4b, 0xb4, 0x87,
+ /*5190:*/ 0xa3, 0xcb, 0x24, 0x88, 0x5f, 0xd7, 0xc0, 0x28, 0x2e, 0x13, 0x12, 0x6c, 0xf5, 0x00, 0x09, 0x12,
+ /*51a0:*/ 0x59, 0x8d, 0x38, 0x6c, 0xb7, 0x33, 0xda, 0x11, 0x66, 0x06, 0xd5, 0x11, 0x99, 0x1f, 0x3f, 0x44,
+ /*51b0:*/ 0xf1, 0x5e, 0x58, 0x7f, 0x30, 0xaf, 0x73, 0x8d, 0x24, 0x01, 0x5c, 0x1d, 0x02, 0x4a, 0x15, 0xd9,
+ /*51c0:*/ 0x8c, 0x6e, 0x12, 0xe6, 0x54, 0x73, 0xe9, 0x62, 0x31, 0xf9, 0x8e, 0x3c, 0x00, 0xff, 0x80, 0x48,
+ /*51d0:*/ 0xb9, 0x24, 0x18, 0x2f, 0xa7, 0xd8, 0x07, 0xd0, 0x84, 0x64, 0xe6, 0xad, 0x9d, 0xe9, 0xa7, 0xd8,
+ /*51e0:*/ 0x3c, 0xaa, 0x59, 0x19, 0x5a, 0x29, 0x61, 0xf8, 0x39, 0xcb, 0x16, 0x63, 0x9e, 0x6a, 0xc8, 0xcd,
+ /*51f0:*/ 0x5d, 0x4f, 0x97, 0x8c, 0xe3, 0xf1, 0x9a, 0xa0, 0x33, 0x24, 0x7c, 0x15, 0x65, 0x95, 0xb3, 0x09,
+ /*5200:*/ 0xaf, 0x2f, 0x11, 0x6c, 0xac, 0xea, 0x75, 0x33, 0x4b, 0x5a, 0xf3, 0x9f, 0x38, 0xa4, 0x60, 0xd8,
+ /*5210:*/ 0x0c, 0xff, 0x92, 0x97, 0x35, 0x63, 0xbe, 0x2f, 0x44, 0xa5, 0xc6, 0x4d, 0x61, 0x3e, 0xc5, 0xad,
+ /*5220:*/ 0xc6, 0x9b, 0x41, 0x02, 0x0c, 0x9d, 0x1e, 0xc5, 0xb1, 0x21, 0x0e, 0xd3, 0x44, 0xd8, 0x36, 0x49,
+ /*5230:*/ 0x73, 0x20, 0x23, 0xbc, 0x97, 0x99, 0xf0, 0xc2, 0x6f, 0x2c, 0x10, 0x69, 0x9d, 0xfe, 0x4d, 0x85,
+ /*5240:*/ 0xf7, 0xd6, 0x86, 0x87, 0x05, 0x42, 0x8d, 0xcb, 0xc7, 0x9f, 0xbd, 0x28, 0x0b, 0xdd, 0x8c, 0xe0,
+ /*5250:*/ 0x60, 0x61, 0x77, 0xb5, 0xca, 0x50, 0x33, 0x3d, 0xd4, 0x82, 0x51, 0x8d, 0x5b, 0x14, 0x28, 0x98,
+ /*5260:*/ 0x88, 0x90, 0x34, 0x1e, 0x77, 0xf6, 0x7f, 0xc2, 0x00, 0xf8, 0x55, 0x6d, 0xf9, 0xce, 0xb0, 0x3a,
+ /*5270:*/ 0xec, 0xe5, 0x5f, 0x8b, 0x2b, 0x12, 0x5c, 0x9b, 0x01, 0x33, 0xa6, 0x9b, 0x8b, 0xb1, 0x6a, 0x8d,
+ /*5280:*/ 0x70, 0xb2, 0x9e, 0x07, 0x27, 0x5a, 0x40, 0x5d, 0xba, 0x7f, 0x8b, 0x4c, 0x99, 0x49, 0x6e, 0x31,
+ /*5290:*/ 0x1e, 0xe4, 0x7e, 0x4a, 0x5d, 0xc3, 0xd1, 0x04, 0x0a, 0x7a, 0xab, 0x6a, 0x3c, 0x38, 0xa7, 0x7f,
+ /*52a0:*/ 0xd0, 0xcd, 0x06, 0x6a, 0x81, 0x37, 0x28, 0x25, 0xe9, 0xd2, 0xe6, 0x79, 0x1c, 0x43, 0x36, 0x80,
+ /*52b0:*/ 0x2b, 0x1d, 0xee, 0xd4, 0x4b, 0x7a, 0x5f, 0x9a, 0x7c, 0x38, 0xc1, 0x08, 0xa9, 0x17, 0x18, 0xd2,
+ /*52c0:*/ 0x6c, 0x78, 0xf0, 0xaa, 0xb4, 0x62, 0x38, 0x96, 0x6e, 0x96, 0x7b, 0x21, 0xc3, 0x21, 0x9b, 0xb2,
+ /*52d0:*/ 0x70, 0x5d, 0x7b, 0x2f, 0xb1, 0xc6, 0x96, 0x1a, 0xe0, 0xd7, 0x76, 0x6a, 0x6f, 0x4b, 0x23, 0x38,
+ /*52e0:*/ 0x9b, 0xc7, 0xac, 0xbf, 0x44, 0x01, 0x0f, 0xb6, 0x66, 0x97, 0xa5, 0xc6, 0xf8, 0xc2, 0xfa, 0x3b,
+ /*52f0:*/ 0x78, 0x48, 0xd1, 0xac, 0xe8, 0x47, 0xd0, 0x0e, 0x80, 0x0c, 0x52, 0xf0, 0xd4, 0x04, 0x4a, 0xd7,
+ /*5300:*/ 0x60, 0x49, 0xe5, 0x78, 0xe6, 0xc6, 0x91, 0xbc, 0x67, 0x12, 0x9a, 0x14, 0x39, 0x3a, 0xd5, 0x3a,
+ /*5310:*/ 0xa4, 0x2c, 0xfc, 0x1c, 0x30, 0x99, 0xdd, 0xf2, 0xba, 0xe6, 0xfa, 0xe3, 0x1d, 0xd9, 0xae, 0x64,
+ /*5320:*/ 0x11, 0x87, 0x92, 0x51, 0xc9, 0x61, 0x50, 0xb0, 0x82, 0x6d, 0x0b, 0x43, 0x8b, 0xf6, 0xae, 0x8e,
+ /*5330:*/ 0x83, 0x7d, 0x00, 0xfc, 0xd9, 0xf5, 0x4b, 0x14, 0x36, 0xf1, 0x4a, 0xea, 0x33, 0x92, 0x8c, 0x16,
+ /*5340:*/ 0x91, 0xb9, 0xf0, 0x44, 0xa2, 0x31, 0xed, 0x0e, 0x6b, 0x45, 0xb3, 0xe2, 0x47, 0xab, 0xc6, 0x70,
+ /*5350:*/ 0xf8, 0x84, 0xe8, 0xa4, 0x41, 0x9f, 0x32, 0xd5, 0x61, 0x6b, 0x81, 0x38, 0x34, 0x5b, 0x88, 0xf2,
+ /*5360:*/ 0x82, 0xae, 0x6c, 0x5e, 0xa0, 0x6f, 0xb1, 0x93, 0xaf, 0x6b, 0x04, 0xbe, 0xd5, 0xcb, 0xae, 0xac,
+ /*5370:*/ 0xd0, 0x09, 0x2a, 0x7d, 0x9f, 0xa6, 0xa9, 0xa2, 0x46, 0x61, 0x82, 0xaa, 0x95, 0x9c, 0xf1, 0x36,
+ /*5380:*/ 0x57, 0xb5, 0xcf, 0x5a, 0x00, 0x43, 0xac, 0x5c, 0xb4, 0xd9, 0xe2, 0x08, 0x03, 0x5c, 0x88, 0xc4,
+ /*5390:*/ 0xab, 0x50, 0xa6, 0x72, 0xae, 0xe0, 0x56, 0xba, 0x93, 0x9a, 0x87, 0x20, 0xe1, 0x08, 0x55, 0x2c,
+ /*53a0:*/ 0xeb, 0xff, 0xfd, 0xc6, 0x31, 0xc0, 0xb2, 0xce, 0x62, 0xe4, 0x8b, 0x31, 0xc3, 0xa9, 0x70, 0xed,
+ /*53b0:*/ 0x0f, 0x98, 0x04, 0x70, 0x07, 0xa3, 0x17, 0xc5, 0xb6, 0x15, 0x02, 0x2b, 0x62, 0x68, 0xb9, 0x18,
+ /*53c0:*/ 0xa4, 0x88, 0xf8, 0xad, 0x61, 0x63, 0x9d, 0x4f, 0x71, 0xd5, 0xbc, 0x32, 0x86, 0xa9, 0x2b, 0x6b,
+ /*53d0:*/ 0xdf, 0x2d, 0x0d, 0x4b, 0x6f, 0x65, 0xe4, 0x57, 0xae, 0x76, 0xac, 0x48, 0xeb, 0xa8, 0x12, 0xc5,
+ /*53e0:*/ 0x30, 0x93, 0x12, 0xfb, 0x85, 0xa9, 0x76, 0xe4, 0xca, 0x36, 0xbc, 0xb4, 0xd4, 0xa5, 0x6f, 0x3c,
+ /*53f0:*/ 0x77, 0x16, 0x05, 0x00, 0x3f, 0xd3, 0x0b, 0x93, 0x3e, 0xf0, 0xdd, 0xa3, 0xd9, 0xba, 0xfd, 0x6d,
+ /*5400:*/ 0x6e, 0x91, 0x64, 0x41, 0xa0, 0x40, 0xd7, 0x1a, 0x25, 0x33, 0xb8, 0x35, 0x50, 0x56, 0xa6, 0xf1,
+ /*5410:*/ 0x18, 0x19, 0x98, 0x5e, 0x74, 0x4b, 0xb0, 0xc0, 0xf2, 0xbb, 0x5b, 0x06, 0x1c, 0xc7, 0x35, 0x3b,
+ /*5420:*/ 0x3f, 0x00, 0x58, 0x20, 0x4a, 0x52, 0x25, 0xd2, 0x10, 0x79, 0x3b, 0x78, 0xd3, 0x6b, 0x39, 0x5c,
+ /*5430:*/ 0xf3, 0x22, 0xde, 0xb8, 0xd6, 0x8b, 0xe9, 0x2c, 0x03, 0x55, 0xd4, 0x82, 0x66, 0x33, 0x6e, 0xa1,
+ /*5440:*/ 0x68, 0xd8, 0x63, 0x1f, 0xda, 0xf8, 0x14, 0x4c, 0xfd, 0x78, 0x70, 0x3e, 0xdf, 0xdb, 0x83, 0x99,
+ /*5450:*/ 0x94, 0x61, 0xa5, 0x86, 0x64, 0xae, 0x9c, 0xfe, 0x33, 0xc7, 0x20, 0x04, 0x5a, 0xbe, 0xd4, 0x74,
+ /*5460:*/ 0xef, 0x19, 0x39, 0xf8, 0xf9, 0xff, 0xcc, 0x96, 0x3a, 0xb6, 0x1c, 0x54, 0xd8, 0xd7, 0xcb, 0xf6,
+ /*5470:*/ 0xd7, 0x97, 0x51, 0xd2, 0xd8, 0x86, 0x8e, 0x04, 0x5f, 0xc6, 0x5c, 0x3e, 0x71, 0x87, 0xa6, 0x50,
+ /*5480:*/ 0xeb, 0x41, 0x45, 0x45, 0xba, 0x0f, 0x67, 0x32, 0x44, 0x64, 0xbf, 0xde, 0xbc, 0x4c, 0x11, 0xfe,
+ /*5490:*/ 0xc2, 0x24, 0xe2, 0xf3, 0x30, 0xb2, 0x87, 0xa1, 0x62, 0xf6, 0xa0, 0x7d, 0xf7, 0xd9, 0x68, 0x83,
+ /*54a0:*/ 0x7a, 0x1b, 0x00, 0x0d, 0x01, 0xd8, 0xc0, 0xa6, 0x99, 0x2a, 0x95, 0x44, 0x5f, 0xda, 0xf6, 0xc3,
+ /*54b0:*/ 0xa0, 0x30, 0x0b, 0x1d, 0x88, 0xb4, 0xae, 0xc7, 0x2b, 0xae, 0x06, 0x2a, 0xb1, 0x72, 0x64, 0xec,
+ /*54c0:*/ 0x0b, 0xdc, 0xc6, 0xba, 0x92, 0xa6, 0xb9, 0x6e, 0x4f, 0x69, 0x12, 0x99, 0xb5, 0x00, 0xcf, 0x8d,
+ /*54d0:*/ 0x8e, 0x0b, 0x94, 0x75, 0xf2, 0x89, 0xb4, 0x35, 0x48, 0x9d, 0x7f, 0x76, 0x15, 0xb9, 0x92, 0x0b,
+ /*54e0:*/ 0x82, 0xba, 0x88, 0x8a, 0xff, 0x21, 0x3b, 0xd8, 0x53, 0x02, 0x78, 0x6a, 0x2a, 0x7c, 0x34, 0xb5,
+ /*54f0:*/ 0xfc, 0xc7, 0xb8, 0x99, 0xe0, 0xed, 0xb8, 0x52, 0xce, 0xc8, 0x68, 0x5e, 0x67, 0x2a, 0x7a, 0x4b,
+ /*5500:*/ 0x75, 0x78, 0x0f, 0x9d, 0xbe, 0x0e, 0x4c, 0xde, 0x5a, 0x1b, 0xc2, 0x36, 0xf3, 0xe4, 0x8a, 0xfd,
+ /*5510:*/ 0xf3, 0x72, 0x42, 0x38, 0xac, 0xd3, 0xc4, 0xaa, 0x16, 0xfa, 0x60, 0x8b, 0x4e, 0xd5, 0x87, 0x34,
+ /*5520:*/ 0x78, 0x01, 0x8b, 0x3b, 0x48, 0x1e, 0x57, 0x46, 0x59, 0x2d, 0x6c, 0xda, 0x80, 0xb2, 0x4b, 0x9c,
+ /*5530:*/ 0x77, 0xa2, 0x1c, 0xc0, 0x70, 0x63, 0xc1, 0x0e, 0x30, 0xf1, 0x26, 0xd1, 0xdd, 0x75, 0xf8, 0x3f,
+ /*5540:*/ 0x2c, 0xeb, 0x9d, 0xdf, 0xbc, 0x74, 0xff, 0x46, 0x6e, 0xbc, 0x7f, 0x9b, 0x41, 0xce, 0x20, 0xb0,
+ /*5550:*/ 0xb7, 0xff, 0x99, 0xc3, 0x13, 0x7c, 0xf6, 0x4b, 0xb3, 0x35, 0x37, 0xaa, 0xf2, 0x9a, 0xad, 0x67,
+ /*5560:*/ 0x81, 0xe0, 0x9d, 0xa6, 0x4f, 0x48, 0x68, 0xc2, 0x22, 0xaf, 0xf8, 0xdf, 0xf9, 0x2f, 0x08, 0x84,
+ /*5570:*/ 0x2c, 0xcb, 0xc4, 0x86, 0xe2, 0x5a, 0x38, 0x94, 0x45, 0x4d, 0xd7, 0x30, 0x97, 0x5a, 0xd4, 0x60,
+ /*5580:*/ 0x3b, 0x20, 0xb5, 0xf8, 0x39, 0x8c, 0x1a, 0x60, 0x05, 0xbb, 0x9e, 0x61, 0x8c, 0x56, 0x96, 0x39,
+ /*5590:*/ 0xe4, 0x78, 0x10, 0x07, 0x14, 0xb3, 0xbe, 0x0d, 0x24, 0x58, 0x78, 0xa8, 0x79, 0x29, 0xf0, 0xcc,
+ /*55a0:*/ 0x12, 0x4b, 0x5a, 0x9a, 0xa4, 0x4b, 0xa8, 0x37, 0x5e, 0xc3, 0x1b, 0x13, 0x77, 0x24, 0x09, 0x29,
+ /*55b0:*/ 0xcc, 0xf9, 0x05, 0xd7, 0x20, 0xe9, 0x16, 0xd5, 0xb0, 0x4d, 0x61, 0x44, 0xd7, 0x29, 0x9b, 0xd7,
+ /*55c0:*/ 0x6c, 0xaa, 0x82, 0xc9, 0x6e, 0x3a, 0x07, 0x8b, 0x9c, 0xef, 0x6a, 0xc0, 0x91, 0x11, 0x4b, 0x2d,
+ /*55d0:*/ 0x26, 0xd7, 0x3b, 0x11, 0x88, 0x4d, 0x6f, 0xf4, 0xad, 0xf3, 0xde, 0xdb, 0xa5, 0xb9, 0x7b, 0x64,
+ /*55e0:*/ 0x60, 0x7b, 0xd8, 0xf2, 0xd3, 0xa3, 0x64, 0x1a, 0x56, 0xc9, 0x5e, 0x6a, 0x86, 0xbd, 0x28, 0xea,
+ /*55f0:*/ 0x31, 0x28, 0x15, 0x84, 0x5c, 0xe5, 0x0a, 0x89, 0x54, 0x69, 0x14, 0x5b, 0xca, 0x24, 0x56, 0xc2,
+ /*5600:*/ 0x71, 0x96, 0xdf, 0x31, 0x9b, 0x72, 0x9f, 0xb3, 0xce, 0xd4, 0x87, 0xf6, 0x6f, 0x32, 0x89, 0x72,
+ /*5610:*/ 0x82, 0x7c, 0x59, 0x5c, 0x57, 0xfa, 0x01, 0x89, 0xd2, 0x2d, 0x45, 0xe3, 0x53, 0x62, 0xc9, 0x40,
+ /*5620:*/ 0x73, 0xa0, 0xcd, 0x96, 0xe1, 0xe5, 0x42, 0xed, 0x1a, 0x51, 0xb2, 0xb6, 0xc3, 0x18, 0xed, 0xd1,
+ /*5630:*/ 0x1f, 0x07, 0x69, 0x66, 0xbd, 0x27, 0x78, 0x6e, 0xd9, 0xf0, 0xe5, 0x37, 0x75, 0xbd, 0x67, 0xcf,
+ /*5640:*/ 0x62, 0x4e, 0xd2, 0xb1, 0xfa, 0xa9, 0x0c, 0x4a, 0xd3, 0x96, 0x96, 0x0f, 0xcd, 0x9b, 0x80, 0x1a,
+ /*5650:*/ 0x3b, 0x4a, 0x99, 0xdb, 0xd4, 0x16, 0x02, 0x62, 0x15, 0x97, 0xfa, 0xac, 0xd2, 0x04, 0x0b, 0xd5,
+ /*5660:*/ 0x7b, 0x20, 0x1d, 0xf3, 0x9c, 0xed, 0x32, 0x9b, 0x90, 0x2d, 0x95, 0xb1, 0x7e, 0x2c, 0xf8, 0x27,
+ /*5670:*/ 0x2c, 0x06, 0x8b, 0x23, 0x93, 0xc5, 0xa2, 0x0d, 0x94, 0xfc, 0xfd, 0x56, 0xe1, 0xe6, 0xa9, 0x81,
+ /*5680:*/ 0xe2, 0x48, 0x53, 0xee, 0x6d, 0xe9, 0x44, 0x92, 0x1b, 0x73, 0x16, 0xd6, 0x99, 0x12, 0xa4, 0x6a,
+ /*5690:*/ 0xa1, 0xfc, 0x8b, 0x1a, 0xf0, 0xb4, 0x1c, 0x67, 0xd4, 0x83, 0x65, 0x69, 0x9c, 0x64, 0xb1, 0x9e,
+ /*56a0:*/ 0x0b, 0x74, 0xbb, 0x0f, 0xa8, 0x7d, 0xb9, 0x39, 0x3b, 0x2c, 0x89, 0xcf, 0x70, 0x74, 0x27, 0xcf,
+ /*56b0:*/ 0x4a, 0xdd, 0x8a, 0xe5, 0x05, 0x46, 0x6d, 0x84, 0xba, 0x1d, 0x70, 0x78, 0x5a, 0x6f, 0x9a, 0xf1,
+ /*56c0:*/ 0xb4, 0xf8, 0x11, 0x7b, 0x39, 0xe7, 0x03, 0x67, 0x58, 0x6b, 0x64, 0x8c, 0x8d, 0xa3, 0xd2, 0x7d,
+ /*56d0:*/ 0xf4, 0x35, 0x4e, 0x48, 0x61, 0xc8, 0xaa, 0x57, 0xb9, 0xf5, 0xcd, 0x9c, 0xaa, 0x38, 0x78, 0x17,
+ /*56e0:*/ 0xaf, 0x59, 0x11, 0x2b, 0xfa, 0x49, 0x6c, 0xf3, 0xdf, 0x53, 0xb0, 0xb5, 0x3d, 0x1e, 0x37, 0x7e,
+ /*56f0:*/ 0x11, 0x2c, 0x56, 0xfa, 0xc7, 0x77, 0x6d, 0x6c, 0xd8, 0xd6, 0x12, 0x41, 0x12, 0xa2, 0x02, 0x06,
+ /*5700:*/ 0xcd, 0x5d, 0x75, 0xba, 0x86, 0xe5, 0xe5, 0x27, 0xdf, 0x8c, 0xd0, 0x06, 0xeb, 0x41, 0xbe, 0x8d,
+ /*5710:*/ 0xe1, 0xa2, 0x90, 0x8f, 0x4b, 0xbf, 0x76, 0x03, 0x75, 0x33, 0x29, 0x1a, 0x80, 0x57, 0xd6, 0x67,
+ /*5720:*/ 0x01, 0x72, 0xc1, 0x5a, 0xea, 0xd3, 0xbe, 0xb1, 0xac, 0x6c, 0x13, 0xc5, 0xc2, 0x72, 0x7d, 0x22,
+ /*5730:*/ 0xb0, 0xa2, 0xab, 0xf6, 0x52, 0x78, 0x37, 0xcf, 0x38, 0x1e, 0x13, 0xb9, 0xee, 0x71, 0x5a, 0xc4,
+ /*5740:*/ 0xfc, 0x6a, 0x11, 0xe1, 0xd6, 0x6e, 0x01, 0x32, 0x5a, 0x51, 0x35, 0x39, 0x59, 0x30, 0xc5, 0x15,
+ /*5750:*/ 0x87, 0x52, 0x63, 0xe8, 0x07, 0x39, 0xd8, 0xf0, 0x85, 0xf5, 0x7c, 0x31, 0x6d, 0xbf, 0x24, 0x27,
+ /*5760:*/ 0xf7, 0x66, 0xca, 0x6a, 0x81, 0xc8, 0x38, 0x02, 0x07, 0x20, 0x49, 0x2e, 0x9e, 0xe6, 0xe9, 0x5e,
+ /*5770:*/ 0x64, 0x81, 0xed, 0xea, 0xf9, 0x87, 0x53, 0xed, 0x06, 0xe0, 0x27, 0xba, 0x29, 0x0b, 0x00, 0xa0,
+ /*5780:*/ 0x2c, 0xbf, 0xee, 0x37, 0x44, 0x63, 0xa0, 0xf4, 0xe3, 0x9a, 0xc5, 0xba, 0x6f, 0x50, 0x1c, 0x72,
+ /*5790:*/ 0x14, 0x89, 0x3c, 0x14, 0xc4, 0xf7, 0x8c, 0x4d, 0x7d, 0x2a, 0xa2, 0xb4, 0x94, 0xfe, 0xfd, 0xce,
+ /*57a0:*/ 0xcf, 0x07, 0x71, 0x33, 0xe0, 0x46, 0xe0, 0x03, 0x94, 0x42, 0x9d, 0x55, 0x69, 0x2c, 0x3d, 0x74,
+ /*57b0:*/ 0x6b, 0x74, 0x52, 0x49, 0x34, 0x9c, 0x51, 0xc0, 0x19, 0x0c, 0x5e, 0x74, 0x76, 0xc2, 0x4a, 0x0a,
+ /*57c0:*/ 0x14, 0x88, 0x4e, 0x2a, 0xa5, 0x9a, 0x9e, 0xc3, 0x99, 0x72, 0x5e, 0xef, 0x9c, 0x94, 0xac, 0xa7,
+ /*57d0:*/ 0x61, 0x78, 0xc2, 0x36, 0x17, 0x82, 0x2d, 0xce, 0x7d, 0x92, 0xd0, 0x8a, 0x3b, 0x3e, 0x1f, 0x1d,
+ /*57e0:*/ 0x83, 0xf9, 0xa8, 0x44, 0xdf, 0xce, 0x84, 0x31, 0xdc, 0xf2, 0xd6, 0x0d, 0xb9, 0x0b, 0x89, 0xc5,
+ /*57f0:*/ 0x77, 0xae, 0xa1, 0x9a, 0x75, 0xc6, 0x93, 0x6e, 0xdb, 0x61, 0xdd, 0x3d, 0x8e, 0x7c, 0x4b, 0x53,
+ /*5800:*/ 0x14, 0x1d, 0x3c, 0x51, 0x5f, 0x60, 0xfe, 0x6a, 0x1d, 0xef, 0x49, 0x30, 0x03, 0xf3, 0xb2, 0x7c,
+ /*5810:*/ 0xf5, 0x1c, 0x88, 0x68, 0xf4, 0xb8, 0xf5, 0x36, 0x4f, 0x17, 0x11, 0x39, 0x44, 0xfc, 0xaa, 0xe2,
+ /*5820:*/ 0x51, 0x20, 0x77, 0xc7, 0xe0, 0xf4, 0x6e, 0x8c, 0xa5, 0x77, 0xc7, 0x66, 0x2c, 0x24, 0xb1, 0xae,
+ /*5830:*/ 0xc1, 0xbd, 0x1a, 0x64, 0x1c, 0x1e, 0xa3, 0xbb, 0x52, 0xb3, 0x53, 0x1a, 0x5e, 0x94, 0xd6, 0x10,
+ /*5840:*/ 0xd4, 0x17, 0x6e, 0x36, 0xe8, 0x09, 0x6a, 0x0f, 0x67, 0x73, 0x40, 0xb8, 0xcf, 0xdd, 0xc0, 0xac,
+ /*5850:*/ 0x3a, 0xfd, 0x08, 0xcd, 0xd2, 0x42, 0xc0, 0xb0, 0x4e, 0xc3, 0xca, 0x66, 0x2b, 0x84, 0x19, 0x6f,
+ /*5860:*/ 0x2e, 0xf2, 0x22, 0x21, 0x56, 0xb7, 0x17, 0xbe, 0x47, 0xc2, 0x96, 0x6e, 0x60, 0xf2, 0xc7, 0x1f,
+ /*5870:*/ 0x9b, 0xb5, 0x82, 0xea, 0x02, 0x46, 0x4e, 0x04, 0xca, 0x64, 0xa1, 0x70, 0xd6, 0xd0, 0xd7, 0x3d,
+ /*5880:*/ 0x15, 0x42, 0x68, 0x17, 0xfd, 0x7f, 0x7f, 0x9a, 0x12, 0x1b, 0xcc, 0x7a, 0x59, 0x85, 0x5e, 0xfd,
+ /*5890:*/ 0x74, 0x55, 0x8b, 0xc9, 0x55, 0xf7, 0x44, 0x64, 0xa8, 0xff, 0xd3, 0xb5, 0x32, 0x2e, 0xb1, 0x3a,
+ /*58a0:*/ 0x36, 0xe2, 0x4d, 0x18, 0x35, 0x37, 0x5c, 0x5b, 0x8d, 0x9b, 0x51, 0x51, 0x39, 0xb2, 0xbe, 0x5a,
+ /*58b0:*/ 0xaf, 0xf6, 0xa4, 0x35, 0xc5, 0x62, 0x26, 0x9e, 0x60, 0xa8, 0xad, 0x12, 0x89, 0xef, 0x23, 0x9a,
+ /*58c0:*/ 0x54, 0x74, 0xa6, 0x07, 0x40, 0xab, 0x97, 0xf4, 0xcc, 0xa9, 0x37, 0xd2, 0x43, 0xda, 0x9b, 0xdb,
+ /*58d0:*/ 0x07, 0x3c, 0x6f, 0x33, 0x64, 0x6b, 0xfd, 0xa7, 0x72, 0x5c, 0x61, 0xce, 0xe7, 0x2a, 0x21, 0x96,
+ /*58e0:*/ 0xac, 0xb4, 0x04, 0x2d, 0x0b, 0x8b, 0x6d, 0xa8, 0xbd, 0x48, 0xab, 0xcd, 0xc9, 0x1f, 0x12, 0xf3,
+ /*58f0:*/ 0xb6, 0x83, 0xec, 0xa2, 0x89, 0x8b, 0x89, 0x35, 0x62, 0x10, 0x5e, 0xc8, 0x28, 0xcc, 0x2f, 0xfb,
+ /*5900:*/ 0x85, 0xb4, 0x9a, 0xab, 0x51, 0x1a, 0x78, 0x84, 0x42, 0xec, 0x99, 0xad, 0x5b, 0x53, 0x24, 0x39,
+ /*5910:*/ 0x68, 0x4c, 0xdb, 0xef, 0xab, 0x5c, 0x89, 0xfa, 0x6f, 0xf7, 0x23, 0x6c, 0x42, 0x7d, 0xbf, 0xe9,
+ /*5920:*/ 0x29, 0x96, 0x1f, 0x47, 0x39, 0x86, 0x02, 0x36, 0x5a, 0x1a, 0x98, 0xe4, 0x1a, 0x7b, 0x03, 0x3b,
+ /*5930:*/ 0x6c, 0x5f, 0x41, 0x61, 0x20, 0x26, 0xe2, 0xf2, 0x26, 0x8a, 0xf7, 0x50, 0xe4, 0x50, 0xd2, 0x64,
+ /*5940:*/ 0xea, 0xec, 0xf5, 0x37, 0xea, 0xf7, 0x68, 0x8b, 0x31, 0x24, 0xc8, 0x78, 0x96, 0x2d, 0xc6, 0x9b,
+ /*5950:*/ 0x46, 0xa1, 0x9a, 0xe2, 0xdc, 0xbb, 0x26, 0x14, 0xd8, 0x7e, 0x78, 0xb9, 0x60, 0x1d, 0xc4, 0x4b,
+ /*5960:*/ 0x66, 0xad, 0x2d, 0x11, 0x40, 0x70, 0xcd, 0x41, 0xb5, 0xb5, 0x8d, 0xe1, 0xc2, 0x44, 0x6a, 0xcf,
+ /*5970:*/ 0x87, 0x28, 0xa8, 0x8a, 0xc6, 0x9b, 0xb4, 0xd8, 0x14, 0xae, 0x0e, 0xae, 0x4e, 0xde, 0x7f, 0xf1,
+ /*5980:*/ 0x79, 0xec, 0x9c, 0xed, 0x96, 0x33, 0xfd, 0x40, 0xae, 0xbf, 0x34, 0xa2, 0x9c, 0x5a, 0xf7, 0xcd,
+ /*5990:*/ 0x4b, 0xab, 0xaa, 0xd2, 0xd5, 0xb2, 0x39, 0xcd, 0x4a, 0x23, 0xc7, 0xb9, 0x82, 0x55, 0xa9, 0x00,
+ /*59a0:*/ 0xf1, 0x6d, 0x29, 0x99, 0x0d, 0xc6, 0x83, 0x5a, 0x21, 0xaa, 0x09, 0xb6, 0x24, 0x17, 0xd9, 0xbe,
+ /*59b0:*/ 0x56, 0xd8, 0x23, 0x56, 0x94, 0xe5, 0x72, 0xdd, 0xb3, 0xc7, 0x30, 0x76, 0x66, 0xc8, 0x79, 0xd6,
+ /*59c0:*/ 0xda, 0xa0, 0x85, 0x20, 0x75, 0xd4, 0x17, 0x65, 0x68, 0xb2, 0x47, 0xe7, 0xae, 0xfc, 0xe8, 0x40,
+ /*59d0:*/ 0xf0, 0x10, 0x64, 0xa8, 0x56, 0x29, 0x92, 0x4c, 0xe1, 0x8d, 0x80, 0x60, 0x3e, 0x05, 0x3d, 0xaa,
+ /*59e0:*/ 0x46, 0x9b, 0x4b, 0xa8, 0x80, 0xd7, 0xb0, 0x81, 0xa4, 0x5c, 0xc6, 0x12, 0xef, 0x4b, 0xda, 0x3f,
+ /*59f0:*/ 0x4b, 0x78, 0xf4, 0x64, 0x17, 0x52, 0xc2, 0xec, 0x4a, 0xc6, 0x44, 0x3b, 0x80, 0xcf, 0xd6, 0xa5,
+ /*5a00:*/ 0x44, 0xa5, 0x02, 0x3b, 0x05, 0x10, 0xd0, 0x69, 0xdf, 0x7e, 0x27, 0xf0, 0x25, 0x26, 0x09, 0xa8,
+ /*5a10:*/ 0xa7, 0x38, 0x72, 0xe5, 0x96, 0x62, 0x8a, 0xc7, 0x5e, 0xb1, 0x6a, 0xf6, 0x5a, 0x1a, 0x08, 0x88,
+ /*5a20:*/ 0xe4, 0x18, 0x42, 0xff, 0x53, 0xbb, 0x93, 0x7c, 0xc5, 0x34, 0x65, 0x29, 0xcc, 0xbe, 0xfa, 0xb2,
+ /*5a30:*/ 0xec, 0x59, 0x23, 0xd8, 0xb2, 0x31, 0xe4, 0xe1, 0xe1, 0xb7, 0xd9, 0x40, 0xbd, 0xb6, 0x1b, 0x29,
+ /*5a40:*/ 0xba, 0x10, 0x60, 0x3d, 0x93, 0x68, 0x2f, 0x08, 0x17, 0xf3, 0x43, 0xa8, 0x0c, 0x1e, 0xda, 0x76,
+ /*5a50:*/ 0x60, 0x8a, 0xb0, 0x2d, 0x44, 0x09, 0x24, 0xf2, 0xca, 0xa8, 0xf5, 0xd4, 0x4e, 0x2a, 0xbd, 0xd7,
+ /*5a60:*/ 0xed, 0x37, 0x24, 0x20, 0xfa, 0x00, 0x0a, 0x01, 0x4d, 0xc1, 0xfe, 0x71, 0x26, 0x76, 0xf0, 0x2f,
+ /*5a70:*/ 0x2b, 0xe9, 0xb5, 0xfe, 0xd9, 0x18, 0x96, 0x84, 0x51, 0xc1, 0x39, 0xf3, 0x1a, 0x87, 0x1c, 0xf6,
+ /*5a80:*/ 0x62, 0xed, 0xcd, 0xa7, 0x7e, 0x57, 0x6d, 0x08, 0xc6, 0x90, 0x6d, 0xe5, 0x6e, 0xee, 0x8f, 0x88,
+ /*5a90:*/ 0x07, 0x71, 0xab, 0x55, 0x66, 0xfc, 0xf7, 0x0b, 0x90, 0x97, 0xc9, 0xe9, 0xf0, 0xe5, 0x30, 0x9a,
+ /*5aa0:*/ 0xd0, 0x5a, 0x00, 0x9c, 0x1c, 0x3c, 0x49, 0x2a, 0x3e, 0x72, 0xb8, 0xfe, 0xab, 0x20, 0xc8, 0xf5,
+ /*5ab0:*/ 0xd7, 0xf9, 0x76, 0xbe, 0x33, 0x45, 0xac, 0x6b, 0x81, 0x50, 0x66, 0x9c, 0x24, 0xa0, 0x47, 0xe0,
+ /*5ac0:*/ 0xbe, 0x7f, 0xa2, 0x85, 0xb0, 0x8a, 0xfb, 0x42, 0x04, 0xe0, 0xed, 0xd6, 0xfd, 0xcc, 0x59, 0x6f,
+ /*5ad0:*/ 0xe7, 0x57, 0x63, 0x52, 0x03, 0x75, 0x28, 0x2d, 0x07, 0x7b, 0xe3, 0xf9, 0xfb, 0xa1, 0xef, 0x85,
+ /*5ae0:*/ 0x51, 0xf0, 0xf8, 0x76, 0x11, 0xa6, 0x80, 0xe4, 0x4b, 0x24, 0xfd, 0x1f, 0xc7, 0x68, 0x05, 0x8f,
+ /*5af0:*/ 0xd8, 0xdb, 0x52, 0xbd, 0x09, 0x85, 0x75, 0x5e, 0xe1, 0x61, 0x14, 0x60, 0xaf, 0xfd, 0xd2, 0xdf,
+ /*5b00:*/ 0xa3, 0x80, 0xc9, 0xa2, 0x80, 0x69, 0x47, 0xe9, 0xb7, 0xcd, 0xbb, 0xae, 0x53, 0xbd, 0xa8, 0xf6,
+ /*5b10:*/ 0x86, 0x88, 0x4c, 0xdb, 0xfc, 0xa7, 0xd1, 0x42, 0xfc, 0xb8, 0x9f, 0xe9, 0xf3, 0x7e, 0xeb, 0x13,
+ /*5b20:*/ 0x4f, 0xb0, 0xfa, 0xe0, 0x40, 0x42, 0xa6, 0x3b, 0x35, 0xf9, 0x72, 0x2f, 0x21, 0x17, 0x2d, 0xdd,
+ /*5b30:*/ 0xa2, 0x39, 0xa5, 0x88, 0xb2, 0x9b, 0xdb, 0x65, 0x3b, 0x70, 0x97, 0xb1, 0xe4, 0x4c, 0xda, 0x69,
+ /*5b40:*/ 0x88, 0x5c, 0xde, 0x5b, 0x89, 0x42, 0xe5, 0x13, 0x29, 0x73, 0x71, 0xe6, 0x37, 0x8a, 0x3e, 0x69,
+ /*5b50:*/ 0x66, 0xfd, 0xb2, 0x4b, 0x85, 0xa9, 0x29, 0x11, 0xce, 0x9b, 0x5a, 0x77, 0x48, 0xc8, 0x45, 0x19,
+ /*5b60:*/ 0x22, 0x07, 0x84, 0x91, 0xa0, 0x91, 0x5d, 0x7b, 0xde, 0x37, 0xd5, 0xcf, 0x62, 0x4e, 0x01, 0xd1,
+ /*5b70:*/ 0x87, 0x1f, 0xf9, 0x2d, 0xe6, 0x35, 0x67, 0x45, 0x69, 0x5a, 0x50, 0xaf, 0xae, 0xa8, 0x5b, 0x62,
+ /*5b80:*/ 0xbb, 0x03, 0x86, 0x97, 0x7f, 0x84, 0xe2, 0xbf, 0xc3, 0x04, 0x06, 0x1d, 0x08, 0xbc, 0x6d, 0x8e,
+ /*5b90:*/ 0xb9, 0x7a, 0x0d, 0xf1, 0x6c, 0xc6, 0x25, 0xd2, 0x17, 0x26, 0x05, 0x4c, 0xe3, 0xd6, 0x52, 0x19,
+ /*5ba0:*/ 0xf3, 0xd0, 0xb1, 0x0b, 0x62, 0x4d, 0x6c, 0x8e, 0xb8, 0x34, 0x1e, 0xd8, 0x0e, 0x88, 0xe2, 0x91,
+ /*5bb0:*/ 0xa8, 0xf0, 0xdf, 0x13, 0xb7, 0x5e, 0x12, 0xae, 0x21, 0x6b, 0x0c, 0x60, 0xa4, 0x40, 0xee, 0x1d,
+ /*5bc0:*/ 0x75, 0xfa, 0xd2, 0x0e, 0x21, 0x57, 0x15, 0x87, 0x0c, 0x30, 0x9f, 0x8a, 0x1c, 0xc6, 0xde, 0x93,
+ /*5bd0:*/ 0xb9, 0xc5, 0x3f, 0x48, 0x81, 0x07, 0xc0, 0xcb, 0x2f, 0xd3, 0x79, 0x60, 0x99, 0xab, 0x22, 0xa2,
+ /*5be0:*/ 0xcd, 0xc1, 0x6a, 0x6e, 0x87, 0xdf, 0xf9, 0x32, 0xba, 0x53, 0x25, 0xab, 0x0d, 0x3a, 0xcc, 0x31,
+ /*5bf0:*/ 0x61, 0x0e, 0xa7, 0x16, 0x4b, 0x2e, 0x1d, 0x94, 0xc5, 0x45, 0x80, 0x0c, 0x16, 0x93, 0x7c, 0xfd,
+ /*5c00:*/ 0x1f, 0xa1, 0x01, 0x20, 0xfb, 0xe3, 0x93, 0x92, 0x81, 0x38, 0x78, 0xd2, 0xda, 0xbd, 0xcd, 0xf0,
+ /*5c10:*/ 0xe6, 0x55, 0x6e, 0x33, 0x24, 0x06, 0xcb, 0xf1, 0xb3, 0x14, 0x90, 0x28, 0xe4, 0x33, 0xd7, 0xc8,
+ /*5c20:*/ 0x0d, 0xbb, 0x79, 0xcc, 0xe5, 0x9f, 0xcd, 0x78, 0x99, 0xb4, 0xab, 0xe1, 0x97, 0x30, 0x26, 0x62,
+ /*5c30:*/ 0xbe, 0x36, 0xfe, 0x00, 0x4d, 0xdf, 0x68, 0x50, 0x67, 0x63, 0xb6, 0xe2, 0x3b, 0xef, 0xbe, 0x2f,
+ /*5c40:*/ 0xca, 0xa2, 0xec, 0xc8, 0x79, 0x51, 0x56, 0x8c, 0xae, 0x14, 0xf8, 0xfc, 0x3f, 0x5f, 0x94, 0xdd,
+ /*5c50:*/ 0xb7, 0x0a, 0x1c, 0x79, 0xea, 0x22, 0x73, 0x33, 0x66, 0x7f, 0x4b, 0x0a, 0xb4, 0x51, 0xbd, 0xa7,
+ /*5c60:*/ 0xed, 0x46, 0x8f, 0xf9, 0x86, 0x65, 0x31, 0xfd, 0xf0, 0xdc, 0x2e, 0xee, 0xcf, 0xa7, 0x13, 0x9f,
+ /*5c70:*/ 0x07, 0x78, 0xc6, 0xc6, 0x07, 0x7b, 0x51, 0xda, 0x8f, 0x0b, 0xdb, 0xba, 0xd2, 0xde, 0xc6, 0x63,
+ /*5c80:*/ 0xbe, 0xd5, 0x92, 0xc6, 0xcb, 0xd3, 0xb3, 0xbb, 0x26, 0xe6, 0x10, 0x1f, 0x83, 0x69, 0x0e, 0x0a,
+ /*5c90:*/ 0xeb, 0xd5, 0x35, 0x71, 0xed, 0xa8, 0x77, 0x7a, 0x5a, 0x07, 0xaf, 0xd1, 0x3a, 0x00, 0xf6, 0x83,
+ /*5ca0:*/ 0x7e, 0x0d, 0x6c, 0xed, 0xd8, 0xc6, 0x3c, 0x15, 0x9d, 0xad, 0x5b, 0x1c, 0xb6, 0xfb, 0x4d, 0x89,
+ /*5cb0:*/ 0x0f, 0xa2, 0x8f, 0xf9, 0x3e, 0x48, 0x77, 0xeb, 0xd0, 0x8a, 0x0e, 0xfe, 0xd2, 0x15, 0x38, 0x1e,
+ /*5cc0:*/ 0x9c, 0x08, 0x60, 0xd8, 0xbf, 0x95, 0xb9, 0xe9, 0x5d, 0x6d, 0x7b, 0x8c, 0x86, 0x33, 0xe4, 0xb1,
+ /*5cd0:*/ 0x10, 0xf6, 0x0b, 0x1c, 0x2a, 0xcc, 0xe7, 0x3b, 0xc1, 0x18, 0x14, 0xf5, 0x8b, 0xf4, 0x50, 0x5b,
+ /*5ce0:*/ 0x64, 0x46, 0x8f, 0xc3, 0x70, 0xfb, 0x68, 0xe6, 0x9a, 0x73, 0x4e, 0x23, 0xc6, 0x21, 0x96, 0xf1,
+ /*5cf0:*/ 0x9f, 0xca, 0x75, 0xc4, 0xaf, 0xb2, 0xde, 0xd6, 0xa9, 0x5c, 0xa5, 0x18, 0x5d, 0x84, 0x79, 0xe3,
+ /*5d00:*/ 0xc5, 0xf5, 0x44, 0x5e, 0x63, 0xf0, 0xc8, 0x35, 0x15, 0xe3, 0xff, 0x04, 0x8a, 0x31, 0xd0, 0xee,
+ /*5d10:*/ 0xc6, 0xe4, 0x77, 0x30, 0xb8, 0x77, 0x49, 0x68, 0x1c, 0x33, 0x99, 0x2d, 0x7e, 0xf5, 0x45, 0xa9,
+ /*5d20:*/ 0x13, 0x69, 0xc2, 0xab, 0x3f, 0xea, 0x49, 0x07, 0x4b, 0xc9, 0x9d, 0x8a, 0x1f, 0x41, 0x7f, 0xf7,
+ /*5d30:*/ 0x98, 0x2d, 0x75, 0x11, 0x10, 0x23, 0xb7, 0xab, 0x26, 0x79, 0x04, 0x9c, 0x10, 0x2a, 0x75, 0xef,
+ /*5d40:*/ 0x54, 0xe6, 0xc7, 0xab, 0x2d, 0xe7, 0xb3, 0xf4, 0xdd, 0x9e, 0xb5, 0xda, 0xbd, 0x7b, 0xe9, 0xbd,
+ /*5d50:*/ 0x6b, 0xd8, 0xf3, 0x4b, 0x05, 0x76, 0xdb, 0x03, 0xa4, 0x2b, 0x37, 0x20, 0x8b, 0x3e, 0x2b, 0xa2,
+ /*5d60:*/ 0x18, 0x01, 0x8e, 0xcf, 0xf9, 0x3e, 0x8b, 0xf1, 0x80, 0x24, 0xde, 0x31, 0xd1, 0x81, 0x70, 0xaf,
+ /*5d70:*/ 0x82, 0xd7, 0x58, 0xa8, 0xdc, 0xce, 0x2b, 0x55, 0x44, 0x21, 0x2b, 0xe1, 0xac, 0x0e, 0x23, 0xe7,
+ /*5d80:*/ 0xb2, 0x0b, 0x5e, 0x12, 0x3c, 0x4e, 0x6e, 0x3b, 0xf7, 0xbb, 0xce, 0x72, 0x5a, 0x5d, 0x54, 0xa0,
+ /*5d90:*/ 0xf5, 0x2e, 0xce, 0x9f, 0x76, 0xbf, 0x25, 0xb1, 0xeb, 0x5a, 0xa6, 0x61, 0x7d, 0x98, 0x33, 0x2f,
+ /*5da0:*/ 0x49, 0x3d, 0xec, 0xdf, 0xef, 0xed, 0xa1, 0x90, 0xeb, 0xde, 0xc3, 0x89, 0xd0, 0x04, 0xa7, 0xa0,
+ /*5db0:*/ 0xaa, 0xb3, 0xed, 0x54, 0x13, 0xc4, 0x70, 0x90, 0xfa, 0x2a, 0xfd, 0x24, 0x87, 0xf5, 0x12, 0x82,
+ /*5dc0:*/ 0xf0, 0x39, 0xfd, 0x1a, 0xd5, 0x0f, 0x26, 0x4a, 0xaf, 0x40, 0xb4, 0x2e, 0x3f, 0x9c, 0xa7, 0x35,
+ /*5dd0:*/ 0xcb, 0x5d, 0xf3, 0x21, 0xea, 0xbf, 0xb9, 0x14, 0x01, 0x06, 0x36, 0xcc, 0x06, 0xba, 0xa9, 0x8a,
+ /*5de0:*/ 0x32, 0x22, 0x12, 0x22, 0x19, 0xff, 0x64, 0xd2, 0x33, 0x98, 0x90, 0xb0, 0x57, 0xcb, 0xe7, 0x6a,
+ /*5df0:*/ 0x58, 0xc9, 0x1d, 0x85, 0x08, 0x4e, 0x18, 0x57, 0x4b, 0x20, 0xd6, 0xbe, 0xaa, 0x8c, 0x44, 0xad,
+ /*5e00:*/ 0x83, 0x78, 0xe5, 0x79, 0x72, 0xc6, 0xa8, 0xf1, 0xe5, 0x09, 0x9d, 0x4f, 0x54, 0xd5, 0xb9, 0x7d,
+ /*5e10:*/ 0x5b, 0xe8, 0x9f, 0xb1, 0x45, 0xc2, 0xe3, 0xe3, 0xe2, 0xbf, 0x4d, 0xb4, 0x5b, 0x88, 0x15, 0x70,
+ /*5e20:*/ 0x94, 0xf0, 0xe6, 0x2c, 0x3c, 0x66, 0x15, 0xf2, 0xab, 0xdf, 0x57, 0x74, 0x59, 0x8e, 0x30, 0x0a,
+ /*5e30:*/ 0x52, 0xe0, 0x96, 0x54, 0x84, 0xbd, 0x28, 0x94, 0x80, 0x4d, 0xac, 0x0a, 0xc1, 0xf6, 0x36, 0x8b,
+ /*5e40:*/ 0x7b, 0x11, 0xce, 0x6e, 0x43, 0x50, 0xbc, 0x94, 0x93, 0x96, 0x29, 0xe3, 0xf3, 0x28, 0x1b, 0x88,
+ /*5e50:*/ 0x23, 0xb8, 0x7d, 0x0e, 0xd0, 0xb9, 0x46, 0x81, 0xa1, 0xb3, 0xba, 0xb9, 0x67, 0x48, 0xe6, 0xc5,
+ /*5e60:*/ 0x11, 0x12, 0xa3, 0xaa, 0xf3, 0x1d, 0xe0, 0x64, 0x20, 0x09, 0x31, 0xe4, 0x21, 0xd1, 0xbb, 0x6c,
+ /*5e70:*/ 0x67, 0x83, 0x43, 0xd1, 0x9b, 0x91, 0x3d, 0xdf, 0xea, 0xf3, 0xaf, 0x77, 0x4d, 0x58, 0x16, 0xe8,
+ /*5e80:*/ 0xce, 0xd6, 0x60, 0xaa, 0xa9, 0x40, 0x6d, 0x44, 0xbc, 0xb2, 0x46, 0x27, 0xc3, 0xa3, 0x5c, 0x18,
+ /*5e90:*/ 0xcd, 0xd9, 0xe5, 0xef, 0x91, 0x14, 0x3b, 0xff, 0xb2, 0xbd, 0x65, 0x9a, 0xf8, 0x75, 0x76, 0x7b,
+ /*5ea0:*/ 0x0f, 0xf8, 0xad, 0x0b, 0xbf, 0x4b, 0xdf, 0x2e, 0xa8, 0x45, 0xac, 0x4c, 0x3b, 0xb0, 0x18, 0x8e,
+ /*5eb0:*/ 0xb5, 0x85, 0x23, 0x1b, 0x63, 0xed, 0xaa, 0x09, 0x52, 0xb6, 0x36, 0xe0, 0xb8, 0x15, 0xa8, 0x8b,
+ /*5ec0:*/ 0x51, 0x4c, 0xa3, 0xca, 0x09, 0x3c, 0xec, 0x83, 0x91, 0xfb, 0x4f, 0x3b, 0xc5, 0x35, 0x4c, 0x13,
+ /*5ed0:*/ 0x0a, 0x8f, 0x58, 0xb5, 0x19, 0x29, 0xdd, 0x46, 0x53, 0xbd, 0xf4, 0x15, 0xdf, 0x29, 0xf5, 0xa4,
+ /*5ee0:*/ 0x25, 0x45, 0x85, 0xa3, 0x00, 0x75, 0x4d, 0x38, 0xfb, 0xfe, 0x53, 0xed, 0x1f, 0x14, 0xf2, 0x0e,
+ /*5ef0:*/ 0xb7, 0x40, 0x62, 0x88, 0x92, 0x54, 0x6e, 0xd2, 0xa5, 0x8d, 0x7a, 0x9b, 0x2b, 0xee, 0x74, 0xb0,
+ /*5f00:*/ 0xb0, 0x17, 0x2b, 0xd3, 0x46, 0x6a, 0x3d, 0xcb, 0xdc, 0x93, 0x00, 0xfc, 0xf1, 0x3d, 0x4d, 0x25,
+ /*5f10:*/ 0xe9, 0x8d, 0xdf, 0x8d, 0x0d, 0x4a, 0x3e, 0xcb, 0x58, 0xc2, 0x33, 0x72, 0x0b, 0xd2, 0x8d, 0x55,
+ /*5f20:*/ 0x74, 0x63, 0x66, 0x3f, 0x9b, 0xeb, 0x77, 0x17, 0xb9, 0x18, 0x9c, 0xc8, 0xb7, 0x9b, 0x52, 0x1c,
+ /*5f30:*/ 0xbd, 0xa9, 0xa1, 0x3d, 0x51, 0x7e, 0x9a, 0xf8, 0x94, 0x14, 0xb8, 0x59, 0xec, 0xe2, 0x2f, 0xf6,
+ /*5f40:*/ 0xdd, 0x8a, 0x44, 0x55, 0x72, 0xc8, 0x7b, 0xaf, 0xce, 0xd2, 0x85, 0xb8, 0x71, 0x2d, 0x2e, 0x9e,
+ /*5f50:*/ 0xcb, 0x22, 0xbf, 0xdb, 0xd3, 0x85, 0x08, 0x7c, 0x48, 0x06, 0xd7, 0xbe, 0x5a, 0xa6, 0x5a, 0xe5,
+ /*5f60:*/ 0x83, 0x6f, 0xbc, 0xc2, 0xf0, 0xce, 0xc1, 0x8c, 0x54, 0x5e, 0x01, 0x93, 0xc4, 0x48, 0x62, 0x29,
+ /*5f70:*/ 0xef, 0x74, 0x0a, 0x80, 0xb8, 0x03, 0x61, 0x67, 0x13, 0x38, 0xd5, 0x55, 0x89, 0xc1, 0x51, 0x06,
+ /*5f80:*/ 0x2f, 0xb6, 0x24, 0x34, 0xbe, 0x92, 0xc9, 0x9b, 0xa4, 0xc8, 0x50, 0x50, 0xb4, 0xf3, 0xba, 0xd3,
+ /*5f90:*/ 0x77, 0x18, 0xd1, 0x8d, 0x95, 0x11, 0x48, 0x0d, 0xbc, 0x2b, 0x0f, 0xee, 0x04, 0x6a, 0xd8, 0xa0,
+ /*5fa0:*/ 0x6a, 0xfb, 0x6e, 0xae, 0xac, 0x6c, 0xad, 0x4b, 0x66, 0x61, 0x35, 0x00, 0x29, 0x19, 0x31, 0x7d,
+ /*5fb0:*/ 0x67, 0x58, 0xd0, 0x95, 0x81, 0xfe, 0x31, 0x46, 0x91, 0xd8, 0xac, 0xb4, 0x5e, 0xbf, 0xf3, 0xfc,
+ /*5fc0:*/ 0x4a, 0xcc, 0x67, 0xc6, 0xbf, 0x89, 0xb9, 0x9a, 0x83, 0x3a, 0x6a, 0x00, 0xe3, 0x8e, 0x7f, 0x03,
+ /*5fd0:*/ 0xa2, 0xc6, 0x6e, 0x81, 0x9a, 0xd3, 0xf9, 0x9e, 0xb9, 0xe1, 0x15, 0x01, 0xb3, 0x6d, 0xc4, 0xea,
+ /*5fe0:*/ 0xa1, 0x3a, 0x29, 0x38, 0x64, 0x07, 0xeb, 0x7c, 0x96, 0x3c, 0x05, 0xc9, 0xee, 0x2c, 0x13, 0x91,
+ /*5ff0:*/ 0x30, 0x33, 0x84, 0x01, 0x31, 0xe0, 0xef, 0xe9, 0x31, 0x07, 0x59, 0x9b, 0xca, 0xc2, 0x73, 0xc1,
+ /*6000:*/ 0xbc, 0x1c, 0xd8, 0xc0, 0xce, 0x1d, 0xf4, 0x25, 0x2e, 0x88, 0xa1, 0xc1, 0x48, 0x98, 0x0c, 0xae,
+ /*6010:*/ 0x01, 0x9f, 0xe0, 0x94, 0x38, 0x4f, 0xd0, 0x8c, 0x36, 0x6b, 0x4d, 0xd5, 0x0b, 0x03, 0x8a, 0x5d,
+ /*6020:*/ 0x15, 0x3c, 0x3a, 0x09, 0x32, 0x95, 0xd8, 0xdb, 0x9f, 0xcf, 0x71, 0x67, 0x9b, 0xc6, 0xab, 0x87,
+ /*6030:*/ 0xd4, 0xfe, 0xad, 0xc2, 0xde, 0x17, 0x9c, 0xba, 0x4b, 0x1c, 0x73, 0x69, 0xe4, 0xa5, 0xc1, 0x90,
+ /*6040:*/ 0x2c, 0x25, 0xec, 0x91, 0x2e, 0xd9, 0x18, 0xe5, 0xa4, 0xfb, 0x4d, 0x6b, 0x31, 0x5d, 0xbb, 0xb5,
+ /*6050:*/ 0xb9, 0xe1, 0xdc, 0xf6, 0xcd, 0x88, 0x15, 0xbe, 0x82, 0xf7, 0x7e, 0x74, 0x9f, 0x67, 0x84, 0x38,
+ /*6060:*/ 0x60, 0x25, 0xa6, 0x22, 0x8a, 0xfa, 0xd1, 0x54, 0x9d, 0x4a, 0xab, 0x80, 0x8e, 0xf3, 0x46, 0x92,
+ /*6070:*/ 0x93, 0xd3, 0x56, 0xdf, 0x3c, 0xed, 0xfe, 0x16, 0x90, 0x7f, 0x22, 0xe8, 0xda, 0x79, 0xe3, 0x4d,
+ /*6080:*/ 0x32, 0x34, 0x05, 0xa4, 0x1e, 0xf8, 0xa1, 0xa4, 0x73, 0xe8, 0x3b, 0x94, 0xcc, 0xc5, 0x56, 0x86,
+ /*6090:*/ 0xd5, 0xc5, 0x52, 0x23, 0xf1, 0x3e, 0xbb, 0x73, 0x5f, 0x2e, 0xa4, 0x53, 0x18, 0x1d, 0xeb, 0xbc,
+ /*60a0:*/ 0xab, 0x38, 0x61, 0x83, 0x15, 0xcf, 0xbc, 0xff, 0xb7, 0x3e, 0x43, 0xa7, 0x48, 0x10, 0x64, 0x52,
+ /*60b0:*/ 0x3c, 0xae, 0x7c, 0x8f, 0xf0, 0x21, 0x96, 0x99, 0xc4, 0xc5, 0xaa, 0xfe, 0x96, 0xc0, 0x13, 0xa9,
+ /*60c0:*/ 0x91, 0xe2, 0xb3, 0x6b, 0x52, 0xea, 0x5f, 0xfa, 0xcd, 0xe3, 0x48, 0xd8, 0x8e, 0x8a, 0x8d, 0x8f,
+ /*60d0:*/ 0x89, 0x45, 0xf0, 0xcb, 0xc8, 0xc7, 0x21, 0x44, 0x22, 0xb3, 0xad, 0x68, 0x55, 0xd1, 0x59, 0xa6,
+ /*60e0:*/ 0xd0, 0x7e, 0xb2, 0xd3, 0xf1, 0xd1, 0x0a, 0x25, 0xc2, 0x3f, 0x3b, 0x40, 0x34, 0x03, 0x1e, 0xc3,
+ /*60f0:*/ 0x3c, 0x71, 0x70, 0xf8, 0x3a, 0x6a, 0x9d, 0x7c, 0x46, 0xbb, 0xd7, 0x79, 0x66, 0x6a, 0x3d, 0xb6,
+ /*6100:*/ 0x6f, 0x57, 0xa8, 0x22, 0xf3, 0x1e, 0x8c, 0x91, 0x44, 0x86, 0xa5, 0x91, 0xce, 0x11, 0x14, 0xc0,
+ /*6110:*/ 0x13, 0xaa, 0xaa, 0xbe, 0xb0, 0x7f, 0x2b, 0x6b, 0x12, 0x53, 0x75, 0x82, 0xcb, 0x1b, 0x56, 0xf8,
+ /*6120:*/ 0xc6, 0x1b, 0x83, 0x8c, 0x94, 0xd4, 0xfa, 0x0b, 0x2f, 0x90, 0x0d, 0xf0, 0x05, 0x80, 0xac, 0x2d,
+ /*6130:*/ 0xf2, 0x1c, 0x7a, 0x53, 0xce, 0x2a, 0xd2, 0xc8, 0xd7, 0x0c, 0x84, 0x60, 0xe1, 0x4d, 0xb1, 0x75,
+ /*6140:*/ 0x56, 0xc8, 0xf8, 0xab, 0x4d, 0x49, 0x16, 0x87, 0x41, 0x71, 0x1b, 0x0f, 0xed, 0x3a, 0xa6, 0xe4,
+ /*6150:*/ 0x92, 0x9e, 0xe7, 0xad, 0xb5, 0xb3, 0x0c, 0xa1, 0x7d, 0x00, 0x3d, 0x54, 0x11, 0xc6, 0x34, 0xb8,
+ /*6160:*/ 0x87, 0x2a, 0xb7, 0xf7, 0x56, 0xd1, 0x3e, 0x18, 0xa1, 0xcc, 0xc0, 0x71, 0x5d, 0xe3, 0x66, 0xf0,
+ /*6170:*/ 0xea, 0x05, 0xa4, 0xe2, 0x55, 0x77, 0x8c, 0x5c, 0xa5, 0xca, 0xb1, 0xae, 0xf4, 0x0f, 0xb3, 0x9d,
+ /*6180:*/ 0xb8, 0x0f, 0x1e, 0x0f, 0x8e, 0x5e, 0xbb, 0x0e, 0x26, 0x5e, 0x3a, 0xdc, 0xca, 0xb5, 0xa2, 0xad,
+ /*6190:*/ 0x1d, 0xfe, 0x65, 0x89, 0x4e, 0x67, 0x8c, 0xe3, 0xc6, 0x61, 0x0f, 0x28, 0x8c, 0x7a, 0xf0, 0x18,
+ /*61a0:*/ 0x26, 0xbd, 0x05, 0x5f, 0x08, 0xba, 0x7b, 0x76, 0xb3, 0xc0, 0x76, 0x52, 0xfe, 0xda, 0x9b, 0x79,
+ /*61b0:*/ 0xb9, 0x2b, 0x12, 0x05, 0xdf, 0x3f, 0xa3, 0x92, 0xff, 0x2f, 0x82, 0x65, 0x0c, 0xe6, 0x10, 0x26,
+ /*61c0:*/ 0x20, 0x3a, 0xbf, 0x49, 0x70, 0x40, 0x94, 0xd3, 0xc2, 0xd9, 0xf1, 0x66, 0xc4, 0x79, 0x57, 0xe6,
+ /*61d0:*/ 0xcd, 0x93, 0xd8, 0xc7, 0x21, 0xd0, 0x4d, 0x71, 0x39, 0x4c, 0xaf, 0xdf, 0xb8, 0x34, 0xa7, 0xdc,
+ /*61e0:*/ 0x94, 0x78, 0x2e, 0x1a, 0x6c, 0x1b, 0xb6, 0xe7, 0x18, 0x45, 0xb7, 0x05, 0xe9, 0x12, 0x20, 0x95,
+ /*61f0:*/ 0xa2, 0x6c, 0x35, 0x27, 0xaf, 0xdf, 0xed, 0x1f, 0x70, 0xd5, 0x74, 0x44, 0x65, 0x54, 0x38, 0x12,
+ /*6200:*/ 0x9c, 0xe8, 0x59, 0x3f, 0x9a, 0x07, 0x44, 0x32, 0xa7, 0x4b, 0x0a, 0xe5, 0x1d, 0x08, 0x82, 0x86,
+ /*6210:*/ 0xcf, 0x99, 0x47, 0x8d, 0xb4, 0x29, 0xa4, 0x96, 0x3f, 0x65, 0x8e, 0xaf, 0xb4, 0x44, 0xe9, 0x69,
+ /*6220:*/ 0x1e, 0xe8, 0xc8, 0xcb, 0x67, 0xd9, 0x78, 0x2e, 0xbb, 0x11, 0x72, 0xed, 0x4f, 0xe5, 0x95, 0xad,
+ /*6230:*/ 0x13, 0xc9, 0x68, 0x0c, 0x0e, 0xe4, 0xde, 0xcf, 0xb1, 0x65, 0xc5, 0x36, 0xe9, 0xeb, 0x25, 0xe7,
+ /*6240:*/ 0xdf, 0xe5, 0x02, 0x09, 0x31, 0x37, 0x99, 0x7a, 0xe3, 0xe5, 0x34, 0xf6, 0xea, 0x6e, 0xcc, 0x39,
+ /*6250:*/ 0x64, 0xbe, 0xb3, 0xd3, 0x0f, 0xf2, 0x7e, 0x18, 0xba, 0x53, 0x35, 0x19, 0x3f, 0x9f, 0x5a, 0x80,
+ /*6260:*/ 0x2a, 0xbb, 0x7e, 0x92, 0x31, 0xfd, 0x2a, 0x66, 0xee, 0x54, 0xd0, 0x32, 0xa3, 0x53, 0x2d, 0xfc,
+ /*6270:*/ 0xf5, 0x59, 0x13, 0xe1, 0xb0, 0xe9, 0x31, 0x07, 0x19, 0xe5, 0x08, 0x8e, 0x24, 0x87, 0x39, 0x8b,
+ /*6280:*/ 0xb2, 0xa8, 0xde, 0x81, 0xaa, 0x47, 0x5b, 0x9a, 0x41, 0xd5, 0xda, 0xb9, 0x61, 0x59, 0x4f, 0x30,
+ /*6290:*/ 0x25, 0xa3, 0x56, 0x4f, 0x9b, 0x9e, 0x63, 0x96, 0x75, 0xba, 0xfd, 0xf0, 0x4b, 0x64, 0x73, 0xbb,
+ /*62a0:*/ 0xa2, 0x96, 0x5b, 0xbf, 0xce, 0xc3, 0xa1, 0xa8, 0x90, 0xc9, 0x19, 0xf7, 0xb1, 0x82, 0xb7, 0xcc,
+ /*62b0:*/ 0xb1, 0x57, 0xa0, 0x13, 0x7c, 0x60, 0x34, 0x32, 0x65, 0xba, 0xf2, 0x5f, 0x41, 0xdc, 0x00, 0xd1,
+ /*62c0:*/ 0x5a, 0x38, 0xb6, 0x4f, 0x4d, 0xec, 0x18, 0x31, 0xc3, 0x8b, 0xaa, 0x06, 0xda, 0x2f, 0x2e, 0x7c,
+ /*62d0:*/ 0x2b, 0x57, 0x29, 0x81, 0x43, 0xb2, 0xca, 0xb9, 0x61, 0x2c, 0x94, 0x5e, 0x8e, 0xa2, 0x33, 0x80,
+ /*62e0:*/ 0x0a, 0x4b, 0x58, 0xa7, 0x1c, 0xf7, 0x0d, 0xc0, 0x1a, 0x61, 0x14, 0xf8, 0x82, 0x57, 0x5b, 0x0d,
+ /*62f0:*/ 0x17, 0x71, 0x8d, 0xf9, 0x42, 0x9a, 0x41, 0x1f, 0x84, 0x98, 0xcb, 0x38, 0x25, 0x4a, 0xb9, 0x0a,
+ /*6300:*/ 0xf1, 0xfc, 0x94, 0x14, 0x21, 0x51, 0xe3, 0xe5, 0x1a, 0xd9, 0x70, 0x31, 0x1a, 0x84, 0xaf, 0x08,
+ /*6310:*/ 0x20, 0x9f, 0x96, 0x61, 0x84, 0xf5, 0xfb, 0xfc, 0x4f, 0xf0, 0xb7, 0xcc, 0xef, 0x99, 0xb9, 0x6d,
+ /*6320:*/ 0x95, 0x11, 0x57, 0x20, 0x62, 0x62, 0xa8, 0xfb, 0xec, 0xf1, 0x0f, 0xcc, 0xc9, 0xf0, 0x63, 0xb8,
+ /*6330:*/ 0x59, 0xa4, 0xf8, 0xb0, 0xfd, 0xf6, 0xe2, 0x61, 0x45, 0x9b, 0xb4, 0x18, 0xf5, 0xe5, 0x9f, 0x3e,
+ /*6340:*/ 0x97, 0xe7, 0x3f, 0x08, 0xf7, 0x63, 0x9b, 0x71, 0x4f, 0x06, 0x95, 0x66, 0xa7, 0x2e, 0xa1, 0xa3,
+ /*6350:*/ 0xef, 0x22, 0xf7, 0x82, 0x00, 0xf8, 0xc6, 0x04, 0x03, 0xf6, 0x90, 0x4d, 0xd2, 0xe7, 0xb2, 0xda,
+ /*6360:*/ 0xeb, 0x4b, 0xff, 0x40, 0x33, 0x28, 0xed, 0x33, 0x81, 0x9e, 0xfa, 0x18, 0x43, 0xac, 0x82, 0x99,
+ /*6370:*/ 0x09, 0xa5, 0x7c, 0xd7, 0xc0, 0xf2, 0x9a, 0xeb, 0xb4, 0xb6, 0x18, 0x9a, 0x9c, 0x8e, 0x5e, 0xed,
+ /*6380:*/ 0x49, 0x18, 0xb6, 0x14, 0x74, 0x3b, 0x19, 0x2d, 0xa0, 0xdf, 0xc0, 0xa3, 0x56, 0x6b, 0x17, 0x80,
+ /*6390:*/ 0x40, 0x36, 0x2f, 0x5b, 0xf8, 0xc0, 0x39, 0x0b, 0x64, 0x73, 0x31, 0x15, 0x0f, 0x54, 0x3d, 0x52,
+ /*63a0:*/ 0x39, 0x99, 0xe3, 0x37, 0xaf, 0xae, 0xaa, 0xf2, 0x1e, 0xc4, 0x53, 0x41, 0xa8, 0x41, 0x82, 0x5c,
+ /*63b0:*/ 0xde, 0x4a, 0xef, 0xa9, 0x4b, 0x31, 0xfe, 0xdb, 0x5a, 0x2d, 0x55, 0xa2, 0x5a, 0x84, 0xda, 0xfc,
+ /*63c0:*/ 0x47, 0xbc, 0x8c, 0x5f, 0x6c, 0x30, 0x6f, 0xb7, 0xb0, 0x57, 0xe2, 0xe3, 0x30, 0x75, 0xae, 0x9d,
+ /*63d0:*/ 0x78, 0xd5, 0x98, 0x44, 0xee, 0x86, 0x44, 0x3c, 0xfd, 0x18, 0x0d, 0x5c, 0x16, 0x86, 0x04, 0xdb,
+ /*63e0:*/ 0x8a, 0xda, 0x0c, 0x37, 0xef, 0xb1, 0xea, 0xe5, 0x7c, 0x10, 0x6a, 0x17, 0x01, 0xd4, 0x44, 0x4e,
+ /*63f0:*/ 0xf3, 0xb3, 0x47, 0xce, 0x10, 0x78, 0x6e, 0x69, 0x98, 0x3e, 0x61, 0x21, 0xde, 0x65, 0x50, 0xb4,
+ /*6400:*/ 0x2e, 0x08, 0x08, 0x6b, 0xef, 0x25, 0x1b, 0x9d, 0x68, 0xee, 0xd0, 0xce, 0xd5, 0x36, 0xb0, 0xcd,
+ /*6410:*/ 0x4e, 0x0c, 0x19, 0x59, 0x57, 0xd8, 0xa1, 0x69, 0xe5, 0x1f, 0xba, 0x8d, 0x28, 0xa4, 0xe0, 0x56,
+ /*6420:*/ 0xdf, 0xab, 0xd0, 0x2a, 0x27, 0x60, 0xd3, 0xa1, 0x69, 0xbb, 0x77, 0xe5, 0xef, 0xa8, 0x99, 0xb4,
+ /*6430:*/ 0x3f, 0xc1, 0x09, 0x72, 0x69, 0xe9, 0x73, 0x5b, 0x59, 0x48, 0x4c, 0x1d, 0x9d, 0x73, 0xb6, 0x8e,
+ /*6440:*/ 0x2a, 0x66, 0x7e, 0xf5, 0xaf, 0x12, 0x69, 0xcf, 0x61, 0xbd, 0xd3, 0x84, 0xd3, 0x3a, 0xe4, 0xbf,
+ /*6450:*/ 0x7f, 0xeb, 0x21, 0x59, 0x72, 0x7c, 0xa6, 0x89, 0x6b, 0x2e, 0xc9, 0x46, 0xa8, 0x05, 0xc9, 0xf9,
+ /*6460:*/ 0x7a, 0x25, 0x27, 0xb8, 0xda, 0x80, 0xf6, 0xa7, 0x69, 0x28, 0x06, 0x5d, 0x8e, 0xa6, 0x0d, 0x3c,
+ /*6470:*/ 0x7b, 0x2a, 0xce, 0x1a, 0x13, 0x53, 0x98, 0x85, 0x1f, 0xc9, 0xce, 0xd0, 0xd4, 0x76, 0x6d, 0x6e,
+ /*6480:*/ 0xa9, 0x4e, 0x5a, 0x44, 0xc2, 0xb4, 0x6f, 0x5e, 0xe8, 0x8c, 0x88, 0xfb, 0xe2, 0x1e, 0x4b, 0x1a,
+ /*6490:*/ 0xa9, 0x55, 0x09, 0x70, 0x73, 0xf9, 0x4f, 0xd4, 0x4a, 0x53, 0xaa, 0x7e, 0x67, 0xe5, 0x61, 0x13,
+ /*64a0:*/ 0x53, 0xfc, 0xef, 0xe6, 0x82, 0x6a, 0xdf, 0x82, 0x87, 0x93, 0x8f, 0x85, 0x7a, 0x8e, 0x7a, 0xb9,
+ /*64b0:*/ 0xd8, 0xf9, 0xac, 0x79, 0x2c, 0x87, 0x9f, 0x40, 0x9a, 0xe3, 0x8b, 0xbd, 0x15, 0xaf, 0x70, 0xfb,
+ /*64c0:*/ 0x7f, 0x80, 0x74, 0x6c, 0x94, 0x02, 0x0d, 0xd2, 0x41, 0x7f, 0xe2, 0x38, 0xcb, 0xfe, 0x99, 0xef,
+ /*64d0:*/ 0xd7, 0x0e, 0x74, 0x93, 0x66, 0xae, 0xa7, 0x10, 0x42, 0x10, 0xf6, 0x77, 0x5e, 0x16, 0xe7, 0x4c,
+ /*64e0:*/ 0x41, 0x51, 0xc8, 0x80, 0x6c, 0xaf, 0xb9, 0xb6, 0x91, 0x17, 0xb3, 0xba, 0x00, 0x07, 0xe4, 0xd1,
+ /*64f0:*/ 0x89, 0x05, 0x31, 0xc9, 0x6c, 0x5a, 0x8f, 0x4c, 0xd2, 0x03, 0xe7, 0x79, 0x65, 0xfb, 0x6a, 0x60,
+ /*6500:*/ 0x6c, 0x1d, 0x88, 0x94, 0xf3, 0xc0, 0x15, 0xd0, 0xc3, 0xad, 0x93, 0x81, 0xee, 0x3e, 0x48, 0x9b,
+ /*6510:*/ 0xa7, 0xe8, 0x9b, 0x26, 0x55, 0x97, 0xcd, 0x15, 0xc1, 0xf0, 0x97, 0xb0, 0x47, 0x42, 0xba, 0xea,
+ /*6520:*/ 0x04, 0x2e, 0x31, 0xf8, 0xb3, 0xf5, 0xcb, 0xa4, 0xec, 0xf5, 0x59, 0xe4, 0x8f, 0x03, 0x69, 0x85,
+ /*6530:*/ 0x94, 0x55, 0x00, 0xeb, 0xa5, 0x15, 0xca, 0xe2, 0xac, 0xc7, 0xfb, 0x79, 0x23, 0xbc, 0x60, 0x2b,
+ /*6540:*/ 0x87, 0xcc, 0x55, 0xc5, 0xe8, 0x79, 0xd0, 0x1e, 0x4b, 0xde, 0xf6, 0xf0, 0x26, 0x87, 0x88, 0x29,
+ /*6550:*/ 0xf4, 0x78, 0x77, 0x42, 0xaf, 0x38, 0x53, 0xc4, 0x91, 0x7b, 0xf0, 0x2d, 0x12, 0x2d, 0xa3, 0x15,
+ /*6560:*/ 0xaf, 0x2d, 0x0d, 0xd1, 0xc5, 0x07, 0x55, 0x03, 0x8c, 0x1a, 0x51, 0x5d, 0x1c, 0xcb, 0xd2, 0xd5,
+ /*6570:*/ 0x6a, 0x9b, 0x6e, 0x48, 0x35, 0x7d, 0xd0, 0xc0, 0x45, 0x8f, 0x14, 0xca, 0x74, 0x9f, 0x84, 0xf8,
+ /*6580:*/ 0xd3, 0xd3, 0xe6, 0x14, 0x66, 0xc6, 0x8c, 0xde, 0x3b, 0x54, 0x33, 0x69, 0x20, 0x23, 0x60, 0x3d,
+ /*6590:*/ 0xc4, 0xd5, 0x7c, 0xc6, 0xa9, 0xd9, 0xf0, 0xbd, 0x4b, 0xbd, 0x0d, 0x5c, 0xea, 0x74, 0x0a, 0x6a,
+ /*65a0:*/ 0x17, 0x0d, 0x71, 0xfd, 0x9b, 0xa9, 0x0a, 0x1c, 0x80, 0xf6, 0x2a, 0xd9, 0xf7, 0x2f, 0x1b, 0x41,
+ /*65b0:*/ 0x06, 0x09, 0x10, 0x95, 0xfc, 0xbd, 0xe4, 0x81, 0x54, 0x47, 0x0e, 0xfd, 0xca, 0xe5, 0x6f, 0x49,
+ /*65c0:*/ 0x39, 0xe7, 0xb4, 0xea, 0x75, 0x3c, 0x02, 0x76, 0xb5, 0xa8, 0x0e, 0x4b, 0x81, 0x2d, 0xbc, 0x9d,
+ /*65d0:*/ 0xc9, 0x88, 0xea, 0x8f, 0xde, 0x8d, 0xdb, 0x69, 0x91, 0x6b, 0x30, 0xbf, 0xdb, 0x43, 0x57, 0xa3,
+ /*65e0:*/ 0xd2, 0xde, 0x8b, 0x8e, 0xaa, 0xc0, 0x46, 0xb5, 0x09, 0x61, 0xfd, 0x92, 0x11, 0x78, 0x73, 0xed,
+ /*65f0:*/ 0x89, 0xa3, 0xf9, 0x33, 0xd8, 0x5f, 0xbe, 0x1c, 0x82, 0x6c, 0xd1, 0xd0, 0x58, 0xb5, 0x72, 0x43,
+ /*6600:*/ 0x37, 0xd6, 0xca, 0x98, 0x30, 0x9c, 0x29, 0xae, 0x11, 0x14, 0x73, 0x17, 0x6d, 0x10, 0xea, 0xa6,
+ /*6610:*/ 0x2d, 0xf3, 0x1b, 0xe4, 0xd2, 0xba, 0x01, 0x52, 0x4b, 0xe9, 0x54, 0xb5, 0x3f, 0x9c, 0xb4, 0x9e,
+ /*6620:*/ 0xac, 0xe0, 0x93, 0x6d, 0xdc, 0x1d, 0xfa, 0xf7, 0x04, 0x8f, 0x4a, 0x7e, 0x97, 0xf3, 0x01, 0x38,
+ /*6630:*/ 0x2f, 0xa2, 0x3d, 0xcf, 0xd1, 0x4c, 0x6c, 0x57, 0xb5, 0x8e, 0xb3, 0x59, 0xdd, 0x84, 0x8c, 0x1a,
+ /*6640:*/ 0xaa, 0xc4, 0x9a, 0x6d, 0x7d, 0xd2, 0xf3, 0x5f, 0x60, 0x2d, 0xd3, 0xc3, 0xdb, 0x3c, 0xef, 0xea,
+ /*6650:*/ 0x0c, 0x99, 0x3a, 0xd0, 0xb5, 0xbb, 0xda, 0xcc, 0x35, 0xce, 0x81, 0xc1, 0x15, 0x61, 0x2d, 0x7c,
+ /*6660:*/ 0x20, 0xb1, 0x2a, 0x4c, 0x19, 0x79, 0xff, 0xe7, 0xfd, 0xa2, 0x7c, 0xd4, 0x81, 0xef, 0xd6, 0xc7,
+ /*6670:*/ 0x89, 0xfd, 0x67, 0x8f, 0xa0, 0x64, 0xb9, 0x84, 0x68, 0x87, 0xa2, 0x7d, 0x21, 0xa9, 0xd4, 0x28,
+ /*6680:*/ 0x89, 0x0d, 0x62, 0x08, 0x25, 0xb6, 0x41, 0x9f, 0x0c, 0x3b, 0xdf, 0x0d, 0x86, 0x9c, 0xbd, 0x16,
+ /*6690:*/ 0x6f, 0x03, 0x1b, 0xd8, 0x1c, 0x00, 0x91, 0x14, 0xc1, 0x3a, 0x45, 0x96, 0xa4, 0x4c, 0xa3, 0x27,
+ /*66a0:*/ 0x31, 0x4d, 0xf7, 0x8b, 0x69, 0xdc, 0xab, 0x4e, 0x91, 0xb7, 0x68, 0x46, 0x52, 0x04, 0xb4, 0xf0,
+ /*66b0:*/ 0xa3, 0x7d, 0xf2, 0xa3, 0x14, 0xb4, 0x12, 0xda, 0xa1, 0xb4, 0xa9, 0x6b, 0x22, 0x49, 0x0c, 0xaa,
+ /*66c0:*/ 0x1a, 0x95, 0x57, 0x4c, 0x6c, 0x0b, 0x72, 0x36, 0xf9, 0x02, 0x41, 0x17, 0xc9, 0x70, 0x7e, 0x10,
+ /*66d0:*/ 0xce, 0x4c, 0xd2, 0xa0, 0x46, 0xac, 0x64, 0x5a, 0x53, 0x12, 0x5a, 0xd1, 0x4b, 0x5c, 0x87, 0xa0,
+ /*66e0:*/ 0xb6, 0xc9, 0xf5, 0x6e, 0xa2, 0xbb, 0x3b, 0x6c, 0x55, 0x67, 0x73, 0xe2, 0x01, 0x5d, 0xac, 0x26,
+ /*66f0:*/ 0xad, 0x79, 0xc4, 0x56, 0x2c, 0x33, 0x66, 0x7b, 0xb9, 0xdf, 0x4f, 0x9e, 0xe5, 0x13, 0xb8, 0xf0,
+ /*6700:*/ 0x70, 0x53, 0x59, 0xa0, 0xc2, 0x74, 0xc5, 0xeb, 0x76, 0x4e, 0x1c, 0x0d, 0xfe, 0x98, 0x05, 0x57,
+ /*6710:*/ 0xd5, 0xbe, 0x81, 0xb2, 0x67, 0x0a, 0xcc, 0xde, 0xc1, 0x4e, 0x07, 0x80, 0x34, 0xee, 0x20, 0x93,
+ /*6720:*/ 0xbd, 0xc1, 0xd6, 0x72, 0x47, 0x17, 0xe0, 0x27, 0x90, 0xca, 0x97, 0x0e, 0x0f, 0x6c, 0xcc, 0xe2,
+ /*6730:*/ 0x97, 0x47, 0x49, 0x0c, 0x73, 0xaf, 0x47, 0x8d, 0x8a, 0x2a, 0x6e, 0xfb, 0x79, 0x81, 0xe2, 0xc8,
+ /*6740:*/ 0x97, 0x9f, 0x7e, 0x9b, 0xf4, 0x9a, 0x8f, 0x10, 0x75, 0x23, 0x4a, 0xb9, 0xbd, 0x0d, 0x25, 0xa1,
+ /*6750:*/ 0x50, 0xdf, 0x40, 0x23, 0xbf, 0x1c, 0x83, 0xcd, 0x4c, 0xb7, 0xa3, 0x51, 0x7f, 0xca, 0x44, 0x23,
+ /*6760:*/ 0xbe, 0xd8, 0x74, 0x8a, 0x4c, 0xb3, 0x72, 0x93, 0xaa, 0x9a, 0x32, 0x11, 0xc1, 0x4b, 0x9b, 0x96,
+ /*6770:*/ 0x88, 0x61, 0xc7, 0x22, 0xa3, 0x6c, 0x28, 0xf1, 0x17, 0xa5, 0x02, 0x5e, 0x6d, 0x71, 0x44, 0xe7,
+ /*6780:*/ 0xa6, 0x63, 0x9e, 0xee, 0xc6, 0xef, 0xc0, 0x18, 0xf8, 0xea, 0xf8, 0x78, 0x73, 0x8f, 0xae, 0xed,
+ /*6790:*/ 0xb3, 0x5b, 0x80, 0x12, 0x5b, 0x47, 0x48, 0x54, 0x3a, 0xf3, 0xaf, 0x37, 0x14, 0xc3, 0x8c, 0x09,
+ /*67a0:*/ 0x1e, 0x11, 0xb5, 0xc2, 0x82, 0xef, 0x31, 0x36, 0xe6, 0x73, 0xbe, 0xea, 0x98, 0x4f, 0x14, 0x17,
+ /*67b0:*/ 0x1d, 0xbb, 0x89, 0xba, 0x95, 0xf6, 0x79, 0xa9, 0x71, 0xc0, 0x47, 0xf1, 0x86, 0x18, 0x7c, 0x74,
+ /*67c0:*/ 0x18, 0x27, 0xb7, 0x28, 0x27, 0xf6, 0x2a, 0x4a, 0xcc, 0x8e, 0x7a, 0x0f, 0x90, 0x65, 0x9a, 0xc0,
+ /*67d0:*/ 0xd1, 0xba, 0xf3, 0xd8, 0x49, 0x6a, 0x88, 0x68, 0x41, 0xaa, 0xb9, 0x28, 0xfe, 0x4f, 0xe4, 0x3e,
+ /*67e0:*/ 0x1b, 0xc8, 0xa2, 0x0f, 0x38, 0x8d, 0x7b, 0x63, 0xee, 0x46, 0xbd, 0xa2, 0x75, 0xb3, 0x27, 0x35,
+ /*67f0:*/ 0x72, 0xa7, 0xd4, 0xdd, 0xea, 0xdb, 0xb6, 0x1a, 0x65, 0x39, 0xce, 0xc3, 0x83, 0x65, 0x2d, 0x83,
+ /*6800:*/ 0xb0, 0xf1, 0xd9, 0xa1, 0xb0, 0x48, 0x0f, 0x55, 0x48, 0x3b, 0x78, 0x98, 0xc9, 0x3a, 0x93, 0xbc,
+ /*6810:*/ 0xdb, 0x43, 0x32, 0x27, 0xf6, 0xba, 0xb7, 0xb7, 0x99, 0x11, 0x04, 0xa9, 0x4f, 0x8f, 0x89, 0x30,
+ /*6820:*/ 0x19, 0xad, 0x0d, 0x30, 0xfd, 0x02, 0xfa, 0x87, 0x73, 0xc1, 0x18, 0x07, 0x51, 0x54, 0x1b, 0xdf,
+ /*6830:*/ 0xae, 0xfd, 0x6f, 0x62, 0x23, 0x0b, 0x7b, 0xfb, 0x8a, 0xf8, 0x2b, 0xcc, 0x69, 0x0e, 0x56, 0x6d,
+ /*6840:*/ 0x35, 0x9d, 0xbd, 0x71, 0x51, 0xa7, 0xd9, 0xeb, 0x34, 0x9a, 0x95, 0x9d, 0x52, 0x71, 0x3e, 0x04,
+ /*6850:*/ 0x9f, 0x20, 0xfb, 0xf8, 0x6a, 0xf7, 0x7d, 0x3e, 0x1f, 0xeb, 0x71, 0xe4, 0xf1, 0xbf, 0xb8, 0xb9,
+ /*6860:*/ 0x62, 0x70, 0x84, 0x87, 0xdc, 0x9e, 0xaf, 0x21, 0xd7, 0xa3, 0x58, 0x03, 0x90, 0x9e, 0xcb, 0x9f,
+ /*6870:*/ 0x5d, 0x48, 0xfb, 0xb7, 0xa6, 0x0e, 0x94, 0xb2, 0xaa, 0x4a, 0xb5, 0x7e, 0xfc, 0x6b, 0xd1, 0x59,
+ /*6880:*/ 0x80, 0xec, 0xb0, 0x91, 0x68, 0x62, 0xd1, 0x93, 0x25, 0x70, 0xf7, 0x47, 0x31, 0x69, 0xc9, 0x05,
+ /*6890:*/ 0x31, 0x5b, 0x97, 0x48, 0x28, 0xee, 0xb0, 0x77, 0xac, 0x56, 0xde, 0xb0, 0x5f, 0x14, 0x19, 0x58,
+ /*68a0:*/ 0x1f, 0xd1, 0x31, 0xf6, 0x02, 0xcb, 0x81, 0x6a, 0xac, 0x57, 0x62, 0xea, 0xb9, 0xf0, 0x8f, 0xfd,
+ /*68b0:*/ 0x78, 0xbf, 0xbc, 0x3b, 0xf2, 0x41, 0x2c, 0xff, 0x6e, 0x83, 0x5d, 0xde, 0x22, 0x7b, 0x48, 0x65,
+ /*68c0:*/ 0xac, 0x72, 0xce, 0x12, 0xcf, 0x0c, 0x27, 0x9b, 0xd5, 0x8d, 0xf3, 0x32, 0x1a, 0x4f, 0x67, 0xa6,
+ /*68d0:*/ 0xeb, 0x6a, 0x4c, 0xc8, 0x81, 0x35, 0xd0, 0x22, 0x75, 0xc9, 0xd1, 0x29, 0x8e, 0x42, 0x73, 0x99,
+ /*68e0:*/ 0xdd, 0x50, 0x7e, 0x3c, 0xcb, 0x5f, 0xca, 0xbf, 0x8d, 0x66, 0x13, 0x0e, 0x19, 0x01, 0x58, 0x2d,
+ /*68f0:*/ 0x16, 0x91, 0xb4, 0x40, 0xba, 0xed, 0x9a, 0x02, 0x04, 0xa3, 0x82, 0x14, 0x9d, 0x8b, 0xcc, 0xd5,
+ /*6900:*/ 0xf5, 0x6f, 0x78, 0x60, 0xe5, 0x8b, 0x06, 0xc7, 0xf0, 0xb0, 0x5d, 0xd7, 0x2e, 0x0f, 0xa0, 0x6b,
+ /*6910:*/ 0x39, 0xcd, 0xb4, 0x2a, 0x2d, 0x81, 0x97, 0xa1, 0xab, 0x07, 0x8c, 0x7e, 0xbc, 0x68, 0x13, 0x38,
+ /*6920:*/ 0x85, 0x0a, 0x88, 0x17, 0xf3, 0xba, 0xbf, 0x58, 0x9c, 0xbe, 0x43, 0x3d, 0x36, 0xc3, 0x92, 0x8c,
+ /*6930:*/ 0x31, 0x90, 0xe3, 0x05, 0x3f, 0x6a, 0x25, 0x6e, 0x65, 0xd7, 0x62, 0x60, 0x6e, 0x79, 0x02, 0x62,
+ /*6940:*/ 0xec, 0xd5, 0x9b, 0x99, 0xe4, 0x30, 0xd8, 0xf1, 0x99, 0x45, 0x9d, 0xfb, 0x62, 0x5a, 0x3f, 0x3e,
+ /*6950:*/ 0x2d, 0x75, 0x94, 0x5c, 0x04, 0x31, 0xc0, 0x56, 0xeb, 0x37, 0x29, 0x60, 0x3c, 0x29, 0x63, 0x54,
+ /*6960:*/ 0x24, 0x1f, 0x34, 0xd3, 0x81, 0x5c, 0x2b, 0x07, 0x78, 0x6a, 0xab, 0x85, 0x02, 0x50, 0xd3, 0x0f,
+ /*6970:*/ 0x0f, 0x94, 0x3b, 0x33, 0x9a, 0xcc, 0x99, 0xad, 0xcc, 0xfc, 0xa3, 0xdf, 0xc9, 0xe7, 0x90, 0xb7,
+ /*6980:*/ 0xc1, 0x76, 0xb5, 0x01, 0x66, 0xa1, 0x33, 0x38, 0x26, 0xa6, 0xbb, 0xff, 0xaf, 0x10, 0x27, 0x0a,
+ /*6990:*/ 0x96, 0x6b, 0x1d, 0x74, 0xb1, 0x7d, 0xa9, 0x17, 0x5c, 0x4f, 0x2d, 0x2e, 0x69, 0xaa, 0xb6, 0x4f,
+ /*69a0:*/ 0x95, 0xa7, 0x90, 0xcd, 0x1b, 0x60, 0xb0, 0x68, 0x93, 0x91, 0xba, 0x34, 0xa8, 0x2d, 0xe4, 0xfe,
+ /*69b0:*/ 0xa0, 0x8b, 0x9e, 0x82, 0x77, 0x7a, 0xe3, 0x32, 0xc1, 0x8c, 0x50, 0xdf, 0x49, 0x5f, 0x57, 0xd4,
+ /*69c0:*/ 0x55, 0xe4, 0x25, 0xf0, 0x07, 0x91, 0xaa, 0x77, 0x9b, 0xf9, 0x99, 0xfb, 0x98, 0xd0, 0x01, 0xf8,
+ /*69d0:*/ 0x6b, 0x14, 0xd3, 0xc1, 0x2d, 0xcb, 0x3e, 0xb7, 0xd5, 0xe8, 0x61, 0x20, 0xbd, 0xa5, 0xe3, 0xe0,
+ /*69e0:*/ 0x11, 0x6e, 0x3b, 0xe5, 0x6e, 0xe0, 0xdc, 0x2f, 0x4c, 0x8b, 0x14, 0xa7, 0x08, 0x93, 0xcd, 0xf3,
+ /*69f0:*/ 0x5c, 0x8e, 0x30, 0xab, 0x09, 0x36, 0x70, 0xe9, 0x0c, 0x09, 0x93, 0x45, 0xad, 0x2a, 0x6c, 0xdf,
+ /*6a00:*/ 0x30, 0xe9, 0x50, 0xae, 0x8b, 0x94, 0x5f, 0x20, 0x52, 0xf1, 0x91, 0x22, 0x07, 0xb6, 0x3a, 0x14,
+ /*6a10:*/ 0xa1, 0x33, 0x78, 0x80, 0xa6, 0x49, 0x08, 0xbf, 0xfc, 0xc2, 0x4c, 0x49, 0xee, 0x93, 0x33, 0x77,
+ /*6a20:*/ 0xfd, 0x7d, 0xb6, 0x3d, 0x23, 0x8f, 0x5a, 0x90, 0xa0, 0xe0, 0x3c, 0xc9, 0x93, 0x97, 0x00, 0x16,
+ /*6a30:*/ 0xc2, 0xeb, 0x9b, 0xfa, 0x24, 0x04, 0xc7, 0x9e, 0x46, 0xbf, 0x14, 0xa7, 0x97, 0x03, 0x5d, 0x25,
+ /*6a40:*/ 0x08, 0xb2, 0xf4, 0xa0, 0x1e, 0xe5, 0x47, 0x36, 0x64, 0x7e, 0xab, 0x5d, 0xa8, 0x04, 0x18, 0x84,
+ /*6a50:*/ 0x8e, 0x3d, 0x96, 0xa8, 0xc9, 0xfb, 0xe0, 0x1f, 0x8d, 0xa8, 0x77, 0x73, 0xe5, 0x6c, 0xcf, 0xbf,
+ /*6a60:*/ 0x65, 0x9c, 0x73, 0x73, 0xed, 0x36, 0x18, 0xbd, 0xcb, 0xd0, 0xb2, 0x87, 0xea, 0x0a, 0x18, 0xf5,
+ /*6a70:*/ 0x7c, 0x0f, 0xf7, 0x6b, 0x35, 0x4f, 0xd9, 0x07, 0x8a, 0xa1, 0xa4, 0x21, 0x40, 0x81, 0x75, 0xff,
+ /*6a80:*/ 0x73, 0xeb, 0xcb, 0xda, 0x30, 0x09, 0xd5, 0x2a, 0x30, 0x5c, 0xd7, 0x86, 0x72, 0xe5, 0xc9, 0x31,
+ /*6a90:*/ 0xca, 0x91, 0xc9, 0x90, 0x48, 0xae, 0x14, 0x59, 0xc3, 0x7e, 0x82, 0xb6, 0x9d, 0x56, 0x10, 0x59,
+ /*6aa0:*/ 0xd7, 0x14, 0xbb, 0x47, 0x61, 0xd8, 0x53, 0x2b, 0x56, 0x62, 0xf2, 0x8f, 0x84, 0x58, 0x1b, 0xfb,
+ /*6ab0:*/ 0x95, 0x8d, 0x29, 0x78, 0xf5, 0x35, 0xeb, 0xe0, 0xe1, 0x1e, 0x9b, 0x66, 0x5f, 0xbd, 0xf9, 0x8f,
+ /*6ac0:*/ 0x3d, 0x12, 0x95, 0xb2, 0xbb, 0x75, 0x84, 0x36, 0x51, 0x33, 0xfa, 0x5a, 0x32, 0x16, 0x93, 0x12,
+ /*6ad0:*/ 0x12, 0x31, 0xb5, 0x48, 0x14, 0xb4, 0xdc, 0xcb, 0xb3, 0x38, 0xa7, 0x0b, 0x60, 0x56, 0xfa, 0x73,
+ /*6ae0:*/ 0x28, 0x5d, 0xcf, 0x1b, 0x56, 0x4d, 0x6f, 0xea, 0xea, 0xbd, 0xfc, 0xe6, 0x3c, 0x5c, 0x41, 0x8a,
+ /*6af0:*/ 0x3f, 0x6c, 0xfc, 0x7d, 0x8b, 0x66, 0x4d, 0x51, 0x8d, 0x71, 0x0e, 0xbf, 0xdd, 0xa1, 0x1e, 0x92,
+ /*6b00:*/ 0x7c, 0x4e, 0xd4, 0x6e, 0x0c, 0xaa, 0x50, 0x96, 0xce, 0x90, 0x55, 0xcb, 0x86, 0x24, 0xf2, 0x33,
+ /*6b10:*/ 0xab, 0x9b, 0xc6, 0x60, 0x0d, 0x7f, 0x5b, 0x94, 0x16, 0xd3, 0x55, 0xb7, 0xb4, 0x9e, 0xfe, 0xf0,
+ /*6b20:*/ 0xdc, 0xae, 0x2c, 0xc5, 0x24, 0x0f, 0x7e, 0x99, 0xe4, 0x77, 0x0e, 0x96, 0x90, 0xe8, 0x39, 0xac,
+ /*6b30:*/ 0x8a, 0x53, 0xfb, 0xe8, 0x75, 0x24, 0x69, 0x6f, 0xb2, 0x11, 0x2a, 0x45, 0x2d, 0x2f, 0x87, 0xac,
+ /*6b40:*/ 0xfa, 0xea, 0xd5, 0x70, 0x98, 0x39, 0xdb, 0x81, 0xcd, 0x56, 0xdd, 0x4f, 0xdf, 0x78, 0xe1, 0x2c,
+ /*6b50:*/ 0xab, 0x35, 0x54, 0x37, 0x11, 0xf7, 0x23, 0x31, 0xda, 0xb1, 0xd8, 0x76, 0x2e, 0x86, 0xaa, 0xc7,
+ /*6b60:*/ 0x8e, 0x73, 0x6a, 0xba, 0x2a, 0x98, 0xd3, 0x6b, 0x8a, 0x1f, 0x1d, 0xd3, 0xe9, 0x04, 0x3f, 0xf0,
+ /*6b70:*/ 0xdb, 0xb8, 0x06, 0xd9, 0xae, 0x7e, 0xcb, 0xbf, 0x3d, 0x85, 0xa6, 0x10, 0x30, 0xbc, 0x04, 0x96,
+ /*6b80:*/ 0x2a, 0xc8, 0x89, 0xa9, 0xa6, 0x14, 0xdc, 0x75, 0x4d, 0x5a, 0xe5, 0x4a, 0x89, 0x49, 0x58, 0x1a,
+ /*6b90:*/ 0x4a, 0x07, 0x55, 0x28, 0xd8, 0x5a, 0x12, 0xa0, 0x97, 0x0e, 0xcb, 0x3b, 0x70, 0xb1, 0xa9, 0xaf,
+ /*6ba0:*/ 0x3a, 0xd3, 0x5b, 0xbb, 0x07, 0x4a, 0x3e, 0x04, 0xa7, 0x2f, 0x1e, 0xb7, 0xa3, 0x80, 0xa5, 0x5d,
+ /*6bb0:*/ 0x52, 0x1c, 0x45, 0xd4, 0x11, 0xdf, 0x1a, 0xc0, 0x8d, 0xf6, 0xe4, 0x87, 0x07, 0xa3, 0xb3, 0xa1,
+ /*6bc0:*/ 0xe0, 0x5d, 0x68, 0x0a, 0x2f, 0x94, 0xc3, 0xab, 0x98, 0x76, 0x5e, 0x71, 0xf3, 0x75, 0xb2, 0xcd,
+ /*6bd0:*/ 0x38, 0x38, 0x8e, 0xa3, 0x10, 0xb8, 0xc3, 0x83, 0x71, 0xde, 0x20, 0xa2, 0x62, 0xa9, 0x5f, 0x28,
+ /*6be0:*/ 0xbb, 0xfd, 0x14, 0x11, 0x6c, 0x9f, 0x90, 0x0e, 0x47, 0x0d, 0xf0, 0x28, 0x52, 0x55, 0x1c, 0x5e,
+ /*6bf0:*/ 0xf2, 0x8d, 0x70, 0x81, 0x73, 0x6b, 0x7a, 0x7d, 0x21, 0x3e, 0x8e, 0x4c, 0x80, 0x38, 0x8e, 0x4c,
+ /*6c00:*/ 0x7e, 0x29, 0x99, 0x07, 0x05, 0x25, 0x81, 0x66, 0x64, 0x34, 0x95, 0x45, 0x8c, 0xf3, 0x00, 0x81,
+ /*6c10:*/ 0x81, 0xb8, 0x91, 0xb4, 0xfc, 0x83, 0xc4, 0xac, 0x60, 0xfd, 0x01, 0x04, 0x7a, 0xff, 0x87, 0x04,
+ /*6c20:*/ 0x79, 0x40, 0xc0, 0x93, 0x72, 0x66, 0x32, 0xc6, 0xc1, 0x42, 0xe5, 0x5e, 0x74, 0xd5, 0x3b, 0xb8,
+ /*6c30:*/ 0xde, 0xca, 0xbd, 0x17, 0xc0, 0x5f, 0x93, 0xe5, 0xdc, 0xe7, 0xdb, 0xf8, 0x53, 0x70, 0x01, 0x4d,
+ /*6c40:*/ 0x7a, 0x78, 0x1f, 0xc9, 0xa8, 0x96, 0xbb, 0xde, 0x29, 0xf8, 0x0b, 0x32, 0xd2, 0x9b, 0x00, 0x33,
+ /*6c50:*/ 0x96, 0xa5, 0xd6, 0x7f, 0x88, 0x78, 0x3d, 0x03, 0x39, 0x8b, 0x82, 0x48, 0x88, 0xd6, 0x2d, 0x3d,
+ /*6c60:*/ 0xc5, 0x13, 0xee, 0x2b, 0x61, 0x54, 0xf2, 0x10, 0xec, 0xd2, 0x8d, 0x4a, 0xc4, 0xbe, 0xef, 0x36,
+ /*6c70:*/ 0x39, 0x4f, 0xdc, 0x63, 0xb7, 0x0c, 0x40, 0x38, 0x47, 0x85, 0x40, 0xc7, 0x8b, 0xfa, 0x1f, 0x69,
+ /*6c80:*/ 0x9f, 0xd9, 0xf7, 0x4f, 0x68, 0x7f, 0x34, 0x23, 0xfc, 0x95, 0xee, 0xb2, 0x1c, 0x18, 0xda, 0x2a,
+ /*6c90:*/ 0x2b, 0x78, 0x53, 0x53, 0xa4, 0x32, 0x01, 0x83, 0xf6, 0x3e, 0xf5, 0x40, 0xb2, 0xae, 0x0f, 0x1f,
+ /*6ca0:*/ 0xf7, 0x1f, 0x7f, 0x69, 0x4e, 0x44, 0x54, 0x24, 0x2d, 0x82, 0x32, 0xd3, 0x71, 0x8f, 0xf4, 0x68,
+ /*6cb0:*/ 0x79, 0xc0, 0xdc, 0x98, 0xa6, 0xfb, 0x9b, 0xde, 0xa5, 0xb3, 0xea, 0xbd, 0x02, 0x64, 0xcc, 0xd9,
+ /*6cc0:*/ 0xa2, 0x25, 0x1c, 0x42, 0x15, 0xa8, 0xf0, 0xe5, 0x43, 0x94, 0x39, 0xaf, 0x10, 0xc3, 0x20, 0xa9,
+ /*6cd0:*/ 0x49, 0x2d, 0x12, 0x9f, 0x8e, 0xe5, 0x10, 0x5f, 0x67, 0xb4, 0x55, 0x7a, 0x58, 0x7c, 0xfd, 0xf0,
+ /*6ce0:*/ 0x13, 0x8a, 0xfe, 0xff, 0x5e, 0xfc, 0xc1, 0x93, 0x57, 0xa8, 0x7f, 0xe0, 0x5e, 0xad, 0x63, 0xa8,
+ /*6cf0:*/ 0x38, 0x0c, 0xa3, 0xfa, 0xb3, 0xab, 0x67, 0x4a, 0x09, 0xb8, 0xe5, 0xb2, 0xbd, 0x52, 0xa6, 0xb2,
+ /*6d00:*/ 0x9f, 0x07, 0xe7, 0xce, 0x31, 0xe3, 0x14, 0x82, 0x99, 0xca, 0xad, 0x55, 0x9b, 0xb6, 0x9e, 0x2f,
+ /*6d10:*/ 0xa4, 0x4f, 0xc7, 0xaa, 0x84, 0xfb, 0x22, 0x0a, 0x45, 0x7d, 0xab, 0x24, 0xd5, 0xe3, 0xd2, 0xb1,
+ /*6d20:*/ 0x12, 0xc7, 0xda, 0x73, 0xe8, 0xd4, 0x43, 0x56, 0xaa, 0x9d, 0xc9, 0x0a, 0x9a, 0x19, 0x12, 0x08,
+ /*6d30:*/ 0x89, 0x6f, 0x37, 0x59, 0xfe, 0x67, 0x0f, 0x3c, 0x7b, 0xae, 0x30, 0xa7, 0x1b, 0x6e, 0x8d, 0xb9,
+ /*6d40:*/ 0xd1, 0x6f, 0x94, 0x03, 0x95, 0x22, 0x90, 0xdd, 0x2a, 0xb2, 0xc2, 0x7a, 0x12, 0xe6, 0xad, 0x41,
+ /*6d50:*/ 0xe6, 0xeb, 0x85, 0x8e, 0x98, 0xc0, 0xe1, 0xeb, 0x87, 0xaa, 0xf0, 0xd4, 0xde, 0x5e, 0x32, 0xdb,
+ /*6d60:*/ 0x73, 0xca, 0xc8, 0x5f, 0x87, 0xca, 0x00, 0x3b, 0xfe, 0x3d, 0x0f, 0x90, 0x75, 0xe1, 0x8b, 0xf6,
+ /*6d70:*/ 0x73, 0x46, 0x86, 0x87, 0x98, 0xbf, 0x7d, 0x6d, 0x21, 0xec, 0xa3, 0x8c, 0x5a, 0x53, 0x48, 0x06,
+ /*6d80:*/ 0x56, 0x9a, 0x3d, 0x2b, 0x0a, 0xd7, 0x85, 0x14, 0x0f, 0x12, 0x19, 0x91, 0xcb, 0xb1, 0x9e, 0x6d,
+ /*6d90:*/ 0x9c, 0x27, 0xb2, 0x4e, 0x36, 0xeb, 0xa6, 0x25, 0x22, 0x4a, 0x15, 0x21, 0xd6, 0x23, 0xcf, 0xf1,
+ /*6da0:*/ 0xdf, 0xba, 0x0a, 0xb0, 0x6b, 0xd9, 0xd1, 0x43, 0xfd, 0x0a, 0xa8, 0xf3, 0xf0, 0x34, 0x78, 0x41,
+ /*6db0:*/ 0x7e, 0x70, 0xf4, 0x40, 0xbf, 0x82, 0x37, 0x79, 0xef, 0xe5, 0x80, 0x48, 0x1f, 0x91, 0x47, 0xd6,
+ /*6dc0:*/ 0x7e, 0x41, 0x92, 0x1e, 0x59, 0x28, 0x05, 0xcc, 0xa6, 0xd2, 0xb8, 0xe0, 0x2c, 0xc0, 0x23, 0x58,
+ /*6dd0:*/ 0x50, 0x3a, 0x96, 0x83, 0xd5, 0xa8, 0xa1, 0x82, 0x88, 0x43, 0xab, 0x0b, 0x88, 0xbe, 0xb7, 0x2d,
+ /*6de0:*/ 0x6f, 0x19, 0x74, 0x41, 0x6f, 0xb9, 0xd4, 0xea, 0x25, 0xe1, 0xc5, 0x62, 0x87, 0xb6, 0x0c, 0x2a,
+ /*6df0:*/ 0x5b, 0x9b, 0xa4, 0xa2, 0xcf, 0x9c, 0xb7, 0x60, 0x3a, 0x99, 0x1a, 0x37, 0xf9, 0xf9, 0xce, 0x49,
+ /*6e00:*/ 0x64, 0x2f, 0x3a, 0xc2, 0x35, 0x1b, 0x48, 0x99, 0x64, 0xdb, 0x26, 0xb4, 0x96, 0x74, 0x48, 0x2a,
+ /*6e10:*/ 0x98, 0x39, 0x51, 0x6b, 0x95, 0xb8, 0xaa, 0x47, 0xaf, 0xba, 0xc9, 0x75, 0x3a, 0x83, 0xf4, 0x6b,
+ /*6e20:*/ 0xc2, 0xe2, 0x9d, 0x35, 0x04, 0x4a, 0x7c, 0x2c, 0xa4, 0xac, 0xaf, 0xd4, 0xb6, 0x9c, 0x8c, 0xb1,
+ /*6e30:*/ 0xf7, 0xff, 0xca, 0xab, 0xda, 0x74, 0x70, 0xaf, 0xfc, 0x79, 0x64, 0x0f, 0x24, 0xb6, 0xab, 0x66,
+ /*6e40:*/ 0x0c, 0x31, 0x15, 0xaa, 0x1e, 0xa8, 0x52, 0xc2, 0x19, 0x93, 0x8c, 0x46, 0xbb, 0x66, 0x66, 0xa0,
+ /*6e50:*/ 0xfb, 0xc8, 0x1d, 0x39, 0x89, 0xed, 0xcc, 0x6c, 0x16, 0x88, 0x4d, 0xc4, 0x28, 0x98, 0x1b, 0x6d,
+ /*6e60:*/ 0xa4, 0x42, 0x67, 0x00, 0x06, 0xf8, 0xd5, 0x2b, 0xc2, 0xe3, 0xc7, 0xa7, 0x19, 0x32, 0xcf, 0x79,
+ /*6e70:*/ 0xce, 0x4b, 0x5f, 0x7f, 0xfe, 0xd6, 0xb1, 0xc8, 0xec, 0xe6, 0x96, 0x8b, 0x6a, 0xf6, 0xa4, 0x2b,
+ /*6e80:*/ 0xa7, 0x8f, 0xd8, 0xb1, 0x1f, 0xc5, 0xce, 0x24, 0xfe, 0xd0, 0xd7, 0xd7, 0xd9, 0xfb, 0x8e, 0x19,
+ /*6e90:*/ 0xfd, 0x6f, 0x54, 0x3a, 0x73, 0xbe, 0x0a, 0x5c, 0xd0, 0x1e, 0xf2, 0x85, 0x7c, 0x1e, 0x18, 0xc9,
+ /*6ea0:*/ 0x4f, 0x86, 0x9b, 0x71, 0x1f, 0x0a, 0x75, 0xc4, 0x5d, 0x68, 0xac, 0x1a, 0xef, 0xce, 0xdf, 0xb0,
+ /*6eb0:*/ 0x23, 0x4b, 0x79, 0xa1, 0x64, 0x86, 0x07, 0xa2, 0x91, 0x0d, 0x00, 0x36, 0xf1, 0xbe, 0xe7, 0x4a,
+ /*6ec0:*/ 0x03, 0x13, 0xf2, 0xc0, 0x40, 0x8a, 0x82, 0x49, 0xa8, 0x80, 0x9c, 0xda, 0x0c, 0xe8, 0xf9, 0xb3,
+ /*6ed0:*/ 0x5c, 0xbb, 0x5c, 0x2b, 0x8b, 0xf7, 0xdd, 0x8f, 0x7a, 0x7a, 0xac, 0x29, 0x65, 0x36, 0xb5, 0xc9,
+ /*6ee0:*/ 0xac, 0x60, 0x77, 0x12, 0xe3, 0x2e, 0xbf, 0x7c, 0xdd, 0x3a, 0x99, 0xe9, 0x79, 0xed, 0x36, 0x85,
+ /*6ef0:*/ 0x0b, 0xc5, 0xe7, 0x0d, 0xdb, 0x4d, 0x5e, 0x8c, 0x3a, 0xb5, 0xc2, 0x09, 0x52, 0xf9, 0xf8, 0x90,
+ /*6f00:*/ 0xbd, 0x35, 0x94, 0x27, 0x21, 0xe1, 0xbf, 0xa7, 0xb6, 0x1d, 0x31, 0x23, 0x55, 0x5c, 0xec, 0x78,
+ /*6f10:*/ 0xe6, 0x86, 0xd0, 0x3a, 0x32, 0x14, 0x2a, 0x20, 0x20, 0x59, 0x78, 0x24, 0xab, 0x27, 0xb5, 0xa0,
+ /*6f20:*/ 0x13, 0xfc, 0xf5, 0x5b, 0x1e, 0xad, 0x3a, 0x36, 0x40, 0x18, 0x4a, 0x73, 0x5b, 0xdd, 0x8d, 0xb2,
+ /*6f30:*/ 0xc3, 0xb9, 0xe4, 0x15, 0xf0, 0xd6, 0xf6, 0xf3, 0x5c, 0x26, 0x00, 0x22, 0xde, 0x9a, 0xa4, 0xe1,
+ /*6f40:*/ 0x36, 0xa6, 0xd9, 0xe7, 0xc9, 0x9e, 0xd7, 0xb2, 0x64, 0xfb, 0x24, 0xe9, 0xb0, 0xba, 0xa1, 0xa6,
+ /*6f50:*/ 0xc5, 0xc6, 0x7f, 0xbe, 0x22, 0x28, 0x02, 0x62, 0xb5, 0xf4, 0x38, 0xaa, 0x2d, 0x85, 0x45, 0xac,
+ /*6f60:*/ 0xe8, 0xcc, 0xfc, 0x2f, 0x75, 0xec, 0x09, 0xd2, 0xf5, 0x63, 0x64, 0xd0, 0x1a, 0xec, 0xfc, 0xfb,
+ /*6f70:*/ 0x59, 0xea, 0x70, 0x42, 0x09, 0xae, 0xe9, 0xd0, 0x4f, 0xbb, 0x34, 0xa8, 0x9e, 0x76, 0x2b, 0x13,
+ /*6f80:*/ 0x00, 0xe0, 0xde, 0x26, 0x12, 0x49, 0x6c, 0x1c, 0x52, 0xc1, 0x8d, 0xb9, 0x47, 0xaa, 0xff, 0xb3,
+ /*6f90:*/ 0x06, 0x54, 0x5e, 0x5f, 0x77, 0x82, 0x93, 0x8f, 0xd0, 0x62, 0xd6, 0xde, 0xd2, 0x00, 0xb2, 0xc2,
+ /*6fa0:*/ 0x7e, 0x08, 0x34, 0x9b, 0xc5, 0x2e, 0x6d, 0x3d, 0xbf, 0x06, 0xc8, 0xce, 0x3c, 0x96, 0x9b, 0x9c,
+ /*6fb0:*/ 0xe5, 0x94, 0x0c, 0x56, 0x4e, 0x54, 0xcf, 0xee, 0xff, 0xb3, 0x61, 0x66, 0xf3, 0x4a, 0xe0, 0x6b,
+ /*6fc0:*/ 0x20, 0xda, 0xe3, 0x5f, 0x04, 0xf7, 0xef, 0xc6, 0x27, 0x85, 0xb0, 0xf8, 0xf0, 0xf5, 0x37, 0x50,
+ /*6fd0:*/ 0x34, 0x5d, 0xde, 0x5e, 0x20, 0x57, 0x95, 0xe4, 0x30, 0x0d, 0xa9, 0xe8, 0x05, 0xb8, 0x5e, 0xbe,
+ /*6fe0:*/ 0x2d, 0x74, 0x7b, 0x4b, 0xff, 0x5a, 0x88, 0x31, 0xe5, 0x11, 0xe3, 0x90, 0xef, 0xb3, 0xd1, 0x28,
+ /*6ff0:*/ 0x92, 0x24, 0x4d, 0x93, 0xd3, 0x9c, 0xbf, 0xfc, 0x9d, 0x1f, 0x80, 0x4c, 0xdb, 0xbc, 0x82, 0x3f,
+ /*7000:*/ 0x0d, 0xc9, 0xa6, 0xf5, 0x90, 0x95, 0x0c, 0x18, 0x9b, 0x5a, 0x08, 0xe4, 0x6d, 0xed, 0x36, 0x63,
+ /*7010:*/ 0x78, 0x36, 0x56, 0xfc, 0x40, 0xa9, 0xbb, 0x23, 0xbe, 0x39, 0x16, 0xae, 0xe9, 0x3d, 0x2c, 0xc8,
+ /*7020:*/ 0x3f, 0x70, 0xfc, 0x9d, 0x6d, 0x3b, 0xc8, 0x75, 0xb5, 0x62, 0x8a, 0x80, 0xea, 0x90, 0x25, 0x1b,
+ /*7030:*/ 0xc2, 0x6c, 0x24, 0xc8, 0xab, 0x99, 0x6e, 0x32, 0x59, 0x3e, 0x03, 0xd1, 0xab, 0x20, 0xab, 0x64,
+ /*7040:*/ 0x55, 0xf5, 0x98, 0x31, 0x92, 0xc5, 0xcd, 0x26, 0x97, 0xe0, 0x80, 0xc5, 0xfe, 0x65, 0xd4, 0x21,
+ /*7050:*/ 0x45, 0x9e, 0xee, 0xad, 0x59, 0xd5, 0x32, 0x61, 0x62, 0x6b, 0x86, 0x53, 0xeb, 0xed, 0x36, 0x4c,
+ /*7060:*/ 0x59, 0x1e, 0x0f, 0xc7, 0xcf, 0xf4, 0x9b, 0x8c, 0x43, 0x08, 0x2f, 0x9a, 0x5e, 0x2c, 0x1f, 0xdb,
+ /*7070:*/ 0x5e, 0xd7, 0x0b, 0xe8, 0x4e, 0xe5, 0x76, 0x67, 0x18, 0xdc, 0xd9, 0x6e, 0x64, 0xf4, 0x8f, 0x98,
+ /*7080:*/ 0x47, 0x2f, 0x8d, 0x85, 0xbe, 0x9c, 0xd7, 0xaf, 0x2e, 0x56, 0x82, 0x9d, 0x71, 0x91, 0xbd, 0x7d,
+ /*7090:*/ 0xdd, 0x40, 0x85, 0xd9, 0x40, 0x7b, 0x2d, 0x51, 0xd6, 0xf4, 0xc9, 0x49, 0x1d, 0x5f, 0x1a, 0x23,
+ /*70a0:*/ 0xdc, 0xa7, 0x67, 0x16, 0xe4, 0xde, 0x7b, 0xd9, 0xf0, 0xd6, 0x0d, 0x0f, 0x20, 0x06, 0x22, 0x70,
+ /*70b0:*/ 0xcb, 0x63, 0x94, 0xab, 0xdb, 0xc8, 0x3c, 0xa6, 0x20, 0x70, 0xf4, 0xf4, 0x01, 0xac, 0x8e, 0xc7,
+ /*70c0:*/ 0x5a, 0x3c, 0x38, 0x5f, 0x39, 0x06, 0x47, 0x35, 0x5c, 0x98, 0xbf, 0x9c, 0x59, 0xd0, 0x8d, 0x2f,
+ /*70d0:*/ 0x73, 0x13, 0x06, 0x14, 0x5c, 0x10, 0xc6, 0x17, 0x87, 0xc6, 0x4d, 0x1e, 0x54, 0x67, 0x94, 0x2c,
+ /*70e0:*/ 0xf2, 0xfc, 0x9f, 0x8a, 0x55, 0x8e, 0xd4, 0x16, 0x76, 0xe2, 0x4f, 0x94, 0x29, 0xc9, 0x27, 0xd4,
+ /*70f0:*/ 0x84, 0xd1, 0xc3, 0x33, 0xc7, 0xf3, 0x5c, 0x82, 0x11, 0x95, 0x4f, 0xfb, 0x7b, 0xa1, 0x4d, 0xb4,
+ /*7100:*/ 0x8c, 0x83, 0xec, 0xb6, 0xb2, 0x27, 0xaf, 0xeb, 0x31, 0x07, 0x52, 0x40, 0xd0, 0xc4, 0x75, 0x78,
+ /*7110:*/ 0xf5, 0xcf, 0x28, 0xce, 0x4d, 0xcb, 0x72, 0x87, 0x97, 0x48, 0x7c, 0xc2, 0x76, 0xc7, 0x43, 0x36,
+ /*7120:*/ 0xa5, 0x95, 0x0f, 0x90, 0x8b, 0x0a, 0x90, 0xf0, 0xb3, 0x37, 0x59, 0x9d, 0x0a, 0xde, 0x1a, 0x3a,
+ /*7130:*/ 0x6e, 0xcd, 0xff, 0x66, 0x15, 0xef, 0xcc, 0x5b, 0x83, 0x84, 0x76, 0x9d, 0x07, 0xb3, 0xe4, 0x1c,
+ /*7140:*/ 0x36, 0xb3, 0x99, 0xf6, 0x62, 0x6c, 0x96, 0x5d, 0x56, 0xa7, 0xd7, 0xf2, 0xe2, 0x39, 0x9e, 0x63,
+ /*7150:*/ 0x54, 0x2b, 0x45, 0xc4, 0x4e, 0x55, 0x92, 0x80, 0xd7, 0x24, 0x4d, 0x05, 0x3a, 0x86, 0x34, 0x17,
+ /*7160:*/ 0xb1, 0x09, 0xb4, 0xaf, 0x34, 0x35, 0x69, 0x4f, 0x74, 0x1e, 0x9e, 0x8f, 0x9f, 0x7d, 0x89, 0x7d,
+ /*7170:*/ 0x7e, 0x5a, 0x0a, 0x38, 0xe1, 0x53, 0x73, 0x9a, 0x80, 0xdc, 0xea, 0x3f, 0x79, 0xf0, 0xd8, 0x48,
+ /*7180:*/ 0x7f, 0xf7, 0xc8, 0x73, 0x20, 0x3f, 0xbe, 0x71, 0xec, 0xc5, 0x8a, 0x65, 0x17, 0x16, 0xd0, 0xf4,
+ /*7190:*/ 0x7f, 0x21, 0x33, 0x94, 0xe1, 0xa5, 0x93, 0x32, 0x02, 0x0f, 0x3b, 0x74, 0x97, 0x88, 0x59, 0xcb,
+ /*71a0:*/ 0x12, 0xc5, 0x80, 0xd8, 0x7a, 0xe5, 0x89, 0x0c, 0x09, 0x62, 0x2b, 0x58, 0x9b, 0xef, 0xb5, 0x21,
+ /*71b0:*/ 0xed, 0xb2, 0x70, 0x45, 0x9e, 0x17, 0x87, 0x3b, 0x1b, 0xef, 0xb1, 0xee, 0xea, 0x0f, 0x6f, 0x70,
+ /*71c0:*/ 0x7d, 0x4d, 0xf9, 0x40, 0x11, 0x81, 0x97, 0xe7, 0x08, 0x94, 0x64, 0xd3, 0xe1, 0xbe, 0x76, 0xec,
+ /*71d0:*/ 0x95, 0x29, 0x5a, 0x83, 0xb3, 0x75, 0xd7, 0x10, 0xb1, 0x55, 0x7f, 0xc5, 0xd2, 0x57, 0xe3, 0xf8,
+ /*71e0:*/ 0xf0, 0x78, 0xef, 0xd9, 0x9a, 0xa5, 0xa8, 0xf6, 0x3d, 0xc8, 0xf2, 0xce, 0x58, 0xf0, 0x4b, 0x5a,
+ /*71f0:*/ 0xf3, 0xb7, 0xb3, 0xc8, 0x94, 0xe8, 0x1f, 0xef, 0x4b, 0x1d, 0x03, 0x0b, 0xc2, 0x51, 0xbf, 0x48,
+ /*7200:*/ 0xa7, 0xcf, 0xbe, 0x93, 0x5d, 0x93, 0x21, 0xfc, 0x33, 0x45, 0x6d, 0x79, 0xee, 0xb1, 0x8a, 0x60,
+ /*7210:*/ 0x70, 0xce, 0x7c, 0xbc, 0x58, 0x0b, 0x34, 0xb3, 0x8c, 0xd6, 0x8f, 0x94, 0x50, 0xbf, 0x0b, 0x50,
+ /*7220:*/ 0xc4, 0xf9, 0x9a, 0xd7, 0x95, 0x1e, 0xb0, 0x53, 0xe8, 0xd8, 0x14, 0x9e, 0x13, 0x5b, 0x9c, 0x9f,
+ /*7230:*/ 0xb4, 0xf5, 0x0d, 0x65, 0xfa, 0xe2, 0xaf, 0x04, 0x94, 0xda, 0x9f, 0x8e, 0x31, 0x0e, 0x66, 0xb6,
+ /*7240:*/ 0x45, 0x8b, 0xa5, 0xb5, 0xbc, 0x10, 0x30, 0xcf, 0xf7, 0x77, 0x79, 0x87, 0xd4, 0xe4, 0x32, 0xe3,
+ /*7250:*/ 0xce, 0x97, 0x4d, 0x63, 0xe8, 0xe5, 0x06, 0xf1, 0x3b, 0x30, 0x29, 0x35, 0xab, 0xe4, 0x46, 0x68,
+ /*7260:*/ 0x77, 0x94, 0xf7, 0x0d, 0x82, 0xf7, 0x61, 0xcb, 0x84, 0x2f, 0x2f, 0xfe, 0x5d, 0xe1, 0x25, 0x93,
+ /*7270:*/ 0xe2, 0xb3, 0xd2, 0x35, 0xf0, 0x3d, 0x43, 0x20, 0x1d, 0x4e, 0x9f, 0x35, 0x8c, 0x44, 0x95, 0xc5,
+ /*7280:*/ 0x71, 0x12, 0xd2, 0xc7, 0x8b, 0xf1, 0x30, 0x4a, 0x49, 0x51, 0xe4, 0xe9, 0x03, 0x9b, 0x14, 0x51,
+ /*7290:*/ 0x90, 0xbd, 0xbb, 0x9c, 0x21, 0xb8, 0xe0, 0x51, 0xe3, 0xca, 0xf4, 0xb4, 0x10, 0xd5, 0xa4, 0x8d,
+ /*72a0:*/ 0x9d, 0x3f, 0x28, 0x73, 0x7e, 0x5b, 0x6c, 0xe7, 0xca, 0x57, 0x66, 0x8d, 0x5b, 0x34, 0xe9, 0xaa,
+ /*72b0:*/ 0xb4, 0x2f, 0x56, 0x49, 0x1e, 0xa9, 0x14, 0xed, 0x2b, 0xee, 0x43, 0xa1, 0x3e, 0x10, 0xa4, 0xed,
+ /*72c0:*/ 0x1a, 0x13, 0xad, 0x78, 0x7a, 0xf2, 0x6e, 0xad, 0xca, 0x30, 0x2a, 0xa1, 0xd8, 0xf8, 0xe1, 0xd1,
+ /*72d0:*/ 0x91, 0x68, 0x5f, 0x6e, 0xd9, 0x06, 0x91, 0xd2, 0x8b, 0x2a, 0x9e, 0x29, 0x8c, 0xca, 0x5f, 0x46,
+ /*72e0:*/ 0x77, 0x6c, 0x19, 0xdc, 0x92, 0xf9, 0x8f, 0xc9, 0x68, 0x21, 0xe7, 0x6b, 0x89, 0xf5, 0x83, 0xa8,
+ /*72f0:*/ 0x6b, 0x9d, 0xe0, 0x1d, 0x77, 0x20, 0x16, 0x66, 0xe6, 0x53, 0xda, 0x32, 0x02, 0x39, 0x09, 0xcf,
+ /*7300:*/ 0xed, 0x34, 0xec, 0x87, 0xf7, 0xc0, 0x8d, 0xc7, 0xfc, 0x05, 0x7f, 0xc0, 0x6c, 0x78, 0x7c, 0xd9,
+ /*7310:*/ 0xa3, 0x30, 0xe3, 0xa2, 0x14, 0x0f, 0x42, 0xd6, 0x16, 0x62, 0xcb, 0xb6, 0x4a, 0xf4, 0xab, 0xee,
+ /*7320:*/ 0x29, 0x7e, 0xf3, 0xc1, 0x8e, 0xb9, 0xdd, 0x61, 0x44, 0x82, 0x2f, 0x1f, 0xc0, 0x28, 0x36, 0xb8,
+ /*7330:*/ 0x2c, 0xec, 0x2a, 0x4c, 0xe7, 0x50, 0x37, 0x9b, 0x6f, 0xb3, 0xb3, 0xc2, 0x1b, 0xf4, 0x91, 0x88,
+ /*7340:*/ 0x46, 0xb8, 0x2a, 0xbe, 0xc9, 0x56, 0x4e, 0x74, 0x16, 0xd7, 0x1f, 0x49, 0x3b, 0x50, 0xf2, 0x60,
+ /*7350:*/ 0xbe, 0x0f, 0x3d, 0x79, 0x4b, 0xae, 0x5d, 0xe5, 0x8b, 0xea, 0xd9, 0xe6, 0xca, 0x84, 0x85, 0x93,
+ /*7360:*/ 0x84, 0x98, 0x10, 0x0b, 0xa6, 0xfb, 0xb2, 0xa5, 0x3c, 0xc2, 0x79, 0x75, 0x56, 0x69, 0x26, 0x55,
+ /*7370:*/ 0x61, 0x6e, 0xf3, 0x3d, 0xb3, 0xfa, 0xdc, 0xd1, 0xe4, 0x57, 0x8f, 0x8f, 0x04, 0x61, 0xec, 0x42,
+ /*7380:*/ 0x6b, 0xe2, 0x89, 0xe2, 0x22, 0xc4, 0xde, 0x2e, 0xae, 0x0f, 0x78, 0x73, 0x0a, 0x7f, 0x33, 0x4a,
+ /*7390:*/ 0x26, 0x13, 0x11, 0x73, 0x32, 0x7f, 0x30, 0x28, 0x02, 0x40, 0x19, 0xfc, 0xaf, 0xf0, 0x12, 0x0c,
+ /*73a0:*/ 0x64, 0xcd, 0x83, 0x47, 0x66, 0x7e, 0xa5, 0x45, 0x0c, 0x91, 0xd4, 0x13, 0x45, 0x83, 0xd2, 0xbe,
+ /*73b0:*/ 0x1e, 0x7b, 0x00, 0x43, 0xd8, 0x12, 0x6c, 0xfe, 0xc4, 0x15, 0x34, 0x6e, 0x17, 0xb0, 0x18, 0x72,
+ /*73c0:*/ 0xc1, 0x08, 0x8d, 0x8c, 0x25, 0x24, 0x1a, 0xce, 0x06, 0xdb, 0x34, 0x8d, 0xec, 0xcb, 0x95, 0xf0,
+ /*73d0:*/ 0x09, 0x72, 0xa5, 0x5a, 0x22, 0x99, 0x0a, 0x93, 0x88, 0xea, 0x6e, 0x50, 0x80, 0x35, 0x0a, 0x12,
+ /*73e0:*/ 0x3f, 0x88, 0x4e, 0xe9, 0x64, 0x70, 0xc9, 0xea, 0x5a, 0xe1, 0x43, 0xe7, 0xb3, 0xd0, 0x32, 0x16,
+ /*73f0:*/ 0x58, 0xbf, 0x4b, 0xa0, 0x40, 0x26, 0xad, 0x4f, 0x83, 0xbe, 0x44, 0xbd, 0x29, 0xb2, 0x11, 0xd7,
+ /*7400:*/ 0x7a, 0x23, 0xe5, 0xc5, 0xda, 0xfc, 0xa6, 0xf8, 0xa1, 0x26, 0x99, 0xb3, 0xbb, 0x3d, 0xe6, 0x37,
+ /*7410:*/ 0x24, 0x36, 0x89, 0xa3, 0x67, 0x9b, 0x16, 0x46, 0xdf, 0x9c, 0x09, 0x07, 0x00, 0xf7, 0x14, 0xac,
+ /*7420:*/ 0x6c, 0x88, 0x2f, 0xfe, 0x3a, 0x88, 0xf2, 0xbf, 0x88, 0x87, 0x4e, 0xe5, 0x1a, 0xad, 0x70, 0x79,
+ /*7430:*/ 0x85, 0x2c, 0xa4, 0x2c, 0xf7, 0x8c, 0x2c, 0x9c, 0x16, 0x07, 0x3b, 0x64, 0x62, 0x94, 0x6b, 0xca,
+ /*7440:*/ 0x30, 0x6f, 0xe6, 0x86, 0x71, 0x82, 0x32, 0xd5, 0x22, 0xb7, 0x69, 0x44, 0x82, 0xab, 0xaa, 0xe1,
+ /*7450:*/ 0x5e, 0xf3, 0xd6, 0xb3, 0xf9, 0xe0, 0x1a, 0xfa, 0xf5, 0x54, 0x11, 0x7d, 0xf7, 0x38, 0xdb, 0x31,
+ /*7460:*/ 0x38, 0xfb, 0xf4, 0x3b, 0x47, 0x90, 0x1c, 0x57, 0xbf, 0x66, 0x4e, 0x68, 0xd9, 0x67, 0x03, 0x5a,
+ /*7470:*/ 0xa8, 0xd9, 0xe9, 0x91, 0xee, 0x66, 0x9c, 0x5f, 0xeb, 0x18, 0x12, 0xaf, 0x90, 0xf7, 0x58, 0x13,
+ /*7480:*/ 0x41, 0x5e, 0xa9, 0x66, 0xd7, 0x8a, 0xe7, 0x0c, 0xe9, 0x47, 0xa8, 0x96, 0x25, 0x7c, 0x5c, 0x38,
+ /*7490:*/ 0x46, 0xbc, 0x5a, 0x3d, 0x7f, 0xed, 0x9e, 0xc2, 0xc0, 0xde, 0x93, 0xcb, 0xfc, 0x19, 0x47, 0x5c,
+ /*74a0:*/ 0x5a, 0xca, 0x38, 0xd1, 0x88, 0xac, 0x7f, 0xf9, 0xad, 0x6f, 0x90, 0x62, 0x80, 0x6a, 0xac, 0x5e,
+ /*74b0:*/ 0x5c, 0x58, 0xfd, 0xa2, 0x62, 0xf8, 0x05, 0xbb, 0x5d, 0x63, 0x32, 0x74, 0x74, 0xc9, 0x1e, 0x28,
+ /*74c0:*/ 0xb6, 0x0e, 0x16, 0xa7, 0x4e, 0xc1, 0x51, 0x8e, 0x0d, 0xad, 0x1c, 0x8d, 0x3e, 0x86, 0x2b, 0x99,
+ /*74d0:*/ 0x77, 0x7c, 0x97, 0x70, 0xe9, 0xdf, 0x15, 0x83, 0xa9, 0x9c, 0x92, 0x7a, 0xf5, 0x54, 0x98, 0x7b,
+ /*74e0:*/ 0x33, 0xdf, 0xfb, 0xac, 0xde, 0xe8, 0x89, 0xda, 0x49, 0x77, 0x99, 0x22, 0xac, 0x52, 0x21, 0xf6,
+ /*74f0:*/ 0x7c, 0xf5, 0xa1, 0x67, 0x21, 0xc1, 0x7f, 0x65, 0x96, 0xcb, 0x84, 0x67, 0x1e, 0x87, 0x0f, 0x19,
+ /*7500:*/ 0x92, 0x53, 0x19, 0xce, 0x4f, 0xc5, 0x26, 0xef, 0x5b, 0xe6, 0xee, 0x9e, 0xe0, 0x4e, 0x26, 0xbc,
+ /*7510:*/ 0xa7, 0xe7, 0x06, 0x2d, 0x20, 0xd6, 0x5b, 0xe9, 0x57, 0x05, 0x50, 0xc1, 0x53, 0x3d, 0x0c, 0x29,
+ /*7520:*/ 0xc3, 0xb3, 0xd1, 0xe4, 0x20, 0x0f, 0xe1, 0xad, 0x1d, 0x0d, 0xe8, 0xd9, 0x8f, 0x32, 0xf8, 0x85,
+ /*7530:*/ 0xf4, 0xac, 0x21, 0x01, 0x5a, 0x64, 0xc8, 0x8c, 0x40, 0x2f, 0xf8, 0x52, 0xc8, 0x4d, 0x41, 0x2e,
+ /*7540:*/ 0x6d, 0x97, 0x57, 0x37, 0xca, 0xef, 0xba, 0x0a, 0xb2, 0x15, 0x38, 0x4c, 0xa1, 0xe1, 0x94, 0x1e,
+ /*7550:*/ 0xc2, 0x8e, 0x58, 0xe4, 0x8b, 0x6d, 0x52, 0x1d, 0x15, 0x7b, 0x10, 0x4b, 0x50, 0x32, 0x7b, 0xff,
+ /*7560:*/ 0x7b, 0xd4, 0xd9, 0xc6, 0x26, 0x21, 0x76, 0xf7, 0x4f, 0x9d, 0x35, 0x56, 0x50, 0x5a, 0x0b, 0x94,
+ /*7570:*/ 0x8d, 0x60, 0x84, 0x4d, 0xb2, 0xb3, 0x75, 0x9d, 0x34, 0xf6, 0x8f, 0x2d, 0xc9, 0x48, 0xd9, 0x16,
+ /*7580:*/ 0x20, 0xb4, 0xfa, 0xd4, 0x03, 0x1c, 0x0b, 0x6f, 0x56, 0x4a, 0x7b, 0x5b, 0x00, 0x4d, 0x09, 0x98,
+ /*7590:*/ 0x73, 0xd2, 0x14, 0xe7, 0xef, 0xc6, 0xba, 0x03, 0xab, 0xf9, 0xc4, 0x49, 0xa1, 0xc2, 0x56, 0xa5,
+ /*75a0:*/ 0x6b, 0xbc, 0x91, 0x76, 0x80, 0xc8, 0x85, 0x39, 0xd1, 0x05, 0x81, 0x7a, 0x78, 0x91, 0x7c, 0x4e,
+ /*75b0:*/ 0x15, 0x5a, 0x67, 0x76, 0x08, 0xa5, 0x76, 0xf1, 0x6f, 0xc4, 0x6d, 0x36, 0x40, 0xc1, 0x0a, 0x2b,
+ /*75c0:*/ 0xa3, 0x03, 0x6a, 0xf3, 0x20, 0xcc, 0x39, 0x24, 0x15, 0x21, 0x0d, 0xff, 0x0d, 0x75, 0x38, 0x93,
+ /*75d0:*/ 0x5a, 0x5b, 0xb0, 0x95, 0x27, 0x16, 0x4a, 0xd2, 0xf2, 0x44, 0x76, 0x1d, 0x01, 0xef, 0xf2, 0x9e,
+ /*75e0:*/ 0x92, 0xad, 0xe9, 0x00, 0x96, 0x51, 0x59, 0x9e, 0x03, 0xf8, 0xc4, 0xe8, 0xbb, 0xec, 0xa8, 0xce,
+ /*75f0:*/ 0x38, 0xb2, 0xc6, 0x7d, 0x8f, 0x08, 0xc8, 0xb1, 0x94, 0x41, 0xa8, 0xa0, 0x33, 0xcd, 0x6e, 0x85,
+ /*7600:*/ 0x56, 0x54, 0xf8, 0x93, 0xec, 0x92, 0x43, 0xee, 0xed, 0xac, 0xa6, 0x1a, 0xa6, 0xcd, 0x2a, 0xe5,
+ /*7610:*/ 0x78, 0xf5, 0x2e, 0x44, 0xaf, 0x5b, 0x21, 0x55, 0x12, 0x75, 0xf3, 0xb6, 0x09, 0x9c, 0x1a, 0x79,
+ /*7620:*/ 0xc3, 0xf4, 0x5c, 0x5f, 0xb9, 0xb9, 0xf1, 0x0b, 0x90, 0xf1, 0xc9, 0x81, 0x2c, 0x1f, 0xea, 0x57,
+ /*7630:*/ 0xfb, 0xce, 0x80, 0x90, 0xbc, 0x2b, 0x6b, 0x19, 0xaa, 0x6e, 0xef, 0xc3, 0xff, 0x04, 0x5a, 0x46,
+ /*7640:*/ 0x1a, 0x31, 0x58, 0x59, 0x90, 0x51, 0x5b, 0x6e, 0x8d, 0x0e, 0x03, 0xd9, 0x1f, 0x97, 0xdd, 0xdf,
+ /*7650:*/ 0x8c, 0xc7, 0xf7, 0x9c, 0x35, 0xfb, 0x11, 0xb1, 0x46, 0x93, 0x50, 0x93, 0xa4, 0xab, 0x2a, 0x9c,
+ /*7660:*/ 0xc9, 0x05, 0x67, 0x82, 0x4c, 0xa9, 0x5f, 0x12, 0xf0, 0xb4, 0x09, 0xe5, 0x95, 0x16, 0xa4, 0xd2,
+ /*7670:*/ 0x49, 0x01, 0x37, 0xb8, 0x69, 0xdf, 0x89, 0xbc, 0xe5, 0x9a, 0x0c, 0x6a, 0xfd, 0xae, 0xd9, 0xa0,
+ /*7680:*/ 0x3c, 0xeb, 0xb6, 0x4c, 0xe9, 0xcb, 0xc2, 0x88, 0xc6, 0x67, 0x8e, 0xa7, 0x69, 0xf5, 0xfc, 0xb6,
+ /*7690:*/ 0xb7, 0x26, 0xf1, 0x13, 0x9f, 0x30, 0xd2, 0x0f, 0xb0, 0x45, 0x39, 0x32, 0xc7, 0x37, 0xb2, 0xc4,
+ /*76a0:*/ 0x0c, 0xbd, 0x8b, 0xff, 0x2f, 0x79, 0x0c, 0x2a, 0xbe, 0x7b, 0xf5, 0x8e, 0x23, 0xb9, 0x83, 0xe2,
+ /*76b0:*/ 0xbe, 0x90, 0xcd, 0xa3, 0x81, 0x81, 0x64, 0x24, 0xf4, 0x09, 0x27, 0x58, 0xf5, 0x9e, 0x96, 0x1a,
+ /*76c0:*/ 0xd6, 0x75, 0x92, 0x63, 0x18, 0xd8, 0xe6, 0x5e, 0x83, 0x9e, 0x1a, 0xaf, 0xcf, 0x68, 0x72, 0xdc,
+ /*76d0:*/ 0xc3, 0x7b, 0xcb, 0x32, 0x28, 0x84, 0xfd, 0x6c, 0x39, 0x1d, 0xc9, 0x9c, 0x17, 0x2d, 0x28, 0x75,
+ /*76e0:*/ 0xba, 0xa4, 0x00, 0xea, 0xe6, 0x04, 0x1e, 0x70, 0x27, 0x67, 0xff, 0x5b, 0xdd, 0xd1, 0x8f, 0xfc,
+ /*76f0:*/ 0x71, 0x27, 0xd1, 0x53, 0xf3, 0xc6, 0xb3, 0x52, 0x47, 0x43, 0x6a, 0x01, 0x07, 0xf6, 0x0a, 0x21,
+ /*7700:*/ 0x2a, 0xda, 0x4e, 0x03, 0x41, 0x2f, 0xee, 0x85, 0xae, 0x7f, 0x3b, 0xe6, 0x38, 0xf7, 0x97, 0xde,
+ /*7710:*/ 0xf5, 0x67, 0x10, 0x52, 0xd5, 0x20, 0x73, 0x1b, 0xd9, 0x6b, 0x5c, 0x9a, 0x00, 0x90, 0xbc, 0xd3,
+ /*7720:*/ 0x9c, 0x8d, 0x26, 0x87, 0x97, 0x94, 0x8f, 0x6f, 0x05, 0x64, 0x8d, 0x7b, 0x6f, 0x51, 0xf1, 0xf1,
+ /*7730:*/ 0x43, 0xd2, 0xa3, 0x5e, 0xd5, 0x93, 0x4a, 0xe1, 0x83, 0x84, 0x7c, 0xde, 0xcf, 0x65, 0x1f, 0x6a,
+ /*7740:*/ 0x45, 0xba, 0x07, 0xa6, 0x8e, 0xe4, 0x01, 0x4d, 0x22, 0xdf, 0x00, 0x22, 0x39, 0x75, 0x3e, 0x0d,
+ /*7750:*/ 0x8d, 0x3c, 0x68, 0x5b, 0x7c, 0x81, 0xd1, 0xc6, 0x79, 0x2b, 0x54, 0xb7, 0xc1, 0x86, 0x2e, 0x03,
+ /*7760:*/ 0x44, 0xa6, 0xc0, 0xe0, 0x17, 0x59, 0x3a, 0xed, 0x0b, 0x6b, 0x0c, 0x08, 0x0a, 0xce, 0x9a, 0x31,
+ /*7770:*/ 0xa5, 0x94, 0x3c, 0x96, 0x29, 0x8f, 0xc7, 0xb0, 0xa3, 0x54, 0x91, 0x0d, 0xd5, 0x5e, 0xb3, 0x73,
+ /*7780:*/ 0x1a, 0xf6, 0x69, 0xb4, 0xb0, 0x16, 0xc1, 0x28, 0xdc, 0xbd, 0x4e, 0x2f, 0x89, 0x9d, 0xd2, 0xfe,
+ /*7790:*/ 0x4f, 0xb9, 0x7b, 0x81, 0xcb, 0xf3, 0x67, 0x99, 0x85, 0x44, 0x62, 0xb0, 0x77, 0xd8, 0x3b, 0x2b,
+ /*77a0:*/ 0xda, 0x8d, 0xcd, 0xa2, 0xf5, 0x00, 0x35, 0x98, 0xc2, 0xb0, 0x1f, 0x8d, 0x24, 0xac, 0x42, 0x1b,
+ /*77b0:*/ 0x8b, 0xe7, 0xc0, 0x66, 0xa8, 0x91, 0xf0, 0x68, 0x0b, 0x21, 0xe2, 0x0d, 0x71, 0x7f, 0x10, 0x7f,
+ /*77c0:*/ 0x54, 0x0d, 0x77, 0x01, 0x21, 0x48, 0xde, 0x35, 0x7d, 0x3d, 0x7d, 0xde, 0xc1, 0x3a, 0x18, 0x27,
+ /*77d0:*/ 0x63, 0xb2, 0x81, 0x34, 0x6f, 0x6f, 0x61, 0x8f, 0xd4, 0xcb, 0x95, 0x14, 0x13, 0xc5, 0x62, 0xf2,
+ /*77e0:*/ 0x53, 0xed, 0xad, 0x38, 0x92, 0x7d, 0xd5, 0x1b, 0x10, 0x45, 0x42, 0x78, 0xd1, 0x85, 0x2c, 0x42,
+ /*77f0:*/ 0xcb, 0x72, 0x74, 0x0b, 0x8a, 0x08, 0x39, 0x7b, 0x7b, 0xdb, 0x97, 0x69, 0xcc, 0x22, 0xc7, 0x6e,
+ /*7800:*/ 0x13, 0x5a, 0x2b, 0x90, 0x4b, 0xd7, 0xb3, 0x54, 0x7b, 0x64, 0xf4, 0x4e, 0x3e, 0xd2, 0xd1, 0xf0,
+ /*7810:*/ 0xbb, 0xa5, 0xab, 0xd4, 0xd7, 0x5d, 0xb4, 0x4b, 0x43, 0x8b, 0xe4, 0x0b, 0x27, 0xcb, 0x4c, 0xf9,
+ /*7820:*/ 0xe8, 0x9c, 0x24, 0x68, 0x42, 0x57, 0x9f, 0xa6, 0xc9, 0xc7, 0x53, 0xfc, 0x94, 0x1b, 0x18, 0x97,
+ /*7830:*/ 0xd5, 0xeb, 0x24, 0xbc, 0xb9, 0xaa, 0xc8, 0xe0, 0x01, 0x30, 0xc5, 0x01, 0x49, 0xc3, 0x61, 0x8a,
+ /*7840:*/ 0x47, 0x7a, 0x8d, 0x5b, 0x74, 0x0d, 0x48, 0xbf, 0x0c, 0xb3, 0xec, 0xe9, 0xe0, 0x1f, 0x6c, 0x36,
+ /*7850:*/ 0x67, 0xb7, 0xa1, 0xec, 0x9d, 0x51, 0x00, 0x4e, 0x2f, 0x58, 0xae, 0x7f, 0x61, 0x2e, 0x79, 0x24,
+ /*7860:*/ 0x50, 0x38, 0xe2, 0x3e, 0xc4, 0x00, 0xbb, 0xf2, 0x25, 0x5b, 0xa8, 0xf6, 0x75, 0x58, 0x30, 0xd9,
+ /*7870:*/ 0x63, 0x46, 0x4a, 0x62, 0xfc, 0x47, 0x83, 0xb5, 0xb7, 0xb0, 0x21, 0xf1, 0xfb, 0xaa, 0x6b, 0x17,
+ /*7880:*/ 0xb9, 0xa9, 0xea, 0xd0, 0x98, 0xfc, 0xd5, 0x76, 0x4f, 0x7f, 0x04, 0x69, 0x70, 0x49, 0xcc, 0x34,
+ /*7890:*/ 0x1f, 0x88, 0x0f, 0x63, 0x29, 0x47, 0x15, 0x56, 0x30, 0xfc, 0x99, 0xa9, 0xb9, 0x1a, 0x42, 0xe3,
+ /*78a0:*/ 0x0f, 0x28, 0x7a, 0xed, 0xca, 0xad, 0x55, 0x0f, 0xd7, 0xca, 0x5a, 0xae, 0x61, 0x4b, 0x24, 0xd2,
+ /*78b0:*/ 0x77, 0x68, 0xcc, 0xd2, 0x4f, 0x97, 0xc2, 0xeb, 0x79, 0x5c, 0x0a, 0xfe, 0x90, 0x5a, 0x31, 0xcb,
+ /*78c0:*/ 0x26, 0xa4, 0x73, 0x1e, 0xea, 0x43, 0xd4, 0x64, 0x6e, 0x0c, 0x07, 0x9d, 0xea, 0x6c, 0x91, 0x3c,
+ /*78d0:*/ 0x86, 0x72, 0xa6, 0xf2, 0xcd, 0x87, 0xc8, 0xbb, 0xfd, 0xef, 0x05, 0xa1, 0xf7, 0xff, 0x5f, 0x08,
+ /*78e0:*/ 0xc3, 0xc6, 0x55, 0x92, 0xb6, 0xf3, 0x3a, 0x87, 0x2b, 0x40, 0x3e, 0xe0, 0x37, 0x1f, 0xe2, 0xd4,
+ /*78f0:*/ 0x1e, 0x67, 0xc3, 0x87, 0xb6, 0x93, 0x76, 0x99, 0x22, 0x79, 0xfd, 0x1d, 0xbc, 0xf8, 0x2c, 0x54,
+ /*7900:*/ 0x10, 0x03, 0x2f, 0x36, 0xdb, 0x8c, 0x63, 0xba, 0x91, 0xbc, 0xca, 0xe1, 0xd7, 0xc7, 0x8e, 0x32,
+ /*7910:*/ 0x02, 0xb1, 0x77, 0x4d, 0x1d, 0x70, 0x2b, 0x3a, 0x84, 0xea, 0x1f, 0x78, 0xcc, 0xe8, 0x85, 0x30,
+ /*7920:*/ 0xbc, 0xe5, 0xb6, 0x15, 0x31, 0x4f, 0x61, 0xb2, 0x18, 0x5e, 0x36, 0xad, 0x70, 0x75, 0xd8, 0xe4,
+ /*7930:*/ 0x65, 0xdf, 0xac, 0xa1, 0xcc, 0x51, 0x1a, 0x0e, 0x8d, 0x45, 0xc4, 0x46, 0x73, 0x69, 0x2c, 0xc9,
+ /*7940:*/ 0xb3, 0x96, 0x4e, 0x58, 0x5d, 0x57, 0x68, 0x4e, 0x60, 0x48, 0x16, 0x74, 0x5e, 0xc3, 0xd8, 0x61,
+ /*7950:*/ 0x22, 0x30, 0x3b, 0x63, 0x96, 0x02, 0x35, 0x2a, 0x15, 0x21, 0x62, 0x92, 0x66, 0x7b, 0xfa, 0x90,
+ /*7960:*/ 0xfd, 0x63, 0x3c, 0xa7, 0x5a, 0x72, 0xd4, 0x95, 0x63, 0xb8, 0x57, 0x2e, 0x3a, 0x71, 0xa7, 0xd4,
+ /*7970:*/ 0xff, 0xf9, 0x02, 0xd4, 0xc1, 0xfe, 0xeb, 0x3e, 0x8c, 0xbf, 0xab, 0x16, 0x42, 0x2c, 0x0c, 0x57,
+ /*7980:*/ 0x12, 0xf0, 0x5a, 0x64, 0xf5, 0x09, 0x1c, 0x46, 0x7c, 0xfb, 0xe0, 0x68, 0x94, 0x97, 0x2c, 0x70,
+ /*7990:*/ 0x57, 0x13, 0xed, 0xec, 0xdc, 0xd8, 0xab, 0xba, 0x8e, 0x49, 0x87, 0x7c, 0x03, 0x6a, 0x5e, 0xf5,
+ /*79a0:*/ 0xca, 0x09, 0x96, 0x2c, 0x4b, 0xfb, 0x55, 0xb6, 0x1a, 0x04, 0xf0, 0xb0, 0xbc, 0x71, 0x4f, 0x68,
+ /*79b0:*/ 0x7c, 0xd4, 0x04, 0xd8, 0x16, 0x6d, 0xae, 0xa9, 0x62, 0xa7, 0xc0, 0xdd, 0x6c, 0xf5, 0x6a, 0x81,
+ /*79c0:*/ 0x56, 0xb9, 0x09, 0xed, 0x6a, 0xe1, 0x86, 0x44, 0xf7, 0x94, 0xbf, 0xda, 0xcc, 0xf6, 0x9c, 0x7a,
+ /*79d0:*/ 0xe8, 0x11, 0x1f, 0xdc, 0x7d, 0x22, 0xf2, 0xf1, 0xd2, 0x29, 0x28, 0x02, 0x90, 0x08, 0xb3, 0xdc,
+ /*79e0:*/ 0x13, 0xe5, 0x57, 0x6b, 0xd1, 0xd5, 0x4c, 0xc6, 0xed, 0xf2, 0x7f, 0x45, 0x38, 0x74, 0xd2, 0xe5,
+ /*79f0:*/ 0xb3, 0x38, 0x15, 0xc8, 0x55, 0xbe, 0x3c, 0x3d, 0x4e, 0x0c, 0xdd, 0x52, 0x4f, 0xea, 0x31, 0x26,
+ /*7a00:*/ 0x66, 0x93, 0x37, 0x93, 0x2b, 0x0e, 0x3b, 0x36, 0xd7, 0xd5, 0xc4, 0x9b, 0x3d, 0x0a, 0x25, 0x34,
+ /*7a10:*/ 0xcd, 0x7f, 0xea, 0x96, 0x9c, 0x34, 0x8f, 0xb8, 0x4a, 0x22, 0x4d, 0x64, 0x33, 0xc8, 0x79, 0x2d,
+ /*7a20:*/ 0xed, 0xe0, 0x63, 0x19, 0xac, 0xed, 0xf4, 0x95, 0x9e, 0x82, 0x87, 0x6d, 0xdd, 0x13, 0x7f, 0x00,
+ /*7a30:*/ 0xfe, 0x0a, 0xf8, 0x23, 0x1c, 0x6f, 0x53, 0xa4, 0xcd, 0x64, 0xe2, 0xae, 0xb8, 0x27, 0xff, 0x9f,
+ /*7a40:*/ 0xe9, 0x1e, 0xd7, 0x3e, 0x62, 0xc2, 0x3b, 0xfb, 0x2c, 0x93, 0x06, 0xcf, 0x21, 0xdb, 0x65, 0x8c,
+ /*7a50:*/ 0xc5, 0xe0, 0xfa, 0x99, 0x71, 0xf6, 0x55, 0x17, 0x64, 0xc9, 0xd6, 0x79, 0x0f, 0x0d, 0x4b, 0xdc,
+ /*7a60:*/ 0xcf, 0x24, 0x5d, 0x52, 0xed, 0x41, 0xe8, 0x06, 0x31, 0x87, 0x76, 0xdc, 0x4f, 0x79, 0x8e, 0x10,
+ /*7a70:*/ 0xa5, 0x5c, 0x37, 0x8c, 0xd4, 0xf7, 0x72, 0x77, 0xd9, 0x69, 0x24, 0x54, 0xdc, 0xf6, 0x35, 0x97,
+ /*7a80:*/ 0x0d, 0xe4, 0x14, 0xdd, 0xc7, 0x1c, 0x75, 0x5f, 0x2c, 0x33, 0xbe, 0xaa, 0x62, 0xbc, 0x53, 0x04,
+ /*7a90:*/ 0x18, 0xe0, 0x56, 0x8b, 0xdb, 0xcd, 0xcf, 0x98, 0xb5, 0x1b, 0xb4, 0xa9, 0x84, 0xb3, 0x89, 0xcf,
+ /*7aa0:*/ 0x5c, 0x57, 0x2d, 0x3d, 0xea, 0x89, 0xd7, 0x14, 0x1e, 0x3b, 0x1e, 0xfb, 0x2e, 0xf6, 0xa7, 0x62,
+ /*7ab0:*/ 0xd5, 0x21, 0x6f, 0xd2, 0x73, 0xd8, 0x3e, 0xde, 0x1a, 0x65, 0x9f, 0xd0, 0xeb, 0x90, 0x0b, 0x9d,
+ /*7ac0:*/ 0x21, 0xe5, 0x62, 0x5f, 0x31, 0x8c, 0x8e, 0x55, 0x8b, 0x85, 0x38, 0xa3, 0x16, 0xe8, 0x85, 0x48,
+ /*7ad0:*/ 0xce, 0xc9, 0xf3, 0x6e, 0x1c, 0x36, 0xd4, 0x38, 0x44, 0x92, 0x9b, 0xf0, 0xc4, 0x6a, 0x44, 0x13,
+ /*7ae0:*/ 0xfa, 0xde, 0x91, 0x4e, 0x04, 0xeb, 0x70, 0x2d, 0xb4, 0x5f, 0xc5, 0xe0, 0x49, 0x1c, 0x42, 0x4c,
+ /*7af0:*/ 0xca, 0xa2, 0x70, 0xc3, 0x5f, 0x38, 0x9c, 0x3b, 0xed, 0x96, 0xdf, 0x8d, 0x7f, 0x8c, 0xf9, 0x29,
+ /*7b00:*/ 0xe6, 0x5d, 0x4e, 0x0e, 0x9d, 0x47, 0x12, 0x37, 0x0c, 0x59, 0xf7, 0x01, 0xa9, 0xab, 0x4a, 0x08,
+ /*7b10:*/ 0x31, 0x9e, 0x5d, 0x7a, 0xbb, 0xe3, 0x69, 0x03, 0x53, 0xaf, 0xca, 0x96, 0x2e, 0x98, 0x12, 0xfd,
+ /*7b20:*/ 0x30, 0xab, 0xed, 0x90, 0xa2, 0x08, 0xd5, 0x2d, 0xcc, 0xda, 0xc3, 0x1b, 0xf9, 0x4c, 0x83, 0x71,
+ /*7b30:*/ 0xb0, 0x40, 0xc9, 0xe6, 0x1f, 0x03, 0x38, 0xc7, 0x6a, 0x85, 0xe1, 0xae, 0x1f, 0xca, 0x12, 0xe4,
+ /*7b40:*/ 0x6e, 0x9c, 0x1d, 0x6f, 0x6d, 0xa8, 0x2b, 0x9b, 0x46, 0x47, 0x8c, 0xba, 0x32, 0x3d, 0x98, 0x5d,
+ /*7b50:*/ 0x1e, 0xea, 0x08, 0xa6, 0x6d, 0xd8, 0x8a, 0x1c, 0x1c, 0xeb, 0x61, 0x0d, 0xc2, 0x9a, 0x3f, 0x79,
+ /*7b60:*/ 0xf4, 0x73, 0x8f, 0x30, 0xb7, 0x73, 0x06, 0x0c, 0xfc, 0x74, 0xf9, 0x60, 0x05, 0x46, 0xe9, 0x10,
+ /*7b70:*/ 0x1f, 0x8d, 0x01, 0x46, 0xd7, 0xc3, 0x72, 0x19, 0x7f, 0x45, 0x09, 0xe7, 0xe2, 0x9f, 0x7e, 0x57,
+ /*7b80:*/ 0x65, 0x0a, 0x4b, 0x02, 0x51, 0x20, 0xda, 0x6d, 0x09, 0xbf, 0x10, 0x02, 0xbc, 0xb9, 0x57, 0x5a,
+ /*7b90:*/ 0x4d, 0x49, 0x51, 0x9d, 0xb5, 0x1d, 0xb1, 0xf0, 0x1d, 0x31, 0xe1, 0xac, 0x27, 0x28, 0x6f, 0xc2,
+ /*7ba0:*/ 0x2f, 0xd2, 0x2e, 0xb6, 0xe8, 0xa9, 0xaa, 0xfd, 0x48, 0x61, 0x1a, 0xcc, 0x06, 0x33, 0x43, 0x42,
+ /*7bb0:*/ 0x5b, 0x37, 0x63, 0x31, 0xbc, 0x08, 0x0b, 0xea, 0x64, 0x64, 0xbf, 0x64, 0x48, 0xd6, 0x67, 0x02,
+ /*7bc0:*/ 0xda, 0xb3, 0xd4, 0x7b, 0xac, 0x59, 0x47, 0xde, 0x5a, 0x69, 0xac, 0xf4, 0xbc, 0x92, 0x5f, 0x23,
+ /*7bd0:*/ 0x0c, 0xd8, 0x07, 0x48, 0xd4, 0x7a, 0x7e, 0x5b, 0x09, 0xff, 0xc6, 0xc8, 0x6d, 0x64, 0xcb, 0x36,
+ /*7be0:*/ 0x0f, 0x71, 0xe9, 0x8a, 0xa2, 0xbe, 0xee, 0xaa, 0x21, 0xf5, 0xfe, 0xe6, 0xdc, 0x05, 0x19, 0x26,
+ /*7bf0:*/ 0x58, 0x85, 0x09, 0x62, 0x18, 0x96, 0x37, 0x0d, 0xde, 0xf5, 0xbf, 0xe6, 0x96, 0x15, 0xea, 0x51,
+ /*7c00:*/ 0x88, 0x63, 0x2e, 0x1d, 0x08, 0xad, 0xa2, 0x48, 0x0b, 0x93, 0x89, 0xb0, 0xfc, 0x89, 0xa7, 0x64,
+ /*7c10:*/ 0x85, 0x42, 0x55, 0x64, 0x67, 0x76, 0xb9, 0x88, 0x94, 0xa0, 0x4a, 0x6a, 0xf2, 0x5e, 0x02, 0xa8,
+ /*7c20:*/ 0x06, 0xd1, 0x43, 0x8b, 0xfa, 0xe7, 0x99, 0x3b, 0xdc, 0x61, 0xbe, 0x3e, 0x9a, 0xd7, 0xea, 0x8f,
+ /*7c30:*/ 0x67, 0xd4, 0xdd, 0x46, 0x5a, 0x87, 0xed, 0x92, 0x25, 0xe7, 0x0e, 0x27, 0x08, 0x49, 0xfc, 0x5c,
+ /*7c40:*/ 0x22, 0x35, 0xa8, 0x2f, 0xcd, 0x9a, 0xa2, 0x2a, 0x54, 0xf5, 0xdb, 0x0e, 0x2c, 0x77, 0xf6, 0x5d,
+ /*7c50:*/ 0xa3, 0x1f, 0xf5, 0xa3, 0x9a, 0xa7, 0x74, 0xce, 0x58, 0xb0, 0xbd, 0x88, 0x8e, 0x4f, 0x97, 0xff,
+ /*7c60:*/ 0x78, 0x0c, 0x9c, 0x7d, 0x5c, 0x65, 0x6c, 0x24, 0x7c, 0xe3, 0x7f, 0xee, 0x2f, 0x50, 0xf3, 0x1f,
+ /*7c70:*/ 0x7d, 0x6b, 0xd4, 0xc3, 0xe3, 0x3a, 0x88, 0x81, 0x8d, 0x61, 0x7f, 0xdc, 0xa9, 0x4b, 0xac, 0x0e,
+ /*7c80:*/ 0x76, 0x1e, 0x4e, 0xd8, 0xf7, 0x5b, 0x2c, 0x03, 0x37, 0xa6, 0x93, 0x78, 0xb0, 0xad, 0x96, 0xff,
+ /*7c90:*/ 0xf1, 0xaf, 0x9a, 0x1c, 0xa4, 0x9d, 0x04, 0x5a, 0xbd, 0x85, 0x1b, 0xd9, 0xad, 0x92, 0x1a, 0x28,
+ /*7ca0:*/ 0xe7, 0x7e, 0x08, 0x25, 0x67, 0xb8, 0x0c, 0x83, 0x2f, 0x3d, 0x92, 0xd7, 0xfe, 0xcf, 0x18, 0xee,
+ /*7cb0:*/ 0xd8, 0xd3, 0x2d, 0xec, 0x6f, 0x56, 0x3c, 0x6a, 0x69, 0x4b, 0x31, 0x8b, 0x7e, 0x9d, 0x18, 0x26,
+ /*7cc0:*/ 0xdc, 0xdd, 0x89, 0xc2, 0x1d, 0x32, 0x49, 0x27, 0xf7, 0x78, 0x46, 0x8e, 0xbf, 0x47, 0x37, 0x9d,
+ /*7cd0:*/ 0x45, 0xad, 0x46, 0x63, 0x9e, 0x70, 0xd7, 0xd9, 0xdd, 0x0f, 0x2f, 0xe1, 0x11, 0xe9, 0x93, 0xa2,
+ /*7ce0:*/ 0x99, 0x6e, 0xc4, 0x98, 0x6a, 0xf3, 0x31, 0x33, 0xe9, 0x54, 0x84, 0x6e, 0xc7, 0xe5, 0x7b, 0x79,
+ /*7cf0:*/ 0x4f, 0x06, 0x69, 0x36, 0x64, 0x23, 0x7e, 0xc5, 0xdc, 0x95, 0x1c, 0x34, 0x86, 0x93, 0x9e, 0xa9,
+ /*7d00:*/ 0x5f, 0xab, 0x6c, 0xff, 0xee, 0x8e, 0x80, 0x0b, 0x66, 0x76, 0xc0, 0x12, 0x75, 0x6d, 0x96, 0xb1,
+ /*7d10:*/ 0xaf, 0xb2, 0xe9, 0x96, 0x34, 0xcc, 0x99, 0x89, 0x59, 0xbc, 0xe0, 0xd5, 0xde, 0x1e, 0x7b, 0x3b,
+ /*7d20:*/ 0x88, 0xd3, 0xe4, 0x27, 0x06, 0x93, 0x4c, 0xf4, 0x8b, 0xdb, 0xef, 0xd3, 0x23, 0x85, 0x30, 0x37,
+ /*7d30:*/ 0x47, 0x54, 0x7e, 0x7d, 0xe7, 0x21, 0xeb, 0xc5, 0x55, 0x93, 0x1f, 0xd4, 0xf1, 0x8c, 0x7d, 0xd4,
+ /*7d40:*/ 0x3b, 0xfe, 0x83, 0x4a, 0xc8, 0x9a, 0xd4, 0x2a, 0x69, 0x52, 0x73, 0x81, 0x77, 0x8f, 0x7c, 0x98,
+ /*7d50:*/ 0xa0, 0x01, 0x7e, 0x7e, 0x34, 0x91, 0xb1, 0xea, 0x5b, 0x05, 0xa4, 0x0d, 0x41, 0x8c, 0x38, 0x0c,
+ /*7d60:*/ 0xfe, 0x32, 0x81, 0xee, 0x1a, 0x54, 0xcf, 0x01, 0x8e, 0xb3, 0x6e, 0xa0, 0x41, 0xa1, 0xa5, 0xa3,
+ /*7d70:*/ 0xc0, 0x18, 0x5e, 0x06, 0x32, 0x04, 0x85, 0x72, 0x60, 0x07, 0xb5, 0x30, 0xce, 0xfc, 0x21, 0xb4,
+ /*7d80:*/ 0xaa, 0xaa, 0xd9, 0xaf, 0xb1, 0x7e, 0xbd, 0x03, 0x32, 0x56, 0x55, 0x5c, 0xdb, 0xe3, 0x05, 0x06,
+ /*7d90:*/ 0x6b, 0x39, 0x67, 0x81, 0xcd, 0xd0, 0xc8, 0x5d, 0xb8, 0xae, 0xb6, 0x13, 0x3b, 0x6e, 0x4c, 0x4b,
+ /*7da0:*/ 0x8f, 0x12, 0x5f, 0x21, 0x61, 0x6c, 0xfc, 0x3f, 0x96, 0x1b, 0x82, 0x57, 0xf9, 0xbe, 0x5a, 0x91,
+ /*7db0:*/ 0x19, 0xac, 0xdd, 0x54, 0x2a, 0xd6, 0x8b, 0xa6, 0x0b, 0xb8, 0x7e, 0xeb, 0xaa, 0x86, 0x3a, 0x44,
+ /*7dc0:*/ 0x96, 0x7a, 0xec, 0x6a, 0x3e, 0xa0, 0x94, 0x3e, 0xb3, 0xe0, 0xc1, 0xf9, 0xd4, 0xff, 0xa4, 0x10,
+ /*7dd0:*/ 0x79, 0x8e, 0x83, 0x65, 0x2e, 0xd9, 0x90, 0xec, 0x00, 0xca, 0x2a, 0x86, 0xb8, 0x85, 0xf1, 0xa1,
+ /*7de0:*/ 0xdc, 0xfe, 0x54, 0x11, 0x67, 0xcf, 0x6d, 0x42, 0x6c, 0x2d, 0xf7, 0x8e, 0x9c, 0x5e, 0x0f, 0x62,
+ /*7df0:*/ 0x49, 0xf8, 0xb2, 0x4c, 0xc8, 0x7a, 0x47, 0x40, 0x59, 0xba, 0xa3, 0x8b, 0xad, 0x61, 0x8e, 0xd6,
+ /*7e00:*/ 0xbf, 0xd1, 0xf4, 0x3e, 0xb9, 0x80, 0x47, 0xd5, 0x94, 0xa9, 0xb9, 0xc1, 0x4d, 0xf4, 0x35, 0xa6,
+ /*7e10:*/ 0xa4, 0x13, 0x90, 0xcb, 0x7f, 0x9d, 0x08, 0xb7, 0x5a, 0x5e, 0x1f, 0x5a, 0x5c, 0x19, 0xc2, 0xce,
+ /*7e20:*/ 0xa2, 0xe4, 0xc1, 0x2c, 0xdb, 0xb9, 0x84, 0xb4, 0x7a, 0xa4, 0x0c, 0xaf, 0xf0, 0xdc, 0x7e, 0xe4,
+ /*7e30:*/ 0x27, 0x94, 0x69, 0x07, 0x6d, 0xc2, 0xaa, 0xc4, 0x95, 0x80, 0xb5, 0x94, 0xf8, 0x57, 0x0e, 0x97,
+ /*7e40:*/ 0x4d, 0x9a, 0x3e, 0x5c, 0x63, 0x44, 0x1b, 0x61, 0x22, 0xd8, 0x47, 0x4c, 0x35, 0x39, 0xa0, 0xfd,
+ /*7e50:*/ 0x52, 0x3c, 0x3f, 0x2f, 0x2d, 0x15, 0x19, 0x7b, 0xd9, 0x17, 0xa7, 0x90, 0x0f, 0xbe, 0x21, 0xf6,
+ /*7e60:*/ 0x7b, 0x58, 0x8f, 0x48, 0x77, 0x0e, 0xac, 0x66, 0xa3, 0x2f, 0x80, 0xee, 0xe6, 0x23, 0x72, 0x03,
+ /*7e70:*/ 0x8e, 0x56, 0x54, 0x13, 0x1e, 0x06, 0xbc, 0x5d, 0xdf, 0x78, 0xf5, 0x1f, 0x1e, 0x2f, 0xd6, 0x68,
+ /*7e80:*/ 0x50, 0x1d, 0xaf, 0x61, 0x5d, 0x4b, 0x38, 0x31, 0x2c, 0xef, 0x54, 0x3c, 0x5f, 0xfc, 0xb5, 0x5e,
+ /*7e90:*/ 0xd9, 0x96, 0x08, 0x31, 0x25, 0x20, 0x42, 0xfb, 0x19, 0xba, 0xc8, 0xf2, 0x0f, 0xe3, 0xfd, 0x5b,
+ /*7ea0:*/ 0xae, 0x65, 0xba, 0x26, 0xfa, 0x7a, 0xfd, 0x79, 0xfd, 0xda, 0x2b, 0xab, 0xb2, 0x0b, 0x40, 0x55,
+ /*7eb0:*/ 0x87, 0x81, 0x6d, 0xc1, 0x02, 0xa4, 0xbc, 0x94, 0x89, 0x81, 0x42, 0xe7, 0x40, 0xf0, 0xd0, 0xfe,
+ /*7ec0:*/ 0x54, 0x56, 0xf8, 0xfa, 0x0c, 0x53, 0xce, 0xac, 0x04, 0xe3, 0xfb, 0xc6, 0x2f, 0x87, 0x6b, 0xde,
+ /*7ed0:*/ 0x74, 0x0f, 0x7a, 0x5b, 0xb8, 0xf2, 0x0a, 0x66, 0xf0, 0xb2, 0x1e, 0xd8, 0x2f, 0x37, 0xe0, 0xc1,
+ /*7ee0:*/ 0x45, 0x62, 0x6b, 0x0b, 0xab, 0xe8, 0x1f, 0x31, 0x7a, 0x28, 0xca, 0x54, 0x6f, 0x36, 0x10, 0xd6,
+ /*7ef0:*/ 0x43, 0xc1, 0xe1, 0x0a, 0x2e, 0xb6, 0xce, 0xaf, 0x45, 0xdc, 0x18, 0x9e, 0xcf, 0x5a, 0xdd, 0xea,
+ /*7f00:*/ 0x2e, 0xd7, 0xe5, 0x55, 0x49, 0x3e, 0x08, 0x15, 0xf7, 0xe3, 0xf7, 0x78, 0x8e, 0x41, 0xd1, 0xf8,
+ /*7f10:*/ 0xf4, 0x7a, 0x59, 0x93, 0xc8, 0xdf, 0xdb, 0xe1, 0x88, 0x66, 0x21, 0x84, 0xb7, 0x4d, 0xd6, 0x4a,
+ /*7f20:*/ 0x61, 0x2c, 0x5b, 0x8b, 0xf4, 0xc3, 0x64, 0xcc, 0x73, 0x69, 0xca, 0x0b, 0x55, 0x38, 0xbd, 0x2a,
+ /*7f30:*/ 0x6d, 0x1f, 0xad, 0xe4, 0xfe, 0x3a, 0xbf, 0x4a, 0xff, 0x18, 0x5f, 0x9c, 0x5d, 0xa7, 0x2f, 0xbc,
+ /*7f40:*/ 0x71, 0x8a, 0xe0, 0x82, 0x4a, 0xd8, 0x92, 0xdb, 0xb6, 0x80, 0x29, 0xa4, 0xed, 0x65, 0x3f, 0x72,
+ /*7f50:*/ 0xc4, 0xbc, 0x05, 0x4f, 0x3a, 0x97, 0x5d, 0x3c, 0x24, 0x50, 0xa4, 0x5b, 0x4e, 0x75, 0xab, 0x20,
+ /*7f60:*/ 0x96, 0x42, 0xa3, 0x5b, 0x36, 0x74, 0x79, 0xb0, 0xd2, 0xce, 0x49, 0x23, 0xa2, 0x22, 0xd7, 0x21,
+ /*7f70:*/ 0x66, 0xbe, 0xc4, 0xa9, 0x0c, 0x9d, 0xb3, 0xfc, 0x18, 0x81, 0x48, 0x7e, 0x1b, 0xfa, 0xdf, 0xb8,
+ /*7f80:*/ 0xba, 0xae, 0x15, 0x16, 0xdf, 0xee, 0x6c, 0x53, 0xf9, 0x6a, 0x80, 0xbb, 0xe0, 0x5e, 0x98, 0x2d,
+ /*7f90:*/ 0x18, 0xf1, 0x45, 0x99, 0x2d, 0xb8, 0xc6, 0xff, 0x74, 0xf4, 0xaa, 0x0b, 0x94, 0x42, 0x09, 0xb8,
+ /*7fa0:*/ 0x26, 0x5f, 0x7c, 0x15, 0x17, 0xe0, 0x90, 0x04, 0x96, 0x1e, 0x8d, 0xa9, 0xc3, 0x59, 0xcb, 0x5a,
+ /*7fb0:*/ 0xc2, 0x22, 0x78, 0x9c, 0xbe, 0xb1, 0xc8, 0x5b, 0x84, 0xda, 0x24, 0x3f, 0x3b, 0xc9, 0x9b, 0x7a,
+ /*7fc0:*/ 0xbb, 0xfd, 0xe7, 0x4b, 0x23, 0x43, 0xd1, 0x04, 0x98, 0x14, 0x5e, 0x23, 0xdb, 0xb9, 0x18, 0x3c,
+ /*7fd0:*/ 0x4f, 0xdb, 0xe1, 0x14, 0x1e, 0x30, 0x19, 0xd6, 0xb6, 0x70, 0xd4, 0xe1, 0xe1, 0x40, 0xad, 0xff,
+ /*7fe0:*/ 0xe9, 0xcc, 0xd5, 0xfa, 0xc1, 0x2b, 0x66, 0x07, 0xde, 0x05, 0x6d, 0xe7, 0x97, 0x75, 0xb9, 0x3f,
+ /*7ff0:*/ 0x5f, 0xd2, 0xdf, 0xd2, 0xd1, 0x27, 0xfe, 0x29, 0xb7, 0xc5, 0xfa, 0x41, 0xfd, 0x39, 0x39, 0x45,
+ /*8000:*/ 0xc6, 0x96, 0xa2, 0xd5, 0x25, 0xab, 0x00, 0xe4, 0x4c, 0xc8, 0x48, 0xe5, 0x89, 0xa5, 0x0b, 0x13,
+ /*8010:*/ 0x82, 0xb5, 0x53, 0xd6, 0x4c, 0x47, 0x7d, 0x28, 0x39, 0xe5, 0xad, 0x94, 0xc4, 0x6d, 0x21, 0x1e,
+ /*8020:*/ 0xb0, 0x73, 0xd9, 0xcc, 0xa6, 0x2f, 0x0b, 0xf0, 0x9c, 0xd7, 0x5c, 0x5f, 0x99, 0xf6, 0x09, 0x6e,
+ /*8030:*/ 0x64, 0xb1, 0xce, 0xcc, 0xee, 0x55, 0xd9, 0xeb, 0x51, 0x5f, 0x03, 0x03, 0x6f, 0xc2, 0xea, 0x70,
+ /*8040:*/ 0xc3, 0x4c, 0xd1, 0x9e, 0x26, 0x06, 0x0f, 0x80, 0x2d, 0xf0, 0x43, 0x75, 0x09, 0x8c, 0x52, 0x6a,
+ /*8050:*/ 0xbb, 0x76, 0xda, 0x09, 0x2f, 0x00, 0x45, 0xad, 0x9a, 0x24, 0x12, 0x4c, 0x29, 0x58, 0x67, 0x4f,
+ /*8060:*/ 0xd8, 0xdd, 0xe9, 0x62, 0xd4, 0x95, 0x0d, 0x83, 0x62, 0xfe, 0x66, 0xad, 0x12, 0x06, 0xe1, 0x16,
+ /*8070:*/ 0xb8, 0x89, 0xb4, 0x9f, 0xa6, 0xb6, 0x4f, 0xa7, 0xfe, 0x72, 0xd5, 0xbc, 0x7c, 0x84, 0x62, 0xe2,
+ /*8080:*/ 0xb1, 0xfb, 0x0c, 0x54, 0xed, 0x69, 0x96, 0x68, 0x5c, 0x1b, 0xcf, 0xa3, 0x56, 0xdd, 0x0b, 0x78,
+ /*8090:*/ 0x9c, 0x5d, 0x7d, 0x9d, 0x05, 0x79, 0x72, 0xb9, 0xa9, 0x6e, 0xd1, 0xfb, 0x0c, 0x28, 0x2b, 0xa9,
+ /*80a0:*/ 0xf4, 0xb3, 0x41, 0xb1, 0x12, 0xe0, 0xe3, 0xf4, 0xf0, 0x6c, 0x86, 0x50, 0xf0, 0xaf, 0x23, 0x87,
+ /*80b0:*/ 0x67, 0x91, 0xe2, 0x07, 0x6c, 0x77, 0x16, 0xf9, 0x5f, 0x83, 0x8a, 0x46, 0xb6, 0xe3, 0x02, 0x59,
+ /*80c0:*/ 0x77, 0xaf, 0x3e, 0x98, 0x33, 0x3f, 0xb6, 0xf4, 0x02, 0x23, 0x50, 0xd8, 0x4b, 0xc9, 0x4e, 0xd9,
+ /*80d0:*/ 0x00, 0xe9, 0x68, 0x13, 0x44, 0xed, 0x2c, 0x4d, 0xd7, 0x60, 0xb4, 0x69, 0xc6, 0xd4, 0xe7, 0xc6,
+ /*80e0:*/ 0x57, 0xe4, 0xb0, 0x5d, 0x74, 0x51, 0xb5, 0x09, 0x54, 0x11, 0x58, 0x1b, 0xab, 0xf6, 0x54, 0xfb,
+ /*80f0:*/ 0xe4, 0xaa, 0x99, 0xb0, 0xc2, 0xa8, 0xc3, 0x2d, 0x52, 0x95, 0x39, 0x51, 0x4b, 0x18, 0x83, 0xe6,
+ /*8100:*/ 0xfc, 0x55, 0xd5, 0x0a, 0xae, 0x93, 0x70, 0x97, 0x60, 0x65, 0x63, 0x61, 0x72, 0x65, 0x9a, 0xe8,
+ /*8110:*/ 0x13, 0x86, 0x99, 0x14, 0x75, 0xca, 0xe2, 0x9b, 0x40, 0xaf, 0x63, 0x49, 0x50, 0xfc, 0x1d, 0x9b,
+ /*8120:*/ 0x2a, 0x26, 0xee, 0xbc, 0x88, 0x78, 0x1d, 0xd8, 0xd6, 0x51, 0x8b, 0x8f, 0x45, 0xf9, 0xe0, 0x4b,
+ /*8130:*/ 0x70, 0xb4, 0x6b, 0x84, 0x42, 0xe5, 0x7b, 0x26, 0xf0, 0xb4, 0xff, 0x15, 0x70, 0x23, 0xc7, 0xd6,
+ /*8140:*/ 0xd7, 0xa0, 0x22, 0x84, 0x8f, 0x3d, 0xd6, 0x25, 0x26, 0x22, 0x3e, 0xcf, 0x81, 0x67, 0x1e, 0xdc,
+ /*8150:*/ 0x23, 0xc7, 0x2a, 0xe7, 0x2e, 0x68, 0x65, 0x06, 0x2f, 0xe0, 0x57, 0xe0, 0x89, 0x27, 0x5f, 0xc6,
+ /*8160:*/ 0x81, 0x85, 0x04, 0xb0, 0xa3, 0xc9, 0xde, 0xe3, 0x4f, 0x68, 0x4d, 0xc7, 0xa2, 0xc9, 0xc2, 0x6c,
+ /*8170:*/ 0x42, 0x37, 0x7d, 0x94, 0xe4, 0x61, 0x26, 0x39, 0x26, 0xc7, 0x30, 0xd9, 0xfc, 0x5a, 0x82, 0x44,
+ /*8180:*/ 0xee, 0x2c, 0x82, 0x2f, 0xa3, 0x66, 0xfc, 0x7a, 0x6b, 0xde, 0x3a, 0xf8, 0xad, 0xc4, 0xcc, 0xdf,
+ /*8190:*/ 0x4f, 0x38, 0xf0, 0x1e, 0xd8, 0x0d, 0x7d, 0x98, 0x6b, 0x74, 0xa5, 0xd7, 0x10, 0xce, 0xa0, 0x53,
+ /*81a0:*/ 0x72, 0x51, 0xf1, 0x5a, 0xa0, 0x01, 0x2c, 0x33, 0xe5, 0xfe, 0x25, 0xeb, 0x6c, 0xe3, 0x79, 0x02,
+ /*81b0:*/ 0x87, 0x5a, 0x56, 0xe9, 0xb6, 0xd0, 0xd1, 0x41, 0xe4, 0x2f, 0x53, 0xed, 0xbd, 0x22, 0x14, 0xe0,
+ /*81c0:*/ 0x2d, 0x48, 0x8c, 0xb9, 0x67, 0xd8, 0x7b, 0x27, 0x58, 0x7a, 0x7c, 0xc8, 0xd6, 0x48, 0xec, 0xd9,
+ /*81d0:*/ 0xba, 0xcf, 0xd1, 0xc4, 0xbd, 0x7f, 0x38, 0xb7, 0xdf, 0x4a, 0xff, 0x99, 0xd8, 0xf4, 0xaa, 0xbf,
+ /*81e0:*/ 0x68, 0x9a, 0xcb, 0x63, 0xcd, 0x01, 0x05, 0x53, 0xfd, 0xae, 0xcd, 0xd7, 0xfe, 0xa7, 0x79, 0x42,
+ /*81f0:*/ 0x85, 0x63, 0x40, 0x44, 0x65, 0x1b, 0x83, 0x70, 0x16, 0x1f, 0xc0, 0xf1, 0xb2, 0x49, 0x0f, 0x99,
+ /*8200:*/ 0x40, 0xbe, 0x21, 0xfa, 0x8e, 0x85, 0xb7, 0x9d, 0xee, 0x28, 0xbc, 0xac, 0x2b, 0x85, 0x3b, 0xdf,
+ /*8210:*/ 0x4a, 0x72, 0x81, 0x6d, 0x0e, 0x75, 0x58, 0x34, 0x41, 0x5b, 0xa3, 0x0f, 0x00, 0x1b, 0x28, 0xcf,
+ /*8220:*/ 0xa7, 0x57, 0x4e, 0x78, 0x41, 0x7c, 0xf9, 0x4e, 0x44, 0xcb, 0x6f, 0x4b, 0x88, 0x84, 0x73, 0x4f,
+ /*8230:*/ 0xfa, 0x4a, 0xc4, 0xa9, 0xad, 0xd7, 0xeb, 0x1d, 0x52, 0xe4, 0xd7, 0xa3, 0xdc, 0x37, 0xae, 0x23,
+ /*8240:*/ 0xe3, 0xa6, 0x91, 0x02, 0x75, 0xf0, 0x16, 0xbb, 0x24, 0x09, 0x15, 0xa3, 0x79, 0xe2, 0xd9, 0x66,
+ /*8250:*/ 0x25, 0x27, 0xe8, 0x5e, 0x72, 0x7d, 0xc6, 0x38, 0xac, 0xfb, 0x62, 0x3b, 0x7d, 0x23, 0xe6, 0xbf,
+ /*8260:*/ 0x94, 0x12, 0x15, 0xcb, 0xd7, 0x73, 0xd7, 0xc9, 0x02, 0xff, 0xa5, 0xae, 0x15, 0x45, 0xc7, 0xfd,
+ /*8270:*/ 0x82, 0x77, 0x54, 0xd3, 0xc0, 0xcb, 0xc6, 0x1c, 0x8d, 0x58, 0x51, 0xd2, 0x82, 0x66, 0x03, 0x84,
+ /*8280:*/ 0x5a, 0x16, 0xad, 0x90, 0x0b, 0x29, 0x98, 0x6c, 0xa1, 0x53, 0xc3, 0x8e, 0x9e, 0x30, 0x61, 0x6f,
+ /*8290:*/ 0xc0, 0xc1, 0x8e, 0x61, 0x67, 0x82, 0x32, 0xb8, 0xa7, 0x4c, 0xa6, 0x78, 0x28, 0x72, 0xed, 0xc9,
+ /*82a0:*/ 0x17, 0x6d, 0xf4, 0xe1, 0x83, 0x9c, 0xa3, 0xc8, 0x57, 0x47, 0xf6, 0x0f, 0xa5, 0x43, 0x36, 0x78,
+ /*82b0:*/ 0x53, 0xd2, 0xf7, 0x75, 0xc2, 0x93, 0xb5, 0x4b, 0x5a, 0xbf, 0xa0, 0xfe, 0x09, 0xb3, 0xa4, 0x69,
+ /*82c0:*/ 0x3e, 0xee, 0x5e, 0xb1, 0xe6, 0x2b, 0xca, 0x21, 0x62, 0xed, 0xf5, 0x3a, 0xa6, 0x3c, 0x41, 0x44,
+ /*82d0:*/ 0x75, 0x03, 0xc8, 0x1e, 0x7f, 0x82, 0x5c, 0x9f, 0x77, 0x72, 0x73, 0xcf, 0xf4, 0x9e, 0x20, 0x63,
+ /*82e0:*/ 0x60, 0xe1, 0x4b, 0x42, 0xb4, 0xa1, 0xdf, 0xda, 0xdc, 0x2e, 0xda, 0x4f, 0xba, 0xf2, 0x2a, 0x44,
+ /*82f0:*/ 0x7a, 0x82, 0x40, 0xb9, 0x5d, 0xa2, 0x61, 0x1e, 0xea, 0xff, 0x9a, 0xd7, 0x85, 0x8b, 0x2a, 0x88,
+ /*8300:*/ 0x6a, 0xbc, 0xdb, 0x16, 0x1b, 0x43, 0x02, 0xbd, 0x36, 0xa1, 0x9e, 0x86, 0x45, 0x15, 0x4b, 0x07,
+ /*8310:*/ 0x05, 0xe0, 0x64, 0x85, 0xda, 0xc3, 0x61, 0xdd, 0xc6, 0xf7, 0xf1, 0x6b, 0xe0, 0xf0, 0x0b, 0xcd,
+ /*8320:*/ 0x6d, 0x6e, 0x33, 0x05, 0xdf, 0x4e, 0x18, 0x79, 0xfc, 0x85, 0x30, 0xf1, 0x04, 0xa8, 0x7a, 0x9a,
+ /*8330:*/ 0xbe, 0x72, 0x8f, 0x92, 0x30, 0xd8, 0x04, 0x19, 0xbc, 0x26, 0xc5, 0xe6, 0x71, 0xd3, 0x4d, 0xfc,
+ /*8340:*/ 0xe8, 0x44, 0xca, 0x60, 0xb6, 0x0a, 0x2f, 0x8a, 0x36, 0x83, 0x54, 0x6f, 0x68, 0xcd, 0xa6, 0x60,
+ /*8350:*/ 0x64, 0xdc, 0xcd, 0xde, 0xeb, 0x92, 0x47, 0x61, 0xce, 0xc7, 0xa9, 0x99, 0xd9, 0xad, 0x4e, 0x4d,
+ /*8360:*/ 0x11, 0xb5, 0x10, 0x46, 0x31, 0x91, 0x66, 0x42, 0xad, 0xe1, 0xb9, 0x79, 0x93, 0x62, 0xde, 0x40,
+ /*8370:*/ 0xd5, 0x1b, 0x74, 0x70, 0x73, 0xb1, 0xa7, 0xa3, 0x85, 0xcd, 0x55, 0x62, 0x8b, 0x2c, 0xf9, 0xcf,
+ /*8380:*/ 0xa5, 0x7f, 0x02, 0x3f, 0x58, 0x04, 0x7c, 0x02, 0x6f, 0x4d, 0xd4, 0x67, 0x95, 0x94, 0xf5, 0x42,
+ /*8390:*/ 0x57, 0xf9, 0xa1, 0x65, 0xc6, 0x2e, 0xb6, 0x7d, 0x1b, 0x93, 0x5b, 0xa3, 0x2d, 0x32, 0x77, 0x6b,
+ /*83a0:*/ 0xb0, 0xcd, 0xd6, 0x9b, 0xd6, 0x11, 0x7b, 0x5b, 0xc5, 0x10, 0x86, 0xc9, 0x74, 0x35, 0xfa, 0x67,
+ /*83b0:*/ 0xbc, 0xea, 0x5d, 0x46, 0x5c, 0xf6, 0x4f, 0xb7, 0x86, 0x58, 0xda, 0x5c, 0x38, 0xf5, 0x68, 0xb8,
+ /*83c0:*/ 0xcf, 0xbb, 0x7e, 0x76, 0x0d, 0xdd, 0x1b, 0x28, 0xcd, 0x4f, 0xb3, 0x99, 0x8c, 0x11, 0xef, 0x6e,
+ /*83d0:*/ 0x1b, 0xf0, 0x81, 0xb4, 0x6b, 0xb9, 0x34, 0xa4, 0x93, 0x5d, 0xf1, 0xca, 0xef, 0x45, 0x60, 0xc2,
+ /*83e0:*/ 0x35, 0xdf, 0x01, 0xcf, 0x2b, 0x3a, 0xb6, 0x1f, 0xd1, 0x8d, 0x3d, 0xe7, 0x12, 0x60, 0xed, 0xc4,
+ /*83f0:*/ 0x0b, 0x36, 0x84, 0xe3, 0x6b, 0x75, 0x09, 0x2a, 0x95, 0xad, 0xa5, 0x37, 0x4f, 0x75, 0xc5, 0x13,
+ /*8400:*/ 0x61, 0x74, 0x17, 0x83, 0x86, 0x94, 0x94, 0xfe, 0x0e, 0x7d, 0xc1, 0x54, 0x6b, 0x13, 0x3b, 0xd9,
+ /*8410:*/ 0x7c, 0xf7, 0x90, 0x56, 0x7d, 0x30, 0x42, 0xd0, 0x82, 0x42, 0xc3, 0x3a, 0x52, 0xdf, 0x70, 0x24,
+ /*8420:*/ 0xb3, 0xcb, 0x25, 0x15, 0x2d, 0x4e, 0xa9, 0xd4, 0x56, 0x33, 0xb9, 0x79, 0xca, 0xbd, 0xcc, 0x56,
+ /*8430:*/ 0x9f, 0x13, 0xc0, 0x44, 0xe4, 0x71, 0xdf, 0x2d, 0xf2, 0x55, 0x49, 0xae, 0x0f, 0x10, 0x4d, 0x03,
+ /*8440:*/ 0x08, 0x59, 0x6d, 0xf9, 0xb1, 0xd8, 0x14, 0x88, 0xdd, 0x0e, 0x0f, 0xa9, 0xbc, 0x5d, 0x74, 0xff,
+ /*8450:*/ 0x9b, 0xf8, 0x8c, 0xbb, 0xdf, 0xb4, 0x60, 0x64, 0x2f, 0x7b, 0x5e, 0x83, 0x52, 0xf5, 0x7a, 0xf7,
+ /*8460:*/ 0x33, 0x50, 0x08, 0x07, 0xb0, 0x2e, 0x7e, 0x88, 0xa8, 0x4b, 0xd2, 0xe5, 0xbc, 0x9c, 0xf2, 0x1b,
+ /*8470:*/ 0x64, 0xe9, 0x1c, 0x65, 0xb4, 0xec, 0x97, 0x0d, 0xd3, 0xa0, 0x8e, 0x02, 0xe9, 0x2b, 0xb1, 0x05,
+ /*8480:*/ 0x74, 0xe9, 0x8c, 0x18, 0x27, 0xcd, 0x6c, 0x59, 0x5d, 0xfd, 0xf3, 0x56, 0x5e, 0x56, 0xd7, 0xf0,
+ /*8490:*/ 0xa4, 0x0a, 0xc0, 0x16, 0x81, 0x07, 0x41, 0xc7, 0xf0, 0xe1, 0x08, 0x1a, 0xf8, 0xa8, 0x0f, 0xa7,
+ /*84a0:*/ 0x23, 0x95, 0xaa, 0x49, 0x3c, 0x5e, 0xb2, 0x7f, 0x69, 0xf3, 0x3d, 0xdd, 0xb4, 0x56, 0x96, 0xdb,
+ /*84b0:*/ 0xea, 0xf2, 0x34, 0xa8, 0xd0, 0xb7, 0x72, 0x98, 0x47, 0x15, 0x93, 0xf6, 0x57, 0x9c, 0xb1, 0x26,
+ /*84c0:*/ 0xf1, 0x00, 0xdf, 0xe8, 0xfb, 0x81, 0x15, 0x0f, 0x8d, 0x33, 0x9e, 0x79, 0x0e, 0x41, 0xf4, 0x16,
+ /*84d0:*/ 0x31, 0xdd, 0xfd, 0xec, 0x7d, 0x4b, 0x7e, 0x3b, 0xd7, 0x71, 0xf1, 0x1c, 0xb2, 0x53, 0x2b, 0x6f,
+ /*84e0:*/ 0xc5, 0x58, 0xf1, 0x50, 0xfe, 0xc3, 0x29, 0x82, 0xd2, 0xf4, 0x7c, 0xd7, 0x42, 0x8a, 0x7a, 0x83,
+ /*84f0:*/ 0x79, 0x42, 0x62, 0xde, 0x92, 0x64, 0x58, 0x6e, 0x9b, 0x24, 0x8d, 0x16, 0xb8, 0xf9, 0x83, 0xf9,
+ /*8500:*/ 0x8a, 0x35, 0x67, 0xf7, 0x07, 0xd5, 0x43, 0xd0, 0xc6, 0x71, 0x35, 0xfb, 0xb5, 0x9f, 0x0d, 0x84,
+ /*8510:*/ 0x9e, 0xa9, 0x69, 0x3b, 0x4e, 0x3c, 0xa3, 0x72, 0xd7, 0x48, 0xaf, 0xae, 0xba, 0xae, 0x4a, 0xf7,
+ /*8520:*/ 0x06, 0xce, 0xf6, 0xc8, 0x41, 0x0a, 0x7e, 0xfb, 0x76, 0xc6, 0xb0, 0xcc, 0xa9, 0xd9, 0xd3, 0xb6,
+ /*8530:*/ 0xfe, 0xc5, 0x62, 0x99, 0x28, 0x03, 0xdb, 0xa8, 0x10, 0xe9, 0xd2, 0x3b, 0x1b, 0xe2, 0xf5, 0x1b,
+ /*8540:*/ 0x81, 0xea, 0xfd, 0xd2, 0x9f, 0x34, 0xc8, 0xca, 0x58, 0x6d, 0x74, 0xbf, 0x2b, 0x53, 0x17, 0xf2,
+ /*8550:*/ 0x64, 0x15, 0xc0, 0x31, 0x77, 0x7a, 0x00, 0xcd, 0x28, 0x72, 0x56, 0x82, 0x81, 0xb8, 0xd8, 0x56,
+ /*8560:*/ 0x0f, 0xe1, 0xa3, 0xc2, 0xf8, 0x78, 0x01, 0x9f, 0x76, 0xd8, 0x77, 0xf6, 0x06, 0x78, 0x4c, 0xf4,
+ /*8570:*/ 0xf8, 0xab, 0x09, 0x9f, 0x81, 0x7c, 0xdf, 0x6c, 0x79, 0x0f, 0xb8, 0xed, 0xec, 0x92, 0x68, 0xb1,
+ /*8580:*/ 0x0d, 0xed, 0x5c, 0x62, 0xe1, 0x94, 0x91, 0xfd, 0x39, 0xbe, 0x65, 0x59, 0x45, 0xfb, 0x59, 0xe1,
+ /*8590:*/ 0xbd, 0xad, 0xbc, 0x41, 0xa0, 0x94, 0x49, 0xec, 0x29, 0x06, 0xe9, 0xd8, 0x64, 0x04, 0xe1, 0x70,
+ /*85a0:*/ 0x31, 0xb9, 0xe4, 0xdf, 0x23, 0xf9, 0x7d, 0x0f, 0x5d, 0x9a, 0xa6, 0x67, 0x4c, 0xde, 0xdd, 0xb6,
+ /*85b0:*/ 0xb2, 0xc5, 0x33, 0x87, 0xee, 0xb8, 0x36, 0xaa, 0x32, 0xdb, 0xc4, 0x90, 0x9b, 0xe0, 0xc2, 0x6c,
+ /*85c0:*/ 0xcd, 0xae, 0xff, 0x7e, 0x9a, 0x35, 0xa7, 0x4e, 0x48, 0xe2, 0x62, 0x1b, 0x0e, 0x7d, 0x9b, 0x44,
+ /*85d0:*/ 0x43, 0xbd, 0x55, 0x82, 0x88, 0x1a, 0x9c, 0x83, 0xfc, 0x1e, 0x3d, 0x8b, 0x6b, 0x29, 0x23, 0xf8,
+ /*85e0:*/ 0x1e, 0xba, 0xb4, 0x5b, 0xc5, 0x80, 0x12, 0x70, 0x48, 0x9b, 0x41, 0xfb, 0xe6, 0xc8, 0xf3, 0x19,
+ /*85f0:*/ 0x15, 0x7b, 0xc0, 0x8d, 0xb0, 0x49, 0x67, 0xcc, 0xf4, 0xe0, 0x12, 0x41, 0xf9, 0xfb, 0xd4, 0x1a,
+ /*8600:*/ 0xe8, 0x72, 0x1b, 0xfc, 0x02, 0xbe, 0x6d, 0x34, 0x96, 0xaf, 0xba, 0x96, 0x44, 0x7d, 0xce, 0x3f,
+ /*8610:*/ 0x0e, 0x58, 0x7b, 0xb1, 0x0d, 0xb7, 0x00, 0x43, 0x6d, 0x81, 0xaa, 0xa6, 0xe4, 0x5c, 0xf1, 0xa4,
+ /*8620:*/ 0x1f, 0xe4, 0xa8, 0x30, 0x2b, 0x0c, 0xbf, 0xdd, 0x69, 0xfa, 0xe7, 0xf7, 0x44, 0xff, 0x50, 0x2b,
+ /*8630:*/ 0x39, 0x73, 0xbd, 0x03, 0x22, 0x84, 0xef, 0x14, 0x08, 0x74, 0xa8, 0x85, 0x05, 0x64, 0xd4, 0xc7,
+ /*8640:*/ 0x30, 0xa4, 0x84, 0x2e, 0xbd, 0x8d, 0x0c, 0xee, 0xfc, 0x11, 0x0f, 0x0c, 0x3f, 0xb1, 0x48, 0x6e,
+ /*8650:*/ 0xb6, 0x09, 0x01, 0xc8, 0x54, 0x6a, 0xe7, 0x1b, 0x46, 0x90, 0x5b, 0x79, 0x64, 0x08, 0xa8, 0xda,
+ /*8660:*/ 0xb0, 0x7e, 0x1f, 0xc3, 0x8c, 0xee, 0x9e, 0x9f, 0x8b, 0x9b, 0xc2, 0x80, 0x2f, 0x4f, 0x0d, 0x3a,
+ /*8670:*/ 0x97, 0x3b, 0xcd, 0xfa, 0xde, 0xa0, 0xaf, 0x6d, 0x1e, 0xd2, 0x47, 0x31, 0xe0, 0xf3, 0xcf, 0x15,
+ /*8680:*/ 0x12, 0xae, 0x45, 0xbb, 0x28, 0x04, 0x5e, 0xf6, 0x2e, 0xab, 0xa5, 0x8f, 0xea, 0xd0, 0xa4, 0xbf,
+ /*8690:*/ 0xbe, 0xa7, 0x77, 0x5d, 0x7b, 0xab, 0x48, 0x5f, 0x1a, 0xe4, 0xc6, 0xb3, 0x62, 0x70, 0xdf, 0x82,
+ /*86a0:*/ 0x24, 0x59, 0xd6, 0x88, 0x5c, 0x36, 0xd6, 0x0c, 0xbe, 0xbc, 0xbd, 0xc6, 0x1a, 0xcb, 0x93, 0xfa,
+ /*86b0:*/ 0xff, 0x16, 0x26, 0xea, 0xd2, 0xd3, 0x41, 0x5a, 0x49, 0x00, 0x99, 0x12, 0x48, 0xbe, 0xa8, 0xc7,
+ /*86c0:*/ 0xe3, 0x5d, 0x3b, 0xb1, 0x40, 0x35, 0xee, 0xfe, 0xc3, 0x78, 0x2b, 0xfe, 0x10, 0x20, 0xc9, 0x96,
+ /*86d0:*/ 0x28, 0xc2, 0xb2, 0x17, 0x03, 0x69, 0x85, 0x74, 0xf5, 0xac, 0x28, 0x02, 0xd0, 0x97, 0x74, 0xf2,
+ /*86e0:*/ 0x22, 0x12, 0x80, 0xf1, 0x1b, 0xd8, 0x49, 0x1d, 0x70, 0x79, 0x56, 0x7a, 0xbb, 0x2e, 0x5b, 0x35,
+ /*86f0:*/ 0x17, 0x34, 0x9b, 0xef, 0xf8, 0x58, 0x8d, 0x4b, 0xf3, 0x9a, 0x7a, 0xb3, 0xf7, 0x8c, 0x08, 0x4c,
+ /*8700:*/ 0x1f, 0xe4, 0x47, 0x30, 0xa2, 0x16, 0x9e, 0xe3, 0x5f, 0xb6, 0x57, 0xb3, 0x93, 0x8f, 0xd0, 0x5e,
+ /*8710:*/ 0x3b, 0x8d, 0x64, 0x70, 0x7c, 0xbc, 0x6e, 0xc0, 0x12, 0x4b, 0x1e, 0xcd, 0x0b, 0x58, 0x5c, 0xed,
+ /*8720:*/ 0x19, 0x2f, 0x72, 0x39, 0xaf, 0x03, 0xaf, 0x8f, 0xe0, 0xc1, 0x3f, 0xcc, 0x8a, 0x9a, 0x95, 0x12,
+ /*8730:*/ 0x7c, 0x88, 0x38, 0x7d, 0x82, 0xdb, 0xbe, 0x58, 0xbb, 0xa8, 0x9b, 0x05, 0x5f, 0x81, 0xe4, 0xaa,
+ /*8740:*/ 0x58, 0x81, 0xdc, 0x5f, 0x8a, 0x7c, 0xc0, 0xbc, 0x57, 0xa8, 0x48, 0xa4, 0x7e, 0xd5, 0x6d, 0xc4,
+ /*8750:*/ 0x04, 0x62, 0xbd, 0x28, 0x0e, 0x5c, 0x97, 0x3b, 0xf2, 0x6f, 0xee, 0xe9, 0x0d, 0x5a, 0x9c, 0x79,
+ /*8760:*/ 0x17, 0xfe, 0xac, 0x66, 0xb0, 0xa6, 0x6e, 0x11, 0x9b, 0xbe, 0x0b, 0xb4, 0x32, 0x67, 0x47, 0x14,
+ /*8770:*/ 0x70, 0xd6, 0x1c, 0x8c, 0x8f, 0x95, 0x96, 0xa8, 0x46, 0x10, 0x82, 0x49, 0xb7, 0x69, 0xb7, 0x40,
+ /*8780:*/ 0x83, 0xad, 0xfa, 0x1f, 0x89, 0x05, 0x8a, 0x16, 0x58, 0xee, 0x9c, 0xfd, 0x9f, 0x0c, 0xc6, 0xca,
+ /*8790:*/ 0xaf, 0x47, 0x5a, 0x00, 0xcd, 0xd6, 0x83, 0x8d, 0x04, 0xf6, 0x18, 0xc7, 0xf3, 0xd2, 0x4c, 0x7c,
+ /*87a0:*/ 0xdf, 0xc8, 0x61, 0xa9, 0x82, 0x96, 0xf3, 0x18, 0x77, 0xe2, 0x0a, 0x2c, 0x77, 0x67, 0x3c, 0x65,
+ /*87b0:*/ 0xd4, 0x56, 0xb0, 0xa6, 0x57, 0x0e, 0x74, 0xc9, 0xb5, 0x5e, 0xde, 0xe3, 0x09, 0x69, 0x53, 0x77,
+ /*87c0:*/ 0xdf, 0xd6, 0x20, 0xba, 0x19, 0xd6, 0x16, 0xbd, 0x4c, 0x95, 0x94, 0x00, 0x4a, 0xf8, 0x72, 0x83,
+ /*87d0:*/ 0x4c, 0xf2, 0x96, 0xa7, 0x1e, 0xf9, 0x62, 0x98, 0x64, 0x1a, 0xa5, 0x40, 0xb1, 0xbe, 0xd5, 0xb6,
+ /*87e0:*/ 0x53, 0x5f, 0xb9, 0xce, 0xa3, 0xcf, 0x03, 0x46, 0x94, 0x85, 0xd8, 0xc4, 0x86, 0x23, 0x85, 0x08,
+ /*87f0:*/ 0x1a, 0x13, 0xa2, 0x41, 0xf6, 0x9d, 0x52, 0xc6, 0xb2, 0x67, 0xe3, 0x30, 0x23, 0xcb, 0x3a, 0x4b,
+ /*8800:*/ 0x41, 0x57, 0x5f, 0xd2, 0x75, 0x8b, 0x5f, 0x44, 0x39, 0x40, 0x34, 0x25, 0xf1, 0xda, 0x0a, 0xb0,
+ /*8810:*/ 0xf0, 0xac, 0x15, 0x8d, 0xee, 0x68, 0x5c, 0x39, 0xbf, 0x48, 0x9a, 0x82, 0xfd, 0x81, 0x45, 0x7e,
+ /*8820:*/ 0xce, 0x81, 0xe6, 0x97, 0x3d, 0xf4, 0x21, 0x8c, 0x9b, 0x36, 0xe6, 0xd0, 0xbf, 0xcc, 0xf2, 0x33,
+ /*8830:*/ 0x4e, 0x98, 0x70, 0x3f, 0x08, 0x52, 0x9f, 0xd4, 0x48, 0xf3, 0x0a, 0xd8, 0x51, 0xfb, 0x39, 0x9b,
+ /*8840:*/ 0x8a, 0xf1, 0x32, 0x55, 0xf0, 0x59, 0x68, 0x17, 0xc8, 0x35, 0xe3, 0x38, 0x8c, 0x40, 0xd4, 0xf7,
+ /*8850:*/ 0xd3, 0xe7, 0x20, 0x07, 0x84, 0xf8, 0xc0, 0x9a, 0x2c, 0x56, 0x6d, 0xaa, 0xae, 0xca, 0x16, 0x82,
+ /*8860:*/ 0x9a, 0xd1, 0x72, 0x2e, 0xd4, 0x12, 0xda, 0x65, 0xe6, 0x78, 0x01, 0x79, 0x16, 0xa2, 0x05, 0x45,
+ /*8870:*/ 0x0b, 0xbc, 0x65, 0xd4, 0xf5, 0x19, 0x9d, 0x1f, 0xa4, 0x49, 0x02, 0xe3, 0x0f, 0x1a, 0x82, 0x49,
+ /*8880:*/ 0x2c, 0xd2, 0x22, 0xdf, 0x97, 0x7d, 0xe6, 0xaf, 0x14, 0x03, 0xdf, 0x69, 0xe6, 0xf3, 0x07, 0x50,
+ /*8890:*/ 0x48, 0xe5, 0x42, 0xfe, 0xe3, 0x59, 0x91, 0x6d, 0xbc, 0xf6, 0xd1, 0xf0, 0x2a, 0xbd, 0x0a, 0x4d,
+ /*88a0:*/ 0x4f, 0x51, 0x6e, 0x0f, 0x76, 0xef, 0xa8, 0xb5, 0xa7, 0x8b, 0x49, 0xf3, 0xd5, 0x8e, 0xf4, 0x41,
+ /*88b0:*/ 0xf9, 0x57, 0x26, 0x2f, 0xcf, 0xa8, 0xd7, 0x76, 0x36, 0xd1, 0xf1, 0xb9, 0x26, 0x79, 0x92, 0xaf,
+ /*88c0:*/ 0xcc, 0xf6, 0xe9, 0xab, 0xf2, 0x96, 0xec, 0x5e, 0xbb, 0xcc, 0xf0, 0x89, 0x39, 0xc1, 0x83, 0x8f,
+ /*88d0:*/ 0xf5, 0x07, 0xb6, 0x17, 0x61, 0x17, 0x1c, 0xcd, 0xb6, 0x3b, 0xcc, 0x68, 0x8d, 0x52, 0x96, 0x18,
+ /*88e0:*/ 0xbf, 0x18, 0x00, 0xcf, 0xf5, 0x9c, 0x81, 0x20, 0xb0, 0xed, 0x63, 0xef, 0x1e, 0xa2, 0xac, 0x84,
+ /*88f0:*/ 0x19, 0xd8, 0x9a, 0x28, 0x68, 0x27, 0xb1, 0x99, 0x54, 0x4b, 0xe4, 0x0b, 0xcc, 0x55, 0x9e, 0x49,
+ /*8900:*/ 0xdb, 0xbc, 0x4d, 0x85, 0x1d, 0x83, 0x83, 0x46, 0x64, 0x27, 0xe1, 0x6d, 0x25, 0x24, 0x72, 0xfe,
+ /*8910:*/ 0xfb, 0x37, 0x67, 0x48, 0xf0, 0x7f, 0x7a, 0xbc, 0x9c, 0x9b, 0xa6, 0xe0, 0x55, 0xa4, 0x98, 0x3b,
+ /*8920:*/ 0x8e, 0xbe, 0x5b, 0x92, 0x29, 0x5e, 0xcd, 0x46, 0xcd, 0x83, 0x43, 0xfb, 0x8a, 0xaf, 0x68, 0x89,
+ /*8930:*/ 0xc6, 0x68, 0x32, 0x83, 0x7c, 0x33, 0x6e, 0xf9, 0x8f, 0x53, 0x40, 0xda, 0x2c, 0x6f, 0xcc, 0x7a,
+ /*8940:*/ 0xd7, 0x90, 0xd7, 0xc0, 0x29, 0x9d, 0xb7, 0x08, 0xe0, 0xa4, 0x41, 0x25, 0x7e, 0x39, 0x04, 0xf3,
+ /*8950:*/ 0x02, 0xb8, 0x4e, 0x3e, 0xee, 0x80, 0x07, 0x20, 0xdc, 0x49, 0x16, 0x9e, 0xab, 0xb0, 0x81, 0xd3,
+ /*8960:*/ 0x33, 0x00, 0xfe, 0xf6, 0x85, 0xcd, 0xf8, 0xe6, 0x79, 0x87, 0x1a, 0x5b, 0x1e, 0x11, 0x1b, 0xca,
+ /*8970:*/ 0x89, 0x35, 0xa5, 0x3a, 0x98, 0x0f, 0x4d, 0x20, 0x25, 0xe4, 0xbf, 0x48, 0x6d, 0x2c, 0x03, 0x97,
+ /*8980:*/ 0xff, 0xbb, 0x85, 0x3b, 0x1f, 0x17, 0x4f, 0xd6, 0xf4, 0xd4, 0xb8, 0x80, 0x49, 0x1a, 0x52, 0x26,
+ /*8990:*/ 0xbd, 0x81, 0x41, 0xe8, 0xc3, 0x63, 0x67, 0xf3, 0xe5, 0xeb, 0x57, 0xbe, 0x28, 0x83, 0xef, 0x3f,
+ /*89a0:*/ 0xcc, 0xff, 0x4f, 0xed, 0x19, 0xce, 0xe9, 0xe5, 0x0d, 0x1e, 0x0c, 0xd3, 0x8d, 0xed, 0xa3, 0x47,
+ /*89b0:*/ 0xb7, 0x1d, 0x63, 0x61, 0xc7, 0xfe, 0x36, 0xfa, 0x05, 0x30, 0xd9, 0x36, 0x04, 0xb8, 0x05, 0x1b,
+ /*89c0:*/ 0x89, 0xf3, 0xc0, 0x81, 0x07, 0xd5, 0xdf, 0x7f, 0x17, 0x5c, 0xaf, 0x75, 0x35, 0xeb, 0x2b, 0xac,
+ /*89d0:*/ 0x48, 0xd6, 0x07, 0xe7, 0x72, 0x3e, 0xa6, 0x30, 0x75, 0x77, 0x03, 0x74, 0x31, 0xe5, 0x8b, 0x10,
+ /*89e0:*/ 0xd0, 0x2a, 0x3c, 0xc7, 0x7d, 0xd4, 0x4e, 0xa5, 0xc9, 0xc7, 0xd1, 0xb8, 0xdb, 0x9d, 0x34, 0xbb,
+ /*89f0:*/ 0xce, 0x26, 0x16, 0x60, 0x38, 0x95, 0x28, 0x78, 0x60, 0xcb, 0x3f, 0xbd, 0xaa, 0x93, 0xed, 0xb3,
+ /*8a00:*/ 0x0d, 0xd0, 0x8c, 0xf4, 0x69, 0x24, 0x35, 0x84, 0x60, 0x2b, 0x48, 0x5b, 0x9a, 0x7e, 0xb8, 0xe1,
+ /*8a10:*/ 0xec, 0x6a, 0x17, 0x17, 0xb9, 0xdc, 0x5d, 0xa9, 0xf2, 0x95, 0x7f, 0xf5, 0xe7, 0x6c, 0x79, 0x93,
+ /*8a20:*/ 0xab, 0xb2, 0x52, 0x1a, 0x39, 0x5b, 0x3e, 0x49, 0x18, 0x19, 0x3c, 0xe7, 0x7e, 0xf4, 0x95, 0x96,
+ /*8a30:*/ 0x79, 0x30, 0xc0, 0x3f, 0x7a, 0xde, 0x28, 0xd9, 0x95, 0xe3, 0x69, 0x5b, 0xa5, 0x10, 0xb3, 0xe6,
+ /*8a40:*/ 0x1c, 0x01, 0xcc, 0xd4, 0xf2, 0x58, 0x76, 0x52, 0x9b, 0x1e, 0xa1, 0x90, 0xb0, 0xa4, 0x8e, 0x3e,
+ /*8a50:*/ 0x9f, 0x46, 0x9e, 0xa8, 0x75, 0x15, 0xe7, 0xfb, 0xf8, 0x5b, 0xb4, 0x55, 0x92, 0x12, 0x1b, 0x07,
+ /*8a60:*/ 0xb0, 0xe9, 0x0e, 0xf7, 0xf6, 0x1c, 0x7b, 0x31, 0x35, 0x2c, 0x3f, 0x12, 0x08, 0x1f, 0xe5, 0xf7,
+ /*8a70:*/ 0x7c, 0x9a, 0x32, 0xa2, 0xa5, 0x5c, 0x49, 0x54, 0x52, 0x0d, 0xca, 0xeb, 0x2c, 0x5e, 0x0d, 0xf2,
+ /*8a80:*/ 0x54, 0x10, 0x6b, 0x8f, 0x81, 0x1d, 0x56, 0x6e, 0x62, 0x7b, 0xfa, 0xe5, 0x65, 0x85, 0x71, 0xde,
+ /*8a90:*/ 0x53, 0x5e, 0x8a, 0x39, 0xed, 0x01, 0x3d, 0xe0, 0x37, 0x22, 0x1d, 0xd5, 0x6d, 0x94, 0xee, 0x8b,
+ /*8aa0:*/ 0x26, 0x8b, 0xe4, 0xf9, 0x2e, 0x14, 0xe8, 0x33, 0x59, 0xd1, 0x91, 0x32, 0x4a, 0x57, 0x4b, 0x8a,
+ /*8ab0:*/ 0x81, 0xbc, 0x57, 0x87, 0xe4, 0xa2, 0x73, 0x27, 0xd5, 0x25, 0x7b, 0x25, 0x09, 0x58, 0x29, 0xd5,
+ /*8ac0:*/ 0xb2, 0x7a, 0x3b, 0x59, 0x00, 0xf3, 0xba, 0x38, 0x72, 0xa2, 0xd3, 0x0e, 0x92, 0x0f, 0xbd, 0x9d,
+ /*8ad0:*/ 0x08, 0xbb, 0xe1, 0xdd, 0x55, 0x7c, 0xd7, 0xaa, 0xf6, 0x23, 0x2f, 0x21, 0xba, 0x7a, 0x4c, 0xe6,
+ /*8ae0:*/ 0xf6, 0x21, 0x8a, 0x3f, 0x28, 0xfa, 0x5d, 0x78, 0x4a, 0xba, 0x36, 0x1f, 0xdc, 0xeb, 0xa4, 0x25,
+ /*8af0:*/ 0x4a, 0x5c, 0x19, 0xab, 0xaf, 0x78, 0x25, 0x85, 0x5d, 0x2c, 0x56, 0x91, 0xb2, 0xc2, 0x4c, 0xd1,
+ /*8b00:*/ 0x12, 0x1b, 0x0f, 0xcf, 0x71, 0x79, 0x3f, 0x39, 0xd4, 0x0c, 0x02, 0xef, 0x4c, 0x77, 0x61, 0xb2,
+ /*8b10:*/ 0x3e, 0x7e, 0x2e, 0x89, 0x23, 0x88, 0x61, 0xd2, 0xb7, 0x7b, 0xe0, 0xfa, 0x91, 0xa6, 0x7b, 0x20,
+ /*8b20:*/ 0x26, 0x37, 0xbd, 0xd0, 0xaa, 0x0c, 0x6b, 0x9a, 0x12, 0x3a, 0xf6, 0xff, 0x39, 0x7f, 0x41, 0xee,
+ /*8b30:*/ 0x8b, 0xd3, 0xc6, 0x0e, 0x0e, 0xc1, 0x73, 0x60, 0x7e, 0xd0, 0x65, 0x4b, 0x47, 0x16, 0x17, 0xcd,
+ /*8b40:*/ 0x6d, 0x4d, 0x6e, 0x24, 0xdd, 0x1f, 0x24, 0x4c, 0x2a, 0xb1, 0x09, 0xf7, 0x77, 0xb6, 0x18, 0xe2,
+ /*8b50:*/ 0xa6, 0xd7, 0x2f, 0x41, 0xf8, 0x87, 0xb2, 0x89, 0x86, 0x60, 0xdc, 0x55, 0x0f, 0xbe, 0x68, 0xa9,
+ /*8b60:*/ 0x3c, 0x3e, 0xc1, 0xd9, 0x2b, 0x92, 0x1e, 0xb1, 0xe9, 0x97, 0xfc, 0xc8, 0xe9, 0x0a, 0xdc, 0xa6,
+ /*8b70:*/ 0x43, 0xe8, 0xc1, 0xeb, 0x02, 0x54, 0x9f, 0x94, 0xaa, 0xf2, 0xef, 0x72, 0xa3, 0x5b, 0x96, 0xfe,
+ /*8b80:*/ 0x33, 0xc5, 0x04, 0x0f, 0x37, 0x1c, 0x77, 0x5d, 0x53, 0x7c, 0xa3, 0x42, 0x0c, 0x40, 0x4a, 0x50,
+ /*8b90:*/ 0xc6, 0x44, 0x1e, 0xdd, 0x1c, 0x27, 0x87, 0x8f, 0x79, 0x8f, 0x2b, 0x7e, 0x2c, 0x2c, 0x08, 0xaf,
+ /*8ba0:*/ 0xc6, 0xcb, 0x68, 0xbe, 0xc7, 0x41, 0x9e, 0x01, 0xf5, 0x51, 0x04, 0xa2, 0x52, 0xb0, 0x58, 0xa6,
+ /*8bb0:*/ 0xc3, 0xd9, 0xf8, 0xe5, 0xe5, 0x60, 0x5a, 0x42, 0x1c, 0x92, 0x71, 0x27, 0x2b, 0x1b, 0x7b, 0xad,
+ /*8bc0:*/ 0x32, 0x24, 0x3e, 0x75, 0xa2, 0x64, 0xaa, 0x8e, 0xe1, 0x96, 0x6e, 0x80, 0xf7, 0x6f, 0xdb, 0xce,
+ /*8bd0:*/ 0xa8, 0xd5, 0x4a, 0x8b, 0xd4, 0x29, 0x10, 0x03, 0x17, 0x38, 0x5f, 0xdc, 0xca, 0xd7, 0xeb, 0xac,
+ /*8be0:*/ 0x45, 0x3d, 0xb8, 0x1b, 0x20, 0xae, 0x91, 0x6b, 0x63, 0xc7, 0xe4, 0x69, 0x94, 0xb9, 0x41, 0xe8,
+ /*8bf0:*/ 0xdc, 0x67, 0xb8, 0x0a, 0xfa, 0x72, 0x4e, 0x23, 0x12, 0xd9, 0xb1, 0x13, 0xf7, 0x53, 0xf6, 0x2b,
+ /*8c00:*/ 0x89, 0x06, 0x80, 0x67, 0x02, 0xc5, 0x4b, 0xbd, 0xaf, 0x60, 0x73, 0x90, 0x00, 0xd3, 0xfc, 0x9e,
+ /*8c10:*/ 0x59, 0x76, 0xaf, 0x70, 0x44, 0xd9, 0xae, 0x1a, 0x6b, 0xa7, 0x56, 0xad, 0x1b, 0xc2, 0xe6, 0xd5,
+ /*8c20:*/ 0xbc, 0x6f, 0x4a, 0xd9, 0x59, 0x11, 0xc1, 0xc5, 0xaf, 0x36, 0x26, 0x93, 0xd6, 0x20, 0x72, 0x61,
+ /*8c30:*/ 0x8e, 0xb6, 0x84, 0xab, 0x54, 0xcb, 0x7c, 0xf6, 0x84, 0x3b, 0x09, 0x3a, 0x46, 0x2f, 0xc6, 0x95,
+ /*8c40:*/ 0x07, 0x5f, 0xda, 0xf6, 0x8b, 0x30, 0x6d, 0xd9, 0xbb, 0x6f, 0x13, 0xea, 0x81, 0xa3, 0xd5, 0x72,
+ /*8c50:*/ 0x46, 0x43, 0x53, 0xe5, 0xbd, 0x02, 0x9c, 0x1d, 0x29, 0x94, 0x97, 0x01, 0xce, 0x6a, 0x76, 0x7b,
+ /*8c60:*/ 0xc3, 0xa5, 0x2f, 0xcf, 0xe4, 0x81, 0x32, 0xb5, 0x9f, 0xa1, 0x98, 0xea, 0xab, 0xe9, 0x6c, 0x8a,
+ /*8c70:*/ 0x37, 0x4e, 0x9e, 0x10, 0x1b, 0x87, 0xbd, 0x06, 0x77, 0xd5, 0x79, 0x79, 0xe3, 0x6d, 0x4e, 0x96,
+ /*8c80:*/ 0x51, 0x56, 0xd6, 0x18, 0x93, 0xe8, 0x69, 0xb4, 0x50, 0xf6, 0x61, 0xfc, 0x67, 0xdf, 0x82, 0xd4,
+ /*8c90:*/ 0x99, 0x06, 0x16, 0x97, 0x95, 0xd6, 0x43, 0xd6, 0x31, 0x4f, 0xb7, 0xeb, 0x2f, 0x3a, 0x3b, 0x1a,
+ /*8ca0:*/ 0xd9, 0xe2, 0xa1, 0xca, 0xbb, 0x76, 0x48, 0xe3, 0x47, 0xcc, 0xbe, 0x67, 0x24, 0xa2, 0xd0, 0x9a,
+ /*8cb0:*/ 0x7c, 0x30, 0x4f, 0x1b, 0x85, 0x08, 0xc9, 0xec, 0x98, 0x65, 0xb0, 0x93, 0x10, 0x1c, 0xca, 0x83,
+ /*8cc0:*/ 0x2d, 0x00, 0x68, 0x96, 0x39, 0x3f, 0x3f, 0x7c, 0x42, 0x6b, 0x6f, 0x41, 0x3f, 0xf3, 0x29, 0x66,
+ /*8cd0:*/ 0x98, 0xfb, 0x14, 0x3c, 0x8b, 0xd9, 0x5f, 0xdd, 0xe7, 0x8d, 0xbd, 0x40, 0x5a, 0x12, 0x41, 0x0c,
+ /*8ce0:*/ 0xd8, 0x02, 0x89, 0xc1, 0x65, 0x1b, 0xb2, 0x79, 0x6b, 0x98, 0x50, 0xff, 0xc8, 0xf0, 0x67, 0x66,
+ /*8cf0:*/ 0x51, 0xb8, 0x05, 0xc9, 0x1a, 0xcc, 0x7e, 0x28, 0x22, 0xc7, 0x11, 0xf6, 0xfc, 0x71, 0xeb, 0x97,
+ /*8d00:*/ 0x4b, 0x51, 0x53, 0x25, 0x88, 0xc9, 0x5e, 0x11, 0x84, 0x79, 0x4e, 0xf2, 0x02, 0x2f, 0xa6, 0x7e,
+ /*8d10:*/ 0x82, 0x65, 0x34, 0xfa, 0xd6, 0x33, 0xfe, 0xaa, 0x95, 0xe5, 0xb3, 0xd1, 0x5e, 0xf6, 0xdf, 0x96,
+ /*8d20:*/ 0x20, 0x29, 0xd6, 0xd4, 0xc1, 0x5c, 0x53, 0x2b, 0x4c, 0x32, 0xf4, 0xae, 0xfc, 0x69, 0x53, 0xfc,
+ /*8d30:*/ 0x2a, 0x7e, 0x83, 0xfb, 0x8f, 0x35, 0xe2, 0xd9, 0x5c, 0x12, 0x22, 0x5c, 0xc0, 0x75, 0x8a, 0x23,
+ /*8d40:*/ 0x8d, 0x63, 0xc8, 0xa9, 0x69, 0x40, 0x9c, 0x29, 0x22, 0xe9, 0x6a, 0x2b, 0x0c, 0xb7, 0xc8, 0x79,
+ /*8d50:*/ 0xb6, 0xcd, 0xaf, 0xac, 0x91, 0x96, 0x78, 0xb6, 0x29, 0x0b, 0xbd, 0x76, 0xd5, 0x2e, 0xcc, 0x39,
+ /*8d60:*/ 0x3b, 0xcc, 0xb1, 0xff, 0x91, 0xb9, 0xab, 0xcb, 0x34, 0xfb, 0xcf, 0xaf, 0xe3, 0xde, 0xb2, 0x37,
+ /*8d70:*/ 0xb5, 0x79, 0x47, 0xb3, 0xac, 0x9b, 0x20, 0xc4, 0xda, 0x7d, 0x6f, 0x49, 0x6f, 0x8b, 0xe3, 0x4b,
+ /*8d80:*/ 0x31, 0x23, 0x28, 0x63, 0x08, 0x59, 0x23, 0xf1, 0xa5, 0xea, 0x64, 0x08, 0x88, 0x34, 0xf3, 0x39,
+ /*8d90:*/ 0x62, 0xe8, 0x7a, 0x18, 0xed, 0x25, 0xa4, 0x68, 0x3d, 0xa6, 0x64, 0x0d, 0xdc, 0x99, 0x05, 0xc9,
+ /*8da0:*/ 0xb0, 0x9e, 0xc3, 0xe3, 0xa2, 0x9e, 0xc7, 0x92, 0x7a, 0xe1, 0xdd, 0x0e, 0x9d, 0x71, 0x6c, 0xf5,
+ /*8db0:*/ 0x73, 0xa5, 0xf9, 0xdf, 0x94, 0x49, 0xa3, 0x23, 0x73, 0xe0, 0x51, 0x6d, 0x0f, 0x9e, 0x1a, 0x87,
+ /*8dc0:*/ 0x3a, 0xef, 0xa4, 0x63, 0x13, 0x79, 0x7a, 0x2d, 0x0f, 0x7c, 0x88, 0x8b, 0xb1, 0x65, 0xbf, 0x0a,
+ /*8dd0:*/ 0xb5, 0x21, 0xc4, 0x7c, 0x65, 0xe3, 0x52, 0x1d, 0xa2, 0xf6, 0x1d, 0x93, 0x84, 0x86, 0x7a, 0xe8,
+ /*8de0:*/ 0x5f, 0x72, 0x4b, 0x85, 0x48, 0x8f, 0x23, 0x93, 0x7f, 0xdd, 0xef, 0x17, 0x46, 0x5d, 0xbe, 0xc0,
+ /*8df0:*/ 0x67, 0xbd, 0xe4, 0xd7, 0xc9, 0xca, 0x2e, 0xc6, 0x8b, 0xc3, 0x82, 0x28, 0x0f, 0xa6, 0x22, 0x9c,
+ /*8e00:*/ 0xaf, 0x0c, 0xa2, 0x5f, 0xe6, 0x91, 0x72, 0x6b, 0x43, 0x44, 0xd5, 0x8c, 0xd5, 0x55, 0xc2, 0x6a,
+ /*8e10:*/ 0x95, 0xe0, 0x42, 0x22, 0x41, 0xe7, 0xd5, 0x2a, 0xfa, 0xf7, 0xaa, 0x74, 0x29, 0x4f, 0x87, 0x2c,
+ /*8e20:*/ 0x38, 0x6a, 0x4a, 0x07, 0x38, 0xfd, 0x8c, 0xe2, 0x8d, 0xd8, 0x2b, 0x2e, 0xe7, 0x2b, 0xbc, 0x02,
+ /*8e30:*/ 0x22, 0xa1, 0x26, 0xce, 0x57, 0xab, 0x9b, 0x20, 0x02, 0x43, 0xaf, 0xb5, 0x73, 0x95, 0xc1, 0x5a,
+ /*8e40:*/ 0xe2, 0xe3, 0x7f, 0x60, 0x04, 0xab, 0xa3, 0x21, 0xf8, 0x18, 0xdb, 0x6b, 0x01, 0xdf, 0x6a, 0xac,
+ /*8e50:*/ 0xdb, 0x37, 0xa4, 0xdd, 0x4b, 0x0e, 0xfa, 0x39, 0xed, 0x64, 0xfb, 0xfc, 0x98, 0xe7, 0x71, 0x02,
+ /*8e60:*/ 0xdd, 0xbb, 0xa5, 0x62, 0x7e, 0x18, 0x16, 0xe1, 0x6e, 0xbd, 0x1d, 0xb3, 0xc5, 0x11, 0xd2, 0xdb,
+ /*8e70:*/ 0x20, 0x1f, 0x3a, 0x84, 0xda, 0x08, 0x7d, 0x58, 0x50, 0xc3, 0x3c, 0x5c, 0x7c, 0xc9, 0xb8, 0x78,
+ /*8e80:*/ 0x03, 0x57, 0x93, 0x71, 0x71, 0x28, 0xaf, 0x84, 0xd6, 0x89, 0xa2, 0xd4, 0x01, 0xcb, 0x26, 0x1b,
+ /*8e90:*/ 0x0a, 0x35, 0x38, 0xf8, 0x77, 0xb1, 0x09, 0x03, 0xb7, 0x1a, 0x0d, 0xb2, 0x82, 0x90, 0x22, 0x05,
+ /*8ea0:*/ 0x19, 0x63, 0x66, 0x58, 0x4a, 0xf9, 0x2f, 0x2f, 0xe2, 0xbb, 0x2b, 0x31, 0xca, 0xdc, 0x96, 0x47,
+ /*8eb0:*/ 0x88, 0x7d, 0x62, 0x75, 0xe6, 0x96, 0xf3, 0xa2, 0x1e, 0x62, 0x59, 0xff, 0x24, 0xbe, 0x2f, 0x8f,
+ /*8ec0:*/ 0xdf, 0xd5, 0x72, 0xfc, 0x0f, 0xc8, 0x10, 0x48, 0xa2, 0x90, 0xe0, 0x1a, 0xa2, 0x0c, 0x80, 0x80,
+ /*8ed0:*/ 0xda, 0xb8, 0x2f, 0x8c, 0xc4, 0x07, 0x49, 0x7a, 0x29, 0xf5, 0xbb, 0x02, 0x49, 0xc0, 0xa5, 0x5c,
+ /*8ee0:*/ 0x54, 0x6f, 0x05, 0xb6, 0x48, 0x1c, 0x41, 0xc9, 0xa2, 0x19, 0xab, 0xc4, 0x39, 0x6d, 0xf7, 0x7b,
+ /*8ef0:*/ 0x22, 0xc0, 0xbd, 0xbf, 0xd7, 0x88, 0x46, 0xe4, 0x18, 0x42, 0x06, 0xea, 0x45, 0xcb, 0x6a, 0xe1,
+ /*8f00:*/ 0x23, 0xe6, 0x93, 0x32, 0x7a, 0x56, 0x90, 0x80, 0xa9, 0xb1, 0xe3, 0x47, 0x6f, 0x71, 0x17, 0xb2,
+ /*8f10:*/ 0x6f, 0x5b, 0x23, 0x7a, 0x22, 0xea, 0xeb, 0xd1, 0x52, 0xed, 0x41, 0x71, 0xf5, 0x16, 0x98, 0x3a,
+ /*8f20:*/ 0x57, 0x79, 0x86, 0x99, 0xbf, 0xbe, 0xd2, 0x6b, 0x9d, 0x2a, 0x14, 0x61, 0x03, 0x5e, 0x4b, 0x5f,
+ /*8f30:*/ 0x02, 0x59, 0x22, 0x37, 0x13, 0x79, 0x7d, 0x47, 0xca, 0xc4, 0xe9, 0xa9, 0x0f, 0x33, 0x89, 0x72,
+ /*8f40:*/ 0x86, 0x3a, 0x79, 0x68, 0x17, 0x63, 0x6a, 0x0d, 0x50, 0x59, 0xd3, 0xb8, 0x3f, 0x32, 0x84, 0x6a,
+ /*8f50:*/ 0x7c, 0x11, 0x65, 0xb1, 0x34, 0xb6, 0x6a, 0x9f, 0x59, 0x28, 0xdd, 0xe8, 0xef, 0x10, 0x2a, 0x65,
+ /*8f60:*/ 0xde, 0x73, 0x8e, 0x15, 0x64, 0xcf, 0x99, 0xa9, 0x01, 0xdb, 0x79, 0x12, 0x99, 0x9b, 0x66, 0x0c,
+ /*8f70:*/ 0x5b, 0x2f, 0x31, 0xd4, 0xdd, 0x74, 0x8b, 0x64, 0x3e, 0x7e, 0xee, 0x85, 0xac, 0xcb, 0x94, 0x8a,
+ /*8f80:*/ 0xfb, 0xc8, 0x87, 0xce, 0xeb, 0x18, 0x23, 0xd4, 0x13, 0x4c, 0x22, 0xeb, 0x2d, 0x71, 0x7e, 0xd6,
+ /*8f90:*/ 0x4f, 0x06, 0x85, 0xf2, 0xf7, 0x4d, 0x39, 0xc3, 0x11, 0x33, 0x2a, 0x9e, 0xf8, 0x3c, 0xde, 0xef,
+ /*8fa0:*/ 0x06, 0xbe, 0xcd, 0x77, 0x21, 0xeb, 0xb0, 0xd6, 0xcf, 0x41, 0xd2, 0xd9, 0xb5, 0x8c, 0xa9, 0x51,
+ /*8fb0:*/ 0xae, 0x17, 0xe0, 0xb0, 0x60, 0x3f, 0x62, 0x82, 0x71, 0x28, 0x7e, 0xb9, 0x6d, 0x17, 0x26, 0xde,
+ /*8fc0:*/ 0xb0, 0x98, 0xeb, 0x35, 0x28, 0xb9, 0x1e, 0xd5, 0x82, 0xf7, 0xaf, 0xa2, 0x3b, 0xb7, 0xbe, 0xfd,
+ /*8fd0:*/ 0x4d, 0x68, 0x6a, 0x20, 0x61, 0x50, 0x47, 0xb2, 0x4a, 0x42, 0x7a, 0xfa, 0x29, 0xcc, 0x9e, 0x2f,
+ /*8fe0:*/ 0xd9, 0x50, 0x5b, 0xac, 0x1d, 0x02, 0x90, 0xd9, 0xe5, 0xe8, 0x51, 0x12, 0xe8, 0x3b, 0xb9, 0x06,
+ /*8ff0:*/ 0x93, 0xb5, 0x3c, 0xa3, 0xdf, 0x96, 0xd1, 0x07, 0xb5, 0xf7, 0x6d, 0xcd, 0x6e, 0x2c, 0xd3, 0x89,
+ /*9000:*/ 0xcd, 0x97, 0xfb, 0x6a, 0x85, 0xcf, 0x10, 0x46, 0xdc, 0xc6, 0xde, 0x2d, 0x28, 0x1a, 0xe7, 0x1a,
+ /*9010:*/ 0x6a, 0x19, 0x84, 0x67, 0x2d, 0x47, 0xb2, 0x05, 0xca, 0xe2, 0x74, 0xf6, 0xbc, 0x62, 0x15, 0x74,
+ /*9020:*/ 0x19, 0x15, 0x04, 0x73, 0xd1, 0x52, 0xe6, 0x57, 0xbf, 0x05, 0x0b, 0xe4, 0x38, 0x0c, 0x7c, 0x7b,
+ /*9030:*/ 0x87, 0x7c, 0xa0, 0xd3, 0x14, 0x94, 0xcc, 0x4d, 0x73, 0x12, 0xac, 0x5e, 0x7d, 0x74, 0xb3, 0x43,
+ /*9040:*/ 0xe1, 0x88, 0xca, 0x1d, 0x3d, 0x1c, 0xa1, 0x11, 0x83, 0xea, 0xf0, 0x72, 0x29, 0xda, 0xbe, 0xd3,
+ /*9050:*/ 0x98, 0xd2, 0xd8, 0xd6, 0x71, 0x9c, 0x7b, 0x44, 0xb8, 0x3c, 0xf6, 0x04, 0xc5, 0x32, 0xb8, 0x4e,
+ /*9060:*/ 0xb9, 0xcd, 0x59, 0x36, 0xe8, 0xd1, 0x63, 0x70, 0xd6, 0x5d, 0x0d, 0x49, 0xc8, 0x0e, 0xb6, 0x28,
+ /*9070:*/ 0x68, 0x67, 0xe8, 0x0c, 0x8c, 0x2f, 0x74, 0xfd, 0x56, 0x1d, 0x65, 0xaf, 0x33, 0xba, 0xf4, 0xe0,
+ /*9080:*/ 0x8c, 0xff, 0x5e, 0x96, 0x4c, 0xa9, 0x25, 0xde, 0x03, 0x8d, 0x38, 0xc6, 0xba, 0x40, 0xf8, 0xdf,
+ /*9090:*/ 0x93, 0xb4, 0x50, 0x58, 0x42, 0x73, 0x91, 0xad, 0xb4, 0x6f, 0x25, 0x0b, 0x7f, 0x5a, 0xd0, 0x69,
+ /*90a0:*/ 0x0e, 0x44, 0xbc, 0x27, 0xcc, 0x14, 0x07, 0xeb, 0x11, 0x20, 0x05, 0x3b, 0xf0, 0x73, 0x51, 0xc2,
+ /*90b0:*/ 0x3e, 0xbb, 0x85, 0xc9, 0xd7, 0xea, 0xd0, 0x0e, 0x25, 0xa1, 0x41, 0xe1, 0x70, 0xbd, 0xae, 0x81,
+ /*90c0:*/ 0xcc, 0x2b, 0x19, 0x39, 0x3b, 0xb3, 0x65, 0x2b, 0xd7, 0x9d, 0x94, 0xb3, 0xe1, 0xe7, 0xa5, 0xde,
+ /*90d0:*/ 0xd5, 0xe8, 0xb7, 0xc3, 0x4d, 0xbb, 0x32, 0x71, 0xa3, 0xfc, 0xb0, 0x6c, 0x8e, 0x20, 0xe7, 0xeb,
+ /*90e0:*/ 0x88, 0xc8, 0xa4, 0x76, 0xe8, 0xd5, 0xb1, 0x24, 0xbb, 0xa4, 0x35, 0xc8, 0x74, 0xb5, 0x3b, 0xba,
+ /*90f0:*/ 0x08, 0xbc, 0xbd, 0xcd, 0xe6, 0x0e, 0x71, 0x32, 0x0e, 0x88, 0x52, 0xfa, 0x45, 0xe7, 0x02, 0x3b,
+ /*9100:*/ 0x11, 0x5d, 0x8c, 0x07, 0x14, 0xc1, 0x68, 0x05, 0xc2, 0x4f, 0x03, 0x1c, 0x17, 0xa6, 0x38, 0xa1,
+ /*9110:*/ 0x9d, 0x07, 0xb0, 0xb3, 0x00, 0xab, 0x98, 0x89, 0x79, 0xd3, 0x8b, 0xb2, 0x93, 0x6b, 0x30, 0xf4,
+ /*9120:*/ 0x0c, 0xbd, 0xe3, 0x79, 0x3d, 0x1e, 0x3a, 0x75, 0xf8, 0x67, 0x3f, 0xd9, 0x20, 0x07, 0x22, 0xe6,
+ /*9130:*/ 0xc1, 0x4f, 0x85, 0x56, 0x68, 0xaa, 0xd1, 0x70, 0xd9, 0x3c, 0x24, 0xee, 0xdf, 0xcc, 0x1c, 0xda,
+ /*9140:*/ 0x76, 0xf5, 0x18, 0xd1, 0x53, 0x43, 0x3c, 0x1a, 0x51, 0xa4, 0x34, 0xce, 0xde, 0x4d, 0xfb, 0xee,
+ /*9150:*/ 0x8e, 0xca, 0xb7, 0x36, 0xae, 0x68, 0xcc, 0x22, 0x8b, 0xec, 0x66, 0xba, 0xcd, 0x93, 0x41, 0x75,
+ /*9160:*/ 0xc5, 0xba, 0x92, 0x23, 0xde, 0x1b, 0xc4, 0xc8, 0x75, 0xcb, 0xcc, 0x14, 0x2b, 0x99, 0x06, 0x43,
+ /*9170:*/ 0xd1, 0x9d, 0xae, 0xd5, 0x54, 0xda, 0x5f, 0x6f, 0x9c, 0x96, 0x52, 0x1c, 0xca, 0xf6, 0xab, 0x58,
+ /*9180:*/ 0xe4, 0xbd, 0x83, 0x35, 0xc6, 0x32, 0xae, 0xd7, 0x54, 0x59, 0x53, 0xb3, 0x33, 0xe6, 0xd9, 0x7c,
+ /*9190:*/ 0x72, 0xb5, 0xcb, 0x02, 0x92, 0xd8, 0xf2, 0x68, 0xd1, 0xdb, 0x93, 0xd8, 0x2e, 0xc9, 0xda, 0x87,
+ /*91a0:*/ 0x50, 0xf2, 0x6c, 0xf9, 0x58, 0x2e, 0x6a, 0x6a, 0xfc, 0x08, 0x56, 0x9c, 0x6e, 0xe1, 0xdf, 0xe2,
+ /*91b0:*/ 0x90, 0x38, 0xbe, 0xb9, 0xbc, 0x2e, 0xb9, 0x2c, 0xcc, 0xd9, 0x0d, 0x25, 0xe2, 0x37, 0xf4, 0x28,
+ /*91c0:*/ 0xe1, 0xc1, 0xf2, 0xc9, 0x68, 0xd3, 0xff, 0xa3, 0xf0, 0x28, 0x67, 0x48, 0xfb, 0x91, 0xfe, 0x46,
+ /*91d0:*/ 0xc4, 0xbf, 0x60, 0xe7, 0x97, 0x37, 0x3f, 0xd2, 0x7e, 0xdf, 0x3d, 0x27, 0x6d, 0x3e, 0x69, 0xa5,
+ /*91e0:*/ 0x7f, 0x2f, 0x57, 0xeb, 0x82, 0x7e, 0x94, 0x85, 0x69, 0xb2, 0x9d, 0xa6, 0x66, 0x16, 0xa7, 0xc2,
+ /*91f0:*/ 0x87, 0xe8, 0x72, 0x7c, 0x99, 0xd4, 0xb1, 0x43, 0xa8, 0x06, 0x32, 0x32, 0x1e, 0xb2, 0x6e, 0x2f,
+ /*9200:*/ 0xd0, 0xca, 0xe7, 0x10, 0xd5, 0xc2, 0xe5, 0x6b, 0x91, 0xac, 0xb4, 0x79, 0x6f, 0x23, 0xcc, 0xfc,
+ /*9210:*/ 0x09, 0xe4, 0x62, 0x5e, 0xb6, 0x58, 0xd1, 0x53, 0xd4, 0x10, 0x0b, 0x01, 0xf5, 0x26, 0x5f, 0x5a,
+ /*9220:*/ 0xcf, 0xf6, 0x44, 0x93, 0xad, 0xed, 0x64, 0xd2, 0xfd, 0x2c, 0x6a, 0xfe, 0x3c, 0x37, 0x44, 0xf0,
+ /*9230:*/ 0x0d, 0x21, 0xd3, 0x7b, 0x8d, 0x8a, 0xfe, 0x0c, 0xf9, 0x5a, 0x0a, 0x86, 0xed, 0xfb, 0x5b, 0x6b,
+ /*9240:*/ 0xbe, 0x39, 0xb9, 0x85, 0xf8, 0x76, 0xde, 0x5f, 0xd8, 0x6e, 0x95, 0xb6, 0xd5, 0x4b, 0x40, 0x32,
+ /*9250:*/ 0x4a, 0xf1, 0x1c, 0xa8, 0x48, 0xe2, 0xf3, 0x10, 0xa6, 0x51, 0xee, 0x2a, 0xbb, 0x65, 0xaa, 0xe6,
+ /*9260:*/ 0x4b, 0x9c, 0x5f, 0x30, 0xcc, 0xbe, 0xae, 0xe3, 0x0f, 0xbe, 0x34, 0x44, 0xf5, 0x3c, 0xb2, 0x6d,
+ /*9270:*/ 0xd5, 0x2f, 0x3b, 0x59, 0xc8, 0x7f, 0x48, 0xfa, 0x53, 0x6f, 0x85, 0x7b, 0xaa, 0x6d, 0xf5, 0x2c,
+ /*9280:*/ 0x0f, 0x23, 0x8a, 0x25, 0xee, 0x4f, 0x08, 0x00, 0xc9, 0x1d, 0x53, 0xdb, 0xad, 0x37, 0x35, 0x41,
+ /*9290:*/ 0x6c, 0x9f, 0xe2, 0x79, 0x6a, 0x21, 0x04, 0x05, 0xe6, 0x6f, 0x74, 0x9e, 0x9a, 0x1c, 0x33, 0xd6,
+ /*92a0:*/ 0x44, 0x5c, 0x09, 0x40, 0xcb, 0x0e, 0xe4, 0x27, 0xa3, 0xf8, 0xf7, 0xd4, 0xed, 0x09, 0x33, 0x71,
+ /*92b0:*/ 0x5d, 0x5c, 0x95, 0x25, 0x67, 0x0a, 0x5c, 0x2e, 0xb6, 0xe7, 0xb0, 0x10, 0x9c, 0x19, 0xb4, 0x39,
+ /*92c0:*/ 0x99, 0x11, 0xbd, 0x82, 0x87, 0x28, 0x6d, 0x75, 0x9d, 0x4e, 0x66, 0xbb, 0x1f, 0x01, 0x6b, 0x33,
+ /*92d0:*/ 0xf5, 0x01, 0x20, 0x9f, 0x69, 0x09, 0x99, 0x29, 0xda, 0x12, 0x5a, 0xa5, 0x47, 0xe2, 0x4d, 0x3c,
+ /*92e0:*/ 0x39, 0x54, 0x5e, 0x69, 0xa4, 0x54, 0x14, 0x1f, 0x3f, 0x75, 0xfc, 0x25, 0xa3, 0x3d, 0xc1, 0x65,
+ /*92f0:*/ 0xc6, 0xd0, 0xdb, 0x44, 0xbe, 0xe9, 0x6d, 0x3d, 0x00, 0x81, 0x3b, 0xed, 0xb5, 0xfd, 0xa6, 0x19,
+ /*9300:*/ 0x63, 0xa2, 0xf0, 0xd8, 0x86, 0xeb, 0x86, 0x20, 0xe2, 0xaa, 0x98, 0xf9, 0x21, 0x51, 0x40, 0x63,
+ /*9310:*/ 0x84, 0x80, 0x6d, 0x18, 0x84, 0x3c, 0x91, 0x6a, 0x93, 0x85, 0x25, 0x5b, 0x5a, 0x12, 0x61, 0xf3,
+ /*9320:*/ 0x20, 0x02, 0x6e, 0x52, 0x08, 0xcf, 0x9a, 0xda, 0xd0, 0xbc, 0xd5, 0x70, 0xca, 0x73, 0x28, 0xcb,
+ /*9330:*/ 0x6c, 0x97, 0xc1, 0xb0, 0x0e, 0xb7, 0xa2, 0xd7, 0xb8, 0xb2, 0xe3, 0x98, 0xf7, 0x9e, 0x60, 0xc6,
+ /*9340:*/ 0x54, 0x2d, 0x04, 0x98, 0x6f, 0x29, 0xbe, 0xdc, 0x67, 0xad, 0xfd, 0x2d, 0xf5, 0x0e, 0x11, 0xfb,
+ /*9350:*/ 0x00, 0xac, 0xef, 0x9d, 0x6c, 0x12, 0x26, 0xf4, 0xf0, 0xaf, 0x05, 0xe4, 0xbf, 0x07, 0x50, 0x17,
+ /*9360:*/ 0x9e, 0xf9, 0xfe, 0x37, 0x35, 0xa2, 0xb5, 0xff, 0x98, 0xd7, 0x05, 0xa2, 0xb2, 0xa7, 0x5c, 0x2a,
+ /*9370:*/ 0x3f, 0x67, 0x01, 0x06, 0xa9, 0x3e, 0xdc, 0x76, 0x97, 0xfb, 0x36, 0x72, 0x30, 0xb7, 0xe4, 0x30,
+ /*9380:*/ 0x51, 0xe3, 0xe7, 0xeb, 0xcc, 0xd3, 0x3d, 0x6f, 0x9e, 0x7e, 0x00, 0xc6, 0x7c, 0x14, 0xb0, 0xae,
+ /*9390:*/ 0x79, 0x1c, 0x0b, 0x55, 0xcc, 0x61, 0xaf, 0xfc, 0x96, 0xcf, 0xcc, 0xe1, 0x99, 0x4b, 0x85, 0xe7,
+ /*93a0:*/ 0xa8, 0x9b, 0x40, 0xa9, 0xf8, 0xe8, 0x68, 0xe7, 0x9d, 0xde, 0xf4, 0xdc, 0x93, 0x57, 0x0a, 0x54,
+ /*93b0:*/ 0x5e, 0x4a, 0x1c, 0xd7, 0x2f, 0xc4, 0x5d, 0x37, 0x98, 0xbc, 0x63, 0xf6, 0x5c, 0x9a, 0xc0, 0xf4,
+ /*93c0:*/ 0x5e, 0x07, 0xc5, 0xab, 0xe5, 0x51, 0xf1, 0xe9, 0x8d, 0xcd, 0x48, 0x54, 0xce, 0x87, 0x69, 0x51,
+ /*93d0:*/ 0x10, 0xb9, 0xe6, 0x47, 0x8c, 0x2f, 0x2f, 0xe1, 0x9b, 0xcd, 0x05, 0x55, 0x9c, 0xa7, 0x0f, 0x18,
+ /*93e0:*/ 0x76, 0xee, 0xc3, 0x7e, 0xfa, 0x69, 0xa3, 0x7f, 0xc2, 0xa9, 0xff, 0xaa, 0x7a, 0x2d, 0x13, 0xd1,
+ /*93f0:*/ 0xde, 0x8b, 0x1c, 0xd8, 0xe6, 0x6f, 0x12, 0xfc, 0x4c, 0xec, 0x79, 0x02, 0x17, 0x6f, 0xc3, 0xd1,
+ /*9400:*/ 0xb5, 0x6e, 0xff, 0x06, 0xf1, 0x06, 0xd6, 0xbe, 0xbf, 0x02, 0x04, 0x72, 0x48, 0xed, 0x80, 0x58,
+ /*9410:*/ 0xf0, 0x5f, 0x31, 0xcf, 0x4d, 0xec, 0xe0, 0x1b, 0x6d, 0x33, 0x69, 0xfd, 0x2f, 0x62, 0xb8, 0x93,
+ /*9420:*/ 0xac, 0x31, 0x56, 0x8e, 0x61, 0xde, 0x88, 0xea, 0x3f, 0xc4, 0x6b, 0xff, 0xcc, 0x6f, 0x10, 0x26,
+ /*9430:*/ 0x85, 0x04, 0x98, 0xe4, 0x3a, 0xda, 0x18, 0xa2, 0x99, 0x59, 0x73, 0x58, 0x91, 0x7c, 0x22, 0x7e,
+ /*9440:*/ 0x16, 0xd4, 0xd3, 0x20, 0x4c, 0x82, 0x21, 0x81, 0x43, 0x83, 0x36, 0x73, 0x04, 0x0e, 0x07, 0x79,
+ /*9450:*/ 0x81, 0xd7, 0x8e, 0x44, 0x50, 0x9f, 0x33, 0x68, 0x0c, 0x67, 0x18, 0xd3, 0xba, 0xbe, 0xc9, 0xb7,
+ /*9460:*/ 0xed, 0x8f, 0xb0, 0xdc, 0xc6, 0xab, 0x17, 0x84, 0xa0, 0x79, 0x78, 0xf9, 0x87, 0x8a, 0x21, 0xdf,
+ /*9470:*/ 0xe7, 0x4d, 0xfa, 0x3b, 0xd8, 0xf4, 0x00, 0x85, 0x00, 0x0d, 0x8e, 0x68, 0x7a, 0x5a, 0x1a, 0x6a,
+ /*9480:*/ 0x3a, 0x6d, 0x36, 0x12, 0xf4, 0xd4, 0x09, 0xf9, 0xc5, 0x50, 0x1c, 0xe6, 0xe0, 0x58, 0x25, 0xfa,
+ /*9490:*/ 0xbc, 0xea, 0xfe, 0x6e, 0x1f, 0x1a, 0x16, 0x8f, 0x2f, 0x0f, 0xb2, 0xf3, 0x85, 0xe0, 0x11, 0x9e,
+ /*94a0:*/ 0x90, 0xf1, 0xab, 0x01, 0xea, 0x9e, 0x03, 0xbe, 0xaa, 0x73, 0x8c, 0x96, 0xf2, 0x1c, 0x74, 0x46,
+ /*94b0:*/ 0xdd, 0x4c, 0xff, 0x63, 0x18, 0x4b, 0xee, 0x7d, 0xed, 0xff, 0x16, 0xc8, 0x8d, 0xac, 0x0e, 0xe1,
+ /*94c0:*/ 0x3b, 0x21, 0x1a, 0x5b, 0x69, 0x16, 0xb9, 0xb7, 0xbd, 0x97, 0x02, 0xb6, 0x29, 0xba, 0xd7, 0x0c,
+ /*94d0:*/ 0xb0, 0x33, 0xba, 0x5a, 0x0d, 0xd2, 0xe6, 0x32, 0x70, 0xd9, 0x71, 0xa3, 0x59, 0xce, 0xe0, 0xac,
+ /*94e0:*/ 0x9f, 0x3d, 0xd3, 0xba, 0x2e, 0x3d, 0x70, 0x1c, 0x19, 0x9e, 0xa5, 0x34, 0xef, 0xf7, 0x93, 0xcd,
+ /*94f0:*/ 0x6f, 0xd1, 0xfd, 0x72, 0x76, 0x3a, 0x33, 0x5c, 0x54, 0xd9, 0x85, 0xbf, 0x72, 0xfd, 0x13, 0xf0,
+ /*9500:*/ 0x5d, 0x37, 0x35, 0x42, 0x1c, 0xd2, 0x41, 0x66, 0x1d, 0xcb, 0xf9, 0x76, 0xd9, 0x26, 0x3b, 0xb7,
+ /*9510:*/ 0xe7, 0xf6, 0x32, 0xa9, 0x26, 0xba, 0x25, 0x9c, 0x35, 0xa5, 0x80, 0x11, 0x3d, 0x0d, 0x43, 0x80,
+ /*9520:*/ 0xd1, 0x90, 0xba, 0xe1, 0xc8, 0x1c, 0xe4, 0x83, 0x08, 0xaa, 0xaf, 0x66, 0x8e, 0x33, 0x9a, 0x4a,
+ /*9530:*/ 0xdd, 0x79, 0xf6, 0xa7, 0xfa, 0x15, 0x59, 0x61, 0xf6, 0x35, 0xd8, 0x0b, 0xe4, 0x86, 0xbb, 0x74,
+ /*9540:*/ 0xfa, 0x6b, 0xa5, 0x4e, 0xf8, 0x41, 0xa7, 0xb4, 0x37, 0x82, 0x8e, 0x5b, 0x1c, 0x71, 0xe2, 0xe1,
+ /*9550:*/ 0x57, 0xa8, 0xa1, 0xc3, 0x18, 0x6f, 0xcb, 0x31, 0x2e, 0x28, 0x9d, 0x09, 0x33, 0x67, 0x9b, 0xaf,
+ /*9560:*/ 0x6f, 0x07, 0x18, 0x49, 0xd1, 0x78, 0x5d, 0x87, 0xdf, 0xb7, 0x62, 0x14, 0x00, 0x7e, 0xc7, 0xe8,
+ /*9570:*/ 0x7f, 0xbc, 0x6a, 0xd4, 0x4c, 0x91, 0xc6, 0xde, 0xd3, 0x89, 0xc8, 0xbf, 0x90, 0xda, 0x84, 0x0f,
+ /*9580:*/ 0x56, 0xdd, 0x95, 0xae, 0x92, 0x78, 0xf3, 0x93, 0xf0, 0x6c, 0x9e, 0xab, 0xf5, 0xb7, 0xb5, 0x99,
+ /*9590:*/ 0xf6, 0xb3, 0x94, 0x57, 0xd1, 0x96, 0x91, 0x60, 0x31, 0x0d, 0xa9, 0xf4, 0x67, 0x62, 0xa4, 0xd5,
+ /*95a0:*/ 0xf1, 0x5e, 0x15, 0xd8, 0xba, 0x27, 0x4c, 0x2d, 0x1f, 0x92, 0x0e, 0x8a, 0x51, 0x74, 0xdd, 0x8f,
+ /*95b0:*/ 0x27, 0x89, 0x9b, 0xba, 0x1b, 0x1a, 0x01, 0x1e, 0x9a, 0xb5, 0x77, 0x72, 0x8e, 0xde, 0x73, 0xbb,
+ /*95c0:*/ 0xe9, 0x6a, 0xa1, 0xeb, 0xa2, 0xab, 0x70, 0x7a, 0x34, 0x34, 0x4f, 0x86, 0x2f, 0x26, 0x4f, 0x39,
+ /*95d0:*/ 0xab, 0x57, 0x4f, 0x76, 0xed, 0xf8, 0x30, 0xc0, 0x21, 0xb5, 0x17, 0x03, 0x8e, 0xf1, 0x4c, 0xe2,
+ /*95e0:*/ 0x50, 0x6e, 0xf8, 0x95, 0xee, 0x19, 0xc9, 0xf0, 0x7c, 0x06, 0x9e, 0x3d, 0x69, 0xdf, 0x90, 0x03,
+ /*95f0:*/ 0xae, 0xfb, 0xc4, 0x34, 0x9e, 0x0a, 0x7d, 0x2e, 0x4d, 0xc5, 0x97, 0x18, 0x01, 0xb7, 0xfb, 0xd7,
+ /*9600:*/ 0x89, 0x81, 0xd8, 0xd7, 0x2c, 0x12, 0x29, 0xd4, 0x3f, 0xa7, 0xcc, 0x67, 0x9a, 0xed, 0x17, 0xb9,
+ /*9610:*/ 0xd8, 0x74, 0x27, 0x54, 0xa0, 0x11, 0x44, 0xe0, 0x64, 0xfe, 0xa2, 0x57, 0xf5, 0x63, 0x55, 0xdd,
+ /*9620:*/ 0x7b, 0x45, 0xea, 0xc2, 0x19, 0xad, 0x3d, 0x68, 0xb7, 0x94, 0x89, 0xa6, 0x6e, 0x28, 0xd2, 0xbc,
+ /*9630:*/ 0x09, 0xe4, 0x75, 0x37, 0xd4, 0x26, 0x4e, 0xf1, 0x6c, 0x8b, 0x5d, 0x16, 0x12, 0xfc, 0x10, 0xff,
+ /*9640:*/ 0x12, 0x33, 0xdb, 0xd9, 0x7b, 0x22, 0x55, 0x7b, 0xe7, 0xc4, 0x9c, 0xd7, 0x50, 0x87, 0xc5, 0xde,
+ /*9650:*/ 0x8d, 0xe0, 0x74, 0xc7, 0x03, 0x9f, 0x64, 0x7f, 0xf4, 0xfd, 0xbd, 0xed, 0x0c, 0x14, 0x8c, 0x2a,
+ /*9660:*/ 0xf9, 0x2e, 0x06, 0x6e, 0xb7, 0x2a, 0x3e, 0x61, 0x02, 0xce, 0x84, 0xd4, 0xb6, 0x02, 0xee, 0x47,
+ /*9670:*/ 0x13, 0x01, 0x8c, 0x78, 0x6d, 0x2b, 0xea, 0xa2, 0x74, 0x3f, 0x87, 0x2d, 0x42, 0xa1, 0x7a, 0x63,
+ /*9680:*/ 0x25, 0x81, 0x88, 0x65, 0x0a, 0x42, 0x52, 0xa1, 0x8f, 0xba, 0xf5, 0x32, 0x27, 0xdd, 0x87, 0x68,
+ /*9690:*/ 0x95, 0x0e, 0x6e, 0xb3, 0x04, 0xbb, 0x40, 0x5e, 0x65, 0x0e, 0x51, 0x4c, 0x2a, 0x9c, 0x5a, 0x2e,
+ /*96a0:*/ 0xc9, 0xed, 0xc0, 0xe1, 0xb5, 0x7e, 0x69, 0xcf, 0x4e, 0x16, 0xe3, 0x11, 0x8e, 0xef, 0xb9, 0x44,
+ /*96b0:*/ 0x6b, 0x79, 0x1a, 0xf2, 0x7a, 0x58, 0xe7, 0xd3, 0xbb, 0x95, 0x9e, 0x9a, 0x63, 0xa2, 0x3c, 0x8c,
+ /*96c0:*/ 0xd3, 0x4f, 0x7e, 0x08, 0xd5, 0x48, 0x8f, 0x6f, 0x6d, 0x14, 0x44, 0x9d, 0x82, 0x1e, 0x27, 0x1c,
+ /*96d0:*/ 0xb7, 0x0d, 0xb5, 0xc8, 0x4a, 0x9e, 0x1d, 0x45, 0x6c, 0x69, 0x8d, 0x8b, 0x46, 0x21, 0x36, 0x51,
+ /*96e0:*/ 0xb8, 0x41, 0x18, 0x2f, 0x3c, 0x1f, 0xe1, 0xeb, 0x34, 0xc3, 0x09, 0xb5, 0xe8, 0xd7, 0x78, 0x60,
+ /*96f0:*/ 0xd5, 0x6f, 0xe4, 0xb1, 0x01, 0x3e, 0xac, 0xbf, 0xaa, 0xfd, 0x1a, 0x33, 0x75, 0xc7, 0x11, 0x66,
+ /*9700:*/ 0xed, 0x08, 0x5e, 0xbc, 0xa4, 0xc2, 0x12, 0x3e, 0x9f, 0xac, 0xc4, 0xee, 0xfe, 0xb2, 0xdb, 0x0f,
+ /*9710:*/ 0x0d, 0x6a, 0x03, 0x63, 0xe8, 0x9a, 0xfe, 0xde, 0xe1, 0x30, 0xba, 0x98, 0x1d, 0x33, 0x5c, 0x94,
+ /*9720:*/ 0x07, 0x88, 0x25, 0x84, 0xbe, 0x9c, 0x01, 0x21, 0xc3, 0x27, 0x98, 0xdb, 0x69, 0xb4, 0xec, 0x17,
+ /*9730:*/ 0x21, 0x15, 0x40, 0xbc, 0x54, 0xb3, 0xda, 0x62, 0x73, 0x09, 0x64, 0x6a, 0x41, 0x23, 0x8d, 0x47,
+ /*9740:*/ 0x19, 0xf7, 0x30, 0xe7, 0xb4, 0x2c, 0x60, 0xcb, 0x8c, 0xf3, 0xc4, 0xd8, 0xc5, 0x38, 0xba, 0xf7,
+ /*9750:*/ 0xf7, 0xe8, 0x1a, 0x07, 0x9c, 0xde, 0x82, 0x1c, 0x0f, 0xf9, 0x38, 0x4f, 0x32, 0xc0, 0x6c, 0x3d,
+ /*9760:*/ 0x4d, 0x90, 0x04, 0x0a, 0xe6, 0x34, 0xa9, 0x1d, 0xf6, 0x00, 0x97, 0xd8, 0x07, 0x8b, 0xfa, 0x3d,
+ /*9770:*/ 0x65, 0x0f, 0x31, 0x24, 0xd9, 0xf9, 0xdb, 0xc4, 0xbd, 0x6d, 0x14, 0xc5, 0x97, 0xdf, 0x6d, 0x22,
+ /*9780:*/ 0x82, 0x7b, 0x9d, 0x2e, 0x40, 0x53, 0x71, 0x0c, 0xde, 0x63, 0xe3, 0xf0, 0x50, 0xb9, 0x00, 0x99,
+ /*9790:*/ 0x76, 0x75, 0x3c, 0x90, 0x2d, 0x17, 0xb9, 0xed, 0x04, 0xcf, 0x14, 0x78, 0x8b, 0xe2, 0xcc, 0x7f,
+ /*97a0:*/ 0xa9, 0x49, 0xb0, 0x5d, 0x04, 0x64, 0xe4, 0x72, 0x55, 0x39, 0x1a, 0x9e, 0x88, 0xd4, 0x23, 0x9c,
+ /*97b0:*/ 0x04, 0xbf, 0xe0, 0x9b, 0xdf, 0xeb, 0x68, 0x6c, 0xc7, 0x04, 0xef, 0x6c, 0xb7, 0x6f, 0xd6, 0xff,
+ /*97c0:*/ 0xfe, 0x63, 0xeb, 0x9c, 0xc9, 0x7b, 0xfe, 0x30, 0x15, 0xce, 0x6c, 0xd2, 0x6f, 0xcc, 0x64, 0x5c,
+ /*97d0:*/ 0x76, 0x65, 0x45, 0xa6, 0x17, 0x85, 0x6c, 0xc5, 0x27, 0x2f, 0xd7, 0x16, 0x9e, 0xb7, 0x56, 0xb2,
+ /*97e0:*/ 0xb0, 0x72, 0x83, 0x5e, 0xde, 0xba, 0x80, 0xf1, 0x06, 0xe3, 0xaf, 0xcb, 0xad, 0xd8, 0x6b, 0xdd,
+ /*97f0:*/ 0x4a, 0xa9, 0xb6, 0x19, 0x48, 0x10, 0x50, 0xb7, 0xeb, 0x0a, 0x85, 0xa8, 0x9e, 0xbd, 0x10, 0x63,
+ /*9800:*/ 0x6c, 0x14, 0x33, 0x0a, 0x90, 0x63, 0x1f, 0xda, 0x0b, 0x1d, 0x19, 0xee, 0xf6, 0x20, 0xc5, 0x0c,
+ /*9810:*/ 0x79, 0x2d, 0x38, 0xbb, 0xdc, 0x38, 0x86, 0x4e, 0xce, 0x64, 0x1e, 0xfb, 0xfd, 0xbf, 0x8e, 0xa6,
+ /*9820:*/ 0x16, 0xec, 0xd9, 0x7b, 0x69, 0xb9, 0xc3, 0x96, 0x4a, 0x86, 0x43, 0x02, 0xf6, 0x74, 0xb5, 0x5f,
+ /*9830:*/ 0xb8, 0x39, 0xb1, 0x83, 0x40, 0x45, 0x72, 0xd8, 0xe9, 0x64, 0x81, 0x6a, 0xeb, 0x19, 0xbb, 0x42,
+ /*9840:*/ 0x61, 0xba, 0x45, 0x42, 0x47, 0x81, 0xe9, 0x19, 0x34, 0xdd, 0x80, 0x3e, 0xb9, 0x2c, 0x00, 0xad,
+ /*9850:*/ 0x0e, 0x3c, 0x71, 0x0b, 0xea, 0x1f, 0xf8, 0xa5, 0x38, 0x68, 0x66, 0x01, 0xa0, 0x70, 0xf4, 0x41,
+ /*9860:*/ 0x96, 0xa7, 0xb1, 0xae, 0x3c, 0xd9, 0xfd, 0x10, 0xb8, 0x4a, 0x70, 0x7b, 0x94, 0x00, 0xe8, 0xb6,
+ /*9870:*/ 0xa5, 0x24, 0xac, 0xa3, 0x5a, 0xd8, 0x6f, 0xa5, 0x48, 0x26, 0xd8, 0x7b, 0x4c, 0x5c, 0x30, 0x8b,
+ /*9880:*/ 0x6b, 0x55, 0x8a, 0x7b, 0x1b, 0xc8, 0xce, 0x9b, 0x7a, 0xc1, 0x36, 0xe7, 0x9a, 0x58, 0xe8, 0xc7,
+ /*9890:*/ 0x14, 0x8b, 0x01, 0x5f, 0x13, 0x04, 0x4c, 0x10, 0x43, 0x44, 0x33, 0x44, 0xe2, 0x60, 0xb6, 0x47,
+ /*98a0:*/ 0xca, 0x0a, 0x2e, 0x90, 0xa7, 0x49, 0xfc, 0x06, 0x3d, 0xf2, 0x4f, 0xd2, 0x69, 0x69, 0x6c, 0x0b,
+ /*98b0:*/ 0xe4, 0x37, 0x2a, 0x60, 0x8a, 0x8c, 0x0f, 0x33, 0xa9, 0xb1, 0xb3, 0xc8, 0xe6, 0x82, 0xa8, 0xaf,
+ /*98c0:*/ 0x56, 0x17, 0xc7, 0x77, 0xf6, 0xc9, 0xb2, 0x27, 0x79, 0x7e, 0xec, 0x3c, 0xba, 0xc4, 0x3b, 0x0f,
+ /*98d0:*/ 0x4f, 0xf4, 0x22, 0x13, 0x4c, 0x20, 0xda, 0xfb, 0xaf, 0x56, 0xae, 0x51, 0x27, 0x54, 0x15, 0x80,
+ /*98e0:*/ 0x85, 0x94, 0xb7, 0x97, 0x82, 0x8b, 0xef, 0xcf, 0x4a, 0xbf, 0xb8, 0x18, 0x2c, 0x37, 0x59, 0x8d,
+ /*98f0:*/ 0x32, 0xed, 0x94, 0x78, 0x56, 0x01, 0x05, 0xc0, 0xfe, 0x6f, 0x8c, 0x60, 0x7e, 0x77, 0xee, 0xc0,
+ /*9900:*/ 0xa8, 0x3f, 0x8d, 0xb9, 0x7d, 0x19, 0x8e, 0x95, 0xf8, 0xbe, 0xc5, 0xe8, 0x57, 0xbd, 0x3c, 0xfc,
+ /*9910:*/ 0x9b, 0xfd, 0x72, 0x44, 0xf4, 0x42, 0x2d, 0xcb, 0x8c, 0x81, 0x8c, 0x3b, 0x0c, 0xfe, 0x05, 0x42,
+ /*9920:*/ 0x55, 0xeb, 0xb9, 0x30, 0x27, 0xc5, 0x4c, 0x1b, 0x79, 0xd5, 0x9e, 0x2e, 0x50, 0x25, 0x08, 0x62,
+ /*9930:*/ 0xcc, 0x75, 0x72, 0x33, 0x26, 0xc3, 0xcd, 0x86, 0xb0, 0xe4, 0xee, 0xea, 0xd6, 0x2d, 0x57, 0xd3,
+ /*9940:*/ 0x80, 0x9c, 0xef, 0x9d, 0x78, 0x6d, 0x96, 0x28, 0xac, 0xed, 0x27, 0xea, 0x62, 0xbd, 0x8d, 0x9e,
+ /*9950:*/ 0x20, 0x2b, 0xc4, 0xe4, 0x3d, 0x61, 0x68, 0xff, 0x5c, 0x5d, 0x47, 0x44, 0x40, 0x4c, 0x9a, 0x47,
+ /*9960:*/ 0xa0, 0x24, 0x16, 0x1e, 0x88, 0xd5, 0x86, 0x29, 0x96, 0x0c, 0x4f, 0x13, 0x1f, 0x2c, 0x03, 0x98,
+ /*9970:*/ 0x56, 0xd9, 0x46, 0xe5, 0x18, 0x83, 0xed, 0x85, 0xd9, 0x8a, 0x8a, 0x88, 0xe6, 0x19, 0xf2, 0x7b,
+ /*9980:*/ 0xe4, 0x68, 0x3d, 0xfc, 0xbd, 0x71, 0x27, 0x22, 0xf4, 0x60, 0x51, 0x30, 0x52, 0x99, 0x43, 0x88,
+ /*9990:*/ 0x42, 0xa4, 0xe8, 0x16, 0xf2, 0x17, 0x3a, 0xd7, 0x2b, 0x85, 0x49, 0x53, 0x50, 0x14, 0x51, 0xd3,
+ /*99a0:*/ 0x4c, 0x85, 0xcc, 0x80, 0x1e, 0x49, 0x18, 0xb8, 0x3c, 0x3e, 0x1c, 0xbe, 0x56, 0x07, 0xf7, 0xc7,
+ /*99b0:*/ 0x9f, 0xda, 0xce, 0x00, 0x93, 0xe6, 0xa1, 0xda, 0xf1, 0x45, 0x7b, 0x3f, 0x26, 0x9c, 0xb6, 0xe8,
+ /*99c0:*/ 0xfb, 0xce, 0x3b, 0x85, 0x64, 0xf5, 0x85, 0x9c, 0x34, 0x4f, 0x89, 0x44, 0x52, 0x69, 0x99, 0xc9,
+ /*99d0:*/ 0x5d, 0x87, 0x52, 0x2c, 0xd3, 0x3a, 0x6e, 0x5c, 0x02, 0x41, 0x5c, 0x03, 0xa8, 0xfb, 0xcd, 0x82,
+ /*99e0:*/ 0xe6, 0xd7, 0xe2, 0x90, 0x06, 0x9e, 0x4f, 0xbc, 0x53, 0x79, 0x24, 0xd9, 0x20, 0xb6, 0x5f, 0xa6,
+ /*99f0:*/ 0x0d, 0x88, 0x85, 0xbe, 0x19, 0xe4, 0x1f, 0x95, 0xf8, 0x94, 0x6e, 0x01, 0x9d, 0xc0, 0xef, 0x18,
+ /*9a00:*/ 0xaf, 0xda, 0xac, 0x64, 0x8c, 0x7a, 0x84, 0x6d, 0x45, 0xa4, 0x34, 0x66, 0x9b, 0x81, 0xab, 0x69,
+ /*9a10:*/ 0x19, 0x49, 0x6c, 0xa8, 0xc6, 0x8b, 0x3b, 0xbd, 0xff, 0x27, 0x23, 0x48, 0xa6, 0x6b, 0xa9, 0x30,
+ /*9a20:*/ 0xf0, 0xbb, 0xe4, 0x08, 0x3d, 0x52, 0x21, 0x70, 0xbc, 0x42, 0x45, 0x92, 0xf7, 0x0c, 0x83, 0x33,
+ /*9a30:*/ 0x9f, 0x38, 0x28, 0x1b, 0xb3, 0xf2, 0xc4, 0x38, 0x24, 0x03, 0xfd, 0xa9, 0x18, 0x60, 0x54, 0xcc,
+ /*9a40:*/ 0xc1, 0xb0, 0x78, 0x8e, 0x99, 0x64, 0x9c, 0xeb, 0x02, 0xbc, 0x63, 0x7b, 0xd6, 0x03, 0x6d, 0xcb,
+ /*9a50:*/ 0x1f, 0x6f, 0x34, 0x59, 0xe6, 0x7e, 0xb0, 0x10, 0xbb, 0x5d, 0xe6, 0xfa, 0x66, 0xbe, 0x14, 0x10,
+ /*9a60:*/ 0xca, 0xd1, 0x3f, 0x99, 0x4c, 0x04, 0xfb, 0x56, 0x64, 0xec, 0x2e, 0x07, 0x61, 0x05, 0x9c, 0x8c,
+ /*9a70:*/ 0x1a, 0xc4, 0x34, 0x1d, 0xbf, 0x33, 0x69, 0x38, 0x9f, 0xa4, 0x9e, 0xbd, 0xc6, 0x4d, 0x49, 0xe4,
+ /*9a80:*/ 0xf3, 0xc5, 0x38, 0xb4, 0xb7, 0xa3, 0x0a, 0x49, 0x67, 0x9e, 0x79, 0xf0, 0xa7, 0x4c, 0x91, 0xf7,
+ /*9a90:*/ 0x42, 0x88, 0xc1, 0x4f, 0x01, 0xa0, 0x43, 0x6e, 0x39, 0xbd, 0x96, 0x07, 0x3e, 0xab, 0x70, 0x56,
+ /*9aa0:*/ 0x54, 0xe1, 0xc9, 0xa2, 0x9a, 0x98, 0xb9, 0xd6, 0x3c, 0x17, 0xa9, 0xbe, 0xc5, 0xe2, 0x36, 0x18,
+ /*9ab0:*/ 0xf4, 0x15, 0x9d, 0x0b, 0xa2, 0x66, 0x87, 0x79, 0x45, 0x6d, 0x24, 0x09, 0xa0, 0xcd, 0x87, 0xdc,
+ /*9ac0:*/ 0x3d, 0x69, 0x16, 0x6b, 0xef, 0xf4, 0x3b, 0x04, 0x34, 0x84, 0xf1, 0x19, 0x8c, 0x73, 0x90, 0xf0,
+ /*9ad0:*/ 0xde, 0xfb, 0xcf, 0x48, 0x44, 0x41, 0xf9, 0x81, 0xb3, 0xa7, 0x0a, 0xc2, 0xd4, 0x8c, 0x84, 0x9a,
+ /*9ae0:*/ 0x6a, 0x1c, 0x34, 0x63, 0x96, 0x0a, 0xe0, 0xc6, 0x10, 0x88, 0x8f, 0x8e, 0xac, 0x96, 0xee, 0xc0,
+ /*9af0:*/ 0x86, 0x16, 0x61, 0x8f, 0x35, 0xec, 0x47, 0x4e, 0x75, 0x17, 0x49, 0x0e, 0x3f, 0x34, 0x68, 0x7e,
+ /*9b00:*/ 0xae, 0x61, 0x0e, 0x7e, 0xd2, 0x81, 0x53, 0xd1, 0x53, 0x7a, 0x20, 0x7a, 0x40, 0x7a, 0x2e, 0xbc,
+ /*9b10:*/ 0x43, 0x3a, 0x66, 0x39, 0x0f, 0xc1, 0x85, 0xc0, 0x71, 0xe0, 0x15, 0x28, 0x47, 0xb5, 0xd1, 0x99,
+ /*9b20:*/ 0x6e, 0xd3, 0x48, 0xe0, 0x41, 0xa7, 0xf3, 0x27, 0x8f, 0xda, 0x55, 0x5f, 0x89, 0x0f, 0x9b, 0x91,
+ /*9b30:*/ 0xe9, 0x1f, 0x9b, 0x5e, 0x32, 0x53, 0x3e, 0x8c, 0x65, 0xd5, 0x92, 0x0b, 0x8c, 0x5f, 0x73, 0xcc,
+ /*9b40:*/ 0x0d, 0xc5, 0xa7, 0x1c, 0x80, 0x85, 0xca, 0xbc, 0x00, 0xf6, 0x73, 0x07, 0x9b, 0xb4, 0x93, 0x48,
+ /*9b50:*/ 0x22, 0xe3, 0xf9, 0x63, 0x9d, 0xe5, 0x82, 0x17, 0x3e, 0x65, 0x2b, 0x4f, 0x68, 0xc3, 0xc3, 0x6d,
+ /*9b60:*/ 0x8d, 0x9a, 0x5e, 0x47, 0xe6, 0x1f, 0x99, 0x94, 0xab, 0xd6, 0xc2, 0xeb, 0x05, 0x70, 0x23, 0x7a,
+ /*9b70:*/ 0x6b, 0xbd, 0xc0, 0x1d, 0xe2, 0x22, 0xa9, 0xb5, 0x56, 0xcb, 0x93, 0x2c, 0x88, 0xed, 0xd9, 0xbf,
+ /*9b80:*/ 0x14, 0x44, 0xb3, 0x99, 0xe2, 0x58, 0x2d, 0x78, 0x53, 0xc3, 0xbf, 0x94, 0xd0, 0x57, 0x95, 0xec,
+ /*9b90:*/ 0x25, 0xe2, 0x51, 0xb4, 0x6f, 0x2d, 0xf9, 0xb4, 0x15, 0x32, 0xa4, 0x20, 0xf8, 0x7e, 0x47, 0x65,
+ /*9ba0:*/ 0xc8, 0xb2, 0x95, 0xad, 0x41, 0xd5, 0x91, 0xbb, 0xd7, 0x66, 0x2c, 0x96, 0x7d, 0x78, 0x85, 0x3c,
+ /*9bb0:*/ 0x72, 0x21, 0x9d, 0xe4, 0x4a, 0x4a, 0x4f, 0x29, 0x76, 0x24, 0x82, 0x83, 0xb8, 0x19, 0x1b, 0x5a,
+ /*9bc0:*/ 0x1f, 0x13, 0x76, 0xc2, 0xe3, 0x69, 0x75, 0xea, 0x4a, 0xb0, 0xbd, 0x34, 0x87, 0x0c, 0xe3, 0xda,
+ /*9bd0:*/ 0x14, 0xce, 0x42, 0x65, 0x42, 0xed, 0x9a, 0x7f, 0x69, 0x83, 0x55, 0xa4, 0xbf, 0xd5, 0x91, 0xa9,
+ /*9be0:*/ 0x00, 0x57, 0xa1, 0x24, 0x8d, 0xd8, 0x01, 0xf7, 0x5a, 0x76, 0xf8, 0x15, 0x14, 0x80, 0xd0, 0x8e,
+ /*9bf0:*/ 0x26, 0xbb, 0x5c, 0x5b, 0x6b, 0x62, 0x5c, 0xa4, 0x75, 0xe2, 0x01, 0xd1, 0x46, 0x9b, 0x7f, 0x7f,
+ /*9c00:*/ 0x16, 0xd1, 0xa0, 0xfa, 0x4f, 0x8e, 0x3d, 0xe4, 0xe0, 0xab, 0xc4, 0x25, 0x7f, 0x3a, 0x1b, 0x17,
+ /*9c10:*/ 0x3a, 0x99, 0xff, 0xa6, 0x54, 0xce, 0x8d, 0x7c, 0xa6, 0x4a, 0xce, 0x6f, 0x98, 0xe3, 0x1d, 0x84,
+ /*9c20:*/ 0x8b, 0x74, 0xf7, 0x01, 0x99, 0x05, 0x21, 0xce, 0x4d, 0x0f, 0x4c, 0x91, 0x40, 0x24, 0xf4, 0x78,
+ /*9c30:*/ 0xec, 0x90, 0xc9, 0xca, 0xc2, 0x63, 0x97, 0x84, 0x56, 0x21, 0x88, 0x57, 0xc2, 0xc0, 0x9d, 0xbd,
+ /*9c40:*/ 0x78, 0xc8, 0x69, 0x9a, 0x00, 0xd0, 0xaa, 0x65, 0x9a, 0x74, 0x06, 0xf1, 0x66, 0x15, 0xcc, 0xf2,
+ /*9c50:*/ 0x2a, 0x6a, 0xc1, 0xf3, 0x02, 0x6e, 0x08, 0xc4, 0xea, 0x54, 0x55, 0x05, 0x86, 0xeb, 0x19, 0x4a,
+ /*9c60:*/ 0xa3, 0xee, 0xa7, 0x1a, 0x3c, 0x93, 0x34, 0x07, 0x91, 0x72, 0x36, 0xbd, 0xb7, 0x54, 0xc5, 0x05,
+ /*9c70:*/ 0xdb, 0xe3, 0xe6, 0x5d, 0x48, 0x58, 0x16, 0x23, 0xed, 0x21, 0x9e, 0xe6, 0xed, 0xb4, 0x8f, 0x75,
+ /*9c80:*/ 0x8d, 0x5b, 0x9a, 0x16, 0x65, 0x9e, 0x5f, 0xb9, 0xff, 0xc9, 0xcd, 0xd0, 0xa8, 0xd3, 0x36, 0x3e,
+ /*9c90:*/ 0x36, 0x67, 0x30, 0xf5, 0xd8, 0xbe, 0x1c, 0xe3, 0x30, 0x9e, 0x0c, 0x1b, 0x06, 0x6d, 0x34, 0x07,
+ /*9ca0:*/ 0x73, 0x56, 0x08, 0xff, 0xaa, 0x12, 0x5b, 0x46, 0x54, 0x57, 0xb5, 0x3d, 0x56, 0x95, 0x09, 0x9f,
+ /*9cb0:*/ 0x40, 0x99, 0x96, 0x83, 0x58, 0xbb, 0xcc, 0x88, 0x1a, 0x62, 0xbd, 0xb7, 0xaa, 0x27, 0x9a, 0xf7,
+ /*9cc0:*/ 0xd1, 0x23, 0x3c, 0xa7, 0x5f, 0x82, 0x20, 0x91, 0x0c, 0xa5, 0x4c, 0xda, 0x74, 0xf8, 0x0e, 0x59,
+ /*9cd0:*/ 0x68, 0x13, 0xd6, 0x07, 0xe2, 0x4e, 0x57, 0x5c, 0xd3, 0xb5, 0xb9, 0x11, 0xaa, 0x45, 0x74, 0xf2,
+ /*9ce0:*/ 0xf4, 0x37, 0x37, 0xff, 0x45, 0x6c, 0x51, 0x1d, 0xfe, 0xf0, 0x12, 0x40, 0x57, 0x6f, 0x41, 0x93,
+ /*9cf0:*/ 0xb0, 0x7c, 0xd3, 0x5d, 0xe4, 0x10, 0x0c, 0xe2, 0xfa, 0x90, 0xa9, 0x68, 0xf9, 0x41, 0xd4, 0x71,
+ /*9d00:*/ 0x2e, 0x46, 0xfb, 0x78, 0xca, 0xa6, 0x44, 0xec, 0xbf, 0xfb, 0x33, 0xea, 0xcd, 0x46, 0x64, 0xf0,
+ /*9d10:*/ 0x1e, 0x5a, 0x3a, 0x3a, 0xbe, 0x7f, 0x83, 0x94, 0xb2, 0x11, 0xb1, 0x32, 0x14, 0x05, 0xc0, 0xa0,
+ /*9d20:*/ 0x87, 0x7f, 0xb7, 0xf2, 0xe9, 0x08, 0xcb, 0x1f, 0x5d, 0x87, 0x30, 0xec, 0x05, 0xcf, 0xaa, 0x01,
+ /*9d30:*/ 0x2f, 0x23, 0x0d, 0x81, 0xde, 0x30, 0x8e, 0x03, 0x0e, 0x44, 0x6e, 0x62, 0xb9, 0x6e, 0x7c, 0x0e,
+ /*9d40:*/ 0x0a, 0x00, 0x63, 0xea, 0xb9, 0xbd, 0x9b, 0x8e, 0x1a, 0x3c, 0xb4, 0xff, 0xae, 0xd4, 0x15, 0x18,
+ /*9d50:*/ 0xe6, 0x0f, 0xfe, 0x28, 0x6e, 0xdc, 0x76, 0x2a, 0xf5, 0xd4, 0x14, 0xd8, 0x8c, 0x76, 0x35, 0xa8,
+ /*9d60:*/ 0x85, 0x38, 0x55, 0xfe, 0xc3, 0x83, 0xd5, 0xaa, 0x58, 0x92, 0xb8, 0x82, 0x45, 0x9c, 0xe5, 0x92,
+ /*9d70:*/ 0xd4, 0x11, 0xc9, 0xf9, 0xab, 0x5b, 0x9c, 0x77, 0xb3, 0xbe, 0x3f, 0x65, 0x89, 0xbd, 0x1d, 0xdf,
+ /*9d80:*/ 0x89, 0x64, 0xe3, 0x0b, 0xf4, 0xc8, 0xf2, 0xe1, 0x23, 0xbf, 0x13, 0x81, 0x33, 0x92, 0x94, 0x75,
+ /*9d90:*/ 0x1b, 0xd1, 0xfc, 0x34, 0xee, 0x54, 0xdc, 0x3c, 0x40, 0xf4, 0x5d, 0xdd, 0x64, 0xd5, 0xb0, 0xdf,
+ /*9da0:*/ 0x6a, 0xb6, 0x3b, 0x92, 0x71, 0x06, 0x33, 0xf7, 0xba, 0x9b, 0x4a, 0x79, 0x91, 0x31, 0x17, 0x86,
+ /*9db0:*/ 0x35, 0x37, 0x8f, 0x62, 0x57, 0x43, 0xe7, 0x72, 0x32, 0x56, 0x91, 0x41, 0xd5, 0xc9, 0x27, 0x54,
+ /*9dc0:*/ 0x7e, 0x61, 0x7b, 0x36, 0x15, 0x2d, 0xbd, 0x4d, 0x9f, 0x51, 0xfd, 0x85, 0x8d, 0x00, 0x91, 0xe3,
+ /*9dd0:*/ 0x64, 0xb1, 0x8b, 0x51, 0xbe, 0x0e, 0x5d, 0xdb, 0x41, 0x79, 0xec, 0x11, 0x95, 0xa7, 0xfa, 0x4b,
+ /*9de0:*/ 0xd3, 0x55, 0x98, 0xb2, 0xd2, 0x51, 0xfe, 0x51, 0x35, 0x9c, 0x22, 0x3e, 0x25, 0x91, 0x42, 0xc3,
+ /*9df0:*/ 0xb0, 0x75, 0x05, 0xeb, 0xf2, 0xcb, 0x7d, 0xaa, 0xb6, 0x4b, 0x82, 0x12, 0xc2, 0x88, 0xf9, 0x78,
+ /*9e00:*/ 0xf6, 0x01, 0x30, 0x50, 0x38, 0x6a, 0xcb, 0xb1, 0xf1, 0x27, 0xcb, 0xf7, 0xd3, 0xe1, 0x43, 0xf3,
+ /*9e10:*/ 0x9e, 0x8c, 0x92, 0xab, 0xcd, 0xa7, 0x03, 0xc3, 0xd0, 0x9c, 0x91, 0x8b, 0x2d, 0xde, 0xbc, 0x50,
+ /*9e20:*/ 0x63, 0x95, 0x4b, 0x7e, 0xda, 0xf4, 0x72, 0xe3, 0xcc, 0x2c, 0x35, 0x5d, 0x2c, 0xd0, 0x4b, 0x54,
+ /*9e30:*/ 0xaf, 0xf4, 0x42, 0x0e, 0xd4, 0x8a, 0x66, 0x56, 0x83, 0xd9, 0x5e, 0x1d, 0x81, 0xd3, 0xce, 0xad,
+ /*9e40:*/ 0x61, 0xca, 0x20, 0xe6, 0xc3, 0x17, 0xef, 0x4b, 0xbe, 0xf0, 0xbc, 0xda, 0xb3, 0x79, 0xb5, 0xcb,
+ /*9e50:*/ 0x38, 0x67, 0x2a, 0x17, 0x4f, 0xda, 0xfc, 0x1a, 0x87, 0x8d, 0xc3, 0x73, 0x87, 0x65, 0xf6, 0x03,
+ /*9e60:*/ 0xc9, 0xf0, 0xab, 0x2c, 0x6f, 0xae, 0x90, 0x15, 0x10, 0xf1, 0x8d, 0x90, 0x05, 0x1a, 0x27, 0x72,
+ /*9e70:*/ 0x2d, 0x2d, 0xfb, 0x1b, 0xec, 0x9a, 0x90, 0x21, 0x08, 0xb6, 0x58, 0x57, 0xb3, 0x3d, 0xb1, 0x29,
+ /*9e80:*/ 0x00, 0x62, 0x95, 0x68, 0x6b, 0x5b, 0xfb, 0x98, 0x6e, 0xbb, 0x9c, 0x53, 0x03, 0xd3, 0xda, 0x91,
+ /*9e90:*/ 0xac, 0xec, 0x1c, 0x4e, 0x56, 0xbb, 0x50, 0xe3, 0x23, 0xc0, 0x01, 0x63, 0x45, 0x01, 0xff, 0x30,
+ /*9ea0:*/ 0x6e, 0x6f, 0xe9, 0x60, 0xed, 0xab, 0x89, 0x5c, 0xcf, 0x0a, 0x89, 0x13, 0x39, 0x2a, 0xa6, 0x93,
+ /*9eb0:*/ 0x18, 0xc8, 0x26, 0xd3, 0x23, 0x8c, 0x22, 0xa4, 0x3c, 0xde, 0xe7, 0x7d, 0x9c, 0x5c, 0x35, 0x4c,
+ /*9ec0:*/ 0xb1, 0x6e, 0xfc, 0x19, 0xaa, 0x5a, 0x17, 0xad, 0x22, 0x75, 0x3e, 0x83, 0xa7, 0x7e, 0x72, 0xe0,
+ /*9ed0:*/ 0xaa, 0x75, 0x37, 0x2a, 0xd0, 0xd3, 0x8f, 0xbf, 0x20, 0x0b, 0x3e, 0xff, 0xea, 0x0b, 0x3c, 0x20,
+ /*9ee0:*/ 0x33, 0x6b, 0x28, 0xc8, 0x67, 0x85, 0x97, 0x61, 0x5f, 0x48, 0xaf, 0x38, 0x38, 0x07, 0x41, 0x6a,
+ /*9ef0:*/ 0x5e, 0x5a, 0x39, 0x4e, 0x45, 0xc6, 0xb5, 0x8f, 0xea, 0x78, 0x47, 0x51, 0x83, 0xb2, 0x98, 0xd1,
+ /*9f00:*/ 0x43, 0x0f, 0xc4, 0xaf, 0xad, 0xf4, 0x95, 0xe5, 0xc8, 0x6f, 0x48, 0x50, 0x83, 0x7c, 0xd4, 0xb9,
+ /*9f10:*/ 0x13, 0x7b, 0x60, 0x41, 0xf9, 0x2f, 0xe0, 0x31, 0x5f, 0x3f, 0x20, 0xce, 0x6f, 0xcd, 0x94, 0x0a,
+ /*9f20:*/ 0xd5, 0x0b, 0x01, 0x09, 0x5f, 0x1d, 0x43, 0x0a, 0x35, 0x05, 0x6b, 0xe6, 0x0a, 0x48, 0xb1, 0xa7,
+ /*9f30:*/ 0xe5, 0x03, 0x7f, 0x6b, 0xfe, 0xcc, 0xdf, 0x88, 0xbc, 0xde, 0x8f, 0x1f, 0xad, 0x77, 0xb0, 0xe9,
+ /*9f40:*/ 0x53, 0x1f, 0xad, 0xb0, 0x81, 0x9f, 0xa6, 0x9f, 0x7e, 0x36, 0x8e, 0xed, 0xba, 0xa9, 0x07, 0x78,
+ /*9f50:*/ 0x2f, 0xea, 0xdb, 0x66, 0x63, 0x32, 0x47, 0xbf, 0x38, 0xfe, 0x6b, 0xa8, 0x29, 0x27, 0x0a, 0x41,
+ /*9f60:*/ 0x0b, 0x84, 0x11, 0xcf, 0x5c, 0x57, 0x0f, 0x2a, 0xbc, 0x6f, 0xc8, 0xa8, 0x55, 0x19, 0xd8, 0xd0,
+ /*9f70:*/ 0x7c, 0xec, 0x19, 0x72, 0x50, 0xfa, 0x86, 0xf8, 0xa9, 0x1e, 0xb7, 0xa3, 0x96, 0xe2, 0x58, 0x17,
+ /*9f80:*/ 0x1c, 0xc9, 0x95, 0x38, 0x9e, 0x94, 0x9e, 0x16, 0xe1, 0x69, 0xe7, 0xea, 0xf2, 0x49, 0x5f, 0x9a,
+ /*9f90:*/ 0x64, 0x42, 0x5e, 0x7b, 0xb5, 0x4b, 0x5c, 0x29, 0x23, 0x84, 0xaf, 0xa3, 0x41, 0x54, 0xd2, 0x9e,
+ /*9fa0:*/ 0x25, 0x1d, 0x19, 0x1a, 0x86, 0x1d, 0xa5, 0xb4, 0xc6, 0x8f, 0x81, 0x1f, 0x06, 0xed, 0xb8, 0xee,
+ /*9fb0:*/ 0x1b, 0xf0, 0xb6, 0x78, 0xd1, 0x00, 0x85, 0x81, 0xff, 0xde, 0xdb, 0xc1, 0x6c, 0xb9, 0xdc, 0xb3,
+ /*9fc0:*/ 0x45, 0x16, 0x5f, 0xaf, 0x54, 0x17, 0xef, 0x0b, 0x98, 0x33, 0x29, 0xb5, 0x4a, 0xfb, 0x3d, 0x19,
+ /*9fd0:*/ 0x0d, 0x74, 0x8b, 0xee, 0x20, 0x94, 0x80, 0x59, 0xac, 0x93, 0xba, 0x50, 0x8a, 0x7b, 0xff, 0xd1,
+ /*9fe0:*/ 0xad, 0x7e, 0x91, 0x79, 0xcb, 0xb1, 0x64, 0x58, 0x55, 0x2a, 0xf8, 0xc4, 0xcd, 0x9b, 0xdc, 0x4c,
+ /*9ff0:*/ 0x17, 0x61, 0x19, 0x99, 0x54, 0x30, 0x20, 0x6b, 0xe9, 0xc8, 0xad, 0x1f, 0xcf, 0x61, 0x18, 0x5f,
+ /*a000:*/ 0x1d, 0x2d, 0xb1, 0xb6, 0xbf, 0xd9, 0xee, 0x38, 0x22, 0xd1, 0xd4, 0xad, 0xe7, 0xe4, 0xb3, 0xcd,
+ /*a010:*/ 0x65, 0x9c, 0x45, 0xcf, 0x2b, 0xe0, 0xde, 0x2c, 0x3a, 0x53, 0x1f, 0x98, 0x10, 0xf5, 0x15, 0xd8,
+ /*a020:*/ 0x53, 0xa4, 0x3c, 0x46, 0x00, 0x53, 0xab, 0x9b, 0x4f, 0x92, 0xb8, 0x70, 0x84, 0x24, 0xa7, 0xaf,
+ /*a030:*/ 0xe3, 0x0a, 0x5f, 0x89, 0x10, 0xa1, 0x72, 0x3d, 0x68, 0x14, 0x1d, 0xb9, 0x16, 0x4e, 0x6c, 0x19,
+ /*a040:*/ 0x43, 0x95, 0x83, 0xb8, 0x18, 0x61, 0x4d, 0x20, 0x6d, 0xb9, 0x97, 0x6b, 0x44, 0xe4, 0x9b, 0x2c,
+ /*a050:*/ 0xb5, 0x5a, 0xdd, 0xd5, 0xd1, 0x6a, 0xdf, 0x19, 0xf7, 0xb0, 0x5a, 0x09, 0xc1, 0x55, 0x3e, 0x88,
+ /*a060:*/ 0xbe, 0xa5, 0x49, 0x20, 0x95, 0x7f, 0xcb, 0x97, 0x5b, 0x51, 0x4d, 0xb0, 0x77, 0x89, 0xab, 0x4d,
+ /*a070:*/ 0xfc, 0x88, 0x20, 0x25, 0x68, 0x38, 0x6a, 0xb9, 0x5d, 0x0b, 0x9a, 0xe6, 0x96, 0xeb, 0x64, 0x66,
+ /*a080:*/ 0x1f, 0x7b, 0xb0, 0x2f, 0x35, 0xb6, 0x45, 0x25, 0x46, 0x09, 0x70, 0x98, 0xf8, 0xdc, 0x47, 0x14,
+ /*a090:*/ 0x7d, 0x61, 0xfa, 0x6e, 0x4e, 0x7c, 0x4f, 0x42, 0xe3, 0xaa, 0x1a, 0xf7, 0x44, 0xa8, 0x4a, 0x85,
+ /*a0a0:*/ 0xa5, 0xcc, 0x07, 0x7c, 0x2a, 0x23, 0xab, 0x1d, 0xf7, 0xa0, 0xd5, 0xd9, 0x9b, 0xfc, 0xf9, 0x9b,
+ /*a0b0:*/ 0xec, 0x93, 0xd4, 0x03, 0x86, 0x1d, 0x0b, 0x02, 0x82, 0xde, 0x06, 0xb3, 0xd1, 0x58, 0x03, 0xf1,
+ /*a0c0:*/ 0xbd, 0x8f, 0xf8, 0xc9, 0x39, 0x9d, 0xce, 0x16, 0x54, 0xb0, 0x42, 0x8b, 0xac, 0x08, 0x5c, 0xfb,
+ /*a0d0:*/ 0x0c, 0xcb, 0x79, 0xfc, 0x65, 0xe0, 0xe6, 0x54, 0xcd, 0x39, 0x6d, 0x3d, 0x67, 0x69, 0xf4, 0xb6,
+ /*a0e0:*/ 0x0d, 0x51, 0xb2, 0x3b, 0xc0, 0x61, 0x97, 0xde, 0xbd, 0x7f, 0x0a, 0xe0, 0xb0, 0xd7, 0x46, 0x21,
+ /*a0f0:*/ 0xb4, 0xa5, 0x9b, 0x96, 0x3c, 0xf5, 0x75, 0x39, 0x44, 0xb9, 0x06, 0xf2, 0xf7, 0x51, 0xc8, 0xfa,
+ /*a100:*/ 0x6f, 0x1c, 0x06, 0x3c, 0x90, 0xf0, 0xf6, 0x67, 0x17, 0xe8, 0xb2, 0x0c, 0x75, 0x40, 0x92, 0x4d,
+ /*a110:*/ 0x41, 0x08, 0x39, 0xf9, 0x71, 0xb8, 0xe5, 0xbf, 0x8f, 0xad, 0x90, 0x84, 0x29, 0x48, 0x8e, 0x75,
+ /*a120:*/ 0x4f, 0xb3, 0xf3, 0xe3, 0xc3, 0xf5, 0x3d, 0xe6, 0x95, 0xfb, 0x14, 0x5b, 0x89, 0xe4, 0xd8, 0xf3,
+ /*a130:*/ 0x16, 0x26, 0x76, 0xf5, 0x76, 0x43, 0x1f, 0xe3, 0x0b, 0xe4, 0xb7, 0x5a, 0x1a, 0x2c, 0x71, 0xb0,
+ /*a140:*/ 0xd4, 0xd0, 0x09, 0x8c, 0x64, 0x70, 0x57, 0x98, 0xe6, 0xa6, 0x10, 0x6f, 0xde, 0xe1, 0xa5, 0x45,
+ /*a150:*/ 0x9e, 0x41, 0x35, 0x3f, 0x78, 0x8e, 0xf1, 0x3c, 0x30, 0x32, 0xe2, 0xe1, 0xa6, 0xd8, 0x58, 0xc0,
+ /*a160:*/ 0xa4, 0x69, 0x1a, 0x5a, 0xb2, 0x56, 0x7f, 0x33, 0x3f, 0x10, 0x77, 0x92, 0xa7, 0xc0, 0xb2, 0xc0,
+ /*a170:*/ 0xf8, 0x27, 0xa5, 0xcd, 0xfa, 0x27, 0x9f, 0xe3, 0x28, 0x59, 0x54, 0xb3, 0x43, 0xf8, 0xd7, 0x20,
+ /*a180:*/ 0x25, 0xee, 0x34, 0x3d, 0x66, 0xa1, 0x48, 0x83, 0x61, 0x03, 0x29, 0xcb, 0xbb, 0x72, 0x56, 0x1d,
+ /*a190:*/ 0x66, 0xfc, 0xcf, 0x6e, 0x28, 0x22, 0xed, 0x3a, 0x2f, 0xdb, 0x4a, 0x0b, 0xa6, 0xbe, 0xb2, 0xe4,
+ /*a1a0:*/ 0x26, 0x40, 0x82, 0xd0, 0xab, 0xfa, 0x95, 0x03, 0x4d, 0xdb, 0x5b, 0x97, 0x65, 0x36, 0x4a, 0x5e,
+ /*a1b0:*/ 0xd9, 0x63, 0xc8, 0x9c, 0xbe, 0x70, 0x76, 0xee, 0xa0, 0xcf, 0x34, 0xad, 0xcd, 0xa1, 0x81, 0x19,
+ /*a1c0:*/ 0x71, 0x49, 0xb7, 0xc9, 0x47, 0xec, 0x92, 0x32, 0xc8, 0xf0, 0xe0, 0x30, 0xee, 0x9a, 0xbb, 0x11,
+ /*a1d0:*/ 0x8e, 0xe4, 0xa8, 0xdb, 0x1f, 0x29, 0xf5, 0xcf, 0x16, 0x82, 0x7b, 0xcf, 0x10, 0x48, 0xaa, 0x55,
+ /*a1e0:*/ 0x75, 0x9e, 0x8b, 0xc1, 0x34, 0xd2, 0x91, 0xd1, 0x56, 0x51, 0xee, 0xcb, 0xc5, 0x8b, 0xeb, 0x30,
+ /*a1f0:*/ 0xa9, 0x0c, 0xcd, 0x05, 0x7c, 0xd0, 0x64, 0x8b, 0x66, 0xba, 0x59, 0xd2, 0x0d, 0x87, 0x8f, 0xf6,
+ /*a200:*/ 0x67, 0x8b, 0x85, 0x44, 0x7f, 0xd9, 0x02, 0xfd, 0x75, 0x0b, 0x11, 0x45, 0xa5, 0x1d, 0x2a, 0x37,
+ /*a210:*/ 0xd8, 0xe7, 0xde, 0x33, 0xcf, 0xdb, 0xdb, 0x31, 0xe4, 0xf5, 0x41, 0xae, 0x33, 0x6e, 0x0e, 0x02,
+ /*a220:*/ 0x02, 0x38, 0xd7, 0x67, 0xb5, 0x24, 0xe9, 0x31, 0x91, 0x0f, 0x5f, 0x24, 0xd3, 0x2f, 0x41, 0xe7,
+ /*a230:*/ 0x8a, 0xb0, 0x5c, 0x88, 0x32, 0x4e, 0xff, 0xf1, 0xa4, 0xaf, 0xa8, 0x6b, 0x04, 0x5d, 0x0e, 0xb2,
+ /*a240:*/ 0xd8, 0x69, 0x74, 0x5b, 0xbc, 0x91, 0xf3, 0x59, 0x98, 0xf5, 0x13, 0xdd, 0x10, 0x45, 0x02, 0x6d,
+ /*a250:*/ 0xcb, 0x3e, 0x01, 0x31, 0xa0, 0x29, 0x07, 0x67, 0x3b, 0x04, 0x4a, 0xc3, 0x9c, 0x9e, 0x90, 0xa0,
+ /*a260:*/ 0x1d, 0xc1, 0x6a, 0x9e, 0xef, 0xd5, 0xf2, 0x1f, 0x91, 0xd0, 0xe7, 0xe2, 0x76, 0x83, 0xaa, 0x85,
+ /*a270:*/ 0xd6, 0x29, 0x8a, 0x74, 0x09, 0x94, 0xed, 0x4e, 0x2b, 0xd9, 0x6a, 0x55, 0x70, 0x3d, 0x16, 0x57,
+ /*a280:*/ 0xd4, 0x9e, 0x31, 0x66, 0x8b, 0xf4, 0x6a, 0x70, 0xce, 0xe5, 0x33, 0xc0, 0xb4, 0xcf, 0x41, 0xf7,
+ /*a290:*/ 0xb2, 0xbf, 0x95, 0xa1, 0xe3, 0x8b, 0x2e, 0x46, 0x1f, 0x44, 0xe5, 0xd0, 0x5e, 0x99, 0x4a, 0xb6,
+ /*a2a0:*/ 0x65, 0x90, 0x74, 0x2a, 0x8e, 0xbc, 0x1f, 0x17, 0x6a, 0x01, 0x05, 0xb7, 0xb5, 0xd2, 0xab, 0xf6,
+ /*a2b0:*/ 0xe6, 0x90, 0x5a, 0x07, 0xa1, 0x7c, 0x68, 0x9d, 0x7a, 0x88, 0x1c, 0x10, 0xa4, 0xe3, 0x7b, 0xbb,
+ /*a2c0:*/ 0xf4, 0xb0, 0x1f, 0x59, 0x96, 0x31, 0xea, 0xc5, 0xf2, 0x7e, 0x1e, 0x31, 0xa2, 0x94, 0x84, 0x3a,
+ /*a2d0:*/ 0xbd, 0x08, 0x8a, 0x3a, 0xa5, 0x6d, 0x0e, 0x45, 0x63, 0xd8, 0xe5, 0xf4, 0x53, 0xd5, 0x04, 0x64,
+ /*a2e0:*/ 0x43, 0x14, 0xed, 0x45, 0x96, 0x31, 0xdd, 0x73, 0xf8, 0xe5, 0x1f, 0x4f, 0xd7, 0x41, 0x9e, 0xed,
+ /*a2f0:*/ 0x87, 0xb0, 0x20, 0x8a, 0x51, 0xcf, 0x9e, 0x42, 0xe4, 0xb8, 0xce, 0x61, 0xbe, 0x3f, 0x03, 0xf6,
+ /*a300:*/ 0xdd, 0x55, 0x57, 0x17, 0x89, 0xe3, 0x11, 0x2f, 0x75, 0x54, 0x8f, 0xcc, 0x69, 0xc8, 0xd9, 0xd0,
+ /*a310:*/ 0x17, 0xfc, 0x6a, 0x4f, 0x11, 0x08, 0xc5, 0x67, 0xd4, 0xdd, 0x6e, 0x9c, 0xae, 0x18, 0x05, 0x50,
+ /*a320:*/ 0xd9, 0xb0, 0x75, 0x8c, 0x4a, 0x0a, 0xb9, 0x37, 0x91, 0x38, 0xab, 0x5e, 0xbc, 0xe0, 0x15, 0x07,
+ /*a330:*/ 0x10, 0xdd, 0x4c, 0xb2, 0xc7, 0x62, 0x57, 0x51, 0x72, 0xe9, 0x23, 0x50, 0x47, 0xf9, 0xc2, 0x31,
+ /*a340:*/ 0x40, 0x47, 0xfd, 0xe3, 0xf6, 0x45, 0xc4, 0xd8, 0x3b, 0x42, 0x47, 0xed, 0xd6, 0x36, 0x0a, 0x66,
+ /*a350:*/ 0x96, 0x1d, 0x3a, 0x27, 0x59, 0xa3, 0x51, 0xa6, 0xc0, 0x6c, 0xdb, 0x43, 0x0f, 0x86, 0xcb, 0xe6,
+ /*a360:*/ 0x01, 0x2d, 0x42, 0xcd, 0xa7, 0x63, 0x27, 0x0e, 0xd0, 0xdb, 0xa9, 0x39, 0xbe, 0x43, 0x78, 0x16,
+ /*a370:*/ 0x54, 0xcc, 0xff, 0x0d, 0x4c, 0x44, 0x22, 0x9e, 0xbf, 0x33, 0xbb, 0xb6, 0xd5, 0x9b, 0xe1, 0x80,
+ /*a380:*/ 0x26, 0x54, 0x76, 0xe7, 0xcb, 0x8b, 0x36, 0x9c, 0x85, 0xb7, 0xee, 0x62, 0x26, 0xa0, 0xd9, 0x99,
+ /*a390:*/ 0x1d, 0x8e, 0xfc, 0x66, 0xb8, 0x80, 0x64, 0x74, 0xc7, 0x5a, 0x51, 0x4e, 0x27, 0xac, 0x53, 0xb5,
+ /*a3a0:*/ 0x94, 0xf8, 0xab, 0xd9, 0xf9, 0x7b, 0xdd, 0xda, 0xac, 0xd6, 0xf8, 0x81, 0x8b, 0x1e, 0xd2, 0x11,
+ /*a3b0:*/ 0xc3, 0x2a, 0xc2, 0x32, 0xb5, 0x96, 0x11, 0xae, 0xa5, 0x44, 0xe8, 0xe3, 0x37, 0x2e, 0xe5, 0x46,
+ /*a3c0:*/ 0x89, 0xc1, 0x4a, 0x18, 0xdd, 0x0d, 0x08, 0x7c, 0x54, 0x4e, 0xe6, 0x48, 0x76, 0x74, 0x19, 0x7e,
+ /*a3d0:*/ 0x40, 0xf4, 0xf4, 0xe6, 0x04, 0x1c, 0xe2, 0x19, 0x2a, 0x87, 0x1d, 0x07, 0x3b, 0xf9, 0xf5, 0x72,
+ /*a3e0:*/ 0x67, 0xc5, 0xd5, 0x53, 0x5d, 0xa2, 0x6f, 0x87, 0x38, 0xe6, 0x3d, 0x7c, 0xf5, 0xcd, 0x02, 0xfc,
+ /*a3f0:*/ 0xf2, 0x74, 0x27, 0x62, 0x62, 0x71, 0x45, 0xaa, 0x1f, 0xbd, 0x49, 0x8c, 0xa3, 0xb8, 0xf7, 0x14,
+ /*a400:*/ 0xac, 0x49, 0xeb, 0xb3, 0x8f, 0x5f, 0x12, 0x46, 0x07, 0x28, 0x32, 0x4a, 0x50, 0x0e, 0x98, 0xb3,
+ /*a410:*/ 0x8f, 0x63, 0x38, 0x45, 0x76, 0xf1, 0xcf, 0x04, 0x86, 0x16, 0x2f, 0x10, 0xbd, 0xa0, 0xb1, 0xd1,
+ /*a420:*/ 0xe4, 0x32, 0x09, 0xa3, 0x0c, 0x4c, 0xf3, 0xb0, 0x3b, 0x7d, 0xa8, 0x9b, 0xf7, 0x6c, 0x11, 0xce,
+ /*a430:*/ 0xe4, 0x19, 0x8c, 0xbb, 0x27, 0x12, 0x73, 0x9f, 0xe9, 0x46, 0x4a, 0x82, 0xf9, 0x26, 0x30, 0x4e,
+ /*a440:*/ 0xef, 0x11, 0x55, 0x98, 0x2c, 0xa4, 0xf4, 0xa9, 0x42, 0x56, 0x67, 0x36, 0xbf, 0x8c, 0xe4, 0x8c,
+ /*a450:*/ 0xf8, 0x47, 0x8f, 0x73, 0x3a, 0x0c, 0xdd, 0xe6, 0x49, 0x29, 0x12, 0xf4, 0xc2, 0x7d, 0x72, 0x0f,
+ /*a460:*/ 0xa5, 0x5b, 0xb9, 0x19, 0xfe, 0x24, 0x65, 0xfd, 0x5a, 0xe6, 0x3f, 0xb0, 0x2c, 0x78, 0xec, 0x3f,
+ /*a470:*/ 0x1f, 0xc2, 0xa8, 0xd0, 0xdf, 0x1b, 0xa1, 0x9b, 0x47, 0x0b, 0x16, 0xb2, 0x1d, 0x75, 0xba, 0x23,
+ /*a480:*/ 0x20, 0x5a, 0x88, 0xca, 0x99, 0x54, 0x00, 0x8e, 0xd4, 0x9e, 0x31, 0x71, 0xdf, 0xb8, 0xf9, 0x23,
+ /*a490:*/ 0xc7, 0x88, 0x2a, 0x40, 0xc5, 0x5f, 0x17, 0x07, 0xe5, 0xab, 0x70, 0xff, 0xac, 0x79, 0xe8, 0x51,
+ /*a4a0:*/ 0x9c, 0x9f, 0x06, 0x43, 0x31, 0x7a, 0x0f, 0xa1, 0x12, 0x5a, 0x50, 0x86, 0x7a, 0x0f, 0xf9, 0xf2,
+ /*a4b0:*/ 0x13, 0x7d, 0x11, 0x72, 0x56, 0xa5, 0x54, 0x52, 0xb4, 0xcf, 0xb0, 0xdb, 0xce, 0xe1, 0x02, 0x8e,
+ /*a4c0:*/ 0xeb, 0xf8, 0xc6, 0xdd, 0xcf, 0x7f, 0x48, 0xa6, 0x18, 0xc1, 0x8e, 0xeb, 0xf7, 0xf0, 0x59, 0x2e,
+ /*a4d0:*/ 0xb5, 0xb0, 0x29, 0x7c, 0x46, 0x88, 0xfb, 0xf8, 0x5e, 0xb8, 0xd1, 0x96, 0x23, 0x8e, 0xaf, 0x06,
+ /*a4e0:*/ 0x44, 0x1b, 0xe0, 0xac, 0xf9, 0x5c, 0xa0, 0x2a, 0x05, 0xfc, 0x8f, 0x74, 0x4d, 0x42, 0x4c, 0xca,
+ /*a4f0:*/ 0xe8, 0x98, 0x96, 0x8c, 0x9b, 0x59, 0x92, 0xb1, 0x9a, 0x19, 0xed, 0x41, 0xc7, 0xe7, 0x61, 0x9b,
+ /*a500:*/ 0x30, 0x3c, 0x5b, 0x45, 0xcf, 0x90, 0xfb, 0xf4, 0x9f, 0xce, 0xc3, 0x83, 0x82, 0x70, 0xc2, 0xfd,
+ /*a510:*/ 0xb6, 0xcd, 0x94, 0x6a, 0x15, 0xa5, 0x30, 0x39, 0xa3, 0xbb, 0x0a, 0x70, 0x18, 0x69, 0x93, 0x7b,
+ /*a520:*/ 0x21, 0x1f, 0x7f, 0x71, 0x61, 0xb7, 0xa3, 0x21, 0xb1, 0xba, 0x65, 0x1d, 0x84, 0x39, 0xc7, 0x4e,
+ /*a530:*/ 0x21, 0x2f, 0xfe, 0x8a, 0x0f, 0xdf, 0x81, 0xbb, 0xb2, 0x72, 0x71, 0x25, 0xfa, 0xc2, 0xc5, 0xff,
+ /*a540:*/ 0x99, 0x6d, 0x1f, 0xa3, 0xfc, 0xf3, 0xec, 0x32, 0x92, 0xd3, 0x28, 0xf2, 0xc6, 0x26, 0x1f, 0xa0,
+ /*a550:*/ 0xe6, 0xdf, 0xc5, 0xb2, 0x6b, 0x17, 0x69, 0x64, 0xe1, 0xda, 0x68, 0x38, 0x14, 0xf5, 0x2e, 0xf5,
+ /*a560:*/ 0xaf, 0x57, 0x74, 0x44, 0xe1, 0x28, 0x6e, 0x2e, 0x28, 0x7f, 0x99, 0x1c, 0x23, 0x26, 0x96, 0x38,
+ /*a570:*/ 0xcb, 0x70, 0x62, 0x53, 0x1b, 0x70, 0xb3, 0x1b, 0xbb, 0x9a, 0x9e, 0x31, 0xfd, 0x6f, 0x74, 0x84,
+ /*a580:*/ 0x5c, 0xd5, 0xf7, 0x10, 0xf7, 0x76, 0xd4, 0x22, 0xe6, 0x5e, 0x4b, 0xad, 0x41, 0xe6, 0x23, 0xe5,
+ /*a590:*/ 0x36, 0xf1, 0x2b, 0x57, 0x87, 0x97, 0x60, 0x46, 0x9d, 0xea, 0x18, 0x25, 0xcf, 0x33, 0x4f, 0x68,
+ /*a5a0:*/ 0x4d, 0x9f, 0x61, 0x59, 0x09, 0xf4, 0x45, 0xa3, 0x03, 0x76, 0x68, 0x24, 0x18, 0x36, 0xbe, 0xb7,
+ /*a5b0:*/ 0x78, 0xf7, 0xdc, 0x21, 0xce, 0x36, 0x28, 0xd2, 0x79, 0xb9, 0xda, 0xf3, 0x7f, 0xc0, 0x74, 0x55,
+ /*a5c0:*/ 0x00, 0x38, 0x57, 0x73, 0x9b, 0x1e, 0x80, 0x84, 0x55, 0xfc, 0x35, 0x1c, 0xbd, 0x8c, 0x27, 0xf0,
+ /*a5d0:*/ 0x6d, 0xef, 0x8a, 0x6a, 0x3a, 0x76, 0x77, 0xd1, 0xf3, 0xf7, 0xbc, 0xdd, 0x97, 0x0b, 0x68, 0xcc,
+ /*a5e0:*/ 0x2b, 0xdc, 0x1f, 0xde, 0x52, 0x66, 0x67, 0x7d, 0x72, 0x4c, 0x2c, 0xa8, 0xf1, 0x8d, 0x6d, 0xa3,
+ /*a5f0:*/ 0x4c, 0x33, 0xcf, 0xa9, 0x25, 0x6b, 0x6e, 0xe0, 0x48, 0x81, 0x51, 0x85, 0xf4, 0x33, 0xda, 0x32,
+ /*a600:*/ 0x7b, 0xdd, 0xa8, 0x0e, 0x94, 0x08, 0xc2, 0x16, 0xd0, 0xdd, 0x93, 0x22, 0xdc, 0x90, 0x04, 0xc9,
+ /*a610:*/ 0xee, 0x2a, 0xcd, 0x58, 0xac, 0xf7, 0x9a, 0xe2, 0xd9, 0x0a, 0x7b, 0x18, 0x9f, 0x85, 0xfc, 0x8e,
+ /*a620:*/ 0xb6, 0x5c, 0x05, 0x46, 0x94, 0x55, 0xd5, 0x28, 0x84, 0x0a, 0xb1, 0x35, 0x8d, 0x38, 0x34, 0xd5,
+ /*a630:*/ 0xd6, 0x2b, 0x66, 0xd6, 0xc1, 0x19, 0x5d, 0x99, 0x2f, 0xbe, 0x7f, 0xd9, 0x53, 0xa5, 0x6f, 0xa0,
+ /*a640:*/ 0x18, 0xb5, 0x77, 0x12, 0x56, 0xdd, 0x64, 0x4c, 0x84, 0x43, 0xa6, 0x05, 0x29, 0xf2, 0x70, 0x88,
+ /*a650:*/ 0x64, 0x1e, 0x28, 0x35, 0x31, 0x2d, 0x9a, 0xa0, 0x1e, 0x05, 0x53, 0xa2, 0xf1, 0xa9, 0xa8, 0xae,
+ /*a660:*/ 0x6d, 0x93, 0x13, 0x2d, 0xeb, 0x94, 0xe9, 0x7f, 0x9e, 0x05, 0x52, 0x18, 0xa0, 0xaa, 0x4d, 0x25,
+ /*a670:*/ 0xf2, 0x1c, 0xa6, 0xf4, 0x38, 0x14, 0x36, 0xb6, 0x0c, 0x5f, 0xb3, 0x26, 0x1f, 0x35, 0x3d, 0x6d,
+ /*a680:*/ 0xa2, 0xa1, 0x06, 0x41, 0x44, 0xf2, 0xc2, 0xee, 0x8a, 0xf0, 0x5b, 0x4c, 0x15, 0xa2, 0x1d, 0xd1,
+ /*a690:*/ 0xd3, 0x44, 0x89, 0x49, 0x92, 0xe3, 0x1c, 0x15, 0x69, 0x43, 0xab, 0x10, 0xce, 0x16, 0xcf, 0x82,
+ /*a6a0:*/ 0x5b, 0x81, 0x1b, 0x86, 0x8b, 0x71, 0x79, 0x47, 0x49, 0x87, 0x8f, 0x73, 0x7a, 0xc2, 0xda, 0xb6,
+ /*a6b0:*/ 0x68, 0x45, 0x4d, 0x41, 0xbc, 0xec, 0x5c, 0x4a, 0xb1, 0x8b, 0x2d, 0xc2, 0x1f, 0x62, 0xd8, 0x8c,
+ /*a6c0:*/ 0x9e, 0x0d, 0x00, 0x5b, 0x20, 0x23, 0x39, 0xfe, 0x8c, 0x1c, 0x1d, 0xf6, 0xb8, 0x86, 0xb4, 0x2b,
+ /*a6d0:*/ 0xe2, 0xe9, 0x79, 0xc4, 0x30, 0xcf, 0xd8, 0xc4, 0x9d, 0xcf, 0x9d, 0xb2, 0xd3, 0x50, 0x2b, 0xdc,
+ /*a6e0:*/ 0xae, 0xfb, 0x67, 0x50, 0x73, 0x86, 0x0c, 0x01, 0x31, 0x8e, 0xb0, 0x98, 0x96, 0xe9, 0x3c, 0x58,
+ /*a6f0:*/ 0x08, 0x68, 0x0a, 0x63, 0xd2, 0xdf, 0xc7, 0x2e, 0xd5, 0xed, 0x14, 0xeb, 0x61, 0x56, 0x63, 0xa1,
+ /*a700:*/ 0xc1, 0xa9, 0x26, 0x25, 0xe8, 0x6c, 0xea, 0xa0, 0x5a, 0x8e, 0xaf, 0x5d, 0xca, 0x06, 0xa4, 0x64,
+ /*a710:*/ 0xad, 0xf8, 0xbd, 0x90, 0xbb, 0xbf, 0xb7, 0xb6, 0x25, 0x5d, 0x09, 0x39, 0x82, 0x01, 0x7d, 0xfb,
+ /*a720:*/ 0x31, 0x3c, 0x82, 0x2b, 0x40, 0x63, 0x01, 0x80, 0x4e, 0x7c, 0xe8, 0x6c, 0x9b, 0xef, 0x12, 0x2c,
+ /*a730:*/ 0x8d, 0x63, 0xff, 0xf5, 0xad, 0x77, 0x59, 0x39, 0x20, 0x99, 0x85, 0x51, 0xe7, 0x75, 0x07, 0xac,
+ /*a740:*/ 0xe8, 0x30, 0xa4, 0xc9, 0xbf, 0x9f, 0xa4, 0x1f, 0x11, 0x98, 0x01, 0x9b, 0xfb, 0x96, 0x7d, 0xa3,
+ /*a750:*/ 0xaf, 0x73, 0x15, 0x7b, 0xce, 0x7a, 0xce, 0x2c, 0x00, 0xa1, 0x0f, 0x3c, 0x49, 0x6c, 0x62, 0x4c,
+ /*a760:*/ 0x7c, 0xec, 0xbb, 0x44, 0xb5, 0xed, 0x16, 0x9d, 0x57, 0x2b, 0x76, 0x56, 0x57, 0x54, 0x8d, 0xd7,
+ /*a770:*/ 0xa1, 0x6c, 0xd8, 0x0f, 0xb5, 0x13, 0xe0, 0x56, 0xb6, 0xea, 0xaf, 0x60, 0x13, 0xd1, 0xf8, 0xbc,
+ /*a780:*/ 0x58, 0xa8, 0x52, 0x5e, 0x42, 0x1b, 0x70, 0x7d, 0x63, 0x7d, 0x8b, 0x69, 0x82, 0xc3, 0xab, 0x38,
+ /*a790:*/ 0x64, 0x82, 0xef, 0x3f, 0xa9, 0xd9, 0x51, 0x5c, 0x4b, 0x88, 0x35, 0x17, 0xc4, 0xd2, 0x2d, 0xa5,
+ /*a7a0:*/ 0x46, 0xb0, 0x11, 0xcf, 0x6d, 0x94, 0xa3, 0x93, 0x93, 0xb7, 0xa7, 0xf8, 0x09, 0x39, 0x03, 0x1c,
+ /*a7b0:*/ 0x15, 0xba, 0x34, 0x3e, 0xe0, 0x08, 0xda, 0x0a, 0x93, 0xa2, 0x35, 0x23, 0x9b, 0xa0, 0x49, 0x7e,
+ /*a7c0:*/ 0x58, 0xe4, 0x6d, 0xef, 0x21, 0xbd, 0xfb, 0x15, 0xe5, 0xb2, 0x26, 0xb9, 0xd9, 0xab, 0xef, 0x0e,
+ /*a7d0:*/ 0x12, 0xfc, 0x24, 0xd6, 0x5c, 0xfd, 0x0e, 0xf2, 0x00, 0x12, 0x0f, 0x22, 0x0c, 0x53, 0x54, 0xdd,
+ /*a7e0:*/ 0xe6, 0x04, 0x61, 0xcb, 0xf5, 0x4b, 0xd0, 0x91, 0x24, 0x7e, 0x91, 0x95, 0x07, 0x41, 0x4c, 0x32,
+ /*a7f0:*/ 0x64, 0x44, 0x4e, 0xdc, 0x0b, 0xf4, 0x8a, 0xb5, 0x75, 0xc8, 0x73, 0xee, 0xc3, 0x7d, 0xb0, 0xbf,
+ /*a800:*/ 0x63, 0x7d, 0x69, 0x96, 0x58, 0x9c, 0x10, 0xed, 0xe6, 0x5a, 0x55, 0xf7, 0x20, 0xda, 0xbd, 0x1b,
+ /*a810:*/ 0xba, 0x0a, 0xab, 0x36, 0x1f, 0xe3, 0xe0, 0x3c, 0x20, 0xae, 0x90, 0x60, 0xcd, 0xe0, 0x29, 0xe7,
+ /*a820:*/ 0x41, 0x27, 0x68, 0x1c, 0xf3, 0xcc, 0xb7, 0x79, 0xfb, 0x06, 0x48, 0x89, 0x61, 0xb2, 0x02, 0xb2,
+ /*a830:*/ 0xcf, 0x61, 0xe9, 0x77, 0x9f, 0x8d, 0x7e, 0x19, 0x2b, 0xd0, 0x2d, 0xf9, 0x61, 0x29, 0xc9, 0x46,
+ /*a840:*/ 0x84, 0xd1, 0x54, 0x4d, 0x83, 0xb0, 0x8c, 0x33, 0x4f, 0xa5, 0xeb, 0x98, 0xa0, 0x41, 0x5b, 0xa0,
+ /*a850:*/ 0x04, 0x09, 0x37, 0xc2, 0xa7, 0x5f, 0xdf, 0x63, 0xa8, 0x82, 0x78, 0xf9, 0xea, 0xfc, 0xde, 0xa5,
+ /*a860:*/ 0x5c, 0xe4, 0xd9, 0x80, 0x54, 0x78, 0x34, 0x77, 0x59, 0x2b, 0xbb, 0x38, 0x6e, 0xdd, 0x57, 0x9e,
+ /*a870:*/ 0xd7, 0xe3, 0x9c, 0x67, 0x2e, 0xc1, 0xa1, 0x9d, 0xf2, 0xa1, 0xb8, 0x99, 0xc0, 0x89, 0x83, 0x2c,
+ /*a880:*/ 0x03, 0xfc, 0xc0, 0x03, 0x77, 0x06, 0xc9, 0xbe, 0x8a, 0xe6, 0xaa, 0x42, 0x95, 0x43, 0x57, 0x30,
+ /*a890:*/ 0xdf, 0xc0, 0x71, 0x9b, 0x42, 0x39, 0x67, 0x35, 0xc1, 0xa8, 0xb0, 0x16, 0xe3, 0xc3, 0xa8, 0x20,
+ /*a8a0:*/ 0xd6, 0x11, 0xed, 0x12, 0x42, 0x62, 0x2e, 0x2b, 0x17, 0x43, 0x3a, 0x27, 0x0d, 0x83, 0xd6, 0x87,
+ /*a8b0:*/ 0x70, 0x0e, 0x84, 0x01, 0xfd, 0xa1, 0xd9, 0x2b, 0x5c, 0xdb, 0xf9, 0xbe, 0x27, 0xd3, 0x05, 0x7a,
+ /*a8c0:*/ 0x89, 0x77, 0x23, 0x7a, 0x0c, 0x4c, 0x3f, 0xb3, 0xbc, 0xc1, 0x80, 0xde, 0x88, 0x68, 0x6c, 0xbe,
+ /*a8d0:*/ 0x6b, 0xa0, 0xf4, 0xfe, 0x9d, 0xde, 0xa4, 0x8d, 0xc8, 0xfe, 0x8f, 0x0d, 0xf8, 0xfb, 0xe3, 0x33,
+ /*a8e0:*/ 0xd9, 0x9f, 0x38, 0x44, 0xf0, 0x1e, 0x13, 0x87, 0x4a, 0x35, 0x79, 0xbd, 0x56, 0x77, 0x4d, 0x2e,
+ /*a8f0:*/ 0xed, 0x44, 0x05, 0x70, 0xcb, 0xee, 0x56, 0xb8, 0x40, 0xc4, 0x29, 0x1a, 0xaf, 0x14, 0xd3, 0xd3,
+ /*a900:*/ 0x18, 0x34, 0x77, 0x79, 0x7c, 0x69, 0x36, 0xbc, 0x18, 0xea, 0xc8, 0x5e, 0xdf, 0x17, 0xfe, 0xf0,
+ /*a910:*/ 0x22, 0xd7, 0x5c, 0xa7, 0x24, 0xd8, 0xe9, 0x85, 0x2f, 0x08, 0xef, 0x68, 0x9a, 0xe9, 0x81, 0x80,
+ /*a920:*/ 0xe2, 0xb2, 0x5d, 0x11, 0x30, 0xf0, 0xa9, 0xab, 0x6b, 0xee, 0x2c, 0x62, 0x0a, 0xde, 0xec, 0x4e,
+ /*a930:*/ 0xd0, 0x25, 0xbb, 0xd5, 0xc5, 0x2d, 0xa8, 0xea, 0x1e, 0x7b, 0xfc, 0x84, 0x4b, 0x38, 0xb8, 0x90,
+ /*a940:*/ 0x8d, 0x4b, 0x3d, 0x7c, 0xa6, 0x8d, 0x1a, 0x73, 0x0f, 0x72, 0xb9, 0x2a, 0xc2, 0x31, 0x3c, 0xa5,
+ /*a950:*/ 0x18, 0xfe, 0x02, 0xb6, 0x2f, 0xfa, 0x3c, 0x23, 0x99, 0x73, 0x93, 0xcf, 0x14, 0x06, 0xb8, 0x76,
+ /*a960:*/ 0xf5, 0x66, 0xb2, 0xb8, 0x04, 0xd0, 0x10, 0x13, 0x38, 0x41, 0x17, 0x59, 0x20, 0x63, 0x09, 0xee,
+ /*a970:*/ 0x1b, 0xae, 0xc0, 0xea, 0xf3, 0xbf, 0xca, 0x9f, 0x25, 0x94, 0x0c, 0x96, 0x3f, 0x2d, 0x99, 0xc3,
+ /*a980:*/ 0x42, 0xe4, 0xe0, 0x92, 0x9c, 0x13, 0x0d, 0xb6, 0x87, 0xd6, 0x42, 0xbd, 0x35, 0xb2, 0x72, 0x57,
+ /*a990:*/ 0xb4, 0x52, 0x16, 0xa3, 0x86, 0x82, 0x21, 0x67, 0x5f, 0xff, 0x3d, 0x58, 0xcd, 0xb1, 0x9e, 0xbd,
+ /*a9a0:*/ 0x15, 0x87, 0x1e, 0x2f, 0x8d, 0x98, 0xcf, 0x4b, 0x93, 0x7b, 0x3f, 0xdd, 0x7c, 0x2b, 0xc5, 0x57,
+ /*a9b0:*/ 0x9b, 0x98, 0xfb, 0xc7, 0x53, 0xc3, 0x1f, 0xae, 0x9d, 0xd6, 0xed, 0xc8, 0xd0, 0xb6, 0x34, 0x21,
+ /*a9c0:*/ 0x94, 0xf3, 0x95, 0xfb, 0xf0, 0x80, 0x24, 0x98, 0x0f, 0xd1, 0xd3, 0xe0, 0xfd, 0xc5, 0xcd, 0xa6,
+ /*a9d0:*/ 0xda, 0xfb, 0x58, 0xb0, 0x1b, 0x9a, 0x24, 0x59, 0xaf, 0x55, 0xa6, 0x82, 0xab, 0x21, 0x40, 0x4a,
+ /*a9e0:*/ 0xaa, 0x4e, 0xcd, 0x23, 0x7d, 0x2b, 0xa3, 0x01, 0x18, 0x63, 0xfd, 0x2f, 0x12, 0xd3, 0x2b, 0x25,
+ /*a9f0:*/ 0xbd, 0xb0, 0x10, 0x59, 0x7c, 0x85, 0x5d, 0xdb, 0x28, 0x34, 0xd1, 0x1d, 0x9d, 0x50, 0x78, 0xef,
+ /*aa00:*/ 0x84, 0x97, 0x1a, 0x49, 0x1a, 0x8b, 0xd3, 0x88, 0xbe, 0x67, 0xac, 0x4a, 0x1f, 0x1b, 0x15, 0x21,
+ /*aa10:*/ 0x61, 0x85, 0xf3, 0x74, 0x48, 0x20, 0xe1, 0x55, 0x16, 0x2a, 0xf3, 0xdd, 0x5c, 0x9e, 0xc9, 0x13,
+ /*aa20:*/ 0x55, 0x70, 0xf7, 0xc1, 0x07, 0xcb, 0xa2, 0xa5, 0x7d, 0x7d, 0xcb, 0xbb, 0x56, 0x07, 0x7a, 0x5a,
+ /*aa30:*/ 0xa4, 0xf7, 0x1b, 0x28, 0x0a, 0x89, 0xef, 0x5a, 0x28, 0x01, 0xe0, 0xbb, 0x67, 0x9d, 0xab, 0x2f,
+ /*aa40:*/ 0xb8, 0x71, 0x48, 0x6c, 0x6e, 0x98, 0xc5, 0x7d, 0x81, 0xcd, 0xba, 0xc2, 0x70, 0x63, 0x9e, 0x87,
+ /*aa50:*/ 0x14, 0x54, 0xbb, 0xbb, 0xd6, 0x7b, 0xb1, 0xaa, 0xae, 0x22, 0xba, 0x87, 0x80, 0x59, 0x6f, 0x23,
+ /*aa60:*/ 0x06, 0x5c, 0x6c, 0x1d, 0x34, 0x70, 0xce, 0xfd, 0x37, 0x73, 0xff, 0x85, 0x92, 0xae, 0x13, 0xb7,
+ /*aa70:*/ 0x67, 0x5d, 0x32, 0xff, 0x39, 0x8e, 0x52, 0xaa, 0x3c, 0x99, 0xa7, 0xe9, 0x27, 0x4e, 0xbb, 0x58,
+ /*aa80:*/ 0x78, 0xa2, 0x85, 0x36, 0xad, 0xa5, 0xbe, 0xa9, 0x78, 0xc4, 0xae, 0x78, 0xef, 0xea, 0x18, 0x24,
+ /*aa90:*/ 0x50, 0x4a, 0x56, 0x85, 0x6c, 0xdc, 0x69, 0x14, 0xe2, 0xe0, 0xb3, 0x8d, 0x2e, 0xdf, 0x62, 0x47,
+ /*aaa0:*/ 0xcf, 0xf2, 0xee, 0xe2, 0x0b, 0xab, 0x08, 0xf0, 0x89, 0x29, 0x91, 0x12, 0xfc, 0x9f, 0x4c, 0xb9,
+ /*aab0:*/ 0x0c, 0x92, 0xd3, 0x0d, 0x41, 0x72, 0xce, 0x67, 0xbf, 0x72, 0x4a, 0xd5, 0x10, 0x3b, 0x7b, 0xa0,
+ /*aac0:*/ 0x6e, 0xf4, 0x51, 0x63, 0x47, 0x74, 0xd9, 0x5e, 0x0b, 0xb3, 0x3e, 0x56, 0xb9, 0x90, 0x30, 0xd8,
+ /*aad0:*/ 0xa6, 0x54, 0xf3, 0x87, 0x87, 0xf2, 0xca, 0xa8, 0x81, 0x72, 0xea, 0x07, 0x34, 0x2f, 0xb2, 0x11,
+ /*aae0:*/ 0x23, 0x49, 0xf5, 0x9d, 0x6c, 0x52, 0xd6, 0x41, 0x71, 0xe4, 0x2c, 0xc1, 0x4c, 0x30, 0x9e, 0xf3,
+ /*aaf0:*/ 0xb2, 0x21, 0x21, 0x3e, 0x1f, 0x12, 0x7b, 0x6b, 0xd1, 0xc7, 0xe8, 0xd0, 0x74, 0x1c, 0xf2, 0x46,
+ /*ab00:*/ 0xcc, 0x12, 0x89, 0x97, 0x9e, 0x92, 0x7f, 0x89, 0xdb, 0x82, 0x1c, 0xd4, 0xe8, 0xcd, 0x36, 0x76,
+ /*ab10:*/ 0x6c, 0x09, 0xe3, 0x15, 0x2e, 0x6a, 0xbf, 0x46, 0x28, 0x95, 0x2f, 0x01, 0x92, 0x00, 0x68, 0x6e,
+ /*ab20:*/ 0x5d, 0xbf, 0x3d, 0xc1, 0x29, 0xbf, 0x09, 0x4a, 0x08, 0x74, 0x79, 0x48, 0xb4, 0x5e, 0x5f, 0x52,
+ /*ab30:*/ 0x55, 0x0c, 0x41, 0x69, 0x3d, 0x48, 0xf6, 0xf0, 0x9b, 0x63, 0x1f, 0xaa, 0x6e, 0xfd, 0x7f, 0x0f,
+ /*ab40:*/ 0x83, 0x29, 0x68, 0xd7, 0xb5, 0xa6, 0x12, 0x05, 0x8f, 0x43, 0x07, 0xbc, 0x25, 0xd2, 0xec, 0xb3,
+ /*ab50:*/ 0xab, 0xc9, 0xf3, 0x1f, 0xbb, 0xc2, 0xe3, 0x78, 0x4e, 0xb6, 0x35, 0xfb, 0x94, 0xde, 0xf0, 0xd9,
+ /*ab60:*/ 0xe6, 0xec, 0xf8, 0xae, 0xf8, 0x46, 0x1a, 0x83, 0xd3, 0xdb, 0xfe, 0xbc, 0x80, 0x65, 0x4d, 0xc7,
+ /*ab70:*/ 0x83, 0x75, 0xb2, 0xdd, 0x77, 0xc3, 0x46, 0xd4, 0x32, 0xa4, 0x54, 0xef, 0x9b, 0xa3, 0x76, 0xb7,
+ /*ab80:*/ 0x9e, 0x60, 0x14, 0x6d, 0xd7, 0xb1, 0x47, 0x82, 0xef, 0x2c, 0xcf, 0x88, 0x17, 0x5c, 0xa1, 0xe6,
+ /*ab90:*/ 0x60, 0x22, 0xdb, 0x85, 0x18, 0x11, 0x08, 0xd0, 0x59, 0xc6, 0xe9, 0x19, 0x55, 0x3c, 0x81, 0xf4,
+ /*aba0:*/ 0x6d, 0xec, 0x1b, 0x88, 0xd6, 0xb6, 0x7a, 0x62, 0x5d, 0x7a, 0xc4, 0xf1, 0xf0, 0xa0, 0x09, 0x1a,
+ /*abb0:*/ 0xbc, 0xdf, 0x3c, 0xb0, 0x4f, 0x2b, 0xe1, 0x2e, 0x44, 0x3d, 0x9d, 0x0a, 0xb1, 0x1d, 0x66, 0x62,
+ /*abc0:*/ 0xbe, 0xbf, 0xe2, 0x2b, 0x66, 0xae, 0xa1, 0x35, 0x04, 0x63, 0x77, 0x97, 0xc9, 0x0b, 0xab, 0xeb,
+ /*abd0:*/ 0xf0, 0x61, 0xf2, 0x1f, 0xdb, 0x60, 0x51, 0x6f, 0xda, 0xd6, 0x19, 0xdf, 0x5b, 0xad, 0x6e, 0x02,
+ /*abe0:*/ 0x9c, 0xc8, 0xce, 0x0c, 0xa7, 0xcb, 0x93, 0x3d, 0x3c, 0xff, 0x9e, 0x88, 0xfa, 0xf9, 0x9c, 0x73,
+ /*abf0:*/ 0x9f, 0x3e, 0xbb, 0xa9, 0x40, 0x2c, 0x88, 0x4f, 0x19, 0x59, 0x1a, 0x42, 0x13, 0xca, 0x47, 0xb8,
+ /*ac00:*/ 0x46, 0x77, 0x49, 0xa0, 0xb7, 0xec, 0x73, 0x72, 0xb1, 0x9b, 0x61, 0x07, 0x8a, 0x61, 0x08, 0x1a,
+ /*ac10:*/ 0x4a, 0x59, 0x63, 0x60, 0x2a, 0x0f, 0x5a, 0xdf, 0x3c, 0x23, 0x83, 0x47, 0x32, 0x37, 0xde, 0x8a,
+ /*ac20:*/ 0x30, 0x10, 0x24, 0x3f, 0x31, 0x93, 0xcb, 0xca, 0xfa, 0x5c, 0xf0, 0xf9, 0x28, 0x50, 0x40, 0x2a,
+ /*ac30:*/ 0x62, 0xfd, 0x0b, 0x22, 0x52, 0x0b, 0xa4, 0x4d, 0xc4, 0xbc, 0x88, 0x32, 0x0f, 0x85, 0xab, 0xc9,
+ /*ac40:*/ 0x5c, 0x55, 0xc5, 0x63, 0xbb, 0x2f, 0xfb, 0x41, 0xf6, 0x52, 0xd7, 0x67, 0x35, 0x96, 0x0e, 0xf6,
+ /*ac50:*/ 0x46, 0x10, 0xaa, 0x92, 0x0a, 0xdf, 0xdf, 0xcb, 0x9b, 0xa7, 0xaa, 0x71, 0xe1, 0xd8, 0xfe, 0x03,
+ /*ac60:*/ 0xef, 0x25, 0x22, 0x72, 0x86, 0x42, 0x72, 0x00, 0xfc, 0xd2, 0x13, 0xbe, 0x03, 0x1c, 0x4c, 0x4d,
+ /*ac70:*/ 0x48, 0xb3, 0xaf, 0x7b, 0xb4, 0xa0, 0xe7, 0x0f, 0xc0, 0x40, 0x2b, 0x99, 0xfe, 0x6a, 0x8d, 0x82,
+ /*ac80:*/ 0x72, 0xef, 0x2b, 0x76, 0xdf, 0x82, 0x74, 0xd2, 0x17, 0xd0, 0xbc, 0xcf, 0x54, 0xb3, 0x6f, 0x34,
+ /*ac90:*/ 0xd7, 0x86, 0x90, 0x63, 0x1f, 0xdc, 0x54, 0xa6, 0xa7, 0x77, 0x4d, 0x84, 0x0d, 0x5a, 0x02, 0xc1,
+ /*aca0:*/ 0x3c, 0xd2, 0xc0, 0xc6, 0x1d, 0xa5, 0x60, 0x9b, 0x22, 0x08, 0x44, 0x01, 0xb8, 0x1a, 0xe4, 0x59,
+ /*acb0:*/ 0x63, 0x2b, 0x48, 0xed, 0xf1, 0x1f, 0x86, 0x18, 0x9c, 0x27, 0xe3, 0x11, 0xb8, 0x03, 0x1a, 0x28,
+ /*acc0:*/ 0xbb, 0x16, 0x90, 0x80, 0x8e, 0xc9, 0xd7, 0x57, 0x33, 0x82, 0x06, 0x44, 0x2b, 0x3f, 0xee, 0xbc,
+ /*acd0:*/ 0x4a, 0x19, 0x73, 0x96, 0x09, 0xb9, 0x26, 0x08, 0x57, 0xe9, 0x66, 0x86, 0x33, 0xfe, 0xf0, 0xad,
+ /*ace0:*/ 0xeb, 0x5f, 0x46, 0xd3, 0x8c, 0x6e, 0xa9, 0xeb, 0x0f, 0x58, 0x27, 0x1d, 0x37, 0x42, 0xd9, 0xbb,
+ /*acf0:*/ 0x65, 0x6d, 0xf0, 0x75, 0x89, 0xfb, 0x5e, 0x4d, 0xd7, 0x6d, 0x09, 0xb4, 0x42, 0x7e, 0x7c, 0x94,
+ /*ad00:*/ 0xa5, 0x34, 0x36, 0x13, 0x88, 0x1a, 0x12, 0x2b, 0x02, 0xd4, 0x38, 0x00, 0x25, 0xc4, 0x95, 0xe6,
+ /*ad10:*/ 0x3c, 0x9b, 0xbe, 0x55, 0x5d, 0x58, 0x6c, 0xef, 0x36, 0xbf, 0xeb, 0x90, 0x74, 0x93, 0x14, 0x07,
+ /*ad20:*/ 0xad, 0xfa, 0x42, 0x13, 0x7b, 0x13, 0x17, 0x1a, 0x9b, 0x0f, 0x36, 0xee, 0x61, 0x76, 0xe2, 0x85,
+ /*ad30:*/ 0x99, 0x42, 0x29, 0x50, 0x20, 0x7e, 0x3f, 0x09, 0xaf, 0x3a, 0xe5, 0x3f, 0x53, 0xf6, 0x76, 0x79,
+ /*ad40:*/ 0xfb, 0x8c, 0x73, 0xc9, 0x83, 0xf6, 0x1c, 0x21, 0xec, 0x05, 0x07, 0x10, 0xbc, 0x16, 0x8e, 0x65,
+ /*ad50:*/ 0x7f, 0xfe, 0x4a, 0x3e, 0xbe, 0xf7, 0x74, 0x47, 0x51, 0x89, 0x5f, 0xad, 0xc1, 0x9e, 0xa1, 0x6a,
+ /*ad60:*/ 0x69, 0x33, 0x5c, 0x10, 0x48, 0x10, 0xbb, 0x49, 0x98, 0x63, 0x04, 0xe4, 0x19, 0xfa, 0x45, 0x93,
+ /*ad70:*/ 0x09, 0x0d, 0xda, 0x37, 0x2e, 0xff, 0x4f, 0xaf, 0xdc, 0x3d, 0x71, 0x3e, 0x0c, 0x97, 0x3b, 0x8f,
+ /*ad80:*/ 0x80, 0xfc, 0x34, 0x24, 0x4e, 0x37, 0xaa, 0x11, 0xd0, 0x4a, 0x57, 0x9b, 0xa6, 0x6c, 0x4d, 0xc1,
+ /*ad90:*/ 0x65, 0x07, 0x6d, 0x1c, 0x9e, 0x06, 0xd9, 0xe3, 0x1a, 0x3f, 0xe0, 0xf1, 0x36, 0x9e, 0x74, 0x65,
+ /*ada0:*/ 0x5c, 0x75, 0xd2, 0xf5, 0xd9, 0xbc, 0x3c, 0x4f, 0x24, 0x4e, 0x04, 0x62, 0x04, 0x97, 0x3e, 0x6e,
+ /*adb0:*/ 0xc4, 0x01, 0x4c, 0x88, 0xfb, 0xb0, 0xdf, 0x7d, 0x45, 0xcd, 0xa0, 0xca, 0x91, 0x96, 0x11, 0x6e,
+ /*adc0:*/ 0x56, 0x5d, 0xe5, 0xd1, 0xf3, 0x2c, 0x4a, 0xf6, 0x07, 0xb3, 0x6d, 0xb6, 0x6b, 0x98, 0x7b, 0x9b,
+ /*add0:*/ 0x80, 0x7a, 0x02, 0x83, 0xc7, 0xef, 0x0e, 0x00, 0x81, 0xfc, 0x95, 0x64, 0xe4, 0xc0, 0xb3, 0xc1,
+ /*ade0:*/ 0x2f, 0xfe, 0x4a, 0x97, 0xa1, 0x1c, 0x68, 0xde, 0xee, 0xc6, 0xcc, 0x23, 0x33, 0x5c, 0x2b, 0xcd,
+ /*adf0:*/ 0xa1, 0x4b, 0xff, 0x97, 0x08, 0x01, 0x51, 0x5a, 0xc1, 0x69, 0x6a, 0xbc, 0xac, 0x3f, 0xc4, 0xf3,
+ /*ae00:*/ 0x5d, 0x75, 0x53, 0x23, 0x8d, 0xb5, 0x43, 0x8d, 0x2f, 0x41, 0x05, 0xd2, 0x7f, 0x88, 0xdd, 0x9e,
+ /*ae10:*/ 0xb8, 0x5b, 0x13, 0x34, 0x1a, 0x74, 0x5c, 0x6e, 0x81, 0xd3, 0x65, 0x6e, 0x02, 0xcf, 0xf1, 0xf2,
+ /*ae20:*/ 0xf2, 0x87, 0xca, 0xab, 0x11, 0x6e, 0xea, 0xf6, 0xa4, 0xa8, 0x82, 0xa8, 0x00, 0xbd, 0xc7, 0x80,
+ /*ae30:*/ 0x4f, 0xeb, 0x73, 0xbc, 0x9f, 0xbb, 0xc4, 0x17, 0x58, 0x68, 0x1f, 0x36, 0xfb, 0x3c, 0xda, 0xf4,
+ /*ae40:*/ 0xf4, 0xea, 0x6a, 0xce, 0x79, 0xe9, 0xb1, 0x83, 0x6d, 0x27, 0x22, 0xdc, 0x01, 0xf8, 0xec, 0x58,
+ /*ae50:*/ 0x6b, 0x58, 0x03, 0x24, 0x50, 0xeb, 0xed, 0xa9, 0x1c, 0x01, 0x1a, 0x7c, 0x50, 0xe3, 0x5e, 0x78,
+ /*ae60:*/ 0x90, 0xe8, 0x50, 0xfd, 0xe8, 0x34, 0xfc, 0x7c, 0x3e, 0x7b, 0x61, 0xd5, 0x93, 0x65, 0x47, 0xed,
+ /*ae70:*/ 0xfe, 0x63, 0xc1, 0xd1, 0x31, 0x86, 0x78, 0xa1, 0x68, 0xee, 0xfa, 0x4f, 0x5c, 0xf2, 0x45, 0x90,
+ /*ae80:*/ 0x7c, 0xb9, 0x6d, 0x98, 0x89, 0x3f, 0x3e, 0xc8, 0x0d, 0x02, 0xa2, 0x2e, 0xfd, 0x96, 0x3e, 0x16,
+ /*ae90:*/ 0xd6, 0xc8, 0x46, 0x89, 0xf5, 0x82, 0x71, 0xe7, 0x93, 0xcb, 0x57, 0x14, 0xce, 0xef, 0x51, 0x53,
+ /*aea0:*/ 0xaa, 0x3d, 0xe7, 0xdc, 0xbf, 0x14, 0xc1, 0x14, 0xdc, 0x24, 0xd1, 0xc9, 0x61, 0xb3, 0x0a, 0x9d,
+ /*aeb0:*/ 0xca, 0xcb, 0x00, 0x49, 0xc0, 0x9a, 0xbe, 0x59, 0x10, 0x9a, 0x0a, 0x75, 0x0a, 0x7a, 0x2d, 0xe2,
+ /*aec0:*/ 0x87, 0xe5, 0xb1, 0x32, 0x55, 0x8d, 0xd2, 0x3a, 0x0b, 0x3b, 0xd9, 0x16, 0xb1, 0x78, 0xa8, 0x83,
+ /*aed0:*/ 0x13, 0x30, 0x2f, 0xf8, 0xa0, 0x91, 0x55, 0xc5, 0x0b, 0x5e, 0x4a, 0x90, 0x1c, 0x10, 0x7c, 0x5a,
+ /*aee0:*/ 0x8e, 0x4b, 0x4b, 0xea, 0x12, 0xe2, 0x51, 0xfa, 0xc4, 0x5a, 0x52, 0x33, 0xff, 0xf9, 0x18, 0xc1,
+ /*aef0:*/ 0x5b, 0xa1, 0x29, 0xeb, 0x3f, 0xab, 0xf8, 0x1c, 0xa2, 0x7e, 0x97, 0xfd, 0x59, 0x04, 0x1a, 0x0c,
+ /*af00:*/ 0x60, 0x5e, 0x3d, 0x23, 0x5e, 0x0b, 0x8e, 0x2b, 0xf5, 0x57, 0xe7, 0x06, 0x71, 0x11, 0x68, 0xb6,
+ /*af10:*/ 0x5a, 0xc4, 0x49, 0xfa, 0x24, 0x17, 0xe7, 0xf7, 0xd2, 0xca, 0xc8, 0xbf, 0x5c, 0x5a, 0x98, 0xe5,
+ /*af20:*/ 0xb8, 0x72, 0x85, 0xb0, 0x8c, 0x4c, 0x49, 0xbc, 0x5f, 0xd5, 0xb3, 0x36, 0xa0, 0xc9, 0x59, 0xbc,
+ /*af30:*/ 0xc8, 0x5e, 0x00, 0xa4, 0x09, 0x95, 0x48, 0x31, 0x96, 0x76, 0x80, 0xee, 0x49, 0x9a, 0xac, 0xe4,
+ /*af40:*/ 0xbe, 0x94, 0xa5, 0xc6, 0x6c, 0xd0, 0xce, 0xcf, 0xa8, 0xdf, 0x61, 0xbb, 0xe5, 0x7a, 0x59, 0xe3,
+ /*af50:*/ 0x7d, 0xad, 0x3b, 0xa9, 0xcc, 0x26, 0xe7, 0x4e, 0x29, 0x5b, 0xed, 0x59, 0x43, 0x70, 0xdd, 0xb6,
+ /*af60:*/ 0xbf, 0x6c, 0xa6, 0x12, 0x87, 0xd0, 0xa2, 0x33, 0xf2, 0x9a, 0x8a, 0x39, 0xca, 0x63, 0x1e, 0x6a,
+ /*af70:*/ 0xf4, 0xf7, 0x4a, 0x97, 0xc6, 0x62, 0x85, 0xb1, 0x98, 0xf4, 0xbd, 0x2d, 0x2c, 0xf7, 0xe8, 0x47,
+ /*af80:*/ 0x73, 0x61, 0xda, 0x0b, 0xca, 0xc7, 0xa8, 0x37, 0x72, 0xdd, 0x08, 0xed, 0xfe, 0xb2, 0xc2, 0xa7,
+ /*af90:*/ 0x1f, 0x30, 0xce, 0x3a, 0x2e, 0xd8, 0x73, 0x77, 0xbf, 0xe1, 0x53, 0xab, 0xcf, 0xbf, 0x1d, 0xa2,
+ /*afa0:*/ 0x7b, 0xe6, 0x93, 0xa8, 0x0b, 0x1d, 0x7b, 0xdb, 0xaa, 0x83, 0x91, 0x76, 0x0b, 0xda, 0x09, 0x17,
+ /*afb0:*/ 0xe6, 0x8a, 0x25, 0x89, 0x1e, 0x9e, 0xe3, 0xec, 0xed, 0x9e, 0xfd, 0x5e, 0xb1, 0x47, 0x78, 0xd9,
+ /*afc0:*/ 0x1e, 0x2a, 0xfe, 0x92, 0x9b, 0x73, 0x70, 0x16, 0x2d, 0xdf, 0x76, 0x18, 0x35, 0x84, 0x40, 0xed,
+ /*afd0:*/ 0x42, 0xb5, 0xa6, 0x89, 0x52, 0x75, 0xf0, 0xbb, 0x20, 0xea, 0xea, 0xec, 0xa2, 0x40, 0xc8, 0x32,
+ /*afe0:*/ 0x82, 0xfb, 0x84, 0x0b, 0x99, 0x22, 0x39, 0x22, 0x0a, 0xde, 0x4f, 0x92, 0x96, 0xd1, 0xa5, 0xf1,
+ /*aff0:*/ 0x6b, 0xf4, 0x01, 0x04, 0x3d, 0x65, 0x70, 0x82, 0xe2, 0x2e, 0x76, 0xfc, 0x25, 0x81, 0x24, 0x59,
+ /*b000:*/ 0x7c, 0x77, 0x24, 0xab, 0x00, 0x06, 0x74, 0x9e, 0xa7, 0x6c, 0xaa, 0x04, 0x30, 0xed, 0x9d, 0xb3,
+ /*b010:*/ 0x56, 0xfc, 0x85, 0x8d, 0xa2, 0x90, 0xc3, 0xcd, 0x08, 0xd2, 0x71, 0xd7, 0xf2, 0x2e, 0x28, 0xfb,
+ /*b020:*/ 0x13, 0x28, 0xfc, 0x43, 0x40, 0x56, 0x80, 0xc4, 0x56, 0xd1, 0x39, 0x96, 0x1f, 0xdc, 0xa8, 0x70,
+ /*b030:*/ 0x32, 0x84, 0x40, 0xa1, 0x98, 0xb6, 0x1e, 0x7f, 0xbc, 0x05, 0xb8, 0x2c, 0x95, 0x26, 0xfd, 0x41,
+ /*b040:*/ 0x20, 0xbb, 0x88, 0x9f, 0x26, 0xf6, 0x4e, 0x99, 0x0e, 0x9c, 0xd9, 0xac, 0xc9, 0xcf, 0x71, 0x31,
+ /*b050:*/ 0xab, 0x6e, 0x05, 0xfd, 0x20, 0x69, 0x50, 0x93, 0x54, 0xe5, 0xc4, 0x0b, 0xc6, 0xa4, 0xd4, 0x00,
+ /*b060:*/ 0xcb, 0x58, 0x27, 0x33, 0x07, 0x01, 0xd6, 0xce, 0x25, 0xdf, 0xf9, 0x36, 0x54, 0x94, 0xf1, 0x40,
+ /*b070:*/ 0x61, 0x69, 0x12, 0x79, 0x5c, 0xb0, 0xf1, 0xba, 0xd2, 0x01, 0x9a, 0xd7, 0x96, 0xbe, 0x34, 0x95,
+ /*b080:*/ 0x06, 0xe7, 0x05, 0xc3, 0x13, 0x58, 0x4e, 0x85, 0xb6, 0xdb, 0x72, 0xba, 0x5e, 0x15, 0xc9, 0x0a,
+ /*b090:*/ 0x62, 0x60, 0x53, 0x3f, 0xad, 0x29, 0x3f, 0xe3, 0xe1, 0xbb, 0x23, 0xcc, 0x13, 0xb9, 0xbd, 0x85,
+ /*b0a0:*/ 0x5d, 0x84, 0x0b, 0x5f, 0x7c, 0x4d, 0x2e, 0x64, 0x41, 0x06, 0x39, 0x71, 0x2b, 0x30, 0x14, 0x59,
+ /*b0b0:*/ 0xfe, 0x18, 0x80, 0x37, 0x17, 0x9e, 0x40, 0xa8, 0x55, 0xf2, 0xf6, 0xcc, 0x4c, 0xad, 0x10, 0x88,
+ /*b0c0:*/ 0x70, 0x6d, 0xcc, 0x69, 0xc9, 0xfd, 0x11, 0xa3, 0xba, 0xd0, 0x6a, 0xe0, 0x65, 0xd1, 0xb8, 0x38,
+ /*b0d0:*/ 0x55, 0xec, 0x1a, 0x81, 0xd0, 0x51, 0x33, 0x31, 0x3b, 0x5a, 0xc9, 0x26, 0xc6, 0xf2, 0x78, 0x2d,
+ /*b0e0:*/ 0x8e, 0x4e, 0x22, 0x8b, 0x0d, 0x74, 0x4d, 0x36, 0x18, 0x45, 0xdc, 0x41, 0x44, 0x35, 0x6a, 0x3b,
+ /*b0f0:*/ 0x66, 0x2c, 0xd4, 0x61, 0x92, 0xb8, 0x48, 0xab, 0xa2, 0xb6, 0x09, 0x7f, 0xa7, 0x91, 0xe9, 0x97,
+ /*b100:*/ 0x53, 0x59, 0x03, 0x08, 0x00, 0x3f, 0x03, 0x1e, 0x05, 0x0e, 0x88, 0x00, 0x01, 0x01, 0xff, 0x0a,
+ /*b110:*/ 0x1f, 0x03, 0xff, 0x04, 0x1e, 0x06, 0x2d, 0x5c, 0x0f, 0x8d, 0x03, 0x01, 0x34, 0xfe, 0x33, 0xff,
+ /*b120:*/ 0x78, 0x43, 0xfd, 0x43, 0x50, 0xc3, 0x38, 0xc7, 0x00, 0x18, 0x20, 0x20, 0x20, 0x20, 0x14, 0x02,
+ /*b130:*/ 0x0c, 0x32, 0xe3, 0xbc, 0x00, 0x00, 0x05, 0x28, 0x0a, 0x2d, 0x00, 0x28, 0x0a, 0x32, 0x00, 0xc4,
+ /*b140:*/ 0x09, 0x3c, 0x00, 0xf0, 0x0a, 0x50, 0x00, 0x1e, 0x1e, 0x8c, 0x00, 0x96, 0x00, 0x14, 0x0a, 0x04,
+ /*b150:*/ 0x29, 0x1a, 0x64, 0x07, 0x66, 0x64, 0xc0, 0x20, 0x02, 0xaf, 0x00, 0x03, 0x0e, 0x1f, 0x08, 0x2a,
+ /*b160:*/ 0x00, 0x20, 0x04, 0x1b, 0x00, 0x80, 0x14, 0xc0, 0xc8, 0xc8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0x38,
+ /*b170:*/ 0x37, 0x35, 0x34, 0x32, 0x31, 0x2f, 0x2d, 0x01, 0x04, 0x07, 0x09, 0x0b, 0x0d, 0x0f, 0x13, 0x00,
+ /*b180:*/ 0x00, 0x00, 0x40, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x20, 0x20, 0x20, 0x20,
+ /*b190:*/ 0x20, 0x20, 0x20, 0x10, 0x5a, 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6d, 0x39, 0x00, 0x0a, 0x00, 0x10,
+ /*b1a0:*/ 0x27, 0x66, 0x12, 0xd4, 0x10, 0xff, 0x1a, 0x00, 0x28, 0x28, 0x1c, 0x26, 0x66, 0x66, 0x66, 0x66,
+ /*b1b0:*/ 0x66, 0x66, 0x66, 0xff, 0xc8, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x11,
+ /*b1c0:*/ 0x04, 0x20, 0x40, 0x03, 0x00, 0x1f, 0x00, 0x1d, 0x2d, 0x1d, 0x2b, 0x1d, 0x28, 0x1d, 0x2c, 0x1d,
+ /*b1d0:*/ 0x20, 0xdc, 0x73, 0xfe, 0x73, 0xe5, 0xcd, 0x0d, 0x04, 0x02, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+ /*b1e0:*/ 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15,
+ /*b1f0:*/ 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26,
+ /*b200:*/ 0x27, 0x29, 0x2a, 0x2d, 0x2b, 0x28, 0x2c, 0x20, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x14,
+ /*b210:*/ 0x12, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02,
+ /*b220:*/ 0x01, 0x00, 0x1d, 0x66, 0x66, 0x6d, 0x6d, 0x73, 0x73, 0x7a, 0x7a, 0x80, 0x80, 0x86, 0x86, 0x8d,
+ /*b230:*/ 0x8d, 0x93, 0x93, 0x9a, 0x9a, 0xa0, 0xa0, 0xa6, 0xa6, 0xad, 0xad, 0xb3, 0xb3, 0x80, 0x80, 0x80,
+ /*b240:*/ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /*b250:*/ 0x80, 0x0a, 0x1c, 0x2b, 0x1e, 0x0a, 0x80, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b260:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b270:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b280:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b290:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x48, 0xb2,
+ /*b300:*/ 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b310:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b320:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b330:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b340:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b350:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b360:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b370:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b380:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b390:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b400:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b410:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b420:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b430:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b440:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ /*b450:*/ 0x3f, 0x03, 0x1e, 0x05, 0x0e, 0x08, 0x00, 0x19, 0x19, 0x00, 0x10, 0xe2, 0x04, 0xb6, 0x08, 0x1e,
+ /*b460:*/ 0x05, 0x28, 0xf5, 0x28, 0x1e, 0x05, 0x01, 0x30, 0x00, 0x30, 0x00, 0x00, 0x50, 0x00, 0x50, 0xf0,
+ /*b470:*/ 0xd2, 0xf0, 0xd2, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0xc0, 0x32, 0x70, 0x00, 0x00,
+ /*b480:*/ 0x00, 0x80, 0x04, 0x2e, 0x1b, 0x64, 0x07, 0x00, 0x00, 0x56, 0x35, 0x05, 0x10, 0x00, 0x00, 0x0b,
+ /*b490:*/ 0x20, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x37, 0x33,
+ /*b4a0:*/ 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x03, 0x0f, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf0,
+ /*b4b0:*/ 0x15, 0x1b, 0x2e, 0x49, 0x40, 0xff, 0x0b, 0x20, 0x0c, 0x18, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+ /*b4c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b4d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x88, 0x55,
+ /*b4e0:*/ 0x15, 0x21, 0x11, 0x92, 0x87, 0x4f, 0x13, 0x01, 0x01, 0x89, 0x00, 0x4b, 0x00, 0x01, 0x34, 0x00,
+ /*b4f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b500:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b510:*/ 0x00, 0x02, 0x5e, 0x01, 0x03, 0x0e, 0x1f, 0x00, 0xde, 0x01, 0x19, 0x04, 0x1b, 0x00, 0x10, 0x0a,
+ /*b520:*/ 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b530:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x80, 0x05, 0x00, 0x00,
+ /*b540:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00,
+ /*b550:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x28, 0x00, 0x77, 0x18, 0x80, 0x18, 0x80, 0x1a,
+ /*b560:*/ 0x01, 0x19, 0x3f, 0x4d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x6d, 0x10, 0x0a, 0x00, 0x00,
+ /*b570:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x04, 0x40, 0x40, 0x03, 0x00, 0x2e, 0x1b,
+ /*b580:*/ 0x44, 0x00, 0x19, 0x01, 0x00, 0xbe, 0x00, 0xde, 0x3f, 0xd0, 0x80, 0x08, 0x03, 0x00, 0x00, 0x00,
+ /*b590:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7d, 0x10, 0x00, 0x01, 0x54, 0x00,
+ /*b5f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b600:*/ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x51, 0x51,
+ /*b610:*/ 0x51, 0x51, 0x51, 0xcd, 0x0d, 0x04, 0x00, 0x00, 0x1c, 0x80, 0x00, 0x04, 0xff, 0x2e, 0x1b, 0x05,
+ /*b620:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b630:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b640:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b650:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b660:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b670:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b680:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b690:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6e0:*/ 0x00, 0x00, 0x00, 0x1d, 0x1a, 0x16, 0x00, 0x01, 0x55, 0x1b, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x00,
+ /*b6f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b700:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b710:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b720:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x32, 0x00, 0x1e, 0x04, 0x80, 0xc0, 0x04,
+ /*b730:*/ 0x28, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b740:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b750:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b760:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b770:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b780:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b790:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x28, 0x00, 0x00, 0x51, 0x00,
+ /*b7f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b800:*/ 0xff};
+#endif
+
+const char *rmi_config_ver = "N51XX_SY_1216";
+
+const u8 rmi_fw[] = {
+ /*0000:*/ 0x02, 0x62, 0x3e, 0x94, 0x00, 0x00, 0x00, 0x05, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+ /*0010:*/ 0x53, 0x37, 0x33, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0030:*/ 0x44, 0x53, 0x34, 0x20, 0x52, 0x33, 0x2e, 0x35, 0x2e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0040:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0050:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0060:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0070:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0080:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*0090:*/ 0x49, 0x32, 0x43, 0x00, 0x04, 0x00, 0xff, 0x00, 0x0c, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*00a0:*/ 0x49, 0x32, 0x43, 0x00, 0x04, 0x00, 0xff, 0x00, 0x0c, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*00b0:*/ 0x09, 0xd9, 0x94, 0xe6, 0x23, 0xe3, 0x8d, 0xce, 0x50, 0x96, 0xc3, 0x4b, 0x8f, 0x1a, 0x4f, 0x6d,
+ /*00c0:*/ 0x57, 0x05, 0x48, 0x7c, 0xd7, 0x03, 0xb0, 0x50, 0xe0, 0x77, 0x3c, 0x8b, 0x79, 0xf6, 0x71, 0x75,
+ /*00d0:*/ 0xca, 0xec, 0xb0, 0x31, 0x53, 0xaa, 0x37, 0xe9, 0x19, 0x47, 0x46, 0x84, 0xba, 0x28, 0x18, 0xe9,
+ /*00e0:*/ 0x51, 0x89, 0xe7, 0xce, 0x3e, 0x64, 0x26, 0xa6, 0x25, 0x31, 0xc5, 0x0d, 0x9a, 0xa9, 0x93, 0xfa,
+ /*00f0:*/ 0x8a, 0x67, 0xd2, 0x1b, 0x4b, 0x66, 0x4d, 0x12, 0xa8, 0x62, 0x72, 0xf6, 0xed, 0xb7, 0x09, 0x4e,
+ /*0100:*/ 0xce, 0xd6, 0xc5, 0x28, 0x69, 0xd2, 0xa9, 0x7d, 0x39, 0xf4, 0xe4, 0x78, 0x56, 0xd2, 0x53, 0x4e,
+ /*0110:*/ 0x35, 0x9f, 0xa7, 0xc9, 0x55, 0x7b, 0xec, 0xb3, 0xd2, 0xb0, 0x47, 0x38, 0x01, 0x7e, 0xf6, 0x5d,
+ /*0120:*/ 0xa3, 0xef, 0xc0, 0x55, 0xf3, 0xca, 0x62, 0x4f, 0xc8, 0x13, 0xbd, 0x20, 0xe6, 0x3a, 0xac, 0xcd,
+ /*0130:*/ 0x2b, 0x4b, 0x2c, 0x18, 0x21, 0x16, 0xf3, 0xb6, 0xaa, 0x41, 0xe2, 0x66, 0xfc, 0x6f, 0x1f, 0xce,
+ /*0140:*/ 0x14, 0xd1, 0x9c, 0x00, 0x78, 0x74, 0x94, 0xa6, 0xd2, 0x4e, 0xff, 0x63, 0x8f, 0x42, 0xcb, 0x54,
+ /*0150:*/ 0xcc, 0x1b, 0x3f, 0x78, 0xf2, 0xf6, 0x8a, 0xbe, 0x7f, 0x80, 0x69, 0x1a, 0x1a, 0xff, 0xc2, 0x2a,
+ /*0160:*/ 0x12, 0x01, 0xc8, 0x11, 0xe3, 0xe2, 0x83, 0xc2, 0x71, 0x24, 0x74, 0x0e, 0x6b, 0xd3, 0x26, 0xb3,
+ /*0170:*/ 0xda, 0xdc, 0xfd, 0x86, 0xe6, 0xdc, 0xb0, 0x14, 0xc0, 0x87, 0x68, 0x6d, 0x15, 0x39, 0x99, 0x81,
+ /*0180:*/ 0xf4, 0x8f, 0xfa, 0x4b, 0x47, 0x53, 0x99, 0x05, 0xe8, 0x9f, 0xd7, 0x8c, 0x0a, 0xdd, 0x12, 0x95,
+ /*0190:*/ 0xc6, 0xd0, 0xe3, 0xf9, 0x2c, 0xb0, 0xee, 0x4f, 0x50, 0x51, 0x9e, 0x2c, 0x7f, 0x07, 0xd7, 0xd7,
+ /*01a0:*/ 0xa6, 0xfc, 0x58, 0x56, 0x65, 0x04, 0x49, 0x73, 0x05, 0x3e, 0xd2, 0xe9, 0x37, 0xb8, 0xd7, 0xbc,
+ /*01b0:*/ 0x79, 0x5f, 0x8c, 0xc7, 0x28, 0xe6, 0x39, 0xef, 0x29, 0x7f, 0x26, 0x52, 0xd8, 0xda, 0x99, 0x4c,
+ /*01c0:*/ 0x6b, 0x6e, 0x7a, 0xd3, 0x9e, 0x75, 0xca, 0x55, 0xb2, 0x29, 0x88, 0xb8, 0x0b, 0x1d, 0x1c, 0x81,
+ /*01d0:*/ 0x98, 0x15, 0xf7, 0x59, 0x1d, 0x73, 0xc3, 0x8d, 0x42, 0x5e, 0xce, 0x78, 0x9b, 0x36, 0x49, 0xbe,
+ /*01e0:*/ 0xad, 0xc9, 0x81, 0xa4, 0x7e, 0x4c, 0xcb, 0x35, 0x52, 0x17, 0xd7, 0x73, 0x29, 0x4e, 0x81, 0xdf,
+ /*01f0:*/ 0x66, 0x04, 0x1d, 0x49, 0x3f, 0xa0, 0xf2, 0x2f, 0x42, 0xd0, 0xf4, 0xe9, 0x49, 0xae, 0x52, 0xf7,
+ /*0200:*/ 0xce, 0x67, 0x45, 0x5c, 0x59, 0x91, 0xb0, 0x83, 0xc0, 0x2e, 0xf4, 0x77, 0xcb, 0x65, 0xb5, 0xd3,
+ /*0210:*/ 0x18, 0x15, 0x9e, 0x05, 0x30, 0x8f, 0xb7, 0xb8, 0x40, 0x1f, 0x71, 0xb1, 0x0f, 0x81, 0x03, 0x89,
+ /*0220:*/ 0xb7, 0x6d, 0xef, 0x46, 0x6e, 0x45, 0x46, 0xc5, 0xd3, 0x94, 0x92, 0x41, 0xca, 0xc5, 0x32, 0xac,
+ /*0230:*/ 0x34, 0x10, 0x2b, 0x1a, 0x4f, 0xec, 0x94, 0xcf, 0x91, 0xd9, 0x80, 0xf1, 0x60, 0x9d, 0xe7, 0x63,
+ /*0240:*/ 0x51, 0xa7, 0xec, 0xe6, 0x1d, 0xf8, 0x38, 0xc7, 0xec, 0xe7, 0x69, 0x08, 0x02, 0x7b, 0x09, 0x89,
+ /*0250:*/ 0x84, 0x9a, 0xbd, 0x1f, 0x04, 0x9f, 0xf3, 0x20, 0xc8, 0x23, 0x4c, 0xd7, 0x0a, 0x64, 0x47, 0x43,
+ /*0260:*/ 0xb6, 0xc8, 0xad, 0xb7, 0xd5, 0xa4, 0xb0, 0xea, 0x57, 0x8d, 0xe9, 0x4e, 0x18, 0x81, 0x08, 0x26,
+ /*0270:*/ 0x68, 0x66, 0xe6, 0x0b, 0xb2, 0x5d, 0xf5, 0xc3, 0xc1, 0xc1, 0x25, 0x84, 0xdd, 0x00, 0x34, 0x10,
+ /*0280:*/ 0x94, 0xb6, 0xaf, 0x9f, 0x6a, 0xd5, 0x34, 0x1e, 0x9a, 0x42, 0xd0, 0xa7, 0xc9, 0xd7, 0x3f, 0xc3,
+ /*0290:*/ 0x43, 0xf2, 0x80, 0x94, 0x2e, 0xb9, 0xdb, 0x60, 0x76, 0xc5, 0xf5, 0x6f, 0xe8, 0x83, 0x96, 0x1b,
+ /*02a0:*/ 0xe4, 0xdc, 0x2e, 0x2b, 0xb5, 0x80, 0x99, 0x1c, 0x26, 0xda, 0x52, 0x46, 0x1f, 0x54, 0x1c, 0x0e,
+ /*02b0:*/ 0xee, 0x3a, 0xd2, 0x3f, 0x8f, 0x98, 0x5b, 0xf3, 0x5b, 0xa2, 0x33, 0x03, 0xef, 0x98, 0x35, 0xed,
+ /*02c0:*/ 0x73, 0xd5, 0xe3, 0x66, 0xca, 0xd7, 0x62, 0x65, 0x93, 0xe2, 0x4d, 0x2c, 0x3c, 0xa9, 0x47, 0xfa,
+ /*02d0:*/ 0x3d, 0x52, 0x65, 0x92, 0xc1, 0x57, 0xf4, 0x92, 0xff, 0x86, 0x14, 0x22, 0xb1, 0x5b, 0x72, 0xc3,
+ /*02e0:*/ 0x17, 0x47, 0xb6, 0x8d, 0xb4, 0x55, 0xf9, 0xf9, 0x89, 0xf2, 0xfa, 0xc5, 0xc9, 0xc7, 0xe0, 0xd6,
+ /*02f0:*/ 0x2c, 0xba, 0x56, 0xc1, 0xc6, 0x0f, 0x69, 0x51, 0x0e, 0x7c, 0x1e, 0x6a, 0x5d, 0x2f, 0x2d, 0x26,
+ /*0300:*/ 0xaf, 0xa0, 0x68, 0x71, 0x08, 0xf3, 0x10, 0xea, 0xb1, 0xc8, 0x48, 0x14, 0x73, 0xcb, 0x9c, 0x33,
+ /*0310:*/ 0x9d, 0x4d, 0x2b, 0x1d, 0x18, 0xc2, 0x61, 0xbe, 0xde, 0x02, 0x96, 0x68, 0xf0, 0xaa, 0x9c, 0xb8,
+ /*0320:*/ 0x2a, 0x94, 0xf2, 0xc1, 0xc3, 0xdb, 0xf9, 0x6e, 0x5b, 0x6e, 0xb5, 0xb4, 0xa3, 0x0e, 0xb6, 0xb9,
+ /*0330:*/ 0x95, 0x0e, 0x18, 0x69, 0x40, 0x4c, 0xcb, 0xf7, 0xf3, 0xd6, 0x53, 0x16, 0xc1, 0xcf, 0xc0, 0x34,
+ /*0340:*/ 0xcb, 0xe9, 0x2b, 0x3f, 0xdd, 0xe0, 0xa4, 0x4e, 0x97, 0x41, 0x72, 0x15, 0xfc, 0x7a, 0x40, 0x84,
+ /*0350:*/ 0x96, 0xeb, 0x45, 0x16, 0x96, 0xcb, 0x72, 0x8d, 0xb6, 0xca, 0x00, 0x58, 0x56, 0x88, 0x47, 0x39,
+ /*0360:*/ 0x90, 0x34, 0x76, 0x5c, 0x46, 0x70, 0x96, 0x89, 0xd0, 0x34, 0x60, 0xbd, 0x7d, 0x0e, 0xdb, 0xa6,
+ /*0370:*/ 0x0f, 0x17, 0x49, 0x67, 0x27, 0x87, 0x06, 0xae, 0x69, 0x19, 0x89, 0xcd, 0xb2, 0x68, 0xa1, 0x1b,
+ /*0380:*/ 0x52, 0xb4, 0x1d, 0xfa, 0xc4, 0x5b, 0xf1, 0xe8, 0x1f, 0xef, 0xa7, 0x5e, 0x87, 0x18, 0x0d, 0xdb,
+ /*0390:*/ 0xdf, 0xc9, 0xf3, 0x03, 0x3c, 0xfd, 0x9f, 0x0b, 0xa0, 0x17, 0x2b, 0x4b, 0xad, 0x14, 0x66, 0xb5,
+ /*03a0:*/ 0x31, 0x7b, 0x5f, 0xc7, 0x03, 0xa7, 0x83, 0x9c, 0xab, 0x7b, 0x58, 0x1b, 0x39, 0xb8, 0xc4, 0x44,
+ /*03b0:*/ 0xdd, 0xa1, 0xf8, 0xe8, 0x9e, 0x51, 0x92, 0xb1, 0xd5, 0xfa, 0x8e, 0x53, 0x7a, 0x51, 0xd9, 0x1b,
+ /*03c0:*/ 0xa2, 0x4a, 0x7f, 0xc6, 0xf7, 0x58, 0x64, 0xe3, 0x8d, 0x35, 0xbf, 0xb0, 0xd6, 0x11, 0x88, 0x05,
+ /*03d0:*/ 0x17, 0x26, 0x53, 0x5a, 0x02, 0x3d, 0xe1, 0x35, 0x2a, 0x81, 0xd3, 0xac, 0xfd, 0xb6, 0xdc, 0xf0,
+ /*03e0:*/ 0x35, 0x02, 0x6f, 0x72, 0xcd, 0x53, 0xf3, 0xbf, 0x18, 0x3e, 0x4f, 0x64, 0xee, 0x02, 0xfc, 0xdd,
+ /*03f0:*/ 0x78, 0xb8, 0x46, 0x06, 0x46, 0x0a, 0x13, 0xa0, 0x07, 0xc2, 0x42, 0x2a, 0xd2, 0xb3, 0x5d, 0x74,
+ /*0400:*/ 0x8b, 0x1d, 0x47, 0x64, 0x9b, 0x78, 0x86, 0x62, 0x89, 0x5f, 0xdd, 0x65, 0x16, 0x89, 0x46, 0x73,
+ /*0410:*/ 0xe0, 0x54, 0x1d, 0xf1, 0xc2, 0x20, 0x12, 0x49, 0x6e, 0x45, 0xf1, 0xce, 0x25, 0x3e, 0xb5, 0x1b,
+ /*0420:*/ 0x09, 0xd6, 0xc7, 0xb4, 0xe7, 0x79, 0xfb, 0x48, 0x3e, 0x7a, 0x86, 0xa5, 0xc1, 0xca, 0x99, 0xb9,
+ /*0430:*/ 0xeb, 0xe1, 0x06, 0x4b, 0xe5, 0xf0, 0xa2, 0xf0, 0xd9, 0xff, 0x6b, 0x76, 0x9f, 0x86, 0x6e, 0x6f,
+ /*0440:*/ 0xe6, 0x7a, 0xe8, 0x74, 0x77, 0x25, 0xc1, 0x86, 0x2a, 0xc7, 0x1e, 0xe4, 0xb5, 0x88, 0x3a, 0xd7,
+ /*0450:*/ 0x43, 0x1e, 0xc9, 0x66, 0xa9, 0x0b, 0x7a, 0x9b, 0x8f, 0x9f, 0xb5, 0x9a, 0x89, 0x5f, 0x2f, 0xa7,
+ /*0460:*/ 0xe1, 0x1d, 0x19, 0x20, 0x6f, 0x17, 0x71, 0xd1, 0x33, 0x63, 0xdf, 0xed, 0x82, 0x08, 0x28, 0xab,
+ /*0470:*/ 0x3c, 0xb5, 0x73, 0x84, 0x3f, 0x78, 0x19, 0x26, 0x5b, 0x6d, 0x08, 0x8f, 0xde, 0x61, 0x87, 0x24,
+ /*0480:*/ 0x60, 0xd9, 0x85, 0xa9, 0x88, 0x5b, 0xcf, 0x56, 0xd6, 0x23, 0x88, 0xfc, 0xf3, 0x2c, 0xae, 0x7c,
+ /*0490:*/ 0x31, 0x33, 0xee, 0xc6, 0xf0, 0xff, 0xae, 0x56, 0x90, 0xba, 0x15, 0xbe, 0xfb, 0x18, 0xae, 0x8b,
+ /*04a0:*/ 0xe9, 0x34, 0x9d, 0xbb, 0xbe, 0xf6, 0xea, 0x90, 0x87, 0xf3, 0x55, 0xd5, 0xca, 0x3e, 0xc3, 0x04,
+ /*04b0:*/ 0x17, 0xab, 0x3c, 0x9e, 0x2a, 0x11, 0x07, 0x24, 0xbe, 0x3c, 0x4a, 0x2a, 0x11, 0xe1, 0x48, 0x52,
+ /*04c0:*/ 0x93, 0x5f, 0xee, 0x8f, 0x57, 0x3e, 0x06, 0x53, 0xc5, 0xc7, 0x16, 0x60, 0x01, 0x83, 0xc1, 0xb5,
+ /*04d0:*/ 0x9b, 0xf5, 0xaf, 0x0e, 0xe3, 0x03, 0x80, 0xb0, 0x42, 0x71, 0xf1, 0x14, 0xa0, 0x21, 0x3e, 0xd8,
+ /*04e0:*/ 0xb9, 0x15, 0x8c, 0x8a, 0xdc, 0x48, 0x51, 0xdc, 0xe4, 0x9c, 0x2e, 0x5f, 0x41, 0x55, 0x4f, 0x10,
+ /*04f0:*/ 0x4d, 0x5a, 0x4c, 0x32, 0xfa, 0x6e, 0x54, 0x63, 0x57, 0x43, 0x19, 0x0f, 0x97, 0x18, 0x4e, 0xa9,
+ /*0500:*/ 0xde, 0x48, 0x20, 0x1f, 0xc5, 0x24, 0x15, 0xe0, 0x56, 0x58, 0x99, 0x2d, 0xf8, 0xb2, 0x3d, 0xc9,
+ /*0510:*/ 0x39, 0xe0, 0xfb, 0xf0, 0x3c, 0x67, 0xc1, 0x98, 0x5f, 0x13, 0x52, 0x10, 0x0e, 0xe2, 0x64, 0xfc,
+ /*0520:*/ 0x22, 0x38, 0x9a, 0x59, 0x78, 0x7f, 0x0d, 0x8c, 0xc3, 0xb6, 0x3a, 0x76, 0x1b, 0x91, 0x66, 0xaa,
+ /*0530:*/ 0x02, 0x90, 0x41, 0xfb, 0x50, 0x6f, 0xb9, 0xba, 0x6b, 0x6a, 0xc8, 0x2f, 0xdb, 0x06, 0x9f, 0x1c,
+ /*0540:*/ 0xc2, 0xec, 0x4e, 0xa2, 0x9a, 0xbf, 0x24, 0xb6, 0x56, 0x7e, 0x0e, 0xd8, 0x6a, 0x83, 0x7f, 0x35,
+ /*0550:*/ 0xfc, 0xe8, 0xf4, 0xc6, 0x49, 0x4d, 0xeb, 0xa3, 0x99, 0xb7, 0x07, 0xff, 0x25, 0x4a, 0x72, 0xd9,
+ /*0560:*/ 0xe7, 0xce, 0x3d, 0x37, 0x9b, 0x77, 0x4a, 0x06, 0x1b, 0x41, 0xc9, 0xae, 0x2e, 0x51, 0x41, 0x94,
+ /*0570:*/ 0x14, 0x08, 0xc4, 0x74, 0x7c, 0xa2, 0xfe, 0xa1, 0x4e, 0x6b, 0x31, 0x0e, 0xb2, 0x41, 0xd1, 0x44,
+ /*0580:*/ 0xde, 0xc6, 0x53, 0xd3, 0x14, 0xec, 0x71, 0x19, 0x91, 0x3d, 0x5b, 0xb0, 0xd0, 0x89, 0x5d, 0xa0,
+ /*0590:*/ 0x0c, 0x16, 0xb7, 0x5c, 0x6c, 0xbb, 0x17, 0xb3, 0xd0, 0xea, 0x14, 0x4c, 0x80, 0xa3, 0xb3, 0xe4,
+ /*05a0:*/ 0x4e, 0xdf, 0x8d, 0x11, 0xc1, 0x4a, 0x2b, 0x72, 0x4a, 0x9f, 0x09, 0x8d, 0x2d, 0x74, 0x3d, 0x62,
+ /*05b0:*/ 0x0e, 0x9c, 0xa0, 0x2b, 0x9f, 0xc1, 0x7e, 0xeb, 0x6f, 0x55, 0x8e, 0x4f, 0xe1, 0x74, 0xb4, 0x53,
+ /*05c0:*/ 0x0f, 0x32, 0xf4, 0x99, 0xec, 0x0e, 0xc4, 0x38, 0x27, 0xd2, 0xd0, 0x6f, 0x6e, 0x34, 0xba, 0x1b,
+ /*05d0:*/ 0x60, 0xbd, 0xcb, 0x06, 0xfe, 0x2e, 0xd1, 0x81, 0x56, 0x9d, 0xcf, 0x68, 0x3e, 0xa5, 0xa0, 0x1a,
+ /*05e0:*/ 0x7e, 0x52, 0x0f, 0xad, 0x55, 0x6f, 0x00, 0xc6, 0xd4, 0x24, 0x74, 0x75, 0x2e, 0x5b, 0x61, 0xd6,
+ /*05f0:*/ 0x1d, 0xf9, 0xab, 0xdf, 0x58, 0xfb, 0xac, 0x07, 0x57, 0x22, 0x3d, 0xdd, 0x11, 0xe5, 0xa2, 0x2d,
+ /*0600:*/ 0xeb, 0x99, 0x3c, 0xb3, 0x65, 0x08, 0x79, 0xe7, 0x82, 0x65, 0x8f, 0x6e, 0x43, 0xa8, 0xa0, 0x51,
+ /*0610:*/ 0xde, 0xd1, 0xf4, 0xb4, 0x38, 0xa7, 0xb8, 0x68, 0x92, 0xb9, 0x99, 0x2d, 0x9f, 0x2b, 0x0c, 0xe7,
+ /*0620:*/ 0x31, 0xcd, 0x05, 0xcb, 0x97, 0xb8, 0xf1, 0xf2, 0xfc, 0x2b, 0xb0, 0x17, 0xcd, 0x7b, 0x62, 0x6a,
+ /*0630:*/ 0x0d, 0x30, 0xaa, 0x14, 0xd6, 0xd2, 0xd7, 0x66, 0xc0, 0x1f, 0x57, 0xe9, 0xd8, 0xe5, 0x4d, 0xe3,
+ /*0640:*/ 0x23, 0xaf, 0xa2, 0xbb, 0x01, 0xda, 0xcd, 0x3e, 0xf8, 0x4a, 0x6d, 0x11, 0xe5, 0x8f, 0x5f, 0x8e,
+ /*0650:*/ 0x08, 0x30, 0x98, 0x6a, 0xad, 0x73, 0x4e, 0xcf, 0xd6, 0xc8, 0x51, 0x73, 0xf4, 0x3e, 0xd5, 0x8e,
+ /*0660:*/ 0x7c, 0x26, 0x9c, 0xcc, 0xe8, 0xf4, 0xfb, 0x69, 0x43, 0xac, 0x08, 0x60, 0xae, 0x90, 0xb6, 0x84,
+ /*0670:*/ 0x40, 0xc8, 0x73, 0xbb, 0xfc, 0xff, 0xf3, 0x16, 0xaf, 0x21, 0xd2, 0x4f, 0x29, 0x8e, 0xb3, 0x69,
+ /*0680:*/ 0xe6, 0xfe, 0x47, 0x85, 0xdd, 0x0b, 0x4d, 0x12, 0x8b, 0x1b, 0x55, 0xdf, 0x65, 0xb5, 0x4a, 0xdd,
+ /*0690:*/ 0x4d, 0x67, 0x68, 0xf2, 0x38, 0xd5, 0x73, 0x00, 0xbe, 0x37, 0x2f, 0xab, 0xda, 0x25, 0x6d, 0x26,
+ /*06a0:*/ 0x62, 0x47, 0xa9, 0x73, 0x6b, 0x87, 0x26, 0x66, 0xb6, 0x4f, 0xee, 0x15, 0x7f, 0x3e, 0xc1, 0xe4,
+ /*06b0:*/ 0xa9, 0x13, 0xd3, 0x56, 0xb7, 0x1c, 0x81, 0x21, 0x2a, 0xa6, 0x1c, 0x3f, 0x58, 0xe2, 0xd9, 0x38,
+ /*06c0:*/ 0xc2, 0x0d, 0x49, 0x3e, 0x8c, 0xdf, 0x6b, 0x56, 0x76, 0xc4, 0xe6, 0x9d, 0x4f, 0x5b, 0x77, 0x0f,
+ /*06d0:*/ 0x18, 0x38, 0xeb, 0x07, 0xc1, 0x00, 0x0c, 0xfa, 0x8e, 0x60, 0x6b, 0xde, 0xcc, 0xf5, 0xd1, 0x2a,
+ /*06e0:*/ 0x0d, 0x0f, 0x01, 0x93, 0xf9, 0x12, 0x55, 0x3f, 0x51, 0x4e, 0x84, 0xcd, 0x89, 0x3e, 0xf8, 0xee,
+ /*06f0:*/ 0xca, 0x1c, 0x5c, 0xa8, 0x9c, 0x3d, 0x5d, 0xad, 0x12, 0x1a, 0xf5, 0x28, 0xb3, 0x57, 0xb7, 0xb7,
+ /*0700:*/ 0x64, 0x74, 0xcb, 0x92, 0x4a, 0xdf, 0x9b, 0xb2, 0xfa, 0x08, 0xa1, 0xcc, 0xde, 0x6d, 0x0b, 0x9e,
+ /*0710:*/ 0x4e, 0x6d, 0xde, 0xfc, 0x69, 0xe2, 0xaa, 0x4e, 0x49, 0x10, 0xd9, 0xec, 0x58, 0x7c, 0x1e, 0x84,
+ /*0720:*/ 0x8d, 0x50, 0x6c, 0x90, 0x5f, 0x76, 0x67, 0x77, 0x66, 0x95, 0x54, 0xec, 0xda, 0xc6, 0xd4, 0x44,
+ /*0730:*/ 0x0a, 0xe5, 0xbe, 0x52, 0x08, 0xdf, 0x44, 0x62, 0x77, 0x38, 0x15, 0x73, 0xa2, 0xcc, 0xa3, 0x06,
+ /*0740:*/ 0xd0, 0xb2, 0x7b, 0xe2, 0xdd, 0x55, 0xd2, 0xa3, 0x65, 0x51, 0x8f, 0x39, 0x0c, 0x3e, 0x19, 0xf6,
+ /*0750:*/ 0x52, 0xa6, 0x4c, 0xf0, 0xb1, 0x2c, 0xe2, 0x71, 0x89, 0x40, 0x92, 0x7b, 0x11, 0xa0, 0x76, 0xfa,
+ /*0760:*/ 0x07, 0x23, 0x2d, 0x8e, 0xb1, 0xbc, 0x5e, 0x04, 0xdb, 0xba, 0xa0, 0x2e, 0xc0, 0xc5, 0xac, 0x03,
+ /*0770:*/ 0x65, 0xbe, 0x68, 0x95, 0xbe, 0x0d, 0x6e, 0xe4, 0x3e, 0xbe, 0x88, 0x47, 0x2f, 0xb8, 0xd9, 0xf6,
+ /*0780:*/ 0x59, 0x2b, 0xe0, 0x27, 0xc6, 0xbc, 0xf4, 0x0d, 0x01, 0x46, 0x7a, 0x70, 0xfe, 0x0c, 0xcc, 0x30,
+ /*0790:*/ 0x97, 0xa7, 0x19, 0x00, 0x5a, 0x5b, 0x3a, 0xfa, 0xc8, 0x07, 0x33, 0xa3, 0x31, 0x3f, 0x0c, 0xe1,
+ /*07a0:*/ 0x81, 0xa7, 0xef, 0x18, 0x7f, 0x78, 0x9d, 0x3f, 0x79, 0xe2, 0x59, 0x02, 0x55, 0xe0, 0xae, 0x2b,
+ /*07b0:*/ 0xaf, 0xdf, 0x2d, 0x7b, 0x3d, 0xd8, 0x1a, 0x28, 0xfb, 0xcd, 0x01, 0x12, 0xb8, 0xbf, 0x13, 0x45,
+ /*07c0:*/ 0xfd, 0x46, 0xb3, 0x8d, 0x46, 0x74, 0x76, 0xfd, 0x35, 0x7c, 0xe4, 0x6e, 0xe9, 0xc5, 0x42, 0x60,
+ /*07d0:*/ 0x0d, 0xfd, 0x2e, 0xf1, 0xcb, 0x30, 0xb1, 0x4e, 0x23, 0xf0, 0x68, 0x99, 0x95, 0xba, 0x8d, 0x5f,
+ /*07e0:*/ 0x08, 0xf7, 0x43, 0xed, 0xa1, 0x12, 0x1b, 0x54, 0x27, 0x78, 0x31, 0x19, 0xf7, 0xbb, 0x5d, 0xdd,
+ /*07f0:*/ 0x89, 0x97, 0x69, 0x27, 0x86, 0x00, 0x6a, 0x3b, 0xc5, 0xef, 0x13, 0xa0, 0x70, 0x91, 0x5c, 0xfa,
+ /*0800:*/ 0x05, 0xc6, 0xfa, 0x45, 0x1a, 0xbd, 0x58, 0x86, 0xfd, 0x0d, 0x51, 0x5d, 0xc6, 0x21, 0x55, 0x15,
+ /*0810:*/ 0x18, 0x11, 0x42, 0x81, 0xde, 0xbb, 0x44, 0x37, 0xaf, 0x59, 0xa5, 0x6d, 0x2a, 0xf8, 0x97, 0xc3,
+ /*0820:*/ 0x47, 0x5a, 0x09, 0x01, 0xfd, 0x6c, 0xcb, 0x59, 0xfd, 0x48, 0x36, 0xaf, 0x7a, 0x13, 0x62, 0xa3,
+ /*0830:*/ 0xc0, 0xa9, 0xe5, 0xa6, 0xbc, 0xf5, 0xd6, 0xa0, 0xa4, 0x52, 0xa4, 0xb8, 0x6f, 0x9d, 0x05, 0x30,
+ /*0840:*/ 0x71, 0x59, 0x44, 0xac, 0xa1, 0x81, 0x1d, 0xc3, 0xc7, 0xe6, 0xee, 0xde, 0xed, 0xd5, 0xf5, 0x67,
+ /*0850:*/ 0x11, 0x04, 0xc2, 0x33, 0xe2, 0x9c, 0x26, 0xb5, 0x05, 0x80, 0xa4, 0x51, 0xca, 0xd7, 0xc6, 0xda,
+ /*0860:*/ 0x08, 0xe6, 0xa1, 0xc5, 0xc2, 0x25, 0xc1, 0xa7, 0x5c, 0x84, 0x67, 0xbf, 0x4b, 0x69, 0xf3, 0xc3,
+ /*0870:*/ 0x4c, 0xfe, 0xc5, 0xa3, 0xdb, 0x05, 0xe4, 0x17, 0x94, 0x0c, 0x05, 0xf2, 0x73, 0x9b, 0xf0, 0xe5,
+ /*0880:*/ 0x6b, 0x4e, 0x44, 0xcc, 0x4c, 0xcd, 0x40, 0x4d, 0x18, 0x2f, 0xe0, 0xa8, 0x8c, 0xb8, 0x6d, 0x02,
+ /*0890:*/ 0xc8, 0x13, 0x1f, 0x46, 0x2c, 0x42, 0x63, 0x9c, 0xb3, 0xb8, 0xc3, 0x60, 0xb8, 0xfe, 0x84, 0x5c,
+ /*08a0:*/ 0xa0, 0x6d, 0xba, 0x03, 0xf7, 0x98, 0xfd, 0x44, 0xaa, 0xcf, 0x24, 0x5b, 0x51, 0x77, 0x57, 0x63,
+ /*08b0:*/ 0x3f, 0x19, 0x7a, 0x7f, 0x56, 0x35, 0x2a, 0x32, 0xd8, 0x2c, 0x3a, 0x2a, 0x32, 0xf7, 0x5a, 0xd6,
+ /*08c0:*/ 0x1a, 0xb7, 0x81, 0xb1, 0xd1, 0x4f, 0xb2, 0xa6, 0xea, 0xde, 0x1d, 0x9b, 0x12, 0x31, 0x3f, 0x9d,
+ /*08d0:*/ 0xd6, 0x68, 0x60, 0x0d, 0x12, 0x57, 0xa9, 0x0e, 0xab, 0x0a, 0xe2, 0x46, 0xf8, 0x22, 0x06, 0x3f,
+ /*08e0:*/ 0xa5, 0x21, 0xa1, 0xea, 0xe6, 0xd1, 0x74, 0x03, 0x14, 0xad, 0x4e, 0x60, 0x8a, 0xe1, 0x59, 0x07,
+ /*08f0:*/ 0x45, 0x73, 0x5c, 0x13, 0x98, 0xf1, 0x18, 0x5f, 0x26, 0xdb, 0x2c, 0xa2, 0x43, 0xe6, 0x9a, 0xf9,
+ /*0900:*/ 0x90, 0x16, 0xaf, 0x08, 0x7e, 0xa3, 0xba, 0x46, 0x95, 0xce, 0x18, 0x2e, 0x32, 0x73, 0x63, 0x0a,
+ /*0910:*/ 0xe4, 0xfb, 0x81, 0x51, 0x0f, 0x81, 0x8a, 0x6e, 0x79, 0xd3, 0x53, 0x5c, 0x95, 0x2d, 0xc3, 0x86,
+ /*0920:*/ 0x62, 0xd8, 0xd5, 0x64, 0xe3, 0xda, 0xb0, 0xa6, 0x3d, 0x12, 0xb4, 0xfc, 0x26, 0x84, 0x8c, 0xcf,
+ /*0930:*/ 0x08, 0x84, 0xab, 0xe2, 0x0e, 0x18, 0xf5, 0x6a, 0x7b, 0xcc, 0xd5, 0x27, 0x9d, 0x2b, 0x66, 0x6e,
+ /*0940:*/ 0x9e, 0xfe, 0x7d, 0x30, 0x2d, 0x77, 0x33, 0x0e, 0xc4, 0x74, 0xc2, 0x12, 0x10, 0x5c, 0xf4, 0xb5,
+ /*0950:*/ 0xe7, 0xbb, 0x96, 0xd8, 0xc6, 0x07, 0x22, 0x31, 0xd6, 0x7a, 0xd6, 0xa6, 0x86, 0xa7, 0x53, 0x31,
+ /*0960:*/ 0xff, 0x41, 0x87, 0xad, 0xda, 0x77, 0xe7, 0xaf, 0x36, 0xc9, 0xda, 0x41, 0x2e, 0x9d, 0xd0, 0x08,
+ /*0970:*/ 0x02, 0x81, 0xc1, 0x88, 0xac, 0xb4, 0x40, 0xb8, 0x4f, 0x8b, 0xb4, 0xc7, 0x7e, 0x65, 0x58, 0x68,
+ /*0980:*/ 0x04, 0x17, 0x69, 0xbd, 0xb5, 0xf2, 0x66, 0xf3, 0xab, 0x7b, 0x2c, 0xba, 0x63, 0x47, 0x9d, 0x17,
+ /*0990:*/ 0xce, 0x6d, 0x77, 0xf6, 0x25, 0x14, 0x58, 0x1c, 0xa6, 0xbc, 0xd1, 0xa6, 0x74, 0xed, 0x49, 0x55,
+ /*09a0:*/ 0x6d, 0x46, 0xfe, 0xdd, 0xea, 0x7b, 0x50, 0xf9, 0xb2, 0x5b, 0xa5, 0x2e, 0x7b, 0x90, 0x24, 0x51,
+ /*09b0:*/ 0xda, 0x35, 0x01, 0x31, 0x15, 0x15, 0xba, 0x83, 0x9b, 0x82, 0x1a, 0xe0, 0x20, 0x2a, 0xb1, 0xd7,
+ /*09c0:*/ 0x1b, 0x46, 0xb8, 0xea, 0xc2, 0xb8, 0x2d, 0x44, 0xe0, 0x0d, 0xd6, 0x3c, 0x9e, 0xe2, 0xcf, 0x44,
+ /*09d0:*/ 0x1d, 0x24, 0x58, 0xb0, 0x68, 0x0a, 0xfe, 0x05, 0x36, 0x8a, 0x96, 0x91, 0x40, 0xfa, 0x12, 0xb8,
+ /*09e0:*/ 0xd0, 0xf1, 0x6b, 0xd4, 0x76, 0x4e, 0x62, 0x7d, 0xf6, 0x8e, 0xe8, 0x77, 0x48, 0x02, 0xef, 0x6f,
+ /*09f0:*/ 0xac, 0xc6, 0xd9, 0x21, 0x96, 0x91, 0xcd, 0xf1, 0xa6, 0xe1, 0xd5, 0xd0, 0x6d, 0x62, 0x95, 0xbf,
+ /*0a00:*/ 0xf6, 0x91, 0x7b, 0xf0, 0xd6, 0x63, 0x6d, 0x5c, 0xd3, 0x9d, 0x8f, 0xe7, 0x3e, 0x2a, 0x82, 0xc6,
+ /*0a10:*/ 0x38, 0x24, 0xb0, 0x2c, 0x7d, 0x8f, 0x00, 0x26, 0xbd, 0x4c, 0xf0, 0x45, 0xc6, 0x16, 0xdd, 0x82,
+ /*0a20:*/ 0xa3, 0x8b, 0x32, 0xe4, 0xd8, 0xa8, 0x71, 0xca, 0x1d, 0x02, 0x4f, 0x58, 0x50, 0xd4, 0x8d, 0x21,
+ /*0a30:*/ 0x3a, 0x68, 0x49, 0x34, 0xac, 0x55, 0xbb, 0xc4, 0x3d, 0x9e, 0x2a, 0x90, 0x6d, 0x4b, 0x15, 0x6b,
+ /*0a40:*/ 0xe6, 0xe2, 0x04, 0x78, 0xe6, 0x8f, 0xd4, 0xf7, 0xce, 0x64, 0x95, 0xfb, 0xc7, 0x77, 0x6e, 0x4f,
+ /*0a50:*/ 0xea, 0x44, 0x2f, 0x34, 0x67, 0xbc, 0xef, 0xba, 0xe5, 0x02, 0xa0, 0x87, 0x26, 0x4f, 0x40, 0x95,
+ /*0a60:*/ 0x9d, 0x63, 0xcb, 0xc2, 0xdd, 0xf2, 0x31, 0x4f, 0x28, 0xee, 0x12, 0x8a, 0x5e, 0x05, 0xad, 0xd6,
+ /*0a70:*/ 0x55, 0x16, 0xfc, 0x3f, 0x5d, 0x35, 0x57, 0xdc, 0xef, 0x33, 0x98, 0x31, 0xb7, 0xc1, 0xe4, 0x05,
+ /*0a80:*/ 0x28, 0x17, 0xf0, 0x0c, 0x0e, 0x92, 0xf4, 0xa7, 0x02, 0x57, 0xb3, 0x9f, 0xcb, 0xd4, 0x83, 0x41,
+ /*0a90:*/ 0x50, 0xbe, 0xba, 0xe4, 0x3a, 0xdc, 0xe4, 0xc5, 0xab, 0x5b, 0xa5, 0x47, 0x81, 0xc3, 0x8b, 0x34,
+ /*0aa0:*/ 0x2b, 0xe7, 0x52, 0x4a, 0x0d, 0x78, 0x57, 0x1c, 0xa6, 0x50, 0x6c, 0xe0, 0x19, 0xc0, 0x12, 0xa1,
+ /*0ab0:*/ 0x0c, 0x54, 0x53, 0x89, 0xff, 0xbd, 0xd1, 0x2c, 0xb3, 0x59, 0xd9, 0x43, 0xc2, 0xd5, 0x92, 0xab,
+ /*0ac0:*/ 0xe6, 0xc9, 0xfa, 0x39, 0xec, 0x29, 0xfd, 0x17, 0xf4, 0x87, 0x3b, 0x1f, 0x16, 0x22, 0x5d, 0x1b,
+ /*0ad0:*/ 0x49, 0x95, 0x59, 0xe5, 0xa6, 0x7f, 0xb0, 0x25, 0x38, 0x34, 0x2d, 0x10, 0x62, 0x20, 0x3c, 0x55,
+ /*0ae0:*/ 0x8a, 0x5e, 0x1d, 0x31, 0x45, 0x23, 0xa9, 0x62, 0x2b, 0x35, 0x3f, 0x60, 0xe3, 0xb7, 0xf0, 0x85,
+ /*0af0:*/ 0xcc, 0x0b, 0xba, 0xa9, 0x1b, 0xde, 0x36, 0x65, 0x11, 0x9e, 0x69, 0x01, 0xfd, 0x3b, 0xb0, 0xa9,
+ /*0b00:*/ 0x99, 0x37, 0x01, 0xcf, 0x08, 0x35, 0x1b, 0x15, 0x36, 0x55, 0x40, 0x29, 0xc0, 0x67, 0x3d, 0x2e,
+ /*0b10:*/ 0xd3, 0xe1, 0x27, 0x5b, 0x43, 0x0d, 0xec, 0xa8, 0x1c, 0x2f, 0x75, 0x73, 0xc9, 0x91, 0x4c, 0x1b,
+ /*0b20:*/ 0xe0, 0x75, 0xe2, 0xcb, 0xcc, 0x15, 0x58, 0x84, 0x32, 0x88, 0xec, 0x1d, 0x68, 0x89, 0xed, 0xc5,
+ /*0b30:*/ 0xb5, 0xcf, 0x7c, 0xa8, 0xe4, 0x14, 0x8f, 0x76, 0x7f, 0xc3, 0xd0, 0xde, 0xd8, 0x59, 0xb1, 0x1d,
+ /*0b40:*/ 0xc8, 0x72, 0x68, 0x7c, 0x2a, 0x6a, 0xc2, 0x45, 0xf2, 0xbb, 0xe6, 0x48, 0x30, 0x0f, 0x37, 0xa1,
+ /*0b50:*/ 0x71, 0x5e, 0x98, 0xa3, 0x7d, 0x53, 0x9c, 0x21, 0xdd, 0xf6, 0x75, 0x90, 0xcd, 0xd8, 0x09, 0x9b,
+ /*0b60:*/ 0x0f, 0x36, 0xda, 0x1c, 0xf9, 0x18, 0xa3, 0xc2, 0x2b, 0xf0, 0xec, 0x0f, 0xff, 0x04, 0xf6, 0xfc,
+ /*0b70:*/ 0x39, 0x93, 0x96, 0x93, 0x5d, 0xac, 0x8a, 0x08, 0xc3, 0x10, 0xe0, 0xfc, 0xf9, 0x28, 0x97, 0x0d,
+ /*0b80:*/ 0x69, 0xa2, 0x55, 0x7c, 0x39, 0x66, 0xb5, 0xaf, 0x88, 0x7b, 0x56, 0x1e, 0x5b, 0xbf, 0x51, 0xf5,
+ /*0b90:*/ 0x75, 0x71, 0x8d, 0x2c, 0xf1, 0x6e, 0x23, 0x93, 0xbc, 0x4d, 0x0b, 0x82, 0x73, 0x57, 0x14, 0x62,
+ /*0ba0:*/ 0x53, 0x75, 0xd5, 0x75, 0xed, 0x96, 0x4e, 0x62, 0xf4, 0x26, 0x85, 0x33, 0x6d, 0x3f, 0xf8, 0x8b,
+ /*0bb0:*/ 0xcd, 0x71, 0x27, 0x83, 0xd5, 0x55, 0x2c, 0x3a, 0x2f, 0xa6, 0x52, 0xc4, 0xf5, 0xfa, 0x21, 0xc1,
+ /*0bc0:*/ 0xbe, 0xbe, 0x02, 0x7f, 0xc2, 0xf6, 0x8c, 0xf5, 0xa7, 0x4f, 0x7d, 0xaa, 0x0d, 0xd1, 0x50, 0x15,
+ /*0bd0:*/ 0xda, 0x9e, 0x94, 0x99, 0x40, 0xb2, 0x40, 0xf3, 0xc7, 0x0f, 0x3f, 0x65, 0x32, 0xd6, 0x87, 0xdc,
+ /*0be0:*/ 0x54, 0x27, 0xac, 0xd9, 0x5b, 0xa1, 0x8d, 0x7f, 0x7e, 0x6f, 0x71, 0xa0, 0xee, 0x56, 0x2d, 0x58,
+ /*0bf0:*/ 0x85, 0x1f, 0x59, 0xf0, 0x52, 0xf3, 0x76, 0x46, 0xe0, 0xd6, 0x71, 0xf7, 0xb2, 0x4f, 0xc2, 0xa6,
+ /*0c00:*/ 0xe6, 0x15, 0xa0, 0x5a, 0x9c, 0x13, 0xbd, 0x46, 0x44, 0xa8, 0xd2, 0x44, 0xf8, 0xec, 0xe4, 0xd1,
+ /*0c10:*/ 0xa2, 0x9f, 0x5b, 0xda, 0x80, 0x80, 0x37, 0x1e, 0x99, 0xbe, 0xf7, 0x3a, 0xf1, 0xa8, 0x3d, 0x16,
+ /*0c20:*/ 0x90, 0x5f, 0xb0, 0xa7, 0x04, 0x8d, 0x21, 0xc5, 0xa3, 0x75, 0xaf, 0x7f, 0x54, 0xe5, 0x91, 0xaf,
+ /*0c30:*/ 0x05, 0xf1, 0xc3, 0xf7, 0x9e, 0xf5, 0x22, 0x31, 0xc9, 0xa9, 0x23, 0x60, 0x18, 0x3f, 0xc2, 0x55,
+ /*0c40:*/ 0x69, 0xbe, 0x13, 0xc3, 0x22, 0x9c, 0xb7, 0x26, 0x79, 0x06, 0xdf, 0x6e, 0x37, 0x79, 0xd9, 0x88,
+ /*0c50:*/ 0xdf, 0xb3, 0x21, 0xc0, 0xff, 0x78, 0xdf, 0x0f, 0x58, 0x59, 0x09, 0xc5, 0x48, 0x6a, 0xc4, 0x67,
+ /*0c60:*/ 0x89, 0x88, 0x8e, 0x22, 0x9a, 0x0e, 0xb2, 0x82, 0x29, 0xb0, 0x2e, 0xd4, 0xaa, 0x7e, 0x82, 0xfa,
+ /*0c70:*/ 0x58, 0x3e, 0x63, 0x5c, 0x53, 0x6d, 0xbf, 0xbd, 0xe0, 0x68, 0x0a, 0xca, 0x6e, 0x4c, 0xc8, 0x62,
+ /*0c80:*/ 0xe5, 0x45, 0xa3, 0x1f, 0xf1, 0xe1, 0x0d, 0xee, 0xd2, 0xff, 0xbb, 0x18, 0x80, 0x2e, 0xc0, 0xba,
+ /*0c90:*/ 0x59, 0xe7, 0x51, 0x1c, 0xf0, 0x26, 0x04, 0x43, 0x7b, 0xc5, 0xec, 0x74, 0x89, 0x27, 0x7c, 0xcf,
+ /*0ca0:*/ 0x99, 0xbe, 0xe7, 0x7d, 0x5b, 0x2f, 0x4b, 0xa8, 0xae, 0xb9, 0xe9, 0x04, 0xa3, 0x28, 0x9b, 0x60,
+ /*0cb0:*/ 0x6e, 0x3b, 0x4b, 0x1e, 0x14, 0x02, 0x6b, 0x90, 0x5f, 0x54, 0xa5, 0x8e, 0x29, 0x7f, 0xcc, 0xa2,
+ /*0cc0:*/ 0x43, 0xd6, 0x19, 0xfc, 0xef, 0x65, 0x3f, 0xff, 0x85, 0xb8, 0xcd, 0x50, 0x17, 0x33, 0x00, 0xce,
+ /*0cd0:*/ 0x8c, 0xd9, 0xe1, 0x7f, 0x2d, 0x53, 0x2b, 0xe7, 0x6b, 0xe3, 0x38, 0x39, 0xbd, 0x96, 0xe6, 0x1a,
+ /*0ce0:*/ 0x9b, 0x9a, 0x75, 0xdc, 0x59, 0xd4, 0x7c, 0x90, 0xbd, 0x20, 0x72, 0xa2, 0x6b, 0x34, 0x86, 0x98,
+ /*0cf0:*/ 0x91, 0xa4, 0xf8, 0xa8, 0xaf, 0x54, 0x8a, 0x0f, 0x0a, 0xcc, 0x3d, 0x9a, 0x26, 0xbe, 0x1d, 0x3f,
+ /*0d00:*/ 0x8b, 0x32, 0x78, 0x47, 0x2b, 0xb3, 0x12, 0x5f, 0xf2, 0xb8, 0x63, 0x2a, 0xd3, 0x4e, 0xc1, 0xbb,
+ /*0d10:*/ 0x24, 0x9a, 0xac, 0x8c, 0x34, 0xe3, 0x03, 0x81, 0xbd, 0xdf, 0x5f, 0xae, 0xa4, 0x29, 0x9a, 0x17,
+ /*0d20:*/ 0x11, 0x31, 0xc7, 0xba, 0xcf, 0xed, 0x48, 0x68, 0x7f, 0x85, 0xfe, 0xdb, 0xfe, 0x50, 0x86, 0xe6,
+ /*0d30:*/ 0xbb, 0x68, 0x44, 0xa6, 0xb6, 0x5b, 0xe3, 0xf4, 0x84, 0x32, 0x3d, 0x7c, 0x4c, 0xd8, 0xf3, 0xe5,
+ /*0d40:*/ 0xa0, 0x3b, 0x18, 0x91, 0x7a, 0xe7, 0x56, 0x5f, 0xa1, 0xd6, 0xf0, 0xbf, 0x23, 0xf0, 0x89, 0x26,
+ /*0d50:*/ 0x03, 0xf8, 0x5e, 0xc6, 0x55, 0xb4, 0x78, 0x25, 0xb1, 0x4b, 0x32, 0x1b, 0xf7, 0x67, 0x37, 0xae,
+ /*0d60:*/ 0xc6, 0x23, 0x0e, 0x85, 0x90, 0x15, 0x3e, 0x38, 0xb4, 0x42, 0xc0, 0x77, 0xe6, 0x52, 0xa1, 0xc8,
+ /*0d70:*/ 0x64, 0x96, 0x63, 0x20, 0x14, 0x9c, 0xe8, 0xc8, 0x88, 0x24, 0xa3, 0x40, 0xd1, 0xb2, 0x7f, 0xed,
+ /*0d80:*/ 0x4a, 0xb8, 0x8e, 0x71, 0x73, 0x58, 0x7d, 0x51, 0x7e, 0xde, 0x58, 0x64, 0x6f, 0xa9, 0x19, 0xa1,
+ /*0d90:*/ 0x0e, 0x7f, 0x20, 0x6e, 0xfa, 0xfb, 0x9f, 0xc6, 0xd3, 0xc5, 0x4d, 0xd2, 0x1b, 0x5e, 0x8a, 0x14,
+ /*0da0:*/ 0xb9, 0x6a, 0xcf, 0xf6, 0x2c, 0xa0, 0x85, 0xdd, 0xa4, 0xa1, 0x0d, 0x75, 0xd0, 0x75, 0xa1, 0x07,
+ /*0db0:*/ 0xf4, 0x45, 0x09, 0x7a, 0xbd, 0x00, 0x03, 0xbd, 0x4c, 0x42, 0x49, 0xb2, 0x3c, 0x09, 0xd8, 0x87,
+ /*0dc0:*/ 0xfb, 0xa1, 0xc2, 0x1a, 0xd7, 0x16, 0xae, 0x3a, 0x0b, 0x61, 0x4b, 0x34, 0x98, 0x32, 0x77, 0x23,
+ /*0dd0:*/ 0xc8, 0x0b, 0x8b, 0x81, 0xed, 0xc1, 0x56, 0x8a, 0xcc, 0x79, 0x03, 0x58, 0x01, 0x57, 0xc1, 0x94,
+ /*0de0:*/ 0x60, 0x2c, 0x0a, 0x56, 0x12, 0xf1, 0xd8, 0xb8, 0xaa, 0x4e, 0xb5, 0x7b, 0xb5, 0xe6, 0x35, 0x1c,
+ /*0df0:*/ 0x20, 0x87, 0x40, 0x52, 0xd0, 0xe1, 0xf8, 0x59, 0xb3, 0xaf, 0x45, 0x0b, 0xce, 0xb0, 0xf7, 0x48,
+ /*0e00:*/ 0x3d, 0x60, 0x16, 0xbb, 0x1c, 0x3d, 0xf8, 0x10, 0xba, 0xfa, 0x86, 0x47, 0xb8, 0x9f, 0x89, 0x43,
+ /*0e10:*/ 0xc9, 0x3f, 0xa7, 0x5f, 0x3b, 0xa6, 0x30, 0x60, 0xce, 0x7a, 0x29, 0x87, 0xf1, 0x38, 0xde, 0x17,
+ /*0e20:*/ 0x70, 0xc5, 0x10, 0xb9, 0xa4, 0x0e, 0x13, 0x8b, 0xa9, 0x5c, 0x8a, 0xe8, 0x11, 0xfe, 0xf0, 0x0e,
+ /*0e30:*/ 0x63, 0x22, 0xc5, 0xeb, 0x16, 0x7a, 0x8e, 0xbc, 0x90, 0x54, 0x6e, 0x54, 0x8f, 0x41, 0xb8, 0x13,
+ /*0e40:*/ 0xe8, 0x2e, 0x7a, 0xaf, 0xf6, 0xcf, 0x11, 0xf8, 0xd8, 0xdf, 0x06, 0x00, 0x76, 0xa3, 0x05, 0x0a,
+ /*0e50:*/ 0x92, 0x37, 0xb9, 0x87, 0x84, 0x53, 0xfe, 0x6f, 0x27, 0xdc, 0xa0, 0x75, 0xd8, 0x83, 0xa7, 0xa2,
+ /*0e60:*/ 0x65, 0xa9, 0x45, 0x3f, 0xfe, 0xf2, 0xef, 0x4e, 0xc0, 0xc9, 0x9f, 0x58, 0xa6, 0xfd, 0x62, 0xc8,
+ /*0e70:*/ 0x69, 0x36, 0xd5, 0xad, 0x64, 0xc1, 0xdb, 0x55, 0x29, 0xe4, 0x37, 0xe8, 0xde, 0x1e, 0x1c, 0x80,
+ /*0e80:*/ 0x58, 0xb3, 0x31, 0x7a, 0x14, 0xbd, 0xde, 0x3c, 0xf9, 0x64, 0xbb, 0xb4, 0x2d, 0x4e, 0x78, 0x52,
+ /*0e90:*/ 0xe6, 0xba, 0x90, 0xf7, 0x36, 0xc3, 0x56, 0xaf, 0xf4, 0x06, 0xe3, 0xee, 0x12, 0x3e, 0x35, 0x41,
+ /*0ea0:*/ 0xcd, 0xe7, 0x3d, 0xec, 0x02, 0x8f, 0x88, 0x23, 0x7e, 0x84, 0x81, 0x24, 0x49, 0x46, 0xe9, 0x4c,
+ /*0eb0:*/ 0xaf, 0x7c, 0x81, 0x34, 0x63, 0xcd, 0xe0, 0x55, 0xa1, 0xdb, 0x2e, 0x8a, 0xb7, 0x08, 0x89, 0x22,
+ /*0ec0:*/ 0x01, 0xeb, 0xa8, 0x20, 0x90, 0xc5, 0x43, 0x51, 0xd1, 0x49, 0xa7, 0x80, 0xd8, 0xb3, 0xda, 0xcb,
+ /*0ed0:*/ 0x06, 0x68, 0x27, 0x0f, 0x8b, 0xc5, 0x85, 0x19, 0x8b, 0x72, 0x7f, 0x9c, 0x01, 0x9e, 0x9c, 0x89,
+ /*0ee0:*/ 0xb2, 0x95, 0xe0, 0xcb, 0x15, 0xd8, 0xc7, 0x60, 0x48, 0x93, 0x24, 0x18, 0x78, 0xc0, 0x8b, 0x40,
+ /*0ef0:*/ 0x5a, 0x2f, 0xe9, 0xc9, 0xc4, 0xec, 0xb3, 0x26, 0xb5, 0xdf, 0x88, 0x1b, 0xf3, 0x4f, 0x0e, 0xe4,
+ /*0f00:*/ 0xc0, 0x7c, 0x07, 0xf1, 0xcd, 0xa6, 0xb2, 0x8e, 0x53, 0x74, 0x42, 0x89, 0xb5, 0x8c, 0xa7, 0xcc,
+ /*0f10:*/ 0x22, 0x2a, 0x15, 0x6c, 0xc8, 0x45, 0xdf, 0x88, 0xbc, 0xec, 0x64, 0xea, 0x73, 0x22, 0xde, 0xe4,
+ /*0f20:*/ 0xb1, 0x55, 0x66, 0x37, 0xbc, 0x8d, 0x67, 0x60, 0x13, 0xcb, 0xc2, 0x3e, 0xe1, 0x5f, 0x9c, 0x90,
+ /*0f30:*/ 0xc8, 0xa5, 0x8e, 0x70, 0x48, 0xf3, 0xcd, 0xcf, 0x3b, 0x73, 0xfc, 0x98, 0x0f, 0xa0, 0x2e, 0x6e,
+ /*0f40:*/ 0x53, 0xfc, 0xcb, 0xd9, 0x2e, 0x7e, 0x9e, 0x2f, 0x66, 0x23, 0xd4, 0xe3, 0xb5, 0xda, 0xb0, 0xef,
+ /*0f50:*/ 0x7c, 0x28, 0xc4, 0xe3, 0x6b, 0xeb, 0x28, 0x06, 0x83, 0xcd, 0x58, 0xd1, 0xa4, 0x08, 0x73, 0x36,
+ /*0f60:*/ 0x7d, 0x87, 0xdf, 0x67, 0x72, 0x23, 0x8a, 0x8d, 0xce, 0x4d, 0xcd, 0x95, 0x7e, 0xec, 0x8e, 0x9e,
+ /*0f70:*/ 0x0c, 0x21, 0x09, 0x89, 0x4b, 0x2e, 0x86, 0xd7, 0x1b, 0x7e, 0xbc, 0x67, 0x17, 0x4d, 0x18, 0xa7,
+ /*0f80:*/ 0xba, 0xca, 0x25, 0x30, 0x2d, 0x72, 0xb1, 0xfe, 0x49, 0xd9, 0xdc, 0x54, 0x8e, 0x81, 0x47, 0x50,
+ /*0f90:*/ 0x03, 0x95, 0xb4, 0xb6, 0x37, 0x36, 0xeb, 0xc4, 0xc3, 0x9d, 0x90, 0xaf, 0x24, 0x03, 0x6d, 0x78,
+ /*0fa0:*/ 0x35, 0x12, 0x17, 0x64, 0xb3, 0xb5, 0x20, 0xf5, 0xc6, 0xc1, 0xd2, 0xdd, 0xa8, 0x5f, 0xdb, 0xc8,
+ /*0fb0:*/ 0xc2, 0xa9, 0xbd, 0x38, 0x9a, 0xc2, 0x75, 0x29, 0xca, 0xb2, 0x5f, 0x02, 0x9d, 0x02, 0x25, 0x12,
+ /*0fc0:*/ 0x2a, 0x90, 0x56, 0x93, 0x1b, 0xcd, 0x5c, 0x75, 0x73, 0xdc, 0xeb, 0x03, 0x62, 0x52, 0x02, 0x6d,
+ /*0fd0:*/ 0x14, 0x20, 0xeb, 0x16, 0x2a, 0x08, 0x1c, 0x0f, 0xbb, 0x36, 0x0a, 0x0a, 0x9f, 0x44, 0x1c, 0xb5,
+ /*0fe0:*/ 0xb7, 0x60, 0x82, 0xcc, 0x33, 0xa0, 0x53, 0xb3, 0xb7, 0xe5, 0xc5, 0x9a, 0xb7, 0xa3, 0xf2, 0x2e,
+ /*0ff0:*/ 0x85, 0x8b, 0xc9, 0x5c, 0xe9, 0x22, 0x82, 0xb1, 0x23, 0x7f, 0x39, 0xf6, 0xd8, 0x6e, 0x1a, 0xb4,
+ /*1000:*/ 0xb8, 0xe2, 0x6f, 0x88, 0xe1, 0x34, 0x48, 0x15, 0xb1, 0x37, 0x42, 0x64, 0xe1, 0xb6, 0xc6, 0x7a,
+ /*1010:*/ 0x21, 0x55, 0x20, 0x11, 0x29, 0x1b, 0xc3, 0x81, 0x1e, 0x43, 0x28, 0xb0, 0x2c, 0x0c, 0x71, 0x04,
+ /*1020:*/ 0x24, 0xde, 0xbb, 0x81, 0xac, 0xb7, 0xb5, 0xda, 0xf9, 0x85, 0x78, 0x2c, 0xdb, 0xfb, 0x1f, 0xed,
+ /*1030:*/ 0x95, 0xd6, 0x67, 0x04, 0xa7, 0xde, 0xc4, 0x00, 0x6a, 0xf4, 0x97, 0xe6, 0xa5, 0x46, 0x9f, 0x42,
+ /*1040:*/ 0x68, 0x79, 0xea, 0xcd, 0xfa, 0xb1, 0xb0, 0x97, 0xfc, 0x78, 0xc3, 0xa8, 0xcc, 0xdd, 0x09, 0x9b,
+ /*1050:*/ 0x93, 0x5b, 0x0a, 0xd2, 0xe4, 0x42, 0x98, 0x61, 0xbe, 0xa2, 0xbe, 0x8f, 0xf4, 0x1f, 0x1a, 0xeb,
+ /*1060:*/ 0xda, 0x59, 0x1e, 0xe5, 0x8e, 0x41, 0x3c, 0x96, 0x14, 0xb9, 0xb0, 0x16, 0x07, 0x38, 0xa4, 0xc9,
+ /*1070:*/ 0xb3, 0xff, 0xb4, 0xf1, 0xed, 0xe7, 0xe5, 0x4e, 0x21, 0x90, 0x5f, 0x35, 0x6e, 0x9f, 0xfb, 0xd3,
+ /*1080:*/ 0x57, 0x86, 0x12, 0xe1, 0xde, 0x74, 0x33, 0xe5, 0xf3, 0x29, 0x3f, 0xe6, 0x49, 0x30, 0xae, 0xaa,
+ /*1090:*/ 0x62, 0xaf, 0xd5, 0x1f, 0xc8, 0xca, 0x4f, 0xea, 0x00, 0xda, 0x4e, 0xba, 0x21, 0x5f, 0xeb, 0x85,
+ /*10a0:*/ 0xa9, 0x77, 0xce, 0x2e, 0x98, 0xa5, 0xa0, 0x22, 0x12, 0x9f, 0x15, 0xaa, 0x25, 0xd9, 0x65, 0x03,
+ /*10b0:*/ 0x7b, 0xda, 0x3e, 0x29, 0xb1, 0x94, 0x5f, 0x9b, 0x7d, 0x0e, 0xf0, 0xe3, 0x29, 0x95, 0xef, 0xc5,
+ /*10c0:*/ 0x0b, 0x97, 0x61, 0x8b, 0xa2, 0x03, 0xe1, 0x33, 0x76, 0x0c, 0xb7, 0xe6, 0xaa, 0x4d, 0x66, 0xc1,
+ /*10d0:*/ 0x5c, 0x9c, 0xa9, 0x36, 0xef, 0xda, 0xe4, 0xad, 0xed, 0xbf, 0x93, 0x9a, 0xdd, 0xa4, 0x52, 0xcb,
+ /*10e0:*/ 0x5f, 0xdb, 0x61, 0x82, 0xfe, 0x77, 0x86, 0x28, 0x33, 0x3d, 0x90, 0xbb, 0x86, 0x6a, 0xb3, 0x15,
+ /*10f0:*/ 0x2f, 0x91, 0xfe, 0x99, 0x18, 0xb9, 0xe9, 0x47, 0x27, 0xfe, 0x78, 0x07, 0x33, 0xa0, 0x96, 0xb8,
+ /*1100:*/ 0x06, 0x09, 0x74, 0xad, 0x1a, 0x75, 0x49, 0xbe, 0x35, 0xe9, 0x18, 0x1a, 0x79, 0x31, 0x9f, 0xf2,
+ /*1110:*/ 0x35, 0x4f, 0xa9, 0xf4, 0xfa, 0x64, 0x20, 0xbb, 0x0d, 0x65, 0x1f, 0x80, 0x5b, 0x8d, 0x83, 0xca,
+ /*1120:*/ 0x2a, 0x42, 0xea, 0x84, 0x15, 0x6e, 0xd3, 0xbb, 0x51, 0xe5, 0x65, 0x95, 0x44, 0x09, 0x56, 0x50,
+ /*1130:*/ 0x53, 0x8f, 0xbb, 0xd9, 0xf7, 0x5d, 0xc9, 0xdf, 0x16, 0x95, 0xa6, 0x8a, 0x22, 0x29, 0xd9, 0x00,
+ /*1140:*/ 0xcf, 0x55, 0xab, 0xc8, 0x90, 0x96, 0x8f, 0x07, 0xdd, 0x0b, 0x40, 0xb6, 0xde, 0xd3, 0x1d, 0x96,
+ /*1150:*/ 0x58, 0xff, 0x89, 0x25, 0xfb, 0x2d, 0x0c, 0xcc, 0x05, 0xb4, 0xe9, 0x47, 0x60, 0xeb, 0xb4, 0xe2,
+ /*1160:*/ 0x24, 0x99, 0xb9, 0xf1, 0x88, 0xba, 0x1e, 0xd3, 0x16, 0xa7, 0x6e, 0x44, 0x48, 0x57, 0x90, 0x04,
+ /*1170:*/ 0x37, 0x94, 0xd3, 0x42, 0x1c, 0xbd, 0x51, 0x2c, 0x0d, 0x4f, 0x71, 0xf8, 0x98, 0x71, 0x16, 0x48,
+ /*1180:*/ 0x53, 0x2b, 0x62, 0x90, 0x21, 0xc3, 0xbf, 0xf4, 0x83, 0x11, 0xb5, 0xd4, 0xc7, 0xe4, 0x73, 0x65,
+ /*1190:*/ 0xed, 0x01, 0x49, 0xf2, 0xb1, 0x1b, 0xb8, 0x6c, 0xce, 0x55, 0xe1, 0xa7, 0x58, 0xf0, 0x2f, 0x24,
+ /*11a0:*/ 0xf5, 0xc1, 0x26, 0x02, 0x78, 0x66, 0x48, 0x7d, 0x2f, 0xb9, 0x81, 0x4b, 0xac, 0x73, 0x6d, 0x0d,
+ /*11b0:*/ 0xfd, 0xe6, 0x27, 0xa8, 0x3a, 0xcd, 0x35, 0x4d, 0xa4, 0xc8, 0xf7, 0xb5, 0x2c, 0xa0, 0xa6, 0x4a,
+ /*11c0:*/ 0x57, 0xb8, 0x62, 0xb3, 0xd7, 0xd4, 0x2a, 0xa9, 0xa5, 0x93, 0x5b, 0x23, 0x0f, 0x88, 0xb3, 0x69,
+ /*11d0:*/ 0xd2, 0x89, 0x21, 0x66, 0x9c, 0x4a, 0x40, 0xce, 0x22, 0x0d, 0xcf, 0xff, 0x1b, 0x60, 0xae, 0xff,
+ /*11e0:*/ 0x10, 0xb0, 0xfb, 0x5c, 0x02, 0x26, 0x72, 0x3d, 0xb1, 0x9b, 0x7e, 0xab, 0x18, 0xba, 0x0a, 0x49,
+ /*11f0:*/ 0xf0, 0x1f, 0xfd, 0x53, 0xa7, 0x96, 0xe8, 0xf7, 0xde, 0xab, 0xf0, 0x72, 0xce, 0x21, 0xb9, 0xb9,
+ /*1200:*/ 0x8f, 0x14, 0xb5, 0x13, 0x37, 0x61, 0x72, 0x73, 0xa3, 0xca, 0x5c, 0x63, 0x60, 0xe4, 0x99, 0xd5,
+ /*1210:*/ 0x6f, 0x38, 0x72, 0x7e, 0xa4, 0xf6, 0xc9, 0xb7, 0xc4, 0x66, 0xd9, 0xdd, 0x50, 0x2c, 0x56, 0x21,
+ /*1220:*/ 0x66, 0x3f, 0x3b, 0xc4, 0x28, 0x50, 0x87, 0x9b, 0x2f, 0xec, 0x71, 0xd8, 0x3a, 0x1b, 0x71, 0x97,
+ /*1230:*/ 0x2d, 0xf3, 0x59, 0xdf, 0x3d, 0xc6, 0x22, 0x44, 0xa2, 0xf0, 0x8f, 0xed, 0x6a, 0x11, 0x03, 0x49,
+ /*1240:*/ 0x8f, 0x86, 0x98, 0xc7, 0x34, 0xc6, 0x20, 0x1f, 0x96, 0x39, 0x2e, 0x6e, 0xa3, 0x5f, 0x26, 0x17,
+ /*1250:*/ 0xaf, 0x24, 0x7a, 0x70, 0x3d, 0x23, 0x30, 0x97, 0x4d, 0xf5, 0x9c, 0x9c, 0xfe, 0x64, 0x15, 0x99,
+ /*1260:*/ 0xee, 0x9e, 0xb1, 0x85, 0x28, 0xe8, 0xcd, 0xc8, 0x3a, 0x5e, 0x8f, 0x0c, 0x20, 0x48, 0x56, 0x62,
+ /*1270:*/ 0x88, 0xf8, 0x70, 0x0c, 0xee, 0x60, 0x12, 0xbf, 0xee, 0xa8, 0x94, 0xe6, 0x03, 0x10, 0x1f, 0x6e,
+ /*1280:*/ 0x5c, 0x60, 0x27, 0x5e, 0x64, 0xa3, 0x65, 0x88, 0xe6, 0x65, 0x53, 0xc3, 0xe8, 0x9c, 0xd5, 0xc6,
+ /*1290:*/ 0xe5, 0x55, 0x19, 0xdc, 0xc6, 0x9f, 0x80, 0x65, 0x35, 0x32, 0xea, 0xd1, 0xb4, 0x4f, 0xf8, 0x0b,
+ /*12a0:*/ 0xc5, 0x53, 0x74, 0x61, 0x01, 0xb6, 0x0b, 0x60, 0x46, 0x54, 0xd7, 0x21, 0x7e, 0x90, 0xc5, 0x7e,
+ /*12b0:*/ 0x38, 0xd6, 0x5c, 0x70, 0x02, 0x44, 0x35, 0xc9, 0x83, 0xb6, 0x7b, 0x47, 0xb6, 0xb8, 0x22, 0x39,
+ /*12c0:*/ 0x87, 0x10, 0xe0, 0x72, 0xec, 0x04, 0x86, 0x62, 0xfe, 0xb8, 0xf3, 0x2d, 0x63, 0x39, 0xd0, 0x6f,
+ /*12d0:*/ 0x23, 0x80, 0xc1, 0x51, 0xd5, 0xeb, 0x4a, 0x8d, 0x03, 0xce, 0xb9, 0xf1, 0x59, 0x13, 0x6f, 0xc8,
+ /*12e0:*/ 0x03, 0x64, 0x6e, 0x1b, 0x8b, 0x24, 0xe0, 0x91, 0x0b, 0xbb, 0x9d, 0x34, 0x13, 0x42, 0xf6, 0xd4,
+ /*12f0:*/ 0x0c, 0xe9, 0xb9, 0x4c, 0x5b, 0xb5, 0xd0, 0x18, 0x11, 0x80, 0x78, 0x1c, 0xfc, 0x89, 0xe8, 0xb2,
+ /*1300:*/ 0xde, 0xf7, 0x01, 0x2a, 0x07, 0x39, 0x8f, 0x4e, 0x34, 0xce, 0xf8, 0xd1, 0x86, 0x44, 0x02, 0xc4,
+ /*1310:*/ 0x3e, 0xd7, 0x8e, 0x49, 0x2e, 0x84, 0x86, 0x6d, 0x4f, 0x67, 0xbf, 0x80, 0x2d, 0xe2, 0x5a, 0x1b,
+ /*1320:*/ 0xed, 0xbe, 0xd2, 0x41, 0x25, 0x78, 0x53, 0x1c, 0x04, 0xa8, 0x2f, 0x9c, 0x4e, 0xaf, 0x8c, 0x97,
+ /*1330:*/ 0x38, 0xac, 0x56, 0xd9, 0x81, 0x08, 0x91, 0x0c, 0xf0, 0x20, 0xdb, 0x0a, 0x68, 0x87, 0x3f, 0x44,
+ /*1340:*/ 0xd5, 0xee, 0xb1, 0x04, 0x09, 0x42, 0x86, 0xd2, 0x5c, 0xd9, 0xa9, 0x6d, 0x52, 0x68, 0xd9, 0x29,
+ /*1350:*/ 0x82, 0x42, 0xbb, 0x2a, 0xc9, 0x7e, 0x9b, 0x8f, 0x57, 0xcf, 0x90, 0xf0, 0x7e, 0xd6, 0x42, 0xef,
+ /*1360:*/ 0xd2, 0xf4, 0xbe, 0xae, 0x6e, 0xdb, 0x71, 0xe5, 0xb8, 0xe0, 0x11, 0x20, 0x8b, 0xfd, 0x96, 0x59,
+ /*1370:*/ 0x48, 0x94, 0x49, 0xf0, 0x3d, 0x37, 0xa7, 0xa4, 0x7d, 0x5e, 0x93, 0x0b, 0x55, 0x92, 0x7a, 0x69,
+ /*1380:*/ 0xdc, 0x9f, 0xb5, 0x0e, 0xe7, 0x4a, 0x60, 0x3f, 0x44, 0x6a, 0x93, 0x52, 0x6a, 0x6f, 0x18, 0xf9,
+ /*1390:*/ 0xda, 0x98, 0x94, 0x38, 0xb7, 0x45, 0x4a, 0xcf, 0xb1, 0xc5, 0xf7, 0x03, 0x39, 0x8a, 0x21, 0x07,
+ /*13a0:*/ 0xb1, 0x3f, 0x53, 0x5a, 0xde, 0xde, 0xee, 0xf5, 0xbd, 0x1d, 0xb3, 0xea, 0xa2, 0x0e, 0x0c, 0xe4,
+ /*13b0:*/ 0xd2, 0x25, 0x45, 0xc5, 0x29, 0xfa, 0x9e, 0x3a, 0x75, 0x8a, 0x75, 0x3e, 0x3b, 0x8e, 0x82, 0xea,
+ /*13c0:*/ 0xef, 0x7e, 0x1e, 0x4c, 0xb4, 0x26, 0x15, 0x19, 0x82, 0x40, 0x12, 0xe1, 0x04, 0x4c, 0x48, 0x24,
+ /*13d0:*/ 0xad, 0xed, 0x4b, 0xe8, 0xc5, 0x0c, 0x15, 0x91, 0x22, 0x7f, 0xb5, 0xd0, 0x9e, 0x73, 0x6e, 0x59,
+ /*13e0:*/ 0xd0, 0xfb, 0x26, 0xb2, 0x2a, 0x60, 0xdb, 0x1c, 0xd0, 0x86, 0xd6, 0x7d, 0xdd, 0xfe, 0x64, 0x1c,
+ /*13f0:*/ 0xd2, 0xb1, 0x9e, 0x73, 0xeb, 0x5b, 0x99, 0x4b, 0x13, 0x14, 0xc2, 0xf3, 0x20, 0xdf, 0x55, 0xc1,
+ /*1400:*/ 0x57, 0xf2, 0x13, 0x0f, 0xc9, 0x8f, 0xa1, 0x7e, 0x94, 0x1f, 0xff, 0xf6, 0x78, 0x8c, 0x46, 0xf9,
+ /*1410:*/ 0xd1, 0x99, 0xa3, 0xe9, 0xe8, 0x0e, 0x97, 0x00, 0xde, 0x34, 0xd9, 0x14, 0xd7, 0x1e, 0xa4, 0x83,
+ /*1420:*/ 0x39, 0xa9, 0xda, 0x7c, 0x47, 0x54, 0x40, 0x45, 0x13, 0x49, 0x55, 0x7d, 0x00, 0x79, 0xb0, 0x00,
+ /*1430:*/ 0x32, 0x1b, 0x3b, 0x53, 0xc9, 0x96, 0x1c, 0xb4, 0xb3, 0xac, 0xaa, 0x67, 0xbb, 0x42, 0xaa, 0xcf,
+ /*1440:*/ 0x81, 0x08, 0x5a, 0x56, 0x3e, 0x0e, 0x41, 0x18, 0xdb, 0xe7, 0x99, 0xd0, 0x0e, 0xe9, 0x40, 0x1b,
+ /*1450:*/ 0xc7, 0x6a, 0x57, 0x12, 0x89, 0x64, 0xb6, 0x1d, 0xd1, 0xd6, 0x04, 0xa5, 0xa1, 0xb0, 0xe9, 0x46,
+ /*1460:*/ 0x32, 0x88, 0x9b, 0x39, 0x06, 0xab, 0x4f, 0xef, 0xef, 0x49, 0xfb, 0x42, 0x58, 0x01, 0xcc, 0x29,
+ /*1470:*/ 0x53, 0x06, 0xc7, 0xb2, 0x09, 0x63, 0xff, 0xd3, 0x7d, 0xb3, 0xbb, 0x54, 0xd3, 0x2c, 0x7e, 0x4b,
+ /*1480:*/ 0xf8, 0x05, 0x7e, 0xb3, 0x55, 0x38, 0xc9, 0x92, 0x15, 0x12, 0xd4, 0xde, 0x38, 0x29, 0x8d, 0xcf,
+ /*1490:*/ 0xaa, 0xc4, 0x88, 0x61, 0x36, 0x34, 0x95, 0x3c, 0x48, 0xfb, 0xec, 0x5e, 0xdf, 0x72, 0x83, 0xff,
+ /*14a0:*/ 0xe7, 0x8f, 0x72, 0x1a, 0xaf, 0xa8, 0xef, 0xbf, 0xbe, 0xb7, 0x57, 0xa8, 0xa4, 0xe0, 0x80, 0x2a,
+ /*14b0:*/ 0x45, 0x3a, 0xf0, 0x80, 0x5d, 0xd5, 0x3a, 0x3c, 0x03, 0x77, 0x66, 0xd1, 0x46, 0xb0, 0x92, 0x2e,
+ /*14c0:*/ 0x54, 0xce, 0xe5, 0x08, 0x00, 0xfd, 0x84, 0xf0, 0x0d, 0x2f, 0xd9, 0x9b, 0x73, 0x31, 0x40, 0x53,
+ /*14d0:*/ 0x66, 0x2d, 0xd1, 0x84, 0xc8, 0xfe, 0x1a, 0xdf, 0xd4, 0x4a, 0x80, 0x30, 0x56, 0xc3, 0x26, 0x3b,
+ /*14e0:*/ 0x61, 0xde, 0x37, 0x34, 0x08, 0xbd, 0x40, 0xd8, 0x5e, 0xdf, 0x45, 0xf4, 0xe4, 0x2b, 0xf7, 0x4b,
+ /*14f0:*/ 0x8f, 0xf5, 0xa7, 0x70, 0x50, 0x25, 0x48, 0x18, 0xfd, 0x1a, 0xb5, 0xfd, 0xf2, 0x6a, 0xb4, 0x1b,
+ /*1500:*/ 0x44, 0xd5, 0x3f, 0x59, 0x23, 0x4b, 0x96, 0x7e, 0x72, 0x3a, 0xf1, 0x6e, 0x13, 0x40, 0x7b, 0x17,
+ /*1510:*/ 0x20, 0x09, 0xf2, 0x09, 0xb7, 0x77, 0xd3, 0x4e, 0x21, 0xbf, 0xac, 0x16, 0x2c, 0x9c, 0x95, 0x17,
+ /*1520:*/ 0xd1, 0x4b, 0x55, 0x00, 0x8a, 0xff, 0x4e, 0x25, 0x59, 0xba, 0xad, 0x4c, 0xf9, 0x17, 0xce, 0xec,
+ /*1530:*/ 0x1e, 0xdd, 0xfb, 0xb0, 0x4f, 0x5d, 0xca, 0xe8, 0x29, 0xb1, 0xba, 0x5e, 0x77, 0x2c, 0xf2, 0xa3,
+ /*1540:*/ 0x26, 0x86, 0x39, 0x86, 0x9d, 0xa4, 0xd5, 0x0a, 0x94, 0xea, 0xbf, 0x39, 0xc4, 0x21, 0x4c, 0xd7,
+ /*1550:*/ 0x5f, 0xdb, 0xdd, 0x10, 0x14, 0x81, 0x45, 0x36, 0xe4, 0xe5, 0xcc, 0x84, 0x8f, 0x8c, 0xa3, 0xee,
+ /*1560:*/ 0x23, 0x0e, 0x1c, 0xf9, 0x23, 0xa7, 0x48, 0xac, 0x69, 0xfc, 0x09, 0x30, 0xf6, 0x2c, 0x44, 0x04,
+ /*1570:*/ 0xe7, 0x3f, 0xc1, 0xeb, 0xb7, 0x28, 0x1b, 0x1f, 0xe0, 0x47, 0x54, 0x41, 0xf8, 0x4f, 0x6c, 0xb4,
+ /*1580:*/ 0xb3, 0x23, 0x1f, 0x7c, 0xb2, 0xfc, 0x96, 0x1a, 0xf1, 0x37, 0x28, 0x66, 0xf8, 0xa8, 0x6b, 0xe1,
+ /*1590:*/ 0x4b, 0xb5, 0x61, 0xf2, 0xd2, 0xa7, 0x8c, 0xfc, 0x24, 0x3e, 0x4e, 0xc7, 0x00, 0xd4, 0x20, 0x06,
+ /*15a0:*/ 0x1f, 0xe3, 0x48, 0xe5, 0x95, 0x2c, 0xa7, 0x10, 0x55, 0x5f, 0xe2, 0x51, 0x8d, 0x80, 0x7c, 0x2d,
+ /*15b0:*/ 0x86, 0x05, 0x1e, 0x95, 0xd1, 0x19, 0xe1, 0xe9, 0x1f, 0x94, 0x26, 0x82, 0x57, 0x8b, 0x63, 0xd2,
+ /*15c0:*/ 0xa7, 0xff, 0xb1, 0x5a, 0x82, 0x87, 0xd2, 0xc6, 0x1a, 0x01, 0xa2, 0xa6, 0xe9, 0xc1, 0x09, 0xb7,
+ /*15d0:*/ 0xc1, 0x00, 0x92, 0xdf, 0x2a, 0xee, 0xb7, 0xb0, 0x89, 0xf5, 0x23, 0x24, 0xac, 0xf3, 0xc9, 0xfc,
+ /*15e0:*/ 0xd2, 0x26, 0xdc, 0x0b, 0xf4, 0x00, 0xbb, 0x39, 0x74, 0xe8, 0x31, 0xa2, 0xbb, 0x5b, 0x79, 0xcd,
+ /*15f0:*/ 0x09, 0x89, 0x45, 0x29, 0xba, 0xee, 0x42, 0x5c, 0x38, 0xa1, 0xd2, 0x94, 0xaa, 0x26, 0x31, 0x6d,
+ /*1600:*/ 0x74, 0xec, 0xb0, 0xdb, 0xfc, 0x70, 0x70, 0xf3, 0x3e, 0xa2, 0x5f, 0xef, 0xab, 0xbc, 0x2c, 0xc2,
+ /*1610:*/ 0x17, 0xc9, 0x3b, 0xd0, 0xba, 0xf9, 0x4a, 0x54, 0x43, 0x8e, 0xc7, 0x96, 0x1c, 0x66, 0x0e, 0x25,
+ /*1620:*/ 0xb6, 0x62, 0x08, 0x51, 0x57, 0x1f, 0x5d, 0xfa, 0x16, 0x8b, 0x14, 0x06, 0x20, 0x01, 0x79, 0xda,
+ /*1630:*/ 0xc9, 0x41, 0x59, 0x33, 0x38, 0xb6, 0x92, 0xe9, 0xea, 0x6d, 0x03, 0x75, 0x86, 0xa1, 0x6f, 0xb7,
+ /*1640:*/ 0x15, 0xe2, 0xa4, 0x48, 0x7d, 0xa3, 0x89, 0x72, 0x38, 0xfc, 0xab, 0x06, 0xac, 0x9e, 0xc7, 0xa0,
+ /*1650:*/ 0x94, 0x51, 0x5c, 0x7a, 0xea, 0x80, 0xc8, 0x7d, 0xf6, 0x7d, 0xbf, 0x42, 0xdb, 0x04, 0x62, 0x9e,
+ /*1660:*/ 0xba, 0x05, 0x1f, 0xaa, 0x94, 0x62, 0xfc, 0x83, 0xa2, 0x96, 0x71, 0xe5, 0x89, 0x70, 0xc1, 0x17,
+ /*1670:*/ 0x25, 0xd3, 0x40, 0x0d, 0x25, 0x25, 0x19, 0xb8, 0x13, 0xba, 0x50, 0x30, 0xab, 0x97, 0x0d, 0x3c,
+ /*1680:*/ 0x73, 0xa5, 0x86, 0xa7, 0x37, 0x99, 0xa8, 0xff, 0x37, 0xeb, 0x1a, 0xca, 0x80, 0xe9, 0xda, 0xb6,
+ /*1690:*/ 0x1c, 0xbc, 0x29, 0x6f, 0x96, 0x50, 0x28, 0xd1, 0x63, 0x17, 0x1b, 0xb4, 0xfa, 0x3c, 0x9b, 0x30,
+ /*16a0:*/ 0xa2, 0xe2, 0x76, 0x5d, 0x6e, 0x07, 0xef, 0xb2, 0x20, 0x83, 0x26, 0x13, 0x1d, 0xd0, 0x35, 0x17,
+ /*16b0:*/ 0x49, 0xf8, 0x38, 0x88, 0xeb, 0x18, 0xd1, 0x8f, 0x54, 0x96, 0x70, 0x42, 0x4c, 0x7c, 0x42, 0x21,
+ /*16c0:*/ 0xba, 0x4a, 0xb5, 0xc0, 0x07, 0xee, 0x00, 0xe4, 0x0f, 0x9c, 0xe5, 0x57, 0xaf, 0x18, 0x38, 0x0c,
+ /*16d0:*/ 0x0e, 0x08, 0x61, 0x76, 0xb8, 0xf4, 0x91, 0x73, 0xa3, 0xab, 0x54, 0x8c, 0x84, 0x4e, 0xff, 0xee,
+ /*16e0:*/ 0x36, 0x1c, 0x95, 0x31, 0x29, 0x6b, 0x52, 0xeb, 0x77, 0x78, 0xed, 0x17, 0x00, 0xbf, 0x71, 0x4a,
+ /*16f0:*/ 0x44, 0x5f, 0xfe, 0xb1, 0x14, 0xe5, 0xf2, 0xa5, 0x25, 0x4d, 0x90, 0x61, 0x97, 0x83, 0x27, 0xff,
+ /*1700:*/ 0xa9, 0x04, 0xd2, 0xcc, 0xfe, 0xae, 0xf0, 0x31, 0x90, 0x2d, 0xcb, 0xea, 0x8e, 0xd9, 0xbf, 0x66,
+ /*1710:*/ 0x32, 0xbb, 0x23, 0xf5, 0x97, 0xf7, 0xf4, 0x00, 0xd9, 0x18, 0xf7, 0x49, 0xc8, 0x6c, 0xb7, 0xa7,
+ /*1720:*/ 0xb4, 0x94, 0x25, 0x8d, 0xe6, 0xfc, 0x04, 0x70, 0x52, 0x8a, 0x3c, 0x73, 0x83, 0x54, 0xd6, 0x80,
+ /*1730:*/ 0x78, 0x17, 0xb8, 0xe8, 0xf1, 0x81, 0x5c, 0xc9, 0x02, 0x81, 0xe2, 0x79, 0x28, 0xa1, 0x2a, 0x1a,
+ /*1740:*/ 0x88, 0xa5, 0xcf, 0x00, 0x69, 0xeb, 0xff, 0x47, 0x24, 0x37, 0x3c, 0x61, 0x9e, 0x8a, 0xa9, 0x5e,
+ /*1750:*/ 0xc7, 0xe6, 0xe3, 0x39, 0x39, 0x5e, 0x24, 0x8e, 0x47, 0x2d, 0x86, 0x37, 0x3c, 0xfd, 0x4b, 0xf2,
+ /*1760:*/ 0xfd, 0x16, 0xa7, 0x3f, 0x0c, 0x90, 0x99, 0x81, 0x91, 0x98, 0x76, 0x8e, 0xd9, 0xc4, 0x87, 0x9c,
+ /*1770:*/ 0x5e, 0xaa, 0x8f, 0xa1, 0x12, 0xc8, 0x7a, 0x55, 0x63, 0x43, 0x80, 0x38, 0xa5, 0x92, 0x51, 0x20,
+ /*1780:*/ 0x74, 0x98, 0xb3, 0x05, 0xc8, 0xf1, 0xae, 0xe1, 0xf8, 0x7c, 0x73, 0x63, 0xe7, 0x6c, 0x70, 0x43,
+ /*1790:*/ 0x1a, 0xed, 0x1c, 0xd5, 0x44, 0x7f, 0x89, 0x4f, 0x92, 0x38, 0x02, 0x05, 0x8d, 0x1e, 0x71, 0x44,
+ /*17a0:*/ 0x31, 0x10, 0xc9, 0xae, 0xb0, 0x6e, 0x62, 0xd3, 0xd6, 0x00, 0x99, 0xa7, 0x1b, 0x81, 0xc2, 0x4f,
+ /*17b0:*/ 0x81, 0x5c, 0xf3, 0x30, 0xe6, 0x80, 0xc2, 0xa7, 0x1c, 0x42, 0xbb, 0x61, 0xd9, 0xd2, 0x0d, 0xe2,
+ /*17c0:*/ 0xc3, 0xd1, 0x9c, 0x28, 0xda, 0xb4, 0x62, 0x8b, 0x48, 0x56, 0x97, 0x08, 0x23, 0x94, 0x96, 0xa3,
+ /*17d0:*/ 0x98, 0x66, 0x39, 0x36, 0xd3, 0xb5, 0x67, 0x0c, 0x01, 0x3c, 0x12, 0xda, 0xc9, 0x42, 0x25, 0x47,
+ /*17e0:*/ 0xeb, 0x29, 0xe5, 0x53, 0xc8, 0x12, 0x98, 0x44, 0x6f, 0x73, 0x4f, 0x7c, 0x5f, 0xcd, 0x69, 0x02,
+ /*17f0:*/ 0x5b, 0x3c, 0xad, 0xc9, 0xcb, 0xd4, 0xe5, 0x8d, 0x5c, 0x73, 0xa0, 0x9d, 0x51, 0xf4, 0x99, 0x19,
+ /*1800:*/ 0xe1, 0xe0, 0x22, 0xcf, 0x00, 0xbd, 0x63, 0xab, 0xd7, 0x9b, 0xb6, 0x2a, 0xdd, 0xa1, 0x1e, 0x3d,
+ /*1810:*/ 0x19, 0xe0, 0x63, 0x6f, 0x3f, 0xf6, 0x4a, 0x70, 0xd8, 0x6d, 0x73, 0xa7, 0x88, 0xbc, 0xcd, 0x7d,
+ /*1820:*/ 0xae, 0xe2, 0xe4, 0x2b, 0x63, 0x44, 0x29, 0x83, 0xfc, 0x3b, 0x69, 0x9f, 0x11, 0x8e, 0xee, 0xf5,
+ /*1830:*/ 0xb0, 0x38, 0xd2, 0x71, 0xe3, 0x90, 0xde, 0x04, 0x81, 0x29, 0xbf, 0xc7, 0x4d, 0xb9, 0xf2, 0x29,
+ /*1840:*/ 0x57, 0xc3, 0xa5, 0x41, 0x3f, 0x1b, 0x70, 0xec, 0x48, 0x97, 0xee, 0xb9, 0xce, 0xfd, 0xbb, 0x74,
+ /*1850:*/ 0x12, 0xf4, 0x57, 0x4b, 0x44, 0xcd, 0x6c, 0xdd, 0xd6, 0xd5, 0x0f, 0xa0, 0xc9, 0x40, 0x52, 0x8f,
+ /*1860:*/ 0x8c, 0x22, 0x4e, 0xb2, 0x3c, 0x12, 0x5a, 0x13, 0x1f, 0x24, 0xcc, 0xb8, 0xd2, 0xa6, 0xb4, 0xe1,
+ /*1870:*/ 0x22, 0x71, 0x96, 0x48, 0xf3, 0x08, 0xd5, 0x55, 0x20, 0x71, 0x1e, 0x9b, 0x51, 0x56, 0xf3, 0x81,
+ /*1880:*/ 0x3f, 0x3b, 0x4c, 0xe7, 0x67, 0xa4, 0x24, 0x1c, 0x84, 0x4d, 0x57, 0xd7, 0x33, 0x2d, 0xb2, 0x3e,
+ /*1890:*/ 0xff, 0xe4, 0x42, 0xbb, 0x37, 0x4b, 0x5c, 0x71, 0xf0, 0xd8, 0x5a, 0xc8, 0xcb, 0xbc, 0x46, 0x60,
+ /*18a0:*/ 0x4e, 0x33, 0x9e, 0x9b, 0x02, 0x83, 0xf7, 0x65, 0x61, 0x14, 0x69, 0xd5, 0x9d, 0x78, 0xef, 0x44,
+ /*18b0:*/ 0x79, 0xf3, 0x5c, 0xf9, 0xab, 0x9b, 0x6b, 0x93, 0x12, 0x7a, 0x2d, 0x1d, 0xab, 0xff, 0xf8, 0x1d,
+ /*18c0:*/ 0xcb, 0x2e, 0x2d, 0xa8, 0x24, 0xcd, 0x74, 0x7e, 0xc1, 0xb7, 0xf1, 0x7f, 0x5a, 0xa7, 0x4f, 0xd5,
+ /*18d0:*/ 0xe1, 0x7c, 0xbe, 0x5c, 0xcc, 0x8d, 0xb0, 0xe8, 0x05, 0x0c, 0xc6, 0x53, 0x79, 0xa3, 0xe6, 0xda,
+ /*18e0:*/ 0xa6, 0x23, 0x6c, 0x9d, 0x1b, 0x98, 0xa9, 0x78, 0xe2, 0x20, 0xd6, 0xcf, 0xb1, 0x12, 0x4c, 0xec,
+ /*18f0:*/ 0xb7, 0xb3, 0x04, 0x1d, 0xe3, 0xf0, 0xc2, 0xa6, 0x97, 0x29, 0xef, 0x43, 0x55, 0xef, 0xff, 0x71,
+ /*1900:*/ 0xb1, 0x1f, 0x4e, 0x0f, 0x08, 0x05, 0x91, 0x19, 0xd0, 0x73, 0x6b, 0x36, 0x7d, 0x1d, 0xae, 0xc6,
+ /*1910:*/ 0xbf, 0xdb, 0x03, 0x3f, 0xc7, 0x06, 0xf3, 0xed, 0x15, 0xa3, 0xda, 0x03, 0xbd, 0x57, 0x6f, 0x86,
+ /*1920:*/ 0x30, 0x77, 0x7b, 0x2c, 0xd9, 0xa9, 0x77, 0x8f, 0xf0, 0xe3, 0x78, 0x75, 0x88, 0x13, 0x3b, 0x1a,
+ /*1930:*/ 0xa8, 0xdf, 0x4a, 0x09, 0xb0, 0x52, 0x55, 0x79, 0xba, 0x0a, 0xf3, 0x36, 0x9a, 0x0c, 0xd5, 0x93,
+ /*1940:*/ 0xed, 0x15, 0x47, 0x80, 0xb8, 0x0d, 0xb7, 0xd7, 0x6d, 0x51, 0xd0, 0x1c, 0xc5, 0x2c, 0x8d, 0x31,
+ /*1950:*/ 0xb7, 0x35, 0x62, 0xf9, 0xa3, 0xd2, 0xfa, 0x26, 0xe7, 0x61, 0x3f, 0x85, 0xae, 0x96, 0x85, 0xf9,
+ /*1960:*/ 0xb3, 0x4a, 0x1b, 0x0e, 0x30, 0x2a, 0xc2, 0x10, 0xe8, 0xfb, 0x16, 0xc0, 0x74, 0x29, 0x2a, 0x16,
+ /*1970:*/ 0x39, 0xd9, 0xd8, 0xaf, 0x45, 0x92, 0x5e, 0xdf, 0xa4, 0x2f, 0xae, 0x42, 0xc2, 0xf5, 0x7b, 0xa1,
+ /*1980:*/ 0x33, 0x26, 0xa1, 0x06, 0x7f, 0x57, 0x4e, 0x1e, 0x5d, 0xaa, 0x5c, 0xa1, 0x52, 0xdb, 0xb3, 0xba,
+ /*1990:*/ 0x8f, 0x4e, 0x6f, 0x00, 0xc2, 0x95, 0x12, 0x0c, 0xe7, 0xf0, 0xad, 0xb8, 0x33, 0xc0, 0xfc, 0x3b,
+ /*19a0:*/ 0x9f, 0x06, 0x4d, 0x4c, 0x45, 0x5c, 0xea, 0x12, 0x92, 0xff, 0x3e, 0xa7, 0xc6, 0x4b, 0x15, 0xb0,
+ /*19b0:*/ 0x51, 0x59, 0x5d, 0x40, 0xb1, 0xff, 0xae, 0xfb, 0x9a, 0x66, 0xc0, 0x1c, 0x38, 0x7b, 0x6f, 0xa7,
+ /*19c0:*/ 0xc6, 0x81, 0xbe, 0x91, 0xb1, 0xb0, 0xce, 0x2b, 0x7c, 0x04, 0x69, 0xdd, 0x67, 0xd1, 0x9e, 0x9e,
+ /*19d0:*/ 0x41, 0x3c, 0x90, 0x04, 0x17, 0x5c, 0x73, 0x51, 0xfd, 0x49, 0x7e, 0x2d, 0x0a, 0xd3, 0x77, 0x1d,
+ /*19e0:*/ 0xbc, 0x8e, 0x2e, 0xf6, 0x44, 0x20, 0x8a, 0x3f, 0x44, 0xa2, 0xd6, 0x8c, 0x40, 0xac, 0x6c, 0x91,
+ /*19f0:*/ 0xa4, 0x34, 0xe6, 0xbe, 0x3b, 0x55, 0xde, 0x9b, 0x3b, 0x97, 0xba, 0xbc, 0x43, 0x79, 0xe5, 0xba,
+ /*1a00:*/ 0xc5, 0x34, 0x87, 0xb9, 0x68, 0xef, 0x83, 0x9c, 0x90, 0x55, 0x27, 0xcb, 0xc2, 0x57, 0xad, 0x27,
+ /*1a10:*/ 0xe8, 0xe4, 0xe0, 0xa6, 0x03, 0x27, 0x9f, 0x41, 0x38, 0xb4, 0x1e, 0x7b, 0xa4, 0xe2, 0xab, 0x27,
+ /*1a20:*/ 0x7b, 0x81, 0xfa, 0x9a, 0x7b, 0xc0, 0xb6, 0xd4, 0xe4, 0x0f, 0xf2, 0x2c, 0x25, 0x73, 0xef, 0x3f,
+ /*1a30:*/ 0xae, 0xb2, 0x84, 0xd9, 0x6d, 0xc2, 0x41, 0x34, 0xc1, 0x00, 0x69, 0xc7, 0x68, 0xda, 0xca, 0xbb,
+ /*1a40:*/ 0x82, 0x97, 0x93, 0xb8, 0x21, 0xe4, 0xee, 0xd9, 0x65, 0xcc, 0xa9, 0x89, 0x70, 0x3d, 0x87, 0x8a,
+ /*1a50:*/ 0x98, 0xaf, 0x73, 0xdd, 0x9e, 0x41, 0x9b, 0xad, 0xbb, 0xb8, 0xfb, 0x3e, 0xdd, 0x57, 0xd0, 0x66,
+ /*1a60:*/ 0xc8, 0x11, 0x42, 0xd8, 0x84, 0x5e, 0x20, 0x4c, 0xe9, 0xaa, 0xad, 0x08, 0x8f, 0x9d, 0x9e, 0xf9,
+ /*1a70:*/ 0x47, 0xfb, 0x46, 0x89, 0xaa, 0xec, 0x21, 0x32, 0x56, 0x49, 0x47, 0xc3, 0x0d, 0x26, 0x06, 0xe8,
+ /*1a80:*/ 0xfe, 0x50, 0xbb, 0xf1, 0x13, 0xec, 0x78, 0x02, 0xcb, 0xe2, 0x5d, 0x4c, 0xe5, 0x17, 0x50, 0x9a,
+ /*1a90:*/ 0x29, 0x24, 0x06, 0xd2, 0x27, 0xf1, 0xcc, 0x31, 0x44, 0xc5, 0xeb, 0xda, 0xbf, 0x7f, 0xe0, 0xa8,
+ /*1aa0:*/ 0x27, 0xad, 0xc9, 0xf1, 0x22, 0xce, 0x52, 0x1f, 0x66, 0xac, 0x29, 0xc3, 0x6b, 0xea, 0x7e, 0xdc,
+ /*1ab0:*/ 0x57, 0xc1, 0xee, 0xf2, 0xa3, 0x9d, 0xc2, 0xdb, 0x47, 0xa3, 0xd1, 0x40, 0xda, 0xa8, 0x4f, 0x51,
+ /*1ac0:*/ 0x31, 0x7a, 0x58, 0xf4, 0x76, 0xef, 0xe4, 0xeb, 0x47, 0xd8, 0x33, 0x1e, 0x33, 0x1d, 0xca, 0xd8,
+ /*1ad0:*/ 0xce, 0x20, 0x21, 0x6d, 0xd4, 0xa4, 0x0d, 0x9b, 0x41, 0x8e, 0xcb, 0x00, 0xb3, 0x3c, 0x7f, 0x2a,
+ /*1ae0:*/ 0xe1, 0x4f, 0x43, 0x10, 0xde, 0x96, 0x71, 0xd1, 0x23, 0x21, 0x2b, 0x4a, 0xab, 0x4d, 0x88, 0xbb,
+ /*1af0:*/ 0x4e, 0x7d, 0x51, 0x42, 0x86, 0xd0, 0x45, 0x8a, 0x12, 0x01, 0xec, 0x87, 0xc3, 0xa4, 0xfc, 0x9e,
+ /*1b00:*/ 0x38, 0x47, 0xd6, 0xdb, 0xbb, 0x9f, 0x76, 0xa7, 0x7a, 0x20, 0x6c, 0x1f, 0x2b, 0x85, 0xbf, 0xf0,
+ /*1b10:*/ 0x2b, 0x17, 0x29, 0xd3, 0xc1, 0x21, 0x76, 0x33, 0x54, 0xc7, 0x00, 0x8b, 0x42, 0xf7, 0x4b, 0x1f,
+ /*1b20:*/ 0x90, 0x95, 0xe3, 0x00, 0x06, 0x7c, 0x16, 0x8e, 0x55, 0x75, 0x25, 0x72, 0xcf, 0x6c, 0xaf, 0x03,
+ /*1b30:*/ 0x60, 0xde, 0xe0, 0x4f, 0xb5, 0x46, 0x98, 0xb9, 0xbf, 0x42, 0x6d, 0x50, 0xcf, 0xe2, 0x7c, 0xe7,
+ /*1b40:*/ 0x69, 0xa1, 0x38, 0x08, 0xbb, 0x4d, 0x28, 0xf0, 0x1a, 0x09, 0x2b, 0x15, 0xa9, 0x90, 0x50, 0x09,
+ /*1b50:*/ 0x9a, 0xd0, 0x06, 0x1d, 0xe6, 0x25, 0xb9, 0x11, 0xbd, 0x10, 0xc1, 0x8d, 0x99, 0xba, 0x51, 0xca,
+ /*1b60:*/ 0xc1, 0x6b, 0x26, 0xac, 0x6a, 0x81, 0xd7, 0xbd, 0x84, 0xc8, 0x6d, 0xb1, 0x22, 0x73, 0x99, 0x7c,
+ /*1b70:*/ 0x7d, 0xdc, 0xcc, 0xa8, 0x36, 0xcf, 0xf7, 0x85, 0xb2, 0x2f, 0x3a, 0xfa, 0x31, 0x21, 0x5b, 0x86,
+ /*1b80:*/ 0xf3, 0xae, 0x82, 0xc3, 0x69, 0x08, 0xf4, 0xa4, 0xfc, 0x70, 0x9f, 0xf3, 0x64, 0xdb, 0x90, 0xa8,
+ /*1b90:*/ 0x2c, 0x81, 0xe2, 0x2b, 0x59, 0x5b, 0x8d, 0xed, 0x08, 0x37, 0x88, 0xd0, 0xca, 0xf2, 0xaf, 0x6e,
+ /*1ba0:*/ 0x46, 0x00, 0x60, 0x6f, 0xbf, 0x7b, 0xf4, 0x69, 0xa1, 0x92, 0x4e, 0x30, 0x2c, 0x0f, 0xa1, 0xcb,
+ /*1bb0:*/ 0xbf, 0x8e, 0xe9, 0x1b, 0xe5, 0x90, 0x6c, 0x90, 0x5a, 0x5e, 0x92, 0xdf, 0x4f, 0xc6, 0x9c, 0x07,
+ /*1bc0:*/ 0xaf, 0xdd, 0x6b, 0x7c, 0x28, 0x8b, 0x01, 0x42, 0x1a, 0x7f, 0x43, 0xca, 0xbf, 0x9f, 0xf4, 0x56,
+ /*1bd0:*/ 0x88, 0xc2, 0x6e, 0xb4, 0x2d, 0xec, 0x75, 0x55, 0x88, 0x89, 0xec, 0x34, 0xd1, 0x4e, 0x7f, 0x58,
+ /*1be0:*/ 0x2d, 0xaf, 0x4b, 0x74, 0x9e, 0x1f, 0x40, 0x17, 0xcd, 0xa5, 0x03, 0x63, 0x2a, 0x52, 0xb5, 0x85,
+ /*1bf0:*/ 0x37, 0xac, 0xf9, 0x35, 0xe7, 0x04, 0x4f, 0x6f, 0x9b, 0xe4, 0x21, 0xd7, 0xc1, 0x37, 0x03, 0x6a,
+ /*1c00:*/ 0xc5, 0x2e, 0xf2, 0xa7, 0xfa, 0x3f, 0x41, 0x08, 0xf2, 0xf1, 0x9b, 0x3b, 0xef, 0xf8, 0x39, 0x16,
+ /*1c10:*/ 0xf9, 0xe9, 0xe7, 0x7c, 0xb9, 0x7c, 0xde, 0x7b, 0xd8, 0x32, 0xdf, 0x67, 0xff, 0x6f, 0x47, 0x8f,
+ /*1c20:*/ 0x4f, 0x90, 0x80, 0x6a, 0xf6, 0x3f, 0xef, 0x14, 0xd5, 0x9c, 0x78, 0x65, 0x95, 0xb3, 0x16, 0x7e,
+ /*1c30:*/ 0x22, 0xc1, 0x12, 0xb6, 0x7e, 0x8a, 0xa8, 0x2e, 0x06, 0x29, 0x41, 0xe7, 0x19, 0xf3, 0x60, 0xc1,
+ /*1c40:*/ 0xe7, 0xad, 0x7b, 0xd6, 0xf4, 0xa3, 0x9a, 0x60, 0x33, 0xfc, 0x00, 0x37, 0xe3, 0xe8, 0xba, 0xa7,
+ /*1c50:*/ 0xbe, 0x25, 0x09, 0x0b, 0x6b, 0x10, 0x9e, 0x5a, 0x8b, 0xfb, 0x16, 0x34, 0xae, 0x70, 0x16, 0x62,
+ /*1c60:*/ 0x08, 0x44, 0x83, 0x13, 0xa2, 0xb4, 0x5f, 0xe6, 0x4e, 0x97, 0xf0, 0x38, 0x32, 0xf0, 0xeb, 0x15,
+ /*1c70:*/ 0x3f, 0x22, 0xa5, 0x2d, 0xda, 0x5e, 0x8a, 0xc7, 0x1a, 0x67, 0xbc, 0x27, 0xb6, 0xe2, 0x33, 0xe0,
+ /*1c80:*/ 0x7e, 0xe1, 0x48, 0xcf, 0xbb, 0x98, 0xd5, 0xf4, 0x46, 0x9f, 0xc0, 0xa8, 0x9b, 0x5d, 0xcd, 0x51,
+ /*1c90:*/ 0xae, 0xab, 0xf8, 0xf1, 0x3a, 0x61, 0xb7, 0x40, 0x68, 0x8f, 0xb9, 0x65, 0xfe, 0x7f, 0xcf, 0x9d,
+ /*1ca0:*/ 0xc3, 0xf8, 0x9c, 0x02, 0x69, 0xa4, 0x46, 0xfd, 0x90, 0x94, 0xb4, 0x17, 0x48, 0x24, 0xd7, 0x9b,
+ /*1cb0:*/ 0x9e, 0xad, 0xe4, 0x0c, 0x7b, 0x8e, 0xf5, 0xcc, 0xf6, 0x6d, 0x8b, 0x25, 0x27, 0xd0, 0x12, 0x25,
+ /*1cc0:*/ 0x4e, 0x26, 0xca, 0x25, 0x3e, 0x0f, 0x85, 0x07, 0x03, 0xad, 0xb5, 0xed, 0xb5, 0xd3, 0x42, 0xbc,
+ /*1cd0:*/ 0xaa, 0xa5, 0xd1, 0xbb, 0xa9, 0xd7, 0x2f, 0x8e, 0x1a, 0x05, 0x00, 0xf1, 0xcd, 0x8b, 0x30, 0x11,
+ /*1ce0:*/ 0xa9, 0x3c, 0x7d, 0x08, 0x86, 0xf0, 0xc0, 0x5e, 0x89, 0x2a, 0xdc, 0xf7, 0xaa, 0xfa, 0x69, 0xf4,
+ /*1cf0:*/ 0xed, 0x1f, 0x73, 0x5f, 0x12, 0x9f, 0x7d, 0x6d, 0x56, 0x38, 0x39, 0x52, 0xfb, 0xa1, 0x59, 0xc5,
+ /*1d00:*/ 0x33, 0x4b, 0x60, 0x65, 0x0a, 0xee, 0x64, 0xbc, 0xd1, 0x08, 0x07, 0x65, 0xa7, 0x25, 0x08, 0xd5,
+ /*1d10:*/ 0xc5, 0x66, 0x36, 0x26, 0x2b, 0x08, 0xb2, 0x9a, 0x94, 0x84, 0x3e, 0xb3, 0x1e, 0xff, 0xeb, 0x0b,
+ /*1d20:*/ 0x17, 0xa2, 0xc2, 0x3b, 0x2d, 0x87, 0xdf, 0xcc, 0x2d, 0x33, 0x90, 0xd1, 0xb8, 0x13, 0x52, 0xf9,
+ /*1d30:*/ 0xf6, 0xde, 0xba, 0x43, 0x17, 0x57, 0x4b, 0x25, 0xe7, 0xd6, 0x6f, 0x92, 0xed, 0x9a, 0xf6, 0x33,
+ /*1d40:*/ 0x79, 0x3b, 0xfb, 0x4f, 0x06, 0xff, 0x16, 0x17, 0xba, 0xdd, 0x76, 0x85, 0x31, 0xaa, 0x6a, 0x02,
+ /*1d50:*/ 0x8a, 0xd0, 0x4e, 0xcd, 0xd1, 0x16, 0xa0, 0x81, 0xff, 0x68, 0x17, 0x89, 0xdc, 0x66, 0x1a, 0x01,
+ /*1d60:*/ 0xf5, 0x61, 0xe6, 0xb7, 0x9c, 0xc8, 0x4a, 0x0c, 0x8c, 0xbc, 0x4e, 0x8f, 0x1e, 0x8f, 0x44, 0x1b,
+ /*1d70:*/ 0x31, 0x53, 0x99, 0xa3, 0x4b, 0x59, 0xfe, 0xc1, 0x51, 0x98, 0x5a, 0x4f, 0x27, 0x56, 0x37, 0xe5,
+ /*1d80:*/ 0x90, 0x48, 0x02, 0x07, 0xaf, 0xf7, 0xbd, 0xe1, 0xcb, 0xe0, 0x08, 0x4f, 0x75, 0x68, 0x38, 0xdc,
+ /*1d90:*/ 0xb0, 0xad, 0x92, 0xc0, 0xf9, 0xc8, 0x84, 0x25, 0x4f, 0xac, 0x0e, 0x89, 0x41, 0x26, 0x0e, 0xb8,
+ /*1da0:*/ 0xa0, 0x73, 0x56, 0x16, 0xd9, 0x70, 0xdf, 0xde, 0xd8, 0x9b, 0x84, 0x8b, 0x2c, 0xe2, 0x2e, 0x80,
+ /*1db0:*/ 0x39, 0x33, 0x20, 0x18, 0x29, 0x72, 0x69, 0x2d, 0x61, 0x44, 0x67, 0xc5, 0x56, 0x04, 0x7d, 0xe5,
+ /*1dc0:*/ 0xc8, 0xdb, 0xb1, 0x6d, 0x5d, 0x2b, 0x34, 0x4e, 0xdd, 0x14, 0xff, 0x4b, 0x5a, 0xae, 0xa6, 0xee,
+ /*1dd0:*/ 0x5c, 0x81, 0xee, 0x61, 0x5d, 0x9f, 0x0d, 0x24, 0x21, 0x05, 0x48, 0x58, 0xe9, 0x12, 0x3a, 0x17,
+ /*1de0:*/ 0x73, 0x77, 0xb6, 0x54, 0x63, 0xd0, 0xe6, 0x7c, 0x87, 0x6b, 0xdf, 0xdd, 0x24, 0xd9, 0xd5, 0xc0,
+ /*1df0:*/ 0x4f, 0xed, 0xb6, 0x18, 0x72, 0x46, 0x98, 0x51, 0x78, 0x63, 0xe3, 0xf7, 0x55, 0xbe, 0x2b, 0x1a,
+ /*1e00:*/ 0x92, 0xb1, 0x7e, 0x7f, 0x37, 0xb0, 0xf8, 0x3c, 0x54, 0xc3, 0xf2, 0x8c, 0xa3, 0x57, 0x57, 0xd0,
+ /*1e10:*/ 0x7f, 0x72, 0x59, 0xda, 0xfe, 0xe2, 0x11, 0x84, 0x35, 0x69, 0xcc, 0x58, 0x19, 0x02, 0x17, 0x7a,
+ /*1e20:*/ 0xf1, 0xfc, 0x3a, 0x5f, 0x44, 0x2c, 0x8d, 0x61, 0xf5, 0x6f, 0x47, 0xd4, 0xc7, 0xe7, 0xb4, 0xe4,
+ /*1e30:*/ 0x39, 0xe6, 0xde, 0xf3, 0xa7, 0x40, 0x30, 0xf4, 0x47, 0x58, 0xd6, 0x9e, 0x2b, 0x26, 0x67, 0x59,
+ /*1e40:*/ 0xb6, 0xf1, 0x28, 0x8a, 0x23, 0xad, 0x08, 0xd0, 0x84, 0xf3, 0xd8, 0xfa, 0xfb, 0x72, 0x0a, 0x94,
+ /*1e50:*/ 0x89, 0xca, 0x41, 0x88, 0x2f, 0x33, 0xa1, 0x42, 0xbb, 0xe2, 0x30, 0x90, 0xb1, 0xa4, 0xbb, 0x28,
+ /*1e60:*/ 0x2b, 0xc5, 0x6f, 0xb2, 0x36, 0xd7, 0x35, 0xc5, 0x57, 0xb5, 0x94, 0x77, 0x63, 0x0c, 0x9a, 0x72,
+ /*1e70:*/ 0xf8, 0x93, 0xcf, 0x24, 0x28, 0xb6, 0x62, 0x95, 0x8d, 0xf4, 0x5e, 0xb8, 0x71, 0x49, 0x74, 0x97,
+ /*1e80:*/ 0xeb, 0xd0, 0x51, 0x58, 0x14, 0xe1, 0xc9, 0x70, 0xf1, 0x49, 0x26, 0x46, 0x1e, 0x3f, 0x36, 0x81,
+ /*1e90:*/ 0xb6, 0xc8, 0x1c, 0x9c, 0x5d, 0x67, 0x35, 0x25, 0xc1, 0x9b, 0x76, 0x3a, 0x95, 0x52, 0xb2, 0xe1,
+ /*1ea0:*/ 0xb2, 0x8a, 0x56, 0x1b, 0x82, 0x67, 0xfe, 0x48, 0x08, 0x3e, 0x5f, 0xc6, 0xf8, 0xe9, 0xb8, 0xe0,
+ /*1eb0:*/ 0x7e, 0x93, 0x99, 0xed, 0x22, 0x58, 0x6e, 0x5a, 0x8d, 0x9a, 0x51, 0xf1, 0x74, 0x6e, 0x92, 0x91,
+ /*1ec0:*/ 0xd6, 0x76, 0x19, 0xd2, 0xaf, 0xee, 0xaa, 0x0d, 0x91, 0x36, 0xae, 0xa6, 0xc6, 0xea, 0x8e, 0xe2,
+ /*1ed0:*/ 0x43, 0x34, 0x45, 0x6e, 0x11, 0x49, 0x32, 0x8d, 0x8d, 0x08, 0xfd, 0xc5, 0xf5, 0xb8, 0xf7, 0x49,
+ /*1ee0:*/ 0x66, 0x00, 0x6b, 0x50, 0x61, 0x3e, 0x24, 0xa3, 0x67, 0x0c, 0x9f, 0x3b, 0x4d, 0x69, 0x0d, 0xe5,
+ /*1ef0:*/ 0x66, 0x67, 0xf2, 0xcd, 0x79, 0x88, 0x36, 0xff, 0x21, 0x3b, 0x41, 0xcb, 0x88, 0x67, 0xdb, 0xa7,
+ /*1f00:*/ 0xc8, 0x3d, 0x16, 0xda, 0x7e, 0x58, 0x76, 0xdc, 0x0c, 0xd7, 0x96, 0x23, 0x59, 0x6f, 0xe2, 0xda,
+ /*1f10:*/ 0x62, 0xf7, 0x9f, 0x11, 0xee, 0x3f, 0x84, 0xeb, 0xbb, 0xeb, 0x62, 0x79, 0xa9, 0x6c, 0x93, 0x82,
+ /*1f20:*/ 0x07, 0x8f, 0x98, 0xcc, 0x27, 0x16, 0xf1, 0x65, 0x40, 0x20, 0x40, 0x00, 0x31, 0x16, 0xdb, 0x9c,
+ /*1f30:*/ 0x3a, 0x03, 0xc1, 0x73, 0x5f, 0x0e, 0x5a, 0xc1, 0x19, 0x5a, 0xcb, 0x72, 0x73, 0x62, 0x3c, 0x83,
+ /*1f40:*/ 0x8c, 0x05, 0x39, 0x8c, 0x10, 0x81, 0x06, 0xb9, 0x9a, 0x37, 0xed, 0x5a, 0xb0, 0x92, 0x75, 0x51,
+ /*1f50:*/ 0x20, 0x62, 0xc6, 0xca, 0xf7, 0x0d, 0xd0, 0x7a, 0x98, 0x41, 0x43, 0x5b, 0x08, 0x08, 0xb2, 0x04,
+ /*1f60:*/ 0x7f, 0x86, 0x84, 0x39, 0xe3, 0x7e, 0x5f, 0x9b, 0xff, 0x8a, 0x49, 0x78, 0x40, 0x99, 0x71, 0x77,
+ /*1f70:*/ 0xbd, 0xb3, 0x01, 0xfa, 0x4f, 0x57, 0x9c, 0xe4, 0x92, 0x00, 0xef, 0xcd, 0x60, 0x4a, 0xb8, 0x73,
+ /*1f80:*/ 0xb6, 0xd0, 0x51, 0x62, 0x34, 0x27, 0xb0, 0x40, 0xd9, 0x25, 0x8c, 0x7b, 0x47, 0x7f, 0x33, 0xdd,
+ /*1f90:*/ 0x64, 0x9d, 0x1b, 0xfb, 0xe8, 0x4f, 0x85, 0x95, 0x62, 0xb7, 0x87, 0x43, 0x47, 0x28, 0xec, 0xda,
+ /*1fa0:*/ 0x08, 0x52, 0x16, 0xca, 0x11, 0xf7, 0x35, 0x5c, 0x6d, 0xbd, 0xa6, 0x3d, 0xe3, 0x45, 0x78, 0xe7,
+ /*1fb0:*/ 0xb9, 0x08, 0xc3, 0xca, 0x97, 0x8e, 0x88, 0x6e, 0xb2, 0x00, 0x15, 0x9c, 0x44, 0x6f, 0x98, 0x80,
+ /*1fc0:*/ 0xe6, 0x24, 0x0e, 0xf9, 0xaa, 0xf6, 0x22, 0x54, 0xd5, 0xde, 0x97, 0x93, 0x77, 0x25, 0x79, 0xbf,
+ /*1fd0:*/ 0x93, 0xb1, 0x26, 0xbd, 0x8e, 0x6f, 0x71, 0xeb, 0xeb, 0x26, 0xb9, 0xca, 0x21, 0x53, 0x21, 0x73,
+ /*1fe0:*/ 0x1b, 0x09, 0x60, 0x03, 0xe3, 0x28, 0x7c, 0x8e, 0x55, 0x59, 0x99, 0x6a, 0xb8, 0xdc, 0x15, 0xf3,
+ /*1ff0:*/ 0xcf, 0x96, 0x61, 0x26, 0x2b, 0x2b, 0x32, 0xaa, 0xa0, 0x37, 0x1f, 0x3c, 0x22, 0x9e, 0xc2, 0x14,
+ /*2000:*/ 0x43, 0x79, 0x50, 0x7b, 0xf7, 0x72, 0xc8, 0xc4, 0xb5, 0x9e, 0x04, 0xe7, 0x7b, 0xd5, 0x01, 0xd0,
+ /*2010:*/ 0xd9, 0xf2, 0x57, 0x76, 0x6a, 0x11, 0xd4, 0xe5, 0x0f, 0xcd, 0xd8, 0xd1, 0x5c, 0xf1, 0x9d, 0x7e,
+ /*2020:*/ 0x31, 0x43, 0xdf, 0x82, 0x81, 0x30, 0xe1, 0xf9, 0x85, 0x9d, 0xbf, 0xe8, 0x6d, 0xb9, 0xa0, 0x40,
+ /*2030:*/ 0x4e, 0x7f, 0x88, 0x3f, 0xb4, 0x78, 0xb8, 0x5a, 0x30, 0x39, 0xf1, 0xb5, 0x3e, 0x13, 0x91, 0x63,
+ /*2040:*/ 0x88, 0xce, 0xc3, 0x29, 0xde, 0x4c, 0x40, 0x0d, 0x1f, 0x98, 0x36, 0x78, 0x0b, 0x6a, 0x0e, 0x3a,
+ /*2050:*/ 0x4c, 0x24, 0xe5, 0x5c, 0x48, 0x9f, 0x4c, 0xa7, 0xc7, 0x2d, 0x57, 0x7a, 0x2a, 0xa1, 0x5e, 0x47,
+ /*2060:*/ 0xbc, 0x29, 0x31, 0xb5, 0x51, 0xe6, 0x01, 0x22, 0x61, 0xcb, 0xed, 0x8f, 0xb9, 0xc7, 0x47, 0xf3,
+ /*2070:*/ 0x74, 0x32, 0xc3, 0x83, 0xf8, 0x29, 0x61, 0x07, 0x5d, 0xc1, 0xe4, 0x45, 0x53, 0xcd, 0x3d, 0x7a,
+ /*2080:*/ 0xfd, 0x65, 0xce, 0x29, 0xdc, 0x73, 0x22, 0xa8, 0x99, 0xfb, 0xcb, 0xee, 0xc7, 0xb4, 0x96, 0x7f,
+ /*2090:*/ 0x5a, 0xb9, 0xd6, 0xa0, 0xd1, 0xcc, 0x6f, 0x87, 0x6e, 0x82, 0x66, 0xa3, 0x81, 0xb2, 0xee, 0x2e,
+ /*20a0:*/ 0x32, 0x32, 0xd8, 0xf3, 0x3e, 0xfc, 0x43, 0xc1, 0x3c, 0x2c, 0xa4, 0x43, 0x3b, 0x10, 0x5b, 0x2b,
+ /*20b0:*/ 0xf0, 0x6a, 0xce, 0xee, 0x77, 0xb2, 0xb8, 0xac, 0x87, 0xdb, 0x6c, 0x85, 0xc5, 0x61, 0x45, 0x47,
+ /*20c0:*/ 0xb1, 0xb8, 0x95, 0x39, 0x7f, 0xdc, 0x3c, 0xfb, 0xf3, 0x1a, 0x0d, 0xbf, 0xd8, 0x43, 0xcb, 0x7b,
+ /*20d0:*/ 0xfa, 0xf0, 0xa5, 0x56, 0xca, 0x40, 0xe1, 0x54, 0xe9, 0x8a, 0x33, 0xee, 0x00, 0xdd, 0xcf, 0xb6,
+ /*20e0:*/ 0x95, 0x67, 0x91, 0x36, 0xac, 0x3b, 0xa3, 0x72, 0xf6, 0x24, 0x5c, 0xed, 0x39, 0x53, 0xc0, 0xfd,
+ /*20f0:*/ 0x25, 0x61, 0x7b, 0x4d, 0x67, 0xff, 0x5b, 0x6d, 0xce, 0x5b, 0x85, 0x9b, 0x20, 0xc5, 0x8a, 0x62,
+ /*2100:*/ 0x70, 0x14, 0x6a, 0x7e, 0x78, 0x54, 0x4b, 0x77, 0x2b, 0xb9, 0x42, 0x12, 0xca, 0xb5, 0xad, 0x37,
+ /*2110:*/ 0x6d, 0x2f, 0x3e, 0x2e, 0x32, 0x0c, 0xba, 0x17, 0x1e, 0x4b, 0xd0, 0x0f, 0x29, 0xf9, 0x45, 0xa0,
+ /*2120:*/ 0xa4, 0x7b, 0xb9, 0xce, 0x7f, 0x3a, 0xd5, 0xaf, 0x1c, 0xeb, 0x49, 0xb9, 0xb6, 0x5d, 0x61, 0x1f,
+ /*2130:*/ 0x7a, 0x36, 0xab, 0x92, 0x9e, 0xb9, 0xfb, 0x54, 0xcf, 0xf1, 0xd4, 0x1f, 0xdd, 0x48, 0xc4, 0xd1,
+ /*2140:*/ 0x6a, 0x73, 0x9d, 0x07, 0xce, 0x87, 0x9f, 0x53, 0x82, 0x28, 0x43, 0x27, 0x53, 0x85, 0x19, 0x5d,
+ /*2150:*/ 0xd6, 0x88, 0x3e, 0xe1, 0x77, 0x4a, 0x1f, 0x73, 0x4d, 0x82, 0x42, 0x87, 0x49, 0x5b, 0x1f, 0x49,
+ /*2160:*/ 0x1c, 0x46, 0xaf, 0x7f, 0xbc, 0xa4, 0xdf, 0x0b, 0xa5, 0x8f, 0xdf, 0x0a, 0x33, 0x13, 0xc4, 0x33,
+ /*2170:*/ 0xa9, 0x7c, 0x05, 0x76, 0x83, 0xbd, 0x2a, 0xa2, 0x48, 0xfa, 0xf9, 0x0a, 0xfb, 0x17, 0xa8, 0x46,
+ /*2180:*/ 0x10, 0x9b, 0x16, 0x17, 0x45, 0xa1, 0x0b, 0xf9, 0x63, 0x5f, 0x5a, 0xb7, 0x86, 0x84, 0xc8, 0x3f,
+ /*2190:*/ 0x1d, 0x8a, 0xf1, 0xba, 0x57, 0x00, 0xd9, 0x7e, 0x52, 0xf0, 0x2d, 0x05, 0x26, 0x72, 0x97, 0xb4,
+ /*21a0:*/ 0x8d, 0x92, 0x37, 0xf8, 0x02, 0x9e, 0x6a, 0x41, 0x68, 0x37, 0x76, 0xb0, 0xeb, 0xca, 0xbc, 0xd3,
+ /*21b0:*/ 0x7a, 0xdf, 0xa9, 0x2c, 0x30, 0x36, 0x1c, 0x1d, 0x0e, 0x19, 0x2b, 0xc0, 0x7a, 0x59, 0x29, 0x82,
+ /*21c0:*/ 0x36, 0x5e, 0x76, 0x8e, 0x50, 0x27, 0xc4, 0x6c, 0xfb, 0xf0, 0x19, 0x9d, 0x40, 0x0c, 0x21, 0x95,
+ /*21d0:*/ 0x2d, 0xdc, 0xaf, 0x0d, 0x23, 0xde, 0xa2, 0x6a, 0xf3, 0x7a, 0x30, 0x3e, 0x2b, 0x07, 0xd4, 0x3d,
+ /*21e0:*/ 0xaa, 0x45, 0xec, 0x32, 0x87, 0x23, 0xb2, 0xb9, 0x77, 0xca, 0x6e, 0xfb, 0x68, 0xfc, 0x22, 0x0c,
+ /*21f0:*/ 0x5a, 0xff, 0x25, 0xfa, 0x62, 0x40, 0xe7, 0xb9, 0x3f, 0x84, 0x17, 0x35, 0x2a, 0x72, 0xff, 0x42,
+ /*2200:*/ 0xab, 0x0e, 0xbe, 0xe6, 0x46, 0x28, 0xb7, 0xb3, 0x9d, 0x84, 0x7e, 0x5f, 0x02, 0xd7, 0xe9, 0xa2,
+ /*2210:*/ 0x68, 0xb1, 0x27, 0xc6, 0x89, 0xda, 0xc3, 0x37, 0x3b, 0x6c, 0x1a, 0x70, 0x08, 0xaa, 0x84, 0x7c,
+ /*2220:*/ 0xc9, 0x7e, 0x69, 0x4c, 0x5c, 0x8c, 0x98, 0x82, 0xc8, 0xe0, 0x58, 0x17, 0xeb, 0x8a, 0xda, 0x2a,
+ /*2230:*/ 0xe3, 0x68, 0x5a, 0x65, 0xef, 0x23, 0xd4, 0x46, 0x02, 0x8e, 0x68, 0xb5, 0x19, 0x25, 0x31, 0x69,
+ /*2240:*/ 0xd2, 0xc6, 0xe0, 0x84, 0x8e, 0x0a, 0xc4, 0x72, 0x9a, 0x4a, 0x1d, 0x56, 0x06, 0x4a, 0x9f, 0xaa,
+ /*2250:*/ 0x7a, 0xbe, 0x37, 0x5a, 0x38, 0xd0, 0x7b, 0xaa, 0x11, 0x40, 0x6a, 0xdb, 0xea, 0x6b, 0xa5, 0x7a,
+ /*2260:*/ 0xa3, 0x8e, 0xa1, 0x8e, 0x93, 0x9c, 0x38, 0x09, 0x27, 0x9d, 0xf2, 0x07, 0xfb, 0xf0, 0xba, 0x4d,
+ /*2270:*/ 0x9d, 0xaa, 0xa6, 0xd3, 0x32, 0x86, 0x3f, 0xd1, 0x6b, 0xcf, 0x86, 0x61, 0xdc, 0x28, 0xf0, 0x6a,
+ /*2280:*/ 0x11, 0x1f, 0x6d, 0x2e, 0xaf, 0x98, 0x59, 0x5b, 0x97, 0x2a, 0xd5, 0x5f, 0xf1, 0xca, 0x9d, 0xb6,
+ /*2290:*/ 0x48, 0x87, 0x21, 0x85, 0xfa, 0xb5, 0x80, 0x01, 0x85, 0x9e, 0xc3, 0x57, 0x20, 0xb9, 0x86, 0xea,
+ /*22a0:*/ 0x27, 0x8e, 0x29, 0xa7, 0xca, 0x5c, 0x89, 0x50, 0xc6, 0xa2, 0x6b, 0xdb, 0x0b, 0x0c, 0xc4, 0x1f,
+ /*22b0:*/ 0x57, 0x20, 0xbe, 0xfe, 0xcf, 0xca, 0x4b, 0x81, 0xb9, 0x6e, 0x82, 0x4f, 0x5d, 0xa9, 0xf5, 0x2e,
+ /*22c0:*/ 0x32, 0x07, 0x8d, 0x67, 0x65, 0x00, 0xe6, 0x92, 0x82, 0x68, 0x79, 0x54, 0x45, 0x89, 0x3e, 0xd0,
+ /*22d0:*/ 0x0d, 0x5c, 0x42, 0x11, 0xe6, 0xdd, 0xf5, 0xd0, 0x59, 0x1e, 0xd5, 0xb7, 0x0b, 0xd5, 0x80, 0xb7,
+ /*22e0:*/ 0xa9, 0x02, 0x96, 0xea, 0x77, 0x7d, 0x63, 0x72, 0x6c, 0x16, 0xb2, 0xfb, 0xf8, 0x28, 0xe5, 0xb1,
+ /*22f0:*/ 0x7a, 0x1c, 0xb0, 0xbd, 0xcd, 0xe0, 0x7f, 0xe8, 0xca, 0x36, 0xa9, 0x84, 0x87, 0x8e, 0x43, 0x42,
+ /*2300:*/ 0xe5, 0x06, 0xea, 0x4d, 0xef, 0xa5, 0x70, 0x40, 0xe1, 0xc1, 0x25, 0xec, 0x3d, 0x25, 0x14, 0xb1,
+ /*2310:*/ 0x90, 0x01, 0x67, 0x4e, 0xea, 0x7c, 0xf7, 0x8b, 0xca, 0x8d, 0x17, 0xc6, 0xa2, 0x73, 0x28, 0x09,
+ /*2320:*/ 0x8a, 0x9a, 0x02, 0x1d, 0x55, 0x86, 0xdd, 0x2f, 0x02, 0x9c, 0x3b, 0x8e, 0x2c, 0x54, 0x14, 0x62,
+ /*2330:*/ 0x5a, 0x5a, 0x96, 0x97, 0x40, 0x55, 0xd2, 0x8f, 0xb9, 0x79, 0x4e, 0x9a, 0xe0, 0xb3, 0xb8, 0xa9,
+ /*2340:*/ 0xfe, 0xbb, 0xc5, 0xca, 0x9a, 0x07, 0x9d, 0x20, 0x89, 0x9b, 0xb0, 0x2d, 0x57, 0xc9, 0x74, 0xbe,
+ /*2350:*/ 0x21, 0xc8, 0xd9, 0x6d, 0x3a, 0x12, 0xcd, 0xa8, 0xb4, 0xa4, 0x44, 0x2c, 0xca, 0xff, 0x5c, 0xd0,
+ /*2360:*/ 0xa0, 0x0a, 0x1f, 0xe4, 0x1b, 0x68, 0xbe, 0xe6, 0x27, 0xa6, 0x41, 0x58, 0xf9, 0x45, 0x5d, 0xd5,
+ /*2370:*/ 0xb0, 0x5e, 0x03, 0x29, 0xa0, 0xa7, 0x38, 0xfd, 0x80, 0x30, 0xa8, 0x59, 0x15, 0xc5, 0x9a, 0x73,
+ /*2380:*/ 0xb1, 0x37, 0xe9, 0x1f, 0xfe, 0x24, 0x29, 0x25, 0xdb, 0x02, 0xd4, 0x31, 0xbc, 0xff, 0x51, 0xc0,
+ /*2390:*/ 0x6a, 0xee, 0x2c, 0xc5, 0xe7, 0x99, 0xa2, 0x3f, 0xeb, 0xbe, 0x12, 0x89, 0xfd, 0xd7, 0x81, 0xe3,
+ /*23a0:*/ 0x2b, 0xc2, 0x17, 0x83, 0x4d, 0x0e, 0x38, 0x3d, 0x5a, 0xae, 0xf3, 0xdf, 0xd1, 0xcb, 0x1b, 0xca,
+ /*23b0:*/ 0x6f, 0xfc, 0xe9, 0xd4, 0x22, 0x6a, 0x1d, 0x22, 0xe2, 0xef, 0x2e, 0xde, 0xcd, 0x24, 0x93, 0xf1,
+ /*23c0:*/ 0x8f, 0xff, 0x43, 0x31, 0x63, 0x6b, 0xc9, 0xfc, 0x87, 0x77, 0xbe, 0x5b, 0x1c, 0x65, 0xad, 0x90,
+ /*23d0:*/ 0xd0, 0x5a, 0x63, 0x00, 0x3c, 0x41, 0x68, 0x2b, 0x1d, 0xdf, 0x4b, 0x72, 0x8c, 0xdd, 0x0a, 0x9b,
+ /*23e0:*/ 0xe6, 0xab, 0x61, 0x2f, 0xe8, 0xaa, 0x1a, 0x0f, 0x3a, 0x9b, 0x1a, 0x46, 0x6a, 0xf2, 0xaa, 0x2c,
+ /*23f0:*/ 0xa9, 0x20, 0xab, 0xf0, 0xb3, 0x6a, 0xd9, 0x8a, 0x8e, 0x28, 0x40, 0xb6, 0xd4, 0x47, 0x86, 0x0f,
+ /*2400:*/ 0x86, 0x10, 0x9c, 0xbc, 0xad, 0x68, 0x19, 0x3c, 0x4d, 0xed, 0x32, 0xa7, 0xfd, 0x26, 0xa1, 0x69,
+ /*2410:*/ 0x15, 0xf4, 0xe1, 0x59, 0x48, 0x9d, 0xab, 0x05, 0x46, 0x54, 0x3a, 0xcc, 0x77, 0x91, 0xfd, 0x48,
+ /*2420:*/ 0x21, 0x49, 0x98, 0x26, 0x9a, 0x08, 0xe9, 0x63, 0x3b, 0x43, 0x0b, 0x00, 0xa4, 0x51, 0xf3, 0xcb,
+ /*2430:*/ 0x95, 0xba, 0x03, 0x48, 0xd7, 0x6e, 0x43, 0xdc, 0x6a, 0xfa, 0x35, 0x83, 0x19, 0xd9, 0xc0, 0x90,
+ /*2440:*/ 0x3d, 0x8b, 0x22, 0x63, 0xaf, 0xb5, 0x00, 0x5d, 0x65, 0x2c, 0x5f, 0xbc, 0xad, 0x40, 0x94, 0x55,
+ /*2450:*/ 0x23, 0x0e, 0x1d, 0x14, 0x51, 0x01, 0x64, 0x28, 0x94, 0x39, 0xbc, 0x50, 0x9c, 0x76, 0xbf, 0x6c,
+ /*2460:*/ 0xd2, 0xc3, 0xd9, 0xd6, 0x8f, 0x20, 0x46, 0xe4, 0xe0, 0x6e, 0x2a, 0x36, 0x48, 0x03, 0x2c, 0x1b,
+ /*2470:*/ 0xc1, 0xdb, 0x9d, 0x91, 0x30, 0xfc, 0xf7, 0x8f, 0x05, 0x73, 0xac, 0xcc, 0x7d, 0xc6, 0x2a, 0x0f,
+ /*2480:*/ 0xc6, 0xce, 0xd6, 0x6c, 0xc9, 0x2a, 0x9f, 0x80, 0x58, 0xd0, 0x84, 0x16, 0xd6, 0xe2, 0xe8, 0x75,
+ /*2490:*/ 0x0e, 0x93, 0x96, 0x1b, 0xb3, 0xa3, 0x60, 0x24, 0x30, 0x9d, 0x67, 0xaf, 0xc3, 0x16, 0xe0, 0x36,
+ /*24a0:*/ 0xdc, 0x6e, 0x59, 0xf6, 0x81, 0xfb, 0x6c, 0x5e, 0x96, 0x5c, 0xd3, 0xac, 0xa3, 0x29, 0xdf, 0x02,
+ /*24b0:*/ 0xf3, 0x3c, 0x47, 0x1f, 0x94, 0x26, 0x9f, 0x18, 0x80, 0xc1, 0x28, 0xeb, 0x23, 0xd5, 0x7d, 0x2a,
+ /*24c0:*/ 0x73, 0x7d, 0x44, 0x40, 0x48, 0x33, 0x64, 0x4f, 0x9c, 0x69, 0x12, 0xe6, 0xa8, 0x58, 0xa6, 0x10,
+ /*24d0:*/ 0x50, 0x64, 0xb1, 0x3c, 0x6c, 0x07, 0x7e, 0xf5, 0x2d, 0x87, 0x3a, 0x67, 0xa7, 0x72, 0xad, 0xaa,
+ /*24e0:*/ 0xe8, 0x07, 0x51, 0xf0, 0xbf, 0x5d, 0x91, 0xc5, 0x3d, 0xba, 0x82, 0xe6, 0xd6, 0xf3, 0x06, 0x42,
+ /*24f0:*/ 0x38, 0x12, 0x84, 0xc1, 0x4c, 0x16, 0xc4, 0xbf, 0xca, 0xcc, 0x88, 0xcf, 0x6d, 0xb3, 0x64, 0xb7,
+ /*2500:*/ 0x83, 0x3d, 0xb3, 0xc4, 0xeb, 0x8a, 0xb4, 0x51, 0xe2, 0xd2, 0xa7, 0x7d, 0x7a, 0x42, 0x06, 0x76,
+ /*2510:*/ 0x12, 0xd2, 0xd6, 0x93, 0x59, 0xa4, 0xd9, 0x03, 0xf1, 0x86, 0x9b, 0xb3, 0xb7, 0x95, 0xcc, 0xe6,
+ /*2520:*/ 0x9f, 0x58, 0x50, 0x65, 0xfc, 0xbd, 0x56, 0xd3, 0x0c, 0x62, 0xc7, 0x26, 0x18, 0x37, 0x9f, 0x1f,
+ /*2530:*/ 0x59, 0x2e, 0x19, 0x85, 0x53, 0x2f, 0x89, 0x34, 0x6d, 0xcd, 0x55, 0x5b, 0x43, 0xe9, 0x04, 0x58,
+ /*2540:*/ 0x3d, 0x5d, 0x35, 0x8e, 0x87, 0xcc, 0x0b, 0x86, 0x3f, 0x6f, 0xdc, 0x2e, 0xb2, 0xf6, 0x9a, 0x34,
+ /*2550:*/ 0x32, 0xef, 0x53, 0x27, 0xbd, 0x7f, 0x46, 0xce, 0xf5, 0x12, 0x45, 0x61, 0x30, 0x05, 0x75, 0xa7,
+ /*2560:*/ 0x15, 0x6a, 0xb2, 0xe5, 0x64, 0xde, 0x84, 0x1b, 0xef, 0x1d, 0xeb, 0x9d, 0xc8, 0x40, 0x59, 0xf7,
+ /*2570:*/ 0xd7, 0x8d, 0xb1, 0x43, 0x4d, 0xbf, 0xb8, 0x6f, 0x5f, 0x1e, 0xd8, 0x78, 0xb0, 0x76, 0x6c, 0x98,
+ /*2580:*/ 0xb3, 0xc5, 0xe6, 0x42, 0xe6, 0x75, 0xfd, 0xeb, 0x5b, 0xc4, 0xea, 0xa8, 0xc3, 0x09, 0x0c, 0x14,
+ /*2590:*/ 0x10, 0xd3, 0x07, 0x51, 0x18, 0xb7, 0x92, 0x96, 0x9c, 0x89, 0x69, 0xa6, 0xba, 0xe4, 0xed, 0x46,
+ /*25a0:*/ 0xdd, 0x8a, 0x2b, 0x72, 0x79, 0xe5, 0x99, 0xb6, 0x9e, 0x9a, 0x6e, 0x43, 0x6f, 0xd8, 0xbb, 0x1f,
+ /*25b0:*/ 0xea, 0x95, 0xe4, 0x91, 0xfd, 0x22, 0x9a, 0xa3, 0x70, 0x17, 0x4e, 0x20, 0xc9, 0x58, 0x8b, 0x68,
+ /*25c0:*/ 0xac, 0xcb, 0x5a, 0xc6, 0xdb, 0xe4, 0x3d, 0xb6, 0x38, 0x64, 0x9a, 0x92, 0xe2, 0x7d, 0xf0, 0x4d,
+ /*25d0:*/ 0x7f, 0x7d, 0x32, 0x2c, 0xf1, 0xc5, 0x5f, 0xf6, 0x69, 0x87, 0xa9, 0x5d, 0x28, 0x5b, 0x4c, 0x47,
+ /*25e0:*/ 0xd9, 0x6a, 0x2f, 0x30, 0xdc, 0x94, 0x08, 0xe7, 0x19, 0x85, 0x82, 0x8d, 0xf7, 0xce, 0x71, 0x5e,
+ /*25f0:*/ 0x14, 0x5a, 0x69, 0x2a, 0xb1, 0x43, 0x4c, 0xc4, 0xd1, 0xbf, 0xcb, 0x22, 0x57, 0xa4, 0x17, 0x48,
+ /*2600:*/ 0x41, 0x40, 0x19, 0xb6, 0xed, 0x43, 0xf6, 0xba, 0xec, 0x75, 0x34, 0xd7, 0x1b, 0xf8, 0x24, 0x75,
+ /*2610:*/ 0xb2, 0xd3, 0x5c, 0xf3, 0xa1, 0x09, 0xea, 0xa7, 0xd8, 0x51, 0x83, 0xc4, 0xe1, 0x19, 0x4a, 0x6f,
+ /*2620:*/ 0x18, 0x23, 0xba, 0x6d, 0xea, 0x68, 0xf2, 0x9f, 0x94, 0xbd, 0x7a, 0xdc, 0xb8, 0xbf, 0x31, 0x1a,
+ /*2630:*/ 0x9e, 0xfa, 0xa2, 0xcd, 0xd2, 0x06, 0xc5, 0xd4, 0x40, 0xeb, 0x36, 0xca, 0x5a, 0xd6, 0xc6, 0x1e,
+ /*2640:*/ 0x4d, 0xdf, 0xcd, 0x9d, 0x0e, 0x03, 0x8a, 0x17, 0x0e, 0x14, 0x71, 0xf4, 0xf8, 0x7b, 0x0b, 0x3e,
+ /*2650:*/ 0x75, 0xf2, 0xed, 0x86, 0xe7, 0x80, 0xa8, 0xdc, 0x49, 0x2f, 0xe7, 0xc8, 0x4c, 0xa4, 0x41, 0x31,
+ /*2660:*/ 0xe5, 0xa4, 0x18, 0x26, 0x92, 0xd9, 0x8d, 0xb6, 0x7d, 0x8e, 0xaa, 0xff, 0x36, 0xdd, 0x05, 0x6e,
+ /*2670:*/ 0x90, 0x3f, 0x4c, 0xf8, 0x9d, 0xbc, 0xba, 0x80, 0x23, 0xa8, 0x0e, 0xff, 0x30, 0x3a, 0x72, 0x35,
+ /*2680:*/ 0xa2, 0x0d, 0x5d, 0xcc, 0xcf, 0xef, 0xc1, 0x85, 0x50, 0xdd, 0x44, 0x1e, 0x2b, 0x27, 0x1d, 0x24,
+ /*2690:*/ 0x69, 0x3c, 0xc6, 0x1d, 0xdc, 0xd7, 0x36, 0xbb, 0xc4, 0xd9, 0x6e, 0xb2, 0x47, 0x1a, 0x10, 0x31,
+ /*26a0:*/ 0xe8, 0x0d, 0xcd, 0x1a, 0x6e, 0x5f, 0xf4, 0xeb, 0xb9, 0xa2, 0xa9, 0xaa, 0x2e, 0x24, 0x63, 0xf2,
+ /*26b0:*/ 0x06, 0x8d, 0xa2, 0x9e, 0x43, 0x67, 0x5f, 0x54, 0x46, 0xa4, 0x9a, 0x21, 0xab, 0x3a, 0x94, 0xb9,
+ /*26c0:*/ 0x31, 0x26, 0x2b, 0x00, 0xd9, 0xc8, 0x8a, 0xd9, 0x21, 0x57, 0x1d, 0xad, 0x5b, 0xe7, 0x16, 0x97,
+ /*26d0:*/ 0x7b, 0xaf, 0xdc, 0x29, 0x0e, 0x65, 0xbb, 0xa6, 0x37, 0x60, 0xd3, 0x3a, 0x16, 0x54, 0xad, 0xc2,
+ /*26e0:*/ 0x24, 0x16, 0x37, 0x50, 0x70, 0xa4, 0xbf, 0x2f, 0x2e, 0xbb, 0x70, 0x7f, 0x8c, 0x02, 0x79, 0xd4,
+ /*26f0:*/ 0xd8, 0xcd, 0x30, 0x86, 0x41, 0xb2, 0x04, 0xee, 0x02, 0x48, 0xc4, 0xe3, 0x0f, 0x07, 0x16, 0x33,
+ /*2700:*/ 0x84, 0xb9, 0xe3, 0xcb, 0x93, 0x08, 0x0a, 0xb9, 0x43, 0xa3, 0xde, 0x93, 0x3c, 0x28, 0x87, 0xc6,
+ /*2710:*/ 0x86, 0xcd, 0x2c, 0x76, 0xf1, 0xcf, 0x6b, 0x9d, 0x5f, 0xe5, 0x4a, 0x2d, 0xf6, 0xa5, 0xaf, 0x07,
+ /*2720:*/ 0x86, 0xa1, 0x47, 0xa7, 0x2a, 0xb3, 0xa7, 0xa7, 0x58, 0xe4, 0x0f, 0x8c, 0x01, 0xe3, 0x1d, 0x9a,
+ /*2730:*/ 0xc5, 0xe6, 0xac, 0x1b, 0x54, 0xf0, 0x67, 0x9b, 0x41, 0xdd, 0x28, 0x6a, 0xed, 0xf0, 0x09, 0x3a,
+ /*2740:*/ 0xd1, 0x73, 0x7a, 0x22, 0x4f, 0x1e, 0x51, 0xa4, 0xdf, 0x72, 0xf7, 0xef, 0xb9, 0xbb, 0x3b, 0x4d,
+ /*2750:*/ 0x12, 0x3b, 0xd3, 0xcb, 0x3d, 0xe2, 0xe4, 0x2b, 0x11, 0x9b, 0x3a, 0xa1, 0x53, 0xaa, 0xeb, 0xc4,
+ /*2760:*/ 0xc9, 0xbc, 0x1c, 0x58, 0xd1, 0x52, 0x8f, 0x32, 0xac, 0xee, 0x91, 0xe6, 0x2f, 0x24, 0x92, 0x33,
+ /*2770:*/ 0xdd, 0xe5, 0xab, 0x20, 0x8c, 0x5f, 0x2a, 0x17, 0x93, 0x25, 0x9e, 0xb7, 0x93, 0x60, 0x6e, 0xde,
+ /*2780:*/ 0x42, 0x5e, 0x76, 0x54, 0xe9, 0x33, 0xf2, 0xd0, 0x8a, 0x15, 0xec, 0x0b, 0xff, 0x40, 0xf2, 0xe7,
+ /*2790:*/ 0x2e, 0x17, 0xeb, 0x36, 0x13, 0x9d, 0xe3, 0xd2, 0xa4, 0x14, 0x27, 0xbe, 0x8f, 0x3a, 0x80, 0xa7,
+ /*27a0:*/ 0x5d, 0xb8, 0xa7, 0xf6, 0x6a, 0x7f, 0x39, 0xdb, 0xa6, 0x39, 0x14, 0xfa, 0x57, 0xa7, 0x77, 0xbf,
+ /*27b0:*/ 0xe3, 0xe4, 0xf0, 0x8f, 0x13, 0x85, 0xd4, 0x21, 0xfb, 0x5c, 0x0d, 0xb8, 0xea, 0x0a, 0xb5, 0xb4,
+ /*27c0:*/ 0x92, 0x9f, 0x2b, 0x48, 0x47, 0x14, 0x26, 0x04, 0x4c, 0xe9, 0x66, 0x11, 0x55, 0x09, 0x09, 0x81,
+ /*27d0:*/ 0x80, 0x04, 0x2c, 0x3d, 0x2e, 0x53, 0x28, 0x5e, 0x75, 0x34, 0xc5, 0x26, 0x03, 0xfe, 0x1a, 0xe5,
+ /*27e0:*/ 0x69, 0xea, 0xec, 0x65, 0x5f, 0xaa, 0x8f, 0x51, 0xfe, 0x66, 0xd2, 0x7c, 0x14, 0x95, 0xfc, 0xaf,
+ /*27f0:*/ 0x93, 0x95, 0xe9, 0x2a, 0x21, 0x73, 0x19, 0x03, 0xc0, 0x22, 0xb8, 0xcb, 0xfa, 0x70, 0xde, 0xb1,
+ /*2800:*/ 0x22, 0xa5, 0xc1, 0xf5, 0x7c, 0xb1, 0xe4, 0x27, 0xbc, 0xd5, 0xcf, 0x5f, 0x8d, 0x0c, 0xb1, 0x32,
+ /*2810:*/ 0x32, 0x42, 0xa0, 0x9a, 0x4e, 0xbf, 0x49, 0x8f, 0xb1, 0xd9, 0x54, 0xe9, 0x43, 0x87, 0x62, 0xb2,
+ /*2820:*/ 0xe5, 0xc8, 0xda, 0xbb, 0x94, 0x2c, 0x70, 0x98, 0x53, 0x34, 0xaa, 0x5e, 0x6e, 0x83, 0x62, 0x33,
+ /*2830:*/ 0x82, 0xeb, 0x3f, 0xa2, 0x3b, 0x47, 0xfa, 0x8a, 0x53, 0x9f, 0xc4, 0xff, 0x5f, 0x42, 0x54, 0xea,
+ /*2840:*/ 0x39, 0xf6, 0xc5, 0x6f, 0x25, 0xcb, 0x8e, 0xc2, 0x6a, 0xa2, 0x89, 0xed, 0x4d, 0xee, 0x3b, 0xe9,
+ /*2850:*/ 0xba, 0x33, 0x84, 0x55, 0xc3, 0x3e, 0xae, 0xba, 0xd4, 0x1a, 0x15, 0x76, 0xe8, 0x86, 0x6c, 0xf2,
+ /*2860:*/ 0x71, 0x9e, 0xa9, 0x53, 0x47, 0xbc, 0x84, 0x0a, 0xdf, 0x7e, 0x76, 0x58, 0xdd, 0x29, 0x11, 0x33,
+ /*2870:*/ 0xa8, 0xf4, 0x83, 0xe9, 0xad, 0x0f, 0x49, 0x14, 0x5d, 0xd2, 0x1d, 0xa7, 0x9a, 0xa7, 0x99, 0xdb,
+ /*2880:*/ 0xff, 0x6c, 0x7d, 0x15, 0x8d, 0x8a, 0x57, 0x2e, 0x20, 0x0a, 0xcb, 0x45, 0x76, 0x0b, 0x7b, 0xf0,
+ /*2890:*/ 0x7f, 0xb7, 0x76, 0x74, 0x25, 0xec, 0x3c, 0x57, 0xd7, 0x59, 0xb0, 0x8e, 0xef, 0xb3, 0x69, 0xa6,
+ /*28a0:*/ 0x56, 0x78, 0x16, 0x52, 0x5a, 0xa1, 0x1a, 0xf1, 0x71, 0xe6, 0xfb, 0x0e, 0xcc, 0xde, 0xa7, 0xf5,
+ /*28b0:*/ 0x13, 0x3f, 0xe4, 0x6a, 0x8f, 0x59, 0xb1, 0x99, 0x3b, 0x87, 0x51, 0xee, 0x93, 0x50, 0xd6, 0xac,
+ /*28c0:*/ 0x70, 0xc6, 0xd8, 0x62, 0xad, 0x35, 0xc0, 0xb4, 0xd4, 0x2b, 0xba, 0x47, 0x5c, 0x7d, 0xc9, 0xb5,
+ /*28d0:*/ 0x77, 0x88, 0xf2, 0x89, 0x2e, 0x0e, 0x32, 0x9d, 0x7f, 0xc5, 0x23, 0x59, 0xc7, 0x9c, 0x2e, 0xa4,
+ /*28e0:*/ 0x55, 0x9f, 0xd1, 0xbd, 0xaf, 0x79, 0x22, 0xb3, 0xdc, 0xb6, 0xb0, 0xc4, 0xa6, 0x94, 0x0b, 0x75,
+ /*28f0:*/ 0x84, 0x73, 0xb4, 0x9e, 0xed, 0xd5, 0x7b, 0x4d, 0x2c, 0x99, 0x38, 0x40, 0xd1, 0xec, 0x86, 0x20,
+ /*2900:*/ 0x98, 0xe4, 0x4b, 0xad, 0xa4, 0x1f, 0x52, 0xb1, 0x1e, 0xc1, 0x6a, 0x36, 0xe1, 0x81, 0x01, 0xf8,
+ /*2910:*/ 0xea, 0xbf, 0xaf, 0x50, 0xcb, 0x26, 0x91, 0xc0, 0xaf, 0x58, 0x83, 0x18, 0x35, 0x9f, 0x5d, 0x81,
+ /*2920:*/ 0x2d, 0xb6, 0x57, 0x44, 0xce, 0x5f, 0x90, 0x0d, 0x80, 0x6c, 0xd3, 0xc7, 0x54, 0x09, 0x17, 0xde,
+ /*2930:*/ 0xe7, 0x6c, 0xef, 0x31, 0xa5, 0x19, 0xc3, 0xfd, 0x8e, 0x66, 0xd5, 0x6c, 0x12, 0x3c, 0x42, 0xc6,
+ /*2940:*/ 0x35, 0xc8, 0x76, 0x06, 0x1e, 0xc0, 0xfc, 0xe7, 0xc0, 0x0c, 0x0c, 0x79, 0xec, 0x36, 0x82, 0xf2,
+ /*2950:*/ 0xcc, 0x60, 0x97, 0x2e, 0xf7, 0x81, 0x35, 0xa0, 0x47, 0x1b, 0xbc, 0xfe, 0x2e, 0x0f, 0xdc, 0xfc,
+ /*2960:*/ 0xa6, 0xc2, 0xe5, 0x86, 0x4f, 0x26, 0x8d, 0x45, 0x1f, 0x41, 0xdf, 0x94, 0x0c, 0x7e, 0x56, 0x3f,
+ /*2970:*/ 0x1c, 0x8a, 0xfd, 0x31, 0x83, 0xf8, 0x14, 0x25, 0xf0, 0x01, 0x42, 0x26, 0xe3, 0xf8, 0x9a, 0x17,
+ /*2980:*/ 0xa8, 0x9b, 0x88, 0x39, 0x52, 0x1e, 0x4b, 0x8b, 0x06, 0x67, 0x75, 0x7d, 0xa1, 0x11, 0x4a, 0x98,
+ /*2990:*/ 0x2c, 0x84, 0x91, 0x87, 0xdc, 0x4a, 0xf7, 0x8d, 0x81, 0x60, 0x85, 0xb9, 0xd8, 0x70, 0x55, 0xa6,
+ /*29a0:*/ 0xae, 0x44, 0xbd, 0x27, 0x2a, 0x4e, 0x36, 0xcc, 0x02, 0x8e, 0x21, 0x4b, 0xbf, 0xdc, 0x86, 0xa8,
+ /*29b0:*/ 0xb8, 0x61, 0xad, 0x98, 0x96, 0xd5, 0x02, 0xc5, 0x1f, 0xe2, 0x6b, 0xf3, 0x4c, 0x54, 0xc0, 0x4f,
+ /*29c0:*/ 0xfb, 0x39, 0x1a, 0xf7, 0x2e, 0x56, 0xc8, 0x95, 0x7e, 0x1f, 0xeb, 0xa9, 0x1e, 0xec, 0xe7, 0x48,
+ /*29d0:*/ 0x2c, 0x03, 0x11, 0xde, 0xec, 0x97, 0x23, 0x2e, 0x16, 0x42, 0x4c, 0xdd, 0x4b, 0x18, 0x32, 0x6e,
+ /*29e0:*/ 0x6e, 0x0e, 0x1f, 0xf9, 0x69, 0xbd, 0xde, 0xf9, 0x37, 0xb8, 0xf8, 0x98, 0xf8, 0x5c, 0x88, 0xaa,
+ /*29f0:*/ 0x61, 0xb3, 0xe7, 0x79, 0x92, 0x68, 0xef, 0x86, 0x04, 0xba, 0x18, 0x5e, 0xa6, 0x03, 0x68, 0x4b,
+ /*2a00:*/ 0x26, 0xe5, 0x5f, 0x0f, 0xf6, 0xb2, 0xae, 0x02, 0x40, 0xbe, 0xa7, 0x1a, 0xec, 0x22, 0x5e, 0xe6,
+ /*2a10:*/ 0x21, 0x42, 0xd9, 0xb0, 0xd2, 0xe4, 0x89, 0xf5, 0xd0, 0x2d, 0xd6, 0x23, 0x39, 0xc9, 0xdb, 0xeb,
+ /*2a20:*/ 0x53, 0x55, 0xbf, 0x01, 0x36, 0x17, 0xf9, 0x05, 0x20, 0x80, 0x13, 0x38, 0x32, 0x2d, 0x09, 0x98,
+ /*2a30:*/ 0x04, 0x6a, 0x90, 0x6c, 0x18, 0x52, 0x41, 0x82, 0xc7, 0x0c, 0xe9, 0xae, 0x12, 0x35, 0xc9, 0xaf,
+ /*2a40:*/ 0x43, 0x52, 0x68, 0x19, 0x2f, 0xff, 0x75, 0xf7, 0xab, 0x9d, 0x58, 0x13, 0x0f, 0xa4, 0x17, 0x3f,
+ /*2a50:*/ 0x9f, 0x29, 0x37, 0xb9, 0x28, 0x00, 0x19, 0x06, 0xb9, 0xe9, 0x54, 0x6d, 0xa7, 0x21, 0x58, 0xf9,
+ /*2a60:*/ 0xa5, 0xf2, 0xc5, 0x10, 0x50, 0x0d, 0x50, 0x0d, 0xb4, 0xe5, 0xb8, 0x27, 0xa3, 0xe7, 0xab, 0x25,
+ /*2a70:*/ 0x8d, 0x8c, 0x09, 0x28, 0xd8, 0x8c, 0x69, 0x34, 0xd2, 0x8e, 0xa1, 0xf7, 0x49, 0x35, 0xa0, 0x2f,
+ /*2a80:*/ 0x06, 0x38, 0x57, 0xfe, 0x6f, 0xdc, 0x68, 0xcd, 0xfc, 0x71, 0xf1, 0x9e, 0xb9, 0x1e, 0x75, 0xff,
+ /*2a90:*/ 0x90, 0x36, 0xbc, 0x7a, 0x86, 0x65, 0xd3, 0xeb, 0x71, 0xa1, 0x62, 0x05, 0x33, 0xa5, 0x3c, 0xe5,
+ /*2aa0:*/ 0x2b, 0xfd, 0x7b, 0x4c, 0x25, 0x6f, 0x7b, 0xba, 0xdf, 0x90, 0x9e, 0xed, 0x8c, 0x1a, 0x7b, 0xac,
+ /*2ab0:*/ 0x08, 0xa7, 0x7d, 0xf4, 0xf4, 0xa2, 0x60, 0x48, 0xd5, 0x53, 0x39, 0xb4, 0xd9, 0x59, 0x8c, 0xcc,
+ /*2ac0:*/ 0x20, 0xb7, 0x16, 0x97, 0x7e, 0xd9, 0x6f, 0x2b, 0x57, 0xd9, 0xb5, 0xfa, 0x67, 0x3f, 0xc6, 0x45,
+ /*2ad0:*/ 0x50, 0x16, 0x24, 0x46, 0x4f, 0x5c, 0xfe, 0x43, 0xc7, 0x7d, 0x35, 0xec, 0x69, 0x41, 0xf6, 0x8f,
+ /*2ae0:*/ 0xaf, 0x55, 0x53, 0x43, 0xc7, 0x08, 0x1c, 0x15, 0x0e, 0x77, 0xea, 0x2d, 0x80, 0x05, 0xf6, 0x5e,
+ /*2af0:*/ 0x66, 0x93, 0x9b, 0x2b, 0xd8, 0xc3, 0xc1, 0xf4, 0x3a, 0x6e, 0x1a, 0x81, 0x7e, 0xba, 0x14, 0xe2,
+ /*2b00:*/ 0x62, 0x13, 0xb4, 0x2b, 0x64, 0x83, 0x75, 0x8d, 0x7c, 0xce, 0x9d, 0xbd, 0x65, 0xd5, 0x4b, 0x28,
+ /*2b10:*/ 0x37, 0xb3, 0xc2, 0x7c, 0xcd, 0xbd, 0x68, 0x52, 0xa9, 0x23, 0x3e, 0xdf, 0xb6, 0xec, 0x34, 0x06,
+ /*2b20:*/ 0x36, 0xd7, 0x41, 0x1e, 0xff, 0x03, 0xa3, 0x53, 0x76, 0x06, 0x05, 0x1f, 0xe0, 0x56, 0xc7, 0xb5,
+ /*2b30:*/ 0x13, 0xc1, 0x82, 0x6c, 0x72, 0x9f, 0x9f, 0xa5, 0x33, 0x68, 0x2f, 0x54, 0x75, 0x02, 0xd6, 0xfa,
+ /*2b40:*/ 0x02, 0x9d, 0xe2, 0xde, 0xaf, 0x77, 0xb6, 0x5d, 0xc7, 0xa6, 0xff, 0xaf, 0x91, 0x07, 0x63, 0xd5,
+ /*2b50:*/ 0x75, 0xf4, 0xa6, 0xf6, 0x66, 0xe2, 0x8c, 0xb0, 0xf5, 0x40, 0xd8, 0xc3, 0xfd, 0x7c, 0xb7, 0xe4,
+ /*2b60:*/ 0x6f, 0xd1, 0xfa, 0xe5, 0x86, 0xba, 0x04, 0xb4, 0x65, 0xba, 0x92, 0x80, 0xa0, 0x40, 0x2c, 0xe1,
+ /*2b70:*/ 0x5f, 0xdb, 0xc3, 0x62, 0x73, 0xf7, 0xa9, 0x9d, 0xbf, 0x17, 0x13, 0x6d, 0xc9, 0x4a, 0x8a, 0x51,
+ /*2b80:*/ 0x72, 0x8f, 0xad, 0x35, 0x5a, 0xac, 0x43, 0x70, 0xd2, 0xc2, 0x64, 0xaf, 0x33, 0x76, 0xe5, 0xda,
+ /*2b90:*/ 0x59, 0xb2, 0xdf, 0x54, 0x61, 0x9f, 0x9a, 0xa3, 0x57, 0x74, 0xf1, 0x22, 0xcc, 0x4d, 0x87, 0x68,
+ /*2ba0:*/ 0x4f, 0x77, 0xcb, 0xc1, 0x7c, 0xb5, 0xaf, 0x6f, 0xe0, 0x79, 0xbd, 0xa6, 0x2b, 0xf1, 0xb3, 0x4c,
+ /*2bb0:*/ 0xcf, 0x7e, 0xa4, 0x41, 0x32, 0x49, 0x72, 0x8b, 0x3c, 0xaf, 0xe4, 0xf4, 0x38, 0x30, 0x95, 0xb7,
+ /*2bc0:*/ 0x16, 0x80, 0x59, 0x18, 0x3d, 0x24, 0x91, 0xa5, 0x13, 0x4e, 0x8e, 0xe3, 0xe0, 0x55, 0x86, 0x3c,
+ /*2bd0:*/ 0xe9, 0x28, 0xae, 0x85, 0x2a, 0x08, 0xa0, 0xa5, 0x99, 0xdd, 0x66, 0xfd, 0x55, 0x4f, 0x71, 0x73,
+ /*2be0:*/ 0x05, 0xd6, 0x82, 0xbf, 0x7f, 0x4c, 0x3f, 0x20, 0xaf, 0x7d, 0x15, 0x71, 0x5a, 0x1a, 0x11, 0xaf,
+ /*2bf0:*/ 0xcc, 0xc8, 0x3f, 0x3a, 0x20, 0x0e, 0x87, 0x31, 0xdb, 0x6a, 0xe7, 0x41, 0x26, 0x72, 0xce, 0xe0,
+ /*2c00:*/ 0xd7, 0x69, 0x04, 0x34, 0x58, 0x82, 0xac, 0x25, 0x70, 0x0f, 0x2a, 0x71, 0x4b, 0x03, 0x39, 0x74,
+ /*2c10:*/ 0x74, 0x7a, 0x42, 0xde, 0x91, 0xaa, 0xdf, 0xf3, 0x9c, 0x7f, 0x72, 0x54, 0x40, 0x31, 0x01, 0xfd,
+ /*2c20:*/ 0x71, 0xc5, 0x2d, 0x5e, 0xfa, 0xb9, 0xab, 0x2c, 0x86, 0x63, 0x6e, 0xa7, 0xde, 0x01, 0xe8, 0x0f,
+ /*2c30:*/ 0x97, 0x72, 0xa2, 0x18, 0x4b, 0xd8, 0xb1, 0x04, 0xd7, 0x66, 0x2b, 0xad, 0x5b, 0xe5, 0x2c, 0x68,
+ /*2c40:*/ 0x78, 0xb4, 0xb5, 0x28, 0xc3, 0x8b, 0x05, 0x01, 0xf3, 0xcc, 0xf0, 0x21, 0x30, 0x1b, 0xd4, 0xab,
+ /*2c50:*/ 0x0a, 0x97, 0x8e, 0x46, 0xcf, 0x9a, 0xc7, 0x40, 0xe2, 0xd0, 0x8f, 0x00, 0xd7, 0x02, 0x7e, 0xab,
+ /*2c60:*/ 0xd3, 0xd4, 0xf4, 0x8d, 0x1f, 0x3e, 0x29, 0x26, 0x17, 0xf6, 0x06, 0xfa, 0x41, 0x45, 0x53, 0xa6,
+ /*2c70:*/ 0x9d, 0x50, 0xdc, 0xf8, 0x19, 0x76, 0x83, 0xc7, 0x9c, 0xe3, 0x24, 0x24, 0xd3, 0x3a, 0x14, 0x61,
+ /*2c80:*/ 0xb5, 0x6b, 0x08, 0x21, 0x08, 0xb1, 0xe5, 0x64, 0x8f, 0x5c, 0x2f, 0x17, 0x47, 0xef, 0x89, 0x72,
+ /*2c90:*/ 0x9d, 0x9e, 0x24, 0x36, 0xe9, 0x38, 0x11, 0xf2, 0x1c, 0xaf, 0x15, 0xe3, 0xac, 0x90, 0x93, 0x91,
+ /*2ca0:*/ 0x22, 0x30, 0x7f, 0x4d, 0x13, 0x3f, 0x64, 0x5e, 0x60, 0xc0, 0xf3, 0x47, 0xad, 0xdb, 0x94, 0xc4,
+ /*2cb0:*/ 0x10, 0x2e, 0xdd, 0x45, 0x21, 0xc7, 0xca, 0x0d, 0xd2, 0x3e, 0xb8, 0x28, 0xa3, 0x6c, 0x75, 0xfd,
+ /*2cc0:*/ 0xbc, 0xf7, 0x05, 0x70, 0x00, 0xf6, 0xda, 0xc4, 0xd0, 0x6d, 0xa7, 0x67, 0x3a, 0xa2, 0x1e, 0x4f,
+ /*2cd0:*/ 0xdc, 0xf8, 0x5c, 0xde, 0xb8, 0x63, 0xe6, 0xcd, 0xcd, 0x9f, 0x63, 0x54, 0x34, 0xd4, 0xa7, 0xd2,
+ /*2ce0:*/ 0xcf, 0xef, 0x89, 0x81, 0x83, 0x93, 0xf1, 0xda, 0xee, 0x97, 0x5a, 0x97, 0x89, 0x62, 0x03, 0xc6,
+ /*2cf0:*/ 0x64, 0x9d, 0x1f, 0xbb, 0x4e, 0x11, 0xf8, 0x7f, 0x6e, 0x3a, 0xd9, 0x97, 0x0d, 0xb6, 0xf1, 0x8c,
+ /*2d00:*/ 0xfd, 0x2d, 0x21, 0x3a, 0x20, 0xee, 0x22, 0x0a, 0xca, 0x9a, 0x46, 0x95, 0x99, 0x70, 0x84, 0x62,
+ /*2d10:*/ 0x65, 0x4c, 0x56, 0x13, 0x9f, 0xc4, 0xf3, 0xb1, 0x3a, 0x05, 0xe9, 0x14, 0xec, 0xb4, 0x63, 0x17,
+ /*2d20:*/ 0x08, 0x63, 0xc5, 0x3c, 0x0f, 0xf2, 0x26, 0xea, 0x2e, 0xc1, 0x0d, 0xc8, 0xe8, 0x02, 0x36, 0xbb,
+ /*2d30:*/ 0x62, 0x69, 0x99, 0x0e, 0xfc, 0xa9, 0x84, 0x1a, 0xfa, 0x38, 0xb3, 0xac, 0x7f, 0x74, 0x9e, 0x7f,
+ /*2d40:*/ 0xad, 0xeb, 0x76, 0xab, 0x09, 0xba, 0x81, 0x4e, 0x2a, 0x68, 0x00, 0xce, 0x1f, 0xc2, 0xc2, 0x25,
+ /*2d50:*/ 0x86, 0x77, 0x70, 0x27, 0x23, 0xe7, 0xf2, 0x71, 0x50, 0xc2, 0x0b, 0x30, 0x98, 0xbc, 0x0d, 0xb3,
+ /*2d60:*/ 0x41, 0xa7, 0x30, 0xc4, 0x32, 0x96, 0x5d, 0xa8, 0x57, 0xa4, 0x89, 0x16, 0xd3, 0x4f, 0x4b, 0x6c,
+ /*2d70:*/ 0xb3, 0xea, 0xc3, 0x8f, 0xc1, 0x4b, 0x19, 0xc8, 0x3d, 0xea, 0xe3, 0xf2, 0x57, 0x94, 0x4f, 0x27,
+ /*2d80:*/ 0x87, 0x19, 0x07, 0x46, 0xfb, 0x3e, 0x52, 0x5c, 0xdc, 0x5b, 0xb4, 0xd5, 0xee, 0x16, 0x39, 0x70,
+ /*2d90:*/ 0x2c, 0x0c, 0xf2, 0xe5, 0x78, 0xef, 0x10, 0xe9, 0x0f, 0xbd, 0x30, 0xdb, 0x42, 0xb9, 0xb5, 0x04,
+ /*2da0:*/ 0x0f, 0xa6, 0x43, 0x7b, 0x93, 0x3b, 0xb5, 0xf3, 0xb0, 0x1c, 0x52, 0x5e, 0x68, 0xb4, 0xda, 0xba,
+ /*2db0:*/ 0x3b, 0x66, 0x50, 0x97, 0xcd, 0x26, 0xf0, 0x3c, 0x76, 0xa3, 0xad, 0xe1, 0x42, 0x00, 0xde, 0x59,
+ /*2dc0:*/ 0x90, 0x70, 0xf5, 0x2f, 0x71, 0xd5, 0x82, 0x83, 0xfb, 0x74, 0xd2, 0x46, 0xbc, 0xad, 0x40, 0xf3,
+ /*2dd0:*/ 0x37, 0x9e, 0x6e, 0xa6, 0xa7, 0x1a, 0x3e, 0xbb, 0x5b, 0xd3, 0x09, 0x04, 0x68, 0xcf, 0xdb, 0xdd,
+ /*2de0:*/ 0x9e, 0x31, 0x4d, 0xf9, 0x41, 0x8d, 0xf2, 0xfc, 0x8b, 0xc6, 0x84, 0xf0, 0x77, 0xd6, 0xf0, 0x33,
+ /*2df0:*/ 0x5f, 0x8c, 0x26, 0x23, 0x96, 0x7a, 0x28, 0x6c, 0xfd, 0x39, 0xab, 0xa8, 0x95, 0xd2, 0xa6, 0x93,
+ /*2e00:*/ 0xe0, 0x0e, 0xe5, 0x2d, 0x92, 0xa4, 0xee, 0xfe, 0x4e, 0x7e, 0x7e, 0xe3, 0xae, 0x1d, 0x85, 0xfb,
+ /*2e10:*/ 0xb7, 0xc3, 0x7c, 0x16, 0x83, 0x98, 0x62, 0x48, 0xfe, 0x97, 0xae, 0xc7, 0x43, 0x00, 0xc4, 0xe7,
+ /*2e20:*/ 0x62, 0xc1, 0xcf, 0xfe, 0x7d, 0xce, 0xbe, 0xdc, 0xfa, 0x73, 0xde, 0xc5, 0x04, 0x22, 0x56, 0x18,
+ /*2e30:*/ 0x9c, 0xf9, 0xea, 0xab, 0x3a, 0x82, 0xb6, 0xab, 0xc7, 0x55, 0xe1, 0xe7, 0x4e, 0x88, 0xc9, 0xf5,
+ /*2e40:*/ 0x48, 0x1a, 0x92, 0xd0, 0x2e, 0x2a, 0x00, 0xbe, 0x2f, 0x10, 0x74, 0x8e, 0xde, 0x04, 0x01, 0x82,
+ /*2e50:*/ 0xe3, 0x21, 0xc2, 0x63, 0xab, 0x2b, 0x68, 0x6a, 0x2b, 0xfb, 0xd8, 0xca, 0xb9, 0x8b, 0x75, 0xe3,
+ /*2e60:*/ 0xd5, 0xe3, 0xcf, 0x0d, 0xde, 0x70, 0x39, 0x88, 0x85, 0xa5, 0x52, 0x96, 0x6c, 0x95, 0x44, 0x8b,
+ /*2e70:*/ 0x5e, 0x31, 0x57, 0xb3, 0xe8, 0xef, 0x7a, 0x1e, 0xfa, 0x56, 0x4a, 0xe9, 0x5a, 0xb2, 0xba, 0x24,
+ /*2e80:*/ 0x01, 0x19, 0x1c, 0x4e, 0xa9, 0xd3, 0xdf, 0xcb, 0xe0, 0x48, 0xb1, 0xd6, 0x30, 0xca, 0xa8, 0x5c,
+ /*2e90:*/ 0x91, 0x2f, 0x37, 0x8b, 0x9a, 0x06, 0x2a, 0x4d, 0x30, 0x32, 0x13, 0x4b, 0x4b, 0x67, 0x61, 0xbc,
+ /*2ea0:*/ 0xc3, 0x74, 0xae, 0xeb, 0xcb, 0x45, 0xd6, 0xaa, 0xf7, 0x60, 0xb6, 0x4b, 0xf5, 0x83, 0xe8, 0x7f,
+ /*2eb0:*/ 0x3a, 0x91, 0xdd, 0x92, 0xfa, 0xe7, 0x49, 0x8c, 0x20, 0x60, 0x74, 0x68, 0xe5, 0x24, 0xce, 0xc1,
+ /*2ec0:*/ 0x83, 0xa7, 0x43, 0xb3, 0x8d, 0x3f, 0xd6, 0x23, 0x2b, 0x1c, 0xc5, 0x7d, 0xdc, 0x00, 0xea, 0x3f,
+ /*2ed0:*/ 0x78, 0xc8, 0x72, 0x9a, 0x59, 0x37, 0x86, 0xfb, 0x33, 0x35, 0x8f, 0x9f, 0x7d, 0x67, 0xe9, 0x6e,
+ /*2ee0:*/ 0x11, 0xd5, 0x0e, 0x95, 0x3d, 0xcc, 0xb7, 0x1d, 0x06, 0xf5, 0x72, 0x48, 0xdc, 0x8f, 0xbe, 0xbf,
+ /*2ef0:*/ 0xd2, 0x37, 0x03, 0xa9, 0x2f, 0xa6, 0x7e, 0x73, 0xd7, 0xbe, 0xd2, 0xd2, 0x21, 0xbf, 0x1d, 0xf4,
+ /*2f00:*/ 0x61, 0xd1, 0x58, 0x0e, 0x83, 0xcd, 0xdb, 0x2a, 0x94, 0x5c, 0xe7, 0x38, 0x34, 0x68, 0x3a, 0x12,
+ /*2f10:*/ 0x80, 0xa7, 0x2b, 0x5a, 0xc6, 0x49, 0x20, 0x8f, 0x45, 0x5d, 0x04, 0xcf, 0xc6, 0xc8, 0xa3, 0x24,
+ /*2f20:*/ 0xc7, 0x33, 0xb3, 0x6c, 0x63, 0x78, 0x8f, 0xcf, 0xe3, 0x61, 0xf5, 0xe3, 0x0a, 0x43, 0xfd, 0x89,
+ /*2f30:*/ 0x62, 0x82, 0xe0, 0x91, 0x66, 0xf4, 0x04, 0x60, 0xe2, 0x15, 0x1a, 0x81, 0xe2, 0x1e, 0x6f, 0xc6,
+ /*2f40:*/ 0xcc, 0x87, 0xe4, 0xb5, 0xf2, 0xe5, 0xcf, 0x22, 0x11, 0xfe, 0x03, 0x3a, 0xc3, 0x0f, 0x0c, 0xe7,
+ /*2f50:*/ 0xb7, 0x87, 0xf9, 0x45, 0x5a, 0x78, 0x18, 0xba, 0x73, 0x63, 0x4d, 0x89, 0x00, 0xeb, 0x35, 0xa6,
+ /*2f60:*/ 0xee, 0x71, 0xa1, 0xb1, 0x17, 0xc6, 0x83, 0x69, 0xab, 0x7a, 0x18, 0xed, 0xaa, 0x1c, 0x56, 0x88,
+ /*2f70:*/ 0x89, 0x3e, 0x3a, 0x54, 0x18, 0x7d, 0x3e, 0x72, 0x86, 0x0f, 0xa4, 0xfb, 0x96, 0x14, 0x12, 0x7b,
+ /*2f80:*/ 0x94, 0x3c, 0x6a, 0xbc, 0x8b, 0x2d, 0x81, 0x36, 0x24, 0x12, 0xfc, 0x73, 0x78, 0xcd, 0xe4, 0x7a,
+ /*2f90:*/ 0xfb, 0xd2, 0x48, 0xfa, 0x59, 0x8b, 0xf0, 0x2a, 0xe8, 0xae, 0xf5, 0x88, 0x31, 0xdf, 0xbe, 0x89,
+ /*2fa0:*/ 0x6b, 0x6e, 0xa1, 0x8f, 0x57, 0x94, 0x92, 0x0c, 0x0c, 0x23, 0x81, 0x6b, 0x48, 0x9b, 0xe7, 0x96,
+ /*2fb0:*/ 0xd3, 0xe3, 0x3b, 0x4a, 0xff, 0xe4, 0x7a, 0x79, 0xa2, 0x25, 0xf0, 0x08, 0x04, 0x59, 0x91, 0xe3,
+ /*2fc0:*/ 0x44, 0xa4, 0xf1, 0xe6, 0x56, 0x34, 0xc0, 0x94, 0x75, 0x51, 0x7c, 0x78, 0x71, 0xdd, 0xb9, 0x36,
+ /*2fd0:*/ 0xb8, 0xf5, 0xc3, 0xf4, 0xb6, 0x87, 0x72, 0xcb, 0x99, 0x79, 0x24, 0x12, 0xc8, 0x3e, 0xf6, 0xcd,
+ /*2fe0:*/ 0x00, 0x6f, 0x4e, 0x47, 0xac, 0x90, 0x08, 0x69, 0x26, 0xd2, 0x5e, 0x84, 0x71, 0x5f, 0xb2, 0x1e,
+ /*2ff0:*/ 0x7f, 0x3c, 0x9d, 0x9d, 0x11, 0x37, 0xa6, 0x2d, 0x12, 0x0c, 0xb3, 0x43, 0x2b, 0xe0, 0x03, 0x40,
+ /*3000:*/ 0x04, 0x7b, 0xc5, 0x3a, 0x76, 0xf1, 0xa0, 0xf6, 0x40, 0x30, 0x60, 0xf7, 0xe4, 0x08, 0x0f, 0x0e,
+ /*3010:*/ 0x3a, 0x7d, 0x2c, 0xac, 0xe1, 0x11, 0xfc, 0x01, 0xef, 0x9c, 0x5b, 0x94, 0xda, 0x52, 0x80, 0xe4,
+ /*3020:*/ 0x98, 0x17, 0x01, 0xc2, 0x95, 0xa2, 0xce, 0x8b, 0x61, 0xb2, 0x96, 0x70, 0xdc, 0xfc, 0x33, 0x63,
+ /*3030:*/ 0x25, 0xa2, 0x7a, 0x70, 0xe3, 0xb5, 0x65, 0x98, 0xe2, 0x99, 0x46, 0x54, 0x0d, 0x36, 0xff, 0xfd,
+ /*3040:*/ 0x36, 0x4d, 0x26, 0x4c, 0x1d, 0x67, 0xea, 0xd8, 0x2b, 0x0d, 0xd4, 0x9f, 0xab, 0x77, 0xde, 0x9d,
+ /*3050:*/ 0x0d, 0xa1, 0x12, 0x41, 0xa6, 0xc5, 0x37, 0x6d, 0x76, 0xdb, 0xdb, 0xa2, 0x90, 0xa3, 0xbf, 0x96,
+ /*3060:*/ 0xb7, 0xef, 0x0b, 0xd0, 0xf0, 0xda, 0x1e, 0x91, 0xcf, 0x4e, 0xd8, 0x18, 0x0e, 0x80, 0x0a, 0x4b,
+ /*3070:*/ 0x51, 0xf0, 0x05, 0xb0, 0x18, 0xc2, 0x95, 0xb7, 0xa6, 0x83, 0x66, 0x92, 0x99, 0x06, 0x0e, 0x93,
+ /*3080:*/ 0xff, 0x18, 0x70, 0x1c, 0x4f, 0xec, 0x72, 0x13, 0x38, 0xcb, 0x6d, 0xe7, 0x81, 0x7a, 0xb4, 0x90,
+ /*3090:*/ 0x16, 0xc2, 0xac, 0xaa, 0x09, 0xdc, 0x5b, 0xe2, 0x6a, 0xf3, 0xfe, 0xc6, 0x63, 0x17, 0x33, 0x72,
+ /*30a0:*/ 0xbd, 0xee, 0x7c, 0xb4, 0x1c, 0x54, 0x18, 0xff, 0x10, 0x87, 0xe1, 0x26, 0xe5, 0xa6, 0x1a, 0xba,
+ /*30b0:*/ 0xd3, 0x96, 0x31, 0xf1, 0x95, 0x71, 0xbf, 0xe2, 0x6e, 0x37, 0xaa, 0x89, 0x64, 0x94, 0xdf, 0x77,
+ /*30c0:*/ 0xc3, 0x26, 0x42, 0xe2, 0xc2, 0xa5, 0x62, 0xea, 0x02, 0x58, 0xa6, 0x55, 0x71, 0xe5, 0xf5, 0x5b,
+ /*30d0:*/ 0x3c, 0xea, 0x7f, 0x64, 0xac, 0xc0, 0xc4, 0x86, 0xc0, 0xa9, 0xeb, 0xcb, 0x17, 0x13, 0xff, 0x9e,
+ /*30e0:*/ 0xe0, 0xbb, 0xd0, 0x78, 0xfb, 0xfb, 0x5e, 0xe8, 0xb9, 0xbc, 0x71, 0x91, 0x67, 0x17, 0x18, 0x57,
+ /*30f0:*/ 0x66, 0x96, 0x10, 0x74, 0xca, 0xb9, 0x26, 0x7b, 0x4d, 0x70, 0xf0, 0xa7, 0x17, 0x45, 0xe8, 0x9a,
+ /*3100:*/ 0xe6, 0x8a, 0x20, 0xca, 0x70, 0x36, 0x05, 0x97, 0x9b, 0x72, 0x5b, 0xf4, 0x8d, 0x53, 0x53, 0xbb,
+ /*3110:*/ 0x7f, 0xdd, 0x50, 0xb7, 0x15, 0xec, 0xd2, 0x2f, 0x4b, 0xa6, 0xdc, 0x3d, 0x35, 0xf4, 0xa0, 0x33,
+ /*3120:*/ 0xaa, 0x3a, 0xff, 0x10, 0x6f, 0x90, 0x12, 0x28, 0x2b, 0x63, 0x07, 0xa6, 0x9d, 0xd9, 0xa7, 0x9a,
+ /*3130:*/ 0x3c, 0x70, 0xbd, 0x00, 0x8f, 0x32, 0x13, 0x70, 0xff, 0xd0, 0x19, 0x50, 0xcb, 0x96, 0x3f, 0xfe,
+ /*3140:*/ 0x11, 0x89, 0x27, 0xfb, 0xbf, 0x3d, 0x0d, 0x76, 0x99, 0x06, 0xc3, 0x75, 0xd4, 0xa4, 0x3c, 0xbe,
+ /*3150:*/ 0xdb, 0x7c, 0x0c, 0xf1, 0xb7, 0xf4, 0x56, 0xdd, 0x90, 0x54, 0xbd, 0x3e, 0x69, 0x15, 0xda, 0x17,
+ /*3160:*/ 0xf7, 0xb8, 0x06, 0xf5, 0xab, 0x2d, 0x69, 0xb2, 0xaf, 0xa9, 0x01, 0xa0, 0xc4, 0x61, 0x79, 0x63,
+ /*3170:*/ 0xb9, 0x9c, 0x06, 0x21, 0x1d, 0x8c, 0xd3, 0x31, 0x65, 0x12, 0x4e, 0xb0, 0xcb, 0x2a, 0x36, 0x06,
+ /*3180:*/ 0x28, 0xff, 0x9d, 0x97, 0xd0, 0x75, 0xbc, 0x69, 0xec, 0x90, 0xb3, 0xf9, 0x4a, 0x94, 0xf0, 0xd6,
+ /*3190:*/ 0xd0, 0xd5, 0xd2, 0xb3, 0xd9, 0x58, 0x02, 0x75, 0x60, 0xf0, 0x49, 0x45, 0xe5, 0xa8, 0x41, 0x77,
+ /*31a0:*/ 0xb7, 0xd4, 0x8d, 0x93, 0x05, 0xb8, 0x56, 0xb9, 0xe8, 0x79, 0x9e, 0x83, 0xc4, 0x45, 0xe5, 0x20,
+ /*31b0:*/ 0xa9, 0x7d, 0x7a, 0xf7, 0x20, 0x23, 0x6c, 0xf4, 0x57, 0xc2, 0xba, 0x79, 0xa8, 0x8c, 0x01, 0x9e,
+ /*31c0:*/ 0x66, 0x6a, 0xae, 0x76, 0x49, 0x27, 0x74, 0xe7, 0x17, 0x84, 0xaa, 0x49, 0xb5, 0x16, 0x37, 0xea,
+ /*31d0:*/ 0x6c, 0x01, 0x90, 0x79, 0x21, 0xe2, 0x0d, 0x77, 0xca, 0x7a, 0xf8, 0xff, 0x41, 0x21, 0xf5, 0x1c,
+ /*31e0:*/ 0xf7, 0x9f, 0x8b, 0xa3, 0x5c, 0xc1, 0x5b, 0xce, 0xbb, 0x12, 0x22, 0xf8, 0xd0, 0x36, 0x67, 0x23,
+ /*31f0:*/ 0xa1, 0x1d, 0xf7, 0x60, 0x33, 0xa3, 0x85, 0xcd, 0x0f, 0xeb, 0x39, 0xa7, 0xda, 0xd5, 0xcd, 0x8c,
+ /*3200:*/ 0xaf, 0x12, 0x06, 0xe8, 0x4c, 0x44, 0x1d, 0x93, 0xfc, 0x89, 0x93, 0x00, 0x64, 0xa3, 0xcc, 0x00,
+ /*3210:*/ 0x00, 0x09, 0x9a, 0x19, 0x9e, 0xbc, 0x82, 0x1c, 0x22, 0x1a, 0x65, 0x08, 0x99, 0xe8, 0x42, 0x68,
+ /*3220:*/ 0x98, 0x1d, 0x63, 0x25, 0x00, 0xda, 0xa5, 0xce, 0xf2, 0x6b, 0x6c, 0x12, 0x3b, 0xda, 0xde, 0xa2,
+ /*3230:*/ 0xaa, 0xd3, 0x5e, 0x3d, 0x32, 0x84, 0x53, 0x53, 0x7f, 0x44, 0x68, 0xbd, 0x1e, 0xea, 0xd6, 0x38,
+ /*3240:*/ 0xba, 0x80, 0xf5, 0x2d, 0x29, 0x10, 0x53, 0x4f, 0xc7, 0x72, 0xc6, 0xab, 0xfd, 0xe5, 0x6b, 0x74,
+ /*3250:*/ 0x30, 0xe7, 0x86, 0x5c, 0x39, 0x6e, 0x9d, 0xf2, 0x06, 0xa6, 0xc1, 0x2d, 0x62, 0x5e, 0x6b, 0x08,
+ /*3260:*/ 0xf8, 0x05, 0xb8, 0xa0, 0xc3, 0x36, 0x92, 0x13, 0xcd, 0x55, 0x51, 0xca, 0x1c, 0xcf, 0xb4, 0x70,
+ /*3270:*/ 0x6d, 0xa4, 0x5d, 0x8c, 0xa4, 0x56, 0xe9, 0xd2, 0x79, 0xe1, 0xe4, 0xfa, 0x68, 0x91, 0xb9, 0x45,
+ /*3280:*/ 0x28, 0x3c, 0xf2, 0x2e, 0x40, 0xda, 0x1b, 0xc4, 0x0e, 0x22, 0x17, 0x7c, 0xd4, 0xc6, 0x74, 0xc9,
+ /*3290:*/ 0x13, 0x9c, 0xa5, 0x12, 0xa8, 0x7d, 0xa4, 0x68, 0xff, 0x17, 0xb0, 0xdd, 0xae, 0xcb, 0xb3, 0x95,
+ /*32a0:*/ 0x15, 0xec, 0x61, 0x2a, 0x40, 0x92, 0x0f, 0x44, 0xfb, 0x62, 0xd5, 0xf7, 0x75, 0x69, 0x0d, 0xa8,
+ /*32b0:*/ 0xb6, 0x99, 0x85, 0xac, 0x63, 0x9d, 0x7c, 0x50, 0xa5, 0xed, 0x27, 0x3d, 0xd8, 0x6e, 0x54, 0xb5,
+ /*32c0:*/ 0x43, 0x27, 0xab, 0x2d, 0x29, 0x4d, 0x2e, 0x10, 0xc9, 0xa4, 0x25, 0xa4, 0x5b, 0x43, 0xb0, 0x1a,
+ /*32d0:*/ 0x5c, 0xfd, 0x36, 0xc9, 0xfb, 0x04, 0x02, 0x9e, 0x13, 0x2b, 0xc8, 0xfa, 0xfa, 0x4d, 0x06, 0x1d,
+ /*32e0:*/ 0xdd, 0xb4, 0x02, 0x35, 0xac, 0x92, 0xb3, 0x9d, 0xd4, 0xb0, 0xea, 0xeb, 0x0b, 0xce, 0xbe, 0x02,
+ /*32f0:*/ 0xc1, 0x58, 0xc9, 0x3c, 0x04, 0x67, 0x48, 0x60, 0x5c, 0xe3, 0x0d, 0x86, 0xfc, 0x94, 0x1f, 0x87,
+ /*3300:*/ 0x20, 0xff, 0x0c, 0x15, 0x4f, 0x26, 0xc7, 0x71, 0xfd, 0x97, 0xff, 0xe9, 0xce, 0x84, 0x20, 0xcb,
+ /*3310:*/ 0xcf, 0x8f, 0x03, 0x17, 0x34, 0x50, 0xe5, 0xca, 0x30, 0xd2, 0x0c, 0x05, 0x2b, 0x61, 0x80, 0x9a,
+ /*3320:*/ 0x85, 0xa2, 0x3a, 0xa9, 0xfe, 0xf0, 0xda, 0xc4, 0xeb, 0xc7, 0x77, 0xc0, 0x03, 0x48, 0xaf, 0x40,
+ /*3330:*/ 0xab, 0xc0, 0xf6, 0xc6, 0xb7, 0x49, 0x02, 0x39, 0x6a, 0xfb, 0x17, 0x5e, 0x06, 0x3a, 0xad, 0x30,
+ /*3340:*/ 0x25, 0x7d, 0xbf, 0x48, 0xa9, 0x79, 0x0e, 0x7e, 0x2d, 0x2e, 0xa2, 0xa9, 0x66, 0xda, 0x55, 0x37,
+ /*3350:*/ 0x0e, 0x04, 0x76, 0x06, 0x84, 0x40, 0x10, 0x22, 0x23, 0xbf, 0xe7, 0xef, 0xd4, 0xc8, 0x95, 0x30,
+ /*3360:*/ 0x88, 0x4a, 0xbf, 0x09, 0x69, 0x9a, 0x05, 0xe6, 0xd1, 0x48, 0xea, 0x7b, 0x31, 0x4e, 0x47, 0x73,
+ /*3370:*/ 0x8d, 0xe4, 0x0a, 0x12, 0x7b, 0xb8, 0xfb, 0x48, 0x80, 0x5c, 0x1c, 0x35, 0xcc, 0x68, 0x93, 0x65,
+ /*3380:*/ 0x60, 0x3b, 0x3a, 0x6e, 0x3c, 0x99, 0x51, 0xbf, 0x27, 0x1f, 0x24, 0x5e, 0x40, 0xc2, 0xf0, 0x48,
+ /*3390:*/ 0x60, 0x3d, 0x5c, 0xc3, 0x4d, 0xb7, 0xdf, 0x10, 0x54, 0x62, 0x5e, 0x6e, 0xb9, 0xd2, 0x5a, 0x95,
+ /*33a0:*/ 0xfc, 0x10, 0xa8, 0xc2, 0xfc, 0x77, 0x3a, 0xea, 0x99, 0x12, 0x7c, 0xa6, 0xd7, 0x2b, 0xba, 0xd0,
+ /*33b0:*/ 0xa1, 0x31, 0x6d, 0xc2, 0x26, 0x7c, 0xc4, 0x03, 0x32, 0x27, 0x48, 0x6a, 0x80, 0x02, 0xa8, 0x58,
+ /*33c0:*/ 0x23, 0xba, 0xb1, 0x8c, 0x8e, 0x66, 0x83, 0x54, 0x6c, 0x96, 0xad, 0xfa, 0xe6, 0xaa, 0x98, 0x6a,
+ /*33d0:*/ 0xd9, 0x7e, 0x03, 0xf9, 0xe2, 0x54, 0xf1, 0x0a, 0x41, 0x19, 0x33, 0x7a, 0x13, 0x85, 0xfa, 0xd8,
+ /*33e0:*/ 0xa5, 0xbc, 0x55, 0x2e, 0xc2, 0x39, 0x7d, 0xbf, 0x82, 0xd4, 0x3d, 0x43, 0x6f, 0xf0, 0xc0, 0x8c,
+ /*33f0:*/ 0x30, 0xdc, 0x25, 0x0b, 0x20, 0x09, 0x13, 0x0e, 0x64, 0x62, 0x7e, 0xd5, 0xdd, 0xc3, 0x87, 0x95,
+ /*3400:*/ 0xe0, 0xae, 0x49, 0xf1, 0x8a, 0xb1, 0x89, 0x76, 0x94, 0x0e, 0xd3, 0x14, 0x8d, 0xfa, 0xb3, 0xf1,
+ /*3410:*/ 0x3f, 0x3a, 0xa9, 0x07, 0xf8, 0x6a, 0x81, 0x60, 0x73, 0x3b, 0x81, 0xd8, 0xbc, 0xf2, 0xf1, 0x62,
+ /*3420:*/ 0xcb, 0xa3, 0x60, 0xb5, 0x27, 0x06, 0x57, 0x91, 0x5b, 0xd3, 0xab, 0x95, 0xe9, 0x42, 0xce, 0x1a,
+ /*3430:*/ 0x80, 0xd8, 0x54, 0x8b, 0x12, 0x5e, 0x75, 0x31, 0xc6, 0x74, 0xe7, 0xfb, 0xe7, 0xa4, 0xf8, 0xbc,
+ /*3440:*/ 0xff, 0x8d, 0x3c, 0x9b, 0xcf, 0x3e, 0xc7, 0x3a, 0xd9, 0x8f, 0x85, 0xc9, 0x17, 0xe6, 0x43, 0x04,
+ /*3450:*/ 0xa2, 0xa6, 0xba, 0x06, 0x6f, 0xa1, 0x0a, 0x1a, 0x61, 0xc3, 0x4c, 0x2c, 0x9d, 0x0f, 0xcc, 0xf6,
+ /*3460:*/ 0x74, 0x2e, 0x12, 0xc7, 0xa4, 0x79, 0x27, 0xd8, 0x75, 0x92, 0xab, 0x1e, 0x18, 0xd5, 0xb5, 0xc8,
+ /*3470:*/ 0xa7, 0x57, 0x58, 0x40, 0xcd, 0x3e, 0xb4, 0x1e, 0x99, 0xde, 0x5f, 0x97, 0x76, 0x83, 0xac, 0x61,
+ /*3480:*/ 0x41, 0xbd, 0xb6, 0x05, 0xf7, 0xec, 0x2a, 0x50, 0xb3, 0x03, 0xca, 0x2d, 0x0f, 0xf1, 0x2a, 0xc7,
+ /*3490:*/ 0x87, 0x41, 0xcd, 0xfc, 0x19, 0x0a, 0x7e, 0xf6, 0x14, 0x06, 0xfd, 0x03, 0x6e, 0xdf, 0xcf, 0x12,
+ /*34a0:*/ 0x9a, 0xa9, 0xe6, 0xe7, 0xb8, 0x30, 0x5a, 0xfb, 0xe7, 0xe4, 0xe0, 0x66, 0x26, 0x8a, 0x32, 0x68,
+ /*34b0:*/ 0x59, 0x2b, 0xca, 0x10, 0x59, 0x71, 0x23, 0x07, 0xb6, 0xb6, 0xc4, 0x55, 0xdb, 0xd7, 0xe9, 0xc1,
+ /*34c0:*/ 0x6d, 0x21, 0xf3, 0x12, 0x68, 0x7d, 0x4d, 0x58, 0x15, 0xd4, 0xc0, 0x03, 0x89, 0x62, 0x33, 0x4a,
+ /*34d0:*/ 0x34, 0x9e, 0xc3, 0x93, 0xda, 0xd8, 0xe8, 0x42, 0x4e, 0x8a, 0x2a, 0xc3, 0x4c, 0x5e, 0xd1, 0x84,
+ /*34e0:*/ 0x7e, 0xfb, 0x57, 0x11, 0x8a, 0xda, 0xdf, 0x37, 0x67, 0xdd, 0xbc, 0x67, 0x67, 0x23, 0xaf, 0xe6,
+ /*34f0:*/ 0x1c, 0xaf, 0x65, 0xf6, 0x9f, 0x93, 0x64, 0x5c, 0x97, 0xe2, 0x23, 0xbb, 0xcf, 0xb7, 0x37, 0x6c,
+ /*3500:*/ 0xfa, 0xc6, 0x26, 0xb6, 0x00, 0xc0, 0xf1, 0x3a, 0x99, 0x2a, 0x2b, 0x75, 0xb9, 0x59, 0xf8, 0xaa,
+ /*3510:*/ 0x9a, 0x93, 0x1a, 0x91, 0x49, 0x58, 0x1f, 0x4a, 0xf2, 0xe2, 0x17, 0x6d, 0xd7, 0x8a, 0xba, 0xa8,
+ /*3520:*/ 0x74, 0xe5, 0xa9, 0x95, 0xb8, 0xc9, 0x5e, 0x04, 0x2c, 0x23, 0x04, 0xa2, 0x43, 0x1b, 0x78, 0x8f,
+ /*3530:*/ 0x8d, 0x82, 0xd7, 0x3f, 0x5a, 0x2b, 0x8c, 0x8e, 0xd9, 0x59, 0x54, 0xf1, 0x02, 0x6d, 0x5e, 0x74,
+ /*3540:*/ 0xf7, 0xf5, 0xb2, 0x08, 0xce, 0x35, 0x71, 0x96, 0x83, 0xc9, 0x1f, 0xb3, 0x47, 0xdf, 0x5a, 0x10,
+ /*3550:*/ 0x95, 0x2b, 0x1f, 0xf4, 0x6b, 0x96, 0xc0, 0x72, 0x16, 0x8a, 0x98, 0xf1, 0x4a, 0x75, 0x6c, 0x7e,
+ /*3560:*/ 0xff, 0x07, 0xe3, 0x60, 0xa1, 0xcc, 0xe2, 0xd0, 0xbc, 0xe2, 0x61, 0xa9, 0x14, 0x9c, 0xea, 0xa9,
+ /*3570:*/ 0x8d, 0x0f, 0xe4, 0x3e, 0x2d, 0xee, 0x77, 0x13, 0x89, 0xa7, 0x5f, 0x6c, 0x3b, 0x2b, 0xc3, 0xeb,
+ /*3580:*/ 0x6c, 0x89, 0xd9, 0x55, 0xbc, 0xe8, 0xe6, 0x1a, 0xf9, 0xcf, 0xa8, 0x7a, 0x59, 0xd4, 0x5c, 0x3b,
+ /*3590:*/ 0x03, 0x34, 0x17, 0xe3, 0xaf, 0x69, 0x16, 0x75, 0xb1, 0x03, 0x6f, 0x40, 0xb2, 0xf5, 0x88, 0x36,
+ /*35a0:*/ 0x3e, 0x1e, 0x0e, 0x75, 0xfd, 0x8c, 0x40, 0x5d, 0x07, 0x7f, 0xc0, 0x63, 0x45, 0xa2, 0x86, 0x52,
+ /*35b0:*/ 0xbb, 0x20, 0xab, 0x78, 0xb2, 0x73, 0x44, 0xfd, 0xac, 0xca, 0xa7, 0x93, 0x46, 0x44, 0xc0, 0x20,
+ /*35c0:*/ 0x44, 0x8c, 0xc4, 0xb5, 0x15, 0xed, 0x52, 0xf1, 0x67, 0x35, 0x35, 0xb0, 0x4d, 0xd5, 0x4c, 0xb0,
+ /*35d0:*/ 0x31, 0x6f, 0xfe, 0x67, 0x38, 0x17, 0x97, 0xab, 0xce, 0x8f, 0xb0, 0xc1, 0x9d, 0x84, 0x1d, 0xef,
+ /*35e0:*/ 0x19, 0x4b, 0x4f, 0x09, 0xf9, 0x5d, 0xea, 0x98, 0xf6, 0xcf, 0xf3, 0x76, 0x41, 0x94, 0x32, 0xa6,
+ /*35f0:*/ 0x9f, 0xb4, 0x20, 0xed, 0xda, 0xdb, 0x9e, 0x89, 0xa3, 0xaf, 0x62, 0x0a, 0x76, 0xae, 0x78, 0x84,
+ /*3600:*/ 0xa3, 0xda, 0x48, 0xaa, 0x16, 0xd5, 0x50, 0x27, 0xcb, 0x8d, 0xd0, 0x7e, 0x3b, 0x4e, 0x7f, 0x92,
+ /*3610:*/ 0x68, 0x58, 0xc0, 0xec, 0x95, 0xc0, 0x37, 0x17, 0x38, 0x09, 0xfa, 0xd8, 0x87, 0xf0, 0xd7, 0xe9,
+ /*3620:*/ 0xcf, 0x2d, 0x74, 0x29, 0xb8, 0x07, 0x8b, 0xb5, 0x09, 0xc6, 0x4f, 0xe7, 0x65, 0xe9, 0xc5, 0x8a,
+ /*3630:*/ 0xc1, 0xee, 0xa8, 0xbf, 0xa4, 0x3f, 0x25, 0x47, 0xee, 0x18, 0xca, 0x7d, 0x8f, 0xc8, 0xfa, 0xf9,
+ /*3640:*/ 0xb8, 0xab, 0x00, 0xa1, 0x72, 0xc3, 0x16, 0x35, 0x50, 0x2c, 0x8f, 0x1a, 0x63, 0xc6, 0x7f, 0x20,
+ /*3650:*/ 0x9b, 0x1a, 0xc1, 0xb5, 0xbd, 0xfb, 0xb5, 0x42, 0x95, 0xdf, 0x1c, 0xa5, 0x62, 0x89, 0x78, 0x2f,
+ /*3660:*/ 0xb3, 0xa6, 0x57, 0x0a, 0x1a, 0x67, 0xf9, 0xdc, 0x21, 0x27, 0xee, 0xe2, 0x7b, 0x00, 0xd6, 0x26,
+ /*3670:*/ 0x2b, 0x12, 0xce, 0x69, 0x8d, 0x57, 0x26, 0x14, 0x21, 0x24, 0x71, 0x1a, 0x67, 0x3e, 0x8a, 0xa1,
+ /*3680:*/ 0xa2, 0xb1, 0x3a, 0x08, 0xaa, 0xcf, 0x32, 0xfc, 0xc7, 0x95, 0x42, 0xdb, 0x72, 0x26, 0x34, 0xe2,
+ /*3690:*/ 0x8d, 0x44, 0x5e, 0x02, 0xd3, 0x89, 0x08, 0x9c, 0x61, 0x54, 0xeb, 0x2b, 0x4e, 0xa6, 0x5d, 0x3e,
+ /*36a0:*/ 0x69, 0x0b, 0xd2, 0xfb, 0x00, 0xdd, 0xa7, 0x24, 0x44, 0x89, 0x68, 0x14, 0xcb, 0x2c, 0xbb, 0xf7,
+ /*36b0:*/ 0x8b, 0xef, 0xe9, 0x24, 0xb6, 0x60, 0x3b, 0x9d, 0xdf, 0xfb, 0x0c, 0x6f, 0xb1, 0xf1, 0x09, 0x7c,
+ /*36c0:*/ 0xa2, 0x53, 0xfc, 0x44, 0x89, 0x43, 0x93, 0x0f, 0xe3, 0x34, 0x39, 0xaa, 0x70, 0x6f, 0x28, 0x5a,
+ /*36d0:*/ 0x1c, 0x58, 0x68, 0xb3, 0xe2, 0xee, 0xf6, 0xb8, 0x43, 0x54, 0xb8, 0xdf, 0x9a, 0xed, 0x38, 0xf0,
+ /*36e0:*/ 0xd5, 0xfe, 0x11, 0xc5, 0x46, 0x98, 0x99, 0x25, 0x29, 0xa6, 0xbb, 0x03, 0x5e, 0x5f, 0x7b, 0xfe,
+ /*36f0:*/ 0xce, 0x22, 0x24, 0xb3, 0x6f, 0x77, 0xab, 0x90, 0x02, 0xe4, 0x0c, 0x5c, 0x6e, 0x6e, 0x86, 0x3a,
+ /*3700:*/ 0x0e, 0xbf, 0x93, 0x9a, 0x78, 0xba, 0xa3, 0x55, 0xfd, 0xbc, 0x0e, 0xde, 0x99, 0xc3, 0x6b, 0x6d,
+ /*3710:*/ 0x87, 0x90, 0x93, 0x10, 0xb4, 0x7e, 0xce, 0x84, 0x98, 0xed, 0x01, 0x7e, 0x8d, 0x8c, 0x48, 0x06,
+ /*3720:*/ 0xbb, 0x58, 0xce, 0xd3, 0x6d, 0x41, 0x3b, 0x41, 0x13, 0x84, 0x68, 0x33, 0xf2, 0xb3, 0xba, 0x05,
+ /*3730:*/ 0x41, 0x55, 0xdf, 0x13, 0x1a, 0xb8, 0x86, 0x20, 0x5a, 0xbb, 0x7a, 0x36, 0x3b, 0x77, 0x1a, 0xe8,
+ /*3740:*/ 0x46, 0x31, 0x27, 0x0d, 0xb8, 0x7a, 0x19, 0x2c, 0x4d, 0xd1, 0xfb, 0xc3, 0xda, 0x2b, 0x0d, 0x97,
+ /*3750:*/ 0x04, 0xef, 0xf7, 0x54, 0xf3, 0xc4, 0xa6, 0x32, 0xb9, 0xce, 0xca, 0xd8, 0x88, 0x63, 0x0c, 0x5c,
+ /*3760:*/ 0xa7, 0xe6, 0xe1, 0xa7, 0xc4, 0xdc, 0xb1, 0x6e, 0xb7, 0xd3, 0x82, 0x69, 0xca, 0xa0, 0x57, 0x5d,
+ /*3770:*/ 0xfd, 0x41, 0x58, 0x8d, 0xe0, 0x8c, 0x51, 0x81, 0xc4, 0xa1, 0x52, 0xa9, 0x6d, 0x86, 0x06, 0x43,
+ /*3780:*/ 0x07, 0x07, 0xcb, 0xb8, 0xd7, 0xdb, 0x65, 0xb3, 0xc9, 0xe8, 0x43, 0x0f, 0xe2, 0x3d, 0xde, 0x30,
+ /*3790:*/ 0x66, 0xca, 0x30, 0x25, 0xba, 0x71, 0x9e, 0x12, 0x73, 0x40, 0xf2, 0xd6, 0xff, 0xa7, 0x51, 0x72,
+ /*37a0:*/ 0x44, 0x7e, 0xd5, 0xba, 0xa8, 0x89, 0x4a, 0xf8, 0x30, 0x1e, 0xe9, 0x3c, 0xab, 0x16, 0xc9, 0x51,
+ /*37b0:*/ 0x3c, 0xef, 0xfe, 0x6f, 0x8f, 0x04, 0x47, 0xbc, 0xce, 0x7d, 0x27, 0x61, 0x28, 0xd8, 0x47, 0x9f,
+ /*37c0:*/ 0x1c, 0x89, 0x6c, 0x25, 0xc9, 0x61, 0x8d, 0x47, 0x63, 0xb3, 0x6f, 0xbc, 0xb9, 0x44, 0x8e, 0x50,
+ /*37d0:*/ 0x60, 0x5a, 0xa3, 0x26, 0x5d, 0xb8, 0x3c, 0xf9, 0xef, 0x8f, 0xfc, 0xdb, 0xd6, 0x62, 0x87, 0xd2,
+ /*37e0:*/ 0xfd, 0x95, 0xbd, 0x61, 0x2b, 0xcc, 0xef, 0xf7, 0x74, 0x96, 0x30, 0x10, 0x48, 0x0f, 0x84, 0xaf,
+ /*37f0:*/ 0x0c, 0x5d, 0x8f, 0xb8, 0x4e, 0x08, 0x60, 0xf5, 0x84, 0x1b, 0xa7, 0x02, 0x58, 0xc4, 0x1c, 0x6e,
+ /*3800:*/ 0xd2, 0x6d, 0xe1, 0x70, 0x4f, 0x57, 0x67, 0xfe, 0xbb, 0x59, 0x03, 0xac, 0x98, 0xa6, 0x88, 0xc4,
+ /*3810:*/ 0x93, 0x4c, 0x53, 0x55, 0xbe, 0xc0, 0x97, 0x09, 0x61, 0x05, 0x11, 0x9e, 0x43, 0x9b, 0x03, 0x56,
+ /*3820:*/ 0x77, 0x89, 0xcb, 0x32, 0x15, 0xe9, 0x0b, 0xa8, 0xe7, 0x00, 0x66, 0xbf, 0xf9, 0xbf, 0x9f, 0x77,
+ /*3830:*/ 0xde, 0xf2, 0x50, 0x0d, 0x88, 0xb8, 0x4d, 0x16, 0x42, 0x0b, 0xaf, 0xda, 0xe2, 0x9c, 0x29, 0xf8,
+ /*3840:*/ 0xc5, 0x2b, 0xf6, 0xfc, 0x89, 0xf0, 0x0c, 0x2e, 0xf7, 0xb8, 0xb9, 0x60, 0x31, 0x5d, 0x7a, 0x8a,
+ /*3850:*/ 0x7f, 0xdf, 0xf2, 0xa6, 0xd6, 0x39, 0x4f, 0x20, 0xaf, 0x07, 0xc9, 0x9c, 0xd0, 0x8f, 0x21, 0x2c,
+ /*3860:*/ 0xae, 0x78, 0x1a, 0x00, 0xad, 0x52, 0x07, 0x2c, 0xbd, 0x99, 0x8e, 0x43, 0x68, 0xa0, 0x47, 0xf6,
+ /*3870:*/ 0xf9, 0xb7, 0xe1, 0x42, 0x53, 0x37, 0x8c, 0x5d, 0xcc, 0x5e, 0x7c, 0x70, 0x89, 0x0c, 0xeb, 0x66,
+ /*3880:*/ 0x5c, 0x5f, 0x96, 0xf1, 0x29, 0xa9, 0x49, 0x68, 0xb2, 0x9f, 0x5c, 0x49, 0x85, 0xb9, 0x47, 0x4c,
+ /*3890:*/ 0xb9, 0x40, 0x42, 0x29, 0x98, 0x2e, 0xbc, 0xd1, 0xde, 0xd1, 0xe4, 0x67, 0x66, 0x98, 0x7c, 0x6a,
+ /*38a0:*/ 0x60, 0x00, 0xd2, 0xd0, 0x3f, 0xcb, 0xc0, 0xde, 0x18, 0x95, 0xb9, 0xd7, 0xbc, 0x2c, 0x39, 0xc7,
+ /*38b0:*/ 0x90, 0x59, 0x88, 0xa9, 0x17, 0xcd, 0x81, 0x28, 0x09, 0x97, 0xe0, 0x34, 0x7a, 0x6a, 0xcb, 0x0c,
+ /*38c0:*/ 0x8a, 0x9c, 0xf2, 0x9d, 0xa6, 0xce, 0xdd, 0x09, 0x13, 0x4e, 0x0f, 0x51, 0xfc, 0xa0, 0x11, 0xf5,
+ /*38d0:*/ 0x74, 0xd2, 0x3e, 0xcb, 0x93, 0xca, 0x60, 0x48, 0x00, 0xb6, 0xd9, 0xa6, 0x7b, 0x14, 0x26, 0x8f,
+ /*38e0:*/ 0x75, 0x77, 0x74, 0x55, 0xd6, 0x29, 0x6f, 0x6f, 0x4d, 0xac, 0x4c, 0x7b, 0xba, 0x9c, 0xb5, 0x88,
+ /*38f0:*/ 0x0f, 0x7c, 0x45, 0x74, 0x26, 0xe2, 0x2e, 0xd4, 0x45, 0x79, 0x29, 0x07, 0xd6, 0x58, 0x7d, 0x8c,
+ /*3900:*/ 0x93, 0x61, 0x8d, 0x96, 0xef, 0xc2, 0xc5, 0xa5, 0xf6, 0xab, 0xa1, 0x20, 0x44, 0x61, 0xd7, 0x60,
+ /*3910:*/ 0x62, 0x79, 0xa7, 0x7a, 0xeb, 0x8f, 0xd9, 0x96, 0xce, 0xf9, 0xb1, 0xb0, 0xe7, 0xfe, 0xe0, 0x69,
+ /*3920:*/ 0x2b, 0xbd, 0xfd, 0xb2, 0x25, 0x6b, 0x8b, 0x11, 0x8b, 0x59, 0x92, 0xfa, 0xcd, 0x6c, 0xd0, 0x90,
+ /*3930:*/ 0xb4, 0xde, 0x70, 0x32, 0xa9, 0x4d, 0x08, 0x92, 0x47, 0x0c, 0x7a, 0xb6, 0x00, 0xe2, 0x1c, 0x71,
+ /*3940:*/ 0xa0, 0x39, 0x1c, 0xcb, 0x96, 0xc2, 0xda, 0x70, 0x50, 0x29, 0x35, 0x3e, 0x28, 0xf6, 0x86, 0xbb,
+ /*3950:*/ 0xb2, 0x8a, 0xba, 0x93, 0xf9, 0x42, 0xf4, 0xc9, 0xa8, 0x54, 0x03, 0xd3, 0xb4, 0xc4, 0x40, 0xbf,
+ /*3960:*/ 0x72, 0x1f, 0x86, 0xfe, 0x32, 0xc3, 0x44, 0x80, 0x9c, 0x77, 0x7b, 0x30, 0xb2, 0xeb, 0x44, 0x2c,
+ /*3970:*/ 0xee, 0x15, 0x00, 0x16, 0x1b, 0x57, 0xfe, 0x22, 0x9f, 0x4a, 0x7e, 0x40, 0xe8, 0xd3, 0xb1, 0x12,
+ /*3980:*/ 0xe2, 0x78, 0x36, 0x94, 0x61, 0x9e, 0x46, 0x37, 0x5b, 0x17, 0x0a, 0x58, 0xd5, 0x40, 0x25, 0x52,
+ /*3990:*/ 0x08, 0xc6, 0x42, 0x50, 0xb7, 0x4d, 0x76, 0xe4, 0x05, 0xb7, 0x3f, 0x83, 0x0b, 0xab, 0x32, 0x1a,
+ /*39a0:*/ 0x66, 0xcc, 0x14, 0xc5, 0x98, 0xb6, 0x37, 0x7d, 0x44, 0xbd, 0xb0, 0x38, 0x29, 0x17, 0xe0, 0xa7,
+ /*39b0:*/ 0x27, 0x2f, 0x66, 0x88, 0x8a, 0x45, 0x53, 0xda, 0x57, 0x9d, 0xcc, 0xca, 0x25, 0x83, 0xe8, 0x18,
+ /*39c0:*/ 0x6e, 0x8a, 0x22, 0x0a, 0x35, 0x49, 0x78, 0x85, 0x05, 0xe1, 0xec, 0x02, 0x62, 0x3e, 0xad, 0x6b,
+ /*39d0:*/ 0x71, 0x95, 0xf7, 0xd7, 0x29, 0xea, 0x21, 0xc4, 0x63, 0x5f, 0x68, 0x9f, 0x10, 0x9d, 0x31, 0x39,
+ /*39e0:*/ 0x92, 0xc9, 0x79, 0x66, 0x9b, 0xb4, 0xe0, 0x53, 0xb4, 0x2b, 0xd8, 0xe8, 0xea, 0x4f, 0x47, 0x88,
+ /*39f0:*/ 0xaa, 0xb1, 0x7f, 0x5d, 0xd0, 0x16, 0x80, 0xa9, 0x24, 0xd5, 0x51, 0x68, 0x58, 0xff, 0x5b, 0x35,
+ /*3a00:*/ 0x11, 0x32, 0x0d, 0x3d, 0xb9, 0xa5, 0x3b, 0xb8, 0x5c, 0x19, 0xc1, 0xe7, 0x04, 0xcb, 0x7c, 0xc2,
+ /*3a10:*/ 0x01, 0x87, 0xea, 0xf3, 0x5a, 0x55, 0xb9, 0x31, 0x27, 0x95, 0xae, 0x6e, 0x68, 0x1a, 0x64, 0xda,
+ /*3a20:*/ 0x78, 0x65, 0x56, 0x67, 0x61, 0x03, 0xb9, 0xfb, 0x99, 0x0c, 0xa9, 0xa6, 0x72, 0x88, 0x89, 0x3f,
+ /*3a30:*/ 0xd1, 0x3e, 0xe3, 0xb1, 0x93, 0x09, 0xce, 0x0e, 0x0b, 0x7c, 0x08, 0xa5, 0x82, 0x4e, 0x2a, 0x52,
+ /*3a40:*/ 0x99, 0x0d, 0xee, 0x35, 0x28, 0xff, 0xe2, 0x17, 0x65, 0xfb, 0xb4, 0x59, 0x05, 0x86, 0xf2, 0x0a,
+ /*3a50:*/ 0xff, 0xb4, 0x4c, 0xe0, 0x0e, 0x9b, 0xd6, 0x86, 0xb3, 0xb3, 0x6f, 0x22, 0x35, 0x0c, 0x77, 0x3a,
+ /*3a60:*/ 0xd5, 0x42, 0x5b, 0x1a, 0xc6, 0x45, 0xb4, 0x16, 0x4e, 0x7b, 0x22, 0xbb, 0xb3, 0xe2, 0x18, 0x8f,
+ /*3a70:*/ 0xf0, 0x13, 0xc4, 0xaf, 0x03, 0x7f, 0xbe, 0x0f, 0x43, 0x5f, 0x83, 0xd3, 0x57, 0xbf, 0xc0, 0x6b,
+ /*3a80:*/ 0xb3, 0xea, 0x7f, 0x39, 0xa1, 0xf6, 0xb2, 0x67, 0xeb, 0xa0, 0x6a, 0x1f, 0xc8, 0x0b, 0x33, 0x06,
+ /*3a90:*/ 0x5b, 0x69, 0x67, 0x82, 0x39, 0x27, 0x38, 0xa5, 0x14, 0xa2, 0x68, 0xbc, 0xe8, 0x52, 0xf7, 0xcb,
+ /*3aa0:*/ 0x4c, 0xfd, 0xa3, 0x9a, 0x23, 0x9c, 0xa1, 0xd7, 0x3e, 0x1d, 0x3b, 0x6b, 0x6e, 0x1e, 0xbc, 0x8b,
+ /*3ab0:*/ 0xff, 0xc1, 0xa5, 0x3e, 0xa9, 0x5b, 0x7f, 0x86, 0xa6, 0x95, 0xf0, 0xcc, 0x3b, 0xeb, 0x76, 0x77,
+ /*3ac0:*/ 0x51, 0x51, 0x3e, 0xe6, 0x97, 0x38, 0x1e, 0xd1, 0x34, 0x20, 0xb2, 0xeb, 0x8a, 0x35, 0xc1, 0x5f,
+ /*3ad0:*/ 0x5e, 0xd9, 0x97, 0xab, 0x30, 0x95, 0xae, 0x5e, 0xb0, 0x62, 0xa3, 0x4c, 0x12, 0xf6, 0x0c, 0xd7,
+ /*3ae0:*/ 0x16, 0x92, 0x97, 0x27, 0xcb, 0xe7, 0x1e, 0xf1, 0x87, 0xc4, 0xd1, 0x09, 0xb9, 0xe6, 0xff, 0xb6,
+ /*3af0:*/ 0xab, 0xc7, 0x9c, 0x42, 0x55, 0xab, 0x1f, 0x6a, 0x85, 0x80, 0x6f, 0xc4, 0x3c, 0x16, 0x9b, 0x89,
+ /*3b00:*/ 0x9c, 0x42, 0xed, 0xd9, 0x97, 0xdc, 0x4f, 0xe2, 0x69, 0xdd, 0xab, 0xe7, 0x2c, 0x9a, 0xda, 0x91,
+ /*3b10:*/ 0x7c, 0x71, 0x63, 0x41, 0x48, 0xc0, 0x6f, 0x24, 0xd6, 0xaf, 0x6b, 0x30, 0xce, 0xc0, 0x86, 0xff,
+ /*3b20:*/ 0xa9, 0x26, 0x91, 0xd7, 0x42, 0xa0, 0x00, 0x4e, 0x39, 0xb0, 0x6c, 0xfc, 0xad, 0xd4, 0x22, 0xd0,
+ /*3b30:*/ 0x6d, 0xb6, 0xf1, 0xeb, 0xbd, 0x28, 0x72, 0x87, 0x15, 0xb5, 0x17, 0x76, 0x0a, 0x31, 0xc2, 0x2b,
+ /*3b40:*/ 0xc0, 0x5f, 0x4a, 0x52, 0xa0, 0xed, 0x9e, 0xe0, 0x7d, 0x7e, 0x6e, 0x0c, 0x12, 0x03, 0x27, 0x58,
+ /*3b50:*/ 0x28, 0x68, 0xb0, 0x6e, 0x19, 0xfb, 0xec, 0x50, 0x0e, 0xc8, 0xf9, 0x0b, 0xfb, 0xfd, 0xf4, 0x17,
+ /*3b60:*/ 0x79, 0xec, 0xaf, 0x1b, 0x79, 0x15, 0x23, 0x9a, 0x06, 0xcd, 0x60, 0xbc, 0x95, 0x5d, 0x8a, 0x76,
+ /*3b70:*/ 0x49, 0x3e, 0xa9, 0xd3, 0xcb, 0xed, 0x2f, 0x5f, 0xe0, 0xa7, 0xb8, 0xc7, 0x01, 0x60, 0x78, 0x0d,
+ /*3b80:*/ 0x33, 0x8b, 0xda, 0xb8, 0x04, 0x15, 0x00, 0x6a, 0xe6, 0x4e, 0x43, 0xb6, 0xd2, 0x0d, 0x81, 0x60,
+ /*3b90:*/ 0x74, 0x6c, 0x09, 0xdb, 0x05, 0xc3, 0xb4, 0xc3, 0x8f, 0xae, 0x23, 0xeb, 0xe0, 0x32, 0x73, 0x24,
+ /*3ba0:*/ 0xa9, 0xfa, 0xee, 0xc0, 0xfe, 0x44, 0x14, 0x41, 0xce, 0xe9, 0x31, 0x8a, 0x24, 0x8d, 0xd3, 0xa9,
+ /*3bb0:*/ 0x49, 0x0c, 0xe0, 0x6b, 0xb6, 0xd5, 0xf8, 0x5d, 0xe2, 0x5b, 0xac, 0xc8, 0x31, 0x5b, 0xb3, 0x25,
+ /*3bc0:*/ 0xe2, 0x3f, 0x51, 0x22, 0x38, 0x6c, 0x72, 0x68, 0xdd, 0xe9, 0x80, 0xb4, 0x39, 0xa3, 0xe0, 0xc1,
+ /*3bd0:*/ 0x3b, 0x02, 0x7d, 0x63, 0xbe, 0xb0, 0xb2, 0x80, 0x87, 0x6e, 0x55, 0x32, 0x4e, 0x12, 0x92, 0xee,
+ /*3be0:*/ 0xf0, 0xe1, 0x45, 0xf5, 0x1b, 0x1b, 0xa4, 0x56, 0xa6, 0x11, 0x92, 0xa1, 0x15, 0x56, 0x25, 0xb7,
+ /*3bf0:*/ 0x94, 0x8e, 0x04, 0x12, 0x1c, 0x4b, 0x9a, 0x87, 0x84, 0x70, 0x1e, 0xdb, 0x49, 0xeb, 0xd5, 0xfa,
+ /*3c00:*/ 0xa2, 0xb1, 0x11, 0xd2, 0x8c, 0x4f, 0x88, 0xed, 0xf9, 0x69, 0x08, 0x53, 0xff, 0x82, 0x79, 0x18,
+ /*3c10:*/ 0x2b, 0xf8, 0xa6, 0x87, 0xdd, 0x13, 0xa0, 0x7b, 0xfc, 0x51, 0x7d, 0xde, 0xac, 0xfc, 0x8b, 0xd4,
+ /*3c20:*/ 0x0e, 0xf5, 0x61, 0x7e, 0x0f, 0xa9, 0x96, 0xd2, 0xcf, 0x85, 0x2c, 0x4d, 0x9b, 0x12, 0xbe, 0xf9,
+ /*3c30:*/ 0x7c, 0x4f, 0x75, 0x68, 0x4d, 0x34, 0x98, 0xf8, 0x5f, 0xc4, 0xcf, 0x29, 0x87, 0x26, 0xec, 0x09,
+ /*3c40:*/ 0x64, 0xd0, 0x6e, 0x92, 0x13, 0xc4, 0x49, 0xc1, 0xb3, 0xe2, 0x2a, 0x70, 0x03, 0x28, 0x83, 0xde,
+ /*3c50:*/ 0x28, 0x33, 0x6a, 0x48, 0x9e, 0xf2, 0x8b, 0x9b, 0x52, 0xc3, 0xc3, 0x20, 0x8b, 0xc3, 0xdb, 0x74,
+ /*3c60:*/ 0x56, 0xb6, 0x7a, 0x2b, 0xe8, 0x7d, 0x2d, 0x54, 0x27, 0x8b, 0xa8, 0xa3, 0x52, 0x99, 0xcb, 0x9a,
+ /*3c70:*/ 0xbf, 0x32, 0xa7, 0xb4, 0x82, 0x51, 0x05, 0xad, 0xc2, 0x81, 0x7f, 0xaa, 0xfe, 0x87, 0x1e, 0xb4,
+ /*3c80:*/ 0x57, 0xb7, 0x63, 0x6a, 0x7d, 0x5d, 0x0f, 0x8c, 0x77, 0x16, 0x1f, 0x49, 0xa4, 0xba, 0x0f, 0x56,
+ /*3c90:*/ 0x1c, 0x73, 0x95, 0x42, 0x1e, 0x56, 0xc6, 0x11, 0x5a, 0x0d, 0x3d, 0x88, 0x23, 0xc8, 0xaa, 0x5d,
+ /*3ca0:*/ 0x60, 0x87, 0xce, 0xd0, 0xd0, 0xea, 0x43, 0xd4, 0x31, 0xbb, 0xb3, 0xd9, 0xbb, 0x5e, 0x56, 0x79,
+ /*3cb0:*/ 0x4e, 0x6c, 0x4a, 0x54, 0x1a, 0x96, 0x81, 0xe2, 0xdb, 0x47, 0xc4, 0x6d, 0xb3, 0xfa, 0xc0, 0x0e,
+ /*3cc0:*/ 0xdd, 0x3d, 0x12, 0xe3, 0x51, 0x66, 0x05, 0xe1, 0xe1, 0x8e, 0x3d, 0x0a, 0x7d, 0xb2, 0xe5, 0x7d,
+ /*3cd0:*/ 0x78, 0x10, 0xb9, 0x95, 0xf1, 0xdc, 0xa7, 0xcd, 0x3a, 0xcf, 0xf3, 0xe0, 0x11, 0x10, 0x6b, 0xc2,
+ /*3ce0:*/ 0xc0, 0x9b, 0x7e, 0xc1, 0x40, 0x7e, 0x57, 0xfa, 0xe8, 0x95, 0x42, 0x52, 0x32, 0xe2, 0x3f, 0xf0,
+ /*3cf0:*/ 0x74, 0x94, 0xd7, 0x2f, 0x47, 0xdc, 0xe0, 0x98, 0x09, 0xf1, 0x51, 0xca, 0x0f, 0x03, 0xfc, 0xf6,
+ /*3d00:*/ 0x89, 0xef, 0xa6, 0x49, 0x1b, 0x05, 0x1b, 0x3e, 0xbc, 0x3d, 0xde, 0x32, 0x4e, 0xff, 0xcb, 0x44,
+ /*3d10:*/ 0x86, 0xbf, 0xeb, 0x1f, 0xeb, 0x15, 0x37, 0xb9, 0xde, 0x68, 0xd0, 0x91, 0x37, 0xff, 0x9b, 0xf9,
+ /*3d20:*/ 0xcd, 0x62, 0xf8, 0x1a, 0xfb, 0x80, 0x60, 0x15, 0x76, 0x62, 0x01, 0x8c, 0x9e, 0xda, 0x93, 0xd9,
+ /*3d30:*/ 0x51, 0x5a, 0x87, 0xd4, 0xe0, 0x24, 0x67, 0xac, 0xa7, 0x72, 0x33, 0x54, 0xc0, 0x94, 0x15, 0x23,
+ /*3d40:*/ 0x10, 0xa3, 0x18, 0xde, 0x0d, 0x0f, 0xd9, 0xc1, 0x52, 0xad, 0x37, 0xd2, 0x6d, 0xf0, 0x57, 0x20,
+ /*3d50:*/ 0xe6, 0xaf, 0x21, 0xe5, 0xa5, 0x32, 0xd5, 0xfe, 0xca, 0x57, 0x50, 0x75, 0xd7, 0xb7, 0x20, 0xa2,
+ /*3d60:*/ 0x3c, 0xf0, 0xa2, 0xca, 0xce, 0x43, 0xe5, 0xe0, 0xaa, 0xb2, 0xf3, 0x5d, 0x12, 0x15, 0x46, 0x72,
+ /*3d70:*/ 0xfe, 0x99, 0x21, 0x2a, 0x43, 0x6f, 0x9f, 0x70, 0x42, 0x9d, 0xe9, 0xf7, 0x8e, 0xc7, 0x4a, 0xd9,
+ /*3d80:*/ 0x05, 0x09, 0xc6, 0xb5, 0x9f, 0x4b, 0x6f, 0xb9, 0x53, 0x4b, 0x4e, 0x3f, 0x01, 0x7b, 0x3e, 0x7c,
+ /*3d90:*/ 0x75, 0x61, 0x32, 0x46, 0xb9, 0x3d, 0xc6, 0xdf, 0x75, 0x05, 0x6a, 0xe5, 0x7e, 0xbf, 0x44, 0xdd,
+ /*3da0:*/ 0xc5, 0xca, 0xa8, 0x9a, 0x9b, 0x71, 0xf7, 0x98, 0xa3, 0xec, 0xee, 0x1c, 0xc9, 0x8d, 0x10, 0x11,
+ /*3db0:*/ 0xd6, 0x3b, 0xda, 0x3c, 0x35, 0x89, 0x3d, 0x8d, 0x9a, 0xcc, 0x43, 0x17, 0x1e, 0x32, 0x05, 0x23,
+ /*3dc0:*/ 0x70, 0xa4, 0x26, 0x69, 0xc1, 0x8a, 0x83, 0x7a, 0xdf, 0x9d, 0x1a, 0x3b, 0xcc, 0x22, 0x52, 0x76,
+ /*3dd0:*/ 0xe5, 0x7e, 0xc3, 0x63, 0xf8, 0xd1, 0xc1, 0x3a, 0x8e, 0x88, 0x64, 0x80, 0x50, 0x5f, 0xa0, 0x8d,
+ /*3de0:*/ 0x16, 0x89, 0x88, 0x57, 0x21, 0x38, 0xc1, 0x76, 0x19, 0xc5, 0x5b, 0x90, 0x92, 0xd3, 0x45, 0xf5,
+ /*3df0:*/ 0xf4, 0x79, 0x35, 0xf5, 0x1a, 0x2d, 0x53, 0xe1, 0x7c, 0x23, 0x3a, 0x52, 0x6f, 0x4c, 0x44, 0x87,
+ /*3e00:*/ 0x99, 0x71, 0xf7, 0x13, 0x5b, 0x4f, 0x50, 0x15, 0x06, 0x10, 0x32, 0xc4, 0xb7, 0x81, 0xd7, 0x73,
+ /*3e10:*/ 0xeb, 0x20, 0x8b, 0x92, 0x62, 0xd1, 0x37, 0xe7, 0x6b, 0xe8, 0x8c, 0x5b, 0xe3, 0x27, 0x13, 0x07,
+ /*3e20:*/ 0x39, 0xdc, 0x1b, 0xa7, 0x67, 0x40, 0x8b, 0x44, 0x83, 0xff, 0x47, 0x1a, 0xfa, 0x0d, 0x27, 0x98,
+ /*3e30:*/ 0x4c, 0xc9, 0xe4, 0x76, 0x9f, 0x4f, 0xc3, 0xf7, 0x3a, 0x51, 0x54, 0x84, 0x75, 0x21, 0x6b, 0xb8,
+ /*3e40:*/ 0x3f, 0x01, 0x54, 0x46, 0x7f, 0x0d, 0x0d, 0x26, 0x4a, 0x6a, 0x92, 0xe1, 0x8a, 0x3a, 0x22, 0x9f,
+ /*3e50:*/ 0x01, 0x00, 0x55, 0x3a, 0x16, 0x2a, 0xc5, 0xad, 0x3a, 0xb1, 0x76, 0xd5, 0x13, 0xf2, 0x6a, 0xd4,
+ /*3e60:*/ 0x7f, 0x50, 0xca, 0x75, 0x20, 0x77, 0xd0, 0xbf, 0x34, 0x7e, 0x22, 0xd7, 0x9a, 0xaf, 0xcb, 0x0b,
+ /*3e70:*/ 0x07, 0x67, 0x77, 0xb9, 0xa5, 0xaf, 0x86, 0x42, 0x3f, 0xc1, 0x4b, 0x17, 0xc1, 0x0c, 0xe7, 0x4e,
+ /*3e80:*/ 0xab, 0x11, 0xe3, 0xbd, 0x21, 0x30, 0xe3, 0x58, 0x0f, 0xbe, 0xeb, 0xaa, 0xe0, 0x0c, 0x25, 0xfd,
+ /*3e90:*/ 0x8f, 0xc2, 0x67, 0x5b, 0xbf, 0x62, 0xe8, 0x5b, 0x0a, 0x08, 0xd5, 0xee, 0xf4, 0x0a, 0x90, 0x58,
+ /*3ea0:*/ 0xf6, 0x6d, 0x0e, 0x17, 0x3f, 0x7b, 0x63, 0x52, 0x9b, 0x1e, 0xd5, 0x57, 0x44, 0xc9, 0x2f, 0x36,
+ /*3eb0:*/ 0xd0, 0x82, 0x95, 0x9a, 0xf8, 0xe7, 0x52, 0x3b, 0xda, 0x91, 0xf1, 0xd4, 0x33, 0xb6, 0xca, 0x5b,
+ /*3ec0:*/ 0xf5, 0x86, 0x72, 0x9f, 0x5a, 0x75, 0xaf, 0xde, 0xcc, 0xc2, 0x86, 0x7f, 0x36, 0xcc, 0x0f, 0x90,
+ /*3ed0:*/ 0x69, 0x7b, 0x7b, 0xa4, 0xdf, 0xf3, 0x65, 0x6d, 0xb2, 0xd5, 0xd0, 0x47, 0x27, 0x80, 0x03, 0x86,
+ /*3ee0:*/ 0x0c, 0x5a, 0x6b, 0x53, 0x62, 0x54, 0x87, 0xe3, 0xd7, 0x19, 0xdb, 0x6d, 0xb8, 0x4f, 0x7c, 0x32,
+ /*3ef0:*/ 0xd1, 0xd6, 0xe1, 0x1e, 0xa0, 0x02, 0x28, 0xed, 0x7e, 0xe0, 0x11, 0x8c, 0x94, 0x64, 0xa8, 0xee,
+ /*3f00:*/ 0x25, 0x81, 0x1d, 0x38, 0xa7, 0x2d, 0x65, 0xdc, 0x64, 0x2e, 0x61, 0xb5, 0x1e, 0xc7, 0x50, 0x20,
+ /*3f10:*/ 0x2a, 0x20, 0x28, 0x65, 0xba, 0x5a, 0xb3, 0x31, 0x10, 0x07, 0x4f, 0xb0, 0x74, 0x53, 0xd2, 0xb3,
+ /*3f20:*/ 0xf3, 0xbe, 0x5a, 0x5c, 0x0b, 0xcc, 0x31, 0x8e, 0xfe, 0x0f, 0xd2, 0x27, 0x1f, 0x4e, 0x76, 0xd0,
+ /*3f30:*/ 0x6a, 0xf6, 0x23, 0x19, 0x2e, 0xc7, 0x79, 0xcf, 0x27, 0xe6, 0xb9, 0x64, 0xa0, 0x46, 0x30, 0xf9,
+ /*3f40:*/ 0x7a, 0x7e, 0x42, 0x98, 0x68, 0x20, 0x56, 0x59, 0xe5, 0xf2, 0x32, 0x9e, 0x24, 0xf3, 0x39, 0xcb,
+ /*3f50:*/ 0x8d, 0x1c, 0x40, 0xc8, 0x56, 0x5d, 0x61, 0x03, 0xbc, 0x9f, 0x9b, 0x1c, 0xe6, 0x6d, 0xa2, 0xee,
+ /*3f60:*/ 0xf1, 0x33, 0x5a, 0xe7, 0x7e, 0xf7, 0x9c, 0xd4, 0x9c, 0xd9, 0x20, 0xce, 0x9f, 0x80, 0x18, 0x8a,
+ /*3f70:*/ 0xaa, 0xe7, 0x44, 0x87, 0xd7, 0x23, 0xc6, 0x9c, 0x9c, 0x5d, 0x0c, 0xc0, 0xc9, 0x6f, 0x7b, 0x3d,
+ /*3f80:*/ 0x49, 0xa7, 0x2d, 0x88, 0x0b, 0xf3, 0x23, 0xec, 0x42, 0xfd, 0xc7, 0x61, 0x0d, 0xa2, 0xed, 0xac,
+ /*3f90:*/ 0x13, 0x07, 0xe5, 0xd6, 0x77, 0x55, 0x48, 0xa1, 0x34, 0xbb, 0xe2, 0x77, 0x30, 0xc0, 0x15, 0x19,
+ /*3fa0:*/ 0xfd, 0xdf, 0xd2, 0x39, 0x60, 0xc6, 0x98, 0x0e, 0x82, 0xfd, 0xe1, 0xef, 0x34, 0xf0, 0x83, 0x8c,
+ /*3fb0:*/ 0x9e, 0x2b, 0x1b, 0xdf, 0xf5, 0xfc, 0x42, 0x78, 0x43, 0xa1, 0x6d, 0xa4, 0x0a, 0x65, 0xae, 0xfe,
+ /*3fc0:*/ 0xf6, 0xdb, 0xfb, 0x02, 0x9d, 0x53, 0x15, 0xcf, 0x9d, 0x65, 0x1b, 0x9e, 0xfb, 0x20, 0x50, 0xe4,
+ /*3fd0:*/ 0xe3, 0xf0, 0x5d, 0xc8, 0x68, 0xb8, 0xd8, 0xa3, 0xe3, 0xff, 0xc5, 0xc1, 0x8c, 0xab, 0xcc, 0x8d,
+ /*3fe0:*/ 0xa1, 0x7a, 0x17, 0xe5, 0xdc, 0xb1, 0xf1, 0xea, 0x0c, 0x47, 0x0e, 0x22, 0xe2, 0x2e, 0x45, 0x3a,
+ /*3ff0:*/ 0x36, 0x66, 0xbb, 0x39, 0x38, 0xbd, 0x44, 0x1a, 0x53, 0xce, 0xd9, 0x41, 0x2c, 0x01, 0x2b, 0x49,
+ /*4000:*/ 0x81, 0x18, 0x05, 0x96, 0x4d, 0xd8, 0xd2, 0x38, 0xab, 0xef, 0xf9, 0x44, 0xc0, 0x12, 0xfe, 0xa3,
+ /*4010:*/ 0x16, 0xdf, 0x1f, 0xe8, 0xcd, 0x87, 0xb2, 0x00, 0x76, 0xcb, 0xa3, 0x14, 0xfa, 0x4c, 0x3b, 0x22,
+ /*4020:*/ 0xd8, 0x5b, 0x2e, 0xe3, 0x06, 0xee, 0x77, 0xd1, 0x3f, 0xbb, 0x22, 0x9a, 0xd5, 0x10, 0x09, 0xc0,
+ /*4030:*/ 0x91, 0xd7, 0x81, 0x8d, 0x95, 0x6c, 0x57, 0x72, 0xf3, 0x67, 0xa6, 0xc8, 0x29, 0xc5, 0xd1, 0x85,
+ /*4040:*/ 0xac, 0x37, 0x1e, 0x5b, 0x7b, 0x5f, 0x69, 0x35, 0x39, 0xce, 0x5d, 0xea, 0x6a, 0x3b, 0x4c, 0xa7,
+ /*4050:*/ 0x12, 0x3a, 0x68, 0xa8, 0xc9, 0x72, 0xc3, 0x1b, 0x98, 0xdb, 0x61, 0xd4, 0xc4, 0xf9, 0x8f, 0x8b,
+ /*4060:*/ 0xd9, 0x29, 0xf4, 0x89, 0xcb, 0x3b, 0x28, 0x62, 0x0a, 0x9c, 0x2d, 0x9e, 0xc1, 0xab, 0xe6, 0xb5,
+ /*4070:*/ 0x7e, 0x66, 0x51, 0xc7, 0x9c, 0x6f, 0xa8, 0xd4, 0x5d, 0xa5, 0x22, 0xed, 0x30, 0x26, 0xb6, 0x2b,
+ /*4080:*/ 0x85, 0x6d, 0x76, 0xc6, 0x86, 0x0e, 0xef, 0xe2, 0x1e, 0x9a, 0xaa, 0xf9, 0xae, 0xed, 0x02, 0x26,
+ /*4090:*/ 0x68, 0x0b, 0x15, 0xf9, 0x45, 0xf8, 0xb7, 0xcb, 0xfc, 0xff, 0xf2, 0x3e, 0xc9, 0x5a, 0x35, 0x14,
+ /*40a0:*/ 0x6b, 0x67, 0x69, 0xe9, 0x03, 0x12, 0xf4, 0xfb, 0x46, 0xa7, 0x9c, 0xc8, 0x43, 0x03, 0x08, 0xea,
+ /*40b0:*/ 0xf8, 0x5b, 0xdb, 0x29, 0xad, 0x73, 0x8c, 0x19, 0x18, 0x70, 0x47, 0xd7, 0x40, 0x66, 0x50, 0xfe,
+ /*40c0:*/ 0xf2, 0x00, 0xc4, 0xeb, 0x20, 0x8f, 0x20, 0xf1, 0x9d, 0xea, 0x23, 0x37, 0x8f, 0x22, 0x5d, 0xff,
+ /*40d0:*/ 0x8c, 0x17, 0xaa, 0x6a, 0x3a, 0xad, 0x9a, 0x79, 0x74, 0xe9, 0xdc, 0xc2, 0x97, 0x96, 0xb0, 0xf8,
+ /*40e0:*/ 0x86, 0x38, 0x13, 0x41, 0xfa, 0x08, 0xd9, 0x2a, 0x18, 0xbc, 0x4a, 0xb6, 0x2a, 0x7e, 0x8f, 0x0d,
+ /*40f0:*/ 0xeb, 0x09, 0x6c, 0xec, 0x39, 0xdc, 0x2e, 0x4c, 0xcd, 0x58, 0x0f, 0xaf, 0x7e, 0x0f, 0x04, 0x71,
+ /*4100:*/ 0x8f, 0xa4, 0x08, 0xe6, 0x2b, 0xda, 0xde, 0x42, 0x48, 0xb4, 0xa3, 0x4c, 0x1c, 0x70, 0x4d, 0x5c,
+ /*4110:*/ 0x5c, 0x5b, 0xca, 0x00, 0xa4, 0x2c, 0x9c, 0x39, 0x23, 0xcc, 0xf8, 0xbb, 0xa2, 0x5a, 0xe9, 0x33,
+ /*4120:*/ 0xe0, 0xa5, 0xb6, 0xcc, 0x86, 0x70, 0x8c, 0xd9, 0x22, 0x34, 0xf2, 0x44, 0xd0, 0xcb, 0x23, 0xbe,
+ /*4130:*/ 0xee, 0xa1, 0xeb, 0xbf, 0x17, 0xb5, 0x95, 0x5d, 0xc2, 0x35, 0xd2, 0x7e, 0xbb, 0xc4, 0xd7, 0xb3,
+ /*4140:*/ 0x43, 0x9e, 0x03, 0x5b, 0xc8, 0x54, 0xd8, 0x78, 0x8d, 0x6d, 0x3f, 0x51, 0x40, 0x0a, 0x9d, 0x44,
+ /*4150:*/ 0xcf, 0xc5, 0x9d, 0xe8, 0x44, 0x9b, 0xb7, 0x65, 0xd5, 0x42, 0x6f, 0xb5, 0x1f, 0x1a, 0x52, 0x36,
+ /*4160:*/ 0x73, 0x30, 0x29, 0xb4, 0x4c, 0x31, 0xa4, 0xff, 0xc8, 0x54, 0xb2, 0xde, 0xa7, 0x10, 0xa9, 0xb4,
+ /*4170:*/ 0x3b, 0xfd, 0x20, 0xdf, 0xc6, 0xcc, 0xfa, 0x32, 0xea, 0xf3, 0x60, 0x08, 0x4a, 0x29, 0x16, 0x72,
+ /*4180:*/ 0xb3, 0x4c, 0x7a, 0xe5, 0xc1, 0x88, 0x29, 0x23, 0x10, 0x02, 0x14, 0xad, 0x24, 0x64, 0xe3, 0x9e,
+ /*4190:*/ 0xfc, 0xd3, 0x5b, 0x43, 0xee, 0x1a, 0x4b, 0x1e, 0x49, 0xf2, 0x53, 0x37, 0xae, 0x21, 0xe9, 0x4b,
+ /*41a0:*/ 0x61, 0x89, 0xd0, 0x70, 0x94, 0x20, 0x17, 0x75, 0x59, 0x01, 0x0a, 0xb4, 0x98, 0xb2, 0x98, 0x0b,
+ /*41b0:*/ 0x17, 0x99, 0xc3, 0xfe, 0x63, 0x51, 0x97, 0xb2, 0x3b, 0x71, 0x54, 0x63, 0x70, 0x12, 0x3f, 0x26,
+ /*41c0:*/ 0xbe, 0x0e, 0x39, 0x26, 0xf6, 0xe4, 0xda, 0x87, 0xb2, 0x45, 0x03, 0x71, 0xce, 0xe6, 0xc1, 0xd1,
+ /*41d0:*/ 0x05, 0xfc, 0x46, 0x37, 0x27, 0x92, 0xb2, 0xa2, 0xfd, 0xa7, 0x9f, 0xa3, 0xdd, 0x94, 0x38, 0x83,
+ /*41e0:*/ 0x3e, 0x7b, 0xa2, 0x1d, 0xc2, 0x32, 0x36, 0xbf, 0x35, 0x2d, 0xa6, 0x1d, 0xf0, 0x94, 0x01, 0x78,
+ /*41f0:*/ 0xd3, 0x80, 0x66, 0x5f, 0xc8, 0xa5, 0x12, 0x99, 0x35, 0xb7, 0x96, 0x7b, 0x18, 0x41, 0x85, 0x9a,
+ /*4200:*/ 0x4b, 0x56, 0xd4, 0xf4, 0x3e, 0xe3, 0x17, 0xb8, 0x46, 0x55, 0xe8, 0x54, 0xbc, 0x1f, 0x43, 0x18,
+ /*4210:*/ 0xf4, 0xb7, 0x51, 0x7c, 0xd2, 0xa6, 0x3d, 0x75, 0xb6, 0x1d, 0x29, 0xad, 0x5b, 0xb7, 0xb0, 0x4c,
+ /*4220:*/ 0xc9, 0x51, 0xc0, 0x09, 0x25, 0x40, 0x90, 0xd7, 0x7c, 0x43, 0xfb, 0xa2, 0x86, 0x69, 0x0e, 0x3e,
+ /*4230:*/ 0x2b, 0x3e, 0xe9, 0x13, 0xef, 0x95, 0x70, 0x17, 0x57, 0x02, 0x0b, 0x50, 0x9d, 0x94, 0x1b, 0xb6,
+ /*4240:*/ 0x1e, 0x6b, 0x5e, 0x5f, 0xa1, 0x78, 0xc3, 0xfd, 0x5c, 0x2d, 0x66, 0x3e, 0xbe, 0x44, 0x03, 0x4e,
+ /*4250:*/ 0x95, 0x44, 0x28, 0xba, 0x09, 0xdc, 0x2d, 0x25, 0x68, 0xac, 0x17, 0x90, 0x5f, 0x2a, 0x8e, 0x74,
+ /*4260:*/ 0x88, 0x30, 0x7d, 0x60, 0x5b, 0xfd, 0x21, 0x3c, 0x72, 0x0c, 0x48, 0x90, 0x14, 0x8d, 0xc7, 0x8b,
+ /*4270:*/ 0xa9, 0x92, 0x66, 0xaa, 0xe4, 0x2d, 0x1b, 0x6f, 0xaf, 0x40, 0xd1, 0x63, 0x78, 0x7c, 0x19, 0x0a,
+ /*4280:*/ 0x30, 0x75, 0x7c, 0xb5, 0xaf, 0x64, 0xb7, 0x37, 0x60, 0x11, 0x7c, 0xc0, 0x1f, 0xa1, 0xeb, 0xf8,
+ /*4290:*/ 0x2b, 0x9b, 0x95, 0x31, 0x9f, 0x51, 0x8e, 0x5b, 0x88, 0xaa, 0x13, 0x54, 0xa8, 0xba, 0x21, 0xfe,
+ /*42a0:*/ 0x3c, 0xc3, 0x28, 0x7f, 0xc6, 0x03, 0xbc, 0x53, 0xde, 0xcd, 0x3c, 0x88, 0xd9, 0xa6, 0x3b, 0xe8,
+ /*42b0:*/ 0x47, 0x97, 0xca, 0xe9, 0x30, 0x9d, 0xb2, 0x3e, 0x61, 0x87, 0xc2, 0x65, 0x1a, 0x3d, 0x43, 0x8c,
+ /*42c0:*/ 0x0d, 0x46, 0x44, 0x20, 0xfb, 0x36, 0xd1, 0x1b, 0x67, 0x63, 0x5a, 0x75, 0xdc, 0x14, 0x26, 0xb3,
+ /*42d0:*/ 0xca, 0x3a, 0xab, 0x17, 0x2e, 0xaf, 0xe1, 0xec, 0x76, 0xc5, 0xc2, 0xef, 0xba, 0xfa, 0xb7, 0xa9,
+ /*42e0:*/ 0x52, 0xb9, 0x3e, 0xe5, 0x74, 0x21, 0xc3, 0x6b, 0x24, 0x43, 0xcb, 0x82, 0x73, 0x5d, 0x49, 0x59,
+ /*42f0:*/ 0xa1, 0xf8, 0x5c, 0x95, 0xea, 0x94, 0x93, 0x5b, 0x01, 0xda, 0xd9, 0x19, 0x50, 0x8d, 0x40, 0xa5,
+ /*4300:*/ 0x83, 0x34, 0x52, 0x7e, 0x41, 0x3f, 0x81, 0x87, 0xc5, 0x5a, 0x70, 0xc9, 0x04, 0x07, 0xe9, 0x68,
+ /*4310:*/ 0x8e, 0x56, 0x93, 0x6f, 0x2b, 0x2a, 0x7a, 0x16, 0xdb, 0x4e, 0x7b, 0x2b, 0xcd, 0xe0, 0x24, 0x9a,
+ /*4320:*/ 0xc1, 0xbd, 0x2e, 0x4b, 0x36, 0xba, 0x49, 0x97, 0xbf, 0x97, 0x51, 0x2a, 0xfd, 0xe5, 0xf9, 0x71,
+ /*4330:*/ 0xf2, 0xf0, 0x2a, 0xe1, 0x33, 0x99, 0x49, 0xf6, 0x7f, 0xea, 0x07, 0x1d, 0x55, 0x88, 0x2b, 0x24,
+ /*4340:*/ 0xed, 0x3b, 0x9f, 0xd4, 0xaf, 0x50, 0x6b, 0xfe, 0xdf, 0xe2, 0x66, 0x0d, 0xdc, 0x13, 0x5e, 0xf9,
+ /*4350:*/ 0x66, 0xb8, 0x61, 0x52, 0x93, 0x14, 0x12, 0x8e, 0x36, 0x21, 0xe2, 0x34, 0xa0, 0xd6, 0xde, 0x0e,
+ /*4360:*/ 0x8d, 0x35, 0x01, 0xfb, 0xe7, 0xe7, 0x60, 0x41, 0xe8, 0xab, 0xf5, 0x4c, 0x82, 0x60, 0x69, 0xbe,
+ /*4370:*/ 0x3e, 0x9e, 0x9f, 0x65, 0xa3, 0x0a, 0x6e, 0xba, 0x86, 0xff, 0x45, 0x20, 0x8a, 0x3d, 0xf9, 0xfa,
+ /*4380:*/ 0xe8, 0x01, 0xf4, 0x42, 0x21, 0x5d, 0xa5, 0x3b, 0xff, 0x80, 0xd1, 0xbf, 0xe0, 0x9d, 0x99, 0xf1,
+ /*4390:*/ 0xe0, 0x97, 0x14, 0xd9, 0xc7, 0x1a, 0x3b, 0xf2, 0x21, 0x76, 0x56, 0x75, 0xf6, 0x8b, 0x75, 0x95,
+ /*43a0:*/ 0x5d, 0x0d, 0x2e, 0x59, 0xcb, 0xf2, 0x0e, 0xde, 0x42, 0xb8, 0xdd, 0x86, 0x2a, 0xcc, 0xb3, 0x97,
+ /*43b0:*/ 0x7d, 0x5f, 0x81, 0xb7, 0xf5, 0x88, 0x54, 0xea, 0xdb, 0x0a, 0x97, 0x08, 0x08, 0x55, 0x97, 0x51,
+ /*43c0:*/ 0x1d, 0x8d, 0xae, 0xf4, 0x5a, 0xc5, 0x84, 0xef, 0x07, 0xb0, 0xb3, 0x4d, 0x3b, 0xfb, 0xe8, 0x33,
+ /*43d0:*/ 0x24, 0xed, 0x5a, 0xb3, 0xa4, 0xe6, 0x0c, 0x14, 0xb3, 0xd2, 0x39, 0x8f, 0x1e, 0x39, 0xe0, 0x00,
+ /*43e0:*/ 0xfc, 0x4e, 0x0a, 0x0e, 0x76, 0x8c, 0xef, 0x21, 0xec, 0x95, 0xf8, 0x18, 0xa6, 0x66, 0xce, 0xec,
+ /*43f0:*/ 0x62, 0x22, 0xf5, 0xfe, 0xc8, 0x6c, 0x6e, 0x3e, 0x42, 0x35, 0xde, 0xce, 0xa9, 0x73, 0x8c, 0xc9,
+ /*4400:*/ 0xe2, 0xaa, 0xe8, 0xfa, 0xab, 0x13, 0xcb, 0x06, 0xf7, 0xee, 0x99, 0xfd, 0x2d, 0x0b, 0x92, 0xe2,
+ /*4410:*/ 0x79, 0x96, 0x6b, 0xf3, 0x73, 0x01, 0x26, 0x48, 0x32, 0xcd, 0x19, 0x2a, 0x12, 0x84, 0xa0, 0xca,
+ /*4420:*/ 0x5f, 0xc0, 0xe8, 0x86, 0x40, 0x8c, 0xa3, 0xd5, 0x2e, 0x14, 0x5d, 0x58, 0xad, 0x2b, 0xcf, 0xf7,
+ /*4430:*/ 0xeb, 0x8c, 0xba, 0x59, 0x18, 0x13, 0x62, 0x14, 0xe6, 0x01, 0x89, 0xeb, 0xae, 0x22, 0xf6, 0x66,
+ /*4440:*/ 0xd5, 0x9a, 0x07, 0x76, 0x87, 0xf8, 0xb9, 0x1b, 0xa5, 0x4f, 0xa2, 0xfd, 0x84, 0xcd, 0x1d, 0x81,
+ /*4450:*/ 0x1b, 0xda, 0xd6, 0x14, 0x60, 0xfa, 0x17, 0x14, 0x59, 0x18, 0x06, 0x70, 0x06, 0x61, 0x03, 0x80,
+ /*4460:*/ 0x44, 0x8f, 0x5e, 0xb8, 0xb8, 0xc5, 0x80, 0x43, 0xb5, 0x35, 0x97, 0xbe, 0x4c, 0x25, 0x38, 0xfd,
+ /*4470:*/ 0x2b, 0xa6, 0xbc, 0xcc, 0x37, 0x34, 0x23, 0x44, 0x32, 0x85, 0xf1, 0x7d, 0xea, 0xc5, 0xb2, 0x3d,
+ /*4480:*/ 0xed, 0x58, 0xe3, 0x07, 0xed, 0xb4, 0x52, 0x84, 0xf4, 0xcf, 0xa4, 0xe9, 0x4b, 0xe4, 0x35, 0xb5,
+ /*4490:*/ 0x4b, 0x3d, 0xb1, 0x2f, 0x6f, 0xcc, 0x9f, 0xc5, 0xf1, 0x6e, 0x74, 0xe4, 0x07, 0x1e, 0xef, 0x0e,
+ /*44a0:*/ 0xf0, 0x32, 0x3f, 0x91, 0x7d, 0x44, 0x0c, 0xe6, 0xb9, 0x3a, 0xdd, 0x8b, 0x0b, 0x34, 0x7b, 0x28,
+ /*44b0:*/ 0x10, 0xe5, 0xc9, 0x95, 0x34, 0x18, 0xa7, 0xd2, 0x6f, 0x67, 0x8b, 0x3d, 0xa3, 0x49, 0x16, 0xb8,
+ /*44c0:*/ 0x9e, 0x1b, 0x64, 0x2d, 0xbe, 0xf9, 0x81, 0x16, 0xcb, 0xd5, 0x2f, 0x67, 0x1d, 0x54, 0x64, 0xb8,
+ /*44d0:*/ 0xee, 0x98, 0x75, 0x12, 0xa1, 0x62, 0xb9, 0xa6, 0x4b, 0xc7, 0x8f, 0x85, 0x77, 0xd2, 0xf4, 0x8f,
+ /*44e0:*/ 0x36, 0xbe, 0xa3, 0xe7, 0x6c, 0xf9, 0xb1, 0x88, 0xf8, 0xf0, 0xac, 0x74, 0x32, 0xa5, 0x47, 0x69,
+ /*44f0:*/ 0x6d, 0xb6, 0x11, 0xc7, 0x47, 0x0d, 0xdf, 0x35, 0xf3, 0x59, 0x66, 0x2b, 0x47, 0xd7, 0x21, 0x46,
+ /*4500:*/ 0x57, 0x53, 0x83, 0x33, 0x66, 0x00, 0x78, 0x82, 0x93, 0x7c, 0xb8, 0x46, 0x3b, 0xe6, 0xd5, 0xe9,
+ /*4510:*/ 0xee, 0xac, 0x1a, 0x7f, 0x88, 0xb3, 0xc1, 0x06, 0xd1, 0x97, 0x9f, 0xa6, 0x03, 0xea, 0x7a, 0x41,
+ /*4520:*/ 0xfd, 0xae, 0xc6, 0x75, 0x11, 0x77, 0x35, 0x1b, 0x7b, 0x79, 0x6b, 0xb0, 0x0d, 0xd8, 0x7c, 0xd2,
+ /*4530:*/ 0x7a, 0x50, 0x58, 0x38, 0x94, 0x8e, 0x19, 0x4d, 0x97, 0x45, 0x53, 0xf9, 0x99, 0xa2, 0x8c, 0xaf,
+ /*4540:*/ 0xf9, 0x87, 0x11, 0x5a, 0xd3, 0x09, 0xcb, 0x63, 0x93, 0x0e, 0xd1, 0xbf, 0x27, 0x88, 0x3d, 0xb6,
+ /*4550:*/ 0x17, 0x96, 0x20, 0x9a, 0x27, 0x49, 0xd9, 0x45, 0x05, 0x34, 0x70, 0xa6, 0x4e, 0xab, 0x6b, 0xa2,
+ /*4560:*/ 0x3c, 0xa6, 0x2e, 0xf2, 0x29, 0xfe, 0x7a, 0xc9, 0x06, 0x7d, 0xa1, 0xb6, 0x8b, 0xf2, 0xbf, 0xe7,
+ /*4570:*/ 0xd0, 0x02, 0x39, 0x04, 0x19, 0x22, 0xf0, 0x18, 0x6e, 0x7f, 0x00, 0x4b, 0x8a, 0x42, 0xa7, 0xe3,
+ /*4580:*/ 0x8f, 0x46, 0x0a, 0x92, 0x12, 0x7a, 0xe5, 0xf9, 0x4a, 0x4f, 0x28, 0xb2, 0x57, 0x1c, 0x8a, 0xb2,
+ /*4590:*/ 0x6d, 0xce, 0x6e, 0x42, 0xd6, 0x68, 0xba, 0x60, 0xb2, 0x2a, 0x82, 0x12, 0x80, 0x8c, 0x61, 0xc9,
+ /*45a0:*/ 0xdb, 0xdf, 0x9f, 0x0a, 0x18, 0x8b, 0x7c, 0xf4, 0x25, 0xba, 0x7f, 0x7e, 0x0d, 0x7e, 0x17, 0xc8,
+ /*45b0:*/ 0x05, 0x39, 0x13, 0x55, 0x55, 0x0d, 0x0f, 0x21, 0x5d, 0xf8, 0x6a, 0x83, 0x2a, 0xe4, 0x25, 0xa9,
+ /*45c0:*/ 0x27, 0x6b, 0x3b, 0xa5, 0xff, 0x66, 0xfc, 0x83, 0xcf, 0x73, 0xef, 0xfc, 0x72, 0x51, 0x58, 0x97,
+ /*45d0:*/ 0x52, 0x1f, 0x57, 0x54, 0xa5, 0xe6, 0x14, 0xe5, 0xfe, 0xb2, 0x3e, 0xb7, 0x52, 0x13, 0x62, 0x8c,
+ /*45e0:*/ 0x39, 0xfe, 0x67, 0x45, 0xc4, 0xf3, 0x16, 0xd7, 0xa1, 0x0e, 0x16, 0xe1, 0xb2, 0xb9, 0xba, 0xe7,
+ /*45f0:*/ 0xe1, 0x5c, 0x44, 0x6c, 0xaf, 0xae, 0xea, 0xdf, 0x16, 0x7a, 0xd1, 0xcd, 0xe6, 0x77, 0xf8, 0x0c,
+ /*4600:*/ 0x99, 0xc9, 0x07, 0xa4, 0x3a, 0xa9, 0x7a, 0x79, 0xe1, 0x00, 0x76, 0xbf, 0x8c, 0x54, 0xf9, 0x13,
+ /*4610:*/ 0xf3, 0x2d, 0xe5, 0xc1, 0xcc, 0x39, 0x18, 0xbb, 0x68, 0x44, 0x14, 0xdb, 0x52, 0x3f, 0x9d, 0x5e,
+ /*4620:*/ 0x70, 0x80, 0xd1, 0x12, 0x69, 0xe8, 0xe5, 0x05, 0x9b, 0x3f, 0x34, 0x24, 0xf6, 0xb9, 0x14, 0xaf,
+ /*4630:*/ 0x62, 0x38, 0x5b, 0x41, 0xa7, 0x2a, 0x4f, 0x75, 0xb1, 0x4a, 0x5c, 0xef, 0x78, 0x21, 0x9c, 0x78,
+ /*4640:*/ 0xd7, 0xf8, 0x4e, 0xe6, 0x9c, 0x2e, 0xde, 0xe5, 0x65, 0x3d, 0xfe, 0x7b, 0xd2, 0xea, 0x2f, 0x15,
+ /*4650:*/ 0x35, 0x6e, 0xc7, 0xfe, 0xcc, 0xe6, 0x3d, 0x40, 0xb6, 0x4a, 0xb8, 0x0e, 0x78, 0x26, 0xba, 0xa0,
+ /*4660:*/ 0xf5, 0xdd, 0xfd, 0x89, 0x5a, 0xb8, 0x3d, 0x92, 0x62, 0x32, 0xe8, 0xc5, 0xc8, 0x69, 0x93, 0xb0,
+ /*4670:*/ 0xd2, 0xaa, 0xe2, 0xda, 0x9c, 0xe4, 0xd7, 0x41, 0x5e, 0xdc, 0x74, 0xab, 0x36, 0x1b, 0xaf, 0x71,
+ /*4680:*/ 0xdd, 0xd2, 0x67, 0x25, 0x38, 0x10, 0xd3, 0xc6, 0x00, 0x8e, 0xe6, 0xba, 0xea, 0x91, 0x81, 0x45,
+ /*4690:*/ 0x2e, 0xad, 0x9b, 0x38, 0xe8, 0x77, 0x1d, 0x11, 0x81, 0xd4, 0x90, 0x1a, 0xac, 0xb5, 0x66, 0xdf,
+ /*46a0:*/ 0x5e, 0x4c, 0xc1, 0x1e, 0x82, 0x7a, 0xb1, 0x89, 0xbe, 0xb1, 0xe1, 0xad, 0x4d, 0xd4, 0xce, 0xa3,
+ /*46b0:*/ 0x76, 0x0f, 0x2a, 0xe7, 0x5b, 0x4a, 0x75, 0x0d, 0xbb, 0xd9, 0xf8, 0xe0, 0x8c, 0xd3, 0x0f, 0x3d,
+ /*46c0:*/ 0xbe, 0x17, 0x58, 0x15, 0x5a, 0x83, 0x2e, 0x81, 0xae, 0xa5, 0x69, 0xe2, 0x71, 0xf4, 0x24, 0xd7,
+ /*46d0:*/ 0xd2, 0x18, 0x5c, 0x74, 0x2c, 0x2e, 0xe7, 0xae, 0x6e, 0xe9, 0x18, 0x64, 0x83, 0x24, 0xb4, 0x5b,
+ /*46e0:*/ 0x6e, 0xe3, 0xb3, 0xae, 0x38, 0xe0, 0xb4, 0xba, 0xfe, 0xf7, 0x82, 0xed, 0xa3, 0x88, 0xad, 0xa9,
+ /*46f0:*/ 0xa6, 0x37, 0xf2, 0xc5, 0x83, 0xf8, 0x24, 0xc9, 0x56, 0x8e, 0x94, 0xa3, 0x7d, 0xa7, 0x2b, 0x83,
+ /*4700:*/ 0xc2, 0xe9, 0x87, 0xa0, 0x85, 0x05, 0x4d, 0x35, 0x1e, 0xe0, 0x9e, 0x06, 0xbf, 0x81, 0x26, 0xde,
+ /*4710:*/ 0x6d, 0x55, 0x5f, 0x93, 0xad, 0x80, 0x1e, 0xa5, 0x5c, 0x9d, 0xa6, 0xac, 0x19, 0xa1, 0xf7, 0xb4,
+ /*4720:*/ 0x65, 0x4a, 0xfd, 0xe1, 0xeb, 0x3d, 0xb9, 0x44, 0x53, 0x8f, 0xd0, 0xbe, 0x7d, 0xcf, 0xd5, 0x6c,
+ /*4730:*/ 0xf8, 0x32, 0xde, 0x8f, 0x50, 0x63, 0xa7, 0x4d, 0xe5, 0x0a, 0x5b, 0x2a, 0x2c, 0xd1, 0xcd, 0x32,
+ /*4740:*/ 0x96, 0xd1, 0x4e, 0x21, 0x08, 0xa7, 0x4a, 0xbd, 0x96, 0x51, 0xa3, 0x18, 0x7a, 0xb2, 0xba, 0x41,
+ /*4750:*/ 0xb6, 0x99, 0x70, 0xc8, 0xc1, 0x7b, 0xb8, 0x84, 0xa2, 0x20, 0x8a, 0x1e, 0x1b, 0x9b, 0x56, 0xd4,
+ /*4760:*/ 0xc6, 0xdd, 0x00, 0xfe, 0xa6, 0xb1, 0xb6, 0x8b, 0x02, 0x5b, 0xcd, 0xdf, 0xb5, 0x72, 0xe4, 0xd0,
+ /*4770:*/ 0x9d, 0x95, 0x1d, 0x44, 0xf2, 0x73, 0x7f, 0x18, 0x5b, 0xc5, 0xc3, 0xc4, 0xdd, 0xc6, 0x13, 0x58,
+ /*4780:*/ 0x71, 0x44, 0xec, 0x5b, 0xf6, 0x43, 0x89, 0x21, 0xd8, 0x91, 0x64, 0xb6, 0x69, 0x89, 0x91, 0x4f,
+ /*4790:*/ 0x78, 0x3d, 0xfb, 0xa1, 0x73, 0x96, 0x5f, 0xbf, 0xc0, 0x19, 0x82, 0x0f, 0xb5, 0x2b, 0x3f, 0x1d,
+ /*47a0:*/ 0xba, 0x9a, 0xe8, 0x2e, 0xe5, 0xb9, 0xb9, 0xe7, 0x4c, 0x27, 0x00, 0xca, 0x79, 0xac, 0x5a, 0xfd,
+ /*47b0:*/ 0x13, 0xcb, 0x53, 0x35, 0x65, 0xfa, 0x4d, 0xed, 0xe7, 0x98, 0xe4, 0x00, 0xa0, 0x0f, 0x9d, 0xfc,
+ /*47c0:*/ 0x54, 0x71, 0x69, 0x14, 0x0b, 0xd4, 0x46, 0x62, 0xa9, 0xa5, 0x72, 0x75, 0x5d, 0x22, 0x7b, 0x82,
+ /*47d0:*/ 0x3d, 0xf2, 0x2b, 0xd8, 0x8e, 0x77, 0xc8, 0xf8, 0x97, 0xc3, 0xce, 0x00, 0xdf, 0xa8, 0x00, 0x8a,
+ /*47e0:*/ 0x2a, 0x12, 0x75, 0x10, 0xa8, 0x21, 0x82, 0x86, 0xbd, 0xa8, 0xa1, 0x75, 0xc1, 0x9a, 0x00, 0x71,
+ /*47f0:*/ 0x27, 0x73, 0x00, 0xb8, 0x2a, 0x04, 0x21, 0xb8, 0xc4, 0x56, 0xa0, 0xef, 0xd2, 0x90, 0xc7, 0x23,
+ /*4800:*/ 0x4e, 0x51, 0x7e, 0xcb, 0x9b, 0x5e, 0x4c, 0xae, 0xb0, 0x62, 0xbe, 0x39, 0x3d, 0x19, 0x39, 0x5f,
+ /*4810:*/ 0x32, 0x13, 0x86, 0x6a, 0x5a, 0xad, 0x11, 0x6c, 0x74, 0xf9, 0x5e, 0x78, 0x5e, 0x6e, 0x04, 0xcf,
+ /*4820:*/ 0xeb, 0x2d, 0xe1, 0x7c, 0x5a, 0xfa, 0x7d, 0x26, 0xdc, 0x68, 0x43, 0x09, 0x55, 0x1c, 0x32, 0xcf,
+ /*4830:*/ 0xd8, 0x6d, 0x89, 0xa1, 0xab, 0xb3, 0x17, 0x94, 0x18, 0x25, 0x86, 0x76, 0xc2, 0x05, 0xf4, 0x11,
+ /*4840:*/ 0x06, 0x39, 0x9b, 0x1b, 0x89, 0xab, 0x3d, 0x33, 0x77, 0x09, 0xf1, 0x16, 0x7d, 0x44, 0x2e, 0x05,
+ /*4850:*/ 0xe4, 0x38, 0xc6, 0xc6, 0x4e, 0xdb, 0xe1, 0x2f, 0x98, 0xae, 0x45, 0xf5, 0xf5, 0x34, 0x50, 0x05,
+ /*4860:*/ 0xf0, 0x32, 0x1f, 0x7a, 0x7c, 0xf5, 0x71, 0xa5, 0x08, 0xbb, 0x61, 0x58, 0x3b, 0x4d, 0x48, 0xf8,
+ /*4870:*/ 0x9b, 0x76, 0x32, 0x34, 0x1b, 0x3d, 0x13, 0x1e, 0xf8, 0xed, 0x51, 0x6b, 0x24, 0xa5, 0xe9, 0x96,
+ /*4880:*/ 0x34, 0x98, 0x68, 0xfb, 0xa9, 0x4d, 0x12, 0xa1, 0xa1, 0x0d, 0x6e, 0x32, 0x82, 0xb4, 0xd3, 0xb1,
+ /*4890:*/ 0xb5, 0x20, 0x42, 0xa0, 0xe2, 0x3f, 0x8e, 0xac, 0xe9, 0x37, 0xc5, 0x14, 0x91, 0x5d, 0xd4, 0xd3,
+ /*48a0:*/ 0xed, 0x11, 0x04, 0x27, 0x90, 0xe1, 0x6d, 0xe4, 0xef, 0xd3, 0x41, 0xe3, 0xdc, 0xd3, 0xfc, 0x4c,
+ /*48b0:*/ 0x22, 0x59, 0xc2, 0x33, 0x3c, 0x08, 0xbb, 0x80, 0x32, 0x44, 0xf9, 0x50, 0x11, 0x26, 0x12, 0xd8,
+ /*48c0:*/ 0x68, 0x6c, 0x3b, 0x7f, 0x54, 0x94, 0x03, 0x59, 0x00, 0xea, 0x1d, 0x9d, 0xbb, 0x22, 0xe2, 0xbd,
+ /*48d0:*/ 0xd6, 0x00, 0xe9, 0xcf, 0x9f, 0x86, 0x05, 0x2f, 0x48, 0x2b, 0x79, 0x86, 0x0f, 0x4c, 0xc9, 0xb2,
+ /*48e0:*/ 0x2d, 0xbb, 0xde, 0x59, 0x01, 0x47, 0x98, 0x6b, 0x0d, 0xb2, 0xeb, 0x84, 0x66, 0x1a, 0xd4, 0xa3,
+ /*48f0:*/ 0x0f, 0xb9, 0xb7, 0xd9, 0xa5, 0x0b, 0x23, 0xa8, 0x49, 0xc9, 0x47, 0xd3, 0xff, 0x94, 0xcd, 0x5e,
+ /*4900:*/ 0x78, 0x6a, 0x58, 0x7b, 0x41, 0x12, 0x8d, 0x50, 0x3e, 0xa4, 0x50, 0x53, 0x1d, 0x84, 0xda, 0x58,
+ /*4910:*/ 0x6f, 0x7f, 0x90, 0x58, 0xaf, 0xfa, 0x25, 0xd0, 0x02, 0xd8, 0xea, 0xc9, 0x35, 0x88, 0xd9, 0xf3,
+ /*4920:*/ 0x02, 0xa8, 0xf0, 0xbc, 0x8b, 0x46, 0x42, 0xc5, 0x36, 0xf6, 0xcf, 0x15, 0x5c, 0x74, 0x98, 0x2d,
+ /*4930:*/ 0x29, 0x7f, 0x80, 0xe5, 0xae, 0xb7, 0xb6, 0xf3, 0x11, 0xcc, 0x54, 0x1f, 0xb4, 0x93, 0x34, 0xbe,
+ /*4940:*/ 0x85, 0x7f, 0x4e, 0x3d, 0x1e, 0xe9, 0x63, 0x9c, 0x17, 0x10, 0x28, 0xfb, 0x5a, 0xbc, 0xcb, 0x71,
+ /*4950:*/ 0xb5, 0x64, 0x09, 0x84, 0x9c, 0x6b, 0x8c, 0x54, 0x35, 0xc7, 0x75, 0xc2, 0x6c, 0x3a, 0xee, 0xc2,
+ /*4960:*/ 0xcb, 0xb6, 0x57, 0xad, 0x23, 0xea, 0x18, 0x65, 0x6f, 0xd8, 0xbe, 0x2d, 0x5f, 0x05, 0x18, 0x0e,
+ /*4970:*/ 0x1d, 0xe6, 0xce, 0xaa, 0xd7, 0xf3, 0x36, 0xed, 0xc9, 0x8c, 0xaf, 0x33, 0x80, 0xe0, 0xf2, 0x80,
+ /*4980:*/ 0x78, 0x4d, 0xa9, 0x69, 0xa7, 0x1c, 0xd6, 0x13, 0x0f, 0xdd, 0xd6, 0x58, 0x05, 0xc8, 0xad, 0x98,
+ /*4990:*/ 0x2e, 0x6f, 0xcd, 0x38, 0x75, 0x85, 0x99, 0xd2, 0xc3, 0x3f, 0x8b, 0xcb, 0x8b, 0xf0, 0xcf, 0x87,
+ /*49a0:*/ 0x84, 0xd5, 0xf7, 0xb9, 0xca, 0x85, 0x3e, 0x5d, 0x0a, 0xbd, 0xd8, 0x4b, 0xfb, 0x5a, 0xdc, 0x84,
+ /*49b0:*/ 0x3e, 0x0f, 0x0e, 0x16, 0x6b, 0x0a, 0x17, 0xac, 0xc6, 0x91, 0x65, 0xd0, 0x7b, 0xaf, 0x41, 0xea,
+ /*49c0:*/ 0xaf, 0xa9, 0x9e, 0x8f, 0xfb, 0x38, 0xee, 0xe9, 0xf8, 0xcd, 0x90, 0xf4, 0xc0, 0x9c, 0xb3, 0x2f,
+ /*49d0:*/ 0x0d, 0x52, 0xdc, 0x83, 0x06, 0xfd, 0xb0, 0xe8, 0x2e, 0x89, 0x1a, 0x1f, 0xb0, 0x86, 0x05, 0x2b,
+ /*49e0:*/ 0x00, 0xac, 0x0a, 0x8e, 0xf7, 0x3b, 0xb0, 0xa3, 0x94, 0x6e, 0x5b, 0xb9, 0x02, 0x34, 0xc5, 0xa1,
+ /*49f0:*/ 0x65, 0xce, 0x03, 0x23, 0x71, 0x3b, 0x96, 0x96, 0x20, 0x29, 0x13, 0x6a, 0x5d, 0x1d, 0xab, 0x44,
+ /*4a00:*/ 0xc2, 0xfc, 0xab, 0x74, 0xf9, 0x90, 0xeb, 0xf7, 0x4a, 0x08, 0x8e, 0x47, 0x9f, 0x16, 0xc0, 0x07,
+ /*4a10:*/ 0x97, 0x36, 0x59, 0x1b, 0xce, 0x87, 0xf4, 0xf9, 0x4c, 0x8b, 0xa9, 0xa0, 0x06, 0x25, 0x4e, 0x0f,
+ /*4a20:*/ 0xc3, 0xb9, 0x67, 0xe1, 0xb1, 0xfd, 0x4c, 0x5e, 0xad, 0x29, 0x28, 0xc5, 0x34, 0x00, 0x11, 0x23,
+ /*4a30:*/ 0xb9, 0x29, 0xb3, 0x5a, 0x5c, 0x31, 0x67, 0x23, 0x84, 0xa6, 0xd9, 0x26, 0x27, 0x11, 0x09, 0x21,
+ /*4a40:*/ 0x43, 0x0b, 0x8b, 0x97, 0xbc, 0x4d, 0x9b, 0x3b, 0x21, 0xf8, 0x8d, 0xa2, 0x1f, 0xbb, 0xca, 0xd7,
+ /*4a50:*/ 0x38, 0xcf, 0xb7, 0x20, 0x7c, 0x95, 0x0d, 0x42, 0xaf, 0xf4, 0x71, 0x6f, 0x3c, 0x47, 0xb1, 0x0d,
+ /*4a60:*/ 0x76, 0x26, 0x14, 0x70, 0xff, 0x2c, 0xd8, 0x06, 0xc0, 0xdd, 0x18, 0xa1, 0x18, 0x83, 0x26, 0x6e,
+ /*4a70:*/ 0x9a, 0x3b, 0x25, 0xf0, 0xfb, 0x7e, 0xab, 0xaf, 0x9a, 0x26, 0x90, 0xd1, 0xb2, 0x29, 0x94, 0x49,
+ /*4a80:*/ 0x45, 0x4b, 0x4b, 0x95, 0xf4, 0xd6, 0xc6, 0x30, 0xc5, 0xf7, 0x21, 0x1b, 0x48, 0x45, 0x50, 0x01,
+ /*4a90:*/ 0xb1, 0xb8, 0x83, 0xe4, 0xfb, 0xbb, 0x5a, 0xc6, 0x63, 0xe2, 0x5e, 0x85, 0x98, 0x3e, 0xdf, 0x67,
+ /*4aa0:*/ 0x75, 0xbd, 0xb6, 0x59, 0x67, 0x47, 0x01, 0xea, 0xe3, 0x2d, 0xcc, 0xde, 0xf8, 0x58, 0x37, 0x99,
+ /*4ab0:*/ 0xb6, 0xbd, 0xec, 0xd5, 0x51, 0x9c, 0x22, 0x4e, 0x96, 0x52, 0x2a, 0x2a, 0x2e, 0x3b, 0x82, 0x98,
+ /*4ac0:*/ 0xd8, 0xae, 0x56, 0x6a, 0x20, 0x7c, 0x4d, 0x86, 0x46, 0x1c, 0x0c, 0x91, 0x4c, 0xe4, 0x23, 0xf2,
+ /*4ad0:*/ 0x0d, 0x06, 0x89, 0x72, 0xd3, 0xd7, 0x24, 0xd9, 0xb8, 0x4e, 0xb2, 0x6a, 0x72, 0x75, 0x74, 0x9a,
+ /*4ae0:*/ 0x94, 0x65, 0x97, 0xac, 0xdf, 0x1d, 0x5c, 0x48, 0x0e, 0xa7, 0x1a, 0x22, 0x69, 0x2e, 0xb3, 0x92,
+ /*4af0:*/ 0x6e, 0x69, 0xdc, 0x65, 0xd1, 0xf0, 0xfa, 0xf5, 0x41, 0x5c, 0x78, 0x54, 0x72, 0x1a, 0x8e, 0xe7,
+ /*4b00:*/ 0xc8, 0x7c, 0xd2, 0x43, 0x6b, 0x78, 0xe9, 0x22, 0xc3, 0x87, 0x28, 0x3c, 0x10, 0x8d, 0x86, 0x9f,
+ /*4b10:*/ 0x93, 0xdf, 0x0c, 0x5c, 0x55, 0x91, 0x4c, 0x7f, 0x3a, 0x80, 0x47, 0x5f, 0x73, 0xba, 0xa1, 0xbb,
+ /*4b20:*/ 0xe2, 0xb5, 0xba, 0xfc, 0x83, 0x0f, 0x70, 0xe5, 0xea, 0x7c, 0x9e, 0xe8, 0x8e, 0x3d, 0x3a, 0xde,
+ /*4b30:*/ 0x5c, 0x60, 0xc7, 0x99, 0x21, 0x3e, 0x2d, 0x35, 0x45, 0xee, 0x11, 0xe6, 0xdd, 0x3f, 0x21, 0xb4,
+ /*4b40:*/ 0xae, 0x9c, 0x69, 0x48, 0x86, 0xec, 0xac, 0x6c, 0x53, 0x98, 0xba, 0x8c, 0xcc, 0xf2, 0x10, 0x39,
+ /*4b50:*/ 0x7b, 0x83, 0x71, 0x8b, 0xda, 0x2f, 0xd3, 0xca, 0x64, 0xd8, 0x56, 0xdc, 0xc2, 0x34, 0x51, 0x64,
+ /*4b60:*/ 0x78, 0x90, 0x57, 0x1d, 0xa7, 0xae, 0x70, 0x77, 0x3d, 0x0d, 0xef, 0x4d, 0x58, 0xae, 0xe1, 0xe4,
+ /*4b70:*/ 0xe6, 0xee, 0xfd, 0x21, 0x12, 0xf7, 0x3b, 0x8d, 0x9f, 0xb2, 0x62, 0xe4, 0x97, 0x6b, 0x46, 0x69,
+ /*4b80:*/ 0xfa, 0x03, 0x9e, 0x30, 0x9b, 0x16, 0xad, 0xe5, 0xe6, 0x06, 0xf6, 0x8e, 0x87, 0x68, 0xa6, 0x48,
+ /*4b90:*/ 0x91, 0xa2, 0x77, 0x54, 0xc4, 0xd8, 0x52, 0x58, 0x59, 0x66, 0x19, 0xc9, 0x88, 0x4e, 0x4e, 0xd7,
+ /*4ba0:*/ 0xd3, 0x8a, 0x3f, 0x33, 0xa2, 0x55, 0xfe, 0x6a, 0x00, 0xc3, 0x40, 0xec, 0x36, 0x5f, 0x61, 0x0a,
+ /*4bb0:*/ 0xbe, 0x37, 0x62, 0x35, 0x75, 0x82, 0x73, 0x20, 0x52, 0x22, 0x01, 0x48, 0x6a, 0x64, 0x99, 0x81,
+ /*4bc0:*/ 0xa2, 0x86, 0xb6, 0x62, 0xe9, 0x23, 0x73, 0xdf, 0x4b, 0xc2, 0xf8, 0x08, 0x7d, 0xe6, 0x0f, 0x5d,
+ /*4bd0:*/ 0x98, 0xbd, 0xb7, 0x7e, 0x60, 0x8d, 0xfd, 0x30, 0x59, 0x38, 0xf8, 0xa2, 0xa3, 0x7e, 0x92, 0x4a,
+ /*4be0:*/ 0xe1, 0x46, 0x20, 0xab, 0xa8, 0x0f, 0x5f, 0x4e, 0x95, 0xa3, 0x23, 0x4b, 0x50, 0x92, 0x39, 0xb3,
+ /*4bf0:*/ 0x45, 0xa3, 0x67, 0xee, 0xbe, 0x0f, 0xea, 0x34, 0xd1, 0x2d, 0x0f, 0x78, 0x31, 0xfc, 0x4b, 0x32,
+ /*4c00:*/ 0xe6, 0x2b, 0x63, 0xab, 0xda, 0xf1, 0xbc, 0x55, 0xc2, 0xfe, 0x9e, 0xae, 0x07, 0x4f, 0x1e, 0x0c,
+ /*4c10:*/ 0x18, 0x78, 0xf5, 0x6a, 0x6c, 0xa4, 0x8b, 0xc3, 0xe3, 0xd1, 0x87, 0x04, 0x8d, 0x9a, 0xb7, 0x87,
+ /*4c20:*/ 0x68, 0x8b, 0x44, 0x6e, 0x2f, 0x0b, 0x07, 0x33, 0x43, 0x87, 0x0f, 0x86, 0x08, 0x7a, 0xd6, 0xb5,
+ /*4c30:*/ 0x3c, 0x5f, 0x81, 0x49, 0x10, 0xa4, 0x07, 0x09, 0xef, 0xc9, 0xb4, 0xbf, 0x95, 0x84, 0x0a, 0x5c,
+ /*4c40:*/ 0xfd, 0x44, 0xfe, 0x7f, 0xf4, 0x5a, 0xb0, 0xb4, 0xb1, 0x42, 0xe8, 0xbf, 0x82, 0xf7, 0xe9, 0x09,
+ /*4c50:*/ 0x97, 0x6c, 0xbf, 0x30, 0x2b, 0x83, 0xd1, 0x40, 0xe8, 0x2b, 0xb8, 0x10, 0x54, 0x12, 0xaa, 0x8f,
+ /*4c60:*/ 0x33, 0x76, 0x1a, 0xc9, 0x70, 0x6e, 0xaa, 0xa7, 0xe9, 0xcd, 0x16, 0x58, 0x2c, 0x18, 0xb0, 0x4f,
+ /*4c70:*/ 0x2c, 0x0c, 0x7d, 0xd2, 0xa4, 0x42, 0x3f, 0xbf, 0x50, 0x14, 0xa3, 0x8f, 0x10, 0x8a, 0xd6, 0xcc,
+ /*4c80:*/ 0x89, 0xf8, 0xdb, 0x77, 0x0f, 0x91, 0xf0, 0x9b, 0xbd, 0x1a, 0xfd, 0xc6, 0x2b, 0x58, 0x26, 0x92,
+ /*4c90:*/ 0x31, 0xf3, 0x6c, 0xdd, 0xd1, 0x39, 0x25, 0xc6, 0xff, 0x7d, 0x97, 0xae, 0x2d, 0xa7, 0x72, 0xa8,
+ /*4ca0:*/ 0x9b, 0x02, 0x3a, 0xad, 0x61, 0x73, 0x82, 0xf2, 0xbb, 0x18, 0x7e, 0xf4, 0x3c, 0x66, 0x8f, 0x6a,
+ /*4cb0:*/ 0xb9, 0xb0, 0xad, 0x7a, 0x25, 0x3a, 0xbe, 0x0c, 0x78, 0xc3, 0x3c, 0x53, 0xd7, 0x3d, 0xf8, 0xb5,
+ /*4cc0:*/ 0xab, 0xd9, 0xe2, 0x59, 0xaf, 0x37, 0x67, 0x31, 0xc2, 0x6d, 0x02, 0xf8, 0x0b, 0x96, 0xd0, 0x50,
+ /*4cd0:*/ 0x8a, 0x35, 0xdf, 0x92, 0x27, 0x44, 0x2c, 0x5d, 0x31, 0x84, 0x3d, 0x12, 0xe6, 0xe3, 0xd1, 0x01,
+ /*4ce0:*/ 0xe8, 0xd3, 0xbb, 0x68, 0x6c, 0x12, 0x74, 0x0a, 0x83, 0x53, 0x29, 0x88, 0xff, 0xec, 0xef, 0x2f,
+ /*4cf0:*/ 0xe2, 0xa8, 0x8e, 0xd0, 0x07, 0xb8, 0x6e, 0xae, 0x80, 0x9c, 0x34, 0x51, 0xcd, 0xdb, 0x59, 0x2c,
+ /*4d00:*/ 0x06, 0x7e, 0x72, 0x9c, 0xa7, 0x7f, 0xeb, 0x2d, 0x4e, 0x1e, 0xfe, 0xa6, 0x89, 0x93, 0x8a, 0x6d,
+ /*4d10:*/ 0x82, 0xec, 0x91, 0x75, 0x2b, 0x13, 0x72, 0x2d, 0x21, 0xa6, 0x3c, 0x99, 0x03, 0xc2, 0x39, 0x33,
+ /*4d20:*/ 0xb1, 0xd9, 0xae, 0x23, 0x04, 0x33, 0xd7, 0x03, 0x19, 0x83, 0x04, 0xdd, 0x1b, 0x7b, 0x19, 0xd0,
+ /*4d30:*/ 0xf7, 0x75, 0x2f, 0x8b, 0xda, 0x8d, 0xad, 0xae, 0xd3, 0x84, 0x0a, 0x14, 0xf7, 0xb6, 0x4a, 0x6f,
+ /*4d40:*/ 0xf6, 0x6c, 0x2b, 0x8c, 0x2a, 0x0d, 0x21, 0xc0, 0x16, 0x2f, 0x76, 0x75, 0xac, 0x58, 0xa4, 0x2d,
+ /*4d50:*/ 0xae, 0xa5, 0x0c, 0xe7, 0xc4, 0x16, 0xb2, 0xc3, 0xf0, 0x56, 0x39, 0xa2, 0xc9, 0xc4, 0x05, 0xd1,
+ /*4d60:*/ 0x6b, 0xe6, 0x25, 0xdb, 0x9b, 0x0f, 0x41, 0x9c, 0x59, 0xe5, 0x81, 0xca, 0x47, 0x78, 0x66, 0xae,
+ /*4d70:*/ 0xb7, 0x5d, 0x90, 0xa2, 0xcc, 0x8a, 0x66, 0x5c, 0x36, 0xd8, 0x22, 0x4d, 0x26, 0x4c, 0x66, 0x4a,
+ /*4d80:*/ 0x08, 0xce, 0x04, 0x8c, 0x3f, 0x02, 0xcc, 0x06, 0x36, 0x41, 0x0b, 0x27, 0x7a, 0x1c, 0x4d, 0x84,
+ /*4d90:*/ 0xbc, 0x32, 0x5e, 0x32, 0x2c, 0x35, 0x24, 0xaa, 0x29, 0x0d, 0xd1, 0xfc, 0x5b, 0x16, 0x5b, 0x63,
+ /*4da0:*/ 0x3b, 0x22, 0x15, 0x80, 0xe7, 0x2b, 0x25, 0x78, 0xc5, 0xae, 0x8a, 0x9f, 0xff, 0xc0, 0xbd, 0x49,
+ /*4db0:*/ 0x56, 0x77, 0x5b, 0xf0, 0xee, 0x4d, 0xc7, 0x60, 0x9d, 0x53, 0x60, 0xd7, 0xd9, 0xa9, 0x22, 0x9d,
+ /*4dc0:*/ 0xa9, 0x1f, 0x58, 0x0e, 0x55, 0x7e, 0xc1, 0x39, 0x38, 0x70, 0x7c, 0x7b, 0x9f, 0xc8, 0x74, 0x91,
+ /*4dd0:*/ 0xbf, 0x5c, 0xd9, 0xba, 0x67, 0x9f, 0xe7, 0xcb, 0xe6, 0xda, 0x6c, 0xb5, 0xe2, 0x15, 0x77, 0x35,
+ /*4de0:*/ 0x43, 0x09, 0x40, 0x0f, 0x2a, 0x2d, 0x58, 0x1a, 0xda, 0xd4, 0x42, 0x34, 0x02, 0x5e, 0x28, 0x5b,
+ /*4df0:*/ 0x93, 0x26, 0x9e, 0xfb, 0x2a, 0x3f, 0xb0, 0x48, 0xc6, 0x22, 0x75, 0x54, 0x72, 0xbc, 0x68, 0x2a,
+ /*4e00:*/ 0xb3, 0x90, 0xe6, 0xaf, 0x37, 0x08, 0x41, 0xad, 0xf9, 0x45, 0x97, 0x4a, 0x10, 0x07, 0x51, 0x3d,
+ /*4e10:*/ 0x19, 0xd9, 0x36, 0xa4, 0x4f, 0x42, 0x92, 0xd3, 0x2e, 0x7e, 0xe1, 0x30, 0xbe, 0x9f, 0x2f, 0x79,
+ /*4e20:*/ 0x34, 0xc8, 0x95, 0xee, 0x28, 0x5e, 0x01, 0x05, 0xc3, 0x00, 0xcb, 0x49, 0x38, 0xcf, 0x52, 0xa4,
+ /*4e30:*/ 0x2b, 0xb2, 0xcd, 0xb8, 0x7c, 0x74, 0xb6, 0xd5, 0x8a, 0xff, 0x61, 0x35, 0x19, 0x5f, 0xea, 0x54,
+ /*4e40:*/ 0x9f, 0xa9, 0xa0, 0x47, 0x2b, 0x98, 0x65, 0x1d, 0x13, 0xe2, 0x2d, 0x86, 0xa4, 0x96, 0xb6, 0x19,
+ /*4e50:*/ 0xc0, 0x72, 0xfd, 0x06, 0x92, 0x7f, 0x1d, 0x98, 0x47, 0x39, 0x66, 0xff, 0xea, 0x00, 0x80, 0x34,
+ /*4e60:*/ 0xd4, 0x73, 0x0e, 0xc5, 0x88, 0x1c, 0x66, 0xf7, 0x0c, 0xb4, 0x67, 0x75, 0xe5, 0x8b, 0x37, 0x03,
+ /*4e70:*/ 0x41, 0x96, 0x6d, 0x62, 0xda, 0xbb, 0x77, 0x2a, 0x93, 0x2b, 0xf6, 0xce, 0x8a, 0x89, 0x25, 0x0a,
+ /*4e80:*/ 0x97, 0x73, 0x99, 0x68, 0x2d, 0xbe, 0x96, 0x31, 0x16, 0xba, 0xfe, 0x05, 0x0e, 0x37, 0x58, 0x3f,
+ /*4e90:*/ 0x2d, 0xce, 0xd1, 0x8e, 0x9d, 0x0a, 0xac, 0x91, 0x06, 0xbd, 0x38, 0x8c, 0x43, 0x43, 0xf8, 0xbd,
+ /*4ea0:*/ 0x43, 0xb7, 0xfc, 0xf1, 0xe0, 0x53, 0x59, 0x67, 0xbb, 0x99, 0x22, 0xd7, 0xb5, 0x9d, 0xed, 0x85,
+ /*4eb0:*/ 0xae, 0xbc, 0xb3, 0xa4, 0x6a, 0xe2, 0x5b, 0x8d, 0x4e, 0x93, 0x31, 0x44, 0xeb, 0x5b, 0x78, 0x1f,
+ /*4ec0:*/ 0x1c, 0x20, 0x20, 0x1d, 0xb6, 0xd2, 0x51, 0x96, 0x0b, 0xcd, 0x09, 0x5c, 0x44, 0x20, 0x0d, 0xc5,
+ /*4ed0:*/ 0x7a, 0x54, 0x0c, 0xef, 0xb9, 0x2e, 0x34, 0x56, 0xa5, 0xbd, 0x06, 0x4f, 0x73, 0x1a, 0x4b, 0x97,
+ /*4ee0:*/ 0x43, 0xcd, 0xf6, 0xe1, 0x35, 0x29, 0x82, 0x0e, 0xcc, 0x62, 0x4f, 0xe9, 0x32, 0x40, 0x78, 0x33,
+ /*4ef0:*/ 0xa2, 0xcb, 0x4d, 0x6a, 0x7f, 0x04, 0x5b, 0x04, 0x45, 0xc4, 0xd2, 0xef, 0x6d, 0x51, 0xff, 0xe3,
+ /*4f00:*/ 0x28, 0xbb, 0x23, 0x1e, 0x21, 0x7f, 0x19, 0x61, 0x7c, 0xb6, 0x6f, 0x8f, 0x2a, 0x10, 0x2b, 0x3e,
+ /*4f10:*/ 0x77, 0x6a, 0x6d, 0xfa, 0x2a, 0x63, 0xa2, 0x09, 0xde, 0x84, 0x67, 0xd2, 0x1b, 0xf2, 0x06, 0x5e,
+ /*4f20:*/ 0xc4, 0x63, 0xce, 0xe0, 0x23, 0x85, 0xb3, 0x30, 0x22, 0x61, 0xd4, 0x99, 0x2b, 0x3a, 0xca, 0xf4,
+ /*4f30:*/ 0x80, 0xba, 0x0a, 0xee, 0xa3, 0x58, 0xfc, 0xcd, 0x3e, 0x66, 0x3e, 0xfe, 0xb5, 0xaa, 0xdf, 0x69,
+ /*4f40:*/ 0x62, 0x8e, 0x7e, 0xda, 0x44, 0x4d, 0xc6, 0x6a, 0x0b, 0x20, 0x52, 0xbb, 0xf3, 0xf3, 0x0c, 0x39,
+ /*4f50:*/ 0x4b, 0xf8, 0x6c, 0x94, 0xce, 0x1f, 0x11, 0x5f, 0x6f, 0xbd, 0x4b, 0xbc, 0xcc, 0x21, 0xf0, 0x0c,
+ /*4f60:*/ 0x8f, 0x64, 0x98, 0x82, 0x99, 0x47, 0xa1, 0x73, 0x46, 0x0d, 0x1b, 0xd4, 0x66, 0x16, 0xd2, 0xed,
+ /*4f70:*/ 0xaf, 0xcd, 0x35, 0x5c, 0x61, 0xe7, 0xdc, 0xd3, 0xac, 0x82, 0xa1, 0xea, 0x90, 0x33, 0x19, 0x8a,
+ /*4f80:*/ 0x68, 0x20, 0x1c, 0xfd, 0xae, 0xfc, 0x6f, 0x8a, 0x69, 0xcd, 0xcc, 0x8e, 0x22, 0x68, 0xef, 0x8a,
+ /*4f90:*/ 0xa9, 0x64, 0x86, 0xcc, 0x2f, 0x46, 0xc6, 0x8d, 0x81, 0x1f, 0x5a, 0xc9, 0x3d, 0xdc, 0x84, 0xf3,
+ /*4fa0:*/ 0x27, 0x81, 0x4d, 0x34, 0xc3, 0x66, 0x2b, 0xbb, 0x13, 0xa4, 0x7d, 0x02, 0x91, 0x43, 0x7d, 0x2c,
+ /*4fb0:*/ 0x5b, 0x7b, 0xd0, 0x82, 0x51, 0xa8, 0x1b, 0x9b, 0xbd, 0xa3, 0x95, 0x5b, 0xca, 0x21, 0x48, 0x34,
+ /*4fc0:*/ 0xaa, 0x00, 0x30, 0x3d, 0xa0, 0x6c, 0x5a, 0xa6, 0x16, 0xa6, 0x92, 0x6b, 0x25, 0xb6, 0x47, 0xbb,
+ /*4fd0:*/ 0xb0, 0x2b, 0xb7, 0x82, 0x1b, 0xa3, 0x4a, 0xc4, 0x72, 0xbe, 0xf7, 0xbf, 0xaf, 0xcf, 0xaf, 0x2b,
+ /*4fe0:*/ 0x0e, 0x9e, 0x88, 0x91, 0xe6, 0xcd, 0x2a, 0x50, 0x73, 0xd8, 0xf7, 0x6e, 0xf6, 0x7d, 0xb4, 0xc9,
+ /*4ff0:*/ 0xb6, 0xb8, 0x03, 0x90, 0xf8, 0xbe, 0x36, 0x95, 0x5c, 0x91, 0x54, 0x24, 0x6f, 0xfd, 0x6c, 0xa5,
+ /*5000:*/ 0x07, 0xfd, 0x75, 0x1e, 0x2e, 0xcb, 0x11, 0x08, 0x84, 0x18, 0xc6, 0xcb, 0xdd, 0x01, 0xf1, 0x5a,
+ /*5010:*/ 0x64, 0xf7, 0x8b, 0x64, 0xa4, 0x6f, 0xe8, 0xad, 0xc2, 0x27, 0x86, 0xeb, 0xca, 0xdd, 0xe1, 0x2e,
+ /*5020:*/ 0x10, 0x34, 0x9c, 0x03, 0x7e, 0x6b, 0x5a, 0x7f, 0x83, 0xe6, 0xd3, 0x60, 0xe7, 0x1e, 0xec, 0xd2,
+ /*5030:*/ 0x63, 0xe6, 0x60, 0xd2, 0xab, 0x12, 0x56, 0x65, 0x3d, 0xfe, 0x9c, 0x36, 0xab, 0x5a, 0x43, 0x57,
+ /*5040:*/ 0xf1, 0x12, 0x31, 0x7c, 0xa8, 0xf4, 0xbc, 0x48, 0x36, 0x0f, 0xa7, 0xc4, 0x47, 0x3c, 0x67, 0xc9,
+ /*5050:*/ 0xbd, 0xa3, 0x46, 0x86, 0x13, 0x0e, 0xc2, 0xdc, 0x43, 0xa3, 0xa6, 0x16, 0xfa, 0xa7, 0xeb, 0xae,
+ /*5060:*/ 0xbb, 0x6d, 0x07, 0x3d, 0xb5, 0x2c, 0xad, 0x2a, 0x7c, 0x78, 0xd1, 0x58, 0x31, 0x5a, 0x1e, 0x5c,
+ /*5070:*/ 0xf9, 0xbf, 0x89, 0xbf, 0x99, 0xc5, 0xd2, 0x6b, 0x0d, 0xf1, 0xbe, 0x27, 0xfc, 0x60, 0x70, 0xb5,
+ /*5080:*/ 0xbd, 0xd4, 0x59, 0x37, 0x9c, 0xd4, 0x94, 0xd9, 0x3e, 0x32, 0x8a, 0xe9, 0xe1, 0x26, 0x25, 0x81,
+ /*5090:*/ 0x47, 0x4a, 0x0e, 0xfc, 0xa0, 0xae, 0xa3, 0x94, 0x2e, 0x1f, 0x56, 0x83, 0xc4, 0xc8, 0x23, 0x99,
+ /*50a0:*/ 0xf1, 0x23, 0xdd, 0xb1, 0xa6, 0x6b, 0xa7, 0x37, 0x39, 0x54, 0xb4, 0xbc, 0x67, 0x65, 0x9d, 0x69,
+ /*50b0:*/ 0x23, 0x28, 0xf2, 0x69, 0xbf, 0xd4, 0xdf, 0x54, 0xd5, 0x05, 0x21, 0xbc, 0xe5, 0xb6, 0xe1, 0xd2,
+ /*50c0:*/ 0xae, 0x2c, 0x87, 0x03, 0x21, 0x77, 0xe0, 0x86, 0xe7, 0x1a, 0x55, 0x8c, 0x0d, 0x14, 0x78, 0xbb,
+ /*50d0:*/ 0xe1, 0xc8, 0xf1, 0xd3, 0xf7, 0x10, 0x58, 0x23, 0xf7, 0x39, 0x38, 0x05, 0xbe, 0x62, 0xb0, 0x14,
+ /*50e0:*/ 0xd1, 0x9f, 0xdd, 0xb9, 0xf8, 0x79, 0x37, 0x1f, 0x8b, 0xf9, 0x54, 0x71, 0xde, 0x08, 0xeb, 0x46,
+ /*50f0:*/ 0xbf, 0xa8, 0x74, 0xd5, 0xc6, 0x92, 0xb7, 0x18, 0xed, 0xae, 0xcd, 0x62, 0x29, 0xf7, 0xb9, 0x74,
+ /*5100:*/ 0x27, 0x91, 0x95, 0x3b, 0x34, 0x64, 0x17, 0xbf, 0x35, 0x52, 0xb0, 0x9e, 0x1a, 0x0e, 0x37, 0x48,
+ /*5110:*/ 0xaa, 0x47, 0x2b, 0xe5, 0xbb, 0x48, 0xc5, 0xe5, 0x58, 0x35, 0xd7, 0x3a, 0x1a, 0x55, 0xf8, 0x30,
+ /*5120:*/ 0xd4, 0xdd, 0x07, 0xd0, 0x31, 0x42, 0xce, 0x57, 0x2e, 0xdd, 0xea, 0x97, 0x7a, 0xbe, 0xa3, 0xc0,
+ /*5130:*/ 0x2a, 0xb2, 0xad, 0xf2, 0x13, 0x54, 0x09, 0x90, 0x0d, 0xe7, 0x58, 0xf2, 0x37, 0x51, 0xd8, 0x1d,
+ /*5140:*/ 0x2e, 0x72, 0x34, 0x51, 0xd6, 0x21, 0x41, 0x3c, 0x5e, 0xab, 0x16, 0xec, 0x1a, 0x23, 0xd4, 0xde,
+ /*5150:*/ 0x40, 0x3f, 0x5c, 0xce, 0xb0, 0x9f, 0x1a, 0x96, 0xf6, 0x78, 0x9d, 0xec, 0xef, 0x73, 0x63, 0x11,
+ /*5160:*/ 0x12, 0x57, 0x71, 0x01, 0x20, 0xa5, 0x63, 0xdc, 0x33, 0x18, 0x1a, 0x67, 0x1c, 0x6a, 0x82, 0xfe,
+ /*5170:*/ 0x41, 0xca, 0x6b, 0x17, 0x62, 0x75, 0xda, 0xff, 0xa0, 0x8e, 0xb3, 0x75, 0xab, 0x13, 0x81, 0x2d,
+ /*5180:*/ 0x4c, 0x35, 0x3a, 0x6b, 0xe2, 0x7d, 0x31, 0x8d, 0xc0, 0x7b, 0xb3, 0x6b, 0xd9, 0xea, 0xaf, 0x52,
+ /*5190:*/ 0x93, 0x35, 0x76, 0x9b, 0xc9, 0xc4, 0x85, 0x08, 0xf7, 0x6c, 0x79, 0xcf, 0x80, 0x8a, 0x03, 0xed,
+ /*51a0:*/ 0xe5, 0xac, 0x2a, 0x22, 0xdb, 0x37, 0x67, 0xa2, 0xcb, 0xa0, 0xd4, 0x34, 0x04, 0x40, 0xc4, 0x09,
+ /*51b0:*/ 0xae, 0xde, 0xea, 0xa4, 0xd0, 0x1f, 0x33, 0x3e, 0x00, 0xa0, 0x10, 0x68, 0x1e, 0xe9, 0x95, 0xa9,
+ /*51c0:*/ 0x91, 0x9d, 0xb1, 0x73, 0xc9, 0xa1, 0x89, 0xce, 0x72, 0x4a, 0x41, 0xc9, 0x35, 0x2c, 0x0f, 0x10,
+ /*51d0:*/ 0xb0, 0xab, 0xe1, 0x72, 0x48, 0x2f, 0x53, 0x3c, 0x3d, 0x6f, 0x9d, 0x09, 0x82, 0x88, 0x14, 0xee,
+ /*51e0:*/ 0x38, 0xa9, 0x72, 0x01, 0xfd, 0xd4, 0x24, 0xba, 0x14, 0xb9, 0x90, 0x4a, 0x0c, 0x9a, 0xe4, 0x47,
+ /*51f0:*/ 0x9f, 0x72, 0xe2, 0x3b, 0x9e, 0x0e, 0x72, 0x43, 0xf4, 0x74, 0xb6, 0x57, 0x53, 0x88, 0x33, 0xef,
+ /*5200:*/ 0xf5, 0x8a, 0xd1, 0x96, 0x0f, 0x47, 0xb3, 0x98, 0x8a, 0xd5, 0x49, 0x2d, 0x0f, 0xf6, 0x99, 0x53,
+ /*5210:*/ 0x68, 0xa9, 0x84, 0x38, 0xe6, 0x88, 0x94, 0x27, 0x7f, 0xfa, 0xd4, 0x13, 0x37, 0x2a, 0xe1, 0xfe,
+ /*5220:*/ 0x8f, 0xe4, 0x56, 0x1b, 0xce, 0xbf, 0x27, 0x8b, 0x62, 0xb3, 0xbb, 0xca, 0xa7, 0x81, 0x8a, 0xb4,
+ /*5230:*/ 0x4a, 0x73, 0xba, 0x09, 0xcf, 0xab, 0xa1, 0xfa, 0x7b, 0xc6, 0xdb, 0xd4, 0x12, 0x15, 0x89, 0x58,
+ /*5240:*/ 0xc0, 0xd1, 0xe5, 0x26, 0x3f, 0x99, 0xe0, 0xa6, 0x0f, 0xb6, 0x81, 0xbf, 0x72, 0x53, 0x3a, 0xda,
+ /*5250:*/ 0x2f, 0x8a, 0xa5, 0x93, 0x6a, 0xc5, 0x89, 0x0c, 0xc6, 0x44, 0xda, 0xed, 0x46, 0x76, 0x7e, 0x9a,
+ /*5260:*/ 0xd5, 0x96, 0x96, 0x7c, 0xa5, 0x90, 0x80, 0xb4, 0x71, 0x01, 0xdb, 0x08, 0xe6, 0x37, 0x2b, 0x5c,
+ /*5270:*/ 0x83, 0xca, 0x24, 0x1e, 0x9b, 0xd6, 0x71, 0xe6, 0xfc, 0xae, 0x0f, 0x24, 0xbc, 0x89, 0x13, 0x4f,
+ /*5280:*/ 0xbc, 0x43, 0x5c, 0x9c, 0x3f, 0x48, 0x94, 0xe0, 0x66, 0xf0, 0x4a, 0x76, 0xa0, 0x08, 0x9a, 0x10,
+ /*5290:*/ 0x09, 0x8b, 0xa6, 0x2c, 0xc5, 0x9d, 0xd6, 0xc5, 0x45, 0xd1, 0x63, 0x43, 0x44, 0x0f, 0xca, 0x5b,
+ /*52a0:*/ 0x66, 0x77, 0xa3, 0x44, 0x90, 0x2c, 0xe4, 0xab, 0x28, 0xcb, 0x06, 0xab, 0x98, 0x64, 0x2b, 0xfb,
+ /*52b0:*/ 0x4a, 0x7b, 0xb5, 0x9b, 0x12, 0xca, 0x30, 0xa7, 0x01, 0x5a, 0x99, 0x53, 0xde, 0x87, 0x24, 0x1a,
+ /*52c0:*/ 0xa6, 0xec, 0x13, 0xd1, 0x0c, 0xf0, 0x90, 0x41, 0x4c, 0x00, 0x91, 0x86, 0xbb, 0x1e, 0xf0, 0xed,
+ /*52d0:*/ 0x81, 0xeb, 0xa7, 0x39, 0x6e, 0xfd, 0x88, 0xf8, 0x31, 0x23, 0x73, 0x6c, 0xd0, 0x21, 0xf4, 0x16,
+ /*52e0:*/ 0xc3, 0x6f, 0xcc, 0xb0, 0x46, 0x78, 0x96, 0x2d, 0x5e, 0xeb, 0x10, 0x68, 0x7b, 0x1e, 0xaa, 0x21,
+ /*52f0:*/ 0x8e, 0x22, 0x75, 0xbf, 0xaf, 0xbc, 0x00, 0xa2, 0x45, 0x65, 0x5b, 0x6b, 0x32, 0x0e, 0xe7, 0x05,
+ /*5300:*/ 0xa2, 0xbc, 0xcc, 0x21, 0x5f, 0x32, 0x68, 0xad, 0x74, 0x7e, 0xdd, 0xe5, 0x80, 0x22, 0x0e, 0x30,
+ /*5310:*/ 0x18, 0xc7, 0x38, 0xd2, 0xec, 0x8d, 0x19, 0xf5, 0xb7, 0xe4, 0x15, 0x8f, 0x44, 0x40, 0x5a, 0xf0,
+ /*5320:*/ 0x03, 0x91, 0xc7, 0x4c, 0x21, 0xa2, 0xe7, 0xe0, 0x41, 0x22, 0x7c, 0xde, 0xb8, 0xf1, 0xe5, 0x8d,
+ /*5330:*/ 0x83, 0x56, 0xd5, 0x46, 0x68, 0x9a, 0x33, 0xb7, 0xba, 0xd2, 0x35, 0x62, 0x54, 0x4e, 0x4a, 0x73,
+ /*5340:*/ 0x3d, 0x52, 0x6d, 0x25, 0x2c, 0x04, 0x03, 0x05, 0x41, 0x01, 0x74, 0xfa, 0xe2, 0x49, 0x48, 0xdc,
+ /*5350:*/ 0xf7, 0x77, 0x03, 0x33, 0x85, 0xda, 0xa3, 0xb8, 0xef, 0xf8, 0x0d, 0x04, 0x55, 0x85, 0x21, 0xdf,
+ /*5360:*/ 0xe8, 0xc4, 0x2d, 0x14, 0xe2, 0xf2, 0x55, 0xc8, 0xbe, 0xf0, 0xfd, 0x1b, 0x4f, 0x7b, 0x2c, 0x40,
+ /*5370:*/ 0x0b, 0x9f, 0x79, 0x98, 0xfa, 0x2d, 0x3a, 0xc5, 0xa2, 0x94, 0xdb, 0xcc, 0x5c, 0x50, 0x0b, 0x24,
+ /*5380:*/ 0x12, 0x2e, 0xe8, 0x91, 0x87, 0xf5, 0x63, 0xcd, 0x08, 0x75, 0xa9, 0x47, 0x22, 0x81, 0xba, 0xa6,
+ /*5390:*/ 0xd2, 0x60, 0xc4, 0x39, 0x28, 0xf8, 0x8f, 0x03, 0xc0, 0x1a, 0xac, 0xb0, 0x98, 0xb9, 0x0e, 0x18,
+ /*53a0:*/ 0x2a, 0xa8, 0x7c, 0xb5, 0xbd, 0xb8, 0x43, 0x20, 0xe2, 0x7e, 0xe5, 0x30, 0x18, 0x76, 0xca, 0xe5,
+ /*53b0:*/ 0xe0, 0xd6, 0x57, 0xa8, 0x6a, 0xdf, 0x35, 0x4c, 0x35, 0xd4, 0xa2, 0x6b, 0x4a, 0x05, 0xf9, 0xa4,
+ /*53c0:*/ 0x9c, 0x35, 0x61, 0xff, 0x0b, 0x77, 0x41, 0x99, 0x65, 0xed, 0x56, 0xa4, 0x6e, 0xfb, 0xd6, 0x08,
+ /*53d0:*/ 0x9e, 0x54, 0x04, 0x1e, 0x02, 0x71, 0xab, 0x2b, 0xed, 0xeb, 0xc4, 0x26, 0x98, 0xfa, 0xc6, 0xd5,
+ /*53e0:*/ 0xc8, 0x19, 0xb3, 0xa0, 0xe7, 0xb9, 0x11, 0x5b, 0xf2, 0x9b, 0x5d, 0xd8, 0x7c, 0x14, 0x98, 0x07,
+ /*53f0:*/ 0x5f, 0xf0, 0xcc, 0xad, 0x8d, 0x70, 0x30, 0xb7, 0x87, 0xea, 0x60, 0x0e, 0xcf, 0x06, 0x3d, 0xa5,
+ /*5400:*/ 0x0d, 0xad, 0x7c, 0x35, 0xe8, 0xc8, 0x7d, 0x72, 0x33, 0xa5, 0x10, 0x14, 0x93, 0xca, 0x95, 0x54,
+ /*5410:*/ 0xda, 0xb7, 0x18, 0xc1, 0xae, 0xc5, 0x98, 0xc6, 0xe2, 0xc5, 0xd5, 0xac, 0x56, 0x55, 0xcc, 0xd1,
+ /*5420:*/ 0x04, 0xbe, 0x6c, 0xb8, 0xc9, 0xa7, 0xac, 0x52, 0x4b, 0x91, 0xf5, 0x0c, 0x77, 0xf8, 0x75, 0x79,
+ /*5430:*/ 0xe2, 0x56, 0xa3, 0xe8, 0xff, 0xf7, 0x22, 0x5a, 0x24, 0x4e, 0x6e, 0xf1, 0xc9, 0xcb, 0xd0, 0xd3,
+ /*5440:*/ 0xfc, 0x16, 0x82, 0xb5, 0x49, 0x47, 0xfe, 0x27, 0x8a, 0xd5, 0xa3, 0xc0, 0x5c, 0x90, 0xf1, 0xfb,
+ /*5450:*/ 0xb2, 0xec, 0x3d, 0xb6, 0x01, 0x6e, 0x14, 0x32, 0xc9, 0xcc, 0xfa, 0xfa, 0xc5, 0x17, 0xff, 0xb3,
+ /*5460:*/ 0x18, 0x6f, 0xd5, 0x04, 0x7a, 0xa7, 0xfc, 0xcf, 0x18, 0x25, 0xe3, 0x69, 0x86, 0x27, 0xeb, 0x16,
+ /*5470:*/ 0x93, 0xf6, 0x6e, 0x3b, 0xc7, 0x73, 0xf8, 0x83, 0xb7, 0xce, 0x82, 0x8d, 0x4a, 0x0a, 0xcb, 0xe3,
+ /*5480:*/ 0x07, 0x55, 0x79, 0x8c, 0x18, 0x39, 0x31, 0xdf, 0xca, 0xcb, 0xfd, 0x41, 0x1b, 0xfb, 0xb6, 0x35,
+ /*5490:*/ 0x09, 0x59, 0xca, 0x90, 0xad, 0x71, 0x46, 0xeb, 0xf6, 0x18, 0xb2, 0xb6, 0x3f, 0xa9, 0x08, 0x03,
+ /*54a0:*/ 0x57, 0x57, 0xf1, 0x0c, 0x73, 0x26, 0x20, 0x33, 0xef, 0x74, 0xa7, 0xe7, 0x6e, 0x25, 0x9a, 0x7e,
+ /*54b0:*/ 0x3a, 0x66, 0xf1, 0x97, 0x07, 0xcc, 0x89, 0xea, 0x4d, 0x3c, 0x92, 0x15, 0xd9, 0xe1, 0x99, 0x89,
+ /*54c0:*/ 0x2c, 0xd4, 0x5a, 0xf3, 0x51, 0x10, 0xa0, 0x54, 0x77, 0x7e, 0x1a, 0x07, 0x02, 0x87, 0x0e, 0xb8,
+ /*54d0:*/ 0x87, 0x11, 0xce, 0xd2, 0xd8, 0x84, 0x30, 0x2a, 0xe7, 0x08, 0x49, 0x8b, 0x7c, 0xcb, 0xaf, 0x43,
+ /*54e0:*/ 0x17, 0x15, 0x17, 0xa1, 0xa0, 0xa2, 0x74, 0x4c, 0xa9, 0xcc, 0xe0, 0x26, 0xd5, 0xc1, 0xc3, 0x4a,
+ /*54f0:*/ 0x69, 0x0c, 0x89, 0x52, 0xcd, 0xae, 0x47, 0xd7, 0x6e, 0x0c, 0xc5, 0x62, 0x6e, 0xaa, 0x0e, 0x08,
+ /*5500:*/ 0x40, 0x32, 0x21, 0x50, 0x6c, 0xd8, 0xb7, 0xd6, 0xc7, 0xd3, 0x3f, 0xae, 0x4f, 0x0d, 0xba, 0xaa,
+ /*5510:*/ 0x37, 0x17, 0xbd, 0x13, 0x0a, 0xcc, 0x12, 0x3d, 0x6b, 0xab, 0x12, 0xc9, 0xf4, 0xa6, 0xe9, 0x64,
+ /*5520:*/ 0x73, 0xa2, 0xd6, 0xe0, 0x1f, 0x8d, 0xd7, 0xab, 0x95, 0x4d, 0x8d, 0x25, 0xca, 0xe8, 0x9f, 0xca,
+ /*5530:*/ 0xf6, 0x54, 0x4a, 0xbf, 0x1d, 0xeb, 0xf6, 0x39, 0x20, 0xaa, 0x2c, 0xc9, 0x3c, 0xa7, 0x0c, 0x4b,
+ /*5540:*/ 0x85, 0x92, 0x23, 0x48, 0xed, 0x7c, 0x55, 0x0a, 0xbb, 0x4f, 0x65, 0xac, 0x6d, 0x23, 0x4c, 0x5e,
+ /*5550:*/ 0xf9, 0x9e, 0xa7, 0x76, 0x4d, 0xdd, 0xfb, 0x52, 0x68, 0x75, 0x1d, 0xab, 0xc9, 0x53, 0xa8, 0xfc,
+ /*5560:*/ 0x39, 0xcf, 0xea, 0x93, 0x90, 0x50, 0x95, 0x3e, 0x91, 0x4a, 0xac, 0xc7, 0x80, 0x02, 0x84, 0x1a,
+ /*5570:*/ 0x6a, 0xf3, 0x61, 0xad, 0xca, 0x78, 0x09, 0x67, 0x8a, 0x41, 0x79, 0xda, 0x5b, 0x8f, 0x79, 0xc2,
+ /*5580:*/ 0xf4, 0x73, 0x26, 0xb8, 0x8c, 0xf8, 0x64, 0x7f, 0xba, 0x25, 0xa7, 0x90, 0xf5, 0x49, 0xd6, 0x5f,
+ /*5590:*/ 0x4c, 0xf4, 0x18, 0x5d, 0xe0, 0x20, 0x61, 0xc5, 0x59, 0x69, 0x89, 0x48, 0x29, 0xbb, 0x98, 0xcd,
+ /*55a0:*/ 0x92, 0x42, 0x80, 0x91, 0xc4, 0x35, 0x24, 0x7d, 0x70, 0x35, 0x23, 0x90, 0xa4, 0x19, 0x2d, 0x8a,
+ /*55b0:*/ 0xf3, 0x7b, 0x89, 0x1b, 0xb9, 0xe2, 0x4e, 0x12, 0xa5, 0x41, 0x7e, 0x4e, 0x84, 0xb7, 0x0d, 0x6b,
+ /*55c0:*/ 0xf2, 0xb6, 0xb8, 0x29, 0x1a, 0x85, 0xa3, 0xc5, 0x00, 0x71, 0xf4, 0xad, 0x4c, 0x62, 0x75, 0xc5,
+ /*55d0:*/ 0xa8, 0xd1, 0xad, 0xcd, 0x4e, 0x62, 0xd5, 0x37, 0xf0, 0xaf, 0x4c, 0xdd, 0x31, 0x83, 0x92, 0x81,
+ /*55e0:*/ 0xb9, 0x11, 0x20, 0xcc, 0x4c, 0x4f, 0xff, 0x3e, 0x5b, 0x68, 0xb9, 0xbf, 0x3b, 0x1b, 0x8f, 0xdf,
+ /*55f0:*/ 0xd7, 0x13, 0x13, 0x49, 0x3f, 0x6e, 0x00, 0x87, 0xae, 0x8d, 0x9d, 0x00, 0x66, 0x29, 0x30, 0x6e,
+ /*5600:*/ 0x65, 0x28, 0x09, 0x87, 0xa4, 0xf7, 0xde, 0xf8, 0x04, 0xba, 0x20, 0x0c, 0xb0, 0x68, 0x13, 0xfb,
+ /*5610:*/ 0x73, 0x66, 0x82, 0x04, 0xea, 0xd6, 0x7b, 0x89, 0x43, 0x52, 0x08, 0x3a, 0x37, 0x17, 0x56, 0xa3,
+ /*5620:*/ 0x63, 0xbd, 0x01, 0x82, 0x9c, 0xeb, 0x44, 0x3c, 0x01, 0xf9, 0x77, 0x64, 0x0a, 0x18, 0xff, 0x50,
+ /*5630:*/ 0xe5, 0x15, 0x69, 0xa3, 0x2d, 0xcc, 0xb0, 0xba, 0xb1, 0xef, 0x78, 0x3c, 0x07, 0x19, 0xfd, 0x7a,
+ /*5640:*/ 0xd6, 0x91, 0x66, 0x35, 0xd1, 0xef, 0x8e, 0xc2, 0xf6, 0xb0, 0xfe, 0x5d, 0x2c, 0x7e, 0x28, 0x77,
+ /*5650:*/ 0x1d, 0xc6, 0x3e, 0x5f, 0x58, 0x11, 0x3f, 0x72, 0xf6, 0x1e, 0x59, 0x88, 0xcf, 0x16, 0x52, 0xc9,
+ /*5660:*/ 0x7f, 0x31, 0xce, 0x87, 0x22, 0x3b, 0x81, 0xab, 0x52, 0xb5, 0x22, 0x67, 0x56, 0xdf, 0xe8, 0xed,
+ /*5670:*/ 0x72, 0xe5, 0xff, 0xcf, 0xa7, 0xf1, 0xa3, 0xb7, 0x97, 0x8e, 0x9c, 0x56, 0x5b, 0x0c, 0x0c, 0x5a,
+ /*5680:*/ 0x2e, 0x08, 0xa1, 0xee, 0xcb, 0xd2, 0xc9, 0x26, 0xa8, 0x38, 0xd4, 0x94, 0x8e, 0x47, 0xb0, 0x69,
+ /*5690:*/ 0x0d, 0x5e, 0xbb, 0xc0, 0x53, 0x8a, 0xc8, 0x98, 0x7a, 0x9f, 0xa6, 0x5c, 0x8a, 0x6f, 0x87, 0xbf,
+ /*56a0:*/ 0xd2, 0xae, 0x7e, 0x57, 0xd5, 0xc5, 0xf3, 0x7b, 0xcb, 0x04, 0x27, 0xd3, 0x95, 0x43, 0x28, 0x8d,
+ /*56b0:*/ 0x6f, 0xe5, 0xa4, 0xaa, 0x88, 0x52, 0xea, 0x6a, 0xa7, 0xbf, 0x18, 0x15, 0xd5, 0x0d, 0x57, 0xf1,
+ /*56c0:*/ 0xe2, 0x8e, 0xfc, 0x86, 0x19, 0xf1, 0xce, 0xee, 0xab, 0x7e, 0x56, 0xfb, 0xac, 0xe8, 0x20, 0xfb,
+ /*56d0:*/ 0x77, 0x43, 0x09, 0xf5, 0xca, 0xf6, 0xd1, 0x80, 0x3d, 0xed, 0xd1, 0x8c, 0x67, 0xc1, 0x6d, 0x99,
+ /*56e0:*/ 0x76, 0xb3, 0xcd, 0xc0, 0x22, 0xd2, 0xe3, 0xff, 0xe6, 0x00, 0xff, 0xe2, 0x48, 0xdc, 0x73, 0xc5,
+ /*56f0:*/ 0x10, 0x1d, 0x32, 0x90, 0x42, 0xfd, 0xe5, 0x2c, 0x94, 0x1a, 0x9d, 0x7f, 0x11, 0x1e, 0x7a, 0xf6,
+ /*5700:*/ 0xba, 0x50, 0x22, 0x08, 0xc5, 0x38, 0xb8, 0x15, 0xb7, 0x80, 0x50, 0x45, 0x1d, 0xe8, 0x4d, 0x9f,
+ /*5710:*/ 0xd5, 0xbc, 0x45, 0xd6, 0x83, 0x3d, 0x59, 0xf3, 0x1e, 0x33, 0x60, 0x83, 0x91, 0xb8, 0x0e, 0xb9,
+ /*5720:*/ 0x16, 0x6c, 0x57, 0xaf, 0x4d, 0x91, 0x84, 0x0c, 0xe4, 0x0f, 0x25, 0xdc, 0xed, 0x09, 0x73, 0xc9,
+ /*5730:*/ 0xcf, 0x6f, 0x96, 0x37, 0x9f, 0xf0, 0xd8, 0xee, 0xbb, 0x55, 0x9d, 0xf1, 0xa8, 0xfd, 0xbd, 0x93,
+ /*5740:*/ 0xb6, 0xc5, 0x43, 0xf3, 0xa6, 0x0f, 0x9d, 0x33, 0x04, 0x6b, 0x3f, 0xd1, 0x73, 0xd4, 0xaf, 0xe4,
+ /*5750:*/ 0x23, 0xf8, 0xc5, 0xa1, 0xbb, 0x86, 0x42, 0x7e, 0x14, 0x15, 0x32, 0xe0, 0xe9, 0x9c, 0x8e, 0xa1,
+ /*5760:*/ 0x4c, 0xee, 0x6c, 0x0f, 0xb3, 0xd2, 0x1c, 0xc9, 0x52, 0x14, 0x06, 0x06, 0xb5, 0x38, 0x77, 0x5f,
+ /*5770:*/ 0x4e, 0xa0, 0x32, 0xe6, 0x4d, 0x51, 0x67, 0x44, 0x8f, 0xb2, 0x6e, 0x57, 0x63, 0xb1, 0x19, 0x20,
+ /*5780:*/ 0xd3, 0x04, 0x3c, 0xf3, 0x37, 0xc5, 0x86, 0x44, 0xec, 0xf0, 0x20, 0xe1, 0x52, 0xeb, 0xe7, 0xeb,
+ /*5790:*/ 0x17, 0x87, 0xa1, 0x6e, 0xa9, 0xe5, 0xae, 0x75, 0x3d, 0x3c, 0x44, 0x6d, 0x20, 0x76, 0xc5, 0x84,
+ /*57a0:*/ 0x7e, 0x45, 0xf4, 0x57, 0x85, 0x5c, 0x41, 0x4b, 0x45, 0xf5, 0x8f, 0x89, 0xab, 0x01, 0xce, 0x9a,
+ /*57b0:*/ 0xe2, 0x47, 0xcb, 0xe6, 0x14, 0x14, 0x0e, 0x23, 0xb8, 0xa1, 0x15, 0x4b, 0x67, 0xfe, 0xf5, 0x38,
+ /*57c0:*/ 0x48, 0x9b, 0x48, 0x3e, 0x60, 0xd2, 0x9e, 0x86, 0x60, 0xa1, 0xf1, 0x31, 0x8c, 0x95, 0x93, 0xfc,
+ /*57d0:*/ 0xd4, 0x26, 0xb9, 0xd5, 0x36, 0xac, 0x57, 0x03, 0x86, 0xac, 0xcb, 0xb7, 0x75, 0x66, 0xda, 0x48,
+ /*57e0:*/ 0x74, 0x17, 0x12, 0x22, 0xd1, 0xf0, 0x9f, 0xed, 0x50, 0xcf, 0xea, 0xc5, 0xce, 0x94, 0x68, 0x81,
+ /*57f0:*/ 0x2a, 0x0e, 0xf3, 0x48, 0xe3, 0x03, 0xf0, 0xe4, 0x4e, 0x95, 0xfa, 0xc0, 0xda, 0x35, 0x41, 0x23,
+ /*5800:*/ 0x0d, 0x8b, 0xcc, 0xff, 0x25, 0xe5, 0x18, 0x88, 0x25, 0x20, 0x0c, 0xa5, 0x32, 0xae, 0xfe, 0x89,
+ /*5810:*/ 0xaa, 0xc6, 0xa3, 0x47, 0x0e, 0xc8, 0x8a, 0x83, 0xd9, 0x2a, 0x97, 0x85, 0xbf, 0xe5, 0x9f, 0xe6,
+ /*5820:*/ 0x0e, 0x79, 0x21, 0x25, 0xc2, 0x99, 0x81, 0x28, 0x70, 0x32, 0x23, 0xa3, 0x4d, 0x8a, 0x2d, 0x97,
+ /*5830:*/ 0xbb, 0x7d, 0xa7, 0x9a, 0xee, 0xb6, 0xed, 0xda, 0x09, 0x5f, 0x9f, 0xfc, 0x1a, 0x27, 0xd0, 0x94,
+ /*5840:*/ 0xb7, 0x83, 0x29, 0x59, 0x46, 0x63, 0x01, 0xc9, 0x10, 0xbe, 0x37, 0xf8, 0xac, 0x4f, 0x84, 0x10,
+ /*5850:*/ 0x8a, 0x8e, 0x08, 0x99, 0x13, 0x29, 0x0e, 0x8b, 0xd3, 0xd4, 0x89, 0x8e, 0xd6, 0xe7, 0x1c, 0x47,
+ /*5860:*/ 0xbb, 0x24, 0x6f, 0x25, 0x74, 0x9c, 0x08, 0x85, 0x49, 0x5b, 0x15, 0x25, 0xc2, 0x09, 0xb4, 0x33,
+ /*5870:*/ 0xe3, 0xc3, 0xe9, 0xa9, 0xa2, 0xa4, 0x38, 0x7f, 0x81, 0xa1, 0x16, 0xcb, 0x28, 0x42, 0xf2, 0x9f,
+ /*5880:*/ 0x37, 0x48, 0x73, 0xa2, 0xcf, 0x40, 0x4b, 0xea, 0x8f, 0x86, 0xf0, 0x74, 0x54, 0xe9, 0xc8, 0xa2,
+ /*5890:*/ 0x62, 0x9a, 0x6b, 0x5a, 0x82, 0x02, 0xf3, 0x63, 0x67, 0xdd, 0xb7, 0x81, 0xe6, 0xa9, 0x98, 0x44,
+ /*58a0:*/ 0xb6, 0xb1, 0x63, 0xb7, 0x18, 0xb9, 0x54, 0x10, 0xac, 0x44, 0x97, 0x03, 0x92, 0x11, 0xfe, 0x84,
+ /*58b0:*/ 0xeb, 0x60, 0x6f, 0x15, 0xf5, 0x61, 0x87, 0x3e, 0x5b, 0x27, 0x87, 0x3b, 0xaf, 0x6b, 0xa9, 0x65,
+ /*58c0:*/ 0x42, 0x27, 0xe5, 0x0d, 0xba, 0x83, 0xe1, 0xf2, 0x7c, 0xda, 0x1b, 0x1e, 0x7b, 0x12, 0xc5, 0x36,
+ /*58d0:*/ 0x6a, 0x4b, 0x10, 0x65, 0xa3, 0xfd, 0xd6, 0xf9, 0x5b, 0xf7, 0xd6, 0x93, 0xa4, 0x01, 0x64, 0xf0,
+ /*58e0:*/ 0x10, 0x10, 0x9b, 0x94, 0xa7, 0x16, 0x1c, 0x34, 0xc0, 0x3d, 0x33, 0xba, 0x46, 0x41, 0x5e, 0x3c,
+ /*58f0:*/ 0xdf, 0xaf, 0xab, 0x39, 0x94, 0x36, 0xe0, 0x7c, 0x83, 0x80, 0x92, 0xa9, 0x3b, 0xb1, 0x4e, 0x1d,
+ /*5900:*/ 0xff, 0x97, 0x02, 0x0d, 0x7b, 0x57, 0x23, 0x1f, 0x85, 0x41, 0xc9, 0xdd, 0x83, 0x7b, 0x01, 0x97,
+ /*5910:*/ 0xe0, 0x28, 0x15, 0x91, 0x49, 0x5c, 0x7f, 0xaf, 0xf1, 0x40, 0xac, 0x45, 0xf7, 0xf3, 0x26, 0x37,
+ /*5920:*/ 0xc5, 0xd6, 0xa6, 0xc5, 0xe1, 0x70, 0xd1, 0xca, 0x0a, 0x33, 0x54, 0x33, 0xe6, 0x7f, 0xf2, 0xb0,
+ /*5930:*/ 0xd5, 0x09, 0xb8, 0xe0, 0x7f, 0x54, 0x81, 0x7f, 0xd3, 0x14, 0x1a, 0xbf, 0xeb, 0x1b, 0xd5, 0xa7,
+ /*5940:*/ 0x81, 0x5c, 0xa4, 0x0a, 0xc7, 0x05, 0x33, 0xce, 0x97, 0xf4, 0xd8, 0x74, 0xac, 0xe1, 0x90, 0x3f,
+ /*5950:*/ 0xc3, 0x8d, 0x5e, 0xe2, 0x43, 0xda, 0x55, 0xbe, 0x3b, 0x12, 0x9a, 0xfc, 0xb8, 0x7f, 0x9e, 0xd1,
+ /*5960:*/ 0x36, 0x6e, 0x2b, 0x89, 0xe3, 0x49, 0x9b, 0x5c, 0xa8, 0xe6, 0xc4, 0xb6, 0x9d, 0xea, 0xe4, 0x71,
+ /*5970:*/ 0x19, 0x15, 0x7e, 0x4a, 0x28, 0xa9, 0x11, 0x31, 0xc7, 0xb2, 0xf7, 0x16, 0x38, 0xb5, 0x99, 0x92,
+ /*5980:*/ 0xfe, 0x9a, 0xa1, 0x08, 0xfd, 0xbc, 0xea, 0x14, 0x43, 0xa8, 0xc3, 0xc7, 0xdb, 0xae, 0x7f, 0xc4,
+ /*5990:*/ 0x26, 0x1d, 0x75, 0x6b, 0xbd, 0x9e, 0x46, 0x07, 0x2c, 0x3c, 0x96, 0xef, 0x54, 0xfa, 0xb7, 0x64,
+ /*59a0:*/ 0x3a, 0x36, 0xf6, 0xcf, 0x0e, 0xe4, 0xd8, 0x45, 0x3a, 0x11, 0x68, 0x05, 0xed, 0xf0, 0xf7, 0xe8,
+ /*59b0:*/ 0x39, 0x57, 0xa8, 0x9c, 0x37, 0xc9, 0x04, 0x3d, 0xf8, 0x15, 0xf6, 0xcf, 0x8a, 0x11, 0x84, 0xcd,
+ /*59c0:*/ 0x5f, 0xe7, 0xb9, 0x23, 0xbb, 0xab, 0xe2, 0xc5, 0x82, 0xef, 0xd4, 0x08, 0x42, 0x15, 0xcd, 0x55,
+ /*59d0:*/ 0xfa, 0x6c, 0x50, 0x4e, 0x53, 0xfc, 0x47, 0x9d, 0x7d, 0xdc, 0x5b, 0xda, 0x05, 0x64, 0xfa, 0xcf,
+ /*59e0:*/ 0x41, 0x88, 0xd1, 0xbd, 0x3f, 0x15, 0xcd, 0xba, 0xb1, 0x67, 0xf6, 0x7a, 0x82, 0x76, 0x1a, 0x64,
+ /*59f0:*/ 0xf7, 0x75, 0xfa, 0x71, 0xdf, 0x9a, 0xf9, 0x05, 0xb2, 0x30, 0x5a, 0x74, 0x53, 0x3d, 0xd8, 0x97,
+ /*5a00:*/ 0x7c, 0xdf, 0xd8, 0xda, 0x91, 0xa2, 0x0f, 0xed, 0x0b, 0x08, 0x95, 0x4c, 0x90, 0x13, 0x24, 0xd3,
+ /*5a10:*/ 0xb0, 0x63, 0xae, 0x46, 0x86, 0x56, 0x4c, 0x1a, 0x36, 0x41, 0x34, 0x2f, 0x30, 0x9e, 0xf0, 0x91,
+ /*5a20:*/ 0x9b, 0x51, 0x02, 0x8a, 0x70, 0x71, 0xfd, 0xf8, 0x19, 0xc2, 0xb3, 0xaf, 0x5e, 0x65, 0xd2, 0xca,
+ /*5a30:*/ 0xcc, 0x80, 0x2f, 0xcc, 0xd4, 0xe9, 0xce, 0xa0, 0x6d, 0x38, 0x5e, 0x00, 0x02, 0x2d, 0xcc, 0x4e,
+ /*5a40:*/ 0x05, 0xe5, 0x4f, 0xeb, 0x7d, 0x94, 0x74, 0x6e, 0xaa, 0xa5, 0xc0, 0xce, 0xaa, 0xd6, 0xed, 0xcf,
+ /*5a50:*/ 0x84, 0xdd, 0x44, 0xa6, 0xc8, 0x01, 0x2f, 0x30, 0xd0, 0x1a, 0xa1, 0x14, 0x83, 0x82, 0xe2, 0x6a,
+ /*5a60:*/ 0x6e, 0x0a, 0x42, 0xf6, 0x14, 0xbc, 0xd8, 0xa4, 0x44, 0x67, 0x29, 0x92, 0xaf, 0x0b, 0x8b, 0x6a,
+ /*5a70:*/ 0xa5, 0x45, 0x7f, 0xd3, 0x46, 0xc9, 0xec, 0x29, 0xa9, 0x3d, 0xa3, 0xd2, 0x56, 0x5f, 0xd8, 0x37,
+ /*5a80:*/ 0x2d, 0xf0, 0x07, 0x91, 0xe2, 0xc9, 0x78, 0xbe, 0x4c, 0x00, 0x5a, 0xda, 0x89, 0xc7, 0x96, 0xd6,
+ /*5a90:*/ 0x67, 0x1a, 0x33, 0x98, 0x9c, 0x0a, 0x96, 0x82, 0x44, 0x07, 0x9d, 0x08, 0x39, 0x83, 0x5d, 0xae,
+ /*5aa0:*/ 0x03, 0xa7, 0x36, 0xc6, 0xb1, 0x15, 0xd2, 0x80, 0x97, 0xbb, 0x6e, 0x93, 0x22, 0x99, 0xc1, 0x12,
+ /*5ab0:*/ 0xd9, 0x63, 0xa4, 0xa6, 0xc0, 0x99, 0x53, 0xeb, 0x9b, 0x38, 0x72, 0xe0, 0x3f, 0x2d, 0xb3, 0xd1,
+ /*5ac0:*/ 0x15, 0xef, 0x6f, 0xfe, 0x36, 0x11, 0xfb, 0x7a, 0xa9, 0x53, 0x44, 0x76, 0xeb, 0xfa, 0x29, 0x75,
+ /*5ad0:*/ 0xc0, 0xd9, 0xbf, 0x98, 0x44, 0xcb, 0x57, 0x0f, 0xa6, 0x1e, 0xab, 0xff, 0xa2, 0x1d, 0x0c, 0x70,
+ /*5ae0:*/ 0x2c, 0x67, 0x03, 0x82, 0x3f, 0x0e, 0x3f, 0x0b, 0xad, 0xa4, 0x42, 0x72, 0xf7, 0xbf, 0x6d, 0x6e,
+ /*5af0:*/ 0xf5, 0x58, 0x82, 0xdd, 0xbd, 0xd2, 0xc8, 0x1a, 0xa0, 0xf9, 0xb7, 0x27, 0x14, 0x7b, 0xe2, 0x42,
+ /*5b00:*/ 0xa1, 0xe2, 0xcd, 0x52, 0x65, 0xee, 0x08, 0x02, 0x2c, 0x8f, 0x8d, 0x2f, 0x6c, 0x5f, 0xa2, 0x1c,
+ /*5b10:*/ 0xde, 0x77, 0xa7, 0xc7, 0x4d, 0xa3, 0x87, 0x92, 0x9c, 0xb1, 0xf3, 0xcc, 0x5a, 0x8e, 0x9a, 0x98,
+ /*5b20:*/ 0xb9, 0x7e, 0xee, 0x20, 0x57, 0x1a, 0x27, 0x80, 0xda, 0x66, 0x34, 0xb7, 0xa6, 0xea, 0x15, 0xcd,
+ /*5b30:*/ 0x8f, 0x47, 0x05, 0xb6, 0x86, 0xd7, 0xb9, 0x21, 0x27, 0x9c, 0x47, 0x0e, 0x4b, 0x80, 0x10, 0x8d,
+ /*5b40:*/ 0x06, 0x02, 0xe8, 0x42, 0x34, 0x08, 0x67, 0x1e, 0x77, 0xd4, 0xdc, 0x61, 0xd7, 0xe5, 0xad, 0xb9,
+ /*5b50:*/ 0x3d, 0xf9, 0x16, 0xdf, 0x5f, 0x12, 0xd9, 0x7d, 0xaa, 0xce, 0x5d, 0x5c, 0x4f, 0xe4, 0x5d, 0x28,
+ /*5b60:*/ 0xd0, 0x3f, 0xea, 0xb8, 0xcc, 0xc9, 0xbe, 0x07, 0xe3, 0x27, 0x97, 0x35, 0x70, 0xb3, 0xac, 0xd4,
+ /*5b70:*/ 0x7a, 0xc7, 0xff, 0xc4, 0x44, 0xf8, 0x36, 0xd7, 0xb8, 0x5c, 0x7b, 0xcc, 0xd5, 0xac, 0xef, 0x16,
+ /*5b80:*/ 0xd4, 0x3e, 0x1c, 0xf7, 0x47, 0xa1, 0xf9, 0xeb, 0xb4, 0xd2, 0x7d, 0x0a, 0x03, 0x61, 0xb4, 0xe4,
+ /*5b90:*/ 0x2c, 0x3c, 0x05, 0xe6, 0x87, 0xc2, 0x07, 0xd7, 0xce, 0xc9, 0xb6, 0x98, 0xa7, 0xc8, 0x18, 0x9f,
+ /*5ba0:*/ 0x12, 0x4b, 0x50, 0x52, 0xfc, 0xc7, 0xd1, 0x70, 0xff, 0x06, 0xe8, 0x5b, 0xbf, 0xce, 0xf4, 0xc1,
+ /*5bb0:*/ 0xa0, 0xbd, 0x97, 0x8d, 0x8c, 0x3a, 0xe3, 0xf6, 0x87, 0x3b, 0x37, 0xdd, 0xb0, 0x53, 0x08, 0x25,
+ /*5bc0:*/ 0xbb, 0x18, 0x46, 0xf5, 0x0b, 0x39, 0x3f, 0xe7, 0x62, 0x7e, 0x29, 0x87, 0x70, 0xca, 0xa8, 0x35,
+ /*5bd0:*/ 0xfc, 0x36, 0xbf, 0x69, 0x24, 0xe0, 0x11, 0x7e, 0x9c, 0x09, 0x97, 0xdb, 0x83, 0x22, 0x3a, 0xa5,
+ /*5be0:*/ 0x5e, 0x05, 0xe7, 0x31, 0xaa, 0x44, 0x4c, 0x9b, 0xd5, 0xcc, 0x7e, 0x78, 0x86, 0xa6, 0x4b, 0x59,
+ /*5bf0:*/ 0x12, 0xa4, 0x98, 0xab, 0x18, 0xf6, 0x34, 0x4d, 0xc8, 0xa5, 0xdc, 0xa1, 0x96, 0x30, 0x8c, 0xed,
+ /*5c00:*/ 0xe6, 0x68, 0x6f, 0x90, 0xa4, 0xd3, 0x25, 0x5a, 0x35, 0x89, 0x94, 0x66, 0x0e, 0x7c, 0x91, 0x84,
+ /*5c10:*/ 0x89, 0x3a, 0xb6, 0x7e, 0x34, 0x0f, 0x05, 0x6a, 0x82, 0x9a, 0xbc, 0x13, 0x01, 0xed, 0x43, 0xde,
+ /*5c20:*/ 0xdb, 0x16, 0xf3, 0x5b, 0xa9, 0xad, 0xca, 0x66, 0xb9, 0x73, 0x61, 0xd8, 0xb2, 0x9c, 0x61, 0xfe,
+ /*5c30:*/ 0xe7, 0x2f, 0xad, 0xec, 0x9d, 0x96, 0xe3, 0xd9, 0x35, 0xb2, 0xf9, 0x3a, 0xf8, 0xf7, 0x6f, 0x9d,
+ /*5c40:*/ 0x2a, 0xcf, 0x0e, 0x72, 0x15, 0x9d, 0xe2, 0x74, 0x35, 0x82, 0x26, 0x48, 0x68, 0x66, 0x2c, 0x33,
+ /*5c50:*/ 0x82, 0x46, 0x33, 0x66, 0xa3, 0xf3, 0xbb, 0x01, 0xfe, 0xf5, 0x1b, 0x49, 0xd2, 0xdf, 0x42, 0xb3,
+ /*5c60:*/ 0x59, 0x5b, 0x7f, 0xee, 0xbe, 0x16, 0xf0, 0x17, 0x50, 0xf8, 0xc0, 0xfb, 0x99, 0xd6, 0x7f, 0x9c,
+ /*5c70:*/ 0x6c, 0x92, 0x83, 0x53, 0x32, 0x0e, 0x87, 0x26, 0x32, 0xd7, 0x5e, 0x9b, 0x2c, 0x93, 0x01, 0xa4,
+ /*5c80:*/ 0x83, 0x2d, 0x78, 0x58, 0x8c, 0x34, 0x8a, 0xdd, 0x94, 0xec, 0xe3, 0x61, 0x05, 0x57, 0xaa, 0xcf,
+ /*5c90:*/ 0x63, 0x63, 0x98, 0x3e, 0xc3, 0x6c, 0xce, 0x7d, 0x40, 0xbe, 0x23, 0x07, 0x13, 0x61, 0x21, 0x96,
+ /*5ca0:*/ 0x0f, 0x78, 0x5d, 0x6e, 0x84, 0x24, 0x01, 0x16, 0x5b, 0x52, 0x41, 0x64, 0x35, 0xe6, 0xb5, 0x8f,
+ /*5cb0:*/ 0xeb, 0xfa, 0x3b, 0xc1, 0x04, 0xaf, 0x39, 0x21, 0x13, 0xc8, 0x63, 0x6b, 0xab, 0xb6, 0x42, 0x5f,
+ /*5cc0:*/ 0xb5, 0x54, 0x76, 0x62, 0x47, 0xed, 0x55, 0x62, 0x81, 0x3e, 0xea, 0xdb, 0xf3, 0xcd, 0x81, 0x6c,
+ /*5cd0:*/ 0xa5, 0x7b, 0xaf, 0x77, 0x22, 0xe8, 0x13, 0x66, 0xf2, 0x50, 0xc1, 0xc9, 0xb0, 0xae, 0x99, 0x08,
+ /*5ce0:*/ 0xea, 0x4c, 0x17, 0xbe, 0x80, 0xb4, 0x66, 0x41, 0x27, 0xdb, 0x7f, 0xc8, 0xe1, 0x79, 0xc7, 0x48,
+ /*5cf0:*/ 0xc9, 0xc4, 0x69, 0x8d, 0x5d, 0x50, 0x6e, 0x82, 0xdc, 0x96, 0xa2, 0x2b, 0x2d, 0xc0, 0xf7, 0x0b,
+ /*5d00:*/ 0x00, 0xe9, 0xab, 0x36, 0xe4, 0xe3, 0xb8, 0xd6, 0xa7, 0xe8, 0x8c, 0xe5, 0x84, 0x72, 0xa6, 0xfa,
+ /*5d10:*/ 0xf5, 0xbf, 0xd6, 0xec, 0xe9, 0x65, 0x6f, 0x7b, 0xcc, 0x6c, 0x43, 0x77, 0x04, 0x63, 0x84, 0x25,
+ /*5d20:*/ 0x27, 0xc7, 0x58, 0xe4, 0xa9, 0x34, 0x68, 0x57, 0xeb, 0xe4, 0x5f, 0x24, 0x5e, 0xeb, 0x9b, 0x3c,
+ /*5d30:*/ 0x69, 0x4b, 0xa1, 0xfc, 0x33, 0xbf, 0x4a, 0xd9, 0x24, 0x77, 0x2c, 0x07, 0xd5, 0x32, 0xe6, 0x31,
+ /*5d40:*/ 0xf3, 0xa8, 0xc9, 0x36, 0xf0, 0x9a, 0x89, 0xa7, 0xce, 0x85, 0x98, 0x08, 0x8a, 0x95, 0x20, 0x0d,
+ /*5d50:*/ 0x94, 0xf3, 0xb0, 0x1b, 0x15, 0x27, 0xde, 0xa9, 0xb1, 0xfc, 0x89, 0xdc, 0x61, 0x25, 0x8b, 0xd4,
+ /*5d60:*/ 0x6a, 0xff, 0x02, 0x30, 0xf8, 0xff, 0x60, 0x0b, 0x43, 0x2a, 0x46, 0x27, 0x2b, 0xad, 0x91, 0x93,
+ /*5d70:*/ 0x19, 0x7d, 0x56, 0x0b, 0x47, 0xd0, 0x52, 0xa1, 0x34, 0x6b, 0xbd, 0xb1, 0x3d, 0x66, 0x51, 0x25,
+ /*5d80:*/ 0x00, 0xf9, 0xa0, 0x3e, 0x7f, 0xd5, 0xc3, 0xb4, 0x32, 0x63, 0x30, 0x6b, 0x41, 0xe6, 0x53, 0x7c,
+ /*5d90:*/ 0x02, 0xd9, 0xa2, 0xa9, 0xb4, 0x97, 0xc2, 0x4c, 0x2f, 0x68, 0xd0, 0x8e, 0x72, 0x0f, 0xac, 0x57,
+ /*5da0:*/ 0x1d, 0xf2, 0x6f, 0xe6, 0x6f, 0x5b, 0x4a, 0x7e, 0xf6, 0x77, 0x77, 0x0a, 0xac, 0x58, 0x32, 0x39,
+ /*5db0:*/ 0x61, 0xef, 0x09, 0x44, 0x85, 0x3f, 0x25, 0x99, 0x86, 0x97, 0x0a, 0x20, 0x28, 0x1d, 0xb9, 0x82,
+ /*5dc0:*/ 0x2b, 0x99, 0x4a, 0x6e, 0x54, 0x3b, 0xe8, 0x12, 0xde, 0xfb, 0xc7, 0x97, 0xa5, 0x23, 0x79, 0xed,
+ /*5dd0:*/ 0x4d, 0x8f, 0xca, 0x7f, 0xb6, 0x25, 0x08, 0x97, 0x50, 0xda, 0x73, 0xe0, 0x8f, 0xa8, 0xc5, 0xce,
+ /*5de0:*/ 0xa2, 0xb8, 0x2f, 0x5f, 0x10, 0xce, 0xb0, 0xd6, 0x90, 0x2a, 0x84, 0x90, 0x9e, 0xaf, 0x7c, 0x5c,
+ /*5df0:*/ 0xfb, 0x69, 0xe9, 0x33, 0x50, 0x43, 0xf5, 0x37, 0x75, 0x82, 0x30, 0xd0, 0x83, 0x7f, 0x6b, 0xe5,
+ /*5e00:*/ 0x93, 0x03, 0xce, 0xca, 0x41, 0x5c, 0x91, 0x31, 0x15, 0x00, 0x5c, 0x88, 0xa4, 0xcd, 0xd1, 0xb1,
+ /*5e10:*/ 0x11, 0x12, 0x35, 0x1c, 0xbf, 0xb7, 0xf5, 0x76, 0xf6, 0x78, 0xe4, 0x31, 0x03, 0xce, 0xbe, 0x43,
+ /*5e20:*/ 0xae, 0xc0, 0x32, 0x28, 0xc1, 0xf1, 0x67, 0x2b, 0x00, 0x99, 0xc5, 0xb5, 0x54, 0xe2, 0x67, 0x3b,
+ /*5e30:*/ 0xf0, 0x2f, 0x7f, 0x71, 0xf1, 0x56, 0xe0, 0x2c, 0x4c, 0x38, 0x88, 0x12, 0x28, 0x1c, 0x4c, 0x98,
+ /*5e40:*/ 0xa6, 0xf7, 0x2e, 0xbc, 0x68, 0x16, 0xf4, 0x79, 0x65, 0x91, 0x6c, 0x5e, 0xe2, 0x3e, 0x10, 0x9e,
+ /*5e50:*/ 0x88, 0xab, 0xb3, 0x14, 0x0e, 0x25, 0x6e, 0xd3, 0x0c, 0x63, 0x1c, 0xa5, 0x18, 0xc5, 0x9c, 0x8b,
+ /*5e60:*/ 0x12, 0x9e, 0x2c, 0xbe, 0x37, 0x59, 0x2c, 0x4c, 0xfb, 0x2b, 0xec, 0x4a, 0x5b, 0x6b, 0x69, 0xf0,
+ /*5e70:*/ 0xcc, 0x22, 0x77, 0x5d, 0xa1, 0xe0, 0x25, 0x16, 0x11, 0x23, 0x76, 0x8d, 0xbb, 0x9d, 0xea, 0x19,
+ /*5e80:*/ 0x40, 0x73, 0x68, 0x9b, 0x72, 0x63, 0x0c, 0xe6, 0x87, 0x58, 0x8f, 0x6d, 0x5a, 0xd6, 0xf2, 0xbc,
+ /*5e90:*/ 0x82, 0x57, 0x50, 0x6e, 0x35, 0x92, 0x4a, 0x88, 0x5e, 0x26, 0x50, 0xe7, 0x93, 0x8e, 0x41, 0xe4,
+ /*5ea0:*/ 0xdd, 0xe7, 0xdf, 0x64, 0xfa, 0x3b, 0x94, 0xea, 0xae, 0xd4, 0x60, 0x64, 0x73, 0x43, 0x27, 0xe5,
+ /*5eb0:*/ 0xb7, 0x22, 0x2b, 0x79, 0x13, 0x24, 0xaf, 0x74, 0xf4, 0x97, 0x05, 0xde, 0x6f, 0xa8, 0xf9, 0x34,
+ /*5ec0:*/ 0xb5, 0xa6, 0x17, 0x06, 0x9b, 0x5c, 0xdf, 0xe7, 0x7b, 0x12, 0x48, 0xb2, 0x7b, 0x68, 0xe9, 0x5a,
+ /*5ed0:*/ 0xc4, 0x4a, 0xab, 0x49, 0xb5, 0xce, 0x69, 0xec, 0x77, 0x42, 0x61, 0x85, 0xf5, 0x5f, 0x05, 0x2a,
+ /*5ee0:*/ 0x17, 0x65, 0xef, 0x88, 0x5c, 0x23, 0x5f, 0xb3, 0xf1, 0x55, 0x49, 0x46, 0x51, 0xee, 0x22, 0x4e,
+ /*5ef0:*/ 0xb6, 0x43, 0x84, 0xfd, 0x99, 0xe3, 0x7b, 0x77, 0xfa, 0x63, 0x5b, 0x88, 0xd7, 0xa0, 0xc0, 0x49,
+ /*5f00:*/ 0x87, 0xac, 0x08, 0x20, 0x72, 0x84, 0xd9, 0x1a, 0xf7, 0x4d, 0xe9, 0x05, 0xbc, 0x19, 0xe8, 0x2b,
+ /*5f10:*/ 0x1b, 0x1d, 0xe6, 0x76, 0x7d, 0x1f, 0x19, 0x15, 0x8b, 0xcd, 0x78, 0x3f, 0x99, 0x6a, 0xcb, 0x65,
+ /*5f20:*/ 0xaf, 0x0b, 0x05, 0xcb, 0x64, 0x3d, 0x54, 0xb6, 0x79, 0xfd, 0x66, 0xdc, 0x7c, 0x30, 0x87, 0x57,
+ /*5f30:*/ 0x94, 0x16, 0xce, 0x4b, 0x6a, 0x94, 0x57, 0x87, 0xea, 0x8d, 0xdc, 0x6c, 0xb5, 0x89, 0xd7, 0x55,
+ /*5f40:*/ 0x3b, 0xb2, 0x6b, 0x44, 0x10, 0x43, 0x79, 0x0f, 0xc0, 0xa2, 0x42, 0x59, 0x80, 0x7a, 0xf7, 0x02,
+ /*5f50:*/ 0x2a, 0xa2, 0x9c, 0x0a, 0x73, 0xfc, 0xbb, 0xab, 0x2b, 0x9b, 0xb5, 0xb0, 0xcc, 0x2c, 0x9b, 0xf3,
+ /*5f60:*/ 0x3c, 0xbe, 0x64, 0xb8, 0x00, 0x12, 0x58, 0x99, 0x8d, 0x7c, 0x2d, 0xcd, 0xb7, 0x8e, 0xef, 0x55,
+ /*5f70:*/ 0x3e, 0x91, 0xa5, 0x4f, 0xf8, 0x47, 0x8d, 0x04, 0x2e, 0xd5, 0x71, 0x59, 0x07, 0x01, 0x49, 0x99,
+ /*5f80:*/ 0x05, 0x1f, 0x50, 0xf0, 0x5e, 0x2f, 0xd8, 0xb5, 0x34, 0x02, 0x0c, 0x55, 0x91, 0x36, 0x64, 0xd5,
+ /*5f90:*/ 0x29, 0x63, 0x58, 0x81, 0xae, 0x49, 0xe4, 0xa5, 0x34, 0x17, 0xa8, 0x98, 0x2a, 0x70, 0x1a, 0xd9,
+ /*5fa0:*/ 0x3b, 0xc2, 0x90, 0x3e, 0x1a, 0xf5, 0xa7, 0x7d, 0xa5, 0x12, 0x6d, 0xf8, 0x2a, 0x6a, 0x7a, 0x16,
+ /*5fb0:*/ 0x65, 0x4e, 0xc6, 0xc3, 0xd8, 0xea, 0xa9, 0x5f, 0xfc, 0x68, 0x21, 0x29, 0x35, 0x0a, 0xbf, 0xf0,
+ /*5fc0:*/ 0x54, 0x3e, 0x64, 0x4e, 0x67, 0x4d, 0xf7, 0x9d, 0xe5, 0x9f, 0x90, 0x70, 0x4a, 0xfa, 0xea, 0xc3,
+ /*5fd0:*/ 0xd7, 0x61, 0x53, 0xcc, 0x41, 0x99, 0xed, 0x44, 0x16, 0xc0, 0xe1, 0x15, 0x50, 0xaf, 0xa0, 0x2d,
+ /*5fe0:*/ 0x45, 0x02, 0xad, 0x0f, 0xcc, 0x6e, 0xa4, 0x45, 0x7b, 0x2e, 0x49, 0x84, 0x0f, 0x51, 0x05, 0xe7,
+ /*5ff0:*/ 0x64, 0x1c, 0xbc, 0xa5, 0x79, 0x51, 0xab, 0xc6, 0x5c, 0x6a, 0xe3, 0x66, 0x96, 0x75, 0x8c, 0x3f,
+ /*6000:*/ 0xca, 0xe6, 0x4d, 0xf5, 0x3f, 0x56, 0x05, 0x3c, 0xa9, 0xb8, 0x0d, 0xc1, 0xbc, 0xfe, 0x9a, 0x63,
+ /*6010:*/ 0x3c, 0x1f, 0x3f, 0xee, 0xd3, 0x53, 0x2d, 0xfb, 0xb6, 0x49, 0x04, 0x88, 0xaa, 0x2e, 0x67, 0x4b,
+ /*6020:*/ 0x04, 0x0e, 0x9d, 0xbd, 0xd0, 0x95, 0x3f, 0xb4, 0xef, 0x26, 0x78, 0xad, 0x04, 0x21, 0x60, 0x5b,
+ /*6030:*/ 0x08, 0xd4, 0x13, 0x85, 0xbe, 0x05, 0x8a, 0x36, 0xfc, 0xb9, 0x44, 0x3e, 0xb0, 0x01, 0xff, 0x0f,
+ /*6040:*/ 0x4d, 0x0f, 0x38, 0x57, 0xca, 0x00, 0xe7, 0x40, 0xf1, 0xb7, 0x95, 0xf6, 0xf7, 0x6d, 0x22, 0x4b,
+ /*6050:*/ 0x34, 0x14, 0xed, 0x01, 0xc2, 0x91, 0x5d, 0x68, 0xb5, 0xf7, 0x6a, 0xa1, 0x12, 0xd8, 0x84, 0x4f,
+ /*6060:*/ 0xf0, 0x99, 0x9a, 0x56, 0xd7, 0x2c, 0xd1, 0x38, 0xb5, 0x94, 0x81, 0xf2, 0x05, 0x8f, 0x5f, 0x1c,
+ /*6070:*/ 0xb2, 0xdb, 0x4c, 0x98, 0x7a, 0x62, 0x82, 0xe9, 0x02, 0x58, 0x98, 0xa3, 0x78, 0xf0, 0x67, 0x21,
+ /*6080:*/ 0x22, 0x4c, 0xa7, 0x73, 0x6f, 0xc1, 0x50, 0xd8, 0xde, 0x6d, 0x85, 0xfd, 0xa0, 0x84, 0x8f, 0xbc,
+ /*6090:*/ 0x04, 0x20, 0x88, 0x6f, 0x73, 0x74, 0x18, 0x7d, 0xa1, 0x23, 0xfd, 0xb4, 0x25, 0xc1, 0x1b, 0x4b,
+ /*60a0:*/ 0x93, 0x43, 0x8a, 0x3b, 0x89, 0x81, 0x11, 0x9f, 0xf7, 0x8e, 0x0c, 0xdc, 0xfe, 0x74, 0x9f, 0xaf,
+ /*60b0:*/ 0x83, 0xe4, 0xbb, 0x37, 0xaf, 0x4d, 0x5d, 0x68, 0xf4, 0xa0, 0x73, 0x24, 0x06, 0x55, 0xbe, 0xe7,
+ /*60c0:*/ 0xe9, 0xbb, 0xfa, 0x94, 0x28, 0x4b, 0xd6, 0xa5, 0x06, 0xa7, 0x9a, 0x30, 0xc4, 0x22, 0xec, 0xa7,
+ /*60d0:*/ 0x1b, 0xbc, 0x9d, 0xb9, 0x54, 0xe4, 0x8a, 0xc1, 0x79, 0xa4, 0x5f, 0xc3, 0xf3, 0xe6, 0xe6, 0x4b,
+ /*60e0:*/ 0x9f, 0x93, 0x77, 0x53, 0xed, 0x12, 0xbb, 0xc7, 0x7f, 0xc0, 0x8e, 0xbb, 0xcf, 0xd1, 0x2e, 0x8c,
+ /*60f0:*/ 0x17, 0x20, 0xc6, 0x03, 0xc9, 0x8e, 0x89, 0x33, 0x8f, 0x19, 0x83, 0x29, 0xd9, 0xb7, 0x8e, 0x58,
+ /*6100:*/ 0x7c, 0x3c, 0xf4, 0x9c, 0x63, 0x70, 0xbe, 0xba, 0x9a, 0x02, 0x5f, 0x44, 0x04, 0xcd, 0x24, 0xf3,
+ /*6110:*/ 0x1a, 0x8d, 0xaa, 0xff, 0x69, 0x71, 0x97, 0x98, 0x06, 0x4d, 0xcc, 0xd9, 0x76, 0x34, 0x6f, 0x91,
+ /*6120:*/ 0xff, 0xef, 0x1b, 0x65, 0x39, 0x6e, 0xb7, 0xb0, 0x5f, 0x9e, 0xfb, 0x42, 0x50, 0xc1, 0xf4, 0x79,
+ /*6130:*/ 0x9c, 0x56, 0xfa, 0xcc, 0x51, 0x54, 0xca, 0x53, 0x2d, 0xa4, 0x01, 0x00, 0xfd, 0x4e, 0x1d, 0x8b,
+ /*6140:*/ 0x54, 0x3d, 0xcc, 0x2c, 0xef, 0x12, 0x10, 0x55, 0xaf, 0x7c, 0xd1, 0xcc, 0xf2, 0x60, 0xc6, 0xcd,
+ /*6150:*/ 0xfa, 0x1d, 0x13, 0x93, 0xb7, 0x14, 0x0a, 0x6c, 0xe2, 0xf6, 0x21, 0x0a, 0x08, 0xa0, 0x48, 0xef,
+ /*6160:*/ 0x9d, 0xae, 0x72, 0x00, 0xd3, 0xef, 0xe7, 0x22, 0x1e, 0xd4, 0x98, 0x6c, 0xf3, 0x44, 0x81, 0xaf,
+ /*6170:*/ 0xe5, 0x57, 0x4b, 0xf9, 0xcb, 0x4c, 0x26, 0x0a, 0x73, 0xe4, 0x55, 0xc9, 0x43, 0x03, 0x29, 0xd9,
+ /*6180:*/ 0x79, 0xd1, 0x12, 0x5c, 0x06, 0x3c, 0xf1, 0x7d, 0x80, 0x26, 0x73, 0x20, 0x07, 0x99, 0xf4, 0xfa,
+ /*6190:*/ 0x34, 0x51, 0xb5, 0x59, 0x75, 0x72, 0xd7, 0x61, 0xf4, 0xd0, 0x44, 0x71, 0xc1, 0x13, 0xc7, 0xfd,
+ /*61a0:*/ 0x59, 0xc6, 0x49, 0x49, 0x70, 0xc4, 0x78, 0xf7, 0x3a, 0xe3, 0x5a, 0x8a, 0xf8, 0xc5, 0x52, 0xe0,
+ /*61b0:*/ 0xbd, 0x47, 0x38, 0x2a, 0x50, 0xb3, 0x80, 0x93, 0x60, 0x63, 0xfd, 0x01, 0xd6, 0x98, 0xb4, 0xea,
+ /*61c0:*/ 0x78, 0x13, 0x47, 0x50, 0xf5, 0xf9, 0x86, 0x6c, 0x95, 0x6d, 0x5a, 0xfa, 0x6f, 0x8f, 0x00, 0xed,
+ /*61d0:*/ 0x9a, 0xfa, 0xd4, 0x78, 0x2f, 0x3a, 0x62, 0x0e, 0x76, 0x15, 0x4b, 0xdf, 0x79, 0x1a, 0x6a, 0xcf,
+ /*61e0:*/ 0x75, 0x49, 0xfd, 0xf7, 0x63, 0x59, 0xd8, 0x46, 0xc2, 0xc1, 0x87, 0xbf, 0x6c, 0xfe, 0xcf, 0xe6,
+ /*61f0:*/ 0x10, 0x6f, 0x16, 0xa9, 0xfb, 0xae, 0x43, 0x1b, 0x04, 0xa1, 0x2d, 0xfa, 0x0b, 0x85, 0x31, 0x3d,
+ /*6200:*/ 0x45, 0x0f, 0xe4, 0xe6, 0xe8, 0xf0, 0x1c, 0x5e, 0x03, 0x4a, 0x25, 0x0a, 0xcf, 0xdd, 0x10, 0x17,
+ /*6210:*/ 0xef, 0xac, 0x90, 0xf4, 0x03, 0xc9, 0xec, 0x98, 0x78, 0x35, 0x8c, 0x96, 0x3b, 0x83, 0xd1, 0xed,
+ /*6220:*/ 0x53, 0x89, 0x9d, 0x9d, 0xab, 0xa9, 0x99, 0x8c, 0x0b, 0xd4, 0xcb, 0xf9, 0x5e, 0x02, 0x4c, 0x5c,
+ /*6230:*/ 0x11, 0xec, 0x45, 0x0e, 0xba, 0x35, 0x64, 0xa2, 0xa0, 0x20, 0x5f, 0xae, 0x7b, 0x28, 0x9d, 0x38,
+ /*6240:*/ 0x0c, 0x9a, 0x88, 0x75, 0x69, 0xc7, 0x2b, 0xdd, 0x06, 0xd6, 0xfb, 0xd0, 0x56, 0x29, 0x81, 0xb7,
+ /*6250:*/ 0xfe, 0x00, 0x0d, 0xc5, 0xf7, 0x79, 0x1f, 0xec, 0x75, 0x67, 0x1c, 0x04, 0xae, 0x39, 0x8b, 0x11,
+ /*6260:*/ 0xdd, 0xed, 0x83, 0x97, 0x59, 0x22, 0x02, 0x38, 0xe8, 0x04, 0x0f, 0x4f, 0xf5, 0xd1, 0x89, 0x0a,
+ /*6270:*/ 0xe4, 0x5a, 0x17, 0x3f, 0x66, 0x1b, 0x70, 0x5a, 0xfa, 0xea, 0xc7, 0x8f, 0x24, 0x42, 0xd5, 0x2d,
+ /*6280:*/ 0x47, 0x63, 0x19, 0xad, 0x95, 0x94, 0xac, 0x45, 0xbc, 0xb2, 0x15, 0xb6, 0xd3, 0x76, 0x78, 0xee,
+ /*6290:*/ 0x2f, 0xbc, 0x98, 0xfc, 0x0b, 0x71, 0x48, 0x21, 0x1b, 0xda, 0xc4, 0x76, 0x3f, 0x43, 0x12, 0x4a,
+ /*62a0:*/ 0x7b, 0x64, 0x24, 0x6b, 0xea, 0xbf, 0x9f, 0xdd, 0x47, 0x8a, 0x25, 0x2d, 0x8d, 0x3e, 0xe6, 0x1b,
+ /*62b0:*/ 0x7f, 0xea, 0xc8, 0xa7, 0xb1, 0x80, 0x30, 0xa7, 0x20, 0xc9, 0x6e, 0x8b, 0xee, 0xc8, 0x6a, 0x47,
+ /*62c0:*/ 0x20, 0xe7, 0x27, 0x25, 0x4b, 0x14, 0x3e, 0x98, 0xf3, 0x87, 0x95, 0x20, 0x59, 0xb8, 0x71, 0x44,
+ /*62d0:*/ 0x35, 0xf8, 0x72, 0xf8, 0x06, 0x94, 0xde, 0x42, 0xe5, 0x93, 0x57, 0x30, 0xd7, 0xc4, 0x36, 0x0a,
+ /*62e0:*/ 0x07, 0x53, 0xd8, 0x86, 0x17, 0x6b, 0xda, 0xf8, 0x35, 0x14, 0xa6, 0xd3, 0x35, 0xfd, 0xcd, 0xba,
+ /*62f0:*/ 0x43, 0x6c, 0x91, 0xb9, 0x77, 0x8a, 0xf1, 0x9a, 0x6d, 0x77, 0x47, 0x7b, 0x80, 0x3a, 0xb8, 0x39,
+ /*6300:*/ 0x34, 0x43, 0x31, 0x79, 0x25, 0x37, 0x01, 0x2b, 0xad, 0x07, 0xac, 0x67, 0xe2, 0xea, 0x2c, 0x29,
+ /*6310:*/ 0x5f, 0xfa, 0x6d, 0x73, 0x76, 0x58, 0x75, 0x0a, 0x40, 0x4d, 0xbf, 0x31, 0x0f, 0xa8, 0x4e, 0xf0,
+ /*6320:*/ 0x39, 0xba, 0xe2, 0x18, 0x91, 0x2d, 0xe5, 0xe4, 0xbf, 0x37, 0x86, 0x8d, 0xbe, 0x14, 0x93, 0x9f,
+ /*6330:*/ 0x0d, 0x95, 0x21, 0xc8, 0xae, 0x76, 0x90, 0x87, 0xad, 0xdb, 0x07, 0x11, 0x27, 0x24, 0xcb, 0xce,
+ /*6340:*/ 0x5d, 0x8f, 0x49, 0x84, 0xc2, 0x10, 0xe9, 0xd1, 0xa5, 0x0c, 0xea, 0xf0, 0x0d, 0x3f, 0x20, 0xf6,
+ /*6350:*/ 0x0e, 0x54, 0x7f, 0xca, 0x89, 0xf1, 0x10, 0x37, 0x06, 0xbe, 0x67, 0xdd, 0x9b, 0x1d, 0x6b, 0xd0,
+ /*6360:*/ 0x92, 0x5c, 0x78, 0xca, 0xbe, 0x5f, 0x4d, 0xc3, 0xc8, 0xfa, 0x48, 0x57, 0x7f, 0xda, 0x82, 0xb1,
+ /*6370:*/ 0x0d, 0xe2, 0xc3, 0x28, 0x76, 0x33, 0x0f, 0x6b, 0x0a, 0xc6, 0xbb, 0xdb, 0x1c, 0x94, 0x4f, 0x6a,
+ /*6380:*/ 0xe9, 0xff, 0x5c, 0xf9, 0x99, 0x45, 0x74, 0xda, 0xca, 0x3a, 0x2d, 0x1b, 0xf5, 0x98, 0xb0, 0xc8,
+ /*6390:*/ 0x4d, 0xa0, 0x8f, 0x78, 0xc5, 0xe8, 0xb8, 0xea, 0x63, 0x20, 0x34, 0x23, 0x67, 0xea, 0x30, 0xa7,
+ /*63a0:*/ 0x42, 0xf7, 0x2d, 0x0f, 0x35, 0xe3, 0xe0, 0x36, 0xad, 0x97, 0xe9, 0x02, 0x36, 0x02, 0x6d, 0x5f,
+ /*63b0:*/ 0x04, 0x5c, 0xcc, 0x65, 0x5a, 0x3b, 0x5a, 0x9f, 0xe3, 0x71, 0xb2, 0x9c, 0x49, 0xd6, 0x0a, 0x24,
+ /*63c0:*/ 0xfb, 0xd2, 0xb0, 0x7e, 0x72, 0x16, 0xe1, 0x7f, 0xb1, 0xbf, 0x04, 0x9f, 0xd2, 0xe5, 0x53, 0x98,
+ /*63d0:*/ 0xad, 0x68, 0x08, 0x9c, 0x4d, 0xa8, 0x5b, 0x22, 0xd9, 0xaf, 0x56, 0xb4, 0xad, 0x45, 0x9c, 0x07,
+ /*63e0:*/ 0x15, 0xc8, 0xc0, 0xec, 0x5f, 0x09, 0x02, 0x3b, 0xf9, 0xe3, 0xbc, 0x7d, 0x27, 0xe2, 0x2d, 0xde,
+ /*63f0:*/ 0xea, 0x7a, 0xdd, 0x90, 0x63, 0xed, 0x55, 0x10, 0xf4, 0x95, 0x73, 0x24, 0xd1, 0xcb, 0x1d, 0x3d,
+ /*6400:*/ 0xcf, 0x45, 0x53, 0x41, 0x47, 0x94, 0x85, 0xc0, 0x8b, 0x1f, 0xd1, 0x0d, 0x46, 0x13, 0x42, 0xef,
+ /*6410:*/ 0xe9, 0xc5, 0xc4, 0xa9, 0xa2, 0xf0, 0x87, 0x35, 0x34, 0x00, 0xbe, 0xc5, 0x5d, 0x40, 0x11, 0x75,
+ /*6420:*/ 0x8b, 0xec, 0x46, 0xd3, 0x1d, 0x54, 0xdc, 0xb3, 0x6c, 0x6e, 0x3b, 0x49, 0xa9, 0x80, 0xe8, 0x76,
+ /*6430:*/ 0x5d, 0xad, 0xce, 0x0e, 0x96, 0x24, 0xfd, 0x79, 0xb1, 0x58, 0x79, 0x98, 0x50, 0x29, 0x64, 0x8c,
+ /*6440:*/ 0x85, 0xd8, 0x16, 0x7b, 0xec, 0xa9, 0xb7, 0x53, 0x18, 0x55, 0x41, 0x44, 0x12, 0xf6, 0x52, 0x77,
+ /*6450:*/ 0x6c, 0x0f, 0xfe, 0x71, 0xf8, 0xf6, 0xf8, 0xb3, 0xb3, 0x47, 0xb6, 0xe5, 0x9e, 0x28, 0x4f, 0x87,
+ /*6460:*/ 0x92, 0xb0, 0x0c, 0x60, 0xbe, 0x7a, 0x91, 0xf3, 0x6e, 0x9a, 0xae, 0x2b, 0x37, 0x20, 0x8d, 0xf8,
+ /*6470:*/ 0x08, 0xdd, 0x65, 0xbe, 0xe5, 0x83, 0xeb, 0x6d, 0xf0, 0xe9, 0x07, 0x29, 0xb2, 0x3b, 0x10, 0x8a,
+ /*6480:*/ 0x95, 0xc7, 0x57, 0xdd, 0x21, 0x7b, 0xb0, 0x48, 0x91, 0x88, 0x68, 0x87, 0x93, 0x85, 0x82, 0x50,
+ /*6490:*/ 0xfa, 0x3d, 0xb9, 0x26, 0x86, 0xa2, 0x84, 0x47, 0x9d, 0x41, 0x91, 0xe5, 0x2e, 0xcb, 0xd1, 0x92,
+ /*64a0:*/ 0xcb, 0xb2, 0x20, 0x33, 0x05, 0x1e, 0xde, 0x16, 0x75, 0x5f, 0xc1, 0xd1, 0x84, 0x2c, 0x98, 0xb9,
+ /*64b0:*/ 0xf4, 0xba, 0x69, 0x13, 0x6f, 0x51, 0x55, 0x07, 0xcd, 0x4e, 0x10, 0x61, 0xd9, 0x67, 0x4b, 0x57,
+ /*64c0:*/ 0x8e, 0x3a, 0x88, 0x09, 0xdb, 0xfe, 0x71, 0x34, 0x5d, 0xd8, 0x7e, 0xb1, 0x10, 0xa8, 0x07, 0xf7,
+ /*64d0:*/ 0x05, 0x3c, 0x3c, 0x81, 0xb4, 0xd9, 0x13, 0x31, 0x9b, 0x9d, 0x97, 0xee, 0xeb, 0x07, 0xbb, 0x0a,
+ /*64e0:*/ 0xa9, 0x76, 0x8d, 0x3b, 0x49, 0x35, 0xeb, 0x31, 0x32, 0x99, 0x25, 0x3f, 0x44, 0xf5, 0x6c, 0x76,
+ /*64f0:*/ 0x08, 0x34, 0x96, 0xd8, 0xfa, 0x6f, 0xef, 0x23, 0xf1, 0x7d, 0x77, 0x07, 0x56, 0x46, 0x18, 0x2c,
+ /*6500:*/ 0x80, 0xa3, 0xbc, 0x4e, 0x35, 0xfc, 0x9a, 0x32, 0xc9, 0x64, 0x15, 0xd1, 0x2d, 0x47, 0xa1, 0xd7,
+ /*6510:*/ 0x87, 0xb3, 0xc3, 0x99, 0x64, 0xfe, 0xd1, 0x53, 0xce, 0x5c, 0x56, 0x54, 0x3e, 0x9c, 0xf7, 0xa3,
+ /*6520:*/ 0xb5, 0x81, 0xf3, 0x54, 0x35, 0xbc, 0x1c, 0x40, 0x52, 0xe4, 0xba, 0x08, 0x45, 0xf7, 0x6a, 0x85,
+ /*6530:*/ 0xc9, 0xe6, 0x0a, 0x2d, 0xe5, 0xf6, 0x86, 0x30, 0x61, 0x5f, 0xa8, 0x7a, 0xdb, 0x2c, 0x38, 0x78,
+ /*6540:*/ 0xff, 0x45, 0x9f, 0x7b, 0xcf, 0xf7, 0x66, 0x8d, 0x57, 0xfe, 0xcd, 0x0a, 0x3c, 0xbb, 0x4a, 0x45,
+ /*6550:*/ 0x82, 0x01, 0xd0, 0x30, 0x34, 0x22, 0xd9, 0x84, 0xb5, 0x19, 0x5e, 0xe2, 0xa9, 0x23, 0x3b, 0xfb,
+ /*6560:*/ 0xed, 0x42, 0xb2, 0x80, 0xdc, 0x8c, 0xae, 0x27, 0x6e, 0x54, 0xab, 0x9c, 0x87, 0x60, 0x18, 0xd6,
+ /*6570:*/ 0x57, 0x62, 0x6b, 0xb9, 0x87, 0xc4, 0x28, 0x52, 0x42, 0xc2, 0x0c, 0x83, 0xad, 0x1e, 0x79, 0xce,
+ /*6580:*/ 0x50, 0x49, 0x8b, 0xd4, 0xe7, 0x10, 0x1a, 0x32, 0x5a, 0x8f, 0x98, 0xd1, 0x20, 0x29, 0xc1, 0x35,
+ /*6590:*/ 0x02, 0x7f, 0xcf, 0x18, 0xac, 0x45, 0x24, 0x9f, 0xd3, 0x82, 0xe5, 0x95, 0xdc, 0x68, 0x2d, 0x1a,
+ /*65a0:*/ 0x8c, 0x6e, 0xa5, 0x79, 0x2b, 0xde, 0x17, 0x6c, 0x8b, 0x23, 0x06, 0x92, 0x01, 0x4e, 0x29, 0x3d,
+ /*65b0:*/ 0x5e, 0x8e, 0x45, 0x13, 0x85, 0x1c, 0x13, 0x61, 0xf4, 0xbb, 0x1b, 0x39, 0xcd, 0xd7, 0x3f, 0xde,
+ /*65c0:*/ 0xd3, 0xbe, 0x60, 0x41, 0xda, 0xe4, 0x95, 0xa6, 0xf8, 0x10, 0xe5, 0xe9, 0x34, 0x47, 0x49, 0x75,
+ /*65d0:*/ 0x7b, 0xa0, 0xbe, 0xa1, 0x4d, 0xce, 0xe3, 0xa5, 0xe7, 0xb3, 0x88, 0xf2, 0x06, 0x7c, 0xa5, 0x5f,
+ /*65e0:*/ 0xb7, 0x08, 0x1a, 0x19, 0x33, 0xc9, 0x66, 0x29, 0x77, 0xf6, 0x00, 0x48, 0x3c, 0x1b, 0xda, 0xa6,
+ /*65f0:*/ 0xb9, 0x31, 0xc3, 0xf6, 0x81, 0x32, 0x77, 0x69, 0x61, 0x7e, 0xc5, 0xe4, 0x90, 0xb1, 0xdd, 0x01,
+ /*6600:*/ 0xac, 0x89, 0xcf, 0x5b, 0x49, 0x10, 0xef, 0x23, 0x0d, 0x05, 0x87, 0x0f, 0xa2, 0x62, 0x24, 0x49,
+ /*6610:*/ 0x54, 0xa1, 0x9d, 0xc2, 0x4f, 0x4f, 0x06, 0x61, 0xa4, 0x24, 0x76, 0xd7, 0xcd, 0x59, 0x34, 0xb9,
+ /*6620:*/ 0xcc, 0x25, 0x41, 0x2e, 0xbd, 0x73, 0x3e, 0x07, 0xe7, 0xf0, 0x8f, 0xf3, 0xe0, 0x82, 0xf4, 0xc8,
+ /*6630:*/ 0x1f, 0x93, 0x0c, 0x79, 0xa3, 0x83, 0xba, 0xa1, 0x2e, 0x1b, 0x08, 0x0c, 0x26, 0x5e, 0x92, 0x75,
+ /*6640:*/ 0x2a, 0x8c, 0xcb, 0x4d, 0x1b, 0xd6, 0x95, 0x66, 0xf1, 0xa8, 0xea, 0x41, 0x49, 0x0c, 0x62, 0x7f,
+ /*6650:*/ 0x98, 0x9e, 0xd8, 0xf1, 0x2b, 0x26, 0x07, 0xe7, 0xa7, 0xb2, 0xc3, 0x95, 0xcb, 0x5f, 0xa7, 0x4f,
+ /*6660:*/ 0x5d, 0x45, 0x57, 0x00, 0xb1, 0x1d, 0xd5, 0x8b, 0x7a, 0x00, 0x78, 0xeb, 0x57, 0xad, 0xe4, 0x4b,
+ /*6670:*/ 0xa6, 0x47, 0xfe, 0x40, 0x19, 0x6b, 0x3f, 0xac, 0xba, 0xe8, 0xaf, 0x03, 0xe8, 0x8e, 0x1f, 0xb1,
+ /*6680:*/ 0x89, 0x26, 0x4b, 0x57, 0x2e, 0x74, 0xc0, 0xd8, 0x42, 0x2c, 0xb5, 0x0b, 0x95, 0xf0, 0x2f, 0x04,
+ /*6690:*/ 0x00, 0x44, 0x19, 0xdd, 0xff, 0x6f, 0xe4, 0x6e, 0x93, 0x33, 0x2e, 0xd1, 0x4a, 0xc5, 0x68, 0x5c,
+ /*66a0:*/ 0x9c, 0xea, 0x25, 0x9f, 0x78, 0xac, 0x08, 0xc1, 0x84, 0x8d, 0x08, 0x25, 0xb0, 0x79, 0x13, 0xbb,
+ /*66b0:*/ 0xf0, 0x5c, 0x2c, 0xa9, 0x22, 0x7c, 0xd4, 0xf9, 0xbe, 0xc4, 0x99, 0x8b, 0xba, 0xe0, 0x1b, 0x3a,
+ /*66c0:*/ 0xa2, 0xe8, 0xbf, 0x1a, 0xe2, 0x90, 0xd2, 0x0c, 0xfc, 0x7c, 0x96, 0x17, 0xd7, 0x25, 0x14, 0xa1,
+ /*66d0:*/ 0x67, 0xfe, 0xb2, 0x62, 0xca, 0x38, 0x0c, 0x6e, 0x6d, 0x6c, 0x65, 0x27, 0xb5, 0x53, 0x49, 0xc6,
+ /*66e0:*/ 0x62, 0x53, 0xc2, 0x14, 0x14, 0xf7, 0xec, 0xef, 0xfa, 0x9f, 0x81, 0x71, 0x80, 0xf7, 0x03, 0x9c,
+ /*66f0:*/ 0x69, 0x37, 0x38, 0xfc, 0xa6, 0x3b, 0x31, 0x81, 0x7e, 0x4c, 0x81, 0xf9, 0xd4, 0x17, 0xfe, 0x92,
+ /*6700:*/ 0x4d, 0x93, 0x1b, 0xbd, 0xcf, 0x5a, 0xfa, 0xfb, 0xaa, 0xcf, 0xf9, 0x10, 0xb2, 0x0f, 0xd7, 0x2f,
+ /*6710:*/ 0x71, 0x20, 0xd0, 0xda, 0x25, 0xd8, 0x6d, 0xe2, 0x81, 0x1d, 0x17, 0x55, 0x16, 0x1a, 0x66, 0xcc,
+ /*6720:*/ 0x21, 0x95, 0xf7, 0x3d, 0x96, 0xe1, 0x71, 0x59, 0x7c, 0x9c, 0xdd, 0xbe, 0xf8, 0xa5, 0x14, 0xe4,
+ /*6730:*/ 0x21, 0x31, 0x2c, 0xe2, 0x6e, 0x4a, 0x4e, 0x27, 0x29, 0x73, 0xf6, 0x9a, 0x8b, 0x04, 0xcd, 0x34,
+ /*6740:*/ 0xa4, 0x0f, 0x15, 0x57, 0x51, 0x42, 0x95, 0xf7, 0x54, 0x35, 0x0d, 0xd2, 0x5b, 0x9f, 0xd7, 0x51,
+ /*6750:*/ 0xff, 0x30, 0x1e, 0xa3, 0x14, 0x20, 0xa9, 0x46, 0xca, 0x87, 0x55, 0x83, 0x24, 0x2f, 0x97, 0x6f,
+ /*6760:*/ 0xc0, 0x03, 0xe3, 0x9a, 0x97, 0x92, 0x80, 0x95, 0x38, 0x69, 0x78, 0x2d, 0xed, 0xb0, 0x32, 0x85,
+ /*6770:*/ 0xfa, 0xb8, 0x78, 0x8c, 0xc2, 0x5d, 0x7b, 0xc9, 0x17, 0x6e, 0xca, 0x3b, 0xdd, 0x7d, 0xbc, 0xbe,
+ /*6780:*/ 0x80, 0xe0, 0xfb, 0x80, 0x5d, 0x33, 0xc1, 0xa3, 0x47, 0xf2, 0xdc, 0x97, 0x7d, 0xb1, 0xce, 0xbd,
+ /*6790:*/ 0xf2, 0x4d, 0xec, 0x19, 0xdc, 0x87, 0x15, 0x44, 0x0e, 0xe9, 0xbe, 0x14, 0x8a, 0xbb, 0x4b, 0x4b,
+ /*67a0:*/ 0x65, 0x64, 0x90, 0x12, 0x6c, 0xd5, 0x34, 0x33, 0xde, 0xd4, 0x66, 0x8c, 0x0e, 0xef, 0xfe, 0xa6,
+ /*67b0:*/ 0x95, 0x1b, 0x81, 0x0e, 0xa1, 0xa2, 0xf8, 0x3c, 0xd4, 0xa9, 0xea, 0xc6, 0x39, 0x10, 0x36, 0x08,
+ /*67c0:*/ 0xd0, 0xce, 0x40, 0x1e, 0x2e, 0x83, 0x19, 0x64, 0x1d, 0x64, 0x65, 0xc2, 0xda, 0xad, 0xc4, 0x0a,
+ /*67d0:*/ 0x64, 0xe6, 0x58, 0x26, 0x05, 0x6b, 0xec, 0x41, 0xea, 0x55, 0x4d, 0x4c, 0x1a, 0xac, 0x7c, 0x72,
+ /*67e0:*/ 0x4c, 0x4d, 0x56, 0xab, 0x0a, 0x2d, 0x17, 0xe9, 0x2a, 0x9d, 0xe1, 0xc1, 0x84, 0xb0, 0xd9, 0x95,
+ /*67f0:*/ 0x7d, 0x4a, 0x11, 0x77, 0xeb, 0x93, 0x02, 0x9b, 0xb1, 0xfb, 0xd2, 0xa9, 0xf1, 0xde, 0x59, 0x25,
+ /*6800:*/ 0x5a, 0x49, 0x62, 0xc1, 0xad, 0xbb, 0x50, 0x5f, 0xaf, 0x8e, 0xb7, 0xdf, 0x11, 0x55, 0xf4, 0xb9,
+ /*6810:*/ 0x29, 0xc3, 0xc8, 0x70, 0xea, 0xcd, 0x9c, 0x65, 0x72, 0x29, 0xfb, 0x3b, 0x12, 0x69, 0xf4, 0x4c,
+ /*6820:*/ 0xbc, 0x6d, 0xbf, 0xce, 0xc9, 0x09, 0x38, 0xf1, 0x00, 0x81, 0x47, 0x24, 0x60, 0x46, 0x2c, 0x14,
+ /*6830:*/ 0xf1, 0xd5, 0x92, 0xdd, 0x44, 0x68, 0x20, 0x44, 0x70, 0xf1, 0xd2, 0x0e, 0x32, 0x1f, 0x60, 0xed,
+ /*6840:*/ 0x58, 0x02, 0x5a, 0x79, 0x2c, 0xa1, 0x3c, 0x70, 0x3e, 0xb5, 0xf4, 0x64, 0xa1, 0x69, 0x56, 0x76,
+ /*6850:*/ 0xd3, 0xf9, 0x61, 0xc4, 0xe7, 0x11, 0x07, 0x10, 0x1f, 0x87, 0xa2, 0x8d, 0x2a, 0xb1, 0x6d, 0x4a,
+ /*6860:*/ 0xa8, 0x79, 0x62, 0x7c, 0xf6, 0xfc, 0x22, 0x18, 0xa0, 0x22, 0x91, 0x33, 0xb9, 0x8a, 0xe6, 0xc6,
+ /*6870:*/ 0x98, 0x2d, 0x80, 0x49, 0x53, 0x2f, 0x76, 0xd0, 0x9a, 0x4b, 0x5c, 0x5b, 0x21, 0xe1, 0x19, 0xb3,
+ /*6880:*/ 0x76, 0x20, 0x90, 0xe3, 0xd7, 0xa5, 0x83, 0xcb, 0x0c, 0x9c, 0x04, 0x63, 0xf0, 0x1d, 0xfb, 0x07,
+ /*6890:*/ 0xd7, 0xae, 0x43, 0xfe, 0x97, 0x1e, 0x6e, 0xb4, 0xb3, 0xea, 0xf7, 0x7c, 0x31, 0x75, 0xf3, 0x04,
+ /*68a0:*/ 0x93, 0x40, 0xd7, 0x18, 0x3d, 0xaf, 0x3f, 0x22, 0x4e, 0x7f, 0x34, 0xb7, 0xb1, 0x43, 0x9f, 0xc3,
+ /*68b0:*/ 0xeb, 0x05, 0x6e, 0xb0, 0xdd, 0xa5, 0x0d, 0x0d, 0x80, 0x78, 0x3a, 0xdc, 0x8e, 0xb1, 0x8d, 0x40,
+ /*68c0:*/ 0x4b, 0x94, 0xfb, 0x04, 0xf5, 0x34, 0x39, 0x90, 0x02, 0x56, 0xd4, 0xd8, 0xd3, 0x9d, 0x51, 0x10,
+ /*68d0:*/ 0x36, 0x6c, 0x12, 0xcc, 0x8c, 0x80, 0x8b, 0xee, 0x60, 0xdc, 0x6b, 0x38, 0x2e, 0xe0, 0x4d, 0x1f,
+ /*68e0:*/ 0x9f, 0x83, 0x6b, 0x3d, 0x7e, 0xc2, 0x56, 0x01, 0xe2, 0x80, 0xf6, 0xd2, 0xbf, 0x0f, 0x52, 0x78,
+ /*68f0:*/ 0x28, 0xe3, 0xaf, 0x74, 0x74, 0x56, 0x98, 0x62, 0x53, 0x10, 0x48, 0xb3, 0xcd, 0xc7, 0x63, 0x37,
+ /*6900:*/ 0x4c, 0x7b, 0x4a, 0x13, 0x52, 0x46, 0xaf, 0xd8, 0xbb, 0x27, 0x12, 0x87, 0x02, 0x9a, 0xae, 0xff,
+ /*6910:*/ 0x49, 0xcc, 0x5f, 0xd2, 0x09, 0x10, 0x08, 0xe6, 0x70, 0x53, 0x36, 0xf2, 0x0e, 0x54, 0x34, 0x66,
+ /*6920:*/ 0x42, 0x26, 0x59, 0x1b, 0xdf, 0x88, 0x33, 0x9a, 0xb1, 0xaf, 0xa6, 0xdb, 0x71, 0xa9, 0xea, 0x89,
+ /*6930:*/ 0xe8, 0xdb, 0xb9, 0xcf, 0x78, 0x03, 0x5c, 0x33, 0x9b, 0x2c, 0x1e, 0x84, 0x97, 0x99, 0xc8, 0xdb,
+ /*6940:*/ 0xdd, 0x94, 0x98, 0xf3, 0x8f, 0x1f, 0xfb, 0xf2, 0x45, 0x46, 0x66, 0xb9, 0x24, 0x4d, 0x2f, 0x69,
+ /*6950:*/ 0x3a, 0xb7, 0x5c, 0x0e, 0x53, 0xf9, 0xdb, 0x65, 0xbb, 0x13, 0xd0, 0x18, 0x61, 0x5c, 0x95, 0xa4,
+ /*6960:*/ 0x1b, 0xdf, 0x9b, 0x3d, 0x8c, 0x62, 0x39, 0x19, 0x80, 0xec, 0x37, 0xa7, 0x60, 0xa4, 0x56, 0xf1,
+ /*6970:*/ 0xf5, 0x4b, 0x1f, 0xd2, 0x1d, 0x5c, 0x83, 0x7c, 0xc3, 0xbe, 0xe6, 0x6f, 0x02, 0x1f, 0xfc, 0xbd,
+ /*6980:*/ 0xad, 0x2a, 0x56, 0x61, 0x3f, 0xfd, 0x73, 0xac, 0x38, 0x89, 0xe5, 0x13, 0x14, 0xcd, 0x3e, 0x94,
+ /*6990:*/ 0x43, 0x37, 0xb1, 0x29, 0x9e, 0xbf, 0xa5, 0xc2, 0x10, 0x4e, 0xac, 0xc8, 0x5e, 0x72, 0xa5, 0x85,
+ /*69a0:*/ 0x30, 0xe2, 0xcb, 0x49, 0x0e, 0x7a, 0x30, 0x32, 0x03, 0x0b, 0xf7, 0xec, 0x54, 0x07, 0xc5, 0xd5,
+ /*69b0:*/ 0xb3, 0x86, 0xe6, 0x22, 0x3c, 0x69, 0x39, 0xa4, 0xda, 0xa8, 0xea, 0xc9, 0xcc, 0x67, 0xda, 0xf4,
+ /*69c0:*/ 0xbd, 0xf4, 0xd4, 0x6d, 0x4d, 0x89, 0x9c, 0xcb, 0x5a, 0x22, 0x9a, 0x29, 0x6d, 0x70, 0xff, 0x43,
+ /*69d0:*/ 0xc8, 0xdb, 0x38, 0x2e, 0x44, 0x8c, 0x19, 0x50, 0x82, 0xc1, 0x0a, 0xa5, 0xdf, 0x0e, 0xd2, 0x49,
+ /*69e0:*/ 0x08, 0x39, 0xdb, 0xf6, 0xc3, 0xa9, 0xad, 0x58, 0x17, 0x0c, 0xac, 0x0c, 0x61, 0x18, 0xaf, 0x6f,
+ /*69f0:*/ 0xbc, 0x52, 0x8e, 0x80, 0x6b, 0x8b, 0xd9, 0x94, 0x1c, 0x83, 0x13, 0xe9, 0x1e, 0xd6, 0x83, 0x3d,
+ /*6a00:*/ 0x32, 0x59, 0x6f, 0x6d, 0x8d, 0xa0, 0x4e, 0x1b, 0x7b, 0x14, 0xda, 0x28, 0x6a, 0x15, 0x56, 0xc2,
+ /*6a10:*/ 0x89, 0x65, 0xc1, 0x42, 0x01, 0x3a, 0x2a, 0xc3, 0x29, 0xd1, 0x3e, 0x65, 0xae, 0x00, 0xbf, 0x67,
+ /*6a20:*/ 0xbd, 0xd4, 0x20, 0xfd, 0xf8, 0x46, 0x06, 0x2b, 0xe5, 0x31, 0x6f, 0x70, 0x3b, 0x81, 0x81, 0x4a,
+ /*6a30:*/ 0xc7, 0xcf, 0x72, 0x99, 0x2c, 0x2d, 0x4b, 0xdf, 0xc3, 0x09, 0xe3, 0x5b, 0x29, 0x1d, 0x59, 0xd3,
+ /*6a40:*/ 0xe0, 0x89, 0x7e, 0xc4, 0x8c, 0x30, 0x46, 0x8a, 0x6b, 0x3b, 0xd0, 0x1b, 0x30, 0xe5, 0x14, 0x51,
+ /*6a50:*/ 0x34, 0xbc, 0x4c, 0xd5, 0x4b, 0x04, 0x2f, 0x1b, 0x7c, 0x50, 0x01, 0xdf, 0x5f, 0xa2, 0xdf, 0x10,
+ /*6a60:*/ 0x56, 0xbc, 0xde, 0x26, 0x5a, 0x11, 0xa7, 0xc8, 0xc9, 0x78, 0xa0, 0x5a, 0xb4, 0xfc, 0x6b, 0xa6,
+ /*6a70:*/ 0xb0, 0x08, 0xbc, 0xd8, 0xfd, 0xf2, 0xb0, 0xa2, 0xd5, 0xc3, 0x92, 0x0f, 0xcc, 0x6d, 0xbf, 0xb0,
+ /*6a80:*/ 0xc9, 0x9f, 0xc2, 0x4e, 0xf6, 0x5a, 0xc1, 0x26, 0x16, 0x3d, 0x90, 0x50, 0x65, 0x53, 0xd4, 0x66,
+ /*6a90:*/ 0xab, 0x4d, 0xce, 0x70, 0xd3, 0x91, 0x56, 0x4f, 0x14, 0x29, 0x4c, 0x8f, 0x8c, 0xf7, 0xcb, 0xad,
+ /*6aa0:*/ 0xca, 0x87, 0x67, 0x0d, 0x48, 0xc1, 0x15, 0xa1, 0xbd, 0x22, 0xb4, 0xa7, 0x41, 0x10, 0xfc, 0x49,
+ /*6ab0:*/ 0x35, 0x01, 0xc5, 0xa7, 0xf1, 0xd1, 0x92, 0xa3, 0x19, 0xf0, 0x75, 0x65, 0xf0, 0xe3, 0xec, 0x64,
+ /*6ac0:*/ 0xd9, 0x9d, 0x3f, 0x5e, 0x89, 0x5e, 0x30, 0xad, 0x98, 0x83, 0xca, 0x09, 0xc4, 0x80, 0x7d, 0x3f,
+ /*6ad0:*/ 0x9b, 0x74, 0x59, 0xde, 0xdf, 0x75, 0xad, 0xf2, 0x09, 0x1d, 0xff, 0xaf, 0x80, 0x71, 0x77, 0x0b,
+ /*6ae0:*/ 0xc1, 0x47, 0xad, 0xde, 0x6c, 0x59, 0x06, 0x38, 0x59, 0x8e, 0xe8, 0x99, 0x77, 0xd4, 0xf1, 0xab,
+ /*6af0:*/ 0x24, 0x2a, 0x51, 0x46, 0x9f, 0x9c, 0x00, 0x24, 0x86, 0x93, 0x82, 0xbf, 0x52, 0x68, 0x46, 0xdf,
+ /*6b00:*/ 0xd7, 0x3f, 0xb1, 0x23, 0x2b, 0xd4, 0xc7, 0xb1, 0x4a, 0x9b, 0x31, 0xe0, 0x20, 0x8a, 0xaa, 0xc2,
+ /*6b10:*/ 0x9e, 0x4d, 0xd8, 0x14, 0xfd, 0x89, 0xfc, 0xfa, 0x3a, 0x42, 0xe3, 0xed, 0x21, 0x23, 0x17, 0xe4,
+ /*6b20:*/ 0xe8, 0xd2, 0x88, 0xea, 0x58, 0x9f, 0xb4, 0xff, 0xfc, 0xce, 0x9d, 0x8d, 0x9a, 0xa4, 0x8c, 0xaf,
+ /*6b30:*/ 0x17, 0xf3, 0x80, 0x16, 0x9b, 0xcf, 0x16, 0x25, 0x88, 0x2e, 0x37, 0x59, 0x64, 0x27, 0x1b, 0xb5,
+ /*6b40:*/ 0xba, 0x9e, 0x89, 0xbd, 0xc2, 0xfd, 0x65, 0x31, 0x8b, 0xc8, 0xc2, 0x6b, 0x11, 0xfd, 0xf6, 0x86,
+ /*6b50:*/ 0x64, 0xdd, 0xe4, 0xb8, 0xa8, 0x9b, 0x64, 0x47, 0xce, 0x85, 0x01, 0xb9, 0xa2, 0xf1, 0xe4, 0x40,
+ /*6b60:*/ 0x6a, 0x46, 0x60, 0x6d, 0x28, 0xea, 0x53, 0xf7, 0x47, 0x28, 0x48, 0x72, 0xe7, 0x71, 0x61, 0xb9,
+ /*6b70:*/ 0x24, 0xd6, 0xc6, 0xc6, 0x0d, 0x5f, 0x07, 0xe6, 0xa0, 0xcf, 0x50, 0x2e, 0x8a, 0xb1, 0xa1, 0x64,
+ /*6b80:*/ 0x8c, 0xf4, 0x82, 0x81, 0xed, 0x60, 0xe6, 0x1c, 0xc0, 0x16, 0x98, 0x43, 0x6c, 0x26, 0x7d, 0xc1,
+ /*6b90:*/ 0x2a, 0xa5, 0xbb, 0x2b, 0x30, 0xa5, 0xd3, 0xf2, 0x00, 0x7b, 0x37, 0xe8, 0x8b, 0x15, 0xdc, 0xaf,
+ /*6ba0:*/ 0xc7, 0x08, 0x83, 0x66, 0x5f, 0x9b, 0x7b, 0xbb, 0x2d, 0x4c, 0x14, 0xb7, 0xb1, 0x18, 0x82, 0x62,
+ /*6bb0:*/ 0x0a, 0xfa, 0x55, 0x8a, 0xc8, 0x61, 0xe6, 0x18, 0x1f, 0xcc, 0xe0, 0xf1, 0x66, 0x73, 0x08, 0xac,
+ /*6bc0:*/ 0x66, 0x0d, 0x3e, 0x4f, 0xfc, 0xbe, 0xd8, 0x0b, 0xad, 0x84, 0xcd, 0x31, 0x6e, 0x78, 0x54, 0xa7,
+ /*6bd0:*/ 0x1e, 0x23, 0x0b, 0x2d, 0x19, 0x70, 0xaa, 0x27, 0x7a, 0x46, 0x7d, 0x0d, 0x98, 0xfe, 0x60, 0x7e,
+ /*6be0:*/ 0x61, 0x05, 0xce, 0x71, 0x2e, 0x96, 0x01, 0x99, 0x38, 0x5e, 0x09, 0x03, 0x38, 0x7d, 0x07, 0xbf,
+ /*6bf0:*/ 0x19, 0xc9, 0xa3, 0x48, 0x56, 0x6f, 0xc1, 0xc2, 0x67, 0x38, 0xfb, 0xa8, 0x45, 0xc2, 0xd9, 0x7d,
+ /*6c00:*/ 0x4b, 0xb7, 0x69, 0xad, 0x47, 0x6d, 0x2d, 0xe8, 0xcb, 0x35, 0x27, 0x14, 0x1a, 0x70, 0x20, 0x58,
+ /*6c10:*/ 0xfb, 0x58, 0xa1, 0x40, 0x1f, 0x58, 0x7a, 0xfd, 0x05, 0x58, 0xbe, 0x82, 0xb6, 0x4b, 0x93, 0x0d,
+ /*6c20:*/ 0xe0, 0x84, 0xed, 0xf8, 0x33, 0x76, 0x6c, 0x59, 0x8a, 0xab, 0x2e, 0x26, 0x40, 0xea, 0xb0, 0x43,
+ /*6c30:*/ 0x99, 0xf5, 0xbe, 0x65, 0xe7, 0x78, 0xdc, 0x77, 0x0b, 0xf5, 0xed, 0x37, 0x61, 0x4e, 0x08, 0x1f,
+ /*6c40:*/ 0x03, 0xfd, 0xa4, 0x53, 0xa6, 0x00, 0x50, 0x49, 0xb5, 0xe3, 0x7d, 0x62, 0xef, 0x0f, 0xc9, 0x76,
+ /*6c50:*/ 0x60, 0x3a, 0x23, 0x42, 0x68, 0xb0, 0xfa, 0x0e, 0x2b, 0x6c, 0x3b, 0xed, 0x68, 0x12, 0x06, 0x59,
+ /*6c60:*/ 0xf2, 0x6a, 0xf0, 0xae, 0xe1, 0x16, 0xc3, 0x56, 0xe2, 0x59, 0xec, 0x1d, 0x0e, 0x8e, 0x81, 0xb3,
+ /*6c70:*/ 0xce, 0xe3, 0x73, 0x98, 0x9c, 0xd7, 0x61, 0xe1, 0xac, 0x9c, 0x9c, 0xd2, 0x1e, 0x4a, 0x14, 0x47,
+ /*6c80:*/ 0x65, 0x44, 0x0a, 0x75, 0x89, 0x0a, 0x1f, 0x57, 0x5d, 0x7e, 0x8f, 0x04, 0x9c, 0xd1, 0x85, 0x98,
+ /*6c90:*/ 0x01, 0x6d, 0x62, 0xd2, 0xb6, 0x90, 0xc4, 0xbf, 0xe3, 0x68, 0xb4, 0x28, 0x2f, 0x12, 0x05, 0x63,
+ /*6ca0:*/ 0x27, 0x85, 0xf5, 0x01, 0xda, 0xea, 0x64, 0xf4, 0x0e, 0x10, 0x8b, 0xd7, 0x0a, 0x7b, 0x49, 0xff,
+ /*6cb0:*/ 0xbe, 0xf9, 0x9d, 0xfd, 0x76, 0xa8, 0x69, 0x04, 0x9e, 0xf1, 0x42, 0xd4, 0x5f, 0x14, 0x54, 0x76,
+ /*6cc0:*/ 0x7f, 0x9d, 0xc0, 0xe3, 0x2c, 0xda, 0x53, 0x1b, 0x7a, 0x15, 0x30, 0x64, 0xab, 0xce, 0x8b, 0x93,
+ /*6cd0:*/ 0x3c, 0x5b, 0x08, 0x58, 0x89, 0x94, 0xb6, 0xb2, 0x93, 0xd0, 0x29, 0x7f, 0x0c, 0x5b, 0xa6, 0x1d,
+ /*6ce0:*/ 0xe4, 0x20, 0x8d, 0x45, 0xc8, 0xb1, 0xee, 0xa7, 0x1f, 0x1e, 0x20, 0x3e, 0xef, 0x44, 0x23, 0x0a,
+ /*6cf0:*/ 0x6a, 0x13, 0x75, 0x8e, 0x80, 0xfc, 0x00, 0x7b, 0xff, 0x0a, 0xb4, 0x78, 0x2f, 0x00, 0x43, 0xde,
+ /*6d00:*/ 0x54, 0x85, 0x90, 0xbe, 0x67, 0x1f, 0xfa, 0xc5, 0x4b, 0xb7, 0x10, 0x8c, 0xb7, 0x09, 0xe0, 0xbb,
+ /*6d10:*/ 0x9e, 0xa8, 0xb4, 0x57, 0x34, 0x69, 0x47, 0x62, 0x59, 0x45, 0x75, 0x8e, 0x3d, 0x1f, 0xd7, 0xe9,
+ /*6d20:*/ 0xc4, 0xb2, 0x21, 0x5b, 0x96, 0x09, 0xd0, 0x4d, 0x22, 0x5e, 0xf3, 0xa2, 0x7b, 0x53, 0x0c, 0x6a,
+ /*6d30:*/ 0x91, 0xba, 0xd2, 0x4d, 0x9d, 0x3a, 0x68, 0xbd, 0x6a, 0xb7, 0x64, 0x7c, 0xd9, 0x18, 0xb3, 0x64,
+ /*6d40:*/ 0x2c, 0x81, 0x53, 0xdc, 0x01, 0xe6, 0x72, 0x6e, 0xcb, 0xb0, 0x6b, 0xce, 0x35, 0x2f, 0x15, 0xeb,
+ /*6d50:*/ 0xae, 0xfc, 0x7c, 0x34, 0xda, 0xde, 0xd8, 0x11, 0xc4, 0xb9, 0xf8, 0x73, 0x51, 0xdf, 0x45, 0x99,
+ /*6d60:*/ 0xae, 0x86, 0x8d, 0x80, 0x3e, 0xc1, 0x7e, 0x63, 0xae, 0xdd, 0x24, 0xbe, 0xe1, 0xfe, 0x71, 0x99,
+ /*6d70:*/ 0xaf, 0xf9, 0xec, 0x67, 0x14, 0xe2, 0x17, 0x3b, 0x0b, 0x5a, 0xb4, 0x40, 0x5d, 0x29, 0x05, 0x67,
+ /*6d80:*/ 0xae, 0x25, 0xef, 0xbf, 0x41, 0x47, 0x3d, 0x12, 0xd3, 0x80, 0xed, 0x57, 0xfa, 0x3e, 0x9c, 0x32,
+ /*6d90:*/ 0x3b, 0x04, 0xf0, 0xc8, 0x96, 0x67, 0x5a, 0x32, 0x04, 0x88, 0xa8, 0x81, 0x1f, 0x3f, 0xe7, 0xd5,
+ /*6da0:*/ 0x0f, 0xc5, 0x78, 0x8a, 0x95, 0x24, 0x72, 0xf2, 0x0b, 0xd4, 0xa5, 0xa9, 0x5a, 0xf1, 0xef, 0x53,
+ /*6db0:*/ 0x45, 0x53, 0x2b, 0xd2, 0xd7, 0x33, 0x02, 0x55, 0xcd, 0xd5, 0x11, 0x80, 0xa3, 0xbb, 0xf1, 0xed,
+ /*6dc0:*/ 0x5e, 0x4c, 0x50, 0xa2, 0x18, 0xd1, 0xcd, 0xd2, 0x30, 0x87, 0x49, 0x99, 0xd2, 0x33, 0x96, 0x50,
+ /*6dd0:*/ 0x71, 0xe4, 0x19, 0x8b, 0x59, 0x95, 0xd4, 0x88, 0x4d, 0x7b, 0x19, 0xdb, 0x09, 0x22, 0x02, 0x36,
+ /*6de0:*/ 0xc7, 0x60, 0xde, 0xfc, 0x22, 0x2c, 0x06, 0xa8, 0x75, 0x07, 0xe4, 0x3a, 0xa3, 0xfa, 0xa1, 0x85,
+ /*6df0:*/ 0x1e, 0x0c, 0x8d, 0x27, 0xa2, 0xa3, 0x0f, 0x68, 0x54, 0xee, 0xb5, 0x17, 0x48, 0x36, 0x7e, 0x9e,
+ /*6e00:*/ 0x7f, 0xe1, 0x8f, 0x09, 0xaa, 0xfe, 0x4f, 0x5d, 0xfd, 0x17, 0xe9, 0x42, 0x57, 0xa8, 0x3f, 0x18,
+ /*6e10:*/ 0xb6, 0x52, 0xf5, 0xa9, 0xcd, 0xd4, 0x30, 0x39, 0xa4, 0xc7, 0x1a, 0x6c, 0x7a, 0x81, 0xb7, 0xfb,
+ /*6e20:*/ 0xca, 0xab, 0xb8, 0xeb, 0x8b, 0x2b, 0x20, 0x4f, 0x0d, 0xbb, 0x44, 0x2f, 0xc7, 0x2c, 0x7c, 0x8a,
+ /*6e30:*/ 0x92, 0x48, 0x85, 0x92, 0xea, 0xd2, 0xde, 0x4e, 0xad, 0xec, 0x90, 0xe4, 0xe2, 0x9d, 0x4b, 0x7b,
+ /*6e40:*/ 0xce, 0xab, 0x43, 0x19, 0x65, 0xc2, 0xc2, 0xe2, 0x3c, 0xea, 0x7c, 0xd3, 0xd7, 0x76, 0x56, 0x5c,
+ /*6e50:*/ 0xd4, 0xad, 0x31, 0xb7, 0xeb, 0x3b, 0x54, 0x01, 0x18, 0x9f, 0x0a, 0xec, 0xb2, 0x0b, 0xcb, 0x5e,
+ /*6e60:*/ 0xf9, 0x2f, 0x13, 0x10, 0xce, 0xa5, 0x73, 0x89, 0x3a, 0x8f, 0x69, 0xa3, 0x61, 0xcc, 0x05, 0x10,
+ /*6e70:*/ 0x96, 0x67, 0x61, 0xfb, 0xde, 0x0d, 0xdc, 0x19, 0x7e, 0xc2, 0xf6, 0x0f, 0x00, 0x07, 0x52, 0x90,
+ /*6e80:*/ 0x36, 0xda, 0x40, 0xc5, 0x99, 0xa7, 0xd5, 0xd2, 0x13, 0x40, 0x8a, 0x49, 0xae, 0xd2, 0x53, 0x54,
+ /*6e90:*/ 0x37, 0x66, 0x64, 0x1c, 0x75, 0xb3, 0x31, 0xf6, 0x80, 0x86, 0xe3, 0xb1, 0x1d, 0xfb, 0x1b, 0x36,
+ /*6ea0:*/ 0x9b, 0x7d, 0x7a, 0x67, 0x64, 0x6a, 0x31, 0xd4, 0xc9, 0xc8, 0x11, 0x91, 0xb4, 0x78, 0x2a, 0x3f,
+ /*6eb0:*/ 0xef, 0x4f, 0x12, 0x7d, 0x03, 0xe9, 0x8c, 0x2a, 0x27, 0xd5, 0x70, 0x5c, 0x3b, 0x87, 0xc6, 0x7e,
+ /*6ec0:*/ 0xfb, 0x7e, 0x46, 0x08, 0x06, 0x17, 0x89, 0x29, 0x6c, 0x5d, 0xac, 0x0e, 0x96, 0x53, 0x77, 0x0f,
+ /*6ed0:*/ 0x6b, 0xd7, 0x07, 0xe7, 0xf4, 0xbd, 0xdf, 0x40, 0xbf, 0xf9, 0x91, 0x38, 0xdb, 0xb5, 0x0d, 0x0b,
+ /*6ee0:*/ 0x04, 0xcc, 0x5e, 0x4b, 0x62, 0xeb, 0xd1, 0xf6, 0xc9, 0x91, 0xf6, 0x27, 0xf1, 0x71, 0xf7, 0xe3,
+ /*6ef0:*/ 0x6f, 0xb0, 0x85, 0xa2, 0x79, 0x45, 0xe8, 0x0c, 0x15, 0xbf, 0x65, 0x29, 0xfa, 0x4f, 0xed, 0xea,
+ /*6f00:*/ 0x51, 0xe2, 0xc9, 0x57, 0x47, 0x84, 0x5f, 0x4d, 0x04, 0xb2, 0xa4, 0xc4, 0xc6, 0x6a, 0xef, 0x15,
+ /*6f10:*/ 0x27, 0xf3, 0x1c, 0xc6, 0x39, 0xd9, 0x26, 0xee, 0x32, 0xde, 0x51, 0x9c, 0x51, 0x64, 0x4b, 0xc7,
+ /*6f20:*/ 0xf1, 0xc3, 0x69, 0xcb, 0xce, 0x9c, 0x81, 0x1d, 0x5b, 0x25, 0xe8, 0x17, 0xbc, 0xf4, 0x42, 0x0a,
+ /*6f30:*/ 0x6f, 0x6a, 0x51, 0x99, 0x62, 0x29, 0x97, 0x39, 0x88, 0xc3, 0xc8, 0x4e, 0x58, 0x9a, 0x86, 0xe1,
+ /*6f40:*/ 0x36, 0xa6, 0x26, 0x6b, 0x06, 0x90, 0x56, 0x62, 0xc4, 0xb7, 0x24, 0x85, 0xd3, 0x37, 0x17, 0x36,
+ /*6f50:*/ 0x1a, 0xef, 0xce, 0x8c, 0xf3, 0x3f, 0x3c, 0x36, 0x19, 0x8f, 0xb7, 0x29, 0x69, 0x83, 0x31, 0xb1,
+ /*6f60:*/ 0x87, 0x8d, 0xc5, 0x2e, 0x6e, 0x0e, 0x4f, 0xdb, 0xee, 0xcd, 0x96, 0xbc, 0x59, 0x85, 0x80, 0xef,
+ /*6f70:*/ 0xe5, 0xcf, 0xa1, 0x9d, 0xf9, 0xe0, 0x2d, 0xe3, 0x2c, 0x38, 0xf2, 0x0a, 0x11, 0x1b, 0x3e, 0x58,
+ /*6f80:*/ 0x1b, 0x8a, 0x19, 0x32, 0x6c, 0x64, 0xb3, 0x78, 0xf1, 0x66, 0xbd, 0x9b, 0x69, 0xbe, 0x85, 0x53,
+ /*6f90:*/ 0xf7, 0x92, 0xa6, 0xd9, 0xc3, 0xac, 0x77, 0xba, 0x52, 0x64, 0x89, 0x30, 0xd6, 0x30, 0x4f, 0xa6,
+ /*6fa0:*/ 0xc2, 0xec, 0xd9, 0x96, 0x50, 0xfb, 0x30, 0xe4, 0xb6, 0xea, 0xb9, 0x37, 0xfe, 0x5c, 0x0f, 0x8c,
+ /*6fb0:*/ 0x1b, 0xae, 0x0a, 0x82, 0xc6, 0x00, 0x2c, 0x9c, 0xca, 0xb2, 0x44, 0xc0, 0x87, 0x5d, 0x9e, 0x81,
+ /*6fc0:*/ 0x0b, 0x08, 0x2d, 0xf0, 0xde, 0x57, 0xd7, 0x67, 0x02, 0xf8, 0x8d, 0x14, 0x4e, 0x37, 0xef, 0x06,
+ /*6fd0:*/ 0x7b, 0xfe, 0x96, 0x0f, 0x7b, 0xc0, 0x28, 0xe6, 0x4e, 0x88, 0xba, 0xc9, 0x78, 0x3c, 0x3e, 0x35,
+ /*6fe0:*/ 0x82, 0x92, 0x27, 0x11, 0x95, 0x5d, 0x4b, 0x3d, 0xb6, 0x70, 0x57, 0x05, 0xfd, 0x2f, 0x8a, 0xd4,
+ /*6ff0:*/ 0xa4, 0xd5, 0x80, 0x1f, 0xde, 0xb8, 0x8c, 0xaa, 0x46, 0x75, 0x23, 0x34, 0x7a, 0x67, 0xf5, 0x08,
+ /*7000:*/ 0xed, 0x66, 0xd7, 0x1e, 0x1d, 0x17, 0x75, 0x41, 0x8e, 0xaa, 0x72, 0x6b, 0xeb, 0x46, 0x33, 0x33,
+ /*7010:*/ 0x5b, 0xb4, 0x19, 0x3f, 0x1b, 0x51, 0xdf, 0x9c, 0x74, 0x3a, 0x8c, 0x43, 0x72, 0xf6, 0xf4, 0xb4,
+ /*7020:*/ 0x53, 0x29, 0x76, 0x5f, 0x71, 0x61, 0x79, 0x8a, 0x29, 0xe7, 0x06, 0x81, 0xe2, 0xc7, 0xd4, 0x4d,
+ /*7030:*/ 0x86, 0x5a, 0xcb, 0xf8, 0xcd, 0x90, 0x0d, 0x7c, 0x72, 0x04, 0xf3, 0xc0, 0x0a, 0x7f, 0xb1, 0xca,
+ /*7040:*/ 0xab, 0x5c, 0x81, 0x6a, 0x66, 0x1e, 0x09, 0x66, 0xbd, 0x39, 0x3b, 0xec, 0x9e, 0xa1, 0xf7, 0xfa,
+ /*7050:*/ 0x1d, 0xbe, 0x5c, 0x31, 0x08, 0xcd, 0x9b, 0x32, 0xf7, 0x1f, 0x50, 0x3a, 0x59, 0xbd, 0x6a, 0xa0,
+ /*7060:*/ 0xea, 0xcc, 0xcd, 0x50, 0x2c, 0x54, 0x5b, 0x2d, 0x0f, 0xc2, 0x68, 0xe4, 0xe1, 0x2c, 0xf9, 0xbf,
+ /*7070:*/ 0x50, 0x55, 0x2c, 0x53, 0x9a, 0x07, 0xb2, 0xe4, 0x9d, 0x0f, 0xde, 0xc4, 0x9e, 0xe5, 0xe8, 0x26,
+ /*7080:*/ 0xb3, 0x7a, 0x40, 0x35, 0xc1, 0x1b, 0x28, 0xc0, 0xe4, 0x83, 0x07, 0x32, 0xc0, 0xfb, 0xb5, 0x68,
+ /*7090:*/ 0xba, 0xf2, 0xab, 0xe2, 0xe5, 0xaf, 0x17, 0x4e, 0x0a, 0x9d, 0xf9, 0x7d, 0x8a, 0x8b, 0xc4, 0x5d,
+ /*70a0:*/ 0x36, 0x14, 0xe2, 0x96, 0x91, 0xd2, 0x3d, 0x39, 0x6e, 0xda, 0xb4, 0xe3, 0xcb, 0x43, 0x73, 0xb4,
+ /*70b0:*/ 0x99, 0xa2, 0x4a, 0x4b, 0x78, 0x35, 0x09, 0xe6, 0x37, 0xa7, 0xe3, 0xf5, 0x1b, 0xac, 0x0e, 0x0f,
+ /*70c0:*/ 0x84, 0xd4, 0xd3, 0xf8, 0x37, 0xee, 0x8d, 0x80, 0x6a, 0xd0, 0xd5, 0xb6, 0x67, 0xeb, 0x4b, 0xc0,
+ /*70d0:*/ 0x69, 0x9f, 0xe6, 0x45, 0xb8, 0xe0, 0x84, 0x3c, 0xe3, 0xab, 0x9e, 0xd7, 0x83, 0x5b, 0x75, 0x48,
+ /*70e0:*/ 0xdd, 0xde, 0x89, 0x82, 0x1e, 0x68, 0x96, 0x20, 0x29, 0x3b, 0xa8, 0x8a, 0xfc, 0xd3, 0x85, 0x69,
+ /*70f0:*/ 0x3a, 0x94, 0x7e, 0x1c, 0xe1, 0x00, 0xb8, 0xdf, 0xe7, 0xa8, 0x5f, 0x87, 0xce, 0x95, 0xf1, 0xb7,
+ /*7100:*/ 0x69, 0x97, 0xac, 0x98, 0xdb, 0x50, 0x77, 0x37, 0x99, 0xae, 0xe8, 0x7e, 0xb1, 0x95, 0xf3, 0x10,
+ /*7110:*/ 0x8b, 0x97, 0x7d, 0xfd, 0x2b, 0x9c, 0xb5, 0x09, 0x5f, 0x9d, 0x0a, 0xa1, 0x08, 0x37, 0x89, 0xe4,
+ /*7120:*/ 0x17, 0xaf, 0xd3, 0x33, 0xd2, 0xe5, 0x33, 0x9a, 0xe1, 0xab, 0x83, 0xdc, 0x20, 0xdd, 0xe1, 0xdf,
+ /*7130:*/ 0x25, 0x7d, 0x72, 0x29, 0x7e, 0x69, 0x97, 0x69, 0xd4, 0xdc, 0x8b, 0xda, 0x92, 0x99, 0x21, 0xec,
+ /*7140:*/ 0xe1, 0x3c, 0x7f, 0x9c, 0xc3, 0xac, 0x3a, 0x55, 0xde, 0x82, 0xb7, 0x98, 0x1f, 0xd3, 0xa9, 0x7c,
+ /*7150:*/ 0xdb, 0x71, 0x5b, 0xd8, 0xe9, 0xb9, 0x01, 0x0d, 0xb7, 0x36, 0x9d, 0xa4, 0xde, 0x90, 0x57, 0x43,
+ /*7160:*/ 0x88, 0xdf, 0xd4, 0xaf, 0xbf, 0xd1, 0x4d, 0xdd, 0x25, 0xd1, 0xf0, 0x6b, 0x99, 0xc2, 0x1e, 0xda,
+ /*7170:*/ 0x22, 0x52, 0xc1, 0xbc, 0x09, 0xbd, 0xdf, 0x2b, 0x76, 0xfc, 0xbf, 0xc4, 0x43, 0x0b, 0x8f, 0x22,
+ /*7180:*/ 0x09, 0x8d, 0x31, 0x30, 0x82, 0x56, 0x96, 0x5d, 0x65, 0xa5, 0x1f, 0xa2, 0x6c, 0x18, 0x95, 0x07,
+ /*7190:*/ 0x5f, 0xd1, 0xa5, 0x6b, 0xbc, 0x7a, 0xbb, 0x90, 0xbb, 0x75, 0xc6, 0xba, 0xac, 0xcb, 0x78, 0x3c,
+ /*71a0:*/ 0xa2, 0x10, 0x68, 0x07, 0x5a, 0xf5, 0x61, 0xc9, 0x44, 0x90, 0x44, 0x2c, 0xe3, 0x00, 0x2d, 0xb1,
+ /*71b0:*/ 0x52, 0x64, 0x27, 0xd2, 0x0a, 0xc2, 0x0c, 0x75, 0x67, 0x5b, 0xaf, 0xea, 0x5f, 0xbe, 0xea, 0x35,
+ /*71c0:*/ 0x88, 0x19, 0x2d, 0x1c, 0xa5, 0x84, 0x06, 0xc5, 0x5c, 0x95, 0xc7, 0x4c, 0x30, 0xf1, 0x06, 0xed,
+ /*71d0:*/ 0xa9, 0x41, 0x66, 0x5e, 0x2c, 0x97, 0x8a, 0x87, 0x5e, 0xb6, 0xee, 0x5e, 0x86, 0xf4, 0xd0, 0xf2,
+ /*71e0:*/ 0x47, 0x1f, 0x3b, 0x1e, 0xc2, 0xfa, 0x49, 0x50, 0x28, 0x80, 0xd1, 0x9e, 0xf5, 0x5c, 0x55, 0xee,
+ /*71f0:*/ 0x1c, 0x49, 0x6d, 0xd2, 0xf2, 0x81, 0x3e, 0x19, 0x2a, 0x35, 0xd4, 0xae, 0xd2, 0xe8, 0xf7, 0x9f,
+ /*7200:*/ 0x08, 0x95, 0x97, 0x15, 0xb1, 0x16, 0x3e, 0xb3, 0x43, 0xf1, 0x95, 0xbf, 0xc8, 0x7b, 0xa9, 0x09,
+ /*7210:*/ 0xd5, 0x82, 0x6b, 0x0c, 0x4a, 0xe0, 0x74, 0xa7, 0xd8, 0x3d, 0x21, 0x9c, 0xf4, 0x9f, 0xf1, 0xa0,
+ /*7220:*/ 0x13, 0x7c, 0x48, 0x0d, 0x2c, 0x8b, 0xb7, 0x71, 0xb7, 0xe5, 0x1c, 0x30, 0x36, 0xe8, 0x2a, 0x72,
+ /*7230:*/ 0x92, 0x9b, 0xf0, 0x92, 0xdc, 0x9d, 0x3f, 0xd3, 0x3e, 0xe3, 0xc3, 0x22, 0xff, 0x20, 0x06, 0x91,
+ /*7240:*/ 0x7f, 0x39, 0xe4, 0x99, 0x68, 0xd2, 0xaa, 0x0b, 0x1c, 0x1c, 0xc2, 0x3b, 0xa0, 0x0b, 0x65, 0x47,
+ /*7250:*/ 0xf9, 0x25, 0x8e, 0xac, 0x71, 0x8f, 0x17, 0x4d, 0xed, 0x64, 0x35, 0xb8, 0x4f, 0x28, 0x90, 0x1d,
+ /*7260:*/ 0x44, 0x9b, 0xb3, 0xe5, 0x42, 0x5b, 0x77, 0x47, 0x3c, 0x17, 0x38, 0x9d, 0x13, 0xe7, 0xca, 0x9e,
+ /*7270:*/ 0xf1, 0x86, 0xcf, 0xe3, 0x21, 0x35, 0x9a, 0x3d, 0x9b, 0x0e, 0x40, 0xf7, 0x56, 0x30, 0x22, 0x48,
+ /*7280:*/ 0x0b, 0xd6, 0xae, 0x1b, 0xf9, 0x2d, 0xbd, 0x62, 0x4f, 0xc7, 0xd3, 0x59, 0x0a, 0x26, 0xc9, 0xc8,
+ /*7290:*/ 0x0e, 0xe0, 0x28, 0x8a, 0x8d, 0x46, 0x42, 0x48, 0xea, 0x78, 0x8d, 0x51, 0x3c, 0x34, 0x84, 0x96,
+ /*72a0:*/ 0x3e, 0xcc, 0xf0, 0x98, 0x94, 0x68, 0x81, 0xed, 0xd3, 0xe1, 0x0d, 0x46, 0x3d, 0xcb, 0xea, 0xf0,
+ /*72b0:*/ 0xc6, 0x7e, 0x15, 0x97, 0x86, 0x0d, 0xd0, 0x84, 0xcb, 0x1b, 0xa6, 0x0e, 0xce, 0xa4, 0x7c, 0xbd,
+ /*72c0:*/ 0x65, 0x0c, 0x9f, 0x98, 0x7d, 0x13, 0x8e, 0x7a, 0x0a, 0xa9, 0xa7, 0x20, 0x3b, 0xa1, 0x4b, 0xda,
+ /*72d0:*/ 0xe7, 0x8a, 0x2e, 0x3f, 0xe2, 0xff, 0x11, 0xb7, 0x08, 0x8b, 0x80, 0xc9, 0xa1, 0xb4, 0xf6, 0xde,
+ /*72e0:*/ 0xce, 0x58, 0xb7, 0xf6, 0x5e, 0x73, 0xdb, 0xfe, 0x18, 0x87, 0x1e, 0x45, 0xe7, 0xa1, 0x84, 0xc2,
+ /*72f0:*/ 0xfa, 0x6a, 0x90, 0x4b, 0x4e, 0x41, 0x28, 0xc0, 0x1c, 0xb7, 0x1d, 0xc2, 0xb6, 0xa2, 0x0b, 0x08,
+ /*7300:*/ 0x0b, 0x61, 0xcb, 0xf6, 0xd6, 0xa1, 0x3a, 0x36, 0x23, 0x9b, 0x5c, 0x08, 0x91, 0x34, 0xfa, 0xc5,
+ /*7310:*/ 0x46, 0x0c, 0x54, 0x67, 0x59, 0x7f, 0x90, 0xc3, 0x05, 0x58, 0x3a, 0xee, 0x28, 0x62, 0x7b, 0xf7,
+ /*7320:*/ 0x25, 0xd5, 0x31, 0x6c, 0x03, 0x15, 0x7a, 0xf5, 0x3d, 0xd5, 0x53, 0x5a, 0xe6, 0xd3, 0x95, 0x6d,
+ /*7330:*/ 0x56, 0xb9, 0x8b, 0x3a, 0xca, 0x52, 0xe5, 0xe2, 0x6d, 0xfe, 0xf0, 0x39, 0x54, 0x7c, 0xdc, 0x10,
+ /*7340:*/ 0xd5, 0x46, 0xe3, 0x3b, 0xad, 0x1a, 0x3b, 0x49, 0x55, 0x28, 0x7a, 0x03, 0x3e, 0x0f, 0x4e, 0x11,
+ /*7350:*/ 0x64, 0x1b, 0x27, 0xa5, 0x63, 0x48, 0x70, 0x41, 0xff, 0x45, 0x85, 0x91, 0xce, 0x5b, 0xbb, 0x69,
+ /*7360:*/ 0x84, 0x15, 0x9d, 0x80, 0xf1, 0x1e, 0xad, 0x8e, 0xca, 0x73, 0x6c, 0x9a, 0x15, 0xd8, 0x47, 0xc1,
+ /*7370:*/ 0x99, 0x46, 0x4a, 0xd1, 0x70, 0x03, 0x24, 0x59, 0x1c, 0x42, 0x43, 0xf0, 0x6d, 0x49, 0xb9, 0xe0,
+ /*7380:*/ 0x1a, 0x20, 0x4e, 0x53, 0x08, 0x12, 0x31, 0x45, 0x11, 0xdf, 0xd5, 0x40, 0x42, 0xf5, 0x96, 0xa8,
+ /*7390:*/ 0x6c, 0x00, 0x0f, 0xbc, 0x92, 0xdc, 0xb3, 0x08, 0x15, 0xd6, 0x36, 0xff, 0x6b, 0x34, 0xfc, 0x42,
+ /*73a0:*/ 0x90, 0x30, 0x27, 0x6d, 0xf5, 0x65, 0x3c, 0x49, 0x22, 0x0c, 0x26, 0x6c, 0x8a, 0xb7, 0x26, 0xf0,
+ /*73b0:*/ 0xec, 0xcc, 0x00, 0x5f, 0xbd, 0x54, 0x31, 0x04, 0xe6, 0x9c, 0xe4, 0x54, 0x7b, 0x3e, 0x41, 0xe6,
+ /*73c0:*/ 0xcd, 0xda, 0x15, 0x1c, 0xaa, 0xb7, 0x27, 0x5f, 0xfd, 0xf6, 0xde, 0x9f, 0x04, 0xdd, 0x0e, 0xad,
+ /*73d0:*/ 0xda, 0xda, 0x34, 0xd0, 0x61, 0x64, 0xfa, 0x34, 0x3a, 0x9e, 0x8b, 0xb7, 0xaa, 0x35, 0x00, 0xa8,
+ /*73e0:*/ 0x94, 0x62, 0xbc, 0xac, 0xcb, 0x94, 0xeb, 0x92, 0x66, 0xc5, 0xc5, 0x54, 0x05, 0xb7, 0x86, 0x6c,
+ /*73f0:*/ 0x98, 0xa5, 0xa6, 0xd4, 0x83, 0xf0, 0x0c, 0x80, 0xa2, 0x82, 0x8c, 0x51, 0x31, 0xad, 0xe0, 0xa0,
+ /*7400:*/ 0x95, 0x71, 0xd1, 0xb4, 0x12, 0xd5, 0xcd, 0x25, 0x2f, 0x09, 0xa3, 0xd5, 0x1c, 0xe4, 0x4c, 0x73,
+ /*7410:*/ 0x94, 0x19, 0x1f, 0xe5, 0xcb, 0x66, 0xfa, 0x14, 0xaa, 0x1c, 0xdf, 0xdb, 0x48, 0x95, 0x9c, 0x20,
+ /*7420:*/ 0xd8, 0xb3, 0x46, 0xc9, 0xc7, 0xf6, 0x0e, 0x63, 0x1c, 0xec, 0x4e, 0xbe, 0xdd, 0x08, 0xdb, 0x94,
+ /*7430:*/ 0x2d, 0x38, 0x86, 0xae, 0xd3, 0x76, 0x04, 0xb2, 0xc1, 0x0e, 0x63, 0x6c, 0x22, 0xd5, 0xc9, 0x7f,
+ /*7440:*/ 0x6f, 0x83, 0x54, 0x52, 0x9f, 0xc5, 0x0a, 0x43, 0xa1, 0xa8, 0x9c, 0x4a, 0x1e, 0x7a, 0x2f, 0xcf,
+ /*7450:*/ 0x56, 0x9a, 0x46, 0x83, 0xc0, 0x2e, 0x43, 0x62, 0x54, 0x16, 0x37, 0xdd, 0x9e, 0xcf, 0xcb, 0xc5,
+ /*7460:*/ 0xe1, 0x8e, 0x5f, 0x83, 0xc8, 0xac, 0x6e, 0xb3, 0xcf, 0xdc, 0x3d, 0x14, 0xb0, 0x99, 0x25, 0x47,
+ /*7470:*/ 0x1f, 0xd6, 0xa9, 0xe3, 0x8f, 0x29, 0x98, 0x6d, 0xf5, 0xac, 0x2d, 0x6b, 0x07, 0x15, 0x71, 0xa0,
+ /*7480:*/ 0x4b, 0x5d, 0xd7, 0x5f, 0x55, 0xcc, 0xca, 0xd2, 0x9e, 0xd5, 0x8c, 0x42, 0x61, 0xaf, 0xee, 0x46,
+ /*7490:*/ 0x2d, 0x10, 0xce, 0x31, 0xf8, 0xeb, 0x96, 0xdd, 0x29, 0x1d, 0xb6, 0x75, 0x79, 0x85, 0xf6, 0xc9,
+ /*74a0:*/ 0x28, 0x17, 0x8c, 0x23, 0x56, 0x0e, 0xc0, 0xb2, 0x96, 0xdf, 0x21, 0xbf, 0x14, 0x8b, 0x3e, 0xe3,
+ /*74b0:*/ 0x21, 0xe1, 0x48, 0x07, 0x1c, 0x47, 0x8d, 0x12, 0xc2, 0xdd, 0xfd, 0x8e, 0x22, 0xbf, 0x68, 0xa9,
+ /*74c0:*/ 0xe1, 0x2e, 0x96, 0x3a, 0x1d, 0xa0, 0x7e, 0x94, 0xfa, 0x9c, 0xbb, 0x72, 0xf2, 0xa1, 0xc7, 0x17,
+ /*74d0:*/ 0x65, 0x8a, 0xb6, 0x8f, 0xdf, 0x18, 0xdd, 0x27, 0x11, 0x9d, 0x32, 0xdf, 0x9d, 0xb1, 0x00, 0x83,
+ /*74e0:*/ 0x00, 0xe3, 0x2c, 0xc1, 0xd5, 0x6e, 0x7d, 0x05, 0x4e, 0x93, 0x48, 0x03, 0x86, 0x3c, 0xe7, 0xe2,
+ /*74f0:*/ 0x5a, 0x59, 0x25, 0x4e, 0xa9, 0xb5, 0x6a, 0x27, 0x3e, 0x06, 0x75, 0xea, 0xca, 0x1a, 0x70, 0x20,
+ /*7500:*/ 0xbb, 0x04, 0xca, 0x0d, 0x7c, 0xe3, 0x3e, 0x0b, 0xe7, 0xdb, 0xeb, 0xbe, 0x41, 0x4d, 0x04, 0xd5,
+ /*7510:*/ 0x6f, 0xa2, 0x2c, 0x42, 0x5f, 0xc5, 0x6b, 0x66, 0x10, 0xf4, 0xb9, 0x14, 0x44, 0x7d, 0xfc, 0xa3,
+ /*7520:*/ 0x42, 0x95, 0x2b, 0xc3, 0x9e, 0x31, 0x75, 0x8f, 0x92, 0x25, 0xfa, 0xf5, 0xde, 0x86, 0x5f, 0x57,
+ /*7530:*/ 0xa8, 0x26, 0x41, 0x39, 0xc9, 0xc7, 0x56, 0x1f, 0x4a, 0x52, 0x7a, 0x25, 0x82, 0x1d, 0xa2, 0xd1,
+ /*7540:*/ 0xcd, 0x35, 0xa4, 0x1b, 0x73, 0xd8, 0x8e, 0x17, 0x2d, 0xfb, 0x49, 0x60, 0x54, 0x60, 0x1a, 0x7d,
+ /*7550:*/ 0x16, 0xe3, 0x8a, 0xa5, 0xd0, 0x2f, 0x81, 0xc7, 0xb4, 0x75, 0xb6, 0xba, 0xfc, 0xae, 0x96, 0x25,
+ /*7560:*/ 0x4e, 0xba, 0x0d, 0x8a, 0x22, 0x59, 0xe8, 0xa3, 0xd3, 0xb0, 0x87, 0xc1, 0xa7, 0x72, 0x07, 0x51,
+ /*7570:*/ 0x60, 0xed, 0x1c, 0xd3, 0xb1, 0x2d, 0xfb, 0xb5, 0xbc, 0xb4, 0x01, 0x22, 0x0e, 0xfe, 0x75, 0xfa,
+ /*7580:*/ 0x9a, 0x4b, 0xe2, 0xb3, 0x89, 0xb9, 0xe9, 0x58, 0x63, 0xf5, 0x14, 0xec, 0x1f, 0x18, 0x4c, 0x3a,
+ /*7590:*/ 0xf0, 0xfd, 0x0f, 0x75, 0x29, 0x40, 0x51, 0x7e, 0x39, 0xfd, 0x74, 0xa1, 0xf5, 0x7d, 0xf5, 0x6b,
+ /*75a0:*/ 0x15, 0x91, 0xf1, 0xd5, 0x72, 0x23, 0x07, 0x58, 0xd8, 0x7b, 0x85, 0xe3, 0x66, 0x31, 0x2b, 0x8a,
+ /*75b0:*/ 0xa4, 0x79, 0x58, 0x71, 0x43, 0xdb, 0x81, 0xdd, 0xb4, 0x49, 0x7d, 0x6c, 0xd7, 0xea, 0x6c, 0x07,
+ /*75c0:*/ 0x01, 0xfe, 0x6b, 0x50, 0x43, 0x49, 0x37, 0xd4, 0x63, 0x4f, 0xaa, 0x59, 0x44, 0xa1, 0x89, 0xac,
+ /*75d0:*/ 0x4c, 0x41, 0x7c, 0x0a, 0x30, 0x95, 0xa9, 0xb1, 0x4b, 0x64, 0x1e, 0x5c, 0x4b, 0xee, 0xe0, 0x0c,
+ /*75e0:*/ 0x7b, 0xa0, 0xc8, 0x8b, 0x3c, 0xe7, 0xec, 0x19, 0xc1, 0x9b, 0x06, 0x1c, 0xae, 0x83, 0x11, 0xc4,
+ /*75f0:*/ 0x48, 0xb7, 0xda, 0x18, 0xd7, 0xf3, 0x77, 0x32, 0xf4, 0x15, 0xc3, 0x62, 0x0a, 0x01, 0x98, 0x5a,
+ /*7600:*/ 0x5f, 0x43, 0xfb, 0x25, 0x23, 0xde, 0xfe, 0xdb, 0x2c, 0x88, 0xaa, 0x5e, 0x57, 0xcc, 0x33, 0x3c,
+ /*7610:*/ 0x66, 0x4a, 0x85, 0x4f, 0xfe, 0xf3, 0x72, 0x2e, 0xba, 0x3e, 0x4c, 0x31, 0x7e, 0x48, 0xe4, 0xe3,
+ /*7620:*/ 0x2d, 0x6e, 0xbc, 0x1c, 0x0f, 0x88, 0x58, 0x12, 0x35, 0xfa, 0x3f, 0xe0, 0xe2, 0xc9, 0x62, 0xee,
+ /*7630:*/ 0xe3, 0x5d, 0x3b, 0x33, 0x21, 0x14, 0x29, 0x3f, 0x99, 0x5d, 0x81, 0x54, 0x27, 0xb8, 0xba, 0xc6,
+ /*7640:*/ 0xcb, 0x61, 0x60, 0x74, 0xee, 0xbc, 0x9b, 0xa7, 0x43, 0x5a, 0x05, 0xcb, 0x7b, 0x82, 0x80, 0xe3,
+ /*7650:*/ 0xea, 0xed, 0x26, 0x35, 0xa9, 0x0f, 0xb8, 0xf3, 0x3f, 0x6b, 0x06, 0xd7, 0x91, 0x7a, 0x29, 0x1f,
+ /*7660:*/ 0x37, 0x2e, 0x7a, 0xac, 0x48, 0xda, 0x47, 0x0f, 0x39, 0x50, 0x38, 0xa7, 0x3d, 0x3b, 0x4e, 0xbf,
+ /*7670:*/ 0x78, 0x1c, 0x62, 0x97, 0x46, 0xd9, 0x9a, 0x34, 0x68, 0x9e, 0x2d, 0x60, 0x8e, 0x74, 0xfd, 0xfa,
+ /*7680:*/ 0xf1, 0xad, 0x01, 0x6f, 0x71, 0xc5, 0xc1, 0xc0, 0x2c, 0x34, 0x3e, 0xe9, 0x26, 0xeb, 0xa6, 0xce,
+ /*7690:*/ 0xf7, 0x9c, 0x25, 0x0b, 0x9f, 0x38, 0x54, 0xda, 0x17, 0xf5, 0x57, 0x7e, 0xfc, 0xd2, 0x60, 0xaf,
+ /*76a0:*/ 0x67, 0x58, 0x29, 0x71, 0x49, 0xeb, 0x4e, 0x91, 0x01, 0x42, 0x35, 0xd6, 0x18, 0x77, 0x72, 0xb4,
+ /*76b0:*/ 0xad, 0x56, 0xde, 0xa7, 0x36, 0x13, 0xfd, 0x7d, 0x8b, 0xe3, 0xf3, 0x5d, 0xb5, 0xb5, 0x8e, 0x30,
+ /*76c0:*/ 0x60, 0x44, 0x24, 0x9f, 0x34, 0xc0, 0x55, 0xf7, 0xab, 0xd1, 0x50, 0xfa, 0x3b, 0x92, 0x84, 0x90,
+ /*76d0:*/ 0xc0, 0xc3, 0xca, 0x33, 0xec, 0x34, 0x88, 0x29, 0xcd, 0x62, 0xc9, 0xd6, 0xda, 0x1c, 0x36, 0x57,
+ /*76e0:*/ 0x33, 0x6a, 0xe5, 0x11, 0x52, 0x63, 0xed, 0xcf, 0x63, 0x07, 0x34, 0x72, 0xf5, 0xf8, 0xc2, 0xba,
+ /*76f0:*/ 0xd5, 0x20, 0xde, 0xcc, 0x8f, 0xc6, 0xf1, 0x20, 0x2b, 0x34, 0x78, 0xfb, 0x73, 0x42, 0x98, 0xa8,
+ /*7700:*/ 0x69, 0x4c, 0x1e, 0xd1, 0xdb, 0x9a, 0xe6, 0x3c, 0x68, 0x79, 0x10, 0x5f, 0xbb, 0xbc, 0x4f, 0x54,
+ /*7710:*/ 0x58, 0x0c, 0xee, 0x5e, 0x83, 0x47, 0x29, 0xd7, 0xee, 0xc7, 0xea, 0xc9, 0xd3, 0x94, 0xc5, 0x7a,
+ /*7720:*/ 0x73, 0xfd, 0x72, 0x43, 0x15, 0x7f, 0xfb, 0x5d, 0x05, 0x2f, 0x3a, 0x69, 0x9e, 0x58, 0xcc, 0xd3,
+ /*7730:*/ 0xf5, 0xbd, 0x47, 0x6f, 0xbd, 0x63, 0xfb, 0xbb, 0x5f, 0xe5, 0xa0, 0x28, 0x88, 0x29, 0x05, 0xa0,
+ /*7740:*/ 0x1d, 0xbc, 0x48, 0xd9, 0xbc, 0xd5, 0xa0, 0xcc, 0x27, 0x46, 0xf2, 0xca, 0xee, 0xe9, 0x6b, 0xa3,
+ /*7750:*/ 0x63, 0xed, 0xf5, 0xe8, 0x5e, 0x1b, 0x1d, 0x91, 0xa4, 0x50, 0xb1, 0x61, 0x95, 0x53, 0xb4, 0xd6,
+ /*7760:*/ 0xda, 0x3d, 0x56, 0x92, 0xbb, 0x85, 0x79, 0x86, 0x1d, 0x32, 0xcd, 0xeb, 0xfd, 0x86, 0x57, 0x2f,
+ /*7770:*/ 0x35, 0xd1, 0x6d, 0xd8, 0xab, 0x6a, 0x86, 0xec, 0xa3, 0xe9, 0x9b, 0x1b, 0xa7, 0x24, 0x1c, 0xc4,
+ /*7780:*/ 0xad, 0x5d, 0xc4, 0x71, 0xad, 0xe5, 0xff, 0xcf, 0x6e, 0xf8, 0x7b, 0xfb, 0x24, 0xb3, 0xe7, 0x49,
+ /*7790:*/ 0x6d, 0xe0, 0xfa, 0xe2, 0x32, 0xfc, 0xcb, 0xb8, 0x10, 0x30, 0x8b, 0x57, 0x45, 0x0c, 0xe6, 0x40,
+ /*77a0:*/ 0x45, 0x52, 0xbf, 0xab, 0x4d, 0x16, 0xc9, 0x89, 0x67, 0x3f, 0xb7, 0x01, 0x65, 0x3e, 0xa8, 0x60,
+ /*77b0:*/ 0x7d, 0x02, 0x1e, 0xba, 0xe7, 0x3d, 0x01, 0x7e, 0x84, 0x60, 0xce, 0xed, 0xac, 0xc3, 0x20, 0x4b,
+ /*77c0:*/ 0x2b, 0xcd, 0x7c, 0x48, 0xbe, 0xeb, 0x62, 0x4b, 0x1e, 0xea, 0x14, 0x52, 0xe9, 0xe5, 0xc0, 0xe7,
+ /*77d0:*/ 0xf8, 0x38, 0xf9, 0x9d, 0xaa, 0x1c, 0x5a, 0x45, 0xf7, 0x17, 0x34, 0xc4, 0xcd, 0x20, 0xa7, 0xa4,
+ /*77e0:*/ 0x63, 0xd8, 0xbd, 0x4b, 0xf1, 0xdb, 0x91, 0x00, 0xd7, 0x2e, 0x65, 0xa9, 0xbd, 0x50, 0xe5, 0x0a,
+ /*77f0:*/ 0xda, 0x2f, 0x8f, 0x30, 0xc2, 0xf3, 0xf1, 0xa5, 0x7f, 0x36, 0x82, 0x18, 0xb7, 0xbb, 0x28, 0xb5,
+ /*7800:*/ 0xd5, 0x8d, 0x06, 0xcb, 0x99, 0x9a, 0xa6, 0xc5, 0x56, 0xfe, 0xca, 0x08, 0x92, 0x79, 0x32, 0xdd,
+ /*7810:*/ 0xbc, 0x82, 0x04, 0x70, 0x2c, 0xfd, 0x26, 0x47, 0x0c, 0xa2, 0x4c, 0xf5, 0xb3, 0x86, 0x86, 0xdf,
+ /*7820:*/ 0xd0, 0x43, 0x37, 0xd4, 0x5c, 0x34, 0xae, 0x35, 0x13, 0xc1, 0xc5, 0xa8, 0xca, 0x63, 0x8e, 0xb6,
+ /*7830:*/ 0xb3, 0xb5, 0x1d, 0xd0, 0x79, 0x77, 0xef, 0x84, 0x88, 0xf0, 0xba, 0xe9, 0xd0, 0x9a, 0x6c, 0x55,
+ /*7840:*/ 0xa0, 0xd9, 0x0e, 0x5d, 0x9e, 0x6d, 0x6e, 0x1f, 0x9d, 0xcc, 0x1c, 0x68, 0x16, 0xa5, 0xe5, 0x86,
+ /*7850:*/ 0x24, 0x83, 0x2b, 0xb7, 0xc6, 0xac, 0xa4, 0xa7, 0x38, 0xca, 0xdf, 0xec, 0x9e, 0x7c, 0x7d, 0x63,
+ /*7860:*/ 0x6e, 0x5e, 0xb2, 0x59, 0x24, 0xb5, 0xed, 0x8e, 0xa7, 0xf0, 0x63, 0x85, 0x48, 0x73, 0x6c, 0xa8,
+ /*7870:*/ 0xe6, 0x95, 0x6c, 0xd6, 0xf4, 0x7e, 0xdc, 0xa2, 0x61, 0x00, 0xf1, 0x9f, 0xf4, 0x51, 0x5b, 0x1a,
+ /*7880:*/ 0x47, 0xdc, 0x57, 0x16, 0xf1, 0x8f, 0x0c, 0xfa, 0xa3, 0xb3, 0x3d, 0xe8, 0xd5, 0xc8, 0x6a, 0x52,
+ /*7890:*/ 0xb8, 0xcb, 0x57, 0x9a, 0x81, 0xb3, 0x5e, 0x47, 0xb2, 0xcb, 0x64, 0x7e, 0x2f, 0x92, 0xb2, 0x57,
+ /*78a0:*/ 0xd1, 0x3a, 0x9f, 0x6f, 0xc6, 0xeb, 0x5e, 0xbf, 0x84, 0xf9, 0x7d, 0x31, 0x63, 0x96, 0x3d, 0x4c,
+ /*78b0:*/ 0x17, 0x38, 0x91, 0xd3, 0xde, 0xe6, 0x04, 0xf6, 0xe9, 0xa2, 0x7e, 0xd6, 0xe9, 0xd4, 0x50, 0x61,
+ /*78c0:*/ 0x5c, 0x75, 0x57, 0xee, 0x7e, 0x03, 0xe9, 0x06, 0x8c, 0x57, 0x4a, 0x8d, 0xc8, 0x54, 0x08, 0xca,
+ /*78d0:*/ 0x17, 0xa8, 0x9c, 0x27, 0x28, 0xc3, 0xe4, 0x85, 0xd1, 0x2d, 0x33, 0x44, 0x74, 0xc6, 0x50, 0x42,
+ /*78e0:*/ 0xd9, 0x29, 0x00, 0x38, 0xa4, 0xe6, 0xb9, 0xf3, 0xfa, 0x40, 0xb9, 0x83, 0x20, 0xed, 0x22, 0xb7,
+ /*78f0:*/ 0xf0, 0xf4, 0xe7, 0x10, 0x73, 0xc3, 0xe9, 0x5a, 0xe6, 0xed, 0x21, 0x7e, 0x7c, 0xc6, 0x78, 0x00,
+ /*7900:*/ 0x94, 0x02, 0x42, 0x91, 0xa0, 0x24, 0x71, 0x85, 0x14, 0x97, 0x94, 0xfa, 0x75, 0x84, 0xbc, 0x36,
+ /*7910:*/ 0xd1, 0x69, 0xb3, 0x13, 0xf2, 0x67, 0x0a, 0xc3, 0xcf, 0xe5, 0x4c, 0x9f, 0x49, 0xc3, 0xc2, 0x35,
+ /*7920:*/ 0xdf, 0xb2, 0xb5, 0x0e, 0xf6, 0x05, 0x77, 0x6e, 0x5f, 0x84, 0x58, 0x8c, 0x99, 0xee, 0xb4, 0xe7,
+ /*7930:*/ 0x38, 0xa1, 0xa6, 0x31, 0x62, 0x20, 0x1f, 0x13, 0x4b, 0xc8, 0x44, 0x6b, 0x06, 0x3d, 0xd3, 0x69,
+ /*7940:*/ 0x89, 0x24, 0xa1, 0xa3, 0x78, 0x1f, 0x0b, 0x49, 0x0b, 0x59, 0xa7, 0x75, 0x02, 0x13, 0x33, 0xe2,
+ /*7950:*/ 0x5c, 0x20, 0x5b, 0xe5, 0x92, 0x61, 0x7a, 0x82, 0xaf, 0x4a, 0x08, 0x91, 0xc8, 0x1f, 0x66, 0xd5,
+ /*7960:*/ 0xf8, 0x3b, 0xb3, 0x65, 0xcf, 0xc6, 0x01, 0xfa, 0x32, 0x27, 0xfe, 0xec, 0x0f, 0xbf, 0xd0, 0x99,
+ /*7970:*/ 0xf5, 0x5b, 0xd0, 0x78, 0xa3, 0x0f, 0x0d, 0xac, 0x12, 0x6c, 0xa5, 0x50, 0xc5, 0x89, 0x32, 0x5e,
+ /*7980:*/ 0x9f, 0x76, 0xcf, 0x66, 0x81, 0xca, 0xdf, 0x7a, 0x29, 0xf3, 0x1b, 0xe9, 0xfb, 0x53, 0x68, 0x72,
+ /*7990:*/ 0xdf, 0x88, 0x6a, 0xbb, 0x55, 0x9b, 0xd2, 0x8f, 0xca, 0x84, 0xcd, 0x66, 0x67, 0x37, 0x04, 0x20,
+ /*79a0:*/ 0x99, 0xb2, 0x70, 0x70, 0x50, 0x93, 0x54, 0x27, 0x7f, 0xe2, 0x9e, 0x9e, 0xaf, 0xe6, 0xd0, 0x4a,
+ /*79b0:*/ 0x8c, 0x64, 0x3e, 0xfe, 0xb7, 0xbf, 0xdf, 0x0a, 0x86, 0x72, 0xf2, 0x9f, 0x96, 0xdb, 0x13, 0x73,
+ /*79c0:*/ 0x75, 0xfe, 0x7e, 0xa8, 0xce, 0xa4, 0x24, 0x54, 0xe2, 0x72, 0x76, 0xfa, 0x75, 0x23, 0xd6, 0xa9,
+ /*79d0:*/ 0x63, 0xf0, 0x5a, 0xdf, 0x80, 0xb7, 0x6d, 0x42, 0x87, 0x7e, 0x53, 0xcf, 0xaa, 0x0b, 0x42, 0x2a,
+ /*79e0:*/ 0x6f, 0xe9, 0x11, 0xd7, 0xb8, 0xbd, 0x70, 0xe0, 0x0d, 0xdc, 0x2e, 0x3e, 0x83, 0x79, 0x9b, 0x1e,
+ /*79f0:*/ 0xc9, 0x6b, 0x82, 0x5d, 0x85, 0x61, 0xd1, 0x80, 0xac, 0x64, 0xae, 0x89, 0xc6, 0x8a, 0x24, 0x0b,
+ /*7a00:*/ 0xc3, 0x24, 0xf9, 0xdb, 0x93, 0xc7, 0xd5, 0x09, 0xae, 0x72, 0xf9, 0x1c, 0x59, 0xd7, 0xa1, 0x45,
+ /*7a10:*/ 0x41, 0xff, 0xc2, 0xa7, 0x8d, 0x63, 0x9f, 0x6f, 0x84, 0x77, 0x42, 0xa3, 0x8f, 0x8b, 0xba, 0x5b,
+ /*7a20:*/ 0xdf, 0xc0, 0xad, 0xc8, 0x37, 0x34, 0x11, 0x02, 0xc3, 0xcd, 0xdc, 0x51, 0x98, 0xa2, 0xc8, 0x6e,
+ /*7a30:*/ 0x45, 0x71, 0xd3, 0x52, 0xa6, 0xdb, 0xa0, 0x5a, 0x9b, 0x5b, 0xe5, 0x2e, 0x6c, 0x94, 0xd6, 0xe8,
+ /*7a40:*/ 0xd1, 0xcf, 0x3a, 0x9a, 0x92, 0x99, 0x76, 0x71, 0xb7, 0x76, 0x0a, 0x69, 0xbe, 0x76, 0x9a, 0x6f,
+ /*7a50:*/ 0xa3, 0xc0, 0x30, 0xef, 0x79, 0xf8, 0xc0, 0xd4, 0x01, 0xd5, 0x32, 0x75, 0xfc, 0x94, 0x95, 0x77,
+ /*7a60:*/ 0x25, 0x93, 0xfa, 0x16, 0x82, 0xac, 0xa7, 0xad, 0x30, 0xd2, 0xfe, 0xed, 0x90, 0x5b, 0xf1, 0xca,
+ /*7a70:*/ 0x6c, 0x9b, 0x49, 0x5b, 0x63, 0x1c, 0xbd, 0xeb, 0x59, 0x56, 0xd2, 0x48, 0xf0, 0xfb, 0x76, 0xe9,
+ /*7a80:*/ 0x84, 0xdf, 0xd8, 0xa8, 0x1a, 0x69, 0x09, 0x3c, 0x62, 0x89, 0x15, 0x7c, 0x8b, 0x37, 0x40, 0x6a,
+ /*7a90:*/ 0x00, 0xc6, 0x8d, 0xe8, 0x34, 0xc1, 0x89, 0xa8, 0x9e, 0xe1, 0x0c, 0x48, 0x63, 0xc0, 0xc2, 0xf7,
+ /*7aa0:*/ 0x8c, 0xe2, 0xed, 0x3c, 0xaf, 0xbf, 0xef, 0xf9, 0xd8, 0xa0, 0x44, 0xfc, 0x3f, 0xc2, 0x00, 0xa6,
+ /*7ab0:*/ 0x14, 0xa3, 0xf0, 0xf4, 0xf3, 0x08, 0x21, 0x65, 0xb4, 0xae, 0x40, 0xfd, 0x1f, 0x20, 0xbc, 0x1c,
+ /*7ac0:*/ 0xa6, 0x61, 0xec, 0x33, 0xa4, 0xa5, 0xd7, 0x47, 0x2b, 0x7a, 0x67, 0x0c, 0xd9, 0xbf, 0x4e, 0xf2,
+ /*7ad0:*/ 0x08, 0x2f, 0xf0, 0xa3, 0x3b, 0xf3, 0xf0, 0xf9, 0x8d, 0xad, 0x6e, 0x2f, 0x99, 0x65, 0x8d, 0x53,
+ /*7ae0:*/ 0xe3, 0xec, 0x7f, 0xf2, 0xff, 0x58, 0x38, 0x17, 0xd0, 0xc8, 0xd5, 0xe6, 0x92, 0x75, 0xe9, 0x77,
+ /*7af0:*/ 0x90, 0x1b, 0xa2, 0xbe, 0x35, 0xc9, 0x39, 0x0c, 0x67, 0x35, 0x9a, 0xb8, 0x7c, 0x6f, 0xe3, 0x46,
+ /*7b00:*/ 0xc3, 0xa7, 0x83, 0x1e, 0xe1, 0x61, 0x6a, 0x74, 0xcc, 0x1d, 0x57, 0xa4, 0xaa, 0x0c, 0x4b, 0x70,
+ /*7b10:*/ 0xa0, 0xa3, 0xc9, 0xa0, 0x95, 0xcf, 0xa6, 0xfa, 0x2b, 0x7e, 0x0d, 0x32, 0xe0, 0xdc, 0x23, 0xfc,
+ /*7b20:*/ 0x61, 0x93, 0xfa, 0xf7, 0x13, 0x26, 0xb0, 0xd8, 0xff, 0xbb, 0xc8, 0xfa, 0xfa, 0x91, 0x31, 0xcf,
+ /*7b30:*/ 0xcd, 0x54, 0x8c, 0xfc, 0x6d, 0x6b, 0x30, 0x00, 0x11, 0x43, 0x8c, 0xdc, 0x86, 0xf8, 0x11, 0x18,
+ /*7b40:*/ 0xee, 0xd5, 0xef, 0x9b, 0x79, 0x10, 0xc0, 0x2f, 0x08, 0xaa, 0xe3, 0xc5, 0x53, 0x7e, 0x61, 0xa0,
+ /*7b50:*/ 0xe2, 0xf0, 0xab, 0x8d, 0x70, 0x51, 0xd6, 0x2c, 0x6a, 0xbb, 0x2b, 0x26, 0x21, 0x61, 0x3f, 0x42,
+ /*7b60:*/ 0x3b, 0xd9, 0x24, 0x7d, 0xe6, 0x2c, 0x6d, 0xbb, 0xcc, 0xf4, 0x17, 0x12, 0x9e, 0xb0, 0x1e, 0xac,
+ /*7b70:*/ 0x28, 0xf0, 0xe6, 0x12, 0xf8, 0xde, 0x1f, 0xf4, 0x10, 0x43, 0xcb, 0x1f, 0xb6, 0xb3, 0x93, 0x18,
+ /*7b80:*/ 0x37, 0x3a, 0xe4, 0xc2, 0x7c, 0xaf, 0x0f, 0xea, 0x9c, 0x41, 0x78, 0x56, 0x46, 0x23, 0xeb, 0xce,
+ /*7b90:*/ 0x9e, 0x4b, 0xfb, 0x68, 0x3e, 0x68, 0x75, 0xe5, 0xfb, 0x9c, 0xf1, 0x5a, 0xba, 0x50, 0x82, 0x26,
+ /*7ba0:*/ 0x06, 0x0f, 0xfb, 0x39, 0x04, 0x17, 0x6d, 0x73, 0xa6, 0x7a, 0x57, 0x7b, 0xe7, 0xe3, 0x77, 0x23,
+ /*7bb0:*/ 0xfa, 0x99, 0x7f, 0x16, 0xa8, 0xbe, 0x80, 0xb1, 0x0d, 0x56, 0xb4, 0x5e, 0xd2, 0x1e, 0x73, 0xc7,
+ /*7bc0:*/ 0xe8, 0x07, 0xea, 0x35, 0xde, 0xd1, 0xc2, 0x0f, 0x40, 0x05, 0x64, 0x8d, 0x4f, 0x2a, 0xd8, 0x91,
+ /*7bd0:*/ 0x85, 0xa0, 0xca, 0x88, 0xad, 0xd5, 0xbc, 0x64, 0xcf, 0x62, 0xce, 0x57, 0x3d, 0xc9, 0x08, 0x51,
+ /*7be0:*/ 0x3f, 0x0c, 0xb1, 0xbf, 0xb3, 0xc0, 0x53, 0xe4, 0xd9, 0x28, 0xc6, 0x5f, 0xd9, 0x23, 0x87, 0x19,
+ /*7bf0:*/ 0x3b, 0xbc, 0x81, 0x46, 0xbe, 0x15, 0x84, 0x60, 0xc6, 0x9b, 0x8c, 0x50, 0x5f, 0xff, 0x94, 0xd4,
+ /*7c00:*/ 0x7c, 0xbe, 0x72, 0x2d, 0x08, 0x63, 0xba, 0x21, 0x0a, 0x18, 0x23, 0x06, 0x47, 0x37, 0x74, 0x67,
+ /*7c10:*/ 0xa4, 0xf1, 0x95, 0xcc, 0x92, 0x9e, 0x36, 0x51, 0xaf, 0xbc, 0x8b, 0x20, 0x0f, 0x88, 0x92, 0x03,
+ /*7c20:*/ 0xa5, 0xbf, 0x0e, 0xa6, 0x48, 0xb5, 0xc7, 0x73, 0xab, 0x12, 0x3e, 0x24, 0x45, 0xb4, 0x65, 0x35,
+ /*7c30:*/ 0x7d, 0xb8, 0xb0, 0x0e, 0xc6, 0xb9, 0x66, 0x7f, 0x7a, 0x42, 0x43, 0xf0, 0xf2, 0x5b, 0x07, 0xe1,
+ /*7c40:*/ 0x4c, 0xb4, 0xc6, 0x3c, 0x67, 0xca, 0x6b, 0xe4, 0x01, 0xd6, 0x4d, 0x55, 0x3b, 0xc8, 0x73, 0x9b,
+ /*7c50:*/ 0x79, 0x58, 0xee, 0x29, 0x78, 0xe6, 0x7e, 0xf3, 0xc6, 0x60, 0xe0, 0xb6, 0x27, 0xca, 0x6c, 0x49,
+ /*7c60:*/ 0xb5, 0x36, 0x1d, 0x16, 0x44, 0xc0, 0x17, 0xf0, 0xfe, 0x35, 0xd4, 0x04, 0xb7, 0x4a, 0x0c, 0x41,
+ /*7c70:*/ 0xe1, 0x71, 0x56, 0x26, 0xfd, 0x92, 0xaa, 0xc5, 0x97, 0x16, 0x55, 0xc6, 0x8c, 0xb3, 0x4b, 0x12,
+ /*7c80:*/ 0xb9, 0x6f, 0xca, 0x13, 0x41, 0x7c, 0x39, 0x55, 0x23, 0x6a, 0xe0, 0xc8, 0x11, 0x03, 0xb7, 0xf0,
+ /*7c90:*/ 0x01, 0x7b, 0x90, 0xa0, 0xa4, 0x77, 0xbe, 0x09, 0xa8, 0xcb, 0xd6, 0x24, 0x12, 0x26, 0xc9, 0x4d,
+ /*7ca0:*/ 0xd3, 0xb0, 0x09, 0x0b, 0x02, 0x1a, 0xbe, 0x7c, 0x0f, 0x24, 0xad, 0xa7, 0xf0, 0x20, 0xaa, 0xae,
+ /*7cb0:*/ 0xa4, 0x50, 0x0f, 0xe9, 0xfb, 0x54, 0x0e, 0x05, 0x32, 0xc7, 0x14, 0xfe, 0x5f, 0xd7, 0x5b, 0x3d,
+ /*7cc0:*/ 0x34, 0x72, 0xa7, 0x11, 0xc4, 0x20, 0x6a, 0x26, 0x9a, 0x27, 0x43, 0x11, 0xdd, 0xd4, 0x98, 0xad,
+ /*7cd0:*/ 0x3c, 0x00, 0x61, 0x33, 0xe7, 0x9f, 0x9b, 0xef, 0xb3, 0xe4, 0x24, 0x09, 0x40, 0x62, 0x84, 0x9d,
+ /*7ce0:*/ 0x00, 0x00, 0xf9, 0xb9, 0x7a, 0xca, 0x31, 0x0f, 0x3d, 0x6e, 0x28, 0x94, 0x2a, 0xb4, 0x44, 0xd5,
+ /*7cf0:*/ 0xab, 0x39, 0xf5, 0xf6, 0xe2, 0x90, 0x42, 0x01, 0x04, 0x8f, 0x0e, 0x29, 0xcc, 0xbd, 0x73, 0x3c,
+ /*7d00:*/ 0x08, 0x60, 0x9a, 0x31, 0x96, 0xb8, 0x1d, 0xcb, 0xcb, 0x30, 0xba, 0xdc, 0x15, 0xec, 0x1c, 0x2d,
+ /*7d10:*/ 0x72, 0x31, 0x7d, 0x93, 0xf5, 0x4f, 0x67, 0x11, 0x28, 0x09, 0x2d, 0x11, 0xc1, 0x94, 0xee, 0xa3,
+ /*7d20:*/ 0xac, 0x13, 0xbb, 0xb3, 0x86, 0x00, 0x98, 0xd7, 0x09, 0xc0, 0xd7, 0x7c, 0x56, 0x5b, 0x80, 0x1c,
+ /*7d30:*/ 0x40, 0x52, 0xc5, 0x99, 0x1e, 0x5f, 0x77, 0x0c, 0x6c, 0x66, 0xe4, 0x5d, 0x92, 0x86, 0xcb, 0x33,
+ /*7d40:*/ 0x57, 0x64, 0xdf, 0x12, 0xcd, 0x80, 0xf3, 0x49, 0xc2, 0x9e, 0x63, 0xe6, 0xb7, 0xbe, 0x9d, 0x77,
+ /*7d50:*/ 0xe5, 0xd4, 0xe3, 0xc5, 0x7d, 0x0f, 0x41, 0x33, 0xc7, 0x4d, 0x64, 0x47, 0x23, 0x5a, 0xd1, 0x37,
+ /*7d60:*/ 0x3f, 0xb9, 0xb8, 0x0a, 0xbf, 0x6f, 0xff, 0xe8, 0x85, 0xae, 0x31, 0x77, 0xf6, 0xc2, 0xbe, 0x0c,
+ /*7d70:*/ 0x52, 0xdb, 0x9e, 0x63, 0xbd, 0xe5, 0x1a, 0xdc, 0x78, 0x07, 0x46, 0x25, 0x2e, 0x2c, 0xe1, 0xdc,
+ /*7d80:*/ 0x76, 0x81, 0xd6, 0x5c, 0xf8, 0x81, 0x84, 0xea, 0x30, 0x90, 0xda, 0x6c, 0x5b, 0x55, 0xb4, 0x18,
+ /*7d90:*/ 0x89, 0x7b, 0xe0, 0x77, 0x6f, 0x9e, 0xfc, 0x88, 0x8f, 0x03, 0xd8, 0xaa, 0x16, 0xb9, 0x44, 0xb1,
+ /*7da0:*/ 0x4e, 0x3f, 0x60, 0x73, 0xe5, 0xe7, 0x97, 0xe8, 0x37, 0x42, 0x46, 0x92, 0x91, 0xf4, 0x03, 0xff,
+ /*7db0:*/ 0xdd, 0xed, 0x76, 0xce, 0x37, 0xbd, 0x06, 0xa6, 0x46, 0x97, 0xe0, 0xed, 0x2b, 0xdf, 0x04, 0x5e,
+ /*7dc0:*/ 0x97, 0x6c, 0x96, 0xee, 0x99, 0x79, 0x33, 0xba, 0x0a, 0x56, 0x4a, 0xa4, 0x8a, 0x2e, 0x4d, 0x94,
+ /*7dd0:*/ 0xab, 0x2d, 0xf0, 0x34, 0xc1, 0x11, 0xb1, 0xc9, 0x99, 0xfe, 0x6f, 0xf8, 0x70, 0x4e, 0x8f, 0x52,
+ /*7de0:*/ 0x0d, 0xa5, 0xb4, 0xbb, 0x7e, 0x26, 0x04, 0x80, 0xdc, 0x3d, 0x24, 0xc0, 0x7a, 0x40, 0x0d, 0x89,
+ /*7df0:*/ 0x9a, 0x0c, 0x12, 0xa7, 0x56, 0x76, 0xb8, 0x3d, 0xac, 0xba, 0xbf, 0x23, 0x81, 0x2c, 0xe9, 0x18,
+ /*7e00:*/ 0xac, 0x48, 0xbc, 0xaf, 0x78, 0xcd, 0xd2, 0x31, 0x05, 0x9a, 0x75, 0x50, 0x90, 0x48, 0x7a, 0xd0,
+ /*7e10:*/ 0x87, 0x86, 0x25, 0xaa, 0xd2, 0x41, 0x36, 0x85, 0x77, 0x76, 0x68, 0x06, 0xdf, 0x7b, 0xfa, 0x4f,
+ /*7e20:*/ 0x1e, 0x99, 0xe4, 0x93, 0x43, 0xde, 0x4a, 0x4c, 0x97, 0xdb, 0x1f, 0x2c, 0xa4, 0x40, 0x02, 0xcd,
+ /*7e30:*/ 0xf4, 0x85, 0x40, 0xbe, 0x28, 0xa4, 0x10, 0x5c, 0x62, 0x6f, 0x83, 0x9d, 0x5b, 0xbf, 0xec, 0xf6,
+ /*7e40:*/ 0xb5, 0xec, 0x11, 0x6f, 0x10, 0x10, 0xe9, 0x25, 0x28, 0x05, 0xfa, 0x2d, 0xf8, 0x9f, 0x9e, 0xa5,
+ /*7e50:*/ 0x0e, 0x9c, 0x7a, 0x27, 0x10, 0xaa, 0x6b, 0x9d, 0xcc, 0x3f, 0x02, 0xdd, 0x62, 0x53, 0x16, 0xfc,
+ /*7e60:*/ 0x3a, 0x6a, 0x9e, 0x44, 0xfd, 0x02, 0x72, 0x20, 0xd3, 0x86, 0xe4, 0xaf, 0x4e, 0xba, 0x06, 0x97,
+ /*7e70:*/ 0xc7, 0x7f, 0x53, 0xd5, 0x0d, 0xd3, 0x14, 0xad, 0x58, 0xfc, 0x86, 0x4c, 0x4d, 0x67, 0x54, 0xa2,
+ /*7e80:*/ 0x6e, 0xbc, 0x6c, 0x46, 0xbf, 0x41, 0xad, 0xf3, 0x8a, 0x1d, 0x82, 0x46, 0xde, 0x33, 0x4c, 0x63,
+ /*7e90:*/ 0xea, 0x15, 0xad, 0xf4, 0x9e, 0x8e, 0x9f, 0x95, 0xa7, 0x77, 0x02, 0xee, 0x22, 0x7f, 0xfb, 0x62,
+ /*7ea0:*/ 0x1e, 0x47, 0x4b, 0xb7, 0x60, 0xc7, 0xa4, 0xa6, 0x9a, 0x6c, 0x27, 0x1f, 0x6e, 0x72, 0xb3, 0x91,
+ /*7eb0:*/ 0x3c, 0x54, 0xf5, 0x78, 0x9c, 0x52, 0x80, 0xb7, 0xc0, 0x60, 0x12, 0xc2, 0x87, 0x41, 0x76, 0xd8,
+ /*7ec0:*/ 0x5f, 0x34, 0x4b, 0xf5, 0x81, 0x64, 0x81, 0x97, 0xa6, 0x3e, 0x27, 0x7f, 0x79, 0x90, 0xd9, 0xda,
+ /*7ed0:*/ 0xd4, 0x06, 0xbb, 0x54, 0x37, 0xd2, 0x65, 0x64, 0x70, 0xaa, 0x8d, 0xd0, 0x29, 0x5f, 0xa3, 0x53,
+ /*7ee0:*/ 0x93, 0xf6, 0x80, 0x35, 0x02, 0x59, 0x7a, 0x66, 0x57, 0xcd, 0x5a, 0xfb, 0xca, 0x1f, 0x5a, 0xdc,
+ /*7ef0:*/ 0xc8, 0x54, 0xb1, 0xf6, 0xb6, 0x42, 0xe8, 0x2b, 0x24, 0xee, 0x82, 0xe1, 0xf0, 0xf8, 0x51, 0x22,
+ /*7f00:*/ 0x0c, 0x8b, 0x6b, 0x30, 0xab, 0xb8, 0x54, 0xfe, 0x44, 0x03, 0xd8, 0x17, 0xa7, 0x15, 0xe7, 0xa1,
+ /*7f10:*/ 0xe6, 0xe4, 0x59, 0x36, 0xfd, 0xd3, 0x49, 0xe3, 0x73, 0x41, 0xa9, 0x30, 0xe4, 0xc5, 0x5b, 0x68,
+ /*7f20:*/ 0x63, 0x4e, 0xd4, 0x19, 0x3c, 0x1a, 0xf5, 0xde, 0x0a, 0x4f, 0x97, 0x59, 0x3b, 0x3f, 0xb1, 0x66,
+ /*7f30:*/ 0x9f, 0x0e, 0x56, 0xd8, 0xaf, 0x45, 0x60, 0x79, 0x74, 0xbd, 0x3d, 0xd1, 0xa9, 0x74, 0x4b, 0xa3,
+ /*7f40:*/ 0xd4, 0xfe, 0x1e, 0xc3, 0x8a, 0x63, 0x2e, 0x13, 0xe3, 0x57, 0xd3, 0xd0, 0x99, 0x17, 0x34, 0xa8,
+ /*7f50:*/ 0x01, 0x4a, 0xa6, 0x04, 0x77, 0x1f, 0xf0, 0xaa, 0x47, 0xfe, 0x93, 0xcb, 0x04, 0x4d, 0x89, 0x3d,
+ /*7f60:*/ 0xfc, 0x97, 0xc9, 0x64, 0x64, 0x4d, 0x92, 0x29, 0x88, 0xf4, 0x0c, 0xcc, 0x1b, 0x93, 0xdd, 0xb2,
+ /*7f70:*/ 0x84, 0x1a, 0x41, 0x88, 0xfa, 0xa5, 0x02, 0xf5, 0x01, 0x0a, 0x53, 0xc3, 0x3d, 0x3c, 0x56, 0x41,
+ /*7f80:*/ 0xde, 0x46, 0xfd, 0xdb, 0x5f, 0xe7, 0xf9, 0xc7, 0xb7, 0x16, 0x07, 0xd9, 0x60, 0xd6, 0xde, 0xea,
+ /*7f90:*/ 0x3d, 0xb8, 0xcb, 0xaf, 0x78, 0x2a, 0xeb, 0x60, 0x7e, 0xf4, 0x81, 0x81, 0x0b, 0xa2, 0x3a, 0xdb,
+ /*7fa0:*/ 0xc0, 0x4f, 0x30, 0x19, 0x37, 0xab, 0xc3, 0x61, 0x6f, 0xeb, 0x89, 0x08, 0x8a, 0xab, 0x5c, 0xb0,
+ /*7fb0:*/ 0x37, 0x16, 0x05, 0x4b, 0x4f, 0x03, 0x9d, 0x0e, 0x79, 0x88, 0x2c, 0x1b, 0xe7, 0x20, 0x9c, 0xff,
+ /*7fc0:*/ 0xce, 0x91, 0x6a, 0x6b, 0x73, 0x5a, 0x7b, 0xa0, 0x6a, 0x3e, 0xab, 0xb4, 0x8d, 0x3a, 0xce, 0x53,
+ /*7fd0:*/ 0x43, 0x57, 0x2f, 0x93, 0xae, 0x51, 0x28, 0xd9, 0xb8, 0x1e, 0x0d, 0x35, 0x6a, 0x22, 0x00, 0x12,
+ /*7fe0:*/ 0x36, 0x4e, 0xed, 0x2d, 0x98, 0xd1, 0x68, 0xbe, 0x34, 0x81, 0xea, 0x36, 0xab, 0xd2, 0x8c, 0x1a,
+ /*7ff0:*/ 0xf0, 0x19, 0x85, 0x36, 0x02, 0xff, 0x87, 0x6a, 0x84, 0x20, 0x5a, 0xa0, 0x57, 0xba, 0xa3, 0x04,
+ /*8000:*/ 0x84, 0x34, 0x21, 0xef, 0xbc, 0x7b, 0xde, 0xec, 0x8c, 0x4b, 0x65, 0x20, 0x4d, 0x3f, 0x2a, 0xae,
+ /*8010:*/ 0x0c, 0xad, 0x59, 0xce, 0x99, 0x77, 0x05, 0xb8, 0xc8, 0x18, 0xf9, 0xe0, 0xac, 0xcd, 0xbc, 0xfe,
+ /*8020:*/ 0xa1, 0x37, 0xc5, 0xba, 0xa5, 0xb3, 0xf2, 0x01, 0x81, 0x17, 0x79, 0xa7, 0x22, 0x9d, 0x04, 0x05,
+ /*8030:*/ 0x8f, 0xf6, 0xc1, 0x74, 0x42, 0xb5, 0xa3, 0x4d, 0x41, 0x5e, 0x98, 0x5e, 0xa7, 0xd3, 0xb0, 0xb5,
+ /*8040:*/ 0x8d, 0xf9, 0xc8, 0x20, 0x47, 0x50, 0x32, 0x4a, 0x9c, 0x10, 0xe7, 0x8d, 0x1b, 0xcf, 0xd8, 0x75,
+ /*8050:*/ 0x9d, 0x3d, 0x56, 0x88, 0xe6, 0x9b, 0xa1, 0xf1, 0xd0, 0x74, 0x26, 0x87, 0xfa, 0xab, 0xea, 0x8f,
+ /*8060:*/ 0xaf, 0x3c, 0x38, 0xd5, 0xe2, 0xe6, 0x05, 0xbd, 0x57, 0x0c, 0x05, 0x80, 0xc3, 0xd7, 0xde, 0x66,
+ /*8070:*/ 0x14, 0x67, 0x4a, 0x3e, 0x4a, 0xe6, 0xe0, 0x54, 0xfa, 0xce, 0x09, 0x8a, 0x75, 0xd0, 0x87, 0x39,
+ /*8080:*/ 0xb1, 0xfb, 0x0c, 0x54, 0xed, 0x69, 0x96, 0x68, 0x5c, 0x1b, 0xcf, 0xa3, 0x56, 0xdd, 0x0b, 0x78,
+ /*8090:*/ 0x9c, 0x5d, 0x7d, 0x9d, 0x05, 0x79, 0x72, 0xb9, 0xa9, 0x6e, 0xd1, 0xfb, 0x0c, 0x28, 0x2b, 0xa9,
+ /*80a0:*/ 0xf4, 0xb3, 0x41, 0xb1, 0x12, 0xe0, 0xe3, 0xf4, 0xf0, 0x6c, 0x86, 0x50, 0xf0, 0xaf, 0x23, 0x87,
+ /*80b0:*/ 0x67, 0x91, 0xe2, 0x07, 0x6c, 0x77, 0x16, 0xf9, 0x5f, 0x83, 0x8a, 0x46, 0xb6, 0xe3, 0x02, 0x59,
+ /*80c0:*/ 0x77, 0xaf, 0x3e, 0x98, 0x33, 0x3f, 0xb6, 0xf4, 0x02, 0x23, 0x50, 0xd8, 0x4b, 0xc9, 0x4e, 0xd9,
+ /*80d0:*/ 0x00, 0xe9, 0x68, 0x13, 0x44, 0xed, 0x2c, 0x4d, 0xd7, 0x60, 0xb4, 0x69, 0xc6, 0xd4, 0xe7, 0xc6,
+ /*80e0:*/ 0x57, 0xe4, 0xb0, 0x5d, 0x74, 0x51, 0xb5, 0x09, 0x54, 0x11, 0x58, 0x1b, 0xab, 0xf6, 0x54, 0xfb,
+ /*80f0:*/ 0xe4, 0xaa, 0x99, 0xb0, 0xc2, 0xa8, 0xc3, 0x2d, 0x52, 0x95, 0x39, 0x51, 0x4b, 0x18, 0x83, 0xe6,
+ /*8100:*/ 0xfc, 0x55, 0xd5, 0x0a, 0xae, 0x93, 0x70, 0x97, 0x60, 0x65, 0x63, 0x61, 0x72, 0x65, 0x9a, 0xe8,
+ /*8110:*/ 0x13, 0x86, 0x99, 0x14, 0x75, 0xca, 0xe2, 0x9b, 0x40, 0xaf, 0x63, 0x49, 0x50, 0xfc, 0x1d, 0x9b,
+ /*8120:*/ 0x2a, 0x26, 0xee, 0xbc, 0x88, 0x78, 0x1d, 0xd8, 0xd6, 0x51, 0x8b, 0x8f, 0x45, 0xf9, 0xe0, 0x4b,
+ /*8130:*/ 0x29, 0x6a, 0x46, 0xf6, 0x9b, 0x5b, 0x6e, 0x2c, 0x83, 0xbf, 0x03, 0x82, 0x8f, 0xb6, 0xe4, 0x76,
+ /*8140:*/ 0x6b, 0x70, 0xaf, 0x88, 0x69, 0x6e, 0x82, 0x00, 0x44, 0x71, 0x3d, 0xf3, 0x05, 0x0d, 0xa0, 0x33,
+ /*8150:*/ 0x92, 0x10, 0x87, 0x70, 0xda, 0x2d, 0x0c, 0x97, 0x41, 0x1f, 0x5c, 0x2f, 0x3d, 0x8b, 0xe8, 0x53,
+ /*8160:*/ 0xf3, 0x01, 0x1e, 0x79, 0x47, 0x60, 0xf1, 0x72, 0x9e, 0x0d, 0x5d, 0x45, 0x93, 0xb9, 0x5f, 0x57,
+ /*8170:*/ 0x88, 0xaf, 0x23, 0x27, 0x0e, 0xaa, 0xab, 0x4b, 0x29, 0x37, 0x10, 0xe0, 0x81, 0xd1, 0xd0, 0x4d,
+ /*8180:*/ 0xdf, 0x72, 0xe9, 0xbb, 0xc2, 0x80, 0x3b, 0x42, 0xc2, 0x61, 0x10, 0xd0, 0x07, 0xb9, 0x0b, 0x05,
+ /*8190:*/ 0x09, 0xb8, 0xa6, 0x11, 0x92, 0x90, 0x22, 0x73, 0xd2, 0x02, 0xfc, 0x4a, 0x99, 0x28, 0x7e, 0x0a,
+ /*81a0:*/ 0xa6, 0x24, 0xe8, 0xc4, 0xa2, 0xe0, 0x5c, 0x32, 0x5d, 0x3a, 0xc2, 0xd7, 0x6c, 0x77, 0x9a, 0xa7,
+ /*81b0:*/ 0x3e, 0xa2, 0x42, 0xd8, 0x14, 0x84, 0x0a, 0x46, 0x0e, 0x0f, 0x94, 0x5f, 0x0e, 0x4c, 0x5a, 0x9a,
+ /*81c0:*/ 0x75, 0x50, 0x8f, 0xe4, 0x5c, 0xaa, 0xf4, 0x99, 0x29, 0x14, 0x8a, 0xac, 0xd3, 0x5b, 0xcc, 0x87,
+ /*81d0:*/ 0x03, 0xc2, 0x58, 0xd3, 0x63, 0x09, 0x92, 0x1f, 0xb4, 0x59, 0x5e, 0x5c, 0x5a, 0x03, 0x32, 0x30,
+ /*81e0:*/ 0x28, 0xb8, 0xdb, 0x8a, 0xdc, 0x93, 0x74, 0xf6, 0xe9, 0x3c, 0xfa, 0x31, 0xef, 0xa7, 0xf4, 0x79,
+ /*81f0:*/ 0x11, 0x97, 0x4a, 0xbd, 0xa3, 0x95, 0x3e, 0x40, 0x6a, 0x72, 0xe0, 0x7c, 0x2b, 0xe8, 0xa4, 0x0d,
+ /*8200:*/ 0x01, 0x74, 0x6f, 0x3d, 0x70, 0x89, 0x04, 0x37, 0x1b, 0x1b, 0x05, 0x69, 0x89, 0x9b, 0xa0, 0x48,
+ /*8210:*/ 0x5b, 0x5f, 0x25, 0x8f, 0xb7, 0xc1, 0xe7, 0xf3, 0x04, 0x3b, 0xf7, 0x18, 0xfe, 0x44, 0xc7, 0x60,
+ /*8220:*/ 0x6d, 0xae, 0x7d, 0x08, 0xe3, 0x6f, 0xc6, 0x4f, 0x36, 0xe5, 0x86, 0xbc, 0x99, 0x12, 0x1a, 0xb6,
+ /*8230:*/ 0x06, 0x4c, 0xe6, 0x52, 0xeb, 0x42, 0xfb, 0x66, 0x87, 0x8b, 0x67, 0x0e, 0xac, 0xd5, 0xb8, 0x02,
+ /*8240:*/ 0x5e, 0xc8, 0xed, 0x80, 0x66, 0x7c, 0x83, 0x0b, 0x85, 0x28, 0x84, 0x2d, 0xbd, 0xfc, 0x2e, 0x13,
+ /*8250:*/ 0x4a, 0x09, 0x39, 0x52, 0x88, 0xc1, 0xb5, 0xc6, 0x81, 0x56, 0xed, 0xfd, 0xdb, 0x55, 0xa5, 0x57,
+ /*8260:*/ 0x1a, 0xaa, 0xec, 0x95, 0x96, 0xca, 0x51, 0xfa, 0xd0, 0x88, 0xe8, 0xd2, 0x85, 0x8c, 0xc9, 0x73,
+ /*8270:*/ 0x98, 0x99, 0xc0, 0x5b, 0xef, 0x4e, 0xe9, 0xd0, 0x25, 0x0b, 0x9d, 0xdd, 0x8a, 0xc3, 0x06, 0x2b,
+ /*8280:*/ 0x2f, 0x45, 0xb2, 0x7b, 0x2c, 0x49, 0x41, 0xa9, 0x5c, 0xcf, 0x00, 0x6f, 0xbe, 0x9f, 0x9f, 0x3c,
+ /*8290:*/ 0x10, 0xd7, 0xf1, 0x80, 0x8e, 0x9c, 0x99, 0xb8, 0xc5, 0xee, 0x98, 0x46, 0x49, 0xf3, 0x33, 0xea,
+ /*82a0:*/ 0x6c, 0xc2, 0x8b, 0x3b, 0x14, 0x45, 0xbd, 0xce, 0x5f, 0x2c, 0xec, 0x88, 0x2f, 0x9d, 0x5d, 0xd5,
+ /*82b0:*/ 0xee, 0x8f, 0x0d, 0x07, 0xaa, 0x04, 0xdd, 0xaa, 0x2f, 0x80, 0xd8, 0xd3, 0xa2, 0xb1, 0x90, 0xdd,
+ /*82c0:*/ 0x0b, 0x0e, 0xd8, 0x70, 0x4a, 0x22, 0x8a, 0x49, 0x85, 0xcd, 0xf6, 0x63, 0x14, 0x3a, 0x28, 0x8c,
+ /*82d0:*/ 0x65, 0x7f, 0x18, 0x90, 0x3d, 0xa2, 0x7d, 0x1c, 0x1f, 0x04, 0xc3, 0xc4, 0xbc, 0x0e, 0xb1, 0x19,
+ /*82e0:*/ 0xae, 0x35, 0xa7, 0xf7, 0x3f, 0x4d, 0x6a, 0xb5, 0x57, 0x98, 0x44, 0x62, 0x6d, 0xbd, 0x29, 0x5a,
+ /*82f0:*/ 0x7a, 0x82, 0x40, 0xb9, 0x5d, 0xa2, 0x61, 0x1e, 0xea, 0xff, 0x9a, 0xd7, 0x85, 0x8b, 0x2a, 0x88,
+ /*8300:*/ 0x6a, 0xbc, 0xdb, 0x16, 0x1b, 0x43, 0x02, 0xbd, 0x36, 0xa1, 0x9e, 0x86, 0x45, 0x15, 0x4b, 0x07,
+ /*8310:*/ 0xaf, 0x96, 0x11, 0xcb, 0xb7, 0x23, 0xb1, 0xb2, 0xcf, 0x25, 0x99, 0xd5, 0x31, 0xc9, 0xde, 0x7a,
+ /*8320:*/ 0x7b, 0x74, 0x80, 0x3d, 0xcd, 0x17, 0xab, 0x63, 0xe6, 0x27, 0x17, 0xce, 0x07, 0xb3, 0x12, 0xec,
+ /*8330:*/ 0x5f, 0x5f, 0xe7, 0xcb, 0x92, 0xb1, 0xe9, 0x58, 0x57, 0x40, 0xb4, 0x43, 0xcb, 0x61, 0x45, 0xd8,
+ /*8340:*/ 0x15, 0xe3, 0xd9, 0xc1, 0x65, 0x88, 0x33, 0x6b, 0xc5, 0x9d, 0x93, 0x49, 0xd6, 0x95, 0xb5, 0x5a,
+ /*8350:*/ 0x07, 0xae, 0x98, 0xe8, 0xda, 0x3e, 0x7c, 0x5c, 0x29, 0xfb, 0xd1, 0xbf, 0x2d, 0x45, 0x2f, 0xb2,
+ /*8360:*/ 0xcc, 0xfd, 0x93, 0xb3, 0x5d, 0x4e, 0x68, 0xce, 0xa7, 0x6b, 0xf5, 0xf4, 0xa8, 0x4c, 0x9f, 0x2f,
+ /*8370:*/ 0xe4, 0xf6, 0x4a, 0x0d, 0xe8, 0xb1, 0x07, 0xb0, 0x5a, 0xc7, 0x2e, 0xbe, 0x32, 0xc6, 0x84, 0x7b,
+ /*8380:*/ 0x19, 0xba, 0x32, 0x9d, 0x2b, 0x01, 0x53, 0x5d, 0x91, 0x21, 0x21, 0xed, 0xe7, 0x71, 0xe5, 0xe0,
+ /*8390:*/ 0xae, 0x15, 0x51, 0xec, 0xfb, 0x4c, 0xe3, 0x35, 0xa3, 0x04, 0x70, 0x22, 0x26, 0x38, 0xa8, 0x3d,
+ /*83a0:*/ 0x41, 0x39, 0xc0, 0x87, 0xc3, 0x33, 0x8a, 0x3a, 0x73, 0xb4, 0x20, 0x99, 0x3d, 0xe8, 0xbd, 0x19,
+ /*83b0:*/ 0xa7, 0xa2, 0x06, 0xb1, 0xd7, 0xa4, 0x09, 0x04, 0xfa, 0x48, 0xa6, 0xd0, 0xa9, 0xbb, 0xeb, 0x42,
+ /*83c0:*/ 0x33, 0xf9, 0x10, 0x6e, 0xda, 0x32, 0x8e, 0x31, 0x71, 0xfb, 0x91, 0x8a, 0x3b, 0xe2, 0x27, 0x4d,
+ /*83d0:*/ 0xb2, 0x5d, 0x40, 0x1c, 0x3b, 0xf2, 0xb8, 0x30, 0x90, 0x59, 0xe4, 0xa3, 0xa7, 0x80, 0x89, 0xbb,
+ /*83e0:*/ 0xaa, 0x6a, 0x85, 0x9e, 0x93, 0x92, 0xe0, 0x72, 0x2f, 0x32, 0x49, 0xa9, 0x91, 0x72, 0xc8, 0xf7,
+ /*83f0:*/ 0x06, 0x28, 0x9d, 0x81, 0xb1, 0x2a, 0x25, 0x60, 0x45, 0x83, 0xec, 0x2b, 0x7e, 0x4b, 0x4c, 0xc9,
+ /*8400:*/ 0x68, 0x27, 0xc6, 0x76, 0x9d, 0x4b, 0x7f, 0x22, 0x5e, 0x29, 0xad, 0x2f, 0x4c, 0xf2, 0x40, 0xea,
+ /*8410:*/ 0x27, 0x0f, 0xed, 0xb4, 0x65, 0x07, 0x05, 0x8d, 0x12, 0x5f, 0x71, 0x2d, 0x75, 0x6d, 0x3f, 0xef,
+ /*8420:*/ 0xd0, 0xd5, 0xd8, 0x3e, 0x54, 0x85, 0xc1, 0x50, 0xd3, 0x56, 0x39, 0xd1, 0x10, 0x84, 0x2d, 0xbb,
+ /*8430:*/ 0x7c, 0xd4, 0x6a, 0x49, 0x40, 0xc6, 0xdd, 0xb3, 0xd5, 0x80, 0x58, 0x0b, 0xa2, 0x98, 0x34, 0xbc,
+ /*8440:*/ 0xf6, 0x31, 0xde, 0xa7, 0xed, 0x6e, 0xc0, 0x74, 0x33, 0x9f, 0x25, 0x8f, 0xf1, 0xf2, 0x27, 0x95,
+ /*8450:*/ 0xe3, 0x25, 0xe4, 0x3d, 0x28, 0x05, 0xe7, 0x68, 0x8e, 0xdf, 0xbe, 0x45, 0xe4, 0x11, 0x71, 0x19,
+ /*8460:*/ 0x6d, 0x34, 0xd6, 0x56, 0x52, 0x04, 0xaf, 0x5d, 0x4e, 0x22, 0x22, 0x98, 0xd3, 0x52, 0x26, 0xf4,
+ /*8470:*/ 0xd1, 0x73, 0xa1, 0x97, 0xa0, 0x3c, 0xef, 0xfa, 0x80, 0x7a, 0xe4, 0x1d, 0xe8, 0x53, 0x04, 0x19,
+ /*8480:*/ 0x4d, 0x65, 0x55, 0xf4, 0xf2, 0x55, 0x94, 0xf6, 0xcb, 0x1e, 0xfe, 0x91, 0x42, 0x83, 0xa7, 0x5a,
+ /*8490:*/ 0x8d, 0x81, 0xba, 0xd6, 0xaa, 0x4c, 0xb8, 0xfd, 0x36, 0xfc, 0x0e, 0x42, 0xe3, 0xd4, 0xdf, 0xfc,
+ /*84a0:*/ 0xb3, 0x71, 0x22, 0x91, 0xe5, 0xea, 0xce, 0xa0, 0xb7, 0xfb, 0x03, 0x19, 0xa7, 0x0a, 0xb0, 0xf5,
+ /*84b0:*/ 0x26, 0xfe, 0x01, 0xe9, 0x05, 0xc4, 0x09, 0x61, 0xb5, 0x29, 0x07, 0xcb, 0xce, 0x14, 0x7d, 0x49,
+ /*84c0:*/ 0xfd, 0xe1, 0x91, 0x10, 0x62, 0x0d, 0xf8, 0x37, 0x8f, 0xed, 0xf2, 0x5e, 0x31, 0x6e, 0x80, 0xeb,
+ /*84d0:*/ 0x08, 0x10, 0x7c, 0x07, 0x61, 0x7e, 0xd2, 0xf4, 0xfc, 0xc8, 0xf1, 0x88, 0xdb, 0x02, 0xe5, 0xa8,
+ /*84e0:*/ 0x63, 0x91, 0x43, 0x24, 0x77, 0x61, 0x05, 0x56, 0x73, 0xfa, 0x9c, 0x50, 0x9c, 0x93, 0x75, 0x5b,
+ /*84f0:*/ 0xb2, 0x6c, 0xec, 0x9d, 0x7d, 0x33, 0x1d, 0xb4, 0xa8, 0x1c, 0xc8, 0x4d, 0x9b, 0xde, 0xa8, 0x9e,
+ /*8500:*/ 0x6d, 0xef, 0x92, 0xd5, 0x2f, 0xdf, 0x14, 0xc3, 0xa0, 0xd7, 0x42, 0x31, 0xec, 0xc9, 0x1e, 0x63,
+ /*8510:*/ 0x99, 0x1e, 0xd7, 0xce, 0xaf, 0x03, 0xd8, 0x59, 0x74, 0xa3, 0x50, 0xd9, 0x5b, 0x38, 0xc8, 0xbe,
+ /*8520:*/ 0xa0, 0xfd, 0xa9, 0x08, 0x97, 0xf3, 0x58, 0x28, 0xa7, 0xc3, 0x3c, 0x92, 0x99, 0x45, 0x13, 0xfd,
+ /*8530:*/ 0xae, 0xb3, 0xe9, 0x27, 0xa6, 0xa2, 0x9c, 0x81, 0x8f, 0x78, 0x1d, 0x8a, 0x26, 0x73, 0x04, 0x67,
+ /*8540:*/ 0xbd, 0xe8, 0x02, 0xb2, 0x69, 0xf4, 0x6b, 0xad, 0xd8, 0xd8, 0x34, 0x5e, 0xff, 0xb3, 0xbe, 0x82,
+ /*8550:*/ 0xd4, 0xde, 0x4c, 0xd1, 0x83, 0xc9, 0x94, 0x12, 0xfe, 0x7d, 0x15, 0xd1, 0x70, 0x75, 0x2c, 0x1b,
+ /*8560:*/ 0xd6, 0x5b, 0x0e, 0x96, 0x8d, 0xf4, 0x29, 0x61, 0xca, 0x50, 0xe4, 0x00, 0xa5, 0x56, 0x4f, 0xf8,
+ /*8570:*/ 0xcb, 0xef, 0xe8, 0x56, 0x77, 0x99, 0x28, 0x91, 0x05, 0xb8, 0xc2, 0x70, 0xaf, 0x0a, 0x55, 0x02,
+ /*8580:*/ 0xa1, 0x1f, 0x38, 0x04, 0x2e, 0xc5, 0x69, 0xbe, 0xca, 0xa2, 0x15, 0x08, 0x71, 0xe4, 0x90, 0xed,
+ /*8590:*/ 0x5c, 0x54, 0x54, 0x72, 0x6f, 0x42, 0x75, 0x7e, 0xc7, 0x87, 0x23, 0xce, 0x3b, 0xc8, 0xe1, 0x2f,
+ /*85a0:*/ 0xc8, 0x18, 0xf8, 0x13, 0x52, 0xbf, 0x6f, 0x2b, 0xae, 0x40, 0x3a, 0x3e, 0x51, 0x59, 0x44, 0xd1,
+ /*85b0:*/ 0xca, 0x6f, 0x40, 0x7e, 0xaa, 0x2f, 0x3e, 0xc2, 0xa8, 0x6d, 0xb6, 0x7b, 0xc4, 0xcd, 0xec, 0xd4,
+ /*85c0:*/ 0x6d, 0x3e, 0x8e, 0x17, 0x9c, 0x08, 0x97, 0xe6, 0x07, 0x70, 0x93, 0xe0, 0xf3, 0x33, 0xa2, 0x17,
+ /*85d0:*/ 0x1c, 0x3d, 0x67, 0x8f, 0xdc, 0x9e, 0x6a, 0x9c, 0x1d, 0xb4, 0x1d, 0x0d, 0x62, 0x63, 0xd8, 0x34,
+ /*85e0:*/ 0xd0, 0xb9, 0x84, 0x72, 0xa9, 0xef, 0x53, 0x6d, 0x0b, 0xc3, 0xd7, 0xe4, 0x4d, 0x66, 0x14, 0x1c,
+ /*85f0:*/ 0x86, 0x4b, 0x41, 0xa5, 0x61, 0x42, 0x50, 0xa1, 0x70, 0xe9, 0x6e, 0xf1, 0x01, 0xfd, 0x1a, 0x92,
+ /*8600:*/ 0x8a, 0x68, 0xf6, 0x21, 0x27, 0x77, 0xb6, 0x35, 0x41, 0xd4, 0xd9, 0x01, 0xcc, 0x5f, 0x23, 0x82,
+ /*8610:*/ 0xc5, 0xca, 0x09, 0x4e, 0x67, 0x10, 0xfa, 0x7c, 0xcb, 0xde, 0x53, 0x53, 0xe2, 0x3c, 0x0f, 0x65,
+ /*8620:*/ 0x08, 0x4b, 0x8c, 0x5b, 0xd0, 0x36, 0xce, 0x2c, 0x90, 0x03, 0x0b, 0x7c, 0x02, 0x84, 0x02, 0x97,
+ /*8630:*/ 0xb0, 0xcd, 0xbe, 0xa1, 0x44, 0x0e, 0x56, 0x0e, 0xe9, 0x72, 0xc1, 0xd8, 0xd4, 0x25, 0xac, 0xfb,
+ /*8640:*/ 0x04, 0xe3, 0xba, 0x9a, 0x11, 0x4a, 0x16, 0x83, 0xdd, 0xcf, 0x77, 0x9e, 0xe7, 0x2d, 0xf4, 0xfd,
+ /*8650:*/ 0xa1, 0x70, 0xac, 0xc6, 0xb8, 0x8e, 0x40, 0xdc, 0x6b, 0x1a, 0x9e, 0x09, 0x4b, 0x6b, 0xed, 0xbd,
+ /*8660:*/ 0xb8, 0xc5, 0x50, 0x59, 0x7f, 0x71, 0x67, 0xbb, 0xac, 0x74, 0x06, 0xa6, 0x2b, 0x2b, 0x6f, 0xb9,
+ /*8670:*/ 0x92, 0xdb, 0xac, 0x6e, 0x88, 0x56, 0x80, 0x7c, 0xcd, 0x6f, 0x01, 0x5c, 0xa8, 0x10, 0x66, 0xe1,
+ /*8680:*/ 0x4e, 0x28, 0x32, 0xd4, 0xf0, 0x1f, 0x71, 0x3b, 0xcb, 0x80, 0x86, 0x00, 0xe5, 0x85, 0xd5, 0xf6,
+ /*8690:*/ 0x69, 0x62, 0xbf, 0x3a, 0x52, 0x6e, 0xcd, 0x21, 0xde, 0x16, 0xe2, 0x6b, 0x64, 0x0e, 0xae, 0x4e,
+ /*86a0:*/ 0xf3, 0xaa, 0xb4, 0xbe, 0xc7, 0xd0, 0xe1, 0xc4, 0x41, 0xf0, 0xaa, 0x83, 0xf3, 0xfa, 0x36, 0x97,
+ /*86b0:*/ 0x10, 0x36, 0x9a, 0xad, 0xd4, 0x61, 0xf2, 0x19, 0x0e, 0xce, 0xa5, 0x31, 0x24, 0x69, 0xf2, 0xde,
+ /*86c0:*/ 0xb7, 0x90, 0xd1, 0x0b, 0x2b, 0xc7, 0x16, 0x95, 0xf2, 0xa9, 0x54, 0x59, 0x8c, 0x03, 0x66, 0xb5,
+ /*86d0:*/ 0xf4, 0x5c, 0x10, 0x9c, 0xae, 0x19, 0xdd, 0x81, 0xbf, 0x82, 0x6b, 0x3d, 0xf2, 0x52, 0xe3, 0xb4,
+ /*86e0:*/ 0x59, 0x3e, 0x9b, 0x5f, 0x6a, 0x49, 0xa7, 0xb9, 0x5b, 0xae, 0xd7, 0xc0, 0x9f, 0xd5, 0x73, 0x7c,
+ /*86f0:*/ 0x9f, 0xba, 0xcc, 0x8f, 0x8a, 0x87, 0x91, 0xac, 0x5e, 0x24, 0x89, 0xe6, 0x8c, 0x7a, 0x61, 0x04,
+ /*8700:*/ 0x0d, 0xd0, 0x28, 0x83, 0xe0, 0x78, 0x7c, 0x7c, 0x97, 0xf6, 0x8c, 0x24, 0x56, 0x47, 0xb3, 0x6e,
+ /*8710:*/ 0xcb, 0xd3, 0x5c, 0x36, 0xb2, 0xe9, 0x2c, 0x6b, 0xae, 0xf8, 0x09, 0xb2, 0x1c, 0xa9, 0x5b, 0xbc,
+ /*8720:*/ 0xde, 0x9b, 0x8b, 0xcc, 0xc3, 0x05, 0x3d, 0xb9, 0x3d, 0x7b, 0xba, 0xd3, 0xb0, 0x89, 0xfc, 0xb4,
+ /*8730:*/ 0x0a, 0x90, 0x19, 0x7d, 0x96, 0x67, 0x0f, 0x0f, 0x1b, 0x0f, 0x7c, 0xef, 0xed, 0x9f, 0x5f, 0x4e,
+ /*8740:*/ 0x27, 0x5e, 0x64, 0xd9, 0xc5, 0xd8, 0xe8, 0x70, 0xfc, 0xe0, 0xca, 0x69, 0x16, 0x4a, 0xae, 0x0d,
+ /*8750:*/ 0x53, 0x2f, 0x1b, 0x51, 0x0e, 0x4c, 0xcc, 0x4d, 0x5c, 0x43, 0x63, 0x0a, 0x69, 0x10, 0x5a, 0xe9,
+ /*8760:*/ 0x90, 0x93, 0xd0, 0x14, 0xc8, 0x36, 0x30, 0xce, 0xfa, 0x29, 0x88, 0xa8, 0x19, 0xff, 0x32, 0x9c,
+ /*8770:*/ 0xbf, 0xa0, 0xc3, 0x09, 0x7d, 0x6a, 0xb0, 0xbd, 0x42, 0x6f, 0xdd, 0x59, 0x6b, 0xe7, 0xae, 0x05,
+ /*8780:*/ 0x7b, 0xcd, 0x9e, 0xeb, 0xcd, 0xf5, 0x4c, 0x19, 0xce, 0xc3, 0x6f, 0x1c, 0x66, 0x55, 0x9b, 0x17,
+ /*8790:*/ 0xd5, 0x5b, 0xaf, 0xa9, 0x84, 0xf6, 0x80, 0xfd, 0x6f, 0x3e, 0xc1, 0x8e, 0x7b, 0x05, 0x8c, 0x63,
+ /*87a0:*/ 0xf3, 0xb8, 0x7e, 0x91, 0x1c, 0x26, 0x25, 0x96, 0xf9, 0xab, 0xce, 0x80, 0xba, 0x61, 0x03, 0xd9,
+ /*87b0:*/ 0xb8, 0x72, 0x4b, 0x40, 0xea, 0x4b, 0x8c, 0x2d, 0x83, 0x70, 0x50, 0x5f, 0x42, 0x6f, 0x0d, 0xdf,
+ /*87c0:*/ 0xa4, 0xdc, 0x3d, 0x01, 0x51, 0x5f, 0x94, 0x0e, 0x7f, 0xc0, 0x2e, 0xa1, 0xe2, 0x5b, 0x99, 0xf5,
+ /*87d0:*/ 0x32, 0xad, 0x9a, 0x2f, 0x7c, 0xcd, 0x09, 0xb4, 0x71, 0x3b, 0x2e, 0xba, 0xbd, 0xf8, 0xce, 0xba,
+ /*87e0:*/ 0x34, 0x93, 0xd6, 0x2d, 0x35, 0xac, 0x33, 0x99, 0x3a, 0x1a, 0x94, 0xf6, 0x9a, 0x59, 0xf0, 0xcc,
+ /*87f0:*/ 0xe5, 0x46, 0xde, 0xfb, 0x31, 0x7f, 0x0c, 0x95, 0x66, 0x2c, 0xc2, 0x84, 0x00, 0xf6, 0x12, 0xfa,
+ /*8800:*/ 0xb8, 0xbd, 0x24, 0xd3, 0xdd, 0x4d, 0xfc, 0xc9, 0x38, 0xfe, 0x14, 0xd4, 0xb6, 0xe2, 0xc3, 0x2a,
+ /*8810:*/ 0x3f, 0xc3, 0x7e, 0x66, 0x30, 0x4b, 0x3a, 0x14, 0x3d, 0xbb, 0x6f, 0x30, 0x3f, 0xce, 0x27, 0xc4,
+ /*8820:*/ 0xd2, 0xc0, 0x60, 0x41, 0x86, 0x83, 0x11, 0x0c, 0x7e, 0x1a, 0x16, 0xca, 0xb9, 0x44, 0xde, 0xbe,
+ /*8830:*/ 0x84, 0xac, 0x43, 0x67, 0x49, 0x07, 0xb4, 0xc9, 0x75, 0x19, 0xf1, 0x70, 0x95, 0xfb, 0x06, 0x73,
+ /*8840:*/ 0x3d, 0x0a, 0x5b, 0x66, 0x13, 0x7c, 0x0e, 0x10, 0x62, 0x26, 0x30, 0x26, 0x3e, 0xd7, 0x27, 0x57,
+ /*8850:*/ 0xd3, 0xd4, 0x83, 0x31, 0x42, 0xcd, 0x95, 0xcf, 0xbd, 0xf7, 0x46, 0x36, 0x93, 0x91, 0xfc, 0x36,
+ /*8860:*/ 0x34, 0x4b, 0xb8, 0x3a, 0x20, 0xcb, 0x4d, 0x91, 0x78, 0x9e, 0xa7, 0xb4, 0x1a, 0xe4, 0xe2, 0x4a,
+ /*8870:*/ 0x1a, 0xee, 0x39, 0x3a, 0x39, 0xac, 0xa0, 0x4d, 0x12, 0xdf, 0xe6, 0xad, 0xdc, 0xf3, 0x71, 0xa7,
+ /*8880:*/ 0xcb, 0x34, 0xc8, 0xd2, 0xc8, 0x35, 0x82, 0x2a, 0xef, 0x42, 0x32, 0x8a, 0x6c, 0x57, 0xbc, 0xb5,
+ /*8890:*/ 0xd4, 0x8f, 0xca, 0x10, 0x5a, 0x4e, 0x41, 0xc1, 0x1c, 0x50, 0x3a, 0xca, 0x62, 0x95, 0x6b, 0x29,
+ /*88a0:*/ 0x25, 0xbb, 0xfd, 0xc3, 0xbe, 0x2b, 0xce, 0xf6, 0x83, 0xd5, 0xfa, 0x26, 0x30, 0xfa, 0x36, 0xa9,
+ /*88b0:*/ 0xe7, 0x26, 0x4e, 0x95, 0xbb, 0x73, 0xbe, 0x56, 0xc6, 0x26, 0xb4, 0xa7, 0x60, 0x27, 0x19, 0x8f,
+ /*88c0:*/ 0x1d, 0x49, 0xe2, 0xfd, 0x99, 0xce, 0xb1, 0x75, 0x20, 0x34, 0xcf, 0x55, 0xa1, 0xab, 0x4b, 0x4b,
+ /*88d0:*/ 0x89, 0x8b, 0x5e, 0x24, 0xe6, 0x8f, 0xbe, 0x6a, 0xfb, 0x23, 0x9b, 0x52, 0xe2, 0xcd, 0x37, 0xb8,
+ /*88e0:*/ 0xa1, 0xc3, 0xf6, 0x6b, 0xb8, 0x11, 0x33, 0x1f, 0xa6, 0xd2, 0xed, 0x54, 0x0c, 0xce, 0xba, 0xe2,
+ /*88f0:*/ 0x20, 0xb6, 0xca, 0x6d, 0x69, 0xde, 0xc6, 0x7e, 0xa4, 0xd0, 0xbb, 0xb3, 0x31, 0x81, 0xc7, 0x17,
+ /*8900:*/ 0x07, 0x76, 0xc3, 0x72, 0xaf, 0x66, 0x3c, 0x9f, 0x9b, 0x95, 0x51, 0xdc, 0x94, 0xbf, 0xd0, 0x84,
+ /*8910:*/ 0xb8, 0x7c, 0x88, 0xda, 0x3d, 0x2b, 0x15, 0x20, 0xb7, 0x26, 0x9d, 0x3f, 0xd0, 0x5c, 0x10, 0x26,
+ /*8920:*/ 0x42, 0x4a, 0xfc, 0x1f, 0xf9, 0xe3, 0x25, 0x1b, 0xe2, 0x4e, 0x35, 0x76, 0xdf, 0x4c, 0xcc, 0x7e,
+ /*8930:*/ 0x13, 0x46, 0x8d, 0x40, 0xdf, 0xa4, 0xbd, 0x71, 0x6d, 0xa3, 0x8b, 0x0b, 0x2c, 0x31, 0x8c, 0xbd,
+ /*8940:*/ 0x5e, 0x3c, 0x19, 0x0b, 0x2b, 0x59, 0x9d, 0xb2, 0x7f, 0xb7, 0xe1, 0xe4, 0x42, 0x9a, 0x20, 0xcd,
+ /*8950:*/ 0x9e, 0x49, 0x9b, 0x4e, 0x3f, 0xca, 0xc3, 0x45, 0x23, 0xd3, 0x56, 0xd8, 0xe9, 0x83, 0xae, 0x53,
+ /*8960:*/ 0x7e, 0x53, 0x83, 0x37, 0xa0, 0x03, 0x06, 0x26, 0x7b, 0x4d, 0x87, 0x50, 0x48, 0xab, 0x50, 0x7b,
+ /*8970:*/ 0x5b, 0x91, 0x69, 0xeb, 0xbc, 0xce, 0x22, 0x12, 0x36, 0xbc, 0x36, 0xb1, 0xde, 0xf3, 0x92, 0xce,
+ /*8980:*/ 0x8e, 0x4b, 0x5c, 0xdc, 0xa5, 0x46, 0xab, 0x1d, 0x60, 0x0b, 0xf2, 0x2b, 0xbe, 0xf4, 0xa5, 0xa2,
+ /*8990:*/ 0x69, 0xf1, 0x7e, 0x5f, 0x53, 0x28, 0xd9, 0xec, 0xb7, 0xf5, 0x8b, 0x9d, 0x87, 0x18, 0xac, 0x7c,
+ /*89a0:*/ 0x33, 0x1e, 0x8b, 0xfc, 0x77, 0x4c, 0xae, 0xbc, 0x33, 0xae, 0x25, 0xa0, 0x7a, 0x91, 0xd3, 0x22,
+ /*89b0:*/ 0xc4, 0xbf, 0x18, 0xb3, 0xa3, 0x6a, 0x79, 0x22, 0xb5, 0x07, 0x30, 0xd8, 0x71, 0x79, 0xf7, 0xd2,
+ /*89c0:*/ 0x35, 0xab, 0x51, 0xce, 0x51, 0xcb, 0xd6, 0x22, 0x61, 0xf8, 0x92, 0xe7, 0xeb, 0xb0, 0x15, 0x9a,
+ /*89d0:*/ 0xb4, 0x6f, 0x5c, 0x9c, 0x0f, 0xad, 0x41, 0x61, 0xbe, 0xbd, 0x0e, 0xc4, 0xb0, 0x15, 0x34, 0xc4,
+ /*89e0:*/ 0xf7, 0x8c, 0xf0, 0x26, 0xbe, 0x7f, 0x99, 0xd0, 0x04, 0x5a, 0x90, 0x9d, 0x16, 0xe8, 0x93, 0x8a,
+ /*89f0:*/ 0x39, 0xb0, 0x2c, 0xfa, 0x03, 0x78, 0xb3, 0x2e, 0x5d, 0x06, 0x6a, 0x21, 0x3b, 0x8a, 0x7a, 0x22,
+ /*8a00:*/ 0x10, 0x70, 0x82, 0x1c, 0x69, 0x88, 0x89, 0x51, 0x11, 0x43, 0x7c, 0x9c, 0x3e, 0xcd, 0x7e, 0x7a,
+ /*8a10:*/ 0x99, 0xb4, 0x1c, 0xf3, 0xd8, 0xd3, 0x1b, 0xfa, 0x9d, 0xec, 0xd4, 0x36, 0xcc, 0xac, 0x5e, 0xc3,
+ /*8a20:*/ 0xd9, 0x45, 0x7b, 0xc6, 0x7b, 0x1d, 0xfe, 0xa5, 0xac, 0xb9, 0x22, 0xe0, 0x18, 0xc0, 0x1d, 0x04,
+ /*8a30:*/ 0xfe, 0x9a, 0xb9, 0xc8, 0x40, 0xa2, 0xcc, 0x3e, 0xb4, 0x81, 0xfe, 0x0f, 0xf8, 0xc4, 0xe0, 0x89,
+ /*8a40:*/ 0xfc, 0xfd, 0x93, 0x2d, 0xd0, 0x00, 0x52, 0x70, 0x5a, 0x95, 0x41, 0x4e, 0xbd, 0xd3, 0x76, 0x2b,
+ /*8a50:*/ 0xa4, 0xa3, 0x56, 0x22, 0x50, 0x6d, 0xc2, 0xd2, 0x59, 0xea, 0xe8, 0x32, 0x9c, 0x84, 0xdc, 0x93,
+ /*8a60:*/ 0xad, 0xdb, 0xaf, 0xba, 0xb3, 0x0e, 0x38, 0x0a, 0xac, 0xde, 0xe7, 0xff, 0x87, 0xcd, 0x9b, 0x80,
+ /*8a70:*/ 0xea, 0x72, 0x10, 0x66, 0xff, 0x63, 0x7f, 0xe6, 0x33, 0x88, 0xd2, 0xc0, 0xdc, 0xd6, 0xcb, 0xe6,
+ /*8a80:*/ 0xcb, 0x37, 0x70, 0x74, 0x72, 0x26, 0xac, 0x73, 0xbf, 0x1d, 0x6f, 0x75, 0x6c, 0xe5, 0xb5, 0x37,
+ /*8a90:*/ 0x4e, 0xc3, 0x85, 0x58, 0x79, 0x2a, 0x21, 0x51, 0xe1, 0x16, 0x00, 0x31, 0x75, 0x0e, 0x79, 0x5e,
+ /*8aa0:*/ 0x3d, 0x84, 0x19, 0x22, 0x2b, 0x97, 0x4a, 0x59, 0x2b, 0xa0, 0x79, 0x53, 0x45, 0x34, 0x35, 0x2f,
+ /*8ab0:*/ 0x8a, 0xfd, 0x64, 0xf2, 0x0b, 0xb5, 0xe4, 0xb9, 0x73, 0xe9, 0xee, 0x47, 0xb0, 0x51, 0x5a, 0x5f,
+ /*8ac0:*/ 0xf9, 0x2a, 0xe1, 0xd5, 0x5a, 0xee, 0x67, 0xaf, 0xb5, 0xfa, 0x28, 0x8a, 0xec, 0xec, 0x5f, 0x38,
+ /*8ad0:*/ 0x4a, 0xdb, 0x0e, 0x1a, 0xbd, 0x57, 0x09, 0xcc, 0x02, 0x09, 0xa4, 0x1f, 0xe1, 0x5b, 0x4d, 0x80,
+ /*8ae0:*/ 0xb0, 0x85, 0x97, 0xbb, 0x7e, 0x3e, 0x14, 0x18, 0xe6, 0xc8, 0x84, 0x57, 0x88, 0x3c, 0xe8, 0x09,
+ /*8af0:*/ 0x91, 0x93, 0xda, 0x5a, 0x77, 0x9a, 0x23, 0x77, 0x18, 0x1c, 0x16, 0xb8, 0x22, 0xf6, 0xc5, 0x73,
+ /*8b00:*/ 0xc3, 0xc4, 0x44, 0x4b, 0x8b, 0xa5, 0x4f, 0xdc, 0xa1, 0x65, 0xc1, 0x99, 0xfb, 0x97, 0xf8, 0x4f,
+ /*8b10:*/ 0xe9, 0xd0, 0xc4, 0x66, 0xd4, 0xed, 0x3e, 0x58, 0x8d, 0x6c, 0x09, 0xe7, 0xad, 0xde, 0x66, 0xa6,
+ /*8b20:*/ 0x82, 0xfc, 0xc2, 0xf8, 0x04, 0x6f, 0x5c, 0x6a, 0xeb, 0x96, 0x85, 0x28, 0x03, 0xc7, 0x3f, 0xa7,
+ /*8b30:*/ 0x31, 0x75, 0x71, 0x56, 0x8d, 0x98, 0x0d, 0x08, 0x21, 0x1f, 0x59, 0x0c, 0x99, 0x72, 0x6a, 0xa4,
+ /*8b40:*/ 0xa7, 0x6f, 0x34, 0x70, 0x5e, 0x5a, 0xb5, 0x73, 0x01, 0xcb, 0xea, 0xa9, 0x59, 0x14, 0xa1, 0xfb,
+ /*8b50:*/ 0xda, 0x5d, 0x7d, 0x22, 0x35, 0x83, 0xd1, 0x16, 0x8a, 0x15, 0x2f, 0x4a, 0xb8, 0xfa, 0xf6, 0x6f,
+ /*8b60:*/ 0x92, 0x64, 0xbb, 0x32, 0xcb, 0x56, 0xd8, 0xec, 0xda, 0xec, 0xb7, 0x52, 0x77, 0x90, 0x36, 0x29,
+ /*8b70:*/ 0x65, 0x47, 0xdc, 0xc8, 0x31, 0x6b, 0xa5, 0xff, 0xf3, 0x00, 0x8d, 0x49, 0xb5, 0x70, 0xa7, 0x48,
+ /*8b80:*/ 0x53, 0x05, 0x6b, 0x0f, 0x49, 0x50, 0xb2, 0xdb, 0x8d, 0x77, 0x6d, 0x45, 0x03, 0xc4, 0x5a, 0xc0,
+ /*8b90:*/ 0x1f, 0x1d, 0x0f, 0x13, 0xc3, 0x7d, 0x0f, 0x75, 0xfc, 0xc5, 0xf1, 0x73, 0xcc, 0x14, 0x97, 0xc3,
+ /*8ba0:*/ 0x87, 0x45, 0xc7, 0x9e, 0xd5, 0x6b, 0x9b, 0x84, 0xd4, 0x00, 0x77, 0x0f, 0x67, 0xb1, 0x2c, 0xc8,
+ /*8bb0:*/ 0xdc, 0xa5, 0x13, 0xb0, 0x61, 0x61, 0x2b, 0x9c, 0xda, 0x51, 0xad, 0xfc, 0x49, 0x05, 0xc0, 0x47,
+ /*8bc0:*/ 0xb2, 0x43, 0x1c, 0x54, 0x47, 0xd4, 0xfb, 0x5a, 0xb3, 0x95, 0xda, 0xee, 0x0b, 0x0a, 0x4a, 0x94,
+ /*8bd0:*/ 0x4d, 0x3d, 0xdf, 0xf0, 0xb3, 0xb0, 0xb8, 0x60, 0xf7, 0x80, 0x97, 0xa8, 0xea, 0xdf, 0xde, 0x5e,
+ /*8be0:*/ 0x61, 0xff, 0x2a, 0x17, 0x6d, 0xfe, 0x53, 0x98, 0x4e, 0x2c, 0x22, 0x09, 0xc7, 0x09, 0x5b, 0xa0,
+ /*8bf0:*/ 0x2f, 0x90, 0xce, 0xb8, 0x70, 0xf1, 0xb2, 0x7c, 0xa0, 0x91, 0x8d, 0x9b, 0x26, 0x1a, 0x5c, 0x5b,
+ /*8c00:*/ 0xbc, 0x3d, 0xa8, 0xbb, 0x47, 0xde, 0x20, 0x1c, 0x22, 0xb7, 0xdf, 0xdf, 0x04, 0x5e, 0x97, 0xf7,
+ /*8c10:*/ 0xa7, 0xbb, 0x2e, 0x78, 0x62, 0xe9, 0xad, 0x73, 0x60, 0x37, 0x8d, 0x2c, 0x5d, 0x3e, 0xe3, 0x40,
+ /*8c20:*/ 0xdd, 0xb4, 0xc6, 0x1d, 0xe4, 0x8c, 0x79, 0x12, 0x3e, 0xe2, 0x38, 0x2e, 0xd4, 0xec, 0xcc, 0xeb,
+ /*8c30:*/ 0xe4, 0x37, 0xd5, 0x6e, 0x1b, 0x05, 0x20, 0xa3, 0x36, 0x45, 0x0f, 0xcf, 0xad, 0x31, 0x5b, 0xb6,
+ /*8c40:*/ 0x6f, 0x10, 0xc4, 0x95, 0x3b, 0xef, 0x07, 0xf4, 0xae, 0x4e, 0xb8, 0x93, 0x88, 0x30, 0x6a, 0x92,
+ /*8c50:*/ 0x83, 0xcd, 0xab, 0x19, 0xca, 0x30, 0xd2, 0x1d, 0x27, 0x00, 0x22, 0x42, 0xe8, 0x5f, 0x60, 0x54,
+ /*8c60:*/ 0x0d, 0xa1, 0xcf, 0x27, 0xb2, 0x95, 0xd2, 0x65, 0x1d, 0xb4, 0xb4, 0xc2, 0x57, 0x61, 0x7e, 0x12,
+ /*8c70:*/ 0x5e, 0x84, 0x0f, 0xa3, 0x02, 0xfe, 0x2e, 0x3c, 0xf2, 0x0e, 0xd7, 0x22, 0xb9, 0xae, 0xb6, 0xed,
+ /*8c80:*/ 0x48, 0xfd, 0xe3, 0x02, 0x42, 0xf4, 0x5e, 0x84, 0xb5, 0xce, 0xe4, 0x39, 0xa1, 0x26, 0x57, 0xc2,
+ /*8c90:*/ 0xe1, 0x05, 0x82, 0x66, 0x53, 0x6b, 0x7b, 0x26, 0x32, 0x58, 0x6f, 0x1c, 0x9c, 0x79, 0xa8, 0xd5,
+ /*8ca0:*/ 0x0b, 0xab, 0x75, 0xed, 0x34, 0x55, 0xc4, 0x55, 0x8a, 0x08, 0xb5, 0xdd, 0x96, 0xc8, 0xf0, 0x0f,
+ /*8cb0:*/ 0x3b, 0xe9, 0x03, 0xc5, 0x21, 0xcb, 0x52, 0xac, 0x80, 0x1a, 0x05, 0x81, 0x44, 0x75, 0x19, 0xb4,
+ /*8cc0:*/ 0x9e, 0x2e, 0x40, 0x50, 0xbf, 0xb2, 0x56, 0x1d, 0xd0, 0xc6, 0xcb, 0x09, 0x95, 0x55, 0xfd, 0xcc,
+ /*8cd0:*/ 0xd0, 0x5e, 0x3a, 0xab, 0x13, 0xf0, 0xdc, 0xb6, 0xfd, 0x80, 0x92, 0xf5, 0x24, 0xd9, 0xcc, 0xd2,
+ /*8ce0:*/ 0xf9, 0x37, 0xef, 0x42, 0x56, 0x0a, 0xf3, 0x67, 0xf4, 0x09, 0x0a, 0x3b, 0x24, 0x46, 0x85, 0x4c,
+ /*8cf0:*/ 0x54, 0x2b, 0x1d, 0xee, 0xc6, 0x2c, 0xe2, 0x30, 0x42, 0x20, 0xda, 0x3c, 0xe5, 0xac, 0x84, 0x9e,
+ /*8d00:*/ 0x64, 0xc1, 0xf8, 0xbc, 0x2b, 0xcb, 0xb1, 0x92, 0xa6, 0x82, 0x9f, 0x31, 0xec, 0x5b, 0x82, 0x41,
+ /*8d10:*/ 0x9b, 0x59, 0xe8, 0x70, 0x87, 0xcf, 0xd0, 0xd3, 0xfc, 0xc9, 0xbe, 0x8a, 0xba, 0x8e, 0x81, 0x7c,
+ /*8d20:*/ 0x54, 0xf3, 0x96, 0x66, 0xec, 0x3e, 0x0c, 0x7d, 0xdf, 0x46, 0xe3, 0xdf, 0xad, 0x64, 0x10, 0xc1,
+ /*8d30:*/ 0x7e, 0x71, 0x62, 0xd4, 0xc9, 0x92, 0x6f, 0xae, 0x46, 0x33, 0x44, 0xfd, 0xb2, 0x68, 0x4e, 0xd4,
+ /*8d40:*/ 0xdf, 0x00, 0x1e, 0xda, 0xfd, 0x25, 0x01, 0x56, 0x2e, 0xd6, 0xec, 0xa0, 0xca, 0x47, 0x3e, 0x9f,
+ /*8d50:*/ 0x0e, 0xd8, 0x91, 0x51, 0xb3, 0x5e, 0xf1, 0x09, 0x6a, 0xa2, 0x66, 0x90, 0xe7, 0x5d, 0x89, 0x97,
+ /*8d60:*/ 0x4e, 0xb1, 0x2b, 0xe4, 0x2b, 0x0a, 0x5e, 0x29, 0x19, 0xd7, 0xbd, 0x72, 0xc4, 0xf4, 0xdd, 0xbf,
+ /*8d70:*/ 0x2f, 0x9c, 0x37, 0x41, 0xed, 0x5e, 0x6f, 0x8e, 0x54, 0xdb, 0x4b, 0x60, 0x5b, 0x24, 0x5e, 0x7c,
+ /*8d80:*/ 0x8f, 0xf5, 0x6a, 0xb8, 0x1a, 0x31, 0xd9, 0x64, 0xb6, 0x5a, 0x47, 0x59, 0xf9, 0x19, 0xc8, 0x67,
+ /*8d90:*/ 0xc3, 0x92, 0x0d, 0xb7, 0x27, 0xfa, 0x88, 0x10, 0x96, 0x27, 0x76, 0xf9, 0x0a, 0x29, 0x09, 0x36,
+ /*8da0:*/ 0x93, 0xe2, 0x00, 0x29, 0xdc, 0x27, 0x35, 0x82, 0x45, 0x27, 0xc9, 0xf9, 0x87, 0xdb, 0x02, 0x2c,
+ /*8db0:*/ 0xcd, 0x80, 0x60, 0x8f, 0xab, 0x34, 0x59, 0xb1, 0x95, 0x50, 0xc7, 0x7f, 0x8b, 0xd5, 0x32, 0x1a,
+ /*8dc0:*/ 0xed, 0xd5, 0xef, 0x9a, 0x0b, 0x5f, 0x67, 0x53, 0xdf, 0xe3, 0xa0, 0xa0, 0x45, 0xef, 0xd0, 0x96,
+ /*8dd0:*/ 0xf2, 0x4a, 0x03, 0xe7, 0x88, 0xe1, 0x0d, 0xcc, 0x37, 0x8a, 0x2b, 0x83, 0x45, 0x23, 0x99, 0x2a,
+ /*8de0:*/ 0xc0, 0x57, 0xd0, 0xea, 0xd5, 0xb7, 0xc4, 0x38, 0xae, 0xe5, 0x2c, 0x77, 0x97, 0xc2, 0x7b, 0xcf,
+ /*8df0:*/ 0x76, 0x5f, 0x29, 0xf4, 0xbb, 0xb8, 0xcf, 0xb4, 0xd7, 0xe5, 0x58, 0x02, 0xf0, 0x10, 0xe8, 0xda,
+ /*8e00:*/ 0x29, 0x06, 0xc3, 0x56, 0xf1, 0x1b, 0x22, 0xc9, 0x83, 0x3d, 0x68, 0xca, 0x32, 0x1c, 0x3a, 0x2b,
+ /*8e10:*/ 0xbe, 0x83, 0xb6, 0x19, 0x0b, 0xad, 0xa7, 0x0e, 0x7b, 0x4e, 0x9e, 0xa5, 0xaa, 0xc6, 0xb8, 0x33,
+ /*8e20:*/ 0x66, 0x57, 0xca, 0x1e, 0x61, 0xef, 0x4b, 0x1b, 0xb9, 0x4a, 0xc1, 0x84, 0x65, 0x43, 0x38, 0xa2,
+ /*8e30:*/ 0x13, 0x05, 0x4e, 0xe4, 0xe8, 0xac, 0x47, 0xd9, 0xb8, 0x3e, 0x14, 0xd4, 0x0c, 0x98, 0xdc, 0x1f,
+ /*8e40:*/ 0x92, 0x74, 0x92, 0xaf, 0xa6, 0x56, 0x36, 0xc4, 0xf0, 0xd5, 0x14, 0x66, 0xb2, 0xc9, 0x68, 0x51,
+ /*8e50:*/ 0xaf, 0x93, 0xa6, 0xe7, 0x76, 0x74, 0x18, 0x84, 0xc6, 0xb3, 0x93, 0x19, 0xc8, 0xe8, 0x92, 0x31,
+ /*8e60:*/ 0x84, 0xb2, 0xd2, 0x1a, 0x6d, 0x70, 0x95, 0xaa, 0x16, 0x63, 0x2d, 0xa9, 0x90, 0x9e, 0x66, 0x80,
+ /*8e70:*/ 0x71, 0xe0, 0xc6, 0xc4, 0x50, 0xf8, 0x20, 0x80, 0xcd, 0xbe, 0x08, 0x5d, 0xdd, 0x69, 0x51, 0xbb,
+ /*8e80:*/ 0x1a, 0xd0, 0x28, 0x7f, 0x02, 0x0f, 0xac, 0x90, 0xb6, 0xfc, 0xaa, 0x81, 0x09, 0x3e, 0xc5, 0x72,
+ /*8e90:*/ 0x7e, 0x30, 0xe3, 0x42, 0x81, 0x8b, 0x03, 0x8b, 0x1f, 0x96, 0x02, 0xfa, 0xe1, 0xf3, 0xc5, 0x1e,
+ /*8ea0:*/ 0xfd, 0x5e, 0x30, 0xfe, 0xec, 0x09, 0x86, 0x83, 0x48, 0x78, 0x41, 0x48, 0xf7, 0x42, 0xa0, 0xe5,
+ /*8eb0:*/ 0xc7, 0x50, 0x5b, 0x60, 0xa8, 0xb1, 0xdc, 0xe4, 0xc3, 0x30, 0xca, 0x3b, 0xdc, 0x16, 0x13, 0xf7,
+ /*8ec0:*/ 0xca, 0xff, 0x1f, 0x74, 0x73, 0x47, 0x52, 0x2c, 0x54, 0x2f, 0x1b, 0xe2, 0xb5, 0xaf, 0xaf, 0xc7,
+ /*8ed0:*/ 0x2c, 0x53, 0x16, 0x0f, 0xf7, 0xe7, 0x99, 0x7d, 0x57, 0x88, 0xe6, 0x39, 0xe7, 0x66, 0x73, 0xaf,
+ /*8ee0:*/ 0xab, 0x9f, 0x74, 0x4f, 0x0a, 0xd9, 0x0d, 0x9d, 0xc1, 0x5c, 0x43, 0x8d, 0x7a, 0x90, 0x56, 0xe2,
+ /*8ef0:*/ 0xd7, 0x8e, 0x76, 0xd9, 0xe9, 0x7f, 0x93, 0x66, 0x1c, 0x32, 0x1e, 0xda, 0x25, 0xbf, 0x28, 0x85,
+ /*8f00:*/ 0xea, 0xe8, 0x72, 0x9b, 0x7b, 0x32, 0xd7, 0xac, 0x20, 0xc2, 0x2e, 0x08, 0x27, 0x0e, 0xa6, 0x80,
+ /*8f10:*/ 0x6c, 0x15, 0x49, 0x20, 0xda, 0x01, 0xae, 0x5f, 0x07, 0x1e, 0xc2, 0x13, 0xcf, 0x51, 0xbe, 0xca,
+ /*8f20:*/ 0x68, 0x22, 0x59, 0xff, 0x0c, 0x05, 0xe2, 0x3a, 0xa3, 0xce, 0x60, 0xde, 0x7b, 0xa7, 0x89, 0xa1,
+ /*8f30:*/ 0x8b, 0xad, 0xc0, 0x5d, 0x5e, 0x31, 0x52, 0x64, 0x1a, 0xc1, 0x0e, 0xd2, 0xb2, 0x56, 0x4c, 0x01,
+ /*8f40:*/ 0xd9, 0x0e, 0xa8, 0x1b, 0x64, 0x7b, 0xa7, 0xcd, 0x02, 0x6f, 0x43, 0xbe, 0xfa, 0x46, 0x5c, 0xdd,
+ /*8f50:*/ 0xae, 0x5b, 0xe7, 0x53, 0x11, 0x3a, 0xc9, 0x03, 0xfb, 0x64, 0xfd, 0xfc, 0x89, 0x45, 0xf5, 0x8b,
+ /*8f60:*/ 0x54, 0x41, 0x15, 0xa2, 0x68, 0x72, 0x35, 0x21, 0xcf, 0xa5, 0x20, 0xb5, 0xbc, 0x3c, 0x0d, 0xa0,
+ /*8f70:*/ 0xed, 0xf5, 0xe9, 0xfd, 0xb2, 0x8e, 0x12, 0xc3, 0xcf, 0x9a, 0x96, 0x2f, 0x19, 0x9f, 0x2a, 0xdc,
+ /*8f80:*/ 0x1d, 0x7e, 0x2d, 0x98, 0x7d, 0x88, 0x6a, 0x84, 0x4a, 0xb5, 0xca, 0xaf, 0x77, 0x83, 0xea, 0x92,
+ /*8f90:*/ 0x10, 0xd9, 0x81, 0xc5, 0x8b, 0x38, 0x01, 0xc6, 0x4b, 0x00, 0x85, 0x58, 0xaa, 0x79, 0xe4, 0x95,
+ /*8fa0:*/ 0x09, 0x31, 0x93, 0x5e, 0x74, 0xee, 0x87, 0x26, 0x91, 0xd7, 0x82, 0x89, 0x77, 0x99, 0xf7, 0xc2,
+ /*8fb0:*/ 0x3e, 0x0b, 0xd9, 0xe6, 0x67, 0x15, 0x8b, 0x62, 0xe7, 0x1f, 0xde, 0x9c, 0xf4, 0xee, 0x19, 0x06,
+ /*8fc0:*/ 0xec, 0x04, 0x9f, 0xe2, 0xcd, 0x27, 0xce, 0x57, 0xb2, 0xa8, 0x8c, 0xac, 0x9f, 0x26, 0xdb, 0xc7,
+ /*8fd0:*/ 0x44, 0xcc, 0x03, 0x0b, 0x44, 0xff, 0xa5, 0x52, 0x79, 0x7d, 0xea, 0x54, 0x31, 0xa0, 0xe9, 0xbb,
+ /*8fe0:*/ 0x89, 0x05, 0x07, 0x7a, 0x29, 0x3f, 0xa1, 0xd2, 0xff, 0xd2, 0x5b, 0x1a, 0x86, 0xca, 0x96, 0x6b,
+ /*8ff0:*/ 0x86, 0x59, 0x7a, 0x43, 0x82, 0xd4, 0x63, 0x9f, 0x92, 0xfa, 0x54, 0x92, 0x72, 0x2b, 0x1b, 0x4d,
+ /*9000:*/ 0x98, 0x22, 0x9f, 0xbf, 0x4e, 0xd9, 0x15, 0xbf, 0x77, 0x18, 0xf3, 0x40, 0x25, 0xfc, 0x32, 0xe1,
+ /*9010:*/ 0x6e, 0xc5, 0xd4, 0xc7, 0x92, 0xf3, 0xa3, 0x44, 0x29, 0xe3, 0xdb, 0x95, 0xe9, 0x9d, 0xdf, 0x6a,
+ /*9020:*/ 0x46, 0xd6, 0xcd, 0x67, 0x36, 0x09, 0xfa, 0xa1, 0x01, 0xc4, 0x55, 0x84, 0x1c, 0xb4, 0x02, 0x7e,
+ /*9030:*/ 0x5f, 0x70, 0x25, 0xc1, 0x61, 0x9c, 0xfc, 0xa2, 0xa2, 0x15, 0x17, 0x7d, 0x9c, 0x5f, 0x67, 0x41,
+ /*9040:*/ 0xca, 0x60, 0x0b, 0x9e, 0x48, 0x71, 0x16, 0xc6, 0x0b, 0xf4, 0x03, 0x86, 0xb5, 0x0e, 0xad, 0xc6,
+ /*9050:*/ 0xf8, 0xbd, 0x96, 0x46, 0xe1, 0xc6, 0xe0, 0x96, 0x0a, 0x95, 0xda, 0x5f, 0xba, 0x0b, 0x56, 0xc1,
+ /*9060:*/ 0x39, 0x20, 0xd0, 0xa8, 0xf4, 0x06, 0x7c, 0xc7, 0x02, 0xed, 0x5a, 0x7b, 0xaa, 0x0f, 0x4c, 0x71,
+ /*9070:*/ 0xf7, 0x8a, 0xeb, 0x95, 0xd9, 0x08, 0xfa, 0x57, 0xd4, 0x0a, 0xed, 0x10, 0xda, 0xf8, 0x3e, 0xa0,
+ /*9080:*/ 0xeb, 0xf2, 0x27, 0x2f, 0x7f, 0x65, 0x47, 0x76, 0x33, 0x0f, 0x96, 0xc7, 0x6e, 0xbe, 0x07, 0xe7,
+ /*9090:*/ 0xd5, 0xdc, 0x49, 0xc3, 0x94, 0x32, 0xc0, 0xa0, 0xb1, 0x80, 0xab, 0x0a, 0xd7, 0x7b, 0x88, 0x10,
+ /*90a0:*/ 0xa1, 0x0b, 0x23, 0x5b, 0x2f, 0x61, 0x67, 0xd0, 0x01, 0xd9, 0xb4, 0xc3, 0xda, 0x34, 0xb3, 0x09,
+ /*90b0:*/ 0x58, 0x9f, 0x7b, 0x65, 0x4e, 0x8b, 0xc2, 0xb7, 0x19, 0x6f, 0x27, 0x72, 0x8e, 0x20, 0x32, 0x23,
+ /*90c0:*/ 0xcb, 0xbd, 0x3a, 0x97, 0xf6, 0xb0, 0xc0, 0xab, 0x23, 0x2d, 0x37, 0x1f, 0x00, 0x54, 0xbc, 0x51,
+ /*90d0:*/ 0x17, 0xd1, 0x79, 0xbe, 0x2b, 0x24, 0xe7, 0xfc, 0x2a, 0x61, 0x04, 0xc9, 0xc5, 0x95, 0x7e, 0x09,
+ /*90e0:*/ 0x53, 0x9f, 0x6c, 0x93, 0x26, 0x48, 0xa1, 0x21, 0x84, 0xcc, 0x3c, 0xbc, 0x48, 0x67, 0xdb, 0x82,
+ /*90f0:*/ 0x73, 0xdf, 0x42, 0xe4, 0xf0, 0x34, 0x28, 0xff, 0xa5, 0x32, 0x4d, 0x6f, 0xa7, 0x09, 0x07, 0xa9,
+ /*9100:*/ 0x70, 0xaf, 0x1a, 0xd4, 0x41, 0x92, 0x7a, 0x7e, 0x6b, 0x7b, 0x43, 0xd1, 0xa8, 0x79, 0xdd, 0x29,
+ /*9110:*/ 0xf9, 0x37, 0xb3, 0x3f, 0xad, 0x3c, 0x59, 0xc2, 0x01, 0x5c, 0x50, 0xbd, 0x65, 0x57, 0xbe, 0x63,
+ /*9120:*/ 0x62, 0x8e, 0x3f, 0x66, 0xf3, 0xd7, 0x38, 0xa4, 0x65, 0x67, 0xab, 0x24, 0xbb, 0x5c, 0x94, 0x38,
+ /*9130:*/ 0xda, 0x46, 0x36, 0xc3, 0x06, 0x88, 0x7e, 0xba, 0x7c, 0x2c, 0xc1, 0x47, 0x78, 0x1d, 0x9f, 0x5b,
+ /*9140:*/ 0xd8, 0x58, 0xc7, 0xd4, 0x7c, 0x47, 0xab, 0x05, 0xe2, 0xcb, 0x44, 0xe2, 0xbf, 0x9b, 0xc8, 0xe9,
+ /*9150:*/ 0x45, 0xe7, 0x3f, 0x27, 0x8a, 0xbe, 0xed, 0x82, 0x09, 0xa3, 0xa4, 0x71, 0x65, 0x4d, 0x8f, 0xdd,
+ /*9160:*/ 0x52, 0xfa, 0x4f, 0xfb, 0x47, 0x70, 0x03, 0x34, 0x34, 0xc2, 0x3a, 0xf4, 0xb5, 0xa2, 0xa5, 0xc6,
+ /*9170:*/ 0x82, 0xea, 0x76, 0x1b, 0x89, 0x14, 0xd4, 0xec, 0x2e, 0x47, 0xb1, 0x22, 0xde, 0xaf, 0xa0, 0x36,
+ /*9180:*/ 0x8d, 0xcf, 0xc1, 0xe0, 0x49, 0x07, 0xbf, 0x7c, 0xad, 0xf9, 0xf5, 0x10, 0x70, 0x49, 0x5e, 0x76,
+ /*9190:*/ 0x0a, 0x64, 0xa1, 0xde, 0x47, 0xde, 0x42, 0xc4, 0xc9, 0x0e, 0xcc, 0x97, 0x16, 0xa3, 0x72, 0x94,
+ /*91a0:*/ 0xde, 0x16, 0x03, 0xa1, 0xf6, 0x87, 0x97, 0x5c, 0x6a, 0xed, 0x99, 0x94, 0x48, 0x27, 0xc9, 0x33,
+ /*91b0:*/ 0x42, 0xdc, 0x13, 0x8b, 0xef, 0x93, 0x21, 0xa1, 0x53, 0x8f, 0xd8, 0xcb, 0xb1, 0xef, 0x66, 0xfa,
+ /*91c0:*/ 0xc5, 0x01, 0xa9, 0x11, 0xfc, 0x52, 0x91, 0x28, 0x82, 0x00, 0x7d, 0xeb, 0xfc, 0xbb, 0x03, 0x3c,
+ /*91d0:*/ 0x90, 0x83, 0x0d, 0x37, 0x10, 0xdc, 0xdf, 0xd3, 0x6d, 0xb8, 0x36, 0xc1, 0xad, 0x4e, 0xf5, 0x54,
+ /*91e0:*/ 0xed, 0x2b, 0x85, 0x14, 0xe4, 0x50, 0x80, 0x88, 0x7e, 0x9d, 0x0c, 0x41, 0x13, 0x8b, 0x2b, 0x32,
+ /*91f0:*/ 0x2e, 0xc6, 0x52, 0x2e, 0x3f, 0x12, 0x53, 0xee, 0x63, 0x6d, 0xad, 0xfb, 0x04, 0xf9, 0xc0, 0xc4,
+ /*9200:*/ 0x7e, 0x71, 0x59, 0x9f, 0x28, 0xc8, 0xde, 0x50, 0xd3, 0xe3, 0xeb, 0xdd, 0x01, 0x55, 0x83, 0x8b,
+ /*9210:*/ 0xed, 0x76, 0x01, 0x02, 0xc4, 0x94, 0xb1, 0x47, 0xfe, 0xa8, 0x0e, 0x95, 0xdf, 0xaa, 0x82, 0x44,
+ /*9220:*/ 0x9b, 0x61, 0x65, 0xbc, 0x4b, 0xbc, 0x86, 0x85, 0xbd, 0x45, 0xee, 0x87, 0xd0, 0x76, 0x68, 0xe1,
+ /*9230:*/ 0xa7, 0x19, 0x0a, 0x75, 0xc4, 0x22, 0x32, 0x75, 0x01, 0x03, 0x8c, 0x98, 0xfa, 0x13, 0x79, 0x17,
+ /*9240:*/ 0x43, 0x8a, 0x76, 0x6e, 0xa7, 0x22, 0x46, 0x29, 0x0f, 0xb3, 0x1f, 0xa5, 0xf6, 0x34, 0x6d, 0x03,
+ /*9250:*/ 0xef, 0xf9, 0xcf, 0x52, 0x17, 0xef, 0x65, 0x01, 0xd9, 0x9d, 0xc1, 0x74, 0x10, 0x96, 0x5a, 0x60,
+ /*9260:*/ 0xc1, 0xc1, 0x79, 0xcc, 0xfe, 0x44, 0x80, 0x12, 0x15, 0x12, 0xf3, 0xa4, 0x6f, 0x45, 0x53, 0x03,
+ /*9270:*/ 0xbf, 0xcb, 0xbc, 0xaf, 0x11, 0xab, 0x2d, 0x56, 0x12, 0xeb, 0xd8, 0x16, 0x40, 0xd1, 0x2b, 0xfb,
+ /*9280:*/ 0xc5, 0x76, 0x7d, 0xc3, 0xe1, 0xcc, 0xd4, 0x0a, 0x15, 0xef, 0x78, 0x64, 0xdb, 0x1b, 0x67, 0x40,
+ /*9290:*/ 0x7c, 0xb9, 0x01, 0xc8, 0xaf, 0x29, 0xcc, 0x06, 0x74, 0x72, 0xd1, 0xf8, 0x9e, 0x77, 0x0a, 0xe4,
+ /*92a0:*/ 0x4d, 0x3e, 0xc5, 0x35, 0xd1, 0x3e, 0xcd, 0x8b, 0xd6, 0x75, 0x18, 0x0c, 0xdd, 0xc1, 0x1a, 0x2a,
+ /*92b0:*/ 0x83, 0x26, 0x64, 0x6b, 0x3a, 0x53, 0x04, 0x13, 0xb2, 0x51, 0x89, 0x17, 0xfd, 0xe7, 0x8e, 0x8b,
+ /*92c0:*/ 0xfb, 0xd1, 0x17, 0x61, 0x42, 0x30, 0x0b, 0xcb, 0x1d, 0x4b, 0x95, 0xbe, 0x60, 0xce, 0xf9, 0x53,
+ /*92d0:*/ 0xd5, 0x46, 0x7a, 0x46, 0x20, 0xed, 0x2b, 0xb0, 0x7a, 0x76, 0x07, 0x50, 0xcf, 0x72, 0x29, 0x93,
+ /*92e0:*/ 0x6d, 0x49, 0x43, 0xde, 0xb5, 0x06, 0x7a, 0xed, 0x99, 0x4e, 0x1b, 0x87, 0x71, 0xc8, 0x60, 0xb4,
+ /*92f0:*/ 0xd4, 0x3b, 0xe8, 0xbd, 0x2a, 0x21, 0x23, 0xba, 0x42, 0x81, 0xde, 0xe8, 0x60, 0xd7, 0xfd, 0xfd,
+ /*9300:*/ 0x99, 0x2b, 0x50, 0xfc, 0xa6, 0xa0, 0x03, 0xa2, 0x29, 0xdf, 0x0e, 0x2c, 0x02, 0x06, 0x33, 0xe7,
+ /*9310:*/ 0x34, 0x9a, 0x54, 0x43, 0x0c, 0xeb, 0xf0, 0xe8, 0x61, 0x05, 0x6a, 0x60, 0xb5, 0x64, 0xc7, 0x58,
+ /*9320:*/ 0xd0, 0x24, 0xe0, 0xfe, 0x6a, 0xd8, 0xb0, 0xa5, 0xe0, 0xbf, 0x3b, 0x54, 0xba, 0x0c, 0x93, 0x12,
+ /*9330:*/ 0x4e, 0x80, 0xf4, 0xd4, 0x17, 0x6b, 0x78, 0x48, 0x37, 0x41, 0x69, 0x73, 0xc8, 0xee, 0xaf, 0x71,
+ /*9340:*/ 0x5e, 0xe1, 0x3a, 0x70, 0x9a, 0x67, 0x9d, 0x7e, 0x26, 0xb9, 0x0f, 0x81, 0x2f, 0x53, 0x4b, 0x8b,
+ /*9350:*/ 0xf8, 0x64, 0x5f, 0x1e, 0xfe, 0xef, 0xf8, 0x31, 0xbc, 0x43, 0x1e, 0xf7, 0x38, 0x82, 0x8d, 0xb9,
+ /*9360:*/ 0x30, 0x99, 0xc8, 0x13, 0xb0, 0xde, 0x00, 0x93, 0xe3, 0x0b, 0xb9, 0x12, 0x92, 0x9f, 0xb3, 0x8e,
+ /*9370:*/ 0xd6, 0xda, 0xfa, 0x7b, 0x13, 0xb4, 0xcc, 0x9e, 0x8a, 0x65, 0xb0, 0x4e, 0x07, 0xda, 0xa6, 0x6d,
+ /*9380:*/ 0x29, 0xae, 0xf2, 0xbc, 0xd9, 0xde, 0xfc, 0x45, 0x20, 0x25, 0x2f, 0x21, 0x5c, 0x74, 0x95, 0x6b,
+ /*9390:*/ 0x9c, 0xa4, 0xa3, 0x06, 0xf8, 0x83, 0x09, 0x9f, 0x4c, 0xcc, 0x7b, 0xdb, 0xd7, 0x08, 0xd7, 0x79,
+ /*93a0:*/ 0x3e, 0x57, 0xef, 0xdb, 0x4d, 0xc6, 0x4b, 0x3e, 0xdd, 0xb4, 0x2a, 0xd2, 0x61, 0x72, 0x82, 0xff,
+ /*93b0:*/ 0x29, 0xf5, 0x8d, 0xbe, 0x68, 0xd2, 0x14, 0x53, 0x29, 0x15, 0x03, 0xfd, 0x04, 0x14, 0x24, 0x6a,
+ /*93c0:*/ 0x2d, 0xe4, 0x26, 0x4a, 0xba, 0x1a, 0xf9, 0x09, 0x8c, 0x48, 0x34, 0xc4, 0x86, 0xcc, 0xb3, 0x80,
+ /*93d0:*/ 0x14, 0x9e, 0xd4, 0xd0, 0x9f, 0xac, 0xdb, 0xc1, 0xfa, 0x25, 0xb2, 0x09, 0x9e, 0x69, 0xa5, 0x2c,
+ /*93e0:*/ 0x13, 0x6c, 0xec, 0x2e, 0x2d, 0xfa, 0xe6, 0x3b, 0xa0, 0x03, 0xeb, 0x79, 0xf3, 0x62, 0x81, 0xd1,
+ /*93f0:*/ 0x72, 0x11, 0xd0, 0xaa, 0xd3, 0xf0, 0x6b, 0xb4, 0xc7, 0x88, 0xa6, 0x0f, 0x50, 0x92, 0x55, 0x59,
+ /*9400:*/ 0x85, 0xe2, 0xf8, 0x6a, 0x32, 0xa9, 0xa6, 0xde, 0xdd, 0x2e, 0x0e, 0x3d, 0xbc, 0x66, 0x70, 0xfc,
+ /*9410:*/ 0x79, 0xdb, 0xc7, 0x01, 0x86, 0xdb, 0xb5, 0xd3, 0x28, 0xf2, 0xbd, 0x01, 0xe5, 0x6e, 0x47, 0xef,
+ /*9420:*/ 0x96, 0x22, 0x86, 0x63, 0x7b, 0xa3, 0x8a, 0xa0, 0x54, 0x2c, 0x4f, 0x22, 0xd0, 0x1a, 0xb4, 0x76,
+ /*9430:*/ 0xca, 0x51, 0x0b, 0x59, 0x86, 0x73, 0xf9, 0x29, 0xa1, 0xc0, 0xcc, 0xe9, 0xbd, 0x50, 0x4b, 0xfd,
+ /*9440:*/ 0x3b, 0x57, 0xae, 0x82, 0xc1, 0xcc, 0x6d, 0xbc, 0xd6, 0x5f, 0x18, 0x30, 0xd9, 0xb8, 0x29, 0x1f,
+ /*9450:*/ 0x33, 0x7e, 0x73, 0xf2, 0x14, 0xb2, 0xce, 0x04, 0x0d, 0x53, 0x5b, 0x0d, 0x8c, 0x0f, 0x79, 0xe2,
+ /*9460:*/ 0x95, 0x96, 0xf9, 0x78, 0xc5, 0x48, 0x05, 0xc1, 0xd4, 0x3c, 0x69, 0x80, 0x24, 0x11, 0x3e, 0xdb,
+ /*9470:*/ 0x14, 0x91, 0x2f, 0xc8, 0xcc, 0x76, 0xd3, 0x8b, 0x31, 0x49, 0x6d, 0x4a, 0xbc, 0x8e, 0xe7, 0x35,
+ /*9480:*/ 0xe2, 0xf2, 0x6d, 0x13, 0x23, 0xa0, 0x7a, 0xa7, 0x65, 0x19, 0x4b, 0xee, 0xe5, 0xc3, 0xdc, 0xce,
+ /*9490:*/ 0x91, 0x51, 0x2c, 0x1c, 0x52, 0xcd, 0x10, 0x2c, 0xc0, 0x13, 0x00, 0x98, 0xbb, 0xa4, 0x8b, 0xad,
+ /*94a0:*/ 0x56, 0x76, 0x2a, 0xc4, 0xeb, 0xef, 0xa4, 0x8e, 0xf1, 0x12, 0x01, 0x6a, 0xd6, 0xb8, 0x3d, 0xfc,
+ /*94b0:*/ 0x03, 0x78, 0x75, 0xef, 0x67, 0xe6, 0xeb, 0xf2, 0xf9, 0xb8, 0x80, 0xfe, 0x7c, 0xac, 0x30, 0xb3,
+ /*94c0:*/ 0x90, 0xc6, 0x6b, 0xd8, 0xf9, 0xad, 0x80, 0x93, 0x6e, 0x88, 0x62, 0xb7, 0xf7, 0xe8, 0x01, 0x3a,
+ /*94d0:*/ 0x6f, 0x97, 0x7b, 0x0a, 0x20, 0x95, 0x5e, 0x1f, 0xdd, 0x71, 0x59, 0xd4, 0x51, 0x14, 0xe4, 0xa6,
+ /*94e0:*/ 0xf3, 0x01, 0x9f, 0x7f, 0x57, 0x59, 0x85, 0xf0, 0x72, 0x17, 0xa7, 0xc0, 0x4c, 0x15, 0x15, 0x7e,
+ /*94f0:*/ 0xd3, 0xbb, 0xc8, 0xc2, 0x31, 0x3c, 0x2a, 0x10, 0x89, 0xf7, 0xa2, 0x22, 0x81, 0x45, 0xa0, 0xdd,
+ /*9500:*/ 0xd2, 0x4e, 0x50, 0xc1, 0x4e, 0xdf, 0xc0, 0x2e, 0x54, 0x14, 0x07, 0x99, 0x03, 0x37, 0x6c, 0x8f,
+ /*9510:*/ 0x43, 0x86, 0x08, 0xbe, 0x29, 0xfa, 0x91, 0xdc, 0x00, 0x65, 0x04, 0xa6, 0xc0, 0x20, 0x47, 0x1a,
+ /*9520:*/ 0x0d, 0x08, 0x91, 0x87, 0x14, 0x90, 0xe4, 0x92, 0xed, 0x79, 0x1b, 0xed, 0x98, 0xca, 0xfc, 0x57,
+ /*9530:*/ 0x81, 0xf1, 0x2c, 0xda, 0xc7, 0x02, 0xde, 0xf3, 0xd4, 0xda, 0xd2, 0x88, 0x3d, 0x8e, 0x47, 0xaa,
+ /*9540:*/ 0x50, 0x59, 0x14, 0xf8, 0x41, 0x37, 0xfb, 0x57, 0x47, 0xf3, 0x51, 0xb4, 0x80, 0x5a, 0x24, 0xbb,
+ /*9550:*/ 0x66, 0xe7, 0x06, 0x32, 0x2d, 0x86, 0x1b, 0x8c, 0x88, 0x39, 0x0a, 0x87, 0x26, 0xee, 0xda, 0x54,
+ /*9560:*/ 0x8c, 0x0a, 0x8b, 0x3d, 0x2b, 0x26, 0x72, 0x46, 0xe0, 0xdc, 0x8e, 0xd4, 0xb7, 0x10, 0x8d, 0x3c,
+ /*9570:*/ 0x37, 0x53, 0xd4, 0x11, 0xd6, 0x3e, 0x62, 0xc9, 0x55, 0xc3, 0xdd, 0x28, 0x6d, 0xb9, 0x65, 0x0c,
+ /*9580:*/ 0xa5, 0x3f, 0xdb, 0xfd, 0xf9, 0x5f, 0x72, 0xf7, 0xeb, 0xd6, 0x2c, 0xdc, 0xc6, 0xa1, 0x3d, 0xd9,
+ /*9590:*/ 0x35, 0x01, 0xff, 0xe6, 0x8b, 0x7d, 0x4f, 0x38, 0x9a, 0x34, 0xd0, 0x12, 0xdf, 0xbd, 0x98, 0xc3,
+ /*95a0:*/ 0x91, 0xd5, 0xc6, 0x81, 0x09, 0xf4, 0x62, 0x6a, 0x0c, 0x5f, 0x40, 0xcc, 0x5e, 0xe3, 0x06, 0x38,
+ /*95b0:*/ 0xc1, 0xfe, 0xf7, 0xac, 0x7e, 0x82, 0xc2, 0x87, 0x56, 0x4b, 0x2a, 0x10, 0x70, 0xc2, 0x2c, 0x9c,
+ /*95c0:*/ 0x7f, 0x55, 0x5e, 0x58, 0x54, 0xc8, 0x38, 0x2c, 0x02, 0xbd, 0xe2, 0x2d, 0xb9, 0x47, 0x64, 0xe5,
+ /*95d0:*/ 0x0a, 0x3e, 0xb4, 0xc4, 0x85, 0x2d, 0x22, 0xd3, 0x2f, 0x58, 0xdd, 0xca, 0x40, 0x8a, 0x8f, 0x46,
+ /*95e0:*/ 0x32, 0x9f, 0x2b, 0x87, 0x6f, 0x90, 0x19, 0xcf, 0x4e, 0x7a, 0x6d, 0x45, 0xc5, 0x3d, 0x12, 0x3e,
+ /*95f0:*/ 0x82, 0x23, 0x6a, 0x69, 0x21, 0x29, 0x94, 0x1c, 0x8b, 0x95, 0xbd, 0x06, 0x24, 0xb1, 0xbc, 0x12,
+ /*9600:*/ 0x6a, 0x25, 0xd5, 0x56, 0xbf, 0xb6, 0xde, 0x8d, 0xc9, 0xa9, 0x88, 0x8d, 0x93, 0xe8, 0x55, 0x7a,
+ /*9610:*/ 0x5c, 0xe5, 0xae, 0x4b, 0xa0, 0xfc, 0xbe, 0xea, 0x6d, 0x89, 0xa6, 0x02, 0xfa, 0x73, 0xa4, 0x77,
+ /*9620:*/ 0x90, 0x5a, 0x1b, 0x0c, 0x7e, 0x2f, 0xa6, 0xad, 0x96, 0x9d, 0x3e, 0x59, 0x27, 0x4b, 0x72, 0x2d,
+ /*9630:*/ 0xd3, 0xb3, 0x01, 0x6d, 0x07, 0x31, 0xe4, 0x52, 0x43, 0xe0, 0x95, 0x46, 0x0e, 0x15, 0x1b, 0x24,
+ /*9640:*/ 0xb0, 0x4c, 0xc9, 0x93, 0xeb, 0x19, 0xb1, 0xf7, 0xe1, 0x7f, 0x90, 0xaa, 0x46, 0x39, 0xd7, 0x87,
+ /*9650:*/ 0xc8, 0xc0, 0xb4, 0x55, 0x6f, 0x7b, 0xff, 0x49, 0xa4, 0xca, 0x8c, 0xe2, 0x87, 0x03, 0x56, 0x4e,
+ /*9660:*/ 0x21, 0x17, 0xbb, 0x15, 0xec, 0x10, 0x87, 0x15, 0xe3, 0x94, 0x75, 0x1a, 0x28, 0x44, 0x8f, 0xeb,
+ /*9670:*/ 0xfb, 0x27, 0x43, 0xdf, 0x1a, 0xcd, 0x79, 0x6b, 0x3e, 0x92, 0x09, 0xc5, 0xd5, 0x32, 0x30, 0x91,
+ /*9680:*/ 0xb5, 0x53, 0x1b, 0xfb, 0x4a, 0x1d, 0x57, 0x9b, 0x66, 0x68, 0x69, 0x6f, 0xca, 0x7f, 0xe0, 0xb1,
+ /*9690:*/ 0x20, 0xdf, 0x9e, 0xb2, 0x14, 0xaa, 0xdc, 0x0a, 0xab, 0x55, 0x25, 0xeb, 0xd7, 0xcc, 0x82, 0x9f,
+ /*96a0:*/ 0xfe, 0xbd, 0x49, 0x89, 0x82, 0xb9, 0xc0, 0x97, 0xf6, 0x36, 0x87, 0x25, 0x09, 0xf7, 0xd8, 0xa0,
+ /*96b0:*/ 0xb5, 0x47, 0x3b, 0x7c, 0x7d, 0x7a, 0xbe, 0xed, 0x13, 0x7f, 0xb0, 0x86, 0xd8, 0x9c, 0x52, 0x4b,
+ /*96c0:*/ 0xa6, 0xad, 0x90, 0x16, 0x28, 0xbe, 0x75, 0x6f, 0x41, 0xdc, 0x0f, 0x71, 0x00, 0xcd, 0xae, 0x1d,
+ /*96d0:*/ 0x56, 0x8d, 0x7a, 0xc5, 0xec, 0xe3, 0xef, 0x55, 0x97, 0x6f, 0x8e, 0x55, 0xc3, 0xdc, 0x97, 0x5a,
+ /*96e0:*/ 0x86, 0x91, 0x38, 0xda, 0xc9, 0x1c, 0x98, 0x62, 0xe1, 0xc9, 0x45, 0x26, 0x2d, 0x19, 0xcd, 0x83,
+ /*96f0:*/ 0x81, 0x25, 0x2f, 0x93, 0xa2, 0x34, 0x74, 0x01, 0x96, 0x30, 0x18, 0xc3, 0xa7, 0xd9, 0xd7, 0x5b,
+ /*9700:*/ 0xcf, 0x33, 0x35, 0x0b, 0xfa, 0xdd, 0x4a, 0x14, 0xdb, 0x05, 0xf4, 0x34, 0xde, 0xa8, 0xeb, 0xaa,
+ /*9710:*/ 0x35, 0x82, 0xf6, 0x47, 0x28, 0x84, 0x56, 0x8f, 0xbe, 0xf7, 0xc8, 0xaa, 0xdd, 0x39, 0x9b, 0x40,
+ /*9720:*/ 0xe9, 0x80, 0x16, 0xe6, 0x1e, 0x3a, 0xfb, 0x82, 0x62, 0x73, 0x05, 0x92, 0x13, 0x1d, 0x46, 0x29,
+ /*9730:*/ 0x04, 0xcf, 0xc3, 0x8b, 0xb3, 0xb4, 0x95, 0x66, 0xcd, 0x07, 0x10, 0x18, 0x03, 0x19, 0xb7, 0x3f,
+ /*9740:*/ 0x43, 0x30, 0x87, 0xd8, 0x37, 0x1d, 0x57, 0x4d, 0x9d, 0x94, 0x5f, 0xe7, 0xf9, 0xa3, 0xa3, 0xe9,
+ /*9750:*/ 0xa4, 0x23, 0x3d, 0x53, 0xe2, 0xe0, 0xd9, 0x12, 0xbb, 0x38, 0xc1, 0xe9, 0xbb, 0x44, 0xdf, 0x87,
+ /*9760:*/ 0x2c, 0x8f, 0x38, 0x34, 0x9e, 0xd5, 0xcc, 0x1f, 0x24, 0x42, 0x1e, 0xa6, 0xf3, 0x2f, 0xd0, 0xc2,
+ /*9770:*/ 0xf4, 0x11, 0x5f, 0xa6, 0x10, 0x78, 0xc4, 0x78, 0x3a, 0xad, 0x14, 0xf5, 0x1b, 0xb2, 0x19, 0x20,
+ /*9780:*/ 0x8b, 0xbd, 0x38, 0xe4, 0x8d, 0x62, 0x00, 0xe9, 0x34, 0xab, 0x3d, 0x43, 0x75, 0x5d, 0xa7, 0xc6,
+ /*9790:*/ 0x0f, 0x2b, 0x30, 0x0e, 0xd7, 0x9b, 0x94, 0x9e, 0x84, 0xc7, 0xe1, 0x83, 0x24, 0x3c, 0xaa, 0x0f,
+ /*97a0:*/ 0x60, 0x22, 0x6d, 0x12, 0xd7, 0xec, 0x95, 0x82, 0xff, 0xa7, 0x87, 0xef, 0xf4, 0x7c, 0xd7, 0x13,
+ /*97b0:*/ 0x3f, 0x5f, 0x59, 0xc1, 0x73, 0x4a, 0x8f, 0x34, 0x2e, 0x25, 0xa0, 0xb5, 0xea, 0xd0, 0x0e, 0x46,
+ /*97c0:*/ 0xba, 0x74, 0x40, 0x2f, 0xab, 0x21, 0xc8, 0x3e, 0x05, 0x41, 0xe8, 0x6b, 0x2c, 0x6f, 0x85, 0x3c,
+ /*97d0:*/ 0xbb, 0x8f, 0xa3, 0x58, 0x86, 0x9d, 0x7b, 0xfc, 0x21, 0xe6, 0x7b, 0x7e, 0xad, 0xe3, 0x16, 0x68,
+ /*97e0:*/ 0x06, 0xad, 0x90, 0xc4, 0x31, 0xaf, 0xcd, 0x25, 0xaf, 0x79, 0x22, 0x0a, 0xb8, 0xc8, 0x07, 0xa1,
+ /*97f0:*/ 0x84, 0xbc, 0x99, 0x79, 0x99, 0x64, 0xd4, 0x26, 0xec, 0x5c, 0x0e, 0x3d, 0xa3, 0xd9, 0x08, 0xd5,
+ /*9800:*/ 0x30, 0xa2, 0xb5, 0x6d, 0x52, 0x5f, 0x4a, 0x3b, 0xc3, 0x2f, 0x20, 0xcf, 0x28, 0xfc, 0xd4, 0x1c,
+ /*9810:*/ 0xfa, 0xc0, 0x18, 0xa3, 0x44, 0x4a, 0xaf, 0xa5, 0xaa, 0x52, 0xe8, 0xee, 0x84, 0x9b, 0x28, 0xf7,
+ /*9820:*/ 0xc1, 0x48, 0x69, 0xaa, 0xe6, 0x16, 0xf0, 0xf8, 0x9d, 0x02, 0x09, 0xf0, 0xad, 0xa3, 0x51, 0x2a,
+ /*9830:*/ 0x15, 0x1a, 0x4e, 0xcf, 0x96, 0x33, 0xeb, 0x66, 0x10, 0x58, 0xc0, 0x17, 0xe9, 0x57, 0x6e, 0xbc,
+ /*9840:*/ 0xe1, 0x2a, 0xd9, 0x78, 0x55, 0xd8, 0xef, 0x29, 0x70, 0xa6, 0xdc, 0x12, 0x89, 0xce, 0xfd, 0x7a,
+ /*9850:*/ 0x14, 0xe6, 0x0e, 0x03, 0xc9, 0xb3, 0x21, 0x8b, 0xfd, 0x01, 0xfa, 0x12, 0x34, 0x9b, 0x47, 0x23,
+ /*9860:*/ 0x3c, 0x3a, 0x70, 0x72, 0x70, 0x45, 0xf0, 0xa2, 0x04, 0xf9, 0xe6, 0x3f, 0x22, 0xf6, 0x41, 0x71,
+ /*9870:*/ 0x10, 0xe1, 0x44, 0x5d, 0xd7, 0x03, 0xa9, 0x07, 0x34, 0x5e, 0x50, 0xb9, 0x1b, 0x77, 0x18, 0x05,
+ /*9880:*/ 0x90, 0x8d, 0xfe, 0x48, 0x63, 0xe8, 0xbd, 0xe1, 0x59, 0xa9, 0x6b, 0xe2, 0xb9, 0xdf, 0x28, 0x1b,
+ /*9890:*/ 0xe9, 0x74, 0x48, 0x42, 0xed, 0x66, 0xc4, 0xf6, 0xaf, 0x72, 0xf7, 0x8a, 0x14, 0xf4, 0xb1, 0x3a,
+ /*98a0:*/ 0x9d, 0x10, 0xb9, 0x37, 0xe6, 0x53, 0xe3, 0x08, 0x0d, 0xf4, 0x43, 0x02, 0x07, 0x18, 0x9c, 0x42,
+ /*98b0:*/ 0xdb, 0xa9, 0x34, 0xfa, 0x14, 0x63, 0xfd, 0xb5, 0x0d, 0x93, 0xc3, 0x20, 0x5d, 0xc4, 0x05, 0xb1,
+ /*98c0:*/ 0x35, 0x37, 0xa0, 0x7a, 0x2f, 0xa3, 0x0f, 0xf9, 0xa0, 0x1e, 0x96, 0x79, 0xe1, 0x6a, 0xf0, 0xec,
+ /*98d0:*/ 0x73, 0x20, 0xa5, 0x76, 0xd6, 0xe8, 0x0e, 0x63, 0xe9, 0x0c, 0x6b, 0xf7, 0x61, 0x92, 0xee, 0xf3,
+ /*98e0:*/ 0x94, 0x53, 0xbd, 0x4e, 0x9c, 0xc9, 0xd4, 0x30, 0x07, 0x6f, 0xcf, 0xf8, 0x14, 0xf7, 0xfc, 0xdd,
+ /*98f0:*/ 0x3d, 0x77, 0x0c, 0x49, 0xc2, 0x90, 0xa2, 0xfa, 0x04, 0x3a, 0x63, 0xeb, 0x94, 0xc0, 0x2c, 0xfa,
+ /*9900:*/ 0x7c, 0x86, 0x94, 0x0f, 0x47, 0x38, 0x7d, 0xee, 0x5c, 0xa7, 0xa4, 0x6c, 0x7c, 0x12, 0xaa, 0x45,
+ /*9910:*/ 0xfb, 0xd0, 0x5d, 0xa9, 0xb5, 0x92, 0xef, 0x89, 0x61, 0x0b, 0xf2, 0xf4, 0xeb, 0x42, 0x96, 0x34,
+ /*9920:*/ 0x14, 0xa8, 0xed, 0x8e, 0x41, 0x87, 0x72, 0xd0, 0x13, 0x7b, 0x7d, 0x76, 0x1e, 0x5b, 0xb2, 0xee,
+ /*9930:*/ 0xbc, 0x84, 0xc0, 0xbd, 0xb1, 0x6a, 0x67, 0x08, 0xee, 0x0b, 0x0e, 0xf8, 0x27, 0x61, 0xff, 0x81,
+ /*9940:*/ 0xc0, 0xc2, 0xa1, 0x32, 0xfb, 0x00, 0x32, 0x62, 0x58, 0xc6, 0x8c, 0xe3, 0x25, 0x28, 0x91, 0x32,
+ /*9950:*/ 0x56, 0xba, 0x80, 0x5e, 0x91, 0xeb, 0x2b, 0x77, 0x3e, 0x80, 0x91, 0x40, 0x0d, 0x05, 0x92, 0xf6,
+ /*9960:*/ 0x9a, 0xf4, 0x7b, 0x03, 0x24, 0xdd, 0x02, 0xf0, 0x33, 0x82, 0x6f, 0xc8, 0x6d, 0x35, 0xe8, 0xd3,
+ /*9970:*/ 0xe6, 0x1e, 0x16, 0x5b, 0x97, 0x32, 0xea, 0xa2, 0xf4, 0xfb, 0x87, 0xff, 0x17, 0x96, 0xa5, 0xe0,
+ /*9980:*/ 0xfe, 0xdd, 0x12, 0xcc, 0x01, 0xd5, 0xb2, 0x00, 0xcd, 0x17, 0xc3, 0x05, 0x2e, 0x3b, 0x83, 0x7f,
+ /*9990:*/ 0x38, 0xe2, 0xfc, 0xf7, 0xa4, 0x14, 0xd9, 0x24, 0x44, 0xbd, 0x7f, 0x58, 0xfb, 0xbd, 0x5d, 0x55,
+ /*99a0:*/ 0xc6, 0x58, 0x09, 0x2d, 0x37, 0x84, 0x8f, 0x16, 0x3f, 0xa6, 0xac, 0x43, 0x36, 0xda, 0x5e, 0x61,
+ /*99b0:*/ 0x81, 0x0c, 0xeb, 0xa9, 0x5f, 0xb1, 0xee, 0xd6, 0xee, 0x11, 0xaf, 0x05, 0x76, 0x76, 0x4d, 0xa9,
+ /*99c0:*/ 0xd1, 0xd5, 0x5e, 0x15, 0x35, 0xc1, 0x08, 0x01, 0x51, 0x0d, 0xbe, 0x00, 0x04, 0xb9, 0xf0, 0xc3,
+ /*99d0:*/ 0x1f, 0xc2, 0xeb, 0x76, 0xb3, 0xa6, 0xca, 0xd0, 0x41, 0xc5, 0x75, 0x48, 0x75, 0x5b, 0x68, 0x9e,
+ /*99e0:*/ 0x84, 0xe7, 0xda, 0xe2, 0x03, 0x0b, 0xf5, 0x86, 0x22, 0x4d, 0x1e, 0x92, 0xd8, 0xc4, 0x1a, 0x9b,
+ /*99f0:*/ 0x3e, 0x1c, 0x5d, 0x53, 0x39, 0xeb, 0xb3, 0xd5, 0x84, 0x93, 0x17, 0xe2, 0x2e, 0x0a, 0xed, 0xb0,
+ /*9a00:*/ 0x6e, 0xb7, 0x27, 0x0b, 0x85, 0x5d, 0x8f, 0x0b, 0x5a, 0x52, 0x25, 0xc5, 0x11, 0xa0, 0xd9, 0xe8,
+ /*9a10:*/ 0xd5, 0x02, 0x07, 0x27, 0x21, 0x80, 0x3c, 0xd0, 0x43, 0x9c, 0x32, 0xd4, 0x95, 0xa0, 0xca, 0x0e,
+ /*9a20:*/ 0x25, 0x72, 0x08, 0x38, 0x86, 0x25, 0xf5, 0x18, 0x3b, 0x7d, 0x13, 0x19, 0x3f, 0xed, 0xc3, 0x6f,
+ /*9a30:*/ 0x54, 0x03, 0x64, 0xf1, 0x2a, 0x69, 0x9f, 0x58, 0x5f, 0x68, 0xdf, 0x39, 0x6b, 0x2c, 0xb5, 0x39,
+ /*9a40:*/ 0xeb, 0x49, 0x37, 0xbb, 0x1a, 0xc1, 0x3b, 0xb0, 0x71, 0xa4, 0x1d, 0x17, 0xfd, 0x23, 0xba, 0x5c,
+ /*9a50:*/ 0xde, 0x7a, 0x9e, 0x57, 0x8e, 0x6d, 0x1c, 0x4e, 0x41, 0xe4, 0xa2, 0xd4, 0xee, 0xbf, 0x9c, 0x8c,
+ /*9a60:*/ 0x66, 0x76, 0xf8, 0x62, 0x21, 0xae, 0xad, 0x3e, 0x2a, 0x64, 0xcf, 0xa1, 0x32, 0x69, 0xe4, 0xb3,
+ /*9a70:*/ 0xe3, 0xff, 0xf7, 0xd7, 0x85, 0x5f, 0xd8, 0x9c, 0xe9, 0xe7, 0x5b, 0xc1, 0xd2, 0x2e, 0xbb, 0xc9,
+ /*9a80:*/ 0xeb, 0xbf, 0x81, 0x51, 0x14, 0x6c, 0xf6, 0x23, 0x4e, 0xed, 0x68, 0x29, 0xb6, 0x90, 0x05, 0x24,
+ /*9a90:*/ 0x98, 0x53, 0xf3, 0x2a, 0x09, 0x88, 0xb5, 0xe1, 0x19, 0xc5, 0xac, 0x15, 0xb3, 0x12, 0x78, 0x25,
+ /*9aa0:*/ 0xb6, 0x09, 0xc7, 0x50, 0x39, 0x61, 0xee, 0x82, 0x85, 0x59, 0x7f, 0x10, 0x4f, 0xb7, 0x4c, 0xa6,
+ /*9ab0:*/ 0xb2, 0xce, 0x19, 0x5e, 0x3b, 0x94, 0xd2, 0x1f, 0x3b, 0xa2, 0xd6, 0x06, 0xe8, 0x04, 0xeb, 0x10,
+ /*9ac0:*/ 0xaa, 0x1b, 0x92, 0x0b, 0x98, 0x20, 0x7c, 0x02, 0x40, 0x2a, 0x9e, 0xbd, 0xeb, 0x73, 0x27, 0x6b,
+ /*9ad0:*/ 0x6d, 0xc5, 0x3e, 0x99, 0x06, 0x82, 0x22, 0xe6, 0xb8, 0x54, 0x88, 0x03, 0x7f, 0xf9, 0x8c, 0xda,
+ /*9ae0:*/ 0xc4, 0xfe, 0xd7, 0x94, 0x52, 0xca, 0x5a, 0x73, 0xba, 0x76, 0xb7, 0x90, 0x82, 0xaf, 0xb1, 0x02,
+ /*9af0:*/ 0xc4, 0x11, 0x84, 0x19, 0x65, 0xf3, 0x6c, 0x2d, 0x57, 0x11, 0x9e, 0xa5, 0x39, 0x74, 0xcd, 0x98,
+ /*9b00:*/ 0x6b, 0x89, 0x7c, 0x59, 0xea, 0x89, 0x41, 0x51, 0xbb, 0xd1, 0xc5, 0x01, 0xa0, 0xad, 0x35, 0xcd,
+ /*9b10:*/ 0x0a, 0x05, 0x28, 0xa1, 0x02, 0xb0, 0xf5, 0xf3, 0xd6, 0xb4, 0x8b, 0x05, 0xd5, 0x72, 0xa7, 0x9a,
+ /*9b20:*/ 0xb6, 0x13, 0xc6, 0xa0, 0xd4, 0x73, 0xa0, 0xd1, 0x15, 0x53, 0x2b, 0xb0, 0x43, 0x75, 0xfb, 0xb5,
+ /*9b30:*/ 0x81, 0x85, 0x30, 0xd0, 0xd4, 0x8c, 0x84, 0xea, 0x89, 0xb1, 0x9f, 0x9c, 0xc7, 0x5a, 0x56, 0x88,
+ /*9b40:*/ 0xa1, 0x74, 0xb3, 0x41, 0xdb, 0x6e, 0x7b, 0x02, 0x16, 0x6c, 0xbc, 0x95, 0x21, 0x5d, 0x83, 0x62,
+ /*9b50:*/ 0x56, 0x4c, 0xd5, 0x2a, 0xd3, 0xe3, 0xa0, 0xad, 0x49, 0x95, 0x12, 0x84, 0x81, 0xcd, 0xc1, 0x49,
+ /*9b60:*/ 0xcd, 0xc8, 0x77, 0x75, 0x67, 0x80, 0x3e, 0x83, 0x92, 0x4a, 0xe9, 0xa1, 0xa6, 0xe5, 0xa5, 0x7c,
+ /*9b70:*/ 0xf4, 0x33, 0x63, 0x69, 0x91, 0x08, 0x12, 0xfa, 0xe0, 0x8e, 0x4f, 0xaf, 0xfb, 0x24, 0x96, 0xcd,
+ /*9b80:*/ 0xf8, 0xb9, 0xa7, 0xbb, 0xc1, 0x59, 0xe8, 0x6f, 0xbc, 0xee, 0x25, 0x3f, 0xa0, 0x52, 0x92, 0x3e,
+ /*9b90:*/ 0xf3, 0x4b, 0xc3, 0x11, 0xa4, 0x94, 0x40, 0x24, 0x47, 0x9e, 0x71, 0xc5, 0x76, 0x57, 0xf1, 0xef,
+ /*9ba0:*/ 0x11, 0x53, 0x1a, 0x7f, 0x39, 0x23, 0x36, 0x13, 0x06, 0xe2, 0x20, 0x9e, 0x3b, 0x6d, 0x85, 0xef,
+ /*9bb0:*/ 0x80, 0x42, 0xaa, 0x08, 0x51, 0x91, 0x0c, 0xad, 0x68, 0xbe, 0xb8, 0xe2, 0x5f, 0xb1, 0xbb, 0xc8,
+ /*9bc0:*/ 0x0a, 0x32, 0x10, 0xbb, 0xb3, 0x07, 0x1c, 0x50, 0x4d, 0xca, 0x26, 0xf4, 0x5a, 0x20, 0x99, 0x95,
+ /*9bd0:*/ 0xe5, 0x2c, 0xbb, 0x80, 0x59, 0xef, 0x7d, 0x0c, 0x46, 0x4c, 0xa3, 0xcf, 0xc6, 0x9e, 0x6a, 0x0a,
+ /*9be0:*/ 0xa3, 0x17, 0x40, 0x77, 0x0e, 0xf6, 0x19, 0x93, 0x9a, 0x06, 0xc9, 0x3c, 0xc5, 0xcb, 0x33, 0x6e,
+ /*9bf0:*/ 0xb3, 0xfa, 0xeb, 0xbf, 0x63, 0x16, 0xad, 0x55, 0x79, 0xee, 0x5b, 0x15, 0x4e, 0xe1, 0x65, 0xa9,
+ /*9c00:*/ 0x69, 0x00, 0x7a, 0x99, 0xbf, 0x32, 0x32, 0x24, 0x66, 0xc0, 0xf0, 0x63, 0x3c, 0x94, 0xdf, 0xb2,
+ /*9c10:*/ 0x4b, 0xc8, 0x9a, 0xdd, 0xac, 0x0b, 0x6a, 0x20, 0x9e, 0xb9, 0x88, 0x9e, 0x60, 0x51, 0x04, 0xbc,
+ /*9c20:*/ 0x87, 0xd2, 0x9f, 0x53, 0x8d, 0x3f, 0x47, 0x5d, 0x17, 0xe0, 0xf8, 0xe1, 0x5f, 0xa9, 0x5a, 0xc3,
+ /*9c30:*/ 0xdf, 0xfc, 0x7f, 0xbe, 0x9c, 0x0d, 0x56, 0xe6, 0x7f, 0xe3, 0xf4, 0xfb, 0x5b, 0x4c, 0xd8, 0x3f,
+ /*9c40:*/ 0xc5, 0xc7, 0x7d, 0xc5, 0xa4, 0x74, 0x20, 0xe7, 0xb8, 0x35, 0x3d, 0xd0, 0xfe, 0x97, 0xb3, 0x7c,
+ /*9c50:*/ 0x5b, 0xba, 0x6f, 0x58, 0x1c, 0x47, 0xc8, 0xb7, 0x16, 0xf4, 0xa5, 0xb3, 0xb1, 0x51, 0x8a, 0x7d,
+ /*9c60:*/ 0x31, 0x9c, 0x20, 0x0e, 0x5a, 0x9d, 0x70, 0xea, 0xe2, 0x55, 0xe5, 0x0e, 0xe3, 0x0c, 0x62, 0x5b,
+ /*9c70:*/ 0xf3, 0xd3, 0x48, 0xfc, 0x20, 0xc0, 0x75, 0x6e, 0x16, 0xe8, 0xe8, 0xce, 0xf0, 0x1d, 0x4c, 0xdc,
+ /*9c80:*/ 0x82, 0xe0, 0x22, 0x34, 0xf6, 0x0a, 0x8b, 0xe5, 0x0c, 0x44, 0xc0, 0x8d, 0x77, 0xd9, 0xf3, 0x68,
+ /*9c90:*/ 0x04, 0xe2, 0xd1, 0x10, 0x0a, 0xbd, 0x34, 0xac, 0xcb, 0x0b, 0xcf, 0xab, 0xb7, 0x30, 0x73, 0x53,
+ /*9ca0:*/ 0x3a, 0xc2, 0x37, 0x21, 0x48, 0x8e, 0xf9, 0xa6, 0x4b, 0x85, 0xe4, 0x6c, 0xf3, 0x58, 0x71, 0xdb,
+ /*9cb0:*/ 0xe9, 0x4f, 0xc4, 0x80, 0xe1, 0xad, 0x5d, 0xe5, 0x82, 0xc9, 0x6f, 0xa6, 0xc7, 0xaf, 0x7d, 0x58,
+ /*9cc0:*/ 0xbc, 0xaa, 0x21, 0x43, 0x7f, 0xe5, 0x4c, 0x2e, 0x51, 0x52, 0xfe, 0xdd, 0x4f, 0xe0, 0xd7, 0xce,
+ /*9cd0:*/ 0x1e, 0x20, 0xcd, 0x24, 0x7d, 0xf8, 0xa2, 0x34, 0x80, 0xf0, 0x00, 0xef, 0x43, 0x97, 0xd6, 0xb6,
+ /*9ce0:*/ 0xd5, 0x4d, 0x14, 0xd3, 0x2f, 0x77, 0x74, 0xbb, 0xa4, 0x51, 0x72, 0x2b, 0x5d, 0x9c, 0xe2, 0x61,
+ /*9cf0:*/ 0xe8, 0xac, 0xf0, 0x96, 0x45, 0x92, 0xab, 0x9d, 0x6c, 0x86, 0xb6, 0x0d, 0x43, 0xdb, 0xe4, 0x86,
+ /*9d00:*/ 0x87, 0xe4, 0xc5, 0xd2, 0x92, 0x3c, 0x7e, 0x63, 0x2a, 0x07, 0x00, 0xf8, 0xfb, 0x9a, 0x99, 0x32,
+ /*9d10:*/ 0xe8, 0xf9, 0xb1, 0x88, 0x56, 0xb5, 0x7f, 0xcf, 0x6c, 0xe8, 0x63, 0xeb, 0x67, 0x4a, 0x53, 0xb1,
+ /*9d20:*/ 0x5f, 0x79, 0x73, 0x9e, 0xfa, 0xd3, 0x59, 0x00, 0xb6, 0xf6, 0x70, 0x20, 0x2d, 0x1b, 0x8e, 0x71,
+ /*9d30:*/ 0xea, 0xf0, 0x11, 0x2f, 0x12, 0xf3, 0xd2, 0x16, 0x51, 0xcd, 0x75, 0x70, 0x82, 0x06, 0x82, 0xa6,
+ /*9d40:*/ 0x03, 0x84, 0xc6, 0x5d, 0x54, 0xf5, 0xbe, 0xcd, 0x9e, 0x23, 0x69, 0xe2, 0x62, 0xfc, 0x86, 0x69,
+ /*9d50:*/ 0xb8, 0xfd, 0x6c, 0x67, 0x3a, 0x70, 0x74, 0xad, 0x0d, 0xce, 0xaa, 0x92, 0xd2, 0xc8, 0xfc, 0xeb,
+ /*9d60:*/ 0x32, 0xc7, 0x8f, 0x51, 0x7c, 0xf8, 0x94, 0x13, 0x49, 0xd2, 0xd0, 0x92, 0x47, 0x74, 0x65, 0x0f,
+ /*9d70:*/ 0x4d, 0xf2, 0x78, 0x30, 0x0c, 0xca, 0xe3, 0x12, 0x73, 0x46, 0x90, 0xac, 0xc1, 0x0b, 0x9e, 0xed,
+ /*9d80:*/ 0x2a, 0x32, 0xa0, 0x01, 0xdb, 0x4b, 0x80, 0x6d, 0xc3, 0x1b, 0x11, 0xad, 0x81, 0x84, 0xdd, 0x20,
+ /*9d90:*/ 0x21, 0x90, 0x7c, 0xda, 0x2d, 0x59, 0x89, 0x61, 0x66, 0x4d, 0x35, 0x8d, 0xcd, 0x59, 0xed, 0x6c,
+ /*9da0:*/ 0x2b, 0xde, 0xd1, 0x71, 0xf6, 0x62, 0x18, 0x6d, 0x2a, 0xfa, 0xcf, 0xd2, 0x78, 0x2e, 0x91, 0xed,
+ /*9db0:*/ 0xef, 0x42, 0xaf, 0x27, 0x5f, 0xe8, 0xc8, 0xd4, 0x49, 0xae, 0x29, 0xeb, 0x55, 0x53, 0x48, 0xdc,
+ /*9dc0:*/ 0x5d, 0xa0, 0xf9, 0x8a, 0x2b, 0x88, 0x65, 0x88, 0x94, 0x45, 0x38, 0xa9, 0xb4, 0xc4, 0xcf, 0x8e,
+ /*9dd0:*/ 0x56, 0x2a, 0x92, 0x76, 0x1e, 0x68, 0x50, 0x89, 0x7f, 0x99, 0x3b, 0xf1, 0x74, 0xdd, 0xf1, 0x0e,
+ /*9de0:*/ 0xb5, 0xd2, 0x0f, 0x80, 0x65, 0xe8, 0xe3, 0xc5, 0x66, 0x69, 0x75, 0xeb, 0x78, 0x2e, 0xc5, 0xbf,
+ /*9df0:*/ 0x35, 0xb9, 0x39, 0x0c, 0x7f, 0x81, 0x03, 0xbf, 0x14, 0xd1, 0x99, 0x4b, 0xd6, 0xaf, 0x44, 0x1e,
+ /*9e00:*/ 0x04, 0xe6, 0xd0, 0x26, 0x69, 0xe9, 0x35, 0xca, 0xe0, 0x39, 0xa6, 0x74, 0x2c, 0x5e, 0xe8, 0xeb,
+ /*9e10:*/ 0x53, 0x8e, 0xce, 0xc9, 0xd6, 0xa8, 0xe5, 0x78, 0x8a, 0xf8, 0xe1, 0x62, 0xe0, 0x71, 0xcf, 0xa2,
+ /*9e20:*/ 0x87, 0xf9, 0x51, 0x52, 0x94, 0x64, 0xde, 0xce, 0xa3, 0x09, 0x3c, 0x16, 0x7d, 0xce, 0xbb, 0xf9,
+ /*9e30:*/ 0x81, 0xb8, 0x86, 0xe3, 0x5f, 0xf9, 0x24, 0x8d, 0xfc, 0xbd, 0x5f, 0xd7, 0x15, 0x1a, 0x3e, 0x9f,
+ /*9e40:*/ 0x11, 0xab, 0xc4, 0xee, 0x23, 0x3b, 0x66, 0x66, 0xbb, 0x52, 0xfa, 0x75, 0x78, 0x37, 0x54, 0x71,
+ /*9e50:*/ 0x47, 0x4a, 0x9a, 0x8a, 0x7a, 0x7b, 0x1a, 0x18, 0x45, 0x4b, 0xf5, 0x91, 0x3a, 0xf1, 0x1a, 0x9f,
+ /*9e60:*/ 0x0e, 0x00, 0xc2, 0xa0, 0xc9, 0xfa, 0x95, 0x89, 0x8b, 0x59, 0x3b, 0x52, 0x16, 0xb8, 0x20, 0x89,
+ /*9e70:*/ 0xee, 0x83, 0xda, 0xda, 0x37, 0x5f, 0x8a, 0x7e, 0x9f, 0xbe, 0x7e, 0x20, 0xca, 0xb8, 0x52, 0xd4,
+ /*9e80:*/ 0x3d, 0x4d, 0xe2, 0x6e, 0xe9, 0x63, 0xfc, 0xaa, 0x74, 0xb2, 0x49, 0xac, 0x95, 0xd4, 0xb9, 0xf1,
+ /*9e90:*/ 0x97, 0xe7, 0xc8, 0x87, 0xab, 0xc5, 0xd2, 0x70, 0xe2, 0x8b, 0xe3, 0x3a, 0xa4, 0x58, 0x98, 0x31,
+ /*9ea0:*/ 0xce, 0x21, 0xbd, 0xf1, 0xc2, 0x7f, 0x87, 0x7a, 0xc9, 0x9f, 0xb2, 0x0b, 0x49, 0x1d, 0xff, 0x5a,
+ /*9eb0:*/ 0x60, 0x39, 0x77, 0x7e, 0x6f, 0xa3, 0x1a, 0x44, 0x81, 0x25, 0xac, 0x67, 0x9a, 0xa1, 0xbe, 0x9d,
+ /*9ec0:*/ 0x9e, 0xa4, 0x37, 0x7e, 0xb7, 0xdc, 0xd0, 0xbf, 0x57, 0x62, 0x9e, 0x6c, 0x8c, 0x4e, 0x2e, 0x3c,
+ /*9ed0:*/ 0xd3, 0x38, 0x91, 0x0c, 0xf4, 0x57, 0x91, 0x87, 0x00, 0x26, 0xd4, 0x0c, 0x22, 0x21, 0x0b, 0xab,
+ /*9ee0:*/ 0x1f, 0x3a, 0xe2, 0xcd, 0x41, 0x4c, 0xae, 0xfe, 0x9d, 0x11, 0xd1, 0x9b, 0xca, 0xc0, 0x95, 0x56,
+ /*9ef0:*/ 0xf9, 0xff, 0x70, 0xcd, 0xe2, 0x2b, 0x67, 0x5a, 0x1e, 0x5e, 0xb1, 0x70, 0x7f, 0x80, 0xb8, 0xd9,
+ /*9f00:*/ 0x85, 0x4f, 0x6a, 0xc5, 0xb1, 0xd3, 0x93, 0x11, 0x81, 0xf0, 0x9a, 0xf8, 0xf5, 0x97, 0x95, 0x63,
+ /*9f10:*/ 0x23, 0x45, 0x77, 0x19, 0x92, 0xdd, 0x33, 0x83, 0x48, 0x6e, 0xc7, 0xbd, 0x6a, 0xa8, 0x82, 0xb1,
+ /*9f20:*/ 0x5c, 0x64, 0x36, 0xda, 0xa2, 0x11, 0xbe, 0xc8, 0x9e, 0xc6, 0x43, 0x62, 0xe0, 0x02, 0x5f, 0x2f,
+ /*9f30:*/ 0x18, 0x29, 0xda, 0x32, 0x0e, 0xe5, 0x6c, 0xfa, 0x74, 0x79, 0x8b, 0xd2, 0x89, 0x3c, 0x88, 0xe3,
+ /*9f40:*/ 0xb5, 0x1d, 0x90, 0xce, 0x8d, 0x82, 0x41, 0xeb, 0x83, 0x90, 0x5e, 0xba, 0x6a, 0xb7, 0x1a, 0xb5,
+ /*9f50:*/ 0x54, 0xd7, 0x3c, 0x26, 0x63, 0x3c, 0x22, 0x80, 0x0a, 0x9e, 0xf8, 0x24, 0x82, 0x54, 0x64, 0x84,
+ /*9f60:*/ 0x51, 0xa9, 0x89, 0x2d, 0x39, 0x83, 0x35, 0x15, 0x1b, 0x95, 0x03, 0xf1, 0xb6, 0x2d, 0xd4, 0x96,
+ /*9f70:*/ 0x9b, 0x80, 0x13, 0x5c, 0x06, 0xf5, 0xa0, 0x76, 0xad, 0x2a, 0x02, 0x73, 0x96, 0x47, 0xe5, 0x38,
+ /*9f80:*/ 0xb8, 0x5d, 0x22, 0x37, 0xa5, 0x4c, 0x17, 0x36, 0xb2, 0x17, 0xd4, 0x6d, 0x5f, 0x54, 0xc2, 0xc7,
+ /*9f90:*/ 0x60, 0xe4, 0xd6, 0x53, 0x51, 0x20, 0x29, 0x3a, 0xa3, 0x15, 0x73, 0x13, 0xcc, 0xb6, 0xda, 0x81,
+ /*9fa0:*/ 0xcc, 0xe7, 0xd0, 0x9b, 0xb4, 0x52, 0xc9, 0x5a, 0x10, 0xda, 0x05, 0x08, 0xc9, 0x6e, 0x56, 0x9a,
+ /*9fb0:*/ 0xe8, 0x5f, 0xa4, 0x29, 0xff, 0x31, 0xad, 0x4a, 0x25, 0x46, 0x72, 0xab, 0xa1, 0xbf, 0x3a, 0x36,
+ /*9fc0:*/ 0x0b, 0x1d, 0x06, 0x90, 0xc3, 0x8b, 0x8e, 0x8e, 0x84, 0x60, 0xcf, 0x2d, 0xa3, 0x93, 0x2f, 0x68,
+ /*9fd0:*/ 0x53, 0x89, 0xb6, 0x2e, 0xde, 0xbc, 0x18, 0x7c, 0xbd, 0x66, 0x54, 0x92, 0xed, 0x0f, 0xf5, 0x82,
+ /*9fe0:*/ 0xdf, 0xba, 0x99, 0xc9, 0x8c, 0x63, 0xc2, 0x3b, 0x25, 0x6e, 0x86, 0x83, 0xf9, 0xe0, 0x1c, 0x34,
+ /*9ff0:*/ 0x8e, 0x27, 0xe0, 0x76, 0xe5, 0xa3, 0x23, 0x89, 0x5a, 0x0c, 0x7d, 0x37, 0xcc, 0x74, 0xeb, 0x22,
+ /*a000:*/ 0x13, 0x21, 0xa9, 0x64, 0x68, 0x50, 0xaa, 0x35, 0x5b, 0x57, 0x29, 0xff, 0xc1, 0x83, 0xb8, 0x00,
+ /*a010:*/ 0x11, 0x85, 0xa8, 0xe7, 0xbb, 0xc7, 0x9f, 0x8e, 0x73, 0x0b, 0x23, 0xfe, 0x4c, 0x59, 0x1e, 0x31,
+ /*a020:*/ 0x55, 0x74, 0x50, 0xf0, 0xb1, 0x95, 0xae, 0x8e, 0xbf, 0x46, 0x82, 0x05, 0xab, 0x19, 0x33, 0xe4,
+ /*a030:*/ 0x7f, 0xf5, 0xbd, 0x83, 0xa9, 0x0f, 0xf3, 0xe7, 0x88, 0x41, 0x47, 0xa7, 0x7f, 0xf3, 0xa3, 0x49,
+ /*a040:*/ 0x23, 0x18, 0xe7, 0x31, 0xba, 0xbf, 0x77, 0x47, 0x43, 0xa7, 0x79, 0x9e, 0xf7, 0xfb, 0x86, 0xfa,
+ /*a050:*/ 0x78, 0xe0, 0x7d, 0x89, 0xc4, 0xb5, 0x1d, 0xd5, 0xf9, 0x78, 0xbf, 0x24, 0x7c, 0xb0, 0xf7, 0x6c,
+ /*a060:*/ 0x95, 0xce, 0xe4, 0x98, 0xa8, 0xb1, 0x8d, 0x13, 0x16, 0xcf, 0x1c, 0xc8, 0x13, 0xf0, 0xfa, 0x10,
+ /*a070:*/ 0x64, 0x10, 0xd4, 0xb9, 0xab, 0xb2, 0x5d, 0x52, 0x92, 0x69, 0x18, 0xec, 0x27, 0xa7, 0x73, 0xde,
+ /*a080:*/ 0x2e, 0xfb, 0xa3, 0xe3, 0xc7, 0xf9, 0xb1, 0x16, 0xdf, 0x5c, 0x60, 0xfa, 0x3a, 0x1d, 0x1a, 0x51,
+ /*a090:*/ 0x6d, 0x00, 0xaf, 0x1d, 0x17, 0x7d, 0x99, 0xb2, 0x8e, 0x39, 0x84, 0x86, 0x81, 0xdb, 0x4b, 0xe6,
+ /*a0a0:*/ 0xc9, 0xa4, 0x6d, 0x0a, 0x53, 0xe3, 0x5e, 0x2b, 0x5b, 0x01, 0x81, 0x75, 0x0a, 0x84, 0xda, 0x5c,
+ /*a0b0:*/ 0x9b, 0x42, 0x5c, 0xab, 0x7b, 0xb8, 0x65, 0x41, 0xb2, 0x6e, 0x74, 0x64, 0x45, 0xc0, 0xe7, 0x24,
+ /*a0c0:*/ 0xf4, 0x64, 0xd8, 0x95, 0x0c, 0x7a, 0xf9, 0x8c, 0x08, 0xf6, 0xd1, 0xe8, 0x36, 0xbc, 0x9f, 0x1e,
+ /*a0d0:*/ 0x46, 0xa8, 0xfa, 0xe9, 0xf6, 0x36, 0x00, 0xf3, 0x1d, 0x5b, 0x63, 0xdc, 0xe0, 0xe7, 0x3f, 0xb6,
+ /*a0e0:*/ 0xb3, 0x2b, 0x74, 0x8d, 0xfb, 0x5e, 0x37, 0x41, 0x51, 0x1f, 0x82, 0x89, 0x37, 0x26, 0x7d, 0x1e,
+ /*a0f0:*/ 0x7e, 0x37, 0xf1, 0xb4, 0xcc, 0x65, 0x19, 0xe5, 0x99, 0x41, 0x4d, 0x93, 0x52, 0x7b, 0x2b, 0xa4,
+ /*a100:*/ 0xb7, 0x31, 0x13, 0x64, 0xdd, 0xed, 0x04, 0x94, 0x22, 0x7e, 0x35, 0xdb, 0xb5, 0xc7, 0xf2, 0x82,
+ /*a110:*/ 0x8d, 0xdf, 0x99, 0x41, 0x65, 0x8c, 0xd7, 0xbe, 0x8b, 0xbf, 0xf8, 0x28, 0x07, 0x33, 0x76, 0x7b,
+ /*a120:*/ 0x17, 0xc5, 0x83, 0x06, 0x63, 0xf5, 0x0c, 0x6a, 0xc8, 0x56, 0x42, 0x13, 0xa5, 0x28, 0x85, 0xba,
+ /*a130:*/ 0xb2, 0x25, 0x2d, 0x95, 0xf2, 0xff, 0x40, 0x20, 0x68, 0xd8, 0x11, 0xfc, 0xf4, 0x02, 0x76, 0x99,
+ /*a140:*/ 0xcf, 0x58, 0x0a, 0xa0, 0x6e, 0x2e, 0x13, 0xfd, 0x57, 0x66, 0x0b, 0xea, 0x05, 0x52, 0xc9, 0x8d,
+ /*a150:*/ 0xf8, 0xff, 0x68, 0x08, 0xc4, 0x10, 0xfd, 0x6d, 0x11, 0xa7, 0x40, 0xcb, 0xe6, 0xc6, 0x67, 0xbc,
+ /*a160:*/ 0x5b, 0xaa, 0xfc, 0xaf, 0xa9, 0x0e, 0xe0, 0x41, 0x8e, 0xa3, 0x83, 0x3e, 0xd6, 0x53, 0xe6, 0x77,
+ /*a170:*/ 0xfb, 0x1e, 0xcd, 0xfe, 0x06, 0x71, 0x0d, 0xc4, 0xf5, 0xff, 0xbc, 0xef, 0xbf, 0x0c, 0x58, 0xee,
+ /*a180:*/ 0xe2, 0x51, 0xf5, 0x32, 0xe9, 0x14, 0x46, 0x13, 0xc7, 0x2a, 0xd9, 0x91, 0x2b, 0xf1, 0x68, 0xce,
+ /*a190:*/ 0x14, 0xfd, 0xf7, 0x48, 0x1b, 0x08, 0x26, 0xdb, 0xc6, 0xdf, 0x1d, 0x4a, 0xc8, 0xac, 0xf2, 0x9b,
+ /*a1a0:*/ 0x23, 0xce, 0x72, 0xff, 0x3d, 0xdc, 0x4a, 0x9b, 0xe6, 0x6b, 0xcd, 0x3d, 0x07, 0xb3, 0x65, 0x58,
+ /*a1b0:*/ 0x08, 0x00, 0xea, 0x68, 0x65, 0x40, 0xb0, 0x0e, 0xfc, 0x37, 0x9a, 0x3b, 0xe2, 0x14, 0x9c, 0xdf,
+ /*a1c0:*/ 0x74, 0x1b, 0x7a, 0xc2, 0xf6, 0x5d, 0x2e, 0xdd, 0xdd, 0xf1, 0x9d, 0x7b, 0x6c, 0xf5, 0xe8, 0xc2,
+ /*a1d0:*/ 0x3f, 0x5b, 0xb3, 0xe0, 0xc7, 0xf4, 0xc3, 0x60, 0x81, 0x9a, 0xff, 0x4a, 0x50, 0xbf, 0xff, 0x14,
+ /*a1e0:*/ 0x9a, 0xea, 0x5e, 0x7b, 0x5f, 0xeb, 0xad, 0xf1, 0x40, 0x19, 0x67, 0x45, 0x6b, 0x69, 0x18, 0x55,
+ /*a1f0:*/ 0xb6, 0x39, 0x32, 0x15, 0xd0, 0xad, 0xb5, 0x66, 0xb2, 0x43, 0x13, 0x27, 0x90, 0xc8, 0x82, 0x7f,
+ /*a200:*/ 0x65, 0x0e, 0xc4, 0x4f, 0xec, 0xa5, 0xa0, 0x93, 0x72, 0x4e, 0x1c, 0xfd, 0xae, 0x29, 0x7f, 0x52,
+ /*a210:*/ 0xde, 0x65, 0xd4, 0xc4, 0x41, 0x48, 0xf3, 0xe7, 0x7b, 0xe9, 0xcc, 0x40, 0xd4, 0xfd, 0xa9, 0x72,
+ /*a220:*/ 0xe9, 0x22, 0x3a, 0xc9, 0xd2, 0x95, 0xd7, 0x84, 0xf4, 0x00, 0x05, 0x1c, 0xd7, 0x06, 0xa5, 0x02,
+ /*a230:*/ 0x41, 0xf2, 0x95, 0xb9, 0x46, 0x25, 0xf1, 0x27, 0x4f, 0xaa, 0x34, 0x8d, 0x1d, 0x06, 0x1f, 0x43,
+ /*a240:*/ 0x69, 0x13, 0x99, 0xcd, 0x6a, 0xd2, 0xa0, 0x6f, 0x47, 0x36, 0x39, 0xda, 0xdd, 0x73, 0x07, 0x58,
+ /*a250:*/ 0x6e, 0x4c, 0x2a, 0xd1, 0x8a, 0x1b, 0xfc, 0xcd, 0x22, 0xed, 0xb9, 0x43, 0xb6, 0x28, 0xfd, 0x58,
+ /*a260:*/ 0xa5, 0x03, 0x30, 0xd4, 0x5a, 0xca, 0x12, 0xb2, 0x8d, 0x06, 0x42, 0x26, 0x72, 0x71, 0xef, 0xf5,
+ /*a270:*/ 0x09, 0x89, 0x86, 0xf1, 0xd9, 0xb2, 0xa6, 0xc1, 0x7d, 0xa2, 0x8c, 0xbc, 0x31, 0xfa, 0x2a, 0xd2,
+ /*a280:*/ 0x3c, 0xd3, 0xf4, 0x60, 0x9c, 0x23, 0xf7, 0xc8, 0x17, 0xf0, 0xd2, 0x89, 0x25, 0xff, 0x45, 0x26,
+ /*a290:*/ 0x5a, 0xa7, 0x68, 0x96, 0x72, 0xca, 0xba, 0x5e, 0xab, 0x97, 0x6d, 0xba, 0xb9, 0x05, 0x91, 0x92,
+ /*a2a0:*/ 0xa5, 0xa1, 0x02, 0x1a, 0x82, 0xaa, 0xa9, 0xf2, 0x51, 0x96, 0x78, 0x25, 0xae, 0x82, 0x89, 0x55,
+ /*a2b0:*/ 0xba, 0x05, 0xd0, 0x4c, 0x86, 0x6b, 0x61, 0x9b, 0x77, 0x4c, 0x8d, 0x6f, 0x7a, 0xac, 0x58, 0x82,
+ /*a2c0:*/ 0xcb, 0xf3, 0xca, 0xe2, 0x7f, 0x9f, 0xbb, 0x69, 0x77, 0x23, 0x15, 0x5b, 0x72, 0x2d, 0x6c, 0x4f,
+ /*a2d0:*/ 0x20, 0x38, 0x5a, 0x5a, 0x37, 0xd8, 0x2e, 0x71, 0x33, 0x4a, 0x14, 0x56, 0xbb, 0x04, 0xc7, 0xb3,
+ /*a2e0:*/ 0xd8, 0x33, 0x1c, 0xa4, 0xd5, 0x57, 0xbf, 0x10, 0xda, 0x1c, 0x30, 0x15, 0x87, 0x87, 0xc2, 0x28,
+ /*a2f0:*/ 0xf6, 0x6c, 0x0d, 0x11, 0x1f, 0xb9, 0x87, 0x86, 0x67, 0x77, 0xbf, 0xee, 0xf6, 0x6d, 0x01, 0x6c,
+ /*a300:*/ 0xb4, 0x00, 0x91, 0x0e, 0xf4, 0x0b, 0x45, 0x85, 0x9e, 0x47, 0x4b, 0xe0, 0x73, 0xc8, 0x7f, 0xc3,
+ /*a310:*/ 0xd7, 0x38, 0x5c, 0x3d, 0x75, 0x0a, 0x48, 0xc6, 0x25, 0xb1, 0x2d, 0xdf, 0xc1, 0xd2, 0xfe, 0xd8,
+ /*a320:*/ 0x63, 0xf0, 0x46, 0xe8, 0x63, 0xb6, 0x72, 0xe3, 0x82, 0xbb, 0x31, 0x2f, 0x12, 0xfb, 0x10, 0x01,
+ /*a330:*/ 0xe4, 0xe2, 0x73, 0xe2, 0x08, 0x2d, 0x1e, 0x60, 0x90, 0x8a, 0x49, 0x9f, 0xf3, 0x9a, 0x97, 0x4d,
+ /*a340:*/ 0x62, 0xa2, 0x8a, 0xee, 0x27, 0x5f, 0x17, 0xfb, 0x36, 0x2b, 0xef, 0x7d, 0xcf, 0x74, 0xce, 0xa0,
+ /*a350:*/ 0x4d, 0x99, 0x34, 0x50, 0xa9, 0x49, 0x57, 0x20, 0x44, 0xd3, 0x84, 0xc9, 0xac, 0xba, 0xe6, 0x5b,
+ /*a360:*/ 0xd2, 0xd1, 0x91, 0xc6, 0x7a, 0xea, 0x3c, 0x0f, 0x4a, 0xc6, 0x30, 0xaa, 0x80, 0xbd, 0x72, 0x0d,
+ /*a370:*/ 0x83, 0xa2, 0x65, 0x47, 0x47, 0x80, 0x80, 0xf5, 0xab, 0xf6, 0x4c, 0x15, 0x6d, 0x99, 0x63, 0x06,
+ /*a380:*/ 0xea, 0xb7, 0x5a, 0x6e, 0x5b, 0x70, 0x4c, 0x00, 0x72, 0x0d, 0x27, 0xb7, 0xd0, 0x81, 0xe9, 0xee,
+ /*a390:*/ 0x23, 0x95, 0xce, 0xc6, 0xa7, 0x71, 0xb5, 0xd9, 0x8f, 0xe5, 0xed, 0xba, 0x88, 0x62, 0x44, 0xbd,
+ /*a3a0:*/ 0x1a, 0x76, 0x49, 0x41, 0xfd, 0x4f, 0x9e, 0x1d, 0x6e, 0xfc, 0x9e, 0x62, 0xc2, 0xd3, 0x54, 0x1b,
+ /*a3b0:*/ 0xf4, 0x69, 0xf0, 0x29, 0xf4, 0xbb, 0x32, 0x5a, 0x1f, 0x5f, 0x70, 0xe3, 0xe6, 0x86, 0x03, 0xe7,
+ /*a3c0:*/ 0x85, 0xbd, 0x29, 0x9c, 0x1a, 0xb3, 0xae, 0xa6, 0xca, 0xbf, 0x4f, 0x47, 0xc1, 0xb3, 0x52, 0xd2,
+ /*a3d0:*/ 0xf1, 0x50, 0x51, 0x23, 0xd6, 0x60, 0x55, 0x61, 0x41, 0xec, 0xf3, 0x23, 0xb7, 0x8f, 0x1c, 0x15,
+ /*a3e0:*/ 0x60, 0x8c, 0xd7, 0x79, 0x0b, 0x77, 0x19, 0x4e, 0x04, 0x42, 0xb0, 0x5c, 0xb9, 0x0c, 0xb9, 0x4a,
+ /*a3f0:*/ 0x0b, 0x2b, 0xf3, 0xd7, 0x4a, 0xd1, 0x46, 0xc2, 0x80, 0xf1, 0xab, 0xac, 0x19, 0xb6, 0x69, 0x2b,
+ /*a400:*/ 0x7d, 0x0b, 0x05, 0xbb, 0x27, 0x37, 0x80, 0x65, 0x98, 0x60, 0x25, 0xe3, 0xab, 0x75, 0x2a, 0xac,
+ /*a410:*/ 0x6a, 0xb0, 0x3a, 0x41, 0x09, 0xcb, 0x85, 0x49, 0xa8, 0x88, 0x6f, 0x9c, 0x07, 0xef, 0x96, 0xca,
+ /*a420:*/ 0xd6, 0x14, 0x41, 0xbf, 0xe7, 0x3a, 0x35, 0xc1, 0x7a, 0x75, 0x3a, 0x2e, 0x9f, 0x7a, 0xd2, 0xfc,
+ /*a430:*/ 0xb0, 0x9d, 0x46, 0xd6, 0xb8, 0xa9, 0x69, 0x19, 0x4a, 0x1d, 0x48, 0xf5, 0xbb, 0x22, 0x78, 0x41,
+ /*a440:*/ 0x21, 0xbc, 0x25, 0xd2, 0xb9, 0x00, 0x4b, 0xcd, 0x4e, 0x16, 0x06, 0x91, 0x2b, 0xb9, 0x12, 0xbc,
+ /*a450:*/ 0x57, 0xa0, 0x41, 0x60, 0x88, 0x76, 0xa0, 0xe7, 0xe6, 0xc9, 0x16, 0x62, 0x70, 0x79, 0x56, 0xe3,
+ /*a460:*/ 0xa4, 0x03, 0x9d, 0x46, 0x62, 0xb3, 0x1b, 0x42, 0x1b, 0x2d, 0x11, 0x83, 0xba, 0x35, 0xa7, 0x8d,
+ /*a470:*/ 0x38, 0xb7, 0xfa, 0xa4, 0x4c, 0x02, 0x1c, 0x60, 0x47, 0x62, 0x96, 0xbe, 0x83, 0x15, 0x9f, 0x31,
+ /*a480:*/ 0xd5, 0x84, 0x2a, 0x8e, 0x7e, 0xb1, 0xba, 0x69, 0x09, 0xa2, 0x68, 0xfa, 0xf9, 0xf0, 0xd3, 0x47,
+ /*a490:*/ 0x3c, 0x10, 0x50, 0x4c, 0x7f, 0x3b, 0x2d, 0x56, 0x0f, 0xa4, 0xea, 0x83, 0xc5, 0x94, 0x02, 0x86,
+ /*a4a0:*/ 0x24, 0x10, 0xae, 0x94, 0x7e, 0x8e, 0xdb, 0xe1, 0xda, 0x9f, 0xd5, 0x79, 0x1f, 0x74, 0x75, 0x81,
+ /*a4b0:*/ 0x86, 0x71, 0xce, 0xf6, 0x47, 0x93, 0xb4, 0xad, 0x0e, 0x3f, 0x02, 0x8b, 0xd9, 0xaa, 0xea, 0x19,
+ /*a4c0:*/ 0x94, 0x6e, 0x43, 0xaa, 0xd6, 0x85, 0x5c, 0x07, 0x52, 0xd0, 0xde, 0xad, 0x23, 0x14, 0x09, 0x0c,
+ /*a4d0:*/ 0xf9, 0xab, 0x4b, 0x77, 0x4d, 0x26, 0xa3, 0x05, 0x61, 0x06, 0x32, 0xe4, 0xac, 0x89, 0xb8, 0xbe,
+ /*a4e0:*/ 0x85, 0x80, 0xde, 0xf0, 0xdb, 0x36, 0x1b, 0x68, 0x62, 0x86, 0xa0, 0x72, 0x71, 0x62, 0x7f, 0xd3,
+ /*a4f0:*/ 0xbf, 0x14, 0x3b, 0x1f, 0x84, 0x63, 0x47, 0x20, 0x09, 0x42, 0x57, 0xb6, 0x72, 0x09, 0xa8, 0xac,
+ /*a500:*/ 0xb0, 0x9b, 0xdf, 0x64, 0x4f, 0x47, 0xe4, 0x03, 0x72, 0x91, 0x88, 0x9d, 0x71, 0x13, 0x9f, 0xf2,
+ /*a510:*/ 0xf0, 0x90, 0x1b, 0xf8, 0x3c, 0x98, 0xff, 0x75, 0x63, 0xb4, 0x83, 0x9c, 0x28, 0x0a, 0x3b, 0x7d,
+ /*a520:*/ 0xda, 0xcc, 0xff, 0x1b, 0x5b, 0x20, 0x19, 0xb9, 0x54, 0xcf, 0xf6, 0x56, 0x9c, 0xb7, 0x73, 0xa3,
+ /*a530:*/ 0xbc, 0x12, 0x86, 0x03, 0xe5, 0x00, 0x9f, 0xf5, 0x27, 0xdd, 0xa0, 0xbd, 0x33, 0xe4, 0x31, 0x8e,
+ /*a540:*/ 0x04, 0xb7, 0x98, 0x16, 0x6d, 0x8c, 0x6c, 0x27, 0x91, 0x34, 0x70, 0x90, 0xca, 0x5f, 0x80, 0x9a,
+ /*a550:*/ 0xf9, 0x33, 0xf5, 0x26, 0xcd, 0xee, 0x48, 0xfc, 0xde, 0x3d, 0x69, 0xd7, 0x57, 0x94, 0x8e, 0xa1,
+ /*a560:*/ 0xda, 0x9e, 0x53, 0x93, 0x45, 0x53, 0x43, 0xa7, 0x33, 0x9c, 0x2d, 0x4b, 0x77, 0xe4, 0x65, 0x3f,
+ /*a570:*/ 0xce, 0x65, 0xa7, 0x47, 0xe1, 0x25, 0xbe, 0x56, 0xd8, 0xa6, 0xb7, 0x81, 0x8b, 0x77, 0x74, 0x74,
+ /*a580:*/ 0xa9, 0x66, 0xe5, 0x57, 0xa8, 0x69, 0x41, 0xc1, 0xff, 0x69, 0xa7, 0x76, 0x10, 0xd5, 0xab, 0x08,
+ /*a590:*/ 0x15, 0xb1, 0x7f, 0xa2, 0x33, 0xbe, 0x71, 0xae, 0x2c, 0x49, 0x45, 0x17, 0xba, 0x0c, 0xe0, 0xc1,
+ /*a5a0:*/ 0x6c, 0x2f, 0x12, 0x72, 0xa8, 0x84, 0x96, 0x8e, 0x33, 0x13, 0xb2, 0xea, 0x3a, 0x6a, 0x47, 0xb3,
+ /*a5b0:*/ 0xf3, 0x79, 0xbf, 0xf6, 0x61, 0x97, 0xbf, 0xd4, 0xe0, 0xcc, 0x23, 0xa8, 0x37, 0x21, 0xeb, 0x6e,
+ /*a5c0:*/ 0x20, 0x07, 0x4f, 0x93, 0x2d, 0x42, 0xf0, 0xba, 0x97, 0x8e, 0xfe, 0x33, 0xe5, 0x70, 0x6c, 0x1f,
+ /*a5d0:*/ 0x1f, 0xac, 0xd2, 0x48, 0xee, 0x4d, 0x50, 0xc2, 0x26, 0x93, 0x11, 0x08, 0x1a, 0x5d, 0x05, 0x4c,
+ /*a5e0:*/ 0xf9, 0x2a, 0x27, 0xfa, 0x1f, 0xfa, 0xcd, 0x60, 0xee, 0xa1, 0xf8, 0x61, 0xed, 0xc4, 0xb3, 0x6f,
+ /*a5f0:*/ 0x53, 0xb2, 0xd2, 0x4a, 0x62, 0xbe, 0x11, 0xd3, 0x88, 0x1f, 0x64, 0xb2, 0xc9, 0x42, 0x87, 0xa8,
+ /*a600:*/ 0xa0, 0xd6, 0xb3, 0x78, 0x9d, 0xcb, 0x7f, 0xec, 0x7f, 0xb9, 0xad, 0x23, 0x78, 0x1f, 0x5f, 0xd0,
+ /*a610:*/ 0x3f, 0x61, 0x45, 0xf3, 0x55, 0xee, 0xd1, 0xd6, 0x2c, 0x59, 0x20, 0x1c, 0x6e, 0xd7, 0xaa, 0xf0,
+ /*a620:*/ 0xf2, 0x4b, 0x77, 0x95, 0x93, 0x68, 0x0a, 0xc8, 0x31, 0x06, 0x01, 0xf9, 0x58, 0xc8, 0xb0, 0x49,
+ /*a630:*/ 0xe3, 0x87, 0x5f, 0x5e, 0xd1, 0x95, 0xbe, 0xf6, 0xcc, 0xf2, 0xbb, 0xb9, 0x5d, 0xa7, 0x9e, 0x4d,
+ /*a640:*/ 0xde, 0x0e, 0x52, 0xe0, 0xf2, 0x88, 0x3b, 0xca, 0x7c, 0x74, 0x0f, 0x76, 0x6c, 0xb5, 0xa2, 0xab,
+ /*a650:*/ 0xb2, 0x02, 0xdc, 0xae, 0x83, 0x7b, 0xd8, 0x01, 0x24, 0x11, 0x49, 0xe9, 0x58, 0x00, 0xad, 0x54,
+ /*a660:*/ 0x89, 0xa6, 0x84, 0x7e, 0x79, 0x20, 0x6a, 0xf8, 0x5e, 0xc3, 0x25, 0x29, 0xb7, 0x15, 0x8b, 0xaa,
+ /*a670:*/ 0x67, 0xf4, 0x08, 0x88, 0x75, 0xe0, 0xee, 0x5e, 0x40, 0xb0, 0x93, 0x77, 0x44, 0x1e, 0xe6, 0x92,
+ /*a680:*/ 0xe9, 0x54, 0xfc, 0x8c, 0x9c, 0x03, 0x2b, 0x8e, 0x4a, 0x04, 0x3d, 0x76, 0xa4, 0x07, 0xe2, 0x62,
+ /*a690:*/ 0xfb, 0x17, 0xab, 0x7c, 0x32, 0x69, 0xb7, 0xb8, 0x53, 0x4a, 0x6a, 0xe2, 0x9c, 0xd8, 0xf1, 0x7c,
+ /*a6a0:*/ 0x31, 0xfd, 0x2e, 0xdc, 0xb8, 0xce, 0xf0, 0xa3, 0x90, 0xe4, 0xc1, 0xa1, 0xf8, 0xda, 0xb9, 0x74,
+ /*a6b0:*/ 0x95, 0x9e, 0x2f, 0xcf, 0x74, 0x90, 0x5e, 0x10, 0x2c, 0xf7, 0x8f, 0x82, 0xa6, 0x6d, 0x97, 0xb2,
+ /*a6c0:*/ 0x25, 0x44, 0x5b, 0xae, 0x03, 0x6a, 0x09, 0xe8, 0x69, 0x9b, 0xdf, 0x34, 0x57, 0x5e, 0x1b, 0x58,
+ /*a6d0:*/ 0x36, 0x4a, 0x79, 0x26, 0x1a, 0x6f, 0x4e, 0xa1, 0xf6, 0xfd, 0xa9, 0x6a, 0xd4, 0xb6, 0x2c, 0x1e,
+ /*a6e0:*/ 0x54, 0xee, 0x6a, 0x3d, 0x13, 0xed, 0x98, 0xb9, 0xd1, 0xc7, 0x40, 0x3b, 0xb1, 0x08, 0x74, 0xf2,
+ /*a6f0:*/ 0x9e, 0x23, 0x70, 0x0f, 0xfe, 0xcf, 0xe0, 0x42, 0x94, 0xb9, 0xfb, 0x1a, 0xf5, 0xfa, 0xee, 0xe5,
+ /*a700:*/ 0x60, 0xf3, 0x74, 0x2e, 0x8a, 0x6b, 0x45, 0xbe, 0x6f, 0x0e, 0x98, 0xa8, 0xe4, 0x39, 0x81, 0xdf,
+ /*a710:*/ 0xd1, 0x0e, 0x17, 0xfc, 0xd1, 0xfe, 0x65, 0xa6, 0xe0, 0xe0, 0x3a, 0xd2, 0xe6, 0xb5, 0xe7, 0x50,
+ /*a720:*/ 0x08, 0x6a, 0x16, 0x66, 0x2e, 0x7f, 0x9d, 0x24, 0xbb, 0x88, 0xa8, 0x39, 0xac, 0xe4, 0x83, 0xf1,
+ /*a730:*/ 0x82, 0x24, 0x25, 0xbc, 0x70, 0x61, 0x83, 0xf8, 0x33, 0x88, 0xee, 0xd7, 0x03, 0x31, 0x88, 0x22,
+ /*a740:*/ 0x06, 0xee, 0x65, 0x98, 0x1c, 0x79, 0x74, 0x8d, 0x62, 0xda, 0x8c, 0x4d, 0xa6, 0x65, 0x39, 0x0b,
+ /*a750:*/ 0xbb, 0xaa, 0x7b, 0x3e, 0xc7, 0x21, 0x34, 0xbc, 0x1a, 0xd0, 0x83, 0x0d, 0x28, 0x32, 0x03, 0xd6,
+ /*a760:*/ 0x1d, 0x57, 0x40, 0x62, 0xd3, 0xba, 0x59, 0xdd, 0x21, 0x3a, 0xb6, 0xcc, 0x9f, 0xd9, 0x48, 0xa1,
+ /*a770:*/ 0x5f, 0x79, 0xb0, 0x25, 0x6f, 0x8b, 0x9c, 0x9a, 0x38, 0x02, 0x45, 0xfb, 0xc4, 0x4c, 0x19, 0x6a,
+ /*a780:*/ 0x80, 0x89, 0x53, 0xfc, 0x16, 0x92, 0xa2, 0x65, 0x6f, 0x49, 0xca, 0x34, 0x44, 0xd7, 0x47, 0xb1,
+ /*a790:*/ 0xca, 0xcb, 0x6f, 0x1b, 0x4e, 0xad, 0x40, 0x93, 0x3e, 0x17, 0x51, 0x24, 0xc7, 0xa4, 0x91, 0x94,
+ /*a7a0:*/ 0x85, 0xbc, 0x2e, 0x1a, 0xc0, 0x60, 0x26, 0xb9, 0x50, 0x3b, 0x40, 0xb0, 0x35, 0x85, 0xb7, 0x1f,
+ /*a7b0:*/ 0x06, 0x30, 0x1e, 0x8e, 0x23, 0xf2, 0xad, 0x79, 0xe5, 0x6e, 0xfa, 0xf6, 0x68, 0x11, 0xdc, 0xce,
+ /*a7c0:*/ 0x35, 0xe2, 0x8e, 0xcb, 0x2d, 0xe1, 0x00, 0x4b, 0x47, 0xeb, 0x86, 0x23, 0x94, 0xfb, 0xa2, 0x30,
+ /*a7d0:*/ 0xf5, 0x36, 0x9e, 0x94, 0xc9, 0x80, 0x16, 0xdc, 0x57, 0x9e, 0xb5, 0x8a, 0x0c, 0x0e, 0xcb, 0x28,
+ /*a7e0:*/ 0xf4, 0x5f, 0x4d, 0xc2, 0xa3, 0x6a, 0x07, 0x86, 0xda, 0xf4, 0x6c, 0x4e, 0xc8, 0xa1, 0xac, 0x9b,
+ /*a7f0:*/ 0x15, 0xd7, 0x86, 0x2c, 0x83, 0x2d, 0x5a, 0x83, 0x51, 0x6a, 0xd5, 0x1b, 0x92, 0xf7, 0x63, 0x8b,
+ /*a800:*/ 0x1d, 0x94, 0xc5, 0x1c, 0x6d, 0x85, 0xb1, 0x77, 0x54, 0x86, 0x46, 0xc4, 0x42, 0x73, 0x6e, 0xf2,
+ /*a810:*/ 0x81, 0x4a, 0xb0, 0xac, 0x34, 0x32, 0xe6, 0x00, 0x93, 0x55, 0xe6, 0x78, 0x31, 0xb8, 0xc4, 0x9c,
+ /*a820:*/ 0xe0, 0xdd, 0x9d, 0xa4, 0x67, 0x6c, 0x8c, 0x64, 0xf1, 0xd6, 0x5d, 0x4a, 0x2e, 0xff, 0x6e, 0x7e,
+ /*a830:*/ 0xc5, 0x09, 0x8e, 0x27, 0xbe, 0x1e, 0xc4, 0xe3, 0x8b, 0x6b, 0x4b, 0x72, 0xb6, 0x18, 0xf3, 0x69,
+ /*a840:*/ 0x0e, 0x2e, 0xda, 0xb3, 0x0b, 0x35, 0x1a, 0xb2, 0x17, 0xa6, 0x25, 0x96, 0xbc, 0xe8, 0x41, 0xdb,
+ /*a850:*/ 0xc5, 0x76, 0xa3, 0xe9, 0x11, 0xf1, 0xc1, 0xe0, 0xde, 0x91, 0x1b, 0x26, 0x93, 0x9c, 0xd6, 0xe9,
+ /*a860:*/ 0x3a, 0xb8, 0x91, 0xd5, 0x02, 0x1b, 0x7a, 0x0c, 0x3e, 0x0a, 0x01, 0xe0, 0x4b, 0xdc, 0xd7, 0xa4,
+ /*a870:*/ 0x41, 0x19, 0x3a, 0xd5, 0xa9, 0x3d, 0x9e, 0x51, 0x01, 0xa2, 0xb4, 0xbf, 0xf3, 0xbf, 0x54, 0xe0,
+ /*a880:*/ 0xdc, 0x29, 0xdc, 0x44, 0xd9, 0x6d, 0xd0, 0x93, 0x45, 0x59, 0x78, 0xa7, 0xce, 0x43, 0x2e, 0x60,
+ /*a890:*/ 0xae, 0xab, 0x59, 0x9f, 0x4b, 0xfe, 0x8e, 0x43, 0x5c, 0xd8, 0xbd, 0x59, 0xa4, 0x6e, 0x9d, 0xab,
+ /*a8a0:*/ 0xf1, 0xb6, 0x24, 0x4a, 0x05, 0x39, 0x4b, 0xbd, 0x66, 0x55, 0xcf, 0x43, 0xd4, 0x59, 0xc6, 0x0d,
+ /*a8b0:*/ 0x1b, 0x08, 0xe5, 0x5b, 0x15, 0xc9, 0x40, 0x30, 0xc4, 0x82, 0xfb, 0xf9, 0xd8, 0xee, 0x89, 0x81,
+ /*a8c0:*/ 0x9c, 0xa1, 0x5c, 0xd5, 0x4a, 0x76, 0x1d, 0x57, 0xa0, 0x9e, 0xb8, 0x7d, 0x10, 0x86, 0x99, 0x5b,
+ /*a8d0:*/ 0x96, 0x08, 0x92, 0x19, 0xca, 0xb4, 0xef, 0x92, 0x4f, 0x80, 0x80, 0x5f, 0xe1, 0xf8, 0x89, 0x72,
+ /*a8e0:*/ 0xc0, 0x51, 0xf5, 0xa4, 0xda, 0x24, 0xca, 0x43, 0xf3, 0x4e, 0x3a, 0x72, 0x88, 0x3d, 0x1d, 0x36,
+ /*a8f0:*/ 0xa6, 0xdb, 0x52, 0x3e, 0x8c, 0x41, 0x16, 0xb7, 0x5c, 0x0a, 0x64, 0x2a, 0x53, 0x62, 0x28, 0x67,
+ /*a900:*/ 0xa4, 0x5d, 0x75, 0x75, 0x4e, 0x45, 0x80, 0x6b, 0xb7, 0xc8, 0x84, 0xaa, 0xe9, 0x53, 0x7e, 0x86,
+ /*a910:*/ 0x2e, 0x80, 0x39, 0x72, 0x3b, 0x03, 0xd2, 0x8a, 0xe9, 0xa6, 0xd0, 0xfc, 0x2e, 0xe4, 0x87, 0xd1,
+ /*a920:*/ 0xc3, 0x2b, 0x42, 0x46, 0xe6, 0xe4, 0x38, 0xa1, 0x0c, 0x18, 0xe4, 0x31, 0xd4, 0xd1, 0xd3, 0x50,
+ /*a930:*/ 0xcb, 0xd0, 0x67, 0x68, 0x15, 0x8e, 0x47, 0x85, 0x4b, 0x94, 0x13, 0x8b, 0x2c, 0x66, 0xa0, 0x2f,
+ /*a940:*/ 0xd3, 0xf8, 0x7a, 0xcc, 0xb4, 0xb4, 0x26, 0xb7, 0xbd, 0x2c, 0xff, 0xaa, 0x93, 0xfb, 0xa0, 0xc0,
+ /*a950:*/ 0xc3, 0x55, 0x3b, 0x98, 0xe6, 0xac, 0x75, 0xd0, 0x0b, 0x3a, 0x7c, 0xd0, 0xe1, 0x45, 0x3f, 0x4b,
+ /*a960:*/ 0xc2, 0xe1, 0x72, 0xbd, 0xda, 0x91, 0xd8, 0x4d, 0x1e, 0x37, 0xdb, 0x09, 0xf6, 0xb6, 0x84, 0x90,
+ /*a970:*/ 0xdb, 0xde, 0xb4, 0x45, 0xed, 0x6b, 0x85, 0x15, 0x41, 0x8e, 0x04, 0x62, 0x10, 0x31, 0x75, 0x75,
+ /*a980:*/ 0xa2, 0xce, 0x16, 0xa0, 0xdd, 0x28, 0x98, 0x39, 0xf8, 0x15, 0xcc, 0x93, 0x75, 0xc4, 0xf1, 0xa1,
+ /*a990:*/ 0xc7, 0xab, 0x0e, 0x86, 0x54, 0x70, 0x2f, 0x39, 0x76, 0x49, 0x20, 0x87, 0x42, 0x6e, 0x37, 0x7b,
+ /*a9a0:*/ 0x31, 0x8d, 0x72, 0xf3, 0x97, 0xae, 0x38, 0xb7, 0x63, 0x38, 0xb3, 0x65, 0x86, 0xa2, 0x0b, 0xaa,
+ /*a9b0:*/ 0x6a, 0x16, 0xf0, 0xe6, 0xf4, 0xd0, 0x29, 0x66, 0xbb, 0x6c, 0xd0, 0x2e, 0x86, 0x44, 0xe8, 0x39,
+ /*a9c0:*/ 0xd1, 0x37, 0x50, 0xd3, 0x5c, 0xdd, 0x5a, 0xf4, 0xc0, 0x08, 0x35, 0x82, 0xd9, 0xdf, 0x76, 0xc8,
+ /*a9d0:*/ 0x65, 0x54, 0x18, 0xf3, 0xf3, 0x48, 0xfc, 0x03, 0x0d, 0x2e, 0xee, 0xdb, 0xd8, 0x89, 0x47, 0x1a,
+ /*a9e0:*/ 0xd1, 0x90, 0xaf, 0xe7, 0x87, 0x92, 0xb0, 0x32, 0x02, 0x7d, 0x5b, 0xd1, 0x75, 0xa9, 0xd0, 0xfc,
+ /*a9f0:*/ 0x0e, 0x02, 0x64, 0x31, 0xba, 0xc0, 0x40, 0xfc, 0x48, 0xc5, 0x74, 0x6c, 0xbb, 0x76, 0x05, 0x2b,
+ /*aa00:*/ 0x92, 0xd0, 0xed, 0xd4, 0x1e, 0x87, 0x63, 0xba, 0x01, 0x0a, 0xf9, 0xb3, 0xe3, 0x3a, 0xbf, 0x34,
+ /*aa10:*/ 0x4d, 0x92, 0x00, 0xc4, 0xf4, 0x13, 0x65, 0x72, 0xaf, 0x4f, 0x1e, 0xa9, 0x35, 0xc9, 0x3b, 0x76,
+ /*aa20:*/ 0xba, 0x0b, 0x34, 0x4f, 0xaf, 0xcf, 0x13, 0x39, 0x4a, 0xb0, 0xf3, 0x4c, 0x2e, 0x88, 0xfa, 0x4a,
+ /*aa30:*/ 0xde, 0xa1, 0x3b, 0xcf, 0x21, 0x2c, 0x0f, 0x2e, 0x32, 0xe6, 0x24, 0x83, 0xe5, 0x6b, 0x36, 0x21,
+ /*aa40:*/ 0x7f, 0xe1, 0x25, 0xa5, 0x49, 0xf0, 0xb5, 0x9f, 0x93, 0xe9, 0x59, 0x09, 0x19, 0x8f, 0x71, 0x6b,
+ /*aa50:*/ 0x08, 0x53, 0xfd, 0x6e, 0xdc, 0x53, 0x7b, 0xfe, 0x0f, 0xa2, 0x2b, 0x16, 0xca, 0xca, 0x31, 0x3d,
+ /*aa60:*/ 0x79, 0x13, 0x0b, 0x8a, 0x39, 0x1d, 0x9f, 0x70, 0x94, 0xc5, 0x3c, 0xa0, 0x3d, 0x2f, 0x73, 0xe0,
+ /*aa70:*/ 0x27, 0x37, 0x49, 0xe4, 0x84, 0xf5, 0xe6, 0x68, 0xfb, 0xab, 0x15, 0x76, 0xee, 0x65, 0x3c, 0xbf,
+ /*aa80:*/ 0x30, 0x90, 0x0c, 0x6d, 0x15, 0xfc, 0xa0, 0x1b, 0xb6, 0xa5, 0xea, 0x32, 0x63, 0x4f, 0x6b, 0x20,
+ /*aa90:*/ 0x0d, 0x04, 0xff, 0xaf, 0x95, 0xe4, 0x9b, 0xe8, 0xae, 0x91, 0x85, 0x3a, 0x6b, 0x9d, 0xa7, 0x3a,
+ /*aaa0:*/ 0x3b, 0x88, 0xd6, 0xc4, 0x28, 0x02, 0x17, 0x20, 0xfc, 0x2b, 0x8d, 0x73, 0x2f, 0xcb, 0xd4, 0x31,
+ /*aab0:*/ 0x4a, 0x30, 0xa5, 0x52, 0x56, 0xbd, 0xed, 0xb2, 0x88, 0x5d, 0xa7, 0xf6, 0xcf, 0xe2, 0x70, 0x7b,
+ /*aac0:*/ 0x46, 0x4f, 0x24, 0x65, 0xdb, 0xaf, 0x56, 0xef, 0x07, 0x30, 0x0b, 0xa6, 0x8f, 0xc3, 0x9e, 0x39,
+ /*aad0:*/ 0x0c, 0x91, 0xd8, 0x2b, 0x14, 0xa0, 0xc9, 0x93, 0x8a, 0x94, 0x22, 0xee, 0x81, 0x74, 0xbc, 0x12,
+ /*aae0:*/ 0x69, 0x0b, 0x3f, 0x4a, 0x3b, 0x79, 0x9b, 0x6f, 0x2f, 0x0d, 0x6f, 0xd0, 0x3f, 0xf8, 0x2d, 0x50,
+ /*aaf0:*/ 0x0a, 0xa0, 0xda, 0xb4, 0x0a, 0xf4, 0xda, 0xdb, 0x21, 0x85, 0x8b, 0xf9, 0x61, 0xa4, 0xe6, 0xda,
+ /*ab00:*/ 0x42, 0xf8, 0x02, 0x1e, 0x78, 0x34, 0x8c, 0xd2, 0xbd, 0xf0, 0x3b, 0x75, 0x5b, 0x0b, 0x7e, 0x91,
+ /*ab10:*/ 0x60, 0xcd, 0x20, 0xab, 0x04, 0x61, 0x9b, 0x45, 0x04, 0x53, 0x0d, 0x27, 0x27, 0x18, 0x27, 0x44,
+ /*ab20:*/ 0x14, 0xb0, 0xe2, 0x54, 0x7d, 0x41, 0xbc, 0x44, 0xf4, 0x94, 0xfe, 0xf3, 0xfa, 0x6a, 0x0f, 0xda,
+ /*ab30:*/ 0xe1, 0x7c, 0x5e, 0x72, 0x64, 0xe2, 0xe7, 0xd7, 0x81, 0x49, 0x69, 0x94, 0x9e, 0xee, 0xb6, 0x8a,
+ /*ab40:*/ 0x20, 0xf8, 0x19, 0x48, 0xc5, 0x9c, 0x7e, 0x25, 0xb6, 0xf6, 0xe6, 0x92, 0xba, 0xb0, 0x0d, 0x47,
+ /*ab50:*/ 0x9f, 0x4e, 0x40, 0x7f, 0x90, 0x6b, 0x56, 0xdc, 0x07, 0x4f, 0x88, 0xcb, 0xf0, 0x1f, 0x09, 0x1d,
+ /*ab60:*/ 0xad, 0x14, 0x36, 0x7e, 0x19, 0x32, 0xdd, 0x75, 0x3a, 0xc2, 0x46, 0xc6, 0xb4, 0xce, 0x11, 0xee,
+ /*ab70:*/ 0x5d, 0x15, 0xdd, 0xd0, 0xc5, 0xfc, 0x59, 0x39, 0x14, 0x0b, 0x87, 0x37, 0x71, 0x24, 0x33, 0x5d,
+ /*ab80:*/ 0xb6, 0x71, 0xea, 0x4c, 0xd8, 0x5b, 0x73, 0x3e, 0x7d, 0x40, 0x8b, 0x65, 0x16, 0xa1, 0x08, 0xf1,
+ /*ab90:*/ 0xfd, 0x2f, 0xab, 0xed, 0x8f, 0xeb, 0x7e, 0xfb, 0x40, 0x26, 0x66, 0xce, 0x05, 0x07, 0x6b, 0x65,
+ /*aba0:*/ 0x93, 0x00, 0x69, 0xbc, 0xdf, 0x11, 0x67, 0xf5, 0x39, 0x9a, 0xce, 0x51, 0xcf, 0x63, 0x90, 0xa5,
+ /*abb0:*/ 0xcc, 0x0b, 0xf9, 0x00, 0x44, 0xe4, 0x14, 0xc1, 0x16, 0xa6, 0x3f, 0x1b, 0x15, 0x2e, 0x7d, 0x3e,
+ /*abc0:*/ 0x86, 0xbd, 0xc5, 0x4a, 0x3b, 0xff, 0x2f, 0x9b, 0x73, 0x2b, 0x40, 0x1b, 0xa0, 0xb1, 0x51, 0x84,
+ /*abd0:*/ 0x76, 0x8b, 0x5e, 0x61, 0x32, 0xc1, 0xcc, 0xb6, 0xd8, 0x39, 0xce, 0xbb, 0xe6, 0x82, 0xf0, 0x72,
+ /*abe0:*/ 0x09, 0x07, 0xe5, 0x25, 0x98, 0x60, 0x02, 0x37, 0x29, 0x5a, 0x9f, 0xca, 0x83, 0x90, 0x85, 0x28,
+ /*abf0:*/ 0xa7, 0x88, 0xae, 0xb8, 0x77, 0xee, 0x61, 0x85, 0x32, 0x57, 0xb6, 0xf8, 0x3c, 0x69, 0x39, 0xc0,
+ /*ac00:*/ 0x3d, 0x78, 0x30, 0x86, 0x7a, 0x8f, 0x86, 0x4b, 0xe7, 0x0d, 0xb1, 0x6f, 0x4a, 0x21, 0x56, 0x40,
+ /*ac10:*/ 0xb8, 0xd6, 0x1e, 0x36, 0xca, 0xb0, 0x94, 0xb0, 0x1c, 0x84, 0x6b, 0x45, 0xe7, 0xee, 0x10, 0xf6,
+ /*ac20:*/ 0xdd, 0xa0, 0x32, 0x58, 0x04, 0xad, 0x5e, 0xd2, 0x99, 0x74, 0x78, 0x56, 0x78, 0x7e, 0x81, 0x0f,
+ /*ac30:*/ 0x2d, 0x2b, 0x86, 0x0d, 0x67, 0xd3, 0x00, 0xf8, 0xe5, 0xb0, 0x2b, 0xf9, 0x86, 0x8f, 0xf7, 0x48,
+ /*ac40:*/ 0x7d, 0xc0, 0xf6, 0x65, 0x55, 0xe2, 0xed, 0xb3, 0x17, 0xb5, 0x5c, 0xc7, 0xc2, 0xba, 0xf6, 0x51,
+ /*ac50:*/ 0xf9, 0x9b, 0x63, 0xd9, 0xf9, 0x31, 0xfe, 0xe2, 0x70, 0x50, 0x81, 0x09, 0x4c, 0xf6, 0x5a, 0x8c,
+ /*ac60:*/ 0x9c, 0xcf, 0x66, 0x48, 0xb7, 0x7c, 0x95, 0x9d, 0xbd, 0x3f, 0x65, 0x5d, 0x6b, 0x3d, 0xe1, 0x3e,
+ /*ac70:*/ 0x5c, 0x3a, 0xff, 0xcc, 0x19, 0xef, 0x3f, 0xa5, 0xe0, 0xaf, 0xa9, 0x58, 0x9f, 0xae, 0xb7, 0x7d,
+ /*ac80:*/ 0xad, 0xde, 0x83, 0x6f, 0xfa, 0x44, 0x1a, 0x44, 0x8f, 0x46, 0xed, 0x15, 0x73, 0xb4, 0x3d, 0x92,
+ /*ac90:*/ 0x56, 0xb5, 0x56, 0x42, 0xe6, 0x3d, 0xc4, 0x5a, 0xd9, 0xa7, 0x57, 0x01, 0x50, 0x06, 0x76, 0xf2,
+ /*aca0:*/ 0x20, 0xa5, 0x8f, 0xb0, 0xc5, 0xe8, 0x44, 0x51, 0xec, 0xf8, 0x36, 0x6f, 0x0e, 0xf6, 0xa8, 0xd4,
+ /*acb0:*/ 0x60, 0xe3, 0x01, 0xe5, 0xaf, 0xf9, 0xae, 0x1e, 0x6e, 0x5c, 0x6f, 0x2f, 0x29, 0xc3, 0xc3, 0xa5,
+ /*acc0:*/ 0xf4, 0xb8, 0x5f, 0x8e, 0x12, 0xab, 0x00, 0xaa, 0xbd, 0x06, 0x8a, 0x1e, 0xbb, 0x43, 0xc4, 0xbd,
+ /*acd0:*/ 0x9d, 0xe5, 0x6d, 0x6f, 0xad, 0xf7, 0x87, 0xfd, 0xc4, 0xd4, 0x65, 0x1e, 0xa5, 0xbc, 0x79, 0x88,
+ /*ace0:*/ 0x01, 0xdb, 0xd9, 0xaa, 0x2c, 0xde, 0x23, 0xfb, 0xee, 0x54, 0x92, 0x24, 0x70, 0x65, 0xd7, 0xbb,
+ /*acf0:*/ 0xfd, 0x33, 0x1e, 0x61, 0xa5, 0xd6, 0x97, 0x71, 0x1f, 0x9a, 0xf8, 0x72, 0xe1, 0x42, 0x40, 0x16,
+ /*ad00:*/ 0x73, 0xda, 0x68, 0xca, 0xe0, 0x46, 0xf0, 0xaa, 0x64, 0x0b, 0x8e, 0x0a, 0x36, 0x82, 0xd9, 0x63,
+ /*ad10:*/ 0x06, 0xc5, 0x84, 0x65, 0xea, 0xd7, 0xd1, 0x29, 0x00, 0xf1, 0xf3, 0x27, 0x7d, 0x1a, 0x7d, 0x42,
+ /*ad20:*/ 0xc3, 0x80, 0x5f, 0xb8, 0xaf, 0x37, 0x43, 0x96, 0x83, 0x65, 0xff, 0xe0, 0x71, 0x43, 0x83, 0x64,
+ /*ad30:*/ 0xe7, 0x88, 0x6e, 0xf5, 0x18, 0x92, 0x78, 0xd0, 0x1c, 0xa3, 0x3d, 0x5a, 0x01, 0xd0, 0xb6, 0xf2,
+ /*ad40:*/ 0xd7, 0x14, 0x28, 0x8c, 0x2c, 0xac, 0xdb, 0x35, 0x3e, 0x26, 0x52, 0x18, 0xfb, 0x5d, 0x07, 0x49,
+ /*ad50:*/ 0x19, 0x4c, 0x0c, 0x62, 0xab, 0x3b, 0x6c, 0x7b, 0x90, 0x41, 0x47, 0x30, 0xf9, 0x41, 0xe0, 0x59,
+ /*ad60:*/ 0xc9, 0xeb, 0x0a, 0xa6, 0x23, 0xad, 0x2d, 0xd5, 0x87, 0x20, 0xd4, 0xf9, 0x76, 0x7d, 0xfc, 0xfe,
+ /*ad70:*/ 0x19, 0x77, 0xef, 0x35, 0xb8, 0xeb, 0xca, 0x15, 0xd1, 0x46, 0xcb, 0x34, 0xef, 0xcf, 0x18, 0x8f,
+ /*ad80:*/ 0x77, 0xfe, 0x62, 0xb8, 0xa9, 0xcd, 0x47, 0xd7, 0x0c, 0xb6, 0x36, 0xaf, 0xde, 0x5a, 0x1d, 0x55,
+ /*ad90:*/ 0x76, 0x51, 0x64, 0x77, 0x90, 0x93, 0xab, 0x38, 0xeb, 0x97, 0x73, 0xcc, 0xa7, 0x1b, 0x0d, 0x1f,
+ /*ada0:*/ 0x8d, 0x77, 0x40, 0xb4, 0x66, 0x85, 0xbc, 0xda, 0x3a, 0xd4, 0xb0, 0x00, 0x5e, 0x9a, 0x97, 0xf1,
+ /*adb0:*/ 0x94, 0xb3, 0x1c, 0x53, 0x46, 0xf3, 0xbd, 0x4b, 0xa5, 0x92, 0xf1, 0xba, 0xad, 0xbf, 0xdd, 0x83,
+ /*adc0:*/ 0x45, 0x20, 0x58, 0x52, 0x23, 0xbf, 0x86, 0x9f, 0xe8, 0xb4, 0xef, 0x72, 0x17, 0xae, 0x86, 0x54,
+ /*add0:*/ 0xba, 0x7e, 0x47, 0x08, 0x21, 0x68, 0x39, 0x5d, 0x8a, 0x4a, 0x19, 0x7e, 0x82, 0x5d, 0xdf, 0x81,
+ /*ade0:*/ 0x58, 0xfe, 0xe3, 0xd4, 0x99, 0xa8, 0x4b, 0x3e, 0x95, 0xea, 0xba, 0x72, 0x4c, 0x87, 0xfc, 0x8b,
+ /*adf0:*/ 0x8d, 0x92, 0x0a, 0xbe, 0xe5, 0xdf, 0xa9, 0xbc, 0x55, 0x24, 0x14, 0xcc, 0xb1, 0x74, 0xaa, 0x47,
+ /*ae00:*/ 0x87, 0x3f, 0x81, 0xe7, 0x5a, 0xd2, 0x38, 0x8c, 0x98, 0x90, 0x71, 0xe1, 0x5f, 0xd7, 0xbb, 0x15,
+ /*ae10:*/ 0xd0, 0xf7, 0x87, 0xac, 0xe1, 0xd6, 0xec, 0xa5, 0xcf, 0x1c, 0xd4, 0x26, 0xb7, 0x34, 0x01, 0xaf,
+ /*ae20:*/ 0xf5, 0x27, 0x01, 0xaf, 0xa7, 0xfb, 0xde, 0x81, 0xb3, 0xa7, 0x72, 0x13, 0x0f, 0xbe, 0x73, 0x80,
+ /*ae30:*/ 0xb5, 0xfc, 0xd7, 0xee, 0xed, 0x32, 0x73, 0xe3, 0x8e, 0x8f, 0x0e, 0x28, 0xa8, 0x20, 0x3a, 0xf7,
+ /*ae40:*/ 0xbc, 0xe2, 0x2b, 0x87, 0xce, 0x46, 0xb6, 0x75, 0xd8, 0x55, 0x9b, 0x32, 0xbd, 0x30, 0x94, 0x83,
+ /*ae50:*/ 0x39, 0xfb, 0x28, 0xc9, 0x23, 0xeb, 0x9a, 0x55, 0xc2, 0x40, 0xa6, 0x5a, 0x04, 0xad, 0xab, 0x00,
+ /*ae60:*/ 0xb3, 0x51, 0xbf, 0x07, 0x9e, 0xbd, 0x44, 0x76, 0x2f, 0x23, 0x26, 0x92, 0x57, 0xdc, 0x92, 0xe8,
+ /*ae70:*/ 0x50, 0x21, 0xbb, 0x03, 0x6c, 0x23, 0xa1, 0xb4, 0xbd, 0x48, 0x24, 0x8f, 0xfe, 0x9b, 0x3c, 0x67,
+ /*ae80:*/ 0x32, 0xaf, 0x9e, 0x9a, 0x64, 0x1d, 0xb7, 0xe1, 0x81, 0x76, 0x26, 0x33, 0x3d, 0x6d, 0xbf, 0x80,
+ /*ae90:*/ 0x14, 0x66, 0xef, 0x49, 0xca, 0x69, 0xe9, 0xdc, 0xb5, 0x4c, 0x94, 0xa8, 0x97, 0x27, 0x5e, 0x1d,
+ /*aea0:*/ 0x02, 0xe9, 0x8b, 0x07, 0x0e, 0xbb, 0xb4, 0x59, 0x28, 0x68, 0x61, 0xb5, 0x11, 0x23, 0xb4, 0xde,
+ /*aeb0:*/ 0x83, 0x0c, 0xbf, 0x91, 0xfd, 0xf2, 0x3a, 0x3a, 0xd7, 0xe4, 0xc6, 0x90, 0x95, 0x7d, 0x35, 0x8b,
+ /*aec0:*/ 0x1a, 0x42, 0xf4, 0xfc, 0x90, 0xe3, 0x1a, 0xe3, 0x5d, 0xd2, 0x0e, 0xcd, 0xbd, 0x18, 0x46, 0x20,
+ /*aed0:*/ 0x1b, 0x0f, 0x82, 0x79, 0xca, 0x8d, 0xac, 0x92, 0x8e, 0x7b, 0x81, 0xf9, 0xde, 0x7d, 0x9a, 0xa6,
+ /*aee0:*/ 0x95, 0x31, 0x49, 0x54, 0x28, 0x27, 0x22, 0x04, 0xdf, 0xf2, 0x1a, 0xb7, 0x7f, 0xf0, 0x94, 0x00,
+ /*aef0:*/ 0x25, 0x16, 0x5c, 0x2a, 0x36, 0x5b, 0xec, 0x7f, 0xd7, 0x79, 0x12, 0x6c, 0x25, 0x25, 0xa6, 0x5c,
+ /*af00:*/ 0x7c, 0xe8, 0x94, 0x0d, 0x7b, 0xe7, 0x8d, 0x57, 0x60, 0xaf, 0x88, 0xbc, 0xf1, 0x8b, 0xd8, 0x40,
+ /*af10:*/ 0x62, 0x77, 0xb1, 0xa7, 0x6b, 0xee, 0x26, 0xca, 0x6b, 0x33, 0xa0, 0x92, 0x28, 0x6d, 0x45, 0xf6,
+ /*af20:*/ 0x6d, 0xd5, 0x3a, 0x9c, 0x7c, 0xc1, 0x1c, 0xe2, 0x46, 0x00, 0x3c, 0xb8, 0x7b, 0xc7, 0x44, 0xd4,
+ /*af30:*/ 0xa8, 0x82, 0xab, 0x08, 0x11, 0x75, 0x29, 0x08, 0x99, 0xfb, 0x60, 0xed, 0x2b, 0x93, 0xa1, 0x4b,
+ /*af40:*/ 0x1d, 0x25, 0xee, 0xef, 0x64, 0xb5, 0x5d, 0xa8, 0x9f, 0xcf, 0x5b, 0xc7, 0x2d, 0x7c, 0x69, 0x66,
+ /*af50:*/ 0xc4, 0x64, 0x13, 0xd8, 0xad, 0x60, 0x57, 0x56, 0x18, 0x09, 0x72, 0x15, 0x43, 0x4c, 0x6b, 0x6d,
+ /*af60:*/ 0xc1, 0x24, 0x15, 0x4d, 0x7b, 0x0f, 0x8c, 0x46, 0x52, 0xff, 0x6c, 0xfa, 0x3d, 0xb0, 0xfd, 0x3a,
+ /*af70:*/ 0x72, 0x48, 0x5f, 0x88, 0x39, 0x72, 0x2a, 0x37, 0x1b, 0x95, 0x4e, 0x06, 0xa0, 0x9a, 0xdb, 0x1b,
+ /*af80:*/ 0x01, 0xcb, 0xc1, 0x98, 0x30, 0xaf, 0xfe, 0xb5, 0x2a, 0xaa, 0xc9, 0xed, 0x80, 0x9e, 0x43, 0xcb,
+ /*af90:*/ 0x63, 0x52, 0xf8, 0x63, 0xa0, 0x4d, 0x00, 0xa8, 0xc6, 0xf4, 0xfe, 0x47, 0xfc, 0x23, 0xc7, 0xba,
+ /*afa0:*/ 0x23, 0x81, 0x12, 0x13, 0xe3, 0xe7, 0xea, 0x47, 0xd3, 0x59, 0xb8, 0xcc, 0xb4, 0xb3, 0x8c, 0xcb,
+ /*afb0:*/ 0xc0, 0x0a, 0x8f, 0x34, 0xe4, 0xd8, 0x0e, 0x6f, 0x1e, 0x08, 0xc4, 0xc6, 0xb9, 0x98, 0x40, 0x16,
+ /*afc0:*/ 0x60, 0x1d, 0xc1, 0x8e, 0x43, 0xdf, 0xd1, 0x86, 0x04, 0x6e, 0x50, 0xc0, 0xe9, 0x99, 0x1d, 0x55,
+ /*afd0:*/ 0x9b, 0x2f, 0xdf, 0x0b, 0x6a, 0xcc, 0x9f, 0x54, 0xdf, 0x8a, 0x75, 0xaa, 0x3d, 0x7f, 0xf8, 0x49,
+ /*afe0:*/ 0x4b, 0x91, 0x58, 0x67, 0x32, 0x61, 0xae, 0x0a, 0x5c, 0x81, 0x05, 0x49, 0x2c, 0x90, 0x62, 0xdb,
+ /*aff0:*/ 0x79, 0x55, 0xa3, 0xb5, 0x6a, 0x74, 0x24, 0x81, 0x24, 0xa0, 0xcf, 0x14, 0xe3, 0x0a, 0xf0, 0xdd,
+ /*b000:*/ 0x23, 0x98, 0xfc, 0x13, 0x94, 0xe0, 0x73, 0xc2, 0x44, 0x25, 0x79, 0x88, 0x6c, 0xe8, 0xb4, 0x5e,
+ /*b010:*/ 0x57, 0xcf, 0xd3, 0x3b, 0xa1, 0x81, 0xbf, 0xa7, 0x96, 0xd3, 0x06, 0xfe, 0xa9, 0x4e, 0xe7, 0x0f,
+ /*b020:*/ 0x26, 0x4a, 0x73, 0x60, 0x4c, 0x95, 0x0e, 0xf3, 0x75, 0x29, 0x63, 0x50, 0x54, 0xbb, 0xc0, 0x88,
+ /*b030:*/ 0x55, 0x7e, 0xf0, 0x09, 0x14, 0x7a, 0xdb, 0x31, 0x76, 0xfa, 0x86, 0x28, 0xf2, 0x2a, 0x01, 0xcb,
+ /*b040:*/ 0x21, 0xa3, 0x39, 0xa1, 0x26, 0xb7, 0x5d, 0x54, 0xae, 0x2b, 0xe6, 0xd7, 0x7d, 0xb3, 0x8f, 0x8a,
+ /*b050:*/ 0x0e, 0x8e, 0x12, 0x31, 0x8e, 0x75, 0x7e, 0x66, 0xa0, 0xfe, 0x66, 0x90, 0xde, 0x47, 0x00, 0xa6,
+ /*b060:*/ 0x14, 0xa3, 0x49, 0xe7, 0xe3, 0xd0, 0xdc, 0x99, 0xbc, 0x64, 0xaf, 0xd7, 0xdc, 0x73, 0x36, 0x05,
+ /*b070:*/ 0x13, 0xd7, 0xac, 0xd5, 0x55, 0x6a, 0xda, 0xb0, 0x10, 0xe6, 0x6b, 0x17, 0xe9, 0xf1, 0x80, 0x19,
+ /*b080:*/ 0xcf, 0xfb, 0x15, 0x61, 0xf6, 0x3b, 0xa3, 0xc2, 0x21, 0x63, 0xe0, 0xb0, 0x89, 0xe4, 0xd2, 0xf8,
+ /*b090:*/ 0xc8, 0x14, 0x1a, 0xb5, 0xfa, 0x1f, 0x83, 0xd7, 0x9c, 0x5b, 0x3c, 0x5c, 0x28, 0x62, 0x5e, 0x56,
+ /*b0a0:*/ 0x7d, 0x17, 0x5f, 0x8e, 0xd3, 0x6c, 0x17, 0xa4, 0xd7, 0xde, 0xb8, 0xf3, 0xbb, 0x27, 0x45, 0x74,
+ /*b0b0:*/ 0x24, 0x50, 0x6a, 0x4c, 0xf0, 0xf6, 0xe6, 0x47, 0x23, 0x77, 0x41, 0x1c, 0xcc, 0x0b, 0x24, 0xe2,
+ /*b0c0:*/ 0x09, 0x99, 0x72, 0x69, 0x5f, 0x9b, 0x88, 0x45, 0x4b, 0x29, 0x79, 0x98, 0xb2, 0x51, 0xbf, 0x14,
+ /*b0d0:*/ 0x27, 0x74, 0xa9, 0x98, 0x98, 0x1d, 0x34, 0xd3, 0x1c, 0x86, 0xf5, 0x00, 0xa9, 0x46, 0x1e, 0xd9,
+ /*b0e0:*/ 0x76, 0x27, 0xe7, 0x05, 0x47, 0xe8, 0x2f, 0xe0, 0x75, 0x15, 0x79, 0x29, 0x6a, 0xca, 0xed, 0xf5,
+ /*b0f0:*/ 0xf9, 0xca, 0x2d, 0x1d, 0x92, 0x6f, 0xcb, 0xd4, 0xec, 0x9a, 0x79, 0xa4, 0x3a, 0xb6, 0x7b, 0x38,
+ /*b100:*/ 0x53, 0x59, 0x02, 0x02, 0x00, 0x3f, 0x03, 0x1e, 0x05, 0x0e, 0x89, 0x00, 0x01, 0x01, 0xff, 0x0a,
+ /*b110:*/ 0x1f, 0x03, 0xff, 0x04, 0x1e, 0x06, 0x2d, 0x72, 0x0f, 0x7b, 0x02, 0x01, 0x31, 0xff, 0x31, 0xff,
+ /*b120:*/ 0x78, 0x43, 0xfd, 0x43, 0x84, 0xe4, 0x6c, 0xe8, 0x00, 0x70, 0x20, 0x20, 0x20, 0x20, 0x0a, 0x04,
+ /*b130:*/ 0x0c, 0x32, 0x70, 0x17, 0x0a, 0x0a, 0x05, 0x80, 0x0c, 0x46, 0x00, 0x80, 0x0c, 0x5a, 0x00, 0x28,
+ /*b140:*/ 0x0a, 0x8c, 0x00, 0xb8, 0x0b, 0x96, 0x00, 0x1e, 0x1e, 0x64, 0x00, 0xf4, 0x01, 0x14, 0x0a, 0x04,
+ /*b150:*/ 0x29, 0x1a, 0x0a, 0x64, 0x03, 0x66, 0x64, 0xc0, 0x20, 0x02, 0x87, 0x00, 0x80, 0x02, 0x0e, 0x1f,
+ /*b160:*/ 0x01, 0x2a, 0x00, 0x20, 0x0a, 0x1b, 0x00, 0x80, 0x0a, 0xa8, 0xa0, 0x80, 0x88, 0x88, 0x88, 0x68,
+ /*b170:*/ 0x68, 0x2e, 0x2d, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x25, 0x01, 0x04, 0x07, 0x09, 0x0b, 0x0d, 0x0f,
+ /*b180:*/ 0x13, 0x00, 0xe8, 0x03, 0x00, 0x14, 0x00, 0xe8, 0x03, 0x9a, 0x64, 0xda, 0xb8, 0x0b, 0x00, 0xc0,
+ /*b190:*/ 0x80, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ /*b1a0:*/ 0x10, 0x5a, 0x5e, 0x61, 0x64, 0x67, 0x6a, 0x6d, 0x39, 0x00, 0x1e, 0x00, 0x10, 0x0a, 0x17, 0x00,
+ /*b1b0:*/ 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x30, 0x04, 0x20, 0x40, 0x03, 0x04, 0x03, 0x00,
+ /*b1c0:*/ 0x1d, 0x2b, 0x1d, 0x2c, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x78, 0x7d, 0x51, 0x51, 0x51, 0xcd,
+ /*b1d0:*/ 0x0d, 0x04, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+ /*b1e0:*/ 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c,
+ /*b1f0:*/ 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x29, 0x2a, 0x2b, 0x2c, 0xff, 0xff,
+ /*b200:*/ 0xff, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 0x14, 0x12, 0x10, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b,
+ /*b210:*/ 0x0a, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x1d, 0xff, 0xff, 0xff, 0x00,
+ /*b220:*/ 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /*b230:*/ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /*b240:*/ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ /*b250:*/ 0x80, 0x80, 0x80, 0x80, 0x80, 0x66, 0x66, 0x6d, 0x6d, 0x73, 0x73, 0x7a, 0x7a, 0x80, 0x80, 0x86,
+ /*b260:*/ 0x86, 0x8d, 0x8d, 0x93, 0x93, 0x9a, 0x9a, 0xa0, 0xa0, 0xa6, 0xa6, 0xad, 0xad, 0xb3, 0xb3, 0x80,
+ /*b270:*/ 0x80, 0x80, 0x80, 0x04, 0x02, 0xff, 0x08, 0xff, 0xff, 0x03, 0x1c, 0x43, 0x80, 0x08, 0x10, 0x0a,
+ /*b280:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b290:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b2f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x5d, 0xdc, 0x9d,
+ /*b300:*/ 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b310:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b320:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b330:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b340:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b350:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b360:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b370:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b380:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b390:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b3f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b400:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b410:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b420:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b430:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b440:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b450:*/ 0x04, 0x3f, 0x03, 0x1e, 0x05, 0x0e, 0x08, 0x00, 0x19, 0x19, 0x00, 0x10, 0xe2, 0x04, 0xb6, 0x08,
+ /*b460:*/ 0x1e, 0x05, 0x28, 0xf5, 0x28, 0x1e, 0x05, 0x01, 0x30, 0x00, 0x30, 0x00, 0x00, 0x50, 0x00, 0x50,
+ /*b470:*/ 0xf0, 0xd2, 0xf0, 0xd2, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x04, 0xc0, 0x0f, 0x49, 0x00,
+ /*b480:*/ 0x00, 0x00, 0x85, 0x03, 0x2e, 0x1e, 0x0a, 0x64, 0x07, 0x00, 0x00, 0x56, 0x35, 0x05, 0x10, 0x00,
+ /*b490:*/ 0x00, 0x0b, 0x20, 0x00, 0x01, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
+ /*b4a0:*/ 0x37, 0x33, 0x30, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x03, 0x0f, 0x00, 0x03, 0x00, 0x00,
+ /*b4b0:*/ 0x00, 0xf0, 0x15, 0x1e, 0x2e, 0x4c, 0x40, 0xff, 0x4b, 0x20, 0x0c, 0x18, 0x09, 0x04, 0x00, 0x00,
+ /*b4c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b4d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x8a, 0x56,
+ /*b4e0:*/ 0x15, 0x21, 0x11, 0x94, 0x89, 0x50, 0x13, 0x01, 0x01, 0x8b, 0x00, 0x4c, 0x00, 0x01, 0x34, 0x00,
+ /*b4f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b500:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x5e, 0x01, 0x80,
+ /*b510:*/ 0x03, 0x0e, 0x1f, 0x00, 0xde, 0x01, 0x19, 0x04, 0x1b, 0x00, 0x10, 0x0a, 0xc0, 0x00, 0x00, 0x00,
+ /*b520:*/ 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b530:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff,
+ /*b540:*/ 0xff, 0x00, 0xc0, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+ /*b550:*/ 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x10,
+ /*b560:*/ 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x04, 0x40, 0x40, 0x03,
+ /*b570:*/ 0x00, 0x2e, 0x1e, 0x44, 0x00, 0x19, 0x01, 0x01, 0xbe, 0x00, 0xde, 0x3d, 0x90, 0x80, 0x08, 0x03,
+ /*b580:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b590:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b5e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x70, 0x0b, 0x00, 0x01, 0x54, 0x00,
+ /*b5f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b600:*/ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x51, 0x51,
+ /*b610:*/ 0x51, 0x51, 0x51, 0xcd, 0x0d, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x04, 0xff, 0x2e,
+ /*b620:*/ 0x1e, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b630:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b640:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b650:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b660:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b670:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b680:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b690:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b6e0:*/ 0x00, 0x00, 0x00, 0x1f, 0x1c, 0x16, 0x00, 0x01, 0x55, 0x1d, 0x00, 0x01, 0x00, 0x01, 0x1a, 0x00,
+ /*b6f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b700:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b710:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b720:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0xff, 0xff, 0x03, 0x32,
+ /*b730:*/ 0x00, 0x80, 0x08, 0x10, 0x0a, 0x04, 0x28, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b740:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b750:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b760:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b770:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b780:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b790:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7a0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7b0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7c0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7d0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b7e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x28, 0x00, 0x00, 0x51, 0x00,
+ /*b7f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ /*b800:*/ 0xff};
+#else
const char *rmi_config_ver = "N80XX_SY_0518";
const u8 rmi_fw[] = {
@@ -2917,4 +11765,5 @@ const u8 rmi_fw[] = {
/*b5e0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xb4, 0x0b, 0x00, 0x01, 0x54, 0x00,
/*b5f0:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/*b600:*/ 0xff};
-#endif /* __RMI_FW_H */ \ No newline at end of file
+ #endif
+ #endif /* __RMI_FW_H */
diff --git a/drivers/input/touchscreen/synaptics_fw_updater.c b/drivers/input/touchscreen/synaptics_fw_updater.c
index 1a15fdc..2b8293f 100644
--- a/drivers/input/touchscreen/synaptics_fw_updater.c
+++ b/drivers/input/touchscreen/synaptics_fw_updater.c
@@ -399,39 +399,79 @@ int synaptics_fw_updater(struct synaptics_drv_data *data, u8 *fw_data)
{
struct synaptics_ts_fw_block *fw;
int irq = gpio_to_irq(data->gpio);
- bool update = true;
+ bool update = false;
fw = kzalloc(sizeof(struct synaptics_ts_fw_block), GFP_KERNEL);
data->fw = fw;
if (NULL == fw_data) {
- u8 *buf, *fw_version;
- buf = kzalloc(4, GFP_KERNEL);
- fw_version = kzalloc(4, GFP_KERNEL);
+ u8 buf[5] = {0, };
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ if (data->pdata->support_extend_button) {
+ fw->fw_data = (u8 *)rmi_fw_button;
+
+ /* set firmware data */
+ data->firm_version[0] = rmi_fw_button[0xb100];
+ data->firm_version[1] = rmi_fw_button[0xb101];
+ data->firm_version[2] = rmi_fw_button[0xb102];
+ data->firm_version[3] = rmi_fw_button[0xb103];
+ data->firm_version[4] = '\0';
+
+ strncpy(data->firm_config, rmi_config_ver_button,
+ sizeof(data->firm_config));
+ } else {
+ fw->fw_data = (u8 *)rmi_fw;
+
+ data->firm_version[0] = rmi_fw[0xb100];
+ data->firm_version[1] = rmi_fw[0xb101];
+ data->firm_version[2] = rmi_fw[0xb102];
+ data->firm_version[3] = rmi_fw[0xb103];
+ data->firm_version[4] = '\0';
+
+ strncpy(data->firm_config, rmi_config_ver,
+ sizeof(data->firm_config));
+ }
+#else
fw->fw_data = (u8 *)rmi_fw;
- strncpy(fw_version, &rmi_fw[0xb100],
- sizeof(fw_version));
- strncpy(data->firm_version, fw_version,
- sizeof(data->firm_version));
+
+ data->firm_version[0] = rmi_fw[0xb100];
+ data->firm_version[1] = rmi_fw[0xb101];
+ data->firm_version[2] = rmi_fw[0xb102];
+ data->firm_version[3] = rmi_fw[0xb103];
+ data->firm_version[4] = '\0';
+
strncpy(data->firm_config, rmi_config_ver,
sizeof(data->firm_config));
- synaptics_ts_read_block(data,
+#endif
+ if (synaptics_ts_read_block(data,
data->f34.control_base_addr,
- buf, 4);
-
- printk(KERN_DEBUG "[TSP] IC FW. : [%s], new FW. : [%s]\n",
- buf, fw_version);
-
- if (strncmp((char *)fw_version, (char *)buf, 4) == 0)
- update = false;
-
- kfree(buf);
- kfree(fw_version);
-
- } else
+ buf, 4) > 0)
+ printk(KERN_DEBUG "[TSP] block read success!\n");
+ else
+ printk(KERN_DEBUG "[TSP] block read failed!\n");
+
+ printk(KERN_DEBUG "[TSP] IC FW. : [%c%c%.2d%.2d00], new FW. : [%c%c%.2d%.2d00]\n",
+ buf[0],buf[1],buf[2],buf[3],
+ data->firm_version[0],data->firm_version[1],
+ data->firm_version[2],data->firm_version[3]);
+
+ /* update firm > tsp */
+ /*
+ if (strcmp(data->firm_version, buf) > 0) {
+ printk(KERN_DEBUG "[TSP] update!\n");
+ update = true;
+ }
+ */
+ /* update if firm != tsp */
+ if (strncmp(data->firm_version, buf, 4) != 0)
+ update = true;
+ } else {
fw->fw_data = fw_data;
-
+ update = true;
+ }
+
if (update) {
+ printk(KERN_DEBUG "[TSP] tsp update!!\n");
disable_irq(irq);
wake_lock(&data->wakelock);
synaptics_fw_initialize(data);
@@ -463,6 +503,13 @@ int synaptics_fw_updater(struct synaptics_drv_data *data, u8 *fw_data)
void forced_fw_update(struct synaptics_drv_data *data)
{
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ if (data->pdata->support_extend_button)
+ synaptics_fw_updater(data, (u8 *)rmi_fw_button);
+ else
+ synaptics_fw_updater(data, (u8 *)rmi_fw);
+#else
synaptics_fw_updater(data, (u8 *)rmi_fw);
+#endif
}
diff --git a/drivers/input/touchscreen/synaptics_s7301.c b/drivers/input/touchscreen/synaptics_s7301.c
index bd2bf8f..34d42e7 100644
--- a/drivers/input/touchscreen/synaptics_s7301.c
+++ b/drivers/input/touchscreen/synaptics_s7301.c
@@ -15,6 +15,14 @@
#include <linux/synaptics_s7301.h>
+#define REPORT_MT_NOZ(x, y, w_max, w_min) \
+do { \
+ input_report_abs(data->input, ABS_MT_POSITION_X, x); \
+ input_report_abs(data->input, ABS_MT_POSITION_Y, y); \
+ input_report_abs(data->input, ABS_MT_TOUCH_MAJOR, w_max); \
+ input_report_abs(data->input, ABS_MT_TOUCH_MINOR, w_min); \
+} while (0)
+
#define REPORT_MT(x, y, z, w_max, w_min) \
do { \
input_report_abs(data->input, ABS_MT_POSITION_X, x); \
@@ -185,6 +193,29 @@ void set_dvfs_lock(struct synaptics_drv_data *data, bool en)
}
#endif /* CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK */
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+static void forced_release_buttons(struct synaptics_drv_data *data)
+{
+ int i;
+#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
+ printk(KERN_DEBUG "[TSP] %s\n", __func__);
+#endif
+ if (data->pdata->support_extend_button) {
+ for (i = 0; i < data->pdata->extend_button_map->nbuttons; i++) {
+ input_report_key(data->input,
+ data->pdata->extend_button_map->map[i],
+ 0);
+ }
+ } else {
+ for (i = 0; i < data->pdata->button_map->nbuttons; i++) {
+ input_report_key(data->input,
+ data->pdata->button_map->map[i], 0);
+ }
+ }
+ input_sync(data->input);
+}
+#endif
+
static void forced_release_fingers(struct synaptics_drv_data *data)
{
int i;
@@ -200,6 +231,9 @@ static void forced_release_fingers(struct synaptics_drv_data *data)
data->finger[i].z = 0;
}
input_sync(data->input);
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ forced_release_buttons(data);
+#endif
set_dvfs_lock(data, false);
return ;
}
@@ -212,9 +246,9 @@ static int synaptics_ts_set_func_info(struct synaptics_drv_data *data)
u16 base_addr = FUNC_ADDR_FIRST;
u16 last_addr = FUNC_ADDR_LAST;
- for (i = 0; i <= PAGE_MAX; i += PAGE_MAX) {
- base_addr += i;
- last_addr += i;
+ for (i = 0; i <= PAGE_MAX; i += NEXT_PAGE) {
+ base_addr = i + FUNC_ADDR_FIRST;
+ last_addr = i + FUNC_ADDR_LAST;
for (addr = base_addr; addr >= last_addr;
addr -= FUNC_ADDR_SIZE) {
synaptics_ts_read_block(data,
@@ -245,6 +279,12 @@ static int synaptics_ts_set_func_info(struct synaptics_drv_data *data)
SET_FUNC_ADDR(11, i);
break;
+#if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ case 0x1a:
+ SET_FUNC_ADDR(1a, i);
+ break;
+#endif
+
case 0x34:
SET_FUNC_ADDR(34, i);
break;
@@ -253,12 +293,26 @@ static int synaptics_ts_set_func_info(struct synaptics_drv_data *data)
SET_FUNC_ADDR(54, i);
break;
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ case 0x51:
+ SET_FUNC_ADDR(51, i);
+ break;
+#endif
+
default:
break;
}
}
}
- return cnt;
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ cnt--;
+#endif
+
+#if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ return (5 != cnt);
+#else
+ return (4 != cnt);
+#endif
}
static int synaptics_ts_read_dummy(struct synaptics_drv_data *data)
@@ -314,17 +368,43 @@ static void inform_charger_connection(struct charger_callbacks *cb, int mode)
struct synaptics_drv_data, callbacks);
data->charger_connection = !!mode;
- if (data->ready)
+ if (data->ready) {
+#if !defined(CONFIG_MACH_KONA)
set_charger_connection_bit(data);
+#endif
+ }
}
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+static void set_palm_threshold(struct synaptics_drv_data *data)
+{
+ u8 threshold = data->pdata->palm_threshold;
+
+ synaptics_ts_write_data(data,
+ data->f11.control_base_addr + 17, threshold);
+}
+#endif
+
static int synaptics_ts_set_func(struct synaptics_drv_data *data)
{
int i = 0;
-
+ int retry_count = 10;
+ int ret = 0;
+
printk(KERN_DEBUG "[TSP] %s\n", __func__);
-
- if (synaptics_ts_set_func_info(data) != 4) {
+
+ while(retry_count--) {
+ ret = synaptics_ts_set_func_info(data);
+
+ if (ret) {
+ pr_err("[TSP] failed to get function info retry_count = %d \n",retry_count);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ if (ret) {
pr_err("[TSP] failed to get function info.\n");
forced_fw_update(data);
synaptics_ts_set_func_info(data);
@@ -340,40 +420,159 @@ static int synaptics_ts_set_func(struct synaptics_drv_data *data)
return synaptics_ts_read_dummy(data);
}
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+static void synaptics_ts_check_buttons(struct synaptics_drv_data *data)
+{
+ int ret = 0, i, pos_button = 1;
+ u16 touch_key_addr = data->f1a.data_base_addr;
+ u8 touch_key_data;
+ u8 check_mask_data;
+
+ ret = synaptics_ts_read_block(data,
+ touch_key_addr, &touch_key_data, 1);
+
+ if (ret < 0) {
+ pr_err("[TSP] failed to read button data\n");
+ return ;
+ }
+
+#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
+ printk(KERN_DEBUG "[TSP] button [0x%x]\n", touch_key_data);
+#endif
+
+ if (data->pdata->support_extend_button) {
+ if (data->pdata->enable_extend_button_event) {
+ for (i = 0; i < data->pdata->extend_button_map->nbuttons; i++) {
+ if ((touch_key_data & (pos_button<<i)) != 0) {
+ input_report_key(data->input,
+ data->pdata->extend_button_map->map[i],
+ 1);
+ } else {
+ input_report_key(data->input,
+ data->pdata->extend_button_map->map[i],
+ 0);
+ }
+ input_sync(data->input);
+ }
+ } else {
+ /* check mask data and return */
+ check_mask_data = touch_key_data &
+ data->pdata->extend_button_map->button_mask;
+
+ if (check_mask_data != 0) {
+ printk(KERN_DEBUG "[TSP] igb\n");
+ return;
+ }
+
+ for (i = 0; i < data->pdata->extend_button_map->nbuttons; i++) {
+ if ((data->pdata->extend_button_map->button_mask & (pos_button<<i)) !=0)
+ continue;
+
+ if ((touch_key_data & (pos_button<<i)) != 0) {
+ input_report_key(data->input,
+ data->pdata->extend_button_map->map[i],
+ 1);
+ printk(KERN_DEBUG "[TSP] b[%d][%c]\n", i, 'p');
+ } else {
+ input_report_key(data->input,
+ data->pdata->extend_button_map->map[i],
+ 0);
+ printk(KERN_DEBUG "[TSP] b[%d][%c]\n", i, 'r');
+ }
+ input_sync(data->input);
+ }
+ }
+ } else {
+ for (i = 0; i < data->pdata->button_map->nbuttons; i++) {
+ if ((touch_key_data & (pos_button<<i)) != 0)
+ input_report_key(data->input,
+ data->pdata->button_map->map[i], 1);
+ else
+ input_report_key(data->input,
+ data->pdata->button_map->map[i], 0);
+ input_sync(data->input);
+ }
+ }
+}
+#endif
+
static int check_interrupt_status(struct synaptics_drv_data *data,
u32 *finger_status)
{
int ret = 0;
u8 buf[3];
+ u8 tmp;
u16 addr = 0;
+ int analog_int = 0;
/* read the interrupt status */
addr = data->f01.data_base_addr + 1;
ret = synaptics_ts_read_data(data,
- addr, buf);
+ addr, &tmp);
if (ret < 0) {
pr_err("[TSP] failed to read i2c data(%d)\n", __LINE__);
return -EIO;
}
- /* read the finger states */
- addr = data->f11.data_base_addr;
- ret = synaptics_ts_read_block(data,
- addr, buf, 3);
- if (ret < 0) {
- pr_err("[TSP] failed to read i2c data(%d)\n", __LINE__);
- return -EIO;
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ /* check button */
+ if ((tmp & 0x10) != 0) {
+ synaptics_ts_check_buttons(data);
}
+#endif
- *finger_status = (u32) (buf[0] | (buf[1] << 8) |
- ((buf[2] & 0xf) << 16));
+ /* check analog interrupt */
+ if (tmp & 0x4)
+ analog_int = 1;
- if (data->debug)
- printk(KERN_DEBUG
- "[TSP] finger_status : 0x%x\n",
- *finger_status);
+#if defined(CONFIG_MACH_KONA)
+ /* check interrupt status register */
+ if ((tmp & 0x0F) == 0x2) {
+ addr = data->f01.data_base_addr;
+ /* check esd status register */
+ ret = synaptics_ts_read_data(data,
+ addr, &tmp);
+ if (ret < 0) {
+ pr_err("[TSP] failed to read i2c data(%d)\n", __LINE__);
+ return -EIO;
+ } else if ((tmp & 0x3) == 0x3) {
+ pr_err("[TSP] esd detect\n");
+ forced_release_fingers(data);
+ data->pdata->hw_reset();
+ return 0;
+ }
+ }
+#else
+ /* esd detect */
+ if ((tmp & 0x0F) == 0x03) {
+ pr_err("[TSP] esd detect\n");
+ data->pdata->hw_reset();
+ return 0;
+ }
+#endif
- return 0;
+ if (analog_int) {
+ /* read the finger states */
+ addr = data->f11.data_base_addr;
+ ret = synaptics_ts_read_block(data,
+ addr, buf, 3);
+ if (ret < 0) {
+ pr_err("[TSP] failed to read i2c data(%d)\n", __LINE__);
+ return -EIO;
+ }
+
+ *finger_status = (u32) (buf[0] | (buf[1] << 8) |
+ ((buf[2] & 0xf) << 16));
+
+ if (data->debug)
+ printk(KERN_DEBUG
+ "[TSP] finger_status : [%d] 0x%x\n", analog_int,
+ *finger_status);
+ }
+ if (analog_int == 1)
+ return 1;
+ else
+ return 0;
}
static void synaptics_ts_read_points(struct synaptics_drv_data *data,
@@ -383,10 +582,33 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
bool finger_pressed = false;
int ret = 0;
int id = 0;
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ u8 palm;
+ u8 surface_data[4];
+ u16 palm_addr = data->f11.data_base_addr + 53;
+ u16 surface_addr = data->f51.data_base_addr;
+ int angle = 0;
+#endif
u16 addr = data->f11.data_base_addr + 3;
+ u16 x = 0, y = 0;
+
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ ret = synaptics_ts_read_block(data,
+ palm_addr, &palm, 1);
+ if (ret < 0) {
+ pr_err("[TSP] failed to read palm data\n");
+ return ;
+ }
+
+ palm = (palm & 0x02) ? 1 : 0;
+#endif
for (id = 0; id < MAX_TOUCH_NUM; id++,
addr += sizeof(struct finger_data)) {
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND)
+ if ((finger_status & (0x3 << (id * 2))) == 0x3)
+ continue;
+#endif
if (finger_status & (0x3 << (id * 2))) {
ret = synaptics_ts_read_block(data,
addr, (u8 *) &buf, 5);
@@ -394,6 +616,15 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
pr_err("[TSP] failed to read finger[%u]\n", id);
return ;
}
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ ret = synaptics_ts_read_block(data,
+ surface_addr + (id * 4),
+ surface_data, 4);
+ if (ret < 0) {
+ pr_err("[TSP] failed to read surface data\n");
+ return ;
+ }
+#endif
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
if (data->debug)
@@ -405,13 +636,47 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
buf.z);
#endif
- data->finger[id].x =
- (buf.x_msb << 4) +
- (buf.xy_lsb & 0x0F);
- data->finger[id].y =
- (buf.y_msb << 4) +
- (buf.xy_lsb >> 4);
+ x = (buf.x_msb << 4) + (buf.xy_lsb & 0x0F);
+ y = (buf.y_msb << 4) + (buf.xy_lsb >> 4);
+
+ if (data->pdata->swap_xy)
+ swap(x, y);
+ if (data->pdata->invert_x)
+ x = data->pdata->max_x - x;
+
+ if (data->pdata->invert_y)
+ y = data->pdata->max_y - y;
+
+ data->finger[id].x = x;
+ data->finger[id].y = y;
+
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ data->finger[id].w_max = surface_data[2];
+ data->finger[id].w_min = surface_data[3];
+ if (data->pdata->support_extend_button) {
+ if (surface_data[1] >= 90 && surface_data[1] <= 180)
+ angle = surface_data[1] - 90;
+ else if (surface_data[1] < 90)
+ angle = -(90 - surface_data[1]);
+ else
+ printk(KERN_DEBUG "[TSP] wrong TSP angle data [%d][%d]\n", id,
+ surface_data[1]);
+ } else {
+ if (surface_data[1] <= 90)
+ angle = surface_data[1];
+ else if (surface_data[1] > 168 && surface_data[1] < 256)
+ angle = -(256 - surface_data[1]);
+ else
+ printk(KERN_DEBUG "[TSP] wrong TSP angle data [%d][%d]\n", id,
+ surface_data[1]);
+ }
+
+ if (data->finger[id].w_max <
+ data->finger[id].w_min)
+ swap(data->finger[id].w_max,
+ data->finger[id].w_min);
+#else
if ((buf.w >> 4) >
(buf.w & 0x0F)) {
data->finger[id].w_max =
@@ -424,7 +689,12 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
data->finger[id].w_max =
(buf.w & 0x0F);
}
-
+#endif
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ data->finger[id].angle = angle;
+ data->finger[id].width = surface_data[0];
+#endif
+
data->finger[id].z = buf.z;
if (data->finger[id].z) {
if (MT_STATUS_INACTIVE ==
@@ -438,19 +708,35 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
data->finger[id].x,
data->finger[id].y,
data->finger[id].z);
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ printk(KERN_DEBUG
+ "[TSP] palm %d, surface_data %d, %d\n",
+ palm,
+ surface_data[0],
+ surface_data[1]);
+#endif
#else
printk(KERN_DEBUG
"s7301 %d P\n", id);
#endif
}
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
- else if (data->debug)
+ else if (data->debug) {
printk(KERN_DEBUG
"[TSP] ID: %d, x: %d, y: %d, z: %d\n",
id,
data->finger[id].x,
data->finger[id].y,
data->finger[id].z);
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ printk(KERN_DEBUG
+ "[TSP] palm %d, surface_data %d, %d, %d\n",
+ palm,
+ surface_data[0],
+ surface_data[1],
+ angle);
+#endif
+ }
#endif
}
} else if (MT_STATUS_PRESS == data->finger[id].status) {
@@ -464,7 +750,29 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
}
}
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ if (palm) {
+ if (data->palm_flag == 3)
+ data->palm_flag = 1;
+ else {
+ data->palm_flag = 3;
+ palm = 3;
+ }
+ } else {
+ if (data->palm_flag == 2)
+ data->palm_flag = 0;
+ else {
+ data->palm_flag = 2;
+ palm = 2;
+ }
+ }
+#endif
+
for (id = 0; id < MAX_TOUCH_NUM; ++id) {
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND)
+ if ((finger_status & (0x3 << (id * 2))) == 0x3)
+ continue;
+#endif
if (MT_STATUS_INACTIVE == data->finger[id].status)
continue;
@@ -477,12 +785,30 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
case MT_STATUS_PRESS:
case MT_STATUS_MOVE:
finger_pressed = true;
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND)
+ if (0 == !!data->finger[id].z)
+ break;
+
+ REPORT_MT_NOZ(
+ data->finger[id].x,
+ data->finger[id].y,
+ data->finger[id].w_max,
+ data->finger[id].w_min);
+#else
REPORT_MT(
data->finger[id].x,
data->finger[id].y,
data->finger[id].z,
data->finger[id].w_max,
data->finger[id].w_min);
+#endif
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ input_report_abs(data->input, ABS_MT_WIDTH_MAJOR,
+ data->finger[id].width);
+ input_report_abs(data->input, ABS_MT_ANGLE,
+ data->finger[id].angle);
+ input_report_abs(data->input, ABS_MT_PALM, palm);
+#endif
break;
case MT_STATUS_RELEASE:
@@ -496,11 +822,17 @@ static void synaptics_ts_read_points(struct synaptics_drv_data *data,
set_dvfs_lock(data, finger_pressed);
}
+#if 0
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ synaptics_ts_check_buttons(data);
+#endif
+#endif
+
static irqreturn_t synaptics_ts_irq_handler(int irq, void *_data)
{
struct synaptics_drv_data *data = (struct synaptics_drv_data *)_data;
u32 finger_status = 0;
- if (!check_interrupt_status(data, &finger_status))
+ if (check_interrupt_status(data, &finger_status) == 1)
synaptics_ts_read_points(data, finger_status);
return IRQ_HANDLED;
}
@@ -510,6 +842,13 @@ static void synaptics_ts_early_suspend(struct early_suspend *h)
{
struct synaptics_drv_data *data =
container_of(h, struct synaptics_drv_data, early_suspend);
+#if defined(CONFIG_MACH_KONA)
+ disable_irq(data->client->irq);
+ forced_release_fingers(data);
+ if (!wake_lock_active(&data->wakelock)) {
+ data->pdata->set_power(0);
+ }
+#else
printk(KERN_DEBUG "[TSP] %s\n", __func__);
cancel_delayed_work_sync(&data->resume_dwork);
mutex_lock(&data->mutex);
@@ -522,6 +861,7 @@ static void synaptics_ts_early_suspend(struct early_suspend *h)
}
}
mutex_unlock(&data->mutex);
+#endif
}
static void synaptics_ts_late_resume(struct early_suspend *h)
@@ -531,11 +871,20 @@ static void synaptics_ts_late_resume(struct early_suspend *h)
printk(KERN_DEBUG "[TSP] %s\n", __func__);
+#if defined(CONFIG_MACH_KONA)
+ /* turned on tsp power */
+ data->pdata->set_power(1);
+
+ mdelay(200);
+ enable_irq(data->client->irq);
+#else
if (data->suspend) {
if (data->pdata->set_power(1))
data->pdata->hw_reset();
}
+
schedule_delayed_work(&data->resume_dwork, HZ / 10);
+#endif
}
#endif
@@ -572,7 +921,12 @@ static void init_function_data_dwork(struct work_struct *work)
#endif
data->ready = true;
+#if !defined(CONFIG_MACH_KONA)
set_charger_connection_bit(data);
+#endif
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ set_palm_threshold(data);
+#endif
if (data->client->irq) {
ret = request_threaded_irq(data->client->irq, NULL,
@@ -602,8 +956,10 @@ static void synaptics_ts_resume_dwork(struct work_struct *work)
mutex_lock(&data->mutex);
if (data->suspend) {
data->suspend = false;
+#if !defined(CONFIG_MACH_KONA)
set_charger_connection_bit(data);
synaptics_ts_drawing_mode(data);
+#endif
synaptics_ts_read_dummy(data);
enable_irq(data->client->irq);
}
@@ -619,6 +975,19 @@ static void synaptics_ts_noti_dwork(struct work_struct *work)
set_charger_connection_bit(data);
}
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND)
+static void synaptics_reset_ts_dwork(struct work_struct *work)
+{
+ struct synaptics_drv_data *data =
+ container_of(work, struct synaptics_drv_data,
+ reset_dwork.work);
+
+ if (data->firmware_update_check != true) {
+ data->pdata->hw_reset();
+ }
+}
+#endif
+
static int synaptics_ts_open(struct input_dev *dev)
{
struct synaptics_drv_data *data =
@@ -671,6 +1040,11 @@ static int __init synaptics_ts_probe(struct i2c_client *client,
ddata->gpio = pdata->gpio_attn;
ddata->x_line = pdata->x_line;
ddata->y_line = pdata->y_line;
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ ddata->palm_flag = 0;
+#endif
+ if (pdata->swap_xy)
+ swap(pdata->x_line, pdata->y_line);
/* Register callbacks */
/* To inform tsp , charger connection status*/
@@ -703,17 +1077,51 @@ static int __init synaptics_ts_probe(struct i2c_client *client,
__set_bit(MT_TOOL_FINGER, input->keybit);
__set_bit(INPUT_PROP_DIRECT, input->propbit);
+ atomic_set(&ddata->keypad_enable, 1);
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+ if (pdata->led_event && atomic_read(&ddata->keypad_enable)) {
+ __set_bit(EV_LED, input->evbit);
+ __set_bit(LED_MISC, input->ledbit);
+ }
+#endif
+
input_mt_init_slots(input, MAX_TOUCH_NUM);
input_set_abs_params(input, ABS_MT_POSITION_X, 0,
pdata->max_x, 0, 0);
input_set_abs_params(input, ABS_MT_POSITION_Y, 0,
pdata->max_y, 0, 0);
+#if !defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND)
input_set_abs_params(input, ABS_MT_PRESSURE, 0,
- pdata->max_pressure, 0, 0);
+ pdata->max_pressure, 0, 0);
+#endif
input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0,
pdata->max_width, 0, 0);
input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0,
pdata->max_width, 0, 0);
+#if defined(CONFIG_SEC_TOUCHSCREEN_SURFACE_TOUCH)
+ input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0,
+ pdata->x_line * pdata->y_line, 0, 0);
+ input_set_abs_params(input, ABS_MT_ANGLE,
+ MIN_ANGLE, MAX_ANGLE, 0, 0);
+ input_set_abs_params(input, ABS_MT_PALM,
+ 0, 1, 0, 0);
+#endif
+#if defined (CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ if(atomic_read(&ddata->keypad_enable)){
+ if (pdata->support_extend_button) {
+ for (ret = 0; ret < pdata->extend_button_map->nbuttons; ret++) {
+ if (pdata->extend_button_map->map[ret] != KEY_RESERVED)
+ input_set_capability(input, EV_KEY,
+ pdata->extend_button_map->map[ret]);
+ }
+ } else {
+ for (ret = 0; ret < pdata->button_map->nbuttons; ret++)
+ input_set_capability(input, EV_KEY,
+ pdata->button_map->map[ret]);
+ }
+ }
+#endif
ret = input_register_device(input);
if (ret) {
@@ -727,8 +1135,16 @@ static int __init synaptics_ts_probe(struct i2c_client *client,
INIT_DELAYED_WORK(&ddata->init_dwork, init_function_data_dwork);
INIT_DELAYED_WORK(&ddata->resume_dwork, synaptics_ts_resume_dwork);
+#if !defined(CONFIG_MACH_KONA)
INIT_DELAYED_WORK(&ddata->noti_dwork, synaptics_ts_noti_dwork);
+#endif
schedule_delayed_work(&ddata->init_dwork, HZ);
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_WORKAROUND)
+ pdata->hw_reset();
+// INIT_DELAYED_WORK(&ddata->reset_dwork, synaptics_reset_ts_dwork);
+// schedule_delayed_work(&ddata->reset_dwork, HZ*10);
+#endif
ret = set_tsp_sysfs(ddata);
if (ret) {
diff --git a/drivers/input/touchscreen/synaptics_sysfs.c b/drivers/input/touchscreen/synaptics_sysfs.c
index 510bc98..840a362 100644
--- a/drivers/input/touchscreen/synaptics_sysfs.c
+++ b/drivers/input/touchscreen/synaptics_sysfs.c
@@ -18,6 +18,10 @@
#include <linux/synaptics_s7301.h>
#include "synaptics_sysfs.h"
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+struct device *synaptics_with_gpio_led_device;
+#endif
+
const char *sec_sysfs_cmd_list[] = {
"fw_update",
"get_fw_ver_bin",
@@ -50,7 +54,11 @@ static int synaptics_ts_load_fw(struct synaptics_drv_data *data)
old_fs = get_fs();
set_fs(KERNEL_DS);
+#if defined(CONFIG_MACH_KONA)
+ fp = filp_open(SYNAPTICS_FW2, O_RDONLY, S_IRUSR);
+#else
fp = filp_open(SYNAPTICS_FW, O_RDONLY, S_IRUSR);
+#endif
if (IS_ERR(fp)) {
printk(KERN_ERR "[TSP] failed to open %s.\n", SYNAPTICS_FW);
error = -ENOENT;
@@ -63,8 +71,14 @@ static int synaptics_ts_load_fw(struct synaptics_drv_data *data)
fw_data = kzalloc(fw_size, GFP_KERNEL);
nread = vfs_read(fp, (char __user *)fw_data,
fw_size, &fp->f_pos);
+#if defined(CONFIG_MACH_KONA)
+ printk(KERN_DEBUG "[TSP] start, file path %s, size %u Bytes\n",
+ SYNAPTICS_FW2, fw_size);
+#else
printk(KERN_DEBUG "[TSP] start, file path %s, size %u Bytes\n",
SYNAPTICS_FW, fw_size);
+#endif
+
if (nread != fw_size) {
printk(KERN_ERR
"[TSP] failed to read firmware file, nread %u Bytes\n",
@@ -142,9 +156,69 @@ static void soft_reset(struct synaptics_drv_data *data)
static void check_all_raw_cap(struct synaptics_drv_data *data)
{
- int i;
+ int i, j, k=0;
u16 temp = 0;
- u16 length = data->x_line * data->y_line * 2;
+ u16 length;
+
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ u8 escape_rx_line;
+
+ if (data->pdata->support_extend_button)
+ escape_rx_line = data->pdata->extend_button_map->nbuttons;
+ else
+ escape_rx_line = data->pdata->button_map->nbuttons;
+
+ length = data->x_line * (data->y_line + escape_rx_line) * 2;
+
+ if (NULL == data->references)
+ data->references = kzalloc(length, GFP_KERNEL);
+
+ data->refer_min = 0xffff;
+ data->refer_max = 0x0;
+
+ /* set the index */
+ set_report_index(data, 0x0000);
+
+ /* Set the GetReport bit to run the AutoScan */
+ set_report_mode(data, 0x01, 0x00);
+
+ /* read all report data */
+ synaptics_ts_read_block(data,
+ data->f54.data_base_addr + 3,
+ data->references, length);
+
+ for (i = 0; i < data->x_line; i++) {
+ for (j = 0; j < data->y_line + escape_rx_line; j++) {
+ temp = (u16)(data->references[k] |
+ (data->references[k+1] << 8));
+
+ if (k != 0 && j !=0) {
+ if (j >= data->y_line) {
+ if (data->debug) {
+ printk(KERN_DEBUG
+ "[TSP][skip] raw cap[%d] : %u\n",
+ k, temp);
+ }
+ k += 2;
+ continue;
+ }
+ }
+ if (data->debug) {
+ if (data->debug) {
+ printk(KERN_DEBUG
+ "[TSP] raw cap[%d] : %u\n",
+ k, temp);
+ }
+ }
+ if (temp < data->refer_min)
+ data->refer_min = temp;
+ if (temp > data->refer_max)
+ data->refer_max = temp;
+ k += 2;
+ }
+ }
+#else
+ length = data->x_line * data->y_line * 2;
if (NULL == data->references)
data->references = kzalloc(length, GFP_KERNEL);
@@ -179,6 +253,7 @@ static void check_all_raw_cap(struct synaptics_drv_data *data)
if (temp > data->refer_max)
data->refer_max = temp;
}
+#endif
printk(KERN_DEBUG "[TSP] min : %u, max : %u\n",
data->refer_min, data->refer_max);
}
@@ -333,6 +408,56 @@ static void check_rx_to_rx(struct synaptics_drv_data *data)
kfree(buff);
}
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+static void check_delta_cap(struct synaptics_drv_data *data)
+{
+ int i, k=0;
+ u16 temp = 0;
+ u16 length;
+ u8 escape_rx_line;
+ u8 *btn_data;
+ int start_button_data;
+
+ if (data->pdata->support_extend_button)
+ escape_rx_line = data->pdata->extend_button_map->nbuttons;
+ else
+ escape_rx_line = data->pdata->button_map->nbuttons;
+
+ length = escape_rx_line * 2;
+
+ btn_data = kzalloc(length, GFP_KERNEL);
+
+ data->refer_min = 0xffff;
+ data->refer_max = 0x0;
+
+ start_button_data = ((data->x_line * (data->y_line + escape_rx_line)) + data->y_line) * 2;
+
+ /* set the index */
+ set_report_index(data, start_button_data);
+
+ /* Set the GetReport bit to run the AutoScan */
+ set_report_mode(data, 0x01, 0x00);
+
+ /* read all report data */
+ synaptics_ts_read_block(data,
+ data->f54.data_base_addr + 3,
+ btn_data, length);
+
+ for (i = 0; i < escape_rx_line; i++) {
+ temp = (u16)(btn_data[k] | (btn_data[k+1] << 8));
+ printk(KERN_DEBUG "[TSP] index[btn:%d] data[0x%x]\n", i, temp);
+
+ if (temp > BUTTON_THRESHOLD_LIMIT)
+ data->pdata->button_pressure[i] = BUTTON_THRESHOLD_MIN;
+ else
+ data->pdata->button_pressure[i] = temp;
+ k = k + 2;
+ }
+
+ kfree(btn_data);
+}
+#endif
+
static void check_diagnostics_mode(struct synaptics_drv_data *data)
{
/* Set report mode */
@@ -355,6 +480,12 @@ static void check_diagnostics_mode(struct synaptics_drv_data *data)
check_rx_to_rx(data);
break;
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ case REPORT_TYPE_DELTA_CAP:
+ check_delta_cap(data);
+ break;
+#endif
+
default:
break;
}
@@ -427,11 +558,25 @@ static u16 get_value(struct synaptics_drv_data *data,
u32 pos_x, u32 pos_y)
{
u16 tmp = 0;
+ u8 escape_rx_line;
switch (data->cmd_report_type) {
case REPORT_TYPE_RAW_CAP:
{
- u16 position = (u16)(data->y_line * pos_x) + pos_y;
+ u16 position;
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYS)
+ if (data->pdata->support_extend_button)
+ escape_rx_line =
+ data->pdata->extend_button_map->nbuttons;
+ else
+ escape_rx_line =
+ data->pdata->button_map->nbuttons;
+
+ position = (u16)((data->y_line +
+ escape_rx_line) * pos_x) + pos_y;
+#else
+ position = (u16)(data->y_line * pos_x) + pos_y;
+#endif
position *= 2;
tmp = (u16)(data->references[position] |
(data->references[position+1] << 8));
@@ -845,6 +990,297 @@ static struct attribute_group sec_sysfs_attr_group = {
.attrs = sec_sysfs_attributes,
};
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+static ssize_t sec_touchkey_sensitivity_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ printk(KERN_INFO "[TSP] do noting!\n");
+ return size;
+}
+
+static ssize_t sec_touchkey_back_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON4]);
+ else
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON2]);
+}
+
+static ssize_t sec_touchkey_menu_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON2]);
+ else
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON1]);
+}
+
+static ssize_t sec_touchkey_threshold_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d %d %d %d %d\n",
+ BUTTON5_0_THRESHOLD,
+ BUTTON5_1_THRESHOLD,
+ BUTTON5_2_THRESHOLD,
+ BUTTON5_3_THRESHOLD,
+ BUTTON5_4_THRESHOLD);
+ else
+ return sprintf(buf, "%d %d\n",
+ BUTTON2_0_THRESHOLD,
+ BUTTON2_1_THRESHOLD);
+}
+
+static ssize_t sec_touchkey_dummy_btn1_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON1]);
+ else {
+ printk(KERN_DEBUG "[TSP] dummy btn1 not supported\n");
+ return 0;
+ }
+}
+
+static ssize_t sec_touchkey_dummy_btn3_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON3]);
+ else {
+ printk(KERN_DEBUG "[TSP] dummy btn3 not supported\n");
+ return 0;
+ }
+}
+
+static ssize_t sec_touchkey_dummy_btn5_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d\n", data->pdata->button_pressure[BUTTON5]);
+ else {
+ printk(KERN_DEBUG "[TSP] dummy btn5 not supported\n");
+ return 0;
+ }
+}
+
+static ssize_t sec_touchkey_button_all_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int irq = gpio_to_irq(data->gpio);
+
+ disable_irq(irq);
+ synaptics_ts_write_data(data, 0xf0, 0x01);
+ data->cmd_report_type = REPORT_TYPE_DELTA_CAP;
+ check_diagnostics_mode(data);
+ synaptics_ts_write_data(data, 0xf0, 0x00);
+ enable_irq(irq);
+
+ if (data->pdata->support_extend_button)
+ return sprintf(buf, "%d %d %d %d %d\n",
+ data->pdata->button_pressure[BUTTON1],
+ data->pdata->button_pressure[BUTTON2],
+ data->pdata->button_pressure[BUTTON3],
+ data->pdata->button_pressure[BUTTON4],
+ data->pdata->button_pressure[BUTTON5]);
+ else
+ return sprintf(buf, "%d %d\n",
+ data->pdata->button_pressure[BUTTON1],
+ data->pdata->button_pressure[BUTTON2]);
+}
+
+static ssize_t sec_touchkey_button_status_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ u8 int_status = 0;
+ u8 button_status = 0;
+
+ /* check interrupt status */
+ synaptics_ts_read_data(data,
+ data->f01.data_base_addr + 1,
+ &int_status);
+
+ /* check button status */
+ synaptics_ts_read_data(data,
+ data->f1a.data_base_addr,
+ &button_status);
+
+ return sprintf(buf, "%d %d\n",
+ int_status,
+ button_status);
+}
+
+static ssize_t sec_brightness_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+ int on_off;
+
+ if (sscanf(buf, "%d\n", &on_off) == 1) {
+ //printk(KERN_DEBUG "[TSPLED] touch_led_on [%d]\n", on_off);
+ data->pdata->led_control(on_off);
+ } else {
+ printk(KERN_DEBUG "[TSPLED] buffer read failed\n");
+ }
+ return size;
+}
+
+static ssize_t sec_extra_button_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int extra_event;
+
+ if (sscanf(buf, "%d\n", &extra_event) == 1) {
+ printk(KERN_DEBUG "[TSP] extra event [%d]\n", extra_event);
+ } else {
+ printk(KERN_DEBUG "[TSP] buffer read failed\n");
+ }
+ return size;
+}
+
+static ssize_t sec_keypad_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", atomic_read(&data->keypad_enable));
+}
+
+static ssize_t sec_keypad_enable_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct synaptics_drv_data *data = dev_get_drvdata(dev);
+
+ unsigned int val = 0;
+ sscanf(buf, "%d", &val);
+ val = (val == 0 ? 0 : 1);
+ atomic_set(&data->keypad_enable, val);
+ if (val) {
+ set_bit(KEY_BACK, data->input->keybit);
+ set_bit(KEY_MENU, data->input->keybit);
+ set_bit(KEY_HOME, data->input->keybit);
+ } else {
+ clear_bit(KEY_BACK, data->input->keybit);
+ clear_bit(KEY_MENU, data->input->keybit);
+ clear_bit(KEY_HOME, data->input->keybit);
+ }
+ input_sync(data->input);
+
+ return count;
+}
+
+static DEVICE_ATTR(touch_sensitivity, S_IRUGO | S_IWUSR,
+ NULL, sec_touchkey_sensitivity_store);
+static DEVICE_ATTR(touchkey_back, S_IRUGO | S_IWUSR,
+ sec_touchkey_back_show, NULL);
+static DEVICE_ATTR(touchkey_menu, S_IRUGO | S_IWUSR,
+ sec_touchkey_menu_show, NULL);
+static DEVICE_ATTR(touchkey_threshold, S_IRUGO | S_IWUSR,
+ sec_touchkey_threshold_show, NULL);
+static DEVICE_ATTR(touchkey_dummy_btn1, S_IRUGO | S_IWUSR,
+ sec_touchkey_dummy_btn1_show, NULL);
+static DEVICE_ATTR(touchkey_dummy_btn3, S_IRUGO | S_IWUSR,
+ sec_touchkey_dummy_btn3_show, NULL);
+static DEVICE_ATTR(touchkey_dummy_btn5, S_IRUGO | S_IWUSR,
+ sec_touchkey_dummy_btn5_show, NULL);
+static DEVICE_ATTR(touchkey_button_all, S_IRUGO | S_IWUSR,
+ sec_touchkey_button_all_show, NULL);
+static DEVICE_ATTR(brightness, S_IRUGO | S_IWUSR,
+ NULL, sec_brightness_store);
+static DEVICE_ATTR(extra_button_event, S_IRUGO | S_IWUSR,
+ NULL, sec_extra_button_store);
+static DEVICE_ATTR(touchkey_button_status, S_IRUGO | S_IWUSR,
+ sec_touchkey_button_status_show, NULL);
+static DEVICE_ATTR(keypad_enable, S_IRUGO|S_IWUSR,
+ sec_keypad_enable_show, sec_keypad_enable_store);
+
+static struct attribute *sec_touchkey_sysfs_attributes[] = {
+ &dev_attr_touch_sensitivity.attr,
+ &dev_attr_touchkey_back.attr,
+ &dev_attr_touchkey_menu.attr,
+ &dev_attr_touchkey_threshold.attr,
+ &dev_attr_touchkey_dummy_btn1.attr,
+ &dev_attr_touchkey_dummy_btn3.attr,
+ &dev_attr_touchkey_dummy_btn5.attr,
+ &dev_attr_touchkey_button_all.attr,
+ &dev_attr_brightness.attr,
+ &dev_attr_extra_button_event.attr,
+ &dev_attr_touchkey_button_status.attr,
+ &dev_attr_keypad_enable.attr,
+ NULL,
+};
+
+static struct attribute_group sec_touchkey_sysfs_attr_group = {
+ .attrs = sec_touchkey_sysfs_attributes,
+};
+#endif
+
int set_tsp_sysfs(struct synaptics_drv_data *data)
{
int ret = 0;
@@ -861,6 +1297,23 @@ int set_tsp_sysfs(struct synaptics_drv_data *data)
pr_err("[TSP] failed to create sysfs group\n");
goto err_device_create;
}
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+ synaptics_with_gpio_led_device = device_create(sec_class,
+ NULL, 0, data, "sec_touchkey");
+ if (IS_ERR(synaptics_with_gpio_led_device)) {
+ pr_err("[TSP] failed to create device for tsp_touchkey sysfs\n");
+ ret = -ENODEV;
+ goto err_device_create;
+ }
+
+ ret = sysfs_create_group(&synaptics_with_gpio_led_device->kobj,
+ &sec_touchkey_sysfs_attr_group);
+ if (ret) {
+ pr_err("[TSP] failed to create sec_touchkey sysfs group\n");
+ goto err_device_create;
+ }
+#endif
+
return 0;
err_device_create:
@@ -877,6 +1330,10 @@ void remove_tsp_sysfs(struct synaptics_drv_data *data)
kfree(data->tx_to_gnd);
sysfs_remove_group(&data->dev->kobj, &sec_sysfs_attr_group);
+#if defined(CONFIG_TOUCHSCREEN_SYNAPTICS_S7301_KEYLED)
+ sysfs_remove_group(&synaptics_with_gpio_led_device->kobj,
+ &sec_touchkey_sysfs_attr_group);
+#endif
put_device(data->dev);
device_unregister(data->dev);
}
diff --git a/drivers/input/touchscreen/synaptics_sysfs.h b/drivers/input/touchscreen/synaptics_sysfs.h
index 6d212c8..0f62b54 100644
--- a/drivers/input/touchscreen/synaptics_sysfs.h
+++ b/drivers/input/touchscreen/synaptics_sysfs.h
@@ -15,6 +15,7 @@
#include <linux/wakelock.h>
#define SYNAPTICS_FW "/sdcard/firmware/synaptics_fw"
+#define SYNAPTICS_FW2 "/sdcard/synaptics_fw.img"
#define FULL_RAW_CAP_LOWER_LIMIT 1000
#define FULL_RAW_CAP_UPPER_LIMIT 3000
#define MAX_RX_SIZE 45
diff --git a/drivers/input/touchscreen/wacom/w9002_flash.c b/drivers/input/touchscreen/wacom/w9002_flash.c
new file mode 100644
index 0000000..e2fe54d
--- /dev/null
+++ b/drivers/input/touchscreen/wacom/w9002_flash.c
@@ -0,0 +1,1253 @@
+/*
+ * w9002_flash.c - Wacom Digitizer Controller Flash Driver
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/wacom_i2c.h>
+#include "w9002_flash.h"
+
+static int wacom_i2c_flash_chksum(struct wacom_i2c *wac_i2c,
+ unsigned char *flash_data,
+ unsigned long *max_address)
+{
+ unsigned long i;
+ unsigned long chksum = 0;
+
+ for (i = 0x0000; i <= *max_address; i++)
+ chksum += flash_data[i];
+
+ chksum &= 0xFFFF;
+
+ return (int)chksum;
+}
+
+static int wacom_flash_cmd(struct wacom_i2c *wac_i2c)
+{
+ int rv, len, i;
+ u8 buf[10];
+ bool i2c_mode = WACOM_I2C_MODE_BOOT;
+
+#if defined(CONFIG_MACH_KONA)
+ buf[0] = 0x0d;
+ buf[1] = FLASH_START0;
+ buf[2] = FLASH_START1;
+ buf[3] = FLASH_START2;
+ buf[4] = FLASH_START3;
+ buf[5] = FLASH_START4;
+ buf[6] = FLASH_START5;
+ buf[7] = 0x0d;
+
+ len = 8;
+ rv = wacom_i2c_send(wac_i2c, buf, len, i2c_mode);
+#else
+
+ for (i = 0; i < 2; ++i) {
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x32;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, i2c_mode);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen:fail change to normal:%d\n",
+ rv);
+
+ i2c_mode = WACOM_I2C_MODE_NORMAL;
+ continue;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 2;
+ buf[len++] = 2;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, i2c_mode);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen:fail change to normal:%d\n",
+ rv);
+ i2c_mode = WACOM_I2C_MODE_NORMAL;
+ continue;
+ }
+ }
+#endif
+ if (rv < 0) {
+ printk(KERN_ERR
+ "Sending flash command failed\n");
+ return -1;
+ }
+
+ printk(KERN_DEBUG "epen:flash cmd sent:%d\n", rv);
+ msleep(500);
+
+ return 0;
+}
+
+static bool flash_query(struct wacom_i2c *wac_i2c)
+{
+ int rv, ECH;
+ u8 buf[4];
+ u16 len;
+ unsigned char command[CMD_SIZE];
+ unsigned char response[RSP_SIZE];
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ printk(KERN_DEBUG "epen: %s\n", __func__);
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 5;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_QUERY;
+ command[6] = ECH = 7;
+
+ rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 5 rv:%d\n", rv);
+ return false;
+ }
+
+ if ((response[3] != QUERY_CMD) || (response[4] != ECH)) {
+ printk(KERN_DEBUG "epen: res3:%d res4:%d\n", response[3],
+ response[4]);
+ return false;
+ }
+ if (response[5] != QUERY_RSP) {
+ printk(KERN_DEBUG "epen: res5:%d\n", response[5]);
+ return false;
+ }
+
+ return true;
+}
+
+static bool flash_blver(struct wacom_i2c *wac_i2c, int *blver)
+{
+ int rv, ECH;
+ u8 buf[4];
+ u16 len;
+ unsigned char command[CMD_SIZE];
+ unsigned char response[RSP_SIZE];
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 5;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_BLVER;
+ command[6] = ECH = 7;
+
+ rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 5 rv:%d\n", rv);
+ return false;
+ }
+
+ if ((response[3] != BOOT_CMD) || (response[4] != ECH))
+ return false;
+
+ *blver = (int)response[5];
+
+ return true;
+}
+
+static bool flash_mputype(struct wacom_i2c *wac_i2c, int *pMpuType)
+{
+ int rv, ECH;
+ u8 buf[4];
+ u16 len;
+ unsigned char command[CMD_SIZE];
+ unsigned char response[RSP_SIZE];
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE; /* Command-MSB, SET_REPORT */
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 5;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_MPU;
+ command[6] = ECH = 7;
+
+ rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(1000, 1000);
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 5 rv:%d\n", rv);
+ return false;
+ }
+
+ if ((response[3] != MPU_CMD) || (response[4] != ECH))
+ return false;
+
+ *pMpuType = (int)response[5];
+
+ return true;
+}
+
+static bool flash_security_unlock(struct wacom_i2c *wac_i2c, int *status)
+{
+ int rv, ECH;
+ u8 buf[4];
+ u16 len;
+ unsigned char command[CMD_SIZE];
+ unsigned char response[RSP_SIZE];
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 5;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_SECURITY_UNLOCK;
+ command[6] = ECH = 7;
+
+ rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return 0;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(1000, 1000);
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 5 rv:%d\n", rv);
+ return false;
+ }
+
+ if ((response[3] != SEC_CMD) || (response[4] != ECH))
+ return false;
+
+ *status = (int)response[5];
+
+ return true;
+}
+
+static bool flash_end(struct wacom_i2c *wac_i2c)
+{
+ int rv, ECH;
+ u8 buf[4];
+ u16 len;
+ unsigned char command[CMD_SIZE];
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 5;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_EXIT;
+ command[6] = ECH = 7;
+
+ rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ return true;
+}
+
+static int GetBLVersion(struct wacom_i2c *wac_i2c, int *pBLVer)
+{
+ int rv;
+ int retry = 0;
+
+ wacom_flash_cmd(wac_i2c);
+ do {
+ msleep(100);
+ rv = flash_query(wac_i2c);
+ retry++;
+ } while (rv < 0 && retry < 10);
+
+ if (rv < 0)
+ return EXIT_FAIL_GET_BOOT_LOADER_VERSION;
+
+ rv = flash_blver(wac_i2c, pBLVer);
+ if (rv)
+ return EXIT_OK;
+ else
+ return EXIT_FAIL_GET_BOOT_LOADER_VERSION;
+}
+
+static int GetMpuType(struct wacom_i2c *wac_i2c, int *pMpuType)
+{
+ int rv;
+
+ if (!flash_query(wac_i2c)) {
+ if (!wacom_flash_cmd(wac_i2c)) {
+ return EXIT_FAIL_ENTER_FLASH_MODE;
+ } else {
+ msleep(100);
+ if (!flash_query(wac_i2c))
+ return EXIT_FAIL_FLASH_QUERY;
+ }
+ }
+
+ rv = flash_mputype(wac_i2c, pMpuType);
+ if (rv)
+ return EXIT_OK;
+ else
+ return EXIT_FAIL_GET_MPU_TYPE;
+}
+
+static int SetSecurityUnlock(struct wacom_i2c *wac_i2c, int *pStatus)
+{
+ int rv;
+
+ if (!flash_query(wac_i2c)) {
+ if (!wacom_flash_cmd(wac_i2c)) {
+ return EXIT_FAIL_ENTER_FLASH_MODE;
+ } else {
+ msleep(100);
+ if (!flash_query(wac_i2c))
+ return EXIT_FAIL_FLASH_QUERY;
+ }
+ }
+
+ rv = flash_security_unlock(wac_i2c, pStatus);
+ if (rv)
+ return EXIT_OK;
+ else
+ return EXIT_FAIL;
+}
+
+static bool flash_erase(struct wacom_i2c *wac_i2c, bool bAllUserArea,
+ int *eraseBlock, int num)
+{
+ int rv, ECH;
+ unsigned char sum;
+ unsigned char buf[72];
+ unsigned char cmd_chksum;
+ u16 len;
+ int i, j;
+ unsigned char command[CMD_SIZE];
+ unsigned char response[RSP_SIZE];
+
+ for (i = 0; i < num; i++) {
+ /*msleep(500);*/
+retry:
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: failing 1:%d\n", i);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 7;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_ERASE_FLASH;
+ command[6] = ECH = i;
+ command[7] = *eraseBlock;
+ eraseBlock++;
+
+ sum = 0;
+ for (j = 0; j < 8; j++)
+ sum += command[j];
+ cmd_chksum = ~sum + 1;
+ command[8] = cmd_chksum;
+
+ rv = wacom_i2c_send(wac_i2c, command, 9, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: failing 2:%d\n", i);
+ return false;
+ }
+
+ switch (i) {
+ case 0:
+ msleep(3000);
+ break;
+
+ case 1:
+ msleep(3000);
+ break;
+
+ case 2:
+ msleep(5000);
+ break;
+
+ case 3:
+ msleep(500);
+ break;
+
+ default:
+ msleep(5000);
+ break;
+ }
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: failing 3:%d\n", i);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: failing 4:%d\n", i);
+ return false;
+ }
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: failing 5:%d\n", i);
+ return false;
+ }
+
+ if ((response[3] != ERS_CMD) || (response[4] != ECH)) {
+ printk(KERN_DEBUG "epen: failing 6:%d\n", i);
+ return false;
+ }
+
+ if (response[5] == 0x80) {
+ printk(KERN_DEBUG "epen: retry\n");
+ goto retry;
+ }
+ if (response[5] != ACK) {
+ printk(KERN_DEBUG "epen: failing 7:%d res5:%d\n", i,
+ response[5]);
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool is_flash_marking(struct wacom_i2c *wac_i2c,
+ size_t data_size, bool *bMarking, int iMpuID)
+{
+ const int MAX_CMD_SIZE = (12 + FLASH_BLOCK_SIZE + 2);
+ int rv, ECH;
+ unsigned char flash_data[FLASH_BLOCK_SIZE];
+ unsigned char buf[300];
+ unsigned char sum;
+ int len;
+ unsigned int i, j;
+ unsigned char response[RSP_SIZE];
+ unsigned char command[MAX_CMD_SIZE];
+
+ *bMarking = false;
+
+ printk(KERN_DEBUG "epen: started\n");
+ for (i = 0; i < FLASH_BLOCK_SIZE; i++)
+ flash_data[i] = 0xFF;
+
+ flash_data[56] = 0x00;
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 76;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_VERIFY_FLASH;
+ command[6] = ECH = 1;
+ command[7] = 0xC0;
+ command[8] = 0x1F;
+ command[9] = 0x01;
+ command[10] = 0x00;
+ command[11] = 8;
+
+ sum = 0;
+ for (j = 0; j < 12; j++)
+ sum += command[j];
+
+ command[MAX_CMD_SIZE - 2] = ~sum + 1;
+
+ sum = 0;
+ printk(KERN_DEBUG "epen: start writing command\n");
+ for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) {
+ command[i] = flash_data[i - 12];
+ sum += flash_data[i - 12];
+ }
+ command[MAX_CMD_SIZE - 1] = ~sum + 1;
+
+ printk(KERN_DEBUG "epen: sending command\n");
+ rv = wacom_i2c_send(wac_i2c, command, MAX_CMD_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ rv = wacom_i2c_recv(wac_i2c, response, RSP_SIZE, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 5 rv:%d\n", rv);
+ return false;
+ }
+
+ printk(KERN_DEBUG "epen: checking response\n");
+ if ((response[3] != MARK_CMD) ||
+ (response[4] != ECH) || (response[5] != ACK)) {
+ printk(KERN_DEBUG "epen: fails res3:%d res4:%d res5:%d\n",
+ response[3], response[4], response[5]);
+ return false;
+ }
+
+ *bMarking = true;
+ return true;
+}
+
+static bool flash_write_block(struct wacom_i2c *wac_i2c, char *flash_data,
+ unsigned long ulAddress, u8 *pcommand_id)
+{
+ const int MAX_COM_SIZE = (12 + FLASH_BLOCK_SIZE + 2);
+ int len, ECH;
+ unsigned char buf[300];
+ int rv;
+ unsigned char sum;
+ unsigned char command[MAX_COM_SIZE];
+ unsigned char response[RSP_SIZE];
+ unsigned int i;
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0)
+ return false;
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 76;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_WRITE_FLASH;
+ command[6] = ECH = ++(*pcommand_id);
+ command[7] = ulAddress & 0x000000ff;
+ command[8] = (ulAddress & 0x0000ff00) >> 8;
+ command[9] = (ulAddress & 0x00ff0000) >> 16;
+ command[10] = (ulAddress & 0xff000000) >> 24;
+ command[11] = 8;
+ sum = 0;
+ for (i = 0; i < 12; i++)
+ sum += command[i];
+ command[MAX_COM_SIZE - 2] = ~sum + 1;
+
+ sum = 0;
+ for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) {
+ command[i] = flash_data[ulAddress + (i - 12)];
+ sum += flash_data[ulAddress + (i - 12)];
+ }
+ command[MAX_COM_SIZE - 1] = ~sum + 1;
+
+ rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ if ((response[3] != WRITE_CMD) ||
+ (response[4] != ECH) || response[5] != ACK)
+ return false;
+
+ return true;
+
+}
+
+static bool flash_write(struct wacom_i2c *wac_i2c,
+ unsigned char *flash_data, size_t data_size,
+ unsigned long start_address, unsigned long *max_address,
+ int mpuType)
+{
+ unsigned long ulAddress;
+ int i;
+ bool rv;
+ unsigned long pageNo = 0;
+ u8 command_id = 0;
+
+ printk(KERN_DEBUG "epen: flash_write start\n");
+
+ for (ulAddress = start_address; ulAddress < *max_address;
+ ulAddress += FLASH_BLOCK_SIZE) {
+ unsigned int j;
+ bool bWrite = false;
+
+ /* Wacom 2012/10/04: skip if all each data locating on
+ from ulAddr to ulAddr+Block_SIZE_W are 0xff */
+ for (i = 0; i < FLASH_BLOCK_SIZE; i++) {
+ if (flash_data[ulAddress + i] != 0xFF)
+ break;
+ }
+ if (i == (FLASH_BLOCK_SIZE)) {
+ /*printk(KERN_DEBUG"epen:BLOCK PASSED\n"); */
+ continue;
+ }
+ /* Wacom 2012/10/04 */
+
+ for (j = 0; j < FLASH_BLOCK_SIZE; j++) {
+ if (flash_data[ulAddress + j] == 0xFF)
+ continue;
+ else {
+ bWrite = true;
+ break;
+ }
+ }
+
+ if (!bWrite) {
+ pageNo++;
+ continue;
+ }
+
+ rv = flash_write_block(wac_i2c, flash_data, ulAddress,
+ &command_id);
+ if (!rv)
+ return false;
+
+ pageNo++;
+ }
+
+ return true;
+}
+
+static bool flash_verify(struct wacom_i2c *wac_i2c,
+ unsigned char *flash_data, size_t data_size,
+ unsigned long start_address,
+ unsigned long *max_address, int mpuType)
+{
+ int ECH;
+ unsigned long ulAddress;
+ int rv;
+ unsigned long pageNo = 0;
+ u8 command_id = 0;
+ printk(KERN_DEBUG "epen: verify starts\n");
+ for (ulAddress = start_address; ulAddress < *max_address;
+ ulAddress += FLASH_BLOCK_SIZE) {
+ const int MAX_CMD_SIZE = 12 + FLASH_BLOCK_SIZE + 2;
+ unsigned char buf[300];
+ unsigned char sum;
+ int len;
+ unsigned int i, j;
+ unsigned char command[MAX_CMD_SIZE];
+ unsigned char response[RSP_SIZE];
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 76;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_VERIFY_FLASH;
+ command[6] = ECH = ++command_id;
+ command[7] = ulAddress & 0x000000ff;
+ command[8] = (ulAddress & 0x0000ff00) >> 8;
+ command[9] = (ulAddress & 0x00ff0000) >> 16;
+ command[10] = (ulAddress & 0xff000000) >> 24;
+ command[11] = 8;
+
+ sum = 0;
+ for (j = 0; j < 12; j++)
+ sum += command[j];
+ command[MAX_CMD_SIZE - 2] = ~sum + 1;
+
+ sum = 0;
+ for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) {
+ command[i] = flash_data[ulAddress + (i - 12)];
+ sum += flash_data[ulAddress + (i - 12)];
+ }
+ command[MAX_CMD_SIZE - 1] = ~sum + 1;
+
+ rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ if (ulAddress <= 0x0ffff)
+ ndelay(250000);
+ else if (ulAddress >= 0x10000 && ulAddress <= 0x20000)
+ ndelay(350000);
+ else
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 5 rv:%d\n", rv);
+ return false;
+ }
+
+ if ((response[3] != VERIFY_CMD) ||
+ (response[4] != ECH) || (response[5] != ACK)) {
+ printk(KERN_DEBUG "epen: res3:%d res4:%d res5:%d\n",
+ response[3], response[4], response[5]);
+ return false;
+ }
+ pageNo++;
+ }
+
+ return true;
+}
+
+static bool flash_marking(struct wacom_i2c *wac_i2c,
+ size_t data_size, bool bMarking, int iMpuID)
+{
+ const int MAX_CMD_SIZE = 12 + FLASH_BLOCK_SIZE + 2;
+ int rv, ECH;
+ unsigned char flash_data[FLASH_BLOCK_SIZE];
+ unsigned char buf[300];
+ unsigned char response[RSP_SIZE];
+ unsigned char sum;
+ int len;
+ unsigned int i, j;
+ unsigned char command[MAX_CMD_SIZE];
+
+ for (i = 0; i < FLASH_BLOCK_SIZE; i++)
+ flash_data[i] = 0xFF;
+
+ if (bMarking)
+ flash_data[56] = 0x00;
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x37;
+ buf[len++] = CMD_SET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 1 rv:%d\n", rv);
+ return false;
+ }
+
+ command[0] = 5;
+ command[1] = 0;
+ command[2] = 76;
+ command[3] = 0;
+ command[4] = BOOT_CMD_REPORT_ID;
+ command[5] = BOOT_WRITE_FLASH;
+ command[6] = ECH = 1;
+ command[7] = 0xC0;
+ command[8] = 0x1F;
+ command[9] = 0x01;
+ command[10] = 0x00;
+ command[11] = 8;
+
+ sum = 0;
+ for (j = 0; j < 12; j++)
+ sum += command[j];
+ command[MAX_CMD_SIZE - 2] = ~sum + 1;
+
+ sum = 0;
+ for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) {
+ command[i] = flash_data[i - 12];
+ sum += flash_data[i - 12];
+ }
+ command[MAX_CMD_SIZE - 1] = ~sum + 1;
+
+ rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 2 rv:%d\n", rv);
+ return false;
+ }
+
+ usleep_range(10000, 10000);
+
+ len = 0;
+ buf[len++] = 4;
+ buf[len++] = 0;
+ buf[len++] = 0x38;
+ buf[len++] = CMD_GET_FEATURE;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 3 rv:%d\n", rv);
+ return false;
+ }
+
+ len = 0;
+ buf[len++] = 5;
+ buf[len++] = 0;
+
+ rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT);
+ if (rv < 0) {
+ printk(KERN_DEBUG "epen: 4 rv:%d\n", rv);
+ return false;
+ }
+
+ printk(KERN_DEBUG "epen: confirming marking\n");
+ rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE,
+ WACOM_I2C_MODE_BOOT);
+ if (rv < 0)
+ return false;
+
+ if ((response[3] != 1) || (response[4] != ECH)\
+ || (response[5] != ACK)) {
+ printk(KERN_DEBUG "epen: failing res3:%d res4:%d res5:%d\n",
+ response[3], response[4], response[5]);
+ return false;
+ }
+
+ return true;
+}
+
+int wacom_i2c_flash(struct wacom_i2c *wac_i2c)
+{
+ unsigned long max_address = 0;
+ unsigned long start_address = 0x4000;
+ int eraseBlock[50], eraseBlockNum;
+ bool bRet;
+ int iChecksum;
+ int iBLVer, iMpuType, iStatus;
+ bool bMarking;
+ int iRet;
+ unsigned long ulMaxRange;
+
+ if (Binary == NULL) {
+ printk(KERN_ERR"[E-PEN] Data is NULL. Exit.\n");
+ return -1;
+ }
+
+#ifdef WACOM_HAVE_FWE_PIN
+ if (wac_i2c->have_fwe_pin) {
+ wac_i2c->wac_pdata->compulsory_flash_mode(true);
+ /*Reset */
+ wac_i2c->wac_pdata->reset_platform_hw();
+ msleep(200);
+ printk(KERN_DEBUG "epen: Set FWE\n");
+ }
+#endif
+ wake_lock(&wac_i2c->wakelock);
+
+ printk(KERN_DEBUG "epen:start getting the boot loader version\n");
+ /*Obtain boot loader version */
+ iRet = GetBLVersion(wac_i2c, &iBLVer);
+ if (iRet != EXIT_OK) {
+ printk(KERN_DEBUG "epen:failed to get Boot Loader version\n");
+ goto fw_update_error;
+ }
+
+ printk(KERN_DEBUG "epen: start getting the MPU version\n");
+ /*Obtain MPU type: this can be manually done in user space */
+ iRet = GetMpuType(wac_i2c, &iMpuType);
+ if (iRet != EXIT_OK) {
+ printk(KERN_DEBUG "epen: failed to get MPU type\n");
+ goto fw_update_error;
+ }
+
+ /*Set start and end address and block numbers */
+ eraseBlockNum = 0;
+ start_address = 0x4000;
+ max_address = 0x12FFF;
+ eraseBlock[eraseBlockNum++] = 2;
+ eraseBlock[eraseBlockNum++] = 1;
+ eraseBlock[eraseBlockNum++] = 0;
+ eraseBlock[eraseBlockNum++] = 3;
+
+ printk(KERN_DEBUG "epen: obtaining the checksum\n");
+ /*Calculate checksum */
+ iChecksum = wacom_i2c_flash_chksum(wac_i2c, Binary, &max_address);
+ printk(KERN_DEBUG "epen: Checksum is :%d\n", iChecksum);
+
+ bRet = true;
+
+ printk(KERN_DEBUG "epen: setting the security unlock\n");
+ /*Unlock security */
+ iRet = SetSecurityUnlock(wac_i2c, &iStatus);
+ if (iRet != EXIT_OK) {
+ printk(KERN_DEBUG "epen: failed to set security unlock\n");
+ goto fw_update_error;
+ }
+
+ /*Set adress range */
+ ulMaxRange = max_address;
+ ulMaxRange -= start_address;
+ ulMaxRange >>= 6;
+ if (max_address > (ulMaxRange << 6))
+ ulMaxRange++;
+
+ printk(KERN_DEBUG "epen: connecting to Wacom Digitizer\n");
+ printk(KERN_DEBUG "epen: erasing the current firmware\n");
+ /*Erase the old program */
+ bRet = flash_erase(wac_i2c, true, eraseBlock, eraseBlockNum);
+ if (!bRet) {
+ printk(KERN_DEBUG "epen: failed to erase the user program\n");
+ iRet = EXIT_FAIL_ERASE;
+ goto fw_update_error;
+ }
+ printk(KERN_DEBUG "epen: erasing done\n");
+
+ max_address = 0x11FC0;
+
+ printk(KERN_DEBUG "epen: writing new firmware\n");
+ /*Write the new program */
+ bRet =
+ flash_write(wac_i2c, Binary, DATA_SIZE, start_address, &max_address,
+ iMpuType);
+ if (!bRet) {
+ printk(KERN_DEBUG "epen: failed to write firmware\n");
+ iRet = EXIT_FAIL_WRITE_FIRMWARE;
+ goto fw_update_error;
+ }
+
+ printk(KERN_DEBUG "epen: start marking\n");
+ /*Set mark in writing process */
+ bRet = flash_marking(wac_i2c, DATA_SIZE, true, iMpuType);
+ if (!bRet) {
+ printk(KERN_DEBUG "epen: failed to mark firmware\n");
+ iRet = EXIT_FAIL_WRITE_FIRMWARE;
+ goto fw_update_error;
+ }
+
+ /*Set the address for verify */
+ start_address = 0x4000;
+ max_address = 0x11FBF;
+
+ printk(KERN_DEBUG "epen: start the verification\n");
+ /*Verify the written program */
+ bRet =
+ flash_verify(wac_i2c, Binary, DATA_SIZE, start_address,
+ &max_address, iMpuType);
+ if (!bRet) {
+ printk(KERN_DEBUG "epen: failed to verify the firmware\n");
+ iRet = EXIT_FAIL_VERIFY_FIRMWARE;
+ goto fw_update_error;
+ }
+
+ printk(KERN_DEBUG "epen: checking the mark\n");
+ /*Set mark */
+ bRet = is_flash_marking(wac_i2c, DATA_SIZE, &bMarking, iMpuType);
+ if (!bRet) {
+ printk(KERN_DEBUG "epen: marking firmwrae failed\n");
+ iRet = EXIT_FAIL_WRITING_MARK_NOT_SET;
+ goto fw_update_error;
+ }
+
+ /*Enable */
+ printk(KERN_DEBUG "epen: closing the boot mode\n");
+ bRet = flash_end(wac_i2c);
+ if (!bRet) {
+ printk(KERN_DEBUG "epen: closing boot mode failed\n");
+ iRet = EXIT_FAIL_WRITING_MARK_NOT_SET;
+ goto fw_update_error;
+ }
+ iRet = EXIT_OK;
+ printk(KERN_DEBUG "epen: write and verify completed\n");
+
+fw_update_error:
+ wake_unlock(&wac_i2c->wakelock);
+
+#ifdef WACOM_HAVE_FWE_PIN
+ if (wac_i2c->have_fwe_pin) {
+ wac_i2c->wac_pdata->compulsory_flash_mode(false);
+ /*Reset */
+ wac_i2c->wac_pdata->reset_platform_hw();
+ msleep(200);
+ }
+#endif
+ return iRet;
+}
diff --git a/drivers/input/touchscreen/wacom/w9002_flash.h b/drivers/input/touchscreen/wacom/w9002_flash.h
new file mode 100644
index 0000000..a6d0e49
--- /dev/null
+++ b/drivers/input/touchscreen/wacom/w9002_flash.h
@@ -0,0 +1,211 @@
+/*
+ * w9002_flash.h
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "wacom_i2c_func.h"
+#include "wacom_i2c_firm.h"
+
+#ifndef _WACOM_I2C_FLASH_H
+#define _WACOM_I2C_FLASH_H
+
+#define WACOM_CMD_QUERY0 0x04
+#define WACOM_CMD_QUERY1 0x00
+#define WACOM_CMD_QUERY2 0x33
+#define WACOM_CMD_QUERY3 0x02
+#define WACOM_CMD_THROW0 0x05
+#define WACOM_CMD_THROW1 0x00
+#define WACOM_QUERY_SIZE 19
+#define WACOM_RETRY_CNT 100
+
+struct flash {
+ int BLen;
+ unsigned long size;
+ unsigned char *data;
+};
+
+#define FLASH_START0 'f'
+#define FLASH_START1 'l'
+#define FLASH_START2 'a'
+#define FLASH_START3 's'
+#define FLASH_START4 'h'
+#define FLASH_START5 '\r'
+#define FLASH_ACK 0x06
+
+#define pana_QUERY 0x11
+
+#define flash_END 0x80
+#define flash_VERIFY 0x81
+#define flash_WRITE 0x82
+#define flash_READ 0x83
+#define flash_ERASE 0x84
+#define flash_SET_INFO 0x85
+#define flash_END_TO_BOOT 0x87
+#define flash_BAUDRATE 0x88
+
+#define flash_QUERY 0xE0
+#define flash_BLVER 0xE1
+#define flash_UNITID 0xE2
+#define flash_GET_INFO 0xE3
+#define flash_FWVER 0xE4
+#define flash_MPU 0xE8
+
+#define pen_QUERY '*'
+
+#define V09 0
+#define V095 1
+
+#define HIDIIC_VERSION V095
+
+#define FLASH_BLOCK_SIZE 64
+
+#define ASCINT_ON 0x0
+#define ASCINT_OFF 0x1
+#define ASCINT_ERROR 0xFF
+
+/*#define WRITE 0*/
+#define VERIFY 1
+#define WRITEVERIFY 2
+#define ERASE 3
+#define GETVERSION 4
+
+#define USER_ADDRESS 0x56
+#define BOOT_ADDRESS 0x57
+
+#define CMD_GET_FEATURE 2
+#define CMD_SET_FEATURE 3
+
+#define ACK 0
+
+#define BOOT_CMD_SIZE 78
+#define BOOT_RSP_SIZE 6
+
+#define BOOT_CMD_REPORT_ID 7
+
+#define BOOT_ERASE_FLASH 0
+#define BOOT_WRITE_FLASH 1
+#define BOOT_VERIFY_FLASH 2
+#define BOOT_EXIT 3
+#define BOOT_BLVER 4
+#define BOOT_MPU 5
+#define BOOT_SECURITY_UNLOCK 6
+#define BOOT_QUERY 7
+
+#define QUERY_CMD 0x07
+#define QUERY_ECH 'D'
+#define QUERY_RSP 0x06
+
+#define BOOT_CMD 0x04
+#define BOOT_ECH 'D'
+
+#define MPU_CMD 0x05
+#define MPU_ECH 'D'
+
+#define SEC_CMD 0x06
+#define SEC_ECH 'D'
+#define SEC_RSP 0x00
+
+#define ERS_CMD 0x00
+#define ERS_ECH 'D'
+#define ERS_RSP 0x00
+
+#define MARK_CMD 0x02
+#define MARK_ECH 'D'
+#define MARK_RSP 0x00
+
+#define WRITE_CMD 0x01
+#define WRITE_ECH 'D'
+#define WRITE_RSP 0x00
+
+#define VERIFY_CMD 0x02
+#define VERIFY_ECH 'D'
+#define VERIFY_RSP 0x00
+
+#define CMD_SIZE (72+6)
+#define RSP_SIZE 6
+
+#define DATA_SIZE (65536 * 2)
+
+/*exit codes*/
+#define EXIT_OK (0)
+#define EXIT_REBOOT (1)
+#define EXIT_FAIL (2)
+#define EXIT_USAGE (3)
+#define EXIT_NO_SUCH_FILE (4)
+#define EXIT_NO_INTEL_HEX (5)
+#define EXIT_FAIL_OPEN_COM_PORT (6)
+#define EXIT_FAIL_ENTER_FLASH_MODE (7)
+#define EXIT_FAIL_FLASH_QUERY (8)
+#define EXIT_FAIL_BAUDRATE_CHANGE (9)
+#define EXIT_FAIL_WRITE_FIRMWARE (10)
+#define EXIT_FAIL_EXIT_FLASH_MODE (11)
+#define EXIT_CANCEL_UPDATE (12)
+#define EXIT_SUCCESS_UPDATE (13)
+#define EXIT_FAIL_HID2SERIAL (14)
+#define EXIT_FAIL_VERIFY_FIRMWARE (15)
+#define EXIT_FAIL_MAKE_WRITING_MARK (16)
+#define EXIT_FAIL_ERASE_WRITING_MARK (17)
+#define EXIT_FAIL_READ_WRITING_MARK (18)
+#define EXIT_EXIST_MARKING (19)
+#define EXIT_FAIL_MISMATCHING (20)
+#define EXIT_FAIL_ERASE (21)
+#define EXIT_FAIL_GET_BOOT_LOADER_VERSION (22)
+#define EXIT_FAIL_GET_MPU_TYPE (23)
+#define EXIT_MISMATCH_BOOTLOADER (24)
+#define EXIT_MISMATCH_MPUTYPE (25)
+#define EXIT_FAIL_ERASE_BOOT (26)
+#define EXIT_FAIL_WRITE_BOOTLOADER (27)
+#define EXIT_FAIL_SWAP_BOOT (28)
+#define EXIT_FAIL_WRITE_DATA (29)
+#define EXIT_FAIL_GET_FIRMWARE_VERSION (30)
+#define EXIT_FAIL_GET_UNIT_ID (31)
+#define EXIT_FAIL_SEND_STOP_COMMAND (32)
+#define EXIT_FAIL_SEND_QUERY_COMMAND (33)
+#define EXIT_NOT_FILE_FOR_535 (34)
+#define EXIT_NOT_FILE_FOR_514 (35)
+#define EXIT_NOT_FILE_FOR_503 (36)
+#define EXIT_MISMATCH_MPU_TYPE (37)
+#define EXIT_NOT_FILE_FOR_515 (38)
+#define EXIT_NOT_FILE_FOR_1024 (39)
+#define EXIT_FAIL_VERIFY_WRITING_MARK (40)
+#define EXIT_DEVICE_NOT_FOUND (41)
+#define EXIT_FAIL_WRITING_MARK_NOT_SET (42)
+
+/*For Report Descreptor of HID over I2C*/
+#define HID_USAGE_UNDEFINED 0x00
+#define HID_USAGE_PAGE 0x05
+#define HID_USAGE_PAGE_DIGITIZER 0x0d
+#define HID_USAGE_PAGE_DESKTOP 0x01
+#define HID_USAGE 0x09
+#define HID_USAGE_X 0x30
+#define HID_USAGE_Y 0x31
+#define HID_USAGE_X_TILT 0x3d
+#define HID_USAGE_Y_TILT 0x3e
+#define HID_USAGE_FINGER 0x22
+#define HID_USAGE_STYLUS 0x20
+#define HID_USAGE_TIP_PRESSURE 0x30
+#define HID_COLLECTION 0xc0
+
+#define I2C_REQ_GET_REPORT 0x01
+#define I2C_REQ_SET_REPORT 0x09
+
+#define WAC_HID_FEATURE_REPORT 0x03
+#define WAC_MSG_RETRIES 5
+
+extern int wacom_i2c_flash(struct wacom_i2c *wac_i2c);
+
+#endif /*_WACOM_I2C_FLASH_H*/
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c.c b/drivers/input/touchscreen/wacom/wacom_i2c.c
index e0dd530..4a47709 100644
--- a/drivers/input/touchscreen/wacom/wacom_i2c.c
+++ b/drivers/input/touchscreen/wacom/wacom_i2c.c
@@ -25,7 +25,11 @@
#include <linux/uaccess.h>
#include <linux/firmware.h>
#include "wacom_i2c_func.h"
+#ifdef CONFIG_EPEN_WACOM_G9PL
+#include "w9002_flash.h"
+#else
#include "wacom_i2c_flash.h"
+#endif
#ifdef WACOM_IMPORT_FW_ALGO
#include "wacom_i2c_coord_tables.h"
#endif
@@ -151,13 +155,19 @@ int wacom_i2c_get_ums_data(struct wacom_i2c *wac_i2c, u8 **ums_data)
"[E-PEN] start, file path %s, size %ld Bytes\n",
WACOM_FW_PATH, fsize);
+#ifndef CONFIG_MACH_KONA
if (fsize != nSize) {
printk(KERN_ERR "[E-PEN] UMS firmware size is different\n");
ret = -EFBIG;
goto size_error;
}
+#endif
+#ifdef CONFIG_MACH_KONA
+ *ums_data = kmalloc(65536*2, GFP_KERNEL);
+#else
*ums_data = kmalloc(fsize, GFP_KERNEL);
+#endif
if (IS_ERR(*ums_data)) {
printk(KERN_ERR
"[E-PEN] %s, kmalloc failed\n", __func__);
@@ -165,6 +175,10 @@ int wacom_i2c_get_ums_data(struct wacom_i2c *wac_i2c, u8 **ums_data)
goto malloc_error;
}
+#ifdef CONFIG_MACH_KONA
+ memset((void *)*ums_data, 0xff, 65536*2);
+#endif
+
nread = vfs_read(fp, (char __user *)*ums_data,
fsize, &fp->f_pos);
printk(KERN_NOTICE "[E-PEN] nread %ld Bytes\n", nread);
@@ -223,12 +237,25 @@ int wacom_i2c_fw_update_UMS(struct wacom_i2c *wac_i2c)
return 0;
}
-#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_T0)
+#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_T0)\
+ || defined(CONFIG_MACH_KONA)
int wacom_i2c_firm_update(struct wacom_i2c *wac_i2c)
{
int ret;
int retry = 3;
const struct firmware *firm_data = NULL;
+
+#if defined(CONFIG_MACH_KONA)
+ u8 *flash_data;
+
+ flash_data = kmalloc(65536*2, GFP_KERNEL);
+ if (IS_ERR(flash_data)) {
+ printk(KERN_ERR
+ "[E-PEN] %s, kmalloc failed\n", __func__);
+ return -1;
+ }
+ memset((void *)flash_data, 0xff, 65536*2);
+#endif
firmware_updating_state = true;
@@ -242,8 +269,14 @@ int wacom_i2c_firm_update(struct wacom_i2c *wac_i2c)
ret, retry);
continue;
}
+#if defined(CONFIG_MACH_KONA)
+ memcpy((void *)flash_data,
+ (const void *)firm_data->data,
+ firm_data->size);
+ wacom_i2c_set_firm_data((unsigned char *)flash_data);
+#else
wacom_i2c_set_firm_data((unsigned char *)firm_data->data);
-
+#endif
ret = wacom_i2c_flash(wac_i2c);
if (ret == 0) {
@@ -259,6 +292,10 @@ int wacom_i2c_firm_update(struct wacom_i2c *wac_i2c)
}
firmware_updating_state = false;
+
+#if defined(CONFIG_MACH_KONA)
+ kfree(flash_data);
+#endif
if (ret < 0)
return -1;
@@ -535,6 +572,14 @@ static void wacom_i2c_set_input_values(struct i2c_client *client,
/* __set_bit(BTN_STYLUS2, input_dev->keybit); */
/* __set_bit(ABS_MISC, input_dev->absbit); */
+
+ /*softkey*/
+#ifdef WACOM_USE_SOFTKEY
+ __set_bit(EV_LED, input_dev->evbit);
+ __set_bit(LED_MISC, input_dev->ledbit);
+ __set_bit(KEY_MENU, input_dev->keybit);
+ __set_bit(KEY_BACK, input_dev->keybit);
+#endif
}
static int wacom_check_emr_prox(struct wacom_g5_callbacks *cb)
@@ -1349,6 +1394,9 @@ static int wacom_i2c_probe(struct i2c_client *client,
/*Set switch type*/
wac_i2c->invert_pen_insert = wacom_i2c_invert_by_switch_type();
+#elif defined(CONFIG_MACH_KONA)
+ wac_i2c->wac_pdata->late_resume_platform_hw();
+ msleep(200);
#endif
#ifdef WACOM_PDCT_WORK_AROUND
wac_i2c->pen_pdct = PDCT_NOSIGNAL;
@@ -1447,7 +1495,7 @@ static int wacom_i2c_probe(struct i2c_client *client,
printk(KERN_ERR "[E-PEN] exynos_cpufreq_get_level Error\n");
#ifdef SEC_BUS_LOCK
wac_i2c->dvfs_lock_status = false;
-#if defined(CONFIG_MACH_P4NOTE)
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
wac_i2c->bus_dev = dev_get("exynos-busfreq");
#endif /* CONFIG_MACH_P4NOTE */
#endif /* SEC_BUS_LOCK */
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_firm.c b/drivers/input/touchscreen/wacom/wacom_i2c_firm.c
index fddb8c9..f826f86 100644
--- a/drivers/input/touchscreen/wacom/wacom_i2c_firm.c
+++ b/drivers/input/touchscreen/wacom/wacom_i2c_firm.c
@@ -71,6 +71,13 @@ char Firmware_checksum[] = { 0x1F, 0x27, 0x85, 0x8B, 0xFB, };
const char B713X_checksum[] = { 0x1F, 0xB5, 0x84, 0x38, 0x34, };
/*checksum for 0x16*/
const char B660X_checksum[] = { 0x1F, 0x83, 0x88, 0xD4, 0x67, };
+#elif defined(CONFIG_MACH_KONA)
+const unsigned int Binary_nLength = 0xCBCB;
+const unsigned char Mpu_type = 0x00;
+unsigned int Firmware_version_of_file = 0x65D;
+unsigned char *firmware_name = "epen/W9002_B781.bin";
+
+char Firmware_checksum[] = { 0x1F, 0x72, 0xCD, 0x6E, 0xE3, };
#endif
void wacom_i2c_set_firm_data(unsigned char *Binary_new)
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_flash.c b/drivers/input/touchscreen/wacom/wacom_i2c_flash.c
index 691e66c..cf92018 100644
--- a/drivers/input/touchscreen/wacom/wacom_i2c_flash.c
+++ b/drivers/input/touchscreen/wacom/wacom_i2c_flash.c
@@ -73,6 +73,28 @@ int wacom_i2c_flash_cmd(struct wacom_i2c *wac_i2c)
int ret, len, i;
u8 buf[10], flashq;
+
+#if defined(CONFIG_MACH_KONA)
+ buf[0] = 0x0d;
+ buf[1] = FLASH_START0;
+ buf[2] = FLASH_START1;
+ buf[3] = FLASH_START2;
+ buf[4] = FLASH_START3;
+ buf[5] = FLASH_START4;
+ buf[6] = FLASH_START5;
+ buf[7] = 0x0d;
+
+ printk(KERN_DEBUG "[E-PEN][jjals] w9002 running!!\n");
+
+ len = 8;
+ ret = i2c_master_send(wac_i2c->client, buf, len);
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "Sending flash command failed\n");
+ return -1;
+ }
+#else
buf[0] = 0x0d;
buf[1] = FLASH_START0;
@@ -110,8 +132,7 @@ int wacom_i2c_flash_cmd(struct wacom_i2c *wac_i2c)
printk(KERN_DEBUG "[E-PEN]: flash send?:%d\n", ret);
msleep(270);
}
-
- wac_i2c->boot_mode = true;
+#endif
return 0;
}
@@ -174,6 +195,9 @@ int wacom_i2c_flash_enter(struct wacom_i2c *wac_i2c)
{
if (wacom_i2c_flash_query(wac_i2c, FLASH_QUERY, FLASH_ACK) == -1)
return ERR_NOT_FLASH;
+
+ wac_i2c->boot_mode = true;
+
return 0;
}
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_func.c b/drivers/input/touchscreen/wacom/wacom_i2c_func.c
index 18a7900..a981cbc 100644
--- a/drivers/input/touchscreen/wacom/wacom_i2c_func.c
+++ b/drivers/input/touchscreen/wacom/wacom_i2c_func.c
@@ -381,7 +381,8 @@ int wacom_i2c_query(struct wacom_i2c *wac_i2c)
#if defined(CONFIG_MACH_Q1_BD)\
|| defined(CONFIG_MACH_P4NOTE)\
- || defined(CONFIG_MACH_T0)
+ || defined(CONFIG_MACH_T0)\
+ || defined(CONFIG_MACH_KONA)
wac_feature->x_max = (u16) WACOM_MAX_COORD_X;
wac_feature->y_max = (u16) WACOM_MAX_COORD_Y;
#else
@@ -425,7 +426,7 @@ int wacom_i2c_query(struct wacom_i2c *wac_i2c)
}
wac_i2c->query_status = true;
-#if defined(CONFIG_MACH_P4NOTE)
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
wacom_checksum(wac_i2c);
#endif
@@ -797,6 +798,9 @@ static bool wacom_i2c_coord_range(s16 *x, s16 *y)
#if defined(CONFIG_MACH_T0)
if ((*x >= 0) && (*y >= 0) &&
(*x <= WACOM_POSX_MAX) && (*y <= WACOM_POSY_MAX - 50))
+#elif defined(CONFIG_MACH_KONA)
+ if ((*x >= WACOM_POSX_OFFSET) && (*y >= WACOM_POSX_OFFSET) &&
+ (*x <= WACOM_POSY_MAX) && (*y <= WACOM_POSX_MAX))
#else
if ((*x <= WACOM_POSX_MAX) && (*y <= WACOM_POSY_MAX))
#endif
@@ -805,6 +809,29 @@ static bool wacom_i2c_coord_range(s16 *x, s16 *y)
return false;
}
+#ifdef WACOM_USE_SOFTKEY
+static int keycode[] = {
+ KEY_MENU, KEY_BACK,
+};
+void wacom_i2c_softkey(struct wacom_i2c *wac_i2c, s16 key, s16 pressed)
+{
+ if (gpio_get_value(wac_i2c->wac_pdata->gpio_pendct) && pressed)
+ forced_release(wac_i2c);
+
+ input_report_key(wac_i2c->input_dev,
+ keycode[key], pressed);
+ input_sync(wac_i2c->input_dev);
+
+#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
+ printk(KERN_DEBUG "[E-PEN] keycode:%d pressed:%d\n",
+ keycode[key], pressed);
+#else
+ printk(KERN_DEBUG "[E-PEN] pressed:%d\n",
+ pressed);
+#endif
+}
+#endif
+
int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
{
bool prox = false;
@@ -817,6 +844,9 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
u8 gain = 0;
u8 height = 0;
int aveStrength = 2;
+#ifdef WACOM_USE_SOFTKEY
+ static s16 softkey, pressed, keycode;
+#endif
#ifdef WACOM_IRQ_WORK_AROUND
cancel_delayed_work(&wac_i2c->pendct_dwork);
@@ -854,6 +884,15 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
pr_debug("[E-PEN] is in(%d)\n", wac_i2c->tool);
#endif
}
+#ifdef WACOM_USE_SOFTKEY
+ softkey = !!(data[5] & 0x80);
+ if (softkey) {
+ pressed = !!(data[5] & 0x40);
+ keycode = (data[5] & 0x30) >> 4;
+ wacom_i2c_softkey(wac_i2c, keycode, pressed);
+ return 0;
+ }
+#endif
prox = !!(data[0] & 0x10);
stylus = !!(data[0] & 0x20);
@@ -976,9 +1015,16 @@ int wacom_i2c_coord(struct wacom_i2c *wac_i2c)
wac_i2c->side_pressed = stylus;
}
#if defined(CONFIG_SAMSUNG_KERNEL_DEBUG_USER)
- else
+ else {
printk(KERN_DEBUG "[E-PEN] raw data x=%d, y=%d\n",
x, y);
+#ifdef CONFIG_MACH_KONA
+ /* Pen should be released in the NOT AA area even if rdy value is 1. */
+ if (wac_i2c->pen_pressed || wac_i2c->side_pressed
+ || wac_i2c->pen_prox)
+ forced_release(wac_i2c);
+#endif
+ }
#endif
} else {
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index da5f5f2..3e64023 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -30,7 +30,6 @@
#include <linux/device-mapper.h>
#define DM_MSG_PREFIX "crypt"
-#define MESG_STR(x) x, sizeof(x)
/*
* context holding the current state of a multi-part conversion
@@ -238,7 +237,7 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{
memset(iv, 0, cc->iv_size);
- *(u32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff);
+ *(__le32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff);
return 0;
}
@@ -247,7 +246,7 @@ static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv,
struct dm_crypt_request *dmreq)
{
memset(iv, 0, cc->iv_size);
- *(u64 *)iv = cpu_to_le64(dmreq->iv_sector);
+ *(__le64 *)iv = cpu_to_le64(dmreq->iv_sector);
return 0;
}
@@ -414,7 +413,7 @@ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv,
struct crypto_cipher *essiv_tfm = this_crypt_config(cc)->iv_private;
memset(iv, 0, cc->iv_size);
- *(u64 *)iv = cpu_to_le64(dmreq->iv_sector);
+ *(__le64 *)iv = cpu_to_le64(dmreq->iv_sector);
crypto_cipher_encrypt_one(essiv_tfm, iv, iv);
return 0;
@@ -1577,11 +1576,17 @@ bad_mem:
static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
{
struct crypt_config *cc;
- unsigned int key_size;
+ unsigned int key_size, opt_params;
unsigned long long tmpll;
int ret;
+ struct dm_arg_set as;
+ const char *opt_string;
+
+ static struct dm_arg _args[] = {
+ {0, 1, "Invalid number of feature args"},
+ };
- if (argc != 5) {
+ if (argc < 5) {
ti->error = "Not enough arguments";
return -EINVAL;
}
@@ -1650,6 +1655,30 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
cc->start = tmpll;
+ argv += 5;
+ argc -= 5;
+
+ /* Optional parameters */
+ if (argc) {
+ as.argc = argc;
+ as.argv = argv;
+
+ ret = dm_read_arg_group(_args, &as, &opt_params, &ti->error);
+ if (ret)
+ goto bad;
+
+ opt_string = dm_shift_arg(&as);
+
+ if (opt_params == 1 && opt_string &&
+ !strcasecmp(opt_string, "allow_discards"))
+ ti->num_discard_requests = 1;
+ else if (opt_params) {
+ ret = -EINVAL;
+ ti->error = "Invalid feature arguments";
+ goto bad;
+ }
+ }
+
ret = -ENOMEM;
#if 1
cc->io_queue = create_singlethread_workqueue("kcryptd_io");
@@ -1691,9 +1720,16 @@ static int crypt_map(struct dm_target *ti, struct bio *bio,
struct dm_crypt_io *io;
struct crypt_config *cc;
- if (bio->bi_rw & REQ_FLUSH) {
+ /*
+ * If bio is REQ_FLUSH or REQ_DISCARD, just bypass crypt queues.
+ * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight
+ * - for REQ_DISCARD caller must use flush if IO ordering matters
+ */
+ if (unlikely(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) {
cc = ti->private;
bio->bi_bdev = cc->dev->bdev;
+ if (bio_sectors(bio))
+ bio->bi_sector = cc->start + dm_target_offset(ti, bio->bi_sector);
return DM_MAPIO_REMAPPED;
}
@@ -1736,6 +1772,10 @@ static int crypt_status(struct dm_target *ti, status_type_t type,
DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset,
cc->dev->name, (unsigned long long)cc->start);
+
+ if (ti->num_discard_requests)
+ DMEMIT(" 1 allow_discards");
+
break;
}
return 0;
@@ -1779,12 +1819,12 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
if (argc < 2)
goto error;
- if (!strnicmp(argv[0], MESG_STR("key"))) {
+ if (!strcasecmp(argv[0], "key")) {
if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) {
DMWARN("not suspended during key manipulation.");
return -EINVAL;
}
- if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) {
+ if (argc == 3 && !strcasecmp(argv[1], "set")) {
ret = crypt_set_key(cc, argv[2]);
if (ret)
return ret;
@@ -1792,7 +1832,7 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv)
ret = cc->iv_gen_ops->init(cc);
return ret;
}
- if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) {
+ if (argc == 2 && !strcasecmp(argv[1], "wipe")) {
if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) {
ret = cc->iv_gen_ops->wipe(cc);
if (ret)
@@ -1832,7 +1872,7 @@ static int crypt_iterate_devices(struct dm_target *ti,
static struct target_type crypt_target = {
.name = "crypt",
- .version = {1, 10, 0},
+ .version = {1, 11, 0},
.module = THIS_MODULE,
.ctr = crypt_ctr,
.dtr = crypt_dtr,
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 948e3f4..5f06fb6 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -197,15 +197,21 @@ EXPORT_SYMBOL(dm_dirty_log_destroy);
#define MIRROR_DISK_VERSION 2
#define LOG_OFFSET 2
-struct log_header {
- uint32_t magic;
+struct log_header_disk {
+ __le32 magic;
/*
* Simple, incrementing version. no backward
* compatibility.
*/
+ __le32 version;
+ __le64 nr_regions;
+} __packed;
+
+struct log_header_core {
+ uint32_t magic;
uint32_t version;
- sector_t nr_regions;
+ uint64_t nr_regions;
};
struct log_c {
@@ -239,10 +245,10 @@ struct log_c {
int log_dev_failed;
int log_dev_flush_failed;
struct dm_dev *log_dev;
- struct log_header header;
+ struct log_header_core header;
struct dm_io_region header_location;
- struct log_header *disk_header;
+ struct log_header_disk *disk_header;
};
/*
@@ -271,14 +277,14 @@ static inline void log_clear_bit(struct log_c *l,
/*----------------------------------------------------------------
* Header IO
*--------------------------------------------------------------*/
-static void header_to_disk(struct log_header *core, struct log_header *disk)
+static void header_to_disk(struct log_header_core *core, struct log_header_disk *disk)
{
disk->magic = cpu_to_le32(core->magic);
disk->version = cpu_to_le32(core->version);
disk->nr_regions = cpu_to_le64(core->nr_regions);
}
-static void header_from_disk(struct log_header *core, struct log_header *disk)
+static void header_from_disk(struct log_header_core *core, struct log_header_disk *disk)
{
core->magic = le32_to_cpu(disk->magic);
core->version = le32_to_cpu(disk->version);
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 70373bf..d13c431 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -22,7 +22,6 @@
#include <asm/atomic.h>
#define DM_MSG_PREFIX "multipath"
-#define MESG_STR(x) x, sizeof(x)
#define DM_PG_INIT_DELAY_MSECS 2000
#define DM_PG_INIT_DELAY_DEFAULT ((unsigned) -1)
@@ -505,80 +504,29 @@ static void trigger_event(struct work_struct *work)
* <#paths> <#per-path selector args>
* [<path> [<arg>]* ]+ ]+
*---------------------------------------------------------------*/
-struct param {
- unsigned min;
- unsigned max;
- char *error;
-};
-
-static int read_param(struct param *param, char *str, unsigned *v, char **error)
-{
- if (!str ||
- (sscanf(str, "%u", v) != 1) ||
- (*v < param->min) ||
- (*v > param->max)) {
- *error = param->error;
- return -EINVAL;
- }
-
- return 0;
-}
-
-struct arg_set {
- unsigned argc;
- char **argv;
-};
-
-static char *shift(struct arg_set *as)
-{
- char *r;
-
- if (as->argc) {
- as->argc--;
- r = *as->argv;
- as->argv++;
- return r;
- }
-
- return NULL;
-}
-
-static void consume(struct arg_set *as, unsigned n)
-{
- BUG_ON (as->argc < n);
- as->argc -= n;
- as->argv += n;
-}
-
-static int parse_path_selector(struct arg_set *as, struct priority_group *pg,
+static int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg,
struct dm_target *ti)
{
int r;
struct path_selector_type *pst;
unsigned ps_argc;
- static struct param _params[] = {
+ static struct dm_arg _args[] = {
{0, 1024, "invalid number of path selector args"},
};
- pst = dm_get_path_selector(shift(as));
+ pst = dm_get_path_selector(dm_shift_arg(as));
if (!pst) {
ti->error = "unknown path selector type";
return -EINVAL;
}
- r = read_param(_params, shift(as), &ps_argc, &ti->error);
+ r = dm_read_arg_group(_args, as, &ps_argc, &ti->error);
if (r) {
dm_put_path_selector(pst);
return -EINVAL;
}
- if (ps_argc > as->argc) {
- dm_put_path_selector(pst);
- ti->error = "not enough arguments for path selector";
- return -EINVAL;
- }
-
r = pst->create(&pg->ps, ps_argc, as->argv);
if (r) {
dm_put_path_selector(pst);
@@ -587,12 +535,12 @@ static int parse_path_selector(struct arg_set *as, struct priority_group *pg,
}
pg->ps.type = pst;
- consume(as, ps_argc);
+ dm_consume_args(as, ps_argc);
return 0;
}
-static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
+static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps,
struct dm_target *ti)
{
int r;
@@ -609,7 +557,7 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
if (!p)
return ERR_PTR(-ENOMEM);
- r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table),
+ r = dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table),
&p->path.dev);
if (r) {
ti->error = "error getting device";
@@ -660,16 +608,16 @@ static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps,
return ERR_PTR(r);
}
-static struct priority_group *parse_priority_group(struct arg_set *as,
+static struct priority_group *parse_priority_group(struct dm_arg_set *as,
struct multipath *m)
{
- static struct param _params[] = {
+ static struct dm_arg _args[] = {
{1, 1024, "invalid number of paths"},
{0, 1024, "invalid number of selector args"}
};
int r;
- unsigned i, nr_selector_args, nr_params;
+ unsigned i, nr_selector_args, nr_args;
struct priority_group *pg;
struct dm_target *ti = m->ti;
@@ -693,26 +641,26 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
/*
* read the paths
*/
- r = read_param(_params, shift(as), &pg->nr_pgpaths, &ti->error);
+ r = dm_read_arg(_args, as, &pg->nr_pgpaths, &ti->error);
if (r)
goto bad;
- r = read_param(_params + 1, shift(as), &nr_selector_args, &ti->error);
+ r = dm_read_arg(_args + 1, as, &nr_selector_args, &ti->error);
if (r)
goto bad;
- nr_params = 1 + nr_selector_args;
+ nr_args = 1 + nr_selector_args;
for (i = 0; i < pg->nr_pgpaths; i++) {
struct pgpath *pgpath;
- struct arg_set path_args;
+ struct dm_arg_set path_args;
- if (as->argc < nr_params) {
+ if (as->argc < nr_args) {
ti->error = "not enough path parameters";
r = -EINVAL;
goto bad;
}
- path_args.argc = nr_params;
+ path_args.argc = nr_args;
path_args.argv = as->argv;
pgpath = parse_path(&path_args, &pg->ps, ti);
@@ -723,7 +671,7 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
pgpath->pg = pg;
list_add_tail(&pgpath->list, &pg->pgpaths);
- consume(as, nr_params);
+ dm_consume_args(as, nr_args);
}
return pg;
@@ -733,28 +681,23 @@ static struct priority_group *parse_priority_group(struct arg_set *as,
return ERR_PTR(r);
}
-static int parse_hw_handler(struct arg_set *as, struct multipath *m)
+static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
{
unsigned hw_argc;
int ret;
struct dm_target *ti = m->ti;
- static struct param _params[] = {
+ static struct dm_arg _args[] = {
{0, 1024, "invalid number of hardware handler args"},
};
- if (read_param(_params, shift(as), &hw_argc, &ti->error))
+ if (dm_read_arg_group(_args, as, &hw_argc, &ti->error))
return -EINVAL;
if (!hw_argc)
return 0;
- if (hw_argc > as->argc) {
- ti->error = "not enough arguments for hardware handler";
- return -EINVAL;
- }
-
- m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL);
+ m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL);
request_module("scsi_dh_%s", m->hw_handler_name);
if (scsi_dh_handler_exist(m->hw_handler_name) == 0) {
ti->error = "unknown hardware handler type";
@@ -778,7 +721,7 @@ static int parse_hw_handler(struct arg_set *as, struct multipath *m)
for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1)
j = sprintf(p, "%s", as->argv[i]);
}
- consume(as, hw_argc - 1);
+ dm_consume_args(as, hw_argc - 1);
return 0;
fail:
@@ -787,52 +730,45 @@ fail:
return ret;
}
-static int parse_features(struct arg_set *as, struct multipath *m)
+static int parse_features(struct dm_arg_set *as, struct multipath *m)
{
int r;
unsigned argc;
struct dm_target *ti = m->ti;
- const char *param_name;
+ const char *arg_name;
- static struct param _params[] = {
+ static struct dm_arg _args[] = {
{0, 5, "invalid number of feature args"},
{1, 50, "pg_init_retries must be between 1 and 50"},
{0, 60000, "pg_init_delay_msecs must be between 0 and 60000"},
};
- r = read_param(_params, shift(as), &argc, &ti->error);
+ r = dm_read_arg_group(_args, as, &argc, &ti->error);
if (r)
return -EINVAL;
if (!argc)
return 0;
- if (argc > as->argc) {
- ti->error = "not enough arguments for features";
- return -EINVAL;
- }
-
do {
- param_name = shift(as);
+ arg_name = dm_shift_arg(as);
argc--;
- if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) {
+ if (!strcasecmp(arg_name, "queue_if_no_path")) {
r = queue_if_no_path(m, 1, 0);
continue;
}
- if (!strnicmp(param_name, MESG_STR("pg_init_retries")) &&
+ if (!strcasecmp(arg_name, "pg_init_retries") &&
(argc >= 1)) {
- r = read_param(_params + 1, shift(as),
- &m->pg_init_retries, &ti->error);
+ r = dm_read_arg(_args + 1, as, &m->pg_init_retries, &ti->error);
argc--;
continue;
}
- if (!strnicmp(param_name, MESG_STR("pg_init_delay_msecs")) &&
+ if (!strcasecmp(arg_name, "pg_init_delay_msecs") &&
(argc >= 1)) {
- r = read_param(_params + 2, shift(as),
- &m->pg_init_delay_msecs, &ti->error);
+ r = dm_read_arg(_args + 2, as, &m->pg_init_delay_msecs, &ti->error);
argc--;
continue;
}
@@ -847,15 +783,15 @@ static int parse_features(struct arg_set *as, struct multipath *m)
static int multipath_ctr(struct dm_target *ti, unsigned int argc,
char **argv)
{
- /* target parameters */
- static struct param _params[] = {
+ /* target arguments */
+ static struct dm_arg _args[] = {
{0, 1024, "invalid number of priority groups"},
{0, 1024, "invalid initial priority group number"},
};
int r;
struct multipath *m;
- struct arg_set as;
+ struct dm_arg_set as;
unsigned pg_count = 0;
unsigned next_pg_num;
@@ -876,11 +812,11 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc,
if (r)
goto bad;
- r = read_param(_params, shift(&as), &m->nr_priority_groups, &ti->error);
+ r = dm_read_arg(_args, &as, &m->nr_priority_groups, &ti->error);
if (r)
goto bad;
- r = read_param(_params + 1, shift(&as), &next_pg_num, &ti->error);
+ r = dm_read_arg(_args + 1, &as, &next_pg_num, &ti->error);
if (r)
goto bad;
@@ -1510,10 +1446,10 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
}
if (argc == 1) {
- if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) {
+ if (!strcasecmp(argv[0], "queue_if_no_path")) {
r = queue_if_no_path(m, 1, 0);
goto out;
- } else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) {
+ } else if (!strcasecmp(argv[0], "fail_if_no_path")) {
r = queue_if_no_path(m, 0, 0);
goto out;
}
@@ -1524,18 +1460,18 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv)
goto out;
}
- if (!strnicmp(argv[0], MESG_STR("disable_group"))) {
+ if (!strcasecmp(argv[0], "disable_group")) {
r = bypass_pg_num(m, argv[1], 1);
goto out;
- } else if (!strnicmp(argv[0], MESG_STR("enable_group"))) {
+ } else if (!strcasecmp(argv[0], "enable_group")) {
r = bypass_pg_num(m, argv[1], 0);
goto out;
- } else if (!strnicmp(argv[0], MESG_STR("switch_group"))) {
+ } else if (!strcasecmp(argv[0], "switch_group")) {
r = switch_pg_num(m, argv[1]);
goto out;
- } else if (!strnicmp(argv[0], MESG_STR("reinstate_path")))
+ } else if (!strcasecmp(argv[0], "reinstate_path"))
action = reinstate_path;
- else if (!strnicmp(argv[0], MESG_STR("fail_path")))
+ else if (!strcasecmp(argv[0], "fail_path"))
action = fail_path;
else {
DMWARN("Unrecognised multipath message received.");
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index e4ecadf..39becbe 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -58,25 +58,30 @@
#define NUM_SNAPSHOT_HDR_CHUNKS 1
struct disk_header {
- uint32_t magic;
+ __le32 magic;
/*
* Is this snapshot valid. There is no way of recovering
* an invalid snapshot.
*/
- uint32_t valid;
+ __le32 valid;
/*
* Simple, incrementing version. no backward
* compatibility.
*/
- uint32_t version;
+ __le32 version;
/* In sectors */
- uint32_t chunk_size;
-};
+ __le32 chunk_size;
+} __packed;
struct disk_exception {
+ __le64 old_chunk;
+ __le64 new_chunk;
+} __packed;
+
+struct core_exception {
uint64_t old_chunk;
uint64_t new_chunk;
};
@@ -396,32 +401,32 @@ static struct disk_exception *get_exception(struct pstore *ps, uint32_t index)
}
static void read_exception(struct pstore *ps,
- uint32_t index, struct disk_exception *result)
+ uint32_t index, struct core_exception *result)
{
- struct disk_exception *e = get_exception(ps, index);
+ struct disk_exception *de = get_exception(ps, index);
/* copy it */
- result->old_chunk = le64_to_cpu(e->old_chunk);
- result->new_chunk = le64_to_cpu(e->new_chunk);
+ result->old_chunk = le64_to_cpu(de->old_chunk);
+ result->new_chunk = le64_to_cpu(de->new_chunk);
}
static void write_exception(struct pstore *ps,
- uint32_t index, struct disk_exception *de)
+ uint32_t index, struct core_exception *e)
{
- struct disk_exception *e = get_exception(ps, index);
+ struct disk_exception *de = get_exception(ps, index);
/* copy it */
- e->old_chunk = cpu_to_le64(de->old_chunk);
- e->new_chunk = cpu_to_le64(de->new_chunk);
+ de->old_chunk = cpu_to_le64(e->old_chunk);
+ de->new_chunk = cpu_to_le64(e->new_chunk);
}
static void clear_exception(struct pstore *ps, uint32_t index)
{
- struct disk_exception *e = get_exception(ps, index);
+ struct disk_exception *de = get_exception(ps, index);
/* clear it */
- e->old_chunk = 0;
- e->new_chunk = 0;
+ de->old_chunk = 0;
+ de->new_chunk = 0;
}
/*
@@ -437,13 +442,13 @@ static int insert_exceptions(struct pstore *ps,
{
int r;
unsigned int i;
- struct disk_exception de;
+ struct core_exception e;
/* presume the area is full */
*full = 1;
for (i = 0; i < ps->exceptions_per_area; i++) {
- read_exception(ps, i, &de);
+ read_exception(ps, i, &e);
/*
* If the new_chunk is pointing at the start of
@@ -451,7 +456,7 @@ static int insert_exceptions(struct pstore *ps,
* is we know that we've hit the end of the
* exceptions. Therefore the area is not full.
*/
- if (de.new_chunk == 0LL) {
+ if (e.new_chunk == 0LL) {
ps->current_committed = i;
*full = 0;
break;
@@ -460,13 +465,13 @@ static int insert_exceptions(struct pstore *ps,
/*
* Keep track of the start of the free chunks.
*/
- if (ps->next_free <= de.new_chunk)
- ps->next_free = de.new_chunk + 1;
+ if (ps->next_free <= e.new_chunk)
+ ps->next_free = e.new_chunk + 1;
/*
* Otherwise we add the exception to the snapshot.
*/
- r = callback(callback_context, de.old_chunk, de.new_chunk);
+ r = callback(callback_context, e.old_chunk, e.new_chunk);
if (r)
return r;
}
@@ -641,12 +646,12 @@ static void persistent_commit_exception(struct dm_exception_store *store,
{
unsigned int i;
struct pstore *ps = get_info(store);
- struct disk_exception de;
+ struct core_exception ce;
struct commit_callback *cb;
- de.old_chunk = e->old_chunk;
- de.new_chunk = e->new_chunk;
- write_exception(ps, ps->current_committed++, &de);
+ ce.old_chunk = e->old_chunk;
+ ce.new_chunk = e->new_chunk;
+ write_exception(ps, ps->current_committed++, &ce);
/*
* Add the callback to the back of the array. This code
@@ -701,7 +706,7 @@ static int persistent_prepare_merge(struct dm_exception_store *store,
chunk_t *last_new_chunk)
{
struct pstore *ps = get_info(store);
- struct disk_exception de;
+ struct core_exception ce;
int nr_consecutive;
int r;
@@ -722,9 +727,9 @@ static int persistent_prepare_merge(struct dm_exception_store *store,
ps->current_committed = ps->exceptions_per_area;
}
- read_exception(ps, ps->current_committed - 1, &de);
- *last_old_chunk = de.old_chunk;
- *last_new_chunk = de.new_chunk;
+ read_exception(ps, ps->current_committed - 1, &ce);
+ *last_old_chunk = ce.old_chunk;
+ *last_new_chunk = ce.new_chunk;
/*
* Find number of consecutive chunks within the current area,
@@ -733,9 +738,9 @@ static int persistent_prepare_merge(struct dm_exception_store *store,
for (nr_consecutive = 1; nr_consecutive < ps->current_committed;
nr_consecutive++) {
read_exception(ps, ps->current_committed - 1 - nr_consecutive,
- &de);
- if (de.old_chunk != *last_old_chunk - nr_consecutive ||
- de.new_chunk != *last_new_chunk - nr_consecutive)
+ &ce);
+ if (ce.old_chunk != *last_old_chunk - nr_consecutive ||
+ ce.new_chunk != *last_new_chunk - nr_consecutive)
break;
}
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index ebdae6e..92cd686 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -539,8 +539,7 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev,
* If not we'll force DM to use PAGE_SIZE or
* smaller I/O, just to be safe.
*/
-
- if (q->merge_bvec_fn && !ti->type->merge)
+ if (dm_queue_merge_is_compulsory(q) && !ti->type->merge)
blk_limits_max_hw_sectors(limits,
(unsigned int) (PAGE_SIZE >> 9));
return 0;
@@ -802,6 +801,63 @@ int dm_table_add_target(struct dm_table *t, const char *type,
return r;
}
+/*
+ * Target argument parsing helpers.
+ */
+static int validate_next_arg(struct dm_arg *arg, struct dm_arg_set *arg_set,
+ unsigned *value, char **error, unsigned grouped)
+{
+ const char *arg_str = dm_shift_arg(arg_set);
+
+ if (!arg_str ||
+ (sscanf(arg_str, "%u", value) != 1) ||
+ (*value < arg->min) ||
+ (*value > arg->max) ||
+ (grouped && arg_set->argc < *value)) {
+ *error = arg->error;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set,
+ unsigned *value, char **error)
+{
+ return validate_next_arg(arg, arg_set, value, error, 0);
+}
+EXPORT_SYMBOL(dm_read_arg);
+
+int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set,
+ unsigned *value, char **error)
+{
+ return validate_next_arg(arg, arg_set, value, error, 1);
+}
+EXPORT_SYMBOL(dm_read_arg_group);
+
+const char *dm_shift_arg(struct dm_arg_set *as)
+{
+ char *r;
+
+ if (as->argc) {
+ as->argc--;
+ r = *as->argv;
+ as->argv++;
+ return r;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(dm_shift_arg);
+
+void dm_consume_args(struct dm_arg_set *as, unsigned num_args)
+{
+ BUG_ON(as->argc < num_args);
+ as->argc -= num_args;
+ as->argv += num_args;
+}
+EXPORT_SYMBOL(dm_consume_args);
+
static int dm_table_set_type(struct dm_table *t)
{
unsigned i;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 9f472d5..1eeef9c 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -111,6 +111,7 @@ EXPORT_SYMBOL_GPL(dm_get_rq_mapinfo);
#define DMF_FREEING 3
#define DMF_DELETING 4
#define DMF_NOFLUSH_SUSPENDING 5
+#define DMF_MERGE_IS_OPTIONAL 6
/*
* Work processed by per-device workqueue.
@@ -2018,6 +2019,59 @@ static void __set_size(struct mapped_device *md, sector_t size)
}
/*
+ * Return 1 if the queue has a compulsory merge_bvec_fn function.
+ *
+ * If this function returns 0, then the device is either a non-dm
+ * device without a merge_bvec_fn, or it is a dm device that is
+ * able to split any bios it receives that are too big.
+ */
+int dm_queue_merge_is_compulsory(struct request_queue *q)
+{
+ struct mapped_device *dev_md;
+
+ if (!q->merge_bvec_fn)
+ return 0;
+
+ if (q->make_request_fn == dm_request) {
+ dev_md = q->queuedata;
+ if (test_bit(DMF_MERGE_IS_OPTIONAL, &dev_md->flags))
+ return 0;
+ }
+
+ return 1;
+}
+
+static int dm_device_merge_is_compulsory(struct dm_target *ti,
+ struct dm_dev *dev, sector_t start,
+ sector_t len, void *data)
+{
+ struct block_device *bdev = dev->bdev;
+ struct request_queue *q = bdev_get_queue(bdev);
+
+ return dm_queue_merge_is_compulsory(q);
+}
+
+/*
+ * Return 1 if it is acceptable to ignore merge_bvec_fn based
+ * on the properties of the underlying devices.
+ */
+static int dm_table_merge_is_optional(struct dm_table *table)
+{
+ unsigned i = 0;
+ struct dm_target *ti;
+
+ while (i < dm_table_get_num_targets(table)) {
+ ti = dm_table_get_target(table, i++);
+
+ if (ti->type->iterate_devices &&
+ ti->type->iterate_devices(ti, dm_device_merge_is_compulsory, NULL))
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
* Returns old map, which caller must destroy.
*/
static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
@@ -2027,6 +2081,7 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
struct request_queue *q = md->queue;
sector_t size;
unsigned long flags;
+ int merge_is_optional;
size = dm_table_get_size(t);
@@ -2052,10 +2107,16 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t,
__bind_mempools(md, t);
+ merge_is_optional = dm_table_merge_is_optional(t);
+
write_lock_irqsave(&md->map_lock, flags);
old_map = md->map;
md->map = t;
dm_table_set_restrictions(t, q, limits);
+ if (merge_is_optional)
+ set_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
+ else
+ clear_bit(DMF_MERGE_IS_OPTIONAL, &md->flags);
write_unlock_irqrestore(&md->map_lock, flags);
return old_map;
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 1aaf167..6745dbd 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -66,6 +66,8 @@ int dm_table_alloc_md_mempools(struct dm_table *t);
void dm_table_free_md_mempools(struct dm_table *t);
struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t);
+int dm_queue_merge_is_compulsory(struct request_queue *q);
+
void dm_lock_md_type(struct mapped_device *md);
void dm_unlock_md_type(struct mapped_device *md);
void dm_set_md_type(struct mapped_device *md, unsigned type);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index aeedd90..cc7c047 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -652,6 +652,15 @@ config VIDEO_SLP_S5C73M3
---help---
This driver supports s5c73m3 ISP camera module with MIPI CSI-2 as well
+config VIDEO_SR130PC20
+ tristate "SR130PC20 camera driver"
+ depends on I2C && VIDEO_V4L2
+ ---help---
+ This driver supports SR130PC20 SoC camera module.
+ The SR130PC20 camera module uses siliconfile camera sensor
+ supporting 1.3M capture with MIPI interface. And also, It support
+ VGA recording with 25fps.
+
config VIDEO_IMPROVE_STREAMOFF
bool "Improve shtter lag"
depends on VIDEO_FIMC_MIPI
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 64f0f5b..7ce4839 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -92,6 +92,7 @@ obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3.o
obj-$(CONFIG_VIDEO_ISX012) += isx012.o
obj-$(CONFIG_VIDEO_S5C73M3_SPI) += s5c73m3_spi.o
+obj-$(CONFIG_VIDEO_SR130PC20) += sr130pc20.o
obj-$(CONFIG_VIDEO_SLP_S5C73M3) += slp_s5c73m3.o
obj-$(CONFIG_VIDEO_SLP_S5K4ECGX) += slp_s5k4ecgx.o
obj-$(CONFIG_VIDEO_SLP_DB8131M) += slp_db8131m.o
diff --git a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c
index 011787c..0a10f2e 100644
--- a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c
+++ b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.c
@@ -122,7 +122,7 @@ static struct flite_fmt *find_format(u32 *pixelformat, u32 *mbus_code, int index
}
#endif
-inline struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf)
+struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf)
{
int num_fmt = ARRAY_SIZE(flite_formats);
diff --git a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h
index 2c46c8b..a8a0a2e 100644
--- a/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h
+++ b/drivers/media/video/exynos/fimc-lite/fimc-lite-core.h
@@ -295,7 +295,7 @@ static inline void user_to_drv(struct v4l2_ctrl *ctrl, s32 value)
ctrl->cur.val = ctrl->val = value;
}
-inline struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf);
+struct flite_fmt const *find_flite_format(struct v4l2_mbus_framefmt *mf);
/*
* Add buf to the capture active buffers queue.
diff --git a/drivers/media/video/isx012.c b/drivers/media/video/isx012.c
index 427d59b..e33a430 100644
--- a/drivers/media/video/isx012.c
+++ b/drivers/media/video/isx012.c
@@ -28,6 +28,7 @@
#define isx012_wait_ae_stable_cap(sd) isx012_wait_ae_stable(sd, false, false)
static int dbg_level;
+static u32 VendorID;
static const struct isx012_fps isx012_framerates[] = {
{ I_FPS_0, FRAME_RATE_AUTO },
@@ -42,6 +43,11 @@ static const struct isx012_framesize isx012_preview_frmsizes[] = {
{ PREVIEW_SZ_320x240, 320, 240 },
{ PREVIEW_SZ_CIF, 352, 288 },
{ PREVIEW_SZ_528x432, 528, 432 },
+#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/
+ { PREVIEW_SZ_VERTICAL_VGA, 480, 640 },
+#endif
{ PREVIEW_SZ_VGA, 640, 480 },
{ PREVIEW_SZ_D1, 720, 480 },
{ PREVIEW_SZ_880x720, 880, 720 },
@@ -83,154 +89,167 @@ static struct isx012_control isx012_ctrls[] = {
static const struct isx012_regs reg_datas = {
.ev = {
ISX012_REGSET(GET_EV_INDEX(EV_MINUS_4),
- ISX012_ExpSetting_M4Step),
+ ISX012_ExpSetting_M4Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_MINUS_3),
- ISX012_ExpSetting_M3Step),
+ ISX012_ExpSetting_M3Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_MINUS_2),
- ISX012_ExpSetting_M2Step),
+ ISX012_ExpSetting_M2Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_MINUS_1),
- ISX012_ExpSetting_M1Step),
+ ISX012_ExpSetting_M1Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_DEFAULT),
- ISX012_ExpSetting_Default),
+ ISX012_ExpSetting_Default, 0),
ISX012_REGSET(GET_EV_INDEX(EV_PLUS_1),
- ISX012_ExpSetting_P1Step),
+ ISX012_ExpSetting_P1Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_PLUS_2),
- ISX012_ExpSetting_P2Step),
+ ISX012_ExpSetting_P2Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_PLUS_3),
- ISX012_ExpSetting_P3Step),
+ ISX012_ExpSetting_P3Step, 0),
ISX012_REGSET(GET_EV_INDEX(EV_PLUS_4),
- ISX012_ExpSetting_P4Step),
+ ISX012_ExpSetting_P4Step, 0),
},
.metering = {
- ISX012_REGSET(METERING_MATRIX, isx012_Metering_Matrix),
- ISX012_REGSET(METERING_CENTER, isx012_Metering_Center),
- ISX012_REGSET(METERING_SPOT, isx012_Metering_Spot),
+ ISX012_REGSET(METERING_MATRIX, isx012_Metering_Matrix, 0),
+ ISX012_REGSET(METERING_CENTER, isx012_Metering_Center, 0),
+ ISX012_REGSET(METERING_SPOT, isx012_Metering_Spot, 0),
},
.iso = {
- ISX012_REGSET(ISO_AUTO, isx012_ISO_Auto),
- ISX012_REGSET(ISO_50, isx012_ISO_50),
- ISX012_REGSET(ISO_100, isx012_ISO_100),
- ISX012_REGSET(ISO_200, isx012_ISO_200),
- ISX012_REGSET(ISO_400, isx012_ISO_400),
+ ISX012_REGSET(ISO_AUTO, isx012_ISO_Auto, 0),
+ ISX012_REGSET(ISO_50, isx012_ISO_50, 0),
+ ISX012_REGSET(ISO_100, isx012_ISO_100, 0),
+ ISX012_REGSET(ISO_200, isx012_ISO_200, 0),
+ ISX012_REGSET(ISO_400, isx012_ISO_400, 0),
},
.effect = {
- ISX012_REGSET(IMAGE_EFFECT_NONE, isx012_Effect_Normal),
- ISX012_REGSET(IMAGE_EFFECT_BNW, isx012_Effect_Black_White),
- ISX012_REGSET(IMAGE_EFFECT_SEPIA, isx012_Effect_Sepia),
+ ISX012_REGSET(IMAGE_EFFECT_NONE, isx012_Effect_Normal, 0),
+ ISX012_REGSET(IMAGE_EFFECT_BNW, isx012_Effect_Black_White, 0),
+ ISX012_REGSET(IMAGE_EFFECT_SEPIA, isx012_Effect_Sepia, 0),
ISX012_REGSET(IMAGE_EFFECT_NEGATIVE,
- ISX012_Effect_Negative),
- ISX012_REGSET(IMAGE_EFFECT_SOLARIZE, isx012_Effect_Solar),
- ISX012_REGSET(IMAGE_EFFECT_SKETCH, isx012_Effect_Sketch),
- ISX012_REGSET(IMAGE_EFFECT_POINT_COLOR_3, isx012_Effect_Pastel),
+ ISX012_Effect_Negative, 0),
+ ISX012_REGSET(IMAGE_EFFECT_SOLARIZE, isx012_Effect_Solar, 0),
+ ISX012_REGSET(IMAGE_EFFECT_SKETCH, isx012_Effect_Sketch, 0),
+ ISX012_REGSET(IMAGE_EFFECT_POINT_COLOR_3,
+ isx012_Effect_Pastel, 0),
},
.white_balance = {
- ISX012_REGSET(WHITE_BALANCE_AUTO, isx012_WB_Auto),
- ISX012_REGSET(WHITE_BALANCE_SUNNY, isx012_WB_Sunny),
- ISX012_REGSET(WHITE_BALANCE_CLOUDY, isx012_WB_Cloudy),
+ ISX012_REGSET(WHITE_BALANCE_AUTO, isx012_WB_Auto, 0),
+ ISX012_REGSET(WHITE_BALANCE_SUNNY, isx012_WB_Sunny, 0),
+ ISX012_REGSET(WHITE_BALANCE_CLOUDY, isx012_WB_Cloudy, 0),
ISX012_REGSET(WHITE_BALANCE_TUNGSTEN,
- isx012_WB_Tungsten),
+ isx012_WB_Tungsten, 0),
ISX012_REGSET(WHITE_BALANCE_FLUORESCENT,
- isx012_WB_Fluorescent),
+ isx012_WB_Fluorescent, 0),
},
.scene_mode = {
- ISX012_REGSET(SCENE_MODE_NONE, isx012_Scene_Default),
- ISX012_REGSET(SCENE_MODE_PORTRAIT, isx012_Scene_Portrait),
- ISX012_REGSET(SCENE_MODE_NIGHTSHOT, isx012_Scene_Nightshot),
- ISX012_REGSET(SCENE_MODE_BACK_LIGHT, isx012_Scene_Backlight),
- ISX012_REGSET(SCENE_MODE_LANDSCAPE, isx012_Scene_Landscape),
- ISX012_REGSET(SCENE_MODE_SPORTS, isx012_Scene_Sports),
+ ISX012_REGSET(SCENE_MODE_NONE, isx012_Scene_Default, 0),
+ ISX012_REGSET(SCENE_MODE_PORTRAIT, isx012_Scene_Portrait, 0),
+ ISX012_REGSET(SCENE_MODE_NIGHTSHOT, isx012_Scene_Nightshot, 0),
+ ISX012_REGSET(SCENE_MODE_BACK_LIGHT, isx012_Scene_Backlight, 0),
+ ISX012_REGSET(SCENE_MODE_LANDSCAPE, isx012_Scene_Landscape, 0),
+ ISX012_REGSET(SCENE_MODE_SPORTS, isx012_Scene_Sports, 0),
ISX012_REGSET(SCENE_MODE_PARTY_INDOOR,
- isx012_Scene_Party_Indoor),
- ISX012_REGSET(SCENE_MODE_BEACH_SNOW, isx012_Scene_Beach_Snow),
- ISX012_REGSET(SCENE_MODE_SUNSET, isx012_Scene_Sunset),
- ISX012_REGSET(SCENE_MODE_DUSK_DAWN, isx012_Scene_Duskdawn),
- ISX012_REGSET(SCENE_MODE_FALL_COLOR, isx012_Scene_Fall_Color),
- ISX012_REGSET(SCENE_MODE_FIREWORKS, isx012_Scene_Fireworks),
- ISX012_REGSET(SCENE_MODE_TEXT, isx012_Scene_Text),
+ isx012_Scene_Party_Indoor, 0),
+ ISX012_REGSET(SCENE_MODE_BEACH_SNOW,
+ isx012_Scene_Beach_Snow, 0),
+ ISX012_REGSET(SCENE_MODE_SUNSET, isx012_Scene_Sunset, 0),
+ ISX012_REGSET(SCENE_MODE_DUSK_DAWN, isx012_Scene_Duskdawn, 0),
+ ISX012_REGSET(SCENE_MODE_FALL_COLOR,
+ isx012_Scene_Fall_Color, 0),
+ ISX012_REGSET(SCENE_MODE_FIREWORKS, isx012_Scene_Fireworks, 0),
+ ISX012_REGSET(SCENE_MODE_TEXT, isx012_Scene_Text, 0),
ISX012_REGSET(SCENE_MODE_CANDLE_LIGHT,
- isx012_Scene_Candle_Light),
+ isx012_Scene_Candle_Light, 0),
},
.saturation = {
- ISX012_REGSET(SATURATION_MINUS_2, isx012_Saturation_Minus_2),
- ISX012_REGSET(SATURATION_MINUS_1, isx012_Saturation_Minus_1),
- ISX012_REGSET(SATURATION_DEFAULT, isx012_Saturation_Default),
- ISX012_REGSET(SATURATION_PLUS_1, isx012_Saturation_Plus_1),
- ISX012_REGSET(SATURATION_PLUS_2, isx012_Saturation_Plus_2),
+ ISX012_REGSET(SATURATION_MINUS_2, isx012_Saturation_Minus_2, 0),
+ ISX012_REGSET(SATURATION_MINUS_1, isx012_Saturation_Minus_1, 0),
+ ISX012_REGSET(SATURATION_DEFAULT, isx012_Saturation_Default, 0),
+ ISX012_REGSET(SATURATION_PLUS_1, isx012_Saturation_Plus_1, 0),
+ ISX012_REGSET(SATURATION_PLUS_2, isx012_Saturation_Plus_2, 0),
},
.contrast = {
- ISX012_REGSET(CONTRAST_MINUS_2, isx012_Contrast_Minus_2),
- ISX012_REGSET(CONTRAST_MINUS_1, isx012_Contrast_Minus_1),
- ISX012_REGSET(CONTRAST_DEFAULT, isx012_Contrast_Default),
- ISX012_REGSET(CONTRAST_PLUS_1, isx012_Contrast_Plus_1),
- ISX012_REGSET(CONTRAST_PLUS_2, isx012_Contrast_Plus_2),
+ ISX012_REGSET(CONTRAST_MINUS_2, isx012_Contrast_Minus_2, 0),
+ ISX012_REGSET(CONTRAST_MINUS_1, isx012_Contrast_Minus_1, 0),
+ ISX012_REGSET(CONTRAST_DEFAULT, isx012_Contrast_Default, 0),
+ ISX012_REGSET(CONTRAST_PLUS_1, isx012_Contrast_Plus_1, 0),
+ ISX012_REGSET(CONTRAST_PLUS_2, isx012_Contrast_Plus_2, 0),
},
.sharpness = {
- ISX012_REGSET(SHARPNESS_MINUS_2, isx012_Sharpness_Minus_2),
- ISX012_REGSET(SHARPNESS_MINUS_1, isx012_Sharpness_Minus_1),
- ISX012_REGSET(SHARPNESS_DEFAULT, isx012_Sharpness_Default),
- ISX012_REGSET(SHARPNESS_PLUS_1, isx012_Sharpness_Plus_1),
- ISX012_REGSET(SHARPNESS_PLUS_2, isx012_Sharpness_Plus_2),
+ ISX012_REGSET(SHARPNESS_MINUS_2, isx012_Sharpness_Minus_2, 0),
+ ISX012_REGSET(SHARPNESS_MINUS_1, isx012_Sharpness_Minus_1, 0),
+ ISX012_REGSET(SHARPNESS_DEFAULT, isx012_Sharpness_Default, 0),
+ ISX012_REGSET(SHARPNESS_PLUS_1, isx012_Sharpness_Plus_1, 0),
+ ISX012_REGSET(SHARPNESS_PLUS_2, isx012_Sharpness_Plus_2, 0),
},
.fps = {
- ISX012_REGSET(I_FPS_0, isx012_fps_auto),
- ISX012_REGSET(I_FPS_7, isx012_fps_7fix),
- ISX012_REGSET(I_FPS_15, isx012_fps_15fix),
- ISX012_REGSET(I_FPS_25, isx012_fps_25fix),
- ISX012_REGSET(I_FPS_30, isx012_fps_30fix),
+ ISX012_REGSET(I_FPS_0, isx012_fps_auto, 0),
+ ISX012_REGSET(I_FPS_7, isx012_fps_7fix, 0),
+ ISX012_REGSET(I_FPS_15, isx012_fps_15fix, 0),
+ ISX012_REGSET(I_FPS_25, isx012_fps_25fix, 0),
+ ISX012_REGSET(I_FPS_30, isx012_fps_30fix, 0),
},
.preview_size = {
- ISX012_REGSET(PREVIEW_SZ_320x240, isx012_320_Preview),
- ISX012_REGSET(PREVIEW_SZ_VGA, isx012_640_Preview),
- ISX012_REGSET(PREVIEW_SZ_D1, isx012_720_Preview),
- ISX012_REGSET(PREVIEW_SZ_XGA, isx012_1024_768_Preview),
- ISX012_REGSET(PREVIEW_SZ_PVGA, isx012_1280_Preview_E),
+ ISX012_REGSET(PREVIEW_SZ_320x240, isx012_320_Preview, 0),
+#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/
+ ISX012_REGSET(PREVIEW_SZ_VERTICAL_VGA, isx012_480_Preview, 0),
+#endif
+ ISX012_REGSET(PREVIEW_SZ_VGA, isx012_640_Preview, 0),
+ ISX012_REGSET(PREVIEW_SZ_D1, isx012_720_Preview, 0),
+ ISX012_REGSET(PREVIEW_SZ_XGA, isx012_1024_768_Preview, 0),
+ ISX012_REGSET(PREVIEW_SZ_PVGA, isx012_1280_Preview_E, 0),
},
.capture_size = {
- ISX012_REGSET(CAPTURE_SZ_VGA, isx012_VGA_Capture),
- ISX012_REGSET(CAPTURE_SZ_960_720, isx012_960_720_Capture),
- ISX012_REGSET(CAPTURE_SZ_3MP, isx012_3M_Capture),
- ISX012_REGSET(CAPTURE_SZ_5MP, isx012_5M_Capture),
+ ISX012_REGSET(CAPTURE_SZ_VGA, isx012_VGA_Capture, 0),
+ ISX012_REGSET(CAPTURE_SZ_960_720, isx012_960_720_Capture, 0),
+ ISX012_REGSET(CAPTURE_SZ_3MP, isx012_3M_Capture, 0),
+ ISX012_REGSET(CAPTURE_SZ_5MP, isx012_5M_Capture, 0),
},
/* AF */
- .af_window_reset = ISX012_REGSET_TABLE(ISX012_AF_Window_Reset),
- .af_winddow_set = ISX012_REGSET_TABLE(ISX012_AF_Window_Set),
- .af_restart = ISX012_REGSET_TABLE(ISX012_AF_ReStart),
- .af_saf_off = ISX012_REGSET_TABLE(ISX012_AF_SAF_OFF),
- .af_touch_saf_off = ISX012_REGSET_TABLE(ISX012_AF_TouchSAF_OFF),
- .cancel_af_macro = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_ON),
- .cancel_af_normal = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_OFF),
- .af_macro_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_ON),
- .af_normal_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_OFF),
- .af_camcorder_start = ISX012_REGSET_TABLE(ISX012_Camcorder_SAF_Start),
+ .af_window_reset = ISX012_REGSET_TABLE(ISX012_AF_Window_Reset, 1),
+ .af_winddow_set = ISX012_REGSET_TABLE(ISX012_AF_Window_Set, 0),
+ .af_restart = ISX012_REGSET_TABLE(ISX012_AF_ReStart, 0),
+ .af_saf_off = ISX012_REGSET_TABLE(ISX012_AF_SAF_OFF, 0),
+ .af_touch_saf_off = ISX012_REGSET_TABLE(ISX012_AF_TouchSAF_OFF, 0),
+ .cancel_af_macro = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_ON, 0),
+ .cancel_af_normal = ISX012_REGSET_TABLE(ISX012_AF_Cancel_Macro_OFF, 0),
+ .af_macro_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_ON, 0),
+ .af_normal_mode = ISX012_REGSET_TABLE(ISX012_AF_Macro_OFF, 0),
+ .af_camcorder_start = ISX012_REGSET_TABLE(
+ ISX012_Camcorder_SAF_Start, 0),
/* Flash */
- .flash_ae_line = ISX012_REGSET_TABLE(ISX012_Flash_AELINE),
- .flash_on = ISX012_REGSET_TABLE(ISX012_Flash_ON),
- .flash_off = ISX012_REGSET_TABLE(ISX012_Flash_OFF),
- .ae_manual = ISX012_REGSET_TABLE(ISX012_ae_manual_mode),
- .flash_fast_ae_awb = ISX012_REGSET_TABLE(ISX012_flash_fast_ae_awb),
+ .flash_ae_line = ISX012_REGSET_TABLE(ISX012_Flash_AELINE, 0),
+ .flash_on = ISX012_REGSET_TABLE(ISX012_Flash_ON, 1),
+ .flash_off = ISX012_REGSET_TABLE(ISX012_Flash_OFF, 1),
+ .ae_manual = ISX012_REGSET_TABLE(ISX012_ae_manual_mode, 0),
+ .flash_fast_ae_awb = ISX012_REGSET_TABLE(ISX012_flash_fast_ae_awb, 0),
- .init_reg = ISX012_REGSET_TABLE(ISX012_Init_Reg),
+ .init_reg = ISX012_REGSET_TABLE(ISX012_Init_Reg, 1),
/* Camera mode */
- .preview_mode = ISX012_REGSET_TABLE(ISX012_Preview_Mode),
- .capture_mode = ISX012_REGSET_TABLE(ISX012_Capture_Mode),
+ .preview_mode = ISX012_REGSET_TABLE(ISX012_Preview_Mode, 0),
+ .capture_mode = ISX012_REGSET_TABLE(ISX012_Capture_Mode, 0),
.capture_mode_night =
- ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Capture_Mode),
- .halfrelease_mode = ISX012_REGSET_TABLE(ISX012_Halfrelease_Mode),
+ ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Capture_Mode, 0),
+ .halfrelease_mode = ISX012_REGSET_TABLE(ISX012_Halfrelease_Mode, 0),
.halfrelease_mode_night =
- ISX012_REGSET_TABLE(ISX012_Lowlux_night_Halfrelease_Mode),
- .camcorder_on = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_ON),
- .camcorder_off = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_OFF),
-
- .lowlux_night_reset = ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Reset),
-
- .set_pll_4 = ISX012_REGSET_TABLE(ISX012_Pll_Setting_4),
- .softlanding = ISX012_REGSET_TABLE(ISX012_Sensor_Off_VCM),
+ ISX012_REGSET_TABLE(ISX012_Lowlux_night_Halfrelease_Mode, 0),
+ .camcorder_on = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_ON, 1),
+ .camcorder_off = ISX012_REGSET_TABLE(ISX012_Camcorder_Mode_OFF, 1),
+
+ .lowlux_night_reset = ISX012_REGSET_TABLE(ISX012_Lowlux_Night_Reset, 0),
+
+ .set_pll_4 = ISX012_REGSET_TABLE(ISX012_Pll_Setting_4, 1),
+ .shading_0 = ISX012_REGSET_TABLE(ISX012_Shading_0, 1),
+ .shading_1 = ISX012_REGSET_TABLE(ISX012_Shading_1, 1),
+ .shading_2 = ISX012_REGSET_TABLE(ISX012_Shading_2, 1),
+ .shading_nocal = ISX012_REGSET_TABLE(ISX012_Shading_Nocal, 1),
+ .softlanding = ISX012_REGSET_TABLE(ISX012_Sensor_Off_VCM, 0),
#if 0 /* def CONFIG_VIDEO_ISX012_P8*/
- .antibanding = ISX012_REGSET_TABLE(ISX012_ANTIBANDING_REG),
+ .antibanding = ISX012_REGSET_TABLE(ISX012_ANTIBANDING_REG, 0),
#endif
};
@@ -854,6 +873,8 @@ static int isx012_i2c_burst_write_list(struct v4l2_subdev *sd,
struct i2c_msg msg = {isx012_client->addr, 0, 4, buf};
+ cam_trace("%s\n", name);
+
if (!isx012_client->adapter) {
printk(KERN_ERR "%s: %d can't search i2c client adapter\n", __func__, __LINE__);
return -EIO;
@@ -965,7 +986,12 @@ static int isx012_set_from_table(struct v4l2_subdev *sd,
table->name);
# endif /* DEBUG_WRITE_REGS */
- err = isx012_write_regs(sd, table->reg, table->array_size);
+ if (table->burst) {
+ err = isx012_i2c_burst_write_list(sd,
+ table->reg, table->array_size, setting_name);
+ } else
+ err = isx012_write_regs(sd, table->reg, table->array_size);
+
CHECK_ERR_MSG(err, "write regs(%s), err=%d\n", setting_name, err);
return 0;
@@ -2098,11 +2124,11 @@ static int isx012_do_af(struct v4l2_subdev *sd, u32 touch)
break;
af_dbg("AF state= %d(0x%X)\n", read_value, read_value);
- msleep_debug(30, false);
+ msleep_debug(10, false);
}
if (unlikely(count >= AF_SEARCH_COUNT)) {
- cam_warn("warning, AF check failed. val=0x%X\n\n", read_value);
+ cam_warn("warning, AF check timeout. val=0x%X\n\n", read_value);
isx012_writeb(sd, REG_INTCLR, 0x10);
goto check_fail;
}
@@ -2195,6 +2221,13 @@ static int isx012_set_af(struct v4l2_subdev *sd, s32 val)
state->focus.start = val;
if (val == AUTO_FOCUS_ON) {
+ if ((state->runmode != RUNMODE_RUNNING) &&
+ (state->runmode != RUNMODE_RECORDING)) {
+ cam_err("error, AF can't start, not in preview\n");
+ state->focus.start = AUTO_FOCUS_OFF;
+ return -ESRCH;
+ }
+
err = queue_work(state->workqueue, &state->af_work);
if (likely(err))
state->focus.status = AF_RESULT_DOING;
@@ -2604,6 +2637,10 @@ static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd)
#if !defined(CONFIG_VIDEO_IMPROVE_STREAMOFF)
state->capture.pre_req = 0;
#endif
+
+ if (state->focus.status == AF_RESULT_DOING)
+ isx012_set_af(sd, AUTO_FOCUS_OFF);
+
if (!((state->runmode == RUNMODE_RUNNING)
&& state->capture.pre_req)) {
isx012_writeb(sd, 0x00BF, 0x01);
@@ -3126,8 +3163,10 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd,
isx012_set_framesize(sd, isx012_preview_frmsizes,
ARRAY_SIZE(isx012_preview_frmsizes), true);
- if (previous_index != state->preview.frmsize->index)
+ if ((state->preview.frmsize != NULL) &&
+ (previous_index != state->preview.frmsize->index))
state->preview.update_frmsize = 1;
+
} else {
/*
* In case of image capture mode,
@@ -3136,6 +3175,15 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd,
isx012_set_framesize(sd, isx012_capture_frmsizes,
ARRAY_SIZE(isx012_capture_frmsizes), false);
+ /* for maket app.
+ * Samsung camera app does not use unmatched ratio.*/
+ if (unlikely(NULL == state->preview.frmsize)) {
+ cam_warn("warning, capture without preview resolution\n");
+ } else if (unlikely(FRM_RATIO(state->preview.frmsize)
+ != FRM_RATIO(state->capture.frmsize))) {
+ cam_warn("warning, capture ratio " \
+ "is different with preview ratio\n");
+ }
}
return 0;
@@ -3540,22 +3588,9 @@ static int isx012_s_stream(struct v4l2_subdev *sd, int enable)
return 0;
}
-#if 0 /* DSLIM */
-static int isx012_reset(struct v4l2_subdev *sd, u32 val)
-{
- struct isx012_state *state = to_state(sd);
-
- cam_trace("EX\n");
-
- isx012_return_focus(sd);
- state->initialized = 0;
-
- return 0;
-}
-#endif
-
void isx012_Sensor_Calibration(struct v4l2_subdev *sd)
{
+ struct isx012_state *state = to_state(sd);
int status = 0;
int temp = 0;
@@ -3573,11 +3608,14 @@ void isx012_Sensor_Calibration(struct v4l2_subdev *sd)
/* Write Shading Table */
if (temp == 0x0)
- ISX012_BURST_WRITE_LIST(ISX012_Shading_0);
+ isx012_set_from_table(sd, "Shading_0",
+ &state->regs->shading_0, 1, 0);
else if (temp == 0x1)
- ISX012_BURST_WRITE_LIST(ISX012_Shading_1);
+ isx012_set_from_table(sd, "Shading_1",
+ &state->regs->shading_1, 1, 0);
else if (temp == 0x2)
- ISX012_BURST_WRITE_LIST(ISX012_Shading_2);
+ isx012_set_from_table(sd, "Shading_2",
+ &state->regs->shading_2, 1, 0);
/* Write NorR */
isx012_readw(sd, 0x0054, &status);
@@ -3615,11 +3653,14 @@ void isx012_Sensor_Calibration(struct v4l2_subdev *sd)
/* Write Shading Table */
if (temp == 0x0)
- ISX012_BURST_WRITE_LIST(ISX012_Shading_0);
+ isx012_set_from_table(sd, "Shading_0",
+ &state->regs->shading_0, 1, 0);
else if (temp == 0x1)
- ISX012_BURST_WRITE_LIST(ISX012_Shading_1);
+ isx012_set_from_table(sd, "Shading_1",
+ &state->regs->shading_1, 1, 0);
else if (temp == 0x2)
- ISX012_BURST_WRITE_LIST(ISX012_Shading_2);
+ isx012_set_from_table(sd, "Shading_2",
+ &state->regs->shading_2, 1, 0);
/* Write NorR */
isx012_readw(sd, 0x0045, &status);
@@ -3645,7 +3686,8 @@ void isx012_Sensor_Calibration(struct v4l2_subdev *sd)
boot_dbg("Cal: PreB read : %x\n", temp);
isx012_writew(sd, 0x680A, temp);
} else
- ISX012_BURST_WRITE_LIST(ISX012_Shading_Nocal);
+ isx012_set_from_table(sd, "Shading_nocal",
+ &state->regs->shading_nocal, 1, 0);
}
}
@@ -3658,10 +3700,46 @@ static inline int isx012_check_i2c(struct v4l2_subdev *sd, u16 data)
if (unlikely(err))
return err;
- cam_info("version: 0x%04X is 0x6017?\n", val);
+ cam_dbg("version: 0x%04X is 0x6017?\n", val);
+ return 0;
+}
+
+static int isx012_check_vendorid(struct v4l2_subdev *sd)
+{
+ struct isx012_state *state = to_state(sd);
+ int status = 0;
+ int temp = 0;
+ int temp_msb = 0;
+ int temp_lsb = 0;
+
+ /* Read OTP version */
+ isx012_readw(sd, 0x004F, &status);
+ cam_dbg("OTP : 0x004F read 0x%04X\n", status);
+ if ((status & 0x10) == 0x10) {
+ isx012_readw(sd, 0x0051, &status);
+ temp = (status&0xFFFC);
+ cam_dbg("OTP1 : 0x0051 read : 0x%04X\n", temp);
+ } else {
+ isx012_readw(sd, 0x0042, &status);
+ temp = status&0xFFFC;
+ cam_dbg("OTP0 : 0x0042 read : 0x%04X\n", temp);
+ }
+
+ temp_msb = (temp&0x03FC) << 6;
+ temp_lsb = (temp&0xFC00) >> 10;
+ VendorID = temp_msb | temp_lsb;
+ cam_info("Vendor ID: 0x%04X\n", VendorID);
+
return 0;
}
+u32 isx012_get_vendorid(void)
+{
+ cam_dbg("VendorID: 0x%04X\n", VendorID);
+
+ return VendorID;
+}
+
static int isx012_post_poweron(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
@@ -3675,7 +3753,14 @@ static int isx012_post_poweron(struct v4l2_subdev *sd)
cam_err("%s: error, I2C check fail\n", __func__);
return err;
}
- cam_info("I2C check success!\n");
+ cam_dbg("I2C check success!\n");
+
+ err = isx012_check_vendorid(sd);
+ if (err) {
+ cam_err("%s: error, VendorID check fail\n", __func__);
+ return err;
+ }
+ cam_dbg("VendorID check success!\n");
msleep_debug(10, false);
err = isx012_is_om_changed(sd);
@@ -3953,8 +4038,8 @@ static int is_sysdev(struct device *dev, void *str)
return !strcmp(dev_name(dev), (char *)str) ? 1 : 0;
}
-ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr,
- char *buf)
+static ssize_t cam_loglevel_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
char temp_buf[60] = {0,};
@@ -3980,8 +4065,9 @@ ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr,
return strlen(buf);
}
-ssize_t cam_loglevel_store(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t cam_loglevel_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
printk(KERN_DEBUG "CAM buf=%s, count=%d\n", buf, count);
@@ -4056,6 +4142,6 @@ static void __exit v4l2_i2c_drv_cleanup(void)
module_init(v4l2_i2c_drv_init);
module_exit(v4l2_i2c_drv_cleanup);
-MODULE_DESCRIPTION("LSI ISX012 3MP SOC camera driver");
+MODULE_DESCRIPTION("SONY ISX012 5MP SOC camera driver");
MODULE_AUTHOR("Dong-Seong Lim <dongseong.lim@samsung.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/isx012.h b/drivers/media/video/isx012.h
index 5e65195..e427cc2 100644
--- a/drivers/media/video/isx012.h
+++ b/drivers/media/video/isx012.h
@@ -38,9 +38,9 @@
/* #define CONFIG_DEBUG_NO_FRAME */
/** Debuging Feature **/
-/* #define CONFIG_CAM_DEBUG */
-/* #define CONFIG_CAM_TRACE */ /* Enable it with CONFIG_CAM_DEBUG */
-/* #define CONFIG_CAM_AF_DEBUG *//* Enable it with CONFIG_CAM_DEBUG */
+#define CONFIG_CAM_DEBUG
+#define CONFIG_CAM_TRACE /* Enable it with CONFIG_CAM_DEBUG */
+#define CONFIG_CAM_AF_DEBUG //* Enable it with CONFIG_CAM_DEBUG */
/* #define DEBUG_WRITE_REGS */
/***********************************/
@@ -193,6 +193,11 @@ enum isx012_preview_frame_size {
PREVIEW_SZ_320x240, /* 320x240 */
PREVIEW_SZ_CIF, /* 352x288 */
PREVIEW_SZ_528x432, /* 528x432 */
+#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/
+ PREVIEW_SZ_VERTICAL_VGA, /* 480x640 */
+#endif
PREVIEW_SZ_VGA, /* 640x480 */
PREVIEW_SZ_D1, /* 720x480 */
PREVIEW_SZ_880x720, /* 880x720 */
@@ -458,12 +463,12 @@ struct regset_table {
const char *const name;
};
-#define ISX012_REGSET(x, y) \
+#define ISX012_REGSET(x, y, z) \
[(x)] = { \
.name = #y, \
}
-#define ISX012_REGSET_TABLE(y) \
+#define ISX012_REGSET_TABLE(y, z) \
{ \
.name = #y, \
}
@@ -476,31 +481,36 @@ struct regset_table {
#ifdef DEBUG_WRITE_REGS
const char * const name;
#endif
+ const u32 burst; /* on/off */
};
#ifdef DEBUG_WRITE_REGS
-#define ISX012_REGSET(x, y) \
+#define ISX012_REGSET(x, y, z) \
[(x)] = { \
.reg = (y), \
.array_size = ARRAY_SIZE((y)), \
.name = #y, \
+ .burst = z, \
}
-#define ISX012_REGSET_TABLE(y) \
+#define ISX012_REGSET_TABLE(y, z) \
{ \
.reg = (y), \
.array_size = ARRAY_SIZE((y)), \
.name = #y, \
+ .burst = z, \
}
#else /* !DEBUG_WRITE_REGS */
-#define ISX012_REGSET(x, y) \
+#define ISX012_REGSET(x, y, z) \
[(x)] = { \
.reg = (y), \
.array_size = ARRAY_SIZE((y)), \
+ .burst = z, \
}
-#define ISX012_REGSET_TABLE(y) \
+#define ISX012_REGSET_TABLE(y, z) \
{ \
.reg = (y), \
.array_size = ARRAY_SIZE((y)), \
+ .burst = z, \
}
#endif /* DEBUG_WRITE_REGS */
@@ -558,6 +568,11 @@ struct isx012_regs {
struct regset_table init_reg;
struct regset_table set_pll_4;
+ struct regset_table shading_0;
+ struct regset_table shading_1;
+ struct regset_table shading_2;
+ struct regset_table shading_nocal;
+
#ifdef CONFIG_VIDEO_ISX012_P8
struct regset_table antibanding;
#endif /* CONFIG_VIDEO_ISX012_P8 */
@@ -658,7 +673,7 @@ extern int isx012_create_file(struct class *cls);
#define ISX012_CNT_CM_CHECK 280 /* 160 -> 180 */
#define ISX012_CNT_STREAMOFF 300
-#define AF_SEARCH_COUNT 200
+#define AF_SEARCH_COUNT 550 /* about 6s */
#define AE_STABLE_SEARCH_COUNT 7
/* Sensor AF first,second window size.
@@ -736,6 +751,10 @@ extern int isx012_create_file(struct class *cls);
#define TUNING_FILE_PATH "/mnt/sdcard/isx012_regs.h"
#endif /* CONFIG_LOAD_FILE*/
+#ifdef CONFIG_MACH_KONA
+#include "isx012_regs_kona.h"
+#else /* P4NOTE */
#include "isx012_regs.h"
+#endif
#endif /* __ISX012_H__ */
diff --git a/drivers/media/video/isx012_regs.h b/drivers/media/video/isx012_regs.h
index fa8de0c..0bb1a28 100644
--- a/drivers/media/video/isx012_regs.h
+++ b/drivers/media/video/isx012_regs.h
@@ -28,7 +28,7 @@
/* change 4129 to 4802 */
#define AE_SCL_SUBRACT_VALUE 4802
-const uint16_t aeoffset_table[] = { // normal 4.6times
+static const uint16_t aeoffset_table[] = { /* normal 4.6times */
0, 35, 70, 103, 136, 167, 198, 228, 257, 285,
313, 339, 366, 391, 416, 441, 465, 488, 511, 533,
555, 576, 597, 618, 638, 657, 677, 696, 714, 732,
@@ -4760,7 +4760,6 @@ static const isx012_regset_t isx012_720_Preview[] =
{
{0x0090,0x02D0,0x02}, //HSIZE_MONI : 720
{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480
-
};
static const isx012_regset_t isx012_640_Preview[] =
@@ -4769,6 +4768,15 @@ static const isx012_regset_t isx012_640_Preview[] =
{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480
};
+#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/
+static const isx012_regset_t isx012_480_Preview[] = {
+{0x0090, 0x01E0, 0x02}, /* HSIZE_MONI : 480 */
+{0x0096, 0x0280, 0x02}, /* VSIZE_MONI : 640 */
+};
+#endif
+
static const isx012_regset_t isx012_320_Preview[] =
{
{0x0090,0x0140,0x02}, //HSIZE_MONI : 320
@@ -11223,7 +11231,7 @@ static const isx012_regset_t ISX012_ae_manual_mode[] =
static const isx012_regset_t ISX012_flash_fast_ae_awb[] =
{
{0x5E32,0x0A,0x01},
-{0x5E3D,0x05,0x01},
+{0x5E3D,0x05,0x01}, /* Don't fix me. 0x05 */
{0x0181,0x01,0x01}, // CAP_HALF_AE_CTRL
{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
diff --git a/drivers/media/video/isx012_regs_kona.h b/drivers/media/video/isx012_regs_kona.h
new file mode 100644
index 0000000..9d9496b
--- /dev/null
+++ b/drivers/media/video/isx012_regs_kona.h
@@ -0,0 +1,11284 @@
+/* drivers/media/video/s5k5ccgx_regs-p4w.h
+ *
+ * Driver for s5k5ccgx (5MP Camera) from SEC(LSI), firmware EVT1.1
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * 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.
+ *
+ * Change Date: 2012.06.28
+ */
+
+#ifndef __ISX012_REGS_H__
+#define __ISX012_REGS_H__
+
+#define AE_OFSETVAL 3450 //for tuning // max 5.1times
+#define AE_MAXDIFF 4000 //for tuning // max =< 5000
+#define GLOWLIGHT_DEFAULT 0x002B //for tuning
+#define GLOWLIGHT_ISO50 0xB52A //for tuning
+#define GLOWLIGHT_ISO100 0x9DBA //for tuning
+#define GLOWLIGHT_ISO200 0x864A //for tuning
+#define GLOWLIGHT_ISO400 0x738A //for tuning
+
+#define ESD_VALUE 0xA6A6
+
+/* change 4129 to 4802 */
+#define AE_SCL_SUBRACT_VALUE 4802
+
+static const uint16_t aeoffset_table[] = { /* normal 4.6times */
+ 0, 35, 70, 103, 136, 167, 198, 228, 257, 285,
+ 313, 339, 366, 391, 416, 441, 465, 488, 511, 533,
+ 555, 576, 597, 618, 638, 657, 677, 696, 714, 732,
+ 750, 768, 785, 802, 818, 835, 851, 866, 882, 897,
+ 912, 927, 941, 955, 969, 983, 997, 1010, 1023, 1036,
+ 1049, 1061, 1074, 1086, 1098, 1109, 1121, 1133, 1144, 1155,
+ 1166, 1177, 1187, 1198, 1208, 1219, 1229, 1239, 1248, 1258,
+ 1268, 1277, 1286, 1296, 1305, 1314, 1322, 1331, 1340, 1348,
+ 1357, 1365, 1373, 1381, 1389, 1397, 1405, 1413, 1420, 1428,
+ 1435, 1443, 1450, 1457, 1464, 1471, 1478, 1485, 1492, 1499,
+ 1505, 1512, 1518, 1525, 1531, 1538, 1544, 1550, 1556, 1562,
+ 1568, 1574, 1580, 1585, 1591, 1597, 1602, 1608, 1613, 1619,
+ 1624, 1629, 1635, 1640, 1645, 1650, 1655, 1660, 1665, 1670,
+ 1675, 1679, 1684, 1689, 1693, 1698, 1703, 1707, 1712, 1716,
+ 1720, 1725, 1729, 1733, 1737, 1742, 1746, 1750, 1754, 1758,
+ 1762, 1766, 1770, 1774, 1777, 1781, 1785, 1789, 1792, 1796,
+ 1800, 1803, 1807, 1810, 1814, 1817, 1821, 1824, 1828, 1831,
+ 1834, 1837, 1841, 1844, 1847, 1850, 1853, 1856, 1860, 1863,
+ 1866, 1869, 1872, 1875, 1877, 1880, 1883, 1886, 1889, 1892,
+ 1894, 1897, 1900, 1903, 1905, 1908, 1911, 1913, 1916, 1918,
+ 1921, 1923, 1926, 1928, 1931, 1933, 1936, 1938, 1941, 1943,
+ 1945, 1948, 1950, 1952, 1954, 1957, 1959, 1961, 1963, 1965,
+ 1968, 1970, 1972, 1974, 1976, 1978, 1980, 1982, 1984, 1986,
+ 1988, 1990, 1992, 1994, 1996, 1998, 2000, 2002, 2003, 2005,
+ 2007, 2009, 2011, 2013, 2014, 2016, 2018, 2020, 2021, 2023,
+ 2025, 2026, 2028, 2030, 2031, 2033, 2034, 2036, 2038, 2039,
+ 2041, 2042, 2044, 2045, 2047, 2048, 2050, 2051, 2053, 2054,
+ 2056, 2057, 2059, 2060, 2061, 2063, 2064, 2066, 2067, 2068,
+ 2070, 2071, 2072, 2074, 2075, 2076, 2077, 2079, 2080, 2081,
+ 2082, 2084, 2085, 2086, 2087, 2089, 2090, 2091, 2092, 2093,
+ 2094, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104,
+ 2105, 2106, 2107, 2109, 2110, 2111, 2112, 2113, 2114, 2115,
+ 2116, 2117, 2118, 2119, 2120, 2120, 2121, 2122, 2123, 2124,
+ 2125, 2126, 2127, 2128, 2129, 2130, 2130, 2131, 2132, 2133,
+ 2134, 2135, 2136, 2136, 2137, 2138, 2139, 2140, 2141, 2141,
+ 2142, 2143, 2144, 2144, 2145, 2146, 2147, 2148, 2148, 2149,
+ 2150, 2150, 2151, 2152, 2153, 2153, 2154, 2155, 2155, 2156,
+ 2157, 2158, 2158, 2159, 2160, 2160, 2161, 2162, 2162, 2163,
+ 2163, 2164, 2165, 2165, 2166, 2167, 2167, 2168, 2168, 2169,
+ 2170, 2170, 2171, 2171, 2172, 2172, 2173, 2174, 2174, 2175,
+ 2175, 2176, 2176, 2177, 2177, 2178, 2179, 2179, 2180, 2180,
+ 2181, 2181, 2182, 2182, 2183, 2183, 2184, 2184, 2185, 2185,
+ 2186, 2186, 2186, 2187, 2187, 2188, 2188, 2189, 2189, 2190,
+ 2190, 2191, 2191, 2191, 2192, 2192, 2193, 2193, 2194, 2194,
+ 2194, 2195, 2195, 2196, 2196, 2196, 2197, 2197, 2198, 2198,
+ 2198, 2199, 2199, 2200, 2200, 2200, 2201, 2201, 2201, 2202,
+ 2202, 2203, 2203, 2203, 2204, 2204, 2204, 2205, 2205, 2205,
+ 2206, 2206, 2206, 2207, 2207, 2207, 2208, 2208, 2208, 2209,
+ 2209, 2209, 2210, 2210, 2210, 2210, 2211, 2211, 2211, 2212,
+ 2212, 2212, 2213, 2213, 2213, 2213, 2214, 2214, 2214, 2214,
+};
+
+static const isx012_regset_t ISX012_Init_Reg[] =
+{
+/////////////////////////////////////
+//AF driver setting//³»ºÎ AF driver//
+/////////////////////////////////////
+{0x66C2,0x0C,0x01},//AF_INTERNAL_LENSDRV_ADRS
+{0x66C3,0x02,0x01},//AF_INTERNAL_LENSDRV_SIZE
+{0x66C5,0x14,0x01},//AF_INTERNAL_LENSDRV_SHIFT
+{0x66C8,0x0000,0x02},//AF_INTERNAL_LENSDRV_FIXEDPTN
+{0x66CA,0x000F,0x02},
+{0x000B,0x01,0x01},//AF_EXT : AF driver start
+
+//////////////////////////////////////////
+// ISX012_Initial_Setting.ini //
+//////////////////////////////////////////
+// AE window add V02
+{0x6000,0x06,0x01}, // CENTER_FIXWEIGHT_00_TYPE1 :
+{0x6001,0x06,0x01}, // CENTER_FIXWEIGHT_01_TYPE1 :
+{0x6002,0x06,0x01}, // CENTER_FIXWEIGHT_02_TYPE1 :
+{0x6003,0x06,0x01}, // CENTER_FIXWEIGHT_03_TYPE1 :
+{0x6004,0x06,0x01}, // CENTER_FIXWEIGHT_04_TYPE1 :
+{0x6005,0x06,0x01}, // CENTER_FIXWEIGHT_05_TYPE1 :
+{0x6006,0x06,0x01}, // CENTER_FIXWEIGHT_06_TYPE1 :
+{0x6007,0x06,0x01}, // CENTER_FIXWEIGHT_07_TYPE1 :
+{0x6008,0x06,0x01}, // CENTER_FIXWEIGHT_08_TYPE1 :
+{0x6009,0x0C,0x01}, // CENTER_FIXWEIGHT_09_TYPE1 :
+{0x600A,0x0C,0x01}, // CENTER_FIXWEIGHT_10_TYPE1 :
+{0x600B,0x0C,0x01}, // CENTER_FIXWEIGHT_11_TYPE1 :
+{0x600C,0x10,0x01}, // CENTER_FIXWEIGHT_12_TYPE1 :
+{0x600D,0x10,0x01}, // CENTER_FIXWEIGHT_13_TYPE1 :
+{0x600E,0x10,0x01}, // CENTER_FIXWEIGHT_14_TYPE1 :
+{0x600F,0x0C,0x01}, // CENTER_FIXWEIGHT_15_TYPE1 :
+{0x6010,0x0C,0x01}, // CENTER_FIXWEIGHT_16_TYPE1 :
+{0x6011,0x0C,0x01}, // CENTER_FIXWEIGHT_17_TYPE1 :
+{0x6012,0x0C,0x01}, // CENTER_FIXWEIGHT_18_TYPE1 :
+{0x6013,0x0C,0x01}, // CENTER_FIXWEIGHT_19_TYPE1 :
+{0x6014,0x18,0x01}, // CENTER_FIXWEIGHT_20_TYPE1 :
+{0x6015,0x18,0x01}, // CENTER_FIXWEIGHT_21_TYPE1 :
+{0x6016,0x18,0x01}, // CENTER_FIXWEIGHT_22_TYPE1 :
+{0x6017,0x18,0x01}, // CENTER_FIXWEIGHT_23_TYPE1 :
+{0x6018,0x18,0x01}, // CENTER_FIXWEIGHT_24_TYPE1 :
+{0x6019,0x0C,0x01}, // CENTER_FIXWEIGHT_25_TYPE1 :
+{0x601A,0x0C,0x01}, // CENTER_FIXWEIGHT_26_TYPE1 :
+{0x601B,0x0C,0x01}, // CENTER_FIXWEIGHT_27_TYPE1 :
+{0x601C,0x18,0x01}, // CENTER_FIXWEIGHT_28_TYPE1 :
+{0x601D,0x18,0x01}, // CENTER_FIXWEIGHT_29_TYPE1 :
+{0x601E,0x1E,0x01}, // CENTER_FIXWEIGHT_30_TYPE1 :
+{0x601F,0x1E,0x01}, // CENTER_FIXWEIGHT_31_TYPE1 :
+{0x6020,0x1E,0x01}, // CENTER_FIXWEIGHT_32_TYPE1 :
+{0x6021,0x18,0x01}, // CENTER_FIXWEIGHT_33_TYPE1 :
+{0x6022,0x18,0x01}, // CENTER_FIXWEIGHT_34_TYPE1 :
+{0x6023,0x0C,0x01}, // CENTER_FIXWEIGHT_35_TYPE1 :
+{0x6024,0x0C,0x01}, // CENTER_FIXWEIGHT_36_TYPE1 :
+{0x6025,0x18,0x01}, // CENTER_FIXWEIGHT_37_TYPE1 :
+{0x6026,0x18,0x01}, // CENTER_FIXWEIGHT_38_TYPE1 :
+{0x6027,0x1E,0x01}, // CENTER_FIXWEIGHT_39_TYPE1 :
+{0x6028,0x1E,0x01}, // CENTER_FIXWEIGHT_40_TYPE1 :
+{0x6029,0x1E,0x01}, // CENTER_FIXWEIGHT_41_TYPE1 :
+{0x602A,0x18,0x01}, // CENTER_FIXWEIGHT_42_TYPE1 :
+{0x602B,0x18,0x01}, // CENTER_FIXWEIGHT_43_TYPE1 :
+{0x602C,0x0C,0x01}, // CENTER_FIXWEIGHT_44_TYPE1 :
+{0x602D,0x0C,0x01}, // CENTER_FIXWEIGHT_45_TYPE1 :
+{0x602E,0x0C,0x01}, // CENTER_FIXWEIGHT_46_TYPE1 :
+{0x602F,0x18,0x01}, // CENTER_FIXWEIGHT_47_TYPE1 :
+{0x6030,0x18,0x01}, // CENTER_FIXWEIGHT_48_TYPE1 :
+{0x6031,0x18,0x01}, // CENTER_FIXWEIGHT_49_TYPE1 :
+{0x6032,0x18,0x01}, // CENTER_FIXWEIGHT_50_TYPE1 :
+{0x6033,0x18,0x01}, // CENTER_FIXWEIGHT_51_TYPE1 :
+{0x6034,0x0C,0x01}, // CENTER_FIXWEIGHT_52_TYPE1 :
+{0x6035,0x0C,0x01}, // CENTER_FIXWEIGHT_53_TYPE1 :
+{0x6036,0x0C,0x01}, // CENTER_FIXWEIGHT_54_TYPE1 :
+{0x6037,0x0C,0x01}, // CENTER_FIXWEIGHT_55_TYPE1 :
+{0x6038,0x0C,0x01}, // CENTER_FIXWEIGHT_56_TYPE1 :
+{0x6039,0x0C,0x01}, // CENTER_FIXWEIGHT_57_TYPE1 :
+{0x603A,0x0C,0x01}, // CENTER_FIXWEIGHT_58_TYPE1 :
+{0x603B,0x0C,0x01}, // CENTER_FIXWEIGHT_59_TYPE1 :
+{0x603C,0x0C,0x01}, // CENTER_FIXWEIGHT_60_TYPE1 :
+{0x603D,0x0C,0x01}, // CENTER_FIXWEIGHT_61_TYPE1 :
+{0x603E,0x0C,0x01}, // CENTER_FIXWEIGHT_62_TYPE1 :
+
+
+//AF filter
+{0x6D14,0x0001,0x02}, // HPF_HBPF_CORSL_Y1 :
+{0x6D16,0x0001,0x02}, // HPF_HBPF_CORSL_Y2 :
+{0x6D18,0x0002,0x02}, // HPF_HBPF_CORSL_Y3 :
+{0x6D1A,0x0005,0x02}, // HPF_HBPF_CORSL_Y4 :
+
+{0x6D20,0x0004,0x02}, // HPF_HBPF_CORL_Y1 :
+{0x6D22,0x0004,0x02}, // HPF_HBPF_CORL_Y2 :
+{0x6D24,0x000F,0x02}, // HPF_HBPF_CORL_Y3 :
+{0x6D26,0x001E,0x02}, // HPF_HBPF_CORL_Y4 :
+
+{0x6D2C,0x000E,0x02}, // HPF_HBPF_CORH_Y1 :
+{0x6D2E,0x000F,0x02}, // HPF_HBPF_CORH_Y2 :
+{0x6D30,0x0022,0x02}, // HPF_HBPF_CORH_Y3 :
+{0x6D32,0x004D,0x02}, // HPF_HBPF_CORH_Y4 :
+
+{0x6D44,0x0001,0x02}, // HPF_LBPF_CORSL_Y1 :
+{0x6D46,0x0001,0x02}, // HPF_LBPF_CORSL_Y2 :
+{0x6D48,0x0002,0x02}, // HPF_LBPF_CORSL_Y3 :
+{0x6D4A,0x0004,0x02}, // HPF_LBPF_CORSL_Y4 :
+
+{0x6D50,0x03FF,0x02}, // HPF_LBPF_CORL_Y1 :
+{0x6D52,0x03FF,0x02}, // HPF_LBPF_CORL_Y2 :
+{0x6D54,0x03FF,0x02}, // HPF_LBPF_CORL_Y3 :
+{0x6D56,0x03FF,0x02}, // HPF_LBPF_CORL_Y4 :
+
+{0x6D5C,0x03FF,0x02}, // HPF_LBPF_CORH_Y1 :
+{0x6D5E,0x03FF,0x02}, // HPF_LBPF_CORH_Y2 :
+{0x6D60,0x03FF,0x02}, // HPF_LBPF_CORH_Y3 :
+{0x6D62,0x03FF,0x02}, // HPF_LBPF_CORH_Y4 :
+
+{0x6D74,0x0001,0x02}, // HPF_VHBPF_CORSL_Y1 :
+{0x6D76,0x0001,0x02}, // HPF_VHBPF_CORSL_Y2 :
+{0x6D78,0x0002,0x02}, // HPF_VHBPF_CORSL_Y3 :
+{0x6D7A,0x0005,0x02}, // HPF_VHBPF_CORSL_Y4 :
+
+{0x6D80,0x0004,0x02}, // HPF_VHBPF_CORL_Y1 :
+{0x6D82,0x0005,0x02}, // HPF_VHBPF_CORL_Y2 :
+{0x6D84,0x000C,0x02}, // HPF_VHBPF_CORL_Y3 :
+{0x6D86,0x001C,0x02}, // HPF_VHBPF_CORL_Y4 :
+
+{0x6D8C,0x000D,0x02}, // HPF_VHBPF_CORH_Y1 :
+{0x6D8E,0x0010,0x02}, // HPF_VHBPF_CORH_Y2 :
+{0x6D90,0x0026,0x02}, // HPF_VHBPF_CORH_Y3 :
+{0x6D92,0x004D,0x02}, // HPF_VHBPF_CORH_Y4 :
+
+// CAF Ãß°¡ºÎºÐ
+{0x6622,0x0004,0x02}, // AF_CAF_PARAM_WOBBLE_STEP :
+{0x6624,0x0008,0x02}, // AF_CAF_CLIMB_STEP :
+{0x6687,0x01,0x01}, // AF_CAF_CLIMB_PEAK_BACK_STEP_ENABLE :
+{0x6698,0x00,0x01}, // AF_CAF_WOBBLE_FILTER_ENABLE :
+{0x66A4,0x06,0x01}, // AF_CAF_OPD_FLAT_MOVE_ENABLE :
+{0x66B0,0x0002,0x02}, // AF_CAF_WAIT_FOR_AF_STABLE_TH :
+{0x5003,0x04,0x01}, // Z1_HOLD = 1
+//110819
+{0x6696,0x16,0x01}, //AF_CAF_WOBBLE_START_INTERVAL_COUNTER
+{0x6716,0x0000,0x02}, // CAF_LVD_WOB_HBPF_VAL1 :
+{0x6718,0x0000,0x02}, // CAF_LVD_WOB_HBPF_VAL2 :
+{0x671A,0x00C8,0x02}, // CAF_LVD_WOB_HBPF_RATE1 :
+{0x671C,0x00C8,0x02}, // CAF_LVD_WOB_HBPF_RATE2 :
+{0x671E,0x00,0x01}, // CAF_LVD_WOB_HBPF_SHIFT :
+{0x6720,0x0000,0x02}, // CAF_LVD_WOB_LBPF_VAL1 :
+{0x6722,0x0000,0x02}, // CAF_LVD_WOB_LBPF_VAL2 :
+{0x6724,0x0014,0x02}, // CAF_LVD_WOB_LBPF_RATE1 :
+{0x6726,0x0014,0x02}, // CAF_LVD_WOB_LBPF_RATE2 :
+{0x6728,0x00,0x01}, // CAF_LVD_WOB_LBPF_SHIFT :
+{0x672A,0x0000,0x02}, // CAF_LVD_CLMP_HBPF_VAL1 :
+{0x672C,0x0000,0x02}, // CAF_LVD_CLMP_HBPF_VAL2 :
+{0x672E,0x012C,0x02}, // CAF_LVD_CLMP_HBPF_RATE1 :
+{0x6730,0x012C,0x02}, // CAF_LVD_CLMP_HBPF_RATE2 :
+{0x6732,0x00,0x01}, // CAF_LVD_CLMP_HBPF_SHIFT :
+{0x6734,0x0000,0x02}, // CAF_LVD_CLMP_LBPF_VAL1 :
+{0x6736,0x0000,0x02}, // CAF_LVD_CLMP_LBPF_VAL2 :
+{0x6738,0x0046,0x02}, // CAF_LVD_CLMP_LBPF_RATE1 :
+{0x673A,0x0046,0x02}, // CAF_LVD_CLMP_LBPF_RATE2 :
+{0x673C,0x00,0x01}, // CAF_LVD_CLMP_LBPF_SHIFT :
+{0x661E,0x00C8,0x02}, //AF_CAF_FAR_POSITION
+{0x6620,0x02BC,0x02}, //AF_CAF_NEAR_POSITION
+
+//Ãß°¡¼ÂÆúκРSAFºÎºÐ
+{0x00B2,0x02,0x01}, // AFMODE_MONI : manual AF mode
+{0x028E,0x00,0x01}, // AF_SN1_2 :
+{0x028F,0x00,0x01}, // AF_SN3_4 :
+{0x0290,0x00,0x01}, // AF_SN5_6 :
+{0x0291,0x00,0x01}, // AF_SN7_8 :
+{0x0292,0x00,0x01}, // AF_SN9_10 :
+{0x0293,0x00,0x01}, // AF_SN11_12 :
+{0x6604,0x00,0x01}, // AF_SEARCH_DIR :
+{0x6616,0x01,0x01}, // AF_DIRECTBACK_F :On=1
+{0x661B,0x03,0x01}, // AF_OPDDATA_SAVE :
+{0x661C,0x00,0x01}, // AF_MONOTONY_POS :
+{0x663E,0x00,0x01}, // AF_SEARCH_SECOND_DIR :
+{0x663F,0x01,0x01}, // AF_DIRECTBACK_SECOND_F :
+{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F : AF off½Ã zero positionÀ¸·Î °¥Áö(01) ÇöÀ§Ä¡¿¡ ÀÖÀ»Áö(00) Á¤ÇÔ
+{0x6675,0x01,0x01}, // CAP_AF_CANCEL_F : 1·Î ¼³Á¤½Ã capture¸ðµå¿¡¼­ AFÀÚµ¿ ĵ½½
+{0x6676,0x02,0x01}, // AF_SAxF_MODE :
+{0x669E,0x02,0x01}, // AF_SECOND_WND_CHK :
+{0x6600,0x00C8,0x02}, // AF_SEARCH_AREA_LOW :
+{0x6602,0x02BC,0x02}, // AF_SEARCH_AREA_HIGH :
+{0x6640,0x02,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND :
+{0x6641,0x02,0x01}, // AF_UPN_ON_PEAK_DETECT_SECOND :
+{0x6642,0x02,0x01}, //AF_DROPRATE_ON_DETECT_SECOND_HBPF
+{0x6643,0x02,0x01}, //AF_DROPRATE_ON_DETECT_SECOND_LBPF
+{0x6644,0x14,0x01}, // AF_UPRATE_ON_PEAK_DETECT_HBPF_SECOND :
+{0x6646,0x08,0x01}, // AF_OPD_WEIGHT_TH :
+{0x664A,0x04,0x01}, // AF_DROPN_ON_PEAK_DETECT :
+{0x664B,0x02,0x01}, // AF_UPN_ON_PEAK_DETECT :
+{0x664C,0xFF,0x01}, // AF_UPRATE_ON_PEAK_DETECT_HBPF :
+{0x665A,0x00C8,0x02}, // AF_LENSPOS_ON_AFNG :
+{0x665C,0x0018,0x02}, // AF_DRV_AMOUNT_TONEAR_F :
+{0x665E,0x0003,0x02}, // AF_DRV_AMOUNT_TONEAR_S :
+{0x6660,0x0018,0x02}, // AF_DRV_AMOUNT_TOFAR_F :
+{0x6662,0x0003,0x02}, // AF_DRV_AMOUNT_TOFAR_S :
+{0x6666,0x00C8,0x02}, // AF_AREA_LOW_TYPE1 :
+{0x6668,0x02BC,0x02}, // AF_AREA_HIGH_TYPE1 :
+{0x669A,0x01F4,0x02}, // AF_OPD_MONOTONYUP_HBPF_TH :
+{0x66E4,0x50,0x01}, // AF_TH_1STDEPEND_HBPF_RATE :
+{0x66EE,0x03E8,0x02}, // AF_LVD_HBPF_VAL1_1ST :
+{0x66F0,0x4E20,0x02}, // AF_LVD_HBPF_VAL2_1ST :
+{0x66F2,0x004C,0x02}, // AF_LVD_HBPF_RATE1_1ST :
+{0x66F4,0x0019,0x02}, // AF_LVD_HBPF_RATE2_1ST :
+{0x66F6,0x00,0x01}, // AF_LVD_HBPF_SHIFT_1ST :
+{0x6702,0x03E8,0x02}, // AF_LVD_HBPF_VAL1_2ND :
+{0x6704,0x4E20,0x02}, // AF_LVD_HBPF_VAL2_2ND :
+{0x6706,0x0003,0x02}, // AF_LVD_HBPF_RATE1_2ND :
+{0x6708,0x0003,0x02}, // AF_LVD_HBPF_RATE2_2ND :
+{0x670A,0x00,0x01}, // AF_LVD_HBPF_SHIFT_2ND :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+//chooys add
+{0x6677,0x00,0x01}, // AF_SEND_PARTITION : Use=1
+{0x6678,0x20,0x01}, // AF_SENDNUM_ALL
+{0x6679,0x01,0x01}, // AF_SENDNUM_UP
+{0x667A,0x01,0x01}, // AF_SENDNUM_DOWN
+{0x667C,0x0002,0x02}, // AF_SENDAMOUNT_ADDLIMIT
+{0x667E,0x0020,0x02}, //AF_SENDLINE
+
+// AF opd_TH
+{0x660E,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN
+{0x6610,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX
+
+{0x66E4,0xC8,0x01},
+{0x66E5,0xC8,0x01},
+
+//AF opd window setting
+{0x6A30,0x044E,0x02}, // AF_OPD0_HDELAY :
+{0x6A32,0x02E5,0x02}, // AF_OPD0_VDELAY :
+{0x6A34,0x01D8,0x02}, // AF_OPD0_HVALID :
+{0x6A36,0x01D8,0x02}, // AF_OPD0_VVALID :
+{0x6A38,0x0412,0x02}, // AF_OPD1_HDELAY :
+{0x6A3A,0x02A9,0x02}, // AF_OPD1_VDELAY :
+{0x6A3C,0x0251,0x02}, // AF_OPD1_HVALID :
+{0x6A3E,0x0251,0x02}, // AF_OPD1_VVALID :
+{0x6A40,0x04B4,0x02}, // AF_OPD2_HDELAY :
+{0x6A42,0x0114,0x02}, // AF_OPD2_VDELAY :
+{0x6A44,0x0118,0x02}, // AF_OPD2_HVALID :
+{0x6A46,0x0118,0x02}, // AF_OPD2_VVALID :
+{0x6A48,0x0469,0x02}, // AF_OPD3_HDELAY :
+{0x6A4A,0x00C9,0x02}, // AF_OPD3_VDELAY :
+{0x6A4C,0x01AE,0x02}, // AF_OPD3_HVALID :
+{0x6A4E,0x01AE,0x02}, // AF_OPD3_VVALID :
+{0x6A50,0x04C6,0x02}, // AF_OPD4_HDELAY :
+{0x6A52,0x035D,0x02}, // AF_OPD4_VDELAY :
+{0x6A54,0x00E6,0x02}, // AF_OPD4_HVALID :
+{0x6A56,0x00E6,0x02}, // AF_OPD4_VVALID :
+{0x6A58,0x048A,0x02}, // AF_OPD5_HDELAY :
+{0x6A5A,0x0321,0x02}, // AF_OPD5_VDELAY :
+{0x6A5C,0x015F,0x02}, // AF_OPD5_HVALID :
+{0x6A5E,0x015F,0x02}, // AF_OPD5_VVALID :
+{0x6A60,0x04B4,0x02}, // AF_OPD6_HDELAY :
+{0x6A62,0x0579,0x02}, // AF_OPD6_VDELAY :
+{0x6A64,0x0118,0x02}, // AF_OPD6_HVALID :
+{0x6A66,0x0118,0x02}, // AF_OPD6_VVALID :
+{0x6A68,0x0469,0x02}, // AF_OPD7_HDELAY :
+{0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY :
+{0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID :
+{0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID :
+{0x6A70,0x021D,0x02}, // AF_OPD8_HDELAY :
+{0x6A72,0x02F5,0x02}, // AF_OPD8_VDELAY :
+{0x6A74,0x01AE,0x02}, // AF_OPD8_HVALID :
+{0x6A76,0x01AE,0x02}, // AF_OPD8_VVALID :
+{0x6A78,0x06A4,0x02}, // AF_OPD9_HDELAY :
+{0x6A7A,0x02F5,0x02}, // AF_OPD9_VDELAY :
+{0x6A7C,0x01AE,0x02}, // AF_OPD9_HVALID :
+{0x6A7E,0x01AE,0x02}, // AF_OPD9_VVALID :
+{0x6A80,0x06,0x01}, // AF_OPD1A_WEIGHT :
+{0x6A81,0x05,0x01}, // AF_OPD1B_WEIGHT :
+{0x6A82,0x02,0x01}, // AF_OPD2A_WEIGHT :
+{0x6A83,0x02,0x01}, // AF_OPD2B_WEIGHT :
+{0x6A84,0x08,0x01}, // AF_OPD3A_WEIGHT :
+{0x6A85,0x07,0x01}, // AF_OPD3B_WEIGHT :
+{0x6A86,0x04,0x01}, // AF_OPD4A_WEIGHT :
+{0x6A87,0x03,0x01}, // AF_OPD4B_WEIGHT :
+{0x6A88,0x01,0x01}, // AF_OPD5A_WEIGHT :
+{0x6A89,0x01,0x01}, // AF_OPD5B_WEIGHT :
+
+
+//lee haknoh add
+{0x661C,0x00,0x01},
+//S,66BE,0F,8, //AF_JUDGE_CONF
+//S,669A,01F4,16, //AF_OPD_MONOTONYUP_HBPF_TH
+//S,669C,03E8,16, //AF_OPD_MONOTONYUP_LBPF_TH
+{0x673D,0x01,0x01}, //AF_MANUAL_MOVE_TYTPE : manual mode½Ã AF_MANUAL_POS·Î À̵¿ÇÒÁö ¼³Á¤
+{0x6648,0x00C8,0x02}, //AF_MANUAL_POS
+{0x66E0,0x00C8,0x02}, //AF_POS_INF_SET
+{0x66E2,0x02BC,0x02}, //AF_POS_MACRO_SET
+{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode
+
+
+//Ãß°¡ ¼¼Æà ºÎºÐ
+{0x00F7,0x52,0x01}, // INIT_QLTY0 : Standard 82
+{0x00F8,0x59,0x01}, // INIT_QLTY1 : Fine 89
+{0x00F9,0x5F,0x01}, // INIT_QLTY2 : SuperFine 95
+
+//minimum shutter speed
+{0x6800,0x03,0x01}, //SHTMINLINE
+
+/////// Normal AE Line //////
+// normal capture AE line
+{0x0326,0x21,0x01}, // SHTCTRLTIME1_TYPE1 :
+{0x0327,0x19,0x01}, // AGCGAIN1_TYPE1 :
+{0x0328,0x52,0x01}, // SHTCTRLTIME2_TYPE1 :
+{0x0329,0x23,0x01}, // AGCGAIN2_TYPE1 :
+{0x032A,0x3E,0x01}, // SHTCTRLTIME3_TYPE1 :
+{0x032B,0x3F,0x01}, // AGCGAIN3_TYPE1 :
+
+// normal preview AE line
+{0x032C,0x7C,0x01}, // SHTCTRLTIME1_TYPE2
+{0x032D,0x3D,0x01}, // AGCGAIN1_TYPE2
+{0x032E,0x7C,0x01}, // SHTCTRLTIME2_TYPE2
+{0x032F,0x3D,0x01}, // AGCGAIN2_TYPE2
+{0x0330,0x3E,0x01}, // SHTCTRLTIME3_TYPE2
+{0x0331,0x3F,0x01}, // AGCGAIN3_TYPE2
+
+// flash ae line
+{0x0332,0x42,0x01}, // SHTCTRLTIME1_TYPE3 :
+{0x0333,0x3C,0x01}, // AGCGAIN1_TYPE3 :
+{0x0334,0x42,0x01}, // SHTCTRLTIME2_TYPE3 :
+{0x0335,0x3C,0x01}, // AGCGAIN2_TYPE3 :
+{0x0336,0x21,0x01}, // SHTCTRLTIME3_TYPE3 :
+{0x0337,0x3C,0x01}, // AGCGAIN3_TYPE3 :
+
+//sports ae line
+{0x0338,0x00,0x01}, // SHTCTRLTIME1_TYPE4
+{0x0339,0x14,0x01}, // AGCGAIN1_TYPE4
+{0x033A,0x21,0x01}, // SHTCTRLTIME2_TYPE4
+{0x033B,0x19,0x01}, // AGCGAIN2_TYPE4
+{0x033C,0x3E,0x01}, // SHTCTRLTIME3_TYPE4
+{0x033D,0x3D,0x01}, // AGCGAIN3_TYPE4
+
+//night mode AF ae line
+{0x033E,0xFF,0x01}, // SHTCTRLTIME1_TYPE5 :
+{0x033F,0x00,0x01}, // AGCGAIN1_TYPE5 :
+{0x0340,0xFF,0x01}, // SHTCTRLTIME2_TYPE5 :
+{0x0341,0x00,0x01}, // AGCGAIN2_TYPE5 :
+{0x0342,0xA6,0x01}, // SHTCTRLTIME3_TYPE5 :
+{0x0343,0x49,0x01}, // AGCGAIN3_TYPE5 :
+
+//night mode capture ae line
+{0x0344,0xFF,0x01}, // SHTCTRLTIME1_TYPE6 :
+{0x0345,0x00,0x01}, // AGCGAIN1_TYPE6 :
+{0x0346,0xFF,0x01}, // SHTCTRLTIME2_TYPE6 :
+{0x0347,0x00,0x01}, // AGCGAIN2_TYPE6 :
+{0x0348,0xFA,0x01}, // SHTCTRLTIME3_TYPE6 :
+{0x0349,0x3B,0x01}, // AGCGAIN3_TYPE6 :
+
+// fire mode line
+{0x0356,0x01,0x01}, // SHTCTRLTIME1_TYPE9 :
+{0x0357,0x04,0x01}, // AGCGAIN1_TYPE9 :
+{0x0358,0x01,0x01}, // SHTCTRLTIME2_TYPE9 :
+{0x0359,0x04,0x01}, // AGCGAIN2_TYPE9 :
+{0x035A,0xF8,0x01}, // SHTCTRLTIME3_TYPE9 :
+{0x035B,0x04,0x01}, // AGCGAIN3_TYPE9 :
+
+// fire mode AF line
+{0x035C,0x01,0x01}, // SHTCTRLTIME1_TYPE10 :
+{0x035D,0x04,0x01}, // AGCGAIN1_TYPE10 :
+{0x035E,0x01,0x01}, // SHTCTRLTIME2_TYPE10 :
+{0x035F,0x04,0x01}, // AGCGAIN2_TYPE10 :
+{0x0360,0x21,0x01}, // SHTCTRLTIME3_TYPE10 :
+{0x0361,0x3E,0x01}, // AGCGAIN3_TYPE10 :
+
+
+//AE ref tunning
+{0x5E8A,0x02,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x02,0x01}, // EVREF_GAIN_B :
+{0x5E8C,0xFD,0x01}, // EVREF_GAIN_C :
+{0x5E8D,0xFD,0x01}, // EVREF_GAIN_D :
+{0x5E8E,0xFD,0x01}, // EVREF_GAIN_E :
+{0x5E8F,0x90,0x01}, // EVREF_TH_A :
+{0x5E90,0x94,0x01}, // EVREF_TH_B :
+{0x5E91,0xA5,0x01}, // EVREF_TH_C :
+{0x5E92,0xC0,0x01}, // EVREF_TH_D :
+{0x5E93,0xD5,0x01}, // EVREF_TH_E :
+
+
+//gamma Ilumi
+{0x9211,0x58,0x01}, // GAIN_TH_A_TYPE3 :
+{0x9212,0x63,0x01}, // GAIN_TH_B_TYPE3 :
+{0x9213,0x9F,0x01}, // GAIN_TH_C_TYPE3 :
+
+{0x984E,0x0A,0x01}, // GAMMA0_0CLIP_A :
+{0x984F,0x0A,0x01}, // GAMMA0_0CLIP_B :
+{0x9850,0x05,0x01}, // GAMMA0_0CLIP_C :
+{0x9851,0x1E,0x01}, // GAMMA0_SLOPE_A :
+{0x9852,0x1E,0x01}, // GAMMA0_SLOPE_B :
+{0x9853,0x1E,0x01}, // GAMMA0_SLOPE_C :
+{0x9854,0x0A,0x01}, // GAMMA1_0CLIP_A :
+{0x9855,0x0F,0x01}, // GAMMA1_0CLIP_B :
+{0x9856,0x0F,0x01}, // GAMMA1_0CLIP_C :
+{0x9857,0x32,0x01}, // GAMMA1_SLOPE_A :
+{0x9858,0x1E,0x01}, // GAMMA1_SLOPE_B :
+{0x9859,0x1E,0x01}, // GAMMA1_SLOPE_C :
+
+
+//Gammma Table 0
+{0x7000,0x0000,0x02}, // G0_KNOT_G0 :
+{0x7002,0x0015,0x02}, // G0_KNOT_G1 :
+{0x7004,0x002C,0x02}, // G0_KNOT_G2 :
+{0x7006,0x0041,0x02}, // G0_KNOT_G3 :
+{0x7008,0x004D,0x02}, // G0_KNOT_G4 :
+{0x700A,0x005B,0x02}, // G0_KNOT_G5 :
+{0x700C,0x0060,0x02}, // G0_KNOT_G6 :
+{0x700E,0x0068,0x02}, // G0_KNOT_G7 :
+{0x7010,0x006F,0x02}, // G0_KNOT_G8 :
+{0x7012,0x0078,0x02}, // G0_KNOT_G9 :
+{0x7014,0x0057,0x02}, // G0_KNOT_G10 :
+{0x7016,0x0090,0x02}, // G0_KNOT_G11 :
+{0x7018,0x00BB,0x02}, // G0_KNOT_G12 :
+{0x701A,0x00D6,0x02}, // G0_KNOT_G13 :
+{0x701C,0x00E5,0x02}, // G0_KNOT_G14 :
+{0x701E,0x00F0,0x02}, // G0_KNOT_G15 :
+{0x7020,0x00F9,0x02}, // G0_KNOT_G16 :
+{0x7022,0x0103,0x02}, // G0_KNOT_G17 :
+{0x7024,0x010C,0x02}, // G0_KNOT_G18 :
+{0x7026,0x00,0x01}, // G0_KNOT_R0_OFFSET :
+{0x7027,0x00,0x01}, // G0_KNOT_R2_OFFSET :
+{0x7028,0x00,0x01}, // G0_KNOT_R4_OFFSET :
+{0x7029,0x00,0x01}, // G0_KNOT_R6_OFFSET :
+{0x702A,0x00,0x01}, // G0_KNOT_R8_OFFSET :
+{0x702B,0x00,0x01}, // G0_KNOT_R10_OFFSET :
+{0x702C,0x00,0x01}, // G0_KNOT_R12_OFFSET :
+{0x702D,0x00,0x01}, // G0_KNOT_R14_OFFSET :
+{0x702E,0x00,0x01}, // G0_KNOT_R16_OFFSET :
+{0x702F,0x00,0x01}, // G0_KNOT_R18_OFFSET :
+{0x7030,0x00,0x01}, // G0_KNOT_B0_OFFSET :
+{0x7031,0x00,0x01}, // G0_KNOT_B2_OFFSET :
+{0x7032,0x00,0x01}, // G0_KNOT_B4_OFFSET :
+{0x7033,0x00,0x01}, // G0_KNOT_B6_OFFSET :
+{0x7034,0x00,0x01}, // G0_KNOT_B8_OFFSET :
+{0x7035,0x00,0x01}, // G0_KNOT_B10_OFFSET :
+{0x7036,0x00,0x01}, // G0_KNOT_B12_OFFSET :
+{0x7037,0x00,0x01}, // G0_KNOT_B14_OFFSET :
+{0x7038,0x00,0x01}, // G0_KNOT_B16_OFFSET :
+{0x7039,0x00,0x01}, // G0_KNOT_B18_OFFSET :
+{0x703A,0x0611,0x02}, // G0_LOWGM_ON_R :
+{0x703C,0x1E0A,0x02}, // G0_0CLIP_R :
+{0x703E,0x0611,0x02}, // G0_LOWGM_ON_G :
+{0x7040,0x1E0A,0x02}, // G0_0CLIP_G :
+{0x7042,0x0611,0x02}, // G0_LOWGM_ON_B :
+{0x7044,0x1E0A,0x02}, // G0_0CLIP_B :
+{0x7046,0x9C,0x01}, // G0_KNOT_GAINCTRL_TH_L :
+{0x7047,0xA1,0x01}, // G0_KNOT_GAINCTRL_TH_H :
+{0x7048,0x0000,0x02}, // G0_KNOT_L_G0 :
+{0x704A,0x0007,0x02}, // G0_KNOT_L_G1 :
+{0x704C,0x0016,0x02}, // G0_KNOT_L_G2 :
+{0x704E,0x002A,0x02}, // G0_KNOT_L_G3 :
+{0x7050,0x0039,0x02}, // G0_KNOT_L_G4 :
+{0x7052,0x004A,0x02}, // G0_KNOT_L_G5 :
+{0x7054,0x0051,0x02}, // G0_KNOT_L_G6 :
+{0x7056,0x005D,0x02}, // G0_KNOT_L_G7 :
+{0x7058,0x0065,0x02}, // G0_KNOT_L_G8 :
+{0x705A,0x006C,0x02}, // G0_KNOT_L_G9 :
+{0x705C,0x004E,0x02}, // G0_KNOT_L_G10 :
+{0x705E,0x0083,0x02}, // G0_KNOT_L_G11 :
+{0x7060,0x00AA,0x02}, // G0_KNOT_L_G12 :
+{0x7062,0x00C8,0x02}, // G0_KNOT_L_G13 :
+{0x7064,0x00E1,0x02}, // G0_KNOT_L_G14 :
+{0x7066,0x00F5,0x02}, // G0_KNOT_L_G15 :
+{0x7068,0x0100,0x02}, // G0_KNOT_L_G16 :
+{0x706A,0x0106,0x02}, // G0_KNOT_L_G17 :
+{0x706C,0x010C,0x02}, // G0_KNOT_L_G18 :
+
+//Gammma Table 1
+{0x7200,0x0000,0x02}, // G1_KNOT_G0 :
+{0x7202,0x0008,0x02}, // G1_KNOT_G1 :
+{0x7204,0x0020,0x02}, // G1_KNOT_G2 :
+{0x7206,0x0037,0x02}, // G1_KNOT_G3 :
+{0x7208,0x004D,0x02}, // G1_KNOT_G4 :
+{0x720A,0x0064,0x02}, // G1_KNOT_G5 :
+{0x720C,0x006E,0x02}, // G1_KNOT_G6 :
+{0x720E,0x0072,0x02}, // G1_KNOT_G7 :
+{0x7210,0x007A,0x02}, // G1_KNOT_G8 :
+{0x7212,0x007E,0x02}, // G1_KNOT_G9 :
+{0x7214,0x0064,0x02}, // G1_KNOT_G10 :
+{0x7216,0x0093,0x02}, // G1_KNOT_G11 :
+{0x7218,0x00B7,0x02}, // G1_KNOT_G12 :
+{0x721A,0x00CD,0x02}, // G1_KNOT_G13 :
+{0x721C,0x00DD,0x02}, // G1_KNOT_G14 :
+{0x721E,0x00ED,0x02}, // G1_KNOT_G15 :
+{0x7220,0x00F9,0x02}, // G1_KNOT_G16 :
+{0x7222,0x0102,0x02}, // G1_KNOT_G17 :
+{0x7224,0x0101,0x02}, // G1_KNOT_G18 :
+{0x7226,0x00,0x01}, // G1_KNOT_R0_OFFSET :
+{0x7227,0x00,0x01}, // G1_KNOT_R2_OFFSET :
+{0x7228,0x00,0x01}, // G1_KNOT_R4_OFFSET :
+{0x7229,0x00,0x01}, // G1_KNOT_R6_OFFSET :
+{0x722A,0x00,0x01}, // G1_KNOT_R8_OFFSET :
+{0x722B,0x00,0x01}, // G1_KNOT_R10_OFFSET :
+{0x722C,0x00,0x01}, // G1_KNOT_R12_OFFSET :
+{0x722D,0x00,0x01}, // G1_KNOT_R14_OFFSET :
+{0x722E,0x00,0x01}, // G1_KNOT_R16_OFFSET :
+{0x722F,0x00,0x01}, // G1_KNOT_R18_OFFSET :
+{0x7230,0x00,0x01}, // G1_KNOT_B0_OFFSET :
+{0x7231,0x00,0x01}, // G1_KNOT_B2_OFFSET :
+{0x7232,0x00,0x01}, // G1_KNOT_B4_OFFSET :
+{0x7233,0x00,0x01}, // G1_KNOT_B6_OFFSET :
+{0x7234,0x00,0x01}, // G1_KNOT_B8_OFFSET :
+{0x7235,0x00,0x01}, // G1_KNOT_B10_OFFSET :
+{0x7236,0x00,0x01}, // G1_KNOT_B12_OFFSET :
+{0x7237,0x00,0x01}, // G1_KNOT_B14_OFFSET :
+{0x7238,0x00,0x01}, // G1_KNOT_B16_OFFSET :
+{0x7239,0x00,0x01}, // G1_KNOT_B18_OFFSET :
+{0x723A,0x0321,0x02}, // G1_LOWGM_ON_R :
+{0x723C,0x0C00,0x02}, // G1_0CLIP_R :
+{0x723E,0x0321,0x02}, // G1_LOWGM_ON_G :
+{0x7240,0x0C00,0x02}, // G1_0CLIP_G :
+{0x7242,0x0321,0x02}, // G1_LOWGM_ON_B :
+{0x7244,0x0C00,0x02}, // G1_0CLIP_B :
+
+
+//Gammma Table 2
+{0x7400,0x0000,0x02}, // G2_KNOT_G0 :
+{0x7402,0x000A,0x02}, // G2_KNOT_G1 :
+{0x7404,0x0023,0x02}, // G2_KNOT_G2 :
+{0x7406,0x0038,0x02}, // G2_KNOT_G3 :
+{0x7408,0x003F,0x02}, // G2_KNOT_G4 :
+{0x740A,0x0047,0x02}, // G2_KNOT_G5 :
+{0x740C,0x004F,0x02}, // G2_KNOT_G6 :
+{0x740E,0x0058,0x02}, // G2_KNOT_G7 :
+{0x7410,0x005F,0x02}, // G2_KNOT_G8 :
+{0x7412,0x0068,0x02}, // G2_KNOT_G9 :
+{0x7414,0x0044,0x02}, // G2_KNOT_G10 :
+{0x7416,0x0083,0x02}, // G2_KNOT_G11 :
+{0x7418,0x00B6,0x02}, // G2_KNOT_G12 :
+{0x741A,0x00D1,0x02}, // G2_KNOT_G13 :
+{0x741C,0x00E4,0x02}, // G2_KNOT_G14 :
+{0x741E,0x00F0,0x02}, // G2_KNOT_G15 :
+{0x7420,0x00F9,0x02}, // G2_KNOT_G16 :
+{0x7422,0x0103,0x02}, // G2_KNOT_G17 :
+{0x7424,0x010C,0x02}, // G2_KNOT_G18 :
+{0x7426,0x00,0x01}, // G2_KNOT_R0_OFFSET :
+{0x7427,0x00,0x01}, // G2_KNOT_R2_OFFSET :
+{0x7428,0x00,0x01}, // G2_KNOT_R4_OFFSET :
+{0x7429,0x00,0x01}, // G2_KNOT_R6_OFFSET :
+{0x742A,0x00,0x01}, // G2_KNOT_R8_OFFSET :
+{0x742B,0x00,0x01}, // G2_KNOT_R10_OFFSET :
+{0x742C,0x00,0x01}, // G2_KNOT_R12_OFFSET :
+{0x742D,0x00,0x01}, // G2_KNOT_R14_OFFSET :
+{0x742E,0x00,0x01}, // G2_KNOT_R16_OFFSET :
+{0x742F,0x00,0x01}, // G2_KNOT_R18_OFFSET :
+{0x7430,0x00,0x01}, // G2_KNOT_B0_OFFSET :
+{0x7431,0x00,0x01}, // G2_KNOT_B2_OFFSET :
+{0x7432,0x00,0x01}, // G2_KNOT_B4_OFFSET :
+{0x7433,0x00,0x01}, // G2_KNOT_B6_OFFSET :
+{0x7434,0x00,0x01}, // G2_KNOT_B8_OFFSET :
+{0x7435,0x00,0x01}, // G2_KNOT_B10_OFFSET :
+{0x7436,0x00,0x01}, // G2_KNOT_B12_OFFSET :
+{0x7437,0x00,0x01}, // G2_KNOT_B14_OFFSET :
+{0x7438,0x00,0x01}, // G2_KNOT_B16_OFFSET :
+{0x7439,0x00,0x01}, // G2_KNOT_B18_OFFSET :
+{0x743A,0x0611,0x02}, // G2_LOWGM_ON_R :
+{0x743C,0x1E0A,0x02}, // G2_0CLIP_R :
+{0x743E,0x0611,0x02}, // G2_LOWGM_ON_G :
+{0x7440,0x1E0A,0x02}, // G2_0CLIP_G :
+{0x7442,0x0611,0x02}, // G2_LOWGM_ON_B :
+{0x7444,0x1E0A,0x02}, // G2_0CLIP_B :
+
+
+//AWB tuning
+{0x64A4,0xFF,0x01}, // OUTFRM_LEFT00 :
+{0x64A5,0xFF,0x01}, // OUTFRM_LEFT01 :
+{0x64A6,0xFF,0x01}, // OUTFRM_LEFT02 :
+{0x64A7,0xFF,0x01}, // OUTFRM_LEFT03 :
+{0x64A8,0xFF,0x01}, // OUTFRM_LEFT04 :
+{0x64A9,0xFF,0x01}, // OUTFRM_LEFT05 :
+{0x64AA,0xFF,0x01}, // OUTFRM_LEFT06 :
+{0x64AB,0xFF,0x01}, // OUTFRM_LEFT07 :
+{0x64AC,0xFF,0x01}, // OUTFRM_LEFT08 :
+{0x64AD,0xFD,0x01}, // OUTFRM_LEFT09 :
+{0x64AE,0xCB,0x01}, // OUTFRM_LEFT10 :
+{0x64AF,0xA9,0x01}, // OUTFRM_LEFT11 :
+{0x64B0,0x90,0x01}, // OUTFRM_LEFT12 :
+{0x64B1,0x7D,0x01}, // OUTFRM_LEFT13 :
+{0x64B2,0x70,0x01}, // OUTFRM_LEFT14 :
+{0x64B3,0x65,0x01}, // OUTFRM_LEFT15 :
+{0x64B4,0x5C,0x01}, // OUTFRM_LEFT16 :
+{0x64B5,0x55,0x01}, // OUTFRM_LEFT17 :
+{0x64B6,0x4F,0x01}, // OUTFRM_LEFT18 :
+{0x64B7,0x32,0x01}, // OUTFRM_LEFT19 :
+{0x64B8,0x4D,0x01}, // OUTFRM_LEFT20 :
+{0x64B9,0x40,0x01}, // OUTFRM_LEFT21 :
+{0x64BA,0x2D,0x01}, // OUTFRM_LEFT22 :
+{0x64BB,0x2B,0x01}, // OUTFRM_LEFT23 :
+{0x64BC,0x29,0x01}, // OUTFRM_LEFT24 :
+{0x64BD,0x27,0x01}, // OUTFRM_LEFT25 :
+{0x64BE,0x25,0x01}, // OUTFRM_LEFT26 :
+{0x64BF,0x23,0x01}, // OUTFRM_LEFT27 :
+{0x64C0,0x21,0x01}, // OUTFRM_LEFT28 :
+{0x64C1,0x1F,0x01}, // OUTFRM_LEFT29 :
+{0x64C2,0x1D,0x01}, // OUTFRM_LEFT30 :
+{0x64C3,0x1B,0x01}, // OUTFRM_LEFT31 :
+{0x64C4,0x1A,0x01}, // OUTFRM_LEFT32 :
+{0x64C5,0x1A,0x01}, // OUTFRM_LEFT33 :
+{0x64C6,0x1A,0x01}, // OUTFRM_LEFT34 :
+{0x64C7,0x28,0x01}, // OUTFRM_LEFT35 :
+{0x64C8,0x27,0x01}, // OUTFRM_LEFT36 :
+{0x64C9,0x26,0x01}, // OUTFRM_LEFT37 :
+{0x64CA,0xFF,0x01}, // OUTFRM_RIGHT00 :
+{0x64CB,0xFF,0x01}, // OUTFRM_RIGHT01 :
+{0x64CC,0xFF,0x01}, // OUTFRM_RIGHT02 :
+{0x64CD,0xFF,0x01}, // OUTFRM_RIGHT03 :
+{0x64CE,0xFF,0x01}, // OUTFRM_RIGHT04 :
+{0x64CF,0xFF,0x01}, // OUTFRM_RIGHT05 :
+{0x64D0,0xFF,0x01}, // OUTFRM_RIGHT06 :
+{0x64D1,0xFF,0x01}, // OUTFRM_RIGHT07 :
+{0x64D2,0xFF,0x01}, // OUTFRM_RIGHT08 :
+{0x64D3,0xFF,0x01}, // OUTFRM_RIGHT09 :
+{0x64D4,0xD3,0x01}, // OUTFRM_RIGHT10 :
+{0x64D5,0xB1,0x01}, // OUTFRM_RIGHT11 :
+{0x64D6,0x98,0x01}, // OUTFRM_RIGHT12 :
+{0x64D7,0x85,0x01}, // OUTFRM_RIGHT13 :
+{0x64D8,0x78,0x01}, // OUTFRM_RIGHT14 :
+{0x64D9,0x6D,0x01}, // OUTFRM_RIGHT15 :
+{0x64DA,0x64,0x01}, // OUTFRM_RIGHT16 :
+{0x64DB,0x5D,0x01}, // OUTFRM_RIGHT17 :
+{0x64DC,0x57,0x01}, // OUTFRM_RIGHT18 :
+{0x64DD,0x63,0x01}, // OUTFRM_RIGHT19 :
+{0x64DE,0x5E,0x01}, // OUTFRM_RIGHT20 :
+{0x64DF,0x5A,0x01}, // OUTFRM_RIGHT21 :
+{0x64E0,0x56,0x01}, // OUTFRM_RIGHT22 :
+{0x64E1,0x52,0x01}, // OUTFRM_RIGHT23 :
+{0x64E2,0x50,0x01}, // OUTFRM_RIGHT24 :
+{0x64E3,0x4E,0x01}, // OUTFRM_RIGHT25 :
+{0x64E4,0x4C,0x01}, // OUTFRM_RIGHT26 :
+{0x64E5,0x4A,0x01}, // OUTFRM_RIGHT27 :
+{0x64E6,0x48,0x01}, // OUTFRM_RIGHT28 :
+{0x64E7,0x46,0x01}, // OUTFRM_RIGHT29 :
+{0x64E8,0x44,0x01}, // OUTFRM_RIGHT30 :
+{0x64E9,0x43,0x01}, // OUTFRM_RIGHT31 :
+{0x64EA,0x42,0x01}, // OUTFRM_RIGHT32 :
+{0x64EB,0x42,0x01}, // OUTFRM_RIGHT33 :
+{0x64EC,0x42,0x01}, // OUTFRM_RIGHT34 :
+{0x64ED,0x30,0x01}, // OUTFRM_RIGHT35 :
+{0x64EE,0x2F,0x01}, // OUTFRM_RIGHT36 :
+{0x64EF,0x2E,0x01}, // OUTFRM_RIGHT37 :
+{0x64F0,0x2163,0x02}, // OUTFRM_TOP :
+{0x64F2,0x1400,0x02}, // OUTFRM_BOTM :
+{0x64F4,0x19,0x01}, // OUTFRM_FLTOP :
+{0x64F5,0x14,0x01}, // OUTFRM_FLBOTM :
+{0x64F6,0xFF,0x01}, // OUTAIM_LEFT00 :
+{0x64F7,0xFF,0x01}, // OUTAIM_LEFT01 :
+{0x64F8,0xFF,0x01}, // OUTAIM_LEFT02 :
+{0x64F9,0xFF,0x01}, // OUTAIM_LEFT03 :
+{0x64FA,0xFF,0x01}, // OUTAIM_LEFT04 :
+{0x64FB,0xFF,0x01}, // OUTAIM_LEFT05 :
+{0x64FC,0xFF,0x01}, // OUTAIM_LEFT06 :
+{0x64FD,0xFF,0x01}, // OUTAIM_LEFT07 :
+{0x64FE,0xFF,0x01}, // OUTAIM_LEFT08 :
+{0x64FF,0xFF,0x01}, // OUTAIM_LEFT09 :
+{0x6500,0x91,0x01}, // OUTAIM_LEFT10 :
+{0x6501,0x91,0x01}, // OUTAIM_LEFT11 :
+{0x6502,0x91,0x01}, // OUTAIM_LEFT12 :
+{0x6503,0x66,0x01}, // OUTAIM_LEFT13 :
+{0x6504,0x5D,0x01}, // OUTAIM_LEFT14 :
+{0x6505,0x3C,0x01}, // OUTAIM_LEFT15 :
+{0x6506,0x3C,0x01}, // OUTAIM_LEFT16 :
+{0x6507,0x3C,0x01}, // OUTAIM_LEFT17 :
+{0x6508,0x3A,0x01}, // OUTAIM_LEFT18 :
+{0x6509,0x39,0x01}, // OUTAIM_LEFT19 :
+{0x650A,0x40,0x01}, // OUTAIM_LEFT20 :
+{0x650B,0x46,0x01}, // OUTAIM_LEFT21 :
+{0x650C,0x42,0x01}, // OUTAIM_LEFT22 :
+{0x650D,0x3D,0x01}, // OUTAIM_LEFT23 :
+{0x650E,0x3A,0x01}, // OUTAIM_LEFT24 :
+{0x650F,0x3E,0x01}, // OUTAIM_LEFT25 :
+{0x6510,0x38,0x01}, // OUTAIM_LEFT26 :
+{0x6511,0x36,0x01}, // OUTAIM_LEFT27 :
+{0x6512,0x34,0x01}, // OUTAIM_LEFT28 :
+{0x6513,0x32,0x01}, // OUTAIM_LEFT29 :
+{0x6514,0x30,0x01}, // OUTAIM_LEFT30 :
+{0x6515,0x2F,0x01}, // OUTAIM_LEFT31 :
+{0x6516,0x2D,0x01}, // OUTAIM_LEFT32 :
+{0x6517,0x2C,0x01}, // OUTAIM_LEFT33 :
+{0x6518,0x2B,0x01}, // OUTAIM_LEFT34 :
+{0x6519,0x2A,0x01}, // OUTAIM_LEFT35 :
+{0x651A,0x29,0x01}, // OUTAIM_LEFT36 :
+{0x651B,0x28,0x01}, // OUTAIM_LEFT37 :
+{0x651C,0xFF,0x01}, // OUTAIM_RIGHT00 :
+{0x651D,0xFF,0x01}, // OUTAIM_RIGHT01 :
+{0x651E,0xFF,0x01}, // OUTAIM_RIGHT02 :
+{0x651F,0xFF,0x01}, // OUTAIM_RIGHT03 :
+{0x6520,0xFF,0x01}, // OUTAIM_RIGHT04 :
+{0x6521,0xFF,0x01}, // OUTAIM_RIGHT05 :
+{0x6522,0xFF,0x01}, // OUTAIM_RIGHT06 :
+{0x6523,0xFF,0x01}, // OUTAIM_RIGHT07 :
+{0x6524,0xFF,0x01}, // OUTAIM_RIGHT08 :
+{0x6525,0xFF,0x01}, // OUTAIM_RIGHT09 :
+{0x6526,0xD9,0x01}, // OUTAIM_RIGHT10 :
+{0x6527,0xB7,0x01}, // OUTAIM_RIGHT11 :
+{0x6528,0x96,0x01}, // OUTAIM_RIGHT12 :
+{0x6529,0x6C,0x01}, // OUTAIM_RIGHT13 :
+{0x652A,0x64,0x01}, // OUTAIM_RIGHT14 :
+{0x652B,0x62,0x01}, // OUTAIM_RIGHT15 :
+{0x652C,0x62,0x01}, // OUTAIM_RIGHT16 :
+{0x652D,0x61,0x01}, // OUTAIM_RIGHT17 :
+{0x652E,0x60,0x01}, // OUTAIM_RIGHT18 :
+{0x652F,0x5E,0x01}, // OUTAIM_RIGHT19 :
+{0x6530,0x5B,0x01}, // OUTAIM_RIGHT20 :
+{0x6531,0x4F,0x01}, // OUTAIM_RIGHT21 :
+{0x6532,0x48,0x01}, // OUTAIM_RIGHT22 :
+{0x6533,0x43,0x01}, // OUTAIM_RIGHT23 :
+{0x6534,0x41,0x01}, // OUTAIM_RIGHT24 :
+{0x6535,0x40,0x01}, // OUTAIM_RIGHT25 :
+{0x6536,0x3D,0x01}, // OUTAIM_RIGHT26 :
+{0x6537,0x3B,0x01}, // OUTAIM_RIGHT27 :
+{0x6538,0x39,0x01}, // OUTAIM_RIGHT28 :
+{0x6539,0x37,0x01}, // OUTAIM_RIGHT29 :
+{0x653A,0x36,0x01}, // OUTAIM_RIGHT30 :
+{0x653B,0x35,0x01}, // OUTAIM_RIGHT31 :
+{0x653C,0x33,0x01}, // OUTAIM_RIGHT32 :
+{0x653D,0x32,0x01}, // OUTAIM_RIGHT33 :
+{0x653E,0x31,0x01}, // OUTAIM_RIGHT34 :
+{0x653F,0x30,0x01}, // OUTAIM_RIGHT35 :
+{0x6540,0x2F,0x01}, // OUTAIM_RIGHT36 :
+{0x6541,0x2E,0x01}, // OUTAIM_RIGHT37 :
+{0x6542,0x1F40,0x02}, // OUTAIM_TOP :
+{0x6544,0x1752,0x02}, // OUTAIM_BOTM :
+{0x6546,0x19,0x01}, // OUTAIM_FLTOP :
+{0x6547,0x17,0x01}, // OUTAIM_FLBOTM :
+
+{0x657A,0x82,0x01}, // IN_CTMP_FRM_BG0 :
+{0x657B,0x78,0x01}, // IN_CTMP_FRM_BG1 :
+{0x657C,0x65,0x01}, // IN_CTMP_FRM_BG2 :
+{0x657D,0x5B,0x01}, // IN_CTMP_FRM_BG3 :
+{0x657E,0x55,0x01}, // IN_CTMP_FRM_BG4 :
+{0x657F,0x4F,0x01}, // IN_CTMP_FRM_BG5 :
+{0x6580,0x49,0x01}, // IN_CTMP_FRM_BG6 :
+{0x6581,0x43,0x01}, // IN_CTMP_FRM_BG7 :
+{0x6582,0x3E,0x01}, // IN_CTMP_FRM_BG8 :
+{0x6583,0x35,0x01}, // IN_CTMP_FRM_BG9 :
+{0x6584,0x30,0x01}, // IN_CTMP_FRM_BG10 :
+{0x6585,0x23,0x01}, // IN_CTMP_FRM_RG0 :
+{0x6586,0x33,0x01}, // IN_CTMP_FRM_RG1 :
+{0x6587,0x3F,0x01}, // IN_CTMP_FRM_RG2 :
+{0x6588,0x53,0x01}, // IN_CTMP_FRM_RG3 :
+{0x6589,0x63,0x01}, // IN_CTMP_FRM_RG4 :
+{0x658A,0x76,0x01}, // IN_CTMP_FRM_RG5 :
+{0x658B,0x9A,0x01}, // IN_CTMP_FRM_RG6 :
+{0x658C,0x00,0x01}, // IN_CTMP_WEIGHT00_01 :
+{0x658D,0x00,0x01}, // IN_CTMP_WEIGHT02_03 :
+{0x658E,0x00,0x01}, // IN_CTMP_WEIGHT04_05 :
+{0x658F,0x00,0x01}, // IN_CTMP_WEIGHT06_07 :
+{0x6590,0x00,0x01}, // IN_CTMP_WEIGHT08_09 :
+{0x6591,0x00,0x01}, // IN_CTMP_WEIGHT10_11 :
+{0x6592,0x00,0x01}, // IN_CTMP_WEIGHT12_13 :
+{0x6593,0x00,0x01}, // IN_CTMP_WEIGHT14_15 :
+{0x6594,0x00,0x01}, // IN_CTMP_WEIGHT16_17 :
+{0x6595,0x00,0x01}, // IN_CTMP_WEIGHT18_19 :
+{0x6596,0x00,0x01}, // IN_CTMP_WEIGHT20_21 :
+{0x6597,0x00,0x01}, // IN_CTMP_WEIGHT22_23 :
+{0x6598,0x00,0x01}, // IN_CTMP_WEIGHT24_25 :
+{0x6599,0x00,0x01}, // IN_CTMP_WEIGHT26_27 :
+{0x659A,0x00,0x01}, // IN_CTMP_WEIGHT28_29 :
+{0x659B,0x00,0x01}, // IN_CTMP_WEIGHT30_31 :
+{0x659C,0x00,0x01}, // IN_CTMP_WEIGHT32_33 :
+{0x659D,0x00,0x01}, // IN_CTMP_WEIGHT34_35 :
+{0x659E,0x00,0x01}, // IN_CTMP_WEIGHT36_37 :
+{0x659F,0x00,0x01}, // IN_CTMP_WEIGHT38_39 :
+{0x65A0,0x00,0x01}, // IN_CTMP_WEIGHT40_41 :
+{0x65A1,0x00,0x01}, // IN_CTMP_WEIGHT42_43 :
+{0x65A2,0x00,0x01}, // IN_CTMP_WEIGHT44_45 :
+{0x65A3,0x00,0x01}, // IN_CTMP_WEIGHT46_47 :
+{0x65A4,0x00,0x01}, // IN_CTMP_WEIGHT48_49 :
+{0x65A5,0x00,0x01}, // IN_CTMP_WEIGHT50_51 :
+{0x65A6,0x00,0x01}, // IN_CTMP_WEIGHT52_53 :
+{0x65A7,0x00,0x01}, // IN_CTMP_WEIGHT54_55 :
+{0x65A8,0x00,0x01}, // IN_CTMP_WEIGHT56_57 :
+{0x65A9,0x10,0x01}, // IN_CTMP_WEIGHT58_59 :
+
+{0x65AA,0x78,0x01}, // OUT_CTMP_FRM_BG0 :
+{0x65AB,0x74,0x01}, // OUT_CTMP_FRM_BG1 :
+{0x65AC,0x70,0x01}, // OUT_CTMP_FRM_BG2 :
+{0x65AD,0x6D,0x01}, // OUT_CTMP_FRM_BG3 :
+{0x65AE,0x69,0x01}, // OUT_CTMP_FRM_BG4 :
+{0x65AF,0x66,0x01}, // OUT_CTMP_FRM_BG5 :
+{0x65B0,0x61,0x01}, // OUT_CTMP_FRM_BG6 :
+{0x65B1,0x5D,0x01}, // OUT_CTMP_FRM_BG7 :
+{0x65B2,0x52,0x01}, // OUT_CTMP_FRM_BG8 :
+{0x65B3,0x4B,0x01}, // OUT_CTMP_FRM_BG9 :
+{0x65B4,0x44,0x01}, // OUT_CTMP_FRM_BG10 :
+{0x65B5,0x19,0x01}, // OUT_CTMP_FRM_RG0 :
+{0x65B6,0x27,0x01}, // OUT_CTMP_FRM_RG1 :
+{0x65B7,0x32,0x01}, // OUT_CTMP_FRM_RG2 :
+{0x65B8,0x3A,0x01}, // OUT_CTMP_FRM_RG3 :
+{0x65B9,0x43,0x01}, // OUT_CTMP_FRM_RG4 :
+{0x65BA,0x4A,0x01}, // OUT_CTMP_FRM_RG5 :
+{0x65BB,0x5E,0x01}, // OUT_CTMP_FRM_RG6 :
+{0x65BC,0x00,0x01}, // OUT_CTMP_WEIGHT00_01 :
+{0x65BD,0x00,0x01}, // OUT_CTMP_WEIGHT02_03 :
+{0x65BE,0x00,0x01}, // OUT_CTMP_WEIGHT04_05 :
+{0x65BF,0x00,0x01}, // OUT_CTMP_WEIGHT06_07 :
+{0x65C0,0x33,0x01}, // OUT_CTMP_WEIGHT08_09 :
+{0x65C1,0x00,0x01}, // OUT_CTMP_WEIGHT10_11 :
+{0x65C2,0x30,0x01}, // OUT_CTMP_WEIGHT12_13 :
+{0x65C3,0x33,0x01}, // OUT_CTMP_WEIGHT14_15 :
+{0x65C4,0x00,0x01}, // OUT_CTMP_WEIGHT16_17 :
+{0x65C5,0x30,0x01}, // OUT_CTMP_WEIGHT18_19 :
+{0x65C6,0x33,0x01}, // OUT_CTMP_WEIGHT20_21 :
+{0x65C7,0x00,0x01}, // OUT_CTMP_WEIGHT22_23 :
+{0x65C8,0x30,0x01}, // OUT_CTMP_WEIGHT24_25 :
+{0x65C9,0x33,0x01}, // OUT_CTMP_WEIGHT26_27 :
+{0x65CA,0x00,0x01}, // OUT_CTMP_WEIGHT28_29 :
+{0x65CB,0x30,0x01}, // OUT_CTMP_WEIGHT30_31 :
+{0x65CC,0x44,0x01}, // OUT_CTMP_WEIGHT32_33 :
+{0x65CD,0x00,0x01}, // OUT_CTMP_WEIGHT34_35 :
+{0x65CE,0x40,0x01}, // OUT_CTMP_WEIGHT36_37 :
+{0x65CF,0x55,0x01}, // OUT_CTMP_WEIGHT38_39 :
+{0x65D0,0x05,0x01}, // OUT_CTMP_WEIGHT40_41 :
+{0x65D1,0x20,0x01}, // OUT_CTMP_WEIGHT42_43 :
+{0x65D2,0x72,0x01}, // OUT_CTMP_WEIGHT44_45 :
+{0x65D3,0x07,0x01}, // OUT_CTMP_WEIGHT46_47 :
+{0x65D4,0x00,0x01}, // OUT_CTMP_WEIGHT48_49 :
+{0x65D5,0x00,0x01}, // OUT_CTMP_WEIGHT50_51 :
+{0x65D6,0x00,0x01}, // OUT_CTMP_WEIGHT52_53 :
+{0x65D7,0x00,0x01}, // OUT_CTMP_WEIGHT54_55 :
+{0x65D8,0x00,0x01}, // OUT_CTMP_WEIGHT56_57 :
+{0x65D9,0x00,0x01}, // OUT_CTMP_WEIGHT58_59 :
+
+{0x6400,0xAA,0x01}, // INFRM_LEFT00 :
+{0x6401,0xAA,0x01}, // INFRM_LEFT01 :
+{0x6402,0xAA,0x01}, // INFRM_LEFT02 :
+{0x6403,0xAA,0x01}, // INFRM_LEFT03 :
+{0x6404,0xAA,0x01}, // INFRM_LEFT04 :
+{0x6405,0xAA,0x01}, // INFRM_LEFT05 :
+{0x6406,0xAA,0x01}, // INFRM_LEFT06 :
+{0x6407,0xAA,0x01}, // INFRM_LEFT07 :
+{0x6408,0xAA,0x01}, // INFRM_LEFT08 :
+{0x6409,0xAE,0x01}, // INFRM_LEFT09 :
+{0x640A,0xA0,0x01}, // INFRM_LEFT10 :
+{0x640B,0x8C,0x01}, // INFRM_LEFT11 :
+{0x640C,0x72,0x01}, // INFRM_LEFT12 :
+{0x640D,0x64,0x01}, // INFRM_LEFT13 :
+{0x640E,0x5A,0x01}, // INFRM_LEFT14 :
+{0x640F,0x52,0x01}, // INFRM_LEFT15 :
+{0x6410,0x48,0x01}, // INFRM_LEFT16 :
+{0x6411,0x43,0x01}, // INFRM_LEFT17 :
+{0x6412,0x3D,0x01}, // INFRM_LEFT18 :
+{0x6413,0x37,0x01}, // INFRM_LEFT19 :
+{0x6414,0x33,0x01}, // INFRM_LEFT20 :
+{0x6415,0x30,0x01}, // INFRM_LEFT21 :
+{0x6416,0x2E,0x01}, // INFRM_LEFT22 :
+{0x6417,0x2B,0x01}, // INFRM_LEFT23 :
+{0x6418,0x28,0x01}, // INFRM_LEFT24 :
+{0x6419,0x26,0x01}, // INFRM_LEFT25 :
+{0x641A,0x24,0x01}, // INFRM_LEFT26 :
+{0x641B,0x23,0x01}, // INFRM_LEFT27 :
+{0x641C,0x22,0x01}, // INFRM_LEFT28 :
+{0x641D,0x22,0x01}, // INFRM_LEFT29 :
+{0x641E,0x21,0x01}, // INFRM_LEFT30 :
+{0x641F,0x20,0x01}, // INFRM_LEFT31 :
+{0x6420,0x1D,0x01}, // INFRM_LEFT32 :
+{0x6421,0x1A,0x01}, // INFRM_LEFT33 :
+{0x6422,0x18,0x01}, // INFRM_LEFT34 :
+{0x6423,0x17,0x01}, // INFRM_LEFT35 :
+{0x6424,0x16,0x01}, // INFRM_LEFT36 :
+{0x6425,0x17,0x01}, // INFRM_LEFT37 :
+{0x6426,0xAF,0x01}, // INFRM_RIGHT00 :
+{0x6427,0xAF,0x01}, // INFRM_RIGHT01 :
+{0x6428,0xAF,0x01}, // INFRM_RIGHT02 :
+{0x6429,0xAF,0x01}, // INFRM_RIGHT03 :
+{0x642A,0xAF,0x01}, // INFRM_RIGHT04 :
+{0x642B,0xAF,0x01}, // INFRM_RIGHT05 :
+{0x642C,0xAF,0x01}, // INFRM_RIGHT06 :
+{0x642D,0xAF,0x01}, // INFRM_RIGHT07 :
+{0x642E,0xAF,0x01}, // INFRM_RIGHT08 :
+{0x642F,0xAA,0x01}, // INFRM_RIGHT09 :
+{0x6430,0xB2,0x01}, // INFRM_RIGHT10 :
+{0x6431,0xB4,0x01}, // INFRM_RIGHT11 :
+{0x6432,0xB6,0x01}, // INFRM_RIGHT12 :
+{0x6433,0xB4,0x01}, // INFRM_RIGHT13 :
+{0x6434,0x9B,0x01}, // INFRM_RIGHT14 :
+{0x6435,0x8E,0x01}, // INFRM_RIGHT15 :
+{0x6436,0x84,0x01}, // INFRM_RIGHT16 :
+{0x6437,0x7A,0x01}, // INFRM_RIGHT17 :
+{0x6438,0x72,0x01}, // INFRM_RIGHT18 :
+{0x6439,0x6A,0x01}, // INFRM_RIGHT19 :
+{0x643A,0x63,0x01}, // INFRM_RIGHT20 :
+{0x643B,0x5E,0x01}, // INFRM_RIGHT21 :
+{0x643C,0x58,0x01}, // INFRM_RIGHT22 :
+{0x643D,0x53,0x01}, // INFRM_RIGHT23 :
+{0x643E,0x4E,0x01}, // INFRM_RIGHT24 :
+{0x643F,0x4A,0x01}, // INFRM_RIGHT25 :
+{0x6440,0x46,0x01}, // INFRM_RIGHT26 :
+{0x6441,0x42,0x01}, // INFRM_RIGHT27 :
+{0x6442,0x3F,0x01}, // INFRM_RIGHT28 :
+{0x6443,0x3C,0x01}, // INFRM_RIGHT29 :
+{0x6444,0x3A,0x01}, // INFRM_RIGHT30 :
+{0x6445,0x38,0x01}, // INFRM_RIGHT31 :
+{0x6446,0x37,0x01}, // INFRM_RIGHT32 :
+{0x6447,0x35,0x01}, // INFRM_RIGHT33 :
+{0x6448,0x33,0x01}, // INFRM_RIGHT34 :
+{0x6449,0x32,0x01}, // INFRM_RIGHT35 :
+{0x644A,0x32,0x01}, // INFRM_RIGHT36 :
+{0x644B,0x32,0x01}, // INFRM_RIGHT37 :
+{0x644C,0x24FA,0x02}, // INFRM_TOP :
+{0x644E,0x0940,0x02}, // INFRM_BOTM :
+{0x6450,0x19,0x01}, // INFRM_FLTOP :
+{0x6451,0x10,0x01}, // INFRM_FLBOTM :
+{0x6452,0x91,0x01}, // INAIM_LEFT00 :
+{0x6453,0x91,0x01}, // INAIM_LEFT01 :
+{0x6454,0x91,0x01}, // INAIM_LEFT02 :
+{0x6455,0x91,0x01}, // INAIM_LEFT03 :
+{0x6456,0x91,0x01}, // INAIM_LEFT04 :
+{0x6457,0x91,0x01}, // INAIM_LEFT05 :
+{0x6458,0x91,0x01}, // INAIM_LEFT06 :
+{0x6459,0x91,0x01}, // INAIM_LEFT07 :
+{0x645A,0x91,0x01}, // INAIM_LEFT08 :
+{0x645B,0x91,0x01}, // INAIM_LEFT09 :
+{0x645C,0x91,0x01}, // INAIM_LEFT10 :
+{0x645D,0x91,0x01}, // INAIM_LEFT11 :
+{0x645E,0x91,0x01}, // INAIM_LEFT12 :
+{0x645F,0x66,0x01}, // INAIM_LEFT13 :
+{0x6460,0x71,0x01}, // INAIM_LEFT14 :
+{0x6461,0x5A,0x01}, // INAIM_LEFT15 :
+{0x6462,0x4E,0x01}, // INAIM_LEFT16 :
+{0x6463,0x47,0x01}, // INAIM_LEFT17 :
+{0x6464,0x42,0x01}, // INAIM_LEFT18 :
+{0x6465,0x3C,0x01}, // INAIM_LEFT19 :
+{0x6466,0x38,0x01}, // INAIM_LEFT20 :
+{0x6467,0x36,0x01}, // INAIM_LEFT21 :
+{0x6468,0x33,0x01}, // INAIM_LEFT22 :
+{0x6469,0x30,0x01}, // INAIM_LEFT23 :
+{0x646A,0x2F,0x01}, // INAIM_LEFT24 :
+{0x646B,0x2B,0x01}, // INAIM_LEFT25 :
+{0x646C,0x29,0x01}, // INAIM_LEFT26 :
+{0x646D,0x27,0x01}, // INAIM_LEFT27 :
+{0x646E,0x26,0x01}, // INAIM_LEFT28 :
+{0x646F,0x28,0x01}, // INAIM_LEFT29 :
+{0x6470,0x2A,0x01}, // INAIM_LEFT30 :
+{0x6471,0x28,0x01}, // INAIM_LEFT31 :
+{0x6472,0x26,0x01}, // INAIM_LEFT32 :
+{0x6473,0x24,0x01}, // INAIM_LEFT33 :
+{0x6474,0x29,0x01}, // INAIM_LEFT34 :
+{0x6475,0x28,0x01}, // INAIM_LEFT35 :
+{0x6476,0x29,0x01}, // INAIM_LEFT36 :
+{0x6477,0x26,0x01}, // INAIM_LEFT37 :
+{0x6478,0xFF,0x01}, // INAIM_RIGHT00 :
+{0x6479,0xFF,0x01}, // INAIM_RIGHT01 :
+{0x647A,0xFF,0x01}, // INAIM_RIGHT02 :
+{0x647B,0xFF,0x01}, // INAIM_RIGHT03 :
+{0x647C,0xFF,0x01}, // INAIM_RIGHT04 :
+{0x647D,0xFF,0x01}, // INAIM_RIGHT05 :
+{0x647E,0xFF,0x01}, // INAIM_RIGHT06 :
+{0x647F,0xFF,0x01}, // INAIM_RIGHT07 :
+{0x6480,0xFF,0x01}, // INAIM_RIGHT08 :
+{0x6481,0xFF,0x01}, // INAIM_RIGHT09 :
+{0x6482,0xD9,0x01}, // INAIM_RIGHT10 :
+{0x6483,0xB7,0x01}, // INAIM_RIGHT11 :
+{0x6484,0x96,0x01}, // INAIM_RIGHT12 :
+{0x6485,0x68,0x01}, // INAIM_RIGHT13 :
+{0x6486,0x72,0x01}, // INAIM_RIGHT14 :
+{0x6487,0x71,0x01}, // INAIM_RIGHT15 :
+{0x6488,0x6E,0x01}, // INAIM_RIGHT16 :
+{0x6489,0x6A,0x01}, // INAIM_RIGHT17 :
+{0x648A,0x65,0x01}, // INAIM_RIGHT18 :
+{0x648B,0x60,0x01}, // INAIM_RIGHT19 :
+{0x648C,0x5B,0x01}, // INAIM_RIGHT20 :
+{0x648D,0x56,0x01}, // INAIM_RIGHT21 :
+{0x648E,0x51,0x01}, // INAIM_RIGHT22 :
+{0x648F,0x4C,0x01}, // INAIM_RIGHT23 :
+{0x6490,0x47,0x01}, // INAIM_RIGHT24 :
+{0x6491,0x44,0x01}, // INAIM_RIGHT25 :
+{0x6492,0x41,0x01}, // INAIM_RIGHT26 :
+{0x6493,0x3E,0x01}, // INAIM_RIGHT27 :
+{0x6494,0x3B,0x01}, // INAIM_RIGHT28 :
+{0x6495,0x39,0x01}, // INAIM_RIGHT29 :
+{0x6496,0x37,0x01}, // INAIM_RIGHT30 :
+{0x6497,0x34,0x01}, // INAIM_RIGHT31 :
+{0x6498,0x33,0x01}, // INAIM_RIGHT32 :
+{0x6499,0x32,0x01}, // INAIM_RIGHT33 :
+{0x649A,0x31,0x01}, // INAIM_RIGHT34 :
+{0x649B,0x30,0x01}, // INAIM_RIGHT35 :
+{0x649C,0x2F,0x01}, // INAIM_RIGHT36 :
+{0x649D,0x2E,0x01}, // INAIM_RIGHT37 :
+{0x649E,0x1E00,0x02}, // INAIM_TOP :
+{0x64A0,0x0DFF,0x02}, // INAIM_BOTM :
+{0x64A2,0x18,0x01}, // INAIM_FLTOP :
+{0x64A3,0x09,0x01}, // INAIM_FLBOTM :
+
+//AWB setting
+{0x629A,0x13,0x01}, // CAT_AWB_2 : OPDG ±â´É off
+{0x629B,0x41,0x01}, // CAT_AWB_3 : outdoor_°¡ÁßÄ¡ on
+{0x625F,0x15,0x01}, // CAT_AWB_1 : MWB½Ã userÁÂÇ¥·Î ÁÂÇ¥ °íÁ¤(AWB½Ã¿¡´Â ¿µÇâ ¹«)
+{0x629C,0x80,0x01}, // FRMOUT_RATIO_BLEND1_OUT
+{0x6224,0x04,0x01}, // ATW_DELAY
+{0x6226,0x08,0x01}, // ATW_GAINS_IN_NR :
+{0x6227,0x04,0x01}, // ATW_GAINS_IN :
+{0x6228,0x08,0x01}, // ATW_GAINS_OUT_NR :
+{0x6229,0x04,0x01}, // ATW_GAINS_OUT :
+
+//Bluesky threshold º¯°æ
+{0x6548,0x18F7,0x02}, // OUTAIM_TOP_BLUESKY :
+
+//Hue, Gain setting
+{0x6E86,0x0000,0x02}, // IBYHUE1_POS1 :
+{0x6E88,0xFFF5,0x02}, // IRYHUE1_POS1 :
+{0x6E8A,0xFFF8,0x02}, // IBYHUE2_POS1 :
+{0x6E8C,0xFFF5,0x02}, // IRYHUE2_POS1 :
+{0x6E8E,0xFFF8,0x02}, // IBYHUE3_POS1 :
+{0x6E90,0xFFEE,0x02}, // IRYHUE3_POS1 :
+{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 :
+{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 :
+{0x6E96,0x0000,0x02}, // IBYHUE1_POS2 :
+{0x6E98,0xFFF5,0x02}, // IRYHUE1_POS2 :
+{0x6E9A,0xFFFD,0x02}, // IBYHUE2_POS2 :
+{0x6E9C,0xFFF5,0x02}, // IRYHUE2_POS2 :
+{0x6E9E,0xFFFD,0x02}, // IBYHUE3_POS2 :
+{0x6EA0,0xFFEE,0x02}, // IRYHUE3_POS2 :
+{0x6EA2,0x0000,0x02}, // IBYHUE4_POS2 :
+{0x6EA4,0xFFEC,0x02}, // IRYHUE4_POS2 :
+{0x6EA6,0x0000,0x02}, // IBYHUE1_POS3 :
+{0x6EA8,0xFFF5,0x02}, // IRYHUE1_POS3 :
+{0x6EAA,0xFFF8,0x02}, // IBYHUE2_POS3 :
+{0x6EAC,0xFFF5,0x02}, // IRYHUE2_POS3 :
+{0x6EAE,0xFFF8,0x02}, // IBYHUE3_POS3 :
+{0x6EB0,0xFFEE,0x02}, // IRYHUE3_POS3 :
+{0x6EB2,0x0000,0x02}, // IBYHUE4_POS3 :
+{0x6EB4,0xFFEC,0x02}, // IRYHUE4_POS3 :
+{0x6EB6,0x0000,0x02}, // IBYHUE1_POS4 :
+{0x6EB8,0xFFF5,0x02}, // IRYHUE1_POS4 :
+{0x6EBA,0xFFF8,0x02}, // IBYHUE2_POS4 :
+{0x6EBC,0xFFF5,0x02}, // IRYHUE2_POS4 :
+{0x6EBE,0xFFF8,0x02}, // IBYHUE3_POS4 :
+{0x6EC0,0xFFEE,0x02}, // IRYHUE3_POS4 :
+{0x6EC2,0x0000,0x02}, // IBYHUE4_POS4 :
+{0x6EC4,0xFFEC,0x02}, // IRYHUE4_POS4 :
+{0x6EC6,0x0000,0x02}, // IBYHUE1_POS5 :
+{0x6EC8,0xFFF5,0x02}, // IRYHUE1_POS5 :
+{0x6ECA,0xFFF8,0x02}, // IBYHUE2_POS5 :
+{0x6ECC,0xFFF5,0x02}, // IRYHUE2_POS5 :
+{0x6ECE,0xFFF8,0x02}, // IBYHUE3_POS5 :
+{0x6ED0,0xFFEE,0x02}, // IRYHUE3_POS5 :
+{0x6ED2,0x0000,0x02}, // IBYHUE4_POS5 :
+{0x6ED4,0xFFEC,0x02}, // IRYHUE4_POS5 :
+{0x6ED6,0x0000,0x02}, // IBYHUE1_POS6 :
+{0x6ED8,0xFFF5,0x02}, // IRYHUE1_POS6 :
+{0x6EDA,0xFFF8,0x02}, // IBYHUE2_POS6 :
+{0x6EDC,0xFFF5,0x02}, // IRYHUE2_POS6 :
+{0x6EDE,0xFFF8,0x02}, // IBYHUE3_POS6 :
+{0x6EE0,0xFFEE,0x02}, // IRYHUE3_POS6 :
+{0x6EE2,0x0000,0x02}, // IBYHUE4_POS6 :
+{0x6EE4,0xFFEC,0x02}, // IRYHUE4_POS6 :
+{0x6EE6,0x0000,0x02}, // IBYHUE1_POS7 :
+{0x6EE8,0xFFF5,0x02}, // IRYHUE1_POS7 :
+{0x6EEA,0xFFEA,0x02}, // IBYHUE2_POS7 :
+{0x6EEC,0xFFF5,0x02}, // IRYHUE2_POS7 :
+{0x6EEE,0xFFEA,0x02}, // IBYHUE3_POS7 :
+{0x6EF0,0xFFEE,0x02}, // IRYHUE3_POS7 :
+{0x6EF2,0x0000,0x02}, // IBYHUE4_POS7 :
+{0x6EF4,0xFFEC,0x02}, // IRYHUE4_POS7 :
+{0x6EF6,0xFFF2,0x02}, // IBYHUE1_OUT :
+{0x6EF8,0x0000,0x02}, // IRYHUE1_OUT :
+{0x6EFA,0xFFFA,0x02}, // IBYHUE2_OUT :
+{0x6EFC,0x0000,0x02}, // IRYHUE2_OUT :
+{0x6EFE,0xFFFA,0x02}, // IBYHUE3_OUT :
+{0x6F00,0xFFE7,0x02}, // IRYHUE3_OUT :
+{0x6F02,0xFFF2,0x02}, // IBYHUE4_OUT :
+{0x6F04,0xFFE7,0x02}, // IRYHUE4_OUT :
+{0x6F06,0x0000,0x02}, // IBYHUE1_R2_POS4 :
+{0x6F08,0xFFF5,0x02}, // IRYHUE1_R2_POS4 :
+{0x6F0A,0xFFF8,0x02}, // IBYHUE2_R2_POS4 :
+{0x6F0C,0xFFF5,0x02}, // IRYHUE2_R2_POS4 :
+{0x6F0E,0xFFF8,0x02}, // IBYHUE3_R2_POS4 :
+{0x6F10,0xFFEE,0x02}, // IRYHUE3_R2_POS4 :
+{0x6F12,0x0000,0x02}, // IBYHUE4_R2_POS4 :
+{0x6F14,0xFFEC,0x02}, // IRYHUE4_R2_POS4 :
+{0x6F16,0x0000,0x02}, // IBYHUE1_R2_POS5 :
+{0x6F18,0xFFF5,0x02}, // IRYHUE1_R2_POS5 :
+{0x6F1A,0xFFF8,0x02}, // IBYHUE2_R2_POS5 :
+{0x6F1C,0xFFF5,0x02}, // IRYHUE2_R2_POS5 :
+{0x6F1E,0xFFF8,0x02}, // IBYHUE3_R2_POS5 :
+{0x6F20,0xFFEE,0x02}, // IRYHUE3_R2_POS5 :
+{0x6F22,0x0000,0x02}, // IBYHUE4_R2_POS5 :
+{0x6F24,0xFFEC,0x02}, // IRYHUE4_R2_POS5 :
+{0x6F26,0x4B,0x01}, // IRYGAIN1_POS1 :
+{0x6F27,0x50,0x01}, // IBYGAIN1_POS1 :
+{0x6F28,0x4B,0x01}, // IRYGAIN2_POS1 :
+{0x6F29,0x57,0x01}, // IBYGAIN2_POS1 :
+{0x6F2A,0x56,0x01}, // IRYGAIN3_POS1 :
+{0x6F2B,0x57,0x01}, // IBYGAIN3_POS1 :
+{0x6F2C,0x56,0x01}, // IRYGAIN4_POS1 :
+{0x6F2D,0x50,0x01}, // IBYGAIN4_POS1 :
+{0x6F2E,0x4B,0x01}, // IRYGAIN1_POS2 :
+{0x6F2F,0x50,0x01}, // IBYGAIN1_POS2 :
+{0x6F30,0x4B,0x01}, // IRYGAIN2_POS2 :
+{0x6F31,0x57,0x01}, // IBYGAIN2_POS2 :
+{0x6F32,0x54,0x01}, // IRYGAIN3_POS2 :
+{0x6F33,0x57,0x01}, // IBYGAIN3_POS2 :
+{0x6F34,0x54,0x01}, // IRYGAIN4_POS2 :
+{0x6F35,0x50,0x01}, // IBYGAIN4_POS2 :
+{0x6F36,0x4B,0x01}, // IRYGAIN1_POS3 :
+{0x6F37,0x50,0x01}, // IBYGAIN1_POS3 :
+{0x6F38,0x4B,0x01}, // IRYGAIN2_POS3 :
+{0x6F39,0x57,0x01}, // IBYGAIN2_POS3 :
+{0x6F3A,0x50,0x01}, // IRYGAIN3_POS3 :
+{0x6F3B,0x57,0x01}, // IBYGAIN3_POS3 :
+{0x6F3C,0x50,0x01}, // IRYGAIN4_POS3 :
+{0x6F3D,0x50,0x01}, // IBYGAIN4_POS3 :
+{0x6F3E,0x4B,0x01}, // IRYGAIN1_POS4 :
+{0x6F3F,0x50,0x01}, // IBYGAIN1_POS4 :
+{0x6F40,0x4B,0x01}, // IRYGAIN2_POS4 :
+{0x6F41,0x57,0x01}, // IBYGAIN2_POS4 :
+{0x6F42,0x50,0x01}, // IRYGAIN3_POS4 :
+{0x6F43,0x57,0x01}, // IBYGAIN3_POS4 :
+{0x6F44,0x50,0x01}, // IRYGAIN4_POS4 :
+{0x6F45,0x50,0x01}, // IBYGAIN4_POS4 :
+{0x6F46,0x4B,0x01}, // IRYGAIN1_POS5 :
+{0x6F47,0x50,0x01}, // IBYGAIN1_POS5 :
+{0x6F48,0x4B,0x01}, // IRYGAIN2_POS5 :
+{0x6F49,0x57,0x01}, // IBYGAIN2_POS5 :
+{0x6F4A,0x50,0x01}, // IRYGAIN3_POS5 :
+{0x6F4B,0x57,0x01}, // IBYGAIN3_POS5 :
+{0x6F4C,0x50,0x01}, // IRYGAIN4_POS5 :
+{0x6F4D,0x50,0x01}, // IBYGAIN4_POS5 :
+{0x6F4E,0x4B,0x01}, // IRYGAIN1_POS6 :
+{0x6F4F,0x50,0x01}, // IBYGAIN1_POS6 :
+{0x6F50,0x4B,0x01}, // IRYGAIN2_POS6 :
+{0x6F51,0x57,0x01}, // IBYGAIN2_POS6 :
+{0x6F52,0x50,0x01}, // IRYGAIN3_POS6 :
+{0x6F53,0x57,0x01}, // IBYGAIN3_POS6 :
+{0x6F54,0x50,0x01}, // IRYGAIN4_POS6 :
+{0x6F55,0x50,0x01}, // IBYGAIN4_POS6 :
+{0x6F56,0x4B,0x01}, // IRYGAIN1_POS7 :
+{0x6F57,0x50,0x01}, // IBYGAIN1_POS7 :
+{0x6F58,0x4B,0x01}, // IRYGAIN2_POS7 :
+{0x6F59,0x57,0x01}, // IBYGAIN2_POS7 :
+{0x6F5A,0x50,0x01}, // IRYGAIN3_POS7 :
+{0x6F5B,0x57,0x01}, // IBYGAIN3_POS7 :
+{0x6F5C,0x50,0x01}, // IRYGAIN4_POS7 :
+{0x6F5D,0x50,0x01}, // IBYGAIN4_POS7 :
+{0x6F5E,0x50,0x01}, // IRYGAIN1_OUT :
+{0x6F5F,0x5A,0x01}, // IBYGAIN1_OUT :
+{0x6F60,0x50,0x01}, // IRYGAIN2_OUT :
+{0x6F61,0x51,0x01}, // IBYGAIN2_OUT :
+{0x6F62,0x64,0x01}, // IRYGAIN3_OUT :
+{0x6F63,0x51,0x01}, // IBYGAIN3_OUT :
+{0x6F64,0x64,0x01}, // IRYGAIN4_OUT :
+{0x6F65,0x5A,0x01}, // IBYGAIN4_OUT :
+{0x6F66,0x4B,0x01}, // IRYGAIN1_R2_POS4 :
+{0x6F67,0x50,0x01}, // IBYGAIN1_R2_POS4 :
+{0x6F68,0x4B,0x01}, // IRYGAIN2_R2_POS4 :
+{0x6F69,0x57,0x01}, // IBYGAIN2_R2_POS4 :
+{0x6F6A,0x50,0x01}, // IRYGAIN3_R2_POS4 :
+{0x6F6B,0x57,0x01}, // IBYGAIN3_R2_POS4 :
+{0x6F6C,0x50,0x01}, // IRYGAIN4_R2_POS4 :
+{0x6F6D,0x50,0x01}, // IBYGAIN4_R2_POS4 :
+{0x6F6E,0x4B,0x01}, // IRYGAIN1_R2_POS5 :
+{0x6F6F,0x50,0x01}, // IBYGAIN1_R2_POS5 :
+{0x6F70,0x4B,0x01}, // IRYGAIN2_R2_POS5 :
+{0x6F71,0x57,0x01}, // IBYGAIN2_R2_POS5 :
+{0x6F72,0x50,0x01}, // IRYGAIN3_R2_POS5 :
+{0x6F73,0x57,0x01}, // IBYGAIN3_R2_POS5 :
+{0x6F74,0x50,0x01}, // IRYGAIN4_R2_POS5 :
+{0x6F75,0x50,0x01}, // IBYGAIN4_R2_POS5 :
+
+
+//LMT outdoor setting
+{0x6E54,0xFFB1,0x02}, // LM_GRG_OUT :
+{0x6E56,0x0015,0x02}, // LM_GRB_OUT :
+{0x6E58,0xFFE5,0x02}, // LM_GGR_OUT :
+{0x6E5A,0xFFFA,0x02}, // LM_GGB_OUT :
+{0x6E5C,0xFFDA,0x02}, // LM_GBR_OUT :
+{0x6E5E,0xFFE9,0x02}, // LM_GBG_OUT :
+
+//MC3 ON&OFF
+{0x6C49,0xF5,0x01}, // MAIN_CONFIG4 :
+
+
+////////////////////////////////////////////////////////////////
+
+{0x941F,0x00,0x01}, // AP_N_GC_POS_CORE_A : <<N´ë¿ª Coring ¾ç¼öÃø Äھ ¹üÀ§ A¼³Á¤°ª
+{0x9420,0x00,0x01}, // AP_N_GC_POS_CORE_B :
+{0x9421,0x02,0x01}, // AP_N_GC_POS_CORE_C1 :
+{0x9422,0x01,0x01}, // AP_N_GC_POS_CORE_C2 :
+{0x9423,0x20,0x01}, // AP_N_GC_POS_SLOPE_A : <<N´ë¿ª Coring ¾ç¼öÃø °íÁøÆøÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x9424,0x0D,0x01}, // AP_N_GC_POS_SLOPE_B :
+{0x9425,0x0F,0x01}, // AP_N_GC_POS_SLOPE_C1 :
+{0x9426,0x08,0x01}, // AP_N_GC_POS_SLOPE_C2 :
+{0x9427,0x00,0x01}, // AP_N_GC_NEG_CORE_A : <<N´ë¿ª Coring À½¼öÃøÄھ¹üÀ§ A¼³Á¤°ª
+{0x9428,0x00,0x01}, // AP_N_GC_NEG_CORE_B :
+{0x9429,0x02,0x01}, // AP_N_GC_NEG_CORE_C1 :
+{0x942A,0x01,0x01}, // AP_N_GC_NEG_CORE_C2 :
+{0x942B,0x20,0x01}, // AP_N_GC_NEG_SLOPE_A : <<N´ë¿ª Coring À½¼öÃø °íÁøÆøÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x942C,0x13,0x01}, // AP_N_GC_NEG_SLOPE_B :
+{0x942D,0x10,0x01}, // AP_N_GC_NEG_SLOPE_C1 :
+{0x942E,0x08,0x01}, // AP_N_GC_NEG_SLOPE_C2 :
+{0x942F,0x20,0x01}, // AP_N_GAIN_POS_A : <<N´ë¿ª POST Gain ¾ç¼öÃø A¼³Á¤°ª
+{0x9430,0x3C,0x01}, // AP_N_GAIN_POS_B :
+{0x9431,0x33,0x01}, // AP_N_GAIN_POS_C1 :
+{0x9432,0x30,0x01}, // AP_N_GAIN_POS_C2 :
+{0x9433,0x20,0x01}, // AP_N_GAIN_NEG_A : <<N´ë¿ª POST Gain À½¼öÃø A¼³Á¤°ª
+{0x9434,0x48,0x01}, // AP_N_GAIN_NEG_B :
+{0x9435,0x37,0x01}, // AP_N_GAIN_NEG_C1 :
+{0x9436,0x38,0x01}, // AP_N_GAIN_NEG_C2 :
+////////////////////////////////////////////////////////////////
+
+{0x9437,0x01,0x01}, // AP_H_GC_POS_CORE_A : <<H´ë¿ª Coring ¾ç¼öÃøÄھ¹üÀ§ A¼³Á¤°ª
+{0x9438,0x01,0x01}, // AP_H_GC_POS_CORE_B :
+{0x9439,0x00,0x01}, // AP_H_GC_POS_CORE_C1 :
+{0x943A,0x00,0x01}, // AP_H_GC_POS_CORE_C2 :
+{0x943B,0x38,0x01}, // AP_H_GC_POS_SLOPE_A : <<H´ë¿ª Coring ¾ç¼öÃø °íÁøÆøÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x943C,0x3F,0x01}, // AP_H_GC_POS_SLOPE_B :
+{0x943D,0x30,0x01}, // AP_H_GC_POS_SLOPE_C1 :
+{0x943E,0x13,0x01}, // AP_H_GC_POS_SLOPE_C2 :
+{0x943F,0x00,0x01}, // AP_H_GC_NEG_CORE_A : <<H´ë¿ª Coring À½¼öÃøÄھ¹üÀ§ A¼³Á¤°ª
+{0x9440,0x01,0x01}, // AP_H_GC_NEG_CORE_B :
+{0x9441,0x00,0x01}, // AP_H_GC_NEG_CORE_C1 :
+{0x9442,0x00,0x01}, // AP_H_GC_NEG_CORE_C2 :
+{0x9443,0x38,0x01}, // AP_H_GC_NEG_SLOPE_A : <<H´ë¿ª Coring À½¼öÃø °íÁøÆøÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x9444,0x09,0x01}, // AP_H_GC_NEG_SLOPE_B :
+{0x9445,0x2D,0x01}, // AP_H_GC_NEG_SLOPE_C1 :
+{0x9446,0x0A,0x01}, // AP_H_GC_NEG_SLOPE_C2 :
+{0x9447,0x50,0x01}, // AP_H_GAIN_POS_A : <<H´ë¿ª POST Gain ¾ç¼öÃø A¼³Á¤°ª
+{0x9448,0x38,0x01}, // AP_H_GAIN_POS_B :
+{0x9449,0x72,0x01}, // AP_H_GAIN_POS_C1 :
+{0x944A,0x72,0x01}, // AP_H_GAIN_POS_C2 :
+{0x944B,0x50,0x01}, // AP_H_GAIN_NEG_A : <<H´ë¿ª POST Gain À½¼öÃø A¼³Á¤°ª
+{0x944C,0x40,0x01}, // AP_H_GAIN_NEG_B :
+{0x944D,0x66,0x01}, // AP_H_GAIN_NEG_C1 :
+{0x944E,0x96,0x01}, // AP_H_GAIN_NEG_C2 :
+{0x944F,0x01,0x01}, // AP_L_GC_POS_CORE_A : <<L´ë¿ª Coring ¾ç¼öÃøÄھ¹üÀ§ A¼³Á¤°ª
+{0x9450,0x00,0x01}, // AP_L_GC_POS_CORE_B :
+{0x9451,0x00,0x01}, // AP_L_GC_POS_CORE_C1 :
+{0x9452,0x04,0x01}, // AP_L_GC_POS_CORE_C2
+{0x9453,0x24,0x01}, // AP_L_GC_POS_SLOPE_A : <<L´ë¿ª Coring ¾ç¼öÃø °íÁøÆøÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x9454,0x20,0x01}, // AP_L_GC_POS_SLOPE_B :
+{0x9455,0x08,0x01}, // AP_L_GC_POS_SLOPE_C1 :
+{0x9456,0x08,0x01}, // AP_L_GC_POS_SLOPE_C2 :
+{0x9457,0x01,0x01}, // AP_L_GC_NEG_CORE_A : <L´ë¿ª Coring À½¼öÃøÄھ¹üÀ§ A¼³Á¤°ª
+{0x9458,0x00,0x01}, // AP_L_GC_NEG_CORE_B :
+{0x9459,0x00,0x01}, // AP_L_GC_NEG_CORE_C1
+{0x945A,0x04,0x01}, // AP_L_GC_NEG_CORE_C2
+{0x945B,0x24,0x01}, // AP_L_GC_NEG_SLOPE_A : <<L´ë¿ª Coring À½¼öÃø °íÁøÆøÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x945C,0x20,0x01}, // AP_L_GC_NEG_SLOPE_B :
+{0x945D,0x04,0x01}, // AP_L_GC_NEG_SLOPE_C1 :
+{0x945E,0x04,0x01}, // AP_L_GC_NEG_SLOPE_C2 :
+{0x945F,0x0A,0x01}, // AP_L_GAIN_POS_A : <<L´ë¿ª POST Gain ¾ç¼öÃø A¼³Á¤°ª
+{0x9460,0x11,0x01}, // AP_L_GAIN_POS_B :
+{0x9461,0x1C,0x01}, // AP_L_GAIN_POS_C1 :
+{0x9462,0x60,0x01}, // AP_L_GAIN_POS_C2 :
+{0x9463,0x08,0x01}, // AP_L_GAIN_NEG_A : <<L´ë¿ª POST Gain À½¼öÃø A¼³Á¤°ª
+{0x9464,0x0B,0x01}, // AP_L_GAIN_NEG_B :
+{0x9465,0x0A,0x01}, // AP_L_GAIN_NEG_C1 :
+{0x9466,0x20,0x01}, // AP_L_GAIN_NEG_C2 :
+////////////////////////////////////////////////////////////////
+{0x9468,0x0200,0x02}, // AP_N_GC_POS_TH_A : <<N´ë¿ª Coring ¾ç¼öÃø °íÁøÆø ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x946A,0x00C0,0x02}, // AP_N_GC_POS_TH_B :
+{0x946C,0x0168,0x02}, // AP_N_GC_POS_TH_C1 :
+{0x946E,0x0168,0x02}, // AP_N_GC_POS_TH_C2 :
+{0x9470,0x0200,0x02}, // AP_N_GC_NEG_TH_A : <<N´ë¿ª Coring À½¼öÃø °íÁøÆø ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x9472,0x00C0,0x02}, // AP_N_GC_NEG_TH_B :
+{0x9474,0x00B4,0x02}, // AP_N_GC_NEG_TH_C1 :
+{0x9476,0x00B4,0x02}, // AP_N_GC_NEG_TH_C2 :
+{0x9478,0x0000,0x02}, // AP_N_LD_DARK_TH_A : <<£Î´ë¿ª LevelDepend ÀúÈÖµµ ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x947A,0x0000,0x02}, // AP_N_LD_DARK_TH_B :
+{0x947C,0x0000,0x02}, // AP_N_LD_DARK_TH_C1 :
+{0x947E,0x0000,0x02}, // AP_N_LD_DARK_TH_C2 :
+{0x9480,0x0096,0x02}, // AP_N_LD_HIGH_TH0_X_A: <<£Î´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡0 A¼³Á¤°ª
+{0x9482,0x0050,0x02}, // AP_N_LD_HIGH_TH0_X_B :
+{0x9484,0x0050,0x02}, // AP_N_LD_HIGH_TH0_X_C1 :
+{0x9486,0x0050,0x02}, // AP_N_LD_HIGH_TH0_X_C2 :
+{0x9488,0x0080,0x02}, // AP_N_LD_HIGH_TH0_Y_A : <<£Î´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡0¿¡¼­ÀÇ Ãâ·Â Gain A¼³Á¤°ª
+{0x948A,0x0080,0x02}, // AP_N_LD_HIGH_TH0_Y_B :
+{0x948C,0x0080,0x02}, // AP_N_LD_HIGH_TH0_Y_C1 :
+{0x948E,0x0080,0x02}, // AP_N_LD_HIGH_TH0_Y_C2 :
+{0x9490,0x00C8,0x02}, // AP_N_LD_HIGH_TH1_X_A : <<N´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡1 A¼³Á¤°ª
+{0x9492,0x012C,0x02}, // AP_N_LD_HIGH_TH1_X_B :
+{0x9494,0x00C8,0x02}, // AP_N_LD_HIGH_TH1_X_C1 :
+{0x9496,0x00C8,0x02}, // AP_N_LD_HIGH_TH1_X_C2
+{0x9498,0x01F4,0x02}, // AP_N_LD_HIGH_TH2_X_A : <<N´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡2 A¼³Á¤°ª
+{0x949A,0x0200,0x02}, // AP_N_LD_HIGH_TH2_X_B :
+{0x949C,0x0200,0x02}, // AP_N_LD_HIGH_TH2_X_C1 :
+{0x949E,0x0200,0x02}, // AP_N_LD_HIGH_TH2_X_C2 :
+////////////////////////////////////////////////////////////////
+
+{0x94A0,0x0050,0x02}, // AP_H_GC_POS_TH_A : <<H´ë¿ª Coring ¾ç¼öÃø °íÁøÆø ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x94A2,0x00A0,0x02}, // AP_H_GC_POS_TH_B :
+{0x94A4,0x0033,0x02}, // AP_H_GC_POS_TH_C1 :
+{0x94A6,0x0033,0x02}, // AP_H_GC_POS_TH_C2 :
+{0x94A8,0x0050,0x02}, // AP_H_GC_NEG_TH_A : <<H´ë¿ª Coring À½¼öÃø °íÁøÆø ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x94AA,0x00A0,0x02}, // AP_H_GC_NEG_TH_B :
+{0x94AC,0x0033,0x02}, // AP_H_GC_NEG_TH_C1 :
+{0x94AE,0x0033,0x02}, // AP_H_GC_NEG_TH_C2 :
+{0x94B0,0x0021,0x02}, // AP_H_LD_DARK_TH_A : <<H´ë¿ª LevelDepend ÀúÈÖµµ ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x94B2,0x0000,0x02}, // AP_H_LD_DARK_TH_B :
+{0x94B4,0x0000,0x02}, // AP_H_LD_DARK_TH_C1 :
+{0x94B6,0x0000,0x02}, // AP_H_LD_DARK_TH_C2
+{0x94B8,0x01F4,0x02}, // AP_H_LD_HIGH_TH0_X_A : <<H´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡0 A¼³Á¤°ª
+{0x94BA,0x0083,0x02}, // AP_H_LD_HIGH_TH0_X_B :
+{0x94BC,0x0064,0x02}, // AP_H_LD_HIGH_TH0_X_C1 :
+{0x94BE,0x0064,0x02}, // AP_H_LD_HIGH_TH0_X_C2 :
+{0x94C0,0x0080,0x02}, // AP_H_LD_HIGH_TH0_Y_A : <<H´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡0¿¡¼­ÀÇ Ãâ·Â Gain A¼³Á¤°ª
+{0x94C2,0x0080,0x02}, // AP_H_LD_HIGH_TH0_Y_B :
+{0x94C4,0x0080,0x02}, // AP_H_LD_HIGH_TH0_Y_C1 :
+{0x94C6,0x0080,0x02}, // AP_H_LD_HIGH_TH0_Y_C2 :
+{0x94C8,0x0244,0x02}, // AP_H_LD_HIGH_TH1_X_A : <<H´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡1 A¼³Á¤
+{0x94CA,0x01AA,0x02}, // AP_H_LD_HIGH_TH1_X_B :
+{0x94CC,0x00C8,0x02}, // AP_H_LD_HIGH_TH1_X_C1 :
+{0x94CE,0x00C8,0x02}, // AP_H_LD_HIGH_TH1_X_C2 :
+{0x94D0,0x02EC,0x02}, // AP_H_LD_HIGH_TH2_X_A : <<H´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡2 A¼³Á¤°ª
+{0x94D2,0x01EF,0x02}, // AP_H_LD_HIGH_TH2_X_B :
+{0x94D4,0x01E0,0x02}, // AP_H_LD_HIGH_TH2_X_C1 :
+{0x94D6,0x01E0,0x02}, // AP_H_LD_HIGH_TH2_X_C2 :
+{0x94D8,0x0001,0x02}, // AP_L_GC_POS_TH_A : <<L´ë¿ª Coring ¾ç¼öÃø °íÁøÆø ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x94DA,0x0040,0x02}, // AP_L_GC_POS_TH_B :
+{0x94DC,0x0010,0x02}, // AP_L_GC_POS_TH_C1 :
+{0x94DE,0x0010,0x02}, // AP_L_GC_POS_TH_C2 :
+{0x94E0,0x0001,0x02}, // AP_L_GC_NEG_TH_A : <<L´ë¿ª Coring À½¼öÃø °íÁøÆø ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x94E2,0x0030,0x02}, // AP_L_GC_NEG_TH_B :
+{0x94E4,0x0020,0x02}, // AP_L_GC_NEG_TH_C1 :
+{0x94E6,0x0020,0x02}, // AP_L_GC_NEG_TH_C2 :
+{0x94E8,0x0000,0x02}, // AP_L_LD_DARK_TH_A : <<L´ë¿ª LevelDepend ÀúÈÖµµ ÀÓ°èÄ¡ A¼³Á¤°ª
+{0x94EA,0x0000,0x02}, // AP_L_LD_DARK_TH_B :
+{0x94EC,0x0000,0x02}, // AP_L_LD_DARK_TH_C1 :
+{0x94EE,0x0000,0x02}, // AP_L_LD_DARK_TH_C2 :
+{0x94F0,0x015E,0x02}, // AP_L_LD_HIGH_TH0_X_A : <<L´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡0 A¼³Á¤°ª
+{0x94F2,0x015E,0x02}, // AP_L_LD_HIGH_TH0_X_B :
+{0x94F4,0x0010,0x02}, // AP_L_LD_HIGH_TH0_X_C1 :
+{0x94F6,0x0010,0x02}, // AP_L_LD_HIGH_TH0_X_C2 :
+{0x94F8,0x0080,0x02}, // AP_L_LD_HIGH_TH0_Y_A : <<L´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡0¿¡¼­ÀÇ Ãâ·Â Gain A¼³Á¤°ª
+{0x94FA,0x0080,0x02}, // AP_L_LD_HIGH_TH0_Y_B :
+{0x94FC,0x0080,0x02}, // AP_L_LD_HIGH_TH0_Y_C1 :
+{0x94FE,0x0080,0x02}, // AP_L_LD_HIGH_TH0_Y_C2 :
+{0x9500,0x0226,0x02}, // AP_L_LD_HIGH_TH1_X_A : <<L´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡1 A¼³Á¤°ª
+{0x9502,0x0226,0x02}, // AP_L_LD_HIGH_TH1_X_B :
+{0x9504,0x0020,0x02}, // AP_L_LD_HIGH_TH1_X_C1 :
+{0x9506,0x0020,0x02}, // AP_L_LD_HIGH_TH1_X_C2 :
+{0x9508,0x02A2,0x02}, // AP_L_LD_HIGH_TH2_X_A : <<L´ë¿ª LevelDepend °íÈÖµµ ÀÓ°èÄ¡2 A¼³Á¤°ª
+{0x950A,0x028A,0x02}, // AP_L_LD_HIGH_TH2_X_B :
+{0x950C,0x0050,0x02}, // AP_L_LD_HIGH_TH2_X_C1 :
+{0x950E,0x0050,0x02}, // AP_L_LD_HIGH_TH2_X_C2 :
+
+//blendÈÄ ¸®¹ÌÆ® ¼³Á¤
+
+{0x9510,0x0020,0x02}, // AP_POST_LIM_POS_A : <<
+{0x9512,0x0060,0x02}, // AP_POST_LIM_POS_B :
+{0x9514,0x0060,0x02}, // AP_POST_LIM_POS_C1 :
+{0x9516,0x0060,0x02}, // AP_POST_LIM_POS_C2 :
+{0x9518,0x0030,0x02}, // AP_POST_LIM_NEG_A : <<
+{0x951A,0x0048,0x02}, // AP_POST_LIM_NEG_B :
+{0x951C,0x0048,0x02}, // AP_POST_LIM_NEG_C1 :
+{0x951E,0x0048,0x02}, // AP_POST_LIM_NEG_C2 :
+{0x9520,0x0000,0x02}, // AP_POST_CORE_POS_A : <<
+{0x9522,0x0000,0x02}, // AP_POST_CORE_POS_B :
+{0x9524,0x0001,0x02}, // AP_POST_CORE_POS_C1 :
+{0x9526,0x0001,0x02}, // AP_POST_CORE_POS_C2 :
+{0x9528,0x0002,0x02}, // AP_POST_CORE_NEG_A : <
+{0x952A,0x0000,0x02}, // AP_POST_CORE_NEG_B :
+{0x952C,0x0000,0x02}, // AP_POST_CORE_NEG_C1 :
+{0x952E,0x0000,0x02}, // AP_POST_CORE_NEG_C2 :
+
+//level defender ¼³Á¤
+
+{0x9530,0x0000,0x02}, // AP_N_LD_DARK_SLOPE_A : << N´ë¿ª LevelDepend ÀúÈÖµµÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x9532,0x0000,0x02},
+{0x9534,0x0000,0x02}, // AP_N_LD_DARK_SLOPE_B :
+{0x9536,0x0000,0x02},
+{0x9538,0x0000,0x02}, // AP_N_LD_DARK_SLOPE_C1 :
+{0x953A,0x0000,0x02},
+{0x953C,0x0000,0x02}, // AP_N_LD_DARK_SLOPE_C2 :
+{0x953E,0x0000,0x02},
+{0x9540,0x0061,0x02}, // AP_N_LD_HIGH_SLOPE0_A : << N´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡0¢¦ÀÓ°èÄ¡1¿¡¼­ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x9542,0x0000,0x02},
+{0x9544,0x0031,0x02}, // AP_N_LD_HIGH_SLOPE0_B :
+{0x9546,0x0000,0x02},
+{0x9548,0x0000,0x02}, // AP_N_LD_HIGH_SLOPE0_C1 :
+{0x954A,0x0000,0x02},
+{0x954C,0x0000,0x02}, // AP_N_LD_HIGH_SLOPE0_C2 :
+{0x954E,0x0000,0x02},
+{0x9550,0x001C,0x02}, // AP_N_LD_HIGH_SLOPE1_A : <<N´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡1¢¦ÀÓ°èÄ¡2¿¡¼­ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x9552,0x0000,0x02},
+{0x9554,0x000C,0x02}, // AP_N_LD_HIGH_SLOPE1_B :
+{0x9556,0x0000,0x02},
+{0x9558,0x001A,0x02}, // AP_N_LD_HIGH_SLOPE1_C1 :
+{0x955A,0x0000,0x02},
+{0x955C,0x001A,0x02}, // AP_N_LD_HIGH_SLOPE1_C2 :
+{0x955E,0x0000,0x02},
+{0x9560,0x0000,0x02}, // AP_N_LD_HIGH_SLOPE2_A : <<N´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡2ì¤Ë½ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x9562,0x0000,0x02},
+{0x9564,0x0005,0x02}, // AP_N_LD_HIGH_SLOPE2_B :
+{0x9566,0x0000,0x02},
+{0x9568,0x0014,0x02}, // AP_N_LD_HIGH_SLOPE2_C1 :
+{0x956A,0x0000,0x02},
+{0x956C,0x0014,0x02}, // AP_N_LD_HIGH_SLOPE2_C2 :
+{0x956E,0x0000,0x02},
+{0x9570,0x0000,0x02}, // AP_H_LD_DARK_SLOPE_A : <<H´ë¿ª LevelDepend ÀúÈÖµµÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x9572,0x0000,0x02},
+{0x9574,0x0000,0x02}, // AP_H_LD_DARK_SLOPE_B :
+{0x9576,0x0000,0x02},
+{0x9578,0x0000,0x02}, // AP_H_LD_DARK_SLOPE_C1 :
+{0x957A,0x0000,0x02},
+{0x957C,0x0000,0x02}, // AP_H_LD_DARK_SLOPE_C2 :
+{0x957E,0x0000,0x02},
+{0x9580,0x0025,0x02}, // AP_H_LD_HIGH_SLOPE0_A : <<H´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡0¢¦ÀÓ°èÄ¡1¿¡¼­ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x9582,0x0000,0x02},
+{0x9584,0x0025,0x02}, // AP_H_LD_HIGH_SLOPE0_B :
+{0x9586,0x0000,0x02},
+{0x9588,0x0064,0x02}, // AP_H_LD_HIGH_SLOPE0_C1 :
+{0x958A,0x0000,0x02},
+{0x958C,0x004D,0x02}, // AP_H_LD_HIGH_SLOPE0_C2 :
+{0x958E,0x0000,0x02},
+{0x9590,0x0050,0x02}, // AP_H_LD_HIGH_SLOPE1_A : <<H´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡1¢¦ÀÓ°èÄ¡2¿¡¼­ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x9592,0x0000,0x02},
+{0x9594,0x0050,0x02}, // AP_H_LD_HIGH_SLOPE1_B :
+{0x9596,0x0000,0x02},
+{0x9598,0x0004,0x02}, // AP_H_LD_HIGH_SLOPE1_C1 :
+{0x959A,0x0000,0x02},
+{0x959C,0x000C,0x02}, // AP_H_LD_HIGH_SLOPE1_C2 :
+{0x959E,0x0000,0x02},
+{0x95A0,0x0000,0x02}, // AP_H_LD_HIGH_SLOPE2_A : <<H´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡2ì¤Ë½ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x95A2,0x0000,0x02},
+{0x95A4,0x0000,0x02}, // AP_H_LD_HIGH_SLOPE2_B :
+{0x95A6,0x0000,0x02},
+{0x95A8,0x000D,0x02}, // AP_H_LD_HIGH_SLOPE2_C1 :
+{0x95AA,0x0000,0x02},
+{0x95AC,0x000D,0x02}, // AP_H_LD_HIGH_SLOPE2_C2 :
+{0x95AE,0x0000,0x02},
+{0x95B0,0x0000,0x02}, // AP_L_LD_DARK_SLOPE_A : <<L´ë¿ª LevelDepend ÀúÈÖµµÂÊ ±â¿ï±â A¼³Á¤°ª
+{0x95B2,0x0000,0x02},
+{0x95B4,0x0000,0x02}, // AP_L_LD_DARK_SLOPE_B :
+{0x95B6,0x0000,0x02},
+{0x95B8,0x0000,0x02}, // AP_L_LD_DARK_SLOPE_C1 :
+{0x95BA,0x0000,0x02},
+{0x95BC,0x0000,0x02}, // AP_L_LD_DARK_SLOPE_C2 :
+{0x95BE,0x0000,0x02},
+{0x95C0,0x0020,0x02}, // AP_L_LD_HIGH_SLOPE0_A : <<L´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡0¢¦ÀÓ°èÄ¡1¿¡¼­ÀÇ ±â¿ï±â A¼³Á¤
+{0x95C2,0x0000,0x02},
+{0x95C4,0x0023,0x02}, // AP_L_LD_HIGH_SLOPE0_B :
+{0x95C6,0x0000,0x02},
+{0x95C8,0x012C,0x02}, // AP_L_LD_HIGH_SLOPE0_C1 :
+{0x95CA,0x0000,0x02},
+{0x95CC,0x012C,0x02}, // AP_L_LD_HIGH_SLOPE0_C2 :
+{0x95CE,0x0000,0x02},
+{0x95D0,0x0051,0x02}, // AP_L_LD_HIGH_SLOPE1_A : <<L´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡1¢¦ÀÓ°èÄ¡2¿¡¼­ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x95D2,0x0000,0x02},
+{0x95D4,0x0050,0x02}, // AP_L_LD_HIGH_SLOPE1_B :
+{0x95D6,0x0000,0x02},
+{0x95D8,0x0058,0x02}, // AP_L_LD_HIGH_SLOPE1_C1 :
+{0x95DA,0x0000,0x02},
+{0x95DC,0x0058,0x02}, // AP_L_LD_HIGH_SLOPE1_C2 :
+{0x95DE,0x0000,0x02},
+{0x95E0,0x0000,0x02}, // AP_L_LD_HIGH_SLOPE2_A : <<L´ë¿ª LevelDepend °íÈÖµµÂÊ ÀÓ°èÄ¡2ì¤Ë½ÀÇ ±â¿ï±â A¼³Á¤°ª
+{0x95E2,0x0000,0x02},
+{0x95E4,0x0050,0x02}, // AP_L_LD_HIGH_SLOPE2_B :
+{0x95E6,0x0000,0x02},
+{0x95E8,0x002A,0x02}, // AP_L_LD_HIGH_SLOPE2_C1 :
+{0x95EA,0x0000,0x02},
+{0x95EC,0x002A,0x02}, // AP_L_LD_HIGH_SLOPE2_C2 :
+{0x95EE,0x0000,0x02},
+
+//C-sup tuning
+{0x6C47,0x0F,0x01}, // MAIN_CONFIG2 :
+{0x6C48,0x03,0x01}, // MAIN_CONFIG3 :
+{0x9805,0x0A,0x01}, // CS_SLP_C_A :
+{0x9806,0x0A,0x01}, // CS_SLP_C_B :
+{0x9807,0x0A,0x01}, // CS_SLP_C_C :
+{0x9808,0x20,0x01}, // CS_SLP_YC_A :
+{0x9809,0x20,0x01}, // CS_SLP_YC_B :
+{0x980A,0x20,0x01}, // CS_SLP_YC_C :
+{0x980B,0x20,0x01}, // CS_SLP_Y_A :
+{0x980C,0x20,0x01}, // CS_SLP_Y_B :
+{0x980D,0x20,0x01}, // CS_SLP_Y_C :
+{0x980E,0x14,0x01}, // CS_CBHLEV_A :
+{0x980F,0x14,0x01}, // CS_CBHLEV_B :
+{0x9810,0x14,0x01}, // CS_CBHLEV_C :
+{0x9811,0x14,0x01}, // CS_CRHLEV_A :
+{0x9812,0x14,0x01}, // CS_CRHLEV_B :
+{0x9813,0x14,0x01}, // CS_CRHLEV_C :
+{0x9802,0x77,0x01}, // CS_YHCOEF_A :
+{0x9803,0x77,0x01}, // CS_YHCOEF_B :
+{0x9804,0x77,0x01}, // CS_YHCOEF_C :
+{0x9808,0x20,0x01}, // CS_SLP_YC_A :
+{0x9809,0x20,0x01}, // CS_SLP_YC_B :
+{0x980A,0x20,0x01}, // CS_SLP_YC_C :
+{0x980B,0x20,0x01}, // CS_SLP_Y_A :
+{0x980C,0x20,0x01}, // CS_SLP_Y_B :
+{0x980D,0x20,0x01}, // CS_SLP_Y_C :
+{0x9814,0x14,0x01}, // CS_CBHLEV_Y_A :
+{0x9815,0x14,0x01}, // CS_CBHLEV_Y_B :
+{0x9816,0x14,0x01}, // CS_CBHLEV_Y_C :
+{0x9817,0x00,0x01}, // CS_CRHLEV_Y_A :
+{0x9818,0x00,0x01}, // CS_CRHLEV_Y_B :
+{0x9819,0x00,0x01}, // CS_CRHLEV_Y_C :
+{0x9836,0x0000,0x02}, // CS_CBLLEV_Y_A :
+{0x9838,0x0000,0x02}, // CS_CBLLEV_Y_B :
+{0x983A,0x0000,0x02}, // CS_CBLLEV_Y_C :
+{0x983C,0xFFEC,0x02}, // CS_CRLLEV_Y_A :
+{0x983E,0xFFEC,0x02}, // CS_CRLLEV_Y_B :
+{0x9840,0xFFEC,0x02}, // CS_CRLLEV_Y_C :
+{0x981A,0x03,0x01}, // CS_SLP_YC_L_A :
+{0x981B,0x03,0x01}, // CS_SLP_YC_L_B :
+{0x981C,0x03,0x01}, // CS_SLP_YC_L_C :
+{0x981D,0x32,0x01}, // CS_SLP_Y_L_A :
+{0x981E,0x20,0x01}, // CS_SLP_Y_L_B :
+{0x981F,0x20,0x01}, // CS_SLP_Y_L_C :
+{0x9820,0x1E,0x01}, // CS_YLCOEF_A :
+{0x9821,0x1E,0x01}, // CS_YLCOEF_B :
+{0x9822,0x1E,0x01}, // CS_YLCOEF_C :
+{0x9823,0x32,0x01}, // CS_CBHLEV_Y_L_A :
+{0x9824,0x32,0x01}, // CS_CBHLEV_Y_L_B :
+{0x9825,0x32,0x01}, // CS_CBHLEV_Y_L_C :
+{0x9826,0x32,0x01}, // CS_CRHLEV_Y_L_A :
+{0x9827,0x32,0x01}, // CS_CRHLEV_Y_L_B :
+{0x9828,0x32,0x01}, // CS_CRHLEV_Y_L_C :
+{0x982A,0xFFEC,0x02}, // CS_CBLLEV_A :
+{0x982C,0xFFEC,0x02}, // CS_CBLLEV_B :
+{0x982E,0xFFEC,0x02}, // CS_CBLLEV_C :
+{0x9830,0xFFEC,0x02}, // CS_CRLLEV_A :
+{0x9832,0xFFEC,0x02}, // CS_CRLLEV_B :
+{0x9834,0xFFEC,0x02}, // CS_CRLLEV_C :
+{0x9836,0x0000,0x02}, // CS_CBLLEV_Y_A :
+{0x9838,0x0000,0x02}, // CS_CBLLEV_Y_B :
+{0x983A,0x0000,0x02}, // CS_CBLLEV_Y_C :
+{0x983C,0xFFEC,0x02}, // CS_CRLLEV_Y_A :
+{0x983E,0xFFEC,0x02}, // CS_CRLLEV_Y_B :
+{0x9840,0xFFEC,0x02}, // CS_CRLLEV_Y_C :
+{0x9842,0xFFCE,0x02}, // CS_CBLLEV_Y_L_A :
+{0x9844,0xFFCE,0x02}, // CS_CBLLEV_Y_L_B :
+{0x9846,0xFFCE,0x02}, // CS_CBLLEV_Y_L_C :
+{0x9848,0xFFCE,0x02}, // CS_CRLLEV_Y_L_A :
+{0x984A,0xFFCE,0x02}, // CS_CRLLEV_Y_L_B :
+{0x984C,0xFFCE,0x02}, // CS_CRLLEV_Y_L_C :
+
+//CNR°ü·Ã
+{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 :
+{0x6C4C,0x190A,0x02}, // CNR_CTRL_TH_H :
+{0x6C4E,0x1000,0x02}, // CNR_CTRL_TH_L :
+{0x9866,0x40,0x01}, // CNR_PREHNR_GAIN_A :
+{0x9867,0x00,0x01}, // CNR_PREHNR_GAIN_B :
+{0x9868,0x00,0x01}, // CNR_PREHNR_GAIN_C :
+{0x9869,0x32,0x01}, // CNR_NLM_TH_CR_H_A :
+{0x986A,0x04,0x01}, // CNR_NLM_TH_CR_H_B :
+{0x986B,0x0E,0x01}, // CNR_NLM_TH_CR_H_C :
+{0x986C,0x32,0x01}, // CNR_NLM_TH_CR_L_A :
+{0x986D,0x04,0x01}, // CNR_NLM_TH_CR_L_B :
+{0x986E,0x0E,0x01}, // CNR_NLM_TH_CR_L_C :
+{0x986F,0x32,0x01}, // CNR_NLM_TH_CR_M_H_A :
+{0x9870,0x04,0x01}, // CNR_NLM_TH_CR_M_H_B :
+{0x9871,0x0E,0x01}, // CNR_NLM_TH_CR_M_H_C :
+{0x9872,0x32,0x01}, // CNR_NLM_TH_CR_M_L_A :
+{0x9873,0x04,0x01}, // CNR_NLM_TH_CR_M_L_B :
+{0x9874,0x0E,0x01}, // CNR_NLM_TH_CR_M_L_C :
+{0x9875,0x32,0x01}, // CNR_NLM_TH_CB_H_A :
+{0x9876,0x04,0x01}, // CNR_NLM_TH_CB_H_B :
+{0x9877,0x0E,0x01}, // CNR_NLM_TH_CB_H_C :
+{0x9878,0x32,0x01}, // CNR_NLM_TH_CB_L_A :
+{0x9879,0x04,0x01}, // CNR_NLM_TH_CB_L_B :
+{0x987A,0x0E,0x01}, // CNR_NLM_TH_CB_L_C :
+{0x987B,0x32,0x01}, // CNR_NLM_TH_CB_M_H_A :
+{0x987C,0x04,0x01}, // CNR_NLM_TH_CB_M_H_B :
+{0x987D,0x0E,0x01}, // CNR_NLM_TH_CB_M_H_C :
+{0x987E,0x32,0x01}, // CNR_NLM_TH_CB_M_L_A :
+{0x987F,0x04,0x01}, // CNR_NLM_TH_CB_M_L_B :
+{0x9880,0x0E,0x01}, // CNR_NLM_TH_CB_M_L_C :
+{0x9881,0x7F,0x01}, // CNR_VE_TH_CR_H_A :
+{0x9882,0x01,0x01}, // CNR_VE_TH_CR_H_B :
+{0x9883,0x04,0x01}, // CNR_VE_TH_CR_H_C :
+{0x9884,0x7F,0x01}, // CNR_VE_TH_CR_L_A :
+{0x9885,0x01,0x01}, // CNR_VE_TH_CR_L_B :
+{0x9886,0x04,0x01}, // CNR_VE_TH_CR_L_C :
+{0x9887,0x7F,0x01}, // CNR_VE_TH_CR_M_H_A :
+{0x9888,0x01,0x01}, // CNR_VE_TH_CR_M_H_B :
+{0x9889,0x04,0x01}, // CNR_VE_TH_CR_M_H_C :
+{0x988A,0x7F,0x01}, // CNR_VE_TH_CR_M_L_A :
+{0x988B,0x01,0x01}, // CNR_VE_TH_CR_M_L_B :
+{0x988C,0x04,0x01}, // CNR_VE_TH_CR_M_L_C :
+{0x988D,0x7F,0x01}, // CNR_VE_TH_CB_H_A :
+{0x988E,0x01,0x01}, // CNR_VE_TH_CB_H_B :
+{0x988F,0x04,0x01}, // CNR_VE_TH_CB_H_C :
+{0x9890,0x7F,0x01}, // CNR_VE_TH_CB_L_A :
+{0x9891,0x01,0x01}, // CNR_VE_TH_CB_L_B :
+{0x9892,0x04,0x01}, // CNR_VE_TH_CB_L_C :
+{0x9893,0x7F,0x01}, // CNR_VE_TH_CB_M_H_A :
+{0x9894,0x01,0x01}, // CNR_VE_TH_CB_M_H_B :
+{0x9895,0x04,0x01}, // CNR_VE_TH_CB_M_H_C :
+{0x9896,0x7F,0x01}, // CNR_VE_TH_CB_M_L_A :
+{0x9897,0x01,0x01}, // CNR_VE_TH_CB_M_L_B :
+{0x9898,0x04,0x01}, // CNR_VE_TH_CB_M_L_C :
+{0x9881,0x7F,0x01}, // CNR_VE_TH_CR_H_A :
+{0x9882,0x01,0x01}, // CNR_VE_TH_CR_H_B :
+{0x9883,0x04,0x01}, // CNR_VE_TH_CR_H_C :
+{0x9884,0x7F,0x01}, // CNR_VE_TH_CR_L_A :
+{0x9885,0x01,0x01}, // CNR_VE_TH_CR_L_B :
+{0x9886,0x04,0x01}, // CNR_VE_TH_CR_L_C :
+{0x9887,0x7F,0x01}, // CNR_VE_TH_CR_M_H_A :
+{0x9888,0x01,0x01}, // CNR_VE_TH_CR_M_H_B :
+{0x9889,0x04,0x01}, // CNR_VE_TH_CR_M_H_C :
+{0x988A,0x7F,0x01}, // CNR_VE_TH_CR_M_L_A :
+{0x988B,0x01,0x01}, // CNR_VE_TH_CR_M_L_B :
+{0x988C,0x04,0x01}, // CNR_VE_TH_CR_M_L_C :
+{0x988D,0x7F,0x01}, // CNR_VE_TH_CB_H_A :
+{0x988E,0x01,0x01}, // CNR_VE_TH_CB_H_B :
+{0x988F,0x04,0x01}, // CNR_VE_TH_CB_H_C :
+{0x9890,0x7F,0x01}, // CNR_VE_TH_CB_L_A :
+{0x9891,0x01,0x01}, // CNR_VE_TH_CB_L_B :
+{0x9892,0x04,0x01}, // CNR_VE_TH_CB_L_C :
+{0x9893,0x7F,0x01}, // CNR_VE_TH_CB_M_H_A :
+{0x9894,0x01,0x01}, // CNR_VE_TH_CB_M_H_B :
+{0x9895,0x04,0x01}, // CNR_VE_TH_CB_M_H_C :
+{0x9896,0x7F,0x01}, // CNR_VE_TH_CB_M_L_A :
+{0x9897,0x01,0x01}, // CNR_VE_TH_CB_M_L_B :
+{0x9898,0x04,0x01}, // CNR_VE_TH_CB_M_L_C :
+{0x989A,0x0066,0x02}, // CNR_COEF_CR_H_A :
+{0x989C,0x0100,0x02}, // CNR_COEF_CR_H_B :
+{0x989E,0x0100,0x02}, // CNR_COEF_CR_H_C :
+{0x98A0,0x0066,0x02}, // CNR_COEF_CR_L_A :
+{0x98A2,0x0100,0x02}, // CNR_COEF_CR_L_B :
+{0x98A4,0x0100,0x02}, // CNR_COEF_CR_L_C :
+{0x98A6,0x0066,0x02}, // CNR_COEF_CR_M_H_A :
+{0x98A8,0x0100,0x02}, // CNR_COEF_CR_M_H_B :
+{0x98AA,0x0100,0x02}, // CNR_COEF_CR_M_H_C :
+{0x98AC,0x0066,0x02}, // CNR_COEF_CR_M_L_A :
+{0x98AE,0x0100,0x02}, // CNR_COEF_CR_M_L_B :
+{0x98B0,0x0100,0x02}, // CNR_COEF_CR_M_L_C :
+{0x98B2,0x0066,0x02}, // CNR_COEF_CB_H_A :
+{0x98B4,0x0100,0x02}, // CNR_COEF_CB_H_B :
+{0x98B6,0x0100,0x02}, // CNR_COEF_CB_H_C :
+{0x98B8,0x0066,0x02}, // CNR_COEF_CB_L_A :
+{0x98BA,0x0100,0x02}, // CNR_COEF_CB_L_B :
+{0x98BC,0x0100,0x02}, // CNR_COEF_CB_L_C :
+{0x98BE,0x0066,0x02}, // CNR_COEF_CB_M_H_A :
+{0x98C0,0x0100,0x02}, // CNR_COEF_CB_M_H_B :
+{0x98C2,0x0100,0x02}, // CNR_COEF_CB_M_H_C :
+{0x98C4,0x0066,0x02}, // CNR_COEF_CB_M_L_A :
+{0x98C6,0x0100,0x02}, // CNR_COEF_CB_M_L_B :
+{0x98C8,0x0100,0x02}, // CNR_COEF_CB_M_L_C :
+{0x98CA,0x1770,0x02}, // CNR_EDGE_GAIN_CR_H_A :
+{0x98CC,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_H_B :
+{0x98CE,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_H_C :
+{0x98D0,0x1770,0x02}, // CNR_EDGE_GAIN_CR_L_A :
+{0x98D2,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_L_B :
+{0x98D4,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_L_C :
+{0x98D6,0x1770,0x02}, // CNR_EDGE_GAIN_CR_M_H_A :
+{0x98D8,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_M_H_B :
+{0x98DA,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_M_H_C :
+{0x98DC,0x1770,0x02}, // CNR_EDGE_GAIN_CR_M_L_A :
+{0x98DE,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_M_L_B :
+{0x98E0,0x07D0,0x02}, // CNR_EDGE_GAIN_CR_M_L_C :
+{0x98E2,0x1770,0x02}, // CNR_EDGE_GAIN_CB_H_A :
+{0x98E4,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_H_B :
+{0x98E6,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_H_C :
+{0x98E8,0x1770,0x02}, // CNR_EDGE_GAIN_CB_L_A :
+{0x98EA,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_L_B :
+{0x98EC,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_L_C :
+{0x98EE,0x1770,0x02}, // CNR_EDGE_GAIN_CB_M_H_A :
+{0x98F0,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_M_H_B :
+{0x98F2,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_M_H_C :
+{0x98F4,0x1770,0x02}, // CNR_EDGE_GAIN_CB_M_L_A :
+{0x98F6,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_M_L_B :
+{0x98F8,0x07D0,0x02}, // CNR_EDGE_GAIN_CB_M_L_C :
+{0x98FA,0x7530,0x02}, // CNR_EDGE_TH_CR_H_A :
+{0x98FC,0x0000,0x02}, // CNR_EDGE_TH_CR_H_B :
+{0x98FE,0x0000,0x02}, // CNR_EDGE_TH_CR_H_C :
+{0x9900,0x7530,0x02}, // CNR_EDGE_TH_CR_L_A :
+{0x9902,0x0000,0x02}, // CNR_EDGE_TH_CR_L_B :
+{0x9904,0x0000,0x02}, // CNR_EDGE_TH_CR_L_C :
+{0x9906,0x7530,0x02}, // CNR_EDGE_TH_CR_M_H_A :
+{0x9908,0x0000,0x02}, // CNR_EDGE_TH_CR_M_H_B :
+{0x990A,0x0000,0x02}, // CNR_EDGE_TH_CR_M_H_C :
+{0x990C,0x7530,0x02}, // CNR_EDGE_TH_CR_M_L_A :
+{0x990E,0x0000,0x02}, // CNR_EDGE_TH_CR_M_L_B :
+{0x9910,0x0000,0x02}, // CNR_EDGE_TH_CR_M_L_C :
+{0x9912,0x7530,0x02}, // CNR_EDGE_TH_CB_H_A :
+{0x9914,0x0000,0x02}, // CNR_EDGE_TH_CB_H_B :
+{0x9916,0x0000,0x02}, // CNR_EDGE_TH_CB_H_C :
+{0x9918,0x7530,0x02}, // CNR_EDGE_TH_CB_L_A :
+{0x991A,0x0000,0x02}, // CNR_EDGE_TH_CB_L_B :
+{0x991C,0x0000,0x02}, // CNR_EDGE_TH_CB_L_C :
+{0x991E,0x7530,0x02}, // CNR_EDGE_TH_CB_M_H_A :
+{0x9920,0x0000,0x02}, // CNR_EDGE_TH_CB_M_H_B :
+{0x9922,0x0000,0x02}, // CNR_EDGE_TH_CB_M_H_C :
+{0x9924,0x7530,0x02}, // CNR_EDGE_TH_CB_M_L_A :
+{0x9926,0x0000,0x02}, // CNR_EDGE_TH_CB_M_L_B :
+{0x9928,0x0000,0x02}, // CNR_EDGE_TH_CB_M_L_C :
+
+//ITP NR°ü·Ã
+{0x5005,0xBB,0x01}, // DM_SW1 :
+{0x5006,0x03,0x01}, // DM_SW2 :
+{0x9608,0x0000,0x02}, // DS_GRADCORE_A :
+{0x960A,0x0004,0x02}, // DS_GRADCORE_B :
+{0x960C,0x0000,0x02}, // DS_GRADCORE_C1 :
+{0x960E,0x0000,0x02}, // DS_GRADCORE_C2 :
+{0x9610,0x000A,0x02}, // DS_GRADLIM_A :
+{0x9612,0x0019,0x02}, // DS_GRADLIM_B :
+{0x9614,0x0020,0x02}, // DS_GRADLIM_C1 :
+{0x9616,0x0020,0x02}, // DS_GRADLIM_C2 :
+{0x9600,0x0080,0x02}, // DS_NOISELVL_A :
+{0x9602,0x0039,0x02}, // DS_NOISELVL_B :
+{0x9604,0x0030,0x02}, // DS_NOISELVL_C1 :
+{0x9606,0x0030,0x02}, // DS_NOISELVL_C2
+{0x9670,0x14,0x01}, // YN_SLOPELIMIT_A :
+{0x9671,0x20,0x01}, // YN_SLOPELIMIT_B :
+{0x9672,0x20,0x01}, // YN_SLOPELIMIT_C1 :
+{0x9673,0x20,0x01}, // YN_SLOPELIMIT_C2 :
+{0x9674,0x0032,0x02}, // YN_LNRTH_CORE_A :
+{0x9676,0x0006,0x02}, // YN_LNRTH_CORE_B :
+{0x9678,0x0003,0x02}, // YN_LNRTH_CORE_C1 :
+{0x967A,0x0003,0x02}, // YN_LNRTH_CORE_C2 :
+{0x967C,0x0032,0x02}, // YN_LNRTH_LIM_A :
+{0x967E,0x0058,0x02}, // YN_LNRTH_LIM_B :
+{0x9680,0x00A0,0x02}, // YN_LNRTH_LIM_C1 :
+{0x9682,0x00A0,0x02}, // YN_LNRTH_LIM_C2 :
+{0x9684,0x000F,0x02}, // LN_CNRTH_A :
+{0x9686,0x0014,0x02}, // LN_CNRTH_B :
+{0x9688,0x0014,0x02}, // LN_CNRTH_C1 :
+{0x968A,0x0014,0x02}, // LN_CNRTH_C2 :
+{0x968C,0x0100,0x02}, // CS_BLEND_LL_A :
+{0x968E,0x0000,0x02}, // CS_BLEND_LL_B :
+{0x9690,0x03FF,0x02}, // CS_BLEND_LL_C1 :
+{0x9692,0x03FF,0x02}, // CS_BLEND_LL_C2 :
+{0x9628,0x0008,0x02}, // DS_HLNLBLENDCORE_A :
+{0x962A,0x0003,0x02}, // DS_HLNLBLENDCORE_B :
+{0x962C,0x0000,0x02}, // DS_HLNLBLENDCORE_C1 :
+{0x962E,0x0000,0x02}, // DS_HLNLBLENDCORE_C2 :
+{0x9630,0x0018,0x02}, // DS_HLNLBLENDLIM_A :
+{0x9632,0x0024,0x02}, // DS_HLNLBLENDLIM_B :
+{0x9634,0x0028,0x02}, // DS_HLNLBLENDLIM_C1 :
+{0x9636,0x0028,0x02}, // DS_HLNLBLENDLIM_C2 :
+{0x9638,0x0000,0x02}, // DS_MNBLENDCORE_A :
+{0x963A,0x000C,0x02}, // DS_MNBLENDCORE_B :
+{0x963C,0x0000,0x02}, // DS_MNBLENDCORE_C1 :
+{0x963E,0x0000,0x02}, // DS_MNBLENDCORE_C2 :
+{0x9640,0x0020,0x02}, // DS_MNBLENDLIM_A :
+{0x9642,0x0030,0x02}, // DS_MNBLENDLIM_B :
+{0x9644,0x0080,0x02}, // DS_MNBLENDLIM_C1 :
+{0x9646,0x0080,0x02}, // DS_MNBLENDLIM_C2 :
+{0x9648,0x0008,0x02}, // DS_MHBLENDCORE_A :
+{0x964A,0x0005,0x02}, // DS_MHBLENDCORE_B :
+{0x964C,0x0001,0x02}, // DS_MHBLENDCORE_C1 :
+{0x964E,0x0001,0x02}, // DS_MHBLENDCORE_C2 :
+{0x9650,0x0018,0x02}, // DS_MHBLENDLIM_A :
+{0x9652,0x0041,0x02}, // DS_MHBLENDLIM_B :
+{0x9654,0x005A,0x02}, // DS_MHBLENDLIM_C1 :
+{0x9656,0x0050,0x02}, // DS_MHBLENDLIM_C2 :
+{0x9668,0x0008,0x02}, // DS_NAPMSKLIM_A :
+{0x966A,0x0010,0x02}, // DS_NAPMSKLIM_B :
+{0x966C,0x0018,0x02}, // DS_NAPMSKLIM_C1 :
+{0x966E,0x0018,0x02}, // DS_NAPMSKLIM_C2 :
+{0x9618,0x0018,0x02}, // DS_ZIPSUPCORE_A :
+{0x961A,0x0018,0x02}, // DS_ZIPSUPCORE_B :
+{0x961C,0x0004,0x02}, // DS_ZIPSUPCORE_C1 :
+{0x961E,0x0004,0x02}, // DS_ZIPSUPCORE_C2 :
+{0x9620,0x0010,0x02}, // DS_ZIPSUPLIM_A :
+{0x9622,0x0010,0x02}, // DS_ZIPSUPLIM_B :
+{0x9624,0x0010,0x02}, // DS_ZIPSUPLIM_C1 :
+{0x9626,0x0010,0x02}, // DS_ZIPSUPLIM_C2 :
+{0x9658,0x0020,0x02}, // DS_ICDCORE_A :
+{0x965A,0x0010,0x02}, // DS_ICDCORE_B :
+{0x965C,0x0000,0x02}, // DS_ICDCORE_C1 :
+{0x965E,0x0000,0x02}, // DS_ICDCORE_C2 :
+{0x9660,0x0020,0x02}, // DS_ICDLIM_A :
+{0x9662,0x0040,0x02}, // DS_ICDLIM_B :
+{0x9664,0x0040,0x02}, // DS_ICDLIM_C1 :
+{0x9666,0x0040,0x02}, // DS_ICDLIM_C2 :
+{0x9694,0x000C,0x02}, // CS_EDGE_CSUP_CORE_A :
+{0x9696,0x000C,0x02}, // CS_EDGE_CSUP_CORE_B :
+{0x9698,0x000C,0x02}, // CS_EDGE_CSUP_CORE_C1 :
+{0x969A,0x0006,0x02}, // CS_EDGE_CSUP_CORE_C2 :
+{0x969C,0x000C,0x02}, // CS_EDGE_CSUP_LIM_A :
+{0x969E,0x000C,0x02}, // CS_EDGE_CSUP_LIM_B :
+{0x96A0,0x0010,0x02}, // CS_EDGE_CSUP_LIM_C1 :
+{0x96A2,0x0008,0x02}, // CS_EDGE_CSUP_LIM_C2 :
+{0x96A4,0x0180,0x02}, // CS_SPOT_CSUP_CORE_A :
+{0x96A6,0x0180,0x02}, // CS_SPOT_CSUP_CORE_B :
+{0x96A8,0x0100,0x02}, // CS_SPOT_CSUP_CORE_C1 :
+{0x96AA,0x0100,0x02}, // CS_SPOT_CSUP_CORE_C2 :
+{0x96AC,0x000A,0x02}, // CS_SPOT_CSUP_LIM_A :
+{0x96AE,0x000A,0x02}, // CS_SPOT_CSUP_LIM_B :
+{0x96B0,0x0018,0x02}, // CS_SPOT_CSUP_LIM_C1 :
+{0x96B2,0x0018,0x02}, // CS_SPOT_CSUP_LIM_C2 :
+
+//LMT Á¶µµ¿¬µ¿ Blend °ü·Ã
+{0x9800,0x40,0x01}, //
+{0x9801,0x80,0x01}, //
+
+//°ÔÀוּ¿ Type ¼³Á¤ °ü·Ã
+{0x9217,0x3C,0x01}, // GAIN_TH_A_TYPE5 :
+{0x9218,0x28,0x01}, // GAIN_TH_B_TYPE5 :
+{0x9219,0x1E,0x01}, // GAIN_TH_C_TYPE5 :
+
+//CNR Á¶µµ¿¬µ¿ °ü·Ã
+{0x928F,0x05,0x01}, // CNR_PREHNR_GAIN_SEL :
+{0x9290,0x05,0x01}, // CNR_NLM_TH_CR_H_SEL :
+{0x9291,0x05,0x01}, // CNR_NLM_TH_CR_L_SEL :
+{0x9292,0x05,0x01}, // CNR_NLM_TH_CR_M_H_SEL :
+{0x9293,0x05,0x01}, // CNR_NLM_TH_CR_M_L_SEL :
+{0x9294,0x05,0x01}, // CNR_NLM_TH_CB_H_SEL :
+{0x9295,0x05,0x01}, // CNR_NLM_TH_CB_L_SEL :
+{0x9296,0x05,0x01}, // CNR_NLM_TH_CB_M_H_SEL :
+{0x9297,0x05,0x01}, // CNR_NLM_TH_CB_M_L_SEL :
+{0x9298,0x05,0x01}, // CNR_VE_TH_CR_H_SEL :
+{0x9299,0x05,0x01}, // CNR_VE_TH_CR_L_SEL :
+{0x929A,0x05,0x01}, // CNR_VE_TH_CR_M_H_SEL :
+{0x929B,0x05,0x01}, // CNR_VE_TH_CR_M_L_SEL :
+{0x929C,0x05,0x01}, // CNR_VE_TH_CB_H_SEL :
+{0x929D,0x05,0x01}, // CNR_VE_TH_CB_L_SEL :
+{0x929E,0x05,0x01}, // CNR_VE_TH_CB_M_H_SEL :
+{0x929F,0x05,0x01}, // CNR_VE_TH_CB_M_L_SEL :
+{0x92A0,0x05,0x01}, // CNR_COEF_CR_H_SEL :
+{0x92A1,0x05,0x01}, // CNR_COEF_CR_L_SEL :
+{0x92A2,0x05,0x01}, // CNR_COEF_CR_M_H_SEL :
+{0x92A3,0x05,0x01}, // CNR_COEF_CR_M_L_SEL :
+{0x92A4,0x05,0x01}, // CNR_COEF_CB_H_SEL :
+{0x92A5,0x05,0x01}, // CNR_COEF_CB_L_SEL :
+{0x92A6,0x05,0x01}, // CNR_COEF_CB_M_H_SEL :
+{0x92A7,0x05,0x01}, // CNR_COEF_CB_M_L_SEL :
+{0x92A8,0x05,0x01}, // CNR_EDGE_GAIN_CR_H_SEL :
+{0x92A9,0x05,0x01}, // CNR_EDGE_GAIN_CR_L_SEL :
+{0x92AA,0x05,0x01}, // CNR_EDGE_GAIN_CR_M_H_SEL :
+{0x92AB,0x05,0x01}, // CNR_EDGE_GAIN_CR_M_L_SEL :
+{0x92AC,0x05,0x01}, // CNR_EDGE_GAIN_CB_H_SEL :
+{0x92AD,0x05,0x01}, // CNR_EDGE_GAIN_CB_L_SEL :
+{0x92AE,0x05,0x01}, // CNR_EDGE_GAIN_CB_M_H_SEL :
+{0x92AF,0x05,0x01}, // CNR_EDGE_GAIN_CB_M_L_SEL :
+{0x92B0,0x05,0x01}, // CNR_EDGE_TH_CR_H_SEL :
+{0x92B1,0x05,0x01}, // CNR_EDGE_TH_CR_L_SEL :
+{0x92B2,0x05,0x01}, // CNR_EDGE_TH_CR_M_H_SEL :
+{0x92B3,0x05,0x01}, // CNR_EDGE_TH_CR_M_L_SEL :
+{0x92B4,0x05,0x01}, // CNR_EDGE_TH_CB_H_SEL :
+{0x92B5,0x05,0x01}, // CNR_EDGE_TH_CB_L_SEL :
+{0x92B6,0x05,0x01}, // CNR_EDGE_TH_CB_M_H_SEL :
+{0x92B7,0x05,0x01}, // CNR_EDGE_TH_CB_M_L_SEL :
+
+////////////////MWB & AWB Æ©´×////////////
+{0x6244,0x0B81,0x02}, // USER0R :
+{0x6246,0x1832,0x02}, // USER0B :
+{0x6248,0x0C9E,0x02}, // USER1R : Daylight
+{0x624A,0x1766,0x02}, // USER1B :
+{0x624C,0x09C8,0x02}, // USER2R : Cloudy
+{0x624E,0x1A06,0x02}, // USER2B :
+{0x6250,0x0D61,0x02}, // USER3R : Fluorescent
+{0x6252,0x1161,0x02}, // USER3B :
+{0x6254,0x130B,0x02}, // USER4R : A
+{0x6256,0x0E92,0x02}, // USER4B :
+
+{0x6270,0x0000,0x02}, // USER2_CONT_SHIFT_R : Cloudy cont shift
+{0x6272,0x0000,0x02}, // USER2_CONT_SHIFT_B :
+{0x62C6,0x1096,0x02}, // A_LIGHT_R :
+{0x62C8,0x0F26,0x02}, // A_LIGHT_B :
+{0x62CA,0x00B0,0x02}, // A_LIGHT_AIM_SHIFT_R :
+{0x62CC,0x00C0,0x02}, // A_LIGHT_AIM_SHIFT_B :
+{0x62CE,0x04,0x01}, // A_LIGHT_SCOPE_S_UP :
+{0x62CF,0x04,0x01}, // A_LIGHT_SCOPE_S_DOWN :
+{0x62D0,0x04,0x01}, // A_LIGHT_SCOPE_S_RIGHT :
+{0x62D1,0x04,0x01}, // A_LIGHT_SCOPE_S_LEFT :
+{0x62D2,0x14,0x01}, // A_LIGHT_SCOPE_L_UP :
+{0x62D3,0x14,0x01}, // A_LIGHT_SCOPE_L_DOWN :
+{0x62D4,0x14,0x01}, // A_LIGHT_SCOPE_L_RIGHT :
+{0x62D5,0x14,0x01}, // A_LIGHT_SCOPE_L_LEFT :
+{0x62D6,0x1217,0x02}, // H_LIGHT_R :
+{0x62D8,0x0B95,0x02}, // H_LIGHT_B :
+{0x62DA,0xFF7E,0x02}, // H_LIGHT_AIM_SHIFT_R :
+{0x62DC,0xFF36,0x02}, // H_LIGHT_AIM_SHIFT_B :
+{0x62DE,0x04,0x01}, // H_LIGHT_SCOPE_S_UP :
+{0x62DF,0x04,0x01}, // H_LIGHT_SCOPE_S_DOWN :
+{0x62E0,0x04,0x01}, // H_LIGHT_SCOPE_S_RIGHT :
+{0x62E1,0x04,0x01}, // H_LIGHT_SCOPE_S_LEFT :
+{0x62E2,0x14,0x01}, // H_LIGHT_SCOPE_L_UP :
+{0x62E3,0x17,0x01}, // H_LIGHT_SCOPE_L_DOWN :
+{0x62E4,0x26,0x01}, // H_LIGHT_SCOPE_L_RIGHT :
+{0x62E5,0x19,0x01}, // H_LIGHT_SCOPE_L_LEFT :
+
+/////MC3 Setting/////
+{0x7600,0x07,0x01}, // MC3_PXDEF0_SEL :
+{0x7601,0x07,0x01}, // MC3_PYDEF0_SEL :
+{0x7602,0x07,0x01}, // MC3_PXDEF1_SEL :
+{0x7603,0x07,0x01}, // MC3_PYDEF1_SEL :
+{0x7604,0x07,0x01}, // MC3_PXDEF2_SEL :
+{0x7605,0x07,0x01}, // MC3_PYDEF2_SEL :
+{0x7606,0x07,0x01}, // MC3_PXDEF3_SEL :
+{0x7607,0x07,0x01}, // MC3_PYDEF3_SEL :
+{0x7608,0x40,0x01}, // MC3_PXDEF0_A :
+{0x7609,0x40,0x01}, // MC3_PXDEF0_B :
+{0x760A,0x40,0x01}, // MC3_PXDEF0_C :
+{0x760B,0x40,0x01}, // MC3_PYDEF0_A :
+{0x760C,0x40,0x01}, // MC3_PYDEF0_B :
+{0x760D,0x40,0x01}, // MC3_PYDEF0_C :
+{0x760E,0x40,0x01}, // MC3_PXDEF1_A :
+{0x760F,0x40,0x01}, // MC3_PXDEF1_B :
+{0x7610,0x40,0x01}, // MC3_PXDEF1_C :
+{0x7611,0x40,0x01}, // MC3_PYDEF1_A :
+{0x7612,0x40,0x01}, // MC3_PYDEF1_B :
+{0x7613,0x40,0x01}, // MC3_PYDEF1_C :
+{0x7614,0x40,0x01}, // MC3_PXDEF2_A :
+{0x7615,0x40,0x01}, // MC3_PXDEF2_B :
+{0x7616,0x40,0x01}, // MC3_PXDEF2_C :
+{0x7617,0x40,0x01}, // MC3_PYDEF2_A :
+{0x7618,0x40,0x01}, // MC3_PYDEF2_B :
+{0x7619,0x40,0x01}, // MC3_PYDEF2_C :
+{0x761A,0x40,0x01}, // MC3_PXDEF3_A :
+{0x761B,0x40,0x01}, // MC3_PXDEF3_B :
+{0x761C,0x40,0x01}, // MC3_PXDEF3_C :
+{0x761D,0x40,0x01}, // MC3_PYDEF3_A :
+{0x761E,0x40,0x01}, // MC3_PYDEF3_B :
+{0x761F,0x40,0x01}, // MC3_PYDEF3_C :
+{0x7620,0x00,0x01}, // MC3_LUMSL0_IN :
+{0x7621,0x06,0x01}, // MC3_LUMSL1_IN :
+{0x7622,0x03,0x01}, // MC3_LUMSL2_IN :
+{0x7623,0x06,0x01}, // MC3_LUMSL3_IN :
+{0x7624,0x00,0x01}, // MC3_LUMSL0_OUT :
+{0x7625,0x03,0x01}, // MC3_LUMSL1_OUT :
+{0x7626,0x00,0x01}, // MC3_LUMSL2_OUT :
+{0x7627,0x00,0x01}, // MC3_LUMSL3_OUT :
+{0x7628,0x0000,0x02}, // MC3_L0DEF0_IN :
+{0x762A,0x008C,0x02}, // MC3_L0DEF1_IN :
+{0x762C,0x0078,0x02}, // MC3_L0DEF2_IN :
+{0x762E,0x00E6,0x02}, // MC3_L0DEF3_IN :
+{0x7630,0x0000,0x02}, // MC3_L0DEF0_OUT :
+{0x7632,0x0082,0x02}, // MC3_L0DEF1_OUT :
+{0x7634,0x0000,0x02}, // MC3_L0DEF2_OUT :
+{0x7636,0x0000,0x02}, // MC3_L0DEF3_OUT :
+{0x7638,0x41,0x01}, // MC3_RDEF0_POS1 :
+{0x7639,0x10,0x01}, // MC3_RDEF1_POS1 :
+{0x763A,0x15,0x01}, // MC3_RDEF2_POS1 :
+{0x763B,0x71,0x01}, // MC3_RDEF3_POS1 :
+{0x763C,0x41,0x01}, // MC3_RDEF0_POS2 :
+{0x763D,0x10,0x01}, // MC3_RDEF1_POS2 :
+{0x763E,0x15,0x01}, // MC3_RDEF2_POS2 :
+{0x763F,0x71,0x01}, // MC3_RDEF3_POS2 :
+{0x7640,0x3C,0x01}, // MC3_RDEF0_POS3 :
+{0x7641,0x10,0x01}, // MC3_RDEF1_POS3 :
+{0x7642,0x15,0x01}, // MC3_RDEF2_POS3 :
+{0x7643,0x71,0x01}, // MC3_RDEF3_POS3 :
+{0x7644,0x46,0x01}, // MC3_RDEF0_POS4 :
+{0x7645,0x32,0x01}, // MC3_RDEF1_POS4 :
+{0x7646,0x15,0x01}, // MC3_RDEF2_POS4 :
+{0x7647,0x71,0x01}, // MC3_RDEF3_POS4 :
+{0x7648,0x46,0x01}, // MC3_RDEF0_POS5 :
+{0x7649,0x32,0x01}, // MC3_RDEF1_POS5 :
+{0x764A,0x15,0x01}, // MC3_RDEF2_POS5 :
+{0x764B,0x71,0x01}, // MC3_RDEF3_POS5 :
+{0x764C,0x46,0x01}, // MC3_RDEF0_POS6 :
+{0x764D,0x10,0x01}, // MC3_RDEF1_POS6 :
+{0x764E,0x15,0x01}, // MC3_RDEF2_POS6 :
+{0x764F,0x71,0x01}, // MC3_RDEF3_POS6 :
+{0x7650,0x46,0x01}, // MC3_RDEF0_POS7 :
+{0x7651,0x10,0x01}, // MC3_RDEF1_POS7 :
+{0x7652,0x15,0x01}, // MC3_RDEF2_POS7 :
+{0x7653,0x71,0x01}, // MC3_RDEF3_POS7 :
+{0x7654,0x2D,0x01}, // MC3_RDEF0_OUT :
+{0x7655,0x10,0x01}, // MC3_RDEF1_OUT :
+{0x7656,0x15,0x01}, // MC3_RDEF2_OUT :
+{0x7657,0x54,0x01}, // MC3_RDEF3_OUT :
+{0x7658,0x46,0x01}, // MC3_RDEF0_R2_POS4 :
+{0x7659,0x32,0x01}, // MC3_RDEF1_R2_POS4 :
+{0x765A,0x15,0x01}, // MC3_RDEF2_R2_POS4 :
+{0x765B,0x71,0x01}, // MC3_RDEF3_R2_POS4 :
+{0x765C,0x46,0x01}, // MC3_RDEF0_R2_POS5 :
+{0x765D,0x32,0x01}, // MC3_RDEF1_R2_POS5 :
+{0x765E,0x15,0x01}, // MC3_RDEF2_R2_POS5 :
+{0x765F,0x71,0x01}, // MC3_RDEF3_R2_POS5 :
+{0x7660,0xFFBA,0x02}, // MC3_X0DEF0_POS1 :
+{0x7662,0xFFBA,0x02}, // MC3_Y0DEF0_POS1 :
+{0x7664,0xFFFE,0x02}, // MC3_X0DEF1_POS1 :
+{0x7666,0x000D,0x02}, // MC3_Y0DEF1_POS1 :
+{0x7668,0x0002,0x02}, // MC3_X0DEF2_POS1 :
+{0x766A,0xFFF6,0x02}, // MC3_Y0DEF2_POS1 :
+{0x766C,0x003B,0x02}, // MC3_X0DEF3_POS1 :
+{0x766E,0xFFBB,0x02}, // MC3_Y0DEF3_POS1 :
+{0x7670,0xFFBA,0x02}, // MC3_X0DEF0_POS2 :
+{0x7672,0xFFBA,0x02}, // MC3_Y0DEF0_POS2 :
+{0x7674,0xFFFE,0x02}, // MC3_X0DEF1_POS2 :
+{0x7676,0x000D,0x02}, // MC3_Y0DEF1_POS2 :
+{0x7678,0x0002,0x02}, // MC3_X0DEF2_POS2 :
+{0x767A,0xFFF6,0x02}, // MC3_Y0DEF2_POS2 :
+{0x767C,0x003B,0x02}, // MC3_X0DEF3_POS2 :
+{0x767E,0xFFBB,0x02}, // MC3_Y0DEF3_POS2 :
+{0x7680,0xFFCE,0x02}, // MC3_X0DEF0_POS3 :
+{0x7682,0xFFBA,0x02}, // MC3_Y0DEF0_POS3 :
+{0x7684,0xFFFE,0x02}, // MC3_X0DEF1_POS3 :
+{0x7686,0x000D,0x02}, // MC3_Y0DEF1_POS3 :
+{0x7688,0x0002,0x02}, // MC3_X0DEF2_POS3 :
+{0x768A,0xFFF6,0x02}, // MC3_Y0DEF2_POS3 :
+{0x768C,0x003B,0x02}, // MC3_X0DEF3_POS3 :
+{0x768E,0xFFBB,0x02}, // MC3_Y0DEF3_POS3 :
+{0x7690,0xFFCE,0x02}, // MC3_X0DEF0_POS4 :
+{0x7692,0xFFC9,0x02}, // MC3_Y0DEF0_POS4 :
+{0x7694,0xFFD0,0x02}, // MC3_X0DEF1_POS4 :
+{0x7696,0x0037,0x02}, // MC3_Y0DEF1_POS4 :
+{0x7698,0x0002,0x02}, // MC3_X0DEF2_POS4 :
+{0x769A,0xFFF6,0x02}, // MC3_Y0DEF2_POS4 :
+{0x769C,0x003B,0x02}, // MC3_X0DEF3_POS4 :
+{0x769E,0xFFBB,0x02}, // MC3_Y0DEF3_POS4 :
+{0x76A0,0xFFCE,0x02}, // MC3_X0DEF0_POS5 :
+{0x76A2,0xFFC9,0x02}, // MC3_Y0DEF0_POS5 :
+{0x76A4,0xFFD0,0x02}, // MC3_X0DEF1_POS5 :
+{0x76A6,0x0037,0x02}, // MC3_Y0DEF1_POS5 :
+{0x76A8,0x0002,0x02}, // MC3_X0DEF2_POS5 :
+{0x76AA,0xFFF6,0x02}, // MC3_Y0DEF2_POS5 :
+{0x76AC,0x003B,0x02}, // MC3_X0DEF3_POS5 :
+{0x76AE,0xFFBB,0x02}, // MC3_Y0DEF3_POS5 :
+{0x76B0,0xFFCE,0x02}, // MC3_X0DEF0_POS6 :
+{0x76B2,0xFFC9,0x02}, // MC3_Y0DEF0_POS6 :
+{0x76B4,0xFFFE,0x02}, // MC3_X0DEF1_POS6 :
+{0x76B6,0x000D,0x02}, // MC3_Y0DEF1_POS6 :
+{0x76B8,0x0002,0x02}, // MC3_X0DEF2_POS6 :
+{0x76BA,0xFFF6,0x02}, // MC3_Y0DEF2_POS6 :
+{0x76BC,0x003B,0x02}, // MC3_X0DEF3_POS6 :
+{0x76BE,0xFFBB,0x02}, // MC3_Y0DEF3_POS6 :
+{0x76C0,0xFFCE,0x02}, // MC3_X0DEF0_POS7 :
+{0x76C2,0xFFC9,0x02}, // MC3_Y0DEF0_POS7 :
+{0x76C4,0xFFFE,0x02}, // MC3_X0DEF1_POS7 :
+{0x76C6,0x000D,0x02}, // MC3_Y0DEF1_POS7 :
+{0x76C8,0x0002,0x02}, // MC3_X0DEF2_POS7 :
+{0x76CA,0xFFF6,0x02}, // MC3_Y0DEF2_POS7 :
+{0x76CC,0x003B,0x02}, // MC3_X0DEF3_POS7 :
+{0x76CE,0xFFBB,0x02}, // MC3_Y0DEF3_POS7 :
+{0x76D0,0xFF7E,0x02}, // MC3_X0DEF0_OUT :
+{0x76D2,0xFFE2,0x02}, // MC3_Y0DEF0_OUT :
+{0x76D4,0xFFFE,0x02}, // MC3_X0DEF1_OUT :
+{0x76D6,0x000D,0x02}, // MC3_Y0DEF1_OUT :
+{0x76D8,0x0002,0x02}, // MC3_X0DEF2_OUT :
+{0x76DA,0xFFF6,0x02}, // MC3_Y0DEF2_OUT :
+{0x76DC,0xFFC4,0x02}, // MC3_X0DEF3_OUT :
+{0x76DE,0xFFEC,0x02}, // MC3_Y0DEF3_OUT :
+{0x76E0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS4 :
+{0x76E2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS4 :
+{0x76E4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS4 :
+{0x76E6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS4 :
+{0x76E8,0x0002,0x02}, // MC3_X0DEF2_R2_POS4 :
+{0x76EA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS4 :
+{0x76EC,0x003B,0x02}, // MC3_X0DEF3_R2_POS4 :
+{0x76EE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS4 :
+{0x76F0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS5 :
+{0x76F2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS5 :
+{0x76F4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS5 :
+{0x76F6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS5 :
+{0x76F8,0x0002,0x02}, // MC3_X0DEF2_R2_POS5 :
+{0x76FA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS5 :
+{0x76FC,0x003B,0x02}, // MC3_X0DEF3_R2_POS5 :
+{0x76FE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS5 :
+{0x7700,0x0019,0x02}, // MC3_PXDEF0_POS1 :
+{0x7702,0xFF66,0x02}, // MC3_PYDEF0_POS1 :
+{0x7704,0x0000,0x02}, // MC3_PXDEF1_POS1 :
+{0x7706,0x0000,0x02}, // MC3_PYDEF1_POS1 :
+{0x7708,0x0000,0x02}, // MC3_PXDEF2_POS1 :
+{0x770A,0x0000,0x02}, // MC3_PYDEF2_POS1 :
+{0x770C,0xFFD7,0x02}, // MC3_PXDEF3_POS1 :
+{0x770E,0x0068,0x02}, // MC3_PYDEF3_POS1 :
+{0x7710,0x0000,0x02}, // MC3_PXDEF0_POS2 :
+{0x7712,0xFF66,0x02}, // MC3_PYDEF0_POS2 :
+{0x7714,0x0033,0x02}, // MC3_PXDEF1_POS2 :
+{0x7716,0xFF4C,0x02}, // MC3_PYDEF1_POS2 :
+{0x7718,0x0000,0x02}, // MC3_PXDEF2_POS2 :
+{0x771A,0x00B3,0x02}, // MC3_PYDEF2_POS2 :
+{0x771C,0xFFD7,0x02}, // MC3_PXDEF3_POS2 :
+{0x771E,0x0068,0x02}, // MC3_PYDEF3_POS2 :
+{0x7720,0x0000,0x02}, // MC3_PXDEF0_POS3 :
+{0x7722,0xFF80,0x02}, // MC3_PYDEF0_POS3 :
+{0x7724,0x0000,0x02}, // MC3_PXDEF1_POS3 :
+{0x7726,0x0000,0x02}, // MC3_PYDEF1_POS3 :
+{0x7728,0x0000,0x02}, // MC3_PXDEF2_POS3 :
+{0x772A,0x0000,0x02}, // MC3_PYDEF2_POS3 :
+{0x772C,0xFFD7,0x02}, // MC3_PXDEF3_POS3 :
+{0x772E,0x0068,0x02}, // MC3_PYDEF3_POS3 :
+{0x7730,0x0000,0x02}, // MC3_PXDEF0_POS4 :
+{0x7732,0xFFCC,0x02}, // MC3_PYDEF0_POS4 :
+{0x7734,0x0000,0x02}, // MC3_PXDEF1_POS4 :
+{0x7736,0x0000,0x02}, // MC3_PYDEF1_POS4 :
+{0x7738,0x0000,0x02}, // MC3_PXDEF2_POS4 :
+{0x773A,0x0000,0x02}, // MC3_PYDEF2_POS4 :
+{0x773C,0xFFD7,0x02}, // MC3_PXDEF3_POS4 :
+{0x773E,0x0068,0x02}, // MC3_PYDEF3_POS4 :
+{0x7740,0x0000,0x02}, // MC3_PXDEF0_POS5 :
+{0x7742,0xFFCC,0x02}, // MC3_PYDEF0_POS5 :
+{0x7744,0x0000,0x02}, // MC3_PXDEF1_POS5 :
+{0x7746,0x0000,0x02}, // MC3_PYDEF1_POS5 :
+{0x7748,0x0000,0x02}, // MC3_PXDEF2_POS5 :
+{0x774A,0x0000,0x02}, // MC3_PYDEF2_POS5 :
+{0x774C,0xFFD7,0x02}, // MC3_PXDEF3_POS5 :
+{0x774E,0x0068,0x02}, // MC3_PYDEF3_POS5 :
+{0x7750,0xFFB3,0x02}, // MC3_PXDEF0_POS6 :
+{0x7752,0x0000,0x02}, // MC3_PYDEF0_POS6 :
+{0x7754,0x0033,0x02}, // MC3_PXDEF1_POS6 :
+{0x7756,0xFF4C,0x02}, // MC3_PYDEF1_POS6 :
+{0x7758,0x0000,0x02}, // MC3_PXDEF2_POS6 :
+{0x775A,0x00B3,0x02}, // MC3_PYDEF2_POS6 :
+{0x775C,0xFFD7,0x02}, // MC3_PXDEF3_POS6 :
+{0x775E,0x0068,0x02}, // MC3_PYDEF3_POS6 :
+{0x7760,0xFFB3,0x02}, // MC3_PXDEF0_POS7 :
+{0x7762,0x0000,0x02}, // MC3_PYDEF0_POS7 :
+{0x7764,0x0000,0x02}, // MC3_PXDEF1_POS7 :
+{0x7766,0x0000,0x02}, // MC3_PYDEF1_POS7 :
+{0x7768,0x0000,0x02}, // MC3_PXDEF2_POS7 :
+{0x776A,0x0000,0x02}, // MC3_PYDEF2_POS7 :
+{0x776C,0xFFD7,0x02}, // MC3_PXDEF3_POS7 :
+{0x776E,0x0068,0x02}, // MC3_PYDEF3_POS7 :
+{0x7770,0x0019,0x02}, // MC3_PXDEF0_OUT :
+{0x7772,0xFFE6,0x02}, // MC3_PYDEF0_OUT :
+{0x7774,0x0000,0x02}, // MC3_PXDEF1_OUT :
+{0x7776,0x0000,0x02}, // MC3_PYDEF1_OUT :
+{0x7778,0x0000,0x02}, // MC3_PXDEF2_OUT :
+{0x777A,0x0000,0x02}, // MC3_PYDEF2_OUT :
+{0x777C,0xFFE1,0x02}, // MC3_PXDEF3_OUT :
+{0x777E,0xFFEB,0x02}, // MC3_PYDEF3_OUT :
+{0x7780,0x0000,0x02}, // MC3_PXDEF0_R2_POS4 :
+{0x7782,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS4 :
+{0x7784,0x0000,0x02}, // MC3_PXDEF1_R2_POS4 :
+{0x7786,0x0000,0x02}, // MC3_PYDEF1_R2_POS4 :
+{0x7788,0x0000,0x02}, // MC3_PXDEF2_R2_POS4 :
+{0x778A,0x0000,0x02}, // MC3_PYDEF2_R2_POS4 :
+{0x778C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS4 :
+{0x778E,0x0068,0x02}, // MC3_PYDEF3_R2_POS4 :
+{0x7790,0x0000,0x02}, // MC3_PXDEF0_R2_POS5 :
+{0x7792,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS5 :
+{0x7794,0x0000,0x02}, // MC3_PXDEF1_R2_POS5 :
+{0x7796,0x0000,0x02}, // MC3_PYDEF1_R2_POS5 :
+{0x7798,0x0000,0x02}, // MC3_PXDEF2_R2_POS5 :
+{0x779A,0x0000,0x02}, // MC3_PYDEF2_R2_POS5 :
+{0x779C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS5 :
+{0x779E,0x0068,0x02}, // MC3_PYDEF3_R2_POS5 :
+
+
+{0x6C44,0x13,0x01}, // G_CTRL_SEL :
+{0x0363,0x95,0x01}, // PICT3_GAMMA_MONI1 :
+{0x0366,0x95,0x01}, // PICT3_GAMMA_CAP1 :
+
+
+///////Scene Mode Setting////////////
+{0x0282,0x20,0x01}, //AWB_SN1 :
+{0x0283,0x20,0x01}, //AWB_SN2 :
+{0x0284,0x20,0x01}, //AWB_SN3 :
+{0x0285,0x20,0x01}, //AWB_SN4 :
+{0x0286,0x20,0x01}, //AWB_SN5 :
+{0x0287,0x25,0x01}, //AWB_SN6 :
+{0x0288,0x20,0x01}, //AWB_SN7 :
+{0x0289,0x20,0x01}, //AWB_SN8 :
+{0x028A,0x20,0x01}, //AWB_SN9 :
+{0x028B,0x20,0x01}, //AWB_SN10 :
+{0x028C,0x20,0x01}, //AWB_SN11 :
+{0x028D,0x20,0x01}, //AWB_SN12 :
+{0x028E,0x00,0x01}, //AF_SN1_2 :
+{0x028F,0x00,0x01}, //AF_SN3_4 :
+{0x0290,0x00,0x01}, //AF_SN5_6 :
+{0x0291,0x00,0x01}, //AF_SN7_8 :
+{0x0292,0x00,0x01}, //AF_SN9_10 :
+{0x0293,0x00,0x01}, //AF_SN11_12 :
+{0x0294,0x00,0x01}, //AE_SN1 :
+{0x0295,0x00,0x01}, //AE_SN2 :
+{0x0296,0x00,0x01}, //AE_SN3 :
+{0x0297,0x40,0x01}, //AE_SN4 :
+{0x0298,0x20,0x01}, //AE_SN5 :
+{0x0299,0x00,0x01}, //AE_SN6 :
+{0x029A,0x00,0x01}, //AE_SN7 :
+{0x029B,0x00,0x01}, //AE_SN8 :
+{0x029C,0x60,0x01}, //AE_SN9 :
+{0x029D,0x00,0x01}, //AE_SN10 :
+{0x029E,0x00,0x01}, //AE_SN11 :
+{0x029F,0x00,0x01}, //AE_SN12 :
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : AUTO
+{0x02A9,0x04,0x01}, //ISO_TYPE2 : ISO50
+{0x02AA,0x0A,0x01}, //ISO_TYPE3 : ISO200
+{0x02AB,0x00,0x01}, //ISO_TYPE4 : AUTO
+{0x02AC,0x01,0x01}, //AE_SUB_SN1 :
+{0x02AD,0x00,0x01}, //AE_SUB_SN2 :
+{0x02AE,0x01,0x01}, //AE_SUB_SN3 :
+{0x02AF,0x01,0x01}, //AE_SUB_SN4 :
+{0x02B0,0x01,0x01}, //AE_SUB_SN5 :
+{0x02B1,0x01,0x01}, //AE_SUB_SN6 :
+{0x02B2,0x01,0x01}, //AE_SUB_SN7 :
+{0x02B3,0x01,0x01}, //AE_SUB_SN8 :
+{0x02B4,0x01,0x01}, //AE_SUB_SN9 :
+{0x02B5,0x01,0x01}, //AE_SUB_SN10 :
+{0x02B6,0x02,0x01}, //AE_SUB_SN11 :
+{0x02B7,0x01,0x01}, //AE_SUB_SN12 :
+{0x02EA,0x00,0x01}, //EVREF_MONI_SN1_2 :
+{0x02EB,0x00,0x01}, //EVREF_MONI_SN3_4 :
+{0x02EC,0x03,0x01}, //EVREF_MONI_SN5_6 :
+{0x02ED,0x00,0x01}, //EVREF_MONI_SN7_8 :
+{0x02EE,0x00,0x01}, //EVREF_MONI_SN9_10 :
+{0x02EF,0x00,0x01}, //EVREF_MONI_SN11_12 :
+{0x02F0,0x01,0x01}, //EVREF_CAP_SN1_2 :
+{0x02F1,0x00,0x01}, //EVREF_CAP_SN3_4 :
+{0x02F2,0x03,0x01}, //EVREF_CAP_SN5_6 :
+{0x02F3,0x00,0x01}, //EVREF_CAP_SN7_8 :
+{0x02F4,0x00,0x01}, //EVREF_CAP_SN9_10 :
+{0x02F5,0x00,0x01}, //EVREF_CAP_SN11_12 :
+{0x02F6,0x00,0x01}, //EVREF_MOVIE_SN1_2 :
+{0x02F7,0x00,0x01}, //EVREF_MOVIE_SN3_4 :
+{0x02F8,0x03,0x01}, //EVREF_MOVIE_SN5_6 :
+{0x02F9,0x00,0x01}, //EVREF_MOVIE_SN7_8 :
+{0x02FA,0x00,0x01}, //EVREF_MOVIE_SN9_10 :
+{0x02FB,0x00,0x01}, //EVREF_MOVIE_SN11_12 :
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x0390,0xA4,0x01}, //PICT1_SN2 :
+{0x0391,0x00,0x01}, //PICT1_SN3 :
+{0x0392,0x04,0x01}, //PICT1_SN4 :
+{0x0393,0x04,0x01}, //PICT1_SN5 :
+{0x0394,0x00,0x01}, //PICT1_SN6 :
+{0x0395,0x50,0x01}, //PICT1_SN7 :
+{0x0396,0x0A,0x01}, //PICT1_SN8 :
+{0x0397,0x00,0x01}, //PICT1_SN9 :
+{0x0398,0xA0,0x01}, //PICT1_SN10 :
+{0x0399,0x00,0x01}, //PICT1_SN11 :
+{0x039A,0x00,0x01}, //PICT1_SN12 :
+{0x039B,0x00,0x01}, //UIHUE_TYPE1 :
+{0x039C,0x00,0x01}, //UIHUE_TYPE2 :
+{0x039D,0x00,0x01}, //UIHUE_TYPE3 :
+{0x039E,0x80,0x01}, //UISATURATION_TYPE1 :
+{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 :
+{0x03A0,0x80,0x01}, //UISATURATION_TYPE3 :
+{0x03A1,0x20,0x01}, //UISHARPNESS_POS_TYPE1 :
+{0x03A2,0x14,0x01}, //UISHARPNESS_POS_TYPE2 :
+{0x03A3,0x2C,0x01}, //UISHARPNESS_POS_TYPE3 :
+{0x03A4,0x20,0x01}, //UISHARPNESS_NEG_TYPE1 :
+{0x03A5,0x14,0x01}, //UISHARPNESS_NEG_TYPE2 :
+{0x03A6,0x2C,0x01}, //UISHARPNESS_NEG_TYPE3 :
+{0x0308,0x11,0x01}, //AELINE_MONI_SN1_2 :
+{0x0309,0x13,0x01}, //AELINE_MONI_SN3_4 :
+{0x030A,0x11,0x01}, //AELINE_MONI_SN5_6 :
+{0x030B,0x41,0x01}, //AELINE_MONI_SN7_8 :
+{0x030C,0x19,0x01}, //AELINE_MONI_SN9_10 :
+{0x030D,0x11,0x01}, //AELINE_MONI_SN11_12 :
+{0x030E,0x11,0x01}, //AELINE_HALF_SN1_2 :
+{0x030F,0x13,0x01}, //AELINE_HALF_SN3_4 :
+{0x0310,0x11,0x01}, //AELINE_HALF_SN5_6 :
+{0x0311,0x41,0x01}, //AELINE_HALF_SN7_8 :
+{0x0312,0x19,0x01}, //AELINE_HALF_SN9_10 :
+{0x0313,0x11,0x01}, //AELINE_HALF_SN11_12 :
+{0x0314,0x11,0x01}, //AELINE_HALF_AFEND_SN1_2 :
+{0x0315,0x13,0x01}, //AELINE_HALF_AFEND_SN3_4 :
+{0x0316,0x11,0x01}, //AELINE_HALF_AFEND_SN5_6 :
+{0x0317,0x41,0x01}, //AELINE_HALF_AFEND_SN7_8 :
+{0x0318,0x19,0x01}, //AELINE_HALF_AFEND_SN9_10 :
+{0x0319,0x11,0x01}, //AELINE_HALF_AFEND_SN11_12 :
+{0x031A,0x00,0x01}, //AELINE_CAP_SN1_2 :
+{0x031B,0x03,0x01}, //AELINE_CAP_SN3_4 :
+{0x031C,0x00,0x01}, //AELINE_CAP_SN5_6 :
+{0x031D,0x50,0x01}, //AELINE_CAP_SN7_8 :
+{0x031E,0x08,0x01}, //AELINE_CAP_SN9_10 :
+{0x031F,0x00,0x01}, //AELINE_CAP_SN11_12 :
+{0x0320,0x22,0x01}, //AELINE_MOVIE_SN1_2 :
+{0x0321,0x22,0x01}, //AELINE_MOVIE_SN3_4 :
+{0x0322,0x22,0x01}, //AELINE_MOVIE_SN5_6 :
+{0x0323,0x22,0x01}, //AELINE_MOVIE_SN7_8 :
+{0x0324,0x22,0x01}, //AELINE_MOVIE_SN9_10 :
+{0x0325,0x22,0x01}, //AELINE_MOVIE_SN11_12 :
+{0x02DB,0x33,0x01}, //VADD_SHTGAIN_CTRL_SN1_2 :
+{0x02DC,0x33,0x01}, //VADD_SHTGAIN_CTRL_SN3_4 :
+{0x02DD,0x33,0x01}, //VADD_SHTGAIN_CTRL_SN5_6 :
+{0x02DE,0x33,0x01}, //VADD_SHTGAIN_CTRL_SN7_8 :
+{0x02DF,0x33,0x01}, //VADD_SHTGAIN_CTRL_SN9_10 :
+{0x02E0,0x33,0x01}, //VADD_SHTGAIN_CTRL_SN11_12 :
+{0x0383,0x80,0x01}, // MC3_MODE_SN_1 :
+{0x0384,0x80,0x01}, // MC3_MODE_SN_2 :
+{0x0385,0x80,0x01}, // MC3_MODE_SN_3 :
+{0x0386,0x80,0x01}, // MC3_MODE_SN_4 :
+{0x0387,0x80,0x01}, // MC3_MODE_SN_5 :
+{0x0388,0x80,0x01}, // MC3_MODE_SN_6 :
+{0x0389,0x80,0x01}, // MC3_MODE_SN_7 :
+{0x038A,0x80,0x01}, // MC3_MODE_SN_8 :
+{0x038B,0x80,0x01}, // MC3_MODE_SN_9 :
+{0x038C,0x80,0x01}, // MC3_MODE_SN_10 :
+{0x038D,0x80,0x01}, // MC3_MODE_SN_11 :
+{0x038E,0x80,0x01}, // MC3_MODE_SN_12 :
+
+///AWBÃʱâÁÂÇ¥
+{0x6238,0x0BE3,0x02}, // INIT_CONT_INR :
+{0x623A,0x1718,0x02}, // INIT_CONT_INB :
+{0x623C,0x0BBB,0x02}, // INIT_CONT_OUTR :
+{0x623E,0x18B7,0x02}, // INIT_CONT_OUTB :
+
+//bluesky brightness setting
+{0x6298,0xB0,0x01}, // SHADE_JUDGPOS :
+{0x6299,0xB5,0x01}, // BLUESKY_JUDGPOS :
+
+//EV SEL gain step
+{0x5E6B,0x04,0x01}, // EVSEL_GAIN_P1_3 :
+{0x5E6C,0x08,0x01}, // EVSEL_GAIN_P2_3 :
+{0x5E6D,0x0C,0x01}, // EVSEL_GAIN_P3_3 :
+{0x5E6E,0x10,0x01}, // EVSEL_GAIN_P4_3 :
+{0x5E6F,0x14,0x01}, // EVSEL_GAIN_P5_3 :
+{0x5E70,0x18,0x01}, // EVSEL_GAIN_P6_3 :
+{0x5E71,0x05,0x01}, // EVSEL_GAIN_M1_3 :
+{0x5E72,0x0A,0x01}, // EVSEL_GAIN_M2_3 :
+{0x5E73,0x0F,0x01}, // EVSEL_GAIN_M3_3 :
+{0x5E74,0x16,0x01}, // EVSEL_GAIN_M4_3 :
+{0x5E75,0x1B,0x01}, // EVSEL_GAIN_M5_3 :
+{0x5E76,0x20,0x01}, // EVSEL_GAIN_M6_3 :
+
+//In, Out judge
+{0x62A2,0x8C,0x01}, // INOUT_WEIGHT_AREA_ST : 140
+{0x6258,0xA0,0x01}, // IN_JUDGPOS : 160
+{0x6259,0xA1,0x01}, // OUT_JUDGPOS : 161
+{0x62A3,0xA4,0x01}, // INOUT_WEIGHT_AREA_ED : 164
+{0x62A4,0x92,0x01}, // IN_LUMST : 146
+{0x62A5,0x9C,0x01}, // OUT_LUMST : 156
+
+//ISO output setting
+{0x5E3F,0x00,0x01}, // ISOSENS_OUT_SEL :
+
+/* ++CONFIG_MACH_KONA */
+{0x008C,0x03,0x01},
+{0x008D,0x03,0x01},
+{0x008E,0x03,0x01},
+{0x0082,0x01,0x01},
+/* --CONFIG_MACH_KONA */
+};
+
+// ISX012-0
+// MIPI 2LANE 648
+// PLL 648MHz
+// DCK 81
+// inifile
+// size address data
+//
+static const isx012_regset_t ISX012_Pll_Setting_2[] =
+{
+{0x0007,0x01,0x01}, // PLL_CKSEL : PLL 648MHz
+{0x0008,0x03,0x01}, // SRCCK_DIV : 1/8 frequency
+
+{0x0004,0x03,0x01}, //I2C_ADR_SEL 2: 0x3C MIPI selected, 3: 0x3D MIPI selected
+{0x5008,0x00,0x01}, //ENDIAN_SEL : 0:Little Endian
+{0x6DA8,0x01,0x01}, //SHD_CoEF (OTP shading ON flag)
+{0x6DA9,0x09,0x01}, // WHITE_CTRL
+{0x6DCB,0x22,0x01}, // YGAM_CONFIG2 :
+
+{0x00C4,0x11,0x01}, // VIF_CLKCONFIG1 : VIFSEL and VIFDIV setting value with full frame pixel setting for other then JPG
+{0x00C5,0x11,0x01}, // VIF_CLKCONFIG2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other then JPG
+{0x00C6,0x11,0x01}, // VIF_CLKCONFIG3 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other then JPG
+{0x00C7,0x11,0x01}, // VIF_CLKCONFIG4 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other then JPG
+{0x00C8,0x11,0x01}, // VIF_CLKCONFIG5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode
+{0x00C9,0x11,0x01}, // VIF_CLKCONFIG6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode
+{0x00CA,0x11,0x01}, // VIF_CLKCONFIG7 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for JPG mode
+{0x018C,0x0000,0x02}, // VADJ_SENS_1_1 : VMAX adjustment value for full frame pixel
+{0x018E,0x0000,0x02}, // VADJ_SENS_1_2 : VMAX adjustment value for 1/2 sub-sampling
+{0x0190,0x0000,0x02}, // VADJ_SENS_1_4 : VMAX adjustment value for 1/4 sub-sampling
+{0x0192,0x0000,0x02}, // VADJ_SENS_1_8 : VMAX adjustment value for 1/8 sub-sampling
+{0x0194,0x0000,0x02}, // VADJ_SENS_HD_1_1 : VMAX adjustment value for HD full frame pixel
+{0x0196,0x0000,0x02}, // VADJ_SENS_HD_1_2 : VMAX adjustment value for HD 1/2 sub-sampling
+{0x6A16,0x0400,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_1 : Detection window vertical size with all 32 windows for FLC full frame pixel
+{0x6A18,0x03C0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_2 : Detection window vertical size with all 32 windows for FLC 1/2 sub-sampling
+{0x6A1A,0x01E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_4 : Detection window vertical size with all 32 windows for FLC 1/4 sub-sampling
+{0x6A1C,0x00E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_8 : Detection window vertical size with all 32 windows for FLC 1/8 sub-sampling
+{0x6A1E,0x0400,0x02}, // FLC_OPD_HEIGHT_HD_1_1 : Detection window vertical size with all 32 windows for FLC HD full frame pixel
+{0x6A20,0x02C0,0x02}, // FLC_OPD_HEIGHT_HD_1_2 : Detection window vertical size with all 32 windows for FLC HD 1/2 sub-sampling
+{0x0016,0x0010,0x02}, // GPIO_FUNCSEL : GPIO setting
+{0x5C01,0x00,0x01}, // RGLANESEL : Select 1Lane or 2Lane
+
+{0x5C04,0x06,0x01}, // RGTLPX : //0x5C04 0x4 -> 0x6
+{0x5C05,0x05,0x01}, // RGTCLKPREPARE : //0x5C05 0x3 -> 0x5
+{0x5C06,0x14,0x01}, // RGTCLKZERO :
+{0x5C07,0x02,0x01}, // RGTCLKPRE :
+{0x5C08,0x0D,0x01}, // RGTCLKPOST : //0x5C08 0x11 -> 0xD
+{0x5C09,0x07,0x01}, // RGTCLKTRAIL : //0x5C09 0x5 -> 0x7
+{0x5C0A,0x0A,0x01}, // RGTHSEXIT : //0x5C0A 0x7 -> 0xA
+{0x5C0B,0x05,0x01}, // RGTHSPREPARE : //0x5C0B 0x3 -> 0x5
+{0x5C0C,0x08,0x01}, // RGTHSZERO : //0x5C0C 0x7 -> 0x8
+{0x5C0D,0x07,0x01}, // RGTHSTRAIL : //0x5C0D 0x5 -> 0x7
+
+{0x0009,0x01,0x01}, // EXT_PLL_CKSEL : PLL 648MHz
+{0x00D0,0x11,0x01}, // VIF_CLKCONFIG_EXT1 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG and interleave mode
+{0x00D1,0x11,0x01}, // VIF_CLKCONFIG_EXT2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG and interleave mode
+{0x00D4,0x11,0x01}, // VIF_CLKCONFIG_EXT5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode
+{0x00D5,0x11,0x01}, // VIF_CLKCONFIG_EXT6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode
+{0x00D8,0x11,0x01}, // VIF_CLKCONFIG_EXT9 : VIFSEL and VIFDIV setting value with full frame pixel setting for other than JPG
+{0x00D9,0x11,0x01}, // VIF_CLKCONFIG_EXT10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other than JPG
+
+//init Preview setting
+{0x0089,0x00,0x01},//OUTFMT_MONI
+{0x0090,0x0280,0x02},//HSIZE_MONI : 640
+{0x0096,0x01E0,0x02},//VSIZE_MONI : 480
+{0x0083,0x01,0x01},//SENSMODE_MONI
+{0x0086,0x02,0x01},//FPSTYPE_MONI
+{0x0081,0x00,0x01},//MODESEL
+{0x0082,0x01,0x01},//MONI_REFRESH
+
+//jpeg setting
+//Apex40 is not Jpeg Capture
+
+//Fast mode setting
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT
+
+//Select sensor inversion link control
+{0x501A,0x00,0x01}, //SENS_REVERSE_CTRL
+
+//shading
+{0x6DBC,0x03,0x01}, // WHITE_EDGE_MAX :
+{0x6DF6,0xFF,0x01}, // WHITE_SHD_JUDGE_BODY_COLOR_RATIO :
+{0x6DF7,0xF0,0x01}, // WHITE_SHD_JUDGE_RED_RATIO :
+{0x6DAD,0x0C,0x01}, // WHITE_OFSET1_UP :
+{0x6DAE,0x0C,0x01}, // WHITE_OFSET1_DOWN :
+{0x6DAF,0x11,0x01}, // WHITE_OFSET1_RIGHT :
+{0x6DB0,0x1B,0x01}, // WHITE_OFSET1_LEFT :
+{0x6DB1,0x0D,0x01}, // WHITE_OFSET2_UP :
+{0x6DB2,0x13,0x01}, // WHITE_OFSET2_DOWN :
+{0x6DB3,0x11,0x01}, // WHITE_OFSET2_RIGHT :
+{0x6DB4,0x17,0x01}, // WHITE_OFSET2_LEFT :
+
+//addtional code
+{0xF200,0xB9B9,0x02},
+{0xF202,0x4E12,0x02},
+{0xF204,0x6055,0x02},
+{0xF206,0x008B,0x02},
+{0xF208,0xF177,0x02},
+{0xF20A,0xFA70,0x02},
+{0xF20C,0x0000,0x02},
+{0xF20E,0x0000,0x02},
+{0xF210,0x0000,0x02},
+{0xF212,0x0000,0x02},
+{0xF214,0x0000,0x02},
+{0xF216,0x0000,0x02},
+{0xF218,0x0000,0x02},
+{0xF21A,0x0000,0x02},
+{0xF21C,0x0000,0x02},
+{0xF21E,0x0000,0x02},
+{0xF220,0x0000,0x02},
+{0xF222,0x0000,0x02},
+{0xF224,0x0000,0x02},
+{0xF226,0x0000,0x02},
+{0xF228,0x0000,0x02},
+{0xF22A,0x0000,0x02},
+{0xF22C,0x0000,0x02},
+{0xF22E,0x0000,0x02},
+{0xF230,0x0000,0x02},
+{0xF232,0x0000,0x02},
+{0xF234,0x0000,0x02},
+{0xF236,0x0000,0x02},
+{0xF238,0x0000,0x02},
+{0xF23A,0x0000,0x02},
+{0xF23C,0x0000,0x02},
+{0xF23E,0x0000,0x02},
+{0xF240,0x0000,0x02},
+{0xF242,0x0000,0x02},
+{0xF244,0xB47E,0x02},
+{0xF246,0x4808,0x02},
+{0xF248,0x7800,0x02},
+{0xF24A,0x07C0,0x02},
+{0xF24C,0x0FC0,0x02},
+{0xF24E,0xF687,0x02},
+{0xF250,0xF8ED,0x02},
+{0xF252,0xF68E,0x02},
+{0xF254,0xFE2B,0x02},
+{0xF256,0xF688,0x02},
+{0xF258,0xFF6B,0x02},
+{0xF25A,0xF693,0x02},
+{0xF25C,0xFB6B,0x02},
+{0xF25E,0xF687,0x02},
+{0xF260,0xF947,0x02},
+{0xF262,0xBC7E,0x02},
+{0xF264,0xF688,0x02},
+{0xF266,0xFD8F,0x02},
+{0xF268,0x239C,0x02},
+{0xF26A,0x0018,0x02},
+
+
+{0x0006,0x16,0x01}, //INCK_SET : 24MHz
+};
+
+// ISX012-0
+// MIPI 2LANE 432/LANE
+// PLL 432MHz
+// DCK 54
+// inifile
+// size address data
+//
+static const isx012_regset_t ISX012_Pll_Setting_3[] =
+{
+{0x0007,0x00,0x01}, // PLL_CKSEL : PLL 432MHz
+{0x0008,0x00,0x01}, // SRCCK_DIV : 1/5 frequency
+
+{0x0004,0x03,0x01}, //I2C_ADR_SEL 2: 0x3C MIPI selected, 3: 0x3D MIPI selected
+{0x5008,0x00,0x01}, //ENDIAN_SEL : 0:Little Endian
+{0x6DA8,0x01,0x01}, //SHD_CoEF (OTP shading ON flag)
+{0x6DA9,0x09,0x01}, // WHITE_CTRL
+{0x6DCB,0x22,0x01}, // YGAM_CONFIG2 :
+
+{0x00C4,0x11,0x01}, // VIF_CLKCONFIG1 : VIFSEL and VIFDIV setting value with full frame pixel setting for other then JPG
+{0x00C5,0x11,0x01}, // VIF_CLKCONFIG2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other then JPG
+{0x00C6,0x11,0x01}, // VIF_CLKCONFIG3 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other then JPG
+{0x00C7,0x11,0x01}, // VIF_CLKCONFIG4 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other then JPG
+{0x00C8,0x11,0x01}, // VIF_CLKCONFIG5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode
+{0x00C9,0x11,0x01}, // VIF_CLKCONFIG6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode
+{0x00CA,0x11,0x01}, // VIF_CLKCONFIG7 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for JPG mode
+{0x00CC,0x11,0x01}, // VIF_CLKCONFIG9 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG and interleave mode
+{0x00CD,0x11,0x01}, // VIF_CLKCONFIG10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG and interleave mode
+{0x6A12,0x11,0x01}, // VIF_CLKCONFIG13 for RAW8 : VIFSEL and VIFDIV setting value with full frame pixel setting for RAW mode
+{0x6A13,0x11,0x01}, // VIF_CLKCONFIG14 for RAW8 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for RAW mode
+{0x6A14,0x11,0x01}, // VIF_CLKCONFIG15 for RAW8 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for RAW mode
+{0x6A15,0x11,0x01}, // VIF_CLKCONFIG16 for RAW8 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for RAW mode
+{0x018C,0x0000,0x02}, // VADJ_SENS_1_1 : VMAX adjustment value for full frame pixel
+{0x018E,0x0012,0x02}, // VADJ_SENS_1_2 : VMAX adjustment value for 1/2 sub-sampling
+{0x0190,0x0000,0x02}, // VADJ_SENS_1_4 : VMAX adjustment value for 1/4 sub-sampling
+{0x0192,0x0000,0x02}, // VADJ_SENS_1_8 : VMAX adjustment value for 1/8 sub-sampling
+{0x0194,0x0027,0x02}, // VADJ_SENS_HD_1_1 : VMAX adjustment value for HD full frame pixel
+{0x0196,0x0015,0x02}, // VADJ_SENS_HD_1_2 : VMAX adjustment value for HD 1/2 sub-sampling
+{0x6A16,0x0440,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_1 : Detection window vertical size with all 32 windows for FLC full frame pixel
+{0x6A18,0x03C0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_2 : Detection window vertical size with all 32 windows for FLC 1/2 sub-sampling
+{0x6A1A,0x01E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_4 : Detection window vertical size with all 32 windows for FLC 1/4 sub-sampling
+{0x6A1C,0x00E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_8 : Detection window vertical size with all 32 windows for FLC 1/8 sub-sampling
+{0x6A1E,0x0420,0x02}, // FLC_OPD_HEIGHT_HD_1_1 : Detection window vertical size with all 32 windows for FLC HD full frame pixel
+{0x6A20,0x02C0,0x02}, // FLC_OPD_HEIGHT_HD_1_2 : Detection window vertical size with all 32 windows for FLC HD 1/2 sub-sampling
+{0x0016,0x0010,0x02}, // GPIO_FUNCSEL : GPIO setting
+{0x5C01,0x00,0x01}, // RGLANESEL :
+{0x5C04,0x04,0x01}, // RGTLPX :
+{0x5C05,0x03,0x01}, // RGTCLKPREPARE :
+{0x5C06,0x0E,0x01}, // RGTCLKZERO :
+{0x5C07,0x02,0x01}, // RGTCLKPRE :
+{0x5C08,0x0B,0x01}, // RGTCLKPOST :
+{0x5C09,0x05,0x01}, // RGTCLKTRAIL :
+{0x5C0A,0x07,0x01}, // RGTHSEXIT :
+{0x5C0B,0x03,0x01}, // RGTHSPREPARE :
+{0x5C0C,0x07,0x01}, // RGTHSZERO :
+{0x5C0D,0x05,0x01}, // RGTHSTRAIL :
+
+{0x0009,0x01,0x01}, //
+{0x000A,0x03,0x01}, // EXT_SRCCK_DIV : 1/8 frequency
+{0x00D8,0x11,0x01}, // VIF_CLKCONFIG_EXT9 : VIFSEL and VIFDIV setting value with full frame pixel setting for other than JPG
+{0x00D9,0x11,0x01}, // VIF_CLKCONFIG_EXT10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other than JPG
+{0x00DA,0x11,0x01}, // VIF_CLKCONFIG_EXT11 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other than JPG
+{0x00DB,0x11,0x01}, // VIF_CLKCONFIG_EXT12 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other than JPG
+{0x00AC,0x02,0x01}, //
+
+//init Preview setting
+{0x0089,0x00,0x01},//OUTFMT_MONI
+{0x0090,0x0280,0x02},//HSIZE_MONI : 640
+{0x0096,0x01E0,0x02},//VSIZE_MONI : 480
+{0x0083,0x01,0x01},//SENSMODE_MONI
+{0x0086,0x02,0x01},//FPSTYPE_MONI
+{0x0081,0x00,0x01},//MODESEL
+{0x0082,0x01,0x01},//MONI_REFRESH
+
+//jpeg setting
+//Apex40 is not Jpeg Capture
+
+//Fast mode setting
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT
+
+//Select sensor inversion link control
+{0x501A,0x00,0x01}, //SENS_REVERSE_CTRL
+
+//shading
+{0x6DBC,0x03,0x01}, // WHITE_EDGE_MAX :
+{0x6DF6,0xFF,0x01}, // WHITE_SHD_JUDGE_BODY_COLOR_RATIO :
+{0x6DF7,0xF0,0x01}, // WHITE_SHD_JUDGE_RED_RATIO :
+{0x6DAD,0x0C,0x01}, // WHITE_OFSET1_UP :
+{0x6DAE,0x0C,0x01}, // WHITE_OFSET1_DOWN :
+{0x6DAF,0x11,0x01}, // WHITE_OFSET1_RIGHT :
+{0x6DB0,0x1B,0x01}, // WHITE_OFSET1_LEFT :
+{0x6DB1,0x0D,0x01}, // WHITE_OFSET2_UP :
+{0x6DB2,0x13,0x01}, // WHITE_OFSET2_DOWN :
+{0x6DB3,0x11,0x01}, // WHITE_OFSET2_RIGHT :
+{0x6DB4,0x17,0x01}, // WHITE_OFSET2_LEFT :
+
+//additional code
+{0xF200,0xB9B9,0x02},
+{0xF202,0x4E12,0x02},
+{0xF204,0x6055,0x02},
+{0xF206,0x008B,0x02},
+{0xF208,0xF177,0x02},
+{0xF20A,0xFA70,0x02},
+{0xF20C,0x0000,0x02},
+{0xF20E,0x0000,0x02},
+{0xF210,0x0000,0x02},
+{0xF212,0x0000,0x02},
+{0xF214,0x0000,0x02},
+{0xF216,0x0000,0x02},
+{0xF218,0x0000,0x02},
+{0xF21A,0x0000,0x02},
+{0xF21C,0x0000,0x02},
+{0xF21E,0x0000,0x02},
+{0xF220,0x0000,0x02},
+{0xF222,0x0000,0x02},
+{0xF224,0x0000,0x02},
+{0xF226,0x0000,0x02},
+{0xF228,0x0000,0x02},
+{0xF22A,0x0000,0x02},
+{0xF22C,0x0000,0x02},
+{0xF22E,0x0000,0x02},
+{0xF230,0x0000,0x02},
+{0xF232,0x0000,0x02},
+{0xF234,0x0000,0x02},
+{0xF236,0x0000,0x02},
+{0xF238,0x0000,0x02},
+{0xF23A,0x0000,0x02},
+{0xF23C,0x0000,0x02},
+{0xF23E,0x0000,0x02},
+{0xF240,0x0000,0x02},
+{0xF242,0x0000,0x02},
+{0xF244,0xB47E,0x02},
+{0xF246,0x4808,0x02},
+{0xF248,0x7800,0x02},
+{0xF24A,0x07C0,0x02},
+{0xF24C,0x0FC0,0x02},
+{0xF24E,0xF687,0x02},
+{0xF250,0xF8ED,0x02},
+{0xF252,0xF68E,0x02},
+{0xF254,0xFE2B,0x02},
+{0xF256,0xF688,0x02},
+{0xF258,0xFF6B,0x02},
+{0xF25A,0xF693,0x02},
+{0xF25C,0xFB6B,0x02},
+{0xF25E,0xF687,0x02},
+{0xF260,0xF947,0x02},
+{0xF262,0xBC7E,0x02},
+{0xF264,0xF688,0x02},
+{0xF266,0xFD8F,0x02},
+{0xF268,0x239C,0x02},
+{0xF26A,0x0018,0x02},
+
+{0x0006,0x16,0x01}, //INCK_SET : 24MHz
+};
+
+// ISX012-0
+// MIPI 2LANE 432/LANE
+// PLL 432MHz
+// DCK 54
+// inifile
+// size address data
+//
+static const isx012_regset_t ISX012_Pll_Setting_4[] =
+{
+{0x0007,0x00,0x01}, // PLL_CKSEL : PLL 432MHz
+{0x0008,0x00,0x01}, // SRCCK_DIV : 1/5 frequency
+
+{0x0004,0x03,0x01}, //I2C_ADR_SEL 2: 0x3C MIPI selected, 3: 0x3D MIPI selected
+{0x5008,0x00,0x01}, //ENDIAN_SEL : 0:Little Endian
+{0x6DA8,0x01,0x01}, //SHD_CoEF (OTP shading ON flag)
+{0x6DA9,0x09,0x01}, // WHITE_CTRL
+{0x6DCB,0x22,0x01}, // YGAM_CONFIG2 :
+
+{0x00C4,0x11,0x01}, // VIF_CLKCONFIG1 : VIFSEL and VIFDIV setting value with full frame pixel setting for other then JPG
+{0x00C5,0x11,0x01}, // VIF_CLKCONFIG2 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other then JPG
+{0x00C6,0x11,0x01}, // VIF_CLKCONFIG3 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other then JPG
+{0x00C7,0x11,0x01}, // VIF_CLKCONFIG4 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other then JPG
+{0x00C8,0x11,0x01}, // VIF_CLKCONFIG5 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG mode
+{0x00C9,0x11,0x01}, // VIF_CLKCONFIG6 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG mode
+{0x00CA,0x11,0x01}, // VIF_CLKCONFIG7 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for JPG mode
+{0x00CC,0x11,0x01}, // VIF_CLKCONFIG9 : VIFSEL and VIFDIV setting value with full frame pixel setting for JPG and interleave mode
+{0x00CD,0x11,0x01}, // VIF_CLKCONFIG10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for JPG and interleave mode
+{0x6A12,0x11,0x01}, // VIF_CLKCONFIG13 for RAW8 : VIFSEL and VIFDIV setting value with full frame pixel setting for RAW mode
+{0x6A13,0x11,0x01}, // VIF_CLKCONFIG14 for RAW8 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for RAW mode
+{0x6A14,0x11,0x01}, // VIF_CLKCONFIG15 for RAW8 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for RAW mode
+{0x6A15,0x11,0x01}, // VIF_CLKCONFIG16 for RAW8 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for RAW mode
+{0x018C,0x0026,0x02}, // VADJ_SENS_1_1 : VMAX adjustment value for full frame pixel
+{0x018E,0x0012,0x02}, // VADJ_SENS_1_2 : VMAX adjustment value for 1/2 sub-sampling
+{0x0190,0x0000,0x02}, // VADJ_SENS_1_4 : VMAX adjustment value for 1/4 sub-sampling
+{0x0192,0x0000,0x02}, // VADJ_SENS_1_8 : VMAX adjustment value for 1/8 sub-sampling
+{0x0194,0x0027,0x02}, // VADJ_SENS_HD_1_1 : VMAX adjustment value for HD full frame pixel
+{0x0196,0x0015,0x02}, // VADJ_SENS_HD_1_2 : VMAX adjustment value for HD 1/2 sub-sampling
+{0x6A16,0x0440,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_1 : Detection window vertical size with all 32 windows for FLC full frame pixel
+{0x6A18,0x03C0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_2 : Detection window vertical size with all 32 windows for FLC 1/2 sub-sampling
+{0x6A1A,0x01E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_4 : Detection window vertical size with all 32 windows for FLC 1/4 sub-sampling
+{0x6A1C,0x00E0,0x02}, // FLC_OPD_HEIGHT_NORMAL_1_8 : Detection window vertical size with all 32 windows for FLC 1/8 sub-sampling
+{0x6A1E,0x0420,0x02}, // FLC_OPD_HEIGHT_HD_1_1 : Detection window vertical size with all 32 windows for FLC HD full frame pixel
+{0x6A20,0x02C0,0x02}, // FLC_OPD_HEIGHT_HD_1_2 : Detection window vertical size with all 32 windows for FLC HD 1/2 sub-sampling
+{0x0016,0x0010,0x02}, // GPIO_FUNCSEL : GPIO setting
+{0x5C01,0x00,0x01}, // RGLANESEL :
+{0x5C04,0x04,0x01}, // RGTLPX :
+{0x5C05,0x03,0x01}, // RGTCLKPREPARE :
+{0x5C06,0x0E,0x01}, // RGTCLKZERO :
+{0x5C07,0x02,0x01}, // RGTCLKPRE :
+{0x5C08,0x0B,0x01}, // RGTCLKPOST :
+{0x5C09,0x05,0x01}, // RGTCLKTRAIL :
+{0x5C0A,0x07,0x01}, // RGTHSEXIT :
+{0x5C0B,0x03,0x01}, // RGTHSPREPARE :
+{0x5C0C,0x07,0x01}, // RGTHSZERO :
+{0x5C0D,0x05,0x01}, // RGTHSTRAIL :
+
+{0x6A9E,0x15C0,0x02}, //HMAX_1_1(0x6A9E)=0x15C0
+
+{0x0009,0x01,0x01}, //
+{0x000A,0x03,0x01}, // EXT_SRCCK_DIV : 1/8 frequency
+{0x00D8,0x11,0x01}, // VIF_CLKCONFIG_EXT9 : VIFSEL and VIFDIV setting value with full frame pixel setting for other than JPG
+{0x00D9,0x11,0x01}, // VIF_CLKCONFIG_EXT10 : VIFSEL and VIFDIV setting value with 1/2 sub-sampling setting for other than JPG
+{0x00DA,0x11,0x01}, // VIF_CLKCONFIG_EXT11 : VIFSEL and VIFDIV setting value with 1/4 sub-sampling setting for other than JPG
+{0x00DB,0x11,0x01}, // VIF_CLKCONFIG_EXT12 : VIFSEL and VIFDIV setting value with 1/8 sub-sampling setting for other than JPG
+{0x00AC,0x00,0x01}, //
+
+//init Preview setting
+{0x0089,0x00,0x01},//OUTFMT_MONI
+{0x0090,0x0280,0x02},//HSIZE_MONI : 640
+{0x0096,0x01E0,0x02},//VSIZE_MONI : 480
+{0x0083,0x01,0x01},//SENSMODE_MONI
+{0x0086,0x02,0x01},//FPSTYPE_MONI
+{0x0081,0x00,0x01},//MODESEL
+{0x0082,0x01,0x01},//MONI_REFRESH
+
+//jpeg setting
+//Apex40 is not Jpeg Capture
+
+//Fast mode setting
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT
+
+//Select sensor inversion link control
+{0x501A,0x00,0x01}, //SENS_REVERSE_CTRL
+
+//shading
+{0x6DBC,0x03,0x01}, // WHITE_EDGE_MAX :
+{0x6DF6,0xFF,0x01}, // WHITE_SHD_JUDGE_BODY_COLOR_RATIO :
+{0x6DF7,0xF0,0x01}, // WHITE_SHD_JUDGE_RED_RATIO :
+{0x6DAD,0x0C,0x01}, // WHITE_OFSET1_UP :
+{0x6DAE,0x0C,0x01}, // WHITE_OFSET1_DOWN :
+{0x6DAF,0x11,0x01}, // WHITE_OFSET1_RIGHT :
+{0x6DB0,0x1B,0x01}, // WHITE_OFSET1_LEFT :
+{0x6DB1,0x0D,0x01}, // WHITE_OFSET2_UP :
+{0x6DB2,0x13,0x01}, // WHITE_OFSET2_DOWN :
+{0x6DB3,0x11,0x01}, // WHITE_OFSET2_RIGHT :
+{0x6DB4,0x17,0x01}, // WHITE_OFSET2_LEFT :
+
+//additional code
+{0xF200,0xB9B9,0x02},
+{0xF202,0x4E12,0x02},
+{0xF204,0x6055,0x02},
+{0xF206,0x008B,0x02},
+{0xF208,0xF177,0x02},
+{0xF20A,0xFA70,0x02},
+{0xF20C,0x0000,0x02},
+{0xF20E,0x0000,0x02},
+{0xF210,0x0000,0x02},
+{0xF212,0x0000,0x02},
+{0xF214,0x0000,0x02},
+{0xF216,0x0000,0x02},
+{0xF218,0x0000,0x02},
+{0xF21A,0x0000,0x02},
+{0xF21C,0x0000,0x02},
+{0xF21E,0x0000,0x02},
+{0xF220,0x0000,0x02},
+{0xF222,0x0000,0x02},
+{0xF224,0x0000,0x02},
+{0xF226,0x0000,0x02},
+{0xF228,0x0000,0x02},
+{0xF22A,0x0000,0x02},
+{0xF22C,0x0000,0x02},
+{0xF22E,0x0000,0x02},
+{0xF230,0x0000,0x02},
+{0xF232,0x0000,0x02},
+{0xF234,0x0000,0x02},
+{0xF236,0x0000,0x02},
+{0xF238,0x0000,0x02},
+{0xF23A,0x0000,0x02},
+{0xF23C,0x0000,0x02},
+{0xF23E,0x0000,0x02},
+{0xF240,0x0000,0x02},
+{0xF242,0x0000,0x02},
+{0xF244,0xB47E,0x02},
+{0xF246,0x4808,0x02},
+{0xF248,0x7800,0x02},
+{0xF24A,0x07C0,0x02},
+{0xF24C,0x0FC0,0x02},
+{0xF24E,0xF687,0x02},
+{0xF250,0xF8ED,0x02},
+{0xF252,0xF68E,0x02},
+{0xF254,0xFE2B,0x02},
+{0xF256,0xF688,0x02},
+{0xF258,0xFF6B,0x02},
+{0xF25A,0xF693,0x02},
+{0xF25C,0xFB6B,0x02},
+{0xF25E,0xF687,0x02},
+{0xF260,0xF947,0x02},
+{0xF262,0xBC7E,0x02},
+{0xF264,0xF688,0x02},
+{0xF266,0xFD8F,0x02},
+{0xF268,0x239C,0x02},
+{0xF26A,0x0018,0x02},
+
+{0x0006,0x16,0x01}, //INCK_SET : 24MHz
+};
+
+static const isx012_regset_t ISX012_Preview_SizeSetting[] =
+{
+{0x0090,0x0280,0x02}, //HSIZE_MONI : 640
+{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480
+};
+
+static const isx012_regset_t ISX012_Preview_Mode[] =
+{
+{0x5000,0x00,0x01}, /* CPUEXT, added by SAMSUNG TN */
+{0x5E32,0x0F,0x01}, /* for Fast-AE reset */
+{0x5E3D,0x0A,0x01}, /* for Fast-AE reset */
+{0x0181,0x00,0x01}, // CAP_HALF_AE_CTRL
+
+{0x0089,0x00,0x01}, //OUTFMT_MONI
+{0x0083,0x01,0x01}, //SENSMODE_MONI
+{0x0086,0x02,0x01}, //FPSTYPE_MONI
+{0x0012,0xFF,0x01}, //INTCLR0
+{0x00F7,0x52,0x01}, // INIT_QLTY0 : Standard 82
+{0x00F8,0x59,0x01}, // INIT_QLTY1 : Fine 89
+{0x00F9,0x5F,0x01}, // INIT_QLTY2 : SuperFine 95
+{0x0081,0x00,0x01}, //MODESEL
+{0x0082,0x01,0x01}, //MONI_REFRESH
+{0xFFFF,0x1E,0x01}, //$wait,30
+};
+
+static const isx012_regset_t ISX012_Camcorder_Mode_ON[] =
+{
+//SN setting
+{0x0308,0x02,0x01}, // AELINE_MONI_SN1_2 :
+{0x0320,0x02,0x01}, // AELINE_MONI_SN1_2 :
+{0x00B2,0x02,0x01}, /* AFMODE_MONI : manual mode */
+
+//BRIGHTNESS setting
+{0x01C6,0x10,0x01}, //UIBRIGHTNESS
+
+//AE speed
+{0x02AC,0x00,0x01}, // AE_SUB_SN1 :
+{0x5E2D,0x0C,0x01}, // AEMOVECNT :
+{0x5E2E,0x20,0x01}, // AEINDEADBAND :
+{0x5E2F,0x08,0x01}, // AEOUTDEADBAND :
+{0x5E30,0xA0,0x01}, // AESPEED :
+
+{0x5E31,0x0F,0x01}, // AESPEED_INIT :
+{0x5E32,0x0F,0x01}, // AESPEED_FAST :
+
+{0x621E,0x18,0x01}, // AIM_NR_TH_UP :
+{0x621F,0x18,0x01}, // AIM_NR_TH_DOWN :
+{0x6220,0x18,0x01}, // AIM_NR_TH_RIGHT :
+{0x6221,0x18,0x01}, // AIM_NR_TH_LEFT :
+
+//AWB speed
+{0x6222,0x00,0x01}, // INIT_AIMW :
+{0x6223,0x04,0x01}, // INIT_GAINS :
+{0x6224,0x10,0x01}, // ATW_DELAY :
+{0x6225,0x00,0x01}, // ATW_AIMW :
+
+{0x6226,0x20,0x01}, // ATW_GAINS_IN_NR :
+{0x6227,0x30,0x01}, // ATW_GAINS_IN :
+{0x6228,0x20,0x01}, // ATW_GAINS_OUT_NR :
+{0x6229,0x30,0x01}, // ATW_GAINS_OUT :
+{0x622A,0x0D,0x01}, // ALLWB_GAINS :
+
+//Gammma Table 0
+{0x7000,0x0000,0x02}, // G0_KNOT_G0 :
+{0x7002,0x0000,0x02}, // G0_KNOT_G1 :
+{0x7004,0x001E,0x02}, // G0_KNOT_G2 :
+{0x7006,0x0038,0x02}, // G0_KNOT_G3 :
+{0x7008,0x0046,0x02}, // G0_KNOT_G4 :
+{0x700A,0x0053,0x02}, // G0_KNOT_G5 :
+{0x700C,0x005A,0x02}, // G0_KNOT_G6 :
+{0x700E,0x0063,0x02}, // G0_KNOT_G7 :
+{0x7010,0x006D,0x02}, // G0_KNOT_G8 :
+{0x7012,0x0076,0x02}, // G0_KNOT_G9 :
+{0x7014,0x0055,0x02}, // G0_KNOT_G10 :
+{0x7016,0x008E,0x02}, // G0_KNOT_G11 :
+{0x7018,0x00B9,0x02}, // G0_KNOT_G12 :
+{0x701A,0x00D5,0x02}, // G0_KNOT_G13 :
+{0x701C,0x00E4,0x02}, // G0_KNOT_G14 :
+{0x701E,0x00F0,0x02}, // G0_KNOT_G15 :
+{0x7020,0x00F9,0x02}, // G0_KNOT_G16 :
+{0x7022,0x0103,0x02}, // G0_KNOT_G17 :
+{0x7024,0x010C,0x02}, // G0_KNOT_G18 :
+{0x7026,0x00,0x01}, // G0_KNOT_R0_OFFSET :
+{0x7027,0x00,0x01}, // G0_KNOT_R2_OFFSET :
+{0x7028,0x00,0x01}, // G0_KNOT_R4_OFFSET :
+{0x7029,0x00,0x01}, // G0_KNOT_R6_OFFSET :
+{0x702A,0x00,0x01}, // G0_KNOT_R8_OFFSET :
+{0x702B,0x00,0x01}, // G0_KNOT_R10_OFFSET :
+{0x702C,0x00,0x01}, // G0_KNOT_R12_OFFSET :
+{0x702D,0x00,0x01}, // G0_KNOT_R14_OFFSET :
+{0x702E,0x00,0x01}, // G0_KNOT_R16_OFFSET :
+{0x702F,0x00,0x01}, // G0_KNOT_R18_OFFSET :
+{0x7030,0x00,0x01}, // G0_KNOT_B0_OFFSET :
+{0x7031,0x00,0x01}, // G0_KNOT_B2_OFFSET :
+{0x7032,0x00,0x01}, // G0_KNOT_B4_OFFSET :
+{0x7033,0x00,0x01}, // G0_KNOT_B6_OFFSET :
+{0x7034,0x00,0x01}, // G0_KNOT_B8_OFFSET :
+{0x7035,0x00,0x01}, // G0_KNOT_B10_OFFSET :
+{0x7036,0x00,0x01}, // G0_KNOT_B12_OFFSET :
+{0x7037,0x00,0x01}, // G0_KNOT_B14_OFFSET :
+{0x7038,0x00,0x01}, // G0_KNOT_B16_OFFSET :
+{0x7039,0x00,0x01}, // G0_KNOT_B18_OFFSET :
+{0x703A,0x0611,0x02}, // G0_LOWGM_ON_R :
+{0x703C,0x1E0A,0x02}, // G0_0CLIP_R :
+{0x703E,0x0611,0x02}, // G0_LOWGM_ON_G :
+{0x7040,0x1E0A,0x02}, // G0_0CLIP_G :
+{0x7042,0x0611,0x02}, // G0_LOWGM_ON_B :
+{0x7044,0x1E0A,0x02}, // G0_0CLIP_B :
+{0x7046,0x91,0x01}, // G0_KNOT_GAINCTRL_TH_L :
+{0x7047,0x96,0x01}, // G0_KNOT_GAINCTRL_TH_H :
+{0x7048,0x0000,0x02}, // G0_KNOT_L_G0 :
+{0x704A,0x0000,0x02}, // G0_KNOT_L_G1 :
+{0x704C,0x000E,0x02}, // G0_KNOT_L_G2 :
+{0x704E,0x002F,0x02}, // G0_KNOT_L_G3 :
+{0x7050,0x003D,0x02}, // G0_KNOT_L_G4 :
+{0x7052,0x004A,0x02}, // G0_KNOT_L_G5 :
+{0x7054,0x0051,0x02}, // G0_KNOT_L_G6 :
+{0x7056,0x005A,0x02}, // G0_KNOT_L_G7 :
+{0x7058,0x0061,0x02}, // G0_KNOT_L_G8 :
+{0x705A,0x006A,0x02}, // G0_KNOT_L_G9 :
+{0x705C,0x0049,0x02}, // G0_KNOT_L_G10 :
+{0x705E,0x0082,0x02}, // G0_KNOT_L_G11 :
+{0x7060,0x00AD,0x02}, // G0_KNOT_L_G12 :
+{0x7062,0x00CC,0x02}, // G0_KNOT_L_G13 :
+{0x7064,0x00E1,0x02}, // G0_KNOT_L_G14 :
+{0x7066,0x00ED,0x02}, // G0_KNOT_L_G15 :
+{0x7068,0x00F6,0x02}, // G0_KNOT_L_G16 :
+{0x706A,0x0106,0x02}, // G0_KNOT_L_G17 :
+{0x706C,0x010C,0x02}, // G0_KNOT_L_G18 :
+
+
+{0x6400,0x00,0x01}, // INFRM_LEFT00 :
+{0x6401,0x00,0x01}, // INFRM_LEFT01 :
+{0x6402,0x00,0x01}, // INFRM_LEFT02 :
+{0x6403,0x00,0x01}, // INFRM_LEFT03 :
+{0x6404,0x00,0x01}, // INFRM_LEFT04 :
+{0x6405,0x00,0x01}, // INFRM_LEFT05 :
+{0x6406,0x00,0x01}, // INFRM_LEFT06 :
+{0x6407,0x00,0x01}, // INFRM_LEFT07 :
+{0x6408,0x00,0x01}, // INFRM_LEFT08 :
+{0x6409,0x00,0x01}, // INFRM_LEFT09 :
+{0x640A,0x00,0x01}, // INFRM_LEFT10 :
+{0x640B,0x00,0x01}, // INFRM_LEFT11 :
+{0x640C,0x00,0x01}, // INFRM_LEFT12 :
+{0x640D,0x00,0x01}, // INFRM_LEFT13 :
+{0x640E,0x00,0x01}, // INFRM_LEFT14 :
+{0x640F,0x00,0x01}, // INFRM_LEFT15 :
+{0x6410,0x00,0x01}, // INFRM_LEFT16 :
+{0x6411,0x00,0x01}, // INFRM_LEFT17 :
+{0x6412,0x00,0x01}, // INFRM_LEFT18 :
+{0x6413,0x00,0x01}, // INFRM_LEFT19 :
+{0x6414,0x00,0x01}, // INFRM_LEFT20 :
+{0x6415,0x00,0x01}, // INFRM_LEFT21 :
+{0x6416,0x00,0x01}, // INFRM_LEFT22 :
+{0x6417,0x00,0x01}, // INFRM_LEFT23 :
+{0x6418,0x00,0x01}, // INFRM_LEFT24 :
+{0x6419,0x00,0x01}, // INFRM_LEFT25 :
+{0x641A,0x00,0x01}, // INFRM_LEFT26 :
+{0x641B,0x00,0x01}, // INFRM_LEFT27 :
+{0x641C,0x00,0x01}, // INFRM_LEFT28 :
+{0x641D,0x00,0x01}, // INFRM_LEFT29 :
+{0x641E,0x00,0x01}, // INFRM_LEFT30 :
+{0x641F,0x00,0x01}, // INFRM_LEFT31 :
+{0x6420,0x00,0x01}, // INFRM_LEFT32 :
+{0x6421,0x00,0x01}, // INFRM_LEFT33 :
+{0x6422,0x00,0x01}, // INFRM_LEFT34 :
+{0x6423,0x00,0x01}, // INFRM_LEFT35 :
+{0x6424,0x00,0x01}, // INFRM_LEFT36 :
+{0x6425,0x00,0x01}, // INFRM_LEFT37 :
+{0x6426,0xFF,0x01}, // INFRM_RIGHT00 :
+{0x6427,0xFF,0x01}, // INFRM_RIGHT01 :
+{0x6428,0xFF,0x01}, // INFRM_RIGHT02 :
+{0x6429,0xFF,0x01}, // INFRM_RIGHT03 :
+{0x642A,0xFF,0x01}, // INFRM_RIGHT04 :
+{0x642B,0xFF,0x01}, // INFRM_RIGHT05 :
+{0x642C,0xFF,0x01}, // INFRM_RIGHT06 :
+{0x642D,0xFF,0x01}, // INFRM_RIGHT07 :
+{0x642E,0xFF,0x01}, // INFRM_RIGHT08 :
+{0x642F,0xFF,0x01}, // INFRM_RIGHT09 :
+{0x6430,0xFF,0x01}, // INFRM_RIGHT10 :
+{0x6431,0xFF,0x01}, // INFRM_RIGHT11 :
+{0x6432,0xFF,0x01}, // INFRM_RIGHT12 :
+{0x6433,0xFF,0x01}, // INFRM_RIGHT13 :
+{0x6434,0xFF,0x01}, // INFRM_RIGHT14 :
+{0x6435,0xFF,0x01}, // INFRM_RIGHT15 :
+{0x6436,0xFF,0x01}, // INFRM_RIGHT16 :
+{0x6437,0xFF,0x01}, // INFRM_RIGHT17 :
+{0x6438,0xFF,0x01}, // INFRM_RIGHT18 :
+{0x6439,0xFF,0x01}, // INFRM_RIGHT19 :
+{0x643A,0xFF,0x01}, // INFRM_RIGHT20 :
+{0x643B,0xFF,0x01}, // INFRM_RIGHT21 :
+{0x643C,0xFF,0x01}, // INFRM_RIGHT22 :
+{0x643D,0xFF,0x01}, // INFRM_RIGHT23 :
+{0x643E,0xFF,0x01}, // INFRM_RIGHT24 :
+{0x643F,0xFF,0x01}, // INFRM_RIGHT25 :
+{0x6440,0xFF,0x01}, // INFRM_RIGHT26 :
+{0x6441,0xFF,0x01}, // INFRM_RIGHT27 :
+{0x6442,0xFF,0x01}, // INFRM_RIGHT28 :
+{0x6443,0xFF,0x01}, // INFRM_RIGHT29 :
+{0x6444,0xFF,0x01}, // INFRM_RIGHT30 :
+{0x6445,0xFF,0x01}, // INFRM_RIGHT31 :
+{0x6446,0xFF,0x01}, // INFRM_RIGHT32 :
+{0x6447,0xFF,0x01}, // INFRM_RIGHT33 :
+{0x6448,0xFF,0x01}, // INFRM_RIGHT34 :
+{0x6449,0xFF,0x01}, // INFRM_RIGHT35 :
+{0x644A,0xFF,0x01}, // INFRM_RIGHT36 :
+{0x644B,0xFF,0x01}, // INFRM_RIGHT37 :
+{0x644C,0xFFFF,0x02}, // INFRM_TOP :
+{0x644E,0x0000,0x02}, // INFRM_BOTM :
+{0x6450,0x25,0x01}, // INFRM_FLTOP :
+{0x6451,0x00,0x01}, // INFRM_FLBOTM :
+{0x6452,0x91,0x01}, // INAIM_LEFT00 :
+{0x6453,0x91,0x01}, // INAIM_LEFT01 :
+{0x6454,0x91,0x01}, // INAIM_LEFT02 :
+{0x6455,0x91,0x01}, // INAIM_LEFT03 :
+{0x6456,0x91,0x01}, // INAIM_LEFT04 :
+{0x6457,0x91,0x01}, // INAIM_LEFT05 :
+{0x6458,0x91,0x01}, // INAIM_LEFT06 :
+{0x6459,0x91,0x01}, // INAIM_LEFT07 :
+{0x645A,0x91,0x01}, // INAIM_LEFT08 :
+{0x645B,0x91,0x01}, // INAIM_LEFT09 :
+{0x645C,0x91,0x01}, // INAIM_LEFT10 :
+{0x645D,0x91,0x01}, // INAIM_LEFT11 :
+{0x645E,0x91,0x01}, // INAIM_LEFT12 :
+{0x645F,0x66,0x01}, // INAIM_LEFT13 :
+{0x6460,0x5D,0x01}, // INAIM_LEFT14 :
+{0x6461,0x69,0x01}, // INAIM_LEFT15 :
+{0x6462,0x54,0x01}, // INAIM_LEFT16 :
+{0x6463,0x4B,0x01}, // INAIM_LEFT17 :
+{0x6464,0x42,0x01}, // INAIM_LEFT18 :
+{0x6465,0x3C,0x01}, // INAIM_LEFT19 :
+{0x6466,0x38,0x01}, // INAIM_LEFT20 :
+{0x6467,0x36,0x01}, // INAIM_LEFT21 :
+{0x6468,0x35,0x01}, // INAIM_LEFT22 :
+{0x6469,0x33,0x01}, // INAIM_LEFT23 :
+{0x646A,0x32,0x01}, // INAIM_LEFT24 :
+{0x646B,0x30,0x01}, // INAIM_LEFT25 :
+{0x646C,0x2F,0x01}, // INAIM_LEFT26 :
+{0x646D,0x2D,0x01}, // INAIM_LEFT27 :
+{0x646E,0x2C,0x01}, // INAIM_LEFT28 :
+{0x646F,0x2B,0x01}, // INAIM_LEFT29 :
+{0x6470,0x2A,0x01}, // INAIM_LEFT30 :
+{0x6471,0x28,0x01}, // INAIM_LEFT31 :
+{0x6472,0x26,0x01}, // INAIM_LEFT32 :
+{0x6473,0x24,0x01}, // INAIM_LEFT33 :
+{0x6474,0x29,0x01}, // INAIM_LEFT34 :
+{0x6475,0x28,0x01}, // INAIM_LEFT35 :
+{0x6476,0x29,0x01}, // INAIM_LEFT36 :
+{0x6477,0x26,0x01}, // INAIM_LEFT37 :
+{0x6478,0xFF,0x01}, // INAIM_RIGHT00 :
+{0x6479,0xFF,0x01}, // INAIM_RIGHT01 :
+{0x647A,0xFF,0x01}, // INAIM_RIGHT02 :
+{0x647B,0xFF,0x01}, // INAIM_RIGHT03 :
+{0x647C,0xFF,0x01}, // INAIM_RIGHT04 :
+{0x647D,0xFF,0x01}, // INAIM_RIGHT05 :
+{0x647E,0xFF,0x01}, // INAIM_RIGHT06 :
+{0x647F,0xFF,0x01}, // INAIM_RIGHT07 :
+{0x6480,0xFF,0x01}, // INAIM_RIGHT08 :
+{0x6481,0xFF,0x01}, // INAIM_RIGHT09 :
+{0x6482,0xD9,0x01}, // INAIM_RIGHT10 :
+{0x6483,0xB7,0x01}, // INAIM_RIGHT11 :
+{0x6484,0x96,0x01}, // INAIM_RIGHT12 :
+{0x6485,0x68,0x01}, // INAIM_RIGHT13 :
+{0x6486,0x70,0x01}, // INAIM_RIGHT14 :
+{0x6487,0x72,0x01}, // INAIM_RIGHT15 :
+{0x6488,0x71,0x01}, // INAIM_RIGHT16 :
+{0x6489,0x6B,0x01}, // INAIM_RIGHT17 :
+{0x648A,0x65,0x01}, // INAIM_RIGHT18 :
+{0x648B,0x60,0x01}, // INAIM_RIGHT19 :
+{0x648C,0x5B,0x01}, // INAIM_RIGHT20 :
+{0x648D,0x56,0x01}, // INAIM_RIGHT21 :
+{0x648E,0x51,0x01}, // INAIM_RIGHT22 :
+{0x648F,0x4C,0x01}, // INAIM_RIGHT23 :
+{0x6490,0x47,0x01}, // INAIM_RIGHT24 :
+{0x6491,0x44,0x01}, // INAIM_RIGHT25 :
+{0x6492,0x41,0x01}, // INAIM_RIGHT26 :
+{0x6493,0x3E,0x01}, // INAIM_RIGHT27 :
+{0x6494,0x3B,0x01}, // INAIM_RIGHT28 :
+{0x6495,0x39,0x01}, // INAIM_RIGHT29 :
+{0x6496,0x37,0x01}, // INAIM_RIGHT30 :
+{0x6497,0x34,0x01}, // INAIM_RIGHT31 :
+{0x6498,0x33,0x01}, // INAIM_RIGHT32 :
+{0x6499,0x32,0x01}, // INAIM_RIGHT33 :
+{0x649A,0x31,0x01}, // INAIM_RIGHT34 :
+{0x649B,0x30,0x01}, // INAIM_RIGHT35 :
+{0x649C,0x2F,0x01}, // INAIM_RIGHT36 :
+{0x649D,0x2E,0x01}, // INAIM_RIGHT37 :
+{0x649E,0x1E00,0x02}, // INAIM_TOP :
+{0x64A0,0x0F48,0x02}, // INAIM_BOTM :
+{0x64A2,0x18,0x01}, // INAIM_FLTOP :
+{0x64A3,0x11,0x01}, // INAIM_FLBOTM :
+{0x64A4,0x00,0x01}, // OUTFRM_LEFT00 :
+{0x64A5,0x00,0x01}, // OUTFRM_LEFT01 :
+{0x64A6,0x00,0x01}, // OUTFRM_LEFT02 :
+{0x64A7,0x00,0x01}, // OUTFRM_LEFT03 :
+{0x64A8,0x00,0x01}, // OUTFRM_LEFT04 :
+{0x64A9,0x00,0x01}, // OUTFRM_LEFT05 :
+{0x64AA,0x00,0x01}, // OUTFRM_LEFT06 :
+{0x64AB,0x00,0x01}, // OUTFRM_LEFT07 :
+{0x64AC,0x00,0x01}, // OUTFRM_LEFT08 :
+{0x64AD,0x00,0x01}, // OUTFRM_LEFT09 :
+{0x64AE,0x00,0x01}, // OUTFRM_LEFT10 :
+{0x64AF,0x00,0x01}, // OUTFRM_LEFT11 :
+{0x64B0,0x00,0x01}, // OUTFRM_LEFT12 :
+{0x64B1,0x00,0x01}, // OUTFRM_LEFT13 :
+{0x64B2,0x00,0x01}, // OUTFRM_LEFT14 :
+{0x64B3,0x00,0x01}, // OUTFRM_LEFT15 :
+{0x64B4,0x00,0x01}, // OUTFRM_LEFT16 :
+{0x64B5,0x00,0x01}, // OUTFRM_LEFT17 :
+{0x64B6,0x00,0x01}, // OUTFRM_LEFT18 :
+{0x64B7,0x00,0x01}, // OUTFRM_LEFT19 :
+{0x64B8,0x00,0x01}, // OUTFRM_LEFT20 :
+{0x64B9,0x00,0x01}, // OUTFRM_LEFT21 :
+{0x64BA,0x00,0x01}, // OUTFRM_LEFT22 :
+{0x64BB,0x00,0x01}, // OUTFRM_LEFT23 :
+{0x64BC,0x00,0x01}, // OUTFRM_LEFT24 :
+{0x64BD,0x00,0x01}, // OUTFRM_LEFT25 :
+{0x64BE,0x00,0x01}, // OUTFRM_LEFT26 :
+{0x64BF,0x00,0x01}, // OUTFRM_LEFT27 :
+{0x64C0,0x00,0x01}, // OUTFRM_LEFT28 :
+{0x64C1,0x00,0x01}, // OUTFRM_LEFT29 :
+{0x64C2,0x00,0x01}, // OUTFRM_LEFT30 :
+{0x64C3,0x00,0x01}, // OUTFRM_LEFT31 :
+{0x64C4,0x00,0x01}, // OUTFRM_LEFT32 :
+{0x64C5,0x00,0x01}, // OUTFRM_LEFT33 :
+{0x64C6,0x00,0x01}, // OUTFRM_LEFT34 :
+{0x64C7,0x00,0x01}, // OUTFRM_LEFT35 :
+{0x64C8,0x00,0x01}, // OUTFRM_LEFT36 :
+{0x64C9,0x00,0x01}, // OUTFRM_LEFT37 :
+{0x64CA,0xFF,0x01}, // OUTFRM_RIGHT00 :
+{0x64CB,0xFF,0x01}, // OUTFRM_RIGHT01 :
+{0x64CC,0xFF,0x01}, // OUTFRM_RIGHT02 :
+{0x64CD,0xFF,0x01}, // OUTFRM_RIGHT03 :
+{0x64CE,0xFF,0x01}, // OUTFRM_RIGHT04 :
+{0x64CF,0xFF,0x01}, // OUTFRM_RIGHT05 :
+{0x64D0,0xFF,0x01}, // OUTFRM_RIGHT06 :
+{0x64D1,0xFF,0x01}, // OUTFRM_RIGHT07 :
+{0x64D2,0xFF,0x01}, // OUTFRM_RIGHT08 :
+{0x64D3,0xFF,0x01}, // OUTFRM_RIGHT09 :
+{0x64D4,0xFF,0x01}, // OUTFRM_RIGHT10 :
+{0x64D5,0xFF,0x01}, // OUTFRM_RIGHT11 :
+{0x64D6,0xFF,0x01}, // OUTFRM_RIGHT12 :
+{0x64D7,0xFF,0x01}, // OUTFRM_RIGHT13 :
+{0x64D8,0xFF,0x01}, // OUTFRM_RIGHT14 :
+{0x64D9,0xFF,0x01}, // OUTFRM_RIGHT15 :
+{0x64DA,0xFF,0x01}, // OUTFRM_RIGHT16 :
+{0x64DB,0xFF,0x01}, // OUTFRM_RIGHT17 :
+{0x64DC,0xFF,0x01}, // OUTFRM_RIGHT18 :
+{0x64DD,0xFF,0x01}, // OUTFRM_RIGHT19 :
+{0x64DE,0xFF,0x01}, // OUTFRM_RIGHT20 :
+{0x64DF,0xFF,0x01}, // OUTFRM_RIGHT21 :
+{0x64E0,0xFF,0x01}, // OUTFRM_RIGHT22 :
+{0x64E1,0xFF,0x01}, // OUTFRM_RIGHT23 :
+{0x64E2,0xFF,0x01}, // OUTFRM_RIGHT24 :
+{0x64E3,0xFF,0x01}, // OUTFRM_RIGHT25 :
+{0x64E4,0xFF,0x01}, // OUTFRM_RIGHT26 :
+{0x64E5,0xFF,0x01}, // OUTFRM_RIGHT27 :
+{0x64E6,0xFF,0x01}, // OUTFRM_RIGHT28 :
+{0x64E7,0xFF,0x01}, // OUTFRM_RIGHT29 :
+{0x64E8,0xFF,0x01}, // OUTFRM_RIGHT30 :
+{0x64E9,0xFF,0x01}, // OUTFRM_RIGHT31 :
+{0x64EA,0xFF,0x01}, // OUTFRM_RIGHT32 :
+{0x64EB,0xFF,0x01}, // OUTFRM_RIGHT33 :
+{0x64EC,0xFF,0x01}, // OUTFRM_RIGHT34 :
+{0x64ED,0xFF,0x01}, // OUTFRM_RIGHT35 :
+{0x64EE,0xFF,0x01}, // OUTFRM_RIGHT36 :
+{0x64EF,0xFF,0x01}, // OUTFRM_RIGHT37 :
+{0x64F0,0x24F0,0x02}, // OUTFRM_TOP :
+{0x64F2,0x1400,0x02}, // OUTFRM_BOTM :
+{0x64F4,0x37,0x01}, // OUTFRM_FLTOP :
+{0x64F5,0x00,0x01}, // OUTFRM_FLBOTM :
+
+//AWB
+{0x6232,0x07,0x01},//ATW_SFTLMT_OUT_NR
+{0x6234,0x05,0x01},//ATW_SFTLMT_OUT
+
+/////MC3 Setting/////
+{0x7600,0x07,0x01}, // MC3_PXDEF0_SEL :
+{0x7601,0x07,0x01}, // MC3_PYDEF0_SEL :
+{0x7602,0x07,0x01}, // MC3_PXDEF1_SEL :
+{0x7603,0x07,0x01}, // MC3_PYDEF1_SEL :
+{0x7604,0x07,0x01}, // MC3_PXDEF2_SEL :
+{0x7605,0x07,0x01}, // MC3_PYDEF2_SEL :
+{0x7606,0x07,0x01}, // MC3_PXDEF3_SEL :
+{0x7607,0x07,0x01}, // MC3_PYDEF3_SEL :
+{0x7608,0x40,0x01}, // MC3_PXDEF0_A :
+{0x7609,0x40,0x01}, // MC3_PXDEF0_B :
+{0x760A,0x40,0x01}, // MC3_PXDEF0_C :
+{0x760B,0x40,0x01}, // MC3_PYDEF0_A :
+{0x760C,0x40,0x01}, // MC3_PYDEF0_B :
+{0x760D,0x40,0x01}, // MC3_PYDEF0_C :
+{0x760E,0x40,0x01}, // MC3_PXDEF1_A :
+{0x760F,0x40,0x01}, // MC3_PXDEF1_B :
+{0x7610,0x40,0x01}, // MC3_PXDEF1_C :
+{0x7611,0x40,0x01}, // MC3_PYDEF1_A :
+{0x7612,0x40,0x01}, // MC3_PYDEF1_B :
+{0x7613,0x40,0x01}, // MC3_PYDEF1_C :
+{0x7614,0x40,0x01}, // MC3_PXDEF2_A :
+{0x7615,0x40,0x01}, // MC3_PXDEF2_B :
+{0x7616,0x40,0x01}, // MC3_PXDEF2_C :
+{0x7617,0x40,0x01}, // MC3_PYDEF2_A :
+{0x7618,0x40,0x01}, // MC3_PYDEF2_B :
+{0x7619,0x40,0x01}, // MC3_PYDEF2_C :
+{0x761A,0x40,0x01}, // MC3_PXDEF3_A :
+{0x761B,0x40,0x01}, // MC3_PXDEF3_B :
+{0x761C,0x40,0x01}, // MC3_PXDEF3_C :
+{0x761D,0x40,0x01}, // MC3_PYDEF3_A :
+{0x761E,0x40,0x01}, // MC3_PYDEF3_B :
+{0x761F,0x40,0x01}, // MC3_PYDEF3_C :
+{0x7620,0x00,0x01}, // MC3_LUMSL0_IN :
+{0x7621,0x06,0x01}, // MC3_LUMSL1_IN :
+{0x7622,0x03,0x01}, // MC3_LUMSL2_IN :
+{0x7623,0x06,0x01}, // MC3_LUMSL3_IN :
+{0x7624,0x00,0x01}, // MC3_LUMSL0_OUT :
+{0x7625,0x03,0x01}, // MC3_LUMSL1_OUT :
+{0x7626,0x00,0x01}, // MC3_LUMSL2_OUT :
+{0x7627,0x00,0x01}, // MC3_LUMSL3_OUT :
+{0x7628,0x0000,0x02}, // MC3_L0DEF0_IN :
+{0x762A,0x008C,0x02}, // MC3_L0DEF1_IN :
+{0x762C,0x0078,0x02}, // MC3_L0DEF2_IN :
+{0x762E,0x00E6,0x02}, // MC3_L0DEF3_IN :
+{0x7630,0x0000,0x02}, // MC3_L0DEF0_OUT :
+{0x7632,0x0082,0x02}, // MC3_L0DEF1_OUT :
+{0x7634,0x0000,0x02}, // MC3_L0DEF2_OUT :
+{0x7636,0x0000,0x02}, // MC3_L0DEF3_OUT :
+{0x7638,0x41,0x01}, // MC3_RDEF0_POS1 :
+{0x7639,0x10,0x01}, // MC3_RDEF1_POS1 :
+{0x763A,0x15,0x01}, // MC3_RDEF2_POS1 :
+{0x763B,0x71,0x01}, // MC3_RDEF3_POS1 :
+{0x763C,0x41,0x01}, // MC3_RDEF0_POS2 :
+{0x763D,0x10,0x01}, // MC3_RDEF1_POS2 :
+{0x763E,0x15,0x01}, // MC3_RDEF2_POS2 :
+{0x763F,0x71,0x01}, // MC3_RDEF3_POS2 :
+{0x7640,0x3C,0x01}, // MC3_RDEF0_POS3 :
+{0x7641,0x10,0x01}, // MC3_RDEF1_POS3 :
+{0x7642,0x15,0x01}, // MC3_RDEF2_POS3 :
+{0x7643,0x71,0x01}, // MC3_RDEF3_POS3 :
+{0x7644,0x46,0x01}, // MC3_RDEF0_POS4 :
+{0x7645,0x32,0x01}, // MC3_RDEF1_POS4 :
+{0x7646,0x15,0x01}, // MC3_RDEF2_POS4 :
+{0x7647,0x71,0x01}, // MC3_RDEF3_POS4 :
+{0x7648,0x46,0x01}, // MC3_RDEF0_POS5 :
+{0x7649,0x32,0x01}, // MC3_RDEF1_POS5 :
+{0x764A,0x15,0x01}, // MC3_RDEF2_POS5 :
+{0x764B,0x71,0x01}, // MC3_RDEF3_POS5 :
+{0x764C,0x46,0x01}, // MC3_RDEF0_POS6 :
+{0x764D,0x10,0x01}, // MC3_RDEF1_POS6 :
+{0x764E,0x15,0x01}, // MC3_RDEF2_POS6 :
+{0x764F,0x71,0x01}, // MC3_RDEF3_POS6 :
+{0x7650,0x46,0x01}, // MC3_RDEF0_POS7 :
+{0x7651,0x10,0x01}, // MC3_RDEF1_POS7 :
+{0x7652,0x15,0x01}, // MC3_RDEF2_POS7 :
+{0x7653,0x71,0x01}, // MC3_RDEF3_POS7 :
+{0x7654,0x2D,0x01}, // MC3_RDEF0_OUT :
+{0x7655,0x10,0x01}, // MC3_RDEF1_OUT :
+{0x7656,0x15,0x01}, // MC3_RDEF2_OUT :
+{0x7657,0x54,0x01}, // MC3_RDEF3_OUT :
+{0x7658,0x46,0x01}, // MC3_RDEF0_R2_POS4 :
+{0x7659,0x32,0x01}, // MC3_RDEF1_R2_POS4 :
+{0x765A,0x15,0x01}, // MC3_RDEF2_R2_POS4 :
+{0x765B,0x71,0x01}, // MC3_RDEF3_R2_POS4 :
+{0x765C,0x46,0x01}, // MC3_RDEF0_R2_POS5 :
+{0x765D,0x32,0x01}, // MC3_RDEF1_R2_POS5 :
+{0x765E,0x15,0x01}, // MC3_RDEF2_R2_POS5 :
+{0x765F,0x71,0x01}, // MC3_RDEF3_R2_POS5 :
+{0x7660,0xFFBA,0x02}, // MC3_X0DEF0_POS1 :
+{0x7662,0xFFBA,0x02}, // MC3_Y0DEF0_POS1 :
+{0x7664,0xFFFE,0x02}, // MC3_X0DEF1_POS1 :
+{0x7666,0x000D,0x02}, // MC3_Y0DEF1_POS1 :
+{0x7668,0x0002,0x02}, // MC3_X0DEF2_POS1 :
+{0x766A,0xFFF6,0x02}, // MC3_Y0DEF2_POS1 :
+{0x766C,0x003B,0x02}, // MC3_X0DEF3_POS1 :
+{0x766E,0xFFBB,0x02}, // MC3_Y0DEF3_POS1 :
+{0x7670,0xFFBA,0x02}, // MC3_X0DEF0_POS2 :
+{0x7672,0xFFBA,0x02}, // MC3_Y0DEF0_POS2 :
+{0x7674,0xFFFE,0x02}, // MC3_X0DEF1_POS2 :
+{0x7676,0x000D,0x02}, // MC3_Y0DEF1_POS2 :
+{0x7678,0x0002,0x02}, // MC3_X0DEF2_POS2 :
+{0x767A,0xFFF6,0x02}, // MC3_Y0DEF2_POS2 :
+{0x767C,0x003B,0x02}, // MC3_X0DEF3_POS2 :
+{0x767E,0xFFBB,0x02}, // MC3_Y0DEF3_POS2 :
+{0x7680,0xFFCE,0x02}, // MC3_X0DEF0_POS3 :
+{0x7682,0xFFBA,0x02}, // MC3_Y0DEF0_POS3 :
+{0x7684,0xFFFE,0x02}, // MC3_X0DEF1_POS3 :
+{0x7686,0x000D,0x02}, // MC3_Y0DEF1_POS3 :
+{0x7688,0x0002,0x02}, // MC3_X0DEF2_POS3 :
+{0x768A,0xFFF6,0x02}, // MC3_Y0DEF2_POS3 :
+{0x768C,0x003B,0x02}, // MC3_X0DEF3_POS3 :
+{0x768E,0xFFBB,0x02}, // MC3_Y0DEF3_POS3 :
+{0x7690,0xFFCE,0x02}, // MC3_X0DEF0_POS4 :
+{0x7692,0xFFC9,0x02}, // MC3_Y0DEF0_POS4 :
+{0x7694,0xFFD0,0x02}, // MC3_X0DEF1_POS4 :
+{0x7696,0x0037,0x02}, // MC3_Y0DEF1_POS4 :
+{0x7698,0x0002,0x02}, // MC3_X0DEF2_POS4 :
+{0x769A,0xFFF6,0x02}, // MC3_Y0DEF2_POS4 :
+{0x769C,0x003B,0x02}, // MC3_X0DEF3_POS4 :
+{0x769E,0xFFBB,0x02}, // MC3_Y0DEF3_POS4 :
+{0x76A0,0xFFCE,0x02}, // MC3_X0DEF0_POS5 :
+{0x76A2,0xFFC9,0x02}, // MC3_Y0DEF0_POS5 :
+{0x76A4,0xFFD0,0x02}, // MC3_X0DEF1_POS5 :
+{0x76A6,0x0037,0x02}, // MC3_Y0DEF1_POS5 :
+{0x76A8,0x0002,0x02}, // MC3_X0DEF2_POS5 :
+{0x76AA,0xFFF6,0x02}, // MC3_Y0DEF2_POS5 :
+{0x76AC,0x003B,0x02}, // MC3_X0DEF3_POS5 :
+{0x76AE,0xFFBB,0x02}, // MC3_Y0DEF3_POS5 :
+{0x76B0,0xFFCE,0x02}, // MC3_X0DEF0_POS6 :
+{0x76B2,0xFFC9,0x02}, // MC3_Y0DEF0_POS6 :
+{0x76B4,0xFFFE,0x02}, // MC3_X0DEF1_POS6 :
+{0x76B6,0x000D,0x02}, // MC3_Y0DEF1_POS6 :
+{0x76B8,0x0002,0x02}, // MC3_X0DEF2_POS6 :
+{0x76BA,0xFFF6,0x02}, // MC3_Y0DEF2_POS6 :
+{0x76BC,0x003B,0x02}, // MC3_X0DEF3_POS6 :
+{0x76BE,0xFFBB,0x02}, // MC3_Y0DEF3_POS6 :
+{0x76C0,0xFFCE,0x02}, // MC3_X0DEF0_POS7 :
+{0x76C2,0xFFC9,0x02}, // MC3_Y0DEF0_POS7 :
+{0x76C4,0xFFFE,0x02}, // MC3_X0DEF1_POS7 :
+{0x76C6,0x000D,0x02}, // MC3_Y0DEF1_POS7 :
+{0x76C8,0x0002,0x02}, // MC3_X0DEF2_POS7 :
+{0x76CA,0xFFF6,0x02}, // MC3_Y0DEF2_POS7 :
+{0x76CC,0x003B,0x02}, // MC3_X0DEF3_POS7 :
+{0x76CE,0xFFBB,0x02}, // MC3_Y0DEF3_POS7 :
+{0x76D0,0xFF7E,0x02}, // MC3_X0DEF0_OUT :
+{0x76D2,0xFFE2,0x02}, // MC3_Y0DEF0_OUT :
+{0x76D4,0xFFFE,0x02}, // MC3_X0DEF1_OUT :
+{0x76D6,0x000D,0x02}, // MC3_Y0DEF1_OUT :
+{0x76D8,0x0002,0x02}, // MC3_X0DEF2_OUT :
+{0x76DA,0xFFF6,0x02}, // MC3_Y0DEF2_OUT :
+{0x76DC,0xFFC4,0x02}, // MC3_X0DEF3_OUT :
+{0x76DE,0xFFEC,0x02}, // MC3_Y0DEF3_OUT :
+{0x76E0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS4 :
+{0x76E2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS4 :
+{0x76E4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS4 :
+{0x76E6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS4 :
+{0x76E8,0x0002,0x02}, // MC3_X0DEF2_R2_POS4 :
+{0x76EA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS4 :
+{0x76EC,0x003B,0x02}, // MC3_X0DEF3_R2_POS4 :
+{0x76EE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS4 :
+{0x76F0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS5 :
+{0x76F2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS5 :
+{0x76F4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS5 :
+{0x76F6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS5 :
+{0x76F8,0x0002,0x02}, // MC3_X0DEF2_R2_POS5 :
+{0x76FA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS5 :
+{0x76FC,0x003B,0x02}, // MC3_X0DEF3_R2_POS5 :
+{0x76FE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS5 :
+{0x7700,0x0019,0x02}, // MC3_PXDEF0_POS1 :
+{0x7702,0xFF66,0x02}, // MC3_PYDEF0_POS1 :
+{0x7704,0x0000,0x02}, // MC3_PXDEF1_POS1 :
+{0x7706,0x0000,0x02}, // MC3_PYDEF1_POS1 :
+{0x7708,0x0000,0x02}, // MC3_PXDEF2_POS1 :
+{0x770A,0x0000,0x02}, // MC3_PYDEF2_POS1 :
+{0x770C,0xFFD7,0x02}, // MC3_PXDEF3_POS1 :
+{0x770E,0x0068,0x02}, // MC3_PYDEF3_POS1 :
+{0x7710,0x0000,0x02}, // MC3_PXDEF0_POS2 :
+{0x7712,0xFF66,0x02}, // MC3_PYDEF0_POS2 :
+{0x7714,0x0033,0x02}, // MC3_PXDEF1_POS2 :
+{0x7716,0xFF4C,0x02}, // MC3_PYDEF1_POS2 :
+{0x7718,0x0000,0x02}, // MC3_PXDEF2_POS2 :
+{0x771A,0x00B3,0x02}, // MC3_PYDEF2_POS2 :
+{0x771C,0xFFD7,0x02}, // MC3_PXDEF3_POS2 :
+{0x771E,0x0068,0x02}, // MC3_PYDEF3_POS2 :
+{0x7720,0x0000,0x02}, // MC3_PXDEF0_POS3 :
+{0x7722,0xFF80,0x02}, // MC3_PYDEF0_POS3 :
+{0x7724,0x0000,0x02}, // MC3_PXDEF1_POS3 :
+{0x7726,0x0000,0x02}, // MC3_PYDEF1_POS3 :
+{0x7728,0x0000,0x02}, // MC3_PXDEF2_POS3 :
+{0x772A,0x0000,0x02}, // MC3_PYDEF2_POS3 :
+{0x772C,0xFFD7,0x02}, // MC3_PXDEF3_POS3 :
+{0x772E,0x0068,0x02}, // MC3_PYDEF3_POS3 :
+{0x7730,0x0000,0x02}, // MC3_PXDEF0_POS4 :
+{0x7732,0xFFCC,0x02}, // MC3_PYDEF0_POS4 :
+{0x7734,0x0000,0x02}, // MC3_PXDEF1_POS4 :
+{0x7736,0x0000,0x02}, // MC3_PYDEF1_POS4 :
+{0x7738,0x0000,0x02}, // MC3_PXDEF2_POS4 :
+{0x773A,0x0000,0x02}, // MC3_PYDEF2_POS4 :
+{0x773C,0xFFD7,0x02}, // MC3_PXDEF3_POS4 :
+{0x773E,0x0068,0x02}, // MC3_PYDEF3_POS4 :
+{0x7740,0x0000,0x02}, // MC3_PXDEF0_POS5 :
+{0x7742,0xFFCC,0x02}, // MC3_PYDEF0_POS5 :
+{0x7744,0x0000,0x02}, // MC3_PXDEF1_POS5 :
+{0x7746,0x0000,0x02}, // MC3_PYDEF1_POS5 :
+{0x7748,0x0000,0x02}, // MC3_PXDEF2_POS5 :
+{0x774A,0x0000,0x02}, // MC3_PYDEF2_POS5 :
+{0x774C,0xFFD7,0x02}, // MC3_PXDEF3_POS5 :
+{0x774E,0x0068,0x02}, // MC3_PYDEF3_POS5 :
+{0x7750,0xFFB3,0x02}, // MC3_PXDEF0_POS6 :
+{0x7752,0x0000,0x02}, // MC3_PYDEF0_POS6 :
+{0x7754,0x0033,0x02}, // MC3_PXDEF1_POS6 :
+{0x7756,0xFF4C,0x02}, // MC3_PYDEF1_POS6 :
+{0x7758,0x0000,0x02}, // MC3_PXDEF2_POS6 :
+{0x775A,0x00B3,0x02}, // MC3_PYDEF2_POS6 :
+{0x775C,0xFFD7,0x02}, // MC3_PXDEF3_POS6 :
+{0x775E,0x0068,0x02}, // MC3_PYDEF3_POS6 :
+{0x7760,0xFFB3,0x02}, // MC3_PXDEF0_POS7 :
+{0x7762,0x0000,0x02}, // MC3_PYDEF0_POS7 :
+{0x7764,0x0000,0x02}, // MC3_PXDEF1_POS7 :
+{0x7766,0x0000,0x02}, // MC3_PYDEF1_POS7 :
+{0x7768,0x0000,0x02}, // MC3_PXDEF2_POS7 :
+{0x776A,0x0000,0x02}, // MC3_PYDEF2_POS7 :
+{0x776C,0xFFD7,0x02}, // MC3_PXDEF3_POS7 :
+{0x776E,0x0068,0x02}, // MC3_PYDEF3_POS7 :
+{0x7770,0x0019,0x02}, // MC3_PXDEF0_OUT :
+{0x7772,0xFFE6,0x02}, // MC3_PYDEF0_OUT :
+{0x7774,0x0000,0x02}, // MC3_PXDEF1_OUT :
+{0x7776,0x0000,0x02}, // MC3_PYDEF1_OUT :
+{0x7778,0x0000,0x02}, // MC3_PXDEF2_OUT :
+{0x777A,0x0000,0x02}, // MC3_PYDEF2_OUT :
+{0x777C,0xFFE1,0x02}, // MC3_PXDEF3_OUT :
+{0x777E,0xFFEB,0x02}, // MC3_PYDEF3_OUT :
+{0x7780,0x0000,0x02}, // MC3_PXDEF0_R2_POS4 :
+{0x7782,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS4 :
+{0x7784,0x0000,0x02}, // MC3_PXDEF1_R2_POS4 :
+{0x7786,0x0000,0x02}, // MC3_PYDEF1_R2_POS4 :
+{0x7788,0x0000,0x02}, // MC3_PXDEF2_R2_POS4 :
+{0x778A,0x0000,0x02}, // MC3_PYDEF2_R2_POS4 :
+{0x778C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS4 :
+{0x778E,0x0068,0x02}, // MC3_PYDEF3_R2_POS4 :
+{0x7790,0x0000,0x02}, // MC3_PXDEF0_R2_POS5 :
+{0x7792,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS5 :
+{0x7794,0x0000,0x02}, // MC3_PXDEF1_R2_POS5 :
+{0x7796,0x0000,0x02}, // MC3_PYDEF1_R2_POS5 :
+{0x7798,0x0000,0x02}, // MC3_PXDEF2_R2_POS5 :
+{0x779A,0x0000,0x02}, // MC3_PYDEF2_R2_POS5 :
+{0x779C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS5 :
+{0x779E,0x0068,0x02}, // MC3_PYDEF3_R2_POS5 :
+
+};
+
+static const isx012_regset_t ISX012_Camcorder_Mode_OFF[] = {
+//SN setting
+{0x0308,0x11,0x01}, // AELINE_MONI_SN1_2 :
+{0x0320,0x22,0x01}, // AELINE_MONI_SN1_2 :
+{0x00B2,0x02,0x01}, // AFMODE_MONI :
+//BRIGHTNESS setting
+{0x01C6,0x00,0x01}, // UIBRIGHTNESS
+//AE speed
+{0x02AC,0x01,0x01}, // AE_SUB_SN1 :
+{0x5E2D,0x08,0x01}, // AEMOVECNT :
+{0x5E2E,0x1A,0x01}, // AEINDEADBAND :
+{0x5E2F,0x04,0x01}, // AEOUTDEADBAND :
+{0x5E30,0x20,0x01}, // AESPEED :
+{0x5E31,0x0F,0x01}, // AESPEED_INIT :
+{0x5E32,0x0F,0x01}, // AESPEED_FAST :
+{0x621E,0x20,0x01}, // AIM_NR_TH_UP :
+{0x621F,0x20,0x01}, // AIM_NR_TH_DOWN :
+{0x6220,0x20,0x01}, // AIM_NR_TH_RIGHT :
+{0x6221,0x20,0x01}, // AIM_NR_TH_LEFT :
+//AWB speed
+{0x6222,0x00,0x01}, // INIT_AIMW :
+{0x6223,0x04,0x01}, // INIT_GAINS :
+{0x6224,0x04,0x01}, // ATW_DELAY :
+{0x6225,0x00,0x01}, // ATW_AIMW :
+{0x6226,0x08,0x01}, // ATW_GAINS_IN_NR :
+{0x6227,0x04,0x01}, // ATW_GAINS_IN :
+{0x6228,0x08,0x01}, // ATW_GAINS_OUT_NR :
+{0x6229,0x04,0x01}, // ATW_GAINS_OUT :
+{0x622A,0x02,0x01}, // ALLWB_GAINS :
+//Gammma Table 0
+{0x7000,0x0000,0x02}, // G0_KNOT_G0 :
+{0x7002,0x0015,0x02}, // G0_KNOT_G1 :
+{0x7004,0x002C,0x02}, // G0_KNOT_G2 :
+{0x7006,0x0041,0x02}, // G0_KNOT_G3 :
+{0x7008,0x004D,0x02}, // G0_KNOT_G4 :
+{0x700A,0x005B,0x02}, // G0_KNOT_G5 :
+{0x700C,0x0060,0x02}, // G0_KNOT_G6 :
+{0x700E,0x0068,0x02}, // G0_KNOT_G7 :
+{0x7010,0x006F,0x02}, // G0_KNOT_G8 :
+{0x7012,0x0078,0x02}, // G0_KNOT_G9 :
+{0x7014,0x0057,0x02}, // G0_KNOT_G10 :
+{0x7016,0x0090,0x02}, // G0_KNOT_G11 :
+{0x7018,0x00BB,0x02}, // G0_KNOT_G12 :
+{0x701A,0x00D6,0x02}, // G0_KNOT_G13 :
+{0x701C,0x00E5,0x02}, // G0_KNOT_G14 :
+{0x701E,0x00F0,0x02}, // G0_KNOT_G15 :
+{0x7020,0x00F9,0x02}, // G0_KNOT_G16 :
+{0x7022,0x0103,0x02}, // G0_KNOT_G17 :
+{0x7024,0x010C,0x02}, // G0_KNOT_G18 :
+{0x7026,0x00,0x01}, // G0_KNOT_R0_OFFSET :
+{0x7027,0x00,0x01}, // G0_KNOT_R2_OFFSET :
+{0x7028,0x00,0x01}, // G0_KNOT_R4_OFFSET :
+{0x7029,0x00,0x01}, // G0_KNOT_R6_OFFSET :
+{0x702A,0x00,0x01}, // G0_KNOT_R8_OFFSET :
+{0x702B,0x00,0x01}, // G0_KNOT_R10_OFFSET :
+{0x702C,0x00,0x01}, // G0_KNOT_R12_OFFSET :
+{0x702D,0x00,0x01}, // G0_KNOT_R14_OFFSET :
+{0x702E,0x00,0x01}, // G0_KNOT_R16_OFFSET :
+{0x702F,0x00,0x01}, // G0_KNOT_R18_OFFSET :
+{0x7030,0x00,0x01}, // G0_KNOT_B0_OFFSET :
+{0x7031,0x00,0x01}, // G0_KNOT_B2_OFFSET :
+{0x7032,0x00,0x01}, // G0_KNOT_B4_OFFSET :
+{0x7033,0x00,0x01}, // G0_KNOT_B6_OFFSET :
+{0x7034,0x00,0x01}, // G0_KNOT_B8_OFFSET :
+{0x7035,0x00,0x01}, // G0_KNOT_B10_OFFSET :
+{0x7036,0x00,0x01}, // G0_KNOT_B12_OFFSET :
+{0x7037,0x00,0x01}, // G0_KNOT_B14_OFFSET :
+{0x7038,0x00,0x01}, // G0_KNOT_B16_OFFSET :
+{0x7039,0x00,0x01}, // G0_KNOT_B18_OFFSET :
+{0x703A,0x0611,0x02}, // G0_LOWGM_ON_R :
+{0x703C,0x1E0A,0x02}, // G0_0CLIP_R :
+{0x703E,0x0611,0x02}, // G0_LOWGM_ON_G :
+{0x7040,0x1E0A,0x02}, // G0_0CLIP_G :
+{0x7042,0x0611,0x02}, // G0_LOWGM_ON_B :
+{0x7044,0x1E0A,0x02}, // G0_0CLIP_B :
+{0x7046,0x9C,0x01}, // G0_KNOT_GAINCTRL_TH_L :
+{0x7047,0xA1,0x01}, // G0_KNOT_GAINCTRL_TH_H :
+{0x7048,0x0000,0x02}, // G0_KNOT_L_G0 :
+{0x704A,0x0007,0x02}, // G0_KNOT_L_G1 :
+{0x704C,0x0016,0x02}, // G0_KNOT_L_G2 :
+{0x704E,0x002A,0x02}, // G0_KNOT_L_G3 :
+{0x7050,0x0039,0x02}, // G0_KNOT_L_G4 :
+{0x7052,0x004A,0x02}, // G0_KNOT_L_G5 :
+{0x7054,0x0051,0x02}, // G0_KNOT_L_G6 :
+{0x7056,0x005D,0x02}, // G0_KNOT_L_G7 :
+{0x7058,0x0065,0x02}, // G0_KNOT_L_G8 :
+{0x705A,0x006C,0x02}, // G0_KNOT_L_G9 :
+{0x705C,0x004E,0x02}, // G0_KNOT_L_G10 :
+{0x705E,0x0083,0x02}, // G0_KNOT_L_G11 :
+{0x7060,0x00AA,0x02}, // G0_KNOT_L_G12 :
+{0x7062,0x00C8,0x02}, // G0_KNOT_L_G13 :
+{0x7064,0x00E1,0x02}, // G0_KNOT_L_G14 :
+{0x7066,0x00F5,0x02}, // G0_KNOT_L_G15 :
+{0x7068,0x0100,0x02}, // G0_KNOT_L_G16 :
+{0x706A,0x0106,0x02}, // G0_KNOT_L_G17 :
+{0x706C,0x010C,0x02}, // G0_KNOT_L_G18 :
+{0x6400,0xAA,0x01}, // INFRM_LEFT00 :
+{0x6401,0xAA,0x01}, // INFRM_LEFT01 :
+{0x6402,0xAA,0x01}, // INFRM_LEFT02 :
+{0x6403,0xAA,0x01}, // INFRM_LEFT03 :
+{0x6404,0xAA,0x01}, // INFRM_LEFT04 :
+{0x6405,0xAA,0x01}, // INFRM_LEFT05 :
+{0x6406,0xAA,0x01}, // INFRM_LEFT06 :
+{0x6407,0xAA,0x01}, // INFRM_LEFT07 :
+{0x6408,0xAA,0x01}, // INFRM_LEFT08 :
+{0x6409,0xAE,0x01}, // INFRM_LEFT09 :
+{0x640A,0xA0,0x01}, // INFRM_LEFT10 :
+{0x640B,0x8C,0x01}, // INFRM_LEFT11 :
+{0x640C,0x72,0x01}, // INFRM_LEFT12 :
+{0x640D,0x64,0x01}, // INFRM_LEFT13 :
+{0x640E,0x5A,0x01}, // INFRM_LEFT14 :
+{0x640F,0x52,0x01}, // INFRM_LEFT15 :
+{0x6410,0x48,0x01}, // INFRM_LEFT16 :
+{0x6411,0x43,0x01}, // INFRM_LEFT17 :
+{0x6412,0x3D,0x01}, // INFRM_LEFT18 :
+{0x6413,0x37,0x01}, // INFRM_LEFT19 :
+{0x6414,0x33,0x01}, // INFRM_LEFT20 :
+{0x6415,0x30,0x01}, // INFRM_LEFT21 :
+{0x6416,0x2E,0x01}, // INFRM_LEFT22 :
+{0x6417,0x2B,0x01}, // INFRM_LEFT23 :
+{0x6418,0x28,0x01}, // INFRM_LEFT24 :
+{0x6419,0x26,0x01}, // INFRM_LEFT25 :
+{0x641A,0x24,0x01}, // INFRM_LEFT26 :
+{0x641B,0x23,0x01}, // INFRM_LEFT27 :
+{0x641C,0x22,0x01}, // INFRM_LEFT28 :
+{0x641D,0x22,0x01}, // INFRM_LEFT29 :
+{0x641E,0x21,0x01}, // INFRM_LEFT30 :
+{0x641F,0x20,0x01}, // INFRM_LEFT31 :
+{0x6420,0x1D,0x01}, // INFRM_LEFT32 :
+{0x6421,0x1A,0x01}, // INFRM_LEFT33 :
+{0x6422,0x18,0x01}, // INFRM_LEFT34 :
+{0x6423,0x17,0x01}, // INFRM_LEFT35 :
+{0x6424,0x16,0x01}, // INFRM_LEFT36 :
+{0x6425,0x17,0x01}, // INFRM_LEFT37 :
+{0x6426,0xAF,0x01}, // INFRM_RIGHT00 :
+{0x6427,0xAF,0x01}, // INFRM_RIGHT01 :
+{0x6428,0xAF,0x01}, // INFRM_RIGHT02 :
+{0x6429,0xAF,0x01}, // INFRM_RIGHT03 :
+{0x642A,0xAF,0x01}, // INFRM_RIGHT04 :
+{0x642B,0xAF,0x01}, // INFRM_RIGHT05 :
+{0x642C,0xAF,0x01}, // INFRM_RIGHT06 :
+{0x642D,0xAF,0x01}, // INFRM_RIGHT07 :
+{0x642E,0xAF,0x01}, // INFRM_RIGHT08 :
+{0x642F,0xAA,0x01}, // INFRM_RIGHT09 :
+{0x6430,0xB2,0x01}, // INFRM_RIGHT10 :
+{0x6431,0xB4,0x01}, // INFRM_RIGHT11 :
+{0x6432,0xB6,0x01}, // INFRM_RIGHT12 :
+{0x6433,0xB4,0x01}, // INFRM_RIGHT13 :
+{0x6434,0x9B,0x01}, // INFRM_RIGHT14 :
+{0x6435,0x8E,0x01}, // INFRM_RIGHT15 :
+{0x6436,0x84,0x01}, // INFRM_RIGHT16 :
+{0x6437,0x7A,0x01}, // INFRM_RIGHT17 :
+{0x6438,0x72,0x01}, // INFRM_RIGHT18 :
+{0x6439,0x6A,0x01}, // INFRM_RIGHT19 :
+{0x643A,0x63,0x01}, // INFRM_RIGHT20 :
+{0x643B,0x5E,0x01}, // INFRM_RIGHT21 :
+{0x643C,0x58,0x01}, // INFRM_RIGHT22 :
+{0x643D,0x53,0x01}, // INFRM_RIGHT23 :
+{0x643E,0x4E,0x01}, // INFRM_RIGHT24 :
+{0x643F,0x4A,0x01}, // INFRM_RIGHT25 :
+{0x6440,0x46,0x01}, // INFRM_RIGHT26 :
+{0x6441,0x42,0x01}, // INFRM_RIGHT27 :
+{0x6442,0x3F,0x01}, // INFRM_RIGHT28 :
+{0x6443,0x3C,0x01}, // INFRM_RIGHT29 :
+{0x6444,0x3A,0x01}, // INFRM_RIGHT30 :
+{0x6445,0x38,0x01}, // INFRM_RIGHT31 :
+{0x6446,0x37,0x01}, // INFRM_RIGHT32 :
+{0x6447,0x35,0x01}, // INFRM_RIGHT33 :
+{0x6448,0x33,0x01}, // INFRM_RIGHT34 :
+{0x6449,0x32,0x01}, // INFRM_RIGHT35 :
+{0x644A,0x32,0x01}, // INFRM_RIGHT36 :
+{0x644B,0x32,0x01}, // INFRM_RIGHT37 :
+{0x644C,0x24FA,0x02}, // INFRM_TOP :
+{0x644E,0x0940,0x02}, // INFRM_BOTM :
+{0x6450,0x19,0x01}, // INFRM_FLTOP :
+{0x6451,0x10,0x01}, // INFRM_FLBOTM :
+{0x6452,0x91,0x01}, // INAIM_LEFT00 :
+{0x6453,0x91,0x01}, // INAIM_LEFT01 :
+{0x6454,0x91,0x01}, // INAIM_LEFT02 :
+{0x6455,0x91,0x01}, // INAIM_LEFT03 :
+{0x6456,0x91,0x01}, // INAIM_LEFT04 :
+{0x6457,0x91,0x01}, // INAIM_LEFT05 :
+{0x6458,0x91,0x01}, // INAIM_LEFT06 :
+{0x6459,0x91,0x01}, // INAIM_LEFT07 :
+{0x645A,0x91,0x01}, // INAIM_LEFT08 :
+{0x645B,0x91,0x01}, // INAIM_LEFT09 :
+{0x645C,0x91,0x01}, // INAIM_LEFT10 :
+{0x645D,0x91,0x01}, // INAIM_LEFT11 :
+{0x645E,0x91,0x01}, // INAIM_LEFT12 :
+{0x645F,0x66,0x01}, // INAIM_LEFT13 :
+{0x6460,0x71,0x01}, // INAIM_LEFT14 :
+{0x6461,0x5A,0x01}, // INAIM_LEFT15 :
+{0x6462,0x4E,0x01}, // INAIM_LEFT16 :
+{0x6463,0x47,0x01}, // INAIM_LEFT17 :
+{0x6464,0x42,0x01}, // INAIM_LEFT18 :
+{0x6465,0x3C,0x01}, // INAIM_LEFT19 :
+{0x6466,0x38,0x01}, // INAIM_LEFT20 :
+{0x6467,0x36,0x01}, // INAIM_LEFT21 :
+{0x6468,0x33,0x01}, // INAIM_LEFT22 :
+{0x6469,0x30,0x01}, // INAIM_LEFT23 :
+{0x646A,0x2F,0x01}, // INAIM_LEFT24 :
+{0x646B,0x2B,0x01}, // INAIM_LEFT25 :
+{0x646C,0x29,0x01}, // INAIM_LEFT26 :
+{0x646D,0x27,0x01}, // INAIM_LEFT27 :
+{0x646E,0x26,0x01}, // INAIM_LEFT28 :
+{0x646F,0x28,0x01}, // INAIM_LEFT29 :
+{0x6470,0x2A,0x01}, // INAIM_LEFT30 :
+{0x6471,0x28,0x01}, // INAIM_LEFT31 :
+{0x6472,0x26,0x01}, // INAIM_LEFT32 :
+{0x6473,0x24,0x01}, // INAIM_LEFT33 :
+{0x6474,0x29,0x01}, // INAIM_LEFT34 :
+{0x6475,0x28,0x01}, // INAIM_LEFT35 :
+{0x6476,0x29,0x01}, // INAIM_LEFT36 :
+{0x6477,0x26,0x01}, // INAIM_LEFT37 :
+{0x6478,0xFF,0x01}, // INAIM_RIGHT00 :
+{0x6479,0xFF,0x01}, // INAIM_RIGHT01 :
+{0x647A,0xFF,0x01}, // INAIM_RIGHT02 :
+{0x647B,0xFF,0x01}, // INAIM_RIGHT03 :
+{0x647C,0xFF,0x01}, // INAIM_RIGHT04 :
+{0x647D,0xFF,0x01}, // INAIM_RIGHT05 :
+{0x647E,0xFF,0x01}, // INAIM_RIGHT06 :
+{0x647F,0xFF,0x01}, // INAIM_RIGHT07 :
+{0x6480,0xFF,0x01}, // INAIM_RIGHT08 :
+{0x6481,0xFF,0x01}, // INAIM_RIGHT09 :
+{0x6482,0xD9,0x01}, // INAIM_RIGHT10 :
+{0x6483,0xB7,0x01}, // INAIM_RIGHT11 :
+{0x6484,0x96,0x01}, // INAIM_RIGHT12 :
+{0x6485,0x68,0x01}, // INAIM_RIGHT13 :
+{0x6486,0x72,0x01}, // INAIM_RIGHT14 :
+{0x6487,0x71,0x01}, // INAIM_RIGHT15 :
+{0x6488,0x6E,0x01}, // INAIM_RIGHT16 :
+{0x6489,0x6A,0x01}, // INAIM_RIGHT17 :
+{0x648A,0x65,0x01}, // INAIM_RIGHT18 :
+{0x648B,0x60,0x01}, // INAIM_RIGHT19 :
+{0x648C,0x5B,0x01}, // INAIM_RIGHT20 :
+{0x648D,0x56,0x01}, // INAIM_RIGHT21 :
+{0x648E,0x51,0x01}, // INAIM_RIGHT22 :
+{0x648F,0x4C,0x01}, // INAIM_RIGHT23 :
+{0x6490,0x47,0x01}, // INAIM_RIGHT24 :
+{0x6491,0x44,0x01}, // INAIM_RIGHT25 :
+{0x6492,0x41,0x01}, // INAIM_RIGHT26 :
+{0x6493,0x3E,0x01}, // INAIM_RIGHT27 :
+{0x6494,0x3B,0x01}, // INAIM_RIGHT28 :
+{0x6495,0x39,0x01}, // INAIM_RIGHT29 :
+{0x6496,0x37,0x01}, // INAIM_RIGHT30 :
+{0x6497,0x34,0x01}, // INAIM_RIGHT31 :
+{0x6498,0x33,0x01}, // INAIM_RIGHT32 :
+{0x6499,0x32,0x01}, // INAIM_RIGHT33 :
+{0x649A,0x31,0x01}, // INAIM_RIGHT34 :
+{0x649B,0x30,0x01}, // INAIM_RIGHT35 :
+{0x649C,0x2F,0x01}, // INAIM_RIGHT36 :
+{0x649D,0x2E,0x01}, // INAIM_RIGHT37 :
+{0x649E,0x1E00,0x02}, // INAIM_TOP :
+{0x64A0,0x0DFF,0x02}, // INAIM_BOTM :
+{0x64A2,0x18,0x01}, // INAIM_FLTOP :
+{0x64A3,0x09,0x01}, // INAIM_FLBOTM :
+{0x64A4,0xFF,0x01}, // OUTFRM_LEFT00 :
+{0x64A5,0xFF,0x01}, // OUTFRM_LEFT01 :
+{0x64A6,0xFF,0x01}, // OUTFRM_LEFT02 :
+{0x64A7,0xFF,0x01}, // OUTFRM_LEFT03 :
+{0x64A8,0xFF,0x01}, // OUTFRM_LEFT04 :
+{0x64A9,0xFF,0x01}, // OUTFRM_LEFT05 :
+{0x64AA,0xFF,0x01}, // OUTFRM_LEFT06 :
+{0x64AB,0xFF,0x01}, // OUTFRM_LEFT07 :
+{0x64AC,0xFF,0x01}, // OUTFRM_LEFT08 :
+{0x64AD,0xFD,0x01}, // OUTFRM_LEFT09 :
+{0x64AE,0xCB,0x01}, // OUTFRM_LEFT10 :
+{0x64AF,0xA9,0x01}, // OUTFRM_LEFT11 :
+{0x64B0,0x90,0x01}, // OUTFRM_LEFT12 :
+{0x64B1,0x7D,0x01}, // OUTFRM_LEFT13 :
+{0x64B2,0x70,0x01}, // OUTFRM_LEFT14 :
+{0x64B3,0x65,0x01}, // OUTFRM_LEFT15 :
+{0x64B4,0x5C,0x01}, // OUTFRM_LEFT16 :
+{0x64B5,0x55,0x01}, // OUTFRM_LEFT17 :
+{0x64B6,0x4F,0x01}, // OUTFRM_LEFT18 :
+{0x64B7,0x32,0x01}, // OUTFRM_LEFT19 :
+{0x64B8,0x4D,0x01}, // OUTFRM_LEFT20 :
+{0x64B9,0x40,0x01}, // OUTFRM_LEFT21 :
+{0x64BA,0x2D,0x01}, // OUTFRM_LEFT22 :
+{0x64BB,0x2B,0x01}, // OUTFRM_LEFT23 :
+{0x64BC,0x29,0x01}, // OUTFRM_LEFT24 :
+{0x64BD,0x27,0x01}, // OUTFRM_LEFT25 :
+{0x64BE,0x25,0x01}, // OUTFRM_LEFT26 :
+{0x64BF,0x23,0x01}, // OUTFRM_LEFT27 :
+{0x64C0,0x21,0x01}, // OUTFRM_LEFT28 :
+{0x64C1,0x1F,0x01}, // OUTFRM_LEFT29 :
+{0x64C2,0x1D,0x01}, // OUTFRM_LEFT30 :
+{0x64C3,0x1B,0x01}, // OUTFRM_LEFT31 :
+{0x64C4,0x1A,0x01}, // OUTFRM_LEFT32 :
+{0x64C5,0x1A,0x01}, // OUTFRM_LEFT33 :
+{0x64C6,0x1A,0x01}, // OUTFRM_LEFT34 :
+{0x64C7,0x28,0x01}, // OUTFRM_LEFT35 :
+{0x64C8,0x27,0x01}, // OUTFRM_LEFT36 :
+{0x64C9,0x26,0x01}, // OUTFRM_LEFT37 :
+{0x64CA,0xFF,0x01}, // OUTFRM_RIGHT00 :
+{0x64CB,0xFF,0x01}, // OUTFRM_RIGHT01 :
+{0x64CC,0xFF,0x01}, // OUTFRM_RIGHT02 :
+{0x64CD,0xFF,0x01}, // OUTFRM_RIGHT03 :
+{0x64CE,0xFF,0x01}, // OUTFRM_RIGHT04 :
+{0x64CF,0xFF,0x01}, // OUTFRM_RIGHT05 :
+{0x64D0,0xFF,0x01}, // OUTFRM_RIGHT06 :
+{0x64D1,0xFF,0x01}, // OUTFRM_RIGHT07 :
+{0x64D2,0xFF,0x01}, // OUTFRM_RIGHT08 :
+{0x64D3,0xFF,0x01}, // OUTFRM_RIGHT09 :
+{0x64D4,0xD3,0x01}, // OUTFRM_RIGHT10 :
+{0x64D5,0xB1,0x01}, // OUTFRM_RIGHT11 :
+{0x64D6,0x98,0x01}, // OUTFRM_RIGHT12 :
+{0x64D7,0x85,0x01}, // OUTFRM_RIGHT13 :
+{0x64D8,0x78,0x01}, // OUTFRM_RIGHT14 :
+{0x64D9,0x6D,0x01}, // OUTFRM_RIGHT15 :
+{0x64DA,0x64,0x01}, // OUTFRM_RIGHT16 :
+{0x64DB,0x5D,0x01}, // OUTFRM_RIGHT17 :
+{0x64DC,0x57,0x01}, // OUTFRM_RIGHT18 :
+{0x64DD,0x63,0x01}, // OUTFRM_RIGHT19 :
+{0x64DE,0x5E,0x01}, // OUTFRM_RIGHT20 :
+{0x64DF,0x5A,0x01}, // OUTFRM_RIGHT21 :
+{0x64E0,0x56,0x01}, // OUTFRM_RIGHT22 :
+{0x64E1,0x52,0x01}, // OUTFRM_RIGHT23 :
+{0x64E2,0x50,0x01}, // OUTFRM_RIGHT24 :
+{0x64E3,0x4E,0x01}, // OUTFRM_RIGHT25 :
+{0x64E4,0x4C,0x01}, // OUTFRM_RIGHT26 :
+{0x64E5,0x4A,0x01}, // OUTFRM_RIGHT27 :
+{0x64E6,0x48,0x01}, // OUTFRM_RIGHT28 :
+{0x64E7,0x46,0x01}, // OUTFRM_RIGHT29 :
+{0x64E8,0x44,0x01}, // OUTFRM_RIGHT30 :
+{0x64E9,0x43,0x01}, // OUTFRM_RIGHT31 :
+{0x64EA,0x42,0x01}, // OUTFRM_RIGHT32 :
+{0x64EB,0x42,0x01}, // OUTFRM_RIGHT33 :
+{0x64EC,0x42,0x01}, // OUTFRM_RIGHT34 :
+{0x64ED,0x30,0x01}, // OUTFRM_RIGHT35 :
+{0x64EE,0x2F,0x01}, // OUTFRM_RIGHT36 :
+{0x64EF,0x2E,0x01}, // OUTFRM_RIGHT37 :
+{0x64F0,0x2163,0x02}, // OUTFRM_TOP :
+{0x64F2,0x1400,0x02}, // OUTFRM_BOTM :
+{0x64F4,0x19,0x01}, // OUTFRM_FLTOP :
+{0x64F5,0x14,0x01}, // OUTFRM_FLBOTM :
+//AWB
+{0x6232,0xFF,0x01}, // ATW_SFTLMT_OUT_NR
+{0x6234,0xFF,0x01}, // ATW_SFTLMT_OUT
+/////MC3 Setting/////
+{0x7600,0x07,0x01}, // MC3_PXDEF0_SEL :
+{0x7601,0x07,0x01}, // MC3_PYDEF0_SEL :
+{0x7602,0x07,0x01}, // MC3_PXDEF1_SEL :
+{0x7603,0x07,0x01}, // MC3_PYDEF1_SEL :
+{0x7604,0x07,0x01}, // MC3_PXDEF2_SEL :
+{0x7605,0x07,0x01}, // MC3_PYDEF2_SEL :
+{0x7606,0x07,0x01}, // MC3_PXDEF3_SEL :
+{0x7607,0x07,0x01}, // MC3_PYDEF3_SEL :
+{0x7608,0x40,0x01}, // MC3_PXDEF0_A :
+{0x7609,0x40,0x01}, // MC3_PXDEF0_B :
+{0x760A,0x40,0x01}, // MC3_PXDEF0_C :
+{0x760B,0x40,0x01}, // MC3_PYDEF0_A :
+{0x760C,0x40,0x01}, // MC3_PYDEF0_B :
+{0x760D,0x40,0x01}, // MC3_PYDEF0_C :
+{0x760E,0x40,0x01}, // MC3_PXDEF1_A :
+{0x760F,0x40,0x01}, // MC3_PXDEF1_B :
+{0x7610,0x40,0x01}, // MC3_PXDEF1_C :
+{0x7611,0x40,0x01}, // MC3_PYDEF1_A :
+{0x7612,0x40,0x01}, // MC3_PYDEF1_B :
+{0x7613,0x40,0x01}, // MC3_PYDEF1_C :
+{0x7614,0x40,0x01}, // MC3_PXDEF2_A :
+{0x7615,0x40,0x01}, // MC3_PXDEF2_B :
+{0x7616,0x40,0x01}, // MC3_PXDEF2_C :
+{0x7617,0x40,0x01}, // MC3_PYDEF2_A :
+{0x7618,0x40,0x01}, // MC3_PYDEF2_B :
+{0x7619,0x40,0x01}, // MC3_PYDEF2_C :
+{0x761A,0x40,0x01}, // MC3_PXDEF3_A :
+{0x761B,0x40,0x01}, // MC3_PXDEF3_B :
+{0x761C,0x40,0x01}, // MC3_PXDEF3_C :
+{0x761D,0x40,0x01}, // MC3_PYDEF3_A :
+{0x761E,0x40,0x01}, // MC3_PYDEF3_B :
+{0x761F,0x40,0x01}, // MC3_PYDEF3_C :
+{0x7620,0x00,0x01}, // MC3_LUMSL0_IN :
+{0x7621,0x06,0x01}, // MC3_LUMSL1_IN :
+{0x7622,0x03,0x01}, // MC3_LUMSL2_IN :
+{0x7623,0x06,0x01}, // MC3_LUMSL3_IN :
+{0x7624,0x00,0x01}, // MC3_LUMSL0_OUT :
+{0x7625,0x03,0x01}, // MC3_LUMSL1_OUT :
+{0x7626,0x00,0x01}, // MC3_LUMSL2_OUT :
+{0x7627,0x00,0x01}, // MC3_LUMSL3_OUT :
+{0x7628,0x0000,0x02}, // MC3_L0DEF0_IN :
+{0x762A,0x008C,0x02}, // MC3_L0DEF1_IN :
+{0x762C,0x0078,0x02}, // MC3_L0DEF2_IN :
+{0x762E,0x00E6,0x02}, // MC3_L0DEF3_IN :
+{0x7630,0x0000,0x02}, // MC3_L0DEF0_OUT :
+{0x7632,0x0082,0x02}, // MC3_L0DEF1_OUT :
+{0x7634,0x0000,0x02}, // MC3_L0DEF2_OUT :
+{0x7636,0x0000,0x02}, // MC3_L0DEF3_OUT :
+{0x7638,0x41,0x01}, // MC3_RDEF0_POS1 :
+{0x7639,0x10,0x01}, // MC3_RDEF1_POS1 :
+{0x763A,0x15,0x01}, // MC3_RDEF2_POS1 :
+{0x763B,0x71,0x01}, // MC3_RDEF3_POS1 :
+{0x763C,0x41,0x01}, // MC3_RDEF0_POS2 :
+{0x763D,0x10,0x01}, // MC3_RDEF1_POS2 :
+{0x763E,0x15,0x01}, // MC3_RDEF2_POS2 :
+{0x763F,0x71,0x01}, // MC3_RDEF3_POS2 :
+{0x7640,0x3C,0x01}, // MC3_RDEF0_POS3 :
+{0x7641,0x10,0x01}, // MC3_RDEF1_POS3 :
+{0x7642,0x15,0x01}, // MC3_RDEF2_POS3 :
+{0x7643,0x71,0x01}, // MC3_RDEF3_POS3 :
+{0x7644,0x46,0x01}, // MC3_RDEF0_POS4 :
+{0x7645,0x32,0x01}, // MC3_RDEF1_POS4 :
+{0x7646,0x15,0x01}, // MC3_RDEF2_POS4 :
+{0x7647,0x71,0x01}, // MC3_RDEF3_POS4 :
+{0x7648,0x46,0x01}, // MC3_RDEF0_POS5 :
+{0x7649,0x32,0x01}, // MC3_RDEF1_POS5 :
+{0x764A,0x15,0x01}, // MC3_RDEF2_POS5 :
+{0x764B,0x71,0x01}, // MC3_RDEF3_POS5 :
+{0x764C,0x46,0x01}, // MC3_RDEF0_POS6 :
+{0x764D,0x10,0x01}, // MC3_RDEF1_POS6 :
+{0x764E,0x15,0x01}, // MC3_RDEF2_POS6 :
+{0x764F,0x71,0x01}, // MC3_RDEF3_POS6 :
+{0x7650,0x46,0x01}, // MC3_RDEF0_POS7 :
+{0x7651,0x10,0x01}, // MC3_RDEF1_POS7 :
+{0x7652,0x15,0x01}, // MC3_RDEF2_POS7 :
+{0x7653,0x71,0x01}, // MC3_RDEF3_POS7 :
+{0x7654,0x2D,0x01}, // MC3_RDEF0_OUT :
+{0x7655,0x10,0x01}, // MC3_RDEF1_OUT :
+{0x7656,0x15,0x01}, // MC3_RDEF2_OUT :
+{0x7657,0x54,0x01}, // MC3_RDEF3_OUT :
+{0x7658,0x46,0x01}, // MC3_RDEF0_R2_POS4 :
+{0x7659,0x32,0x01}, // MC3_RDEF1_R2_POS4 :
+{0x765A,0x15,0x01}, // MC3_RDEF2_R2_POS4 :
+{0x765B,0x71,0x01}, // MC3_RDEF3_R2_POS4 :
+{0x765C,0x46,0x01}, // MC3_RDEF0_R2_POS5 :
+{0x765D,0x32,0x01}, // MC3_RDEF1_R2_POS5 :
+{0x765E,0x15,0x01}, // MC3_RDEF2_R2_POS5 :
+{0x765F,0x71,0x01}, // MC3_RDEF3_R2_POS5 :
+{0x7660,0xFFBA,0x02}, // MC3_X0DEF0_POS1 :
+{0x7662,0xFFBA,0x02}, // MC3_Y0DEF0_POS1 :
+{0x7664,0xFFFE,0x02}, // MC3_X0DEF1_POS1 :
+{0x7666,0x000D,0x02}, // MC3_Y0DEF1_POS1 :
+{0x7668,0x0002,0x02}, // MC3_X0DEF2_POS1 :
+{0x766A,0xFFF6,0x02}, // MC3_Y0DEF2_POS1 :
+{0x766C,0x003B,0x02}, // MC3_X0DEF3_POS1 :
+{0x766E,0xFFBB,0x02}, // MC3_Y0DEF3_POS1 :
+{0x7670,0xFFBA,0x02}, // MC3_X0DEF0_POS2 :
+{0x7672,0xFFBA,0x02}, // MC3_Y0DEF0_POS2 :
+{0x7674,0xFFFE,0x02}, // MC3_X0DEF1_POS2 :
+{0x7676,0x000D,0x02}, // MC3_Y0DEF1_POS2 :
+{0x7678,0x0002,0x02}, // MC3_X0DEF2_POS2 :
+{0x767A,0xFFF6,0x02}, // MC3_Y0DEF2_POS2 :
+{0x767C,0x003B,0x02}, // MC3_X0DEF3_POS2 :
+{0x767E,0xFFBB,0x02}, // MC3_Y0DEF3_POS2 :
+{0x7680,0xFFCE,0x02}, // MC3_X0DEF0_POS3 :
+{0x7682,0xFFBA,0x02}, // MC3_Y0DEF0_POS3 :
+{0x7684,0xFFFE,0x02}, // MC3_X0DEF1_POS3 :
+{0x7686,0x000D,0x02}, // MC3_Y0DEF1_POS3 :
+{0x7688,0x0002,0x02}, // MC3_X0DEF2_POS3 :
+{0x768A,0xFFF6,0x02}, // MC3_Y0DEF2_POS3 :
+{0x768C,0x003B,0x02}, // MC3_X0DEF3_POS3 :
+{0x768E,0xFFBB,0x02}, // MC3_Y0DEF3_POS3 :
+{0x7690,0xFFCE,0x02}, // MC3_X0DEF0_POS4 :
+{0x7692,0xFFC9,0x02}, // MC3_Y0DEF0_POS4 :
+{0x7694,0xFFD0,0x02}, // MC3_X0DEF1_POS4 :
+{0x7696,0x0037,0x02}, // MC3_Y0DEF1_POS4 :
+{0x7698,0x0002,0x02}, // MC3_X0DEF2_POS4 :
+{0x769A,0xFFF6,0x02}, // MC3_Y0DEF2_POS4 :
+{0x769C,0x003B,0x02}, // MC3_X0DEF3_POS4 :
+{0x769E,0xFFBB,0x02}, // MC3_Y0DEF3_POS4 :
+{0x76A0,0xFFCE,0x02}, // MC3_X0DEF0_POS5 :
+{0x76A2,0xFFC9,0x02}, // MC3_Y0DEF0_POS5 :
+{0x76A4,0xFFD0,0x02}, // MC3_X0DEF1_POS5 :
+{0x76A6,0x0037,0x02}, // MC3_Y0DEF1_POS5 :
+{0x76A8,0x0002,0x02}, // MC3_X0DEF2_POS5 :
+{0x76AA,0xFFF6,0x02}, // MC3_Y0DEF2_POS5 :
+{0x76AC,0x003B,0x02}, // MC3_X0DEF3_POS5 :
+{0x76AE,0xFFBB,0x02}, // MC3_Y0DEF3_POS5 :
+{0x76B0,0xFFCE,0x02}, // MC3_X0DEF0_POS6 :
+{0x76B2,0xFFC9,0x02}, // MC3_Y0DEF0_POS6 :
+{0x76B4,0xFFFE,0x02}, // MC3_X0DEF1_POS6 :
+{0x76B6,0x000D,0x02}, // MC3_Y0DEF1_POS6 :
+{0x76B8,0x0002,0x02}, // MC3_X0DEF2_POS6 :
+{0x76BA,0xFFF6,0x02}, // MC3_Y0DEF2_POS6 :
+{0x76BC,0x003B,0x02}, // MC3_X0DEF3_POS6 :
+{0x76BE,0xFFBB,0x02}, // MC3_Y0DEF3_POS6 :
+{0x76C0,0xFFCE,0x02}, // MC3_X0DEF0_POS7 :
+{0x76C2,0xFFC9,0x02}, // MC3_Y0DEF0_POS7 :
+{0x76C4,0xFFFE,0x02}, // MC3_X0DEF1_POS7 :
+{0x76C6,0x000D,0x02}, // MC3_Y0DEF1_POS7 :
+{0x76C8,0x0002,0x02}, // MC3_X0DEF2_POS7 :
+{0x76CA,0xFFF6,0x02}, // MC3_Y0DEF2_POS7 :
+{0x76CC,0x003B,0x02}, // MC3_X0DEF3_POS7 :
+{0x76CE,0xFFBB,0x02}, // MC3_Y0DEF3_POS7 :
+{0x76D0,0xFF7E,0x02}, // MC3_X0DEF0_OUT :
+{0x76D2,0xFFE2,0x02}, // MC3_Y0DEF0_OUT :
+{0x76D4,0xFFFE,0x02}, // MC3_X0DEF1_OUT :
+{0x76D6,0x000D,0x02}, // MC3_Y0DEF1_OUT :
+{0x76D8,0x0002,0x02}, // MC3_X0DEF2_OUT :
+{0x76DA,0xFFF6,0x02}, // MC3_Y0DEF2_OUT :
+{0x76DC,0xFFC4,0x02}, // MC3_X0DEF3_OUT :
+{0x76DE,0xFFEC,0x02}, // MC3_Y0DEF3_OUT :
+{0x76E0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS4 :
+{0x76E2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS4 :
+{0x76E4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS4 :
+{0x76E6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS4 :
+{0x76E8,0x0002,0x02}, // MC3_X0DEF2_R2_POS4 :
+{0x76EA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS4 :
+{0x76EC,0x003B,0x02}, // MC3_X0DEF3_R2_POS4 :
+{0x76EE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS4 :
+{0x76F0,0xFFCE,0x02}, // MC3_X0DEF0_R2_POS5 :
+{0x76F2,0xFFC9,0x02}, // MC3_Y0DEF0_R2_POS5 :
+{0x76F4,0xFFD0,0x02}, // MC3_X0DEF1_R2_POS5 :
+{0x76F6,0x0037,0x02}, // MC3_Y0DEF1_R2_POS5 :
+{0x76F8,0x0002,0x02}, // MC3_X0DEF2_R2_POS5 :
+{0x76FA,0xFFF6,0x02}, // MC3_Y0DEF2_R2_POS5 :
+{0x76FC,0x003B,0x02}, // MC3_X0DEF3_R2_POS5 :
+{0x76FE,0xFFBB,0x02}, // MC3_Y0DEF3_R2_POS5 :
+{0x7700,0x0019,0x02}, // MC3_PXDEF0_POS1 :
+{0x7702,0xFF66,0x02}, // MC3_PYDEF0_POS1 :
+{0x7704,0x0000,0x02}, // MC3_PXDEF1_POS1 :
+{0x7706,0x0000,0x02}, // MC3_PYDEF1_POS1 :
+{0x7708,0x0000,0x02}, // MC3_PXDEF2_POS1 :
+{0x770A,0x0000,0x02}, // MC3_PYDEF2_POS1 :
+{0x770C,0xFFD7,0x02}, // MC3_PXDEF3_POS1 :
+{0x770E,0x0068,0x02}, // MC3_PYDEF3_POS1 :
+{0x7710,0x0000,0x02}, // MC3_PXDEF0_POS2 :
+{0x7712,0xFF66,0x02}, // MC3_PYDEF0_POS2 :
+{0x7714,0x0033,0x02}, // MC3_PXDEF1_POS2 :
+{0x7716,0xFF4C,0x02}, // MC3_PYDEF1_POS2 :
+{0x7718,0x0000,0x02}, // MC3_PXDEF2_POS2 :
+{0x771A,0x00B3,0x02}, // MC3_PYDEF2_POS2 :
+{0x771C,0xFFD7,0x02}, // MC3_PXDEF3_POS2 :
+{0x771E,0x0068,0x02}, // MC3_PYDEF3_POS2 :
+{0x7720,0x0000,0x02}, // MC3_PXDEF0_POS3 :
+{0x7722,0xFF80,0x02}, // MC3_PYDEF0_POS3 :
+{0x7724,0x0000,0x02}, // MC3_PXDEF1_POS3 :
+{0x7726,0x0000,0x02}, // MC3_PYDEF1_POS3 :
+{0x7728,0x0000,0x02}, // MC3_PXDEF2_POS3 :
+{0x772A,0x0000,0x02}, // MC3_PYDEF2_POS3 :
+{0x772C,0xFFD7,0x02}, // MC3_PXDEF3_POS3 :
+{0x772E,0x0068,0x02}, // MC3_PYDEF3_POS3 :
+{0x7730,0x0000,0x02}, // MC3_PXDEF0_POS4 :
+{0x7732,0xFFCC,0x02}, // MC3_PYDEF0_POS4 :
+{0x7734,0x0000,0x02}, // MC3_PXDEF1_POS4 :
+{0x7736,0x0000,0x02}, // MC3_PYDEF1_POS4 :
+{0x7738,0x0000,0x02}, // MC3_PXDEF2_POS4 :
+{0x773A,0x0000,0x02}, // MC3_PYDEF2_POS4 :
+{0x773C,0xFFD7,0x02}, // MC3_PXDEF3_POS4 :
+{0x773E,0x0068,0x02}, // MC3_PYDEF3_POS4 :
+{0x7740,0x0000,0x02}, // MC3_PXDEF0_POS5 :
+{0x7742,0xFFCC,0x02}, // MC3_PYDEF0_POS5 :
+{0x7744,0x0000,0x02}, // MC3_PXDEF1_POS5 :
+{0x7746,0x0000,0x02}, // MC3_PYDEF1_POS5 :
+{0x7748,0x0000,0x02}, // MC3_PXDEF2_POS5 :
+{0x774A,0x0000,0x02}, // MC3_PYDEF2_POS5 :
+{0x774C,0xFFD7,0x02}, // MC3_PXDEF3_POS5 :
+{0x774E,0x0068,0x02}, // MC3_PYDEF3_POS5 :
+{0x7750,0xFFB3,0x02}, // MC3_PXDEF0_POS6 :
+{0x7752,0x0000,0x02}, // MC3_PYDEF0_POS6 :
+{0x7754,0x0033,0x02}, // MC3_PXDEF1_POS6 :
+{0x7756,0xFF4C,0x02}, // MC3_PYDEF1_POS6 :
+{0x7758,0x0000,0x02}, // MC3_PXDEF2_POS6 :
+{0x775A,0x00B3,0x02}, // MC3_PYDEF2_POS6 :
+{0x775C,0xFFD7,0x02}, // MC3_PXDEF3_POS6 :
+{0x775E,0x0068,0x02}, // MC3_PYDEF3_POS6 :
+{0x7760,0xFFB3,0x02}, // MC3_PXDEF0_POS7 :
+{0x7762,0x0000,0x02}, // MC3_PYDEF0_POS7 :
+{0x7764,0x0000,0x02}, // MC3_PXDEF1_POS7 :
+{0x7766,0x0000,0x02}, // MC3_PYDEF1_POS7 :
+{0x7768,0x0000,0x02}, // MC3_PXDEF2_POS7 :
+{0x776A,0x0000,0x02}, // MC3_PYDEF2_POS7 :
+{0x776C,0xFFD7,0x02}, // MC3_PXDEF3_POS7 :
+{0x776E,0x0068,0x02}, // MC3_PYDEF3_POS7 :
+{0x7770,0x0019,0x02}, // MC3_PXDEF0_OUT :
+{0x7772,0xFFE6,0x02}, // MC3_PYDEF0_OUT :
+{0x7774,0x0000,0x02}, // MC3_PXDEF1_OUT :
+{0x7776,0x0000,0x02}, // MC3_PYDEF1_OUT :
+{0x7778,0x0000,0x02}, // MC3_PXDEF2_OUT :
+{0x777A,0x0000,0x02}, // MC3_PYDEF2_OUT :
+{0x777C,0xFFE1,0x02}, // MC3_PXDEF3_OUT :
+{0x777E,0xFFEB,0x02}, // MC3_PYDEF3_OUT :
+{0x7780,0x0000,0x02}, // MC3_PXDEF0_R2_POS4 :
+{0x7782,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS4 :
+{0x7784,0x0000,0x02}, // MC3_PXDEF1_R2_POS4 :
+{0x7786,0x0000,0x02}, // MC3_PYDEF1_R2_POS4 :
+{0x7788,0x0000,0x02}, // MC3_PXDEF2_R2_POS4 :
+{0x778A,0x0000,0x02}, // MC3_PYDEF2_R2_POS4 :
+{0x778C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS4 :
+{0x778E,0x0068,0x02}, // MC3_PYDEF3_R2_POS4 :
+{0x7790,0x0000,0x02}, // MC3_PXDEF0_R2_POS5 :
+{0x7792,0xFFCC,0x02}, // MC3_PYDEF0_R2_POS5 :
+{0x7794,0x0000,0x02}, // MC3_PXDEF1_R2_POS5 :
+{0x7796,0x0000,0x02}, // MC3_PYDEF1_R2_POS5 :
+{0x7798,0x0000,0x02}, // MC3_PXDEF2_R2_POS5 :
+{0x779A,0x0000,0x02}, // MC3_PYDEF2_R2_POS5 :
+{0x779C,0xFFD7,0x02}, // MC3_PXDEF3_R2_POS5 :
+{0x779E,0x0068,0x02}, // MC3_PYDEF3_R2_POS5 :
+};
+
+static const isx012_regset_t ISX012_Halfrelease_Mode[] =
+{
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B1,0x01,0x01}, //AF_RESTART_F :
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
+{0x00B3,0x00,0x01}, //AFMODE_HREL :
+//{0xFFFF,0x42,0x01}, //$wait, 66
+{0x0081,0x01,0x01}, //MODESEL
+};
+
+static const isx012_regset_t ISX012_Barcode_SAF[] =
+{
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B1,0x01,0x01}, //AF_RESTART_F :
+//{0xFFFF,0x21,0x01}, //$wait, 33
+{0x00B2,0x00,0x01}, //AFMODE_MONI :
+};
+
+static const isx012_regset_t ISX012_Lowlux_night_Halfrelease_Mode[] =
+{
+{0x660E,0x04,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN
+{0x6610,0x04,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX
+{0x664A,0x01,0x01}, // AF_DROPN_ON_PEAK_DETECT :
+{0x6640,0x01,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND :
+{0x0289,0x21,0x01}, //AWB_SN8
+{0x6674,0x01,0x01}, // AF_MONICHG_MOVE_F
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B1,0x01,0x01}, //AF_RESTART_F
+{0x00B3,0x00,0x01}, //AFMODE_HREL :
+//{0xFFFF,0x42,0x01}, //$wait, 66
+{0x0081,0x01,0x01}, //MODESEL
+};
+
+static const isx012_regset_t ISX012_AF_Cancel_Macro_ON[] =
+{
+{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode
+{0x0081,0x00,0x01}, //MODESEL : Monitoring mode
+{0x6648,0x02BC,0x02}, //AF_MANUAL_POS : MANUA AF search start position
+{0x00B1,0x01,0x01}, //AF_RESTART_F
+};
+
+static const isx012_regset_t ISX012_AF_Cancel_Macro_OFF[] =
+{
+{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode
+{0x0081,0x00,0x01}, //MODESEL : Monitoring mode
+{0x6648,0x00C8,0x02}, //AF_MANUAL_POS : MANUA AF search start position
+{0x00B1,0x01,0x01}, //AF_RESTART_F
+};
+
+static const isx012_regset_t ISX012_AF_ReStart[] =
+{
+{0x00B1,0x01,0x01}, //AF_RESTART_F
+{0x0082,0x01,0x01}, // MONI_REFRESH
+};
+
+static const isx012_regset_t ISX012_AF_Macro_OFF[] =
+{
+{0x0081,0x00,0x01}, //MODESEL : Monitoring mode
+{0x6648,0x00C8,0x02}, //AF_MANUAL_POS : MANUA AF search start position
+{0x66DC,0x02BC,0x02}, //AF_JUDGE_MONO_POS_S
+{0x665A,0x00C8,0x02}, // AF_LENSPOS_ON_AFNG :
+{0x028E,0x00,0x01}, //AF_SEARCH_DIR : NEAR->FAR
+{0x00B3,0x00,0x01}, //AFMODE_HREL : Manual AF mode
+{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode
+//{0xFFFF,0x21,0x01}, //$wait, 33
+};
+
+static const isx012_regset_t ISX012_AF_Macro_ON[] =
+{
+{0x0081,0x00,0x01}, //MODESEL : Monitoring mode
+{0x6648,0x02BC,0x02}, //AF_MANUAL_POS : MANUA AF search start position
+{0x66DC,0x00C8,0x02}, //AF_JUDGE_MONO_POS_S
+{0x665A,0x02BC,0x02}, // AF_LENSPOS_ON_AFNG :
+{0x028E,0x01,0x01}, //AF_SEARCH_DIR : NEAR->FAR
+{0x00B3,0x00,0x01}, //AFMODE_HREL : Manual AF mode
+{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode
+//{0xFFFF,0x21,0x01}, //$wait, 33
+};
+
+static const isx012_regset_t ISX012_AF_SAF[] =
+{
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B1,0x01,0x01}, //AF_RESTART_F :
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
+{0x00B3,0x00,0x01}, //AFMODE_HREL :
+//{0xFFFF,0x42,0x01}, //$wait, 66
+{0x0081,0x01,0x01}, //MODESEL
+};
+
+static const isx012_regset_t ISX012_AF_SAF_OFF[] =
+{
+{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F
+{0x0082,0x01,0x01}, // MONI_REFRESH
+//{0xFFFF,0x42,0x01}, //$wait, 66
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
+{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF
+};
+
+static const isx012_regset_t ISX012_AF_TouchSAF_OFF[] =
+{
+{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F
+{0x0082,0x01,0x01}, // MONI_REFRESH
+//{0xFFFF,0x42,0x01}, //$wait, 66
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
+{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF
+{0x0081,0x00,0x01}, //MODESEL
+};
+
+static const isx012_regset_t ISX012_Camcorder_SAF_Start[] =
+{
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B1,0x01,0x01}, /* AF_RESTART_F */
+//{0xFFFF,0x21,0x01}, /* $wait, 33 */
+{0x00B2,0x00,0x01}, /* AFMODE_MONI */
+};
+
+static const isx012_regset_t ISX012_Camcorder_CAF_Start[] =
+{
+{0x00B2,0x01,0x01}, /* AFMODE_MONI */
+};
+
+static const isx012_regset_t ISX012_AF_Window_Reset[] =
+{
+//AF opd window setting
+{0x6A30,0x044E,0x02}, // AF_OPD0_HDELAY :
+{0x6A32,0x02E5,0x02}, // AF_OPD0_VDELAY :
+{0x6A34,0x01D8,0x02}, // AF_OPD0_HVALID :
+{0x6A36,0x01D8,0x02}, // AF_OPD0_VVALID :
+{0x6A38,0x0412,0x02}, // AF_OPD1_HDELAY :
+{0x6A3A,0x02A9,0x02}, // AF_OPD1_VDELAY :
+{0x6A3C,0x0251,0x02}, // AF_OPD1_HVALID :
+{0x6A3E,0x0251,0x02}, // AF_OPD1_VVALID :
+{0x6A40,0x04B4,0x02}, // AF_OPD2_HDELAY :
+{0x6A42,0x0114,0x02}, // AF_OPD2_VDELAY :
+{0x6A44,0x0118,0x02}, // AF_OPD2_HVALID :
+{0x6A46,0x0118,0x02}, // AF_OPD2_VVALID :
+{0x6A48,0x0469,0x02}, // AF_OPD3_HDELAY :
+{0x6A4A,0x00C9,0x02}, // AF_OPD3_VDELAY :
+{0x6A4C,0x01AE,0x02}, // AF_OPD3_HVALID :
+{0x6A4E,0x01AE,0x02}, // AF_OPD3_VVALID :
+{0x6A50,0x04C6,0x02}, // AF_OPD4_HDELAY :
+{0x6A52,0x035D,0x02}, // AF_OPD4_VDELAY :
+{0x6A54,0x00E6,0x02}, // AF_OPD4_HVALID :
+{0x6A56,0x00E6,0x02}, // AF_OPD4_VVALID :
+{0x6A58,0x048A,0x02}, // AF_OPD5_HDELAY :
+{0x6A5A,0x0321,0x02}, // AF_OPD5_VDELAY :
+{0x6A5C,0x015F,0x02}, // AF_OPD5_HVALID :
+{0x6A5E,0x015F,0x02}, // AF_OPD5_VVALID :
+{0x6A60,0x04B4,0x02}, // AF_OPD6_HDELAY :
+{0x6A62,0x0579,0x02}, // AF_OPD6_VDELAY :
+{0x6A64,0x0118,0x02}, // AF_OPD6_HVALID :
+{0x6A66,0x0118,0x02}, // AF_OPD6_VVALID :
+{0x6A68,0x0469,0x02}, // AF_OPD7_HDELAY :
+{0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY :
+{0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID :
+{0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID :
+{0x6A70,0x021D,0x02}, // AF_OPD8_HDELAY :
+{0x6A72,0x02F5,0x02}, // AF_OPD8_VDELAY :
+{0x6A74,0x01AE,0x02}, // AF_OPD8_HVALID :
+{0x6A76,0x01AE,0x02}, // AF_OPD8_VVALID :
+{0x6A78,0x06A4,0x02}, // AF_OPD9_HDELAY :
+{0x6A7A,0x02F5,0x02}, // AF_OPD9_VDELAY :
+{0x6A7C,0x01AE,0x02}, // AF_OPD9_HVALID :
+{0x6A7E,0x01AE,0x02}, // AF_OPD9_VVALID :
+{0x6A80,0x06,0x01}, // AF_OPD1A_WEIGHT :
+{0x6A81,0x05,0x01}, // AF_OPD1B_WEIGHT :
+{0x6A82,0x02,0x01}, // AF_OPD2A_WEIGHT :
+{0x6A83,0x02,0x01}, // AF_OPD2B_WEIGHT :
+{0x6A84,0x08,0x01}, // AF_OPD3A_WEIGHT :
+{0x6A85,0x07,0x01}, // AF_OPD3B_WEIGHT :
+{0x6A86,0x04,0x01}, // AF_OPD4A_WEIGHT :
+{0x6A87,0x03,0x01}, // AF_OPD4B_WEIGHT :
+{0x6A88,0x01,0x01}, // AF_OPD5A_WEIGHT :
+{0x6A89,0x01,0x01}, // AF_OPD5B_WEIGHT :
+{0x6646,0x08,0x01}, // AF_OPD_WEIGHT_TH :
+};
+
+/* Added by Samsung TN */
+static const isx012_regset_t ISX012_AF_Window_Set[] =
+{
+{0x6A80,0x00,0x01},
+{0x6A81,0x00,0x01},
+{0x6A82,0x00,0x01},
+{0x6A83,0x00,0x01},
+{0x6A84,0x08,0x01},
+{0x6A85,0x00,0x01},
+{0x6A86,0x00,0x01},
+{0x6A87,0x00,0x01},
+{0x6A88,0x00,0x01},
+{0x6A89,0x00,0x01},
+{0x6646,0x08,0x01},
+};
+
+static const isx012_regset_t isx012_Contrast_Minus_2[] =
+{
+{0x01C7,0x58,0x01}, //UICONTRAST
+};
+
+static const isx012_regset_t isx012_Contrast_Minus_1[] =
+{
+{0x01C7,0x6C,0x01}, //UICONTRAST
+};
+
+static const isx012_regset_t isx012_Contrast_Default[] =
+{
+{0x01C7,0x80,0x01}, //UICONTRAST
+};
+
+static const isx012_regset_t isx012_Contrast_Plus_1[] =
+{
+{0x01C7,0x94,0x01}, //UICONTRAST
+};
+
+static const isx012_regset_t isx012_Contrast_Plus_2[] =
+{
+{0x01C7,0xA8,0x01}, //UICONTRAST
+};
+
+static const isx012_regset_t isx012_Effect_Sketch[] =
+{
+{0x01C5,0x06,0x01}, /* FMODE */
+{0x6C5F,0x04,0x01}, /* SKETCH_APGAIN */
+};
+
+static const isx012_regset_t isx012_Effect_Pastel[] =
+{
+{0x01C5,0x05,0x01}, /* FMODE */
+};
+
+static const isx012_regset_t isx012_Effect_Black_White[] =
+{
+{0x01C5,0x04,0x01}, //FMODE
+};
+
+static const isx012_regset_t ISX012_Effect_Negative[] =
+{
+{0x01C5,0x02,0x01}, //FMODE
+};
+
+static const isx012_regset_t isx012_Effect_Solar[] =
+{
+{0x01C5,0x01,0x01}, /* FMODE */
+};
+
+static const isx012_regset_t isx012_Effect_Normal[] =
+{
+{0x01C5,0x00,0x01}, //FMODE
+};
+
+static const isx012_regset_t isx012_Effect_Sepia[] =
+{
+{0x01C5,0x03,0x01}, //FMODE
+};
+
+static const isx012_regset_t isx012_Metering_Center[] =
+{
+{0x02AC,0x01,0x01}, //AE_SUB_SN1
+{0x02B6,0x01,0x01}, //AE_SUB_SN11
+};
+
+static const isx012_regset_t isx012_Metering_Matrix[] =
+{
+{0x02AC,0x00,0x01}, //AE_SUB_SN1
+};
+
+static const isx012_regset_t isx012_Metering_Spot[] =
+{
+{0x02AC,0x02,0x01}, //AE_SUB_SN1
+{0x02B6,0x02,0x01}, //AE_SUB_SN11
+};
+
+static const isx012_regset_t ISX012_ExpSetting_Default[] =
+{
+{0x0180,0x00,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_M1Step[] =
+{
+{0x0180,0xFF,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_M2Step[] =
+{
+{0x0180,0xFE,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_M3Step[] =
+{
+{0x0180,0xFD,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_M4Step[] =
+{
+{0x0180,0xFC,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_P1Step[] =
+{
+{0x0180,0x01,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_P2Step[] =
+{
+{0x0180,0x02,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_P3Step[] =
+{
+{0x0180,0x03,0x01}, //EVSEL
+};
+
+static const isx012_regset_t ISX012_ExpSetting_P4Step[] =
+{
+{0x0180,0x04,0x01}, //EVSEL
+};
+
+static const isx012_regset_t isx012_ISO_50[] =
+{
+{0x02A8,0x04,0x01}, //ISO_TYPE1
+{0x5E8A,0x00,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x00,0x01}, // EVREF_GAIN_B :
+{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 :
+{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 :
+};
+
+static const isx012_regset_t isx012_ISO_100[] =
+{
+{0x02A8,0x07,0x01}, //ISO_TYPE1
+{0x5E8A,0x00,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x00,0x01}, // EVREF_GAIN_B :
+{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 :
+{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 :
+};
+
+static const isx012_regset_t isx012_ISO_200[] =
+{
+{0x02A8,0x0A,0x01}, //ISO_TYPE1
+{0x5E8A,0x00,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x00,0x01}, // EVREF_GAIN_B :
+{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 :
+{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 :
+};
+
+static const isx012_regset_t isx012_ISO_400[] =
+{
+{0x02A8,0x0D,0x01}, //ISO_TYPE1
+{0x5E8A,0x00,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x00,0x01}, // EVREF_GAIN_B :
+{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 :
+{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 :
+};
+
+#if 0
+static const isx012_regset_t ISX012_ISO_800[] =
+{
+{0x02A8,0x10,0x01}, //ISO_TYPE1
+{0x5E8A,0x00,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x00,0x01}, // EVREF_GAIN_B :
+{0x0362,0x57,0x01}, // PICT3_GAMMA_MONI0 :
+{0x0365,0x57,0x01}, // PICT3_GAMMA_CAP0 :
+};
+#endif
+
+static const isx012_regset_t isx012_ISO_Auto[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1
+{0x5E8A,0x02,0x01}, // EVREF_GAIN_A :
+{0x5E8B,0x02,0x01}, // EVREF_GAIN_B :
+{0x0362,0x55,0x01}, // PICT3_GAMMA_MONI0 :
+{0x0365,0x55,0x01}, // PICT3_GAMMA_CAP0 :
+};
+
+static const isx012_regset_t ISX012_Capture_SizeSetting[] =
+{
+{0x0092,0x0A20,0x02}, //HSIZE_CAP : 2592
+{0x0098,0x0798,0x02}, //VSIZE_CAP : 1944
+};
+
+static const isx012_regset_t ISX012_Capture_Mode[] =
+{
+{0x008A,0x00,0x01}, //OUTFMT_CAP
+{0x0084,0x00,0x01}, //SENSMODE_CAP
+{0x0087,0x03,0x01}, //FPSTYPE_CAP
+{0x0012,0xFF,0x01}, //INTCLR0
+{0x0081,0x02,0x01}, //MODESEL
+{0x0082,0x01,0x01}, //MONI_REFRESH
+};
+
+static const isx012_regset_t ISX012_Lowlux_Night_Capture_Mode[] =
+{
+{0x03A0,0xA0,0x01}, //UISATURATION_TYPE3 :
+{0x039D,0xF4,0x01}, //UIHUE_TYPE3 :
+{0x982A,0xFFD8,0x02}, // CS_CBLLEV_A :
+{0x9830,0xFFD8,0x02}, // CS_CRLLEV_A :
+{0x9805,0x06,0x01}, // CS_SLP_C_A :
+{0x008A,0x00,0x01}, //OUTFMT_CAP
+{0x0084,0x00,0x01}, //SENSMODE_CAP
+{0x0087,0x03,0x01}, //FPSTYPE_CAP
+{0x0012,0xFF,0x01}, //INTCLR0
+{0x0081,0x02,0x01}, //MODESEL
+{0x0082,0x01,0x01}, //MONI_REFRESH
+};
+
+static const isx012_regset_t isx012_Saturation_Default[] =
+{
+{0x039E,0x80,0x01}, //UISATURATION_TYPE1
+};
+
+static const isx012_regset_t isx012_Saturation_Minus_1[] =
+{
+{0x039E,0x62,0x01}, //UISATURATION_TYPE1
+};
+
+static const isx012_regset_t isx012_Saturation_Minus_2[] =
+{
+{0x039E,0x44,0x01}, //UISATURATION_TYPE1
+};
+
+static const isx012_regset_t isx012_Saturation_Plus_1[] =
+{
+{0x039E,0x9E,0x01}, //UISATURATION_TYPE1
+};
+
+static const isx012_regset_t isx012_Saturation_Plus_2[] =
+{
+{0x039E,0xBC,0x01}, //UISATURATION_TYPE1
+};
+
+static const isx012_regset_t isx012_Scene_Default[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x00,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Landscape[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 :
+{0x03A3,0x2C,0x01}, //UISHARPNESS_POS_TYPE3 : +1
+{0x03A6,0x2C,0x01}, //UISHARPNESS_NEG_TYPE3 : +1
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x01,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Sports[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x02,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Party_Indoor[] =
+{
+{0x02A8,0x0A,0x01}, //ISO_TYPE1 : ISO200
+{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 :
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x04,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x00,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Beach_Snow[] =
+{
+{0x02A8,0x04,0x01}, //ISO_TYPE1 : ISO50
+{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 :
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x04,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Sunset[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x0287,0x25,0x01}, //AWB_SN6 : daylight
+{0x0394,0x00,0x01}, //PICT1_SN6 :
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x05,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Duskdawn[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x0287,0x27,0x01}, //AWB_SN6 : CWF
+{0x0394,0x00,0x01}, //PICT1_SN6 :
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x05,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Candle_Light[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x0287,0x25,0x01}, //AWB_SN6 : daylight
+{0x0394,0x00,0x01}, //PICT1_SN6 :
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x05,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Fall_Color[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x039F,0xBC,0x01}, //UISATURATION_TYPE2 :
+{0x0287,0x20,0x01}, //AWB_SN6 : AWB
+{0x0394,0x04,0x01}, //PICT1_SN6 :
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x05,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Portrait[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x50,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x00,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Nightshot[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x07,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Fireworks[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : AUTO
+{0x5E06,0x04,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x08,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Text[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x03A3,0x38,0x01}, //UISHARPNESS_POS_TYPE3 : +2
+{0x03A6,0x38,0x01}, //UISHARPNESS_NEG_TYPE3 : +2
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0xA0,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x00,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Scene_Backlight[] =
+{
+{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
+{0x5E06,0x02,0x01}, //SHTCTRLMAG3
+{0x038F,0x00,0x01}, //PICT1_SN1 :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x500B,0x01,0x01}, // FAST_SHT_MODE_SEL
+{0x0280,0x00,0x01}, //SCENE_SELECT
+};
+
+static const isx012_regset_t isx012_Sharpness_Default[] =
+{
+{0x00A1,0x20,0x01}, //UISHARPNESS_POS_TYPE1
+{0x00A4,0x20,0x01}, //UISHARPNESS_NEG_TYPE1
+};
+
+static const isx012_regset_t isx012_Sharpness_Minus_1[] =
+{
+{0x00A1,0x14,0x01}, //UISHARPNESS_POS_TYPE1
+{0x00A4,0x14,0x01}, //UISHARPNESS_NEG_TYPE1
+};
+
+static const isx012_regset_t isx012_Sharpness_Minus_2[] =
+{
+{0x00A1,0x08,0x01}, //UISHARPNESS_POS_TYPE1
+{0x00A4,0x08,0x01}, //UISHARPNESS_NEG_TYPE1
+};
+
+static const isx012_regset_t isx012_Sharpness_Plus_1[] =
+{
+{0x00A1,0x2C,0x01}, //UISHARPNESS_POS_TYPE1
+{0x00A4,0x2C,0x01}, //UISHARPNESS_NEG_TYPE1
+};
+
+static const isx012_regset_t isx012_Sharpness_Plus_2[] =
+{
+{0x00A1,0x38,0x01}, //UISHARPNESS_POS_TYPE1
+{0x00A4,0x38,0x01}, //UISHARPNESS_NEG_TYPE1
+};
+
+static const isx012_regset_t isx012_WB_Auto[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_WB_Cloudy[] =
+{
+{0x0282,0x26,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_WB_Sunny[] =
+{
+{0x0282,0x25,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_WB_Fluorescent[] =
+{
+{0x0282,0x27,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_WB_Tungsten[] =
+{
+{0x0282,0x28,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t ISX012_Image_Quality_Standard[] =
+{
+{0x00F6,0x00,0x01}, //JPG_QLTY
+{0x0082,0x01,0x01}, //MONI_REFRESH
+};
+
+static const isx012_regset_t ISX012_Image_Quality_Fine[] =
+{
+{0x00F6,0x01,0x01}, //JPG_QLTY
+{0x0082,0x01,0x01}, //MONI_REFRESH
+};
+
+static const isx012_regset_t ISX012_Image_Quality_Super_Fine[] =
+{
+{0x00F6,0x02,0x01}, //JPG_QLTY
+{0x0082,0x01,0x01}, //MONI_REFRESH
+};
+
+static const isx012_regset_t ISX012_Image_Quality_Table[] =
+{
+{0x00F7,0x52,0x01}, // INIT_QLTY0 : Standard 82
+{0x00F8,0x59,0x01}, // INIT_QLTY1 : Fine 89
+{0x00F9,0x5F,0x01}, // INIT_QLTY2 : SuperFine 95
+};
+
+static const isx012_regset_t ISX012_Sensor_Off_VCM[] =
+{
+{0x6674,0x00,0x01}, // AF_MONICHG_MOVE_F
+{0x00B2,0x02,0x01}, //AFMODE_MONI : Manual AF mode
+{0x0081,0x00,0x01}, //MODESEL : Monitoring mode
+{0x6600,0x0000,0x02}, // AF_SEARCH_AREA_LOW
+{0x6666,0x0000,0x02}, // AF_AREA_LOW_TYPE1
+{0x6648,0x00C8,0x02}, // AF_MANUAL_POS :
+{0x00B1,0x01,0x01}, //AF_RESTART_F
+{0xFFFF,0x64,0x01}, // $wait, 100
+{0x6648,0x0019,0x02}, // AF_MANUAL_POS :
+{0x00B1,0x01,0x01}, // AF_RESTART_F
+{0xFFFF,0x64,0x01}, // $wait, 100
+};
+
+static const isx012_regset_t isx012_1280_Preview_E[] =
+{
+{0x0090,0x0500,0x02}, //HSIZE_MONI : 1280
+{0x0096,0x02D0,0x02}, //VSIZE_MONI : 720
+};
+
+static const isx012_regset_t isx012_1024_768_Preview[] = {
+{0x0090,0x0400,0x02}, /* HSIZE_MONI : 1024 */
+{0x0096,0x0300,0x02}, /* VSIZE_MONI : 768 */
+};
+
+static const isx012_regset_t isx012_800_Preview[] =
+{
+{0x0090,0x0320,0x02}, //HSIZE_MONI : 800
+{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480
+};
+
+static const isx012_regset_t isx012_720_Preview[] =
+{
+{0x0090,0x02D0,0x02}, //HSIZE_MONI : 720
+{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480
+};
+
+static const isx012_regset_t isx012_640_Preview[] =
+{
+{0x0090,0x0280,0x02}, //HSIZE_MONI : 640
+{0x0096,0x01E0,0x02}, //VSIZE_MONI : 480
+};
+
+#if defined(CONFIG_MACH_P4NOTELTE_KOR_SKT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_KT) \
+ || defined(CONFIG_MACH_P4NOTELTE_KOR_LGT) /*For 4G VT call in Domestic*/
+static const isx012_regset_t isx012_480_Preview[] = {
+{0x0090, 0x01E0, 0x02}, /* HSIZE_MONI : 480 */
+{0x0096, 0x0280, 0x02}, /* VSIZE_MONI : 640 */
+};
+#endif
+
+static const isx012_regset_t isx012_320_Preview[] =
+{
+{0x0090,0x0140,0x02}, //HSIZE_MONI : 320
+{0x0096,0x00F0,0x02}, //VSIZE_MONI :240
+
+};
+static const isx012_regset_t isx012_176_Preview[] =
+{
+{0x0090,0x00B0,0x02}, //HSIZE_MONI : 176
+{0x0096,0x0090,0x02}, //VSIZE_MONI : 144
+};
+
+
+static const isx012_regset_t isx012_5M_Capture[] = {
+{0x0092,0x0A00,0x02}, /* HSIZE_CAP: 2560 */
+{0x0098,0x0780,0x02}, /* VSIZE_CAP: 1920 */
+};
+
+static const isx012_regset_t isx012_4M_WIDE_Capture[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_3M_Capture[] = {
+{0x0092,0x0800,0x02}, /* HSIZE_CAP : 2048 */
+{0x0098,0x0600,0x02}, /* VSIZE_CAP : 1536 */
+};
+
+static const isx012_regset_t isx012_2_4M_WIDE_Capture[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_1_5M_WIDE_Capture[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_960_720_Capture[] = {
+{0x0092,0x03C0,0x02}, /* HSIZE_CAP : 960 */
+{0x0098,0x02D0,0x02}, /* VSIZE_CAP : 720 */
+};
+
+static const isx012_regset_t isx012_1M_Capture[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_4K_WIDE_Capture[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_VGA_Capture[] = {
+{0x0092,0x0280,0x02}, /* HSIZE_CAP : 640 */
+{0x0098,0x01E0,0x02}, /* VSIZE_CAP : 480 */
+};
+
+static const isx012_regset_t isx012_QVGA_Capture[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_DTP_init[] =
+{
+{0x01BC,0x50,0x01},//Shading Gain off
+{0x5E00,0x07,0x01},//Flicker off
+
+// Pre-WB
+{0x6804,0x1000,0x02}, // NORMR
+{0x6806,0x1000,0x02}, // NORMB
+{0x6808,0x0100,0x02}, // AWBPRER
+{0x680A,0x0100,0x02}, // AWBPREB
+{0x6818,0x00,0x01}, //REFERENCE SENSITIVITY RATIO OF SENSOR (R/G)
+{0x6819,0x00,0x01}, //REFERENCE SENSITIVITY RATIO OF SENSOR (B/G)
+
+{0x036B,0x11,0x01},
+{0x0377,0x11,0x01},
+{0x0383,0x11,0x01},
+
+//
+{0x6C44,0x00,0x01}, // G_CTRL_SEL :
+
+//CNR
+{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 :
+
+//ITP NR
+{0x5005,0xBB,0x01}, // DM_SW1 :
+{0x5006,0x03,0x01}, // DM_SW2 :
+{0x0362,0x00,0x01},
+
+{0x6C0B,0x04,0x01}, // PICT_FLAG :
+{0x9800,0x80,0x01}, // LMT_WEIGHT_A :
+{0x9801,0x80,0x01}, // LMT_WEIGHT_B :
+
+{0x6C46,0x00,0x01}, // MAIN_CONFIG1 :
+{0x6C47,0x00,0x01}, // MAIN_CONFIG2 :
+{0x6C48,0x00,0x01}, // MAIN_CONFIG3 :
+{0x6C49,0x00,0x01}, // MAIN_CONFIG4 :
+{0x6C4A,0x00,0x01}, // MAIN_CONFIG5 :
+
+
+{0x5001,0x04,0x01}, // MUTECNT :
+{0x5002,0x00,0x01}, // WDT_EN :
+{0x5003,0x07,0x01}, // Z1_SEL1 :
+{0x5004,0x00,0x01}, // Z1_SEL2 :
+{0x5005,0x00,0x01}, // DM_SW1 :
+{0x5006,0x00,0x01}, // DM_SW2 :
+{0x5007,0x00,0x01}, // CLMP_CTRL :
+{0x5009,0x00,0x01}, // CPUSLEEP_EN :
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN :
+{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL :
+{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT :
+{0x500E,0x06D0,0x02}, // SYSINT3_VDLY_1_1 :
+{0x5010,0x02F8,0x02}, // SYSINT3_VDLY_1_2 :
+{0x5012,0x0118,0x02}, // SYSINT3_VDLY_1_4 :
+{0x5014,0x0028,0x02}, // SYSINT3_VDLY_1_8 :
+{0x5016,0x0370,0x02}, // SYSINT3_VDLY_1_1_HD :
+{0x5018,0x0208,0x02}, // SYSINT3_VDLY_1_2_HD :
+{0x501A,0x00,0x01}, // SENS_REVERSE_CTRL :
+{0x501B,0x19,0x01}, // EEP_ADDRESS :
+{0x501C,0x5180,0x02}, // SRCCK :
+{0x501E,0x0001,0x02},
+
+{0x6E86,0x0000,0x02}, // IBYHUE1_POS1 :
+{0x6E88,0xFFF5,0x02}, // IRYHUE1_POS1 :
+{0x6E8A,0xFFF8,0x02}, // IBYHUE2_POS1 :
+{0x6E8C,0xFFF5,0x02}, // IRYHUE2_POS1 :
+{0x6E8E,0xFFF8,0x02}, // IBYHUE3_POS1 :
+{0x6E90,0xFFEE,0x02}, // IRYHUE3_POS1 :
+{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 :
+{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 :
+{0x6F26,0x4E,0x01}, // IRYGAIN1_POS1 :
+{0x6F27,0x50,0x01}, // IBYGAIN1_POS1 :
+{0x6F28,0x4E,0x01}, // IRYGAIN2_POS1 :
+{0x6F29,0x5A,0x01}, // IBYGAIN2_POS1 :
+{0x6F2A,0x50,0x01}, // IRYGAIN3_POS1 :
+{0x6F2B,0x5A,0x01}, // IBYGAIN3_POS1 :
+{0x6F2C,0x50,0x01}, // IRYGAIN4_POS1 :
+{0x6F2D,0x50,0x01}, // IBYGAIN4_POS1 :
+
+//ae
+{0x5E12,0x0000,0x02},
+{0x5E14,0x0000,0x02},
+{0x0294,0x03,0x01},
+
+//AWB
+{0x625F,0x35,0x01},//CAT_AWB_1
+{0x0282,0x05,0x01},//AWB_SN1
+//S, 5000, 3F, 8, // CPUEXT :
+
+
+{0x5021,0x00,0x01}, // PG_GAIN_SEL :
+{0x5022,0x01,0x01}, // PG_WIDTH_SEL :
+{0x5023,0x04,0x01}, // PG_MODE_SEL :
+{0x5024,0x0000,0x02}, // PG_LEVEL_SEL :
+{0x5026,0x00,0x01}, // PG_DATEN_OFF_SEL :
+{0x5020,0x01,0x01}, // PGSEL :
+
+};
+
+static const isx012_regset_t isx012_DTP_stop[] =
+{
+{0x01BC,0x57,0x01}, // Shading Gain off
+{0x5E00,0x00,0x01}, // Flicker off
+{0x6804,0x11F0,0x02}, // NORMR
+{0x6806,0x106F,0x02}, // NORMB
+{0x6808,0x014C,0x02}, // AWBPRER
+{0x680A,0x021E,0x02}, // AWBPREB
+{0x6818,0x00,0x01}, // REFERENCE SENSITIVITY RATIO OF SENSOR (R/G)
+{0x6819,0x00,0x01}, // REFERENCE SENSITIVITY RATIO OF SENSOR (B/G)
+{0x036B,0x80,0x01}, //
+{0x0377,0x80,0x01}, //
+{0x0383,0x80,0x01}, //
+{0x6C44,0x13,0x01}, // G_CTRL_SEL :
+{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 :
+{0x5005,0xBB,0x01}, // DM_SW1 :
+{0x5006,0x03,0x01}, // DM_SW2 :
+{0x0362,0x55,0x01}, //
+{0x6C0B,0x00,0x01}, // PICT_FLAG :
+{0x9800,0x40,0x01}, // LMT_WEIGHT_A :
+{0x9801,0x80,0x01}, // LMT_WEIGHT_B :
+{0x6C46,0x1C,0x01}, // MAIN_CONFIG1 :
+{0x6C47,0x0F,0x01}, // MAIN_CONFIG2 :
+{0x6C48,0x03,0x01}, // MAIN_CONFIG3 :
+{0x6C49,0xF5,0x01}, // MAIN_CONFIG4 :
+{0x6C4A,0x07,0x01}, // MAIN_CONFIG5 :
+{0x5001,0x04,0x01}, // MUTECNT :
+{0x5002,0x01,0x01}, // WDT_EN :
+{0x5003,0x04,0x01}, // Z1_SEL1 :
+{0x5004,0x00,0x01}, // Z1_SEL2 :
+{0x5005,0xBB,0x01}, // DM_SW1 :
+{0x5006,0x03,0x01}, // DM_SW2 :
+{0x5007,0x01,0x01}, // CLMP_CTRL :
+{0x5009,0x00,0x01}, // CPUSLEEP_EN :
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN :
+{0x500B,0x00,0x01}, // FAST_SHT_MODE_SEL :
+{0x500C,0x00FA,0x02}, // FAST_SHT_LIMIT_COUNT :
+{0x500E,0x06D0,0x02}, // SYSINT3_VDLY_1_1 :
+{0x5010,0x02F8,0x02}, // SYSINT3_VDLY_1_2 :
+{0x5012,0x0118,0x02}, // SYSINT3_VDLY_1_4 :
+{0x5014,0x0028,0x02}, // SYSINT3_VDLY_1_8 :
+{0x5016,0x0370,0x02}, // SYSINT3_VDLY_1_1_HD :
+{0x5018,0x0208,0x02}, // SYSINT3_VDLY_1_2_HD :
+{0x501A,0x00,0x01}, // SENS_REVERSE_CTRL :
+{0x501B,0x50,0x01}, // EEP_ADDRESS :
+{0x501C,0x5180,0x02}, // SRCCK :
+{0x501E,0x0001,0x02},
+{0x6E86,0x0000,0x02}, // IBYHUE1_POS1 :
+{0x6E88,0xFFF5,0x02}, // IRYHUE1_POS1 :
+{0x6E8A,0xFFF8,0x02}, // IBYHUE2_POS1 :
+{0x6E8C,0xFFF5,0x02}, // IRYHUE2_POS1 :
+{0x6E8E,0xFFF8,0x02}, // IBYHUE3_POS1 :
+{0x6E90,0xFFEE,0x02}, // IRYHUE3_POS1 :
+{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 :
+{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 :
+{0x6F26,0x4E,0x01}, // IRYGAIN1_POS1 :
+{0x6F27,0x50,0x01}, // IBYGAIN1_POS1 :
+{0x6F28,0x4E,0x01}, // IRYGAIN2_POS1 :
+{0x6F29,0x5A,0x01}, // IBYGAIN2_POS1 :
+{0x6F2A,0x50,0x01}, // IRYGAIN3_POS1 :
+{0x6F2B,0x5A,0x01}, // IBYGAIN3_POS1 :
+{0x6F2C,0x50,0x01}, // IRYGAIN4_POS1 :
+{0x6F2D,0x50,0x01}, // IBYGAIN4_POS1 :
+{0x5E12,0x014A,0x02}, //
+{0x5E14,0x000D,0x02}, //
+{0x0294,0x00,0x01}, //
+{0x625F,0x35,0x01}, // CAT_AWB_1
+{0x0282,0x20,0x01}, // AWB_SN1
+{0x5021,0x00,0x01}, // PG_GAIN_SEL :
+{0x5022,0x00,0x01}, // PG_WIDTH_SEL :
+{0x5023,0x00,0x01}, // PG_MODE_SEL :
+{0x5024,0x0000,0x02}, // PG_LEVEL_SEL :
+{0x5026,0x00,0x01}, // PG_DATEN_OFF_SEL :
+{0x5020,0x00,0x01}, // PGSEL :
+
+};
+
+static const isx012_regset_t isx012_Preview_Return[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+
+};
+
+static const isx012_regset_t isx012_Capture_Start[] =
+{
+ {0x008A,0x00,0x01}, //OUTFMT_CAP
+ {0x0084,0x00,0x01}, //SENSMODE_CAP
+ {0x0087,0x03,0x01}, //FPSTYPE_CAP
+ {0x0012,0x06,0x01}, //INTCLR0
+ {0x0081,0x02,0x01}, //MODESEL
+ {0x0082,0x01,0x01}, //MONI_REFRESH
+};
+#if 0
+static const isx012_regset_t isx012_Preview_Return[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+#endif
+
+static const isx012_regset_t isx012_fps_auto[] =
+{
+{0x0308,0x11,0x01}, /* AELINE_MONI_SN1_2 */
+{0x018E,0x0012,0x02}, /* VADJ_SENS_1_2 */
+};
+
+static const isx012_regset_t isx012_fps_7fix[] =
+{
+{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */
+{0x018E,0x0D59,0x02}, /* VADJ_SENS_1_2 */
+};
+
+static const isx012_regset_t isx012_fps_15fix[] =
+{
+{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */
+{0x018E,0x041C,0x02}, /* VADJ_SENS_1_2 */
+};
+
+static const isx012_regset_t isx012_fps_25fix[] =
+{
+{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */
+{0x018E,0x00E1,0x02}, /* VADJ_SENS_1_2 */
+};
+
+static const isx012_regset_t isx012_fps_30fix[] =
+{
+{0x0308,0x02,0x01}, /* AELINE_MONI_SN1_2 */
+{0x018E,0x0012,0x02}, /* VADJ_SENS_1_2 */
+};
+
+static const isx012_regset_t isx012_ae_lock[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_ae_unlock[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_awb_lock[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+static const isx012_regset_t isx012_awb_unlock[] =
+{
+{0x0282,0x20,0x01}, //AWB_SN1
+};
+
+
+static const isx012_regset_t ISX012_Shading_Nocal[] =
+{
+{0x01BC,0x50,0x01}, // CXC OFF SHD OFF
+{0xEB00,0x8282,0x02}, //valid_code
+{0xEB02,0xFE,0x01},
+{0xEB03,0x84,0x01},
+{0xEB04,0x3F,0x01},
+{0xEB05,0x01,0x01},
+{0xEB06,0x50,0x01},
+{0xEB07,0x08,0x01},
+{0xEB08,0x14,0x01},
+{0xEB09,0xFF,0x01},
+{0xEB0A,0x45,0x01},
+{0xEB0B,0x80,0x01},
+{0xEB0C,0x01,0x01},
+{0xEB0D,0x68,0x01},
+{0xEB0E,0x04,0x01},
+{0xEB0F,0x1A,0x01},
+{0xEB10,0x81,0x01},
+{0xEB11,0x86,0x01},
+{0xEB12,0x3F,0x01},
+{0xEB13,0xE1,0x01},
+{0xEB14,0x4F,0x01},
+{0xEB15,0x00,0x01},
+{0xEB16,0x14,0x01},
+{0xEB17,0x02,0x01},
+{0xEB18,0xC5,0x01},
+{0xEB19,0x7F,0x01},
+{0xEB1A,0x11,0x01},
+{0xEB1B,0x60,0x01},
+{0xEB1C,0x00,0x01},
+{0xEB1D,0x1A,0x01},
+{0xEB1E,0x81,0x01},
+{0xEB1F,0x46,0x01},
+{0xEB20,0xA0,0x01},
+{0xEB21,0x01,0x01},
+{0xEB22,0x48,0x01},
+{0xEB23,0x00,0x01},
+{0xEB24,0x12,0x01},
+{0xEB25,0x81,0x01},
+{0xEB26,0x05,0x01},
+{0xEB27,0x20,0x01},
+{0xEB28,0xF1,0x01},
+{0xEB29,0x4F,0x01},
+{0xEB2A,0x00,0x01},
+{0xEB2B,0x14,0x01},
+{0xEB2C,0x82,0x01},
+{0xEB2D,0x85,0x01},
+{0xEB2E,0x80,0x01},
+{0xEB2F,0x21,0x01},
+{0xEB30,0x60,0x01},
+{0xEB31,0x04,0x01},
+{0xEB32,0x12,0x01},
+{0xEB33,0x81,0x01},
+{0xEB34,0x84,0x01},
+{0xEB35,0xE0,0x01},
+{0xEB36,0x00,0x01},
+{0xEB37,0x28,0x01},
+{0xEB38,0x04,0x01},
+{0xEB39,0x0C,0x01},
+{0xEB3A,0x82,0x01},
+{0xEB3B,0x43,0x01},
+{0xEB3C,0x20,0x01},
+{0xEB3D,0x11,0x01},
+{0xEB3E,0x68,0x01},
+{0xEB3F,0x04,0x01},
+{0xEB40,0x1A,0x01},
+{0xEB41,0x82,0x01},
+{0xEB42,0x83,0x01},
+{0xEB43,0xE0,0x01},
+{0xEB44,0x00,0x01},
+{0xEB45,0x20,0x01},
+{0xEB46,0x00,0x01},
+{0xEB47,0x06,0x01},
+{0xEB48,0xFF,0x01},
+{0xEB49,0x41,0x01},
+{0xEB4A,0x80,0x01},
+{0xEB4B,0x10,0x01},
+{0xEB4C,0x30,0x01},
+{0xEB4D,0x08,0x01},
+{0xEB4E,0x14,0x01},
+{0xEB4F,0x02,0x01},
+{0xEB50,0x45,0x01},
+{0xEB51,0xC0,0x01},
+{0xEB52,0x10,0x01},
+{0xEB53,0x30,0x01},
+{0xEB54,0x04,0x01},
+{0xEB55,0x04,0x01},
+{0xEB56,0x01,0x01},
+{0xEB57,0xC0,0x01},
+{0xEB58,0x3F,0x01},
+{0xEB59,0x10,0x01},
+{0xEB5A,0x10,0x01},
+{0xEB5B,0x04,0x01},
+{0xEB5C,0x0A,0x01},
+{0xEB5D,0x80,0x01},
+{0xEB5E,0x03,0x01},
+{0xEB5F,0xE0,0x01},
+{0xEB60,0x10,0x01},
+{0xEB61,0x28,0x01},
+{0xEB62,0x04,0x01},
+{0xEB63,0x0A,0x01},
+{0xEB64,0x81,0x01},
+{0xEB65,0x01,0x01},
+{0xEB66,0x00,0x01},
+{0xEB67,0x10,0x01},
+{0xEB68,0x00,0x01},
+{0xEB69,0x04,0x01},
+{0xEB6A,0x04,0x01},
+{0xEB6B,0x01,0x01},
+{0xEB6C,0x42,0x01},
+{0xEB6D,0xE0,0x01},
+{0xEB6E,0x10,0x01},
+{0xEB6F,0x38,0x01},
+{0xEB70,0xFC,0x01},
+{0xEB71,0x0D,0x01},
+{0xEB72,0x7F,0x01},
+{0xEB73,0x43,0x01},
+{0xEB74,0x60,0x01},
+{0xEB75,0x00,0x01},
+{0xEB76,0x08,0x01},
+{0xEB77,0x08,0x01},
+{0xEB78,0x02,0x01},
+{0xEB79,0x81,0x01},
+{0xEB7A,0x41,0x01},
+{0xEB7B,0x80,0x01},
+{0xEB7C,0x10,0x01},
+{0xEB7D,0x30,0x01},
+{0xEB7E,0x04,0x01},
+{0xEB7F,0x0C,0x01},
+{0xEB80,0x01,0x01},
+{0xEB81,0x43,0x01},
+{0xEB82,0xC0,0x01},
+{0xEB83,0x20,0x01},
+{0xEB84,0x28,0x01},
+{0xEB85,0x08,0x01},
+{0xEB86,0x06,0x01},
+{0xEB87,0x02,0x01},
+{0xEB88,0xC2,0x01},
+{0xEB89,0xA0,0x01},
+{0xEB8A,0x30,0x01},
+{0xEB8B,0x30,0x01},
+{0xEB8C,0x0C,0x01},
+{0xEB8D,0x12,0x01},
+{0xEB8E,0x83,0x01},
+{0xEB8F,0x84,0x01},
+{0xEB90,0x00,0x01},
+{0xEB91,0x21,0x01},
+{0xEB92,0x40,0x01},
+{0xEB93,0x0C,0x01},
+{0xEB94,0x0C,0x01},
+{0xEB95,0x82,0x01},
+{0xEB96,0x03,0x01},
+{0xEB97,0xC1,0x01},
+{0xEB98,0x40,0x01},
+{0xEB99,0x40,0x01},
+{0xEB9A,0x08,0x01},
+{0xEB9B,0x10,0x01},
+{0xEB9C,0x03,0x01},
+{0xEB9D,0xC4,0x01},
+{0xEB9E,0x00,0x01},
+{0xEB9F,0x21,0x01},
+{0xEBA0,0x38,0x01},
+{0xEBA1,0x08,0x01},
+{0xEBA2,0x0E,0x01},
+{0xEBA3,0x82,0x01},
+{0xEBA4,0xC3,0x01},
+{0xEBA5,0x20,0x01},
+{0xEBA6,0x41,0x01},
+{0xEBA7,0x48,0x01},
+{0xEBA8,0x00,0x01},
+{0xEBA9,0x14,0x01},
+{0xEBAA,0x83,0x01},
+{0xEBAB,0x44,0x01},
+{0xEBAC,0x20,0x01},
+{0xEBAD,0x11,0x01},
+{0xEBAE,0x48,0x01},
+{0xEBAF,0x08,0x01},
+{0xEBB0,0x0E,0x01},
+{0xEBB1,0x82,0x01},
+{0xEBB2,0x83,0x01},
+{0xEBB3,0xE0,0x01},
+{0xEBB4,0x30,0x01},
+{0xEBB5,0x48,0x01},
+{0xEBB6,0x10,0x01},
+{0xEBB7,0x12,0x01},
+{0xEBB8,0x00,0x01},
+{0xEBB9,0xC5,0x01},
+{0xEBBA,0x20,0x01},
+{0xEBBB,0x11,0x01},
+{0xEBBC,0x48,0x01},
+{0xEBBD,0x04,0x01},
+{0xEBBE,0x12,0x01},
+{0xEBBF,0x04,0x01},
+{0xEBC0,0x3B,0x01},
+{0xEBC1,0xC1,0x01},
+{0xEBC2,0x1E,0x01},
+{0xEBC3,0xC8,0x01},
+{0xEBC4,0x0F,0x01},
+{0xEBC5,0xF8,0x01},
+{0xEBC6,0x02,0x01},
+{0xEBC7,0xBB,0x01},
+{0xEBC8,0x60,0x01},
+{0xEBC9,0x0F,0x01},
+{0xEBCA,0xB8,0x01},
+{0xEBCB,0x0F,0x01},
+{0xEBCC,0xEA,0x01},
+{0xEBCD,0x83,0x01},
+{0xEBCE,0x3A,0x01},
+{0xEBCF,0xC1,0x01},
+{0xEBD0,0x4E,0x01},
+{0xEBD1,0xB0,0x01},
+{0xEBD2,0x07,0x01},
+{0xEBD3,0xF2,0x01},
+{0xEBD4,0x03,0x01},
+{0xEBD5,0xBE,0x01},
+{0xEBD6,0xC0,0x01},
+{0xEBD7,0x2E,0x01},
+{0xEBD8,0xD8,0x01},
+{0xEBD9,0x03,0x01},
+{0xEBDA,0xEE,0x01},
+{0xEBDB,0x83,0x01},
+{0xEBDC,0xFA,0x01},
+{0xEBDD,0xA0,0x01},
+{0xEBDE,0x2E,0x01},
+{0xEBDF,0xB0,0x01},
+{0xEBE0,0x0B,0x01},
+{0xEBE1,0xEC,0x01},
+{0xEBE2,0x05,0x01},
+{0xEBE3,0xBD,0x01},
+{0xEBE4,0x60,0x01},
+{0xEBE5,0x2F,0x01},
+{0xEBE6,0xD0,0x01},
+{0xEBE7,0x07,0x01},
+{0xEBE8,0xEC,0x01},
+{0xEBE9,0x02,0x01},
+{0xEBEA,0xBC,0x01},
+{0xEBEB,0x40,0x01},
+{0xEBEC,0x2F,0x01},
+{0xEBED,0xD0,0x01},
+{0xEBEE,0x13,0x01},
+{0xEBEF,0xEE,0x01},
+{0xEBF0,0x84,0x01},
+{0xEBF1,0xBB,0x01},
+{0xEBF2,0x00,0x01},
+{0xEBF3,0x1F,0x01},
+{0xEBF4,0xC8,0x01},
+{0xEBF5,0xFF,0x01},
+{0xEBF6,0xEF,0x01},
+{0xEBF7,0x00,0x01},
+{0xEBF8,0x7D,0x01},
+{0xEBF9,0x60,0x01},
+{0xEBFA,0x2F,0x01},
+{0xEBFB,0xD0,0x01},
+{0xEBFC,0x0B,0x01},
+{0xEBFD,0xF4,0x01},
+{0xEBFE,0x85,0x01},
+{0xEBFF,0x7D,0x01},
+{0xEC00,0x61,0x01},
+{0xEC01,0x0F,0x01},
+{0xEC02,0xC0,0x01},
+{0xEC03,0xFF,0x01},
+{0xEC04,0xF7,0x01},
+{0xEC05,0x7F,0x01},
+{0xEC06,0x3D,0x01},
+{0xEC07,0x40,0x01},
+{0xEC08,0xFF,0x01},
+{0xEC09,0xDF,0x01},
+{0xEC0A,0x07,0x01},
+{0xEC0B,0xFA,0x01},
+{0xEC0C,0x81,0x01},
+{0xEC0D,0x3E,0x01},
+{0xEC0E,0x61,0x01},
+{0xEC0F,0x4F,0x01},
+{0xEC10,0xD8,0x01},
+{0xEC11,0x0B,0x01},
+{0xEC12,0xFC,0x01},
+{0xEC13,0xFE,0x01},
+{0xEC14,0x3D,0x01},
+{0xEC15,0xC0,0x01},
+{0xEC16,0xFF,0x01},
+{0xEC17,0xFF,0x01},
+{0xEC18,0x03,0x01},
+{0xEC19,0xFC,0x01},
+{0xEC1A,0x82,0x01},
+{0xEC1B,0xBE,0x01},
+{0xEC1C,0xA0,0x01},
+{0xEC1D,0x6F,0x01},
+{0xEC1E,0xF8,0x01},
+{0xEC1F,0x1B,0x01},
+{0xEC20,0xFE,0x01},
+{0xEC21,0x83,0x01},
+{0xEC22,0xBF,0x01},
+{0xEC23,0xE0,0x01},
+{0xEC24,0x0F,0x01},
+{0xEC25,0x10,0x01},
+{0xEC26,0x00,0x01},
+{0xEC27,0x00,0x01},
+{0xEC28,0x82,0x01},
+{0xEC29,0xC0,0x01},
+{0xEC2A,0x60,0x01},
+{0xEC2B,0x30,0x01},
+{0xEC2C,0x18,0x01},
+{0xEC2D,0x20,0x01},
+{0xEC2E,0x04,0x01},
+{0xEC2F,0x08,0x01},
+{0xEC30,0x81,0x01},
+{0xEC31,0x21,0x01},
+{0xEC32,0x30,0x01},
+{0xEC33,0x08,0x01},
+{0xEC34,0x08,0x01},
+{0xEC35,0x08,0x01},
+{0xEC36,0x82,0x01},
+{0xEC37,0x01,0x01},
+{0xEC38,0x81,0x01},
+{0xEC39,0x50,0x01},
+{0xEC3A,0x08,0x01},
+{0xEC3B,0x14,0x01},
+{0xEC3C,0x02,0x01},
+{0xEC3D,0x09,0x01},
+{0xEC3E,0x41,0x01},
+{0xEC3F,0x42,0x01},
+{0xEC40,0x70,0x01},
+{0xEC41,0x20,0x01},
+{0xEC42,0x0C,0x01},
+{0xEC43,0x06,0x01},
+{0xEC44,0x84,0x01},
+{0xEC45,0x42,0x01},
+{0xEC46,0xE1,0x01},
+{0xEC47,0x40,0x01},
+{0xEC48,0x38,0x01},
+{0xEC49,0x1C,0x01},
+{0xEC4A,0x0C,0x01},
+{0xEC4B,0x07,0x01},
+{0xEC4C,0x03,0x01},
+{0xEC4D,0xA2,0x01},
+{0xEC4E,0x80,0x01},
+{0xEC4F,0x28,0x01},
+{0xEC50,0x18,0x01},
+{0xEC51,0x10,0x01},
+{0xEC52,0x87,0x01},
+{0xEC53,0x43,0x01},
+{0xEC54,0x61,0x01},
+{0xEC55,0x41,0x01},
+{0xEC56,0x48,0x01},
+{0xEC57,0x14,0x01},
+{0xEC58,0x10,0x01},
+{0xEC59,0x07,0x01},
+{0xEC5A,0xC2,0x01},
+{0xEC5B,0x81,0x01},
+{0xEC5C,0x80,0x01},
+{0xEC5D,0x30,0x01},
+{0xEC5E,0x20,0x01},
+{0xEC5F,0x0C,0x01},
+{0xEC60,0x87,0x01},
+{0xEC61,0x83,0x01},
+{0xEC62,0xC1,0x01},
+{0xEC63,0x40,0x01},
+{0xEC64,0x38,0x01},
+{0xEC65,0x14,0x01},
+{0xEC66,0x0A,0x01},
+{0xEC67,0x07,0x01},
+{0xEC68,0xC3,0x01},
+{0xEC69,0xC1,0x01},
+{0xEC6A,0x70,0x01},
+{0xEC6B,0x30,0x01},
+{0xEC6C,0x20,0x01},
+{0xEC6D,0x0C,0x01},
+{0xEC6E,0x08,0x01},
+{0xEC6F,0xC3,0x01},
+{0xEC70,0xE1,0x01},
+{0xEC71,0x60,0x01},
+{0xEC72,0x30,0x01},
+{0xEC73,0x10,0x01},
+{0xEC74,0x0E,0x01},
+{0xEC75,0x85,0x01},
+{0xEC76,0xC2,0x01},
+{0xEC77,0xC1,0x01},
+{0xEC78,0x70,0x01},
+{0xEC79,0x30,0x01},
+{0xEC7A,0x1C,0x01},
+{0xEC7B,0x0C,0x01},
+
+//SHD1(from CO1)
+{0xED02,0xE6,0x01},
+{0xED03,0x61,0x01},
+{0xED04,0x92,0x01},
+{0xED05,0x7C,0x01},
+{0xED06,0xBE,0x01},
+{0xED07,0xB4,0x01},
+{0xED08,0x9E,0x01},
+{0xED09,0x2C,0x01},
+{0xED0A,0x75,0x01},
+{0xED0B,0x47,0x01},
+{0xED0C,0x49,0x01},
+{0xED0D,0xD7,0x01},
+{0xED0E,0x61,0x01},
+{0xED0F,0x12,0x01},
+{0xED10,0x76,0x01},
+{0xED11,0xA8,0x01},
+{0xED12,0x34,0x01},
+{0xED13,0x1E,0x01},
+{0xED14,0x31,0x01},
+{0xED15,0xA1,0x01},
+{0xED16,0xC7,0x01},
+{0xED17,0x4C,0x01},
+{0xED18,0xDE,0x01},
+{0xED19,0xC1,0x01},
+{0xED1A,0xD2,0x01},
+{0xED1B,0x77,0x01},
+{0xED1C,0x76,0x01},
+{0xED1D,0x94,0x01},
+{0xED1E,0x9C,0x01},
+{0xED1F,0x10,0x01},
+{0xED20,0xC9,0x01},
+{0xED21,0xC6,0x01},
+{0xED22,0x40,0x01},
+{0xED23,0xA2,0x01},
+{0xED24,0x99,0x01},
+{0xED25,0x8F,0x01},
+{0xED26,0x66,0x01},
+{0xED27,0xDC,0x01},
+{0xED28,0xF3,0x01},
+{0xED29,0x19,0x01},
+{0xED2A,0xFC,0x01},
+{0xED2B,0xB0,0x01},
+{0xED2C,0xA6,0x01},
+{0xED2D,0x41,0x01},
+{0xED2E,0xC1,0x01},
+{0xED2F,0x49,0x01},
+{0xED30,0x91,0x01},
+{0xED31,0x75,0x01},
+{0xED32,0x8C,0x01},
+{0xED33,0x74,0x01},
+{0xED34,0x1C,0x01},
+{0xED35,0x0B,0x01},
+{0xED36,0x91,0x01},
+{0xED37,0x86,0x01},
+{0xED38,0x3D,0x01},
+{0xED39,0x87,0x01},
+{0xED3A,0x39,0x01},
+{0xED3B,0x4E,0x01},
+{0xED3C,0x5C,0x01},
+{0xED3D,0x50,0x01},
+{0xED3E,0x83,0x01},
+{0xED3F,0x16,0x01},
+{0xED40,0xCF,0x01},
+{0xED41,0xBC,0x01},
+{0xED42,0x45,0x01},
+{0xED43,0x35,0x01},
+{0xED44,0x83,0x01},
+{0xED45,0x41,0x01},
+{0xED46,0xCE,0x01},
+{0xED47,0x67,0x01},
+{0xED48,0xE8,0x01},
+{0xED49,0x33,0x01},
+{0xED4A,0x1C,0x01},
+{0xED4B,0x16,0x01},
+{0xED4C,0xC1,0x01},
+{0xED4D,0x86,0x01},
+{0xED4E,0x3E,0x01},
+{0xED4F,0x83,0x01},
+{0xED50,0xC1,0x01},
+{0xED51,0x0D,0x01},
+{0xED52,0x57,0x01},
+{0xED53,0x02,0x01},
+{0xED54,0x23,0x01},
+{0xED55,0x14,0x01},
+{0xED56,0xAE,0x01},
+{0xED57,0xE4,0x01},
+{0xED58,0x44,0x01},
+{0xED59,0x2A,0x01},
+{0xED5A,0x43,0x01},
+{0xED5B,0xF9,0x01},
+{0xED5C,0xCA,0x01},
+{0xED5D,0x56,0x01},
+{0xED5E,0x0C,0x01},
+{0xED5F,0x03,0x01},
+{0xED60,0x98,0x01},
+{0xED61,0xE2,0x01},
+{0xED62,0xA8,0x01},
+{0xED63,0x26,0x01},
+{0xED64,0x41,0x01},
+{0xED65,0x9E,0x01},
+{0xED66,0xC1,0x01},
+{0xED67,0xCE,0x01},
+{0xED68,0x59,0x01},
+{0xED69,0x1C,0x01},
+{0xED6A,0xB3,0x01},
+{0xED6B,0x93,0x01},
+{0xED6C,0xA7,0x01},
+{0xED6D,0x74,0x01},
+{0xED6E,0x04,0x01},
+{0xED6F,0x25,0x01},
+{0xED70,0x13,0x01},
+{0xED71,0xD9,0x01},
+{0xED72,0xC8,0x01},
+{0xED73,0x47,0x01},
+{0xED74,0x54,0x01},
+{0xED75,0xD2,0x01},
+{0xED76,0x93,0x01},
+{0xED77,0xAA,0x01},
+{0xED78,0x98,0x01},
+{0xED79,0xE5,0x01},
+{0xED7A,0x32,0x01},
+{0xED7B,0x9A,0x01},
+{0xED7C,0x29,0x01},
+{0xED7D,0xCF,0x01},
+{0xED7E,0x64,0x01},
+{0xED7F,0x8E,0x01},
+{0xED80,0x73,0x01},
+{0xED81,0x95,0x01},
+{0xED82,0xBB,0x01},
+{0xED83,0xA4,0x01},
+{0xED84,0xA4,0x01},
+{0xED85,0x26,0x01},
+{0xED86,0x0A,0x01},
+{0xED87,0x59,0x01},
+{0xED88,0x08,0x01},
+{0xED89,0x40,0x01},
+{0xED8A,0x00,0x01},
+{0xED8B,0xC2,0x01},
+{0xED8C,0x10,0x01},
+{0xED8D,0x88,0x01},
+{0xED8E,0xB0,0x01},
+{0xED8F,0x84,0x01},
+{0xED90,0x27,0x01},
+{0xED91,0x59,0x01},
+{0xED92,0xF1,0x01},
+{0xED93,0x0B,0x01},
+{0xED94,0x64,0x01},
+{0xED95,0xA2,0x01},
+{0xED96,0x43,0x01},
+{0xED97,0x99,0x01},
+{0xED98,0xE4,0x01},
+{0xED99,0x68,0x01},
+{0xED9A,0x25,0x01},
+{0xED9B,0x2F,0x01},
+{0xED9C,0x2B,0x01},
+{0xED9D,0xB1,0x01},
+{0xED9E,0xC9,0x01},
+{0xED9F,0x42,0x01},
+{0xEDA0,0x18,0x01},
+{0xEDA1,0x32,0x01},
+{0xEDA2,0x90,0x01},
+{0xEDA3,0x80,0x01},
+{0xEDA4,0x3C,0x01},
+{0xEDA5,0x24,0x01},
+{0xEDA6,0x22,0x01},
+{0xEDA7,0x2F,0x01},
+{0xEDA8,0xF1,0x01},
+{0xEDA9,0x09,0x01},
+{0xEDAA,0x57,0x01},
+{0xEDAB,0x00,0x01},
+{0xEDAC,0x53,0x01},
+{0xEDAD,0x99,0x01},
+{0xEDAE,0xEA,0x01},
+{0xEDAF,0x90,0x01},
+{0xEDB0,0xC6,0x01},
+{0xEDB1,0x3B,0x01},
+{0xEDB2,0x6D,0x01},
+{0xEDB3,0x99,0x01},
+{0xEDB4,0x4C,0x01},
+{0xEDB5,0x50,0x01},
+{0xEDB6,0xA4,0x01},
+{0xEDB7,0x32,0x01},
+{0xEDB8,0x12,0x01},
+{0xEDB9,0x94,0x01},
+{0xEDBA,0x64,0x01},
+{0xEDBB,0xA4,0x01},
+{0xEDBC,0x23,0x01},
+{0xEDBD,0x25,0x01},
+{0xEDBE,0x71,0x01},
+{0xEDBF,0x49,0x01},
+{0xEDC0,0x51,0x01},
+{0xEDC1,0xB2,0x01},
+{0xEDC2,0x02,0x01},
+{0xEDC3,0x17,0x01},
+{0xEDC4,0xCD,0x01},
+{0xEDC5,0x98,0x01},
+{0xEDC6,0x86,0x01},
+{0xEDC7,0x3D,0x01},
+{0xEDC8,0xBC,0x01},
+{0xEDC9,0x01,0x01},
+{0xEDCA,0x50,0x01},
+{0xEDCB,0x63,0x01},
+{0xEDCC,0x80,0x01},
+{0xEDCD,0x63,0x01},
+{0xEDCE,0x16,0x01},
+{0xEDCF,0xC3,0x01},
+{0xEDD0,0x2C,0x01},
+{0xEDD1,0x25,0x01},
+{0xEDD2,0x2C,0x01},
+{0xEDD3,0x43,0x01},
+{0xEDD4,0xB1,0x01},
+{0xEDD5,0x4A,0x01},
+{0xEDD6,0x53,0x01},
+{0xEDD7,0xCC,0x01},
+{0xEDD8,0x82,0x01},
+{0xEDD9,0x96,0x01},
+{0xEDDA,0xC7,0x01},
+{0xEDDB,0x40,0x01},
+{0xEDDC,0xA6,0x01},
+{0xEDDD,0x39,0x01},
+{0xEDDE,0xBE,0x01},
+{0xEDDF,0x91,0x01},
+{0xEDE0,0xD0,0x01},
+{0xEDE1,0x75,0x01},
+{0xEDE2,0x54,0x01},
+{0xEDE3,0x34,0x01},
+{0xEDE4,0x1B,0x01},
+{0xEDE5,0xFC,0x01},
+{0xEDE6,0x4C,0x01},
+{0xEDE7,0x46,0x01},
+{0xEDE8,0x39,0x01},
+{0xEDE9,0x7D,0x01},
+{0xEDEA,0x71,0x01},
+{0xEDEB,0x8D,0x01},
+{0xEDEC,0x5D,0x01},
+{0xEDED,0x46,0x01},
+{0xEDEE,0xE3,0x01},
+{0xEDEF,0x17,0x01},
+{0xEDF0,0xD9,0x01},
+{0xEDF1,0x50,0x01},
+{0xEDF2,0x86,0x01},
+{0xEDF3,0x3A,0x01},
+{0xEDF4,0xB3,0x01},
+{0xEDF5,0x09,0x01},
+{0xEDF6,0x50,0x01},
+{0xEDF7,0x76,0x01},
+{0xEDF8,0x6A,0x01},
+{0xEDF9,0xF4,0x01},
+{0xEDFA,0x1E,0x01},
+{0xEDFB,0x25,0x01},
+{0xEDFC,0x61,0x01},
+{0xEDFD,0x67,0x01},
+{0xEDFE,0x45,0x01},
+{0xEDFF,0xC0,0x01},
+{0xEE00,0x69,0x01},
+{0xEE01,0xD0,0x01},
+{0xEE02,0x6B,0x01},
+{0xEE03,0xF6,0x01},
+{0xEE04,0x93,0x01},
+{0xEE05,0x9A,0x01},
+{0xEE06,0xFA,0x01},
+{0xEE07,0xB8,0x01},
+{0xEE08,0x26,0x01},
+{0xEE09,0x40,0x01},
+{0xEE0A,0xC0,0x01},
+{0xEE0B,0xB9,0x01},
+{0xEE0C,0xD0,0x01},
+{0xEE0D,0x75,0x01},
+{0xEE0E,0x6E,0x01},
+{0xEE0F,0xE4,0x01},
+{0xEE10,0x9E,0x01},
+{0xEE11,0x2D,0x01},
+{0xEE12,0xE1,0x01},
+{0xEE13,0xA7,0x01},
+{0xEE14,0x49,0x01},
+{0xEE15,0xFD,0x01},
+{0xEE16,0xB9,0x01},
+{0xEE17,0x52,0x01},
+{0xEE18,0x7C,0x01},
+{0xEE19,0x98,0x01},
+{0xEE1A,0x64,0x01},
+{0xEE1B,0x1E,0x01},
+{0xEE1C,0x22,0x01},
+{0xEE1D,0x89,0x01},
+{0xEE1E,0xA7,0x01},
+{0xEE1F,0x48,0x01},
+{0xEE20,0xE4,0x01},
+{0xEE21,0x49,0x01},
+{0xEE22,0x12,0x01},
+{0xEE23,0x7D,0x01},
+{0xEE24,0xB4,0x01},
+{0xEE25,0xB4,0x01},
+{0xEE26,0x1F,0x01},
+{0xEE27,0x31,0x01},
+{0xEE28,0xC5,0x01},
+{0xEE29,0x47,0x01},
+{0xEE2A,0x4B,0x01},
+{0xEE2B,0xC2,0x01},
+{0xEE2C,0x19,0x01},
+{0xEE2D,0x0F,0x01},
+{0xEE2E,0x73,0x01},
+{0xEE2F,0xE2,0x01},
+{0xEE30,0x13,0x01},
+{0xEE31,0x1C,0x01},
+{0xEE32,0xF5,0x01},
+{0xEE33,0xE0,0x01},
+{0xEE34,0xC6,0x01},
+{0xEE35,0x3B,0x01},
+{0xEE36,0xB6,0x01},
+{0xEE37,0xB1,0x01},
+{0xEE38,0xCE,0x01},
+{0xEE39,0x6D,0x01},
+{0xEE3A,0xB8,0x01},
+{0xEE3B,0xF3,0x01},
+{0xEE3C,0x9B,0x01},
+{0xEE3D,0xF2,0x01},
+{0xEE3E,0x18,0x01},
+{0xEE3F,0x27,0x01},
+{0xEE40,0x3D,0x01},
+{0xEE41,0xBF,0x01},
+{0xEE42,0xE9,0x01},
+{0xEE43,0xCE,0x01},
+{0xEE44,0x6E,0x01},
+{0xEE45,0xBA,0x01},
+{0xEE46,0x83,0x01},
+{0xEE47,0x9A,0x01},
+{0xEE48,0xE4,0x01},
+{0xEE49,0x50,0x01},
+{0xEE4A,0x66,0x01},
+{0xEE4B,0x36,0x01},
+{0xEE4C,0x8A,0x01},
+{0xEE4D,0x29,0x01},
+{0xEE4E,0x4D,0x01},
+{0xEE4F,0x61,0x01},
+{0xEE50,0x3A,0x01},
+{0xEE51,0xA3,0x01},
+{0xEE52,0x18,0x01},
+{0xEE53,0xD2,0x01},
+{0xEE54,0x50,0x01},
+{0xEE55,0x26,0x01},
+{0xEE56,0x36,0x01},
+{0xEE57,0xA8,0x01},
+{0xEE58,0x21,0x01},
+{0xEE59,0xCE,0x01},
+{0xEE5A,0x6E,0x01},
+{0xEE5B,0xB2,0x01},
+{0xEE5C,0x03,0x01},
+{0xEE5D,0x9A,0x01},
+{0xEE5E,0xE0,0x01},
+{0xEE5F,0x1C,0x01},
+{0xEE60,0x46,0x01},
+{0xEE61,0x34,0x01},
+{0xEE62,0x72,0x01},
+{0xEE63,0x41,0x01},
+{0xEE64,0x8C,0x01},
+{0xEE65,0x58,0x01},
+{0xEE66,0xE8,0x01},
+{0xEE67,0xC2,0x01},
+{0xEE68,0x95,0x01},
+{0xEE69,0xB5,0x01},
+{0xEE6A,0x88,0x01},
+{0xEE6B,0x65,0x01},
+{0xEE6C,0x2E,0x01},
+{0xEE6D,0x72,0x01},
+{0xEE6E,0x39,0x01},
+{0xEE6F,0x8C,0x01},
+{0xEE70,0x62,0x01},
+{0xEE71,0x48,0x01},
+{0xEE72,0x83,0x01},
+{0xEE73,0x1A,0x01},
+{0xEE74,0xE4,0x01},
+{0xEE75,0x28,0x01},
+{0xEE76,0x06,0x01},
+{0xEE77,0x35,0x01},
+{0xEE78,0x6A,0x01},
+{0xEE79,0xF9,0x01},
+{0xEE7A,0x4B,0x01},
+{0xEE7B,0x53,0x01},
+{0xEE7C,0xB8,0x01},
+{0xEE7D,0x92,0x01},
+{0xEE7E,0x13,0x01},
+{0xEE7F,0xA2,0x01},
+{0xEE80,0xCC,0x01},
+{0xEE81,0x64,0x01},
+{0xEE82,0x27,0x01},
+{0xEE83,0x3B,0x01},
+{0xEE84,0x29,0x01},
+{0xEE85,0x0A,0x01},
+{0xEE86,0x54,0x01},
+{0xEE87,0xBC,0x01},
+{0xEE88,0xF2,0x01},
+{0xEE89,0x96,0x01},
+{0xEE8A,0xC1,0x01},
+{0xEE8B,0x40,0x01},
+{0xEE8C,0xA6,0x01},
+{0xEE8D,0x35,0x01},
+{0xEE8E,0x7A,0x01},
+{0xEE8F,0xB1,0x01},
+{0xEE90,0x8C,0x01},
+{0xEE91,0x54,0x01},
+{0xEE92,0xC8,0x01},
+{0xEE93,0xF2,0x01},
+{0xEE94,0x92,0x01},
+{0xEE95,0x9D,0x01},
+{0xEE96,0x64,0x01},
+{0xEE97,0xE4,0x01},
+{0xEE98,0x23,0x01},
+{0xEE99,0x13,0x01},
+{0xEE9A,0xA9,0x01},
+{0xEE9B,0x48,0x01},
+{0xEE9C,0x47,0x01},
+{0xEE9D,0x40,0x01},
+{0xEE9E,0x42,0x01},
+{0xEE9F,0x13,0x01},
+{0xEEA0,0x9F,0x01},
+{0xEEA1,0x58,0x01},
+{0xEEA2,0xE5,0x01},
+{0xEEA3,0x2C,0x01},
+{0xEEA4,0x7F,0x01},
+{0xEEA5,0xD9,0x01},
+{0xEEA6,0x8C,0x01},
+{0xEEA7,0x5B,0x01},
+{0xEEA8,0x12,0x01},
+{0xEEA9,0x43,0x01},
+{0xEEAA,0x14,0x01},
+{0xEEAB,0xAA,0x01},
+{0xEEAC,0x80,0x01},
+{0xEEAD,0x04,0x01},
+{0xEEAE,0x25,0x01},
+{0xEEAF,0x06,0x01},
+{0xEEB0,0x51,0x01},
+{0xEEB1,0x08,0x01},
+{0xEEB2,0x40,0x01},
+{0xEEB3,0x00,0x01},
+{0xEEB4,0xB2,0x01},
+{0xEEB5,0x10,0x01},
+{0xEEB6,0x86,0x01},
+{0xEEB7,0x98,0x01},
+{0xEEB8,0x64,0x01},
+{0xEEB9,0x25,0x01},
+{0xEEBA,0x4A,0x01},
+{0xEEBB,0xB9,0x01},
+{0xEEBC,0x0A,0x01},
+{0xEEBD,0x5D,0x01},
+{0xEEBE,0x1C,0x01},
+{0xEEBF,0x13,0x01},
+{0xEEC0,0x97,0x01},
+{0xEEC1,0xC4,0x01},
+{0xEEC2,0x18,0x01},
+{0xEEC3,0x85,0x01},
+{0xEEC4,0x2A,0x01},
+{0xEEC5,0x21,0x01},
+{0xEEC6,0x41,0x01},
+{0xEEC7,0xC9,0x01},
+{0xEEC8,0x41,0x01},
+{0xEEC9,0x12,0x01},
+{0xEECA,0x02,0x01},
+{0xEECB,0x10,0x01},
+{0xEECC,0x80,0x01},
+{0xEECD,0x2C,0x01},
+{0xEECE,0x64,0x01},
+{0xEECF,0x21,0x01},
+{0xEED0,0x27,0x01},
+{0xEED1,0x61,0x01},
+{0xEED2,0xC9,0x01},
+{0xEED3,0x52,0x01},
+{0xEED4,0xB0,0x01},
+{0xEED5,0x42,0x01},
+{0xEED6,0x17,0x01},
+{0xEED7,0xC8,0x01},
+{0xEED8,0x04,0x01},
+{0xEED9,0xE6,0x01},
+{0xEEDA,0x32,0x01},
+{0xEEDB,0x58,0x01},
+{0xEEDC,0x29,0x01},
+{0xEEDD,0xCB,0x01},
+{0xEEDE,0x4C,0x01},
+{0xEEDF,0x74,0x01},
+{0xEEE0,0x92,0x01},
+{0xEEE1,0x91,0x01},
+{0xEEE2,0x8E,0x01},
+{0xEEE3,0x48,0x01},
+{0xEEE4,0x84,0x01},
+{0xEEE5,0x22,0x01},
+{0xEEE6,0x1D,0x01},
+{0xEEE7,0x01,0x01},
+{0xEEE8,0xC9,0x01},
+{0xEEE9,0x4D,0x01},
+{0xEEEA,0x7E,0x01},
+{0xEEEB,0x82,0x01},
+{0xEEEC,0x15,0x01},
+{0xEEED,0xB5,0x01},
+{0xEEEE,0x04,0x01},
+{0xEEEF,0xE6,0x01},
+{0xEEF0,0x33,0x01},
+{0xEEF1,0x99,0x01},
+{0xEEF2,0x69,0x01},
+{0xEEF3,0x0D,0x01},
+{0xEEF4,0x5D,0x01},
+{0xEEF5,0x06,0x01},
+{0xEEF6,0x33,0x01},
+{0xEEF7,0x15,0x01},
+{0xEEF8,0xAF,0x01},
+{0xEEF9,0xEC,0x01},
+{0xEEFA,0xA4,0x01},
+{0xEEFB,0x28,0x01},
+{0xEEFC,0x35,0x01},
+{0xEEFD,0xE9,0x01},
+{0xEEFE,0x09,0x01},
+{0xEEFF,0x4F,0x01},
+{0xEF00,0x8E,0x01},
+{0xEF01,0x02,0x01},
+{0xEF02,0x95,0x01},
+{0xEF03,0xB1,0x01},
+{0xEF04,0xC4,0x01},
+{0xEF05,0x25,0x01},
+{0xEF06,0x31,0x01},
+{0xEF07,0x94,0x01},
+{0xEF08,0xB1,0x01},
+{0xEF09,0x4D,0x01},
+{0xEF0A,0x6C,0x01},
+{0xEF0B,0x94,0x01},
+{0xEF0C,0x43,0x01},
+{0xEF0D,0x99,0x01},
+{0xEF0E,0xD4,0x01},
+{0xEF0F,0xEC,0x01},
+{0xEF10,0xC5,0x01},
+{0xEF11,0x31,0x01},
+{0xEF12,0x69,0x01},
+{0xEF13,0xC9,0x01},
+{0xEF14,0x0B,0x01},
+{0xEF15,0x58,0x01},
+{0xEF16,0xE6,0x01},
+{0xEF17,0x52,0x01},
+{0xEF18,0x16,0x01},
+{0xEF19,0xBE,0x01},
+{0xEF1A,0xD4,0x01},
+{0xEF1B,0x45,0x01},
+{0xEF1C,0x32,0x01},
+{0xEF1D,0x8E,0x01},
+{0xEF1E,0x79,0x01},
+{0xEF1F,0x4D,0x01},
+{0xEF20,0x6A,0x01},
+{0xEF21,0xA4,0x01},
+{0xEF22,0x83,0x01},
+{0xEF23,0x1C,0x01},
+{0xEF24,0xF2,0x01},
+{0xEF25,0xDC,0x01},
+{0xEF26,0x26,0x01},
+{0xEF27,0x3A,0x01},
+{0xEF28,0xA3,0x01},
+{0xEF29,0xE1,0x01},
+{0xEF2A,0x4D,0x01},
+{0xEF2B,0x65,0x01},
+{0xEF2C,0x5C,0x01},
+{0xEF2D,0xC3,0x01},
+{0xEF2E,0x98,0x01},
+{0xEF2F,0xD4,0x01},
+{0xEF30,0x3C,0x01},
+{0xEF31,0xE6,0x01},
+{0xEF32,0x35,0x01},
+{0xEF33,0x9D,0x01},
+{0xEF34,0x09,0x01},
+{0xEF35,0x8E,0x01},
+{0xEF36,0x6B,0x01},
+{0xEF37,0xAC,0x01},
+{0xEF38,0xE3,0x01},
+{0xEF39,0x9B,0x01},
+{0xEF3A,0xF4,0x01},
+{0xEF3B,0x34,0x01},
+{0xEF3C,0x07,0x01},
+{0xEF3D,0x3E,0x01},
+{0xEF3E,0xDA,0x01},
+{0xEF3F,0xC1,0x01},
+{0xEF40,0x8F,0x01},
+{0xEF41,0x74,0x01},
+{0xEF42,0xEA,0x01},
+{0xEF43,0x13,0x01},
+{0xEF44,0x9C,0x01},
+{0xEF45,0xF4,0x01},
+{0xEF46,0xF0,0x01},
+{0xEF47,0xA6,0x01},
+{0xEF48,0x3C,0x01},
+{0xEF49,0xC0,0x01},
+{0xEF4A,0x49,0x01},
+{0xEF4B,0x0F,0x01},
+{0xEF4C,0x72,0x01},
+{0xEF4D,0xEA,0x01},
+{0xEF4E,0xD3,0x01},
+{0xEF4F,0x9C,0x01},
+{0xEF50,0xFE,0x01},
+{0xEF51,0x04,0x01},
+{0xEF52,0xA7,0x01},
+{0xEF53,0x3D,0x01},
+
+//SHD2 CW+TL84 33:66
+
+{0xED00,0x9191,0x02},//
+{0xEF54,0x28,0x01},
+{0xEF55,0xC2,0x01},
+{0xEF56,0x11,0x01},
+{0xEF57,0x8C,0x01},
+{0xEF58,0x46,0x01},
+{0xEF59,0x34,0x01},
+{0xEF5A,0xA2,0x01},
+{0xEF5B,0x12,0x01},
+{0xEF5C,0xCD,0x01},
+{0xEF5D,0x08,0x01},
+{0xEF5E,0x47,0x01},
+{0xEF5F,0x27,0x01},
+{0xEF60,0xAA,0x01},
+{0xEF61,0x10,0x01},
+{0xEF62,0x7F,0x01},
+{0xEF63,0xC2,0x01},
+{0xEF64,0xF3,0x01},
+{0xEF65,0x1C,0x01},
+{0xEF66,0xE4,0x01},
+{0xEF67,0x40,0x01},
+{0xEF68,0x27,0x01},
+{0xEF69,0x3C,0x01},
+{0xEF6A,0xFB,0x01},
+{0xEF6B,0xA1,0x01},
+{0xEF6C,0x90,0x01},
+{0xEF6D,0x7C,0x01},
+{0xEF6E,0x92,0x01},
+{0xEF6F,0x63,0x01},
+{0xEF70,0x9A,0x01},
+{0xEF71,0xC5,0x01},
+{0xEF72,0x0C,0x01},
+{0xEF73,0x66,0x01},
+{0xEF74,0x31,0x01},
+{0xEF75,0xA4,0x01},
+{0xEF76,0x49,0x01},
+{0xEF77,0x0E,0x01},
+{0xEF78,0x7F,0x01},
+{0xEF79,0xA0,0x01},
+{0xEF7A,0xB3,0x01},
+{0xEF7B,0x19,0x01},
+{0xEF7C,0xB6,0x01},
+{0xEF7D,0x34,0x01},
+{0xEF7E,0x85,0x01},
+{0xEF7F,0x28,0x01},
+{0xEF80,0x4D,0x01},
+{0xEF81,0x61,0x01},
+{0xEF82,0x0B,0x01},
+{0xEF83,0x68,0x01},
+{0xEF84,0xB6,0x01},
+{0xEF85,0x73,0x01},
+{0xEF86,0x9B,0x01},
+{0xEF87,0xBB,0x01},
+{0xEF88,0x0C,0x01},
+{0xEF89,0x45,0x01},
+{0xEF8A,0x24,0x01},
+{0xEF8B,0x17,0x01},
+{0xEF8C,0x11,0x01},
+{0xEF8D,0x49,0x01},
+{0xEF8E,0x51,0x01},
+{0xEF8F,0xF4,0x01},
+{0xEF90,0xC2,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD4,0x01},
+{0xEF93,0x94,0x01},
+{0xEF94,0xC5,0x01},
+{0xEF95,0x25,0x01},
+{0xEF96,0x0B,0x01},
+{0xEF97,0x01,0x01},
+{0xEF98,0x48,0x01},
+{0xEF99,0x43,0x01},
+{0xEF9A,0x62,0x01},
+{0xEF9B,0x62,0x01},
+{0xEF9C,0x96,0x01},
+{0xEF9D,0xD5,0x01},
+{0xEF9E,0xA4,0x01},
+{0xEF9F,0xC6,0x01},
+{0xEFA0,0x2C,0x01},
+{0xEFA1,0x2F,0x01},
+{0xEFA2,0x51,0x01},
+{0xEFA3,0x48,0x01},
+{0xEFA4,0x40,0x01},
+{0xEFA5,0x1C,0x01},
+{0xEFA6,0x22,0x01},
+{0xEFA7,0x13,0x01},
+{0xEFA8,0xB4,0x01},
+{0xEFA9,0xC0,0x01},
+{0xEFAA,0x86,0x01},
+{0xEFAB,0x37,0x01},
+{0xEFAC,0x7B,0x01},
+{0xEFAD,0x29,0x01},
+{0xEFAE,0x8A,0x01},
+{0xEFAF,0x48,0x01},
+{0xEFB0,0x30,0x01},
+{0xEFB1,0x52,0x01},
+{0xEFB2,0x12,0x01},
+{0xEFB3,0xA4,0x01},
+{0xEFB4,0xF4,0x01},
+{0xEFB5,0x25,0x01},
+{0xEFB6,0x38,0x01},
+{0xEFB7,0xD9,0x01},
+{0xEFB8,0x01,0x01},
+{0xEFB9,0xCD,0x01},
+{0xEFBA,0x5B,0x01},
+{0xEFBB,0xA0,0x01},
+{0xEFBC,0x72,0x01},
+{0xEFBD,0x14,0x01},
+{0xEFBE,0xA9,0x01},
+{0xEFBF,0xCC,0x01},
+{0xEFC0,0xC5,0x01},
+{0xEFC1,0x34,0x01},
+{0xEFC2,0xE3,0x01},
+{0xEFC3,0xF1,0x01},
+{0xEFC4,0x0F,0x01},
+{0xEFC5,0x74,0x01},
+{0xEFC6,0x50,0x01},
+{0xEFC7,0xF3,0x01},
+{0xEFC8,0x98,0x01},
+{0xEFC9,0xC2,0x01},
+{0xEFCA,0x40,0x01},
+{0xEFCB,0x86,0x01},
+{0xEFCC,0x35,0x01},
+{0xEFCD,0xD4,0x01},
+{0xEFCE,0x29,0x01},
+{0xEFCF,0xD0,0x01},
+{0xEFD0,0x86,0x01},
+{0xEFD1,0xFE,0x01},
+{0xEFD2,0x23,0x01},
+{0xEFD3,0x9E,0x01},
+{0xEFD4,0xE8,0x01},
+{0xEFD5,0x28,0x01},
+{0xEFD6,0x87,0x01},
+{0xEFD7,0x3A,0x01},
+{0xEFD8,0xE7,0x01},
+{0xEFD9,0x21,0x01},
+{0xEFDA,0x10,0x01},
+{0xEFDB,0x89,0x01},
+{0xEFDC,0x3E,0x01},
+{0xEFDD,0x64,0x01},
+{0xEFDE,0xA2,0x01},
+{0xEFDF,0x0D,0x01},
+{0xEFE0,0x41,0x01},
+{0xEFE1,0xC8,0x01},
+{0xEFE2,0x41,0x01},
+{0xEFE3,0x14,0x01},
+{0xEFE4,0x02,0x01},
+{0xEFE5,0x11,0x01},
+{0xEFE6,0x8A,0x01},
+{0xEFE7,0x4C,0x01},
+{0xEFE8,0x04,0x01},
+{0xEFE9,0x00,0x01},
+{0xEFEA,0x00,0x01},
+{0xEFEB,0x00,0x01},
+{0xEFEC,0x00,0x01},
+{0xEFED,0x00,0x01},
+
+
+//SHD3 D65+TL84 C01//
+{0xED00,0x9191,0x02},//
+{0xEFEE,0x12,0x01},
+{0xEFEF,0x42,0x01},
+{0xEFF0,0x51,0x01},
+{0xEFF1,0x89,0x01},
+{0xEFF2,0x38,0x01},
+{0xEFF3,0xD4,0x01},
+{0xEFF4,0x21,0x01},
+{0xEFF5,0x10,0x01},
+{0xEFF6,0xAD,0x01},
+{0xEFF7,0xA8,0x01},
+{0xEFF8,0x45,0x01},
+{0xEFF9,0x18,0x01},
+{0xEFFA,0x4A,0x01},
+{0xEFFB,0x50,0x01},
+{0xEFFC,0x7D,0x01},
+{0xEFFD,0xBA,0x01},
+{0xEFFE,0xD3,0x01},
+{0xEFFF,0x1C,0x01},
+{0xF000,0xE4,0x01},
+{0xF001,0x40,0x01},
+{0xF002,0x27,0x01},
+{0xF003,0x3C,0x01},
+{0xF004,0xF8,0x01},
+{0xF005,0x69,0x01},
+{0xF006,0x10,0x01},
+{0xF007,0x7B,0x01},
+{0xF008,0x8E,0x01},
+{0xF009,0x63,0x01},
+{0xF00A,0x1A,0x01},
+{0xF00B,0xC6,0x01},
+{0xF00C,0x10,0x01},
+{0xF00D,0xA6,0x01},
+{0xF00E,0x31,0x01},
+{0xF00F,0xA6,0x01},
+{0xF010,0x59,0x01},
+{0xF011,0x8E,0x01},
+{0xF012,0x7E,0x01},
+{0xF013,0x9A,0x01},
+{0xF014,0xB3,0x01},
+{0xF015,0x19,0x01},
+{0xF016,0xB6,0x01},
+{0xF017,0x38,0x01},
+{0xF018,0xA5,0x01},
+{0xF019,0x28,0x01},
+{0xF01A,0x4F,0x01},
+{0xF01B,0x79,0x01},
+{0xF01C,0xCB,0x01},
+{0xF01D,0x68,0x01},
+{0xF01E,0xBA,0x01},
+{0xF01F,0x53,0x01},
+{0xF020,0x9B,0x01},
+{0xF021,0xBB,0x01},
+{0xF022,0x0C,0x01},
+{0xF023,0x65,0x01},
+{0xF024,0x24,0x01},
+{0xF025,0x17,0x01},
+{0xF026,0x21,0x01},
+{0xF027,0xC9,0x01},
+{0xF028,0x51,0x01},
+{0xF029,0xFC,0x01},
+{0xF02A,0xF2,0x01},
+{0xF02B,0x9B,0x01},
+{0xF02C,0xD3,0x01},
+{0xF02D,0x94,0x01},
+{0xF02E,0xC5,0x01},
+{0xF02F,0x25,0x01},
+{0xF030,0x0A,0x01},
+{0xF031,0x01,0x01},
+{0xF032,0x48,0x01},
+{0xF033,0x43,0x01},
+{0xF034,0x66,0x01},
+{0xF035,0x92,0x01},
+{0xF036,0x96,0x01},
+{0xF037,0xD7,0x01},
+{0xF038,0xA0,0x01},
+{0xF039,0xE6,0x01},
+{0xF03A,0x2C,0x01},
+{0xF03B,0x2F,0x01},
+{0xF03C,0x51,0x01},
+{0xF03D,0x48,0x01},
+{0xF03E,0x40,0x01},
+{0xF03F,0x1E,0x01},
+{0xF040,0x42,0x01},
+{0xF041,0x93,0x01},
+{0xF042,0xB5,0x01},
+{0xF043,0xCC,0x01},
+{0xF044,0x46,0x01},
+{0xF045,0x37,0x01},
+{0xF046,0x7C,0x01},
+{0xF047,0x29,0x01},
+{0xF048,0x8A,0x01},
+{0xF049,0x48,0x01},
+{0xF04A,0x32,0x01},
+{0xF04B,0x72,0x01},
+{0xF04C,0x12,0x01},
+{0xF04D,0xA5,0x01},
+{0xF04E,0x00,0x01},
+{0xF04F,0xA6,0x01},
+{0xF050,0x38,0x01},
+{0xF051,0xD7,0x01},
+{0xF052,0x01,0x01},
+{0xF053,0x0D,0x01},
+{0xF054,0x5C,0x01},
+{0xF055,0xA2,0x01},
+{0xF056,0x82,0x01},
+{0xF057,0x94,0x01},
+{0xF058,0xAA,0x01},
+{0xF059,0xD8,0x01},
+{0xF05A,0x45,0x01},
+{0xF05B,0x35,0x01},
+{0xF05C,0xE5,0x01},
+{0xF05D,0xC9,0x01},
+{0xF05E,0xCF,0x01},
+{0xF05F,0x73,0x01},
+{0xF060,0x50,0x01},
+{0xF061,0x03,0x01},
+{0xF062,0x99,0x01},
+{0xF063,0xC3,0x01},
+{0xF064,0x4C,0x01},
+{0xF065,0xE6,0x01},
+{0xF066,0x35,0x01},
+{0xF067,0xD7,0x01},
+{0xF068,0x21,0x01},
+{0xF069,0x10,0x01},
+{0xF06A,0x84,0x01},
+{0xF06B,0xF2,0x01},
+{0xF06C,0x03,0x01},
+{0xF06D,0x9E,0x01},
+{0xF06E,0xE8,0x01},
+{0xF06F,0x2C,0x01},
+{0xF070,0xA7,0x01},
+{0xF071,0x3A,0x01},
+{0xF072,0xE8,0x01},
+{0xF073,0x11,0x01},
+{0xF074,0x90,0x01},
+{0xF075,0x87,0x01},
+{0xF076,0x18,0x01},
+{0xF077,0x94,0x01},
+{0xF078,0x21,0x01},
+{0xF079,0x09,0x01},
+{0xF07A,0x2D,0x01},
+{0xF07B,0x68,0x01},
+{0xF07C,0x41,0x01},
+{0xF07D,0x11,0x01},
+{0xF07E,0xDA,0x01},
+{0xF07F,0x10,0x01},
+{0xF080,0x88,0x01},
+{0xF081,0x2A,0x01},
+{0xF082,0x04,0x01},
+{0xF083,0x00,0x01},
+{0xF084,0x00,0x01},
+{0xF085,0x00,0x01},
+{0xF086,0x00,0x01},
+{0xF087,0x00,0x01},
+{0xF088,0xBE,0x01},
+{0xF089,0x51,0x01},
+{0xF08A,0x4E,0x01},
+{0xF08B,0x6F,0x01},
+{0xF08C,0x6C,0x01},
+{0xF08D,0x43,0x01},
+{0xF08E,0x1B,0x01},
+{0xF08F,0xDA,0x01},
+{0xF090,0xEC,0x01},
+{0xF091,0x46,0x01},
+{0xF092,0x38,0x01},
+{0xF093,0xBB,0x01},
+{0xF094,0xC1,0x01},
+{0xF095,0xCD,0x01},
+{0xF096,0x69,0x01},
+{0xF097,0x26,0x01},
+{0xF098,0x93,0x01},
+{0xF099,0x98,0x01},
+{0xF09A,0xC1,0x01},
+{0xF09B,0x20,0x01},
+{0xF09C,0x26,0x01},
+{0xF09D,0x32,0x01},
+{0xF09E,0xA5,0x01},
+{0xF09F,0xB1,0x01},
+{0xF0A0,0x8D,0x01},
+{0xF0A1,0x67,0x01},
+{0xF0A2,0x0E,0x01},
+{0xF0A3,0x23,0x01},
+{0xF0A4,0x97,0x01},
+{0xF0A5,0xB0,0x01},
+{0xF0A6,0x6C,0x01},
+{0xF0A7,0x25,0x01},
+{0xF0A8,0x2C,0x01},
+{0xF0A9,0x71,0x01},
+{0xF0AA,0x41,0x01},
+{0xF0AB,0x0C,0x01},
+{0xF0AC,0x69,0x01},
+{0xF0AD,0x14,0x01},
+{0xF0AE,0xB3,0x01},
+{0xF0AF,0x96,0x01},
+{0xF0B0,0xA6,0x01},
+{0xF0B1,0xE8,0x01},
+{0xF0B2,0x64,0x01},
+{0xF0B3,0x26,0x01},
+{0xF0B4,0x3A,0x01},
+{0xF0B5,0x79,0x01},
+{0xF0B6,0x4A,0x01},
+{0xF0B7,0x5B,0x01},
+{0xF0B8,0x18,0x01},
+{0xF0B9,0xA3,0x01},
+{0xF0BA,0x97,0x01},
+{0xF0BB,0xA9,0x01},
+{0xF0BC,0xBC,0x01},
+{0xF0BD,0x24,0x01},
+{0xF0BE,0x23,0x01},
+{0xF0BF,0x13,0x01},
+{0xF0C0,0xE1,0x01},
+{0xF0C1,0xC8,0x01},
+{0xF0C2,0x4C,0x01},
+{0xF0C3,0xAA,0x01},
+{0xF0C4,0xA2,0x01},
+{0xF0C5,0x97,0x01},
+{0xF0C6,0xB6,0x01},
+{0xF0C7,0x14,0x01},
+{0xF0C8,0x05,0x01},
+{0xF0C9,0x24,0x01},
+{0xF0CA,0x06,0x01},
+{0xF0CB,0x09,0x01},
+{0xF0CC,0xC8,0x01},
+{0xF0CD,0x42,0x01},
+{0xF0CE,0x48,0x01},
+{0xF0CF,0x82,0x01},
+{0xF0D0,0x14,0x01},
+{0xF0D1,0xB8,0x01},
+{0xF0D2,0xC0,0x01},
+{0xF0D3,0xE5,0x01},
+{0xF0D4,0x28,0x01},
+{0xF0D5,0x21,0x01},
+{0xF0D6,0x39,0x01},
+{0xF0D7,0x08,0x01},
+{0xF0D8,0x40,0x01},
+{0xF0D9,0x14,0x01},
+{0xF0DA,0x62,0x01},
+{0xF0DB,0x92,0x01},
+{0xF0DC,0xA4,0x01},
+{0xF0DD,0xC4,0x01},
+{0xF0DE,0x05,0x01},
+{0xF0DF,0x30,0x01},
+{0xF0E0,0x58,0x01},
+{0xF0E1,0xA1,0x01},
+{0xF0E2,0x49,0x01},
+{0xF0E3,0x46,0x01},
+{0xF0E4,0x22,0x01},
+{0xF0E5,0xB2,0x01},
+{0xF0E6,0x91,0x01},
+{0xF0E7,0x9A,0x01},
+{0xF0E8,0x58,0x01},
+{0xF0E9,0xA5,0x01},
+{0xF0EA,0x2F,0x01},
+{0xF0EB,0x96,0x01},
+{0xF0EC,0x99,0x01},
+{0xF0ED,0x8B,0x01},
+{0xF0EE,0x54,0x01},
+{0xF0EF,0x74,0x01},
+{0xF0F0,0x32,0x01},
+{0xF0F1,0x13,0x01},
+{0xF0F2,0x9D,0x01},
+{0xF0F3,0x38,0x01},
+{0xF0F4,0xC5,0x01},
+{0xF0F5,0x2D,0x01},
+{0xF0F6,0x90,0x01},
+{0xF0F7,0x59,0x01},
+{0xF0F8,0x4D,0x01},
+{0xF0F9,0x64,0x01},
+{0xF0FA,0xEE,0x01},
+{0xF0FB,0x62,0x01},
+{0xF0FC,0x16,0x01},
+{0xF0FD,0xAE,0x01},
+{0xF0FE,0x84,0x01},
+{0xF0FF,0x25,0x01},
+{0xF100,0x2E,0x01},
+{0xF101,0x8B,0x01},
+{0xF102,0x31,0x01},
+{0xF103,0xCD,0x01},
+{0xF104,0x6F,0x01},
+{0xF105,0x60,0x01},
+{0xF106,0xC3,0x01},
+{0xF107,0x19,0x01},
+{0xF108,0xC7,0x01},
+{0xF109,0x14,0x01},
+{0xF10A,0x26,0x01},
+{0xF10B,0x31,0x01},
+{0xF10C,0x97,0x01},
+{0xF10D,0x41,0x01},
+{0xF10E,0x8D,0x01},
+{0xF10F,0x6D,0x01},
+{0xF110,0x86,0x01},
+{0xF111,0xE3,0x01},
+{0xF112,0x9C,0x01},
+{0xF113,0xE2,0x01},
+{0xF114,0xD8,0x01},
+{0xF115,0x06,0x01},
+{0xF116,0x36,0x01},
+{0xF117,0xB5,0x01},
+{0xF118,0xE9,0x01},
+{0xF119,0x4D,0x01},
+{0xF11A,0x70,0x01},
+{0xF11B,0x68,0x01},
+{0xF11C,0x03,0x01},
+{0xF11D,0x00,0x01},
+{0xF11E,0x00,0x01},
+{0xF11F,0x00,0x01},
+{0xF120,0x00,0x01},
+{0xF121,0x00,0x01},
+
+
+//SHD TH
+{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2
+{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2
+{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2
+{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2
+{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB
+{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB
+{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB
+{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB
+
+//PreWB_offset (for SHD2)
+{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 :
+//PreWB_offset (for SHD3)
+{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB :
+{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB :
+
+// CXC/SHD EN
+{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF
+};
+
+static const isx012_regset_t ISX012_Shading_0[] =
+{
+{0x01BC,0x50,0x01}, // CXC OFF SHD OFF
+{0xEB00,0x8282,0x02}, //valid_code
+{0xEB02,0xFE,0x01},
+{0xEB03,0x84,0x01},
+{0xEB04,0x3F,0x01},
+{0xEB05,0x01,0x01},
+{0xEB06,0x50,0x01},
+{0xEB07,0x08,0x01},
+{0xEB08,0x14,0x01},
+{0xEB09,0xFF,0x01},
+{0xEB0A,0x45,0x01},
+{0xEB0B,0x80,0x01},
+{0xEB0C,0x01,0x01},
+{0xEB0D,0x68,0x01},
+{0xEB0E,0x04,0x01},
+{0xEB0F,0x1A,0x01},
+{0xEB10,0x81,0x01},
+{0xEB11,0x86,0x01},
+{0xEB12,0x3F,0x01},
+{0xEB13,0xE1,0x01},
+{0xEB14,0x4F,0x01},
+{0xEB15,0x00,0x01},
+{0xEB16,0x14,0x01},
+{0xEB17,0x02,0x01},
+{0xEB18,0xC5,0x01},
+{0xEB19,0x7F,0x01},
+{0xEB1A,0x11,0x01},
+{0xEB1B,0x60,0x01},
+{0xEB1C,0x00,0x01},
+{0xEB1D,0x1A,0x01},
+{0xEB1E,0x81,0x01},
+{0xEB1F,0x46,0x01},
+{0xEB20,0xA0,0x01},
+{0xEB21,0x01,0x01},
+{0xEB22,0x48,0x01},
+{0xEB23,0x00,0x01},
+{0xEB24,0x12,0x01},
+{0xEB25,0x81,0x01},
+{0xEB26,0x05,0x01},
+{0xEB27,0x20,0x01},
+{0xEB28,0xF1,0x01},
+{0xEB29,0x4F,0x01},
+{0xEB2A,0x00,0x01},
+{0xEB2B,0x14,0x01},
+{0xEB2C,0x82,0x01},
+{0xEB2D,0x85,0x01},
+{0xEB2E,0x80,0x01},
+{0xEB2F,0x21,0x01},
+{0xEB30,0x60,0x01},
+{0xEB31,0x04,0x01},
+{0xEB32,0x12,0x01},
+{0xEB33,0x81,0x01},
+{0xEB34,0x84,0x01},
+{0xEB35,0xE0,0x01},
+{0xEB36,0x00,0x01},
+{0xEB37,0x28,0x01},
+{0xEB38,0x04,0x01},
+{0xEB39,0x0C,0x01},
+{0xEB3A,0x82,0x01},
+{0xEB3B,0x43,0x01},
+{0xEB3C,0x20,0x01},
+{0xEB3D,0x11,0x01},
+{0xEB3E,0x68,0x01},
+{0xEB3F,0x04,0x01},
+{0xEB40,0x1A,0x01},
+{0xEB41,0x82,0x01},
+{0xEB42,0x83,0x01},
+{0xEB43,0xE0,0x01},
+{0xEB44,0x00,0x01},
+{0xEB45,0x20,0x01},
+{0xEB46,0x00,0x01},
+{0xEB47,0x06,0x01},
+{0xEB48,0xFF,0x01},
+{0xEB49,0x41,0x01},
+{0xEB4A,0x80,0x01},
+{0xEB4B,0x10,0x01},
+{0xEB4C,0x30,0x01},
+{0xEB4D,0x08,0x01},
+{0xEB4E,0x14,0x01},
+{0xEB4F,0x02,0x01},
+{0xEB50,0x45,0x01},
+{0xEB51,0xC0,0x01},
+{0xEB52,0x10,0x01},
+{0xEB53,0x30,0x01},
+{0xEB54,0x04,0x01},
+{0xEB55,0x04,0x01},
+{0xEB56,0x01,0x01},
+{0xEB57,0xC0,0x01},
+{0xEB58,0x3F,0x01},
+{0xEB59,0x10,0x01},
+{0xEB5A,0x10,0x01},
+{0xEB5B,0x04,0x01},
+{0xEB5C,0x0A,0x01},
+{0xEB5D,0x80,0x01},
+{0xEB5E,0x03,0x01},
+{0xEB5F,0xE0,0x01},
+{0xEB60,0x10,0x01},
+{0xEB61,0x28,0x01},
+{0xEB62,0x04,0x01},
+{0xEB63,0x0A,0x01},
+{0xEB64,0x81,0x01},
+{0xEB65,0x01,0x01},
+{0xEB66,0x00,0x01},
+{0xEB67,0x10,0x01},
+{0xEB68,0x00,0x01},
+{0xEB69,0x04,0x01},
+{0xEB6A,0x04,0x01},
+{0xEB6B,0x01,0x01},
+{0xEB6C,0x42,0x01},
+{0xEB6D,0xE0,0x01},
+{0xEB6E,0x10,0x01},
+{0xEB6F,0x38,0x01},
+{0xEB70,0xFC,0x01},
+{0xEB71,0x0D,0x01},
+{0xEB72,0x7F,0x01},
+{0xEB73,0x43,0x01},
+{0xEB74,0x60,0x01},
+{0xEB75,0x00,0x01},
+{0xEB76,0x08,0x01},
+{0xEB77,0x08,0x01},
+{0xEB78,0x02,0x01},
+{0xEB79,0x81,0x01},
+{0xEB7A,0x41,0x01},
+{0xEB7B,0x80,0x01},
+{0xEB7C,0x10,0x01},
+{0xEB7D,0x30,0x01},
+{0xEB7E,0x04,0x01},
+{0xEB7F,0x0C,0x01},
+{0xEB80,0x01,0x01},
+{0xEB81,0x43,0x01},
+{0xEB82,0xC0,0x01},
+{0xEB83,0x20,0x01},
+{0xEB84,0x28,0x01},
+{0xEB85,0x08,0x01},
+{0xEB86,0x06,0x01},
+{0xEB87,0x02,0x01},
+{0xEB88,0xC2,0x01},
+{0xEB89,0xA0,0x01},
+{0xEB8A,0x30,0x01},
+{0xEB8B,0x30,0x01},
+{0xEB8C,0x0C,0x01},
+{0xEB8D,0x12,0x01},
+{0xEB8E,0x83,0x01},
+{0xEB8F,0x84,0x01},
+{0xEB90,0x00,0x01},
+{0xEB91,0x21,0x01},
+{0xEB92,0x40,0x01},
+{0xEB93,0x0C,0x01},
+{0xEB94,0x0C,0x01},
+{0xEB95,0x82,0x01},
+{0xEB96,0x03,0x01},
+{0xEB97,0xC1,0x01},
+{0xEB98,0x40,0x01},
+{0xEB99,0x40,0x01},
+{0xEB9A,0x08,0x01},
+{0xEB9B,0x10,0x01},
+{0xEB9C,0x03,0x01},
+{0xEB9D,0xC4,0x01},
+{0xEB9E,0x00,0x01},
+{0xEB9F,0x21,0x01},
+{0xEBA0,0x38,0x01},
+{0xEBA1,0x08,0x01},
+{0xEBA2,0x0E,0x01},
+{0xEBA3,0x82,0x01},
+{0xEBA4,0xC3,0x01},
+{0xEBA5,0x20,0x01},
+{0xEBA6,0x41,0x01},
+{0xEBA7,0x48,0x01},
+{0xEBA8,0x00,0x01},
+{0xEBA9,0x14,0x01},
+{0xEBAA,0x83,0x01},
+{0xEBAB,0x44,0x01},
+{0xEBAC,0x20,0x01},
+{0xEBAD,0x11,0x01},
+{0xEBAE,0x48,0x01},
+{0xEBAF,0x08,0x01},
+{0xEBB0,0x0E,0x01},
+{0xEBB1,0x82,0x01},
+{0xEBB2,0x83,0x01},
+{0xEBB3,0xE0,0x01},
+{0xEBB4,0x30,0x01},
+{0xEBB5,0x48,0x01},
+{0xEBB6,0x10,0x01},
+{0xEBB7,0x12,0x01},
+{0xEBB8,0x00,0x01},
+{0xEBB9,0xC5,0x01},
+{0xEBBA,0x20,0x01},
+{0xEBBB,0x11,0x01},
+{0xEBBC,0x48,0x01},
+{0xEBBD,0x04,0x01},
+{0xEBBE,0x12,0x01},
+{0xEBBF,0x04,0x01},
+{0xEBC0,0x3B,0x01},
+{0xEBC1,0xC1,0x01},
+{0xEBC2,0x1E,0x01},
+{0xEBC3,0xC8,0x01},
+{0xEBC4,0x0F,0x01},
+{0xEBC5,0xF8,0x01},
+{0xEBC6,0x02,0x01},
+{0xEBC7,0xBB,0x01},
+{0xEBC8,0x60,0x01},
+{0xEBC9,0x0F,0x01},
+{0xEBCA,0xB8,0x01},
+{0xEBCB,0x0F,0x01},
+{0xEBCC,0xEA,0x01},
+{0xEBCD,0x83,0x01},
+{0xEBCE,0x3A,0x01},
+{0xEBCF,0xC1,0x01},
+{0xEBD0,0x4E,0x01},
+{0xEBD1,0xB0,0x01},
+{0xEBD2,0x07,0x01},
+{0xEBD3,0xF2,0x01},
+{0xEBD4,0x03,0x01},
+{0xEBD5,0xBE,0x01},
+{0xEBD6,0xC0,0x01},
+{0xEBD7,0x2E,0x01},
+{0xEBD8,0xD8,0x01},
+{0xEBD9,0x03,0x01},
+{0xEBDA,0xEE,0x01},
+{0xEBDB,0x83,0x01},
+{0xEBDC,0xFA,0x01},
+{0xEBDD,0xA0,0x01},
+{0xEBDE,0x2E,0x01},
+{0xEBDF,0xB0,0x01},
+{0xEBE0,0x0B,0x01},
+{0xEBE1,0xEC,0x01},
+{0xEBE2,0x05,0x01},
+{0xEBE3,0xBD,0x01},
+{0xEBE4,0x60,0x01},
+{0xEBE5,0x2F,0x01},
+{0xEBE6,0xD0,0x01},
+{0xEBE7,0x07,0x01},
+{0xEBE8,0xEC,0x01},
+{0xEBE9,0x02,0x01},
+{0xEBEA,0xBC,0x01},
+{0xEBEB,0x40,0x01},
+{0xEBEC,0x2F,0x01},
+{0xEBED,0xD0,0x01},
+{0xEBEE,0x13,0x01},
+{0xEBEF,0xEE,0x01},
+{0xEBF0,0x84,0x01},
+{0xEBF1,0xBB,0x01},
+{0xEBF2,0x00,0x01},
+{0xEBF3,0x1F,0x01},
+{0xEBF4,0xC8,0x01},
+{0xEBF5,0xFF,0x01},
+{0xEBF6,0xEF,0x01},
+{0xEBF7,0x00,0x01},
+{0xEBF8,0x7D,0x01},
+{0xEBF9,0x60,0x01},
+{0xEBFA,0x2F,0x01},
+{0xEBFB,0xD0,0x01},
+{0xEBFC,0x0B,0x01},
+{0xEBFD,0xF4,0x01},
+{0xEBFE,0x85,0x01},
+{0xEBFF,0x7D,0x01},
+{0xEC00,0x61,0x01},
+{0xEC01,0x0F,0x01},
+{0xEC02,0xC0,0x01},
+{0xEC03,0xFF,0x01},
+{0xEC04,0xF7,0x01},
+{0xEC05,0x7F,0x01},
+{0xEC06,0x3D,0x01},
+{0xEC07,0x40,0x01},
+{0xEC08,0xFF,0x01},
+{0xEC09,0xDF,0x01},
+{0xEC0A,0x07,0x01},
+{0xEC0B,0xFA,0x01},
+{0xEC0C,0x81,0x01},
+{0xEC0D,0x3E,0x01},
+{0xEC0E,0x61,0x01},
+{0xEC0F,0x4F,0x01},
+{0xEC10,0xD8,0x01},
+{0xEC11,0x0B,0x01},
+{0xEC12,0xFC,0x01},
+{0xEC13,0xFE,0x01},
+{0xEC14,0x3D,0x01},
+{0xEC15,0xC0,0x01},
+{0xEC16,0xFF,0x01},
+{0xEC17,0xFF,0x01},
+{0xEC18,0x03,0x01},
+{0xEC19,0xFC,0x01},
+{0xEC1A,0x82,0x01},
+{0xEC1B,0xBE,0x01},
+{0xEC1C,0xA0,0x01},
+{0xEC1D,0x6F,0x01},
+{0xEC1E,0xF8,0x01},
+{0xEC1F,0x1B,0x01},
+{0xEC20,0xFE,0x01},
+{0xEC21,0x83,0x01},
+{0xEC22,0xBF,0x01},
+{0xEC23,0xE0,0x01},
+{0xEC24,0x0F,0x01},
+{0xEC25,0x10,0x01},
+{0xEC26,0x00,0x01},
+{0xEC27,0x00,0x01},
+{0xEC28,0x82,0x01},
+{0xEC29,0xC0,0x01},
+{0xEC2A,0x60,0x01},
+{0xEC2B,0x30,0x01},
+{0xEC2C,0x18,0x01},
+{0xEC2D,0x20,0x01},
+{0xEC2E,0x04,0x01},
+{0xEC2F,0x08,0x01},
+{0xEC30,0x81,0x01},
+{0xEC31,0x21,0x01},
+{0xEC32,0x30,0x01},
+{0xEC33,0x08,0x01},
+{0xEC34,0x08,0x01},
+{0xEC35,0x08,0x01},
+{0xEC36,0x82,0x01},
+{0xEC37,0x01,0x01},
+{0xEC38,0x81,0x01},
+{0xEC39,0x50,0x01},
+{0xEC3A,0x08,0x01},
+{0xEC3B,0x14,0x01},
+{0xEC3C,0x02,0x01},
+{0xEC3D,0x09,0x01},
+{0xEC3E,0x41,0x01},
+{0xEC3F,0x42,0x01},
+{0xEC40,0x70,0x01},
+{0xEC41,0x20,0x01},
+{0xEC42,0x0C,0x01},
+{0xEC43,0x06,0x01},
+{0xEC44,0x84,0x01},
+{0xEC45,0x42,0x01},
+{0xEC46,0xE1,0x01},
+{0xEC47,0x40,0x01},
+{0xEC48,0x38,0x01},
+{0xEC49,0x1C,0x01},
+{0xEC4A,0x0C,0x01},
+{0xEC4B,0x07,0x01},
+{0xEC4C,0x03,0x01},
+{0xEC4D,0xA2,0x01},
+{0xEC4E,0x80,0x01},
+{0xEC4F,0x28,0x01},
+{0xEC50,0x18,0x01},
+{0xEC51,0x10,0x01},
+{0xEC52,0x87,0x01},
+{0xEC53,0x43,0x01},
+{0xEC54,0x61,0x01},
+{0xEC55,0x41,0x01},
+{0xEC56,0x48,0x01},
+{0xEC57,0x14,0x01},
+{0xEC58,0x10,0x01},
+{0xEC59,0x07,0x01},
+{0xEC5A,0xC2,0x01},
+{0xEC5B,0x81,0x01},
+{0xEC5C,0x80,0x01},
+{0xEC5D,0x30,0x01},
+{0xEC5E,0x20,0x01},
+{0xEC5F,0x0C,0x01},
+{0xEC60,0x87,0x01},
+{0xEC61,0x83,0x01},
+{0xEC62,0xC1,0x01},
+{0xEC63,0x40,0x01},
+{0xEC64,0x38,0x01},
+{0xEC65,0x14,0x01},
+{0xEC66,0x0A,0x01},
+{0xEC67,0x07,0x01},
+{0xEC68,0xC3,0x01},
+{0xEC69,0xC1,0x01},
+{0xEC6A,0x70,0x01},
+{0xEC6B,0x30,0x01},
+{0xEC6C,0x20,0x01},
+{0xEC6D,0x0C,0x01},
+{0xEC6E,0x08,0x01},
+{0xEC6F,0xC3,0x01},
+{0xEC70,0xE1,0x01},
+{0xEC71,0x60,0x01},
+{0xEC72,0x30,0x01},
+{0xEC73,0x10,0x01},
+{0xEC74,0x0E,0x01},
+{0xEC75,0x85,0x01},
+{0xEC76,0xC2,0x01},
+{0xEC77,0xC1,0x01},
+{0xEC78,0x70,0x01},
+{0xEC79,0x30,0x01},
+{0xEC7A,0x1C,0x01},
+{0xEC7B,0x0C,0x01},
+
+//SHD1(from CO1)
+{0xED02,0xE6,0x01},
+{0xED03,0x61,0x01},
+{0xED04,0x92,0x01},
+{0xED05,0x7C,0x01},
+{0xED06,0xBE,0x01},
+{0xED07,0xB4,0x01},
+{0xED08,0x9E,0x01},
+{0xED09,0x2C,0x01},
+{0xED0A,0x75,0x01},
+{0xED0B,0x47,0x01},
+{0xED0C,0x49,0x01},
+{0xED0D,0xD7,0x01},
+{0xED0E,0x61,0x01},
+{0xED0F,0x12,0x01},
+{0xED10,0x76,0x01},
+{0xED11,0xA8,0x01},
+{0xED12,0x34,0x01},
+{0xED13,0x1E,0x01},
+{0xED14,0x31,0x01},
+{0xED15,0xA1,0x01},
+{0xED16,0xC7,0x01},
+{0xED17,0x4C,0x01},
+{0xED18,0xDE,0x01},
+{0xED19,0xC1,0x01},
+{0xED1A,0xD2,0x01},
+{0xED1B,0x77,0x01},
+{0xED1C,0x76,0x01},
+{0xED1D,0x94,0x01},
+{0xED1E,0x9C,0x01},
+{0xED1F,0x10,0x01},
+{0xED20,0xC9,0x01},
+{0xED21,0xC6,0x01},
+{0xED22,0x40,0x01},
+{0xED23,0xA2,0x01},
+{0xED24,0x99,0x01},
+{0xED25,0x8F,0x01},
+{0xED26,0x66,0x01},
+{0xED27,0xDC,0x01},
+{0xED28,0xF3,0x01},
+{0xED29,0x19,0x01},
+{0xED2A,0xFC,0x01},
+{0xED2B,0xB0,0x01},
+{0xED2C,0xA6,0x01},
+{0xED2D,0x41,0x01},
+{0xED2E,0xC1,0x01},
+{0xED2F,0x49,0x01},
+{0xED30,0x91,0x01},
+{0xED31,0x75,0x01},
+{0xED32,0x8C,0x01},
+{0xED33,0x74,0x01},
+{0xED34,0x1C,0x01},
+{0xED35,0x0B,0x01},
+{0xED36,0x91,0x01},
+{0xED37,0x86,0x01},
+{0xED38,0x3D,0x01},
+{0xED39,0x87,0x01},
+{0xED3A,0x39,0x01},
+{0xED3B,0x4E,0x01},
+{0xED3C,0x5C,0x01},
+{0xED3D,0x50,0x01},
+{0xED3E,0x83,0x01},
+{0xED3F,0x16,0x01},
+{0xED40,0xCF,0x01},
+{0xED41,0xBC,0x01},
+{0xED42,0x45,0x01},
+{0xED43,0x35,0x01},
+{0xED44,0x83,0x01},
+{0xED45,0x41,0x01},
+{0xED46,0xCE,0x01},
+{0xED47,0x67,0x01},
+{0xED48,0xE8,0x01},
+{0xED49,0x33,0x01},
+{0xED4A,0x1C,0x01},
+{0xED4B,0x16,0x01},
+{0xED4C,0xC1,0x01},
+{0xED4D,0x86,0x01},
+{0xED4E,0x3E,0x01},
+{0xED4F,0x83,0x01},
+{0xED50,0xC1,0x01},
+{0xED51,0x0D,0x01},
+{0xED52,0x57,0x01},
+{0xED53,0x02,0x01},
+{0xED54,0x23,0x01},
+{0xED55,0x14,0x01},
+{0xED56,0xAE,0x01},
+{0xED57,0xE4,0x01},
+{0xED58,0x44,0x01},
+{0xED59,0x2A,0x01},
+{0xED5A,0x43,0x01},
+{0xED5B,0xF9,0x01},
+{0xED5C,0xCA,0x01},
+{0xED5D,0x56,0x01},
+{0xED5E,0x0C,0x01},
+{0xED5F,0x03,0x01},
+{0xED60,0x98,0x01},
+{0xED61,0xE2,0x01},
+{0xED62,0xA8,0x01},
+{0xED63,0x26,0x01},
+{0xED64,0x41,0x01},
+{0xED65,0x9E,0x01},
+{0xED66,0xC1,0x01},
+{0xED67,0xCE,0x01},
+{0xED68,0x59,0x01},
+{0xED69,0x1C,0x01},
+{0xED6A,0xB3,0x01},
+{0xED6B,0x93,0x01},
+{0xED6C,0xA7,0x01},
+{0xED6D,0x74,0x01},
+{0xED6E,0x04,0x01},
+{0xED6F,0x25,0x01},
+{0xED70,0x13,0x01},
+{0xED71,0xD9,0x01},
+{0xED72,0xC8,0x01},
+{0xED73,0x47,0x01},
+{0xED74,0x54,0x01},
+{0xED75,0xD2,0x01},
+{0xED76,0x93,0x01},
+{0xED77,0xAA,0x01},
+{0xED78,0x98,0x01},
+{0xED79,0xE5,0x01},
+{0xED7A,0x32,0x01},
+{0xED7B,0x9A,0x01},
+{0xED7C,0x29,0x01},
+{0xED7D,0xCF,0x01},
+{0xED7E,0x64,0x01},
+{0xED7F,0x8E,0x01},
+{0xED80,0x73,0x01},
+{0xED81,0x95,0x01},
+{0xED82,0xBB,0x01},
+{0xED83,0xA4,0x01},
+{0xED84,0xA4,0x01},
+{0xED85,0x26,0x01},
+{0xED86,0x0A,0x01},
+{0xED87,0x59,0x01},
+{0xED88,0x08,0x01},
+{0xED89,0x40,0x01},
+{0xED8A,0x00,0x01},
+{0xED8B,0xC2,0x01},
+{0xED8C,0x10,0x01},
+{0xED8D,0x88,0x01},
+{0xED8E,0xB0,0x01},
+{0xED8F,0x84,0x01},
+{0xED90,0x27,0x01},
+{0xED91,0x59,0x01},
+{0xED92,0xF1,0x01},
+{0xED93,0x0B,0x01},
+{0xED94,0x64,0x01},
+{0xED95,0xA2,0x01},
+{0xED96,0x43,0x01},
+{0xED97,0x99,0x01},
+{0xED98,0xE4,0x01},
+{0xED99,0x68,0x01},
+{0xED9A,0x25,0x01},
+{0xED9B,0x2F,0x01},
+{0xED9C,0x2B,0x01},
+{0xED9D,0xB1,0x01},
+{0xED9E,0xC9,0x01},
+{0xED9F,0x42,0x01},
+{0xEDA0,0x18,0x01},
+{0xEDA1,0x32,0x01},
+{0xEDA2,0x90,0x01},
+{0xEDA3,0x80,0x01},
+{0xEDA4,0x3C,0x01},
+{0xEDA5,0x24,0x01},
+{0xEDA6,0x22,0x01},
+{0xEDA7,0x2F,0x01},
+{0xEDA8,0xF1,0x01},
+{0xEDA9,0x09,0x01},
+{0xEDAA,0x57,0x01},
+{0xEDAB,0x00,0x01},
+{0xEDAC,0x53,0x01},
+{0xEDAD,0x99,0x01},
+{0xEDAE,0xEA,0x01},
+{0xEDAF,0x90,0x01},
+{0xEDB0,0xC6,0x01},
+{0xEDB1,0x3B,0x01},
+{0xEDB2,0x6D,0x01},
+{0xEDB3,0x99,0x01},
+{0xEDB4,0x4C,0x01},
+{0xEDB5,0x50,0x01},
+{0xEDB6,0xA4,0x01},
+{0xEDB7,0x32,0x01},
+{0xEDB8,0x12,0x01},
+{0xEDB9,0x94,0x01},
+{0xEDBA,0x64,0x01},
+{0xEDBB,0xA4,0x01},
+{0xEDBC,0x23,0x01},
+{0xEDBD,0x25,0x01},
+{0xEDBE,0x71,0x01},
+{0xEDBF,0x49,0x01},
+{0xEDC0,0x51,0x01},
+{0xEDC1,0xB2,0x01},
+{0xEDC2,0x02,0x01},
+{0xEDC3,0x17,0x01},
+{0xEDC4,0xCD,0x01},
+{0xEDC5,0x98,0x01},
+{0xEDC6,0x86,0x01},
+{0xEDC7,0x3D,0x01},
+{0xEDC8,0xBC,0x01},
+{0xEDC9,0x01,0x01},
+{0xEDCA,0x50,0x01},
+{0xEDCB,0x63,0x01},
+{0xEDCC,0x80,0x01},
+{0xEDCD,0x63,0x01},
+{0xEDCE,0x16,0x01},
+{0xEDCF,0xC3,0x01},
+{0xEDD0,0x2C,0x01},
+{0xEDD1,0x25,0x01},
+{0xEDD2,0x2C,0x01},
+{0xEDD3,0x43,0x01},
+{0xEDD4,0xB1,0x01},
+{0xEDD5,0x4A,0x01},
+{0xEDD6,0x53,0x01},
+{0xEDD7,0xCC,0x01},
+{0xEDD8,0x82,0x01},
+{0xEDD9,0x96,0x01},
+{0xEDDA,0xC7,0x01},
+{0xEDDB,0x40,0x01},
+{0xEDDC,0xA6,0x01},
+{0xEDDD,0x39,0x01},
+{0xEDDE,0xBE,0x01},
+{0xEDDF,0x91,0x01},
+{0xEDE0,0xD0,0x01},
+{0xEDE1,0x75,0x01},
+{0xEDE2,0x54,0x01},
+{0xEDE3,0x34,0x01},
+{0xEDE4,0x1B,0x01},
+{0xEDE5,0xFC,0x01},
+{0xEDE6,0x4C,0x01},
+{0xEDE7,0x46,0x01},
+{0xEDE8,0x39,0x01},
+{0xEDE9,0x7D,0x01},
+{0xEDEA,0x71,0x01},
+{0xEDEB,0x8D,0x01},
+{0xEDEC,0x5D,0x01},
+{0xEDED,0x46,0x01},
+{0xEDEE,0xE3,0x01},
+{0xEDEF,0x17,0x01},
+{0xEDF0,0xD9,0x01},
+{0xEDF1,0x50,0x01},
+{0xEDF2,0x86,0x01},
+{0xEDF3,0x3A,0x01},
+{0xEDF4,0xB3,0x01},
+{0xEDF5,0x09,0x01},
+{0xEDF6,0x50,0x01},
+{0xEDF7,0x76,0x01},
+{0xEDF8,0x6A,0x01},
+{0xEDF9,0xF4,0x01},
+{0xEDFA,0x1E,0x01},
+{0xEDFB,0x25,0x01},
+{0xEDFC,0x61,0x01},
+{0xEDFD,0x67,0x01},
+{0xEDFE,0x45,0x01},
+{0xEDFF,0xC0,0x01},
+{0xEE00,0x69,0x01},
+{0xEE01,0xD0,0x01},
+{0xEE02,0x6B,0x01},
+{0xEE03,0xF6,0x01},
+{0xEE04,0x93,0x01},
+{0xEE05,0x9A,0x01},
+{0xEE06,0xFA,0x01},
+{0xEE07,0xB8,0x01},
+{0xEE08,0x26,0x01},
+{0xEE09,0x40,0x01},
+{0xEE0A,0xC0,0x01},
+{0xEE0B,0xB9,0x01},
+{0xEE0C,0xD0,0x01},
+{0xEE0D,0x75,0x01},
+{0xEE0E,0x6E,0x01},
+{0xEE0F,0xE4,0x01},
+{0xEE10,0x9E,0x01},
+{0xEE11,0x2D,0x01},
+{0xEE12,0xE1,0x01},
+{0xEE13,0xA7,0x01},
+{0xEE14,0x49,0x01},
+{0xEE15,0xFD,0x01},
+{0xEE16,0xB9,0x01},
+{0xEE17,0x52,0x01},
+{0xEE18,0x7C,0x01},
+{0xEE19,0x98,0x01},
+{0xEE1A,0x64,0x01},
+{0xEE1B,0x1E,0x01},
+{0xEE1C,0x22,0x01},
+{0xEE1D,0x89,0x01},
+{0xEE1E,0xA7,0x01},
+{0xEE1F,0x48,0x01},
+{0xEE20,0xE4,0x01},
+{0xEE21,0x49,0x01},
+{0xEE22,0x12,0x01},
+{0xEE23,0x7D,0x01},
+{0xEE24,0xB4,0x01},
+{0xEE25,0xB4,0x01},
+{0xEE26,0x1F,0x01},
+{0xEE27,0x31,0x01},
+{0xEE28,0xC5,0x01},
+{0xEE29,0x47,0x01},
+{0xEE2A,0x4B,0x01},
+{0xEE2B,0xC2,0x01},
+{0xEE2C,0x19,0x01},
+{0xEE2D,0x0F,0x01},
+{0xEE2E,0x73,0x01},
+{0xEE2F,0xE2,0x01},
+{0xEE30,0x13,0x01},
+{0xEE31,0x1C,0x01},
+{0xEE32,0xF5,0x01},
+{0xEE33,0xE0,0x01},
+{0xEE34,0xC6,0x01},
+{0xEE35,0x3B,0x01},
+{0xEE36,0xB6,0x01},
+{0xEE37,0xB1,0x01},
+{0xEE38,0xCE,0x01},
+{0xEE39,0x6D,0x01},
+{0xEE3A,0xB8,0x01},
+{0xEE3B,0xF3,0x01},
+{0xEE3C,0x9B,0x01},
+{0xEE3D,0xF2,0x01},
+{0xEE3E,0x18,0x01},
+{0xEE3F,0x27,0x01},
+{0xEE40,0x3D,0x01},
+{0xEE41,0xBF,0x01},
+{0xEE42,0xE9,0x01},
+{0xEE43,0xCE,0x01},
+{0xEE44,0x6E,0x01},
+{0xEE45,0xBA,0x01},
+{0xEE46,0x83,0x01},
+{0xEE47,0x9A,0x01},
+{0xEE48,0xE4,0x01},
+{0xEE49,0x50,0x01},
+{0xEE4A,0x66,0x01},
+{0xEE4B,0x36,0x01},
+{0xEE4C,0x8A,0x01},
+{0xEE4D,0x29,0x01},
+{0xEE4E,0x4D,0x01},
+{0xEE4F,0x61,0x01},
+{0xEE50,0x3A,0x01},
+{0xEE51,0xA3,0x01},
+{0xEE52,0x18,0x01},
+{0xEE53,0xD2,0x01},
+{0xEE54,0x50,0x01},
+{0xEE55,0x26,0x01},
+{0xEE56,0x36,0x01},
+{0xEE57,0xA8,0x01},
+{0xEE58,0x21,0x01},
+{0xEE59,0xCE,0x01},
+{0xEE5A,0x6E,0x01},
+{0xEE5B,0xB2,0x01},
+{0xEE5C,0x03,0x01},
+{0xEE5D,0x9A,0x01},
+{0xEE5E,0xE0,0x01},
+{0xEE5F,0x1C,0x01},
+{0xEE60,0x46,0x01},
+{0xEE61,0x34,0x01},
+{0xEE62,0x72,0x01},
+{0xEE63,0x41,0x01},
+{0xEE64,0x8C,0x01},
+{0xEE65,0x58,0x01},
+{0xEE66,0xE8,0x01},
+{0xEE67,0xC2,0x01},
+{0xEE68,0x95,0x01},
+{0xEE69,0xB5,0x01},
+{0xEE6A,0x88,0x01},
+{0xEE6B,0x65,0x01},
+{0xEE6C,0x2E,0x01},
+{0xEE6D,0x72,0x01},
+{0xEE6E,0x39,0x01},
+{0xEE6F,0x8C,0x01},
+{0xEE70,0x62,0x01},
+{0xEE71,0x48,0x01},
+{0xEE72,0x83,0x01},
+{0xEE73,0x1A,0x01},
+{0xEE74,0xE4,0x01},
+{0xEE75,0x28,0x01},
+{0xEE76,0x06,0x01},
+{0xEE77,0x35,0x01},
+{0xEE78,0x6A,0x01},
+{0xEE79,0xF9,0x01},
+{0xEE7A,0x4B,0x01},
+{0xEE7B,0x53,0x01},
+{0xEE7C,0xB8,0x01},
+{0xEE7D,0x92,0x01},
+{0xEE7E,0x13,0x01},
+{0xEE7F,0xA2,0x01},
+{0xEE80,0xCC,0x01},
+{0xEE81,0x64,0x01},
+{0xEE82,0x27,0x01},
+{0xEE83,0x3B,0x01},
+{0xEE84,0x29,0x01},
+{0xEE85,0x0A,0x01},
+{0xEE86,0x54,0x01},
+{0xEE87,0xBC,0x01},
+{0xEE88,0xF2,0x01},
+{0xEE89,0x96,0x01},
+{0xEE8A,0xC1,0x01},
+{0xEE8B,0x40,0x01},
+{0xEE8C,0xA6,0x01},
+{0xEE8D,0x35,0x01},
+{0xEE8E,0x7A,0x01},
+{0xEE8F,0xB1,0x01},
+{0xEE90,0x8C,0x01},
+{0xEE91,0x54,0x01},
+{0xEE92,0xC8,0x01},
+{0xEE93,0xF2,0x01},
+{0xEE94,0x92,0x01},
+{0xEE95,0x9D,0x01},
+{0xEE96,0x64,0x01},
+{0xEE97,0xE4,0x01},
+{0xEE98,0x23,0x01},
+{0xEE99,0x13,0x01},
+{0xEE9A,0xA9,0x01},
+{0xEE9B,0x48,0x01},
+{0xEE9C,0x47,0x01},
+{0xEE9D,0x40,0x01},
+{0xEE9E,0x42,0x01},
+{0xEE9F,0x13,0x01},
+{0xEEA0,0x9F,0x01},
+{0xEEA1,0x58,0x01},
+{0xEEA2,0xE5,0x01},
+{0xEEA3,0x2C,0x01},
+{0xEEA4,0x7F,0x01},
+{0xEEA5,0xD9,0x01},
+{0xEEA6,0x8C,0x01},
+{0xEEA7,0x5B,0x01},
+{0xEEA8,0x12,0x01},
+{0xEEA9,0x43,0x01},
+{0xEEAA,0x14,0x01},
+{0xEEAB,0xAA,0x01},
+{0xEEAC,0x80,0x01},
+{0xEEAD,0x04,0x01},
+{0xEEAE,0x25,0x01},
+{0xEEAF,0x06,0x01},
+{0xEEB0,0x51,0x01},
+{0xEEB1,0x08,0x01},
+{0xEEB2,0x40,0x01},
+{0xEEB3,0x00,0x01},
+{0xEEB4,0xB2,0x01},
+{0xEEB5,0x10,0x01},
+{0xEEB6,0x86,0x01},
+{0xEEB7,0x98,0x01},
+{0xEEB8,0x64,0x01},
+{0xEEB9,0x25,0x01},
+{0xEEBA,0x4A,0x01},
+{0xEEBB,0xB9,0x01},
+{0xEEBC,0x0A,0x01},
+{0xEEBD,0x5D,0x01},
+{0xEEBE,0x1C,0x01},
+{0xEEBF,0x13,0x01},
+{0xEEC0,0x97,0x01},
+{0xEEC1,0xC4,0x01},
+{0xEEC2,0x18,0x01},
+{0xEEC3,0x85,0x01},
+{0xEEC4,0x2A,0x01},
+{0xEEC5,0x21,0x01},
+{0xEEC6,0x41,0x01},
+{0xEEC7,0xC9,0x01},
+{0xEEC8,0x41,0x01},
+{0xEEC9,0x12,0x01},
+{0xEECA,0x02,0x01},
+{0xEECB,0x10,0x01},
+{0xEECC,0x80,0x01},
+{0xEECD,0x2C,0x01},
+{0xEECE,0x64,0x01},
+{0xEECF,0x21,0x01},
+{0xEED0,0x27,0x01},
+{0xEED1,0x61,0x01},
+{0xEED2,0xC9,0x01},
+{0xEED3,0x52,0x01},
+{0xEED4,0xB0,0x01},
+{0xEED5,0x42,0x01},
+{0xEED6,0x17,0x01},
+{0xEED7,0xC8,0x01},
+{0xEED8,0x04,0x01},
+{0xEED9,0xE6,0x01},
+{0xEEDA,0x32,0x01},
+{0xEEDB,0x58,0x01},
+{0xEEDC,0x29,0x01},
+{0xEEDD,0xCB,0x01},
+{0xEEDE,0x4C,0x01},
+{0xEEDF,0x74,0x01},
+{0xEEE0,0x92,0x01},
+{0xEEE1,0x91,0x01},
+{0xEEE2,0x8E,0x01},
+{0xEEE3,0x48,0x01},
+{0xEEE4,0x84,0x01},
+{0xEEE5,0x22,0x01},
+{0xEEE6,0x1D,0x01},
+{0xEEE7,0x01,0x01},
+{0xEEE8,0xC9,0x01},
+{0xEEE9,0x4D,0x01},
+{0xEEEA,0x7E,0x01},
+{0xEEEB,0x82,0x01},
+{0xEEEC,0x15,0x01},
+{0xEEED,0xB5,0x01},
+{0xEEEE,0x04,0x01},
+{0xEEEF,0xE6,0x01},
+{0xEEF0,0x33,0x01},
+{0xEEF1,0x99,0x01},
+{0xEEF2,0x69,0x01},
+{0xEEF3,0x0D,0x01},
+{0xEEF4,0x5D,0x01},
+{0xEEF5,0x06,0x01},
+{0xEEF6,0x33,0x01},
+{0xEEF7,0x15,0x01},
+{0xEEF8,0xAF,0x01},
+{0xEEF9,0xEC,0x01},
+{0xEEFA,0xA4,0x01},
+{0xEEFB,0x28,0x01},
+{0xEEFC,0x35,0x01},
+{0xEEFD,0xE9,0x01},
+{0xEEFE,0x09,0x01},
+{0xEEFF,0x4F,0x01},
+{0xEF00,0x8E,0x01},
+{0xEF01,0x02,0x01},
+{0xEF02,0x95,0x01},
+{0xEF03,0xB1,0x01},
+{0xEF04,0xC4,0x01},
+{0xEF05,0x25,0x01},
+{0xEF06,0x31,0x01},
+{0xEF07,0x94,0x01},
+{0xEF08,0xB1,0x01},
+{0xEF09,0x4D,0x01},
+{0xEF0A,0x6C,0x01},
+{0xEF0B,0x94,0x01},
+{0xEF0C,0x43,0x01},
+{0xEF0D,0x99,0x01},
+{0xEF0E,0xD4,0x01},
+{0xEF0F,0xEC,0x01},
+{0xEF10,0xC5,0x01},
+{0xEF11,0x31,0x01},
+{0xEF12,0x69,0x01},
+{0xEF13,0xC9,0x01},
+{0xEF14,0x0B,0x01},
+{0xEF15,0x58,0x01},
+{0xEF16,0xE6,0x01},
+{0xEF17,0x52,0x01},
+{0xEF18,0x16,0x01},
+{0xEF19,0xBE,0x01},
+{0xEF1A,0xD4,0x01},
+{0xEF1B,0x45,0x01},
+{0xEF1C,0x32,0x01},
+{0xEF1D,0x8E,0x01},
+{0xEF1E,0x79,0x01},
+{0xEF1F,0x4D,0x01},
+{0xEF20,0x6A,0x01},
+{0xEF21,0xA4,0x01},
+{0xEF22,0x83,0x01},
+{0xEF23,0x1C,0x01},
+{0xEF24,0xF2,0x01},
+{0xEF25,0xDC,0x01},
+{0xEF26,0x26,0x01},
+{0xEF27,0x3A,0x01},
+{0xEF28,0xA3,0x01},
+{0xEF29,0xE1,0x01},
+{0xEF2A,0x4D,0x01},
+{0xEF2B,0x65,0x01},
+{0xEF2C,0x5C,0x01},
+{0xEF2D,0xC3,0x01},
+{0xEF2E,0x98,0x01},
+{0xEF2F,0xD4,0x01},
+{0xEF30,0x3C,0x01},
+{0xEF31,0xE6,0x01},
+{0xEF32,0x35,0x01},
+{0xEF33,0x9D,0x01},
+{0xEF34,0x09,0x01},
+{0xEF35,0x8E,0x01},
+{0xEF36,0x6B,0x01},
+{0xEF37,0xAC,0x01},
+{0xEF38,0xE3,0x01},
+{0xEF39,0x9B,0x01},
+{0xEF3A,0xF4,0x01},
+{0xEF3B,0x34,0x01},
+{0xEF3C,0x07,0x01},
+{0xEF3D,0x3E,0x01},
+{0xEF3E,0xDA,0x01},
+{0xEF3F,0xC1,0x01},
+{0xEF40,0x8F,0x01},
+{0xEF41,0x74,0x01},
+{0xEF42,0xEA,0x01},
+{0xEF43,0x13,0x01},
+{0xEF44,0x9C,0x01},
+{0xEF45,0xF4,0x01},
+{0xEF46,0xF0,0x01},
+{0xEF47,0xA6,0x01},
+{0xEF48,0x3C,0x01},
+{0xEF49,0xC0,0x01},
+{0xEF4A,0x49,0x01},
+{0xEF4B,0x0F,0x01},
+{0xEF4C,0x72,0x01},
+{0xEF4D,0xEA,0x01},
+{0xEF4E,0xD3,0x01},
+{0xEF4F,0x9C,0x01},
+{0xEF50,0xFE,0x01},
+{0xEF51,0x04,0x01},
+{0xEF52,0xA7,0x01},
+{0xEF53,0x3D,0x01},
+
+//SHD2 CW+TL84 33:66
+
+{0xED00,0x9191,0x02},//
+{0xEF54,0x28,0x01},
+{0xEF55,0xC2,0x01},
+{0xEF56,0x11,0x01},
+{0xEF57,0x8C,0x01},
+{0xEF58,0x46,0x01},
+{0xEF59,0x34,0x01},
+{0xEF5A,0xA2,0x01},
+{0xEF5B,0x12,0x01},
+{0xEF5C,0xCD,0x01},
+{0xEF5D,0x08,0x01},
+{0xEF5E,0x47,0x01},
+{0xEF5F,0x27,0x01},
+{0xEF60,0xAA,0x01},
+{0xEF61,0x10,0x01},
+{0xEF62,0x7F,0x01},
+{0xEF63,0xC2,0x01},
+{0xEF64,0xF3,0x01},
+{0xEF65,0x1C,0x01},
+{0xEF66,0xE4,0x01},
+{0xEF67,0x40,0x01},
+{0xEF68,0x27,0x01},
+{0xEF69,0x3C,0x01},
+{0xEF6A,0xFB,0x01},
+{0xEF6B,0xA1,0x01},
+{0xEF6C,0x90,0x01},
+{0xEF6D,0x7C,0x01},
+{0xEF6E,0x92,0x01},
+{0xEF6F,0x63,0x01},
+{0xEF70,0x9A,0x01},
+{0xEF71,0xC5,0x01},
+{0xEF72,0x0C,0x01},
+{0xEF73,0x66,0x01},
+{0xEF74,0x31,0x01},
+{0xEF75,0xA4,0x01},
+{0xEF76,0x49,0x01},
+{0xEF77,0x0E,0x01},
+{0xEF78,0x7F,0x01},
+{0xEF79,0xA0,0x01},
+{0xEF7A,0xB3,0x01},
+{0xEF7B,0x19,0x01},
+{0xEF7C,0xB6,0x01},
+{0xEF7D,0x34,0x01},
+{0xEF7E,0x85,0x01},
+{0xEF7F,0x28,0x01},
+{0xEF80,0x4D,0x01},
+{0xEF81,0x61,0x01},
+{0xEF82,0x0B,0x01},
+{0xEF83,0x68,0x01},
+{0xEF84,0xB6,0x01},
+{0xEF85,0x73,0x01},
+{0xEF86,0x9B,0x01},
+{0xEF87,0xBB,0x01},
+{0xEF88,0x0C,0x01},
+{0xEF89,0x45,0x01},
+{0xEF8A,0x24,0x01},
+{0xEF8B,0x17,0x01},
+{0xEF8C,0x11,0x01},
+{0xEF8D,0x49,0x01},
+{0xEF8E,0x51,0x01},
+{0xEF8F,0xF4,0x01},
+{0xEF90,0xC2,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD4,0x01},
+{0xEF93,0x94,0x01},
+{0xEF94,0xC5,0x01},
+{0xEF95,0x25,0x01},
+{0xEF96,0x0B,0x01},
+{0xEF97,0x01,0x01},
+{0xEF98,0x48,0x01},
+{0xEF99,0x43,0x01},
+{0xEF9A,0x62,0x01},
+{0xEF9B,0x62,0x01},
+{0xEF9C,0x96,0x01},
+{0xEF9D,0xD5,0x01},
+{0xEF9E,0xA4,0x01},
+{0xEF9F,0xC6,0x01},
+{0xEFA0,0x2C,0x01},
+{0xEFA1,0x2F,0x01},
+{0xEFA2,0x51,0x01},
+{0xEFA3,0x48,0x01},
+{0xEFA4,0x40,0x01},
+{0xEFA5,0x1C,0x01},
+{0xEFA6,0x22,0x01},
+{0xEFA7,0x13,0x01},
+{0xEFA8,0xB4,0x01},
+{0xEFA9,0xC0,0x01},
+{0xEFAA,0x86,0x01},
+{0xEFAB,0x37,0x01},
+{0xEFAC,0x7B,0x01},
+{0xEFAD,0x29,0x01},
+{0xEFAE,0x8A,0x01},
+{0xEFAF,0x48,0x01},
+{0xEFB0,0x30,0x01},
+{0xEFB1,0x52,0x01},
+{0xEFB2,0x12,0x01},
+{0xEFB3,0xA4,0x01},
+{0xEFB4,0xF4,0x01},
+{0xEFB5,0x25,0x01},
+{0xEFB6,0x38,0x01},
+{0xEFB7,0xD9,0x01},
+{0xEFB8,0x01,0x01},
+{0xEFB9,0xCD,0x01},
+{0xEFBA,0x5B,0x01},
+{0xEFBB,0xA0,0x01},
+{0xEFBC,0x72,0x01},
+{0xEFBD,0x14,0x01},
+{0xEFBE,0xA9,0x01},
+{0xEFBF,0xCC,0x01},
+{0xEFC0,0xC5,0x01},
+{0xEFC1,0x34,0x01},
+{0xEFC2,0xE3,0x01},
+{0xEFC3,0xF1,0x01},
+{0xEFC4,0x0F,0x01},
+{0xEFC5,0x74,0x01},
+{0xEFC6,0x50,0x01},
+{0xEFC7,0xF3,0x01},
+{0xEFC8,0x98,0x01},
+{0xEFC9,0xC2,0x01},
+{0xEFCA,0x40,0x01},
+{0xEFCB,0x86,0x01},
+{0xEFCC,0x35,0x01},
+{0xEFCD,0xD4,0x01},
+{0xEFCE,0x29,0x01},
+{0xEFCF,0xD0,0x01},
+{0xEFD0,0x86,0x01},
+{0xEFD1,0xFE,0x01},
+{0xEFD2,0x23,0x01},
+{0xEFD3,0x9E,0x01},
+{0xEFD4,0xE8,0x01},
+{0xEFD5,0x28,0x01},
+{0xEFD6,0x87,0x01},
+{0xEFD7,0x3A,0x01},
+{0xEFD8,0xE7,0x01},
+{0xEFD9,0x21,0x01},
+{0xEFDA,0x10,0x01},
+{0xEFDB,0x89,0x01},
+{0xEFDC,0x3E,0x01},
+{0xEFDD,0x64,0x01},
+{0xEFDE,0xA2,0x01},
+{0xEFDF,0x0D,0x01},
+{0xEFE0,0x41,0x01},
+{0xEFE1,0xC8,0x01},
+{0xEFE2,0x41,0x01},
+{0xEFE3,0x14,0x01},
+{0xEFE4,0x02,0x01},
+{0xEFE5,0x11,0x01},
+{0xEFE6,0x8A,0x01},
+{0xEFE7,0x4C,0x01},
+{0xEFE8,0x04,0x01},
+{0xEFE9,0x00,0x01},
+{0xEFEA,0x00,0x01},
+{0xEFEB,0x00,0x01},
+{0xEFEC,0x00,0x01},
+{0xEFED,0x00,0x01},
+
+
+//SHD3 D65+TL84 C01//
+{0xED00,0x9191,0x02},//
+{0xEFEE,0x12,0x01},
+{0xEFEF,0x42,0x01},
+{0xEFF0,0x51,0x01},
+{0xEFF1,0x89,0x01},
+{0xEFF2,0x38,0x01},
+{0xEFF3,0xD4,0x01},
+{0xEFF4,0x21,0x01},
+{0xEFF5,0x10,0x01},
+{0xEFF6,0xAD,0x01},
+{0xEFF7,0xA8,0x01},
+{0xEFF8,0x45,0x01},
+{0xEFF9,0x18,0x01},
+{0xEFFA,0x4A,0x01},
+{0xEFFB,0x50,0x01},
+{0xEFFC,0x7D,0x01},
+{0xEFFD,0xBA,0x01},
+{0xEFFE,0xD3,0x01},
+{0xEFFF,0x1C,0x01},
+{0xF000,0xE4,0x01},
+{0xF001,0x40,0x01},
+{0xF002,0x27,0x01},
+{0xF003,0x3C,0x01},
+{0xF004,0xF8,0x01},
+{0xF005,0x69,0x01},
+{0xF006,0x10,0x01},
+{0xF007,0x7B,0x01},
+{0xF008,0x8E,0x01},
+{0xF009,0x63,0x01},
+{0xF00A,0x1A,0x01},
+{0xF00B,0xC6,0x01},
+{0xF00C,0x10,0x01},
+{0xF00D,0xA6,0x01},
+{0xF00E,0x31,0x01},
+{0xF00F,0xA6,0x01},
+{0xF010,0x59,0x01},
+{0xF011,0x8E,0x01},
+{0xF012,0x7E,0x01},
+{0xF013,0x9A,0x01},
+{0xF014,0xB3,0x01},
+{0xF015,0x19,0x01},
+{0xF016,0xB6,0x01},
+{0xF017,0x38,0x01},
+{0xF018,0xA5,0x01},
+{0xF019,0x28,0x01},
+{0xF01A,0x4F,0x01},
+{0xF01B,0x79,0x01},
+{0xF01C,0xCB,0x01},
+{0xF01D,0x68,0x01},
+{0xF01E,0xBA,0x01},
+{0xF01F,0x53,0x01},
+{0xF020,0x9B,0x01},
+{0xF021,0xBB,0x01},
+{0xF022,0x0C,0x01},
+{0xF023,0x65,0x01},
+{0xF024,0x24,0x01},
+{0xF025,0x17,0x01},
+{0xF026,0x21,0x01},
+{0xF027,0xC9,0x01},
+{0xF028,0x51,0x01},
+{0xF029,0xFC,0x01},
+{0xF02A,0xF2,0x01},
+{0xF02B,0x9B,0x01},
+{0xF02C,0xD3,0x01},
+{0xF02D,0x94,0x01},
+{0xF02E,0xC5,0x01},
+{0xF02F,0x25,0x01},
+{0xF030,0x0A,0x01},
+{0xF031,0x01,0x01},
+{0xF032,0x48,0x01},
+{0xF033,0x43,0x01},
+{0xF034,0x66,0x01},
+{0xF035,0x92,0x01},
+{0xF036,0x96,0x01},
+{0xF037,0xD7,0x01},
+{0xF038,0xA0,0x01},
+{0xF039,0xE6,0x01},
+{0xF03A,0x2C,0x01},
+{0xF03B,0x2F,0x01},
+{0xF03C,0x51,0x01},
+{0xF03D,0x48,0x01},
+{0xF03E,0x40,0x01},
+{0xF03F,0x1E,0x01},
+{0xF040,0x42,0x01},
+{0xF041,0x93,0x01},
+{0xF042,0xB5,0x01},
+{0xF043,0xCC,0x01},
+{0xF044,0x46,0x01},
+{0xF045,0x37,0x01},
+{0xF046,0x7C,0x01},
+{0xF047,0x29,0x01},
+{0xF048,0x8A,0x01},
+{0xF049,0x48,0x01},
+{0xF04A,0x32,0x01},
+{0xF04B,0x72,0x01},
+{0xF04C,0x12,0x01},
+{0xF04D,0xA5,0x01},
+{0xF04E,0x00,0x01},
+{0xF04F,0xA6,0x01},
+{0xF050,0x38,0x01},
+{0xF051,0xD7,0x01},
+{0xF052,0x01,0x01},
+{0xF053,0x0D,0x01},
+{0xF054,0x5C,0x01},
+{0xF055,0xA2,0x01},
+{0xF056,0x82,0x01},
+{0xF057,0x94,0x01},
+{0xF058,0xAA,0x01},
+{0xF059,0xD8,0x01},
+{0xF05A,0x45,0x01},
+{0xF05B,0x35,0x01},
+{0xF05C,0xE5,0x01},
+{0xF05D,0xC9,0x01},
+{0xF05E,0xCF,0x01},
+{0xF05F,0x73,0x01},
+{0xF060,0x50,0x01},
+{0xF061,0x03,0x01},
+{0xF062,0x99,0x01},
+{0xF063,0xC3,0x01},
+{0xF064,0x4C,0x01},
+{0xF065,0xE6,0x01},
+{0xF066,0x35,0x01},
+{0xF067,0xD7,0x01},
+{0xF068,0x21,0x01},
+{0xF069,0x10,0x01},
+{0xF06A,0x84,0x01},
+{0xF06B,0xF2,0x01},
+{0xF06C,0x03,0x01},
+{0xF06D,0x9E,0x01},
+{0xF06E,0xE8,0x01},
+{0xF06F,0x2C,0x01},
+{0xF070,0xA7,0x01},
+{0xF071,0x3A,0x01},
+{0xF072,0xE8,0x01},
+{0xF073,0x11,0x01},
+{0xF074,0x90,0x01},
+{0xF075,0x87,0x01},
+{0xF076,0x18,0x01},
+{0xF077,0x94,0x01},
+{0xF078,0x21,0x01},
+{0xF079,0x09,0x01},
+{0xF07A,0x2D,0x01},
+{0xF07B,0x68,0x01},
+{0xF07C,0x41,0x01},
+{0xF07D,0x11,0x01},
+{0xF07E,0xDA,0x01},
+{0xF07F,0x10,0x01},
+{0xF080,0x88,0x01},
+{0xF081,0x2A,0x01},
+{0xF082,0x04,0x01},
+{0xF083,0x00,0x01},
+{0xF084,0x00,0x01},
+{0xF085,0x00,0x01},
+{0xF086,0x00,0x01},
+{0xF087,0x00,0x01},
+{0xF088,0xBE,0x01},
+{0xF089,0x51,0x01},
+{0xF08A,0x4E,0x01},
+{0xF08B,0x6F,0x01},
+{0xF08C,0x6C,0x01},
+{0xF08D,0x43,0x01},
+{0xF08E,0x1B,0x01},
+{0xF08F,0xDA,0x01},
+{0xF090,0xEC,0x01},
+{0xF091,0x46,0x01},
+{0xF092,0x38,0x01},
+{0xF093,0xBB,0x01},
+{0xF094,0xC1,0x01},
+{0xF095,0xCD,0x01},
+{0xF096,0x69,0x01},
+{0xF097,0x26,0x01},
+{0xF098,0x93,0x01},
+{0xF099,0x98,0x01},
+{0xF09A,0xC1,0x01},
+{0xF09B,0x20,0x01},
+{0xF09C,0x26,0x01},
+{0xF09D,0x32,0x01},
+{0xF09E,0xA5,0x01},
+{0xF09F,0xB1,0x01},
+{0xF0A0,0x8D,0x01},
+{0xF0A1,0x67,0x01},
+{0xF0A2,0x0E,0x01},
+{0xF0A3,0x23,0x01},
+{0xF0A4,0x97,0x01},
+{0xF0A5,0xB0,0x01},
+{0xF0A6,0x6C,0x01},
+{0xF0A7,0x25,0x01},
+{0xF0A8,0x2C,0x01},
+{0xF0A9,0x71,0x01},
+{0xF0AA,0x41,0x01},
+{0xF0AB,0x0C,0x01},
+{0xF0AC,0x69,0x01},
+{0xF0AD,0x14,0x01},
+{0xF0AE,0xB3,0x01},
+{0xF0AF,0x96,0x01},
+{0xF0B0,0xA6,0x01},
+{0xF0B1,0xE8,0x01},
+{0xF0B2,0x64,0x01},
+{0xF0B3,0x26,0x01},
+{0xF0B4,0x3A,0x01},
+{0xF0B5,0x79,0x01},
+{0xF0B6,0x4A,0x01},
+{0xF0B7,0x5B,0x01},
+{0xF0B8,0x18,0x01},
+{0xF0B9,0xA3,0x01},
+{0xF0BA,0x97,0x01},
+{0xF0BB,0xA9,0x01},
+{0xF0BC,0xBC,0x01},
+{0xF0BD,0x24,0x01},
+{0xF0BE,0x23,0x01},
+{0xF0BF,0x13,0x01},
+{0xF0C0,0xE1,0x01},
+{0xF0C1,0xC8,0x01},
+{0xF0C2,0x4C,0x01},
+{0xF0C3,0xAA,0x01},
+{0xF0C4,0xA2,0x01},
+{0xF0C5,0x97,0x01},
+{0xF0C6,0xB6,0x01},
+{0xF0C7,0x14,0x01},
+{0xF0C8,0x05,0x01},
+{0xF0C9,0x24,0x01},
+{0xF0CA,0x06,0x01},
+{0xF0CB,0x09,0x01},
+{0xF0CC,0xC8,0x01},
+{0xF0CD,0x42,0x01},
+{0xF0CE,0x48,0x01},
+{0xF0CF,0x82,0x01},
+{0xF0D0,0x14,0x01},
+{0xF0D1,0xB8,0x01},
+{0xF0D2,0xC0,0x01},
+{0xF0D3,0xE5,0x01},
+{0xF0D4,0x28,0x01},
+{0xF0D5,0x21,0x01},
+{0xF0D6,0x39,0x01},
+{0xF0D7,0x08,0x01},
+{0xF0D8,0x40,0x01},
+{0xF0D9,0x14,0x01},
+{0xF0DA,0x62,0x01},
+{0xF0DB,0x92,0x01},
+{0xF0DC,0xA4,0x01},
+{0xF0DD,0xC4,0x01},
+{0xF0DE,0x05,0x01},
+{0xF0DF,0x30,0x01},
+{0xF0E0,0x58,0x01},
+{0xF0E1,0xA1,0x01},
+{0xF0E2,0x49,0x01},
+{0xF0E3,0x46,0x01},
+{0xF0E4,0x22,0x01},
+{0xF0E5,0xB2,0x01},
+{0xF0E6,0x91,0x01},
+{0xF0E7,0x9A,0x01},
+{0xF0E8,0x58,0x01},
+{0xF0E9,0xA5,0x01},
+{0xF0EA,0x2F,0x01},
+{0xF0EB,0x96,0x01},
+{0xF0EC,0x99,0x01},
+{0xF0ED,0x8B,0x01},
+{0xF0EE,0x54,0x01},
+{0xF0EF,0x74,0x01},
+{0xF0F0,0x32,0x01},
+{0xF0F1,0x13,0x01},
+{0xF0F2,0x9D,0x01},
+{0xF0F3,0x38,0x01},
+{0xF0F4,0xC5,0x01},
+{0xF0F5,0x2D,0x01},
+{0xF0F6,0x90,0x01},
+{0xF0F7,0x59,0x01},
+{0xF0F8,0x4D,0x01},
+{0xF0F9,0x64,0x01},
+{0xF0FA,0xEE,0x01},
+{0xF0FB,0x62,0x01},
+{0xF0FC,0x16,0x01},
+{0xF0FD,0xAE,0x01},
+{0xF0FE,0x84,0x01},
+{0xF0FF,0x25,0x01},
+{0xF100,0x2E,0x01},
+{0xF101,0x8B,0x01},
+{0xF102,0x31,0x01},
+{0xF103,0xCD,0x01},
+{0xF104,0x6F,0x01},
+{0xF105,0x60,0x01},
+{0xF106,0xC3,0x01},
+{0xF107,0x19,0x01},
+{0xF108,0xC7,0x01},
+{0xF109,0x14,0x01},
+{0xF10A,0x26,0x01},
+{0xF10B,0x31,0x01},
+{0xF10C,0x97,0x01},
+{0xF10D,0x41,0x01},
+{0xF10E,0x8D,0x01},
+{0xF10F,0x6D,0x01},
+{0xF110,0x86,0x01},
+{0xF111,0xE3,0x01},
+{0xF112,0x9C,0x01},
+{0xF113,0xE2,0x01},
+{0xF114,0xD8,0x01},
+{0xF115,0x06,0x01},
+{0xF116,0x36,0x01},
+{0xF117,0xB5,0x01},
+{0xF118,0xE9,0x01},
+{0xF119,0x4D,0x01},
+{0xF11A,0x70,0x01},
+{0xF11B,0x68,0x01},
+{0xF11C,0x03,0x01},
+{0xF11D,0x00,0x01},
+{0xF11E,0x00,0x01},
+{0xF11F,0x00,0x01},
+{0xF120,0x00,0x01},
+{0xF121,0x00,0x01},
+
+
+//SHD TH
+{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2
+{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2
+{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2
+{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2
+{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB
+{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB
+{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB
+{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB
+
+//PreWB_offset (for SHD2)
+{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 :
+//PreWB_offset (for SHD3)
+{0x682C,0x000C,0x02}, // SHD_PRER_OFFSET_RB :
+{0x6830,0xFFFF,0x02}, // SHD_PREB_OFFSET_RB :
+
+// CXC/SHD EN
+{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF
+};
+
+static const isx012_regset_t ISX012_Shading_1[] =
+{
+{0x01BC,0x50,0x01}, // CXC OFF SHD OFF
+{0xEB00,0x8282,0x02}, //valid_code
+{0xEB02,0xFE,0x01},
+{0xEB03,0x84,0x01},
+{0xEB04,0x3F,0x01},
+{0xEB05,0x01,0x01},
+{0xEB06,0x50,0x01},
+{0xEB07,0x08,0x01},
+{0xEB08,0x14,0x01},
+{0xEB09,0xFF,0x01},
+{0xEB0A,0x45,0x01},
+{0xEB0B,0x80,0x01},
+{0xEB0C,0x01,0x01},
+{0xEB0D,0x68,0x01},
+{0xEB0E,0x04,0x01},
+{0xEB0F,0x1A,0x01},
+{0xEB10,0x81,0x01},
+{0xEB11,0x86,0x01},
+{0xEB12,0x3F,0x01},
+{0xEB13,0xE1,0x01},
+{0xEB14,0x4F,0x01},
+{0xEB15,0x00,0x01},
+{0xEB16,0x14,0x01},
+{0xEB17,0x02,0x01},
+{0xEB18,0xC5,0x01},
+{0xEB19,0x7F,0x01},
+{0xEB1A,0x11,0x01},
+{0xEB1B,0x60,0x01},
+{0xEB1C,0x00,0x01},
+{0xEB1D,0x1A,0x01},
+{0xEB1E,0x81,0x01},
+{0xEB1F,0x46,0x01},
+{0xEB20,0xA0,0x01},
+{0xEB21,0x01,0x01},
+{0xEB22,0x48,0x01},
+{0xEB23,0x00,0x01},
+{0xEB24,0x12,0x01},
+{0xEB25,0x81,0x01},
+{0xEB26,0x05,0x01},
+{0xEB27,0x20,0x01},
+{0xEB28,0xF1,0x01},
+{0xEB29,0x4F,0x01},
+{0xEB2A,0x00,0x01},
+{0xEB2B,0x14,0x01},
+{0xEB2C,0x82,0x01},
+{0xEB2D,0x85,0x01},
+{0xEB2E,0x80,0x01},
+{0xEB2F,0x21,0x01},
+{0xEB30,0x60,0x01},
+{0xEB31,0x04,0x01},
+{0xEB32,0x12,0x01},
+{0xEB33,0x81,0x01},
+{0xEB34,0x84,0x01},
+{0xEB35,0xE0,0x01},
+{0xEB36,0x00,0x01},
+{0xEB37,0x28,0x01},
+{0xEB38,0x04,0x01},
+{0xEB39,0x0C,0x01},
+{0xEB3A,0x82,0x01},
+{0xEB3B,0x43,0x01},
+{0xEB3C,0x20,0x01},
+{0xEB3D,0x11,0x01},
+{0xEB3E,0x68,0x01},
+{0xEB3F,0x04,0x01},
+{0xEB40,0x1A,0x01},
+{0xEB41,0x82,0x01},
+{0xEB42,0x83,0x01},
+{0xEB43,0xE0,0x01},
+{0xEB44,0x00,0x01},
+{0xEB45,0x20,0x01},
+{0xEB46,0x00,0x01},
+{0xEB47,0x06,0x01},
+{0xEB48,0xFF,0x01},
+{0xEB49,0x41,0x01},
+{0xEB4A,0x80,0x01},
+{0xEB4B,0x10,0x01},
+{0xEB4C,0x30,0x01},
+{0xEB4D,0x08,0x01},
+{0xEB4E,0x14,0x01},
+{0xEB4F,0x02,0x01},
+{0xEB50,0x45,0x01},
+{0xEB51,0xC0,0x01},
+{0xEB52,0x10,0x01},
+{0xEB53,0x30,0x01},
+{0xEB54,0x04,0x01},
+{0xEB55,0x04,0x01},
+{0xEB56,0x01,0x01},
+{0xEB57,0xC0,0x01},
+{0xEB58,0x3F,0x01},
+{0xEB59,0x10,0x01},
+{0xEB5A,0x10,0x01},
+{0xEB5B,0x04,0x01},
+{0xEB5C,0x0A,0x01},
+{0xEB5D,0x80,0x01},
+{0xEB5E,0x03,0x01},
+{0xEB5F,0xE0,0x01},
+{0xEB60,0x10,0x01},
+{0xEB61,0x28,0x01},
+{0xEB62,0x04,0x01},
+{0xEB63,0x0A,0x01},
+{0xEB64,0x81,0x01},
+{0xEB65,0x01,0x01},
+{0xEB66,0x00,0x01},
+{0xEB67,0x10,0x01},
+{0xEB68,0x00,0x01},
+{0xEB69,0x04,0x01},
+{0xEB6A,0x04,0x01},
+{0xEB6B,0x01,0x01},
+{0xEB6C,0x42,0x01},
+{0xEB6D,0xE0,0x01},
+{0xEB6E,0x10,0x01},
+{0xEB6F,0x38,0x01},
+{0xEB70,0xFC,0x01},
+{0xEB71,0x0D,0x01},
+{0xEB72,0x7F,0x01},
+{0xEB73,0x43,0x01},
+{0xEB74,0x60,0x01},
+{0xEB75,0x00,0x01},
+{0xEB76,0x08,0x01},
+{0xEB77,0x08,0x01},
+{0xEB78,0x02,0x01},
+{0xEB79,0x81,0x01},
+{0xEB7A,0x41,0x01},
+{0xEB7B,0x80,0x01},
+{0xEB7C,0x10,0x01},
+{0xEB7D,0x30,0x01},
+{0xEB7E,0x04,0x01},
+{0xEB7F,0x0C,0x01},
+{0xEB80,0x01,0x01},
+{0xEB81,0x43,0x01},
+{0xEB82,0xC0,0x01},
+{0xEB83,0x20,0x01},
+{0xEB84,0x28,0x01},
+{0xEB85,0x08,0x01},
+{0xEB86,0x06,0x01},
+{0xEB87,0x02,0x01},
+{0xEB88,0xC2,0x01},
+{0xEB89,0xA0,0x01},
+{0xEB8A,0x30,0x01},
+{0xEB8B,0x30,0x01},
+{0xEB8C,0x0C,0x01},
+{0xEB8D,0x12,0x01},
+{0xEB8E,0x83,0x01},
+{0xEB8F,0x84,0x01},
+{0xEB90,0x00,0x01},
+{0xEB91,0x21,0x01},
+{0xEB92,0x40,0x01},
+{0xEB93,0x0C,0x01},
+{0xEB94,0x0C,0x01},
+{0xEB95,0x82,0x01},
+{0xEB96,0x03,0x01},
+{0xEB97,0xC1,0x01},
+{0xEB98,0x40,0x01},
+{0xEB99,0x40,0x01},
+{0xEB9A,0x08,0x01},
+{0xEB9B,0x10,0x01},
+{0xEB9C,0x03,0x01},
+{0xEB9D,0xC4,0x01},
+{0xEB9E,0x00,0x01},
+{0xEB9F,0x21,0x01},
+{0xEBA0,0x38,0x01},
+{0xEBA1,0x08,0x01},
+{0xEBA2,0x0E,0x01},
+{0xEBA3,0x82,0x01},
+{0xEBA4,0xC3,0x01},
+{0xEBA5,0x20,0x01},
+{0xEBA6,0x41,0x01},
+{0xEBA7,0x48,0x01},
+{0xEBA8,0x00,0x01},
+{0xEBA9,0x14,0x01},
+{0xEBAA,0x83,0x01},
+{0xEBAB,0x44,0x01},
+{0xEBAC,0x20,0x01},
+{0xEBAD,0x11,0x01},
+{0xEBAE,0x48,0x01},
+{0xEBAF,0x08,0x01},
+{0xEBB0,0x0E,0x01},
+{0xEBB1,0x82,0x01},
+{0xEBB2,0x83,0x01},
+{0xEBB3,0xE0,0x01},
+{0xEBB4,0x30,0x01},
+{0xEBB5,0x48,0x01},
+{0xEBB6,0x10,0x01},
+{0xEBB7,0x12,0x01},
+{0xEBB8,0x00,0x01},
+{0xEBB9,0xC5,0x01},
+{0xEBBA,0x20,0x01},
+{0xEBBB,0x11,0x01},
+{0xEBBC,0x48,0x01},
+{0xEBBD,0x04,0x01},
+{0xEBBE,0x12,0x01},
+{0xEBBF,0x04,0x01},
+{0xEBC0,0x3B,0x01},
+{0xEBC1,0xC1,0x01},
+{0xEBC2,0x1E,0x01},
+{0xEBC3,0xC8,0x01},
+{0xEBC4,0x0F,0x01},
+{0xEBC5,0xF8,0x01},
+{0xEBC6,0x02,0x01},
+{0xEBC7,0xBB,0x01},
+{0xEBC8,0x60,0x01},
+{0xEBC9,0x0F,0x01},
+{0xEBCA,0xB8,0x01},
+{0xEBCB,0x0F,0x01},
+{0xEBCC,0xEA,0x01},
+{0xEBCD,0x83,0x01},
+{0xEBCE,0x3A,0x01},
+{0xEBCF,0xC1,0x01},
+{0xEBD0,0x4E,0x01},
+{0xEBD1,0xB0,0x01},
+{0xEBD2,0x07,0x01},
+{0xEBD3,0xF2,0x01},
+{0xEBD4,0x03,0x01},
+{0xEBD5,0xBE,0x01},
+{0xEBD6,0xC0,0x01},
+{0xEBD7,0x2E,0x01},
+{0xEBD8,0xD8,0x01},
+{0xEBD9,0x03,0x01},
+{0xEBDA,0xEE,0x01},
+{0xEBDB,0x83,0x01},
+{0xEBDC,0xFA,0x01},
+{0xEBDD,0xA0,0x01},
+{0xEBDE,0x2E,0x01},
+{0xEBDF,0xB0,0x01},
+{0xEBE0,0x0B,0x01},
+{0xEBE1,0xEC,0x01},
+{0xEBE2,0x05,0x01},
+{0xEBE3,0xBD,0x01},
+{0xEBE4,0x60,0x01},
+{0xEBE5,0x2F,0x01},
+{0xEBE6,0xD0,0x01},
+{0xEBE7,0x07,0x01},
+{0xEBE8,0xEC,0x01},
+{0xEBE9,0x02,0x01},
+{0xEBEA,0xBC,0x01},
+{0xEBEB,0x40,0x01},
+{0xEBEC,0x2F,0x01},
+{0xEBED,0xD0,0x01},
+{0xEBEE,0x13,0x01},
+{0xEBEF,0xEE,0x01},
+{0xEBF0,0x84,0x01},
+{0xEBF1,0xBB,0x01},
+{0xEBF2,0x00,0x01},
+{0xEBF3,0x1F,0x01},
+{0xEBF4,0xC8,0x01},
+{0xEBF5,0xFF,0x01},
+{0xEBF6,0xEF,0x01},
+{0xEBF7,0x00,0x01},
+{0xEBF8,0x7D,0x01},
+{0xEBF9,0x60,0x01},
+{0xEBFA,0x2F,0x01},
+{0xEBFB,0xD0,0x01},
+{0xEBFC,0x0B,0x01},
+{0xEBFD,0xF4,0x01},
+{0xEBFE,0x85,0x01},
+{0xEBFF,0x7D,0x01},
+{0xEC00,0x61,0x01},
+{0xEC01,0x0F,0x01},
+{0xEC02,0xC0,0x01},
+{0xEC03,0xFF,0x01},
+{0xEC04,0xF7,0x01},
+{0xEC05,0x7F,0x01},
+{0xEC06,0x3D,0x01},
+{0xEC07,0x40,0x01},
+{0xEC08,0xFF,0x01},
+{0xEC09,0xDF,0x01},
+{0xEC0A,0x07,0x01},
+{0xEC0B,0xFA,0x01},
+{0xEC0C,0x81,0x01},
+{0xEC0D,0x3E,0x01},
+{0xEC0E,0x61,0x01},
+{0xEC0F,0x4F,0x01},
+{0xEC10,0xD8,0x01},
+{0xEC11,0x0B,0x01},
+{0xEC12,0xFC,0x01},
+{0xEC13,0xFE,0x01},
+{0xEC14,0x3D,0x01},
+{0xEC15,0xC0,0x01},
+{0xEC16,0xFF,0x01},
+{0xEC17,0xFF,0x01},
+{0xEC18,0x03,0x01},
+{0xEC19,0xFC,0x01},
+{0xEC1A,0x82,0x01},
+{0xEC1B,0xBE,0x01},
+{0xEC1C,0xA0,0x01},
+{0xEC1D,0x6F,0x01},
+{0xEC1E,0xF8,0x01},
+{0xEC1F,0x1B,0x01},
+{0xEC20,0xFE,0x01},
+{0xEC21,0x83,0x01},
+{0xEC22,0xBF,0x01},
+{0xEC23,0xE0,0x01},
+{0xEC24,0x0F,0x01},
+{0xEC25,0x10,0x01},
+{0xEC26,0x00,0x01},
+{0xEC27,0x00,0x01},
+{0xEC28,0x82,0x01},
+{0xEC29,0xC0,0x01},
+{0xEC2A,0x60,0x01},
+{0xEC2B,0x30,0x01},
+{0xEC2C,0x18,0x01},
+{0xEC2D,0x20,0x01},
+{0xEC2E,0x04,0x01},
+{0xEC2F,0x08,0x01},
+{0xEC30,0x81,0x01},
+{0xEC31,0x21,0x01},
+{0xEC32,0x30,0x01},
+{0xEC33,0x08,0x01},
+{0xEC34,0x08,0x01},
+{0xEC35,0x08,0x01},
+{0xEC36,0x82,0x01},
+{0xEC37,0x01,0x01},
+{0xEC38,0x81,0x01},
+{0xEC39,0x50,0x01},
+{0xEC3A,0x08,0x01},
+{0xEC3B,0x14,0x01},
+{0xEC3C,0x02,0x01},
+{0xEC3D,0x09,0x01},
+{0xEC3E,0x41,0x01},
+{0xEC3F,0x42,0x01},
+{0xEC40,0x70,0x01},
+{0xEC41,0x20,0x01},
+{0xEC42,0x0C,0x01},
+{0xEC43,0x06,0x01},
+{0xEC44,0x84,0x01},
+{0xEC45,0x42,0x01},
+{0xEC46,0xE1,0x01},
+{0xEC47,0x40,0x01},
+{0xEC48,0x38,0x01},
+{0xEC49,0x1C,0x01},
+{0xEC4A,0x0C,0x01},
+{0xEC4B,0x07,0x01},
+{0xEC4C,0x03,0x01},
+{0xEC4D,0xA2,0x01},
+{0xEC4E,0x80,0x01},
+{0xEC4F,0x28,0x01},
+{0xEC50,0x18,0x01},
+{0xEC51,0x10,0x01},
+{0xEC52,0x87,0x01},
+{0xEC53,0x43,0x01},
+{0xEC54,0x61,0x01},
+{0xEC55,0x41,0x01},
+{0xEC56,0x48,0x01},
+{0xEC57,0x14,0x01},
+{0xEC58,0x10,0x01},
+{0xEC59,0x07,0x01},
+{0xEC5A,0xC2,0x01},
+{0xEC5B,0x81,0x01},
+{0xEC5C,0x80,0x01},
+{0xEC5D,0x30,0x01},
+{0xEC5E,0x20,0x01},
+{0xEC5F,0x0C,0x01},
+{0xEC60,0x87,0x01},
+{0xEC61,0x83,0x01},
+{0xEC62,0xC1,0x01},
+{0xEC63,0x40,0x01},
+{0xEC64,0x38,0x01},
+{0xEC65,0x14,0x01},
+{0xEC66,0x0A,0x01},
+{0xEC67,0x07,0x01},
+{0xEC68,0xC3,0x01},
+{0xEC69,0xC1,0x01},
+{0xEC6A,0x70,0x01},
+{0xEC6B,0x30,0x01},
+{0xEC6C,0x20,0x01},
+{0xEC6D,0x0C,0x01},
+{0xEC6E,0x08,0x01},
+{0xEC6F,0xC3,0x01},
+{0xEC70,0xE1,0x01},
+{0xEC71,0x60,0x01},
+{0xEC72,0x30,0x01},
+{0xEC73,0x10,0x01},
+{0xEC74,0x0E,0x01},
+{0xEC75,0x85,0x01},
+{0xEC76,0xC2,0x01},
+{0xEC77,0xC1,0x01},
+{0xEC78,0x70,0x01},
+{0xEC79,0x30,0x01},
+{0xEC7A,0x1C,0x01},
+{0xEC7B,0x0C,0x01},
+
+//SHD1(from CO1)
+{0xED02,0xE6,0x01},
+{0xED03,0x61,0x01},
+{0xED04,0x92,0x01},
+{0xED05,0x7C,0x01},
+{0xED06,0xBE,0x01},
+{0xED07,0xB4,0x01},
+{0xED08,0x9E,0x01},
+{0xED09,0x2C,0x01},
+{0xED0A,0x75,0x01},
+{0xED0B,0x47,0x01},
+{0xED0C,0x49,0x01},
+{0xED0D,0xD7,0x01},
+{0xED0E,0x61,0x01},
+{0xED0F,0x12,0x01},
+{0xED10,0x76,0x01},
+{0xED11,0xA8,0x01},
+{0xED12,0x34,0x01},
+{0xED13,0x1E,0x01},
+{0xED14,0x31,0x01},
+{0xED15,0xA1,0x01},
+{0xED16,0xC7,0x01},
+{0xED17,0x4C,0x01},
+{0xED18,0xDE,0x01},
+{0xED19,0xC1,0x01},
+{0xED1A,0xD2,0x01},
+{0xED1B,0x77,0x01},
+{0xED1C,0x76,0x01},
+{0xED1D,0x94,0x01},
+{0xED1E,0x9C,0x01},
+{0xED1F,0x10,0x01},
+{0xED20,0xC9,0x01},
+{0xED21,0xC6,0x01},
+{0xED22,0x40,0x01},
+{0xED23,0xA2,0x01},
+{0xED24,0x99,0x01},
+{0xED25,0x8F,0x01},
+{0xED26,0x66,0x01},
+{0xED27,0xDC,0x01},
+{0xED28,0xF3,0x01},
+{0xED29,0x19,0x01},
+{0xED2A,0xFC,0x01},
+{0xED2B,0xB0,0x01},
+{0xED2C,0xA6,0x01},
+{0xED2D,0x41,0x01},
+{0xED2E,0xC1,0x01},
+{0xED2F,0x49,0x01},
+{0xED30,0x91,0x01},
+{0xED31,0x75,0x01},
+{0xED32,0x8C,0x01},
+{0xED33,0x74,0x01},
+{0xED34,0x1C,0x01},
+{0xED35,0x0B,0x01},
+{0xED36,0x91,0x01},
+{0xED37,0x86,0x01},
+{0xED38,0x3D,0x01},
+{0xED39,0x87,0x01},
+{0xED3A,0x39,0x01},
+{0xED3B,0x4E,0x01},
+{0xED3C,0x5C,0x01},
+{0xED3D,0x50,0x01},
+{0xED3E,0x83,0x01},
+{0xED3F,0x16,0x01},
+{0xED40,0xCF,0x01},
+{0xED41,0xBC,0x01},
+{0xED42,0x45,0x01},
+{0xED43,0x35,0x01},
+{0xED44,0x83,0x01},
+{0xED45,0x41,0x01},
+{0xED46,0xCE,0x01},
+{0xED47,0x67,0x01},
+{0xED48,0xE8,0x01},
+{0xED49,0x33,0x01},
+{0xED4A,0x1C,0x01},
+{0xED4B,0x16,0x01},
+{0xED4C,0xC1,0x01},
+{0xED4D,0x86,0x01},
+{0xED4E,0x3E,0x01},
+{0xED4F,0x83,0x01},
+{0xED50,0xC1,0x01},
+{0xED51,0x0D,0x01},
+{0xED52,0x57,0x01},
+{0xED53,0x02,0x01},
+{0xED54,0x23,0x01},
+{0xED55,0x14,0x01},
+{0xED56,0xAE,0x01},
+{0xED57,0xE4,0x01},
+{0xED58,0x44,0x01},
+{0xED59,0x2A,0x01},
+{0xED5A,0x43,0x01},
+{0xED5B,0xF9,0x01},
+{0xED5C,0xCA,0x01},
+{0xED5D,0x56,0x01},
+{0xED5E,0x0C,0x01},
+{0xED5F,0x03,0x01},
+{0xED60,0x98,0x01},
+{0xED61,0xE2,0x01},
+{0xED62,0xA8,0x01},
+{0xED63,0x26,0x01},
+{0xED64,0x41,0x01},
+{0xED65,0x9E,0x01},
+{0xED66,0xC1,0x01},
+{0xED67,0xCE,0x01},
+{0xED68,0x59,0x01},
+{0xED69,0x1C,0x01},
+{0xED6A,0xB3,0x01},
+{0xED6B,0x93,0x01},
+{0xED6C,0xA7,0x01},
+{0xED6D,0x74,0x01},
+{0xED6E,0x04,0x01},
+{0xED6F,0x25,0x01},
+{0xED70,0x13,0x01},
+{0xED71,0xD9,0x01},
+{0xED72,0xC8,0x01},
+{0xED73,0x47,0x01},
+{0xED74,0x54,0x01},
+{0xED75,0xD2,0x01},
+{0xED76,0x93,0x01},
+{0xED77,0xAA,0x01},
+{0xED78,0x98,0x01},
+{0xED79,0xE5,0x01},
+{0xED7A,0x32,0x01},
+{0xED7B,0x9A,0x01},
+{0xED7C,0x29,0x01},
+{0xED7D,0xCF,0x01},
+{0xED7E,0x64,0x01},
+{0xED7F,0x8E,0x01},
+{0xED80,0x73,0x01},
+{0xED81,0x95,0x01},
+{0xED82,0xBB,0x01},
+{0xED83,0xA4,0x01},
+{0xED84,0xA4,0x01},
+{0xED85,0x26,0x01},
+{0xED86,0x0A,0x01},
+{0xED87,0x59,0x01},
+{0xED88,0x08,0x01},
+{0xED89,0x40,0x01},
+{0xED8A,0x00,0x01},
+{0xED8B,0xC2,0x01},
+{0xED8C,0x10,0x01},
+{0xED8D,0x88,0x01},
+{0xED8E,0xB0,0x01},
+{0xED8F,0x84,0x01},
+{0xED90,0x27,0x01},
+{0xED91,0x59,0x01},
+{0xED92,0xF1,0x01},
+{0xED93,0x0B,0x01},
+{0xED94,0x64,0x01},
+{0xED95,0xA2,0x01},
+{0xED96,0x43,0x01},
+{0xED97,0x99,0x01},
+{0xED98,0xE4,0x01},
+{0xED99,0x68,0x01},
+{0xED9A,0x25,0x01},
+{0xED9B,0x2F,0x01},
+{0xED9C,0x2B,0x01},
+{0xED9D,0xB1,0x01},
+{0xED9E,0xC9,0x01},
+{0xED9F,0x42,0x01},
+{0xEDA0,0x18,0x01},
+{0xEDA1,0x32,0x01},
+{0xEDA2,0x90,0x01},
+{0xEDA3,0x80,0x01},
+{0xEDA4,0x3C,0x01},
+{0xEDA5,0x24,0x01},
+{0xEDA6,0x22,0x01},
+{0xEDA7,0x2F,0x01},
+{0xEDA8,0xF1,0x01},
+{0xEDA9,0x09,0x01},
+{0xEDAA,0x57,0x01},
+{0xEDAB,0x00,0x01},
+{0xEDAC,0x53,0x01},
+{0xEDAD,0x99,0x01},
+{0xEDAE,0xEA,0x01},
+{0xEDAF,0x90,0x01},
+{0xEDB0,0xC6,0x01},
+{0xEDB1,0x3B,0x01},
+{0xEDB2,0x6D,0x01},
+{0xEDB3,0x99,0x01},
+{0xEDB4,0x4C,0x01},
+{0xEDB5,0x50,0x01},
+{0xEDB6,0xA4,0x01},
+{0xEDB7,0x32,0x01},
+{0xEDB8,0x12,0x01},
+{0xEDB9,0x94,0x01},
+{0xEDBA,0x64,0x01},
+{0xEDBB,0xA4,0x01},
+{0xEDBC,0x23,0x01},
+{0xEDBD,0x25,0x01},
+{0xEDBE,0x71,0x01},
+{0xEDBF,0x49,0x01},
+{0xEDC0,0x51,0x01},
+{0xEDC1,0xB2,0x01},
+{0xEDC2,0x02,0x01},
+{0xEDC3,0x17,0x01},
+{0xEDC4,0xCD,0x01},
+{0xEDC5,0x98,0x01},
+{0xEDC6,0x86,0x01},
+{0xEDC7,0x3D,0x01},
+{0xEDC8,0xBC,0x01},
+{0xEDC9,0x01,0x01},
+{0xEDCA,0x50,0x01},
+{0xEDCB,0x63,0x01},
+{0xEDCC,0x80,0x01},
+{0xEDCD,0x63,0x01},
+{0xEDCE,0x16,0x01},
+{0xEDCF,0xC3,0x01},
+{0xEDD0,0x2C,0x01},
+{0xEDD1,0x25,0x01},
+{0xEDD2,0x2C,0x01},
+{0xEDD3,0x43,0x01},
+{0xEDD4,0xB1,0x01},
+{0xEDD5,0x4A,0x01},
+{0xEDD6,0x53,0x01},
+{0xEDD7,0xCC,0x01},
+{0xEDD8,0x82,0x01},
+{0xEDD9,0x96,0x01},
+{0xEDDA,0xC7,0x01},
+{0xEDDB,0x40,0x01},
+{0xEDDC,0xA6,0x01},
+{0xEDDD,0x39,0x01},
+{0xEDDE,0xBE,0x01},
+{0xEDDF,0x91,0x01},
+{0xEDE0,0xD0,0x01},
+{0xEDE1,0x75,0x01},
+{0xEDE2,0x54,0x01},
+{0xEDE3,0x34,0x01},
+{0xEDE4,0x1B,0x01},
+{0xEDE5,0xFC,0x01},
+{0xEDE6,0x4C,0x01},
+{0xEDE7,0x46,0x01},
+{0xEDE8,0x39,0x01},
+{0xEDE9,0x7D,0x01},
+{0xEDEA,0x71,0x01},
+{0xEDEB,0x8D,0x01},
+{0xEDEC,0x5D,0x01},
+{0xEDED,0x46,0x01},
+{0xEDEE,0xE3,0x01},
+{0xEDEF,0x17,0x01},
+{0xEDF0,0xD9,0x01},
+{0xEDF1,0x50,0x01},
+{0xEDF2,0x86,0x01},
+{0xEDF3,0x3A,0x01},
+{0xEDF4,0xB3,0x01},
+{0xEDF5,0x09,0x01},
+{0xEDF6,0x50,0x01},
+{0xEDF7,0x76,0x01},
+{0xEDF8,0x6A,0x01},
+{0xEDF9,0xF4,0x01},
+{0xEDFA,0x1E,0x01},
+{0xEDFB,0x25,0x01},
+{0xEDFC,0x61,0x01},
+{0xEDFD,0x67,0x01},
+{0xEDFE,0x45,0x01},
+{0xEDFF,0xC0,0x01},
+{0xEE00,0x69,0x01},
+{0xEE01,0xD0,0x01},
+{0xEE02,0x6B,0x01},
+{0xEE03,0xF6,0x01},
+{0xEE04,0x93,0x01},
+{0xEE05,0x9A,0x01},
+{0xEE06,0xFA,0x01},
+{0xEE07,0xB8,0x01},
+{0xEE08,0x26,0x01},
+{0xEE09,0x40,0x01},
+{0xEE0A,0xC0,0x01},
+{0xEE0B,0xB9,0x01},
+{0xEE0C,0xD0,0x01},
+{0xEE0D,0x75,0x01},
+{0xEE0E,0x6E,0x01},
+{0xEE0F,0xE4,0x01},
+{0xEE10,0x9E,0x01},
+{0xEE11,0x2D,0x01},
+{0xEE12,0xE1,0x01},
+{0xEE13,0xA7,0x01},
+{0xEE14,0x49,0x01},
+{0xEE15,0xFD,0x01},
+{0xEE16,0xB9,0x01},
+{0xEE17,0x52,0x01},
+{0xEE18,0x7C,0x01},
+{0xEE19,0x98,0x01},
+{0xEE1A,0x64,0x01},
+{0xEE1B,0x1E,0x01},
+{0xEE1C,0x22,0x01},
+{0xEE1D,0x89,0x01},
+{0xEE1E,0xA7,0x01},
+{0xEE1F,0x48,0x01},
+{0xEE20,0xE4,0x01},
+{0xEE21,0x49,0x01},
+{0xEE22,0x12,0x01},
+{0xEE23,0x7D,0x01},
+{0xEE24,0xB4,0x01},
+{0xEE25,0xB4,0x01},
+{0xEE26,0x1F,0x01},
+{0xEE27,0x31,0x01},
+{0xEE28,0xC5,0x01},
+{0xEE29,0x47,0x01},
+{0xEE2A,0x4B,0x01},
+{0xEE2B,0xC2,0x01},
+{0xEE2C,0x19,0x01},
+{0xEE2D,0x0F,0x01},
+{0xEE2E,0x73,0x01},
+{0xEE2F,0xE2,0x01},
+{0xEE30,0x13,0x01},
+{0xEE31,0x1C,0x01},
+{0xEE32,0xF5,0x01},
+{0xEE33,0xE0,0x01},
+{0xEE34,0xC6,0x01},
+{0xEE35,0x3B,0x01},
+{0xEE36,0xB6,0x01},
+{0xEE37,0xB1,0x01},
+{0xEE38,0xCE,0x01},
+{0xEE39,0x6D,0x01},
+{0xEE3A,0xB8,0x01},
+{0xEE3B,0xF3,0x01},
+{0xEE3C,0x9B,0x01},
+{0xEE3D,0xF2,0x01},
+{0xEE3E,0x18,0x01},
+{0xEE3F,0x27,0x01},
+{0xEE40,0x3D,0x01},
+{0xEE41,0xBF,0x01},
+{0xEE42,0xE9,0x01},
+{0xEE43,0xCE,0x01},
+{0xEE44,0x6E,0x01},
+{0xEE45,0xBA,0x01},
+{0xEE46,0x83,0x01},
+{0xEE47,0x9A,0x01},
+{0xEE48,0xE4,0x01},
+{0xEE49,0x50,0x01},
+{0xEE4A,0x66,0x01},
+{0xEE4B,0x36,0x01},
+{0xEE4C,0x8A,0x01},
+{0xEE4D,0x29,0x01},
+{0xEE4E,0x4D,0x01},
+{0xEE4F,0x61,0x01},
+{0xEE50,0x3A,0x01},
+{0xEE51,0xA3,0x01},
+{0xEE52,0x18,0x01},
+{0xEE53,0xD2,0x01},
+{0xEE54,0x50,0x01},
+{0xEE55,0x26,0x01},
+{0xEE56,0x36,0x01},
+{0xEE57,0xA8,0x01},
+{0xEE58,0x21,0x01},
+{0xEE59,0xCE,0x01},
+{0xEE5A,0x6E,0x01},
+{0xEE5B,0xB2,0x01},
+{0xEE5C,0x03,0x01},
+{0xEE5D,0x9A,0x01},
+{0xEE5E,0xE0,0x01},
+{0xEE5F,0x1C,0x01},
+{0xEE60,0x46,0x01},
+{0xEE61,0x34,0x01},
+{0xEE62,0x72,0x01},
+{0xEE63,0x41,0x01},
+{0xEE64,0x8C,0x01},
+{0xEE65,0x58,0x01},
+{0xEE66,0xE8,0x01},
+{0xEE67,0xC2,0x01},
+{0xEE68,0x95,0x01},
+{0xEE69,0xB5,0x01},
+{0xEE6A,0x88,0x01},
+{0xEE6B,0x65,0x01},
+{0xEE6C,0x2E,0x01},
+{0xEE6D,0x72,0x01},
+{0xEE6E,0x39,0x01},
+{0xEE6F,0x8C,0x01},
+{0xEE70,0x62,0x01},
+{0xEE71,0x48,0x01},
+{0xEE72,0x83,0x01},
+{0xEE73,0x1A,0x01},
+{0xEE74,0xE4,0x01},
+{0xEE75,0x28,0x01},
+{0xEE76,0x06,0x01},
+{0xEE77,0x35,0x01},
+{0xEE78,0x6A,0x01},
+{0xEE79,0xF9,0x01},
+{0xEE7A,0x4B,0x01},
+{0xEE7B,0x53,0x01},
+{0xEE7C,0xB8,0x01},
+{0xEE7D,0x92,0x01},
+{0xEE7E,0x13,0x01},
+{0xEE7F,0xA2,0x01},
+{0xEE80,0xCC,0x01},
+{0xEE81,0x64,0x01},
+{0xEE82,0x27,0x01},
+{0xEE83,0x3B,0x01},
+{0xEE84,0x29,0x01},
+{0xEE85,0x0A,0x01},
+{0xEE86,0x54,0x01},
+{0xEE87,0xBC,0x01},
+{0xEE88,0xF2,0x01},
+{0xEE89,0x96,0x01},
+{0xEE8A,0xC1,0x01},
+{0xEE8B,0x40,0x01},
+{0xEE8C,0xA6,0x01},
+{0xEE8D,0x35,0x01},
+{0xEE8E,0x7A,0x01},
+{0xEE8F,0xB1,0x01},
+{0xEE90,0x8C,0x01},
+{0xEE91,0x54,0x01},
+{0xEE92,0xC8,0x01},
+{0xEE93,0xF2,0x01},
+{0xEE94,0x92,0x01},
+{0xEE95,0x9D,0x01},
+{0xEE96,0x64,0x01},
+{0xEE97,0xE4,0x01},
+{0xEE98,0x23,0x01},
+{0xEE99,0x13,0x01},
+{0xEE9A,0xA9,0x01},
+{0xEE9B,0x48,0x01},
+{0xEE9C,0x47,0x01},
+{0xEE9D,0x40,0x01},
+{0xEE9E,0x42,0x01},
+{0xEE9F,0x13,0x01},
+{0xEEA0,0x9F,0x01},
+{0xEEA1,0x58,0x01},
+{0xEEA2,0xE5,0x01},
+{0xEEA3,0x2C,0x01},
+{0xEEA4,0x7F,0x01},
+{0xEEA5,0xD9,0x01},
+{0xEEA6,0x8C,0x01},
+{0xEEA7,0x5B,0x01},
+{0xEEA8,0x12,0x01},
+{0xEEA9,0x43,0x01},
+{0xEEAA,0x14,0x01},
+{0xEEAB,0xAA,0x01},
+{0xEEAC,0x80,0x01},
+{0xEEAD,0x04,0x01},
+{0xEEAE,0x25,0x01},
+{0xEEAF,0x06,0x01},
+{0xEEB0,0x51,0x01},
+{0xEEB1,0x08,0x01},
+{0xEEB2,0x40,0x01},
+{0xEEB3,0x00,0x01},
+{0xEEB4,0xB2,0x01},
+{0xEEB5,0x10,0x01},
+{0xEEB6,0x86,0x01},
+{0xEEB7,0x98,0x01},
+{0xEEB8,0x64,0x01},
+{0xEEB9,0x25,0x01},
+{0xEEBA,0x4A,0x01},
+{0xEEBB,0xB9,0x01},
+{0xEEBC,0x0A,0x01},
+{0xEEBD,0x5D,0x01},
+{0xEEBE,0x1C,0x01},
+{0xEEBF,0x13,0x01},
+{0xEEC0,0x97,0x01},
+{0xEEC1,0xC4,0x01},
+{0xEEC2,0x18,0x01},
+{0xEEC3,0x85,0x01},
+{0xEEC4,0x2A,0x01},
+{0xEEC5,0x21,0x01},
+{0xEEC6,0x41,0x01},
+{0xEEC7,0xC9,0x01},
+{0xEEC8,0x41,0x01},
+{0xEEC9,0x12,0x01},
+{0xEECA,0x02,0x01},
+{0xEECB,0x10,0x01},
+{0xEECC,0x80,0x01},
+{0xEECD,0x2C,0x01},
+{0xEECE,0x64,0x01},
+{0xEECF,0x21,0x01},
+{0xEED0,0x27,0x01},
+{0xEED1,0x61,0x01},
+{0xEED2,0xC9,0x01},
+{0xEED3,0x52,0x01},
+{0xEED4,0xB0,0x01},
+{0xEED5,0x42,0x01},
+{0xEED6,0x17,0x01},
+{0xEED7,0xC8,0x01},
+{0xEED8,0x04,0x01},
+{0xEED9,0xE6,0x01},
+{0xEEDA,0x32,0x01},
+{0xEEDB,0x58,0x01},
+{0xEEDC,0x29,0x01},
+{0xEEDD,0xCB,0x01},
+{0xEEDE,0x4C,0x01},
+{0xEEDF,0x74,0x01},
+{0xEEE0,0x92,0x01},
+{0xEEE1,0x91,0x01},
+{0xEEE2,0x8E,0x01},
+{0xEEE3,0x48,0x01},
+{0xEEE4,0x84,0x01},
+{0xEEE5,0x22,0x01},
+{0xEEE6,0x1D,0x01},
+{0xEEE7,0x01,0x01},
+{0xEEE8,0xC9,0x01},
+{0xEEE9,0x4D,0x01},
+{0xEEEA,0x7E,0x01},
+{0xEEEB,0x82,0x01},
+{0xEEEC,0x15,0x01},
+{0xEEED,0xB5,0x01},
+{0xEEEE,0x04,0x01},
+{0xEEEF,0xE6,0x01},
+{0xEEF0,0x33,0x01},
+{0xEEF1,0x99,0x01},
+{0xEEF2,0x69,0x01},
+{0xEEF3,0x0D,0x01},
+{0xEEF4,0x5D,0x01},
+{0xEEF5,0x06,0x01},
+{0xEEF6,0x33,0x01},
+{0xEEF7,0x15,0x01},
+{0xEEF8,0xAF,0x01},
+{0xEEF9,0xEC,0x01},
+{0xEEFA,0xA4,0x01},
+{0xEEFB,0x28,0x01},
+{0xEEFC,0x35,0x01},
+{0xEEFD,0xE9,0x01},
+{0xEEFE,0x09,0x01},
+{0xEEFF,0x4F,0x01},
+{0xEF00,0x8E,0x01},
+{0xEF01,0x02,0x01},
+{0xEF02,0x95,0x01},
+{0xEF03,0xB1,0x01},
+{0xEF04,0xC4,0x01},
+{0xEF05,0x25,0x01},
+{0xEF06,0x31,0x01},
+{0xEF07,0x94,0x01},
+{0xEF08,0xB1,0x01},
+{0xEF09,0x4D,0x01},
+{0xEF0A,0x6C,0x01},
+{0xEF0B,0x94,0x01},
+{0xEF0C,0x43,0x01},
+{0xEF0D,0x99,0x01},
+{0xEF0E,0xD4,0x01},
+{0xEF0F,0xEC,0x01},
+{0xEF10,0xC5,0x01},
+{0xEF11,0x31,0x01},
+{0xEF12,0x69,0x01},
+{0xEF13,0xC9,0x01},
+{0xEF14,0x0B,0x01},
+{0xEF15,0x58,0x01},
+{0xEF16,0xE6,0x01},
+{0xEF17,0x52,0x01},
+{0xEF18,0x16,0x01},
+{0xEF19,0xBE,0x01},
+{0xEF1A,0xD4,0x01},
+{0xEF1B,0x45,0x01},
+{0xEF1C,0x32,0x01},
+{0xEF1D,0x8E,0x01},
+{0xEF1E,0x79,0x01},
+{0xEF1F,0x4D,0x01},
+{0xEF20,0x6A,0x01},
+{0xEF21,0xA4,0x01},
+{0xEF22,0x83,0x01},
+{0xEF23,0x1C,0x01},
+{0xEF24,0xF2,0x01},
+{0xEF25,0xDC,0x01},
+{0xEF26,0x26,0x01},
+{0xEF27,0x3A,0x01},
+{0xEF28,0xA3,0x01},
+{0xEF29,0xE1,0x01},
+{0xEF2A,0x4D,0x01},
+{0xEF2B,0x65,0x01},
+{0xEF2C,0x5C,0x01},
+{0xEF2D,0xC3,0x01},
+{0xEF2E,0x98,0x01},
+{0xEF2F,0xD4,0x01},
+{0xEF30,0x3C,0x01},
+{0xEF31,0xE6,0x01},
+{0xEF32,0x35,0x01},
+{0xEF33,0x9D,0x01},
+{0xEF34,0x09,0x01},
+{0xEF35,0x8E,0x01},
+{0xEF36,0x6B,0x01},
+{0xEF37,0xAC,0x01},
+{0xEF38,0xE3,0x01},
+{0xEF39,0x9B,0x01},
+{0xEF3A,0xF4,0x01},
+{0xEF3B,0x34,0x01},
+{0xEF3C,0x07,0x01},
+{0xEF3D,0x3E,0x01},
+{0xEF3E,0xDA,0x01},
+{0xEF3F,0xC1,0x01},
+{0xEF40,0x8F,0x01},
+{0xEF41,0x74,0x01},
+{0xEF42,0xEA,0x01},
+{0xEF43,0x13,0x01},
+{0xEF44,0x9C,0x01},
+{0xEF45,0xF4,0x01},
+{0xEF46,0xF0,0x01},
+{0xEF47,0xA6,0x01},
+{0xEF48,0x3C,0x01},
+{0xEF49,0xC0,0x01},
+{0xEF4A,0x49,0x01},
+{0xEF4B,0x0F,0x01},
+{0xEF4C,0x72,0x01},
+{0xEF4D,0xEA,0x01},
+{0xEF4E,0xD3,0x01},
+{0xEF4F,0x9C,0x01},
+{0xEF50,0xFE,0x01},
+{0xEF51,0x04,0x01},
+{0xEF52,0xA7,0x01},
+{0xEF53,0x3D,0x01},
+
+//SHD2 CW+TL84 33:66
+
+{0xED00,0x9191,0x02},//
+{0xEF54,0x0B,0x01},
+{0xEF55,0xFA,0x01},
+{0xEF56,0x10,0x01},
+{0xEF57,0x87,0x01},
+{0xEF58,0x24,0x01},
+{0xEF59,0x24,0x01},
+{0xEF5A,0xA1,0x01},
+{0xEF5B,0x09,0x01},
+{0xEF5C,0x7D,0x01},
+{0xEF5D,0x08,0x01},
+{0xEF5E,0x44,0x01},
+{0xEF5F,0x0A,0x01},
+{0xEF60,0x0A,0x01},
+{0xEF61,0x50,0x01},
+{0xEF62,0x7B,0x01},
+{0xEF63,0xAA,0x01},
+{0xEF64,0x53,0x01},
+{0xEF65,0x9C,0x01},
+{0xEF66,0xDF,0x01},
+{0xEF67,0x18,0x01},
+{0xEF68,0xC7,0x01},
+{0xEF69,0x3A,0x01},
+{0xEF6A,0xEC,0x01},
+{0xEF6B,0xF9,0x01},
+{0xEF6C,0x0F,0x01},
+{0xEF6D,0x79,0x01},
+{0xEF6E,0x80,0x01},
+{0xEF6F,0x03,0x01},
+{0xEF70,0x9A,0x01},
+{0xEF71,0xC3,0x01},
+{0xEF72,0xF8,0x01},
+{0xEF73,0xE5,0x01},
+{0xEF74,0x30,0x01},
+{0xEF75,0x9D,0x01},
+{0xEF76,0x01,0x01},
+{0xEF77,0x4E,0x01},
+{0xEF78,0x7B,0x01},
+{0xEF79,0x8C,0x01},
+{0xEF7A,0x53,0x01},
+{0xEF7B,0x19,0x01},
+{0xEF7C,0xB4,0x01},
+{0xEF7D,0x2C,0x01},
+{0xEF7E,0x45,0x01},
+{0xEF7F,0x28,0x01},
+{0xEF80,0x4B,0x01},
+{0xEF81,0x49,0x01},
+{0xEF82,0x8B,0x01},
+{0xEF83,0x66,0x01},
+{0xEF84,0xA0,0x01},
+{0xEF85,0xF3,0x01},
+{0xEF86,0x9A,0x01},
+{0xEF87,0xB9,0x01},
+{0xEF88,0x04,0x01},
+{0xEF89,0x45,0x01},
+{0xEF8A,0x24,0x01},
+{0xEF8B,0x16,0x01},
+{0xEF8C,0x09,0x01},
+{0xEF8D,0xC9,0x01},
+{0xEF8E,0x50,0x01},
+{0xEF8F,0xEC,0x01},
+{0xEF90,0x42,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD1,0x01},
+{0xEF93,0x88,0x01},
+{0xEF94,0xA5,0x01},
+{0xEF95,0x25,0x01},
+{0xEF96,0x0A,0x01},
+{0xEF97,0x01,0x01},
+{0xEF98,0x48,0x01},
+{0xEF99,0x43,0x01},
+{0xEF9A,0x60,0x01},
+{0xEF9B,0x32,0x01},
+{0xEF9C,0x96,0x01},
+{0xEF9D,0xD2,0x01},
+{0xEF9E,0x88,0x01},
+{0xEF9F,0x66,0x01},
+{0xEFA0,0x2C,0x01},
+{0xEFA1,0x2E,0x01},
+{0xEFA2,0x51,0x01},
+{0xEFA3,0x48,0x01},
+{0xEFA4,0x40,0x01},
+{0xEFA5,0x1C,0x01},
+{0xEFA6,0x12,0x01},
+{0xEFA7,0x93,0x01},
+{0xEFA8,0xB2,0x01},
+{0xEFA9,0xA4,0x01},
+{0xEFAA,0x86,0x01},
+{0xEFAB,0x36,0x01},
+{0xEFAC,0x77,0x01},
+{0xEFAD,0x19,0x01},
+{0xEFAE,0x4A,0x01},
+{0xEFAF,0x48,0x01},
+{0xEFB0,0x30,0x01},
+{0xEFB1,0x52,0x01},
+{0xEFB2,0x12,0x01},
+{0xEFB3,0xA3,0x01},
+{0xEFB4,0xE4,0x01},
+{0xEFB5,0x25,0x01},
+{0xEFB6,0x37,0x01},
+{0xEFB7,0xCF,0x01},
+{0xEFB8,0xD1,0x01},
+{0xEFB9,0xCC,0x01},
+{0xEFBA,0x5A,0x01},
+{0xEFBB,0x9A,0x01},
+{0xEFBC,0x52,0x01},
+{0xEFBD,0x14,0x01},
+{0xEFBE,0xA8,0x01},
+{0xEFBF,0xC0,0x01},
+{0xEFC0,0x05,0x01},
+{0xEFC1,0x34,0x01},
+{0xEFC2,0xD8,0x01},
+{0xEFC3,0x79,0x01},
+{0xEFC4,0xCF,0x01},
+{0xEFC5,0x71,0x01},
+{0xEFC6,0x42,0x01},
+{0xEFC7,0xA3,0x01},
+{0xEFC8,0x98,0x01},
+{0xEFC9,0xC0,0x01},
+{0xEFCA,0x30,0x01},
+{0xEFCB,0xA6,0x01},
+{0xEFCC,0x34,0x01},
+{0xEFCD,0xCA,0x01},
+{0xEFCE,0xB1,0x01},
+{0xEFCF,0x8F,0x01},
+{0xEFD0,0x81,0x01},
+{0xEFD1,0xE0,0x01},
+{0xEFD2,0x73,0x01},
+{0xEFD3,0x9D,0x01},
+{0xEFD4,0xE3,0x01},
+{0xEFD5,0x04,0x01},
+{0xEFD6,0x47,0x01},
+{0xEFD7,0x39,0x01},
+{0xEFD8,0xDB,0x01},
+{0xEFD9,0xA9,0x01},
+{0xEFDA,0x8F,0x01},
+{0xEFDB,0x83,0x01},
+{0xEFDC,0x06,0x01},
+{0xEFDD,0xE4,0x01},
+{0xEFDE,0xA0,0x01},
+{0xEFDF,0x03,0x01},
+{0xEFE0,0xFD,0x01},
+{0xEFE1,0xA7,0x01},
+{0xEFE2,0x3F,0x01},
+{0xEFE3,0x03,0x01},
+{0xEFE4,0x62,0x01},
+{0xEFE5,0x10,0x01},
+{0xEFE6,0x84,0x01},
+{0xEFE7,0x12,0x01},
+{0xEFE8,0x04,0x01},
+{0xEFE9,0x00,0x01},
+{0xEFEA,0x00,0x01},
+{0xEFEB,0x00,0x01},
+{0xEFEC,0x00,0x01},
+{0xEFED,0x00,0x01},
+
+
+
+//SHD3 D65+TL84 C01//
+{0xED00,0x9191,0x02},//
+{0xEFEE,0x0B,0x01},
+{0xEFEF,0x12,0x01},
+{0xEFF0,0x11,0x01},
+{0xEFF1,0x88,0x01},
+{0xEFF2,0x2E,0x01},
+{0xEFF3,0x94,0x01},
+{0xEFF4,0x21,0x01},
+{0xEFF5,0x0E,0x01},
+{0xEFF6,0x99,0x01},
+{0xEFF7,0xE8,0x01},
+{0xEFF8,0x44,0x01},
+{0xEFF9,0x10,0x01},
+{0xEFFA,0x22,0x01},
+{0xEFFB,0x50,0x01},
+{0xEFFC,0x7C,0x01},
+{0xEFFD,0xB6,0x01},
+{0xEFFE,0xB3,0x01},
+{0xEFFF,0x1C,0x01},
+{0xF000,0xE3,0x01},
+{0xF001,0x38,0x01},
+{0xF002,0xC7,0x01},
+{0xF003,0x3B,0x01},
+{0xF004,0xF4,0x01},
+{0xF005,0x39,0x01},
+{0xF006,0x10,0x01},
+{0xF007,0x7A,0x01},
+{0xF008,0x8A,0x01},
+{0xF009,0x53,0x01},
+{0xF00A,0x9A,0x01},
+{0xF00B,0xC5,0x01},
+{0xF00C,0x0C,0x01},
+{0xF00D,0x86,0x01},
+{0xF00E,0x31,0x01},
+{0xF00F,0xA5,0x01},
+{0xF010,0x49,0x01},
+{0xF011,0xCE,0x01},
+{0xF012,0x7D,0x01},
+{0xF013,0x94,0x01},
+{0xF014,0xA3,0x01},
+{0xF015,0x19,0x01},
+{0xF016,0xB6,0x01},
+{0xF017,0x38,0x01},
+{0xF018,0xA5,0x01},
+{0xF019,0x28,0x01},
+{0xF01A,0x4F,0x01},
+{0xF01B,0x79,0x01},
+{0xF01C,0x8B,0x01},
+{0xF01D,0x68,0x01},
+{0xF01E,0xB4,0x01},
+{0xF01F,0x43,0x01},
+{0xF020,0x1B,0x01},
+{0xF021,0xBB,0x01},
+{0xF022,0x0C,0x01},
+{0xF023,0x45,0x01},
+{0xF024,0x24,0x01},
+{0xF025,0x17,0x01},
+{0xF026,0x19,0x01},
+{0xF027,0xC9,0x01},
+{0xF028,0x51,0x01},
+{0xF029,0xFA,0x01},
+{0xF02A,0xD2,0x01},
+{0xF02B,0x1B,0x01},
+{0xF02C,0xD3,0x01},
+{0xF02D,0x94,0x01},
+{0xF02E,0xC5,0x01},
+{0xF02F,0x25,0x01},
+{0xF030,0x0A,0x01},
+{0xF031,0x01,0x01},
+{0xF032,0x48,0x01},
+{0xF033,0x43,0x01},
+{0xF034,0x66,0x01},
+{0xF035,0x82,0x01},
+{0xF036,0x96,0x01},
+{0xF037,0xD6,0x01},
+{0xF038,0x98,0x01},
+{0xF039,0xC6,0x01},
+{0xF03A,0x2C,0x01},
+{0xF03B,0x2F,0x01},
+{0xF03C,0x51,0x01},
+{0xF03D,0x48,0x01},
+{0xF03E,0x40,0x01},
+{0xF03F,0x1E,0x01},
+{0xF040,0x42,0x01},
+{0xF041,0x13,0x01},
+{0xF042,0xB5,0x01},
+{0xF043,0xC8,0x01},
+{0xF044,0x06,0x01},
+{0xF045,0x37,0x01},
+{0xF046,0x7B,0x01},
+{0xF047,0x29,0x01},
+{0xF048,0x8A,0x01},
+{0xF049,0x48,0x01},
+{0xF04A,0x32,0x01},
+{0xF04B,0x72,0x01},
+{0xF04C,0x12,0x01},
+{0xF04D,0xA5,0x01},
+{0xF04E,0xFC,0x01},
+{0xF04F,0x65,0x01},
+{0xF050,0x38,0x01},
+{0xF051,0xD4,0x01},
+{0xF052,0xF9,0x01},
+{0xF053,0xCC,0x01},
+{0xF054,0x5B,0x01},
+{0xF055,0xA0,0x01},
+{0xF056,0x82,0x01},
+{0xF057,0x14,0x01},
+{0xF058,0xAA,0x01},
+{0xF059,0xD4,0x01},
+{0xF05A,0x05,0x01},
+{0xF05B,0x35,0x01},
+{0xF05C,0xE2,0x01},
+{0xF05D,0xA9,0x01},
+{0xF05E,0x4F,0x01},
+{0xF05F,0x73,0x01},
+{0xF060,0x4E,0x01},
+{0xF061,0xF3,0x01},
+{0xF062,0x18,0x01},
+{0xF063,0xC3,0x01},
+{0xF064,0x48,0x01},
+{0xF065,0xC6,0x01},
+{0xF066,0x35,0x01},
+{0xF067,0xD4,0x01},
+{0xF068,0x01,0x01},
+{0xF069,0xD0,0x01},
+{0xF06A,0x82,0x01},
+{0xF06B,0xEA,0x01},
+{0xF06C,0xD3,0x01},
+{0xF06D,0x1D,0x01},
+{0xF06E,0xE7,0x01},
+{0xF06F,0x24,0x01},
+{0xF070,0x47,0x01},
+{0xF071,0x3A,0x01},
+{0xF072,0xE5,0x01},
+{0xF073,0xF1,0x01},
+{0xF074,0x0F,0x01},
+{0xF075,0x86,0x01},
+{0xF076,0x0A,0x01},
+{0xF077,0x34,0x01},
+{0xF078,0xA1,0x01},
+{0xF079,0x06,0x01},
+{0xF07A,0x19,0x01},
+{0xF07B,0xE8,0x01},
+{0xF07C,0x40,0x01},
+{0xF07D,0x0D,0x01},
+{0xF07E,0xB2,0x01},
+{0xF07F,0x90,0x01},
+{0xF080,0x86,0x01},
+{0xF081,0x1C,0x01},
+{0xF082,0x04,0x01},
+{0xF083,0x00,0x01},
+{0xF084,0x00,0x01},
+{0xF085,0x00,0x01},
+{0xF086,0x00,0x01},
+{0xF087,0x00,0x01},
+{0xF088,0xBE,0x01},
+{0xF089,0x51,0x01},
+{0xF08A,0x4E,0x01},
+{0xF08B,0x6F,0x01},
+{0xF08C,0x6C,0x01},
+{0xF08D,0x43,0x01},
+{0xF08E,0x1B,0x01},
+{0xF08F,0xDA,0x01},
+{0xF090,0xEC,0x01},
+{0xF091,0x46,0x01},
+{0xF092,0x38,0x01},
+{0xF093,0xBB,0x01},
+{0xF094,0xC1,0x01},
+{0xF095,0xCD,0x01},
+{0xF096,0x69,0x01},
+{0xF097,0x26,0x01},
+{0xF098,0x93,0x01},
+{0xF099,0x98,0x01},
+{0xF09A,0xC1,0x01},
+{0xF09B,0x20,0x01},
+{0xF09C,0x26,0x01},
+{0xF09D,0x32,0x01},
+{0xF09E,0xA5,0x01},
+{0xF09F,0xB1,0x01},
+{0xF0A0,0x8D,0x01},
+{0xF0A1,0x67,0x01},
+{0xF0A2,0x0E,0x01},
+{0xF0A3,0x23,0x01},
+{0xF0A4,0x97,0x01},
+{0xF0A5,0xB0,0x01},
+{0xF0A6,0x6C,0x01},
+{0xF0A7,0x25,0x01},
+{0xF0A8,0x2C,0x01},
+{0xF0A9,0x71,0x01},
+{0xF0AA,0x41,0x01},
+{0xF0AB,0x0C,0x01},
+{0xF0AC,0x69,0x01},
+{0xF0AD,0x14,0x01},
+{0xF0AE,0xB3,0x01},
+{0xF0AF,0x96,0x01},
+{0xF0B0,0xA6,0x01},
+{0xF0B1,0xE8,0x01},
+{0xF0B2,0x64,0x01},
+{0xF0B3,0x26,0x01},
+{0xF0B4,0x3A,0x01},
+{0xF0B5,0x79,0x01},
+{0xF0B6,0x4A,0x01},
+{0xF0B7,0x5B,0x01},
+{0xF0B8,0x18,0x01},
+{0xF0B9,0xA3,0x01},
+{0xF0BA,0x97,0x01},
+{0xF0BB,0xA9,0x01},
+{0xF0BC,0xBC,0x01},
+{0xF0BD,0x24,0x01},
+{0xF0BE,0x23,0x01},
+{0xF0BF,0x13,0x01},
+{0xF0C0,0xE1,0x01},
+{0xF0C1,0xC8,0x01},
+{0xF0C2,0x4C,0x01},
+{0xF0C3,0xAA,0x01},
+{0xF0C4,0xA2,0x01},
+{0xF0C5,0x97,0x01},
+{0xF0C6,0xB6,0x01},
+{0xF0C7,0x14,0x01},
+{0xF0C8,0x05,0x01},
+{0xF0C9,0x24,0x01},
+{0xF0CA,0x06,0x01},
+{0xF0CB,0x09,0x01},
+{0xF0CC,0xC8,0x01},
+{0xF0CD,0x42,0x01},
+{0xF0CE,0x48,0x01},
+{0xF0CF,0x82,0x01},
+{0xF0D0,0x14,0x01},
+{0xF0D1,0xB8,0x01},
+{0xF0D2,0xC0,0x01},
+{0xF0D3,0xE5,0x01},
+{0xF0D4,0x28,0x01},
+{0xF0D5,0x21,0x01},
+{0xF0D6,0x39,0x01},
+{0xF0D7,0x08,0x01},
+{0xF0D8,0x40,0x01},
+{0xF0D9,0x14,0x01},
+{0xF0DA,0x62,0x01},
+{0xF0DB,0x92,0x01},
+{0xF0DC,0xA4,0x01},
+{0xF0DD,0xC4,0x01},
+{0xF0DE,0x05,0x01},
+{0xF0DF,0x30,0x01},
+{0xF0E0,0x58,0x01},
+{0xF0E1,0xA1,0x01},
+{0xF0E2,0x49,0x01},
+{0xF0E3,0x46,0x01},
+{0xF0E4,0x22,0x01},
+{0xF0E5,0xB2,0x01},
+{0xF0E6,0x91,0x01},
+{0xF0E7,0x9A,0x01},
+{0xF0E8,0x58,0x01},
+{0xF0E9,0xA5,0x01},
+{0xF0EA,0x2F,0x01},
+{0xF0EB,0x96,0x01},
+{0xF0EC,0x99,0x01},
+{0xF0ED,0x8B,0x01},
+{0xF0EE,0x54,0x01},
+{0xF0EF,0x74,0x01},
+{0xF0F0,0x32,0x01},
+{0xF0F1,0x13,0x01},
+{0xF0F2,0x9D,0x01},
+{0xF0F3,0x38,0x01},
+{0xF0F4,0xC5,0x01},
+{0xF0F5,0x2D,0x01},
+{0xF0F6,0x90,0x01},
+{0xF0F7,0x59,0x01},
+{0xF0F8,0x4D,0x01},
+{0xF0F9,0x64,0x01},
+{0xF0FA,0xEE,0x01},
+{0xF0FB,0x62,0x01},
+{0xF0FC,0x16,0x01},
+{0xF0FD,0xAE,0x01},
+{0xF0FE,0x84,0x01},
+{0xF0FF,0x25,0x01},
+{0xF100,0x2E,0x01},
+{0xF101,0x8B,0x01},
+{0xF102,0x31,0x01},
+{0xF103,0xCD,0x01},
+{0xF104,0x6F,0x01},
+{0xF105,0x60,0x01},
+{0xF106,0xC3,0x01},
+{0xF107,0x19,0x01},
+{0xF108,0xC7,0x01},
+{0xF109,0x14,0x01},
+{0xF10A,0x26,0x01},
+{0xF10B,0x31,0x01},
+{0xF10C,0x97,0x01},
+{0xF10D,0x41,0x01},
+{0xF10E,0x8D,0x01},
+{0xF10F,0x6D,0x01},
+{0xF110,0x86,0x01},
+{0xF111,0xE3,0x01},
+{0xF112,0x9C,0x01},
+{0xF113,0xE2,0x01},
+{0xF114,0xD8,0x01},
+{0xF115,0x06,0x01},
+{0xF116,0x36,0x01},
+{0xF117,0xB5,0x01},
+{0xF118,0xE9,0x01},
+{0xF119,0x4D,0x01},
+{0xF11A,0x70,0x01},
+{0xF11B,0x68,0x01},
+{0xF11C,0x03,0x01},
+{0xF11D,0x00,0x01},
+{0xF11E,0x00,0x01},
+{0xF11F,0x00,0x01},
+{0xF120,0x00,0x01},
+{0xF121,0x00,0x01},
+
+
+//SHD TH
+{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2
+{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2
+{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2
+{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2
+{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB
+{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB
+{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB
+{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB
+
+//PreWB_offset (for SHD2)
+{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 :
+//PreWB_offset (for SHD3)
+{0x682C,0x000D,0x02}, // SHD_PRER_OFFSET_RB :
+{0x6830,0xFFFE,0x02}, // SHD_PREB_OFFSET_RB :
+
+// CXC/SHD EN
+{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF
+};
+
+static const isx012_regset_t ISX012_Shading_2[] =
+{
+{0x01BC,0x50,0x01}, // CXC OFF SHD OFF
+{0xEB00,0x8282,0x02}, //valid_code
+{0xEB02,0xFE,0x01},
+{0xEB03,0x84,0x01},
+{0xEB04,0x3F,0x01},
+{0xEB05,0x01,0x01},
+{0xEB06,0x50,0x01},
+{0xEB07,0x08,0x01},
+{0xEB08,0x14,0x01},
+{0xEB09,0xFF,0x01},
+{0xEB0A,0x45,0x01},
+{0xEB0B,0x80,0x01},
+{0xEB0C,0x01,0x01},
+{0xEB0D,0x68,0x01},
+{0xEB0E,0x04,0x01},
+{0xEB0F,0x1A,0x01},
+{0xEB10,0x81,0x01},
+{0xEB11,0x86,0x01},
+{0xEB12,0x3F,0x01},
+{0xEB13,0xE1,0x01},
+{0xEB14,0x4F,0x01},
+{0xEB15,0x00,0x01},
+{0xEB16,0x14,0x01},
+{0xEB17,0x02,0x01},
+{0xEB18,0xC5,0x01},
+{0xEB19,0x7F,0x01},
+{0xEB1A,0x11,0x01},
+{0xEB1B,0x60,0x01},
+{0xEB1C,0x00,0x01},
+{0xEB1D,0x1A,0x01},
+{0xEB1E,0x81,0x01},
+{0xEB1F,0x46,0x01},
+{0xEB20,0xA0,0x01},
+{0xEB21,0x01,0x01},
+{0xEB22,0x48,0x01},
+{0xEB23,0x00,0x01},
+{0xEB24,0x12,0x01},
+{0xEB25,0x81,0x01},
+{0xEB26,0x05,0x01},
+{0xEB27,0x20,0x01},
+{0xEB28,0xF1,0x01},
+{0xEB29,0x4F,0x01},
+{0xEB2A,0x00,0x01},
+{0xEB2B,0x14,0x01},
+{0xEB2C,0x82,0x01},
+{0xEB2D,0x85,0x01},
+{0xEB2E,0x80,0x01},
+{0xEB2F,0x21,0x01},
+{0xEB30,0x60,0x01},
+{0xEB31,0x04,0x01},
+{0xEB32,0x12,0x01},
+{0xEB33,0x81,0x01},
+{0xEB34,0x84,0x01},
+{0xEB35,0xE0,0x01},
+{0xEB36,0x00,0x01},
+{0xEB37,0x28,0x01},
+{0xEB38,0x04,0x01},
+{0xEB39,0x0C,0x01},
+{0xEB3A,0x82,0x01},
+{0xEB3B,0x43,0x01},
+{0xEB3C,0x20,0x01},
+{0xEB3D,0x11,0x01},
+{0xEB3E,0x68,0x01},
+{0xEB3F,0x04,0x01},
+{0xEB40,0x1A,0x01},
+{0xEB41,0x82,0x01},
+{0xEB42,0x83,0x01},
+{0xEB43,0xE0,0x01},
+{0xEB44,0x00,0x01},
+{0xEB45,0x20,0x01},
+{0xEB46,0x00,0x01},
+{0xEB47,0x06,0x01},
+{0xEB48,0xFF,0x01},
+{0xEB49,0x41,0x01},
+{0xEB4A,0x80,0x01},
+{0xEB4B,0x10,0x01},
+{0xEB4C,0x30,0x01},
+{0xEB4D,0x08,0x01},
+{0xEB4E,0x14,0x01},
+{0xEB4F,0x02,0x01},
+{0xEB50,0x45,0x01},
+{0xEB51,0xC0,0x01},
+{0xEB52,0x10,0x01},
+{0xEB53,0x30,0x01},
+{0xEB54,0x04,0x01},
+{0xEB55,0x04,0x01},
+{0xEB56,0x01,0x01},
+{0xEB57,0xC0,0x01},
+{0xEB58,0x3F,0x01},
+{0xEB59,0x10,0x01},
+{0xEB5A,0x10,0x01},
+{0xEB5B,0x04,0x01},
+{0xEB5C,0x0A,0x01},
+{0xEB5D,0x80,0x01},
+{0xEB5E,0x03,0x01},
+{0xEB5F,0xE0,0x01},
+{0xEB60,0x10,0x01},
+{0xEB61,0x28,0x01},
+{0xEB62,0x04,0x01},
+{0xEB63,0x0A,0x01},
+{0xEB64,0x81,0x01},
+{0xEB65,0x01,0x01},
+{0xEB66,0x00,0x01},
+{0xEB67,0x10,0x01},
+{0xEB68,0x00,0x01},
+{0xEB69,0x04,0x01},
+{0xEB6A,0x04,0x01},
+{0xEB6B,0x01,0x01},
+{0xEB6C,0x42,0x01},
+{0xEB6D,0xE0,0x01},
+{0xEB6E,0x10,0x01},
+{0xEB6F,0x38,0x01},
+{0xEB70,0xFC,0x01},
+{0xEB71,0x0D,0x01},
+{0xEB72,0x7F,0x01},
+{0xEB73,0x43,0x01},
+{0xEB74,0x60,0x01},
+{0xEB75,0x00,0x01},
+{0xEB76,0x08,0x01},
+{0xEB77,0x08,0x01},
+{0xEB78,0x02,0x01},
+{0xEB79,0x81,0x01},
+{0xEB7A,0x41,0x01},
+{0xEB7B,0x80,0x01},
+{0xEB7C,0x10,0x01},
+{0xEB7D,0x30,0x01},
+{0xEB7E,0x04,0x01},
+{0xEB7F,0x0C,0x01},
+{0xEB80,0x01,0x01},
+{0xEB81,0x43,0x01},
+{0xEB82,0xC0,0x01},
+{0xEB83,0x20,0x01},
+{0xEB84,0x28,0x01},
+{0xEB85,0x08,0x01},
+{0xEB86,0x06,0x01},
+{0xEB87,0x02,0x01},
+{0xEB88,0xC2,0x01},
+{0xEB89,0xA0,0x01},
+{0xEB8A,0x30,0x01},
+{0xEB8B,0x30,0x01},
+{0xEB8C,0x0C,0x01},
+{0xEB8D,0x12,0x01},
+{0xEB8E,0x83,0x01},
+{0xEB8F,0x84,0x01},
+{0xEB90,0x00,0x01},
+{0xEB91,0x21,0x01},
+{0xEB92,0x40,0x01},
+{0xEB93,0x0C,0x01},
+{0xEB94,0x0C,0x01},
+{0xEB95,0x82,0x01},
+{0xEB96,0x03,0x01},
+{0xEB97,0xC1,0x01},
+{0xEB98,0x40,0x01},
+{0xEB99,0x40,0x01},
+{0xEB9A,0x08,0x01},
+{0xEB9B,0x10,0x01},
+{0xEB9C,0x03,0x01},
+{0xEB9D,0xC4,0x01},
+{0xEB9E,0x00,0x01},
+{0xEB9F,0x21,0x01},
+{0xEBA0,0x38,0x01},
+{0xEBA1,0x08,0x01},
+{0xEBA2,0x0E,0x01},
+{0xEBA3,0x82,0x01},
+{0xEBA4,0xC3,0x01},
+{0xEBA5,0x20,0x01},
+{0xEBA6,0x41,0x01},
+{0xEBA7,0x48,0x01},
+{0xEBA8,0x00,0x01},
+{0xEBA9,0x14,0x01},
+{0xEBAA,0x83,0x01},
+{0xEBAB,0x44,0x01},
+{0xEBAC,0x20,0x01},
+{0xEBAD,0x11,0x01},
+{0xEBAE,0x48,0x01},
+{0xEBAF,0x08,0x01},
+{0xEBB0,0x0E,0x01},
+{0xEBB1,0x82,0x01},
+{0xEBB2,0x83,0x01},
+{0xEBB3,0xE0,0x01},
+{0xEBB4,0x30,0x01},
+{0xEBB5,0x48,0x01},
+{0xEBB6,0x10,0x01},
+{0xEBB7,0x12,0x01},
+{0xEBB8,0x00,0x01},
+{0xEBB9,0xC5,0x01},
+{0xEBBA,0x20,0x01},
+{0xEBBB,0x11,0x01},
+{0xEBBC,0x48,0x01},
+{0xEBBD,0x04,0x01},
+{0xEBBE,0x12,0x01},
+{0xEBBF,0x04,0x01},
+{0xEBC0,0x3B,0x01},
+{0xEBC1,0xC1,0x01},
+{0xEBC2,0x1E,0x01},
+{0xEBC3,0xC8,0x01},
+{0xEBC4,0x0F,0x01},
+{0xEBC5,0xF8,0x01},
+{0xEBC6,0x02,0x01},
+{0xEBC7,0xBB,0x01},
+{0xEBC8,0x60,0x01},
+{0xEBC9,0x0F,0x01},
+{0xEBCA,0xB8,0x01},
+{0xEBCB,0x0F,0x01},
+{0xEBCC,0xEA,0x01},
+{0xEBCD,0x83,0x01},
+{0xEBCE,0x3A,0x01},
+{0xEBCF,0xC1,0x01},
+{0xEBD0,0x4E,0x01},
+{0xEBD1,0xB0,0x01},
+{0xEBD2,0x07,0x01},
+{0xEBD3,0xF2,0x01},
+{0xEBD4,0x03,0x01},
+{0xEBD5,0xBE,0x01},
+{0xEBD6,0xC0,0x01},
+{0xEBD7,0x2E,0x01},
+{0xEBD8,0xD8,0x01},
+{0xEBD9,0x03,0x01},
+{0xEBDA,0xEE,0x01},
+{0xEBDB,0x83,0x01},
+{0xEBDC,0xFA,0x01},
+{0xEBDD,0xA0,0x01},
+{0xEBDE,0x2E,0x01},
+{0xEBDF,0xB0,0x01},
+{0xEBE0,0x0B,0x01},
+{0xEBE1,0xEC,0x01},
+{0xEBE2,0x05,0x01},
+{0xEBE3,0xBD,0x01},
+{0xEBE4,0x60,0x01},
+{0xEBE5,0x2F,0x01},
+{0xEBE6,0xD0,0x01},
+{0xEBE7,0x07,0x01},
+{0xEBE8,0xEC,0x01},
+{0xEBE9,0x02,0x01},
+{0xEBEA,0xBC,0x01},
+{0xEBEB,0x40,0x01},
+{0xEBEC,0x2F,0x01},
+{0xEBED,0xD0,0x01},
+{0xEBEE,0x13,0x01},
+{0xEBEF,0xEE,0x01},
+{0xEBF0,0x84,0x01},
+{0xEBF1,0xBB,0x01},
+{0xEBF2,0x00,0x01},
+{0xEBF3,0x1F,0x01},
+{0xEBF4,0xC8,0x01},
+{0xEBF5,0xFF,0x01},
+{0xEBF6,0xEF,0x01},
+{0xEBF7,0x00,0x01},
+{0xEBF8,0x7D,0x01},
+{0xEBF9,0x60,0x01},
+{0xEBFA,0x2F,0x01},
+{0xEBFB,0xD0,0x01},
+{0xEBFC,0x0B,0x01},
+{0xEBFD,0xF4,0x01},
+{0xEBFE,0x85,0x01},
+{0xEBFF,0x7D,0x01},
+{0xEC00,0x61,0x01},
+{0xEC01,0x0F,0x01},
+{0xEC02,0xC0,0x01},
+{0xEC03,0xFF,0x01},
+{0xEC04,0xF7,0x01},
+{0xEC05,0x7F,0x01},
+{0xEC06,0x3D,0x01},
+{0xEC07,0x40,0x01},
+{0xEC08,0xFF,0x01},
+{0xEC09,0xDF,0x01},
+{0xEC0A,0x07,0x01},
+{0xEC0B,0xFA,0x01},
+{0xEC0C,0x81,0x01},
+{0xEC0D,0x3E,0x01},
+{0xEC0E,0x61,0x01},
+{0xEC0F,0x4F,0x01},
+{0xEC10,0xD8,0x01},
+{0xEC11,0x0B,0x01},
+{0xEC12,0xFC,0x01},
+{0xEC13,0xFE,0x01},
+{0xEC14,0x3D,0x01},
+{0xEC15,0xC0,0x01},
+{0xEC16,0xFF,0x01},
+{0xEC17,0xFF,0x01},
+{0xEC18,0x03,0x01},
+{0xEC19,0xFC,0x01},
+{0xEC1A,0x82,0x01},
+{0xEC1B,0xBE,0x01},
+{0xEC1C,0xA0,0x01},
+{0xEC1D,0x6F,0x01},
+{0xEC1E,0xF8,0x01},
+{0xEC1F,0x1B,0x01},
+{0xEC20,0xFE,0x01},
+{0xEC21,0x83,0x01},
+{0xEC22,0xBF,0x01},
+{0xEC23,0xE0,0x01},
+{0xEC24,0x0F,0x01},
+{0xEC25,0x10,0x01},
+{0xEC26,0x00,0x01},
+{0xEC27,0x00,0x01},
+{0xEC28,0x82,0x01},
+{0xEC29,0xC0,0x01},
+{0xEC2A,0x60,0x01},
+{0xEC2B,0x30,0x01},
+{0xEC2C,0x18,0x01},
+{0xEC2D,0x20,0x01},
+{0xEC2E,0x04,0x01},
+{0xEC2F,0x08,0x01},
+{0xEC30,0x81,0x01},
+{0xEC31,0x21,0x01},
+{0xEC32,0x30,0x01},
+{0xEC33,0x08,0x01},
+{0xEC34,0x08,0x01},
+{0xEC35,0x08,0x01},
+{0xEC36,0x82,0x01},
+{0xEC37,0x01,0x01},
+{0xEC38,0x81,0x01},
+{0xEC39,0x50,0x01},
+{0xEC3A,0x08,0x01},
+{0xEC3B,0x14,0x01},
+{0xEC3C,0x02,0x01},
+{0xEC3D,0x09,0x01},
+{0xEC3E,0x41,0x01},
+{0xEC3F,0x42,0x01},
+{0xEC40,0x70,0x01},
+{0xEC41,0x20,0x01},
+{0xEC42,0x0C,0x01},
+{0xEC43,0x06,0x01},
+{0xEC44,0x84,0x01},
+{0xEC45,0x42,0x01},
+{0xEC46,0xE1,0x01},
+{0xEC47,0x40,0x01},
+{0xEC48,0x38,0x01},
+{0xEC49,0x1C,0x01},
+{0xEC4A,0x0C,0x01},
+{0xEC4B,0x07,0x01},
+{0xEC4C,0x03,0x01},
+{0xEC4D,0xA2,0x01},
+{0xEC4E,0x80,0x01},
+{0xEC4F,0x28,0x01},
+{0xEC50,0x18,0x01},
+{0xEC51,0x10,0x01},
+{0xEC52,0x87,0x01},
+{0xEC53,0x43,0x01},
+{0xEC54,0x61,0x01},
+{0xEC55,0x41,0x01},
+{0xEC56,0x48,0x01},
+{0xEC57,0x14,0x01},
+{0xEC58,0x10,0x01},
+{0xEC59,0x07,0x01},
+{0xEC5A,0xC2,0x01},
+{0xEC5B,0x81,0x01},
+{0xEC5C,0x80,0x01},
+{0xEC5D,0x30,0x01},
+{0xEC5E,0x20,0x01},
+{0xEC5F,0x0C,0x01},
+{0xEC60,0x87,0x01},
+{0xEC61,0x83,0x01},
+{0xEC62,0xC1,0x01},
+{0xEC63,0x40,0x01},
+{0xEC64,0x38,0x01},
+{0xEC65,0x14,0x01},
+{0xEC66,0x0A,0x01},
+{0xEC67,0x07,0x01},
+{0xEC68,0xC3,0x01},
+{0xEC69,0xC1,0x01},
+{0xEC6A,0x70,0x01},
+{0xEC6B,0x30,0x01},
+{0xEC6C,0x20,0x01},
+{0xEC6D,0x0C,0x01},
+{0xEC6E,0x08,0x01},
+{0xEC6F,0xC3,0x01},
+{0xEC70,0xE1,0x01},
+{0xEC71,0x60,0x01},
+{0xEC72,0x30,0x01},
+{0xEC73,0x10,0x01},
+{0xEC74,0x0E,0x01},
+{0xEC75,0x85,0x01},
+{0xEC76,0xC2,0x01},
+{0xEC77,0xC1,0x01},
+{0xEC78,0x70,0x01},
+{0xEC79,0x30,0x01},
+{0xEC7A,0x1C,0x01},
+{0xEC7B,0x0C,0x01},
+
+//SHD1(from CO1)
+{0xED02,0xE6,0x01},
+{0xED03,0xD9,0x01},
+{0xED04,0x92,0x01},
+{0xED05,0x7C,0x01},
+{0xED06,0xD8,0x01},
+{0xED07,0xB4,0x01},
+{0xED08,0x1E,0x01},
+{0xED09,0x32,0x01},
+{0xED0A,0x75,0x01},
+{0xED0B,0x67,0x01},
+{0xED0C,0x4A,0x01},
+{0xED0D,0xD7,0x01},
+{0xED0E,0xA9,0x01},
+{0xED0F,0x12,0x01},
+{0xED10,0x76,0x01},
+{0xED11,0xBC,0x01},
+{0xED12,0x34,0x01},
+{0xED13,0x1E,0x01},
+{0xED14,0x37,0x01},
+{0xED15,0xA1,0x01},
+{0xED16,0x87,0x01},
+{0xED17,0x4E,0x01},
+{0xED18,0xDE,0x01},
+{0xED19,0x41,0x01},
+{0xED1A,0xD3,0x01},
+{0xED1B,0x77,0x01},
+{0xED1C,0x8C,0x01},
+{0xED1D,0x94,0x01},
+{0xED1E,0x9C,0x01},
+{0xED1F,0x14,0x01},
+{0xED20,0xC9,0x01},
+{0xED21,0xA6,0x01},
+{0xED22,0x41,0x01},
+{0xED23,0xA2,0x01},
+{0xED24,0xC1,0x01},
+{0xED25,0x8F,0x01},
+{0xED26,0x66,0x01},
+{0xED27,0xE6,0x01},
+{0xED28,0xF3,0x01},
+{0xED29,0x19,0x01},
+{0xED2A,0xFF,0x01},
+{0xED2B,0xB0,0x01},
+{0xED2C,0x66,0x01},
+{0xED2D,0x42,0x01},
+{0xED2E,0xC1,0x01},
+{0xED2F,0x91,0x01},
+{0xED30,0x91,0x01},
+{0xED31,0x75,0x01},
+{0xED32,0xA2,0x01},
+{0xED33,0x74,0x01},
+{0xED34,0x1C,0x01},
+{0xED35,0x0F,0x01},
+{0xED36,0x91,0x01},
+{0xED37,0x26,0x01},
+{0xED38,0x3E,0x01},
+{0xED39,0x87,0x01},
+{0xED3A,0x51,0x01},
+{0xED3B,0x4E,0x01},
+{0xED3C,0x5C,0x01},
+{0xED3D,0x54,0x01},
+{0xED3E,0x83,0x01},
+{0xED3F,0x96,0x01},
+{0xED40,0xD0,0x01},
+{0xED41,0xBC,0x01},
+{0xED42,0xA5,0x01},
+{0xED43,0x35,0x01},
+{0xED44,0x83,0x01},
+{0xED45,0x61,0x01},
+{0xED46,0xCE,0x01},
+{0xED47,0x67,0x01},
+{0xED48,0xF2,0x01},
+{0xED49,0x33,0x01},
+{0xED4A,0x1C,0x01},
+{0xED4B,0x1A,0x01},
+{0xED4C,0xC1,0x01},
+{0xED4D,0x46,0x01},
+{0xED4E,0x3F,0x01},
+{0xED4F,0x83,0x01},
+{0xED50,0xD9,0x01},
+{0xED51,0x0D,0x01},
+{0xED52,0x57,0x01},
+{0xED53,0x06,0x01},
+{0xED54,0x23,0x01},
+{0xED55,0x14,0x01},
+{0xED56,0xAF,0x01},
+{0xED57,0xE4,0x01},
+{0xED58,0x64,0x01},
+{0xED59,0x2A,0x01},
+{0xED5A,0x43,0x01},
+{0xED5B,0x01,0x01},
+{0xED5C,0xCB,0x01},
+{0xED5D,0x56,0x01},
+{0xED5E,0x10,0x01},
+{0xED5F,0x03,0x01},
+{0xED60,0x18,0x01},
+{0xED61,0xE4,0x01},
+{0xED62,0xA8,0x01},
+{0xED63,0xE6,0x01},
+{0xED64,0x41,0x01},
+{0xED65,0x9E,0x01},
+{0xED66,0xE1,0x01},
+{0xED67,0xCE,0x01},
+{0xED68,0x59,0x01},
+{0xED69,0x20,0x01},
+{0xED6A,0xB3,0x01},
+{0xED6B,0x13,0x01},
+{0xED6C,0xA8,0x01},
+{0xED6D,0x74,0x01},
+{0xED6E,0x04,0x01},
+{0xED6F,0x25,0x01},
+{0xED70,0x13,0x01},
+{0xED71,0xE1,0x01},
+{0xED72,0xC8,0x01},
+{0xED73,0x47,0x01},
+{0xED74,0x56,0x01},
+{0xED75,0xD2,0x01},
+{0xED76,0x13,0x01},
+{0xED77,0xAB,0x01},
+{0xED78,0x98,0x01},
+{0xED79,0x25,0x01},
+{0xED7A,0x33,0x01},
+{0xED7B,0x9A,0x01},
+{0xED7C,0x49,0x01},
+{0xED7D,0xCF,0x01},
+{0xED7E,0x64,0x01},
+{0xED7F,0x96,0x01},
+{0xED80,0x73,0x01},
+{0xED81,0x95,0x01},
+{0xED82,0xBC,0x01},
+{0xED83,0xA4,0x01},
+{0xED84,0xC4,0x01},
+{0xED85,0x26,0x01},
+{0xED86,0x0A,0x01},
+{0xED87,0x59,0x01},
+{0xED88,0x08,0x01},
+{0xED89,0x40,0x01},
+{0xED8A,0x00,0x01},
+{0xED8B,0xC2,0x01},
+{0xED8C,0x10,0x01},
+{0xED8D,0x88,0x01},
+{0xED8E,0xB0,0x01},
+{0xED8F,0xA4,0x01},
+{0xED90,0x27,0x01},
+{0xED91,0x59,0x01},
+{0xED92,0xF9,0x01},
+{0xED93,0x0B,0x01},
+{0xED94,0x64,0x01},
+{0xED95,0xA8,0x01},
+{0xED96,0x43,0x01},
+{0xED97,0x19,0x01},
+{0xED98,0xE6,0x01},
+{0xED99,0x68,0x01},
+{0xED9A,0x45,0x01},
+{0xED9B,0x2F,0x01},
+{0xED9C,0x2B,0x01},
+{0xED9D,0xB9,0x01},
+{0xED9E,0xC9,0x01},
+{0xED9F,0x42,0x01},
+{0xEDA0,0x18,0x01},
+{0xEDA1,0x32,0x01},
+{0xEDA2,0x90,0x01},
+{0xEDA3,0x80,0x01},
+{0xEDA4,0x3C,0x01},
+{0xEDA5,0x44,0x01},
+{0xEDA6,0x22,0x01},
+{0xEDA7,0x2F,0x01},
+{0xEDA8,0xF1,0x01},
+{0xEDA9,0x09,0x01},
+{0xEDAA,0x57,0x01},
+{0xEDAB,0x04,0x01},
+{0xEDAC,0x53,0x01},
+{0xEDAD,0x99,0x01},
+{0xEDAE,0xEC,0x01},
+{0xEDAF,0x90,0x01},
+{0xEDB0,0x66,0x01},
+{0xEDB1,0x3C,0x01},
+{0xEDB2,0x6D,0x01},
+{0xEDB3,0xA9,0x01},
+{0xEDB4,0x4C,0x01},
+{0xEDB5,0x50,0x01},
+{0xEDB6,0xA6,0x01},
+{0xEDB7,0x32,0x01},
+{0xEDB8,0x12,0x01},
+{0xEDB9,0x94,0x01},
+{0xEDBA,0x64,0x01},
+{0xEDBB,0xA4,0x01},
+{0xEDBC,0x23,0x01},
+{0xEDBD,0x25,0x01},
+{0xEDBE,0x71,0x01},
+{0xEDBF,0x49,0x01},
+{0xEDC0,0x51,0x01},
+{0xEDC1,0xB4,0x01},
+{0xEDC2,0x02,0x01},
+{0xEDC3,0x17,0x01},
+{0xEDC4,0xCE,0x01},
+{0xEDC5,0x98,0x01},
+{0xEDC6,0x06,0x01},
+{0xEDC7,0x3E,0x01},
+{0xEDC8,0xBC,0x01},
+{0xEDC9,0x31,0x01},
+{0xEDCA,0x50,0x01},
+{0xEDCB,0x63,0x01},
+{0xEDCC,0x86,0x01},
+{0xEDCD,0x63,0x01},
+{0xEDCE,0x16,0x01},
+{0xEDCF,0xC4,0x01},
+{0xEDD0,0x2C,0x01},
+{0xEDD1,0x45,0x01},
+{0xEDD2,0x2C,0x01},
+{0xEDD3,0x43,0x01},
+{0xEDD4,0xB9,0x01},
+{0xEDD5,0x4A,0x01},
+{0xEDD6,0x53,0x01},
+{0xEDD7,0xCE,0x01},
+{0xEDD8,0x82,0x01},
+{0xEDD9,0x96,0x01},
+{0xEDDA,0xC8,0x01},
+{0xEDDB,0x40,0x01},
+{0xEDDC,0x06,0x01},
+{0xEDDD,0x3A,0x01},
+{0xEDDE,0xBE,0x01},
+{0xEDDF,0xC1,0x01},
+{0xEDE0,0xD0,0x01},
+{0xEDE1,0x75,0x01},
+{0xEDE2,0x64,0x01},
+{0xEDE3,0x34,0x01},
+{0xEDE4,0x9B,0x01},
+{0xEDE5,0xFE,0x01},
+{0xEDE6,0x4C,0x01},
+{0xEDE7,0xA6,0x01},
+{0xEDE8,0x39,0x01},
+{0xEDE9,0x7D,0x01},
+{0xEDEA,0x89,0x01},
+{0xEDEB,0x8D,0x01},
+{0xEDEC,0x5D,0x01},
+{0xEDED,0x4A,0x01},
+{0xEDEE,0xE3,0x01},
+{0xEDEF,0x97,0x01},
+{0xEDF0,0xDA,0x01},
+{0xEDF1,0x50,0x01},
+{0xEDF2,0xE6,0x01},
+{0xEDF3,0x3A,0x01},
+{0xEDF4,0xB3,0x01},
+{0xEDF5,0x39,0x01},
+{0xEDF6,0x50,0x01},
+{0xEDF7,0x76,0x01},
+{0xEDF8,0x7A,0x01},
+{0xEDF9,0xF4,0x01},
+{0xEDFA,0x9E,0x01},
+{0xEDFB,0x2A,0x01},
+{0xEDFC,0x61,0x01},
+{0xEDFD,0x87,0x01},
+{0xEDFE,0x46,0x01},
+{0xEDFF,0xC0,0x01},
+{0xEE00,0x99,0x01},
+{0xEE01,0xD0,0x01},
+{0xEE02,0x6B,0x01},
+{0xEE03,0x02,0x01},
+{0xEE04,0x94,0x01},
+{0xEE05,0x1A,0x01},
+{0xEE06,0xFD,0x01},
+{0xEE07,0xB8,0x01},
+{0xEE08,0xE6,0x01},
+{0xEE09,0x40,0x01},
+{0xEE0A,0xC0,0x01},
+{0xEE0B,0xF1,0x01},
+{0xEE0C,0xD0,0x01},
+{0xEE0D,0x75,0x01},
+{0xEE0E,0x80,0x01},
+{0xEE0F,0xE4,0x01},
+{0xEE10,0x9E,0x01},
+{0xEE11,0x33,0x01},
+{0xEE12,0xE1,0x01},
+{0xEE13,0xA7,0x01},
+{0xEE14,0x4B,0x01},
+{0xEE15,0xFD,0x01},
+{0xEE16,0x21,0x01},
+{0xEE17,0x53,0x01},
+{0xEE18,0x7C,0x01},
+{0xEE19,0xAE,0x01},
+{0xEE1A,0x64,0x01},
+{0xEE1B,0x9E,0x01},
+{0xEE1C,0x26,0x01},
+{0xEE1D,0x89,0x01},
+{0xEE1E,0xC7,0x01},
+{0xEE1F,0x49,0x01},
+{0xEE20,0xE4,0x01},
+{0xEE21,0x99,0x01},
+{0xEE22,0x12,0x01},
+{0xEE23,0x7D,0x01},
+{0xEE24,0xCA,0x01},
+{0xEE25,0xB4,0x01},
+{0xEE26,0x9F,0x01},
+{0xEE27,0x37,0x01},
+{0xEE28,0xC5,0x01},
+{0xEE29,0x47,0x01},
+{0xEE2A,0x4D,0x01},
+{0xEE2B,0xC2,0x01},
+{0xEE2C,0x19,0x01},
+{0xEE2D,0x0F,0x01},
+{0xEE2E,0x73,0x01},
+{0xEE2F,0xE2,0x01},
+{0xEE30,0x13,0x01},
+{0xEE31,0x1C,0x01},
+{0xEE32,0xF5,0x01},
+{0xEE33,0xE0,0x01},
+{0xEE34,0xC6,0x01},
+{0xEE35,0x3B,0x01},
+{0xEE36,0xB6,0x01},
+{0xEE37,0xB1,0x01},
+{0xEE38,0xCE,0x01},
+{0xEE39,0x6D,0x01},
+{0xEE3A,0xB8,0x01},
+{0xEE3B,0xF3,0x01},
+{0xEE3C,0x9B,0x01},
+{0xEE3D,0xF2,0x01},
+{0xEE3E,0x18,0x01},
+{0xEE3F,0x27,0x01},
+{0xEE40,0x3D,0x01},
+{0xEE41,0xBF,0x01},
+{0xEE42,0xE9,0x01},
+{0xEE43,0xCE,0x01},
+{0xEE44,0x6E,0x01},
+{0xEE45,0xBA,0x01},
+{0xEE46,0x83,0x01},
+{0xEE47,0x9A,0x01},
+{0xEE48,0xE4,0x01},
+{0xEE49,0x50,0x01},
+{0xEE4A,0x66,0x01},
+{0xEE4B,0x36,0x01},
+{0xEE4C,0x8A,0x01},
+{0xEE4D,0x29,0x01},
+{0xEE4E,0x4D,0x01},
+{0xEE4F,0x61,0x01},
+{0xEE50,0x3A,0x01},
+{0xEE51,0xA3,0x01},
+{0xEE52,0x18,0x01},
+{0xEE53,0xD2,0x01},
+{0xEE54,0x50,0x01},
+{0xEE55,0x26,0x01},
+{0xEE56,0x36,0x01},
+{0xEE57,0xA8,0x01},
+{0xEE58,0x21,0x01},
+{0xEE59,0xCE,0x01},
+{0xEE5A,0x6E,0x01},
+{0xEE5B,0xB2,0x01},
+{0xEE5C,0x03,0x01},
+{0xEE5D,0x9A,0x01},
+{0xEE5E,0xE0,0x01},
+{0xEE5F,0x1C,0x01},
+{0xEE60,0x46,0x01},
+{0xEE61,0x34,0x01},
+{0xEE62,0x72,0x01},
+{0xEE63,0x41,0x01},
+{0xEE64,0x8C,0x01},
+{0xEE65,0x58,0x01},
+{0xEE66,0xE8,0x01},
+{0xEE67,0xC2,0x01},
+{0xEE68,0x95,0x01},
+{0xEE69,0xB5,0x01},
+{0xEE6A,0x88,0x01},
+{0xEE6B,0x65,0x01},
+{0xEE6C,0x2E,0x01},
+{0xEE6D,0x72,0x01},
+{0xEE6E,0x39,0x01},
+{0xEE6F,0x8C,0x01},
+{0xEE70,0x62,0x01},
+{0xEE71,0x48,0x01},
+{0xEE72,0x83,0x01},
+{0xEE73,0x1A,0x01},
+{0xEE74,0xE4,0x01},
+{0xEE75,0x28,0x01},
+{0xEE76,0x06,0x01},
+{0xEE77,0x35,0x01},
+{0xEE78,0x6A,0x01},
+{0xEE79,0xF9,0x01},
+{0xEE7A,0x4B,0x01},
+{0xEE7B,0x53,0x01},
+{0xEE7C,0xB8,0x01},
+{0xEE7D,0x92,0x01},
+{0xEE7E,0x13,0x01},
+{0xEE7F,0xA2,0x01},
+{0xEE80,0xCC,0x01},
+{0xEE81,0x64,0x01},
+{0xEE82,0x27,0x01},
+{0xEE83,0x3B,0x01},
+{0xEE84,0x29,0x01},
+{0xEE85,0x0A,0x01},
+{0xEE86,0x54,0x01},
+{0xEE87,0xBC,0x01},
+{0xEE88,0xF2,0x01},
+{0xEE89,0x96,0x01},
+{0xEE8A,0xC1,0x01},
+{0xEE8B,0x40,0x01},
+{0xEE8C,0xA6,0x01},
+{0xEE8D,0x35,0x01},
+{0xEE8E,0x7A,0x01},
+{0xEE8F,0xB1,0x01},
+{0xEE90,0x8C,0x01},
+{0xEE91,0x54,0x01},
+{0xEE92,0xC8,0x01},
+{0xEE93,0xF2,0x01},
+{0xEE94,0x92,0x01},
+{0xEE95,0x9D,0x01},
+{0xEE96,0x64,0x01},
+{0xEE97,0xE4,0x01},
+{0xEE98,0x23,0x01},
+{0xEE99,0x13,0x01},
+{0xEE9A,0xA9,0x01},
+{0xEE9B,0x48,0x01},
+{0xEE9C,0x47,0x01},
+{0xEE9D,0x40,0x01},
+{0xEE9E,0x42,0x01},
+{0xEE9F,0x13,0x01},
+{0xEEA0,0x9F,0x01},
+{0xEEA1,0x58,0x01},
+{0xEEA2,0xE5,0x01},
+{0xEEA3,0x2C,0x01},
+{0xEEA4,0x7F,0x01},
+{0xEEA5,0xD9,0x01},
+{0xEEA6,0x8C,0x01},
+{0xEEA7,0x5B,0x01},
+{0xEEA8,0x12,0x01},
+{0xEEA9,0x43,0x01},
+{0xEEAA,0x14,0x01},
+{0xEEAB,0xAA,0x01},
+{0xEEAC,0x80,0x01},
+{0xEEAD,0x04,0x01},
+{0xEEAE,0x25,0x01},
+{0xEEAF,0x06,0x01},
+{0xEEB0,0x51,0x01},
+{0xEEB1,0x08,0x01},
+{0xEEB2,0x40,0x01},
+{0xEEB3,0x00,0x01},
+{0xEEB4,0xB2,0x01},
+{0xEEB5,0x10,0x01},
+{0xEEB6,0x86,0x01},
+{0xEEB7,0x98,0x01},
+{0xEEB8,0x64,0x01},
+{0xEEB9,0x25,0x01},
+{0xEEBA,0x4A,0x01},
+{0xEEBB,0xB9,0x01},
+{0xEEBC,0x0A,0x01},
+{0xEEBD,0x5D,0x01},
+{0xEEBE,0x1C,0x01},
+{0xEEBF,0x13,0x01},
+{0xEEC0,0x97,0x01},
+{0xEEC1,0xC4,0x01},
+{0xEEC2,0x18,0x01},
+{0xEEC3,0x85,0x01},
+{0xEEC4,0x2A,0x01},
+{0xEEC5,0x21,0x01},
+{0xEEC6,0x41,0x01},
+{0xEEC7,0xC9,0x01},
+{0xEEC8,0x41,0x01},
+{0xEEC9,0x12,0x01},
+{0xEECA,0x02,0x01},
+{0xEECB,0x10,0x01},
+{0xEECC,0x80,0x01},
+{0xEECD,0x2C,0x01},
+{0xEECE,0x64,0x01},
+{0xEECF,0x21,0x01},
+{0xEED0,0x27,0x01},
+{0xEED1,0x61,0x01},
+{0xEED2,0xC9,0x01},
+{0xEED3,0x52,0x01},
+{0xEED4,0xB0,0x01},
+{0xEED5,0x42,0x01},
+{0xEED6,0x17,0x01},
+{0xEED7,0xC8,0x01},
+{0xEED8,0x04,0x01},
+{0xEED9,0xE6,0x01},
+{0xEEDA,0x32,0x01},
+{0xEEDB,0x58,0x01},
+{0xEEDC,0x29,0x01},
+{0xEEDD,0xCB,0x01},
+{0xEEDE,0x4C,0x01},
+{0xEEDF,0x74,0x01},
+{0xEEE0,0x92,0x01},
+{0xEEE1,0x91,0x01},
+{0xEEE2,0x8E,0x01},
+{0xEEE3,0x48,0x01},
+{0xEEE4,0x84,0x01},
+{0xEEE5,0x22,0x01},
+{0xEEE6,0x1D,0x01},
+{0xEEE7,0x01,0x01},
+{0xEEE8,0xC9,0x01},
+{0xEEE9,0x4D,0x01},
+{0xEEEA,0x7E,0x01},
+{0xEEEB,0x82,0x01},
+{0xEEEC,0x15,0x01},
+{0xEEED,0xB5,0x01},
+{0xEEEE,0x04,0x01},
+{0xEEEF,0xE6,0x01},
+{0xEEF0,0x33,0x01},
+{0xEEF1,0x99,0x01},
+{0xEEF2,0x69,0x01},
+{0xEEF3,0x0D,0x01},
+{0xEEF4,0x5D,0x01},
+{0xEEF5,0x06,0x01},
+{0xEEF6,0x33,0x01},
+{0xEEF7,0x15,0x01},
+{0xEEF8,0xAF,0x01},
+{0xEEF9,0xEC,0x01},
+{0xEEFA,0xA4,0x01},
+{0xEEFB,0x28,0x01},
+{0xEEFC,0x35,0x01},
+{0xEEFD,0xE9,0x01},
+{0xEEFE,0x09,0x01},
+{0xEEFF,0x4F,0x01},
+{0xEF00,0x8E,0x01},
+{0xEF01,0x02,0x01},
+{0xEF02,0x95,0x01},
+{0xEF03,0xB1,0x01},
+{0xEF04,0xC4,0x01},
+{0xEF05,0x25,0x01},
+{0xEF06,0x31,0x01},
+{0xEF07,0x94,0x01},
+{0xEF08,0xB1,0x01},
+{0xEF09,0x4D,0x01},
+{0xEF0A,0x6C,0x01},
+{0xEF0B,0x94,0x01},
+{0xEF0C,0x43,0x01},
+{0xEF0D,0x99,0x01},
+{0xEF0E,0xD4,0x01},
+{0xEF0F,0xEC,0x01},
+{0xEF10,0xC5,0x01},
+{0xEF11,0x31,0x01},
+{0xEF12,0x69,0x01},
+{0xEF13,0xC9,0x01},
+{0xEF14,0x0B,0x01},
+{0xEF15,0x58,0x01},
+{0xEF16,0xE6,0x01},
+{0xEF17,0x52,0x01},
+{0xEF18,0x16,0x01},
+{0xEF19,0xBE,0x01},
+{0xEF1A,0xD4,0x01},
+{0xEF1B,0x45,0x01},
+{0xEF1C,0x32,0x01},
+{0xEF1D,0x8E,0x01},
+{0xEF1E,0x79,0x01},
+{0xEF1F,0x4D,0x01},
+{0xEF20,0x6A,0x01},
+{0xEF21,0xA4,0x01},
+{0xEF22,0x83,0x01},
+{0xEF23,0x1C,0x01},
+{0xEF24,0xF2,0x01},
+{0xEF25,0xDC,0x01},
+{0xEF26,0x26,0x01},
+{0xEF27,0x3A,0x01},
+{0xEF28,0xA3,0x01},
+{0xEF29,0xE1,0x01},
+{0xEF2A,0x4D,0x01},
+{0xEF2B,0x65,0x01},
+{0xEF2C,0x5C,0x01},
+{0xEF2D,0xC3,0x01},
+{0xEF2E,0x98,0x01},
+{0xEF2F,0xD4,0x01},
+{0xEF30,0x3C,0x01},
+{0xEF31,0xE6,0x01},
+{0xEF32,0x35,0x01},
+{0xEF33,0x9D,0x01},
+{0xEF34,0x09,0x01},
+{0xEF35,0x8E,0x01},
+{0xEF36,0x6B,0x01},
+{0xEF37,0xAC,0x01},
+{0xEF38,0xE3,0x01},
+{0xEF39,0x9B,0x01},
+{0xEF3A,0xF4,0x01},
+{0xEF3B,0x34,0x01},
+{0xEF3C,0x07,0x01},
+{0xEF3D,0x3E,0x01},
+{0xEF3E,0xDA,0x01},
+{0xEF3F,0xC1,0x01},
+{0xEF40,0x8F,0x01},
+{0xEF41,0x74,0x01},
+{0xEF42,0xEA,0x01},
+{0xEF43,0x13,0x01},
+{0xEF44,0x9C,0x01},
+{0xEF45,0xF4,0x01},
+{0xEF46,0xF0,0x01},
+{0xEF47,0xA6,0x01},
+{0xEF48,0x3C,0x01},
+{0xEF49,0xC0,0x01},
+{0xEF4A,0x49,0x01},
+{0xEF4B,0x0F,0x01},
+{0xEF4C,0x72,0x01},
+{0xEF4D,0xEA,0x01},
+{0xEF4E,0xD3,0x01},
+{0xEF4F,0x9C,0x01},
+{0xEF50,0xFE,0x01},
+{0xEF51,0x04,0x01},
+{0xEF52,0xA7,0x01},
+{0xEF53,0x3D,0x01},
+
+//SHD2 CW+TL84 33:66
+
+{0xED00,0x9191,0x02},//
+{0xEF54,0x2F,0x01},
+{0xEF55,0xF2,0x01},
+{0xEF56,0x51,0x01},
+{0xEF57,0x8D,0x01},
+{0xEF58,0x50,0x01},
+{0xEF59,0x74,0x01},
+{0xEF5A,0xA2,0x01},
+{0xEF5B,0x14,0x01},
+{0xEF5C,0xE1,0x01},
+{0xEF5D,0xC8,0x01},
+{0xEF5E,0x47,0x01},
+{0xEF5F,0x2E,0x01},
+{0xEF60,0xD2,0x01},
+{0xEF61,0x10,0x01},
+{0xEF62,0x80,0x01},
+{0xEF63,0xC8,0x01},
+{0xEF64,0x13,0x01},
+{0xEF65,0x9D,0x01},
+{0xEF66,0xE5,0x01},
+{0xEF67,0x48,0x01},
+{0xEF68,0x87,0x01},
+{0xEF69,0x3C,0x01},
+{0xEF6A,0xFE,0x01},
+{0xEF6B,0xC9,0x01},
+{0xEF6C,0x50,0x01},
+{0xEF6D,0x7D,0x01},
+{0xEF6E,0x96,0x01},
+{0xEF6F,0x83,0x01},
+{0xEF70,0x9A,0x01},
+{0xEF71,0xC6,0x01},
+{0xEF72,0x10,0x01},
+{0xEF73,0xA6,0x01},
+{0xEF74,0x31,0x01},
+{0xEF75,0xA5,0x01},
+{0xEF76,0x61,0x01},
+{0xEF77,0xCE,0x01},
+{0xEF78,0x7F,0x01},
+{0xEF79,0xA4,0x01},
+{0xEF7A,0xD3,0x01},
+{0xEF7B,0x19,0x01},
+{0xEF7C,0xB6,0x01},
+{0xEF7D,0x38,0x01},
+{0xEF7E,0xA5,0x01},
+{0xEF7F,0x28,0x01},
+{0xEF80,0x4E,0x01},
+{0xEF81,0x69,0x01},
+{0xEF82,0x4B,0x01},
+{0xEF83,0x68,0x01},
+{0xEF84,0xBA,0x01},
+{0xEF85,0x93,0x01},
+{0xEF86,0x1B,0x01},
+{0xEF87,0xBC,0x01},
+{0xEF88,0x0C,0x01},
+{0xEF89,0x65,0x01},
+{0xEF8A,0x24,0x01},
+{0xEF8B,0x17,0x01},
+{0xEF8C,0x19,0x01},
+{0xEF8D,0x49,0x01},
+{0xEF8E,0x51,0x01},
+{0xEF8F,0xF6,0x01},
+{0xEF90,0xE2,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD5,0x01},
+{0xEF93,0x98,0x01},
+{0xEF94,0xC5,0x01},
+{0xEF95,0x25,0x01},
+{0xEF96,0x0B,0x01},
+{0xEF97,0x01,0x01},
+{0xEF98,0x48,0x01},
+{0xEF99,0x43,0x01},
+{0xEF9A,0x64,0x01},
+{0xEF9B,0x72,0x01},
+{0xEF9C,0x96,0x01},
+{0xEF9D,0xD6,0x01},
+{0xEF9E,0xA8,0x01},
+{0xEF9F,0xE6,0x01},
+{0xEFA0,0x2C,0x01},
+{0xEFA1,0x30,0x01},
+{0xEFA2,0x51,0x01},
+{0xEFA3,0x48,0x01},
+{0xEFA4,0x40,0x01},
+{0xEFA5,0x1C,0x01},
+{0xEFA6,0x22,0x01},
+{0xEFA7,0x93,0x01},
+{0xEFA8,0xB4,0x01},
+{0xEFA9,0xC8,0x01},
+{0xEFAA,0xA6,0x01},
+{0xEFAB,0x37,0x01},
+{0xEFAC,0x7C,0x01},
+{0xEFAD,0x29,0x01},
+{0xEFAE,0x8A,0x01},
+{0xEFAF,0x48,0x01},
+{0xEFB0,0x30,0x01},
+{0xEFB1,0x62,0x01},
+{0xEFB2,0x12,0x01},
+{0xEFB3,0xA4,0x01},
+{0xEFB4,0xF8,0x01},
+{0xEFB5,0x65,0x01},
+{0xEFB6,0x38,0x01},
+{0xEFB7,0xDB,0x01},
+{0xEFB8,0x11,0x01},
+{0xEFB9,0x0D,0x01},
+{0xEFBA,0x5C,0x01},
+{0xEFBB,0xA0,0x01},
+{0xEFBC,0x72,0x01},
+{0xEFBD,0x94,0x01},
+{0xEFBE,0xA9,0x01},
+{0xEFBF,0xD0,0x01},
+{0xEFC0,0x05,0x01},
+{0xEFC1,0x35,0x01},
+{0xEFC2,0xE5,0x01},
+{0xEFC3,0x11,0x01},
+{0xEFC4,0xD0,0x01},
+{0xEFC5,0x74,0x01},
+{0xEFC6,0x52,0x01},
+{0xEFC7,0x03,0x01},
+{0xEFC8,0x19,0x01},
+{0xEFC9,0xC3,0x01},
+{0xEFCA,0x48,0x01},
+{0xEFCB,0xC6,0x01},
+{0xEFCC,0x35,0x01},
+{0xEFCD,0xD7,0x01},
+{0xEFCE,0x41,0x01},
+{0xEFCF,0x10,0x01},
+{0xEFD0,0x88,0x01},
+{0xEFD1,0x06,0x01},
+{0xEFD2,0x54,0x01},
+{0xEFD3,0x9E,0x01},
+{0xEFD4,0xE9,0x01},
+{0xEFD5,0x30,0x01},
+{0xEFD6,0xC7,0x01},
+{0xEFD7,0x3A,0x01},
+{0xEFD8,0xEA,0x01},
+{0xEFD9,0x41,0x01},
+{0xEFDA,0x50,0x01},
+{0xEFDB,0x8A,0x01},
+{0xEFDC,0x4E,0x01},
+{0xEFDD,0xB4,0x01},
+{0xEFDE,0x22,0x01},
+{0xEFDF,0x10,0x01},
+{0xEFE0,0x51,0x01},
+{0xEFE1,0x48,0x01},
+{0xEFE2,0x42,0x01},
+{0xEFE3,0x19,0x01},
+{0xEFE4,0x2A,0x01},
+{0xEFE5,0x91,0x01},
+{0xEFE6,0x8B,0x01},
+{0xEFE7,0x5A,0x01},
+{0xEFE8,0x04,0x01},
+{0xEFE9,0x00,0x01},
+{0xEFEA,0x00,0x01},
+{0xEFEB,0x00,0x01},
+{0xEFEC,0x00,0x01},
+{0xEFED,0x00,0x01},
+
+
+
+//SHD3 D65+TL84 C01//
+{0xED00,0x9191,0x02},//
+{0xEFEE,0x21,0x01},
+{0xEFEF,0xAA,0x01},
+{0xEFF0,0xD1,0x01},
+{0xEFF1,0x8B,0x01},
+{0xEFF2,0x4A,0x01},
+{0xEFF3,0x64,0x01},
+{0xEFF4,0x22,0x01},
+{0xEFF5,0x15,0x01},
+{0xEFF6,0xD9,0x01},
+{0xEFF7,0x28,0x01},
+{0xEFF8,0x47,0x01},
+{0xEFF9,0x26,0x01},
+{0xEFFA,0xA2,0x01},
+{0xEFFB,0x50,0x01},
+{0xEFFC,0x7F,0x01},
+{0xEFFD,0xC6,0x01},
+{0xEFFE,0x23,0x01},
+{0xEFFF,0x9D,0x01},
+{0xF000,0xE6,0x01},
+{0xF001,0x54,0x01},
+{0xF002,0xE7,0x01},
+{0xF003,0x3C,0x01},
+{0xF004,0x00,0x01},
+{0xF005,0xBA,0x01},
+{0xF006,0xD0,0x01},
+{0xF007,0x7C,0x01},
+{0xF008,0x98,0x01},
+{0xF009,0xA3,0x01},
+{0xF00A,0x9A,0x01},
+{0xF00B,0xC7,0x01},
+{0xF00C,0x18,0x01},
+{0xF00D,0x06,0x01},
+{0xF00E,0x32,0x01},
+{0xF00F,0xAA,0x01},
+{0xF010,0x81,0x01},
+{0xF011,0x8E,0x01},
+{0xF012,0x80,0x01},
+{0xF013,0xA4,0x01},
+{0xF014,0xE3,0x01},
+{0xF015,0x19,0x01},
+{0xF016,0xB7,0x01},
+{0xF017,0x3C,0x01},
+{0xF018,0xC5,0x01},
+{0xF019,0x28,0x01},
+{0xF01A,0x51,0x01},
+{0xF01B,0x89,0x01},
+{0xF01C,0x8B,0x01},
+{0xF01D,0x69,0x01},
+{0xF01E,0xC4,0x01},
+{0xF01F,0x93,0x01},
+{0xF020,0x9B,0x01},
+{0xF021,0xBC,0x01},
+{0xF022,0x10,0x01},
+{0xF023,0x65,0x01},
+{0xF024,0x24,0x01},
+{0xF025,0x18,0x01},
+{0xF026,0x21,0x01},
+{0xF027,0x09,0x01},
+{0xF028,0x52,0x01},
+{0xF029,0x00,0x01},
+{0xF02A,0x33,0x01},
+{0xF02B,0x9C,0x01},
+{0xF02C,0xD5,0x01},
+{0xF02D,0x9C,0x01},
+{0xF02E,0xE5,0x01},
+{0xF02F,0x25,0x01},
+{0xF030,0x0A,0x01},
+{0xF031,0x01,0x01},
+{0xF032,0x88,0x01},
+{0xF033,0x43,0x01},
+{0xF034,0x68,0x01},
+{0xF035,0xA2,0x01},
+{0xF036,0x16,0x01},
+{0xF037,0xD9,0x01},
+{0xF038,0xAC,0x01},
+{0xF039,0x06,0x01},
+{0xF03A,0x2D,0x01},
+{0xF03B,0x30,0x01},
+{0xF03C,0x51,0x01},
+{0xF03D,0x48,0x01},
+{0xF03E,0x40,0x01},
+{0xF03F,0x1E,0x01},
+{0xF040,0x42,0x01},
+{0xF041,0x93,0x01},
+{0xF042,0xB6,0x01},
+{0xF043,0xDC,0x01},
+{0xF044,0xC6,0x01},
+{0xF045,0x37,0x01},
+{0xF046,0x7E,0x01},
+{0xF047,0x31,0x01},
+{0xF048,0xCA,0x01},
+{0xF049,0x48,0x01},
+{0xF04A,0x32,0x01},
+{0xF04B,0x72,0x01},
+{0xF04C,0x92,0x01},
+{0xF04D,0xA5,0x01},
+{0xF04E,0x08,0x01},
+{0xF04F,0x26,0x01},
+{0xF050,0x39,0x01},
+{0xF051,0xDC,0x01},
+{0xF052,0x19,0x01},
+{0xF053,0x8D,0x01},
+{0xF054,0x5C,0x01},
+{0xF055,0xA4,0x01},
+{0xF056,0x92,0x01},
+{0xF057,0x14,0x01},
+{0xF058,0xAB,0x01},
+{0xF059,0xE0,0x01},
+{0xF05A,0xA5,0x01},
+{0xF05B,0x35,0x01},
+{0xF05C,0xEA,0x01},
+{0xF05D,0x09,0x01},
+{0xF05E,0x10,0x01},
+{0xF05F,0x75,0x01},
+{0xF060,0x58,0x01},
+{0xF061,0x33,0x01},
+{0xF062,0x99,0x01},
+{0xF063,0xC4,0x01},
+{0xF064,0x58,0x01},
+{0xF065,0x66,0x01},
+{0xF066,0x36,0x01},
+{0xF067,0xDB,0x01},
+{0xF068,0x61,0x01},
+{0xF069,0xD0,0x01},
+{0xF06A,0x86,0x01},
+{0xF06B,0x02,0x01},
+{0xF06C,0x64,0x01},
+{0xF06D,0x1E,0x01},
+{0xF06E,0xEB,0x01},
+{0xF06F,0x40,0x01},
+{0xF070,0x47,0x01},
+{0xF071,0x3B,0x01},
+{0xF072,0xEE,0x01},
+{0xF073,0x51,0x01},
+{0xF074,0x10,0x01},
+{0xF075,0x8A,0x01},
+{0xF076,0x36,0x01},
+{0xF077,0x54,0x01},
+{0xF078,0x22,0x01},
+{0xF079,0x0E,0x01},
+{0xF07A,0x51,0x01},
+{0xF07B,0x88,0x01},
+{0xF07C,0x42,0x01},
+{0xF07D,0x1A,0x01},
+{0xF07E,0x2A,0x01},
+{0xF07F,0x11,0x01},
+{0xF080,0x8B,0x01},
+{0xF081,0x48,0x01},
+{0xF082,0x04,0x01},
+{0xF083,0x00,0x01},
+{0xF084,0x00,0x01},
+{0xF085,0x00,0x01},
+{0xF086,0x00,0x01},
+{0xF087,0x00,0x01},
+{0xF088,0xBE,0x01},
+{0xF089,0x51,0x01},
+{0xF08A,0x4E,0x01},
+{0xF08B,0x6F,0x01},
+{0xF08C,0x6C,0x01},
+{0xF08D,0x43,0x01},
+{0xF08E,0x1B,0x01},
+{0xF08F,0xDA,0x01},
+{0xF090,0xEC,0x01},
+{0xF091,0x46,0x01},
+{0xF092,0x38,0x01},
+{0xF093,0xBB,0x01},
+{0xF094,0xC1,0x01},
+{0xF095,0xCD,0x01},
+{0xF096,0x69,0x01},
+{0xF097,0x26,0x01},
+{0xF098,0x93,0x01},
+{0xF099,0x98,0x01},
+{0xF09A,0xC1,0x01},
+{0xF09B,0x20,0x01},
+{0xF09C,0x26,0x01},
+{0xF09D,0x32,0x01},
+{0xF09E,0xA5,0x01},
+{0xF09F,0xB1,0x01},
+{0xF0A0,0x8D,0x01},
+{0xF0A1,0x67,0x01},
+{0xF0A2,0x0E,0x01},
+{0xF0A3,0x23,0x01},
+{0xF0A4,0x97,0x01},
+{0xF0A5,0xB0,0x01},
+{0xF0A6,0x6C,0x01},
+{0xF0A7,0x25,0x01},
+{0xF0A8,0x2C,0x01},
+{0xF0A9,0x71,0x01},
+{0xF0AA,0x41,0x01},
+{0xF0AB,0x0C,0x01},
+{0xF0AC,0x69,0x01},
+{0xF0AD,0x14,0x01},
+{0xF0AE,0xB3,0x01},
+{0xF0AF,0x96,0x01},
+{0xF0B0,0xA6,0x01},
+{0xF0B1,0xE8,0x01},
+{0xF0B2,0x64,0x01},
+{0xF0B3,0x26,0x01},
+{0xF0B4,0x3A,0x01},
+{0xF0B5,0x79,0x01},
+{0xF0B6,0x4A,0x01},
+{0xF0B7,0x5B,0x01},
+{0xF0B8,0x18,0x01},
+{0xF0B9,0xA3,0x01},
+{0xF0BA,0x97,0x01},
+{0xF0BB,0xA9,0x01},
+{0xF0BC,0xBC,0x01},
+{0xF0BD,0x24,0x01},
+{0xF0BE,0x23,0x01},
+{0xF0BF,0x13,0x01},
+{0xF0C0,0xE1,0x01},
+{0xF0C1,0xC8,0x01},
+{0xF0C2,0x4C,0x01},
+{0xF0C3,0xAA,0x01},
+{0xF0C4,0xA2,0x01},
+{0xF0C5,0x97,0x01},
+{0xF0C6,0xB6,0x01},
+{0xF0C7,0x14,0x01},
+{0xF0C8,0x05,0x01},
+{0xF0C9,0x24,0x01},
+{0xF0CA,0x06,0x01},
+{0xF0CB,0x09,0x01},
+{0xF0CC,0xC8,0x01},
+{0xF0CD,0x42,0x01},
+{0xF0CE,0x48,0x01},
+{0xF0CF,0x82,0x01},
+{0xF0D0,0x14,0x01},
+{0xF0D1,0xB8,0x01},
+{0xF0D2,0xC0,0x01},
+{0xF0D3,0xE5,0x01},
+{0xF0D4,0x28,0x01},
+{0xF0D5,0x21,0x01},
+{0xF0D6,0x39,0x01},
+{0xF0D7,0x08,0x01},
+{0xF0D8,0x40,0x01},
+{0xF0D9,0x14,0x01},
+{0xF0DA,0x62,0x01},
+{0xF0DB,0x92,0x01},
+{0xF0DC,0xA4,0x01},
+{0xF0DD,0xC4,0x01},
+{0xF0DE,0x05,0x01},
+{0xF0DF,0x30,0x01},
+{0xF0E0,0x58,0x01},
+{0xF0E1,0xA1,0x01},
+{0xF0E2,0x49,0x01},
+{0xF0E3,0x46,0x01},
+{0xF0E4,0x22,0x01},
+{0xF0E5,0xB2,0x01},
+{0xF0E6,0x91,0x01},
+{0xF0E7,0x9A,0x01},
+{0xF0E8,0x58,0x01},
+{0xF0E9,0xA5,0x01},
+{0xF0EA,0x2F,0x01},
+{0xF0EB,0x96,0x01},
+{0xF0EC,0x99,0x01},
+{0xF0ED,0x8B,0x01},
+{0xF0EE,0x54,0x01},
+{0xF0EF,0x74,0x01},
+{0xF0F0,0x32,0x01},
+{0xF0F1,0x13,0x01},
+{0xF0F2,0x9D,0x01},
+{0xF0F3,0x38,0x01},
+{0xF0F4,0xC5,0x01},
+{0xF0F5,0x2D,0x01},
+{0xF0F6,0x90,0x01},
+{0xF0F7,0x59,0x01},
+{0xF0F8,0x4D,0x01},
+{0xF0F9,0x64,0x01},
+{0xF0FA,0xEE,0x01},
+{0xF0FB,0x62,0x01},
+{0xF0FC,0x16,0x01},
+{0xF0FD,0xAE,0x01},
+{0xF0FE,0x84,0x01},
+{0xF0FF,0x25,0x01},
+{0xF100,0x2E,0x01},
+{0xF101,0x8B,0x01},
+{0xF102,0x31,0x01},
+{0xF103,0xCD,0x01},
+{0xF104,0x6F,0x01},
+{0xF105,0x60,0x01},
+{0xF106,0xC3,0x01},
+{0xF107,0x19,0x01},
+{0xF108,0xC7,0x01},
+{0xF109,0x14,0x01},
+{0xF10A,0x26,0x01},
+{0xF10B,0x31,0x01},
+{0xF10C,0x97,0x01},
+{0xF10D,0x41,0x01},
+{0xF10E,0x8D,0x01},
+{0xF10F,0x6D,0x01},
+{0xF110,0x86,0x01},
+{0xF111,0xE3,0x01},
+{0xF112,0x9C,0x01},
+{0xF113,0xE2,0x01},
+{0xF114,0xD8,0x01},
+{0xF115,0x06,0x01},
+{0xF116,0x36,0x01},
+{0xF117,0xB5,0x01},
+{0xF118,0xE9,0x01},
+{0xF119,0x4D,0x01},
+{0xF11A,0x70,0x01},
+{0xF11B,0x68,0x01},
+{0xF11C,0x03,0x01},
+{0xF11D,0x00,0x01},
+{0xF11E,0x00,0x01},
+{0xF11F,0x00,0x01},
+{0xF120,0x00,0x01},
+{0xF121,0x00,0x01},
+
+
+//SHD TH
+{0x6C32,0x1964,0x02}, // SHD_INP_TH_HB_H_R2
+{0x6C34,0x18CE,0x02}, // SHD_INP_TH_HB_L_R2
+{0x6C36,0x10CC,0x02}, // SHD_INP_TH_LB_H_R2
+{0x6C38,0x1004,0x02}, // SHD_INP_TH_LB_L_R2
+{0x6C3C,0x10CC,0x02}, // SHD_INP_TH_HB_H_RB
+{0x6C3E,0x1004,0x02}, // SHD_INP_TH_HB_L_RB
+{0x6C40,0x0000,0x02}, // SHD_INP_TH_LB_H_RB
+{0x6C42,0x0000,0x02}, // SHD_INP_TH_LB_L_RB
+
+//PreWB_offset (for SHD2)
+{0x6828,0x0013,0x02}, // SHD_PRER_OFFSET_R2 :
+//PreWB_offset (for SHD3)
+{0x682C,0x000B,0x02}, // SHD_PRER_OFFSET_RB :
+{0x6830,0xFFFD,0x02}, // SHD_PREB_OFFSET_RB :
+
+// CXC/SHD EN
+{0x01BC,0x57,0x01}, // CXC ON SHD ON INP ON GAIN OFF
+};
+
+static const isx012_regset_t ISX012_Flash_ON[] =
+{
+//Flash_ON_SET
+{0x00B7,0x15,0x01}, // LED_ON
+{0x0016,0x10,0x01}, // GPIO_FUNCSEL
+{0x0181,0x05,0x01}, // CAP_HALF_AE_CTRL
+{0x01AE,0x01,0x01}, // HALF_AWB_CTRL
+{0x6223,0x01,0x01}, // INIT_GAINS
+{0x6226,0x01,0x01}, // ATW_GAINS_IN_NR
+{0x6227,0x01,0x01}, // ATW_GAINS_IN
+{0x6228,0x01,0x01}, // ATW_GAINS_OUT_NR
+{0x6229,0x01,0x01}, // ATW_GAINS_OUT
+{0x5E3D,0x0F,0x01}, // FASTMOVE_TIMEOUT
+{0x5E32,0x0F,0x01}, // AESPEED_FAST
+{0x5E2E,0x1A,0x01}, // AEIINDEADBAND
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN
+{0x01AF,0x01,0x01}, // CAP_AWB_CTRL
+{0x6224,0x01,0x01}, // ATW_DELAY
+//AWB boundary set
+{0x6400,0x00,0x01}, // INFRM_LEFT00 :
+{0x6401,0x00,0x01}, // INFRM_LEFT01 :
+{0x6402,0x00,0x01}, // INFRM_LEFT02 :
+{0x6403,0x00,0x01}, // INFRM_LEFT03 :
+{0x6404,0x00,0x01}, // INFRM_LEFT04 :
+{0x6405,0x00,0x01}, // INFRM_LEFT05 :
+{0x6406,0x00,0x01}, // INFRM_LEFT06 :
+{0x6407,0x00,0x01}, // INFRM_LEFT07 :
+{0x6408,0x00,0x01}, // INFRM_LEFT08 :
+{0x6409,0x00,0x01}, // INFRM_LEFT09 :
+{0x640A,0x00,0x01}, // INFRM_LEFT10 :
+{0x640B,0x00,0x01}, // INFRM_LEFT11 :
+{0x640C,0x00,0x01}, // INFRM_LEFT12 :
+{0x640D,0x00,0x01}, // INFRM_LEFT13 :
+{0x640E,0x00,0x01}, // INFRM_LEFT14 :
+{0x640F,0x00,0x01}, // INFRM_LEFT15 :
+{0x6410,0x00,0x01}, // INFRM_LEFT16 :
+{0x6411,0x00,0x01}, // INFRM_LEFT17 :
+{0x6412,0x00,0x01}, // INFRM_LEFT18 :
+{0x6413,0x00,0x01}, // INFRM_LEFT19 :
+{0x6414,0x00,0x01}, // INFRM_LEFT20 :
+{0x6415,0x00,0x01}, // INFRM_LEFT21 :
+{0x6416,0x00,0x01}, // INFRM_LEFT22 :
+{0x6417,0x00,0x01}, // INFRM_LEFT23 :
+{0x6418,0x00,0x01}, // INFRM_LEFT24 :
+{0x6419,0x00,0x01}, // INFRM_LEFT25 :
+{0x641A,0x00,0x01}, // INFRM_LEFT26 :
+{0x641B,0x00,0x01}, // INFRM_LEFT27 :
+{0x641C,0x00,0x01}, // INFRM_LEFT28 :
+{0x641D,0x00,0x01}, // INFRM_LEFT29 :
+{0x641E,0x00,0x01}, // INFRM_LEFT30 :
+{0x641F,0x00,0x01}, // INFRM_LEFT31 :
+{0x6420,0x00,0x01}, // INFRM_LEFT32 :
+{0x6421,0x00,0x01}, // INFRM_LEFT33 :
+{0x6422,0x00,0x01}, // INFRM_LEFT34 :
+{0x6423,0x00,0x01}, // INFRM_LEFT35 :
+{0x6424,0x00,0x01}, // INFRM_LEFT36 :
+{0x6425,0x00,0x01}, // INFRM_LEFT37 :
+{0x6426,0xFF,0x01}, // INFRM_RIGHT00 :
+{0x6427,0xFF,0x01}, // INFRM_RIGHT01 :
+{0x6428,0xFF,0x01}, // INFRM_RIGHT02 :
+{0x6429,0xFF,0x01}, // INFRM_RIGHT03 :
+{0x642A,0xFF,0x01}, // INFRM_RIGHT04 :
+{0x642B,0xFF,0x01}, // INFRM_RIGHT05 :
+{0x642C,0xFF,0x01}, // INFRM_RIGHT06 :
+{0x642D,0xFF,0x01}, // INFRM_RIGHT07 :
+{0x642E,0xFF,0x01}, // INFRM_RIGHT08 :
+{0x642F,0xFF,0x01}, // INFRM_RIGHT09 :
+{0x6430,0xFF,0x01}, // INFRM_RIGHT10 :
+{0x6431,0xFF,0x01}, // INFRM_RIGHT11 :
+{0x6432,0xFF,0x01}, // INFRM_RIGHT12 :
+{0x6433,0xFF,0x01}, // INFRM_RIGHT13 :
+{0x6434,0xFF,0x01}, // INFRM_RIGHT14 :
+{0x6435,0xFF,0x01}, // INFRM_RIGHT15 :
+{0x6436,0xFF,0x01}, // INFRM_RIGHT16 :
+{0x6437,0xFF,0x01}, // INFRM_RIGHT17 :
+{0x6438,0xFF,0x01}, // INFRM_RIGHT18 :
+{0x6439,0xFF,0x01}, // INFRM_RIGHT19 :
+{0x643A,0xFF,0x01}, // INFRM_RIGHT20 :
+{0x643B,0xFF,0x01}, // INFRM_RIGHT21 :
+{0x643C,0xFF,0x01}, // INFRM_RIGHT22 :
+{0x643D,0xFF,0x01}, // INFRM_RIGHT23 :
+{0x643E,0xFF,0x01}, // INFRM_RIGHT24 :
+{0x643F,0xFF,0x01}, // INFRM_RIGHT25 :
+{0x6440,0xFF,0x01}, // INFRM_RIGHT26 :
+{0x6441,0xFF,0x01}, // INFRM_RIGHT27 :
+{0x6442,0xFF,0x01}, // INFRM_RIGHT28 :
+{0x6443,0xFF,0x01}, // INFRM_RIGHT29 :
+{0x6444,0xFF,0x01}, // INFRM_RIGHT30 :
+{0x6445,0xFF,0x01}, // INFRM_RIGHT31 :
+{0x6446,0xFF,0x01}, // INFRM_RIGHT32 :
+{0x6447,0xFF,0x01}, // INFRM_RIGHT33 :
+{0x6448,0xFF,0x01}, // INFRM_RIGHT34 :
+{0x6449,0xFF,0x01}, // INFRM_RIGHT35 :
+{0x644A,0xFF,0x01}, // INFRM_RIGHT36 :
+{0x644B,0xFF,0x01}, // INFRM_RIGHT37 :
+{0x644C,0x25C2,0x02}, // INFRM_TOP :
+{0x644E,0x0348,0x02}, // INFRM_BOTM :
+{0x6450,0x1D,0x01}, // INFRM_FLTOP :
+{0x6451,0x00,0x01}, // INFRM_FLBOTM :
+//halfrelease_mode value
+{0x0082,0x01,0x01}, // MONI_REFRESH
+{0x00B1,0x01,0x01}, //AF_RESTART_F :
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
+{0x00B3,0x00,0x01}, //AFMODE_HREL :
+{0xFFFF,0x42,0x01},//$wait, 66
+{0x0081,0x01,0x01}, //MODESEL
+};
+
+static const isx012_regset_t ISX012_Flash_OFF[] =
+{
+//Flash_OFF_RESET
+{0x00B7,0x00,0x01}, // LED_ON
+{0x0016,0x10,0x01}, // GPIO_FUNCSEL
+{0x0181,0x00,0x01}, // CAP_HALF_AE_CTRL
+{0x01AE,0x00,0x01}, // HALF_AWB_CTRL
+{0x6223,0x04,0x01}, // INIT_GAINS
+{0x6226,0x08,0x01}, // ATW_GAINS_IN_NR
+{0x6227,0x04,0x01}, // ATW_GAINS_IN
+{0x6228,0x08,0x01}, // ATW_GAINS_OUT_NR
+{0x6229,0x04,0x01}, // ATW_GAINS_OUT
+{0x5E3D,0x0A,0x01}, // FASTMOVE_TIMEOUT
+{0x5E32,0x0F,0x01}, // AESPEED_FAST
+{0x5E2E,0x1A,0x01}, // AEIINDEADBAND
+{0x500A,0x00,0x01}, // FAST_MODECHG_EN
+{0x01AF,0x00,0x01}, // CAP_AWB_CTRL
+{0x6224,0x04,0x01}, // ATW_DELAY
+//AWB boundary reset
+{0x6400,0xAA,0x01}, // INFRM_LEFT00 :
+{0x6401,0xAA,0x01}, // INFRM_LEFT01 :
+{0x6402,0xAA,0x01}, // INFRM_LEFT02 :
+{0x6403,0xAA,0x01}, // INFRM_LEFT03 :
+{0x6404,0xAA,0x01}, // INFRM_LEFT04 :
+{0x6405,0xAA,0x01}, // INFRM_LEFT05 :
+{0x6406,0xAA,0x01}, // INFRM_LEFT06 :
+{0x6407,0xAA,0x01}, // INFRM_LEFT07 :
+{0x6408,0xAA,0x01}, // INFRM_LEFT08 :
+{0x6409,0xAE,0x01}, // INFRM_LEFT09 :
+{0x640A,0xA0,0x01}, // INFRM_LEFT10 :
+{0x640B,0x8C,0x01}, // INFRM_LEFT11 :
+{0x640C,0x72,0x01}, // INFRM_LEFT12 :
+{0x640D,0x64,0x01}, // INFRM_LEFT13 :
+{0x640E,0x5A,0x01}, // INFRM_LEFT14 :
+{0x640F,0x52,0x01}, // INFRM_LEFT15 :
+{0x6410,0x48,0x01}, // INFRM_LEFT16 :
+{0x6411,0x43,0x01}, // INFRM_LEFT17 :
+{0x6412,0x3D,0x01}, // INFRM_LEFT18 :
+{0x6413,0x37,0x01}, // INFRM_LEFT19 :
+{0x6414,0x33,0x01}, // INFRM_LEFT20 :
+{0x6415,0x30,0x01}, // INFRM_LEFT21 :
+{0x6416,0x2E,0x01}, // INFRM_LEFT22 :
+{0x6417,0x2B,0x01}, // INFRM_LEFT23 :
+{0x6418,0x28,0x01}, // INFRM_LEFT24 :
+{0x6419,0x26,0x01}, // INFRM_LEFT25 :
+{0x641A,0x24,0x01}, // INFRM_LEFT26 :
+{0x641B,0x23,0x01}, // INFRM_LEFT27 :
+{0x641C,0x22,0x01}, // INFRM_LEFT28 :
+{0x641D,0x22,0x01}, // INFRM_LEFT29 :
+{0x641E,0x21,0x01}, // INFRM_LEFT30 :
+{0x641F,0x20,0x01}, // INFRM_LEFT31 :
+{0x6420,0x1D,0x01}, // INFRM_LEFT32 :
+{0x6421,0x1A,0x01}, // INFRM_LEFT33 :
+{0x6422,0x18,0x01}, // INFRM_LEFT34 :
+{0x6423,0x17,0x01}, // INFRM_LEFT35 :
+{0x6424,0x16,0x01}, // INFRM_LEFT36 :
+{0x6425,0x17,0x01}, // INFRM_LEFT37 :
+{0x6426,0xAF,0x01}, // INFRM_RIGHT00 :
+{0x6427,0xAF,0x01}, // INFRM_RIGHT01 :
+{0x6428,0xAF,0x01}, // INFRM_RIGHT02 :
+{0x6429,0xAF,0x01}, // INFRM_RIGHT03 :
+{0x642A,0xAF,0x01}, // INFRM_RIGHT04 :
+{0x642B,0xAF,0x01}, // INFRM_RIGHT05 :
+{0x642C,0xAF,0x01}, // INFRM_RIGHT06 :
+{0x642D,0xAF,0x01}, // INFRM_RIGHT07 :
+{0x642E,0xAF,0x01}, // INFRM_RIGHT08 :
+{0x642F,0xAA,0x01}, // INFRM_RIGHT09 :
+{0x6430,0xB2,0x01}, // INFRM_RIGHT10 :
+{0x6431,0xB4,0x01}, // INFRM_RIGHT11 :
+{0x6432,0xB6,0x01}, // INFRM_RIGHT12 :
+{0x6433,0xB4,0x01}, // INFRM_RIGHT13 :
+{0x6434,0x9B,0x01}, // INFRM_RIGHT14 :
+{0x6435,0x8E,0x01}, // INFRM_RIGHT15 :
+{0x6436,0x84,0x01}, // INFRM_RIGHT16 :
+{0x6437,0x7A,0x01}, // INFRM_RIGHT17 :
+{0x6438,0x72,0x01}, // INFRM_RIGHT18 :
+{0x6439,0x6A,0x01}, // INFRM_RIGHT19 :
+{0x643A,0x63,0x01}, // INFRM_RIGHT20 :
+{0x643B,0x5E,0x01}, // INFRM_RIGHT21 :
+{0x643C,0x58,0x01}, // INFRM_RIGHT22 :
+{0x643D,0x53,0x01}, // INFRM_RIGHT23 :
+{0x643E,0x4E,0x01}, // INFRM_RIGHT24 :
+{0x643F,0x4A,0x01}, // INFRM_RIGHT25 :
+{0x6440,0x46,0x01}, // INFRM_RIGHT26 :
+{0x6441,0x42,0x01}, // INFRM_RIGHT27 :
+{0x6442,0x3F,0x01}, // INFRM_RIGHT28 :
+{0x6443,0x3C,0x01}, // INFRM_RIGHT29 :
+{0x6444,0x3A,0x01}, // INFRM_RIGHT30 :
+{0x6445,0x38,0x01}, // INFRM_RIGHT31 :
+{0x6446,0x37,0x01}, // INFRM_RIGHT32 :
+{0x6447,0x35,0x01}, // INFRM_RIGHT33 :
+{0x6448,0x33,0x01}, // INFRM_RIGHT34 :
+{0x6449,0x32,0x01}, // INFRM_RIGHT35 :
+{0x644A,0x32,0x01}, // INFRM_RIGHT36 :
+{0x644B,0x32,0x01}, // INFRM_RIGHT37 :
+{0x644C,0x24FA,0x02}, // INFRM_TOP :
+{0x644E,0x0940,0x02}, // INFRM_BOTM :
+{0x6450,0x19,0x01}, // INFRM_FLTOP :
+{0x6451,0x10,0x01}, // INFRM_FLBOTM :
+////Flash_ON_RESET
+{0x0308,0x11,0x01}, // AELINE_MONI_SN1_2 :
+{0x0309,0x13,0x01}, // AELINE_MONI_SN3_4 :
+{0x030B,0x41,0x01}, // AELINE_MONI_SN7_8 :
+{0x030D,0x11,0x01}, // AELINE_MONI_SN11_12 :
+{0x030E,0x11,0x01}, // AELINE_HALF_SN1_2 :
+{0x030F,0x13,0x01}, // AELINE_HALF_SN3_4 :
+{0x0311,0x41,0x01}, // AELINE_HALF_SN7_8 :
+{0x0313,0x11,0x01}, // AELINE_HALF_SN11_12 :
+{0x0314,0x11,0x01}, // AELINE_HALF_AFEND_SN1_2 :
+{0x0315,0x13,0x01}, // AELINE_HALF_AFEND_SN3_4 :
+{0x0317,0x41,0x01}, // AELINE_HALF_AFEND_SN7_8 :
+{0x0319,0x11,0x01}, // AELINE_HALF_AFEND_SN11_12 :
+{0x031A,0x00,0x01}, // AELINE_CAP_SN1_2 :
+{0x031B,0x03,0x01}, // AELINE_CAP_SN3_4 :
+{0x031D,0x50,0x01}, // AELINE_CAP_SN7_8 :
+{0x031F,0x00,0x01}, // AELINE_CAP_SN11_12 :
+{0x0294,0x00,0x01}, // AE_SN1
+{0x0297,0x00,0x01}, // AE_SN4
+{0x029A,0x00,0x01}, // AE_SN7
+{0x029E,0x00,0x01}, // AE_SN11
+};
+
+static const isx012_regset_t ISX012_Flash_AELINE[] =
+{
+//Flash_ON_SET
+{0x0308,0x12,0x01}, // AELINE_MONI_SN1_2 :
+{0x0309,0x23,0x01}, // AELINE_MONI_SN3_4 :
+{0x030B,0x42,0x01}, // AELINE_MONI_SN7_8 :
+{0x030D,0x12,0x01}, // AELINE_MONI_SN11_12 :
+{0x030E,0x12,0x01}, // AELINE_HALF_SN1_2 :
+{0x030F,0x23,0x01}, // AELINE_HALF_SN3_4 :
+{0x0311,0x42,0x01}, // AELINE_HALF_SN7_8 :
+{0x0313,0x12,0x01}, // AELINE_HALF_SN11_12 :
+{0x0314,0x12,0x01}, // AELINE_HALF_AFEND_SN1_2 :
+{0x0315,0x23,0x01}, // AELINE_HALF_AFEND_SN3_4 :
+{0x0317,0x42,0x01}, // AELINE_HALF_AFEND_SN7_8 :
+{0x0319,0x12,0x01}, // AELINE_HALF_AFEND_SN11_12 :
+{0x031A,0x02,0x01}, // AELINE_CAP_SN1_2 :
+{0x031B,0x23,0x01}, // AELINE_CAP_SN3_4 :
+{0x031D,0x52,0x01}, // AELINE_CAP_SN7_8 :
+{0x031F,0x02,0x01}, // AELINE_CAP_SN11_12 :
+};
+
+static const isx012_regset_t ISX012_ae_manual_mode[] =
+{
+{0x0294,0x02,0x01}, /* AE_SN1 */
+{0x0297,0x02,0x01}, /* AE_SN4 */
+{0x029A,0x02,0x01}, /* AE_SN7 */
+{0x029E,0x02,0x01}, /* AE_SN11 */
+{0xFFFF,0x42,0x01}, /* $wait, 66 */
+};
+
+static const isx012_regset_t ISX012_flash_fast_ae_awb[] =
+{
+{0x5E32,0x0A,0x01},
+{0x5E3D,0x05,0x01}, /* Don't fix me. 0x05 */
+
+{0x0181,0x01,0x01}, // CAP_HALF_AE_CTRL
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
+{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF
+{0x0081,0x01,0x01}, //MODESEL
+};
+
+static const isx012_regset_t ISX012_Lowlux_Night_Reset[] =
+{
+{0x039D,0x00,0x01}, //UIHUE_TYPE3 :
+{0x03A0,0x80,0x01}, //UISATURATION_TYPE3 :
+{0x982A,0xFFEC,0x02}, // CS_CBLLEV_A :
+{0x9830,0xFFEC,0x02}, // CS_CRLLEV_A :
+{0x9805,0x0A,0x01}, // CS_SLP_C_A :
+{0x6A9E,0x15C0,0x02}, //HMAX_1_1(0x6A9E)=0x15C0
+{0x00AC,0x00,0x01}, //
+{0x660E,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN
+{0x6610,0x5A,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX
+{0x664A,0x04,0x01}, // AF_DROPN_ON_PEAK_DETECT :
+{0x6640,0x02,0x01}, // AF_DROPN_ON_PEAK_DETECT_SECOND :
+{0x0289,0x20,0x01}, //AWB_SN8
+};
+
+#endif /* __ISX012_REGS_H__ */
diff --git a/drivers/media/video/samsung/Kconfig b/drivers/media/video/samsung/Kconfig
index 7ae9e6a..01232a0 100644
--- a/drivers/media/video/samsung/Kconfig
+++ b/drivers/media/video/samsung/Kconfig
@@ -17,8 +17,8 @@ if CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
source "drivers/media/video/samsung/fimc/Kconfig"
source "drivers/media/video/samsung/tvout/Kconfig"
source "drivers/media/video/samsung/mfc5x/Kconfig"
- source "drivers/media/video/samsung/mali/Kconfig"
- source "drivers/media/video/samsung/ump/Kconfig"
+ source "drivers/media/video/samsung/mali/Kconfig"
+ source "drivers/media/video/samsung/ump/Kconfig"
endif
config VIDEO_FIMG2D
diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h
index b648965..228a1c4 100644
--- a/drivers/media/video/samsung/fimc/fimc.h
+++ b/drivers/media/video/samsung/fimc/fimc.h
@@ -469,6 +469,7 @@ struct fimc_control {
struct mutex lock; /* controller lock */
struct mutex v4l2_lock;
spinlock_t outq_lock;
+ spinlock_t inq_lock;
wait_queue_head_t wq;
struct device *dev;
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c
index 7d00c8b..f76345c 100644
--- a/drivers/media/video/samsung/fimc/fimc_capture.c
+++ b/drivers/media/video/samsung/fimc/fimc_capture.c
@@ -32,6 +32,10 @@
#include "fimc.h"
+#ifdef CONFIG_MACH_KONA
+extern fimc_is;
+#endif
+
static struct pm_qos_request_list bus_qos_pm_qos_req;
static const struct v4l2_fmtdesc capture_fmts[] = {
@@ -816,6 +820,7 @@ static int fimc_configure_subdev(struct fimc_control *ctrl)
if (!sd) {
fimc_err("%s: v4l2 subdev board registering failed\n",
__func__);
+ return -ENODEV;
}
/* Assign subdev to proper camera device pointer */
ctrl->cam->sd = sd;
@@ -1435,7 +1440,7 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f)
mbus_fmt = &ctrl->cap->mbus_fmt;
mbus_fmt->width = pix->width;
mbus_fmt->height = pix->height;
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE)
/* Unfortuntely, we have to use pix->field (not pix->priv) since
* pix.field is already used in the below else condtion statement
* (in case that sub-devices are not registered)
@@ -1445,6 +1450,11 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f)
#if defined(CONFIG_MACH_GC1)
mbus_fmt->field = pix->priv;
#endif
+
+#if defined(CONFIG_MACH_KONA)
+ if(!fimc_is)
+ mbus_fmt->field = pix->field;
+#endif
printk(KERN_INFO "%s mbus_fmt->width = %d, height = %d,\n",
__func__,mbus_fmt->width ,mbus_fmt->height);
@@ -1927,6 +1937,8 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b)
case V4L2_PIX_FMT_YVYU: /* fall through */
case V4L2_PIX_FMT_NV16: /* fall through */
case V4L2_PIX_FMT_NV61: /* fall through */
+ fimc_err("%s : w %d h %d \n",__func__,
+ cap->fmt.width, cap->fmt.height);
fimc_info1("%s : 1plane\n", __func__);
ret = fimc_alloc_buffers(ctrl, 1,
cap->fmt.width * cap->fmt.height, SZ_4K, bpp, cap->pktdata_enable, cap->pktdata_size);
@@ -1940,6 +1952,7 @@ int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b)
break;
case V4L2_PIX_FMT_NV12:
+
fimc_info1("%s : 2plane for NV12\n", __func__);
ret = fimc_alloc_buffers(ctrl, 2,
cap->fmt.width * cap->fmt.height, SZ_64K, bpp, cap->pktdata_enable, cap->pktdata_size);
@@ -2143,6 +2156,7 @@ int fimc_querybuf_capture(void *fh, struct v4l2_buffer *b)
int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c)
{
struct fimc_control *ctrl = fh;
+ struct v4l2_frmsizeenum cam_frmsize;
int ret = 0;
fimc_dbg("%s\n", __func__);
@@ -2164,6 +2178,24 @@ int fimc_g_ctrl_capture(void *fh, struct v4l2_control *c)
c->value = ctrl->cap->cacheable;
break;
+ case V4L2_CID_CAMERA_SENSOR_OUTPUT_SIZE:
+ cam_frmsize.index = -1;
+ cam_frmsize.discrete.width = 0;
+ cam_frmsize.discrete.height = 0;
+
+ ret = v4l2_subdev_call(ctrl->cam->sd, video, enum_framesizes,
+ &cam_frmsize);
+ if (ret < 0) {
+ dev_err(ctrl->dev, "%s: enum_framesizes failed\n",
+ __func__);
+ if (ret != -ENOIOCTLCMD)
+ return ret;
+ } else {
+ c->value = (cam_frmsize.discrete.width << 16)|(cam_frmsize.discrete.height&0xFFFF);
+ dev_err(ctrl->dev,"sensor_output (%d, %d)\n", cam_frmsize.discrete.width, cam_frmsize.discrete.height);
+ }
+ break;
+
default:
/* get ctrl supported by subdev */
/* WriteBack doesn't have subdev_call */
@@ -2248,7 +2280,7 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c)
clk_disable(ctrl->cam->clk);
fimc->mclk_status = CAM_MCLK_OFF;
ctrl->cam->initialized = 0;
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
/* 100ms: increase delay.
* There are cases that sensor doesn't get revived
* inspite of doing power reset.*/
@@ -2723,7 +2755,7 @@ int fimc_streamon_capture(void *fh)
}
}
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
#ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF
v4l2_subdev_call(cam->sd, video, s_stream,
STREAM_MODE_WAIT_OFF);
@@ -2753,7 +2785,7 @@ int fimc_streamon_capture(void *fh)
cap->fmt.pixelformat);
}
}
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
if (1) {
#else
if (cap->fmt.priv != V4L2_PIX_FMT_MODE_CAPTURE) {
@@ -2930,9 +2962,20 @@ int fimc_streamon_capture(void *fh)
fimc_start_capture(ctrl);
ctrl->status = FIMC_STREAMON;
- if (ctrl->is.sd && fimc_cam_use)
+ if (ctrl->is.sd && fimc_cam_use) {
ret = v4l2_subdev_call(ctrl->is.sd, video, s_stream, 1);
- printk(KERN_INFO "%s-- fimc%d\n", __func__, ctrl->id);
+ if (ret < 0) {
+ dev_err(ctrl->dev, "%s: s_stream failed\n",
+ __func__);
+ if (cam->type == CAM_TYPE_MIPI) {
+ if (cam->id == CAMERA_CSI_C)
+ s3c_csis_stop(CSI_CH_0);
+ else
+ s3c_csis_stop(CSI_CH_1);
+ }
+ return ret;
+ }
+ }
/* if available buffer did not remained */
return 0;
@@ -3135,17 +3178,16 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
int available_bufnum;
size_t length = 0;
int i;
+ unsigned long spin_flags;
if (!cap || !ctrl->cam) {
fimc_err("%s: No capture device.\n", __func__);
return -ENODEV;
}
- mutex_lock(&ctrl->v4l2_lock);
if (pdata->hw_ver >= 0x51) {
if (cap->bufs[idx].state != VIDEOBUF_IDLE) {
fimc_err("%s: invalid state idx : %d\n", __func__, idx);
- mutex_unlock(&ctrl->v4l2_lock);
return -EINVAL;
} else {
if (b->memory == V4L2_MEMORY_USERPTR) {
@@ -3167,7 +3209,6 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
if (ret < 0) {
fimc_err("%s: _qbuf_dmabuf error.\n",
__func__);
- mutex_unlock(&ctrl->v4l2_lock);
return -ENODEV;
}
for (i = 0; i < vb->num_planes; i++) {
@@ -3181,7 +3222,6 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
} else {
fimc_err("%s: Wrong sg value.\n",
__func__);
- mutex_unlock(&ctrl->v4l2_lock);
return -ENODEV;
}
}
@@ -3203,6 +3243,7 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
#endif
}
+ spin_lock_irqsave(&ctrl->inq_lock, spin_flags);
fimc_hwset_output_buf_sequence(ctrl, idx, FIMC_FRAMECNT_SEQ_ENABLE);
cap->bufs[idx].state = VIDEOBUF_QUEUED;
if (ctrl->status == FIMC_BUFFER_STOP) {
@@ -3217,13 +3258,12 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
ctrl->restart = true;
}
}
+ spin_unlock_irqrestore(&ctrl->inq_lock, spin_flags);
}
} else {
fimc_add_inqueue(ctrl, b->index);
}
- mutex_unlock(&ctrl->v4l2_lock);
-
if (!cap->cacheable)
return 0;
diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c
index 1ed79dd..4822587 100644
--- a/drivers/media/video/samsung/fimc/fimc_dev.c
+++ b/drivers/media/video/samsung/fimc/fimc_dev.c
@@ -898,6 +898,50 @@ static struct vm_operations_struct fimc_mmap_ops = {
};
static inline
+int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ u32 start_phy_addr = 0;
+ u32 size = vma->vm_end - vma->vm_start;
+ u32 pfn, idx = vma->vm_pgoff;
+ u32 buf_length = 0;
+
+ buf_length = ctrl->mem.size;
+ if (size > PAGE_ALIGN(buf_length)) {
+ fimc_err("Requested mmap size is too big\n");
+ return -EINVAL;
+ }
+
+ start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT);
+
+ if (!cma_is_registered_region(start_phy_addr, size)) {
+ pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n",
+ __func__, buf_length, start_phy_addr);
+ return -EINVAL;
+ }
+
+ /* only supports non-cached mmap */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+
+ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
+ fimc_err("writable mapping must be shared\n");
+ return -EINVAL;
+ }
+
+ pfn = __phys_to_pfn(start_phy_addr);
+
+ if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
+ fimc_err("mmap fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline
int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma)
{
struct fimc_prv_data *prv_data =
@@ -981,10 +1025,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma)
int idx = ctrl->out->ctx[ctx_id].overlay.req_idx;
int ret = -1;
+#if 0
if (idx >= 0)
ret = fimc_mmap_out_dst(filp, vma, idx);
else if (idx == FIMC_MMAP_IDX)
ret = fimc_mmap_out_src(filp, vma);
+#else
+ ret = fimc_mmap_own_mem(filp, vma);
+#endif
return ret;
}
@@ -1002,6 +1050,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma)
vma->vm_flags |= VM_RESERVED;
+ if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) {
+ pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n",
+ __func__, size, ctrl->cap->bufs[idx].base[0]);
+ return -EINVAL;
+ }
+
/*
* page frame number of the address for a source frame
* to be stored at.
diff --git a/drivers/media/video/samsung/fimc/fimc_dev_u1.c b/drivers/media/video/samsung/fimc/fimc_dev_u1.c
index 811ac96..52246a1 100644
--- a/drivers/media/video/samsung/fimc/fimc_dev_u1.c
+++ b/drivers/media/video/samsung/fimc/fimc_dev_u1.c
@@ -745,6 +745,50 @@ static struct vm_operations_struct fimc_mmap_ops = {
};
static inline
+int fimc_mmap_own_mem(struct file *filp, struct vm_area_struct *vma)
+{
+ struct fimc_prv_data *prv_data =
+ (struct fimc_prv_data *)filp->private_data;
+ struct fimc_control *ctrl = prv_data->ctrl;
+ u32 start_phy_addr = 0;
+ u32 size = vma->vm_end - vma->vm_start;
+ u32 pfn, idx = vma->vm_pgoff;
+ u32 buf_length = 0;
+
+ buf_length = ctrl->mem.size;
+ if (size > PAGE_ALIGN(buf_length)) {
+ fimc_err("Requested mmap size is too big\n");
+ return -EINVAL;
+ }
+
+ start_phy_addr = ctrl->mem.base + (vma->vm_pgoff << PAGE_SHIFT);
+
+ if (!cma_is_registered_region(start_phy_addr, size)) {
+ pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n",
+ __func__, buf_length, start_phy_addr);
+ return -EINVAL;
+ }
+
+ /* only supports non-cached mmap */
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ vma->vm_flags |= VM_RESERVED;
+
+ if ((vma->vm_flags & VM_WRITE) && !(vma->vm_flags & VM_SHARED)) {
+ fimc_err("writable mapping must be shared\n");
+ return -EINVAL;
+ }
+
+ pfn = __phys_to_pfn(start_phy_addr);
+
+ if (remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot)) {
+ fimc_err("mmap fail\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static inline
int fimc_mmap_out_src(struct file *filp, struct vm_area_struct *vma)
{
struct fimc_prv_data *prv_data =
@@ -829,10 +873,14 @@ static inline int fimc_mmap_out(struct file *filp, struct vm_area_struct *vma)
int idx = ctrl->out->ctx[ctx_id].overlay.req_idx;
int ret = -1;
+#if 0
if (idx >= 0)
ret = fimc_mmap_out_dst(filp, vma, idx);
else if (idx == FIMC_MMAP_IDX)
ret = fimc_mmap_out_src(filp, vma);
+#else
+ ret = fimc_mmap_own_mem(filp, vma);
+#endif
return ret;
}
@@ -849,6 +897,12 @@ static inline int fimc_mmap_cap(struct file *filp, struct vm_area_struct *vma)
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
vma->vm_flags |= VM_RESERVED;
+ if (!cma_is_registered_region(ctrl->cap->bufs[idx].base[0], size)) {
+ pr_err("[%s] handling non-cma region (%#x@%#x)is prohibited\n",
+ __func__, size, ctrl->cap->bufs[idx].base[0]);
+ return -EINVAL;
+ }
+
/*
* page frame number of the address for a source frame
* to be stored at.
diff --git a/drivers/media/video/samsung/mali/Kconfig b/drivers/media/video/samsung/mali/Kconfig
index 1736eed..e53d2b3 100644
--- a/drivers/media/video/samsung/mali/Kconfig
+++ b/drivers/media/video/samsung/mali/Kconfig
@@ -6,7 +6,7 @@
config VIDEO_MALI400MP
bool "Enable MALI integration"
depends on VIDEO_SAMSUNG
- default y
+ default n
---help---
This enables MALI integration in the multimedia device driver
diff --git a/drivers/media/video/samsung/mali/Kconfig_module b/drivers/media/video/samsung/mali/Kconfig_module
index dabb36e..1fdc638 100644
--- a/drivers/media/video/samsung/mali/Kconfig_module
+++ b/drivers/media/video/samsung/mali/Kconfig_module
@@ -1,13 +1,3 @@
-config MALI400
- tristate "Mali-300/400/450 support"
- depends on ARM
- select FB
- ---help---
- This enables support for the Mali-300, Mali-400, and Mali-450 GPUs.
-
- To compile this driver as a module, choose M here: the module will be
- called mali.
-
config MALI400_DEBUG
bool "Enable debug in Mali driver"
depends on MALI400
diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-orion-m400/config.h
index 5c4d79d..73502a2 100644
--- a/drivers/media/video/samsung/mali/arch-orion-m400/config.h
+++ b/drivers/media/video/samsung/mali/arch-orion-m400/config.h
@@ -130,7 +130,7 @@ static _mali_osk_resource_t arch_configuration [] =
#endif/* if USING_OS_MEMORY*/
{
.type = MEM_VALIDATION,
- .description = "memory validation",
+ .description = "Framebuffer Memory",
.base = MEM_BASE_ADDR,
.size = MEM_TOTAL_SIZE,
.flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE | _MALI_MMU_READABLE | _MALI_MMU_WRITEABLE
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
index 7fbea2a..8ff3d37 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c
@@ -243,7 +243,15 @@ static void os_allocator_release(void * ctx, void * handle)
static mali_physical_memory_allocation_result os_allocator_allocate_page_table_block(void * ctx, mali_page_table_block * block)
{
- int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 11 */
+#if defined(CONFIG_MACH_KONA)
+#ifndef CONFIG_FORCE_MAX_ZONEORDER
+ int allocation_order = 10;
+#else
+ int allocation_order = CONFIG_FORCE_MAX_ZONEORDER - 1;
+#endif
+#else
+ int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 6 */
+#endif
void *virt = NULL;
u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
os_allocator * info;
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
index 3fa6e55..228be02 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
@@ -27,6 +27,8 @@
#include <plat/sysmmu.h>
#endif
+#include <linux/cma.h>
+
#ifdef CONFIG_UMP_VCM_ALLOC
#include "ump_kernel_interface.h"
#endif
@@ -881,13 +883,24 @@ long s5p_tvout_tvif_ioctl(
goto end_tvif_ioctl;
}
for (i = 0; i < S5PTV_VP_BUFF_CNT; i++) {
- s5ptv_vp_buff.vp_buffs[i].phy_base = buffs[i].phy_base;
- s5ptv_vp_buff.vp_buffs[i].vir_base =
- (unsigned int)phys_to_virt(buffs[i].phy_base);
- s5ptv_vp_buff.vp_buffs[i].size = buffs[i].size;
- tvout_dbg("s5ptv_vp_buff phy_base = 0x%x, vir_base = 0x%8x\n",
- s5ptv_vp_buff.vp_buffs[i].phy_base,
- s5ptv_vp_buff.vp_buffs[i].vir_base);
+ if (cma_is_registered_region(buffs[i].phy_base,
+ buffs[i].size)) {
+ s5ptv_vp_buff.vp_buffs[i].phy_base =
+ buffs[i].phy_base;
+ s5ptv_vp_buff.vp_buffs[i].vir_base =
+ (unsigned int)phys_to_virt(buffs[i].phy_base);
+ s5ptv_vp_buff.vp_buffs[i].size = buffs[i].size;
+ tvout_dbg("s5ptv_vp_buff phy_base = 0x%x, "
+ "vir_base = 0x%8x\n",
+ s5ptv_vp_buff.vp_buffs[i].phy_base,
+ s5ptv_vp_buff.vp_buffs[i].vir_base);
+ } else {
+ s5ptv_vp_buff.vp_buffs[i].phy_base = 0;
+ s5ptv_vp_buff.vp_buffs[i].vir_base = 0;
+ printk(KERN_ERR "Buffer for VP is not CMA region\n");
+ ret = -EINVAL;
+ goto end_tvif_ioctl;
+ }
}
goto end_tvif_ioctl;
}
@@ -1134,6 +1147,25 @@ static int s5p_tvout_vo_s_fmt_type_private(
pix_fmt->height, color, field);
#else
if (pix_fmt->priv) {
+ if (pix_fmt->pixelformat == V4L2_PIX_FMT_NV12T
+ || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) {
+ y_size = ALIGN(ALIGN(pix_fmt->width, 128) *
+ ALIGN(pix_fmt->height, 32), SZ_8K);
+ cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) *
+ ALIGN(pix_fmt->height >> 1, 32), SZ_8K);
+ } else {
+ y_size = pix_fmt->width * pix_fmt->height;
+ cbcr_size = pix_fmt->width * (pix_fmt->height >> 1);
+ }
+ if (!cma_is_registered_region((unsigned int)vparam.base_y,
+ y_size) ||
+ !cma_is_registered_region((unsigned int)vparam.base_c,
+ cbcr_size)) {
+ printk(KERN_ERR "Source image for VP is not"
+ "CMA region\n");
+ goto error_on_s_fmt_type_private;
+ }
+
copy_buff_idx =
s5ptv_vp_buff.
copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx];
@@ -1144,19 +1176,6 @@ static int s5p_tvout_vo_s_fmt_type_private(
(u32) vparam.base_y, (u32) vparam.base_c,
pix_fmt->width, pix_fmt->height, color, field);
} else {
- if (pix_fmt->pixelformat ==
- V4L2_PIX_FMT_NV12T
- || pix_fmt->pixelformat == V4L2_PIX_FMT_NV21T) {
- y_size = ALIGN(ALIGN(pix_fmt->width, 128) *
- ALIGN(pix_fmt->height, 32), SZ_8K);
- cbcr_size = ALIGN(ALIGN(pix_fmt->width, 128) *
- ALIGN(pix_fmt->height >> 1, 32), SZ_8K);
- } else {
- y_size = pix_fmt->width * pix_fmt->height;
- cbcr_size =
- pix_fmt->width * (pix_fmt->height >> 1);
- }
-
src_vir_y_addr = (unsigned int)phys_to_virt(
(unsigned long)vparam.base_y);
src_vir_cb_addr = (unsigned int)phys_to_virt(
diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig
index 9d8e5e6..09e8daf 100644
--- a/drivers/media/video/samsung/ump/Kconfig
+++ b/drivers/media/video/samsung/ump/Kconfig
@@ -6,7 +6,7 @@
# For UMP
config VIDEO_UMP
bool "Enable UMP(Unified Memory Provider)"
- default y
+ default n
---help---
This enables UMP memory provider
diff --git a/drivers/media/video/sr130pc20.c b/drivers/media/video/sr130pc20.c
new file mode 100644
index 0000000..8dbc83f
--- /dev/null
+++ b/drivers/media/video/sr130pc20.c
@@ -0,0 +1,1994 @@
+/* drivers/media/video/sr130pc20.c
+ *
+ * Copyright (c) 2010, Samsung Electronics. All rights reserved
+ * Author: dongseong.lim
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ * - change date: 2012.06.28
+ */
+#include "sr130pc20.h"
+#include <linux/gpio.h>
+
+#define i2c_read_nop() \
+ (cam_err("error, not used read function, line %d\n", __LINE__))
+#define i2c_write_nop() \
+ (cam_err("error, not used write function, line %d\n", __LINE__))
+
+#define isx012_readb(sd, addr, data) i2c_read_nop()
+#define isx012_writeb(sd, addr, data) i2c_write_nop()
+
+#define sr130pc20_readb(sd, addr, data) sr130pc20_i2c_read(sd, addr, data)
+#define sr130pc20_readw(sd, addr, data) i2c_read_nop()
+#define sr130pc20_readl(sd, addr, data) i2c_read_nop()
+#define sr130pc20_writeb(sd, addr, data) sr130pc20_i2c_write(sd, addr, data)
+#define sr130pc20_writew(sd, addr, data) i2c_write_nop()
+#define sr130pc20_writel(sd, addr, data) i2c_write_nop()
+
+int fimc_is;
+EXPORT(fimc_is);
+
+static int dbg_level;
+
+static const struct sr130pc20_fps sr130pc20_framerates[] = {
+ { I_FPS_0, FRAME_RATE_AUTO },
+ { I_FPS_7, FRAME_RATE_7},
+ { I_FPS_15, FRAME_RATE_15 },
+ { I_FPS_25, FRAME_RATE_25 },
+ { I_FPS_30, FRAME_RATE_30 },
+};
+
+static const struct sr130pc20_framesize sr130pc20_preview_frmsizes[] = {
+ { PREVIEW_SZ_320x240, 320, 240 },
+ { PREVIEW_SZ_CIF, 352, 288 },
+ { PREVIEW_SZ_VGA, 640, 480 },
+};
+
+static const struct sr130pc20_framesize sr130pc20_capture_frmsizes[] = {
+/* { CAPTURE_SZ_VGA, 640, 480 },*/
+ { CAPTURE_SZ_1MP, 1280, 960 },
+};
+
+static struct sr130pc20_control sr130pc20_ctrls[] = {
+ SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_FLASH_MODE, \
+ FLASH_MODE_OFF),
+
+ SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_BRIGHTNESS, \
+ EV_DEFAULT),
+
+ SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_METERING, \
+ METERING_MATRIX),
+
+ SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_WHITE_BALANCE, \
+ WHITE_BALANCE_AUTO),
+
+ SR130PC20_INIT_CONTROL(V4L2_CID_CAMERA_EFFECT, \
+ IMAGE_EFFECT_NONE),
+};
+
+static const struct sr130pc20_regs reg_datas = {
+ .ev = {
+ SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_4),
+ SR130PC20_ExpSetting_M4Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_3),
+ SR130PC20_ExpSetting_M3Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_2),
+ SR130PC20_ExpSetting_M2Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_MINUS_1),
+ SR130PC20_ExpSetting_M1Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_DEFAULT),
+ SR130PC20_ExpSetting_Default, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_1),
+ SR130PC20_ExpSetting_P1Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_2),
+ SR130PC20_ExpSetting_P2Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_3),
+ SR130PC20_ExpSetting_P3Step, 0),
+ SR130PC20_REGSET(GET_EV_INDEX(EV_PLUS_4),
+ SR130PC20_ExpSetting_P4Step, 0),
+ },
+ .metering = {
+ SR130PC20_REGSET(METERING_MATRIX, sr130pc20_Metering_Matrix, 0),
+ SR130PC20_REGSET(METERING_CENTER, sr130pc20_Metering_Center, 0),
+ SR130PC20_REGSET(METERING_SPOT, sr130pc20_Metering_Spot, 0),
+ },
+ .iso = {
+ SR130PC20_REGSET(ISO_AUTO, sr130pc20_ISO_Auto, 0),
+ SR130PC20_REGSET(ISO_50, sr130pc20_ISO_50, 0),
+ SR130PC20_REGSET(ISO_100, sr130pc20_ISO_100, 0),
+ SR130PC20_REGSET(ISO_200, sr130pc20_ISO_200, 0),
+ SR130PC20_REGSET(ISO_400, sr130pc20_ISO_400, 0),
+ },
+ .effect = {
+ SR130PC20_REGSET(IMAGE_EFFECT_NONE, sr130pc20_Effect_Normal, 0),
+ SR130PC20_REGSET(IMAGE_EFFECT_BNW, sr130pc20_Effect_Black_White, 0),
+ SR130PC20_REGSET(IMAGE_EFFECT_SEPIA, sr130pc20_Effect_Sepia, 0),
+ SR130PC20_REGSET(IMAGE_EFFECT_NEGATIVE,
+ SR130PC20_Effect_Negative, 0),
+ SR130PC20_REGSET(IMAGE_EFFECT_SOLARIZE, sr130pc20_Effect_Solar, 0),
+ SR130PC20_REGSET(IMAGE_EFFECT_SKETCH, sr130pc20_Effect_Sketch, 0),
+ SR130PC20_REGSET(IMAGE_EFFECT_POINT_COLOR_3,
+ sr130pc20_Effect_Pastel, 0),
+ },
+ .white_balance = {
+ SR130PC20_REGSET(WHITE_BALANCE_AUTO, sr130pc20_WB_Auto, 0),
+ SR130PC20_REGSET(WHITE_BALANCE_SUNNY, sr130pc20_WB_Sunny, 0),
+ SR130PC20_REGSET(WHITE_BALANCE_CLOUDY, sr130pc20_WB_Cloudy, 0),
+ SR130PC20_REGSET(WHITE_BALANCE_TUNGSTEN,
+ sr130pc20_WB_Tungsten, 0),
+ SR130PC20_REGSET(WHITE_BALANCE_FLUORESCENT,
+ sr130pc20_WB_Fluorescent, 0),
+ },
+ .scene_mode = {
+ SR130PC20_REGSET(SCENE_MODE_NONE, sr130pc20_Scene_Default, 0),
+ SR130PC20_REGSET(SCENE_MODE_PORTRAIT, sr130pc20_Scene_Portrait, 0),
+ SR130PC20_REGSET(SCENE_MODE_NIGHTSHOT, sr130pc20_Scene_Nightshot, 0),
+ SR130PC20_REGSET(SCENE_MODE_BACK_LIGHT, sr130pc20_Scene_Backlight, 0),
+ SR130PC20_REGSET(SCENE_MODE_LANDSCAPE, sr130pc20_Scene_Landscape, 0),
+ SR130PC20_REGSET(SCENE_MODE_SPORTS, sr130pc20_Scene_Sports, 0),
+ SR130PC20_REGSET(SCENE_MODE_PARTY_INDOOR,
+ sr130pc20_Scene_Party_Indoor, 0),
+ SR130PC20_REGSET(SCENE_MODE_BEACH_SNOW,
+ sr130pc20_Scene_Beach_Snow, 0),
+ SR130PC20_REGSET(SCENE_MODE_SUNSET, sr130pc20_Scene_Sunset, 0),
+ SR130PC20_REGSET(SCENE_MODE_DUSK_DAWN, sr130pc20_Scene_Duskdawn, 0),
+ SR130PC20_REGSET(SCENE_MODE_FALL_COLOR,
+ sr130pc20_Scene_Fall_Color, 0),
+ SR130PC20_REGSET(SCENE_MODE_FIREWORKS, sr130pc20_Scene_Fireworks, 0),
+ SR130PC20_REGSET(SCENE_MODE_TEXT, sr130pc20_Scene_Text, 0),
+ SR130PC20_REGSET(SCENE_MODE_CANDLE_LIGHT,
+ sr130pc20_Scene_Candle_Light, 0),
+ },
+ .fps = {
+ SR130PC20_REGSET(I_FPS_0, sr130pc20_fps_auto, 0),
+ SR130PC20_REGSET(I_FPS_7, sr130pc20_fps_7fix, 0),
+ SR130PC20_REGSET(I_FPS_15, sr130pc20_fps_15fix, 0),
+ SR130PC20_REGSET(I_FPS_25, sr130pc20_fps_25fix, 0),
+ SR130PC20_REGSET(I_FPS_30, sr130pc20_fps_30fix, 0),
+ },
+ .preview_size = {
+ SR130PC20_REGSET(PREVIEW_SZ_320x240,
+ sr130pc20_320_240_Preview, 0),
+ SR130PC20_REGSET(PREVIEW_SZ_CIF, sr130pc20_352_288_Preview, 0),
+ SR130PC20_REGSET(PREVIEW_SZ_VGA, sr130pc20_640_480_Preview, 0),
+ },
+ .capture_size = {
+ /*SR130PC20_REGSET(CAPTURE_SZ_VGA, sr130pc20_VGA_Capture, 0),*/
+ SR130PC20_REGSET(CAPTURE_SZ_1MP, sr130pc20_1280_960_Capture, 0),
+ },
+
+ .init_reg = SR130PC20_REGSET_TABLE(SR130PC20_Init_Reg, 0),
+ .VT_init_reg = SR130PC20_REGSET_TABLE(sr130pc20_VT_Init_Reg, 0),
+ .SS_init_reg = SR130PC20_REGSET_TABLE(sr130pc20_SmartStay_Init_Reg, 0),
+ /* Camera mode */
+ .preview_mode = SR130PC20_REGSET_TABLE(SR130PC20_Preview_Mode, 0),
+ .capture_mode = SR130PC20_REGSET_TABLE(SR130PC20_Capture_Mode, 0),
+ .capture_mode_night =
+ SR130PC20_REGSET_TABLE(SR130PC20_Lowlux_Night_Capture_Mode, 0),
+ .stream_stop = SR130PC20_REGSET_TABLE(sr130pc20_stop_stream, 0),
+};
+
+static const struct v4l2_mbus_framefmt capture_fmts[] = {
+ {
+ .code = V4L2_MBUS_FMT_FIXED,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+};
+
+/**
+ * msleep_debug: wrapper function calling proper sleep()
+ * @msecs: time to be sleep (in milli-seconds unit)
+ * @dbg_on: whether enable log or not.
+ */
+static void msleep_debug(u32 msecs, bool dbg_on)
+{
+ u32 delta_halfrange; /* in us unit */
+
+ if (unlikely(!msecs))
+ return;
+
+ if (dbg_on)
+ cam_dbg("delay for %dms\n", msecs);
+
+ if (msecs <= 7)
+ delta_halfrange = 100;
+ else
+ delta_halfrange = 300;
+
+ if (msecs <= 20)
+ usleep_range((msecs * 1000 - delta_halfrange),
+ (msecs * 1000 + delta_halfrange));
+ else
+ msleep(msecs);
+}
+
+#ifdef CONFIG_LOAD_FILE
+#define TABLE_MAX_NUM 500
+static char *sr130pc20_regs_table;
+static int sr130pc20_regs_table_size;
+static int gtable_buf[TABLE_MAX_NUM];
+static int sr130pc20_i2c_write(struct v4l2_subdev *sd,
+ u8 subaddr, u8 data);
+
+int sr130pc20_regs_table_init(void)
+{
+ struct file *filp;
+ char *dp;
+ long l;
+ loff_t pos;
+ int ret;
+ mm_segment_t fs = get_fs();
+
+ cam_info("%s %d\n", __func__, __LINE__);
+
+ set_fs(get_ds());
+
+ filp = filp_open("/mnt/sdcard/sr130pc20_regs.h", O_RDONLY, 0);
+
+ if (IS_ERR_OR_NULL(filp)) {
+ cam_err("file open error\n");
+ return PTR_ERR(filp);
+ }
+
+ l = filp->f_path.dentry->d_inode->i_size;
+ cam_trace("l = %ld\n", l);
+ //dp = kmalloc(l, GFP_KERNEL);
+ dp = vmalloc(l);
+ if (dp == NULL) {
+ cam_err("Out of Memory\n");
+ filp_close(filp, current->files);
+ return -EINVAL;
+ }
+
+ pos = 0;
+ memset(dp, 0, l);
+ ret = vfs_read(filp, (char __user *)dp, l, &pos);
+
+ if (ret != l) {
+ cam_err("Failed to read file ret = %d\n", ret);
+ /*kfree(dp);*/
+ vfree(dp);
+ filp_close(filp, current->files);
+ return -EINVAL;
+ }
+
+ filp_close(filp, current->files);
+
+ set_fs(fs);
+
+ sr130pc20_regs_table = dp;
+
+ sr130pc20_regs_table_size = l;
+
+ *((sr130pc20_regs_table + sr130pc20_regs_table_size) - 1) = '\0';
+
+ printk("sr130pc20_reg_table_init end\n");
+ return 0;
+}
+
+void sr130pc20_regs_table_exit(void)
+{
+ printk(KERN_DEBUG "%s %d\n", __func__, __LINE__);
+
+ if (sr130pc20_regs_table) {
+ vfree(sr130pc20_regs_table);
+ sr130pc20_regs_table = NULL;
+ }
+}
+
+static int sr130pc20_is_hexnum(char *num)
+{
+ int i = 0;
+ for (i = 2; num[i] != '\0'; i++) {
+ if (!((num[i] >= '0' && num[5] <= '9')
+ || (num[5] >= 'a' && num[5] <= 'f') || (num[5] >= 'A'
+ && num[5] <=
+ 'F'))) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int sr130pc20_write_regs_from_sd(struct v4l2_subdev *sd,
+ const char *name)
+{
+ char *start = NULL, *end = NULL, *reg = NULL, *temp = NULL;
+ unsigned char addr = 0, value = 0;
+ unsigned short data = 0;
+ char data_buf[7] = { 0 };
+ int err = 0;
+
+ cam_info("Enter!!\n");
+
+ addr = value = 0;
+
+ *(data_buf + 6) = '\0';
+
+ start = strnstr(sr130pc20_regs_table, name, sr130pc20_regs_table_size);
+ if (start == NULL) {
+ cam_err("[%s : %d] start is NULL\n", __func__, __LINE__);
+ err = -EIO;
+ return err;
+ }
+
+ end = strnstr(start, "};", sr130pc20_regs_table_size);
+ if (end == NULL) {
+ cam_err("[%s : %d] end is NULL\n", __func__, __LINE__);
+ err = -EIO;
+ return err;
+ }
+
+ while (1) {
+ /* Find Address */
+ reg = strnstr(start, "0x", sr130pc20_regs_table_size);
+ if (reg)
+ start = (reg + 6);
+
+ if ((reg == NULL) || (reg > end)) {
+ cam_err("[%s : %d] write end of %s\n",
+ __func__, __LINE__, name);
+ break;
+ }
+ /* Write Value to Address */
+ memcpy(data_buf, reg, 6);
+
+ if (sr130pc20_is_hexnum(data_buf) == 0) {
+ cam_err("[%s : %d] it's not hex number %s\n",
+ __func__, __LINE__, data_buf);
+ continue;
+ }
+
+ err = kstrtou16(data_buf, 16, &data);
+ if (err < 0) {
+ cam_err("[%s : %d] kstrtou16 failed\n",
+ __func__, __LINE__);
+ }
+ addr = (data >> 8);
+ value = (data & 0xff);
+
+ if (addr == 0xff) {
+ msleep(value * 10); /*one step is 10ms */
+ cam_trace("delay %d msec\n", value * 10);
+ } else {
+ if (sr130pc20_i2c_write(sd, addr, value) < 0) {
+ cam_err
+ ("[%s : %d] fail on sensor_write :"
+ "addr[0x%04x], value[0x%04x]\n",
+ __func__, __LINE__, addr, value);
+ err = -EIO;
+ return err;
+ }
+ cam_trace
+ ("success on sensor_write :"
+ "addr[0x%04x], value[0x%04x]\n", addr, value);
+ }
+ }
+
+ cam_info("Exit!!\n");
+
+ return err;
+}
+#endif
+
+/**
+ * sr130pc20_read: read data from sensor with I2C
+ * Note the data-store way(Big or Little)
+ */
+static int sr130pc20_i2c_read(struct v4l2_subdev *sd,
+ u8 subaddr, u8 *data)
+{
+ int err = -EIO;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct i2c_msg msg[2];
+ u8 buf[16] = {0,};
+ int retry = 5;
+
+
+ CHECK_ERR_COND_MSG(!client->adapter, -ENODEV,
+ "can't search i2c client adapter\n");
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0;
+ msg[0].len = sizeof(subaddr);
+ msg[0].buf = &subaddr;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = 1;
+ msg[1].buf = buf;
+
+ while (retry-- > 0) {
+ err = i2c_transfer(client->adapter, msg, 2);
+ if (likely(err == 2))
+ break;
+ cam_err("i2c read: error, read register(0x%X). cnt %d\n",
+ subaddr, retry);
+ msleep_debug(POLL_TIME_MS, false);
+ }
+
+ CHECK_ERR_COND_MSG(err != 2, -EIO, "I2C does not work\n");
+
+ *data = buf[0];
+
+ return 0;
+}
+
+/**
+ * sr130pc20_write: write data with I2C
+ * Note the data-store way(Big or Little)
+ */
+static inline int sr130pc20_i2c_write(struct v4l2_subdev *sd,
+ u8 subaddr, u8 data)
+{
+ u8 buf[2];
+ int err = 0, retry = 5;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = buf,
+ .len = 2,
+ };
+
+ CHECK_ERR_COND_MSG(!client->adapter, -ENODEV,
+ "can't search i2c client adapter\n");
+
+ buf[0] = subaddr;
+ buf[1] = data;
+
+ while (retry-- > 0) {
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(err == 1))
+ break;
+ cam_err("i2c write: error %d, write 0x%04X, retry %d\n",
+ err, ((subaddr << 8) | data), retry);
+ msleep_debug(POLL_TIME_MS, false);
+ }
+
+ CHECK_ERR_COND_MSG(err != 1, -EIO, "I2C does not work\n");
+ return 0;
+}
+
+static int sr130pc20_i2c_burst_write_list(struct v4l2_subdev *sd,
+ const sr130pc20_regset_t regs[], int size, const char *name)
+{
+
+ cam_err("burst write: not implemented\n");
+
+ return 0;
+}
+
+static inline int sr130pc20_write_regs(struct v4l2_subdev *sd,
+ const sr130pc20_regset_t regs[], int size)
+{
+ int err = 0, i;
+ u8 subaddr, value;
+
+ cam_trace("size %d\n", size);
+
+ for (i = 0; i < size; i++) {
+ subaddr = (u8)(regs[i] >> 8);
+ value = (u8)(regs[i]);
+ if (unlikely(DELAY_SEQ == subaddr))
+ msleep_debug(value * 10, true);
+ else {
+ err = sr130pc20_writeb(sd, subaddr, value);
+ CHECK_ERR_MSG(err, "register set failed\n")
+ }
+ }
+
+ return 0;
+}
+
+/* PX: */
+static int sr130pc20_set_from_table(struct v4l2_subdev *sd,
+ const char *setting_name,
+ const struct regset_table *table,
+ u32 table_size, s32 index)
+{
+ int err = 0;
+
+ cam_trace("set %s index %d\n", setting_name, index);
+
+ CHECK_ERR_COND_MSG(((index < 0) || (index >= table_size)),
+ -EINVAL, "index(%d) out of range[0:%d] for table for %s\n",
+ index, table_size, setting_name);
+
+ table += index;
+
+#ifdef CONFIG_LOAD_FILE
+ cam_dbg("%s: \"%s\", reg_name=%s\n", __func__,
+ setting_name, table->name);
+ return sr130pc20_write_regs_from_sd(sd, table->name);
+
+#else /* !CONFIG_LOAD_FILE */
+ CHECK_ERR_COND_MSG(!table->reg, -EFAULT, \
+ "table=%s, index=%d, reg = NULL\n", setting_name, index);
+# ifdef DEBUG_WRITE_REGS
+ cam_dbg("write_regtable: \"%s\", reg_name=%s\n", setting_name,
+ table->name);
+# endif /* DEBUG_WRITE_REGS */
+
+ if (table->burst) {
+ err = sr130pc20_i2c_burst_write_list(sd,
+ table->reg, table->array_size, setting_name);
+ } else
+ err = sr130pc20_write_regs(sd, table->reg, table->array_size);
+
+ CHECK_ERR_MSG(err, "write regs(%s), err=%d\n", setting_name, err);
+
+ return 0;
+#endif /* CONFIG_LOAD_FILE */
+}
+
+static inline int sr130pc20_transit_preview_mode(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ if (state->exposure.ae_lock || state->wb.awb_lock)
+ cam_info("Restore user ae(awb)-lock...\n");
+
+ err = sr130pc20_set_from_table(sd, "preview_mode",
+ &state->regs->preview_mode, 1, 0);
+
+ return err;
+}
+
+static inline int sr130pc20_transit_capture_mode(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -EIO;
+
+ if (state->capture.lowlux_night) {
+ cam_info("capture_mode: night lowlux\n");
+ err = sr130pc20_set_from_table(sd, "capture_mode_night",
+ &state->regs->capture_mode_night, 1, 0);
+ } else
+ err = sr130pc20_set_from_table(sd, "capture_mode",
+ &state->regs->capture_mode, 1, 0);
+
+ return err;
+}
+
+/**
+ * sr130pc20_transit_movie_mode: switch camera mode if needed.
+ * Note that this fuction should be called from start_preview().
+ */
+static inline int sr130pc20_transit_movie_mode(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ /* we'll go from the below modes to RUNNING or RECORDING */
+ switch (state->runmode) {
+ case RUNMODE_INIT:
+ /* case of entering camcorder firstly */
+ break;
+ case RUNMODE_RUNNING_STOP:
+ /* case of switching from camera to camcorder */
+ break;
+ case RUNMODE_RECORDING_STOP:
+ /* case of switching from camcorder to camera */
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+/**
+ * sr130pc20_is_hwflash_on - check whether flash device is on
+ *
+ * Refer to state->flash.on to check whether flash is in use in driver.
+ */
+static inline int sr130pc20_is_hwflash_on(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+#ifdef SR130PC20_SUPPORT_FLASH
+ return state->pdata->is_flash_on();
+#else
+ return 0;
+#endif
+}
+
+/**
+ * sr130pc20_flash_en - contro Flash LED
+ * @mode: SR130PC20_FLASH_MODE_NORMAL or SR130PC20_FLASH_MODE_MOVIE
+ * @onoff: SR130PC20_FLASH_ON or SR130PC20_FLASH_OFF
+ */
+static int sr130pc20_flash_en(struct v4l2_subdev *sd, s32 mode, s32 onoff)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ if (unlikely(state->flash.ignore_flash)) {
+ cam_warn("WARNING, we ignore flash command.\n");
+ return 0;
+ }
+
+#ifdef SR130PC20_SUPPORT_FLASH
+ return state->pdata->flash_en(mode, onoff);
+#else
+ return 0;
+#endif
+}
+
+/**
+ * sr130pc20_flash_torch - turn flash on/off as torch for preflash, recording
+ * @onoff: SR130PC20_FLASH_ON or SR130PC20_FLASH_OFF
+ *
+ * This func set state->flash.on properly.
+ */
+static inline int sr130pc20_flash_torch(struct v4l2_subdev *sd, s32 onoff)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ err = sr130pc20_flash_en(sd, SR130PC20_FLASH_MODE_MOVIE, onoff);
+ state->flash.on = (onoff == SR130PC20_FLASH_ON) ? 1 : 0;
+
+ return err;
+}
+
+/**
+ * sr130pc20_flash_oneshot - turn main flash on for capture
+ * @onoff: SR130PC20_FLASH_ON or SR130PC20_FLASH_OFF
+ *
+ * Main flash is turn off automatically in some milliseconds.
+ */
+static inline int sr130pc20_flash_oneshot(struct v4l2_subdev *sd, s32 onoff)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ err = sr130pc20_flash_en(sd, SR130PC20_FLASH_MODE_NORMAL, onoff);
+ state->flash.on = (onoff == SR130PC20_FLASH_ON) ? 1 : 0;
+
+ return err;
+}
+
+static const struct sr130pc20_framesize *sr130pc20_get_framesize
+ (const struct sr130pc20_framesize *frmsizes,
+ u32 frmsize_count, u32 index)
+{
+ int i = 0;
+
+ for (i = 0; i < frmsize_count; i++) {
+ if (frmsizes[i].index == index)
+ return &frmsizes[i];
+ }
+
+ return NULL;
+}
+
+/* This function is called from the g_ctrl api
+ *
+ * This function should be called only after the s_fmt call,
+ * which sets the required width/height value.
+ *
+ * It checks a list of available frame sizes and sets the
+ * most appropriate frame size.
+ *
+ * The list is stored in an increasing order (as far as possible).
+ * Hence the first entry (searching from the beginning) where both the
+ * width and height is more than the required value is returned.
+ * In case of no perfect match, we set the last entry (which is supposed
+ * to be the largest resolution supported.)
+ */
+static void sr130pc20_set_framesize(struct v4l2_subdev *sd,
+ const struct sr130pc20_framesize *frmsizes,
+ u32 num_frmsize, bool preview)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ const struct sr130pc20_framesize **found_frmsize = NULL;
+ u32 width = state->req_fmt.width;
+ u32 height = state->req_fmt.height;
+ int i = 0;
+
+ cam_dbg("%s: Requested Res %dx%d\n", __func__,
+ width, height);
+
+ found_frmsize = preview ?
+ &state->preview.frmsize : &state->capture.frmsize;
+
+ for (i = 0; i < num_frmsize; i++) {
+ if ((frmsizes[i].width == width) &&
+ (frmsizes[i].height == height)) {
+ *found_frmsize = &frmsizes[i];
+ break;
+ }
+ }
+
+ if (*found_frmsize == NULL) {
+ cam_err("%s: error, invalid frame size %dx%d\n",
+ __func__, width, height);
+ *found_frmsize = preview ?
+ sr130pc20_get_framesize(frmsizes, num_frmsize,
+ PREVIEW_SZ_VGA) :
+ sr130pc20_get_framesize(frmsizes, num_frmsize,
+ CAPTURE_SZ_1MP);
+ BUG_ON(!(*found_frmsize));
+ }
+
+ if (preview)
+ cam_info("Preview Res Set: %dx%d, index %d\n",
+ (*found_frmsize)->width, (*found_frmsize)->height,
+ (*found_frmsize)->index);
+ else
+ cam_info("Capture Res Set: %dx%d, index %d\n",
+ (*found_frmsize)->width, (*found_frmsize)->height,
+ (*found_frmsize)->index);
+}
+
+/* PX: Set scene mode */
+static int sr130pc20_set_scene_mode(struct v4l2_subdev *sd, s32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ cam_trace("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case SCENE_MODE_NONE:
+ case SCENE_MODE_PORTRAIT:
+ case SCENE_MODE_NIGHTSHOT:
+ case SCENE_MODE_BACK_LIGHT:
+ case SCENE_MODE_LANDSCAPE:
+ case SCENE_MODE_SPORTS:
+ case SCENE_MODE_PARTY_INDOOR:
+ case SCENE_MODE_BEACH_SNOW:
+ case SCENE_MODE_SUNSET:
+ case SCENE_MODE_DUSK_DAWN:
+ case SCENE_MODE_FALL_COLOR:
+ case SCENE_MODE_FIREWORKS:
+ case SCENE_MODE_TEXT:
+ case SCENE_MODE_CANDLE_LIGHT:
+ sr130pc20_set_from_table(sd, "scene_mode",
+ state->regs->scene_mode,
+ ARRAY_SIZE(state->regs->scene_mode), val);
+ break;
+
+ default:
+ cam_err("set_scene: error, not supported (%d)\n", val);
+ val = SCENE_MODE_NONE;
+ goto retry;
+ }
+
+ state->scene_mode = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+/* PX: Set brightness */
+static int sr130pc20_set_exposure(struct v4l2_subdev *sd, s32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ if ((val < EV_MINUS_4) || (val > EV_PLUS_4)) {
+ cam_err("%s: error, invalid value(%d)\n", __func__, val);
+ return -EINVAL;
+ }
+
+ sr130pc20_set_from_table(sd, "brightness", state->regs->ev,
+ ARRAY_SIZE(state->regs->ev), GET_EV_INDEX(val));
+
+ state->exposure.val = val;
+
+ return err;
+}
+
+static int sr130pc20_set_vt_mode(struct v4l2_subdev *sd, s32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ if (val == PREVIEW_VIDEOCALL) {
+ err = sr130pc20_set_from_table(sd, "VT_init_reg",
+ &state->regs->VT_init_reg, 1, 0);
+ cam_info("VT Mode\n");
+ } else if (val == PREVIEW_SMARTSTAY) {
+ err = sr130pc20_set_from_table(sd, "SS_init_reg",
+ &state->regs->SS_init_reg, 1, 0);
+ cam_info("SMART STAY Mode\n");
+ }
+
+ state->vt_mode = val;
+
+ return err;
+}
+
+/* PX(NEW) */
+static int sr130pc20_set_capture_size(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ u32 width, height;
+
+ if (unlikely(!state->capture.frmsize)) {
+ cam_warn("warning, capture resolution not set\n");
+ state->capture.frmsize = sr130pc20_get_framesize(
+ sr130pc20_capture_frmsizes,
+ ARRAY_SIZE(sr130pc20_capture_frmsizes),
+ CAPTURE_SZ_1MP);
+ }
+
+ width = state->capture.frmsize->width;
+ height = state->capture.frmsize->height;
+
+ state->preview.update_frmsize = 1;
+
+ cam_dbg("set capture size(%dx%d)\n", width, height);
+
+ return 0;
+}
+
+/* PX: Set sensor mode */
+static int sr130pc20_set_sensor_mode(struct v4l2_subdev *sd, s32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ cam_trace("mode=%d\n", val);
+
+ switch (val) {
+ case SENSOR_MOVIE:
+ /* We does not support movie mode when in VT. */
+ if (state->vt_mode) {
+ state->sensor_mode = SENSOR_CAMERA;
+ cam_err("%s: error, Not support movie\n", __func__);
+ break;
+ }
+ /* We do not break. */
+
+ case SENSOR_CAMERA:
+ state->sensor_mode = val;
+ break;
+
+ default:
+ cam_err("%s: error, Not support.(%d)\n", __func__, val);
+ state->sensor_mode = SENSOR_CAMERA;
+ WARN_ON(1);
+ break;
+ }
+
+ return 0;
+}
+
+/* PX: Set framerate */
+static int sr130pc20_set_frame_rate(struct v4l2_subdev *sd, s32 fps)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -EIO;
+ int i = 0, fps_index = -1;
+
+ if (!state->initialized || (state->req_fps < 0))
+ return 0;
+
+ cam_info("set frame rate %d\n", fps);
+
+ if (fps > 25)
+ fps = 25; /* sensor limitation */
+
+ for (i = 0; i < ARRAY_SIZE(sr130pc20_framerates); i++) {
+ if (fps == sr130pc20_framerates[i].fps) {
+ fps_index = sr130pc20_framerates[i].index;
+ state->fps = fps;
+ state->req_fps = -1;
+ break;
+ }
+ }
+
+ if (unlikely(fps_index < 0)) {
+ cam_err("set_fps: warning, not supported fps %d\n", fps);
+ return 0;
+ }
+
+ err = sr130pc20_set_from_table(sd, "fps", state->regs->fps,
+ ARRAY_SIZE(state->regs->fps), fps_index);
+ CHECK_ERR_MSG(err, "fail to set framerate\n");
+
+ /*sr130pc20_control_stream(sd, STREAM_STOP);*/
+
+ return 0;
+}
+
+static int sr130pc20_control_stream(struct v4l2_subdev *sd, u32 cmd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ if (cmd == STREAM_STOP) {
+ if (!((state->runmode == RUNMODE_RUNNING)
+ && state->capture.pre_req)) {
+ cam_info("STREAM STOP!!\n");
+ // [ W/A : Skip stream off sr130pc20 to prevent I2C behavior (P130301-0098)
+ // - DPM timeout (kernel Panic) happen by I2C behavior during system suspending
+ // ]
+ if (state->vt_mode != PREVIEW_SMARTSTAY) {
+ err = sr130pc20_set_from_table(sd, "stream_stop",
+ &state->regs->stream_stop, 1, 0);
+ CHECK_ERR_MSG(err, "failed to stop stream\n");
+ }
+ state->preview.update_frmsize = 1;
+ }
+ } else {
+ cam_info("STREAM START\n");
+ return 0;
+ }
+
+ switch (state->runmode) {
+ case RUNMODE_CAPTURING:
+ cam_dbg("Capture Stop!\n");
+ state->runmode = RUNMODE_CAPTURING_STOP;
+ state->capture.ready = 0;
+ state->capture.lowlux_night = 0;
+ break;
+
+ case RUNMODE_RUNNING:
+ cam_dbg("Preview Stop!\n");
+ state->runmode = RUNMODE_RUNNING_STOP;
+ if (state->capture.pre_req) {
+ sr130pc20_prepare_fast_capture(sd);
+ state->capture.pre_req = 0;
+ }
+ break;
+
+ case RUNMODE_RECORDING:
+ state->runmode = RUNMODE_RECORDING_STOP;
+ break;
+
+ default:
+ break;
+ }
+
+ /*msleep_debug(state->pdata->streamoff_delay, true);*/
+
+ return 0;
+}
+
+/* PX: Set flash mode */
+static int sr130pc20_set_flash_mode(struct v4l2_subdev *sd, s32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ /* movie flash mode should be set when recording is started */
+/* if (state->sensor_mode == SENSOR_MOVIE && !state->recording)
+ return 0;*/
+
+ if (state->flash.mode == val) {
+ cam_dbg("the same flash mode=%d\n", val);
+ return 0;
+ }
+
+ if (val == FLASH_MODE_TORCH)
+ sr130pc20_flash_torch(sd, SR130PC20_FLASH_ON);
+
+ if ((state->flash.mode == FLASH_MODE_TORCH)
+ && (val == FLASH_MODE_OFF))
+ sr130pc20_flash_torch(sd, SR130PC20_FLASH_OFF);
+
+ state->flash.mode = val;
+ cam_dbg("Flash mode = %d\n", val);
+ return 0;
+}
+
+static int sr130pc20_check_esd(struct v4l2_subdev *sd, s32 val)
+{
+ u32 data = 0, size_h = 0, size_v = 0;
+
+/* To do */
+ return 0;
+
+esd_out:
+ cam_err("Check ESD(%d): ESD Shock detected! val=0x%X\n\n", data, val);
+ return -ERESTART;
+}
+
+/* returns the real iso currently used by sensor due to lighting
+ * conditions, not the requested iso we sent using s_ctrl.
+ */
+static inline int sr130pc20_get_exif_iso(struct v4l2_subdev *sd, u16 *iso)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+ u8 read_value = 0;
+ unsigned short gain_value = 0;
+
+ err = sr130pc20_writeb(sd, 0x03, 0x20);
+ CHECK_ERR_COND(err < 0, -ENODEV);
+ sr130pc20_readb(sd, 0xb0, &read_value);
+
+ gain_value = ((read_value * 100) / 32) + 50;
+ cam_dbg("gain_value=%d, read_value=%d\n", gain_value, read_value);
+
+ if (gain_value < 114)
+ *iso = 50;
+ else if (gain_value < 214)
+ *iso = 100;
+ else if (gain_value < 264)
+ *iso = 200;
+ else if (gain_value < 825)
+ *iso = 400;
+ else
+ *iso = 800;
+
+ cam_dbg("gain_value=%d, ISO=%d\n", gain_value, *iso);
+ return 0;
+}
+
+/* PX: Set ISO */
+static int __used sr130pc20_set_iso(struct v4l2_subdev *sd, s32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ sr130pc20_set_from_table(sd, "iso", state->regs->iso,
+ ARRAY_SIZE(state->regs->iso), val);
+
+ state->iso = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+/* PX: Return exposure time (ms) */
+static inline int sr130pc20_get_exif_exptime(struct v4l2_subdev *sd,
+ u32 *exp_time)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+ u8 read_value1 = 0;
+ u8 read_value2 = 0;
+ u8 read_value3 = 0;
+
+ err = sr130pc20_writeb(sd, 0x03, 0x20);
+ CHECK_ERR_COND(err < 0, -ENODEV);
+
+ sr130pc20_readb(sd, 0x80, &read_value1);
+ sr130pc20_readb(sd, 0x81, &read_value2);
+ sr130pc20_readb(sd, 0x82, &read_value3);
+
+ cam_dbg("exposure time read_value %d, %d, %d\n",
+ read_value1, read_value2, read_value3);
+ *exp_time = (read_value1 << 19)
+ + (read_value2 << 11) + (read_value3 << 3);
+
+ cam_dbg("exposure time %dus\n", *exp_time);
+ return 0;
+}
+
+static inline void sr130pc20_get_exif_flash(struct v4l2_subdev *sd,
+ u16 *flash)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ *flash = 0;
+
+ switch (state->flash.mode) {
+ case FLASH_MODE_OFF:
+ *flash |= EXIF_FLASH_MODE_SUPPRESSION;
+ break;
+
+ case FLASH_MODE_AUTO:
+ *flash |= EXIF_FLASH_MODE_AUTO;
+ break;
+
+ case FLASH_MODE_ON:
+ case FLASH_MODE_TORCH:
+ *flash |= EXIF_FLASH_MODE_FIRING;
+ break;
+
+ default:
+ break;
+ }
+
+ if (state->flash.on)
+ *flash |= EXIF_FLASH_FIRED;
+}
+
+/* PX: */
+static int sr130pc20_get_exif(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ u32 exposure_time = 0;
+ u32 int_dec, integer;
+ int OPCLK = 24000000;
+
+ /* exposure time */
+ state->exif.exp_time_den = 0;
+ sr130pc20_get_exif_exptime(sd, &exposure_time);
+ if (exposure_time) {
+ state->exif.exp_time_den = OPCLK / exposure_time;
+ } else {
+ state->exif.exp_time_den = 0;
+ }
+
+ /* iso */
+ state->exif.iso = 0;
+ sr130pc20_get_exif_iso(sd, &state->exif.iso);
+
+ /* flash */
+ sr130pc20_get_exif_flash(sd, &state->exif.flash);
+
+ cam_dbg("EXIF: ex_time_den=%d, iso=%d, flash=0x%02X\n",
+ state->exif.exp_time_den, state->exif.iso, state->exif.flash);
+
+ return 0;
+}
+
+static int sr130pc20_set_preview_size(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ u32 width, height;
+ int err = -EINVAL;
+
+ if (!state->preview.update_frmsize)
+ return 0;
+
+ if (unlikely(!state->preview.frmsize)) {
+ cam_warn("warning, preview resolution not set\n");
+ state->preview.frmsize = sr130pc20_get_framesize(
+ sr130pc20_preview_frmsizes,
+ ARRAY_SIZE(sr130pc20_preview_frmsizes),
+ PREVIEW_SZ_VGA);
+ }
+
+ width = state->preview.frmsize->width;
+ height = state->preview.frmsize->height;
+
+ cam_dbg("set preview size(%dx%d)\n", width, height);
+
+ err = sr130pc20_set_from_table(sd, "preview_size",
+ state->regs->preview_size, ARRAY_SIZE(state->regs->preview_size),
+ state->preview.frmsize->index);
+ CHECK_ERR_MSG(err, "fail to set preview size\n");
+
+ state->preview.update_frmsize = 0;
+
+ return 0;
+}
+
+static int sr130pc20_start_preview(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_info("Camera Preview start, runmode = %d\n", state->runmode);
+
+ if ((state->runmode == RUNMODE_NOTREADY) ||
+ (state->runmode == RUNMODE_CAPTURING)) {
+ cam_err("%s: error - Invalid runmode\n", __func__);
+ return -EPERM;
+ }
+
+ state->focus.status = AF_RESULT_SUCCESS;
+
+ /* Transit preview mode */
+ err = sr130pc20_transit_preview_mode(sd);
+ CHECK_ERR_MSG(err, "preview_mode(%d)\n", err);
+
+ /* Set preview size */
+ sr130pc20_set_preview_size(sd);
+
+ sr130pc20_control_stream(sd, STREAM_START);
+
+ state->runmode = (state->sensor_mode == SENSOR_CAMERA) ?
+ RUNMODE_RUNNING : RUNMODE_RECORDING;
+ return 0;
+}
+
+static int sr130pc20_set_capture(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("set_capture\n");
+
+ /* Set capture size */
+ sr130pc20_set_capture_size(sd);
+
+ /* Transit to capture mode */
+ err = sr130pc20_transit_capture_mode(sd);
+ CHECK_ERR_MSG(err, "fail to capture_mode (%d)\n", err);
+ return 0;
+}
+
+static int sr130pc20_prepare_fast_capture(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("prepare_fast_capture\n");
+
+ state->req_fmt.width = (state->capture.pre_req >> 16);
+ state->req_fmt.height = (state->capture.pre_req & 0xFFFF);
+ sr130pc20_set_framesize(sd, sr130pc20_capture_frmsizes,
+ ARRAY_SIZE(sr130pc20_capture_frmsizes), false);
+
+ err = sr130pc20_set_capture(sd);
+ CHECK_ERR(err);
+
+ state->capture.ready = 1;
+
+ return 0;
+}
+
+static int sr130pc20_start_capture(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -ENODEV, count;
+ u32 val = 0;
+ u32 night_delay;
+
+ cam_info("start_capture\n");
+
+ if (!state->capture.ready) {
+ err = sr130pc20_set_capture(sd);
+ CHECK_ERR(err);
+
+ sr130pc20_control_stream(sd, STREAM_START);
+ night_delay = 500;
+ } else
+ night_delay = 700; /* for completely skipping 1 frame. */
+
+ state->runmode = RUNMODE_CAPTURING;
+
+ if (state->capture.lowlux_night)
+ msleep_debug(night_delay, true);
+
+ /* Get EXIF */
+ sr130pc20_get_exif(sd);
+
+ return 0;
+}
+
+/**
+ * sr200pc20_init_regs: Indentify chip and get pointer to reg table
+ * @
+ */
+static int sr130pc20_init_regs(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -ENODEV;
+ u8 read_value = 0;
+
+ err = sr130pc20_writeb(sd, 0x03, 0x00);
+ CHECK_ERR_COND(err < 0, -ENODEV);
+
+ sr130pc20_readb(sd, 0x04, &read_value);
+ if (SR130PC20_CHIP_ID == read_value)
+ cam_info("Sensor ChipID: 0x%02X\n", SR130PC20_CHIP_ID);
+ else
+ cam_info("Sensor ChipID: 0x%02X, unknown chipID\n", read_value);
+
+ state->regs = &reg_datas;
+
+ return 0;
+}
+
+
+/* PX(NEW) */
+static int sr130pc20_s_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ s32 previous_index = 0;
+
+ cam_dbg("%s: pixelformat = 0x%x, colorspace = 0x%x, width = %d, height = %d\n",
+ __func__, fmt->code, fmt->colorspace, fmt->width, fmt->height);
+
+ v4l2_fill_pix_format(&state->req_fmt, fmt);
+ if ((IS_MODE_CAPTURE_STILL == fmt->field)
+ && (SENSOR_CAMERA == state->sensor_mode))
+ state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE;
+ else
+ state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW;
+
+ if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
+ previous_index = state->preview.frmsize ?
+ state->preview.frmsize->index : -1;
+ sr130pc20_set_framesize(sd, sr130pc20_preview_frmsizes,
+ ARRAY_SIZE(sr130pc20_preview_frmsizes), true);
+
+ if (previous_index != state->preview.frmsize->index)
+ state->preview.update_frmsize = 1;
+ } else {
+ /*
+ * In case of image capture mode,
+ * if the given image resolution is not supported,
+ * use the next higher image resolution. */
+ sr130pc20_set_framesize(sd, sr130pc20_capture_frmsizes,
+ ARRAY_SIZE(sr130pc20_capture_frmsizes), false);
+
+ /* for maket app.
+ * Samsung camera app does not use unmatched ratio.*/
+ if (unlikely(NULL == state->preview.frmsize)) {
+ cam_warn("warning, capture without preview resolution\n");
+ } else if (unlikely(FRM_RATIO(state->preview.frmsize)
+ != FRM_RATIO(state->capture.frmsize))) {
+ cam_warn("warning, capture ratio " \
+ "is different with preview ratio\n");
+ }
+ }
+
+ return 0;
+}
+
+static int sr130pc20_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned int index,
+ enum v4l2_mbus_pixelcode *code)
+{
+ cam_dbg("%s: index = %d\n", __func__, index);
+
+ if (index >= ARRAY_SIZE(capture_fmts))
+ return -EINVAL;
+
+ *code = capture_fmts[index].code;
+
+ return 0;
+}
+
+static int sr130pc20_try_mbus_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *fmt)
+{
+ int num_entries;
+ int i;
+
+ num_entries = ARRAY_SIZE(capture_fmts);
+
+ cam_dbg("%s: code = 0x%x , colorspace = 0x%x, num_entries = %d\n",
+ __func__, fmt->code, fmt->colorspace, num_entries);
+
+ for (i = 0; i < num_entries; i++) {
+ if (capture_fmts[i].code == fmt->code &&
+ capture_fmts[i].colorspace == fmt->colorspace) {
+ cam_info("%s: match found, returning 0\n", __func__);
+ return 0;
+ }
+ }
+
+ cam_err("%s: no match found, returning -EINVAL\n", __func__);
+ return -EINVAL;
+}
+
+
+static int sr130pc20_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ /*
+ * The camera interface should read this value, this is the resolution
+ * at which the sensor would provide framedata to the camera i/f
+ * In case of image capture,
+ * this returns the default camera resolution (VGA)
+ */
+ if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
+ if (unlikely(state->preview.frmsize == NULL)) {
+ cam_err("%s: error\n", __func__);
+ return -EFAULT;
+ }
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = state->preview.frmsize->width;
+ fsize->discrete.height = state->preview.frmsize->height;
+ } else {
+ if (unlikely(state->capture.frmsize == NULL)) {
+ cam_err("%s: error\n", __func__);
+ return -EFAULT;
+ }
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = state->capture.frmsize->width;
+ fsize->discrete.height = state->capture.frmsize->height;
+ }
+
+ return 0;
+}
+
+static int sr130pc20_g_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *param)
+{
+ return 0;
+}
+
+static int sr130pc20_s_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *param)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ state->req_fps = param->parm.capture.timeperframe.denominator /
+ param->parm.capture.timeperframe.numerator;
+
+ cam_dbg("s_parm state->fps=%d, state->req_fps=%d\n",
+ state->fps, state->req_fps);
+
+ if (state->req_fps < 0) {
+ cam_err("%s: error, invalid frame rate %d. we'll set to 0\n",
+ __func__, state->req_fps);
+ state->req_fps = 0;
+ } else if (state->req_fps > 25) {
+ cam_err("%s: error, invalid frame rate %d. we'll set to 25\n",
+ __func__, state->req_fps);
+ state->req_fps = 25;
+ }
+
+ return sr130pc20_set_frame_rate(sd, state->req_fps);
+}
+
+static int sr130pc20_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ if (!state->initialized) {
+ cam_err("%s: WARNING, camera not initialized\n", __func__);
+ return 0;
+ }
+
+ mutex_lock(&state->ctrl_lock);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_EXIF_EXPTIME:
+ if (state->sensor_mode == SENSOR_CAMERA)
+ ctrl->value = state->exif.exp_time_den;
+ else
+ ctrl->value = 24;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_ISO:
+ if (state->sensor_mode == SENSOR_CAMERA)
+ ctrl->value = state->exif.iso;
+ else
+ ctrl->value = 100;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_FLASH:
+ if (state->sensor_mode == SENSOR_CAMERA)
+ ctrl->value = state->exif.flash;
+ else
+ sr130pc20_get_exif_flash(sd, (u16 *)ctrl->value);
+ break;
+
+#if !defined(CONFIG_CAM_YUV_CAPTURE)
+ case V4L2_CID_CAM_JPEG_MAIN_SIZE:
+ ctrl->value = state->jpeg.main_size;
+ break;
+
+ case V4L2_CID_CAM_JPEG_MAIN_OFFSET:
+ ctrl->value = state->jpeg.main_offset;
+ break;
+
+ case V4L2_CID_CAM_JPEG_THUMB_SIZE:
+ ctrl->value = state->jpeg.thumb_size;
+ break;
+
+ case V4L2_CID_CAM_JPEG_THUMB_OFFSET:
+ ctrl->value = state->jpeg.thumb_offset;
+ break;
+
+ case V4L2_CID_CAM_JPEG_QUALITY:
+ ctrl->value = state->jpeg.quality;
+ break;
+
+ case V4L2_CID_CAM_JPEG_MEMSIZE:
+ ctrl->value = SENSOR_JPEG_SNAPSHOT_MEMSIZE;
+ break;
+#endif
+
+ case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT:
+ ctrl->value = state->focus.status;
+ break;
+
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ case V4L2_CID_CAMERA_EFFECT:
+ case V4L2_CID_CAMERA_CONTRAST:
+ case V4L2_CID_CAMERA_SATURATION:
+ case V4L2_CID_CAMERA_SHARPNESS:
+ case V4L2_CID_CAMERA_OBJ_TRACKING_STATUS:
+ case V4L2_CID_CAMERA_SMART_AUTO_STATUS:
+ default:
+ cam_err("%s: WARNING, unknown Ctrl-ID 0x%x\n",
+ __func__, ctrl->id);
+ err = 0; /* we return no error. */
+ break;
+ }
+
+ mutex_unlock(&state->ctrl_lock);
+
+ return err;
+}
+
+static int sr130pc20_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ if (!state->initialized && ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE
+ && ctrl->id != V4L2_CID_CAMERA_VT_MODE) {
+ cam_warn("%s: WARNING, camera not initialized. ID = %d(0x%X)\n",
+ __func__, ctrl->id - V4L2_CID_PRIVATE_BASE,
+ ctrl->id - V4L2_CID_PRIVATE_BASE);
+ return 0;
+ }
+
+ cam_dbg("%s: ID =%d, val = %d\n",
+ __func__, ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
+
+ mutex_lock(&state->ctrl_lock);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_SENSOR_MODE:
+ err = sr130pc20_set_sensor_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_BRIGHTNESS:
+ err = sr130pc20_set_exposure(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ err = sr130pc20_set_from_table(sd, "white balance",
+ state->regs->white_balance,
+ ARRAY_SIZE(state->regs->white_balance), ctrl->value);
+ state->wb.mode = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_EFFECT:
+ err = sr130pc20_set_from_table(sd, "effects",
+ state->regs->effect,
+ ARRAY_SIZE(state->regs->effect), ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_METERING:
+ err = sr130pc20_set_from_table(sd, "metering",
+ state->regs->metering,
+ ARRAY_SIZE(state->regs->metering), ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SCENE_MODE:
+ err = sr130pc20_set_scene_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_ESD:
+ err = sr130pc20_check_esd(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_ISO:
+ err = sr130pc20_set_iso(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CAPTURE_MODE:
+ if (RUNMODE_RUNNING == state->runmode)
+ state->capture.pre_req = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_VT_MODE:
+ err = sr130pc20_set_vt_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_ANTI_BANDING:
+ break;
+
+ case V4L2_CID_CAMERA_OBJECT_POSITION_X:
+ case V4L2_CID_CAMERA_OBJECT_POSITION_Y:
+ case V4L2_CID_CAMERA_TOUCH_AF_START_STOP:
+ case V4L2_CID_CAMERA_FOCUS_MODE:
+ case V4L2_CID_CAMERA_SET_AUTO_FOCUS:
+ case V4L2_CID_CAMERA_FLASH_MODE:
+ case V4L2_CID_CAMERA_CONTRAST:
+ case V4L2_CID_CAMERA_SATURATION:
+ case V4L2_CID_CAMERA_SHARPNESS:
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ case V4L2_CID_CAMERA_AE_LOCK_UNLOCK:
+ case V4L2_CID_CAMERA_AWB_LOCK_UNLOCK:
+ default:
+ cam_err("%s: WARNING, unknown Ctrl-ID 0x%x\n",
+ __func__, ctrl->id);
+ /* we return no error. */
+ break;
+ }
+
+ mutex_unlock(&state->ctrl_lock);
+ CHECK_ERR_MSG(err, "s_ctrl failed %d\n", err)
+
+ return 0;
+}
+
+static int sr130pc20_s_ext_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_ext_control *ctrl)
+{
+ return 0;
+}
+
+static int sr130pc20_s_ext_ctrls(struct v4l2_subdev *sd,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct v4l2_ext_control *ctrl = ctrls->controls;
+ int ret;
+ int i;
+
+ for (i = 0; i < ctrls->count; i++, ctrl++) {
+ ret = sr130pc20_s_ext_ctrl(sd, ctrl);
+
+ if (ret) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int sr130pc20_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("stream mode = %d\n", enable);
+
+ if (unlikely(!state->initialized)) {
+ WARN(1, "s_stream, not initialized\n");
+ return -EPERM;
+ }
+
+ switch (enable) {
+ case STREAM_MODE_CAM_OFF:
+ if (state->pdata->is_mipi)
+ err = sr130pc20_control_stream(sd, STREAM_STOP);
+ break;
+
+ case STREAM_MODE_CAM_ON:
+ if (state->format_mode == V4L2_PIX_FMT_MODE_CAPTURE)
+ err = sr130pc20_start_capture(sd);
+ else
+ err = sr130pc20_start_preview(sd);
+ break;
+
+ case STREAM_MODE_MOVIE_OFF:
+ cam_info("movie off");
+ state->recording = 0;
+ break;
+
+ case STREAM_MODE_MOVIE_ON:
+ cam_info("movie on");
+ state->recording = 1;
+ break;
+
+ default:
+ cam_err("%s: error - Invalid stream mode\n", __func__);
+ break;
+ }
+
+ CHECK_ERR_MSG(err, "failed\n");
+
+ return 0;
+}
+
+static inline int sr130pc20_check_i2c(struct v4l2_subdev *sd, u16 data)
+{
+ return 0;
+}
+
+static void sr130pc20_init_parameter(struct v4l2_subdev *sd)
+{
+ struct sr130pc20_state *state = to_state(sd);
+
+ state->runmode = RUNMODE_INIT;
+
+ /* Default state values */
+ state->scene_mode = SCENE_MODE_NONE;
+ state->wb.mode = WHITE_BALANCE_AUTO;
+ state->light_level = LUX_LEVEL_MAX;
+
+ /* Set update_frmsize to 1 for case of power reset */
+ state->preview.update_frmsize = 1;
+
+ /* Initialize focus field for case of init after power reset. */
+ memset(&state->focus, 0, sizeof(state->focus));
+
+ state->lux_level_flash = LUX_LEVEL_FLASH_ON;
+ state->shutter_level_flash = 0x0;
+
+}
+
+static int sr130pc20_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_info("init: start (%s)\n", __DATE__);
+
+#ifdef CONFIG_LOAD_FILE
+ err = sr130pc20_regs_table_init();
+ CHECK_ERR_MSG(err, "loading setfile fail!\n");
+#endif
+ err = sr130pc20_init_regs(sd);
+ CHECK_ERR_MSG(err, "failed to indentify sensor chip\n");
+
+ err = sr130pc20_set_from_table(sd, "init_reg",
+ &state->regs->init_reg, 1, 0);
+
+ CHECK_ERR_MSG(err, "failed to initialize camera device\n");
+ sr130pc20_init_parameter(sd);
+ state->initialized = 1;
+ fimc_is = 1;
+
+ return 0;
+}
+
+/*
+ * s_config subdev ops
+ * With camera device, we need to re-initialize
+ * every single opening time therefor,
+ * it is not necessary to be initialized on probe time.
+ * except for version checking
+ * NOTE: version checking is optional
+ */
+static int sr130pc20_s_config(struct v4l2_subdev *sd,
+ int irq, void *platform_data)
+{
+ struct sr130pc20_state *state = to_state(sd);
+ int i;
+
+ if (!platform_data) {
+ cam_err("%s: error, no platform data\n", __func__);
+ return -ENODEV;
+ }
+ state->pdata = platform_data;
+ state->dbg_level = &state->pdata->dbg_level;
+
+ /*
+ * Assign default format and resolution
+ * Use configured default information in platform data
+ * or without them, use default information in driver
+ */
+ state->req_fmt.width = state->pdata->default_width;
+ state->req_fmt.height = state->pdata->default_height;
+
+ if (!state->pdata->pixelformat)
+ state->req_fmt.pixelformat = DEFAULT_PIX_FMT;
+ else
+ state->req_fmt.pixelformat = state->pdata->pixelformat;
+
+ if (!state->pdata->freq)
+ state->freq = DEFAULT_MCLK; /* 24MHz default */
+ else
+ state->freq = state->pdata->freq;
+
+ state->preview.frmsize = state->capture.frmsize = NULL;
+ state->sensor_mode = SENSOR_CAMERA;
+ state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW;
+ state->fps = 0;
+ state->req_fps = -1;
+ state->write_fps = 0;
+
+ /* Initialize the independant HW module like flash here */
+ state->flash.mode = FLASH_MODE_OFF;
+ state->flash.on = 0;
+
+ for (i = 0; i < ARRAY_SIZE(sr130pc20_ctrls); i++)
+ sr130pc20_ctrls[i].value = sr130pc20_ctrls[i].default_value;
+
+#ifdef SR130PC20_SUPPORT_FLASH
+ if (sr130pc20_is_hwflash_on(sd))
+ state->flash.ignore_flash = 1;
+#endif
+
+ state->regs = &reg_datas;
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops sr130pc20_core_ops = {
+ .init = sr130pc20_init, /* initializing API */
+ .g_ctrl = sr130pc20_g_ctrl,
+ .s_ctrl = sr130pc20_s_ctrl,
+ .s_ext_ctrls = sr130pc20_s_ext_ctrls,
+ /*eset = sr130pc20_reset, */
+};
+
+static const struct v4l2_subdev_video_ops sr130pc20_video_ops = {
+ .s_mbus_fmt = sr130pc20_s_mbus_fmt,
+ .enum_framesizes = sr130pc20_enum_framesizes,
+ .enum_mbus_fmt = sr130pc20_enum_mbus_fmt,
+ .try_mbus_fmt = sr130pc20_try_mbus_fmt,
+ .g_parm = sr130pc20_g_parm,
+ .s_parm = sr130pc20_s_parm,
+ .s_stream = sr130pc20_s_stream,
+};
+
+static const struct v4l2_subdev_ops sr130pc20_ops = {
+ .core = &sr130pc20_core_ops,
+ .video = &sr130pc20_video_ops,
+};
+
+
+/*
+ * sr130pc20_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int sr130pc20_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct v4l2_subdev *sd;
+ struct sr130pc20_state *state;
+ int err = -EINVAL;
+
+ state = kzalloc(sizeof(struct sr130pc20_state), GFP_KERNEL);
+ if (unlikely(!state)) {
+ dev_err(&client->dev, "probe, fail to get memory\n");
+ return -ENOMEM;
+ }
+
+ mutex_init(&state->ctrl_lock);
+
+ state->runmode = RUNMODE_NOTREADY;
+ sd = &state->sd;
+ strcpy(sd->name, SR130PC20_DRIVER_NAME);
+
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &sr130pc20_ops);
+
+ state->workqueue = create_workqueue("cam_workqueue");
+ if (unlikely(!state->workqueue)) {
+ dev_err(&client->dev, "probe, fail to create workqueue\n");
+ goto err_out;
+ }
+
+ err = sr130pc20_s_config(sd, 0, client->dev.platform_data);
+ CHECK_ERR_MSG(err, "fail to s_config\n");
+
+ printk(KERN_DEBUG "%s %s: driver probed!!\n",
+ dev_driver_string(&client->dev), dev_name(&client->dev));
+
+ return 0;
+
+err_out:
+ kfree(state);
+ return -ENOMEM;
+}
+
+static int sr130pc20_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct sr130pc20_state *state = to_state(sd);
+
+ destroy_workqueue(state->workqueue);
+
+ /* Check whether flash is on when unlolading driver,
+ * to preventing Market App from controlling improperly flash.
+ * It isn't necessary in case that you power flash down
+ * in power routine to turn camera off.*/
+ if (unlikely(state->flash.on && !state->flash.ignore_flash))
+ sr130pc20_flash_torch(sd, SR130PC20_FLASH_OFF);
+
+ v4l2_device_unregister_subdev(sd);
+ mutex_destroy(&state->ctrl_lock);
+ kfree(state);
+ fimc_is = 0;
+
+ printk(KERN_DEBUG "%s %s: driver removed!!\n",
+ dev_driver_string(&client->dev), dev_name(&client->dev));
+ return 0;
+}
+
+static int is_sysdev(struct device *dev, void *str)
+{
+ return !strcmp(dev_name(dev), (char *)str) ? 1 : 0;
+}
+
+static ssize_t cam_loglevel_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ char temp_buf[60] = {0,};
+
+ sprintf(buf, "Log Level: ");
+ if (dbg_level & CAMDBG_LEVEL_TRACE) {
+ sprintf(temp_buf, "trace ");
+ strcat(buf, temp_buf);
+ }
+
+ if (dbg_level & CAMDBG_LEVEL_DEBUG) {
+ sprintf(temp_buf, "debug ");
+ strcat(buf, temp_buf);
+ }
+
+ if (dbg_level & CAMDBG_LEVEL_INFO) {
+ sprintf(temp_buf, "info ");
+ strcat(buf, temp_buf);
+ }
+
+ sprintf(temp_buf, "\n - warn and error level is always on\n\n");
+ strcat(buf, temp_buf);
+
+ return strlen(buf);
+}
+
+static ssize_t cam_loglevel_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ printk(KERN_DEBUG "CAM buf=%s, count=%d\n", buf, count);
+
+ if (strstr(buf, "trace"))
+ dbg_level |= CAMDBG_LEVEL_TRACE;
+ else
+ dbg_level &= ~CAMDBG_LEVEL_TRACE;
+
+ if (strstr(buf, "debug"))
+ dbg_level |= CAMDBG_LEVEL_DEBUG;
+ else
+ dbg_level &= ~CAMDBG_LEVEL_DEBUG;
+
+ if (strstr(buf, "info"))
+ dbg_level |= CAMDBG_LEVEL_INFO;
+
+ return count;
+}
+
+static DEVICE_ATTR(loglevel, 0664, cam_loglevel_show, cam_loglevel_store);
+
+static int sr130pc20_create_dbglogfile(struct class *cls)
+{
+ struct device *dev;
+ int err;
+
+ dbg_level |= CAMDBG_LEVEL_DEFAULT;
+
+ dev = class_find_device(cls, NULL, "front", is_sysdev);
+ if (unlikely(!dev)) {
+ pr_info("[SR130PC20] can not find front device\n");
+ return 0;
+ }
+
+ err = device_create_file(dev, &dev_attr_loglevel);
+ if (unlikely(err < 0)) {
+ pr_err("cam_init: failed to create device file, %s\n",
+ dev_attr_loglevel.attr.name);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id sr130pc20_id[] = {
+ { SR130PC20_DRIVER_NAME, 0 },
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, sr130pc20_id);
+
+static struct i2c_driver v4l2_i2c_driver = {
+ .driver.name = SR130PC20_DRIVER_NAME,
+ .probe = sr130pc20_probe,
+ .remove = sr130pc20_remove,
+ .id_table = sr130pc20_id,
+};
+
+static int __init v4l2_i2c_drv_init(void)
+{
+ pr_info("%s: %s called\n", __func__, SR130PC20_DRIVER_NAME); /* dslim*/
+ sr130pc20_create_file(camera_class);
+ sr130pc20_create_dbglogfile(camera_class);
+ return i2c_add_driver(&v4l2_i2c_driver);
+}
+
+static void __exit v4l2_i2c_drv_cleanup(void)
+{
+ pr_info("%s: %s called\n", __func__, SR130PC20_DRIVER_NAME); /* dslim*/
+ i2c_del_driver(&v4l2_i2c_driver);
+}
+
+module_init(v4l2_i2c_drv_init);
+module_exit(v4l2_i2c_drv_cleanup);
+
+MODULE_DESCRIPTION("SILICONFILE SR130PC20 1.3MP SOC camera driver");
+MODULE_AUTHOR("Dong-Seong Lim <dongseong.lim@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/sr130pc20.h b/drivers/media/video/sr130pc20.h
new file mode 100755
index 0000000..25a5949
--- /dev/null
+++ b/drivers/media/video/sr130pc20.h
@@ -0,0 +1,655 @@
+/* drivers/media/video/sr130pc20.h
+ *
+ * Driver for sr130pc20 (1.5MP Camera) from siliconfile
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * 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.
+ *
+ * - change date: 2012.06.28
+ */
+
+#ifndef __SR130PC20_H__
+#define __SR130PC20_H__
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <linux/vmalloc.h>
+#include <linux/completion.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/sr130pc20_platform.h>
+#include <linux/videodev2_exynos_camera.h>
+#include <linux/workqueue.h>
+
+#define SR130PC20_DRIVER_NAME "SR130PC20"
+
+#define SR130PC20_DELAY 0xFFFF0000
+
+/************************************
+ * FEATURE DEFINITIONS
+ ************************************/
+#define CONFIG_CAM_YUV_CAPTURE
+#define CONFIG_CAM_I2C_LITTLE_ENDIAN
+/* #define CONFIG_LOAD_FILE *//* for tuning */
+/* #define CONFIG_DEBUG_NO_FRAME */
+
+/** Debuging Feature **/
+// #define CONFIG_CAM_DEBUG */
+// #define CONFIG_CAM_TRACE *//* Enable it with CONFIG_CAM_DEBUG */
+// #define CONFIG_CAM_AF_DEBUG *//* Enable it with CONFIG_CAM_DEBUG */
+#define DEBUG_WRITE_REGS
+/***********************************/
+
+#ifdef CONFIG_VIDEO_SR130PC20_DEBUG
+enum {
+ SR130PC20_DEBUG_I2C = 1U << 0,
+ SR130PC20_DEBUG_I2C_BURSTS = 1U << 1,
+};
+static uint32_t sr130pc20_debug_mask = SR130PC20_DEBUG_I2C_BURSTS;
+module_param_named(debug_mask, sr130pc20_debug_mask, uint, S_IWUSR | S_IRUGO);
+
+#define sr130pc20_debug(mask, x...) \
+ do { \
+ if (sr130pc20_debug_mask & mask) \
+ pr_info(x); \
+ } while (0)
+#else
+#define sr130pc20_debug(mask, x...)
+#endif
+
+#define TAG_NAME "["SR130PC20_DRIVER_NAME"]"" "
+
+/* Define debug level */
+#define CAMDBG_LEVEL_ERR (1 << 0)
+#define CAMDBG_LEVEL_WARN (1 << 1)
+#define CAMDBG_LEVEL_INFO (1 << 2)
+#define CAMDBG_LEVEL_DEBUG (1 << 3)
+#define CAMDBG_LEVEL_TRACE (1 << 4)
+#define CAMDBG_LEVEL_DEFAULT \
+ (CAMDBG_LEVEL_ERR | CAMDBG_LEVEL_WARN | CAMDBG_LEVEL_INFO)
+
+#define cam_err(fmt, ...) \
+ printk(KERN_ERR TAG_NAME fmt, ##__VA_ARGS__)
+#define cam_warn(fmt, ...) \
+ printk(KERN_WARNING TAG_NAME fmt, ##__VA_ARGS__)
+#define cam_info(fmt, ...) \
+ printk(KERN_INFO TAG_NAME fmt, ##__VA_ARGS__)
+
+#if defined(CONFIG_CAM_DEBUG)
+#define cam_dbg(fmt, ...) \
+ printk(KERN_DEBUG TAG_NAME fmt, ##__VA_ARGS__)
+#else
+#define cam_dbg(fmt, ...) \
+ do { \
+ if (dbg_level & CAMDBG_LEVEL_DEBUG) \
+ printk(KERN_DEBUG TAG_NAME fmt, ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+#if defined(CONFIG_CAM_DEBUG) && defined(CONFIG_CAM_TRACE)
+#define cam_trace(fmt, ...) cam_dbg("%s: " fmt, __func__, ##__VA_ARGS__);
+#else
+#define cam_trace(fmt, ...) \
+ do { \
+ if (dbg_level & CAMDBG_LEVEL_TRACE) \
+ printk(KERN_DEBUG TAG_NAME "%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ } while (0)
+#endif
+
+#if defined(CONFIG_CAM_DEBUG) && defined(CONFIG_CAM_AF_DEBUG)
+#define af_dbg(fmt, ...) cam_dbg(fmt, ##__VA_ARGS__);
+#else
+#define af_dbg(fmt, ...)
+#endif
+#if defined(CONFIG_CAM_DEBUG) && defined(CONFIG_CAM_BOOT_DEBUG)
+#define boot_dbg(fmt, ...) cam_dbg(fmt, ##__VA_ARGS__);
+#else
+#define boot_dbg(fmt, ...)
+#endif
+
+#if 0
+#define cam_bug_on(arg...) \
+ do { cam_err(arg); BUG_ON(1); } while (0)
+#else
+#define cam_bug_on(arg...)
+#endif
+
+#define CHECK_ERR_COND(condition, ret) \
+ do { if (unlikely(condition)) return ret; } while (0)
+#define CHECK_ERR_COND_MSG(condition, ret, fmt, ...) \
+ if (unlikely(condition)) { \
+ cam_err("%s: error, " fmt, __func__, ##__VA_ARGS__); \
+ return ret; \
+ }
+
+#define CHECK_ERR(x) CHECK_ERR_COND(((x) < 0), (x))
+#define CHECK_ERR_MSG(x, fmt, ...) \
+ CHECK_ERR_COND_MSG(((x) < 0), (x), fmt, ##__VA_ARGS__)
+
+/* result values returned to HAL */
+enum af_result_status {
+ AF_RESULT_NONE = 0x00,
+ AF_RESULT_FAILED = 0x01,
+ AF_RESULT_SUCCESS = 0x02,
+ AF_RESULT_CANCELLED = 0x04,
+ AF_RESULT_DOING = 0x08
+};
+
+enum af_operation_status {
+ AF_NONE = 0,
+ AF_START,
+ AF_CANCEL,
+};
+
+enum preflash_status {
+ PREFLASH_NONE = 0,
+ PREFLASH_OFF,
+ PREFLASH_ON,
+};
+
+enum sr130pc20_oprmode {
+ SR130PC20_OPRMODE_VIDEO = 0,
+ SR130PC20_OPRMODE_IMAGE = 1,
+};
+
+enum stream_cmd {
+ STREAM_STOP,
+ STREAM_START,
+};
+
+enum wide_req_cmd {
+ WIDE_REQ_NONE,
+ WIDE_REQ_CHANGE,
+ WIDE_REQ_RESTORE,
+};
+
+/* Preview Size List: refer to the belows. */
+enum sr130pc20_preview_frame_size {
+ PREVIEW_SZ_QCIF = 0, /* 176x144 */
+ PREVIEW_SZ_320x240, /* 320x240 */
+ PREVIEW_SZ_CIF, /* 352x288 */
+ PREVIEW_SZ_528x432, /* 528x432 */
+ PREVIEW_SZ_VGA, /* 640x480 */
+ PREVIEW_SZ_D1, /* 720x480 */
+ PREVIEW_SZ_880x720, /* 880x720 */
+ PREVIEW_SZ_SVGA, /* 800x600 */
+ PREVIEW_SZ_1024x576, /* 1024x576, 16:9 */
+ PREVIEW_SZ_1024x616, /* 1024x616, ? */
+ PREVIEW_SZ_XGA, /* 1024x768 */
+ PREVIEW_SZ_PVGA, /* 1280x720 */
+ PREVIEW_SZ_SXGA, /* 1280x1024 */
+ PREVIEW_SZ_MAX,
+};
+
+/* Capture Size List: Capture size is defined as below.
+ *
+ * CAPTURE_SZ_VGA: 640x480
+ * CAPTURE_SZ_WVGA: 800x480
+ * CAPTURE_SZ_SVGA: 800x600
+ * CAPTURE_SZ_WSVGA: 1024x600
+ * CAPTURE_SZ_1MP: 1280x960
+ * CAPTURE_SZ_W1MP: 1600x960
+ * CAPTURE_SZ_2MP: UXGA - 1600x1200
+ * CAPTURE_SZ_W2MP: 35mm Academy Offset Standard 1.66
+ * 2048x1232, 2.4MP
+ * CAPTURE_SZ_3MP: QXGA - 2048x1536
+ * CAPTURE_SZ_W4MP: WQXGA - 2560x1536
+ * CAPTURE_SZ_5MP: 2560x1920
+ */
+
+enum sr130pc20_capture_frame_size {
+ /*CAPTURE_SZ_VGA = 0,*/ /* 640x480 */
+ /*CAPTURE_SZ_960_720,*/
+ CAPTURE_SZ_1MP,/* 1280x960 */
+ CAPTURE_SZ_MAX,
+};
+
+#define PREVIEW_WIDE_SIZE PREVIEW_SZ_1024x576
+#define CAPTURE_WIDE_SIZE CAPTURE_SZ_W2MP
+
+enum frame_ratio {
+ FRMRATIO_QCIF = 12, /* 11 : 9 */
+ FRMRATIO_VGA = 13, /* 4 : 3 */
+ FRMRATIO_D1 = 15, /* 3 : 2 */
+ FRMRATIO_WVGA = 16, /* 5 : 3 */
+ FRMRATIO_HD = 17, /* 16 : 9 */
+};
+
+enum sr130pc20_fps_index {
+ I_FPS_0,
+ I_FPS_7,
+ I_FPS_10,
+ I_FPS_12,
+ I_FPS_15,
+ I_FPS_25,
+ I_FPS_30,
+ I_FPS_MAX,
+};
+
+enum ae_awb_lock {
+ AEAWB_UNLOCK = 0,
+ AEAWB_LOCK,
+ AEAWB_LOCK_MAX,
+};
+
+enum runmode {
+ RUNMODE_NOTREADY,
+ RUNMODE_INIT,
+ /*RUNMODE_IDLE,*/
+ RUNMODE_RUNNING, /* previewing */
+ RUNMODE_RUNNING_STOP,
+ RUNMODE_CAPTURING,
+ RUNMODE_CAPTURING_STOP,
+ RUNMODE_RECORDING, /* camcorder mode */
+ RUNMODE_RECORDING_STOP,
+};
+
+enum sr130pc20_stby_type {
+ SR130PC20_STBY_HW,
+ SR130PC20_STBY_SW,
+};
+
+enum sr130_pc20_preview_mode {
+ PREVIEW_CAMERA = 1,
+ PREVIEW_VIDEOCALL,
+ PREVIEW_SMARTSTAY,
+};
+
+struct sr130pc20_control {
+ u32 id;
+ s32 value;
+ s32 default_value;
+};
+
+#define SR130PC20_INIT_CONTROL(ctrl_id, default_val) \
+ { \
+ .id = ctrl_id, \
+ .value = default_val, \
+ .default_value = default_val, \
+ }
+
+struct sr130pc20_framesize {
+ s32 index;
+ u32 width;
+ u32 height;
+};
+
+#define FRM_RATIO(framesize) \
+ (((framesize)->width) * 10 / ((framesize)->height))
+
+struct sr130pc20_fps {
+ u32 index;
+ u32 fps;
+};
+
+struct sr130pc20_version {
+ u32 major;
+ u32 minor;
+};
+
+struct sr130pc20_date_info {
+ u32 year;
+ u32 month;
+ u32 date;
+};
+
+struct sr130pc20_firmware {
+ u32 addr;
+ u32 size;
+};
+
+struct sr130pc20_jpeg_param {
+ u32 enable;
+ u32 quality;
+ u32 main_size; /* Main JPEG file size */
+ u32 thumb_size; /* Thumbnail file size */
+ u32 main_offset;
+ u32 thumb_offset;
+ /* u32 postview_offset; */
+};
+
+struct sr130pc20_position {
+ s32 x;
+ s32 y;
+};
+
+struct sr130pc20_rect {
+ s32 x;
+ s32 y;
+ u32 width;
+ u32 height;
+};
+
+struct gps_info_common {
+ u32 direction;
+ u32 dgree;
+ u32 minute;
+ u32 second;
+};
+
+struct sr130pc20_gps_info {
+ u8 gps_buf[8];
+ u8 altitude_buf[4];
+ s32 gps_timeStamp;
+};
+
+struct sr130pc20_preview {
+ const struct sr130pc20_framesize *frmsize;
+ u32 update_frmsize:1;
+ u32 fast_ae:1;
+};
+
+struct sr130pc20_capture {
+ const struct sr130pc20_framesize *frmsize;
+ u32 pre_req; /* for fast capture */
+ u32 ae_manual_mode:1;
+ u32 lowlux_night:1;
+ u32 ready:1; /* for fast capture */
+};
+
+/* Focus struct */
+struct sr130pc20_focus {
+ enum v4l2_focusmode mode;
+ enum af_result_status status;
+
+ u32 pos_x;
+ u32 pos_y;
+
+ u32 start:1; /* enum v4l2_auto_focus*/
+ u32 touch:1;
+ u32 lock:1; /* set if single AF is done */
+};
+
+/* struct for sensor specific data */
+struct sr130pc20_ae_gain_offset {
+ u32 ae_auto;
+ u32 ae_now;
+ u32 ersc_auto;
+ u32 ersc_now;
+
+ u32 ae_ofsetval;
+ u32 ae_maxdiff;
+};
+
+/* Flash struct */
+struct sr130pc20_flash {
+ struct sr130pc20_ae_gain_offset ae_offset;
+ enum v4l2_flash_mode mode;
+ enum preflash_status preflash;
+ u32 awb_delay;
+ u32 ae_scl; /* for back-up */
+ u32 on:1; /* flash on/off */
+ u32 ignore_flash:1;
+ u32 ae_flash_lock:1;
+};
+
+/* Exposure struct */
+struct sr130pc20_exposure {
+ s32 val; /* exposure value */
+ u32 ae_lock:1;
+};
+
+/* White Balance struct */
+struct sr130pc20_whitebalance {
+ enum v4l2_wb_mode mode; /* wb mode */
+ u32 awb_lock:1;
+};
+
+struct sr130pc20_exif {
+ u16 exp_time_den;
+ u16 iso;
+ u16 flash;
+
+ /*int bv;*/ /* brightness */
+ /*int ebv;*/ /* exposure bias */
+};
+
+/* EXIF - flash filed */
+#define EXIF_FLASH_FIRED (0x01)
+#define EXIF_FLASH_MODE_FIRING (0x01 << 3)
+#define EXIF_FLASH_MODE_SUPPRESSION (0x02 << 3)
+#define EXIF_FLASH_MODE_AUTO (0x03 << 3)
+
+struct sr130pc20_stream_time {
+ struct timeval curr_time;
+ struct timeval before_time;
+};
+
+#define GET_ELAPSED_TIME(cur, before) \
+ (((cur).tv_sec - (before).tv_sec) * USEC_PER_SEC \
+ + ((cur).tv_usec - (before).tv_usec))
+
+typedef u16 sr130pc20_regset_t;
+
+typedef struct isx012_regset {
+ u16 subaddr;
+ u32 value;
+ u32 len;
+} isx012_regset_t;
+
+#ifdef CONFIG_LOAD_FILE
+#define DEBUG_WRITE_REGS
+struct regset_table {
+ const char *const name;
+};
+
+#define SR130PC20_REGSET(x, y, z) \
+ [(x)] = { \
+ .name = #y, \
+ }
+
+#define SR130PC20_REGSET_TABLE(y, z) \
+ { \
+ .name = #y, \
+ }
+
+#else /* !CONFIG_LOAD_FILE */
+
+struct regset_table {
+ const sr130pc20_regset_t * const reg;
+ const u32 array_size;
+#ifdef DEBUG_WRITE_REGS
+ const char * const name;
+#endif
+ const u32 burst; /* on/off */
+};
+
+#ifdef DEBUG_WRITE_REGS
+#define SR130PC20_REGSET(x, y, z) \
+ [(x)] = { \
+ .reg = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+ .name = #y, \
+ .burst = z, \
+ }
+#define SR130PC20_REGSET_TABLE(y, z) \
+ { \
+ .reg = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+ .name = #y, \
+ .burst = z, \
+ }
+#else /* !DEBUG_WRITE_REGS */
+#define SR130PC20_REGSET(x, y, z) \
+ [(x)] = { \
+ .reg = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+ .burst = z, \
+ }
+#define SR130PC20_REGSET_TABLE(y, z) \
+ { \
+ .reg = (y), \
+ .array_size = ARRAY_SIZE((y)), \
+ .burst = z, \
+ }
+#endif /* DEBUG_WRITE_REGS */
+
+#endif /* CONFIG_LOAD_FILE */
+
+#define EV_MIN_VLAUE EV_MINUS_4
+#define GET_EV_INDEX(EV) ((EV) - (EV_MIN_VLAUE))
+
+struct sr130pc20_regs {
+ struct regset_table ev[GET_EV_INDEX(EV_MAX_V4L2)];
+ struct regset_table metering[METERING_MAX];
+ struct regset_table iso[ISO_MAX];
+ struct regset_table effect[IMAGE_EFFECT_MAX];
+ struct regset_table white_balance[WHITE_BALANCE_MAX];
+ struct regset_table preview_size[PREVIEW_SZ_MAX];
+ struct regset_table capture_size[CAPTURE_SZ_MAX];
+ struct regset_table scene_mode[SCENE_MODE_MAX];
+ struct regset_table fps[I_FPS_MAX];
+ /* camera mode */
+ struct regset_table preview_mode;
+ struct regset_table capture_mode;
+ struct regset_table capture_mode_night;
+ struct regset_table stream_stop;
+ struct regset_table init_reg;
+ struct regset_table VT_init_reg;
+ struct regset_table SS_init_reg;
+};
+
+struct sr130pc20_state {
+ struct sr130pc20_platform_data *pdata;
+ struct v4l2_subdev sd;
+ struct v4l2_pix_format req_fmt;
+ struct sr130pc20_preview preview;
+ struct sr130pc20_capture capture;
+ struct sr130pc20_focus focus;
+ struct sr130pc20_flash flash;
+ struct sr130pc20_exposure exposure;
+ struct sr130pc20_whitebalance wb;
+ struct sr130pc20_exif exif;
+#if !defined(CONFIG_CAM_YUV_CAPTURE)
+ struct sr130pc20_jpeg_param jpeg;
+#endif
+ struct sr130pc20_stream_time stream_time;
+ const struct sr130pc20_regs *regs;
+ struct mutex ctrl_lock;
+ struct mutex af_lock;
+ struct workqueue_struct *workqueue;
+ struct work_struct af_work;
+ struct work_struct af_win_work;
+#ifdef CONFIG_DEBUG_NO_FRAME
+ struct work_struct frame_work;
+#endif
+ enum runmode runmode;
+ enum v4l2_sensor_mode sensor_mode;
+ enum v4l2_pix_format_mode format_mode;
+ enum v4l2_scene_mode scene_mode;
+ enum v4l2_iso_mode iso;
+
+ s32 vt_mode;
+ s32 req_fps;
+ s32 fps;
+ s32 write_fps;
+ s32 freq; /* MCLK in Hz */
+ u32 one_frame_delay_ms;
+ u32 light_level; /* light level */
+ u32 lux_level_flash;
+ u32 shutter_level_flash;
+ u8 *dbg_level;
+#ifdef CONFIG_DEBUG_NO_FRAME
+ bool frame_check;
+#endif
+ u32 recording:1;
+ u32 hd_videomode:1;
+ u32 need_wait_streamoff:1;
+ u32 initialized:1;
+};
+
+static inline struct sr130pc20_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct sr130pc20_state, sd);
+}
+
+static inline int sr130pc20_restore_sensor_flash(struct v4l2_subdev *sd);
+static int sr130pc20_set_capture(struct v4l2_subdev *sd);
+static int sr130pc20_prepare_fast_capture(struct v4l2_subdev *sd);
+static int sr130pc20_control_stream(struct v4l2_subdev *sd, u32 cmd);
+
+extern struct class *camera_class;
+extern int sr130pc20_create_file(struct class *cls);
+
+#if !defined(CONFIG_CAM_YUV_CAPTURE)
+/* JPEG MEMORY SIZE */
+#define SENSOR_JPEG_OUTPUT_MAXSIZE 0x29999A /*2726298bytes, 2.6M */
+#define EXTRA_MEMSIZE (0 * SZ_1K)
+#define SENSOR_JPEG_SNAPSHOT_MEMSIZE \
+ (((SENSOR_JPEG_OUTPUT_MAXSIZE + EXTRA_MEMSIZE + SZ_16K-1) / SZ_16K) * SZ_16K)
+#endif
+
+/*********** Sensor specific ************/
+#define DELAY_SEQ 0xFF
+#define SR130PC20_CHIP_ID 0xC1
+
+#define SR130PC20_INTSRC_VINT (0x01 << 5)
+
+#define POLL_TIME_MS 10
+#define CAPTURE_POLL_TIME_MS 1000
+
+/* maximum time for one frame in norma light */
+#define ONE_FRAME_DELAY_MS_NORMAL 66
+/* maximum time for one frame in low light: minimum 10fps. */
+#define ONE_FRAME_DELAY_MS_LOW 100
+/* maximum time for one frame in night mode: 6fps */
+#define ONE_FRAME_DELAY_MS_NIGHTMODE 166
+
+/* level at or below which we need to enable flash when in auto mode */
+#define LUX_LEVEL_MAX 0x00 /* the brightest */
+#define LUX_LEVEL_LOW 0x3D /* low light */
+#define LUX_LEVEL_FLASH_ON 0x2B
+
+/* Count for loop */
+#define SR130PC20_CNT_CAPTURE_FRM 330
+#define SR130PC20_CNT_CLEAR_VINT 20
+#define SR130PC20_CNT_AE_STABLE 100 /* for checking MODESEL_FIX */
+#define SR130PC20_CNT_CAPTURE_AWB 3 /* 8 -> 3 */
+#define SR130PC20_CNT_OM_CHECK 30
+#define SR130PC20_CNT_CM_CHECK 280 /* 160 -> 180 */
+#define SR130PC20_CNT_STREAMOFF 300
+
+#define AF_SEARCH_COUNT 550 /* about 6s */
+#define AE_STABLE_SEARCH_COUNT 7
+
+/* Sensor AF first,second window size.
+ * we use constant values intead of reading sensor register */
+#define DEFAULT_WINDOW_WIDTH 80
+#define DEFAULT_WINDOW_HEIGHT 80
+#define AF_PRECISION 100
+
+/* diff value fior fast AE in preview */
+#define AESCL_DIFF_FASTAE 1000
+
+
+/*
+ * Register Address Definition
+ */
+
+/* The Path of Setfile */
+#ifdef CONFIG_LOAD_FILE
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#ifdef CONFIG_MACH_KONA
+#define TUNING_FILE_PATH "/mnt/sdcard/sr130pc20_regs_kona.h"
+#else
+#define TUNING_FILE_PATH "/mnt/sdcard/sr130pc20_regs.h"
+#endif /* CONFIG_MACH_KONA */
+#endif /* CONFIG_LOAD_FILE*/
+
+#ifdef CONFIG_MACH_KONA
+#include "sr130pc20_regs_kona.h"
+#else
+#include "sr130pc20_regs.h"
+#endif
+
+#endif /* __SR130PC20_H__ */
diff --git a/drivers/media/video/sr130pc20_regs.h b/drivers/media/video/sr130pc20_regs.h
new file mode 100644
index 0000000..ebc578b
--- /dev/null
+++ b/drivers/media/video/sr130pc20_regs.h
@@ -0,0 +1,4229 @@
+/* sr130pc20_regs.h
+ *
+ * Driver for s5k5ccgx (5MP Camera) from siliconfile
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * 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.
+ *
+ * Change Date: 2012.06.28
+ */
+
+#ifndef __SR130PC20_REGS_H__
+#define __SR130PC20_REGS_H__
+
+/* PV 1st */
+
+static const sr130pc20_regset_t SR130PC20_Init_Reg[] = {
+
+/*0 Page*/
+0x0300,
+0x0101, /*sleep*/
+0x0103, /*s/w reset*/
+0x0101, /*sleep*/
+
+0x0800,/*Don't touch*/
+0x0937,/*Don't touch*/
+0x0a33,/*Don't touch*/
+
+/*PLL Setting*/
+0xd005,
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x1011,
+0x1190, /*xy flip*/
+0x1200,
+0x1488,
+
+0x0300,
+0x2000,
+0x2104,
+0x2200,
+0x2304,
+0x2403,
+0x25C0,
+0x2605,
+0x2700,
+
+0x4001, /*Hblank_280*/
+0x4118,
+0x4200, /*Vblank 100*/
+0x4364,
+
+/*--------------- BLC*/
+0x8008, /*Don't touch */
+0x8197, /*Don't touch */
+0x8290, /*Don't touch */
+0x8330, /*Don't touch */
+0x84cc, /*Don't touch*/
+0x8500, /*Don't touch*/
+0x86d4, /*Don' t touch*/
+0x870f, /*Don't touch*/
+0x8834, /*Don't touch*/
+
+0x900c, /*BLC_TIME_TH_ON*/
+0x910c, /*BLC_TIME_TH_OFF */
+0x92f0, /*BLC_AG_TH_ON*/
+0x93e8, /*BLC_AG_TH_OFF*/
+
+0x9495, /*091202*/
+0x9590, /*091202 */
+0x9838, /*Don't touch*/
+
+/*Dark BLC*/
+0xa001, /* 20100309*/
+0xa201, /* 20100309*/
+0xa401, /* 20100309*/
+0xa601, /* 20100309*/
+
+/*Normal BLC*/
+0xa800,
+0xaa00,
+0xac00,
+0xae00,
+
+/*Out BLC*/
+0x9900,
+0x9a00,
+0x9b00,
+0x9c00,
+
+/*2 Page*/
+0x0302,
+0x1200, /*Don't touch*/
+0x1400, /*Don't touch*/
+0x1500, /*Don't touch*/
+0x184C, /*Don't touch*/
+0x1900, /*Don't touch*/
+0x1A39, /*Don't touch*/
+0x1B00,/*Don't touch*/
+0x1C1a, /*Don't touch*/
+0x1D14, /*Don't touch*/
+0x1E30,/*Don't touch*/
+0x1F10,/*Don't touch*/
+
+0x2077,
+0x21de,
+0x22a7,
+0x2330,
+0x2477,
+0x2510,
+0x2610,
+0x273c,
+0x2b80,
+0x2c02,
+0x2da0,
+0x2e00,
+0x2fa7,
+
+0x3000,
+0x3199,
+0x3200,
+0x3300,
+0x3422,
+0x3601,
+0x3701,
+0x3888,
+0x3988,
+0x3d03,
+0x3e0d,
+0x3f02,
+
+0x49d1,
+0x4a14,
+
+0x5021,
+0x5201,
+0x5381,
+0x5410,
+0x551c,
+0x5611,
+0x5818,
+0x5916,
+0x5da2,
+0x5e5a,
+
+0x6093, /* 20120517 modify*/
+0x61a4, /* 20120517 modify*/
+0x6294, /* 20120517 modify*/
+0x63a3, /* 20120517 modify*/
+0x6494, /* 20120517 modify*/
+0x65a3, /* 20120517 modify*/
+0x670c,
+0x680c,
+0x690c,
+0x6ab4,
+0x6bc4,
+0x6cb5,
+0x6dc2,
+0x6eb5,
+0x6fc0,
+
+0x70b6,
+0x71b8,
+0x7295, /* 20120517 modify*/
+0x73a2, /* 20120517 modify*/
+0x7495, /* 20120517 modify*/
+0x75a2, /* 20120517 modify*/
+0x7695, /* 20120517 modify*/
+0x77a2, /* 20120517 modify*/
+0x7C92, /* 20120517 modify*/
+0x7Dff, /* 20120517 modify*/
+
+0x8001, /* 20120517 modify*/
+0x818a, /* 20120517 modify*/
+0x821e, /* 20120517 modify*/
+0x8336, /* 20120517 modify*/
+0x8489, /* 20120517 modify*/
+0x858b, /* 20120517 modify*/
+0x8689, /* 20120517 modify*/
+0x878b, /* 20120517 modify*/
+0x88ab,
+0x89bc,
+0x8aac,
+0x8bba,
+0x8cad,
+0x8db8,
+0x8eae,
+0x8fb2,
+
+0x90b3,
+0x91b7,
+0x9252, /* 20120517 modify*/
+0x936a, /* 20120517 modify*/
+0x9489, /* 20120517 modify*/
+0x958b, /* 20120517 modify*/
+0x9689, /* 20120517 modify*/
+0x978b, /* 20120517 modify*/
+
+0xA002,
+0xA186, /* 20120517 modify*/
+0xA202,
+0xA386, /* 20120517 modify*/
+0xA486, /* 20120517 modify*/
+0xA502,
+0xA686, /* 20120517 modify*/
+0xA702,
+0xA892, /* 20120517 modify*/
+0xA994, /* 20120517 modify*/
+0xAA92, /* 20120517 modify*/
+0xAB94, /* 20120517 modify*/
+0xAC1c,
+0xAD22,
+0xAE1c,
+0xAF22,
+
+0xB0a4, /* 20120517 modify*/
+0xB1ae, /* 20120517 modify*/
+0xB2a4, /* 20120517 modify*/
+0xB3ae, /* 20120517 modify*/
+0xB4a6, /* 20120517 modify*/
+0xB5ac, /* 20120517 modify*/
+0xB6a6, /* 20120517 modify*/
+0xB7ac, /* 20120517 modify*/
+0xB8a6, /* 20120517 modify*/
+0xB9ab, /* 20120517 modify*/
+0xBAa6, /* 20120517 modify*/
+0xBBab, /* 20120517 modify*/
+0xBCa6, /* 20120517 modify*/
+0xBDab, /* 20120517 modify*/
+0xBEa6, /* 20120517 modify*/
+0xBFab, /* 20120517 modify*/
+
+0xc437,
+0xc552,
+0xc66b,
+0xc786,
+0xc838, /* 20120517 modify*/
+0xc950, /* 20120517 modify*/
+0xca38, /* 20120517 modify*/
+0xcb50, /* 20120517 modify*/
+0xcc6c, /* 20120517 modify*/
+0xcd84, /* 20120517 modify*/
+0xce6c, /* 20120517 modify*/
+0xcf84, /* 20120517 modify*/
+
+/*0xd4a6,*/
+/*0xd5ac,*/
+/*0xd6a6,*/
+/*0xd7ac,*/
+/*add 20120517*/
+0xdc00, /* Added*/
+0xddaf, /* Added*/
+0xde00, /* Added*/
+0xdf90, /* Added*/
+
+0xd010,
+0xd114,
+0xd220,
+0xd300,
+/*DCDC */
+0xd40c, /*DCDC_TIME_TH_ON*/
+0xd50c, /*DCDC_TIME_TH_OFF */
+0xd6f0, /*DCDC_AG_TH_ON*/
+0xd7e8, /*DCDC_AG_TH_OFF*/
+
+0xea8a,
+
+0xF001, /* clock inversion*/
+0xF101,
+0xF201,
+0xF301,
+0xF401,
+0xF500,
+
+/*----------------------------------------------*/
+0x0310, /*page 10*/
+0x1001, /*Ycbcr422_bit Order: YUYV*/
+0x1103,
+0x1230, /*y offset[4], dif_offset[5]*/
+0x1302, /*contrast effet enable : 0x02*/
+0x3400, /*hidden 10->00 100209*/
+0x3701, /*yc2d power save */
+0x3f04, /*100825*/
+0x4080, /*Y offset */
+0x4880,
+0x5300, /*dif_offset option */
+0x5530, /*dif_offset option diff_offset max */
+
+0x604f, /*out color sat en[7] | auto color decrement en[1] /
+ | manual color sat en[0]*/
+
+0x6183, /*blue saturation_C0*/
+0x6280, /*red saturation_B0*/
+
+0x63ff, /*auto decresment on AG th*/
+0x64c0, /*auto decresment on DG th*/
+0x66e4, /*Outdoor saturation step 137fps apply out th */
+0x6703, /*Outdoor saturation B/R*/
+0x7601, /* ADD 20121031 */
+0x7904, /* ADD 20121031 */
+
+/* Hi 163 */
+/* PAGE 10 START*/
+0x0310,
+0x8000, /* dsshin --> color enhance*/
+0xf500, /* dsshin --> h blank option*/
+
+0x0311, /*page 11 D_LPF */
+0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/
+0x1120, /* Uniform Full GbGr/OV-Nr*/
+
+0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/
+0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */
+
+0x30ba, /*Outdoor2 H th*/
+0x3110, /*Outdoor2 L th*/
+0x3250, /*Outdoor2 gain ratio*/
+0x331d, /*Outdoor2 H lum*/
+0x3420, /*Outdoor2 M lum*/
+0x351f, /*Outdoor2 L lum*/
+
+0x36b0, /*Outdoor1 H th*/
+0x3718, /*Outdoor1 L th*/
+0x3850, /*Outdoor1 gain ratio 0x80->40*/
+0x391d, /*Outdoor1 H lum 0x28->1e*/
+0x3a20, /*Outdoor1 M lum 0x10->15*/
+0x3b1f, /*Outdoor1 L lum 0x08->20*/
+
+0x3c3f, /*indoor H th*/
+0x3d16, /*indoor L th*/
+0x3e30, /*indoor gain ratio 0x44 6a */
+0x3f1a, /*indoor H lum 0x12 18 */
+0x4060, /*indoor M lum 0x18 1c*/
+0x411a, /*indoor L lum 0x18 3e*/
+
+0x4298, /*dark1 H th*/
+0x4328, /*dark1 L th*/
+0x4465, /*dark1 gain ratio*/
+0x4516, /*dark1 H lum 0x38->0x28 */
+0x4630, /*dark1 M lum 0x27->0x17*/
+0x4734, /*dark1 L lum 0x20->0x1a */
+
+0x4890, /*dark2 H th*/
+0x492a, /*dark2 L th*/
+0x4a65, /*dark2 gain ratio*/
+0x4b18, /*dark2 H lum */
+0x4c31, /*dark2 M lum*/
+0x4d36, /*dark2 L lum */
+
+0x4e80, /*dark3 H th*/
+0x4f30, /*dark3 L th*/
+0x5065, /*dark3 gain ratio*/
+0x5119, /*dark3 H lum */
+0x5231, /*dark3 M lum */
+0x5336, /*dark3 L lum */
+
+0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */
+0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/
+0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/
+
+0x603f, /*GbGr all enable*/
+0x620f, /*GbGr offset*/
+
+0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/
+0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/
+0x6700, /*dark GbGr rate H/M/L 100%*/
+
+0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/
+0x75a0, /* Outdoor2 Abberation Luminance lvl */
+0x7db4, /* Indoor Abberation Luminance lvl*/
+
+0x9608, /*indoor/Dark1 edgeoffset1*/
+0x9714, /*indoor/Dark1 center G value*/
+0x98f5, /*slope indoor :: left/right graph polarity, slope*/
+0x992a, /*indoor uncertain ratio control*/
+0x9a20, /*Edgeoffset_dark*/
+
+/*DPC_CTRL*/
+0x0312, /*Preview DPC off[0x5c] on[0x5d]*/
+0x200f,
+0x210f,
+
+0x2500, /* 0x30*/
+
+0x2a01,
+0x2e00, /*2010.8.25*/
+
+0x3035, /*Texture region(most detail)*/
+0x31a0, /*STD uniform1 most blur region*/
+0x32b0, /*STD uniform2 2nd blur*/
+0x33c0, /*STD uniform3 3rd blur*/
+0x34d0, /*STD normal noise1 4th blur */
+0x35e0, /*STD normal noise2 5th blur*/
+0x36ff, /*STD normal noise3 6th blur*/
+
+0x4083, /*Outdoor2 H th*/
+0x4120, /*Outdoor2 L th */
+0x4208, /*Outdoor2 H luminance */
+0x4310, /*Outdoor2 M luminance */
+0x4410, /*Outdoor2 l luminance */
+0x4550, /*Outdoor2 ratio*/
+
+0x4683, /*Outdoor1 H th*/
+0x4720, /*Outdoor1 L th */
+0x4808, /*Outdoor1 H luminance*/
+0x4910, /*Outdoor1 M luminance*/
+0x4a10, /*Outdoor1 L luminance*/
+0x4b50, /*Outdoor1 ratio*/
+
+0x4c80, /*Indoor H th*/
+0x4d48, /*Indoor L th*/
+0x4e30, /*indoor H lum*/
+0x4f30, /*indoor M lum*/
+0x5012, /*indoor L lum */
+0x5170, /*indoor ratio 0x10 -> 0x45*/
+
+0x52a8, /*dark1 H th*/
+0x5330, /*dark1 L th */
+0x5428, /*dark1 H lum */
+0x553e, /*dark1 M lum*/
+0x5667, /*dark1 L lum*/
+0x576a, /*dark1 ratio*/
+
+0x58a0, /*dark2 H th*/
+0x5940, /*dark2 L th*/
+0x5a28, /*dark2 H lum*/
+0x5b3f, /*dark2 M lum*/
+0x5c68, /*dark2 L lum*/
+0x5d70, /*dark2 ratio*/
+
+0x5ea0, /*dark3 H th*/
+0x5f40, /*dark3 L th*/
+0x6029, /*dark3 H lum*/
+0x613f, /*dark3 M lum*/
+0x6269, /*dark3 L lum*/
+0x636a, /*dark3 ratio*/
+
+/*C-filter(Out2&Out1)*/
+0x7010,
+0x710a,
+
+/*C-filter(Indoor&Dark3)*/
+0x7210,
+0x730a,
+
+/*C-filter(Dark2&Dark1)*/
+0x7418,
+0x7512,
+
+0x8020,
+0x8140,
+0x8265,
+0x851a,
+0x8800,
+0x8900,
+0x905d, /*Preview DPC off[0x5c] on[0x5d]*/
+
+/*DPC-Dark1,2,3*/
+0xad07, /*10825*/
+0xae07, /*10825*/
+0xaf07, /*10825*/
+
+/*Blue Det..*/
+0xc558, /*BlueRange 2010.8.25 0x40->23 */
+0xc620, /*GreenRange 2010.8.25 0x3b->20 */
+
+0xd088, /*2010.8.25*/
+0xd180,
+0xd217,/*preview 17, full 67*/
+0xd300,
+0xd400,
+0xd50f,/*preview 0f, full 02*/
+0xd6ff,
+0xd7ff,/*preview ff, full 18*/
+0xd800,
+0xd904,
+
+/*interpolated with average*/
+0xdb38, /*resolution issue 0x00->0x18->0x38 */
+0xd904, /*strong_edge detect ratio*/
+0xe001, /*strong_edge detect ratio*/
+
+0x0313, /*page 13 sharpness 1D*/
+0x10c5,
+0x117b,
+0x120e,
+0x1400,
+
+0x1511, /*added option 1.3M*/
+0x1830, /*added option 1.3M*/
+
+0x2015,
+0x2113,
+0x2233,
+0x2308, /*hi_clip th1*/
+0x241a, /*hi_clip th2*/
+0x2506, /*low clip th*/
+
+0x2618,
+0x2730,
+0x2910, /*time th*/
+0x2a30, /*pga th*/
+
+0x2b03, /*lpf out2*/
+0x2c03, /*lpf out1*/
+0x2d0c,
+0x2e12,
+0x2f12,
+
+/*1D Edge*/
+0x500a, /*out2 hi nega*/
+0x5307, /* hi pos*/
+0x510c, /* mi nega*/
+0x5407, /* mi pos*/
+0x520b, /* lo nega*/
+0x5508, /* lo pos*/
+
+0x560a, /*out1 hi nega*/
+0x5907, /* hi pos */
+0x570c, /* mi nega*/
+0x5a07, /* mi pos */
+0x580b, /* lo nega*/
+0x5b08, /* lo pos */
+
+/*Indoor Edge*/
+0x5c08, /*indoor hi nega*/
+0x5f07, /* hi pos*/
+0x5d14,
+0x6012,
+0x5e0a,
+0x6108, /* low pos*/
+
+0x6208, /*dark1 hi nega*/
+0x6506, /* hi pos */
+0x6308, /* mid nega */
+0x6606, /* mid pos */
+0x6408, /* low nega */
+0x6706, /* low pos */
+
+0x6807, /*dark2 hi nega*/
+0x6b05, /* hi pos */
+0x6907, /* mid nega */
+0x6c05, /* mid pos */
+0x6a07, /* low nega */
+0x6d05, /* low pos */
+
+0x6e0a, /*dark3 hi nega*/
+0x7109, /* hi pos */
+0x6f0a, /* mid nega */
+0x7209, /* mid pos */
+0x700a, /* low nega */
+0x7309, /* low pos */
+
+ /* 2DY*/
+0x80c1,
+0x811f,
+0x82e1,
+0x8333,
+
+0x9005,
+0x9105,
+0x9233,
+0x9330,
+0x9403,
+0x9514,
+0x9730,
+0x9930,
+
+0xa002, /*2d lclp out2 nega*/
+0xa103, /*2d lclp out2 pos*/
+0xa202, /*2d lclp out1 nega*/
+0xa303, /*2d lclp out1 pos*/
+0xa403, /*2d lclp in nega*/
+0xa504, /*2d lclp in pos*/
+0xa607, /*2d lclp dark1 nega*/
+0xa708, /*2d lclp dark1 pos*/
+0xa807, /*2d lclp dark2 nega*/
+0xa908, /*2d lclp dark2 pos*/
+0xaa07, /*2d lclp dark3 nega*/
+0xab08, /*2d lclp dark3 pos*/
+
+0xb010, /*out2 H Ne*/
+0xb310, /* H Po*/
+0xb11e, /* M Ne*/
+0xb41e, /* M Po*/
+0xb21f, /* L Ne*/
+0xb51e, /* L Po*/
+
+0xb610, /*out1 H Ne */
+0xb910, /* H Po */
+0xb71e, /* M Ne */
+0xba1e, /* M Po */
+0xb81f, /* L Ne */
+0xbb1e, /* L Po */
+
+0xbc20, /*indoor H Ne*/
+0xbf1e, /* H Po*/
+0xbd25, /* M Ne*/
+0xc023, /* M Po*/
+0xbe24, /* L Ne*/
+0xc122, /* L Po*/
+
+0xc223, /*dark1 H Ne*/
+0xc523, /* H Po*/
+0xc329, /* M Ne*/
+0xc629, /* M Po*/
+0xc425, /* L Ne*/
+0xc725, /* L Po*/
+
+0xc81c, /*dark2 H Ne*/
+0xcb1c, /* H Po*/
+0xc925, /* M Ne*/
+0xcc25, /* M Po*/
+0xca23, /* L Ne*/
+0xcd23, /* L Po*/
+
+0xce1c, /*dark3 H Ne*/
+0xd11c, /* H Po*/
+0xcf25, /* M Ne*/
+0xd225, /* M Po*/
+0xd023, /* L Ne*/
+0xd323, /* L Po*/
+
+/* PAGE 14 START*/
+0x0314,
+0x1031,
+
+0x1480, /* GX*/
+0x1580, /* GY*/
+0x1680, /* RX*/
+0x1780, /* RY*/
+0x1880, /* BX*/
+0x1980, /* BY*/
+
+0x2060, /* X Center*/
+0x2180, /* Y Center*/
+
+0x2280,
+0x2380,
+0x2480,
+
+0x30c8,
+0x312b,
+0x3200,
+0x3300,
+0x3490,
+
+0x4056, /*R min's set 4e*/
+0x413a, /*Gr*/
+0x4237, /*B*/
+0x433a, /*Gb*/
+
+0x0315,
+0x1021,
+0x1444, /*49*/
+0x1534, /*38*/
+0x1626, /*2b*/
+0x172f,
+
+0x30dd,
+0x3162,
+0x3205,
+0x3326,
+0x34bd,
+0x3517,
+0x3618,
+0x3738,
+0x38d0,
+
+0x40b0,
+0x4130,
+0x4200,
+0x4300,
+0x4400,
+0x4500,
+0x4699,
+0x4719,
+0x4800,
+
+0x5016,
+0x51b2,
+0x521c,
+0x5306,
+0x5420,
+0x55a6,
+0x560e,
+0x57b2,
+0x5824,
+
+0x0316,
+0x1031, /*GMA_CTL*/
+0x187e, /*AG_ON*/
+0x197d, /*AG_OFF*/
+0x1a0e, /*TIME_ON*/
+0x1b01, /*TIME_OFF*/
+0x1Cdc, /*OUT_ON*/
+0x1Dfe, /*OUT_OFF*/
+
+/*GMA Indoor*/
+0x3000,
+0x3107,
+0x321a,
+0x3335,
+0x345a,
+0x357c,
+0x3696,
+0x37a9,
+0x38b7,
+0x39c6,
+0x3ad2,
+0x3bdc,
+0x3ce4,
+0x3deb,
+0x3ef1,
+0x3ff5,
+0x40f9,
+0x41fd,
+0x42ff,
+
+/*RGMA Outdoor*/
+0x5000,
+0x5103,
+0x5213,
+0x532e,
+0x5459,
+0x5579,
+0x5690,
+0x57a3,
+0x58b4,
+0x59c2,
+0x5acd,
+0x5bd7,
+0x5ce0,
+0x5de5,
+0x5ee9,
+0x5fee,
+0x60f1,
+0x61f3,
+0x62f6,
+
+/*BGMA Dark*/
+0x7003,
+0x7111,
+0x721f,
+0x7337,
+0x7452,
+0x756c,
+0x7685,
+0x779a,
+0x78ad,
+0x79bd,
+0x7acb,
+0x7bd6,
+0x7ce0,
+0x7de8,
+0x7eef,
+0x7ff4,
+0x80f8,
+0x81fb,
+0x82fe,
+
+0x0324, /*Resol control */
+0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/
+0x6104, /*even frame update */
+0x6408,
+0x6500,
+0x6626, /*edge th2 H */
+0x6700, /*edge th2 L */
+
+0x0313,
+0x1831, /*flat center Gb/Gr*/
+0x7402, /*det slope en | gausian filter*/
+0x750d, /*1D negative gain det 09 */
+0x760d, /*1D postive gain det 08*/
+0x7710, /*1D hclp2 det*/
+0x7808, /*outdoor flat threshold*/
+0x7910, /*indoor flat threshold*/
+
+0x81df, /*det gain controler*/
+0x8690, /*2D negative gain det */
+0x8790, /*2D postive gain det */
+0x962a, /*2D hclp2 det*/
+
+0x0312, /*0x12 page*/
+0xd088,
+0xd9e4,
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+/* PAGE 20 START*/
+0x0320,
+0x111c,
+0x1830,
+0x1a08,
+0x2045,/*weight*/
+0x2130,
+0x2210,
+0x2300,
+0x2400,
+
+0x28e7, /* add 20120223*/
+0x290d, /* 20100305 ad -> 0d*/
+0x2afd,
+0x2bf8,
+
+0x2cc3,
+0x2d5f, /* add 20120223*/
+0x2e33,
+0x30f8,
+0x3203,
+0x332e,
+0x3430,
+0x35d4,
+0x36ff, /*fe*/
+0x3732,
+0x3804,
+0x3922,
+0x3ade,
+0x3b22,
+0x3cde,
+0x3de1,
+
+0x5045,
+0x5188,
+
+0x561a,
+0x5780,
+0x580e,
+0x596a,
+0x5a04,
+
+0x5e9d, /*AE_AWB_start*/
+0x5f76, /*AE_AWB_start*/
+
+0x7033, /* 6c*/
+0x7182, /* 82(+8)*/
+
+0x7621,
+0x7771,
+0x7822, /* 24*/
+0x7923, /* Y Target 70 => 25, 72 => 26*/
+0x7a23, /* 23*/
+0x7b22, /* 22*/
+0x7d23,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+0x8601, /*EXPMin 7500.00 fps*/
+0x8790,
+0x8805, /*EXP Max(120Hz) 8.00 fps */
+0x89b8,
+0x8ad8,
+0xa505, /*EXP Max(100Hz) 8.33 fps */
+0xa67e,
+0xa740,
+0x8B75, /*EXP100 */
+0x8C30,
+0x8D61, /*EXP120 */
+0x8Ea8,
+0x9c09, /*EXP Limit 1250.00 fps */
+0x9d60,
+0x9e01, /*EXP Unit */
+0x9f90,
+0x989d,
+
+0xb016,
+0xb114,
+0xb2f8,
+0xb314,
+0xb41b,
+0xb546,
+0xb631,
+0xb729,
+0xb826,
+0xb924,
+0xba22,
+0xbb42,
+0xbc41,
+0xbd40,
+
+0xc010,
+0xc138,
+0xc238,
+0xc338,
+0xc407,
+
+0xc880,
+0xc980,
+0x109c, /* ae enable*/
+/* PAGE 20 END*/
+
+/*AE_Weight*/
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2412,
+0x2522,
+0x2622,
+0x2721,
+0x2812,
+0x2922,
+0x2a22,
+0x2b21,
+0x2c12,
+0x2d23,
+0x2e32,
+0x2f21,
+0x3012,
+0x3123,
+0x3232,
+0x3321,
+0x3412,
+0x3522,
+0x3622,
+0x3721,
+0x3812,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+
+/* PAGE 22 START*/
+0x0322,
+0x10fd,
+0x112e,
+0x1901, /* Low On*/
+0x2030, /* for wb speed*/
+0x2140,
+0x2401,
+0x257e, /* for tracking 20120314 */
+
+0x3080, /* 20120224 test*/
+0x3180,
+0x3811,
+0x3934,
+
+0x40e8,
+0x4143, /* 33*/
+0x4222, /* 22*/
+
+0x43f3, /* f6*/
+0x4454, /* 44*/
+0x4522, /* 33*/
+
+0x4600,
+0x480a,
+0x50b2,
+0x5181,
+0x5298,
+
+0x8038,
+0x8120,
+0x8238, /* 3a*/
+
+0x8356, /* R Max*/
+0x8420, /* R Min*/
+0x8552, /* B Max*/
+0x8620, /* B Min*/
+
+0x8745,
+0x883a,
+0x8933,
+0x8a2c,
+
+0x8b42,
+0x8c3d,
+0x8d30,
+0x8e2c,
+
+0x8f5a,
+0x9059,
+0x9155,
+0x924e,
+0x9344,
+0x943a,
+0x9534,
+0x962c,
+0x9723,
+0x9820,
+0x991f,
+0x9a1f,
+
+0x9b77,
+0x9c77,
+0x9d48,
+0x9e38,
+0x9f30,
+
+0xa040,
+0xa121,
+0xa26f,
+0xa3ff,
+
+0xa414, /* 1500fps*/
+0xa544, /* 700fps*/
+0xa6cf,
+
+0xad40,
+0xae4a,
+
+0xaf2a, /* low temp Rgain*/
+0xb028, /* low temp Rgain*/
+
+0xb100, /* 0x20 -> 0x00 0405 modify*/
+0xb4bf, /* for tracking 20120314*/
+0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/
+0xb900,
+/* PAGE 22 END*/
+
+/* PAGE 48 (MiPi 1600x1200)*/
+0x0300,
+
+/* PLL Setting */
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0e,
+0x1e07,
+0x1f08,
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2b40,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_VT_Init_Reg[] = {
+/*0 Page*/
+0x0300,
+0x0101, /*sleep*/
+0x0103, /*s/w reset*/
+0x0101, /*sleep*/
+
+0x0800,/*Don't touch*/
+0x0937,/*Don't touch*/
+0x0a33,/*Don't touch*/
+
+/*PLL Setting*/
+0xd005,
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x1011,
+0x1194, /*xy flip*/
+0x1200, /*Sync type default:0x00 PCLK[2] 0 falling, 1 rising*/
+0x1488,
+
+/*--------------- windowing */
+0x0300,
+0x2000,
+0x2104,
+0x2200,
+0x2304,
+0x2403,
+0x25C0,
+0x2605,
+0x2700,
+
+0x4001, /*Hblank 280*/
+0x4118,
+0x4200, /*Vblank 20*/
+0x4314,
+
+/*--------------- BLC*/
+0x8008, /*Don't touch */
+0x8197, /*Don't touch */
+0x8290, /*Don't touch */
+0x8330, /*Don't touch */
+0x84cc, /*Don't touch*/
+0x8500, /*Don't touch*/
+0x86d4, /*Don' t touch*/
+0x870f, /*Don't touch*/
+0x8834, /*Don't touch*/
+
+0x9009, /*BLC_TIME_TH_ON*/
+0x9109, /*BLC_TIME_TH_OFF */
+0x92f0, /*BLC_AG_TH_ON*/
+0x93e8, /*BLC_AG_TH_OFF*/
+
+0x9495, /*091202*/
+0x9590, /*091202 */
+0x9838, /*Don't touch*/
+
+/*Dark BLC*/
+0xa001, /* 20100309*/
+0xa201, /* 20100309*/
+0xa401, /* 20100309*/
+0xa601, /* 20100309*/
+
+/*Normal BLC*/
+0xa800,
+0xaa00,
+0xac00,
+0xae00,
+
+/*Out BLC*/
+0x9900,
+0x9a00,
+0x9b00,
+0x9c00,
+
+/*2 Page*/
+0x0302,
+0x1200, /*Don't touch*/
+0x1400, /*Don't touch*/
+0x1500, /*Don't touch*/
+0x184C, /*Don't touch*/
+0x1900, /*Don't touch*/
+0x1A39, /*Don't touch*/
+0x1B00,/*Don't touch*/
+0x1C1a, /*Don't touch*/
+0x1D14, /*Don't touch*/
+0x1E30,/*Don't touch*/
+0x1F10,/*Don't touch*/
+
+0x2077,
+0x21de,
+0x22a7,
+0x2330,
+0x2477,
+0x2510,
+0x2610,
+0x273c,
+0x2b80,
+0x2c02,
+0x2da0,
+0x2e00,
+0x2fa7,
+
+0x3000,
+0x3199,
+0x3200,
+0x3300,
+0x3422,
+0x3601,
+0x3701,
+0x3888,
+0x3988,
+0x3d03,
+0x3e0d,
+0x3f02,
+
+0x49d1,
+0x4a14,
+
+0x5021,
+0x5201,
+0x5381,
+0x5410,
+0x551c,
+0x5611,
+0x5818,
+0x5916,
+0x5da2,
+0x5e5a,
+
+0x6093, /* 20120517 modify*/
+0x61a4, /* 20120517 modify*/
+0x6294, /* 20120517 modify*/
+0x63a3, /* 20120517 modify*/
+0x6494, /* 20120517 modify*/
+0x65a3, /* 20120517 modify*/
+0x670c,
+0x680c,
+0x690c,
+0x6ab4,
+0x6bc4,
+0x6cb5,
+0x6dc2,
+0x6eb5,
+0x6fc0,
+
+0x70b6,
+0x71b8,
+0x7295, /* 20120517 modify*/
+0x73a2, /* 20120517 modify*/
+0x7495, /* 20120517 modify*/
+0x75a2, /* 20120517 modify*/
+0x7695, /* 20120517 modify*/
+0x77a2, /* 20120517 modify*/
+0x7C92, /* 20120517 modify*/
+0x7Dff, /* 20120517 modify*/
+
+0x8001, /* 20120517 modify*/
+0x818a, /* 20120517 modify*/
+0x821e, /* 20120517 modify*/
+0x8336, /* 20120517 modify*/
+0x8489, /* 20120517 modify*/
+0x858b, /* 20120517 modify*/
+0x8689, /* 20120517 modify*/
+0x878b, /* 20120517 modify*/
+0x88ab,
+0x89bc,
+0x8aac,
+0x8bba,
+0x8cad,
+0x8db8,
+0x8eae,
+0x8fb2,
+
+0x90b3,
+0x91b7,
+0x9252, /* 20120517 modify*/
+0x936a, /* 20120517 modify*/
+0x9489, /* 20120517 modify*/
+0x958b, /* 20120517 modify*/
+0x9689, /* 20120517 modify*/
+0x978b, /* 20120517 modify*/
+
+0xA002,
+0xA186, /* 20120517 modify*/
+0xA202,
+0xA386, /* 20120517 modify*/
+0xA486, /* 20120517 modify*/
+0xA502,
+0xA686, /* 20120517 modify*/
+0xA702,
+0xA892, /* 20120517 modify*/
+0xA994, /* 20120517 modify*/
+0xAA92, /* 20120517 modify*/
+0xAB94, /* 20120517 modify*/
+0xAC1c,
+0xAD22,
+0xAE1c,
+0xAF22,
+
+0xB0a4, /* 20120517 modify*/
+0xB1ae, /* 20120517 modify*/
+0xB2a4, /* 20120517 modify*/
+0xB3ae, /* 20120517 modify*/
+0xB4a6, /* 20120517 modify*/
+0xB5ac, /* 20120517 modify*/
+0xB6a6, /* 20120517 modify*/
+0xB7ac, /* 20120517 modify*/
+0xB8a6, /* 20120517 modify*/
+0xB9ab, /* 20120517 modify*/
+0xBAa6, /* 20120517 modify*/
+0xBBab, /* 20120517 modify*/
+0xBCa6, /* 20120517 modify*/
+0xBDab, /* 20120517 modify*/
+0xBEa6, /* 20120517 modify*/
+0xBFab, /* 20120517 modify*/
+
+0xc437,
+0xc552,
+0xc66b,
+0xc786,
+0xc838, /* 20120517 modify*/
+0xc950, /* 20120517 modify*/
+0xca38, /* 20120517 modify*/
+0xcb50, /* 20120517 modify*/
+0xcc6c, /* 20120517 modify*/
+0xcd84, /* 20120517 modify*/
+0xce6c, /* 20120517 modify*/
+0xcf84, /* 20120517 modify*/
+
+/*0xd4a6,*/
+/*0xd5ac,*/
+/*0xd6a6,*/
+/*0xd7ac,*/
+/*add 20120517*/
+0xdc00, /* Added*/
+0xddaf, /* Added*/
+0xde00, /* Added*/
+0xdf90, /* Added*/
+
+0xd010,
+0xd114,
+0xd220,
+0xd300,
+/*DCDC */
+0xd409, /*DCDC_TIME_TH_ON*/
+0xd509, /*DCDC_TIME_TH_OFF */
+0xd6f0, /*DCDC_AG_TH_ON*/
+0xd7e8, /*DCDC_AG_TH_OFF*/
+
+0xea8a,
+
+0xF001, /* clock inversion*/
+0xF101,
+0xF201,
+0xF301,
+0xF401,
+0xF500,
+
+/*----------------------------------------------*/
+0x0310, /*page 10*/
+0x1001, /*Ycbcr422_bit Order: YUYV*/
+0x1230, /*y offset[4], dif_offset[5]*/
+0x1302, /*contrast effet enable : 0x02*/
+0x3400, /*hidden 10->00 100209*/
+0x3701, /*yc2d power save */
+0x3f04, /*100825*/
+0x4080, /*Y offset */
+0x4138,
+0x4880, /*Contrast (Y = constrast * (Y - 128) + 128)*//*86 */
+0x50f0,
+0x5300, /*dif_offset option */
+0x5530, /*dif_offset option diff_offset max */
+
+0x6003, /*out color sat en[7] | auto color decrement en[1] /
+ | manual color sat en[0]*/
+
+
+0x6183, /*blue saturation_C0*/
+0x6280, /*red saturation_B0*/
+
+0x63ff, /*auto decresment on AG th*/
+0x64ff, /*auto decresment on DG th*/
+0x66e4, /*Outdoor saturation step 137fps apply out th */
+0x6700, /*Outdoor saturation B/R*/
+0x7601, /* ADD 20121031 */
+0x7904, /* ADD 20121031 */
+
+/* Hi 163 */
+/* PAGE 10 START*/
+0x0310,
+0x8000, /* dsshin --> color enhance*/
+0xf500, /* dsshin --> h blank option*/
+
+0x0311, /*page 11 D_LPF */
+0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/
+0x1120, /* Uniform Full GbGr/OV-Nr*/
+
+0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/
+0x13b8, /*dark2[7] | dark2 maxfilter ratio[6:4]
+ | dark3[3] | dark3 maxfilter ratio[2:0] */
+
+0x30ba, /*Outdoor2 H th*/
+0x3110, /*Outdoor2 L th*/
+0x3250, /*Outdoor2 gain ratio*/
+0x331d, /*Outdoor2 H lum*/
+0x3420, /*Outdoor2 M lum*/
+0x351f, /*Outdoor2 L lum*/
+
+0x36b0, /*Outdoor1 H th*/
+0x3718, /*Outdoor1 L th*/
+0x3850, /*Outdoor1 gain ratio 0x80->40*/
+0x391d, /*Outdoor1 H lum 0x28->1e*/
+0x3a20, /*Outdoor1 M lum 0x10->15*/
+0x3b1f, /*Outdoor1 L lum 0x08->20*/
+
+0x3c3f, /*indoor H th*/
+0x3d16, /*indoor L th*/
+0x3e30, /*indoor gain ratio 0x44 6a */
+0x3f1a, /*indoor H lum 0x12 18 */
+0x4060, /*indoor M lum 0x18 1c*/
+0x411a, /*indoor L lum 0x18 3e*/
+
+0x4298, /*dark1 H th*/
+0x4328, /*dark1 L th*/
+0x4465, /*dark1 gain ratio*/
+0x4516, /*dark1 H lum 0x38->0x28 */
+0x4630, /*dark1 M lum 0x27->0x17*/
+0x4734, /*dark1 L lum 0x20->0x1a */
+
+0x4890, /*dark2 H th*/
+0x492a, /*dark2 L th*/
+0x4a65, /*dark2 gain ratio*/
+0x4b18, /*dark2 H lum */
+0x4c31, /*dark2 M lum*/
+0x4d36, /*dark2 L lum */
+
+0x4e80, /*dark3 H th*/
+0x4f30, /*dark3 L th*/
+0x5065, /*dark3 gain ratio*/
+0x5119, /*dark3 H lum */
+0x5231, /*dark3 M lum */
+0x5336, /*dark3 L lum */
+
+0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */
+0x5b00, /*Impulse pixel enable dark123,in,out123
+ :: must be 0x07 fix setting use!*/
+0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/
+
+0x603f, /*GbGr all enable*/
+0x620f, /*GbGr offset*/
+/*0x6325,*/ /*GbGr max_20120605_off*/
+/*0x6410,*/ /*GbGr min_20120605_off*/
+
+0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/
+0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/
+0x6700, /*dark GbGr rate H/M/L 100%*/
+
+0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/
+0x75a0, /* Outdoor2 Abberation Luminance lvl */
+0x7db4, /* Indoor Abberation Luminance lvl*/
+
+0x9608, /*indoor/Dark1 edgeoffset1*/
+0x9714, /*indoor/Dark1 center G value*/
+0x98f5, /*slope indoor :: left/right graph polarity, slope*/
+0x992a, /*indoor uncertain ratio control*/
+0x9a20, /*Edgeoffset_dark*/
+
+/*DPC_CTRL*/
+0x0312, /*Preview DPC off[0x5c] on[0x5d]*/
+0x200e,
+0x210e,
+
+0x2500, /* 0x30*/
+
+0x2a01,
+0x2e00, /*2010.8.25*/
+
+0x3035, /*Texture region(most detail)*/
+0x31a0, /*STD uniform1 most blur region*/
+0x32b0, /*STD uniform2 2nd blur*/
+0x33c0, /*STD uniform3 3rd blur*/
+0x34d0, /*STD normal noise1 4th blur */
+0x35e0, /*STD normal noise2 5th blur*/
+0x36ff, /*STD normal noise3 6th blur*/
+
+0x4083, /*Outdoor2 H th*/
+0x4120, /*Outdoor2 L th */
+0x4208, /*Outdoor2 H luminance */
+0x4310, /*Outdoor2 M luminance */
+0x4410, /*Outdoor2 l luminance */
+0x4550, /*Outdoor2 ratio*/
+
+0x4683, /*Outdoor1 H th*/
+0x4720, /*Outdoor1 L th */
+0x4808, /*Outdoor1 H luminance*/
+0x4910, /*Outdoor1 M luminance*/
+0x4a10, /*Outdoor1 L luminance*/
+0x4b50, /*Outdoor1 ratio*/
+
+0x4c80, /*Indoor H th*/
+0x4d48, /*Indoor L th*/
+0x4e30, /*indoor H lum*/
+0x4f30, /*indoor M lum*/
+0x5012, /*indoor L lum */
+0x5170, /*indoor ratio 0x10 -> 0x45*/
+
+0x52a8, /*dark1 H th*/
+0x5330, /*dark1 L th */
+0x5428, /*dark1 H lum */
+0x553e, /*dark1 M lum*/
+0x5667, /*dark1 L lum*/
+0x576a, /*dark1 ratio*/
+
+0x58a0, /*dark2 H th*/
+0x5940, /*dark2 L th*/
+0x5a28, /*dark2 H lum*/
+0x5b3f, /*dark2 M lum*/
+0x5c68, /*dark2 L lum*/
+0x5d70, /*dark2 ratio*/
+
+0x5ea0, /*dark3 H th*/
+0x5f40, /*dark3 L th*/
+0x6029, /*dark3 H lum*/
+0x613f, /*dark3 M lum*/
+0x6269, /*dark3 L lum*/
+0x636a, /*dark3 ratio*/
+
+/*C-filter(Out2&Out1)*/
+0x7010,
+0x710a,
+
+/*C-filter(Indoor&Dark3)*/
+0x7210,
+0x730a,
+
+/*C-filter(Dark2&Dark1)*/
+0x7418,
+0x7512,
+
+0x8020,
+0x8140,
+0x8265,
+0x851a,
+0x8800,
+0x8900,
+0x905d, /*Preview DPC off[0x5c] on[0x5d]*/
+
+/*DPC-Dark1,2,3*/
+0xad07, /*10825*/
+0xae07, /*10825*/
+0xaf07, /*10825*/
+
+/*Blue Det..*/
+0xc558, /*BlueRange 2010.8.25 0x40->23 */
+0xc620, /*GreenRange 2010.8.25 0x3b->20 */
+
+0xd088, /*2010.8.25*/
+0xd180,
+0xd217,/*preview 17, full 67*/
+0xd300,
+0xd400,
+0xd50f,/*preview 0f, full 02*/
+0xd6ff,
+0xd7ff,/*preview ff, full 18*/
+0xd800,
+0xd904,
+
+/*interpolated with average*/
+0xdb38, /*resolution issue 0x00->0x18->0x38 */
+0xd904, /*strong_edge detect ratio*/
+0xe001, /*strong_edge detect ratio*/
+
+0x0313, /*page 13 sharpness 1D*/
+0x10c5,
+0x117b,
+0x120e,
+0x1400,
+
+0x1511, /*added option 1.3M*/
+0x1830, /*added option 1.3M*/
+
+0x2015,
+0x2113,
+0x2233,
+0x2308, /*hi_clip th1*/
+0x241a, /*hi_clip th2*/
+0x2506, /*low clip th*/
+
+0x2618,
+0x2730,
+0x2910, /*time th*/
+0x2a30, /*pga th*/
+
+0x2b03, /*lpf out2*/
+0x2c03, /*lpf out1*/
+0x2d0c,
+0x2e12,
+0x2f12,
+
+/*1D Edge*/
+0x500a, /*out2 hi nega*/
+0x5307, /* hi pos*/
+0x510c, /* mi nega*/
+0x5407, /* mi pos*/
+0x520b, /* lo nega*/
+0x5508, /* lo pos*/
+
+0x560a, /*out1 hi nega*/
+0x5907, /* hi pos */
+0x570c, /* mi nega*/
+0x5a07, /* mi pos */
+0x580b, /* lo nega*/
+0x5b08, /* lo pos */
+
+/*Indoor Edge*/
+0x5c08, /*indoor hi nega*/
+0x5f07, /* hi pos*/
+0x5d14, /* mid nega ,11*/
+0x6012, /* mid pos ,0*/
+0x5e0a, /* low nega */
+0x6108, /* low pos*/
+
+0x6208, /*dark1 hi nega*/
+0x6506, /* hi pos */
+0x6308, /* mid nega */
+0x6606, /* mid pos */
+0x6408, /* low nega */
+0x6706, /* low pos */
+
+0x6807, /*dark2 hi nega*/
+0x6b05, /* hi pos */
+0x6907, /* mid nega */
+0x6c05, /* mid pos */
+0x6a07, /* low nega */
+0x6d05, /* low pos */
+
+0x6e0a, /*dark3 hi nega*/
+0x7109, /* hi pos */
+0x6f0a, /* mid nega */
+0x7209, /* mid pos */
+0x700a, /* low nega */
+0x7309, /* low pos */
+
+ /* 2DY*/
+0x80c1,
+0x811f,
+0x82e1,
+0x8333,
+
+0x9005,
+0x9105,
+0x9233,
+0x9330,
+0x9403,
+0x9514,
+0x9730,
+0x9930,
+
+0xa002, /*2d lclp out2 nega*/
+0xa103, /*2d lclp out2 pos*/
+0xa202, /*2d lclp out1 nega*/
+0xa303, /*2d lclp out1 pos*/
+0xa403, /*2d lclp in nega*/
+0xa504, /*2d lclp in pos*/
+0xa607, /*2d lclp dark1 nega*/
+0xa708, /*2d lclp dark1 pos*/
+0xa807, /*2d lclp dark2 nega*/
+0xa908, /*2d lclp dark2 pos*/
+0xaa07, /*2d lclp dark3 nega*/
+0xab08, /*2d lclp dark3 pos*/
+
+0xb010, /*out2 H Ne*/
+0xb310, /* H Po*/
+0xb11e, /* M Ne*/
+0xb41e, /* M Po*/
+0xb21f, /* L Ne*/
+0xb51e, /* L Po*/
+
+0xb610, /*out1 H Ne */
+0xb910, /* H Po */
+0xb71e, /* M Ne */
+0xba1e, /* M Po */
+0xb81f, /* L Ne */
+0xbb1e, /* L Po */
+
+0xbc20, /*indoor H Ne*/
+0xbf1e, /* H Po*/
+0xbd25, /* M Ne*/
+0xc023, /* M Po*/
+0xbe24, /* L Ne*/
+0xc122, /* L Po*/
+
+0xc223, /*dark1 H Ne*/
+0xc523, /* H Po*/
+0xc329, /* M Ne*/
+0xc629, /* M Po*/
+0xc425, /* L Ne*/
+0xc725, /* L Po*/
+
+0xc81c, /*dark2 H Ne*/
+0xcb1c, /* H Po*/
+0xc925, /* M Ne*/
+0xcc25, /* M Po*/
+0xca23, /* L Ne*/
+0xcd23, /* L Po*/
+
+0xce1c, /*dark3 H Ne*/
+0xd11c, /* H Po*/
+0xcf25, /* M Ne*/
+0xd225, /* M Po*/
+0xd023, /* L Ne*/
+0xd323, /* L Po*/
+
+/* PAGE 14 START*/
+0x0314,
+0x1031,
+
+0x1480, /* GX*/
+0x1580, /* GY*/
+0x1680, /* RX*/
+0x1780, /* RY*/
+0x1880, /* BX*/
+0x1980, /* BY*/
+
+0x2060, /* X Center*/
+0x2180, /* Y Center*/
+
+0x2280,
+0x2380,
+0x2480,
+
+0x30c8,
+0x312b,
+0x3200,
+0x3300,
+0x3490,
+
+0x4056, /*R min's set 4e*/
+0x413a, /*Gr*/
+0x4237, /*B*/
+0x433a, /*Gb*/
+
+0x0315,
+0x1021,
+0x1444, /*49*/
+0x1534, /*38*/
+0x1626, /*2b*/
+0x172f,
+
+0x30dd,
+0x3162,
+0x3205,
+0x3326,
+0x34bd,
+0x3517,
+0x3618,
+0x3738,
+0x38d0,
+
+0x40b0,
+0x4130,
+0x4200,
+0x4300,
+0x4400,
+0x4500,
+0x4699,
+0x4719,
+0x4800,
+
+0x5016,
+0x51b2,
+0x521c,
+0x5306,
+0x5420,
+0x55a6,
+0x560e,
+0x57b2,
+0x5824,
+
+0x0316,
+0x1031, /*GMA_CTL*/
+0x187e, /*AG_ON*/
+0x197d, /*AG_OFF*/
+0x1a0e, /*TIME_ON*/
+0x1b01, /*TIME_OFF*/
+0x1Cdc, /*OUT_ON*/
+0x1Dfe, /*OUT_OFF*/
+
+/*GMA, Indoor*/
+0x3000,
+0x3107,
+0x321a,
+0x3335,
+0x345a,
+0x357c,
+0x3696,
+0x37a9,
+0x38b7,
+0x39c6,
+0x3ad2,
+0x3bdc,
+0x3ce4,
+0x3deb,
+0x3ef1,
+0x3ff5,
+0x40f9,
+0x41fd,
+0x42ff,
+
+/*RGMA, Outdoor*/
+0x5000,
+0x5103,
+0x5213,
+0x532e,
+0x5459,
+0x5579,
+0x5690,
+0x57a3,
+0x58b4,
+0x59c2,
+0x5acd,
+0x5bd7,
+0x5ce0,
+0x5de5,
+0x5ee9,
+0x5fee,
+0x60f1,
+0x61f3,
+0x62f6,
+
+/*BGMA Dark*/
+0x7000,
+0x7107,
+0x721a,
+0x7335,
+0x745a,
+0x757c,
+0x7696,
+0x77a9,
+0x78b7,
+0x79c6,
+0x7ad2,
+0x7bdc,
+0x7ce4,
+0x7deb,
+0x7ef1,
+0x7ff5,
+0x80f9,
+0x81fd,
+0x82ff,
+
+0x0324, /*Resol control */
+0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/
+0x6104, /*even frame update */
+0x6408, /* 0x6435, edge th1 H*/
+0x6500, /*edge th1 L*/
+0x6626, /*edge th2 H */
+0x6700, /*edge th2 L */
+
+0x0313,
+0x1831, /*flat center Gb/Gr*/
+0x7402, /*det slope en | gausian filter*/
+0x750d, /*1D negative gain det 09 */
+0x760d, /*1D postive gain det 08*/
+0x7710, /*1D hclp2 det*/
+0x7808, /*outdoor flat threshold*/
+0x7910, /*indoor flat threshold*/
+
+0x81df, /*det gain controler*/
+0x8690, /*2D negative gain det */
+0x8790, /*2D postive gain det */
+0x962a, /*2D hclp2 det*/
+
+0x0312, /*0x12 page*/
+0xd088,
+0xd9e4,
+
+/* PAGE 20 START*/
+0x0320,
+0x111c,
+0x1830,
+0x1a08,
+0x2045,/*weight*/
+0x2130,
+0x2210,
+0x2300,
+0x2400,
+
+0x28e7, /* add 20120223*/
+0x290d, /* 20100305 ad -> 0d*/
+0x2afd,
+0x2bf8,
+
+0x2cc3,
+0x2d5f, /* add 20120223*/
+0x2e33,
+0x30f8,
+0x3203,
+0x332e,
+0x3430,
+0x35d4,
+0x36fe,
+0x3732,
+0x3804,
+0x3922,
+0x3ade,
+0x3b22,
+0x3cde,
+0x3de1,
+
+0x5045,
+0x5188,
+
+0x561a,
+0x5780,
+0x580e,
+0x596a,
+0x5a04,
+
+0x5e9d, /*AE_AWB_start*/
+0x5f76, /*AE_AWB_start*/
+
+0x7040, /* 6c*/
+0x7182, /* 82(+8)*/
+
+0x7621,
+0x7791,
+0x7822, /* 24*/
+0x792b, /* Y Target 70 => 25, 72 => 26*/
+0x7a23, /* 23*/
+0x7b22, /* 22*/
+0x7d23,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+
+0x8601, /*EXPMin 7500.00 fps*/
+0x8790,
+
+0x8803, /*EXP Max(120Hz) 12.00 fps*/
+0x89d0,
+0x8a90,
+
+0xa504, /*EXP Max(100Hz) 11.11 fps*/
+0xa61e,
+0xa7b0,
+
+0x8B75, /*EXP100 */
+0x8C30,
+0x8D61, /*EXP120 */
+0x8Ea8,
+
+0x9104, /*EXP Fix 10.00 fps*/
+0x9293,
+0x93e0,
+
+0x9c0a, /*EXP Limit 1071.43 fps*/
+0x9df0,
+0x9e01, /*EXP Unit */
+0x9f90,
+0x989d,
+
+0xb016,
+0xb114,
+0xb2f8,
+0xb314,
+0xb41b,
+0xb546,
+0xb631,
+0xb729,
+0xb826,
+0xb924,
+0xba22,
+0xbb42,
+0xbc41,
+0xbd40,
+
+0xc010,
+0xc138,
+0xc238,
+0xc338,
+0xc407,
+
+0xc880,
+0xc980,
+0x109c, /* ae enable*/
+/* PAGE 20 END*/
+
+/*AE_Weight*/
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2412,
+0x2522,
+0x2622,
+0x2721,
+0x2812,
+0x2922,
+0x2a22,
+0x2b21,
+0x2c12,
+0x2d23,
+0x2e32,
+0x2f21,
+0x3012,
+0x3123,
+0x3232,
+0x3321,
+0x3412,
+0x3522,
+0x3622,
+0x3721,
+0x3812,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+
+/* PAGE 22 START*/
+0x0322,
+0x10fd,
+0x112e,
+0x1901, /* Low On*/
+0x2030, /* for wb speed*/
+0x2140,
+0x2401,
+0x257e, /* for tracking 20120314 */
+
+0x3080, /* 20120224 test*/
+0x3180,
+0x3811,
+0x3934,
+
+0x40e8,
+0x4143, /* 33*/
+0x4222, /* 22*/
+
+0x43f3, /* f6*/
+0x4454, /* 44*/
+0x4522, /* 33*/
+
+0x4600,
+0x480a,
+0x50b2,
+0x5181,
+0x5298,
+
+0x8038,
+0x8120,
+0x8238, /* 3a*/
+
+0x8356, /* R Max*/
+0x8420, /* R Min*/
+0x8554, /* B Max*/
+0x8620, /* B Min*/
+
+0x8746,
+0x8836,
+0x893a,
+0x8a2f,
+
+0x8b3d,
+0x8c37,
+0x8d35,
+0x8e32,
+
+0x8f5a,
+0x9059,
+0x9155,
+0x924e,
+0x9344,
+0x943a,
+0x9534,
+0x962c,
+0x9723,
+0x9820,
+0x991f,
+0x9a1f,
+
+0x9b77,
+0x9c77,
+0x9d48,
+0x9e38,
+0x9f30,
+
+0xa040,
+0xa121,
+0xa26f,
+0xa3ff,
+
+0xa414, /* 1500fps*/
+0xa544, /* 700fps*/
+0xa6cf,
+
+0xad40,
+0xae4a,
+
+0xaf2a, /* low temp Rgain*/
+0xb028, /* low temp Rgain*/
+
+0xb100, /* 0x20 -> 0x00 0405 modify*/
+0xb4bf, /* for tracking 20120314*/
+0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/
+0xb900,
+/* PAGE 22 END*/
+
+/* PAGE 48 (MiPi 1600x1200)*/
+0x0300,
+
+/* PLL Setting */
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+/* MIPI TX Setting */
+0x0348,
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0e,
+0x1e07,
+0x1f08,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+/*0x3601,*/
+/*0x3707,*/
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_SmartStay_Init_Reg[] = {
+/*0 Page*/
+0x0300,
+0x0101, /*sleep*/
+0x0103, /*s/w reset*/
+0x0101, /*sleep*/
+
+0x0800,/*Don't touch*/
+0x0937,/*Don't touch*/
+0x0a33,/*Don't touch*/
+
+/*PLL Setting*/
+0xd005,
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x1011,
+0x1190, /*xy flip*/
+0x1200,
+0x1488,
+
+0x0300,
+0x2000,
+0x2104,
+0x2200,
+0x2304,
+0x2403,
+0x25C0,
+0x2605,
+0x2700,
+
+0x4001, /*Hblank_280*/
+0x4118,
+0x4201, /*Vblank 400*/
+0x4390,
+
+/*--------------- BLC*/
+0x8008, /*Don't touch */
+0x8197, /*Don't touch */
+0x8290, /*Don't touch */
+0x8330, /*Don't touch */
+0x84cc, /*Don't touch*/
+0x8500, /*Don't touch*/
+0x86d4, /*Don' t touch*/
+0x870f, /*Don't touch*/
+0x8834, /*Don't touch*/
+
+0x900c, /*BLC_TIME_TH_ON*/
+0x910c, /*BLC_TIME_TH_OFF */
+0x92f7, /*BLC_AG_TH_ON*/
+0x93ef, /*BLC_AG_TH_OFF*/
+
+0x9495, /*091202*/
+0x9590, /*091202 */
+0x9838, /*Don't touch*/
+
+/*Dark BLC*/
+0xa000, /* 20100309*/
+0xa200, /* 20100309*/
+0xa400, /* 20100309*/
+0xa600, /* 20100309*/
+
+/*Normal BLC*/
+0xa800,
+0xaa00,
+0xac00,
+0xae00,
+
+/*Out BLC*/
+0x9900,
+0x9a00,
+0x9b00,
+0x9c00,
+
+/*2 Page*/
+0x0302,
+0x1200, /*Don't touch*/
+0x1400, /*Don't touch*/
+0x1500, /*Don't touch*/
+0x184C, /*Don't touch*/
+0x1900, /*Don't touch*/
+0x1A39, /*Don't touch*/
+0x1B00,/*Don't touch*/
+0x1C1a, /*Don't touch*/
+0x1D14, /*Don't touch*/
+0x1E30,/*Don't touch*/
+0x1F10,/*Don't touch*/
+
+0x2077,
+0x21de,
+0x22a7,
+0x2330,
+0x2477,
+0x2510,
+0x2610,
+0x273c,
+0x2b80,
+0x2c02,
+0x2da0,
+0x2e00,
+0x2fa7,
+
+0x3000,
+0x3199,
+0x3200,
+0x3300,
+0x3422,
+0x3601,
+0x3701,
+0x3888,
+0x3988,
+0x3d03,
+0x3e0d,
+0x3f02,
+
+0x49d1,
+0x4a14,
+
+0x5021,
+0x5201,
+0x5381,
+0x5410,
+0x551c,
+0x5611,
+0x5818,
+0x5916,
+0x5da2,
+0x5e5a,
+
+0x6093, /* 20120517 modify*/
+0x61a4, /* 20120517 modify*/
+0x6294, /* 20120517 modify*/
+0x63a3, /* 20120517 modify*/
+0x6494, /* 20120517 modify*/
+0x65a3, /* 20120517 modify*/
+0x670c,
+0x680c,
+0x690c,
+0x6ab4,
+0x6bc4,
+0x6cb5,
+0x6dc2,
+0x6eb5,
+0x6fc0,
+
+0x70b6,
+0x71b8,
+0x7295, /* 20120517 modify*/
+0x73a2, /* 20120517 modify*/
+0x7495, /* 20120517 modify*/
+0x75a2, /* 20120517 modify*/
+0x7695, /* 20120517 modify*/
+0x77a2, /* 20120517 modify*/
+0x7C92, /* 20120517 modify*/
+0x7Dff, /* 20120517 modify*/
+
+0x8001, /* 20120517 modify*/
+0x818a, /* 20120517 modify*/
+0x821e, /* 20120517 modify*/
+0x8336, /* 20120517 modify*/
+0x8489, /* 20120517 modify*/
+0x858b, /* 20120517 modify*/
+0x8689, /* 20120517 modify*/
+0x878b, /* 20120517 modify*/
+0x88ab,
+0x89bc,
+0x8aac,
+0x8bba,
+0x8cad,
+0x8db8,
+0x8eae,
+0x8fb2,
+
+0x90b3,
+0x91b7,
+0x9252, /* 20120517 modify*/
+0x936a, /* 20120517 modify*/
+0x9489, /* 20120517 modify*/
+0x958b, /* 20120517 modify*/
+0x9689, /* 20120517 modify*/
+0x978b, /* 20120517 modify*/
+
+0xA002,
+0xA186, /* 20120517 modify*/
+0xA202,
+0xA386, /* 20120517 modify*/
+0xA486, /* 20120517 modify*/
+0xA502,
+0xA686, /* 20120517 modify*/
+0xA702,
+0xA892, /* 20120517 modify*/
+0xA994, /* 20120517 modify*/
+0xAA92, /* 20120517 modify*/
+0xAB94, /* 20120517 modify*/
+0xAC1c,
+0xAD22,
+0xAE1c,
+0xAF22,
+
+0xB0a4, /* 20120517 modify*/
+0xB1ae, /* 20120517 modify*/
+0xB2a4, /* 20120517 modify*/
+0xB3ae, /* 20120517 modify*/
+0xB4a6, /* 20120517 modify*/
+0xB5ac, /* 20120517 modify*/
+0xB6a6, /* 20120517 modify*/
+0xB7ac, /* 20120517 modify*/
+0xB8a6, /* 20120517 modify*/
+0xB9ab, /* 20120517 modify*/
+0xBAa6, /* 20120517 modify*/
+0xBBab, /* 20120517 modify*/
+0xBCa6, /* 20120517 modify*/
+0xBDab, /* 20120517 modify*/
+0xBEa6, /* 20120517 modify*/
+0xBFab, /* 20120517 modify*/
+
+0xc437,
+0xc552,
+0xc66b,
+0xc786,
+0xc838, /* 20120517 modify*/
+0xc950, /* 20120517 modify*/
+0xca38, /* 20120517 modify*/
+0xcb50, /* 20120517 modify*/
+0xcc6c, /* 20120517 modify*/
+0xcd84, /* 20120517 modify*/
+0xce6c, /* 20120517 modify*/
+0xcf84, /* 20120517 modify*/
+
+/*0xd4a6,*/
+/*0xd5ac,*/
+/*0xd6a6,*/
+/*0xd7ac,*/
+/*add 20120517*/
+0xdc00, /* Added*/
+0xddaf, /* Added*/
+0xde00, /* Added*/
+0xdf90, /* Added*/
+
+0xd010,
+0xd114,
+0xd220,
+0xd300,
+/*DCDC */
+0xd40c, /*DCDC_TIME_TH_ON*/
+0xd50c, /*DCDC_TIME_TH_OFF */
+0xd6f7, /*DCDC_AG_TH_ON*/
+0xd7ef, /*DCDC_AG_TH_OFF*/
+
+0xea8a,
+
+0xF001, /* clock inversion*/
+0xF101,
+0xF201,
+0xF301,
+0xF401,
+0xF500,
+
+/*----------------------------------------------*/
+0x0310, /*page 10*/
+0x1001, /*Ycbcr422_bit Order: YUYV*/
+0x1103,
+0x1230, /*y offset[4], dif_offset[5]*/
+0x1302, /*contrast effet enable : 0x02*/
+0x3400, /*hidden 10->00 100209*/
+0x3701, /*yc2d power save */
+0x3f04, /*100825*/
+0x4080, /*Y offset */
+0x4128,
+0x4880,
+0x5300, /*dif_offset option */
+0x5530, /*dif_offset option diff_offset max */
+
+0x606b, /*out color sat en[7] | auto color decrement en[1] /
+ | manual color sat en[0]*/
+
+0x6183, /*blue saturation_C0*/
+0x6280, /*red saturation_B0*/
+
+0x63b0, /*auto decresment on AG th*/
+0x64ff, /*auto decresment on DG th*/
+0x66e4, /*Outdoor saturation step 137fps apply out th */
+0x6700, /*Outdoor saturation B/R*/
+0x7601, /* ADD 20121031 */
+0x7904, /* ADD 20121031 */
+
+/* Hi 163 */
+/* PAGE 10 START*/
+0x0310,
+0x8000, /* dsshin --> color enhance*/
+0xf500, /* dsshin --> h blank option*/
+
+0x0311, /*page 11 D_LPF */
+0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/
+0x1120, /* Uniform Full GbGr/OV-Nr*/
+
+0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/
+0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */
+
+0x30ba, /*Outdoor2 H th*/
+0x3110, /*Outdoor2 L th*/
+0x3250, /*Outdoor2 gain ratio*/
+0x331d, /*Outdoor2 H lum*/
+0x3420, /*Outdoor2 M lum*/
+0x351f, /*Outdoor2 L lum*/
+
+0x36b0, /*Outdoor1 H th*/
+0x3718, /*Outdoor1 L th*/
+0x3850, /*Outdoor1 gain ratio 0x80->40*/
+0x391d, /*Outdoor1 H lum 0x28->1e*/
+0x3a20, /*Outdoor1 M lum 0x10->15*/
+0x3b1f, /*Outdoor1 L lum 0x08->20*/
+
+0x3c3f, /*indoor H th*/
+0x3d16, /*indoor L th*/
+0x3e30, /*indoor gain ratio 0x44 6a */
+0x3f1a, /*indoor H lum 0x12 18 */
+0x4060, /*indoor M lum 0x18 1c*/
+0x411a, /*indoor L lum 0x18 3e*/
+
+0x4280, /*dark1 H th*/
+0x4318, /*dark1 L th*/
+0x4480, /*dark1 gain ratio*/
+0x450f, /*dark1 H lum 0x38->0x28 */
+0x460c, /*dark1 M lum 0x27->0x17*/
+0x470b, /*dark1 L lum 0x20->0x1a */
+
+0x4880, /*dark2 H th*/
+0x4918, /*dark2 L th*/
+0x4a80, /*dark2 gain ratio*/
+0x4b0f, /*dark2 H lum */
+0x4c0c, /*dark2 M lum*/
+0x4d0b, /*dark2 L lum */
+
+0x4e80, /*dark3 H th*/
+0x4f23, /*dark3 L th*/
+0x5080, /*dark3 gain ratio*/
+0x511d, /*dark3 H lum */
+0x521f, /*dark3 M lum */
+0x531f, /*dark3 L lum */
+
+0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */
+0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/
+0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/
+
+0x603f, /*GbGr all enable*/
+0x620f, /*GbGr offset*/
+
+0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/
+0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/
+0x6700, /*dark GbGr rate H/M/L 100%*/
+
+0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/
+0x75a0, /* Outdoor2 Abberation Luminance lvl */
+0x7db4, /* Indoor Abberation Luminance lvl*/
+
+0x9608, /*indoor/Dark1 edgeoffset1*/
+0x9714, /*indoor/Dark1 center G value*/
+0x98f5, /*slope indoor :: left/right graph polarity, slope*/
+0x992a, /*indoor uncertain ratio control*/
+0x9a20, /*Edgeoffset_dark*/
+
+/*DPC_CTRL*/
+0x0312, /*Preview DPC off[0x5c] on[0x5d]*/
+0x200f,
+0x210f,
+
+0x2500, /* 0x30*/
+
+0x2a01,
+0x2e00, /*2010.8.25*/
+
+0x3035, /*Texture region(most detail)*/
+0x31a0, /*STD uniform1 most blur region*/
+0x32b0, /*STD uniform2 2nd blur*/
+0x33c0, /*STD uniform3 3rd blur*/
+0x34d0, /*STD normal noise1 4th blur */
+0x35e0, /*STD normal noise2 5th blur*/
+0x36ff, /*STD normal noise3 6th blur*/
+
+0x4083, /*Outdoor2 H th*/
+0x4120, /*Outdoor2 L th */
+0x4208, /*Outdoor2 H luminance */
+0x4310, /*Outdoor2 M luminance */
+0x4410, /*Outdoor2 l luminance */
+0x4550, /*Outdoor2 ratio*/
+
+0x4683, /*Outdoor1 H th*/
+0x4720, /*Outdoor1 L th */
+0x4808, /*Outdoor1 H luminance*/
+0x4910, /*Outdoor1 M luminance*/
+0x4a10, /*Outdoor1 L luminance*/
+0x4b50, /*Outdoor1 ratio*/
+
+0x4c80, /*Indoor H th*/
+0x4d48, /*Indoor L th*/
+0x4e30, /*indoor H lum*/
+0x4f30, /*indoor M lum*/
+0x5012, /*indoor L lum */
+0x5170, /*indoor ratio 0x10 -> 0x45*/
+
+0x52a8, /*dark1 H th*/
+0x5330, /*dark1 L th */
+0x5428, /*dark1 H lum */
+0x553e, /*dark1 M lum*/
+0x5667, /*dark1 L lum*/
+0x576a, /*dark1 ratio*/
+
+0x58a0, /*dark2 H th*/
+0x5940, /*dark2 L th*/
+0x5a28, /*dark2 H lum*/
+0x5b3f, /*dark2 M lum*/
+0x5c68, /*dark2 L lum*/
+0x5d70, /*dark2 ratio*/
+
+0x5ea0, /*dark3 H th*/
+0x5f1c, /*dark3 L th*/
+0x6029, /*dark3 H lum*/
+0x614a, /*dark3 M lum*/
+0x62ff, /*dark3 L lum*/
+0x63ff, /*dark3 ratio*/
+
+/*C-filter(Out2&Out1)*/
+0x7010,
+0x710a,
+
+/*C-filter(Indoor&Dark3)*/
+0x7210,
+0x730a,
+
+/*C-filter(Dark2&Dark1)*/
+0x7418,
+0x7512,
+
+0x8020,
+0x8140,
+0x8265,
+0x851a,
+0x8800,
+0x8900,
+0x905d, /*Preview DPC off[0x5c] on[0x5d]*/
+
+/*DPC-Dark1,2,3*/
+0xad07, /*10825*/
+0xae07, /*10825*/
+0xaf07, /*10825*/
+
+/*Blue Det..*/
+0xc558, /*BlueRange 2010.8.25 0x40->23 */
+0xc620, /*GreenRange 2010.8.25 0x3b->20 */
+
+0xd088, /*2010.8.25*/
+0xd180,
+0xd217,/*preview 17, full 67*/
+0xd300,
+0xd400,
+0xd50f,/*preview 0f, full 02*/
+0xd6ff,
+0xd7ff,/*preview ff, full 18*/
+0xd800,
+0xd904,
+
+/*interpolated with average*/
+0xdb38, /*resolution issue 0x00->0x18->0x38 */
+0xd904, /*strong_edge detect ratio*/
+0xe001, /*strong_edge detect ratio*/
+
+0x0313, /*page 13 sharpness 1D*/
+0x10c5,
+0x117b,
+0x120e,
+0x1400,
+
+0x1511, /*added option 1.3M*/
+0x1830, /*added option 1.3M*/
+
+0x2015,
+0x2113,
+0x2233,
+0x2308, /*hi_clip th1*/
+0x241a, /*hi_clip th2*/
+0x2506, /*low clip th*/
+
+0x2618,
+0x2730,
+0x2910, /*time th*/
+0x2a30, /*pga th*/
+
+0x2b03, /*lpf out2*/
+0x2c03, /*lpf out1*/
+0x2d0c,
+0x2e12,
+0x2f12,
+
+/*1D Edge*/
+0x500a, /*out2 hi nega*/
+0x5307, /* hi pos*/
+0x510c, /* mi nega*/
+0x5407, /* mi pos*/
+0x520b, /* lo nega*/
+0x5508, /* lo pos*/
+
+0x560a, /*out1 hi nega*/
+0x5907, /* hi pos */
+0x570c, /* mi nega*/
+0x5a07, /* mi pos */
+0x580b, /* lo nega*/
+0x5b08, /* lo pos */
+
+/*Indoor Edge*/
+0x5c08, /*indoor hi nega*/
+0x5f07, /* hi pos*/
+0x5d14,
+0x6012,
+0x5e0a,
+0x6108, /* low pos*/
+
+0x6208, /*dark1 hi nega*/
+0x6506, /* hi pos */
+0x6308, /* mid nega */
+0x6606, /* mid pos */
+0x6408, /* low nega */
+0x6706, /* low pos */
+
+0x6807, /*dark2 hi nega*/
+0x6b05, /* hi pos */
+0x6907, /* mid nega */
+0x6c05, /* mid pos */
+0x6a07, /* low nega */
+0x6d05, /* low pos */
+
+0x6e0a, /*dark3 hi nega*/
+0x7109, /* hi pos */
+0x6f0d, /* mid nega */
+0x720c, /* mid pos */
+0x700d, /* low nega */
+0x730c, /* low pos */
+
+ /* 2DY*/
+0x80c1,
+0x811f,
+0x82e1,
+0x8333,
+
+0x9005,
+0x9105,
+0x9233,
+0x9330,
+0x9403,
+0x9514,
+0x9730,
+0x9930,
+
+0xa002, /*2d lclp out2 nega*/
+0xa103, /*2d lclp out2 pos*/
+0xa202, /*2d lclp out1 nega*/
+0xa303, /*2d lclp out1 pos*/
+0xa403, /*2d lclp in nega*/
+0xa504, /*2d lclp in pos*/
+0xa607, /*2d lclp dark1 nega*/
+0xa708, /*2d lclp dark1 pos*/
+0xa807, /*2d lclp dark2 nega*/
+0xa908, /*2d lclp dark2 pos*/
+0xaa07, /*2d lclp dark3 nega*/
+0xab08, /*2d lclp dark3 pos*/
+
+0xb010, /*out2 H Ne*/
+0xb310, /* H Po*/
+0xb11e, /* M Ne*/
+0xb41e, /* M Po*/
+0xb21f, /* L Ne*/
+0xb51e, /* L Po*/
+
+0xb610, /*out1 H Ne */
+0xb910, /* H Po */
+0xb71e, /* M Ne */
+0xba1e, /* M Po */
+0xb81f, /* L Ne */
+0xbb1e, /* L Po */
+
+0xbc20, /*indoor H Ne*/
+0xbf1e, /* H Po*/
+0xbd25, /* M Ne*/
+0xc023, /* M Po*/
+0xbe24, /* L Ne*/
+0xc122, /* L Po*/
+
+0xc223, /*dark1 H Ne*/
+0xc523, /* H Po*/
+0xc329, /* M Ne*/
+0xc629, /* M Po*/
+0xc425, /* L Ne*/
+0xc725, /* L Po*/
+
+0xc81c, /*dark2 H Ne*/
+0xcb1c, /* H Po*/
+0xc925, /* M Ne*/
+0xcc25, /* M Po*/
+0xca23, /* L Ne*/
+0xcd23, /* L Po*/
+
+0xce1c, /*dark3 H Ne*/
+0xd11c, /* H Po*/
+0xcf29, /* M Ne*/
+0xd229, /* M Po*/
+0xd027, /* L Ne*/
+0xd327, /* L Po*/
+
+/* PAGE 14 START*/
+0x0314,
+0x1031,
+
+0x1480, /* GX*/
+0x1580, /* GY*/
+0x1680, /* RX*/
+0x1780, /* RY*/
+0x1880, /* BX*/
+0x1980, /* BY*/
+
+0x2060, /* X Center*/
+0x2180, /* Y Center*/
+
+0x2280,
+0x2380,
+0x2480,
+
+0x30c8,
+0x312b,
+0x3200,
+0x3300,
+0x3490,
+
+0x4056, /*R min's set 4e*/
+0x413a, /*Gr*/
+0x4237, /*B*/
+0x433a, /*Gb*/
+
+0x0315,
+0x1021,
+0x1444, /*49*/
+0x1534, /*38*/
+0x1626, /*2b*/
+0x172f,
+
+0x30dd,
+0x3162,
+0x3205,
+0x3326,
+0x34bd,
+0x3517,
+0x3618,
+0x3738,
+0x38d0,
+
+0x40b0,
+0x4130,
+0x4200,
+0x4300,
+0x4400,
+0x4500,
+0x4699,
+0x4719,
+0x4800,
+
+0x5016,
+0x51b2,
+0x521c,
+0x5306,
+0x5420,
+0x55a6,
+0x560e,
+0x57b2,
+0x5824,
+
+0x0316,
+0x1031, /*GMA_CTL*/
+0x187e, /*AG_ON*/
+0x197d, /*AG_OFF*/
+0x1a0e, /*TIME_ON*/
+0x1b01, /*TIME_OFF*/
+0x1Cdc, /*OUT_ON*/
+0x1Dfe, /*OUT_OFF*/
+
+/*GMA Indoor*/
+0x3000,
+0x3126,
+0x3238,
+0x3355,
+0x347e,
+0x3597,
+0x36a9,
+0x37ba,
+0x38c7,
+0x39d2,
+0x3adb,
+0x3be3,
+0x3cea,
+0x3dee,
+0x3ef5,
+0x3ff9,
+0x40fc,
+0x41fe,
+0x42ff,
+
+/*RGMA Outdoor*/
+0x5000,
+0x5126,
+0x5238,
+0x5355,
+0x547e,
+0x5597,
+0x56a9,
+0x57ba,
+0x58c7,
+0x59d2,
+0x5adb,
+0x5be3,
+0x5cea,
+0x5dee,
+0x5ef5,
+0x5ff9,
+0x60fc,
+0x61fe,
+0x62ff,
+
+/*BGMA Dark*/
+0x7002,
+0x712a,
+0x723b,
+0x7359,
+0x7481,
+0x759b,
+0x76ac,
+0x77be,
+0x78ca,
+0x79d4,
+0x7adb,
+0x7be4,
+0x7ceb,
+0x7def,
+0x7ef6,
+0x7ffa,
+0x80fc,
+0x81fe,
+0x82ff,
+
+0x0324, /*Resol control */
+0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/
+0x6104, /*even frame update */
+0x6408,
+0x6500,
+0x6626, /*edge th2 H */
+0x6700, /*edge th2 L */
+
+0x0313,
+0x1831, /*flat center Gb/Gr*/
+0x7402, /*det slope en | gausian filter*/
+0x750d, /*1D negative gain det 09 */
+0x760d, /*1D postive gain det 08*/
+0x7710, /*1D hclp2 det*/
+0x7808, /*outdoor flat threshold*/
+0x7910, /*indoor flat threshold*/
+
+0x81df, /*det gain controler*/
+0x8690, /*2D negative gain det */
+0x8790, /*2D postive gain det */
+0x962a, /*2D hclp2 det*/
+
+0x0312, /*0x12 page*/
+0xd088,
+0xd9e4,
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+/* PAGE 20 START*/
+0x0320,
+0x111c,
+0x1830,
+0x1a08,
+0x2045,/*weight*/
+0x2130,
+0x2210,
+0x2300,
+0x2400,
+
+0x28e7, /* add 20120223*/
+0x290d, /* 20100305 ad -> 0d*/
+0x2afd,
+0x2bf8,
+
+0x2cc3,
+0x2d5f, /* add 20120223*/
+0x2e33,
+0x30f8,
+0x3203,
+0x332e,
+0x3430,
+0x35d4,
+0x36ff, /*fe*/
+0x3732,
+0x3804,
+0x3922,
+0x3ade,
+0x3b22,
+0x3cde,
+0x3de1,
+
+0x5045,
+0x5188,
+
+0x561a,
+0x5780,
+0x580e,
+0x596a,
+0x5a04,
+
+0x5e9d, /*AE_AWB_start*/
+0x5f76, /*AE_AWB_start*/
+
+0x703f, /* 6c*/
+0x7180, /* 82(+8)*/
+
+0x7621,
+0x7781,
+0x7822, /* 24*/
+0x7925, /* Y Target 70 => 25, 72 => 26*/
+0x7a23, /* 23*/
+0x7b22, /* 22*/
+0x7d23,
+
+0x8301, /*EXP Normal 30.00 fps */
+0x845f,
+0x8590,
+0x8601, /*EXPMin 7500.00 fps*/
+0x8790,
+0x8805, /*EXP Max(120Hz) 8.00 fps */
+0x89b8,
+0x8ad8,
+0xa505, /*EXP Max(100Hz) 8.33 fps */
+0xa67e,
+0xa740,
+0x8B75, /*EXP100 */
+0x8C30,
+0x8D61, /*EXP120 */
+0x8Ea8,
+0x9c09, /*EXP Limit 1250.00 fps */
+0x9d60,
+0x9e01, /*EXP Unit */
+0x9f90,
+0x989d,
+
+0xb016,
+0xb114,
+0xb2f0,
+0xb314,
+0xb41b,
+0xb546,
+0xb631,
+0xb729,
+0xb826,
+0xb924,
+0xba22,
+0xbb42,
+0xbc41,
+0xbd40,
+
+0xc010,
+0xc138,
+0xc238,
+0xc338,
+0xc407,
+
+0xc880,
+0xc980,
+0x109c, /* ae enable*/
+/* PAGE 20 END*/
+
+/*AE_Weight*/
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2422,
+0x2522,
+0x2622,
+0x2721,
+0x2823,
+0x2933,
+0x2a32,
+0x2b21,
+0x2c23,
+0x2d44,
+0x2e32,
+0x2f21,
+0x3023,
+0x3144,
+0x3232,
+0x3311,
+0x3423,
+0x3533,
+0x3632,
+0x3721,
+0x3822,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+
+/* PAGE 22 START*/
+0x0322,
+0x10fd,
+0x112e,
+0x1901, /* Low On*/
+0x2030, /* for wb speed*/
+0x2140,
+0x2401,
+0x257e, /* for tracking 20120314 */
+
+0x3080, /* 20120224 test*/
+0x3180,
+0x3811,
+0x3934,
+
+0x40e8,
+0x4143, /* 33*/
+0x4222, /* 22*/
+
+0x43f3, /* f6*/
+0x4454, /* 44*/
+0x4522, /* 33*/
+
+0x4600,
+0x480a,
+0x50b2,
+0x5181,
+0x5298,
+
+0x8038,
+0x8120,
+0x8238, /* 3a*/
+
+0x8356, /* R Max*/
+0x8420, /* R Min*/
+0x8552, /* B Max*/
+0x8620, /* B Min*/
+
+0x8746,
+0x8836,
+0x8939,
+0x8a2d,
+
+0x8b3c,
+0x8c36,
+0x8d34,
+0x8e31,
+
+0x8f5a,
+0x9059,
+0x9154,
+0x924d,
+0x9342,
+0x943a,
+0x9534,
+0x962c,
+0x9723,
+0x9820,
+0x991f,
+0x9a1f,
+
+0x9b77,
+0x9c77,
+0x9d48,
+0x9e38,
+0x9f30,
+
+0xa040,
+0xa122,
+0xa26f,
+0xa3ff,
+
+0xa414, /* 1500fps*/
+0xa544, /* 700fps*/
+0xa6cf,
+
+0xad40,
+0xae4a,
+
+0xaf2a, /* low temp Rgain*/
+0xb028, /* low temp Rgain*/
+
+0xb100, /* 0x20 -> 0x00 0405 modify*/
+0xb4bf, /* for tracking 20120314*/
+0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/
+0xb900,
+/* PAGE 22 END*/
+
+/* PAGE 48 (MiPi 1600x1200)*/
+0x0300,
+
+/* PLL Setting */
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0e,
+0x1e07,
+0x1f08,
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2b40,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_stop_stream[] = {
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t SR130PC20_Preview_Mode[] =
+{
+0x0300,
+0x0101,/*sleep*/
+
+0xd005,/*Pll Off*/
+
+0x0320,
+0x101c,/*AE off (0x0c:60Hz 0x1c:50Hz)*/
+0x0322,
+0x107d,/*AWB off*/
+
+0x0300,
+0x1011,
+/* 0x1190, *//*0x91 : mirror mode*/
+
+/* page 11 yc_lpf */
+0x0311,
+0x5b00,/*don't touch*/
+
+/* PAGE 12 YC_LPF */
+0x0312,
+0x200f,
+0x210f,
+
+/*preview DPC*/
+0xd217,
+0xd50f,
+0xd7ff,
+
+
+/* PAGE13 Sharpness 1D/2D */
+0x0313,
+0x10c4,
+0x80c0,
+
+/* PAGE 18 START*/
+0x0318,
+0x1443, /*83*/
+
+0x0320,
+0x109c, /*AE ON (0x8c:60Hz 0x9c:50Hz)*/
+0x0322,
+0x10fd, /*AWB ON*/
+
+0x0300, /*Page 0 PLL on*/
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+/* MIPI TX Setting */
+0x0348,
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+/*0x1d09,*/
+0x1d0e,
+0x1e07,
+0x1f08,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+/*0x3601,*/
+/*0x3707,*/
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0100,
+
+};
+
+static const sr130pc20_regset_t SR130PC20_Capture_Mode[] =
+{
+0x0300,
+0x0101,/*sleep*/
+
+0xd005,/*Pll off*/
+
+0x0322,
+0x107d,/*AWB off*/
+
+0x0300,
+0x1000,
+/* 0x1190, */
+
+0x0302,
+0x2faa,
+
+0x0311,
+0x5b00,/*don't touch*/
+
+0x0312,
+0x200f,
+0x210f,
+
+/*preview DPC*/
+0xd267,
+0xd502,
+0xd718,
+
+0x0313,
+0x10c5,
+0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+0x0300,
+0xd005,/*pll on*/
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0d, /* 0c:90ns , 0b:110ns */
+0x1e0f,
+0x1f0a,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x300a,
+0x3100,
+
+0x320d,
+0x330b,
+0x3402,
+0x3504,
+0x3601,
+0x3709,
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0100,/*sleep off*/
+
+};
+
+static const sr130pc20_regset_t SR130PC20_Lowlux_Night_Capture_Mode[] =
+{
+0x0300,
+0x0101,/*sleep*/
+
+0xd005,/*Pll off*/
+
+0x0322,
+0x107d,/*AWB off*/
+
+0x0300,
+0x1000,
+/* 0x1190, */
+
+0x0302,
+0x2faa,
+
+0x0311,
+0x5b00,/*don't touch*/
+
+0x0312,
+0x200f,
+0x210f,
+
+/*preview DPC*/
+0xd267,
+0xd502,
+0xd718,
+
+0x0313,
+0x10c5,
+0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+0x0300,
+0xd005,/*pll on*/
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0d, /* 0c:90ns , 0b:110ns */
+0x1e0f,
+0x1f0a,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x300a,
+0x3100,
+
+0x320d,
+0x330b,
+0x3402,
+0x3504,
+0x3601,
+0x3709,
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0100,/*sleep off*/
+
+0xff03,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Sketch[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Pastel[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Black_White[] =
+{
+0x0310,
+0x1103,
+0x1233,
+0x1302,
+0x4080,
+0x4480,
+0x4580,
+};
+
+static const sr130pc20_regset_t SR130PC20_Effect_Negative[] =
+{
+0x0310,
+0x1103,
+0x1238,
+0x1302,
+0x4080,
+0x4480,
+0x4580,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Solar[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Normal[] =
+{
+0x0310,
+0x1103,
+0x1230,
+0x1302,
+0x4080,
+0x4480,
+0x4580,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Sepia[] =
+{
+0x0310,
+0x1103,
+0x1233,
+0x1302,
+0x4080,
+0x4470,
+0x4598,
+};
+
+static const sr130pc20_regset_t sr130pc20_Metering_Center[] =
+{
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2412,
+0x2522,
+0x2622,
+0x2721,
+0x2812,
+0x2922,
+0x2a22,
+0x2b21,
+0x2c12,
+0x2d23,
+0x2e32,
+0x2f21,
+0x3012,
+0x3123,
+0x3232,
+0x3321,
+0x3412,
+0x3522,
+0x3622,
+0x3721,
+0x3812,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+};
+
+static const sr130pc20_regset_t sr130pc20_Metering_Matrix[] =
+{
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2411,
+0x2511,
+0x2611,
+0x2711,
+0x2811,
+0x2911,
+0x2a11,
+0x2b11,
+0x2c11,
+0x2d11,
+0x2e11,
+0x2f11,
+0x3011,
+0x3111,
+0x3211,
+0x3311,
+0x3411,
+0x3511,
+0x3611,
+0x3711,
+0x3811,
+0x3911,
+0x3a11,
+0x3b11,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+};
+
+static const sr130pc20_regset_t sr130pc20_Metering_Spot[] =
+{
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2411,
+0x2511,
+0x2611,
+0x2711,
+0x2811,
+0x2911,
+0x2a11,
+0x2b11,
+0x2c11,
+0x2d13,
+0x2e31,
+0x2f11,
+0x3011,
+0x3113,
+0x3231,
+0x3311,
+0x3411,
+0x3511,
+0x3611,
+0x3711,
+0x3811,
+0x3911,
+0x3a11,
+0x3b11,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_Default[] =
+{
+0x0310,
+0x4080,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M1Step[] =
+{
+0x0310,
+0x4090,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M2Step[] =
+{
+0x0310,
+0x40A0,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M3Step[] =
+{
+0x0310,
+0x40B0,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M4Step[] =
+{
+0x0310,
+0x40d0,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P1Step[] =
+{
+0x0310,
+0x4010,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P2Step[] =
+{
+0x0310,
+0x4020,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P3Step[] =
+{
+0x0310,
+0x4030,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P4Step[] =
+{
+0x0310,
+0x4050,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_50[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_100[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_200[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_400[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_Auto[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Default[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Landscape[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Sports[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Party_Indoor[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Beach_Snow[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Sunset[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Duskdawn[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Candle_Light[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Fall_Color[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Portrait[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Nightshot[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Fireworks[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Text[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Backlight[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Sharpness_Default[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Auto[] =
+{
+0x0322,
+0x106b,
+0x112e,
+0x8038,
+0x8120,
+0x8238,
+0x8356,
+0x8420,
+0x8552,
+0x8620,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Cloudy[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8050,
+0x8120,
+0x8228,
+0x8352,
+0x844c,
+0x852c,
+0x8622,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Sunny[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8038,
+0x8120,
+0x8235,
+0x833b,
+0x8434,
+0x8538,
+0x8631,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Fluorescent[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8037,
+0x8120,
+0x8248,
+0x8339,
+0x8434,
+0x854a,
+0x8645,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Tungsten[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8021,
+0x8120,
+0x824f,
+0x8327,
+0x841b,
+0x8559,
+0x8650,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_640_480_Preview[] = {
+0x0300,
+0x0101,
+
+0x0300,
+0x1011,
+
+0x0318,
+0x1000,
+
+0x0348,
+0x3005,
+0x3100,
+
+0x0300,
+0x0100,
+
+0xff0a,
+};
+
+static const sr130pc20_regset_t sr130pc20_352_288_Preview[] = {
+0x0300,
+0x0101,
+0x0300,
+0x1011,
+
+0x0318,
+0x1007,
+0x1200,
+0x2003,
+0x2100,
+0x2201,
+0x2320,
+0x2400,
+0x2520,
+0x2600,
+0x2700,
+0x2802,
+0x29e0,
+0x2a01,
+0x2b20,
+0x2c0d,
+0x2d55,
+0x2e0d,
+0x2f55,
+0x3051,
+
+0x0348,
+0x3002,
+0x31c0,
+
+0x0300,
+0x0100,
+
+0xff28,
+};
+
+static const sr130pc20_regset_t sr130pc20_320_240_Preview[] = {
+0x0300,
+0x0101,
+
+0x0300,
+0x1023,
+
+0x0318,
+0x1000,
+
+0x0348,
+0x3002,
+0x3180,
+
+0x0300,
+0x0100,
+
+0xff28,
+};
+
+static const sr130pc20_regset_t sr130pc20_176_144_Preview[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_1280_960_Capture[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_960_720_Capture[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_VGA_Capture[] = {
+0xff00
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_auto[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_7fix[] = {
+0x0300,
+0x0101,
+
+0x1190,
+
+0x4200,
+0x4314,
+
+0x0320,
+0x101C,
+
+0x0322,
+0x107d,
+
+0x0320,
+0x2af3,
+0x2bf5,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+
+0x8806, /*EXP Max(120Hz) 7.50 fps */
+0x8968,
+0x8aa0,
+
+0xa506, /*EXP Max(100Hz) 7.14 fps */
+0xa668,
+0xa7a0,
+
+0x9106, /*EXP Fix 7.00 fps*/
+0x9289,
+0x9370,
+
+0x0320,
+0x109C,
+
+0x0322,
+0x10fd,
+
+0x0300,
+0x1194,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_15fix[] = {
+0x0300,
+0x0101,
+
+0x1190,
+
+0x4200,
+0x4314,
+
+0x0320,
+0x101C,
+
+0x0322,
+0x107d,
+
+0x0310, /*page 10*/
+0x6007,
+0x6380, /*auto decresment on AG th*/
+
+0x0316,
+0x7007,
+0x711a,
+0x722d,
+0x7346,
+0x746a,
+0x7586,
+0x769c,
+0x77ad,
+0x78bc,
+0x79c9,
+0x7ad4,
+0x7bde,
+0x7ce4,
+0x7deb,
+0x7ef1,
+0x7ff5,
+0x80f9,
+0x81fd,
+0x82ff,
+
+0x0322,
+0x8f5d,
+0x905a,
+0x9156,
+0x9250,
+0x9348,
+0x943f,
+
+0x0320,
+0x2afd,
+0x2bf8,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+
+0x8802, /*EXP Max(120Hz) 17.14 fps */
+0x89bf,
+0x8a20,
+
+0xa502, /*EXP Max(100Hz) 16.67 fps */
+0xa6bf,
+0xa720,
+
+0x9103, /*EXP Fix 15.00 fps*/
+0x920d,
+0x9340,
+
+0x0320,
+0x109C,
+
+0x0322,
+0x10fd,
+
+0x0300,
+0x1194,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_25fix[] = {
+0x0300,
+0x0101,
+
+0x1190,
+
+0x4200,
+0x4362,
+
+0x0320,
+0x101C,
+
+0x0322,
+0x107d,
+
+0x0310, /*page 10*/
+
+0x410a,
+0x6007,
+0x6380, /*auto decresment on AG th*/
+
+0x0316,
+0x7007,
+0x711a,
+0x722d,
+0x7346,
+0x746a,
+0x7586,
+0x769c,
+0x77ad,
+0x78bc,
+0x79c9,
+0x7ad4,
+0x7bde,
+0x7ce4,
+0x7deb,
+0x7ef1,
+0x7ff5,
+0x80f9,
+0x81fd,
+0x82ff,
+
+0x0322,
+0x8f5d,
+0x905a,
+0x9156,
+0x9250,
+0x9348,
+0x943f,
+
+0x0320,
+0x2afd,
+0x2bf8,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845d,
+0x8538,
+
+0x8801, /*EXP Max(120Hz) 40.00 fps */
+0x895f,
+0x8a90,
+
+0xa501, /*EXP Max(100Hz) 25.xx fps */
+0xa6d1,
+0xa7a0,
+
+0x8b74, /*EXP100 */
+0x8c68,
+0x8d60, /*EXP120 */
+0x8ee0,
+
+0x9101, /*EXP Fix 25.00 fps*/
+0x92d4,
+0x93c0,
+
+0x0320,
+0x109C,
+
+0x0322,
+0x10fd,
+
+0x0300,
+0x1194,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_30fix[] =
+{
+/* sensor limitation, use 25fps */
+0xff00,
+};
+
+#endif /* __SR130PC20_REGS_H__ */
diff --git a/drivers/media/video/sr130pc20_regs_kona.h b/drivers/media/video/sr130pc20_regs_kona.h
new file mode 100644
index 0000000..ebc578b
--- /dev/null
+++ b/drivers/media/video/sr130pc20_regs_kona.h
@@ -0,0 +1,4229 @@
+/* sr130pc20_regs.h
+ *
+ * Driver for s5k5ccgx (5MP Camera) from siliconfile
+ *
+ * Copyright (C) 2010, SAMSUNG ELECTRONICS
+ *
+ * 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.
+ *
+ * Change Date: 2012.06.28
+ */
+
+#ifndef __SR130PC20_REGS_H__
+#define __SR130PC20_REGS_H__
+
+/* PV 1st */
+
+static const sr130pc20_regset_t SR130PC20_Init_Reg[] = {
+
+/*0 Page*/
+0x0300,
+0x0101, /*sleep*/
+0x0103, /*s/w reset*/
+0x0101, /*sleep*/
+
+0x0800,/*Don't touch*/
+0x0937,/*Don't touch*/
+0x0a33,/*Don't touch*/
+
+/*PLL Setting*/
+0xd005,
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x1011,
+0x1190, /*xy flip*/
+0x1200,
+0x1488,
+
+0x0300,
+0x2000,
+0x2104,
+0x2200,
+0x2304,
+0x2403,
+0x25C0,
+0x2605,
+0x2700,
+
+0x4001, /*Hblank_280*/
+0x4118,
+0x4200, /*Vblank 100*/
+0x4364,
+
+/*--------------- BLC*/
+0x8008, /*Don't touch */
+0x8197, /*Don't touch */
+0x8290, /*Don't touch */
+0x8330, /*Don't touch */
+0x84cc, /*Don't touch*/
+0x8500, /*Don't touch*/
+0x86d4, /*Don' t touch*/
+0x870f, /*Don't touch*/
+0x8834, /*Don't touch*/
+
+0x900c, /*BLC_TIME_TH_ON*/
+0x910c, /*BLC_TIME_TH_OFF */
+0x92f0, /*BLC_AG_TH_ON*/
+0x93e8, /*BLC_AG_TH_OFF*/
+
+0x9495, /*091202*/
+0x9590, /*091202 */
+0x9838, /*Don't touch*/
+
+/*Dark BLC*/
+0xa001, /* 20100309*/
+0xa201, /* 20100309*/
+0xa401, /* 20100309*/
+0xa601, /* 20100309*/
+
+/*Normal BLC*/
+0xa800,
+0xaa00,
+0xac00,
+0xae00,
+
+/*Out BLC*/
+0x9900,
+0x9a00,
+0x9b00,
+0x9c00,
+
+/*2 Page*/
+0x0302,
+0x1200, /*Don't touch*/
+0x1400, /*Don't touch*/
+0x1500, /*Don't touch*/
+0x184C, /*Don't touch*/
+0x1900, /*Don't touch*/
+0x1A39, /*Don't touch*/
+0x1B00,/*Don't touch*/
+0x1C1a, /*Don't touch*/
+0x1D14, /*Don't touch*/
+0x1E30,/*Don't touch*/
+0x1F10,/*Don't touch*/
+
+0x2077,
+0x21de,
+0x22a7,
+0x2330,
+0x2477,
+0x2510,
+0x2610,
+0x273c,
+0x2b80,
+0x2c02,
+0x2da0,
+0x2e00,
+0x2fa7,
+
+0x3000,
+0x3199,
+0x3200,
+0x3300,
+0x3422,
+0x3601,
+0x3701,
+0x3888,
+0x3988,
+0x3d03,
+0x3e0d,
+0x3f02,
+
+0x49d1,
+0x4a14,
+
+0x5021,
+0x5201,
+0x5381,
+0x5410,
+0x551c,
+0x5611,
+0x5818,
+0x5916,
+0x5da2,
+0x5e5a,
+
+0x6093, /* 20120517 modify*/
+0x61a4, /* 20120517 modify*/
+0x6294, /* 20120517 modify*/
+0x63a3, /* 20120517 modify*/
+0x6494, /* 20120517 modify*/
+0x65a3, /* 20120517 modify*/
+0x670c,
+0x680c,
+0x690c,
+0x6ab4,
+0x6bc4,
+0x6cb5,
+0x6dc2,
+0x6eb5,
+0x6fc0,
+
+0x70b6,
+0x71b8,
+0x7295, /* 20120517 modify*/
+0x73a2, /* 20120517 modify*/
+0x7495, /* 20120517 modify*/
+0x75a2, /* 20120517 modify*/
+0x7695, /* 20120517 modify*/
+0x77a2, /* 20120517 modify*/
+0x7C92, /* 20120517 modify*/
+0x7Dff, /* 20120517 modify*/
+
+0x8001, /* 20120517 modify*/
+0x818a, /* 20120517 modify*/
+0x821e, /* 20120517 modify*/
+0x8336, /* 20120517 modify*/
+0x8489, /* 20120517 modify*/
+0x858b, /* 20120517 modify*/
+0x8689, /* 20120517 modify*/
+0x878b, /* 20120517 modify*/
+0x88ab,
+0x89bc,
+0x8aac,
+0x8bba,
+0x8cad,
+0x8db8,
+0x8eae,
+0x8fb2,
+
+0x90b3,
+0x91b7,
+0x9252, /* 20120517 modify*/
+0x936a, /* 20120517 modify*/
+0x9489, /* 20120517 modify*/
+0x958b, /* 20120517 modify*/
+0x9689, /* 20120517 modify*/
+0x978b, /* 20120517 modify*/
+
+0xA002,
+0xA186, /* 20120517 modify*/
+0xA202,
+0xA386, /* 20120517 modify*/
+0xA486, /* 20120517 modify*/
+0xA502,
+0xA686, /* 20120517 modify*/
+0xA702,
+0xA892, /* 20120517 modify*/
+0xA994, /* 20120517 modify*/
+0xAA92, /* 20120517 modify*/
+0xAB94, /* 20120517 modify*/
+0xAC1c,
+0xAD22,
+0xAE1c,
+0xAF22,
+
+0xB0a4, /* 20120517 modify*/
+0xB1ae, /* 20120517 modify*/
+0xB2a4, /* 20120517 modify*/
+0xB3ae, /* 20120517 modify*/
+0xB4a6, /* 20120517 modify*/
+0xB5ac, /* 20120517 modify*/
+0xB6a6, /* 20120517 modify*/
+0xB7ac, /* 20120517 modify*/
+0xB8a6, /* 20120517 modify*/
+0xB9ab, /* 20120517 modify*/
+0xBAa6, /* 20120517 modify*/
+0xBBab, /* 20120517 modify*/
+0xBCa6, /* 20120517 modify*/
+0xBDab, /* 20120517 modify*/
+0xBEa6, /* 20120517 modify*/
+0xBFab, /* 20120517 modify*/
+
+0xc437,
+0xc552,
+0xc66b,
+0xc786,
+0xc838, /* 20120517 modify*/
+0xc950, /* 20120517 modify*/
+0xca38, /* 20120517 modify*/
+0xcb50, /* 20120517 modify*/
+0xcc6c, /* 20120517 modify*/
+0xcd84, /* 20120517 modify*/
+0xce6c, /* 20120517 modify*/
+0xcf84, /* 20120517 modify*/
+
+/*0xd4a6,*/
+/*0xd5ac,*/
+/*0xd6a6,*/
+/*0xd7ac,*/
+/*add 20120517*/
+0xdc00, /* Added*/
+0xddaf, /* Added*/
+0xde00, /* Added*/
+0xdf90, /* Added*/
+
+0xd010,
+0xd114,
+0xd220,
+0xd300,
+/*DCDC */
+0xd40c, /*DCDC_TIME_TH_ON*/
+0xd50c, /*DCDC_TIME_TH_OFF */
+0xd6f0, /*DCDC_AG_TH_ON*/
+0xd7e8, /*DCDC_AG_TH_OFF*/
+
+0xea8a,
+
+0xF001, /* clock inversion*/
+0xF101,
+0xF201,
+0xF301,
+0xF401,
+0xF500,
+
+/*----------------------------------------------*/
+0x0310, /*page 10*/
+0x1001, /*Ycbcr422_bit Order: YUYV*/
+0x1103,
+0x1230, /*y offset[4], dif_offset[5]*/
+0x1302, /*contrast effet enable : 0x02*/
+0x3400, /*hidden 10->00 100209*/
+0x3701, /*yc2d power save */
+0x3f04, /*100825*/
+0x4080, /*Y offset */
+0x4880,
+0x5300, /*dif_offset option */
+0x5530, /*dif_offset option diff_offset max */
+
+0x604f, /*out color sat en[7] | auto color decrement en[1] /
+ | manual color sat en[0]*/
+
+0x6183, /*blue saturation_C0*/
+0x6280, /*red saturation_B0*/
+
+0x63ff, /*auto decresment on AG th*/
+0x64c0, /*auto decresment on DG th*/
+0x66e4, /*Outdoor saturation step 137fps apply out th */
+0x6703, /*Outdoor saturation B/R*/
+0x7601, /* ADD 20121031 */
+0x7904, /* ADD 20121031 */
+
+/* Hi 163 */
+/* PAGE 10 START*/
+0x0310,
+0x8000, /* dsshin --> color enhance*/
+0xf500, /* dsshin --> h blank option*/
+
+0x0311, /*page 11 D_LPF */
+0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/
+0x1120, /* Uniform Full GbGr/OV-Nr*/
+
+0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/
+0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */
+
+0x30ba, /*Outdoor2 H th*/
+0x3110, /*Outdoor2 L th*/
+0x3250, /*Outdoor2 gain ratio*/
+0x331d, /*Outdoor2 H lum*/
+0x3420, /*Outdoor2 M lum*/
+0x351f, /*Outdoor2 L lum*/
+
+0x36b0, /*Outdoor1 H th*/
+0x3718, /*Outdoor1 L th*/
+0x3850, /*Outdoor1 gain ratio 0x80->40*/
+0x391d, /*Outdoor1 H lum 0x28->1e*/
+0x3a20, /*Outdoor1 M lum 0x10->15*/
+0x3b1f, /*Outdoor1 L lum 0x08->20*/
+
+0x3c3f, /*indoor H th*/
+0x3d16, /*indoor L th*/
+0x3e30, /*indoor gain ratio 0x44 6a */
+0x3f1a, /*indoor H lum 0x12 18 */
+0x4060, /*indoor M lum 0x18 1c*/
+0x411a, /*indoor L lum 0x18 3e*/
+
+0x4298, /*dark1 H th*/
+0x4328, /*dark1 L th*/
+0x4465, /*dark1 gain ratio*/
+0x4516, /*dark1 H lum 0x38->0x28 */
+0x4630, /*dark1 M lum 0x27->0x17*/
+0x4734, /*dark1 L lum 0x20->0x1a */
+
+0x4890, /*dark2 H th*/
+0x492a, /*dark2 L th*/
+0x4a65, /*dark2 gain ratio*/
+0x4b18, /*dark2 H lum */
+0x4c31, /*dark2 M lum*/
+0x4d36, /*dark2 L lum */
+
+0x4e80, /*dark3 H th*/
+0x4f30, /*dark3 L th*/
+0x5065, /*dark3 gain ratio*/
+0x5119, /*dark3 H lum */
+0x5231, /*dark3 M lum */
+0x5336, /*dark3 L lum */
+
+0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */
+0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/
+0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/
+
+0x603f, /*GbGr all enable*/
+0x620f, /*GbGr offset*/
+
+0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/
+0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/
+0x6700, /*dark GbGr rate H/M/L 100%*/
+
+0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/
+0x75a0, /* Outdoor2 Abberation Luminance lvl */
+0x7db4, /* Indoor Abberation Luminance lvl*/
+
+0x9608, /*indoor/Dark1 edgeoffset1*/
+0x9714, /*indoor/Dark1 center G value*/
+0x98f5, /*slope indoor :: left/right graph polarity, slope*/
+0x992a, /*indoor uncertain ratio control*/
+0x9a20, /*Edgeoffset_dark*/
+
+/*DPC_CTRL*/
+0x0312, /*Preview DPC off[0x5c] on[0x5d]*/
+0x200f,
+0x210f,
+
+0x2500, /* 0x30*/
+
+0x2a01,
+0x2e00, /*2010.8.25*/
+
+0x3035, /*Texture region(most detail)*/
+0x31a0, /*STD uniform1 most blur region*/
+0x32b0, /*STD uniform2 2nd blur*/
+0x33c0, /*STD uniform3 3rd blur*/
+0x34d0, /*STD normal noise1 4th blur */
+0x35e0, /*STD normal noise2 5th blur*/
+0x36ff, /*STD normal noise3 6th blur*/
+
+0x4083, /*Outdoor2 H th*/
+0x4120, /*Outdoor2 L th */
+0x4208, /*Outdoor2 H luminance */
+0x4310, /*Outdoor2 M luminance */
+0x4410, /*Outdoor2 l luminance */
+0x4550, /*Outdoor2 ratio*/
+
+0x4683, /*Outdoor1 H th*/
+0x4720, /*Outdoor1 L th */
+0x4808, /*Outdoor1 H luminance*/
+0x4910, /*Outdoor1 M luminance*/
+0x4a10, /*Outdoor1 L luminance*/
+0x4b50, /*Outdoor1 ratio*/
+
+0x4c80, /*Indoor H th*/
+0x4d48, /*Indoor L th*/
+0x4e30, /*indoor H lum*/
+0x4f30, /*indoor M lum*/
+0x5012, /*indoor L lum */
+0x5170, /*indoor ratio 0x10 -> 0x45*/
+
+0x52a8, /*dark1 H th*/
+0x5330, /*dark1 L th */
+0x5428, /*dark1 H lum */
+0x553e, /*dark1 M lum*/
+0x5667, /*dark1 L lum*/
+0x576a, /*dark1 ratio*/
+
+0x58a0, /*dark2 H th*/
+0x5940, /*dark2 L th*/
+0x5a28, /*dark2 H lum*/
+0x5b3f, /*dark2 M lum*/
+0x5c68, /*dark2 L lum*/
+0x5d70, /*dark2 ratio*/
+
+0x5ea0, /*dark3 H th*/
+0x5f40, /*dark3 L th*/
+0x6029, /*dark3 H lum*/
+0x613f, /*dark3 M lum*/
+0x6269, /*dark3 L lum*/
+0x636a, /*dark3 ratio*/
+
+/*C-filter(Out2&Out1)*/
+0x7010,
+0x710a,
+
+/*C-filter(Indoor&Dark3)*/
+0x7210,
+0x730a,
+
+/*C-filter(Dark2&Dark1)*/
+0x7418,
+0x7512,
+
+0x8020,
+0x8140,
+0x8265,
+0x851a,
+0x8800,
+0x8900,
+0x905d, /*Preview DPC off[0x5c] on[0x5d]*/
+
+/*DPC-Dark1,2,3*/
+0xad07, /*10825*/
+0xae07, /*10825*/
+0xaf07, /*10825*/
+
+/*Blue Det..*/
+0xc558, /*BlueRange 2010.8.25 0x40->23 */
+0xc620, /*GreenRange 2010.8.25 0x3b->20 */
+
+0xd088, /*2010.8.25*/
+0xd180,
+0xd217,/*preview 17, full 67*/
+0xd300,
+0xd400,
+0xd50f,/*preview 0f, full 02*/
+0xd6ff,
+0xd7ff,/*preview ff, full 18*/
+0xd800,
+0xd904,
+
+/*interpolated with average*/
+0xdb38, /*resolution issue 0x00->0x18->0x38 */
+0xd904, /*strong_edge detect ratio*/
+0xe001, /*strong_edge detect ratio*/
+
+0x0313, /*page 13 sharpness 1D*/
+0x10c5,
+0x117b,
+0x120e,
+0x1400,
+
+0x1511, /*added option 1.3M*/
+0x1830, /*added option 1.3M*/
+
+0x2015,
+0x2113,
+0x2233,
+0x2308, /*hi_clip th1*/
+0x241a, /*hi_clip th2*/
+0x2506, /*low clip th*/
+
+0x2618,
+0x2730,
+0x2910, /*time th*/
+0x2a30, /*pga th*/
+
+0x2b03, /*lpf out2*/
+0x2c03, /*lpf out1*/
+0x2d0c,
+0x2e12,
+0x2f12,
+
+/*1D Edge*/
+0x500a, /*out2 hi nega*/
+0x5307, /* hi pos*/
+0x510c, /* mi nega*/
+0x5407, /* mi pos*/
+0x520b, /* lo nega*/
+0x5508, /* lo pos*/
+
+0x560a, /*out1 hi nega*/
+0x5907, /* hi pos */
+0x570c, /* mi nega*/
+0x5a07, /* mi pos */
+0x580b, /* lo nega*/
+0x5b08, /* lo pos */
+
+/*Indoor Edge*/
+0x5c08, /*indoor hi nega*/
+0x5f07, /* hi pos*/
+0x5d14,
+0x6012,
+0x5e0a,
+0x6108, /* low pos*/
+
+0x6208, /*dark1 hi nega*/
+0x6506, /* hi pos */
+0x6308, /* mid nega */
+0x6606, /* mid pos */
+0x6408, /* low nega */
+0x6706, /* low pos */
+
+0x6807, /*dark2 hi nega*/
+0x6b05, /* hi pos */
+0x6907, /* mid nega */
+0x6c05, /* mid pos */
+0x6a07, /* low nega */
+0x6d05, /* low pos */
+
+0x6e0a, /*dark3 hi nega*/
+0x7109, /* hi pos */
+0x6f0a, /* mid nega */
+0x7209, /* mid pos */
+0x700a, /* low nega */
+0x7309, /* low pos */
+
+ /* 2DY*/
+0x80c1,
+0x811f,
+0x82e1,
+0x8333,
+
+0x9005,
+0x9105,
+0x9233,
+0x9330,
+0x9403,
+0x9514,
+0x9730,
+0x9930,
+
+0xa002, /*2d lclp out2 nega*/
+0xa103, /*2d lclp out2 pos*/
+0xa202, /*2d lclp out1 nega*/
+0xa303, /*2d lclp out1 pos*/
+0xa403, /*2d lclp in nega*/
+0xa504, /*2d lclp in pos*/
+0xa607, /*2d lclp dark1 nega*/
+0xa708, /*2d lclp dark1 pos*/
+0xa807, /*2d lclp dark2 nega*/
+0xa908, /*2d lclp dark2 pos*/
+0xaa07, /*2d lclp dark3 nega*/
+0xab08, /*2d lclp dark3 pos*/
+
+0xb010, /*out2 H Ne*/
+0xb310, /* H Po*/
+0xb11e, /* M Ne*/
+0xb41e, /* M Po*/
+0xb21f, /* L Ne*/
+0xb51e, /* L Po*/
+
+0xb610, /*out1 H Ne */
+0xb910, /* H Po */
+0xb71e, /* M Ne */
+0xba1e, /* M Po */
+0xb81f, /* L Ne */
+0xbb1e, /* L Po */
+
+0xbc20, /*indoor H Ne*/
+0xbf1e, /* H Po*/
+0xbd25, /* M Ne*/
+0xc023, /* M Po*/
+0xbe24, /* L Ne*/
+0xc122, /* L Po*/
+
+0xc223, /*dark1 H Ne*/
+0xc523, /* H Po*/
+0xc329, /* M Ne*/
+0xc629, /* M Po*/
+0xc425, /* L Ne*/
+0xc725, /* L Po*/
+
+0xc81c, /*dark2 H Ne*/
+0xcb1c, /* H Po*/
+0xc925, /* M Ne*/
+0xcc25, /* M Po*/
+0xca23, /* L Ne*/
+0xcd23, /* L Po*/
+
+0xce1c, /*dark3 H Ne*/
+0xd11c, /* H Po*/
+0xcf25, /* M Ne*/
+0xd225, /* M Po*/
+0xd023, /* L Ne*/
+0xd323, /* L Po*/
+
+/* PAGE 14 START*/
+0x0314,
+0x1031,
+
+0x1480, /* GX*/
+0x1580, /* GY*/
+0x1680, /* RX*/
+0x1780, /* RY*/
+0x1880, /* BX*/
+0x1980, /* BY*/
+
+0x2060, /* X Center*/
+0x2180, /* Y Center*/
+
+0x2280,
+0x2380,
+0x2480,
+
+0x30c8,
+0x312b,
+0x3200,
+0x3300,
+0x3490,
+
+0x4056, /*R min's set 4e*/
+0x413a, /*Gr*/
+0x4237, /*B*/
+0x433a, /*Gb*/
+
+0x0315,
+0x1021,
+0x1444, /*49*/
+0x1534, /*38*/
+0x1626, /*2b*/
+0x172f,
+
+0x30dd,
+0x3162,
+0x3205,
+0x3326,
+0x34bd,
+0x3517,
+0x3618,
+0x3738,
+0x38d0,
+
+0x40b0,
+0x4130,
+0x4200,
+0x4300,
+0x4400,
+0x4500,
+0x4699,
+0x4719,
+0x4800,
+
+0x5016,
+0x51b2,
+0x521c,
+0x5306,
+0x5420,
+0x55a6,
+0x560e,
+0x57b2,
+0x5824,
+
+0x0316,
+0x1031, /*GMA_CTL*/
+0x187e, /*AG_ON*/
+0x197d, /*AG_OFF*/
+0x1a0e, /*TIME_ON*/
+0x1b01, /*TIME_OFF*/
+0x1Cdc, /*OUT_ON*/
+0x1Dfe, /*OUT_OFF*/
+
+/*GMA Indoor*/
+0x3000,
+0x3107,
+0x321a,
+0x3335,
+0x345a,
+0x357c,
+0x3696,
+0x37a9,
+0x38b7,
+0x39c6,
+0x3ad2,
+0x3bdc,
+0x3ce4,
+0x3deb,
+0x3ef1,
+0x3ff5,
+0x40f9,
+0x41fd,
+0x42ff,
+
+/*RGMA Outdoor*/
+0x5000,
+0x5103,
+0x5213,
+0x532e,
+0x5459,
+0x5579,
+0x5690,
+0x57a3,
+0x58b4,
+0x59c2,
+0x5acd,
+0x5bd7,
+0x5ce0,
+0x5de5,
+0x5ee9,
+0x5fee,
+0x60f1,
+0x61f3,
+0x62f6,
+
+/*BGMA Dark*/
+0x7003,
+0x7111,
+0x721f,
+0x7337,
+0x7452,
+0x756c,
+0x7685,
+0x779a,
+0x78ad,
+0x79bd,
+0x7acb,
+0x7bd6,
+0x7ce0,
+0x7de8,
+0x7eef,
+0x7ff4,
+0x80f8,
+0x81fb,
+0x82fe,
+
+0x0324, /*Resol control */
+0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/
+0x6104, /*even frame update */
+0x6408,
+0x6500,
+0x6626, /*edge th2 H */
+0x6700, /*edge th2 L */
+
+0x0313,
+0x1831, /*flat center Gb/Gr*/
+0x7402, /*det slope en | gausian filter*/
+0x750d, /*1D negative gain det 09 */
+0x760d, /*1D postive gain det 08*/
+0x7710, /*1D hclp2 det*/
+0x7808, /*outdoor flat threshold*/
+0x7910, /*indoor flat threshold*/
+
+0x81df, /*det gain controler*/
+0x8690, /*2D negative gain det */
+0x8790, /*2D postive gain det */
+0x962a, /*2D hclp2 det*/
+
+0x0312, /*0x12 page*/
+0xd088,
+0xd9e4,
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+/* PAGE 20 START*/
+0x0320,
+0x111c,
+0x1830,
+0x1a08,
+0x2045,/*weight*/
+0x2130,
+0x2210,
+0x2300,
+0x2400,
+
+0x28e7, /* add 20120223*/
+0x290d, /* 20100305 ad -> 0d*/
+0x2afd,
+0x2bf8,
+
+0x2cc3,
+0x2d5f, /* add 20120223*/
+0x2e33,
+0x30f8,
+0x3203,
+0x332e,
+0x3430,
+0x35d4,
+0x36ff, /*fe*/
+0x3732,
+0x3804,
+0x3922,
+0x3ade,
+0x3b22,
+0x3cde,
+0x3de1,
+
+0x5045,
+0x5188,
+
+0x561a,
+0x5780,
+0x580e,
+0x596a,
+0x5a04,
+
+0x5e9d, /*AE_AWB_start*/
+0x5f76, /*AE_AWB_start*/
+
+0x7033, /* 6c*/
+0x7182, /* 82(+8)*/
+
+0x7621,
+0x7771,
+0x7822, /* 24*/
+0x7923, /* Y Target 70 => 25, 72 => 26*/
+0x7a23, /* 23*/
+0x7b22, /* 22*/
+0x7d23,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+0x8601, /*EXPMin 7500.00 fps*/
+0x8790,
+0x8805, /*EXP Max(120Hz) 8.00 fps */
+0x89b8,
+0x8ad8,
+0xa505, /*EXP Max(100Hz) 8.33 fps */
+0xa67e,
+0xa740,
+0x8B75, /*EXP100 */
+0x8C30,
+0x8D61, /*EXP120 */
+0x8Ea8,
+0x9c09, /*EXP Limit 1250.00 fps */
+0x9d60,
+0x9e01, /*EXP Unit */
+0x9f90,
+0x989d,
+
+0xb016,
+0xb114,
+0xb2f8,
+0xb314,
+0xb41b,
+0xb546,
+0xb631,
+0xb729,
+0xb826,
+0xb924,
+0xba22,
+0xbb42,
+0xbc41,
+0xbd40,
+
+0xc010,
+0xc138,
+0xc238,
+0xc338,
+0xc407,
+
+0xc880,
+0xc980,
+0x109c, /* ae enable*/
+/* PAGE 20 END*/
+
+/*AE_Weight*/
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2412,
+0x2522,
+0x2622,
+0x2721,
+0x2812,
+0x2922,
+0x2a22,
+0x2b21,
+0x2c12,
+0x2d23,
+0x2e32,
+0x2f21,
+0x3012,
+0x3123,
+0x3232,
+0x3321,
+0x3412,
+0x3522,
+0x3622,
+0x3721,
+0x3812,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+
+/* PAGE 22 START*/
+0x0322,
+0x10fd,
+0x112e,
+0x1901, /* Low On*/
+0x2030, /* for wb speed*/
+0x2140,
+0x2401,
+0x257e, /* for tracking 20120314 */
+
+0x3080, /* 20120224 test*/
+0x3180,
+0x3811,
+0x3934,
+
+0x40e8,
+0x4143, /* 33*/
+0x4222, /* 22*/
+
+0x43f3, /* f6*/
+0x4454, /* 44*/
+0x4522, /* 33*/
+
+0x4600,
+0x480a,
+0x50b2,
+0x5181,
+0x5298,
+
+0x8038,
+0x8120,
+0x8238, /* 3a*/
+
+0x8356, /* R Max*/
+0x8420, /* R Min*/
+0x8552, /* B Max*/
+0x8620, /* B Min*/
+
+0x8745,
+0x883a,
+0x8933,
+0x8a2c,
+
+0x8b42,
+0x8c3d,
+0x8d30,
+0x8e2c,
+
+0x8f5a,
+0x9059,
+0x9155,
+0x924e,
+0x9344,
+0x943a,
+0x9534,
+0x962c,
+0x9723,
+0x9820,
+0x991f,
+0x9a1f,
+
+0x9b77,
+0x9c77,
+0x9d48,
+0x9e38,
+0x9f30,
+
+0xa040,
+0xa121,
+0xa26f,
+0xa3ff,
+
+0xa414, /* 1500fps*/
+0xa544, /* 700fps*/
+0xa6cf,
+
+0xad40,
+0xae4a,
+
+0xaf2a, /* low temp Rgain*/
+0xb028, /* low temp Rgain*/
+
+0xb100, /* 0x20 -> 0x00 0405 modify*/
+0xb4bf, /* for tracking 20120314*/
+0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/
+0xb900,
+/* PAGE 22 END*/
+
+/* PAGE 48 (MiPi 1600x1200)*/
+0x0300,
+
+/* PLL Setting */
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0e,
+0x1e07,
+0x1f08,
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2b40,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_VT_Init_Reg[] = {
+/*0 Page*/
+0x0300,
+0x0101, /*sleep*/
+0x0103, /*s/w reset*/
+0x0101, /*sleep*/
+
+0x0800,/*Don't touch*/
+0x0937,/*Don't touch*/
+0x0a33,/*Don't touch*/
+
+/*PLL Setting*/
+0xd005,
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x1011,
+0x1194, /*xy flip*/
+0x1200, /*Sync type default:0x00 PCLK[2] 0 falling, 1 rising*/
+0x1488,
+
+/*--------------- windowing */
+0x0300,
+0x2000,
+0x2104,
+0x2200,
+0x2304,
+0x2403,
+0x25C0,
+0x2605,
+0x2700,
+
+0x4001, /*Hblank 280*/
+0x4118,
+0x4200, /*Vblank 20*/
+0x4314,
+
+/*--------------- BLC*/
+0x8008, /*Don't touch */
+0x8197, /*Don't touch */
+0x8290, /*Don't touch */
+0x8330, /*Don't touch */
+0x84cc, /*Don't touch*/
+0x8500, /*Don't touch*/
+0x86d4, /*Don' t touch*/
+0x870f, /*Don't touch*/
+0x8834, /*Don't touch*/
+
+0x9009, /*BLC_TIME_TH_ON*/
+0x9109, /*BLC_TIME_TH_OFF */
+0x92f0, /*BLC_AG_TH_ON*/
+0x93e8, /*BLC_AG_TH_OFF*/
+
+0x9495, /*091202*/
+0x9590, /*091202 */
+0x9838, /*Don't touch*/
+
+/*Dark BLC*/
+0xa001, /* 20100309*/
+0xa201, /* 20100309*/
+0xa401, /* 20100309*/
+0xa601, /* 20100309*/
+
+/*Normal BLC*/
+0xa800,
+0xaa00,
+0xac00,
+0xae00,
+
+/*Out BLC*/
+0x9900,
+0x9a00,
+0x9b00,
+0x9c00,
+
+/*2 Page*/
+0x0302,
+0x1200, /*Don't touch*/
+0x1400, /*Don't touch*/
+0x1500, /*Don't touch*/
+0x184C, /*Don't touch*/
+0x1900, /*Don't touch*/
+0x1A39, /*Don't touch*/
+0x1B00,/*Don't touch*/
+0x1C1a, /*Don't touch*/
+0x1D14, /*Don't touch*/
+0x1E30,/*Don't touch*/
+0x1F10,/*Don't touch*/
+
+0x2077,
+0x21de,
+0x22a7,
+0x2330,
+0x2477,
+0x2510,
+0x2610,
+0x273c,
+0x2b80,
+0x2c02,
+0x2da0,
+0x2e00,
+0x2fa7,
+
+0x3000,
+0x3199,
+0x3200,
+0x3300,
+0x3422,
+0x3601,
+0x3701,
+0x3888,
+0x3988,
+0x3d03,
+0x3e0d,
+0x3f02,
+
+0x49d1,
+0x4a14,
+
+0x5021,
+0x5201,
+0x5381,
+0x5410,
+0x551c,
+0x5611,
+0x5818,
+0x5916,
+0x5da2,
+0x5e5a,
+
+0x6093, /* 20120517 modify*/
+0x61a4, /* 20120517 modify*/
+0x6294, /* 20120517 modify*/
+0x63a3, /* 20120517 modify*/
+0x6494, /* 20120517 modify*/
+0x65a3, /* 20120517 modify*/
+0x670c,
+0x680c,
+0x690c,
+0x6ab4,
+0x6bc4,
+0x6cb5,
+0x6dc2,
+0x6eb5,
+0x6fc0,
+
+0x70b6,
+0x71b8,
+0x7295, /* 20120517 modify*/
+0x73a2, /* 20120517 modify*/
+0x7495, /* 20120517 modify*/
+0x75a2, /* 20120517 modify*/
+0x7695, /* 20120517 modify*/
+0x77a2, /* 20120517 modify*/
+0x7C92, /* 20120517 modify*/
+0x7Dff, /* 20120517 modify*/
+
+0x8001, /* 20120517 modify*/
+0x818a, /* 20120517 modify*/
+0x821e, /* 20120517 modify*/
+0x8336, /* 20120517 modify*/
+0x8489, /* 20120517 modify*/
+0x858b, /* 20120517 modify*/
+0x8689, /* 20120517 modify*/
+0x878b, /* 20120517 modify*/
+0x88ab,
+0x89bc,
+0x8aac,
+0x8bba,
+0x8cad,
+0x8db8,
+0x8eae,
+0x8fb2,
+
+0x90b3,
+0x91b7,
+0x9252, /* 20120517 modify*/
+0x936a, /* 20120517 modify*/
+0x9489, /* 20120517 modify*/
+0x958b, /* 20120517 modify*/
+0x9689, /* 20120517 modify*/
+0x978b, /* 20120517 modify*/
+
+0xA002,
+0xA186, /* 20120517 modify*/
+0xA202,
+0xA386, /* 20120517 modify*/
+0xA486, /* 20120517 modify*/
+0xA502,
+0xA686, /* 20120517 modify*/
+0xA702,
+0xA892, /* 20120517 modify*/
+0xA994, /* 20120517 modify*/
+0xAA92, /* 20120517 modify*/
+0xAB94, /* 20120517 modify*/
+0xAC1c,
+0xAD22,
+0xAE1c,
+0xAF22,
+
+0xB0a4, /* 20120517 modify*/
+0xB1ae, /* 20120517 modify*/
+0xB2a4, /* 20120517 modify*/
+0xB3ae, /* 20120517 modify*/
+0xB4a6, /* 20120517 modify*/
+0xB5ac, /* 20120517 modify*/
+0xB6a6, /* 20120517 modify*/
+0xB7ac, /* 20120517 modify*/
+0xB8a6, /* 20120517 modify*/
+0xB9ab, /* 20120517 modify*/
+0xBAa6, /* 20120517 modify*/
+0xBBab, /* 20120517 modify*/
+0xBCa6, /* 20120517 modify*/
+0xBDab, /* 20120517 modify*/
+0xBEa6, /* 20120517 modify*/
+0xBFab, /* 20120517 modify*/
+
+0xc437,
+0xc552,
+0xc66b,
+0xc786,
+0xc838, /* 20120517 modify*/
+0xc950, /* 20120517 modify*/
+0xca38, /* 20120517 modify*/
+0xcb50, /* 20120517 modify*/
+0xcc6c, /* 20120517 modify*/
+0xcd84, /* 20120517 modify*/
+0xce6c, /* 20120517 modify*/
+0xcf84, /* 20120517 modify*/
+
+/*0xd4a6,*/
+/*0xd5ac,*/
+/*0xd6a6,*/
+/*0xd7ac,*/
+/*add 20120517*/
+0xdc00, /* Added*/
+0xddaf, /* Added*/
+0xde00, /* Added*/
+0xdf90, /* Added*/
+
+0xd010,
+0xd114,
+0xd220,
+0xd300,
+/*DCDC */
+0xd409, /*DCDC_TIME_TH_ON*/
+0xd509, /*DCDC_TIME_TH_OFF */
+0xd6f0, /*DCDC_AG_TH_ON*/
+0xd7e8, /*DCDC_AG_TH_OFF*/
+
+0xea8a,
+
+0xF001, /* clock inversion*/
+0xF101,
+0xF201,
+0xF301,
+0xF401,
+0xF500,
+
+/*----------------------------------------------*/
+0x0310, /*page 10*/
+0x1001, /*Ycbcr422_bit Order: YUYV*/
+0x1230, /*y offset[4], dif_offset[5]*/
+0x1302, /*contrast effet enable : 0x02*/
+0x3400, /*hidden 10->00 100209*/
+0x3701, /*yc2d power save */
+0x3f04, /*100825*/
+0x4080, /*Y offset */
+0x4138,
+0x4880, /*Contrast (Y = constrast * (Y - 128) + 128)*//*86 */
+0x50f0,
+0x5300, /*dif_offset option */
+0x5530, /*dif_offset option diff_offset max */
+
+0x6003, /*out color sat en[7] | auto color decrement en[1] /
+ | manual color sat en[0]*/
+
+
+0x6183, /*blue saturation_C0*/
+0x6280, /*red saturation_B0*/
+
+0x63ff, /*auto decresment on AG th*/
+0x64ff, /*auto decresment on DG th*/
+0x66e4, /*Outdoor saturation step 137fps apply out th */
+0x6700, /*Outdoor saturation B/R*/
+0x7601, /* ADD 20121031 */
+0x7904, /* ADD 20121031 */
+
+/* Hi 163 */
+/* PAGE 10 START*/
+0x0310,
+0x8000, /* dsshin --> color enhance*/
+0xf500, /* dsshin --> h blank option*/
+
+0x0311, /*page 11 D_LPF */
+0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/
+0x1120, /* Uniform Full GbGr/OV-Nr*/
+
+0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/
+0x13b8, /*dark2[7] | dark2 maxfilter ratio[6:4]
+ | dark3[3] | dark3 maxfilter ratio[2:0] */
+
+0x30ba, /*Outdoor2 H th*/
+0x3110, /*Outdoor2 L th*/
+0x3250, /*Outdoor2 gain ratio*/
+0x331d, /*Outdoor2 H lum*/
+0x3420, /*Outdoor2 M lum*/
+0x351f, /*Outdoor2 L lum*/
+
+0x36b0, /*Outdoor1 H th*/
+0x3718, /*Outdoor1 L th*/
+0x3850, /*Outdoor1 gain ratio 0x80->40*/
+0x391d, /*Outdoor1 H lum 0x28->1e*/
+0x3a20, /*Outdoor1 M lum 0x10->15*/
+0x3b1f, /*Outdoor1 L lum 0x08->20*/
+
+0x3c3f, /*indoor H th*/
+0x3d16, /*indoor L th*/
+0x3e30, /*indoor gain ratio 0x44 6a */
+0x3f1a, /*indoor H lum 0x12 18 */
+0x4060, /*indoor M lum 0x18 1c*/
+0x411a, /*indoor L lum 0x18 3e*/
+
+0x4298, /*dark1 H th*/
+0x4328, /*dark1 L th*/
+0x4465, /*dark1 gain ratio*/
+0x4516, /*dark1 H lum 0x38->0x28 */
+0x4630, /*dark1 M lum 0x27->0x17*/
+0x4734, /*dark1 L lum 0x20->0x1a */
+
+0x4890, /*dark2 H th*/
+0x492a, /*dark2 L th*/
+0x4a65, /*dark2 gain ratio*/
+0x4b18, /*dark2 H lum */
+0x4c31, /*dark2 M lum*/
+0x4d36, /*dark2 L lum */
+
+0x4e80, /*dark3 H th*/
+0x4f30, /*dark3 L th*/
+0x5065, /*dark3 gain ratio*/
+0x5119, /*dark3 H lum */
+0x5231, /*dark3 M lum */
+0x5336, /*dark3 L lum */
+
+0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */
+0x5b00, /*Impulse pixel enable dark123,in,out123
+ :: must be 0x07 fix setting use!*/
+0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/
+
+0x603f, /*GbGr all enable*/
+0x620f, /*GbGr offset*/
+/*0x6325,*/ /*GbGr max_20120605_off*/
+/*0x6410,*/ /*GbGr min_20120605_off*/
+
+0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/
+0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/
+0x6700, /*dark GbGr rate H/M/L 100%*/
+
+0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/
+0x75a0, /* Outdoor2 Abberation Luminance lvl */
+0x7db4, /* Indoor Abberation Luminance lvl*/
+
+0x9608, /*indoor/Dark1 edgeoffset1*/
+0x9714, /*indoor/Dark1 center G value*/
+0x98f5, /*slope indoor :: left/right graph polarity, slope*/
+0x992a, /*indoor uncertain ratio control*/
+0x9a20, /*Edgeoffset_dark*/
+
+/*DPC_CTRL*/
+0x0312, /*Preview DPC off[0x5c] on[0x5d]*/
+0x200e,
+0x210e,
+
+0x2500, /* 0x30*/
+
+0x2a01,
+0x2e00, /*2010.8.25*/
+
+0x3035, /*Texture region(most detail)*/
+0x31a0, /*STD uniform1 most blur region*/
+0x32b0, /*STD uniform2 2nd blur*/
+0x33c0, /*STD uniform3 3rd blur*/
+0x34d0, /*STD normal noise1 4th blur */
+0x35e0, /*STD normal noise2 5th blur*/
+0x36ff, /*STD normal noise3 6th blur*/
+
+0x4083, /*Outdoor2 H th*/
+0x4120, /*Outdoor2 L th */
+0x4208, /*Outdoor2 H luminance */
+0x4310, /*Outdoor2 M luminance */
+0x4410, /*Outdoor2 l luminance */
+0x4550, /*Outdoor2 ratio*/
+
+0x4683, /*Outdoor1 H th*/
+0x4720, /*Outdoor1 L th */
+0x4808, /*Outdoor1 H luminance*/
+0x4910, /*Outdoor1 M luminance*/
+0x4a10, /*Outdoor1 L luminance*/
+0x4b50, /*Outdoor1 ratio*/
+
+0x4c80, /*Indoor H th*/
+0x4d48, /*Indoor L th*/
+0x4e30, /*indoor H lum*/
+0x4f30, /*indoor M lum*/
+0x5012, /*indoor L lum */
+0x5170, /*indoor ratio 0x10 -> 0x45*/
+
+0x52a8, /*dark1 H th*/
+0x5330, /*dark1 L th */
+0x5428, /*dark1 H lum */
+0x553e, /*dark1 M lum*/
+0x5667, /*dark1 L lum*/
+0x576a, /*dark1 ratio*/
+
+0x58a0, /*dark2 H th*/
+0x5940, /*dark2 L th*/
+0x5a28, /*dark2 H lum*/
+0x5b3f, /*dark2 M lum*/
+0x5c68, /*dark2 L lum*/
+0x5d70, /*dark2 ratio*/
+
+0x5ea0, /*dark3 H th*/
+0x5f40, /*dark3 L th*/
+0x6029, /*dark3 H lum*/
+0x613f, /*dark3 M lum*/
+0x6269, /*dark3 L lum*/
+0x636a, /*dark3 ratio*/
+
+/*C-filter(Out2&Out1)*/
+0x7010,
+0x710a,
+
+/*C-filter(Indoor&Dark3)*/
+0x7210,
+0x730a,
+
+/*C-filter(Dark2&Dark1)*/
+0x7418,
+0x7512,
+
+0x8020,
+0x8140,
+0x8265,
+0x851a,
+0x8800,
+0x8900,
+0x905d, /*Preview DPC off[0x5c] on[0x5d]*/
+
+/*DPC-Dark1,2,3*/
+0xad07, /*10825*/
+0xae07, /*10825*/
+0xaf07, /*10825*/
+
+/*Blue Det..*/
+0xc558, /*BlueRange 2010.8.25 0x40->23 */
+0xc620, /*GreenRange 2010.8.25 0x3b->20 */
+
+0xd088, /*2010.8.25*/
+0xd180,
+0xd217,/*preview 17, full 67*/
+0xd300,
+0xd400,
+0xd50f,/*preview 0f, full 02*/
+0xd6ff,
+0xd7ff,/*preview ff, full 18*/
+0xd800,
+0xd904,
+
+/*interpolated with average*/
+0xdb38, /*resolution issue 0x00->0x18->0x38 */
+0xd904, /*strong_edge detect ratio*/
+0xe001, /*strong_edge detect ratio*/
+
+0x0313, /*page 13 sharpness 1D*/
+0x10c5,
+0x117b,
+0x120e,
+0x1400,
+
+0x1511, /*added option 1.3M*/
+0x1830, /*added option 1.3M*/
+
+0x2015,
+0x2113,
+0x2233,
+0x2308, /*hi_clip th1*/
+0x241a, /*hi_clip th2*/
+0x2506, /*low clip th*/
+
+0x2618,
+0x2730,
+0x2910, /*time th*/
+0x2a30, /*pga th*/
+
+0x2b03, /*lpf out2*/
+0x2c03, /*lpf out1*/
+0x2d0c,
+0x2e12,
+0x2f12,
+
+/*1D Edge*/
+0x500a, /*out2 hi nega*/
+0x5307, /* hi pos*/
+0x510c, /* mi nega*/
+0x5407, /* mi pos*/
+0x520b, /* lo nega*/
+0x5508, /* lo pos*/
+
+0x560a, /*out1 hi nega*/
+0x5907, /* hi pos */
+0x570c, /* mi nega*/
+0x5a07, /* mi pos */
+0x580b, /* lo nega*/
+0x5b08, /* lo pos */
+
+/*Indoor Edge*/
+0x5c08, /*indoor hi nega*/
+0x5f07, /* hi pos*/
+0x5d14, /* mid nega ,11*/
+0x6012, /* mid pos ,0*/
+0x5e0a, /* low nega */
+0x6108, /* low pos*/
+
+0x6208, /*dark1 hi nega*/
+0x6506, /* hi pos */
+0x6308, /* mid nega */
+0x6606, /* mid pos */
+0x6408, /* low nega */
+0x6706, /* low pos */
+
+0x6807, /*dark2 hi nega*/
+0x6b05, /* hi pos */
+0x6907, /* mid nega */
+0x6c05, /* mid pos */
+0x6a07, /* low nega */
+0x6d05, /* low pos */
+
+0x6e0a, /*dark3 hi nega*/
+0x7109, /* hi pos */
+0x6f0a, /* mid nega */
+0x7209, /* mid pos */
+0x700a, /* low nega */
+0x7309, /* low pos */
+
+ /* 2DY*/
+0x80c1,
+0x811f,
+0x82e1,
+0x8333,
+
+0x9005,
+0x9105,
+0x9233,
+0x9330,
+0x9403,
+0x9514,
+0x9730,
+0x9930,
+
+0xa002, /*2d lclp out2 nega*/
+0xa103, /*2d lclp out2 pos*/
+0xa202, /*2d lclp out1 nega*/
+0xa303, /*2d lclp out1 pos*/
+0xa403, /*2d lclp in nega*/
+0xa504, /*2d lclp in pos*/
+0xa607, /*2d lclp dark1 nega*/
+0xa708, /*2d lclp dark1 pos*/
+0xa807, /*2d lclp dark2 nega*/
+0xa908, /*2d lclp dark2 pos*/
+0xaa07, /*2d lclp dark3 nega*/
+0xab08, /*2d lclp dark3 pos*/
+
+0xb010, /*out2 H Ne*/
+0xb310, /* H Po*/
+0xb11e, /* M Ne*/
+0xb41e, /* M Po*/
+0xb21f, /* L Ne*/
+0xb51e, /* L Po*/
+
+0xb610, /*out1 H Ne */
+0xb910, /* H Po */
+0xb71e, /* M Ne */
+0xba1e, /* M Po */
+0xb81f, /* L Ne */
+0xbb1e, /* L Po */
+
+0xbc20, /*indoor H Ne*/
+0xbf1e, /* H Po*/
+0xbd25, /* M Ne*/
+0xc023, /* M Po*/
+0xbe24, /* L Ne*/
+0xc122, /* L Po*/
+
+0xc223, /*dark1 H Ne*/
+0xc523, /* H Po*/
+0xc329, /* M Ne*/
+0xc629, /* M Po*/
+0xc425, /* L Ne*/
+0xc725, /* L Po*/
+
+0xc81c, /*dark2 H Ne*/
+0xcb1c, /* H Po*/
+0xc925, /* M Ne*/
+0xcc25, /* M Po*/
+0xca23, /* L Ne*/
+0xcd23, /* L Po*/
+
+0xce1c, /*dark3 H Ne*/
+0xd11c, /* H Po*/
+0xcf25, /* M Ne*/
+0xd225, /* M Po*/
+0xd023, /* L Ne*/
+0xd323, /* L Po*/
+
+/* PAGE 14 START*/
+0x0314,
+0x1031,
+
+0x1480, /* GX*/
+0x1580, /* GY*/
+0x1680, /* RX*/
+0x1780, /* RY*/
+0x1880, /* BX*/
+0x1980, /* BY*/
+
+0x2060, /* X Center*/
+0x2180, /* Y Center*/
+
+0x2280,
+0x2380,
+0x2480,
+
+0x30c8,
+0x312b,
+0x3200,
+0x3300,
+0x3490,
+
+0x4056, /*R min's set 4e*/
+0x413a, /*Gr*/
+0x4237, /*B*/
+0x433a, /*Gb*/
+
+0x0315,
+0x1021,
+0x1444, /*49*/
+0x1534, /*38*/
+0x1626, /*2b*/
+0x172f,
+
+0x30dd,
+0x3162,
+0x3205,
+0x3326,
+0x34bd,
+0x3517,
+0x3618,
+0x3738,
+0x38d0,
+
+0x40b0,
+0x4130,
+0x4200,
+0x4300,
+0x4400,
+0x4500,
+0x4699,
+0x4719,
+0x4800,
+
+0x5016,
+0x51b2,
+0x521c,
+0x5306,
+0x5420,
+0x55a6,
+0x560e,
+0x57b2,
+0x5824,
+
+0x0316,
+0x1031, /*GMA_CTL*/
+0x187e, /*AG_ON*/
+0x197d, /*AG_OFF*/
+0x1a0e, /*TIME_ON*/
+0x1b01, /*TIME_OFF*/
+0x1Cdc, /*OUT_ON*/
+0x1Dfe, /*OUT_OFF*/
+
+/*GMA, Indoor*/
+0x3000,
+0x3107,
+0x321a,
+0x3335,
+0x345a,
+0x357c,
+0x3696,
+0x37a9,
+0x38b7,
+0x39c6,
+0x3ad2,
+0x3bdc,
+0x3ce4,
+0x3deb,
+0x3ef1,
+0x3ff5,
+0x40f9,
+0x41fd,
+0x42ff,
+
+/*RGMA, Outdoor*/
+0x5000,
+0x5103,
+0x5213,
+0x532e,
+0x5459,
+0x5579,
+0x5690,
+0x57a3,
+0x58b4,
+0x59c2,
+0x5acd,
+0x5bd7,
+0x5ce0,
+0x5de5,
+0x5ee9,
+0x5fee,
+0x60f1,
+0x61f3,
+0x62f6,
+
+/*BGMA Dark*/
+0x7000,
+0x7107,
+0x721a,
+0x7335,
+0x745a,
+0x757c,
+0x7696,
+0x77a9,
+0x78b7,
+0x79c6,
+0x7ad2,
+0x7bdc,
+0x7ce4,
+0x7deb,
+0x7ef1,
+0x7ff5,
+0x80f9,
+0x81fd,
+0x82ff,
+
+0x0324, /*Resol control */
+0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/
+0x6104, /*even frame update */
+0x6408, /* 0x6435, edge th1 H*/
+0x6500, /*edge th1 L*/
+0x6626, /*edge th2 H */
+0x6700, /*edge th2 L */
+
+0x0313,
+0x1831, /*flat center Gb/Gr*/
+0x7402, /*det slope en | gausian filter*/
+0x750d, /*1D negative gain det 09 */
+0x760d, /*1D postive gain det 08*/
+0x7710, /*1D hclp2 det*/
+0x7808, /*outdoor flat threshold*/
+0x7910, /*indoor flat threshold*/
+
+0x81df, /*det gain controler*/
+0x8690, /*2D negative gain det */
+0x8790, /*2D postive gain det */
+0x962a, /*2D hclp2 det*/
+
+0x0312, /*0x12 page*/
+0xd088,
+0xd9e4,
+
+/* PAGE 20 START*/
+0x0320,
+0x111c,
+0x1830,
+0x1a08,
+0x2045,/*weight*/
+0x2130,
+0x2210,
+0x2300,
+0x2400,
+
+0x28e7, /* add 20120223*/
+0x290d, /* 20100305 ad -> 0d*/
+0x2afd,
+0x2bf8,
+
+0x2cc3,
+0x2d5f, /* add 20120223*/
+0x2e33,
+0x30f8,
+0x3203,
+0x332e,
+0x3430,
+0x35d4,
+0x36fe,
+0x3732,
+0x3804,
+0x3922,
+0x3ade,
+0x3b22,
+0x3cde,
+0x3de1,
+
+0x5045,
+0x5188,
+
+0x561a,
+0x5780,
+0x580e,
+0x596a,
+0x5a04,
+
+0x5e9d, /*AE_AWB_start*/
+0x5f76, /*AE_AWB_start*/
+
+0x7040, /* 6c*/
+0x7182, /* 82(+8)*/
+
+0x7621,
+0x7791,
+0x7822, /* 24*/
+0x792b, /* Y Target 70 => 25, 72 => 26*/
+0x7a23, /* 23*/
+0x7b22, /* 22*/
+0x7d23,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+
+0x8601, /*EXPMin 7500.00 fps*/
+0x8790,
+
+0x8803, /*EXP Max(120Hz) 12.00 fps*/
+0x89d0,
+0x8a90,
+
+0xa504, /*EXP Max(100Hz) 11.11 fps*/
+0xa61e,
+0xa7b0,
+
+0x8B75, /*EXP100 */
+0x8C30,
+0x8D61, /*EXP120 */
+0x8Ea8,
+
+0x9104, /*EXP Fix 10.00 fps*/
+0x9293,
+0x93e0,
+
+0x9c0a, /*EXP Limit 1071.43 fps*/
+0x9df0,
+0x9e01, /*EXP Unit */
+0x9f90,
+0x989d,
+
+0xb016,
+0xb114,
+0xb2f8,
+0xb314,
+0xb41b,
+0xb546,
+0xb631,
+0xb729,
+0xb826,
+0xb924,
+0xba22,
+0xbb42,
+0xbc41,
+0xbd40,
+
+0xc010,
+0xc138,
+0xc238,
+0xc338,
+0xc407,
+
+0xc880,
+0xc980,
+0x109c, /* ae enable*/
+/* PAGE 20 END*/
+
+/*AE_Weight*/
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2412,
+0x2522,
+0x2622,
+0x2721,
+0x2812,
+0x2922,
+0x2a22,
+0x2b21,
+0x2c12,
+0x2d23,
+0x2e32,
+0x2f21,
+0x3012,
+0x3123,
+0x3232,
+0x3321,
+0x3412,
+0x3522,
+0x3622,
+0x3721,
+0x3812,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+
+/* PAGE 22 START*/
+0x0322,
+0x10fd,
+0x112e,
+0x1901, /* Low On*/
+0x2030, /* for wb speed*/
+0x2140,
+0x2401,
+0x257e, /* for tracking 20120314 */
+
+0x3080, /* 20120224 test*/
+0x3180,
+0x3811,
+0x3934,
+
+0x40e8,
+0x4143, /* 33*/
+0x4222, /* 22*/
+
+0x43f3, /* f6*/
+0x4454, /* 44*/
+0x4522, /* 33*/
+
+0x4600,
+0x480a,
+0x50b2,
+0x5181,
+0x5298,
+
+0x8038,
+0x8120,
+0x8238, /* 3a*/
+
+0x8356, /* R Max*/
+0x8420, /* R Min*/
+0x8554, /* B Max*/
+0x8620, /* B Min*/
+
+0x8746,
+0x8836,
+0x893a,
+0x8a2f,
+
+0x8b3d,
+0x8c37,
+0x8d35,
+0x8e32,
+
+0x8f5a,
+0x9059,
+0x9155,
+0x924e,
+0x9344,
+0x943a,
+0x9534,
+0x962c,
+0x9723,
+0x9820,
+0x991f,
+0x9a1f,
+
+0x9b77,
+0x9c77,
+0x9d48,
+0x9e38,
+0x9f30,
+
+0xa040,
+0xa121,
+0xa26f,
+0xa3ff,
+
+0xa414, /* 1500fps*/
+0xa544, /* 700fps*/
+0xa6cf,
+
+0xad40,
+0xae4a,
+
+0xaf2a, /* low temp Rgain*/
+0xb028, /* low temp Rgain*/
+
+0xb100, /* 0x20 -> 0x00 0405 modify*/
+0xb4bf, /* for tracking 20120314*/
+0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/
+0xb900,
+/* PAGE 22 END*/
+
+/* PAGE 48 (MiPi 1600x1200)*/
+0x0300,
+
+/* PLL Setting */
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+/* MIPI TX Setting */
+0x0348,
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0e,
+0x1e07,
+0x1f08,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+/*0x3601,*/
+/*0x3707,*/
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_SmartStay_Init_Reg[] = {
+/*0 Page*/
+0x0300,
+0x0101, /*sleep*/
+0x0103, /*s/w reset*/
+0x0101, /*sleep*/
+
+0x0800,/*Don't touch*/
+0x0937,/*Don't touch*/
+0x0a33,/*Don't touch*/
+
+/*PLL Setting*/
+0xd005,
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x1011,
+0x1190, /*xy flip*/
+0x1200,
+0x1488,
+
+0x0300,
+0x2000,
+0x2104,
+0x2200,
+0x2304,
+0x2403,
+0x25C0,
+0x2605,
+0x2700,
+
+0x4001, /*Hblank_280*/
+0x4118,
+0x4201, /*Vblank 400*/
+0x4390,
+
+/*--------------- BLC*/
+0x8008, /*Don't touch */
+0x8197, /*Don't touch */
+0x8290, /*Don't touch */
+0x8330, /*Don't touch */
+0x84cc, /*Don't touch*/
+0x8500, /*Don't touch*/
+0x86d4, /*Don' t touch*/
+0x870f, /*Don't touch*/
+0x8834, /*Don't touch*/
+
+0x900c, /*BLC_TIME_TH_ON*/
+0x910c, /*BLC_TIME_TH_OFF */
+0x92f7, /*BLC_AG_TH_ON*/
+0x93ef, /*BLC_AG_TH_OFF*/
+
+0x9495, /*091202*/
+0x9590, /*091202 */
+0x9838, /*Don't touch*/
+
+/*Dark BLC*/
+0xa000, /* 20100309*/
+0xa200, /* 20100309*/
+0xa400, /* 20100309*/
+0xa600, /* 20100309*/
+
+/*Normal BLC*/
+0xa800,
+0xaa00,
+0xac00,
+0xae00,
+
+/*Out BLC*/
+0x9900,
+0x9a00,
+0x9b00,
+0x9c00,
+
+/*2 Page*/
+0x0302,
+0x1200, /*Don't touch*/
+0x1400, /*Don't touch*/
+0x1500, /*Don't touch*/
+0x184C, /*Don't touch*/
+0x1900, /*Don't touch*/
+0x1A39, /*Don't touch*/
+0x1B00,/*Don't touch*/
+0x1C1a, /*Don't touch*/
+0x1D14, /*Don't touch*/
+0x1E30,/*Don't touch*/
+0x1F10,/*Don't touch*/
+
+0x2077,
+0x21de,
+0x22a7,
+0x2330,
+0x2477,
+0x2510,
+0x2610,
+0x273c,
+0x2b80,
+0x2c02,
+0x2da0,
+0x2e00,
+0x2fa7,
+
+0x3000,
+0x3199,
+0x3200,
+0x3300,
+0x3422,
+0x3601,
+0x3701,
+0x3888,
+0x3988,
+0x3d03,
+0x3e0d,
+0x3f02,
+
+0x49d1,
+0x4a14,
+
+0x5021,
+0x5201,
+0x5381,
+0x5410,
+0x551c,
+0x5611,
+0x5818,
+0x5916,
+0x5da2,
+0x5e5a,
+
+0x6093, /* 20120517 modify*/
+0x61a4, /* 20120517 modify*/
+0x6294, /* 20120517 modify*/
+0x63a3, /* 20120517 modify*/
+0x6494, /* 20120517 modify*/
+0x65a3, /* 20120517 modify*/
+0x670c,
+0x680c,
+0x690c,
+0x6ab4,
+0x6bc4,
+0x6cb5,
+0x6dc2,
+0x6eb5,
+0x6fc0,
+
+0x70b6,
+0x71b8,
+0x7295, /* 20120517 modify*/
+0x73a2, /* 20120517 modify*/
+0x7495, /* 20120517 modify*/
+0x75a2, /* 20120517 modify*/
+0x7695, /* 20120517 modify*/
+0x77a2, /* 20120517 modify*/
+0x7C92, /* 20120517 modify*/
+0x7Dff, /* 20120517 modify*/
+
+0x8001, /* 20120517 modify*/
+0x818a, /* 20120517 modify*/
+0x821e, /* 20120517 modify*/
+0x8336, /* 20120517 modify*/
+0x8489, /* 20120517 modify*/
+0x858b, /* 20120517 modify*/
+0x8689, /* 20120517 modify*/
+0x878b, /* 20120517 modify*/
+0x88ab,
+0x89bc,
+0x8aac,
+0x8bba,
+0x8cad,
+0x8db8,
+0x8eae,
+0x8fb2,
+
+0x90b3,
+0x91b7,
+0x9252, /* 20120517 modify*/
+0x936a, /* 20120517 modify*/
+0x9489, /* 20120517 modify*/
+0x958b, /* 20120517 modify*/
+0x9689, /* 20120517 modify*/
+0x978b, /* 20120517 modify*/
+
+0xA002,
+0xA186, /* 20120517 modify*/
+0xA202,
+0xA386, /* 20120517 modify*/
+0xA486, /* 20120517 modify*/
+0xA502,
+0xA686, /* 20120517 modify*/
+0xA702,
+0xA892, /* 20120517 modify*/
+0xA994, /* 20120517 modify*/
+0xAA92, /* 20120517 modify*/
+0xAB94, /* 20120517 modify*/
+0xAC1c,
+0xAD22,
+0xAE1c,
+0xAF22,
+
+0xB0a4, /* 20120517 modify*/
+0xB1ae, /* 20120517 modify*/
+0xB2a4, /* 20120517 modify*/
+0xB3ae, /* 20120517 modify*/
+0xB4a6, /* 20120517 modify*/
+0xB5ac, /* 20120517 modify*/
+0xB6a6, /* 20120517 modify*/
+0xB7ac, /* 20120517 modify*/
+0xB8a6, /* 20120517 modify*/
+0xB9ab, /* 20120517 modify*/
+0xBAa6, /* 20120517 modify*/
+0xBBab, /* 20120517 modify*/
+0xBCa6, /* 20120517 modify*/
+0xBDab, /* 20120517 modify*/
+0xBEa6, /* 20120517 modify*/
+0xBFab, /* 20120517 modify*/
+
+0xc437,
+0xc552,
+0xc66b,
+0xc786,
+0xc838, /* 20120517 modify*/
+0xc950, /* 20120517 modify*/
+0xca38, /* 20120517 modify*/
+0xcb50, /* 20120517 modify*/
+0xcc6c, /* 20120517 modify*/
+0xcd84, /* 20120517 modify*/
+0xce6c, /* 20120517 modify*/
+0xcf84, /* 20120517 modify*/
+
+/*0xd4a6,*/
+/*0xd5ac,*/
+/*0xd6a6,*/
+/*0xd7ac,*/
+/*add 20120517*/
+0xdc00, /* Added*/
+0xddaf, /* Added*/
+0xde00, /* Added*/
+0xdf90, /* Added*/
+
+0xd010,
+0xd114,
+0xd220,
+0xd300,
+/*DCDC */
+0xd40c, /*DCDC_TIME_TH_ON*/
+0xd50c, /*DCDC_TIME_TH_OFF */
+0xd6f7, /*DCDC_AG_TH_ON*/
+0xd7ef, /*DCDC_AG_TH_OFF*/
+
+0xea8a,
+
+0xF001, /* clock inversion*/
+0xF101,
+0xF201,
+0xF301,
+0xF401,
+0xF500,
+
+/*----------------------------------------------*/
+0x0310, /*page 10*/
+0x1001, /*Ycbcr422_bit Order: YUYV*/
+0x1103,
+0x1230, /*y offset[4], dif_offset[5]*/
+0x1302, /*contrast effet enable : 0x02*/
+0x3400, /*hidden 10->00 100209*/
+0x3701, /*yc2d power save */
+0x3f04, /*100825*/
+0x4080, /*Y offset */
+0x4128,
+0x4880,
+0x5300, /*dif_offset option */
+0x5530, /*dif_offset option diff_offset max */
+
+0x606b, /*out color sat en[7] | auto color decrement en[1] /
+ | manual color sat en[0]*/
+
+0x6183, /*blue saturation_C0*/
+0x6280, /*red saturation_B0*/
+
+0x63b0, /*auto decresment on AG th*/
+0x64ff, /*auto decresment on DG th*/
+0x66e4, /*Outdoor saturation step 137fps apply out th */
+0x6700, /*Outdoor saturation B/R*/
+0x7601, /* ADD 20121031 */
+0x7904, /* ADD 20121031 */
+
+/* Hi 163 */
+/* PAGE 10 START*/
+0x0310,
+0x8000, /* dsshin --> color enhance*/
+0xf500, /* dsshin --> h blank option*/
+
+0x0311, /*page 11 D_LPF */
+0x103f, /*B[6]:Blue En Dlpf on[4:0] Sky over off : 0x7f->3f*/
+0x1120, /* Uniform Full GbGr/OV-Nr*/
+
+0x1280, /*Blue MaxOpt blue sky max filter optoin rate : 0 0xc0->80*/
+0x13b8, /*dark2[7] | ratio[6:4] | dark3[3] | dark3 maxfilter ratio[2:0] */
+
+0x30ba, /*Outdoor2 H th*/
+0x3110, /*Outdoor2 L th*/
+0x3250, /*Outdoor2 gain ratio*/
+0x331d, /*Outdoor2 H lum*/
+0x3420, /*Outdoor2 M lum*/
+0x351f, /*Outdoor2 L lum*/
+
+0x36b0, /*Outdoor1 H th*/
+0x3718, /*Outdoor1 L th*/
+0x3850, /*Outdoor1 gain ratio 0x80->40*/
+0x391d, /*Outdoor1 H lum 0x28->1e*/
+0x3a20, /*Outdoor1 M lum 0x10->15*/
+0x3b1f, /*Outdoor1 L lum 0x08->20*/
+
+0x3c3f, /*indoor H th*/
+0x3d16, /*indoor L th*/
+0x3e30, /*indoor gain ratio 0x44 6a */
+0x3f1a, /*indoor H lum 0x12 18 */
+0x4060, /*indoor M lum 0x18 1c*/
+0x411a, /*indoor L lum 0x18 3e*/
+
+0x4280, /*dark1 H th*/
+0x4318, /*dark1 L th*/
+0x4480, /*dark1 gain ratio*/
+0x450f, /*dark1 H lum 0x38->0x28 */
+0x460c, /*dark1 M lum 0x27->0x17*/
+0x470b, /*dark1 L lum 0x20->0x1a */
+
+0x4880, /*dark2 H th*/
+0x4918, /*dark2 L th*/
+0x4a80, /*dark2 gain ratio*/
+0x4b0f, /*dark2 H lum */
+0x4c0c, /*dark2 M lum*/
+0x4d0b, /*dark2 L lum */
+
+0x4e80, /*dark3 H th*/
+0x4f23, /*dark3 L th*/
+0x5080, /*dark3 gain ratio*/
+0x511d, /*dark3 H lum */
+0x521f, /*dark3 M lum */
+0x531f, /*dark3 L lum */
+
+0x5a3f, /*blue sky mode out1/2 enable 0x27->3f */
+0x5b00, /*Impulse pixel enable dark123,in,out123 :: must be 0x07*/
+0x5c9f, /*Indoor maxfilter rate[7:5] | Uncertain onoff[4:0] 0x1f ->0x9f*/
+
+0x603f, /*GbGr all enable*/
+0x620f, /*GbGr offset*/
+
+0x650c, /*Outdoor GbGr rate H 100% M 25% L 100%*/
+0x660c, /*Indoor GbGr rate H 100% M 25% L 100%*/
+0x6700, /*dark GbGr rate H/M/L 100%*/
+
+0x700c, /* Abberation On/Off B[1]: Outdoor B[0]: Indoor 07>>c*/
+0x75a0, /* Outdoor2 Abberation Luminance lvl */
+0x7db4, /* Indoor Abberation Luminance lvl*/
+
+0x9608, /*indoor/Dark1 edgeoffset1*/
+0x9714, /*indoor/Dark1 center G value*/
+0x98f5, /*slope indoor :: left/right graph polarity, slope*/
+0x992a, /*indoor uncertain ratio control*/
+0x9a20, /*Edgeoffset_dark*/
+
+/*DPC_CTRL*/
+0x0312, /*Preview DPC off[0x5c] on[0x5d]*/
+0x200f,
+0x210f,
+
+0x2500, /* 0x30*/
+
+0x2a01,
+0x2e00, /*2010.8.25*/
+
+0x3035, /*Texture region(most detail)*/
+0x31a0, /*STD uniform1 most blur region*/
+0x32b0, /*STD uniform2 2nd blur*/
+0x33c0, /*STD uniform3 3rd blur*/
+0x34d0, /*STD normal noise1 4th blur */
+0x35e0, /*STD normal noise2 5th blur*/
+0x36ff, /*STD normal noise3 6th blur*/
+
+0x4083, /*Outdoor2 H th*/
+0x4120, /*Outdoor2 L th */
+0x4208, /*Outdoor2 H luminance */
+0x4310, /*Outdoor2 M luminance */
+0x4410, /*Outdoor2 l luminance */
+0x4550, /*Outdoor2 ratio*/
+
+0x4683, /*Outdoor1 H th*/
+0x4720, /*Outdoor1 L th */
+0x4808, /*Outdoor1 H luminance*/
+0x4910, /*Outdoor1 M luminance*/
+0x4a10, /*Outdoor1 L luminance*/
+0x4b50, /*Outdoor1 ratio*/
+
+0x4c80, /*Indoor H th*/
+0x4d48, /*Indoor L th*/
+0x4e30, /*indoor H lum*/
+0x4f30, /*indoor M lum*/
+0x5012, /*indoor L lum */
+0x5170, /*indoor ratio 0x10 -> 0x45*/
+
+0x52a8, /*dark1 H th*/
+0x5330, /*dark1 L th */
+0x5428, /*dark1 H lum */
+0x553e, /*dark1 M lum*/
+0x5667, /*dark1 L lum*/
+0x576a, /*dark1 ratio*/
+
+0x58a0, /*dark2 H th*/
+0x5940, /*dark2 L th*/
+0x5a28, /*dark2 H lum*/
+0x5b3f, /*dark2 M lum*/
+0x5c68, /*dark2 L lum*/
+0x5d70, /*dark2 ratio*/
+
+0x5ea0, /*dark3 H th*/
+0x5f1c, /*dark3 L th*/
+0x6029, /*dark3 H lum*/
+0x614a, /*dark3 M lum*/
+0x62ff, /*dark3 L lum*/
+0x63ff, /*dark3 ratio*/
+
+/*C-filter(Out2&Out1)*/
+0x7010,
+0x710a,
+
+/*C-filter(Indoor&Dark3)*/
+0x7210,
+0x730a,
+
+/*C-filter(Dark2&Dark1)*/
+0x7418,
+0x7512,
+
+0x8020,
+0x8140,
+0x8265,
+0x851a,
+0x8800,
+0x8900,
+0x905d, /*Preview DPC off[0x5c] on[0x5d]*/
+
+/*DPC-Dark1,2,3*/
+0xad07, /*10825*/
+0xae07, /*10825*/
+0xaf07, /*10825*/
+
+/*Blue Det..*/
+0xc558, /*BlueRange 2010.8.25 0x40->23 */
+0xc620, /*GreenRange 2010.8.25 0x3b->20 */
+
+0xd088, /*2010.8.25*/
+0xd180,
+0xd217,/*preview 17, full 67*/
+0xd300,
+0xd400,
+0xd50f,/*preview 0f, full 02*/
+0xd6ff,
+0xd7ff,/*preview ff, full 18*/
+0xd800,
+0xd904,
+
+/*interpolated with average*/
+0xdb38, /*resolution issue 0x00->0x18->0x38 */
+0xd904, /*strong_edge detect ratio*/
+0xe001, /*strong_edge detect ratio*/
+
+0x0313, /*page 13 sharpness 1D*/
+0x10c5,
+0x117b,
+0x120e,
+0x1400,
+
+0x1511, /*added option 1.3M*/
+0x1830, /*added option 1.3M*/
+
+0x2015,
+0x2113,
+0x2233,
+0x2308, /*hi_clip th1*/
+0x241a, /*hi_clip th2*/
+0x2506, /*low clip th*/
+
+0x2618,
+0x2730,
+0x2910, /*time th*/
+0x2a30, /*pga th*/
+
+0x2b03, /*lpf out2*/
+0x2c03, /*lpf out1*/
+0x2d0c,
+0x2e12,
+0x2f12,
+
+/*1D Edge*/
+0x500a, /*out2 hi nega*/
+0x5307, /* hi pos*/
+0x510c, /* mi nega*/
+0x5407, /* mi pos*/
+0x520b, /* lo nega*/
+0x5508, /* lo pos*/
+
+0x560a, /*out1 hi nega*/
+0x5907, /* hi pos */
+0x570c, /* mi nega*/
+0x5a07, /* mi pos */
+0x580b, /* lo nega*/
+0x5b08, /* lo pos */
+
+/*Indoor Edge*/
+0x5c08, /*indoor hi nega*/
+0x5f07, /* hi pos*/
+0x5d14,
+0x6012,
+0x5e0a,
+0x6108, /* low pos*/
+
+0x6208, /*dark1 hi nega*/
+0x6506, /* hi pos */
+0x6308, /* mid nega */
+0x6606, /* mid pos */
+0x6408, /* low nega */
+0x6706, /* low pos */
+
+0x6807, /*dark2 hi nega*/
+0x6b05, /* hi pos */
+0x6907, /* mid nega */
+0x6c05, /* mid pos */
+0x6a07, /* low nega */
+0x6d05, /* low pos */
+
+0x6e0a, /*dark3 hi nega*/
+0x7109, /* hi pos */
+0x6f0d, /* mid nega */
+0x720c, /* mid pos */
+0x700d, /* low nega */
+0x730c, /* low pos */
+
+ /* 2DY*/
+0x80c1,
+0x811f,
+0x82e1,
+0x8333,
+
+0x9005,
+0x9105,
+0x9233,
+0x9330,
+0x9403,
+0x9514,
+0x9730,
+0x9930,
+
+0xa002, /*2d lclp out2 nega*/
+0xa103, /*2d lclp out2 pos*/
+0xa202, /*2d lclp out1 nega*/
+0xa303, /*2d lclp out1 pos*/
+0xa403, /*2d lclp in nega*/
+0xa504, /*2d lclp in pos*/
+0xa607, /*2d lclp dark1 nega*/
+0xa708, /*2d lclp dark1 pos*/
+0xa807, /*2d lclp dark2 nega*/
+0xa908, /*2d lclp dark2 pos*/
+0xaa07, /*2d lclp dark3 nega*/
+0xab08, /*2d lclp dark3 pos*/
+
+0xb010, /*out2 H Ne*/
+0xb310, /* H Po*/
+0xb11e, /* M Ne*/
+0xb41e, /* M Po*/
+0xb21f, /* L Ne*/
+0xb51e, /* L Po*/
+
+0xb610, /*out1 H Ne */
+0xb910, /* H Po */
+0xb71e, /* M Ne */
+0xba1e, /* M Po */
+0xb81f, /* L Ne */
+0xbb1e, /* L Po */
+
+0xbc20, /*indoor H Ne*/
+0xbf1e, /* H Po*/
+0xbd25, /* M Ne*/
+0xc023, /* M Po*/
+0xbe24, /* L Ne*/
+0xc122, /* L Po*/
+
+0xc223, /*dark1 H Ne*/
+0xc523, /* H Po*/
+0xc329, /* M Ne*/
+0xc629, /* M Po*/
+0xc425, /* L Ne*/
+0xc725, /* L Po*/
+
+0xc81c, /*dark2 H Ne*/
+0xcb1c, /* H Po*/
+0xc925, /* M Ne*/
+0xcc25, /* M Po*/
+0xca23, /* L Ne*/
+0xcd23, /* L Po*/
+
+0xce1c, /*dark3 H Ne*/
+0xd11c, /* H Po*/
+0xcf29, /* M Ne*/
+0xd229, /* M Po*/
+0xd027, /* L Ne*/
+0xd327, /* L Po*/
+
+/* PAGE 14 START*/
+0x0314,
+0x1031,
+
+0x1480, /* GX*/
+0x1580, /* GY*/
+0x1680, /* RX*/
+0x1780, /* RY*/
+0x1880, /* BX*/
+0x1980, /* BY*/
+
+0x2060, /* X Center*/
+0x2180, /* Y Center*/
+
+0x2280,
+0x2380,
+0x2480,
+
+0x30c8,
+0x312b,
+0x3200,
+0x3300,
+0x3490,
+
+0x4056, /*R min's set 4e*/
+0x413a, /*Gr*/
+0x4237, /*B*/
+0x433a, /*Gb*/
+
+0x0315,
+0x1021,
+0x1444, /*49*/
+0x1534, /*38*/
+0x1626, /*2b*/
+0x172f,
+
+0x30dd,
+0x3162,
+0x3205,
+0x3326,
+0x34bd,
+0x3517,
+0x3618,
+0x3738,
+0x38d0,
+
+0x40b0,
+0x4130,
+0x4200,
+0x4300,
+0x4400,
+0x4500,
+0x4699,
+0x4719,
+0x4800,
+
+0x5016,
+0x51b2,
+0x521c,
+0x5306,
+0x5420,
+0x55a6,
+0x560e,
+0x57b2,
+0x5824,
+
+0x0316,
+0x1031, /*GMA_CTL*/
+0x187e, /*AG_ON*/
+0x197d, /*AG_OFF*/
+0x1a0e, /*TIME_ON*/
+0x1b01, /*TIME_OFF*/
+0x1Cdc, /*OUT_ON*/
+0x1Dfe, /*OUT_OFF*/
+
+/*GMA Indoor*/
+0x3000,
+0x3126,
+0x3238,
+0x3355,
+0x347e,
+0x3597,
+0x36a9,
+0x37ba,
+0x38c7,
+0x39d2,
+0x3adb,
+0x3be3,
+0x3cea,
+0x3dee,
+0x3ef5,
+0x3ff9,
+0x40fc,
+0x41fe,
+0x42ff,
+
+/*RGMA Outdoor*/
+0x5000,
+0x5126,
+0x5238,
+0x5355,
+0x547e,
+0x5597,
+0x56a9,
+0x57ba,
+0x58c7,
+0x59d2,
+0x5adb,
+0x5be3,
+0x5cea,
+0x5dee,
+0x5ef5,
+0x5ff9,
+0x60fc,
+0x61fe,
+0x62ff,
+
+/*BGMA Dark*/
+0x7002,
+0x712a,
+0x723b,
+0x7359,
+0x7481,
+0x759b,
+0x76ac,
+0x77be,
+0x78ca,
+0x79d4,
+0x7adb,
+0x7be4,
+0x7ceb,
+0x7def,
+0x7ef6,
+0x7ffa,
+0x80fc,
+0x81fe,
+0x82ff,
+
+0x0324, /*Resol control */
+0x60c5, /*edge even frame | 16bit resol | white edge cnt | scene resol enable*/
+0x6104, /*even frame update */
+0x6408,
+0x6500,
+0x6626, /*edge th2 H */
+0x6700, /*edge th2 L */
+
+0x0313,
+0x1831, /*flat center Gb/Gr*/
+0x7402, /*det slope en | gausian filter*/
+0x750d, /*1D negative gain det 09 */
+0x760d, /*1D postive gain det 08*/
+0x7710, /*1D hclp2 det*/
+0x7808, /*outdoor flat threshold*/
+0x7910, /*indoor flat threshold*/
+
+0x81df, /*det gain controler*/
+0x8690, /*2D negative gain det */
+0x8790, /*2D postive gain det */
+0x962a, /*2D hclp2 det*/
+
+0x0312, /*0x12 page*/
+0xd088,
+0xd9e4,
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+/* PAGE 20 START*/
+0x0320,
+0x111c,
+0x1830,
+0x1a08,
+0x2045,/*weight*/
+0x2130,
+0x2210,
+0x2300,
+0x2400,
+
+0x28e7, /* add 20120223*/
+0x290d, /* 20100305 ad -> 0d*/
+0x2afd,
+0x2bf8,
+
+0x2cc3,
+0x2d5f, /* add 20120223*/
+0x2e33,
+0x30f8,
+0x3203,
+0x332e,
+0x3430,
+0x35d4,
+0x36ff, /*fe*/
+0x3732,
+0x3804,
+0x3922,
+0x3ade,
+0x3b22,
+0x3cde,
+0x3de1,
+
+0x5045,
+0x5188,
+
+0x561a,
+0x5780,
+0x580e,
+0x596a,
+0x5a04,
+
+0x5e9d, /*AE_AWB_start*/
+0x5f76, /*AE_AWB_start*/
+
+0x703f, /* 6c*/
+0x7180, /* 82(+8)*/
+
+0x7621,
+0x7781,
+0x7822, /* 24*/
+0x7925, /* Y Target 70 => 25, 72 => 26*/
+0x7a23, /* 23*/
+0x7b22, /* 22*/
+0x7d23,
+
+0x8301, /*EXP Normal 30.00 fps */
+0x845f,
+0x8590,
+0x8601, /*EXPMin 7500.00 fps*/
+0x8790,
+0x8805, /*EXP Max(120Hz) 8.00 fps */
+0x89b8,
+0x8ad8,
+0xa505, /*EXP Max(100Hz) 8.33 fps */
+0xa67e,
+0xa740,
+0x8B75, /*EXP100 */
+0x8C30,
+0x8D61, /*EXP120 */
+0x8Ea8,
+0x9c09, /*EXP Limit 1250.00 fps */
+0x9d60,
+0x9e01, /*EXP Unit */
+0x9f90,
+0x989d,
+
+0xb016,
+0xb114,
+0xb2f0,
+0xb314,
+0xb41b,
+0xb546,
+0xb631,
+0xb729,
+0xb826,
+0xb924,
+0xba22,
+0xbb42,
+0xbc41,
+0xbd40,
+
+0xc010,
+0xc138,
+0xc238,
+0xc338,
+0xc407,
+
+0xc880,
+0xc980,
+0x109c, /* ae enable*/
+/* PAGE 20 END*/
+
+/*AE_Weight*/
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2422,
+0x2522,
+0x2622,
+0x2721,
+0x2823,
+0x2933,
+0x2a32,
+0x2b21,
+0x2c23,
+0x2d44,
+0x2e32,
+0x2f21,
+0x3023,
+0x3144,
+0x3232,
+0x3311,
+0x3423,
+0x3533,
+0x3632,
+0x3721,
+0x3822,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+
+/* PAGE 22 START*/
+0x0322,
+0x10fd,
+0x112e,
+0x1901, /* Low On*/
+0x2030, /* for wb speed*/
+0x2140,
+0x2401,
+0x257e, /* for tracking 20120314 */
+
+0x3080, /* 20120224 test*/
+0x3180,
+0x3811,
+0x3934,
+
+0x40e8,
+0x4143, /* 33*/
+0x4222, /* 22*/
+
+0x43f3, /* f6*/
+0x4454, /* 44*/
+0x4522, /* 33*/
+
+0x4600,
+0x480a,
+0x50b2,
+0x5181,
+0x5298,
+
+0x8038,
+0x8120,
+0x8238, /* 3a*/
+
+0x8356, /* R Max*/
+0x8420, /* R Min*/
+0x8552, /* B Max*/
+0x8620, /* B Min*/
+
+0x8746,
+0x8836,
+0x8939,
+0x8a2d,
+
+0x8b3c,
+0x8c36,
+0x8d34,
+0x8e31,
+
+0x8f5a,
+0x9059,
+0x9154,
+0x924d,
+0x9342,
+0x943a,
+0x9534,
+0x962c,
+0x9723,
+0x9820,
+0x991f,
+0x9a1f,
+
+0x9b77,
+0x9c77,
+0x9d48,
+0x9e38,
+0x9f30,
+
+0xa040,
+0xa122,
+0xa26f,
+0xa3ff,
+
+0xa414, /* 1500fps*/
+0xa544, /* 700fps*/
+0xa6cf,
+
+0xad40,
+0xae4a,
+
+0xaf2a, /* low temp Rgain*/
+0xb028, /* low temp Rgain*/
+
+0xb100, /* 0x20 -> 0x00 0405 modify*/
+0xb4bf, /* for tracking 20120314*/
+0xb8a1, /* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify*/
+0xb900,
+/* PAGE 22 END*/
+
+/* PAGE 48 (MiPi 1600x1200)*/
+0x0300,
+
+/* PLL Setting */
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0e,
+0x1e07,
+0x1f08,
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2b40,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_stop_stream[] = {
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t SR130PC20_Preview_Mode[] =
+{
+0x0300,
+0x0101,/*sleep*/
+
+0xd005,/*Pll Off*/
+
+0x0320,
+0x101c,/*AE off (0x0c:60Hz 0x1c:50Hz)*/
+0x0322,
+0x107d,/*AWB off*/
+
+0x0300,
+0x1011,
+/* 0x1190, *//*0x91 : mirror mode*/
+
+/* page 11 yc_lpf */
+0x0311,
+0x5b00,/*don't touch*/
+
+/* PAGE 12 YC_LPF */
+0x0312,
+0x200f,
+0x210f,
+
+/*preview DPC*/
+0xd217,
+0xd50f,
+0xd7ff,
+
+
+/* PAGE13 Sharpness 1D/2D */
+0x0313,
+0x10c4,
+0x80c0,
+
+/* PAGE 18 START*/
+0x0318,
+0x1443, /*83*/
+
+0x0320,
+0x109c, /*AE ON (0x8c:60Hz 0x9c:50Hz)*/
+0x0322,
+0x10fd, /*AWB ON*/
+
+0x0300, /*Page 0 PLL on*/
+0xd005,
+0xd130,
+0xd205,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+/* MIPI TX Setting */
+0x0348,
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+/*0x1d09,*/
+0x1d0e,
+0x1e07,
+0x1f08,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x3005,
+0x3100,
+
+0x3207,
+0x3309,
+0x3401,
+0x3501,
+/*0x3601,*/
+/*0x3707,*/
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0100,
+
+};
+
+static const sr130pc20_regset_t SR130PC20_Capture_Mode[] =
+{
+0x0300,
+0x0101,/*sleep*/
+
+0xd005,/*Pll off*/
+
+0x0322,
+0x107d,/*AWB off*/
+
+0x0300,
+0x1000,
+/* 0x1190, */
+
+0x0302,
+0x2faa,
+
+0x0311,
+0x5b00,/*don't touch*/
+
+0x0312,
+0x200f,
+0x210f,
+
+/*preview DPC*/
+0xd267,
+0xd502,
+0xd718,
+
+0x0313,
+0x10c5,
+0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+0x0300,
+0xd005,/*pll on*/
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0d, /* 0c:90ns , 0b:110ns */
+0x1e0f,
+0x1f0a,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x300a,
+0x3100,
+
+0x320d,
+0x330b,
+0x3402,
+0x3504,
+0x3601,
+0x3709,
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0100,/*sleep off*/
+
+};
+
+static const sr130pc20_regset_t SR130PC20_Lowlux_Night_Capture_Mode[] =
+{
+0x0300,
+0x0101,/*sleep*/
+
+0xd005,/*Pll off*/
+
+0x0322,
+0x107d,/*AWB off*/
+
+0x0300,
+0x1000,
+/* 0x1190, */
+
+0x0302,
+0x2faa,
+
+0x0311,
+0x5b00,/*don't touch*/
+
+0x0312,
+0x200f,
+0x210f,
+
+/*preview DPC*/
+0xd267,
+0xd502,
+0xd718,
+
+0x0313,
+0x10c5,
+0x80c1,/*Sharpness 2D On[0xc1] Off[0xc0]*/
+
+/* PAGE 18 START*/
+0x0318,
+0x1400,
+
+0x0300,
+0xd005,/*pll on*/
+0xd130,
+0xd201,
+0xd320,
+0xd085,
+0xd085,
+0xd085,
+0xd095,
+
+0x0348,
+/* MIPI TX Setting */
+0x101c,
+0x1100,
+0x1200,
+0x1400,
+0x1604,
+0x1700,
+0x1880,
+0x1900,
+0x1aa0,
+/*0x1b0d,*/
+0x1c02,
+0x1d0d, /* 0c:90ns , 0b:110ns */
+0x1e0f,
+0x1f0a,
+/*0x2000,*/
+
+0x2200,
+0x2301,
+0x241e,
+0x2500,
+0x2600,
+0x2708,
+0x2800,
+/*0x2a06,*/
+/*0x2b40,*/
+/*0x2c04,*/
+/*0x2db0,*/
+
+0x300a,
+0x3100,
+
+0x320d,
+0x330b,
+0x3402,
+0x3504,
+0x3601,
+0x3709,
+/*0x3802,*/
+/*0x3902,*/
+
+0x0300,
+0x0100,/*sleep off*/
+
+0xff03,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Sketch[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Pastel[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Black_White[] =
+{
+0x0310,
+0x1103,
+0x1233,
+0x1302,
+0x4080,
+0x4480,
+0x4580,
+};
+
+static const sr130pc20_regset_t SR130PC20_Effect_Negative[] =
+{
+0x0310,
+0x1103,
+0x1238,
+0x1302,
+0x4080,
+0x4480,
+0x4580,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Solar[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Normal[] =
+{
+0x0310,
+0x1103,
+0x1230,
+0x1302,
+0x4080,
+0x4480,
+0x4580,
+};
+
+static const sr130pc20_regset_t sr130pc20_Effect_Sepia[] =
+{
+0x0310,
+0x1103,
+0x1233,
+0x1302,
+0x4080,
+0x4470,
+0x4598,
+};
+
+static const sr130pc20_regset_t sr130pc20_Metering_Center[] =
+{
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2412,
+0x2522,
+0x2622,
+0x2721,
+0x2812,
+0x2922,
+0x2a22,
+0x2b21,
+0x2c12,
+0x2d23,
+0x2e32,
+0x2f21,
+0x3012,
+0x3123,
+0x3232,
+0x3321,
+0x3412,
+0x3522,
+0x3622,
+0x3721,
+0x3812,
+0x3922,
+0x3a22,
+0x3b21,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+};
+
+static const sr130pc20_regset_t sr130pc20_Metering_Matrix[] =
+{
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2411,
+0x2511,
+0x2611,
+0x2711,
+0x2811,
+0x2911,
+0x2a11,
+0x2b11,
+0x2c11,
+0x2d11,
+0x2e11,
+0x2f11,
+0x3011,
+0x3111,
+0x3211,
+0x3311,
+0x3411,
+0x3511,
+0x3611,
+0x3711,
+0x3811,
+0x3911,
+0x3a11,
+0x3b11,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+};
+
+static const sr130pc20_regset_t sr130pc20_Metering_Spot[] =
+{
+0x0321,
+0x2011,
+0x2111,
+0x2211,
+0x2311,
+0x2411,
+0x2511,
+0x2611,
+0x2711,
+0x2811,
+0x2911,
+0x2a11,
+0x2b11,
+0x2c11,
+0x2d13,
+0x2e31,
+0x2f11,
+0x3011,
+0x3113,
+0x3231,
+0x3311,
+0x3411,
+0x3511,
+0x3611,
+0x3711,
+0x3811,
+0x3911,
+0x3a11,
+0x3b11,
+0x3c11,
+0x3d11,
+0x3e11,
+0x3f11,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_Default[] =
+{
+0x0310,
+0x4080,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M1Step[] =
+{
+0x0310,
+0x4090,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M2Step[] =
+{
+0x0310,
+0x40A0,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M3Step[] =
+{
+0x0310,
+0x40B0,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_M4Step[] =
+{
+0x0310,
+0x40d0,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P1Step[] =
+{
+0x0310,
+0x4010,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P2Step[] =
+{
+0x0310,
+0x4020,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P3Step[] =
+{
+0x0310,
+0x4030,
+};
+
+static const sr130pc20_regset_t SR130PC20_ExpSetting_P4Step[] =
+{
+0x0310,
+0x4050,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_50[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_100[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_200[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_400[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_ISO_Auto[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Default[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Landscape[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Sports[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Party_Indoor[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Beach_Snow[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Sunset[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Duskdawn[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Candle_Light[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Fall_Color[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Portrait[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Nightshot[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Fireworks[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Text[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Scene_Backlight[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_Sharpness_Default[] =
+{
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Auto[] =
+{
+0x0322,
+0x106b,
+0x112e,
+0x8038,
+0x8120,
+0x8238,
+0x8356,
+0x8420,
+0x8552,
+0x8620,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Cloudy[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8050,
+0x8120,
+0x8228,
+0x8352,
+0x844c,
+0x852c,
+0x8622,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Sunny[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8038,
+0x8120,
+0x8235,
+0x833b,
+0x8434,
+0x8538,
+0x8631,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Fluorescent[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8037,
+0x8120,
+0x8248,
+0x8339,
+0x8434,
+0x854a,
+0x8645,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_WB_Tungsten[] =
+{
+0x0322,
+0x106b,
+0x112c,
+0x8021,
+0x8120,
+0x824f,
+0x8327,
+0x841b,
+0x8559,
+0x8650,
+0x10eb,
+};
+
+static const sr130pc20_regset_t sr130pc20_640_480_Preview[] = {
+0x0300,
+0x0101,
+
+0x0300,
+0x1011,
+
+0x0318,
+0x1000,
+
+0x0348,
+0x3005,
+0x3100,
+
+0x0300,
+0x0100,
+
+0xff0a,
+};
+
+static const sr130pc20_regset_t sr130pc20_352_288_Preview[] = {
+0x0300,
+0x0101,
+0x0300,
+0x1011,
+
+0x0318,
+0x1007,
+0x1200,
+0x2003,
+0x2100,
+0x2201,
+0x2320,
+0x2400,
+0x2520,
+0x2600,
+0x2700,
+0x2802,
+0x29e0,
+0x2a01,
+0x2b20,
+0x2c0d,
+0x2d55,
+0x2e0d,
+0x2f55,
+0x3051,
+
+0x0348,
+0x3002,
+0x31c0,
+
+0x0300,
+0x0100,
+
+0xff28,
+};
+
+static const sr130pc20_regset_t sr130pc20_320_240_Preview[] = {
+0x0300,
+0x0101,
+
+0x0300,
+0x1023,
+
+0x0318,
+0x1000,
+
+0x0348,
+0x3002,
+0x3180,
+
+0x0300,
+0x0100,
+
+0xff28,
+};
+
+static const sr130pc20_regset_t sr130pc20_176_144_Preview[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_1280_960_Capture[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_960_720_Capture[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_VGA_Capture[] = {
+0xff00
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_auto[] = {
+0xff00,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_7fix[] = {
+0x0300,
+0x0101,
+
+0x1190,
+
+0x4200,
+0x4314,
+
+0x0320,
+0x101C,
+
+0x0322,
+0x107d,
+
+0x0320,
+0x2af3,
+0x2bf5,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+
+0x8806, /*EXP Max(120Hz) 7.50 fps */
+0x8968,
+0x8aa0,
+
+0xa506, /*EXP Max(100Hz) 7.14 fps */
+0xa668,
+0xa7a0,
+
+0x9106, /*EXP Fix 7.00 fps*/
+0x9289,
+0x9370,
+
+0x0320,
+0x109C,
+
+0x0322,
+0x10fd,
+
+0x0300,
+0x1194,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_15fix[] = {
+0x0300,
+0x0101,
+
+0x1190,
+
+0x4200,
+0x4314,
+
+0x0320,
+0x101C,
+
+0x0322,
+0x107d,
+
+0x0310, /*page 10*/
+0x6007,
+0x6380, /*auto decresment on AG th*/
+
+0x0316,
+0x7007,
+0x711a,
+0x722d,
+0x7346,
+0x746a,
+0x7586,
+0x769c,
+0x77ad,
+0x78bc,
+0x79c9,
+0x7ad4,
+0x7bde,
+0x7ce4,
+0x7deb,
+0x7ef1,
+0x7ff5,
+0x80f9,
+0x81fd,
+0x82ff,
+
+0x0322,
+0x8f5d,
+0x905a,
+0x9156,
+0x9250,
+0x9348,
+0x943f,
+
+0x0320,
+0x2afd,
+0x2bf8,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845f,
+0x8590,
+
+0x8802, /*EXP Max(120Hz) 17.14 fps */
+0x89bf,
+0x8a20,
+
+0xa502, /*EXP Max(100Hz) 16.67 fps */
+0xa6bf,
+0xa720,
+
+0x9103, /*EXP Fix 15.00 fps*/
+0x920d,
+0x9340,
+
+0x0320,
+0x109C,
+
+0x0322,
+0x10fd,
+
+0x0300,
+0x1194,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_25fix[] = {
+0x0300,
+0x0101,
+
+0x1190,
+
+0x4200,
+0x4362,
+
+0x0320,
+0x101C,
+
+0x0322,
+0x107d,
+
+0x0310, /*page 10*/
+
+0x410a,
+0x6007,
+0x6380, /*auto decresment on AG th*/
+
+0x0316,
+0x7007,
+0x711a,
+0x722d,
+0x7346,
+0x746a,
+0x7586,
+0x769c,
+0x77ad,
+0x78bc,
+0x79c9,
+0x7ad4,
+0x7bde,
+0x7ce4,
+0x7deb,
+0x7ef1,
+0x7ff5,
+0x80f9,
+0x81fd,
+0x82ff,
+
+0x0322,
+0x8f5d,
+0x905a,
+0x9156,
+0x9250,
+0x9348,
+0x943f,
+
+0x0320,
+0x2afd,
+0x2bf8,
+
+0x8301, /*EXP Normal 33.33 fps */
+0x845d,
+0x8538,
+
+0x8801, /*EXP Max(120Hz) 40.00 fps */
+0x895f,
+0x8a90,
+
+0xa501, /*EXP Max(100Hz) 25.xx fps */
+0xa6d1,
+0xa7a0,
+
+0x8b74, /*EXP100 */
+0x8c68,
+0x8d60, /*EXP120 */
+0x8ee0,
+
+0x9101, /*EXP Fix 25.00 fps*/
+0x92d4,
+0x93c0,
+
+0x0320,
+0x109C,
+
+0x0322,
+0x10fd,
+
+0x0300,
+0x1194,
+
+0x0300,
+0x0101,
+};
+
+static const sr130pc20_regset_t sr130pc20_fps_30fix[] =
+{
+/* sensor limitation, use 25fps */
+0xff00,
+};
+
+#endif /* __SR130PC20_REGS_H__ */
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b7291cf..881a9af 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -88,4 +88,5 @@ obj-$(CONFIG_SLP_LOWMEM_NOTIFY) += slp_lowmem_notify.o
obj-$(CONFIG_MACH_M0_CTC) += cw_tty.o
# Secure OS Mobicore Interface
+CFLAGS_tzic.o :=$(call as-instr,.arch_extension sec,-DREQUIRES_SEC=1)
obj-$(CONFIG_MOBICORE_SUPPORT) += tzic.o
diff --git a/drivers/misc/max77693-muic.c b/drivers/misc/max77693-muic.c
index 9a78d76..082777d 100644
--- a/drivers/misc/max77693-muic.c
+++ b/drivers/misc/max77693-muic.c
@@ -473,7 +473,7 @@ static ssize_t max77693_muic_show_manualsw(struct device *dev,
struct max77693_muic_info *info = dev_get_drvdata(dev);
#if !defined(CONFIG_MACH_T0) && !defined(CONFIG_MACH_M3) \
- && !defined(CONFIG_MACH_SLP_T0_LTE)
+ && !defined(CONFIG_MACH_SLP_T0_LTE) && !defined(CONFIG_MACH_KONA)
dev_info(info->dev, "func:%s ap(0),cp(1),vps(2)sw_path:%d(%d)\n",
__func__, info->muic_data->sw_path,
gpio_get_value(GPIO_USB_SEL));/*For debuging*/
@@ -716,7 +716,7 @@ static ssize_t max77693_muic_set_uart_sel(struct device *dev,
if (info->max77693->pmic_rev < MAX77693_REV_PASS2) {
#if !defined(CONFIG_MACH_T0) && !defined(CONFIG_MACH_M3) \
- && !defined(CONFIG_MACH_SLP_T0_LTE)
+ && !defined(CONFIG_MACH_SLP_T0_LTE) && !defined(CONFIG_MACH_KONA)
if (!strncasecmp(buf, "AP", 2)) {
info->muic_data->uart_path = UART_PATH_AP;
if (gpio_is_valid(GPIO_UART_SEL)) {
@@ -845,7 +845,7 @@ static ssize_t max77693_muic_show_uart_sel(struct device *dev,
struct max77693_muic_info *info = dev_get_drvdata(dev);
if (info->max77693->pmic_rev < MAX77693_REV_PASS2) {
#if !defined(CONFIG_MACH_T0) && !defined(CONFIG_MACH_M3) \
- && !defined(CONFIG_MACH_SLP_T0_LTE)
+ && !defined(CONFIG_MACH_SLP_T0_LTE) && !defined(CONFIG_MACH_KONA)
switch (info->muic_data->uart_path) {
case UART_PATH_AP:
if (gpio_get_value(GPIO_UART_SEL) == GPIO_LEVEL_HIGH)
@@ -3112,7 +3112,7 @@ static int uart_switch_init(struct max77693_muic_info *info)
int ret, val;
#if !defined(CONFIG_MACH_T0) && !defined(CONFIG_MACH_M3) \
- && !defined(CONFIG_MACH_SLP_T0_LTE)
+ && !defined(CONFIG_MACH_SLP_T0_LTE) && !defined(CONFIG_MACH_KONA)
if (info->max77693->pmic_rev < MAX77693_REV_PASS2) {
ret = gpio_request(GPIO_UART_SEL, "UART_SEL");
if (ret < 0) {
diff --git a/drivers/misc/tzic.c b/drivers/misc/tzic.c
index e1da409..6a5e3ba 100644
--- a/drivers/misc/tzic.c
+++ b/drivers/misc/tzic.c
@@ -42,7 +42,9 @@ u32 exynos_smc1(u32 cmd, u32 arg1, u32 arg2, u32 arg3)
register u32 reg3 __asm__("r3") = arg3;
__asm__ volatile (
- ".arch_extension sec\n"
+#ifdef REQUIRES_SEC
+ ".arch_extension sec\n"
+#endif
"smc 0\n"
: "+r"(reg0), "+r"(reg1), "+r"(reg2), "+r"(reg3)
);
@@ -65,7 +67,9 @@ int exynos_smc_read_oemflag(u32 ctrl_word, u32 *val)
reg2 = idx;
__asm__ volatile (
+#ifdef REQUIRES_SEC
".arch_extension sec\n"
+#endif
"smc 0\n"
:"+r" (reg0), "+r"(reg1),
"+r"(reg2), "+r"(reg3)
@@ -79,7 +83,9 @@ int exynos_smc_read_oemflag(u32 ctrl_word, u32 *val)
reg2 = idx;
__asm__ volatile (
+#ifdef REQUIRES_SEC
".arch_extension sec\n"
+#endif
"smc 0\n"
:"+r" (reg0), "+r"(reg1), "+r"(reg2),
"+r"(reg3)
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 1c63296..2d55947 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2020,7 +2020,6 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
mq_rq->packed_num -= idx;
#ifdef CONFIG_WIMAX_CMC
if (mq_rq->packed_num == 1) {
- printk(KERN_ERR "SBRISSEN - I AM HERE\n");
mq_rq->packed_cmd = MMC_PACKED_NONE;
mq_rq->packed_num = 0;
}
diff --git a/drivers/motor/isa1200_vibrator.c b/drivers/motor/isa1200_vibrator.c
index 4b26dc3..0f2da51 100644
--- a/drivers/motor/isa1200_vibrator.c
+++ b/drivers/motor/isa1200_vibrator.c
@@ -269,7 +269,7 @@ static void isa1200_vibrator_enable(struct timed_output_dev *_dev, int value)
spin_unlock_irqrestore(&data->lock, flags);
}
-static ssize_t pwm_val_show(struct device *dev,
+static ssize_t pwm_value_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int count;
@@ -277,19 +277,19 @@ static ssize_t pwm_val_show(struct device *dev,
pwm_val = ((isapwm_duty - 500) * 100) / 500;
count = sprintf(buf, "%lu\n", pwm_val);
- pr_debug("[VIB] pwm_val: %lu\n", pwm_val);
+ pr_debug("[VIB] pwm_value: %lu\n", pwm_val);
return count;
}
-ssize_t pwm_val_store(struct device *dev,
+ssize_t pwm_value_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
if (kstrtoul(buf, 0, &pwm_val))
- pr_err("[VIB] %s: error on storing pwm_val\n", __func__);
+ pr_err("[VIB] %s: error on storing pwm_value\n", __func__);
- pr_info("[VIB] %s: pwm_val=%lu\n", __func__, pwm_val);
+ pr_info("[VIB] %s: pwm_value=%lu\n", __func__, pwm_val);
isapwm_duty = (pwm_val * 500) / 100 + 500;
@@ -307,26 +307,8 @@ ssize_t pwm_val_store(struct device *dev,
return size;
}
-static DEVICE_ATTR(pwm_val, S_IRUGO | S_IWUSR,
- pwm_val_show, pwm_val_store);
-
-static int create_vibrator_sysfs(void)
-{
- int ret;
- struct kobject *vibrator_kobj;
- vibrator_kobj = kobject_create_and_add("vibrator", NULL);
- if (unlikely(!vibrator_kobj))
- return -ENOMEM;
-
- ret = sysfs_create_file(vibrator_kobj,
- &dev_attr_pwm_val.attr);
- if (unlikely(ret < 0)) {
- pr_err("[VIB] sysfs_create_file failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
+static DEVICE_ATTR(pwm_value, S_IRUGO | S_IWUSR,
+ pwm_value_show, pwm_value_store);
static int __devinit isa1200_vibrator_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
@@ -373,12 +355,16 @@ static int __devinit isa1200_vibrator_i2c_probe(struct i2c_client *client,
ddata->duty = pdata->duty;
ddata->period = pdata->period;
+ /* User controllable pwm level */
+ ret = device_create_file(ddata->dev.dev, &dev_attr_pwm_value);
+ if (ret < 0) {
+ pr_err("[VIB] create sysfs fail: pwm_value\n");
+ }
+
ddata->dev.name = "vibrator";
ddata->dev.get_time = isa1200_vibrator_get_time;
ddata->dev.enable = isa1200_vibrator_enable;
- create_vibrator_sysfs();
-
hrtimer_init(&ddata->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ddata->timer.function = isa1200_vibrator_timer_func;
INIT_WORK(&ddata->work, isa1200_vibrator_work);
diff --git a/drivers/motor/max77693_haptic.c b/drivers/motor/max77693_haptic.c
index 1836e33..beb7f2a 100644
--- a/drivers/motor/max77693_haptic.c
+++ b/drivers/motor/max77693_haptic.c
@@ -3,7 +3,7 @@
*
* Copyright (C) 2011 ByungChang Cha <bc.cha@samsung.com>
* Copyright (C) 2012 The CyanogenMod Project
- * Daniel Hillenbrand <codeworkx@cyanogenmod.com>
+ * Daniel Hillenbrand <codeworkx@cyanogenmod.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -260,64 +260,46 @@ void vibtonz_pwm(int nForce)
EXPORT_SYMBOL(vibtonz_pwm);
#endif
-static ssize_t pwm_val_show(struct device *dev,
+static ssize_t pwm_value_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int count;
- pwm_val = ((pwm_duty - 18525) * 100) / 18525;
+ pwm_val = ((pwm_duty - 18525) * 100) / 18525;
count = sprintf(buf, "%lu\n", pwm_val);
- pr_debug("[VIB] pwm_val: %lu\n", pwm_val);
+ pr_debug("[VIB] pwm_value: %lu\n", pwm_val);
return count;
}
-ssize_t pwm_val_store(struct device *dev,
+ssize_t pwm_value_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
if (kstrtoul(buf, 0, &pwm_val))
pr_err("[VIB] %s: error on storing pwm_val\n", __func__);
- pr_info("[VIB] %s: pwm_val=%lu\n", __func__, pwm_val);
+ pr_info("[VIB] %s: pwm_value=%lu\n", __func__, pwm_val);
- pwm_duty = (pwm_val * 18525) / 100 + 18525;
+ pwm_duty = (pwm_val * 18525) / 100 + 18525;
- /* make sure new pwm duty is in range */
- if(pwm_duty > 37050)
- {
- pwm_duty = 37050;
- }
- else if (pwm_duty < 18525)
- {
- pwm_duty = 18525;
- }
+ /* make sure new pwm duty is in range */
+ if(pwm_duty > 37050)
+ {
+ pwm_duty = 37050;
+ }
+ else if (pwm_duty < 18525)
+ {
+ pwm_duty = 18525;
+ }
pr_info("[VIB] %s: pwm_duty=%d\n", __func__, pwm_duty);
return size;
}
-static DEVICE_ATTR(pwm_val, S_IRUGO | S_IWUSR,
- pwm_val_show, pwm_val_store);
-
-static int create_vibrator_sysfs(void)
-{
- int ret;
- struct kobject *vibrator_kobj;
- vibrator_kobj = kobject_create_and_add("vibrator", NULL);
- if (unlikely(!vibrator_kobj))
- return -ENOMEM;
-
- ret = sysfs_create_file(vibrator_kobj,
- &dev_attr_pwm_val.attr);
- if (unlikely(ret < 0)) {
- pr_err("[VIB] sysfs_create_file failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
+static DEVICE_ATTR(pwm_value, S_IRUGO | S_IWUSR,
+ pwm_value_show, pwm_value_store);
static int max77693_haptic_probe(struct platform_device *pdev)
{
@@ -381,8 +363,6 @@ static int max77693_haptic_probe(struct platform_device *pdev)
hap_data->tout_dev.get_time = haptic_get_time;
hap_data->tout_dev.enable = haptic_enable;
- create_vibrator_sysfs();
-
#ifdef CONFIG_ANDROID_TIMED_OUTPUT
error = timed_output_dev_register(&hap_data->tout_dev);
if (error < 0) {
@@ -390,8 +370,15 @@ static int max77693_haptic_probe(struct platform_device *pdev)
error = -EFAULT;
goto err_timed_output_register;
}
-#endif
+
pr_err("[VIB] timed_output device is registrated\n");
+
+ /* User controllable pwm level */
+ error = device_create_file(hap_data->tout_dev.dev, &dev_attr_pwm_value);
+ if (error < 0) {
+ pr_err("[VIB] create sysfs fail: pwm_value\n");
+ }
+#endif
pr_debug("[VIB] -- %s\n", __func__);
return error;
diff --git a/drivers/motor/max8997_vibrator.c b/drivers/motor/max8997_vibrator.c
index c3b07f8..827793d 100644
--- a/drivers/motor/max8997_vibrator.c
+++ b/drivers/motor/max8997_vibrator.c
@@ -225,7 +225,7 @@ void vibtonz_pwm(int nForce)
}
EXPORT_SYMBOL(vibtonz_pwm);
-static ssize_t pwm_val_show(struct device *dev,
+static ssize_t pwm_value_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int count;
@@ -233,19 +233,19 @@ static ssize_t pwm_val_show(struct device *dev,
pwm_val = ((pwm_duty - pwm_duty_min) * 100) / pwm_duty_min;
count = sprintf(buf, "%lu\n", pwm_val);
- pr_debug("[VIB] pwm_val: %lu\n", pwm_val);
+ pr_debug("[VIB] pwm_value: %lu\n", pwm_val);
return count;
}
-ssize_t pwm_val_store(struct device *dev,
+ssize_t pwm_value_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
if (kstrtoul(buf, 0, &pwm_val))
- pr_err("[VIB] %s: error on storing pwm_val\n", __func__);
+ pr_err("[VIB] %s: error on storing pwm_value\n", __func__);
- pr_info("[VIB] %s: pwm_val=%lu\n", __func__, pwm_val);
+ pr_info("[VIB] %s: pwm_value=%lu\n", __func__, pwm_val);
pwm_duty = (pwm_val * pwm_duty_min) / 100 + pwm_duty_min;
@@ -261,28 +261,10 @@ ssize_t pwm_val_store(struct device *dev,
return size;
}
-static DEVICE_ATTR(pwm_val, S_IRUGO | S_IWUSR,
- pwm_val_show, pwm_val_store);
+static DEVICE_ATTR(pwm_value, S_IRUGO | S_IWUSR,
+ pwm_value_show, pwm_value_store);
#endif
-static int create_vibrator_sysfs(void)
-{
- int ret;
- struct kobject *vibrator_kobj;
- vibrator_kobj = kobject_create_and_add("vibrator", NULL);
- if (unlikely(!vibrator_kobj))
- return -ENOMEM;
-
- ret = sysfs_create_file(vibrator_kobj,
- &dev_attr_pwm_val.attr);
- if (unlikely(ret < 0)) {
- pr_err("[VIB] sysfs_create_file failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
static int __devinit vibrator_probe(struct platform_device *pdev)
{
struct max8997_dev *max8997 = dev_get_drvdata(pdev->dev.parent);
@@ -323,8 +305,6 @@ static int __devinit vibrator_probe(struct platform_device *pdev)
INIT_WORK(&ddata->work, vibrator_work);
spin_lock_init(&ddata->lock);
- create_vibrator_sysfs();
-
ddata->pwm = pwm_request(pdata->pwm_id, "vibrator");
if (IS_ERR(ddata->pwm)) {
pr_err("[VIB] Failed to request pwm.\n");
@@ -343,6 +323,12 @@ static int __devinit vibrator_probe(struct platform_device *pdev)
goto err_timed_output_register;
}
+ /* User controllable pwm level */
+ error = device_create_file(ddata->dev.dev, &dev_attr_pwm_value);
+ if (error < 0) {
+ pr_err("[VIB] create sysfs fail: pwm_value\n");
+ }
+
#ifdef CONFIG_VIBETONZ
g_data = ddata;
pwm_duty_max = g_data->pdata->duty;
diff --git a/drivers/net/wireless/bcmdhd/Makefile b/drivers/net/wireless/bcmdhd/Makefile
index 40bc790..5121318 100644
--- a/drivers/net/wireless/bcmdhd/Makefile
+++ b/drivers/net/wireless/bcmdhd/Makefile
@@ -18,7 +18,7 @@ DHDCFLAGS += -Wall -Wstrict-prototypes -Dlinux -DLINUX -DBCMDRIVER \
DHDCFLAGS += -DCUSTOMER_HW4
DHDCFLAGS += -DDEBUGFS_CFG80211
-DHDCFLAGS += -DBLOCK_IPV6_PACKET -DPASS_IPV4_SUSPEND
+DHDCFLAGS += -DBLOCK_IPV6_PACKET
DHDCFLAGS += -DSUPPORT_DEEP_SLEEP
DHDCFLAGS += -DSIMPLE_MAC_PRINT
diff --git a/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c b/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
index 9e3922b..6d1d495 100755
--- a/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdspi_linux.c
@@ -355,7 +355,7 @@ hexdump(char *pfx, unsigned char *msg, int msglen)
for (i = 0; i < msglen; i++, col++) {
if (col % 16 == 0)
strcpy(buf, pfx);
- sprintf(buf + strlen(buf), "%02x", msg[i]);
+ sprintf(buf + strlen(buf), "%02hhx", msg[i]);
if ((col + 1) % 16 == 0)
printf("%s\n", buf);
else
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index c4ac414..6a25fc2 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -760,7 +760,7 @@ wl_show_host_event(wl_event_msg_t *event, void *event_data)
datalen = ntoh32(event->datalen);
/* debug dump of event messages */
- snprintf(eabuf, sizeof(eabuf), "%02x:%02x:%02x:%02x:%02x:%02x",
+ snprintf(eabuf, sizeof(eabuf), MACF,
(uchar)event->addr.octet[0]&0xff,
(uchar)event->addr.octet[1]&0xff,
(uchar)event->addr.octet[2]&0xff,
diff --git a/drivers/net/wireless/bcmdhd/dhd_custom_sec.c b/drivers/net/wireless/bcmdhd/dhd_custom_sec.c
index be129b5..7fab834 100755
--- a/drivers/net/wireless/bcmdhd/dhd_custom_sec.c
+++ b/drivers/net/wireless/bcmdhd/dhd_custom_sec.c
@@ -324,14 +324,16 @@ void get_customized_country_code(char *country_iso_code, wl_country_t *cspec)
#define CIS_BUF_SIZE 512
#endif /* BCM4330_CHIP */
+#define MACBUFFER_SZ (sizeof("00:11:22:33:44:55\n"))
+
#ifdef READ_MACADDR
int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
{
struct file *fp = NULL;
- char macbuffer[18] = {0};
+ char macbuffer[MACBUFFER_SZ] = {0};
mm_segment_t oldfs = {0};
char randommac[3] = {0};
- char buf[18] = {0};
+ char buf[MACBUFFER_SZ] = {0};
char *filepath_efs = MACINFO_EFS;
int ret = 0;
@@ -350,13 +352,13 @@ start_readmac:
/* Generating the Random Bytes for 3 last octects of the MAC address */
get_random_bytes(randommac, 3);
- sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(macbuffer, "%02X:%02X:%02X:%02hhX:%02hhX:%02hhX\n",
0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]);
DHD_ERROR(("[WIFI]The Random Generated MAC ID: %s\n", macbuffer));
if (fp->f_mode & FMODE_WRITE) {
ret = fp->f_op->write(fp, (const char *)macbuffer,
- sizeof(macbuffer), &fp->f_pos);
+ sizeof(macbuffer) - 1 /* skip null byte */, &fp->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n",
macbuffer, filepath_efs));
@@ -386,10 +388,10 @@ start_readmac:
}
if (ret)
- sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]),
- (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
- (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
+ sscanf(buf, MACF_U,
+ &(mac->octet[0]), &(mac->octet[1]),
+ &(mac->octet[2]), &(mac->octet[3]),
+ &(mac->octet[4]), &(mac->octet[5]));
else
DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath_efs));
@@ -423,14 +425,14 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac)
char *filepath_data = MACINFO;
char *filepath_efs = MACINFO_EFS;
struct file *fp_mac = NULL;
- char buf[18] = {0};
+ char buf[MACBUFFER_SZ] = {0};
mm_segment_t oldfs = {0};
int ret = -1;
if ((g_imac_flag != MACADDR_COB) && (g_imac_flag != MACADDR_MOD))
return 0;
- sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(buf, MACF_U "\n",
mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]);
@@ -445,7 +447,7 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac)
if (fp_mac->f_mode & FMODE_WRITE) {
ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
- sizeof(buf), &fp_mac->f_pos);
+ sizeof(buf) - 1 /* skip null byte */, &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed"
" to write into File: %s\n", buf, filepath_data));
@@ -467,7 +469,7 @@ int dhd_write_rdwr_macaddr(struct ether_addr *mac)
if (fp_mac->f_mode & FMODE_WRITE) {
ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
- sizeof(buf), &fp_mac->f_pos);
+ sizeof(buf) - 1 /* skip null byte */, &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed"
" to write into File: %s\n", buf, filepath_efs));
@@ -488,9 +490,9 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
{
struct file *fp_mac = NULL;
struct file *fp_nvm = NULL;
- char macbuffer[18] = {0};
+ char macbuffer[MACBUFFER_SZ] = {0};
char randommac[3] = {0};
- char buf[18] = {0};
+ char buf[MACBUFFER_SZ] = {0};
char *filepath_data = MACINFO;
char *filepath_efs = MACINFO_EFS;
#ifdef CONFIG_TARGET_LOCALE_NA
@@ -500,7 +502,7 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
#endif
char cur_mac[128] = {0};
char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38};
- char cur_macbuffer[18] = {0};
+ char cur_macbuffer[MACBUFFER_SZ] = {0};
int ret = -1;
g_imac_flag = MACADDR_NONE;
@@ -519,11 +521,12 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
} else {
DHD_ERROR(("MAC (OTP) : "
"[%02X:%02X:%02X:%02X:%02X:%02X] \r\n",
- cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3],
- cur_mac[4], cur_mac[5]));
+ (unsigned)cur_mac[0], (unsigned)cur_mac[1],
+ (unsigned)cur_mac[2], (unsigned)cur_mac[3],
+ (unsigned)cur_mac[4], (unsigned)cur_mac[5]));
}
- sprintf(cur_macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(cur_macbuffer, MACF_U "\n",
cur_mac[0], cur_mac[1], cur_mac[2],
cur_mac[3], cur_mac[4], cur_mac[5]);
@@ -552,13 +555,13 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
" Trying Random MAC.\n"));
g_imac_flag = MACADDR_MOD_RANDOM;
} else {
- sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&(mac->octet[0]),
- (unsigned int *)&(mac->octet[1]),
- (unsigned int *)&(mac->octet[2]),
- (unsigned int *)&(mac->octet[3]),
- (unsigned int *)&(mac->octet[4]),
- (unsigned int *)&(mac->octet[5]));
+ sscanf(buf, MACF_U,
+ &(mac->octet[0]),
+ &(mac->octet[1]),
+ &(mac->octet[2]),
+ &(mac->octet[3]),
+ &(mac->octet[4]),
+ &(mac->octet[5]));
/* current MAC address is same as previous one */
if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
g_imac_flag = MACADDR_NONE;
@@ -601,13 +604,13 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
" Trying Random MAC.\n"));
g_imac_flag = MACADDR_MOD_RANDOM;
} else {
- sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&(mac->octet[0]),
- (unsigned int *)&(mac->octet[1]),
- (unsigned int *)&(mac->octet[2]),
- (unsigned int *)&(mac->octet[3]),
- (unsigned int *)&(mac->octet[4]),
- (unsigned int *)&(mac->octet[5]));
+ sscanf(buf, MACF_U,
+ &(mac->octet[0]),
+ &(mac->octet[1]),
+ &(mac->octet[2]),
+ &(mac->octet[3]),
+ &(mac->octet[4]),
+ &(mac->octet[5]));
/* current MAC address is same as previous one */
if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
g_imac_flag = MACADDR_NONE;
@@ -642,13 +645,13 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
(strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
g_imac_flag = MACADDR_COB_RANDOM;
} else {
- sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&(mac->octet[0]),
- (unsigned int *)&(mac->octet[1]),
- (unsigned int *)&(mac->octet[2]),
- (unsigned int *)&(mac->octet[3]),
- (unsigned int *)&(mac->octet[4]),
- (unsigned int *)&(mac->octet[5]));
+ sscanf(buf, MACF_U,
+ &(mac->octet[0]),
+ &(mac->octet[1]),
+ &(mac->octet[2]),
+ &(mac->octet[3]),
+ &(mac->octet[4]),
+ &(mac->octet[5]));
/* Writing Newly generated MAC ID to the Dongle */
if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
DHD_INFO(("%s: MACID is overwritten\n",
@@ -665,18 +668,18 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
if ((g_imac_flag == MACADDR_COB_RANDOM) ||
(g_imac_flag == MACADDR_MOD_RANDOM)) {
get_random_bytes(randommac, 3);
- sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(macbuffer, "%02X:%02X:%02X:%02hhX:%02hhX:%02hhX\n",
0x60, 0xd0, 0xa9, randommac[0], randommac[1],
randommac[2]);
DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n",
macbuffer));
- sscanf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&(mac->octet[0]),
- (unsigned int *)&(mac->octet[1]),
- (unsigned int *)&(mac->octet[2]),
- (unsigned int *)&(mac->octet[3]),
- (unsigned int *)&(mac->octet[4]),
- (unsigned int *)&(mac->octet[5]));
+ sscanf(macbuffer, MACF_U,
+ &(mac->octet[0]),
+ &(mac->octet[1]),
+ &(mac->octet[2]),
+ &(mac->octet[3]),
+ &(mac->octet[4]),
+ &(mac->octet[5]));
if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__));
g_imac_flag = MACADDR_COB;
@@ -694,10 +697,10 @@ int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
{
struct file *fp = NULL;
- char macbuffer[18] = {0};
+ char macbuffer[MACBUFFER_SZ] = {0};
mm_segment_t oldfs = {0};
char randommac[3] = {0};
- char buf[18] = {0};
+ char buf[MACBUFFER_SZ] = {0};
char *filepath_efs = MACINFO_EFS;
int is_zeromac = 0;
int ret = 0;
@@ -721,7 +724,7 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
*/
get_random_bytes(randommac, 3);
- sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(macbuffer, "%02X:%02X:%02X:%02hhX:%02hhX:%02hhX\n",
0x60, 0xd0, 0xa9, randommac[0],
randommac[1], randommac[2]);
DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n",
@@ -730,7 +733,7 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
if (fp->f_mode & FMODE_WRITE) {
ret = fp->f_op->write(fp,
(const char *)macbuffer,
- sizeof(macbuffer), &fp->f_pos);
+ sizeof(macbuffer) - 1 /* skip null byte */, &fp->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s]"
" Failed to write into File:"
@@ -761,13 +764,13 @@ int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
}
if (ret)
- sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- (unsigned int *)&(mac->octet[0]),
- (unsigned int *)&(mac->octet[1]),
- (unsigned int *)&(mac->octet[2]),
- (unsigned int *)&(mac->octet[3]),
- (unsigned int *)&(mac->octet[4]),
- (unsigned int *)&(mac->octet[5]));
+ sscanf(buf, MACF_U,
+ &(mac->octet[0]),
+ &(mac->octet[1]),
+ &(mac->octet[2]),
+ &(mac->octet[3]),
+ &(mac->octet[4]),
+ &(mac->octet[5]));
else
DHD_INFO(("dhd_bus_start: Reading from the"
" '%s' returns 0 bytes\n", filepath_efs));
@@ -827,8 +830,8 @@ static void dhd_dump_cis(const unsigned char *buf, int size)
{
int i;
for (i = 0; i < size; i++) {
- DHD_ERROR(("%02X ", buf[i]));
- if ((i % 15) == 15) DHD_ERROR(("\n"));
+ DHD_ERROR(("%02X ", (unsigned)buf[i]));
+ if ((i % 15) == 15) DHD_ERROR(("\n")); /* FIXME: Will always be false */
}
DHD_ERROR(("\n"));
}
@@ -1054,11 +1057,14 @@ int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
if (ret < 0) {
DHD_TRACE(("%s: CIS reading failed, err=%d\n", __func__,
ret));
- sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(otp_mac_buf, MACF_U "\n",
mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]);
DHD_ERROR(("%s: Check module mac by legacy FW : %02X:%02X:%02X\n",
- __func__, mac->octet[0], mac->octet[4], mac->octet[5]));
+ __func__,
+ (unsigned)mac->octet[0],
+ (unsigned)mac->octet[4],
+ (unsigned)mac->octet[5]));
} else {
unsigned char mac_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#ifdef DUMP_CIS
@@ -1071,7 +1077,7 @@ int dhd_check_module_mac(dhd_pub_t *dhd, struct ether_addr *mac)
mac_id[4] = cis_buf[CIS_MAC_OFFSET + 4];
mac_id[5] = cis_buf[CIS_MAC_OFFSET + 5];
- sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(otp_mac_buf, MACF_U "\n",
mac_id[0], mac_id[1], mac_id[2], mac_id[3], mac_id[4],
mac_id[5]);
DHD_ERROR(("[WIFI]mac_id is setted from OTP \n"));
@@ -1100,14 +1106,14 @@ int dhd_write_macaddr(struct ether_addr *mac)
char *filepath_efs = MACINFO_EFS;
struct file *fp_mac = NULL;
- char buf[18] = {0};
+ char buf[MACBUFFER_SZ] = {0};
mm_segment_t oldfs = {0};
int ret = -1;
int retry_count = 0;
startwrite:
- sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ sprintf(buf, MACF_U "\n",
mac->octet[0], mac->octet[1], mac->octet[2],
mac->octet[3], mac->octet[4], mac->octet[5]);
@@ -1123,7 +1129,7 @@ startwrite:
if (fp_mac->f_mode & FMODE_WRITE) {
ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
- sizeof(buf), &fp_mac->f_pos);
+ sizeof(buf) - 1 /* skip null byte */, &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed to"
" write into File: %s\n", buf, filepath_data));
@@ -1163,7 +1169,7 @@ startwrite:
if (fp_mac->f_mode & FMODE_WRITE) {
ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
- sizeof(buf), &fp_mac->f_pos);
+ sizeof(buf) - 1 /* skip null byte */, &fp_mac->f_pos);
if (ret < 0)
DHD_ERROR(("[WIFI] Mac address [%s] Failed to"
" write into File: %s\n", buf, filepath_efs));
diff --git a/drivers/net/wireless/bcmdhd/dhd_sec_feature.h b/drivers/net/wireless/bcmdhd/dhd_sec_feature.h
index 933a78a..98a41a0 100755
--- a/drivers/net/wireless/bcmdhd/dhd_sec_feature.h
+++ b/drivers/net/wireless/bcmdhd/dhd_sec_feature.h
@@ -49,7 +49,8 @@
#define READ_MACADDR
#endif /* CONFIG_ARCH_MSM7X30 */
-#if defined(CONFIG_MACH_GC1) || defined(CONFIG_MACH_U1_NA_SPR) || defined(CONFIG_MACH_V1)
+#if defined(CONFIG_MACH_GC1) || defined(CONFIG_MACH_U1_NA_SPR) || defined(CONFIG_MACH_V1)\
+ || defined(CONFIG_MACH_KONA)
#undef USE_CID_CHECK
#define READ_MACADDR
#endif /* CONFIG_MACH_GC1 || CONFIG_MACH_U1_NA_SPR || CONFIG_MACH_V1 */
diff --git a/drivers/net/wireless/bcmdhd/include/bcmutils.h b/drivers/net/wireless/bcmdhd/include/bcmutils.h
index 1b21327..90f8f40 100644
--- a/drivers/net/wireless/bcmdhd/include/bcmutils.h
+++ b/drivers/net/wireless/bcmdhd/include/bcmutils.h
@@ -669,7 +669,8 @@ extern void *_bcmutils_dummy_fn;
#define CRC32_GOOD_VALUE 0xdebb20e3
-#define MACF "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MACF "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx"
+#define MACF_U "%02hhX:%02hhX:%02hhX:%02hhX:%02hhX:%02hhX" /* upper case hex */
#define ETHERP_TO_MACF(ea) ((struct ether_addr *) (ea))->octet[0], \
((struct ether_addr *) (ea))->octet[1], \
((struct ether_addr *) (ea))->octet[2], \
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index b2acd6a..16a8911 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -2423,7 +2423,7 @@ wl_iw_set_encodeext(
for (j = 0; j < (WSEC_MAX_PSK_LEN / 2); j++) {
- sprintf(charptr, "%02x", iwe->key[j]);
+ sprintf(charptr, "%02hhx", iwe->key[j]);
charptr += 2;
}
len = strlen(keystring);
diff --git a/drivers/power/sec_battery_px.c b/drivers/power/sec_battery_px.c
index 0a31772..f039c17 100644
--- a/drivers/power/sec_battery_px.c
+++ b/drivers/power/sec_battery_px.c
@@ -60,7 +60,7 @@ enum {
#define P2_CHARGING_FEATURE_02 /* SMB136 + MAX17042, Cable detect by TA_nCon */
#endif
-#if defined(CONFIG_MACH_P4NOTE)
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
#define P4_CHARGING_FEATURE_01 /* SMB347 + MAX17042, use TA_nCON */
#endif
diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig
index f7888b9..36464eb 100644
--- a/drivers/sensor/Kconfig
+++ b/drivers/sensor/Kconfig
@@ -112,6 +112,17 @@ config SENSORS_AL3201
Say N here if you do not use AL3201.
+config SENSORS_K2DH
+ tristate "K2DH acceleration sensor support"
+ depends on I2C
+ default n
+ help
+ Say Y here if you use K2DH.
+ This option enables accelerometer sensors using
+ STM K2DH in K2DH device driver.
+
+ Say N here if you do not use K2DH.
+
config SENSORS_K3DH
tristate "K3DH acceleration sensor support"
depends on I2C
@@ -119,6 +130,17 @@ config SENSORS_K3DH
help
Driver for STMicroelectronic K3DH accelerometer.
+config SENSOR_K3DH_INPUTDEV
+ bool "K3DH acceleration sensor input dev support"
+ depends on SENSORS_K3DH
+ default n
+ help
+ Say Y here if you use K3DH.
+ This option enables accelerometer sensor using
+ K3DH device driver.
+
+ Say N here if you do not use K3DH.
+
config SENSORS_K3G
tristate "K3G driver for s5pc210"
depends on I2C
@@ -139,4 +161,36 @@ config SENSORS_LPS331
depends on I2C
help
Driver for STMicro LPS331
+
+config SENSORS_YAS532
+ depends on I2C
+ tristate "yas532 Sensor Support"
+ default n
+ help
+ Say Y to enable YAS532 Magnetic Sensor support.
+ This allows control of supported Magnetic Sensor.
+
+config SENSORS_YAS_ORI
+ depends on I2C
+ tristate "yas orientation Sensor Support"
+ default n
+ help
+ Say Y to enable YAS532 Magnetic Sensor support.
+ This allows control of supported Magnetic Sensor.
+
+config INPUT_YAS_MAGNETOMETER_POSITION
+ int "YAS Geomagnetic Sensor Mounting Position on Board"
+ depends on I2C
+ default "0"
+ help
+ Chip mounting position (pin 1).
+ 0: top, upper-left
+ 1: top, upper-right
+ 2: top, lower-right
+ 3: top, lower-left
+ 4: bottom, upper-left
+ 5: bottom, upper-right
+ 6: bottom, lower-right
+ 7: bottom, lower-left
+
endif
diff --git a/drivers/sensor/Makefile b/drivers/sensor/Makefile
index 44adf31..195f0f9 100644
--- a/drivers/sensor/Makefile
+++ b/drivers/sensor/Makefile
@@ -6,7 +6,11 @@
obj-$(CONFIG_SENSORS_CORE) += sensors_core.o
# accelerometer_sensor
+ifeq ($(CONFIG_MACH_KONA_SENSOR),y)
+obj-$(CONFIG_SENSORS_K3DH) += k3dh_kona.o
+else
obj-$(CONFIG_SENSORS_K3DH) += k3dh.o
+endif
obj-$(CONFIG_SENSORS_BMA254) += bma254_driver.o
# gyro_sensor
obj-$(CONFIG_SENSORS_K3G) += k3g.o
@@ -15,6 +19,8 @@ obj-$(CONFIG_SENSORS_LSM330DLC) += lsm330dlc_accel.o lsm330dlc_gyro.o
# magnetic_sensor
obj-$(CONFIG_SENSORS_AK8975C) += ak8975.o
obj-$(CONFIG_SENSORS_AK8963C) += ak8963.o
+obj-$(CONFIG_SENSORS_YAS532) += yas_mag_kernel_driver.o
+obj-$(CONFIG_SENSORS_YAS_ORI) += yas_ori_kernel_driver.o
# optical_sensor
obj-$(CONFIG_SENSORS_CM3663) += cm3663.o
obj-$(CONFIG_SENSORS_TAOS) += taos.o
diff --git a/drivers/sensor/al3201.c b/drivers/sensor/al3201.c
index a225b1a..df21515 100644
--- a/drivers/sensor/al3201.c
+++ b/drivers/sensor/al3201.c
@@ -304,10 +304,35 @@ static ssize_t get_chip_name(struct device *dev,
{
return sprintf(buf, "%s\n", CHIP_NAME);
}
+#if defined(CONFIG_MACH_KONA)
+static ssize_t al3201_lux_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int result;
+ struct input_dev *input = to_input_dev(dev);
+ struct al3201_data *data = input_get_drvdata(input);
+
+ /* No LUX data if not operational */
+ if (data->state == OFF) {
+ al3201_set_power_state(data->client, ON);
+ msleep(180);
+ }
+
+ result = al3201_get_adc_value(data->client);
+
+ if (data->state == OFF)
+ al3201_set_power_state(data->client, OFF);
+
+ return sprintf(buf, "%d\n", result);
+}
+#endif
static DEVICE_ATTR(raw_data, 0644, al3201_raw_data_show, NULL);
static DEVICE_ATTR(vendor, 0644, get_vendor_name, NULL);
static DEVICE_ATTR(name, 0644, get_chip_name, NULL);
+#if defined(CONFIG_MACH_KONA)
+static DEVICE_ATTR(lux, 0644, al3201_lux_show, NULL);
+#endif
/* factory test*/
#ifdef LSC_DBG
@@ -582,26 +607,38 @@ static int __devinit al3201_probe(struct i2c_client *client,
dev_attr_name.attr.name);
goto err_light_device_create_file3;
}
+
+#if defined(CONFIG_MACH_KONA)
+ if (device_create_file(data->light_dev, &dev_attr_lux) < 0) {
+ pr_err("%s: could not create device file(%s)!\n", __func__,
+ dev_attr_lux.attr.name);
+ goto err_light_device_create_file4;
+ }
+#endif
dev_set_drvdata(data->light_dev, data);
pr_info("%s: success!\n", __func__);
goto done;
- err_light_device_create_file3:
+#if defined(CONFIG_MACH_KONA)
+err_light_device_create_file4:
+ device_remove_file(data->light_dev, &dev_attr_lux);
+#endif
+err_light_device_create_file3:
device_remove_file(data->light_dev, &dev_attr_vendor);
err_light_device_create_file2:
device_remove_file(data->light_dev, &dev_attr_raw_data);
err_light_device_create_file1:
sensors_classdev_unregister(data->light_dev);
- err_light_device_create:
+err_light_device_create:
sysfs_remove_group(&data->input->dev.kobj, &al3201_attribute_group);
- err_sysfs_create_group_light:
+err_sysfs_create_group_light:
input_unregister_device(data->input);
- err_input_register_device_light:
- err_input_allocate_device_light:
+err_input_register_device_light:
+err_input_allocate_device_light:
destroy_workqueue(data->wq);
- err_create_workqueue:
- err_initializ_chip:
+err_create_workqueue:
+err_initializ_chip:
mutex_destroy(&data->lock);
kfree(data);
done:
diff --git a/drivers/sensor/gp2a_proximity.c b/drivers/sensor/gp2a_proximity.c
index 7efbf3e..c1624e6 100644
--- a/drivers/sensor/gp2a_proximity.c
+++ b/drivers/sensor/gp2a_proximity.c
@@ -47,8 +47,6 @@
#define VENDOR "SHARP"
#define CHIP_ID "GP2AP"
-#define OFFSET_FILE_PATH "/efs/prox_cal"
-
#if 1
#define gprintk(fmt, x...) printk(KERN_INFO "%s(%d): "\
fmt, __func__ , __LINE__, ## x)
@@ -56,17 +54,31 @@ fmt, __func__ , __LINE__, ## x)
#define gprintk(x...) do { } while (0)
#endif
/**************************************************/
-#if defined(CONFIG_MACH_BAFFIN)
-#define PROX_READ_NUM 20
+/* Calibration*/
+#define GP2A_CALIBRATION
+#ifdef GP2A_CALIBRATION
+#ifdef CONFIG_SLP
+#define CALIBRATION_FILE_PATH "/csa/sensor/prox_cal_data"
#else
-#define PROX_READ_NUM 40
+#define CALIBRATION_FILE_PATH "/efs/prox_cal"
+#endif
+#endif
+#if defined(CONFIG_MACH_KONA_SENSOR)
+#define DEFAULT_THRESHOLD_DIFF 2
+#else
+#define DEFAULT_THRESHOLD_DIFF 1
#endif
+#define PROX_READ_NUM 40
#define PS_LOW_THD_L 0x08
#define PS_LOW_THD_H 0x09
#define PS_HIGH_THD_L 0x0A
#define PS_HIGH_THD_H 0x0B
+#if defined(CONFIG_MACH_KONA_SENSOR)
+#define XTALK 8
+#define THDL 10
+#endif
/* global var */
static struct i2c_driver opt_i2c_driver;
static struct i2c_client *opt_i2c_client;
@@ -85,17 +97,17 @@ struct gp2a_data {
struct hrtimer prox_timer;
struct workqueue_struct *prox_wq;
struct work_struct work_prox;
- int enabled;
int proximity_data;
int irq;
int average[3]; /*for proximity adc average */
ktime_t prox_poll_delay;
-
- /* Auto Calibration */
- int offset_value;
- int cal_result;
- uint16_t threshold_high;
- bool offset_cal_high;
+ u8 enabled;
+ u8 thresh_diff;
+ u8 power_state;
+#ifdef GP2A_CALIBRATION
+ u8 default_threshold;
+ u8 cal_data;
+#endif
};
/* initial value for sensor register */
@@ -113,13 +125,17 @@ static u8 gp2a_original_image_030a[COL][2] = {
/* {0x05 , 0x00}, */
/* {0x06 , 0xFF}, */
/* {0x07 , 0xFF}, */
-#if defined(CONFIG_MACH_BAFFIN)
- {0x08, 0x08},
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ {0x08, 0x08}, /*PS mode LTH(Loff): (??mm) */
#else
- {0x08, 0x09}, /*PS mode LTH(Loff): (??mm) */
+ {0x08, 0x09}, /*PS mode LTH(Loff): (??mm) */
#endif
{0x09, 0x00}, /*PS mode LTH(Loff) : */
- {0x0A, 0x0A}, /*PS mode HTH(Lon) : (??mm) */
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ {0x0A, 0x0A}, /*PS mode HTH(Lon) : (??mm) */
+#else
+ {0x0A, 0x0A}, /*PS mode HTH(Lon) : (??mm) */
+#endif
{0x0B, 0x00}, /* PS mode HTH(Lon) : */
/* {0x13 , 0x08}, by sharp for internal calculation (type:0) */
/*alternating mode (PS+ALS), TYPE=1
@@ -150,27 +166,22 @@ static u8 gp2a_original_image[COL][2] = {
{0x00, 0xC0}
};
-#define THR_REG_LSB(data, reg) \
- { \
- reg = (u8)data & 0xff; \
- }
-#define THR_REG_MSB(data, reg) \
- { \
- reg = (u8)data >> 8; \
- }
-
static int proximity_onoff(u8 onoff);
+#ifdef GP2A_CALIBRATION
+static int proximity_open_calibration(struct gp2a_data *data);
+#endif
int is_gp2a030a(void)
{
-#if defined(CONFIG_MACH_C1) || \
- defined(CONFIG_MACH_M0) || \
- defined(CONFIG_MACH_GRANDE) || \
+#if defined(CONFIG_MACH_GRANDE) || \
defined(CONFIG_MACH_IRON)
return (system_rev != 0 && system_rev != 3);
#endif
-#if defined(CONFIG_MACH_M3) || \
- defined(CONFIG_MACH_BAFFIN)
+#if defined(CONFIG_MACH_M3_USA_TMO) || \
+ defined(CONFIG_MACH_BAFFIN) || \
+ defined(CONFIG_MACH_KONA_SENSOR) ||\
+ defined(CONFIG_MACH_TAB3) ||\
+ defined(CONFIG_MACH_GC2PD)
return 1;
#endif
#if defined(CONFIG_MACH_REDWOOD)
@@ -180,17 +191,23 @@ int is_gp2a030a(void)
return 0;
}
-static int gp2a_update_threshold(u8 (*selected_image)[2],
- unsigned long new_threshold, bool update_reg)
+static int gp2a_update_threshold(struct gp2a_data *data,
+ u8 (*selected_image)[2], u8 new_threshold, bool update_reg)
{
int i, err = 0;
u8 set_value;
+ pr_info("%s, new = 0x%x, thresh_diff = %d\n", __func__,
+ new_threshold, data->thresh_diff);
for (i = 0; i < COL; i++) {
switch (selected_image[i][0]) {
case PS_LOW_THD_L:
/*PS mode LTH(Loff) for low 8bit*/
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ set_value = (new_threshold-data->thresh_diff) & 0x00FF;
+#else
set_value = new_threshold & 0x00FF;
+#endif
break;
case PS_LOW_THD_H:
@@ -200,12 +217,17 @@ static int gp2a_update_threshold(u8 (*selected_image)[2],
case PS_HIGH_THD_L:
/*PS mode HTH(Lon) for low 8bit*/
- set_value = (new_threshold+1) & 0x00FF;
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ set_value = (new_threshold) & 0x00FF;
+#else
+ set_value = (new_threshold+data->thresh_diff) & 0x00FF;
+#endif
break;
case PS_HIGH_THD_H:
/* PS mode HTH(Lon) for high 8bit*/
- set_value = ((new_threshold+1) & 0xFF00) >> 8;
+ set_value = ((new_threshold
+ +data->thresh_diff) & 0xFF00) >> 8;
break;
default:
@@ -219,238 +241,14 @@ static int gp2a_update_threshold(u8 (*selected_image)[2],
pr_err("%s : setting error i = %d, err=%d\n",
__func__, i, err);
return err;
- } else
- selected_image[i][1] = set_value;
- }
-
- return err;
-}
-
-static int proximity_adc_read(struct gp2a_data *data)
-{
- int sum[OFFSET_ARRAY_LENGTH];
- int i = OFFSET_ARRAY_LENGTH-1;
- int avg;
- int min;
- int max;
- int total;
- int D2_data;
- unsigned char get_D2_data[2];
-
- mutex_lock(&data->data_mutex);
- do {
- msleep(50);
- opt_i2c_read(DATA2_LSB, get_D2_data, sizeof(get_D2_data));
- D2_data = (get_D2_data[1] << 8) | get_D2_data[0];
- sum[i] = D2_data;
- if (i == 0) {
- min = sum[i];
- max = sum[i];
} else {
- if (sum[i] < min)
- min = sum[i];
- else if (sum[i] > max)
- max = sum[i];
+ selected_image[i][1] = set_value;
}
- total += sum[i];
- } while (i--);
- mutex_unlock(&data->data_mutex);
-
- total -= (min + max);
- avg = (int)(total / (OFFSET_ARRAY_LENGTH - 2));
- pr_info("%s: offset = %d\n", __func__, avg);
-
- return avg;
-}
-
-
-static int proximity_open_calibration(struct gp2a_data *data)
-{
- struct file *cal_filp = NULL;
- int err = 0;
- mm_segment_t old_fs;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- cal_filp = filp_open(OFFSET_FILE_PATH,
- O_RDONLY, S_IRUGO | S_IWUSR | S_IWGRP);
-
- if (IS_ERR(cal_filp)) {
- pr_err("%s: Can't open calibration file\n", __func__);
- set_fs(old_fs);
- err = PTR_ERR(cal_filp);
- goto done;
}
- err = cal_filp->f_op->read(cal_filp,
- (char *)&data->offset_value,
- sizeof(int), &cal_filp->f_pos);
- if (err != sizeof(int)) {
- pr_err("%s: Can't read the cal data from file\n", __func__);
- err = -EIO;
- }
-
- pr_info("%s: (%d)\n", __func__,
- data->offset_value);
-
- filp_close(cal_filp, current->files);
-done:
- set_fs(old_fs);
return err;
}
-static int proximity_do_calibrate(struct gp2a_data *data,
- bool do_calib, bool thresh_set)
-{
- struct file *cal_filp;
- int err;
- int xtalk_avg = 0;
- int offset_change = 0;
- uint16_t thrd = 0;
- u8 reg;
- mm_segment_t old_fs;
-
- u8 (*cal_image)[2] = (is_gp2a030a() ?
- gp2a_original_image_030a : gp2a_original_image);
-
- if (do_calib) {
- if (thresh_set) {
- /* for proximity_thresh_store */
- data->offset_value =
- data->threshold_high -
- (cal_image[6][1] << 8 | cal_image[5][1]);
- } else {
- /* tap offset button */
- /* get offset value */
- xtalk_avg = proximity_adc_read(data);
- offset_change =
- (cal_image[6][1] << 8 | cal_image[5][1])
- - DEFAULT_HI_THR;
- if (xtalk_avg < offset_change) {
- /* do not need calibration */
- data->cal_result = 0;
- err = 0;
- goto no_cal;
- }
- data->offset_value = xtalk_avg - offset_change;
- }
- /* update threshold */
- thrd = (cal_image[4][1] << 8 | cal_image[3][1])
- + (data->offset_value);
- THR_REG_LSB(thrd, reg);
- opt_i2c_write(cal_image[3][0], &reg);
- THR_REG_MSB(thrd, reg);
- opt_i2c_write(cal_image[4][0], &reg);
-
- thrd = (cal_image[4][1] << 8 | cal_image[5][1])
- +(data->offset_value);
- THR_REG_LSB(thrd, reg);
- opt_i2c_write(cal_image[5][0], &reg);
- THR_REG_MSB(thrd, reg);
- opt_i2c_write(cal_image[6][0], &reg);
-
- /* calibration result */
- if (!thresh_set)
- data->cal_result = 1;
- } else {
- /* tap reset button */
- data->offset_value = 0;
- /* update threshold */
- opt_i2c_write(cal_image[3][0], &cal_image[3][1]);
- opt_i2c_write(cal_image[4][0], &cal_image[4][1]);
- opt_i2c_write(cal_image[5][0], &cal_image[5][1]);
- opt_i2c_write(cal_image[6][0], &cal_image[6][1]);
- /* calibration result */
- data->cal_result = 2;
- }
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- cal_filp = filp_open(OFFSET_FILE_PATH,
- O_CREAT | O_TRUNC | O_WRONLY,
- S_IRUGO | S_IWUSR | S_IWGRP);
-
- if (IS_ERR(cal_filp)) {
- pr_err("%s: Can't open calibration file\n", __func__);
- set_fs(old_fs);
- err = PTR_ERR(cal_filp);
- goto done;
- }
-
- err = cal_filp->f_op->write(cal_filp,
- (char *)&data->offset_value, sizeof(int),
- &cal_filp->f_pos);
- if (err != sizeof(int)) {
- pr_err("%s: Can't write the cal data to file\n", __func__);
- err = -EIO;
- }
-
- filp_close(cal_filp, current->files);
-done:
- set_fs(old_fs);
-no_cal:
- return err;
-}
-
-static int proximity_manual_offset(struct gp2a_data *data, u8 change_on)
-{
- struct file *cal_filp;
- int err;
- int16_t thrd;
- u8 reg;
- mm_segment_t old_fs;
-
- u8 (*manual_image)[2] = (is_gp2a030a() ?
- gp2a_original_image_030a : gp2a_original_image);
-
- data->offset_value = change_on;
- /* update threshold */
- thrd = manual_image[3][1]+(data->offset_value);
- THR_REG_LSB(thrd, reg);
- opt_i2c_write(manual_image[3][0], &reg);
- THR_REG_MSB(thrd, reg);
- opt_i2c_write(manual_image[4][0], &reg);
-
- thrd = manual_image[5][1]+(data->offset_value);
- THR_REG_LSB(thrd, reg);
- opt_i2c_write(manual_image[5][0], &reg);
- THR_REG_MSB(thrd, reg);
- opt_i2c_write(manual_image[6][0], &reg);
-
- /* calibration result */
- data->cal_result = 1;
-
- old_fs = get_fs();
- set_fs(KERNEL_DS);
-
- cal_filp = filp_open(OFFSET_FILE_PATH,
- O_CREAT | O_TRUNC | O_WRONLY,
- S_IRUGO | S_IWUSR | S_IWGRP);
-
- if (IS_ERR(cal_filp)) {
- pr_err("%s: Can't open calibration file\n", __func__);
- set_fs(old_fs);
- err = PTR_ERR(cal_filp);
- goto done;
- }
-
- err = cal_filp->f_op->write(cal_filp,
- (char *)&data->offset_value, sizeof(int),
- &cal_filp->f_pos);
- if (err != sizeof(int)) {
- pr_err("%s: Can't write the cal data to file\n", __func__);
- err = -EIO;
- }
-
- filp_close(cal_filp, current->files);
-done:
- set_fs(old_fs);
- return err;
-}
-
-
/* Proximity Sysfs interface */
static ssize_t
proximity_enable_show(struct device *dev,
@@ -477,28 +275,63 @@ proximity_enable_store(struct device *dev,
err = kstrtoint(buf, 10, &value);
if (err)
- printk(KERN_ERR "%s, kstrtoint failed.", __func__);
+ pr_err("%s, kstrtoint failed.", __func__);
if (value != 0 && value != 1)
return count;
gprintk("value = %d\n", value);
- if (data->enabled && !value) { /* Proximity power off */
+ if (data->enabled && !value) { /* proximity disable */
disable_irq(data->irq);
- proximity_enable = value;
+ data->enabled = 0;
proximity_onoff(0);
disable_irq_wake(data->irq);
- data->pdata->gp2a_led_on(false);
- } else if (!data->enabled && value) { /* proximity power on */
- data->pdata->gp2a_led_on(true);
- /*msleep(1); */
- proximity_enable = value;
+ /* proximity power off */
+ if (data->pdata->gp2a_led_on
+ && data->power_state) {
+ data->pdata->gp2a_led_on(false);
+ data->power_state = 0;
+ }
+
+#ifdef CONFIG_SENSORS_GP2A_VDD_CONTROL
+ /* gp2a vdd power off */
+ if (data->pdata->gp2a_vdd_on
+ && !(data->enabled & LIGHT_ENABLED)) {
+ data->pdata->gp2a_vdd_on(false);
+ data->power_state &= ~LIGHT_ENABLED;
+ }
+#endif
+ } else if (!(data->enabled) && value) { /* proximity enable */
+ /* proximity power on */
+ if (data->pdata->gp2a_led_on
+ && !(data->power_state)) {
+ data->pdata->gp2a_led_on(true);
+ data->power_state = 1;
+ }
+
+#ifdef CONFIG_SENSORS_GP2A_VDD_CONTROL
+ /* gp2a vdd power on */
+ if (data->pdata->gp2a_vdd_on
+ && !(data->power_state & LIGHT_ENABLED)) {
+ data->pdata->gp2a_vdd_on(true);
+ data->power_state |= LIGHT_ENABLED;
+ }
+#endif
+
+ /*msleep(1); */
+#ifdef GP2A_CALIBRATION
+ /* open cancelation data */
+ err = proximity_open_calibration(data);
+ if (err < 0 && err != -ENOENT)
+ pr_err("%s: proximity_open_calibration() failed\n",
+ __func__);
+#endif
+ data->enabled = 1;
proximity_onoff(1);
enable_irq_wake(data->irq);
- msleep(160);
input = gpio_get_value(data->pdata->p_out);
input_report_abs(data->input_dev, ABS_DISTANCE, input);
@@ -506,7 +339,6 @@ proximity_enable_store(struct device *dev,
enable_irq(data->irq);
}
- data->enabled = value;
return count;
}
@@ -515,8 +347,6 @@ static ssize_t proximity_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct gp2a_data *data = dev_get_drvdata(dev);
- static int count; /*count for proximity average */
-
int D2_data = 0;
unsigned char get_D2_data[2] = { 0, };
@@ -525,12 +355,7 @@ static ssize_t proximity_state_show(struct device *dev,
mutex_unlock(&data->data_mutex);
D2_data = (get_D2_data[1] << 8) | get_D2_data[0];
- data->average[count] = D2_data;
- count++;
- if (count == PROX_READ_NUM)
- count = 0;
- pr_debug("%s: D2_data = %d\n", __func__, D2_data);
- return snprintf(buf, PAGE_SIZE, "%d\n", D2_data);
+ return sprintf(buf, "%d\n", D2_data);
}
static ssize_t proximity_avg_show(struct device *dev,
@@ -559,7 +384,7 @@ static ssize_t proximity_avg_store(struct device *dev,
}
if (new_value && !proximity_avg_on) {
- if (!(proximity_enable)) {
+ if (!(data->enabled)) {
/*data->pdata->gp2a_led_on(true);*/
proximity_onoff(1);
}
@@ -573,7 +398,7 @@ static ssize_t proximity_avg_store(struct device *dev,
hrtimer_cancel(&data->prox_timer);
proximity_avg_on = 0;
- if (!(proximity_enable)) {
+ if (!(data->enabled)) {
proximity_onoff(0);
/*data->pdata->gp2a_led_on(false);*/
}
@@ -589,7 +414,7 @@ static ssize_t proximity_thresh_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int i;
- int threshold = 0;
+ u8 threshold = 0;
u8 (*selected_image)[2] = (is_gp2a030a() ?
gp2a_original_image_030a : gp2a_original_image);
@@ -609,10 +434,11 @@ static ssize_t proximity_thresh_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t size)
{
- unsigned long threshold;
+ struct gp2a_data *data = dev_get_drvdata(dev);
+ u8 threshold = 0;
int err = 0;
- err = strict_strtoul(buf, 10, &threshold);
+ err = kstrtou8(buf, 10, &threshold);
if (err) {
pr_err("%s, conversion %s to number.\n",
@@ -620,7 +446,7 @@ static ssize_t proximity_thresh_store(struct device *dev,
return err;
}
- err = gp2a_update_threshold(is_gp2a030a() ?
+ err = gp2a_update_threshold(data, is_gp2a030a() ?
gp2a_original_image_030a : gp2a_original_image,
threshold, true);
@@ -632,53 +458,262 @@ static ssize_t proximity_thresh_store(struct device *dev,
return size;
}
+#ifdef GP2A_CALIBRATION
+static u8 proximity_adc_read(struct gp2a_data *gp2a)
+{
+ int adc_arr[OFFSET_ARRAY_LENGTH];
+ int total = 0, min = 0, max = 0;
+ u8 avg = 0;
+ int D2_data = 0;
+ unsigned char get_D2_data[2] = {0,};
+ int i;
+
+ for (i = 0; i < OFFSET_ARRAY_LENGTH; i++) {
+ mdelay(50);
+ mutex_lock(&gp2a->data_mutex);
+ opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
+ mutex_unlock(&gp2a->data_mutex);
+ D2_data = (get_D2_data[1] << 8) | get_D2_data[0];
+ adc_arr[i] = D2_data;
+ if (i == 0) {
+ min = adc_arr[i];
+ max = adc_arr[i];
+ } else {
+ if (adc_arr[i] < min)
+ min = adc_arr[i];
+ else if (adc_arr[i] > max)
+ max = adc_arr[i];
+ }
+ total += adc_arr[i];
+ }
+
+ total -= (min + max);
+ avg = (u8)(total / (OFFSET_ARRAY_LENGTH - 2));
+ pr_info("%s: offset = %d\n", __func__, avg);
+
+ return avg;
+}
+
+static int proximity_open_calibration(struct gp2a_data *data)
+{
+ struct file *cancel_filp = NULL;
+ int err = 0;
+ mm_segment_t old_fs;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ cancel_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
+ if (IS_ERR(cancel_filp)) {
+ err = PTR_ERR(cancel_filp);
+ if (err != -ENOENT)
+ pr_err("%s: Can't open cancelation file\n", __func__);
+ set_fs(old_fs);
+ return err;
+ }
+
+ err = cancel_filp->f_op->read(cancel_filp,
+ (char *)&data->cal_data, sizeof(u8), &cancel_filp->f_pos);
+ if (err != sizeof(u8)) {
+ pr_err("%s: Can't read the cancel data from file\n", __func__);
+ err = -EIO;
+ }
+
+ if (data->cal_data != 0) {/*If there is an offset cal data. */
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ if (is_gp2a030a()) {
+ gp2a_original_image_030a[5][1] =
+ data->default_threshold + data->cal_data;
+ gp2a_original_image_030a[3][1] =
+ data->default_threshold
+ + data->cal_data - DEFAULT_THRESHOLD_DIFF;
+ }
+#else
+ if (is_gp2a030a())
+ gp2a_original_image_030a[3][1] =
+ data->default_threshold + data->cal_data;
+
+#endif
+ else
+ gp2a_original_image[3][1] =
+ data->default_threshold + data->cal_data;
+
+ pr_info("%s: prox_cal = %d, prox_thresh = 0x%x\n",
+ __func__, data->cal_data, (is_gp2a030a() ?
+ gp2a_original_image_030a[3][1] :
+ gp2a_original_image[3][1]));
+ }
+
+ filp_close(cancel_filp, current->files);
+ set_fs(old_fs);
+
+ return err;
+}
+
+static int proximity_store_calibration(struct device *dev, bool do_calib)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ struct file *cancel_filp = NULL;
+ mm_segment_t old_fs;
+ int err = 0;
+ u8 thresh_x;
+
+ if (do_calib) {
+ gp2a->cal_data = proximity_adc_read(gp2a);
+ if (is_gp2a030a()) {
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ gp2a_original_image_030a[3][1] = gp2a->cal_data+XTALK;
+ gp2a->cal_data = gp2a_original_image_030a[3][1]-THDL;
+#else
+ /* if x-talk + 8 > threshold, threhold = x-talk + 8 */
+ /* LTH = threshold - thresh_diff */
+ thresh_x = gp2a->cal_data + 8 - gp2a->thresh_diff;
+
+ if (thresh_x > gp2a_original_image_030a[3][1])
+ gp2a_original_image_030a[3][1]= thresh_x;
+#endif
+ }
+ else
+ gp2a_original_image[3][1] += gp2a->cal_data;
+ } else { /* reset */
+ gp2a->cal_data = 0;
+ if (is_gp2a030a())
+ gp2a_original_image_030a[3][1] =
+ gp2a->default_threshold;
+ else
+ gp2a_original_image[3][1] = gp2a->default_threshold;
+ }
+
+ /* Update cal data. */
+ gp2a_update_threshold(gp2a, is_gp2a030a() ?
+ gp2a_original_image_030a : gp2a_original_image,
+ (is_gp2a030a() ?
+ gp2a_original_image_030a[3][1] :
+ gp2a_original_image[3][1]), true);
+
+ pr_info("%s: prox_cal = %d, prox_thresh = 0x%x\n",
+ __func__, gp2a->cal_data, (is_gp2a030a() ?
+ gp2a_original_image_030a[3][1] :
+ gp2a_original_image[3][1]));
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ cancel_filp = filp_open(CALIBRATION_FILE_PATH,
+ O_CREAT | O_TRUNC | O_WRONLY | O_SYNC, 0666);
+ if (IS_ERR(cancel_filp)) {
+ pr_err("%s: Can't open cancelation file\n", __func__);
+ set_fs(old_fs);
+ err = PTR_ERR(cancel_filp);
+ return err;
+ }
+
+ err = cancel_filp->f_op->write(cancel_filp,
+ (char *)&gp2a->cal_data, sizeof(u8), &cancel_filp->f_pos);
+ if (err != sizeof(u8)) {
+ pr_err("%s: Can't write the cancel data to file\n", __func__);
+ err = -EIO;
+ }
+
+ filp_close(cancel_filp, current->files);
+ set_fs(old_fs);
+
+ return err;
+}
+
static ssize_t proximity_cal_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct gp2a_data *data = dev_get_drvdata(dev);
- int thresh_hi;
- unsigned char get_D2_data[2];
-
- msleep(20);
- opt_i2c_read(PS_HT_LSB, get_D2_data, sizeof(get_D2_data));
- thresh_hi = (get_D2_data[1] << 8) | get_D2_data[0];
- data->threshold_high = thresh_hi;
- return sprintf(buf, "%d,%d\n",
- data->offset_value, data->threshold_high);
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ return sprintf(buf, "%d,%d\n", data->cal_data,
+ gp2a_original_image_030a[5][1]);
+#else
+ return sprintf(buf, "%d,%d\n", data->cal_data, (is_gp2a030a() ?
+ gp2a_original_image_030a[5][1] :
+ gp2a_original_image[5][1]));
+#endif
}
static ssize_t proximity_cal_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
- struct gp2a_data *data = dev_get_drvdata(dev);
bool do_calib;
int err;
- if (sysfs_streq(buf, "1")) { /* calibrate cancelation value */
+ if (sysfs_streq(buf, "1")) /* calibrate cancelation value */
do_calib = true;
- } else if (sysfs_streq(buf, "0")) { /* reset cancelation value */
+ else if (sysfs_streq(buf, "0")) /* reset cancelation value */
do_calib = false;
- } else {
+ else {
pr_err("%s: invalid value %d\n", __func__, *buf);
- err = -EINVAL;
- goto done;
+ return -EINVAL;
}
- err = proximity_do_calibrate(data, do_calib, false);
+
+ err = proximity_store_calibration(dev, do_calib);
if (err < 0) {
- pr_err("%s: proximity_store_offset() failed\n", __func__);
- goto done;
+ pr_err("%s: proximity_store_calibration() failed\n", __func__);
+ return err;
}
-done:
- return err;
+
+ return size;
}
+static ssize_t proximity_thresh_diff_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", gp2a->thresh_diff);
+}
+
+static ssize_t proximity_thresh_diff_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct gp2a_data *gp2a = dev_get_drvdata(dev);
+ struct gp2a_platform_data *pdata = gp2a->pdata;
+ u8 threshold_diff = 0;
+ int err;
+
+ err = kstrtou8(buf, 10, &threshold_diff);
+ if (err) {
+ pr_err("%s, conversion %s to number.\n",
+ __func__, buf);
+ return err;
+ }
+
+ if ((threshold_diff > 0) && (threshold_diff < 5)) { /* update diff */
+ gp2a->thresh_diff = threshold_diff;
+ } else if (threshold_diff == 0) { /* reset to default */
+ pdata->gp2a_get_threshold(&gp2a->thresh_diff);
+ } else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ gp2a_update_threshold(gp2a, is_gp2a030a() ?
+ gp2a_original_image_030a : gp2a_original_image,
+ (is_gp2a030a() ?
+ gp2a_original_image_030a[3][1] :
+ gp2a_original_image[3][1]), true);
+
+ return size;
+}
+#endif
+
static DEVICE_ATTR(enable, 0664, proximity_enable_show, proximity_enable_store);
static DEVICE_ATTR(prox_avg, 0664, proximity_avg_show, proximity_avg_store);
static DEVICE_ATTR(state, 0664, proximity_state_show, NULL);
-static DEVICE_ATTR(prox_thresh, S_IRUGO | S_IWUSR,
+static DEVICE_ATTR(prox_thresh, 0664,
proximity_thresh_show, proximity_thresh_store);
-static DEVICE_ATTR(prox_cal, 0664, proximity_cal_show, proximity_cal_store);
+#ifdef GP2A_CALIBRATION
+static DEVICE_ATTR(prox_cal, 0664,
+ proximity_cal_show, proximity_cal_store);
+static DEVICE_ATTR(prox_diff, 0664,
+ proximity_thresh_diff_show, proximity_thresh_diff_store);
+#endif
static struct attribute *proximity_attributes[] = {
&dev_attr_enable.attr,
@@ -715,7 +750,6 @@ static ssize_t proximity_raw_data_show(struct device *dev,
unsigned char get_D2_data[2] = { 0, };
struct gp2a_data *data = dev_get_drvdata(dev);
- msleep(20);
mutex_lock(&data->data_mutex);
opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
mutex_unlock(&data->data_mutex);
@@ -735,11 +769,10 @@ static void proxsensor_get_avgvalue(struct gp2a_data *data)
u8 proximity_value = 0;
unsigned char get_D2_data[2] = { 0, };
- mutex_lock(&data->data_mutex);
-
for (i = 0; i < PROX_READ_NUM; i++) {
- msleep(20);
+ mutex_lock(&data->data_mutex);
opt_i2c_read(0x10, get_D2_data, sizeof(get_D2_data));
+ mutex_unlock(&data->data_mutex);
proximity_value = (get_D2_data[1] << 8) | get_D2_data[0];
avg += proximity_value;
@@ -751,7 +784,6 @@ static void proxsensor_get_avgvalue(struct gp2a_data *data)
if (proximity_value > max)
max = proximity_value;
}
- mutex_unlock(&data->data_mutex);
avg /= PROX_READ_NUM;
data->average[0] = min;
@@ -901,7 +933,7 @@ static void gp2a_work_func_prox(struct work_struct *work)
static int opt_i2c_init(void)
{
if (i2c_add_driver(&opt_i2c_driver)) {
- printk(KERN_ERR "i2c_add_driver failed\n");
+ pr_info("i2c_add_driver failed\n");
return -ENODEV;
}
return 0;
@@ -911,16 +943,13 @@ int opt_i2c_read(u8 reg, unsigned char *rbuf, int len)
{
int ret = -1;
struct i2c_msg msg;
- /*int i;*/
if ((opt_i2c_client == NULL) || (!opt_i2c_client->adapter)) {
- printk(KERN_ERR "%s %d (opt_i2c_client == NULL)\n",
+ pr_err("%s %d (opt_i2c_client == NULL)\n",
__func__, __LINE__);
return -ENODEV;
}
- /*gprintk("register num : 0x%x\n", reg); */
-
msg.addr = opt_i2c_client->addr;
msg.flags = I2C_M_WR;
msg.len = 1;
@@ -936,12 +965,9 @@ int opt_i2c_read(u8 reg, unsigned char *rbuf, int len)
}
if (ret < 0)
- printk(KERN_ERR "%s, i2c transfer error ret=%d\n"\
+ pr_err("%s, i2c transfer error ret=%d\n"\
, __func__, ret);
- /* for (i=0;i<len;i++)
- gprintk("0x%x, 0x%x\n", reg++,rbuf[i]); */
-
return ret;
}
@@ -970,7 +996,7 @@ int opt_i2c_write(u8 reg, u8 *val)
if (err >= 0)
return 0;
}
- printk(KERN_ERR "%s, i2c transfer error(%d)\n", __func__, err);
+ pr_err("%s, i2c transfer error(%d)\n", __func__, err);
return err;
}
@@ -982,7 +1008,7 @@ static int proximity_input_init(struct gp2a_data *data)
data->input_dev = input_allocate_device();
if (!data->input_dev) {
- printk(KERN_ERR "%s, error\n", __func__);
+ pr_err("%s, error\n", __func__);
return -ENOMEM;
}
@@ -1021,14 +1047,9 @@ static int gp2a_opt_probe(struct platform_device *pdev)
return err;
}
/* gp2a power on */
+#if !defined(CONFIG_MACH_TAB3) || !defined(CONFIG_MACH_GC2PD)
pdata->gp2a_led_on(true);
-
- if (pdata->gp2a_get_threshold) {
- gp2a_update_threshold(is_gp2a030a() ?
- gp2a_original_image_030a : gp2a_original_image,
- pdata->gp2a_get_threshold(), false);
- }
-
+#endif
/* allocate driver_data */
gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
if (!gp2a) {
@@ -1036,10 +1057,35 @@ static int gp2a_opt_probe(struct platform_device *pdev)
return -ENOMEM;
}
- proximity_enable = 0;
+#ifdef CONFIG_SLP
+ gp2a->thresh_diff = DEFAULT_THRESHOLD_DIFF;
+#endif
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ gp2a->thresh_diff = DEFAULT_THRESHOLD_DIFF;
+#else
+ if (pdata->gp2a_get_threshold)
+ gp2a_update_threshold(gp2a, is_gp2a030a() ?
+ gp2a_original_image_030a : gp2a_original_image,
+ pdata->gp2a_get_threshold(&gp2a->thresh_diff), false);
+ else
+ gp2a->thresh_diff = DEFAULT_THRESHOLD_DIFF;
+#endif
+#ifdef GP2A_CALIBRATION
+#if defined(CONFIG_MACH_KONA_SENSOR)
+ gp2a->default_threshold = (is_gp2a030a() ?
+ gp2a_original_image_030a[5][1] :
+ gp2a_original_image[5][1]);
+#else
+ gp2a->default_threshold = (is_gp2a030a() ?
+ gp2a_original_image_030a[3][1] :
+ gp2a_original_image[3][1]);
+#endif
+#endif
+
+ gp2a->enabled = 0;
+
proximity_sensor_detection = 0;
proximity_avg_on = 0;
- gp2a->enabled = 0;
gp2a->pdata = pdata;
/* prox_timer settings. we poll for prox_avg values using a timer. */
@@ -1082,9 +1128,19 @@ static int gp2a_opt_probe(struct platform_device *pdev)
pr_err("opt_probe failed : i2c_client is NULL\n");
goto err_no_device;
} else
- printk(KERN_INFO "opt_i2c_client : (0x%p), address = %x\n",
+ pr_info("opt_i2c_client : (0x%p), address = %x\n",
opt_i2c_client, opt_i2c_client->addr);
+#ifdef CONFIG_SENSORS_GP2A_VDD_CONTROL
+ /* gp2a power on */
+ if (pdata->gp2a_vdd_on) {
+ pdata->gp2a_vdd_on(true);
+ pr_info("%s, power : %d\n", __func__, gp2a-->power_state);
+ }
+ gp2a->power_state |= LIGHT_ENABLED;
+ msleep(20);
+#endif
+
/* GP2A Regs INIT SETTINGS and Check I2C communication */
value = 0x00;
/* shutdown mode op[3]=0 */
@@ -1148,12 +1204,20 @@ static int gp2a_opt_probe(struct platform_device *pdev)
goto err_proximity_device_create_file6;
}
+#ifdef GP2A_CALIBRATION
if (device_create_file(gp2a->proximity_dev, &dev_attr_prox_cal) < 0) {
pr_err("%s: could not create device file(%s)!\n", __func__,
dev_attr_prox_cal.attr.name);
goto err_proximity_device_create_file7;
}
+ if (device_create_file(gp2a->proximity_dev, &dev_attr_prox_diff) < 0) {
+ pr_err("%s: could not create device file(%s)!\n", __func__,
+ dev_attr_prox_diff.attr.name);
+ goto err_proximity_device_create_file8;
+ }
+#endif
+
#ifdef CONFIG_SLP
device_init_wakeup(gp2a->proximity_dev, true);
#endif
@@ -1165,14 +1229,18 @@ static int gp2a_opt_probe(struct platform_device *pdev)
return 0;
-err_proximity_device_create_file7:
+#ifdef GP2A_CALIBRATION
+err_proximity_device_create_file8:
device_remove_file(gp2a->proximity_dev, &dev_attr_prox_cal);
-err_proximity_device_create_file6:
+err_proximity_device_create_file7:
device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data);
-err_proximity_device_create_file5:
+#endif
+err_proximity_device_create_file6:
device_remove_file(gp2a->proximity_dev, &dev_attr_name);
-err_proximity_device_create_file4:
+err_proximity_device_create_file5:
device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
+err_proximity_device_create_file4:
+ device_remove_file(gp2a->proximity_dev, &dev_attr_prox_thresh);
err_proximity_device_create_file3:
device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file2:
@@ -1201,19 +1269,20 @@ static int gp2a_opt_remove(struct platform_device *pdev)
struct gp2a_data *gp2a = platform_get_drvdata(pdev);
if (gp2a == NULL) {
- printk(KERN_ERR "%s, gp2a_data is NULL!!!!!\n", __func__);
+ pr_err("%s, gp2a_data is NULL!!!!!\n", __func__);
return -1;
}
if (gp2a->enabled) {
disable_irq(gp2a->irq);
- proximity_enable = 0;
+ gp2a->enabled = 0;
+
proximity_onoff(0);
disable_irq_wake(gp2a->irq);
-#ifndef CONFIG_MACH_MIDAS_02_BD
+#if !defined(CONFIG_MACH_MIDAS_02_BD)
gp2a->pdata->gp2a_led_on(false);
+ gp2a->power_state = 0;
#endif
- gp2a->enabled = 0;
}
hrtimer_cancel(&gp2a->prox_timer);
@@ -1228,6 +1297,10 @@ static int gp2a_opt_remove(struct platform_device *pdev)
device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
device_remove_file(gp2a->proximity_dev, &dev_attr_name);
device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data);
+#ifdef GP2A_CALIBRATION
+ device_remove_file(gp2a->proximity_dev, &dev_attr_prox_cal);
+ device_remove_file(gp2a->proximity_dev, &dev_attr_prox_diff);
+#endif
sensors_classdev_unregister(gp2a->proximity_dev);
if (gp2a->input_dev != NULL) {
@@ -1274,6 +1347,7 @@ static int gp2a_opt_resume(struct platform_device *pdev)
gprintk("\n");
if (gp2a->enabled) {
+
if (device_may_wakeup(&pdev->dev))
enable_irq_wake(gp2a->irq);
}
@@ -1308,8 +1382,7 @@ static int proximity_onoff(u8 onoff)
opt_i2c_write(gp2a_original_image[i][0],
&gp2a_original_image[i][1]);
if (err < 0)
- printk(KERN_ERR
- "%s : turnning on error i = %d, err=%d\n",
+ pr_err("%s : turnning on error i = %d, err=%d\n",
__func__, i, err);
lightsensor_mode = 0;
}
@@ -1342,7 +1415,7 @@ static int opt_i2c_probe(struct i2c_client *client,
gprintk("start!!!\n");
if (client == NULL)
- printk(KERN_ERR "GP2A i2c client is NULL !!!\n");
+ pr_err("GP2A i2c client is NULL !!!\n");
opt_i2c_client = client;
gprintk("end!!!\n");
diff --git a/drivers/sensor/k3dh_kona.c b/drivers/sensor/k3dh_kona.c
new file mode 100644
index 0000000..04e1f8b
--- /dev/null
+++ b/drivers/sensor/k3dh_kona.c
@@ -0,0 +1,1080 @@
+/*
+ * STMicroelectronics k3dh acceleration sensor driver
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/sensor/sensors_core.h>
+#include <linux/sensor/k3dh.h>
+#include "k3dh_reg.h"
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+#include <linux/input.h>
+#endif
+
+/* For Debugging */
+#if 1
+#define k3dh_dbgmsg(str, args...) pr_debug("%s: " str, __func__, ##args)
+#endif
+#define k3dh_infomsg(str, args...) pr_info("%s: " str, __func__, ##args)
+
+#define VENDOR "STM"
+#define CHIP_ID "K3DH"
+
+/* The default settings when sensor is on is for all 3 axis to be enabled
+ * and output data rate set to 400Hz. Output is via a ioctl read call.
+ */
+#define DEFAULT_POWER_ON_SETTING (ODR400 | ENABLE_ALL_AXES)
+#define ACC_DEV_MAJOR 241
+
+#define CALIBRATION_FILE_PATH "/efs/calibration_data"
+#define CAL_DATA_AMOUNT 20
+
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+/* ABS axes parameter range [um/s^2] (for input event) */
+#define GRAVITY_EARTH 9806550
+#define ABSMAX_2G (GRAVITY_EARTH * 2)
+#define ABSMIN_2G (-GRAVITY_EARTH * 2)
+#define MIN_DELAY 5
+#define MAX_DELAY 200
+#endif
+
+static const struct odr_delay {
+ u8 odr; /* odr reg setting */
+ s64 delay_ns; /* odr in ns */
+} odr_delay_table[] = {
+ { ODR1344, 744047LL }, /* 1344Hz */
+ { ODR400, 2500000LL }, /* 400Hz */
+ { ODR200, 5000000LL }, /* 200Hz */
+ { ODR100, 10000000LL }, /* 100Hz */
+ { ODR50, 20000000LL }, /* 50Hz */
+ { ODR25, 40000000LL }, /* 25Hz */
+ { ODR10, 100000000LL }, /* 10Hz */
+ { ODR1, 1000000000LL }, /* 1Hz */
+};
+
+/* K3DH acceleration data */
+struct k3dh_acc {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct k3dh_data {
+ struct i2c_client *client;
+ struct miscdevice k3dh_device;
+ struct mutex read_lock;
+ struct mutex write_lock;
+ struct completion data_ready;
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+ struct class *acc_class;
+#else
+ struct device *dev;
+#endif
+ struct k3dh_acc cal_data;
+ struct k3dh_acc acc_xyz;
+ u8 ctrl_reg1_shadow;
+ atomic_t opened; /* opened implies enabled */
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+ struct input_dev *input;
+ struct delayed_work work;
+ atomic_t delay;
+ atomic_t enable;
+#endif
+ bool axis_adjust;
+ int position;
+};
+
+static struct k3dh_data *g_k3dh;
+
+
+static void k3dh_xyz_position_adjust(struct k3dh_acc *acc,
+ int position)
+{
+ const int position_map[][3][3] = {
+ {{ 0, 1, 0}, {-1, 0, 0}, { 0, 0, 1} }, /* 0 top/upper-left */
+ {{-1, 0, 0}, { 0, -1, 0}, { 0, 0, 1} }, /* 1 top/upper-right */
+ {{ 0, -1, 0}, { 1, 0, 0}, { 0, 0, 1} }, /* 2 top/lower-right */
+ {{ 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1} }, /* 3 top/lower-left */
+ {{ 0, -1, 0}, {-1, 0, 0}, { 0, 0, -1} }, /* 4 bottom/upper-left */
+ {{ 1, 0, 0}, { 0, -1, 0}, { 0, 0, -1} }, /* 5 bottom/upper-right */
+ {{ 0, 1, 0}, { 1, 0, 0}, { 0, 0, -1} }, /* 6 bottom/lower-right */
+ {{-1, 0, 0}, { 0, 1, 0}, { 0, 0, -1} }, /* 7 bottom/lower-left*/
+ };
+
+ struct k3dh_acc xyz_adjusted = {0,};
+ s16 raw[3] = {0,};
+ int j;
+ raw[0] = acc->x;
+ raw[1] = acc->y;
+ raw[2] = acc->z;
+ for (j = 0; j < 3; j++) {
+ xyz_adjusted.x +=
+ (position_map[position][0][j] * raw[j]);
+ xyz_adjusted.y +=
+ (position_map[position][1][j] * raw[j]);
+ xyz_adjusted.z +=
+ (position_map[position][2][j] * raw[j]);
+ }
+ acc->x = xyz_adjusted.x;
+ acc->y = xyz_adjusted.y;
+ acc->z = xyz_adjusted.z;
+}
+
+/* Read X,Y and Z-axis acceleration raw data */
+static int k3dh_read_accel_raw_xyz(struct k3dh_data *data,
+ struct k3dh_acc *acc)
+{
+ int err;
+ s8 reg = OUT_X_L | AC; /* read from OUT_X_L to OUT_Z_H by auto-inc */
+ u8 acc_data[6];
+
+ err = i2c_smbus_read_i2c_block_data(data->client, reg,
+ sizeof(acc_data), acc_data);
+ if (err != sizeof(acc_data)) {
+ pr_err("%s : failed to read 6 bytes for getting x/y/z\n",
+ __func__);
+ return -EIO;
+ }
+
+ acc->x = (acc_data[1] << 8) | acc_data[0];
+ acc->y = (acc_data[3] << 8) | acc_data[2];
+ acc->z = (acc_data[5] << 8) | acc_data[4];
+
+ acc->x = acc->x >> 4;
+ acc->y = acc->y >> 4;
+
+#if defined(CONFIG_MACH_U1_NA_SPR_REV05) \
+ || defined(CONFIG_MACH_U1_NA_SPR_EPIC2_REV00) \
+ || defined(CONFIG_MACH_U1_NA_USCC_REV05) \
+ || defined(CONFIG_MACH_Q1_BD) \
+ || defined(CONFIG_MACH_U1_NA_USCC) \
+ || defined(CONFIG_MACH_U1_NA_SPR)
+ acc->z = -acc->z >> 4;
+#else
+ acc->z = acc->z >> 4;
+#endif
+
+ if (data->axis_adjust)
+ k3dh_xyz_position_adjust(acc, data->position);
+ return 0;
+}
+
+static int k3dh_read_accel_xyz(struct k3dh_data *data,
+ struct k3dh_acc *acc)
+{
+ int err = 0;
+
+ mutex_lock(&data->read_lock);
+ err = k3dh_read_accel_raw_xyz(data, acc);
+ mutex_unlock(&data->read_lock);
+ if (err < 0) {
+ pr_err("%s: k3dh_read_accel_raw_xyz() failed\n", __func__);
+ return err;
+ }
+
+ acc->x -= data->cal_data.x;
+ acc->y -= data->cal_data.y;
+ acc->z -= data->cal_data.z;
+
+ return err;
+}
+
+static int k3dh_open_calibration(struct k3dh_data *data)
+{
+ struct file *cal_filp = NULL;
+ int err = 0;
+ mm_segment_t old_fs;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ cal_filp = filp_open(CALIBRATION_FILE_PATH, O_RDONLY, 0666);
+ if (IS_ERR(cal_filp)) {
+ err = PTR_ERR(cal_filp);
+ if (err != -ENOENT)
+ pr_err("%s: Can't open calibration file\n", __func__);
+ set_fs(old_fs);
+ return err;
+ }
+
+ err = cal_filp->f_op->read(cal_filp,
+ (char *)&data->cal_data, 3 * sizeof(s16), &cal_filp->f_pos);
+ if (err != 3 * sizeof(s16)) {
+ pr_err("%s: Can't read the cal data from file\n", __func__);
+ err = -EIO;
+ }
+
+ k3dh_dbgmsg("%s: (%u,%u,%u)\n", __func__,
+ data->cal_data.x, data->cal_data.y, data->cal_data.z);
+
+ filp_close(cal_filp, current->files);
+ set_fs(old_fs);
+
+ return err;
+}
+
+static int k3dh_do_calibrate(struct device *dev, bool do_calib)
+{
+ struct k3dh_data *acc_data = dev_get_drvdata(dev);
+ struct k3dh_acc data = { 0, };
+ struct file *cal_filp = NULL;
+ int sum[3] = { 0, };
+ int err = 0;
+ int i;
+ mm_segment_t old_fs;
+
+ if (do_calib) {
+ for (i = 0; i < CAL_DATA_AMOUNT; i++) {
+ mutex_lock(&acc_data->read_lock);
+ err = k3dh_read_accel_raw_xyz(acc_data, &data);
+ mutex_unlock(&acc_data->read_lock);
+ if (err < 0) {
+ pr_err("%s: k3dh_read_accel_raw_xyz() "
+ "failed in the %dth loop\n",
+ __func__, i);
+ return err;
+ }
+
+ sum[0] += data.x;
+ sum[1] += data.y;
+ sum[2] += data.z;
+ }
+
+ acc_data->cal_data.x = sum[0] / CAL_DATA_AMOUNT;
+ acc_data->cal_data.y = sum[1] / CAL_DATA_AMOUNT;
+ if (sum[2] >= 0)
+ acc_data->cal_data.z = (sum[2] / CAL_DATA_AMOUNT)-1024;
+ else
+ acc_data->cal_data.z = (sum[2] / CAL_DATA_AMOUNT)+1024;
+ } else {
+ acc_data->cal_data.x = 0;
+ acc_data->cal_data.y = 0;
+ acc_data->cal_data.z = 0;
+ }
+
+ printk(KERN_INFO "%s: cal data (%d,%d,%d)\n", __func__,
+ acc_data->cal_data.x, acc_data->cal_data.y, acc_data->cal_data.z);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ cal_filp = filp_open(CALIBRATION_FILE_PATH,
+ O_CREAT | O_TRUNC | O_WRONLY, 0666);
+ if (IS_ERR(cal_filp)) {
+ pr_err("%s: Can't open calibration file\n", __func__);
+ set_fs(old_fs);
+ err = PTR_ERR(cal_filp);
+ return err;
+ }
+
+ err = cal_filp->f_op->write(cal_filp,
+ (char *)&acc_data->cal_data, 3 * sizeof(s16), &cal_filp->f_pos);
+ if (err != 3 * sizeof(s16)) {
+ pr_err("%s: Can't write the cal data to file\n", __func__);
+ err = -EIO;
+ }
+
+ filp_close(cal_filp, current->files);
+ set_fs(old_fs);
+
+ return err;
+}
+
+static int k3dh_accel_enable(struct k3dh_data *data)
+{
+ int err = 0;
+
+ if (atomic_read(&data->opened) == 0) {
+ err = k3dh_open_calibration(data);
+ if (err < 0 && err != -ENOENT)
+ pr_err("%s: k3dh_open_calibration() failed\n",
+ __func__);
+ data->ctrl_reg1_shadow = DEFAULT_POWER_ON_SETTING;
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ DEFAULT_POWER_ON_SETTING);
+ if (err)
+ pr_err("%s: i2c write ctrl_reg1 failed\n", __func__);
+
+#if defined(CONFIG_SENSORS_K2DH)
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG4,
+ CTRL_REG4_HR | CTRL_REG4_BDU);
+#else
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG4,
+ CTRL_REG4_HR);
+#endif
+ if (err)
+ pr_err("%s: i2c write ctrl_reg4 failed\n", __func__);
+ }
+
+ atomic_add(1, &data->opened);
+
+ return err;
+}
+
+static int k3dh_accel_disable(struct k3dh_data *data)
+{
+ int err = 0;
+
+ atomic_sub(1, &data->opened);
+ if (atomic_read(&data->opened) == 0) {
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ PM_OFF);
+ data->ctrl_reg1_shadow = PM_OFF;
+ }
+
+ return err;
+}
+
+/* open command for K3DH device file */
+static int k3dh_open(struct inode *inode, struct file *file)
+{
+ k3dh_infomsg("is called.\n");
+ return 0;
+}
+
+/* release command for K3DH device file */
+static int k3dh_close(struct inode *inode, struct file *file)
+{
+ k3dh_infomsg("is called.\n");
+ return 0;
+}
+
+static s64 k3dh_get_delay(struct k3dh_data *data)
+{
+ int i;
+ u8 odr;
+ s64 delay = -1;
+
+ odr = data->ctrl_reg1_shadow & ODR_MASK;
+ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) {
+ if (odr == odr_delay_table[i].odr) {
+ delay = odr_delay_table[i].delay_ns;
+ break;
+ }
+ }
+ return delay;
+}
+
+static int k3dh_set_delay(struct k3dh_data *data, s64 delay_ns)
+{
+ int odr_value = ODR1;
+ int res = 0;
+ int i;
+
+ /* round to the nearest delay that is less than
+ * the requested value (next highest freq)
+ */
+ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) {
+ if (delay_ns < odr_delay_table[i].delay_ns)
+ break;
+ }
+ if (i > 0)
+ i--;
+ odr_value = odr_delay_table[i].odr;
+ delay_ns = odr_delay_table[i].delay_ns;
+
+ k3dh_infomsg("old=%lldns, new=%lldns, odr=0x%x/0x%x\n",
+ k3dh_get_delay(data), delay_ns, odr_value,
+ data->ctrl_reg1_shadow);
+ mutex_lock(&data->write_lock);
+ if (odr_value != (data->ctrl_reg1_shadow & ODR_MASK)) {
+ u8 ctrl = (data->ctrl_reg1_shadow & ~ODR_MASK);
+ ctrl |= odr_value;
+ data->ctrl_reg1_shadow = ctrl;
+ res = i2c_smbus_write_byte_data(data->client, CTRL_REG1, ctrl);
+ }
+ mutex_unlock(&data->write_lock);
+ return res;
+}
+
+/* ioctl command for K3DH device file */
+static long k3dh_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ struct k3dh_data *data = container_of(file->private_data,
+ struct k3dh_data, k3dh_device);
+ s64 delay_ns;
+ int enable = 0;
+
+ /* cmd mapping */
+ switch (cmd) {
+ case K3DH_IOCTL_SET_ENABLE:
+ if (copy_from_user(&enable, (void __user *)arg,
+ sizeof(enable)))
+ return -EFAULT;
+ k3dh_infomsg("opened = %d, enable = %d\n",
+ atomic_read(&data->opened), enable);
+ if (enable)
+ err = k3dh_accel_enable(data);
+ else
+ err = k3dh_accel_disable(data);
+ break;
+ case K3DH_IOCTL_SET_DELAY:
+ if (copy_from_user(&delay_ns, (void __user *)arg,
+ sizeof(delay_ns)))
+ return -EFAULT;
+ err = k3dh_set_delay(data, delay_ns);
+ break;
+ case K3DH_IOCTL_GET_DELAY:
+ delay_ns = k3dh_get_delay(data);
+ if (put_user(delay_ns, (s64 __user *)arg))
+ return -EFAULT;
+ break;
+ case K3DH_IOCTL_READ_ACCEL_XYZ:
+ err = k3dh_read_accel_xyz(data, &data->acc_xyz);
+ if (err)
+ break;
+ if (copy_to_user((void __user *)arg,
+ &data->acc_xyz, sizeof(data->acc_xyz)))
+ return -EFAULT;
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+
+ return err;
+}
+
+static int k3dh_suspend(struct device *dev)
+{
+ int res = 0;
+ struct k3dh_data *data = dev_get_drvdata(dev);
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+ if (atomic_read(&data->enable))
+ cancel_delayed_work_sync(&data->work);
+#endif
+ if (atomic_read(&data->opened) > 0)
+ res = i2c_smbus_write_byte_data(data->client,
+ CTRL_REG1, PM_OFF);
+
+ return res;
+}
+
+static int k3dh_resume(struct device *dev)
+{
+ int res = 0;
+ struct k3dh_data *data = dev_get_drvdata(dev);
+
+ if (atomic_read(&data->opened) > 0)
+ res = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ data->ctrl_reg1_shadow);
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+ if (atomic_read(&data->enable))
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(5));
+#endif
+ return res;
+}
+
+static const struct dev_pm_ops k3dh_pm_ops = {
+ .suspend = k3dh_suspend,
+ .resume = k3dh_resume,
+};
+
+static const struct file_operations k3dh_fops = {
+ .owner = THIS_MODULE,
+ .open = k3dh_open,
+ .release = k3dh_close,
+ .unlocked_ioctl = k3dh_ioctl,
+};
+
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+static ssize_t k3dh_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct k3dh_data *data = input_get_drvdata(input);
+
+ return sprintf(buf, "%d\n", atomic_read(&data->enable));
+}
+
+static ssize_t k3dh_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct k3dh_data *data = input_get_drvdata(input);
+ unsigned long enable = 0;
+ int err;
+
+ if (strict_strtoul(buf, 10, &enable))
+ return -EINVAL;
+ k3dh_open_calibration(data);
+
+ if (enable) {
+ err = k3dh_accel_enable(data);
+ if (err < 0)
+ goto done;
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(5));
+ } else {
+ cancel_delayed_work_sync(&data->work);
+ err = k3dh_accel_disable(data);
+ if (err < 0)
+ goto done;
+ }
+ atomic_set(&data->enable, enable);
+ pr_info("%s, enable = %ld\n", __func__, enable);
+done:
+ return count;
+}
+static DEVICE_ATTR(enable,
+ S_IRUGO | S_IWUSR | S_IWGRP,
+ k3dh_enable_show, k3dh_enable_store);
+
+static ssize_t k3dh_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct k3dh_data *data = input_get_drvdata(input);
+
+ return sprintf(buf, "%d\n", atomic_read(&data->delay));
+}
+
+static ssize_t k3dh_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct k3dh_data *data = input_get_drvdata(input);
+ unsigned long delay = 0;
+ if (strict_strtoul(buf, 10, &delay))
+ return -EINVAL;
+
+ if (delay > MAX_DELAY)
+ delay = MAX_DELAY;
+ if (delay < MIN_DELAY)
+ delay = MIN_DELAY;
+ atomic_set(&data->delay, delay);
+ k3dh_set_delay(data, delay * 1000000);
+ pr_info("%s, delay = %ld\n", __func__, delay);
+ return count;
+}
+static DEVICE_ATTR(poll_delay,
+ S_IRUGO | S_IWUSR | S_IWGRP,
+ k3dh_delay_show, k3dh_delay_store);
+
+static struct attribute *k3dh_attributes[] = {
+ &dev_attr_enable.attr,
+ &dev_attr_poll_delay.attr,
+ NULL
+};
+
+static struct attribute_group k3dh_attribute_group = {
+ .attrs = k3dh_attributes
+};
+#endif
+
+static ssize_t k3dh_fs_read(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct k3dh_data *data = dev_get_drvdata(dev);
+
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+ int err = 0;
+ int on;
+
+ mutex_lock(&data->write_lock);
+ on = atomic_read(&data->opened);
+ if (on == 0) {
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ DEFAULT_POWER_ON_SETTING);
+ }
+ mutex_unlock(&data->write_lock);
+
+ if (err < 0) {
+ pr_err("%s: i2c write ctrl_reg1 failed\n", __func__);
+ return err;
+ }
+
+ err = k3dh_read_accel_xyz(data, &data->acc_xyz);
+ if (err < 0) {
+ pr_err("%s: k3dh_read_accel_xyz failed\n", __func__);
+ return err;
+ }
+
+ if (on == 0) {
+ mutex_lock(&data->write_lock);
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ PM_OFF);
+ mutex_unlock(&data->write_lock);
+ if (err)
+ pr_err("%s: i2c write ctrl_reg1 failed\n", __func__);
+ }
+#endif
+ return sprintf(buf, "%d,%d,%d\n",
+ data->acc_xyz.x, data->acc_xyz.y, data->acc_xyz.z);
+}
+
+static ssize_t k3dh_calibration_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ int err;
+ struct k3dh_data *data = dev_get_drvdata(dev);
+
+ err = k3dh_open_calibration(data);
+ if (err < 0)
+ pr_err("%s: k3dh_open_calibration() failed\n", __func__);
+
+ if (!data->cal_data.x && !data->cal_data.y && !data->cal_data.z)
+ err = -1;
+
+ return sprintf(buf, "%d %d %d %d\n",
+ err, data->cal_data.x, data->cal_data.y, data->cal_data.z);
+}
+
+static ssize_t k3dh_calibration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct k3dh_data *data = dev_get_drvdata(dev);
+ bool do_calib;
+ int err;
+
+ if (sysfs_streq(buf, "1"))
+ do_calib = true;
+ else if (sysfs_streq(buf, "0"))
+ do_calib = false;
+ else {
+ pr_debug("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ if (atomic_read(&data->opened) == 0) {
+ /* if off, turn on the device.*/
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ DEFAULT_POWER_ON_SETTING);
+ if (err) {
+ pr_err("%s: i2c write ctrl_reg1 failed(err=%d)\n",
+ __func__, err);
+ }
+ }
+
+ err = k3dh_do_calibrate(dev, do_calib);
+ if (err < 0) {
+ pr_err("%s: k3dh_do_calibrate() failed\n", __func__);
+ return err;
+ }
+
+ if (atomic_read(&data->opened) == 0) {
+ /* if off, turn on the device.*/
+ err = i2c_smbus_write_byte_data(data->client, CTRL_REG1,
+ PM_OFF);
+ if (err) {
+ pr_err("%s: i2c write ctrl_reg1 failed(err=%d)\n",
+ __func__, err);
+ }
+ }
+
+ return count;
+}
+
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+static DEVICE_ATTR(acc_file, 0664, k3dh_fs_read, NULL);
+#else
+static ssize_t
+k3dh_accel_position_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct k3dh_data *data = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", data->position);
+}
+
+static ssize_t
+k3dh_accel_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct k3dh_data *data = dev_get_drvdata(dev);
+ int err = 0;
+
+ err = kstrtoint(buf, 10, &data->position);
+ if (err < 0)
+ pr_err("%s, kstrtoint failed.", __func__);
+
+ return count;
+}
+
+static ssize_t k3dh_accel_vendor_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", VENDOR);
+}
+
+static ssize_t k3dh_accel_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s\n", CHIP_ID);
+}
+
+static DEVICE_ATTR(name, 0664, k3dh_accel_name_show, NULL);
+static DEVICE_ATTR(vendor, 0664, k3dh_accel_vendor_show, NULL);
+static DEVICE_ATTR(raw_data, 0664, k3dh_fs_read, NULL);
+static DEVICE_ATTR(position, 0664,
+ k3dh_accel_position_show, k3dh_accel_position_store);
+#endif
+static DEVICE_ATTR(calibration, 0664,
+ k3dh_calibration_show, k3dh_calibration_store);
+
+void k3dh_shutdown(struct i2c_client *client)
+{
+ int res = 0;
+ struct k3dh_data *data = i2c_get_clientdata(client);
+
+ k3dh_infomsg("is called.\n");
+
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+ if (atomic_read(&data->enable))
+ cancel_delayed_work_sync(&data->work);
+#endif
+ res = i2c_smbus_write_byte_data(data->client,
+ CTRL_REG1, PM_OFF);
+ if (res < 0)
+ pr_err("%s: pm_off failed %d\n", __func__, res);
+}
+
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+static void k3dh_work_func(struct work_struct *work)
+{
+ k3dh_read_accel_xyz(g_k3dh, &g_k3dh->acc_xyz);
+ pr_debug("%s: x: %d, y: %d, z: %d\n", __func__,
+ g_k3dh->acc_xyz.x, g_k3dh->acc_xyz.y, g_k3dh->acc_xyz.z);
+ input_report_abs(g_k3dh->input, ABS_X, g_k3dh->acc_xyz.x);
+ input_report_abs(g_k3dh->input, ABS_Y, g_k3dh->acc_xyz.y);
+ input_report_abs(g_k3dh->input, ABS_Z, g_k3dh->acc_xyz.z);
+ input_sync(g_k3dh->input);
+ schedule_delayed_work(&g_k3dh->work, msecs_to_jiffies(
+ atomic_read(&g_k3dh->delay)));
+}
+
+/* ----------------- *
+ Input device interface
+ * ------------------ */
+static int k3dh_input_init(struct k3dh_data *data)
+{
+ struct input_dev *dev;
+ int err = 0;
+
+ dev = input_allocate_device();
+ if (!dev)
+ return -ENOMEM;
+ dev->name = "accelerometer";
+ dev->id.bustype = BUS_I2C;
+
+ input_set_capability(dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(dev, ABS_X, ABSMIN_2G, ABSMAX_2G, 0, 0);
+ input_set_abs_params(dev, ABS_Y, ABSMIN_2G, ABSMAX_2G, 0, 0);
+ input_set_abs_params(dev, ABS_Z, ABSMIN_2G, ABSMAX_2G, 0, 0);
+ input_set_drvdata(dev, data);
+
+ err = input_register_device(dev);
+ if (err < 0)
+ goto done;
+ data->input = dev;
+done:
+ return 0;
+}
+#endif
+static int k3dh_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct k3dh_data *data;
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+ struct device *dev_t, *dev_cal;
+#endif
+ struct accel_platform_data *pdata;
+ int err;
+
+ k3dh_infomsg("is started.\n");
+
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK)) {
+ pr_err("%s: i2c functionality check failed!\n", __func__);
+ err = -ENODEV;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct k3dh_data), GFP_KERNEL);
+ if (data == NULL) {
+ dev_err(&client->dev,
+ "failed to allocate memory for module data\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* Checking device */
+ err = i2c_smbus_write_byte_data(client, CTRL_REG1,
+ PM_OFF);
+ if (err) {
+ pr_err("%s: there is no such device, err = %d\n",
+ __func__, err);
+ goto err_read_reg;
+ }
+
+ data->client = client;
+ g_k3dh = data;
+ i2c_set_clientdata(client, data);
+
+ init_completion(&data->data_ready);
+ mutex_init(&data->read_lock);
+ mutex_init(&data->write_lock);
+ atomic_set(&data->opened, 0);
+
+ /* sensor HAL expects to find /dev/accelerometer */
+ data->k3dh_device.minor = MISC_DYNAMIC_MINOR;
+ data->k3dh_device.name = ACC_DEV_NAME;
+ data->k3dh_device.fops = &k3dh_fops;
+
+ err = misc_register(&data->k3dh_device);
+ if (err) {
+ pr_err("%s: misc_register failed\n", __FILE__);
+ goto err_misc_register;
+ }
+
+ pdata = client->dev.platform_data;
+ if (!pdata) {
+ /*Set by default position 3, it doesn't adjust raw value*/
+ data->position = 3;
+ data->axis_adjust = false;
+ pr_err("using defualt position = %d\n", data->position);
+ } else {
+ if (pdata->accel_get_position)
+ data->position = pdata->accel_get_position();
+ data->axis_adjust = pdata->axis_adjust;
+ pr_info("successful, position = %d\n", data->position);
+ }
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+ atomic_set(&data->enable, 0);
+ atomic_set(&data->delay, 200);
+ k3dh_input_init(data);
+
+ /* Setup sysfs */
+ err =
+ sysfs_create_group(&data->input->dev.kobj,
+ &k3dh_attribute_group);
+ if (err < 0)
+ goto err_sysfs_create_group;
+
+ /* Setup driver interface */
+ INIT_DELAYED_WORK(&data->work, k3dh_work_func);
+#endif
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+ /* creating class/device for test */
+ data->acc_class = class_create(THIS_MODULE, "accelerometer");
+ if (IS_ERR(data->acc_class)) {
+ pr_err("%s: class create failed(accelerometer)\n", __func__);
+ err = PTR_ERR(data->acc_class);
+ goto err_class_create;
+ }
+
+ dev_t = device_create(data->acc_class, NULL,
+ MKDEV(ACC_DEV_MAJOR, 0), "%s", "accelerometer");
+ if (IS_ERR(dev_t)) {
+ pr_err("%s: class create failed(accelerometer)\n", __func__);
+ err = PTR_ERR(dev_t);
+ goto err_acc_device_create;
+ }
+
+ err = device_create_file(dev_t, &dev_attr_acc_file);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_acc_file.attr.name);
+ goto err_acc_device_create_file;
+ }
+ dev_set_drvdata(dev_t, data);
+
+ /* creating device for calibration */
+ dev_cal = device_create(sec_class, NULL, 0, NULL, "gsensorcal");
+ if (IS_ERR(dev_cal)) {
+ pr_err("%s: class create failed(gsensorcal)\n", __func__);
+ err = PTR_ERR(dev_cal);
+ goto err_cal_device_create;
+ }
+
+ err = device_create_file(dev_cal, &dev_attr_calibration);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_calibration.attr.name);
+ goto err_cal_device_create_file;
+ }
+ dev_set_drvdata(dev_cal, data);
+#else
+ /* creating device for test & calibration */
+ data->dev = sensors_classdev_register("accelerometer_sensor");
+ if (IS_ERR(data->dev)) {
+ pr_err("%s: class create failed(accelerometer_sensor)\n",
+ __func__);
+ err = PTR_ERR(data->dev);
+ goto err_acc_device_create;
+ }
+
+ err = device_create_file(data->dev, &dev_attr_position);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_position.attr.name);
+ goto err_position_device_create_file;
+ }
+
+ err = device_create_file(data->dev, &dev_attr_raw_data);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_raw_data.attr.name);
+ goto err_acc_device_create_file;
+ }
+
+ err = device_create_file(data->dev, &dev_attr_calibration);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_calibration.attr.name);
+ goto err_cal_device_create_file;
+ }
+
+ err = device_create_file(data->dev, &dev_attr_vendor);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_vendor.attr.name);
+ goto err_vendor_device_create_file;
+ }
+
+ err = device_create_file(data->dev, &dev_attr_name);
+ if (err < 0) {
+ pr_err("%s: Failed to create device file(%s)\n",
+ __func__, dev_attr_name.attr.name);
+ goto err_name_device_create_file;
+ }
+
+ dev_set_drvdata(data->dev, data);
+#endif
+
+ k3dh_infomsg("is successful.\n");
+
+ return 0;
+
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+err_cal_device_create_file:
+ device_destroy(sec_class, 0);
+err_cal_device_create:
+ device_remove_file(dev_t, &dev_attr_acc_file);
+err_acc_device_create_file:
+ device_destroy(data->acc_class, MKDEV(ACC_DEV_MAJOR, 0));
+err_acc_device_create:
+ class_destroy(data->acc_class);
+err_class_create:
+#else
+err_name_device_create_file:
+ device_remove_file(data->dev, &dev_attr_vendor);
+err_vendor_device_create_file:
+ device_remove_file(data->dev, &dev_attr_calibration);
+err_cal_device_create_file:
+ device_remove_file(data->dev, &dev_attr_raw_data);
+err_acc_device_create_file:
+ device_remove_file(data->dev, &dev_attr_position);
+err_position_device_create_file:
+ sensors_classdev_unregister(data->dev);
+
+err_acc_device_create:
+#endif
+#ifdef CONFIG_SENSOR_K3DH_INPUTDEV
+ input_free_device(data->input);
+err_sysfs_create_group:
+#endif
+misc_deregister(&data->k3dh_device);
+err_misc_register:
+ mutex_destroy(&data->read_lock);
+ mutex_destroy(&data->write_lock);
+err_read_reg:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int k3dh_remove(struct i2c_client *client)
+{
+ struct k3dh_data *data = i2c_get_clientdata(client);
+ int err = 0;
+
+ if (atomic_read(&data->opened) > 0) {
+ err = i2c_smbus_write_byte_data(data->client,
+ CTRL_REG1, PM_OFF);
+ if (err < 0)
+ pr_err("%s: pm_off failed %d\n", __func__, err);
+ }
+
+#if defined(CONFIG_MACH_U1) || defined(CONFIG_MACH_TRATS)
+ device_destroy(sec_class, 0);
+ device_destroy(data->acc_class, MKDEV(ACC_DEV_MAJOR, 0));
+ class_destroy(data->acc_class);
+#else
+ device_remove_file(data->dev, &dev_attr_name);
+ device_remove_file(data->dev, &dev_attr_vendor);
+ device_remove_file(data->dev, &dev_attr_calibration);
+ device_remove_file(data->dev, &dev_attr_raw_data);
+ device_remove_file(data->dev, &dev_attr_position);
+ sensors_classdev_unregister(data->dev);
+#endif
+ misc_deregister(&data->k3dh_device);
+ mutex_destroy(&data->read_lock);
+ mutex_destroy(&data->write_lock);
+ kfree(data);
+
+ return 0;
+}
+
+static const struct i2c_device_id k3dh_id[] = {
+ { "k3dh", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, k3dh_id);
+
+static struct i2c_driver k3dh_driver = {
+ .probe = k3dh_probe,
+ .shutdown = k3dh_shutdown,
+ .remove = __devexit_p(k3dh_remove),
+ .id_table = k3dh_id,
+ .driver = {
+ .pm = &k3dh_pm_ops,
+ .owner = THIS_MODULE,
+ .name = "k3dh",
+ },
+};
+
+static int __init k3dh_init(void)
+{
+ return i2c_add_driver(&k3dh_driver);
+}
+
+static void __exit k3dh_exit(void)
+{
+ i2c_del_driver(&k3dh_driver);
+}
+
+module_init(k3dh_init);
+module_exit(k3dh_exit);
+
+MODULE_DESCRIPTION("k3dh accelerometer driver");
+MODULE_AUTHOR("Samsung Electronics");
+MODULE_LICENSE("GPL");
diff --git a/drivers/sensor/k3dh_reg.h b/drivers/sensor/k3dh_reg.h
index 846d0d7..e6c9fa4 100644
--- a/drivers/sensor/k3dh_reg.h
+++ b/drivers/sensor/k3dh_reg.h
@@ -102,6 +102,7 @@
#define I1_OVERRUN (1 << 1)
/* CTRL_REG4 */
+#define CTRL_REG4_BDU (1 << 7)
#define CTRL_REG4_BLE (1 << 6)
#define CTRL_REG4_FS1 (1 << 5)
#define CTRL_REG4_FS0 (1 << 4)
diff --git a/drivers/sensor/yas_mag_driver-yas532.c b/drivers/sensor/yas_mag_driver-yas532.c
new file mode 100644
index 0000000..14259b8
--- /dev/null
+++ b/drivers/sensor/yas_mag_driver-yas532.c
@@ -0,0 +1,2909 @@
+/*
+ * Copyright (c) 2010-2011 Yamaha Corporation
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <linux/sensor/yas.h>
+
+struct utimeval {
+ int32_t tv_sec;
+ int32_t tv_msec;
+};
+
+struct utimer {
+ struct utimeval prev_time;
+ struct utimeval total_time;
+ struct utimeval delay_ms;
+};
+
+static int utimeval_init(struct utimeval *val);
+static int utimeval_is_initial(struct utimeval *val);
+static int utimeval_is_overflow(struct utimeval *val);
+static struct utimeval utimeval_plus(struct utimeval *first,
+ struct utimeval *second);
+static struct utimeval utimeval_minus(struct utimeval *first,
+ struct utimeval *second);
+static int utimeval_greater_than(struct utimeval *first,
+ struct utimeval *second);
+static int utimeval_greater_or_equal(struct utimeval *first,
+ struct utimeval *second);
+static int utimeval_greater_than_zero(struct utimeval *val);
+static int utimeval_less_than_zero(struct utimeval *val);
+static struct utimeval *msec_to_utimeval(struct utimeval *result,
+ uint32_t msec);
+static uint32_t utimeval_to_msec(struct utimeval *val);
+
+static struct utimeval utimer_calc_next_time(struct utimer *ut,
+ struct utimeval *cur);
+static struct utimeval utimer_current_time(void);
+static int utimer_is_timeout(struct utimer *ut);
+static int utimer_clear_timeout(struct utimer *ut);
+static uint32_t utimer_get_total_time(struct utimer *ut);
+static uint32_t utimer_get_delay(struct utimer *ut);
+static int utimer_set_delay(struct utimer *ut, uint32_t delay_ms);
+static int utimer_update(struct utimer *ut);
+static int utimer_update_with_curtime(struct utimer *ut, struct utimeval *cur);
+static uint32_t utimer_sleep_time(struct utimer *ut);
+static uint32_t utimer_sleep_time_with_curtime(struct utimer *ut,
+ struct utimeval *cur);
+static int utimer_init(struct utimer *ut, uint32_t delay_ms);
+static int utimer_clear(struct utimer *ut);
+static void utimer_lib_init(void (*func) (int *sec, int *msec));
+
+#define YAS_REGADDR_DEVICE_ID (0x80)
+#define YAS_REGADDR_ACTUATE_INIT_COIL (0x81)
+#define YAS_REGADDR_MEASURE_COMMAND (0x82)
+#define YAS_REGADDR_CONFIG (0x83)
+#define YAS_REGADDR_MEASURE_INTERVAL (0x84)
+#define YAS_REGADDR_OFFSET_X (0x85)
+#define YAS_REGADDR_OFFSET_Y1 (0x86)
+#define YAS_REGADDR_OFFSET_Y2 (0x87)
+#define YAS_REGADDR_TEST1 (0x88)
+#define YAS_REGADDR_TEST2 (0x89)
+#define YAS_REGADDR_CAL (0x90)
+#define YAS_REGADDR_MEASURE_DATA (0xb0)
+#define YAS_YAS530_DEVICE_ID (0x01) /* YAS530 (MS-3E) */
+#define YAS_YAS530_VERSION_A (0) /* YAS530 (MS-3E Aver) */
+#define YAS_YAS530_VERSION_B (1) /* YAS530B (MS-3E Bver) */
+#define YAS_YAS530_VERSION_A_COEF (380)
+#define YAS_YAS530_VERSION_B_COEF (550)
+#define YAS_YAS530_DATA_CENTER (2048)
+#define YAS_YAS530_DATA_OVERFLOW (4095)
+
+#define YAS_YAS532_DEVICE_ID (0x02) /* YAS532 (MS-3R) */
+#define YAS_YAS532_VERSION_AB (0) /* YAS532AB (MS-3R ABver) */
+#define YAS_YAS532_VERSION_AC (1) /* YAS532AC (MS-3R ACver) */
+#define YAS_YAS532_VERSION_AB_COEF (1800)
+#define YAS_YAS532_VERSION_AC_COEF (900)
+#define YAS_YAS532_DATA_CENTER (4096)
+#define YAS_YAS532_DATA_OVERFLOW (8190)
+
+#undef YAS_YAS530_CAL_SINGLE_READ
+
+struct yas_machdep_func {
+ int (*device_open) (void);
+ int (*device_close) (void);
+ int (*device_write) (uint8_t addr, const uint8_t *buf, int len);
+ int (*device_read) (uint8_t addr, uint8_t *buf, int len);
+ void (*msleep) (int msec);
+};
+
+static int yas_cdrv_actuate_initcoil(void);
+static int yas_cdrv_set_offset(const int8_t *offset);
+static int yas_cdrv_recalc_calib_offset(int32_t *prev_calib_offset,
+ int32_t *new_calib_offset,
+ int8_t *prev_offset,
+ int8_t *new_offset);
+static int yas_cdrv_set_transformatiom_matrix(const int8_t *transform);
+static int yas_cdrv_measure_and_set_offset(int8_t *offset);
+static int yas_cdrv_measure(int32_t *msens, int32_t *raw, int16_t *t);
+static int yas_cdrv_init(const int8_t *transform,
+ struct yas_machdep_func *func);
+static int yas_cdrv_term(void);
+
+static void (*current_time) (int *sec, int *msec) = {
+0};
+
+static int utimeval_init(struct utimeval *val)
+{
+ if (unlikely(!val))
+ return -1;
+ val->tv_sec = val->tv_msec = 0;
+ return 0;
+}
+
+static int utimeval_is_initial(struct utimeval *val)
+{
+ if (unlikely(!val))
+ return 0;
+ return val->tv_sec == 0 && val->tv_msec == 0;
+}
+
+static int utimeval_is_overflow(struct utimeval *val)
+{
+ int32_t max;
+
+ if (unlikely(!val))
+ return 0;
+
+ max = (int32_t) (0xffffffff / 1000);
+ if (val->tv_sec > max) {
+ return 1; /* overflow */
+ } else if (val->tv_sec == max) {
+ if (val->tv_msec >
+ (int32_t) (0xffffffff % 1000)) {
+ return 1; /* overflow */
+ }
+ }
+
+ return 0;
+}
+
+static struct utimeval
+utimeval_plus(struct utimeval *first, struct utimeval *second)
+{
+ struct utimeval result = { 0, 0 };
+ int32_t tmp;
+
+ if (unlikely(!first || !second))
+ return result;
+
+ tmp = first->tv_sec + second->tv_sec;
+ if (first->tv_sec >= 0 && second->tv_sec >= 0 && tmp < 0)
+ goto overflow;
+ if (first->tv_sec < 0 && second->tv_sec < 0 && tmp >= 0)
+ goto underflow;
+
+ result.tv_sec = tmp;
+ result.tv_msec = first->tv_msec + second->tv_msec;
+ if (1000 <= result.tv_msec) {
+ tmp = result.tv_sec + result.tv_msec / 1000;
+ if (result.tv_sec >= 0 && result.tv_msec >= 0 && tmp < 0)
+ goto overflow;
+ result.tv_sec = tmp;
+ result.tv_msec = result.tv_msec % 1000;
+ }
+ if (result.tv_msec < 0) {
+ tmp = result.tv_sec + result.tv_msec / 1000 - 1;
+ if (result.tv_sec < 0 && result.tv_msec < 0 && tmp >= 0)
+ goto underflow;
+ result.tv_sec = tmp;
+ result.tv_msec = result.tv_msec % 1000 + 1000;
+ }
+
+ return result;
+
+overflow:
+ result.tv_sec = 0x7fffffff;
+ result.tv_msec = 999;
+ return result;
+
+underflow:
+ result.tv_sec = 0x80000000;
+ result.tv_msec = 0;
+ return result;
+}
+
+static struct utimeval
+utimeval_minus(struct utimeval *first, struct utimeval *second)
+{
+ struct utimeval result = { 0, 0 }, tmp;
+
+ if (first == NULL || second == NULL
+ || second->tv_sec == (int)0x80000000)
+ return result;
+
+ tmp.tv_sec = -second->tv_sec;
+ tmp.tv_msec = -second->tv_msec;
+ return utimeval_plus(first, &tmp);
+}
+
+static int utimeval_less_than(struct utimeval *first, struct utimeval *second)
+{
+ if (unlikely(!first || !second))
+ return 0;
+
+ if (first->tv_sec > second->tv_sec)
+ return 1;
+ else if (first->tv_sec < second->tv_sec)
+ return 0;
+ else
+ if (first->tv_msec > second->tv_msec)
+ return 1;
+ else
+ return 0;
+}
+
+static int
+utimeval_greater_than(struct utimeval *first, struct utimeval *second)
+{
+ if (unlikely(!first || !second))
+ return 0;
+
+ if (first->tv_sec < second->tv_sec)
+ return 1;
+ else if (first->tv_sec > second->tv_sec)
+ return 0;
+ else
+ if (first->tv_msec < second->tv_msec)
+ return 1;
+ else
+ return 0;
+}
+
+static int
+utimeval_greater_or_equal(struct utimeval *first, struct utimeval *second)
+{
+ return !utimeval_less_than(first, second);
+}
+
+static int utimeval_greater_than_zero(struct utimeval *val)
+{
+ struct utimeval zero = { 0, 0 };
+ return utimeval_greater_than(&zero, val);
+}
+
+static int utimeval_less_than_zero(struct utimeval *val)
+{
+ struct utimeval zero = { 0, 0 };
+ return utimeval_less_than(&zero, val);
+}
+
+static struct utimeval *msec_to_utimeval(struct utimeval *result, uint32_t msec)
+{
+ if (unlikely(!result))
+ return result;
+ result->tv_sec = msec / 1000;
+ result->tv_msec = msec % 1000;
+
+ return result;
+}
+
+static uint32_t utimeval_to_msec(struct utimeval *val)
+{
+ if (unlikely(!val))
+ return 0;
+ if (utimeval_less_than_zero(val))
+ return 0;
+
+ if (utimeval_is_overflow(val))
+ return 0xffffffff;
+
+ return val->tv_sec * 1000 + val->tv_msec;
+}
+
+static struct utimeval
+utimer_calc_next_time(struct utimer *ut, struct utimeval *cur)
+{
+ struct utimeval result = { 0, 0 }, delay;
+
+ if (ut == NULL || cur == NULL)
+ return result;
+ utimer_update_with_curtime(ut, cur);
+ if (utimer_is_timeout(ut)) {
+ result = *cur;
+ } else {
+ delay = utimeval_minus(&ut->delay_ms, &ut->total_time);
+ result = utimeval_plus(cur, &delay);
+ }
+
+ return result;
+}
+
+static struct utimeval utimer_current_time(void)
+{
+ struct utimeval tv;
+ int sec, msec;
+
+ if (current_time != NULL)
+ current_time(&sec, &msec);
+ else
+ sec = 0, msec = 0;
+ tv.tv_sec = sec;
+ tv.tv_msec = msec;
+
+ return tv;
+}
+
+static int utimer_clear(struct utimer *ut)
+{
+ if (unlikely(!ut))
+ return -1;
+ utimeval_init(&ut->prev_time);
+ utimeval_init(&ut->total_time);
+
+ return 0;
+}
+
+static int utimer_update_with_curtime(struct utimer *ut, struct utimeval *cur)
+{
+ struct utimeval tmp;
+
+ if (unlikely(!ut || !cur))
+ return -1;
+ if (utimeval_is_initial(&ut->prev_time))
+ ut->prev_time = *cur;
+ if (utimeval_greater_than_zero(&ut->delay_ms)) {
+ tmp = utimeval_minus(cur, &ut->prev_time);
+ if (utimeval_less_than_zero(&tmp))
+ utimeval_init(&ut->total_time);
+ else {
+ ut->total_time = utimeval_plus(&tmp, &ut->total_time);
+ if (utimeval_is_overflow(&ut->total_time))
+ utimeval_init(&ut->total_time);
+ }
+ ut->prev_time = *cur;
+ }
+
+ return 0;
+}
+
+static int utimer_update(struct utimer *ut)
+{
+ struct utimeval cur;
+
+ if (unlikely(!ut))
+ return -1;
+
+ cur = utimer_current_time();
+ utimer_update_with_curtime(ut, &cur);
+ return 0;
+}
+
+static int utimer_is_timeout(struct utimer *ut)
+{
+ if (unlikely(!ut))
+ return 0;
+
+ if (utimeval_greater_than_zero(&ut->delay_ms))
+ return utimeval_greater_or_equal(&ut->delay_ms,
+ &ut->total_time);
+ else
+ return 1;
+}
+
+static int utimer_clear_timeout(struct utimer *ut)
+{
+ uint32_t delay, total;
+
+ if (unlikely(!ut))
+ return -1;
+
+ delay = utimeval_to_msec(&ut->delay_ms);
+ if (delay == 0 || utimeval_is_overflow(&ut->total_time))
+ total = 0;
+ else
+ if (utimeval_is_overflow(&ut->total_time))
+ total = 0;
+ else {
+ total = utimeval_to_msec(&ut->total_time);
+ total = total % delay;
+ }
+ msec_to_utimeval(&ut->total_time, total);
+
+ return 0;
+}
+
+static uint32_t
+utimer_sleep_time_with_curtime(struct utimer *ut, struct utimeval *cur)
+{
+ struct utimeval tv;
+
+ if (unlikely(!ut || !cur))
+ return 0;
+
+ tv = utimer_calc_next_time(ut, cur);
+ tv = utimeval_minus(&tv, cur);
+ if (utimeval_less_than_zero(&tv))
+ return 0;
+
+ return utimeval_to_msec(&tv);
+}
+
+static uint32_t utimer_sleep_time(struct utimer *ut)
+{
+ struct utimeval cur;
+
+ if (unlikely(!ut))
+ return 0;
+
+ cur = utimer_current_time();
+ return utimer_sleep_time_with_curtime(ut, &cur);
+}
+
+static int utimer_init(struct utimer *ut, uint32_t delay_ms)
+{
+ if (unlikely(!ut))
+ return -1;
+ utimer_clear(ut);
+ msec_to_utimeval(&ut->delay_ms, delay_ms);
+
+ return 0;
+}
+
+static uint32_t utimer_get_total_time(struct utimer *ut)
+{
+ return utimeval_to_msec(&ut->total_time);
+}
+
+static uint32_t utimer_get_delay(struct utimer *ut)
+{
+ if (unlikely(!ut))
+ return -1;
+ return utimeval_to_msec(&ut->delay_ms);
+}
+
+static int utimer_set_delay(struct utimer *ut, uint32_t delay_ms)
+{
+ return utimer_init(ut, delay_ms);
+}
+
+static void utimer_lib_init(void (*func) (int *sec, int *msec))
+{
+ current_time = func;
+}
+
+struct yas_cal_data {
+ uint8_t dx, dy1, dy2;
+ uint8_t d2, d3, d4, d5, d6, d7, d8, d9, d0;
+ uint8_t dck;
+ uint8_t ver;
+};
+struct yas_correction_data {
+ int32_t Cx, Cy1, Cy2;
+ int32_t a2, a3, a4, a5, a6, a7, a8, a9, k;
+};
+struct yas_cdriver {
+ struct yas_cal_data cal;
+ struct yas_correction_data correct;
+ struct yas_machdep_func func;
+ int8_t transform[9];
+ int16_t temperature;
+ uint8_t dev_id;
+ int32_t coef;
+ int16_t center;
+ int16_t overflow;
+};
+static struct yas_cdriver cdriver;
+
+static int device_open(void)
+{
+ if (cdriver.func.device_open == NULL)
+ return -1;
+ return cdriver.func.device_open();
+}
+
+static int device_close(void)
+{
+ if (cdriver.func.device_close == NULL)
+ return -1;
+ return cdriver.func.device_close();
+}
+
+static int device_write(uint8_t addr, const uint8_t *buf, int len)
+{
+ if (cdriver.func.device_write == NULL)
+ return -1;
+ return cdriver.func.device_write(addr, buf, len);
+}
+
+static int device_read(uint8_t addr, uint8_t *buf, int len)
+{
+ if (cdriver.func.device_read == NULL)
+ return -1;
+ return cdriver.func.device_read(addr, buf, len);
+}
+
+static void sleep(int millisec)
+{
+ if (cdriver.func.msleep == NULL)
+ return;
+ cdriver.func.msleep(millisec);
+}
+
+static int init_test_register(void)
+{
+ uint8_t data;
+
+ data = 0x00;
+ if (device_write(YAS_REGADDR_TEST1, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ data = 0x00;
+ if (device_write(YAS_REGADDR_TEST2, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ return YAS_NO_ERROR;
+}
+
+static int get_device_id(uint8_t *id)
+{
+ uint8_t data = 0;
+
+ if (device_read(YAS_REGADDR_DEVICE_ID, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ *id = data;
+
+ return YAS_NO_ERROR;
+}
+
+static int get_cal_data_yas530(struct yas_cal_data *cal)
+{
+ uint8_t data[16];
+#ifdef YAS_YAS530_CAL_SINGLE_READ
+ int i;
+
+ for (i = 0; i < 16; i++) { /* dummy read */
+ if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+ for (i = 0; i < 16; i++) {
+ if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+#else
+ if (device_read(YAS_REGADDR_CAL, data, 16) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (device_read(YAS_REGADDR_CAL, data, 16) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+#endif
+
+ cal->dx = data[0];
+ cal->dy1 = data[1];
+ cal->dy2 = data[2];
+ cal->d2 = (data[3] >> 2) & 0x03f;
+ cal->d3 = ((data[3] << 2) & 0x0c) | ((data[4] >> 6) & 0x03);
+ cal->d4 = data[4] & 0x3f;
+ cal->d5 = (data[5] >> 2) & 0x3f;
+ cal->d6 = ((data[5] << 4) & 0x30) | ((data[6] >> 4) & 0x0f);
+ cal->d7 = ((data[6] << 3) & 0x78) | ((data[7] >> 5) & 0x07);
+ cal->d8 = ((data[7] << 1) & 0x3e) | ((data[8] >> 7) & 0x01);
+ cal->d9 = ((data[8] << 1) & 0xfe) | ((data[9] >> 7) & 0x01);
+ cal->d0 = (data[9] >> 2) & 0x1f;
+ cal->dck = ((data[9] << 1) & 0x06) | ((data[10] >> 7) & 0x01);
+ cal->ver = (data[15]) & 0x03;
+
+ return YAS_NO_ERROR;
+}
+
+static void
+get_correction_value_yas530(struct yas_cal_data *cal,
+ struct yas_correction_data *correct)
+{
+ correct->Cx = cal->dx * 6 - 768;
+ correct->Cy1 = cal->dy1 * 6 - 768;
+ correct->Cy2 = cal->dy2 * 6 - 768;
+ correct->a2 = cal->d2 - 32;
+ correct->a3 = cal->d3 - 8;
+ correct->a4 = cal->d4 - 32;
+ correct->a5 = cal->d5 + 38;
+ correct->a6 = cal->d6 - 32;
+ correct->a7 = cal->d7 - 64;
+ correct->a8 = cal->d8 - 32;
+ correct->a9 = cal->d9;
+ correct->k = cal->d0 + 10;
+}
+
+static int get_cal_data_yas532(struct yas_cal_data *cal)
+{
+ uint8_t data[14];
+#ifdef YAS_YAS530_CAL_SINGLE_READ
+ int i;
+
+ for (i = 0; i < 14; i++) { /* dummy read */
+ if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+ for (i = 0; i < 14; i++) {
+ if (device_read(YAS_REGADDR_CAL + i, &data[i], 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+#else
+ if (device_read(YAS_REGADDR_CAL, data, 14) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (device_read(YAS_REGADDR_CAL, data, 14) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+#endif
+
+ cal->dx = data[0];
+ cal->dy1 = data[1];
+ cal->dy2 = data[2];
+ cal->d2 = (data[3] >> 2) & 0x03f;
+ cal->d3 = ((data[3] << 2) & 0x0c) | ((data[4] >> 6) & 0x03);
+ cal->d4 = data[4] & 0x3f;
+ cal->d5 = (data[5] >> 2) & 0x3f;
+ cal->d6 = ((data[5] << 4) & 0x30) | ((data[6] >> 4) & 0x0f);
+ cal->d7 = ((data[6] << 3) & 0x78) | ((data[7] >> 5) & 0x07);
+ cal->d8 = ((data[7] << 1) & 0x3e) | ((data[8] >> 7) & 0x01);
+ cal->d9 = ((data[8] << 1) & 0xfe) | ((data[9] >> 7) & 0x01);
+ cal->d0 = (data[9] >> 2) & 0x1f;
+ cal->dck = ((data[9] << 1) & 0x06) | ((data[10] >> 7) & 0x01);
+ cal->ver = (data[13]) & 0x01;
+
+ return YAS_NO_ERROR;
+}
+
+static void
+get_correction_value_yas532(struct yas_cal_data *cal,
+ struct yas_correction_data *correct)
+{
+ correct->Cx = cal->dx * 10 - 1280;
+ correct->Cy1 = cal->dy1 * 10 - 1280;
+ correct->Cy2 = cal->dy2 * 10 - 1280;
+ correct->a2 = cal->d2 - 32;
+ correct->a3 = cal->d3 - 8;
+ correct->a4 = cal->d4 - 32;
+ correct->a5 = cal->d5 + 38;
+ correct->a6 = cal->d6 - 32;
+ correct->a7 = cal->d7 - 64;
+ correct->a8 = cal->d8 - 32;
+ correct->a9 = cal->d9;
+ correct->k = cal->d0;
+}
+
+static int set_configuration(int inton, int inthact, int cck)
+{
+ uint8_t data = 0;
+
+ data |= (!!inton) & 0x01;
+ data |= ((!!inthact) << 1) & 0x02;
+ data |= (cck << 2) & 0x1c;
+
+ if (device_write(YAS_REGADDR_CONFIG, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ return YAS_NO_ERROR;
+}
+
+static int get_measure_interval(int32_t *msec)
+{
+ uint8_t data;
+ int mult = 7;
+
+ if (device_read(YAS_REGADDR_MEASURE_INTERVAL, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ switch (cdriver.dev_id) {
+ case YAS_YAS532_DEVICE_ID:
+ mult = 4;
+ break;
+ case YAS_YAS530_DEVICE_ID:
+ default:
+ mult = 7;
+ break;
+ }
+
+ *msec = data * mult;
+
+ return YAS_NO_ERROR;
+}
+
+static int set_measure_interval(int32_t msec)
+{
+ uint8_t data = 0;
+ int mult = 7;
+
+ switch (cdriver.dev_id) {
+ case YAS_YAS532_DEVICE_ID:
+ mult = 4;
+ break;
+ case YAS_YAS530_DEVICE_ID:
+ default:
+ mult = 7;
+ break;
+ }
+
+ if (msec > mult*0xff)
+ data = 0xff;
+ else
+ if (msec % mult == 0)
+ data = (uint8_t)(msec / mult);
+ else
+ data = (uint8_t)(msec / mult + 1);
+ if (device_write(YAS_REGADDR_MEASURE_INTERVAL, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ return YAS_NO_ERROR;
+}
+
+static int set_measure_command(int ldtc, int fors, int dlymes)
+{
+ uint8_t data = 0;
+
+ data |= 0x01; /* bit 0 must be 1 */
+ data |= ((!(!ldtc)) << 1) & 0x02;
+ data |= ((!(!fors)) << 2) & 0x04;
+ data |= ((!(!dlymes)) << 4) & 0x10;
+
+ if (device_write(YAS_REGADDR_MEASURE_COMMAND, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ return YAS_NO_ERROR;
+}
+
+static int
+measure_normal_yas530(int *busy, int16_t *t, int16_t *x, int16_t *y1,
+ int16_t *y2)
+{
+ uint8_t data[8];
+
+ if (set_measure_command(0, 0, 0) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ sleep(2);
+
+ if (device_read(YAS_REGADDR_MEASURE_DATA, data, 8) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ *busy = (data[0] >> 7) & 0x01;
+ *t = (((int32_t) data[0] << 2) & 0x1fc) | ((data[1] >> 6) & 0x03);
+ *x = (((int32_t) data[2] << 5) & 0xfe0) | ((data[3] >> 3) & 0x1f);
+ *y1 = (((int32_t) data[4] << 5) & 0xfe0) | ((data[5] >> 3) & 0x1f);
+ *y2 = (((int32_t) data[6] << 5) & 0xfe0) | ((data[7] >> 3) & 0x1f);
+ /*YLOGD(("f[%d] t[%d] x[%d] y1[%d] y2[%d]\n",
+ *busy, *t, *x, *y1, *y2)); */
+
+ return YAS_NO_ERROR;
+}
+
+static int
+measure_normal_yas532(int *busy, int16_t *t, int16_t *x, int16_t *y1,
+ int16_t *y2)
+{
+ uint8_t data[8];
+
+ if (set_measure_command(0, 0, 0) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ sleep(2);
+
+ if (device_read(YAS_REGADDR_MEASURE_DATA, data, 8) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ *busy = (data[0] >> 7) & 0x01;
+ *t = (((int32_t) data[0] << 3) & 0x3f8) | ((data[1] >> 5) & 0x07);
+ *x = (((int32_t) data[2] << 6) & 0x1fc0) | ((data[3] >> 2) & 0x3f);
+ *y1 = (((int32_t) data[4] << 6) & 0x1fc0) | ((data[5] >> 2) & 0x3f);
+ *y2 = (((int32_t) data[6] << 6) & 0x1fc0) | ((data[7] >> 2) & 0x3f);
+ /*YLOGD(("f[%d] t[%d] x[%d] y1[%d] y2[%d]\n",
+ *busy, *t, *x, *y1, *y2)); */
+
+ return YAS_NO_ERROR;
+}
+
+static int
+measure_normal(int *busy, int16_t *t, int16_t *x, int16_t *y1, int16_t *y2)
+{
+ int result;
+
+ switch (cdriver.dev_id) {
+ case YAS_YAS532_DEVICE_ID:
+ result = measure_normal_yas532(busy, t, x, y1, y2);
+ break;
+ case YAS_YAS530_DEVICE_ID:
+ default:
+ result = measure_normal_yas530(busy, t, x, y1, y2);
+ break;
+ }
+
+ return result;
+}
+
+static int
+coordinate_conversion(int32_t x, int32_t y1, int32_t y2, int16_t t,
+ int32_t *xo, int32_t *yo, int32_t *zo,
+ struct yas_correction_data *c)
+{
+ int32_t sx, sy1, sy2, sy, sz;
+ int32_t hx, hy, hz;
+
+ sx = x - (c->Cx * t) / 100;
+ sy1 = y1 - (c->Cy1 * t) / 100;
+ sy2 = y2 - (c->Cy2 * t) / 100;
+
+ sy = sy1 - sy2;
+ sz = -sy1 - sy2;
+
+ hx = c->k * ((100 * sx + c->a2 * sy + c->a3 * sz) / 10);
+ hy = c->k * ((c->a4 * sx + c->a5 * sy + c->a6 * sz) / 10);
+ hz = c->k * ((c->a7 * sx + c->a8 * sy + c->a9 * sz) / 10);
+
+ *xo = cdriver.transform[0] * hx
+ + cdriver.transform[1] * hy + cdriver.transform[2] * hz;
+ *yo = cdriver.transform[3] * hx
+ + cdriver.transform[4] * hy + cdriver.transform[5] * hz;
+ *zo = cdriver.transform[6] * hx
+ + cdriver.transform[7] * hy + cdriver.transform[8] * hz;
+
+ return YAS_NO_ERROR;
+}
+
+static int
+set_hardware_offset(int8_t offset_x, int8_t offset_y1, int8_t offset_y2)
+{
+ uint8_t data;
+
+ data = offset_x & 0x3f;
+ if (device_write(YAS_REGADDR_OFFSET_X, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ data = offset_y1 & 0x3f;
+ if (device_write(YAS_REGADDR_OFFSET_Y1, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ data = offset_y2 & 0x3f;
+ if (device_write(YAS_REGADDR_OFFSET_Y2, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_cdrv_actuate_initcoil(void)
+{
+ uint8_t data = 0;
+
+ if (device_write(YAS_REGADDR_ACTUATE_INIT_COIL, &data, 1) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ return YAS_NO_ERROR;
+}
+
+static int
+check_offset(int8_t offset_x, int8_t offset_y1, int8_t offset_y2,
+ int *flag_x, int *flag_y1, int *flag_y2)
+{
+ int busy;
+ int16_t t, x, y1, y2;
+
+ if (set_hardware_offset(offset_x, offset_y1, offset_y2) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (measure_normal(&busy, &t, &x, &y1, &y2) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ *flag_x = *flag_y1 = *flag_y2 = 0;
+ if (x > cdriver.center)
+ *flag_x = 1;
+ if (y1 > cdriver.center)
+ *flag_y1 = 1;
+ if (y2 > cdriver.center)
+ *flag_y2 = 1;
+ if (x < cdriver.center)
+ *flag_x = -1;
+ if (y1 < cdriver.center)
+ *flag_y1 = -1;
+ if (y2 < cdriver.center)
+ *flag_y2 = -1;
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_cdrv_measure_and_set_offset(int8_t *offset)
+{
+ int i;
+ int8_t offset_x = 0, offset_y1 = 0, offset_y2 = 0;
+ int flag_x = 0, flag_y1 = 0, flag_y2 = 0;
+ static const int correct[5] = { 16, 8, 4, 2, 1 };
+
+ for (i = 0; i < 5; i++) {
+ if (check_offset(offset_x, offset_y1, offset_y2,
+ &flag_x, &flag_y1, &flag_y2) < 0) {
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+ YLOGD(("offset[%d][%d][%d] flag[%d][%d][%d]\n",
+ offset_x, offset_y1, offset_y2,
+ flag_x, flag_y1, flag_y2));
+ if (flag_x)
+ offset_x += flag_x * correct[i];
+ if (flag_y1)
+ offset_y1 += flag_y1 * correct[i];
+ if (flag_y2)
+ offset_y2 += flag_y2 * correct[i];
+ }
+ if (set_hardware_offset(offset_x, offset_y1, offset_y2) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ offset[0] = offset_x;
+ offset[1] = offset_y1;
+ offset[2] = offset_y2;
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_cdrv_set_offset(const int8_t *offset)
+{
+ if (set_hardware_offset(offset[0], offset[1], offset[2]) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_cdrv_measure(int32_t *data, int32_t *raw, int16_t *temperature)
+{
+ int busy;
+ int16_t x, y1, y2, t;
+ int32_t xx, yy1, yy2;
+ int result = 0;
+
+ if (measure_normal(&busy, &t, &x, &y1, &y2) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ if (x == 0)
+ result |= 0x01;
+ if (x == cdriver.overflow)
+ result |= 0x02;
+ if (y1 == 0)
+ result |= 0x04;
+ if (y1 == cdriver.overflow)
+ result |= 0x08;
+ if (y2 == 0)
+ result |= 0x10;
+ if (y2 == cdriver.overflow)
+ result |= 0x20;
+
+ xx = x;
+ yy1 = y1;
+ yy2 = y2;
+
+ if (coordinate_conversion(xx, yy1, yy2, t, &data[0], &data[1],
+ &data[2], &cdriver.correct) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ cdriver.temperature = t;
+
+ if (raw != NULL)
+ raw[0] = xx, raw[1] = yy1, raw[2] = yy2;
+ if (temperature != NULL)
+ *temperature = t;
+
+ return result;
+}
+
+static int
+yas_cdrv_recalc_calib_offset(int32_t *prev_calib_offset,
+ int32_t *new_calib_offset,
+ int8_t *prev_offset, int8_t *new_offset)
+{
+ int32_t tmp[3], resolution[9], base[3];
+ int32_t raw[3];
+ int32_t diff, i;
+
+ if (prev_calib_offset == NULL || new_calib_offset == NULL
+ || prev_offset == NULL || new_offset == NULL)
+ return YAS_ERROR_ARG;
+
+ raw[0] = raw[1] = raw[2] = 0;
+ if (coordinate_conversion(raw[0], raw[1], raw[2], cdriver.temperature,
+ &base[0], &base[1], &base[2],
+ &cdriver.correct) < 0)
+ return YAS_ERROR_ERROR;
+ for (i = 0; i < 3; i++) {
+ raw[0] = raw[1] = raw[2] = 0;
+ raw[i] = cdriver.coef;
+ if (coordinate_conversion(raw[0], raw[1], raw[2],
+ cdriver.temperature,
+ &resolution[i * 3 + 0],
+ &resolution[i * 3 + 1],
+ &resolution[i * 3 + 2],
+ &cdriver.correct) < 0)
+ return YAS_ERROR_ERROR;
+ resolution[i * 3 + 0] -= base[0];
+ resolution[i * 3 + 1] -= base[1];
+ resolution[i * 3 + 2] -= base[2];
+ }
+
+ for (i = 0; i < 3; i++)
+ tmp[i] = prev_calib_offset[i];
+
+ for (i = 0; i < 3; i++) {
+ diff = (int32_t) new_offset[i] - (int32_t) prev_offset[i];
+ while (diff > 0) {
+ tmp[0] -= resolution[i * 3 + 0];
+ tmp[1] -= resolution[i * 3 + 1];
+ tmp[2] -= resolution[i * 3 + 2];
+ diff--;
+ }
+ while (diff < 0) {
+ tmp[0] += resolution[i * 3 + 0];
+ tmp[1] += resolution[i * 3 + 1];
+ tmp[2] += resolution[i * 3 + 2];
+ diff++;
+ }
+ }
+ for (i = 0; i < 3; i++)
+ new_calib_offset[i] = tmp[i];
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_cdrv_set_transformatiom_matrix(const int8_t *transform)
+{
+ int i;
+
+ if (transform == NULL)
+ return YAS_ERROR_ARG;
+ for (i = 0; i < 9; i++)
+ cdriver.transform[i] = transform[i];
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_cdrv_init(const int8_t *transform, struct yas_machdep_func *func)
+{
+ int interval, i;
+ uint8_t id;
+
+ if (transform == NULL || func == NULL)
+ return YAS_ERROR_ARG;
+
+ for (i = 0; i < 9; i++)
+ cdriver.transform[i] = transform[i];
+
+ cdriver.func = *func;
+
+ if (device_open() < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ if (init_test_register() < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ if (get_device_id(&id) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ YLOGD(("device id:%02x\n", id));
+
+ switch (id) {
+ case YAS_YAS530_DEVICE_ID:
+ if (get_cal_data_yas530(&cdriver.cal) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+
+ get_correction_value_yas530(&cdriver.cal, &cdriver.correct);
+ cdriver.center = YAS_YAS530_DATA_CENTER;
+ cdriver.overflow = YAS_YAS530_DATA_OVERFLOW;
+ switch (cdriver.cal.ver) {
+ case YAS_YAS530_VERSION_B:
+ cdriver.coef = YAS_YAS530_VERSION_B_COEF;
+ break;
+ case YAS_YAS530_VERSION_A:
+ default:
+ cdriver.coef = YAS_YAS530_VERSION_A_COEF;
+ break;
+ }
+ break;
+
+ case YAS_YAS532_DEVICE_ID:
+ if (get_cal_data_yas532(&cdriver.cal) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ get_correction_value_yas532(&cdriver.cal, &cdriver.correct);
+ cdriver.center = YAS_YAS532_DATA_CENTER;
+ cdriver.overflow = YAS_YAS532_DATA_OVERFLOW;
+ switch (cdriver.cal.ver) {
+ case YAS_YAS532_VERSION_AC:
+ cdriver.coef = YAS_YAS532_VERSION_AC_COEF;
+ break;
+ case YAS_YAS532_VERSION_AB:
+ default:
+ cdriver.coef = YAS_YAS532_VERSION_AB_COEF;
+ break;
+ }
+ break;
+
+ default:
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+ cdriver.dev_id = id;
+
+ if (set_configuration(0, 0, cdriver.cal.dck) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (set_measure_interval(0) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (get_measure_interval(&interval) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ YLOGD(("interval[%d]\n", interval));
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_cdrv_term(void)
+{
+ device_close();
+ return YAS_NO_ERROR;
+}
+
+#define YAS_DEFAULT_CALIB_INTERVAL (50) /* 50 msecs */
+#define YAS_DEFAULT_DATA_INTERVAL (200) /* 200 msecs */
+#define YAS_INITCOIL_INTERVAL (200) /* 200 msec */
+#define YAS_INITCOIL_GIVEUP_INTERVAL (180000) /* 180 seconds */
+#define YAS_DETECT_OVERFLOW_INTERVAL (0) /* 0 second */
+
+#define YAS_MAG_ERROR_DELAY (200)
+#define YAS_MAG_STATE_NORMAL (0)
+#define YAS_MAG_STATE_INIT_COIL (1)
+#define YAS_MAG_STATE_MEASURE_OFFSET (2)
+
+static const int8_t YAS_TRANSFORMATION[][9] = {
+ {0, 1, 0, -1, 0, 0, 0, 0, 1},
+ {-1, 0, 0, 0, -1, 0, 0, 0, 1},
+ {0, -1, 0, 1, 0, 0, 0, 0, 1},
+ {1, 0, 0, 0, 1, 0, 0, 0, 1},
+ {0, -1, 0, -1, 0, 0, 0, 0, -1},
+ {1, 0, 0, 0, -1, 0, 0, 0, -1},
+ {0, 1, 0, 1, 0, 0, 0, 0, -1},
+ {-1, 0, 0, 0, 1, 0, 0, 0, -1},
+};
+
+static const int supported_data_interval[] = { 10, 20, 50, 60, 100, 200, 1000 };
+static const int supported_calib_interval[] = { 60, 60, 50, 60, 50, 50, 50 };
+static const int32_t INVALID_CALIB_OFFSET[] = { 0x7fffffff,
+ 0x7fffffff, 0x7fffffff };
+static const int8_t INVALID_OFFSET[] = { 0x7f, 0x7f, 0x7f };
+
+struct yas_adaptive_filter {
+ int num;
+ int index;
+ int filter_len;
+ int filter_noise;
+ int32_t sequence[YAS_MAG_MAX_FILTER_LEN];
+};
+
+struct yas_thresh_filter {
+ int32_t threshold;
+ int32_t last;
+};
+
+struct yas_driver {
+ int initialized;
+ struct yas_mag_driver_callback callback;
+ struct utimer data_timer;
+ struct utimer initcoil_timer;
+ struct utimer initcoil_giveup_timer;
+ struct utimer detect_overflow_timer;
+ int32_t prev_mag[3];
+ int32_t prev_xy1y2[3];
+ int32_t prev_mag_w_offset[3];
+ int16_t prev_temperature;
+ int measure_state;
+ int active;
+ int overflow;
+ int initcoil_gaveup;
+ int position;
+ int delay_timer_use_data;
+ int delay_timer_interval;
+ int delay_timer_counter;
+ int filter_enable;
+ int filter_len;
+ int filter_thresh;
+ int filter_noise[3];
+ struct yas_adaptive_filter adap_filter[3];
+ struct yas_thresh_filter thresh_filter[3];
+ struct yas_mag_offset offset;
+#ifdef YAS_MAG_MANUAL_OFFSET
+ struct yas_vector manual_offset;
+#endif
+ struct yas_matrix static_matrix;
+ struct yas_matrix dynamic_matrix;
+};
+
+static struct yas_driver this_driver;
+
+static int lock(void)
+{
+ if (this_driver.callback.lock != NULL) {
+ if (this_driver.callback.lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+ }
+ return 0;
+}
+
+static int unlock(void)
+{
+ if (this_driver.callback.unlock != NULL) {
+ if (this_driver.callback.unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+ }
+ return 0;
+}
+
+static int32_t square(int32_t data)
+{
+ return data * data;
+}
+
+static void
+adaptive_filter_init(struct yas_adaptive_filter *adap_filter, int len,
+ int noise)
+{
+ int i;
+
+ adap_filter->num = 0;
+ adap_filter->index = 0;
+ adap_filter->filter_noise = noise;
+ adap_filter->filter_len = len;
+
+ for (i = 0; i < adap_filter->filter_len; ++i)
+ adap_filter->sequence[i] = 0;
+}
+
+static int32_t
+adaptive_filter_filter(struct yas_adaptive_filter *adap_filter, int32_t in)
+{
+ int32_t avg, sum;
+ int i;
+
+ if (adap_filter->filter_len == 0)
+ return in;
+
+ if (adap_filter->num < adap_filter->filter_len) {
+ adap_filter->sequence[adap_filter->index++] = in / 100;
+ adap_filter->num++;
+ return in;
+ }
+ if (adap_filter->filter_len <= adap_filter->index)
+ adap_filter->index = 0;
+
+ adap_filter->sequence[adap_filter->index++] = in / 100;
+
+ avg = 0;
+ for (i = 0; i < adap_filter->filter_len; i++)
+ avg += adap_filter->sequence[i];
+
+ avg /= adap_filter->filter_len;
+
+ sum = 0;
+ for (i = 0; i < adap_filter->filter_len; i++)
+ sum += square(avg - adap_filter->sequence[i]);
+
+ sum /= adap_filter->filter_len;
+
+ if (sum <= adap_filter->filter_noise)
+ return avg * 100;
+
+ return ((in / 100 - avg) * (sum - adap_filter->filter_noise) / sum +
+ avg) * 100;
+}
+
+static void
+thresh_filter_init(struct yas_thresh_filter *thresh_filter, int threshold)
+{
+ thresh_filter->threshold = threshold;
+ thresh_filter->last = 0;
+}
+
+static int32_t
+thresh_filter_filter(struct yas_thresh_filter *thresh_filter, int32_t in)
+{
+ if (in < thresh_filter->last - thresh_filter->threshold
+ || thresh_filter->last + thresh_filter->threshold < in) {
+ thresh_filter->last = in;
+ return in;
+ } else
+ return thresh_filter->last;
+}
+
+static void filter_init(struct yas_driver *d)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ adaptive_filter_init(&d->adap_filter[i], d->filter_len,
+ d->filter_noise[i]);
+ thresh_filter_init(&d->thresh_filter[i], d->filter_thresh);
+ }
+}
+
+static void
+filter_filter(struct yas_driver *d, int32_t *orig, int32_t *filtered)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ filtered[i] =
+ adaptive_filter_filter(&d->adap_filter[i], orig[i]);
+ filtered[i] =
+ thresh_filter_filter(&d->thresh_filter[i], filtered[i]);
+ }
+}
+
+static int is_valid_offset(const int8_t *p)
+{
+ return (p != NULL && (p[0] <= 31) && (p[1] <= 31) && (p[2] <= 31)
+ && (-31 <= p[0]) && (-31 <= p[1]) && (-31 <= p[2]));
+}
+
+static int is_valid_calib_offset(const int32_t *p)
+{
+ int i;
+ for (i = 0; i < 3; i++) {
+ if (p[i] != INVALID_CALIB_OFFSET[i])
+ return 1;
+ }
+ return 0;
+}
+
+static int is_offset_differ(const int8_t *p0, const int8_t *p1)
+{
+ if (p0[0] != p1[0] || p0[1] != p1[1] || p0[2] != p1[2])
+ return 1;
+ else
+ return 0;
+}
+
+static int is_calib_offset_differ(const int32_t *p0, const int32_t *p1)
+{
+ if (p0[0] != p1[0] || p0[1] != p1[1] || p0[2] != p1[2])
+ return 1;
+ else
+ return 0;
+}
+
+static int get_overflow(struct yas_driver *d)
+{
+ return d->overflow;
+}
+
+static void set_overflow(struct yas_driver *d, const int overflow)
+{
+ if (d->overflow != overflow)
+ d->overflow = overflow;
+}
+
+static int get_initcoil_gaveup(struct yas_driver *d)
+{
+ return d->initcoil_gaveup;
+}
+
+static void set_initcoil_gaveup(struct yas_driver *d, const int initcoil_gaveup)
+{
+ d->initcoil_gaveup = initcoil_gaveup;
+}
+
+static int32_t *get_calib_offset(struct yas_driver *d)
+{
+ return d->offset.calib_offset.v;
+}
+
+static void set_calib_offset(struct yas_driver *d, const int32_t *offset)
+{
+ int i;
+
+ if (is_calib_offset_differ(d->offset.calib_offset.v, offset)) {
+ for (i = 0; i < 3; i++)
+ d->offset.calib_offset.v[i] = offset[i];
+ }
+}
+
+#ifdef YAS_MAG_MANUAL_OFFSET
+static int32_t *get_manual_offset(struct yas_driver *d)
+{
+ return d->manual_offset.v;
+}
+
+static void set_manual_offset(struct yas_driver *d, const int32_t *offset)
+{
+ int i;
+
+ for (i = 0; i < 3; i++)
+ d->manual_offset.v[i] = offset[i];
+}
+#endif
+
+static int32_t *get_static_matrix(struct yas_driver *d)
+{
+ return d->static_matrix.matrix;
+}
+
+static void set_static_matrix(struct yas_driver *d, const int32_t *matrix)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ d->static_matrix.matrix[i] = matrix[i];
+}
+
+static int32_t *get_dynamic_matrix(struct yas_driver *d)
+{
+ return d->dynamic_matrix.matrix;
+}
+
+static void set_dynamic_matrix(struct yas_driver *d, const int32_t *matrix)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ d->dynamic_matrix.matrix[i] = matrix[i];
+}
+
+static int8_t *get_offset(struct yas_driver *d)
+{
+ return d->offset.hard_offset;
+}
+
+static void set_offset(struct yas_driver *d, const int8_t *offset)
+{
+ int i;
+
+ if (is_offset_differ(d->offset.hard_offset, offset)) {
+ for (i = 0; i < 3; i++)
+ d->offset.hard_offset[i] = offset[i];
+ }
+}
+
+static int get_active(struct yas_driver *d)
+{
+ return d->active;
+}
+
+static void set_active(struct yas_driver *d, const int active)
+{
+ d->active = active;
+}
+
+static int get_position(struct yas_driver *d)
+{
+ return d->position;
+}
+
+static void set_position(struct yas_driver *d, const int position)
+{
+ d->position = position;
+}
+
+static int get_measure_state(struct yas_driver *d)
+{
+ return d->measure_state;
+}
+
+static void set_measure_state(struct yas_driver *d, const int state)
+{
+ d->measure_state = state;
+}
+
+static struct utimer *get_data_timer(struct yas_driver *d)
+{
+ return &d->data_timer;
+}
+
+static struct utimer *get_initcoil_timer(struct yas_driver *d)
+{
+ return &d->initcoil_timer;
+}
+
+static struct utimer *get_initcoil_giveup_timer(struct yas_driver *d)
+{
+ return &d->initcoil_giveup_timer;
+}
+
+static struct utimer *get_detect_overflow_timer(struct yas_driver *d)
+{
+ return &d->detect_overflow_timer;
+}
+
+static int get_delay_timer_use_data(struct yas_driver *d)
+{
+ return d->delay_timer_use_data;
+}
+
+static void set_delay_timer_use_data(struct yas_driver *d, int flag)
+{
+ d->delay_timer_use_data = !(!flag);
+}
+
+static int get_delay_timer_interval(struct yas_driver *d)
+{
+ return d->delay_timer_interval;
+}
+
+static void set_delay_timer_interval(struct yas_driver *d, int interval)
+{
+ d->delay_timer_interval = interval;
+}
+
+static int get_delay_timer_counter(struct yas_driver *d)
+{
+ return d->delay_timer_counter;
+}
+
+static void set_delay_timer_counter(struct yas_driver *d, int counter)
+{
+ d->delay_timer_counter = counter;
+}
+
+static int get_filter_enable(struct yas_driver *d)
+{
+ return d->filter_enable;
+}
+
+static void set_filter_enable(struct yas_driver *d, int enable)
+{
+ if (enable)
+ filter_init(d);
+
+ d->filter_enable = !(!enable);
+}
+
+static int get_filter_len(struct yas_driver *d)
+{
+ return d->filter_len;
+}
+
+static void set_filter_len(struct yas_driver *d, int len)
+{
+ if (len < 0)
+ return;
+
+ if (len > YAS_MAG_MAX_FILTER_LEN)
+ return;
+
+ d->filter_len = len;
+ filter_init(d);
+}
+
+static int get_filter_noise(struct yas_driver *d, int *noise)
+{
+ int i;
+
+ for (i = 0; i < 3; i++)
+ noise[i] = d->filter_noise[i];
+
+ return 0;
+}
+
+static void set_filter_noise(struct yas_driver *d, int *noise)
+{
+ int i;
+
+ if (noise == NULL)
+ return;
+
+ for (i = 0; i < 3; i++) {
+ if (noise[i] < 0)
+ noise[i] = 0;
+
+ d->filter_noise[i] = noise[i];
+ }
+ filter_init(d);
+}
+
+static int get_filter_thresh(struct yas_driver *d)
+{
+ return d->filter_thresh;
+}
+
+static void set_filter_thresh(struct yas_driver *d, int threshold)
+{
+ if (threshold < 0)
+ return;
+
+ d->filter_thresh = threshold;
+ filter_init(d);
+}
+
+static int32_t *get_previous_mag(struct yas_driver *d)
+{
+ return d->prev_mag;
+}
+
+static void set_previous_mag(struct yas_driver *d, int32_t *data)
+{
+ int i;
+ for (i = 0; i < 3; i++)
+ d->prev_mag[i] = data[i];
+}
+
+static int32_t *get_previous_xy1y2(struct yas_driver *d)
+{
+ return d->prev_xy1y2;
+}
+
+static void set_previous_xy1y2(struct yas_driver *d, int32_t *data)
+{
+ int i;
+ for (i = 0; i < 3; i++)
+ d->prev_xy1y2[i] = data[i];
+}
+
+static int32_t *get_previous_mag_w_offset(struct yas_driver *d)
+{
+ return d->prev_mag_w_offset;
+}
+
+static void set_previous_mag_w_offset(struct yas_driver *d, int32_t *data)
+{
+ int i;
+ for (i = 0; i < 3; i++)
+ d->prev_mag_w_offset[i] = data[i];
+}
+
+static int16_t get_previous_temperature(struct yas_driver *d)
+{
+ return d->prev_temperature;
+}
+
+static void set_previous_temperature(struct yas_driver *d, int16_t temperature)
+{
+ d->prev_temperature = temperature;
+}
+
+static int init_coil(struct yas_driver *d)
+{
+ int rt;
+
+ YLOGD(("init_coil IN\n"));
+
+ utimer_update(get_initcoil_timer(d));
+ if (!get_initcoil_gaveup(d)) {
+ utimer_update(get_initcoil_giveup_timer(d));
+ if (utimer_is_timeout(get_initcoil_giveup_timer(d))) {
+ utimer_clear_timeout(get_initcoil_giveup_timer(d));
+ set_initcoil_gaveup(d, TRUE);
+ }
+ }
+ if (utimer_is_timeout(get_initcoil_timer(d)) &&
+ !get_initcoil_gaveup(d)) {
+ utimer_clear_timeout(get_initcoil_timer(d));
+ YLOGI(("init_coil!\n"));
+ rt = yas_cdrv_actuate_initcoil();
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
+ return rt;
+ }
+ if (get_overflow(d) || !is_valid_offset(get_offset(d)))
+ set_measure_state(d, YAS_MAG_STATE_MEASURE_OFFSET);
+ else
+ set_measure_state(d, YAS_MAG_STATE_NORMAL);
+ }
+
+ YLOGD(("init_coil OUT\n"));
+
+ return 0;
+}
+
+static int measure_offset(struct yas_driver *d)
+{
+ int8_t offset[3];
+ int32_t moffset[3];
+ int rt, result = 0, i;
+
+ YLOGI(("measure_offset IN\n"));
+ rt = yas_cdrv_measure_and_set_offset(offset);
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_measure_offset failed[%d]\n", rt));
+ return rt;
+ }
+
+ YLOGI(("offset[%d][%d][%d]\n", offset[0], offset[1], offset[2]));
+
+ for (i = 0; i < 3; i++)
+ moffset[i] = get_calib_offset(d)[i];
+
+ if (is_offset_differ(get_offset(d), offset)) {
+ if (is_valid_offset(get_offset(d))
+ && is_valid_calib_offset(get_calib_offset(d))) {
+ yas_cdrv_recalc_calib_offset(get_calib_offset(d),
+ moffset,
+ get_offset(d), offset);
+ result |= YAS_REPORT_CALIB_OFFSET_CHANGED;
+ }
+ }
+ result |= YAS_REPORT_HARD_OFFSET_CHANGED;
+
+ set_offset(d, offset);
+ if (is_valid_calib_offset(moffset))
+ set_calib_offset(d, moffset);
+
+ set_measure_state(d, YAS_MAG_STATE_NORMAL);
+
+ YLOGI(("measure_offset OUT\n"));
+
+ return result;
+}
+
+static int
+measure_msensor_normal(struct yas_driver *d, int32_t *magnetic,
+ int32_t *mag_w_offset, int32_t * xy1y2,
+ int16_t *temperature)
+{
+ int rt = 0, result, i;
+ int32_t tmp[3];
+
+ YLOGD(("measure_msensor_normal IN\n"));
+
+ result = 0;
+ rt = yas_cdrv_measure(mag_w_offset, tmp, temperature);
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_measure failed[%d]\n", rt));
+ return rt;
+ }
+ for (i = 0; i < 3; i++)
+ xy1y2[i] = tmp[i];
+
+#ifdef YAS_MAG_MANUAL_OFFSET
+ for (i = 0; i < 3; i++)
+ mag_w_offset[i] -= get_manual_offset(d)[i];
+#endif
+ if (rt > 0) {
+ utimer_update(get_detect_overflow_timer(d));
+ set_overflow(d, TRUE);
+ if (utimer_is_timeout(get_detect_overflow_timer(d))) {
+ utimer_clear_timeout(get_detect_overflow_timer(d));
+ result |= YAS_REPORT_OVERFLOW_OCCURED;
+ }
+ if (get_measure_state(d) == YAS_MAG_STATE_NORMAL)
+ set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
+
+ } else {
+ utimer_clear(get_detect_overflow_timer(d));
+ set_overflow(d, FALSE);
+ if (get_measure_state(d) == YAS_MAG_STATE_NORMAL) {
+ utimer_clear(get_initcoil_timer(d));
+ utimer_clear(get_initcoil_giveup_timer(d));
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ tmp[i]
+ = (get_static_matrix(d)[i * 3 + 0] / 10 *
+ (mag_w_offset[0] / 10)) / 100 +
+ (get_static_matrix(d)[i * 3 + 1] / 10 *
+ (mag_w_offset[1] / 10)) / 100 +
+ (get_static_matrix(d)[i * 3 + 2] / 10 *
+ (mag_w_offset[2] / 10)) / 100;
+ }
+ for (i = 0; i < 3; i++)
+ magnetic[i] = mag_w_offset[i] = tmp[i];
+ if (is_valid_calib_offset(get_calib_offset(d))) {
+ for (i = 0; i < 3; i++)
+ magnetic[i] -= get_calib_offset(d)[i];
+ }
+ for (i = 0; i < 3; i++) {
+ tmp[i]
+ = (get_dynamic_matrix(d)[i * 3 + 0] / 10 *
+ (magnetic[0] / 10)) / 100 +
+ (get_dynamic_matrix(d)[i * 3 + 1] / 10 *
+ (magnetic[1] / 10)) / 100 + (get_dynamic_matrix(d)[i * 3 +
+ 2] /
+ 10 * (magnetic[2] / 10)) /
+ 100;
+ }
+ for (i = 0; i < 3; i++)
+ magnetic[i] = tmp[i];
+
+ if (get_filter_enable(d))
+ filter_filter(d, magnetic, magnetic);
+
+ YLOGD(("measure_msensor_normal OUT\n"));
+
+ return result;
+}
+
+static int
+measure_msensor(struct yas_driver *d, int32_t *magnetic,
+ int32_t *mag_w_offset, int32_t *xy1y2, int16_t *temperature)
+{
+ int result, i;
+
+ YLOGD(("measure_msensor IN\n"));
+
+ for (i = 0; i < 3; i++) {
+ magnetic[i] = get_previous_mag(d)[i];
+ mag_w_offset[i] = get_previous_mag_w_offset(d)[i];
+ xy1y2[i] = get_previous_xy1y2(d)[i];
+ *temperature = get_previous_temperature(d);
+ }
+
+ result = 0;
+ switch (get_measure_state(d)) {
+ case YAS_MAG_STATE_INIT_COIL:
+ result = init_coil(d);
+ break;
+ case YAS_MAG_STATE_MEASURE_OFFSET:
+ result = measure_offset(d);
+ break;
+ case YAS_MAG_STATE_NORMAL:
+ result = 0;
+ break;
+ default:
+ result = -1;
+ break;
+ }
+
+ if (result < 0)
+ return result;
+
+ if (!(result & YAS_REPORT_OVERFLOW_OCCURED))
+ result |=
+ measure_msensor_normal(d, magnetic, mag_w_offset, xy1y2,
+ temperature);
+ set_previous_mag(d, magnetic);
+ set_previous_xy1y2(d, xy1y2);
+ set_previous_mag_w_offset(d, mag_w_offset);
+ set_previous_temperature(d, *temperature);
+
+ YLOGD(("measure_msensor OUT\n"));
+
+ return result;
+}
+
+static int
+measure(struct yas_driver *d, int32_t *magnetic, int32_t *mag_w_offset,
+ int32_t *xy1y2, int16_t *temperature, uint32_t *time_delay)
+{
+ int result;
+ int counter;
+ uint32_t total = 0;
+
+ YLOGD(("measure IN\n"));
+
+ utimer_update(get_data_timer(d));
+ result = measure_msensor(d, magnetic, mag_w_offset, xy1y2,
+ temperature);
+ if (result < 0)
+ return result;
+
+ counter = get_delay_timer_counter(d);
+ total = utimer_get_total_time(get_data_timer(d));
+ if (utimer_get_delay(get_data_timer(d)) > 0)
+ counter -= total / utimer_get_delay(get_data_timer(d));
+ else
+ counter = 0;
+
+ if (utimer_is_timeout(get_data_timer(d))) {
+ utimer_clear_timeout(get_data_timer(d));
+
+ if (get_delay_timer_use_data(d)) {
+ result |= YAS_REPORT_DATA;
+ if (counter <= 0)
+ result |= YAS_REPORT_CALIB;
+ } else {
+ result |= YAS_REPORT_CALIB;
+ if (counter <= 0)
+ result |= YAS_REPORT_DATA;
+ }
+ }
+
+ if (counter <= 0)
+ set_delay_timer_counter(d, get_delay_timer_interval(d));
+ else
+ set_delay_timer_counter(d, counter);
+
+ *time_delay = utimer_sleep_time(get_data_timer(d));
+
+ YLOGD(("measure OUT [%d]\n", result));
+
+ return result;
+}
+
+static int resume(struct yas_driver *d)
+{
+ int32_t zero[] = { 0, 0, 0 };
+ struct yas_machdep_func func;
+ int rt;
+
+ YLOGI(("resume IN\n"));
+
+ func.device_open = d->callback.device_open;
+ func.device_close = d->callback.device_close;
+ func.device_write = d->callback.device_write;
+ func.device_read = d->callback.device_read;
+ func.msleep = d->callback.msleep;
+
+ rt =
+ yas_cdrv_init(YAS_TRANSFORMATION[get_position(d)], &func);
+
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_init failed[%d]\n", rt));
+ return rt;
+ }
+
+ utimer_clear(get_data_timer(d));
+ utimer_clear(get_initcoil_giveup_timer(d));
+ utimer_clear(get_initcoil_timer(d));
+ utimer_clear(get_detect_overflow_timer(d));
+
+ set_previous_mag(d, zero);
+ set_previous_xy1y2(d, zero);
+ set_previous_mag_w_offset(d, zero);
+ set_previous_temperature(d, 0);
+ set_overflow(d, FALSE);
+ set_initcoil_gaveup(d, FALSE);
+
+ filter_init(d);
+
+ if (is_valid_offset(d->offset.hard_offset)) {
+ yas_cdrv_set_offset(d->offset.hard_offset);
+ rt = yas_cdrv_actuate_initcoil();
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
+ set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
+ } else
+ set_measure_state(d, YAS_MAG_STATE_NORMAL);
+ } else {
+ rt = yas_cdrv_actuate_initcoil();
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
+ set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
+ } else
+ set_measure_state(d, YAS_MAG_STATE_MEASURE_OFFSET);
+ }
+
+ YLOGI(("resume OUT\n"));
+ return 0;
+}
+
+static int suspend(struct yas_driver *d)
+{
+ YLOGI(("suspend IN\n"));
+
+ (void)d;
+ yas_cdrv_term();
+
+ YLOGI(("suspend OUT\n"));
+ return 0;
+}
+
+static int check_interval(int ms)
+{
+ int index = -1;
+
+ if (ms <= supported_data_interval[0])
+ ms = supported_data_interval[0];
+ for (index = 0; index < NELEMS(supported_data_interval); index++) {
+ if (ms == supported_data_interval[index])
+ goto done;
+ else if (ms < supported_data_interval[index]) {
+ if (index != 0)
+ index -= 1;
+ goto done;
+ }
+ }
+done:
+ return index;
+}
+
+static int yas_get_delay_nolock(struct yas_driver *d, int *ms)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ if (get_delay_timer_use_data(d))
+ *ms = utimer_get_delay(get_data_timer(d));
+ else {
+ *ms =
+ utimer_get_delay(get_data_timer(d)) *
+ get_delay_timer_interval(d);
+ }
+ return YAS_NO_ERROR;
+}
+
+static int yas_set_delay_nolock(struct yas_driver *d, int ms)
+{
+ int index;
+ uint32_t delay_data, delay_calib;
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ index = check_interval(ms);
+ if (index < 0)
+ return YAS_ERROR_ARG;
+ delay_data = supported_data_interval[index];
+ delay_calib = supported_calib_interval[index];
+ set_delay_timer_use_data(d, delay_data < delay_calib);
+ if (delay_data < delay_calib) {
+ set_delay_timer_interval(d, delay_calib / delay_data);
+ set_delay_timer_counter(d, delay_calib / delay_data);
+ utimer_set_delay(get_data_timer(d),
+ supported_data_interval[index]);
+ } else {
+ set_delay_timer_interval(d, delay_data / delay_calib);
+ set_delay_timer_counter(d, delay_data / delay_calib);
+ utimer_set_delay(get_data_timer(d),
+ supported_calib_interval[index]);
+ }
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_get_offset_nolock(struct yas_driver *d, struct yas_mag_offset *offset)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ *offset = d->offset;
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_set_offset_nolock(struct yas_driver *d, struct yas_mag_offset *offset)
+{
+ int32_t zero[] = { 0, 0, 0 };
+ int rt;
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ if (!get_active(d)) {
+ d->offset = *offset;
+ return YAS_NO_ERROR;
+ }
+
+ if (!is_valid_offset(offset->hard_offset)
+ || is_offset_differ(offset->hard_offset, d->offset.hard_offset)) {
+ filter_init(d);
+
+ utimer_clear(get_data_timer(d));
+ utimer_clear(get_initcoil_giveup_timer(d));
+ utimer_clear(get_initcoil_timer(d));
+ utimer_clear(get_detect_overflow_timer(d));
+
+ set_previous_mag(d, zero);
+ set_previous_xy1y2(d, zero);
+ set_previous_mag_w_offset(d, zero);
+ set_previous_temperature(d, 0);
+ set_overflow(d, FALSE);
+ set_initcoil_gaveup(d, FALSE);
+ }
+ d->offset = *offset;
+
+ if (is_valid_offset(d->offset.hard_offset))
+ yas_cdrv_set_offset(d->offset.hard_offset);
+ else {
+ rt = yas_cdrv_actuate_initcoil();
+ if (rt < 0) {
+ YLOGE(("yas_cdrv_actuate_initcoil failed[%d]\n", rt));
+ set_measure_state(d, YAS_MAG_STATE_INIT_COIL);
+ } else
+ set_measure_state(d, YAS_MAG_STATE_MEASURE_OFFSET);
+ }
+
+ return YAS_NO_ERROR;
+}
+
+#ifdef YAS_MAG_MANUAL_OFFSET
+
+static int
+yas_get_manual_offset_nolock(struct yas_driver *d, struct yas_vector *offset)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ *offset = d->manual_offset;
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_set_manual_offset_nolock(struct yas_driver *d, struct yas_vector *offset)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ set_manual_offset(d, offset->v);
+
+ return YAS_NO_ERROR;
+}
+
+#endif
+
+static int
+yas_get_static_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
+{
+ int i;
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ for (i = 0; i < 9; i++)
+ matrix->matrix[i] = get_static_matrix(d)[i];
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_set_static_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ set_static_matrix(d, matrix->matrix);
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_get_dynamic_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
+{
+ int i;
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ for (i = 0; i < 9; i++)
+ matrix->matrix[i] = get_dynamic_matrix(d)[i];
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_set_dynamic_matrix_nolock(struct yas_driver *d, struct yas_matrix *matrix)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ set_dynamic_matrix(d, matrix->matrix);
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_get_enable_nolock(struct yas_driver *d)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ return get_active(d);
+}
+
+static int yas_set_enable_nolock(struct yas_driver *d, int active)
+{
+ int rt;
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ if (active) {
+ if (get_active(d))
+ return YAS_NO_ERROR;
+ rt = resume(d);
+ if (rt < 0)
+ return rt;
+ set_active(d, TRUE);
+ } else {
+ if (!get_active(d))
+ return YAS_NO_ERROR;
+ rt = suspend(d);
+ if (rt < 0)
+ return rt;
+ set_active(d, FALSE);
+ }
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_get_filter_nolock(struct yas_driver *d, struct yas_mag_filter *filter)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ filter->len = get_filter_len(d);
+ get_filter_noise(d, filter->noise);
+ filter->threshold = get_filter_thresh(d);
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_set_filter_nolock(struct yas_driver *d, struct yas_mag_filter *filter)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ set_filter_len(d, filter->len);
+ set_filter_noise(d, filter->noise);
+ set_filter_thresh(d, filter->threshold);
+ return YAS_NO_ERROR;
+}
+
+static int yas_get_filter_enable_nolock(struct yas_driver *d)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ return get_filter_enable(d);
+}
+
+static int yas_set_filter_enable_nolock(struct yas_driver *d, int enable)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ set_filter_enable(d, enable);
+ return YAS_NO_ERROR;
+}
+
+static int yas_get_position_nolock(struct yas_driver *d, int *position)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ *position = get_position(d);
+ return YAS_NO_ERROR;
+}
+
+static int yas_set_position_nolock(struct yas_driver *d, int position)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ if (get_active(d))
+ yas_cdrv_set_transformatiom_matrix(YAS_TRANSFORMATION
+ [position]);
+ set_position(d, position);
+ filter_init(d);
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_read_reg_nolock(struct yas_driver *d, uint8_t addr, uint8_t * buf, int len)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ if (!get_active(d)) {
+ if (d->callback.device_open() < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+ if (d->callback.device_read(addr, buf, len) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (!get_active(d)) {
+ if (d->callback.device_close() < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_write_reg_nolock(struct yas_driver *d, uint8_t addr, const uint8_t * buf,
+ int len)
+{
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ if (!get_active(d)) {
+ if (d->callback.device_open() < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+ if (d->callback.device_write(addr, buf, len) < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ if (!get_active(d)) {
+ if (d->callback.device_close() < 0)
+ return YAS_ERROR_DEVICE_COMMUNICATION;
+ }
+
+ return YAS_NO_ERROR;
+}
+
+static int
+yas_measure_nolock(struct yas_driver *d, struct yas_mag_data *data,
+ int *time_delay_ms)
+{
+ uint32_t time_delay = YAS_MAG_ERROR_DELAY;
+ int rt, i;
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+ *time_delay_ms = YAS_MAG_ERROR_DELAY;
+
+ if (!get_active(d)) {
+ for (i = 0; i < 3; i++) {
+ data->xyz.v[i] = get_previous_mag(d)[i];
+ data->raw.v[i] = get_previous_mag_w_offset(d)[i];
+ data->xy1y2.v[i] = get_previous_xy1y2(d)[i];
+ }
+ data->temperature = get_previous_temperature(d);
+ return YAS_NO_ERROR;
+ }
+
+ rt = measure(d, data->xyz.v, data->raw.v, data->xy1y2.v,
+ &data->temperature, &time_delay);
+ if (rt >= 0) {
+ *time_delay_ms = time_delay;
+ if (*time_delay_ms > 0)
+ *time_delay_ms += 1;
+ }
+
+ return rt;
+}
+
+static int yas_init_nolock(struct yas_driver *d)
+{
+#ifdef YAS_MAG_MANUAL_OFFSET
+ int32_t zero[] = { 0, 0, 0 };
+#endif
+ int32_t notransform[] = { 10000, 0, 0, 0, 10000, 0, 0, 0, 10000 };
+ int noise[] = {
+ YAS_MAG_DEFAULT_FILTER_NOISE_X,
+ YAS_MAG_DEFAULT_FILTER_NOISE_Y,
+ YAS_MAG_DEFAULT_FILTER_NOISE_Z
+ };
+
+ YLOGI(("yas_init_nolock IN\n"));
+
+ utimer_lib_init(this_driver.callback.current_time);
+ utimer_init(get_data_timer(d), 50);
+ utimer_init(get_initcoil_timer(d), YAS_INITCOIL_INTERVAL);
+ utimer_init(get_initcoil_giveup_timer(d), YAS_INITCOIL_GIVEUP_INTERVAL);
+ utimer_init(get_detect_overflow_timer(d), YAS_DETECT_OVERFLOW_INTERVAL);
+
+ set_delay_timer_use_data(d, 0);
+ set_delay_timer_interval(d,
+ YAS_DEFAULT_DATA_INTERVAL /
+ YAS_DEFAULT_CALIB_INTERVAL);
+ set_delay_timer_counter(d,
+ YAS_DEFAULT_DATA_INTERVAL /
+ YAS_DEFAULT_CALIB_INTERVAL);
+
+ set_filter_enable(d, FALSE);
+ set_filter_len(d, YAS_MAG_DEFAULT_FILTER_LEN);
+ set_filter_thresh(d, YAS_MAG_DEFAULT_FILTER_THRESH);
+ set_filter_noise(d, noise);
+ filter_init(d);
+ set_calib_offset(d, INVALID_CALIB_OFFSET);
+#ifdef YAS_MAG_MANUAL_OFFSET
+ set_manual_offset(d, zero);
+#endif
+ set_static_matrix(d, notransform);
+ set_dynamic_matrix(d, notransform);
+ set_offset(d, INVALID_OFFSET);
+ set_active(d, FALSE);
+ set_position(d, 0);
+
+ d->initialized = 1;
+
+ YLOGI(("yas_init_nolock OUT\n"));
+
+ return YAS_NO_ERROR;
+}
+
+static int yas_term_nolock(struct yas_driver *d)
+{
+ YLOGI(("yas_term_nolock\n"));
+
+ if (unlikely(!d->initialized))
+ return YAS_ERROR_NOT_INITIALIZED;
+
+ if (get_active(d))
+ suspend(d);
+ d->initialized = 0;
+
+ YLOGI(("yas_term_nolock out\n"));
+ return YAS_NO_ERROR;
+}
+
+static int yas_get_delay(void)
+{
+ int ms = 0, rt;
+
+ YLOGI(("yas_get_delay\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_delay_nolock(&this_driver, &ms);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_delay[%d] OUT\n", ms));
+
+ return (rt < 0 ? rt : ms);
+}
+
+static int yas_set_delay(int delay)
+{
+ int rt;
+
+ YLOGI(("yas_set_delay\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_delay_nolock(&this_driver, delay);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_delay OUT\n"));
+
+ return rt;
+}
+
+static int yas_get_offset(struct yas_mag_offset *offset)
+{
+ int rt;
+
+ YLOGI(("yas_get_offset\n"));
+
+ if (offset == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_offset_nolock(&this_driver, offset);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_offset[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_set_offset(struct yas_mag_offset *offset)
+{
+ int rt;
+
+ YLOGI(("yas_set_offset IN\n"));
+
+ if (offset == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_offset_nolock(&this_driver, offset);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_offset OUT\n"));
+
+ return rt;
+}
+
+#ifdef YAS_MAG_MANUAL_OFFSET
+
+static int yas_get_manual_offset(struct yas_vector *offset)
+{
+ int rt;
+
+ YLOGI(("yas_get_manual_offset\n"));
+
+ if (offset == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_manual_offset_nolock(&this_driver, offset);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_manual_offset[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_set_manual_offset(struct yas_vector *offset)
+{
+ int rt;
+
+ YLOGI(("yas_set_manual_offset IN\n"));
+
+ if (offset == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_manual_offset_nolock(&this_driver, offset);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_manual_offset OUT\n"));
+
+ return rt;
+}
+
+#endif
+
+static int yas_get_static_matrix(struct yas_matrix *matrix)
+{
+ int rt;
+
+ YLOGI(("yas_get_static_matrix\n"));
+
+ if (matrix == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_static_matrix_nolock(&this_driver, matrix);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_static_matrix[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_set_static_matrix(struct yas_matrix *matrix)
+{
+ int rt;
+
+ YLOGI(("yas_set_static_matrix IN\n"));
+
+ if (matrix == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_static_matrix_nolock(&this_driver, matrix);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_static_matrix OUT\n"));
+
+ return rt;
+}
+
+static int yas_get_dynamic_matrix(struct yas_matrix *matrix)
+{
+ int rt;
+
+ YLOGI(("yas_get_dynamic_matrix\n"));
+
+ if (matrix == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_dynamic_matrix_nolock(&this_driver, matrix);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_dynamic_matrix[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_set_dynamic_matrix(struct yas_matrix *matrix)
+{
+ int rt;
+
+ YLOGI(("yas_set_dynamic_matrix IN\n"));
+
+ if (matrix == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_dynamic_matrix_nolock(&this_driver, matrix);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_dynamic_matrix OUT\n"));
+
+ return rt;
+}
+
+static int yas_get_enable(void)
+{
+ int rt;
+
+ YLOGI(("yas_get_enable\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_enable_nolock(&this_driver);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_enable OUT[%d]\n", rt));
+
+ return rt;
+}
+
+static int yas_set_enable(int enable)
+{
+ int rt;
+
+ YLOGI(("yas_set_enable IN\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_enable_nolock(&this_driver, enable);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_enable OUT\n"));
+
+ return rt;
+}
+
+static int yas_get_filter(struct yas_mag_filter *filter)
+{
+ int rt;
+
+ YLOGI(("yas_get_filter\n"));
+
+ if (filter == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_filter_nolock(&this_driver, filter);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_filter[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_set_filter(struct yas_mag_filter *filter)
+{
+ int rt, i;
+
+ YLOGI(("yas_set_filter IN\n"));
+
+ if (filter == NULL
+ || filter->len < 0
+ || YAS_MAG_MAX_FILTER_LEN < filter->len || filter->threshold < 0) {
+ return YAS_ERROR_ARG;
+ }
+ for (i = 0; i < 3; i++) {
+ if (filter->noise[i] < 0)
+ return YAS_ERROR_ARG;
+ }
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_filter_nolock(&this_driver, filter);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_filter OUT\n"));
+
+ return rt;
+}
+
+static int yas_get_filter_enable(void)
+{
+ int rt;
+
+ YLOGI(("yas_get_filter_enable\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_filter_enable_nolock(&this_driver);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_filter_enable OUT[%d]\n", rt));
+
+ return rt;
+}
+
+static int yas_set_filter_enable(int enable)
+{
+ int rt;
+
+ YLOGI(("yas_set_filter_enable IN\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_filter_enable_nolock(&this_driver, enable);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_filter_enable OUT\n"));
+
+ return rt;
+}
+
+static int yas_get_position(void)
+{
+ int position = 0;
+ int rt;
+
+ YLOGI(("yas_get_position\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_get_position_nolock(&this_driver, &position);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_get_position[%d] OUT\n", position));
+
+ return (rt < 0 ? rt : position);
+}
+
+static int yas_set_position(int position)
+{
+ int rt;
+
+ YLOGI(("yas_set_position\n"));
+
+ if (position < 0 || 7 < position)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_set_position_nolock(&this_driver, position);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_set_position[%d] OUT\n", position));
+
+ return rt;
+}
+
+static int yas_read_reg(uint8_t addr, uint8_t *buf, int len)
+{
+ int rt;
+
+ YLOGI(("yas_read_reg\n"));
+
+ if (buf == NULL || len <= 0)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_read_reg_nolock(&this_driver, addr, buf, len);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_read_reg[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_write_reg(uint8_t addr, const uint8_t *buf, int len)
+{
+ int rt;
+
+ YLOGI(("yas_write_reg\n"));
+
+ if (buf == NULL || len <= 0)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_write_reg_nolock(&this_driver, addr, buf, len);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGI(("yas_write_reg[%d] OUT\n", rt));
+
+ return rt;
+}
+
+static int yas_measure(struct yas_mag_data *data, int *time_delay_ms)
+{
+ int rt;
+
+ YLOGD(("yas_measure IN\n"));
+
+ if (data == NULL || time_delay_ms == NULL)
+ return YAS_ERROR_ARG;
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_measure_nolock(&this_driver, data, time_delay_ms);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ YLOGD(("yas_measure OUT[%d]\n", rt));
+
+ return rt;
+}
+
+static int yas_init(void)
+{
+ int rt;
+
+ YLOGI(("yas_init\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_init_nolock(&this_driver);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ return rt;
+}
+
+static int yas_term(void)
+{
+ int rt;
+ YLOGI(("yas_term\n"));
+
+ if (lock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ rt = yas_term_nolock(&this_driver);
+
+ if (unlock() < 0)
+ return YAS_ERROR_RESTARTSYS;
+
+ return rt;
+}
+
+int yas_mag_driver_init(struct yas_mag_driver *f)
+{
+ if (f == NULL)
+ return YAS_ERROR_ARG;
+ if (f->callback.device_open == NULL
+ || f->callback.device_close == NULL
+ || f->callback.device_read == NULL
+ || f->callback.device_write == NULL
+ || f->callback.msleep == NULL || f->callback.current_time == NULL)
+ return YAS_ERROR_ARG;
+
+ f->init = yas_init;
+ f->term = yas_term;
+ f->get_delay = yas_get_delay;
+ f->set_delay = yas_set_delay;
+ f->get_offset = yas_get_offset;
+ f->set_offset = yas_set_offset;
+#ifdef YAS_MAG_MANUAL_OFFSET
+ f->get_manual_offset = yas_get_manual_offset;
+ f->set_manual_offset = yas_set_manual_offset;
+#endif
+ f->get_static_matrix = yas_get_static_matrix;
+ f->set_static_matrix = yas_set_static_matrix;
+ f->get_dynamic_matrix = yas_get_dynamic_matrix;
+ f->set_dynamic_matrix = yas_set_dynamic_matrix;
+ f->get_enable = yas_get_enable;
+ f->set_enable = yas_set_enable;
+ f->get_filter = yas_get_filter;
+ f->set_filter = yas_set_filter;
+ f->get_filter_enable = yas_get_filter_enable;
+ f->set_filter_enable = yas_set_filter_enable;
+ f->get_position = yas_get_position;
+ f->set_position = yas_set_position;
+ f->read_reg = yas_read_reg;
+ f->write_reg = yas_write_reg;
+ f->measure = yas_measure;
+
+ if ((f->callback.lock == NULL && f->callback.unlock != NULL)
+ || (f->callback.lock != NULL && f->callback.unlock == NULL)) {
+ this_driver.callback.lock = NULL;
+ this_driver.callback.unlock = NULL;
+ } else {
+ this_driver.callback.lock = f->callback.lock;
+ this_driver.callback.unlock = f->callback.unlock;
+ }
+ this_driver.callback.device_open = f->callback.device_open;
+ this_driver.callback.device_close = f->callback.device_close;
+ this_driver.callback.device_write = f->callback.device_write;
+ this_driver.callback.device_read = f->callback.device_read;
+ this_driver.callback.msleep = f->callback.msleep;
+ this_driver.callback.current_time = f->callback.current_time;
+ yas_term();
+
+ return YAS_NO_ERROR;
+}
diff --git a/drivers/sensor/yas_mag_driver.c b/drivers/sensor/yas_mag_driver.c
new file mode 100644
index 0000000..805ec32
--- /dev/null
+++ b/drivers/sensor/yas_mag_driver.c
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2010 Yamaha Corporation
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include <linux/sensor/yas.h>
+
+#if CONFIG_SENSORS_YAS532
+#include "yas_mag_driver-yas532.c"
+#else
+#include "yas_mag_driver-none.c"
+#endif
diff --git a/drivers/sensor/yas_mag_kernel_driver.c b/drivers/sensor/yas_mag_kernel_driver.c
new file mode 100644
index 0000000..0106958
--- /dev/null
+++ b/drivers/sensor/yas_mag_kernel_driver.c
@@ -0,0 +1,2192 @@
+/*
+ * Copyright (c) 2010-2011 Yamaha Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/atomic.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/workqueue.h>
+
+#define __LINUX_KERNEL_DRIVER__
+#include <linux/sensor/yas.h>
+#include <linux/sensor/sensors_core.h>
+#include "yas_mag_driver.c"
+
+#define SYSFS_PCBTEST
+#ifdef SYSFS_PCBTEST
+#include "yas_pcb_test.h"
+#include "yas_pcb_test.c"
+#endif
+
+#define GEOMAGNETIC_I2C_DEVICE_NAME "yas532"
+#define GEOMAGNETIC_INPUT_NAME "geomagnetic"
+#define GEOMAGNETIC_INPUT_RAW_NAME "geomagnetic_raw"
+#undef GEOMAGNETIC_PLATFORM_API
+
+#define ABS_STATUS (ABS_BRAKE)
+#define ABS_WAKE (ABS_MISC)
+
+#define ABS_RAW_DISTORTION (ABS_THROTTLE)
+#define ABS_RAW_THRESHOLD (ABS_RUDDER)
+#define ABS_RAW_SHAPE (ABS_WHEEL)
+#define ABS_RAW_MODE (ABS_HAT0X)
+#define ABS_RAW_REPORT (ABS_GAS)
+
+struct geomagnetic_data {
+ struct input_dev *input_data;
+ struct input_dev *input_raw;
+ struct delayed_work work;
+ struct semaphore driver_lock;
+ struct semaphore multi_lock;
+ atomic_t last_data[3];
+ atomic_t last_status;
+ atomic_t enable;
+ int filter_enable;
+ int filter_len;
+ int32_t filter_noise[3];
+ int32_t filter_threshold;
+ int delay;
+ int32_t threshold;
+ int32_t distortion[3];
+ int32_t shape;
+ int32_t ellipsoid_mode;
+ struct yas_mag_offset driver_offset;
+#if DEBUG
+ int suspend;
+#endif
+#ifdef YAS_MAG_MANUAL_OFFSET
+ struct yas_vector manual_offset;
+#endif
+ struct yas_matrix static_matrix;
+ struct yas_matrix dynamic_matrix;
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct list_head devfile_list;
+ struct list_head raw_devfile_list;
+#endif
+ struct device *magnetic_sensor_device;
+ struct mag_platform_data *mag_pdata;
+ uint8_t dev_id;
+ int noise_test_init;
+};
+
+static struct i2c_client *this_client;
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+
+#include <linux/miscdevice.h>
+#define MAX_COUNT (64)
+#define SENSOR_NAME "geomagnetic"
+#define SENSOR_RAW_NAME "geomagnetic_raw"
+
+struct sensor_device {
+ struct list_head list;
+ struct mutex lock;
+ wait_queue_head_t waitq;
+ struct input_event events[MAX_COUNT];
+ int head, num_event;
+};
+
+static void get_time_stamp(struct timeval *tv)
+{
+ struct timespec ts;
+ ktime_get_ts(&ts);
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+}
+
+static void make_event(struct input_event *ev, int type, int code, int value)
+{
+ struct timeval tv;
+ get_time_stamp(&tv);
+ ev->type = type;
+ ev->code = code;
+ ev->value = value;
+ ev->time = tv;
+}
+
+static void
+make_event_w_time(struct input_event *ev, int type, int code, int value,
+ struct timeval *tv)
+{
+ ev->type = type;
+ ev->code = code;
+ ev->value = value;
+ ev->time = *tv;
+}
+
+static void sensor_enq(struct sensor_device *kdev, struct input_event *ev)
+{
+ int idx;
+
+ idx = kdev->head + kdev->num_event;
+ if (MAX_COUNT <= idx)
+ idx -= MAX_COUNT;
+ kdev->events[idx] = *ev;
+ kdev->num_event++;
+ if (MAX_COUNT < kdev->num_event) {
+ kdev->num_event = MAX_COUNT;
+ kdev->head++;
+ if (MAX_COUNT <= kdev->head)
+ kdev->head -= MAX_COUNT;
+ }
+}
+
+static int sensor_deq(struct sensor_device *kdev, struct input_event *ev)
+{
+ if (kdev->num_event == 0)
+ return 0;
+
+ *ev = kdev->events[kdev->head];
+ kdev->num_event--;
+ kdev->head++;
+ if (MAX_COUNT <= kdev->head)
+ kdev->head -= MAX_COUNT;
+ return 1;
+}
+
+static void
+sensor_event(struct list_head *devlist, struct input_event *ev, int num)
+{
+ struct sensor_device *kdev;
+ int i;
+
+ list_for_each_entry(kdev, devlist, list) {
+ mutex_lock(&kdev->lock);
+ for (i = 0; i < num; i++)
+ sensor_enq(kdev, &ev[i]);
+ mutex_unlock(&kdev->lock);
+ wake_up_interruptible(&kdev->waitq);
+ }
+}
+
+static ssize_t
+sensor_write(struct file *f, const char __user *buf, size_t count,
+ loff_t *pos)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ struct sensor_device *kdev;
+ struct input_event ev[MAX_COUNT];
+ int num, i;
+
+ if (count < sizeof(struct input_event))
+ return -EINVAL;
+ num = count / sizeof(struct input_event);
+ if (MAX_COUNT < num)
+ num = MAX_COUNT;
+
+ if (copy_from_user(ev, buf, num * sizeof(struct input_event)))
+ return -EFAULT;
+
+ list_for_each_entry(kdev, &data->devfile_list, list) {
+ mutex_lock(&kdev->lock);
+ for (i = 0; i < num; i++)
+ sensor_enq(kdev, &ev[i]);
+ mutex_unlock(&kdev->lock);
+ wake_up_interruptible(&kdev->waitq);
+ }
+
+ return count;
+}
+
+static ssize_t
+sensor_read(struct file *f, char __user *buf, size_t count, loff_t *pos)
+{
+ struct sensor_device *kdev = f->private_data;
+ int rt, num;
+ struct input_event ev[MAX_COUNT];
+
+ if (count < sizeof(struct input_event))
+ return -EINVAL;
+
+ rt = wait_event_interruptible(kdev->waitq, kdev->num_event != 0);
+ if (rt)
+ return rt;
+
+ mutex_lock(&kdev->lock);
+ for (num = 0; num < count / sizeof(struct input_event); num++) {
+ if (!sensor_deq(kdev, &ev[num]))
+ break;
+ }
+ mutex_unlock(&kdev->lock);
+
+ if (copy_to_user(buf, ev, num * sizeof(struct input_event)))
+ return -EFAULT;
+
+ return num * sizeof(struct input_event);
+}
+
+static unsigned int sensor_poll(struct file *f, struct poll_table_struct *wait)
+{
+ struct sensor_device *kdev = f->private_data;
+
+ poll_wait(f, &kdev->waitq, wait);
+ if (kdev->num_event != 0)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+static int sensor_open(struct inode *inode, struct file *f)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ struct sensor_device *kdev;
+
+ kdev = kzalloc(sizeof(struct sensor_device), GFP_KERNEL);
+ if (!kdev)
+ return -ENOMEM;
+
+ mutex_init(&kdev->lock);
+ init_waitqueue_head(&kdev->waitq);
+ f->private_data = kdev;
+ kdev->head = 0;
+ kdev->num_event = 0;
+ list_add(&kdev->list, &data->devfile_list);
+
+ return 0;
+}
+
+static int sensor_release(struct inode *inode, struct file *f)
+{
+ struct sensor_device *kdev = f->private_data;
+
+ list_del(&kdev->list);
+ kfree(kdev);
+
+ return 0;
+}
+
+static int sensor_raw_open(struct inode *inode, struct file *f)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ struct sensor_device *kdev;
+
+ kdev = kzalloc(sizeof(struct sensor_device), GFP_KERNEL);
+ if (!kdev)
+ return -ENOMEM;
+
+ mutex_init(&kdev->lock);
+ init_waitqueue_head(&kdev->waitq);
+ f->private_data = kdev;
+ kdev->head = 0;
+ kdev->num_event = 0;
+ list_add(&kdev->list, &data->raw_devfile_list);
+
+ return 0;
+}
+
+const struct file_operations sensor_fops = {
+ .owner = THIS_MODULE,
+ .open = sensor_open,
+ .release = sensor_release,
+ .write = sensor_write,
+ .read = sensor_read,
+ .poll = sensor_poll,
+};
+
+static struct miscdevice sensor_devfile = {
+ .name = SENSOR_NAME,
+ .fops = &sensor_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+};
+
+const struct file_operations sensor_raw_fops = {
+ .owner = THIS_MODULE,
+ .open = sensor_raw_open,
+ .release = sensor_release,
+ .write = sensor_write,
+ .read = sensor_read,
+ .poll = sensor_poll,
+};
+
+static struct miscdevice sensor_raw_devfile = {
+ .name = SENSOR_RAW_NAME,
+ .fops = &sensor_raw_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+};
+
+#endif
+
+static int geomagnetic_i2c_open(void)
+{
+ return 0;
+}
+
+static int geomagnetic_i2c_close(void)
+{
+ return 0;
+}
+
+#if YAS_MAG_DRIVER == YAS_MAG_DRIVER_YAS529
+static int geomagnetic_i2c_write(const uint8_t *buf, int len)
+{
+ if (i2c_master_send(this_client, buf, len) < 0)
+ return -1;
+#if DEBUG
+ YLOGD(("[W] [%02x]\n", buf[0]));
+#endif
+
+ return 0;
+}
+
+static int geomagnetic_i2c_read(uint8_t *buf, int len)
+{
+ if (i2c_master_recv(this_client, buf, len) < 0)
+ return -1;
+ return 0;
+}
+
+#else
+
+static int geomagnetic_i2c_write(uint8_t addr, const uint8_t *buf, int len)
+{
+ uint8_t tmp[16];
+
+ if (sizeof(tmp) - 1 < len)
+ return -1;
+
+ tmp[0] = addr;
+ memcpy(&tmp[1], buf, len);
+
+ if (i2c_master_send(this_client, tmp, len + 1) < 0)
+ return -1;
+#if DEBUG
+ YLOGD(("[W] addr[%02x] [%02x]\n", addr, buf[0]));
+#endif
+
+ return 0;
+}
+
+static int geomagnetic_i2c_read(uint8_t addr, uint8_t *buf, int len)
+{
+ struct i2c_msg msg[2];
+ int err;
+
+ msg[0].addr = this_client->addr;
+ msg[0].flags = 0;
+ msg[0].len = 1;
+ msg[0].buf = &addr;
+ msg[1].addr = this_client->addr;
+ msg[1].flags = I2C_M_RD;
+ msg[1].len = len;
+ msg[1].buf = buf;
+
+ err = i2c_transfer(this_client->adapter, msg, 2);
+ if (err != 2) {
+ dev_err(&this_client->dev,
+ "i2c_transfer() read error: slave_addr=%02x, reg_addr=%02x, err=%d\n",
+ this_client->addr, addr, err);
+ return err;
+ }
+
+ return 0;
+}
+
+#endif
+
+static int geomagnetic_lock(void)
+{
+ struct geomagnetic_data *data = NULL;
+ int rt;
+
+ if (this_client == NULL)
+ return -1;
+
+ data = i2c_get_clientdata(this_client);
+ rt = down_interruptible(&data->driver_lock);
+ if (rt < 0)
+ up(&data->driver_lock);
+ return rt;
+}
+
+static int geomagnetic_unlock(void)
+{
+ struct geomagnetic_data *data = NULL;
+
+ if (this_client == NULL)
+ return -1;
+
+ data = i2c_get_clientdata(this_client);
+ up(&data->driver_lock);
+ return 0;
+}
+
+static void geomagnetic_msleep(int ms)
+{
+ usleep_range(ms * 999, ms * 1000);
+}
+
+static void geomagnetic_current_time(int32_t *sec, int32_t *msec)
+{
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+
+ *sec = tv.tv_sec;
+ *msec = tv.tv_usec / 1000;
+}
+
+static struct yas_mag_driver hwdep_driver = {
+ .callback = {
+ .lock = geomagnetic_lock,
+ .unlock = geomagnetic_unlock,
+ .device_open = geomagnetic_i2c_open,
+ .device_close = geomagnetic_i2c_close,
+ .device_read = geomagnetic_i2c_read,
+ .device_write = geomagnetic_i2c_write,
+ .msleep = geomagnetic_msleep,
+ .current_time = geomagnetic_current_time,
+ },
+};
+
+static int geomagnetic_multi_lock(void)
+{
+ struct geomagnetic_data *data = NULL;
+ int rt;
+
+ if (this_client == NULL)
+ return -1;
+
+ data = i2c_get_clientdata(this_client);
+ rt = down_interruptible(&data->multi_lock);
+ if (rt < 0)
+ up(&data->multi_lock);
+ return rt;
+}
+
+static int geomagnetic_multi_unlock(void)
+{
+ struct geomagnetic_data *data = NULL;
+
+ if (this_client == NULL)
+ return -1;
+
+ data = i2c_get_clientdata(this_client);
+ up(&data->multi_lock);
+ return 0;
+}
+
+static int geomagnetic_enable(struct geomagnetic_data *data)
+{
+ if (!atomic_cmpxchg(&data->enable, 0, 1))
+ schedule_delayed_work(&data->work, 0);
+
+ return 0;
+}
+
+static int geomagnetic_disable(struct geomagnetic_data *data)
+{
+ if (atomic_cmpxchg(&data->enable, 1, 0))
+ cancel_delayed_work_sync(&data->work);
+
+ return 0;
+}
+
+/* Sysfs interface */
+static ssize_t
+geomagnetic_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ int delay;
+
+ geomagnetic_multi_lock();
+
+ delay = data->delay;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", delay);
+}
+
+static ssize_t
+geomagnetic_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ if (hwdep_driver.set_delay == NULL)
+ return -ENOTTY;
+
+ geomagnetic_multi_lock();
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+ if (hwdep_driver.set_delay(value) == 0)
+ data->delay = value;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+
+ return sprintf(buf, "%d\n", atomic_read(&data->enable));
+}
+
+static ssize_t
+geomagnetic_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+ value = !(!value);
+
+ if (hwdep_driver.set_enable == NULL)
+ return -ENOTTY;
+
+ if (geomagnetic_multi_lock() < 0)
+ return count;
+
+ if (hwdep_driver.set_enable(value) == 0) {
+ if (value)
+ geomagnetic_enable(data);
+ else
+ geomagnetic_disable(data);
+ }
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_filter_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ int filter_enable;
+
+ geomagnetic_multi_lock();
+
+ filter_enable = data->filter_enable;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", filter_enable);
+}
+
+static ssize_t
+geomagnetic_filter_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ unsigned long value;
+ int error;
+
+ if (hwdep_driver.set_filter_enable == NULL)
+ return -ENOTTY;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ if (geomagnetic_multi_lock() < 0)
+ return count;
+
+ if (hwdep_driver.set_filter_enable(value) == 0)
+ data->filter_enable = !!value;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_filter_len_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ int filter_len;
+
+ geomagnetic_multi_lock();
+
+ filter_len = data->filter_len;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", filter_len);
+}
+
+static ssize_t
+geomagnetic_filter_len_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ struct yas_mag_filter filter;
+ unsigned long value;
+ int error;
+
+ if (hwdep_driver.get_filter == NULL || hwdep_driver.set_filter == NULL)
+ return -ENOTTY;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ if (geomagnetic_multi_lock() < 0)
+ return count;
+
+ hwdep_driver.get_filter(&filter);
+ filter.len = value;
+ if (hwdep_driver.set_filter(&filter) == 0)
+ data->filter_len = value;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_filter_noise_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int rt;
+
+ geomagnetic_multi_lock();
+
+ rt = sprintf(buf, "%d %d %d\n",
+ data->filter_noise[0],
+ data->filter_noise[1], data->filter_noise[2]);
+
+ geomagnetic_multi_unlock();
+
+ return rt;
+}
+
+static ssize_t
+geomagnetic_filter_noise_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct yas_mag_filter filter;
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int32_t filter_noise[3];
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d %d %d",
+ &filter_noise[0], &filter_noise[1], &filter_noise[2]);
+ hwdep_driver.get_filter(&filter);
+ memcpy(filter.noise, filter_noise, sizeof(filter.noise));
+ if (hwdep_driver.set_filter(&filter) == 0)
+ memcpy(data->filter_noise, filter_noise,
+ sizeof(data->filter_noise));
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_filter_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ int32_t filter_threshold;
+
+ geomagnetic_multi_lock();
+
+ filter_threshold = data->filter_threshold;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", filter_threshold);
+}
+
+static ssize_t
+geomagnetic_filter_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ struct yas_mag_filter filter;
+ unsigned long value;
+ int error;
+
+ if (hwdep_driver.get_filter == NULL || hwdep_driver.set_filter == NULL)
+ return -ENOTTY;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ if (geomagnetic_multi_lock() < 0)
+ return count;
+
+ hwdep_driver.get_filter(&filter);
+ filter.threshold = value;
+ if (hwdep_driver.set_filter(&filter) == 0)
+ data->filter_threshold = value;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_position_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (hwdep_driver.get_position == NULL)
+ return -ENOTTY;
+ return sprintf(buf, "%d\n", hwdep_driver.get_position());
+}
+
+static ssize_t
+geomagnetic_position_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ if (hwdep_driver.set_position == NULL)
+ return -ENOTTY;
+ hwdep_driver.set_position(value);
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_data_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ int rt;
+
+ rt = sprintf(buf, "%d %d %d\n",
+ atomic_read(&data->last_data[0]),
+ atomic_read(&data->last_data[1]),
+ atomic_read(&data->last_data[2]));
+
+ return rt;
+}
+
+static ssize_t
+geomagnetic_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ int rt;
+
+ rt = sprintf(buf, "%d\n", atomic_read(&data->last_status));
+
+ return rt;
+}
+
+static ssize_t
+geomagnetic_status_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ static int16_t cnt = 1;
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev;
+#endif
+ int accuracy = 0;
+ int code = 0;
+ int value = 0;
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d", &accuracy);
+ if (0 <= accuracy && accuracy <= 3)
+ atomic_set(&data->last_status, accuracy);
+ code |= YAS_REPORT_CALIB_OFFSET_CHANGED;
+ value = (cnt++ << 16) | (code);
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ mkev(&ev, EV_ABS, ABS_RAW_REPORT, value);
+ sensor_event(&data->raw_devfile_list, &ev, 1);
+#else
+ input_report_abs(data->input_raw, ABS_RAW_REPORT, value);
+ input_sync(data->input_raw);
+#endif
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_wake_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_data);
+ static int16_t cnt = 1;
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+ make_event(ev, EV_ABS, ABS_WAKE, cnt++);
+ sensor_event(&data->devfile_list, ev, 1);
+#else
+ input_report_abs(data->input_data, ABS_WAKE, cnt++);
+ input_sync(data->input_data);
+#endif
+
+ return count;
+}
+
+#if DEBUG
+
+static int geomagnetic_suspend(struct i2c_client *client, pm_message_t mesg);
+static int geomagnetic_resume(struct i2c_client *client);
+
+static ssize_t
+geomagnetic_debug_suspend_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input);
+
+ return sprintf(buf, "%d\n", data->suspend);
+}
+
+static ssize_t
+geomagnetic_debug_suspend_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long suspend;
+ int error;
+
+ error = strict_strtoul(buf, 10, &suspend);
+ if (unlikely(error))
+ return error;
+
+ if (suspend) {
+ pm_message_t msg;
+ memset(&msg, 0, sizeof(msg));
+ geomagnetic_suspend(this_client, msg);
+ } else
+ geomagnetic_resume(this_client);
+
+ return count;
+}
+
+#endif /* DEBUG */
+
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ geomagnetic_delay_show, geomagnetic_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ geomagnetic_enable_show, geomagnetic_enable_store);
+static DEVICE_ATTR(filter_enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ geomagnetic_filter_enable_show,
+ geomagnetic_filter_enable_store);
+static DEVICE_ATTR(filter_len, S_IRUGO | S_IWUSR | S_IWGRP,
+ geomagnetic_filter_len_show, geomagnetic_filter_len_store);
+static DEVICE_ATTR(filter_threshold, S_IRUGO | S_IWUSR | S_IWGRP,
+ geomagnetic_filter_threshold_show,
+ geomagnetic_filter_threshold_store);
+static DEVICE_ATTR(filter_noise, S_IRUGO | S_IWUSR | S_IWGRP,
+ geomagnetic_filter_noise_show,
+ geomagnetic_filter_noise_store);
+static DEVICE_ATTR(data, S_IRUGO, geomagnetic_data_show, NULL);
+static DEVICE_ATTR(status, S_IRUGO|S_IWUSR|S_IWGRP, geomagnetic_status_show,
+ geomagnetic_status_store);
+static DEVICE_ATTR(wake, S_IWUSR | S_IWGRP, NULL, geomagnetic_wake_store);
+static DEVICE_ATTR(position, S_IRUGO | S_IWUSR,
+ geomagnetic_position_show, geomagnetic_position_store);
+#if DEBUG
+static DEVICE_ATTR(debug_suspend, S_IRUGO | S_IWUSR,
+ geomagnetic_debug_suspend_show,
+ geomagnetic_debug_suspend_store);
+#endif /* DEBUG */
+
+static struct attribute *geomagnetic_attributes[] = {
+ &dev_attr_delay.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_filter_enable.attr,
+ &dev_attr_filter_len.attr,
+ &dev_attr_filter_threshold.attr,
+ &dev_attr_filter_noise.attr,
+ &dev_attr_data.attr,
+ &dev_attr_status.attr,
+ &dev_attr_wake.attr,
+ &dev_attr_position.attr,
+#if DEBUG
+ &dev_attr_debug_suspend.attr,
+#endif /* DEBUG */
+ NULL
+};
+
+static struct attribute_group geomagnetic_attribute_group = {
+ .attrs = geomagnetic_attributes
+};
+
+static ssize_t
+geomagnetic_raw_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int threshold;
+
+ geomagnetic_multi_lock();
+
+ threshold = data->threshold;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", threshold);
+}
+
+static ssize_t
+geomagnetic_raw_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ geomagnetic_multi_lock();
+
+ if (0 <= value && value <= 2) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+ make_event(ev, EV_ABS, ABS_RAW_THRESHOLD, value);
+ sensor_event(&data->raw_devfile_list, ev, 1);
+#endif
+ data->threshold = value;
+#ifndef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ input_report_abs(data->input_raw, ABS_RAW_THRESHOLD, value);
+ input_sync(data->input_raw);
+#endif
+ }
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_raw_distortion_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int rt;
+
+ geomagnetic_multi_lock();
+
+ rt = sprintf(buf, "%d %d %d\n",
+ data->distortion[0],
+ data->distortion[1], data->distortion[2]);
+
+ geomagnetic_multi_unlock();
+
+ return rt;
+}
+
+static ssize_t
+geomagnetic_raw_distortion_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int32_t distortion[3];
+ static int32_t val = 1;
+ int i;
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d %d %d", &distortion[0], &distortion[1], &distortion[2]);
+ if (distortion[0] > 0 && distortion[1] > 0 && distortion[2] > 0) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+ make_event(ev, EV_ABS, ABS_RAW_DISTORTION, val++);
+ sensor_event(&data->raw_devfile_list, ev, 1);
+#endif
+ for (i = 0; i < 3; i++)
+ data->distortion[i] = distortion[i];
+#ifndef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ input_report_abs(data->input_raw, ABS_RAW_DISTORTION, val++);
+ input_sync(data->input_raw);
+#endif
+ }
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_raw_shape_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int shape;
+
+ geomagnetic_multi_lock();
+
+ shape = data->shape;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", shape);
+}
+
+static ssize_t
+geomagnetic_raw_shape_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+ geomagnetic_multi_lock();
+
+ if (0 == value || value == 1) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+ make_event(ev, EV_ABS, ABS_RAW_SHAPE, value);
+ sensor_event(&data->raw_devfile_list, ev, 1);
+#endif
+ data->shape = value;
+#ifndef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ input_report_abs(data->input_raw, ABS_RAW_SHAPE, value);
+ input_sync(data->input_raw);
+#endif
+ }
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_raw_offsets_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_mag_offset offset;
+ int accuracy;
+
+ geomagnetic_multi_lock();
+
+ offset = data->driver_offset;
+ accuracy = atomic_read(&data->last_status);
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d %d %d %d %d %d %d\n",
+ offset.hard_offset[0],
+ offset.hard_offset[1],
+ offset.hard_offset[2],
+ offset.calib_offset.v[0],
+ offset.calib_offset.v[1],
+ offset.calib_offset.v[2], accuracy);
+}
+
+static ssize_t
+geomagnetic_raw_offsets_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_mag_offset offset;
+ int32_t hard_offset[3];
+ int i, accuracy;
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d %d %d %d %d %d %d",
+ &hard_offset[0],
+ &hard_offset[1],
+ &hard_offset[2],
+ &offset.calib_offset.v[0],
+ &offset.calib_offset.v[1], &offset.calib_offset.v[2], &accuracy);
+ if (0 <= accuracy && accuracy <= 3) {
+ for (i = 0; i < 3; i++)
+ offset.hard_offset[i] = (int8_t) hard_offset[i];
+
+ if (hwdep_driver.set_offset(&offset) == 0) {
+ atomic_set(&data->last_status, accuracy);
+ data->driver_offset = offset;
+ }
+ }
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+#ifdef YAS_MAG_MANUAL_OFFSET
+static ssize_t
+geomagnetic_raw_manual_offsets_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_vector offset;
+
+ geomagnetic_multi_lock();
+
+ offset = data->manual_offset;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d %d %d\n", offset.v[0], offset.v[1],
+ offset.v[2]);
+}
+
+static ssize_t
+geomagnetic_raw_manual_offsets_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_vector offset;
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d %d %d", &offset.v[0], &offset.v[1], &offset.v[2]);
+ if (hwdep_driver.set_manual_offset(&offset) == 0)
+ data->manual_offset = offset;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+#endif
+
+static ssize_t
+geomagnetic_raw_static_matrix_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_matrix matrix;
+
+ geomagnetic_multi_lock();
+
+ matrix = data->static_matrix;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d %d %d %d %d %d %d %d %d\n",
+ matrix.matrix[0], matrix.matrix[1], matrix.matrix[2],
+ matrix.matrix[3], matrix.matrix[4], matrix.matrix[5],
+ matrix.matrix[6], matrix.matrix[7], matrix.matrix[8]);
+}
+
+static ssize_t
+geomagnetic_raw_static_matrix_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_matrix matrix;
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d %d %d %d %d %d %d %d %d",
+ &matrix.matrix[0], &matrix.matrix[1], &matrix.matrix[2],
+ &matrix.matrix[3], &matrix.matrix[4], &matrix.matrix[5],
+ &matrix.matrix[6], &matrix.matrix[7], &matrix.matrix[8]);
+ if (hwdep_driver.set_static_matrix(&matrix) == 0)
+ data->static_matrix = matrix;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_raw_dynamic_matrix_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_matrix matrix;
+
+ geomagnetic_multi_lock();
+
+ matrix = data->dynamic_matrix;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d %d %d %d %d %d %d %d %d\n",
+ matrix.matrix[0], matrix.matrix[1], matrix.matrix[2],
+ matrix.matrix[3], matrix.matrix[4], matrix.matrix[5],
+ matrix.matrix[6], matrix.matrix[7], matrix.matrix[8]);
+}
+
+static ssize_t
+geomagnetic_raw_dynamic_matrix_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ struct yas_matrix matrix;
+
+ geomagnetic_multi_lock();
+
+ sscanf(buf, "%d %d %d %d %d %d %d %d %d",
+ &matrix.matrix[0], &matrix.matrix[1], &matrix.matrix[2],
+ &matrix.matrix[3], &matrix.matrix[4], &matrix.matrix[5],
+ &matrix.matrix[6], &matrix.matrix[7], &matrix.matrix[8]);
+ if (hwdep_driver.set_dynamic_matrix(&matrix) == 0)
+ data->dynamic_matrix = matrix;
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+static ssize_t
+geomagnetic_raw_ellipsoid_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ int ellipsoid_mode;
+
+ geomagnetic_multi_lock();
+
+ ellipsoid_mode = data->ellipsoid_mode;
+
+ geomagnetic_multi_unlock();
+
+ return sprintf(buf, "%d\n", ellipsoid_mode);
+}
+
+static ssize_t
+geomagnetic_raw_ellipsoid_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_raw = to_input_dev(dev);
+ struct geomagnetic_data *data = input_get_drvdata(input_raw);
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+ value = !(!value);
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+#endif
+
+ geomagnetic_multi_lock();
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ make_event(ev, EV_ABS, ABS_RAW_MODE, value);
+ sensor_event(&data->raw_devfile_list, ev, 1);
+#endif
+ data->ellipsoid_mode = value;
+#ifndef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ input_report_abs(data->input_raw, ABS_RAW_MODE, value);
+ input_sync(data->input_raw);
+#endif
+
+ geomagnetic_multi_unlock();
+
+ return count;
+}
+
+#ifdef SYSFS_PCBTEST
+
+static int
+pcbtest_i2c_write(uint8_t slave, uint8_t addr, const uint8_t *buf, int len)
+{
+ return geomagnetic_i2c_write(addr, buf, len);
+}
+
+static int
+pcbtest_i2c_read(uint8_t slave, uint8_t addr, uint8_t *buf, int len)
+{
+ return geomagnetic_i2c_read(addr, buf, len);
+}
+
+static struct yas_pcb_test pcbtest = {
+ .callback = {
+ .power_on = NULL,
+ .power_off = NULL,
+ .i2c_open = geomagnetic_i2c_open,
+ .i2c_close = geomagnetic_i2c_close,
+ .i2c_read = pcbtest_i2c_read,
+ .i2c_write = pcbtest_i2c_write,
+ .msleep = geomagnetic_msleep,
+ .read_intpin = NULL,
+ },
+};
+
+
+static ssize_t
+geomagnetic_raw_self_test_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ int id, x, y1, y2, dir, sx, sy, ohx, ohy, ohz;
+ int err1, err2, err3, err4, err5, err6, err7;
+
+ if (data->noise_test_init)
+ pcbtest.power_off();
+ err1 = pcbtest.power_on_and_device_check(&id);
+ err3 = pcbtest.initialization();
+ err4 =
+ pcbtest.offset_control_measurement_and_set_offset_register(
+ &x, &y1, &y2);
+ err5 = pcbtest.direction_measurement(&dir);
+ err6 =
+ pcbtest.sensitivity_measurement_of_magnetic_sensor_by_test_coil(
+ &sx, &sy);
+ err7 = pcbtest.magnetic_field_level_check(&ohx, &ohy, &ohz);
+ err2 = pcbtest.power_off();
+ data->noise_test_init = 0;
+ if (unlikely(id != 0x2))
+ err1 = -1;
+ if (unlikely(x < -30 || x > 30))
+ err4 = -1;
+ if (unlikely(y1 < -30 || y1 > 30))
+ err4 = -1;
+ if (unlikely(y2 < -30 || y2 > 30))
+ err4 = -1;
+ if (unlikely(sx < 17 || sy < 22))
+ err6 = -1;
+ if (unlikely(ohx < -600 || ohx > 600))
+ err7 = -1;
+ if (unlikely(ohy < -600 || ohy > 600))
+ err7 = -1;
+ if (unlikely(ohz < -600 || ohz > 600))
+ err7 = -1;
+
+ pr_info("%s\n"
+ "Test1 - err = %d, id = %d\n"
+ "Test3 - err = %d\n"
+ "Test4 - err = %d, offset = %d,%d,%d\n"
+ "Test5 - err = %d, direction = %d\n"
+ "Test6 - err = %d, sensitivity = %d,%d\n"
+ "Test7 - err = %d, offset = %d,%d,%d\n"
+ "Test2 - err = %d\n", __func__,
+ err1, id, err3, err4, x, y1, y2, err5, dir, err6, sx, sy,
+ err7, ohx, ohy, ohz, err2);
+
+ return sprintf(buf,
+ "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
+ err1, id, err3, err4, x, y1, y2, err5, dir, err6, sx,
+ sy, err7, ohx, ohy, ohz, err2);
+}
+
+static ssize_t
+geomagnetic_raw_self_test_noise_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ int id, x, y1, y2, dir, hx0, hy0, hz0;
+ int err8;
+#if CONFIG_MACH_KONA_SENSOR
+ pcbtest.power_on_and_device_check(&id);
+ pcbtest.initialization();
+ pcbtest.offset_control_measurement_and_set_offset_register(
+ &x, &y1, &y2);
+#else
+ if (!data->noise_test_init) {
+ pcbtest.power_on_and_device_check(&id);
+ pcbtest.initialization();
+ pcbtest.offset_control_measurement_and_set_offset_register(
+ &x, &y1, &y2);
+ }
+#endif
+ pcbtest.direction_measurement(&dir);
+ err8 = pcbtest.noise_level_check(&hx0, &hy0, &hz0);
+ if (err8 < 0) {
+ pr_err("%s: err8=%d\n", __func__, err8);
+ hx0 = 0;
+ hy0 = 0;
+ hz0 = 0;
+ }
+ usleep_range(3000, 3100);
+ data->noise_test_init = 1;
+ pr_debug("%s: %d, %d, %d\n", __func__, hx0, hy0, hz0);
+ return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n", hx0, hy0, hz0);
+}
+
+static DEVICE_ATTR(self_test, S_IRUSR, geomagnetic_raw_self_test_show, NULL);
+static DEVICE_ATTR(self_test_noise, S_IRUSR,
+ geomagnetic_raw_self_test_noise_show, NULL);
+
+#endif
+
+
+static DEVICE_ATTR(threshold, S_IRUGO | S_IWUSR,
+ geomagnetic_raw_threshold_show,
+ geomagnetic_raw_threshold_store);
+static DEVICE_ATTR(distortion, S_IRUGO | S_IWUSR,
+ geomagnetic_raw_distortion_show,
+ geomagnetic_raw_distortion_store);
+static DEVICE_ATTR(shape, S_IRUGO | S_IWUSR, geomagnetic_raw_shape_show,
+ geomagnetic_raw_shape_store);
+static DEVICE_ATTR(offsets, S_IRUGO | S_IWUSR, geomagnetic_raw_offsets_show,
+ geomagnetic_raw_offsets_store);
+#ifdef YAS_MAG_MANUAL_OFFSET
+static DEVICE_ATTR(manual_offsets, S_IRUGO | S_IWUSR,
+ geomagnetic_raw_manual_offsets_show,
+ geomagnetic_raw_manual_offsets_store);
+#endif
+static DEVICE_ATTR(static_matrix, S_IRUGO | S_IWUSR,
+ geomagnetic_raw_static_matrix_show,
+ geomagnetic_raw_static_matrix_store);
+static DEVICE_ATTR(dynamic_matrix, S_IRUGO | S_IWUSR,
+ geomagnetic_raw_dynamic_matrix_show,
+ geomagnetic_raw_dynamic_matrix_store);
+static DEVICE_ATTR(ellipsoid_mode, S_IRUGO | S_IWUSR,
+ geomagnetic_raw_ellipsoid_mode_show,
+ geomagnetic_raw_ellipsoid_mode_store);
+static struct attribute *geomagnetic_raw_attributes[] = {
+#ifdef SYSFS_PCBTEST
+ &dev_attr_self_test.attr,
+ &dev_attr_self_test_noise.attr,
+#endif
+ &dev_attr_threshold.attr,
+ &dev_attr_distortion.attr,
+ &dev_attr_shape.attr,
+ &dev_attr_offsets.attr,
+#ifdef YAS_MAG_MANUAL_OFFSET
+ &dev_attr_manual_offsets.attr,
+#endif
+ &dev_attr_static_matrix.attr,
+ &dev_attr_dynamic_matrix.attr,
+ &dev_attr_ellipsoid_mode.attr,
+ NULL
+};
+
+static struct attribute_group geomagnetic_raw_attribute_group = {
+ .attrs = geomagnetic_raw_attributes
+};
+static struct device_attribute dev_attr_magnetic_sensor_selftest =
+ __ATTR(selftest, S_IRUSR | S_IRGRP,
+ geomagnetic_raw_self_test_show, NULL);
+
+static struct device_attribute dev_attr_magnetic_sensor_raw_data =
+ __ATTR(raw_data, S_IRUSR | S_IRGRP,
+ geomagnetic_raw_self_test_noise_show, NULL);
+
+static ssize_t magnetic_vendor_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ return sprintf(buf, "%s\n", "YAMAHA");
+}
+static struct device_attribute dev_attr_magnetic_sensor_vendor =
+ __ATTR(vendor, S_IRUSR | S_IRGRP, magnetic_vendor_show, NULL);
+
+static ssize_t magnetic_name_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ int ret;
+ if (data->dev_id == YAS_YAS532_DEVICE_ID)
+ ret = sprintf(buf, "%s\n", "YAS532");
+ else
+ ret = sprintf(buf, "%s\n", "YAS530C");
+ return ret;
+}
+static struct device_attribute dev_attr_magnetic_sensor_name =
+ __ATTR(name, S_IRUSR | S_IRGRP, magnetic_name_show, NULL);
+
+static struct device_attribute *magnetic_sensor_attrs[] = {
+ &dev_attr_magnetic_sensor_selftest,
+ &dev_attr_magnetic_sensor_raw_data,
+ &dev_attr_magnetic_sensor_vendor,
+ &dev_attr_magnetic_sensor_name,
+ NULL,
+};
+
+
+/* Interface Functions for Lower Layer */
+#ifdef YAS_MAG_MANUAL_OFFSET
+void geomagnetic_manual_offset(void)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ struct yas_vector offset;
+ if (data->mag_pdata->chg_status == CABLE_TYPE_NONE) {
+ offset = data->mag_pdata->full_offset;
+ if (hwdep_driver.set_manual_offset(&offset) == 0)
+ data->manual_offset = offset;
+ } else if (data->mag_pdata->chg_status == CABLE_TYPE_USB) {
+ offset = data->mag_pdata->usb_offset;
+ if (hwdep_driver.set_manual_offset(&offset) == 0)
+ data->manual_offset = offset;
+ } else if (data->mag_pdata->chg_status == CABLE_TYPE_AC) {
+ offset = data->mag_pdata->ta_offset;
+ if (hwdep_driver.set_manual_offset(&offset) == 0)
+ data->manual_offset = offset;
+ } else {
+ offset = data->mag_pdata->full_offset;
+ if (hwdep_driver.set_manual_offset(&offset) == 0)
+ data->manual_offset = offset;
+ }
+ data->mag_pdata->offset_enable = 0;
+}
+#endif
+
+static int geomagnetic_work(struct yas_mag_data *magdata)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ uint32_t time_delay_ms = 100;
+ static int cnt;
+ int rt, i, accuracy;
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[5];
+ struct timeval tv;
+#endif
+
+#ifdef YAS_MAG_MANUAL_OFFSET
+ if (data->mag_pdata) {
+ if (data->mag_pdata->offset_enable)
+ geomagnetic_manual_offset();
+ }
+#endif
+
+ if (hwdep_driver.measure == NULL || hwdep_driver.get_offset == NULL)
+ return time_delay_ms;
+
+ rt = hwdep_driver.measure(magdata, &time_delay_ms);
+ if (rt < 0)
+ YLOGE(("measure failed[%d]\n", rt));
+ YLOGD(("xy1y2 [%d][%d][%d] raw[%d][%d][%d]\n",
+ magdata->xy1y2.v[0], magdata->xy1y2.v[1], magdata->xy1y2.v[2],
+ magdata->xyz.v[0], magdata->xyz.v[1], magdata->xyz.v[2]));
+
+ if (rt >= 0) {
+ accuracy = atomic_read(&data->last_status);
+
+ if ((rt & YAS_REPORT_OVERFLOW_OCCURED)
+ || (rt & YAS_REPORT_HARD_OFFSET_CHANGED)
+ || (rt & YAS_REPORT_CALIB_OFFSET_CHANGED)) {
+ static uint16_t count = 1;
+ int code = 0;
+ int value = 0;
+
+ hwdep_driver.get_offset(&data->driver_offset);
+ if (rt & YAS_REPORT_OVERFLOW_OCCURED) {
+ atomic_set(&data->last_status, 0);
+ accuracy = 0;
+ }
+
+ /* report event */
+ code |= (rt & YAS_REPORT_OVERFLOW_OCCURED);
+ code |= (rt & YAS_REPORT_HARD_OFFSET_CHANGED);
+ code |= (rt & YAS_REPORT_CALIB_OFFSET_CHANGED);
+ value = (count++ << 16) | (code);
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ make_event(ev, EV_ABS, ABS_RAW_REPORT, value);
+ sensor_event(&data->raw_devfile_list, ev, 1);
+#else
+ input_report_abs(data->input_raw, ABS_RAW_REPORT,
+ value);
+ input_sync(data->input_raw);
+#endif
+ }
+
+ if (rt & YAS_REPORT_DATA) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ get_time_stamp(&tv);
+ make_event_w_time(&ev[0], EV_ABS, ABS_X,
+ magdata->xyz.v[0], &tv);
+ make_event_w_time(&ev[1], EV_ABS, ABS_Y,
+ magdata->xyz.v[1], &tv);
+ make_event_w_time(&ev[2], EV_ABS, ABS_Z,
+ magdata->xyz.v[2], &tv);
+ make_event_w_time(&ev[3], EV_ABS, ABS_STATUS, accuracy,
+ &tv);
+ make_event_w_time(&ev[4], EV_SYN, 0, 0, &tv);
+ sensor_event(&data->devfile_list, ev, 5);
+#else
+ /* report magnetic data in [nT] */
+ input_report_abs(data->input_data, ABS_X,
+ magdata->xyz.v[0]);
+ input_report_abs(data->input_data, ABS_Y,
+ magdata->xyz.v[1]);
+ input_report_abs(data->input_data, ABS_Z,
+ magdata->xyz.v[2]);
+ if (atomic_read(&data->last_data[0]) ==
+ magdata->xyz.v[0]
+ && atomic_read(&data->last_data[1]) ==
+ magdata->xyz.v[1]
+ && atomic_read(&data->last_data[2]) ==
+ magdata->xyz.v[2]) {
+ input_report_abs(data->input_data, ABS_RUDDER,
+ cnt++);
+ }
+ input_report_abs(data->input_data, ABS_STATUS,
+ accuracy);
+ input_sync(data->input_data);
+#endif
+
+ for (i = 0; i < 3; i++)
+ atomic_set(&data->last_data[i],
+ magdata->xyz.v[i]);
+ }
+
+ if (rt & YAS_REPORT_CALIB) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ get_time_stamp(&tv);
+ make_event_w_time(&ev[0], EV_ABS, ABS_X,
+ magdata->raw.v[0], &tv);
+ make_event_w_time(&ev[1], EV_ABS, ABS_Y,
+ magdata->raw.v[1], &tv);
+ make_event_w_time(&ev[2], EV_ABS, ABS_Z,
+ magdata->raw.v[2], &tv);
+ make_event_w_time(&ev[3], EV_SYN, 0, 0, &tv);
+ sensor_event(&data->raw_devfile_list, ev, 4);
+#else
+ /* report raw magnetic data */
+ input_report_abs(data->input_raw, ABS_X,
+ magdata->raw.v[0]);
+ input_report_abs(data->input_raw, ABS_Y,
+ magdata->raw.v[1]);
+ input_report_abs(data->input_raw, ABS_Z,
+ magdata->raw.v[2]);
+ input_sync(data->input_raw);
+#endif
+ }
+ } else {
+ time_delay_ms = 100;
+ }
+
+ return time_delay_ms;
+
+}
+
+static void geomagnetic_input_work_func(struct work_struct *work)
+{
+ struct geomagnetic_data *data =
+ container_of((struct delayed_work *)work,
+ struct geomagnetic_data, work);
+ uint32_t time_delay_ms;
+ struct yas_mag_data magdata;
+
+ time_delay_ms = geomagnetic_work(&magdata);
+
+ if (time_delay_ms > 60)
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(time_delay_ms));
+ else {
+ if (time_delay_ms > 0)
+ usleep_range(time_delay_ms * 1000,
+ time_delay_ms * 1100);
+ schedule_delayed_work(&data->work, 0);
+ }
+}
+
+static int geomagnetic_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(client);
+
+ if (atomic_read(&data->enable))
+ cancel_delayed_work_sync(&data->work);
+#if DEBUG
+ data->suspend = 1;
+#endif
+
+ return 0;
+}
+
+static int geomagnetic_resume(struct i2c_client *client)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(client);
+
+ if (atomic_read(&data->enable))
+ schedule_delayed_work(&data->work, 0);
+#if DEBUG
+ data->suspend = 0;
+#endif
+
+ return 0;
+}
+
+static int
+geomagnetic_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ struct geomagnetic_data *data = NULL;
+ struct input_dev *input_data = NULL, *input_raw = NULL;
+ int rt, sysfs_created = 0, sysfs_raw_created = 0;
+ int data_registered = 0, raw_registered = 0, i;
+ struct yas_mag_filter filter;
+ struct mag_platform_data *pdata;
+
+ pr_err("%s, is called\n", __func__);
+
+ i2c_set_clientdata(client, NULL);
+ data = kzalloc(sizeof(struct geomagnetic_data), GFP_KERNEL);
+ if (data == NULL) {
+ rt = -ENOMEM;
+ goto err;
+ }
+
+ pdata = (struct mag_platform_data *) client->dev.platform_data;
+ data->mag_pdata = pdata;
+
+ if (pdata) {
+ if (pdata->power_on)
+ pdata->power_on(true);
+ }
+ data->threshold = YAS_DEFAULT_MAGCALIB_THRESHOLD;
+ for (i = 0; i < 3; i++)
+ data->distortion[i] = YAS_DEFAULT_MAGCALIB_DISTORTION;
+ data->shape = 0;
+ atomic_set(&data->enable, 0);
+ for (i = 0; i < 3; i++)
+ atomic_set(&data->last_data[i], 0);
+ atomic_set(&data->last_status, 0);
+ INIT_DELAYED_WORK(&data->work, geomagnetic_input_work_func);
+ sema_init(&data->driver_lock, 1);
+ sema_init(&data->multi_lock, 1);
+
+ input_data = input_allocate_device();
+ if (input_data == NULL) {
+ rt = -ENOMEM;
+ YLOGE(("mag Failed to allocate input_data device\n"));
+ goto err;
+ }
+
+ input_data->name = GEOMAGNETIC_INPUT_NAME;
+ input_data->id.bustype = BUS_I2C;
+ set_bit(EV_ABS, input_data->evbit);
+ input_set_abs_params(input_data, ABS_X, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_data, ABS_Y, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_data, ABS_Z, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_data, ABS_RUDDER, 0x80000000, 0x7fffffff, 0,
+ 0);
+ input_set_abs_params(input_data, ABS_STATUS, 0, 3, 0, 0);
+ input_set_abs_params(input_data, ABS_WAKE, 0x80000000, 0x7fffffff, 0,
+ 0);
+ input_data->dev.parent = &client->dev;
+
+ rt = input_register_device(input_data);
+ if (rt) {
+ YLOGE(("mag: Unable to reg input_data %s\n", input_data->name));
+ goto err;
+ }
+ data_registered = 1;
+
+ rt = sysfs_create_group(&input_data->dev.kobj,
+ &geomagnetic_attribute_group);
+ if (rt) {
+ YLOGE(("mag sysfs_create failed[%s]\n", input_data->name));
+ goto err;
+ }
+ sysfs_created = 1;
+
+ input_raw = input_allocate_device();
+ if (input_raw == NULL) {
+ rt = -ENOMEM;
+ YLOGE(("mag Failed to alloc input_raw dev\n"));
+ goto err;
+ }
+
+ input_raw->name = GEOMAGNETIC_INPUT_RAW_NAME;
+ input_raw->id.bustype = BUS_I2C;
+ set_bit(EV_ABS, input_raw->evbit);
+ input_set_abs_params(input_raw, ABS_X, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_raw, ABS_Y, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_raw, ABS_Z, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_raw, ABS_RAW_DISTORTION, 0, 0x7fffffff, 0,
+ 0);
+ input_set_abs_params(input_raw, ABS_RAW_THRESHOLD, 0, 2, 0, 0);
+ input_set_abs_params(input_raw, ABS_RAW_SHAPE, 0, 1, 0, 0);
+ input_set_abs_params(input_raw, ABS_RAW_MODE, 0, 1, 0, 0);
+ input_set_abs_params(input_raw, ABS_RAW_REPORT, 0x80000000, 0x7fffffff,
+ 0, 0);
+ input_raw->dev.parent = &client->dev;
+
+ rt = input_register_device(input_raw);
+ if (rt) {
+ YLOGE(("mag: Unable to reg input_raw dev\n"));
+ goto err;
+ }
+ raw_registered = 1;
+
+ rt = sysfs_create_group(&input_raw->dev.kobj,
+ &geomagnetic_raw_attribute_group);
+ if (rt) {
+ YLOGE(("geomagnetic_probe: sysfs_create_group failed[%s]\n",
+ input_data->name));
+ goto err;
+ }
+ sysfs_raw_created = 1;
+
+ this_client = client;
+ data->input_raw = input_raw;
+ data->input_data = input_data;
+ input_set_drvdata(input_data, data);
+ input_set_drvdata(input_raw, data);
+ i2c_set_clientdata(client, data);
+ rt = yas_mag_driver_init(&hwdep_driver);
+ if (rt < 0) {
+ YLOGE(("yas_mag_driver_init failed[%d]\n", rt));
+ goto err;
+ }
+ if (hwdep_driver.init != NULL) {
+ rt = hwdep_driver.init();
+ if (rt < 0) {
+ YLOGE(("hwdep_driver.init() failed[%d]\n", rt));
+ goto err;
+ }
+ }
+ if (hwdep_driver.set_position != NULL) {
+ if (pdata) {
+ if (pdata->orientation) {
+ pr_info("%s: set from board file.\n", __func__);
+ if (hwdep_driver.
+ set_position(pdata->orientation
+ - YAS532_POSITION_OFFSET) < 0) {
+ pr_err("set_position failed %d\n", rt);
+ goto err;
+ }
+ } else {
+ pr_info("%s: set from defconfig.\n", __func__);
+ if (hwdep_driver.
+ set_position(
+ CONFIG_INPUT_YAS_MAGNETOMETER_POSITION)
+ < 0) {
+ pr_err("set_position failed %d\n", rt);
+ goto err;
+ }
+ }
+ } else {
+ if (hwdep_driver.
+ set_position(
+ CONFIG_INPUT_YAS_MAGNETOMETER_POSITION)
+ < 0) {
+ pr_err("set_position() failed[%d]\n", rt);
+ goto err;
+ }
+ }
+ pr_info("%s: yas magnetic position is %d\n", __func__,
+ hwdep_driver.get_position());
+ }
+ if (hwdep_driver.get_offset != NULL) {
+ if (hwdep_driver.get_offset(&data->driver_offset) < 0) {
+ YLOGE(("hwdep_driver get_driver_state failed\n"));
+ goto err;
+ }
+ }
+ if (hwdep_driver.get_delay != NULL)
+ data->delay = hwdep_driver.get_delay();
+
+ if (hwdep_driver.set_filter_enable != NULL) {
+ /* default to enable */
+ if (hwdep_driver.set_filter_enable(1) == 0)
+ data->filter_enable = 1;
+ }
+ if (hwdep_driver.get_filter != NULL) {
+ if (hwdep_driver.get_filter(&filter) < 0) {
+ YLOGE(("hwdep_driver get_filter failed\n"));
+ goto err;
+ }
+ data->filter_len = filter.len;
+ for (i = 0; i < 3; i++)
+ data->filter_noise[i] = filter.noise[i];
+ data->filter_threshold = filter.threshold;
+ }
+ if (hwdep_driver.get_static_matrix != NULL)
+ hwdep_driver.get_static_matrix(&data->static_matrix);
+ if (hwdep_driver.get_dynamic_matrix != NULL)
+ hwdep_driver.get_dynamic_matrix(&data->dynamic_matrix);
+#ifdef SYSFS_PCBTEST
+ rt = yas_pcb_test_init(&pcbtest);
+ if (rt < 0) {
+ YLOGE(("yas_pcb_test_init failed[%d]\n", rt));
+ goto err;
+ }
+#endif
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ INIT_LIST_HEAD(&data->devfile_list);
+ INIT_LIST_HEAD(&data->raw_devfile_list);
+ if (misc_register(&sensor_devfile) < 0)
+ goto err;
+ if (misc_register(&sensor_raw_devfile) < 0) {
+ misc_deregister(&sensor_devfile);
+ goto err;
+ }
+#endif
+
+ rt =
+ geomagnetic_i2c_read(YAS_REGADDR_DEVICE_ID, &data->dev_id, 1);
+ if (rt) {
+ pr_err("%s: cound not read device id(%d).\n",
+ __func__, rt);
+ goto err;
+ } else
+ pr_info("%s: yamaha magnetic sensor id = %x\n",
+ __func__, data->dev_id);
+
+ rt = sensors_register(data->magnetic_sensor_device,
+ NULL, magnetic_sensor_attrs,
+ "magnetic_sensor");
+ if (rt) {
+ pr_err("%s: cound not register magnetic sensor device(%d).\n",
+ __func__, rt);
+ goto out_sensor_register_failed;
+ }
+
+ return 0;
+
+out_sensor_register_failed:
+err:
+ if (data != NULL) {
+ if (input_raw != NULL) {
+ if (sysfs_raw_created)
+ sysfs_remove_group(&input_raw->dev.kobj,
+ &geomagnetic_raw_attribute_group);
+
+ if (raw_registered)
+ input_unregister_device(input_raw);
+ else
+ input_free_device(input_raw);
+ }
+ if (input_data != NULL) {
+ if (sysfs_created)
+ sysfs_remove_group(&input_data->dev.kobj,
+ &geomagnetic_attribute_group);
+ if (data_registered)
+ input_unregister_device(input_data);
+ else
+ input_free_device(input_data);
+ }
+ if (pdata) {
+ if (pdata->power_on)
+ pdata->power_on(false);
+ }
+ kfree(data);
+ }
+
+ return rt;
+}
+
+static int geomagnetic_remove(struct i2c_client *client)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(client);
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ misc_deregister(&sensor_devfile);
+ misc_deregister(&sensor_raw_devfile);
+#endif
+ if (data != NULL) {
+ geomagnetic_disable(data);
+ if (hwdep_driver.term != NULL)
+ hwdep_driver.term();
+
+ input_unregister_device(data->input_raw);
+ sysfs_remove_group(&data->input_data->dev.kobj,
+ &geomagnetic_attribute_group);
+ sysfs_remove_group(&data->input_raw->dev.kobj,
+ &geomagnetic_raw_attribute_group);
+ input_unregister_device(data->input_data);
+ kfree(data);
+ }
+
+ return 0;
+}
+
+static void geomagnetic_shutdown(struct i2c_client *client)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(client);
+
+ if (data != NULL) {
+ geomagnetic_disable(data);
+ if (data->mag_pdata) {
+ if (data->mag_pdata->power_on)
+ data->mag_pdata->power_on(false);
+ }
+ }
+}
+
+/* I2C Device Driver */
+static struct i2c_device_id geomagnetic_idtable[] = {
+ {GEOMAGNETIC_I2C_DEVICE_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, geomagnetic_idtable);
+
+static struct i2c_driver geomagnetic_i2c_driver = {
+ .driver = {
+ .name = GEOMAGNETIC_I2C_DEVICE_NAME,
+ .owner = THIS_MODULE,
+ },
+
+ .id_table = geomagnetic_idtable,
+ .probe = geomagnetic_probe,
+ .remove = geomagnetic_remove,
+ .suspend = geomagnetic_suspend,
+ .resume = geomagnetic_resume,
+ .shutdown = geomagnetic_shutdown,
+};
+
+static int __init geomagnetic_init(void)
+{
+ return i2c_add_driver(&geomagnetic_i2c_driver);
+}
+
+static void __exit geomagnetic_term(void)
+{
+ i2c_del_driver(&geomagnetic_i2c_driver);
+}
+
+#ifdef GEOMAGNETIC_PLATFORM_API
+static int geomagnetic_api_enable(int enable)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ int rt;
+
+ if (geomagnetic_multi_lock() < 0)
+ return -1;
+ enable = !!enable;
+ rt = hwdep_driver.set_enable(enable);
+ if (rt == 0) {
+ atomic_set(&data->enable, enable);
+ if (enable)
+ rt = hwdep_driver.set_delay(20);
+ }
+
+ geomagnetic_multi_unlock();
+
+ return rt;
+}
+
+int geomagnetic_api_resume(void)
+{
+ return geomagnetic_api_enable(1);
+}
+EXPORT_SYMBOL(geomagnetic_api_resume);
+
+int geomagnetic_api_suspend(void)
+{
+ return geomagnetic_api_enable(0);
+}
+EXPORT_SYMBOL(geomagnetic_api_suspend);
+
+int geomagnetic_api_read(int *xyz, int *raw, int *xy1y2, int *accuracy)
+{
+ struct geomagnetic_data *data = i2c_get_clientdata(this_client);
+ struct yas_mag_data magdata;
+ int i;
+
+ geomagnetic_work(&magdata);
+ if (xyz != NULL) {
+ for (i = 0; i < 3; i++)
+ xyz[i] = magdata.xyz.v[i];
+ }
+ if (raw != NULL) {
+ for (i = 0; i < 3; i++)
+ raw[i] = magdata.raw.v[i];
+ }
+ if (xy1y2 != NULL) {
+ for (i = 0; i < 3; i++)
+ xy1y2[i] = magdata.xy1y2.v[i];
+ }
+ if (accuracy != NULL)
+ *accuracy = atomic_read(&data->last_status);
+
+ return 0;
+}
+EXPORT_SYMBOL(geomagnetic_api_read);
+#endif
+
+module_init(geomagnetic_init);
+module_exit(geomagnetic_term);
+
+MODULE_AUTHOR("Yamaha Corporation");
+#if YAS_MAG_DRIVER == YAS_MAG_DRIVER_YAS529
+MODULE_DESCRIPTION("YAS529 Geomagnetic Sensor Driver");
+#elif YAS_MAG_DRIVER == YAS_MAG_DRIVER_YAS530
+MODULE_DESCRIPTION("YAS530 Geomagnetic Sensor Driver");
+#elif CONFIG_SENSORS_YAS532
+MODULE_DESCRIPTION("YAS532 Geomagnetic Sensor Driver");
+#endif
+MODULE_LICENSE("GPL");
+MODULE_VERSION("4.4.702a");
diff --git a/drivers/sensor/yas_ori_kernel_driver.c b/drivers/sensor/yas_ori_kernel_driver.c
new file mode 100644
index 0000000..20003aa
--- /dev/null
+++ b/drivers/sensor/yas_ori_kernel_driver.c
@@ -0,0 +1,695 @@
+/*
+ * Copyright (c) 2010-2011 Yamaha Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#define __LINUX_KERNEL_DRIVER__
+#include <linux/sensor/yas.h>
+
+#define SENSOR_NAME "orientation"
+#define SENSOR_DEFAULT_DELAY (200) /* 200 ms */
+#define SENSOR_MAX_DELAY (2000) /* 2000 ms */
+#define ABS_STATUS (ABS_BRAKE)
+#define ABS_WAKE (ABS_MISC)
+#define ABS_CONTROL_REPORT (ABS_THROTTLE)
+
+static int suspend(void);
+static int resume(void);
+
+struct sensor_data {
+ struct mutex mutex;
+ int enabled;
+ int delay;
+#if DEBUG
+ int suspend;
+#endif
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct list_head devfile_list;
+#endif
+};
+
+static struct platform_device *sensor_pdev;
+static struct input_dev *this_data;
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+#include <linux/miscdevice.h>
+#define MAX_COUNT (64)
+
+struct sensor_device {
+ struct list_head list;
+ struct mutex lock;
+ wait_queue_head_t waitq;
+ struct input_event events[MAX_COUNT];
+ int head, num_event;
+};
+
+static void get_time_stamp(struct timeval *tv)
+{
+ struct timespec ts;
+ ktime_get_ts(&ts);
+ tv->tv_sec = ts.tv_sec;
+ tv->tv_usec = ts.tv_nsec / 1000;
+}
+
+static void make_event(struct input_event *ev, int type, int code, int value)
+{
+ struct timeval tv;
+ get_time_stamp(&tv);
+ ev->type = type;
+ ev->code = code;
+ ev->value = value;
+ ev->time = tv;
+}
+
+static void
+make_event_w_time(struct input_event *ev, int type, int code, int value,
+ struct timeval *tv)
+{
+ ev->type = type;
+ ev->code = code;
+ ev->value = value;
+ ev->time = *tv;
+}
+
+static void sensor_enq(struct sensor_device *kdev, struct input_event *ev)
+{
+ int idx;
+
+ idx = kdev->head + kdev->num_event;
+ if (MAX_COUNT <= idx)
+ idx -= MAX_COUNT;
+ kdev->events[idx] = *ev;
+ kdev->num_event++;
+ if (MAX_COUNT < kdev->num_event) {
+ kdev->num_event = MAX_COUNT;
+ kdev->head++;
+ if (MAX_COUNT <= kdev->head)
+ kdev->head -= MAX_COUNT;
+ }
+}
+
+static int sensor_deq(struct sensor_device *kdev, struct input_event *ev)
+{
+ if (kdev->num_event == 0)
+ return 0;
+
+ *ev = kdev->events[kdev->head];
+ kdev->num_event--;
+ kdev->head++;
+ if (MAX_COUNT <= kdev->head)
+ kdev->head -= MAX_COUNT;
+ return 1;
+}
+
+static void
+sensor_event(struct list_head *devlist, struct input_event *ev, int num)
+{
+ struct sensor_device *kdev;
+ int i;
+
+ list_for_each_entry(kdev, devlist, list) {
+ mutex_lock(&kdev->lock);
+ for (i = 0; i < num; i++)
+ sensor_enq(kdev, &ev[i]);
+
+ mutex_unlock(&kdev->lock);
+ wake_up_interruptible(&kdev->waitq);
+ }
+}
+
+static ssize_t
+sensor_write(struct file *f, const char __user *buf, size_t count,
+ loff_t *pos)
+{
+ struct sensor_data *data = input_get_drvdata(this_data);
+ struct sensor_device *kdev;
+ struct input_event ev[MAX_COUNT];
+ int num, i;
+
+ if (count < sizeof(struct input_event))
+ return -EINVAL;
+
+ num = count / sizeof(struct input_event);
+ if (MAX_COUNT < num)
+ num = MAX_COUNT;
+
+ if (copy_from_user(ev, buf, num * sizeof(struct input_event)))
+ return -EFAULT;
+
+ list_for_each_entry(kdev, &data->devfile_list, list) {
+ mutex_lock(&kdev->lock);
+ for (i = 0; i < num; i++)
+ sensor_enq(kdev, &ev[i]);
+ mutex_unlock(&kdev->lock);
+ wake_up_interruptible(&kdev->waitq);
+ }
+
+ return count;
+}
+
+static ssize_t
+sensor_read(struct file *f, char __user *buf, size_t count, loff_t *pos)
+{
+ struct sensor_device *kdev = f->private_data;
+ int rt, num;
+ struct input_event ev[MAX_COUNT];
+
+ if (count < sizeof(struct input_event))
+ return -EINVAL;
+
+ rt = wait_event_interruptible(kdev->waitq, kdev->num_event != 0);
+ if (rt)
+ return rt;
+
+ mutex_lock(&kdev->lock);
+ for (num = 0; num < count / sizeof(struct input_event); num++) {
+ if (!sensor_deq(kdev, &ev[num]))
+ break;
+ }
+ mutex_unlock(&kdev->lock);
+
+ if (copy_to_user(buf, ev, num * sizeof(struct input_event)))
+ return -EFAULT;
+
+ return num * sizeof(struct input_event);
+}
+
+static unsigned int sensor_poll(struct file *f, struct poll_table_struct *wait)
+{
+ struct sensor_device *kdev = f->private_data;
+
+ poll_wait(f, &kdev->waitq, wait);
+ if (kdev->num_event != 0)
+ return POLLIN | POLLRDNORM;
+
+ return 0;
+}
+
+static int sensor_open(struct inode *inode, struct file *f)
+{
+ struct sensor_data *data = input_get_drvdata(this_data);
+ struct sensor_device *kdev;
+
+ kdev = kzalloc(sizeof(struct sensor_device), GFP_KERNEL);
+ if (!kdev)
+ return -ENOMEM;
+
+ mutex_init(&kdev->lock);
+ init_waitqueue_head(&kdev->waitq);
+ f->private_data = kdev;
+ kdev->head = 0;
+ kdev->num_event = 0;
+ list_add(&kdev->list, &data->devfile_list);
+
+ return 0;
+}
+
+static int sensor_release(struct inode *inode, struct file *f)
+{
+ struct sensor_device *kdev = f->private_data;
+
+ list_del(&kdev->list);
+ kfree(kdev);
+
+ return 0;
+}
+
+const struct file_operations sensor_fops = {
+ .owner = THIS_MODULE,
+ .open = sensor_open,
+ .release = sensor_release,
+ .write = sensor_write,
+ .read = sensor_read,
+ .poll = sensor_poll,
+};
+
+static struct miscdevice sensor_devfile = {
+ .name = SENSOR_NAME,
+ .fops = &sensor_fops,
+ .minor = MISC_DYNAMIC_MINOR,
+};
+
+#endif
+
+static int suspend(void)
+{
+ /* implement suspend of the sensor */
+ YLOGD(("%s: suspend\n", SENSOR_NAME));
+
+ return 0;
+}
+
+static int resume(void)
+{
+ /* implement resume of the sensor */
+ YLOGD(("%s: resume\n", SENSOR_NAME));
+
+ return 0;
+}
+
+/* Sysfs interface */
+static ssize_t
+sensor_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct sensor_data *data = input_get_drvdata(input_data);
+ int delay;
+
+ mutex_lock(&data->mutex);
+
+ delay = data->delay;
+
+ mutex_unlock(&data->mutex);
+
+ return sprintf(buf, "%d\n", delay);
+}
+
+static ssize_t
+sensor_delay_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct sensor_data *data = input_get_drvdata(input_data);
+ long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+#endif
+
+ if (value < 0)
+ return count;
+
+ if (SENSOR_MAX_DELAY < value)
+ value = SENSOR_MAX_DELAY;
+
+ mutex_lock(&data->mutex);
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ make_event(ev, EV_ABS, ABS_CONTROL_REPORT,
+ (data->enabled << 16) | value);
+ sensor_event(&data->devfile_list, ev, 1);
+#endif
+ data->delay = value;
+#ifndef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ input_report_abs(input_data, ABS_CONTROL_REPORT,
+ (data->enabled << 16) | value);
+#endif
+
+ mutex_unlock(&data->mutex);
+
+ return count;
+}
+
+static ssize_t
+sensor_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct sensor_data *data = input_get_drvdata(input_data);
+ int enabled;
+
+ mutex_lock(&data->mutex);
+
+ enabled = data->enabled;
+
+ mutex_unlock(&data->mutex);
+
+ return sprintf(buf, "%d\n", enabled);
+}
+
+static ssize_t
+sensor_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ struct sensor_data *data = input_get_drvdata(input_data);
+ unsigned long value;
+ int error;
+
+ error = strict_strtoul(buf, 10, &value);
+ if (unlikely(error))
+ return error;
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+#endif
+
+ value = !(!value);
+
+ mutex_lock(&data->mutex);
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ make_event(ev, EV_ABS, ABS_CONTROL_REPORT, (value << 16) | data->delay);
+ sensor_event(&data->devfile_list, ev, 1);
+#else
+ input_report_abs(input_data, ABS_CONTROL_REPORT,
+ (value << 16) | data->delay);
+ input_sync(input_data);
+#endif
+
+ if (data->enabled && !value)
+ suspend();
+ if (!data->enabled && value)
+ resume();
+ data->enabled = value;
+
+ mutex_unlock(&data->mutex);
+
+ return count;
+}
+
+static ssize_t
+sensor_wake_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ static int cnt = 1;
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct sensor_data *data = input_get_drvdata(input_data);
+ struct input_event ev[2];
+ struct timeval tv;
+ get_time_stamp(&tv);
+ make_event_w_time(&ev[0], EV_ABS, ABS_WAKE, cnt++, &tv);
+ make_event_w_time(&ev[1], EV_SYN, 0, 0, &tv);
+ sensor_event(&data->devfile_list, ev, 2);
+#else
+ input_report_abs(input_data, ABS_WAKE, cnt++);
+ input_sync(input_data);
+#endif
+
+ return count;
+}
+
+#if DEBUG
+
+static int sensor_suspend(struct platform_device *pdev, pm_message_t state);
+static int sensor_resume(struct platform_device *pdev);
+
+static ssize_t
+sensor_debug_suspend_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct sensor_data *data = input_get_drvdata(input);
+
+ return sprintf(buf, "%d\n", data->suspend);
+}
+
+static ssize_t
+sensor_debug_suspend_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long suspend;
+ int error;
+
+ error = strict_strtoul(buf, 10, &suspend);
+ if (unlikely(error))
+ return error;
+
+
+ if (suspend) {
+ pm_message_t msg;
+ memset(&msg, 0, sizeof(msg));
+ sensor_suspend(sensor_pdev, msg);
+ } else
+ sensor_resume(sensor_pdev);
+
+ return count;
+}
+
+#endif /* DEBUG */
+
+static ssize_t
+sensor_data_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ int x, y, z;
+
+ x = input_abs_get_val(input_data, ABS_X);
+ y = input_abs_get_val(input_data, ABS_Y);
+ z = input_abs_get_val(input_data, ABS_Z);
+
+ return sprintf(buf, "%d %d %d\n", x, y, z);
+}
+
+static ssize_t
+sensor_status_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input_data = to_input_dev(dev);
+ int status;
+
+ status = input_abs_get_val(input_data, ABS_STATUS);
+
+ return sprintf(buf, "%d\n", status);
+}
+
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ sensor_delay_show, sensor_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ sensor_enable_show, sensor_enable_store);
+static DEVICE_ATTR(wake, S_IWUSR | S_IWGRP, NULL, sensor_wake_store);
+static DEVICE_ATTR(data, S_IRUGO, sensor_data_show, NULL);
+static DEVICE_ATTR(status, S_IRUGO, sensor_status_show, NULL);
+
+#if DEBUG
+static DEVICE_ATTR(debug_suspend, S_IRUGO | S_IWUSR,
+ sensor_debug_suspend_show, sensor_debug_suspend_store);
+#endif /* DEBUG */
+
+static struct attribute *sensor_attributes[] = {
+ &dev_attr_delay.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_wake.attr,
+ &dev_attr_data.attr,
+ &dev_attr_status.attr,
+#if DEBUG
+ &dev_attr_debug_suspend.attr,
+#endif /* DEBUG */
+ NULL
+};
+
+static struct attribute_group sensor_attribute_group = {
+ .attrs = sensor_attributes
+};
+
+static int sensor_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct sensor_data *data = input_get_drvdata(this_data);
+ int rt = 0;
+
+ mutex_lock(&data->mutex);
+
+ if (data->enabled) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+ make_event(ev, EV_ABS, ABS_CONTROL_REPORT,
+ (0 << 16) | data->delay);
+ sensor_event(&data->devfile_list, ev, 1);
+#else
+ input_report_abs(this_data, ABS_CONTROL_REPORT,
+ (0 << 16) | data->delay);
+#endif
+ rt = suspend();
+ }
+
+ mutex_unlock(&data->mutex);
+
+ return rt;
+}
+
+static int sensor_resume(struct platform_device *pdev)
+{
+ struct sensor_data *data = input_get_drvdata(this_data);
+ int rt = 0;
+
+ mutex_lock(&data->mutex);
+
+ if (data->enabled) {
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ struct input_event ev[1];
+ make_event(ev, EV_ABS, ABS_CONTROL_REPORT,
+ (1 << 16) | data->delay);
+ sensor_event(&data->devfile_list, ev, 1);
+#endif
+ rt = resume();
+#ifndef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ input_report_abs(this_data, ABS_CONTROL_REPORT,
+ (1 << 16) | data->delay);
+#endif
+ }
+
+ mutex_unlock(&data->mutex);
+
+ return rt;
+}
+
+static int sensor_probe(struct platform_device *pdev)
+{
+ struct sensor_data *data = NULL;
+ struct input_dev *input_data = NULL;
+ int input_registered = 0, sysfs_created = 0;
+ int rt;
+
+ data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
+ if (!data) {
+ rt = -ENOMEM;
+ goto err;
+ }
+ data->enabled = 0;
+ data->delay = SENSOR_DEFAULT_DELAY;
+
+ input_data = input_allocate_device();
+ if (!input_data) {
+ rt = -ENOMEM;
+ YLOGE(("sensor_probe: Failed to allocate input_data device\n"));
+ goto err;
+ }
+
+ set_bit(EV_ABS, input_data->evbit);
+ input_set_abs_params(input_data, ABS_X, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_data, ABS_Y, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_data, ABS_Z, 0x80000000, 0x7fffffff, 0, 0);
+ input_set_abs_params(input_data, ABS_RUDDER, 0x80000000, 0x7fffffff, 0,
+ 0);
+ input_set_abs_params(input_data, ABS_STATUS, 0, 3, 0, 0);
+ input_set_abs_params(input_data, ABS_WAKE, 0x80000000, 0x7fffffff, 0,
+ 0);
+ input_set_abs_params(input_data, ABS_CONTROL_REPORT, 0x80000000,
+ 0x7fffffff, 0, 0);
+ input_data->name = SENSOR_NAME;
+
+ rt = input_register_device(input_data);
+ if (rt) {
+ YLOGE(("ori Unable to reg input_data %s\n", input_data->name));
+ goto err;
+ }
+ input_set_drvdata(input_data, data);
+ input_registered = 1;
+
+ rt = sysfs_create_group(&input_data->dev.kobj, &sensor_attribute_group);
+ if (rt) {
+ YLOGE(("sensor_probe: sysfs_create_group failed[%s]\n",
+ input_data->name));
+ goto err;
+ }
+ sysfs_created = 1;
+ mutex_init(&data->mutex);
+ this_data = input_data;
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ INIT_LIST_HEAD(&data->devfile_list);
+ if (misc_register(&sensor_devfile) < 0)
+ goto err;
+#endif
+
+ return 0;
+
+err:
+ if (data != NULL) {
+ if (input_data != NULL) {
+ if (sysfs_created)
+ sysfs_remove_group(&input_data->dev.kobj,
+ &sensor_attribute_group);
+ if (input_registered)
+ input_unregister_device(input_data);
+ else
+ input_free_device(input_data);
+ input_data = NULL;
+ }
+ kfree(data);
+ }
+
+ return rt;
+}
+
+static int sensor_remove(struct platform_device *pdev)
+{
+ struct sensor_data *data;
+
+#ifdef YAS_SENSOR_KERNEL_DEVFILE_INTERFACE
+ misc_deregister(&sensor_devfile);
+#endif
+ if (this_data != NULL) {
+ data = input_get_drvdata(this_data);
+ sysfs_remove_group(&this_data->dev.kobj,
+ &sensor_attribute_group);
+ input_unregister_device(this_data);
+ if (data != NULL)
+ kfree(data);
+ }
+
+ return 0;
+}
+
+/*
+ * Module init and exit
+ */
+static struct platform_driver sensor_driver = {
+ .probe = sensor_probe,
+ .remove = sensor_remove,
+ .suspend = sensor_suspend,
+ .resume = sensor_resume,
+ .driver = {
+ .name = SENSOR_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init sensor_init(void)
+{
+ sensor_pdev = platform_device_register_simple(SENSOR_NAME, 0, NULL, 0);
+ if (IS_ERR(sensor_pdev))
+ return -1;
+ return platform_driver_register(&sensor_driver);
+}
+
+module_init(sensor_init);
+
+static void __exit sensor_exit(void)
+{
+ platform_driver_unregister(&sensor_driver);
+ platform_device_unregister(sensor_pdev);
+}
+
+module_exit(sensor_exit);
+
+MODULE_AUTHOR("Yamaha Corporation");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("4.4.702a");
diff --git a/drivers/sensor/yas_pcb_test.c b/drivers/sensor/yas_pcb_test.c
new file mode 100644
index 0000000..686c8c6
--- /dev/null
+++ b/drivers/sensor/yas_pcb_test.c
@@ -0,0 +1,1282 @@
+/*
+ * Copyright (c) 2010-2011 Yamaha Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * File yas_pcb_test.c
+ * Brief pcb test program for yas530/yas532
+ * Date 2013/1/22
+ * Revision 1.4.3
+ */
+#include "yas_pcb_test.h"
+
+/* define */
+/* reg num */
+#define YAS530_CAL_REG_NUM (16)
+#define YAS532_CAL_REG_NUM (14)
+#define YAS_PCB_MEASURE_DATA_REG_NUM (8)
+
+/* default value */
+#define YAS_PCB_TEST1_DEFAULT (0x00)
+#define YAS_PCB_TEST2_DEFAULT (0x00)
+#define YAS_PCB_INTERVAL_DEFAULT (0x00)
+#define YAS_PCB_CONFIG_DEFAULT (0x01) /* INTON = 1 */
+#define YAS_PCB_COIL_DEFAULT (0x00)
+
+/* measure command */
+#define YAS_PCB_MEASURE_COMMAND_START (0x01)
+#define YAS_PCB_MEASURE_COMMAND_LDTC (0x02)
+#define YAS_PCB_MEASURE_COMMAND_FORS (0x04)
+
+#define YAS_PCB_MEASURE_BUSY (0x80)
+
+#define YAS_PCB_MEASURE_WAIT_TIME (2) /* ms */
+#define YAS_PCB_HARD_OFFSET_CORRECT (16)
+#define YAS_PCB_COIL_INIT_CALC_NUM (5)
+
+#define YAS_PCB_HARD_OFFSET_MASK (0x3F)
+
+#define YAS_PCB_INT_CHECK (1)
+#define YAS_PCB_INT_NOTCHECK (0)
+#define YAS_PCB_INT_HIGH (1)
+#define YAS_PCB_INT_LOW (0)
+
+#define YAS_PCB_ACC_Z (9806550L) /* m/s2 */
+
+#define YAS530_DEVICE_ID (0x01) /* MS-3E */
+#define YAS532_DEVICE_ID (0x02) /* MS-3R */
+
+#define YAS530_VERSION_A (0) /* MS-3E Aver */
+#define YAS530_VERSION_B (1) /* MS-3E Bver */
+/*#define YAS530_VERSION_AB (0)*/ /* MS-3R ABver */
+#define YAS532_VERSION_AC (1) /* MS-3R ACver */
+
+#define YAS530_COEF_VERSION_A (380)
+#define YAS530_COEF_VERSION_B (550)
+/*#define YAS532_COEF_VERSION_AB (1800)*/
+/*#define YAS532_COEF_VERSION_AC (900)*/
+#define YAS532_COEFX_VERSION_AC (850)
+#define YAS532_COEFY1_VERSION_AC (750)
+#define YAS532_COEFY2_VERSION_AC (750)
+
+#define YAS530_RAWDATA_CENTER (2048)
+#define YAS530_RAWDATA_OVERFLOW (4095)
+#define YAS532_RAWDATA_CENTER (4096)
+#define YAS532_RAWDATA_OVERFLOW (8190)
+
+#define YAS_PCB_DIR_DIVIDER (400)
+
+#define YAS_PCB_TEST1 (0)
+#define YAS_PCB_TEST3 (1)
+#define YAS_PCB_TEST4 (2)
+#define YAS_PCB_TEST5 (3)
+#define YAS_PCB_TEST6 (4)
+#define YAS_PCB_TEST7 (5)
+#define YAS_PCB_TEST8 (6)
+#define YAS_PCB_TEST2 (7)
+#define YAS_PCB_TEST_NUM (8)
+
+/* typedef */
+struct yas_pcb_vector {
+ int32_t v[3];
+};
+
+struct yas_pcb_correction {
+ int32_t s32Cx, s32Cy1, s32Cy2;
+ int32_t s32A2, s32A3, s32A4, s32A5, s32A6, s32A7, s32A8, s32A9, s32K;
+ int32_t s32ZFlag;
+ int32_t s32Rx, s32Ry1, s32Ry2;
+ int32_t s32Fx, s32Fy1, s32Fy2;
+ int32_t s32Ver;
+};
+
+struct yas_pcb_sensitivity {
+ int32_t s32Sx, s32Sy, s32Sz;
+};
+
+/* values */
+static uint16_t gu16State;
+static struct yas_pcb_test_callback g_callback;
+static struct yas_pcb_vector gstXy1y2;
+static int8_t gs08HardOffset[3];
+static struct yas_pcb_correction gstCorrect;
+static uint8_t gu08DevId;
+static int32_t gs32Center;
+static int32_t gs32Overflow;
+#ifdef YAS_PCBTEST_EXTRA
+static uint8_t gu08Recalc;
+static int32_t gs32RecalcWait;
+#endif
+
+/* functions */
+static int Ms3AxesLibAtan8(int, int, short *);
+static int Ms3AxesLibDir8(int, int, unsigned short *);
+static int yas_pcb_check_state(int);
+static void yas_pcb_update_state(int);
+static int yas_pcb_power_on(void);
+static int yas_pcb_power_off(void);
+static int yas_pcb_reset_coil(void);
+static int yas530_read_cal(uint8_t *);
+static int yas532_read_cal(uint8_t *);
+static void yas530_calc_correction(const uint8_t *);
+static void yas532_calc_correction(const uint8_t *);
+static int yas_pcb_set_offset(const int8_t *);
+static int yas_pcb_measure(struct yas_pcb_vector *, int *, uint8_t, uint8_t);
+static int yas_pcb_is_flow_occued(struct yas_pcb_vector *, int32_t, int32_t);
+static void yas_pcb_calc_sensitivity(struct yas_pcb_vector *,
+ int, struct yas_pcb_sensitivity *);
+static void yas_pcb_calc_position(struct yas_pcb_vector *,
+ struct yas_pcb_vector *, int);
+static int yas_pcb_calc_magnetic_field(struct yas_pcb_vector *,
+ struct yas_pcb_vector *);
+static int yas_pcb_test1(int *);
+static int yas_pcb_test2(void);
+static int yas_pcb_test3(void);
+static int yas_pcb_test4(int *, int *, int *);
+static int yas_pcb_test5(int *);
+static int yas_pcb_test6(int *, int *);
+#ifdef YAS_PCBTEST_EXTRA
+static int yas_pcb_test7(int *, int *, int *);
+#endif
+
+static int Ms3AxesLibAtan8(int ss, int cc, short *ans)
+{
+ static const unsigned char AtanTable[] = {
+ 0, 1, 3, 5, 6, 8, 11, 13,
+ 15, 18, 21, 24, 27, 31, 34, 39,
+ 43, 48, 53, 58, 63, 69, 75, 82,
+ 89, 96, 103, 110, 118, 126, 134, 143,
+ 152
+ };
+
+ unsigned char idx;
+ unsigned short idx_mul64;
+ signed char sign = 1;
+ unsigned int ucc;
+ unsigned int uss;
+ unsigned short ans_mul8;
+ unsigned char idx_mod64;
+ unsigned short ans_diff8;
+
+ if (cc < 0) {
+ sign = -sign;
+ ucc = -cc;
+ } else {
+ ucc = cc;
+ }
+
+ if (ss < 0) {
+ sign = -sign;
+ uss = -ss;
+ } else {
+ uss = ss;
+ }
+
+ while (ucc >= 0x400) {
+ ucc >>= 1;
+ uss >>= 1;
+ }
+
+ if (ucc == 0)
+ return -1;
+
+ idx_mul64 = (uss << 11) / ucc;
+
+ idx = idx_mul64 >> 6;
+ ans_mul8 = (idx << 4) - AtanTable[idx];
+
+ idx_mod64 = (unsigned char)idx_mul64 & 0x3f;
+
+ if (idx < 32) {
+ idx++;
+ ans_diff8 = (idx << 4) - AtanTable[idx] - ans_mul8;
+ ans_mul8 += (ans_diff8 * idx_mod64) >> 6;
+ }
+
+ *ans = (sign == 1) ? ans_mul8 : (-ans_mul8);
+
+ return 0;
+}
+
+static int Ms3AxesLibDir8(int ss, int cc, unsigned short *ans)
+{
+ short temp_ans = 0;
+ int ucc = cc;
+ int uss = ss;
+ int ret = 0;
+
+ if (cc < -2147483647)
+ cc++;
+ if (ss < -2147483647)
+ ss++;
+
+ if (cc < 0)
+ ucc = -cc;
+
+ if (ss < 0)
+ uss = -ss;
+
+ if (uss <= ucc) {
+ ret = Ms3AxesLibAtan8(ss, cc, &temp_ans);
+ if (ret < 0)
+ return 1;
+
+ if (cc > 0) {
+ if (temp_ans < 0)
+ temp_ans += 2880;
+ } else
+ temp_ans += 1440;
+ } else {
+ ret = Ms3AxesLibAtan8(cc, ss, &temp_ans);
+ if (ret < 0)
+ return 1;
+
+ if (ss > 0)
+ temp_ans = 720 - temp_ans;
+ else
+ temp_ans = 2160 - temp_ans;
+ }
+
+ *ans = temp_ans;
+
+ return 0;
+}
+
+static int yas_pcb_check_state(int id)
+{
+ int result = YAS_PCB_ERROR_TEST_ORDER;
+ uint16_t u16Mask;
+ const uint16_t u16TestTable[] = {
+ 0x0000, /* 1 */
+ 0x0000, /* 3 */
+ (1 << YAS_PCB_TEST1) | (1 << YAS_PCB_TEST3), /* 4 */
+ (1 << YAS_PCB_TEST1) | (1 << YAS_PCB_TEST3)
+ | (1 << YAS_PCB_TEST4), /* 5 */
+ (1 << YAS_PCB_TEST1) | (1 << YAS_PCB_TEST3)
+ | (1 << YAS_PCB_TEST4), /* 6 */
+ (1 << YAS_PCB_TEST1) | (1 << YAS_PCB_TEST3)
+ | (1 << YAS_PCB_TEST4) /* 7 */
+ | (1 << YAS_PCB_TEST5),
+ (1 << YAS_PCB_TEST1) | (1 << YAS_PCB_TEST3)
+ | (1 << YAS_PCB_TEST4), /* 8 */
+ (1 << YAS_PCB_TEST1), /* 2 */
+ };
+
+ if ((YAS_PCB_TEST1 <= id) && (id < YAS_PCB_TEST_NUM)) {
+ u16Mask = u16TestTable[id];
+ if (u16Mask == 0) {
+ switch (id) {
+ case YAS_PCB_TEST1:
+ if ((gu16State == 0)
+ || (gu16State == (1 << YAS_PCB_TEST1)))
+ result = YAS_PCB_NO_ERROR;
+ break;
+
+ case YAS_PCB_TEST3:
+ if ((gu16State == (1 << YAS_PCB_TEST1))
+ || (gu16State ==
+ ((1 << YAS_PCB_TEST1)
+ | (1 << YAS_PCB_TEST3))))
+ result = YAS_PCB_NO_ERROR;
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ if ((gu16State & u16Mask) == u16Mask)
+ result = YAS_PCB_NO_ERROR;
+ }
+ }
+
+ return result;
+}
+
+static void yas_pcb_update_state(int id)
+{
+ if ((YAS_PCB_TEST1 <= id) && (id < YAS_PCB_TEST2))
+ gu16State |= (uint16_t)(1 << id);
+ else
+ gu16State = 0;
+}
+
+static int yas_pcb_power_on(void)
+{
+ int result = YAS_PCB_NO_ERROR;
+ int ret;
+
+ if (NULL != g_callback.power_on) {
+ ret = g_callback.power_on();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_POWER;
+ }
+
+ return result;
+}
+
+static int yas_pcb_power_off(void)
+{
+ int result = YAS_PCB_NO_ERROR;
+ int ret;
+
+ if (NULL != g_callback.power_off) {
+ ret = g_callback.power_off();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_POWER;
+ }
+
+ return result;
+}
+
+static int yas_pcb_reset_coil(void)
+{
+ int ret;
+ uint8_t u08Data;
+ u08Data = YAS_PCB_COIL_DEFAULT;
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_COIL,
+ &u08Data, 1);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ return YAS_PCB_NO_ERROR;
+}
+static int yas530_read_cal(uint8_t *pu08Buf)
+{
+ int i;
+ int ret;
+ int size = YAS530_CAL_REG_NUM;
+
+ /* Dummy read */
+ ret = g_callback.i2c_read(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_CAL,
+ pu08Buf, size);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ ret = g_callback.i2c_read(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_CAL,
+ pu08Buf, size);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ /* cal register is all 0 */
+ for (i = 0; i < size; i++) {
+ if (pu08Buf[i] != 0x00)
+ return YAS_PCB_NO_ERROR;
+ }
+
+ return YAS_PCB_ERROR_CALREG;
+}
+
+
+static int yas532_read_cal(uint8_t *pu08Buf)
+{
+ int i;
+ int ret;
+ int size = YAS532_CAL_REG_NUM;
+ int len = size - 1;
+
+ /* Dummy read */
+ ret = g_callback.i2c_read(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_CAL,
+ pu08Buf, size);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ ret = g_callback.i2c_read(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_CAL,
+ pu08Buf, size);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ /* cal register is all 0 */
+ for (i = 0; i < len; i++) {
+ if (pu08Buf[i] != 0x00)
+ return YAS_PCB_NO_ERROR;
+ }
+
+ /* MSB is not 0 */
+ if (pu08Buf[len] & 0x80)
+ return YAS_PCB_NO_ERROR;
+
+ return YAS_PCB_ERROR_CALREG;
+}
+
+static void yas530_calc_correction(const uint8_t *pu08Data)
+{
+ uint8_t u08Dx = pu08Data[0];
+ uint8_t u08Dy1 = pu08Data[1];
+ uint8_t u08Dy2 = pu08Data[2];
+ uint8_t u08D2 = (uint8_t)((pu08Data[3] >> 2) & 0x3F);
+ uint8_t u08D3 = (uint8_t)(((pu08Data[3] << 2) & 0x0C)
+ | ((pu08Data[4] >> 6) & 0x03));
+ uint8_t u08D4 = (uint8_t)(pu08Data[4] & 0x3F);
+ uint8_t u08D5 = (uint8_t)((pu08Data[5] >> 2) & 0x3f);
+ uint8_t u08D6 = (uint8_t)(((pu08Data[5] << 4) & 0x30)
+ | ((pu08Data[6] >> 4) & 0x0F));
+ uint8_t u08D7 = (uint8_t)(((pu08Data[6] << 3) & 0x78)
+ | ((pu08Data[7] >> 5) & 0x07));
+ uint8_t u08D8 = (uint8_t)(((pu08Data[7] << 1) & 0x3E)
+ | ((pu08Data[8] >> 7) & 0x01));
+ uint8_t u08D9 = (uint8_t)(((pu08Data[8] << 1) & 0xFE)
+ | ((pu08Data[9] >> 7) & 0x01));
+ uint8_t u08D0 = (uint8_t)((pu08Data[9] >> 2) & 0x1F);
+ uint8_t u08ZFlag = (uint8_t)((pu08Data[11] >> 5) & 0x01);
+ uint8_t u08Rx = (uint8_t)(((pu08Data[11] << 1) & 0x3E)
+ | ((pu08Data[12] >> 7) & 0x01));
+ uint8_t u08Fx = (uint8_t)((pu08Data[12] >> 5) & 0x03);
+ uint8_t u08Ry1 = (uint8_t)(((pu08Data[12] << 1) & 0x3E)
+ | ((pu08Data[13] >> 7) & 0x01));
+ uint8_t u08Fy1 = (uint8_t)((pu08Data[13] >> 5) & 0x03);
+ uint8_t u08Ry2 = (uint8_t)(((pu08Data[13] << 1) & 0x3E)
+ | ((pu08Data[14] >> 7) & 0x01));
+ uint8_t u08Fy2 = (uint8_t)((pu08Data[14] >> 5) & 0x03);
+ uint8_t u08Ver = pu08Data[15] & 0x07;
+
+ gstCorrect.s32Cx = (int32_t)((u08Dx * 6) - 768);
+ gstCorrect.s32Cy1 = (int32_t)((u08Dy1 * 6) - 768);
+ gstCorrect.s32Cy2 = (int32_t)((u08Dy2 * 6) - 768);
+ gstCorrect.s32A2 = (int32_t)(u08D2 - 32);
+ gstCorrect.s32A3 = (int32_t)(u08D3 - 8);
+ gstCorrect.s32A4 = (int32_t)(u08D4 - 32);
+ gstCorrect.s32A5 = (int32_t)(u08D5 + 38);
+ gstCorrect.s32A6 = (int32_t)(u08D6 - 32);
+ gstCorrect.s32A7 = (int32_t)(u08D7 - 64);
+ gstCorrect.s32A8 = (int32_t)(u08D8 - 32);
+ gstCorrect.s32A9 = (int32_t)u08D9;
+ gstCorrect.s32K = (int32_t)(u08D0) + 10;
+ gstCorrect.s32ZFlag = (int32_t)u08ZFlag;
+ gstCorrect.s32Rx = (int32_t)((int8_t)(u08Rx << 2) >> 2);
+ gstCorrect.s32Fx = (int32_t)u08Fx;
+ gstCorrect.s32Ry1 = (int32_t)((int8_t)(u08Ry1 << 2) >> 2);
+ gstCorrect.s32Fy1 = (int32_t)u08Fy1;
+ gstCorrect.s32Ry2 = (int32_t)((int8_t)(u08Ry2 << 2) >> 2);
+ gstCorrect.s32Fy2 = (int32_t)u08Fy2;
+ gstCorrect.s32Ver = (int32_t)u08Ver;
+}
+
+static void yas532_calc_correction(const uint8_t *pu08Data)
+{
+ uint8_t u08Dx = pu08Data[0];
+ uint8_t u08Dy1 = pu08Data[1];
+ uint8_t u08Dy2 = pu08Data[2];
+ uint8_t u08D2 = (uint8_t)((pu08Data[3] >> 2) & 0x3F);
+ uint8_t u08D3 = (uint8_t)(((pu08Data[3] << 2) & 0x0C)
+ | ((pu08Data[4] >> 6) & 0x03));
+ uint8_t u08D4 = (uint8_t)(pu08Data[4] & 0x3F);
+ uint8_t u08D5 = (uint8_t)((pu08Data[5] >> 2) & 0x3f);
+ uint8_t u08D6 = (uint8_t)(((pu08Data[5] << 4) & 0x30)
+ | ((pu08Data[6] >> 4) & 0x0F));
+ uint8_t u08D7 = (uint8_t)(((pu08Data[6] << 3) & 0x78)
+ | ((pu08Data[7] >> 5) & 0x07));
+ uint8_t u08D8 = (uint8_t)(((pu08Data[7] << 1) & 0x3E)
+ | ((pu08Data[8] >> 7) & 0x01));
+ uint8_t u08D9 = (uint8_t)(((pu08Data[8] << 1) & 0xFE)
+ | ((pu08Data[9] >> 7) & 0x01));
+ uint8_t u08D0 = (uint8_t)((pu08Data[9] >> 2) & 0x1F);
+ uint8_t u08Rx = (uint8_t)((pu08Data[10] >> 1) & 0x3F);
+ uint8_t u08Fx = (uint8_t)(((pu08Data[10] & 0x01) << 1)
+ | ((pu08Data[11] >> 7) & 0x01));
+ uint8_t u08Ry1 = (uint8_t)((pu08Data[11] >> 1) & 0x3F);
+ uint8_t u08Fy1 = (uint8_t)(((pu08Data[11] & 0x01) << 1)
+ | ((pu08Data[12] >> 7) & 0x01));
+ uint8_t u08Ry2 = (uint8_t)((pu08Data[12] >> 1) & 0x3F);
+ uint8_t u08Fy2 = (uint8_t)(((pu08Data[12] & 0x01) << 1)
+ | ((pu08Data[13] >> 7) & 0x01));
+ uint8_t u08Ver = pu08Data[13] & 0x01;
+
+ gstCorrect.s32Cx = (int32_t)((u08Dx * 10) - 1280);
+ gstCorrect.s32Cy1 = (int32_t)((u08Dy1 * 10) - 1280);
+ gstCorrect.s32Cy2 = (int32_t)((u08Dy2 * 10) - 1280);
+ gstCorrect.s32A2 = (int32_t)(u08D2 - 32);
+ gstCorrect.s32A3 = (int32_t)(u08D3 - 8);
+ gstCorrect.s32A4 = (int32_t)(u08D4 - 32);
+ gstCorrect.s32A5 = (int32_t)(u08D5 + 38);
+ gstCorrect.s32A6 = (int32_t)(u08D6 - 32);
+ gstCorrect.s32A7 = (int32_t)(u08D7 - 64);
+ gstCorrect.s32A8 = (int32_t)(u08D8 - 32);
+ gstCorrect.s32A9 = (int32_t)u08D9;
+ gstCorrect.s32K = (int32_t)u08D0;
+ gstCorrect.s32ZFlag = (int32_t)1;
+ gstCorrect.s32Rx = (int32_t)((int8_t)(u08Rx << 2) >> 2);
+ gstCorrect.s32Fx = (int32_t)u08Fx;
+ gstCorrect.s32Ry1 = (int32_t)((int8_t)(u08Ry1 << 2) >> 2);
+ gstCorrect.s32Fy1 = (int32_t)u08Fy1;
+ gstCorrect.s32Ry2 = (int32_t)((int8_t)(u08Ry2 << 2) >> 2);
+ gstCorrect.s32Fy2 = (int32_t)u08Fy2;
+ gstCorrect.s32Ver = (int32_t)u08Ver;
+}
+
+static int yas_pcb_set_offset(const int8_t *ps08Offset)
+{
+ int result = YAS_PCB_NO_ERROR;
+ int ret;
+ uint8_t u08Addr;
+ uint8_t u08Data;
+ uint8_t i;
+
+ for (i = 0; i < 3; i++) {
+ u08Addr = (uint8_t)(YAS_PCB_ADDR_OFFSET + i);
+ u08Data = (uint8_t)ps08Offset[i] & YAS_PCB_HARD_OFFSET_MASK;
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE,
+ u08Addr, &u08Data, 1);
+ if (0 != ret) {
+ result = YAS_PCB_ERROR_I2C;
+ break;
+ }
+ }
+
+ return result;
+}
+
+static int yas_pcb_measure(struct yas_pcb_vector *pstXy1y2, int *temperature,
+ uint8_t u08Command, uint8_t u08CheckIni)
+{
+ int ret;
+ uint8_t u08Buf[YAS_PCB_MEASURE_DATA_REG_NUM];
+ int low_or_high;
+
+ if ((YAS_PCB_INT_CHECK == u08CheckIni)
+ && (NULL != g_callback.read_intpin)) {
+ ret = g_callback.read_intpin(&low_or_high);
+ if ((0 != ret) || (YAS_PCB_INT_HIGH != low_or_high))
+ return YAS_PCB_ERROR_INTERRUPT;
+ }
+
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE,
+ YAS_PCB_ADDR_MEASURE_COMMAND,
+ &u08Command, 1);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ g_callback.msleep(YAS_PCB_MEASURE_WAIT_TIME);
+
+ if ((YAS_PCB_INT_CHECK == u08CheckIni)
+ && (NULL != g_callback.read_intpin)) {
+ ret = g_callback.read_intpin(&low_or_high);
+ if ((0 != ret) || (YAS_PCB_INT_LOW != low_or_high))
+ return YAS_PCB_ERROR_INTERRUPT;
+ }
+
+ ret = g_callback.i2c_read(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_MEASURE_DATA,
+ u08Buf, YAS_PCB_MEASURE_DATA_REG_NUM);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ /* calc measure data */
+ if (YAS532_DEVICE_ID == gu08DevId) {
+ *temperature = (((int32_t)(u08Buf[0] & 0x7F) << 3)
+ | ((u08Buf[1] >> 5) & 0x07));
+ pstXy1y2->v[0] = (int32_t)(((int32_t)(u08Buf[2] & 0x7F) << 6)
+ | ((u08Buf[3] >> 2) & 0x3F));
+ pstXy1y2->v[1] = (int32_t)(((int32_t)(u08Buf[4] & 0x7F) << 6)
+ | ((u08Buf[5] >> 2) & 0x3F));
+ pstXy1y2->v[2] = (int32_t)(((int32_t)(u08Buf[6] & 0x7F) << 6)
+ | ((u08Buf[7] >> 2) & 0x3F));
+ } else {
+ *temperature = (((int32_t)(u08Buf[0] & 0x7F) << 2)
+ | ((u08Buf[1] >> 6) & 0x03));
+ pstXy1y2->v[0] = (int32_t)(((int32_t)(u08Buf[2] & 0x7F) << 5)
+ | ((u08Buf[3] >> 3) & 0x1F));
+ pstXy1y2->v[1] = (int32_t)(((int32_t)(u08Buf[4] & 0x7F) << 5)
+ | ((u08Buf[5] >> 3) & 0x1F));
+ pstXy1y2->v[2] = (int32_t)(((int32_t)(u08Buf[6] & 0x7F) << 5)
+ | ((u08Buf[7] >> 3) & 0x1F));
+ }
+
+ if (YAS_PCB_MEASURE_BUSY == (u08Buf[0] & YAS_PCB_MEASURE_BUSY))
+ return YAS_PCB_ERROR_BUSY;
+
+ return YAS_PCB_NO_ERROR;
+}
+
+static int yas_pcb_is_flow_occued(struct yas_pcb_vector *pstXy1y2,
+ int32_t underflow, int32_t overflow)
+{
+ int result = YAS_PCB_NO_ERROR;
+ int32_t s32Tmp;
+ uint8_t i;
+
+ for (i = 0; i < 3; i++) {
+ s32Tmp = pstXy1y2->v[i];
+ if (s32Tmp <= underflow)
+ result = YAS_PCB_ERROR_UNDERFLOW;
+ else
+ if (overflow <= s32Tmp)
+ result = YAS_PCB_ERROR_OVERFLOW;
+ }
+
+ return result;
+}
+
+static void yas_pcb_calc_sensitivity(struct yas_pcb_vector *pstXy1y2,
+ int temperature, struct yas_pcb_sensitivity *pstYasSensitivity)
+{
+ /* calc XYZ data from xy1y2 data */
+ int32_t s32Sx = pstXy1y2->v[0]
+ - ((gstCorrect.s32Cx * temperature) / 100);
+ int32_t s32Sy1 = pstXy1y2->v[1]
+ - ((gstCorrect.s32Cy1 * temperature) / 100);
+ int32_t s32Sy2 = pstXy1y2->v[2]
+ - ((gstCorrect.s32Cy2 * temperature) / 100);
+ int32_t s32Sy = s32Sy1 - s32Sy2;
+ int32_t s32Sz = -s32Sy1 - s32Sy2;
+
+ pstYasSensitivity->s32Sx = s32Sx;
+ pstYasSensitivity->s32Sy = s32Sy;
+ pstYasSensitivity->s32Sz = s32Sz;
+}
+
+static void yas_pcb_calc_position(struct yas_pcb_vector *pstXy1y2,
+ struct yas_pcb_vector *pstXyz, int temperature)
+{
+ struct yas_pcb_sensitivity stSensitivity;
+ struct yas_pcb_sensitivity *pst;
+
+ yas_pcb_calc_sensitivity(pstXy1y2, temperature, &stSensitivity);
+
+ pst = &stSensitivity;
+ pstXyz->v[0] = (gstCorrect.s32K
+ * ((100 * pst->s32Sx) + (gstCorrect.s32A2 * pst->s32Sy)
+ + (gstCorrect.s32A3 * pst->s32Sz))) / 10;
+ pstXyz->v[1] = (gstCorrect.s32K * ((gstCorrect.s32A4 * pst->s32Sx)
+ + (gstCorrect.s32A5 * pst->s32Sy)
+ + (gstCorrect.s32A6 * pst->s32Sz))) / 10;
+ pstXyz->v[2] = (gstCorrect.s32K * ((gstCorrect.s32A7 * pst->s32Sx)
+ + (gstCorrect.s32A8 * pst->s32Sy)
+ + (gstCorrect.s32A9 * pst->s32Sz))) / 10;
+}
+
+static void yas530_calc_magnetic_field(struct yas_pcb_vector *pstXy1y2,
+ struct yas_pcb_vector *pstXyz, int32_t s32Coef)
+{
+ int32_t s32Oy;
+ int32_t s32Oz;
+ static const int32_t s32HTbl[] = {
+ 1748, 1948, 2148, 2348
+ };
+
+ pstXy1y2->v[0] = gstXy1y2.v[0] - s32HTbl[gstCorrect.s32Fx]
+ + (gs08HardOffset[0] - gstCorrect.s32Rx) * s32Coef;
+ pstXy1y2->v[1] = gstXy1y2.v[1] - s32HTbl[gstCorrect.s32Fy1]
+ + (gs08HardOffset[1] - gstCorrect.s32Ry1) * s32Coef;
+ pstXy1y2->v[2] = gstXy1y2.v[2] - s32HTbl[gstCorrect.s32Fy2]
+ + (gs08HardOffset[2] - gstCorrect.s32Ry2) * s32Coef;
+ s32Oy = pstXy1y2->v[1] - pstXy1y2->v[2];
+ s32Oz = -pstXy1y2->v[1] - pstXy1y2->v[2];
+
+ pstXyz->v[0] = (gstCorrect.s32K
+ * ((100 * pstXy1y2->v[0])
+ + (gstCorrect.s32A2 * s32Oy)
+ + (gstCorrect.s32A3 * s32Oz))) / 10;
+ pstXyz->v[1] = (gstCorrect.s32K
+ * ((gstCorrect.s32A4 * pstXy1y2->v[0])
+ + (gstCorrect.s32A5 * s32Oy)
+ + (gstCorrect.s32A6 * s32Oz))) / 10;
+ pstXyz->v[2] = (gstCorrect.s32K
+ * ((gstCorrect.s32A7 * pstXy1y2->v[0])
+ + (gstCorrect.s32A8 * s32Oy)
+ + (gstCorrect.s32A9 * s32Oz))) / 10;
+}
+
+static void yas532_calc_magnetic_field(struct yas_pcb_vector *pstXy1y2,
+ struct yas_pcb_vector *pstXyz,
+ int32_t s32CoefX, int32_t s32CoefY1, int32_t s32CoefY2)
+{
+ int32_t s32Oy;
+ int32_t s32Oz;
+ static const int32_t s32HTbl[] = {
+ 3721, 3971, 4221, 4471
+ };
+
+ pstXy1y2->v[0] = gstXy1y2.v[0] - s32HTbl[gstCorrect.s32Fx]
+ + (gs08HardOffset[0] - gstCorrect.s32Rx) * s32CoefX;
+ pstXy1y2->v[1] = gstXy1y2.v[1] - s32HTbl[gstCorrect.s32Fy1]
+ + (gs08HardOffset[1] - gstCorrect.s32Ry1) * s32CoefY1;
+ pstXy1y2->v[2] = gstXy1y2.v[2] - s32HTbl[gstCorrect.s32Fy2]
+ + (gs08HardOffset[2] - gstCorrect.s32Ry2) * s32CoefY2;
+ s32Oy = pstXy1y2->v[1] - pstXy1y2->v[2];
+ s32Oz = -pstXy1y2->v[1] - pstXy1y2->v[2];
+
+ pstXyz->v[0] = (gstCorrect.s32K
+ * ((100 * pstXy1y2->v[0])
+ + (gstCorrect.s32A2 * s32Oy)
+ + (gstCorrect.s32A3 * s32Oz))) / 10;
+ pstXyz->v[1] = (gstCorrect.s32K
+ * ((gstCorrect.s32A4 * pstXy1y2->v[0])
+ + (gstCorrect.s32A5 * s32Oy)
+ + (gstCorrect.s32A6 * s32Oz))) / 10;
+ pstXyz->v[2] = (gstCorrect.s32K
+ * ((gstCorrect.s32A7 * pstXy1y2->v[0])
+ + (gstCorrect.s32A8 * s32Oy)
+ + (gstCorrect.s32A9 * s32Oz))) / 10;
+}
+
+static int yas_pcb_calc_magnetic_field(struct yas_pcb_vector *pstXy1y2,
+ struct yas_pcb_vector *pstXyz)
+{
+ int32_t s32Coef;
+
+ if (YAS532_DEVICE_ID == gu08DevId) {
+ switch (gstCorrect.s32Ver) {
+ case YAS532_VERSION_AC:
+ break;
+
+ default:
+ return YAS_PCB_ERROR_I2C;
+ /* break; */
+ }
+
+ /* calculate Ohx/y/z[nT] */
+ yas532_calc_magnetic_field(pstXy1y2, pstXyz,
+ YAS532_COEFX_VERSION_AC,
+ YAS532_COEFY1_VERSION_AC,
+ YAS532_COEFY2_VERSION_AC);
+ } else {
+ switch (gstCorrect.s32Ver) {
+ case YAS530_VERSION_A:
+ s32Coef = YAS530_COEF_VERSION_A;
+ break;
+
+ case YAS530_VERSION_B:
+ s32Coef = YAS530_COEF_VERSION_B;
+ break;
+
+ default:
+ return YAS_PCB_ERROR_I2C;
+ /* break; */
+ }
+
+ /* calculate Ohx/y/z[nT] */
+ yas530_calc_magnetic_field(pstXy1y2, pstXyz, s32Coef);
+ }
+
+ return YAS_PCB_NO_ERROR;
+}
+
+static int yas_pcb_test1(int *id)
+{
+ int result;
+ int ret;
+
+ result = yas_pcb_power_on();
+ if (YAS_PCB_NO_ERROR == result) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_read(YAS_PCB_ADDR_SLAVE,
+ YAS_PCB_ADDR_ID, &gu08DevId, 1);
+ if (0 == ret) {
+ *id = (int)gu08DevId;
+ result = YAS_PCB_NO_ERROR;
+ }
+ }
+
+ return result;
+}
+
+static int yas_pcb_test2(void)
+{
+ return yas_pcb_power_off();
+}
+
+static int yas_pcb_test3(void)
+{
+ int result;
+ int ret;
+ uint8_t u08Data;
+ uint8_t pu08Buf[YAS530_CAL_REG_NUM];
+
+ u08Data = YAS_PCB_TEST1_DEFAULT;
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_TEST1,
+ &u08Data, 1);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ u08Data = YAS_PCB_TEST2_DEFAULT;
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE, YAS_PCB_ADDR_TEST2,
+ &u08Data, 1);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ u08Data = YAS_PCB_INTERVAL_DEFAULT;
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE,
+ YAS_PCB_ADDR_MEASURE_INTERVAL, &u08Data, 1);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ if (YAS532_DEVICE_ID == gu08DevId) {
+ gs32Center = YAS532_RAWDATA_CENTER;
+ gs32Overflow = YAS532_RAWDATA_OVERFLOW;
+ result = yas532_read_cal(pu08Buf);
+ if (YAS_PCB_NO_ERROR == result)
+ yas532_calc_correction(pu08Buf);
+ } else {
+ gs32Center = YAS530_RAWDATA_CENTER;
+ gs32Overflow = YAS530_RAWDATA_OVERFLOW;
+ result = yas530_read_cal(pu08Buf);
+ if (YAS_PCB_NO_ERROR == result)
+ yas530_calc_correction(pu08Buf);
+ }
+
+ if (YAS_PCB_NO_ERROR != result)
+ return result;
+
+ u08Data = (uint8_t)(YAS_PCB_CONFIG_DEFAULT
+ | (uint8_t)((pu08Buf[9] & 0x03) << 3)
+ | (uint8_t)((pu08Buf[10] & 0x80) >> 5));
+ ret = g_callback.i2c_write(YAS_PCB_ADDR_SLAVE,
+ YAS_PCB_ADDR_CONFIG, &u08Data, 1);
+ if (0 != ret)
+ return YAS_PCB_ERROR_I2C;
+
+ ret = yas_pcb_reset_coil();
+ if (YAS_PCB_NO_ERROR != ret)
+ return ret;
+ return YAS_PCB_NO_ERROR;
+}
+
+static int yas_pcb_test4(int *x, int *y1, int *y2)
+{
+ int result;
+ struct yas_pcb_vector stXy1y2;
+ int temperature;
+ int32_t s32Tmp;
+ int8_t s08Correct = YAS_PCB_HARD_OFFSET_CORRECT;
+ uint8_t i;
+ uint8_t k;
+
+ gs08HardOffset[0] = 0;
+ gs08HardOffset[1] = 0;
+ gs08HardOffset[2] = 0;
+ result = yas_pcb_set_offset(&gs08HardOffset[0]);
+ if (YAS_PCB_NO_ERROR == result) {
+ /* calc hard offset */
+ for (i = 0; i < YAS_PCB_COIL_INIT_CALC_NUM; i++) {
+ result = yas_pcb_measure(&stXy1y2, &temperature,
+ YAS_PCB_MEASURE_COMMAND_START,
+ YAS_PCB_INT_NOTCHECK);
+ if (YAS_PCB_NO_ERROR != result)
+ break;
+
+ for (k = 0; k < 3; k++) {
+ s32Tmp = stXy1y2.v[k];
+ if (gs32Center < s32Tmp)
+ gs08HardOffset[k] += s08Correct;
+ else {
+ if (s32Tmp < gs32Center)
+ gs08HardOffset[k] -= s08Correct;
+ }
+ }
+
+ result = yas_pcb_set_offset(&gs08HardOffset[0]);
+ if (YAS_PCB_NO_ERROR != result)
+ break;
+
+ s08Correct = (int8_t)((uint8_t)s08Correct >> 1);
+ }
+
+ if (YAS_PCB_NO_ERROR == result) {
+ *x = (int)gs08HardOffset[0];
+ *y1 = (int)gs08HardOffset[1];
+ *y2 = (int)gs08HardOffset[2];
+ result = yas_pcb_is_flow_occued(&stXy1y2,
+ 0, gs32Overflow);
+ }
+ }
+
+ return result;
+}
+
+static int yas_pcb_test5(int *direction)
+{
+ uint16_t dir;
+ int result;
+ int ret;
+ int x;
+ int y;
+ int nTemp;
+ struct yas_pcb_vector stXyz;
+
+ result = yas_pcb_measure(&gstXy1y2, &nTemp,
+ YAS_PCB_MEASURE_COMMAND_START, YAS_PCB_INT_NOTCHECK);
+ if (YAS_PCB_NO_ERROR == result) {
+ result = YAS_PCB_ERROR_DIRCALC;
+ yas_pcb_calc_position(&gstXy1y2, &stXyz, nTemp);
+
+ x = -stXyz.v[0] / YAS_PCB_DIR_DIVIDER;
+ y = stXyz.v[1] / YAS_PCB_DIR_DIVIDER;
+ ret = Ms3AxesLibDir8(x, y, &dir);
+ if (0 == ret) {
+ *direction = (int)(dir / 8);
+ result = yas_pcb_is_flow_occued(&gstXy1y2,
+ 0, gs32Overflow);
+ }
+ }
+
+ return result;
+}
+
+static int yas_pcb_test6(int *sx, int *sy)
+{
+ int result;
+ struct yas_pcb_vector stXy1y2P;
+ struct yas_pcb_vector stXy1y2N;
+ int temperature;
+ uint8_t u08Command;
+ struct yas_pcb_vector *pP = &stXy1y2P;
+ struct yas_pcb_vector *pN = &stXy1y2N;
+ struct yas_pcb_correction *pC = &gstCorrect;
+
+ u08Command = YAS_PCB_MEASURE_COMMAND_START
+ | YAS_PCB_MEASURE_COMMAND_LDTC;
+ result = yas_pcb_measure(pP, &temperature,
+ u08Command, YAS_PCB_INT_CHECK);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ u08Command = YAS_PCB_MEASURE_COMMAND_START
+ | YAS_PCB_MEASURE_COMMAND_LDTC
+ | YAS_PCB_MEASURE_COMMAND_FORS;
+ result = yas_pcb_measure(pN, &temperature, u08Command,
+ YAS_PCB_INT_NOTCHECK);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if (YAS532_DEVICE_ID == gu08DevId) {
+ *sx = (int)(pC->s32K * 100
+ * (pP->v[0] - pN->v[0]));
+ *sx /= 1000;
+ *sx /= YAS_VCORE;
+ *sy = (int)(pC->s32K * pC->s32A5
+ * ((pP->v[1] - pN->v[1])
+ - (pP->v[2] - pN->v[2])));
+ *sy /= 1000;
+ *sy /= YAS_VCORE;
+ } else {
+ *sx = (int)(pN->v[0] - pP->v[0]);
+ *sy = (int)((pN->v[1] - pP->v[1])
+ - (pN->v[2] - pP->v[2]));
+ }
+
+ result = yas_pcb_is_flow_occued(pP, 0, gs32Overflow);
+ if (YAS_PCB_NO_ERROR == result)
+ result = yas_pcb_is_flow_occued(pN,
+ 0, gs32Overflow);
+ }
+ }
+
+ return result;
+}
+
+#ifdef YAS_PCBTEST_EXTRA
+static int yas_pcb_test7(int *ohx, int *ohy, int *ohz)
+{
+ int nRet = YAS_PCB_ERROR_NOT_SUPPORTED;
+ struct yas_pcb_vector stOhxy1y2, stOhxyz;
+
+ if (0 != gstCorrect.s32ZFlag) {
+ nRet = yas_pcb_calc_magnetic_field(&stOhxy1y2, &stOhxyz);
+ if (YAS_PCB_NO_ERROR == nRet) {
+ /* [nT]->[uT] */
+ *ohx = stOhxyz.v[0] / 1000;
+ *ohy = stOhxyz.v[1] / 1000;
+ *ohz = stOhxyz.v[2] / 1000;
+ }
+ }
+
+ return nRet;
+}
+
+static int yas_pcb_test8(int *hx0, int *hy0, int *hz0)
+{
+ int nRet;
+ int nTemp;
+ int nX, nY1, nY2;
+ int32_t s32Underflow = 0;
+ int32_t s32Overflow = gs32Overflow;
+ struct yas_pcb_vector stOhxy1y2, stOhxyz;
+
+ if (YAS532_DEVICE_ID == gu08DevId) {
+ s32Underflow = YAS_PCB_NOISE_UNDERFLOW;
+ s32Overflow = YAS_PCB_NOISE_OVERFLOW;
+ }
+
+ if (gu08Recalc != 0) {
+ gs32RecalcWait++;
+ if (YAS_PCB_NOISE_INTERVAL <= gs32RecalcWait) {
+ nRet = yas_pcb_reset_coil();
+ if (YAS_PCB_NO_ERROR == nRet)
+ nRet = yas_pcb_test4(&nX, &nY1, &nY2);
+
+ if (YAS_PCB_NO_ERROR == nRet)
+ gu08Recalc = 0;
+
+ gs32RecalcWait = 0;
+ }
+ }
+
+ if (0 != gstCorrect.s32ZFlag) {
+ nRet = yas_pcb_measure(&gstXy1y2, &nTemp,
+ YAS_PCB_MEASURE_COMMAND_START,
+ YAS_PCB_INT_NOTCHECK);
+ if (YAS_PCB_NO_ERROR == nRet) {
+ nRet = yas_pcb_calc_magnetic_field(&stOhxy1y2,
+ &stOhxyz);
+ if (YAS_PCB_NO_ERROR == nRet) {
+ *hx0 = stOhxy1y2.v[0];
+ *hy0 = stOhxy1y2.v[1] - stOhxy1y2.v[2];
+ *hz0 = -stOhxy1y2.v[1] - stOhxy1y2.v[2];
+ nRet = yas_pcb_is_flow_occued(&gstXy1y2,
+ s32Underflow, s32Overflow);
+ if (YAS_PCB_NO_ERROR != nRet) {
+ if (gu08Recalc == 0) {
+ gu08Recalc++;
+ gs32RecalcWait = 0;
+ }
+ }
+ }
+ }
+ } else
+ nRet = YAS_PCB_ERROR_NOT_SUPPORTED;
+
+ return nRet;
+}
+
+#endif
+
+/* test 1 */
+static int power_on_and_device_check(int *id)
+{
+ int ret;
+ int result = yas_pcb_check_state(YAS_PCB_TEST1);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if (id != NULL) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_open();
+ if (0 == ret) {
+ result = yas_pcb_test1(id);
+ ret = g_callback.i2c_close();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_I2C;
+ }
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST1);
+ } else
+ result = YAS_PCB_ERROR_ARG;
+ }
+
+ return result;
+}
+
+/* test 2 */
+static int power_off(void)
+{
+ int result = yas_pcb_check_state(YAS_PCB_TEST2);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ result = yas_pcb_test2();
+
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST2);
+ }
+
+ return result;
+}
+
+/* test 3 */
+static int initialization(void)
+{
+ int ret;
+ int result = yas_pcb_check_state(YAS_PCB_TEST3);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_open();
+ if (0 == ret) {
+ result = yas_pcb_test3();
+ ret = g_callback.i2c_close();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_I2C;
+ }
+
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST3);
+ }
+
+ return result;
+}
+
+/* test 4 */
+static int offset_control_measurement_and_set_offset_register(int *x,
+ int *y1, int *y2)
+{
+ int ret;
+ int result = yas_pcb_check_state(YAS_PCB_TEST4);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if ((x != NULL) && (y1 != NULL) && (y2 != NULL)) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_open();
+ if (0 == ret) {
+ result = yas_pcb_test4(x, y1, y2);
+ ret = g_callback.i2c_close();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_I2C;
+ }
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST4);
+ } else
+ result = YAS_PCB_ERROR_ARG;
+ }
+
+ return result;
+}
+
+/* test 5 */
+static int direction_measurement(int *direction)
+{
+ int ret;
+ int result = yas_pcb_check_state(YAS_PCB_TEST5);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if (direction != NULL) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_open();
+ if (0 == ret) {
+ result = yas_pcb_test5(direction);
+ ret = g_callback.i2c_close();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_I2C;
+ }
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST5);
+ } else
+ result = YAS_PCB_ERROR_ARG;
+ }
+
+ return result;
+}
+
+/* test 6 */
+static int sensitivity_measurement_of_magnetic_sensor_by_test_coil(
+ int *sx, int *sy)
+{
+ int ret;
+ int result = yas_pcb_check_state(YAS_PCB_TEST6);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if ((sx != NULL) && (sy != NULL)) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_open();
+ if (0 == ret) {
+ result = yas_pcb_test6(sx, sy);
+ ret = g_callback.i2c_close();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_I2C;
+ }
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST6);
+ } else
+ result = YAS_PCB_ERROR_ARG;
+ }
+
+ return result;
+}
+
+/* test 7 */
+static int magnetic_field_level_check(int *ohx, int *ohy, int *ohz)
+{
+#ifdef YAS_PCBTEST_EXTRA
+ int result = yas_pcb_check_state(YAS_PCB_TEST7);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if ((ohx != NULL) && (ohy != NULL) && (ohz != NULL)) {
+ result = yas_pcb_test7(ohx, ohy, ohz);
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST7);
+ } else
+ result = YAS_PCB_ERROR_ARG;
+ }
+
+ return result;
+#else
+ return YAS_PCB_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+/* test 8 */
+static int noise_level_check(int *hx0, int *hy0, int *hz0)
+{
+#ifdef YAS_PCBTEST_EXTRA
+ int ret;
+ int result = yas_pcb_check_state(YAS_PCB_TEST8);
+
+ if (YAS_PCB_NO_ERROR == result) {
+ if ((hx0 != NULL) && (hy0 != NULL) && (hz0 != NULL)) {
+ result = YAS_PCB_ERROR_I2C;
+ ret = g_callback.i2c_open();
+ if (0 == ret) {
+ result = yas_pcb_test8(hx0, hy0, hz0);
+ ret = g_callback.i2c_close();
+ if (0 != ret)
+ result = YAS_PCB_ERROR_I2C;
+ }
+ if (YAS_PCB_NO_ERROR == result)
+ yas_pcb_update_state(YAS_PCB_TEST8);
+ } else
+ result = YAS_PCB_ERROR_ARG;
+ }
+
+ return result;
+#else
+ return YAS_PCB_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+/* pcb test module initialize */
+int yas_pcb_test_init(struct yas_pcb_test *func)
+{
+ int result = YAS_PCB_ERROR_ARG;
+
+ if ((NULL != func)
+ && (NULL != func->callback.i2c_open)
+ && (NULL != func->callback.i2c_close)
+ && (NULL != func->callback.i2c_write)
+ && (NULL != func->callback.i2c_read)
+ && (NULL != func->callback.msleep)) {
+ func->power_on_and_device_check = power_on_and_device_check;
+ func->initialization = initialization;
+ func->offset_control_measurement_and_set_offset_register
+ = offset_control_measurement_and_set_offset_register;
+ func->direction_measurement = direction_measurement;
+ func->sensitivity_measurement_of_magnetic_sensor_by_test_coil
+ = sensitivity_measurement_of_magnetic_sensor_by_test_coil;
+ func->magnetic_field_level_check = magnetic_field_level_check;
+ func->noise_level_check = noise_level_check;
+ func->power_off = power_off;
+
+ g_callback = func->callback;
+
+ if (0 != gu16State) {
+ gu16State = 0;
+ yas_pcb_power_off();
+ }
+#ifdef YAS_PCBTEST_EXTRA
+ gu08Recalc = 0;
+ gs32RecalcWait = 0;
+#endif
+ result = YAS_PCB_NO_ERROR;
+ }
+
+ return result;
+}
+/* end of file */
diff --git a/drivers/sensor/yas_pcb_test.h b/drivers/sensor/yas_pcb_test.h
new file mode 100644
index 0000000..40d9dbd
--- /dev/null
+++ b/drivers/sensor/yas_pcb_test.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2010-2011 Yamaha Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * File yas_pcb_test.h
+ * Date 2013/1/22
+ * Revision 1.4.3
+ */
+
+#ifndef __YAS_PCB_TEST_H__
+#define __YAS_PCB_TEST_H__
+
+#include "yas_types.h"
+
+/* extra */
+#define YAS_PCBTEST_EXTRA
+
+/* error code */
+#define YAS_PCB_NO_ERROR (0)
+#define YAS_PCB_ERROR_I2C (-1)
+#define YAS_PCB_ERROR_POWER (-2)
+#define YAS_PCB_ERROR_TEST_ORDER (-3)
+#define YAS_PCB_ERROR_INTERRUPT (-4)
+#define YAS_PCB_ERROR_BUSY (-5)
+#define YAS_PCB_ERROR_OVERFLOW (-6)
+#define YAS_PCB_ERROR_UNDERFLOW (-7)
+#define YAS_PCB_ERROR_DIRCALC (-8)
+#define YAS_PCB_ERROR_NOT_SUPPORTED (-9)
+#define YAS_PCB_ERROR_CALREG (-10)
+#define YAS_PCB_ERROR_ARG (-128)
+
+/* addr */
+#define YAS_PCB_ADDR_SLAVE (0x2E)
+
+#define YAS_PCB_ADDR_ID (0x80)
+#define YAS_PCB_ADDR_COIL (0x81)
+#define YAS_PCB_ADDR_MEASURE_COMMAND (0x82)
+#define YAS_PCB_ADDR_CONFIG (0x83)
+#define YAS_PCB_ADDR_MEASURE_INTERVAL (0x84)
+#define YAS_PCB_ADDR_OFFSET (0x85)
+#define YAS_PCB_ADDR_TEST1 (0x88)
+#define YAS_PCB_ADDR_TEST2 (0x89)
+#define YAS_PCB_ADDR_CAL (0x90)
+#define YAS_PCB_ADDR_MEASURE_DATA (0xB0)
+
+/* V Core */
+#define YAS_VCORE (18)
+#define YAS_PCB_NOISE_OVERFLOW (6000)
+#define YAS_PCB_NOISE_UNDERFLOW (2000)
+#define YAS_PCB_NOISE_INTERVAL (50)
+
+struct yas_pcb_test_callback {
+ int (*power_on)(void);
+ int (*power_off)(void);
+ int (*i2c_open)(void);
+ int (*i2c_close)(void);
+ int (*i2c_write)(uint8_t, uint8_t, const uint8_t *, int);
+ int (*i2c_read)(uint8_t, uint8_t, uint8_t *, int);
+ void (*msleep)(int);
+ int (*read_intpin)(int *);
+};
+
+struct yas_pcb_test {
+ int (*power_on_and_device_check)(int *);
+ int (*initialization)(void);
+ int (*offset_control_measurement_and_set_offset_register)
+ (int *, int *, int *);
+ int (*direction_measurement)(int *);
+ int (*sensitivity_measurement_of_magnetic_sensor_by_test_coil)
+ (int *, int *);
+ int (*magnetic_field_level_check)(int *, int *, int *);
+ int (*noise_level_check)(int *, int *, int *);
+ int (*power_off)(void);
+ struct yas_pcb_test_callback callback;
+};
+
+/* prototype functions */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int yas_pcb_test_init(struct yas_pcb_test *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ! __YAS_PCB_TEST_H__ */
+
+/* end of file */
diff --git a/drivers/sensor/yas_types.h b/drivers/sensor/yas_types.h
new file mode 100644
index 0000000..97aa3f3
--- /dev/null
+++ b/drivers/sensor/yas_types.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2010-2011 Yamaha Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+/*
+ * File yas_types.h
+ * Date 2012/10/05
+ * Revision 1.4.1
+ */
+
+#ifndef __YAS_TYPES_H__
+#define __YAS_TYPES_H__
+
+/* macro */
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#if defined(__KERNEL__)
+#include <linux/types.h>
+#else
+#include <stdint.h>
+/*typedef signed char int8_t;*/
+/*typedef unsigned char uint8_t;*/
+/*typedef signed short int16_t;*/
+/*typedef unsigned short uint16_t;*/
+/*typedef signed int int32_t;*/
+/*typedef unsigned int uint32_t;*/
+#endif
+
+#endif /* __YASTYPES_H__ */
+
+/* end of file */
diff --git a/drivers/sensorhub/ssp_sysfs.c b/drivers/sensorhub/ssp_sysfs.c
index 0ce5ff9..1bc7f17 100644
--- a/drivers/sensorhub/ssp_sysfs.c
+++ b/drivers/sensorhub/ssp_sysfs.c
@@ -103,7 +103,7 @@ static void change_sensor_delay(struct ssp_data *data,
break;
default:
- data->aiCheckStatus[iSensorType] = ADD_SENSOR_STATE;
+ break;
}
}
@@ -133,20 +133,7 @@ static int ssp_remove_sensor(struct ssp_data *data,
data->adDelayBuf[uChangedSensor] = DEFUALT_POLLING_DELAY;
- if (data->aiCheckStatus[uChangedSensor] == INITIALIZATION_STATE) {
- data->aiCheckStatus[uChangedSensor] = NO_SENSOR_STATE;
- if (uChangedSensor == ACCELEROMETER_SENSOR)
- accel_open_calibration(data);
- else if (uChangedSensor == GYROSCOPE_SENSOR)
- gyro_open_calibration(data);
- else if (uChangedSensor == PRESSURE_SENSOR)
- pressure_open_calibration(data);
- else if (uChangedSensor == PROXIMITY_SENSOR) {
- proximity_open_lcd_ldi(data);
- proximity_open_calibration(data);
- }
- return 0;
- } else if (uChangedSensor == ORIENTATION_SENSOR) {
+ if (uChangedSensor == ORIENTATION_SENSOR) {
if (!(atomic_read(&data->aSensorEnable)
& (1 << ACCELEROMETER_SENSOR))) {
uChangedSensor = ACCELEROMETER_SENSOR;
@@ -200,6 +187,7 @@ static ssize_t set_sensors_enable(struct device *dev,
int64_t dTemp;
unsigned int uNewEnable = 0, uChangedSensor = 0;
struct ssp_data *data = dev_get_drvdata(dev);
+ int iRet;
if (strict_strtoll(buf, 10, &dTemp) < 0)
return -1;
@@ -215,11 +203,24 @@ static ssize_t set_sensors_enable(struct device *dev,
if ((atomic_read(&data->aSensorEnable) & (1 << uChangedSensor))
!= (uNewEnable & (1 << uChangedSensor))) {
- if (uNewEnable & (1 << uChangedSensor))
- ssp_add_sensor(data, uChangedSensor);
- else
- ssp_remove_sensor(data, uChangedSensor,
- uNewEnable);
+ if (!(uNewEnable & (1 << uChangedSensor)))
+ ssp_remove_sensor(data, uChangedSensor,
+ uNewEnable); /* disable */
+ else { /* Change to ADD_SENSOR_STATE from KitKat */
+ if (data->aiCheckStatus[uChangedSensor] == INITIALIZATION_STATE) {
+ if (uChangedSensor == ACCELEROMETER_SENSOR)
+ accel_open_calibration(data);
+ else if (uChangedSensor == GYROSCOPE_SENSOR)
+ gyro_open_calibration(data);
+ else if (uChangedSensor == PRESSURE_SENSOR)
+ pressure_open_calibration(data);
+ else if (uChangedSensor == PROXIMITY_SENSOR) {
+ proximity_open_lcd_ldi(data);
+ proximity_open_calibration(data);
+ }
+ }
+ data->aiCheckStatus[uChangedSensor] = ADD_SENSOR_STATE;
+ }
break;
}
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 8cf2cee..8a37cbd 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -1543,7 +1543,7 @@ static void binder_transaction(struct binder_proc *proc,
t->from = thread;
else
t->from = NULL;
-#ifdef CONFIG_MACH_P4NOTE
+#if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA)
/* workaround code for invalid binder proc */
if (!proc->tsk) {
binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index d7164bf..4484d8d 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -1989,7 +1989,9 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
tty->ops->flush_chars(tty);
} else {
while (nr > 0) {
+ mutex_lock(&tty->output_lock);
c = tty->ops->write(tty, b, nr);
+ mutex_unlock(&tty->output_lock);
if (c < 0) {
retval = c;
goto break_out;
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index a3b31b8..5018800 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -483,10 +483,14 @@ static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
} else {
umcon &= ~S3C2410_UMCOM_AFC;
}
-
- } else if (port->line == CONFIG_GPS_S3C_UART) {
+ }
+#if !defined(CONFIG_MACH_KONA_EUR_LTE) && !defined(CONFIG_MACH_KONALTE_USA_ATT)
+ else if (port->line == CONFIG_GPS_S3C_UART) {
umcon |= S3C2410_UMCOM_AFC;
- } else {
+ }
+#endif
+ else {
+
umcon &= ~S3C2410_UMCOM_AFC;
}
diff --git a/drivers/usb/host/shost/shost_readyq.c b/drivers/usb/host/shost/shost_readyq.c
index 9e41da5..b2ccea0 100644
--- a/drivers/usb/host/shost/shost_readyq.c
+++ b/drivers/usb/host/shost/shost_readyq.c
@@ -202,6 +202,7 @@ static int get_ed_from_ready_q(struct ed **get_ed, bool is_periodic)
} else {
otg_list_pop(qlist);
periodic_trans_ready_q.entity_num--;
+ get_ed[0]->ed_status.is_in_transfer_ready_q = false;
}
return USB_ERR_SUCCESS;
@@ -230,6 +231,7 @@ static int get_ed_from_ready_q(struct ed **get_ed, bool is_periodic)
} else {
otg_list_pop(qlist);
nonperiodic_trans_ready_q.entity_num--;
+ get_ed[0]->ed_status.is_in_transfer_ready_q = false;
}
return USB_ERR_SUCCESS;
} else
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index ff3c7b2..1261866 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -182,4 +182,3 @@ obj-$(CONFIG_FB_VIRTUAL) += vfb.o
#video output switch sysfs driver
obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
-
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 29c581f..d82a55b 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -424,6 +424,13 @@ config BACKLIGHT_SMART_DIMMING
help
Say Y to enable the Smart Dimming Feature.
+config BACKLIGHT_LP855X
+ tristate "Backlight driver for TI LP855X"
+ depends on BACKLIGHT_CLASS_DEVICE && I2C
+ help
+ This supports TI LP8550, LP8551, LP8552, LP8553 and LP8556
+ backlight driver.
+
endif # BACKLIGHT_CLASS_DEVICE
endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 9d8d82f..658e9a1 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -30,6 +30,7 @@ obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
+obj-$(CONFIG_BACKLIGHT_LP855X) += lp855x_bl.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
obj-$(CONFIG_BACKLIGHT_PROGEAR) += progear_bl.o
obj-$(CONFIG_BACKLIGHT_CARILLO_RANCH) += cr_bllcd.o
diff --git a/drivers/video/backlight/lp855x_bl.c b/drivers/video/backlight/lp855x_bl.c
new file mode 100644
index 0000000..bbedab5
--- /dev/null
+++ b/drivers/video/backlight/lp855x_bl.c
@@ -0,0 +1,466 @@
+/*
+ * TI LP855x Backlight Driver
+ *
+ * Copyright (C) 2011 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/platform_data/lp855x.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+/* Registers */
+#define BRIGHTNESS_CTRL 0x00
+#define DEVICE_CTRL 0x01
+#define EEPROM_START 0xA0
+#define EEPROM_END 0xA7
+#define EPROM_START 0xA0
+#define EPROM_END 0xAF
+
+#if defined(CONFIG_MACH_KONA)
+#define EEPROM_CFG3 0xA3
+#define EEPROM_CFG5 0xA5
+#endif
+
+#define BUF_SIZE 20
+#define DEFAULT_BL_NAME "lcd-backlight"
+#define MAX_BRIGHTNESS 255
+
+struct lp855x {
+ const char *chipname;
+ enum lp855x_chip_id chip_id;
+ struct i2c_client *client;
+ struct backlight_device *bl;
+ struct device *dev;
+ struct mutex xfer_lock;
+ struct lp855x_platform_data *pdata;
+ int enabled;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+};
+
+static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
+{
+ int ret;
+
+ mutex_lock(&lp->xfer_lock);
+ ret = i2c_smbus_read_byte_data(lp->client, reg);
+ if (ret < 0) {
+ mutex_unlock(&lp->xfer_lock);
+ dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+ return ret;
+ }
+ mutex_unlock(&lp->xfer_lock);
+
+ *data = (u8)ret;
+ return 0;
+}
+
+static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
+{
+ int ret;
+
+ mutex_lock(&lp->xfer_lock);
+ ret = i2c_smbus_write_byte_data(lp->client, reg, data);
+ mutex_unlock(&lp->xfer_lock);
+
+ return ret;
+}
+
+static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
+{
+ u8 start, end;
+
+ switch (lp->chip_id) {
+ case LP8550:
+ case LP8551:
+ case LP8552:
+ case LP8553:
+ start = EEPROM_START;
+ end = EEPROM_END;
+ break;
+ case LP8556:
+ start = EPROM_START;
+ end = EPROM_END;
+ break;
+ default:
+ return false;
+ }
+
+ return (addr >= start && addr <= end);
+}
+
+static int lp855x_init_registers(struct lp855x *lp)
+{
+ u8 val, addr, mask;
+ int i, ret;
+ struct lp855x_platform_data *pd = lp->pdata;
+
+ val = pd->initial_brightness;
+ ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+ if (ret)
+ return ret;
+
+ val = pd->device_control;
+ ret = lp855x_write_byte(lp, DEVICE_CTRL, val);
+ if (ret)
+ return ret;
+
+ if (pd->load_new_rom_data && pd->size_program) {
+ for (i = 0; i < pd->size_program; i++) {
+ addr = pd->rom_data[i].addr;
+ val = pd->rom_data[i].val;
+ mask = pd->rom_data[i].mask;
+ if (!lp855x_is_valid_rom_area(lp, addr))
+ continue;
+
+ if (mask) {
+ u8 reg_val;
+
+ ret = lp855x_read_byte(lp, addr, &reg_val);
+ if (ret)
+ return ret;
+ val = (val & ~mask) | (reg_val & mask);
+ }
+
+ ret = lp855x_write_byte(lp, addr, val);
+ if (ret)
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int lp855x_bl_update_status(struct backlight_device *bl)
+{
+ struct lp855x *lp = bl_get_data(bl);
+ enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+ int ret;
+
+ if (bl->props.state & BL_CORE_SUSPENDED)
+ bl->props.brightness = 0;
+
+ if (mode == PWM_BASED) {
+ struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+ int br = bl->props.brightness;
+ int max_br = bl->props.max_brightness;
+
+ if (pd->pwm_set_intensity)
+ pd->pwm_set_intensity(br, max_br);
+
+ } else if (mode == REGISTER_BASED) {
+ u8 val = bl->props.brightness;
+ ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int lp855x_bl_get_brightness(struct backlight_device *bl)
+{
+ struct lp855x *lp = bl_get_data(bl);
+ enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+
+ if (mode == PWM_BASED) {
+ struct lp855x_pwm_data *pd = &lp->pdata->pwm_data;
+ int max_br = bl->props.max_brightness;
+
+ if (pd->pwm_get_intensity)
+ bl->props.brightness = pd->pwm_get_intensity(max_br);
+
+ } else if (mode == REGISTER_BASED) {
+ u8 val = 0;
+
+ lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
+ bl->props.brightness = val;
+ }
+
+ return bl->props.brightness;
+}
+
+static const struct backlight_ops lp855x_bl_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = lp855x_bl_update_status,
+ .get_brightness = lp855x_bl_get_brightness,
+};
+
+static int lp855x_backlight_register(struct lp855x *lp)
+{
+ struct backlight_device *bl;
+ struct backlight_properties props;
+ struct lp855x_platform_data *pdata = lp->pdata;
+ char *name = pdata->name ? : DEFAULT_BL_NAME;
+
+ props.type = BACKLIGHT_PLATFORM;
+ props.max_brightness = MAX_BRIGHTNESS;
+
+ if (pdata->initial_brightness > props.max_brightness)
+ pdata->initial_brightness = props.max_brightness;
+
+ props.brightness = pdata->initial_brightness;
+
+ bl = backlight_device_register(name, lp->dev, lp,
+ &lp855x_bl_ops, &props);
+ if (IS_ERR(bl))
+ return PTR_ERR(bl);
+
+ lp->bl = bl;
+
+ return 0;
+}
+
+static void lp855x_backlight_unregister(struct lp855x *lp)
+{
+ if (lp->bl)
+ backlight_device_unregister(lp->bl);
+}
+
+static ssize_t lp855x_get_chip_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp855x *lp = dev_get_drvdata(dev);
+ return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname);
+}
+
+static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lp855x *lp = dev_get_drvdata(dev);
+ enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
+ char *strmode = NULL;
+
+ if (mode == PWM_BASED)
+ strmode = "pwm based";
+ else if (mode == REGISTER_BASED)
+ strmode = "register based";
+
+ return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
+}
+
+static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
+static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
+
+static struct attribute *lp855x_attributes[] = {
+ &dev_attr_chip_id.attr,
+ &dev_attr_bl_ctl_mode.attr,
+ NULL,
+};
+
+static const struct attribute_group lp855x_attr_group = {
+ .attrs = lp855x_attributes,
+};
+
+static int lp855x_set_power(struct lp855x *lp, int on)
+{
+ unsigned long on_udelay = lp->pdata->power_on_udelay;
+
+ pr_info("%s : %d\n", __func__, on);
+
+ if (on) {
+ int ret = 0;
+
+ gpio_set_value(lp->pdata->gpio_en, GPIO_LEVEL_HIGH);
+ usleep_range(on_udelay, on_udelay);
+
+ ret = lp855x_init_registers(lp);
+ if (ret)
+ return ret;
+ } else {
+ gpio_set_value(lp->pdata->gpio_en, GPIO_LEVEL_LOW);
+ }
+
+ lp->enabled = on;
+
+ return 0;
+}
+
+#if defined(CONFIG_MACH_KONA)
+static int lp855x_config(struct lp855x *lp)
+{
+ u8 val;
+ int ret;
+
+ /* DEVICE CONTROL: No FAST bit to prevent LP8556 register reset */
+ ret = lp855x_write_byte(lp, DEVICE_CTRL, 0x81);
+ if (ret)
+ return ret;
+
+ /* CFG3: SCURVE_EN is linear transitions, SLOPE = 200ms,
+ * FILTER = heavy smoothing,
+ * PWM_INPUT_HYSTERESIS = 1-bit hysteresis with 12-bit resolution
+ */
+ ret = lp855x_write_byte(lp, EEPROM_CFG3, 0x5E);
+ if (ret)
+ return ret;
+
+ /* CFG5: No PWM_DIRECT, PS_MODE from platform data, PWM_FREQ = 9616Hz */
+ val = 0x2 << 4 | 0x04;
+ ret = lp855x_write_byte(lp, EEPROM_CFG5, val);
+
+ if (ret)
+ return ret;
+
+ return 0;
+
+}
+#endif
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void lp855x_early_suspend(struct early_suspend *h)
+{
+ struct lp855x *lp =
+ container_of(h, struct lp855x, early_suspend);
+
+ lp855x_set_power(lp, 0);
+}
+
+static void lp855x_late_resume(struct early_suspend *h)
+{
+ struct lp855x *lp =
+ container_of(h, struct lp855x, early_suspend);
+
+ lp855x_set_power(lp, 1);
+ backlight_update_status(lp->bl);
+#if defined(CONFIG_MACH_KONA)
+ lp855x_config(lp);
+#endif
+
+}
+#endif
+
+static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+ struct lp855x *lp;
+ struct lp855x_platform_data *pdata = cl->dev.platform_data;
+ enum lp855x_brightness_ctrl_mode mode;
+ int ret;
+
+ if (!pdata) {
+ dev_err(&cl->dev, "no platform data supplied\n");
+ return -EINVAL;
+ }
+
+ if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
+ return -EIO;
+
+ lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
+ if (!lp)
+ return -ENOMEM;
+
+ mode = pdata->mode;
+ lp->client = cl;
+ lp->dev = &cl->dev;
+ lp->pdata = pdata;
+ lp->chipname = id->name;
+ lp->chip_id = id->driver_data;
+ i2c_set_clientdata(cl, lp);
+
+ mutex_init(&lp->xfer_lock);
+
+ ret = lp855x_init_registers(lp);
+ if (ret) {
+ dev_err(lp->dev, "i2c communication err: %d", ret);
+ if (mode == REGISTER_BASED)
+ goto err_dev;
+ }
+
+ lp->enabled = 1;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ if (lp->pdata->use_gpio_en) {
+ lp->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;
+ lp->early_suspend.suspend = lp855x_early_suspend;
+ lp->early_suspend.resume = lp855x_late_resume;
+ register_early_suspend(&lp->early_suspend);
+ }
+#endif
+
+ ret = lp855x_backlight_register(lp);
+ if (ret) {
+ dev_err(lp->dev,
+ "failed to register backlight. err: %d\n", ret);
+ goto err_dev;
+ }
+
+ ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
+ if (ret) {
+ dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
+ goto err_sysfs;
+ }
+
+ backlight_update_status(lp->bl);
+
+#if defined(CONFIG_MACH_KONA)
+ lp855x_config(lp);
+#endif
+
+ return 0;
+
+err_sysfs:
+ lp855x_backlight_unregister(lp);
+err_dev:
+ return ret;
+}
+
+static int __devexit lp855x_remove(struct i2c_client *cl)
+{
+ struct lp855x *lp = i2c_get_clientdata(cl);
+
+ lp->bl->props.brightness = 0;
+ backlight_update_status(lp->bl);
+ sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
+ lp855x_backlight_unregister(lp);
+
+ return 0;
+}
+
+static const struct i2c_device_id lp855x_ids[] = {
+ {"lp8550", LP8550},
+ {"lp8551", LP8551},
+ {"lp8552", LP8552},
+ {"lp8553", LP8553},
+ {"lp8556", LP8556},
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lp855x_ids);
+
+static struct i2c_driver lp855x_driver = {
+ .driver = {
+ .name = "lp855x",
+ },
+ .probe = lp855x_probe,
+ .remove = __devexit_p(lp855x_remove),
+ .id_table = lp855x_ids,
+};
+
+static int __init lp855x_init(void)
+{
+ return i2c_add_driver(&lp855x_driver);
+}
+
+static void __exit lp855x_exit(void)
+{
+ i2c_del_driver(&lp855x_driver);
+}
+
+module_init(lp855x_init);
+module_exit(lp855x_exit);
+
+MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
+MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index b585a38..1ca9b20 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -34,6 +34,7 @@
#include <linux/fb.h>
#include <asm/fb.h>
+#include <linux/cma.h>
/*
@@ -1380,6 +1381,17 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
/* frame buffer memory */
start = info->fix.smem_start;
len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ if (!cma_is_registered_region(start, len)) {
+ pr_err("%s: %x@%x is allowed to map\n",
+ __func__, (unsigned int)start,
+ (unsigned int)len);
+ mutex_unlock(&info->mm_lock);
+ return -EINVAL;
+ }
+#endif
+
if (off >= len) {
/* memory mapped io */
off -= len;
diff --git a/drivers/video/samsung/Kconfig b/drivers/video/samsung/Kconfig
index 0234465..80f6a0a 100644
--- a/drivers/video/samsung/Kconfig
+++ b/drivers/video/samsung/Kconfig
@@ -273,6 +273,12 @@ config FB_S5P_S6E63M0
---help---
This enables support for Samsung S6E63M0 MIPI LCD
+config FB_S5P_NT71391
+ bool "NT71391 MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ ---help---
+ This enables support for Novatek NT71391 MIPI LCD
+
endchoice
choice
diff --git a/drivers/video/samsung/Makefile b/drivers/video/samsung/Makefile
index 75995be..8934e35 100644
--- a/drivers/video/samsung/Makefile
+++ b/drivers/video/samsung/Makefile
@@ -15,11 +15,16 @@ obj-$(CONFIG_FB_S5P_WA101S) += s3cfb_wa101s.o
obj-$(CONFIG_FB_S5P_AMS369FG06) += s3cfb_ams369fg06.o
obj-$(CONFIG_FB_S5P_LD9040) += ld9040.o smart_dimming_ld9042.o
obj-$(CONFIG_FB_S5P_NT35560) += nt35560.o
+ifeq ($(CONFIG_MACH_KONA),y)
+obj-$(CONFIG_FB_S5P_MDNIE) += s3cfb_mdnie_kona.o s3cfb_ielcd_kona.o mdnie_kona.o mdnie_tuning_kona.o
+else
obj-$(CONFIG_FB_S5P_MDNIE) += s3cfb_mdnie.o s3cfb_ielcd.o mdnie.o mdnie_tunning.o
+endif
obj-$(CONFIG_FB_S5P_LMS501KF03) += s3cfb_lms501kf03.o
obj-$(CONFIG_FB_S5P_LMS501XX) += s3cfb_lms501xx.o
obj-$(CONFIG_FB_S5P_DUMMY_MIPI_LCD) += s3cfb_dummymipilcd.o
obj-$(CONFIG_FB_S5P_S6E8AA0) += s3cfb_s6e8aa0.o smart_dimming.o
+obj-$(CONFIG_FB_S5P_NT71391) += s3cfb_nt71391.o
obj-$(CONFIG_FB_S5P_EA8061) += s3cfb_ea8061.o smart_dimming_ea8061.o
obj-$(CONFIG_FB_S5P_S6EVR02) += s3cfb_s6evr02.o smart_dimming_s6evr02.o s3cfb_ea8061.o smart_dimming_ea8061.o
obj-$(CONFIG_FB_S5P_S6E8AB0) += s3cfb_s6e8ab0.o smart_dimming_s6e8ab0.o
diff --git a/drivers/video/samsung/mdnie_color_tone_4412.h b/drivers/video/samsung/mdnie_color_tone_4412.h
new file mode 100644
index 0000000..7a34444
--- /dev/null
+++ b/drivers/video/samsung/mdnie_color_tone_4412.h
@@ -0,0 +1,239 @@
+#ifndef __MDNIE_COLOR_TONE_H__
+#define __MDNIE_COLOR_TONE_H__
+
+#include "mdnie_kona.h"
+
+static const unsigned short tune_scr_setting[9][3] = {
+ {0xff, 0xf9, 0xf9},
+ {0xff, 0xf9, 0xfe},
+ {0xfc, 0xfa, 0xff},
+ {0xff, 0xfc, 0xf8},
+ {0xff, 0xff, 0xff},
+ {0xfb, 0xfb, 0xff},
+ {0xfb, 0xff, 0xf5},
+ {0xfa, 0xff, 0xf9},
+ {0xf8, 0xff, 0xfc},
+};
+
+static unsigned short tune_color_tone_1[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0xaf00, /*SCR RrCr*/
+ 0x00e2, 0x00b7, /*SCR RgCg*/
+ 0x00e3, 0x00bc, /*SCR RbCb*/
+ 0x00e4, 0x00af, /*SCR GrMr*/
+ 0x00e5, 0xb700, /*SCR GgMg*/
+ 0x00e6, 0x00bc, /*SCR GbMb*/
+ 0x00e7, 0x00af, /*SCR BrYr*/
+ 0x00e8, 0x00b7, /*SCR BgYg*/
+ 0x00e9, 0xbc00, /*SCR BbYb*/
+ 0x00ea, 0x00af, /*SCR KrWr*/
+ 0x00eb, 0x00b7, /*SCR KgWg*/
+ 0x00ec, 0x00bc, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+
+};
+
+static unsigned short tune_color_tone_2[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0xa000, /*SCR RrCr*/
+ 0x00e2, 0x00a8, /*SCR RgCg*/
+ 0x00e3, 0x00b2, /*SCR RbCb*/
+ 0x00e4, 0x00a0, /*SCR GrMr*/
+ 0x00e5, 0xa800, /*SCR GgMg*/
+ 0x00e6, 0x00b2, /*SCR GbMb*/
+ 0x00e7, 0x00a0, /*SCR BrYr*/
+ 0x00e8, 0x00a8, /*SCR BgYg*/
+ 0x00e9, 0xb200, /*SCR BbYb*/
+ 0x00ea, 0x00a0, /*SCR KrWr*/
+ 0x00eb, 0x00a8, /*SCR KgWg*/
+ 0x00ec, 0x00b2, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_color_tone_3[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0x9100, /*SCR RrCr*/
+ 0x00e2, 0x0099, /*SCR RgCg*/
+ 0x00e3, 0x00a3, /*SCR RbCb*/
+ 0x00e4, 0x0091, /*SCR GrMr*/
+ 0x00e5, 0x9900, /*SCR GgMg*/
+ 0x00e6, 0x00a3, /*SCR GbMb*/
+ 0x00e7, 0x0091, /*SCR BrYr*/
+ 0x00e8, 0x0099, /*SCR BgYg*/
+ 0x00e9, 0xa300, /*SCR BbYb*/
+ 0x00ea, 0x0091, /*SCR KrWr*/
+ 0x00eb, 0x0099, /*SCR KgWg*/
+ 0x00ec, 0x00a3, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+static unsigned short tune_negative[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0xff00, /*SCR KrWr*/
+ 0x00eb, 0xff00, /*SCR KgWg*/
+ 0x00ec, 0xff00, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_negative_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0220, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0xff00, /*SCR KrWrv*/
+ 0x00eb, 0xff00, /*SCR KgWg*/
+ 0x00ec, 0xff00, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0075, 0x0000, /*CABC dgain*/
+ 0x0076, 0x0000,
+ 0x0077, 0x0000,
+ 0x0078, 0x0000,
+ 0x007f, 0x0002, /*dynamic lcd*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_color_blind[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0xff00, /*SCR KrWr*/
+ 0x00eb, 0xff00, /*SCR KgWg*/
+ 0x00ec, 0xff00, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_color_blind_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0220, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0xff00, /*SCR KrWrv*/
+ 0x00eb, 0xff00, /*SCR KgWg*/
+ 0x00ec, 0xff00, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0075, 0x0000, /*CABC dgain*/
+ 0x0076, 0x0000,
+ 0x0077, 0x0000,
+ 0x0078, 0x0000,
+ 0x007f, 0x0002, /*dynamic lcd*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+#else
+static unsigned short tune_negative[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*SCR*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0xff00, /*SCR KrWr*/
+ 0x00eb, 0xff00, /*SCR KgWg*/
+ 0x00ec, 0xff00, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_color_blind[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0020, /*SCR*/
+ 0x00e1, 0x00ff, /*SCR RrCr*/
+ 0x00e2, 0xff00, /*SCR RgCg*/
+ 0x00e3, 0xff00, /*SCR RbCb*/
+ 0x00e4, 0xff00, /*SCR GrMr*/
+ 0x00e5, 0x00ff, /*SCR GgMg*/
+ 0x00e6, 0xff00, /*SCR GbMb*/
+ 0x00e7, 0xff00, /*SCR BrYr*/
+ 0x00e8, 0xff00, /*SCR BgYg*/
+ 0x00e9, 0x00ff, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00ff, /*SCR KgWg*/
+ 0x00ec, 0x00ff, /*SCR KbWb*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+#endif
+
+struct mdnie_tuning_info negative_table[CABC_MAX] = {
+ {"negative", tune_negative},
+#if defined(CONFIG_FB_MDNIE_PWM)
+ {"negative_cabc", tune_negative_cabc},
+#endif
+};
+
+struct mdnie_tuning_info accessibility_table[CABC_MAX][ACCESSIBILITY_MAX] = {
+ {
+ {NULL, NULL},
+ {"negative", tune_negative},
+ {"color_blind", tune_color_blind},
+ },
+#if defined(CONFIG_FB_MDNIE_PWM)
+ {
+ {NULL, NULL},
+ {"negative_cabc", tune_negative_cabc},
+ {"color_blind_cabc", tune_color_blind_cabc},
+ }
+#endif
+};
+
+struct mdnie_tuning_info color_tone_table[COLOR_TONE_MAX - COLOR_TONE_1] = {
+ {"color_tone_1", tune_color_tone_1},
+ {"color_tone_2", tune_color_tone_2},
+ {"color_tone_3", tune_color_tone_3},
+};
+
+#endif /* __MDNIE_COLOR_TONE_H__ */
diff --git a/drivers/video/samsung/mdnie_kona.c b/drivers/video/samsung/mdnie_kona.c
new file mode 100644
index 0000000..d44aa0e
--- /dev/null
+++ b/drivers/video/samsung/mdnie_kona.c
@@ -0,0 +1,1171 @@
+/* linux/drivers/video/samsung/mdnie.c
+ *
+ * Register interface file for Samsung mDNIe driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/backlight.h>
+#include <linux/platform_device.h>
+#include <linux/mdnie.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/delay.h>
+#include <linux/lcd.h>
+
+#include "s3cfb.h"
+#include "s3cfb_mdnie_kona.h"
+
+#if defined(CONFIG_FB_S5P_NT71391)
+#include "mdnie_table_kona.h"
+#endif
+#include "mdnie_color_tone_4412.h"
+
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+#include "mdnie_table_ebook.h"
+#endif
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+#define MIN_BRIGHTNESS 0
+#define DEFAULT_BRIGHTNESS 150
+#if defined(CONFIG_FB_S5P_S6F1202A)
+#define CABC_CUTOFF_BACKLIGHT_VALUE 40 /* 2.5% */
+#elif defined(CONFIG_FB_S5P_S6C1372)
+#define CABC_CUTOFF_BACKLIGHT_VALUE 34
+#elif defined(CONFIG_FB_S5P_NT71391)
+#define CABC_CUTOFF_BACKLIGHT_VALUE 31
+#endif
+#define MAX_BRIGHTNESS_LEVEL 255
+#define MID_BRIGHTNESS_LEVEL 150
+#define LOW_BRIGHTNESS_LEVEL 30
+#define DIM_BRIGHTNESS_LEVEL 20
+#endif
+
+#define MDNIE_SYSFS_PREFIX "/sdcard/mdnie/"
+#define PANEL_COLOR_OFFSET_PATH "/sys/class/lcd/panel/color_offset"
+
+#if defined(CONFIG_TDMB) || defined(CONFIG_TARGET_LOCALE_NTT)
+#define SCENARIO_IS_DMB(scenario) ((scenario >= DMB_NORMAL_MODE) && (scenario < DMB_MODE_MAX))
+#else
+#define SCENARIO_IS_DMB(scenario) NULL
+#endif
+
+#define SCENARIO_IS_COLOR(scenario) ((scenario >= COLOR_TONE_1) && (scenario < COLOR_TONE_MAX))
+#define SCENARIO_IS_VIDEO(scenario) ((scenario >= VIDEO_MODE) && (scenario <= VIDEO_COLD_MODE))
+#define SCENARIO_IS_VALID(scenario) (SCENARIO_IS_COLOR(scenario) || SCENARIO_IS_DMB(scenario) || scenario < SCENARIO_MAX)
+
+#define ACCESSIBILITY_IS_VALID(accessibility) (accessibility && (accessibility < ACCESSIBILITY_MAX))
+
+#define ADDRESS_IS_SCR_BLACK(address) (address >= MDNIE_REG_BLACK_R && address <= MDNIE_REG_BLACK_B)
+#define ADDRESS_IS_SCR_RGB(address) (address >= MDNIE_REG_RED_R && address <= MDNIE_REG_GREEN_B)
+
+#define SCR_BLACK_MASK(value) (value % MDNIE_REG_BLACK_R)
+#define SCR_RGB_MASK(value) (value % MDNIE_REG_RED_R)
+
+struct class *mdnie_class;
+struct mdnie_info *g_mdnie;
+
+static int mdnie_send_sequence(struct mdnie_info *mdnie, const unsigned short *seq)
+{
+ int ret = 0, i = 0;
+ const unsigned short *wbuf = NULL;
+
+ if (IS_ERR_OR_NULL(seq)) {
+ dev_err(mdnie->dev, "mdnie sequence is null\n");
+ return -EPERM;
+ }
+
+ mutex_lock(&mdnie->dev_lock);
+
+ wbuf = seq;
+
+ mdnie_mask();
+
+ while (wbuf[i] != END_SEQ) {
+ ret += mdnie_write(wbuf[i], wbuf[i+1]);
+ i += 2;
+ }
+
+ mdnie_unmask();
+
+ mutex_unlock(&mdnie->dev_lock);
+
+ return ret;
+}
+
+static struct mdnie_tuning_info *mdnie_request_table(struct mdnie_info *mdnie)
+{
+ struct mdnie_tuning_info *table = NULL;
+
+ mutex_lock(&mdnie->lock);
+
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+ if (mdnie->ebook == EBOOK_ON) {
+ table = &ebook_table[mdnie->cabc];
+ goto exit;
+ }
+#endif
+
+ /* it will be removed next year */
+ if (mdnie->negative == NEGATIVE_ON) {
+ table = &negative_table[mdnie->cabc];
+ goto exit;
+ }
+
+ if (ACCESSIBILITY_IS_VALID(mdnie->accessibility)) {
+ table = &accessibility_table[mdnie->cabc][mdnie->accessibility];
+ goto exit;
+ } else if (SCENARIO_IS_DMB(mdnie->scenario)) {
+#if defined(CONFIG_TDMB) || defined(CONFIG_TARGET_LOCALE_NTT)
+ table = &tune_dmb[mdnie->mode];
+#endif
+ goto exit;
+ } else if (SCENARIO_IS_COLOR(mdnie->scenario)) {
+ table = &color_tone_table[mdnie->scenario % COLOR_TONE_1];
+ goto exit;
+ } else if (mdnie->scenario == CAMERA_MODE) {
+ table = &camera_table[mdnie->outdoor];
+ goto exit;
+ } else if (mdnie->scenario < SCENARIO_MAX) {
+ table = &tuning_table[mdnie->cabc][mdnie->mode][mdnie->scenario];
+ goto exit;
+ }
+
+exit:
+ mutex_unlock(&mdnie->lock);
+
+ return table;
+}
+
+static struct mdnie_tuning_info *mdnie_request_etc_table(struct mdnie_info *mdnie)
+{
+ struct mdnie_tuning_info *table = NULL;
+
+ mutex_lock(&mdnie->lock);
+
+ if (SCENARIO_IS_VIDEO(mdnie->scenario))
+ mdnie->tone = mdnie->scenario - VIDEO_MODE;
+ else if (SCENARIO_IS_DMB(mdnie->scenario))
+ mdnie->tone = mdnie->scenario % DMB_NORMAL_MODE;
+
+ table = &etc_table[mdnie->cabc][mdnie->outdoor][mdnie->tone];
+
+ mutex_unlock(&mdnie->lock);
+
+ return table;
+}
+
+static void mdnie_update_sequence(struct mdnie_info *mdnie, struct mdnie_tuning_info *table)
+{
+ unsigned short *wbuf = NULL;
+ int ret;
+
+ if (unlikely(mdnie->tuning)) {
+ ret = mdnie_request_firmware(mdnie->path, &wbuf, table->name);
+ if (ret < 0 && IS_ERR_OR_NULL(wbuf))
+ goto exit;
+ mdnie_send_sequence(mdnie, wbuf);
+ kfree(wbuf);
+ } else
+ mdnie_send_sequence(mdnie, table->sequence);
+
+exit:
+ return;
+}
+
+static void mdnie_update(struct mdnie_info *mdnie)
+{
+ struct mdnie_tuning_info *table = NULL;
+
+ if (!mdnie->enable) {
+ dev_err(mdnie->dev, "mdnie state is off\n");
+ return;
+ }
+
+ table = mdnie_request_table(mdnie);
+ if (!IS_ERR_OR_NULL(table) && !IS_ERR_OR_NULL(table->sequence)) {
+ mdnie_update_sequence(mdnie, table);
+ dev_info(mdnie->dev, "%s\n", table->name);
+ }
+
+ if (!(SCENARIO_IS_VIDEO(mdnie->scenario) || SCENARIO_IS_DMB(mdnie->scenario)))
+ goto exit;
+
+ table = mdnie_request_etc_table(mdnie);
+ if (!IS_ERR_OR_NULL(table) && !IS_ERR_OR_NULL(table->sequence)) {
+ mdnie_update_sequence(mdnie, table);
+ dev_info(mdnie->dev, "%s\n", table->name);
+ }
+
+exit:
+ return;
+}
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+static int get_backlight_level_from_brightness(struct mdnie_info *mdnie, unsigned int brightness)
+{
+ unsigned int value;
+ struct mdnie_backlight_value *pwm = mdnie->backlight;
+
+ /* brightness tuning*/
+ if (brightness >= MID_BRIGHTNESS_LEVEL) {
+ value = (brightness - MID_BRIGHTNESS_LEVEL) *
+ (pwm->max - pwm->mid) / (MAX_BRIGHTNESS_LEVEL-MID_BRIGHTNESS_LEVEL) + pwm->mid;
+ } else if (brightness >= LOW_BRIGHTNESS_LEVEL) {
+ value = (brightness - LOW_BRIGHTNESS_LEVEL) *
+ (pwm->mid - pwm->low) / (MID_BRIGHTNESS_LEVEL-LOW_BRIGHTNESS_LEVEL) + pwm->low;
+ } else if (brightness >= DIM_BRIGHTNESS_LEVEL) {
+ value = (brightness - DIM_BRIGHTNESS_LEVEL) *
+ (pwm->low - pwm->dim) / (LOW_BRIGHTNESS_LEVEL-DIM_BRIGHTNESS_LEVEL) + pwm->dim;
+ } else if (brightness > 0)
+ value = pwm->dim;
+ else
+ return 0;
+
+ if (value > 1600)
+ value = 1600;
+
+ if (value < 16)
+ value = 1;
+ else
+ value = value >> 4;
+
+ return value;
+}
+
+static void mdnie_pwm_control(struct mdnie_info *mdnie, int value)
+{
+ mutex_lock(&mdnie->dev_lock);
+ mdnie_write(MDNIE_REG_BANK_SEL, MDNIE_PWM_BANK);
+ mdnie_write(MDNIE_REG_PWM_CONTROL, 0xC000 | value);
+ mdnie_write(MDNIE_REG_MASK, 0);
+ mutex_unlock(&mdnie->dev_lock);
+}
+
+static void mdnie_pwm_control_cabc(struct mdnie_info *mdnie, int value)
+{
+ int reg;
+ const unsigned char *p_plut;
+ u16 min_duty;
+ unsigned idx;
+
+ mutex_lock(&mdnie->dev_lock);
+
+ idx = SCENARIO_IS_VIDEO(mdnie->scenario) ? LUT_VIDEO : LUT_DEFAULT;
+ p_plut = power_lut[mdnie->power_lut_idx][idx];
+ min_duty = p_plut[7] * value / 100;
+
+ mdnie_write(MDNIE_REG_BANK_SEL, MDNIE_PWM_BANK);
+
+ if (min_duty < 4)
+ reg = 0xC000 | (max(1, (value * p_plut[3] / 100)));
+ else {
+ /*PowerLUT*/
+ mdnie_write(MDNIE_REG_POWER_LUT0, (p_plut[0] * value / 100) << 8 | (p_plut[1] * value / 100));
+ mdnie_write(MDNIE_REG_POWER_LUT2, (p_plut[2] * value / 100) << 8 | (p_plut[3] * value / 100));
+ mdnie_write(MDNIE_REG_POWER_LUT4, (p_plut[4] * value / 100) << 8 | (p_plut[5] * value / 100));
+ mdnie_write(MDNIE_REG_POWER_LUT6, (p_plut[6] * value / 100) << 8 | (p_plut[7] * value / 100));
+ mdnie_write(MDNIE_REG_POWER_LUT8, (p_plut[8] * value / 100) << 8);
+
+ reg = 0x5000 | (value << 4);
+ }
+
+ mdnie_write(MDNIE_REG_PWM_CONTROL, reg);
+ mdnie_write(MDNIE_REG_MASK, 0);
+
+ mutex_unlock(&mdnie->dev_lock);
+}
+
+void set_mdnie_pwm_value(struct mdnie_info *mdnie, int value)
+{
+ mdnie_pwm_control(mdnie, value);
+}
+
+static int update_brightness(struct mdnie_info *mdnie)
+{
+ unsigned int value;
+ unsigned int brightness = mdnie->bd->props.brightness;
+
+ value = get_backlight_level_from_brightness(mdnie, brightness);
+
+ if (!mdnie->enable) {
+ dev_err(mdnie->dev, "mdnie states is off\n");
+ return 0;
+ }
+
+ if (brightness <= CABC_CUTOFF_BACKLIGHT_VALUE) {
+ mdnie_pwm_control(mdnie, value);
+ } else {
+ if ((mdnie->cabc) && (mdnie->scenario != CAMERA_MODE) && !(mdnie->tuning))
+ mdnie_pwm_control_cabc(mdnie, value);
+ else
+ mdnie_pwm_control(mdnie, value);
+ }
+ return 0;
+}
+
+static int mdnie_set_brightness(struct backlight_device *bd)
+{
+ struct mdnie_info *mdnie = bl_get_data(bd);
+ int ret = 0;
+ unsigned int brightness = bd->props.brightness;
+
+ if (brightness < MIN_BRIGHTNESS ||
+ brightness > bd->props.max_brightness) {
+ dev_err(&bd->dev, "lcd brightness should be %d to %d. now %d\n",
+ MIN_BRIGHTNESS, bd->props.max_brightness, brightness);
+ brightness = bd->props.max_brightness;
+ }
+
+ if ((mdnie->enable) && (mdnie->bd_enable)) {
+ ret = update_brightness(mdnie);
+ dev_info(&bd->dev, "brightness=%d\n", bd->props.brightness);
+ if (ret < 0)
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mdnie_get_brightness(struct backlight_device *bd)
+{
+ return bd->props.brightness;
+}
+
+static const struct backlight_ops mdnie_backlight_ops = {
+ .get_brightness = mdnie_get_brightness,
+ .update_status = mdnie_set_brightness,
+};
+#endif
+
+static void update_color_position(struct mdnie_info *mdnie, u16 idx)
+{
+ u8 cabc, mode, scenario, outdoor, i;
+ unsigned short *wbuf;
+
+ dev_info(mdnie->dev, "%s: idx=%d\n", __func__, idx);
+
+ mutex_lock(&mdnie->lock);
+
+ for (cabc = 0; cabc < CABC_MAX; cabc++) {
+ for (mode = 0; mode <= STANDARD; mode++) {
+ for (scenario = 0; scenario < SCENARIO_MAX; scenario++) {
+ wbuf = tuning_table[cabc][mode][scenario].sequence;
+ if (IS_ERR_OR_NULL(wbuf))
+ continue;
+ i = 0;
+ while (wbuf[i] != END_SEQ) {
+ if (ADDRESS_IS_SCR_BLACK(wbuf[i]))
+ wbuf[i+1] = tune_scr_setting[idx][SCR_BLACK_MASK(wbuf[i])];
+ i += 2;
+ }
+ }
+ }
+ }
+
+ for (outdoor = 0; outdoor < OUTDOOR_MAX; outdoor++) {
+ wbuf = camera_table[outdoor].sequence;
+ if (IS_ERR_OR_NULL(wbuf))
+ continue;
+ i = 0;
+ while (wbuf[i] != END_SEQ) {
+ if (ADDRESS_IS_SCR_BLACK(wbuf[i]))
+ wbuf[i+1] = tune_scr_setting[idx][SCR_BLACK_MASK(wbuf[i])];
+ i += 2;
+ }
+ }
+
+ mutex_unlock(&mdnie->lock);
+}
+
+static int get_panel_color_position(struct mdnie_info *mdnie, int *result)
+{
+ int ret = 0;
+ char *fp = NULL;
+ unsigned int offset[2] = {0,};
+
+ if (likely(mdnie->color_correction))
+ goto skip_color_correction;
+
+ ret = mdnie_open_file(PANEL_COLOR_OFFSET_PATH, &fp);
+ if (IS_ERR_OR_NULL(fp) || ret <= 0) {
+ dev_info(mdnie->dev, "%s: open fail: %s, %d\n", __func__, PANEL_COLOR_OFFSET_PATH, ret);
+ ret = -EINVAL;
+ goto skip_color_correction;
+ }
+
+ ret = sscanf(fp, "0x%x, 0x%x", &offset[0], &offset[1]);
+ if (!(offset[0] + offset[1]) || ret != 2) {
+ dev_info(mdnie->dev, "%s: 0x%x, 0x%x\n", __func__, offset[0], offset[1]);
+ ret = -EINVAL;
+ goto skip_color_correction;
+ }
+
+ ret = mdnie_calibration(offset[0], offset[1], result);
+ dev_info(mdnie->dev, "%s: %x, %x, idx=%d\n", __func__, offset[0], offset[1], ret - 1);
+
+skip_color_correction:
+ mdnie->color_correction = 1;
+ if (!IS_ERR_OR_NULL(fp))
+ kfree(fp);
+
+ return ret;
+}
+
+static ssize_t mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", mdnie->mode);
+}
+
+static ssize_t mode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value = 0;
+ int result[5] = {0,};
+ int ret;
+
+ ret = kstrtoul(buf, 0, (unsigned long *)&value);
+ if (ret)
+ return -EINVAL;
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (value >= MODE_MAX) {
+ value = STANDARD;
+ return -EINVAL;
+ }
+
+ mutex_lock(&mdnie->lock);
+ mdnie->mode = value;
+ mutex_unlock(&mdnie->lock);
+
+ if (!mdnie->color_correction) {
+ ret = get_panel_color_position(mdnie, result);
+ if (ret > 0)
+ update_color_position(mdnie, ret - 1);
+ }
+
+ mdnie_update(mdnie);
+#if defined(CONFIG_FB_MDNIE_PWM)
+ if ((mdnie->enable) && (mdnie->bd_enable))
+ update_brightness(mdnie);
+#endif
+
+ return count;
+}
+
+
+static ssize_t scenario_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", mdnie->scenario);
+}
+
+static ssize_t scenario_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value;
+ int ret;
+
+ ret = kstrtoul(buf, 0, (unsigned long *)&value);
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (!SCENARIO_IS_VALID(value))
+ value = UI_MODE;
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+ if (value >= SCENARIO_MAX)
+ value = UI_MODE;
+#endif
+
+ mutex_lock(&mdnie->lock);
+ mdnie->scenario = value;
+ mutex_unlock(&mdnie->lock);
+
+ mdnie_update(mdnie);
+#if defined(CONFIG_FB_MDNIE_PWM)
+ if ((mdnie->enable) && (mdnie->bd_enable))
+ update_brightness(mdnie);
+#endif
+
+ return count;
+}
+
+
+static ssize_t outdoor_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", mdnie->outdoor);
+}
+
+static ssize_t outdoor_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value;
+ int ret;
+
+ ret = kstrtoul(buf, 0, (unsigned long *)&value);
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (value >= OUTDOOR_MAX)
+ value = OUTDOOR_OFF;
+
+ value = (value) ? OUTDOOR_ON : OUTDOOR_OFF;
+
+ mutex_lock(&mdnie->lock);
+ mdnie->outdoor = value;
+ mutex_unlock(&mdnie->lock);
+
+ mdnie_update(mdnie);
+
+ return count;
+}
+
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+static ssize_t cabc_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", mdnie->cabc);
+}
+
+static ssize_t cabc_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value;
+ int ret;
+
+#if defined(CONFIG_FB_S5P_S6C1372)
+ if (mdnie->auto_brightness)
+ return -EINVAL;
+#endif
+
+ ret = strict_strtoul(buf, 0, (unsigned long *)&value);
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (value >= CABC_MAX)
+ value = CABC_OFF;
+
+ value = (value) ? CABC_ON : CABC_OFF;
+
+ mutex_lock(&mdnie->lock);
+ mdnie->cabc = value;
+ mutex_unlock(&mdnie->lock);
+
+ mdnie_update(mdnie);
+ if ((mdnie->enable) && (mdnie->bd_enable))
+ update_brightness(mdnie);
+
+ return count;
+}
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ char *pos = buf;
+ int i;
+
+ pos += sprintf(pos, "%d, %d, ", mdnie->auto_brightness, mdnie->power_lut_idx);
+ for (i = 0; i < 5; i++)
+ pos += sprintf(pos, "0x%02x, ", power_lut[mdnie->power_lut_idx][0][i]);
+ pos += sprintf(pos, "\n");
+
+ return pos - buf;
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ int value;
+ int rc;
+
+ rc = strict_strtoul(buf, (unsigned int)0, (unsigned long *)&value);
+ if (rc < 0)
+ return rc;
+ else {
+ if (mdnie->auto_brightness != value) {
+ dev_info(dev, "%s - %d -> %d\n", __func__, mdnie->auto_brightness, value);
+ mutex_lock(&mdnie->dev_lock);
+ mdnie->auto_brightness = value;
+#if defined(CONFIG_FB_S5P_S6C1372)
+ mutex_lock(&mdnie->lock);
+ mdnie->cabc = (value) ? CABC_ON : CABC_OFF;
+ mutex_unlock(&mdnie->lock);
+#endif
+ if (mdnie->auto_brightness >= 5)
+ mdnie->power_lut_idx = LUT_LEVEL_OUTDOOR_2;
+ else if (mdnie->auto_brightness == 4)
+ mdnie->power_lut_idx = LUT_LEVEL_OUTDOOR_1;
+ else
+ mdnie->power_lut_idx = LUT_LEVEL_MANUAL_AND_INDOOR;
+ mutex_unlock(&mdnie->dev_lock);
+ mdnie_update(mdnie);
+ if (mdnie->bd_enable)
+ update_brightness(mdnie);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+#endif
+
+static ssize_t tuning_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ char *pos = buf;
+ struct mdnie_tuning_info *table;
+ int ret, i;
+ unsigned short *wbuf;
+
+ pos += sprintf(pos, "++ %s: %s\n", __func__, mdnie->path);
+
+ if (!mdnie->tuning) {
+ pos += sprintf(pos, "tunning mode is off\n");
+ goto exit;
+ }
+
+ if (strncmp(mdnie->path, MDNIE_SYSFS_PREFIX, sizeof(MDNIE_SYSFS_PREFIX) - 1)) {
+ pos += sprintf(pos, "file path is invalid, %s\n", mdnie->path);
+ goto exit;
+ }
+
+ table = mdnie_request_table(mdnie);
+ if (!IS_ERR_OR_NULL(table)) {
+ ret = mdnie_request_firmware(mdnie->path, &wbuf, table->name);
+ i = 0;
+ while (wbuf[i] != END_SEQ) {
+ pos += sprintf(pos, "0x%04x, 0x%04x\n", wbuf[i], wbuf[i+1]);
+ i += 2;
+ }
+ if (!IS_ERR_OR_NULL(wbuf))
+ kfree(wbuf);
+ pos += sprintf(pos, "%s\n", table->name);
+ }
+
+ if (!(SCENARIO_IS_VIDEO(mdnie->scenario) || SCENARIO_IS_DMB(mdnie->scenario)))
+ goto exit;
+
+ table = mdnie_request_etc_table(mdnie);
+ if (!IS_ERR_OR_NULL(table)) {
+ ret = mdnie_request_firmware(mdnie->path, &wbuf, table->name);
+ i = 0;
+ while (wbuf[i] != END_SEQ) {
+ pos += sprintf(pos, "0x%04x, 0x%04x\n", wbuf[i], wbuf[i+1]);
+ i += 2;
+ }
+ if (!IS_ERR_OR_NULL(wbuf))
+ kfree(wbuf);
+ pos += sprintf(pos, "%s\n", table->name);
+ }
+
+exit:
+ pos += sprintf(pos, "-- %s\n", __func__);
+
+ return pos - buf;
+}
+
+static ssize_t tuning_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ int ret;
+
+ if (sysfs_streq(buf, "0") || sysfs_streq(buf, "1")) {
+ ret = kstrtoul(buf, 0, (unsigned long *)&mdnie->tuning);
+ if (!mdnie->tuning)
+ memset(mdnie->path, 0, sizeof(mdnie->path));
+ dev_info(dev, "%s :: %s\n", __func__, mdnie->tuning ? "enable" : "disable");
+ } else {
+ if (!mdnie->tuning)
+ return count;
+
+ if (count > (sizeof(mdnie->path) - sizeof(MDNIE_SYSFS_PREFIX))) {
+ dev_err(dev, "file name %s is too long\n", mdnie->path);
+ return -ENOMEM;
+ }
+
+ memset(mdnie->path, 0, sizeof(mdnie->path));
+ snprintf(mdnie->path, sizeof(MDNIE_SYSFS_PREFIX) + count-1, "%s%s", MDNIE_SYSFS_PREFIX, buf);
+ dev_info(dev, "%s :: %s\n", __func__, mdnie->path);
+
+ mdnie_update(mdnie);
+ }
+
+ return count;
+}
+
+static ssize_t negative_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", mdnie->negative);
+}
+
+static ssize_t negative_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value;
+ int ret;
+
+ ret = kstrtoul(buf, 0, (unsigned long *)&value);
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (ret < 0)
+ return ret;
+ else {
+ if (mdnie->negative == value)
+ return count;
+
+ if (value >= NEGATIVE_MAX)
+ value = NEGATIVE_OFF;
+
+ value = (value) ? NEGATIVE_ON : NEGATIVE_OFF;
+
+ mutex_lock(&mdnie->lock);
+ mdnie->negative = value;
+ mutex_unlock(&mdnie->lock);
+
+ mdnie_update(mdnie);
+ }
+ return count;
+}
+
+static ssize_t accessibility_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ char *pos = buf;
+ unsigned short *wbuf;
+ int i = 0;
+
+ pos += sprintf(pos, "%d, ", mdnie->accessibility);
+ if (mdnie->accessibility == COLOR_BLIND) {
+ if (!IS_ERR_OR_NULL(accessibility_table[mdnie->cabc][COLOR_BLIND].sequence)) {
+ wbuf = accessibility_table[mdnie->cabc][COLOR_BLIND].sequence;
+ while (wbuf[i] != END_SEQ) {
+ if (ADDRESS_IS_SCR_RGB(wbuf[i]))
+ pos += sprintf(pos, "0x%04x, ", wbuf[i+1]);
+ i += 2;
+ }
+ }
+ }
+ pos += sprintf(pos, "\n");
+
+ return pos - buf;
+}
+
+static ssize_t accessibility_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value, s[9], cabc, i, len = 0;
+ int ret;
+ unsigned short *wbuf;
+ char str[100] = {0,};
+
+ ret = sscanf(buf, "%d %x %x %x %x %x %x %x %x %x",
+ &value, &s[0], &s[1], &s[2], &s[3],
+ &s[4], &s[5], &s[6], &s[7], &s[8]);
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (ret < 0)
+ return ret;
+ else {
+ if (value >= ACCESSIBILITY_MAX)
+ value = ACCESSIBILITY_OFF;
+
+ mutex_lock(&mdnie->lock);
+ mdnie->accessibility = value;
+ if (value == COLOR_BLIND) {
+ if (ret != 10) {
+ mutex_unlock(&mdnie->lock);
+ return -EINVAL;
+ }
+
+ for (cabc = 0; cabc < CABC_MAX; cabc++) {
+ wbuf = accessibility_table[cabc][COLOR_BLIND].sequence;
+ if (IS_ERR_OR_NULL(wbuf))
+ continue;
+ i = 0;
+ while (wbuf[i] != END_SEQ) {
+ if (ADDRESS_IS_SCR_RGB(wbuf[i]))
+ wbuf[i+1] = s[SCR_RGB_MASK(wbuf[i])];
+ i += 2;
+ }
+ }
+
+ i = 0;
+ len = sprintf(str + len, "%s :: ", __func__);
+ while (len < sizeof(str) && i < ARRAY_SIZE(s)) {
+ len += sprintf(str + len, "0x%04x, ", s[i]);
+ i++;
+ }
+ dev_info(dev, "%s\n", str);
+ }
+ mutex_unlock(&mdnie->lock);
+
+ mdnie_update(mdnie);
+ }
+ return count;
+}
+
+static ssize_t color_correct_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ char *pos = buf;
+ int i;
+ int result[5] = {0,};
+
+ if (!mdnie->color_correction)
+ return -EINVAL;
+
+ for (i = 1; i < ARRAY_SIZE(result); i++)
+ pos += sprintf(pos, "F%d= %d, ", i, result[i]);
+ pos += sprintf(pos, "idx=%d\n", get_panel_color_position(mdnie, result));
+
+ return pos - buf;
+}
+
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+static ssize_t ebook_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%d\n", mdnie->ebook);
+}
+
+static ssize_t ebook_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(dev);
+ unsigned int value;
+ int ret;
+
+ ret = strict_strtoul(buf, 0, (unsigned long *)&value);
+
+ dev_info(dev, "%s :: value=%d\n", __func__, value);
+
+ if (ret < 0)
+ return ret;
+ else {
+ if (mdnie->ebook == value)
+ return count;
+
+ if (value >= EBOOK_MAX)
+ value = EBOOK_OFF;
+
+ value = (value) ? EBOOK_ON : EBOOK_OFF;
+
+ mutex_lock(&mdnie->lock);
+ mdnie->ebook = value;
+ mutex_unlock(&mdnie->lock);
+
+ mdnie_update(mdnie);
+ }
+ return count;
+}
+#endif
+
+static struct device_attribute mdnie_attributes[] = {
+ __ATTR(mode, 0664, mode_show, mode_store),
+ __ATTR(scenario, 0664, scenario_show, scenario_store),
+ __ATTR(outdoor, 0664, outdoor_show, outdoor_store),
+#if defined(CONFIG_FB_MDNIE_PWM)
+ __ATTR(cabc, 0664, cabc_show, cabc_store),
+#endif
+ __ATTR(tuning, 0664, tuning_show, tuning_store),
+ __ATTR(negative, 0664, negative_show, negative_store),
+ __ATTR(accessibility, 0664, accessibility_show, accessibility_store),
+ __ATTR(color_correct, 0444, color_correct_show, NULL),
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+ __ATTR(ebook, 0664, ebook_show, ebook_store),
+#endif
+ __ATTR_NULL,
+};
+
+#ifdef CONFIG_PM
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+#if defined(CONFIG_FB_MDNIE_PWM)
+static void mdnie_early_suspend(struct early_suspend *h)
+{
+ struct mdnie_info *mdnie = container_of(h, struct mdnie_info, early_suspend);
+ struct lcd_platform_data *pd = mdnie->lcd_pd;
+
+ dev_info(mdnie->dev, "+%s\n", __func__);
+
+ mdnie->bd_enable = FALSE;
+
+ if (mdnie->enable)
+ mdnie_pwm_control(mdnie, 0);
+
+ if (pd && pd->power_on)
+ pd->power_on(NULL, 0);
+
+ dev_info(mdnie->dev, "-%s\n", __func__);
+
+ return;
+}
+#endif
+
+static void mdnie_late_resume(struct early_suspend *h)
+{
+ struct mdnie_info *mdnie = container_of(h, struct mdnie_info, early_suspend);
+#if defined(CONFIG_FB_MDNIE_PWM)
+ struct lcd_platform_data *pd = mdnie->lcd_pd;
+#endif
+
+ dev_info(mdnie->dev, "+%s\n", __func__);
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+ if (mdnie->enable)
+ mdnie_pwm_control(mdnie, 0);
+
+ if (pd && pd->power_on)
+ pd->power_on(NULL, 1);
+
+ if (mdnie->enable) {
+ dev_info(&mdnie->bd->dev, "brightness=%d\n", mdnie->bd->props.brightness);
+ update_brightness(mdnie);
+ }
+
+ mdnie->bd_enable = TRUE;
+#endif
+
+ mdnie_update(mdnie);
+
+ dev_info(mdnie->dev, "-%s\n", __func__);
+
+ return;
+}
+#endif
+#endif
+
+static int mdnie_probe(struct platform_device *pdev)
+{
+#if defined(CONFIG_FB_MDNIE_PWM)
+ struct platform_mdnie_data *pdata = pdev->dev.platform_data;
+#endif
+ struct mdnie_info *mdnie;
+ int ret = 0;
+
+ mdnie_class = class_create(THIS_MODULE, dev_name(&pdev->dev));
+ if (IS_ERR_OR_NULL(mdnie_class)) {
+ pr_err("failed to create mdnie class\n");
+ ret = -EINVAL;
+ goto error0;
+ }
+
+ mdnie_class->dev_attrs = mdnie_attributes;
+
+ mdnie = kzalloc(sizeof(struct mdnie_info), GFP_KERNEL);
+ if (!mdnie) {
+ pr_err("failed to allocate mdnie\n");
+ ret = -ENOMEM;
+ goto error1;
+ }
+
+ mdnie->dev = device_create(mdnie_class, &pdev->dev, 0, &mdnie, "mdnie");
+ if (IS_ERR_OR_NULL(mdnie->dev)) {
+ pr_err("failed to create mdnie device\n");
+ ret = -EINVAL;
+ goto error2;
+ }
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+ if (!pdata) {
+ pr_err("no platform data specified\n");
+ ret = -EINVAL;
+ goto error2;
+ }
+
+ mdnie->bd = backlight_device_register("panel", mdnie->dev,
+ mdnie, &mdnie_backlight_ops, NULL);
+ mdnie->bd->props.max_brightness = MAX_BRIGHTNESS_LEVEL;
+ mdnie->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ mdnie->bd_enable = TRUE;
+ mdnie->lcd_pd = pdata->lcd_pd;
+
+ ret = device_create_file(&mdnie->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&mdnie->bd->dev, "failed to add sysfs entries, %d\n", __LINE__);
+#endif
+
+ mdnie->scenario = UI_MODE;
+ mdnie->mode = STANDARD;
+ mdnie->tone = TONE_NORMAL;
+ mdnie->outdoor = OUTDOOR_OFF;
+ mdnie->enable = TRUE;
+ mdnie->tuning = FALSE;
+ mdnie->negative = NEGATIVE_OFF;
+ mdnie->accessibility = ACCESSIBILITY_OFF;
+ mdnie->cabc = CABC_OFF;
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+#if defined(CONFIG_FB_S5P_S6F1202A)
+ mdnie->cabc = CABC_ON;
+#endif
+ mdnie->power_lut_idx = LUT_LEVEL_MANUAL_AND_INDOOR;
+ mdnie->auto_brightness = 0;
+#endif
+
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+ mdnie->ebook = EBOOK_OFF;
+#endif
+
+ mutex_init(&mdnie->lock);
+ mutex_init(&mdnie->dev_lock);
+
+ platform_set_drvdata(pdev, mdnie);
+ dev_set_drvdata(mdnie->dev, mdnie);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_FB_MDNIE_PWM)
+ mdnie->early_suspend.suspend = mdnie_early_suspend;
+#endif
+ mdnie->early_suspend.resume = mdnie_late_resume;
+ mdnie->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1;
+ register_early_suspend(&mdnie->early_suspend);
+#endif
+
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+ dev_info(mdnie->dev, "lcdtype = %d\n", pdata->display_type);
+ if (pdata->display_type > ARRAY_SIZE(backlight_table))
+ pdata->display_type = 0;
+ mdnie->backlight = &backlight_table[pdata->display_type];
+#endif
+
+#if defined(CONFIG_FB_S5P_S6F1202A)
+ if (pdata->display_type == 0) {
+ memcpy(tuning_table, tuning_table_hydis, sizeof(tuning_table));
+ memcpy(etc_table, etc_table_hydis, sizeof(etc_table));
+ memcpy(camera_table, camera_table_hydis, sizeof(camera_table));
+ } else if (pdata->display_type == 1) {
+ memcpy(tuning_table, tuning_table_sec, sizeof(tuning_table));
+ memcpy(etc_table, etc_table_sec, sizeof(etc_table));
+ memcpy(camera_table, camera_table_sec, sizeof(camera_table));
+ } else if (pdata->display_type == 2) {
+ memcpy(tuning_table, tuning_table_boe, sizeof(tuning_table));
+ memcpy(etc_table, etc_table_boe, sizeof(etc_table));
+ memcpy(camera_table, camera_table_boe, sizeof(camera_table));
+ }
+#endif
+
+ g_mdnie = mdnie;
+
+ mdnie_update(mdnie);
+
+ dev_info(mdnie->dev, "registered successfully\n");
+
+ return 0;
+
+error2:
+ kfree(mdnie);
+error1:
+ class_destroy(mdnie_class);
+error0:
+ return ret;
+}
+
+static int mdnie_remove(struct platform_device *pdev)
+{
+ struct mdnie_info *mdnie = dev_get_drvdata(&pdev->dev);
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+ backlight_device_unregister(mdnie->bd);
+#endif
+ class_destroy(mdnie_class);
+ kfree(mdnie);
+
+ return 0;
+}
+
+static void mdnie_shutdown(struct platform_device *pdev)
+{
+#if defined(CONFIG_FB_MDNIE_PWM)
+ struct mdnie_info *mdnie = dev_get_drvdata(&pdev->dev);
+ struct lcd_platform_data *pd = NULL;
+ pd = mdnie->lcd_pd;
+
+ dev_info(mdnie->dev, "+%s\n", __func__);
+
+ mdnie->bd_enable = FALSE;
+
+ if (mdnie->enable)
+ mdnie_pwm_control(mdnie, 0);
+
+ if (pd && pd->power_on)
+ pd->power_on(NULL, 0);
+
+ dev_info(mdnie->dev, "-%s\n", __func__);
+#endif
+}
+
+
+static struct platform_driver mdnie_driver = {
+ .driver = {
+ .name = "mdnie",
+ .owner = THIS_MODULE,
+ },
+ .probe = mdnie_probe,
+ .remove = mdnie_remove,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+ .suspend = mdnie_suspend,
+ .resume = mdnie_resume,
+#endif
+ .shutdown = mdnie_shutdown,
+};
+
+static int __init mdnie_init(void)
+{
+ return platform_driver_register(&mdnie_driver);
+}
+module_init(mdnie_init);
+
+static void __exit mdnie_exit(void)
+{
+ platform_driver_unregister(&mdnie_driver);
+}
+module_exit(mdnie_exit);
+
+MODULE_DESCRIPTION("mDNIe Driver");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/video/samsung/mdnie_kona.h b/drivers/video/samsung/mdnie_kona.h
new file mode 100644
index 0000000..b5c95ab
--- /dev/null
+++ b/drivers/video/samsung/mdnie_kona.h
@@ -0,0 +1,148 @@
+#ifndef __MDNIE_H__
+#define __MDNIE_H__
+
+#define END_SEQ 0xffff
+
+enum MODE {
+ DYNAMIC,
+ STANDARD,
+#if !defined(CONFIG_FB_MDNIE_PWM)
+ NATURAL,
+#endif
+ MOVIE,
+ MODE_MAX,
+};
+
+enum SCENARIO {
+ CYANOGENMOD_MODE,
+ UI_MODE,
+ VIDEO_MODE,
+ VIDEO_WARM_MODE,
+ VIDEO_COLD_MODE,
+ CAMERA_MODE,
+ NAVI_MODE,
+ GALLERY_MODE,
+ VT_MODE,
+ SCENARIO_MAX,
+ COLOR_TONE_1 = 40,
+ COLOR_TONE_2,
+ COLOR_TONE_3,
+ COLOR_TONE_MAX,
+};
+
+enum SCENARIO_DMB {
+ DMB_NORMAL_MODE = 20,
+ DMB_WARM_MODE,
+ DMB_COLD_MODE,
+ DMB_MODE_MAX,
+};
+
+enum OUTDOOR {
+ OUTDOOR_OFF,
+ OUTDOOR_ON,
+ OUTDOOR_MAX,
+};
+
+enum TONE {
+ TONE_NORMAL,
+ TONE_WARM,
+ TONE_COLD,
+ TONE_MAX,
+};
+
+enum CABC {
+ CABC_OFF,
+#if defined(CONFIG_FB_MDNIE_PWM)
+ CABC_ON,
+#endif
+ CABC_MAX,
+};
+
+enum POWER_LUT {
+ LUT_DEFAULT,
+ LUT_VIDEO,
+ LUT_MAX,
+};
+
+enum POWER_LUT_LEVEL {
+ LUT_LEVEL_MANUAL_AND_INDOOR,
+ LUT_LEVEL_OUTDOOR_1,
+ LUT_LEVEL_OUTDOOR_2,
+ LUT_LEVEL_MAX,
+};
+
+enum NEGATIVE {
+ NEGATIVE_OFF,
+ NEGATIVE_ON,
+ NEGATIVE_MAX,
+};
+
+enum ACCESSIBILITY {
+ ACCESSIBILITY_OFF,
+ NEGATIVE,
+ COLOR_BLIND,
+ ACCESSIBILITY_MAX,
+};
+
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+enum EBOOK {
+ EBOOK_OFF,
+ EBOOK_ON,
+ EBOOK_MAX,
+};
+#endif
+
+struct mdnie_tuning_info {
+ char *name;
+ unsigned short * const sequence;
+};
+
+struct mdnie_backlight_value {
+ const unsigned int max;
+ const unsigned int mid;
+ const unsigned char low;
+ const unsigned char dim;
+};
+
+struct mdnie_info {
+ struct device *dev;
+#if defined(CONFIG_FB_MDNIE_PWM)
+ struct lcd_platform_data *lcd_pd;
+ struct backlight_device *bd;
+ unsigned int bd_enable;
+ unsigned int auto_brightness;
+ unsigned int power_lut_idx;
+ struct mdnie_backlight_value *backlight;
+#endif
+ struct mutex lock;
+ struct mutex dev_lock;
+
+ unsigned int enable;
+ enum SCENARIO scenario;
+ enum MODE mode;
+ enum TONE tone;
+ enum OUTDOOR outdoor;
+ enum CABC cabc;
+ unsigned int tuning;
+ unsigned int negative;
+ unsigned int accessibility;
+ unsigned int color_correction;
+ char path[50];
+#if defined(CONFIG_FB_EBOOK_PANEL_SCENARIO)
+ unsigned int ebook;
+#endif
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+};
+
+extern struct mdnie_info *g_mdnie;
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+extern void set_mdnie_pwm_value(struct mdnie_info *mdnie, int value);
+#endif
+extern int mdnie_calibration(unsigned short x, unsigned short y, int *r);
+extern int mdnie_request_firmware(const char *path, u16 **buf, char *name);
+extern int mdnie_open_file(const char *path, char **fp);
+
+#endif /* __MDNIE_H__ */
diff --git a/drivers/video/samsung/mdnie_table_4412_kona.h b/drivers/video/samsung/mdnie_table_4412_kona.h
new file mode 100644
index 0000000..40e7c07
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_4412_kona.h
@@ -0,0 +1,319 @@
+#ifndef __MDNIE_TABLE_H__
+#define __MDNIE_TABLE_H__
+
+#include "mdnie_kona.h"
+
+
+static unsigned short tune_dynamic_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_natural_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_natural_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_natural_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_natural_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_camera[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static unsigned short tune_camera_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+};
+
+static unsigned short tune_cold[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_cold_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_normal_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_warm[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_warm_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+struct mdnie_tuning_info etc_table[CABC_MAX][OUTDOOR_MAX][TONE_MAX] = {
+ {
+ {
+ {"normal", NULL},
+ {"warm", tune_warm},
+ {"cold", tune_cold},
+ },
+ {
+ {"normal_outdoor", tune_normal_outdoor},
+ {"warm_outdoor", tune_warm_outdoor},
+ {"cold_outdoor", tune_cold_outdoor},
+ },
+ },
+ {
+ {
+ {"normal_cabc", NULL},
+ {"warm_cabc", tune_warm},
+ {"cold_cabc", tune_cold},
+ },
+ {
+ {"normal_outdoor_cabc", tune_normal_outdoor},
+ {"warm_outdoor_cabc", tune_warm_outdoor},
+ {"cold_outdoor_cabc", tune_cold_outdoor},
+ },
+ },
+};
+
+struct mdnie_tuning_info tuning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
+ {
+ {
+ {"dynamic_ui", tune_dynamic_ui},
+ {"dynamic_video", tune_dynamic_video},
+ {"dynamic_video", tune_dynamic_video},
+ {"dynamic_video", tune_dynamic_video},
+ {"camera", NULL},
+ {"dynamic_ui", tune_dynamic_ui},
+ {"dynamic_gallery", tune_dynamic_gallery},
+ {"dynamic_vt", tune_dynamic_vt},
+ }, {
+ {"standard_ui", tune_standard_ui},
+ {"standard_video", tune_standard_video},
+ {"standard_video", tune_standard_video},
+ {"standard_video", tune_standard_video},
+ {"camera", NULL},
+ {"standard_ui", tune_standard_ui},
+ {"standard_gallery", tune_standard_gallery},
+ {"standard_vt", tune_standard_vt},
+ }, {
+ {"movie_ui", tune_movie_ui},
+ {"movie_video", tune_movie_video},
+ {"movie_video", tune_movie_video},
+ {"movie_video", tune_movie_video},
+ {"camera", NULL},
+ {"movie_ui", tune_movie_ui},
+ {"movie_gallery", tune_movie_gallery},
+ {"movie_vt", tune_movie_vt},
+ },
+ }, {
+ {
+ {"dynamic_ui_cabc", tune_dynamic_ui},
+ {"dynamic_video_cabc", tune_dynamic_video},
+ {"dynamic_video_cabc", tune_dynamic_video},
+ {"dynamic_video_cabc", tune_dynamic_video},
+ {"camera", NULL},
+ {"dynamic_ui_cabc", tune_dynamic_ui},
+ {"dynamic_gallery_cabc", tune_dynamic_gallery},
+ {"dynamic_vt_cabc", tune_dynamic_vt},
+ }, {
+ {"standard_ui_cabc", tune_standard_ui},
+ {"standard_video_cabc", tune_standard_video},
+ {"standard_video_cabc", tune_standard_video},
+ {"standard_video_cabc", tune_standard_video},
+ {"camera", NULL},
+ {"standard_ui_cabc", tune_standard_ui},
+ {"standard_gallery_cabc", tune_standard_gallery},
+ {"standard_vt_cabc", tune_standard_vt},
+ }, {
+ {"movie_ui_cabc", tune_movie_ui},
+ {"movie_video_cabc", tune_movie_video},
+ {"movie_video_cabc", tune_movie_video},
+ {"movie_video_cabc", tune_movie_video},
+ {"camera", NULL},
+ {"movie_ui_cabc", tune_movie_ui},
+ {"movie_gallery_cabc", tune_movie_gallery},
+ {"movie_vt_cabc", tune_movie_vt},
+ },
+ },
+};
+#else
+struct mdnie_tuning_info etc_table[CABC_MAX][OUTDOOR_MAX][TONE_MAX] = {
+ {
+ {
+ {"normal", NULL},
+ {"warm", tune_warm},
+ {"cold", tune_cold},
+ },
+ {
+ {"normal_outdoor", tune_normal_outdoor},
+ {"warm_outdoor", tune_warm_outdoor},
+ {"cold_outdoor", tune_cold_outdoor},
+ },
+ }
+};
+
+struct mdnie_tuning_info tuning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
+ {
+ {
+ {"dynamic_ui", tune_dynamic_ui},
+ {"dynamic_video", tune_dynamic_video},
+ {"dynamic_video", tune_dynamic_video},
+ {"dynamic_video", tune_dynamic_video},
+ {"camera", NULL/*tune_camera*/},
+ {"dynamic_ui", tune_dynamic_ui},
+ {"dynamic_gallery", tune_dynamic_gallery},
+ {"dynamic_vt", tune_dynamic_vt},
+ }, {
+ {"standard_ui", tune_standard_ui},
+ {"standard_video", tune_standard_video},
+ {"standard_video", tune_standard_video},
+ {"standard_video", tune_standard_video},
+ {"camera", NULL/*tune_camera*/},
+ {"standard_ui", tune_standard_ui},
+ {"standard_gallery", tune_standard_gallery},
+ {"standard_vt", tune_standard_vt},
+ }, {
+ {"natural_ui", tune_natural_ui},
+ {"natural_video", tune_natural_video},
+ {"natural_video", tune_natural_video},
+ {"natural_video", tune_natural_video},
+ {"camera", NULL/*tune_camera*/},
+ {"natural_ui", tune_natural_ui},
+ {"natural_gallery", tune_natural_gallery},
+ {"natural_vt", tune_natural_vt},
+ }, {
+ {"movie_ui", tune_movie_ui},
+ {"movie_video", tune_movie_video},
+ {"movie_video", tune_movie_video},
+ {"movie_video", tune_movie_video},
+ {"camera", NULL/*tune_camera*/},
+ {"movie_ui", tune_movie_ui},
+ {"movie_gallery", tune_movie_gallery},
+ {"movie_vt", tune_movie_vt},
+ },
+ }
+};
+#endif
+
+struct mdnie_tuning_info camera_table[OUTDOOR_MAX] = {
+ {"camera", tune_camera},
+ {"camera_outdoor", tune_camera_outdoor},
+};
+
+#endif /* __MDNIE_TABLE_H__ */
diff --git a/drivers/video/samsung/mdnie_table_ebook.h b/drivers/video/samsung/mdnie_table_ebook.h
new file mode 100644
index 0000000..2f75fa4
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_ebook.h
@@ -0,0 +1,153 @@
+#ifndef __MDNIE_TABLE_EBOOK_H__
+#define __MDNIE_TABLE_EBOOK_H__
+
+#include "mdnie_kona.h"
+
+#if defined(CONFIG_FB_MDNIE_PWM)
+static unsigned short tune_ebook[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00a0, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00ff, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ef, /*SCR KgWg*/
+ 0x00ec,0x00e4, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x1090, /*CC lut r 16 144*/
+ 0x0022,0x20a0, /*CC lut r 32 160*/
+ 0x0023,0x30b0, /*CC lut r 48 176*/
+ 0x0024,0x40c0, /*CC lut r 64 192*/
+ 0x0025,0x50d0, /*CC lut r 80 208*/
+ 0x0026,0x60e0, /*CC lut r 96 224*/
+ 0x0027,0x70f0, /*CC lut r 112 240*/
+ 0x0028,0x80ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_ebook_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02a0, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00ff, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ef, /*SCR KgWg*/
+ 0x00ec,0x00e4, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x1090, /*CC lut r 16 144*/
+ 0x0022,0x20a0, /*CC lut r 32 160*/
+ 0x0023,0x30b0, /*CC lut r 48 176*/
+ 0x0024,0x40c0, /*CC lut r 64 192*/
+ 0x0025,0x50d0, /*CC lut r 80 208*/
+ 0x0026,0x60e0, /*CC lut r 96 224*/
+ 0x0027,0x70f0, /*CC lut r 112 240*/
+ 0x0028,0x80ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+#else
+static unsigned short tune_ebook[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00a0, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00ff, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ef, /*SCR KgWg*/
+ 0x00ec,0x00e4, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x1090, /*CC lut r 16 144*/
+ 0x0022,0x20a0, /*CC lut r 32 160*/
+ 0x0023,0x30b0, /*CC lut r 48 176*/
+ 0x0024,0x40c0, /*CC lut r 64 192*/
+ 0x0025,0x50d0, /*CC lut r 80 208*/
+ 0x0026,0x60e0, /*CC lut r 96 224*/
+ 0x0027,0x70f0, /*CC lut r 112 240*/
+ 0x0028,0x80ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+#endif
+
+struct mdnie_tuning_info ebook_table[CABC_MAX] = {
+#if defined(CONFIG_FB_MDNIE_PWM)
+ {"EBOOK", tune_ebook},
+ {"EBOOK_CABC", tune_ebook_cabc},
+#else
+ {"EBOOK", tune_ebook},
+#endif
+};
+#endif /* __MDNIE_TABLE_EBOOK_H__ */
diff --git a/drivers/video/samsung/mdnie_table_kona.h b/drivers/video/samsung/mdnie_table_kona.h
new file mode 100644
index 0000000..8b3b283
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_kona.h
@@ -0,0 +1,1304 @@
+#ifndef __MDNIE_TABLE_H__
+#define __MDNIE_TABLE_H__
+
+#include "mdnie_kona.h"
+
+
+static struct mdnie_backlight_value backlight_table[4] = {
+ {
+ .max = 977, /*3G/WIFI BOE LCD SYS REV <= 0x03*/
+ .mid = 531, /*LTE BOE LCD SYS REV <= 0x02*/
+ .low = 16,
+ .dim = 16,
+ }, {
+ .max = 1280, /*3G/WIFI BOE LCD SYS REV >= 0x04*/
+ .mid = 700, /*LTE BOE LCD SYS REV >= 0x03*/
+ .low = 16,
+ .dim = 16,
+ }, {
+ .max = 1056, /*3G/WIFI SDC LCD SYS REV <= 0x03*/
+ .mid = 574, /*LTE SDC LCD SYS REV <= 0x02*/
+ .low = 16,
+ .dim = 16,
+ }, {
+ .max = 1435, /* 3G/WIFI SDC LCD SYS REV >= 0x04*/
+ .mid = 780, /* LTE SDC LCD SYS REV >= 0x03*/
+ .low = 17,
+ .dim = 17,
+ }
+};
+
+static const unsigned char power_lut[LUT_LEVEL_MAX][LUT_MAX][9] = {
+ /* Indoor power look up table */
+ {
+ {0x42, 0x3d, 0x3E, 0x48, 0x42, 0x3F, 0x3A, 0x37, 0x3F},
+ {0x38, 0x3d, 0x34, 0x48, 0x38, 0x35, 0x30, 0x2d, 0x35},
+ },
+ /* Outdoor power look up table for outdoor 1 (1k~15k) */
+ {
+ {0x42, 0x47, 0x3E, 0x52, 0x42, 0x3F, 0x3A, 0x37, 0x3F},
+ {0x38, 0x3d, 0x34, 0x48, 0x38, 0x35, 0x30, 0x2d, 0x35},
+ },
+ /* Outdoor power look up table (15k ~) */
+ {
+ {100, 100, 100, 100, 100, 100, 100, 100, 100},
+ {100, 100, 100, 100, 100, 100, 100, 100, 100},
+ },
+};
+
+static unsigned short tune_camera[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x002c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092,0x0000, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_camera_outdoor[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x042c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092,0x0000, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x00d0,0x01a0, /*UC y*/
+ 0x00d1,0x01ff, /*UC cs*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_ui[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00a8, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_video[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0080, /*DE pf*/
+ 0x0094,0x0080, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0080, /*DE nf*/
+ 0x0097,0x0080, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_gallery[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0050, /*DE pf*/
+ 0x0094,0x0050, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0050, /*DE nf*/
+ 0x0097,0x0050, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_vt[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00ae, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0005, /*FA cs1 de8 hdr2 fa1*/
+ 0x0039,0x0080, /*FA dnrWeight*/
+ 0x0080,0x0fff, /*DNR dirTh*/
+ 0x0081,0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082,0xff16, /*DNR decon5Th maskTh*/
+ 0x0083,0x0000, /*DNR blTh*/
+ 0x0092,0x00e0, /*DE pe*/
+ 0x0093,0x00e0, /*DE pf*/
+ 0x0094,0x00e0, /*DE pb*/
+ 0x0095,0x00e0, /*DE ne*/
+ 0x0096,0x00e0, /*DE nf*/
+ 0x0097,0x00e0, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_ui[] = {
+ /*start KONA standard ui cabcoff*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00a8, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_video[] = {
+ /*start KONA standard video cabcoff*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0060, /*DE pf*/
+ 0x0094,0x0060, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0060, /*DE nf*/
+ 0x0097,0x0060, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_gallery[] = {
+ /*start KONA standard gallery cabcoff*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0000, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_vt[] = {
+ /*start KONA standard vtcall cabcoff*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x00ae, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0005, /*FA cs1 de8 hdr2 fa1*/
+ 0x0039,0x0080, /*FA dnrWeight*/
+ 0x0080,0x0fff, /*DNR dirTh*/
+ 0x0081,0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082,0xff16, /*DNR decon5Th maskTh*/
+ 0x0083,0x0000, /*DNR blTh*/
+ 0x0092,0x00c0, /*DE pe*/
+ 0x0093,0x00c0, /*DE pf*/
+ 0x0094,0x00c0, /*DE pb*/
+ 0x0095,0x00c0, /*DE ne*/
+ 0x0096,0x00c0, /*DE nf*/
+ 0x0097,0x00c0, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_ui[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_video[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092,0x0000, /*DE pe*/
+ 0x0093,0x0000, /*DE pf*/
+ 0x0094,0x0000, /*DE pb*/
+ 0x0095,0x0000, /*DE ne*/
+ 0x0096,0x0000, /*DE nf*/
+ 0x0097,0x0000, /*DE nb*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1004, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_gallery[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x0020, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_vt[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x002e, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0005, /*FA cs1 de8 hdr2 fa1*/
+ 0x0039,0x0080, /*FA dnrWeight*/
+ 0x0080,0x0fff, /*DNR dirTh*/
+ 0x0081,0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082,0xff16, /*DNR decon5Th maskTh*/
+ 0x0083,0x0000, /*DNR blTh*/
+ 0x0092,0x0040, /*DE pe*/
+ 0x0093,0x0040, /*DE pf*/
+ 0x0094,0x0040, /*DE pb*/
+ 0x0095,0x0040, /*DE ne*/
+ 0x0096,0x0040, /*DE nf*/
+ 0x0097,0x0040, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1204, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_ui_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02a8, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_video_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0080, /*DE pf*/
+ 0x0094,0x0080, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0080, /*DE nf*/
+ 0x0097,0x0080, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_gallery_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0050, /*DE pf*/
+ 0x0094,0x0050, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0050, /*DE nf*/
+ 0x0097,0x0050, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_dynamic_vt_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02ae, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0005, /*FA cs1 de8 hdr2 fa1*/
+ 0x0039,0x0080, /*FA dnrWeight*/
+ 0x0080,0x0fff, /*DNR dirTh*/
+ 0x0081,0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082,0xff16, /*DNR decon5Th maskTh*/
+ 0x0083,0x0000, /*DNR blTh*/
+ 0x0092,0x00e0, /*DE pe*/
+ 0x0093,0x00e0, /*DE pf*/
+ 0x0094,0x00e0, /*DE pb*/
+ 0x0095,0x00e0, /*DE ne*/
+ 0x0096,0x00e0, /*DE nf*/
+ 0x0097,0x00e0, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1a04, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0b94, /*CC lut r 16 144*/
+ 0x0022,0x18a6, /*CC lut r 32 160*/
+ 0x0023,0x28b8, /*CC lut r 48 176*/
+ 0x0024,0x3ac9, /*CC lut r 64 192*/
+ 0x0025,0x4cd9, /*CC lut r 80 208*/
+ 0x0026,0x5ee7, /*CC lut r 96 224*/
+ 0x0027,0x70f4, /*CC lut r 112 240*/
+ 0x0028,0x82ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_ui_cabc[] = {
+ /*start KONA standard ui cabcon*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02a8, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_video_cabc[] = {
+ /*start KONA standard video cabcon*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0030, /*DE pe*/
+ 0x0093,0x0060, /*DE pf*/
+ 0x0094,0x0060, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0060, /*DE nf*/
+ 0x0097,0x0060, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_gallery_cabc[] = {
+ /*start KONA standard gallery cabcon*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090,0x0080, /*DE egth*/
+ 0x0092,0x0000, /*DE pe*/
+ 0x0093,0x0030, /*DE pf*/
+ 0x0094,0x0030, /*DE pb*/
+ 0x0095,0x0030, /*DE ne*/
+ 0x0096,0x0030, /*DE nf*/
+ 0x0097,0x0030, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_standard_vt_cabc[] = {
+ /*start KONA standard vtcall cabcon*/
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x02ae, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0005, /*FA cs1 de8 hdr2 fa1*/
+ 0x0039,0x0080, /*FA dnrWeight*/
+ 0x0080,0x0fff, /*DNR dirTh*/
+ 0x0081,0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082,0xff16, /*DNR decon5Th maskTh*/
+ 0x0083,0x0000, /*DNR blTh*/
+ 0x0092,0x00c0, /*DE pe*/
+ 0x0093,0x00c0, /*DE pf*/
+ 0x0094,0x00c0, /*DE pb*/
+ 0x0095,0x00c0, /*DE ne*/
+ 0x0096,0x00c0, /*DE nf*/
+ 0x0097,0x00c0, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1804, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00ff, /*SCR KgWg*/
+ 0x00ec,0x00ff, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x001f,0x0080, /*CC chsel strength*/
+ 0x0020,0x0000, /*CC lut r 0*/
+ 0x0021,0x0a82, /*CC lut r 16 144*/
+ 0x0022,0x1693, /*CC lut r 32 160*/
+ 0x0023,0x23a4, /*CC lut r 48 176*/
+ 0x0024,0x32b6, /*CC lut r 64 192*/
+ 0x0025,0x41c8, /*CC lut r 80 208*/
+ 0x0026,0x50da, /*CC lut r 96 224*/
+ 0x0027,0x60ed, /*CC lut r 112 240*/
+ 0x0028,0x71ff, /*CC lut r 128 255*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ /*end*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_ui_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x0220, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_video_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x0220, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092,0x0000, /*DE pe*/
+ 0x0093,0x0000, /*DE pf*/
+ 0x0094,0x0000, /*DE pb*/
+ 0x0095,0x0000, /*DE ne*/
+ 0x0096,0x0000, /*DE nf*/
+ 0x0097,0x0000, /*DE nb*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1004, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_gallery_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x0220, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_movie_vt_cabc[] = {
+ 0x0000,0x0000, /*BANK 0*/
+ 0x0008,0x022e, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030,0x0005, /*FA cs1 de8 hdr2 fa1*/
+ 0x0039,0x0080, /*FA dnrWeight*/
+ 0x0080,0x0fff, /*DNR dirTh*/
+ 0x0081,0x19ff, /*DNR dirnumTh decon7Th*/
+ 0x0082,0xff16, /*DNR decon5Th maskTh*/
+ 0x0083,0x0000, /*DNR blTh*/
+ 0x0092,0x0040, /*DE pe*/
+ 0x0093,0x0040, /*DE pf*/
+ 0x0094,0x0040, /*DE pb*/
+ 0x0095,0x0040, /*DE ne*/
+ 0x0096,0x0040, /*DE nf*/
+ 0x0097,0x0040, /*DE nb*/
+ 0x0098,0x1000, /*DE max ratio*/
+ 0x0099,0x0100, /*DE min ratio*/
+ 0x00b0,0x1010, /*CS hg ry*/
+ 0x00b1,0x1010, /*CS hg gc*/
+ 0x00b2,0x1010, /*CS hg bm*/
+ 0x00b3,0x1204, /*CS weight grayTH*/
+ 0x00e1,0xff00, /*SCR RrCr*/
+ 0x00e2,0x00ff, /*SCR RgCg*/
+ 0x00e3,0x00ff, /*SCR RbCb*/
+ 0x00e4,0x00ff, /*SCR GrMr*/
+ 0x00e5,0xff00, /*SCR GgMg*/
+ 0x00e6,0x00ff, /*SCR GbMb*/
+ 0x00e7,0x00ff, /*SCR BrYr*/
+ 0x00e8,0x00f0, /*SCR BgYg*/
+ 0x00e9,0xff00, /*SCR BbYb*/
+ 0x00ea,0x00ff, /*SCR KrWr*/
+ 0x00eb,0x00f6, /*SCR KgWg*/
+ 0x00ec,0x00f2, /*SCR KbWb*/
+ 0x0000,0x0001, /*BANK 1*/
+ 0x0075,0x0000, /*CABC dgain*/
+ 0x0076,0x0000,
+ 0x0077,0x0000,
+ 0x0078,0x0000,
+ 0x007f,0x0002, /*dynamic lcd*/
+ 0x00ff,0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_warm[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0028, /*MCM 4000K*/
+ 0x0007, 0x7575, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_cold[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0064, /*MCM 10000K*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7979, /*MCM 4cr 5cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_normal_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x04ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x00d0, 0x01a0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_warm_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x04ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0028, /*MCM 4000K*/
+ 0x0007, 0x7575, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_cold_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x04ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0064, /*MCM 10000K*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7979, /*MCM 4cr 5cr W*/
+ 0x00d0, 0x01a0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_warm_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x02ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0028, /*MCM 4000K*/
+ 0x0007, 0x7575, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_cold_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x02ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0064, /*MCM 10000K*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7979, /*MCM 4cr 5cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_normal_outdoor_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x06ac, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x00d0, 0x01a0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_warm_outdoor_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x06ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0028, /*MCM 4000K*/
+ 0x0007, 0x7575, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static unsigned short tune_cold_outdoor_cabc[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x06ec, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x0001, 0x0064, /*MCM 10000K*/
+ 0x0009, 0xa08e, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7979, /*MCM 4cr 5cr W*/
+ 0x00d0, 0x01a0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+struct mdnie_tuning_info etc_table[CABC_MAX][OUTDOOR_MAX][TONE_MAX] = {
+ {
+ {
+ {"normal", NULL},
+ {"warm", tune_warm},
+ {"cold", tune_cold},
+ },
+ {
+ {"normal_outdoor", tune_normal_outdoor},
+ {"warm_outdoor", tune_warm_outdoor},
+ {"cold_outdoor", tune_cold_outdoor},
+ },
+ },
+ {
+ {
+ {"normal_cabc", NULL},
+ {"warm_cabc", tune_warm_cabc},
+ {"cold_cabc", tune_cold_cabc},
+ },
+ {
+ {"normal_outdoor_cabc", tune_normal_outdoor_cabc},
+ {"warm_outdoor_cabc", tune_warm_outdoor_cabc},
+ {"cold_outdoor_cabc", tune_cold_outdoor_cabc},
+ },
+ },
+};
+
+struct mdnie_tuning_info tuning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
+ {
+ {
+ {"dynamic_ui", tune_dynamic_ui},
+ {"dynamic_video", tune_dynamic_video},
+ {"dynamic_video", tune_dynamic_video},
+ {"dynamic_video", tune_dynamic_video},
+ {"camera", NULL},
+ {"dynamic_ui", tune_dynamic_ui},
+ {"dynamic_gallery", tune_dynamic_gallery},
+ {"dynamic_vt", tune_dynamic_vt},
+ }, {
+ {"standard_ui", tune_standard_ui},
+ {"standard_video", tune_standard_video},
+ {"standard_video", tune_standard_video},
+ {"standard_video", tune_standard_video},
+ {"camera", NULL},
+ {"standard_ui", tune_standard_ui},
+ {"standard_gallery", tune_standard_gallery},
+ {"standard_vt", tune_standard_vt},
+ }, {
+ {"movie_ui", tune_movie_ui},
+ {"movie_video", tune_movie_video},
+ {"movie_video", tune_movie_video},
+ {"movie_video", tune_movie_video},
+ {"camera", NULL},
+ {"movie_ui", tune_movie_ui},
+ {"movie_gallery", tune_movie_gallery},
+ {"movie_vt", tune_movie_vt},
+ },
+ }, {
+ {
+ {"dynamic_ui_cabc", tune_dynamic_ui_cabc},
+ {"dynamic_video_cabc", tune_dynamic_video_cabc},
+ {"dynamic_video_cabc", tune_dynamic_video_cabc},
+ {"dynamic_video_cabc", tune_dynamic_video_cabc},
+ {"camera", NULL},
+ {"dynamic_ui_cabc", tune_dynamic_ui_cabc},
+ {"dynamic_gallery_cabc", tune_dynamic_gallery_cabc},
+ {"dynamic_vt_cabc", tune_dynamic_vt_cabc},
+ }, {
+ {"standard_ui_cabc", tune_standard_ui_cabc},
+ {"standard_video_cabc", tune_standard_video_cabc},
+ {"standard_video_cabc", tune_standard_video_cabc},
+ {"standard_video_cabc", tune_standard_video_cabc},
+ {"camera", NULL},
+ {"standard_ui_cabc", tune_standard_ui_cabc},
+ {"standard_gallery_cabc", tune_standard_gallery_cabc},
+ {"standard_vt_cabc", tune_standard_vt_cabc},
+ }, {
+ {"movie_ui_cabc", tune_movie_ui_cabc},
+ {"movie_video_cabc", tune_movie_video_cabc},
+ {"movie_video_cabc", tune_movie_video_cabc},
+ {"movie_video_cabc", tune_movie_video_cabc},
+ {"camera", NULL},
+ {"movie_ui_cabc", tune_movie_ui_cabc},
+ {"movie_gallery_cabc", tune_movie_gallery_cabc},
+ {"movie_vt_cabc", tune_movie_vt_cabc},
+ },
+ },
+};
+
+struct mdnie_tuning_info camera_table[OUTDOOR_MAX] = {
+ {"camera", tune_camera},
+ {"camera_outdoor", tune_camera_outdoor},
+};
+
+#endif /* __MDNIE_TABLE_H__ */
diff --git a/drivers/video/samsung/mdnie_table_t0.h b/drivers/video/samsung/mdnie_table_t0.h
index 94062c8..f653e4e 100644
--- a/drivers/video/samsung/mdnie_table_t0.h
+++ b/drivers/video/samsung/mdnie_table_t0.h
@@ -3,6 +3,18 @@
#include "mdnie.h"
+static const unsigned short tune_cyanogenmod[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0008, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0090, 0x0080, /*DE egth*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
static const unsigned short tune_dynamic_gallery[] = {
0x0000, 0x0000, /*BANK 0*/
@@ -638,6 +650,7 @@ struct mdnie_tunning_info etc_table[CABC_MAX][OUTDOOR_MAX][TONE_MAX] = {
struct mdnie_tunning_info tunning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
{
{
+ {"CYANOGENMOD", tune_cyanogenmod},
{"DYNAMIC_UI", tune_dynamic_ui},
{"DYNAMIC_VIDEO", tune_dynamic_video},
{"DYNAMIC_VIDEO", tune_dynamic_video},
@@ -647,6 +660,7 @@ struct mdnie_tunning_info tunning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
{"DYNAMIC_GALLERY", tune_dynamic_gallery},
{"DYNAMIC_VT", tune_dynamic_vt},
}, {
+ {"CYANOGENMOD", tune_cyanogenmod},
{"STANDARD_UI", tune_standard_ui},
{"STANDARD_VIDEO", tune_standard_video},
{"STANDARD_VIDEO", tune_standard_video},
@@ -656,6 +670,7 @@ struct mdnie_tunning_info tunning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
{"STANDARD_GALLERY", tune_standard_gallery},
{"STANDARD_VT", tune_standard_vt},
}, {
+ {"CYANOGENMOD", tune_cyanogenmod},
{"NATURAL_UI", tune_natural_ui},
{"NATURAL_VIDEO", tune_natural_video},
{"NATURAL_VIDEO_WARM", tune_natural_video},
@@ -665,6 +680,7 @@ struct mdnie_tunning_info tunning_table[CABC_MAX][MODE_MAX][SCENARIO_MAX] = {
{"NATURAL_GALLERY", tune_natural_gallery},
{"NATURAL_VT", tune_natural_vt},
}, {
+ {"CYANOGENMOD", tune_cyanogenmod},
{"MOVIE_UI", tune_movie_ui},
{"MOVIE_VIDEO", tune_movie_video},
{"MOVIE_VIDEO", tune_movie_video},
diff --git a/drivers/video/samsung/mdnie_tuning_kona.c b/drivers/video/samsung/mdnie_tuning_kona.c
new file mode 100644
index 0000000..e198a85
--- /dev/null
+++ b/drivers/video/samsung/mdnie_tuning_kona.c
@@ -0,0 +1,294 @@
+/* linux/drivers/video/samsung/mdnie_tuning.c
+ *
+ * Register interface file for Samsung mDNIe driver
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/ctype.h>
+#include <linux/uaccess.h>
+#include <linux/magic.h>
+
+#include "s3cfb.h"
+#include "mdnie_kona.h"
+
+#define KFREE(ptr) do { if (ptr) kfree(ptr); (ptr) = NULL; } while (0)
+#define CONSTANT_F1 ((23<<10)/21)
+#define CONSTANT_F2 ((19<<10)/18)
+#define CONSTANT_F3 (5<<10)
+#define CONSTANT_F4 ((21<<10)/8)
+
+int mdnie_calibration(unsigned short x, unsigned short y, int *result)
+{
+ u8 ret = 0;
+
+ result[1] = ((y << 10) - (CONSTANT_F1 * x) + (12 << 10)) >> 10;
+ result[2] = ((y << 10) - (CONSTANT_F2 * x) + (44 << 10)) >> 10;
+ result[3] = ((y << 10) + (CONSTANT_F3 * x) - (18365 << 10)) >> 10;
+ result[4] = ((y << 10) + (CONSTANT_F4 * x) - (10814 << 10)) >> 10;
+
+ pr_info("%d, %d, %d, %d\n", result[1], result[2], result[3], result[4]);
+
+ if (result[1] > 0) {
+ if (result[3] > 0)
+ ret = 3;
+ else
+ ret = (result[4] < 0) ? 1 : 2;
+ } else {
+ if (result[2] < 0) {
+ if (result[3] > 0)
+ ret = 9;
+ else
+ ret = (result[4] < 0) ? 7 : 8;
+ } else {
+ if (result[3] > 0)
+ ret = 6;
+ else
+ ret = (result[4] < 0) ? 4 : 5;
+ }
+ }
+
+ ret = (ret > 0) ? ret : 1;
+ ret = (ret > 9) ? 1 : ret;
+
+ return ret;
+}
+
+static int parse_text(char *src, int len, u16 *buf, char *name)
+{
+ int i, count, ret;
+ int index = 0;
+ char *str_line[100];
+ char *sstart;
+ char *c;
+ unsigned int data1, data2;
+
+ c = src;
+ count = 0;
+ sstart = c;
+
+ for (i = 0; i < len; i++, c++) {
+ char a = *c;
+ if (a == '\r' || a == '\n') {
+ if (c > sstart) {
+ str_line[count] = sstart;
+ count++;
+ }
+ *c = '\0';
+ sstart = c+1;
+ }
+ }
+
+ if (c > sstart) {
+ str_line[count] = sstart;
+ count++;
+ }
+
+ /* printk(KERN_INFO "----------------------------- Total number of lines:%d\n", count); */
+
+ for (i = 0; i < count; i++) {
+ /* printk(KERN_INFO "line:%d, [start]%s[end]\n", i, str_line[i]); */
+ ret = sscanf(str_line[i], "0x%x, 0x%x\n", &data1, &data2);
+ /* printk(KERN_INFO "Result => [0x%2x 0x%4x] %s\n", data1, data2, (ret == 2) ? "Ok" : "Not available"); */
+ if (ret == 2) {
+ buf[index++] = (unsigned short)data1;
+ buf[index++] = (unsigned short)data2;
+ }
+ }
+
+ buf[index] = END_SEQ;
+
+ return index;
+}
+
+int mdnie_txtbuf_to_parsing(char *path, u16 size, u16 *buf, char *name)
+{
+ struct file *filp;
+ char *dp;
+ long l;
+ loff_t pos;
+ int ret, num;
+ mm_segment_t fs;
+
+ fs = get_fs();
+ set_fs(get_ds());
+
+ if (!path) {
+ pr_err("%s: invalid filepath\n", __func__);
+ goto parse_err;
+ }
+
+ filp = filp_open(path, O_RDONLY, 0);
+
+ if (IS_ERR(filp)) {
+ pr_err("file open error: %s\n", path);
+ goto parse_err;
+ }
+
+ l = filp->f_path.dentry->d_inode->i_size;
+ dp = kmalloc(l, GFP_KERNEL);
+ if (dp == NULL) {
+ pr_err("Out of Memory!\n");
+ filp_close(filp, current->files);
+ goto parse_err;
+ }
+ pos = 0;
+ memset(dp, 0, l);
+ ret = vfs_read(filp, (char __user *)dp, l, &pos);
+
+ if (ret != l) {
+ pr_info("read size = %d, l = %ld, size=%d\n", ret, l, size);
+ l = (l > ret) ? ret : l;
+ if (size < l) {
+ KFREE(dp);
+ filp_close(filp, current->files);
+ goto parse_err;
+ }
+ }
+
+ filp_close(filp, current->files);
+ set_fs(fs);
+
+ num = parse_text(dp, l, buf, name);
+
+ if (!num) {
+ pr_err("Nothing to parse!\n");
+ KFREE(dp);
+ goto parse_err;
+ }
+
+ KFREE(dp);
+
+ return num;
+
+parse_err:
+ return -EPERM;
+}
+
+int mdnie_open_file(const char *path, char **fp)
+{
+ struct file *filp;
+ char *dp;
+ long length;
+ int ret;
+ struct super_block *sb;
+ loff_t pos = 0;
+
+ if (!path) {
+ pr_err("%s: path is invalid\n", __func__);
+ return -EPERM;
+ }
+
+ filp = filp_open(path, O_RDONLY, 0);
+ if (IS_ERR(filp)) {
+ pr_err("%s: file open err: %s\n", __func__, path);
+ return -EPERM;
+ }
+
+ length = i_size_read(filp->f_path.dentry->d_inode);
+ if (length <= 0) {
+ pr_err("%s: file size %ld error\n", __func__, length);
+ return -EPERM;
+ }
+
+ dp = kzalloc(length, GFP_KERNEL);
+ if (dp == NULL) {
+ pr_err("%s: Out of Memory\n", __func__);
+ filp_close(filp, current->files);
+ return -EPERM;
+ }
+
+ ret = kernel_read(filp, pos, dp, length);
+ if (ret != length) {
+ /* check node is sysfs, bus this way is not safe */
+ sb = filp->f_path.dentry->d_inode->i_sb;
+ if ((sb->s_magic != SYSFS_MAGIC) && (length != sb->s_blocksize)) {
+ pr_err("%s: read size= %d, length= %ld\n", __func__, ret, length);
+ KFREE(dp);
+ filp_close(filp, current->files);
+ return -EPERM;
+ }
+ }
+
+ filp_close(filp, current->files);
+
+ *fp = dp;
+
+ return ret;
+}
+
+int mdnie_check_firmware(const char *path, char *name)
+{
+ char *ptr = NULL;
+ int ret = 0, size;
+
+ size = mdnie_open_file(path, &ptr);
+ if (IS_ERR_OR_NULL(ptr) || size <= 0) {
+ pr_err("%s: file open fail %s\n", __func__, path);
+ KFREE(ptr);
+ return 0;
+ }
+
+ ret = (strstr(ptr, name) != NULL) ? 1 : 0;
+
+ KFREE(ptr);
+
+ return ret;
+}
+
+int mdnie_request_firmware(const char *path, u16 **buf, char *name)
+{
+ char *token, *ptr = NULL;
+ unsigned short *dp;
+ int ret = 0, size, i = 0;
+ unsigned int data1, data2;
+
+ size = mdnie_open_file(path, &ptr);
+ if (IS_ERR_OR_NULL(ptr) || size <= 0) {
+ pr_err("%s: file open fail %s\n", __func__, path);
+ KFREE(ptr);
+ return ret;
+ }
+
+ dp = kzalloc(size, GFP_KERNEL);
+ if (dp == NULL) {
+ pr_err("%s: Out of Memory\n", __func__);
+ KFREE(ptr);
+ return -ENOMEM;
+ }
+
+ if (name) {
+ if (strstr(ptr, name) != NULL) {
+ pr_info("found %s in %s\n", name, path);
+ ptr = strstr(ptr, name);
+ }
+ }
+
+ while ((token = strsep(&ptr, "\r\n")) != NULL) {
+ if ((name) && (!strncmp(token, "};", 2))) {
+ pr_info("found %s end in local, stop searching\n", name);
+ break;
+ }
+ ret = sscanf(token, "%x, %x", &data1, &data2);
+ if (ret == 2) {
+ dp[i] = (u16)data1;
+ dp[i+1] = (u16)data2;
+ i += 2;
+ }
+ }
+
+ dp[i] = END_SEQ;
+
+ *buf = dp;
+
+ KFREE(ptr);
+
+ return i;
+}
+
diff --git a/drivers/video/samsung/s3cfb_ielcd_kona.c b/drivers/video/samsung/s3cfb_ielcd_kona.c
new file mode 100644
index 0000000..7eadd5f
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ielcd_kona.c
@@ -0,0 +1,136 @@
+/* linux/drivers/video/samsung/s3cfb_mdnie.c
+ *
+ * Register interface file for Samsung IELCD driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/mutex.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/fs.h>
+#include <linux/irq.h>
+#include <linux/mm.h>
+#include <linux/fb.h>
+#include <linux/ctype.h>
+#include <linux/miscdevice.h>
+#include <linux/dma-mapping.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+
+#include <linux/io.h>
+#include <mach/map.h>
+#include <plat/clock.h>
+#include <plat/regs-fb-s5p.h>
+
+#include "s3cfb.h"
+#include "s3cfb_mdnie_kona.h"
+#include "s3cfb_ielcd_kona.h"
+
+static struct resource *s3c_ielcd_mem;
+static void __iomem *s3c_ielcd_base;
+
+#define s3c_ielcd_readl(addr) __raw_readl(s3c_ielcd_base + addr)
+#define s3c_ielcd_writel(addr, val) writel(val, s3c_ielcd_base + addr)
+
+static struct s3cfb_global ielcd_fb;
+static struct s3cfb_global *ielcd_fbdev;
+
+int ielcd_hw_init(void)
+{
+ s3c_ielcd_mem = request_mem_region(S3C_IELCD_PHY_BASE, S3C_IELCD_MAP_SIZE, "ielcd");
+ if (IS_ERR_OR_NULL(s3c_ielcd_mem)) {
+ pr_err("%s: fail to request_mem_region\n", __func__);
+ return -ENOENT;
+ }
+
+ s3c_ielcd_base = ioremap(S3C_IELCD_PHY_BASE, S3C_IELCD_MAP_SIZE);
+ if (IS_ERR_OR_NULL(s3c_ielcd_base)) {
+ pr_err("%s: fail to ioremap\n", __func__);
+ return -ENOENT;
+ }
+
+ ielcd_fbdev = &ielcd_fb;
+
+ return 0;
+}
+
+int ielcd_display_on(void)
+{
+ unsigned int cfg;
+
+ cfg = s3c_ielcd_readl(S3C_VIDCON0);
+ cfg |= (S3C_VIDCON0_ENVID_ENABLE | S3C_VIDCON0_ENVID_F_ENABLE);
+ s3c_ielcd_writel(S3C_VIDCON0, cfg);
+
+ return 0;
+}
+
+int ielcd_display_off(void)
+{
+ unsigned int cfg, ielcd_count = 0;
+
+ cfg = s3c_ielcd_readl(S3C_VIDCON0);
+ cfg |= S3C_VIDCON0_ENVID_ENABLE;
+ cfg &= ~(S3C_VIDCON0_ENVID_F_ENABLE);
+
+ s3c_ielcd_writel(S3C_VIDCON0, cfg);
+
+ do {
+ if (++ielcd_count > 2000000) {
+ printk(KERN_ERR "ielcd off fail\n");
+ return 1;
+ }
+
+ if (!(s3c_ielcd_readl(S3C_VIDCON1) & 0xffff0000))
+ return 0;
+ } while (1);
+}
+
+void ielcd_init_global(struct s3cfb_global *ctrl)
+{
+ unsigned int cfg;
+
+ *ielcd_fbdev = *ctrl;
+ ctrl->ielcd_regs = ielcd_fbdev->regs = s3c_ielcd_base;
+
+ s3c_ielcd_writel(S3C_IELCD_GPOUTCON0, S3C_IELCD_MAGIC_KEY);
+
+ s3cfb_set_polarity_only(ielcd_fbdev);
+ s3cfb_set_timing(ielcd_fbdev);
+ s3cfb_set_lcd_size(ielcd_fbdev);
+
+ /* vclock divider setting , same as FIMD */
+ cfg = readl(ctrl->regs + S3C_VIDCON0);
+ cfg &= ~(S3C_VIDCON0_VIDOUT_MASK | S3C_VIDCON0_VCLKEN_MASK);
+ cfg |= S3C_VIDCON0_VIDOUT_RGB;
+ cfg |= S3C_VIDCON0_VCLKEN_NORMAL;
+ s3c_ielcd_writel(S3C_VIDCON0, cfg);
+
+ /* window0 position setting , fixed */
+ s3c_ielcd_writel(S3C_VIDOSD0A, 0);
+
+ /* window0 position setting */
+ cfg = S3C_VIDOSD_RIGHT_X(ctrl->lcd->width - 1);
+ cfg |= S3C_VIDOSD_BOTTOM_Y(ctrl->lcd->height - 1);
+ s3c_ielcd_writel(S3C_VIDOSD0B, cfg);
+
+ /* window0 osd size setting */
+ s3c_ielcd_writel(S3C_VIDOSD0C, ctrl->lcd->width * ctrl->lcd->height);
+
+ /* window0 setting , fixed */
+ cfg = S3C_WINCON_DATAPATH_LOCAL | S3C_WINCON_BPPMODE_32BPP | S3C_WINCON_INRGB_RGB;
+ s3c_ielcd_writel(S3C_WINCON0, cfg);
+
+ s3cfb_window_on(ielcd_fbdev, 0);
+}
+
diff --git a/drivers/video/samsung/s3cfb_ielcd_kona.h b/drivers/video/samsung/s3cfb_ielcd_kona.h
new file mode 100644
index 0000000..4c89643
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ielcd_kona.h
@@ -0,0 +1,28 @@
+/* linux/drivers/video/samsung/s3cfb_ielcd.h
+ *
+ * Header file for Samsung (IELCD) driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __S3CFB_IELCD_H__
+#define __S3CFB_IELCD_H__
+
+#define S3C_IELCD_MAGIC_KEY 0x2ff47
+
+#define S3C_IELCD_PHY_BASE 0x11C40000
+#define S3C_IELCD_MAP_SIZE 0x00008000
+
+#define S3C_IELCD_GPOUTCON0 0x0278
+
+int ielcd_hw_init(void);
+int ielcd_display_on(void);
+int ielcd_display_off(void);
+void ielcd_init_global(struct s3cfb_global *ctrl);
+
+#endif
diff --git a/drivers/video/samsung/s3cfb_main.c b/drivers/video/samsung/s3cfb_main.c
index fadea40..191c68e 100644
--- a/drivers/video/samsung/s3cfb_main.c
+++ b/drivers/video/samsung/s3cfb_main.c
@@ -41,9 +41,14 @@
#endif
#ifdef CONFIG_FB_S5P_MDNIE
+#ifdef CONFIG_MACH_KONA
+#include "s3cfb_mdnie_kona.h"
+#include "mdnie_kona.h"
+#else
#include "s3cfb_mdnie.h"
#include "mdnie.h"
#endif
+#endif
#ifdef CONFIG_HAS_WAKELOCK
#include <linux/wakelock.h>
#include <linux/earlysuspend.h>
@@ -604,8 +609,12 @@ static int s3cfb_probe(struct platform_device *pdev)
#ifdef CONFIG_FB_S5P_MDNIE
/* only FIMD0 is supported */
if (i == 0)
+#ifdef CONFIG_MACH_KONA
+ mdnie_setup();
+#else
s3c_mdnie_setup();
#endif
+#endif
/* hw setting */
s3cfb_init_global(fbdev[i]);
@@ -636,8 +645,12 @@ static int s3cfb_probe(struct platform_device *pdev)
pdata->set_display_path();
s3cfb_set_dualrgb(fbdev[i], S3C_DUALRGB_MDNIE);
+#ifdef CONFIG_MACH_KONA
+ mdnie_display_on(fbdev[i]);
+#else
s3c_mdnie_init_global(fbdev[i]);
s3c_mdnie_display_on(fbdev[i]);
+#endif
}
#endif
s3cfb_enable_window(fbdev[0], pdata->default_win);
@@ -916,8 +929,12 @@ void s3cfb_early_suspend(struct early_suspend *h)
ret = s3cfb_display_off(fbdev[i]);
#ifdef CONFIG_FB_S5P_MDNIE
+#ifdef CONFIG_MACH_KONA
+ ret += mdnie_display_off();
+#else
ret += s3c_mdnie_display_off();
#endif
+#endif
if (ret > 0)
s3cfb_lcd0_pmu_off();
@@ -1023,10 +1040,14 @@ void s3cfb_late_resume(struct early_suspend *h)
#if defined(CONFIG_FB_S5P_S6C1372) || defined(CONFIG_FB_S5P_S6F1202A)
s5c1372_ldi_enable();
#endif
+#ifdef CONFIG_MACH_KONA
+ mdnie_display_on(fbdev[i]);
+#else
s3c_mdnie_init_global(fbdev[i]);
set_mdnie_value(g_mdnie, 1);
s3c_mdnie_display_on(fbdev[i]);
#endif
+#endif
s3cfb_display_on(fbdev[i]);
/* Set alpha value width to 8-bit */
diff --git a/drivers/video/samsung/s3cfb_mdnie_kona.c b/drivers/video/samsung/s3cfb_mdnie_kona.c
new file mode 100644
index 0000000..1fc7fcd
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_mdnie_kona.c
@@ -0,0 +1,120 @@
+/* linux/drivers/video/samsung/s3cfb_mdnie.c
+ *
+ * Register interface file for Samsung mDNIe driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+
+#include "s3cfb.h"
+#include "s3cfb_ielcd_kona.h"
+#include "s3cfb_mdnie_kona.h"
+#include "mdnie_kona.h"
+
+
+#define s3c_mdnie_read(addr) __raw_readl(s3c_mdnie_base + addr*4)
+#define s3c_mdnie_write(addr, val) __raw_writel(val, s3c_mdnie_base + addr*4)
+
+
+static struct resource *s3c_mdnie_mem;
+static void __iomem *s3c_mdnie_base;
+
+
+int mdnie_write(unsigned int addr, unsigned int val)
+{
+ return s3c_mdnie_write(addr, val);
+}
+
+int mdnie_mask(void)
+{
+ return s3c_mdnie_write(MDNIE_REG_MASK, 0x9FFF);
+}
+
+int mdnie_unmask(void)
+{
+ return s3c_mdnie_write(MDNIE_REG_MASK, 0);
+}
+
+int mdnie_set_size(unsigned int hsize, unsigned int vsize)
+{
+ unsigned int reg;
+
+ /* Bank0 Select : DO NOT REMOVE THIS LINE */
+ s3c_mdnie_write(MDNIE_REG_BANK_SEL, 0);
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ /* Input Data Unmask */
+ reg = s3c_mdnie_read(S3C_MDNIE_rR1);
+ reg &= ~S3C_MDNIE_INPUT_DATA_ENABLE;
+ s3c_mdnie_write(S3C_MDNIE_rR1, reg);
+#endif
+
+ /* LCD width */
+ reg = s3c_mdnie_read(MDNIE_REG_WIDTH);
+ reg &= ~S3C_MDNIE_SIZE_MASK;
+ reg |= S3C_MDNIE_HSIZE(hsize);
+ s3c_mdnie_write(MDNIE_REG_WIDTH, reg);
+
+ /* LCD height */
+ reg = s3c_mdnie_read(MDNIE_REG_HEIGHT);
+ reg &= ~S3C_MDNIE_SIZE_MASK;
+ reg |= S3C_MDNIE_VSIZE(vsize);
+ s3c_mdnie_write(MDNIE_REG_HEIGHT, reg);
+
+ mdnie_unmask();
+
+ return 0;
+}
+
+int mdnie_display_on(struct s3cfb_global *ctrl)
+{
+ mdnie_set_size(ctrl->lcd->width, ctrl->lcd->height);
+
+ ielcd_init_global(ctrl);
+
+ ielcd_display_on();
+
+ if (!IS_ERR_OR_NULL(g_mdnie))
+ g_mdnie->enable = TRUE;
+
+ return 0;
+}
+
+int mdnie_display_off(void)
+{
+ if (!IS_ERR_OR_NULL(g_mdnie))
+ g_mdnie->enable = FALSE;
+
+ return ielcd_display_off();
+}
+
+static int mdnie_hw_init(void)
+{
+ s3c_mdnie_mem = request_mem_region(S3C_MDNIE_PHY_BASE, S3C_MDNIE_MAP_SIZE, "mdnie");
+ if (IS_ERR_OR_NULL(s3c_mdnie_mem)) {
+ pr_err("%s: fail to request_mem_region\n", __func__);
+ return -ENOENT;
+ }
+
+ s3c_mdnie_base = ioremap(S3C_MDNIE_PHY_BASE, S3C_MDNIE_MAP_SIZE);
+ if (IS_ERR_OR_NULL(s3c_mdnie_base)) {
+ pr_err("%s: fail to ioremap\n", __func__);
+ return -ENOENT;
+ }
+
+ return 0;
+}
+
+void mdnie_setup(void)
+{
+ mdnie_hw_init();
+ ielcd_hw_init();
+}
+
+MODULE_DESCRIPTION("EXYNOS mDNIe Device Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_mdnie_kona.h b/drivers/video/samsung/s3cfb_mdnie_kona.h
new file mode 100644
index 0000000..4a91691
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_mdnie_kona.h
@@ -0,0 +1,88 @@
+
+/* linux/drivers/video/samsung/s3cfb_mdnie.h
+ *
+ * Header file for Samsung (MDNIE) driver
+ *
+ * Copyright (c) 2009 Samsung Electronics
+ * http://www.samsungsemi.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __S3CFB_MDNIE_H__
+#define __S3CFB_MDNIE_H__
+
+#define S3C_MDNIE_PHY_BASE 0x11CA0000
+#define S3C_MDNIE_MAP_SIZE 0x00001000
+
+/* Register Address */
+#if defined(CONFIG_CPU_EXYNOS4210)
+#define MDNIE_REG_BANK_SEL 0x0000
+#define MDNIE_REG_WIDTH 0x0022
+#define MDNIE_REG_HEIGHT 0x0023
+#define MDNIE_REG_MASK 0x0028
+
+#define MDNIE_REG_PWM_CONTROL 0x00B4
+#define MDNIE_REG_POWER_LUT0 0x0076
+#define MDNIE_REG_POWER_LUT2 0x0077
+#define MDNIE_REG_POWER_LUT4 0x0078
+#define MDNIE_REG_POWER_LUT6 0x0079
+#define MDNIE_REG_POWER_LUT8 0x007A
+
+#elif defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#define MDNIE_REG_BANK_SEL 0x0000
+#define MDNIE_REG_WIDTH 0x0003
+#define MDNIE_REG_HEIGHT 0x0004
+#define MDNIE_REG_MASK 0x00FF
+
+#define S3C_MDNIE_rR1 0x0001
+
+#define MDNIE_REG_PWM_CONTROL 0x00B6
+#define MDNIE_REG_POWER_LUT0 0x0079
+#define MDNIE_REG_POWER_LUT2 0x007A
+#define MDNIE_REG_POWER_LUT4 0x007B
+#define MDNIE_REG_POWER_LUT6 0x007C
+#define MDNIE_REG_POWER_LUT8 0x007D
+#endif
+
+#define MDNIE_REG_RED_R 0x00E1 /*SCR RrCr*/
+#define MDNIE_REG_RED_G 0x00E2 /*SCR RgCg*/
+#define MDNIE_REG_RED_B 0x00E3 /*SCR RbCb*/
+#define MDNIE_REG_BLUE_R 0x00E4 /*SCR GrMr*/
+#define MDNIE_REG_BLUE_G 0x00E5 /*SCR GgMg*/
+#define MDNIE_REG_BLUE_B 0x00E6 /*SCR GbMb*/
+#define MDNIE_REG_GREEN_R 0x00E7 /*SCR BrYr*/
+#define MDNIE_REG_GREEN_G 0x00E8 /*SCR BgYg*/
+#define MDNIE_REG_GREEN_B 0x00E9 /*SCR BbYb*/
+#define MDNIE_REG_BLACK_R 0x00EA /*SCR KrWr*/
+#define MDNIE_REG_BLACK_G 0x00EB /*SCR KgWg*/
+#define MDNIE_REG_BLACK_B 0x00EC /*SCR KbWb*/
+
+/* Register Value */
+#if defined(CONFIG_CPU_EXYNOS4210)
+#define MDNIE_PWM_BANK 0x0000
+#elif defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#define MDNIE_PWM_BANK 0x0001 /* CMC624's PWM CTL is in BANK1 */
+#endif
+
+#define S3C_MDNIE_INPUT_DATA_ENABLE (1 << 10)
+
+#define S3C_MDNIE_SIZE_MASK 0x7FF
+#define S3C_MDNIE_HSIZE(n) (n & S3C_MDNIE_SIZE_MASK)
+#define S3C_MDNIE_VSIZE(n) (n & S3C_MDNIE_SIZE_MASK)
+
+
+#define TRUE 1
+#define FALSE 0
+
+void mdnie_setup(void);
+int mdnie_display_on(struct s3cfb_global *ctrl);
+int mdnie_display_off(void);
+
+int mdnie_write(unsigned int addr, unsigned int val);
+int mdnie_mask(void);
+int mdnie_unmask(void);
+
+#endif
diff --git a/drivers/video/samsung/s3cfb_nt71391.c b/drivers/video/samsung/s3cfb_nt71391.c
new file mode 100644
index 0000000..921544a
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_nt71391.c
@@ -0,0 +1,415 @@
+/* linux/drivers/video/samsung/s3cfb_nt71391.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com/
+ *
+ * NT71391 : 8" WXGA Landscape LCD module driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/gpio.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/wait.h>
+#include <plat/regs-dsim.h>
+#include <mach/dsim.h>
+#include <mach/mipi_ddi.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "s3cfb.h"
+#include "s5p-dsim.h"
+
+#define NT71391_CHANGE_MINI_LVDS_FREQ_MIPI 1
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+struct lcd_info {
+ struct device *dev;
+ unsigned int ldi_enable;
+ unsigned int power;
+ unsigned int connected;
+ struct mutex lock;
+ struct lcd_device *ld;
+ struct lcd_platform_data *lcd_pd;
+ struct dsim_global *dsim;
+};
+
+#ifdef NT71391_CHANGE_MINI_LVDS_FREQ_MIPI
+
+#define NT71391_TCON_REG_ADD 0xAC
+#define NT71391_TCON_REG_CHECKSUM 0xFF
+#define NT71931_N_16 0x18
+#define NT71931_N_17 0x19
+#define NT71931_N_18 0x1A
+#define NT71931_N_19 0x1B
+#define NT71931_N_20 0x1C
+#define NT71931_N_21 0x1D
+#define NT71931_N_22 0x1E
+#define NT71931_N_23 0x1F
+#define NT71931_N_24 0x10
+#define NT71931_N_25 0x11
+
+
+enum NT71391_COMMAND_TYPE {
+ NT71391_LOCK_CMD2 = 0x03,
+ NT71391_READ = 0x14,
+ NT71391_WRITE = 0x23,
+};
+
+
+static const unsigned char NT71391_UNLOCK_PAGE0[] = {
+ 0xF3,0xA0
+};
+
+static const unsigned char NT71391_UNLOCK_PAGE1[] = {
+ 0xF3,0xA1
+};
+
+static const unsigned char NT71391_FREQ_SETTING[] = {
+ NT71391_TCON_REG_ADD,NT71931_N_16
+};
+
+static const unsigned char TESTA[] = {
+ 0x2B,0xC0
+};
+
+static int _nt71391_write(struct lcd_info *lcd, const unsigned char *seq, enum NT71391_COMMAND_TYPE cmd_type)
+{
+ const unsigned char *wbuf;
+ int ret = 0;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ wbuf = seq;
+
+ switch (cmd_type) {
+ case NT71391_LOCK_CMD2:
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, NT71391_LOCK_CMD2,0x0,0x0);
+ break;
+ case NT71391_READ:
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, NT71391_READ,wbuf[0],0x0);
+ break;
+ case NT71391_WRITE:
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, NT71391_WRITE, wbuf[0], wbuf[1]);
+ break;
+ default:
+ dev_dbg(&lcd->ld->dev, "%s :: Invalid cmd type \n", __func__);
+ break;
+ }
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int nt71391_write(struct lcd_info *lcd, const unsigned char *seq, enum NT71391_COMMAND_TYPE cmd_type)
+{
+ int ret = 0;
+ int retry_cnt = 1;
+
+retry:
+ ret = _nt71391_write(lcd, seq, cmd_type);
+ if (!ret) {
+ if (retry_cnt) {
+ dev_dbg(&lcd->ld->dev, "%s :: retry: %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto retry;
+ } else
+ dev_dbg(&lcd->ld->dev, "%s :: 0x%02x\n", __func__, seq[0]);
+ }
+
+ return ret;
+}
+
+static int _nt71391_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+{
+ int ret = 0;
+
+ if (!lcd->connected)
+ return ret;
+
+ mutex_lock(&lcd->lock);
+
+ if (lcd->dsim->ops->cmd_read)
+ ret = lcd->dsim->ops->cmd_dcs_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int nt71391_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _nt71391_read(lcd, addr, count, buf);
+ if (!ret) {
+ if (retry_cnt) {
+ printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n", __func__, retry_cnt);
+ retry_cnt--;
+ goto read_retry;
+ } else
+ printk(KERN_ERR "[ERROR:LCD] %s : 0x%02x read failed\n", __func__, addr);
+ }
+
+ return ret;
+}
+#endif
+static ssize_t lcdtype_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "BOE_BP080WX7\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0664,
+ lcdtype_show, NULL);
+
+static ssize_t window_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+
+ sprintf(temp, "%x %x %x\n", 0x0, 0x0, 0x0);
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(window_type, 0444,
+ window_type_show, NULL);
+
+static int nt71391_power_on(struct lcd_info *lcd)
+{
+
+#ifdef NT71391_CHANGE_MINI_LVDS_FREQ_MIPI
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ msleep(120); /* power on 50ms, i2c 70ms */
+ nt71391_write(lcd, NT71391_UNLOCK_PAGE0, NT71391_WRITE);
+ nt71391_write(lcd, NT71391_FREQ_SETTING, NT71391_WRITE);
+ nt71391_write(lcd, NULL, NT71391_LOCK_CMD2);
+
+
+ lcd->dsim->ops->cmd_write(lcd->dsim, TURN_ON, 0, 0);
+#else
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ msleep(120); /* power on 50ms, i2c 70ms */
+
+ lcd->dsim->ops->cmd_write(lcd->dsim, TURN_ON, 0, 0);
+#endif
+
+ lcd->ldi_enable = 1;
+
+ return ret;
+}
+
+static int nt71391_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ msleep(135);
+
+ return ret;
+}
+
+static int nt71391_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = nt71391_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = nt71391_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int nt71391_set_power(struct lcd_device *ld, int power)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ if (power != FB_BLANK_UNBLANK && power != FB_BLANK_POWERDOWN &&
+ power != FB_BLANK_NORMAL) {
+ dev_err(&lcd->ld->dev, "power value should be 0, 1 or 4.\n");
+ return -EINVAL;
+ }
+
+ return nt71391_power(lcd, power);
+}
+
+static int nt71391_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static struct lcd_ops nt71391_lcd_ops = {
+ .set_power = nt71391_set_power,
+ .get_power = nt71391_get_power,
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+struct lcd_info *g_lcd;
+
+void nt71391_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+ int err = 0;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+
+ nt71391_power(lcd, FB_BLANK_POWERDOWN);
+
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void nt71391_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+
+ nt71391_power(lcd, FB_BLANK_UNBLANK);
+
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+
+static int __init nt71391_probe(struct device *dev)
+{
+ struct lcd_info *lcd;
+ int ret = 0;
+
+ lcd = kzalloc(sizeof(struct lcd_info), GFP_KERNEL);
+ if (!lcd) {
+ pr_err("failed to allocate for lcd\n");
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ g_lcd = lcd;
+
+ lcd->ld = lcd_device_register("panel", dev, lcd, &nt71391_lcd_ops);
+ if (IS_ERR(lcd->ld)) {
+ pr_err("failed to register lcd device\n");
+ ret = PTR_ERR(lcd->ld);
+ goto out_free_lcd;
+ }
+
+ lcd->dev = dev;
+ lcd->connected = 1;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->power = FB_BLANK_UNBLANK;
+
+ mutex_init(&lcd->lock);
+
+ dev_set_drvdata(dev, lcd);
+
+ dev_info(dev, "lcd panel driver has been probed.\n");
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ lcd_early_suspend = nt71391_early_suspend;
+ lcd_late_resume = nt71391_late_resume;
+#endif
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries\n");
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_window_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add window_type entries\n");
+
+ return 0;
+
+out_free_lcd:
+ kfree(lcd);
+err_alloc:
+ return ret;
+}
+
+static int __devexit nt71391_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ nt71391_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+
+ return 0;
+}
+
+static void nt71391_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ nt71391_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver nt71391_mipi_driver = {
+ .name = "nt71391",
+ .probe = nt71391_probe,
+ .remove = __devexit_p(nt71391_remove),
+ .shutdown = nt71391_shutdown,
+};
+
+static int __init nt71391_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&nt71391_mipi_driver);
+}
+
+static void __exit nt71391_exit(void)
+{
+ return;
+}
+
+module_init(nt71391_init);
+module_exit(nt71391_exit);
+
+MODULE_AUTHOR("SAMSUNG");
+MODULE_DESCRIPTION("NT71391 LCD driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_ops.c b/drivers/video/samsung/s3cfb_ops.c
index 8d5739d..0bcd529 100644
--- a/drivers/video/samsung/s3cfb_ops.c
+++ b/drivers/video/samsung/s3cfb_ops.c
@@ -53,6 +53,10 @@
#include <plat/s5p-sysmmu.h>
#endif
+#if defined(CONFIG_MACH_KONA) || defined(CONFIG_MACH_TAB3) || defined(CONFIG_MACH_T0)
+extern unsigned int lpcharge;
+#endif
+
struct s3c_platform_fb *to_fb_plat(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1078,6 +1082,15 @@ int s3cfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fb)
}
#endif
+#if defined(CONFIG_MACH_KONA) || defined(CONFIG_MACH_TAB3) || defined(CONFIG_MACH_T0)
+ if (lpcharge) {
+ /* support LPM (off charging mode) display based on FBIOPAN_DISPLAY */
+ s3cfb_check_var(var, fb);
+ s3cfb_set_par(fb);
+ s3cfb_enable_window(fbdev, win->id);
+ }
+#endif
+
if (var->yoffset + var->yres > var->yres_virtual) {
dev_err(fbdev->dev, "invalid yoffset value\n");
if (win->id == pdata->default_win)
diff --git a/drivers/video/samsung_extdisp/s3cfb_extdsp.h b/drivers/video/samsung_extdisp/s3cfb_extdsp.h
index 99f134c..11f4f37 100644
--- a/drivers/video/samsung_extdisp/s3cfb_extdsp.h
+++ b/drivers/video/samsung_extdisp/s3cfb_extdsp.h
@@ -151,7 +151,7 @@ struct s3cfb_extdsp_user_window {
#define S3CFB_EXTDSP_GET_FREE_BUFFER _IOW('F', 329, unsigned int)
extern struct fb_ops s3cfb_extdsp_ops;
-extern inline struct s3cfb_extdsp_global *get_extdsp_global(int id);
+extern struct s3cfb_extdsp_global *get_extdsp_global(int id);
/* S3CFB_EXTDSP */
extern int s3cfb_extdsp_enable_window(struct s3cfb_extdsp_global *fbdev, int id);
diff --git a/drivers/video/samsung_extdisp/s3cfb_extdsp_main.c b/drivers/video/samsung_extdisp/s3cfb_extdsp_main.c
index 4f9f2b2..dacd94d 100644
--- a/drivers/video/samsung_extdisp/s3cfb_extdsp_main.c
+++ b/drivers/video/samsung_extdisp/s3cfb_extdsp_main.c
@@ -43,7 +43,7 @@
struct s3cfb_extdsp_extdsp_desc *fbextdsp;
-inline struct s3cfb_extdsp_global *get_extdsp_global(int id)
+struct s3cfb_extdsp_global *get_extdsp_global(int id)
{
struct s3cfb_extdsp_global *fbdev;